summaryrefslogtreecommitdiff
path: root/platform/www
diff options
context:
space:
mode:
authorYaco <franco@reevo.org>2022-03-08 13:08:34 +0000
committerYaco <franco@reevo.org>2022-03-08 13:08:34 +0000
commitc985c40d3f3fc6a2be3be3186df3bf2f32189475 (patch)
treecee11f5e5a7e351ee0fec36d58d72cbee4f7e49b /platform/www
first commit after acervus codebase
Diffstat (limited to 'platform/www')
-rw-r--r--platform/www/.htaccess50
-rw-r--r--platform/www/.htaccess.dist43
-rw-r--r--platform/www/COPYING339
-rw-r--r--platform/www/README10
-rw-r--r--platform/www/VERSION1
-rw-r--r--platform/www/bin/.htaccess7
-rwxr-xr-xplatform/www/bin/dwpage.php322
-rwxr-xr-xplatform/www/bin/gittool.php340
-rwxr-xr-xplatform/www/bin/indexer.php107
-rwxr-xr-xplatform/www/bin/plugin.php103
-rwxr-xr-xplatform/www/bin/render.php64
-rwxr-xr-xplatform/www/bin/striplangs.php114
-rwxr-xr-xplatform/www/bin/wantedpages.php186
-rw-r--r--platform/www/conf/.htaccess8
-rw-r--r--platform/www/conf/acl.auth.php21
-rw-r--r--platform/www/conf/acl.auth.php.dist21
-rw-r--r--platform/www/conf/acronyms.conf62
-rw-r--r--platform/www/conf/dokuwiki.php178
-rw-r--r--platform/www/conf/entities.conf22
-rw-r--r--platform/www/conf/farm.ini.dist26
-rw-r--r--platform/www/conf/farm.ini.save26
-rw-r--r--platform/www/conf/interwiki.conf42
-rw-r--r--platform/www/conf/license.php38
-rw-r--r--platform/www/conf/local.php29
-rw-r--r--platform/www/conf/local.php.bak.php29
-rw-r--r--platform/www/conf/local.php.dist16
-rw-r--r--platform/www/conf/manifest.json3
-rw-r--r--platform/www/conf/mediameta.php91
-rw-r--r--platform/www/conf/mime.conf72
-rw-r--r--platform/www/conf/mysql.conf.php.example253
-rw-r--r--platform/www/conf/plugins.local.php8
-rw-r--r--platform/www/conf/plugins.php6
-rw-r--r--platform/www/conf/plugins.required.php12
-rw-r--r--platform/www/conf/scheme.conf11
-rw-r--r--platform/www/conf/smileys.conf28
-rw-r--r--platform/www/conf/users.auth.php.dist10
-rw-r--r--platform/www/conf/users.auth.php.sample11
-rw-r--r--platform/www/conf/wordblock.conf29
-rw-r--r--platform/www/data/.htaccess7
-rw-r--r--platform/www/data/_dummy1
-rw-r--r--platform/www/data/deleted.files846
-rw-r--r--platform/www/data/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.pngbin0 -> 6516 bytes
-rw-r--r--platform/www/data/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.xcfbin0 -> 12093 bytes
-rw-r--r--platform/www/data/media/wiki/dokuwiki-128.pngbin0 -> 27895 bytes
-rw-r--r--platform/www/data/media/wiki/dokuwiki.svg586
-rw-r--r--platform/www/data/media_attic/_dummy1
-rw-r--r--platform/www/data/media_meta/_dummy1
-rw-r--r--platform/www/data/pages/index.txt3
-rw-r--r--platform/www/data/pages/playground/playground.txt1
-rw-r--r--platform/www/data/pages/start.txt1
-rw-r--r--platform/www/data/pages/wiki/dokuwiki.txt62
-rw-r--r--platform/www/data/pages/wiki/syntax.txt525
-rw-r--r--platform/www/data/pages/wiki/welcome.txt30
-rw-r--r--platform/www/doku.php127
-rw-r--r--platform/www/feed.php521
-rw-r--r--platform/www/inc/.htaccess8
-rw-r--r--platform/www/inc/Action/AbstractAclAction.php25
-rw-r--r--platform/www/inc/Action/AbstractAction.php88
-rw-r--r--platform/www/inc/Action/AbstractAliasAction.php28
-rw-r--r--platform/www/inc/Action/AbstractUserAction.php25
-rw-r--r--platform/www/inc/Action/Admin.php45
-rw-r--r--platform/www/inc/Action/Backlink.php24
-rw-r--r--platform/www/inc/Action/Cancel.php25
-rw-r--r--platform/www/inc/Action/Check.php26
-rw-r--r--platform/www/inc/Action/Conflict.php34
-rw-r--r--platform/www/inc/Action/Denied.php23
-rw-r--r--platform/www/inc/Action/Diff.php35
-rw-r--r--platform/www/inc/Action/Draft.php39
-rw-r--r--platform/www/inc/Action/Draftdel.php38
-rw-r--r--platform/www/inc/Action/Edit.php91
-rw-r--r--platform/www/inc/Action/Exception/ActionAbort.php20
-rw-r--r--platform/www/inc/Action/Exception/ActionAclRequiredException.php17
-rw-r--r--platform/www/inc/Action/Exception/ActionDisabledException.php17
-rw-r--r--platform/www/inc/Action/Exception/ActionException.php66
-rw-r--r--platform/www/inc/Action/Exception/ActionUserRequiredException.php17
-rw-r--r--platform/www/inc/Action/Exception/FatalException.php26
-rw-r--r--platform/www/inc/Action/Exception/NoActionException.php15
-rw-r--r--platform/www/inc/Action/Export.php113
-rw-r--r--platform/www/inc/Action/Index.php25
-rw-r--r--platform/www/inc/Action/Locked.php25
-rw-r--r--platform/www/inc/Action/Login.php36
-rw-r--r--platform/www/inc/Action/Logout.php50
-rw-r--r--platform/www/inc/Action/Media.php24
-rw-r--r--platform/www/inc/Action/Plugin.php32
-rw-r--r--platform/www/inc/Action/Preview.php42
-rw-r--r--platform/www/inc/Action/Profile.php45
-rw-r--r--platform/www/inc/Action/ProfileDelete.php42
-rw-r--r--platform/www/inc/Action/Recent.php40
-rw-r--r--platform/www/inc/Action/Recover.php21
-rw-r--r--platform/www/inc/Action/Redirect.php65
-rw-r--r--platform/www/inc/Action/Register.php45
-rw-r--r--platform/www/inc/Action/Resendpwd.php177
-rw-r--r--platform/www/inc/Action/Revert.php60
-rw-r--r--platform/www/inc/Action/Revisions.php24
-rw-r--r--platform/www/inc/Action/Save.php60
-rw-r--r--platform/www/inc/Action/Search.php135
-rw-r--r--platform/www/inc/Action/Show.php36
-rw-r--r--platform/www/inc/Action/Sitemap.php66
-rw-r--r--platform/www/inc/Action/Source.php36
-rw-r--r--platform/www/inc/Action/Subscribe.php168
-rw-r--r--platform/www/inc/ActionRouter.php228
-rw-r--r--platform/www/inc/Ajax.php438
-rw-r--r--platform/www/inc/Cache/Cache.php240
-rw-r--r--platform/www/inc/Cache/CacheInstructions.php46
-rw-r--r--platform/www/inc/Cache/CacheParser.php64
-rw-r--r--platform/www/inc/Cache/CacheRenderer.php94
-rw-r--r--platform/www/inc/ChangeLog/ChangeLog.php666
-rw-r--r--platform/www/inc/ChangeLog/MediaChangeLog.php30
-rw-r--r--platform/www/inc/ChangeLog/PageChangeLog.php30
-rw-r--r--platform/www/inc/Debug/DebugHelper.php167
-rw-r--r--platform/www/inc/Debug/PropertyDeprecationHelper.php134
-rw-r--r--platform/www/inc/DifferenceEngine.php1544
-rw-r--r--platform/www/inc/Draft.php165
-rw-r--r--platform/www/inc/Extension/ActionPlugin.php22
-rw-r--r--platform/www/inc/Extension/AdminPlugin.php123
-rw-r--r--platform/www/inc/Extension/AuthPlugin.php461
-rw-r--r--platform/www/inc/Extension/CLIPlugin.php13
-rw-r--r--platform/www/inc/Extension/Event.php197
-rw-r--r--platform/www/inc/Extension/EventHandler.php108
-rw-r--r--platform/www/inc/Extension/Plugin.php13
-rw-r--r--platform/www/inc/Extension/PluginController.php393
-rw-r--r--platform/www/inc/Extension/PluginInterface.php162
-rw-r--r--platform/www/inc/Extension/PluginTrait.php256
-rw-r--r--platform/www/inc/Extension/RemotePlugin.php122
-rw-r--r--platform/www/inc/Extension/SyntaxPlugin.php132
-rw-r--r--platform/www/inc/FeedParser.php27
-rw-r--r--platform/www/inc/FeedParserFile.php62
-rw-r--r--platform/www/inc/Form/ButtonElement.php34
-rw-r--r--platform/www/inc/Form/CheckableElement.php62
-rw-r--r--platform/www/inc/Form/DropdownElement.php198
-rw-r--r--platform/www/inc/Form/Element.php151
-rw-r--r--platform/www/inc/Form/FieldsetCloseElement.php30
-rw-r--r--platform/www/inc/Form/FieldsetOpenElement.php36
-rw-r--r--platform/www/inc/Form/Form.php462
-rw-r--r--platform/www/inc/Form/HTMLElement.php29
-rw-r--r--platform/www/inc/Form/InputElement.php159
-rw-r--r--platform/www/inc/Form/LabelElement.php27
-rw-r--r--platform/www/inc/Form/LegacyForm.php181
-rw-r--r--platform/www/inc/Form/OptGroup.php106
-rw-r--r--platform/www/inc/Form/TagCloseElement.php88
-rw-r--r--platform/www/inc/Form/TagElement.php29
-rw-r--r--platform/www/inc/Form/TagOpenElement.php30
-rw-r--r--platform/www/inc/Form/TextareaElement.php51
-rw-r--r--platform/www/inc/Form/ValueElement.php45
-rw-r--r--platform/www/inc/HTTP/DokuHTTPClient.php77
-rw-r--r--platform/www/inc/HTTP/HTTPClient.php885
-rw-r--r--platform/www/inc/HTTP/HTTPClientException.php10
-rw-r--r--platform/www/inc/IXR_Library.php1135
-rw-r--r--platform/www/inc/Input/Get.php29
-rw-r--r--platform/www/inc/Input/Input.php287
-rw-r--r--platform/www/inc/Input/Post.php30
-rw-r--r--platform/www/inc/Input/Server.php19
-rw-r--r--platform/www/inc/JpegMeta.php3188
-rw-r--r--platform/www/inc/Mailer.class.php777
-rw-r--r--platform/www/inc/Manifest.php84
-rw-r--r--platform/www/inc/Menu/AbstractMenu.php96
-rw-r--r--platform/www/inc/Menu/DetailMenu.php21
-rw-r--r--platform/www/inc/Menu/Item/AbstractItem.php253
-rw-r--r--platform/www/inc/Menu/Item/Admin.php28
-rw-r--r--platform/www/inc/Menu/Item/Back.php29
-rw-r--r--platform/www/inc/Menu/Item/Backlink.php18
-rw-r--r--platform/www/inc/Menu/Item/Edit.php65
-rw-r--r--platform/www/inc/Menu/Item/ImgBackto.php24
-rw-r--r--platform/www/inc/Menu/Item/Index.php27
-rw-r--r--platform/www/inc/Menu/Item/Login.php29
-rw-r--r--platform/www/inc/Menu/Item/Media.php21
-rw-r--r--platform/www/inc/Menu/Item/MediaManager.php32
-rw-r--r--platform/www/inc/Menu/Item/Profile.php24
-rw-r--r--platform/www/inc/Menu/Item/Recent.php20
-rw-r--r--platform/www/inc/Menu/Item/Register.php24
-rw-r--r--platform/www/inc/Menu/Item/Resendpwd.php24
-rw-r--r--platform/www/inc/Menu/Item/Revert.php26
-rw-r--r--platform/www/inc/Menu/Item/Revisions.php21
-rw-r--r--platform/www/inc/Menu/Item/Subscribe.php24
-rw-r--r--platform/www/inc/Menu/Item/Top.php36
-rw-r--r--platform/www/inc/Menu/MenuInterface.php20
-rw-r--r--platform/www/inc/Menu/MobileMenu.php93
-rw-r--r--platform/www/inc/Menu/PageMenu.php23
-rw-r--r--platform/www/inc/Menu/SiteMenu.php20
-rw-r--r--platform/www/inc/Menu/UserMenu.php21
-rw-r--r--platform/www/inc/Parsing/Handler/AbstractRewriter.php39
-rw-r--r--platform/www/inc/Parsing/Handler/Block.php211
-rw-r--r--platform/www/inc/Parsing/Handler/CallWriter.php40
-rw-r--r--platform/www/inc/Parsing/Handler/CallWriterInterface.php30
-rw-r--r--platform/www/inc/Parsing/Handler/Lists.php186
-rw-r--r--platform/www/inc/Parsing/Handler/Nest.php82
-rw-r--r--platform/www/inc/Parsing/Handler/Preformatted.php49
-rw-r--r--platform/www/inc/Parsing/Handler/Quote.php86
-rw-r--r--platform/www/inc/Parsing/Handler/ReWriterInterface.php37
-rw-r--r--platform/www/inc/Parsing/Handler/Table.php320
-rw-r--r--platform/www/inc/Parsing/Lexer/Lexer.php349
-rw-r--r--platform/www/inc/Parsing/Lexer/ParallelRegex.php203
-rw-r--r--platform/www/inc/Parsing/Lexer/StateStack.php60
-rw-r--r--platform/www/inc/Parsing/Parser.php128
-rw-r--r--platform/www/inc/Parsing/ParserMode/AbstractMode.php40
-rw-r--r--platform/www/inc/Parsing/ParserMode/Acronym.php68
-rw-r--r--platform/www/inc/Parsing/ParserMode/Base.php31
-rw-r--r--platform/www/inc/Parsing/ParserMode/Camelcaselink.php23
-rw-r--r--platform/www/inc/Parsing/ParserMode/Code.php25
-rw-r--r--platform/www/inc/Parsing/ParserMode/Emaillink.php20
-rw-r--r--platform/www/inc/Parsing/ParserMode/Entity.php50
-rw-r--r--platform/www/inc/Parsing/ParserMode/Eol.php25
-rw-r--r--platform/www/inc/Parsing/ParserMode/Externallink.php44
-rw-r--r--platform/www/inc/Parsing/ParserMode/File.php25
-rw-r--r--platform/www/inc/Parsing/ParserMode/Filelink.php39
-rw-r--r--platform/www/inc/Parsing/ParserMode/Footnote.php50
-rw-r--r--platform/www/inc/Parsing/ParserMode/Formatting.php115
-rw-r--r--platform/www/inc/Parsing/ParserMode/Header.php24
-rw-r--r--platform/www/inc/Parsing/ParserMode/Hr.php19
-rw-r--r--platform/www/inc/Parsing/ParserMode/Html.php27
-rw-r--r--platform/www/inc/Parsing/ParserMode/Internallink.php20
-rw-r--r--platform/www/inc/Parsing/ParserMode/Linebreak.php19
-rw-r--r--platform/www/inc/Parsing/ParserMode/Listblock.php44
-rw-r--r--platform/www/inc/Parsing/ParserMode/Media.php20
-rw-r--r--platform/www/inc/Parsing/ParserMode/ModeInterface.php46
-rw-r--r--platform/www/inc/Parsing/ParserMode/Multiplyentity.php27
-rw-r--r--platform/www/inc/Parsing/ParserMode/Nocache.php19
-rw-r--r--platform/www/inc/Parsing/ParserMode/Notoc.php19
-rw-r--r--platform/www/inc/Parsing/ParserMode/Php.php27
-rw-r--r--platform/www/inc/Parsing/ParserMode/Plugin.php8
-rw-r--r--platform/www/inc/Parsing/ParserMode/Preformatted.php31
-rw-r--r--platform/www/inc/Parsing/ParserMode/Quote.php41
-rw-r--r--platform/www/inc/Parsing/ParserMode/Quotes.php51
-rw-r--r--platform/www/inc/Parsing/ParserMode/Rss.php19
-rw-r--r--platform/www/inc/Parsing/ParserMode/Smiley.php48
-rw-r--r--platform/www/inc/Parsing/ParserMode/Table.php47
-rw-r--r--platform/www/inc/Parsing/ParserMode/Unformatted.php28
-rw-r--r--platform/www/inc/Parsing/ParserMode/Windowssharelink.php31
-rw-r--r--platform/www/inc/Parsing/ParserMode/Wordblock.php52
-rw-r--r--platform/www/inc/PassHash.php808
-rw-r--r--platform/www/inc/Remote/AccessDeniedException.php10
-rw-r--r--platform/www/inc/Remote/Api.php410
-rw-r--r--platform/www/inc/Remote/ApiCore.php1025
-rw-r--r--platform/www/inc/Remote/RemoteException.php10
-rw-r--r--platform/www/inc/Remote/XmlRpcServer.php61
-rw-r--r--platform/www/inc/SafeFN.class.php158
-rw-r--r--platform/www/inc/Search/Indexer.php1214
-rw-r--r--platform/www/inc/Sitemap/Item.php66
-rw-r--r--platform/www/inc/Sitemap/Mapper.php164
-rw-r--r--platform/www/inc/StyleUtils.php194
-rw-r--r--platform/www/inc/Subscriptions/BulkSubscriptionSender.php261
-rw-r--r--platform/www/inc/Subscriptions/MediaSubscriptionSender.php47
-rw-r--r--platform/www/inc/Subscriptions/PageSubscriptionSender.php88
-rw-r--r--platform/www/inc/Subscriptions/RegistrationSubscriptionSender.php40
-rw-r--r--platform/www/inc/Subscriptions/SubscriberManager.php290
-rw-r--r--platform/www/inc/Subscriptions/SubscriberRegexBuilder.php70
-rw-r--r--platform/www/inc/Subscriptions/SubscriptionSender.php86
-rw-r--r--platform/www/inc/TaskRunner.php240
-rw-r--r--platform/www/inc/Ui/Admin.php167
-rw-r--r--platform/www/inc/Ui/Search.php647
-rw-r--r--platform/www/inc/Ui/SearchState.php141
-rw-r--r--platform/www/inc/Ui/Ui.php20
-rw-r--r--platform/www/inc/Utf8/Asian.php99
-rw-r--r--platform/www/inc/Utf8/Clean.php204
-rw-r--r--platform/www/inc/Utf8/Conversion.php162
-rw-r--r--platform/www/inc/Utf8/PhpString.php383
-rw-r--r--platform/www/inc/Utf8/Table.php93
-rw-r--r--platform/www/inc/Utf8/Unicode.php277
-rw-r--r--platform/www/inc/Utf8/tables/case.php659
-rw-r--r--platform/www/inc/Utf8/tables/loweraccents.php116
-rw-r--r--platform/www/inc/Utf8/tables/romanization.php1458
-rw-r--r--platform/www/inc/Utf8/tables/specials.php615
-rw-r--r--platform/www/inc/Utf8/tables/upperaccents.php114
-rw-r--r--platform/www/inc/actions.php64
-rw-r--r--platform/www/inc/auth.php1279
-rw-r--r--platform/www/inc/cache.php57
-rw-r--r--platform/www/inc/changelog.php403
-rw-r--r--platform/www/inc/cli.php656
-rw-r--r--platform/www/inc/common.php2132
-rw-r--r--platform/www/inc/compatibility.php83
-rw-r--r--platform/www/inc/config_cascade.php91
-rw-r--r--platform/www/inc/confutils.php474
-rw-r--r--platform/www/inc/defines.php65
-rw-r--r--platform/www/inc/deprecated.php570
-rw-r--r--platform/www/inc/farm.php150
-rw-r--r--platform/www/inc/fetch.functions.php196
-rw-r--r--platform/www/inc/form.php1105
-rw-r--r--platform/www/inc/fulltext.php933
-rw-r--r--platform/www/inc/html.php2380
-rw-r--r--platform/www/inc/httputils.php346
-rw-r--r--platform/www/inc/indexer.php369
-rw-r--r--platform/www/inc/infoutils.php527
-rw-r--r--platform/www/inc/init.php623
-rw-r--r--platform/www/inc/io.php781
-rw-r--r--platform/www/inc/lang/en/admin.txt3
-rw-r--r--platform/www/inc/lang/en/adminplugins.txt2
-rw-r--r--platform/www/inc/lang/en/backlinks.txt3
-rw-r--r--platform/www/inc/lang/en/conflict.txt5
-rw-r--r--platform/www/inc/lang/en/denied.txt3
-rw-r--r--platform/www/inc/lang/en/diff.txt3
-rw-r--r--platform/www/inc/lang/en/draft.txt5
-rw-r--r--platform/www/inc/lang/en/edit.txt1
-rw-r--r--platform/www/inc/lang/en/editrev.txt2
-rw-r--r--platform/www/inc/lang/en/index.txt3
-rw-r--r--platform/www/inc/lang/en/install.html7
-rw-r--r--platform/www/inc/lang/en/lang.php395
-rw-r--r--platform/www/inc/lang/en/locked.txt3
-rw-r--r--platform/www/inc/lang/en/login.txt3
-rw-r--r--platform/www/inc/lang/en/mailtext.txt15
-rw-r--r--platform/www/inc/lang/en/mailwrap.html13
-rw-r--r--platform/www/inc/lang/en/newpage.txt3
-rw-r--r--platform/www/inc/lang/en/norev.txt3
-rw-r--r--platform/www/inc/lang/en/onceexisted.txt3
-rw-r--r--platform/www/inc/lang/en/password.txt6
-rw-r--r--platform/www/inc/lang/en/preview.txt3
-rw-r--r--platform/www/inc/lang/en/pwconfirm.txt9
-rw-r--r--platform/www/inc/lang/en/read.txt1
-rw-r--r--platform/www/inc/lang/en/recent.txt3
-rw-r--r--platform/www/inc/lang/en/register.txt3
-rw-r--r--platform/www/inc/lang/en/registermail.txt10
-rw-r--r--platform/www/inc/lang/en/resendpwd.txt3
-rw-r--r--platform/www/inc/lang/en/resetpwd.txt3
-rw-r--r--platform/www/inc/lang/en/revisions.txt3
-rw-r--r--platform/www/inc/lang/en/searchpage.txt3
-rw-r--r--platform/www/inc/lang/en/showrev.txt2
-rw-r--r--platform/www/inc/lang/en/stopwords.txt39
-rw-r--r--platform/www/inc/lang/en/subscr_digest.txt16
-rw-r--r--platform/www/inc/lang/en/subscr_form.txt3
-rw-r--r--platform/www/inc/lang/en/subscr_list.txt13
-rw-r--r--platform/www/inc/lang/en/subscr_single.txt19
-rw-r--r--platform/www/inc/lang/en/updateprofile.txt3
-rw-r--r--platform/www/inc/lang/en/uploadmail.txt11
-rw-r--r--platform/www/inc/legacy.php18
-rw-r--r--platform/www/inc/load.php153
-rw-r--r--platform/www/inc/mail.php166
-rw-r--r--platform/www/inc/media.php2541
-rw-r--r--platform/www/inc/pageutils.php778
-rw-r--r--platform/www/inc/parser/code.php71
-rw-r--r--platform/www/inc/parser/handler.php1157
-rw-r--r--platform/www/inc/parser/metadata.php751
-rw-r--r--platform/www/inc/parser/parser.php99
-rw-r--r--platform/www/inc/parser/renderer.php910
-rw-r--r--platform/www/inc/parser/xhtml.php1999
-rw-r--r--platform/www/inc/parser/xhtmlsummary.php84
-rw-r--r--platform/www/inc/parserutils.php809
-rw-r--r--platform/www/inc/pluginutils.php151
-rw-r--r--platform/www/inc/preload.php5
-rw-r--r--platform/www/inc/preload.php.dist17
-rw-r--r--platform/www/inc/search.php518
-rw-r--r--platform/www/inc/template.php1895
-rw-r--r--platform/www/inc/toolbar.php277
-rw-r--r--platform/www/inc/utf8.php284
-rw-r--r--platform/www/index.php77
-rw-r--r--platform/www/install.php663
-rw-r--r--platform/www/lib/exe/ajax.php25
-rw-r--r--platform/www/lib/exe/css.php676
-rw-r--r--platform/www/lib/exe/detail.php42
-rw-r--r--platform/www/lib/exe/fetch.php106
-rw-r--r--platform/www/lib/exe/index.html11
-rw-r--r--platform/www/lib/exe/indexer.php5
-rw-r--r--platform/www/lib/exe/jquery.php44
-rw-r--r--platform/www/lib/exe/js.php490
-rw-r--r--platform/www/lib/exe/manifest.php14
-rw-r--r--platform/www/lib/exe/mediamanager.php129
-rw-r--r--platform/www/lib/exe/opensearch.php38
-rw-r--r--platform/www/lib/exe/taskrunner.php16
-rw-r--r--platform/www/lib/exe/xmlrpc.php15
-rw-r--r--platform/www/lib/images/README6
-rw-r--r--platform/www/lib/images/_deprecated.txt2
-rw-r--r--platform/www/lib/images/admin/README4
-rw-r--r--platform/www/lib/images/admin/acl.pngbin0 -> 1065 bytes
-rw-r--r--platform/www/lib/images/admin/config.pngbin0 -> 1484 bytes
-rw-r--r--platform/www/lib/images/admin/plugin.pngbin0 -> 1115 bytes
-rw-r--r--platform/www/lib/images/admin/popularity.pngbin0 -> 1172 bytes
-rw-r--r--platform/www/lib/images/admin/revert.pngbin0 -> 1295 bytes
-rw-r--r--platform/www/lib/images/admin/styling.pngbin0 -> 970 bytes
-rw-r--r--platform/www/lib/images/admin/usermanager.pngbin0 -> 1460 bytes
-rw-r--r--platform/www/lib/images/blank.gifbin0 -> 42 bytes
-rw-r--r--platform/www/lib/images/bullet.pngbin0 -> 101 bytes
-rw-r--r--platform/www/lib/images/closed-rtl.pngbin0 -> 111 bytes
-rw-r--r--platform/www/lib/images/closed.pngbin0 -> 110 bytes
-rw-r--r--platform/www/lib/images/diff.pngbin0 -> 190 bytes
-rw-r--r--platform/www/lib/images/email.pngbin0 -> 370 bytes
-rw-r--r--platform/www/lib/images/error.pngbin0 -> 637 bytes
-rw-r--r--platform/www/lib/images/external-link.pngbin0 -> 431 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/7z.pngbin0 -> 911 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/asm.pngbin0 -> 955 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/bash.pngbin0 -> 966 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/bz2.pngbin0 -> 920 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/c.pngbin0 -> 929 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/cc.pngbin0 -> 933 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/conf.pngbin0 -> 666 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/cpp.pngbin0 -> 943 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/cs.pngbin0 -> 944 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/csh.pngbin0 -> 952 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/css.pngbin0 -> 952 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/csv.pngbin0 -> 663 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/deb.pngbin0 -> 914 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/diff.pngbin0 -> 942 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/doc.pngbin0 -> 956 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/docx.pngbin0 -> 970 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/file.pngbin0 -> 543 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/gif.pngbin0 -> 873 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/gz.pngbin0 -> 914 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/h.pngbin0 -> 884 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/hpp.pngbin0 -> 942 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/htm.pngbin0 -> 945 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/html.pngbin0 -> 945 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/ico.pngbin0 -> 865 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/java.pngbin0 -> 961 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/jpeg.pngbin0 -> 877 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/jpg.pngbin0 -> 877 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/js.pngbin0 -> 937 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/json.pngbin0 -> 966 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/lua.pngbin0 -> 941 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/mp3.pngbin0 -> 896 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/mp4.pngbin0 -> 1116 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/odc.pngbin0 -> 946 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/odf.pngbin0 -> 951 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/odg.pngbin0 -> 949 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/odi.pngbin0 -> 944 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/odp.pngbin0 -> 949 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/ods.pngbin0 -> 955 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/odt.pngbin0 -> 949 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/ogg.pngbin0 -> 885 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/ogv.pngbin0 -> 1106 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/pas.pngbin0 -> 945 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/pdf.pngbin0 -> 1003 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/php.pngbin0 -> 952 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/pl.pngbin0 -> 936 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/png.pngbin0 -> 877 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/ppt.pngbin0 -> 850 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/pptx.pngbin0 -> 866 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/ps.pngbin0 -> 996 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/py.pngbin0 -> 942 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/rar.pngbin0 -> 914 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/rb.pngbin0 -> 936 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/rpm.pngbin0 -> 920 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/rtf.pngbin0 -> 738 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/sh.pngbin0 -> 941 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/sql.pngbin0 -> 664 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/svg.pngbin0 -> 980 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/swf.pngbin0 -> 1173 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/sxc.pngbin0 -> 964 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/sxd.pngbin0 -> 965 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/sxi.pngbin0 -> 962 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/sxw.pngbin0 -> 968 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/tar.pngbin0 -> 914 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/tgz.pngbin0 -> 919 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/txt.pngbin0 -> 661 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/wav.pngbin0 -> 888 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/webm.pngbin0 -> 1210 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/xls.pngbin0 -> 1124 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/xlsx.pngbin0 -> 1131 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/xml.pngbin0 -> 560 bytes
-rw-r--r--platform/www/lib/images/fileicons/32x32/zip.pngbin0 -> 914 bytes
-rw-r--r--platform/www/lib/images/fileicons/7z.pngbin0 -> 375 bytes
-rw-r--r--platform/www/lib/images/fileicons/README2
-rw-r--r--platform/www/lib/images/fileicons/asm.pngbin0 -> 379 bytes
-rw-r--r--platform/www/lib/images/fileicons/bash.pngbin0 -> 378 bytes
-rw-r--r--platform/www/lib/images/fileicons/bz2.pngbin0 -> 378 bytes
-rw-r--r--platform/www/lib/images/fileicons/c.pngbin0 -> 369 bytes
-rw-r--r--platform/www/lib/images/fileicons/cc.pngbin0 -> 369 bytes
-rw-r--r--platform/www/lib/images/fileicons/conf.pngbin0 -> 370 bytes
-rw-r--r--platform/www/lib/images/fileicons/cpp.pngbin0 -> 377 bytes
-rw-r--r--platform/www/lib/images/fileicons/cs.pngbin0 -> 374 bytes
-rw-r--r--platform/www/lib/images/fileicons/csh.pngbin0 -> 378 bytes
-rw-r--r--platform/www/lib/images/fileicons/css.pngbin0 -> 374 bytes
-rw-r--r--platform/www/lib/images/fileicons/csv.pngbin0 -> 371 bytes
-rw-r--r--platform/www/lib/images/fileicons/deb.pngbin0 -> 376 bytes
-rw-r--r--platform/www/lib/images/fileicons/diff.pngbin0 -> 376 bytes
-rw-r--r--platform/www/lib/images/fileicons/doc.pngbin0 -> 372 bytes
-rw-r--r--platform/www/lib/images/fileicons/docx.pngbin0 -> 375 bytes
-rw-r--r--platform/www/lib/images/fileicons/file.pngbin0 -> 249 bytes
-rw-r--r--platform/www/lib/images/fileicons/gif.pngbin0 -> 374 bytes
-rw-r--r--platform/www/lib/images/fileicons/gz.pngbin0 -> 374 bytes
-rw-r--r--platform/www/lib/images/fileicons/h.pngbin0 -> 368 bytes
-rw-r--r--platform/www/lib/images/fileicons/hpp.pngbin0 -> 376 bytes
-rw-r--r--platform/www/lib/images/fileicons/htm.pngbin0 -> 375 bytes
-rw-r--r--platform/www/lib/images/fileicons/html.pngbin0 -> 375 bytes
-rw-r--r--platform/www/lib/images/fileicons/ico.pngbin0 -> 372 bytes
-rw-r--r--platform/www/lib/images/fileicons/index.php59
-rw-r--r--platform/www/lib/images/fileicons/java.pngbin0 -> 376 bytes
-rw-r--r--platform/www/lib/images/fileicons/jpeg.pngbin0 -> 376 bytes
-rw-r--r--platform/www/lib/images/fileicons/jpg.pngbin0 -> 376 bytes
-rw-r--r--platform/www/lib/images/fileicons/js.pngbin0 -> 374 bytes
-rw-r--r--platform/www/lib/images/fileicons/json.pngbin0 -> 379 bytes
-rw-r--r--platform/www/lib/images/fileicons/lua.pngbin0 -> 374 bytes
-rw-r--r--platform/www/lib/images/fileicons/mp3.pngbin0 -> 378 bytes
-rw-r--r--platform/www/lib/images/fileicons/mp4.pngbin0 -> 377 bytes
-rw-r--r--platform/www/lib/images/fileicons/odc.pngbin0 -> 369 bytes
-rw-r--r--platform/www/lib/images/fileicons/odf.pngbin0 -> 373 bytes
-rw-r--r--platform/www/lib/images/fileicons/odg.pngbin0 -> 370 bytes
-rw-r--r--platform/www/lib/images/fileicons/odi.pngbin0 -> 371 bytes
-rw-r--r--platform/www/lib/images/fileicons/odp.pngbin0 -> 374 bytes
-rw-r--r--platform/www/lib/images/fileicons/ods.pngbin0 -> 373 bytes
-rw-r--r--platform/www/lib/images/fileicons/odt.pngbin0 -> 372 bytes
-rw-r--r--platform/www/lib/images/fileicons/ogg.pngbin0 -> 373 bytes
-rw-r--r--platform/www/lib/images/fileicons/ogv.pngbin0 -> 376 bytes
-rw-r--r--platform/www/lib/images/fileicons/pas.pngbin0 -> 380 bytes
-rw-r--r--platform/www/lib/images/fileicons/pdf.pngbin0 -> 377 bytes
-rw-r--r--platform/www/lib/images/fileicons/php.pngbin0 -> 376 bytes
-rw-r--r--platform/www/lib/images/fileicons/pl.pngbin0 -> 372 bytes
-rw-r--r--platform/www/lib/images/fileicons/png.pngbin0 -> 375 bytes
-rw-r--r--platform/www/lib/images/fileicons/ppt.pngbin0 -> 375 bytes
-rw-r--r--platform/www/lib/images/fileicons/pptx.pngbin0 -> 375 bytes
-rw-r--r--platform/www/lib/images/fileicons/ps.pngbin0 -> 377 bytes
-rw-r--r--platform/www/lib/images/fileicons/py.pngbin0 -> 374 bytes
-rw-r--r--platform/www/lib/images/fileicons/rar.pngbin0 -> 377 bytes
-rw-r--r--platform/www/lib/images/fileicons/rb.pngbin0 -> 375 bytes
-rw-r--r--platform/www/lib/images/fileicons/rpm.pngbin0 -> 374 bytes
-rw-r--r--platform/www/lib/images/fileicons/rtf.pngbin0 -> 376 bytes
-rw-r--r--platform/www/lib/images/fileicons/sh.pngbin0 -> 375 bytes
-rw-r--r--platform/www/lib/images/fileicons/sql.pngbin0 -> 373 bytes
-rw-r--r--platform/www/lib/images/fileicons/svg.pngbin0 -> 437 bytes
-rw-r--r--platform/www/lib/images/fileicons/swf.pngbin0 -> 379 bytes
-rw-r--r--platform/www/lib/images/fileicons/sxc.pngbin0 -> 377 bytes
-rw-r--r--platform/www/lib/images/fileicons/sxd.pngbin0 -> 377 bytes
-rw-r--r--platform/www/lib/images/fileicons/sxi.pngbin0 -> 377 bytes
-rw-r--r--platform/www/lib/images/fileicons/sxw.pngbin0 -> 376 bytes
-rw-r--r--platform/www/lib/images/fileicons/tar.pngbin0 -> 377 bytes
-rw-r--r--platform/www/lib/images/fileicons/tgz.pngbin0 -> 377 bytes
-rw-r--r--platform/www/lib/images/fileicons/txt.pngbin0 -> 371 bytes
-rw-r--r--platform/www/lib/images/fileicons/wav.pngbin0 -> 375 bytes
-rw-r--r--platform/www/lib/images/fileicons/webm.pngbin0 -> 378 bytes
-rw-r--r--platform/www/lib/images/fileicons/xls.pngbin0 -> 378 bytes
-rw-r--r--platform/www/lib/images/fileicons/xlsx.pngbin0 -> 379 bytes
-rw-r--r--platform/www/lib/images/fileicons/xml.pngbin0 -> 376 bytes
-rw-r--r--platform/www/lib/images/fileicons/zip.pngbin0 -> 377 bytes
-rw-r--r--platform/www/lib/images/history.pngbin0 -> 149 bytes
-rw-r--r--platform/www/lib/images/icon-list.pngbin0 -> 584 bytes
-rw-r--r--platform/www/lib/images/icon-sort.pngbin0 -> 211 bytes
-rw-r--r--platform/www/lib/images/index.html11
-rw-r--r--platform/www/lib/images/info.pngbin0 -> 721 bytes
-rw-r--r--platform/www/lib/images/interwiki.pngbin0 -> 442 bytes
-rw-r--r--platform/www/lib/images/interwiki/amazon.de.gifbin0 -> 132 bytes
-rw-r--r--platform/www/lib/images/interwiki/amazon.gifbin0 -> 132 bytes
-rw-r--r--platform/www/lib/images/interwiki/amazon.uk.gifbin0 -> 132 bytes
-rw-r--r--platform/www/lib/images/interwiki/callto.gifbin0 -> 177 bytes
-rw-r--r--platform/www/lib/images/interwiki/doku.gifbin0 -> 188 bytes
-rw-r--r--platform/www/lib/images/interwiki/google.gifbin0 -> 170 bytes
-rw-r--r--platform/www/lib/images/interwiki/paypal.gifbin0 -> 139 bytes
-rw-r--r--platform/www/lib/images/interwiki/phpfn.gifbin0 -> 164 bytes
-rw-r--r--platform/www/lib/images/interwiki/skype.gifbin0 -> 142 bytes
-rw-r--r--platform/www/lib/images/interwiki/tel.gifbin0 -> 177 bytes
-rw-r--r--platform/www/lib/images/interwiki/user.pngbin0 -> 684 bytes
-rw-r--r--platform/www/lib/images/interwiki/wp.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/interwiki/wpde.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/interwiki/wpes.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/interwiki/wpfr.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/interwiki/wpjp.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/interwiki/wpmeta.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/interwiki/wppl.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/larger.gifbin0 -> 87 bytes
-rw-r--r--platform/www/lib/images/license/badge/cc-by-nc-nd.pngbin0 -> 1456 bytes
-rw-r--r--platform/www/lib/images/license/badge/cc-by-nc-sa.pngbin0 -> 1567 bytes
-rw-r--r--platform/www/lib/images/license/badge/cc-by-nc.pngbin0 -> 1401 bytes
-rw-r--r--platform/www/lib/images/license/badge/cc-by-nd.pngbin0 -> 1261 bytes
-rw-r--r--platform/www/lib/images/license/badge/cc-by-sa.pngbin0 -> 1407 bytes
-rw-r--r--platform/www/lib/images/license/badge/cc-by.pngbin0 -> 1186 bytes
-rw-r--r--platform/www/lib/images/license/badge/cc-zero.pngbin0 -> 1182 bytes
-rw-r--r--platform/www/lib/images/license/badge/cc.pngbin0 -> 846 bytes
-rw-r--r--platform/www/lib/images/license/badge/gnufdl.pngbin0 -> 1649 bytes
-rw-r--r--platform/www/lib/images/license/badge/publicdomain.pngbin0 -> 1326 bytes
-rw-r--r--platform/www/lib/images/license/button/cc-by-nc-nd.pngbin0 -> 391 bytes
-rw-r--r--platform/www/lib/images/license/button/cc-by-nc-sa.pngbin0 -> 396 bytes
-rw-r--r--platform/www/lib/images/license/button/cc-by-nc.pngbin0 -> 381 bytes
-rw-r--r--platform/www/lib/images/license/button/cc-by-nd.pngbin0 -> 382 bytes
-rw-r--r--platform/www/lib/images/license/button/cc-by-sa.pngbin0 -> 379 bytes
-rw-r--r--platform/www/lib/images/license/button/cc-by.pngbin0 -> 364 bytes
-rw-r--r--platform/www/lib/images/license/button/cc-zero.pngbin0 -> 381 bytes
-rw-r--r--platform/www/lib/images/license/button/cc.pngbin0 -> 391 bytes
-rw-r--r--platform/www/lib/images/license/button/gnufdl.pngbin0 -> 497 bytes
-rw-r--r--platform/www/lib/images/license/button/publicdomain.pngbin0 -> 364 bytes
-rw-r--r--platform/www/lib/images/magnifier.pngbin0 -> 565 bytes
-rw-r--r--platform/www/lib/images/media_align_center.pngbin0 -> 249 bytes
-rw-r--r--platform/www/lib/images/media_align_left.pngbin0 -> 247 bytes
-rw-r--r--platform/www/lib/images/media_align_noalign.pngbin0 -> 218 bytes
-rw-r--r--platform/www/lib/images/media_align_right.pngbin0 -> 250 bytes
-rw-r--r--platform/www/lib/images/media_link_direct.pngbin0 -> 714 bytes
-rw-r--r--platform/www/lib/images/media_link_displaylnk.pngbin0 -> 304 bytes
-rw-r--r--platform/www/lib/images/media_link_lnk.pngbin0 -> 578 bytes
-rw-r--r--platform/www/lib/images/media_link_nolnk.pngbin0 -> 452 bytes
-rw-r--r--platform/www/lib/images/media_size_large.pngbin0 -> 100 bytes
-rw-r--r--platform/www/lib/images/media_size_medium.pngbin0 -> 226 bytes
-rw-r--r--platform/www/lib/images/media_size_original.pngbin0 -> 210 bytes
-rw-r--r--platform/www/lib/images/media_size_small.pngbin0 -> 206 bytes
-rw-r--r--platform/www/lib/images/mediamanager.pngbin0 -> 455 bytes
-rw-r--r--platform/www/lib/images/menu/00-default_checkbox-blank-circle-outline.svg1
-rw-r--r--platform/www/lib/images/menu/01-edit_pencil.svg1
-rw-r--r--platform/www/lib/images/menu/02-create_pencil.svg1
-rw-r--r--platform/www/lib/images/menu/03-draft_android-studio.svg1
-rw-r--r--platform/www/lib/images/menu/04-show_file-document.svg1
-rw-r--r--platform/www/lib/images/menu/05-source_file-xml.svg1
-rw-r--r--platform/www/lib/images/menu/06-revert_replay.svg1
-rw-r--r--platform/www/lib/images/menu/07-revisions_history.svg1
-rw-r--r--platform/www/lib/images/menu/08-backlink_link-variant.svg1
-rw-r--r--platform/www/lib/images/menu/09-subscribe_email-outline.svg1
-rw-r--r--platform/www/lib/images/menu/10-top_arrow-up.svg1
-rw-r--r--platform/www/lib/images/menu/11-mediamanager_folder-image.svg1
-rw-r--r--platform/www/lib/images/menu/12-back_arrow-left.svg1
-rw-r--r--platform/www/lib/images/menu/account-card-details.svg1
-rw-r--r--platform/www/lib/images/menu/account-plus.svg1
-rw-r--r--platform/www/lib/images/menu/calendar-clock.svg1
-rw-r--r--platform/www/lib/images/menu/file-tree.svg1
-rw-r--r--platform/www/lib/images/menu/folder-multiple-image.svg1
-rw-r--r--platform/www/lib/images/menu/lock-reset.svg1
-rw-r--r--platform/www/lib/images/menu/login.svg1
-rw-r--r--platform/www/lib/images/menu/logout.svg1
-rw-r--r--platform/www/lib/images/menu/settings.svg1
-rw-r--r--platform/www/lib/images/minus.gifbin0 -> 85 bytes
-rw-r--r--platform/www/lib/images/notify.pngbin0 -> 735 bytes
-rw-r--r--platform/www/lib/images/ns.pngbin0 -> 799 bytes
-rw-r--r--platform/www/lib/images/open.pngbin0 -> 107 bytes
-rw-r--r--platform/www/lib/images/page.pngbin0 -> 582 bytes
-rw-r--r--platform/www/lib/images/plus.gifbin0 -> 88 bytes
-rw-r--r--platform/www/lib/images/resizecol.pngbin0 -> 148 bytes
-rw-r--r--platform/www/lib/images/smaller.gifbin0 -> 86 bytes
-rw-r--r--platform/www/lib/images/smileys/delete.gifbin0 -> 448 bytes
-rw-r--r--platform/www/lib/images/smileys/facepalm.gifbin0 -> 185 bytes
-rw-r--r--platform/www/lib/images/smileys/fixme.gifbin0 -> 450 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_arrow.gifbin0 -> 170 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_biggrin.gifbin0 -> 172 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_confused.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_cool.gifbin0 -> 172 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_cry.gifbin0 -> 424 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_doubt.gifbin0 -> 178 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_doubt2.gifbin0 -> 180 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_eek.gifbin0 -> 170 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_evil.gifbin0 -> 188 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_exclaim.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_frown.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_fun.gifbin0 -> 179 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_idea.gifbin0 -> 176 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_kaddi.gifbin0 -> 179 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_lol.gifbin0 -> 344 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_mrgreen.gifbin0 -> 168 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_neutral.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_question.gifbin0 -> 182 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_razz.gifbin0 -> 176 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_redface.gifbin0 -> 669 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_rolleyes.gifbin0 -> 471 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_sad.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_silenced.gifbin0 -> 177 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_smile.gifbin0 -> 174 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_smile2.gifbin0 -> 174 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_surprised.gifbin0 -> 174 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_twisted.gifbin0 -> 180 bytes
-rw-r--r--platform/www/lib/images/smileys/icon_wink.gifbin0 -> 170 bytes
-rw-r--r--platform/www/lib/images/smileys/index.php53
-rw-r--r--platform/www/lib/images/success.pngbin0 -> 725 bytes
-rw-r--r--platform/www/lib/images/throbber.gifbin0 -> 746 bytes
-rw-r--r--platform/www/lib/images/toolbar/bold.pngbin0 -> 249 bytes
-rw-r--r--platform/www/lib/images/toolbar/chars.pngbin0 -> 493 bytes
-rw-r--r--platform/www/lib/images/toolbar/h.pngbin0 -> 257 bytes
-rw-r--r--platform/www/lib/images/toolbar/h1.pngbin0 -> 287 bytes
-rw-r--r--platform/www/lib/images/toolbar/h2.pngbin0 -> 319 bytes
-rw-r--r--platform/www/lib/images/toolbar/h3.pngbin0 -> 320 bytes
-rw-r--r--platform/www/lib/images/toolbar/h4.pngbin0 -> 310 bytes
-rw-r--r--platform/www/lib/images/toolbar/h5.pngbin0 -> 318 bytes
-rw-r--r--platform/www/lib/images/toolbar/hequal.pngbin0 -> 306 bytes
-rw-r--r--platform/www/lib/images/toolbar/hminus.pngbin0 -> 403 bytes
-rw-r--r--platform/www/lib/images/toolbar/hplus.pngbin0 -> 391 bytes
-rw-r--r--platform/www/lib/images/toolbar/hr.pngbin0 -> 251 bytes
-rw-r--r--platform/www/lib/images/toolbar/image.pngbin0 -> 539 bytes
-rw-r--r--platform/www/lib/images/toolbar/italic.pngbin0 -> 239 bytes
-rw-r--r--platform/www/lib/images/toolbar/link.pngbin0 -> 402 bytes
-rw-r--r--platform/www/lib/images/toolbar/linkextern.pngbin0 -> 902 bytes
-rw-r--r--platform/www/lib/images/toolbar/mono.pngbin0 -> 293 bytes
-rw-r--r--platform/www/lib/images/toolbar/ol.pngbin0 -> 302 bytes
-rw-r--r--platform/www/lib/images/toolbar/sig.pngbin0 -> 471 bytes
-rw-r--r--platform/www/lib/images/toolbar/smiley.pngbin0 -> 680 bytes
-rw-r--r--platform/www/lib/images/toolbar/strike.pngbin0 -> 316 bytes
-rw-r--r--platform/www/lib/images/toolbar/ul.pngbin0 -> 288 bytes
-rw-r--r--platform/www/lib/images/toolbar/underline.pngbin0 -> 297 bytes
-rw-r--r--platform/www/lib/images/trash.pngbin0 -> 423 bytes
-rw-r--r--platform/www/lib/images/unc.pngbin0 -> 290 bytes
-rw-r--r--platform/www/lib/images/up.pngbin0 -> 248 bytes
-rw-r--r--platform/www/lib/images/wrap.gifbin0 -> 86 bytes
-rw-r--r--platform/www/lib/index.html11
-rw-r--r--platform/www/lib/plugins/acl/action.php86
-rw-r--r--platform/www/lib/plugins/acl/admin.php858
-rw-r--r--platform/www/lib/plugins/acl/admin.svg1
-rw-r--r--platform/www/lib/plugins/acl/lang/en/help.txt9
-rw-r--r--platform/www/lib/plugins/acl/lang/en/lang.php46
-rw-r--r--platform/www/lib/plugins/acl/pix/group.pngbin0 -> 699 bytes
-rw-r--r--platform/www/lib/plugins/acl/pix/ns.pngbin0 -> 799 bytes
-rw-r--r--platform/www/lib/plugins/acl/pix/page.pngbin0 -> 582 bytes
-rw-r--r--platform/www/lib/plugins/acl/pix/user.pngbin0 -> 650 bytes
-rw-r--r--platform/www/lib/plugins/acl/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/acl/remote.php102
-rw-r--r--platform/www/lib/plugins/acl/script.js121
-rw-r--r--platform/www/lib/plugins/acl/style.css135
-rw-r--r--platform/www/lib/plugins/action.php2
-rw-r--r--platform/www/lib/plugins/admin.php2
-rw-r--r--platform/www/lib/plugins/auth.php2
-rw-r--r--platform/www/lib/plugins/authad/action.php90
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/adLDAP.php949
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/classes/adLDAPComputers.php153
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/classes/adLDAPContacts.php294
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/classes/adLDAPExchange.php390
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/classes/adLDAPFolders.php179
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/classes/adLDAPGroups.php631
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/classes/adLDAPUsers.php682
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/classes/adLDAPUtils.php268
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/collections/adLDAPCollection.php137
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/collections/adLDAPComputerCollection.php46
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/collections/adLDAPContactCollection.php46
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/collections/adLDAPGroupCollection.php46
-rw-r--r--platform/www/lib/plugins/authad/adLDAP/collections/adLDAPUserCollection.php46
-rw-r--r--platform/www/lib/plugins/authad/auth.php786
-rw-r--r--platform/www/lib/plugins/authad/conf/default.php18
-rw-r--r--platform/www/lib/plugins/authad/conf/metadata.php18
-rw-r--r--platform/www/lib/plugins/authad/lang/en/lang.php15
-rw-r--r--platform/www/lib/plugins/authad/lang/en/settings.php18
-rw-r--r--platform/www/lib/plugins/authad/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/authldap/auth.php698
-rw-r--r--platform/www/lib/plugins/authldap/conf/default.php23
-rw-r--r--platform/www/lib/plugins/authldap/conf/metadata.php22
-rw-r--r--platform/www/lib/plugins/authldap/lang/en/lang.php11
-rw-r--r--platform/www/lib/plugins/authldap/lang/en/settings.php30
-rw-r--r--platform/www/lib/plugins/authldap/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/authpdo/README27
-rw-r--r--platform/www/lib/plugins/authpdo/auth.php826
-rw-r--r--platform/www/lib/plugins/authpdo/conf/default.php118
-rw-r--r--platform/www/lib/plugins/authpdo/conf/metadata.php25
-rw-r--r--platform/www/lib/plugins/authpdo/lang/en/lang.php12
-rw-r--r--platform/www/lib/plugins/authpdo/lang/en/settings.php25
-rw-r--r--platform/www/lib/plugins/authpdo/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/authplain/auth.php494
-rw-r--r--platform/www/lib/plugins/authplain/lang/en/lang.php9
-rw-r--r--platform/www/lib/plugins/authplain/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/cli.php2
-rw-r--r--platform/www/lib/plugins/config/admin.php282
-rw-r--r--platform/www/lib/plugins/config/admin.svg1
-rw-r--r--platform/www/lib/plugins/config/core/ConfigParser.php90
-rw-r--r--platform/www/lib/plugins/config/core/Configuration.php219
-rw-r--r--platform/www/lib/plugins/config/core/Loader.php269
-rw-r--r--platform/www/lib/plugins/config/core/Setting/Setting.php294
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingArray.php105
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingAuthtype.php60
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingCompression.php21
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingDirchoice.php33
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingDisableactions.php23
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingEmail.php58
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingFieldset.php17
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingHidden.php10
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingImConvert.php28
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingLicense.php23
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingMulticheckbox.php163
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingMultichoice.php71
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingNoClass.php12
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingNoDefault.php13
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingNoKnownClass.php11
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingNumeric.php42
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingNumericopt.php25
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingOnoff.php57
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingPassword.php39
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingRegex.php34
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingRenderer.php56
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingSavedir.php26
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingSepchar.php18
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingString.php32
-rw-r--r--platform/www/lib/plugins/config/core/Setting/SettingUndefined.php40
-rw-r--r--platform/www/lib/plugins/config/core/Writer.php116
-rw-r--r--platform/www/lib/plugins/config/images/danger.pngbin0 -> 637 bytes
-rw-r--r--platform/www/lib/plugins/config/images/security.pngbin0 -> 682 bytes
-rw-r--r--platform/www/lib/plugins/config/images/warning.pngbin0 -> 606 bytes
-rw-r--r--platform/www/lib/plugins/config/lang/en/intro.txt7
-rw-r--r--platform/www/lib/plugins/config/lang/en/lang.php277
-rw-r--r--platform/www/lib/plugins/config/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/config/settings/config.metadata.php245
-rw-r--r--platform/www/lib/plugins/config/style.css167
-rw-r--r--platform/www/lib/plugins/extension/action.php82
-rw-r--r--platform/www/lib/plugins/extension/admin.php185
-rw-r--r--platform/www/lib/plugins/extension/admin.svg1
-rw-r--r--platform/www/lib/plugins/extension/all.less37
-rw-r--r--platform/www/lib/plugins/extension/cli.php372
-rw-r--r--platform/www/lib/plugins/extension/helper/extension.php1298
-rw-r--r--platform/www/lib/plugins/extension/helper/gui.php237
-rw-r--r--platform/www/lib/plugins/extension/helper/list.php674
-rw-r--r--platform/www/lib/plugins/extension/helper/repository.php203
-rw-r--r--platform/www/lib/plugins/extension/images/bug.gifbin0 -> 194 bytes
-rw-r--r--platform/www/lib/plugins/extension/images/disabled.pngbin0 -> 1163 bytes
-rw-r--r--platform/www/lib/plugins/extension/images/donate.pngbin0 -> 677 bytes
-rw-r--r--platform/www/lib/plugins/extension/images/down.pngbin0 -> 197 bytes
-rw-r--r--platform/www/lib/plugins/extension/images/enabled.pngbin0 -> 1172 bytes
-rw-r--r--platform/www/lib/plugins/extension/images/icons.xcfbin0 -> 67195 bytes
-rw-r--r--platform/www/lib/plugins/extension/images/license.txt4
-rw-r--r--platform/www/lib/plugins/extension/images/overlay.pngbin0 -> 68 bytes
-rw-r--r--platform/www/lib/plugins/extension/images/plugin.pngbin0 -> 4054 bytes
-rw-r--r--platform/www/lib/plugins/extension/images/tag.pngbin0 -> 341 bytes
-rw-r--r--platform/www/lib/plugins/extension/images/template.pngbin0 -> 5206 bytes
-rw-r--r--platform/www/lib/plugins/extension/images/up.pngbin0 -> 197 bytes
-rw-r--r--platform/www/lib/plugins/extension/images/warning.pngbin0 -> 606 bytes
-rw-r--r--platform/www/lib/plugins/extension/lang/en/intro_install.txt1
-rw-r--r--platform/www/lib/plugins/extension/lang/en/intro_plugins.txt1
-rw-r--r--platform/www/lib/plugins/extension/lang/en/intro_search.txt1
-rw-r--r--platform/www/lib/plugins/extension/lang/en/intro_templates.txt1
-rw-r--r--platform/www/lib/plugins/extension/lang/en/lang.php110
-rw-r--r--platform/www/lib/plugins/extension/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/extension/script.js145
-rw-r--r--platform/www/lib/plugins/extension/style.less386
-rw-r--r--platform/www/lib/plugins/farmer/.github/auto-comment.yml9
-rw-r--r--platform/www/lib/plugins/farmer/.travis.yml15
-rw-r--r--platform/www/lib/plugins/farmer/3rdparty/PHPIco.php248
-rw-r--r--platform/www/lib/plugins/farmer/3rdparty/RingIcon.php186
-rw-r--r--platform/www/lib/plugins/farmer/DokuWikiFarmCore.php375
-rw-r--r--platform/www/lib/plugins/farmer/README27
-rw-r--r--platform/www/lib/plugins/farmer/_animal/conf/acl.auth.php21
-rw-r--r--platform/www/lib/plugins/farmer/_animal/conf/local.php6
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/_dummy0
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/attic/_dummy0
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/cache/_dummy0
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/index/_dummy0
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/locks/_dummy0
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/log/_dummy0
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/media/wiki/dokuwiki-128.pngbin0 -> 33615 bytes
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/media_attic/_dummy0
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/media_meta/_dummy0
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/meta/_dummy0
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/pages/wiki/dokuwiki.txt64
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/pages/wiki/syntax.txt486
-rw-r--r--platform/www/lib/plugins/farmer/_animal/data/tmp/_dummy0
-rw-r--r--platform/www/lib/plugins/farmer/_test/core.test.php40
-rw-r--r--platform/www/lib/plugins/farmer/_test/general.test.php36
-rw-r--r--platform/www/lib/plugins/farmer/_test/getUserLine.test.php86
-rw-r--r--platform/www/lib/plugins/farmer/_test/helper.test.php64
-rw-r--r--platform/www/lib/plugins/farmer/action/ajax.php267
-rw-r--r--platform/www/lib/plugins/farmer/action/disable.php56
-rw-r--r--platform/www/lib/plugins/farmer/action/startup.php90
-rw-r--r--platform/www/lib/plugins/farmer/admin.php115
-rw-r--r--platform/www/lib/plugins/farmer/admin.svg1
-rw-r--r--platform/www/lib/plugins/farmer/admin/config.php126
-rw-r--r--platform/www/lib/plugins/farmer/admin/delete.php95
-rw-r--r--platform/www/lib/plugins/farmer/admin/info.php116
-rw-r--r--platform/www/lib/plugins/farmer/admin/new.php338
-rw-r--r--platform/www/lib/plugins/farmer/admin/plugins.php104
-rw-r--r--platform/www/lib/plugins/farmer/admin/setup.php151
-rw-r--r--platform/www/lib/plugins/farmer/all.less13
-rw-r--r--platform/www/lib/plugins/farmer/conf/default.php9
-rw-r--r--platform/www/lib/plugins/farmer/conf/metadata.php9
-rw-r--r--platform/www/lib/plugins/farmer/css/chosen-sprite.pngbin0 -> 538 bytes
-rw-r--r--platform/www/lib/plugins/farmer/css/chosen.less450
-rw-r--r--platform/www/lib/plugins/farmer/deleted.files11
-rw-r--r--platform/www/lib/plugins/farmer/helper.php334
-rw-r--r--platform/www/lib/plugins/farmer/includes/config.php13
-rw-r--r--platform/www/lib/plugins/farmer/includes/plugins.php12
-rw-r--r--platform/www/lib/plugins/farmer/includes/template.php27
-rw-r--r--platform/www/lib/plugins/farmer/lang/de/lang.php118
-rw-r--r--platform/www/lib/plugins/farmer/lang/de/notfound_404.txt3
-rw-r--r--platform/www/lib/plugins/farmer/lang/de/notfound_list.txt3
-rw-r--r--platform/www/lib/plugins/farmer/lang/de/settings.php13
-rw-r--r--platform/www/lib/plugins/farmer/lang/de/tab_config.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/de/tab_delete.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/de/tab_info.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/de/tab_new.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/de/tab_plugins.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/de/tab_setup.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/lang.php128
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/notfound_404.txt3
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/notfound_list.txt3
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/settings.php13
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/tab_config.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/tab_config_help.txt26
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/tab_delete.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/tab_info.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/tab_new.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/tab_new_help.txt31
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/tab_plugins.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/tab_plugins_help.txt16
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/tab_setup.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/en/tab_setup_help.txt37
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/lang.php109
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/notfound_404.txt3
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/notfound_list.txt4
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/settings.php9
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/tab_config.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/tab_config_help.txt37
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/tab_delete.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/tab_info.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/tab_new.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/tab_new_help.txt43
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/tab_plugins.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/tab_plugins_help.txt22
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/tab_setup.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/fr/tab_setup_help.txt52
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/lang.php106
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/notfound_404.txt3
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/notfound_list.txt3
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/settings.php9
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/tab_config.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/tab_config_help.txt25
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/tab_delete.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/tab_info.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/tab_new.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/tab_new_help.txt38
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/tab_plugins.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/tab_plugins_help.txt17
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/tab_setup.txt1
-rw-r--r--platform/www/lib/plugins/farmer/lang/ja/tab_setup_help.txt38
-rw-r--r--platform/www/lib/plugins/farmer/lang/nl/lang.php20
-rw-r--r--platform/www/lib/plugins/farmer/lang/pl/lang.php102
-rw-r--r--platform/www/lib/plugins/farmer/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/farmer/script.js2
-rw-r--r--platform/www/lib/plugins/farmer/script/jquery.chosen.js1257
-rw-r--r--platform/www/lib/plugins/farmer/script/plugins.js149
-rw-r--r--platform/www/lib/plugins/farmer/style.less104
m---------platform/www/lib/plugins/fastwiki0
-rw-r--r--platform/www/lib/plugins/index.html11
-rw-r--r--platform/www/lib/plugins/info/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/info/syntax.php302
-rw-r--r--platform/www/lib/plugins/markdowku/LICENSE27
-rw-r--r--platform/www/lib/plugins/markdowku/README.md2
-rw-r--r--platform/www/lib/plugins/markdowku/manager.dat2
-rw-r--r--platform/www/lib/plugins/markdowku/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/anchorsinline.php46
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/anchorsreference.php62
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/autolinks.php40
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/blockquotes.php115
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/boldasterisk.php45
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/codeblocks.php63
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/codespans1.php35
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/codespans2.php34
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/codespans3.php34
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/codespans4.php34
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/codespans5.php34
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/escapespecialchars.php94
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/githubcodeblocks.php48
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/headeratx.php57
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/headersetext.php56
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/hr.php47
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/imagesinline.php43
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/imagesreference.php58
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/italicasterisk.php49
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/italicunderline.php56
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/linebreak.php32
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/olists.php98
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/references.php41
-rw-r--r--platform/www/lib/plugins/markdowku/syntax/ulists.php99
-rw-r--r--platform/www/lib/plugins/master.zipbin0 -> 139966 bytes
-rw-r--r--platform/www/lib/plugins/popularity/action.php66
-rw-r--r--platform/www/lib/plugins/popularity/admin.php157
-rw-r--r--platform/www/lib/plugins/popularity/admin.svg1
-rw-r--r--platform/www/lib/plugins/popularity/helper.php292
-rw-r--r--platform/www/lib/plugins/popularity/lang/en/intro.txt11
-rw-r--r--platform/www/lib/plugins/popularity/lang/en/lang.php9
-rw-r--r--platform/www/lib/plugins/popularity/lang/en/submitted.txt3
-rw-r--r--platform/www/lib/plugins/popularity/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/remote.php2
-rw-r--r--platform/www/lib/plugins/revert/admin.php193
-rw-r--r--platform/www/lib/plugins/revert/admin.svg1
-rw-r--r--platform/www/lib/plugins/revert/lang/en/intro.txt3
-rw-r--r--platform/www/lib/plugins/revert/lang/en/lang.php23
-rw-r--r--platform/www/lib/plugins/revert/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/safefnrecode/action.php68
-rw-r--r--platform/www/lib/plugins/safefnrecode/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/styling/README27
-rw-r--r--platform/www/lib/plugins/styling/action.php51
-rw-r--r--platform/www/lib/plugins/styling/admin.php224
-rw-r--r--platform/www/lib/plugins/styling/admin.svg1
-rw-r--r--platform/www/lib/plugins/styling/lang/en/intro.txt2
-rw-r--r--platform/www/lib/plugins/styling/lang/en/lang.php35
-rw-r--r--platform/www/lib/plugins/styling/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/styling/popup.php31
-rw-r--r--platform/www/lib/plugins/styling/script.js92
-rw-r--r--platform/www/lib/plugins/styling/style.less13
-rw-r--r--platform/www/lib/plugins/syntax.php2
-rw-r--r--platform/www/lib/plugins/textinsert/README55
-rw-r--r--platform/www/lib/plugins/textinsert/admin.php292
-rw-r--r--platform/www/lib/plugins/textinsert/conf/default.php5
-rw-r--r--platform/www/lib/plugins/textinsert/conf/metadata.php3
-rw-r--r--platform/www/lib/plugins/textinsert/lang/de/lang.php22
-rw-r--r--platform/www/lib/plugins/textinsert/lang/de/settings.php8
-rw-r--r--platform/www/lib/plugins/textinsert/lang/en/intro.txt16
-rw-r--r--platform/www/lib/plugins/textinsert/lang/en/lang.php31
l---------platform/www/lib/plugins/textinsert/lang/en/macros.php1
-rw-r--r--platform/www/lib/plugins/textinsert/lang/en/settings.php3
-rw-r--r--platform/www/lib/plugins/textinsert/lang/es/intro.txt16
-rw-r--r--platform/www/lib/plugins/textinsert/lang/es/lang.php31
l---------platform/www/lib/plugins/textinsert/lang/es/macros.php1
-rw-r--r--platform/www/lib/plugins/textinsert/lang/es/settings.php3
-rw-r--r--platform/www/lib/plugins/textinsert/lang/fr/intro.txt10
-rw-r--r--platform/www/lib/plugins/textinsert/lang/fr/lang.php25
-rw-r--r--platform/www/lib/plugins/textinsert/lang/fr/settings.php10
-rw-r--r--platform/www/lib/plugins/textinsert/lang/ja/intro.txt16
-rw-r--r--platform/www/lib/plugins/textinsert/lang/ja/lang.php23
-rw-r--r--platform/www/lib/plugins/textinsert/lang/ja/settings.php9
-rw-r--r--platform/www/lib/plugins/textinsert/lang/nl/intro.txt11
-rw-r--r--platform/www/lib/plugins/textinsert/lang/nl/lang.php24
-rw-r--r--platform/www/lib/plugins/textinsert/lang/nl/settings.php8
-rw-r--r--platform/www/lib/plugins/textinsert/lang/pt-br/intro.txt13
-rw-r--r--platform/www/lib/plugins/textinsert/lang/pt-br/lang.php23
-rw-r--r--platform/www/lib/plugins/textinsert/lang/pt-br/settings.php9
-rw-r--r--platform/www/lib/plugins/textinsert/lang/ru/intro.txt10
-rw-r--r--platform/www/lib/plugins/textinsert/lang/ru/lang.php25
-rw-r--r--platform/www/lib/plugins/textinsert/lang/ru/settings.php9
-rw-r--r--platform/www/lib/plugins/textinsert/lang/zh/intro.txt11
-rw-r--r--platform/www/lib/plugins/textinsert/lang/zh/lang.php23
-rw-r--r--platform/www/lib/plugins/textinsert/manager.dat2
-rw-r--r--platform/www/lib/plugins/textinsert/plugin.info.txt9
-rw-r--r--platform/www/lib/plugins/textinsert/syntax.php261
-rw-r--r--platform/www/lib/plugins/textinsert/version2
-rw-r--r--platform/www/lib/plugins/translation/.travis.yml13
-rw-r--r--platform/www/lib/plugins/translation/README25
-rw-r--r--platform/www/lib/plugins/translation/_test/basic.test.php113
-rw-r--r--platform/www/lib/plugins/translation/_test/general.test.php61
-rw-r--r--platform/www/lib/plugins/translation/action.php302
-rw-r--r--platform/www/lib/plugins/translation/admin.php101
-rw-r--r--platform/www/lib/plugins/translation/admin.svg1
-rw-r--r--platform/www/lib/plugins/translation/conf/default.php19
-rw-r--r--platform/www/lib/plugins/translation/conf/metadata.php21
-rw-r--r--platform/www/lib/plugins/translation/flags/af.gifbin0 -> 369 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/ar.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/da.gifbin0 -> 374 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/de.gifbin0 -> 362 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/el.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/en.gifbin0 -> 260 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/es.gifbin0 -> 360 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/et.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/fa.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/fr.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/ga.gifbin0 -> 371 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/he.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/hu.gifbin0 -> 357 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/it.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/ja.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/ko.gifbin0 -> 385 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ad.gifbin0 -> 371 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ae.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ag.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ai.gifbin0 -> 369 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/al.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/am.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/an.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ao.gifbin0 -> 244 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ar.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/as.gifbin0 -> 365 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/at.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/au.gifbin0 -> 378 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/aw.gifbin0 -> 365 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ax.gifbin0 -> 376 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/az.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ba.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bb.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bd.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/be.gifbin0 -> 359 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bf.gifbin0 -> 358 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bg.gifbin0 -> 360 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bh.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bi.gifbin0 -> 374 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bj.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/blankflag.gifbin0 -> 42 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bm.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bn.gifbin0 -> 373 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bo.gifbin0 -> 359 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bs.gifbin0 -> 351 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bt.gifbin0 -> 377 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bv.gifbin0 -> 376 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bw.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/by.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/bz.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ca.gifbin0 -> 376 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/catalonia.gifbin0 -> 238 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cc.gifbin0 -> 371 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cd.gifbin0 -> 243 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cf.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cg.gifbin0 -> 359 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ch.gifbin0 -> 332 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ci.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ck.gifbin0 -> 362 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cl.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cm.gifbin0 -> 369 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/co.gifbin0 -> 353 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cr.gifbin0 -> 359 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cs.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cu.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cv.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cx.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cy.gifbin0 -> 365 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/cz.gifbin0 -> 362 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/dj.gifbin0 -> 369 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/dm.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/do.gifbin0 -> 362 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/dz.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ec.gifbin0 -> 362 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/eg.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/eh.gifbin0 -> 359 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/england.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/er.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/et.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/europeanunion.gifbin0 -> 171 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/fam.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/fi.gifbin0 -> 371 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/fj.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/fk.gifbin0 -> 372 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/fm.gifbin0 -> 377 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/fo.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ga.gifbin0 -> 359 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gd.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ge.gifbin0 -> 379 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gf.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gh.gifbin0 -> 358 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gi.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gl.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gm.gifbin0 -> 362 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gn.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gp.gifbin0 -> 357 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gq.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gs.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gt.gifbin0 -> 374 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gu.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gw.gifbin0 -> 358 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/gy.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/hk.gifbin0 -> 373 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/hm.gifbin0 -> 378 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/hn.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/hr.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ht.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/id.gifbin0 -> 362 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/in.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/io.gifbin0 -> 373 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/iq.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/is.gifbin0 -> 373 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ja.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/jm.gifbin0 -> 365 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/jo.gifbin0 -> 360 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ke.gifbin0 -> 360 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/kg.gifbin0 -> 373 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/kh.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ki.gifbin0 -> 371 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/km.gifbin0 -> 358 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/kn.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ko.gifbin0 -> 385 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/kp.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/kw.gifbin0 -> 362 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ky.gifbin0 -> 373 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/kz.gifbin0 -> 374 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/la.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/lb.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/lc.gifbin0 -> 259 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/li.gifbin0 -> 359 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/lk.gifbin0 -> 377 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/lr.gifbin0 -> 360 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ls.gifbin0 -> 369 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/lt.gifbin0 -> 362 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/lu.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/lv.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ly.gifbin0 -> 362 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ma.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mc.gifbin0 -> 359 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/md.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/me.gifbin0 -> 238 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mg.gifbin0 -> 372 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mh.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mk.gifbin0 -> 382 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ml.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mm.gifbin0 -> 365 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mn.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mo.gifbin0 -> 378 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mp.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mq.gifbin0 -> 379 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mr.gifbin0 -> 377 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ms.gifbin0 -> 371 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mt.gifbin0 -> 369 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mu.gifbin0 -> 358 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mv.gifbin0 -> 372 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mw.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mx.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/my.gifbin0 -> 375 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/mz.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/na.gifbin0 -> 371 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/nc.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ne.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/nf.gifbin0 -> 375 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ng.gifbin0 -> 371 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ni.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/np.gifbin0 -> 302 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/nr.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/nu.gifbin0 -> 369 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/nz.gifbin0 -> 369 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/om.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/pa.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/pe.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/pf.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/pg.gifbin0 -> 360 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ph.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/pk.gifbin0 -> 377 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/pl.gifbin0 -> 360 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/pm.gifbin0 -> 374 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/pn.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/pr.gifbin0 -> 369 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ps.gifbin0 -> 358 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/pw.gifbin0 -> 374 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/py.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/qa.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/re.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/rs.gifbin0 -> 238 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/rw.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sb.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sc.gifbin0 -> 357 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/scotland.gifbin0 -> 378 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sd.gifbin0 -> 355 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sg.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sh.gifbin0 -> 371 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/si.gifbin0 -> 362 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sj.gifbin0 -> 376 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sk.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sl.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sm.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sn.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/so.gifbin0 -> 376 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sr.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/st.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sv.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sy.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/sz.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tc.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/td.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tf.gifbin0 -> 365 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tg.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tj.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tk.gifbin0 -> 372 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tl.gifbin0 -> 360 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tm.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tn.gifbin0 -> 375 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/to.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tt.gifbin0 -> 377 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tv.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tw.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/tz.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ua.gifbin0 -> 360 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ug.gifbin0 -> 359 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/um.gifbin0 -> 371 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/us.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/uy.gifbin0 -> 373 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/uz.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/va.gifbin0 -> 369 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/vc.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ve.gifbin0 -> 364 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/vg.gifbin0 -> 368 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/vi.gifbin0 -> 376 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/vu.gifbin0 -> 365 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/wales.gifbin0 -> 372 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/wf.gifbin0 -> 377 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ws.gifbin0 -> 365 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/ye.gifbin0 -> 356 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/yt.gifbin0 -> 382 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/za.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/zm.gifbin0 -> 358 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/more/zw.gifbin0 -> 365 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/nl.gifbin0 -> 360 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/no.gifbin0 -> 376 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/pt-br.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/pt.gifbin0 -> 369 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/ro.gifbin0 -> 363 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/ru.gifbin0 -> 361 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/sv.gifbin0 -> 367 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/th.gifbin0 -> 360 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/tr.gifbin0 -> 371 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/vi.gifbin0 -> 370 bytes
-rw-r--r--platform/www/lib/plugins/translation/flags/zh.gifbin0 -> 366 bytes
-rw-r--r--platform/www/lib/plugins/translation/helper.php446
-rw-r--r--platform/www/lib/plugins/translation/lang/be/lang.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/be/settings.php23
-rw-r--r--platform/www/lib/plugins/translation/lang/be/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/bn/lang.php10
-rw-r--r--platform/www/lib/plugins/translation/lang/bn/settings.php10
-rw-r--r--platform/www/lib/plugins/translation/lang/bn/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/ca/lang.php16
-rw-r--r--platform/www/lib/plugins/translation/lang/ca/settings.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/ca/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/cs/lang.php16
-rw-r--r--platform/www/lib/plugins/translation/lang/cs/settings.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/cs/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/cy/lang.php11
-rw-r--r--platform/www/lib/plugins/translation/lang/cy/settings.php18
-rw-r--r--platform/www/lib/plugins/translation/lang/cy/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/da/lang.php12
-rw-r--r--platform/www/lib/plugins/translation/lang/da/settings.php20
-rw-r--r--platform/www/lib/plugins/translation/lang/da/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/de-informal/lang.php16
-rw-r--r--platform/www/lib/plugins/translation/lang/de-informal/settings.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/de-informal/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/de/lang.php16
-rw-r--r--platform/www/lib/plugins/translation/lang/de/settings.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/de/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/en/lang.php11
-rw-r--r--platform/www/lib/plugins/translation/lang/en/settings.php20
-rw-r--r--platform/www/lib/plugins/translation/lang/en/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/eo/lang.php11
-rw-r--r--platform/www/lib/plugins/translation/lang/eo/settings.php18
-rw-r--r--platform/www/lib/plugins/translation/lang/eo/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/es/lang.php18
-rw-r--r--platform/www/lib/plugins/translation/lang/es/settings.php22
-rw-r--r--platform/www/lib/plugins/translation/lang/es/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/fa/lang.php16
-rw-r--r--platform/www/lib/plugins/translation/lang/fa/settings.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/fa/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/fr/lang.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/fr/settings.php22
-rw-r--r--platform/www/lib/plugins/translation/lang/fr/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/hr/lang.php16
-rw-r--r--platform/www/lib/plugins/translation/lang/hr/settings.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/hr/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/hu/lang.php11
-rw-r--r--platform/www/lib/plugins/translation/lang/hu/settings.php18
-rw-r--r--platform/www/lib/plugins/translation/lang/hu/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/it/lang.php10
-rw-r--r--platform/www/lib/plugins/translation/lang/it/settings.php20
-rw-r--r--platform/www/lib/plugins/translation/lang/it/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/ja/lang.php16
-rw-r--r--platform/www/lib/plugins/translation/lang/ja/settings.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/ja/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/ko/lang.php16
-rw-r--r--platform/www/lib/plugins/translation/lang/ko/settings.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/ko/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/langnames.txt188
-rw-r--r--platform/www/lib/plugins/translation/lang/lv/lang.php11
-rw-r--r--platform/www/lib/plugins/translation/lang/lv/settings.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/lv/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/nl/lang.php17
-rw-r--r--platform/www/lib/plugins/translation/lang/nl/settings.php21
-rw-r--r--platform/www/lib/plugins/translation/lang/nl/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/pt-br/lang.php17
-rw-r--r--platform/www/lib/plugins/translation/lang/pt-br/settings.php21
-rw-r--r--platform/www/lib/plugins/translation/lang/pt-br/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/pt/lang.php11
-rw-r--r--platform/www/lib/plugins/translation/lang/pt/settings.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/ru/lang.php18
-rw-r--r--platform/www/lib/plugins/translation/lang/ru/settings.php21
-rw-r--r--platform/www/lib/plugins/translation/lang/ru/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/sl/lang.php9
-rw-r--r--platform/www/lib/plugins/translation/lang/sl/settings.php18
-rw-r--r--platform/www/lib/plugins/translation/lang/sv/lang.php16
-rw-r--r--platform/www/lib/plugins/translation/lang/sv/settings.php19
-rw-r--r--platform/www/lib/plugins/translation/lang/sv/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/tr/lang.php10
-rw-r--r--platform/www/lib/plugins/translation/lang/tr/settings.php15
-rw-r--r--platform/www/lib/plugins/translation/lang/tr/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/uk/lang.php17
-rw-r--r--platform/www/lib/plugins/translation/lang/uk/settings.php23
-rw-r--r--platform/www/lib/plugins/translation/lang/uk/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/lang/zh-tw/lang.php6
-rw-r--r--platform/www/lib/plugins/translation/lang/zh-tw/settings.php16
-rw-r--r--platform/www/lib/plugins/translation/lang/zh/lang.php18
-rw-r--r--platform/www/lib/plugins/translation/lang/zh/settings.php21
-rw-r--r--platform/www/lib/plugins/translation/lang/zh/totranslate.txt1
-rw-r--r--platform/www/lib/plugins/translation/manager.dat2
-rw-r--r--platform/www/lib/plugins/translation/plugin.info.txt8
-rw-r--r--platform/www/lib/plugins/translation/print.css1
-rw-r--r--platform/www/lib/plugins/translation/script.js20
-rw-r--r--platform/www/lib/plugins/translation/style.css114
-rw-r--r--platform/www/lib/plugins/translation/syntax/notrans.php92
-rw-r--r--platform/www/lib/plugins/translation/syntax/trans.php72
-rw-r--r--platform/www/lib/plugins/usermanager/admin.php1235
-rw-r--r--platform/www/lib/plugins/usermanager/admin.svg1
-rw-r--r--platform/www/lib/plugins/usermanager/images/search.pngbin0 -> 549 bytes
-rw-r--r--platform/www/lib/plugins/usermanager/lang/en/add.txt1
-rw-r--r--platform/www/lib/plugins/usermanager/lang/en/delete.txt1
-rw-r--r--platform/www/lib/plugins/usermanager/lang/en/edit.txt1
-rw-r--r--platform/www/lib/plugins/usermanager/lang/en/import.txt9
-rw-r--r--platform/www/lib/plugins/usermanager/lang/en/intro.txt1
-rw-r--r--platform/www/lib/plugins/usermanager/lang/en/lang.php86
-rw-r--r--platform/www/lib/plugins/usermanager/lang/en/list.txt1
-rw-r--r--platform/www/lib/plugins/usermanager/plugin.info.txt7
-rw-r--r--platform/www/lib/plugins/usermanager/script.js8
-rw-r--r--platform/www/lib/plugins/usermanager/style.css33
-rw-r--r--platform/www/lib/scripts/behaviour.js195
-rw-r--r--platform/www/lib/scripts/compatibility.js42
-rw-r--r--platform/www/lib/scripts/cookie.js71
-rw-r--r--platform/www/lib/scripts/delay.js70
-rw-r--r--platform/www/lib/scripts/edit.js307
-rw-r--r--platform/www/lib/scripts/editor.js205
-rw-r--r--platform/www/lib/scripts/fileuploader.js1249
-rw-r--r--platform/www/lib/scripts/fileuploaderextended.js345
-rw-r--r--platform/www/lib/scripts/helpers.js69
-rw-r--r--platform/www/lib/scripts/hotkeys.js302
-rw-r--r--platform/www/lib/scripts/index.html11
-rw-r--r--platform/www/lib/scripts/index.js16
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.pngbin0 -> 393 bytes
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.pngbin0 -> 265 bytes
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.pngbin0 -> 323 bytes
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.pngbin0 -> 324 bytes
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.pngbin0 -> 390 bytes
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.pngbin0 -> 325 bytes
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.pngbin0 -> 7025 bytes
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.pngbin0 -> 4676 bytes
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.pngbin0 -> 7090 bytes
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.pngbin0 -> 7111 bytes
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.pngbin0 -> 4676 bytes
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui-theme/smoothness.css1311
-rw-r--r--platform/www/lib/scripts/jquery/jquery-ui.min.js13
-rw-r--r--platform/www/lib/scripts/jquery/jquery.cookie.js117
-rw-r--r--platform/www/lib/scripts/jquery/jquery.min.js2
-rwxr-xr-xplatform/www/lib/scripts/jquery/update.sh48
-rw-r--r--platform/www/lib/scripts/jquery/versions3
-rw-r--r--platform/www/lib/scripts/linkwiz.js339
-rw-r--r--platform/www/lib/scripts/locktimer.js151
-rw-r--r--platform/www/lib/scripts/media.js974
-rw-r--r--platform/www/lib/scripts/page.js201
-rw-r--r--platform/www/lib/scripts/qsearch.js191
-rw-r--r--platform/www/lib/scripts/script.js30
-rw-r--r--platform/www/lib/scripts/search.js48
-rw-r--r--platform/www/lib/scripts/textselection.js152
-rw-r--r--platform/www/lib/scripts/toolbar.js282
-rw-r--r--platform/www/lib/scripts/tree.js107
-rw-r--r--platform/www/lib/styles/all.css68
-rw-r--r--platform/www/lib/styles/feed.css63
-rw-r--r--platform/www/lib/styles/geshi.less144
-rw-r--r--platform/www/lib/styles/index.html11
-rw-r--r--platform/www/lib/styles/print.css15
-rw-r--r--platform/www/lib/styles/screen.css96
-rw-r--r--platform/www/lib/tpl/acervus/COPYING339
-rw-r--r--platform/www/lib/tpl/acervus/README.md3
-rw-r--r--platform/www/lib/tpl/acervus/conf/default.php11
-rw-r--r--platform/www/lib/tpl/acervus/conf/metadata.php11
-rw-r--r--platform/www/lib/tpl/acervus/css/basic.less506
-rw-r--r--platform/www/lib/tpl/acervus/css/content.less361
-rw-r--r--platform/www/lib/tpl/acervus/css/design.less301
-rw-r--r--platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.eotbin0 -> 13538 bytes
-rw-r--r--platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.ttfbin0 -> 13268 bytes
-rw-r--r--platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.woffbin0 -> 7228 bytes
-rw-r--r--platform/www/lib/tpl/acervus/css/hacks.css187
-rw-r--r--platform/www/lib/tpl/acervus/css/mobile.less136
-rw-r--r--platform/www/lib/tpl/acervus/css/print.less94
-rw-r--r--platform/www/lib/tpl/acervus/css/responsive.css13
-rw-r--r--platform/www/lib/tpl/acervus/css/structure.less64
-rw-r--r--platform/www/lib/tpl/acervus/detail.php93
-rw-r--r--platform/www/lib/tpl/acervus/images/apple-touch-icon.pngbin0 -> 23590 bytes
-rw-r--r--platform/www/lib/tpl/acervus/images/bg.pngbin0 -> 2948 bytes
-rw-r--r--platform/www/lib/tpl/acervus/images/bg2.pngbin0 -> 9103 bytes
-rw-r--r--platform/www/lib/tpl/acervus/images/bg3.pngbin0 -> 10549 bytes
-rw-r--r--platform/www/lib/tpl/acervus/images/favicon.icobin0 -> 371 bytes
-rw-r--r--platform/www/lib/tpl/acervus/images/ipari-simpleline.pngbin0 -> 11135 bytes
-rw-r--r--platform/www/lib/tpl/acervus/images/top.pngbin0 -> 4105 bytes
-rw-r--r--platform/www/lib/tpl/acervus/lang/de/lang.php15
-rw-r--r--platform/www/lib/tpl/acervus/lang/de/settings.php6
-rw-r--r--platform/www/lib/tpl/acervus/lang/de/style.txt1
-rw-r--r--platform/www/lib/tpl/acervus/lang/en/lang.php13
-rw-r--r--platform/www/lib/tpl/acervus/lang/en/settings.php7
-rw-r--r--platform/www/lib/tpl/acervus/lang/en/style.txt1
-rw-r--r--platform/www/lib/tpl/acervus/lang/es/lang.php5
-rw-r--r--platform/www/lib/tpl/acervus/lang/ko/lang.php15
-rw-r--r--platform/www/lib/tpl/acervus/lang/ko/settings.php7
-rw-r--r--platform/www/lib/tpl/acervus/lang/ko/style.txt1
-rw-r--r--platform/www/lib/tpl/acervus/lang/ru/lang.php12
-rw-r--r--platform/www/lib/tpl/acervus/lang/ru/settings.php3
-rw-r--r--platform/www/lib/tpl/acervus/lang/ru/style.txt1
-rw-r--r--platform/www/lib/tpl/acervus/main.php265
-rw-r--r--platform/www/lib/tpl/acervus/manager.dat2
-rw-r--r--platform/www/lib/tpl/acervus/mediamanager.php46
-rw-r--r--platform/www/lib/tpl/acervus/script.js81
-rw-r--r--platform/www/lib/tpl/acervus/style.ini86
-rw-r--r--platform/www/lib/tpl/acervus/template.info.txt6
-rw-r--r--platform/www/lib/tpl/acervus/tpl_functions.php91
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_admin.less64
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_diff.css137
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_edit.css141
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_fileuploader.css107
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_footnotes.css31
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_forms.css106
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_imgdetail.css38
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_links.css69
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_media_fullscreen.css541
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_media_popup.css208
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_modal.css94
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_recent.css75
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_search.less204
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_tabs.css84
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/_toc.css93
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/basic.less464
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/content.less393
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/design.less354
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/mobile.less332
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/pagetools.less124
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/print.css177
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/structure.less89
-rw-r--r--platform/www/lib/tpl/dokuwiki/css/usertools.less50
-rw-r--r--platform/www/lib/tpl/dokuwiki/detail.php105
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/apple-touch-icon.pngbin0 -> 6336 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/button-css.pngbin0 -> 297 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/button-donate.gifbin0 -> 187 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/button-dw.pngbin0 -> 398 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/button-html5.pngbin0 -> 305 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/button-php.gifbin0 -> 207 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/button-rss.pngbin0 -> 178 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/favicon.icobin0 -> 7406 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/license.txt5
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/logo.pngbin0 -> 3744 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/page-background.svg8
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/page-gradient.pngbin0 -> 209 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools-build.php125
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools-sprite.pngbin0 -> 7759 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/00_default.pngbin0 -> 494 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/01_edit.pngbin0 -> 519 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/02_create.pngbin0 -> 580 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/03_draft.pngbin0 -> 592 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/04_show.pngbin0 -> 321 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/05_source.pngbin0 -> 478 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/06_revert.pngbin0 -> 462 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/07_revisions.pngbin0 -> 769 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/08_backlink.pngbin0 -> 527 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/09_subscribe.pngbin0 -> 374 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/10_top.pngbin0 -> 297 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/11_mediamanager.pngbin0 -> 320 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/12_back.pngbin0 -> 288 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/pagetools/license.txt4
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/search.pngbin0 -> 307 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/toc-arrows.pngbin0 -> 225 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/toc-bullet.pngbin0 -> 113 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/images/usertools.pngbin0 -> 1428 bytes
-rw-r--r--platform/www/lib/tpl/dokuwiki/lang/en/lang.php13
-rw-r--r--platform/www/lib/tpl/dokuwiki/lang/en/style.txt4
-rw-r--r--platform/www/lib/tpl/dokuwiki/main.php87
-rw-r--r--platform/www/lib/tpl/dokuwiki/mediamanager.php44
-rw-r--r--platform/www/lib/tpl/dokuwiki/script.js89
-rw-r--r--platform/www/lib/tpl/dokuwiki/style.ini89
-rw-r--r--platform/www/lib/tpl/dokuwiki/template.info.txt7
-rw-r--r--platform/www/lib/tpl/dokuwiki/tpl_footer.php34
-rw-r--r--platform/www/lib/tpl/dokuwiki/tpl_header.php84
-rw-r--r--platform/www/lib/tpl/index.php71
-rw-r--r--platform/www/vendor/.htaccess7
-rw-r--r--platform/www/vendor/README6
-rw-r--r--platform/www/vendor/autoload.php7
-rw-r--r--platform/www/vendor/aziraphale/email-address-validator/EmailAddressValidator.php183
-rw-r--r--platform/www/vendor/aziraphale/email-address-validator/README.md59
-rw-r--r--platform/www/vendor/composer/ClassLoader.php445
-rw-r--r--platform/www/vendor/composer/LICENSE21
-rw-r--r--platform/www/vendor/composer/autoload_classmap.php35
-rw-r--r--platform/www/vendor/composer/autoload_files.php12
-rw-r--r--platform/www/vendor/composer/autoload_namespaces.php11
-rw-r--r--platform/www/vendor/composer/autoload_psr4.php12
-rw-r--r--platform/www/vendor/composer/autoload_real.php73
-rw-r--r--platform/www/vendor/composer/autoload_static.php98
-rw-r--r--platform/www/vendor/composer/installed.json531
-rw-r--r--platform/www/vendor/geshi/geshi/BUGS29
-rw-r--r--platform/www/vendor/geshi/geshi/CHANGELOG1033
-rw-r--r--platform/www/vendor/geshi/geshi/LICENSE339
-rw-r--r--platform/www/vendor/geshi/geshi/README.md36
-rw-r--r--platform/www/vendor/geshi/geshi/THANKS287
-rw-r--r--platform/www/vendor/geshi/geshi/build.properties.dist1
-rw-r--r--platform/www/vendor/geshi/geshi/build.xml216
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi.php4758
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/4cs.php137
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/6502acme.php228
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/6502kickass.php239
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/6502tasm.php187
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/68000devpac.php166
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/abap.php1407
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/actionscript.php195
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/actionscript3.php471
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/ada.php130
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/aimms.php316
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/algol68.php328
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/apache.php481
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/applescript.php155
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/apt_sources.php153
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/arm.php3316
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/asm.php601
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/asp.php162
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/asymptote.php1850
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/autoconf.php510
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/autohotkey.php371
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/autoit.php1888
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/avisynth.php193
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/awk.php156
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/bascomavr.php183
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/bash.php475
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/basic4gl.php339
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/batch.php228
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/bf.php113
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/biblatex.php200
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/bibtex.php181
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/blitzbasic.php183
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/bnf.php117
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/boo.php215
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/c.php279
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/c_loadrunner.php321
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/c_mac.php225
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/c_winapi.php870
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/caddcl.php124
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/cadlisp.php184
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/ceylon.php171
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/cfdg.php122
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/cfm.php297
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/chaiscript.php138
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/chapel.php169
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/cil.php194
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/clojure.php132
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/cmake.php179
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/cobol.php457
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/coffeescript.php144
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/cpp-qt.php622
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/cpp-winapi.php836
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/cpp.php250
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/csharp.php257
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/css.php944
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/cuesheet.php136
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/d.php250
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/dart.php159
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/dcl.php190
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/dcpu16.php129
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/dcs.php180
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/delphi.php299
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/diff.php194
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/div.php124
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/dos.php225
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/dot.php162
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/e.php206
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/ecmascript.php208
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/eiffel.php393
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/email.php264
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/epc.php152
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/erlang.php439
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/euphoria.php138
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/ezt.php134
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/f1.php149
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/falcon.php217
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/fo.php326
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/fortran.php158
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/freebasic.php139
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/freeswitch.php166
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/fsharp.php211
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/gambas.php212
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/gdb.php194
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/genero.php461
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/genie.php155
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/gettext.php95
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/glsl.php203
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/gml.php367
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/gnuplot.php294
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/go.php373
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/groovy.php1009
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/gwbasic.php151
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/haskell.php195
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/haxe.php158
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/hicest.php106
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/hq9plus.php102
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/html4strict.php188
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/html5.php210
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/icon.php210
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/idl.php121
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/ini.php127
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/inno.php210
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/intercal.php120
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/io.php136
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/ispfpanel.php165
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/j.php188
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/java.php980
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/java5.php1035
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/javascript.php172
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/jcl.php155
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/jquery.php236
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/julia.php171
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/kixtart.php327
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/klonec.php280
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/klonecpp.php308
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/kotlin.php959
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/latex.php221
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/lb.php160
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/ldif.php114
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/lisp.php147
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/llvm.php389
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/locobasic.php128
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/logtalk.php343
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/lolcode.php159
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/lotusformulas.php316
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/lotusscript.php189
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/lscript.php385
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/lsl2.php1276
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/lua.php175
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/m68k.php141
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/magiksf.php191
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/make.php149
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/mapbasic.php906
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/mathematica.php5035
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/matlab.php226
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/mercury.php130
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/metapost.php399
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/mirc.php169
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/mk-61.php106
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/mmix.php191
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/modula2.php134
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/modula3.php133
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/mpasm.php162
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/mxml.php143
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/mysql.php472
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/nagios.php223
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/netrexx.php161
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/newlisp.php189
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/nginx.php873
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/nimrod.php201
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/nsis.php351
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/oberon2.php133
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/objc.php356
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/objeck.php114
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/ocaml-brief.php110
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/ocaml.php185
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/octave.php513
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/oobas.php133
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/oorexx.php169
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/oracle11.php612
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/oracle8.php494
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/oxygene.php155
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/oz.php142
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/parasail.php128
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/parigp.php293
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/pascal.php163
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/pcre.php186
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/per.php300
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/perl.php211
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/perl6.php195
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/pf.php176
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/phix.php439
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/php-brief.php220
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/php.php1115
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/pic16.php139
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/pike.php101
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/pixelbender.php173
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/pli.php198
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/plsql.php254
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/postgresql.php285
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/postscript.php217
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/povray.php198
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/powerbuilder.php417
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/powershell.php275
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/proftpd.php372
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/progress.php483
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/prolog.php141
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/properties.php125
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/providex.php297
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/purebasic.php301
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/pycon.php62
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/pys60.php271
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/python.php242
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/q.php147
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/qbasic.php160
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/qml.php351
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/racket.php964
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/rails.php404
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/rbs.php224
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/rebol.php194
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/reg.php231
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/rexx.php160
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/robots.php98
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/roff.php510
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/rpmspec.php131
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/rsplus.php481
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/ruby.php229
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/rust.php235
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/sas.php288
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/sass.php590
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/scala.php136
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/scheme.php168
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/scilab.php293
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/scl.php148
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/sdlbasic.php163
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/smalltalk.php152
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/smarty.php190
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/spark.php127
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/sparql.php153
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/sql.php168
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/sshconfig.php165
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/standardml.php216
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/stonescript.php305
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/swift.php557
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/systemverilog.php315
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/tcl.php192
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/tclegg.php501
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/teraterm.php352
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/texgraph.php1137
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/text.php82
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/thinbasic.php866
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/tsql.php819
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/twig.php286
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/typoscript.php298
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/unicon.php208
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/upc.php268
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/urbi.php198
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/uscript.php297
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/vala.php149
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/vb.php155
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/vbnet.php180
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/vbscript.php153
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/vedit.php101
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/verilog.php193
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/vhdl.php181
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/vim.php418
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/visualfoxpro.php454
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/visualprolog.php127
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/whitespace.php119
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/whois.php178
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/winbatch.php367
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/wolfram.php967
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/xbasic.php141
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/xml.php155
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/xojo.php279
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/xorg_conf.php122
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/xpp.php434
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/yaml.php149
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/z80.php142
-rw-r--r--platform/www/vendor/geshi/geshi/src/geshi/zxbasic.php148
-rw-r--r--platform/www/vendor/marcusschwarz/lesserphp/HISTORY.md34
-rw-r--r--platform/www/vendor/marcusschwarz/lesserphp/LICENSE661
-rw-r--r--platform/www/vendor/marcusschwarz/lesserphp/README.md97
-rw-r--r--platform/www/vendor/marcusschwarz/lesserphp/lessc.inc.php4019
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/README.md161
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/AtomCreator03.php94
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/AtomCreator10.php164
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/FeedCreator.php273
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/GPXCreator.php49
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/HTMLCreator.php161
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/JSCreator.php44
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/KMLCreator.php106
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/MBOXCreator.php110
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/OPMLCreator.php67
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/PHPCreator.php56
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/PIECreator01.php62
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator091.php197
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator10.php112
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator20.php22
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedDate.php124
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedHtmlField.php59
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedImage.php20
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedItem.php53
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/Element/HtmlDescribable.php37
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/UniversalFeedCreator.php160
-rw-r--r--platform/www/vendor/openpsa/universalfeedcreator/lib/constants.php10
-rw-r--r--platform/www/vendor/paragonie/random_compat/LICENSE22
-rw-r--r--platform/www/vendor/paragonie/random_compat/lib/byte_safe_strings.php195
-rw-r--r--platform/www/vendor/paragonie/random_compat/lib/cast_to_int.php77
-rw-r--r--platform/www/vendor/paragonie/random_compat/lib/error_polyfill.php49
-rw-r--r--platform/www/vendor/paragonie/random_compat/lib/random.php225
-rw-r--r--platform/www/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php91
-rw-r--r--platform/www/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php190
-rw-r--r--platform/www/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php91
-rw-r--r--platform/www/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php93
-rw-r--r--platform/www/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php79
-rw-r--r--platform/www/vendor/paragonie/random_compat/lib/random_int.php204
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/AUTHORS6
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/BACKERS.md8
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/LICENSE20
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/README.md86
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php126
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php2708
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php571
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php1443
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php894
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php688
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php342
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php3201
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php277
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php936
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php460
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php816
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php577
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php1414
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php47
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/File/X509.php5092
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php3787
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php342
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php3173
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php795
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php1645
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php5091
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php351
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php241
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php16
-rw-r--r--platform/www/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf6
-rw-r--r--platform/www/vendor/simplepie/simplepie/CHANGELOG.md134
-rw-r--r--platform/www/vendor/simplepie/simplepie/LICENSE.txt26
-rw-r--r--platform/www/vendor/simplepie/simplepie/README.markdown111
-rw-r--r--platform/www/vendor/simplepie/simplepie/autoloader.php85
-rw-r--r--platform/www/vendor/simplepie/simplepie/idn/LICENCE502
-rw-r--r--platform/www/vendor/simplepie/simplepie/idn/ReadMe.txt123
-rw-r--r--platform/www/vendor/simplepie/simplepie/idn/idna_convert.class.php969
-rw-r--r--platform/www/vendor/simplepie/simplepie/idn/npdata.ser1
-rwxr-xr-xplatform/www/vendor/simplepie/simplepie/library/SimplePie.php3245
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Author.php149
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache.php134
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Base.php113
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/DB.php136
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/File.php164
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Memcache.php180
-rwxr-xr-xplatform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Memcached.php166
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/MySQL.php440
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Redis.php172
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Caption.php198
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Category.php163
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Content/Type/Sniffer.php318
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Copyright.php124
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Core.php56
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Credit.php148
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Decode/HTML/Entities.php610
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Enclosure.php1304
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Exception.php51
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/File.php305
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/HTTP/Parser.php518
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/IRI.php1236
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Item.php2966
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Locator.php424
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Misc.php2262
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Net/IPv6.php269
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Parse/Date.php1025
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Parser.php661
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Rating.php124
-rwxr-xr-xplatform/www/vendor/simplepie/simplepie/library/SimplePie/Registry.php224
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Restriction.php148
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Sanitize.php584
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/Source.php577
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/XML/Declaration/Parser.php359
-rw-r--r--platform/www/vendor/simplepie/simplepie/library/SimplePie/gzdecode.php366
-rw-r--r--platform/www/vendor/splitbrain/php-archive/LICENSE19
-rw-r--r--platform/www/vendor/splitbrain/php-archive/README.md70
-rw-r--r--platform/www/vendor/splitbrain/php-archive/phpunit.xml22
-rw-r--r--platform/www/vendor/splitbrain/php-archive/src/Archive.php135
-rw-r--r--platform/www/vendor/splitbrain/php-archive/src/ArchiveCorruptedException.php10
-rw-r--r--platform/www/vendor/splitbrain/php-archive/src/ArchiveIOException.php10
-rw-r--r--platform/www/vendor/splitbrain/php-archive/src/ArchiveIllegalCompressionException.php10
-rw-r--r--platform/www/vendor/splitbrain/php-archive/src/FileInfo.php340
-rw-r--r--platform/www/vendor/splitbrain/php-archive/src/FileInfoException.php10
-rw-r--r--platform/www/vendor/splitbrain/php-archive/src/Tar.php692
-rw-r--r--platform/www/vendor/splitbrain/php-archive/src/Zip.php895
-rw-r--r--platform/www/vendor/splitbrain/php-cli/LICENSE21
-rw-r--r--platform/www/vendor/splitbrain/php-cli/README.md158
-rw-r--r--platform/www/vendor/splitbrain/php-cli/src/CLI.php362
-rw-r--r--platform/www/vendor/splitbrain/php-cli/src/Colors.php170
-rw-r--r--platform/www/vendor/splitbrain/php-cli/src/Exception.php35
-rw-r--r--platform/www/vendor/splitbrain/php-cli/src/Options.php478
-rw-r--r--platform/www/vendor/splitbrain/php-cli/src/PSR3CLI.php13
-rw-r--r--platform/www/vendor/splitbrain/php-cli/src/TableFormatter.php325
1922 files changed, 270958 insertions, 0 deletions
diff --git a/platform/www/.htaccess b/platform/www/.htaccess
new file mode 100644
index 0000000..7e5ce2a
--- /dev/null
+++ b/platform/www/.htaccess
@@ -0,0 +1,50 @@
+# Options added for farm setup by farmer plugin:
+RewriteEngine On
+RewriteRule ^!([^/]+)/(.*) $2?animal=$1 [QSA,DPI]
+RewriteRule ^!([^/]+)$ ?animal=$1 [QSA,DPI]
+Options +FollowSymLinks
+# end of farm configuration
+
+## You should disable Indexes and MultiViews either here or in the
+## global config. Symlinks maybe needed for URL rewriting.
+#Options -Indexes -MultiViews +FollowSymLinks
+
+## make sure nobody gets the htaccess, README, COPYING or VERSION files
+<Files ~ "^([\._]ht|README$|VERSION$|COPYING$)">
+ <IfModule mod_authz_core.c>
+ Require all denied
+ </IfModule>
+ <IfModule !mod_authz_core.c>
+ Order allow,deny
+ Deny from all
+ </IfModule>
+</Files>
+
+## Don't allow access to git directories
+<IfModule alias_module>
+ RedirectMatch 404 /\.git
+</IfModule>
+
+## Uncomment these rules if you want to have nice URLs using
+## $conf['userewrite'] = 1 - not needed for rewrite mode 2
+#RewriteEngine on
+#
+#RewriteRule ^_media/(.*) lib/exe/fetch.php?media=$1 [QSA,L]
+#RewriteRule ^_detail/(.*) lib/exe/detail.php?media=$1 [QSA,L]
+#RewriteRule ^_export/([^/]+)/(.*) doku.php?do=export_$1&id=$2 [QSA,L]
+#RewriteRule ^$ doku.php [L]
+#RewriteCond %{REQUEST_FILENAME} !-f
+#RewriteCond %{REQUEST_FILENAME} !-d
+#RewriteRule (.*) doku.php?id=$1 [QSA,L]
+#RewriteRule ^index.php$ doku.php
+#
+## Not all installations will require the following line. If you do,
+## change "/dokuwiki" to the path to your dokuwiki directory relative
+## to your document root.
+#RewriteBase /dokuwiki
+#
+## If you enable DokuWikis XML-RPC interface, you should consider to
+## restrict access to it over HTTPS only! Uncomment the following two
+## rules if your server setup allows HTTPS.
+#RewriteCond %{HTTPS} !=on
+#RewriteRule ^lib/exe/xmlrpc.php$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
diff --git a/platform/www/.htaccess.dist b/platform/www/.htaccess.dist
new file mode 100644
index 0000000..3e96a83
--- /dev/null
+++ b/platform/www/.htaccess.dist
@@ -0,0 +1,43 @@
+## You should disable Indexes and MultiViews either here or in the
+## global config. Symlinks maybe needed for URL rewriting.
+#Options -Indexes -MultiViews +FollowSymLinks
+
+## make sure nobody gets the htaccess, README, COPYING or VERSION files
+<Files ~ "^([\._]ht|README$|VERSION$|COPYING$)">
+ <IfModule mod_authz_core.c>
+ Require all denied
+ </IfModule>
+ <IfModule !mod_authz_core.c>
+ Order allow,deny
+ Deny from all
+ </IfModule>
+</Files>
+
+## Don't allow access to git directories
+<IfModule alias_module>
+ RedirectMatch 404 /\.git
+</IfModule>
+
+## Uncomment these rules if you want to have nice URLs using
+## $conf['userewrite'] = 1 - not needed for rewrite mode 2
+#RewriteEngine on
+#
+#RewriteRule ^_media/(.*) lib/exe/fetch.php?media=$1 [QSA,L]
+#RewriteRule ^_detail/(.*) lib/exe/detail.php?media=$1 [QSA,L]
+#RewriteRule ^_export/([^/]+)/(.*) doku.php?do=export_$1&id=$2 [QSA,L]
+#RewriteRule ^$ doku.php [L]
+#RewriteCond %{REQUEST_FILENAME} !-f
+#RewriteCond %{REQUEST_FILENAME} !-d
+#RewriteRule (.*) doku.php?id=$1 [QSA,L]
+#RewriteRule ^index.php$ doku.php
+#
+## Not all installations will require the following line. If you do,
+## change "/dokuwiki" to the path to your dokuwiki directory relative
+## to your document root.
+#RewriteBase /dokuwiki
+#
+## If you enable DokuWikis XML-RPC interface, you should consider to
+## restrict access to it over HTTPS only! Uncomment the following two
+## rules if your server setup allows HTTPS.
+#RewriteCond %{HTTPS} !=on
+#RewriteRule ^lib/exe/xmlrpc.php$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=301]
diff --git a/platform/www/COPYING b/platform/www/COPYING
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/platform/www/COPYING
@@ -0,0 +1,339 @@
+ 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/platform/www/README b/platform/www/README
new file mode 100644
index 0000000..380f353
--- /dev/null
+++ b/platform/www/README
@@ -0,0 +1,10 @@
+All documentation for DokuWiki is available online
+at https://www.dokuwiki.org/
+
+For Installation Instructions see
+https://www.dokuwiki.org/install
+
+DokuWiki - 2004-2020 (c) Andreas Gohr <andi@splitbrain.org>
+ and the DokuWiki Community
+See COPYING and file headers for license info
+
diff --git a/platform/www/VERSION b/platform/www/VERSION
new file mode 100644
index 0000000..a16fdd8
--- /dev/null
+++ b/platform/www/VERSION
@@ -0,0 +1 @@
+2020-07-29 "Hogfather"
diff --git a/platform/www/bin/.htaccess b/platform/www/bin/.htaccess
new file mode 100644
index 0000000..7625314
--- /dev/null
+++ b/platform/www/bin/.htaccess
@@ -0,0 +1,7 @@
+<IfModule mod_authz_core.c>
+ Require all denied
+</IfModule>
+<IfModule !mod_authz_core.c>
+ Order allow,deny
+ Deny from all
+</IfModule>
diff --git a/platform/www/bin/dwpage.php b/platform/www/bin/dwpage.php
new file mode 100755
index 0000000..dee8039
--- /dev/null
+++ b/platform/www/bin/dwpage.php
@@ -0,0 +1,322 @@
+#!/usr/bin/env php
+<?php
+
+use splitbrain\phpcli\CLI;
+use splitbrain\phpcli\Options;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/');
+define('NOSESSION', 1);
+require_once(DOKU_INC . 'inc/init.php');
+
+/**
+ * Checkout and commit pages from the command line while maintaining the history
+ */
+class PageCLI extends CLI {
+
+ protected $force = false;
+ protected $username = '';
+
+ /**
+ * Register options and arguments on the given $options object
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function setup(Options $options) {
+ /* global */
+ $options->registerOption(
+ 'force',
+ 'force obtaining a lock for the page (generally bad idea)',
+ 'f'
+ );
+ $options->registerOption(
+ 'user',
+ 'work as this user. defaults to current CLI user',
+ 'u',
+ 'username'
+ );
+ $options->setHelp(
+ 'Utility to help command line Dokuwiki page editing, allow ' .
+ 'pages to be checked out for editing then committed after changes'
+ );
+
+ /* checkout command */
+ $options->registerCommand(
+ 'checkout',
+ 'Checks out a file from the repository, using the wiki id and obtaining ' .
+ 'a lock for the page. ' . "\n" .
+ 'If a working_file is specified, this is where the page is copied to. ' .
+ 'Otherwise defaults to the same as the wiki page in the current ' .
+ 'working directory.'
+ );
+ $options->registerArgument(
+ 'wikipage',
+ 'The wiki page to checkout',
+ true,
+ 'checkout'
+ );
+ $options->registerArgument(
+ 'workingfile',
+ 'How to name the local checkout',
+ false,
+ 'checkout'
+ );
+
+ /* commit command */
+ $options->registerCommand(
+ 'commit',
+ 'Checks in the working_file into the repository using the specified ' .
+ 'wiki id, archiving the previous version.'
+ );
+ $options->registerArgument(
+ 'workingfile',
+ 'The local file to commit',
+ true,
+ 'commit'
+ );
+ $options->registerArgument(
+ 'wikipage',
+ 'The wiki page to create or update',
+ true,
+ 'commit'
+ );
+ $options->registerOption(
+ 'message',
+ 'Summary describing the change (required)',
+ 'm',
+ 'summary',
+ 'commit'
+ );
+ $options->registerOption(
+ 'trivial',
+ 'minor change',
+ 't',
+ false,
+ 'commit'
+ );
+
+ /* lock command */
+ $options->registerCommand(
+ 'lock',
+ 'Obtains or updates a lock for a wiki page'
+ );
+ $options->registerArgument(
+ 'wikipage',
+ 'The wiki page to lock',
+ true,
+ 'lock'
+ );
+
+ /* unlock command */
+ $options->registerCommand(
+ 'unlock',
+ 'Removes a lock for a wiki page.'
+ );
+ $options->registerArgument(
+ 'wikipage',
+ 'The wiki page to unlock',
+ true,
+ 'unlock'
+ );
+ }
+
+ /**
+ * Your main program
+ *
+ * Arguments and options have been parsed when this is run
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function main(Options $options) {
+ $this->force = $options->getOpt('force', false);
+ $this->username = $options->getOpt('user', $this->getUser());
+
+ $command = $options->getCmd();
+ $args = $options->getArgs();
+ switch($command) {
+ case 'checkout':
+ $wiki_id = array_shift($args);
+ $localfile = array_shift($args);
+ $this->commandCheckout($wiki_id, $localfile);
+ break;
+ case 'commit':
+ $localfile = array_shift($args);
+ $wiki_id = array_shift($args);
+ $this->commandCommit(
+ $localfile,
+ $wiki_id,
+ $options->getOpt('message', ''),
+ $options->getOpt('trivial', false)
+ );
+ break;
+ case 'lock':
+ $wiki_id = array_shift($args);
+ $this->obtainLock($wiki_id);
+ $this->success("$wiki_id locked");
+ break;
+ case 'unlock':
+ $wiki_id = array_shift($args);
+ $this->clearLock($wiki_id);
+ $this->success("$wiki_id unlocked");
+ break;
+ default:
+ echo $options->help();
+ }
+ }
+
+ /**
+ * Check out a file
+ *
+ * @param string $wiki_id
+ * @param string $localfile
+ */
+ protected function commandCheckout($wiki_id, $localfile) {
+ global $conf;
+
+ $wiki_id = cleanID($wiki_id);
+ $wiki_fn = wikiFN($wiki_id);
+
+ if(!file_exists($wiki_fn)) {
+ $this->fatal("$wiki_id does not yet exist");
+ }
+
+ if(empty($localfile)) {
+ $localfile = getcwd() . '/' . \dokuwiki\Utf8\PhpString::basename($wiki_fn);
+ }
+
+ if(!file_exists(dirname($localfile))) {
+ $this->fatal("Directory " . dirname($localfile) . " does not exist");
+ }
+
+ if(stristr(realpath(dirname($localfile)), realpath($conf['datadir'])) !== false) {
+ $this->fatal("Attempt to check out file into data directory - not allowed");
+ }
+
+ $this->obtainLock($wiki_id);
+
+ if(!copy($wiki_fn, $localfile)) {
+ $this->clearLock($wiki_id);
+ $this->fatal("Unable to copy $wiki_fn to $localfile");
+ }
+
+ $this->success("$wiki_id > $localfile");
+ }
+
+ /**
+ * Save a file as a new page revision
+ *
+ * @param string $localfile
+ * @param string $wiki_id
+ * @param string $message
+ * @param bool $minor
+ */
+ protected function commandCommit($localfile, $wiki_id, $message, $minor) {
+ $wiki_id = cleanID($wiki_id);
+ $message = trim($message);
+
+ if(!file_exists($localfile)) {
+ $this->fatal("$localfile does not exist");
+ }
+
+ if(!is_readable($localfile)) {
+ $this->fatal("Cannot read from $localfile");
+ }
+
+ if(!$message) {
+ $this->fatal("Summary message required");
+ }
+
+ $this->obtainLock($wiki_id);
+
+ saveWikiText($wiki_id, file_get_contents($localfile), $message, $minor);
+
+ $this->clearLock($wiki_id);
+
+ $this->success("$localfile > $wiki_id");
+ }
+
+ /**
+ * Lock the given page or exit
+ *
+ * @param string $wiki_id
+ */
+ protected function obtainLock($wiki_id) {
+ if($this->force) $this->deleteLock($wiki_id);
+
+ $_SERVER['REMOTE_USER'] = $this->username;
+
+ if(checklock($wiki_id)) {
+ $this->error("Page $wiki_id is already locked by another user");
+ exit(1);
+ }
+
+ lock($wiki_id);
+
+ if(checklock($wiki_id)) {
+ $this->error("Unable to obtain lock for $wiki_id ");
+ var_dump(checklock($wiki_id));
+ exit(1);
+ }
+ }
+
+ /**
+ * Clear the lock on the given page
+ *
+ * @param string $wiki_id
+ */
+ protected function clearLock($wiki_id) {
+ if($this->force) $this->deleteLock($wiki_id);
+
+ $_SERVER['REMOTE_USER'] = $this->username;
+ if(checklock($wiki_id)) {
+ $this->error("Page $wiki_id is locked by another user");
+ exit(1);
+ }
+
+ unlock($wiki_id);
+
+ if(file_exists(wikiLockFN($wiki_id))) {
+ $this->error("Unable to clear lock for $wiki_id");
+ exit(1);
+ }
+ }
+
+ /**
+ * Forcefully remove a lock on the page given
+ *
+ * @param string $wiki_id
+ */
+ protected function deleteLock($wiki_id) {
+ $wikiLockFN = wikiLockFN($wiki_id);
+
+ if(file_exists($wikiLockFN)) {
+ if(!unlink($wikiLockFN)) {
+ $this->error("Unable to delete $wikiLockFN");
+ exit(1);
+ }
+ }
+ }
+
+ /**
+ * Get the current user's username from the environment
+ *
+ * @return string
+ */
+ protected function getUser() {
+ $user = getenv('USER');
+ if(empty ($user)) {
+ $user = getenv('USERNAME');
+ } else {
+ return $user;
+ }
+ if(empty ($user)) {
+ $user = 'admin';
+ }
+ return $user;
+ }
+}
+
+// Main
+$cli = new PageCLI();
+$cli->run();
diff --git a/platform/www/bin/gittool.php b/platform/www/bin/gittool.php
new file mode 100755
index 0000000..5ebd0c5
--- /dev/null
+++ b/platform/www/bin/gittool.php
@@ -0,0 +1,340 @@
+#!/usr/bin/env php
+<?php
+
+use splitbrain\phpcli\CLI;
+use splitbrain\phpcli\Options;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/');
+define('NOSESSION', 1);
+require_once(DOKU_INC . 'inc/init.php');
+
+/**
+ * Easily manage DokuWiki git repositories
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class GitToolCLI extends CLI {
+
+ /**
+ * Register options and arguments on the given $options object
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function setup(Options $options) {
+ $options->setHelp(
+ "Manage git repositories for DokuWiki and its plugins and templates.\n\n" .
+ "$> ./bin/gittool.php clone gallery template:ach\n" .
+ "$> ./bin/gittool.php repos\n" .
+ "$> ./bin/gittool.php origin -v"
+ );
+
+ $options->registerArgument(
+ 'command',
+ 'Command to execute. See below',
+ true
+ );
+
+ $options->registerCommand(
+ 'clone',
+ 'Tries to install a known plugin or template (prefix with template:) via git. Uses the DokuWiki.org ' .
+ 'plugin repository to find the proper git repository. Multiple extensions can be given as parameters'
+ );
+ $options->registerArgument(
+ 'extension',
+ 'name of the extension to install, prefix with \'template:\' for templates',
+ true,
+ 'clone'
+ );
+
+ $options->registerCommand(
+ 'install',
+ 'The same as clone, but when no git source repository can be found, the extension is installed via ' .
+ 'download'
+ );
+ $options->registerArgument(
+ 'extension',
+ 'name of the extension to install, prefix with \'template:\' for templates',
+ true,
+ 'install'
+ );
+
+ $options->registerCommand(
+ 'repos',
+ 'Lists all git repositories found in this DokuWiki installation'
+ );
+
+ $options->registerCommand(
+ '*',
+ 'Any unknown commands are assumed to be arguments to git and will be executed in all repositories ' .
+ 'found within this DokuWiki installation'
+ );
+ }
+
+ /**
+ * Your main program
+ *
+ * Arguments and options have been parsed when this is run
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function main(Options $options) {
+ $command = $options->getCmd();
+ $args = $options->getArgs();
+ if(!$command) $command = array_shift($args);
+
+ switch($command) {
+ case '':
+ echo $options->help();
+ break;
+ case 'clone':
+ $this->cmdClone($args);
+ break;
+ case 'install':
+ $this->cmdInstall($args);
+ break;
+ case 'repo':
+ case 'repos':
+ $this->cmdRepos();
+ break;
+ default:
+ $this->cmdGit($command, $args);
+ }
+ }
+
+ /**
+ * Tries to install the given extensions using git clone
+ *
+ * @param array $extensions
+ */
+ public function cmdClone($extensions) {
+ $errors = array();
+ $succeeded = array();
+
+ foreach($extensions as $ext) {
+ $repo = $this->getSourceRepo($ext);
+
+ if(!$repo) {
+ $this->error("could not find a repository for $ext");
+ $errors[] = $ext;
+ } else {
+ if($this->cloneExtension($ext, $repo)) {
+ $succeeded[] = $ext;
+ } else {
+ $errors[] = $ext;
+ }
+ }
+ }
+
+ echo "\n";
+ if($succeeded) $this->success('successfully cloned the following extensions: ' . join(', ', $succeeded));
+ if($errors) $this->error('failed to clone the following extensions: ' . join(', ', $errors));
+ }
+
+ /**
+ * Tries to install the given extensions using git clone with fallback to install
+ *
+ * @param array $extensions
+ */
+ public function cmdInstall($extensions) {
+ $errors = array();
+ $succeeded = array();
+
+ foreach($extensions as $ext) {
+ $repo = $this->getSourceRepo($ext);
+
+ if(!$repo) {
+ $this->info("could not find a repository for $ext");
+ if($this->downloadExtension($ext)) {
+ $succeeded[] = $ext;
+ } else {
+ $errors[] = $ext;
+ }
+ } else {
+ if($this->cloneExtension($ext, $repo)) {
+ $succeeded[] = $ext;
+ } else {
+ $errors[] = $ext;
+ }
+ }
+ }
+
+ echo "\n";
+ if($succeeded) $this->success('successfully installed the following extensions: ' . join(', ', $succeeded));
+ if($errors) $this->error('failed to install the following extensions: ' . join(', ', $errors));
+ }
+
+ /**
+ * Executes the given git command in every repository
+ *
+ * @param $cmd
+ * @param $arg
+ */
+ public function cmdGit($cmd, $arg) {
+ $repos = $this->findRepos();
+
+ $shell = array_merge(array('git', $cmd), $arg);
+ $shell = array_map('escapeshellarg', $shell);
+ $shell = join(' ', $shell);
+
+ foreach($repos as $repo) {
+ if(!@chdir($repo)) {
+ $this->error("Could not change into $repo");
+ continue;
+ }
+
+ $this->info("executing $shell in $repo");
+ $ret = 0;
+ system($shell, $ret);
+
+ if($ret == 0) {
+ $this->success("git succeeded in $repo");
+ } else {
+ $this->error("git failed in $repo");
+ }
+ }
+ }
+
+ /**
+ * Simply lists the repositories
+ */
+ public function cmdRepos() {
+ $repos = $this->findRepos();
+ foreach($repos as $repo) {
+ echo "$repo\n";
+ }
+ }
+
+ /**
+ * Install extension from the given download URL
+ *
+ * @param string $ext
+ * @return bool|null
+ */
+ private function downloadExtension($ext) {
+ /** @var helper_plugin_extension_extension $plugin */
+ $plugin = plugin_load('helper', 'extension_extension');
+ if(!$ext) die("extension plugin not available, can't continue");
+
+ $plugin->setExtension($ext);
+
+ $url = $plugin->getDownloadURL();
+ if(!$url) {
+ $this->error("no download URL for $ext");
+ return false;
+ }
+
+ $ok = false;
+ try {
+ $this->info("installing $ext via download from $url");
+ $ok = $plugin->installFromURL($url);
+ } catch(Exception $e) {
+ $this->error($e->getMessage());
+ }
+
+ if($ok) {
+ $this->success("installed $ext via download");
+ return true;
+ } else {
+ $this->success("failed to install $ext via download");
+ return false;
+ }
+ }
+
+ /**
+ * Clones the extension from the given repository
+ *
+ * @param string $ext
+ * @param string $repo
+ * @return bool
+ */
+ private function cloneExtension($ext, $repo) {
+ if(substr($ext, 0, 9) == 'template:') {
+ $target = fullpath(tpl_incdir() . '../' . substr($ext, 9));
+ } else {
+ $target = DOKU_PLUGIN . $ext;
+ }
+
+ $this->info("cloning $ext from $repo to $target");
+ $ret = 0;
+ system("git clone $repo $target", $ret);
+ if($ret === 0) {
+ $this->success("cloning of $ext succeeded");
+ return true;
+ } else {
+ $this->error("cloning of $ext failed");
+ return false;
+ }
+ }
+
+ /**
+ * Returns all git repositories in this DokuWiki install
+ *
+ * Looks in root, template and plugin directories only.
+ *
+ * @return array
+ */
+ private function findRepos() {
+ $this->info('Looking for .git directories');
+ $data = array_merge(
+ glob(DOKU_INC . '.git', GLOB_ONLYDIR),
+ glob(DOKU_PLUGIN . '*/.git', GLOB_ONLYDIR),
+ glob(fullpath(tpl_incdir() . '../') . '/*/.git', GLOB_ONLYDIR)
+ );
+
+ if(!$data) {
+ $this->error('Found no .git directories');
+ } else {
+ $this->success('Found ' . count($data) . ' .git directories');
+ }
+ $data = array_map('fullpath', array_map('dirname', $data));
+ return $data;
+ }
+
+ /**
+ * Returns the repository for the given extension
+ *
+ * @param $extension
+ * @return false|string
+ */
+ private function getSourceRepo($extension) {
+ /** @var helper_plugin_extension_extension $ext */
+ $ext = plugin_load('helper', 'extension_extension');
+ if(!$ext) die("extension plugin not available, can't continue");
+
+ $ext->setExtension($extension);
+
+ $repourl = $ext->getSourcerepoURL();
+ if(!$repourl) return false;
+
+ // match github repos
+ if(preg_match('/github\.com\/([^\/]+)\/([^\/]+)/i', $repourl, $m)) {
+ $user = $m[1];
+ $repo = $m[2];
+ return 'https://github.com/' . $user . '/' . $repo . '.git';
+ }
+
+ // match gitorious repos
+ if(preg_match('/gitorious.org\/([^\/]+)\/([^\/]+)?/i', $repourl, $m)) {
+ $user = $m[1];
+ $repo = $m[2];
+ if(!$repo) $repo = $user;
+
+ return 'https://git.gitorious.org/' . $user . '/' . $repo . '.git';
+ }
+
+ // match bitbucket repos - most people seem to use mercurial there though
+ if(preg_match('/bitbucket\.org\/([^\/]+)\/([^\/]+)/i', $repourl, $m)) {
+ $user = $m[1];
+ $repo = $m[2];
+ return 'https://bitbucket.org/' . $user . '/' . $repo . '.git';
+ }
+
+ return false;
+ }
+}
+
+// Main
+$cli = new GitToolCLI();
+$cli->run();
diff --git a/platform/www/bin/indexer.php b/platform/www/bin/indexer.php
new file mode 100755
index 0000000..c8c8361
--- /dev/null
+++ b/platform/www/bin/indexer.php
@@ -0,0 +1,107 @@
+#!/usr/bin/env php
+<?php
+
+use splitbrain\phpcli\CLI;
+use splitbrain\phpcli\Options;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/');
+define('NOSESSION', 1);
+require_once(DOKU_INC . 'inc/init.php');
+
+/**
+ * Update the Search Index from command line
+ */
+class IndexerCLI extends CLI {
+
+ private $quiet = false;
+ private $clear = false;
+
+ /**
+ * Register options and arguments on the given $options object
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function setup(Options $options) {
+ $options->setHelp(
+ 'Updates the searchindex by indexing all new or changed pages. When the -c option is ' .
+ 'given the index is cleared first.'
+ );
+
+ $options->registerOption(
+ 'clear',
+ 'clear the index before updating',
+ 'c'
+ );
+ $options->registerOption(
+ 'quiet',
+ 'don\'t produce any output',
+ 'q'
+ );
+ }
+
+ /**
+ * Your main program
+ *
+ * Arguments and options have been parsed when this is run
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function main(Options $options) {
+ $this->clear = $options->getOpt('clear');
+ $this->quiet = $options->getOpt('quiet');
+
+ if($this->clear) $this->clearindex();
+
+ $this->update();
+ }
+
+ /**
+ * Update the index
+ */
+ protected function update() {
+ global $conf;
+ $data = array();
+ $this->quietecho("Searching pages... ");
+ search($data, $conf['datadir'], 'search_allpages', array('skipacl' => true));
+ $this->quietecho(count($data) . " pages found.\n");
+
+ foreach($data as $val) {
+ $this->index($val['id']);
+ }
+ }
+
+ /**
+ * Index the given page
+ *
+ * @param string $id
+ */
+ protected function index($id) {
+ $this->quietecho("$id... ");
+ idx_addPage($id, !$this->quiet, $this->clear);
+ $this->quietecho("done.\n");
+ }
+
+ /**
+ * Clear all index files
+ */
+ protected function clearindex() {
+ $this->quietecho("Clearing index... ");
+ idx_get_indexer()->clear();
+ $this->quietecho("done.\n");
+ }
+
+ /**
+ * Print message if not supressed
+ *
+ * @param string $msg
+ */
+ protected function quietecho($msg) {
+ if(!$this->quiet) echo $msg;
+ }
+}
+
+// Main
+$cli = new IndexerCLI();
+$cli->run();
diff --git a/platform/www/bin/plugin.php b/platform/www/bin/plugin.php
new file mode 100755
index 0000000..84a800e
--- /dev/null
+++ b/platform/www/bin/plugin.php
@@ -0,0 +1,103 @@
+#!/usr/bin/env php
+<?php
+
+use dokuwiki\Extension\PluginController;
+use splitbrain\phpcli\CLI;
+use splitbrain\phpcli\Colors;
+use splitbrain\phpcli\Options;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/');
+define('NOSESSION', 1);
+require_once(DOKU_INC . 'inc/init.php');
+
+class PluginCLI extends CLI {
+
+ /**
+ * Register options and arguments on the given $options object
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function setup(Options $options) {
+ $options->setHelp('Excecutes Plugin command line tools');
+ $options->registerArgument('plugin', 'The plugin CLI you want to run. Leave off to see list', false);
+ }
+
+ /**
+ * Your main program
+ *
+ * Arguments and options have been parsed when this is run
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function main(Options $options) {
+ global $argv;
+ $argv = $options->getArgs();
+
+ if($argv) {
+ $plugin = $this->loadPlugin($argv[0]);
+ if($plugin !== null) {
+ $plugin->run();
+ } else {
+ $this->fatal('Command {cmd} not found.', ['cmd' => $argv[0]]);
+ }
+ } else {
+ echo $options->help();
+ $this->listPlugins();
+ }
+ }
+
+ /**
+ * List available plugins
+ */
+ protected function listPlugins() {
+ /** @var PluginController $plugin_controller */
+ global $plugin_controller;
+
+ echo "\n";
+ echo "\n";
+ echo $this->colors->wrap('AVAILABLE PLUGINS:', Colors::C_BROWN);
+ echo "\n";
+
+ $list = $plugin_controller->getList('cli');
+ sort($list);
+ if(!count($list)) {
+ echo $this->colors->wrap(" No plugins providing CLI components available\n", Colors::C_RED);
+ } else {
+ $tf = new \splitbrain\phpcli\TableFormatter($this->colors);
+
+ foreach($list as $name) {
+ $plugin = $this->loadPlugin($name);
+ if($plugin === null) continue;
+ $info = $plugin->getInfo();
+
+ echo $tf->format(
+ [2, '30%', '*'],
+ ['', $name, $info['desc']],
+ ['', Colors::C_CYAN, '']
+
+ );
+ }
+ }
+ }
+
+ /**
+ * Instantiate a CLI plugin
+ *
+ * @param string $name
+ * @return \dokuwiki\Extension\CLIPlugin|null
+ */
+ protected function loadPlugin($name) {
+ // execute the plugin CLI
+ $class = "cli_plugin_$name";
+ if(class_exists($class)) {
+ return new $class();
+ }
+ return null;
+ }
+}
+
+// Main
+$cli = new PluginCLI();
+$cli->run();
diff --git a/platform/www/bin/render.php b/platform/www/bin/render.php
new file mode 100755
index 0000000..6076951
--- /dev/null
+++ b/platform/www/bin/render.php
@@ -0,0 +1,64 @@
+#!/usr/bin/env php
+<?php
+
+use splitbrain\phpcli\CLI;
+use splitbrain\phpcli\Options;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/');
+define('NOSESSION', 1);
+require_once(DOKU_INC . 'inc/init.php');
+
+/**
+ * A simple commandline tool to render some DokuWiki syntax with a given
+ * renderer.
+ *
+ * This may not work for plugins that expect a certain environment to be
+ * set up before rendering, but should work for most or even all standard
+ * DokuWiki markup
+ *
+ * @license GPL2
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class RenderCLI extends CLI {
+
+ /**
+ * Register options and arguments on the given $options object
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function setup(Options $options) {
+ $options->setHelp(
+ 'A simple commandline tool to render some DokuWiki syntax with a given renderer.' .
+ "\n\n" .
+ 'This may not work for plugins that expect a certain environment to be ' .
+ 'set up before rendering, but should work for most or even all standard ' .
+ 'DokuWiki markup'
+ );
+ $options->registerOption('renderer', 'The renderer mode to use. Defaults to xhtml', 'r', 'mode');
+ }
+
+ /**
+ * Your main program
+ *
+ * Arguments and options have been parsed when this is run
+ *
+ * @param Options $options
+ * @throws DokuCLI_Exception
+ * @return void
+ */
+ protected function main(Options $options) {
+ $renderer = $options->getOpt('renderer', 'xhtml');
+
+ // do the action
+ $source = stream_get_contents(STDIN);
+ $info = array();
+ $result = p_render($renderer, p_get_instructions($source), $info);
+ if(is_null($result)) throw new DokuCLI_Exception("No such renderer $renderer");
+ echo $result;
+ }
+}
+
+// Main
+$cli = new RenderCLI();
+$cli->run();
diff --git a/platform/www/bin/striplangs.php b/platform/www/bin/striplangs.php
new file mode 100755
index 0000000..91805d5
--- /dev/null
+++ b/platform/www/bin/striplangs.php
@@ -0,0 +1,114 @@
+#!/usr/bin/env php
+<?php
+
+use splitbrain\phpcli\CLI;
+use splitbrain\phpcli\Options;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/');
+define('NOSESSION', 1);
+require_once(DOKU_INC . 'inc/init.php');
+
+/**
+ * Remove unwanted languages from a DokuWiki install
+ */
+class StripLangsCLI extends CLI {
+
+ /**
+ * Register options and arguments on the given $options object
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function setup(Options $options) {
+
+ $options->setHelp(
+ 'Remove all languages from the installation, besides the ones specified. English language ' .
+ 'is never removed!'
+ );
+
+ $options->registerOption(
+ 'keep',
+ 'Comma separated list of languages to keep in addition to English.',
+ 'k',
+ 'langcodes'
+ );
+ $options->registerOption(
+ 'english-only',
+ 'Remove all languages except English',
+ 'e'
+ );
+ }
+
+ /**
+ * Your main program
+ *
+ * Arguments and options have been parsed when this is run
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function main(Options $options) {
+ if($options->getOpt('keep')) {
+ $keep = explode(',', $options->getOpt('keep'));
+ if(!in_array('en', $keep)) $keep[] = 'en';
+ } elseif($options->getOpt('english-only')) {
+ $keep = array('en');
+ } else {
+ echo $options->help();
+ exit(0);
+ }
+
+ // Kill all language directories in /inc/lang and /lib/plugins besides those in $langs array
+ $this->stripDirLangs(realpath(dirname(__FILE__) . '/../inc/lang'), $keep);
+ $this->processExtensions(realpath(dirname(__FILE__) . '/../lib/plugins'), $keep);
+ $this->processExtensions(realpath(dirname(__FILE__) . '/../lib/tpl'), $keep);
+ }
+
+ /**
+ * Strip languages from extensions
+ *
+ * @param string $path path to plugin or template dir
+ * @param array $keep_langs languages to keep
+ */
+ protected function processExtensions($path, $keep_langs) {
+ if(is_dir($path)) {
+ $entries = scandir($path);
+
+ foreach($entries as $entry) {
+ if($entry != "." && $entry != "..") {
+ if(is_dir($path . '/' . $entry)) {
+
+ $plugin_langs = $path . '/' . $entry . '/lang';
+
+ if(is_dir($plugin_langs)) {
+ $this->stripDirLangs($plugin_langs, $keep_langs);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Strip languages from path
+ *
+ * @param string $path path to lang dir
+ * @param array $keep_langs languages to keep
+ */
+ protected function stripDirLangs($path, $keep_langs) {
+ $dir = dir($path);
+
+ while(($cur_dir = $dir->read()) !== false) {
+ if($cur_dir != '.' and $cur_dir != '..' and is_dir($path . '/' . $cur_dir)) {
+
+ if(!in_array($cur_dir, $keep_langs, true)) {
+ io_rmdir($path . '/' . $cur_dir, true);
+ }
+ }
+ }
+ $dir->close();
+ }
+}
+
+$cli = new StripLangsCLI();
+$cli->run();
diff --git a/platform/www/bin/wantedpages.php b/platform/www/bin/wantedpages.php
new file mode 100755
index 0000000..6b3f787
--- /dev/null
+++ b/platform/www/bin/wantedpages.php
@@ -0,0 +1,186 @@
+#!/usr/bin/env php
+<?php
+
+use splitbrain\phpcli\CLI;
+use splitbrain\phpcli\Options;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__) . '/../') . '/');
+define('NOSESSION', 1);
+require_once(DOKU_INC . 'inc/init.php');
+
+/**
+ * Find wanted pages
+ */
+class WantedPagesCLI extends CLI {
+
+ const DIR_CONTINUE = 1;
+ const DIR_NS = 2;
+ const DIR_PAGE = 3;
+
+ private $skip = false;
+ private $sort = 'wanted';
+
+ private $result = array();
+
+ /**
+ * Register options and arguments on the given $options object
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function setup(Options $options) {
+ $options->setHelp(
+ 'Outputs a list of wanted pages (pages that do not exist yet) and their origin pages ' .
+ ' (the pages that are linkin to these missing pages).'
+ );
+ $options->registerArgument(
+ 'namespace',
+ 'The namespace to lookup. Defaults to root namespace',
+ false
+ );
+
+ $options->registerOption(
+ 'sort',
+ 'Sort by wanted or origin page',
+ 's',
+ '(wanted|origin)'
+ );
+
+ $options->registerOption(
+ 'skip',
+ 'Do not show the second dimension',
+ 'k'
+ );
+ }
+
+ /**
+ * Your main program
+ *
+ * Arguments and options have been parsed when this is run
+ *
+ * @param Options $options
+ * @return void
+ */
+ protected function main(Options $options) {
+ $args = $options->getArgs();
+ if($args) {
+ $startdir = dirname(wikiFN($args[0] . ':xxx'));
+ } else {
+ $startdir = dirname(wikiFN('xxx'));
+ }
+
+ $this->skip = $options->getOpt('skip');
+ $this->sort = $options->getOpt('sort');
+
+ $this->info("searching $startdir");
+
+ foreach($this->getPages($startdir) as $page) {
+ $this->internalLinks($page);
+ }
+ ksort($this->result);
+ foreach($this->result as $main => $subs) {
+ if($this->skip) {
+ print "$main\n";
+ } else {
+ $subs = array_unique($subs);
+ sort($subs);
+ foreach($subs as $sub) {
+ printf("%-40s %s\n", $main, $sub);
+ }
+ }
+ }
+ }
+
+ /**
+ * Determine directions of the search loop
+ *
+ * @param string $entry
+ * @param string $basepath
+ * @return int
+ */
+ protected function dirFilter($entry, $basepath) {
+ if($entry == '.' || $entry == '..') {
+ return WantedPagesCLI::DIR_CONTINUE;
+ }
+ if(is_dir($basepath . '/' . $entry)) {
+ if(strpos($entry, '_') === 0) {
+ return WantedPagesCLI::DIR_CONTINUE;
+ }
+ return WantedPagesCLI::DIR_NS;
+ }
+ if(preg_match('/\.txt$/', $entry)) {
+ return WantedPagesCLI::DIR_PAGE;
+ }
+ return WantedPagesCLI::DIR_CONTINUE;
+ }
+
+ /**
+ * Collects recursively the pages in a namespace
+ *
+ * @param string $dir
+ * @return array
+ * @throws DokuCLI_Exception
+ */
+ protected function getPages($dir) {
+ static $trunclen = null;
+ if(!$trunclen) {
+ global $conf;
+ $trunclen = strlen($conf['datadir'] . ':');
+ }
+
+ if(!is_dir($dir)) {
+ throw new DokuCLI_Exception("Unable to read directory $dir");
+ }
+
+ $pages = array();
+ $dh = opendir($dir);
+ while(false !== ($entry = readdir($dh))) {
+ $status = $this->dirFilter($entry, $dir);
+ if($status == WantedPagesCLI::DIR_CONTINUE) {
+ continue;
+ } else if($status == WantedPagesCLI::DIR_NS) {
+ $pages = array_merge($pages, $this->getPages($dir . '/' . $entry));
+ } else {
+ $page = array(
+ 'id' => pathID(substr($dir . '/' . $entry, $trunclen)),
+ 'file' => $dir . '/' . $entry,
+ );
+ $pages[] = $page;
+ }
+ }
+ closedir($dh);
+ return $pages;
+ }
+
+ /**
+ * Parse instructions and add the non-existing links to the result array
+ *
+ * @param array $page array with page id and file path
+ */
+ protected function internalLinks($page) {
+ global $conf;
+ $instructions = p_get_instructions(file_get_contents($page['file']));
+ $cns = getNS($page['id']);
+ $exists = false;
+ $pid = $page['id'];
+ foreach($instructions as $ins) {
+ if($ins[0] == 'internallink' || ($conf['camelcase'] && $ins[0] == 'camelcaselink')) {
+ $mid = $ins[1][0];
+ resolve_pageid($cns, $mid, $exists);
+ if(!$exists) {
+ list($mid) = explode('#', $mid); //record pages without hashes
+
+ if($this->sort == 'origin') {
+ $this->result[$pid][] = $mid;
+ } else {
+ $this->result[$mid][] = $pid;
+ }
+ }
+ }
+ }
+ }
+}
+
+// Main
+$cli = new WantedPagesCLI();
+$cli->run();
diff --git a/platform/www/conf/.htaccess b/platform/www/conf/.htaccess
new file mode 100644
index 0000000..9f49132
--- /dev/null
+++ b/platform/www/conf/.htaccess
@@ -0,0 +1,8 @@
+## no access to the conf directory
+<IfModule mod_authz_core.c>
+ Require all denied
+</IfModule>
+<IfModule !mod_authz_core.c>
+ Order allow,deny
+ Deny from all
+</IfModule>
diff --git a/platform/www/conf/acl.auth.php b/platform/www/conf/acl.auth.php
new file mode 100644
index 0000000..c70af78
--- /dev/null
+++ b/platform/www/conf/acl.auth.php
@@ -0,0 +1,21 @@
+# acl.auth.php
+# <?php exit()?>
+# Don't modify the lines above
+#
+# Access Control Lists
+#
+# Editing this file by hand shouldn't be necessary. Use the ACL
+# Manager interface instead.
+#
+# If your auth backend allows special char like spaces in groups
+# or user names you need to urlencode them (only chars <128, leave
+# UTF-8 multibyte chars as is)
+#
+# none 0
+# read 1
+# edit 2
+# create 4
+# upload 8
+# delete 16
+
+* @ALL 1
diff --git a/platform/www/conf/acl.auth.php.dist b/platform/www/conf/acl.auth.php.dist
new file mode 100644
index 0000000..14344d7
--- /dev/null
+++ b/platform/www/conf/acl.auth.php.dist
@@ -0,0 +1,21 @@
+# acl.auth.php
+# <?php exit()?>
+# Don't modify the lines above
+#
+# Access Control Lists
+#
+# Editing this file by hand shouldn't be necessary. Use the ACL
+# Manager interface instead.
+#
+# If your auth backend allows special char like spaces in groups
+# or user names you need to urlencode them (only chars <128, leave
+# UTF-8 multibyte chars as is)
+#
+# none 0
+# read 1
+# edit 2
+# create 4
+# upload 8
+# delete 16
+
+* @ALL 8
diff --git a/platform/www/conf/acronyms.conf b/platform/www/conf/acronyms.conf
new file mode 100644
index 0000000..2ecdeda
--- /dev/null
+++ b/platform/www/conf/acronyms.conf
@@ -0,0 +1,62 @@
+# Acronyms.
+
+ACL Access Control List
+AFAICS As far as I can see
+AFAIK As far as I know
+AFAIR As far as I remember
+API Application Programming Interface
+ASAP As soon as possible
+ASCII American Standard Code for Information Interchange
+BTW By the way
+CMS Content Management System
+CSS Cascading Style Sheets
+DNS Domain Name System
+EOF End of file
+EOL End of line
+EOM End of message
+EOT End of text
+FAQ Frequently Asked Questions
+FTP File Transfer Protocol
+FOSS Free & Open-Source Software
+FLOSS Free/Libre and Open Source Software
+FUD Fear, Uncertainty, and Doubt
+FYI For your information
+GB Gigabyte
+GHz Gigahertz
+GPL GNU General Public License
+GUI Graphical User Interface
+HTML HyperText Markup Language
+IANAL I am not a lawyer (but)
+IE Internet Explorer
+IIRC If I remember correctly
+IMHO In my humble opinion
+IMO In my opinion
+IOW In other words
+IRC Internet Relay Chat
+IRL In real life
+KISS Keep it simple stupid
+LAN Local Area Network
+LGPL GNU Lesser General Public License
+LOL Laughing out loud
+MathML Mathematical Markup Language
+MB Megabyte
+MHz Megahertz
+MSIE Microsoft Internet Explorer
+OMG Oh my God
+OS Operating System
+OSS Open Source Software
+OTOH On the other hand
+PITA Pain in the Ass
+RFC Request for Comments
+ROTFL Rolling on the floor laughing
+RTFM Read The Fine Manual
+spec specification
+TIA Thanks in advance
+TL;DR Too long; didn't read
+TOC Table of Contents
+URI Uniform Resource Identifier
+URL Uniform Resource Locator
+W3C World Wide Web Consortium
+WTF? What the f***
+WYSIWYG What You See Is What You Get
+YMMV Your mileage may vary
diff --git a/platform/www/conf/dokuwiki.php b/platform/www/conf/dokuwiki.php
new file mode 100644
index 0000000..290453d
--- /dev/null
+++ b/platform/www/conf/dokuwiki.php
@@ -0,0 +1,178 @@
+<?php
+/**
+ * This is DokuWiki's Main Configuration file
+ *
+ * All the default values are kept here, you should not modify it but use
+ * a local.php file instead to override the settings from here.
+ *
+ * This is a piece of PHP code so PHP syntax applies!
+ *
+ * For help with the configuration and a more detailed explanation of the various options
+ * see https://www.dokuwiki.org/config
+ */
+
+
+/* Basic Settings */
+$conf['title'] = 'DokuWiki'; //what to show in the title
+$conf['start'] = 'start'; //name of start page
+$conf['lang'] = 'en'; //your language
+$conf['template'] = 'dokuwiki'; //see lib/tpl directory
+$conf['tagline'] = ''; //tagline in header (if template supports it)
+$conf['sidebar'] = 'sidebar'; //name of sidebar in root namespace (if template supports it)
+$conf['license'] = 'cc-by-nc-sa'; //see conf/license.php
+$conf['savedir'] = './data'; //where to store all the files
+$conf['basedir'] = ''; //absolute dir from serveroot - blank for autodetection
+$conf['baseurl'] = ''; //URL to server including protocol - blank for autodetect
+$conf['cookiedir'] = ''; //path to use in cookies - blank for basedir
+$conf['dmode'] = 0755; //set directory creation mode
+$conf['fmode'] = 0644; //set file creation mode
+$conf['allowdebug'] = 0; //allow debug output, enable if needed 0|1
+
+/* Display Settings */
+$conf['recent'] = 20; //how many entries to show in recent
+$conf['recent_days'] = 7; //How many days of recent changes to keep. (days)
+$conf['breadcrumbs'] = 10; //how many recent visited pages to show
+$conf['youarehere'] = 0; //show "You are here" navigation? 0|1
+$conf['fullpath'] = 0; //show full path of the document or relative to datadir only? 0|1
+$conf['typography'] = 1; //smartquote conversion 0=off, 1=doublequotes, 2=all quotes
+$conf['dformat'] = '%Y/%m/%d %H:%M'; //dateformat accepted by PHPs strftime() function
+$conf['signature'] = ' --- //[[@MAIL@|@NAME@]] @DATE@//'; //signature see wiki page for details
+$conf['showuseras'] = 'loginname'; // 'loginname' users login name
+ // 'username' users full name
+ // 'email' e-mail address (will be obfuscated as per mailguard)
+ // 'email_link' e-mail address as a mailto: link (obfuscated)
+$conf['toptoclevel'] = 1; //Level starting with and below to include in AutoTOC (max. 5)
+$conf['tocminheads'] = 3; //Minimum amount of headlines that determines if a TOC is built
+$conf['maxtoclevel'] = 3; //Up to which level include into AutoTOC (max. 5)
+$conf['maxseclevel'] = 3; //Up to which level create editable sections (max. 5)
+$conf['camelcase'] = 0; //Use CamelCase for linking? (I don't like it) 0|1
+$conf['deaccent'] = 1; //deaccented chars in pagenames (1) or romanize (2) or keep (0)?
+$conf['useheading'] = 0; //use the first heading in a page as its name
+$conf['sneaky_index']= 0; //check for namespace read permission in index view (0|1) (1 might cause unexpected behavior)
+$conf['hidepages'] = ''; //Regexp for pages to be skipped from RSS, Search and Recent Changes
+
+/* Authentication Settings */
+$conf['useacl'] = 0; //Use Access Control Lists to restrict access?
+$conf['autopasswd'] = 1; //autogenerate passwords and email them to user
+$conf['authtype'] = 'authplain'; //which authentication backend should be used
+$conf['passcrypt'] = 'bcrypt'; //Used crypt method (smd5,md5,sha1,ssha,crypt,mysql,my411,bcrypt)
+$conf['defaultgroup']= 'user'; //Default groups new Users are added to
+$conf['superuser'] = '!!not set!!'; //The admin can be user or @group or comma separated list user1,@group1,user2
+$conf['manager'] = '!!not set!!'; //The manager can be user or @group or comma separated list user1,@group1,user2
+$conf['profileconfirm'] = 1; //Require current password to confirm changes to user profile
+$conf['rememberme'] = 1; //Enable/disable remember me on login
+$conf['disableactions'] = ''; //comma separated list of actions to disable
+$conf['auth_security_timeout'] = 900; //time (seconds) auth data is considered valid, set to 0 to recheck on every page view
+$conf['securecookie'] = 1; //never send HTTPS cookies via HTTP
+$conf['remote'] = 0; //Enable/disable remote interfaces
+$conf['remoteuser'] = '!!not set!!'; //user/groups that have access to remote interface (comma separated). leave empty to allow all users
+
+/* Antispam Features */
+$conf['usewordblock']= 1; //block spam based on words? 0|1
+$conf['relnofollow'] = 1; //use rel="ugc nofollow" for external links?
+$conf['indexdelay'] = 60*60*24*5; //allow indexing after this time (seconds) default is 5 days
+$conf['mailguard'] = 'hex'; //obfuscate email addresses against spam harvesters?
+ //valid entries are:
+ // 'visible' - replace @ with [at], . with [dot] and - with [dash]
+ // 'hex' - use hex entities to encode the mail address
+ // 'none' - do not obfuscate addresses
+$conf['iexssprotect']= 1; // check for JavaScript and HTML in uploaded files 0|1
+
+/* Editing Settings */
+$conf['usedraft'] = 1; //automatically save a draft while editing (0|1)
+$conf['htmlok'] = 0; //may raw HTML be embedded? This may break layout and XHTML validity 0|1
+$conf['phpok'] = 0; //may PHP code be embedded? Never do this on the internet! 0|1
+$conf['locktime'] = 15*60; //maximum age for lockfiles (defaults to 15 minutes)
+$conf['cachetime'] = 60*60*24; //maximum age for cachefile in seconds (defaults to a day)
+
+/* Link Settings */
+// Set target to use when creating links - leave empty for same window
+$conf['target']['wiki'] = '';
+$conf['target']['interwiki'] = '';
+$conf['target']['extern'] = '';
+$conf['target']['media'] = '';
+$conf['target']['windows'] = '';
+
+/* Media Settings */
+$conf['mediarevisions'] = 1; //enable/disable media revisions
+$conf['refcheck'] = 1; //check for references before deleting media files
+$conf['gdlib'] = 2; //the GDlib version (0, 1 or 2) 2 tries to autodetect
+$conf['im_convert'] = ''; //path to ImageMagicks convert (will be used instead of GD)
+$conf['jpg_quality'] = '70'; //quality of compression when scaling jpg images (0-100)
+$conf['fetchsize'] = 0; //maximum size (bytes) fetch.php may download from extern, disabled by default
+
+/* Notification Settings */
+$conf['subscribers'] = 0; //enable change notice subscription support
+$conf['subscribe_time'] = 24*60*60; //Time after which digests / lists are sent (in sec, default 1 day)
+ //Should be smaller than the time specified in recent_days
+$conf['notify'] = ''; //send change info to this email (leave blank for nobody)
+$conf['registernotify'] = ''; //send info about newly registered users to this email (leave blank for nobody)
+$conf['mailfrom'] = ''; //use this email when sending mails
+$conf['mailreturnpath'] = ''; //use this email as returnpath for bounce mails
+$conf['mailprefix'] = ''; //use this as prefix of outgoing mails
+$conf['htmlmail'] = 1; //send HTML multipart mails
+
+/* Syndication Settings */
+$conf['sitemap'] = 0; //Create a google sitemap? How often? In days.
+$conf['rss_type'] = 'rss1'; //type of RSS feed to provide, by default:
+ // 'rss' - RSS 0.91
+ // 'rss1' - RSS 1.0
+ // 'rss2' - RSS 2.0
+ // 'atom' - Atom 0.3
+ // 'atom1' - Atom 1.0
+$conf['rss_linkto'] = 'diff'; //what page RSS entries link to:
+ // 'diff' - page showing revision differences
+ // 'page' - the revised page itself
+ // 'rev' - page showing all revisions
+ // 'current' - most recent revision of page
+$conf['rss_content'] = 'abstract'; //what to put in the items by default?
+ // 'abstract' - plain text, first paragraph or so
+ // 'diff' - plain text unified diff wrapped in <pre> tags
+ // 'htmldiff' - diff as HTML table
+ // 'html' - the full page rendered in XHTML
+$conf['rss_media'] = 'both'; //what should be listed?
+ // 'both' - page and media changes
+ // 'pages' - page changes only
+ // 'media' - media changes only
+$conf['rss_update'] = 5*60; //Update the RSS feed every n seconds (defaults to 5 minutes)
+$conf['rss_show_summary'] = 1; //Add revision summary to title? 0|1
+$conf['rss_show_deleted'] = 1; //Show deleted items 0|1
+
+/* Advanced Settings */
+$conf['updatecheck'] = 1; //automatically check for new releases?
+$conf['userewrite'] = 0; //this makes nice URLs: 0: off 1: .htaccess 2: internal
+$conf['useslash'] = 0; //use slash instead of colon? only when rewrite is on
+$conf['sepchar'] = '_'; //word separator character in page names; may be a
+ // letter, a digit, '_', '-', or '.'.
+$conf['canonical'] = 0; //Should all URLs use full canonical http://... style?
+$conf['fnencode'] = 'url'; //encode filenames (url|safe|utf-8)
+$conf['autoplural'] = 0; //try (non)plural form of nonexisting files?
+$conf['compression'] = 'gz'; //compress old revisions: (0: off) ('gz': gnuzip) ('bz2': bzip)
+ // bz2 generates smaller files, but needs more cpu-power
+$conf['gzip_output'] = 0; //use gzip content encodeing for the output xhtml (if allowed by browser)
+$conf['compress'] = 1; //Strip whitespaces and comments from Styles and JavaScript? 1|0
+$conf['cssdatauri'] = 512; //Maximum byte size of small images to embed into CSS, won't work on IE<8
+$conf['send404'] = 0; //Send a HTTP 404 status for non existing pages?
+$conf['broken_iua'] = 0; //Platform with broken ignore_user_abort (IIS+CGI) 0|1
+$conf['xsendfile'] = 0; //Use X-Sendfile (1 = lighttpd, 2 = standard)
+$conf['renderer_xhtml'] = 'xhtml'; //renderer to use for main page generation
+$conf['readdircache'] = 0; //time cache in second for the readdir operation, 0 to deactivate.
+$conf['search_nslimit'] = 0; //limit the search to the current X namespaces
+$conf['search_fragment'] = 'exact'; //specify the default fragment search behavior
+$conf['trustedproxy'] = '^(::1|[fF][eE]80:|127\.|10\.|192\.168\.|172\.((1[6-9])|(2[0-9])|(3[0-1]))\.)';
+ //Regexp of trusted proxy address when reading IP using HTTP header
+ // if blank, do not trust any proxy (including local IP)
+
+/* Feature Flags */
+$conf['defer_js'] = 1; // Defer javascript to be executed after the page's HTML has been parsed. Setting will be removed in the next release.
+
+/* Network Settings */
+$conf['dnslookups'] = 1; //disable to disallow IP to hostname lookups
+$conf['jquerycdn'] = 0; //use a CDN for delivering jQuery?
+// Proxy setup - if your Server needs a proxy to access the web set these
+$conf['proxy']['host'] = '';
+$conf['proxy']['port'] = '';
+$conf['proxy']['user'] = '';
+$conf['proxy']['pass'] = '';
+$conf['proxy']['ssl'] = 0;
+$conf['proxy']['except'] = '';
diff --git a/platform/www/conf/entities.conf b/platform/www/conf/entities.conf
new file mode 100644
index 0000000..c0d653c
--- /dev/null
+++ b/platform/www/conf/entities.conf
@@ -0,0 +1,22 @@
+# Typography replacements
+#
+# Order does matter!
+#
+# You can use HTML entities here, but it is not recommended because it may break
+# non-HTML renderers. Use UTF-8 chars directly instead.
+
+<-> ↔
+-> →
+<- â†
+<=> ⇔
+=> ⇒
+<= â‡
+>> »
+<< «
+--- —
+-- –
+(c) ©
+(tm) â„¢
+(r) ®
+... …
+
diff --git a/platform/www/conf/farm.ini.dist b/platform/www/conf/farm.ini.dist
new file mode 100644
index 0000000..40aa9f9
--- /dev/null
+++ b/platform/www/conf/farm.ini.dist
@@ -0,0 +1,26 @@
+; Farm config created by the farmer plugin
+
+[base]
+farmhost = "acerv.uz"
+basedomain = "acerv.uz"
+farmdir = "/srv/acerv.us/content/"
+
+[notfound]
+show = "farmer"
+url = ""
+
+[inherit]
+main = 1
+acronyms = 1
+entities = 1
+interwiki = 1
+license = 1
+mime = 1
+scheme = 1
+smileys = 1
+wordblock = 1
+users = 1
+plugins = 1
+userstyle = 0
+userscript = 0
+styleini = 0
diff --git a/platform/www/conf/farm.ini.save b/platform/www/conf/farm.ini.save
new file mode 100644
index 0000000..af1c8da
--- /dev/null
+++ b/platform/www/conf/farm.ini.save
@@ -0,0 +1,26 @@
+; Farm config created by the farmer plugin
+
+[base]
+farmhost = "wikifarm.test"
+basedomain = "wikifarm.test"
+farmdir = "/srv/acerv.us/content"
+
+[notfound]
+show = "farmer"
+url = ""
+
+[inherit]
+main = 1
+acronyms = 1
+entities = 1
+interwiki = 1
+license = 1
+mime = 1
+scheme = 1
+smileys = 1
+wordblock = 1
+users = 0
+plugins = 0
+userstyle = 0
+userscript = 0
+styleini = 0
diff --git a/platform/www/conf/interwiki.conf b/platform/www/conf/interwiki.conf
new file mode 100644
index 0000000..58bc517
--- /dev/null
+++ b/platform/www/conf/interwiki.conf
@@ -0,0 +1,42 @@
+# Each URL may contain one of these placeholders
+# {URL} is replaced by the URL encoded representation of the wikiname
+# this is the right thing to do in most cases
+# {NAME} this is replaced by the wikiname as given in the document
+# only mandatory encoded is done, urlencoding if the link
+# is an external URL, or encoding as a wikiname if it is an
+# internal link (begins with a colon)
+# {SCHEME}
+# {HOST}
+# {PORT}
+# {PATH}
+# {QUERY} these placeholders will be replaced with the appropriate part
+# of the link when parsed as a URL
+# If no placeholder is defined the urlencoded name is appended to the URL
+
+# To prevent losing your added InterWiki shortcuts after an upgrade,
+# you should add new ones to interwiki.local.conf
+
+wp https://en.wikipedia.org/wiki/{NAME}
+wpfr https://fr.wikipedia.org/wiki/{NAME}
+wpde https://de.wikipedia.org/wiki/{NAME}
+wpes https://es.wikipedia.org/wiki/{NAME}
+wppl https://pl.wikipedia.org/wiki/{NAME}
+wpjp https://ja.wikipedia.org/wiki/{NAME}
+wpru https://ru.wikipedia.org/wiki/{NAME}
+wpmeta https://meta.wikipedia.org/wiki/{NAME}
+doku https://www.dokuwiki.org/
+rfc https://tools.ietf.org/html/rfc
+man http://man.cx/
+amazon https://www.amazon.com/dp/{URL}?tag=splitbrain-20
+amazon.de https://www.amazon.de/dp/{URL}?tag=splitbrain-21
+amazon.uk https://www.amazon.co.uk/dp/{URL}
+paypal https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&amp;business=
+phpfn https://secure.php.net/{NAME}
+skype skype:{NAME}
+google.de https://www.google.de/search?q=
+go https://www.google.com/search?q={URL}&amp;btnI=lucky
+user :user:{NAME}
+
+# To support VoIP/SIP/TEL links
+callto callto://{NAME}
+tel tel:{NAME}
diff --git a/platform/www/conf/license.php b/platform/www/conf/license.php
new file mode 100644
index 0000000..845c59f
--- /dev/null
+++ b/platform/www/conf/license.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * This file defines multiple available licenses you can license your
+ * wiki contents under. Do not change this file, but create a
+ * license.local.php instead.
+ */
+
+if(empty($LC)) $LC = empty($conf['lang']) ? 'en' : $conf['lang'];
+
+$license['cc-zero'] = array(
+ 'name' => 'CC0 1.0 Universal',
+ 'url' => 'https://creativecommons.org/publicdomain/zero/1.0/deed.'.$LC,
+);
+$license['publicdomain'] = array(
+ 'name' => 'Public Domain',
+ 'url' => 'https://creativecommons.org/licenses/publicdomain/deed.'.$LC,
+);
+$license['cc-by'] = array(
+ 'name' => 'CC Attribution 4.0 International',
+ 'url' => 'https://creativecommons.org/licenses/by/4.0/deed.'.$LC,
+);
+$license['cc-by-sa'] = array(
+ 'name' => 'CC Attribution-Share Alike 4.0 International',
+ 'url' => 'https://creativecommons.org/licenses/by-sa/4.0/deed.'.$LC,
+);
+$license['gnufdl'] = array(
+ 'name' => 'GNU Free Documentation License 1.3',
+ 'url' => 'https://www.gnu.org/licenses/fdl-1.3.html',
+);
+$license['cc-by-nc'] = array(
+ 'name' => 'CC Attribution-Noncommercial 4.0 International',
+ 'url' => 'https://creativecommons.org/licenses/by-nc/4.0/deed.'.$LC,
+);
+$license['cc-by-nc-sa'] = array(
+ 'name' => 'CC Attribution-Noncommercial-Share Alike 4.0 International',
+ 'url' => 'https://creativecommons.org/licenses/by-nc-sa/4.0/deed.'.$LC,
+);
+
diff --git a/platform/www/conf/local.php b/platform/www/conf/local.php
new file mode 100644
index 0000000..d4bc65f
--- /dev/null
+++ b/platform/www/conf/local.php
@@ -0,0 +1,29 @@
+<?php
+/*
+ * Dokuwiki's Main Configuration File - Local Settings
+ * Auto-generated by config plugin
+ * Run for user: admin
+ * Date: Mon, 07 Mar 2022 01:33:50 +0000
+ */
+
+$conf['title'] = 'The Acervus Project';
+$conf['start'] = 'index';
+$conf['template'] = 'acervus';
+$conf['license'] = '';
+$conf['breadcrumbs'] = 0;
+$conf['youarehere'] = 1;
+$conf['useacl'] = 1;
+$conf['superuser'] = 'admin';
+$conf['disableactions'] = 'register';
+$conf['htmlok'] = 1;
+$conf['userewrite'] = '1';
+$conf['plugin']['authldap']['attributes'] = array();
+$conf['plugin']['fastwiki']['save'] = 1;
+$conf['plugin']['translation']['translations'] = 'en es';
+$conf['plugin']['translation']['display'] = 'langcode,name';
+$conf['plugin']['translation']['translateui'] = 1;
+$conf['plugin']['translation']['localabout'] = 1;
+$conf['plugin']['translation']['copytrans'] = 1;
+$conf['tpl']['acervus']['numberedHeading'] = 1;
+$conf['tpl']['acervus']['tocPosition'] = 'dokuwiki';
+$conf['tpl']['acervus']['footer'] = 'footer';
diff --git a/platform/www/conf/local.php.bak.php b/platform/www/conf/local.php.bak.php
new file mode 100644
index 0000000..8649c89
--- /dev/null
+++ b/platform/www/conf/local.php.bak.php
@@ -0,0 +1,29 @@
+<?php
+/*
+ * Dokuwiki's Main Configuration File - Local Settings
+ * Auto-generated by config plugin
+ * Run for user: admin
+ * Date: Mon, 07 Mar 2022 01:32:28 +0000
+ */
+
+$conf['title'] = 'Acervus2';
+$conf['start'] = 'index';
+$conf['template'] = 'acervus';
+$conf['license'] = '';
+$conf['breadcrumbs'] = 0;
+$conf['youarehere'] = 1;
+$conf['useacl'] = 1;
+$conf['superuser'] = 'admin';
+$conf['disableactions'] = 'register';
+$conf['htmlok'] = 1;
+$conf['userewrite'] = '1';
+$conf['plugin']['authldap']['attributes'] = array();
+$conf['plugin']['fastwiki']['save'] = 1;
+$conf['plugin']['translation']['translations'] = 'en es';
+$conf['plugin']['translation']['display'] = 'langcode,name';
+$conf['plugin']['translation']['translateui'] = 1;
+$conf['plugin']['translation']['localabout'] = 1;
+$conf['plugin']['translation']['copytrans'] = 1;
+$conf['tpl']['acervus']['numberedHeading'] = 1;
+$conf['tpl']['acervus']['tocPosition'] = 'dokuwiki';
+$conf['tpl']['acervus']['footer'] = 'footer';
diff --git a/platform/www/conf/local.php.dist b/platform/www/conf/local.php.dist
new file mode 100644
index 0000000..0397954
--- /dev/null
+++ b/platform/www/conf/local.php.dist
@@ -0,0 +1,16 @@
+<?php
+/**
+ * This is an example of how a local.php could look like.
+ * Simply copy the options you want to change from dokuwiki.php
+ * to this file and change them.
+ *
+ * When using the installer, a correct local.php file be generated for
+ * you automatically.
+ */
+
+
+//$conf['title'] = 'My Wiki'; //what to show in the title
+
+//$conf['useacl'] = 1; //Use Access Control Lists to restrict access?
+//$conf['superuser'] = 'joe';
+
diff --git a/platform/www/conf/manifest.json b/platform/www/conf/manifest.json
new file mode 100644
index 0000000..891bd79
--- /dev/null
+++ b/platform/www/conf/manifest.json
@@ -0,0 +1,3 @@
+{
+ "display": "standalone"
+}
diff --git a/platform/www/conf/mediameta.php b/platform/www/conf/mediameta.php
new file mode 100644
index 0000000..f75fa08
--- /dev/null
+++ b/platform/www/conf/mediameta.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * This configures which meta data will be editable through
+ * the media manager. Each field of the array is an array with the
+ * following contents:
+ * fieldname - Where data will be saved (EXIF or IPTC field)
+ * label - key to lookup in the $lang var, if not found printed as is
+ * htmltype - 'text', 'textarea' or 'date'
+ * lookups - array additional fields to lookup the data (EXIF or IPTC fields)
+ *
+ * The fields are not ordered continously to make inserting additional items
+ * in between simpler.
+ *
+ * This is a PHP snippet, so PHP syntax applies.
+ *
+ * Note: $fields is not a global variable and will not be available to any
+ * other functions or templates later
+ *
+ * You may extend or overwrite this variable in a optional
+ * conf/mediameta.local.php file
+ *
+ * For a list of available EXIF/IPTC fields refer to
+ * http://www.dokuwiki.org/devel:templates:detail.php
+ */
+
+
+$fields = array(
+ 10 => array('Iptc.Headline',
+ 'img_title',
+ 'text'),
+
+ 20 => array('',
+ 'img_date',
+ 'date',
+ array('Date.EarliestTime')),
+
+ 30 => array('',
+ 'img_fname',
+ 'text',
+ array('File.Name')),
+
+ 40 => array('Iptc.Caption',
+ 'img_caption',
+ 'textarea',
+ array('Exif.UserComment',
+ 'Exif.TIFFImageDescription',
+ 'Exif.TIFFUserComment')),
+
+ 50 => array('Iptc.Byline',
+ 'img_artist',
+ 'text',
+ array('Exif.TIFFArtist',
+ 'Exif.Artist',
+ 'Iptc.Credit')),
+
+ 60 => array('Iptc.CopyrightNotice',
+ 'img_copyr',
+ 'text',
+ array('Exif.TIFFCopyright',
+ 'Exif.Copyright')),
+
+ 70 => array('',
+ 'img_format',
+ 'text',
+ array('File.Format')),
+
+ 80 => array('',
+ 'img_fsize',
+ 'text',
+ array('File.NiceSize')),
+
+ 90 => array('',
+ 'img_width',
+ 'text',
+ array('File.Width')),
+
+ 100 => array('',
+ 'img_height',
+ 'text',
+ array('File.Height')),
+
+ 110 => array('',
+ 'img_camera',
+ 'text',
+ array('Simple.Camera')),
+
+ 120 => array('Iptc.Keywords',
+ 'img_keywords',
+ 'text',
+ array('Exif.Category')),
+);
diff --git a/platform/www/conf/mime.conf b/platform/www/conf/mime.conf
new file mode 100644
index 0000000..56b72a4
--- /dev/null
+++ b/platform/www/conf/mime.conf
@@ -0,0 +1,72 @@
+# Allowed uploadable file extensions and mimetypes are defined here.
+# To extend this file it is recommended to create a mime.local.conf
+# file. Mimetypes that should be downloadable and not be opened in the
+# should be prefixed with a !
+
+jpg image/jpeg
+jpeg image/jpeg
+gif image/gif
+png image/png
+ico image/vnd.microsoft.icon
+
+mp3 audio/mpeg
+ogg audio/ogg
+wav audio/wav
+webm video/webm
+ogv video/ogg
+mp4 video/mp4
+vtt text/vtt
+
+tgz !application/octet-stream
+tar !application/x-gtar
+gz !application/octet-stream
+bz2 !application/octet-stream
+zip !application/zip
+rar !application/rar
+7z !application/x-7z-compressed
+
+pdf application/pdf
+ps !application/postscript
+
+rpm !application/octet-stream
+deb !application/octet-stream
+
+doc !application/msword
+xls !application/msexcel
+ppt !application/mspowerpoint
+rtf !application/msword
+
+docx !application/vnd.openxmlformats-officedocument.wordprocessingml.document
+xlsx !application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
+pptx !application/vnd.openxmlformats-officedocument.presentationml.presentation
+
+sxw !application/soffice
+sxc !application/soffice
+sxi !application/soffice
+sxd !application/soffice
+
+odc !application/vnd.oasis.opendocument.chart
+odf !application/vnd.oasis.opendocument.formula
+odg !application/vnd.oasis.opendocument.graphics
+odi !application/vnd.oasis.opendocument.image
+odp !application/vnd.oasis.opendocument.presentation
+ods !application/vnd.oasis.opendocument.spreadsheet
+odt !application/vnd.oasis.opendocument.text
+
+# You should enable HTML and Text uploads only for restricted Wikis.
+# Spammers are known to upload spam pages through unprotected Wikis.
+# Note: Enabling HTML opens Cross Site Scripting vulnerabilities
+# through JavaScript. Only enable this with trusted users. You
+# need to disable the iexssprotect option additionally to
+# adding the mime type here
+#html text/html
+#htm text/html
+#txt text/plain
+#conf text/plain
+#xml text/xml
+#csv text/csv
+
+# Also flash may be able to execute arbitrary scripts in the website's
+# context
+#swf application/x-shockwave-flash
+
diff --git a/platform/www/conf/mysql.conf.php.example b/platform/www/conf/mysql.conf.php.example
new file mode 100644
index 0000000..8337f51
--- /dev/null
+++ b/platform/www/conf/mysql.conf.php.example
@@ -0,0 +1,253 @@
+<?php
+/*
+ * This is an example configuration for the mysql auth plugin.
+ *
+ * This SQL statements are optimized for following table structure.
+ * If you use a different one you have to change them accordingly.
+ * See comments of every statement for details.
+ *
+ * TABLE users
+ * uid login pass firstname lastname email
+ *
+ * TABLE groups
+ * gid name
+ *
+ * TABLE usergroup
+ * uid gid
+ *
+ * To use this configuration you have to copy them to local.protected.php
+ * or at least include this file in local.protected.php.
+ */
+
+/* Options to configure database access. You need to set up this
+ * options carefully, otherwise you won't be able to access you
+ * database.
+ */
+$conf['plugin']['authmysql']['server'] = '';
+$conf['plugin']['authmysql']['user'] = '';
+$conf['plugin']['authmysql']['password'] = '';
+$conf['plugin']['authmysql']['database'] = '';
+
+/* This option enables debug messages in the mysql plugin. It is
+ * mostly useful for system admins.
+ */
+$conf['plugin']['authmysql']['debug'] = 0;
+
+/* Normally password encryption is done by DokuWiki (recommended) but for
+ * some reasons it might be usefull to let the database do the encryption.
+ * Set 'forwardClearPass' to '1' and the cleartext password is forwarded to
+ * the database, otherwise the encrypted one.
+ */
+$conf['plugin']['authmysql']['forwardClearPass'] = 0;
+
+/* Multiple table operations will be protected by locks. This array tolds
+ * the plugin which tables to lock. If you use any aliases for table names
+ * these array must also contain these aliases. Any unamed alias will cause
+ * a warning during operation. See the example below.
+ */
+$conf['plugin']['authmysql']['TablesToLock']= array("users", "users AS u","groups", "groups AS g", "usergroup", "usergroup AS ug");
+
+/***********************************************************************/
+/* Basic SQL statements for user authentication (required) */
+/***********************************************************************/
+
+/* This statement is used to grant or deny access to the wiki. The result
+ * should be a table with exact one line containing at least the password
+ * of the user. If the result table is empty or contains more than one
+ * row, access will be denied.
+ *
+ * The plugin accesses the password as 'pass' so an alias might be necessary.
+ *
+ * Following patters will be replaced:
+ * %{user} user name
+ * %{pass} encrypted or clear text password (depends on 'encryptPass')
+ * %{dgroup} default group name
+ */
+$conf['plugin']['authmysql']['checkPass'] = "SELECT pass
+ FROM usergroup AS ug
+ JOIN users AS u ON u.uid=ug.uid
+ JOIN groups AS g ON g.gid=ug.gid
+ WHERE login='%{user}'
+ AND name='%{dgroup}'";
+
+/* This statement should return a table with exact one row containing
+ * information about one user. The field needed are:
+ * 'pass' containing the encrypted or clear text password
+ * 'name' the user's full name
+ * 'mail' the user's email address
+ *
+ * Keep in mind that Dokuwiki will access thise information through the
+ * names listed above so aliasses might be neseccary.
+ *
+ * Following patters will be replaced:
+ * %{user} user name
+ */
+$conf['plugin']['authmysql']['getUserInfo'] = "SELECT pass, CONCAT(firstname,' ',lastname) AS name, email AS mail
+ FROM users
+ WHERE login='%{user}'";
+
+/* This statement is used to get all groups a user is member of. The
+ * result should be a table containing all groups the given user is
+ * member of. The plugin accesses the group name as 'group' so an alias
+ * might be nessecary.
+ *
+ * Following patters will be replaced:
+ * %{user} user name
+ */
+$conf['plugin']['authmysql']['getGroups'] = "SELECT name as `group`
+ FROM groups g, users u, usergroup ug
+ WHERE u.uid = ug.uid
+ AND g.gid = ug.gid
+ AND u.login='%{user}'";
+
+/***********************************************************************/
+/* Additional minimum SQL statements to use the user manager */
+/***********************************************************************/
+
+/* This statement should return a table containing all user login names
+ * that meet certain filter criteria. The filter expressions will be added
+ * case dependend by the plugin. At the end a sort expression will be added.
+ * Important is that this list contains no double entries for a user. Each
+ * user name is only allowed once in the table.
+ *
+ * The login name will be accessed as 'user' to an alias might be neseccary.
+ * No patterns will be replaced in this statement but following patters
+ * will be replaced in the filter expressions:
+ * %{user} in FilterLogin user's login name
+ * %{name} in FilterName user's full name
+ * %{email} in FilterEmail user's email address
+ * %{group} in FilterGroup group name
+ */
+$conf['plugin']['authmysql']['getUsers'] = "SELECT DISTINCT login AS user
+ FROM users AS u
+ LEFT JOIN usergroup AS ug ON u.uid=ug.uid
+ LEFT JOIN groups AS g ON ug.gid=g.gid";
+$conf['plugin']['authmysql']['FilterLogin'] = "login LIKE '%{user}'";
+$conf['plugin']['authmysql']['FilterName'] = "CONCAT(firstname,' ',lastname) LIKE '%{name}'";
+$conf['plugin']['authmysql']['FilterEmail'] = "email LIKE '%{email}'";
+$conf['plugin']['authmysql']['FilterGroup'] = "name LIKE '%{group}'";
+$conf['plugin']['authmysql']['SortOrder'] = "ORDER BY login";
+
+/***********************************************************************/
+/* Additional SQL statements to add new users with the user manager */
+/***********************************************************************/
+
+/* This statement should add a user to the database. Minimum information
+ * to store are: login name, password, email address and full name.
+ *
+ * Following patterns will be replaced:
+ * %{user} user's login name
+ * %{pass} password (encrypted or clear text, depends on 'encryptPass')
+ * %{email} email address
+ * %{name} user's full name
+ */
+$conf['plugin']['authmysql']['addUser'] = "INSERT INTO users
+ (login, pass, email, firstname, lastname)
+ VALUES ('%{user}', '%{pass}', '%{email}',
+ SUBSTRING_INDEX('%{name}',' ', 1),
+ SUBSTRING_INDEX('%{name}',' ', -1))";
+
+/* This statement should add a group to the database.
+ * Following patterns will be replaced:
+ * %{group} group name
+ */
+$conf['plugin']['authmysql']['addGroup'] = "INSERT INTO groups (name)
+ VALUES ('%{group}')";
+
+/* This statement should connect a user to a group (a user become member
+ * of that group).
+ * Following patterns will be replaced:
+ * %{user} user's login name
+ * %{uid} id of a user dataset
+ * %{group} group name
+ * %{gid} id of a group dataset
+ */
+$conf['plugin']['authmysql']['addUserGroup']= "INSERT INTO usergroup (uid, gid)
+ VALUES ('%{uid}', '%{gid}')";
+
+/* This statement should remove a group fom the database.
+ * Following patterns will be replaced:
+ * %{group} group name
+ * %{gid} id of a group dataset
+ */
+$conf['plugin']['authmysql']['delGroup'] = "DELETE FROM groups
+ WHERE gid='%{gid}'";
+
+/* This statement should return the database index of a given user name.
+ * The plugin will access the index with the name 'id' so an alias might be
+ * necessary.
+ * following patters will be replaced:
+ * %{user} user name
+ */
+$conf['plugin']['authmysql']['getUserID'] = "SELECT uid AS id
+ FROM users
+ WHERE login='%{user}'";
+
+/***********************************************************************/
+/* Additional SQL statements to delete users with the user manager */
+/***********************************************************************/
+
+/* This statement should remove a user fom the database.
+ * Following patterns will be replaced:
+ * %{user} user's login name
+ * %{uid} id of a user dataset
+ */
+$conf['plugin']['authmysql']['delUser'] = "DELETE FROM users
+ WHERE uid='%{uid}'";
+
+/* This statement should remove all connections from a user to any group
+ * (a user quits membership of all groups).
+ * Following patterns will be replaced:
+ * %{uid} id of a user dataset
+ */
+$conf['plugin']['authmysql']['delUserRefs'] = "DELETE FROM usergroup
+ WHERE uid='%{uid}'";
+
+/***********************************************************************/
+/* Additional SQL statements to modify users with the user manager */
+/***********************************************************************/
+
+/* This statements should modify a user entry in the database. The
+ * statements UpdateLogin, UpdatePass, UpdateEmail and UpdateName will be
+ * added to updateUser on demand. Only changed parameters will be used.
+ *
+ * Following patterns will be replaced:
+ * %{user} user's login name
+ * %{pass} password (encrypted or clear text, depends on 'encryptPass')
+ * %{email} email address
+ * %{name} user's full name
+ * %{uid} user id that should be updated
+ */
+$conf['plugin']['authmysql']['updateUser'] = "UPDATE users SET";
+$conf['plugin']['authmysql']['UpdateLogin'] = "login='%{user}'";
+$conf['plugin']['authmysql']['UpdatePass'] = "pass='%{pass}'";
+$conf['plugin']['authmysql']['UpdateEmail'] = "email='%{email}'";
+$conf['plugin']['authmysql']['UpdateName'] = "firstname=SUBSTRING_INDEX('%{name}',' ', 1),
+ lastname=SUBSTRING_INDEX('%{name}',' ', -1)";
+$conf['plugin']['authmysql']['UpdateTarget']= "WHERE uid=%{uid}";
+
+/* This statement should remove a single connection from a user to a
+ * group (a user quits membership of that group).
+ *
+ * Following patterns will be replaced:
+ * %{user} user's login name
+ * %{uid} id of a user dataset
+ * %{group} group name
+ * %{gid} id of a group dataset
+ */
+$conf['plugin']['authmysql']['delUserGroup']= "DELETE FROM usergroup
+ WHERE uid='%{uid}'
+ AND gid='%{gid}'";
+
+/* This statement should return the database index of a given group name.
+ * The plugin will access the index with the name 'id' so an alias might
+ * be necessary.
+ *
+ * Following patters will be replaced:
+ * %{group} group name
+ */
+$conf['plugin']['authmysql']['getGroupID'] = "SELECT gid AS id
+ FROM groups
+ WHERE name='%{group}'";
+
+
diff --git a/platform/www/conf/plugins.local.php b/platform/www/conf/plugins.local.php
new file mode 100644
index 0000000..4f256a9
--- /dev/null
+++ b/platform/www/conf/plugins.local.php
@@ -0,0 +1,8 @@
+<?php
+/*
+ * Local plugin enable/disable settings
+ * Auto-generated through plugin/extension manager
+ *
+ * NOTE: Plugins will not be added to this file unless there is a need to override a default setting. Plugins are
+ * enabled by default.
+ */
diff --git a/platform/www/conf/plugins.php b/platform/www/conf/plugins.php
new file mode 100644
index 0000000..b2c7997
--- /dev/null
+++ b/platform/www/conf/plugins.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * This file configures the default states of available plugins. All settings in
+ * the plugins.*.php files will override those here.
+ */
+$plugins['testing'] = 0;
diff --git a/platform/www/conf/plugins.required.php b/platform/www/conf/plugins.required.php
new file mode 100644
index 0000000..75336da
--- /dev/null
+++ b/platform/www/conf/plugins.required.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * This file configures the enabled/disabled status of plugins, which are also protected
+ * from changes by the extention manager. These settings will override any local settings.
+ * It is not recommended to change this file, as it is overwritten on DokuWiki upgrades.
+ */
+$plugins['acl'] = 1;
+$plugins['authplain'] = 1;
+$plugins['extension'] = 1;
+$plugins['config'] = 1;
+$plugins['usermanager'] = 1;
+$plugins['template:dokuwiki'] = 1; // not a plugin, but this should not be uninstalled either
diff --git a/platform/www/conf/scheme.conf b/platform/www/conf/scheme.conf
new file mode 100644
index 0000000..88cb3c4
--- /dev/null
+++ b/platform/www/conf/scheme.conf
@@ -0,0 +1,11 @@
+#Add URL schemes you want to be recognized as links here
+
+http
+https
+telnet
+gopher
+wais
+ftp
+ed2k
+irc
+ldap \ No newline at end of file
diff --git a/platform/www/conf/smileys.conf b/platform/www/conf/smileys.conf
new file mode 100644
index 0000000..80daed5
--- /dev/null
+++ b/platform/www/conf/smileys.conf
@@ -0,0 +1,28 @@
+# Smileys configured here will be replaced by the
+# configured images in the smiley directory
+
+8-) icon_cool.gif
+8-O icon_eek.gif
+8-o icon_eek.gif
+:-( icon_sad.gif
+:-) icon_smile.gif
+=) icon_smile2.gif
+:-/ icon_doubt.gif
+:-\ icon_doubt2.gif
+:-? icon_confused.gif
+:-D icon_biggrin.gif
+:-P icon_razz.gif
+:-o icon_surprised.gif
+:-O icon_surprised.gif
+:-x icon_silenced.gif
+:-X icon_silenced.gif
+:-| icon_neutral.gif
+;-) icon_wink.gif
+m( facepalm.gif
+^_^ icon_fun.gif
+:?: icon_question.gif
+:!: icon_exclaim.gif
+LOL icon_lol.gif
+FIXME fixme.gif
+DELETEME delete.gif
+
diff --git a/platform/www/conf/users.auth.php.dist b/platform/www/conf/users.auth.php.dist
new file mode 100644
index 0000000..8231aa5
--- /dev/null
+++ b/platform/www/conf/users.auth.php.dist
@@ -0,0 +1,10 @@
+# users.auth.php
+# <?php exit()?>
+# Don't modify the lines above
+#
+# Userfile
+#
+# Format:
+#
+# login:passwordhash:Real Name:email:groups,comma,separated
+
diff --git a/platform/www/conf/users.auth.php.sample b/platform/www/conf/users.auth.php.sample
new file mode 100644
index 0000000..164629a
--- /dev/null
+++ b/platform/www/conf/users.auth.php.sample
@@ -0,0 +1,11 @@
+# users.auth.php
+# <?php exit()?>
+# Don't modify the lines above
+#
+# Userfile
+#
+# Format:
+#
+# login:passwordhash:Real Name:email:groups,comma,seperated
+
+admin:$1$cce258b2$U9o5nK0z4MhTfB5QlKF23/:admin:admin@example.org:admin,user
diff --git a/platform/www/conf/wordblock.conf b/platform/www/conf/wordblock.conf
new file mode 100644
index 0000000..3040fa0
--- /dev/null
+++ b/platform/www/conf/wordblock.conf
@@ -0,0 +1,29 @@
+# This blacklist is maintained by the DokuWiki community
+# patches welcome
+#
+https?:\/\/(\S*?)(-side-effects|top|pharm|pill|discount|discount-|deal|price|order|now|best|cheap|cheap-|online|buy|buy-|sale|sell)(\S*?)(cialis|viagra|prazolam|xanax|zanax|soma|vicodin|zenical|xenical|meridia|paxil|prozac|claritin|allegra|lexapro|wellbutrin|zoloft|retin|valium|levitra|phentermine)
+https?:\/\/(\S*?)(bi\s*sex|gay\s*sex|fetish|incest|penis|\brape\b)
+zoosex
+gang\s*bang
+facials
+ladyboy
+\btits\b
+bolea\.com
+52crystal
+baida\.org
+web-directory\.awardspace\.us
+korsan-team\.com
+BUDA TAMAMDIR
+wow-powerleveling-wow\.com
+wow gold
+wow-gold\.dinmo\.cn
+downgrade-vista\.com
+downgradetowindowsxp\.com
+elegantugg\.com
+classicedhardy\.com
+research-service\.com
+https?:\/\/(\S*?)(2-pay-secure|911essay|academia-research|anypapers|applicationessay|bestbuyessay|bestdissertation|bestessay|bestresume|besttermpaper|businessessay|college-paper|customessay|custom-made-paper|custom-writing|degree-?result|dissertationblog|dissertation-service|dissertations?expert|essaybank|essay-?blog|essaycapital|essaylogic|essaymill|essayontime|essaypaper|essays?land|essaytownsucks|essay-?writ|fastessays|freelancercareers|genuinecontent|genuineessay|genuinepaper|goessay|grandresume|killer-content|ma-dissertation|managementessay|masterpaper|mightystudent|needessay|researchedge|researchpaper-blog|resumecvservice|resumesexperts|resumesplanet|rushessay|samedayessay|superiorcontent|superiorpaper|superiorthesis|term-paper|termpaper-blog|term-paper-research|thesisblog|universalresearch|valwriting|vdwriters|wisetranslation|writersassembly|writers\.com\.ph|writers\.ph)
+flatsinmumbai\.co\.in
+https?:\/\/(\S*?)penny-?stock
+mattressreview\.biz
+(just|simply) (my|a) profile (site|webpage|page)
diff --git a/platform/www/data/.htaccess b/platform/www/data/.htaccess
new file mode 100644
index 0000000..7625314
--- /dev/null
+++ b/platform/www/data/.htaccess
@@ -0,0 +1,7 @@
+<IfModule mod_authz_core.c>
+ Require all denied
+</IfModule>
+<IfModule !mod_authz_core.c>
+ Order allow,deny
+ Deny from all
+</IfModule>
diff --git a/platform/www/data/_dummy b/platform/www/data/_dummy
new file mode 100644
index 0000000..e492265
--- /dev/null
+++ b/platform/www/data/_dummy
@@ -0,0 +1 @@
+You can safely delete this file. \ No newline at end of file
diff --git a/platform/www/data/deleted.files b/platform/www/data/deleted.files
new file mode 100644
index 0000000..1d5db7c
--- /dev/null
+++ b/platform/www/data/deleted.files
@@ -0,0 +1,846 @@
+# This is a list of files that were present in previous DokuWiki releases
+# but were removed later. An up to date DokuWiki should not have any of
+# the files installed
+
+# removed in 2020-06-01
+inc/PluginInterface.php
+inc/PluginTrait.php
+inc/HTTPClient.php
+inc/PassHash.class.php
+inc/remote.php
+inc/RemoteAPICore.php
+inc/Sitemapper.php
+lib/plugins/config/_test/configuration.test.php
+inc/Input.class.php
+inc/JSON.php
+inc/Plugin.php
+inc/events.php
+inc/lang/.htaccess
+inc/lang/az/wordblock.txt
+inc/lang/gl/wordblock.txt
+inc/lang/ru/wordblock.txt
+inc/parser/lexer.php
+inc/plugincontroller.class.php
+inc/subscription.php
+lib/plugins/authmysql/auth.php
+lib/plugins/authmysql/conf/default.php
+lib/plugins/authmysql/conf/metadata.php
+lib/plugins/authmysql/lang/bg/lang.php
+lib/plugins/authmysql/lang/bg/settings.php
+lib/plugins/authmysql/lang/cs/lang.php
+lib/plugins/authmysql/lang/cs/settings.php
+lib/plugins/authmysql/lang/cy/lang.php
+lib/plugins/authmysql/lang/cy/settings.php
+lib/plugins/authmysql/lang/da/lang.php
+lib/plugins/authmysql/lang/da/settings.php
+lib/plugins/authmysql/lang/de-informal/lang.php
+lib/plugins/authmysql/lang/de-informal/settings.php
+lib/plugins/authmysql/lang/de/lang.php
+lib/plugins/authmysql/lang/de/settings.php
+lib/plugins/authmysql/lang/en/lang.php
+lib/plugins/authmysql/lang/en/settings.php
+lib/plugins/authmysql/lang/eo/lang.php
+lib/plugins/authmysql/lang/eo/settings.php
+lib/plugins/authmysql/lang/es/lang.php
+lib/plugins/authmysql/lang/es/settings.php
+lib/plugins/authmysql/lang/eu/lang.php
+lib/plugins/authmysql/lang/eu/settings.php
+lib/plugins/authmysql/lang/fa/lang.php
+lib/plugins/authmysql/lang/fa/settings.php
+lib/plugins/authmysql/lang/fi/settings.php
+lib/plugins/authmysql/lang/fr/lang.php
+lib/plugins/authmysql/lang/fr/settings.php
+lib/plugins/authmysql/lang/he/settings.php
+lib/plugins/authmysql/lang/hr/lang.php
+lib/plugins/authmysql/lang/hr/settings.php
+lib/plugins/authmysql/lang/hu/lang.php
+lib/plugins/authmysql/lang/hu/settings.php
+lib/plugins/authmysql/lang/it/lang.php
+lib/plugins/authmysql/lang/it/settings.php
+lib/plugins/authmysql/lang/ja/lang.php
+lib/plugins/authmysql/lang/ja/settings.php
+lib/plugins/authmysql/lang/ko/lang.php
+lib/plugins/authmysql/lang/ko/settings.php
+lib/plugins/authmysql/lang/lv/settings.php
+lib/plugins/authmysql/lang/nl/lang.php
+lib/plugins/authmysql/lang/nl/settings.php
+lib/plugins/authmysql/lang/no/lang.php
+lib/plugins/authmysql/lang/no/settings.php
+lib/plugins/authmysql/lang/pl/lang.php
+lib/plugins/authmysql/lang/pl/settings.php
+lib/plugins/authmysql/lang/pt-br/lang.php
+lib/plugins/authmysql/lang/pt-br/settings.php
+lib/plugins/authmysql/lang/pt/lang.php
+lib/plugins/authmysql/lang/pt/settings.php
+lib/plugins/authmysql/lang/ru/lang.php
+lib/plugins/authmysql/lang/ru/settings.php
+lib/plugins/authmysql/lang/sk/lang.php
+lib/plugins/authmysql/lang/sk/settings.php
+lib/plugins/authmysql/lang/sl/settings.php
+lib/plugins/authmysql/lang/sr/lang.php
+lib/plugins/authmysql/lang/sr/settings.php
+lib/plugins/authmysql/lang/sv/lang.php
+lib/plugins/authmysql/lang/sv/settings.php
+lib/plugins/authmysql/lang/tr/lang.php
+lib/plugins/authmysql/lang/tr/settings.php
+lib/plugins/authmysql/lang/uk/lang.php
+lib/plugins/authmysql/lang/zh-tw/settings.php
+lib/plugins/authmysql/lang/zh/lang.php
+lib/plugins/authmysql/lang/zh/settings.php
+lib/plugins/authmysql/plugin.info.txt
+lib/plugins/authpgsql/auth.php
+lib/plugins/authpgsql/conf/default.php
+lib/plugins/authpgsql/conf/metadata.php
+lib/plugins/authpgsql/lang/bg/settings.php
+lib/plugins/authpgsql/lang/cs/settings.php
+lib/plugins/authpgsql/lang/cy/settings.php
+lib/plugins/authpgsql/lang/da/settings.php
+lib/plugins/authpgsql/lang/de-informal/settings.php
+lib/plugins/authpgsql/lang/de/settings.php
+lib/plugins/authpgsql/lang/en/settings.php
+lib/plugins/authpgsql/lang/eo/settings.php
+lib/plugins/authpgsql/lang/es/settings.php
+lib/plugins/authpgsql/lang/fa/settings.php
+lib/plugins/authpgsql/lang/fr/settings.php
+lib/plugins/authpgsql/lang/hr/settings.php
+lib/plugins/authpgsql/lang/hu/settings.php
+lib/plugins/authpgsql/lang/it/settings.php
+lib/plugins/authpgsql/lang/ja/settings.php
+lib/plugins/authpgsql/lang/ko/settings.php
+lib/plugins/authpgsql/lang/lv/settings.php
+lib/plugins/authpgsql/lang/nl/settings.php
+lib/plugins/authpgsql/lang/no/settings.php
+lib/plugins/authpgsql/lang/pl/settings.php
+lib/plugins/authpgsql/lang/pt-br/settings.php
+lib/plugins/authpgsql/lang/pt/settings.php
+lib/plugins/authpgsql/lang/ru/settings.php
+lib/plugins/authpgsql/lang/sk/settings.php
+lib/plugins/authpgsql/lang/sl/settings.php
+lib/plugins/authpgsql/lang/sr/settings.php
+lib/plugins/authpgsql/lang/sv/settings.php
+lib/plugins/authpgsql/lang/tr/settings.php
+lib/plugins/authpgsql/lang/uk/settings.php
+lib/plugins/authpgsql/lang/zh-tw/settings.php
+lib/plugins/authpgsql/lang/zh/settings.php
+lib/plugins/authpgsql/plugin.info.txt
+lib/plugins/config/settings/config.class.php
+lib/plugins/config/settings/extra.class.php
+lib/plugins/styling/iris.js
+lib/scripts/jquery/jquery-migrate.min.js
+vendor/paragonie/random_compat/psalm-autoload.php
+vendor/paragonie/random_compat/psalm.xml
+
+# removed in 2018-04-22
+data/security.png
+data/security.xcf
+inc/EmailAddressValidator.php
+inc/blowfish.php
+inc/feedcreator.class.php
+inc/lessc.inc.php
+inc/plugin.php
+lib/images/loading.gif
+lib/tpl/dokuwiki/css/_search.css
+vendor/easybook/geshi
+vendor/phpseclib/phpseclib/composer.lock
+
+# remove in 2017-02-19
+inc/SimplePie.php
+inc/Tar.class.php
+inc/ZipLib.class.php
+inc/phpseclib/Crypt_AES.php
+inc/phpseclib/Crypt_Rijndael.php
+inc/phpseclib/update.sh
+inc/phpseclib/LICENSE
+inc/phpseclib/Crypt_Base.php
+inc/phpseclib/Crypt_Hash.php
+inc/phpseclib/Math_BigInteger.php
+lib/scripts/jquery/jquery-migrate.js
+lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_0_aaaaaa_40x100.png
+lib/scripts/jquery/jquery-ui-theme/images/ui-bg_flat_75_ffffff_40x100.png
+lib/scripts/jquery/jquery-ui.js
+lib/scripts/jquery/jquery.js
+lib/tpl/dokuwiki/css/_admin.css
+
+# removed in 2016-06-26
+inc/cliopts.php
+lib/tpl/dokuwiki/css/mixins.less
+
+# removed in 2015-08-10
+inc/TarLib.class.php
+inc/geshi.php
+inc/geshi/4cs.php
+inc/geshi/6502acme.php
+inc/geshi/6502kickass.php
+inc/geshi/6502tasm.php
+inc/geshi/68000devpac.php
+inc/geshi/abap.php
+inc/geshi/actionscript-french.php
+inc/geshi/actionscript.php
+inc/geshi/actionscript3.php
+inc/geshi/ada.php
+inc/geshi/algol68.php
+inc/geshi/apache.php
+inc/geshi/applescript.php
+inc/geshi/apt_sources.php
+inc/geshi/arm.php
+inc/geshi/asm.php
+inc/geshi/asp.php
+inc/geshi/asymptote.php
+inc/geshi/autoconf.php
+inc/geshi/autohotkey.php
+inc/geshi/autoit.php
+inc/geshi/avisynth.php
+inc/geshi/awk.php
+inc/geshi/bascomavr.php
+inc/geshi/bash.php
+inc/geshi/basic4gl.php
+inc/geshi/bf.php
+inc/geshi/bibtex.php
+inc/geshi/blitzbasic.php
+inc/geshi/bnf.php
+inc/geshi/boo.php
+inc/geshi/c.php
+inc/geshi/c_loadrunner.php
+inc/geshi/c_mac.php
+inc/geshi/caddcl.php
+inc/geshi/cadlisp.php
+inc/geshi/cfdg.php
+inc/geshi/cfm.php
+inc/geshi/chaiscript.php
+inc/geshi/cil.php
+inc/geshi/clojure.php
+inc/geshi/cmake.php
+inc/geshi/cobol.php
+inc/geshi/coffeescript.php
+inc/geshi/cpp-qt.php
+inc/geshi/cpp.php
+inc/geshi/csharp.php
+inc/geshi/css.php
+inc/geshi/cuesheet.php
+inc/geshi/d.php
+inc/geshi/dcl.php
+inc/geshi/dcpu16.php
+inc/geshi/dcs.php
+inc/geshi/delphi.php
+inc/geshi/diff.php
+inc/geshi/div.php
+inc/geshi/dos.php
+inc/geshi/dot.php
+inc/geshi/e.php
+inc/geshi/ecmascript.php
+inc/geshi/eiffel.php
+inc/geshi/email.php
+inc/geshi/epc.php
+inc/geshi/erlang.php
+inc/geshi/euphoria.php
+inc/geshi/f1.php
+inc/geshi/falcon.php
+inc/geshi/fo.php
+inc/geshi/fortran.php
+inc/geshi/freebasic.php
+inc/geshi/freeswitch.php
+inc/geshi/fsharp.php
+inc/geshi/gambas.php
+inc/geshi/gdb.php
+inc/geshi/genero.php
+inc/geshi/genie.php
+inc/geshi/gettext.php
+inc/geshi/glsl.php
+inc/geshi/gml.php
+inc/geshi/gnuplot.php
+inc/geshi/go.php
+inc/geshi/groovy.php
+inc/geshi/gwbasic.php
+inc/geshi/haskell.php
+inc/geshi/haxe.php
+inc/geshi/hicest.php
+inc/geshi/hq9plus.php
+inc/geshi/html4strict.php
+inc/geshi/html5.php
+inc/geshi/icon.php
+inc/geshi/idl.php
+inc/geshi/ini.php
+inc/geshi/inno.php
+inc/geshi/intercal.php
+inc/geshi/io.php
+inc/geshi/j.php
+inc/geshi/java.php
+inc/geshi/java5.php
+inc/geshi/javascript.php
+inc/geshi/jquery.php
+inc/geshi/kixtart.php
+inc/geshi/klonec.php
+inc/geshi/klonecpp.php
+inc/geshi/latex.php
+inc/geshi/lb.php
+inc/geshi/ldif.php
+inc/geshi/lisp.php
+inc/geshi/llvm.php
+inc/geshi/locobasic.php
+inc/geshi/logtalk.php
+inc/geshi/lolcode.php
+inc/geshi/lotusformulas.php
+inc/geshi/lotusscript.php
+inc/geshi/lscript.php
+inc/geshi/lsl2.php
+inc/geshi/lua.php
+inc/geshi/m68k.php
+inc/geshi/magiksf.php
+inc/geshi/make.php
+inc/geshi/mapbasic.php
+inc/geshi/matlab.php
+inc/geshi/mirc.php
+inc/geshi/mmix.php
+inc/geshi/modula2.php
+inc/geshi/modula3.php
+inc/geshi/mpasm.php
+inc/geshi/mxml.php
+inc/geshi/mysql.php
+inc/geshi/nagios.php
+inc/geshi/netrexx.php
+inc/geshi/newlisp.php
+inc/geshi/nsis.php
+inc/geshi/oberon2.php
+inc/geshi/objc.php
+inc/geshi/objeck.php
+inc/geshi/ocaml-brief.php
+inc/geshi/ocaml.php
+inc/geshi/octave.php
+inc/geshi/oobas.php
+inc/geshi/oorexx.php
+inc/geshi/oracle11.php
+inc/geshi/oracle8.php
+inc/geshi/oxygene.php
+inc/geshi/oz.php
+inc/geshi/parasail.php
+inc/geshi/parigp.php
+inc/geshi/pascal.php
+inc/geshi/pcre.php
+inc/geshi/per.php
+inc/geshi/perl.php
+inc/geshi/perl6.php
+inc/geshi/pf.php
+inc/geshi/php-brief.php
+inc/geshi/php.php
+inc/geshi/pic16.php
+inc/geshi/pike.php
+inc/geshi/pixelbender.php
+inc/geshi/pli.php
+inc/geshi/plsql.php
+inc/geshi/postgresql.php
+inc/geshi/povray.php
+inc/geshi/powerbuilder.php
+inc/geshi/powershell.php
+inc/geshi/proftpd.php
+inc/geshi/progress.php
+inc/geshi/prolog.php
+inc/geshi/properties.php
+inc/geshi/providex.php
+inc/geshi/purebasic.php
+inc/geshi/pycon.php
+inc/geshi/pys60.php
+inc/geshi/python.php
+inc/geshi/q.php
+inc/geshi/qbasic.php
+inc/geshi/rails.php
+inc/geshi/rebol.php
+inc/geshi/reg.php
+inc/geshi/rexx.php
+inc/geshi/robots.php
+inc/geshi/rpmspec.php
+inc/geshi/rsplus.php
+inc/geshi/ruby.php
+inc/geshi/sas.php
+inc/geshi/scala.php
+inc/geshi/scheme.php
+inc/geshi/scilab.php
+inc/geshi/sdlbasic.php
+inc/geshi/smalltalk.php
+inc/geshi/smarty.php
+inc/geshi/spark.php
+inc/geshi/sparql.php
+inc/geshi/sql.php
+inc/geshi/stonescript.php
+inc/geshi/systemverilog.php
+inc/geshi/tcl.php
+inc/geshi/teraterm.php
+inc/geshi/text.php
+inc/geshi/thinbasic.php
+inc/geshi/tsql.php
+inc/geshi/typoscript.php
+inc/geshi/unicon.php
+inc/geshi/upc.php
+inc/geshi/urbi.php
+inc/geshi/uscript.php
+inc/geshi/vala.php
+inc/geshi/vb.php
+inc/geshi/vbnet.php
+inc/geshi/vedit.php
+inc/geshi/verilog.php
+inc/geshi/vhdl.php
+inc/geshi/vim.php
+inc/geshi/visualfoxpro.php
+inc/geshi/visualprolog.php
+inc/geshi/whitespace.php
+inc/geshi/whois.php
+inc/geshi/winbatch.php
+inc/geshi/xbasic.php
+inc/geshi/xml.php
+inc/geshi/xorg_conf.php
+inc/geshi/xpp.php
+inc/geshi/yaml.php
+inc/geshi/z80.php
+inc/geshi/zxbasic.php
+lib/images/interwiki/coral.gif
+lib/images/interwiki/dokubug.gif
+lib/images/interwiki/sb.gif
+lib/scripts/drag.js
+lib/scripts/jquery/jquery-ui-theme/images/animated-overlay.gif
+lib/scripts/tw-sack.js
+
+# removed in 2014-05-05
+lib/images/fileicons/audio.png
+lib/plugins/plugin/admin.php
+lib/plugins/plugin/classes/ap_delete.class.php
+lib/plugins/plugin/classes/ap_download.class.php
+lib/plugins/plugin/classes/ap_enable.class.php
+lib/plugins/plugin/classes/ap_info.class.php
+lib/plugins/plugin/classes/ap_manage.class.php
+lib/plugins/plugin/classes/ap_update.class.php
+lib/plugins/plugin/lang/af/lang.php
+lib/plugins/plugin/lang/ar/admin_plugin.txt
+lib/plugins/plugin/lang/ar/lang.php
+lib/plugins/plugin/lang/bg/admin_plugin.txt
+lib/plugins/plugin/lang/bg/lang.php
+lib/plugins/plugin/lang/ca-valencia/admin_plugin.txt
+lib/plugins/plugin/lang/ca-valencia/lang.php
+lib/plugins/plugin/lang/ca/admin_plugin.txt
+lib/plugins/plugin/lang/ca/lang.php
+lib/plugins/plugin/lang/cs/admin_plugin.txt
+lib/plugins/plugin/lang/cs/lang.php
+lib/plugins/plugin/lang/da/admin_plugin.txt
+lib/plugins/plugin/lang/da/lang.php
+lib/plugins/plugin/lang/de-informal/admin_plugin.txt
+lib/plugins/plugin/lang/de-informal/lang.php
+lib/plugins/plugin/lang/de/admin_plugin.txt
+lib/plugins/plugin/lang/de/lang.php
+lib/plugins/plugin/lang/el/admin_plugin.txt
+lib/plugins/plugin/lang/el/lang.php
+lib/plugins/plugin/lang/en/admin_plugin.txt
+lib/plugins/plugin/lang/en/lang.php
+lib/plugins/plugin/lang/eo/admin_plugin.txt
+lib/plugins/plugin/lang/eo/lang.php
+lib/plugins/plugin/lang/es/admin_plugin.txt
+lib/plugins/plugin/lang/es/lang.php
+lib/plugins/plugin/lang/et/lang.php
+lib/plugins/plugin/lang/eu/admin_plugin.txt
+lib/plugins/plugin/lang/eu/lang.php
+lib/plugins/plugin/lang/fa/admin_plugin.txt
+lib/plugins/plugin/lang/fa/lang.php
+lib/plugins/plugin/lang/fi/admin_plugin.txt
+lib/plugins/plugin/lang/fi/lang.php
+lib/plugins/plugin/lang/fr/admin_plugin.txt
+lib/plugins/plugin/lang/fr/lang.php
+lib/plugins/plugin/lang/gl/admin_plugin.txt
+lib/plugins/plugin/lang/gl/lang.php
+lib/plugins/plugin/lang/he/admin_plugin.txt
+lib/plugins/plugin/lang/he/lang.php
+lib/plugins/plugin/lang/hi/lang.php
+lib/plugins/plugin/lang/hr/lang.php
+lib/plugins/plugin/lang/hu/admin_plugin.txt
+lib/plugins/plugin/lang/hu/lang.php
+lib/plugins/plugin/lang/ia/admin_plugin.txt
+lib/plugins/plugin/lang/ia/lang.php
+lib/plugins/plugin/lang/id-ni/lang.php
+lib/plugins/plugin/lang/id/lang.php
+lib/plugins/plugin/lang/is/lang.php
+lib/plugins/plugin/lang/it/admin_plugin.txt
+lib/plugins/plugin/lang/it/lang.php
+lib/plugins/plugin/lang/ja/admin_plugin.txt
+lib/plugins/plugin/lang/ja/lang.php
+lib/plugins/plugin/lang/kk/lang.php
+lib/plugins/plugin/lang/ko/admin_plugin.txt
+lib/plugins/plugin/lang/ko/lang.php
+lib/plugins/plugin/lang/la/admin_plugin.txt
+lib/plugins/plugin/lang/la/lang.php
+lib/plugins/plugin/lang/lb/admin_plugin.txt
+lib/plugins/plugin/lang/lb/lang.php
+lib/plugins/plugin/lang/lt/admin_plugin.txt
+lib/plugins/plugin/lang/lt/lang.php
+lib/plugins/plugin/lang/lv/admin_plugin.txt
+lib/plugins/plugin/lang/lv/lang.php
+lib/plugins/plugin/lang/mk/lang.php
+lib/plugins/plugin/lang/mr/admin_plugin.txt
+lib/plugins/plugin/lang/mr/lang.php
+lib/plugins/plugin/lang/ms/lang.php
+lib/plugins/plugin/lang/ne/lang.php
+lib/plugins/plugin/lang/nl/admin_plugin.txt
+lib/plugins/plugin/lang/nl/lang.php
+lib/plugins/plugin/lang/no/admin_plugin.txt
+lib/plugins/plugin/lang/no/lang.php
+lib/plugins/plugin/lang/pl/admin_plugin.txt
+lib/plugins/plugin/lang/pl/lang.php
+lib/plugins/plugin/lang/pt-br/admin_plugin.txt
+lib/plugins/plugin/lang/pt-br/lang.php
+lib/plugins/plugin/lang/pt/admin_plugin.txt
+lib/plugins/plugin/lang/pt/lang.php
+lib/plugins/plugin/lang/ro/admin_plugin.txt
+lib/plugins/plugin/lang/ro/lang.php
+lib/plugins/plugin/lang/ru/admin_plugin.txt
+lib/plugins/plugin/lang/ru/lang.php
+lib/plugins/plugin/lang/sk/admin_plugin.txt
+lib/plugins/plugin/lang/sk/lang.php
+lib/plugins/plugin/lang/sl/admin_plugin.txt
+lib/plugins/plugin/lang/sl/lang.php
+lib/plugins/plugin/lang/sq/admin_plugin.txt
+lib/plugins/plugin/lang/sq/lang.php
+lib/plugins/plugin/lang/sr/admin_plugin.txt
+lib/plugins/plugin/lang/sr/lang.php
+lib/plugins/plugin/lang/sv/admin_plugin.txt
+lib/plugins/plugin/lang/sv/lang.php
+lib/plugins/plugin/lang/th/admin_plugin.txt
+lib/plugins/plugin/lang/th/lang.php
+lib/plugins/plugin/lang/tr/admin_plugin.txt
+lib/plugins/plugin/lang/tr/lang.php
+lib/plugins/plugin/lang/uk/admin_plugin.txt
+lib/plugins/plugin/lang/uk/lang.php
+lib/plugins/plugin/lang/vi/lang.php
+lib/plugins/plugin/lang/zh-tw/admin_plugin.txt
+lib/plugins/plugin/lang/zh-tw/lang.php
+lib/plugins/plugin/lang/zh/admin_plugin.txt
+lib/plugins/plugin/lang/zh/lang.php
+lib/plugins/plugin/plugin.info.txt
+lib/plugins/plugin/style.css
+
+# removed in 2013-11-18
+lib/images/arrow_down.gif
+lib/images/arrow_up.gif
+lib/images/at.gif
+lib/images/close.png
+lib/images/del.png
+lib/images/edit.gif
+lib/images/list-minus.gif
+lib/images/list-plus.gif
+lib/images/pencil.png
+
+# removed in 2013-10-28
+lib/images/interwiki/meatball.gif
+lib/images/interwiki/wiki.gif
+lib/plugins/acl/ajax.php
+lib/tpl/default/_admin.css
+lib/tpl/default/_fileuploader.css
+lib/tpl/default/_linkwiz.css
+lib/tpl/default/_mediamanager.css
+lib/tpl/default/_mediaoptions.css
+lib/tpl/default/_subscription.css
+lib/tpl/default/_tabs.css
+lib/tpl/default/design.css
+lib/tpl/default/detail.php
+lib/tpl/default/footer.html
+lib/tpl/default/images/UWEB.png
+lib/tpl/default/images/UWEBshadow.png
+lib/tpl/default/images/apple-touch-icon.png
+lib/tpl/default/images/bullet.gif
+lib/tpl/default/images/button-cc.gif
+lib/tpl/default/images/button-css.png
+lib/tpl/default/images/button-donate.gif
+lib/tpl/default/images/button-dw.png
+lib/tpl/default/images/button-php.gif
+lib/tpl/default/images/button-rss.png
+lib/tpl/default/images/button-xhtml.png
+lib/tpl/default/images/buttonshadow.png
+lib/tpl/default/images/closed.gif
+lib/tpl/default/images/favicon.ico
+lib/tpl/default/images/inputshadow.png
+lib/tpl/default/images/link_icon.gif
+lib/tpl/default/images/mail_icon.gif
+lib/tpl/default/images/open.gif
+lib/tpl/default/images/resizecol.png
+lib/tpl/default/images/tocdot2.gif
+lib/tpl/default/images/windows.gif
+lib/tpl/default/layout.css
+lib/tpl/default/main.php
+lib/tpl/default/media.css
+lib/tpl/default/mediamanager.php
+lib/tpl/default/print.css
+lib/tpl/default/rtl.css
+lib/tpl/default/style.ini
+lib/tpl/default/template.info.txt
+lib/tpl/dokuwiki/css/basic.css
+lib/tpl/dokuwiki/css/content.css
+lib/tpl/dokuwiki/css/design.css
+lib/tpl/dokuwiki/css/includes.css
+lib/tpl/dokuwiki/css/mobile.css
+lib/tpl/dokuwiki/css/pagetools.css
+lib/tpl/dokuwiki/css/structure.css
+
+# removed in 2013-05-10
+lib/plugins/info/lang/sl/lang.php
+
+# removed in 2013-04-06
+inc/adLDAP.php
+inc/auth/ad.class.php
+inc/auth/basic.class.php
+inc/auth/ldap.class.php
+inc/auth/mysql.class.php
+inc/auth/pgsql.class.php
+inc/auth/plain.class.php
+
+# removed in 2012-09-10
+lib/images/icon-file.png
+lib/images/icon-thumb.png
+lib/images/interwiki/skype.png
+lib/plugins/acl/rtl.css
+lib/plugins/config/rtl.css
+lib/plugins/plugin/rtl.css
+
+# removed in 2011-11-10
+lib/_fla/.htaccess
+lib/_fla/MultipleUpload.as
+lib/_fla/README
+lib/_fla/index.html
+lib/_fla/multipleUpload.fla
+lib/exe/multipleUpload.swf
+lib/images/multiupload.png
+lib/scripts/ajax.js
+lib/scripts/events.js
+lib/scripts/subscriptions.js
+
+# removed in 2011-05-25
+conf/words.aspell.dist
+lib/styles/style.css
+
+# removed in 2010-11-07
+inc/lang/ar/subscribermail.txt
+inc/lang/az/subscribermail.txt
+inc/lang/bg/subscribermail.txt
+inc/lang/ca/subscribermail.txt
+inc/lang/ca-valencia/subscribermail.txt
+inc/lang/cs/subscribermail.txt
+inc/lang/da/subscribermail.txt
+inc/lang/de-informal/subscribermail.txt
+inc/lang/el/subscribermail.txt
+inc/lang/eo/subscribermail.txt
+inc/lang/es/subscribermail.txt
+inc/lang/et/subscribermail.txt
+inc/lang/eu/subscribermail.txt
+inc/lang/fa/subscribermail.txt
+inc/lang/fi/subscribermail.txt
+inc/lang/fo/subscribermail.txt
+inc/lang/fr/subscribermail.txt
+inc/lang/gl/subscribermail.txt
+inc/lang/he/subscribermail.txt
+inc/lang/hr/subscribermail.txt
+inc/lang/hu/subscribermail.txt
+inc/lang/id/subscribermail.txt
+inc/lang/is/subscribermail.txt
+inc/lang/it/subscribermail.txt
+inc/lang/ja/subscribermail.txt
+inc/lang/ko/subscribermail.txt
+inc/lang/ku/subscribermail.txt
+inc/lang/lt/subscribermail.txt
+inc/lang/lv/subscribermail.txt
+inc/lang/mr/subscribermail.txt
+inc/lang/ne/subscribermail.txt
+inc/lang/nl/subscribermail.txt
+inc/lang/no/subscribermail.txt
+inc/lang/pl/subscribermail.txt
+inc/lang/pt-br/subscribermail.txt
+inc/lang/pt/subscribermail.txt
+inc/lang/ro/subscribermail.txt
+inc/lang/ru/subscribermail.txt
+inc/lang/sk/subscribermail.txt
+inc/lang/sr/subscribermail.txt
+inc/lang/sv/subscribermail.txt
+inc/lang/th/subscribermail.txt
+inc/lang/tr/subscribermail.txt
+inc/lang/uk/subscribermail.txt
+inc/lang/zh/subscribermail.txt
+inc/lang/zh-tw/subscribermail.txt
+
+# removed in rc2010-10-07
+conf/msg
+inc/lang/bg/wordblock.txt
+inc/lang/ca-valencia/wordblock.txt
+inc/lang/ca/wordblock.txt
+inc/lang/cs/wordblock.txt
+inc/lang/da/wordblock.txt
+inc/lang/de-informal/wordblock.txt
+inc/lang/de/subscribermail.txt
+inc/lang/de/wordblock.txt
+inc/lang/el/wordblock.txt
+inc/lang/en/subscribermail.txt
+inc/lang/en/wordblock.txt
+inc/lang/eo/wordblock.txt
+inc/lang/es/wordblock.txt
+inc/lang/et/wordblock.txt
+inc/lang/eu/wordblock.txt
+inc/lang/fa/wordblock.txt
+inc/lang/fi/wordblock.txt
+inc/lang/fo/wordblock.txt
+inc/lang/fr/wordblock.txt
+inc/lang/he/wordblock.txt
+inc/lang/hr/wordblock.txt
+inc/lang/hu/wordblock.txt
+inc/lang/id/wordblock.txt
+inc/lang/it/wordblock.txt
+inc/lang/ja/wordblock.txt
+inc/lang/ko/wordblock.txt
+inc/lang/ku/wordblock.txt
+inc/lang/lt/wordblock.txt
+inc/lang/lv/wordblock.txt
+inc/lang/mg/wordblock.txt
+inc/lang/mr/wordblock.txt
+inc/lang/nl/wordblock.txt
+inc/lang/no/wordblock.txt
+inc/lang/pl/wordblock.txt
+inc/lang/pt-br/wordblock.txt
+inc/lang/pt/wordblock.txt
+inc/lang/ro/wordblock.txt
+inc/lang/sk/wordblock.txt
+inc/lang/sl/wordblock.txt
+inc/lang/sr/wordblock.txt
+inc/lang/sv/wordblock.txt
+inc/lang/th/wordblock.txt
+inc/lang/tr/wordblock.txt
+inc/lang/uk/wordblock.txt
+inc/lang/vi/wordblock.txt
+inc/lang/zh-tw/wordblock.txt
+inc/lang/zh/wordblock.txt
+lib/scripts/pngbehavior.htc
+
+# removed in rc2009-12-02
+inc/lang/ar/wordblock.txt
+inc/lang/ca-va/
+lib/plugins/acl/lang/ca-va/
+lib/plugins/config/lang/ca-va/
+lib/plugins/plugin/lang/ca-va/
+lib/plugins/popularity/lang/ca-va/
+lib/plugins/revert/lang/ca-va/
+lib/plugins/usermanager/lang/ca-va/
+
+# removed in rc2009-01-30
+lib/plugins/upgradeplugindirectory
+lib/plugins/upgradeplugindirectory/action.php
+
+# removed in rc2009-01-26
+inc/auth/punbb.class.php
+inc/lang/ko/edit.txt_bak
+inc/lang/ko/lang.php_bak
+inc/lang/ku/admin_acl.txt
+inc/lang/mg/admin_acl.txt
+lib/plugins/importoldchangelog
+lib/plugins/importoldchangelog/action.php
+lib/plugins/importoldindex
+lib/plugins/importoldindex/action.php
+lib/plugins/usermanager/images/no_user_edit.png
+lib/plugins/usermanager/images/user_edit.png
+lib/tpl/default/UWEB.css
+
+# removed in rc2008-03-31
+inc/aspell.php
+inc/geshi/css-gen.cfg
+inc/lang/fr/admin_acl.txt
+lib/exe/spellcheck.php
+lib/images/toolbar/spellcheck.png
+lib/images/toolbar/spellnoerr.png
+lib/images/toolbar/spellstop.png
+lib/images/toolbar/spellwait.gif
+lib/plugins/acl/lang/ar/intro.txt
+lib/plugins/acl/lang/bg/intro.txt
+lib/plugins/acl/lang/ca/intro.txt
+lib/plugins/acl/lang/cs/intro.txt
+lib/plugins/acl/lang/da/intro.txt
+lib/plugins/acl/lang/de/intro.txt
+lib/plugins/acl/lang/el/intro.txt
+lib/plugins/acl/lang/en/intro.txt
+lib/plugins/acl/lang/es/intro.txt
+lib/plugins/acl/lang/et/intro.txt
+lib/plugins/acl/lang/eu/intro.txt
+lib/plugins/acl/lang/fi/intro.txt
+lib/plugins/acl/lang/fr/intro.txt
+lib/plugins/acl/lang/gl/intro.txt
+lib/plugins/acl/lang/he/intro.txt
+lib/plugins/acl/lang/id/intro.txt
+lib/plugins/acl/lang/it/intro.txt
+lib/plugins/acl/lang/ja/intro.txt
+lib/plugins/acl/lang/ko/intro.txt
+lib/plugins/acl/lang/lt/intro.txt
+lib/plugins/acl/lang/lv/intro.txt
+lib/plugins/acl/lang/nl/intro.txt
+lib/plugins/acl/lang/no/intro.txt
+lib/plugins/acl/lang/pl/intro.txt
+lib/plugins/acl/lang/pt/intro.txt
+lib/plugins/acl/lang/ru/intro.txt
+lib/plugins/acl/lang/sk/intro.txt
+lib/plugins/acl/lang/sr/intro.txt
+lib/plugins/acl/lang/sv/intro.txt
+lib/plugins/acl/lang/tr/intro.txt
+lib/plugins/acl/lang/uk/intro.txt
+lib/plugins/acl/lang/vi/intro.txt
+lib/plugins/acl/lang/zh/intro.txt
+lib/plugins/acl/lang/zh-tw/intro.txt
+lib/scripts/spellcheck.js
+lib/styles/spellcheck.css
+
+# removed in 2007-06-26
+inc/parser/wiki.php
+lib/images/interwiki/bug.gif
+lib/plugins/base.php
+lib/plugins/plugin/inc
+lib/plugins/plugin/inc/tarlib.class.php
+lib/plugins/plugin/inc/zip.lib.php
+lib/scripts/domLib.js
+lib/scripts/domTT.js
+
+# removed in 2006-11-06
+inc/admin_acl.php
+inc/magpie
+inc/magpie/rss_cache.inc
+inc/magpie/rss_fetch.inc
+inc/magpie/rss_parse.inc
+inc/magpie/rss_utils.inc
+lib/exe/media.php
+lib/tpl/default/mediaedit.php
+lib/tpl/default/media.php
+lib/tpl/default/mediaref.php
+
+# removed in 2006-03-09
+data/pages/wiki/playground.txt
+inc/auth/ldap.php
+inc/auth/mysql.php
+inc/auth/pgsql.php
+inc/auth/plain.php
+inc/lang/ca/admin_acl.txt
+inc/lang/cs/admin_acl.txt
+inc/lang/da/admin_acl.txt
+inc/lang/de/admin_acl.txt
+inc/lang/en/admin_acl.txt
+inc/lang/et/admin_acl.txt
+inc/lang/eu/admin_acl.txt
+inc/lang/fr/admin_acl.txt
+inc/lang/it/admin_acl.txt
+inc/lang/ja/admin_acl.txt
+inc/lang/lt/admin_acl.txt
+inc/lang/lv/admin_acl.txt
+inc/lang/nl/admin_acl.txt
+inc/lang/no/admin_acl.txt
+inc/lang/pl/admin_acl.txt
+inc/lang/pt/admin_acl.txt
+inc/lang/vi/admin_acl.txt
+inc/lang/zh-tw/admin_acl.txt
+inc/parser/spamcheck.php
+lib/images/favicon.ico
+lib/images/thumbup.gif
+lib/images/toolbar/code.png
+lib/images/toolbar/empty.png
+lib/images/toolbar/extlink.png
+lib/images/toolbar/fonth1.png
+lib/images/toolbar/fonth2.png
+lib/images/toolbar/fonth3.png
+lib/images/toolbar/fonth4.png
+lib/images/toolbar/fonth5.png
+lib/images/toolbar/list.png
+lib/images/toolbar/list_ul.png
+lib/images/toolbar/rule.png
+lib/tpl/default/images/interwiki.png
diff --git a/platform/www/data/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png b/platform/www/data/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png
new file mode 100644
index 0000000..cea639e
--- /dev/null
+++ b/platform/www/data/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png
Binary files differ
diff --git a/platform/www/data/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.xcf b/platform/www/data/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.xcf
new file mode 100644
index 0000000..9902878
--- /dev/null
+++ b/platform/www/data/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.xcf
Binary files differ
diff --git a/platform/www/data/media/wiki/dokuwiki-128.png b/platform/www/data/media/wiki/dokuwiki-128.png
new file mode 100644
index 0000000..f3f1d66
--- /dev/null
+++ b/platform/www/data/media/wiki/dokuwiki-128.png
Binary files differ
diff --git a/platform/www/data/media/wiki/dokuwiki.svg b/platform/www/data/media/wiki/dokuwiki.svg
new file mode 100644
index 0000000..6e522c8
--- /dev/null
+++ b/platform/www/data/media/wiki/dokuwiki.svg
@@ -0,0 +1,586 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="128.17094"
+ height="128.03864"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.48.1 "
+ sodipodi:docname="dokuwiki-logo.svg"
+ version="1.1">
+ <title
+ id="title3181">DokuWiki Logo</title>
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient2624">
+ <stop
+ style="stop-color:#3a9030;stop-opacity:0.83673471;"
+ offset="0"
+ id="stop2626" />
+ <stop
+ style="stop-color:#3d9c32;stop-opacity:0.79591835;"
+ offset="1"
+ id="stop2628" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2612">
+ <stop
+ style="stop-color:#25901b;stop-opacity:0.83673471;"
+ offset="0"
+ id="stop2614" />
+ <stop
+ style="stop-color:#25901b;stop-opacity:0.37755102;"
+ offset="1"
+ id="stop2616" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2600">
+ <stop
+ style="stop-color:#e32525;stop-opacity:0.81632656;"
+ offset="0"
+ id="stop2602" />
+ <stop
+ style="stop-color:#e32525;stop-opacity:0.5714286;"
+ offset="1"
+ id="stop2604" />
+ </linearGradient>
+ <marker
+ inkscape:stockid="TriangleOutL"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="TriangleOutL"
+ style="overflow:visible">
+ <path
+ id="path2488"
+ d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
+ transform="scale(0.8,0.8)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Lstart"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Lstart"
+ style="overflow:visible">
+ <path
+ id="path2571"
+ style="font-size:12px;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="matrix(1.1,0,0,1.1,-5.5,0)"
+ inkscape:connector-curvature="0" />
+ </marker>
+ <linearGradient
+ id="linearGradient2408">
+ <stop
+ id="stop2410"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:0.17346939;" />
+ <stop
+ id="stop2412"
+ offset="1"
+ style="stop-color:#c7cec2;stop-opacity:0;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2389">
+ <stop
+ style="stop-color:#000000;stop-opacity:0.17346939;"
+ offset="0"
+ id="stop2391" />
+ <stop
+ style="stop-color:#c7cec2;stop-opacity:0;"
+ offset="1"
+ id="stop2393" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2370">
+ <stop
+ style="stop-color:#fbfaf9;stop-opacity:1;"
+ offset="0"
+ id="stop2372" />
+ <stop
+ style="stop-color:#e9dac7;stop-opacity:1;"
+ offset="1"
+ id="stop2374" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2364">
+ <stop
+ id="stop2366"
+ offset="0"
+ style="stop-color:#fbf6f0;stop-opacity:1;" />
+ <stop
+ id="stop2368"
+ offset="1"
+ style="stop-color:#e9dac7;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2348">
+ <stop
+ style="stop-color:#fbf6f0;stop-opacity:1;"
+ offset="0"
+ id="stop2350" />
+ <stop
+ style="stop-color:#e9dac7;stop-opacity:1;"
+ offset="1"
+ id="stop2352" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2332">
+ <stop
+ style="stop-color:#ede1ae;stop-opacity:1;"
+ offset="0"
+ id="stop2334" />
+ <stop
+ style="stop-color:#fefdfa;stop-opacity:1;"
+ offset="1"
+ id="stop2336" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2249">
+ <stop
+ style="stop-color:#00a423;stop-opacity:1;"
+ offset="0"
+ id="stop2251" />
+ <stop
+ style="stop-color:#00b427;stop-opacity:1;"
+ offset="1"
+ id="stop2253" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2229">
+ <stop
+ id="stop2231"
+ offset="0"
+ style="stop-color:#00b62b;stop-opacity:1;" />
+ <stop
+ id="stop2233"
+ offset="1"
+ style="stop-color:#a1d784;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2213">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop2215" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop2217" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2360">
+ <stop
+ style="stop-color:#d69c00;stop-opacity:1;"
+ offset="0"
+ id="stop2362" />
+ <stop
+ style="stop-color:#ffe658;stop-opacity:1;"
+ offset="1"
+ id="stop2364" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2352">
+ <stop
+ id="stop2354"
+ offset="0"
+ style="stop-color:#ce411e;stop-opacity:1;" />
+ <stop
+ id="stop2356"
+ offset="1"
+ style="stop-color:#ecad8d;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient2336">
+ <stop
+ style="stop-color:#8f2a15;stop-opacity:1;"
+ offset="0"
+ id="stop2338" />
+ <stop
+ style="stop-color:#c8381b;stop-opacity:1;"
+ offset="1"
+ id="stop2340" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2336"
+ id="linearGradient2342"
+ x1="219.21262"
+ y1="189.01556"
+ x2="286.22665"
+ y2="189.01556"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2352"
+ id="linearGradient2350"
+ x1="219.66267"
+ y1="192.73286"
+ x2="277.8761"
+ y2="192.73286"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2360"
+ id="radialGradient2366"
+ cx="224.41418"
+ cy="212.80016"
+ fx="224.41418"
+ fy="212.80016"
+ r="8.6813803"
+ gradientTransform="matrix(1,0,0,0.984179,0,3.366635)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2249"
+ id="linearGradient2227"
+ x1="192.03938"
+ y1="262.25757"
+ x2="263.67093"
+ y2="262.25757"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2229"
+ id="linearGradient2247"
+ x1="191.75092"
+ y1="258.91571"
+ x2="255.6561"
+ y2="258.91571"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2360"
+ id="radialGradient2317"
+ cx="257.41144"
+ cy="274.64203"
+ fx="257.41144"
+ fy="274.64203"
+ r="7.1440549"
+ gradientTransform="matrix(1,0,0,1.631384,0,-173.4045)"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2360"
+ id="linearGradient2325"
+ x1="184.07063"
+ y1="246.35907"
+ x2="201.40646"
+ y2="246.35907"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2332"
+ id="linearGradient2346"
+ x1="162.76369"
+ y1="184.99277"
+ x2="240.84924"
+ y2="289.50323"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2348"
+ id="linearGradient2354"
+ x1="140.15784"
+ y1="303.78967"
+ x2="136.14151"
+ y2="195.87151"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2370"
+ id="linearGradient2362"
+ x1="286.15598"
+ y1="262.28729"
+ x2="185.81258"
+ y2="172.32423"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2389"
+ id="linearGradient2395"
+ x1="213.96568"
+ y1="220.07191"
+ x2="244.79126"
+ y2="265.40363"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2408"
+ id="linearGradient2406"
+ x1="184.30582"
+ y1="241.52789"
+ x2="224.67441"
+ y2="307.52844"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2600"
+ id="linearGradient2606"
+ x1="202.41772"
+ y1="222.05145"
+ x2="206.06017"
+ y2="210.3558"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2612"
+ id="linearGradient2618"
+ x1="248.62152"
+ y1="234.52202"
+ x2="251.64362"
+ y2="213.12164"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2624"
+ id="linearGradient2630"
+ x1="275.71765"
+ y1="251.56442"
+ x2="255.68353"
+ y2="217.94008"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2352"
+ id="linearGradient2640"
+ gradientUnits="userSpaceOnUse"
+ x1="219.66267"
+ y1="192.73286"
+ x2="277.8761"
+ y2="192.73286" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2336"
+ id="linearGradient2643"
+ gradientUnits="userSpaceOnUse"
+ x1="219.21262"
+ y1="189.01556"
+ x2="286.22665"
+ y2="189.01556" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient2360"
+ id="radialGradient2647"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.984179,0,3.366635)"
+ cx="224.41418"
+ cy="212.80016"
+ fx="224.41418"
+ fy="212.80016"
+ r="8.6813803" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.03"
+ inkscape:cx="35.144424"
+ inkscape:cy="83.160427"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer3"
+ inkscape:window-width="1366"
+ inkscape:window-height="716"
+ inkscape:window-x="-8"
+ inkscape:window-y="-8"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ showgrid="false"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-maximized="1"
+ inkscape:showpageshadow="false"
+ showborder="true"
+ borderlayer="false" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title>DokuWiki Logo</dc:title>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Esther Brunner</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://www.gnu.org/licenses/gpl-2.0.html" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ id="layer3"
+ inkscape:label="paper"
+ style="display:inline"
+ transform="translate(-158.10602,-158.67323)">
+ <g
+ id="g1419"
+ transform="matrix(0.99993322,0,0,0.9959778,0.01483419,0.8957919)">
+ <g
+ id="g2376">
+ <path
+ transform="matrix(0.989976,-0.141236,0.201069,0.979577,0,0)"
+ style="fill:url(#linearGradient2354);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.7216621px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 120.21543,196.43769 70.90655,-0.79226 -2.40261,109.05308 -71.71761,0.37344 3.21367,-108.63426 z"
+ id="rect1422"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient2362);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 179.20033,182.08731 79.84173,-19.51687 26.61391,101.72428 -82.50312,21.58684 -23.95252,-103.79425 z"
+ id="rect1425"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ transform="matrix(0.995676,-0.09289891,0.08102261,0.996712,0,0)"
+ style="fill:url(#linearGradient2346);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00418305px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
+ d="m 159.01353,181.74387 85.58587,0.53396 0,110.47429 -84.53387,-2.5127 -1.052,-108.49555 z"
+ id="rect1419"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ id="text2382"
+ d="m 167.55116,214.00773 0,-20.1846 5.34962,0 0,2.37403 -2.48145,0 0,15.43654 2.48145,0 0,2.37403 -5.34962,0 m 7.34767,0 0,-20.1846 5.34961,0 0,2.37403 -2.48144,0 0,15.43654 2.48144,0 0,2.37403 -5.34961,0 m 7.36915,-20.1846 5.81153,0 c 1.31054,2e-5 2.30956,0.10028 2.99707,0.30078 0.92382,0.27216 1.71516,0.75555 2.37403,1.4502 0.65884,0.69468 1.16014,1.54689 1.50391,2.55664 0.34373,1.00262 0.51561,2.24155 0.51562,3.71681 -10e-6,1.29623 -0.16115,2.41342 -0.4834,3.35156 -0.39389,1.14584 -0.95607,2.07325 -1.68652,2.78223 -0.55145,0.53711 -1.29624,0.95606 -2.23438,1.25684 -0.70183,0.222 -1.63999,0.33301 -2.81446,0.33301 l -5.9834,0 0,-15.74807 m 3.17969,2.66407 0,10.43067 2.37402,0 c 0.88802,1e-5 1.52897,-0.0501 1.92286,-0.15039 0.51561,-0.1289 0.94172,-0.34732 1.27832,-0.65527 0.34374,-0.30794 0.62304,-0.81282 0.83789,-1.51465 0.21483,-0.70898 0.32226,-1.6722 0.32227,-2.88965 -1e-5,-1.21744 -0.10744,-2.15201 -0.32227,-2.80372 -0.21485,-0.65168 -0.51563,-1.16014 -0.90234,-1.52539 -0.38673,-0.36522 -0.87729,-0.61229 -1.47168,-0.74121 -0.44402,-0.10025 -1.31414,-0.15038 -2.61036,-0.15039 l -1.42871,0 m 14.96388,13.084 -3.75977,-15.74807 3.25489,0 2.37403,10.8174 2.87891,-10.8174 3.78125,0 2.76074,11.00002 2.417,-11.00002 3.20118,0 -3.82423,15.74807 -3.37305,0 -3.13672,-11.77345 -3.12598,11.77345 -3.44825,0 m 22.76272,-15.74807 0,20.1846 -5.34961,0 0,-2.37403 2.48145,0 0,-15.45803 -2.48145,0 0,-2.35254 5.34961,0 m 7.34767,0 0,20.1846 -5.34962,0 0,-2.37403 2.48145,0 0,-15.45803 -2.48145,0 0,-2.35254 5.34962,0"
+ style="font-size:12.0000124px;font-style:normal;font-weight:normal;line-height:125%;fill:#6184a3;fill-opacity:1;stroke:none;display:inline;font-family:Bitstream Vera Sans"
+ transform="matrix(0.995433,-0.09546066,0.09546066,0.995433,0,0)"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g2632"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient2606);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;marker-end:none"
+ d="m 174.75585,201.60224 c -6.04576,2.46667 -10.16789,4.4194 -12.88454,6.35064 -2.71665,1.93124 -3.19257,4.60007 -3.24631,6.26587 -0.0269,0.8329 0.0809,1.77774 0.63189,2.44014 0.55103,0.6624 1.80769,1.87421 2.75794,2.38558 1.90049,1.02274 7.5417,2.42901 10.51899,3.07308 11.90917,2.57627 26.80568,1.68117 26.80568,1.68117 1.69307,1.2452 2.83283,2.82434 3.269,4.26902 4.5766,-1.88674 11.81084,-6.58439 13.15657,-8.57706 -5.45142,-4.19955 -10.79692,-6.33346 -16.51317,-8.30847 -1.59867,-0.71918 -2.87956,-1.22649 -0.71773,2.55635 0.98506,2.47275 0.85786,5.05143 0.57176,7.41825 0,0 -16.52749,0.40678 -28.23838,-2.1266 -2.92772,-0.63334 -5.46627,-0.95523 -7.21875,-1.89832 -0.87624,-0.47154 -1.48296,-0.8208 -1.91578,-1.3411 -0.43282,-0.5203 -0.2196,-1.29055 -0.20128,-1.85858 0.0366,-1.13607 0.25336,-1.67063 2.86177,-3.52492 2.60841,-1.85429 5.65407,-3.36195 11.65936,-5.81211 -0.0877,-1.29125 -0.29025,-2.5059 -1.29702,-2.99294 z"
+ id="path2414"
+ sodipodi:nodetypes="csssssccccccssssscc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient2618);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 269.62539,220.7482 c -1.43576,-0.13963 -2.58044,0.30288 -2.56084,1.50218 0.94391,0.85652 1.34942,2.43518 1.48562,3.14008 0.1362,0.7049 0.0359,1.21914 -0.48562,1.89004 -1.043,1.3418 -3.12498,1.56875 -6.5006,2.72063 -6.75124,2.30377 -16.89306,2.52561 -27.90689,3.84639 -22.02767,2.64157 -39.03164,3.76107 -39.03164,3.76107 1.98346,-4.64758 6.32828,-4.41197 6.34903,-8.20969 0.27376,-0.89755 -3.14597,-1.31638 -5.09943,-0.10731 -4.26694,3.70137 -7.59152,6.75353 -10.69418,10.51311 l 1.88795,3.08438 c 0,0 26.13006,-2.88973 48.19776,-5.5361 11.03385,-1.32318 20.95601,-1.99856 27.80968,-4.33728 3.42683,-1.16936 5.95975,-1.49022 7.6409,-3.51958 0.63172,-0.76256 1.35238,-3.04699 1.06804,-4.73369 -0.21951,-1.30213 -1.14979,-3.09774 -2.15978,-4.01423 z"
+ id="path2608"
+ sodipodi:nodetypes="ccsssscccccssssc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient2630);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 254.36185,220.33948 c -6.84997,3.24198 -7.15311,8.60912 -5.95953,12.79884 1.19358,4.18972 5.26293,8.75677 9.32121,12.40608 8.11656,7.29861 12.06046,9.33163 12.06046,9.33163 -3.71515,-0.10342 -7.89887,-1.41174 -8.13315,0.49304 -0.9483,2.97582 11.49137,3.47486 17.43787,2.70205 -1.39456,-7.57836 -3.79323,-13.21546 -7.73151,-14.90312 -1.68464,-0.14804 0.31242,4.72441 0.76985,9.39604 0,0 -3.62454,-1.73122 -11.60519,-8.90762 -3.99032,-3.5882 -7.37386,-7.3421 -8.47319,-11.20099 -1.09933,-3.85889 0.0776,-6.1205 4.95082,-9.53176 0.92816,-0.99528 -1.28985,-2.45913 -2.63764,-2.58419 z"
+ id="path2620"
+ sodipodi:nodetypes="csscccccsscc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ sodipodi:nodetypes="cccccc"
+ id="rect2386"
+ d="m 213.96569,234.57806 2.18756,-14.42897 15.21982,6.08793 21.49387,29.94828 -20.40591,9.21832 -18.49534,-30.82556 z"
+ style="fill:url(#linearGradient2395);fill-opacity:1;stroke:none;display:inline"
+ inkscape:connector-curvature="0" />
+ <g
+ id="g2649"
+ style="display:inline">
+ <path
+ style="fill:url(#radialGradient2647);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ d="m 232.55816,219.5295 -15.92827,0.32199 3.08809,-15.15716 12.84018,14.83517 z"
+ id="path1443"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#812310;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 221.60041,219.29315 -4.41205,0.0782 0.85429,-3.98263 3.55776,3.90445 z"
+ id="path1452"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient2643);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1"
+ d="m 269.44172,159.27421 0.098,8.91471 8.0581,8.72344 7.75906,0.7992 -52.80669,41.84092 -6.66532,-3.30696 -5.08243,-5.618 -1.08987,-5.91194 49.72911,-45.44137 z"
+ id="rect1437"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient2640);fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 268.94766,168.32844 8.3426,8.82719 -51.1007,38.68262 -4.9197,-5.4436 47.6778,-42.06621 z"
+ id="rect1446"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ffe965;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 285.33776,177.73216 -8.16219,-0.86619 -7.7518,-8.67862 0.0132,-9.14293 8.36213,0.75209 7.18862,9.57682 0.35007,8.35883 z"
+ id="path1440"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#cb391c;fill-opacity:1;fill-rule:evenodd;stroke:none"
+ d="m 280.72049,168.46367 0.1644,4.05654 -3.81335,-0.71676 -2.87504,-3.18901 -0.28089,-3.53393 3.85447,-0.16637 2.95041,3.54953 z"
+ id="path1449"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g2657"
+ style="display:inline">
+ <path
+ style="fill:url(#linearGradient2406);fill-opacity:1;stroke:none"
+ d="m 183.88617,256.82796 0.99991,-16.30721 17.2878,8.44012 26.05488,38.00946 -29.28095,-1.13363 -15.06164,-29.00874 z"
+ id="rect2397"
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient2325);fill-opacity:1;stroke:#000000;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 200.90647,238.44836 -8.04601,15.77386 -7.05577,-13.57337 15.10178,-2.20049 z"
+ id="rect2207"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient2227);fill-opacity:1;stroke:#000000;stroke-linejoin:round;stroke-opacity:1"
+ d="m 201.05389,238.55401 62.11704,24.91912 -7.88689,3.21429 -4.35152,9.30976 1.1716,9.96396 -59.31453,-31.72759 -0.49402,-7.36382 3.09592,-5.82826 5.6624,-2.48746 z"
+ id="rect1328"
+ sodipodi:nodetypes="ccccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#radialGradient2317);fill-opacity:1;stroke:#000000;stroke-linejoin:round;stroke-opacity:1;display:inline"
+ d="m 255.27801,266.53504 7.9241,-3.04772 0.85337,10.24037 -3.9011,8.28983 -8.04601,3.77919 -1.341,-9.63083 4.51064,-9.63084 z"
+ id="rect2204"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:url(#linearGradient2247);fill-opacity:1;stroke:none;display:inline"
+ d="m 195.7549,241.421 59.13059,24.7962 -4.5917,9.76614 -57.48995,-29.00967 2.95106,-5.55267 z"
+ id="rect2210"
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#00b527;fill-opacity:1;stroke:none"
+ d="m 255.02263,275.21029 2.08411,-4.1069 2.96459,-1.06995 0.69433,3.37197 -1.76759,3.85723 -3.15516,1.38315 -0.82028,-3.4355 z"
+ id="rect2308"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#258209;fill-opacity:1;stroke:none;display:inline"
+ d="m 186.56849,241.00362 3.54963,-0.47312 -2.02297,3.53926 -1.52666,-3.06614 z"
+ id="rect2327"
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/platform/www/data/media_attic/_dummy b/platform/www/data/media_attic/_dummy
new file mode 100644
index 0000000..e492265
--- /dev/null
+++ b/platform/www/data/media_attic/_dummy
@@ -0,0 +1 @@
+You can safely delete this file. \ No newline at end of file
diff --git a/platform/www/data/media_meta/_dummy b/platform/www/data/media_meta/_dummy
new file mode 100644
index 0000000..e492265
--- /dev/null
+++ b/platform/www/data/media_meta/_dummy
@@ -0,0 +1 @@
+You can safely delete this file. \ No newline at end of file
diff --git a/platform/www/data/pages/index.txt b/platform/www/data/pages/index.txt
new file mode 100644
index 0000000..f71825e
--- /dev/null
+++ b/platform/www/data/pages/index.txt
@@ -0,0 +1,3 @@
+# Acervus
+
+Welcome to Acervus Project!
diff --git a/platform/www/data/pages/playground/playground.txt b/platform/www/data/pages/playground/playground.txt
new file mode 100644
index 0000000..a2274bd
--- /dev/null
+++ b/platform/www/data/pages/playground/playground.txt
@@ -0,0 +1 @@
+====== PlayGround ======
diff --git a/platform/www/data/pages/start.txt b/platform/www/data/pages/start.txt
new file mode 100644
index 0000000..c66ad6d
--- /dev/null
+++ b/platform/www/data/pages/start.txt
@@ -0,0 +1 @@
+Algo! \ No newline at end of file
diff --git a/platform/www/data/pages/wiki/dokuwiki.txt b/platform/www/data/pages/wiki/dokuwiki.txt
new file mode 100644
index 0000000..1e5a198
--- /dev/null
+++ b/platform/www/data/pages/wiki/dokuwiki.txt
@@ -0,0 +1,62 @@
+====== DokuWiki ======
+
+[[doku>wiki:dokuwiki|{{wiki:dokuwiki-128.png }}]] DokuWiki is a simple to use and highly versatile Open Source [[wp>wiki]] software that doesn't require a database. It is loved by users for its clean and readable [[wiki:syntax]]. The ease of maintenance, backup and integration makes it an administrator's favorite. Built in [[doku>acl|access controls]] and [[doku>auth|authentication connectors]] make DokuWiki especially useful in the enterprise context and the large number of [[doku>plugins]] contributed by its vibrant community allow for a broad range of use cases beyond a traditional wiki.
+
+Read the [[doku>manual|DokuWiki Manual]] to unleash the full power of DokuWiki.
+
+===== Download =====
+
+DokuWiki is available at https://download.dokuwiki.org/
+
+
+===== Read More =====
+
+All documentation and additional information besides the [[syntax|syntax description]] is maintained in the DokuWiki at [[doku>|www.dokuwiki.org]].
+
+**About DokuWiki**
+
+ * [[doku>features|A feature list]] :!:
+ * [[doku>users|Happy Users]]
+ * [[doku>press|Who wrote about it]]
+ * [[doku>blogroll|What Bloggers think]]
+ * [[https://www.wikimatrix.org/show/DokuWiki|Compare it with other wiki software]]
+
+**Installing DokuWiki**
+
+ * [[doku>requirements|System Requirements]]
+ * [[https://download.dokuwiki.org/|Download DokuWiki]] :!:
+ * [[doku>changes|Change Log]]
+ * [[doku>Install|How to install or upgrade]] :!:
+ * [[doku>config|Configuration]]
+
+**Using DokuWiki**
+
+ * [[doku>syntax|Wiki Syntax]]
+ * [[doku>manual|The manual]] :!:
+ * [[doku>FAQ|Frequently Asked Questions (FAQ)]]
+ * [[doku>glossary|Glossary]]
+
+**Customizing DokuWiki**
+
+ * [[doku>tips|Tips and Tricks]]
+ * [[doku>Template|How to create and use templates]]
+ * [[doku>plugins|Installing plugins]]
+ * [[doku>development|Development Resources]]
+
+**DokuWiki Feedback and Community**
+
+ * [[doku>newsletter|Subscribe to the newsletter]] :!:
+ * [[doku>mailinglist|Join the mailing list]]
+ * [[https://forum.dokuwiki.org|Check out the user forum]]
+ * [[doku>irc|Talk to other users in the IRC channel]]
+ * [[https://github.com/splitbrain/dokuwiki/issues|Submit bugs and feature wishes]]
+ * [[doku>thanks|Some humble thanks]]
+
+
+===== Copyright =====
+
+2004-2020 (c) Andreas Gohr <andi@splitbrain.org>((Please do not contact me for help and support -- use the [[doku>mailinglist]] or [[https://forum.dokuwiki.org|forum]] instead)) and the DokuWiki Community
+
+The DokuWiki engine is licensed under [[https://www.gnu.org/licenses/gpl.html|GNU General Public License]] Version 2. If you use DokuWiki in your company, consider [[doku>donate|donating]] a few bucks ;-).
+
+Not sure what this means? See the [[doku>faq:license|FAQ on the Licenses]].
diff --git a/platform/www/data/pages/wiki/syntax.txt b/platform/www/data/pages/wiki/syntax.txt
new file mode 100644
index 0000000..bf36c08
--- /dev/null
+++ b/platform/www/data/pages/wiki/syntax.txt
@@ -0,0 +1,525 @@
+====== Formatting Syntax ======
+
+[[doku>DokuWiki]] supports some simple markup language, which tries to make the datafiles to be as readable as possible. This page contains all possible syntax you may use when editing the pages. Simply have a look at the source of this page by pressing "Edit this page". If you want to try something, just use the [[playground:playground|playground]] page. The simpler markup is easily accessible via [[doku>toolbar|quickbuttons]], too.
+
+===== Basic Text Formatting =====
+
+DokuWiki supports **bold**, //italic//, __underlined__ and ''monospaced'' texts. Of course you can **__//''combine''//__** all these.
+
+ DokuWiki supports **bold**, //italic//, __underlined__ and ''monospaced'' texts.
+ Of course you can **__//''combine''//__** all these.
+
+You can use <sub>subscript</sub> and <sup>superscript</sup>, too.
+
+ You can use <sub>subscript</sub> and <sup>superscript</sup>, too.
+
+You can mark something as <del>deleted</del> as well.
+
+ You can mark something as <del>deleted</del> as well.
+
+**Paragraphs** are created from blank lines. If you want to **force a newline** without a paragraph, you can use two backslashes followed by a whitespace or the end of line.
+
+This is some text with some linebreaks\\ Note that the
+two backslashes are only recognized at the end of a line\\
+or followed by\\ a whitespace \\this happens without it.
+
+ This is some text with some linebreaks\\ Note that the
+ two backslashes are only recognized at the end of a line\\
+ or followed by\\ a whitespace \\this happens without it.
+
+You should use forced newlines only if really needed.
+
+===== Links =====
+
+DokuWiki supports multiple ways of creating links.
+
+==== External ====
+
+External links are recognized automagically: http://www.google.com or simply www.google.com - You can set the link text as well: [[http://www.google.com|This Link points to google]]. Email addresses like this one: <andi@splitbrain.org> are recognized, too.
+
+ DokuWiki supports multiple ways of creating links. External links are recognized
+ automagically: http://www.google.com or simply www.google.com - You can set
+ link text as well: [[http://www.google.com|This Link points to google]]. Email
+ addresses like this one: <andi@splitbrain.org> are recognized, too.
+
+==== Internal ====
+
+Internal links are created by using square brackets. You can either just give a [[pagename]] or use an additional [[pagename|link text]].
+
+ Internal links are created by using square brackets. You can either just give
+ a [[pagename]] or use an additional [[pagename|link text]].
+
+[[doku>pagename|Wiki pagenames]] are converted to lowercase automatically, special characters are not allowed.
+
+You can use [[some:namespaces]] by using a colon in the pagename.
+
+ You can use [[some:namespaces]] by using a colon in the pagename.
+
+For details about namespaces see [[doku>namespaces]].
+
+Linking to a specific section is possible, too. Just add the section name behind a hash character as known from HTML. This links to [[syntax#internal|this Section]].
+
+ This links to [[syntax#internal|this Section]].
+
+Notes:
+
+ * Links to [[syntax|existing pages]] are shown in a different style from [[nonexisting]] ones.
+ * DokuWiki does not use [[wp>CamelCase]] to automatically create links by default, but this behavior can be enabled in the [[doku>config]] file. Hint: If DokuWiki is a link, then it's enabled.
+ * When a section's heading is changed, its bookmark changes, too. So don't rely on section linking too much.
+
+==== Interwiki ====
+
+DokuWiki supports [[doku>Interwiki]] links. These are quick links to other Wikis. For example this is a link to Wikipedia's page about Wikis: [[wp>Wiki]].
+
+ DokuWiki supports [[doku>Interwiki]] links. These are quick links to other Wikis.
+ For example this is a link to Wikipedia's page about Wikis: [[wp>Wiki]].
+
+==== Windows Shares ====
+
+Windows shares like [[\\server\share|this]] are recognized, too. Please note that these only make sense in a homogeneous user group like a corporate [[wp>Intranet]].
+
+ Windows Shares like [[\\server\share|this]] are recognized, too.
+
+Notes:
+
+ * For security reasons direct browsing of windows shares only works in Microsoft Internet Explorer per default (and only in the "local zone").
+ * For Mozilla and Firefox it can be enabled through different workaround mentioned in the [[http://kb.mozillazine.org/Links_to_local_pages_do_not_work|Mozilla Knowledge Base]]. However, there will still be a JavaScript warning about trying to open a Windows Share. To remove this warning (for all users), put the following line in ''conf/lang/en/lang.php'' (more details at [[doku>localization#changing_some_localized_texts_and_strings_in_your_installation|localization]]): <code - conf/lang/en/lang.php>
+<?php
+/**
+ * Customization of the english language file
+ * Copy only the strings that needs to be modified
+ */
+$lang['js']['nosmblinks'] = '';
+</code>
+
+==== Image Links ====
+
+You can also use an image to link to another internal or external page by combining the syntax for links and [[#images_and_other_files|images]] (see below) like this:
+
+ [[http://php.net|{{wiki:dokuwiki-128.png}}]]
+
+[[http://php.net|{{wiki:dokuwiki-128.png}}]]
+
+Please note: The image formatting is the only formatting syntax accepted in link names.
+
+The whole [[#images_and_other_files|image]] and [[#links|link]] syntax is supported (including image resizing, internal and external images and URLs and interwiki links).
+
+===== Footnotes =====
+
+You can add footnotes ((This is a footnote)) by using double parentheses.
+
+ You can add footnotes ((This is a footnote)) by using double parentheses.
+
+===== Sectioning =====
+
+You can use up to five different levels of headlines to structure your content. If you have more than three headlines, a table of contents is generated automatically -- this can be disabled by including the string ''<nowiki>~~NOTOC~~</nowiki>'' in the document.
+
+==== Headline Level 3 ====
+=== Headline Level 4 ===
+== Headline Level 5 ==
+
+ ==== Headline Level 3 ====
+ === Headline Level 4 ===
+ == Headline Level 5 ==
+
+By using four or more dashes, you can make a horizontal line:
+
+----
+
+===== Media Files =====
+
+You can include external and internal [[doku>images|images, videos and audio files]] with curly brackets. Optionally you can specify the size of them.
+
+Real size: {{wiki:dokuwiki-128.png}}
+
+Resize to given width: {{wiki:dokuwiki-128.png?50}}
+
+Resize to given width and height((when the aspect ratio of the given width and height doesn't match that of the image, it will be cropped to the new ratio before resizing)): {{wiki:dokuwiki-128.png?200x50}}
+
+Resized external image:           {{https://secure.php.net/images/php.gif?200x50}}
+
+ Real size: {{wiki:dokuwiki-128.png}}
+ Resize to given width: {{wiki:dokuwiki-128.png?50}}
+ Resize to given width and height: {{wiki:dokuwiki-128.png?200x50}}
+ Resized external image:           {{https://secure.php.net/images/php.gif?200x50}}
+
+
+By using left or right whitespaces you can choose the alignment.
+
+{{ wiki:dokuwiki-128.png}}
+
+{{wiki:dokuwiki-128.png }}
+
+{{ wiki:dokuwiki-128.png }}
+
+ {{ wiki:dokuwiki-128.png}}
+ {{wiki:dokuwiki-128.png }}
+ {{ wiki:dokuwiki-128.png }}
+
+Of course, you can add a title (displayed as a tooltip by most browsers), too.
+
+{{ wiki:dokuwiki-128.png |This is the caption}}
+
+ {{ wiki:dokuwiki-128.png |This is the caption}}
+
+For linking an image to another page see [[#Image Links]] above.
+
+==== Supported Media Formats ====
+
+DokuWiki can embed the following media formats directly.
+
+| Image | ''gif'', ''jpg'', ''png'' |
+| Video | ''webm'', ''ogv'', ''mp4'' |
+| Audio | ''ogg'', ''mp3'', ''wav'' |
+| Flash | ''swf'' |
+
+If you specify a filename that is not a supported media format, then it will be displayed as a link instead.
+
+By adding ''?linkonly'' you provide a link to the media without displaying it inline
+
+ {{wiki:dokuwiki-128.png?linkonly}}
+
+{{wiki:dokuwiki-128.png?linkonly}} This is just a link to the image.
+
+==== Fallback Formats ====
+
+Unfortunately not all browsers understand all video and audio formats. To mitigate the problem, you can upload your file in different formats for maximum browser compatibility.
+
+For example consider this embedded mp4 video:
+
+ {{video.mp4|A funny video}}
+
+When you upload a ''video.webm'' and ''video.ogv'' next to the referenced ''video.mp4'', DokuWiki will automatically add them as alternatives so that one of the three files is understood by your browser.
+
+Additionally DokuWiki supports a "poster" image which will be shown before the video has started. That image needs to have the same filename as the video and be either a jpg or png file. In the example above a ''video.jpg'' file would work.
+
+===== Lists =====
+
+Dokuwiki supports ordered and unordered lists. To create a list item, indent your text by two spaces and use a ''*'' for unordered lists or a ''-'' for ordered ones.
+
+ * This is a list
+ * The second item
+ * You may have different levels
+ * Another item
+
+ - The same list but ordered
+ - Another item
+ - Just use indention for deeper levels
+ - That's it
+
+<code>
+ * This is a list
+ * The second item
+ * You may have different levels
+ * Another item
+
+ - The same list but ordered
+ - Another item
+ - Just use indention for deeper levels
+ - That's it
+</code>
+
+Also take a look at the [[doku>faq:lists|FAQ on list items]].
+
+===== Text Conversions =====
+
+DokuWiki can convert certain pre-defined characters or strings into images or other text or HTML.
+
+The text to image conversion is mainly done for smileys. And the text to HTML conversion is used for typography replacements, but can be configured to use other HTML as well.
+
+==== Text to Image Conversions ====
+
+DokuWiki converts commonly used [[wp>emoticon]]s to their graphical equivalents. Those [[doku>Smileys]] and other images can be configured and extended. Here is an overview of Smileys included in DokuWiki:
+
+ * 8-) %% 8-) %%
+ * 8-O %% 8-O %%
+ * :-( %% :-( %%
+ * :-) %% :-) %%
+ * =) %% =) %%
+ * :-/ %% :-/ %%
+ * :-\ %% :-\ %%
+ * :-? %% :-? %%
+ * :-D %% :-D %%
+ * :-P %% :-P %%
+ * :-O %% :-O %%
+ * :-X %% :-X %%
+ * :-| %% :-| %%
+ * ;-) %% ;-) %%
+ * ^_^ %% ^_^ %%
+ * :?: %% :?: %%
+ * :!: %% :!: %%
+ * LOL %% LOL %%
+ * FIXME %% FIXME %%
+ * DELETEME %% DELETEME %%
+
+==== Text to HTML Conversions ====
+
+Typography: [[DokuWiki]] can convert simple text characters to their typographically correct entities. Here is an example of recognized characters.
+
+-> <- <-> => <= <=> >> << -- --- 640x480 (c) (tm) (r)
+"He thought 'It's a man's world'..."
+
+<code>
+-> <- <-> => <= <=> >> << -- --- 640x480 (c) (tm) (r)
+"He thought 'It's a man's world'..."
+</code>
+
+The same can be done to produce any kind of HTML, it just needs to be added to the [[doku>entities|pattern file]].
+
+There are three exceptions which do not come from that pattern file: multiplication entity (640x480), 'single' and "double quotes". They can be turned off through a [[doku>config:typography|config option]].
+
+===== Quoting =====
+
+Some times you want to mark some text to show it's a reply or comment. You can use the following syntax:
+
+<code>
+I think we should do it
+
+> No we shouldn't
+
+>> Well, I say we should
+
+> Really?
+
+>> Yes!
+
+>>> Then lets do it!
+</code>
+
+I think we should do it
+
+> No we shouldn't
+
+>> Well, I say we should
+
+> Really?
+
+>> Yes!
+
+>>> Then lets do it!
+
+===== Tables =====
+
+DokuWiki supports a simple syntax to create tables.
+
+^ Heading 1 ^ Heading 2 ^ Heading 3 ^
+| Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
+| Row 2 Col 1 | some colspan (note the double pipe) ||
+| Row 3 Col 1 | Row 3 Col 2 | Row 3 Col 3 |
+
+Table rows have to start and end with a ''|'' for normal rows or a ''^'' for headers.
+
+ ^ Heading 1 ^ Heading 2 ^ Heading 3 ^
+ | Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
+ | Row 2 Col 1 | some colspan (note the double pipe) ||
+ | Row 3 Col 1 | Row 3 Col 2 | Row 3 Col 3 |
+
+To connect cells horizontally, just make the next cell completely empty as shown above. Be sure to have always the same amount of cell separators!
+
+Vertical tableheaders are possible, too.
+
+| ^ Heading 1 ^ Heading 2 ^
+^ Heading 3 | Row 1 Col 2 | Row 1 Col 3 |
+^ Heading 4 | no colspan this time | |
+^ Heading 5 | Row 2 Col 2 | Row 2 Col 3 |
+
+As you can see, it's the cell separator before a cell which decides about the formatting:
+
+ | ^ Heading 1 ^ Heading 2 ^
+ ^ Heading 3 | Row 1 Col 2 | Row 1 Col 3 |
+ ^ Heading 4 | no colspan this time | |
+ ^ Heading 5 | Row 2 Col 2 | Row 2 Col 3 |
+
+You can have rowspans (vertically connected cells) by adding ''%%:::%%'' into the cells below the one to which they should connect.
+
+^ Heading 1 ^ Heading 2 ^ Heading 3 ^
+| Row 1 Col 1 | this cell spans vertically | Row 1 Col 3 |
+| Row 2 Col 1 | ::: | Row 2 Col 3 |
+| Row 3 Col 1 | ::: | Row 2 Col 3 |
+
+Apart from the rowspan syntax those cells should not contain anything else.
+
+ ^ Heading 1 ^ Heading 2 ^ Heading 3 ^
+ | Row 1 Col 1 | this cell spans vertically | Row 1 Col 3 |
+ | Row 2 Col 1 | ::: | Row 2 Col 3 |
+ | Row 3 Col 1 | ::: | Row 2 Col 3 |
+
+You can align the table contents, too. Just add at least two whitespaces at the opposite end of your text: Add two spaces on the left to align right, two spaces on the right to align left and two spaces at least at both ends for centered text.
+
+^ Table with alignment ^^^
+| right| center |left |
+|left | right| center |
+| xxxxxxxxxxxx | xxxxxxxxxxxx | xxxxxxxxxxxx |
+
+This is how it looks in the source:
+
+ ^ Table with alignment ^^^
+ | right| center |left |
+ |left | right| center |
+ | xxxxxxxxxxxx | xxxxxxxxxxxx | xxxxxxxxxxxx |
+
+Note: Vertical alignment is not supported.
+
+===== No Formatting =====
+
+If you need to display text exactly like it is typed (without any formatting), enclose the area either with ''%%<nowiki>%%'' tags or even simpler, with double percent signs ''<nowiki>%%</nowiki>''.
+
+<nowiki>
+This is some text which contains addresses like this: http://www.splitbrain.org and **formatting**, but nothing is done with it.
+</nowiki>
+The same is true for %%//__this__ text// with a smiley ;-)%%.
+
+ <nowiki>
+ This is some text which contains addresses like this: http://www.splitbrain.org and **formatting**, but nothing is done with it.
+ </nowiki>
+ The same is true for %%//__this__ text// with a smiley ;-)%%.
+
+===== Code Blocks =====
+
+You can include code blocks into your documents by either indenting them by at least two spaces (like used for the previous examples) or by using the tags ''%%<code>%%'' or ''%%<file>%%''.
+
+ This is text is indented by two spaces.
+
+<code>
+This is preformatted code all spaces are preserved: like <-this
+</code>
+
+<file>
+This is pretty much the same, but you could use it to show that you quoted a file.
+</file>
+
+Those blocks were created by this source:
+
+ This is text is indented by two spaces.
+
+ <code>
+ This is preformatted code all spaces are preserved: like <-this
+ </code>
+
+ <file>
+ This is pretty much the same, but you could use it to show that you quoted a file.
+ </file>
+
+==== Syntax Highlighting ====
+
+[[wiki:DokuWiki]] can highlight sourcecode, which makes it easier to read. It uses the [[http://qbnz.com/highlighter/|GeSHi]] Generic Syntax Highlighter -- so any language supported by GeSHi is supported. The syntax uses the same code and file blocks described in the previous section, but this time the name of the language syntax to be highlighted is included inside the tag, e.g. ''<nowiki><code java></nowiki>'' or ''<nowiki><file java></nowiki>''.
+
+<code java>
+/**
+ * The HelloWorldApp class implements an application that
+ * simply displays "Hello World!" to the standard output.
+ */
+class HelloWorldApp {
+ public static void main(String[] args) {
+ System.out.println("Hello World!"); //Display the string.
+ }
+}
+</code>
+
+The following language strings are currently recognized: //4cs 6502acme 6502kickass 6502tasm 68000devpac abap actionscript3 actionscript ada aimms algol68 apache applescript apt_sources arm asm asp asymptote autoconf autohotkey autoit avisynth awk bascomavr bash basic4gl batch bf biblatex bibtex blitzbasic bnf boo caddcl cadlisp ceylon cfdg cfm chaiscript chapel cil c_loadrunner clojure c_mac cmake cobol coffeescript c cpp cpp-qt cpp-winapi csharp css cuesheet c_winapi dart dcl dcpu16 dcs delphi diff div dos dot d ecmascript eiffel email epc e erlang euphoria ezt f1 falcon fo fortran freebasic freeswitch fsharp gambas gdb genero genie gettext glsl gml gnuplot go groovy gwbasic haskell haxe hicest hq9plus html html4strict html5 icon idl ini inno intercal io ispfpanel java5 java javascript jcl j jquery julia kixtart klonec klonecpp kotlin latex lb ldif lisp llvm locobasic logtalk lolcode lotusformulas lotusscript lscript lsl2 lua m68k magiksf make mapbasic mathematica matlab mercury metapost mirc mk-61 mmix modula2 modula3 mpasm mxml mysql nagios netrexx newlisp nginx nimrod nsis oberon2 objc objeck ocaml-brief ocaml octave oobas oorexx oracle11 oracle8 oxygene oz parasail parigp pascal pcre perl6 perl per pf phix php-brief php pic16 pike pixelbender pli plsql postgresql postscript povray powerbuilder powershell proftpd progress prolog properties providex purebasic pycon pys60 python qbasic qml q racket rails rbs rebol reg rexx robots roff rpmspec rsplus ruby rust sas sass scala scheme scilab scl sdlbasic smalltalk smarty spark sparql sql sshconfig standardml stonescript swift systemverilog tclegg tcl teraterm texgraph text thinbasic tsql twig typoscript unicon upc urbi uscript vala vbnet vb vbscript vedit verilog vhdl vim visualfoxpro visualprolog whitespace whois winbatch wolfram xbasic xml xojo xorg_conf xpp yaml z80 zxbasic//
+
+There are additional [[doku>syntax_highlighting|advanced options]] available for syntax highlighting, such as highlighting lines or adding line numbers.
+
+==== Downloadable Code Blocks ====
+
+When you use the ''%%<code>%%'' or ''%%<file>%%'' syntax as above, you might want to make the shown code available for download as well. You can do this by specifying a file name after language code like this:
+
+<code>
+<file php myexample.php>
+<?php echo "hello world!"; ?>
+</file>
+</code>
+
+<file php myexample.php>
+<?php echo "hello world!"; ?>
+</file>
+
+If you don't want any highlighting but want a downloadable file, specify a dash (''-'') as the language code: ''%%<code - myfile.foo>%%''.
+
+
+===== Embedding HTML and PHP =====
+
+You can embed raw HTML or PHP code into your documents by using the ''%%<html>%%'' or ''%%<php>%%'' tags. (Use uppercase tags if you need to enclose block level elements.)
+
+HTML example:
+
+<code>
+<html>
+This is some <span style="color:red;font-size:150%;">inline HTML</span>
+</html>
+<HTML>
+<p style="border:2px dashed red;">And this is some block HTML</p>
+</HTML>
+</code>
+
+<html>
+This is some <span style="color:red;font-size:150%;">inline HTML</span>
+</html>
+<HTML>
+<p style="border:2px dashed red;">And this is some block HTML</p>
+</HTML>
+
+PHP example:
+
+<code>
+<php>
+echo 'The PHP version: ';
+echo phpversion();
+echo ' (generated inline HTML)';
+</php>
+<PHP>
+echo '<table class="inline"><tr><td>The same, but inside a block level element:</td>';
+echo '<td>'.phpversion().'</td>';
+echo '</tr></table>';
+</PHP>
+</code>
+
+<php>
+echo 'The PHP version: ';
+echo phpversion();
+echo ' (inline HTML)';
+</php>
+<PHP>
+echo '<table class="inline"><tr><td>The same, but inside a block level element:</td>';
+echo '<td>'.phpversion().'</td>';
+echo '</tr></table>';
+</PHP>
+
+**Please Note**: HTML and PHP embedding is disabled by default in the configuration. If disabled, the code is displayed instead of executed.
+
+===== RSS/ATOM Feed Aggregation =====
+[[DokuWiki]] can integrate data from external XML feeds. For parsing the XML feeds, [[http://simplepie.org/|SimplePie]] is used. All formats understood by SimplePie can be used in DokuWiki as well. You can influence the rendering by multiple additional space separated parameters:
+
+^ Parameter ^ Description ^
+| any number | will be used as maximum number items to show, defaults to 8 |
+| reverse | display the last items in the feed first |
+| author | show item authors names |
+| date | show item dates |
+| description| show the item description. If [[doku>config:htmlok|HTML]] is disabled all tags will be stripped |
+| nosort | do not sort the items in the feed |
+| //n//[dhm] | refresh period, where d=days, h=hours, m=minutes. (e.g. 12h = 12 hours). |
+
+The refresh period defaults to 4 hours. Any value below 10 minutes will be treated as 10 minutes. [[wiki:DokuWiki]] will generally try to supply a cached version of a page, obviously this is inappropriate when the page contains dynamic external content. The parameter tells [[wiki:DokuWiki]] to re-render the page if it is more than //refresh period// since the page was last rendered.
+
+By default the feed will be sorted by date, newest items first. You can sort it by oldest first using the ''reverse'' parameter, or display the feed as is with ''nosort''.
+
+**Example:**
+
+ {{rss>http://slashdot.org/index.rss 5 author date 1h }}
+
+{{rss>http://slashdot.org/index.rss 5 author date 1h }}
+
+
+===== Control Macros =====
+
+Some syntax influences how DokuWiki renders a page without creating any output it self. The following control macros are availble:
+
+^ Macro ^ Description |
+| %%~~NOTOC~~%% | If this macro is found on the page, no table of contents will be created |
+| %%~~NOCACHE~~%% | DokuWiki caches all output by default. Sometimes this might not be wanted (eg. when the %%<php>%% syntax above is used), adding this macro will force DokuWiki to rerender a page on every call |
+
+===== Syntax Plugins =====
+
+DokuWiki's syntax can be extended by [[doku>plugins|Plugins]]. How the installed plugins are used is described on their appropriate description pages. The following syntax plugins are available in this particular DokuWiki installation:
+
+~~INFO:syntaxplugins~~
diff --git a/platform/www/data/pages/wiki/welcome.txt b/platform/www/data/pages/wiki/welcome.txt
new file mode 100644
index 0000000..10caa7c
--- /dev/null
+++ b/platform/www/data/pages/wiki/welcome.txt
@@ -0,0 +1,30 @@
+====== Welcome to your new DokuWiki ======
+
+Congratulations, your wiki is now up and running. Here are a few more tips to get you started.
+
+Enjoy your work with DokuWiki,\\
+-- the developers
+
+===== Create your first pages =====
+
+Your wiki needs to have a start page. As long as it doesn't exist, this link will be red: [[:start]].
+
+Go on, follow that link and create the page. If you need help with using the syntax you can always refer to the [[wiki:syntax|syntax page]].
+
+You might also want to use a sidebar. To create it, just edit the [[:sidebar]] page. Everything in that page will be shown in a margin column on the side. Read our [[doku>faq:sidebar|FAQ on sidebars]] to learn more.
+
+Please be aware that not all templates support sidebars.
+
+===== Customize your Wiki =====
+
+Once you're comfortable with creating and editing pages you might want to have a look at the [[this>doku.php?do=admin&page=config|configuration settings]] (be sure to login as superuser first).
+
+You may also want to see what [[doku>plugins|plugins]] and [[doku>templates|templates]] are available at DokuWiki.org to extend the functionality and looks of your DokuWiki installation.
+
+===== Join the Community =====
+
+DokuWiki is an Open Source project that thrives through user contributions. A good way to stay informed on what's going on and to get useful tips in using DokuWiki is subscribing to the [[doku>newsletter]].
+
+The [[https://forum.dokuwiki.org|DokuWiki User Forum]] is an excellent way to get in contact with other DokuWiki users and is just one of the many ways to get [[doku>faq:support|support]].
+
+Of course we'd be more than happy to have you [[doku>teams:getting_involved|getting involved]] with DokuWiki.
diff --git a/platform/www/doku.php b/platform/www/doku.php
new file mode 100644
index 0000000..7921fbe
--- /dev/null
+++ b/platform/www/doku.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * DokuWiki mainscript
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @global Input $INPUT
+ */
+
+// update message version - always use a string to avoid localized floats!
+use dokuwiki\Extension\Event;
+
+$updateVersion = "51.3";
+
+// xdebug_start_profiling();
+
+if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__).'/');
+
+// define all DokuWiki globals here (needed within test requests but also helps to keep track)
+global $ACT, $INPUT, $QUERY, $ID, $REV, $DATE_AT, $IDX,
+ $DATE, $RANGE, $HIGH, $TEXT, $PRE, $SUF, $SUM, $INFO, $JSINFO;
+
+
+if(isset($_SERVER['HTTP_X_DOKUWIKI_DO'])) {
+ $ACT = trim(strtolower($_SERVER['HTTP_X_DOKUWIKI_DO']));
+} elseif(!empty($_REQUEST['idx'])) {
+ $ACT = 'index';
+} elseif(isset($_REQUEST['do'])) {
+ $ACT = $_REQUEST['do'];
+} else {
+ $ACT = 'show';
+}
+
+// load and initialize the core system
+require_once(DOKU_INC.'inc/init.php');
+
+//import variables
+$INPUT->set('id', str_replace("\xC2\xAD", '', $INPUT->str('id'))); //soft-hyphen
+$QUERY = trim($INPUT->str('q'));
+$ID = getID();
+
+$REV = $INPUT->int('rev');
+$DATE_AT = $INPUT->str('at');
+$IDX = $INPUT->str('idx');
+$DATE = $INPUT->int('date');
+$RANGE = $INPUT->str('range');
+$HIGH = $INPUT->param('s');
+if(empty($HIGH)) $HIGH = getGoogleQuery();
+
+if($INPUT->post->has('wikitext')) {
+ $TEXT = cleanText($INPUT->post->str('wikitext'));
+}
+$PRE = cleanText(substr($INPUT->post->str('prefix'), 0, -1));
+$SUF = cleanText($INPUT->post->str('suffix'));
+$SUM = $INPUT->post->str('summary');
+
+
+//parse DATE_AT
+if($DATE_AT) {
+ $date_parse = strtotime($DATE_AT);
+ if($date_parse) {
+ $DATE_AT = $date_parse;
+ } else { // check for UNIX Timestamp
+ $date_parse = @date('Ymd',$DATE_AT);
+ if(!$date_parse || $date_parse === '19700101') {
+ msg(sprintf($lang['unable_to_parse_date'], hsc($DATE_AT)));
+ $DATE_AT = null;
+ }
+ }
+}
+
+//check for existing $REV related to $DATE_AT
+if($DATE_AT) {
+ $pagelog = new \dokuwiki\ChangeLog\PageChangeLog($ID);
+ $rev_t = $pagelog->getLastRevisionAt($DATE_AT);
+ if($rev_t === '') { //current revision
+ $REV = null;
+ $DATE_AT = null;
+ } else if ($rev_t === false) { //page did not exist
+ $rev_n = $pagelog->getRelativeRevision($DATE_AT,+1);
+ msg(sprintf($lang['page_nonexist_rev'],
+ strftime($conf['dformat'],$DATE_AT),
+ wl($ID, array('rev' => $rev_n)),
+ strftime($conf['dformat'],$rev_n)));
+ $REV = $DATE_AT; //will result in a page not exists message
+ } else {
+ $REV = $rev_t;
+ }
+}
+
+//make infos about the selected page available
+$INFO = pageinfo();
+
+// handle debugging
+if($conf['allowdebug'] && $ACT == 'debug') {
+ html_debug();
+ exit;
+}
+
+//send 404 for missing pages if configured or ID has special meaning to bots
+if(!$INFO['exists'] &&
+ ($conf['send404'] || preg_match('/^(robots\.txt|sitemap\.xml(\.gz)?|favicon\.ico|crossdomain\.xml)$/', $ID)) &&
+ ($ACT == 'show' || (!is_array($ACT) && substr($ACT, 0, 7) == 'export_'))
+) {
+ header('HTTP/1.0 404 Not Found');
+}
+
+//prepare breadcrumbs (initialize a static var)
+if($conf['breadcrumbs']) breadcrumbs();
+
+// check upstream
+checkUpdateMessages();
+
+$tmp = array(); // No event data
+Event::createAndTrigger('DOKUWIKI_STARTED', $tmp);
+
+//close session
+session_write_close();
+
+//do the work (picks up what to do from global env)
+act_dispatch();
+
+$tmp = array(); // No event data
+Event::createAndTrigger('DOKUWIKI_DONE', $tmp);
+
+// xdebug_dump_function_profile(1);
diff --git a/platform/www/feed.php b/platform/www/feed.php
new file mode 100644
index 0000000..3302d85
--- /dev/null
+++ b/platform/www/feed.php
@@ -0,0 +1,521 @@
+<?php
+/**
+ * XML feed export
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @global array $conf
+ * @global Input $INPUT
+ */
+
+use dokuwiki\Cache\Cache;
+use dokuwiki\ChangeLog\MediaChangeLog;
+use dokuwiki\ChangeLog\PageChangeLog;
+use dokuwiki\Extension\AuthPlugin;
+use dokuwiki\Extension\Event;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__).'/');
+require_once(DOKU_INC.'inc/init.php');
+
+//close session
+session_write_close();
+
+//feed disabled?
+if(!actionOK('rss')) {
+ http_status(404);
+ echo '<error>RSS feed is disabled.</error>';
+ exit;
+}
+
+// get params
+$opt = rss_parseOptions();
+
+// the feed is dynamic - we need a cache for each combo
+// (but most people just use the default feed so it's still effective)
+$key = join('', array_values($opt)).'$'.$_SERVER['REMOTE_USER'].'$'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'];
+$cache = new Cache($key, '.feed');
+
+// prepare cache depends
+$depends['files'] = getConfigFiles('main');
+$depends['age'] = $conf['rss_update'];
+$depends['purge'] = $INPUT->bool('purge');
+
+// check cacheage and deliver if nothing has changed since last
+// time or the update interval has not passed, also handles conditional requests
+header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+header('Pragma: public');
+header('Content-Type: application/xml; charset=utf-8');
+header('X-Robots-Tag: noindex');
+if($cache->useCache($depends)) {
+ http_conditionalRequest($cache->getTime());
+ if($conf['allowdebug']) header("X-CacheUsed: $cache->cache");
+ print $cache->retrieveCache();
+ exit;
+} else {
+ http_conditionalRequest(time());
+}
+
+// create new feed
+$rss = new UniversalFeedCreator();
+$rss->title = $conf['title'].(($opt['namespace']) ? ' '.$opt['namespace'] : '');
+$rss->link = DOKU_URL;
+$rss->syndicationURL = DOKU_URL.'feed.php';
+$rss->cssStyleSheet = DOKU_URL.'lib/exe/css.php?s=feed';
+
+$image = new FeedImage();
+$image->title = $conf['title'];
+$image->url = tpl_getMediaFile(array(':wiki:favicon.ico', ':favicon.ico', 'images/favicon.ico'), true);
+$image->link = DOKU_URL;
+$rss->image = $image;
+
+$data = null;
+$modes = array(
+ 'list' => 'rssListNamespace',
+ 'search' => 'rssSearch',
+ 'recent' => 'rssRecentChanges'
+);
+if(isset($modes[$opt['feed_mode']])) {
+ $data = $modes[$opt['feed_mode']]($opt);
+} else {
+ $eventData = array(
+ 'opt' => &$opt,
+ 'data' => &$data,
+ );
+ $event = new Event('FEED_MODE_UNKNOWN', $eventData);
+ if($event->advise_before(true)) {
+ echo sprintf('<error>Unknown feed mode %s</error>', hsc($opt['feed_mode']));
+ exit;
+ }
+ $event->advise_after();
+}
+
+rss_buildItems($rss, $data, $opt);
+$feed = $rss->createFeed($opt['feed_type']);
+
+// save cachefile
+$cache->storeCache($feed);
+
+// finally deliver
+print $feed;
+
+// ---------------------------------------------------------------- //
+
+/**
+ * Get URL parameters and config options and return an initialized option array
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function rss_parseOptions() {
+ global $conf;
+ global $INPUT;
+
+ $opt = array();
+
+ foreach(array(
+ // Basic feed properties
+ // Plugins may probably want to add new values to these
+ // properties for implementing own feeds
+
+ // One of: list, search, recent
+ 'feed_mode' => array('str', 'mode', 'recent'),
+ // One of: diff, page, rev, current
+ 'link_to' => array('str', 'linkto', $conf['rss_linkto']),
+ // One of: abstract, diff, htmldiff, html
+ 'item_content' => array('str', 'content', $conf['rss_content']),
+
+ // Special feed properties
+ // These are only used by certain feed_modes
+
+ // String, used for feed title, in list and rc mode
+ 'namespace' => array('str', 'ns', null),
+ // Positive integer, only used in rc mode
+ 'items' => array('int', 'num', $conf['recent']),
+ // Boolean, only used in rc mode
+ 'show_minor' => array('bool', 'minor', false),
+ // Boolean, only used in rc mode
+ 'only_new' => array('bool', 'onlynewpages', false),
+ // String, only used in list mode
+ 'sort' => array('str', 'sort', 'natural'),
+ // String, only used in search mode
+ 'search_query' => array('str', 'q', null),
+ // One of: pages, media, both
+ 'content_type' => array('str', 'view', $conf['rss_media'])
+
+ ) as $name => $val) {
+ $opt[$name] = $INPUT->{$val[0]}($val[1], $val[2], true);
+ }
+
+ $opt['items'] = max(0, (int) $opt['items']);
+ $opt['show_minor'] = (bool) $opt['show_minor'];
+ $opt['only_new'] = (bool) $opt['only_new'];
+ $opt['sort'] = valid_input_set('sort', array('default' => 'natural', 'date'), $opt);
+
+ $opt['guardmail'] = ($conf['mailguard'] != '' && $conf['mailguard'] != 'none');
+
+ $type = $INPUT->valid(
+ 'type',
+ array( 'rss', 'rss2', 'atom', 'atom1', 'rss1'),
+ $conf['rss_type']
+ );
+ switch($type) {
+ case 'rss':
+ $opt['feed_type'] = 'RSS0.91';
+ $opt['mime_type'] = 'text/xml';
+ break;
+ case 'rss2':
+ $opt['feed_type'] = 'RSS2.0';
+ $opt['mime_type'] = 'text/xml';
+ break;
+ case 'atom':
+ $opt['feed_type'] = 'ATOM0.3';
+ $opt['mime_type'] = 'application/xml';
+ break;
+ case 'atom1':
+ $opt['feed_type'] = 'ATOM1.0';
+ $opt['mime_type'] = 'application/atom+xml';
+ break;
+ default:
+ $opt['feed_type'] = 'RSS1.0';
+ $opt['mime_type'] = 'application/xml';
+ }
+
+ $eventData = array(
+ 'opt' => &$opt,
+ );
+ Event::createAndTrigger('FEED_OPTS_POSTPROCESS', $eventData);
+ return $opt;
+}
+
+/**
+ * Add recent changed pages to a feed object
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param FeedCreator $rss the FeedCreator Object
+ * @param array $data the items to add
+ * @param array $opt the feed options
+ */
+function rss_buildItems(&$rss, &$data, $opt) {
+ global $conf;
+ global $lang;
+ /* @var AuthPlugin $auth */
+ global $auth;
+
+ $eventData = array(
+ 'rss' => &$rss,
+ 'data' => &$data,
+ 'opt' => &$opt,
+ );
+ $event = new Event('FEED_DATA_PROCESS', $eventData);
+ if($event->advise_before(false)) {
+ foreach($data as $ditem) {
+ if(!is_array($ditem)) {
+ // not an array? then only a list of IDs was given
+ $ditem = array('id' => $ditem);
+ }
+
+ $item = new FeedItem();
+ $id = $ditem['id'];
+ if(!$ditem['media']) {
+ $meta = p_get_metadata($id);
+ } else {
+ $meta = array();
+ }
+
+ // add date
+ if($ditem['date']) {
+ $date = $ditem['date'];
+ } elseif ($ditem['media']) {
+ $date = @filemtime(mediaFN($id));
+ } elseif (file_exists(wikiFN($id))) {
+ $date = @filemtime(wikiFN($id));
+ } elseif($meta['date']['modified']) {
+ $date = $meta['date']['modified'];
+ } else {
+ $date = 0;
+ }
+ if($date) $item->date = date('r', $date);
+
+ // add title
+ if($conf['useheading'] && $meta['title']) {
+ $item->title = $meta['title'];
+ } else {
+ $item->title = $ditem['id'];
+ }
+ if($conf['rss_show_summary'] && !empty($ditem['sum'])) {
+ $item->title .= ' - '.strip_tags($ditem['sum']);
+ }
+
+ // add item link
+ switch($opt['link_to']) {
+ case 'page':
+ if($ditem['media']) {
+ $item->link = media_managerURL(
+ array(
+ 'image' => $id,
+ 'ns' => getNS($id),
+ 'rev' => $date
+ ), '&', true
+ );
+ } else {
+ $item->link = wl($id, 'rev='.$date, true, '&');
+ }
+ break;
+ case 'rev':
+ if($ditem['media']) {
+ $item->link = media_managerURL(
+ array(
+ 'image' => $id,
+ 'ns' => getNS($id),
+ 'rev' => $date,
+ 'tab_details' => 'history'
+ ), '&', true
+ );
+ } else {
+ $item->link = wl($id, 'do=revisions&rev='.$date, true, '&');
+ }
+ break;
+ case 'current':
+ if($ditem['media']) {
+ $item->link = media_managerURL(
+ array(
+ 'image' => $id,
+ 'ns' => getNS($id)
+ ), '&', true
+ );
+ } else {
+ $item->link = wl($id, '', true, '&');
+ }
+ break;
+ case 'diff':
+ default:
+ if($ditem['media']) {
+ $item->link = media_managerURL(
+ array(
+ 'image' => $id,
+ 'ns' => getNS($id),
+ 'rev' => $date,
+ 'tab_details' => 'history',
+ 'mediado' => 'diff'
+ ), '&', true
+ );
+ } else {
+ $item->link = wl($id, 'rev='.$date.'&do=diff', true, '&');
+ }
+ }
+
+ // add item content
+ switch($opt['item_content']) {
+ case 'diff':
+ case 'htmldiff':
+ if($ditem['media']) {
+ $medialog = new MediaChangeLog($id);
+ $revs = $medialog->getRevisions(0, 1);
+ $rev = $revs[0];
+ $src_r = '';
+ $src_l = '';
+
+ if($size = media_image_preview_size($id, '', new JpegMeta(mediaFN($id)), 300)) {
+ $more = 'w='.$size[0].'&h='.$size[1].'&t='.@filemtime(mediaFN($id));
+ $src_r = ml($id, $more, true, '&amp;', true);
+ }
+ if($rev && $size = media_image_preview_size($id, $rev, new JpegMeta(mediaFN($id, $rev)), 300)) {
+ $more = 'rev='.$rev.'&w='.$size[0].'&h='.$size[1];
+ $src_l = ml($id, $more, true, '&amp;', true);
+ }
+ $content = '';
+ if($src_r) {
+ $content = '<table>';
+ $content .= '<tr><th width="50%">'.$rev.'</th>';
+ $content .= '<th width="50%">'.$lang['current'].'</th></tr>';
+ $content .= '<tr align="center"><td><img src="'.$src_l.'" alt="" /></td><td>';
+ $content .= '<img src="'.$src_r.'" alt="'.$id.'" /></td></tr>';
+ $content .= '</table>';
+ }
+
+ } else {
+ require_once(DOKU_INC.'inc/DifferenceEngine.php');
+ $pagelog = new PageChangeLog($id);
+ $revs = $pagelog->getRevisions(0, 1);
+ $rev = $revs[0];
+
+ if($rev) {
+ $df = new Diff(explode("\n", rawWiki($id, $rev)),
+ explode("\n", rawWiki($id, '')));
+ } else {
+ $df = new Diff(array(''),
+ explode("\n", rawWiki($id, '')));
+ }
+
+ if($opt['item_content'] == 'htmldiff') {
+ // note: no need to escape diff output, TableDiffFormatter provides 'safe' html
+ $tdf = new TableDiffFormatter();
+ $content = '<table>';
+ $content .= '<tr><th colspan="2" width="50%">'.$rev.'</th>';
+ $content .= '<th colspan="2" width="50%">'.$lang['current'].'</th></tr>';
+ $content .= $tdf->format($df);
+ $content .= '</table>';
+ } else {
+ // note: diff output must be escaped, UnifiedDiffFormatter provides plain text
+ $udf = new UnifiedDiffFormatter();
+ $content = "<pre>\n".hsc($udf->format($df))."\n</pre>";
+ }
+ }
+ break;
+ case 'html':
+ if($ditem['media']) {
+ if($size = media_image_preview_size($id, '', new JpegMeta(mediaFN($id)))) {
+ $more = 'w='.$size[0].'&h='.$size[1].'&t='.@filemtime(mediaFN($id));
+ $src = ml($id, $more, true, '&amp;', true);
+ $content = '<img src="'.$src.'" alt="'.$id.'" />';
+ } else {
+ $content = '';
+ }
+ } else {
+ if (@filemtime(wikiFN($id)) === $date) {
+ $content = p_wiki_xhtml($id, '', false);
+ } else {
+ $content = p_wiki_xhtml($id, $date, false);
+ }
+ // no TOC in feeds
+ $content = preg_replace('/(<!-- TOC START -->).*(<!-- TOC END -->)/s', '', $content);
+
+ // add alignment for images
+ $content = preg_replace('/(<img .*?class="medialeft")/s', '\\1 align="left"', $content);
+ $content = preg_replace('/(<img .*?class="mediaright")/s', '\\1 align="right"', $content);
+
+ // make URLs work when canonical is not set, regexp instead of rerendering!
+ if(!$conf['canonical']) {
+ $base = preg_quote(DOKU_REL, '/');
+ $content = preg_replace('/(<a href|<img src)="('.$base.')/s', '$1="'.DOKU_URL, $content);
+ }
+ }
+
+ break;
+ case 'abstract':
+ default:
+ if($ditem['media']) {
+ if($size = media_image_preview_size($id, '', new JpegMeta(mediaFN($id)))) {
+ $more = 'w='.$size[0].'&h='.$size[1].'&t='.@filemtime(mediaFN($id));
+ $src = ml($id, $more, true, '&amp;', true);
+ $content = '<img src="'.$src.'" alt="'.$id.'" />';
+ } else {
+ $content = '';
+ }
+ } else {
+ $content = $meta['description']['abstract'];
+ }
+ }
+ $item->description = $content; //FIXME a plugin hook here could be senseful
+
+ // add user
+ # FIXME should the user be pulled from metadata as well?
+ $user = @$ditem['user']; // the @ spares time repeating lookup
+ if(blank($user)) {
+ $item->author = 'Anonymous';
+ $item->authorEmail = 'anonymous@undisclosed.example.com';
+ } else {
+ $item->author = $user;
+ $item->authorEmail = $user . '@undisclosed.example.com';
+
+ // get real user name if configured
+ if($conf['useacl'] && $auth) {
+ $userInfo = $auth->getUserData($user);
+ if($userInfo) {
+ switch($conf['showuseras']) {
+ case 'username':
+ case 'username_link':
+ $item->author = $userInfo['name'];
+ break;
+ default:
+ $item->author = $user;
+ break;
+ }
+ } else {
+ $item->author = $user;
+ }
+ }
+ }
+
+ // add category
+ if(isset($meta['subject'])) {
+ $item->category = $meta['subject'];
+ } else {
+ $cat = getNS($id);
+ if($cat) $item->category = $cat;
+ }
+
+ // finally add the item to the feed object, after handing it to registered plugins
+ $evdata = array(
+ 'item' => &$item,
+ 'opt' => &$opt,
+ 'ditem' => &$ditem,
+ 'rss' => &$rss
+ );
+ $evt = new Event('FEED_ITEM_ADD', $evdata);
+ if($evt->advise_before()) {
+ $rss->addItem($item);
+ }
+ $evt->advise_after(); // for completeness
+ }
+ }
+ $event->advise_after();
+}
+
+/**
+ * Add recent changed pages to the feed object
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function rssRecentChanges($opt) {
+ global $conf;
+ $flags = 0;
+ if(!$conf['rss_show_deleted']) $flags += RECENTS_SKIP_DELETED;
+ if(!$opt['show_minor']) $flags += RECENTS_SKIP_MINORS;
+ if($opt['only_new']) $flags += RECENTS_ONLY_CREATION;
+ if($opt['content_type'] == 'media' && $conf['mediarevisions']) $flags += RECENTS_MEDIA_CHANGES;
+ if($opt['content_type'] == 'both' && $conf['mediarevisions']) $flags += RECENTS_MEDIA_PAGES_MIXED;
+
+ $recents = getRecents(0, $opt['items'], $opt['namespace'], $flags);
+ return $recents;
+}
+
+/**
+ * Add all pages of a namespace to the feed object
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function rssListNamespace($opt) {
+ require_once(DOKU_INC.'inc/search.php');
+ global $conf;
+
+ $ns = ':'.cleanID($opt['namespace']);
+ $ns = utf8_encodeFN(str_replace(':', '/', $ns));
+
+ $data = array();
+ $search_opts = array(
+ 'depth' => 1,
+ 'pagesonly' => true,
+ 'listfiles' => true
+ );
+ search($data, $conf['datadir'], 'search_universal', $search_opts, $ns, $lvl = 1, $opt['sort']);
+
+ return $data;
+}
+
+/**
+ * Add the result of a full text search to the feed object
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function rssSearch($opt) {
+ if(!$opt['search_query']) return array();
+
+ require_once(DOKU_INC.'inc/fulltext.php');
+ $data = ft_pageSearch($opt['search_query'], $poswords);
+ $data = array_keys($data);
+
+ return $data;
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/inc/.htaccess b/platform/www/inc/.htaccess
new file mode 100644
index 0000000..6ba7d91
--- /dev/null
+++ b/platform/www/inc/.htaccess
@@ -0,0 +1,8 @@
+## no access to the inc directory
+<IfModule mod_authz_core.c>
+ Require all denied
+</IfModule>
+<IfModule !mod_authz_core.c>
+ Order allow,deny
+ Deny from all
+</IfModule>
diff --git a/platform/www/inc/Action/AbstractAclAction.php b/platform/www/inc/Action/AbstractAclAction.php
new file mode 100644
index 0000000..871edb0
--- /dev/null
+++ b/platform/www/inc/Action/AbstractAclAction.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAclRequiredException;
+
+/**
+ * Class AbstractAclAction
+ *
+ * An action that requires the ACL subsystem to be enabled (eg. useacl=1)
+ *
+ * @package dokuwiki\Action
+ */
+abstract class AbstractAclAction extends AbstractAction {
+
+ /** @inheritdoc */
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+ global $conf;
+ global $auth;
+ if(!$conf['useacl']) throw new ActionAclRequiredException();
+ if(!$auth) throw new ActionAclRequiredException();
+ }
+
+}
diff --git a/platform/www/inc/Action/AbstractAction.php b/platform/www/inc/Action/AbstractAction.php
new file mode 100644
index 0000000..ea86238
--- /dev/null
+++ b/platform/www/inc/Action/AbstractAction.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionDisabledException;
+use dokuwiki\Action\Exception\ActionException;
+use dokuwiki\Action\Exception\FatalException;
+
+/**
+ * Class AbstractAction
+ *
+ * Base class for all actions
+ *
+ * @package dokuwiki\Action
+ */
+abstract class AbstractAction {
+
+ /** @var string holds the name of the action (lowercase class name, no namespace) */
+ protected $actionname;
+
+ /**
+ * AbstractAction constructor.
+ *
+ * @param string $actionname the name of this action (see getActionName() for caveats)
+ */
+ public function __construct($actionname = '') {
+ if($actionname !== '') {
+ $this->actionname = $actionname;
+ } else {
+ // http://stackoverflow.com/a/27457689/172068
+ $this->actionname = strtolower(substr(strrchr(get_class($this), '\\'), 1));
+ }
+ }
+
+ /**
+ * Return the minimum permission needed
+ *
+ * This needs to return one of the AUTH_* constants. It will be checked against
+ * the current user and page after checkPermissions() ran through. If it fails,
+ * the user will be shown the Denied action.
+ *
+ * @return int
+ */
+ abstract public function minimumPermission();
+
+ /**
+ * Check conditions are met to run this action
+ *
+ * @throws ActionException
+ * @return void
+ */
+ public function checkPreconditions() {
+ }
+
+ /**
+ * Process data
+ *
+ * This runs before any output is sent to the browser.
+ *
+ * Throw an Exception if a different action should be run after this step.
+ *
+ * @throws ActionException
+ * @return void
+ */
+ public function preProcess() {
+ }
+
+ /**
+ * Output whatever content is wanted within tpl_content();
+ *
+ * @fixme we may want to return a Ui class here
+ */
+ public function tplContent() {
+ throw new FatalException('No content for Action ' . $this->actionname);
+ }
+
+ /**
+ * Returns the name of this action
+ *
+ * This is usually the lowercased class name, but may differ for some actions.
+ * eg. the export_ modes or for the Plugin action.
+ *
+ * @return string
+ */
+ public function getActionName() {
+ return $this->actionname;
+ }
+}
diff --git a/platform/www/inc/Action/AbstractAliasAction.php b/platform/www/inc/Action/AbstractAliasAction.php
new file mode 100644
index 0000000..7240f5e
--- /dev/null
+++ b/platform/www/inc/Action/AbstractAliasAction.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\FatalException;
+
+/**
+ * Class AbstractAliasAction
+ *
+ * An action that is an alias for another action. Skips the minimumPermission check
+ *
+ * Be sure to implement preProcess() and throw an ActionAbort exception
+ * with the proper action.
+ *
+ * @package dokuwiki\Action
+ */
+abstract class AbstractAliasAction extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ public function preProcess() {
+ throw new FatalException('Alias Actions need to implement preProcess to load the aliased action');
+ }
+
+}
diff --git a/platform/www/inc/Action/AbstractUserAction.php b/platform/www/inc/Action/AbstractUserAction.php
new file mode 100644
index 0000000..b4e3f1a
--- /dev/null
+++ b/platform/www/inc/Action/AbstractUserAction.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionUserRequiredException;
+
+/**
+ * Class AbstractUserAction
+ *
+ * An action that requires a logged in user
+ *
+ * @package dokuwiki\Action
+ */
+abstract class AbstractUserAction extends AbstractAclAction {
+
+ /** @inheritdoc */
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+ global $INPUT;
+ if(!$INPUT->server->str('REMOTE_USER')) {
+ throw new ActionUserRequiredException();
+ }
+ }
+
+}
diff --git a/platform/www/inc/Action/Admin.php b/platform/www/inc/Action/Admin.php
new file mode 100644
index 0000000..1c9afd6
--- /dev/null
+++ b/platform/www/inc/Action/Admin.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionException;
+
+/**
+ * Class Admin
+ *
+ * Action to show the admin interface or admin plugins
+ *
+ * @package dokuwiki\Action
+ */
+class Admin extends AbstractUserAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_READ; // let in check later
+ }
+
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+ }
+
+ public function preProcess() {
+ global $INPUT;
+ global $INFO;
+
+ // retrieve admin plugin name from $_REQUEST['page']
+ if(($page = $INPUT->str('page', '', true)) != '') {
+ /** @var $plugin \dokuwiki\Extension\AdminPlugin */
+ if($plugin = plugin_getRequestAdminPlugin()) { // FIXME this method does also permission checking
+ if(!$plugin->isAccessibleByCurrentUser()) {
+ throw new ActionException('denied');
+ }
+ $plugin->handle();
+ }
+ }
+ }
+
+ public function tplContent() {
+ tpl_admin();
+ }
+
+}
diff --git a/platform/www/inc/Action/Backlink.php b/platform/www/inc/Action/Backlink.php
new file mode 100644
index 0000000..0337917
--- /dev/null
+++ b/platform/www/inc/Action/Backlink.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Backlink
+ *
+ * Shows which pages link to the current page
+ *
+ * @package dokuwiki\Action
+ */
+class Backlink extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ html_backlinks();
+ }
+
+}
diff --git a/platform/www/inc/Action/Cancel.php b/platform/www/inc/Action/Cancel.php
new file mode 100644
index 0000000..d4d8277
--- /dev/null
+++ b/platform/www/inc/Action/Cancel.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+
+/**
+ * Class Cancel
+ *
+ * Alias for show. Aborts editing
+ *
+ * @package dokuwiki\Action
+ */
+class Cancel extends AbstractAliasAction {
+
+ /** @inheritdoc */
+ public function preProcess() {
+ global $ID;
+ unlock($ID);
+
+ // continue with draftdel -> redirect -> show
+ throw new ActionAbort('draftdel');
+ }
+
+}
diff --git a/platform/www/inc/Action/Check.php b/platform/www/inc/Action/Check.php
new file mode 100644
index 0000000..36ae8e8
--- /dev/null
+++ b/platform/www/inc/Action/Check.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+
+/**
+ * Class Check
+ *
+ * Adds some debugging info before aborting to show
+ *
+ * @package dokuwiki\Action
+ */
+class Check extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_READ;
+ }
+
+ public function preProcess() {
+ check();
+ throw new ActionAbort();
+ }
+
+}
diff --git a/platform/www/inc/Action/Conflict.php b/platform/www/inc/Action/Conflict.php
new file mode 100644
index 0000000..d880b5b
--- /dev/null
+++ b/platform/www/inc/Action/Conflict.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Conflict
+ *
+ * Show the conflict resolution screen
+ *
+ * @package dokuwiki\Action
+ */
+class Conflict extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ global $INFO;
+ if($INFO['exists']) {
+ return AUTH_EDIT;
+ } else {
+ return AUTH_CREATE;
+ }
+ }
+
+ public function tplContent() {
+ global $PRE;
+ global $TEXT;
+ global $SUF;
+ global $SUM;
+
+ html_conflict(con($PRE, $TEXT, $SUF), $SUM);
+ html_diff(con($PRE, $TEXT, $SUF), false);
+ }
+
+}
diff --git a/platform/www/inc/Action/Denied.php b/platform/www/inc/Action/Denied.php
new file mode 100644
index 0000000..c8e0192
--- /dev/null
+++ b/platform/www/inc/Action/Denied.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Denied
+ *
+ * Show the access denied screen
+ *
+ * @package dokuwiki\Action
+ */
+class Denied extends AbstractAclAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ public function tplContent() {
+ html_denied();
+ }
+
+}
diff --git a/platform/www/inc/Action/Diff.php b/platform/www/inc/Action/Diff.php
new file mode 100644
index 0000000..b14b1d0
--- /dev/null
+++ b/platform/www/inc/Action/Diff.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Diff
+ *
+ * Show the differences between two revisions
+ *
+ * @package dokuwiki\Action
+ */
+class Diff extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_READ;
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ global $INPUT;
+
+ // store the selected diff type in cookie
+ $difftype = $INPUT->str('difftype');
+ if(!empty($difftype)) {
+ set_doku_pref('difftype', $difftype);
+ }
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ html_diff();
+ }
+
+}
diff --git a/platform/www/inc/Action/Draft.php b/platform/www/inc/Action/Draft.php
new file mode 100644
index 0000000..caf0870
--- /dev/null
+++ b/platform/www/inc/Action/Draft.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionException;
+
+/**
+ * Class Draft
+ *
+ * Screen to see and recover a draft
+ *
+ * @package dokuwiki\Action
+ * @fixme combine with Recover?
+ */
+class Draft extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ global $INFO;
+ if($INFO['exists']) {
+ return AUTH_EDIT;
+ } else {
+ return AUTH_CREATE;
+ }
+ }
+
+ /** @inheritdoc */
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+ global $INFO;
+ if(!file_exists($INFO['draft'])) throw new ActionException('edit');
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ html_draft();
+ }
+
+}
diff --git a/platform/www/inc/Action/Draftdel.php b/platform/www/inc/Action/Draftdel.php
new file mode 100644
index 0000000..756c0e8
--- /dev/null
+++ b/platform/www/inc/Action/Draftdel.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+
+/**
+ * Class Draftdel
+ *
+ * Delete a draft
+ *
+ * @package dokuwiki\Action
+ */
+class Draftdel extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_EDIT;
+ }
+
+ /**
+ * Delete an existing draft for the current page and user if any
+ *
+ * Redirects to show, afterwards.
+ *
+ * @throws ActionAbort
+ */
+ public function preProcess() {
+ global $INFO, $ID;
+ $draft = new \dokuwiki\Draft($ID, $INFO['client']);
+ if ($draft->isDraftAvailable()) {
+ $draft->deleteDraft();
+ }
+
+ throw new ActionAbort('redirect');
+ }
+
+}
diff --git a/platform/www/inc/Action/Edit.php b/platform/www/inc/Action/Edit.php
new file mode 100644
index 0000000..061c9e2
--- /dev/null
+++ b/platform/www/inc/Action/Edit.php
@@ -0,0 +1,91 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+
+/**
+ * Class Edit
+ *
+ * Handle editing
+ *
+ * @package dokuwiki\Action
+ */
+class Edit extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ global $INFO;
+ if($INFO['exists']) {
+ return AUTH_READ; // we check again below
+ } else {
+ return AUTH_CREATE;
+ }
+ }
+
+ /**
+ * @inheritdoc falls back to 'source' if page not writable
+ */
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+ global $INFO;
+
+ // no edit permission? view source
+ if($INFO['exists'] && !$INFO['writable']) {
+ throw new ActionAbort('source');
+ }
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ global $ID;
+ global $INFO;
+
+ global $TEXT;
+ global $RANGE;
+ global $PRE;
+ global $SUF;
+ global $REV;
+ global $SUM;
+ global $lang;
+ global $DATE;
+
+ if(!isset($TEXT)) {
+ if($INFO['exists']) {
+ if($RANGE) {
+ list($PRE, $TEXT, $SUF) = rawWikiSlices($RANGE, $ID, $REV);
+ } else {
+ $TEXT = rawWiki($ID, $REV);
+ }
+ } else {
+ $TEXT = pageTemplate($ID);
+ }
+ }
+
+ //set summary default
+ if(!$SUM) {
+ if($REV) {
+ $SUM = sprintf($lang['restored'], dformat($REV));
+ } elseif(!$INFO['exists']) {
+ $SUM = $lang['created'];
+ }
+ }
+
+ // Use the date of the newest revision, not of the revision we edit
+ // This is used for conflict detection
+ if(!$DATE) $DATE = @filemtime(wikiFN($ID));
+
+ //check if locked by anyone - if not lock for my self
+ $lockedby = checklock($ID);
+ if($lockedby) {
+ throw new ActionAbort('locked');
+ };
+ lock($ID);
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ html_edit();
+ }
+
+}
diff --git a/platform/www/inc/Action/Exception/ActionAbort.php b/platform/www/inc/Action/Exception/ActionAbort.php
new file mode 100644
index 0000000..9c188bb
--- /dev/null
+++ b/platform/www/inc/Action/Exception/ActionAbort.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace dokuwiki\Action\Exception;
+
+/**
+ * Class ActionAbort
+ *
+ * Strictly speaking not an Exception but an expected execution path. Used to
+ * signal when one action is done and another should take over.
+ *
+ * If you want to signal the same but under some error condition use ActionException
+ * or one of it's decendants.
+ *
+ * The message will NOT be shown to the enduser
+ *
+ * @package dokuwiki\Action\Exception
+ */
+class ActionAbort extends ActionException {
+
+}
diff --git a/platform/www/inc/Action/Exception/ActionAclRequiredException.php b/platform/www/inc/Action/Exception/ActionAclRequiredException.php
new file mode 100644
index 0000000..64a2c61
--- /dev/null
+++ b/platform/www/inc/Action/Exception/ActionAclRequiredException.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace dokuwiki\Action\Exception;
+
+/**
+ * Class ActionAclRequiredException
+ *
+ * Thrown by AbstractACLAction when an action requires that the ACL subsystem is
+ * enabled but it isn't. You should not use it
+ *
+ * The message will NOT be shown to the enduser
+ *
+ * @package dokuwiki\Action\Exception
+ */
+class ActionAclRequiredException extends ActionException {
+
+}
diff --git a/platform/www/inc/Action/Exception/ActionDisabledException.php b/platform/www/inc/Action/Exception/ActionDisabledException.php
new file mode 100644
index 0000000..40a0c7d
--- /dev/null
+++ b/platform/www/inc/Action/Exception/ActionDisabledException.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace dokuwiki\Action\Exception;
+
+/**
+ * Class ActionDisabledException
+ *
+ * Thrown when the requested action has been disabled. Eg. through the 'disableactions'
+ * config setting. You should probably not use it.
+ *
+ * The message will NOT be shown to the enduser, but a generic information will be shown.
+ *
+ * @package dokuwiki\Action\Exception
+ */
+class ActionDisabledException extends ActionException {
+
+}
diff --git a/platform/www/inc/Action/Exception/ActionException.php b/platform/www/inc/Action/Exception/ActionException.php
new file mode 100644
index 0000000..381584c
--- /dev/null
+++ b/platform/www/inc/Action/Exception/ActionException.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace dokuwiki\Action\Exception;
+
+/**
+ * Class ActionException
+ *
+ * This exception and its subclasses signal that the current action should be
+ * aborted and a different action should be used instead. The new action can
+ * be given as parameter in the constructor. Defaults to 'show'
+ *
+ * The message will NOT be shown to the enduser
+ *
+ * @package dokuwiki\Action\Exception
+ */
+class ActionException extends \Exception {
+
+ /** @var string the new action */
+ protected $newaction;
+
+ /** @var bool should the exception's message be shown to the user? */
+ protected $displayToUser = false;
+
+ /**
+ * ActionException constructor.
+ *
+ * When no new action is given 'show' is assumed. For requests that originated in a POST,
+ * a 'redirect' is used which will cause a redirect to the 'show' action.
+ *
+ * @param string|null $newaction the action that should be used next
+ * @param string $message optional message, will not be shown except for some dub classes
+ */
+ public function __construct($newaction = null, $message = '') {
+ global $INPUT;
+ parent::__construct($message);
+ if(is_null($newaction)) {
+ if(strtolower($INPUT->server->str('REQUEST_METHOD')) == 'post') {
+ $newaction = 'redirect';
+ } else {
+ $newaction = 'show';
+ }
+ }
+
+ $this->newaction = $newaction;
+ }
+
+ /**
+ * Returns the action to use next
+ *
+ * @return string
+ */
+ public function getNewAction() {
+ return $this->newaction;
+ }
+
+ /**
+ * Should this Exception's message be shown to the user?
+ *
+ * @param null|bool $set when null is given, the current setting is not changed
+ * @return bool
+ */
+ public function displayToUser($set = null) {
+ if(!is_null($set)) $this->displayToUser = $set;
+ return $set;
+ }
+}
diff --git a/platform/www/inc/Action/Exception/ActionUserRequiredException.php b/platform/www/inc/Action/Exception/ActionUserRequiredException.php
new file mode 100644
index 0000000..aab06cc
--- /dev/null
+++ b/platform/www/inc/Action/Exception/ActionUserRequiredException.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace dokuwiki\Action\Exception;
+
+/**
+ * Class ActionUserRequiredException
+ *
+ * Thrown by AbstractUserAction when an action requires that a user is logged
+ * in but it isn't. You should not use it.
+ *
+ * The message will NOT be shown to the enduser
+ *
+ * @package dokuwiki\Action\Exception
+ */
+class ActionUserRequiredException extends ActionException {
+
+}
diff --git a/platform/www/inc/Action/Exception/FatalException.php b/platform/www/inc/Action/Exception/FatalException.php
new file mode 100644
index 0000000..42e30cc
--- /dev/null
+++ b/platform/www/inc/Action/Exception/FatalException.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace dokuwiki\Action\Exception;
+
+/**
+ * Class FatalException
+ *
+ * A fatal exception during handling the action
+ *
+ * Will abort all handling and display some info to the user. The HTTP status code
+ * can be defined.
+ *
+ * @package dokuwiki\Action\Exception
+ */
+class FatalException extends \Exception {
+ /**
+ * FatalException constructor.
+ *
+ * @param string $message the message to send
+ * @param int $status the HTTP status to send
+ * @param null|\Exception $previous previous exception
+ */
+ public function __construct($message = 'A fatal error occured', $status = 500, $previous = null) {
+ parent::__construct($message, $status, $previous);
+ }
+}
diff --git a/platform/www/inc/Action/Exception/NoActionException.php b/platform/www/inc/Action/Exception/NoActionException.php
new file mode 100644
index 0000000..1c4e4d0
--- /dev/null
+++ b/platform/www/inc/Action/Exception/NoActionException.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace dokuwiki\Action\Exception;
+
+/**
+ * Class NoActionException
+ *
+ * Thrown in the ActionRouter when a wanted action can not be found. Triggers
+ * the unknown action event
+ *
+ * @package dokuwiki\Action\Exception
+ */
+class NoActionException extends \Exception {
+
+}
diff --git a/platform/www/inc/Action/Export.php b/platform/www/inc/Action/Export.php
new file mode 100644
index 0000000..6b46b27
--- /dev/null
+++ b/platform/www/inc/Action/Export.php
@@ -0,0 +1,113 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+use dokuwiki\Extension\Event;
+
+/**
+ * Class Export
+ *
+ * Handle exporting by calling the appropriate renderer
+ *
+ * @package dokuwiki\Action
+ */
+class Export extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_READ;
+ }
+
+ /**
+ * Export a wiki page for various formats
+ *
+ * Triggers ACTION_EXPORT_POSTPROCESS
+ *
+ * Event data:
+ * data['id'] -- page id
+ * data['mode'] -- requested export mode
+ * data['headers'] -- export headers
+ * data['output'] -- export output
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Klier <chi@chimeric.de>
+ * @inheritdoc
+ */
+ public function preProcess() {
+ global $ID;
+ global $REV;
+ global $conf;
+ global $lang;
+
+ $pre = '';
+ $post = '';
+ $headers = array();
+
+ // search engines: never cache exported docs! (Google only currently)
+ $headers['X-Robots-Tag'] = 'noindex';
+
+ $mode = substr($this->actionname, 7);
+ switch($mode) {
+ case 'raw':
+ $headers['Content-Type'] = 'text/plain; charset=utf-8';
+ $headers['Content-Disposition'] = 'attachment; filename=' . noNS($ID) . '.txt';
+ $output = rawWiki($ID, $REV);
+ break;
+ case 'xhtml':
+ $pre .= '<!DOCTYPE html>' . DOKU_LF;
+ $pre .= '<html lang="' . $conf['lang'] . '" dir="' . $lang['direction'] . '">' . DOKU_LF;
+ $pre .= '<head>' . DOKU_LF;
+ $pre .= ' <meta charset="utf-8" />' . DOKU_LF; // FIXME improve wrapper
+ $pre .= ' <title>' . $ID . '</title>' . DOKU_LF;
+
+ // get metaheaders
+ ob_start();
+ tpl_metaheaders();
+ $pre .= ob_get_clean();
+
+ $pre .= '</head>' . DOKU_LF;
+ $pre .= '<body>' . DOKU_LF;
+ $pre .= '<div class="dokuwiki export">' . DOKU_LF;
+
+ // get toc
+ $pre .= tpl_toc(true);
+
+ $headers['Content-Type'] = 'text/html; charset=utf-8';
+ $output = p_wiki_xhtml($ID, $REV, false);
+
+ $post .= '</div>' . DOKU_LF;
+ $post .= '</body>' . DOKU_LF;
+ $post .= '</html>' . DOKU_LF;
+ break;
+ case 'xhtmlbody':
+ $headers['Content-Type'] = 'text/html; charset=utf-8';
+ $output = p_wiki_xhtml($ID, $REV, false);
+ break;
+ default:
+ $output = p_cached_output(wikiFN($ID, $REV), $mode, $ID);
+ $headers = p_get_metadata($ID, "format $mode");
+ break;
+ }
+
+ // prepare event data
+ $data = array();
+ $data['id'] = $ID;
+ $data['mode'] = $mode;
+ $data['headers'] = $headers;
+ $data['output'] =& $output;
+
+ Event::createAndTrigger('ACTION_EXPORT_POSTPROCESS', $data);
+
+ if(!empty($data['output'])) {
+ if(is_array($data['headers'])) foreach($data['headers'] as $key => $val) {
+ header("$key: $val");
+ }
+ print $pre . $data['output'] . $post;
+ exit;
+ }
+
+ throw new ActionAbort();
+ }
+
+}
diff --git a/platform/www/inc/Action/Index.php b/platform/www/inc/Action/Index.php
new file mode 100644
index 0000000..c87a3f8
--- /dev/null
+++ b/platform/www/inc/Action/Index.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Index
+ *
+ * Show the human readable sitemap. Do not confuse with Sitemap
+ *
+ * @package dokuwiki\Action
+ */
+class Index extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ global $IDX;
+ html_index($IDX);
+ }
+
+}
diff --git a/platform/www/inc/Action/Locked.php b/platform/www/inc/Action/Locked.php
new file mode 100644
index 0000000..41866e3
--- /dev/null
+++ b/platform/www/inc/Action/Locked.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Locked
+ *
+ * Show a locked screen when a page is locked
+ *
+ * @package dokuwiki\Action
+ */
+class Locked extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_READ;
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ html_locked();
+ html_edit();
+ }
+
+}
diff --git a/platform/www/inc/Action/Login.php b/platform/www/inc/Action/Login.php
new file mode 100644
index 0000000..7f903ff
--- /dev/null
+++ b/platform/www/inc/Action/Login.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionException;
+
+/**
+ * Class Login
+ *
+ * The login form. Actual logins are handled in inc/auth.php
+ *
+ * @package dokuwiki\Action
+ */
+class Login extends AbstractAclAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /** @inheritdoc */
+ public function checkPreconditions() {
+ global $INPUT;
+ parent::checkPreconditions();
+ if($INPUT->server->has('REMOTE_USER')) {
+ // nothing to do
+ throw new ActionException();
+ }
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ html_login();
+ }
+
+}
diff --git a/platform/www/inc/Action/Logout.php b/platform/www/inc/Action/Logout.php
new file mode 100644
index 0000000..28e8fee
--- /dev/null
+++ b/platform/www/inc/Action/Logout.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionDisabledException;
+use dokuwiki\Action\Exception\ActionException;
+
+/**
+ * Class Logout
+ *
+ * Log out a user
+ *
+ * @package dokuwiki\Action
+ */
+class Logout extends AbstractUserAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /** @inheritdoc */
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+
+ /** @var \dokuwiki\Extension\AuthPlugin $auth */
+ global $auth;
+ if(!$auth->canDo('logout')) throw new ActionDisabledException();
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ global $ID;
+ global $INPUT;
+
+ // when logging out during an edit session, unlock the page
+ $lockedby = checklock($ID);
+ if($lockedby == $INPUT->server->str('REMOTE_USER')) {
+ unlock($ID);
+ }
+
+ // do the logout stuff and redirect to login
+ auth_logoff();
+ send_redirect(wl($ID, array('do' => 'login'), true, '&'));
+
+ // should never be reached
+ throw new ActionException('login');
+ }
+
+}
diff --git a/platform/www/inc/Action/Media.php b/platform/www/inc/Action/Media.php
new file mode 100644
index 0000000..77a2a6f
--- /dev/null
+++ b/platform/www/inc/Action/Media.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Media
+ *
+ * The full screen media manager
+ *
+ * @package dokuwiki\Action
+ */
+class Media extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_READ;
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ tpl_media();
+ }
+
+}
diff --git a/platform/www/inc/Action/Plugin.php b/platform/www/inc/Action/Plugin.php
new file mode 100644
index 0000000..43964cf
--- /dev/null
+++ b/platform/www/inc/Action/Plugin.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Plugin
+ *
+ * Used to run action plugins
+ *
+ * @package dokuwiki\Action
+ */
+class Plugin extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /**
+ * Outputs nothing but a warning unless an action plugin overwrites it
+ *
+ * @inheritdoc
+ * @triggers TPL_ACT_UNKNOWN
+ */
+ public function tplContent() {
+ $evt = new \dokuwiki\Extension\Event('TPL_ACT_UNKNOWN', $this->actionname);
+ if($evt->advise_before()) {
+ msg('Failed to handle action: ' . hsc($this->actionname), -1);
+ }
+ $evt->advise_after();
+ }
+}
diff --git a/platform/www/inc/Action/Preview.php b/platform/www/inc/Action/Preview.php
new file mode 100644
index 0000000..7a5aa48
--- /dev/null
+++ b/platform/www/inc/Action/Preview.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Preview
+ *
+ * preview during editing
+ *
+ * @package dokuwiki\Action
+ */
+class Preview extends Edit {
+
+ /** @inheritdoc */
+ public function preProcess() {
+ header('X-XSS-Protection: 0');
+ $this->savedraft();
+ parent::preProcess();
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ global $TEXT;
+ html_edit();
+ html_show($TEXT);
+ }
+
+ /**
+ * Saves a draft on preview
+ */
+ protected function savedraft() {
+ global $ID, $INFO;
+ $draft = new \dokuwiki\Draft($ID, $INFO['client']);
+ if (!$draft->saveDraft()) {
+ $errors = $draft->getErrors();
+ foreach ($errors as $error) {
+ msg(hsc($error), -1);
+ }
+ }
+ }
+
+}
diff --git a/platform/www/inc/Action/Profile.php b/platform/www/inc/Action/Profile.php
new file mode 100644
index 0000000..654a238
--- /dev/null
+++ b/platform/www/inc/Action/Profile.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+use dokuwiki\Action\Exception\ActionDisabledException;
+
+/**
+ * Class Profile
+ *
+ * Handle the profile form
+ *
+ * @package dokuwiki\Action
+ */
+class Profile extends AbstractUserAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /** @inheritdoc */
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+
+ /** @var \dokuwiki\Extension\AuthPlugin $auth */
+ global $auth;
+ if(!$auth->canDo('Profile')) throw new ActionDisabledException();
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ global $lang;
+ if(updateprofile()) {
+ msg($lang['profchanged'], 1);
+ throw new ActionAbort('show');
+ }
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ html_updateprofile();
+ }
+
+}
diff --git a/platform/www/inc/Action/ProfileDelete.php b/platform/www/inc/Action/ProfileDelete.php
new file mode 100644
index 0000000..89c58ed
--- /dev/null
+++ b/platform/www/inc/Action/ProfileDelete.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+use dokuwiki\Action\Exception\ActionDisabledException;
+
+/**
+ * Class ProfileDelete
+ *
+ * Delete a user account
+ *
+ * @package dokuwiki\Action
+ */
+class ProfileDelete extends AbstractUserAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /** @inheritdoc */
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+
+ /** @var \dokuwiki\Extension\AuthPlugin $auth */
+ global $auth;
+ if(!$auth->canDo('delUser')) throw new ActionDisabledException();
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ global $lang;
+ if(auth_deleteprofile()) {
+ msg($lang['profdeleted'], 1);
+ throw new ActionAbort('show');
+ } else {
+ throw new ActionAbort('profile');
+ }
+ }
+
+}
diff --git a/platform/www/inc/Action/Recent.php b/platform/www/inc/Action/Recent.php
new file mode 100644
index 0000000..9273d52
--- /dev/null
+++ b/platform/www/inc/Action/Recent.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Recent
+ *
+ * The recent changes view
+ *
+ * @package dokuwiki\Action
+ */
+class Recent extends AbstractAction {
+
+ /** @var string what type of changes to show */
+ protected $showType = 'both';
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ global $INPUT;
+ $show_changes = $INPUT->str('show_changes');
+ if(!empty($show_changes)) {
+ set_doku_pref('show_changes', $show_changes);
+ $this->showType = $show_changes;
+ } else {
+ $this->showType = get_doku_pref('show_changes', 'both');
+ }
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ global $INPUT;
+ html_recent((int) $INPUT->extract('first')->int('first'), $this->showType);
+ }
+
+}
diff --git a/platform/www/inc/Action/Recover.php b/platform/www/inc/Action/Recover.php
new file mode 100644
index 0000000..7966396
--- /dev/null
+++ b/platform/www/inc/Action/Recover.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+
+/**
+ * Class Recover
+ *
+ * Recover a draft
+ *
+ * @package dokuwiki\Action
+ */
+class Recover extends AbstractAliasAction {
+
+ /** @inheritdoc */
+ public function preProcess() {
+ throw new ActionAbort('edit');
+ }
+
+}
diff --git a/platform/www/inc/Action/Redirect.php b/platform/www/inc/Action/Redirect.php
new file mode 100644
index 0000000..dca911a
--- /dev/null
+++ b/platform/www/inc/Action/Redirect.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+use dokuwiki\Extension\Event;
+
+/**
+ * Class Redirect
+ *
+ * Used to redirect to the current page with the last edited section as a target if found
+ *
+ * @package dokuwiki\Action
+ */
+class Redirect extends AbstractAliasAction {
+
+ /**
+ * Redirect to the show action, trying to jump to the previously edited section
+ *
+ * @triggers ACTION_SHOW_REDIRECT
+ * @throws ActionAbort
+ */
+ public function preProcess() {
+ global $PRE;
+ global $TEXT;
+ global $INPUT;
+ global $ID;
+ global $ACT;
+
+ $opts = array(
+ 'id' => $ID,
+ 'preact' => $ACT
+ );
+ //get section name when coming from section edit
+ if($INPUT->has('hid')) {
+ // Use explicitly transmitted header id
+ $opts['fragment'] = $INPUT->str('hid');
+ } else if($PRE && preg_match('/^\s*==+([^=\n]+)/', $TEXT, $match)) {
+ // Fallback to old mechanism
+ $check = false; //Byref
+ $opts['fragment'] = sectionID($match[0], $check);
+ }
+
+ // execute the redirect
+ Event::createAndTrigger('ACTION_SHOW_REDIRECT', $opts, array($this, 'redirect'));
+
+ // should never be reached
+ throw new ActionAbort('show');
+ }
+
+ /**
+ * Execute the redirect
+ *
+ * Default action for ACTION_SHOW_REDIRECT
+ *
+ * @param array $opts id and fragment for the redirect and the preact
+ */
+ public function redirect($opts) {
+ $go = wl($opts['id'], '', true, '&');
+ if(isset($opts['fragment'])) $go .= '#' . $opts['fragment'];
+
+ //show it
+ send_redirect($go);
+ }
+}
diff --git a/platform/www/inc/Action/Register.php b/platform/www/inc/Action/Register.php
new file mode 100644
index 0000000..7d21bff
--- /dev/null
+++ b/platform/www/inc/Action/Register.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+use dokuwiki\Action\Exception\ActionDisabledException;
+
+/**
+ * Class Register
+ *
+ * Self registering a new user
+ *
+ * @package dokuwiki\Action
+ */
+class Register extends AbstractAclAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /** @inheritdoc */
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+
+ /** @var \dokuwiki\Extension\AuthPlugin $auth */
+ global $auth;
+ global $conf;
+ if(isset($conf['openregister']) && !$conf['openregister']) throw new ActionDisabledException();
+ if(!$auth->canDo('addUser')) throw new ActionDisabledException();
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ if(register()) { // FIXME could be moved from auth to here
+ throw new ActionAbort('login');
+ }
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ html_register();
+ }
+
+}
diff --git a/platform/www/inc/Action/Resendpwd.php b/platform/www/inc/Action/Resendpwd.php
new file mode 100644
index 0000000..dfa4a99
--- /dev/null
+++ b/platform/www/inc/Action/Resendpwd.php
@@ -0,0 +1,177 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+use dokuwiki\Action\Exception\ActionDisabledException;
+
+/**
+ * Class Resendpwd
+ *
+ * Handle password recovery
+ *
+ * @package dokuwiki\Action
+ */
+class Resendpwd extends AbstractAclAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /** @inheritdoc */
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+
+ /** @var \dokuwiki\Extension\AuthPlugin $auth */
+ global $auth;
+ global $conf;
+ if(isset($conf['resendpasswd']) && !$conf['resendpasswd']) throw new ActionDisabledException(); //legacy option
+ if(!$auth->canDo('modPass')) throw new ActionDisabledException();
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ if($this->resendpwd()) {
+ throw new ActionAbort('login');
+ }
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ html_resendpwd();
+ }
+
+ /**
+ * Send a new password
+ *
+ * This function handles both phases of the password reset:
+ *
+ * - handling the first request of password reset
+ * - validating the password reset auth token
+ *
+ * @author Benoit Chesneau <benoit@bchesneau.info>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @fixme this should be split up into multiple methods
+ * @return bool true on success, false on any error
+ */
+ protected function resendpwd() {
+ global $lang;
+ global $conf;
+ /* @var \dokuwiki\Extension\AuthPlugin $auth */
+ global $auth;
+ global $INPUT;
+
+ if(!actionOK('resendpwd')) {
+ msg($lang['resendna'], -1);
+ return false;
+ }
+
+ $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth'));
+
+ if($token) {
+ // we're in token phase - get user info from token
+
+ $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth';
+ if(!file_exists($tfile)) {
+ msg($lang['resendpwdbadauth'], -1);
+ $INPUT->remove('pwauth');
+ return false;
+ }
+ // token is only valid for 3 days
+ if((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) {
+ msg($lang['resendpwdbadauth'], -1);
+ $INPUT->remove('pwauth');
+ @unlink($tfile);
+ return false;
+ }
+
+ $user = io_readfile($tfile);
+ $userinfo = $auth->getUserData($user, $requireGroups = false);
+ if(!$userinfo['mail']) {
+ msg($lang['resendpwdnouser'], -1);
+ return false;
+ }
+
+ if(!$conf['autopasswd']) { // we let the user choose a password
+ $pass = $INPUT->str('pass');
+
+ // password given correctly?
+ if(!$pass) return false;
+ if($pass != $INPUT->str('passchk')) {
+ msg($lang['regbadpass'], -1);
+ return false;
+ }
+
+ // change it
+ if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
+ msg($lang['proffail'], -1);
+ return false;
+ }
+
+ } else { // autogenerate the password and send by mail
+
+ $pass = auth_pwgen($user);
+ if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
+ msg($lang['proffail'], -1);
+ return false;
+ }
+
+ if(auth_sendPassword($user, $pass)) {
+ msg($lang['resendpwdsuccess'], 1);
+ } else {
+ msg($lang['regmailfail'], -1);
+ }
+ }
+
+ @unlink($tfile);
+ return true;
+
+ } else {
+ // we're in request phase
+
+ if(!$INPUT->post->bool('save')) return false;
+
+ if(!$INPUT->post->str('login')) {
+ msg($lang['resendpwdmissing'], -1);
+ return false;
+ } else {
+ $user = trim($auth->cleanUser($INPUT->post->str('login')));
+ }
+
+ $userinfo = $auth->getUserData($user, $requireGroups = false);
+ if(!$userinfo['mail']) {
+ msg($lang['resendpwdnouser'], -1);
+ return false;
+ }
+
+ // generate auth token
+ $token = md5(auth_randombytes(16)); // random secret
+ $tfile = $conf['cachedir'] . '/' . $token[0] . '/' . $token . '.pwauth';
+ $url = wl('', array('do' => 'resendpwd', 'pwauth' => $token), true, '&');
+
+ io_saveFile($tfile, $user);
+
+ $text = rawLocale('pwconfirm');
+ $trep = array(
+ 'FULLNAME' => $userinfo['name'],
+ 'LOGIN' => $user,
+ 'CONFIRM' => $url
+ );
+
+ $mail = new \Mailer();
+ $mail->to($userinfo['name'] . ' <' . $userinfo['mail'] . '>');
+ $mail->subject($lang['regpwmail']);
+ $mail->setBody($text, $trep);
+ if($mail->send()) {
+ msg($lang['resendpwdconfirm'], 1);
+ } else {
+ msg($lang['regmailfail'], -1);
+ }
+ return true;
+ }
+ // never reached
+ }
+
+}
diff --git a/platform/www/inc/Action/Revert.php b/platform/www/inc/Action/Revert.php
new file mode 100644
index 0000000..07c322c
--- /dev/null
+++ b/platform/www/inc/Action/Revert.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+use dokuwiki\Action\Exception\ActionException;
+
+/**
+ * Class Revert
+ *
+ * Quick revert to an old revision
+ *
+ * @package dokuwiki\Action
+ */
+class Revert extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_EDIT;
+ }
+
+ /**
+ *
+ * @inheritdoc
+ * @throws ActionAbort
+ * @throws ActionException
+ * @todo check for writability of the current page ($INFO might do it wrong and check the attic version)
+ */
+ public function preProcess() {
+ if(!checkSecurityToken()) throw new ActionException();
+
+ global $ID;
+ global $REV;
+ global $lang;
+
+ // when no revision is given, delete current one
+ // FIXME this feature is not exposed in the GUI currently
+ $text = '';
+ $sum = $lang['deleted'];
+ if($REV) {
+ $text = rawWiki($ID, $REV);
+ if(!$text) throw new ActionException(); //something went wrong
+ $sum = sprintf($lang['restored'], dformat($REV));
+ }
+
+ // spam check
+ if(checkwordblock($text)) {
+ msg($lang['wordblock'], -1);
+ throw new ActionException('edit');
+ }
+
+ saveWikiText($ID, $text, $sum, false);
+ msg($sum, 1);
+ $REV = '';
+
+ // continue with draftdel -> redirect -> show
+ throw new ActionAbort('draftdel');
+ }
+
+}
diff --git a/platform/www/inc/Action/Revisions.php b/platform/www/inc/Action/Revisions.php
new file mode 100644
index 0000000..b8db531
--- /dev/null
+++ b/platform/www/inc/Action/Revisions.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Revisions
+ *
+ * Show the list of old revisions of the current page
+ *
+ * @package dokuwiki\Action
+ */
+class Revisions extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_READ;
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ global $INPUT;
+ html_revisions($INPUT->int('first'));
+ }
+}
diff --git a/platform/www/inc/Action/Save.php b/platform/www/inc/Action/Save.php
new file mode 100644
index 0000000..0b24729
--- /dev/null
+++ b/platform/www/inc/Action/Save.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+use dokuwiki\Action\Exception\ActionException;
+
+/**
+ * Class Save
+ *
+ * Save at the end of an edit session
+ *
+ * @package dokuwiki\Action
+ */
+class Save extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ global $INFO;
+ if($INFO['exists']) {
+ return AUTH_EDIT;
+ } else {
+ return AUTH_CREATE;
+ }
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ if(!checkSecurityToken()) throw new ActionException('preview');
+
+ global $ID;
+ global $DATE;
+ global $PRE;
+ global $TEXT;
+ global $SUF;
+ global $SUM;
+ global $lang;
+ global $INFO;
+ global $INPUT;
+
+ //spam check
+ if(checkwordblock()) {
+ msg($lang['wordblock'], -1);
+ throw new ActionException('edit');
+ }
+ //conflict check
+ if($DATE != 0 && $INFO['meta']['date']['modified'] > $DATE) {
+ throw new ActionException('conflict');
+ }
+
+ //save it
+ saveWikiText($ID, con($PRE, $TEXT, $SUF, true), $SUM, $INPUT->bool('minor')); //use pretty mode for con
+ //unlock it
+ unlock($ID);
+
+ // continue with draftdel -> redirect -> show
+ throw new ActionAbort('draftdel');
+ }
+
+}
diff --git a/platform/www/inc/Action/Search.php b/platform/www/inc/Action/Search.php
new file mode 100644
index 0000000..88bd0ba
--- /dev/null
+++ b/platform/www/inc/Action/Search.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+
+/**
+ * Class Search
+ *
+ * Search for pages and content
+ *
+ * @package dokuwiki\Action
+ */
+class Search extends AbstractAction {
+
+ protected $pageLookupResults = array();
+ protected $fullTextResults = array();
+ protected $highlight = array();
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /**
+ * we only search if a search word was given
+ *
+ * @inheritdoc
+ */
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+ }
+
+ public function preProcess()
+ {
+ global $QUERY, $ID, $conf, $INPUT;
+ $s = cleanID($QUERY);
+
+ if ($ID !== $conf['start'] && !$INPUT->has('q')) {
+ parse_str($INPUT->server->str('QUERY_STRING'), $urlParts);
+ $urlParts['q'] = $urlParts['id'];
+ unset($urlParts['id']);
+ $url = wl($ID, $urlParts, true, '&');
+ send_redirect($url);
+ }
+
+ if ($s === '') throw new ActionAbort();
+ $this->adjustGlobalQuery();
+ }
+
+ /** @inheritdoc */
+ public function tplContent()
+ {
+ $this->execute();
+
+ $search = new \dokuwiki\Ui\Search($this->pageLookupResults, $this->fullTextResults, $this->highlight);
+ $search->show();
+ }
+
+
+ /**
+ * run the search
+ */
+ protected function execute()
+ {
+ global $INPUT, $QUERY;
+ $after = $INPUT->str('min');
+ $before = $INPUT->str('max');
+ $this->pageLookupResults = ft_pageLookup($QUERY, true, useHeading('navigation'), $after, $before);
+ $this->fullTextResults = ft_pageSearch($QUERY, $highlight, $INPUT->str('srt'), $after, $before);
+ $this->highlight = $highlight;
+ }
+
+ /**
+ * Adjust the global query accordingly to the config search_nslimit and search_fragment
+ *
+ * This will only do something if the search didn't originate from the form on the searchpage itself
+ */
+ protected function adjustGlobalQuery()
+ {
+ global $conf, $INPUT, $QUERY, $ID;
+
+ if ($INPUT->bool('sf')) {
+ return;
+ }
+
+ $Indexer = idx_get_indexer();
+ $parsedQuery = ft_queryParser($Indexer, $QUERY);
+
+ if (empty($parsedQuery['ns']) && empty($parsedQuery['notns'])) {
+ if ($conf['search_nslimit'] > 0) {
+ if (getNS($ID) !== false) {
+ $nsParts = explode(':', getNS($ID));
+ $ns = implode(':', array_slice($nsParts, 0, $conf['search_nslimit']));
+ $QUERY .= " @$ns";
+ }
+ }
+ }
+
+ if ($conf['search_fragment'] !== 'exact') {
+ if (empty(array_diff($parsedQuery['words'], $parsedQuery['and']))) {
+ if (strpos($QUERY, '*') === false) {
+ $queryParts = explode(' ', $QUERY);
+ $queryParts = array_map(function ($part) {
+ if (strpos($part, '@') === 0) {
+ return $part;
+ }
+ if (strpos($part, 'ns:') === 0) {
+ return $part;
+ }
+ if (strpos($part, '^') === 0) {
+ return $part;
+ }
+ if (strpos($part, '-ns:') === 0) {
+ return $part;
+ }
+
+ global $conf;
+
+ if ($conf['search_fragment'] === 'starts_with') {
+ return $part . '*';
+ }
+ if ($conf['search_fragment'] === 'ends_with') {
+ return '*' . $part;
+ }
+
+ return '*' . $part . '*';
+
+ }, $queryParts);
+ $QUERY = implode(' ', $queryParts);
+ }
+ }
+ }
+ }
+}
diff --git a/platform/www/inc/Action/Show.php b/platform/www/inc/Action/Show.php
new file mode 100644
index 0000000..a5cb534
--- /dev/null
+++ b/platform/www/inc/Action/Show.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Created by IntelliJ IDEA.
+ * User: andi
+ * Date: 2/10/17
+ * Time: 4:32 PM
+ */
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Show
+ *
+ * The default action of showing a page
+ *
+ * @package dokuwiki\Action
+ */
+class Show extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_READ;
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ global $ID;
+ unlock($ID);
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ html_show();
+ }
+
+}
diff --git a/platform/www/inc/Action/Sitemap.php b/platform/www/inc/Action/Sitemap.php
new file mode 100644
index 0000000..370bcf0
--- /dev/null
+++ b/platform/www/inc/Action/Sitemap.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\FatalException;
+use dokuwiki\Sitemap\Mapper;
+
+/**
+ * Class Sitemap
+ *
+ * Generate an XML sitemap for search engines. Do not confuse with Index
+ *
+ * @package dokuwiki\Action
+ */
+class Sitemap extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_NONE;
+ }
+
+ /**
+ * Handle sitemap delivery
+ *
+ * @author Michael Hamann <michael@content-space.de>
+ * @throws FatalException
+ * @inheritdoc
+ */
+ public function preProcess() {
+ global $conf;
+
+ if($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) {
+ throw new FatalException('Sitemap generation is disabled', 404);
+ }
+
+ $sitemap = Mapper::getFilePath();
+ if(Mapper::sitemapIsCompressed()) {
+ $mime = 'application/x-gzip';
+ } else {
+ $mime = 'application/xml; charset=utf-8';
+ }
+
+ // Check if sitemap file exists, otherwise create it
+ if(!is_readable($sitemap)) {
+ Mapper::generate();
+ }
+
+ if(is_readable($sitemap)) {
+ // Send headers
+ header('Content-Type: ' . $mime);
+ header('Content-Disposition: attachment; filename=' . \dokuwiki\Utf8\PhpString::basename($sitemap));
+
+ http_conditionalRequest(filemtime($sitemap));
+
+ // Send file
+ //use x-sendfile header to pass the delivery to compatible webservers
+ http_sendfile($sitemap);
+
+ readfile($sitemap);
+ exit;
+ }
+
+ throw new FatalException('Could not read the sitemap file - bad permissions?');
+ }
+
+}
diff --git a/platform/www/inc/Action/Source.php b/platform/www/inc/Action/Source.php
new file mode 100644
index 0000000..9b03fe9
--- /dev/null
+++ b/platform/www/inc/Action/Source.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace dokuwiki\Action;
+
+/**
+ * Class Source
+ *
+ * Show the source of a page
+ *
+ * @package dokuwiki\Action
+ */
+class Source extends AbstractAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_READ;
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ global $TEXT;
+ global $INFO;
+ global $ID;
+ global $REV;
+
+ if($INFO['exists']) {
+ $TEXT = rawWiki($ID, $REV);
+ }
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ html_edit();
+ }
+
+}
diff --git a/platform/www/inc/Action/Subscribe.php b/platform/www/inc/Action/Subscribe.php
new file mode 100644
index 0000000..a129a86
--- /dev/null
+++ b/platform/www/inc/Action/Subscribe.php
@@ -0,0 +1,168 @@
+<?php
+
+namespace dokuwiki\Action;
+
+use dokuwiki\Action\Exception\ActionAbort;
+use dokuwiki\Action\Exception\ActionDisabledException;
+use dokuwiki\Subscriptions\SubscriberManager;
+use dokuwiki\Extension\Event;
+
+/**
+ * Class Subscribe
+ *
+ * E-Mail subscription handling
+ *
+ * @package dokuwiki\Action
+ */
+class Subscribe extends AbstractUserAction {
+
+ /** @inheritdoc */
+ public function minimumPermission() {
+ return AUTH_READ;
+ }
+
+ /** @inheritdoc */
+ public function checkPreconditions() {
+ parent::checkPreconditions();
+
+ global $conf;
+ if(isset($conf['subscribers']) && !$conf['subscribers']) throw new ActionDisabledException();
+ }
+
+ /** @inheritdoc */
+ public function preProcess() {
+ try {
+ $this->handleSubscribeData();
+ } catch(ActionAbort $e) {
+ throw $e;
+ } catch(\Exception $e) {
+ msg($e->getMessage(), -1);
+ }
+ }
+
+ /** @inheritdoc */
+ public function tplContent() {
+ tpl_subscribe();
+ }
+
+ /**
+ * Handle page 'subscribe'
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @throws \Exception if (un)subscribing fails
+ * @throws ActionAbort when (un)subscribing worked
+ */
+ protected function handleSubscribeData() {
+ global $lang;
+ global $INFO;
+ global $INPUT;
+
+ // get and preprocess data.
+ $params = array();
+ foreach(array('target', 'style', 'action') as $param) {
+ if($INPUT->has("sub_$param")) {
+ $params[$param] = $INPUT->str("sub_$param");
+ }
+ }
+
+ // any action given? if not just return and show the subscription page
+ if(empty($params['action']) || !checkSecurityToken()) return;
+
+ // Handle POST data, may throw exception.
+ Event::createAndTrigger('ACTION_HANDLE_SUBSCRIBE', $params, array($this, 'handlePostData'));
+
+ $target = $params['target'];
+ $style = $params['style'];
+ $action = $params['action'];
+
+ // Perform action.
+ $subManager = new SubscriberManager();
+ if($action === 'unsubscribe') {
+ $ok = $subManager->remove($target, $INPUT->server->str('REMOTE_USER'), $style);
+ } else {
+ $ok = $subManager->add($target, $INPUT->server->str('REMOTE_USER'), $style);
+ }
+
+ if($ok) {
+ msg(
+ sprintf(
+ $lang["subscr_{$action}_success"], hsc($INFO['userinfo']['name']),
+ prettyprint_id($target)
+ ), 1
+ );
+ throw new ActionAbort('redirect');
+ }
+
+ throw new \Exception(
+ sprintf(
+ $lang["subscr_{$action}_error"],
+ hsc($INFO['userinfo']['name']),
+ prettyprint_id($target)
+ )
+ );
+ }
+
+ /**
+ * Validate POST data
+ *
+ * Validates POST data for a subscribe or unsubscribe request. This is the
+ * default action for the event ACTION_HANDLE_SUBSCRIBE.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param array &$params the parameters: target, style and action
+ * @throws \Exception
+ */
+ public function handlePostData(&$params) {
+ global $INFO;
+ global $lang;
+ global $INPUT;
+
+ // Get and validate parameters.
+ if(!isset($params['target'])) {
+ throw new \Exception('no subscription target given');
+ }
+ $target = $params['target'];
+ $valid_styles = array('every', 'digest');
+ if(substr($target, -1, 1) === ':') {
+ // Allow “list†subscribe style since the target is a namespace.
+ $valid_styles[] = 'list';
+ }
+ $style = valid_input_set(
+ 'style', $valid_styles, $params,
+ 'invalid subscription style given'
+ );
+ $action = valid_input_set(
+ 'action', array('subscribe', 'unsubscribe'),
+ $params, 'invalid subscription action given'
+ );
+
+ // Check other conditions.
+ if($action === 'subscribe') {
+ if($INFO['userinfo']['mail'] === '') {
+ throw new \Exception($lang['subscr_subscribe_noaddress']);
+ }
+ } elseif($action === 'unsubscribe') {
+ $is = false;
+ foreach($INFO['subscribed'] as $subscr) {
+ if($subscr['target'] === $target) {
+ $is = true;
+ }
+ }
+ if($is === false) {
+ throw new \Exception(
+ sprintf(
+ $lang['subscr_not_subscribed'],
+ $INPUT->server->str('REMOTE_USER'),
+ prettyprint_id($target)
+ )
+ );
+ }
+ // subscription_set deletes a subscription if style = null.
+ $style = null;
+ }
+
+ $params = compact('target', 'style', 'action');
+ }
+
+}
diff --git a/platform/www/inc/ActionRouter.php b/platform/www/inc/ActionRouter.php
new file mode 100644
index 0000000..7d8a72a
--- /dev/null
+++ b/platform/www/inc/ActionRouter.php
@@ -0,0 +1,228 @@
+<?php
+
+namespace dokuwiki;
+
+use dokuwiki\Action\AbstractAction;
+use dokuwiki\Action\Exception\ActionDisabledException;
+use dokuwiki\Action\Exception\ActionException;
+use dokuwiki\Action\Exception\FatalException;
+use dokuwiki\Action\Exception\NoActionException;
+use dokuwiki\Action\Plugin;
+
+/**
+ * Class ActionRouter
+ * @package dokuwiki
+ */
+class ActionRouter {
+
+ /** @var AbstractAction */
+ protected $action;
+
+ /** @var ActionRouter */
+ protected static $instance = null;
+
+ /** @var int transition counter */
+ protected $transitions = 0;
+
+ /** maximum loop */
+ const MAX_TRANSITIONS = 5;
+
+ /** @var string[] the actions disabled in the configuration */
+ protected $disabled;
+
+ /**
+ * ActionRouter constructor. Singleton, thus protected!
+ *
+ * Sets up the correct action based on the $ACT global. Writes back
+ * the selected action to $ACT
+ */
+ protected function __construct() {
+ global $ACT;
+ global $conf;
+
+ $this->disabled = explode(',', $conf['disableactions']);
+ $this->disabled = array_map('trim', $this->disabled);
+ $this->transitions = 0;
+
+ $ACT = act_clean($ACT);
+ $this->setupAction($ACT);
+ $ACT = $this->action->getActionName();
+ }
+
+ /**
+ * Get the singleton instance
+ *
+ * @param bool $reinit
+ * @return ActionRouter
+ */
+ public static function getInstance($reinit = false) {
+ if((self::$instance === null) || $reinit) {
+ self::$instance = new ActionRouter();
+ }
+ return self::$instance;
+ }
+
+ /**
+ * Setup the given action
+ *
+ * Instantiates the right class, runs permission checks and pre-processing and
+ * sets $action
+ *
+ * @param string $actionname this is passed as a reference to $ACT, for plugin backward compatibility
+ * @triggers ACTION_ACT_PREPROCESS
+ */
+ protected function setupAction(&$actionname) {
+ $presetup = $actionname;
+
+ try {
+ // give plugins an opportunity to process the actionname
+ $evt = new Extension\Event('ACTION_ACT_PREPROCESS', $actionname);
+ if ($evt->advise_before()) {
+ $this->action = $this->loadAction($actionname);
+ $this->checkAction($this->action);
+ $this->action->preProcess();
+ } else {
+ // event said the action should be kept, assume action plugin will handle it later
+ $this->action = new Plugin($actionname);
+ }
+ $evt->advise_after();
+
+ } catch(ActionException $e) {
+ // we should have gotten a new action
+ $actionname = $e->getNewAction();
+
+ // this one should trigger a user message
+ if(is_a($e, ActionDisabledException::class)) {
+ msg('Action disabled: ' . hsc($presetup), -1);
+ }
+
+ // some actions may request the display of a message
+ if($e->displayToUser()) {
+ msg(hsc($e->getMessage()), -1);
+ }
+
+ // do setup for new action
+ $this->transitionAction($presetup, $actionname);
+
+ } catch(NoActionException $e) {
+ msg('Action unknown: ' . hsc($actionname), -1);
+ $actionname = 'show';
+ $this->transitionAction($presetup, $actionname);
+ } catch(\Exception $e) {
+ $this->handleFatalException($e);
+ }
+ }
+
+ /**
+ * Transitions from one action to another
+ *
+ * Basically just calls setupAction() again but does some checks before.
+ *
+ * @param string $from current action name
+ * @param string $to new action name
+ * @param null|ActionException $e any previous exception that caused the transition
+ */
+ protected function transitionAction($from, $to, $e = null) {
+ $this->transitions++;
+
+ // no infinite recursion
+ if($from == $to) {
+ $this->handleFatalException(new FatalException('Infinite loop in actions', 500, $e));
+ }
+
+ // larger loops will be caught here
+ if($this->transitions >= self::MAX_TRANSITIONS) {
+ $this->handleFatalException(new FatalException('Maximum action transitions reached', 500, $e));
+ }
+
+ // do the recursion
+ $this->setupAction($to);
+ }
+
+ /**
+ * Aborts all processing with a message
+ *
+ * When a FataException instanc is passed, the code is treated as Status code
+ *
+ * @param \Exception|FatalException $e
+ * @throws FatalException during unit testing
+ */
+ protected function handleFatalException(\Exception $e) {
+ if(is_a($e, FatalException::class)) {
+ http_status($e->getCode());
+ } else {
+ http_status(500);
+ }
+ if(defined('DOKU_UNITTEST')) {
+ throw $e;
+ }
+ $msg = 'Something unforeseen has happened: ' . $e->getMessage();
+ nice_die(hsc($msg));
+ }
+
+ /**
+ * Load the given action
+ *
+ * This translates the given name to a class name by uppercasing the first letter.
+ * Underscores translate to camelcase names. For actions with underscores, the different
+ * parts are removed beginning from the end until a matching class is found. The instatiated
+ * Action will always have the full original action set as Name
+ *
+ * Example: 'export_raw' -> ExportRaw then 'export' -> 'Export'
+ *
+ * @param $actionname
+ * @return AbstractAction
+ * @throws NoActionException
+ */
+ public function loadAction($actionname) {
+ $actionname = strtolower($actionname); // FIXME is this needed here? should we run a cleanup somewhere else?
+ $parts = explode('_', $actionname);
+ while(!empty($parts)) {
+ $load = join('_', $parts);
+ $class = 'dokuwiki\\Action\\' . str_replace('_', '', ucwords($load, '_'));
+ if(class_exists($class)) {
+ return new $class($actionname);
+ }
+ array_pop($parts);
+ }
+
+ throw new NoActionException();
+ }
+
+ /**
+ * Execute all the checks to see if this action can be executed
+ *
+ * @param AbstractAction $action
+ * @throws ActionDisabledException
+ * @throws ActionException
+ */
+ public function checkAction(AbstractAction $action) {
+ global $INFO;
+ global $ID;
+
+ if(in_array($action->getActionName(), $this->disabled)) {
+ throw new ActionDisabledException();
+ }
+
+ $action->checkPreconditions();
+
+ if(isset($INFO)) {
+ $perm = $INFO['perm'];
+ } else {
+ $perm = auth_quickaclcheck($ID);
+ }
+
+ if($perm < $action->minimumPermission()) {
+ throw new ActionException('denied');
+ }
+ }
+
+ /**
+ * Returns the action handling the current request
+ *
+ * @return AbstractAction
+ */
+ public function getAction() {
+ return $this->action;
+ }
+}
diff --git a/platform/www/inc/Ajax.php b/platform/www/inc/Ajax.php
new file mode 100644
index 0000000..386d653
--- /dev/null
+++ b/platform/www/inc/Ajax.php
@@ -0,0 +1,438 @@
+<?php
+
+namespace dokuwiki;
+
+/**
+ * Manage all builtin AJAX calls
+ *
+ * @todo The calls should be refactored out to their own proper classes
+ * @package dokuwiki
+ */
+class Ajax {
+
+ /**
+ * Execute the given call
+ *
+ * @param string $call name of the ajax call
+ */
+ public function __construct($call) {
+ $callfn = 'call' . ucfirst($call);
+ if(method_exists($this, $callfn)) {
+ $this->$callfn();
+ } else {
+ $evt = new Extension\Event('AJAX_CALL_UNKNOWN', $call);
+ if($evt->advise_before()) {
+ print "AJAX call '" . hsc($call) . "' unknown!\n";
+ } else {
+ $evt->advise_after();
+ unset($evt);
+ }
+ }
+ }
+
+ /**
+ * Searches for matching pagenames
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function callQsearch() {
+ global $lang;
+ global $INPUT;
+
+ $maxnumbersuggestions = 50;
+
+ $query = $INPUT->post->str('q');
+ if(empty($query)) $query = $INPUT->get->str('q');
+ if(empty($query)) return;
+
+ $query = urldecode($query);
+
+ $data = ft_pageLookup($query, true, useHeading('navigation'));
+
+ if(!count($data)) return;
+
+ print '<strong>' . $lang['quickhits'] . '</strong>';
+ print '<ul>';
+ $counter = 0;
+ foreach($data as $id => $title) {
+ if(useHeading('navigation')) {
+ $name = $title;
+ } else {
+ $ns = getNS($id);
+ if($ns) {
+ $name = noNS($id) . ' (' . $ns . ')';
+ } else {
+ $name = $id;
+ }
+ }
+ echo '<li>' . html_wikilink(':' . $id, $name) . '</li>';
+
+ $counter++;
+ if($counter > $maxnumbersuggestions) {
+ echo '<li>...</li>';
+ break;
+ }
+ }
+ print '</ul>';
+ }
+
+ /**
+ * Support OpenSearch suggestions
+ *
+ * @link http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0
+ * @author Mike Frysinger <vapier@gentoo.org>
+ */
+ protected function callSuggestions() {
+ global $INPUT;
+
+ $query = cleanID($INPUT->post->str('q'));
+ if(empty($query)) $query = cleanID($INPUT->get->str('q'));
+ if(empty($query)) return;
+
+ $data = ft_pageLookup($query);
+ if(!count($data)) return;
+ $data = array_keys($data);
+
+ // limit results to 15 hits
+ $data = array_slice($data, 0, 15);
+ $data = array_map('trim', $data);
+ $data = array_map('noNS', $data);
+ $data = array_unique($data);
+ sort($data);
+
+ /* now construct a json */
+ $suggestions = array(
+ $query, // the original query
+ $data, // some suggestions
+ array(), // no description
+ array() // no urls
+ );
+
+ header('Content-Type: application/x-suggestions+json');
+ print json_encode($suggestions);
+ }
+
+ /**
+ * Refresh a page lock and save draft
+ *
+ * Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function callLock() {
+ global $ID;
+ global $INFO;
+ global $INPUT;
+
+ $ID = cleanID($INPUT->post->str('id'));
+ if(empty($ID)) return;
+
+ $INFO = pageinfo();
+
+ $response = [
+ 'errors' => [],
+ 'lock' => '0',
+ 'draft' => '',
+ ];
+ if(!$INFO['writable']) {
+ $response['errors'][] = 'Permission to write this page has been denied.';
+ echo json_encode($response);
+ return;
+ }
+
+ if(!checklock($ID)) {
+ lock($ID);
+ $response['lock'] = '1';
+ }
+
+ $draft = new Draft($ID, $INFO['client']);
+ if ($draft->saveDraft()) {
+ $response['draft'] = $draft->getDraftMessage();
+ } else {
+ $response['errors'] = array_merge($response['errors'], $draft->getErrors());
+ }
+ echo json_encode($response);
+ }
+
+ /**
+ * Delete a draft
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function callDraftdel() {
+ global $INPUT;
+ $id = cleanID($INPUT->str('id'));
+ if(empty($id)) return;
+
+ $client = $_SERVER['REMOTE_USER'];
+ if(!$client) $client = clientIP(true);
+
+ $cname = getCacheName($client . $id, '.draft');
+ @unlink($cname);
+ }
+
+ /**
+ * Return subnamespaces for the Mediamanager
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function callMedians() {
+ global $conf;
+ global $INPUT;
+
+ // wanted namespace
+ $ns = cleanID($INPUT->post->str('ns'));
+ $dir = utf8_encodeFN(str_replace(':', '/', $ns));
+
+ $lvl = count(explode(':', $ns));
+
+ $data = array();
+ search($data, $conf['mediadir'], 'search_index', array('nofiles' => true), $dir);
+ foreach(array_keys($data) as $item) {
+ $data[$item]['level'] = $lvl + 1;
+ }
+ echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li');
+ }
+
+ /**
+ * Return list of files for the Mediamanager
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function callMedialist() {
+ global $NS;
+ global $INPUT;
+
+ $NS = cleanID($INPUT->post->str('ns'));
+ $sort = $INPUT->post->bool('recent') ? 'date' : 'natural';
+ if($INPUT->post->str('do') == 'media') {
+ tpl_mediaFileList();
+ } else {
+ tpl_mediaContent(true, $sort);
+ }
+ }
+
+ /**
+ * Return the content of the right column
+ * (image details) for the Mediamanager
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ protected function callMediadetails() {
+ global $IMG, $JUMPTO, $REV, $fullscreen, $INPUT;
+ $fullscreen = true;
+ require_once(DOKU_INC . 'lib/exe/mediamanager.php');
+
+ $image = '';
+ if($INPUT->has('image')) $image = cleanID($INPUT->str('image'));
+ if(isset($IMG)) $image = $IMG;
+ if(isset($JUMPTO)) $image = $JUMPTO;
+ $rev = false;
+ if(isset($REV) && !$JUMPTO) $rev = $REV;
+
+ html_msgarea();
+ tpl_mediaFileDetails($image, $rev);
+ }
+
+ /**
+ * Returns image diff representation for mediamanager
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ protected function callMediadiff() {
+ global $NS;
+ global $INPUT;
+
+ $image = '';
+ if($INPUT->has('image')) $image = cleanID($INPUT->str('image'));
+ $NS = getNS($image);
+ $auth = auth_quickaclcheck("$NS:*");
+ media_diff($image, $NS, $auth, true);
+ }
+
+ /**
+ * Manages file uploads
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ protected function callMediaupload() {
+ global $NS, $MSG, $INPUT;
+
+ $id = '';
+ if(isset($_FILES['qqfile']['tmp_name'])) {
+ $id = $INPUT->post->str('mediaid', $_FILES['qqfile']['name']);
+ } elseif($INPUT->get->has('qqfile')) {
+ $id = $INPUT->get->str('qqfile');
+ }
+
+ $id = cleanID($id);
+
+ $NS = $INPUT->str('ns');
+ $ns = $NS . ':' . getNS($id);
+
+ $AUTH = auth_quickaclcheck("$ns:*");
+ if($AUTH >= AUTH_UPLOAD) {
+ io_createNamespace("$ns:xxx", 'media');
+ }
+
+ if(isset($_FILES['qqfile']['error']) && $_FILES['qqfile']['error']) unset($_FILES['qqfile']);
+
+ $res = false;
+ if(isset($_FILES['qqfile']['tmp_name'])) $res = media_upload($NS, $AUTH, $_FILES['qqfile']);
+ if($INPUT->get->has('qqfile')) $res = media_upload_xhr($NS, $AUTH);
+
+ if($res) {
+ $result = array(
+ 'success' => true,
+ 'link' => media_managerURL(array('ns' => $ns, 'image' => $NS . ':' . $id), '&'),
+ 'id' => $NS . ':' . $id,
+ 'ns' => $NS
+ );
+ } else {
+ $error = '';
+ if(isset($MSG)) {
+ foreach($MSG as $msg) {
+ $error .= $msg['msg'];
+ }
+ }
+ $result = array(
+ 'error' => $error,
+ 'ns' => $NS
+ );
+ }
+
+ header('Content-Type: application/json');
+ echo json_encode($result);
+ }
+
+ /**
+ * Return sub index for index view
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function callIndex() {
+ global $conf;
+ global $INPUT;
+
+ // wanted namespace
+ $ns = cleanID($INPUT->post->str('idx'));
+ $dir = utf8_encodeFN(str_replace(':', '/', $ns));
+
+ $lvl = count(explode(':', $ns));
+
+ $data = array();
+ search($data, $conf['datadir'], 'search_index', array('ns' => $ns), $dir);
+ foreach(array_keys($data) as $item) {
+ $data[$item]['level'] = $lvl + 1;
+ }
+ echo html_buildlist($data, 'idx', 'html_list_index', 'html_li_index');
+ }
+
+ /**
+ * List matching namespaces and pages for the link wizard
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+ protected function callLinkwiz() {
+ global $conf;
+ global $lang;
+ global $INPUT;
+
+ $q = ltrim(trim($INPUT->post->str('q')), ':');
+ $id = noNS($q);
+ $ns = getNS($q);
+
+ $ns = cleanID($ns);
+ $id = cleanID($id);
+
+ $nsd = utf8_encodeFN(str_replace(':', '/', $ns));
+
+ $data = array();
+ if($q !== '' && $ns === '') {
+
+ // use index to lookup matching pages
+ $pages = ft_pageLookup($id, true);
+
+ // result contains matches in pages and namespaces
+ // we now extract the matching namespaces to show
+ // them seperately
+ $dirs = array();
+
+ foreach($pages as $pid => $title) {
+ if(strpos(noNS($pid), $id) === false) {
+ // match was in the namespace
+ $dirs[getNS($pid)] = 1; // assoc array avoids dupes
+ } else {
+ // it is a matching page, add it to the result
+ $data[] = array(
+ 'id' => $pid,
+ 'title' => $title,
+ 'type' => 'f',
+ );
+ }
+ unset($pages[$pid]);
+ }
+ foreach($dirs as $dir => $junk) {
+ $data[] = array(
+ 'id' => $dir,
+ 'type' => 'd',
+ );
+ }
+
+ } else {
+
+ $opts = array(
+ 'depth' => 1,
+ 'listfiles' => true,
+ 'listdirs' => true,
+ 'pagesonly' => true,
+ 'firsthead' => true,
+ 'sneakyacl' => $conf['sneaky_index'],
+ );
+ if($id) $opts['filematch'] = '^.*\/' . $id;
+ if($id) $opts['dirmatch'] = '^.*\/' . $id;
+ search($data, $conf['datadir'], 'search_universal', $opts, $nsd);
+
+ // add back to upper
+ if($ns) {
+ array_unshift(
+ $data, array(
+ 'id' => getNS($ns),
+ 'type' => 'u',
+ )
+ );
+ }
+ }
+
+ // fixme sort results in a useful way ?
+
+ if(!count($data)) {
+ echo $lang['nothingfound'];
+ exit;
+ }
+
+ // output the found data
+ $even = 1;
+ foreach($data as $item) {
+ $even *= -1; //zebra
+
+ if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id'] !== '') $item['id'] .= ':';
+ $link = wl($item['id']);
+
+ echo '<div class="' . (($even > 0) ? 'even' : 'odd') . ' type_' . $item['type'] . '">';
+
+ if($item['type'] == 'u') {
+ $name = $lang['upperns'];
+ } else {
+ $name = hsc($item['id']);
+ }
+
+ echo '<a href="' . $link . '" title="' . hsc($item['id']) . '" class="wikilink1">' . $name . '</a>';
+
+ if(!blank($item['title'])) {
+ echo '<span>' . hsc($item['title']) . '</span>';
+ }
+ echo '</div>';
+ }
+
+ }
+
+}
diff --git a/platform/www/inc/Cache/Cache.php b/platform/www/inc/Cache/Cache.php
new file mode 100644
index 0000000..af82e6b
--- /dev/null
+++ b/platform/www/inc/Cache/Cache.php
@@ -0,0 +1,240 @@
+<?php
+
+namespace dokuwiki\Cache;
+
+use dokuwiki\Debug\PropertyDeprecationHelper;
+use dokuwiki\Extension\Event;
+
+/**
+ * Generic handling of caching
+ */
+class Cache
+{
+ use PropertyDeprecationHelper;
+
+ public $key = ''; // primary identifier for this item
+ public $ext = ''; // file ext for cache data, secondary identifier for this item
+ public $cache = ''; // cache file name
+ public $depends = array(); // array containing cache dependency information,
+ // used by makeDefaultCacheDecision to determine cache validity
+
+ // phpcs:disable
+ /**
+ * @deprecated since 2019-02-02 use the respective getters instead!
+ */
+ protected $_event = ''; // event to be triggered during useCache
+ protected $_time;
+ protected $_nocache = false; // if set to true, cache will not be used or stored
+ // phpcs:enable
+
+ /**
+ * @param string $key primary identifier
+ * @param string $ext file extension
+ */
+ public function __construct($key, $ext)
+ {
+ $this->key = $key;
+ $this->ext = $ext;
+ $this->cache = getCacheName($key, $ext);
+
+ /**
+ * @deprecated since 2019-02-02 use the respective getters instead!
+ */
+ $this->deprecatePublicProperty('_event');
+ $this->deprecatePublicProperty('_time');
+ $this->deprecatePublicProperty('_nocache');
+ }
+
+ public function getTime()
+ {
+ return $this->_time;
+ }
+
+ public function getEvent()
+ {
+ return $this->_event;
+ }
+
+ public function setEvent($event)
+ {
+ $this->_event = $event;
+ }
+
+ /**
+ * public method to determine whether the cache can be used
+ *
+ * to assist in centralisation of event triggering and calculation of cache statistics,
+ * don't override this function override makeDefaultCacheDecision()
+ *
+ * @param array $depends array of cache dependencies, support dependecies:
+ * 'age' => max age of the cache in seconds
+ * 'files' => cache must be younger than mtime of each file
+ * (nb. dependency passes if file doesn't exist)
+ *
+ * @return bool true if cache can be used, false otherwise
+ */
+ public function useCache($depends = array())
+ {
+ $this->depends = $depends;
+ $this->addDependencies();
+
+ if ($this->getEvent()) {
+ return $this->stats(
+ Event::createAndTrigger(
+ $this->getEvent(),
+ $this,
+ array($this, 'makeDefaultCacheDecision')
+ )
+ );
+ }
+
+ return $this->stats($this->makeDefaultCacheDecision());
+ }
+
+ /**
+ * internal method containing cache use decision logic
+ *
+ * this function processes the following keys in the depends array
+ * purge - force a purge on any non empty value
+ * age - expire cache if older than age (seconds)
+ * files - expire cache if any file in this array was updated more recently than the cache
+ *
+ * Note that this function needs to be public as it is used as callback for the event handler
+ *
+ * can be overridden
+ *
+ * @internal This method may only be called by the event handler! Call \dokuwiki\Cache\Cache::useCache instead!
+ *
+ * @return bool see useCache()
+ */
+ public function makeDefaultCacheDecision()
+ {
+ if ($this->_nocache) {
+ return false;
+ } // caching turned off
+ if (!empty($this->depends['purge'])) {
+ return false;
+ } // purge requested?
+ if (!($this->_time = @filemtime($this->cache))) {
+ return false;
+ } // cache exists?
+
+ // cache too old?
+ if (!empty($this->depends['age']) && ((time() - $this->_time) > $this->depends['age'])) {
+ return false;
+ }
+
+ if (!empty($this->depends['files'])) {
+ foreach ($this->depends['files'] as $file) {
+ if ($this->_time <= @filemtime($file)) {
+ return false;
+ } // cache older than files it depends on?
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * add dependencies to the depends array
+ *
+ * this method should only add dependencies,
+ * it should not remove any existing dependencies and
+ * it should only overwrite a dependency when the new value is more stringent than the old
+ */
+ protected function addDependencies()
+ {
+ global $INPUT;
+ if ($INPUT->has('purge')) {
+ $this->depends['purge'] = true;
+ } // purge requested
+ }
+
+ /**
+ * retrieve the cached data
+ *
+ * @param bool $clean true to clean line endings, false to leave line endings alone
+ * @return string cache contents
+ */
+ public function retrieveCache($clean = true)
+ {
+ return io_readFile($this->cache, $clean);
+ }
+
+ /**
+ * cache $data
+ *
+ * @param string $data the data to be cached
+ * @return bool true on success, false otherwise
+ */
+ public function storeCache($data)
+ {
+ if ($this->_nocache) {
+ return false;
+ }
+
+ return io_saveFile($this->cache, $data);
+ }
+
+ /**
+ * remove any cached data associated with this cache instance
+ */
+ public function removeCache()
+ {
+ @unlink($this->cache);
+ }
+
+ /**
+ * Record cache hits statistics.
+ * (Only when debugging allowed, to reduce overhead.)
+ *
+ * @param bool $success result of this cache use attempt
+ * @return bool pass-thru $success value
+ */
+ protected function stats($success)
+ {
+ global $conf;
+ static $stats = null;
+ static $file;
+
+ if (!$conf['allowdebug']) {
+ return $success;
+ }
+
+ if (is_null($stats)) {
+ $file = $conf['cachedir'] . '/cache_stats.txt';
+ $lines = explode("\n", io_readFile($file));
+
+ foreach ($lines as $line) {
+ $i = strpos($line, ',');
+ $stats[substr($line, 0, $i)] = $line;
+ }
+ }
+
+ if (isset($stats[$this->ext])) {
+ list($ext, $count, $hits) = explode(',', $stats[$this->ext]);
+ } else {
+ $ext = $this->ext;
+ $count = 0;
+ $hits = 0;
+ }
+
+ $count++;
+ if ($success) {
+ $hits++;
+ }
+ $stats[$this->ext] = "$ext,$count,$hits";
+
+ io_saveFile($file, join("\n", $stats));
+
+ return $success;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isNoCache()
+ {
+ return $this->_nocache;
+ }
+}
diff --git a/platform/www/inc/Cache/CacheInstructions.php b/platform/www/inc/Cache/CacheInstructions.php
new file mode 100644
index 0000000..acd02ab
--- /dev/null
+++ b/platform/www/inc/Cache/CacheInstructions.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace dokuwiki\Cache;
+
+/**
+ * Caching of parser instructions
+ */
+class CacheInstructions extends \dokuwiki\Cache\CacheParser
+{
+
+ /**
+ * @param string $id page id
+ * @param string $file source file for cache
+ */
+ public function __construct($id, $file)
+ {
+ parent::__construct($id, $file, 'i');
+ }
+
+ /**
+ * retrieve the cached data
+ *
+ * @param bool $clean true to clean line endings, false to leave line endings alone
+ * @return array cache contents
+ */
+ public function retrieveCache($clean = true)
+ {
+ $contents = io_readFile($this->cache, false);
+ return !empty($contents) ? unserialize($contents) : array();
+ }
+
+ /**
+ * cache $instructions
+ *
+ * @param array $instructions the instruction to be cached
+ * @return bool true on success, false otherwise
+ */
+ public function storeCache($instructions)
+ {
+ if ($this->_nocache) {
+ return false;
+ }
+
+ return io_saveFile($this->cache, serialize($instructions));
+ }
+}
diff --git a/platform/www/inc/Cache/CacheParser.php b/platform/www/inc/Cache/CacheParser.php
new file mode 100644
index 0000000..ed476f4
--- /dev/null
+++ b/platform/www/inc/Cache/CacheParser.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace dokuwiki\Cache;
+
+/**
+ * Parser caching
+ */
+class CacheParser extends Cache
+{
+
+ public $file = ''; // source file for cache
+ public $mode = ''; // input mode (represents the processing the input file will undergo)
+ public $page = '';
+
+ /**
+ *
+ * @param string $id page id
+ * @param string $file source file for cache
+ * @param string $mode input mode
+ */
+ public function __construct($id, $file, $mode)
+ {
+ if ($id) {
+ $this->page = $id;
+ }
+ $this->file = $file;
+ $this->mode = $mode;
+
+ $this->setEvent('PARSER_CACHE_USE');
+ parent::__construct($file . $_SERVER['HTTP_HOST'] . $_SERVER['SERVER_PORT'], '.' . $mode);
+ }
+
+ /**
+ * method contains cache use decision logic
+ *
+ * @return bool see useCache()
+ */
+ public function makeDefaultCacheDecision()
+ {
+
+ if (!file_exists($this->file)) {
+ return false;
+ } // source exists?
+ return parent::makeDefaultCacheDecision();
+ }
+
+ protected function addDependencies()
+ {
+
+ // parser cache file dependencies ...
+ $files = array(
+ $this->file, // ... source
+ DOKU_INC . 'inc/parser/Parser.php', // ... parser
+ DOKU_INC . 'inc/parser/handler.php', // ... handler
+ );
+ $files = array_merge($files, getConfigFiles('main')); // ... wiki settings
+
+ $this->depends['files'] = !empty($this->depends['files']) ?
+ array_merge($files, $this->depends['files']) :
+ $files;
+ parent::addDependencies();
+ }
+
+}
diff --git a/platform/www/inc/Cache/CacheRenderer.php b/platform/www/inc/Cache/CacheRenderer.php
new file mode 100644
index 0000000..e8a28c3
--- /dev/null
+++ b/platform/www/inc/Cache/CacheRenderer.php
@@ -0,0 +1,94 @@
+<?php
+
+namespace dokuwiki\Cache;
+
+/**
+ * Caching of data of renderer
+ */
+class CacheRenderer extends CacheParser
+{
+
+ /**
+ * method contains cache use decision logic
+ *
+ * @return bool see useCache()
+ */
+ public function makeDefaultCacheDecision()
+ {
+ global $conf;
+
+ if (!parent::makeDefaultCacheDecision()) {
+ return false;
+ }
+
+ if (!isset($this->page)) {
+ return true;
+ }
+
+ // meta cache older than file it depends on?
+ if ($this->_time < @filemtime(metaFN($this->page, '.meta'))) {
+ return false;
+ }
+
+ // check current link existence is consistent with cache version
+ // first check the purgefile
+ // - if the cache is more recent than the purgefile we know no links can have been updated
+ if ($this->_time >= @filemtime($conf['cachedir'] . '/purgefile')) {
+ return true;
+ }
+
+ // for wiki pages, check metadata dependencies
+ $metadata = p_get_metadata($this->page);
+
+ if (!isset($metadata['relation']['references']) ||
+ empty($metadata['relation']['references'])) {
+ return true;
+ }
+
+ foreach ($metadata['relation']['references'] as $id => $exists) {
+ if ($exists != page_exists($id, '', false)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ protected function addDependencies()
+ {
+ global $conf;
+
+ // default renderer cache file 'age' is dependent on 'cachetime' setting, two special values:
+ // -1 : do not cache (should not be overridden)
+ // 0 : cache never expires (can be overridden) - no need to set depends['age']
+ if ($conf['cachetime'] == -1) {
+ $this->_nocache = true;
+ return;
+ } elseif ($conf['cachetime'] > 0) {
+ $this->depends['age'] = isset($this->depends['age']) ?
+ min($this->depends['age'], $conf['cachetime']) : $conf['cachetime'];
+ }
+
+ // renderer cache file dependencies ...
+ $files = array(
+ DOKU_INC . 'inc/parser/' . $this->mode . '.php', // ... the renderer
+ );
+
+ // page implies metadata and possibly some other dependencies
+ if (isset($this->page)) {
+
+ // for xhtml this will render the metadata if needed
+ $valid = p_get_metadata($this->page, 'date valid');
+ if (!empty($valid['age'])) {
+ $this->depends['age'] = isset($this->depends['age']) ?
+ min($this->depends['age'], $valid['age']) : $valid['age'];
+ }
+ }
+
+ $this->depends['files'] = !empty($this->depends['files']) ?
+ array_merge($files, $this->depends['files']) :
+ $files;
+
+ parent::addDependencies();
+ }
+}
diff --git a/platform/www/inc/ChangeLog/ChangeLog.php b/platform/www/inc/ChangeLog/ChangeLog.php
new file mode 100644
index 0000000..16b5cc2
--- /dev/null
+++ b/platform/www/inc/ChangeLog/ChangeLog.php
@@ -0,0 +1,666 @@
+<?php
+
+namespace dokuwiki\ChangeLog;
+
+/**
+ * methods for handling of changelog of pages or media files
+ */
+abstract class ChangeLog
+{
+
+ /** @var string */
+ protected $id;
+ /** @var int */
+ protected $chunk_size;
+ /** @var array */
+ protected $cache;
+
+ /**
+ * Constructor
+ *
+ * @param string $id page id
+ * @param int $chunk_size maximum block size read from file
+ */
+ public function __construct($id, $chunk_size = 8192)
+ {
+ global $cache_revinfo;
+
+ $this->cache =& $cache_revinfo;
+ if (!isset($this->cache[$id])) {
+ $this->cache[$id] = array();
+ }
+
+ $this->id = $id;
+ $this->setChunkSize($chunk_size);
+
+ }
+
+ /**
+ * Set chunk size for file reading
+ * Chunk size zero let read whole file at once
+ *
+ * @param int $chunk_size maximum block size read from file
+ */
+ public function setChunkSize($chunk_size)
+ {
+ if (!is_numeric($chunk_size)) $chunk_size = 0;
+
+ $this->chunk_size = (int)max($chunk_size, 0);
+ }
+
+ /**
+ * Returns path to changelog
+ *
+ * @return string path to file
+ */
+ abstract protected function getChangelogFilename();
+
+ /**
+ * Returns path to current page/media
+ *
+ * @return string path to file
+ */
+ abstract protected function getFilename();
+
+ /**
+ * Get the changelog information for a specific page id and revision (timestamp)
+ *
+ * Adjacent changelog lines are optimistically parsed and cached to speed up
+ * consecutive calls to getRevisionInfo. For large changelog files, only the chunk
+ * containing the requested changelog line is read.
+ *
+ * @param int $rev revision timestamp
+ * @return bool|array false or array with entries:
+ * - date: unix timestamp
+ * - ip: IPv4 address (127.0.0.1)
+ * - type: log line type
+ * - id: page id
+ * - user: user name
+ * - sum: edit summary (or action reason)
+ * - extra: extra data (varies by line type)
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ public function getRevisionInfo($rev)
+ {
+ $rev = max($rev, 0);
+
+ // check if it's already in the memory cache
+ if (isset($this->cache[$this->id]) && isset($this->cache[$this->id][$rev])) {
+ return $this->cache[$this->id][$rev];
+ }
+
+ //read lines from changelog
+ list($fp, $lines) = $this->readloglines($rev);
+ if ($fp) {
+ fclose($fp);
+ }
+ if (empty($lines)) return false;
+
+ // parse and cache changelog lines
+ foreach ($lines as $value) {
+ $tmp = parseChangelogLine($value);
+ if ($tmp !== false) {
+ $this->cache[$this->id][$tmp['date']] = $tmp;
+ }
+ }
+ if (!isset($this->cache[$this->id][$rev])) {
+ return false;
+ }
+ return $this->cache[$this->id][$rev];
+ }
+
+ /**
+ * Return a list of page revisions numbers
+ *
+ * Does not guarantee that the revision exists in the attic,
+ * only that a line with the date exists in the changelog.
+ * By default the current revision is skipped.
+ *
+ * The current revision is automatically skipped when the page exists.
+ * See $INFO['meta']['last_change'] for the current revision.
+ * A negative $first let read the current revision too.
+ *
+ * For efficiency, the log lines are parsed and cached for later
+ * calls to getRevisionInfo. Large changelog files are read
+ * backwards in chunks until the requested number of changelog
+ * lines are recieved.
+ *
+ * @param int $first skip the first n changelog lines
+ * @param int $num number of revisions to return
+ * @return array with the revision timestamps
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ public function getRevisions($first, $num)
+ {
+ $revs = array();
+ $lines = array();
+ $count = 0;
+
+ $num = max($num, 0);
+ if ($num == 0) {
+ return $revs;
+ }
+
+ if ($first < 0) {
+ $first = 0;
+ } else {
+ if (file_exists($this->getFilename())) {
+ // skip current revision if the page exists
+ $first = max($first + 1, 0);
+ }
+ }
+
+ $file = $this->getChangelogFilename();
+
+ if (!file_exists($file)) {
+ return $revs;
+ }
+ if (filesize($file) < $this->chunk_size || $this->chunk_size == 0) {
+ // read whole file
+ $lines = file($file);
+ if ($lines === false) {
+ return $revs;
+ }
+ } else {
+ // read chunks backwards
+ $fp = fopen($file, 'rb'); // "file pointer"
+ if ($fp === false) {
+ return $revs;
+ }
+ fseek($fp, 0, SEEK_END);
+ $tail = ftell($fp);
+
+ // chunk backwards
+ $finger = max($tail - $this->chunk_size, 0);
+ while ($count < $num + $first) {
+ $nl = $this->getNewlinepointer($fp, $finger);
+
+ // was the chunk big enough? if not, take another bite
+ if ($nl > 0 && $tail <= $nl) {
+ $finger = max($finger - $this->chunk_size, 0);
+ continue;
+ } else {
+ $finger = $nl;
+ }
+
+ // read chunk
+ $chunk = '';
+ $read_size = max($tail - $finger, 0); // found chunk size
+ $got = 0;
+ while ($got < $read_size && !feof($fp)) {
+ $tmp = @fread($fp, max(min($this->chunk_size, $read_size - $got), 0));
+ if ($tmp === false) {
+ break;
+ } //error state
+ $got += strlen($tmp);
+ $chunk .= $tmp;
+ }
+ $tmp = explode("\n", $chunk);
+ array_pop($tmp); // remove trailing newline
+
+ // combine with previous chunk
+ $count += count($tmp);
+ $lines = array_merge($tmp, $lines);
+
+ // next chunk
+ if ($finger == 0) {
+ break;
+ } else { // already read all the lines
+ $tail = $finger;
+ $finger = max($tail - $this->chunk_size, 0);
+ }
+ }
+ fclose($fp);
+ }
+
+ // skip parsing extra lines
+ $num = max(min(count($lines) - $first, $num), 0);
+ if ($first > 0 && $num > 0) {
+ $lines = array_slice($lines, max(count($lines) - $first - $num, 0), $num);
+ } else {
+ if ($first > 0 && $num == 0) {
+ $lines = array_slice($lines, 0, max(count($lines) - $first, 0));
+ } elseif ($first == 0 && $num > 0) {
+ $lines = array_slice($lines, max(count($lines) - $num, 0));
+ }
+ }
+
+ // handle lines in reverse order
+ for ($i = count($lines) - 1; $i >= 0; $i--) {
+ $tmp = parseChangelogLine($lines[$i]);
+ if ($tmp !== false) {
+ $this->cache[$this->id][$tmp['date']] = $tmp;
+ $revs[] = $tmp['date'];
+ }
+ }
+
+ return $revs;
+ }
+
+ /**
+ * Get the nth revision left or right handside for a specific page id and revision (timestamp)
+ *
+ * For large changelog files, only the chunk containing the
+ * reference revision $rev is read and sometimes a next chunck.
+ *
+ * Adjacent changelog lines are optimistically parsed and cached to speed up
+ * consecutive calls to getRevisionInfo.
+ *
+ * @param int $rev revision timestamp used as startdate (doesn't need to be revisionnumber)
+ * @param int $direction give position of returned revision with respect to $rev; positive=next, negative=prev
+ * @return bool|int
+ * timestamp of the requested revision
+ * otherwise false
+ */
+ public function getRelativeRevision($rev, $direction)
+ {
+ $rev = max($rev, 0);
+ $direction = (int)$direction;
+
+ //no direction given or last rev, so no follow-up
+ if (!$direction || ($direction > 0 && $this->isCurrentRevision($rev))) {
+ return false;
+ }
+
+ //get lines from changelog
+ list($fp, $lines, $head, $tail, $eof) = $this->readloglines($rev);
+ if (empty($lines)) return false;
+
+ // look for revisions later/earlier then $rev, when founded count till the wanted revision is reached
+ // also parse and cache changelog lines for getRevisionInfo().
+ $revcounter = 0;
+ $relativerev = false;
+ $checkotherchunck = true; //always runs once
+ while (!$relativerev && $checkotherchunck) {
+ $tmp = array();
+ //parse in normal or reverse order
+ $count = count($lines);
+ if ($direction > 0) {
+ $start = 0;
+ $step = 1;
+ } else {
+ $start = $count - 1;
+ $step = -1;
+ }
+ for ($i = $start; $i >= 0 && $i < $count; $i = $i + $step) {
+ $tmp = parseChangelogLine($lines[$i]);
+ if ($tmp !== false) {
+ $this->cache[$this->id][$tmp['date']] = $tmp;
+ //look for revs older/earlier then reference $rev and select $direction-th one
+ if (($direction > 0 && $tmp['date'] > $rev) || ($direction < 0 && $tmp['date'] < $rev)) {
+ $revcounter++;
+ if ($revcounter == abs($direction)) {
+ $relativerev = $tmp['date'];
+ }
+ }
+ }
+ }
+
+ //true when $rev is found, but not the wanted follow-up.
+ $checkotherchunck = $fp
+ && ($tmp['date'] == $rev || ($revcounter > 0 && !$relativerev))
+ && !(($tail == $eof && $direction > 0) || ($head == 0 && $direction < 0));
+
+ if ($checkotherchunck) {
+ list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, $direction);
+
+ if (empty($lines)) break;
+ }
+ }
+ if ($fp) {
+ fclose($fp);
+ }
+
+ return $relativerev;
+ }
+
+ /**
+ * Returns revisions around rev1 and rev2
+ * When available it returns $max entries for each revision
+ *
+ * @param int $rev1 oldest revision timestamp
+ * @param int $rev2 newest revision timestamp (0 looks up last revision)
+ * @param int $max maximum number of revisions returned
+ * @return array with two arrays with revisions surrounding rev1 respectively rev2
+ */
+ public function getRevisionsAround($rev1, $rev2, $max = 50)
+ {
+ $max = floor(abs($max) / 2) * 2 + 1;
+ $rev1 = max($rev1, 0);
+ $rev2 = max($rev2, 0);
+
+ if ($rev2) {
+ if ($rev2 < $rev1) {
+ $rev = $rev2;
+ $rev2 = $rev1;
+ $rev1 = $rev;
+ }
+ } else {
+ //empty right side means a removed page. Look up last revision.
+ $revs = $this->getRevisions(-1, 1);
+ $rev2 = $revs[0];
+ }
+ //collect revisions around rev2
+ list($revs2, $allrevs, $fp, $lines, $head, $tail) = $this->retrieveRevisionsAround($rev2, $max);
+
+ if (empty($revs2)) return array(array(), array());
+
+ //collect revisions around rev1
+ $index = array_search($rev1, $allrevs);
+ if ($index === false) {
+ //no overlapping revisions
+ list($revs1, , , , ,) = $this->retrieveRevisionsAround($rev1, $max);
+ if (empty($revs1)) $revs1 = array();
+ } else {
+ //revisions overlaps, reuse revisions around rev2
+ $revs1 = $allrevs;
+ while ($head > 0) {
+ for ($i = count($lines) - 1; $i >= 0; $i--) {
+ $tmp = parseChangelogLine($lines[$i]);
+ if ($tmp !== false) {
+ $this->cache[$this->id][$tmp['date']] = $tmp;
+ $revs1[] = $tmp['date'];
+ $index++;
+
+ if ($index > floor($max / 2)) break 2;
+ }
+ }
+
+ list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, -1);
+ }
+ sort($revs1);
+ //return wanted selection
+ $revs1 = array_slice($revs1, max($index - floor($max / 2), 0), $max);
+ }
+
+ return array(array_reverse($revs1), array_reverse($revs2));
+ }
+
+
+ /**
+ * Checks if the ID has old revisons
+ * @return boolean
+ */
+ public function hasRevisions() {
+ $file = $this->getChangelogFilename();
+ return file_exists($file);
+ }
+
+ /**
+ * Returns lines from changelog.
+ * If file larger than $chuncksize, only chunck is read that could contain $rev.
+ *
+ * @param int $rev revision timestamp
+ * @return array|false
+ * if success returns array(fp, array(changeloglines), $head, $tail, $eof)
+ * where fp only defined for chuck reading, needs closing.
+ * otherwise false
+ */
+ protected function readloglines($rev)
+ {
+ $file = $this->getChangelogFilename();
+
+ if (!file_exists($file)) {
+ return false;
+ }
+
+ $fp = null;
+ $head = 0;
+ $tail = 0;
+ $eof = 0;
+
+ if (filesize($file) < $this->chunk_size || $this->chunk_size == 0) {
+ // read whole file
+ $lines = file($file);
+ if ($lines === false) {
+ return false;
+ }
+ } else {
+ // read by chunk
+ $fp = fopen($file, 'rb'); // "file pointer"
+ if ($fp === false) {
+ return false;
+ }
+ $head = 0;
+ fseek($fp, 0, SEEK_END);
+ $eof = ftell($fp);
+ $tail = $eof;
+
+ // find chunk
+ while ($tail - $head > $this->chunk_size) {
+ $finger = $head + floor(($tail - $head) / 2.0);
+ $finger = $this->getNewlinepointer($fp, $finger);
+ $tmp = fgets($fp);
+ if ($finger == $head || $finger == $tail) {
+ break;
+ }
+ $tmp = parseChangelogLine($tmp);
+ $finger_rev = $tmp['date'];
+
+ if ($finger_rev > $rev) {
+ $tail = $finger;
+ } else {
+ $head = $finger;
+ }
+ }
+
+ if ($tail - $head < 1) {
+ // cound not find chunk, assume requested rev is missing
+ fclose($fp);
+ return false;
+ }
+
+ $lines = $this->readChunk($fp, $head, $tail);
+ }
+ return array(
+ $fp,
+ $lines,
+ $head,
+ $tail,
+ $eof,
+ );
+ }
+
+ /**
+ * Read chunk and return array with lines of given chunck.
+ * Has no check if $head and $tail are really at a new line
+ *
+ * @param resource $fp resource filepointer
+ * @param int $head start point chunck
+ * @param int $tail end point chunck
+ * @return array lines read from chunck
+ */
+ protected function readChunk($fp, $head, $tail)
+ {
+ $chunk = '';
+ $chunk_size = max($tail - $head, 0); // found chunk size
+ $got = 0;
+ fseek($fp, $head);
+ while ($got < $chunk_size && !feof($fp)) {
+ $tmp = @fread($fp, max(min($this->chunk_size, $chunk_size - $got), 0));
+ if ($tmp === false) { //error state
+ break;
+ }
+ $got += strlen($tmp);
+ $chunk .= $tmp;
+ }
+ $lines = explode("\n", $chunk);
+ array_pop($lines); // remove trailing newline
+ return $lines;
+ }
+
+ /**
+ * Set pointer to first new line after $finger and return its position
+ *
+ * @param resource $fp filepointer
+ * @param int $finger a pointer
+ * @return int pointer
+ */
+ protected function getNewlinepointer($fp, $finger)
+ {
+ fseek($fp, $finger);
+ $nl = $finger;
+ if ($finger > 0) {
+ fgets($fp); // slip the finger forward to a new line
+ $nl = ftell($fp);
+ }
+ return $nl;
+ }
+
+ /**
+ * Check whether given revision is the current page
+ *
+ * @param int $rev timestamp of current page
+ * @return bool true if $rev is current revision, otherwise false
+ */
+ public function isCurrentRevision($rev)
+ {
+ return $rev == @filemtime($this->getFilename());
+ }
+
+ /**
+ * Return an existing revision for a specific date which is
+ * the current one or younger or equal then the date
+ *
+ * @param number $date_at timestamp
+ * @return string revision ('' for current)
+ */
+ public function getLastRevisionAt($date_at)
+ {
+ //requested date_at(timestamp) younger or equal then modified_time($this->id) => load current
+ if (file_exists($this->getFilename()) && $date_at >= @filemtime($this->getFilename())) {
+ return '';
+ } else {
+ if ($rev = $this->getRelativeRevision($date_at + 1, -1)) { //+1 to get also the requested date revision
+ return $rev;
+ } else {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Returns the next lines of the changelog of the chunck before head or after tail
+ *
+ * @param resource $fp filepointer
+ * @param int $head position head of last chunk
+ * @param int $tail position tail of last chunk
+ * @param int $direction positive forward, negative backward
+ * @return array with entries:
+ * - $lines: changelog lines of readed chunk
+ * - $head: head of chunk
+ * - $tail: tail of chunk
+ */
+ protected function readAdjacentChunk($fp, $head, $tail, $direction)
+ {
+ if (!$fp) return array(array(), $head, $tail);
+
+ if ($direction > 0) {
+ //read forward
+ $head = $tail;
+ $tail = $head + floor($this->chunk_size * (2 / 3));
+ $tail = $this->getNewlinepointer($fp, $tail);
+ } else {
+ //read backward
+ $tail = $head;
+ $head = max($tail - $this->chunk_size, 0);
+ while (true) {
+ $nl = $this->getNewlinepointer($fp, $head);
+ // was the chunk big enough? if not, take another bite
+ if ($nl > 0 && $tail <= $nl) {
+ $head = max($head - $this->chunk_size, 0);
+ } else {
+ $head = $nl;
+ break;
+ }
+ }
+ }
+
+ //load next chunck
+ $lines = $this->readChunk($fp, $head, $tail);
+ return array($lines, $head, $tail);
+ }
+
+ /**
+ * Collect the $max revisions near to the timestamp $rev
+ *
+ * @param int $rev revision timestamp
+ * @param int $max maximum number of revisions to be returned
+ * @return bool|array
+ * return array with entries:
+ * - $requestedrevs: array of with $max revision timestamps
+ * - $revs: all parsed revision timestamps
+ * - $fp: filepointer only defined for chuck reading, needs closing.
+ * - $lines: non-parsed changelog lines before the parsed revisions
+ * - $head: position of first readed changelogline
+ * - $lasttail: position of end of last readed changelogline
+ * otherwise false
+ */
+ protected function retrieveRevisionsAround($rev, $max)
+ {
+ //get lines from changelog
+ list($fp, $lines, $starthead, $starttail, /* $eof */) = $this->readloglines($rev);
+ if (empty($lines)) return false;
+
+ //parse chunk containing $rev, and read forward more chunks until $max/2 is reached
+ $head = $starthead;
+ $tail = $starttail;
+ $revs = array();
+ $aftercount = $beforecount = 0;
+ while (count($lines) > 0) {
+ foreach ($lines as $line) {
+ $tmp = parseChangelogLine($line);
+ if ($tmp !== false) {
+ $this->cache[$this->id][$tmp['date']] = $tmp;
+ $revs[] = $tmp['date'];
+ if ($tmp['date'] >= $rev) {
+ //count revs after reference $rev
+ $aftercount++;
+ if ($aftercount == 1) $beforecount = count($revs);
+ }
+ //enough revs after reference $rev?
+ if ($aftercount > floor($max / 2)) break 2;
+ }
+ }
+ //retrieve next chunk
+ list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, 1);
+ }
+ if ($aftercount == 0) return false;
+
+ $lasttail = $tail;
+
+ //read additional chuncks backward until $max/2 is reached and total number of revs is equal to $max
+ $lines = array();
+ $i = 0;
+ if ($aftercount > 0) {
+ $head = $starthead;
+ $tail = $starttail;
+ while ($head > 0) {
+ list($lines, $head, $tail) = $this->readAdjacentChunk($fp, $head, $tail, -1);
+
+ for ($i = count($lines) - 1; $i >= 0; $i--) {
+ $tmp = parseChangelogLine($lines[$i]);
+ if ($tmp !== false) {
+ $this->cache[$this->id][$tmp['date']] = $tmp;
+ $revs[] = $tmp['date'];
+ $beforecount++;
+ //enough revs before reference $rev?
+ if ($beforecount > max(floor($max / 2), $max - $aftercount)) break 2;
+ }
+ }
+ }
+ }
+ sort($revs);
+
+ //keep only non-parsed lines
+ $lines = array_slice($lines, 0, $i);
+ //trunk desired selection
+ $requestedrevs = array_slice($revs, -$max, $max);
+
+ return array($requestedrevs, $revs, $fp, $lines, $head, $lasttail);
+ }
+}
diff --git a/platform/www/inc/ChangeLog/MediaChangeLog.php b/platform/www/inc/ChangeLog/MediaChangeLog.php
new file mode 100644
index 0000000..0d7d8d3
--- /dev/null
+++ b/platform/www/inc/ChangeLog/MediaChangeLog.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace dokuwiki\ChangeLog;
+
+/**
+ * handles changelog of a media file
+ */
+class MediaChangeLog extends ChangeLog
+{
+
+ /**
+ * Returns path to changelog
+ *
+ * @return string path to file
+ */
+ protected function getChangelogFilename()
+ {
+ return mediaMetaFN($this->id, '.changes');
+ }
+
+ /**
+ * Returns path to current page/media
+ *
+ * @return string path to file
+ */
+ protected function getFilename()
+ {
+ return mediaFN($this->id);
+ }
+}
diff --git a/platform/www/inc/ChangeLog/PageChangeLog.php b/platform/www/inc/ChangeLog/PageChangeLog.php
new file mode 100644
index 0000000..f1b91de
--- /dev/null
+++ b/platform/www/inc/ChangeLog/PageChangeLog.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace dokuwiki\ChangeLog;
+
+/**
+ * handles changelog of a wiki page
+ */
+class PageChangeLog extends ChangeLog
+{
+
+ /**
+ * Returns path to changelog
+ *
+ * @return string path to file
+ */
+ protected function getChangelogFilename()
+ {
+ return metaFN($this->id, '.changes');
+ }
+
+ /**
+ * Returns path to current page/media
+ *
+ * @return string path to file
+ */
+ protected function getFilename()
+ {
+ return wikiFN($this->id);
+ }
+}
diff --git a/platform/www/inc/Debug/DebugHelper.php b/platform/www/inc/Debug/DebugHelper.php
new file mode 100644
index 0000000..09ff76b
--- /dev/null
+++ b/platform/www/inc/Debug/DebugHelper.php
@@ -0,0 +1,167 @@
+<?php
+
+
+namespace dokuwiki\Debug;
+
+use Doku_Event;
+use dokuwiki\Extension\EventHandler;
+
+class DebugHelper
+{
+ const INFO_DEPRECATION_LOG_EVENT = 'INFO_DEPRECATION_LOG';
+
+ /**
+ * Log accesses to deprecated fucntions to the debug log
+ *
+ * @param string $alternative (optional) The function or method that should be used instead
+ * @param int $callerOffset (optional) How far the deprecated method is removed from this one
+ *
+ * @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT
+ */
+ public static function dbgDeprecatedFunction($alternative = '', $callerOffset = 1)
+ {
+ global $conf;
+ /** @var EventHandler $EVENT_HANDLER */
+ global $EVENT_HANDLER;
+ if (
+ !$conf['allowdebug'] &&
+ ($EVENT_HANDLER === null || !$EVENT_HANDLER->hasHandlerForEvent('INFO_DEPRECATION_LOG'))
+ ){
+ // avoid any work if no one cares
+ return;
+ }
+
+ $backtrace = debug_backtrace();
+ for ($i = 0; $i < $callerOffset; $i += 1) {
+ array_shift($backtrace);
+ }
+
+ list($self, $call) = $backtrace;
+
+ self::triggerDeprecationEvent(
+ $backtrace,
+ $alternative,
+ trim(
+ (!empty($self['class']) ? ($self['class'] . '::') : '') .
+ $self['function'] . '()', ':'),
+ trim(
+ (!empty($call['class']) ? ($call['class'] . '::') : '') .
+ $call['function'] . '()', ':'),
+ $call['file'],
+ $call['line']
+ );
+ }
+
+ /**
+ * This marks logs a deprecation warning for a property that should no longer be used
+ *
+ * This is usually called withing a magic getter or setter.
+ * For logging deprecated functions or methods see dbgDeprecatedFunction()
+ *
+ * @param string $class The class with the deprecated property
+ * @param string $propertyName The name of the deprecated property
+ *
+ * @triggers \dokuwiki\Debug::INFO_DEPRECATION_LOG_EVENT
+ */
+ public static function dbgDeprecatedProperty($class, $propertyName)
+ {
+ global $conf;
+ global $EVENT_HANDLER;
+ if (!$conf['allowdebug'] && !$EVENT_HANDLER->hasHandlerForEvent(self::INFO_DEPRECATION_LOG_EVENT)) {
+ // avoid any work if no one cares
+ return;
+ }
+
+ $backtrace = debug_backtrace();
+ array_shift($backtrace);
+ $call = $backtrace[1];
+ $caller = trim($call['class'] . '::' . $call['function'] . '()', ':');
+ $qualifiedName = $class . '::$' . $propertyName;
+ self::triggerDeprecationEvent(
+ $backtrace,
+ '',
+ $qualifiedName,
+ $caller,
+ $backtrace[0]['file'],
+ $backtrace[0]['line']
+ );
+ }
+
+ /**
+ * Trigger a custom deprecation event
+ *
+ * Usually dbgDeprecatedFunction() or dbgDeprecatedProperty() should be used instead.
+ * This method is intended only for those situation where they are not applicable.
+ *
+ * @param string $alternative
+ * @param string $deprecatedThing
+ * @param string $caller
+ * @param string $file
+ * @param int $line
+ * @param int $callerOffset How many lines should be removed from the beginning of the backtrace
+ */
+ public static function dbgCustomDeprecationEvent(
+ $alternative,
+ $deprecatedThing,
+ $caller,
+ $file,
+ $line,
+ $callerOffset = 1
+ ) {
+ global $conf;
+ /** @var EventHandler $EVENT_HANDLER */
+ global $EVENT_HANDLER;
+ if (!$conf['allowdebug'] && !$EVENT_HANDLER->hasHandlerForEvent(self::INFO_DEPRECATION_LOG_EVENT)) {
+ // avoid any work if no one cares
+ return;
+ }
+
+ $backtrace = array_slice(debug_backtrace(), $callerOffset);
+
+ self::triggerDeprecationEvent(
+ $backtrace,
+ $alternative,
+ $deprecatedThing,
+ $caller,
+ $file,
+ $line
+ );
+
+ }
+
+ /**
+ * @param array $backtrace
+ * @param string $alternative
+ * @param string $deprecatedThing
+ * @param string $caller
+ * @param string $file
+ * @param int $line
+ */
+ private static function triggerDeprecationEvent(
+ array $backtrace,
+ $alternative,
+ $deprecatedThing,
+ $caller,
+ $file,
+ $line
+ ) {
+ $data = [
+ 'trace' => $backtrace,
+ 'alternative' => $alternative,
+ 'called' => $deprecatedThing,
+ 'caller' => $caller,
+ 'file' => $file,
+ 'line' => $line,
+ ];
+ $event = new Doku_Event(self::INFO_DEPRECATION_LOG_EVENT, $data);
+ if ($event->advise_before()) {
+ $msg = $event->data['called'] . ' is deprecated. It was called from ';
+ $msg .= $event->data['caller'] . ' in ' . $event->data['file'] . ':' . $event->data['line'];
+ if ($event->data['alternative']) {
+ $msg .= ' ' . $event->data['alternative'] . ' should be used instead!';
+ }
+ dbglog($msg);
+ }
+ $event->advise_after();
+ }
+}
diff --git a/platform/www/inc/Debug/PropertyDeprecationHelper.php b/platform/www/inc/Debug/PropertyDeprecationHelper.php
new file mode 100644
index 0000000..6289d5b
--- /dev/null
+++ b/platform/www/inc/Debug/PropertyDeprecationHelper.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * Trait for issuing warnings on deprecated access.
+ *
+ * Adapted from https://github.com/wikimedia/mediawiki/blob/4aedefdbfd193f323097354bf581de1c93f02715/includes/debug/DeprecationHelper.php
+ *
+ */
+
+
+namespace dokuwiki\Debug;
+
+/**
+ * Use this trait in classes which have properties for which public access
+ * is deprecated. Set the list of properties in $deprecatedPublicProperties
+ * and make the properties non-public. The trait will preserve public access
+ * but issue deprecation warnings when it is needed.
+ *
+ * Example usage:
+ * class Foo {
+ * use DeprecationHelper;
+ * protected $bar;
+ * public function __construct() {
+ * $this->deprecatePublicProperty( 'bar', '1.21', __CLASS__ );
+ * }
+ * }
+ *
+ * $foo = new Foo;
+ * $foo->bar; // works but logs a warning
+ *
+ * Cannot be used with classes that have their own __get/__set methods.
+ *
+ */
+trait PropertyDeprecationHelper
+{
+
+ /**
+ * List of deprecated properties, in <property name> => <class> format
+ * where <class> is the the name of the class defining the property
+ *
+ * E.g. [ '_event' => '\dokuwiki\Cache\Cache' ]
+ * @var string[]
+ */
+ protected $deprecatedPublicProperties = [];
+
+ /**
+ * Mark a property as deprecated. Only use this for properties that used to be public and only
+ * call it in the constructor.
+ *
+ * @param string $property The name of the property.
+ * @param null $class name of the class defining the property
+ * @see DebugHelper::dbgDeprecatedProperty
+ */
+ protected function deprecatePublicProperty(
+ $property,
+ $class = null
+ ) {
+ $this->deprecatedPublicProperties[$property] = $class ?: get_class();
+ }
+
+ public function __get($name)
+ {
+ if (isset($this->deprecatedPublicProperties[$name])) {
+ $class = $this->deprecatedPublicProperties[$name];
+ DebugHelper::dbgDeprecatedProperty($class, $name);
+ return $this->$name;
+ }
+
+ $qualifiedName = get_class() . '::$' . $name;
+ if ($this->deprecationHelperGetPropertyOwner($name)) {
+ // Someone tried to access a normal non-public property. Try to behave like PHP would.
+ trigger_error("Cannot access non-public property $qualifiedName", E_USER_ERROR);
+ } else {
+ // Non-existing property. Try to behave like PHP would.
+ trigger_error("Undefined property: $qualifiedName", E_USER_NOTICE);
+ }
+ return null;
+ }
+
+ public function __set($name, $value)
+ {
+ if (isset($this->deprecatedPublicProperties[$name])) {
+ $class = $this->deprecatedPublicProperties[$name];
+ DebugHelper::dbgDeprecatedProperty($class, $name);
+ $this->$name = $value;
+ return;
+ }
+
+ $qualifiedName = get_class() . '::$' . $name;
+ if ($this->deprecationHelperGetPropertyOwner($name)) {
+ // Someone tried to access a normal non-public property. Try to behave like PHP would.
+ trigger_error("Cannot access non-public property $qualifiedName", E_USER_ERROR);
+ } else {
+ // Non-existing property. Try to behave like PHP would.
+ $this->$name = $value;
+ }
+ }
+
+ /**
+ * Like property_exists but also check for non-visible private properties and returns which
+ * class in the inheritance chain declared the property.
+ * @param string $property
+ * @return string|bool Best guess for the class in which the property is defined.
+ */
+ private function deprecationHelperGetPropertyOwner($property)
+ {
+ // Easy branch: check for protected property / private property of the current class.
+ if (property_exists($this, $property)) {
+ // The class name is not necessarily correct here but getting the correct class
+ // name would be expensive, this will work most of the time and getting it
+ // wrong is not a big deal.
+ return __CLASS__;
+ }
+ // property_exists() returns false when the property does exist but is private (and not
+ // defined by the current class, for some value of "current" that differs slightly
+ // between engines).
+ // Since PHP triggers an error on public access of non-public properties but happily
+ // allows public access to undefined properties, we need to detect this case as well.
+ // Reflection is slow so use array cast hack to check for that:
+ $obfuscatedProps = array_keys((array)$this);
+ $obfuscatedPropTail = "\0$property";
+ foreach ($obfuscatedProps as $obfuscatedProp) {
+ // private props are in the form \0<classname>\0<propname>
+ if (strpos($obfuscatedProp, $obfuscatedPropTail, 1) !== false) {
+ $classname = substr($obfuscatedProp, 1, -strlen($obfuscatedPropTail));
+ if ($classname === '*') {
+ // sanity; this shouldn't be possible as protected properties were handled earlier
+ $classname = __CLASS__;
+ }
+ return $classname;
+ }
+ }
+ return false;
+ }
+}
diff --git a/platform/www/inc/DifferenceEngine.php b/platform/www/inc/DifferenceEngine.php
new file mode 100644
index 0000000..70877a4
--- /dev/null
+++ b/platform/www/inc/DifferenceEngine.php
@@ -0,0 +1,1544 @@
+<?php
+/**
+ * A PHP diff engine for phpwiki. (Taken from phpwiki-1.3.3)
+ *
+ * Additions by Axel Boldt for MediaWiki
+ *
+ * @copyright (C) 2000, 2001 Geoffrey T. Dairiki <dairiki@dairiki.org>
+ * @license You may copy this code freely under the conditions of the GPL.
+ */
+define('USE_ASSERTS', function_exists('assert'));
+
+class _DiffOp {
+ var $type;
+ var $orig;
+ var $closing;
+
+ /**
+ * @return _DiffOp
+ */
+ function reverse() {
+ trigger_error("pure virtual", E_USER_ERROR);
+ }
+
+ function norig() {
+ return $this->orig ? count($this->orig) : 0;
+ }
+
+ function nclosing() {
+ return $this->closing ? count($this->closing) : 0;
+ }
+}
+
+class _DiffOp_Copy extends _DiffOp {
+ var $type = 'copy';
+
+ function __construct($orig, $closing = false) {
+ if (!is_array($closing))
+ $closing = $orig;
+ $this->orig = $orig;
+ $this->closing = $closing;
+ }
+
+ function reverse() {
+ return new _DiffOp_Copy($this->closing, $this->orig);
+ }
+}
+
+class _DiffOp_Delete extends _DiffOp {
+ var $type = 'delete';
+
+ function __construct($lines) {
+ $this->orig = $lines;
+ $this->closing = false;
+ }
+
+ function reverse() {
+ return new _DiffOp_Add($this->orig);
+ }
+}
+
+class _DiffOp_Add extends _DiffOp {
+ var $type = 'add';
+
+ function __construct($lines) {
+ $this->closing = $lines;
+ $this->orig = false;
+ }
+
+ function reverse() {
+ return new _DiffOp_Delete($this->closing);
+ }
+}
+
+class _DiffOp_Change extends _DiffOp {
+ var $type = 'change';
+
+ function __construct($orig, $closing) {
+ $this->orig = $orig;
+ $this->closing = $closing;
+ }
+
+ function reverse() {
+ return new _DiffOp_Change($this->closing, $this->orig);
+ }
+}
+
+
+/**
+ * Class used internally by Diff to actually compute the diffs.
+ *
+ * The algorithm used here is mostly lifted from the perl module
+ * Algorithm::Diff (version 1.06) by Ned Konz, which is available at:
+ * http://www.perl.com/CPAN/authors/id/N/NE/NEDKONZ/Algorithm-Diff-1.06.zip
+ *
+ * More ideas are taken from:
+ * http://www.ics.uci.edu/~eppstein/161/960229.html
+ *
+ * Some ideas are (and a bit of code) are from from analyze.c, from GNU
+ * diffutils-2.7, which can be found at:
+ * ftp://gnudist.gnu.org/pub/gnu/diffutils/diffutils-2.7.tar.gz
+ *
+ * closingly, some ideas (subdivision by NCHUNKS > 2, and some optimizations)
+ * are my own.
+ *
+ * @author Geoffrey T. Dairiki
+ * @access private
+ */
+class _DiffEngine {
+
+ var $xchanged = array();
+ var $ychanged = array();
+ var $xv = array();
+ var $yv = array();
+ var $xind = array();
+ var $yind = array();
+ var $seq;
+ var $in_seq;
+ var $lcs;
+
+ /**
+ * @param array $from_lines
+ * @param array $to_lines
+ * @return _DiffOp[]
+ */
+ function diff($from_lines, $to_lines) {
+ $n_from = count($from_lines);
+ $n_to = count($to_lines);
+
+ $this->xchanged = $this->ychanged = array();
+ $this->xv = $this->yv = array();
+ $this->xind = $this->yind = array();
+ unset($this->seq);
+ unset($this->in_seq);
+ unset($this->lcs);
+
+ // Skip leading common lines.
+ for ($skip = 0; $skip < $n_from && $skip < $n_to; $skip++) {
+ if ($from_lines[$skip] != $to_lines[$skip])
+ break;
+ $this->xchanged[$skip] = $this->ychanged[$skip] = false;
+ }
+ // Skip trailing common lines.
+ $xi = $n_from;
+ $yi = $n_to;
+ for ($endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++) {
+ if ($from_lines[$xi] != $to_lines[$yi])
+ break;
+ $this->xchanged[$xi] = $this->ychanged[$yi] = false;
+ }
+
+ // Ignore lines which do not exist in both files.
+ for ($xi = $skip; $xi < $n_from - $endskip; $xi++)
+ $xhash[$from_lines[$xi]] = 1;
+ for ($yi = $skip; $yi < $n_to - $endskip; $yi++) {
+ $line = $to_lines[$yi];
+ if (($this->ychanged[$yi] = empty($xhash[$line])))
+ continue;
+ $yhash[$line] = 1;
+ $this->yv[] = $line;
+ $this->yind[] = $yi;
+ }
+ for ($xi = $skip; $xi < $n_from - $endskip; $xi++) {
+ $line = $from_lines[$xi];
+ if (($this->xchanged[$xi] = empty($yhash[$line])))
+ continue;
+ $this->xv[] = $line;
+ $this->xind[] = $xi;
+ }
+
+ // Find the LCS.
+ $this->_compareseq(0, count($this->xv), 0, count($this->yv));
+
+ // Merge edits when possible
+ $this->_shift_boundaries($from_lines, $this->xchanged, $this->ychanged);
+ $this->_shift_boundaries($to_lines, $this->ychanged, $this->xchanged);
+
+ // Compute the edit operations.
+ $edits = array();
+ $xi = $yi = 0;
+ while ($xi < $n_from || $yi < $n_to) {
+ USE_ASSERTS && assert($yi < $n_to || $this->xchanged[$xi]);
+ USE_ASSERTS && assert($xi < $n_from || $this->ychanged[$yi]);
+
+ // Skip matching "snake".
+ $copy = array();
+ while ($xi < $n_from && $yi < $n_to && !$this->xchanged[$xi] && !$this->ychanged[$yi]) {
+ $copy[] = $from_lines[$xi++];
+ ++$yi;
+ }
+ if ($copy)
+ $edits[] = new _DiffOp_Copy($copy);
+
+ // Find deletes & adds.
+ $delete = array();
+ while ($xi < $n_from && $this->xchanged[$xi])
+ $delete[] = $from_lines[$xi++];
+
+ $add = array();
+ while ($yi < $n_to && $this->ychanged[$yi])
+ $add[] = $to_lines[$yi++];
+
+ if ($delete && $add)
+ $edits[] = new _DiffOp_Change($delete, $add);
+ elseif ($delete)
+ $edits[] = new _DiffOp_Delete($delete);
+ elseif ($add)
+ $edits[] = new _DiffOp_Add($add);
+ }
+ return $edits;
+ }
+
+
+ /**
+ * Divide the Largest Common Subsequence (LCS) of the sequences
+ * [XOFF, XLIM) and [YOFF, YLIM) into NCHUNKS approximately equally
+ * sized segments.
+ *
+ * Returns (LCS, PTS). LCS is the length of the LCS. PTS is an
+ * array of NCHUNKS+1 (X, Y) indexes giving the diving points between
+ * sub sequences. The first sub-sequence is contained in [X0, X1),
+ * [Y0, Y1), the second in [X1, X2), [Y1, Y2) and so on. Note
+ * that (X0, Y0) == (XOFF, YOFF) and
+ * (X[NCHUNKS], Y[NCHUNKS]) == (XLIM, YLIM).
+ *
+ * This function assumes that the first lines of the specified portions
+ * of the two files do not match, and likewise that the last lines do not
+ * match. The caller must trim matching lines from the beginning and end
+ * of the portions it is going to specify.
+ *
+ * @param integer $xoff
+ * @param integer $xlim
+ * @param integer $yoff
+ * @param integer $ylim
+ * @param integer $nchunks
+ *
+ * @return array
+ */
+ function _diag($xoff, $xlim, $yoff, $ylim, $nchunks) {
+ $flip = false;
+
+ if ($xlim - $xoff > $ylim - $yoff) {
+ // Things seems faster (I'm not sure I understand why)
+ // when the shortest sequence in X.
+ $flip = true;
+ list ($xoff, $xlim, $yoff, $ylim) = array($yoff, $ylim, $xoff, $xlim);
+ }
+
+ if ($flip)
+ for ($i = $ylim - 1; $i >= $yoff; $i--)
+ $ymatches[$this->xv[$i]][] = $i;
+ else
+ for ($i = $ylim - 1; $i >= $yoff; $i--)
+ $ymatches[$this->yv[$i]][] = $i;
+
+ $this->lcs = 0;
+ $this->seq[0]= $yoff - 1;
+ $this->in_seq = array();
+ $ymids[0] = array();
+
+ $numer = $xlim - $xoff + $nchunks - 1;
+ $x = $xoff;
+ for ($chunk = 0; $chunk < $nchunks; $chunk++) {
+ if ($chunk > 0)
+ for ($i = 0; $i <= $this->lcs; $i++)
+ $ymids[$i][$chunk-1] = $this->seq[$i];
+
+ $x1 = $xoff + (int)(($numer + ($xlim-$xoff)*$chunk) / $nchunks);
+ for ( ; $x < $x1; $x++) {
+ $line = $flip ? $this->yv[$x] : $this->xv[$x];
+ if (empty($ymatches[$line]))
+ continue;
+ $matches = $ymatches[$line];
+ $switch = false;
+ foreach ($matches as $y) {
+ if ($switch && $y > $this->seq[$k-1]) {
+ USE_ASSERTS && assert($y < $this->seq[$k]);
+ // Optimization: this is a common case:
+ // next match is just replacing previous match.
+ $this->in_seq[$this->seq[$k]] = false;
+ $this->seq[$k] = $y;
+ $this->in_seq[$y] = 1;
+ }
+ else if (empty($this->in_seq[$y])) {
+ $k = $this->_lcs_pos($y);
+ USE_ASSERTS && assert($k > 0);
+ $ymids[$k] = $ymids[$k-1];
+ $switch = true;
+ }
+ }
+ }
+ }
+
+ $seps[] = $flip ? array($yoff, $xoff) : array($xoff, $yoff);
+ $ymid = $ymids[$this->lcs];
+ for ($n = 0; $n < $nchunks - 1; $n++) {
+ $x1 = $xoff + (int)(($numer + ($xlim - $xoff) * $n) / $nchunks);
+ $y1 = $ymid[$n] + 1;
+ $seps[] = $flip ? array($y1, $x1) : array($x1, $y1);
+ }
+ $seps[] = $flip ? array($ylim, $xlim) : array($xlim, $ylim);
+
+ return array($this->lcs, $seps);
+ }
+
+ function _lcs_pos($ypos) {
+ $end = $this->lcs;
+ if ($end == 0 || $ypos > $this->seq[$end]) {
+ $this->seq[++$this->lcs] = $ypos;
+ $this->in_seq[$ypos] = 1;
+ return $this->lcs;
+ }
+
+ $beg = 1;
+ while ($beg < $end) {
+ $mid = (int)(($beg + $end) / 2);
+ if ($ypos > $this->seq[$mid])
+ $beg = $mid + 1;
+ else
+ $end = $mid;
+ }
+
+ USE_ASSERTS && assert($ypos != $this->seq[$end]);
+
+ $this->in_seq[$this->seq[$end]] = false;
+ $this->seq[$end] = $ypos;
+ $this->in_seq[$ypos] = 1;
+ return $end;
+ }
+
+ /**
+ * Find LCS of two sequences.
+ *
+ * The results are recorded in the vectors $this->{x,y}changed[], by
+ * storing a 1 in the element for each line that is an insertion
+ * or deletion (ie. is not in the LCS).
+ *
+ * The subsequence of file 0 is [XOFF, XLIM) and likewise for file 1.
+ *
+ * Note that XLIM, YLIM are exclusive bounds.
+ * All line numbers are origin-0 and discarded lines are not counted.
+ *
+ * @param integer $xoff
+ * @param integer $xlim
+ * @param integer $yoff
+ * @param integer $ylim
+ */
+ function _compareseq($xoff, $xlim, $yoff, $ylim) {
+ // Slide down the bottom initial diagonal.
+ while ($xoff < $xlim && $yoff < $ylim && $this->xv[$xoff] == $this->yv[$yoff]) {
+ ++$xoff;
+ ++$yoff;
+ }
+
+ // Slide up the top initial diagonal.
+ while ($xlim > $xoff && $ylim > $yoff && $this->xv[$xlim - 1] == $this->yv[$ylim - 1]) {
+ --$xlim;
+ --$ylim;
+ }
+
+ if ($xoff == $xlim || $yoff == $ylim)
+ $lcs = 0;
+ else {
+ // This is ad hoc but seems to work well.
+ //$nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5);
+ //$nchunks = max(2,min(8,(int)$nchunks));
+ $nchunks = min(7, $xlim - $xoff, $ylim - $yoff) + 1;
+ list ($lcs, $seps)
+ = $this->_diag($xoff,$xlim,$yoff, $ylim,$nchunks);
+ }
+
+ if ($lcs == 0) {
+ // X and Y sequences have no common subsequence:
+ // mark all changed.
+ while ($yoff < $ylim)
+ $this->ychanged[$this->yind[$yoff++]] = 1;
+ while ($xoff < $xlim)
+ $this->xchanged[$this->xind[$xoff++]] = 1;
+ }
+ else {
+ // Use the partitions to split this problem into subproblems.
+ reset($seps);
+ $pt1 = $seps[0];
+ while ($pt2 = next($seps)) {
+ $this->_compareseq ($pt1[0], $pt2[0], $pt1[1], $pt2[1]);
+ $pt1 = $pt2;
+ }
+ }
+ }
+
+ /**
+ * Adjust inserts/deletes of identical lines to join changes
+ * as much as possible.
+ *
+ * We do something when a run of changed lines include a
+ * line at one end and has an excluded, identical line at the other.
+ * We are free to choose which identical line is included.
+ * `compareseq' usually chooses the one at the beginning,
+ * but usually it is cleaner to consider the following identical line
+ * to be the "change".
+ *
+ * This is extracted verbatim from analyze.c (GNU diffutils-2.7).
+ *
+ * @param array $lines
+ * @param array $changed
+ * @param array $other_changed
+ */
+ function _shift_boundaries($lines, &$changed, $other_changed) {
+ $i = 0;
+ $j = 0;
+
+ USE_ASSERTS && assert(count($lines) == count($changed));
+ $len = count($lines);
+ $other_len = count($other_changed);
+
+ while (1) {
+ /*
+ * Scan forwards to find beginning of another run of changes.
+ * Also keep track of the corresponding point in the other file.
+ *
+ * Throughout this code, $i and $j are adjusted together so that
+ * the first $i elements of $changed and the first $j elements
+ * of $other_changed both contain the same number of zeros
+ * (unchanged lines).
+ * Furthermore, $j is always kept so that $j == $other_len or
+ * $other_changed[$j] == false.
+ */
+ while ($j < $other_len && $other_changed[$j])
+ $j++;
+
+ while ($i < $len && ! $changed[$i]) {
+ USE_ASSERTS && assert($j < $other_len && ! $other_changed[$j]);
+ $i++;
+ $j++;
+ while ($j < $other_len && $other_changed[$j])
+ $j++;
+ }
+
+ if ($i == $len)
+ break;
+
+ $start = $i;
+
+ // Find the end of this run of changes.
+ while (++$i < $len && $changed[$i])
+ continue;
+
+ do {
+ /*
+ * Record the length of this run of changes, so that
+ * we can later determine whether the run has grown.
+ */
+ $runlength = $i - $start;
+
+ /*
+ * Move the changed region back, so long as the
+ * previous unchanged line matches the last changed one.
+ * This merges with previous changed regions.
+ */
+ while ($start > 0 && $lines[$start - 1] == $lines[$i - 1]) {
+ $changed[--$start] = 1;
+ $changed[--$i] = false;
+ while ($start > 0 && $changed[$start - 1])
+ $start--;
+ USE_ASSERTS && assert($j > 0);
+ while ($other_changed[--$j])
+ continue;
+ USE_ASSERTS && assert($j >= 0 && !$other_changed[$j]);
+ }
+
+ /*
+ * Set CORRESPONDING to the end of the changed run, at the last
+ * point where it corresponds to a changed run in the other file.
+ * CORRESPONDING == LEN means no such point has been found.
+ */
+ $corresponding = $j < $other_len ? $i : $len;
+
+ /*
+ * Move the changed region forward, so long as the
+ * first changed line matches the following unchanged one.
+ * This merges with following changed regions.
+ * Do this second, so that if there are no merges,
+ * the changed region is moved forward as far as possible.
+ */
+ while ($i < $len && $lines[$start] == $lines[$i]) {
+ $changed[$start++] = false;
+ $changed[$i++] = 1;
+ while ($i < $len && $changed[$i])
+ $i++;
+
+ USE_ASSERTS && assert($j < $other_len && ! $other_changed[$j]);
+ $j++;
+ if ($j < $other_len && $other_changed[$j]) {
+ $corresponding = $i;
+ while ($j < $other_len && $other_changed[$j])
+ $j++;
+ }
+ }
+ } while ($runlength != $i - $start);
+
+ /*
+ * If possible, move the fully-merged run of changes
+ * back to a corresponding run in the other file.
+ */
+ while ($corresponding < $i) {
+ $changed[--$start] = 1;
+ $changed[--$i] = 0;
+ USE_ASSERTS && assert($j > 0);
+ while ($other_changed[--$j])
+ continue;
+ USE_ASSERTS && assert($j >= 0 && !$other_changed[$j]);
+ }
+ }
+ }
+}
+
+/**
+ * Class representing a 'diff' between two sequences of strings.
+ */
+class Diff {
+
+ var $edits;
+
+ /**
+ * Constructor.
+ * Computes diff between sequences of strings.
+ *
+ * @param array $from_lines An array of strings.
+ * (Typically these are lines from a file.)
+ * @param array $to_lines An array of strings.
+ */
+ function __construct($from_lines, $to_lines) {
+ $eng = new _DiffEngine;
+ $this->edits = $eng->diff($from_lines, $to_lines);
+ //$this->_check($from_lines, $to_lines);
+ }
+
+ /**
+ * Compute reversed Diff.
+ *
+ * SYNOPSIS:
+ *
+ * $diff = new Diff($lines1, $lines2);
+ * $rev = $diff->reverse();
+ *
+ * @return Diff A Diff object representing the inverse of the
+ * original diff.
+ */
+ function reverse() {
+ $rev = $this;
+ $rev->edits = array();
+ foreach ($this->edits as $edit) {
+ $rev->edits[] = $edit->reverse();
+ }
+ return $rev;
+ }
+
+ /**
+ * Check for empty diff.
+ *
+ * @return bool True iff two sequences were identical.
+ */
+ function isEmpty() {
+ foreach ($this->edits as $edit) {
+ if ($edit->type != 'copy')
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Compute the length of the Longest Common Subsequence (LCS).
+ *
+ * This is mostly for diagnostic purposed.
+ *
+ * @return int The length of the LCS.
+ */
+ function lcs() {
+ $lcs = 0;
+ foreach ($this->edits as $edit) {
+ if ($edit->type == 'copy')
+ $lcs += count($edit->orig);
+ }
+ return $lcs;
+ }
+
+ /**
+ * Get the original set of lines.
+ *
+ * This reconstructs the $from_lines parameter passed to the
+ * constructor.
+ *
+ * @return array The original sequence of strings.
+ */
+ function orig() {
+ $lines = array();
+
+ foreach ($this->edits as $edit) {
+ if ($edit->orig)
+ array_splice($lines, count($lines), 0, $edit->orig);
+ }
+ return $lines;
+ }
+
+ /**
+ * Get the closing set of lines.
+ *
+ * This reconstructs the $to_lines parameter passed to the
+ * constructor.
+ *
+ * @return array The sequence of strings.
+ */
+ function closing() {
+ $lines = array();
+
+ foreach ($this->edits as $edit) {
+ if ($edit->closing)
+ array_splice($lines, count($lines), 0, $edit->closing);
+ }
+ return $lines;
+ }
+
+ /**
+ * Check a Diff for validity.
+ *
+ * This is here only for debugging purposes.
+ *
+ * @param mixed $from_lines
+ * @param mixed $to_lines
+ */
+ function _check($from_lines, $to_lines) {
+ if (serialize($from_lines) != serialize($this->orig()))
+ trigger_error("Reconstructed original doesn't match", E_USER_ERROR);
+ if (serialize($to_lines) != serialize($this->closing()))
+ trigger_error("Reconstructed closing doesn't match", E_USER_ERROR);
+
+ $rev = $this->reverse();
+ if (serialize($to_lines) != serialize($rev->orig()))
+ trigger_error("Reversed original doesn't match", E_USER_ERROR);
+ if (serialize($from_lines) != serialize($rev->closing()))
+ trigger_error("Reversed closing doesn't match", E_USER_ERROR);
+
+ $prevtype = 'none';
+ foreach ($this->edits as $edit) {
+ if ($prevtype == $edit->type)
+ trigger_error("Edit sequence is non-optimal", E_USER_ERROR);
+ $prevtype = $edit->type;
+ }
+
+ $lcs = $this->lcs();
+ trigger_error("Diff okay: LCS = $lcs", E_USER_NOTICE);
+ }
+}
+
+/**
+ * FIXME: bad name.
+ */
+class MappedDiff extends Diff {
+ /**
+ * Constructor.
+ *
+ * Computes diff between sequences of strings.
+ *
+ * This can be used to compute things like
+ * case-insensitve diffs, or diffs which ignore
+ * changes in white-space.
+ *
+ * @param string[] $from_lines An array of strings.
+ * (Typically these are lines from a file.)
+ *
+ * @param string[] $to_lines An array of strings.
+ *
+ * @param string[] $mapped_from_lines This array should
+ * have the same size number of elements as $from_lines.
+ * The elements in $mapped_from_lines and
+ * $mapped_to_lines are what is actually compared
+ * when computing the diff.
+ *
+ * @param string[] $mapped_to_lines This array should
+ * have the same number of elements as $to_lines.
+ */
+ function __construct($from_lines, $to_lines, $mapped_from_lines, $mapped_to_lines) {
+
+ assert(count($from_lines) == count($mapped_from_lines));
+ assert(count($to_lines) == count($mapped_to_lines));
+
+ parent::__construct($mapped_from_lines, $mapped_to_lines);
+
+ $xi = $yi = 0;
+ $ecnt = count($this->edits);
+ for ($i = 0; $i < $ecnt; $i++) {
+ $orig = &$this->edits[$i]->orig;
+ if (is_array($orig)) {
+ $orig = array_slice($from_lines, $xi, count($orig));
+ $xi += count($orig);
+ }
+
+ $closing = &$this->edits[$i]->closing;
+ if (is_array($closing)) {
+ $closing = array_slice($to_lines, $yi, count($closing));
+ $yi += count($closing);
+ }
+ }
+ }
+}
+
+/**
+ * A class to format Diffs
+ *
+ * This class formats the diff in classic diff format.
+ * It is intended that this class be customized via inheritance,
+ * to obtain fancier outputs.
+ */
+class DiffFormatter {
+ /**
+ * Number of leading context "lines" to preserve.
+ *
+ * This should be left at zero for this class, but subclasses
+ * may want to set this to other values.
+ */
+ var $leading_context_lines = 0;
+
+ /**
+ * Number of trailing context "lines" to preserve.
+ *
+ * This should be left at zero for this class, but subclasses
+ * may want to set this to other values.
+ */
+ var $trailing_context_lines = 0;
+
+ /**
+ * Format a diff.
+ *
+ * @param Diff $diff A Diff object.
+ * @return string The formatted output.
+ */
+ function format($diff) {
+
+ $xi = $yi = 1;
+ $x0 = $y0 = 0;
+ $block = false;
+ $context = array();
+
+ $nlead = $this->leading_context_lines;
+ $ntrail = $this->trailing_context_lines;
+
+ $this->_start_diff();
+
+ foreach ($diff->edits as $edit) {
+ if ($edit->type == 'copy') {
+ if (is_array($block)) {
+ if (count($edit->orig) <= $nlead + $ntrail) {
+ $block[] = $edit;
+ }
+ else{
+ if ($ntrail) {
+ $context = array_slice($edit->orig, 0, $ntrail);
+ $block[] = new _DiffOp_Copy($context);
+ }
+ $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
+ $block = false;
+ }
+ }
+ $context = $edit->orig;
+ }
+ else {
+ if (! is_array($block)) {
+ $context = array_slice($context, count($context) - $nlead);
+ $x0 = $xi - count($context);
+ $y0 = $yi - count($context);
+ $block = array();
+ if ($context)
+ $block[] = new _DiffOp_Copy($context);
+ }
+ $block[] = $edit;
+ }
+
+ if ($edit->orig)
+ $xi += count($edit->orig);
+ if ($edit->closing)
+ $yi += count($edit->closing);
+ }
+
+ if (is_array($block))
+ $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
+
+ return $this->_end_diff();
+ }
+
+ /**
+ * @param int $xbeg
+ * @param int $xlen
+ * @param int $ybeg
+ * @param int $ylen
+ * @param array $edits
+ */
+ function _block($xbeg, $xlen, $ybeg, $ylen, &$edits) {
+ $this->_start_block($this->_block_header($xbeg, $xlen, $ybeg, $ylen));
+ foreach ($edits as $edit) {
+ if ($edit->type == 'copy')
+ $this->_context($edit->orig);
+ elseif ($edit->type == 'add')
+ $this->_added($edit->closing);
+ elseif ($edit->type == 'delete')
+ $this->_deleted($edit->orig);
+ elseif ($edit->type == 'change')
+ $this->_changed($edit->orig, $edit->closing);
+ else
+ trigger_error("Unknown edit type", E_USER_ERROR);
+ }
+ $this->_end_block();
+ }
+
+ function _start_diff() {
+ ob_start();
+ }
+
+ function _end_diff() {
+ $val = ob_get_contents();
+ ob_end_clean();
+ return $val;
+ }
+
+ /**
+ * @param int $xbeg
+ * @param int $xlen
+ * @param int $ybeg
+ * @param int $ylen
+ * @return string
+ */
+ function _block_header($xbeg, $xlen, $ybeg, $ylen) {
+ if ($xlen > 1)
+ $xbeg .= "," . ($xbeg + $xlen - 1);
+ if ($ylen > 1)
+ $ybeg .= "," . ($ybeg + $ylen - 1);
+
+ return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
+ }
+
+ /**
+ * @param string $header
+ */
+ function _start_block($header) {
+ echo $header;
+ }
+
+ function _end_block() {
+ }
+
+ function _lines($lines, $prefix = ' ') {
+ foreach ($lines as $line)
+ echo "$prefix ".$this->_escape($line)."\n";
+ }
+
+ function _context($lines) {
+ $this->_lines($lines);
+ }
+
+ function _added($lines) {
+ $this->_lines($lines, ">");
+ }
+ function _deleted($lines) {
+ $this->_lines($lines, "<");
+ }
+
+ function _changed($orig, $closing) {
+ $this->_deleted($orig);
+ echo "---\n";
+ $this->_added($closing);
+ }
+
+ /**
+ * Escape string
+ *
+ * Override this method within other formatters if escaping required.
+ * Base class requires $str to be returned WITHOUT escaping.
+ *
+ * @param $str string Text string to escape
+ * @return string The escaped string.
+ */
+ function _escape($str){
+ return $str;
+ }
+}
+
+/**
+ * Utilityclass for styling HTML formatted diffs
+ *
+ * Depends on global var $DIFF_INLINESTYLES, if true some minimal predefined
+ * inline styles are used. Useful for HTML mails and RSS feeds
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class HTMLDiff {
+ /**
+ * Holds the style names and basic CSS
+ */
+ static public $styles = array(
+ 'diff-addedline' => 'background-color: #ddffdd;',
+ 'diff-deletedline' => 'background-color: #ffdddd;',
+ 'diff-context' => 'background-color: #f5f5f5;',
+ 'diff-mark' => 'color: #ff0000;',
+ );
+
+ /**
+ * Return a class or style parameter
+ *
+ * @param string $classname
+ *
+ * @return string
+ */
+ static function css($classname){
+ global $DIFF_INLINESTYLES;
+
+ if($DIFF_INLINESTYLES){
+ if(!isset(self::$styles[$classname])) return '';
+ return 'style="'.self::$styles[$classname].'"';
+ }else{
+ return 'class="'.$classname.'"';
+ }
+ }
+}
+
+/**
+ * Additions by Axel Boldt follow, partly taken from diff.php, phpwiki-1.3.3
+ *
+ */
+
+define('NBSP', "\xC2\xA0"); // utf-8 non-breaking space.
+
+class _HWLDF_WordAccumulator {
+
+ function __construct() {
+ $this->_lines = array();
+ $this->_line = '';
+ $this->_group = '';
+ $this->_tag = '';
+ }
+
+ function _flushGroup($new_tag) {
+ if ($this->_group !== '') {
+ if ($this->_tag == 'mark')
+ $this->_line .= '<strong '.HTMLDiff::css('diff-mark').'>'.$this->_escape($this->_group).'</strong>';
+ elseif ($this->_tag == 'add')
+ $this->_line .= '<span '.HTMLDiff::css('diff-addedline').'>'.$this->_escape($this->_group).'</span>';
+ elseif ($this->_tag == 'del')
+ $this->_line .= '<span '.HTMLDiff::css('diff-deletedline').'><del>'.$this->_escape($this->_group).'</del></span>';
+ else
+ $this->_line .= $this->_escape($this->_group);
+ }
+ $this->_group = '';
+ $this->_tag = $new_tag;
+ }
+
+ /**
+ * @param string $new_tag
+ */
+ function _flushLine($new_tag) {
+ $this->_flushGroup($new_tag);
+ if ($this->_line != '')
+ $this->_lines[] = $this->_line;
+ $this->_line = '';
+ }
+
+ function addWords($words, $tag = '') {
+ if ($tag != $this->_tag)
+ $this->_flushGroup($tag);
+
+ foreach ($words as $word) {
+ // new-line should only come as first char of word.
+ if ($word == '')
+ continue;
+ if ($word[0] == "\n") {
+ $this->_group .= NBSP;
+ $this->_flushLine($tag);
+ $word = substr($word, 1);
+ }
+ assert(!strstr($word, "\n"));
+ $this->_group .= $word;
+ }
+ }
+
+ function getLines() {
+ $this->_flushLine('~done');
+ return $this->_lines;
+ }
+
+ function _escape($str){
+ return hsc($str);
+ }
+}
+
+class WordLevelDiff extends MappedDiff {
+
+ function __construct($orig_lines, $closing_lines) {
+ list ($orig_words, $orig_stripped) = $this->_split($orig_lines);
+ list ($closing_words, $closing_stripped) = $this->_split($closing_lines);
+
+ parent::__construct($orig_words, $closing_words, $orig_stripped, $closing_stripped);
+ }
+
+ function _split($lines) {
+ if (!preg_match_all('/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xsu',
+ implode("\n", $lines), $m)) {
+ return array(array(''), array(''));
+ }
+ return array($m[0], $m[1]);
+ }
+
+ function orig() {
+ $orig = new _HWLDF_WordAccumulator;
+
+ foreach ($this->edits as $edit) {
+ if ($edit->type == 'copy')
+ $orig->addWords($edit->orig);
+ elseif ($edit->orig)
+ $orig->addWords($edit->orig, 'mark');
+ }
+ return $orig->getLines();
+ }
+
+ function closing() {
+ $closing = new _HWLDF_WordAccumulator;
+
+ foreach ($this->edits as $edit) {
+ if ($edit->type == 'copy')
+ $closing->addWords($edit->closing);
+ elseif ($edit->closing)
+ $closing->addWords($edit->closing, 'mark');
+ }
+ return $closing->getLines();
+ }
+}
+
+class InlineWordLevelDiff extends MappedDiff {
+
+ function __construct($orig_lines, $closing_lines) {
+ list ($orig_words, $orig_stripped) = $this->_split($orig_lines);
+ list ($closing_words, $closing_stripped) = $this->_split($closing_lines);
+
+ parent::__construct($orig_words, $closing_words, $orig_stripped, $closing_stripped);
+ }
+
+ function _split($lines) {
+ if (!preg_match_all('/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xsu',
+ implode("\n", $lines), $m)) {
+ return array(array(''), array(''));
+ }
+ return array($m[0], $m[1]);
+ }
+
+ function inline() {
+ $orig = new _HWLDF_WordAccumulator;
+ foreach ($this->edits as $edit) {
+ if ($edit->type == 'copy')
+ $orig->addWords($edit->closing);
+ elseif ($edit->type == 'change'){
+ $orig->addWords($edit->orig, 'del');
+ $orig->addWords($edit->closing, 'add');
+ } elseif ($edit->type == 'delete')
+ $orig->addWords($edit->orig, 'del');
+ elseif ($edit->type == 'add')
+ $orig->addWords($edit->closing, 'add');
+ elseif ($edit->orig)
+ $orig->addWords($edit->orig, 'del');
+ }
+ return $orig->getLines();
+ }
+}
+
+/**
+ * "Unified" diff formatter.
+ *
+ * This class formats the diff in classic "unified diff" format.
+ *
+ * NOTE: output is plain text and unsafe for use in HTML without escaping.
+ */
+class UnifiedDiffFormatter extends DiffFormatter {
+
+ function __construct($context_lines = 4) {
+ $this->leading_context_lines = $context_lines;
+ $this->trailing_context_lines = $context_lines;
+ }
+
+ function _block_header($xbeg, $xlen, $ybeg, $ylen) {
+ if ($xlen != 1)
+ $xbeg .= "," . $xlen;
+ if ($ylen != 1)
+ $ybeg .= "," . $ylen;
+ return "@@ -$xbeg +$ybeg @@\n";
+ }
+
+ function _added($lines) {
+ $this->_lines($lines, "+");
+ }
+ function _deleted($lines) {
+ $this->_lines($lines, "-");
+ }
+ function _changed($orig, $final) {
+ $this->_deleted($orig);
+ $this->_added($final);
+ }
+}
+
+/**
+ * Wikipedia Table style diff formatter.
+ *
+ */
+class TableDiffFormatter extends DiffFormatter {
+ var $colspan = 2;
+
+ function __construct() {
+ $this->leading_context_lines = 2;
+ $this->trailing_context_lines = 2;
+ }
+
+ /**
+ * @param Diff $diff
+ * @return string
+ */
+ function format($diff) {
+ // Preserve whitespaces by converting some to non-breaking spaces.
+ // Do not convert all of them to allow word-wrap.
+ $val = parent::format($diff);
+ $val = str_replace(' ','&#160; ', $val);
+ $val = preg_replace('/ (?=<)|(?<=[ >]) /', '&#160;', $val);
+ return $val;
+ }
+
+ function _pre($text){
+ $text = htmlspecialchars($text);
+ return $text;
+ }
+
+ function _block_header($xbeg, $xlen, $ybeg, $ylen) {
+ global $lang;
+ $l1 = $lang['line'].' '.$xbeg;
+ $l2 = $lang['line'].' '.$ybeg;
+ $r = '<tr><td '.HTMLDiff::css('diff-blockheader').' colspan="'.$this->colspan.'">'.$l1.":</td>\n".
+ '<td '.HTMLDiff::css('diff-blockheader').' colspan="'.$this->colspan.'">'.$l2.":</td>\n".
+ "</tr>\n";
+ return $r;
+ }
+
+ function _start_block($header) {
+ print($header);
+ }
+
+ function _end_block() {
+ }
+
+ function _lines($lines, $prefix=' ', $color="white") {
+ }
+
+ function addedLine($line,$escaped=false) {
+ if (!$escaped){
+ $line = $this->_escape($line);
+ }
+ return '<td '.HTMLDiff::css('diff-lineheader').'>+</td>'.
+ '<td '.HTMLDiff::css('diff-addedline').'>' . $line.'</td>';
+ }
+
+ function deletedLine($line,$escaped=false) {
+ if (!$escaped){
+ $line = $this->_escape($line);
+ }
+ return '<td '.HTMLDiff::css('diff-lineheader').'>-</td>'.
+ '<td '.HTMLDiff::css('diff-deletedline').'>' . $line.'</td>';
+ }
+
+ function emptyLine() {
+ return '<td colspan="'.$this->colspan.'">&#160;</td>';
+ }
+
+ function contextLine($line) {
+ return '<td '.HTMLDiff::css('diff-lineheader').'>&#160;</td>'.
+ '<td '.HTMLDiff::css('diff-context').'>'.$this->_escape($line).'</td>';
+ }
+
+ function _added($lines) {
+ $this->_addedLines($lines,false);
+ }
+
+ function _addedLines($lines,$escaped=false){
+ foreach ($lines as $line) {
+ print('<tr>' . $this->emptyLine() . $this->addedLine($line,$escaped) . "</tr>\n");
+ }
+ }
+
+ function _deleted($lines) {
+ foreach ($lines as $line) {
+ print('<tr>' . $this->deletedLine($line) . $this->emptyLine() . "</tr>\n");
+ }
+ }
+
+ function _context($lines) {
+ foreach ($lines as $line) {
+ print('<tr>' . $this->contextLine($line) . $this->contextLine($line) . "</tr>\n");
+ }
+ }
+
+ function _changed($orig, $closing) {
+ $diff = new WordLevelDiff($orig, $closing); // this escapes the diff data
+ $del = $diff->orig();
+ $add = $diff->closing();
+
+ while ($line = array_shift($del)) {
+ $aline = array_shift($add);
+ print('<tr>' . $this->deletedLine($line,true) . $this->addedLine($aline,true) . "</tr>\n");
+ }
+ $this->_addedLines($add,true); # If any leftovers
+ }
+
+ function _escape($str) {
+ return hsc($str);
+ }
+}
+
+/**
+ * Inline style diff formatter.
+ *
+ */
+class InlineDiffFormatter extends DiffFormatter {
+ var $colspan = 2;
+
+ function __construct() {
+ $this->leading_context_lines = 2;
+ $this->trailing_context_lines = 2;
+ }
+
+ /**
+ * @param Diff $diff
+ * @return string
+ */
+ function format($diff) {
+ // Preserve whitespaces by converting some to non-breaking spaces.
+ // Do not convert all of them to allow word-wrap.
+ $val = parent::format($diff);
+ $val = str_replace(' ','&#160; ', $val);
+ $val = preg_replace('/ (?=<)|(?<=[ >]) /', '&#160;', $val);
+ return $val;
+ }
+
+ function _pre($text){
+ $text = htmlspecialchars($text);
+ return $text;
+ }
+
+ function _block_header($xbeg, $xlen, $ybeg, $ylen) {
+ global $lang;
+ if ($xlen != 1)
+ $xbeg .= "," . $xlen;
+ if ($ylen != 1)
+ $ybeg .= "," . $ylen;
+ $r = '<tr><td colspan="'.$this->colspan.'" '.HTMLDiff::css('diff-blockheader').'>@@ '.$lang['line']." -$xbeg +$ybeg @@";
+ $r .= ' <span '.HTMLDiff::css('diff-deletedline').'><del>'.$lang['deleted'].'</del></span>';
+ $r .= ' <span '.HTMLDiff::css('diff-addedline').'>'.$lang['created'].'</span>';
+ $r .= "</td></tr>\n";
+ return $r;
+ }
+
+ function _start_block($header) {
+ print($header."\n");
+ }
+
+ function _end_block() {
+ }
+
+ function _lines($lines, $prefix=' ', $color="white") {
+ }
+
+ function _added($lines) {
+ foreach ($lines as $line) {
+ print('<tr><td '.HTMLDiff::css('diff-lineheader').'>&#160;</td><td '.HTMLDiff::css('diff-addedline').'>'. $this->_escape($line) . "</td></tr>\n");
+ }
+ }
+
+ function _deleted($lines) {
+ foreach ($lines as $line) {
+ print('<tr><td '.HTMLDiff::css('diff-lineheader').'>&#160;</td><td '.HTMLDiff::css('diff-deletedline').'><del>' . $this->_escape($line) . "</del></td></tr>\n");
+ }
+ }
+
+ function _context($lines) {
+ foreach ($lines as $line) {
+ print('<tr><td '.HTMLDiff::css('diff-lineheader').'>&#160;</td><td '.HTMLDiff::css('diff-context').'>'. $this->_escape($line) ."</td></tr>\n");
+ }
+ }
+
+ function _changed($orig, $closing) {
+ $diff = new InlineWordLevelDiff($orig, $closing); // this escapes the diff data
+ $add = $diff->inline();
+
+ foreach ($add as $line)
+ print('<tr><td '.HTMLDiff::css('diff-lineheader').'>&#160;</td><td>'.$line."</td></tr>\n");
+ }
+
+ function _escape($str) {
+ return hsc($str);
+ }
+}
+
+/**
+ * A class for computing three way diffs.
+ *
+ * @author Geoffrey T. Dairiki <dairiki@dairiki.org>
+ */
+class Diff3 extends Diff {
+
+ /**
+ * Conflict counter.
+ *
+ * @var integer
+ */
+ var $_conflictingBlocks = 0;
+
+ /**
+ * Computes diff between 3 sequences of strings.
+ *
+ * @param array $orig The original lines to use.
+ * @param array $final1 The first version to compare to.
+ * @param array $final2 The second version to compare to.
+ */
+ function __construct($orig, $final1, $final2) {
+ $engine = new _DiffEngine();
+
+ $this->_edits = $this->_diff3($engine->diff($orig, $final1),
+ $engine->diff($orig, $final2));
+ }
+
+ /**
+ * Returns the merged lines
+ *
+ * @param string $label1 label for first version
+ * @param string $label2 label for second version
+ * @param string $label3 separator between versions
+ * @return array lines of the merged text
+ */
+ function mergedOutput($label1='<<<<<<<',$label2='>>>>>>>',$label3='=======') {
+ $lines = array();
+ foreach ($this->_edits as $edit) {
+ if ($edit->isConflict()) {
+ /* FIXME: this should probably be moved somewhere else. */
+ $lines = array_merge($lines,
+ array($label1),
+ $edit->final1,
+ array($label3),
+ $edit->final2,
+ array($label2));
+ $this->_conflictingBlocks++;
+ } else {
+ $lines = array_merge($lines, $edit->merged());
+ }
+ }
+
+ return $lines;
+ }
+
+ /**
+ * @access private
+ *
+ * @param array $edits1
+ * @param array $edits2
+ *
+ * @return array
+ */
+ function _diff3($edits1, $edits2) {
+ $edits = array();
+ $bb = new _Diff3_BlockBuilder();
+
+ $e1 = current($edits1);
+ $e2 = current($edits2);
+ while ($e1 || $e2) {
+ if ($e1 && $e2 && is_a($e1, '_DiffOp_copy') && is_a($e2, '_DiffOp_copy')) {
+ /* We have copy blocks from both diffs. This is the (only)
+ * time we want to emit a diff3 copy block. Flush current
+ * diff3 diff block, if any. */
+ if ($edit = $bb->finish()) {
+ $edits[] = $edit;
+ }
+
+ $ncopy = min($e1->norig(), $e2->norig());
+ assert($ncopy > 0);
+ $edits[] = new _Diff3_Op_copy(array_slice($e1->orig, 0, $ncopy));
+
+ if ($e1->norig() > $ncopy) {
+ array_splice($e1->orig, 0, $ncopy);
+ array_splice($e1->closing, 0, $ncopy);
+ } else {
+ $e1 = next($edits1);
+ }
+
+ if ($e2->norig() > $ncopy) {
+ array_splice($e2->orig, 0, $ncopy);
+ array_splice($e2->closing, 0, $ncopy);
+ } else {
+ $e2 = next($edits2);
+ }
+ } else {
+ if ($e1 && $e2) {
+ if ($e1->orig && $e2->orig) {
+ $norig = min($e1->norig(), $e2->norig());
+ $orig = array_splice($e1->orig, 0, $norig);
+ array_splice($e2->orig, 0, $norig);
+ $bb->input($orig);
+ }
+
+ if (is_a($e1, '_DiffOp_copy')) {
+ $bb->out1(array_splice($e1->closing, 0, $norig));
+ }
+
+ if (is_a($e2, '_DiffOp_copy')) {
+ $bb->out2(array_splice($e2->closing, 0, $norig));
+ }
+ }
+
+ if ($e1 && ! $e1->orig) {
+ $bb->out1($e1->closing);
+ $e1 = next($edits1);
+ }
+ if ($e2 && ! $e2->orig) {
+ $bb->out2($e2->closing);
+ $e2 = next($edits2);
+ }
+ }
+ }
+
+ if ($edit = $bb->finish()) {
+ $edits[] = $edit;
+ }
+
+ return $edits;
+ }
+}
+
+/**
+ * @author Geoffrey T. Dairiki <dairiki@dairiki.org>
+ *
+ * @access private
+ */
+class _Diff3_Op {
+
+ function __construct($orig = false, $final1 = false, $final2 = false) {
+ $this->orig = $orig ? $orig : array();
+ $this->final1 = $final1 ? $final1 : array();
+ $this->final2 = $final2 ? $final2 : array();
+ }
+
+ function merged() {
+ if (!isset($this->_merged)) {
+ if ($this->final1 === $this->final2) {
+ $this->_merged = &$this->final1;
+ } elseif ($this->final1 === $this->orig) {
+ $this->_merged = &$this->final2;
+ } elseif ($this->final2 === $this->orig) {
+ $this->_merged = &$this->final1;
+ } else {
+ $this->_merged = false;
+ }
+ }
+
+ return $this->_merged;
+ }
+
+ function isConflict() {
+ return $this->merged() === false;
+ }
+
+}
+
+/**
+ * @author Geoffrey T. Dairiki <dairiki@dairiki.org>
+ *
+ * @access private
+ */
+class _Diff3_Op_copy extends _Diff3_Op {
+
+ function __construct($lines = false) {
+ $this->orig = $lines ? $lines : array();
+ $this->final1 = &$this->orig;
+ $this->final2 = &$this->orig;
+ }
+
+ function merged() {
+ return $this->orig;
+ }
+
+ function isConflict() {
+ return false;
+ }
+}
+
+/**
+ * @author Geoffrey T. Dairiki <dairiki@dairiki.org>
+ *
+ * @access private
+ */
+class _Diff3_BlockBuilder {
+
+ function __construct() {
+ $this->_init();
+ }
+
+ function input($lines) {
+ if ($lines) {
+ $this->_append($this->orig, $lines);
+ }
+ }
+
+ function out1($lines) {
+ if ($lines) {
+ $this->_append($this->final1, $lines);
+ }
+ }
+
+ function out2($lines) {
+ if ($lines) {
+ $this->_append($this->final2, $lines);
+ }
+ }
+
+ function isEmpty() {
+ return !$this->orig && !$this->final1 && !$this->final2;
+ }
+
+ function finish() {
+ if ($this->isEmpty()) {
+ return false;
+ } else {
+ $edit = new _Diff3_Op($this->orig, $this->final1, $this->final2);
+ $this->_init();
+ return $edit;
+ }
+ }
+
+ function _init() {
+ $this->orig = $this->final1 = $this->final2 = array();
+ }
+
+ function _append(&$array, $lines) {
+ array_splice($array, sizeof($array), 0, $lines);
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/inc/Draft.php b/platform/www/inc/Draft.php
new file mode 100644
index 0000000..f80016c
--- /dev/null
+++ b/platform/www/inc/Draft.php
@@ -0,0 +1,165 @@
+<?php
+
+namespace dokuwiki;
+
+/**
+ * Class Draft
+ *
+ * @package dokuwiki
+ */
+class Draft
+{
+
+ protected $errors = [];
+ protected $cname;
+ protected $id;
+ protected $client;
+
+ /**
+ * Draft constructor.
+ *
+ * @param string $ID the page id for this draft
+ * @param string $client the client identification (username or ip or similar) for this draft
+ */
+ public function __construct($ID, $client)
+ {
+ $this->id = $ID;
+ $this->client = $client;
+ $this->cname = getCacheName($client.$ID, '.draft');
+ if(file_exists($this->cname) && file_exists(wikiFN($ID))) {
+ if (filemtime($this->cname) < filemtime(wikiFN($ID))) {
+ // remove stale draft
+ $this->deleteDraft();
+ }
+ }
+ }
+
+ /**
+ * Get the filename for this draft (whether or not it exists)
+ *
+ * @return string
+ */
+ public function getDraftFilename()
+ {
+ return $this->cname;
+ }
+
+ /**
+ * Checks if this draft exists on the filesystem
+ *
+ * @return bool
+ */
+ public function isDraftAvailable()
+ {
+ return file_exists($this->cname);
+ }
+
+ /**
+ * Save a draft of a current edit session
+ *
+ * The draft will not be saved if
+ * - drafts are deactivated in the config
+ * - or the editarea is empty and there are no event handlers registered
+ * - or the event is prevented
+ *
+ * @triggers DRAFT_SAVE
+ *
+ * @return bool whether has the draft been saved
+ */
+ public function saveDraft()
+ {
+ global $INPUT, $INFO, $EVENT_HANDLER, $conf;
+ if (!$conf['usedraft']) {
+ return false;
+ }
+ if (!$INPUT->post->has('wikitext') &&
+ !$EVENT_HANDLER->hasHandlerForEvent('DRAFT_SAVE')) {
+ return false;
+ }
+ $draft = [
+ 'id' => $this->id,
+ 'prefix' => substr($INPUT->post->str('prefix'), 0, -1),
+ 'text' => $INPUT->post->str('wikitext'),
+ 'suffix' => $INPUT->post->str('suffix'),
+ 'date' => $INPUT->post->int('date'),
+ 'client' => $this->client,
+ 'cname' => $this->cname,
+ 'errors' => [],
+ ];
+ $event = new Extension\Event('DRAFT_SAVE', $draft);
+ if ($event->advise_before()) {
+ $draft['hasBeenSaved'] = io_saveFile($draft['cname'], serialize($draft));
+ if ($draft['hasBeenSaved']) {
+ $INFO['draft'] = $draft['cname'];
+ }
+ } else {
+ $draft['hasBeenSaved'] = false;
+ }
+ $event->advise_after();
+
+ $this->errors = $draft['errors'];
+
+ return $draft['hasBeenSaved'];
+ }
+
+ /**
+ * Get the text from the draft file
+ *
+ * @throws \RuntimeException if the draft file doesn't exist
+ *
+ * @return string
+ */
+ public function getDraftText()
+ {
+ if (!file_exists($this->cname)) {
+ throw new \RuntimeException(
+ "Draft for page $this->id and user $this->client doesn't exist at $this->cname."
+ );
+ }
+ $draft = unserialize(io_readFile($this->cname,false));
+ return cleanText(con($draft['prefix'],$draft['text'],$draft['suffix'],true));
+ }
+
+ /**
+ * Remove the draft from the filesystem
+ *
+ * Also sets $INFO['draft'] to null
+ */
+ public function deleteDraft()
+ {
+ global $INFO;
+ @unlink($this->cname);
+ $INFO['draft'] = null;
+ }
+
+ /**
+ * Get a formatted message stating when the draft was saved
+ *
+ * @return string
+ */
+ public function getDraftMessage()
+ {
+ global $lang;
+ return $lang['draftdate'] . ' ' . dformat(filemtime($this->cname));
+ }
+
+ /**
+ * Retrieve the errors that occured when saving the draft
+ *
+ * @return array
+ */
+ public function getErrors()
+ {
+ return $this->errors;
+ }
+
+ /**
+ * Get the timestamp when this draft was saved
+ *
+ * @return int
+ */
+ public function getDraftDate()
+ {
+ return filemtime($this->cname);
+ }
+}
diff --git a/platform/www/inc/Extension/ActionPlugin.php b/platform/www/inc/Extension/ActionPlugin.php
new file mode 100644
index 0000000..ed6d820
--- /dev/null
+++ b/platform/www/inc/Extension/ActionPlugin.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace dokuwiki\Extension;
+
+/**
+ * Action Plugin Prototype
+ *
+ * Handles action hooks within a plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+abstract class ActionPlugin extends Plugin
+{
+
+ /**
+ * Registers a callback function for a given event
+ *
+ * @param \Doku_Event_Handler $controller
+ */
+ abstract public function register(\Doku_Event_Handler $controller);
+}
diff --git a/platform/www/inc/Extension/AdminPlugin.php b/platform/www/inc/Extension/AdminPlugin.php
new file mode 100644
index 0000000..7900a1e
--- /dev/null
+++ b/platform/www/inc/Extension/AdminPlugin.php
@@ -0,0 +1,123 @@
+<?php
+
+namespace dokuwiki\Extension;
+
+/**
+ * Admin Plugin Prototype
+ *
+ * Implements an admin interface in a plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+abstract class AdminPlugin extends Plugin
+{
+
+ /**
+ * Return the text that is displayed at the main admin menu
+ * (Default localized language string 'menu' is returned, override this function for setting another name)
+ *
+ * @param string $language language code
+ * @return string menu string
+ */
+ public function getMenuText($language)
+ {
+ $menutext = $this->getLang('menu');
+ if (!$menutext) {
+ $info = $this->getInfo();
+ $menutext = $info['name'] . ' ...';
+ }
+ return $menutext;
+ }
+
+ /**
+ * Return the path to the icon being displayed in the main admin menu.
+ * By default it tries to find an 'admin.svg' file in the plugin directory.
+ * (Override this function for setting another image)
+ *
+ * Important: you have to return a single path, monochrome SVG icon! It has to be
+ * under 2 Kilobytes!
+ *
+ * We recommend icons from https://materialdesignicons.com/ or to use a matching
+ * style.
+ *
+ * @return string full path to the icon file
+ */
+ public function getMenuIcon()
+ {
+ $plugin = $this->getPluginName();
+ return DOKU_PLUGIN . $plugin . '/admin.svg';
+ }
+
+ /**
+ * Determine position in list in admin window
+ * Lower values are sorted up
+ *
+ * @return int
+ */
+ public function getMenuSort()
+ {
+ return 1000;
+ }
+
+ /**
+ * Carry out required processing
+ */
+ public function handle()
+ {
+ // some plugins might not need this
+ }
+
+ /**
+ * Output html of the admin page
+ */
+ abstract public function html();
+
+ /**
+ * Checks if access should be granted to this admin plugin
+ *
+ * @return bool true if the current user may access this admin plugin
+ */
+ public function isAccessibleByCurrentUser() {
+ $data = [];
+ $data['instance'] = $this;
+ $data['hasAccess'] = false;
+
+ $event = new Event('ADMINPLUGIN_ACCESS_CHECK', $data);
+ if($event->advise_before()) {
+ if ($this->forAdminOnly()) {
+ $data['hasAccess'] = auth_isadmin();
+ } else {
+ $data['hasAccess'] = auth_ismanager();
+ }
+ }
+ $event->advise_after();
+
+ return $data['hasAccess'];
+ }
+
+ /**
+ * Return true for access only by admins (config:superuser) or false if managers are allowed as well
+ *
+ * @return bool
+ */
+ public function forAdminOnly()
+ {
+ return true;
+ }
+
+ /**
+ * Return array with ToC items. Items can be created with the html_mktocitem()
+ *
+ * @see html_mktocitem()
+ * @see tpl_toc()
+ *
+ * @return array
+ */
+ public function getTOC()
+ {
+ return array();
+ }
+
+}
+
diff --git a/platform/www/inc/Extension/AuthPlugin.php b/platform/www/inc/Extension/AuthPlugin.php
new file mode 100644
index 0000000..4b75fba
--- /dev/null
+++ b/platform/www/inc/Extension/AuthPlugin.php
@@ -0,0 +1,461 @@
+<?php
+
+namespace dokuwiki\Extension;
+
+/**
+ * Auth Plugin Prototype
+ *
+ * allows to authenticate users in a plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Jan Schumann <js@jschumann-it.com>
+ */
+abstract class AuthPlugin extends Plugin
+{
+ public $success = true;
+
+ /**
+ * Possible things an auth backend module may be able to
+ * do. The things a backend can do need to be set to true
+ * in the constructor.
+ */
+ protected $cando = array(
+ 'addUser' => false, // can Users be created?
+ 'delUser' => false, // can Users be deleted?
+ 'modLogin' => false, // can login names be changed?
+ 'modPass' => false, // can passwords be changed?
+ 'modName' => false, // can real names be changed?
+ 'modMail' => false, // can emails be changed?
+ 'modGroups' => false, // can groups be changed?
+ 'getUsers' => false, // can a (filtered) list of users be retrieved?
+ 'getUserCount' => false, // can the number of users be retrieved?
+ 'getGroups' => false, // can a list of available groups be retrieved?
+ 'external' => false, // does the module do external auth checking?
+ 'logout' => true, // can the user logout again? (eg. not possible with HTTP auth)
+ );
+
+ /**
+ * Constructor.
+ *
+ * Carry out sanity checks to ensure the object is
+ * able to operate. Set capabilities in $this->cando
+ * array here
+ *
+ * For future compatibility, sub classes should always include a call
+ * to parent::__constructor() in their constructors!
+ *
+ * Set $this->success to false if checks fail
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+ public function __construct()
+ {
+ // the base class constructor does nothing, derived class
+ // constructors do the real work
+ }
+
+ /**
+ * Available Capabilities. [ DO NOT OVERRIDE ]
+ *
+ * For introspection/debugging
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @return array
+ */
+ public function getCapabilities()
+ {
+ return array_keys($this->cando);
+ }
+
+ /**
+ * Capability check. [ DO NOT OVERRIDE ]
+ *
+ * Checks the capabilities set in the $this->cando array and
+ * some pseudo capabilities (shortcutting access to multiple
+ * ones)
+ *
+ * ususal capabilities start with lowercase letter
+ * shortcut capabilities start with uppercase letter
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $cap the capability to check
+ * @return bool
+ */
+ public function canDo($cap)
+ {
+ switch ($cap) {
+ case 'Profile':
+ // can at least one of the user's properties be changed?
+ return ($this->cando['modPass'] ||
+ $this->cando['modName'] ||
+ $this->cando['modMail']);
+ break;
+ case 'UserMod':
+ // can at least anything be changed?
+ return ($this->cando['modPass'] ||
+ $this->cando['modName'] ||
+ $this->cando['modMail'] ||
+ $this->cando['modLogin'] ||
+ $this->cando['modGroups'] ||
+ $this->cando['modMail']);
+ break;
+ default:
+ // print a helping message for developers
+ if (!isset($this->cando[$cap])) {
+ msg("Check for unknown capability '$cap' - Do you use an outdated Plugin?", -1);
+ }
+ return $this->cando[$cap];
+ }
+ }
+
+ /**
+ * Trigger the AUTH_USERDATA_CHANGE event and call the modification function. [ DO NOT OVERRIDE ]
+ *
+ * You should use this function instead of calling createUser, modifyUser or
+ * deleteUsers directly. The event handlers can prevent the modification, for
+ * example for enforcing a user name schema.
+ *
+ * @author Gabriel Birke <birke@d-scribe.de>
+ * @param string $type Modification type ('create', 'modify', 'delete')
+ * @param array $params Parameters for the createUser, modifyUser or deleteUsers method.
+ * The content of this array depends on the modification type
+ * @return bool|null|int Result from the modification function or false if an event handler has canceled the action
+ */
+ public function triggerUserMod($type, $params)
+ {
+ $validTypes = array(
+ 'create' => 'createUser',
+ 'modify' => 'modifyUser',
+ 'delete' => 'deleteUsers',
+ );
+ if (empty($validTypes[$type])) {
+ return false;
+ }
+
+ $result = false;
+ $eventdata = array('type' => $type, 'params' => $params, 'modification_result' => null);
+ $evt = new Event('AUTH_USER_CHANGE', $eventdata);
+ if ($evt->advise_before(true)) {
+ $result = call_user_func_array(array($this, $validTypes[$type]), $evt->data['params']);
+ $evt->data['modification_result'] = $result;
+ }
+ $evt->advise_after();
+ unset($evt);
+ return $result;
+ }
+
+ /**
+ * Log off the current user [ OPTIONAL ]
+ *
+ * Is run in addition to the ususal logoff method. Should
+ * only be needed when trustExternal is implemented.
+ *
+ * @see auth_logoff()
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function logOff()
+ {
+ }
+
+ /**
+ * Do all authentication [ OPTIONAL ]
+ *
+ * Set $this->cando['external'] = true when implemented
+ *
+ * If this function is implemented it will be used to
+ * authenticate a user - all other DokuWiki internals
+ * will not be used for authenticating (except this
+ * function returns null, in which case, DokuWiki will
+ * still run auth_login as a fallback, which may call
+ * checkPass()). If this function is not returning null,
+ * implementing checkPass() is not needed here anymore.
+ *
+ * The function can be used to authenticate against third
+ * party cookies or Apache auth mechanisms and replaces
+ * the auth_login() function
+ *
+ * The function will be called with or without a set
+ * username. If the Username is given it was called
+ * from the login form and the given credentials might
+ * need to be checked. If no username was given it
+ * the function needs to check if the user is logged in
+ * by other means (cookie, environment).
+ *
+ * The function needs to set some globals needed by
+ * DokuWiki like auth_login() does.
+ *
+ * @see auth_login()
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $user Username
+ * @param string $pass Cleartext Password
+ * @param bool $sticky Cookie should not expire
+ * @return bool true on successful auth,
+ * null on unknown result (fallback to checkPass)
+ */
+ public function trustExternal($user, $pass, $sticky = false)
+ {
+ /* some example:
+
+ global $USERINFO;
+ global $conf;
+ $sticky ? $sticky = true : $sticky = false; //sanity check
+
+ // do the checking here
+
+ // set the globals if authed
+ $USERINFO['name'] = 'FIXME';
+ $USERINFO['mail'] = 'FIXME';
+ $USERINFO['grps'] = array('FIXME');
+ $_SERVER['REMOTE_USER'] = $user;
+ $_SESSION[DOKU_COOKIE]['auth']['user'] = $user;
+ $_SESSION[DOKU_COOKIE]['auth']['pass'] = $pass;
+ $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
+ return true;
+
+ */
+ }
+
+ /**
+ * Check user+password [ MUST BE OVERRIDDEN ]
+ *
+ * Checks if the given user exists and the given
+ * plaintext password is correct
+ *
+ * May be ommited if trustExternal is used.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $user the user name
+ * @param string $pass the clear text password
+ * @return bool
+ */
+ public function checkPass($user, $pass)
+ {
+ msg("no valid authorisation system in use", -1);
+ return false;
+ }
+
+ /**
+ * Return user info [ MUST BE OVERRIDDEN ]
+ *
+ * Returns info about the given user needs to contain
+ * at least these fields:
+ *
+ * name string full name of the user
+ * mail string email address of the user
+ * grps array list of groups the user is in
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $user the user name
+ * @param bool $requireGroups whether or not the returned data must include groups
+ * @return false|array containing user data or false
+ */
+ public function getUserData($user, $requireGroups = true)
+ {
+ if (!$this->cando['external']) msg("no valid authorisation system in use", -1);
+ return false;
+ }
+
+ /**
+ * Create a new User [implement only where required/possible]
+ *
+ * Returns false if the user already exists, null when an error
+ * occurred and true if everything went well.
+ *
+ * The new user HAS TO be added to the default group by this
+ * function!
+ *
+ * Set addUser capability when implemented
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $user
+ * @param string $pass
+ * @param string $name
+ * @param string $mail
+ * @param null|array $grps
+ * @return bool|null
+ */
+ public function createUser($user, $pass, $name, $mail, $grps = null)
+ {
+ msg("authorisation method does not allow creation of new users", -1);
+ return null;
+ }
+
+ /**
+ * Modify user data [implement only where required/possible]
+ *
+ * Set the mod* capabilities according to the implemented features
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param string $user nick of the user to be changed
+ * @param array $changes array of field/value pairs to be changed (password will be clear text)
+ * @return bool
+ */
+ public function modifyUser($user, $changes)
+ {
+ msg("authorisation method does not allow modifying of user data", -1);
+ return false;
+ }
+
+ /**
+ * Delete one or more users [implement only where required/possible]
+ *
+ * Set delUser capability when implemented
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param array $users
+ * @return int number of users deleted
+ */
+ public function deleteUsers($users)
+ {
+ msg("authorisation method does not allow deleting of users", -1);
+ return 0;
+ }
+
+ /**
+ * Return a count of the number of user which meet $filter criteria
+ * [should be implemented whenever retrieveUsers is implemented]
+ *
+ * Set getUserCount capability when implemented
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param array $filter array of field/pattern pairs, empty array for no filter
+ * @return int
+ */
+ public function getUserCount($filter = array())
+ {
+ msg("authorisation method does not provide user counts", -1);
+ return 0;
+ }
+
+ /**
+ * Bulk retrieval of user data [implement only where required/possible]
+ *
+ * Set getUsers capability when implemented
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param int $start index of first user to be returned
+ * @param int $limit max number of users to be returned, 0 for unlimited
+ * @param array $filter array of field/pattern pairs, null for no filter
+ * @return array list of userinfo (refer getUserData for internal userinfo details)
+ */
+ public function retrieveUsers($start = 0, $limit = 0, $filter = null)
+ {
+ msg("authorisation method does not support mass retrieval of user data", -1);
+ return array();
+ }
+
+ /**
+ * Define a group [implement only where required/possible]
+ *
+ * Set addGroup capability when implemented
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param string $group
+ * @return bool
+ */
+ public function addGroup($group)
+ {
+ msg("authorisation method does not support independent group creation", -1);
+ return false;
+ }
+
+ /**
+ * Retrieve groups [implement only where required/possible]
+ *
+ * Set getGroups capability when implemented
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param int $start
+ * @param int $limit
+ * @return array
+ */
+ public function retrieveGroups($start = 0, $limit = 0)
+ {
+ msg("authorisation method does not support group list retrieval", -1);
+ return array();
+ }
+
+ /**
+ * Return case sensitivity of the backend [OPTIONAL]
+ *
+ * When your backend is caseinsensitive (eg. you can login with USER and
+ * user) then you need to overwrite this method and return false
+ *
+ * @return bool
+ */
+ public function isCaseSensitive()
+ {
+ return true;
+ }
+
+ /**
+ * Sanitize a given username [OPTIONAL]
+ *
+ * This function is applied to any user name that is given to
+ * the backend and should also be applied to any user name within
+ * the backend before returning it somewhere.
+ *
+ * This should be used to enforce username restrictions.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $user username
+ * @return string the cleaned username
+ */
+ public function cleanUser($user)
+ {
+ return $user;
+ }
+
+ /**
+ * Sanitize a given groupname [OPTIONAL]
+ *
+ * This function is applied to any groupname that is given to
+ * the backend and should also be applied to any groupname within
+ * the backend before returning it somewhere.
+ *
+ * This should be used to enforce groupname restrictions.
+ *
+ * Groupnames are to be passed without a leading '@' here.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $group groupname
+ * @return string the cleaned groupname
+ */
+ public function cleanGroup($group)
+ {
+ return $group;
+ }
+
+ /**
+ * Check Session Cache validity [implement only where required/possible]
+ *
+ * DokuWiki caches user info in the user's session for the timespan defined
+ * in $conf['auth_security_timeout'].
+ *
+ * This makes sure slow authentication backends do not slow down DokuWiki.
+ * This also means that changes to the user database will not be reflected
+ * on currently logged in users.
+ *
+ * To accommodate for this, the user manager plugin will touch a reference
+ * file whenever a change is submitted. This function compares the filetime
+ * of this reference file with the time stored in the session.
+ *
+ * This reference file mechanism does not reflect changes done directly in
+ * the backend's database through other means than the user manager plugin.
+ *
+ * Fast backends might want to return always false, to force rechecks on
+ * each page load. Others might want to use their own checking here. If
+ * unsure, do not override.
+ *
+ * @param string $user - The username
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @return bool
+ */
+ public function useSessionCache($user)
+ {
+ global $conf;
+ return ($_SESSION[DOKU_COOKIE]['auth']['time'] >= @filemtime($conf['cachedir'] . '/sessionpurge'));
+ }
+}
diff --git a/platform/www/inc/Extension/CLIPlugin.php b/platform/www/inc/Extension/CLIPlugin.php
new file mode 100644
index 0000000..8637ccf
--- /dev/null
+++ b/platform/www/inc/Extension/CLIPlugin.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace dokuwiki\Extension;
+
+/**
+ * CLI plugin prototype
+ *
+ * Provides DokuWiki plugin functionality on top of php-cli
+ */
+abstract class CLIPlugin extends \splitbrain\phpcli\CLI implements PluginInterface
+{
+ use PluginTrait;
+}
diff --git a/platform/www/inc/Extension/Event.php b/platform/www/inc/Extension/Event.php
new file mode 100644
index 0000000..32f346c
--- /dev/null
+++ b/platform/www/inc/Extension/Event.php
@@ -0,0 +1,197 @@
+<?php
+// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
+
+namespace dokuwiki\Extension;
+
+/**
+ * The Action plugin event
+ */
+class Event
+{
+ /** @var string READONLY event name, objects must register against this name to see the event */
+ public $name = '';
+ /** @var mixed|null READWRITE data relevant to the event, no standardised format, refer to event docs */
+ public $data = null;
+ /**
+ * @var mixed|null READWRITE the results of the event action, only relevant in "_AFTER" advise
+ * event handlers may modify this if they are preventing the default action
+ * to provide the after event handlers with event results
+ */
+ public $result = null;
+ /** @var bool READONLY if true, event handlers can prevent the events default action */
+ public $canPreventDefault = true;
+
+ /** @var bool whether or not to carry out the default action associated with the event */
+ protected $runDefault = true;
+ /** @var bool whether or not to continue propagating the event to other handlers */
+ protected $mayContinue = true;
+
+ /**
+ * event constructor
+ *
+ * @param string $name
+ * @param mixed $data
+ */
+ public function __construct($name, &$data)
+ {
+
+ $this->name = $name;
+ $this->data =& $data;
+ }
+
+ /**
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->name;
+ }
+
+ /**
+ * advise all registered BEFORE handlers of this event
+ *
+ * if these methods are used by functions outside of this object, they must
+ * properly handle correct processing of any default action and issue an
+ * advise_after() signal. e.g.
+ * $evt = new dokuwiki\Plugin\Doku_Event(name, data);
+ * if ($evt->advise_before(canPreventDefault) {
+ * // default action code block
+ * }
+ * $evt->advise_after();
+ * unset($evt);
+ *
+ * @param bool $enablePreventDefault
+ * @return bool results of processing the event, usually $this->runDefault
+ */
+ public function advise_before($enablePreventDefault = true)
+ {
+ global $EVENT_HANDLER;
+
+ $this->canPreventDefault = $enablePreventDefault;
+ if ($EVENT_HANDLER !== null) {
+ $EVENT_HANDLER->process_event($this, 'BEFORE');
+ } else {
+ dbglog($this->name . ':BEFORE event triggered before event system was initialized');
+ }
+
+ return (!$enablePreventDefault || $this->runDefault);
+ }
+
+ /**
+ * advise all registered AFTER handlers of this event
+ *
+ * @param bool $enablePreventDefault
+ * @see advise_before() for details
+ */
+ public function advise_after()
+ {
+ global $EVENT_HANDLER;
+
+ $this->mayContinue = true;
+
+ if ($EVENT_HANDLER !== null) {
+ $EVENT_HANDLER->process_event($this, 'AFTER');
+ } else {
+ dbglog($this->name . ':AFTER event triggered before event system was initialized');
+ }
+ }
+
+ /**
+ * trigger
+ *
+ * - advise all registered (<event>_BEFORE) handlers that this event is about to take place
+ * - carry out the default action using $this->data based on $enablePrevent and
+ * $this->_default, all of which may have been modified by the event handlers.
+ * - advise all registered (<event>_AFTER) handlers that the event has taken place
+ *
+ * @param null|callable $action
+ * @param bool $enablePrevent
+ * @return mixed $event->results
+ * the value set by any <event>_before or <event> handlers if the default action is prevented
+ * or the results of the default action (as modified by <event>_after handlers)
+ * or NULL no action took place and no handler modified the value
+ */
+ public function trigger($action = null, $enablePrevent = true)
+ {
+
+ if (!is_callable($action)) {
+ $enablePrevent = false;
+ if ($action !== null) {
+ trigger_error(
+ 'The default action of ' . $this .
+ ' is not null but also not callable. Maybe the method is not public?',
+ E_USER_WARNING
+ );
+ }
+ }
+
+ if ($this->advise_before($enablePrevent) && is_callable($action)) {
+ $this->result = call_user_func_array($action, [&$this->data]);
+ }
+
+ $this->advise_after();
+
+ return $this->result;
+ }
+
+ /**
+ * stopPropagation
+ *
+ * stop any further processing of the event by event handlers
+ * this function does not prevent the default action taking place
+ */
+ public function stopPropagation()
+ {
+ $this->mayContinue = false;
+ }
+
+ /**
+ * may the event propagate to the next handler?
+ *
+ * @return bool
+ */
+ public function mayPropagate()
+ {
+ return $this->mayContinue;
+ }
+
+ /**
+ * preventDefault
+ *
+ * prevent the default action taking place
+ */
+ public function preventDefault()
+ {
+ $this->runDefault = false;
+ }
+
+ /**
+ * should the default action be executed?
+ *
+ * @return bool
+ */
+ public function mayRunDefault()
+ {
+ return $this->runDefault;
+ }
+
+ /**
+ * Convenience method to trigger an event
+ *
+ * Creates, triggers and destroys an event in one go
+ *
+ * @param string $name name for the event
+ * @param mixed $data event data
+ * @param callable $action (optional, default=NULL) default action, a php callback function
+ * @param bool $canPreventDefault (optional, default=true) can hooks prevent the default action
+ *
+ * @return mixed the event results value after all event processing is complete
+ * by default this is the return value of the default action however
+ * it can be set or modified by event handler hooks
+ */
+ static public function createAndTrigger($name, &$data, $action = null, $canPreventDefault = true)
+ {
+ $evt = new Event($name, $data);
+ return $evt->trigger($action, $canPreventDefault);
+ }
+}
diff --git a/platform/www/inc/Extension/EventHandler.php b/platform/www/inc/Extension/EventHandler.php
new file mode 100644
index 0000000..7bed0fe
--- /dev/null
+++ b/platform/www/inc/Extension/EventHandler.php
@@ -0,0 +1,108 @@
+<?php
+// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
+
+namespace dokuwiki\Extension;
+
+/**
+ * Controls the registration and execution of all events,
+ */
+class EventHandler
+{
+
+ // public properties: none
+
+ // private properties
+ protected $hooks = array(); // array of events and their registered handlers
+
+ /**
+ * event_handler
+ *
+ * constructor, loads all action plugins and calls their register() method giving them
+ * an opportunity to register any hooks they require
+ */
+ public function __construct()
+ {
+
+ // load action plugins
+ /** @var ActionPlugin $plugin */
+ $plugin = null;
+ $pluginlist = plugin_list('action');
+
+ foreach ($pluginlist as $plugin_name) {
+ $plugin = plugin_load('action', $plugin_name);
+
+ if ($plugin !== null) $plugin->register($this);
+ }
+ }
+
+ /**
+ * register_hook
+ *
+ * register a hook for an event
+ *
+ * @param string $event string name used by the event, (incl '_before' or '_after' for triggers)
+ * @param string $advise
+ * @param object $obj object in whose scope method is to be executed,
+ * if NULL, method is assumed to be a globally available function
+ * @param string $method event handler function
+ * @param mixed $param data passed to the event handler
+ * @param int $seq sequence number for ordering hook execution (ascending)
+ */
+ public function register_hook($event, $advise, $obj, $method, $param = null, $seq = 0)
+ {
+ $seq = (int)$seq;
+ $doSort = !isset($this->hooks[$event . '_' . $advise][$seq]);
+ $this->hooks[$event . '_' . $advise][$seq][] = array($obj, $method, $param);
+
+ if ($doSort) {
+ ksort($this->hooks[$event . '_' . $advise]);
+ }
+ }
+
+ /**
+ * process the before/after event
+ *
+ * @param Event $event
+ * @param string $advise BEFORE or AFTER
+ */
+ public function process_event($event, $advise = '')
+ {
+
+ $evt_name = $event->name . ($advise ? '_' . $advise : '_BEFORE');
+
+ if (!empty($this->hooks[$evt_name])) {
+ foreach ($this->hooks[$evt_name] as $sequenced_hooks) {
+ foreach ($sequenced_hooks as $hook) {
+ list($obj, $method, $param) = $hook;
+
+ if ($obj === null) {
+ $method($event, $param);
+ } else {
+ $obj->$method($event, $param);
+ }
+
+ if (!$event->mayPropagate()) return;
+ }
+ }
+ }
+ }
+
+ /**
+ * Check if an event has any registered handlers
+ *
+ * When $advise is empty, both BEFORE and AFTER events will be considered,
+ * otherwise only the given advisory is checked
+ *
+ * @param string $name Name of the event
+ * @param string $advise BEFORE, AFTER or empty
+ * @return bool
+ */
+ public function hasHandlerForEvent($name, $advise = '')
+ {
+ if ($advise) {
+ return isset($this->hooks[$name . '_' . $advise]);
+ }
+
+ return isset($this->hooks[$name . '_BEFORE']) || isset($this->hooks[$name . '_AFTER']);
+ }
+}
diff --git a/platform/www/inc/Extension/Plugin.php b/platform/www/inc/Extension/Plugin.php
new file mode 100644
index 0000000..03637fe
--- /dev/null
+++ b/platform/www/inc/Extension/Plugin.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace dokuwiki\Extension;
+
+/**
+ * DokuWiki Base Plugin
+ *
+ * Most plugin types inherit from this class
+ */
+abstract class Plugin implements PluginInterface
+{
+ use PluginTrait;
+}
diff --git a/platform/www/inc/Extension/PluginController.php b/platform/www/inc/Extension/PluginController.php
new file mode 100644
index 0000000..638fd39
--- /dev/null
+++ b/platform/www/inc/Extension/PluginController.php
@@ -0,0 +1,393 @@
+<?php
+
+namespace dokuwiki\Extension;
+
+/**
+ * Class to encapsulate access to dokuwiki plugins
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+class PluginController
+{
+ /** @var array the types of plugins DokuWiki supports */
+ const PLUGIN_TYPES = ['auth', 'admin', 'syntax', 'action', 'renderer', 'helper', 'remote', 'cli'];
+
+ protected $listByType = [];
+ /** @var array all installed plugins and their enabled state [plugin=>enabled] */
+ protected $masterList = [];
+ protected $pluginCascade = ['default' => [], 'local' => [], 'protected' => []];
+ protected $lastLocalConfigFile = '';
+
+ /**
+ * Populates the master list of plugins
+ */
+ public function __construct()
+ {
+ $this->loadConfig();
+ $this->populateMasterList();
+ }
+
+ /**
+ * Returns a list of available plugins of given type
+ *
+ * @param $type string, plugin_type name;
+ * the type of plugin to return,
+ * use empty string for all types
+ * @param $all bool;
+ * false to only return enabled plugins,
+ * true to return both enabled and disabled plugins
+ *
+ * @return array of
+ * - plugin names when $type = ''
+ * - or plugin component names when a $type is given
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function getList($type = '', $all = false)
+ {
+
+ // request the complete list
+ if (!$type) {
+ return $all ? array_keys($this->masterList) : array_keys(array_filter($this->masterList));
+ }
+
+ if (!isset($this->listByType[$type]['enabled'])) {
+ $this->listByType[$type]['enabled'] = $this->getListByType($type, true);
+ }
+ if ($all && !isset($this->listByType[$type]['disabled'])) {
+ $this->listByType[$type]['disabled'] = $this->getListByType($type, false);
+ }
+
+ return $all
+ ? array_merge($this->listByType[$type]['enabled'], $this->listByType[$type]['disabled'])
+ : $this->listByType[$type]['enabled'];
+ }
+
+ /**
+ * Loads the given plugin and creates an object of it
+ *
+ * @param $type string type of plugin to load
+ * @param $name string name of the plugin to load
+ * @param $new bool true to return a new instance of the plugin, false to use an already loaded instance
+ * @param $disabled bool true to load even disabled plugins
+ * @return PluginInterface|null the plugin object or null on failure
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ */
+ public function load($type, $name, $new = false, $disabled = false)
+ {
+
+ //we keep all loaded plugins available in global scope for reuse
+ global $DOKU_PLUGINS;
+
+ list($plugin, /* $component */) = $this->splitName($name);
+
+ // check if disabled
+ if (!$disabled && !$this->isEnabled($plugin)) {
+ return null;
+ }
+
+ $class = $type . '_plugin_' . $name;
+
+ //plugin already loaded?
+ if (!empty($DOKU_PLUGINS[$type][$name])) {
+ if ($new || !$DOKU_PLUGINS[$type][$name]->isSingleton()) {
+ return class_exists($class, true) ? new $class : null;
+ }
+
+ return $DOKU_PLUGINS[$type][$name];
+ }
+
+ //construct class and instantiate
+ if (!class_exists($class, true)) {
+
+ # the plugin might be in the wrong directory
+ $inf = confToHash(DOKU_PLUGIN . "$plugin/plugin.info.txt");
+ if ($inf['base'] && $inf['base'] != $plugin) {
+ msg(
+ sprintf(
+ "Plugin installed incorrectly. Rename plugin directory '%s' to '%s'.",
+ hsc($plugin),
+ hsc(
+ $inf['base']
+ )
+ ), -1
+ );
+ } elseif (preg_match('/^' . DOKU_PLUGIN_NAME_REGEX . '$/', $plugin) !== 1) {
+ msg(
+ sprintf(
+ "Plugin name '%s' is not a valid plugin name, only the characters a-z and 0-9 are allowed. " .
+ 'Maybe the plugin has been installed in the wrong directory?', hsc($plugin)
+ ), -1
+ );
+ }
+ return null;
+ }
+
+ $DOKU_PLUGINS[$type][$name] = new $class;
+ return $DOKU_PLUGINS[$type][$name];
+ }
+
+ /**
+ * Whether plugin is disabled
+ *
+ * @param string $plugin name of plugin
+ * @return bool true disabled, false enabled
+ * @deprecated in favor of the more sensible isEnabled where the return value matches the enabled state
+ */
+ public function isDisabled($plugin)
+ {
+ dbg_deprecated('isEnabled()');
+ return !$this->isEnabled($plugin);
+ }
+
+ /**
+ * Check whether plugin is disabled
+ *
+ * @param string $plugin name of plugin
+ * @return bool true enabled, false disabled
+ */
+ public function isEnabled($plugin)
+ {
+ return !empty($this->masterList[$plugin]);
+ }
+
+ /**
+ * Disable the plugin
+ *
+ * @param string $plugin name of plugin
+ * @return bool true saving succeed, false saving failed
+ */
+ public function disable($plugin)
+ {
+ if (array_key_exists($plugin, $this->pluginCascade['protected'])) return false;
+ $this->masterList[$plugin] = 0;
+ return $this->saveList();
+ }
+
+ /**
+ * Enable the plugin
+ *
+ * @param string $plugin name of plugin
+ * @return bool true saving succeed, false saving failed
+ */
+ public function enable($plugin)
+ {
+ if (array_key_exists($plugin, $this->pluginCascade['protected'])) return false;
+ $this->masterList[$plugin] = 1;
+ return $this->saveList();
+ }
+
+ /**
+ * Returns cascade of the config files
+ *
+ * @return array with arrays of plugin configs
+ */
+ public function getCascade()
+ {
+ return $this->pluginCascade;
+ }
+
+ /**
+ * Read all installed plugins and their current enabled state
+ */
+ protected function populateMasterList()
+ {
+ if ($dh = @opendir(DOKU_PLUGIN)) {
+ $all_plugins = array();
+ while (false !== ($plugin = readdir($dh))) {
+ if ($plugin[0] === '.') continue; // skip hidden entries
+ if (is_file(DOKU_PLUGIN . $plugin)) continue; // skip files, we're only interested in directories
+
+ if (array_key_exists($plugin, $this->masterList) && $this->masterList[$plugin] == 0) {
+ $all_plugins[$plugin] = 0;
+
+ } elseif (array_key_exists($plugin, $this->masterList) && $this->masterList[$plugin] == 1) {
+ $all_plugins[$plugin] = 1;
+ } else {
+ $all_plugins[$plugin] = 1;
+ }
+ }
+ $this->masterList = $all_plugins;
+ if (!file_exists($this->lastLocalConfigFile)) {
+ $this->saveList(true);
+ }
+ }
+ }
+
+ /**
+ * Includes the plugin config $files
+ * and returns the entries of the $plugins array set in these files
+ *
+ * @param array $files list of files to include, latter overrides previous
+ * @return array with entries of the $plugins arrays of the included files
+ */
+ protected function checkRequire($files)
+ {
+ $plugins = array();
+ foreach ($files as $file) {
+ if (file_exists($file)) {
+ include_once($file);
+ }
+ }
+ return $plugins;
+ }
+
+ /**
+ * Save the current list of plugins
+ *
+ * @param bool $forceSave ;
+ * false to save only when config changed
+ * true to always save
+ * @return bool true saving succeed, false saving failed
+ */
+ protected function saveList($forceSave = false)
+ {
+ global $conf;
+
+ if (empty($this->masterList)) return false;
+
+ // Rebuild list of local settings
+ $local_plugins = $this->rebuildLocal();
+ if ($local_plugins != $this->pluginCascade['local'] || $forceSave) {
+ $file = $this->lastLocalConfigFile;
+ $out = "<?php\n/*\n * Local plugin enable/disable settings\n" .
+ " * Auto-generated through plugin/extension manager\n *\n" .
+ " * NOTE: Plugins will not be added to this file unless there " .
+ "is a need to override a default setting. Plugins are\n" .
+ " * enabled by default.\n */\n";
+ foreach ($local_plugins as $plugin => $value) {
+ $out .= "\$plugins['$plugin'] = $value;\n";
+ }
+ // backup current file (remove any existing backup)
+ if (file_exists($file)) {
+ $backup = $file . '.bak';
+ if (file_exists($backup)) @unlink($backup);
+ if (!@copy($file, $backup)) return false;
+ if (!empty($conf['fperm'])) chmod($backup, $conf['fperm']);
+ }
+ //check if can open for writing, else restore
+ return io_saveFile($file, $out);
+ }
+ return false;
+ }
+
+ /**
+ * Rebuild the set of local plugins
+ *
+ * @return array array of plugins to be saved in end($config_cascade['plugins']['local'])
+ */
+ protected function rebuildLocal()
+ {
+ //assign to local variable to avoid overwriting
+ $backup = $this->masterList;
+ //Can't do anything about protected one so rule them out completely
+ $local_default = array_diff_key($backup, $this->pluginCascade['protected']);
+ //Diff between local+default and default
+ //gives us the ones we need to check and save
+ $diffed_ones = array_diff_key($local_default, $this->pluginCascade['default']);
+ //The ones which we are sure of (list of 0s not in default)
+ $sure_plugins = array_filter($diffed_ones, array($this, 'negate'));
+ //the ones in need of diff
+ $conflicts = array_diff_key($local_default, $diffed_ones);
+ //The final list
+ return array_merge($sure_plugins, array_diff_assoc($conflicts, $this->pluginCascade['default']));
+ }
+
+ /**
+ * Build the list of plugins and cascade
+ *
+ */
+ protected function loadConfig()
+ {
+ global $config_cascade;
+ foreach (array('default', 'protected') as $type) {
+ if (array_key_exists($type, $config_cascade['plugins'])) {
+ $this->pluginCascade[$type] = $this->checkRequire($config_cascade['plugins'][$type]);
+ }
+ }
+ $local = $config_cascade['plugins']['local'];
+ $this->lastLocalConfigFile = array_pop($local);
+ $this->pluginCascade['local'] = $this->checkRequire(array($this->lastLocalConfigFile));
+ if (is_array($local)) {
+ $this->pluginCascade['default'] = array_merge(
+ $this->pluginCascade['default'],
+ $this->checkRequire($local)
+ );
+ }
+ $this->masterList = array_merge(
+ $this->pluginCascade['default'],
+ $this->pluginCascade['local'],
+ $this->pluginCascade['protected']
+ );
+ }
+
+ /**
+ * Returns a list of available plugin components of given type
+ *
+ * @param string $type plugin_type name; the type of plugin to return,
+ * @param bool $enabled true to return enabled plugins,
+ * false to return disabled plugins
+ * @return array of plugin components of requested type
+ */
+ protected function getListByType($type, $enabled)
+ {
+ $master_list = $enabled
+ ? array_keys(array_filter($this->masterList))
+ : array_keys(array_filter($this->masterList, array($this, 'negate')));
+ $plugins = array();
+
+ foreach ($master_list as $plugin) {
+
+ if (file_exists(DOKU_PLUGIN . "$plugin/$type.php")) {
+ $plugins[] = $plugin;
+ continue;
+ }
+
+ $typedir = DOKU_PLUGIN . "$plugin/$type/";
+ if (is_dir($typedir)) {
+ if ($dp = opendir($typedir)) {
+ while (false !== ($component = readdir($dp))) {
+ if (strpos($component, '.') === 0 || strtolower(substr($component, -4)) !== '.php') continue;
+ if (is_file($typedir . $component)) {
+ $plugins[] = $plugin . '_' . substr($component, 0, -4);
+ }
+ }
+ closedir($dp);
+ }
+ }
+
+ }//foreach
+
+ return $plugins;
+ }
+
+ /**
+ * Split name in a plugin name and a component name
+ *
+ * @param string $name
+ * @return array with
+ * - plugin name
+ * - and component name when available, otherwise empty string
+ */
+ protected function splitName($name)
+ {
+ if (!isset($this->masterList[$name])) {
+ return explode('_', $name, 2);
+ }
+
+ return array($name, '');
+ }
+
+ /**
+ * Returns inverse boolean value of the input
+ *
+ * @param mixed $input
+ * @return bool inversed boolean value of input
+ */
+ protected function negate($input)
+ {
+ return !(bool)$input;
+ }
+}
diff --git a/platform/www/inc/Extension/PluginInterface.php b/platform/www/inc/Extension/PluginInterface.php
new file mode 100644
index 0000000..f2dbe86
--- /dev/null
+++ b/platform/www/inc/Extension/PluginInterface.php
@@ -0,0 +1,162 @@
+<?php
+
+namespace dokuwiki\Extension;
+
+/**
+ * DokuWiki Plugin Interface
+ *
+ * Defines the public contract all DokuWiki plugins will adhere to. The actual code
+ * to do so is defined in dokuwiki\Extension\PluginTrait
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+interface PluginInterface
+{
+ /**
+ * General Info
+ *
+ * Needs to return a associative array with the following values:
+ *
+ * base - the plugin's base name (eg. the directory it needs to be installed in)
+ * author - Author of the plugin
+ * email - Email address to contact the author
+ * date - Last modified date of the plugin in YYYY-MM-DD format
+ * name - Name of the plugin
+ * desc - Short description of the plugin (Text only)
+ * url - Website with more information on the plugin (eg. syntax description)
+ */
+ public function getInfo();
+
+ /**
+ * The type of the plugin inferred from the class name
+ *
+ * @return string plugin type
+ */
+ public function getPluginType();
+
+ /**
+ * The name of the plugin inferred from the class name
+ *
+ * @return string plugin name
+ */
+ public function getPluginName();
+
+ /**
+ * The component part of the plugin inferred from the class name
+ *
+ * @return string component name
+ */
+ public function getPluginComponent();
+
+ /**
+ * Access plugin language strings
+ *
+ * to try to minimise unnecessary loading of the strings when the plugin doesn't require them
+ * e.g. when info plugin is querying plugins for information about themselves.
+ *
+ * @param string $id id of the string to be retrieved
+ * @return string in appropriate language or english if not available
+ */
+ public function getLang($id);
+
+ /**
+ * retrieve a language dependent file and pass to xhtml renderer for display
+ * plugin equivalent of p_locale_xhtml()
+ *
+ * @param string $id id of language dependent wiki page
+ * @return string parsed contents of the wiki page in xhtml format
+ */
+ public function locale_xhtml($id);
+
+ /**
+ * Prepends appropriate path for a language dependent filename
+ * plugin equivalent of localFN()
+ *
+ * @param string $id id of localization file
+ * @param string $ext The file extension (usually txt)
+ * @return string wiki text
+ */
+ public function localFN($id, $ext = 'txt');
+
+ /**
+ * Reads all the plugins language dependent strings into $this->lang
+ * this function is automatically called by getLang()
+ *
+ * @todo this could be made protected and be moved to the trait only
+ */
+ public function setupLocale();
+
+ /**
+ * use this function to access plugin configuration variables
+ *
+ * @param string $setting the setting to access
+ * @param mixed $notset what to return if the setting is not available
+ * @return mixed
+ */
+ public function getConf($setting, $notset = false);
+
+ /**
+ * merges the plugin's default settings with any local settings
+ * this function is automatically called through getConf()
+ *
+ * @todo this could be made protected and be moved to the trait only
+ */
+ public function loadConfig();
+
+ /**
+ * Loads a given helper plugin (if enabled)
+ *
+ * @author Esther Brunner <wikidesign@gmail.com>
+ *
+ * @param string $name name of plugin to load
+ * @param bool $msg if a message should be displayed in case the plugin is not available
+ * @return PluginInterface|null helper plugin object
+ */
+ public function loadHelper($name, $msg = true);
+
+ /**
+ * email
+ * standardised function to generate an email link according to obfuscation settings
+ *
+ * @param string $email
+ * @param string $name
+ * @param string $class
+ * @param string $more
+ * @return string html
+ */
+ public function email($email, $name = '', $class = '', $more = '');
+
+ /**
+ * external_link
+ * standardised function to generate an external link according to conf settings
+ *
+ * @param string $link
+ * @param string $title
+ * @param string $class
+ * @param string $target
+ * @param string $more
+ * @return string
+ */
+ public function external_link($link, $title = '', $class = '', $target = '', $more = '');
+
+ /**
+ * output text string through the parser, allows dokuwiki markup to be used
+ * very ineffecient for small pieces of data - try not to use
+ *
+ * @param string $text wiki markup to parse
+ * @param string $format output format
+ * @return null|string
+ */
+ public function render_text($text, $format = 'xhtml');
+
+ /**
+ * Allow the plugin to prevent DokuWiki from reusing an instance
+ *
+ * @return bool false if the plugin has to be instantiated
+ */
+ public function isSingleton();
+}
+
+
+
diff --git a/platform/www/inc/Extension/PluginTrait.php b/platform/www/inc/Extension/PluginTrait.php
new file mode 100644
index 0000000..f1db0f5
--- /dev/null
+++ b/platform/www/inc/Extension/PluginTrait.php
@@ -0,0 +1,256 @@
+<?php
+
+namespace dokuwiki\Extension;
+
+/**
+ * Provides standard DokuWiki plugin behaviour
+ */
+trait PluginTrait
+{
+
+ protected $localised = false; // set to true by setupLocale() after loading language dependent strings
+ protected $lang = array(); // array to hold language dependent strings, best accessed via ->getLang()
+ protected $configloaded = false; // set to true by loadConfig() after loading plugin configuration variables
+ protected $conf = array(); // array to hold plugin settings, best accessed via ->getConf()
+
+ /**
+ * @see PluginInterface::getInfo()
+ */
+ public function getInfo()
+ {
+ $parts = explode('_', get_class($this));
+ $info = DOKU_PLUGIN . '/' . $parts[2] . '/plugin.info.txt';
+ if (file_exists($info)) return confToHash($info);
+
+ msg(
+ 'getInfo() not implemented in ' . get_class($this) . ' and ' . $info . ' not found.<br />' .
+ 'Verify you\'re running the latest version of the plugin. If the problem persists, send a ' .
+ 'bug report to the author of the ' . $parts[2] . ' plugin.', -1
+ );
+ return array(
+ 'date' => '0000-00-00',
+ 'name' => $parts[2] . ' plugin',
+ );
+ }
+
+ /**
+ * @see PluginInterface::isSingleton()
+ */
+ public function isSingleton()
+ {
+ return true;
+ }
+
+ /**
+ * @see PluginInterface::loadHelper()
+ */
+ public function loadHelper($name, $msg = true)
+ {
+ $obj = plugin_load('helper', $name);
+ if (is_null($obj) && $msg) msg("Helper plugin $name is not available or invalid.", -1);
+ return $obj;
+ }
+
+ // region introspection methods
+
+ /**
+ * @see PluginInterface::getPluginType()
+ */
+ public function getPluginType()
+ {
+ list($t) = explode('_', get_class($this), 2);
+ return $t;
+ }
+
+ /**
+ * @see PluginInterface::getPluginName()
+ */
+ public function getPluginName()
+ {
+ list(/* $t */, /* $p */, $n) = explode('_', get_class($this), 4);
+ return $n;
+ }
+
+ /**
+ * @see PluginInterface::getPluginComponent()
+ */
+ public function getPluginComponent()
+ {
+ list(/* $t */, /* $p */, /* $n */, $c) = explode('_', get_class($this), 4);
+ return (isset($c) ? $c : '');
+ }
+
+ // endregion
+ // region localization methods
+
+ /**
+ * @see PluginInterface::getLang()
+ */
+ public function getLang($id)
+ {
+ if (!$this->localised) $this->setupLocale();
+
+ return (isset($this->lang[$id]) ? $this->lang[$id] : '');
+ }
+
+ /**
+ * @see PluginInterface::locale_xhtml()
+ */
+ public function locale_xhtml($id)
+ {
+ return p_cached_output($this->localFN($id));
+ }
+
+ /**
+ * @see PluginInterface::localFN()
+ */
+ public function localFN($id, $ext = 'txt')
+ {
+ global $conf;
+ $plugin = $this->getPluginName();
+ $file = DOKU_CONF . 'plugin_lang/' . $plugin . '/' . $conf['lang'] . '/' . $id . '.' . $ext;
+ if (!file_exists($file)) {
+ $file = DOKU_PLUGIN . $plugin . '/lang/' . $conf['lang'] . '/' . $id . '.' . $ext;
+ if (!file_exists($file)) {
+ //fall back to english
+ $file = DOKU_PLUGIN . $plugin . '/lang/en/' . $id . '.' . $ext;
+ }
+ }
+ return $file;
+ }
+
+ /**
+ * @see PluginInterface::setupLocale()
+ */
+ public function setupLocale()
+ {
+ if ($this->localised) return;
+
+ global $conf, $config_cascade; // definitely don't invoke "global $lang"
+ $path = DOKU_PLUGIN . $this->getPluginName() . '/lang/';
+
+ $lang = array();
+
+ // don't include once, in case several plugin components require the same language file
+ @include($path . 'en/lang.php');
+ foreach ($config_cascade['lang']['plugin'] as $config_file) {
+ if (file_exists($config_file . $this->getPluginName() . '/en/lang.php')) {
+ include($config_file . $this->getPluginName() . '/en/lang.php');
+ }
+ }
+
+ if ($conf['lang'] != 'en') {
+ @include($path . $conf['lang'] . '/lang.php');
+ foreach ($config_cascade['lang']['plugin'] as $config_file) {
+ if (file_exists($config_file . $this->getPluginName() . '/' . $conf['lang'] . '/lang.php')) {
+ include($config_file . $this->getPluginName() . '/' . $conf['lang'] . '/lang.php');
+ }
+ }
+ }
+
+ $this->lang = $lang;
+ $this->localised = true;
+ }
+
+ // endregion
+ // region configuration methods
+
+ /**
+ * @see PluginInterface::getConf()
+ */
+ public function getConf($setting, $notset = false)
+ {
+
+ if (!$this->configloaded) {
+ $this->loadConfig();
+ }
+
+ if (isset($this->conf[$setting])) {
+ return $this->conf[$setting];
+ } else {
+ return $notset;
+ }
+ }
+
+ /**
+ * @see PluginInterface::loadConfig()
+ */
+ public function loadConfig()
+ {
+ global $conf;
+
+ $defaults = $this->readDefaultSettings();
+ $plugin = $this->getPluginName();
+
+ foreach ($defaults as $key => $value) {
+ if (isset($conf['plugin'][$plugin][$key])) continue;
+ $conf['plugin'][$plugin][$key] = $value;
+ }
+
+ $this->configloaded = true;
+ $this->conf =& $conf['plugin'][$plugin];
+ }
+
+ /**
+ * read the plugin's default configuration settings from conf/default.php
+ * this function is automatically called through getConf()
+ *
+ * @return array setting => value
+ */
+ protected function readDefaultSettings()
+ {
+
+ $path = DOKU_PLUGIN . $this->getPluginName() . '/conf/';
+ $conf = array();
+
+ if (file_exists($path . 'default.php')) {
+ include($path . 'default.php');
+ }
+
+ return $conf;
+ }
+
+ // endregion
+ // region output methods
+
+ /**
+ * @see PluginInterface::email()
+ */
+ public function email($email, $name = '', $class = '', $more = '')
+ {
+ if (!$email) return $name;
+ $email = obfuscate($email);
+ if (!$name) $name = $email;
+ $class = "class='" . ($class ? $class : 'mail') . "'";
+ return "<a href='mailto:$email' $class title='$email' $more>$name</a>";
+ }
+
+ /**
+ * @see PluginInterface::external_link()
+ */
+ public function external_link($link, $title = '', $class = '', $target = '', $more = '')
+ {
+ global $conf;
+
+ $link = htmlentities($link);
+ if (!$title) $title = $link;
+ if (!$target) $target = $conf['target']['extern'];
+ if ($conf['relnofollow']) $more .= ' rel="nofollow"';
+
+ if ($class) $class = " class='$class'";
+ if ($target) $target = " target='$target'";
+ if ($more) $more = " " . trim($more);
+
+ return "<a href='$link'$class$target$more>$title</a>";
+ }
+
+ /**
+ * @see PluginInterface::render_text()
+ */
+ public function render_text($text, $format = 'xhtml')
+ {
+ return p_render($format, p_get_instructions($text), $info);
+ }
+
+ // endregion
+}
diff --git a/platform/www/inc/Extension/RemotePlugin.php b/platform/www/inc/Extension/RemotePlugin.php
new file mode 100644
index 0000000..33bca98
--- /dev/null
+++ b/platform/www/inc/Extension/RemotePlugin.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace dokuwiki\Extension;
+
+use dokuwiki\Remote\Api;
+use ReflectionException;
+use ReflectionMethod;
+
+/**
+ * Remote Plugin prototype
+ *
+ * Add functionality to the remote API in a plugin
+ */
+abstract class RemotePlugin extends Plugin
+{
+
+ private $api;
+
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ $this->api = new Api();
+ }
+
+ /**
+ * Get all available methods with remote access.
+ *
+ * By default it exports all public methods of a remote plugin. Methods beginning
+ * with an underscore are skipped.
+ *
+ * @return array Information about all provided methods. {@see dokuwiki\Remote\RemoteAPI}.
+ * @throws ReflectionException
+ */
+ public function _getMethods()
+ {
+ $result = array();
+
+ $reflection = new \ReflectionClass($this);
+ foreach ($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
+ // skip parent methods, only methods further down are exported
+ $declaredin = $method->getDeclaringClass()->name;
+ if ($declaredin === 'dokuwiki\Extension\Plugin' || $declaredin === 'dokuwiki\Extension\RemotePlugin') {
+ continue;
+ }
+ $method_name = $method->name;
+ if (strpos($method_name, '_') === 0) {
+ continue;
+ }
+
+ // strip asterisks
+ $doc = $method->getDocComment();
+ $doc = preg_replace(
+ array('/^[ \t]*\/\*+[ \t]*/m', '/[ \t]*\*+[ \t]*/m', '/\*+\/\s*$/m', '/\s*\/\s*$/m'),
+ array('', '', '', ''),
+ $doc
+ );
+
+ // prepare data
+ $data = array();
+ $data['name'] = $method_name;
+ $data['public'] = 0;
+ $data['doc'] = $doc;
+ $data['args'] = array();
+
+ // get parameter type from doc block type hint
+ foreach ($method->getParameters() as $parameter) {
+ $name = $parameter->name;
+ $type = 'string'; // we default to string
+ if (preg_match('/^@param[ \t]+([\w|\[\]]+)[ \t]\$' . $name . '/m', $doc, $m)) {
+ $type = $this->cleanTypeHint($m[1]);
+ }
+ $data['args'][] = $type;
+ }
+
+ // get return type from doc block type hint
+ if (preg_match('/^@return[ \t]+([\w|\[\]]+)/m', $doc, $m)) {
+ $data['return'] = $this->cleanTypeHint($m[1]);
+ } else {
+ $data['return'] = 'string';
+ }
+
+ // add to result
+ $result[$method_name] = $data;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Matches the given type hint against the valid options for the remote API
+ *
+ * @param string $hint
+ * @return string
+ */
+ protected function cleanTypeHint($hint)
+ {
+ $types = explode('|', $hint);
+ foreach ($types as $t) {
+ if (substr($t, -2) === '[]') {
+ return 'array';
+ }
+ if ($t === 'boolean') {
+ return 'bool';
+ }
+ if (in_array($t, array('array', 'string', 'int', 'double', 'bool', 'null', 'date', 'file'))) {
+ return $t;
+ }
+ }
+ return 'string';
+ }
+
+ /**
+ * @return Api
+ */
+ protected function getApi()
+ {
+ return $this->api;
+ }
+
+}
diff --git a/platform/www/inc/Extension/SyntaxPlugin.php b/platform/www/inc/Extension/SyntaxPlugin.php
new file mode 100644
index 0000000..ea8f51b
--- /dev/null
+++ b/platform/www/inc/Extension/SyntaxPlugin.php
@@ -0,0 +1,132 @@
+<?php
+
+namespace dokuwiki\Extension;
+
+use Doku_Handler;
+use Doku_Renderer;
+
+/**
+ * Syntax Plugin Prototype
+ *
+ * All DokuWiki plugins to extend the parser/rendering mechanism
+ * need to inherit from this class
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+abstract class SyntaxPlugin extends \dokuwiki\Parsing\ParserMode\Plugin
+{
+ use PluginTrait;
+
+ protected $allowedModesSetup = false;
+
+ /**
+ * Syntax Type
+ *
+ * Needs to return one of the mode types defined in $PARSER_MODES in Parser.php
+ *
+ * @return string
+ */
+ abstract public function getType();
+
+ /**
+ * Allowed Mode Types
+ *
+ * Defines the mode types for other dokuwiki markup that maybe nested within the
+ * plugin's own markup. Needs to return an array of one or more of the mode types
+ * defined in $PARSER_MODES in Parser.php
+ *
+ * @return array
+ */
+ public function getAllowedTypes()
+ {
+ return array();
+ }
+
+ /**
+ * Paragraph Type
+ *
+ * Defines how this syntax is handled regarding paragraphs. This is important
+ * for correct XHTML nesting. Should return one of the following:
+ *
+ * 'normal' - The plugin can be used inside paragraphs
+ * 'block' - Open paragraphs need to be closed before plugin output
+ * 'stack' - Special case. Plugin wraps other paragraphs.
+ *
+ * @see Doku_Handler_Block
+ *
+ * @return string
+ */
+ public function getPType()
+ {
+ return 'normal';
+ }
+
+ /**
+ * Handler to prepare matched data for the rendering process
+ *
+ * This function can only pass data to render() via its return value - render()
+ * may be not be run during the object's current life.
+ *
+ * Usually you should only need the $match param.
+ *
+ * @param string $match The text matched by the patterns
+ * @param int $state The lexer state for the match
+ * @param int $pos The character position of the matched text
+ * @param Doku_Handler $handler The Doku_Handler object
+ * @return bool|array Return an array with all data you want to use in render, false don't add an instruction
+ */
+ abstract public function handle($match, $state, $pos, Doku_Handler $handler);
+
+ /**
+ * Handles the actual output creation.
+ *
+ * The function must not assume any other of the classes methods have been run
+ * during the object's current life. The only reliable data it receives are its
+ * parameters.
+ *
+ * The function should always check for the given output format and return false
+ * when a format isn't supported.
+ *
+ * $renderer contains a reference to the renderer object which is
+ * currently handling the rendering. You need to use it for writing
+ * the output. How this is done depends on the renderer used (specified
+ * by $format
+ *
+ * The contents of the $data array depends on what the handler() function above
+ * created
+ *
+ * @param string $format output format being rendered
+ * @param Doku_Renderer $renderer the current renderer object
+ * @param array $data data created by handler()
+ * @return boolean rendered correctly? (however, returned value is not used at the moment)
+ */
+ abstract public function render($format, Doku_Renderer $renderer, $data);
+
+ /**
+ * There should be no need to override this function
+ *
+ * @param string $mode
+ * @return bool
+ */
+ public function accepts($mode)
+ {
+
+ if (!$this->allowedModesSetup) {
+ global $PARSER_MODES;
+
+ $allowedModeTypes = $this->getAllowedTypes();
+ foreach ($allowedModeTypes as $mt) {
+ $this->allowedModes = array_merge($this->allowedModes, $PARSER_MODES[$mt]);
+ }
+
+ $idx = array_search(substr(get_class($this), 7), (array)$this->allowedModes);
+ if ($idx !== false) {
+ unset($this->allowedModes[$idx]);
+ }
+ $this->allowedModesSetup = true;
+ }
+
+ return parent::accepts($mode);
+ }
+}
diff --git a/platform/www/inc/FeedParser.php b/platform/www/inc/FeedParser.php
new file mode 100644
index 0000000..8f71b96
--- /dev/null
+++ b/platform/www/inc/FeedParser.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * We override some methods of the original SimplePie class here
+ */
+class FeedParser extends SimplePie {
+
+ /**
+ * Constructor. Set some defaults
+ */
+ public function __construct(){
+ parent::__construct();
+ $this->enable_cache(false);
+ $this->set_file_class(\dokuwiki\FeedParserFile::class);
+ }
+
+ /**
+ * Backward compatibility for older plugins
+ *
+ * phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
+ * @param string $url
+ */
+ public function feed_url($url){
+ $this->set_feed_url($url);
+ }
+}
+
+
diff --git a/platform/www/inc/FeedParserFile.php b/platform/www/inc/FeedParserFile.php
new file mode 100644
index 0000000..be3417e
--- /dev/null
+++ b/platform/www/inc/FeedParserFile.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace dokuwiki;
+
+use dokuwiki\HTTP\DokuHTTPClient;
+
+/**
+ * Fetch an URL using our own HTTPClient
+ *
+ * Replaces SimplePie's own class
+ */
+class FeedParserFile extends \SimplePie_File
+{
+ protected $http;
+ /** @noinspection PhpMissingParentConstructorInspection */
+
+ /**
+ * Inititializes the HTTPClient
+ *
+ * We ignore all given parameters - they are set in DokuHTTPClient
+ *
+ * @inheritdoc
+ */
+ public function __construct(
+ $url,
+ $timeout = 10,
+ $redirects = 5,
+ $headers = null,
+ $useragent = null,
+ $force_fsockopen = false,
+ $curl_options = array()
+ ) {
+ $this->http = new DokuHTTPClient();
+ $this->success = $this->http->sendRequest($url);
+
+ $this->headers = $this->http->resp_headers;
+ $this->body = $this->http->resp_body;
+ $this->error = $this->http->error;
+
+ $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
+
+ return $this->success;
+ }
+
+ /** @inheritdoc */
+ public function headers()
+ {
+ return $this->headers;
+ }
+
+ /** @inheritdoc */
+ public function body()
+ {
+ return $this->body;
+ }
+
+ /** @inheritdoc */
+ public function close()
+ {
+ return true;
+ }
+}
diff --git a/platform/www/inc/Form/ButtonElement.php b/platform/www/inc/Form/ButtonElement.php
new file mode 100644
index 0000000..4f585f0
--- /dev/null
+++ b/platform/www/inc/Form/ButtonElement.php
@@ -0,0 +1,34 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class ButtonElement
+ *
+ * Represents a simple button
+ *
+ * @package dokuwiki\Form
+ */
+class ButtonElement extends Element {
+
+ /** @var string HTML content */
+ protected $content = '';
+
+ /**
+ * @param string $name
+ * @param string $content HTML content of the button. You have to escape it yourself.
+ */
+ public function __construct($name, $content = '') {
+ parent::__construct('button', array('name' => $name, 'value' => 1));
+ $this->content = $content;
+ }
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ public function toHTML() {
+ return '<button ' . buildAttributes($this->attrs(), true) . '>'.$this->content.'</button>';
+ }
+
+}
diff --git a/platform/www/inc/Form/CheckableElement.php b/platform/www/inc/Form/CheckableElement.php
new file mode 100644
index 0000000..27d5c2e
--- /dev/null
+++ b/platform/www/inc/Form/CheckableElement.php
@@ -0,0 +1,62 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class CheckableElement
+ *
+ * For Radio- and Checkboxes
+ *
+ * @package dokuwiki\Form
+ */
+class CheckableElement extends InputElement {
+
+ /**
+ * @param string $type The type of this element
+ * @param string $name The name of this form element
+ * @param string $label The label text for this element
+ */
+ public function __construct($type, $name, $label) {
+ parent::__construct($type, $name, $label);
+ // default value is 1
+ $this->attr('value', 1);
+ }
+
+ /**
+ * Handles the useInput flag and sets the checked attribute accordingly
+ */
+ protected function prefillInput() {
+ global $INPUT;
+ list($name, $key) = $this->getInputName();
+ $myvalue = $this->val();
+
+ if(!$INPUT->has($name)) return;
+
+ if($key === null) {
+ // no key - single value
+ $value = $INPUT->str($name);
+ if($value == $myvalue) {
+ $this->attr('checked', 'checked');
+ } else {
+ $this->rmattr('checked');
+ }
+ } else {
+ // we have an array, there might be several values in it
+ $input = $INPUT->arr($name);
+ if(isset($input[$key])) {
+ $this->rmattr('checked');
+
+ // values seem to be in another sub array
+ if(is_array($input[$key])) {
+ $input = $input[$key];
+ }
+
+ foreach($input as $value) {
+ if($value == $myvalue) {
+ $this->attr('checked', 'checked');
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/platform/www/inc/Form/DropdownElement.php b/platform/www/inc/Form/DropdownElement.php
new file mode 100644
index 0000000..51f4751
--- /dev/null
+++ b/platform/www/inc/Form/DropdownElement.php
@@ -0,0 +1,198 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class DropdownElement
+ *
+ * Represents a HTML select. Please note that this does not support multiple selected options!
+ *
+ * @package dokuwiki\Form
+ */
+class DropdownElement extends InputElement {
+
+ /** @var array OptGroup[] */
+ protected $optGroups = array();
+
+ /**
+ * @param string $name The name of this form element
+ * @param array $options The available options
+ * @param string $label The label text for this element (will be autoescaped)
+ */
+ public function __construct($name, $options, $label = '') {
+ parent::__construct('dropdown', $name, $label);
+ $this->rmattr('type');
+ $this->optGroups[''] = new OptGroup(null, $options);
+ $this->val('');
+ }
+
+ /**
+ * Add an `<optgroup>` and respective options
+ *
+ * @param string $label
+ * @param array $options
+ * @return OptGroup a reference to the added optgroup
+ * @throws \Exception
+ */
+ public function addOptGroup($label, $options) {
+ if (empty($label)) {
+ throw new \InvalidArgumentException(hsc('<optgroup> must have a label!'));
+ }
+ $this->optGroups[$label] = new OptGroup($label, $options);
+ return end($this->optGroups);
+ }
+
+ /**
+ * Set or get the optgroups of an Dropdown-Element.
+ *
+ * optgroups have to be given as associative array
+ * * the key being the label of the group
+ * * the value being an array of options as defined in @see OptGroup::options()
+ *
+ * @param null|array $optGroups
+ * @return OptGroup[]|DropdownElement
+ */
+ public function optGroups($optGroups = null) {
+ if($optGroups === null) {
+ return $this->optGroups;
+ }
+ if (!is_array($optGroups)) {
+ throw new \InvalidArgumentException(hsc('Argument must be an associative array of label => [options]!'));
+ }
+ $this->optGroups = array();
+ foreach ($optGroups as $label => $options) {
+ $this->addOptGroup($label, $options);
+ }
+ return $this;
+ }
+
+ /**
+ * Get or set the options of the Dropdown
+ *
+ * Options can be given as associative array (value => label) or as an
+ * indexd array (label = value) or as an array of arrays. In the latter
+ * case an element has to look as follows:
+ * option-value => array (
+ * 'label' => option-label,
+ * 'attrs' => array (
+ * attr-key => attr-value, ...
+ * )
+ * )
+ *
+ * @param null|array $options
+ * @return $this|array
+ */
+ public function options($options = null) {
+ if ($options === null) {
+ return $this->optGroups['']->options();
+ }
+ $this->optGroups[''] = new OptGroup(null, $options);
+ return $this;
+ }
+
+ /**
+ * Gets or sets an attribute
+ *
+ * When no $value is given, the current content of the attribute is returned.
+ * An empty string is returned for unset attributes.
+ *
+ * When a $value is given, the content is set to that value and the Element
+ * itself is returned for easy chaining
+ *
+ * @param string $name Name of the attribute to access
+ * @param null|string $value New value to set
+ * @return string|$this
+ */
+ public function attr($name, $value = null) {
+ if(strtolower($name) == 'multiple') {
+ throw new \InvalidArgumentException(
+ 'Sorry, the dropdown element does not support the "multiple" attribute'
+ );
+ }
+ return parent::attr($name, $value);
+ }
+
+ /**
+ * Get or set the current value
+ *
+ * When setting a value that is not defined in the options, the value is ignored
+ * and the first option's value is selected instead
+ *
+ * @param null|string $value The value to set
+ * @return $this|string
+ */
+ public function val($value = null) {
+ if($value === null) return $this->value;
+
+ $value_exists = $this->setValueInOptGroups($value);
+
+ if($value_exists) {
+ $this->value = $value;
+ } else {
+ // unknown value set, select first option instead
+ $this->value = $this->getFirstOption();
+ $this->setValueInOptGroups($this->value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Returns the first options as it will be rendered in HTML
+ *
+ * @return string
+ */
+ protected function getFirstOption() {
+ $options = $this->options();
+ if (!empty($options)) {
+ $keys = array_keys($options);
+ return (string) array_shift($keys);
+ }
+ foreach ($this->optGroups as $optGroup) {
+ $options = $optGroup->options();
+ if (!empty($options)) {
+ $keys = array_keys($options);
+ return (string) array_shift($keys);
+ }
+ }
+ }
+
+ /**
+ * Set the value in the OptGroups, including the optgroup for the options without optgroup.
+ *
+ * @param string $value
+ * @return bool
+ */
+ protected function setValueInOptGroups($value) {
+ $value_exists = false;
+ /** @var OptGroup $optGroup */
+ foreach ($this->optGroups as $optGroup) {
+ $value_exists = $optGroup->storeValue($value) || $value_exists;
+ if ($value_exists) {
+ $value = null;
+ }
+ }
+ return $value_exists;
+ }
+
+ /**
+ * Create the HTML for the select it self
+ *
+ * @return string
+ */
+ protected function mainElementHTML() {
+ if($this->useInput) $this->prefillInput();
+
+ $html = '<select ' . buildAttributes($this->attrs()) . '>';
+ $html = array_reduce(
+ $this->optGroups,
+ function ($html, OptGroup $optGroup) {
+ return $html . $optGroup->toHTML();
+ },
+ $html
+ );
+ $html .= '</select>';
+
+ return $html;
+ }
+
+}
diff --git a/platform/www/inc/Form/Element.php b/platform/www/inc/Form/Element.php
new file mode 100644
index 0000000..a357882
--- /dev/null
+++ b/platform/www/inc/Form/Element.php
@@ -0,0 +1,151 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class Element
+ *
+ * The basic building block of a form
+ *
+ * @package dokuwiki\Form
+ */
+abstract class Element {
+
+ /**
+ * @var array the attributes of this element
+ */
+ protected $attributes = array();
+
+ /**
+ * @var string The type of this element
+ */
+ protected $type;
+
+ /**
+ * @param string $type The type of this element
+ * @param array $attributes
+ */
+ public function __construct($type, $attributes = array()) {
+ $this->type = $type;
+ $this->attributes = $attributes;
+ }
+
+ /**
+ * Type of this element
+ *
+ * @return string
+ */
+ public function getType() {
+ return $this->type;
+ }
+
+ /**
+ * Gets or sets an attribute
+ *
+ * When no $value is given, the current content of the attribute is returned.
+ * An empty string is returned for unset attributes.
+ *
+ * When a $value is given, the content is set to that value and the Element
+ * itself is returned for easy chaining
+ *
+ * @param string $name Name of the attribute to access
+ * @param null|string $value New value to set
+ * @return string|$this
+ */
+ public function attr($name, $value = null) {
+ // set
+ if($value !== null) {
+ $this->attributes[$name] = $value;
+ return $this;
+ }
+
+ // get
+ if(isset($this->attributes[$name])) {
+ return $this->attributes[$name];
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Removes the given attribute if it exists
+ *
+ * @param string $name
+ * @return $this
+ */
+ public function rmattr($name) {
+ if(isset($this->attributes[$name])) {
+ unset($this->attributes[$name]);
+ }
+ return $this;
+ }
+
+ /**
+ * Gets or adds a all given attributes at once
+ *
+ * @param array|null $attributes
+ * @return array|$this
+ */
+ public function attrs($attributes = null) {
+ // set
+ if($attributes) {
+ foreach((array) $attributes as $key => $val) {
+ $this->attr($key, $val);
+ }
+ return $this;
+ }
+ // get
+ return $this->attributes;
+ }
+
+ /**
+ * Adds a class to the class attribute
+ *
+ * This is the preferred method of setting the element's class
+ *
+ * @param string $class the new class to add
+ * @return $this
+ */
+ public function addClass($class) {
+ $classes = explode(' ', $this->attr('class'));
+ $classes[] = $class;
+ $classes = array_unique($classes);
+ $classes = array_filter($classes);
+ $this->attr('class', join(' ', $classes));
+ return $this;
+ }
+
+ /**
+ * Get or set the element's ID
+ *
+ * This is the preferred way of setting the element's ID
+ *
+ * @param null|string $id
+ * @return string|$this
+ */
+ public function id($id = null) {
+ if(strpos($id, '__') === false) {
+ throw new \InvalidArgumentException('IDs in DokuWiki have to contain two subsequent underscores');
+ }
+
+ return $this->attr('id', $id);
+ }
+
+ /**
+ * Get or set the element's value
+ *
+ * This is the preferred way of setting the element's value
+ *
+ * @param null|string $value
+ * @return string|$this
+ */
+ public function val($value = null) {
+ return $this->attr('value', $value);
+ }
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ abstract public function toHTML();
+}
diff --git a/platform/www/inc/Form/FieldsetCloseElement.php b/platform/www/inc/Form/FieldsetCloseElement.php
new file mode 100644
index 0000000..8f26717
--- /dev/null
+++ b/platform/www/inc/Form/FieldsetCloseElement.php
@@ -0,0 +1,30 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class FieldsetCloseElement
+ *
+ * Closes an open Fieldset
+ *
+ * @package dokuwiki\Form
+ */
+class FieldsetCloseElement extends TagCloseElement {
+
+ /**
+ * @param array $attributes
+ */
+ public function __construct($attributes = array()) {
+ parent::__construct('', $attributes);
+ $this->type = 'fieldsetclose';
+ }
+
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ public function toHTML() {
+ return '</fieldset>';
+ }
+}
diff --git a/platform/www/inc/Form/FieldsetOpenElement.php b/platform/www/inc/Form/FieldsetOpenElement.php
new file mode 100644
index 0000000..a7de461
--- /dev/null
+++ b/platform/www/inc/Form/FieldsetOpenElement.php
@@ -0,0 +1,36 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class FieldsetOpenElement
+ *
+ * Opens a Fieldset with an optional legend
+ *
+ * @package dokuwiki\Form
+ */
+class FieldsetOpenElement extends TagOpenElement {
+
+ /**
+ * @param string $legend
+ * @param array $attributes
+ */
+ public function __construct($legend='', $attributes = array()) {
+ // this is a bit messy and we just do it for the nicer class hierarchy
+ // the parent would expect the tag in $value but we're storing the
+ // legend there, so we have to set the type manually
+ parent::__construct($legend, $attributes);
+ $this->type = 'fieldsetopen';
+ }
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ public function toHTML() {
+ $html = '<fieldset '.buildAttributes($this->attrs()).'>';
+ $legend = $this->val();
+ if($legend) $html .= DOKU_LF.'<legend>'.hsc($legend).'</legend>';
+ return $html;
+ }
+}
diff --git a/platform/www/inc/Form/Form.php b/platform/www/inc/Form/Form.php
new file mode 100644
index 0000000..c741a69
--- /dev/null
+++ b/platform/www/inc/Form/Form.php
@@ -0,0 +1,462 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class Form
+ *
+ * Represents the whole Form. This is what you work on, and add Elements to
+ *
+ * @package dokuwiki\Form
+ */
+class Form extends Element {
+
+ /**
+ * @var array name value pairs for hidden values
+ */
+ protected $hidden = array();
+
+ /**
+ * @var Element[] the elements of the form
+ */
+ protected $elements = array();
+
+ /**
+ * Creates a new, empty form with some default attributes
+ *
+ * @param array $attributes
+ * @param bool $unsafe if true, then the security token is ommited
+ */
+ public function __construct($attributes = array(), $unsafe = false) {
+ global $ID;
+
+ parent::__construct('form', $attributes);
+
+ // use the current URL as default action
+ if(!$this->attr('action')) {
+ $get = $_GET;
+ if(isset($get['id'])) unset($get['id']);
+ $self = wl($ID, $get, false, '&'); //attributes are escaped later
+ $this->attr('action', $self);
+ }
+
+ // post is default
+ if(!$this->attr('method')) {
+ $this->attr('method', 'post');
+ }
+
+ // we like UTF-8
+ if(!$this->attr('accept-charset')) {
+ $this->attr('accept-charset', 'utf-8');
+ }
+
+ // add the security token by default
+ if (!$unsafe) {
+ $this->setHiddenField('sectok', getSecurityToken());
+ }
+
+ // identify this as a new form based form in HTML
+ $this->addClass('doku_form');
+ }
+
+ /**
+ * Sets a hidden field
+ *
+ * @param string $name
+ * @param string $value
+ * @return $this
+ */
+ public function setHiddenField($name, $value) {
+ $this->hidden[$name] = $value;
+ return $this;
+ }
+
+ #region element query function
+
+ /**
+ * Returns the numbers of elements in the form
+ *
+ * @return int
+ */
+ public function elementCount() {
+ return count($this->elements);
+ }
+
+ /**
+ * Get the position of the element in the form or false if it is not in the form
+ *
+ * Warning: This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates
+ * to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the
+ * return value of this function.
+ *
+ * @param Element $element
+ *
+ * @return false|int
+ */
+ public function getElementPosition(Element $element)
+ {
+ return array_search($element, $this->elements, true);
+ }
+
+ /**
+ * Returns a reference to the element at a position.
+ * A position out-of-bounds will return either the
+ * first (underflow) or last (overflow) element.
+ *
+ * @param int $pos
+ * @return Element
+ */
+ public function getElementAt($pos) {
+ if($pos < 0) $pos = count($this->elements) + $pos;
+ if($pos < 0) $pos = 0;
+ if($pos >= count($this->elements)) $pos = count($this->elements) - 1;
+ return $this->elements[$pos];
+ }
+
+ /**
+ * Gets the position of the first of a type of element
+ *
+ * @param string $type Element type to look for.
+ * @param int $offset search from this position onward
+ * @return false|int position of element if found, otherwise false
+ */
+ public function findPositionByType($type, $offset = 0) {
+ $len = $this->elementCount();
+ for($pos = $offset; $pos < $len; $pos++) {
+ if($this->elements[$pos]->getType() == $type) {
+ return $pos;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Gets the position of the first element matching the attribute
+ *
+ * @param string $name Name of the attribute
+ * @param string $value Value the attribute should have
+ * @param int $offset search from this position onward
+ * @return false|int position of element if found, otherwise false
+ */
+ public function findPositionByAttribute($name, $value, $offset = 0) {
+ $len = $this->elementCount();
+ for($pos = $offset; $pos < $len; $pos++) {
+ if($this->elements[$pos]->attr($name) == $value) {
+ return $pos;
+ }
+ }
+ return false;
+ }
+
+ #endregion
+
+ #region Element positioning functions
+
+ /**
+ * Adds or inserts an element to the form
+ *
+ * @param Element $element
+ * @param int $pos 0-based position in the form, -1 for at the end
+ * @return Element
+ */
+ public function addElement(Element $element, $pos = -1) {
+ if(is_a($element, '\dokuwiki\Form\Form')) throw new \InvalidArgumentException(
+ 'You can\'t add a form to a form'
+ );
+ if($pos < 0) {
+ $this->elements[] = $element;
+ } else {
+ array_splice($this->elements, $pos, 0, array($element));
+ }
+ return $element;
+ }
+
+ /**
+ * Replaces an existing element with a new one
+ *
+ * @param Element $element the new element
+ * @param int $pos 0-based position of the element to replace
+ */
+ public function replaceElement(Element $element, $pos) {
+ if(is_a($element, '\dokuwiki\Form\Form')) throw new \InvalidArgumentException(
+ 'You can\'t add a form to a form'
+ );
+ array_splice($this->elements, $pos, 1, array($element));
+ }
+
+ /**
+ * Remove an element from the form completely
+ *
+ * @param int $pos 0-based position of the element to remove
+ */
+ public function removeElement($pos) {
+ array_splice($this->elements, $pos, 1);
+ }
+
+ #endregion
+
+ #region Element adding functions
+
+ /**
+ * Adds a text input field
+ *
+ * @param string $name
+ * @param string $label
+ * @param int $pos
+ * @return InputElement
+ */
+ public function addTextInput($name, $label = '', $pos = -1) {
+ return $this->addElement(new InputElement('text', $name, $label), $pos);
+ }
+
+ /**
+ * Adds a password input field
+ *
+ * @param string $name
+ * @param string $label
+ * @param int $pos
+ * @return InputElement
+ */
+ public function addPasswordInput($name, $label = '', $pos = -1) {
+ return $this->addElement(new InputElement('password', $name, $label), $pos);
+ }
+
+ /**
+ * Adds a radio button field
+ *
+ * @param string $name
+ * @param string $label
+ * @param int $pos
+ * @return CheckableElement
+ */
+ public function addRadioButton($name, $label = '', $pos = -1) {
+ return $this->addElement(new CheckableElement('radio', $name, $label), $pos);
+ }
+
+ /**
+ * Adds a checkbox field
+ *
+ * @param string $name
+ * @param string $label
+ * @param int $pos
+ * @return CheckableElement
+ */
+ public function addCheckbox($name, $label = '', $pos = -1) {
+ return $this->addElement(new CheckableElement('checkbox', $name, $label), $pos);
+ }
+
+ /**
+ * Adds a dropdown field
+ *
+ * @param string $name
+ * @param array $options
+ * @param string $label
+ * @param int $pos
+ * @return DropdownElement
+ */
+ public function addDropdown($name, $options, $label = '', $pos = -1) {
+ return $this->addElement(new DropdownElement($name, $options, $label), $pos);
+ }
+
+ /**
+ * Adds a textarea field
+ *
+ * @param string $name
+ * @param string $label
+ * @param int $pos
+ * @return TextareaElement
+ */
+ public function addTextarea($name, $label = '', $pos = -1) {
+ return $this->addElement(new TextareaElement($name, $label), $pos);
+ }
+
+ /**
+ * Adds a simple button, escapes the content for you
+ *
+ * @param string $name
+ * @param string $content
+ * @param int $pos
+ * @return Element
+ */
+ public function addButton($name, $content, $pos = -1) {
+ return $this->addElement(new ButtonElement($name, hsc($content)), $pos);
+ }
+
+ /**
+ * Adds a simple button, allows HTML for content
+ *
+ * @param string $name
+ * @param string $html
+ * @param int $pos
+ * @return Element
+ */
+ public function addButtonHTML($name, $html, $pos = -1) {
+ return $this->addElement(new ButtonElement($name, $html), $pos);
+ }
+
+ /**
+ * Adds a label referencing another input element, escapes the label for you
+ *
+ * @param string $label
+ * @param string $for
+ * @param int $pos
+ * @return Element
+ */
+ public function addLabel($label, $for='', $pos = -1) {
+ return $this->addLabelHTML(hsc($label), $for, $pos);
+ }
+
+ /**
+ * Adds a label referencing another input element, allows HTML for content
+ *
+ * @param string $content
+ * @param string|Element $for
+ * @param int $pos
+ * @return Element
+ */
+ public function addLabelHTML($content, $for='', $pos = -1) {
+ $element = new LabelElement(hsc($content));
+
+ if(is_a($for, '\dokuwiki\Form\Element')) {
+ /** @var Element $for */
+ $for = $for->id();
+ }
+ $for = (string) $for;
+ if($for !== '') {
+ $element->attr('for', $for);
+ }
+
+ return $this->addElement($element, $pos);
+ }
+
+ /**
+ * Add fixed HTML to the form
+ *
+ * @param string $html
+ * @param int $pos
+ * @return HTMLElement
+ */
+ public function addHTML($html, $pos = -1) {
+ return $this->addElement(new HTMLElement($html), $pos);
+ }
+
+ /**
+ * Add a closed HTML tag to the form
+ *
+ * @param string $tag
+ * @param int $pos
+ * @return TagElement
+ */
+ public function addTag($tag, $pos = -1) {
+ return $this->addElement(new TagElement($tag), $pos);
+ }
+
+ /**
+ * Add an open HTML tag to the form
+ *
+ * Be sure to close it again!
+ *
+ * @param string $tag
+ * @param int $pos
+ * @return TagOpenElement
+ */
+ public function addTagOpen($tag, $pos = -1) {
+ return $this->addElement(new TagOpenElement($tag), $pos);
+ }
+
+ /**
+ * Add a closing HTML tag to the form
+ *
+ * Be sure it had been opened before
+ *
+ * @param string $tag
+ * @param int $pos
+ * @return TagCloseElement
+ */
+ public function addTagClose($tag, $pos = -1) {
+ return $this->addElement(new TagCloseElement($tag), $pos);
+ }
+
+ /**
+ * Open a Fieldset
+ *
+ * @param string $legend
+ * @param int $pos
+ * @return FieldsetOpenElement
+ */
+ public function addFieldsetOpen($legend = '', $pos = -1) {
+ return $this->addElement(new FieldsetOpenElement($legend), $pos);
+ }
+
+ /**
+ * Close a fieldset
+ *
+ * @param int $pos
+ * @return TagCloseElement
+ */
+ public function addFieldsetClose($pos = -1) {
+ return $this->addElement(new FieldsetCloseElement(), $pos);
+ }
+
+ #endregion
+
+ /**
+ * Adjust the elements so that fieldset open and closes are matching
+ */
+ protected function balanceFieldsets() {
+ $lastclose = 0;
+ $isopen = false;
+ $len = count($this->elements);
+
+ for($pos = 0; $pos < $len; $pos++) {
+ $type = $this->elements[$pos]->getType();
+ if($type == 'fieldsetopen') {
+ if($isopen) {
+ //close previous fieldset
+ $this->addFieldsetClose($pos);
+ $lastclose = $pos + 1;
+ $pos++;
+ $len++;
+ }
+ $isopen = true;
+ } else if($type == 'fieldsetclose') {
+ if(!$isopen) {
+ // make sure there was a fieldsetopen
+ // either right after the last close or at the begining
+ $this->addFieldsetOpen('', $lastclose);
+ $len++;
+ $pos++;
+ }
+ $lastclose = $pos;
+ $isopen = false;
+ }
+ }
+
+ // close open fieldset at the end
+ if($isopen) {
+ $this->addFieldsetClose();
+ }
+ }
+
+ /**
+ * The HTML representation of the whole form
+ *
+ * @return string
+ */
+ public function toHTML() {
+ $this->balanceFieldsets();
+
+ $html = '<form ' . buildAttributes($this->attrs()) . '>';
+
+ foreach($this->hidden as $name => $value) {
+ $html .= '<input type="hidden" name="' . $name . '" value="' . formText($value) . '" />';
+ }
+
+ foreach($this->elements as $element) {
+ $html .= $element->toHTML();
+ }
+
+ $html .= '</form>';
+
+ return $html;
+ }
+}
diff --git a/platform/www/inc/Form/HTMLElement.php b/platform/www/inc/Form/HTMLElement.php
new file mode 100644
index 0000000..591cf47
--- /dev/null
+++ b/platform/www/inc/Form/HTMLElement.php
@@ -0,0 +1,29 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class HTMLElement
+ *
+ * Holds arbitrary HTML that is added as is to the Form
+ *
+ * @package dokuwiki\Form
+ */
+class HTMLElement extends ValueElement {
+
+
+ /**
+ * @param string $html
+ */
+ public function __construct($html) {
+ parent::__construct('html', $html);
+ }
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ public function toHTML() {
+ return $this->val();
+ }
+}
diff --git a/platform/www/inc/Form/InputElement.php b/platform/www/inc/Form/InputElement.php
new file mode 100644
index 0000000..0242b61
--- /dev/null
+++ b/platform/www/inc/Form/InputElement.php
@@ -0,0 +1,159 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class InputElement
+ *
+ * Base class for all input elements. Uses a wrapping label when label
+ * text is given.
+ *
+ * @todo figure out how to make wrapping or related label configurable
+ * @package dokuwiki\Form
+ */
+class InputElement extends Element {
+ /**
+ * @var LabelElement
+ */
+ protected $label = null;
+
+ /**
+ * @var bool if the element should reflect posted values
+ */
+ protected $useInput = true;
+
+ /**
+ * @param string $type The type of this element
+ * @param string $name The name of this form element
+ * @param string $label The label text for this element (will be autoescaped)
+ */
+ public function __construct($type, $name, $label = '') {
+ parent::__construct($type, array('name' => $name));
+ $this->attr('name', $name);
+ $this->attr('type', $type);
+ if($label) $this->label = new LabelElement($label);
+ }
+
+ /**
+ * Returns the label element if there's one set
+ *
+ * @return LabelElement|null
+ */
+ public function getLabel() {
+ return $this->label;
+ }
+
+ /**
+ * Should the user sent input be used to initialize the input field
+ *
+ * The default is true. Any set values will be overwritten by the INPUT
+ * provided values.
+ *
+ * @param bool $useinput
+ * @return $this
+ */
+ public function useInput($useinput) {
+ $this->useInput = (bool) $useinput;
+ return $this;
+ }
+
+ /**
+ * Get or set the element's ID
+ *
+ * @param null|string $id
+ * @return string|$this
+ */
+ public function id($id = null) {
+ if($this->label) $this->label->attr('for', $id);
+ return parent::id($id);
+ }
+
+ /**
+ * Adds a class to the class attribute
+ *
+ * This is the preferred method of setting the element's class
+ *
+ * @param string $class the new class to add
+ * @return $this
+ */
+ public function addClass($class) {
+ if($this->label) $this->label->addClass($class);
+ return parent::addClass($class);
+ }
+
+ /**
+ * Figures out how to access the value for this field from INPUT data
+ *
+ * The element's name could have been given as a simple string ('foo')
+ * or in array notation ('foo[bar]').
+ *
+ * Note: this function only handles one level of arrays. If your data
+ * is nested deeper, you should call useInput(false) and set the
+ * correct value yourself
+ *
+ * @return array name and array key (null if not an array)
+ */
+ protected function getInputName() {
+ $name = $this->attr('name');
+ parse_str("$name=1", $parsed);
+
+ $name = array_keys($parsed);
+ $name = array_shift($name);
+
+ if(is_array($parsed[$name])) {
+ $key = array_keys($parsed[$name]);
+ $key = array_shift($key);
+ } else {
+ $key = null;
+ }
+
+ return array($name, $key);
+ }
+
+ /**
+ * Handles the useInput flag and set the value attribute accordingly
+ */
+ protected function prefillInput() {
+ global $INPUT;
+
+ list($name, $key) = $this->getInputName();
+ if(!$INPUT->has($name)) return;
+
+ if($key === null) {
+ $value = $INPUT->str($name);
+ } else {
+ $value = $INPUT->arr($name);
+ if(isset($value[$key])) {
+ $value = $value[$key];
+ } else {
+ $value = '';
+ }
+ }
+ $this->val($value);
+ }
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ protected function mainElementHTML() {
+ if($this->useInput) $this->prefillInput();
+ return '<input ' . buildAttributes($this->attrs()) . ' />';
+ }
+
+ /**
+ * The HTML representation of this element wrapped in a label
+ *
+ * @return string
+ */
+ public function toHTML() {
+ if($this->label) {
+ return '<label ' . buildAttributes($this->label->attrs()) . '>' . DOKU_LF .
+ '<span>' . hsc($this->label->val()) . '</span>' . DOKU_LF .
+ $this->mainElementHTML() . DOKU_LF .
+ '</label>';
+ } else {
+ return $this->mainElementHTML();
+ }
+ }
+}
diff --git a/platform/www/inc/Form/LabelElement.php b/platform/www/inc/Form/LabelElement.php
new file mode 100644
index 0000000..9c8d542
--- /dev/null
+++ b/platform/www/inc/Form/LabelElement.php
@@ -0,0 +1,27 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class Label
+ * @package dokuwiki\Form
+ */
+class LabelElement extends ValueElement {
+
+ /**
+ * Creates a new Label
+ *
+ * @param string $label This is is raw HTML and will not be escaped
+ */
+ public function __construct($label) {
+ parent::__construct('label', $label);
+ }
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ public function toHTML() {
+ return '<label ' . buildAttributes($this->attrs()) . '>' . $this->val() . '</label>';
+ }
+}
diff --git a/platform/www/inc/Form/LegacyForm.php b/platform/www/inc/Form/LegacyForm.php
new file mode 100644
index 0000000..b30c8df
--- /dev/null
+++ b/platform/www/inc/Form/LegacyForm.php
@@ -0,0 +1,181 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class LegacyForm
+ *
+ * Provides a compatibility layer to the old Doku_Form API
+ *
+ * This can be used to work with the modern API on forms provided by old events for
+ * example. When you start new forms, just use Form\Form
+ *
+ * @package dokuwiki\Form
+ */
+class LegacyForm extends Form {
+
+ /**
+ * Creates a new modern form from an old legacy Doku_Form
+ *
+ * @param \Doku_Form $oldform
+ */
+ public function __construct(\Doku_Form $oldform) {
+ parent::__construct($oldform->params);
+
+ $this->hidden = $oldform->_hidden;
+
+ foreach($oldform->_content as $element) {
+ list($ctl, $attr) = $this->parseLegacyAttr($element);
+
+ if(is_array($element)) {
+ switch($ctl['elem']) {
+ case 'wikitext':
+ $this->addTextarea('wikitext')
+ ->attrs($attr)
+ ->id('wiki__text')
+ ->val($ctl['text'])
+ ->addClass($ctl['class']);
+ break;
+ case 'textfield':
+ $this->addTextInput($ctl['name'], $ctl['text'])
+ ->attrs($attr)
+ ->id($ctl['id'])
+ ->addClass($ctl['class']);
+ break;
+ case 'passwordfield':
+ $this->addPasswordInput($ctl['name'], $ctl['text'])
+ ->attrs($attr)
+ ->id($ctl['id'])
+ ->addClass($ctl['class']);
+ break;
+ case 'checkboxfield':
+ $this->addCheckbox($ctl['name'], $ctl['text'])
+ ->attrs($attr)
+ ->id($ctl['id'])
+ ->addClass($ctl['class']);
+ break;
+ case 'radiofield':
+ $this->addRadioButton($ctl['name'], $ctl['text'])
+ ->attrs($attr)
+ ->id($ctl['id'])
+ ->addClass($ctl['class']);
+ break;
+ case 'tag':
+ $this->addTag($ctl['tag'])
+ ->attrs($attr)
+ ->attr('name', $ctl['name'])
+ ->id($ctl['id'])
+ ->addClass($ctl['class']);
+ break;
+ case 'opentag':
+ $this->addTagOpen($ctl['tag'])
+ ->attrs($attr)
+ ->attr('name', $ctl['name'])
+ ->id($ctl['id'])
+ ->addClass($ctl['class']);
+ break;
+ case 'closetag':
+ $this->addTagClose($ctl['tag']);
+ break;
+ case 'openfieldset':
+ $this->addFieldsetOpen($ctl['legend'])
+ ->attrs($attr)
+ ->attr('name', $ctl['name'])
+ ->id($ctl['id'])
+ ->addClass($ctl['class']);
+ break;
+ case 'closefieldset':
+ $this->addFieldsetClose();
+ break;
+ case 'button':
+ case 'field':
+ case 'fieldright':
+ case 'filefield':
+ case 'menufield':
+ case 'listboxfield':
+ throw new \UnexpectedValueException('Unsupported legacy field ' . $ctl['elem']);
+ break;
+ default:
+ throw new \UnexpectedValueException('Unknown legacy field ' . $ctl['elem']);
+
+ }
+ } else {
+ $this->addHTML($element);
+ }
+ }
+
+ }
+
+ /**
+ * Parses out what is the elements attributes and what is control info
+ *
+ * @param array $legacy
+ * @return array
+ */
+ protected function parseLegacyAttr($legacy) {
+ $attributes = array();
+ $control = array();
+
+ foreach($legacy as $key => $val) {
+ if($key[0] == '_') {
+ $control[substr($key, 1)] = $val;
+ } elseif($key == 'name') {
+ $control[$key] = $val;
+ } elseif($key == 'id') {
+ $control[$key] = $val;
+ } else {
+ $attributes[$key] = $val;
+ }
+ }
+
+ return array($control, $attributes);
+ }
+
+ /**
+ * Translates our types to the legacy types
+ *
+ * @param string $type
+ * @return string
+ */
+ protected function legacyType($type) {
+ static $types = array(
+ 'text' => 'textfield',
+ 'password' => 'passwordfield',
+ 'checkbox' => 'checkboxfield',
+ 'radio' => 'radiofield',
+ 'tagopen' => 'opentag',
+ 'tagclose' => 'closetag',
+ 'fieldsetopen' => 'openfieldset',
+ 'fieldsetclose' => 'closefieldset',
+ );
+ if(isset($types[$type])) return $types[$type];
+ return $type;
+ }
+
+ /**
+ * Creates an old legacy form from this modern form's data
+ *
+ * @return \Doku_Form
+ */
+ public function toLegacy() {
+ $this->balanceFieldsets();
+
+ $legacy = new \Doku_Form($this->attrs());
+ $legacy->_hidden = $this->hidden;
+ foreach($this->elements as $element) {
+ if(is_a($element, 'dokuwiki\Form\HTMLElement')) {
+ $legacy->_content[] = $element->toHTML();
+ } elseif(is_a($element, 'dokuwiki\Form\InputElement')) {
+ /** @var InputElement $element */
+ $data = $element->attrs();
+ $data['_elem'] = $this->legacyType($element->getType());
+ $label = $element->getLabel();
+ if($label) {
+ $data['_class'] = $label->attr('class');
+ }
+ $legacy->_content[] = $data;
+ }
+ }
+
+ return $legacy;
+ }
+}
diff --git a/platform/www/inc/Form/OptGroup.php b/platform/www/inc/Form/OptGroup.php
new file mode 100644
index 0000000..40149b1
--- /dev/null
+++ b/platform/www/inc/Form/OptGroup.php
@@ -0,0 +1,106 @@
+<?php
+
+namespace dokuwiki\Form;
+
+
+class OptGroup extends Element {
+ protected $options = array();
+ protected $value;
+
+ /**
+ * @param string $label The label text for this element (will be autoescaped)
+ * @param array $options The available options
+ */
+ public function __construct($label, $options) {
+ parent::__construct('optGroup', array('label' => $label));
+ $this->options($options);
+ }
+
+ /**
+ * Store the given value so it can be used during rendering
+ *
+ * This is intended to be only called from within @see DropdownElement::val()
+ *
+ * @param string $value
+ * @return bool true if an option with the given value exists, false otherwise
+ */
+ public function storeValue($value) {
+ $this->value = $value;
+ return isset($this->options[$value]);
+ }
+
+ /**
+ * Get or set the options of the optgroup
+ *
+ * Options can be given as associative array (value => label) or as an
+ * indexd array (label = value) or as an array of arrays. In the latter
+ * case an element has to look as follows:
+ * option-value => array (
+ * 'label' => option-label,
+ * 'attrs' => array (
+ * attr-key => attr-value, ...
+ * )
+ * )
+ *
+ * @param null|array $options
+ * @return $this|array
+ */
+ public function options($options = null) {
+ if($options === null) return $this->options;
+ if(!is_array($options)) throw new \InvalidArgumentException('Options have to be an array');
+ $this->options = array();
+ foreach($options as $key => $val) {
+ if (is_array($val)) {
+ if (!key_exists('label', $val)) throw new \InvalidArgumentException(
+ 'If option is given as array, it has to have a "label"-key!'
+ );
+ if (key_exists('attrs', $val) && is_array($val['attrs']) && key_exists('selected', $val['attrs'])) {
+ throw new \InvalidArgumentException(
+ 'Please use function "DropdownElement::val()" to set the selected option'
+ );
+ }
+ $this->options[$key] = $val;
+ } elseif(is_int($key)) {
+ $this->options[$val] = array('label' => (string) $val);
+ } else {
+ $this->options[$key] = array('label' => (string) $val);
+ }
+ }
+ return $this;
+ }
+
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ public function toHTML() {
+ if ($this->attributes['label'] === null) {
+ return $this->renderOptions();
+ }
+ $html = '<optgroup '. buildAttributes($this->attrs()) . '>';
+ $html .= $this->renderOptions();
+ $html .= '</optgroup>';
+ return $html;
+ }
+
+
+ /**
+ * @return string
+ */
+ protected function renderOptions() {
+ $html = '';
+ foreach($this->options as $key => $val) {
+ $selected = ((string)$key === (string)$this->value) ? ' selected="selected"' : '';
+ $attrs = '';
+ if (!empty($val['attrs']) && is_array($val['attrs'])) {
+ $attrs = buildAttributes($val['attrs']);
+ }
+ $html .= '<option' . $selected . ' value="' . hsc($key) . '" '.$attrs.'>';
+ $html .= hsc($val['label']);
+ $html .= '</option>';
+ }
+ return $html;
+ }
+}
diff --git a/platform/www/inc/Form/TagCloseElement.php b/platform/www/inc/Form/TagCloseElement.php
new file mode 100644
index 0000000..b6bf753
--- /dev/null
+++ b/platform/www/inc/Form/TagCloseElement.php
@@ -0,0 +1,88 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class TagCloseElement
+ *
+ * Creates an HTML close tag. You have to make sure it has been opened
+ * before or this will produce invalid HTML
+ *
+ * @package dokuwiki\Form
+ */
+class TagCloseElement extends ValueElement {
+
+ /**
+ * @param string $tag
+ * @param array $attributes
+ */
+ public function __construct($tag, $attributes = array()) {
+ parent::__construct('tagclose', $tag, $attributes);
+ }
+
+ /**
+ * do not call this
+ *
+ * @param string $class
+ * @return void
+ * @throws \BadMethodCallException
+ */
+ public function addClass($class) {
+ throw new \BadMethodCallException('You can\t add classes to closing tag');
+ }
+
+ /**
+ * do not call this
+ *
+ * @param null|string $id
+ * @return string
+ * @throws \BadMethodCallException
+ */
+ public function id($id = null) {
+ if ($id === null) {
+ return '';
+ } else {
+ throw new \BadMethodCallException('You can\t add ID to closing tag');
+ }
+ }
+
+ /**
+ * do not call this
+ *
+ * @param string $name
+ * @param null|string $value
+ * @return string
+ * @throws \BadMethodCallException
+ */
+ public function attr($name, $value = null) {
+ if ($value === null) {
+ return '';
+ } else {
+ throw new \BadMethodCallException('You can\t add attributes to closing tag');
+ }
+ }
+
+ /**
+ * do not call this
+ *
+ * @param array|null $attributes
+ * @return array
+ * @throws \BadMethodCallException
+ */
+ public function attrs($attributes = null) {
+ if ($attributes === null) {
+ return array();
+ } else {
+ throw new \BadMethodCallException('You can\t add attributes to closing tag');
+ }
+ }
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ public function toHTML() {
+ return '</'.$this->val().'>';
+ }
+
+}
diff --git a/platform/www/inc/Form/TagElement.php b/platform/www/inc/Form/TagElement.php
new file mode 100644
index 0000000..ea5144c
--- /dev/null
+++ b/platform/www/inc/Form/TagElement.php
@@ -0,0 +1,29 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class TagElement
+ *
+ * Creates a self closing HTML tag
+ *
+ * @package dokuwiki\Form
+ */
+class TagElement extends ValueElement {
+
+ /**
+ * @param string $tag
+ * @param array $attributes
+ */
+ public function __construct($tag, $attributes = array()) {
+ parent::__construct('tag', $tag, $attributes);
+ }
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ public function toHTML() {
+ return '<'.$this->val().' '.buildAttributes($this->attrs()).' />';
+ }
+}
diff --git a/platform/www/inc/Form/TagOpenElement.php b/platform/www/inc/Form/TagOpenElement.php
new file mode 100644
index 0000000..0afe97b
--- /dev/null
+++ b/platform/www/inc/Form/TagOpenElement.php
@@ -0,0 +1,30 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class TagOpenElement
+ *
+ * Creates an open HTML tag. You have to make sure you close it
+ * again or this will produce invalid HTML
+ *
+ * @package dokuwiki\Form
+ */
+class TagOpenElement extends ValueElement {
+
+ /**
+ * @param string $tag
+ * @param array $attributes
+ */
+ public function __construct($tag, $attributes = array()) {
+ parent::__construct('tagopen', $tag, $attributes);
+ }
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ public function toHTML() {
+ return '<'.$this->val().' '.buildAttributes($this->attrs()).'>';
+ }
+}
diff --git a/platform/www/inc/Form/TextareaElement.php b/platform/www/inc/Form/TextareaElement.php
new file mode 100644
index 0000000..92741ee
--- /dev/null
+++ b/platform/www/inc/Form/TextareaElement.php
@@ -0,0 +1,51 @@
+<?php
+namespace dokuwiki\Form;
+
+/**
+ * Class TextareaElement
+ * @package dokuwiki\Form
+ */
+class TextareaElement extends InputElement {
+
+ /**
+ * @var string the actual text within the area
+ */
+ protected $text;
+
+ /**
+ * @param string $name The name of this form element
+ * @param string $label The label text for this element
+ */
+ public function __construct($name, $label) {
+ parent::__construct('textarea', $name, $label);
+ $this->attr('dir', 'auto');
+ }
+
+ /**
+ * Get or set the element's value
+ *
+ * This is the preferred way of setting the element's value
+ *
+ * @param null|string $value
+ * @return string|$this
+ */
+ public function val($value = null) {
+ if($value !== null) {
+ $this->text = cleanText($value);
+ return $this;
+ }
+ return $this->text;
+ }
+
+ /**
+ * The HTML representation of this element
+ *
+ * @return string
+ */
+ protected function mainElementHTML() {
+ if($this->useInput) $this->prefillInput();
+ return '<textarea ' . buildAttributes($this->attrs()) . '>' .
+ formText($this->val()) . '</textarea>';
+ }
+
+}
diff --git a/platform/www/inc/Form/ValueElement.php b/platform/www/inc/Form/ValueElement.php
new file mode 100644
index 0000000..88db167
--- /dev/null
+++ b/platform/www/inc/Form/ValueElement.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace dokuwiki\Form;
+
+/**
+ * Class ValueElement
+ *
+ * Just like an Element but it's value is not part of its attributes
+ *
+ * What the value is (tag name, content, etc) is defined by the actual implementations
+ *
+ * @package dokuwiki\Form
+ */
+abstract class ValueElement extends Element {
+
+ /**
+ * @var string holds the element's value
+ */
+ protected $value = '';
+
+ /**
+ * @param string $type
+ * @param string $value
+ * @param array $attributes
+ */
+ public function __construct($type, $value, $attributes = array()) {
+ parent::__construct($type, $attributes);
+ $this->val($value);
+ }
+
+ /**
+ * Get or set the element's value
+ *
+ * @param null|string $value
+ * @return string|$this
+ */
+ public function val($value = null) {
+ if($value !== null) {
+ $this->value = $value;
+ return $this;
+ }
+ return $this->value;
+ }
+
+}
diff --git a/platform/www/inc/HTTP/DokuHTTPClient.php b/platform/www/inc/HTTP/DokuHTTPClient.php
new file mode 100644
index 0000000..b1db7e3
--- /dev/null
+++ b/platform/www/inc/HTTP/DokuHTTPClient.php
@@ -0,0 +1,77 @@
+<?php
+
+
+namespace dokuwiki\HTTP;
+
+
+
+/**
+ * Adds DokuWiki specific configs to the HTTP client
+ *
+ * @author Andreas Goetz <cpuidle@gmx.de>
+ */
+class DokuHTTPClient extends HTTPClient {
+
+ /**
+ * Constructor.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function __construct(){
+ global $conf;
+
+ // call parent constructor
+ parent::__construct();
+
+ // set some values from the config
+ $this->proxy_host = $conf['proxy']['host'];
+ $this->proxy_port = $conf['proxy']['port'];
+ $this->proxy_user = $conf['proxy']['user'];
+ $this->proxy_pass = conf_decodeString($conf['proxy']['pass']);
+ $this->proxy_ssl = $conf['proxy']['ssl'];
+ $this->proxy_except = $conf['proxy']['except'];
+
+ // allow enabling debugging via URL parameter (if debugging allowed)
+ if($conf['allowdebug']) {
+ if(
+ isset($_REQUEST['httpdebug']) ||
+ (
+ isset($_SERVER['HTTP_REFERER']) &&
+ strpos($_SERVER['HTTP_REFERER'], 'httpdebug') !== false
+ )
+ ) {
+ $this->debug = true;
+ }
+ }
+ }
+
+
+ /**
+ * Wraps an event around the parent function
+ *
+ * @triggers HTTPCLIENT_REQUEST_SEND
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ /**
+ * @param string $url
+ * @param string|array $data the post data either as array or raw data
+ * @param string $method
+ * @return bool
+ */
+ public function sendRequest($url,$data='',$method='GET'){
+ $httpdata = array('url' => $url,
+ 'data' => $data,
+ 'method' => $method);
+ $evt = new \Doku_Event('HTTPCLIENT_REQUEST_SEND',$httpdata);
+ if($evt->advise_before()){
+ $url = $httpdata['url'];
+ $data = $httpdata['data'];
+ $method = $httpdata['method'];
+ }
+ $evt->advise_after();
+ unset($evt);
+ return parent::sendRequest($url,$data,$method);
+ }
+
+}
+
diff --git a/platform/www/inc/HTTP/HTTPClient.php b/platform/www/inc/HTTP/HTTPClient.php
new file mode 100644
index 0000000..4aaf471
--- /dev/null
+++ b/platform/www/inc/HTTP/HTTPClient.php
@@ -0,0 +1,885 @@
+<?php
+
+namespace dokuwiki\HTTP;
+
+define('HTTP_NL',"\r\n");
+
+
+/**
+ * This class implements a basic HTTP client
+ *
+ * It supports POST and GET, Proxy usage, basic authentication,
+ * handles cookies and referers. It is based upon the httpclient
+ * function from the VideoDB project.
+ *
+ * @link http://www.splitbrain.org/go/videodb
+ * @author Andreas Goetz <cpuidle@gmx.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Tobias Sarnowski <sarnowski@new-thoughts.org>
+ */
+class HTTPClient {
+ //set these if you like
+ public $agent; // User agent
+ public $http; // HTTP version defaults to 1.0
+ public $timeout; // read timeout (seconds)
+ public $cookies;
+ public $referer;
+ public $max_redirect;
+ public $max_bodysize;
+ public $max_bodysize_abort = true; // if set, abort if the response body is bigger than max_bodysize
+ public $header_regexp; // if set this RE must match against the headers, else abort
+ public $headers;
+ public $debug;
+ public $start = 0.0; // for timings
+ public $keep_alive = true; // keep alive rocks
+
+ // don't set these, read on error
+ public $error;
+ public $redirect_count;
+
+ // read these after a successful request
+ public $status;
+ public $resp_body;
+ public $resp_headers;
+
+ // set these to do basic authentication
+ public $user;
+ public $pass;
+
+ // set these if you need to use a proxy
+ public $proxy_host;
+ public $proxy_port;
+ public $proxy_user;
+ public $proxy_pass;
+ public $proxy_ssl; //boolean set to true if your proxy needs SSL
+ public $proxy_except; // regexp of URLs to exclude from proxy
+
+ // list of kept alive connections
+ protected static $connections = array();
+
+ // what we use as boundary on multipart/form-data posts
+ protected $boundary = '---DokuWikiHTTPClient--4523452351';
+
+ /**
+ * Constructor.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function __construct(){
+ $this->agent = 'Mozilla/4.0 (compatible; DokuWiki HTTP Client; '.PHP_OS.')';
+ $this->timeout = 15;
+ $this->cookies = array();
+ $this->referer = '';
+ $this->max_redirect = 3;
+ $this->redirect_count = 0;
+ $this->status = 0;
+ $this->headers = array();
+ $this->http = '1.0';
+ $this->debug = false;
+ $this->max_bodysize = 0;
+ $this->header_regexp= '';
+ if(extension_loaded('zlib')) $this->headers['Accept-encoding'] = 'gzip';
+ $this->headers['Accept'] = 'text/xml,application/xml,application/xhtml+xml,'.
+ 'text/html,text/plain,image/png,image/jpeg,image/gif,*/*';
+ $this->headers['Accept-Language'] = 'en-us';
+ }
+
+
+ /**
+ * Simple function to do a GET request
+ *
+ * Returns the wanted page or false on an error;
+ *
+ * @param string $url The URL to fetch
+ * @param bool $sloppy304 Return body on 304 not modified
+ * @return false|string response body, false on error
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function get($url,$sloppy304=false){
+ if(!$this->sendRequest($url)) return false;
+ if($this->status == 304 && $sloppy304) return $this->resp_body;
+ if($this->status < 200 || $this->status > 206) return false;
+ return $this->resp_body;
+ }
+
+ /**
+ * Simple function to do a GET request with given parameters
+ *
+ * Returns the wanted page or false on an error.
+ *
+ * This is a convenience wrapper around get(). The given parameters
+ * will be correctly encoded and added to the given base URL.
+ *
+ * @param string $url The URL to fetch
+ * @param array $data Associative array of parameters
+ * @param bool $sloppy304 Return body on 304 not modified
+ * @return false|string response body, false on error
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function dget($url,$data,$sloppy304=false){
+ if(strpos($url,'?')){
+ $url .= '&';
+ }else{
+ $url .= '?';
+ }
+ $url .= $this->postEncode($data);
+ return $this->get($url,$sloppy304);
+ }
+
+ /**
+ * Simple function to do a POST request
+ *
+ * Returns the resulting page or false on an error;
+ *
+ * @param string $url The URL to fetch
+ * @param array $data Associative array of parameters
+ * @return false|string response body, false on error
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function post($url,$data){
+ if(!$this->sendRequest($url,$data,'POST')) return false;
+ if($this->status < 200 || $this->status > 206) return false;
+ return $this->resp_body;
+ }
+
+ /**
+ * Send an HTTP request
+ *
+ * This method handles the whole HTTP communication. It respects set proxy settings,
+ * builds the request headers, follows redirects and parses the response.
+ *
+ * Post data should be passed as associative array. When passed as string it will be
+ * sent as is. You will need to setup your own Content-Type header then.
+ *
+ * @param string $url - the complete URL
+ * @param mixed $data - the post data either as array or raw data
+ * @param string $method - HTTP Method usually GET or POST.
+ * @return bool - true on success
+ *
+ * @author Andreas Goetz <cpuidle@gmx.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function sendRequest($url,$data='',$method='GET'){
+ $this->start = $this->time();
+ $this->error = '';
+ $this->status = 0;
+ $this->resp_body = '';
+ $this->resp_headers = array();
+
+ // don't accept gzip if truncated bodies might occur
+ if($this->max_bodysize &&
+ !$this->max_bodysize_abort &&
+ $this->headers['Accept-encoding'] == 'gzip'){
+ unset($this->headers['Accept-encoding']);
+ }
+
+ // parse URL into bits
+ $uri = parse_url($url);
+ $server = $uri['host'];
+ $path = $uri['path'];
+ if(empty($path)) $path = '/';
+ if(!empty($uri['query'])) $path .= '?'.$uri['query'];
+ if(!empty($uri['port'])) $port = $uri['port'];
+ if(isset($uri['user'])) $this->user = $uri['user'];
+ if(isset($uri['pass'])) $this->pass = $uri['pass'];
+
+ // proxy setup
+ if($this->useProxyForUrl($url)){
+ $request_url = $url;
+ $server = $this->proxy_host;
+ $port = $this->proxy_port;
+ if (empty($port)) $port = 8080;
+ $use_tls = $this->proxy_ssl;
+ }else{
+ $request_url = $path;
+ if (!isset($port)) $port = ($uri['scheme'] == 'https') ? 443 : 80;
+ $use_tls = ($uri['scheme'] == 'https');
+ }
+
+ // add SSL stream prefix if needed - needs SSL support in PHP
+ if($use_tls) {
+ if(!in_array('ssl', stream_get_transports())) {
+ $this->status = -200;
+ $this->error = 'This PHP version does not support SSL - cannot connect to server';
+ }
+ $server = 'ssl://'.$server;
+ }
+
+ // prepare headers
+ $headers = $this->headers;
+ $headers['Host'] = $uri['host'];
+ if(!empty($uri['port'])) $headers['Host'].= ':'.$uri['port'];
+ $headers['User-Agent'] = $this->agent;
+ $headers['Referer'] = $this->referer;
+
+ if($method == 'POST'){
+ if(is_array($data)){
+ if (empty($headers['Content-Type'])) {
+ $headers['Content-Type'] = null;
+ }
+ switch ($headers['Content-Type']) {
+ case 'multipart/form-data':
+ $headers['Content-Type'] = 'multipart/form-data; boundary=' . $this->boundary;
+ $data = $this->postMultipartEncode($data);
+ break;
+ default:
+ $headers['Content-Type'] = 'application/x-www-form-urlencoded';
+ $data = $this->postEncode($data);
+ }
+ }
+ }elseif($method == 'GET'){
+ $data = ''; //no data allowed on GET requests
+ }
+
+ $contentlength = strlen($data);
+ if($contentlength) {
+ $headers['Content-Length'] = $contentlength;
+ }
+
+ if($this->user) {
+ $headers['Authorization'] = 'Basic '.base64_encode($this->user.':'.$this->pass);
+ }
+ if($this->proxy_user) {
+ $headers['Proxy-Authorization'] = 'Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass);
+ }
+
+ // already connected?
+ $connectionId = $this->uniqueConnectionId($server,$port);
+ $this->debug('connection pool', self::$connections);
+ $socket = null;
+ if (isset(self::$connections[$connectionId])) {
+ $this->debug('reusing connection', $connectionId);
+ $socket = self::$connections[$connectionId];
+ }
+ if (is_null($socket) || feof($socket)) {
+ $this->debug('opening connection', $connectionId);
+ // open socket
+ $socket = @fsockopen($server,$port,$errno, $errstr, $this->timeout);
+ if (!$socket){
+ $this->status = -100;
+ $this->error = "Could not connect to $server:$port\n$errstr ($errno)";
+ return false;
+ }
+
+ // try establish a CONNECT tunnel for SSL
+ try {
+ if($this->ssltunnel($socket, $request_url)){
+ // no keep alive for tunnels
+ $this->keep_alive = false;
+ // tunnel is authed already
+ if(isset($headers['Proxy-Authentication'])) unset($headers['Proxy-Authentication']);
+ }
+ } catch (HTTPClientException $e) {
+ $this->status = $e->getCode();
+ $this->error = $e->getMessage();
+ fclose($socket);
+ return false;
+ }
+
+ // keep alive?
+ if ($this->keep_alive) {
+ self::$connections[$connectionId] = $socket;
+ } else {
+ unset(self::$connections[$connectionId]);
+ }
+ }
+
+ if ($this->keep_alive && !$this->useProxyForUrl($request_url)) {
+ // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive
+ // connection token to a proxy server. We still do keep the connection the
+ // proxy alive (well except for CONNECT tunnels)
+ $headers['Connection'] = 'Keep-Alive';
+ } else {
+ $headers['Connection'] = 'Close';
+ }
+
+ try {
+ //set non-blocking
+ stream_set_blocking($socket, 0);
+
+ // build request
+ $request = "$method $request_url HTTP/".$this->http.HTTP_NL;
+ $request .= $this->buildHeaders($headers);
+ $request .= $this->getCookies();
+ $request .= HTTP_NL;
+ $request .= $data;
+
+ $this->debug('request',$request);
+ $this->sendData($socket, $request, 'request');
+
+ // read headers from socket
+ $r_headers = '';
+ do{
+ $r_line = $this->readLine($socket, 'headers');
+ $r_headers .= $r_line;
+ }while($r_line != "\r\n" && $r_line != "\n");
+
+ $this->debug('response headers',$r_headers);
+
+ // check if expected body size exceeds allowance
+ if($this->max_bodysize && preg_match('/\r?\nContent-Length:\s*(\d+)\r?\n/i',$r_headers,$match)){
+ if($match[1] > $this->max_bodysize){
+ if ($this->max_bodysize_abort)
+ throw new HTTPClientException('Reported content length exceeds allowed response size');
+ else
+ $this->error = 'Reported content length exceeds allowed response size';
+ }
+ }
+
+ // get Status
+ if (!preg_match('/^HTTP\/(\d\.\d)\s*(\d+).*?\n/s', $r_headers, $m))
+ throw new HTTPClientException('Server returned bad answer '.$r_headers);
+
+ $this->status = $m[2];
+
+ // handle headers and cookies
+ $this->resp_headers = $this->parseHeaders($r_headers);
+ if(isset($this->resp_headers['set-cookie'])){
+ foreach ((array) $this->resp_headers['set-cookie'] as $cookie){
+ list($cookie) = explode(';',$cookie,2);
+ list($key,$val) = explode('=',$cookie,2);
+ $key = trim($key);
+ if($val == 'deleted'){
+ if(isset($this->cookies[$key])){
+ unset($this->cookies[$key]);
+ }
+ }elseif($key){
+ $this->cookies[$key] = $val;
+ }
+ }
+ }
+
+ $this->debug('Object headers',$this->resp_headers);
+
+ // check server status code to follow redirect
+ if($this->status == 301 || $this->status == 302 ){
+ if (empty($this->resp_headers['location'])){
+ throw new HTTPClientException('Redirect but no Location Header found');
+ }elseif($this->redirect_count == $this->max_redirect){
+ throw new HTTPClientException('Maximum number of redirects exceeded');
+ }else{
+ // close the connection because we don't handle content retrieval here
+ // that's the easiest way to clean up the connection
+ fclose($socket);
+ unset(self::$connections[$connectionId]);
+
+ $this->redirect_count++;
+ $this->referer = $url;
+ // handle non-RFC-compliant relative redirects
+ if (!preg_match('/^http/i', $this->resp_headers['location'])){
+ if($this->resp_headers['location'][0] != '/'){
+ $this->resp_headers['location'] = $uri['scheme'].'://'.$uri['host'].':'.$uri['port'].
+ dirname($uri['path']).'/'.$this->resp_headers['location'];
+ }else{
+ $this->resp_headers['location'] = $uri['scheme'].'://'.$uri['host'].':'.$uri['port'].
+ $this->resp_headers['location'];
+ }
+ }
+ // perform redirected request, always via GET (required by RFC)
+ return $this->sendRequest($this->resp_headers['location'],array(),'GET');
+ }
+ }
+
+ // check if headers are as expected
+ if($this->header_regexp && !preg_match($this->header_regexp,$r_headers))
+ throw new HTTPClientException('The received headers did not match the given regexp');
+
+ //read body (with chunked encoding if needed)
+ $r_body = '';
+ if(
+ (
+ isset($this->resp_headers['transfer-encoding']) &&
+ $this->resp_headers['transfer-encoding'] == 'chunked'
+ ) || (
+ isset($this->resp_headers['transfer-coding']) &&
+ $this->resp_headers['transfer-coding'] == 'chunked'
+ )
+ ) {
+ $abort = false;
+ do {
+ $chunk_size = '';
+ while (preg_match('/^[a-zA-Z0-9]?$/',$byte=$this->readData($socket,1,'chunk'))){
+ // read chunksize until \r
+ $chunk_size .= $byte;
+ if (strlen($chunk_size) > 128) // set an abritrary limit on the size of chunks
+ throw new HTTPClientException('Allowed response size exceeded');
+ }
+ $this->readLine($socket, 'chunk'); // readtrailing \n
+ $chunk_size = hexdec($chunk_size);
+
+ if($this->max_bodysize && $chunk_size+strlen($r_body) > $this->max_bodysize){
+ if ($this->max_bodysize_abort)
+ throw new HTTPClientException('Allowed response size exceeded');
+ $this->error = 'Allowed response size exceeded';
+ $chunk_size = $this->max_bodysize - strlen($r_body);
+ $abort = true;
+ }
+
+ if ($chunk_size > 0) {
+ $r_body .= $this->readData($socket, $chunk_size, 'chunk');
+ $this->readData($socket, 2, 'chunk'); // read trailing \r\n
+ }
+ } while ($chunk_size && !$abort);
+ }elseif(isset($this->resp_headers['content-length']) && !isset($this->resp_headers['transfer-encoding'])){
+ /* RFC 2616
+ * If a message is received with both a Transfer-Encoding header field and a Content-Length
+ * header field, the latter MUST be ignored.
+ */
+
+ // read up to the content-length or max_bodysize
+ // for keep alive we need to read the whole message to clean up the socket for the next read
+ if(
+ !$this->keep_alive &&
+ $this->max_bodysize &&
+ $this->max_bodysize < $this->resp_headers['content-length']
+ ) {
+ $length = $this->max_bodysize + 1;
+ }else{
+ $length = $this->resp_headers['content-length'];
+ }
+
+ $r_body = $this->readData($socket, $length, 'response (content-length limited)', true);
+ }elseif( !isset($this->resp_headers['transfer-encoding']) && $this->max_bodysize && !$this->keep_alive){
+ $r_body = $this->readData($socket, $this->max_bodysize+1, 'response (content-length limited)', true);
+ } elseif ((int)$this->status === 204) {
+ // request has no content
+ } else{
+ // read entire socket
+ while (!feof($socket)) {
+ $r_body .= $this->readData($socket, 4096, 'response (unlimited)', true);
+ }
+ }
+
+ // recheck body size, we might have read max_bodysize+1 or even the whole body, so we abort late here
+ if($this->max_bodysize){
+ if(strlen($r_body) > $this->max_bodysize){
+ if ($this->max_bodysize_abort) {
+ throw new HTTPClientException('Allowed response size exceeded');
+ } else {
+ $this->error = 'Allowed response size exceeded';
+ }
+ }
+ }
+
+ } catch (HTTPClientException $err) {
+ $this->error = $err->getMessage();
+ if ($err->getCode())
+ $this->status = $err->getCode();
+ unset(self::$connections[$connectionId]);
+ fclose($socket);
+ return false;
+ }
+
+ if (!$this->keep_alive ||
+ (isset($this->resp_headers['connection']) && $this->resp_headers['connection'] == 'Close')) {
+ // close socket
+ fclose($socket);
+ unset(self::$connections[$connectionId]);
+ }
+
+ // decode gzip if needed
+ if(isset($this->resp_headers['content-encoding']) &&
+ $this->resp_headers['content-encoding'] == 'gzip' &&
+ strlen($r_body) > 10 && substr($r_body,0,3)=="\x1f\x8b\x08"){
+ $this->resp_body = @gzinflate(substr($r_body, 10));
+ if($this->resp_body === false){
+ $this->error = 'Failed to decompress gzip encoded content';
+ $this->resp_body = $r_body;
+ }
+ }else{
+ $this->resp_body = $r_body;
+ }
+
+ $this->debug('response body',$this->resp_body);
+ $this->redirect_count = 0;
+ return true;
+ }
+
+ /**
+ * Tries to establish a CONNECT tunnel via Proxy
+ *
+ * Protocol, Servername and Port will be stripped from the request URL when a successful CONNECT happened
+ *
+ * @param resource &$socket
+ * @param string &$requesturl
+ * @throws HTTPClientException when a tunnel is needed but could not be established
+ * @return bool true if a tunnel was established
+ */
+ protected function ssltunnel(&$socket, &$requesturl){
+ if(!$this->useProxyForUrl($requesturl)) return false;
+ $requestinfo = parse_url($requesturl);
+ if($requestinfo['scheme'] != 'https') return false;
+ if(!$requestinfo['port']) $requestinfo['port'] = 443;
+
+ // build request
+ $request = "CONNECT {$requestinfo['host']}:{$requestinfo['port']} HTTP/1.0".HTTP_NL;
+ $request .= "Host: {$requestinfo['host']}".HTTP_NL;
+ if($this->proxy_user) {
+ $request .= 'Proxy-Authorization: Basic '.base64_encode($this->proxy_user.':'.$this->proxy_pass).HTTP_NL;
+ }
+ $request .= HTTP_NL;
+
+ $this->debug('SSL Tunnel CONNECT',$request);
+ $this->sendData($socket, $request, 'SSL Tunnel CONNECT');
+
+ // read headers from socket
+ $r_headers = '';
+ do{
+ $r_line = $this->readLine($socket, 'headers');
+ $r_headers .= $r_line;
+ }while($r_line != "\r\n" && $r_line != "\n");
+
+ $this->debug('SSL Tunnel Response',$r_headers);
+ if(preg_match('/^HTTP\/1\.[01] 200/i',$r_headers)){
+ // set correct peer name for verification (enabled since PHP 5.6)
+ stream_context_set_option($socket, 'ssl', 'peer_name', $requestinfo['host']);
+
+ // SSLv3 is broken, use only TLS connections.
+ // @link https://bugs.php.net/69195
+ if (PHP_VERSION_ID >= 50600 && PHP_VERSION_ID <= 50606) {
+ $cryptoMethod = STREAM_CRYPTO_METHOD_TLS_CLIENT;
+ } else {
+ // actually means neither SSLv2 nor SSLv3
+ $cryptoMethod = STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
+ }
+
+ if (@stream_socket_enable_crypto($socket, true, $cryptoMethod)) {
+ $requesturl = $requestinfo['path'].
+ (!empty($requestinfo['query'])?'?'.$requestinfo['query']:'');
+ return true;
+ }
+
+ throw new HTTPClientException(
+ 'Failed to set up crypto for secure connection to '.$requestinfo['host'], -151
+ );
+ }
+
+ throw new HTTPClientException('Failed to establish secure proxy connection', -150);
+ }
+
+ /**
+ * Safely write data to a socket
+ *
+ * @param resource $socket An open socket handle
+ * @param string $data The data to write
+ * @param string $message Description of what is being read
+ * @throws HTTPClientException
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function sendData($socket, $data, $message) {
+ // send request
+ $towrite = strlen($data);
+ $written = 0;
+ while($written < $towrite){
+ // check timeout
+ $time_used = $this->time() - $this->start;
+ if($time_used > $this->timeout)
+ throw new HTTPClientException(sprintf('Timeout while sending %s (%.3fs)',$message, $time_used), -100);
+ if(feof($socket))
+ throw new HTTPClientException("Socket disconnected while writing $message");
+
+ // select parameters
+ $sel_r = null;
+ $sel_w = array($socket);
+ $sel_e = null;
+ // wait for stream ready or timeout (1sec)
+ if(@stream_select($sel_r,$sel_w,$sel_e,1) === false){
+ usleep(1000);
+ continue;
+ }
+
+ // write to stream
+ $nbytes = fwrite($socket, substr($data,$written,4096));
+ if($nbytes === false)
+ throw new HTTPClientException("Failed writing to socket while sending $message", -100);
+ $written += $nbytes;
+ }
+ }
+
+ /**
+ * Safely read data from a socket
+ *
+ * Reads up to a given number of bytes or throws an exception if the
+ * response times out or ends prematurely.
+ *
+ * @param resource $socket An open socket handle in non-blocking mode
+ * @param int $nbytes Number of bytes to read
+ * @param string $message Description of what is being read
+ * @param bool $ignore_eof End-of-file is not an error if this is set
+ * @throws HTTPClientException
+ * @return string
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function readData($socket, $nbytes, $message, $ignore_eof = false) {
+ $r_data = '';
+ // Does not return immediately so timeout and eof can be checked
+ if ($nbytes < 0) $nbytes = 0;
+ $to_read = $nbytes;
+ do {
+ $time_used = $this->time() - $this->start;
+ if ($time_used > $this->timeout)
+ throw new HTTPClientException(
+ sprintf('Timeout while reading %s after %d bytes (%.3fs)', $message,
+ strlen($r_data), $time_used), -100);
+ if(feof($socket)) {
+ if(!$ignore_eof)
+ throw new HTTPClientException("Premature End of File (socket) while reading $message");
+ break;
+ }
+
+ if ($to_read > 0) {
+ // select parameters
+ $sel_r = array($socket);
+ $sel_w = null;
+ $sel_e = null;
+ // wait for stream ready or timeout (1sec)
+ if(@stream_select($sel_r,$sel_w,$sel_e,1) === false){
+ usleep(1000);
+ continue;
+ }
+
+ $bytes = fread($socket, $to_read);
+ if($bytes === false)
+ throw new HTTPClientException("Failed reading from socket while reading $message", -100);
+ $r_data .= $bytes;
+ $to_read -= strlen($bytes);
+ }
+ } while ($to_read > 0 && strlen($r_data) < $nbytes);
+ return $r_data;
+ }
+
+ /**
+ * Safely read a \n-terminated line from a socket
+ *
+ * Always returns a complete line, including the terminating \n.
+ *
+ * @param resource $socket An open socket handle in non-blocking mode
+ * @param string $message Description of what is being read
+ * @throws HTTPClientException
+ * @return string
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function readLine($socket, $message) {
+ $r_data = '';
+ do {
+ $time_used = $this->time() - $this->start;
+ if ($time_used > $this->timeout)
+ throw new HTTPClientException(
+ sprintf('Timeout while reading %s (%.3fs) >%s<', $message, $time_used, $r_data),
+ -100);
+ if(feof($socket))
+ throw new HTTPClientException("Premature End of File (socket) while reading $message");
+
+ // select parameters
+ $sel_r = array($socket);
+ $sel_w = null;
+ $sel_e = null;
+ // wait for stream ready or timeout (1sec)
+ if(@stream_select($sel_r,$sel_w,$sel_e,1) === false){
+ usleep(1000);
+ continue;
+ }
+
+ $r_data = fgets($socket, 1024);
+ } while (!preg_match('/\n$/',$r_data));
+ return $r_data;
+ }
+
+ /**
+ * print debug info
+ *
+ * Uses _debug_text or _debug_html depending on the SAPI name
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $info
+ * @param mixed $var
+ */
+ protected function debug($info,$var=null){
+ if(!$this->debug) return;
+ if(php_sapi_name() == 'cli'){
+ $this->debugText($info, $var);
+ }else{
+ $this->debugHtml($info, $var);
+ }
+ }
+
+ /**
+ * print debug info as HTML
+ *
+ * @param string $info
+ * @param mixed $var
+ */
+ protected function debugHtml($info, $var=null){
+ print '<b>'.$info.'</b> '.($this->time() - $this->start).'s<br />';
+ if(!is_null($var)){
+ ob_start();
+ print_r($var);
+ $content = htmlspecialchars(ob_get_contents());
+ ob_end_clean();
+ print '<pre>'.$content.'</pre>';
+ }
+ }
+
+ /**
+ * prints debug info as plain text
+ *
+ * @param string $info
+ * @param mixed $var
+ */
+ protected function debugText($info, $var=null){
+ print '*'.$info.'* '.($this->time() - $this->start)."s\n";
+ if(!is_null($var)) print_r($var);
+ print "\n-----------------------------------------------\n";
+ }
+
+ /**
+ * Return current timestamp in microsecond resolution
+ *
+ * @return float
+ */
+ protected static function time(){
+ list($usec, $sec) = explode(" ", microtime());
+ return ((float)$usec + (float)$sec);
+ }
+
+ /**
+ * convert given header string to Header array
+ *
+ * All Keys are lowercased.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $string
+ * @return array
+ */
+ protected function parseHeaders($string){
+ $headers = array();
+ $lines = explode("\n",$string);
+ array_shift($lines); //skip first line (status)
+ foreach($lines as $line){
+ @list($key, $val) = explode(':',$line,2);
+ $key = trim($key);
+ $val = trim($val);
+ $key = strtolower($key);
+ if(!$key) continue;
+ if(isset($headers[$key])){
+ if(is_array($headers[$key])){
+ $headers[$key][] = $val;
+ }else{
+ $headers[$key] = array($headers[$key],$val);
+ }
+ }else{
+ $headers[$key] = $val;
+ }
+ }
+ return $headers;
+ }
+
+ /**
+ * convert given header array to header string
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $headers
+ * @return string
+ */
+ protected function buildHeaders($headers){
+ $string = '';
+ foreach($headers as $key => $value){
+ if($value === '') continue;
+ $string .= $key.': '.$value.HTTP_NL;
+ }
+ return $string;
+ }
+
+ /**
+ * get cookies as http header string
+ *
+ * @author Andreas Goetz <cpuidle@gmx.de>
+ *
+ * @return string
+ */
+ protected function getCookies(){
+ $headers = '';
+ foreach ($this->cookies as $key => $val){
+ $headers .= "$key=$val; ";
+ }
+ $headers = substr($headers, 0, -2);
+ if ($headers) $headers = "Cookie: $headers".HTTP_NL;
+ return $headers;
+ }
+
+ /**
+ * Encode data for posting
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data
+ * @return string
+ */
+ protected function postEncode($data){
+ return http_build_query($data,'','&');
+ }
+
+ /**
+ * Encode data for posting using multipart encoding
+ *
+ * @fixme use of urlencode might be wrong here
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data
+ * @return string
+ */
+ protected function postMultipartEncode($data){
+ $boundary = '--'.$this->boundary;
+ $out = '';
+ foreach($data as $key => $val){
+ $out .= $boundary.HTTP_NL;
+ if(!is_array($val)){
+ $out .= 'Content-Disposition: form-data; name="'.urlencode($key).'"'.HTTP_NL;
+ $out .= HTTP_NL; // end of headers
+ $out .= $val;
+ $out .= HTTP_NL;
+ }else{
+ $out .= 'Content-Disposition: form-data; name="'.urlencode($key).'"';
+ if($val['filename']) $out .= '; filename="'.urlencode($val['filename']).'"';
+ $out .= HTTP_NL;
+ if($val['mimetype']) $out .= 'Content-Type: '.$val['mimetype'].HTTP_NL;
+ $out .= HTTP_NL; // end of headers
+ $out .= $val['body'];
+ $out .= HTTP_NL;
+ }
+ }
+ $out .= "$boundary--".HTTP_NL;
+ return $out;
+ }
+
+ /**
+ * Generates a unique identifier for a connection.
+ *
+ * @param string $server
+ * @param string $port
+ * @return string unique identifier
+ */
+ protected function uniqueConnectionId($server, $port) {
+ return "$server:$port";
+ }
+
+ /**
+ * Should the Proxy be used for the given URL?
+ *
+ * Checks the exceptions
+ *
+ * @param string $url
+ * @return bool
+ */
+ protected function useProxyForUrl($url) {
+ return $this->proxy_host && (!$this->proxy_except || !preg_match('/' . $this->proxy_except . '/i', $url));
+ }
+}
diff --git a/platform/www/inc/HTTP/HTTPClientException.php b/platform/www/inc/HTTP/HTTPClientException.php
new file mode 100644
index 0000000..5b8f4ee
--- /dev/null
+++ b/platform/www/inc/HTTP/HTTPClientException.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace dokuwiki\HTTP;
+
+use Exception;
+
+class HTTPClientException extends Exception
+{
+
+}
diff --git a/platform/www/inc/IXR_Library.php b/platform/www/inc/IXR_Library.php
new file mode 100644
index 0000000..bb1655f
--- /dev/null
+++ b/platform/www/inc/IXR_Library.php
@@ -0,0 +1,1135 @@
+<?php
+
+use dokuwiki\HTTP\DokuHTTPClient;
+
+/**
+ * IXR - The Incutio XML-RPC Library
+ *
+ * Copyright (c) 2010, Incutio Ltd.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * - Neither the name of Incutio Ltd. nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package IXR
+ * @since 1.5
+ *
+ * @copyright Incutio Ltd 2010 (http://www.incutio.com)
+ * @version 1.7.4 7th September 2010
+ * @author Simon Willison
+ * @link http://scripts.incutio.com/xmlrpc/ Site/manual
+ *
+ * Modified for DokuWiki
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class IXR_Value {
+
+ /** @var IXR_Value[]|IXR_Date|IXR_Base64|int|bool|double|string */
+ var $data;
+ /** @var string */
+ var $type;
+
+ /**
+ * @param mixed $data
+ * @param bool $type
+ */
+ function __construct($data, $type = false) {
+ $this->data = $data;
+ if(!$type) {
+ $type = $this->calculateType();
+ }
+ $this->type = $type;
+ if($type == 'struct') {
+ // Turn all the values in the array in to new IXR_Value objects
+ foreach($this->data as $key => $value) {
+ $this->data[$key] = new IXR_Value($value);
+ }
+ }
+ if($type == 'array') {
+ for($i = 0, $j = count($this->data); $i < $j; $i++) {
+ $this->data[$i] = new IXR_Value($this->data[$i]);
+ }
+ }
+ }
+
+ /**
+ * @return string
+ */
+ function calculateType() {
+ if($this->data === true || $this->data === false) {
+ return 'boolean';
+ }
+ if(is_integer($this->data)) {
+ return 'int';
+ }
+ if(is_double($this->data)) {
+ return 'double';
+ }
+
+ // Deal with IXR object types base64 and date
+ if(is_object($this->data) && is_a($this->data, 'IXR_Date')) {
+ return 'date';
+ }
+ if(is_object($this->data) && is_a($this->data, 'IXR_Base64')) {
+ return 'base64';
+ }
+
+ // If it is a normal PHP object convert it in to a struct
+ if(is_object($this->data)) {
+ $this->data = get_object_vars($this->data);
+ return 'struct';
+ }
+ if(!is_array($this->data)) {
+ return 'string';
+ }
+
+ // We have an array - is it an array or a struct?
+ if($this->isStruct($this->data)) {
+ return 'struct';
+ } else {
+ return 'array';
+ }
+ }
+
+ /**
+ * @return bool|string
+ */
+ function getXml() {
+ // Return XML for this value
+ switch($this->type) {
+ case 'boolean':
+ return '<boolean>' . (($this->data) ? '1' : '0') . '</boolean>';
+ break;
+ case 'int':
+ return '<int>' . $this->data . '</int>';
+ break;
+ case 'double':
+ return '<double>' . $this->data . '</double>';
+ break;
+ case 'string':
+ return '<string>' . htmlspecialchars($this->data) . '</string>';
+ break;
+ case 'array':
+ $return = '<array><data>' . "\n";
+ foreach($this->data as $item) {
+ $return .= ' <value>' . $item->getXml() . "</value>\n";
+ }
+ $return .= '</data></array>';
+ return $return;
+ break;
+ case 'struct':
+ $return = '<struct>' . "\n";
+ foreach($this->data as $name => $value) {
+ $return .= " <member><name>$name</name><value>";
+ $return .= $value->getXml() . "</value></member>\n";
+ }
+ $return .= '</struct>';
+ return $return;
+ break;
+ case 'date':
+ case 'base64':
+ return $this->data->getXml();
+ break;
+ }
+ return false;
+ }
+
+ /**
+ * Checks whether or not the supplied array is a struct or not
+ *
+ * @param array $array
+ * @return boolean
+ */
+ function isStruct($array) {
+ $expected = 0;
+ foreach($array as $key => $value) {
+ if((string) $key != (string) $expected) {
+ return true;
+ }
+ $expected++;
+ }
+ return false;
+ }
+}
+
+/**
+ * IXR_MESSAGE
+ *
+ * @package IXR
+ * @since 1.5
+ *
+ */
+class IXR_Message {
+ var $message;
+ var $messageType; // methodCall / methodResponse / fault
+ var $faultCode;
+ var $faultString;
+ var $methodName;
+ var $params;
+
+ // Current variable stacks
+ var $_arraystructs = array(); // The stack used to keep track of the current array/struct
+ var $_arraystructstypes = array(); // Stack keeping track of if things are structs or array
+ var $_currentStructName = array(); // A stack as well
+ var $_param;
+ var $_value;
+ var $_currentTag;
+ var $_currentTagContents;
+ var $_lastseen;
+ // The XML parser
+ var $_parser;
+
+ /**
+ * @param string $message
+ */
+ function __construct($message) {
+ $this->message =& $message;
+ }
+
+ /**
+ * @return bool
+ */
+ function parse() {
+ // first remove the XML declaration
+ // merged from WP #10698 - this method avoids the RAM usage of preg_replace on very large messages
+ $header = preg_replace('/<\?xml.*?\?' . '>/', '', substr($this->message, 0, 100), 1);
+ $this->message = substr_replace($this->message, $header, 0, 100);
+
+ // workaround for a bug in PHP/libxml2, see http://bugs.php.net/bug.php?id=45996
+ $this->message = str_replace('&lt;', '&#60;', $this->message);
+ $this->message = str_replace('&gt;', '&#62;', $this->message);
+ $this->message = str_replace('&amp;', '&#38;', $this->message);
+ $this->message = str_replace('&apos;', '&#39;', $this->message);
+ $this->message = str_replace('&quot;', '&#34;', $this->message);
+ $this->message = str_replace("\x0b", ' ', $this->message); //vertical tab
+ if(trim($this->message) == '') {
+ return false;
+ }
+ $this->_parser = xml_parser_create();
+ // Set XML parser to take the case of tags in to account
+ xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, false);
+ // Set XML parser callback functions
+ xml_set_object($this->_parser, $this);
+ xml_set_element_handler($this->_parser, 'tag_open', 'tag_close');
+ xml_set_character_data_handler($this->_parser, 'cdata');
+ $chunk_size = 262144; // 256Kb, parse in chunks to avoid the RAM usage on very large messages
+ $final = false;
+ do {
+ if(strlen($this->message) <= $chunk_size) {
+ $final = true;
+ }
+ $part = substr($this->message, 0, $chunk_size);
+ $this->message = substr($this->message, $chunk_size);
+ if(!xml_parse($this->_parser, $part, $final)) {
+ return false;
+ }
+ if($final) {
+ break;
+ }
+ } while(true);
+ xml_parser_free($this->_parser);
+
+ // Grab the error messages, if any
+ if($this->messageType == 'fault') {
+ $this->faultCode = $this->params[0]['faultCode'];
+ $this->faultString = $this->params[0]['faultString'];
+ }
+ return true;
+ }
+
+ /**
+ * @param $parser
+ * @param string $tag
+ * @param $attr
+ */
+ function tag_open($parser, $tag, $attr) {
+ $this->_currentTagContents = '';
+ $this->_currentTag = $tag;
+
+ switch($tag) {
+ case 'methodCall':
+ case 'methodResponse':
+ case 'fault':
+ $this->messageType = $tag;
+ break;
+ /* Deal with stacks of arrays and structs */
+ case 'data': // data is to all intents and purposes more interesting than array
+ $this->_arraystructstypes[] = 'array';
+ $this->_arraystructs[] = array();
+ break;
+ case 'struct':
+ $this->_arraystructstypes[] = 'struct';
+ $this->_arraystructs[] = array();
+ break;
+ }
+ $this->_lastseen = $tag;
+ }
+
+ /**
+ * @param $parser
+ * @param string $cdata
+ */
+ function cdata($parser, $cdata) {
+ $this->_currentTagContents .= $cdata;
+ }
+
+ /**
+ * @param $parser
+ * @param $tag
+ */
+ function tag_close($parser, $tag) {
+ $value = null;
+ $valueFlag = false;
+ switch($tag) {
+ case 'int':
+ case 'i4':
+ $value = (int) trim($this->_currentTagContents);
+ $valueFlag = true;
+ break;
+ case 'double':
+ $value = (double) trim($this->_currentTagContents);
+ $valueFlag = true;
+ break;
+ case 'string':
+ $value = (string) $this->_currentTagContents;
+ $valueFlag = true;
+ break;
+ case 'dateTime.iso8601':
+ $value = new IXR_Date(trim($this->_currentTagContents));
+ $valueFlag = true;
+ break;
+ case 'value':
+ // "If no type is indicated, the type is string."
+ if($this->_lastseen == 'value') {
+ $value = (string) $this->_currentTagContents;
+ $valueFlag = true;
+ }
+ break;
+ case 'boolean':
+ $value = (boolean) trim($this->_currentTagContents);
+ $valueFlag = true;
+ break;
+ case 'base64':
+ $value = base64_decode($this->_currentTagContents);
+ $valueFlag = true;
+ break;
+ /* Deal with stacks of arrays and structs */
+ case 'data':
+ case 'struct':
+ $value = array_pop($this->_arraystructs);
+ array_pop($this->_arraystructstypes);
+ $valueFlag = true;
+ break;
+ case 'member':
+ array_pop($this->_currentStructName);
+ break;
+ case 'name':
+ $this->_currentStructName[] = trim($this->_currentTagContents);
+ break;
+ case 'methodName':
+ $this->methodName = trim($this->_currentTagContents);
+ break;
+ }
+
+ if($valueFlag) {
+ if(count($this->_arraystructs) > 0) {
+ // Add value to struct or array
+ if($this->_arraystructstypes[count($this->_arraystructstypes) - 1] == 'struct') {
+ // Add to struct
+ $this->_arraystructs[count($this->_arraystructs) - 1][$this->_currentStructName[count($this->_currentStructName) - 1]] = $value;
+ } else {
+ // Add to array
+ $this->_arraystructs[count($this->_arraystructs) - 1][] = $value;
+ }
+ } else {
+ // Just add as a parameter
+ $this->params[] = $value;
+ }
+ }
+ $this->_currentTagContents = '';
+ $this->_lastseen = $tag;
+ }
+}
+
+/**
+ * IXR_Server
+ *
+ * @package IXR
+ * @since 1.5
+ */
+class IXR_Server {
+ var $data;
+ /** @var array */
+ var $callbacks = array();
+ var $message;
+ /** @var array */
+ var $capabilities;
+
+ /**
+ * @param array|bool $callbacks
+ * @param bool $data
+ * @param bool $wait
+ */
+ function __construct($callbacks = false, $data = false, $wait = false) {
+ $this->setCapabilities();
+ if($callbacks) {
+ $this->callbacks = $callbacks;
+ }
+ $this->setCallbacks();
+
+ if(!$wait) {
+ $this->serve($data);
+ }
+ }
+
+ /**
+ * @param bool|string $data
+ */
+ function serve($data = false) {
+ if(!$data) {
+
+ $postData = trim(http_get_raw_post_data());
+ if(!$postData) {
+ header('Content-Type: text/plain'); // merged from WP #9093
+ die('XML-RPC server accepts POST requests only.');
+ }
+ $data = $postData;
+ }
+ $this->message = new IXR_Message($data);
+ if(!$this->message->parse()) {
+ $this->error(-32700, 'parse error. not well formed');
+ }
+ if($this->message->messageType != 'methodCall') {
+ $this->error(-32600, 'server error. invalid xml-rpc. not conforming to spec. Request must be a methodCall');
+ }
+ $result = $this->call($this->message->methodName, $this->message->params);
+
+ // Is the result an error?
+ if(is_a($result, 'IXR_Error')) {
+ $this->error($result);
+ }
+
+ // Encode the result
+ $r = new IXR_Value($result);
+ $resultxml = $r->getXml();
+
+ // Create the XML
+ $xml = <<<EOD
+<methodResponse>
+ <params>
+ <param>
+ <value>
+ $resultxml
+ </value>
+ </param>
+ </params>
+</methodResponse>
+
+EOD;
+ // Send it
+ $this->output($xml);
+ }
+
+ /**
+ * @param string $methodname
+ * @param array $args
+ * @return IXR_Error|mixed
+ */
+ function call($methodname, $args) {
+ if(!$this->hasMethod($methodname)) {
+ return new IXR_Error(-32601, 'server error. requested method ' . $methodname . ' does not exist.');
+ }
+ $method = $this->callbacks[$methodname];
+
+ // Perform the callback and send the response
+
+ # Removed for DokuWiki to have a more consistent interface
+ # if (count($args) == 1) {
+ # // If only one parameter just send that instead of the whole array
+ # $args = $args[0];
+ # }
+
+ # Adjusted for DokuWiki to use call_user_func_array
+
+ // args need to be an array
+ $args = (array) $args;
+
+ // Are we dealing with a function or a method?
+ if(is_string($method) && substr($method, 0, 5) == 'this:') {
+ // It's a class method - check it exists
+ $method = substr($method, 5);
+ if(!method_exists($this, $method)) {
+ return new IXR_Error(-32601, 'server error. requested class method "' . $method . '" does not exist.');
+ }
+ // Call the method
+ #$result = $this->$method($args);
+ $result = call_user_func_array(array(&$this, $method), $args);
+ } elseif(substr($method, 0, 7) == 'plugin:') {
+ list($pluginname, $callback) = explode(':', substr($method, 7), 2);
+ if(!plugin_isdisabled($pluginname)) {
+ $plugin = plugin_load('action', $pluginname);
+ return call_user_func_array(array($plugin, $callback), $args);
+ } else {
+ return new IXR_Error(-99999, 'server error');
+ }
+ } else {
+ // It's a function - does it exist?
+ if(is_array($method)) {
+ if(!is_callable(array($method[0], $method[1]))) {
+ return new IXR_Error(-32601, 'server error. requested object method "' . $method[1] . '" does not exist.');
+ }
+ } else if(!function_exists($method)) {
+ return new IXR_Error(-32601, 'server error. requested function "' . $method . '" does not exist.');
+ }
+
+ // Call the function
+ $result = call_user_func($method, $args);
+ }
+ return $result;
+ }
+
+ /**
+ * @param int $error
+ * @param string|bool $message
+ */
+ function error($error, $message = false) {
+ // Accepts either an error object or an error code and message
+ if($message && !is_object($error)) {
+ $error = new IXR_Error($error, $message);
+ }
+ $this->output($error->getXml());
+ }
+
+ /**
+ * @param string $xml
+ */
+ function output($xml) {
+ header('Content-Type: text/xml; charset=utf-8');
+ echo '<?xml version="1.0"?>', "\n", $xml;
+ exit;
+ }
+
+ /**
+ * @param string $method
+ * @return bool
+ */
+ function hasMethod($method) {
+ return in_array($method, array_keys($this->callbacks));
+ }
+
+ function setCapabilities() {
+ // Initialises capabilities array
+ $this->capabilities = array(
+ 'xmlrpc' => array(
+ 'specUrl' => 'http://www.xmlrpc.com/spec',
+ 'specVersion' => 1
+ ),
+ 'faults_interop' => array(
+ 'specUrl' => 'http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php',
+ 'specVersion' => 20010516
+ ),
+ 'system.multicall' => array(
+ 'specUrl' => 'http://www.xmlrpc.com/discuss/msgReader$1208',
+ 'specVersion' => 1
+ ),
+ );
+ }
+
+ /**
+ * @return mixed
+ */
+ function getCapabilities() {
+ return $this->capabilities;
+ }
+
+ function setCallbacks() {
+ $this->callbacks['system.getCapabilities'] = 'this:getCapabilities';
+ $this->callbacks['system.listMethods'] = 'this:listMethods';
+ $this->callbacks['system.multicall'] = 'this:multiCall';
+ }
+
+ /**
+ * @return array
+ */
+ function listMethods() {
+ // Returns a list of methods - uses array_reverse to ensure user defined
+ // methods are listed before server defined methods
+ return array_reverse(array_keys($this->callbacks));
+ }
+
+ /**
+ * @param array $methodcalls
+ * @return array
+ */
+ function multiCall($methodcalls) {
+ // See http://www.xmlrpc.com/discuss/msgReader$1208
+ $return = array();
+ foreach($methodcalls as $call) {
+ $method = $call['methodName'];
+ $params = $call['params'];
+ if($method == 'system.multicall') {
+ $result = new IXR_Error(-32800, 'Recursive calls to system.multicall are forbidden');
+ } else {
+ $result = $this->call($method, $params);
+ }
+ if(is_a($result, 'IXR_Error')) {
+ $return[] = array(
+ 'faultCode' => $result->code,
+ 'faultString' => $result->message
+ );
+ } else {
+ $return[] = array($result);
+ }
+ }
+ return $return;
+ }
+}
+
+/**
+ * IXR_Request
+ *
+ * @package IXR
+ * @since 1.5
+ */
+class IXR_Request {
+ /** @var string */
+ var $method;
+ /** @var array */
+ var $args;
+ /** @var string */
+ var $xml;
+
+ /**
+ * @param string $method
+ * @param array $args
+ */
+ function __construct($method, $args) {
+ $this->method = $method;
+ $this->args = $args;
+ $this->xml = <<<EOD
+<?xml version="1.0"?>
+<methodCall>
+<methodName>{$this->method}</methodName>
+<params>
+
+EOD;
+ foreach($this->args as $arg) {
+ $this->xml .= '<param><value>';
+ $v = new IXR_Value($arg);
+ $this->xml .= $v->getXml();
+ $this->xml .= "</value></param>\n";
+ }
+ $this->xml .= '</params></methodCall>';
+ }
+
+ /**
+ * @return int
+ */
+ function getLength() {
+ return strlen($this->xml);
+ }
+
+ /**
+ * @return string
+ */
+ function getXml() {
+ return $this->xml;
+ }
+}
+
+/**
+ * IXR_Client
+ *
+ * @package IXR
+ * @since 1.5
+ *
+ * Changed for DokuWiki to use DokuHTTPClient
+ *
+ * This should be compatible to the original class, but uses DokuWiki's
+ * HTTP client library which will respect proxy settings
+ *
+ * Because the XMLRPC client is not used in DokuWiki currently this is completely
+ * untested
+ */
+class IXR_Client extends DokuHTTPClient {
+ var $posturl = '';
+ /** @var IXR_Message|bool */
+ var $message = false;
+
+ // Storage place for an error message
+ /** @var IXR_Error|bool */
+ var $xmlerror = false;
+
+ /**
+ * @param string $server
+ * @param string|bool $path
+ * @param int $port
+ * @param int $timeout
+ */
+ function __construct($server, $path = false, $port = 80, $timeout = 15) {
+ parent::__construct();
+ if(!$path) {
+ // Assume we have been given a URL instead
+ $this->posturl = $server;
+ } else {
+ $this->posturl = 'http://' . $server . ':' . $port . $path;
+ }
+ $this->timeout = $timeout;
+ }
+
+ /**
+ * parameters: method and arguments
+ * @return bool success or error
+ */
+ function query() {
+ $args = func_get_args();
+ $method = array_shift($args);
+ $request = new IXR_Request($method, $args);
+ $xml = $request->getXml();
+
+ $this->headers['Content-Type'] = 'text/xml';
+ if(!$this->sendRequest($this->posturl, $xml, 'POST')) {
+ $this->xmlerror = new IXR_Error(-32300, 'transport error - ' . $this->error);
+ return false;
+ }
+
+ // Check HTTP Response code
+ if($this->status < 200 || $this->status > 206) {
+ $this->xmlerror = new IXR_Error(-32300, 'transport error - HTTP status ' . $this->status);
+ return false;
+ }
+
+ // Now parse what we've got back
+ $this->message = new IXR_Message($this->resp_body);
+ if(!$this->message->parse()) {
+ // XML error
+ $this->xmlerror = new IXR_Error(-32700, 'parse error. not well formed');
+ return false;
+ }
+
+ // Is the message a fault?
+ if($this->message->messageType == 'fault') {
+ $this->xmlerror = new IXR_Error($this->message->faultCode, $this->message->faultString);
+ return false;
+ }
+
+ // Message must be OK
+ return true;
+ }
+
+ /**
+ * @return mixed
+ */
+ function getResponse() {
+ // methodResponses can only have one param - return that
+ return $this->message->params[0];
+ }
+
+ /**
+ * @return bool
+ */
+ function isError() {
+ return (is_object($this->xmlerror));
+ }
+
+ /**
+ * @return int
+ */
+ function getErrorCode() {
+ return $this->xmlerror->code;
+ }
+
+ /**
+ * @return string
+ */
+ function getErrorMessage() {
+ return $this->xmlerror->message;
+ }
+}
+
+/**
+ * IXR_Error
+ *
+ * @package IXR
+ * @since 1.5
+ */
+class IXR_Error {
+ var $code;
+ var $message;
+
+ /**
+ * @param int $code
+ * @param string $message
+ */
+ function __construct($code, $message) {
+ $this->code = $code;
+ $this->message = htmlspecialchars($message);
+ }
+
+ /**
+ * @return string
+ */
+ function getXml() {
+ $xml = <<<EOD
+<methodResponse>
+ <fault>
+ <value>
+ <struct>
+ <member>
+ <name>faultCode</name>
+ <value><int>{$this->code}</int></value>
+ </member>
+ <member>
+ <name>faultString</name>
+ <value><string>{$this->message}</string></value>
+ </member>
+ </struct>
+ </value>
+ </fault>
+</methodResponse>
+
+EOD;
+ return $xml;
+ }
+}
+
+/**
+ * IXR_Date
+ *
+ * @package IXR
+ * @since 1.5
+ */
+class IXR_Date {
+
+ const XMLRPC_ISO8601 = "Ymd\TH:i:sO" ;
+ /** @var DateTime */
+ protected $date;
+
+ /**
+ * @param int|string $time
+ */
+ public function __construct($time) {
+ // $time can be a PHP timestamp or an ISO one
+ if(is_numeric($time)) {
+ $this->parseTimestamp($time);
+ } else {
+ $this->parseIso($time);
+ }
+ }
+
+ /**
+ * Parse unix timestamp
+ *
+ * @param int $timestamp
+ */
+ protected function parseTimestamp($timestamp) {
+ $this->date = new DateTime('@' . $timestamp);
+ }
+
+ /**
+ * Parses less or more complete iso dates and much more, if no timezone given assumes UTC
+ *
+ * @param string $iso
+ */
+ protected function parseIso($iso) {
+ $this->date = new DateTime($iso, new DateTimeZone("UTC"));
+ }
+
+ /**
+ * Returns date in ISO 8601 format
+ *
+ * @return string
+ */
+ public function getIso() {
+ return $this->date->format(self::XMLRPC_ISO8601);
+ }
+
+ /**
+ * Returns date in valid xml
+ *
+ * @return string
+ */
+ public function getXml() {
+ return '<dateTime.iso8601>' . $this->getIso() . '</dateTime.iso8601>';
+ }
+
+ /**
+ * Returns Unix timestamp
+ *
+ * @return int
+ */
+ function getTimestamp() {
+ return $this->date->getTimestamp();
+ }
+}
+
+/**
+ * IXR_Base64
+ *
+ * @package IXR
+ * @since 1.5
+ */
+class IXR_Base64 {
+ var $data;
+
+ /**
+ * @param string $data
+ */
+ function __construct($data) {
+ $this->data = $data;
+ }
+
+ /**
+ * @return string
+ */
+ function getXml() {
+ return '<base64>' . base64_encode($this->data) . '</base64>';
+ }
+}
+
+/**
+ * IXR_IntrospectionServer
+ *
+ * @package IXR
+ * @since 1.5
+ */
+class IXR_IntrospectionServer extends IXR_Server {
+ /** @var array[] */
+ var $signatures;
+ /** @var string[] */
+ var $help;
+
+ /**
+ * Constructor
+ */
+ function __construct() {
+ $this->setCallbacks();
+ $this->setCapabilities();
+ $this->capabilities['introspection'] = array(
+ 'specUrl' => 'http://xmlrpc.usefulinc.com/doc/reserved.html',
+ 'specVersion' => 1
+ );
+ $this->addCallback(
+ 'system.methodSignature',
+ 'this:methodSignature',
+ array('array', 'string'),
+ 'Returns an array describing the return type and required parameters of a method'
+ );
+ $this->addCallback(
+ 'system.getCapabilities',
+ 'this:getCapabilities',
+ array('struct'),
+ 'Returns a struct describing the XML-RPC specifications supported by this server'
+ );
+ $this->addCallback(
+ 'system.listMethods',
+ 'this:listMethods',
+ array('array'),
+ 'Returns an array of available methods on this server'
+ );
+ $this->addCallback(
+ 'system.methodHelp',
+ 'this:methodHelp',
+ array('string', 'string'),
+ 'Returns a documentation string for the specified method'
+ );
+ }
+
+ /**
+ * @param string $method
+ * @param string $callback
+ * @param string[] $args
+ * @param string $help
+ */
+ function addCallback($method, $callback, $args, $help) {
+ $this->callbacks[$method] = $callback;
+ $this->signatures[$method] = $args;
+ $this->help[$method] = $help;
+ }
+
+ /**
+ * @param string $methodname
+ * @param array $args
+ * @return IXR_Error|mixed
+ */
+ function call($methodname, $args) {
+ // Make sure it's in an array
+ if($args && !is_array($args)) {
+ $args = array($args);
+ }
+
+ // Over-rides default call method, adds signature check
+ if(!$this->hasMethod($methodname)) {
+ return new IXR_Error(-32601, 'server error. requested method "' . $this->message->methodName . '" not specified.');
+ }
+ $method = $this->callbacks[$methodname];
+ $signature = $this->signatures[$methodname];
+ $returnType = array_shift($signature);
+ // Check the number of arguments. Check only, if the minimum count of parameters is specified. More parameters are possible.
+ // This is a hack to allow optional parameters...
+ if(count($args) < count($signature)) {
+ // print 'Num of args: '.count($args).' Num in signature: '.count($signature);
+ return new IXR_Error(-32602, 'server error. wrong number of method parameters');
+ }
+
+ // Check the argument types
+ $ok = true;
+ $argsbackup = $args;
+ for($i = 0, $j = count($args); $i < $j; $i++) {
+ $arg = array_shift($args);
+ $type = array_shift($signature);
+ switch($type) {
+ case 'int':
+ case 'i4':
+ if(is_array($arg) || !is_int($arg)) {
+ $ok = false;
+ }
+ break;
+ case 'base64':
+ case 'string':
+ if(!is_string($arg)) {
+ $ok = false;
+ }
+ break;
+ case 'boolean':
+ if($arg !== false && $arg !== true) {
+ $ok = false;
+ }
+ break;
+ case 'float':
+ case 'double':
+ if(!is_float($arg)) {
+ $ok = false;
+ }
+ break;
+ case 'date':
+ case 'dateTime.iso8601':
+ if(!is_a($arg, 'IXR_Date')) {
+ $ok = false;
+ }
+ break;
+ }
+ if(!$ok) {
+ return new IXR_Error(-32602, 'server error. invalid method parameters');
+ }
+ }
+ // It passed the test - run the "real" method call
+ return parent::call($methodname, $argsbackup);
+ }
+
+ /**
+ * @param string $method
+ * @return array|IXR_Error
+ */
+ function methodSignature($method) {
+ if(!$this->hasMethod($method)) {
+ return new IXR_Error(-32601, 'server error. requested method "' . $method . '" not specified.');
+ }
+ // We should be returning an array of types
+ $types = $this->signatures[$method];
+ $return = array();
+ foreach($types as $type) {
+ switch($type) {
+ case 'string':
+ $return[] = 'string';
+ break;
+ case 'int':
+ case 'i4':
+ $return[] = 42;
+ break;
+ case 'double':
+ $return[] = 3.1415;
+ break;
+ case 'dateTime.iso8601':
+ $return[] = new IXR_Date(time());
+ break;
+ case 'boolean':
+ $return[] = true;
+ break;
+ case 'base64':
+ $return[] = new IXR_Base64('base64');
+ break;
+ case 'array':
+ $return[] = array('array');
+ break;
+ case 'struct':
+ $return[] = array('struct' => 'struct');
+ break;
+ }
+ }
+ return $return;
+ }
+
+ /**
+ * @param string $method
+ * @return mixed
+ */
+ function methodHelp($method) {
+ return $this->help[$method];
+ }
+}
+
+/**
+ * IXR_ClientMulticall
+ *
+ * @package IXR
+ * @since 1.5
+ */
+class IXR_ClientMulticall extends IXR_Client {
+
+ /** @var array[] */
+ var $calls = array();
+
+ /**
+ * @param string $server
+ * @param string|bool $path
+ * @param int $port
+ */
+ function __construct($server, $path = false, $port = 80) {
+ parent::__construct($server, $path, $port);
+ //$this->useragent = 'The Incutio XML-RPC PHP Library (multicall client)';
+ }
+
+ /**
+ * Add a call
+ */
+ function addCall() {
+ $args = func_get_args();
+ $methodName = array_shift($args);
+ $struct = array(
+ 'methodName' => $methodName,
+ 'params' => $args
+ );
+ $this->calls[] = $struct;
+ }
+
+ /**
+ * @return bool
+ */
+ function query() {
+ // Prepare multicall, then call the parent::query() method
+ return parent::query('system.multicall', $this->calls);
+ }
+}
+
diff --git a/platform/www/inc/Input/Get.php b/platform/www/inc/Input/Get.php
new file mode 100644
index 0000000..99ab265
--- /dev/null
+++ b/platform/www/inc/Input/Get.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace dokuwiki\Input;
+
+/**
+ * Internal class used for $_GET access in dokuwiki\Input\Input class
+ */
+class Get extends Input
+{
+ /** @noinspection PhpMissingParentConstructorInspection
+ * Initialize the $access array, remove subclass members
+ */
+ public function __construct()
+ {
+ $this->access = &$_GET;
+ }
+
+ /**
+ * Sets a parameter in $_GET and $_REQUEST
+ *
+ * @param string $name Parameter name
+ * @param mixed $value Value to set
+ */
+ public function set($name, $value)
+ {
+ parent::set($name, $value);
+ $_REQUEST[$name] = $value;
+ }
+}
diff --git a/platform/www/inc/Input/Input.php b/platform/www/inc/Input/Input.php
new file mode 100644
index 0000000..3d2426b
--- /dev/null
+++ b/platform/www/inc/Input/Input.php
@@ -0,0 +1,287 @@
+<?php
+
+namespace dokuwiki\Input;
+
+/**
+ * Encapsulates access to the $_REQUEST array, making sure used parameters are initialized and
+ * have the correct type.
+ *
+ * All function access the $_REQUEST array by default, if you want to access $_POST or $_GET
+ * explicitly use the $post and $get members.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class Input
+{
+
+ /** @var Post Access $_POST parameters */
+ public $post;
+ /** @var Get Access $_GET parameters */
+ public $get;
+ /** @var Server Access $_SERVER parameters */
+ public $server;
+
+ protected $access;
+
+ /**
+ * @var Callable
+ */
+ protected $filter;
+
+ /**
+ * Intilizes the dokuwiki\Input\Input class and it subcomponents
+ */
+ public function __construct()
+ {
+ $this->access = &$_REQUEST;
+ $this->post = new Post();
+ $this->get = new Get();
+ $this->server = new Server();
+ }
+
+ /**
+ * Apply the set filter to the given value
+ *
+ * @param string $data
+ * @return string
+ */
+ protected function applyfilter($data)
+ {
+ if (!$this->filter) return $data;
+ return call_user_func($this->filter, $data);
+ }
+
+ /**
+ * Return a filtered copy of the input object
+ *
+ * Expects a callable that accepts one string parameter and returns a filtered string
+ *
+ * @param Callable|string $filter
+ * @return Input
+ */
+ public function filter($filter = 'stripctl')
+ {
+ $this->filter = $filter;
+ $clone = clone $this;
+ $this->filter = '';
+ return $clone;
+ }
+
+ /**
+ * Check if a parameter was set
+ *
+ * Basically a wrapper around isset. When called on the $post and $get subclasses,
+ * the parameter is set to $_POST or $_GET and to $_REQUEST
+ *
+ * @see isset
+ * @param string $name Parameter name
+ * @return bool
+ */
+ public function has($name)
+ {
+ return isset($this->access[$name]);
+ }
+
+ /**
+ * Remove a parameter from the superglobals
+ *
+ * Basically a wrapper around unset. When NOT called on the $post and $get subclasses,
+ * the parameter will also be removed from $_POST or $_GET
+ *
+ * @see isset
+ * @param string $name Parameter name
+ */
+ public function remove($name)
+ {
+ if (isset($this->access[$name])) {
+ unset($this->access[$name]);
+ }
+ // also remove from sub classes
+ if (isset($this->post) && isset($_POST[$name])) {
+ unset($_POST[$name]);
+ }
+ if (isset($this->get) && isset($_GET[$name])) {
+ unset($_GET[$name]);
+ }
+ }
+
+ /**
+ * Access a request parameter without any type conversion
+ *
+ * @param string $name Parameter name
+ * @param mixed $default Default to return if parameter isn't set
+ * @param bool $nonempty Return $default if parameter is set but empty()
+ * @return mixed
+ */
+ public function param($name, $default = null, $nonempty = false)
+ {
+ if (!isset($this->access[$name])) return $default;
+ $value = $this->applyfilter($this->access[$name]);
+ if ($nonempty && empty($value)) return $default;
+ return $value;
+ }
+
+ /**
+ * Sets a parameter
+ *
+ * @param string $name Parameter name
+ * @param mixed $value Value to set
+ */
+ public function set($name, $value)
+ {
+ $this->access[$name] = $value;
+ }
+
+ /**
+ * Get a reference to a request parameter
+ *
+ * This avoids copying data in memory, when the parameter is not set it will be created
+ * and intialized with the given $default value before a reference is returned
+ *
+ * @param string $name Parameter name
+ * @param mixed $default If parameter is not set, initialize with this value
+ * @param bool $nonempty Init with $default if parameter is set but empty()
+ * @return mixed (reference)
+ */
+ public function &ref($name, $default = '', $nonempty = false)
+ {
+ if (!isset($this->access[$name]) || ($nonempty && empty($this->access[$name]))) {
+ $this->set($name, $default);
+ }
+
+ return $this->access[$name];
+ }
+
+ /**
+ * Access a request parameter as int
+ *
+ * @param string $name Parameter name
+ * @param int $default Default to return if parameter isn't set or is an array
+ * @param bool $nonempty Return $default if parameter is set but empty()
+ * @return int
+ */
+ public function int($name, $default = 0, $nonempty = false)
+ {
+ if (!isset($this->access[$name])) return $default;
+ if (is_array($this->access[$name])) return $default;
+ $value = $this->applyfilter($this->access[$name]);
+ if ($value === '') return $default;
+ if ($nonempty && empty($value)) return $default;
+
+ return (int)$value;
+ }
+
+ /**
+ * Access a request parameter as string
+ *
+ * @param string $name Parameter name
+ * @param string $default Default to return if parameter isn't set or is an array
+ * @param bool $nonempty Return $default if parameter is set but empty()
+ * @return string
+ */
+ public function str($name, $default = '', $nonempty = false)
+ {
+ if (!isset($this->access[$name])) return $default;
+ if (is_array($this->access[$name])) return $default;
+ $value = $this->applyfilter($this->access[$name]);
+ if ($nonempty && empty($value)) return $default;
+
+ return (string)$value;
+ }
+
+ /**
+ * Access a request parameter and make sure it is has a valid value
+ *
+ * Please note that comparisons to the valid values are not done typesafe (request vars
+ * are always strings) however the function will return the correct type from the $valids
+ * array when an match was found.
+ *
+ * @param string $name Parameter name
+ * @param array $valids Array of valid values
+ * @param mixed $default Default to return if parameter isn't set or not valid
+ * @return null|mixed
+ */
+ public function valid($name, $valids, $default = null)
+ {
+ if (!isset($this->access[$name])) return $default;
+ if (is_array($this->access[$name])) return $default; // we don't allow arrays
+ $value = $this->applyfilter($this->access[$name]);
+ $found = array_search($value, $valids);
+ if ($found !== false) return $valids[$found]; // return the valid value for type safety
+ return $default;
+ }
+
+ /**
+ * Access a request parameter as bool
+ *
+ * Note: $nonempty is here for interface consistency and makes not much sense for booleans
+ *
+ * @param string $name Parameter name
+ * @param mixed $default Default to return if parameter isn't set
+ * @param bool $nonempty Return $default if parameter is set but empty()
+ * @return bool
+ */
+ public function bool($name, $default = false, $nonempty = false)
+ {
+ if (!isset($this->access[$name])) return $default;
+ if (is_array($this->access[$name])) return $default;
+ $value = $this->applyfilter($this->access[$name]);
+ if ($value === '') return $default;
+ if ($nonempty && empty($value)) return $default;
+
+ return (bool)$value;
+ }
+
+ /**
+ * Access a request parameter as array
+ *
+ * @param string $name Parameter name
+ * @param mixed $default Default to return if parameter isn't set
+ * @param bool $nonempty Return $default if parameter is set but empty()
+ * @return array
+ */
+ public function arr($name, $default = array(), $nonempty = false)
+ {
+ if (!isset($this->access[$name])) return $default;
+ if (!is_array($this->access[$name])) return $default;
+ if ($nonempty && empty($this->access[$name])) return $default;
+
+ return (array)$this->access[$name];
+ }
+
+ /**
+ * Create a simple key from an array key
+ *
+ * This is useful to access keys where the information is given as an array key or as a single array value.
+ * For example when the information was submitted as the name of a submit button.
+ *
+ * This function directly changes the access array.
+ *
+ * Eg. $_REQUEST['do']['save']='Speichern' becomes $_REQUEST['do'] = 'save'
+ *
+ * This function returns the $INPUT object itself for easy chaining
+ *
+ * @param string $name
+ * @return Input
+ */
+ public function extract($name)
+ {
+ if (!isset($this->access[$name])) return $this;
+ if (!is_array($this->access[$name])) return $this;
+ $keys = array_keys($this->access[$name]);
+ if (!$keys) {
+ // this was an empty array
+ $this->remove($name);
+ return $this;
+ }
+ // get the first key
+ $value = array_shift($keys);
+ if ($value === 0) {
+ // we had a numeric array, assume the value is not in the key
+ $value = array_shift($this->access[$name]);
+ }
+
+ $this->set($name, $value);
+ return $this;
+ }
+}
diff --git a/platform/www/inc/Input/Post.php b/platform/www/inc/Input/Post.php
new file mode 100644
index 0000000..137cd72
--- /dev/null
+++ b/platform/www/inc/Input/Post.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace dokuwiki\Input;
+
+/**
+ * Internal class used for $_POST access in dokuwiki\Input\Input class
+ */
+class Post extends Input
+{
+
+ /** @noinspection PhpMissingParentConstructorInspection
+ * Initialize the $access array, remove subclass members
+ */
+ public function __construct()
+ {
+ $this->access = &$_POST;
+ }
+
+ /**
+ * Sets a parameter in $_POST and $_REQUEST
+ *
+ * @param string $name Parameter name
+ * @param mixed $value Value to set
+ */
+ public function set($name, $value)
+ {
+ parent::set($name, $value);
+ $_REQUEST[$name] = $value;
+ }
+}
diff --git a/platform/www/inc/Input/Server.php b/platform/www/inc/Input/Server.php
new file mode 100644
index 0000000..60964fd
--- /dev/null
+++ b/platform/www/inc/Input/Server.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace dokuwiki\Input;
+
+/**
+ * Internal class used for $_SERVER access in dokuwiki\Input\Input class
+ */
+class Server extends Input
+{
+
+ /** @noinspection PhpMissingParentConstructorInspection
+ * Initialize the $access array, remove subclass members
+ */
+ public function __construct()
+ {
+ $this->access = &$_SERVER;
+ }
+
+}
diff --git a/platform/www/inc/JpegMeta.php b/platform/www/inc/JpegMeta.php
new file mode 100644
index 0000000..9ed1e2d
--- /dev/null
+++ b/platform/www/inc/JpegMeta.php
@@ -0,0 +1,3188 @@
+<?php
+/**
+ * JPEG metadata reader/writer
+ *
+ * @license BSD <http://www.opensource.org/licenses/bsd-license.php>
+ * @link http://github.com/sd/jpeg-php
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Hakan Sandell <hakan.sandell@mydata.se>
+ * @todo Add support for Maker Notes, Extend for GIF and PNG metadata
+ */
+
+// Original copyright notice:
+//
+// Copyright (c) 2003 Sebastian Delmont <sdelmont@zonageek.com>
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. Neither the name of the author nor the names of its contributors
+// may be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
+
+class JpegMeta {
+ var $_fileName;
+ var $_fp = null;
+ var $_fpout = null;
+ var $_type = 'unknown';
+
+ var $_markers;
+ var $_info;
+
+
+ /**
+ * Constructor
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @param $fileName
+ */
+ function __construct($fileName) {
+
+ $this->_fileName = $fileName;
+
+ $this->_fp = null;
+ $this->_type = 'unknown';
+
+ unset($this->_info);
+ unset($this->_markers);
+ }
+
+ /**
+ * Returns all gathered info as multidim array
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ */
+ function & getRawInfo() {
+ $this->_parseAll();
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ return $this->_info;
+ }
+
+ /**
+ * Returns basic image info
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ */
+ function & getBasicInfo() {
+ $this->_parseAll();
+
+ $info = array();
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ $info['Name'] = $this->_info['file']['Name'];
+ if (isset($this->_info['file']['Url'])) {
+ $info['Url'] = $this->_info['file']['Url'];
+ $info['NiceSize'] = "???KB";
+ } else {
+ $info['Size'] = $this->_info['file']['Size'];
+ $info['NiceSize'] = $this->_info['file']['NiceSize'];
+ }
+
+ if (@isset($this->_info['sof']['Format'])) {
+ $info['Format'] = $this->_info['sof']['Format'] . " JPEG";
+ } else {
+ $info['Format'] = $this->_info['sof']['Format'] . " JPEG";
+ }
+
+ if (@isset($this->_info['sof']['ColorChannels'])) {
+ $info['ColorMode'] = ($this->_info['sof']['ColorChannels'] > 1) ? "Color" : "B&W";
+ }
+
+ $info['Width'] = $this->getWidth();
+ $info['Height'] = $this->getHeight();
+ $info['DimStr'] = $this->getDimStr();
+
+ $dates = $this->getDates();
+
+ $info['DateTime'] = $dates['EarliestTime'];
+ $info['DateTimeStr'] = $dates['EarliestTimeStr'];
+
+ $info['HasThumbnail'] = $this->hasThumbnail();
+
+ return $info;
+ }
+
+
+ /**
+ * Convinience function to access nearly all available Data
+ * through one function
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array|string $fields field name or array with field names
+ * @return bool|string
+ */
+ function getField($fields) {
+ if(!is_array($fields)) $fields = array($fields);
+ $info = false;
+ foreach($fields as $field){
+ if(strtolower(substr($field,0,5)) == 'iptc.'){
+ $info = $this->getIPTCField(substr($field,5));
+ }elseif(strtolower(substr($field,0,5)) == 'exif.'){
+ $info = $this->getExifField(substr($field,5));
+ }elseif(strtolower(substr($field,0,4)) == 'xmp.'){
+ $info = $this->getXmpField(substr($field,4));
+ }elseif(strtolower(substr($field,0,5)) == 'file.'){
+ $info = $this->getFileField(substr($field,5));
+ }elseif(strtolower(substr($field,0,5)) == 'date.'){
+ $info = $this->getDateField(substr($field,5));
+ }elseif(strtolower($field) == 'simple.camera'){
+ $info = $this->getCamera();
+ }elseif(strtolower($field) == 'simple.raw'){
+ return $this->getRawInfo();
+ }elseif(strtolower($field) == 'simple.title'){
+ $info = $this->getTitle();
+ }elseif(strtolower($field) == 'simple.shutterspeed'){
+ $info = $this->getShutterSpeed();
+ }else{
+ $info = $this->getExifField($field);
+ }
+ if($info != false) break;
+ }
+
+ if($info === false) $info = '';
+ if(is_array($info)){
+ if(isset($info['val'])){
+ $info = $info['val'];
+ }else{
+ $info = join(', ',$info);
+ }
+ }
+ return trim($info);
+ }
+
+ /**
+ * Convinience function to set nearly all available Data
+ * through one function
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $field field name
+ * @param string $value
+ * @return bool success or fail
+ */
+ function setField($field, $value) {
+ if(strtolower(substr($field,0,5)) == 'iptc.'){
+ return $this->setIPTCField(substr($field,5),$value);
+ }elseif(strtolower(substr($field,0,5)) == 'exif.'){
+ return $this->setExifField(substr($field,5),$value);
+ }else{
+ return $this->setExifField($field,$value);
+ }
+ }
+
+ /**
+ * Convinience function to delete nearly all available Data
+ * through one function
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $field field name
+ * @return bool
+ */
+ function deleteField($field) {
+ if(strtolower(substr($field,0,5)) == 'iptc.'){
+ return $this->deleteIPTCField(substr($field,5));
+ }elseif(strtolower(substr($field,0,5)) == 'exif.'){
+ return $this->deleteExifField(substr($field,5));
+ }else{
+ return $this->deleteExifField($field);
+ }
+ }
+
+ /**
+ * Return a date field
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $field
+ * @return false|string
+ */
+ function getDateField($field) {
+ if (!isset($this->_info['dates'])) {
+ $this->_info['dates'] = $this->getDates();
+ }
+
+ if (isset($this->_info['dates'][$field])) {
+ return $this->_info['dates'][$field];
+ }
+
+ return false;
+ }
+
+ /**
+ * Return a file info field
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $field field name
+ * @return false|string
+ */
+ function getFileField($field) {
+ if (!isset($this->_info['file'])) {
+ $this->_parseFileInfo();
+ }
+
+ if (isset($this->_info['file'][$field])) {
+ return $this->_info['file'][$field];
+ }
+
+ return false;
+ }
+
+ /**
+ * Return the camera info (Maker and Model)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @todo handle makernotes
+ *
+ * @return false|string
+ */
+ function getCamera(){
+ $make = $this->getField(array('Exif.Make','Exif.TIFFMake'));
+ $model = $this->getField(array('Exif.Model','Exif.TIFFModel'));
+ $cam = trim("$make $model");
+ if(empty($cam)) return false;
+ return $cam;
+ }
+
+ /**
+ * Return shutter speed as a ratio
+ *
+ * @author Joe Lapp <joe.lapp@pobox.com>
+ *
+ * @return string
+ */
+ function getShutterSpeed() {
+ if (!isset($this->_info['exif'])) {
+ $this->_parseMarkerExif();
+ }
+ if(!isset($this->_info['exif']['ExposureTime'])){
+ return '';
+ }
+
+ $field = $this->_info['exif']['ExposureTime'];
+ if($field['den'] == 1) return $field['num'];
+ return $field['num'].'/'.$field['den'];
+ }
+
+ /**
+ * Return an EXIF field
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @param string $field field name
+ * @return false|string
+ */
+ function getExifField($field) {
+ if (!isset($this->_info['exif'])) {
+ $this->_parseMarkerExif();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if (isset($this->_info['exif'][$field])) {
+ return $this->_info['exif'][$field];
+ }
+
+ return false;
+ }
+
+ /**
+ * Return an XMP field
+ *
+ * @author Hakan Sandell <hakan.sandell@mydata.se>
+ *
+ * @param string $field field name
+ * @return false|string
+ */
+ function getXmpField($field) {
+ if (!isset($this->_info['xmp'])) {
+ $this->_parseMarkerXmp();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if (isset($this->_info['xmp'][$field])) {
+ return $this->_info['xmp'][$field];
+ }
+
+ return false;
+ }
+
+ /**
+ * Return an Adobe Field
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @param string $field field name
+ * @return false|string
+ */
+ function getAdobeField($field) {
+ if (!isset($this->_info['adobe'])) {
+ $this->_parseMarkerAdobe();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if (isset($this->_info['adobe'][$field])) {
+ return $this->_info['adobe'][$field];
+ }
+
+ return false;
+ }
+
+ /**
+ * Return an IPTC field
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @param string $field field name
+ * @return false|string
+ */
+ function getIPTCField($field) {
+ if (!isset($this->_info['iptc'])) {
+ $this->_parseMarkerAdobe();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if (isset($this->_info['iptc'][$field])) {
+ return $this->_info['iptc'][$field];
+ }
+
+ return false;
+ }
+
+ /**
+ * Set an EXIF field
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ * @author Joe Lapp <joe.lapp@pobox.com>
+ *
+ * @param string $field field name
+ * @param string $value
+ * @return bool
+ */
+ function setExifField($field, $value) {
+ if (!isset($this->_info['exif'])) {
+ $this->_parseMarkerExif();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if ($this->_info['exif'] == false) {
+ $this->_info['exif'] = array();
+ }
+
+ // make sure datetimes are in correct format
+ if(strlen($field) >= 8 && strtolower(substr($field, 0, 8)) == 'datetime') {
+ if(strlen($value) < 8 || $value[4] != ':' || $value[7] != ':') {
+ $value = date('Y:m:d H:i:s', strtotime($value));
+ }
+ }
+
+ $this->_info['exif'][$field] = $value;
+
+ return true;
+ }
+
+ /**
+ * Set an Adobe Field
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @param string $field field name
+ * @param string $value
+ * @return bool
+ */
+ function setAdobeField($field, $value) {
+ if (!isset($this->_info['adobe'])) {
+ $this->_parseMarkerAdobe();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if ($this->_info['adobe'] == false) {
+ $this->_info['adobe'] = array();
+ }
+
+ $this->_info['adobe'][$field] = $value;
+
+ return true;
+ }
+
+ /**
+ * Calculates the multiplier needed to resize the image to the given
+ * dimensions
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param int $maxwidth
+ * @param int $maxheight
+ * @return float|int
+ */
+ function getResizeRatio($maxwidth,$maxheight=0){
+ if(!$maxheight) $maxheight = $maxwidth;
+
+ $w = $this->getField('File.Width');
+ $h = $this->getField('File.Height');
+
+ $ratio = 1;
+ if($w >= $h){
+ if($w >= $maxwidth){
+ $ratio = $maxwidth/$w;
+ }elseif($h > $maxheight){
+ $ratio = $maxheight/$h;
+ }
+ }else{
+ if($h >= $maxheight){
+ $ratio = $maxheight/$h;
+ }elseif($w > $maxwidth){
+ $ratio = $maxwidth/$w;
+ }
+ }
+ return $ratio;
+ }
+
+
+ /**
+ * Set an IPTC field
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @param string $field field name
+ * @param string $value
+ * @return bool
+ */
+ function setIPTCField($field, $value) {
+ if (!isset($this->_info['iptc'])) {
+ $this->_parseMarkerAdobe();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if ($this->_info['iptc'] == false) {
+ $this->_info['iptc'] = array();
+ }
+
+ $this->_info['iptc'][$field] = $value;
+
+ return true;
+ }
+
+ /**
+ * Delete an EXIF field
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @param string $field field name
+ * @return bool
+ */
+ function deleteExifField($field) {
+ if (!isset($this->_info['exif'])) {
+ $this->_parseMarkerAdobe();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if ($this->_info['exif'] != false) {
+ unset($this->_info['exif'][$field]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Delete an Adobe field
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @param string $field field name
+ * @return bool
+ */
+ function deleteAdobeField($field) {
+ if (!isset($this->_info['adobe'])) {
+ $this->_parseMarkerAdobe();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if ($this->_info['adobe'] != false) {
+ unset($this->_info['adobe'][$field]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Delete an IPTC field
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @param string $field field name
+ * @return bool
+ */
+ function deleteIPTCField($field) {
+ if (!isset($this->_info['iptc'])) {
+ $this->_parseMarkerAdobe();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if ($this->_info['iptc'] != false) {
+ unset($this->_info['iptc'][$field]);
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the image's title, tries various fields
+ *
+ * @param int $max maximum number chars (keeps words)
+ * @return false|string
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function getTitle($max=80){
+ // try various fields
+ $cap = $this->getField(array('Iptc.Headline',
+ 'Iptc.Caption',
+ 'Xmp.dc:title',
+ 'Exif.UserComment',
+ 'Exif.TIFFUserComment',
+ 'Exif.TIFFImageDescription',
+ 'File.Name'));
+ if (empty($cap)) return false;
+
+ if(!$max) return $cap;
+ // Shorten to 80 chars (keeping words)
+ $new = preg_replace('/\n.+$/','',wordwrap($cap, $max));
+ if($new != $cap) $new .= '...';
+
+ return $new;
+ }
+
+ /**
+ * Gather various date fields
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @return array|bool
+ */
+ function getDates() {
+ $this->_parseAll();
+ if ($this->_markers == null) {
+ if (@isset($this->_info['file']['UnixTime'])) {
+ $dates = array();
+ $dates['FileModified'] = $this->_info['file']['UnixTime'];
+ $dates['Time'] = $this->_info['file']['UnixTime'];
+ $dates['TimeSource'] = 'FileModified';
+ $dates['TimeStr'] = date("Y-m-d H:i:s", $this->_info['file']['UnixTime']);
+ $dates['EarliestTime'] = $this->_info['file']['UnixTime'];
+ $dates['EarliestTimeSource'] = 'FileModified';
+ $dates['EarliestTimeStr'] = date("Y-m-d H:i:s", $this->_info['file']['UnixTime']);
+ $dates['LatestTime'] = $this->_info['file']['UnixTime'];
+ $dates['LatestTimeSource'] = 'FileModified';
+ $dates['LatestTimeStr'] = date("Y-m-d H:i:s", $this->_info['file']['UnixTime']);
+ return $dates;
+ }
+ return false;
+ }
+
+ $dates = array();
+
+ $latestTime = 0;
+ $latestTimeSource = "";
+ $earliestTime = time();
+ $earliestTimeSource = "";
+
+ if (@isset($this->_info['exif']['DateTime'])) {
+ $dates['ExifDateTime'] = $this->_info['exif']['DateTime'];
+
+ $aux = $this->_info['exif']['DateTime'];
+ $aux[4] = "-";
+ $aux[7] = "-";
+ $t = strtotime($aux);
+
+ if ($t && $t > $latestTime) {
+ $latestTime = $t;
+ $latestTimeSource = "ExifDateTime";
+ }
+
+ if ($t && $t < $earliestTime) {
+ $earliestTime = $t;
+ $earliestTimeSource = "ExifDateTime";
+ }
+ }
+
+ if (@isset($this->_info['exif']['DateTimeOriginal'])) {
+ $dates['ExifDateTimeOriginal'] = $this->_info['exif']['DateTime'];
+
+ $aux = $this->_info['exif']['DateTimeOriginal'];
+ $aux[4] = "-";
+ $aux[7] = "-";
+ $t = strtotime($aux);
+
+ if ($t && $t > $latestTime) {
+ $latestTime = $t;
+ $latestTimeSource = "ExifDateTimeOriginal";
+ }
+
+ if ($t && $t < $earliestTime) {
+ $earliestTime = $t;
+ $earliestTimeSource = "ExifDateTimeOriginal";
+ }
+ }
+
+ if (@isset($this->_info['exif']['DateTimeDigitized'])) {
+ $dates['ExifDateTimeDigitized'] = $this->_info['exif']['DateTime'];
+
+ $aux = $this->_info['exif']['DateTimeDigitized'];
+ $aux[4] = "-";
+ $aux[7] = "-";
+ $t = strtotime($aux);
+
+ if ($t && $t > $latestTime) {
+ $latestTime = $t;
+ $latestTimeSource = "ExifDateTimeDigitized";
+ }
+
+ if ($t && $t < $earliestTime) {
+ $earliestTime = $t;
+ $earliestTimeSource = "ExifDateTimeDigitized";
+ }
+ }
+
+ if (@isset($this->_info['iptc']['DateCreated'])) {
+ $dates['IPTCDateCreated'] = $this->_info['iptc']['DateCreated'];
+
+ $aux = $this->_info['iptc']['DateCreated'];
+ $aux = substr($aux, 0, 4) . "-" . substr($aux, 4, 2) . "-" . substr($aux, 6, 2);
+ $t = strtotime($aux);
+
+ if ($t && $t > $latestTime) {
+ $latestTime = $t;
+ $latestTimeSource = "IPTCDateCreated";
+ }
+
+ if ($t && $t < $earliestTime) {
+ $earliestTime = $t;
+ $earliestTimeSource = "IPTCDateCreated";
+ }
+ }
+
+ if (@isset($this->_info['file']['UnixTime'])) {
+ $dates['FileModified'] = $this->_info['file']['UnixTime'];
+
+ $t = $this->_info['file']['UnixTime'];
+
+ if ($t && $t > $latestTime) {
+ $latestTime = $t;
+ $latestTimeSource = "FileModified";
+ }
+
+ if ($t && $t < $earliestTime) {
+ $earliestTime = $t;
+ $earliestTimeSource = "FileModified";
+ }
+ }
+
+ $dates['Time'] = $earliestTime;
+ $dates['TimeSource'] = $earliestTimeSource;
+ $dates['TimeStr'] = date("Y-m-d H:i:s", $earliestTime);
+ $dates['EarliestTime'] = $earliestTime;
+ $dates['EarliestTimeSource'] = $earliestTimeSource;
+ $dates['EarliestTimeStr'] = date("Y-m-d H:i:s", $earliestTime);
+ $dates['LatestTime'] = $latestTime;
+ $dates['LatestTimeSource'] = $latestTimeSource;
+ $dates['LatestTimeStr'] = date("Y-m-d H:i:s", $latestTime);
+
+ return $dates;
+ }
+
+ /**
+ * Get the image width, tries various fields
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @return false|string
+ */
+ function getWidth() {
+ if (!isset($this->_info['sof'])) {
+ $this->_parseMarkerSOF();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if (isset($this->_info['sof']['ImageWidth'])) {
+ return $this->_info['sof']['ImageWidth'];
+ }
+
+ if (!isset($this->_info['exif'])) {
+ $this->_parseMarkerExif();
+ }
+
+ if (isset($this->_info['exif']['PixelXDimension'])) {
+ return $this->_info['exif']['PixelXDimension'];
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the image height, tries various fields
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @return false|string
+ */
+ function getHeight() {
+ if (!isset($this->_info['sof'])) {
+ $this->_parseMarkerSOF();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if (isset($this->_info['sof']['ImageHeight'])) {
+ return $this->_info['sof']['ImageHeight'];
+ }
+
+ if (!isset($this->_info['exif'])) {
+ $this->_parseMarkerExif();
+ }
+
+ if (isset($this->_info['exif']['PixelYDimension'])) {
+ return $this->_info['exif']['PixelYDimension'];
+ }
+
+ return false;
+ }
+
+ /**
+ * Get an dimension string for use in img tag
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @return false|string
+ */
+ function getDimStr() {
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ $w = $this->getWidth();
+ $h = $this->getHeight();
+
+ return "width='" . $w . "' height='" . $h . "'";
+ }
+
+ /**
+ * Checks for an embedded thumbnail
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @param string $which possible values: 'any', 'exif' or 'adobe'
+ * @return false|string
+ */
+ function hasThumbnail($which = 'any') {
+ if (($which == 'any') || ($which == 'exif')) {
+ if (!isset($this->_info['exif'])) {
+ $this->_parseMarkerExif();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if (isset($this->_info['exif']) && is_array($this->_info['exif'])) {
+ if (isset($this->_info['exif']['JFIFThumbnail'])) {
+ return 'exif';
+ }
+ }
+ }
+
+ if ($which == 'adobe') {
+ if (!isset($this->_info['adobe'])) {
+ $this->_parseMarkerAdobe();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if (isset($this->_info['adobe']) && is_array($this->_info['adobe'])) {
+ if (isset($this->_info['adobe']['ThumbnailData'])) {
+ return 'exif';
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Send embedded thumbnail to browser
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ *
+ * @param string $which possible values: 'any', 'exif' or 'adobe'
+ * @return bool
+ */
+ function sendThumbnail($which = 'any') {
+ $data = null;
+
+ if (($which == 'any') || ($which == 'exif')) {
+ if (!isset($this->_info['exif'])) {
+ $this->_parseMarkerExif();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if (isset($this->_info['exif']) && is_array($this->_info['exif'])) {
+ if (isset($this->_info['exif']['JFIFThumbnail'])) {
+ $data =& $this->_info['exif']['JFIFThumbnail'];
+ }
+ }
+ }
+
+ if (($which == 'adobe') || ($data == null)){
+ if (!isset($this->_info['adobe'])) {
+ $this->_parseMarkerAdobe();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if (isset($this->_info['adobe']) && is_array($this->_info['adobe'])) {
+ if (isset($this->_info['adobe']['ThumbnailData'])) {
+ $data =& $this->_info['adobe']['ThumbnailData'];
+ }
+ }
+ }
+
+ if ($data != null) {
+ header("Content-type: image/jpeg");
+ echo $data;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Save changed Metadata
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $fileName file name or empty string for a random name
+ * @return bool
+ */
+ function save($fileName = "") {
+ if ($fileName == "") {
+ $tmpName = tempnam(dirname($this->_fileName),'_metatemp_');
+ $this->_writeJPEG($tmpName);
+ if (file_exists($tmpName)) {
+ return io_rename($tmpName, $this->_fileName);
+ }
+ } else {
+ return $this->_writeJPEG($fileName);
+ }
+ return false;
+ }
+
+ /*************************************************************/
+ /* PRIVATE FUNCTIONS (Internal Use Only!) */
+ /*************************************************************/
+
+ /*************************************************************/
+ function _dispose($fileName = "") {
+ $this->_fileName = $fileName;
+
+ $this->_fp = null;
+ $this->_type = 'unknown';
+
+ unset($this->_markers);
+ unset($this->_info);
+ }
+
+ /*************************************************************/
+ function _readJPEG() {
+ unset($this->_markers);
+ //unset($this->_info);
+ $this->_markers = array();
+ //$this->_info = array();
+
+ $this->_fp = @fopen($this->_fileName, 'rb');
+ if ($this->_fp) {
+ if (file_exists($this->_fileName)) {
+ $this->_type = 'file';
+ }
+ else {
+ $this->_type = 'url';
+ }
+ } else {
+ $this->_fp = null;
+ return false; // ERROR: Can't open file
+ }
+
+ // Check for the JPEG signature
+ $c1 = ord(fgetc($this->_fp));
+ $c2 = ord(fgetc($this->_fp));
+
+ if ($c1 != 0xFF || $c2 != 0xD8) { // (0xFF + SOI)
+ $this->_markers = null;
+ return false; // ERROR: File is not a JPEG
+ }
+
+ $count = 0;
+
+ $done = false;
+ $ok = true;
+
+ while (!$done) {
+ $capture = false;
+
+ // First, skip any non 0xFF bytes
+ $discarded = 0;
+ $c = ord(fgetc($this->_fp));
+ while (!feof($this->_fp) && ($c != 0xFF)) {
+ $discarded++;
+ $c = ord(fgetc($this->_fp));
+ }
+ // Then skip all 0xFF until the marker byte
+ do {
+ $marker = ord(fgetc($this->_fp));
+ } while (!feof($this->_fp) && ($marker == 0xFF));
+
+ if (feof($this->_fp)) {
+ return false; // ERROR: Unexpected EOF
+ }
+ if ($discarded != 0) {
+ return false; // ERROR: Extraneous data
+ }
+
+ $length = ord(fgetc($this->_fp)) * 256 + ord(fgetc($this->_fp));
+ if (feof($this->_fp)) {
+ return false; // ERROR: Unexpected EOF
+ }
+ if ($length < 2) {
+ return false; // ERROR: Extraneous data
+ }
+ $length = $length - 2; // The length we got counts itself
+
+ switch ($marker) {
+ case 0xC0: // SOF0
+ case 0xC1: // SOF1
+ case 0xC2: // SOF2
+ case 0xC9: // SOF9
+ case 0xE0: // APP0: JFIF data
+ case 0xE1: // APP1: EXIF or XMP data
+ case 0xED: // APP13: IPTC / Photoshop data
+ $capture = true;
+ break;
+ case 0xDA: // SOS: Start of scan... the image itself and the last block on the file
+ $capture = false;
+ $length = -1; // This field has no length... it includes all data until EOF
+ $done = true;
+ break;
+ default:
+ $capture = true;//false;
+ break;
+ }
+
+ $this->_markers[$count] = array();
+ $this->_markers[$count]['marker'] = $marker;
+ $this->_markers[$count]['length'] = $length;
+
+ if ($capture) {
+ if ($length)
+ $this->_markers[$count]['data'] = fread($this->_fp, $length);
+ else
+ $this->_markers[$count]['data'] = "";
+ }
+ elseif (!$done) {
+ $result = @fseek($this->_fp, $length, SEEK_CUR);
+ // fseek doesn't seem to like HTTP 'files', but fgetc has no problem
+ if (!($result === 0)) {
+ for ($i = 0; $i < $length; $i++) {
+ fgetc($this->_fp);
+ }
+ }
+ }
+ $count++;
+ }
+
+ if ($this->_fp) {
+ fclose($this->_fp);
+ $this->_fp = null;
+ }
+
+ return $ok;
+ }
+
+ /*************************************************************/
+ function _parseAll() {
+ if (!isset($this->_info['file'])) {
+ $this->_parseFileInfo();
+ }
+ if (!isset($this->_markers)) {
+ $this->_readJPEG();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ if (!isset($this->_info['jfif'])) {
+ $this->_parseMarkerJFIF();
+ }
+ if (!isset($this->_info['jpeg'])) {
+ $this->_parseMarkerSOF();
+ }
+ if (!isset($this->_info['exif'])) {
+ $this->_parseMarkerExif();
+ }
+ if (!isset($this->_info['xmp'])) {
+ $this->_parseMarkerXmp();
+ }
+ if (!isset($this->_info['adobe'])) {
+ $this->_parseMarkerAdobe();
+ }
+ }
+
+ /*************************************************************/
+
+ /**
+ * @param string $outputName
+ *
+ * @return bool
+ */
+ function _writeJPEG($outputName) {
+ $this->_parseAll();
+
+ $wroteEXIF = false;
+ $wroteAdobe = false;
+
+ $this->_fp = @fopen($this->_fileName, 'r');
+ if ($this->_fp) {
+ if (file_exists($this->_fileName)) {
+ $this->_type = 'file';
+ }
+ else {
+ $this->_type = 'url';
+ }
+ } else {
+ $this->_fp = null;
+ return false; // ERROR: Can't open file
+ }
+
+ $this->_fpout = fopen($outputName, 'wb');
+ if (!$this->_fpout) {
+ $this->_fpout = null;
+ fclose($this->_fp);
+ $this->_fp = null;
+ return false; // ERROR: Can't open output file
+ }
+
+ // Check for the JPEG signature
+ $c1 = ord(fgetc($this->_fp));
+ $c2 = ord(fgetc($this->_fp));
+
+ if ($c1 != 0xFF || $c2 != 0xD8) { // (0xFF + SOI)
+ return false; // ERROR: File is not a JPEG
+ }
+
+ fputs($this->_fpout, chr(0xFF), 1);
+ fputs($this->_fpout, chr(0xD8), 1); // (0xFF + SOI)
+
+ $count = 0;
+
+ $done = false;
+ $ok = true;
+
+ while (!$done) {
+ // First, skip any non 0xFF bytes
+ $discarded = 0;
+ $c = ord(fgetc($this->_fp));
+ while (!feof($this->_fp) && ($c != 0xFF)) {
+ $discarded++;
+ $c = ord(fgetc($this->_fp));
+ }
+ // Then skip all 0xFF until the marker byte
+ do {
+ $marker = ord(fgetc($this->_fp));
+ } while (!feof($this->_fp) && ($marker == 0xFF));
+
+ if (feof($this->_fp)) {
+ $ok = false;
+ break; // ERROR: Unexpected EOF
+ }
+ if ($discarded != 0) {
+ $ok = false;
+ break; // ERROR: Extraneous data
+ }
+
+ $length = ord(fgetc($this->_fp)) * 256 + ord(fgetc($this->_fp));
+ if (feof($this->_fp)) {
+ $ok = false;
+ break; // ERROR: Unexpected EOF
+ }
+ if ($length < 2) {
+ $ok = false;
+ break; // ERROR: Extraneous data
+ }
+ $length = $length - 2; // The length we got counts itself
+
+ unset($data);
+ if ($marker == 0xE1) { // APP1: EXIF data
+ $data =& $this->_createMarkerEXIF();
+ $wroteEXIF = true;
+ }
+ elseif ($marker == 0xED) { // APP13: IPTC / Photoshop data
+ $data =& $this->_createMarkerAdobe();
+ $wroteAdobe = true;
+ }
+ elseif ($marker == 0xDA) { // SOS: Start of scan... the image itself and the last block on the file
+ $done = true;
+ }
+
+ if (!$wroteEXIF && (($marker < 0xE0) || ($marker > 0xEF))) {
+ if (isset($this->_info['exif']) && is_array($this->_info['exif'])) {
+ $exif =& $this->_createMarkerEXIF();
+ $this->_writeJPEGMarker(0xE1, strlen($exif), $exif, 0);
+ unset($exif);
+ }
+ $wroteEXIF = true;
+ }
+
+ if (!$wroteAdobe && (($marker < 0xE0) || ($marker > 0xEF))) {
+ if ((isset($this->_info['adobe']) && is_array($this->_info['adobe']))
+ || (isset($this->_info['iptc']) && is_array($this->_info['iptc']))) {
+ $adobe =& $this->_createMarkerAdobe();
+ $this->_writeJPEGMarker(0xED, strlen($adobe), $adobe, 0);
+ unset($adobe);
+ }
+ $wroteAdobe = true;
+ }
+
+ $origLength = $length;
+ if (isset($data)) {
+ $length = strlen($data);
+ }
+
+ if ($marker != -1) {
+ $this->_writeJPEGMarker($marker, $length, $data, $origLength);
+ }
+ }
+
+ if ($this->_fp) {
+ fclose($this->_fp);
+ $this->_fp = null;
+ }
+
+ if ($this->_fpout) {
+ fclose($this->_fpout);
+ $this->_fpout = null;
+ }
+
+ return $ok;
+ }
+
+ /*************************************************************/
+
+ /**
+ * @param integer $marker
+ * @param integer $length
+ * @param string $data
+ * @param integer $origLength
+ *
+ * @return bool
+ */
+ function _writeJPEGMarker($marker, $length, &$data, $origLength) {
+ if ($length <= 0) {
+ return false;
+ }
+
+ fputs($this->_fpout, chr(0xFF), 1);
+ fputs($this->_fpout, chr($marker), 1);
+ fputs($this->_fpout, chr((($length + 2) & 0x0000FF00) >> 8), 1);
+ fputs($this->_fpout, chr((($length + 2) & 0x000000FF) >> 0), 1);
+
+ if (isset($data)) {
+ // Copy the generated data
+ fputs($this->_fpout, $data, $length);
+
+ if ($origLength > 0) { // Skip the original data
+ $result = @fseek($this->_fp, $origLength, SEEK_CUR);
+ // fseek doesn't seem to like HTTP 'files', but fgetc has no problem
+ if ($result != 0) {
+ for ($i = 0; $i < $origLength; $i++) {
+ fgetc($this->_fp);
+ }
+ }
+ }
+ } else {
+ if ($marker == 0xDA) { // Copy until EOF
+ while (!feof($this->_fp)) {
+ $data = fread($this->_fp, 1024 * 16);
+ fputs($this->_fpout, $data, strlen($data));
+ }
+ } else { // Copy only $length bytes
+ $data = @fread($this->_fp, $length);
+ fputs($this->_fpout, $data, $length);
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Gets basic info from the file - should work with non-JPEGs
+ *
+ * @author Sebastian Delmont <sdelmont@zonageek.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ function _parseFileInfo() {
+ if (file_exists($this->_fileName) && is_file($this->_fileName)) {
+ $this->_info['file'] = array();
+ $this->_info['file']['Name'] = utf8_decodeFN(\dokuwiki\Utf8\PhpString::basename($this->_fileName));
+ $this->_info['file']['Path'] = fullpath($this->_fileName);
+ $this->_info['file']['Size'] = filesize($this->_fileName);
+ if ($this->_info['file']['Size'] < 1024) {
+ $this->_info['file']['NiceSize'] = $this->_info['file']['Size'] . 'B';
+ } elseif ($this->_info['file']['Size'] < (1024 * 1024)) {
+ $this->_info['file']['NiceSize'] = round($this->_info['file']['Size'] / 1024) . 'KB';
+ } elseif ($this->_info['file']['Size'] < (1024 * 1024 * 1024)) {
+ $this->_info['file']['NiceSize'] = round($this->_info['file']['Size'] / (1024*1024)) . 'MB';
+ } else {
+ $this->_info['file']['NiceSize'] = $this->_info['file']['Size'] . 'B';
+ }
+ $this->_info['file']['UnixTime'] = filemtime($this->_fileName);
+
+ // get image size directly from file
+ $size = getimagesize($this->_fileName);
+ $this->_info['file']['Width'] = $size[0];
+ $this->_info['file']['Height'] = $size[1];
+ // set mime types and formats
+ // http://php.net/manual/en/function.getimagesize.php
+ // http://php.net/manual/en/function.image-type-to-mime-type.php
+ switch ($size[2]){
+ case 1:
+ $this->_info['file']['Mime'] = 'image/gif';
+ $this->_info['file']['Format'] = 'GIF';
+ break;
+ case 2:
+ $this->_info['file']['Mime'] = 'image/jpeg';
+ $this->_info['file']['Format'] = 'JPEG';
+ break;
+ case 3:
+ $this->_info['file']['Mime'] = 'image/png';
+ $this->_info['file']['Format'] = 'PNG';
+ break;
+ case 4:
+ $this->_info['file']['Mime'] = 'application/x-shockwave-flash';
+ $this->_info['file']['Format'] = 'SWF';
+ break;
+ case 5:
+ $this->_info['file']['Mime'] = 'image/psd';
+ $this->_info['file']['Format'] = 'PSD';
+ break;
+ case 6:
+ $this->_info['file']['Mime'] = 'image/bmp';
+ $this->_info['file']['Format'] = 'BMP';
+ break;
+ case 7:
+ $this->_info['file']['Mime'] = 'image/tiff';
+ $this->_info['file']['Format'] = 'TIFF (Intel)';
+ break;
+ case 8:
+ $this->_info['file']['Mime'] = 'image/tiff';
+ $this->_info['file']['Format'] = 'TIFF (Motorola)';
+ break;
+ case 9:
+ $this->_info['file']['Mime'] = 'application/octet-stream';
+ $this->_info['file']['Format'] = 'JPC';
+ break;
+ case 10:
+ $this->_info['file']['Mime'] = 'image/jp2';
+ $this->_info['file']['Format'] = 'JP2';
+ break;
+ case 11:
+ $this->_info['file']['Mime'] = 'application/octet-stream';
+ $this->_info['file']['Format'] = 'JPX';
+ break;
+ case 12:
+ $this->_info['file']['Mime'] = 'application/octet-stream';
+ $this->_info['file']['Format'] = 'JB2';
+ break;
+ case 13:
+ $this->_info['file']['Mime'] = 'application/x-shockwave-flash';
+ $this->_info['file']['Format'] = 'SWC';
+ break;
+ case 14:
+ $this->_info['file']['Mime'] = 'image/iff';
+ $this->_info['file']['Format'] = 'IFF';
+ break;
+ case 15:
+ $this->_info['file']['Mime'] = 'image/vnd.wap.wbmp';
+ $this->_info['file']['Format'] = 'WBMP';
+ break;
+ case 16:
+ $this->_info['file']['Mime'] = 'image/xbm';
+ $this->_info['file']['Format'] = 'XBM';
+ break;
+ default:
+ $this->_info['file']['Mime'] = 'image/unknown';
+ }
+ } else {
+ $this->_info['file'] = array();
+ $this->_info['file']['Name'] = \dokuwiki\Utf8\PhpString::basename($this->_fileName);
+ $this->_info['file']['Url'] = $this->_fileName;
+ }
+
+ return true;
+ }
+
+ /*************************************************************/
+ function _parseMarkerJFIF() {
+ if (!isset($this->_markers)) {
+ $this->_readJPEG();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ $data = null;
+ $count = count($this->_markers);
+ for ($i = 0; $i < $count; $i++) {
+ if ($this->_markers[$i]['marker'] == 0xE0) {
+ $signature = $this->_getFixedString($this->_markers[$i]['data'], 0, 4);
+ if ($signature == 'JFIF') {
+ $data =& $this->_markers[$i]['data'];
+ break;
+ }
+ }
+ }
+
+ if ($data == null) {
+ $this->_info['jfif'] = false;
+ return false;
+ }
+
+ $this->_info['jfif'] = array();
+
+ $vmaj = $this->_getByte($data, 5);
+ $vmin = $this->_getByte($data, 6);
+
+ $this->_info['jfif']['Version'] = sprintf('%d.%02d', $vmaj, $vmin);
+
+ $units = $this->_getByte($data, 7);
+ switch ($units) {
+ case 0:
+ $this->_info['jfif']['Units'] = 'pixels';
+ break;
+ case 1:
+ $this->_info['jfif']['Units'] = 'dpi';
+ break;
+ case 2:
+ $this->_info['jfif']['Units'] = 'dpcm';
+ break;
+ default:
+ $this->_info['jfif']['Units'] = 'unknown';
+ break;
+ }
+
+ $xdens = $this->_getShort($data, 8);
+ $ydens = $this->_getShort($data, 10);
+
+ $this->_info['jfif']['XDensity'] = $xdens;
+ $this->_info['jfif']['YDensity'] = $ydens;
+
+ $thumbx = $this->_getByte($data, 12);
+ $thumby = $this->_getByte($data, 13);
+
+ $this->_info['jfif']['ThumbnailWidth'] = $thumbx;
+ $this->_info['jfif']['ThumbnailHeight'] = $thumby;
+
+ return true;
+ }
+
+ /*************************************************************/
+ function _parseMarkerSOF() {
+ if (!isset($this->_markers)) {
+ $this->_readJPEG();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ $data = null;
+ $count = count($this->_markers);
+ for ($i = 0; $i < $count; $i++) {
+ switch ($this->_markers[$i]['marker']) {
+ case 0xC0: // SOF0
+ case 0xC1: // SOF1
+ case 0xC2: // SOF2
+ case 0xC9: // SOF9
+ $data =& $this->_markers[$i]['data'];
+ $marker = $this->_markers[$i]['marker'];
+ break;
+ }
+ }
+
+ if ($data == null) {
+ $this->_info['sof'] = false;
+ return false;
+ }
+
+ $pos = 0;
+ $this->_info['sof'] = array();
+
+ switch ($marker) {
+ case 0xC0: // SOF0
+ $format = 'Baseline';
+ break;
+ case 0xC1: // SOF1
+ $format = 'Progessive';
+ break;
+ case 0xC2: // SOF2
+ $format = 'Non-baseline';
+ break;
+ case 0xC9: // SOF9
+ $format = 'Arithmetic';
+ break;
+ default:
+ return false;
+ }
+
+ $this->_info['sof']['Format'] = $format;
+ $this->_info['sof']['SamplePrecision'] = $this->_getByte($data, $pos + 0);
+ $this->_info['sof']['ImageHeight'] = $this->_getShort($data, $pos + 1);
+ $this->_info['sof']['ImageWidth'] = $this->_getShort($data, $pos + 3);
+ $this->_info['sof']['ColorChannels'] = $this->_getByte($data, $pos + 5);
+
+ return true;
+ }
+
+ /**
+ * Parses the XMP data
+ *
+ * @author Hakan Sandell <hakan.sandell@mydata.se>
+ */
+ function _parseMarkerXmp() {
+ if (!isset($this->_markers)) {
+ $this->_readJPEG();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ $data = null;
+ $count = count($this->_markers);
+ for ($i = 0; $i < $count; $i++) {
+ if ($this->_markers[$i]['marker'] == 0xE1) {
+ $signature = $this->_getFixedString($this->_markers[$i]['data'], 0, 29);
+ if ($signature == "http://ns.adobe.com/xap/1.0/\0") {
+ $data = substr($this->_markers[$i]['data'], 29);
+ break;
+ }
+ }
+ }
+
+ if ($data == null) {
+ $this->_info['xmp'] = false;
+ return false;
+ }
+
+ $parser = xml_parser_create();
+ xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
+ xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
+ $result = xml_parse_into_struct($parser, $data, $values, $tags);
+ xml_parser_free($parser);
+
+ if ($result == 0) {
+ $this->_info['xmp'] = false;
+ return false;
+ }
+
+ $this->_info['xmp'] = array();
+ $count = count($values);
+ for ($i = 0; $i < $count; $i++) {
+ if ($values[$i]['tag'] == 'rdf:Description' && $values[$i]['type'] == 'open') {
+
+ while ((++$i < $count) && ($values[$i]['tag'] != 'rdf:Description')) {
+ $this->_parseXmpNode($values, $i, $this->_info['xmp'][$values[$i]['tag']], $count);
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Parses XMP nodes by recursion
+ *
+ * @author Hakan Sandell <hakan.sandell@mydata.se>
+ *
+ * @param array $values
+ * @param int $i
+ * @param mixed $meta
+ * @param integer $count
+ */
+ function _parseXmpNode($values, &$i, &$meta, $count) {
+ if ($values[$i]['type'] == 'close') return;
+
+ if ($values[$i]['type'] == 'complete') {
+ // Simple Type property
+ $meta = $values[$i]['value'];
+ return;
+ }
+
+ $i++;
+ if ($i >= $count) return;
+
+ if ($values[$i]['tag'] == 'rdf:Bag' || $values[$i]['tag'] == 'rdf:Seq') {
+ // Array property
+ $meta = array();
+ while ($values[++$i]['tag'] == 'rdf:li') {
+ $this->_parseXmpNode($values, $i, $meta[], $count);
+ }
+ $i++; // skip closing Bag/Seq tag
+
+ } elseif ($values[$i]['tag'] == 'rdf:Alt') {
+ // Language Alternative property, only the first (default) value is used
+ if ($values[$i]['type'] == 'open') {
+ $i++;
+ $this->_parseXmpNode($values, $i, $meta, $count);
+ while ((++$i < $count) && ($values[$i]['tag'] != 'rdf:Alt'));
+ $i++; // skip closing Alt tag
+ }
+
+ } else {
+ // Structure property
+ $meta = array();
+ $startTag = $values[$i-1]['tag'];
+ do {
+ $this->_parseXmpNode($values, $i, $meta[$values[$i]['tag']], $count);
+ } while ((++$i < $count) && ($values[$i]['tag'] != $startTag));
+ }
+ }
+
+ /*************************************************************/
+ function _parseMarkerExif() {
+ if (!isset($this->_markers)) {
+ $this->_readJPEG();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ $data = null;
+ $count = count($this->_markers);
+ for ($i = 0; $i < $count; $i++) {
+ if ($this->_markers[$i]['marker'] == 0xE1) {
+ $signature = $this->_getFixedString($this->_markers[$i]['data'], 0, 6);
+ if ($signature == "Exif\0\0") {
+ $data =& $this->_markers[$i]['data'];
+ break;
+ }
+ }
+ }
+
+ if ($data == null) {
+ $this->_info['exif'] = false;
+ return false;
+ }
+ $pos = 6;
+ $this->_info['exif'] = array();
+
+ // We don't increment $pos after this because Exif uses offsets relative to this point
+
+ $byteAlign = $this->_getShort($data, $pos + 0);
+
+ if ($byteAlign == 0x4949) { // "II"
+ $isBigEndian = false;
+ } elseif ($byteAlign == 0x4D4D) { // "MM"
+ $isBigEndian = true;
+ } else {
+ return false; // Unexpected data
+ }
+
+ $alignCheck = $this->_getShort($data, $pos + 2, $isBigEndian);
+ if ($alignCheck != 0x002A) // That's the expected value
+ return false; // Unexpected data
+
+ if ($isBigEndian) {
+ $this->_info['exif']['ByteAlign'] = "Big Endian";
+ } else {
+ $this->_info['exif']['ByteAlign'] = "Little Endian";
+ }
+
+ $offsetIFD0 = $this->_getLong($data, $pos + 4, $isBigEndian);
+ if ($offsetIFD0 < 8)
+ return false; // Unexpected data
+
+ $offsetIFD1 = $this->_readIFD($data, $pos, $offsetIFD0, $isBigEndian, 'ifd0');
+ if ($offsetIFD1 != 0)
+ $this->_readIFD($data, $pos, $offsetIFD1, $isBigEndian, 'ifd1');
+
+ return true;
+ }
+
+ /*************************************************************/
+
+ /**
+ * @param mixed $data
+ * @param integer $base
+ * @param integer $offset
+ * @param boolean $isBigEndian
+ * @param string $mode
+ *
+ * @return int
+ */
+ function _readIFD($data, $base, $offset, $isBigEndian, $mode) {
+ $EXIFTags = $this->_exifTagNames($mode);
+
+ $numEntries = $this->_getShort($data, $base + $offset, $isBigEndian);
+ $offset += 2;
+
+ $exifTIFFOffset = 0;
+ $exifTIFFLength = 0;
+ $exifThumbnailOffset = 0;
+ $exifThumbnailLength = 0;
+
+ for ($i = 0; $i < $numEntries; $i++) {
+ $tag = $this->_getShort($data, $base + $offset, $isBigEndian);
+ $offset += 2;
+ $type = $this->_getShort($data, $base + $offset, $isBigEndian);
+ $offset += 2;
+ $count = $this->_getLong($data, $base + $offset, $isBigEndian);
+ $offset += 4;
+
+ if (($type < 1) || ($type > 12))
+ return false; // Unexpected Type
+
+ $typeLengths = array( -1, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8 );
+
+ $dataLength = $typeLengths[$type] * $count;
+ if ($dataLength > 4) {
+ $dataOffset = $this->_getLong($data, $base + $offset, $isBigEndian);
+ $rawValue = $this->_getFixedString($data, $base + $dataOffset, $dataLength);
+ } else {
+ $rawValue = $this->_getFixedString($data, $base + $offset, $dataLength);
+ }
+ $offset += 4;
+
+ switch ($type) {
+ case 1: // UBYTE
+ if ($count == 1) {
+ $value = $this->_getByte($rawValue, 0);
+ } else {
+ $value = array();
+ for ($j = 0; $j < $count; $j++)
+ $value[$j] = $this->_getByte($rawValue, $j);
+ }
+ break;
+ case 2: // ASCII
+ $value = $rawValue;
+ break;
+ case 3: // USHORT
+ if ($count == 1) {
+ $value = $this->_getShort($rawValue, 0, $isBigEndian);
+ } else {
+ $value = array();
+ for ($j = 0; $j < $count; $j++)
+ $value[$j] = $this->_getShort($rawValue, $j * 2, $isBigEndian);
+ }
+ break;
+ case 4: // ULONG
+ if ($count == 1) {
+ $value = $this->_getLong($rawValue, 0, $isBigEndian);
+ } else {
+ $value = array();
+ for ($j = 0; $j < $count; $j++)
+ $value[$j] = $this->_getLong($rawValue, $j * 4, $isBigEndian);
+ }
+ break;
+ case 5: // URATIONAL
+ if ($count == 1) {
+ $a = $this->_getLong($rawValue, 0, $isBigEndian);
+ $b = $this->_getLong($rawValue, 4, $isBigEndian);
+ $value = array();
+ $value['val'] = 0;
+ $value['num'] = $a;
+ $value['den'] = $b;
+ if (($a != 0) && ($b != 0)) {
+ $value['val'] = $a / $b;
+ }
+ } else {
+ $value = array();
+ for ($j = 0; $j < $count; $j++) {
+ $a = $this->_getLong($rawValue, $j * 8, $isBigEndian);
+ $b = $this->_getLong($rawValue, ($j * 8) + 4, $isBigEndian);
+ $value = array();
+ $value[$j]['val'] = 0;
+ $value[$j]['num'] = $a;
+ $value[$j]['den'] = $b;
+ if (($a != 0) && ($b != 0))
+ $value[$j]['val'] = $a / $b;
+ }
+ }
+ break;
+ case 6: // SBYTE
+ if ($count == 1) {
+ $value = $this->_getByte($rawValue, 0);
+ } else {
+ $value = array();
+ for ($j = 0; $j < $count; $j++)
+ $value[$j] = $this->_getByte($rawValue, $j);
+ }
+ break;
+ case 7: // UNDEFINED
+ $value = $rawValue;
+ break;
+ case 8: // SSHORT
+ if ($count == 1) {
+ $value = $this->_getShort($rawValue, 0, $isBigEndian);
+ } else {
+ $value = array();
+ for ($j = 0; $j < $count; $j++)
+ $value[$j] = $this->_getShort($rawValue, $j * 2, $isBigEndian);
+ }
+ break;
+ case 9: // SLONG
+ if ($count == 1) {
+ $value = $this->_getLong($rawValue, 0, $isBigEndian);
+ } else {
+ $value = array();
+ for ($j = 0; $j < $count; $j++)
+ $value[$j] = $this->_getLong($rawValue, $j * 4, $isBigEndian);
+ }
+ break;
+ case 10: // SRATIONAL
+ if ($count == 1) {
+ $a = $this->_getLong($rawValue, 0, $isBigEndian);
+ $b = $this->_getLong($rawValue, 4, $isBigEndian);
+ $value = array();
+ $value['val'] = 0;
+ $value['num'] = $a;
+ $value['den'] = $b;
+ if (($a != 0) && ($b != 0))
+ $value['val'] = $a / $b;
+ } else {
+ $value = array();
+ for ($j = 0; $j < $count; $j++) {
+ $a = $this->_getLong($rawValue, $j * 8, $isBigEndian);
+ $b = $this->_getLong($rawValue, ($j * 8) + 4, $isBigEndian);
+ $value = array();
+ $value[$j]['val'] = 0;
+ $value[$j]['num'] = $a;
+ $value[$j]['den'] = $b;
+ if (($a != 0) && ($b != 0))
+ $value[$j]['val'] = $a / $b;
+ }
+ }
+ break;
+ case 11: // FLOAT
+ $value = $rawValue;
+ break;
+
+ case 12: // DFLOAT
+ $value = $rawValue;
+ break;
+ default:
+ return false; // Unexpected Type
+ }
+
+ $tagName = '';
+ if (($mode == 'ifd0') && ($tag == 0x8769)) { // ExifIFDOffset
+ $this->_readIFD($data, $base, $value, $isBigEndian, 'exif');
+ } elseif (($mode == 'ifd0') && ($tag == 0x8825)) { // GPSIFDOffset
+ $this->_readIFD($data, $base, $value, $isBigEndian, 'gps');
+ } elseif (($mode == 'ifd1') && ($tag == 0x0111)) { // TIFFStripOffsets
+ $exifTIFFOffset = $value;
+ } elseif (($mode == 'ifd1') && ($tag == 0x0117)) { // TIFFStripByteCounts
+ $exifTIFFLength = $value;
+ } elseif (($mode == 'ifd1') && ($tag == 0x0201)) { // TIFFJFIFOffset
+ $exifThumbnailOffset = $value;
+ } elseif (($mode == 'ifd1') && ($tag == 0x0202)) { // TIFFJFIFLength
+ $exifThumbnailLength = $value;
+ } elseif (($mode == 'exif') && ($tag == 0xA005)) { // InteropIFDOffset
+ $this->_readIFD($data, $base, $value, $isBigEndian, 'interop');
+ }
+ // elseif (($mode == 'exif') && ($tag == 0x927C)) { // MakerNote
+ // }
+ else {
+ if (isset($EXIFTags[$tag])) {
+ $tagName = $EXIFTags[$tag];
+ if (isset($this->_info['exif'][$tagName])) {
+ if (!is_array($this->_info['exif'][$tagName])) {
+ $aux = array();
+ $aux[0] = $this->_info['exif'][$tagName];
+ $this->_info['exif'][$tagName] = $aux;
+ }
+
+ $this->_info['exif'][$tagName][count($this->_info['exif'][$tagName])] = $value;
+ } else {
+ $this->_info['exif'][$tagName] = $value;
+ }
+ }
+ /*
+ else {
+ echo sprintf("<h1>Unknown tag %02x (t: %d l: %d) %s in %s</h1>", $tag, $type, $count, $mode, $this->_fileName);
+ // Unknown Tags will be ignored!!!
+ // That's because the tag might be a pointer (like the Exif tag)
+ // and saving it without saving the data it points to might
+ // create an invalid file.
+ }
+ */
+ }
+ }
+
+ if (($exifThumbnailOffset > 0) && ($exifThumbnailLength > 0)) {
+ $this->_info['exif']['JFIFThumbnail'] = $this->_getFixedString($data, $base + $exifThumbnailOffset, $exifThumbnailLength);
+ }
+
+ if (($exifTIFFOffset > 0) && ($exifTIFFLength > 0)) {
+ $this->_info['exif']['TIFFStrips'] = $this->_getFixedString($data, $base + $exifTIFFOffset, $exifTIFFLength);
+ }
+
+ $nextOffset = $this->_getLong($data, $base + $offset, $isBigEndian);
+ return $nextOffset;
+ }
+
+ /*************************************************************/
+ function & _createMarkerExif() {
+ $data = null;
+ $count = count($this->_markers);
+ for ($i = 0; $i < $count; $i++) {
+ if ($this->_markers[$i]['marker'] == 0xE1) {
+ $signature = $this->_getFixedString($this->_markers[$i]['data'], 0, 6);
+ if ($signature == "Exif\0\0") {
+ $data =& $this->_markers[$i]['data'];
+ break;
+ }
+ }
+ }
+
+ if (!isset($this->_info['exif'])) {
+ return false;
+ }
+
+ $data = "Exif\0\0";
+ $pos = 6;
+ $offsetBase = 6;
+
+ if (isset($this->_info['exif']['ByteAlign']) && ($this->_info['exif']['ByteAlign'] == "Big Endian")) {
+ $isBigEndian = true;
+ $aux = "MM";
+ $pos = $this->_putString($data, $pos, $aux);
+ } else {
+ $isBigEndian = false;
+ $aux = "II";
+ $pos = $this->_putString($data, $pos, $aux);
+ }
+ $pos = $this->_putShort($data, $pos, 0x002A, $isBigEndian);
+ $pos = $this->_putLong($data, $pos, 0x00000008, $isBigEndian); // IFD0 Offset is always 8
+
+ $ifd0 =& $this->_getIFDEntries($isBigEndian, 'ifd0');
+ $ifd1 =& $this->_getIFDEntries($isBigEndian, 'ifd1');
+
+ $pos = $this->_writeIFD($data, $pos, $offsetBase, $ifd0, $isBigEndian, true);
+ $pos = $this->_writeIFD($data, $pos, $offsetBase, $ifd1, $isBigEndian, false);
+
+ return $data;
+ }
+
+ /*************************************************************/
+
+ /**
+ * @param mixed $data
+ * @param integer $pos
+ * @param integer $offsetBase
+ * @param array $entries
+ * @param boolean $isBigEndian
+ * @param boolean $hasNext
+ *
+ * @return mixed
+ */
+ function _writeIFD(&$data, $pos, $offsetBase, &$entries, $isBigEndian, $hasNext) {
+ $tiffData = null;
+ $tiffDataOffsetPos = -1;
+
+ $entryCount = count($entries);
+
+ $dataPos = $pos + 2 + ($entryCount * 12) + 4;
+ $pos = $this->_putShort($data, $pos, $entryCount, $isBigEndian);
+
+ for ($i = 0; $i < $entryCount; $i++) {
+ $tag = $entries[$i]['tag'];
+ $type = $entries[$i]['type'];
+
+ if ($type == -99) { // SubIFD
+ $pos = $this->_putShort($data, $pos, $tag, $isBigEndian);
+ $pos = $this->_putShort($data, $pos, 0x04, $isBigEndian); // LONG
+ $pos = $this->_putLong($data, $pos, 0x01, $isBigEndian); // Count = 1
+ $pos = $this->_putLong($data, $pos, $dataPos - $offsetBase, $isBigEndian);
+
+ $dataPos = $this->_writeIFD($data, $dataPos, $offsetBase, $entries[$i]['value'], $isBigEndian, false);
+ } elseif ($type == -98) { // TIFF Data
+ $pos = $this->_putShort($data, $pos, $tag, $isBigEndian);
+ $pos = $this->_putShort($data, $pos, 0x04, $isBigEndian); // LONG
+ $pos = $this->_putLong($data, $pos, 0x01, $isBigEndian); // Count = 1
+ $tiffDataOffsetPos = $pos;
+ $pos = $this->_putLong($data, $pos, 0x00, $isBigEndian); // For Now
+ $tiffData =& $entries[$i]['value'] ;
+ } else { // Regular Entry
+ $pos = $this->_putShort($data, $pos, $tag, $isBigEndian);
+ $pos = $this->_putShort($data, $pos, $type, $isBigEndian);
+ $pos = $this->_putLong($data, $pos, $entries[$i]['count'], $isBigEndian);
+ if (strlen($entries[$i]['value']) > 4) {
+ $pos = $this->_putLong($data, $pos, $dataPos - $offsetBase, $isBigEndian);
+ $dataPos = $this->_putString($data, $dataPos, $entries[$i]['value']);
+ } else {
+ $val = str_pad($entries[$i]['value'], 4, "\0");
+ $pos = $this->_putString($data, $pos, $val);
+ }
+ }
+ }
+
+ if ($tiffData != null) {
+ $this->_putLong($data, $tiffDataOffsetPos, $dataPos - $offsetBase, $isBigEndian);
+ $dataPos = $this->_putString($data, $dataPos, $tiffData);
+ }
+
+ if ($hasNext) {
+ $pos = $this->_putLong($data, $pos, $dataPos - $offsetBase, $isBigEndian);
+ } else {
+ $pos = $this->_putLong($data, $pos, 0, $isBigEndian);
+ }
+
+ return $dataPos;
+ }
+
+ /*************************************************************/
+
+ /**
+ * @param boolean $isBigEndian
+ * @param string $mode
+ *
+ * @return array
+ */
+ function & _getIFDEntries($isBigEndian, $mode) {
+ $EXIFNames = $this->_exifTagNames($mode);
+ $EXIFTags = $this->_exifNameTags($mode);
+ $EXIFTypeInfo = $this->_exifTagTypes($mode);
+
+ $ifdEntries = array();
+ $entryCount = 0;
+
+ foreach($EXIFNames as $tag => $name) {
+ $type = $EXIFTypeInfo[$tag][0];
+ $count = $EXIFTypeInfo[$tag][1];
+ $value = null;
+
+ if (($mode == 'ifd0') && ($tag == 0x8769)) { // ExifIFDOffset
+ if (isset($this->_info['exif']['EXIFVersion'])) {
+ $value =& $this->_getIFDEntries($isBigEndian, "exif");
+ $type = -99;
+ }
+ else {
+ $value = null;
+ }
+ } elseif (($mode == 'ifd0') && ($tag == 0x8825)) { // GPSIFDOffset
+ if (isset($this->_info['exif']['GPSVersionID'])) {
+ $value =& $this->_getIFDEntries($isBigEndian, "gps");
+ $type = -99;
+ } else {
+ $value = null;
+ }
+ } elseif (($mode == 'ifd1') && ($tag == 0x0111)) { // TIFFStripOffsets
+ if (isset($this->_info['exif']['TIFFStrips'])) {
+ $value =& $this->_info['exif']['TIFFStrips'];
+ $type = -98;
+ } else {
+ $value = null;
+ }
+ } elseif (($mode == 'ifd1') && ($tag == 0x0117)) { // TIFFStripByteCounts
+ if (isset($this->_info['exif']['TIFFStrips'])) {
+ $value = strlen($this->_info['exif']['TIFFStrips']);
+ } else {
+ $value = null;
+ }
+ } elseif (($mode == 'ifd1') && ($tag == 0x0201)) { // TIFFJFIFOffset
+ if (isset($this->_info['exif']['JFIFThumbnail'])) {
+ $value =& $this->_info['exif']['JFIFThumbnail'];
+ $type = -98;
+ } else {
+ $value = null;
+ }
+ } elseif (($mode == 'ifd1') && ($tag == 0x0202)) { // TIFFJFIFLength
+ if (isset($this->_info['exif']['JFIFThumbnail'])) {
+ $value = strlen($this->_info['exif']['JFIFThumbnail']);
+ } else {
+ $value = null;
+ }
+ } elseif (($mode == 'exif') && ($tag == 0xA005)) { // InteropIFDOffset
+ if (isset($this->_info['exif']['InteroperabilityIndex'])) {
+ $value =& $this->_getIFDEntries($isBigEndian, "interop");
+ $type = -99;
+ } else {
+ $value = null;
+ }
+ } elseif (isset($this->_info['exif'][$name])) {
+ $origValue =& $this->_info['exif'][$name];
+
+ // This makes it easier to process variable size elements
+ if (!is_array($origValue) || isset($origValue['val'])) {
+ unset($origValue); // Break the reference
+ $origValue = array($this->_info['exif'][$name]);
+ }
+ $origCount = count($origValue);
+
+ if ($origCount == 0 ) {
+ $type = -1; // To ignore this field
+ }
+
+ $value = " ";
+
+ switch ($type) {
+ case 1: // UBYTE
+ if ($count == 0) {
+ $count = $origCount;
+ }
+
+ $j = 0;
+ while (($j < $count) && ($j < $origCount)) {
+
+ $this->_putByte($value, $j, $origValue[$j]);
+ $j++;
+ }
+
+ while ($j < $count) {
+ $this->_putByte($value, $j, 0);
+ $j++;
+ }
+ break;
+ case 2: // ASCII
+ $v = strval($origValue[0]);
+ if (($count != 0) && (strlen($v) > $count)) {
+ $v = substr($v, 0, $count);
+ }
+ elseif (($count > 0) && (strlen($v) < $count)) {
+ $v = str_pad($v, $count, "\0");
+ }
+
+ $count = strlen($v);
+
+ $this->_putString($value, 0, $v);
+ break;
+ case 3: // USHORT
+ if ($count == 0) {
+ $count = $origCount;
+ }
+
+ $j = 0;
+ while (($j < $count) && ($j < $origCount)) {
+ $this->_putShort($value, $j * 2, $origValue[$j], $isBigEndian);
+ $j++;
+ }
+
+ while ($j < $count) {
+ $this->_putShort($value, $j * 2, 0, $isBigEndian);
+ $j++;
+ }
+ break;
+ case 4: // ULONG
+ if ($count == 0) {
+ $count = $origCount;
+ }
+
+ $j = 0;
+ while (($j < $count) && ($j < $origCount)) {
+ $this->_putLong($value, $j * 4, $origValue[$j], $isBigEndian);
+ $j++;
+ }
+
+ while ($j < $count) {
+ $this->_putLong($value, $j * 4, 0, $isBigEndian);
+ $j++;
+ }
+ break;
+ case 5: // URATIONAL
+ if ($count == 0) {
+ $count = $origCount;
+ }
+
+ $j = 0;
+ while (($j < $count) && ($j < $origCount)) {
+ $v = $origValue[$j];
+ if (is_array($v)) {
+ $a = $v['num'];
+ $b = $v['den'];
+ }
+ else {
+ $a = 0;
+ $b = 0;
+ // TODO: Allow other types and convert them
+ }
+ $this->_putLong($value, $j * 8, $a, $isBigEndian);
+ $this->_putLong($value, ($j * 8) + 4, $b, $isBigEndian);
+ $j++;
+ }
+
+ while ($j < $count) {
+ $this->_putLong($value, $j * 8, 0, $isBigEndian);
+ $this->_putLong($value, ($j * 8) + 4, 0, $isBigEndian);
+ $j++;
+ }
+ break;
+ case 6: // SBYTE
+ if ($count == 0) {
+ $count = $origCount;
+ }
+
+ $j = 0;
+ while (($j < $count) && ($j < $origCount)) {
+ $this->_putByte($value, $j, $origValue[$j]);
+ $j++;
+ }
+
+ while ($j < $count) {
+ $this->_putByte($value, $j, 0);
+ $j++;
+ }
+ break;
+ case 7: // UNDEFINED
+ $v = strval($origValue[0]);
+ if (($count != 0) && (strlen($v) > $count)) {
+ $v = substr($v, 0, $count);
+ }
+ elseif (($count > 0) && (strlen($v) < $count)) {
+ $v = str_pad($v, $count, "\0");
+ }
+
+ $count = strlen($v);
+
+ $this->_putString($value, 0, $v);
+ break;
+ case 8: // SSHORT
+ if ($count == 0) {
+ $count = $origCount;
+ }
+
+ $j = 0;
+ while (($j < $count) && ($j < $origCount)) {
+ $this->_putShort($value, $j * 2, $origValue[$j], $isBigEndian);
+ $j++;
+ }
+
+ while ($j < $count) {
+ $this->_putShort($value, $j * 2, 0, $isBigEndian);
+ $j++;
+ }
+ break;
+ case 9: // SLONG
+ if ($count == 0) {
+ $count = $origCount;
+ }
+
+ $j = 0;
+ while (($j < $count) && ($j < $origCount)) {
+ $this->_putLong($value, $j * 4, $origValue[$j], $isBigEndian);
+ $j++;
+ }
+
+ while ($j < $count) {
+ $this->_putLong($value, $j * 4, 0, $isBigEndian);
+ $j++;
+ }
+ break;
+ case 10: // SRATIONAL
+ if ($count == 0) {
+ $count = $origCount;
+ }
+
+ $j = 0;
+ while (($j < $count) && ($j < $origCount)) {
+ $v = $origValue[$j];
+ if (is_array($v)) {
+ $a = $v['num'];
+ $b = $v['den'];
+ }
+ else {
+ $a = 0;
+ $b = 0;
+ // TODO: Allow other types and convert them
+ }
+
+ $this->_putLong($value, $j * 8, $a, $isBigEndian);
+ $this->_putLong($value, ($j * 8) + 4, $b, $isBigEndian);
+ $j++;
+ }
+
+ while ($j < $count) {
+ $this->_putLong($value, $j * 8, 0, $isBigEndian);
+ $this->_putLong($value, ($j * 8) + 4, 0, $isBigEndian);
+ $j++;
+ }
+ break;
+ case 11: // FLOAT
+ if ($count == 0) {
+ $count = $origCount;
+ }
+
+ $j = 0;
+ while (($j < $count) && ($j < $origCount)) {
+ $v = strval($origValue[$j]);
+ if (strlen($v) > 4) {
+ $v = substr($v, 0, 4);
+ }
+ elseif (strlen($v) < 4) {
+ $v = str_pad($v, 4, "\0");
+ }
+ $this->_putString($value, $j * 4, $v);
+ $j++;
+ }
+
+ while ($j < $count) {
+ $v = "\0\0\0\0";
+ $this->_putString($value, $j * 4, $v);
+ $j++;
+ }
+ break;
+ case 12: // DFLOAT
+ if ($count == 0) {
+ $count = $origCount;
+ }
+
+ $j = 0;
+ while (($j < $count) && ($j < $origCount)) {
+ $v = strval($origValue[$j]);
+ if (strlen($v) > 8) {
+ $v = substr($v, 0, 8);
+ }
+ elseif (strlen($v) < 8) {
+ $v = str_pad($v, 8, "\0");
+ }
+ $this->_putString($value, $j * 8, $v);
+ $j++;
+ }
+
+ while ($j < $count) {
+ $v = "\0\0\0\0\0\0\0\0";
+ $this->_putString($value, $j * 8, $v);
+ $j++;
+ }
+ break;
+ default:
+ $value = null;
+ break;
+ }
+ }
+
+ if ($value != null) {
+ $ifdEntries[$entryCount] = array();
+ $ifdEntries[$entryCount]['tag'] = $tag;
+ $ifdEntries[$entryCount]['type'] = $type;
+ $ifdEntries[$entryCount]['count'] = $count;
+ $ifdEntries[$entryCount]['value'] = $value;
+
+ $entryCount++;
+ }
+ }
+
+ return $ifdEntries;
+ }
+
+ /*************************************************************/
+ function _parseMarkerAdobe() {
+ if (!isset($this->_markers)) {
+ $this->_readJPEG();
+ }
+
+ if ($this->_markers == null) {
+ return false;
+ }
+
+ $data = null;
+ $count = count($this->_markers);
+ for ($i = 0; $i < $count; $i++) {
+ if ($this->_markers[$i]['marker'] == 0xED) {
+ $signature = $this->_getFixedString($this->_markers[$i]['data'], 0, 14);
+ if ($signature == "Photoshop 3.0\0") {
+ $data =& $this->_markers[$i]['data'];
+ break;
+ }
+ }
+ }
+
+ if ($data == null) {
+ $this->_info['adobe'] = false;
+ $this->_info['iptc'] = false;
+ return false;
+ }
+ $pos = 14;
+ $this->_info['adobe'] = array();
+ $this->_info['adobe']['raw'] = array();
+ $this->_info['iptc'] = array();
+
+ $datasize = strlen($data);
+
+ while ($pos < $datasize) {
+ $signature = $this->_getFixedString($data, $pos, 4);
+ if ($signature != '8BIM')
+ return false;
+ $pos += 4;
+
+ $type = $this->_getShort($data, $pos);
+ $pos += 2;
+
+ $strlen = $this->_getByte($data, $pos);
+ $pos += 1;
+ $header = '';
+ for ($i = 0; $i < $strlen; $i++) {
+ $header .= $data[$pos + $i];
+ }
+ $pos += $strlen + 1 - ($strlen % 2); // The string is padded to even length, counting the length byte itself
+
+ $length = $this->_getLong($data, $pos);
+ $pos += 4;
+
+ $basePos = $pos;
+
+ switch ($type) {
+ case 0x0404: // Caption (IPTC Data)
+ $pos = $this->_readIPTC($data, $pos);
+ if ($pos == false)
+ return false;
+ break;
+ case 0x040A: // CopyrightFlag
+ $this->_info['adobe']['CopyrightFlag'] = $this->_getByte($data, $pos);
+ $pos += $length;
+ break;
+ case 0x040B: // ImageURL
+ $this->_info['adobe']['ImageURL'] = $this->_getFixedString($data, $pos, $length);
+ $pos += $length;
+ break;
+ case 0x040C: // Thumbnail
+ $aux = $this->_getLong($data, $pos);
+ $pos += 4;
+ if ($aux == 1) {
+ $this->_info['adobe']['ThumbnailWidth'] = $this->_getLong($data, $pos);
+ $pos += 4;
+ $this->_info['adobe']['ThumbnailHeight'] = $this->_getLong($data, $pos);
+ $pos += 4;
+
+ $pos += 16; // Skip some data
+
+ $this->_info['adobe']['ThumbnailData'] = $this->_getFixedString($data, $pos, $length - 28);
+ $pos += $length - 28;
+ }
+ break;
+ default:
+ break;
+ }
+
+ // We save all blocks, even those we recognized
+ $label = sprintf('8BIM_0x%04x', $type);
+ $this->_info['adobe']['raw'][$label] = array();
+ $this->_info['adobe']['raw'][$label]['type'] = $type;
+ $this->_info['adobe']['raw'][$label]['header'] = $header;
+ $this->_info['adobe']['raw'][$label]['data'] =& $this->_getFixedString($data, $basePos, $length);
+
+ $pos = $basePos + $length + ($length % 2); // Even padding
+ }
+
+ }
+
+ /*************************************************************/
+ function _readIPTC(&$data, $pos = 0) {
+ $totalLength = strlen($data);
+
+ $IPTCTags = $this->_iptcTagNames();
+
+ while ($pos < ($totalLength - 5)) {
+ $signature = $this->_getShort($data, $pos);
+ if ($signature != 0x1C02)
+ return $pos;
+ $pos += 2;
+
+ $type = $this->_getByte($data, $pos);
+ $pos += 1;
+ $length = $this->_getShort($data, $pos);
+ $pos += 2;
+
+ $basePos = $pos;
+ $label = '';
+
+ if (isset($IPTCTags[$type])) {
+ $label = $IPTCTags[$type];
+ } else {
+ $label = sprintf('IPTC_0x%02x', $type);
+ }
+
+ if ($label != '') {
+ if (isset($this->_info['iptc'][$label])) {
+ if (!is_array($this->_info['iptc'][$label])) {
+ $aux = array();
+ $aux[0] = $this->_info['iptc'][$label];
+ $this->_info['iptc'][$label] = $aux;
+ }
+ $this->_info['iptc'][$label][ count($this->_info['iptc'][$label]) ] = $this->_getFixedString($data, $pos, $length);
+ } else {
+ $this->_info['iptc'][$label] = $this->_getFixedString($data, $pos, $length);
+ }
+ }
+
+ $pos = $basePos + $length; // No padding
+ }
+ return $pos;
+ }
+
+ /*************************************************************/
+ function & _createMarkerAdobe() {
+ if (isset($this->_info['iptc'])) {
+ if (!isset($this->_info['adobe'])) {
+ $this->_info['adobe'] = array();
+ }
+ if (!isset($this->_info['adobe']['raw'])) {
+ $this->_info['adobe']['raw'] = array();
+ }
+ if (!isset($this->_info['adobe']['raw']['8BIM_0x0404'])) {
+ $this->_info['adobe']['raw']['8BIM_0x0404'] = array();
+ }
+ $this->_info['adobe']['raw']['8BIM_0x0404']['type'] = 0x0404;
+ $this->_info['adobe']['raw']['8BIM_0x0404']['header'] = "Caption";
+ $this->_info['adobe']['raw']['8BIM_0x0404']['data'] =& $this->_writeIPTC();
+ }
+
+ if (isset($this->_info['adobe']['raw']) && (count($this->_info['adobe']['raw']) > 0)) {
+ $data = "Photoshop 3.0\0";
+ $pos = 14;
+
+ reset($this->_info['adobe']['raw']);
+ foreach ($this->_info['adobe']['raw'] as $value){
+ $pos = $this->_write8BIM(
+ $data,
+ $pos,
+ $value['type'],
+ $value['header'],
+ $value['data'] );
+ }
+ }
+
+ return $data;
+ }
+
+ /*************************************************************/
+
+ /**
+ * @param mixed $data
+ * @param integer $pos
+ *
+ * @param string $type
+ * @param string $header
+ * @param mixed $value
+ *
+ * @return int|mixed
+ */
+ function _write8BIM(&$data, $pos, $type, $header, &$value) {
+ $signature = "8BIM";
+
+ $pos = $this->_putString($data, $pos, $signature);
+ $pos = $this->_putShort($data, $pos, $type);
+
+ $len = strlen($header);
+
+ $pos = $this->_putByte($data, $pos, $len);
+ $pos = $this->_putString($data, $pos, $header);
+ if (($len % 2) == 0) { // Even padding, including the length byte
+ $pos = $this->_putByte($data, $pos, 0);
+ }
+
+ $len = strlen($value);
+ $pos = $this->_putLong($data, $pos, $len);
+ $pos = $this->_putString($data, $pos, $value);
+ if (($len % 2) != 0) { // Even padding
+ $pos = $this->_putByte($data, $pos, 0);
+ }
+ return $pos;
+ }
+
+ /*************************************************************/
+ function & _writeIPTC() {
+ $data = " ";
+ $pos = 0;
+
+ $IPTCNames =& $this->_iptcNameTags();
+
+ foreach($this->_info['iptc'] as $label => $value) {
+ $value =& $this->_info['iptc'][$label];
+ $type = -1;
+
+ if (isset($IPTCNames[$label])) {
+ $type = $IPTCNames[$label];
+ }
+ elseif (substr($label, 0, 7) == "IPTC_0x") {
+ $type = hexdec(substr($label, 7, 2));
+ }
+
+ if ($type != -1) {
+ if (is_array($value)) {
+ $vcnt = count($value);
+ for ($i = 0; $i < $vcnt; $i++) {
+ $pos = $this->_writeIPTCEntry($data, $pos, $type, $value[$i]);
+ }
+ }
+ else {
+ $pos = $this->_writeIPTCEntry($data, $pos, $type, $value);
+ }
+ }
+ }
+
+ return $data;
+ }
+
+ /*************************************************************/
+
+ /**
+ * @param mixed $data
+ * @param integer $pos
+ *
+ * @param string $type
+ * @param mixed $value
+ *
+ * @return int|mixed
+ */
+ function _writeIPTCEntry(&$data, $pos, $type, &$value) {
+ $pos = $this->_putShort($data, $pos, 0x1C02);
+ $pos = $this->_putByte($data, $pos, $type);
+ $pos = $this->_putShort($data, $pos, strlen($value));
+ $pos = $this->_putString($data, $pos, $value);
+
+ return $pos;
+ }
+
+ /*************************************************************/
+ function _exifTagNames($mode) {
+ $tags = array();
+
+ if ($mode == 'ifd0') {
+ $tags[0x010E] = 'ImageDescription';
+ $tags[0x010F] = 'Make';
+ $tags[0x0110] = 'Model';
+ $tags[0x0112] = 'Orientation';
+ $tags[0x011A] = 'XResolution';
+ $tags[0x011B] = 'YResolution';
+ $tags[0x0128] = 'ResolutionUnit';
+ $tags[0x0131] = 'Software';
+ $tags[0x0132] = 'DateTime';
+ $tags[0x013B] = 'Artist';
+ $tags[0x013E] = 'WhitePoint';
+ $tags[0x013F] = 'PrimaryChromaticities';
+ $tags[0x0211] = 'YCbCrCoefficients';
+ $tags[0x0212] = 'YCbCrSubSampling';
+ $tags[0x0213] = 'YCbCrPositioning';
+ $tags[0x0214] = 'ReferenceBlackWhite';
+ $tags[0x8298] = 'Copyright';
+ $tags[0x8769] = 'ExifIFDOffset';
+ $tags[0x8825] = 'GPSIFDOffset';
+ }
+ if ($mode == 'ifd1') {
+ $tags[0x00FE] = 'TIFFNewSubfileType';
+ $tags[0x00FF] = 'TIFFSubfileType';
+ $tags[0x0100] = 'TIFFImageWidth';
+ $tags[0x0101] = 'TIFFImageHeight';
+ $tags[0x0102] = 'TIFFBitsPerSample';
+ $tags[0x0103] = 'TIFFCompression';
+ $tags[0x0106] = 'TIFFPhotometricInterpretation';
+ $tags[0x0107] = 'TIFFThreshholding';
+ $tags[0x0108] = 'TIFFCellWidth';
+ $tags[0x0109] = 'TIFFCellLength';
+ $tags[0x010A] = 'TIFFFillOrder';
+ $tags[0x010E] = 'TIFFImageDescription';
+ $tags[0x010F] = 'TIFFMake';
+ $tags[0x0110] = 'TIFFModel';
+ $tags[0x0111] = 'TIFFStripOffsets';
+ $tags[0x0112] = 'TIFFOrientation';
+ $tags[0x0115] = 'TIFFSamplesPerPixel';
+ $tags[0x0116] = 'TIFFRowsPerStrip';
+ $tags[0x0117] = 'TIFFStripByteCounts';
+ $tags[0x0118] = 'TIFFMinSampleValue';
+ $tags[0x0119] = 'TIFFMaxSampleValue';
+ $tags[0x011A] = 'TIFFXResolution';
+ $tags[0x011B] = 'TIFFYResolution';
+ $tags[0x011C] = 'TIFFPlanarConfiguration';
+ $tags[0x0122] = 'TIFFGrayResponseUnit';
+ $tags[0x0123] = 'TIFFGrayResponseCurve';
+ $tags[0x0128] = 'TIFFResolutionUnit';
+ $tags[0x0131] = 'TIFFSoftware';
+ $tags[0x0132] = 'TIFFDateTime';
+ $tags[0x013B] = 'TIFFArtist';
+ $tags[0x013C] = 'TIFFHostComputer';
+ $tags[0x0140] = 'TIFFColorMap';
+ $tags[0x0152] = 'TIFFExtraSamples';
+ $tags[0x0201] = 'TIFFJFIFOffset';
+ $tags[0x0202] = 'TIFFJFIFLength';
+ $tags[0x0211] = 'TIFFYCbCrCoefficients';
+ $tags[0x0212] = 'TIFFYCbCrSubSampling';
+ $tags[0x0213] = 'TIFFYCbCrPositioning';
+ $tags[0x0214] = 'TIFFReferenceBlackWhite';
+ $tags[0x8298] = 'TIFFCopyright';
+ $tags[0x9286] = 'TIFFUserComment';
+ } elseif ($mode == 'exif') {
+ $tags[0x829A] = 'ExposureTime';
+ $tags[0x829D] = 'FNumber';
+ $tags[0x8822] = 'ExposureProgram';
+ $tags[0x8824] = 'SpectralSensitivity';
+ $tags[0x8827] = 'ISOSpeedRatings';
+ $tags[0x8828] = 'OECF';
+ $tags[0x9000] = 'EXIFVersion';
+ $tags[0x9003] = 'DateTimeOriginal';
+ $tags[0x9004] = 'DateTimeDigitized';
+ $tags[0x9101] = 'ComponentsConfiguration';
+ $tags[0x9102] = 'CompressedBitsPerPixel';
+ $tags[0x9201] = 'ShutterSpeedValue';
+ $tags[0x9202] = 'ApertureValue';
+ $tags[0x9203] = 'BrightnessValue';
+ $tags[0x9204] = 'ExposureBiasValue';
+ $tags[0x9205] = 'MaxApertureValue';
+ $tags[0x9206] = 'SubjectDistance';
+ $tags[0x9207] = 'MeteringMode';
+ $tags[0x9208] = 'LightSource';
+ $tags[0x9209] = 'Flash';
+ $tags[0x920A] = 'FocalLength';
+ $tags[0x927C] = 'MakerNote';
+ $tags[0x9286] = 'UserComment';
+ $tags[0x9290] = 'SubSecTime';
+ $tags[0x9291] = 'SubSecTimeOriginal';
+ $tags[0x9292] = 'SubSecTimeDigitized';
+ $tags[0xA000] = 'FlashPixVersion';
+ $tags[0xA001] = 'ColorSpace';
+ $tags[0xA002] = 'PixelXDimension';
+ $tags[0xA003] = 'PixelYDimension';
+ $tags[0xA004] = 'RelatedSoundFile';
+ $tags[0xA005] = 'InteropIFDOffset';
+ $tags[0xA20B] = 'FlashEnergy';
+ $tags[0xA20C] = 'SpatialFrequencyResponse';
+ $tags[0xA20E] = 'FocalPlaneXResolution';
+ $tags[0xA20F] = 'FocalPlaneYResolution';
+ $tags[0xA210] = 'FocalPlaneResolutionUnit';
+ $tags[0xA214] = 'SubjectLocation';
+ $tags[0xA215] = 'ExposureIndex';
+ $tags[0xA217] = 'SensingMethod';
+ $tags[0xA300] = 'FileSource';
+ $tags[0xA301] = 'SceneType';
+ $tags[0xA302] = 'CFAPattern';
+ } elseif ($mode == 'interop') {
+ $tags[0x0001] = 'InteroperabilityIndex';
+ $tags[0x0002] = 'InteroperabilityVersion';
+ $tags[0x1000] = 'RelatedImageFileFormat';
+ $tags[0x1001] = 'RelatedImageWidth';
+ $tags[0x1002] = 'RelatedImageLength';
+ } elseif ($mode == 'gps') {
+ $tags[0x0000] = 'GPSVersionID';
+ $tags[0x0001] = 'GPSLatitudeRef';
+ $tags[0x0002] = 'GPSLatitude';
+ $tags[0x0003] = 'GPSLongitudeRef';
+ $tags[0x0004] = 'GPSLongitude';
+ $tags[0x0005] = 'GPSAltitudeRef';
+ $tags[0x0006] = 'GPSAltitude';
+ $tags[0x0007] = 'GPSTimeStamp';
+ $tags[0x0008] = 'GPSSatellites';
+ $tags[0x0009] = 'GPSStatus';
+ $tags[0x000A] = 'GPSMeasureMode';
+ $tags[0x000B] = 'GPSDOP';
+ $tags[0x000C] = 'GPSSpeedRef';
+ $tags[0x000D] = 'GPSSpeed';
+ $tags[0x000E] = 'GPSTrackRef';
+ $tags[0x000F] = 'GPSTrack';
+ $tags[0x0010] = 'GPSImgDirectionRef';
+ $tags[0x0011] = 'GPSImgDirection';
+ $tags[0x0012] = 'GPSMapDatum';
+ $tags[0x0013] = 'GPSDestLatitudeRef';
+ $tags[0x0014] = 'GPSDestLatitude';
+ $tags[0x0015] = 'GPSDestLongitudeRef';
+ $tags[0x0016] = 'GPSDestLongitude';
+ $tags[0x0017] = 'GPSDestBearingRef';
+ $tags[0x0018] = 'GPSDestBearing';
+ $tags[0x0019] = 'GPSDestDistanceRef';
+ $tags[0x001A] = 'GPSDestDistance';
+ }
+
+ return $tags;
+ }
+
+ /*************************************************************/
+ function _exifTagTypes($mode) {
+ $tags = array();
+
+ if ($mode == 'ifd0') {
+ $tags[0x010E] = array(2, 0); // ImageDescription -> ASCII, Any
+ $tags[0x010F] = array(2, 0); // Make -> ASCII, Any
+ $tags[0x0110] = array(2, 0); // Model -> ASCII, Any
+ $tags[0x0112] = array(3, 1); // Orientation -> SHORT, 1
+ $tags[0x011A] = array(5, 1); // XResolution -> RATIONAL, 1
+ $tags[0x011B] = array(5, 1); // YResolution -> RATIONAL, 1
+ $tags[0x0128] = array(3, 1); // ResolutionUnit -> SHORT
+ $tags[0x0131] = array(2, 0); // Software -> ASCII, Any
+ $tags[0x0132] = array(2, 20); // DateTime -> ASCII, 20
+ $tags[0x013B] = array(2, 0); // Artist -> ASCII, Any
+ $tags[0x013E] = array(5, 2); // WhitePoint -> RATIONAL, 2
+ $tags[0x013F] = array(5, 6); // PrimaryChromaticities -> RATIONAL, 6
+ $tags[0x0211] = array(5, 3); // YCbCrCoefficients -> RATIONAL, 3
+ $tags[0x0212] = array(3, 2); // YCbCrSubSampling -> SHORT, 2
+ $tags[0x0213] = array(3, 1); // YCbCrPositioning -> SHORT, 1
+ $tags[0x0214] = array(5, 6); // ReferenceBlackWhite -> RATIONAL, 6
+ $tags[0x8298] = array(2, 0); // Copyright -> ASCII, Any
+ $tags[0x8769] = array(4, 1); // ExifIFDOffset -> LONG, 1
+ $tags[0x8825] = array(4, 1); // GPSIFDOffset -> LONG, 1
+ }
+ if ($mode == 'ifd1') {
+ $tags[0x00FE] = array(4, 1); // TIFFNewSubfileType -> LONG, 1
+ $tags[0x00FF] = array(3, 1); // TIFFSubfileType -> SHORT, 1
+ $tags[0x0100] = array(4, 1); // TIFFImageWidth -> LONG (or SHORT), 1
+ $tags[0x0101] = array(4, 1); // TIFFImageHeight -> LONG (or SHORT), 1
+ $tags[0x0102] = array(3, 3); // TIFFBitsPerSample -> SHORT, 3
+ $tags[0x0103] = array(3, 1); // TIFFCompression -> SHORT, 1
+ $tags[0x0106] = array(3, 1); // TIFFPhotometricInterpretation -> SHORT, 1
+ $tags[0x0107] = array(3, 1); // TIFFThreshholding -> SHORT, 1
+ $tags[0x0108] = array(3, 1); // TIFFCellWidth -> SHORT, 1
+ $tags[0x0109] = array(3, 1); // TIFFCellLength -> SHORT, 1
+ $tags[0x010A] = array(3, 1); // TIFFFillOrder -> SHORT, 1
+ $tags[0x010E] = array(2, 0); // TIFFImageDescription -> ASCII, Any
+ $tags[0x010F] = array(2, 0); // TIFFMake -> ASCII, Any
+ $tags[0x0110] = array(2, 0); // TIFFModel -> ASCII, Any
+ $tags[0x0111] = array(4, 0); // TIFFStripOffsets -> LONG (or SHORT), Any (one per strip)
+ $tags[0x0112] = array(3, 1); // TIFFOrientation -> SHORT, 1
+ $tags[0x0115] = array(3, 1); // TIFFSamplesPerPixel -> SHORT, 1
+ $tags[0x0116] = array(4, 1); // TIFFRowsPerStrip -> LONG (or SHORT), 1
+ $tags[0x0117] = array(4, 0); // TIFFStripByteCounts -> LONG (or SHORT), Any (one per strip)
+ $tags[0x0118] = array(3, 0); // TIFFMinSampleValue -> SHORT, Any (SamplesPerPixel)
+ $tags[0x0119] = array(3, 0); // TIFFMaxSampleValue -> SHORT, Any (SamplesPerPixel)
+ $tags[0x011A] = array(5, 1); // TIFFXResolution -> RATIONAL, 1
+ $tags[0x011B] = array(5, 1); // TIFFYResolution -> RATIONAL, 1
+ $tags[0x011C] = array(3, 1); // TIFFPlanarConfiguration -> SHORT, 1
+ $tags[0x0122] = array(3, 1); // TIFFGrayResponseUnit -> SHORT, 1
+ $tags[0x0123] = array(3, 0); // TIFFGrayResponseCurve -> SHORT, Any (2^BitsPerSample)
+ $tags[0x0128] = array(3, 1); // TIFFResolutionUnit -> SHORT, 1
+ $tags[0x0131] = array(2, 0); // TIFFSoftware -> ASCII, Any
+ $tags[0x0132] = array(2, 20); // TIFFDateTime -> ASCII, 20
+ $tags[0x013B] = array(2, 0); // TIFFArtist -> ASCII, Any
+ $tags[0x013C] = array(2, 0); // TIFFHostComputer -> ASCII, Any
+ $tags[0x0140] = array(3, 0); // TIFFColorMap -> SHORT, Any (3 * 2^BitsPerSample)
+ $tags[0x0152] = array(3, 0); // TIFFExtraSamples -> SHORT, Any (SamplesPerPixel - 3)
+ $tags[0x0201] = array(4, 1); // TIFFJFIFOffset -> LONG, 1
+ $tags[0x0202] = array(4, 1); // TIFFJFIFLength -> LONG, 1
+ $tags[0x0211] = array(5, 3); // TIFFYCbCrCoefficients -> RATIONAL, 3
+ $tags[0x0212] = array(3, 2); // TIFFYCbCrSubSampling -> SHORT, 2
+ $tags[0x0213] = array(3, 1); // TIFFYCbCrPositioning -> SHORT, 1
+ $tags[0x0214] = array(5, 6); // TIFFReferenceBlackWhite -> RATIONAL, 6
+ $tags[0x8298] = array(2, 0); // TIFFCopyright -> ASCII, Any
+ $tags[0x9286] = array(2, 0); // TIFFUserComment -> ASCII, Any
+ } elseif ($mode == 'exif') {
+ $tags[0x829A] = array(5, 1); // ExposureTime -> RATIONAL, 1
+ $tags[0x829D] = array(5, 1); // FNumber -> RATIONAL, 1
+ $tags[0x8822] = array(3, 1); // ExposureProgram -> SHORT, 1
+ $tags[0x8824] = array(2, 0); // SpectralSensitivity -> ASCII, Any
+ $tags[0x8827] = array(3, 0); // ISOSpeedRatings -> SHORT, Any
+ $tags[0x8828] = array(7, 0); // OECF -> UNDEFINED, Any
+ $tags[0x9000] = array(7, 4); // EXIFVersion -> UNDEFINED, 4
+ $tags[0x9003] = array(2, 20); // DateTimeOriginal -> ASCII, 20
+ $tags[0x9004] = array(2, 20); // DateTimeDigitized -> ASCII, 20
+ $tags[0x9101] = array(7, 4); // ComponentsConfiguration -> UNDEFINED, 4
+ $tags[0x9102] = array(5, 1); // CompressedBitsPerPixel -> RATIONAL, 1
+ $tags[0x9201] = array(10, 1); // ShutterSpeedValue -> SRATIONAL, 1
+ $tags[0x9202] = array(5, 1); // ApertureValue -> RATIONAL, 1
+ $tags[0x9203] = array(10, 1); // BrightnessValue -> SRATIONAL, 1
+ $tags[0x9204] = array(10, 1); // ExposureBiasValue -> SRATIONAL, 1
+ $tags[0x9205] = array(5, 1); // MaxApertureValue -> RATIONAL, 1
+ $tags[0x9206] = array(5, 1); // SubjectDistance -> RATIONAL, 1
+ $tags[0x9207] = array(3, 1); // MeteringMode -> SHORT, 1
+ $tags[0x9208] = array(3, 1); // LightSource -> SHORT, 1
+ $tags[0x9209] = array(3, 1); // Flash -> SHORT, 1
+ $tags[0x920A] = array(5, 1); // FocalLength -> RATIONAL, 1
+ $tags[0x927C] = array(7, 0); // MakerNote -> UNDEFINED, Any
+ $tags[0x9286] = array(7, 0); // UserComment -> UNDEFINED, Any
+ $tags[0x9290] = array(2, 0); // SubSecTime -> ASCII, Any
+ $tags[0x9291] = array(2, 0); // SubSecTimeOriginal -> ASCII, Any
+ $tags[0x9292] = array(2, 0); // SubSecTimeDigitized -> ASCII, Any
+ $tags[0xA000] = array(7, 4); // FlashPixVersion -> UNDEFINED, 4
+ $tags[0xA001] = array(3, 1); // ColorSpace -> SHORT, 1
+ $tags[0xA002] = array(4, 1); // PixelXDimension -> LONG (or SHORT), 1
+ $tags[0xA003] = array(4, 1); // PixelYDimension -> LONG (or SHORT), 1
+ $tags[0xA004] = array(2, 13); // RelatedSoundFile -> ASCII, 13
+ $tags[0xA005] = array(4, 1); // InteropIFDOffset -> LONG, 1
+ $tags[0xA20B] = array(5, 1); // FlashEnergy -> RATIONAL, 1
+ $tags[0xA20C] = array(7, 0); // SpatialFrequencyResponse -> UNDEFINED, Any
+ $tags[0xA20E] = array(5, 1); // FocalPlaneXResolution -> RATIONAL, 1
+ $tags[0xA20F] = array(5, 1); // FocalPlaneYResolution -> RATIONAL, 1
+ $tags[0xA210] = array(3, 1); // FocalPlaneResolutionUnit -> SHORT, 1
+ $tags[0xA214] = array(3, 2); // SubjectLocation -> SHORT, 2
+ $tags[0xA215] = array(5, 1); // ExposureIndex -> RATIONAL, 1
+ $tags[0xA217] = array(3, 1); // SensingMethod -> SHORT, 1
+ $tags[0xA300] = array(7, 1); // FileSource -> UNDEFINED, 1
+ $tags[0xA301] = array(7, 1); // SceneType -> UNDEFINED, 1
+ $tags[0xA302] = array(7, 0); // CFAPattern -> UNDEFINED, Any
+ } elseif ($mode == 'interop') {
+ $tags[0x0001] = array(2, 0); // InteroperabilityIndex -> ASCII, Any
+ $tags[0x0002] = array(7, 4); // InteroperabilityVersion -> UNKNOWN, 4
+ $tags[0x1000] = array(2, 0); // RelatedImageFileFormat -> ASCII, Any
+ $tags[0x1001] = array(4, 1); // RelatedImageWidth -> LONG (or SHORT), 1
+ $tags[0x1002] = array(4, 1); // RelatedImageLength -> LONG (or SHORT), 1
+ } elseif ($mode == 'gps') {
+ $tags[0x0000] = array(1, 4); // GPSVersionID -> BYTE, 4
+ $tags[0x0001] = array(2, 2); // GPSLatitudeRef -> ASCII, 2
+ $tags[0x0002] = array(5, 3); // GPSLatitude -> RATIONAL, 3
+ $tags[0x0003] = array(2, 2); // GPSLongitudeRef -> ASCII, 2
+ $tags[0x0004] = array(5, 3); // GPSLongitude -> RATIONAL, 3
+ $tags[0x0005] = array(2, 2); // GPSAltitudeRef -> ASCII, 2
+ $tags[0x0006] = array(5, 1); // GPSAltitude -> RATIONAL, 1
+ $tags[0x0007] = array(5, 3); // GPSTimeStamp -> RATIONAL, 3
+ $tags[0x0008] = array(2, 0); // GPSSatellites -> ASCII, Any
+ $tags[0x0009] = array(2, 2); // GPSStatus -> ASCII, 2
+ $tags[0x000A] = array(2, 2); // GPSMeasureMode -> ASCII, 2
+ $tags[0x000B] = array(5, 1); // GPSDOP -> RATIONAL, 1
+ $tags[0x000C] = array(2, 2); // GPSSpeedRef -> ASCII, 2
+ $tags[0x000D] = array(5, 1); // GPSSpeed -> RATIONAL, 1
+ $tags[0x000E] = array(2, 2); // GPSTrackRef -> ASCII, 2
+ $tags[0x000F] = array(5, 1); // GPSTrack -> RATIONAL, 1
+ $tags[0x0010] = array(2, 2); // GPSImgDirectionRef -> ASCII, 2
+ $tags[0x0011] = array(5, 1); // GPSImgDirection -> RATIONAL, 1
+ $tags[0x0012] = array(2, 0); // GPSMapDatum -> ASCII, Any
+ $tags[0x0013] = array(2, 2); // GPSDestLatitudeRef -> ASCII, 2
+ $tags[0x0014] = array(5, 3); // GPSDestLatitude -> RATIONAL, 3
+ $tags[0x0015] = array(2, 2); // GPSDestLongitudeRef -> ASCII, 2
+ $tags[0x0016] = array(5, 3); // GPSDestLongitude -> RATIONAL, 3
+ $tags[0x0017] = array(2, 2); // GPSDestBearingRef -> ASCII, 2
+ $tags[0x0018] = array(5, 1); // GPSDestBearing -> RATIONAL, 1
+ $tags[0x0019] = array(2, 2); // GPSDestDistanceRef -> ASCII, 2
+ $tags[0x001A] = array(5, 1); // GPSDestDistance -> RATIONAL, 1
+ }
+
+ return $tags;
+ }
+
+ /*************************************************************/
+ function _exifNameTags($mode) {
+ $tags = $this->_exifTagNames($mode);
+ return $this->_names2Tags($tags);
+ }
+
+ /*************************************************************/
+ function _iptcTagNames() {
+ $tags = array();
+ $tags[0x14] = 'SuplementalCategories';
+ $tags[0x19] = 'Keywords';
+ $tags[0x78] = 'Caption';
+ $tags[0x7A] = 'CaptionWriter';
+ $tags[0x69] = 'Headline';
+ $tags[0x28] = 'SpecialInstructions';
+ $tags[0x0F] = 'Category';
+ $tags[0x50] = 'Byline';
+ $tags[0x55] = 'BylineTitle';
+ $tags[0x6E] = 'Credit';
+ $tags[0x73] = 'Source';
+ $tags[0x74] = 'CopyrightNotice';
+ $tags[0x05] = 'ObjectName';
+ $tags[0x5A] = 'City';
+ $tags[0x5C] = 'Sublocation';
+ $tags[0x5F] = 'ProvinceState';
+ $tags[0x65] = 'CountryName';
+ $tags[0x67] = 'OriginalTransmissionReference';
+ $tags[0x37] = 'DateCreated';
+ $tags[0x0A] = 'CopyrightFlag';
+
+ return $tags;
+ }
+
+ /*************************************************************/
+ function & _iptcNameTags() {
+ $tags = $this->_iptcTagNames();
+ return $this->_names2Tags($tags);
+ }
+
+ /*************************************************************/
+ function _names2Tags($tags2Names) {
+ $names2Tags = array();
+
+ foreach($tags2Names as $tag => $name) {
+ $names2Tags[$name] = $tag;
+ }
+
+ return $names2Tags;
+ }
+
+ /*************************************************************/
+
+ /**
+ * @param $data
+ * @param integer $pos
+ *
+ * @return int
+ */
+ function _getByte(&$data, $pos) {
+ return ord($data[$pos]);
+ }
+
+ /*************************************************************/
+
+ /**
+ * @param mixed $data
+ * @param integer $pos
+ *
+ * @param mixed $val
+ *
+ * @return int
+ */
+ function _putByte(&$data, $pos, $val) {
+ $val = intval($val);
+
+ $data[$pos] = chr($val);
+
+ return $pos + 1;
+ }
+
+ /*************************************************************/
+ function _getShort(&$data, $pos, $bigEndian = true) {
+ if ($bigEndian) {
+ return (ord($data[$pos]) << 8)
+ + ord($data[$pos + 1]);
+ } else {
+ return ord($data[$pos])
+ + (ord($data[$pos + 1]) << 8);
+ }
+ }
+
+ /*************************************************************/
+ function _putShort(&$data, $pos = 0, $val = 0, $bigEndian = true) {
+ $val = intval($val);
+
+ if ($bigEndian) {
+ $data[$pos + 0] = chr(($val & 0x0000FF00) >> 8);
+ $data[$pos + 1] = chr(($val & 0x000000FF) >> 0);
+ } else {
+ $data[$pos + 0] = chr(($val & 0x00FF) >> 0);
+ $data[$pos + 1] = chr(($val & 0xFF00) >> 8);
+ }
+
+ return $pos + 2;
+ }
+
+ /*************************************************************/
+
+ /**
+ * @param mixed $data
+ * @param integer $pos
+ *
+ * @param bool $bigEndian
+ *
+ * @return int
+ */
+ function _getLong(&$data, $pos, $bigEndian = true) {
+ if ($bigEndian) {
+ return (ord($data[$pos]) << 24)
+ + (ord($data[$pos + 1]) << 16)
+ + (ord($data[$pos + 2]) << 8)
+ + ord($data[$pos + 3]);
+ } else {
+ return ord($data[$pos])
+ + (ord($data[$pos + 1]) << 8)
+ + (ord($data[$pos + 2]) << 16)
+ + (ord($data[$pos + 3]) << 24);
+ }
+ }
+
+ /*************************************************************/
+
+ /**
+ * @param mixed $data
+ * @param integer $pos
+ *
+ * @param mixed $val
+ * @param bool $bigEndian
+ *
+ * @return int
+ */
+ function _putLong(&$data, $pos, $val, $bigEndian = true) {
+ $val = intval($val);
+
+ if ($bigEndian) {
+ $data[$pos + 0] = chr(($val & 0xFF000000) >> 24);
+ $data[$pos + 1] = chr(($val & 0x00FF0000) >> 16);
+ $data[$pos + 2] = chr(($val & 0x0000FF00) >> 8);
+ $data[$pos + 3] = chr(($val & 0x000000FF) >> 0);
+ } else {
+ $data[$pos + 0] = chr(($val & 0x000000FF) >> 0);
+ $data[$pos + 1] = chr(($val & 0x0000FF00) >> 8);
+ $data[$pos + 2] = chr(($val & 0x00FF0000) >> 16);
+ $data[$pos + 3] = chr(($val & 0xFF000000) >> 24);
+ }
+
+ return $pos + 4;
+ }
+
+ /*************************************************************/
+ function & _getNullString(&$data, $pos) {
+ $str = '';
+ $max = strlen($data);
+
+ while ($pos < $max) {
+ if (ord($data[$pos]) == 0) {
+ return $str;
+ } else {
+ $str .= $data[$pos];
+ }
+ $pos++;
+ }
+
+ return $str;
+ }
+
+ /*************************************************************/
+ function & _getFixedString(&$data, $pos, $length = -1) {
+ if ($length == -1) {
+ $length = strlen($data) - $pos;
+ }
+
+ $rv = substr($data, $pos, $length);
+ return $rv;
+ }
+
+ /*************************************************************/
+ function _putString(&$data, $pos, &$str) {
+ $len = strlen($str);
+ for ($i = 0; $i < $len; $i++) {
+ $data[$pos + $i] = $str[$i];
+ }
+
+ return $pos + $len;
+ }
+
+ /*************************************************************/
+ function _hexDump(&$data, $start = 0, $length = -1) {
+ if (($length == -1) || (($length + $start) > strlen($data))) {
+ $end = strlen($data);
+ } else {
+ $end = $start + $length;
+ }
+
+ $ascii = '';
+ $count = 0;
+
+ echo "<tt>\n";
+
+ while ($start < $end) {
+ if (($count % 16) == 0) {
+ echo sprintf('%04d', $count) . ': ';
+ }
+
+ $c = ord($data[$start]);
+ $count++;
+ $start++;
+
+ $aux = dechex($c);
+ if (strlen($aux) == 1)
+ echo '0';
+ echo $aux . ' ';
+
+ if ($c == 60)
+ $ascii .= '&lt;';
+ elseif ($c == 62)
+ $ascii .= '&gt;';
+ elseif ($c == 32)
+ $ascii .= '&#160;';
+ elseif ($c > 32)
+ $ascii .= chr($c);
+ else
+ $ascii .= '.';
+
+ if (($count % 4) == 0) {
+ echo ' - ';
+ }
+
+ if (($count % 16) == 0) {
+ echo ': ' . $ascii . "<br>\n";
+ $ascii = '';
+ }
+ }
+
+ if ($ascii != '') {
+ while (($count % 16) != 0) {
+ echo '-- ';
+ $count++;
+ if (($count % 4) == 0) {
+ echo ' - ';
+ }
+ }
+ echo ': ' . $ascii . "<br>\n";
+ }
+
+ echo "</tt>\n";
+ }
+
+ /*****************************************************************/
+}
+
+/* vim: set expandtab tabstop=4 shiftwidth=4: */
diff --git a/platform/www/inc/Mailer.class.php b/platform/www/inc/Mailer.class.php
new file mode 100644
index 0000000..dd6cbd3
--- /dev/null
+++ b/platform/www/inc/Mailer.class.php
@@ -0,0 +1,777 @@
+<?php
+/**
+ * A class to build and send multi part mails (with HTML content and embedded
+ * attachments). All mails are assumed to be in UTF-8 encoding.
+ *
+ * Attachments are handled in memory so this shouldn't be used to send huge
+ * files, but then again mail shouldn't be used to send huge files either.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Extension\Event;
+
+// end of line for mail lines - RFC822 says CRLF but postfix (and other MTAs?)
+// think different
+if(!defined('MAILHEADER_EOL')) define('MAILHEADER_EOL', "\n");
+#define('MAILHEADER_ASCIIONLY',1);
+
+/**
+ * Mail Handling
+ */
+class Mailer {
+
+ protected $headers = array();
+ protected $attach = array();
+ protected $html = '';
+ protected $text = '';
+
+ protected $boundary = '';
+ protected $partid = '';
+ protected $sendparam = null;
+
+ protected $allowhtml = true;
+
+ protected $replacements = array('text'=> array(), 'html' => array());
+
+ /**
+ * Constructor
+ *
+ * Initializes the boundary strings, part counters and token replacements
+ */
+ public function __construct() {
+ global $conf;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ $server = parse_url(DOKU_URL, PHP_URL_HOST);
+ if(strpos($server,'.') === false) $server .= '.localhost';
+
+ $this->partid = substr(md5(uniqid(mt_rand(), true)),0, 8).'@'.$server;
+ $this->boundary = '__________'.md5(uniqid(mt_rand(), true));
+
+ $listid = implode('.', array_reverse(explode('/', DOKU_BASE))).$server;
+ $listid = strtolower(trim($listid, '.'));
+
+ $this->allowhtml = (bool)$conf['htmlmail'];
+
+ // add some default headers for mailfiltering FS#2247
+ if(!empty($conf['mailreturnpath'])) {
+ $this->setHeader('Return-Path', $conf['mailreturnpath']);
+ }
+ $this->setHeader('X-Mailer', 'DokuWiki');
+ $this->setHeader('X-DokuWiki-User', $INPUT->server->str('REMOTE_USER'));
+ $this->setHeader('X-DokuWiki-Title', $conf['title']);
+ $this->setHeader('X-DokuWiki-Server', $server);
+ $this->setHeader('X-Auto-Response-Suppress', 'OOF');
+ $this->setHeader('List-Id', $conf['title'].' <'.$listid.'>');
+ $this->setHeader('Date', date('r'), false);
+
+ $this->prepareTokenReplacements();
+ }
+
+ /**
+ * Attach a file
+ *
+ * @param string $path Path to the file to attach
+ * @param string $mime Mimetype of the attached file
+ * @param string $name The filename to use
+ * @param string $embed Unique key to reference this file from the HTML part
+ */
+ public function attachFile($path, $mime, $name = '', $embed = '') {
+ if(!$name) {
+ $name = \dokuwiki\Utf8\PhpString::basename($path);
+ }
+
+ $this->attach[] = array(
+ 'data' => file_get_contents($path),
+ 'mime' => $mime,
+ 'name' => $name,
+ 'embed' => $embed
+ );
+ }
+
+ /**
+ * Attach a file
+ *
+ * @param string $data The file contents to attach
+ * @param string $mime Mimetype of the attached file
+ * @param string $name The filename to use
+ * @param string $embed Unique key to reference this file from the HTML part
+ */
+ public function attachContent($data, $mime, $name = '', $embed = '') {
+ if(!$name) {
+ list(, $ext) = explode('/', $mime);
+ $name = count($this->attach).".$ext";
+ }
+
+ $this->attach[] = array(
+ 'data' => $data,
+ 'mime' => $mime,
+ 'name' => $name,
+ 'embed' => $embed
+ );
+ }
+
+ /**
+ * Callback function to automatically embed images referenced in HTML templates
+ *
+ * @param array $matches
+ * @return string placeholder
+ */
+ protected function autoEmbedCallBack($matches) {
+ static $embeds = 0;
+ $embeds++;
+
+ // get file and mime type
+ $media = cleanID($matches[1]);
+ list(, $mime) = mimetype($media);
+ $file = mediaFN($media);
+ if(!file_exists($file)) return $matches[0]; //bad reference, keep as is
+
+ // attach it and set placeholder
+ $this->attachFile($file, $mime, '', 'autoembed'.$embeds);
+ return '%%autoembed'.$embeds.'%%';
+ }
+
+ /**
+ * Add an arbitrary header to the mail
+ *
+ * If an empy value is passed, the header is removed
+ *
+ * @param string $header the header name (no trailing colon!)
+ * @param string|string[] $value the value of the header
+ * @param bool $clean remove all non-ASCII chars and line feeds?
+ */
+ public function setHeader($header, $value, $clean = true) {
+ $header = str_replace(' ', '-', ucwords(strtolower(str_replace('-', ' ', $header)))); // streamline casing
+ if($clean) {
+ $header = preg_replace('/[^a-zA-Z0-9_ \-\.\+\@]+/', '', $header);
+ $value = preg_replace('/[^a-zA-Z0-9_ \-\.\+\@<>]+/', '', $value);
+ }
+
+ // empty value deletes
+ if(is_array($value)){
+ $value = array_map('trim', $value);
+ $value = array_filter($value);
+ if(!$value) $value = '';
+ }else{
+ $value = trim($value);
+ }
+ if($value === '') {
+ if(isset($this->headers[$header])) unset($this->headers[$header]);
+ } else {
+ $this->headers[$header] = $value;
+ }
+ }
+
+ /**
+ * Set additional parameters to be passed to sendmail
+ *
+ * Whatever is set here is directly passed to PHP's mail() command as last
+ * parameter. Depending on the PHP setup this might break mailing alltogether
+ *
+ * @param string $param
+ */
+ public function setParameters($param) {
+ $this->sendparam = $param;
+ }
+
+ /**
+ * Set the text and HTML body and apply replacements
+ *
+ * This function applies a whole bunch of default replacements in addition
+ * to the ones specified as parameters
+ *
+ * If you pass the HTML part or HTML replacements yourself you have to make
+ * sure you encode all HTML special chars correctly
+ *
+ * @param string $text plain text body
+ * @param array $textrep replacements to apply on the text part
+ * @param array $htmlrep replacements to apply on the HTML part, null to use $textrep (urls wrapped in <a> tags)
+ * @param string $html the HTML body, leave null to create it from $text
+ * @param bool $wrap wrap the HTML in the default header/Footer
+ */
+ public function setBody($text, $textrep = null, $htmlrep = null, $html = null, $wrap = true) {
+
+ $htmlrep = (array)$htmlrep;
+ $textrep = (array)$textrep;
+
+ // create HTML from text if not given
+ if($html === null) {
+ $html = $text;
+ $html = hsc($html);
+ $html = preg_replace('/^----+$/m', '<hr >', $html);
+ $html = nl2br($html);
+ }
+ if($wrap) {
+ $wrapper = rawLocale('mailwrap', 'html');
+ $html = preg_replace('/\n-- <br \/>.*$/s', '', $html); //strip signature
+ $html = str_replace('@EMAILSIGNATURE@', '', $html); //strip @EMAILSIGNATURE@
+ $html = str_replace('@HTMLBODY@', $html, $wrapper);
+ }
+
+ if(strpos($text, '@EMAILSIGNATURE@') === false) {
+ $text .= '@EMAILSIGNATURE@';
+ }
+
+ // copy over all replacements missing for HTML (autolink URLs)
+ foreach($textrep as $key => $value) {
+ if(isset($htmlrep[$key])) continue;
+ if(media_isexternal($value)) {
+ $htmlrep[$key] = '<a href="'.hsc($value).'">'.hsc($value).'</a>';
+ } else {
+ $htmlrep[$key] = hsc($value);
+ }
+ }
+
+ // embed media from templates
+ $html = preg_replace_callback(
+ '/@MEDIA\(([^\)]+)\)@/',
+ array($this, 'autoEmbedCallBack'), $html
+ );
+
+ // add default token replacements
+ $trep = array_merge($this->replacements['text'], (array)$textrep);
+ $hrep = array_merge($this->replacements['html'], (array)$htmlrep);
+
+ // Apply replacements
+ foreach($trep as $key => $substitution) {
+ $text = str_replace('@'.strtoupper($key).'@', $substitution, $text);
+ }
+ foreach($hrep as $key => $substitution) {
+ $html = str_replace('@'.strtoupper($key).'@', $substitution, $html);
+ }
+
+ $this->setHTML($html);
+ $this->setText($text);
+ }
+
+ /**
+ * Set the HTML part of the mail
+ *
+ * Placeholders can be used to reference embedded attachments
+ *
+ * You probably want to use setBody() instead
+ *
+ * @param string $html
+ */
+ public function setHTML($html) {
+ $this->html = $html;
+ }
+
+ /**
+ * Set the plain text part of the mail
+ *
+ * You probably want to use setBody() instead
+ *
+ * @param string $text
+ */
+ public function setText($text) {
+ $this->text = $text;
+ }
+
+ /**
+ * Add the To: recipients
+ *
+ * @see cleanAddress
+ * @param string|string[] $address Multiple adresses separated by commas or as array
+ */
+ public function to($address) {
+ $this->setHeader('To', $address, false);
+ }
+
+ /**
+ * Add the Cc: recipients
+ *
+ * @see cleanAddress
+ * @param string|string[] $address Multiple adresses separated by commas or as array
+ */
+ public function cc($address) {
+ $this->setHeader('Cc', $address, false);
+ }
+
+ /**
+ * Add the Bcc: recipients
+ *
+ * @see cleanAddress
+ * @param string|string[] $address Multiple adresses separated by commas or as array
+ */
+ public function bcc($address) {
+ $this->setHeader('Bcc', $address, false);
+ }
+
+ /**
+ * Add the From: address
+ *
+ * This is set to $conf['mailfrom'] when not specified so you shouldn't need
+ * to call this function
+ *
+ * @see cleanAddress
+ * @param string $address from address
+ */
+ public function from($address) {
+ $this->setHeader('From', $address, false);
+ }
+
+ /**
+ * Add the mail's Subject: header
+ *
+ * @param string $subject the mail subject
+ */
+ public function subject($subject) {
+ $this->headers['Subject'] = $subject;
+ }
+
+ /**
+ * Return a clean name which can be safely used in mail address
+ * fields. That means the name will be enclosed in '"' if it includes
+ * a '"' or a ','. Also a '"' will be escaped as '\"'.
+ *
+ * @param string $name the name to clean-up
+ * @see cleanAddress
+ */
+ public function getCleanName($name) {
+ $name = trim($name, ' \t"');
+ $name = str_replace('"', '\"', $name, $count);
+ if ($count > 0 || strpos($name, ',') !== false) {
+ $name = '"'.$name.'"';
+ }
+ return $name;
+ }
+
+ /**
+ * Sets an email address header with correct encoding
+ *
+ * Unicode characters will be deaccented and encoded base64
+ * for headers. Addresses may not contain Non-ASCII data!
+ *
+ * If @$addresses is a string then it will be split into multiple
+ * addresses. Addresses must be separated by a comma. If the display
+ * name includes a comma then it MUST be properly enclosed by '"' to
+ * prevent spliting at the wrong point.
+ *
+ * Example:
+ * cc("föö <foo@bar.com>, me@somewhere.com","TBcc");
+ * to("foo, Dr." <foo@bar.com>, me@somewhere.com");
+ *
+ * @param string|string[] $addresses Multiple adresses separated by commas or as array
+ * @return false|string the prepared header (can contain multiple lines)
+ */
+ public function cleanAddress($addresses) {
+ $headers = '';
+ if(!is_array($addresses)){
+ $count = preg_match_all('/\s*(?:("[^"]*"[^,]+),*)|([^,]+)\s*,*/', $addresses, $matches, PREG_SET_ORDER);
+ $addresses = array();
+ if ($count !== false && is_array($matches)) {
+ foreach ($matches as $match) {
+ array_push($addresses, rtrim($match[0], ','));
+ }
+ }
+ }
+
+ foreach($addresses as $part) {
+ $part = preg_replace('/[\r\n\0]+/', ' ', $part); // remove attack vectors
+ $part = trim($part);
+
+ // parse address
+ if(preg_match('#(.*?)<(.*?)>#', $part, $matches)) {
+ $text = trim($matches[1]);
+ $addr = $matches[2];
+ } else {
+ $text = '';
+ $addr = $part;
+ }
+ // skip empty ones
+ if(empty($addr)) {
+ continue;
+ }
+
+ // FIXME: is there a way to encode the localpart of a emailaddress?
+ if(!\dokuwiki\Utf8\Clean::isASCII($addr)) {
+ msg(hsc("E-Mail address <$addr> is not ASCII"), -1, __LINE__, __FILE__, MSG_ADMINS_ONLY);
+ continue;
+ }
+
+ if(!mail_isvalid($addr)) {
+ msg(hsc("E-Mail address <$addr> is not valid"), -1, __LINE__, __FILE__, MSG_ADMINS_ONLY);
+ continue;
+ }
+
+ // text was given
+ if(!empty($text) && !isWindows()) { // No named recipients for To: in Windows (see FS#652)
+ // add address quotes
+ $addr = "<$addr>";
+
+ if(defined('MAILHEADER_ASCIIONLY')) {
+ $text = \dokuwiki\Utf8\Clean::deaccent($text);
+ $text = \dokuwiki\Utf8\Clean::strip($text);
+ }
+
+ if(strpos($text, ',') !== false || !\dokuwiki\Utf8\Clean::isASCII($text)) {
+ $text = '=?UTF-8?B?'.base64_encode($text).'?=';
+ }
+ } else {
+ $text = '';
+ }
+
+ // add to header comma seperated
+ if($headers != '') {
+ $headers .= ', ';
+ }
+ $headers .= $text.' '.$addr;
+ }
+
+ $headers = trim($headers);
+ if(empty($headers)) return false;
+
+ return $headers;
+ }
+
+
+ /**
+ * Prepare the mime multiparts for all attachments
+ *
+ * Replaces placeholders in the HTML with the correct CIDs
+ *
+ * @return string mime multiparts
+ */
+ protected function prepareAttachments() {
+ $mime = '';
+ $part = 1;
+ // embedded attachments
+ foreach($this->attach as $media) {
+ $media['name'] = str_replace(':', '_', cleanID($media['name'], true));
+
+ // create content id
+ $cid = 'part'.$part.'.'.$this->partid;
+
+ // replace wildcards
+ if($media['embed']) {
+ $this->html = str_replace('%%'.$media['embed'].'%%', 'cid:'.$cid, $this->html);
+ }
+
+ $mime .= '--'.$this->boundary.MAILHEADER_EOL;
+ $mime .= $this->wrappedHeaderLine('Content-Type', $media['mime'].'; id="'.$cid.'"');
+ $mime .= $this->wrappedHeaderLine('Content-Transfer-Encoding', 'base64');
+ $mime .= $this->wrappedHeaderLine('Content-ID',"<$cid>");
+ if($media['embed']) {
+ $mime .= $this->wrappedHeaderLine('Content-Disposition', 'inline; filename='.$media['name']);
+ } else {
+ $mime .= $this->wrappedHeaderLine('Content-Disposition', 'attachment; filename='.$media['name']);
+ }
+ $mime .= MAILHEADER_EOL; //end of headers
+ $mime .= chunk_split(base64_encode($media['data']), 74, MAILHEADER_EOL);
+
+ $part++;
+ }
+ return $mime;
+ }
+
+ /**
+ * Build the body and handles multi part mails
+ *
+ * Needs to be called before prepareHeaders!
+ *
+ * @return string the prepared mail body, false on errors
+ */
+ protected function prepareBody() {
+
+ // no HTML mails allowed? remove HTML body
+ if(!$this->allowhtml) {
+ $this->html = '';
+ }
+
+ // check for body
+ if(!$this->text && !$this->html) {
+ return false;
+ }
+
+ // add general headers
+ $this->headers['MIME-Version'] = '1.0';
+
+ $body = '';
+
+ if(!$this->html && !count($this->attach)) { // we can send a simple single part message
+ $this->headers['Content-Type'] = 'text/plain; charset=UTF-8';
+ $this->headers['Content-Transfer-Encoding'] = 'base64';
+ $body .= chunk_split(base64_encode($this->text), 72, MAILHEADER_EOL);
+ } else { // multi part it is
+ $body .= "This is a multi-part message in MIME format.".MAILHEADER_EOL;
+
+ // prepare the attachments
+ $attachments = $this->prepareAttachments();
+
+ // do we have alternative text content?
+ if($this->text && $this->html) {
+ $this->headers['Content-Type'] = 'multipart/alternative;'.MAILHEADER_EOL.
+ ' boundary="'.$this->boundary.'XX"';
+ $body .= '--'.$this->boundary.'XX'.MAILHEADER_EOL;
+ $body .= 'Content-Type: text/plain; charset=UTF-8'.MAILHEADER_EOL;
+ $body .= 'Content-Transfer-Encoding: base64'.MAILHEADER_EOL;
+ $body .= MAILHEADER_EOL;
+ $body .= chunk_split(base64_encode($this->text), 72, MAILHEADER_EOL);
+ $body .= '--'.$this->boundary.'XX'.MAILHEADER_EOL;
+ $body .= 'Content-Type: multipart/related;'.MAILHEADER_EOL.
+ ' boundary="'.$this->boundary.'";'.MAILHEADER_EOL.
+ ' type="text/html"'.MAILHEADER_EOL;
+ $body .= MAILHEADER_EOL;
+ }
+
+ $body .= '--'.$this->boundary.MAILHEADER_EOL;
+ $body .= 'Content-Type: text/html; charset=UTF-8'.MAILHEADER_EOL;
+ $body .= 'Content-Transfer-Encoding: base64'.MAILHEADER_EOL;
+ $body .= MAILHEADER_EOL;
+ $body .= chunk_split(base64_encode($this->html), 72, MAILHEADER_EOL);
+ $body .= MAILHEADER_EOL;
+ $body .= $attachments;
+ $body .= '--'.$this->boundary.'--'.MAILHEADER_EOL;
+
+ // close open multipart/alternative boundary
+ if($this->text && $this->html) {
+ $body .= '--'.$this->boundary.'XX--'.MAILHEADER_EOL;
+ }
+ }
+
+ return $body;
+ }
+
+ /**
+ * Cleanup and encode the headers array
+ */
+ protected function cleanHeaders() {
+ global $conf;
+
+ // clean up addresses
+ if(empty($this->headers['From'])) $this->from($conf['mailfrom']);
+ $addrs = array('To', 'From', 'Cc', 'Bcc', 'Reply-To', 'Sender');
+ foreach($addrs as $addr) {
+ if(isset($this->headers[$addr])) {
+ $this->headers[$addr] = $this->cleanAddress($this->headers[$addr]);
+ }
+ }
+
+ if(isset($this->headers['Subject'])) {
+ // add prefix to subject
+ if(empty($conf['mailprefix'])) {
+ if(\dokuwiki\Utf8\PhpString::strlen($conf['title']) < 20) {
+ $prefix = '['.$conf['title'].']';
+ } else {
+ $prefix = '['.\dokuwiki\Utf8\PhpString::substr($conf['title'], 0, 20).'...]';
+ }
+ } else {
+ $prefix = '['.$conf['mailprefix'].']';
+ }
+ $len = strlen($prefix);
+ if(substr($this->headers['Subject'], 0, $len) != $prefix) {
+ $this->headers['Subject'] = $prefix.' '.$this->headers['Subject'];
+ }
+
+ // encode subject
+ if(defined('MAILHEADER_ASCIIONLY')) {
+ $this->headers['Subject'] = \dokuwiki\Utf8\Clean::deaccent($this->headers['Subject']);
+ $this->headers['Subject'] = \dokuwiki\Utf8\Clean::strip($this->headers['Subject']);
+ }
+ if(!\dokuwiki\Utf8\Clean::isASCII($this->headers['Subject'])) {
+ $this->headers['Subject'] = '=?UTF-8?B?'.base64_encode($this->headers['Subject']).'?=';
+ }
+ }
+
+ }
+
+ /**
+ * Returns a complete, EOL terminated header line, wraps it if necessary
+ *
+ * @param string $key
+ * @param string $val
+ * @return string line
+ */
+ protected function wrappedHeaderLine($key, $val){
+ return wordwrap("$key: $val", 78, MAILHEADER_EOL.' ').MAILHEADER_EOL;
+ }
+
+ /**
+ * Create a string from the headers array
+ *
+ * @returns string the headers
+ */
+ protected function prepareHeaders() {
+ $headers = '';
+ foreach($this->headers as $key => $val) {
+ if ($val === '' || $val === null) continue;
+ $headers .= $this->wrappedHeaderLine($key, $val);
+ }
+ return $headers;
+ }
+
+ /**
+ * return a full email with all headers
+ *
+ * This is mainly intended for debugging and testing but could also be
+ * used for MHT exports
+ *
+ * @return string the mail, false on errors
+ */
+ public function dump() {
+ $this->cleanHeaders();
+ $body = $this->prepareBody();
+ if($body === false) return false;
+ $headers = $this->prepareHeaders();
+
+ return $headers.MAILHEADER_EOL.$body;
+ }
+
+ /**
+ * Prepare default token replacement strings
+ *
+ * Populates the '$replacements' property.
+ * Should be called by the class constructor
+ */
+ protected function prepareTokenReplacements() {
+ global $INFO;
+ global $conf;
+ /* @var Input $INPUT */
+ global $INPUT;
+ global $lang;
+
+ $ip = clientIP();
+ $cip = gethostsbyaddrs($ip);
+ $name = isset($INFO) ? $INFO['userinfo']['name'] : '';
+ $mail = isset($INFO) ? $INFO['userinfo']['mail'] : '';
+
+ $this->replacements['text'] = array(
+ 'DATE' => dformat(),
+ 'BROWSER' => $INPUT->server->str('HTTP_USER_AGENT'),
+ 'IPADDRESS' => $ip,
+ 'HOSTNAME' => $cip,
+ 'TITLE' => $conf['title'],
+ 'DOKUWIKIURL' => DOKU_URL,
+ 'USER' => $INPUT->server->str('REMOTE_USER'),
+ 'NAME' => $name,
+ 'MAIL' => $mail
+ );
+ $signature = str_replace(
+ '@DOKUWIKIURL@',
+ $this->replacements['text']['DOKUWIKIURL'],
+ $lang['email_signature_text']
+ );
+ $this->replacements['text']['EMAILSIGNATURE'] = "\n-- \n" . $signature . "\n";
+
+ $this->replacements['html'] = array(
+ 'DATE' => '<i>' . hsc(dformat()) . '</i>',
+ 'BROWSER' => hsc($INPUT->server->str('HTTP_USER_AGENT')),
+ 'IPADDRESS' => '<code>' . hsc($ip) . '</code>',
+ 'HOSTNAME' => '<code>' . hsc($cip) . '</code>',
+ 'TITLE' => hsc($conf['title']),
+ 'DOKUWIKIURL' => '<a href="' . DOKU_URL . '">' . DOKU_URL . '</a>',
+ 'USER' => hsc($INPUT->server->str('REMOTE_USER')),
+ 'NAME' => hsc($name),
+ 'MAIL' => '<a href="mailto:"' . hsc($mail) . '">' .
+ hsc($mail) . '</a>'
+ );
+ $signature = $lang['email_signature_text'];
+ if(!empty($lang['email_signature_html'])) {
+ $signature = $lang['email_signature_html'];
+ }
+ $signature = str_replace(
+ array(
+ '@DOKUWIKIURL@',
+ "\n"
+ ),
+ array(
+ $this->replacements['html']['DOKUWIKIURL'],
+ '<br />'
+ ),
+ $signature
+ );
+ $this->replacements['html']['EMAILSIGNATURE'] = $signature;
+ }
+
+ /**
+ * Send the mail
+ *
+ * Call this after all data was set
+ *
+ * @triggers MAIL_MESSAGE_SEND
+ * @return bool true if the mail was successfully passed to the MTA
+ */
+ public function send() {
+ global $lang;
+ $success = false;
+
+ // prepare hook data
+ $data = array(
+ // pass the whole mail class to plugin
+ 'mail' => $this,
+ // pass references for backward compatibility
+ 'to' => &$this->headers['To'],
+ 'cc' => &$this->headers['Cc'],
+ 'bcc' => &$this->headers['Bcc'],
+ 'from' => &$this->headers['From'],
+ 'subject' => &$this->headers['Subject'],
+ 'body' => &$this->text,
+ 'params' => &$this->sendparam,
+ 'headers' => '', // plugins shouldn't use this
+ // signal if we mailed successfully to AFTER event
+ 'success' => &$success,
+ );
+
+ // do our thing if BEFORE hook approves
+ $evt = new Event('MAIL_MESSAGE_SEND', $data);
+ if($evt->advise_before(true)) {
+ // clean up before using the headers
+ $this->cleanHeaders();
+
+ // any recipients?
+ if(trim($this->headers['To']) === '' &&
+ trim($this->headers['Cc']) === '' &&
+ trim($this->headers['Bcc']) === ''
+ ) return false;
+
+ // The To: header is special
+ if(array_key_exists('To', $this->headers)) {
+ $to = (string)$this->headers['To'];
+ unset($this->headers['To']);
+ } else {
+ $to = '';
+ }
+
+ // so is the subject
+ if(array_key_exists('Subject', $this->headers)) {
+ $subject = (string)$this->headers['Subject'];
+ unset($this->headers['Subject']);
+ } else {
+ $subject = '';
+ }
+
+ // make the body
+ $body = $this->prepareBody();
+ if($body === false) return false;
+
+ // cook the headers
+ $headers = $this->prepareHeaders();
+ // add any headers set by legacy plugins
+ if(trim($data['headers'])) {
+ $headers .= MAILHEADER_EOL.trim($data['headers']);
+ }
+
+ if(!function_exists('mail')){
+ $emsg = $lang['email_fail'] . $subject;
+ error_log($emsg);
+ msg(hsc($emsg), -1, __LINE__, __FILE__, MSG_MANAGERS_ONLY);
+ $evt->advise_after();
+ return false;
+ }
+
+ // send the thing
+ if($this->sendparam === null) {
+ $success = @mail($to, $subject, $body, $headers);
+ } else {
+ $success = @mail($to, $subject, $body, $headers, $this->sendparam);
+ }
+ }
+ // any AFTER actions?
+ $evt->advise_after();
+ return $success;
+ }
+}
diff --git a/platform/www/inc/Manifest.php b/platform/www/inc/Manifest.php
new file mode 100644
index 0000000..29e7f26
--- /dev/null
+++ b/platform/www/inc/Manifest.php
@@ -0,0 +1,84 @@
+<?php
+
+namespace dokuwiki;
+
+use dokuwiki\Extension\Event;
+
+class Manifest
+{
+ public function sendManifest()
+ {
+ $manifest = retrieveConfig('manifest', 'jsonToArray');
+
+ global $conf;
+
+ $manifest['scope'] = DOKU_REL;
+
+ if (empty($manifest['name'])) {
+ $manifest['name'] = $conf['title'];
+ }
+
+ if (empty($manifest['short_name'])) {
+ $manifest['short_name'] = $conf['title'];
+ }
+
+ if (empty($manifest['description'])) {
+ $manifest['description'] = $conf['tagline'];
+ }
+
+ if (empty($manifest['start_url'])) {
+ $manifest['start_url'] = DOKU_REL;
+ }
+
+ $styleUtil = new \dokuwiki\StyleUtils();
+ $styleIni = $styleUtil->cssStyleini();
+ $replacements = $styleIni['replacements'];
+
+ if (empty($manifest['background_color'])) {
+ $manifest['background_color'] = $replacements['__background__'];
+ }
+
+ if (empty($manifest['theme_color'])) {
+ $manifest['theme_color'] = !empty($replacements['__theme_color__'])
+ ? $replacements['__theme_color__']
+ : $replacements['__background_alt__'];
+ }
+
+ if (empty($manifest['icons'])) {
+ $manifest['icons'] = [];
+ if (file_exists(mediaFN(':wiki:favicon.ico'))) {
+ $url = ml(':wiki:favicon.ico', '', true, '', true);
+ $manifest['icons'][] = [
+ 'src' => $url,
+ 'sizes' => '16x16',
+ ];
+ }
+
+ $look = [
+ ':wiki:logo.svg',
+ ':logo.svg',
+ ':wiki:dokuwiki.svg'
+ ];
+
+ foreach ($look as $svgLogo) {
+
+ $svgLogoFN = mediaFN($svgLogo);
+
+ if (file_exists($svgLogoFN)) {
+ $url = ml($svgLogo, '', true, '', true);
+ $manifest['icons'][] = [
+ 'src' => $url,
+ 'sizes' => '17x17 512x512',
+ 'type' => 'image/svg+xml',
+ ];
+ break;
+ };
+ }
+ }
+
+ Event::createAndTrigger('MANIFEST_SEND', $manifest);
+
+ header('Content-Type: application/manifest+json');
+ echo json_encode($manifest);
+ }
+}
diff --git a/platform/www/inc/Menu/AbstractMenu.php b/platform/www/inc/Menu/AbstractMenu.php
new file mode 100644
index 0000000..37e5d2c
--- /dev/null
+++ b/platform/www/inc/Menu/AbstractMenu.php
@@ -0,0 +1,96 @@
+<?php
+
+namespace dokuwiki\Menu;
+
+use dokuwiki\Extension\Event;
+use dokuwiki\Menu\Item\AbstractItem;
+
+/**
+ * Class AbstractMenu
+ *
+ * Basic menu functionality. A menu defines a list of AbstractItem that shall be shown.
+ * It contains convenience functions to display the menu in HTML, but template authors can also
+ * just accesst the items via getItems() and create the HTML as however they see fit.
+ */
+abstract class AbstractMenu implements MenuInterface {
+
+ /** @var string[] list of Item classes to load */
+ protected $types = array();
+
+ /** @var int the context this menu is used in */
+ protected $context = AbstractItem::CTX_DESKTOP;
+
+ /** @var string view identifier to be set in the event */
+ protected $view = '';
+
+ /**
+ * AbstractMenu constructor.
+ *
+ * @param int $context the context this menu is used in
+ */
+ public function __construct($context = AbstractItem::CTX_DESKTOP) {
+ $this->context = $context;
+ }
+
+ /**
+ * Get the list of action items in this menu
+ *
+ * @return AbstractItem[]
+ * @triggers MENU_ITEMS_ASSEMBLY
+ */
+ public function getItems() {
+ $data = array(
+ 'view' => $this->view,
+ 'items' => array(),
+ );
+ Event::createAndTrigger('MENU_ITEMS_ASSEMBLY', $data, array($this, 'loadItems'));
+ return $data['items'];
+ }
+
+ /**
+ * Default action for the MENU_ITEMS_ASSEMBLY event
+ *
+ * @see getItems()
+ * @param array $data The plugin data
+ */
+ public function loadItems(&$data) {
+ foreach($this->types as $class) {
+ try {
+ $class = "\\dokuwiki\\Menu\\Item\\$class";
+ /** @var AbstractItem $item */
+ $item = new $class();
+ if(!$item->visibleInContext($this->context)) continue;
+ $data['items'][] = $item;
+ } catch(\RuntimeException $ignored) {
+ // item not available
+ }
+ }
+ }
+
+ /**
+ * Generate HTML list items for this menu
+ *
+ * This is a convenience method for template authors. If you need more fine control over the
+ * output, use getItems() and build the HTML yourself
+ *
+ * @param string|false $classprefix create a class from type with this prefix, false for no class
+ * @param bool $svg add the SVG link
+ * @return string
+ */
+ public function getListItems($classprefix = '', $svg = true) {
+ $html = '';
+ foreach($this->getItems() as $item) {
+ if($classprefix !== false) {
+ $class = ' class="' . $classprefix . $item->getType() . '"';
+ } else {
+ $class = '';
+ }
+
+ $html .= "<li$class>";
+ $html .= $item->asHtmlLink(false, $svg);
+ $html .= '</li>';
+ }
+ return $html;
+ }
+
+}
diff --git a/platform/www/inc/Menu/DetailMenu.php b/platform/www/inc/Menu/DetailMenu.php
new file mode 100644
index 0000000..27c0c6f
--- /dev/null
+++ b/platform/www/inc/Menu/DetailMenu.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace dokuwiki\Menu;
+
+/**
+ * Class DetailMenu
+ *
+ * This menu offers options on an image detail view. It usually displayed similar to
+ * the PageMenu.
+ */
+class DetailMenu extends AbstractMenu {
+
+ protected $view = 'detail';
+
+ protected $types = array(
+ 'MediaManager',
+ 'ImgBackto',
+ 'Top',
+ );
+
+}
diff --git a/platform/www/inc/Menu/Item/AbstractItem.php b/platform/www/inc/Menu/Item/AbstractItem.php
new file mode 100644
index 0000000..c6b04bf
--- /dev/null
+++ b/platform/www/inc/Menu/Item/AbstractItem.php
@@ -0,0 +1,253 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class AbstractItem
+ *
+ * This class defines a single Item to be displayed in one of DokuWiki's menus. Plugins
+ * can extend those menus through action plugins and add their own instances of this class,
+ * overwriting some of its properties.
+ *
+ * Items may be shown multiple times in different contexts. Eg. for the default template
+ * all menus are shown in a Dropdown list on mobile, but are split into several places on
+ * desktop. The item's $context property can be used to hide the item depending on the current
+ * context.
+ *
+ * Children usually just need to overwrite the different properties, but for complex things
+ * the accessors may be overwritten instead.
+ */
+abstract class AbstractItem {
+
+ /** menu item is to be shown on desktop screens only */
+ const CTX_DESKTOP = 1;
+ /** menu item is to be shown on mobile screens only */
+ const CTX_MOBILE = 2;
+ /** menu item is to be shown in all contexts */
+ const CTX_ALL = 3;
+
+ /** @var string name of the action, usually the lowercase class name */
+ protected $type = '';
+ /** @var string optional keyboard shortcut */
+ protected $accesskey = '';
+ /** @var string the page id this action links to */
+ protected $id = '';
+ /** @var string the method to be used when this action is used in a form */
+ protected $method = 'get';
+ /** @var array parameters for the action (should contain the do parameter) */
+ protected $params = array();
+ /** @var bool when true, a rel=nofollow should be used */
+ protected $nofollow = true;
+ /** @var string this item's label may contain a placeholder, which is replaced with this */
+ protected $replacement = '';
+ /** @var string the full path to the SVG icon of this menu item */
+ protected $svg = DOKU_INC . 'lib/images/menu/00-default_checkbox-blank-circle-outline.svg';
+ /** @var string can be set to overwrite the default lookup in $lang.btn_* */
+ protected $label = '';
+ /** @var string the tooltip title, defaults to $label */
+ protected $title = '';
+ /** @var int the context this titme is shown in */
+ protected $context = self::CTX_ALL;
+
+ /**
+ * AbstractItem constructor.
+ *
+ * Sets the dynamic properties
+ *
+ * Children should always call the parent constructor!
+ *
+ * @throws \RuntimeException when the action is disabled
+ */
+ public function __construct() {
+ global $ID;
+ $this->id = $ID;
+ $this->type = $this->getType();
+ $this->params['do'] = $this->type;
+
+ if(!actionOK($this->type)) throw new \RuntimeException("action disabled: {$this->type}");
+ }
+
+ /**
+ * Return this item's label
+ *
+ * When the label property was set, it is simply returned. Otherwise, the action's type
+ * is used to look up the translation in the main language file and, if used, the replacement
+ * is applied.
+ *
+ * @return string
+ */
+ public function getLabel() {
+ if($this->label !== '') return $this->label;
+
+ /** @var array $lang */
+ global $lang;
+ $label = $lang['btn_' . $this->type];
+ if(strpos($label, '%s')) {
+ $label = sprintf($label, $this->replacement);
+ }
+ if($label === '') $label = '[' . $this->type . ']';
+ return $label;
+ }
+
+ /**
+ * Return this item's title
+ *
+ * This title should be used to display a tooltip (using the HTML title attribute). If
+ * a title property was not explicitly set, the label will be returned.
+ *
+ * @return string
+ */
+ public function getTitle() {
+ if($this->title === '') return $this->getLabel();
+ return $this->title;
+ }
+
+ /**
+ * Return the link this item links to
+ *
+ * Basically runs wl() on $id and $params. However if the ID is a hash it is used directly
+ * as the link
+ *
+ * Please note that the generated URL is *not* XML escaped.
+ *
+ * @see wl()
+ * @return string
+ */
+ public function getLink() {
+ if($this->id && $this->id[0] == '#') {
+ return $this->id;
+ } else {
+ return wl($this->id, $this->params, false, '&');
+ }
+ }
+
+ /**
+ * Convenience method to get the attributes for constructing an <a> element
+ *
+ * @see buildAttributes()
+ * @param string|false $classprefix create a class from type with this prefix, false for no class
+ * @return array
+ */
+ public function getLinkAttributes($classprefix = 'menuitem ') {
+ $attr = array(
+ 'href' => $this->getLink(),
+ 'title' => $this->getTitle(),
+ );
+ if($this->isNofollow()) $attr['rel'] = 'nofollow';
+ if($this->getAccesskey()) {
+ $attr['accesskey'] = $this->getAccesskey();
+ $attr['title'] .= ' [' . $this->getAccesskey() . ']';
+ }
+ if($classprefix !== false) $attr['class'] = $classprefix . $this->getType();
+
+ return $attr;
+ }
+
+ /**
+ * Convenience method to create a full <a> element
+ *
+ * Wraps around the label and SVG image
+ *
+ * @param string|false $classprefix create a class from type with this prefix, false for no class
+ * @param bool $svg add SVG icon to the link
+ * @return string
+ */
+ public function asHtmlLink($classprefix = 'menuitem ', $svg = true) {
+ $attr = buildAttributes($this->getLinkAttributes($classprefix));
+ $html = "<a $attr>";
+ if($svg) {
+ $html .= '<span>' . hsc($this->getLabel()) . '</span>';
+ $html .= inlineSVG($this->getSvg());
+ } else {
+ $html .= hsc($this->getLabel());
+ }
+ $html .= "</a>";
+
+ return $html;
+ }
+
+ /**
+ * Convenience method to create a <button> element inside it's own form element
+ *
+ * Uses html_btn()
+ *
+ * @return string
+ */
+ public function asHtmlButton() {
+ return html_btn(
+ $this->getType(),
+ $this->id,
+ $this->getAccesskey(),
+ $this->getParams(),
+ $this->method,
+ $this->getTitle(),
+ $this->getLabel(),
+ $this->getSvg()
+ );
+ }
+
+ /**
+ * Should this item be shown in the given context
+ *
+ * @param int $ctx the current context
+ * @return bool
+ */
+ public function visibleInContext($ctx) {
+ return (bool) ($ctx & $this->context);
+ }
+
+ /**
+ * @return string the name of this item
+ */
+ public function getType() {
+ if($this->type === '') {
+ $this->type = strtolower(substr(strrchr(get_class($this), '\\'), 1));
+ }
+ return $this->type;
+ }
+
+ /**
+ * @return string
+ */
+ public function getAccesskey() {
+ return $this->accesskey;
+ }
+
+ /**
+ * @return array
+ */
+ public function getParams() {
+ return $this->params;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isNofollow() {
+ return $this->nofollow;
+ }
+
+ /**
+ * @return string
+ */
+ public function getSvg() {
+ return $this->svg;
+ }
+
+ /**
+ * Return this Item's settings as an array as used in tpl_get_action()
+ *
+ * @return array
+ */
+ public function getLegacyData() {
+ return array(
+ 'accesskey' => $this->accesskey ?: null,
+ 'type' => $this->type,
+ 'id' => $this->id,
+ 'method' => $this->method,
+ 'params' => $this->params,
+ 'nofollow' => $this->nofollow,
+ 'replacement' => $this->replacement
+ );
+ }
+}
diff --git a/platform/www/inc/Menu/Item/Admin.php b/platform/www/inc/Menu/Item/Admin.php
new file mode 100644
index 0000000..e5506c2
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Admin.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Admin
+ *
+ * Opens the Admin screen. Only shown to managers or above
+ */
+class Admin extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ parent::__construct();
+
+ $this->svg = DOKU_INC . 'lib/images/menu/settings.svg';
+ }
+
+ /** @inheritdoc */
+ public function visibleInContext($ctx)
+ {
+ global $INFO;
+ if(!$INFO['ismanager']) return false;
+
+ return parent::visibleInContext($ctx);
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Back.php b/platform/www/inc/Menu/Item/Back.php
new file mode 100644
index 0000000..a7cc1d9
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Back.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Back
+ *
+ * Navigates back up one namepspace. This is currently not used in any menu. Templates
+ * would need to add this item manually.
+ */
+class Back extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $ID;
+ parent::__construct();
+
+ $parent = tpl_getparent($ID);
+ if(!$parent) {
+ throw new \RuntimeException("No parent for back action");
+ }
+
+ $this->id = $parent;
+ $this->params = array('do' => '');
+ $this->accesskey = 'b';
+ $this->svg = DOKU_INC . 'lib/images/menu/12-back_arrow-left.svg';
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Backlink.php b/platform/www/inc/Menu/Item/Backlink.php
new file mode 100644
index 0000000..6dc242b
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Backlink.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Backlink
+ *
+ * Shows the backlinks for the current page
+ */
+class Backlink extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ parent::__construct();
+ $this->svg = DOKU_INC . 'lib/images/menu/08-backlink_link-variant.svg';
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Edit.php b/platform/www/inc/Menu/Item/Edit.php
new file mode 100644
index 0000000..15d9543
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Edit.php
@@ -0,0 +1,65 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Edit
+ *
+ * Most complex item. Shows the edit button but mutates to show, draft and create based on
+ * current state.
+ */
+class Edit extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $ACT;
+ global $INFO;
+ global $REV;
+
+ parent::__construct();
+
+ if($ACT === 'show') {
+ $this->method = 'post';
+ if($INFO['writable']) {
+ $this->accesskey = 'e';
+ if(!empty($INFO['draft'])) {
+ $this->type = 'draft';
+ $this->params['do'] = 'draft';
+ } else {
+ $this->params['rev'] = $REV;
+ if(!$INFO['exists']) {
+ $this->type = 'create';
+ }
+ }
+ } else {
+ if(!actionOK("source")) throw new \RuntimeException("action disabled: source");
+ $params['rev'] = $REV;
+ $this->type = 'source';
+ $this->accesskey = 'v';
+ }
+ } else {
+ $this->params = array('do' => '');
+ $this->type = 'show';
+ $this->accesskey = 'v';
+ }
+
+ $this->setIcon();
+ }
+
+ /**
+ * change the icon according to what type the edit button has
+ */
+ protected function setIcon() {
+ $icons = array(
+ 'edit' => '01-edit_pencil.svg',
+ 'create' => '02-create_pencil.svg',
+ 'draft' => '03-draft_android-studio.svg',
+ 'show' => '04-show_file-document.svg',
+ 'source' => '05-source_file-xml.svg',
+ );
+ if(isset($icons[$this->type])) {
+ $this->svg = DOKU_INC . 'lib/images/menu/' . $icons[$this->type];
+ }
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/ImgBackto.php b/platform/www/inc/Menu/Item/ImgBackto.php
new file mode 100644
index 0000000..72820a5
--- /dev/null
+++ b/platform/www/inc/Menu/Item/ImgBackto.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class ImgBackto
+ *
+ * Links back to the originating page from a detail image view
+ */
+class ImgBackto extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $ID;
+ parent::__construct();
+
+ $this->svg = DOKU_INC . 'lib/images/menu/12-back_arrow-left.svg';
+ $this->type = 'img_backto';
+ $this->params = array();
+ $this->accesskey = 'b';
+ $this->replacement = $ID;
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Index.php b/platform/www/inc/Menu/Item/Index.php
new file mode 100644
index 0000000..4132673
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Index.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Index
+ *
+ * Shows the sitemap
+ */
+class Index extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $conf;
+ global $ID;
+ parent::__construct();
+
+ $this->accesskey = 'x';
+ $this->svg = DOKU_INC . 'lib/images/menu/file-tree.svg';
+
+ // allow searchbots to get to the sitemap from the homepage (when dokuwiki isn't providing a sitemap.xml)
+ if($conf['start'] == $ID && !$conf['sitemap']) {
+ $this->nofollow = false;
+ }
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Login.php b/platform/www/inc/Menu/Item/Login.php
new file mode 100644
index 0000000..671f6a7
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Login.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Login
+ *
+ * Show a login or logout item, based on the current state
+ */
+class Login extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $INPUT;
+ parent::__construct();
+
+ $this->svg = DOKU_INC . 'lib/images/menu/login.svg';
+ $this->params['sectok'] = getSecurityToken();
+ if($INPUT->server->has('REMOTE_USER')) {
+ if(!actionOK('logout')) {
+ throw new \RuntimeException("logout disabled");
+ }
+ $this->params['do'] = 'logout';
+ $this->type = 'logout';
+ $this->svg = DOKU_INC . 'lib/images/menu/logout.svg';
+ }
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Media.php b/platform/www/inc/Menu/Item/Media.php
new file mode 100644
index 0000000..0e5f47b
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Media.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Media
+ *
+ * Opens the media manager
+ */
+class Media extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $ID;
+ parent::__construct();
+
+ $this->svg = DOKU_INC . 'lib/images/menu/folder-multiple-image.svg';
+ $this->params['ns'] = getNS($ID);
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/MediaManager.php b/platform/www/inc/Menu/Item/MediaManager.php
new file mode 100644
index 0000000..8549d20
--- /dev/null
+++ b/platform/www/inc/Menu/Item/MediaManager.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class MediaManager
+ *
+ * Opens the current image in the media manager. Used on image detail view.
+ */
+class MediaManager extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $IMG;
+ parent::__construct();
+
+ $imgNS = getNS($IMG);
+ $authNS = auth_quickaclcheck("$imgNS:*");
+ if($authNS < AUTH_UPLOAD) {
+ throw new \RuntimeException("media manager link only with upload permissions");
+ }
+
+ $this->svg = DOKU_INC . 'lib/images/menu/11-mediamanager_folder-image.svg';
+ $this->type = 'mediaManager';
+ $this->params = array(
+ 'ns' => $imgNS,
+ 'image' => $IMG,
+ 'do' => 'media'
+ );
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Profile.php b/platform/www/inc/Menu/Item/Profile.php
new file mode 100644
index 0000000..2b4ceeb
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Profile.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Profile
+ *
+ * Open the user's profile
+ */
+class Profile extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $INPUT;
+ parent::__construct();
+
+ if(!$INPUT->server->str('REMOTE_USER')) {
+ throw new \RuntimeException("profile is only for logged in users");
+ }
+
+ $this->svg = DOKU_INC . 'lib/images/menu/account-card-details.svg';
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Recent.php b/platform/www/inc/Menu/Item/Recent.php
new file mode 100644
index 0000000..ff90ce6
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Recent.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Recent
+ *
+ * Show the site wide recent changes
+ */
+class Recent extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ parent::__construct();
+
+ $this->accesskey = 'r';
+ $this->svg = DOKU_INC . 'lib/images/menu/calendar-clock.svg';
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Register.php b/platform/www/inc/Menu/Item/Register.php
new file mode 100644
index 0000000..615146e
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Register.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Register
+ *
+ * Open the view to register a new account
+ */
+class Register extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $INPUT;
+ parent::__construct();
+
+ if($INPUT->server->str('REMOTE_USER')) {
+ throw new \RuntimeException("no register when already logged in");
+ }
+
+ $this->svg = DOKU_INC . 'lib/images/menu/account-plus.svg';
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Resendpwd.php b/platform/www/inc/Menu/Item/Resendpwd.php
new file mode 100644
index 0000000..7ddc6b0
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Resendpwd.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Resendpwd
+ *
+ * Access the "forgot password" dialog
+ */
+class Resendpwd extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $INPUT;
+ parent::__construct();
+
+ if($INPUT->server->str('REMOTE_USER')) {
+ throw new \RuntimeException("no resendpwd when already logged in");
+ }
+
+ $this->svg = DOKU_INC . 'lib/images/menu/lock-reset.svg';
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Revert.php b/platform/www/inc/Menu/Item/Revert.php
new file mode 100644
index 0000000..7d57df0
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Revert.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Revert
+ *
+ * Quick revert to the currently shown page revision
+ */
+class Revert extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $REV;
+ global $INFO;
+ parent::__construct();
+
+ if(!$REV || !$INFO['writable']) {
+ throw new \RuntimeException('revert not available');
+ }
+ $this->params['rev'] = $REV;
+ $this->params['sectok'] = getSecurityToken();
+ $this->svg = DOKU_INC . 'lib/images/menu/06-revert_replay.svg';
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Revisions.php b/platform/www/inc/Menu/Item/Revisions.php
new file mode 100644
index 0000000..3009a79
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Revisions.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Revisions
+ *
+ * Access the old revisions of the current page
+ */
+class Revisions extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ parent::__construct();
+
+ $this->accesskey = 'o';
+ $this->type = 'revs';
+ $this->svg = DOKU_INC . 'lib/images/menu/07-revisions_history.svg';
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Subscribe.php b/platform/www/inc/Menu/Item/Subscribe.php
new file mode 100644
index 0000000..1c9d335
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Subscribe.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Subscribe
+ *
+ * Access the subscription management view
+ */
+class Subscribe extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ global $INPUT;
+ parent::__construct();
+
+ if(!$INPUT->server->str('REMOTE_USER')) {
+ throw new \RuntimeException("subscribe is only for logged in users");
+ }
+
+ $this->svg = DOKU_INC . 'lib/images/menu/09-subscribe_email-outline.svg';
+ }
+
+}
diff --git a/platform/www/inc/Menu/Item/Top.php b/platform/www/inc/Menu/Item/Top.php
new file mode 100644
index 0000000..a05c4f1
--- /dev/null
+++ b/platform/www/inc/Menu/Item/Top.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace dokuwiki\Menu\Item;
+
+/**
+ * Class Top
+ *
+ * Scroll back to the top. Uses a hash as $id which is handled special in getLink().
+ * Not shown in mobile context
+ */
+class Top extends AbstractItem {
+
+ /** @inheritdoc */
+ public function __construct() {
+ parent::__construct();
+
+ $this->svg = DOKU_INC . 'lib/images/menu/10-top_arrow-up.svg';
+ $this->accesskey = 't';
+ $this->params = array('do' => '');
+ $this->id = '#dokuwiki__top';
+ $this->context = self::CTX_DESKTOP;
+ }
+
+ /**
+ * Convenience method to create a <button> element
+ *
+ * Uses html_topbtn()
+ *
+ * @todo this does currently not support the SVG icon
+ * @return string
+ */
+ public function asHtmlButton() {
+ return html_topbtn();
+ }
+
+}
diff --git a/platform/www/inc/Menu/MenuInterface.php b/platform/www/inc/Menu/MenuInterface.php
new file mode 100644
index 0000000..91dde9d
--- /dev/null
+++ b/platform/www/inc/Menu/MenuInterface.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace dokuwiki\Menu;
+
+use dokuwiki\Menu\Item\AbstractItem;
+
+/**
+ * Interface MenuInterface
+ *
+ * Defines what a Menu provides
+ */
+Interface MenuInterface {
+
+ /**
+ * Get the list of action items in this menu
+ *
+ * @return AbstractItem[]
+ */
+ public function getItems();
+}
diff --git a/platform/www/inc/Menu/MobileMenu.php b/platform/www/inc/Menu/MobileMenu.php
new file mode 100644
index 0000000..2098056
--- /dev/null
+++ b/platform/www/inc/Menu/MobileMenu.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace dokuwiki\Menu;
+
+use dokuwiki\Menu\Item\AbstractItem;
+
+/**
+ * Class MobileMenu
+ *
+ * Note: this does not inherit from AbstractMenu because it is not working like the other
+ * menus. This is a meta menu, aggregating the items from the other menus and offering a combined
+ * view. The idea is to use this on mobile devices, thus the context is fixed to CTX_MOBILE
+ */
+class MobileMenu implements MenuInterface {
+
+ /**
+ * Returns all items grouped by view
+ *
+ * @return AbstractItem[][]
+ */
+ public function getGroupedItems() {
+ $pagemenu = new PageMenu(AbstractItem::CTX_MOBILE);
+ $sitemenu = new SiteMenu(AbstractItem::CTX_MOBILE);
+ $usermenu = new UserMenu(AbstractItem::CTX_MOBILE);
+
+ return array(
+ 'page' => $pagemenu->getItems(),
+ 'site' => $sitemenu->getItems(),
+ 'user' => $usermenu->getItems()
+ );
+ }
+
+ /**
+ * Get all items in a flat array
+ *
+ * This returns the same format as AbstractMenu::getItems()
+ *
+ * @return AbstractItem[]
+ */
+ public function getItems() {
+ $menu = $this->getGroupedItems();
+ return call_user_func_array('array_merge', array_values($menu));
+ }
+
+ /**
+ * Print a dropdown menu with all DokuWiki actions
+ *
+ * Note: this will not use any pretty URLs
+ *
+ * @param string $empty empty option label
+ * @param string $button submit button label
+ * @return string
+ */
+ public function getDropdown($empty = '', $button = '&gt;') {
+ global $ID;
+ global $REV;
+ /** @var string[] $lang */
+ global $lang;
+ global $INPUT;
+
+ $html = '<form action="' . script() . '" method="get" accept-charset="utf-8">';
+ $html .= '<div class="no">';
+ $html .= '<input type="hidden" name="id" value="' . $ID . '" />';
+ if($REV) $html .= '<input type="hidden" name="rev" value="' . $REV . '" />';
+ if($INPUT->server->str('REMOTE_USER')) {
+ $html .= '<input type="hidden" name="sectok" value="' . getSecurityToken() . '" />';
+ }
+
+ $html .= '<select name="do" class="edit quickselect" title="' . $lang['tools'] . '">';
+ $html .= '<option value="">' . $empty . '</option>';
+
+ foreach($this->getGroupedItems() as $tools => $items) {
+ if (count($items)) {
+ $html .= '<optgroup label="' . $lang[$tools . '_tools'] . '">';
+ foreach($items as $item) {
+ $params = $item->getParams();
+ $html .= '<option value="' . $params['do'] . '">';
+ $html .= hsc($item->getLabel());
+ $html .= '</option>';
+ }
+ $html .= '</optgroup>';
+ }
+ }
+
+ $html .= '</select>';
+ $html .= '<button type="submit">' . $button . '</button>';
+ $html .= '</div>';
+ $html .= '</form>';
+
+ return $html;
+ }
+
+}
diff --git a/platform/www/inc/Menu/PageMenu.php b/platform/www/inc/Menu/PageMenu.php
new file mode 100644
index 0000000..9c0a55e
--- /dev/null
+++ b/platform/www/inc/Menu/PageMenu.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace dokuwiki\Menu;
+
+/**
+ * Class PageMenu
+ *
+ * Actions manipulating the current page. Shown as a floating menu in the dokuwiki template
+ */
+class PageMenu extends AbstractMenu {
+
+ protected $view = 'page';
+
+ protected $types = array(
+ 'Edit',
+ 'Revert',
+ 'Revisions',
+ 'Backlink',
+ 'Subscribe',
+ 'Top',
+ );
+
+}
diff --git a/platform/www/inc/Menu/SiteMenu.php b/platform/www/inc/Menu/SiteMenu.php
new file mode 100644
index 0000000..dba6888
--- /dev/null
+++ b/platform/www/inc/Menu/SiteMenu.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace dokuwiki\Menu;
+
+/**
+ * Class SiteMenu
+ *
+ * Actions that are not bound to an individual page but provide toolsfor the whole wiki.
+ */
+class SiteMenu extends AbstractMenu {
+
+ protected $view = 'site';
+
+ protected $types = array(
+ 'Recent',
+ 'Media',
+ 'Index'
+ );
+
+}
diff --git a/platform/www/inc/Menu/UserMenu.php b/platform/www/inc/Menu/UserMenu.php
new file mode 100644
index 0000000..01028d3
--- /dev/null
+++ b/platform/www/inc/Menu/UserMenu.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace dokuwiki\Menu;
+
+/**
+ * Class UserMenu
+ *
+ * Actions related to the current user
+ */
+class UserMenu extends AbstractMenu {
+
+ protected $view = 'user';
+
+ protected $types = array(
+ 'Profile',
+ 'Admin',
+ 'Register',
+ 'Login',
+ );
+
+}
diff --git a/platform/www/inc/Parsing/Handler/AbstractRewriter.php b/platform/www/inc/Parsing/Handler/AbstractRewriter.php
new file mode 100644
index 0000000..d9becbf
--- /dev/null
+++ b/platform/www/inc/Parsing/Handler/AbstractRewriter.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace dokuwiki\Parsing\Handler;
+
+/**
+ * Basic implementation of the rewriter interface to be specialized by children
+ */
+abstract class AbstractRewriter implements ReWriterInterface
+{
+ /** @var CallWriterInterface original CallWriter */
+ protected $callWriter;
+
+ /** @var array[] list of calls */
+ public $calls = array();
+
+ /** @inheritdoc */
+ public function __construct(CallWriterInterface $callWriter)
+ {
+ $this->callWriter = $callWriter;
+ }
+
+ /** @inheritdoc */
+ public function writeCall($call)
+ {
+ $this->calls[] = $call;
+ }
+
+ /** * @inheritdoc */
+ public function writeCalls($calls)
+ {
+ $this->calls = array_merge($this->calls, $calls);
+ }
+
+ /** @inheritDoc */
+ public function getCallWriter()
+ {
+ return $this->callWriter;
+ }
+}
diff --git a/platform/www/inc/Parsing/Handler/Block.php b/platform/www/inc/Parsing/Handler/Block.php
new file mode 100644
index 0000000..4cfa686
--- /dev/null
+++ b/platform/www/inc/Parsing/Handler/Block.php
@@ -0,0 +1,211 @@
+<?php
+
+namespace dokuwiki\Parsing\Handler;
+
+/**
+ * Handler for paragraphs
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+class Block
+{
+ protected $calls = array();
+ protected $skipEol = false;
+ protected $inParagraph = false;
+
+ // Blocks these should not be inside paragraphs
+ protected $blockOpen = array(
+ 'header',
+ 'listu_open','listo_open','listitem_open','listcontent_open',
+ 'table_open','tablerow_open','tablecell_open','tableheader_open','tablethead_open',
+ 'quote_open',
+ 'code','file','hr','preformatted','rss',
+ 'htmlblock','phpblock',
+ 'footnote_open',
+ );
+
+ protected $blockClose = array(
+ 'header',
+ 'listu_close','listo_close','listitem_close','listcontent_close',
+ 'table_close','tablerow_close','tablecell_close','tableheader_close','tablethead_close',
+ 'quote_close',
+ 'code','file','hr','preformatted','rss',
+ 'htmlblock','phpblock',
+ 'footnote_close',
+ );
+
+ // Stacks can contain paragraphs
+ protected $stackOpen = array(
+ 'section_open',
+ );
+
+ protected $stackClose = array(
+ 'section_close',
+ );
+
+
+ /**
+ * Constructor. Adds loaded syntax plugins to the block and stack
+ * arrays
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function __construct()
+ {
+ global $DOKU_PLUGINS;
+ //check if syntax plugins were loaded
+ if (empty($DOKU_PLUGINS['syntax'])) return;
+ foreach ($DOKU_PLUGINS['syntax'] as $n => $p) {
+ $ptype = $p->getPType();
+ if ($ptype == 'block') {
+ $this->blockOpen[] = 'plugin_'.$n;
+ $this->blockClose[] = 'plugin_'.$n;
+ } elseif ($ptype == 'stack') {
+ $this->stackOpen[] = 'plugin_'.$n;
+ $this->stackClose[] = 'plugin_'.$n;
+ }
+ }
+ }
+
+ protected function openParagraph($pos)
+ {
+ if ($this->inParagraph) return;
+ $this->calls[] = array('p_open',array(), $pos);
+ $this->inParagraph = true;
+ $this->skipEol = true;
+ }
+
+ /**
+ * Close a paragraph if needed
+ *
+ * This function makes sure there are no empty paragraphs on the stack
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string|integer $pos
+ */
+ protected function closeParagraph($pos)
+ {
+ if (!$this->inParagraph) return;
+ // look back if there was any content - we don't want empty paragraphs
+ $content = '';
+ $ccount = count($this->calls);
+ for ($i=$ccount-1; $i>=0; $i--) {
+ if ($this->calls[$i][0] == 'p_open') {
+ break;
+ } elseif ($this->calls[$i][0] == 'cdata') {
+ $content .= $this->calls[$i][1][0];
+ } else {
+ $content = 'found markup';
+ break;
+ }
+ }
+
+ if (trim($content)=='') {
+ //remove the whole paragraph
+ //array_splice($this->calls,$i); // <- this is much slower than the loop below
+ for ($x=$ccount; $x>$i;
+ $x--) array_pop($this->calls);
+ } else {
+ // remove ending linebreaks in the paragraph
+ $i=count($this->calls)-1;
+ if ($this->calls[$i][0] == 'cdata') $this->calls[$i][1][0] = rtrim($this->calls[$i][1][0], "\n");
+ $this->calls[] = array('p_close',array(), $pos);
+ }
+
+ $this->inParagraph = false;
+ $this->skipEol = true;
+ }
+
+ protected function addCall($call)
+ {
+ $key = count($this->calls);
+ if ($key and ($call[0] == 'cdata') and ($this->calls[$key-1][0] == 'cdata')) {
+ $this->calls[$key-1][1][0] .= $call[1][0];
+ } else {
+ $this->calls[] = $call;
+ }
+ }
+
+ // simple version of addCall, without checking cdata
+ protected function storeCall($call)
+ {
+ $this->calls[] = $call;
+ }
+
+ /**
+ * Processes the whole instruction stack to open and close paragraphs
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $calls
+ *
+ * @return array
+ */
+ public function process($calls)
+ {
+ // open first paragraph
+ $this->openParagraph(0);
+ foreach ($calls as $key => $call) {
+ $cname = $call[0];
+ if ($cname == 'plugin') {
+ $cname='plugin_'.$call[1][0];
+ $plugin = true;
+ $plugin_open = (($call[1][2] == DOKU_LEXER_ENTER) || ($call[1][2] == DOKU_LEXER_SPECIAL));
+ $plugin_close = (($call[1][2] == DOKU_LEXER_EXIT) || ($call[1][2] == DOKU_LEXER_SPECIAL));
+ } else {
+ $plugin = false;
+ }
+ /* stack */
+ if (in_array($cname, $this->stackClose) && (!$plugin || $plugin_close)) {
+ $this->closeParagraph($call[2]);
+ $this->storeCall($call);
+ $this->openParagraph($call[2]);
+ continue;
+ }
+ if (in_array($cname, $this->stackOpen) && (!$plugin || $plugin_open)) {
+ $this->closeParagraph($call[2]);
+ $this->storeCall($call);
+ $this->openParagraph($call[2]);
+ continue;
+ }
+ /* block */
+ // If it's a substition it opens and closes at the same call.
+ // To make sure next paragraph is correctly started, let close go first.
+ if (in_array($cname, $this->blockClose) && (!$plugin || $plugin_close)) {
+ $this->closeParagraph($call[2]);
+ $this->storeCall($call);
+ $this->openParagraph($call[2]);
+ continue;
+ }
+ if (in_array($cname, $this->blockOpen) && (!$plugin || $plugin_open)) {
+ $this->closeParagraph($call[2]);
+ $this->storeCall($call);
+ continue;
+ }
+ /* eol */
+ if ($cname == 'eol') {
+ // Check this isn't an eol instruction to skip...
+ if (!$this->skipEol) {
+ // Next is EOL => double eol => mark as paragraph
+ if (isset($calls[$key+1]) && $calls[$key+1][0] == 'eol') {
+ $this->closeParagraph($call[2]);
+ $this->openParagraph($call[2]);
+ } else {
+ //if this is just a single eol make a space from it
+ $this->addCall(array('cdata',array("\n"), $call[2]));
+ }
+ }
+ continue;
+ }
+ /* normal */
+ $this->addCall($call);
+ $this->skipEol = false;
+ }
+ // close last paragraph
+ $call = end($this->calls);
+ $this->closeParagraph($call[2]);
+ return $this->calls;
+ }
+}
diff --git a/platform/www/inc/Parsing/Handler/CallWriter.php b/platform/www/inc/Parsing/Handler/CallWriter.php
new file mode 100644
index 0000000..2457143
--- /dev/null
+++ b/platform/www/inc/Parsing/Handler/CallWriter.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace dokuwiki\Parsing\Handler;
+
+class CallWriter implements CallWriterInterface
+{
+
+ /** @var \Doku_Handler $Handler */
+ protected $Handler;
+
+ /**
+ * @param \Doku_Handler $Handler
+ */
+ public function __construct(\Doku_Handler $Handler)
+ {
+ $this->Handler = $Handler;
+ }
+
+ /** @inheritdoc */
+ public function writeCall($call)
+ {
+ $this->Handler->calls[] = $call;
+ }
+
+ /** @inheritdoc */
+ public function writeCalls($calls)
+ {
+ $this->Handler->calls = array_merge($this->Handler->calls, $calls);
+ }
+
+ /**
+ * @inheritdoc
+ * function is required, but since this call writer is first/highest in
+ * the chain it is not required to do anything
+ */
+ public function finalise()
+ {
+ unset($this->Handler);
+ }
+}
diff --git a/platform/www/inc/Parsing/Handler/CallWriterInterface.php b/platform/www/inc/Parsing/Handler/CallWriterInterface.php
new file mode 100644
index 0000000..ffc2468
--- /dev/null
+++ b/platform/www/inc/Parsing/Handler/CallWriterInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace dokuwiki\Parsing\Handler;
+
+interface CallWriterInterface
+{
+ /**
+ * Add a call to our call list
+ *
+ * @param array $call the call to be added
+ */
+ public function writeCall($call);
+
+ /**
+ * Append a list of calls to our call list
+ *
+ * @param array[] $calls list of calls to be appended
+ */
+ public function writeCalls($calls);
+
+ /**
+ * Explicit request to finish up and clean up NOW!
+ * (probably because document end has been reached)
+ *
+ * If part of a CallWriter chain, call finalise on
+ * the original call writer
+ *
+ */
+ public function finalise();
+}
diff --git a/platform/www/inc/Parsing/Handler/Lists.php b/platform/www/inc/Parsing/Handler/Lists.php
new file mode 100644
index 0000000..282ddfb
--- /dev/null
+++ b/platform/www/inc/Parsing/Handler/Lists.php
@@ -0,0 +1,186 @@
+<?php
+
+namespace dokuwiki\Parsing\Handler;
+
+class Lists extends AbstractRewriter
+{
+ protected $listCalls = array();
+ protected $listStack = array();
+
+ protected $initialDepth = 0;
+
+ const NODE = 1;
+
+ /** @inheritdoc */
+ public function finalise()
+ {
+ $last_call = end($this->calls);
+ $this->writeCall(array('list_close',array(), $last_call[2]));
+
+ $this->process();
+ $this->callWriter->finalise();
+ unset($this->callWriter);
+ }
+
+ /** @inheritdoc */
+ public function process()
+ {
+
+ foreach ($this->calls as $call) {
+ switch ($call[0]) {
+ case 'list_item':
+ $this->listOpen($call);
+ break;
+ case 'list_open':
+ $this->listStart($call);
+ break;
+ case 'list_close':
+ $this->listEnd($call);
+ break;
+ default:
+ $this->listContent($call);
+ break;
+ }
+ }
+
+ $this->callWriter->writeCalls($this->listCalls);
+ return $this->callWriter;
+ }
+
+ protected function listStart($call)
+ {
+ $depth = $this->interpretSyntax($call[1][0], $listType);
+
+ $this->initialDepth = $depth;
+ // array(list type, current depth, index of current listitem_open)
+ $this->listStack[] = array($listType, $depth, 1);
+
+ $this->listCalls[] = array('list'.$listType.'_open',array(),$call[2]);
+ $this->listCalls[] = array('listitem_open',array(1),$call[2]);
+ $this->listCalls[] = array('listcontent_open',array(),$call[2]);
+ }
+
+
+ protected function listEnd($call)
+ {
+ $closeContent = true;
+
+ while ($list = array_pop($this->listStack)) {
+ if ($closeContent) {
+ $this->listCalls[] = array('listcontent_close',array(),$call[2]);
+ $closeContent = false;
+ }
+ $this->listCalls[] = array('listitem_close',array(),$call[2]);
+ $this->listCalls[] = array('list'.$list[0].'_close', array(), $call[2]);
+ }
+ }
+
+ protected function listOpen($call)
+ {
+ $depth = $this->interpretSyntax($call[1][0], $listType);
+ $end = end($this->listStack);
+ $key = key($this->listStack);
+
+ // Not allowed to be shallower than initialDepth
+ if ($depth < $this->initialDepth) {
+ $depth = $this->initialDepth;
+ }
+
+ if ($depth == $end[1]) {
+ // Just another item in the list...
+ if ($listType == $end[0]) {
+ $this->listCalls[] = array('listcontent_close',array(),$call[2]);
+ $this->listCalls[] = array('listitem_close',array(),$call[2]);
+ $this->listCalls[] = array('listitem_open',array($depth-1),$call[2]);
+ $this->listCalls[] = array('listcontent_open',array(),$call[2]);
+
+ // new list item, update list stack's index into current listitem_open
+ $this->listStack[$key][2] = count($this->listCalls) - 2;
+
+ // Switched list type...
+ } else {
+ $this->listCalls[] = array('listcontent_close',array(),$call[2]);
+ $this->listCalls[] = array('listitem_close',array(),$call[2]);
+ $this->listCalls[] = array('list'.$end[0].'_close', array(), $call[2]);
+ $this->listCalls[] = array('list'.$listType.'_open', array(), $call[2]);
+ $this->listCalls[] = array('listitem_open', array($depth-1), $call[2]);
+ $this->listCalls[] = array('listcontent_open',array(),$call[2]);
+
+ array_pop($this->listStack);
+ $this->listStack[] = array($listType, $depth, count($this->listCalls) - 2);
+ }
+ } elseif ($depth > $end[1]) { // Getting deeper...
+ $this->listCalls[] = array('listcontent_close',array(),$call[2]);
+ $this->listCalls[] = array('list'.$listType.'_open', array(), $call[2]);
+ $this->listCalls[] = array('listitem_open', array($depth-1), $call[2]);
+ $this->listCalls[] = array('listcontent_open',array(),$call[2]);
+
+ // set the node/leaf state of this item's parent listitem_open to NODE
+ $this->listCalls[$this->listStack[$key][2]][1][1] = self::NODE;
+
+ $this->listStack[] = array($listType, $depth, count($this->listCalls) - 2);
+ } else { // Getting shallower ( $depth < $end[1] )
+ $this->listCalls[] = array('listcontent_close',array(),$call[2]);
+ $this->listCalls[] = array('listitem_close',array(),$call[2]);
+ $this->listCalls[] = array('list'.$end[0].'_close',array(),$call[2]);
+
+ // Throw away the end - done
+ array_pop($this->listStack);
+
+ while (1) {
+ $end = end($this->listStack);
+ $key = key($this->listStack);
+
+ if ($end[1] <= $depth) {
+ // Normalize depths
+ $depth = $end[1];
+
+ $this->listCalls[] = array('listitem_close',array(),$call[2]);
+
+ if ($end[0] == $listType) {
+ $this->listCalls[] = array('listitem_open',array($depth-1),$call[2]);
+ $this->listCalls[] = array('listcontent_open',array(),$call[2]);
+
+ // new list item, update list stack's index into current listitem_open
+ $this->listStack[$key][2] = count($this->listCalls) - 2;
+ } else {
+ // Switching list type...
+ $this->listCalls[] = array('list'.$end[0].'_close', array(), $call[2]);
+ $this->listCalls[] = array('list'.$listType.'_open', array(), $call[2]);
+ $this->listCalls[] = array('listitem_open', array($depth-1), $call[2]);
+ $this->listCalls[] = array('listcontent_open',array(),$call[2]);
+
+ array_pop($this->listStack);
+ $this->listStack[] = array($listType, $depth, count($this->listCalls) - 2);
+ }
+
+ break;
+
+ // Haven't dropped down far enough yet.... ( $end[1] > $depth )
+ } else {
+ $this->listCalls[] = array('listitem_close',array(),$call[2]);
+ $this->listCalls[] = array('list'.$end[0].'_close',array(),$call[2]);
+
+ array_pop($this->listStack);
+ }
+ }
+ }
+ }
+
+ protected function listContent($call)
+ {
+ $this->listCalls[] = $call;
+ }
+
+ protected function interpretSyntax($match, & $type)
+ {
+ if (substr($match, -1) == '*') {
+ $type = 'u';
+ } else {
+ $type = 'o';
+ }
+ // Is the +1 needed? It used to be count(explode(...))
+ // but I don't think the number is seen outside this handler
+ return substr_count(str_replace("\t", ' ', $match), ' ') + 1;
+ }
+}
diff --git a/platform/www/inc/Parsing/Handler/Nest.php b/platform/www/inc/Parsing/Handler/Nest.php
new file mode 100644
index 0000000..98d2134
--- /dev/null
+++ b/platform/www/inc/Parsing/Handler/Nest.php
@@ -0,0 +1,82 @@
+<?php
+
+namespace dokuwiki\Parsing\Handler;
+
+/**
+ * Generic call writer class to handle nesting of rendering instructions
+ * within a render instruction. Also see nest() method of renderer base class
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+class Nest extends AbstractRewriter
+{
+ protected $closingInstruction;
+
+ /**
+ * @inheritdoc
+ *
+ * @param CallWriterInterface $CallWriter the parser's current call writer, i.e. the one above us in the chain
+ * @param string $close closing instruction name, this is required to properly terminate the
+ * syntax mode if the document ends without a closing pattern
+ */
+ public function __construct(CallWriterInterface $CallWriter, $close = "nest_close")
+ {
+ parent::__construct($CallWriter);
+ $this->closingInstruction = $close;
+ }
+
+ /** @inheritdoc */
+ public function writeCall($call)
+ {
+ $this->calls[] = $call;
+ }
+
+ /** @inheritdoc */
+ public function writeCalls($calls)
+ {
+ $this->calls = array_merge($this->calls, $calls);
+ }
+
+ /** @inheritdoc */
+ public function finalise()
+ {
+ $last_call = end($this->calls);
+ $this->writeCall(array($this->closingInstruction,array(), $last_call[2]));
+
+ $this->process();
+ $this->callWriter->finalise();
+ unset($this->callWriter);
+ }
+
+ /** @inheritdoc */
+ public function process()
+ {
+ // merge consecutive cdata
+ $unmerged_calls = $this->calls;
+ $this->calls = array();
+
+ foreach ($unmerged_calls as $call) $this->addCall($call);
+
+ $first_call = reset($this->calls);
+ $this->callWriter->writeCall(array("nest", array($this->calls), $first_call[2]));
+
+ return $this->callWriter;
+ }
+
+ /**
+ * @param array $call
+ */
+ protected function addCall($call)
+ {
+ $key = count($this->calls);
+ if ($key and ($call[0] == 'cdata') and ($this->calls[$key-1][0] == 'cdata')) {
+ $this->calls[$key-1][1][0] .= $call[1][0];
+ } elseif ($call[0] == 'eol') {
+ // do nothing (eol shouldn't be allowed, to counter preformatted fix in #1652 & #1699)
+ } else {
+ $this->calls[] = $call;
+ }
+ }
+
+
+}
diff --git a/platform/www/inc/Parsing/Handler/Preformatted.php b/platform/www/inc/Parsing/Handler/Preformatted.php
new file mode 100644
index 0000000..41beb66
--- /dev/null
+++ b/platform/www/inc/Parsing/Handler/Preformatted.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace dokuwiki\Parsing\Handler;
+
+class Preformatted extends AbstractRewriter
+{
+
+ protected $pos;
+ protected $text ='';
+
+ /** @inheritdoc */
+ public function finalise()
+ {
+ $last_call = end($this->calls);
+ $this->writeCall(array('preformatted_end',array(), $last_call[2]));
+
+ $this->process();
+ $this->callWriter->finalise();
+ unset($this->callWriter);
+ }
+
+ /** @inheritdoc */
+ public function process()
+ {
+ foreach ($this->calls as $call) {
+ switch ($call[0]) {
+ case 'preformatted_start':
+ $this->pos = $call[2];
+ break;
+ case 'preformatted_newline':
+ $this->text .= "\n";
+ break;
+ case 'preformatted_content':
+ $this->text .= $call[1][0];
+ break;
+ case 'preformatted_end':
+ if (trim($this->text)) {
+ $this->callWriter->writeCall(array('preformatted', array($this->text), $this->pos));
+ }
+ // see FS#1699 & FS#1652, add 'eol' instructions to ensure proper triggering of following p_open
+ $this->callWriter->writeCall(array('eol', array(), $this->pos));
+ $this->callWriter->writeCall(array('eol', array(), $this->pos));
+ break;
+ }
+ }
+
+ return $this->callWriter;
+ }
+}
diff --git a/platform/www/inc/Parsing/Handler/Quote.php b/platform/www/inc/Parsing/Handler/Quote.php
new file mode 100644
index 0000000..74861b1
--- /dev/null
+++ b/platform/www/inc/Parsing/Handler/Quote.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace dokuwiki\Parsing\Handler;
+
+class Quote extends AbstractRewriter
+{
+ protected $quoteCalls = array();
+
+ /** @inheritdoc */
+ public function finalise()
+ {
+ $last_call = end($this->calls);
+ $this->writeCall(array('quote_end',array(), $last_call[2]));
+
+ $this->process();
+ $this->callWriter->finalise();
+ unset($this->callWriter);
+ }
+
+ /** @inheritdoc */
+ public function process()
+ {
+
+ $quoteDepth = 1;
+
+ foreach ($this->calls as $call) {
+ switch ($call[0]) {
+
+ /** @noinspection PhpMissingBreakStatementInspection */
+ case 'quote_start':
+ $this->quoteCalls[] = array('quote_open',array(),$call[2]);
+ // fallthrough
+ case 'quote_newline':
+ $quoteLength = $this->getDepth($call[1][0]);
+
+ if ($quoteLength > $quoteDepth) {
+ $quoteDiff = $quoteLength - $quoteDepth;
+ for ($i = 1; $i <= $quoteDiff; $i++) {
+ $this->quoteCalls[] = array('quote_open',array(),$call[2]);
+ }
+ } elseif ($quoteLength < $quoteDepth) {
+ $quoteDiff = $quoteDepth - $quoteLength;
+ for ($i = 1; $i <= $quoteDiff; $i++) {
+ $this->quoteCalls[] = array('quote_close',array(),$call[2]);
+ }
+ } else {
+ if ($call[0] != 'quote_start') $this->quoteCalls[] = array('linebreak',array(),$call[2]);
+ }
+
+ $quoteDepth = $quoteLength;
+
+ break;
+
+ case 'quote_end':
+ if ($quoteDepth > 1) {
+ $quoteDiff = $quoteDepth - 1;
+ for ($i = 1; $i <= $quoteDiff; $i++) {
+ $this->quoteCalls[] = array('quote_close',array(),$call[2]);
+ }
+ }
+
+ $this->quoteCalls[] = array('quote_close',array(),$call[2]);
+
+ $this->callWriter->writeCalls($this->quoteCalls);
+ break;
+
+ default:
+ $this->quoteCalls[] = $call;
+ break;
+ }
+ }
+
+ return $this->callWriter;
+ }
+
+ /**
+ * @param string $marker
+ * @return int
+ */
+ protected function getDepth($marker)
+ {
+ preg_match('/>{1,}/', $marker, $matches);
+ $quoteLength = strlen($matches[0]);
+ return $quoteLength;
+ }
+}
diff --git a/platform/www/inc/Parsing/Handler/ReWriterInterface.php b/platform/www/inc/Parsing/Handler/ReWriterInterface.php
new file mode 100644
index 0000000..2fa7b25
--- /dev/null
+++ b/platform/www/inc/Parsing/Handler/ReWriterInterface.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace dokuwiki\Parsing\Handler;
+
+/**
+ * A ReWriter takes over from the orignal call writer and handles all new calls itself until
+ * the process method is called and control is given back to the original writer.
+ *
+ * @property array[] $calls The list of current calls
+ */
+interface ReWriterInterface extends CallWriterInterface
+{
+ /**
+ * ReWriterInterface constructor.
+ *
+ * This rewriter will be registered as the new call writer in the Handler.
+ * The original is passed as parameter
+ *
+ * @param CallWriterInterface $callWriter the original callwriter
+ */
+ public function __construct(CallWriterInterface $callWriter);
+
+ /**
+ * Process any calls that have been added and add them to the
+ * original call writer
+ *
+ * @return CallWriterInterface the orignal call writer
+ */
+ public function process();
+
+ /**
+ * Accessor for this rewriter's original CallWriter
+ *
+ * @return CallWriterInterface
+ */
+ public function getCallWriter();
+}
diff --git a/platform/www/inc/Parsing/Handler/Table.php b/platform/www/inc/Parsing/Handler/Table.php
new file mode 100644
index 0000000..35ff5a8
--- /dev/null
+++ b/platform/www/inc/Parsing/Handler/Table.php
@@ -0,0 +1,320 @@
+<?php
+
+namespace dokuwiki\Parsing\Handler;
+
+class Table extends AbstractRewriter
+{
+
+ protected $tableCalls = array();
+ protected $maxCols = 0;
+ protected $maxRows = 1;
+ protected $currentCols = 0;
+ protected $firstCell = false;
+ protected $lastCellType = 'tablecell';
+ protected $inTableHead = true;
+ protected $currentRow = array('tableheader' => 0, 'tablecell' => 0);
+ protected $countTableHeadRows = 0;
+
+ /** @inheritdoc */
+ public function finalise()
+ {
+ $last_call = end($this->calls);
+ $this->writeCall(array('table_end',array(), $last_call[2]));
+
+ $this->process();
+ $this->callWriter->finalise();
+ unset($this->callWriter);
+ }
+
+ /** @inheritdoc */
+ public function process()
+ {
+ foreach ($this->calls as $call) {
+ switch ($call[0]) {
+ case 'table_start':
+ $this->tableStart($call);
+ break;
+ case 'table_row':
+ $this->tableRowClose($call);
+ $this->tableRowOpen(array('tablerow_open',$call[1],$call[2]));
+ break;
+ case 'tableheader':
+ case 'tablecell':
+ $this->tableCell($call);
+ break;
+ case 'table_end':
+ $this->tableRowClose($call);
+ $this->tableEnd($call);
+ break;
+ default:
+ $this->tableDefault($call);
+ break;
+ }
+ }
+ $this->callWriter->writeCalls($this->tableCalls);
+
+ return $this->callWriter;
+ }
+
+ protected function tableStart($call)
+ {
+ $this->tableCalls[] = array('table_open',$call[1],$call[2]);
+ $this->tableCalls[] = array('tablerow_open',array(),$call[2]);
+ $this->firstCell = true;
+ }
+
+ protected function tableEnd($call)
+ {
+ $this->tableCalls[] = array('table_close',$call[1],$call[2]);
+ $this->finalizeTable();
+ }
+
+ protected function tableRowOpen($call)
+ {
+ $this->tableCalls[] = $call;
+ $this->currentCols = 0;
+ $this->firstCell = true;
+ $this->lastCellType = 'tablecell';
+ $this->maxRows++;
+ if ($this->inTableHead) {
+ $this->currentRow = array('tablecell' => 0, 'tableheader' => 0);
+ }
+ }
+
+ protected function tableRowClose($call)
+ {
+ if ($this->inTableHead && ($this->inTableHead = $this->isTableHeadRow())) {
+ $this->countTableHeadRows++;
+ }
+ // Strip off final cell opening and anything after it
+ while ($discard = array_pop($this->tableCalls)) {
+ if ($discard[0] == 'tablecell_open' || $discard[0] == 'tableheader_open') {
+ break;
+ }
+ if (!empty($this->currentRow[$discard[0]])) {
+ $this->currentRow[$discard[0]]--;
+ }
+ }
+ $this->tableCalls[] = array('tablerow_close', array(), $call[2]);
+
+ if ($this->currentCols > $this->maxCols) {
+ $this->maxCols = $this->currentCols;
+ }
+ }
+
+ protected function isTableHeadRow()
+ {
+ $td = $this->currentRow['tablecell'];
+ $th = $this->currentRow['tableheader'];
+
+ if (!$th || $td > 2) return false;
+ if (2*$td > $th) return false;
+
+ return true;
+ }
+
+ protected function tableCell($call)
+ {
+ if ($this->inTableHead) {
+ $this->currentRow[$call[0]]++;
+ }
+ if (!$this->firstCell) {
+ // Increase the span
+ $lastCall = end($this->tableCalls);
+
+ // A cell call which follows an open cell means an empty cell so span
+ if ($lastCall[0] == 'tablecell_open' || $lastCall[0] == 'tableheader_open') {
+ $this->tableCalls[] = array('colspan',array(),$call[2]);
+ }
+
+ $this->tableCalls[] = array($this->lastCellType.'_close',array(),$call[2]);
+ $this->tableCalls[] = array($call[0].'_open',array(1,null,1),$call[2]);
+ $this->lastCellType = $call[0];
+ } else {
+ $this->tableCalls[] = array($call[0].'_open',array(1,null,1),$call[2]);
+ $this->lastCellType = $call[0];
+ $this->firstCell = false;
+ }
+
+ $this->currentCols++;
+ }
+
+ protected function tableDefault($call)
+ {
+ $this->tableCalls[] = $call;
+ }
+
+ protected function finalizeTable()
+ {
+
+ // Add the max cols and rows to the table opening
+ if ($this->tableCalls[0][0] == 'table_open') {
+ // Adjust to num cols not num col delimeters
+ $this->tableCalls[0][1][] = $this->maxCols - 1;
+ $this->tableCalls[0][1][] = $this->maxRows;
+ $this->tableCalls[0][1][] = array_shift($this->tableCalls[0][1]);
+ } else {
+ trigger_error('First element in table call list is not table_open');
+ }
+
+ $lastRow = 0;
+ $lastCell = 0;
+ $cellKey = array();
+ $toDelete = array();
+
+ // if still in tableheader, then there can be no table header
+ // as all rows can't be within <THEAD>
+ if ($this->inTableHead) {
+ $this->inTableHead = false;
+ $this->countTableHeadRows = 0;
+ }
+
+ // Look for the colspan elements and increment the colspan on the
+ // previous non-empty opening cell. Once done, delete all the cells
+ // that contain colspans
+ for ($key = 0; $key < count($this->tableCalls); ++$key) {
+ $call = $this->tableCalls[$key];
+
+ switch ($call[0]) {
+ case 'table_open':
+ if ($this->countTableHeadRows) {
+ array_splice($this->tableCalls, $key+1, 0, array(
+ array('tablethead_open', array(), $call[2])));
+ }
+ break;
+
+ case 'tablerow_open':
+ $lastRow++;
+ $lastCell = 0;
+ break;
+
+ case 'tablecell_open':
+ case 'tableheader_open':
+ $lastCell++;
+ $cellKey[$lastRow][$lastCell] = $key;
+ break;
+
+ case 'table_align':
+ $prev = in_array($this->tableCalls[$key-1][0], array('tablecell_open', 'tableheader_open'));
+ $next = in_array($this->tableCalls[$key+1][0], array('tablecell_close', 'tableheader_close'));
+ // If the cell is empty, align left
+ if ($prev && $next) {
+ $this->tableCalls[$key-1][1][1] = 'left';
+
+ // If the previous element was a cell open, align right
+ } elseif ($prev) {
+ $this->tableCalls[$key-1][1][1] = 'right';
+
+ // If the next element is the close of an element, align either center or left
+ } elseif ($next) {
+ if ($this->tableCalls[$cellKey[$lastRow][$lastCell]][1][1] == 'right') {
+ $this->tableCalls[$cellKey[$lastRow][$lastCell]][1][1] = 'center';
+ } else {
+ $this->tableCalls[$cellKey[$lastRow][$lastCell]][1][1] = 'left';
+ }
+ }
+
+ // Now convert the whitespace back to cdata
+ $this->tableCalls[$key][0] = 'cdata';
+ break;
+
+ case 'colspan':
+ $this->tableCalls[$key-1][1][0] = false;
+
+ for ($i = $key-2; $i >= $cellKey[$lastRow][1]; $i--) {
+ if ($this->tableCalls[$i][0] == 'tablecell_open' ||
+ $this->tableCalls[$i][0] == 'tableheader_open'
+ ) {
+ if (false !== $this->tableCalls[$i][1][0]) {
+ $this->tableCalls[$i][1][0]++;
+ break;
+ }
+ }
+ }
+
+ $toDelete[] = $key-1;
+ $toDelete[] = $key;
+ $toDelete[] = $key+1;
+ break;
+
+ case 'rowspan':
+ if ($this->tableCalls[$key-1][0] == 'cdata') {
+ // ignore rowspan if previous call was cdata (text mixed with :::)
+ // we don't have to check next call as that wont match regex
+ $this->tableCalls[$key][0] = 'cdata';
+ } else {
+ $spanning_cell = null;
+
+ // can't cross thead/tbody boundary
+ if (!$this->countTableHeadRows || ($lastRow-1 != $this->countTableHeadRows)) {
+ for ($i = $lastRow-1; $i > 0; $i--) {
+ if ($this->tableCalls[$cellKey[$i][$lastCell]][0] == 'tablecell_open' ||
+ $this->tableCalls[$cellKey[$i][$lastCell]][0] == 'tableheader_open'
+ ) {
+ if ($this->tableCalls[$cellKey[$i][$lastCell]][1][2] >= $lastRow - $i) {
+ $spanning_cell = $i;
+ break;
+ }
+ }
+ }
+ }
+ if (is_null($spanning_cell)) {
+ // No spanning cell found, so convert this cell to
+ // an empty one to avoid broken tables
+ $this->tableCalls[$key][0] = 'cdata';
+ $this->tableCalls[$key][1][0] = '';
+ break;
+ }
+ $this->tableCalls[$cellKey[$spanning_cell][$lastCell]][1][2]++;
+
+ $this->tableCalls[$key-1][1][2] = false;
+
+ $toDelete[] = $key-1;
+ $toDelete[] = $key;
+ $toDelete[] = $key+1;
+ }
+ break;
+
+ case 'tablerow_close':
+ // Fix broken tables by adding missing cells
+ $moreCalls = array();
+ while (++$lastCell < $this->maxCols) {
+ $moreCalls[] = array('tablecell_open', array(1, null, 1), $call[2]);
+ $moreCalls[] = array('cdata', array(''), $call[2]);
+ $moreCalls[] = array('tablecell_close', array(), $call[2]);
+ }
+ $moreCallsLength = count($moreCalls);
+ if ($moreCallsLength) {
+ array_splice($this->tableCalls, $key, 0, $moreCalls);
+ $key += $moreCallsLength;
+ }
+
+ if ($this->countTableHeadRows == $lastRow) {
+ array_splice($this->tableCalls, $key+1, 0, array(
+ array('tablethead_close', array(), $call[2])));
+ }
+ break;
+ }
+ }
+
+ // condense cdata
+ $cnt = count($this->tableCalls);
+ for ($key = 0; $key < $cnt; $key++) {
+ if ($this->tableCalls[$key][0] == 'cdata') {
+ $ckey = $key;
+ $key++;
+ while ($this->tableCalls[$key][0] == 'cdata') {
+ $this->tableCalls[$ckey][1][0] .= $this->tableCalls[$key][1][0];
+ $toDelete[] = $key;
+ $key++;
+ }
+ continue;
+ }
+ }
+
+ foreach ($toDelete as $delete) {
+ unset($this->tableCalls[$delete]);
+ }
+ $this->tableCalls = array_values($this->tableCalls);
+ }
+}
diff --git a/platform/www/inc/Parsing/Lexer/Lexer.php b/platform/www/inc/Parsing/Lexer/Lexer.php
new file mode 100644
index 0000000..edcd251
--- /dev/null
+++ b/platform/www/inc/Parsing/Lexer/Lexer.php
@@ -0,0 +1,349 @@
+<?php
+/**
+ * Lexer adapted from Simple Test: http://sourceforge.net/projects/simpletest/
+ * For an intro to the Lexer see:
+ * https://web.archive.org/web/20120125041816/http://www.phppatterns.com/docs/develop/simple_test_lexer_notes
+ *
+ * @author Marcus Baker http://www.lastcraft.com
+ */
+
+namespace dokuwiki\Parsing\Lexer;
+
+/**
+ * Accepts text and breaks it into tokens.
+ *
+ * Some optimisation to make the sure the content is only scanned by the PHP regex
+ * parser once. Lexer modes must not start with leading underscores.
+ */
+class Lexer
+{
+ /** @var ParallelRegex[] */
+ protected $regexes;
+ /** @var \Doku_Handler */
+ protected $handler;
+ /** @var StateStack */
+ protected $modeStack;
+ /** @var array mode "rewrites" */
+ protected $mode_handlers;
+ /** @var bool case sensitive? */
+ protected $case;
+
+ /**
+ * Sets up the lexer in case insensitive matching by default.
+ *
+ * @param \Doku_Handler $handler Handling strategy by reference.
+ * @param string $start Starting handler.
+ * @param boolean $case True for case sensitive.
+ */
+ public function __construct($handler, $start = "accept", $case = false)
+ {
+ $this->case = $case;
+ $this->regexes = array();
+ $this->handler = $handler;
+ $this->modeStack = new StateStack($start);
+ $this->mode_handlers = array();
+ }
+
+ /**
+ * Adds a token search pattern for a particular parsing mode.
+ *
+ * The pattern does not change the current mode.
+ *
+ * @param string $pattern Perl style regex, but ( and )
+ * lose the usual meaning.
+ * @param string $mode Should only apply this
+ * pattern when dealing with
+ * this type of input.
+ */
+ public function addPattern($pattern, $mode = "accept")
+ {
+ if (! isset($this->regexes[$mode])) {
+ $this->regexes[$mode] = new ParallelRegex($this->case);
+ }
+ $this->regexes[$mode]->addPattern($pattern);
+ }
+
+ /**
+ * Adds a pattern that will enter a new parsing mode.
+ *
+ * Useful for entering parenthesis, strings, tags, etc.
+ *
+ * @param string $pattern Perl style regex, but ( and ) lose the usual meaning.
+ * @param string $mode Should only apply this pattern when dealing with this type of input.
+ * @param string $new_mode Change parsing to this new nested mode.
+ */
+ public function addEntryPattern($pattern, $mode, $new_mode)
+ {
+ if (! isset($this->regexes[$mode])) {
+ $this->regexes[$mode] = new ParallelRegex($this->case);
+ }
+ $this->regexes[$mode]->addPattern($pattern, $new_mode);
+ }
+
+ /**
+ * Adds a pattern that will exit the current mode and re-enter the previous one.
+ *
+ * @param string $pattern Perl style regex, but ( and ) lose the usual meaning.
+ * @param string $mode Mode to leave.
+ */
+ public function addExitPattern($pattern, $mode)
+ {
+ if (! isset($this->regexes[$mode])) {
+ $this->regexes[$mode] = new ParallelRegex($this->case);
+ }
+ $this->regexes[$mode]->addPattern($pattern, "__exit");
+ }
+
+ /**
+ * Adds a pattern that has a special mode.
+ *
+ * Acts as an entry and exit pattern in one go, effectively calling a special
+ * parser handler for this token only.
+ *
+ * @param string $pattern Perl style regex, but ( and ) lose the usual meaning.
+ * @param string $mode Should only apply this pattern when dealing with this type of input.
+ * @param string $special Use this mode for this one token.
+ */
+ public function addSpecialPattern($pattern, $mode, $special)
+ {
+ if (! isset($this->regexes[$mode])) {
+ $this->regexes[$mode] = new ParallelRegex($this->case);
+ }
+ $this->regexes[$mode]->addPattern($pattern, "_$special");
+ }
+
+ /**
+ * Adds a mapping from a mode to another handler.
+ *
+ * @param string $mode Mode to be remapped.
+ * @param string $handler New target handler.
+ */
+ public function mapHandler($mode, $handler)
+ {
+ $this->mode_handlers[$mode] = $handler;
+ }
+
+ /**
+ * Splits the page text into tokens.
+ *
+ * Will fail if the handlers report an error or if no content is consumed. If successful then each
+ * unparsed and parsed token invokes a call to the held listener.
+ *
+ * @param string $raw Raw HTML text.
+ * @return boolean True on success, else false.
+ */
+ public function parse($raw)
+ {
+ if (! isset($this->handler)) {
+ return false;
+ }
+ $initialLength = strlen($raw);
+ $length = $initialLength;
+ $pos = 0;
+ while (is_array($parsed = $this->reduce($raw))) {
+ list($unmatched, $matched, $mode) = $parsed;
+ $currentLength = strlen($raw);
+ $matchPos = $initialLength - $currentLength - strlen($matched);
+ if (! $this->dispatchTokens($unmatched, $matched, $mode, $pos, $matchPos)) {
+ return false;
+ }
+ if ($currentLength == $length) {
+ return false;
+ }
+ $length = $currentLength;
+ $pos = $initialLength - $currentLength;
+ }
+ if (!$parsed) {
+ return false;
+ }
+ return $this->invokeHandler($raw, DOKU_LEXER_UNMATCHED, $pos);
+ }
+
+ /**
+ * Gives plugins access to the mode stack
+ *
+ * @return StateStack
+ */
+ public function getModeStack()
+ {
+ return $this->modeStack;
+ }
+
+ /**
+ * Sends the matched token and any leading unmatched
+ * text to the parser changing the lexer to a new
+ * mode if one is listed.
+ *
+ * @param string $unmatched Unmatched leading portion.
+ * @param string $matched Actual token match.
+ * @param bool|string $mode Mode after match. A boolean false mode causes no change.
+ * @param int $initialPos
+ * @param int $matchPos Current byte index location in raw doc thats being parsed
+ * @return boolean False if there was any error from the parser.
+ */
+ protected function dispatchTokens($unmatched, $matched, $mode, $initialPos, $matchPos)
+ {
+ if (! $this->invokeHandler($unmatched, DOKU_LEXER_UNMATCHED, $initialPos)) {
+ return false;
+ }
+ if ($this->isModeEnd($mode)) {
+ if (! $this->invokeHandler($matched, DOKU_LEXER_EXIT, $matchPos)) {
+ return false;
+ }
+ return $this->modeStack->leave();
+ }
+ if ($this->isSpecialMode($mode)) {
+ $this->modeStack->enter($this->decodeSpecial($mode));
+ if (! $this->invokeHandler($matched, DOKU_LEXER_SPECIAL, $matchPos)) {
+ return false;
+ }
+ return $this->modeStack->leave();
+ }
+ if (is_string($mode)) {
+ $this->modeStack->enter($mode);
+ return $this->invokeHandler($matched, DOKU_LEXER_ENTER, $matchPos);
+ }
+ return $this->invokeHandler($matched, DOKU_LEXER_MATCHED, $matchPos);
+ }
+
+ /**
+ * Tests to see if the new mode is actually to leave the current mode and pop an item from the matching
+ * mode stack.
+ *
+ * @param string $mode Mode to test.
+ * @return boolean True if this is the exit mode.
+ */
+ protected function isModeEnd($mode)
+ {
+ return ($mode === "__exit");
+ }
+
+ /**
+ * Test to see if the mode is one where this mode is entered for this token only and automatically
+ * leaves immediately afterwoods.
+ *
+ * @param string $mode Mode to test.
+ * @return boolean True if this is the exit mode.
+ */
+ protected function isSpecialMode($mode)
+ {
+ return (strncmp($mode, "_", 1) == 0);
+ }
+
+ /**
+ * Strips the magic underscore marking single token modes.
+ *
+ * @param string $mode Mode to decode.
+ * @return string Underlying mode name.
+ */
+ protected function decodeSpecial($mode)
+ {
+ return substr($mode, 1);
+ }
+
+ /**
+ * Calls the parser method named after the current mode.
+ *
+ * Empty content will be ignored. The lexer has a parser handler for each mode in the lexer.
+ *
+ * @param string $content Text parsed.
+ * @param boolean $is_match Token is recognised rather
+ * than unparsed data.
+ * @param int $pos Current byte index location in raw doc
+ * thats being parsed
+ * @return bool
+ */
+ protected function invokeHandler($content, $is_match, $pos)
+ {
+ if (($content === "") || ($content === false)) {
+ return true;
+ }
+ $handler = $this->modeStack->getCurrent();
+ if (isset($this->mode_handlers[$handler])) {
+ $handler = $this->mode_handlers[$handler];
+ }
+
+ // modes starting with plugin_ are all handled by the same
+ // handler but with an additional parameter
+ if (substr($handler, 0, 7)=='plugin_') {
+ list($handler,$plugin) = explode('_', $handler, 2);
+ return $this->handler->$handler($content, $is_match, $pos, $plugin);
+ }
+
+ return $this->handler->$handler($content, $is_match, $pos);
+ }
+
+ /**
+ * Tries to match a chunk of text and if successful removes the recognised chunk and any leading
+ * unparsed data. Empty strings will not be matched.
+ *
+ * @param string $raw The subject to parse. This is the content that will be eaten.
+ * @return array|bool Three item list of unparsed content followed by the
+ * recognised token and finally the action the parser is to take.
+ * True if no match, false if there is a parsing error.
+ */
+ protected function reduce(&$raw)
+ {
+ if (! isset($this->regexes[$this->modeStack->getCurrent()])) {
+ return false;
+ }
+ if ($raw === "") {
+ return true;
+ }
+ if ($action = $this->regexes[$this->modeStack->getCurrent()]->split($raw, $split)) {
+ list($unparsed, $match, $raw) = $split;
+ return array($unparsed, $match, $action);
+ }
+ return true;
+ }
+
+ /**
+ * Escapes regex characters other than (, ) and /
+ *
+ * @param string $str
+ * @return string
+ */
+ public static function escape($str)
+ {
+ $chars = array(
+ '/\\\\/',
+ '/\./',
+ '/\+/',
+ '/\*/',
+ '/\?/',
+ '/\[/',
+ '/\^/',
+ '/\]/',
+ '/\$/',
+ '/\{/',
+ '/\}/',
+ '/\=/',
+ '/\!/',
+ '/\</',
+ '/\>/',
+ '/\|/',
+ '/\:/'
+ );
+
+ $escaped = array(
+ '\\\\\\\\',
+ '\.',
+ '\+',
+ '\*',
+ '\?',
+ '\[',
+ '\^',
+ '\]',
+ '\$',
+ '\{',
+ '\}',
+ '\=',
+ '\!',
+ '\<',
+ '\>',
+ '\|',
+ '\:'
+ );
+ return preg_replace($chars, $escaped, $str);
+ }
+}
diff --git a/platform/www/inc/Parsing/Lexer/ParallelRegex.php b/platform/www/inc/Parsing/Lexer/ParallelRegex.php
new file mode 100644
index 0000000..96f61a1
--- /dev/null
+++ b/platform/www/inc/Parsing/Lexer/ParallelRegex.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * Lexer adapted from Simple Test: http://sourceforge.net/projects/simpletest/
+ * For an intro to the Lexer see:
+ * https://web.archive.org/web/20120125041816/http://www.phppatterns.com/docs/develop/simple_test_lexer_notes
+ *
+ * @author Marcus Baker http://www.lastcraft.com
+ */
+
+namespace dokuwiki\Parsing\Lexer;
+
+/**
+ * Compounded regular expression.
+ *
+ * Any of the contained patterns could match and when one does it's label is returned.
+ */
+class ParallelRegex
+{
+ /** @var string[] patterns to match */
+ protected $patterns;
+ /** @var string[] labels for above patterns */
+ protected $labels;
+ /** @var string the compound regex matching all patterns */
+ protected $regex;
+ /** @var bool case sensitive matching? */
+ protected $case;
+
+ /**
+ * Constructor. Starts with no patterns.
+ *
+ * @param boolean $case True for case sensitive, false
+ * for insensitive.
+ */
+ public function __construct($case)
+ {
+ $this->case = $case;
+ $this->patterns = array();
+ $this->labels = array();
+ $this->regex = null;
+ }
+
+ /**
+ * Adds a pattern with an optional label.
+ *
+ * @param mixed $pattern Perl style regex. Must be UTF-8
+ * encoded. If its a string, the (, )
+ * lose their meaning unless they
+ * form part of a lookahead or
+ * lookbehind assertation.
+ * @param bool|string $label Label of regex to be returned
+ * on a match. Label must be ASCII
+ */
+ public function addPattern($pattern, $label = true)
+ {
+ $count = count($this->patterns);
+ $this->patterns[$count] = $pattern;
+ $this->labels[$count] = $label;
+ $this->regex = null;
+ }
+
+ /**
+ * Attempts to match all patterns at once against a string.
+ *
+ * @param string $subject String to match against.
+ * @param string $match First matched portion of
+ * subject.
+ * @return bool|string False if no match found, label if label exists, true if not
+ */
+ public function match($subject, &$match)
+ {
+ if (count($this->patterns) == 0) {
+ return false;
+ }
+ if (! preg_match($this->getCompoundedRegex(), $subject, $matches)) {
+ $match = "";
+ return false;
+ }
+
+ $match = $matches[0];
+ $size = count($matches);
+ // FIXME this could be made faster by storing the labels as keys in a hashmap
+ for ($i = 1; $i < $size; $i++) {
+ if ($matches[$i] && isset($this->labels[$i - 1])) {
+ return $this->labels[$i - 1];
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Attempts to split the string against all patterns at once
+ *
+ * @param string $subject String to match against.
+ * @param array $split The split result: array containing, pre-match, match & post-match strings
+ * @return boolean True on success.
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+ public function split($subject, &$split)
+ {
+ if (count($this->patterns) == 0) {
+ return false;
+ }
+
+ if (! preg_match($this->getCompoundedRegex(), $subject, $matches)) {
+ if (function_exists('preg_last_error')) {
+ $err = preg_last_error();
+ switch ($err) {
+ case PREG_BACKTRACK_LIMIT_ERROR:
+ msg('A PCRE backtrack error occured. Try to increase the pcre.backtrack_limit in php.ini', -1);
+ break;
+ case PREG_RECURSION_LIMIT_ERROR:
+ msg('A PCRE recursion error occured. Try to increase the pcre.recursion_limit in php.ini', -1);
+ break;
+ case PREG_BAD_UTF8_ERROR:
+ msg('A PCRE UTF-8 error occured. This might be caused by a faulty plugin', -1);
+ break;
+ case PREG_INTERNAL_ERROR:
+ msg('A PCRE internal error occured. This might be caused by a faulty plugin', -1);
+ break;
+ }
+ }
+
+ $split = array($subject, "", "");
+ return false;
+ }
+
+ $idx = count($matches)-2;
+ list($pre, $post) = preg_split($this->patterns[$idx].$this->getPerlMatchingFlags(), $subject, 2);
+ $split = array($pre, $matches[0], $post);
+
+ return isset($this->labels[$idx]) ? $this->labels[$idx] : true;
+ }
+
+ /**
+ * Compounds the patterns into a single
+ * regular expression separated with the
+ * "or" operator. Caches the regex.
+ * Will automatically escape (, ) and / tokens.
+ *
+ * @return null|string
+ */
+ protected function getCompoundedRegex()
+ {
+ if ($this->regex == null) {
+ $cnt = count($this->patterns);
+ for ($i = 0; $i < $cnt; $i++) {
+ /*
+ * decompose the input pattern into "(", "(?", ")",
+ * "[...]", "[]..]", "[^]..]", "[...[:...:]..]", "\x"...
+ * elements.
+ */
+ preg_match_all('/\\\\.|' .
+ '\(\?|' .
+ '[()]|' .
+ '\[\^?\]?(?:\\\\.|\[:[^]]*:\]|[^]\\\\])*\]|' .
+ '[^[()\\\\]+/', $this->patterns[$i], $elts);
+
+ $pattern = "";
+ $level = 0;
+
+ foreach ($elts[0] as $elt) {
+ /*
+ * for "(", ")" remember the nesting level, add "\"
+ * only to the non-"(?" ones.
+ */
+
+ switch ($elt) {
+ case '(':
+ $pattern .= '\(';
+ break;
+ case ')':
+ if ($level > 0)
+ $level--; /* closing (? */
+ else $pattern .= '\\';
+ $pattern .= ')';
+ break;
+ case '(?':
+ $level++;
+ $pattern .= '(?';
+ break;
+ default:
+ if (substr($elt, 0, 1) == '\\')
+ $pattern .= $elt;
+ else $pattern .= str_replace('/', '\/', $elt);
+ }
+ }
+ $this->patterns[$i] = "($pattern)";
+ }
+ $this->regex = "/" . implode("|", $this->patterns) . "/" . $this->getPerlMatchingFlags();
+ }
+ return $this->regex;
+ }
+
+ /**
+ * Accessor for perl regex mode flags to use.
+ * @return string Perl regex flags.
+ */
+ protected function getPerlMatchingFlags()
+ {
+ return ($this->case ? "msS" : "msSi");
+ }
+}
diff --git a/platform/www/inc/Parsing/Lexer/StateStack.php b/platform/www/inc/Parsing/Lexer/StateStack.php
new file mode 100644
index 0000000..325412b
--- /dev/null
+++ b/platform/www/inc/Parsing/Lexer/StateStack.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Lexer adapted from Simple Test: http://sourceforge.net/projects/simpletest/
+ * For an intro to the Lexer see:
+ * https://web.archive.org/web/20120125041816/http://www.phppatterns.com/docs/develop/simple_test_lexer_notes
+ *
+ * @author Marcus Baker http://www.lastcraft.com
+ */
+
+namespace dokuwiki\Parsing\Lexer;
+
+/**
+ * States for a stack machine.
+ */
+class StateStack
+{
+ protected $stack;
+
+ /**
+ * Constructor. Starts in named state.
+ * @param string $start Starting state name.
+ */
+ public function __construct($start)
+ {
+ $this->stack = array($start);
+ }
+
+ /**
+ * Accessor for current state.
+ * @return string State.
+ */
+ public function getCurrent()
+ {
+ return $this->stack[count($this->stack) - 1];
+ }
+
+ /**
+ * Adds a state to the stack and sets it to be the current state.
+ *
+ * @param string $state New state.
+ */
+ public function enter($state)
+ {
+ array_push($this->stack, $state);
+ }
+
+ /**
+ * Leaves the current state and reverts
+ * to the previous one.
+ * @return boolean false if we attempt to drop off the bottom of the list.
+ */
+ public function leave()
+ {
+ if (count($this->stack) == 1) {
+ return false;
+ }
+ array_pop($this->stack);
+ return true;
+ }
+}
diff --git a/platform/www/inc/Parsing/Parser.php b/platform/www/inc/Parsing/Parser.php
new file mode 100644
index 0000000..63f0141
--- /dev/null
+++ b/platform/www/inc/Parsing/Parser.php
@@ -0,0 +1,128 @@
+<?php
+
+namespace dokuwiki\Parsing;
+
+use Doku_Handler;
+use dokuwiki\Parsing\Lexer\Lexer;
+use dokuwiki\Parsing\ParserMode\Base;
+use dokuwiki\Parsing\ParserMode\ModeInterface;
+
+/**
+ * Sets up the Lexer with modes and points it to the Handler
+ * For an intro to the Lexer see: wiki:parser
+ */
+class Parser {
+
+ /** @var Doku_Handler */
+ protected $handler;
+
+ /** @var Lexer $lexer */
+ protected $lexer;
+
+ /** @var ModeInterface[] $modes */
+ protected $modes = array();
+
+ /** @var bool mode connections may only be set up once */
+ protected $connected = false;
+
+ /**
+ * dokuwiki\Parsing\Doku_Parser constructor.
+ *
+ * @param Doku_Handler $handler
+ */
+ public function __construct(Doku_Handler $handler) {
+ $this->handler = $handler;
+ }
+
+ /**
+ * Adds the base mode and initialized the lexer
+ *
+ * @param Base $BaseMode
+ */
+ protected function addBaseMode($BaseMode) {
+ $this->modes['base'] = $BaseMode;
+ if(!$this->lexer) {
+ $this->lexer = new Lexer($this->handler, 'base', true);
+ }
+ $this->modes['base']->Lexer = $this->lexer;
+ }
+
+ /**
+ * Add a new syntax element (mode) to the parser
+ *
+ * PHP preserves order of associative elements
+ * Mode sequence is important
+ *
+ * @param string $name
+ * @param ModeInterface $Mode
+ */
+ public function addMode($name, ModeInterface $Mode) {
+ if(!isset($this->modes['base'])) {
+ $this->addBaseMode(new Base());
+ }
+ $Mode->Lexer = $this->lexer; // FIXME should be done by setter
+ $this->modes[$name] = $Mode;
+ }
+
+ /**
+ * Connect all modes with each other
+ *
+ * This is the last step before actually parsing.
+ */
+ protected function connectModes() {
+
+ if($this->connected) {
+ return;
+ }
+
+ foreach(array_keys($this->modes) as $mode) {
+ // Base isn't connected to anything
+ if($mode == 'base') {
+ continue;
+ }
+ $this->modes[$mode]->preConnect();
+
+ foreach(array_keys($this->modes) as $cm) {
+
+ if($this->modes[$cm]->accepts($mode)) {
+ $this->modes[$mode]->connectTo($cm);
+ }
+
+ }
+
+ $this->modes[$mode]->postConnect();
+ }
+
+ $this->connected = true;
+ }
+
+ /**
+ * Parses wiki syntax to instructions
+ *
+ * @param string $doc the wiki syntax text
+ * @return array instructions
+ */
+ public function parse($doc) {
+ $this->connectModes();
+ // Normalize CRs and pad doc
+ $doc = "\n" . str_replace("\r\n", "\n", $doc) . "\n";
+ $this->lexer->parse($doc);
+
+ if (!method_exists($this->handler, 'finalize')) {
+ /** @deprecated 2019-10 we have a legacy handler from a plugin, assume legacy _finalize exists */
+
+ \dokuwiki\Debug\DebugHelper::dbgCustomDeprecationEvent(
+ 'finalize()',
+ get_class($this->handler) . '::_finalize()',
+ __METHOD__,
+ __FILE__,
+ __LINE__
+ );
+ $this->handler->_finalize();
+ } else {
+ $this->handler->finalize();
+ }
+ return $this->handler->calls;
+ }
+
+}
diff --git a/platform/www/inc/Parsing/ParserMode/AbstractMode.php b/platform/www/inc/Parsing/ParserMode/AbstractMode.php
new file mode 100644
index 0000000..15fc9fe
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/AbstractMode.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+/**
+ * This class and all the subclasses below are used to reduce the effort required to register
+ * modes with the Lexer.
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+abstract class AbstractMode implements ModeInterface
+{
+ /** @var \dokuwiki\Parsing\Lexer\Lexer $Lexer will be injected on loading FIXME this should be done by setter */
+ public $Lexer;
+ protected $allowedModes = array();
+
+ /** @inheritdoc */
+ abstract public function getSort();
+
+ /** @inheritdoc */
+ public function preConnect()
+ {
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+ }
+
+ /** @inheritdoc */
+ public function accepts($mode)
+ {
+ return in_array($mode, (array) $this->allowedModes);
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Acronym.php b/platform/www/inc/Parsing/ParserMode/Acronym.php
new file mode 100644
index 0000000..b42a7b5
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Acronym.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Acronym extends AbstractMode
+{
+ // A list
+ protected $acronyms = array();
+ protected $pattern = '';
+
+ /**
+ * Acronym constructor.
+ *
+ * @param string[] $acronyms
+ */
+ public function __construct($acronyms)
+ {
+ usort($acronyms, array($this,'compare'));
+ $this->acronyms = $acronyms;
+ }
+
+ /** @inheritdoc */
+ public function preConnect()
+ {
+ if (!count($this->acronyms)) return;
+
+ $bound = '[\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]';
+ $acronyms = array_map(['\\dokuwiki\\Parsing\\Lexer\\Lexer', 'escape'], $this->acronyms);
+ $this->pattern = '(?<=^|'.$bound.')(?:'.join('|', $acronyms).')(?='.$bound.')';
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ if (!count($this->acronyms)) return;
+
+ if (strlen($this->pattern) > 0) {
+ $this->Lexer->addSpecialPattern($this->pattern, $mode, 'acronym');
+ }
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 240;
+ }
+
+ /**
+ * sort callback to order by string length descending
+ *
+ * @param string $a
+ * @param string $b
+ *
+ * @return int
+ */
+ protected function compare($a, $b)
+ {
+ $a_len = strlen($a);
+ $b_len = strlen($b);
+ if ($a_len > $b_len) {
+ return -1;
+ } elseif ($a_len < $b_len) {
+ return 1;
+ }
+
+ return 0;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Base.php b/platform/www/inc/Parsing/ParserMode/Base.php
new file mode 100644
index 0000000..5622756
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Base.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Base extends AbstractMode
+{
+
+ /**
+ * Base constructor.
+ */
+ public function __construct()
+ {
+ global $PARSER_MODES;
+
+ $this->allowedModes = array_merge(
+ $PARSER_MODES['container'],
+ $PARSER_MODES['baseonly'],
+ $PARSER_MODES['paragraphs'],
+ $PARSER_MODES['formatting'],
+ $PARSER_MODES['substition'],
+ $PARSER_MODES['protected'],
+ $PARSER_MODES['disabled']
+ );
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 0;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Camelcaselink.php b/platform/www/inc/Parsing/ParserMode/Camelcaselink.php
new file mode 100644
index 0000000..ef0b325
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Camelcaselink.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Camelcaselink extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addSpecialPattern(
+ '\b[A-Z]+[a-z]+[A-Z][A-Za-z]*\b',
+ $mode,
+ 'camelcaselink'
+ );
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 290;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Code.php b/platform/www/inc/Parsing/ParserMode/Code.php
new file mode 100644
index 0000000..aa49437
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Code.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Code extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addEntryPattern('<code\b(?=.*</code>)', $mode, 'code');
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+ $this->Lexer->addExitPattern('</code>', 'code');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 200;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Emaillink.php b/platform/www/inc/Parsing/ParserMode/Emaillink.php
new file mode 100644
index 0000000..f9af28c
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Emaillink.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Emaillink extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ // pattern below is defined in inc/mail.php
+ $this->Lexer->addSpecialPattern('<'.PREG_PATTERN_VALID_EMAIL.'>', $mode, 'emaillink');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 340;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Entity.php b/platform/www/inc/Parsing/ParserMode/Entity.php
new file mode 100644
index 0000000..b670124
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Entity.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+use dokuwiki\Parsing\Lexer\Lexer;
+
+class Entity extends AbstractMode
+{
+
+ protected $entities = array();
+ protected $pattern = '';
+
+ /**
+ * Entity constructor.
+ * @param string[] $entities
+ */
+ public function __construct($entities)
+ {
+ $this->entities = $entities;
+ }
+
+
+ /** @inheritdoc */
+ public function preConnect()
+ {
+ if (!count($this->entities) || $this->pattern != '') return;
+
+ $sep = '';
+ foreach ($this->entities as $entity) {
+ $this->pattern .= $sep. Lexer::escape($entity);
+ $sep = '|';
+ }
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ if (!count($this->entities)) return;
+
+ if (strlen($this->pattern) > 0) {
+ $this->Lexer->addSpecialPattern($this->pattern, $mode, 'entity');
+ }
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 260;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Eol.php b/platform/www/inc/Parsing/ParserMode/Eol.php
new file mode 100644
index 0000000..a5886b5
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Eol.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Eol extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $badModes = array('listblock','table');
+ if (in_array($mode, $badModes)) {
+ return;
+ }
+ // see FS#1652, pattern extended to swallow preceding whitespace to avoid
+ // issues with lines that only contain whitespace
+ $this->Lexer->addSpecialPattern('(?:^[ \t]*)?\n', $mode, 'eol');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 370;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Externallink.php b/platform/www/inc/Parsing/ParserMode/Externallink.php
new file mode 100644
index 0000000..7475745
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Externallink.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Externallink extends AbstractMode
+{
+ protected $schemes = array();
+ protected $patterns = array();
+
+ /** @inheritdoc */
+ public function preConnect()
+ {
+ if (count($this->patterns)) return;
+
+ $ltrs = '\w';
+ $gunk = '/\#~:.?+=&%@!\-\[\]';
+ $punc = '.:?\-;,';
+ $host = $ltrs.$punc;
+ $any = $ltrs.$gunk.$punc;
+
+ $this->schemes = getSchemes();
+ foreach ($this->schemes as $scheme) {
+ $this->patterns[] = '\b(?i)'.$scheme.'(?-i)://['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
+ }
+
+ $this->patterns[] = '(?<=\s)(?i)www?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
+ $this->patterns[] = '(?<=\s)(?i)ftp?(?-i)\.['.$host.']+?\.['.$host.']+?['.$any.']+?(?=['.$punc.']*[^'.$any.'])';
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+
+ foreach ($this->patterns as $pattern) {
+ $this->Lexer->addSpecialPattern($pattern, $mode, 'externallink');
+ }
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 330;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/File.php b/platform/www/inc/Parsing/ParserMode/File.php
new file mode 100644
index 0000000..1491341
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/File.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class File extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addEntryPattern('<file\b(?=.*</file>)', $mode, 'file');
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+ $this->Lexer->addExitPattern('</file>', 'file');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 210;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Filelink.php b/platform/www/inc/Parsing/ParserMode/Filelink.php
new file mode 100644
index 0000000..3cd86cb
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Filelink.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Filelink extends AbstractMode
+{
+
+ protected $pattern;
+
+ /** @inheritdoc */
+ public function preConnect()
+ {
+
+ $ltrs = '\w';
+ $gunk = '/\#~:.?+=&%@!\-';
+ $punc = '.:?\-;,';
+ $host = $ltrs.$punc;
+ $any = $ltrs.$gunk.$punc;
+
+ $this->pattern = '\b(?i)file(?-i)://['.$any.']+?['.
+ $punc.']*[^'.$any.']';
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addSpecialPattern(
+ $this->pattern,
+ $mode,
+ 'filelink'
+ );
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 360;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Footnote.php b/platform/www/inc/Parsing/ParserMode/Footnote.php
new file mode 100644
index 0000000..c399f98
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Footnote.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Footnote extends AbstractMode
+{
+
+ /**
+ * Footnote constructor.
+ */
+ public function __construct()
+ {
+ global $PARSER_MODES;
+
+ $this->allowedModes = array_merge(
+ $PARSER_MODES['container'],
+ $PARSER_MODES['formatting'],
+ $PARSER_MODES['substition'],
+ $PARSER_MODES['protected'],
+ $PARSER_MODES['disabled']
+ );
+
+ unset($this->allowedModes[array_search('footnote', $this->allowedModes)]);
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addEntryPattern(
+ '\x28\x28(?=.*\x29\x29)',
+ $mode,
+ 'footnote'
+ );
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+ $this->Lexer->addExitPattern(
+ '\x29\x29',
+ 'footnote'
+ );
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 150;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Formatting.php b/platform/www/inc/Parsing/ParserMode/Formatting.php
new file mode 100644
index 0000000..a3c465c
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Formatting.php
@@ -0,0 +1,115 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+/**
+ * This class sets the markup for bold (=strong),
+ * italic (=emphasis), underline etc.
+ */
+class Formatting extends AbstractMode
+{
+ protected $type;
+
+ protected $formatting = array(
+ 'strong' => array(
+ 'entry' => '\*\*(?=.*\*\*)',
+ 'exit' => '\*\*',
+ 'sort' => 70
+ ),
+
+ 'emphasis' => array(
+ 'entry' => '//(?=[^\x00]*[^:])', //hack for bugs #384 #763 #1468
+ 'exit' => '//',
+ 'sort' => 80
+ ),
+
+ 'underline' => array(
+ 'entry' => '__(?=.*__)',
+ 'exit' => '__',
+ 'sort' => 90
+ ),
+
+ 'monospace' => array(
+ 'entry' => '\x27\x27(?=.*\x27\x27)',
+ 'exit' => '\x27\x27',
+ 'sort' => 100
+ ),
+
+ 'subscript' => array(
+ 'entry' => '<sub>(?=.*</sub>)',
+ 'exit' => '</sub>',
+ 'sort' => 110
+ ),
+
+ 'superscript' => array(
+ 'entry' => '<sup>(?=.*</sup>)',
+ 'exit' => '</sup>',
+ 'sort' => 120
+ ),
+
+ 'deleted' => array(
+ 'entry' => '<del>(?=.*</del>)',
+ 'exit' => '</del>',
+ 'sort' => 130
+ ),
+ );
+
+ /**
+ * @param string $type
+ */
+ public function __construct($type)
+ {
+ global $PARSER_MODES;
+
+ if (!array_key_exists($type, $this->formatting)) {
+ trigger_error('Invalid formatting type ' . $type, E_USER_WARNING);
+ }
+
+ $this->type = $type;
+
+ // formatting may contain other formatting but not it self
+ $modes = $PARSER_MODES['formatting'];
+ $key = array_search($type, $modes);
+ if (is_int($key)) {
+ unset($modes[$key]);
+ }
+
+ $this->allowedModes = array_merge(
+ $modes,
+ $PARSER_MODES['substition'],
+ $PARSER_MODES['disabled']
+ );
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+
+ // Can't nest formatting in itself
+ if ($mode == $this->type) {
+ return;
+ }
+
+ $this->Lexer->addEntryPattern(
+ $this->formatting[$this->type]['entry'],
+ $mode,
+ $this->type
+ );
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+
+ $this->Lexer->addExitPattern(
+ $this->formatting[$this->type]['exit'],
+ $this->type
+ );
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return $this->formatting[$this->type]['sort'];
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Header.php b/platform/www/inc/Parsing/ParserMode/Header.php
new file mode 100644
index 0000000..854b317
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Header.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Header extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ //we're not picky about the closing ones, two are enough
+ $this->Lexer->addSpecialPattern(
+ '[ \t]*={2,}[^\n]+={2,}[ \t]*(?=\n)',
+ $mode,
+ 'header'
+ );
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 50;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Hr.php b/platform/www/inc/Parsing/ParserMode/Hr.php
new file mode 100644
index 0000000..e4f0b44
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Hr.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Hr extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addSpecialPattern('\n[ \t]*-{4,}[ \t]*(?=\n)', $mode, 'hr');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 160;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Html.php b/platform/www/inc/Parsing/ParserMode/Html.php
new file mode 100644
index 0000000..f5b63ef
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Html.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Html extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addEntryPattern('<html>(?=.*</html>)', $mode, 'html');
+ $this->Lexer->addEntryPattern('<HTML>(?=.*</HTML>)', $mode, 'htmlblock');
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+ $this->Lexer->addExitPattern('</html>', 'html');
+ $this->Lexer->addExitPattern('</HTML>', 'htmlblock');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 190;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Internallink.php b/platform/www/inc/Parsing/ParserMode/Internallink.php
new file mode 100644
index 0000000..6def0d9
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Internallink.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Internallink extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ // Word boundaries?
+ $this->Lexer->addSpecialPattern("\[\[.*?\]\](?!\])", $mode, 'internallink');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 300;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Linebreak.php b/platform/www/inc/Parsing/ParserMode/Linebreak.php
new file mode 100644
index 0000000..dd95cc3
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Linebreak.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Linebreak extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addSpecialPattern('\x5C{2}(?:[ \t]|(?=\n))', $mode, 'linebreak');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 140;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Listblock.php b/platform/www/inc/Parsing/ParserMode/Listblock.php
new file mode 100644
index 0000000..eef7627
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Listblock.php
@@ -0,0 +1,44 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Listblock extends AbstractMode
+{
+
+ /**
+ * Listblock constructor.
+ */
+ public function __construct()
+ {
+ global $PARSER_MODES;
+
+ $this->allowedModes = array_merge(
+ $PARSER_MODES['formatting'],
+ $PARSER_MODES['substition'],
+ $PARSER_MODES['disabled'],
+ $PARSER_MODES['protected']
+ );
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addEntryPattern('[ \t]*\n {2,}[\-\*]', $mode, 'listblock');
+ $this->Lexer->addEntryPattern('[ \t]*\n\t{1,}[\-\*]', $mode, 'listblock');
+
+ $this->Lexer->addPattern('\n {2,}[\-\*]', 'listblock');
+ $this->Lexer->addPattern('\n\t{1,}[\-\*]', 'listblock');
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+ $this->Lexer->addExitPattern('\n', 'listblock');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 10;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Media.php b/platform/www/inc/Parsing/ParserMode/Media.php
new file mode 100644
index 0000000..f93f947
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Media.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Media extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ // Word boundaries?
+ $this->Lexer->addSpecialPattern("\{\{(?:[^\}]|(?:\}[^\}]))+\}\}", $mode, 'media');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 320;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/ModeInterface.php b/platform/www/inc/Parsing/ParserMode/ModeInterface.php
new file mode 100644
index 0000000..7cca038
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/ModeInterface.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+/**
+ * Defines a mode (syntax component) in the Parser
+ */
+interface ModeInterface
+{
+ /**
+ * returns a number used to determine in which order modes are added
+ *
+ * @return int;
+ */
+ public function getSort();
+
+ /**
+ * Called before any calls to connectTo
+ *
+ * @return void
+ */
+ public function preConnect();
+
+ /**
+ * Connects the mode
+ *
+ * @param string $mode
+ * @return void
+ */
+ public function connectTo($mode);
+
+ /**
+ * Called after all calls to connectTo
+ *
+ * @return void
+ */
+ public function postConnect();
+
+ /**
+ * Check if given mode is accepted inside this mode
+ *
+ * @param string $mode
+ * @return bool
+ */
+ public function accepts($mode);
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Multiplyentity.php b/platform/www/inc/Parsing/ParserMode/Multiplyentity.php
new file mode 100644
index 0000000..89df136
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Multiplyentity.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+/**
+ * Implements the 640x480 replacement
+ */
+class Multiplyentity extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+
+ $this->Lexer->addSpecialPattern(
+ '(?<=\b)(?:[1-9]|\d{2,})[xX]\d+(?=\b)',
+ $mode,
+ 'multiplyentity'
+ );
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 270;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Nocache.php b/platform/www/inc/Parsing/ParserMode/Nocache.php
new file mode 100644
index 0000000..fa6db83
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Nocache.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Nocache extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addSpecialPattern('~~NOCACHE~~', $mode, 'nocache');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 40;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Notoc.php b/platform/www/inc/Parsing/ParserMode/Notoc.php
new file mode 100644
index 0000000..5956207
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Notoc.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Notoc extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addSpecialPattern('~~NOTOC~~', $mode, 'notoc');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 30;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Php.php b/platform/www/inc/Parsing/ParserMode/Php.php
new file mode 100644
index 0000000..914648b
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Php.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Php extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addEntryPattern('<php>(?=.*</php>)', $mode, 'php');
+ $this->Lexer->addEntryPattern('<PHP>(?=.*</PHP>)', $mode, 'phpblock');
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+ $this->Lexer->addExitPattern('</php>', 'php');
+ $this->Lexer->addExitPattern('</PHP>', 'phpblock');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 180;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Plugin.php b/platform/www/inc/Parsing/ParserMode/Plugin.php
new file mode 100644
index 0000000..c885c60
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Plugin.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+/**
+ * @fixme do we need this anymore or could the syntax plugin inherit directly from abstract mode?
+ */
+abstract class Plugin extends AbstractMode {}
diff --git a/platform/www/inc/Parsing/ParserMode/Preformatted.php b/platform/www/inc/Parsing/ParserMode/Preformatted.php
new file mode 100644
index 0000000..7dfc474
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Preformatted.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Preformatted extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ // Has hard coded awareness of lists...
+ $this->Lexer->addEntryPattern('\n (?![\*\-])', $mode, 'preformatted');
+ $this->Lexer->addEntryPattern('\n\t(?![\*\-])', $mode, 'preformatted');
+
+ // How to effect a sub pattern with the Lexer!
+ $this->Lexer->addPattern('\n ', 'preformatted');
+ $this->Lexer->addPattern('\n\t', 'preformatted');
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+ $this->Lexer->addExitPattern('\n', 'preformatted');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 20;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Quote.php b/platform/www/inc/Parsing/ParserMode/Quote.php
new file mode 100644
index 0000000..65525b2
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Quote.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Quote extends AbstractMode
+{
+
+ /**
+ * Quote constructor.
+ */
+ public function __construct()
+ {
+ global $PARSER_MODES;
+
+ $this->allowedModes = array_merge(
+ $PARSER_MODES['formatting'],
+ $PARSER_MODES['substition'],
+ $PARSER_MODES['disabled'],
+ $PARSER_MODES['protected']
+ );
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addEntryPattern('\n>{1,}', $mode, 'quote');
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+ $this->Lexer->addPattern('\n>{1,}', 'quote');
+ $this->Lexer->addExitPattern('\n', 'quote');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 220;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Quotes.php b/platform/www/inc/Parsing/ParserMode/Quotes.php
new file mode 100644
index 0000000..13db2e6
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Quotes.php
@@ -0,0 +1,51 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Quotes extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ global $conf;
+
+ $ws = '\s/\#~:+=&%@\-\x28\x29\]\[{}><"\''; // whitespace
+ $punc = ';,\.?!';
+
+ if ($conf['typography'] == 2) {
+ $this->Lexer->addSpecialPattern(
+ "(?<=^|[$ws])'(?=[^$ws$punc])",
+ $mode,
+ 'singlequoteopening'
+ );
+ $this->Lexer->addSpecialPattern(
+ "(?<=^|[^$ws]|[$punc])'(?=$|[$ws$punc])",
+ $mode,
+ 'singlequoteclosing'
+ );
+ $this->Lexer->addSpecialPattern(
+ "(?<=^|[^$ws$punc])'(?=$|[^$ws$punc])",
+ $mode,
+ 'apostrophe'
+ );
+ }
+
+ $this->Lexer->addSpecialPattern(
+ "(?<=^|[$ws])\"(?=[^$ws$punc])",
+ $mode,
+ 'doublequoteopening'
+ );
+ $this->Lexer->addSpecialPattern(
+ "\"",
+ $mode,
+ 'doublequoteclosing'
+ );
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 280;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Rss.php b/platform/www/inc/Parsing/ParserMode/Rss.php
new file mode 100644
index 0000000..a62d9b8
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Rss.php
@@ -0,0 +1,19 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Rss extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addSpecialPattern("\{\{rss>[^\}]+\}\}", $mode, 'rss');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 310;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Smiley.php b/platform/www/inc/Parsing/ParserMode/Smiley.php
new file mode 100644
index 0000000..084ccc9
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Smiley.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+use dokuwiki\Parsing\Lexer\Lexer;
+
+class Smiley extends AbstractMode
+{
+ protected $smileys = array();
+ protected $pattern = '';
+
+ /**
+ * Smiley constructor.
+ * @param string[] $smileys
+ */
+ public function __construct($smileys)
+ {
+ $this->smileys = $smileys;
+ }
+
+ /** @inheritdoc */
+ public function preConnect()
+ {
+ if (!count($this->smileys) || $this->pattern != '') return;
+
+ $sep = '';
+ foreach ($this->smileys as $smiley) {
+ $this->pattern .= $sep.'(?<=\W|^)'. Lexer::escape($smiley).'(?=\W|$)';
+ $sep = '|';
+ }
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ if (!count($this->smileys)) return;
+
+ if (strlen($this->pattern) > 0) {
+ $this->Lexer->addSpecialPattern($this->pattern, $mode, 'smiley');
+ }
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 230;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Table.php b/platform/www/inc/Parsing/ParserMode/Table.php
new file mode 100644
index 0000000..b4b5123
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Table.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Table extends AbstractMode
+{
+
+ /**
+ * Table constructor.
+ */
+ public function __construct()
+ {
+ global $PARSER_MODES;
+
+ $this->allowedModes = array_merge(
+ $PARSER_MODES['formatting'],
+ $PARSER_MODES['substition'],
+ $PARSER_MODES['disabled'],
+ $PARSER_MODES['protected']
+ );
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addEntryPattern('[\t ]*\n\^', $mode, 'table');
+ $this->Lexer->addEntryPattern('[\t ]*\n\|', $mode, 'table');
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+ $this->Lexer->addPattern('\n\^', 'table');
+ $this->Lexer->addPattern('\n\|', 'table');
+ $this->Lexer->addPattern('[\t ]*:::[\t ]*(?=[\|\^])', 'table');
+ $this->Lexer->addPattern('[\t ]+', 'table');
+ $this->Lexer->addPattern('\^', 'table');
+ $this->Lexer->addPattern('\|', 'table');
+ $this->Lexer->addExitPattern('\n', 'table');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 60;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Unformatted.php b/platform/www/inc/Parsing/ParserMode/Unformatted.php
new file mode 100644
index 0000000..1bc2826
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Unformatted.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Unformatted extends AbstractMode
+{
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addEntryPattern('<nowiki>(?=.*</nowiki>)', $mode, 'unformatted');
+ $this->Lexer->addEntryPattern('%%(?=.*%%)', $mode, 'unformattedalt');
+ }
+
+ /** @inheritdoc */
+ public function postConnect()
+ {
+ $this->Lexer->addExitPattern('</nowiki>', 'unformatted');
+ $this->Lexer->addExitPattern('%%', 'unformattedalt');
+ $this->Lexer->mapHandler('unformattedalt', 'unformatted');
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 170;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Windowssharelink.php b/platform/www/inc/Parsing/ParserMode/Windowssharelink.php
new file mode 100644
index 0000000..747d4d8
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Windowssharelink.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+class Windowssharelink extends AbstractMode
+{
+
+ protected $pattern;
+
+ /** @inheritdoc */
+ public function preConnect()
+ {
+ $this->pattern = "\\\\\\\\\w+?(?:\\\\[\w\-$]+)+";
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addSpecialPattern(
+ $this->pattern,
+ $mode,
+ 'windowssharelink'
+ );
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 350;
+ }
+}
diff --git a/platform/www/inc/Parsing/ParserMode/Wordblock.php b/platform/www/inc/Parsing/ParserMode/Wordblock.php
new file mode 100644
index 0000000..50b24b2
--- /dev/null
+++ b/platform/www/inc/Parsing/ParserMode/Wordblock.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace dokuwiki\Parsing\ParserMode;
+
+use dokuwiki\Parsing\Lexer\Lexer;
+
+/**
+ * @fixme is this actually used?
+ */
+class Wordblock extends AbstractMode
+{
+ protected $badwords = array();
+ protected $pattern = '';
+
+ /**
+ * Wordblock constructor.
+ * @param $badwords
+ */
+ public function __construct($badwords)
+ {
+ $this->badwords = $badwords;
+ }
+
+ /** @inheritdoc */
+ public function preConnect()
+ {
+
+ if (count($this->badwords) == 0 || $this->pattern != '') {
+ return;
+ }
+
+ $sep = '';
+ foreach ($this->badwords as $badword) {
+ $this->pattern .= $sep.'(?<=\b)(?i)'. Lexer::escape($badword).'(?-i)(?=\b)';
+ $sep = '|';
+ }
+ }
+
+ /** @inheritdoc */
+ public function connectTo($mode)
+ {
+ if (strlen($this->pattern) > 0) {
+ $this->Lexer->addSpecialPattern($this->pattern, $mode, 'wordblock');
+ }
+ }
+
+ /** @inheritdoc */
+ public function getSort()
+ {
+ return 250;
+ }
+}
diff --git a/platform/www/inc/PassHash.php b/platform/www/inc/PassHash.php
new file mode 100644
index 0000000..1189da0
--- /dev/null
+++ b/platform/www/inc/PassHash.php
@@ -0,0 +1,808 @@
+<?php
+// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
+
+namespace dokuwiki;
+
+/**
+ * Password Hashing Class
+ *
+ * This class implements various mechanisms used to hash passwords
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ * @license LGPL2
+ */
+class PassHash {
+ /**
+ * Verifies a cleartext password against a crypted hash
+ *
+ * The method and salt used for the crypted hash is determined automatically,
+ * then the clear text password is crypted using the same method. If both hashs
+ * match true is is returned else false
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ *
+ * @param string $clear Clear-Text password
+ * @param string $hash Hash to compare against
+ * @return bool
+ */
+ public function verify_hash($clear, $hash) {
+ $method = '';
+ $salt = '';
+ $magic = '';
+
+ //determine the used method and salt
+ if (substr($hash, 0, 2) == 'U$') {
+ // This may be an updated password from user_update_7000(). Such hashes
+ // have 'U' added as the first character and need an extra md5().
+ $hash = substr($hash, 1);
+ $clear = md5($clear);
+ }
+ $len = strlen($hash);
+ if(preg_match('/^\$1\$([^\$]{0,8})\$/', $hash, $m)) {
+ $method = 'smd5';
+ $salt = $m[1];
+ $magic = '1';
+ } elseif(preg_match('/^\$apr1\$([^\$]{0,8})\$/', $hash, $m)) {
+ $method = 'apr1';
+ $salt = $m[1];
+ $magic = 'apr1';
+ } elseif(preg_match('/^\$S\$(.{52})$/', $hash, $m)) {
+ $method = 'drupal_sha512';
+ $salt = $m[1];
+ $magic = 'S';
+ } elseif(preg_match('/^\$P\$(.{31})$/', $hash, $m)) {
+ $method = 'pmd5';
+ $salt = $m[1];
+ $magic = 'P';
+ } elseif(preg_match('/^\$H\$(.{31})$/', $hash, $m)) {
+ $method = 'pmd5';
+ $salt = $m[1];
+ $magic = 'H';
+ } elseif(preg_match('/^pbkdf2_(\w+?)\$(\d+)\$(.{12})\$/', $hash, $m)) {
+ $method = 'djangopbkdf2';
+ $magic = array(
+ 'algo' => $m[1],
+ 'iter' => $m[2],
+ );
+ $salt = $m[3];
+ } elseif(preg_match('/^PBKDF2(SHA\d+)\$(\d+)\$([[:xdigit:]]+)\$([[:xdigit:]]+)$/', $hash, $m)) {
+ $method = 'seafilepbkdf2';
+ $magic = array(
+ 'algo' => $m[1],
+ 'iter' => $m[2],
+ );
+ $salt = $m[3];
+ } elseif(preg_match('/^sha1\$(.{5})\$/', $hash, $m)) {
+ $method = 'djangosha1';
+ $salt = $m[1];
+ } elseif(preg_match('/^md5\$(.{5})\$/', $hash, $m)) {
+ $method = 'djangomd5';
+ $salt = $m[1];
+ } elseif(preg_match('/^\$2(a|y)\$(.{2})\$/', $hash, $m)) {
+ $method = 'bcrypt';
+ $salt = $hash;
+ } elseif(substr($hash, 0, 6) == '{SSHA}') {
+ $method = 'ssha';
+ $salt = substr(base64_decode(substr($hash, 6)), 20);
+ } elseif(substr($hash, 0, 6) == '{SMD5}') {
+ $method = 'lsmd5';
+ $salt = substr(base64_decode(substr($hash, 6)), 16);
+ } elseif(preg_match('/^:B:(.+?):.{32}$/', $hash, $m)) {
+ $method = 'mediawiki';
+ $salt = $m[1];
+ } elseif(preg_match('/^\$6\$(rounds=\d+)?\$?(.+?)\$/', $hash, $m)) {
+ $method = 'sha512';
+ $salt = $m[2];
+ $magic = $m[1];
+ } elseif(preg_match('/^\$(argon2id?)/', $hash, $m)) {
+ if(!defined('PASSWORD_'.strtoupper($m[1]))) {
+ throw new \Exception('This PHP installation has no '.strtoupper($m[1]).' support');
+ }
+ return password_verify($clear,$hash);
+ } elseif($len == 32) {
+ $method = 'md5';
+ } elseif($len == 40) {
+ $method = 'sha1';
+ } elseif($len == 16) {
+ $method = 'mysql';
+ } elseif($len == 41 && $hash[0] == '*') {
+ $method = 'my411';
+ } elseif($len == 34) {
+ $method = 'kmd5';
+ $salt = $hash;
+ } else {
+ $method = 'crypt';
+ $salt = substr($hash, 0, 2);
+ }
+
+ //crypt and compare
+ $call = 'hash_'.$method;
+ $newhash = $this->$call($clear, $salt, $magic);
+ if(\hash_equals($newhash, $hash)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Create a random salt
+ *
+ * @param int $len The length of the salt
+ * @return string
+ */
+ public function gen_salt($len = 32) {
+ $salt = '';
+ $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
+ for($i = 0; $i < $len; $i++) {
+ $salt .= $chars[$this->random(0, 61)];
+ }
+ return $salt;
+ }
+
+ /**
+ * Initialize the passed variable with a salt if needed.
+ *
+ * If $salt is not null, the value is kept, but the lenght restriction is
+ * applied (unless, $cut is false).
+ *
+ * @param string|null &$salt The salt, pass null if you want one generated
+ * @param int $len The length of the salt
+ * @param bool $cut Apply length restriction to existing salt?
+ */
+ public function init_salt(&$salt, $len = 32, $cut = true) {
+ if(is_null($salt)) {
+ $salt = $this->gen_salt($len);
+ $cut = true; // for new hashes we alway apply length restriction
+ }
+ if(strlen($salt) > $len && $cut) $salt = substr($salt, 0, $len);
+ }
+
+ // Password hashing methods follow below
+
+ /**
+ * Password hashing method 'smd5'
+ *
+ * Uses salted MD5 hashs. Salt is 8 bytes long.
+ *
+ * The same mechanism is used by Apache's 'apr1' method. This will
+ * fallback to a implementation in pure PHP if MD5 support is not
+ * available in crypt()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author <mikey_nich at hotmail dot com>
+ * @link http://php.net/manual/en/function.crypt.php#73619
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @return string Hashed password
+ */
+ public function hash_smd5($clear, $salt = null) {
+ $this->init_salt($salt, 8);
+
+ if(defined('CRYPT_MD5') && CRYPT_MD5 && $salt !== '') {
+ return crypt($clear, '$1$'.$salt.'$');
+ } else {
+ // Fall back to PHP-only implementation
+ return $this->hash_apr1($clear, $salt, '1');
+ }
+ }
+
+ /**
+ * Password hashing method 'lsmd5'
+ *
+ * Uses salted MD5 hashs. Salt is 8 bytes long.
+ *
+ * This is the format used by LDAP.
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @return string Hashed password
+ */
+ public function hash_lsmd5($clear, $salt = null) {
+ $this->init_salt($salt, 8);
+ return "{SMD5}".base64_encode(md5($clear.$salt, true).$salt);
+ }
+
+ /**
+ * Password hashing method 'apr1'
+ *
+ * Uses salted MD5 hashs. Salt is 8 bytes long.
+ *
+ * This is basically the same as smd1 above, but as used by Apache.
+ *
+ * @author <mikey_nich at hotmail dot com>
+ * @link http://php.net/manual/en/function.crypt.php#73619
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @param string $magic The hash identifier (apr1 or 1)
+ * @return string Hashed password
+ */
+ public function hash_apr1($clear, $salt = null, $magic = 'apr1') {
+ $this->init_salt($salt, 8);
+
+ $len = strlen($clear);
+ $text = $clear.'$'.$magic.'$'.$salt;
+ $bin = pack("H32", md5($clear.$salt.$clear));
+ for($i = $len; $i > 0; $i -= 16) {
+ $text .= substr($bin, 0, min(16, $i));
+ }
+ for($i = $len; $i > 0; $i >>= 1) {
+ $text .= ($i & 1) ? chr(0) : $clear[0];
+ }
+ $bin = pack("H32", md5($text));
+ for($i = 0; $i < 1000; $i++) {
+ $new = ($i & 1) ? $clear : $bin;
+ if($i % 3) $new .= $salt;
+ if($i % 7) $new .= $clear;
+ $new .= ($i & 1) ? $bin : $clear;
+ $bin = pack("H32", md5($new));
+ }
+ $tmp = '';
+ for($i = 0; $i < 5; $i++) {
+ $k = $i + 6;
+ $j = $i + 12;
+ if($j == 16) $j = 5;
+ $tmp = $bin[$i].$bin[$k].$bin[$j].$tmp;
+ }
+ $tmp = chr(0).chr(0).$bin[11].$tmp;
+ $tmp = strtr(
+ strrev(substr(base64_encode($tmp), 2)),
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
+ "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
+ );
+ return '$'.$magic.'$'.$salt.'$'.$tmp;
+ }
+
+ /**
+ * Password hashing method 'md5'
+ *
+ * Uses MD5 hashs.
+ *
+ * @param string $clear The clear text to hash
+ * @return string Hashed password
+ */
+ public function hash_md5($clear) {
+ return md5($clear);
+ }
+
+ /**
+ * Password hashing method 'sha1'
+ *
+ * Uses SHA1 hashs.
+ *
+ * @param string $clear The clear text to hash
+ * @return string Hashed password
+ */
+ public function hash_sha1($clear) {
+ return sha1($clear);
+ }
+
+ /**
+ * Password hashing method 'ssha' as used by LDAP
+ *
+ * Uses salted SHA1 hashs. Salt is 4 bytes long.
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @return string Hashed password
+ */
+ public function hash_ssha($clear, $salt = null) {
+ $this->init_salt($salt, 4);
+ return '{SSHA}'.base64_encode(pack("H*", sha1($clear.$salt)).$salt);
+ }
+
+ /**
+ * Password hashing method 'crypt'
+ *
+ * Uses salted crypt hashs. Salt is 2 bytes long.
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @return string Hashed password
+ */
+ public function hash_crypt($clear, $salt = null) {
+ $this->init_salt($salt, 2);
+ return crypt($clear, $salt);
+ }
+
+ /**
+ * Password hashing method 'mysql'
+ *
+ * This method was used by old MySQL systems
+ *
+ * @link http://php.net/mysql
+ * @author <soren at byu dot edu>
+ * @param string $clear The clear text to hash
+ * @return string Hashed password
+ */
+ public function hash_mysql($clear) {
+ $nr = 0x50305735;
+ $nr2 = 0x12345671;
+ $add = 7;
+ $charArr = preg_split("//", $clear);
+ foreach($charArr as $char) {
+ if(($char == '') || ($char == ' ') || ($char == '\t')) continue;
+ $charVal = ord($char);
+ $nr ^= ((($nr & 63) + $add) * $charVal) + ($nr << 8);
+ $nr2 += ($nr2 << 8) ^ $nr;
+ $add += $charVal;
+ }
+ return sprintf("%08x%08x", ($nr & 0x7fffffff), ($nr2 & 0x7fffffff));
+ }
+
+ /**
+ * Password hashing method 'my411'
+ *
+ * Uses SHA1 hashs. This method is used by MySQL 4.11 and above
+ *
+ * @param string $clear The clear text to hash
+ * @return string Hashed password
+ */
+ public function hash_my411($clear) {
+ return '*'.strtoupper(sha1(pack("H*", sha1($clear))));
+ }
+
+ /**
+ * Password hashing method 'kmd5'
+ *
+ * Uses salted MD5 hashs.
+ *
+ * Salt is 2 bytes long, but stored at position 16, so you need to pass at
+ * least 18 bytes. You can pass the crypted hash as salt.
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @return string Hashed password
+ */
+ public function hash_kmd5($clear, $salt = null) {
+ $this->init_salt($salt);
+
+ $key = substr($salt, 16, 2);
+ $hash1 = strtolower(md5($key.md5($clear)));
+ $hash2 = substr($hash1, 0, 16).$key.substr($hash1, 16);
+ return $hash2;
+ }
+
+ /**
+ * Password stretched hashing wrapper.
+ *
+ * Initial hash is repeatedly rehashed with same password.
+ * Any salted hash algorithm supported by PHP hash() can be used. Salt
+ * is 1+8 bytes long, 1st byte is the iteration count when given. For null
+ * salts $compute is used.
+ *
+ * The actual iteration count is 2 to the power of the given count,
+ * maximum is 30 (-> 2^30 = 1_073_741_824). If a higher one is given,
+ * the function throws an exception.
+ * This iteration count is expected to grow with increasing power of
+ * new computers.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ * @link http://www.openwall.com/phpass/
+ *
+ * @param string $algo The hash algorithm to be used
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @param string $magic The hash identifier (P or H)
+ * @param int $compute The iteration count for new passwords
+ * @throws \Exception
+ * @return string Hashed password
+ */
+ protected function stretched_hash($algo, $clear, $salt = null, $magic = 'P', $compute = 8) {
+ $itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
+ if(is_null($salt)) {
+ $this->init_salt($salt);
+ $salt = $itoa64[$compute].$salt; // prefix iteration count
+ }
+ $iterc = $salt[0]; // pos 0 of salt is log2(iteration count)
+ $iter = strpos($itoa64, $iterc);
+
+ if($iter > 30) {
+ throw new \Exception("Too high iteration count ($iter) in ".
+ __CLASS__.'::'.__FUNCTION__);
+ }
+
+ $iter = 1 << $iter;
+ $salt = substr($salt, 1, 8);
+
+ // iterate
+ $hash = hash($algo, $salt . $clear, TRUE);
+ do {
+ $hash = hash($algo, $hash.$clear, true);
+ } while(--$iter);
+
+ // encode
+ $output = '';
+ $count = strlen($hash);
+ $i = 0;
+ do {
+ $value = ord($hash[$i++]);
+ $output .= $itoa64[$value & 0x3f];
+ if($i < $count)
+ $value |= ord($hash[$i]) << 8;
+ $output .= $itoa64[($value >> 6) & 0x3f];
+ if($i++ >= $count)
+ break;
+ if($i < $count)
+ $value |= ord($hash[$i]) << 16;
+ $output .= $itoa64[($value >> 12) & 0x3f];
+ if($i++ >= $count)
+ break;
+ $output .= $itoa64[($value >> 18) & 0x3f];
+ } while($i < $count);
+
+ return '$'.$magic.'$'.$iterc.$salt.$output;
+ }
+
+ /**
+ * Password hashing method 'pmd5'
+ *
+ * Repeatedly uses salted MD5 hashs. See stretched_hash() for the
+ * details.
+ *
+ *
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ * @link http://www.openwall.com/phpass/
+ * @see PassHash::stretched_hash() for the implementation details.
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @param string $magic The hash identifier (P or H)
+ * @param int $compute The iteration count for new passwords
+ * @throws Exception
+ * @return string Hashed password
+ */
+ public function hash_pmd5($clear, $salt = null, $magic = 'P', $compute = 8) {
+ return $this->stretched_hash('md5', $clear, $salt, $magic, $compute);
+ }
+
+ /**
+ * Password hashing method 'drupal_sha512'
+ *
+ * Implements Drupal salted sha512 hashs. Drupal truncates the hash at 55
+ * characters. See stretched_hash() for the details;
+ *
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ * @link https://api.drupal.org/api/drupal/includes%21password.inc/7.x
+ * @see PassHash::stretched_hash() for the implementation details.
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @param string $magic The hash identifier (S)
+ * @param int $compute The iteration count for new passwords (defautl is drupal 7's)
+ * @throws Exception
+ * @return string Hashed password
+ */
+ public function hash_drupal_sha512($clear, $salt = null, $magic = 'S', $compute = 15) {
+ return substr($this->stretched_hash('sha512', $clear, $salt, $magic, $compute), 0, 55);
+ }
+
+ /**
+ * Alias for hash_pmd5
+ *
+ * @param string $clear
+ * @param null|string $salt
+ * @param string $magic
+ * @param int $compute
+ *
+ * @return string
+ * @throws \Exception
+ */
+ public function hash_hmd5($clear, $salt = null, $magic = 'H', $compute = 8) {
+ return $this->hash_pmd5($clear, $salt, $magic, $compute);
+ }
+
+ /**
+ * Password hashing method 'djangosha1'
+ *
+ * Uses salted SHA1 hashs. Salt is 5 bytes long.
+ * This is used by the Django Python framework
+ *
+ * @link http://docs.djangoproject.com/en/dev/topics/auth/#passwords
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @return string Hashed password
+ */
+ public function hash_djangosha1($clear, $salt = null) {
+ $this->init_salt($salt, 5);
+ return 'sha1$'.$salt.'$'.sha1($salt.$clear);
+ }
+
+ /**
+ * Password hashing method 'djangomd5'
+ *
+ * Uses salted MD5 hashs. Salt is 5 bytes long.
+ * This is used by the Django Python framework
+ *
+ * @link http://docs.djangoproject.com/en/dev/topics/auth/#passwords
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @return string Hashed password
+ */
+ public function hash_djangomd5($clear, $salt = null) {
+ $this->init_salt($salt, 5);
+ return 'md5$'.$salt.'$'.md5($salt.$clear);
+ }
+
+ /**
+ * Password hashing method 'seafilepbkdf2'
+ *
+ * An algorithm and iteration count should be given in the opts array.
+ *
+ * Hash algorithm is the string that is in the password string in seafile
+ * database. It has to be converted to a php algo name.
+ *
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ * @see https://stackoverflow.com/a/23670177
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @param array $opts ('algo' => hash algorithm, 'iter' => iterations)
+ * @return string Hashed password
+ * @throws Exception when PHP is missing support for the method/algo
+ */
+ public function hash_seafilepbkdf2($clear, $salt=null, $opts=array()) {
+ $this->init_salt($salt, 64);
+ if(empty($opts['algo'])) {
+ $prefixalgo='SHA256';
+ } else {
+ $prefixalgo=$opts['algo'];
+ }
+ $algo = strtolower($prefixalgo);
+ if(empty($opts['iter'])) {
+ $iter = 10000;
+ } else {
+ $iter = (int) $opts['iter'];
+ }
+ if(!function_exists('hash_pbkdf2')) {
+ throw new Exception('This PHP installation has no PBKDF2 support');
+ }
+ if(!in_array($algo, hash_algos())) {
+ throw new Exception("This PHP installation has no $algo support");
+ }
+
+ $hash = hash_pbkdf2($algo, $clear, hex2bin($salt), $iter, 0);
+ return "PBKDF2$prefixalgo\$$iter\$$salt\$$hash";
+ }
+
+ /**
+ * Password hashing method 'djangopbkdf2'
+ *
+ * An algorithm and iteration count should be given in the opts array.
+ * Defaults to sha256 and 24000 iterations
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @param array $opts ('algo' => hash algorithm, 'iter' => iterations)
+ * @return string Hashed password
+ * @throws \Exception when PHP is missing support for the method/algo
+ */
+ public function hash_djangopbkdf2($clear, $salt=null, $opts=array()) {
+ $this->init_salt($salt, 12);
+ if(empty($opts['algo'])) {
+ $algo = 'sha256';
+ } else {
+ $algo = $opts['algo'];
+ }
+ if(empty($opts['iter'])) {
+ $iter = 24000;
+ } else {
+ $iter = (int) $opts['iter'];
+ }
+ if(!function_exists('hash_pbkdf2')) {
+ throw new \Exception('This PHP installation has no PBKDF2 support');
+ }
+ if(!in_array($algo, hash_algos())) {
+ throw new \Exception("This PHP installation has no $algo support");
+ }
+
+ $hash = base64_encode(hash_pbkdf2($algo, $clear, $salt, $iter, 0, true));
+ return "pbkdf2_$algo\$$iter\$$salt\$$hash";
+ }
+
+ /**
+ * Alias for djangopbkdf2 defaulting to sha256 as hash algorithm
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @param array $opts ('iter' => iterations)
+ * @return string Hashed password
+ * @throws \Exception when PHP is missing support for the method/algo
+ */
+ public function hash_djangopbkdf2_sha256($clear, $salt=null, $opts=array()) {
+ $opts['algo'] = 'sha256';
+ return $this->hash_djangopbkdf2($clear, $salt, $opts);
+ }
+
+ /**
+ * Alias for djangopbkdf2 defaulting to sha1 as hash algorithm
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @param array $opts ('iter' => iterations)
+ * @return string Hashed password
+ * @throws \Exception when PHP is missing support for the method/algo
+ */
+ public function hash_djangopbkdf2_sha1($clear, $salt=null, $opts=array()) {
+ $opts['algo'] = 'sha1';
+ return $this->hash_djangopbkdf2($clear, $salt, $opts);
+ }
+
+ /**
+ * Passwordhashing method 'bcrypt'
+ *
+ * Uses a modified blowfish algorithm called eksblowfish
+ * This method works on PHP 5.3+ only and will throw an exception
+ * if the needed crypt support isn't available
+ *
+ * A full hash should be given as salt (starting with $a2$) or this
+ * will break. When no salt is given, the iteration count can be set
+ * through the $compute variable.
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @param int $compute The iteration count (between 4 and 31)
+ * @throws \Exception
+ * @return string Hashed password
+ */
+ public function hash_bcrypt($clear, $salt = null, $compute = 10) {
+ if(!defined('CRYPT_BLOWFISH') || CRYPT_BLOWFISH != 1) {
+ throw new \Exception('This PHP installation has no bcrypt support');
+ }
+
+ if(is_null($salt)) {
+ if($compute < 4 || $compute > 31) $compute = 8;
+ $salt = '$2y$'.str_pad($compute, 2, '0', STR_PAD_LEFT).'$'.
+ $this->gen_salt(22);
+ }
+
+ return crypt($clear, $salt);
+ }
+
+ /**
+ * Password hashing method SHA512
+ *
+ * This is only supported on PHP 5.3.2 or higher and will throw an exception if
+ * the needed crypt support is not available
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @param string $magic The rounds for sha512 (for example "rounds=3000"), null for default value
+ * @return string Hashed password
+ * @throws \Exception
+ */
+ public function hash_sha512($clear, $salt = null, $magic = null) {
+ if(!defined('CRYPT_SHA512') || CRYPT_SHA512 != 1) {
+ throw new \Exception('This PHP installation has no SHA512 support');
+ }
+ $this->init_salt($salt, 8, false);
+ if(empty($magic)) {
+ return crypt($clear, '$6$'.$salt.'$');
+ }else{
+ return crypt($clear, '$6$'.$magic.'$'.$salt.'$');
+ }
+ }
+
+ /**
+ * Password hashing method 'mediawiki'
+ *
+ * Uses salted MD5, this is referred to as Method B in MediaWiki docs. Unsalted md5
+ * method 'A' is not supported.
+ *
+ * @link http://www.mediawiki.org/wiki/Manual_talk:User_table#user_password_column
+ *
+ * @param string $clear The clear text to hash
+ * @param string $salt The salt to use, null for random
+ * @return string Hashed password
+ */
+ public function hash_mediawiki($clear, $salt = null) {
+ $this->init_salt($salt, 8, false);
+ return ':B:'.$salt.':'.md5($salt.'-'.md5($clear));
+ }
+
+
+ /**
+ * Password hashing method 'argon2i'
+ *
+ * Uses php's own password_hash function to create argon2i password hash
+ * Default Cost and thread options are used for now.
+ *
+ * @link https://www.php.net/manual/de/function.password-hash.php
+ *
+ * @param string $clear The clear text to hash
+ * @return string Hashed password
+ */
+ public function hash_argon2i($clear) {
+ if(!defined('PASSWORD_ARGON2I')) {
+ throw new \Exception('This PHP installation has no ARGON2I support');
+ }
+ return password_hash($clear,PASSWORD_ARGON2I);
+ }
+
+ /**
+ * Password hashing method 'argon2id'
+ *
+ * Uses php's own password_hash function to create argon2id password hash
+ * Default Cost and thread options are used for now.
+ *
+ * @link https://www.php.net/manual/de/function.password-hash.php
+ *
+ * @param string $clear The clear text to hash
+ * @return string Hashed password
+ */
+ public function hash_argon2id($clear) {
+ if(!defined('PASSWORD_ARGON2ID')) {
+ throw new \Exception('This PHP installation has no ARGON2ID support');
+ }
+ return password_hash($clear,PASSWORD_ARGON2ID);
+ }
+
+ /**
+ * Wraps around native hash_hmac() or reimplents it
+ *
+ * This is not directly used as password hashing method, and thus isn't callable via the
+ * verify_hash() method. It should be used to create signatures and might be used in other
+ * password hashing methods.
+ *
+ * @see hash_hmac()
+ * @author KC Cloyd
+ * @link http://php.net/manual/en/function.hash-hmac.php#93440
+ *
+ * @param string $algo Name of selected hashing algorithm (i.e. "md5", "sha256", "haval160,4",
+ * etc..) See hash_algos() for a list of supported algorithms.
+ * @param string $data Message to be hashed.
+ * @param string $key Shared secret key used for generating the HMAC variant of the message digest.
+ * @param bool $raw_output When set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits.
+ * @return string
+ */
+ public static function hmac($algo, $data, $key, $raw_output = false) {
+ // use native function if available and not in unit test
+ if(function_exists('hash_hmac') && !defined('SIMPLE_TEST')){
+ return hash_hmac($algo, $data, $key, $raw_output);
+ }
+
+ $algo = strtolower($algo);
+ $pack = 'H' . strlen($algo('test'));
+ $size = 64;
+ $opad = str_repeat(chr(0x5C), $size);
+ $ipad = str_repeat(chr(0x36), $size);
+
+ if(strlen($key) > $size) {
+ $key = str_pad(pack($pack, $algo($key)), $size, chr(0x00));
+ } else {
+ $key = str_pad($key, $size, chr(0x00));
+ }
+
+ for($i = 0; $i < strlen($key) - 1; $i++) {
+ $opad[$i] = $opad[$i] ^ $key[$i];
+ $ipad[$i] = $ipad[$i] ^ $key[$i];
+ }
+
+ $output = $algo($opad . pack($pack, $algo($ipad . $data)));
+
+ return ($raw_output) ? pack($pack, $output) : $output;
+ }
+
+ /**
+ * Use a secure random generator
+ *
+ * @param int $min
+ * @param int $max
+ * @return int
+ */
+ protected function random($min, $max){
+ try {
+ return random_int($min, $max);
+ } catch (\Exception $e) {
+ // availability of random source is checked elsewhere in DokuWiki
+ // we demote this to an unchecked runtime exception here
+ throw new \RuntimeException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+}
diff --git a/platform/www/inc/Remote/AccessDeniedException.php b/platform/www/inc/Remote/AccessDeniedException.php
new file mode 100644
index 0000000..65f6689
--- /dev/null
+++ b/platform/www/inc/Remote/AccessDeniedException.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace dokuwiki\Remote;
+
+/**
+ * Class AccessDeniedException
+ */
+class AccessDeniedException extends RemoteException
+{
+}
diff --git a/platform/www/inc/Remote/Api.php b/platform/www/inc/Remote/Api.php
new file mode 100644
index 0000000..3b52656
--- /dev/null
+++ b/platform/www/inc/Remote/Api.php
@@ -0,0 +1,410 @@
+<?php
+
+namespace dokuwiki\Remote;
+
+use dokuwiki\Extension\Event;
+use dokuwiki\Extension\RemotePlugin;
+
+/**
+ * This class provides information about remote access to the wiki.
+ *
+ * == Types of methods ==
+ * There are two types of remote methods. The first is the core methods.
+ * These are always available and provided by dokuwiki.
+ * The other is plugin methods. These are provided by remote plugins.
+ *
+ * == Information structure ==
+ * The information about methods will be given in an array with the following structure:
+ * array(
+ * 'method.remoteName' => array(
+ * 'args' => array(
+ * 'type eg. string|int|...|date|file',
+ * )
+ * 'name' => 'method name in class',
+ * 'return' => 'type',
+ * 'public' => 1/0 - method bypass default group check (used by login)
+ * ['doc' = 'method documentation'],
+ * )
+ * )
+ *
+ * plugin names are formed the following:
+ * core methods begin by a 'dokuwiki' or 'wiki' followed by a . and the method name itself.
+ * i.e.: dokuwiki.version or wiki.getPage
+ *
+ * plugin methods are formed like 'plugin.<plugin name>.<method name>'.
+ * i.e.: plugin.clock.getTime or plugin.clock_gmt.getTime
+ */
+class Api
+{
+
+ /**
+ * @var ApiCore
+ */
+ private $coreMethods = null;
+
+ /**
+ * @var array remote methods provided by dokuwiki plugins - will be filled lazy via
+ * {@see dokuwiki\Remote\RemoteAPI#getPluginMethods}
+ */
+ private $pluginMethods = null;
+
+ /**
+ * @var array contains custom calls to the api. Plugins can use the XML_CALL_REGISTER event.
+ * The data inside is 'custom.call.something' => array('plugin name', 'remote method name')
+ *
+ * The remote method name is the same as in the remote name returned by _getMethods().
+ */
+ private $pluginCustomCalls = null;
+
+ private $dateTransformation;
+ private $fileTransformation;
+
+ /**
+ * constructor
+ */
+ public function __construct()
+ {
+ $this->dateTransformation = array($this, 'dummyTransformation');
+ $this->fileTransformation = array($this, 'dummyTransformation');
+ }
+
+ /**
+ * Get all available methods with remote access.
+ *
+ * @return array with information to all available methods
+ * @throws RemoteException
+ */
+ public function getMethods()
+ {
+ return array_merge($this->getCoreMethods(), $this->getPluginMethods());
+ }
+
+ /**
+ * Call a method via remote api.
+ *
+ * @param string $method name of the method to call.
+ * @param array $args arguments to pass to the given method
+ * @return mixed result of method call, must be a primitive type.
+ * @throws RemoteException
+ */
+ public function call($method, $args = array())
+ {
+ if ($args === null) {
+ $args = array();
+ }
+ list($type, $pluginName, /* $call */) = explode('.', $method, 3);
+ if ($type === 'plugin') {
+ return $this->callPlugin($pluginName, $method, $args);
+ }
+ if ($this->coreMethodExist($method)) {
+ return $this->callCoreMethod($method, $args);
+ }
+ return $this->callCustomCallPlugin($method, $args);
+ }
+
+ /**
+ * Check existance of core methods
+ *
+ * @param string $name name of the method
+ * @return bool if method exists
+ */
+ private function coreMethodExist($name)
+ {
+ $coreMethods = $this->getCoreMethods();
+ return array_key_exists($name, $coreMethods);
+ }
+
+ /**
+ * Try to call custom methods provided by plugins
+ *
+ * @param string $method name of method
+ * @param array $args
+ * @return mixed
+ * @throws RemoteException if method not exists
+ */
+ private function callCustomCallPlugin($method, $args)
+ {
+ $customCalls = $this->getCustomCallPlugins();
+ if (!array_key_exists($method, $customCalls)) {
+ throw new RemoteException('Method does not exist', -32603);
+ }
+ $customCall = $customCalls[$method];
+ return $this->callPlugin($customCall[0], $customCall[1], $args);
+ }
+
+ /**
+ * Returns plugin calls that are registered via RPC_CALL_ADD action
+ *
+ * @return array with pairs of custom plugin calls
+ * @triggers RPC_CALL_ADD
+ */
+ private function getCustomCallPlugins()
+ {
+ if ($this->pluginCustomCalls === null) {
+ $data = array();
+ Event::createAndTrigger('RPC_CALL_ADD', $data);
+ $this->pluginCustomCalls = $data;
+ }
+ return $this->pluginCustomCalls;
+ }
+
+ /**
+ * Call a plugin method
+ *
+ * @param string $pluginName
+ * @param string $method method name
+ * @param array $args
+ * @return mixed return of custom method
+ * @throws RemoteException
+ */
+ private function callPlugin($pluginName, $method, $args)
+ {
+ $plugin = plugin_load('remote', $pluginName);
+ $methods = $this->getPluginMethods();
+ if (!$plugin) {
+ throw new RemoteException('Method does not exist', -32603);
+ }
+ $this->checkAccess($methods[$method]);
+ $name = $this->getMethodName($methods, $method);
+ try {
+ set_error_handler(array($this, "argumentWarningHandler"), E_WARNING); // for PHP <7.1
+ return call_user_func_array(array($plugin, $name), $args);
+ } catch (\ArgumentCountError $th) {
+ throw new RemoteException('Method does not exist - wrong parameter count.', -32603);
+ } finally {
+ restore_error_handler();
+ }
+ }
+
+ /**
+ * Call a core method
+ *
+ * @param string $method name of method
+ * @param array $args
+ * @return mixed
+ * @throws RemoteException if method not exist
+ */
+ private function callCoreMethod($method, $args)
+ {
+ $coreMethods = $this->getCoreMethods();
+ $this->checkAccess($coreMethods[$method]);
+ if (!isset($coreMethods[$method])) {
+ throw new RemoteException('Method does not exist', -32603);
+ }
+ $this->checkArgumentLength($coreMethods[$method], $args);
+ try {
+ set_error_handler(array($this, "argumentWarningHandler"), E_WARNING); // for PHP <7.1
+ return call_user_func_array(array($this->coreMethods, $this->getMethodName($coreMethods, $method)), $args);
+ } catch (\ArgumentCountError $th) {
+ throw new RemoteException('Method does not exist - wrong parameter count.', -32603);
+ } finally {
+ restore_error_handler();
+ }
+ }
+
+ /**
+ * Check if access should be checked
+ *
+ * @param array $methodMeta data about the method
+ * @throws AccessDeniedException
+ */
+ private function checkAccess($methodMeta)
+ {
+ if (!isset($methodMeta['public'])) {
+ $this->forceAccess();
+ } else {
+ if ($methodMeta['public'] == '0') {
+ $this->forceAccess();
+ }
+ }
+ }
+
+ /**
+ * Check the number of parameters
+ *
+ * @param array $methodMeta data about the method
+ * @param array $args
+ * @throws RemoteException if wrong parameter count
+ */
+ private function checkArgumentLength($methodMeta, $args)
+ {
+ if (count($methodMeta['args']) < count($args)) {
+ throw new RemoteException('Method does not exist - wrong parameter count.', -32603);
+ }
+ }
+
+ /**
+ * Determine the name of the real method
+ *
+ * @param array $methodMeta list of data of the methods
+ * @param string $method name of method
+ * @return string
+ */
+ private function getMethodName($methodMeta, $method)
+ {
+ if (isset($methodMeta[$method]['name'])) {
+ return $methodMeta[$method]['name'];
+ }
+ $method = explode('.', $method);
+ return $method[count($method) - 1];
+ }
+
+ /**
+ * Perform access check for current user
+ *
+ * @return bool true if the current user has access to remote api.
+ * @throws AccessDeniedException If remote access disabled
+ */
+ public function hasAccess()
+ {
+ global $conf;
+ global $USERINFO;
+ /** @var \dokuwiki\Input\Input $INPUT */
+ global $INPUT;
+
+ if (!$conf['remote']) {
+ throw new AccessDeniedException('server error. RPC server not enabled.', -32604);
+ }
+ if (trim($conf['remoteuser']) == '!!not set!!') {
+ return false;
+ }
+ if (!$conf['useacl']) {
+ return true;
+ }
+ if (trim($conf['remoteuser']) == '') {
+ return true;
+ }
+
+ return auth_isMember($conf['remoteuser'], $INPUT->server->str('REMOTE_USER'), (array) $USERINFO['grps']);
+ }
+
+ /**
+ * Requests access
+ *
+ * @return void
+ * @throws AccessDeniedException On denied access.
+ */
+ public function forceAccess()
+ {
+ if (!$this->hasAccess()) {
+ throw new AccessDeniedException('server error. not authorized to call method', -32604);
+ }
+ }
+
+ /**
+ * Collects all the methods of the enabled Remote Plugins
+ *
+ * @return array all plugin methods.
+ * @throws RemoteException if not implemented
+ */
+ public function getPluginMethods()
+ {
+ if ($this->pluginMethods === null) {
+ $this->pluginMethods = array();
+ $plugins = plugin_list('remote');
+
+ foreach ($plugins as $pluginName) {
+ /** @var RemotePlugin $plugin */
+ $plugin = plugin_load('remote', $pluginName);
+ if (!is_subclass_of($plugin, 'dokuwiki\Extension\RemotePlugin')) {
+ throw new RemoteException(
+ "Plugin $pluginName does not implement dokuwiki\Plugin\DokuWiki_Remote_Plugin"
+ );
+ }
+
+ try {
+ $methods = $plugin->_getMethods();
+ } catch (\ReflectionException $e) {
+ throw new RemoteException('Automatic aggregation of available remote methods failed', 0, $e);
+ }
+
+ foreach ($methods as $method => $meta) {
+ $this->pluginMethods["plugin.$pluginName.$method"] = $meta;
+ }
+ }
+ }
+ return $this->pluginMethods;
+ }
+
+ /**
+ * Collects all the core methods
+ *
+ * @param ApiCore $apiCore this parameter is used for testing. Here you can pass a non-default RemoteAPICore
+ * instance. (for mocking)
+ * @return array all core methods.
+ */
+ public function getCoreMethods($apiCore = null)
+ {
+ if ($this->coreMethods === null) {
+ if ($apiCore === null) {
+ $this->coreMethods = new ApiCore($this);
+ } else {
+ $this->coreMethods = $apiCore;
+ }
+ }
+ return $this->coreMethods->__getRemoteInfo();
+ }
+
+ /**
+ * Transform file to xml
+ *
+ * @param mixed $data
+ * @return mixed
+ */
+ public function toFile($data)
+ {
+ return call_user_func($this->fileTransformation, $data);
+ }
+
+ /**
+ * Transform date to xml
+ *
+ * @param mixed $data
+ * @return mixed
+ */
+ public function toDate($data)
+ {
+ return call_user_func($this->dateTransformation, $data);
+ }
+
+ /**
+ * A simple transformation
+ *
+ * @param mixed $data
+ * @return mixed
+ */
+ public function dummyTransformation($data)
+ {
+ return $data;
+ }
+
+ /**
+ * Set the transformer function
+ *
+ * @param callback $dateTransformation
+ */
+ public function setDateTransformation($dateTransformation)
+ {
+ $this->dateTransformation = $dateTransformation;
+ }
+
+ /**
+ * Set the transformer function
+ *
+ * @param callback $fileTransformation
+ */
+ public function setFileTransformation($fileTransformation)
+ {
+ $this->fileTransformation = $fileTransformation;
+ }
+
+ /**
+ * The error handler that catches argument-related warnings
+ */
+ public function argumentWarningHandler($errno, $errstr)
+ {
+ if (substr($errstr, 0, 17) == 'Missing argument ') {
+ throw new RemoteException('Method does not exist - wrong parameter count.', -32603);
+ }
+ }
+}
diff --git a/platform/www/inc/Remote/ApiCore.php b/platform/www/inc/Remote/ApiCore.php
new file mode 100644
index 0000000..3aa7861
--- /dev/null
+++ b/platform/www/inc/Remote/ApiCore.php
@@ -0,0 +1,1025 @@
+<?php
+
+namespace dokuwiki\Remote;
+
+use Doku_Renderer_xhtml;
+use dokuwiki\ChangeLog\MediaChangeLog;
+use dokuwiki\ChangeLog\PageChangeLog;
+use dokuwiki\Extension\Event;
+
+define('DOKU_API_VERSION', 10);
+
+/**
+ * Provides the core methods for the remote API.
+ * The methods are ordered in 'wiki.<method>' and 'dokuwiki.<method>' namespaces
+ */
+class ApiCore
+{
+ /** @var int Increased whenever the API is changed */
+ const API_VERSION = 10;
+
+
+ /** @var Api */
+ private $api;
+
+ /**
+ * @param Api $api
+ */
+ public function __construct(Api $api)
+ {
+ $this->api = $api;
+ }
+
+ /**
+ * Returns details about the core methods
+ *
+ * @return array
+ */
+ public function __getRemoteInfo()
+ {
+ return array(
+ 'dokuwiki.getVersion' => array(
+ 'args' => array(),
+ 'return' => 'string',
+ 'doc' => 'Returns the running DokuWiki version.'
+ ), 'dokuwiki.login' => array(
+ 'args' => array('string', 'string'),
+ 'return' => 'int',
+ 'doc' => 'Tries to login with the given credentials and sets auth cookies.',
+ 'public' => '1'
+ ), 'dokuwiki.logoff' => array(
+ 'args' => array(),
+ 'return' => 'int',
+ 'doc' => 'Tries to logoff by expiring auth cookies and the associated PHP session.'
+ ), 'dokuwiki.getPagelist' => array(
+ 'args' => array('string', 'array'),
+ 'return' => 'array',
+ 'doc' => 'List all pages within the given namespace.',
+ 'name' => 'readNamespace'
+ ), 'dokuwiki.search' => array(
+ 'args' => array('string'),
+ 'return' => 'array',
+ 'doc' => 'Perform a fulltext search and return a list of matching pages'
+ ), 'dokuwiki.getTime' => array(
+ 'args' => array(),
+ 'return' => 'int',
+ 'doc' => 'Returns the current time at the remote wiki server as Unix timestamp.',
+ ), 'dokuwiki.setLocks' => array(
+ 'args' => array('array'),
+ 'return' => 'array',
+ 'doc' => 'Lock or unlock pages.'
+ ), 'dokuwiki.getTitle' => array(
+ 'args' => array(),
+ 'return' => 'string',
+ 'doc' => 'Returns the wiki title.',
+ 'public' => '1'
+ ), 'dokuwiki.appendPage' => array(
+ 'args' => array('string', 'string', 'array'),
+ 'return' => 'bool',
+ 'doc' => 'Append text to a wiki page.'
+ ), 'dokuwiki.deleteUsers' => array(
+ 'args' => array('array'),
+ 'return' => 'bool',
+ 'doc' => 'Remove one or more users from the list of registered users.'
+ ), 'wiki.getPage' => array(
+ 'args' => array('string'),
+ 'return' => 'string',
+ 'doc' => 'Get the raw Wiki text of page, latest version.',
+ 'name' => 'rawPage',
+ ), 'wiki.getPageVersion' => array(
+ 'args' => array('string', 'int'),
+ 'name' => 'rawPage',
+ 'return' => 'string',
+ 'doc' => 'Return a raw wiki page'
+ ), 'wiki.getPageHTML' => array(
+ 'args' => array('string'),
+ 'return' => 'string',
+ 'doc' => 'Return page in rendered HTML, latest version.',
+ 'name' => 'htmlPage'
+ ), 'wiki.getPageHTMLVersion' => array(
+ 'args' => array('string', 'int'),
+ 'return' => 'string',
+ 'doc' => 'Return page in rendered HTML.',
+ 'name' => 'htmlPage'
+ ), 'wiki.getAllPages' => array(
+ 'args' => array(),
+ 'return' => 'array',
+ 'doc' => 'Returns a list of all pages. The result is an array of utf8 pagenames.',
+ 'name' => 'listPages'
+ ), 'wiki.getAttachments' => array(
+ 'args' => array('string', 'array'),
+ 'return' => 'array',
+ 'doc' => 'Returns a list of all media files.',
+ 'name' => 'listAttachments'
+ ), 'wiki.getBackLinks' => array(
+ 'args' => array('string'),
+ 'return' => 'array',
+ 'doc' => 'Returns the pages that link to this page.',
+ 'name' => 'listBackLinks'
+ ), 'wiki.getPageInfo' => array(
+ 'args' => array('string'),
+ 'return' => 'array',
+ 'doc' => 'Returns a struct with info about the page, latest version.',
+ 'name' => 'pageInfo'
+ ), 'wiki.getPageInfoVersion' => array(
+ 'args' => array('string', 'int'),
+ 'return' => 'array',
+ 'doc' => 'Returns a struct with info about the page.',
+ 'name' => 'pageInfo'
+ ), 'wiki.getPageVersions' => array(
+ 'args' => array('string', 'int'),
+ 'return' => 'array',
+ 'doc' => 'Returns the available revisions of the page.',
+ 'name' => 'pageVersions'
+ ), 'wiki.putPage' => array(
+ 'args' => array('string', 'string', 'array'),
+ 'return' => 'bool',
+ 'doc' => 'Saves a wiki page.'
+ ), 'wiki.listLinks' => array(
+ 'args' => array('string'),
+ 'return' => 'array',
+ 'doc' => 'Lists all links contained in a wiki page.'
+ ), 'wiki.getRecentChanges' => array(
+ 'args' => array('int'),
+ 'return' => 'array',
+ 'Returns a struct about all recent changes since given timestamp.'
+ ), 'wiki.getRecentMediaChanges' => array(
+ 'args' => array('int'),
+ 'return' => 'array',
+ 'Returns a struct about all recent media changes since given timestamp.'
+ ), 'wiki.aclCheck' => array(
+ 'args' => array('string', 'string', 'array'),
+ 'return' => 'int',
+ 'doc' => 'Returns the permissions of a given wiki page. By default, for current user/groups'
+ ), 'wiki.putAttachment' => array(
+ 'args' => array('string', 'file', 'array'),
+ 'return' => 'array',
+ 'doc' => 'Upload a file to the wiki.'
+ ), 'wiki.deleteAttachment' => array(
+ 'args' => array('string'),
+ 'return' => 'int',
+ 'doc' => 'Delete a file from the wiki.'
+ ), 'wiki.getAttachment' => array(
+ 'args' => array('string'),
+ 'doc' => 'Return a media file',
+ 'return' => 'file',
+ 'name' => 'getAttachment',
+ ), 'wiki.getAttachmentInfo' => array(
+ 'args' => array('string'),
+ 'return' => 'array',
+ 'doc' => 'Returns a struct with info about the attachment.'
+ ), 'dokuwiki.getXMLRPCAPIVersion' => array(
+ 'args' => array(),
+ 'name' => 'getAPIVersion',
+ 'return' => 'int',
+ 'doc' => 'Returns the XMLRPC API version.',
+ 'public' => '1',
+ ), 'wiki.getRPCVersionSupported' => array(
+ 'args' => array(),
+ 'name' => 'wikiRpcVersion',
+ 'return' => 'int',
+ 'doc' => 'Returns 2 with the supported RPC API version.',
+ 'public' => '1'
+ ),
+
+ );
+ }
+
+ /**
+ * @return string
+ */
+ public function getVersion()
+ {
+ return getVersion();
+ }
+
+ /**
+ * @return int unix timestamp
+ */
+ public function getTime()
+ {
+ return time();
+ }
+
+ /**
+ * Return a raw wiki page
+ *
+ * @param string $id wiki page id
+ * @param int|string $rev revision timestamp of the page or empty string
+ * @return string page text.
+ * @throws AccessDeniedException if no permission for page
+ */
+ public function rawPage($id, $rev = '')
+ {
+ $id = $this->resolvePageId($id);
+ if (auth_quickaclcheck($id) < AUTH_READ) {
+ throw new AccessDeniedException('You are not allowed to read this file', 111);
+ }
+ $text = rawWiki($id, $rev);
+ if (!$text) {
+ return pageTemplate($id);
+ } else {
+ return $text;
+ }
+ }
+
+ /**
+ * Return a media file
+ *
+ * @author Gina Haeussge <osd@foosel.net>
+ *
+ * @param string $id file id
+ * @return mixed media file
+ * @throws AccessDeniedException no permission for media
+ * @throws RemoteException not exist
+ */
+ public function getAttachment($id)
+ {
+ $id = cleanID($id);
+ if (auth_quickaclcheck(getNS($id) . ':*') < AUTH_READ) {
+ throw new AccessDeniedException('You are not allowed to read this file', 211);
+ }
+
+ $file = mediaFN($id);
+ if (!@ file_exists($file)) {
+ throw new RemoteException('The requested file does not exist', 221);
+ }
+
+ $data = io_readFile($file, false);
+ return $this->api->toFile($data);
+ }
+
+ /**
+ * Return info about a media file
+ *
+ * @author Gina Haeussge <osd@foosel.net>
+ *
+ * @param string $id page id
+ * @return array
+ */
+ public function getAttachmentInfo($id)
+ {
+ $id = cleanID($id);
+ $info = array(
+ 'lastModified' => $this->api->toDate(0),
+ 'size' => 0,
+ );
+
+ $file = mediaFN($id);
+ if (auth_quickaclcheck(getNS($id) . ':*') >= AUTH_READ) {
+ if (file_exists($file)) {
+ $info['lastModified'] = $this->api->toDate(filemtime($file));
+ $info['size'] = filesize($file);
+ } else {
+ //Is it deleted media with changelog?
+ $medialog = new MediaChangeLog($id);
+ $revisions = $medialog->getRevisions(0, 1);
+ if (!empty($revisions)) {
+ $info['lastModified'] = $this->api->toDate($revisions[0]);
+ }
+ }
+ }
+
+ return $info;
+ }
+
+ /**
+ * Return a wiki page rendered to html
+ *
+ * @param string $id page id
+ * @param string|int $rev revision timestamp or empty string
+ * @return null|string html
+ * @throws AccessDeniedException no access to page
+ */
+ public function htmlPage($id, $rev = '')
+ {
+ $id = $this->resolvePageId($id);
+ if (auth_quickaclcheck($id) < AUTH_READ) {
+ throw new AccessDeniedException('You are not allowed to read this page', 111);
+ }
+ return p_wiki_xhtml($id, $rev, false);
+ }
+
+ /**
+ * List all pages - we use the indexer list here
+ *
+ * @return array
+ */
+ public function listPages()
+ {
+ $list = array();
+ $pages = idx_get_indexer()->getPages();
+ $pages = array_filter(array_filter($pages, 'isVisiblePage'), 'page_exists');
+
+ foreach (array_keys($pages) as $idx) {
+ $perm = auth_quickaclcheck($pages[$idx]);
+ if ($perm < AUTH_READ) {
+ continue;
+ }
+ $page = array();
+ $page['id'] = trim($pages[$idx]);
+ $page['perms'] = $perm;
+ $page['size'] = @filesize(wikiFN($pages[$idx]));
+ $page['lastModified'] = $this->api->toDate(@filemtime(wikiFN($pages[$idx])));
+ $list[] = $page;
+ }
+
+ return $list;
+ }
+
+ /**
+ * List all pages in the given namespace (and below)
+ *
+ * @param string $ns
+ * @param array $opts
+ * $opts['depth'] recursion level, 0 for all
+ * $opts['hash'] do md5 sum of content?
+ * @return array
+ */
+ public function readNamespace($ns, $opts = array())
+ {
+ global $conf;
+
+ if (!is_array($opts)) $opts = array();
+
+ $ns = cleanID($ns);
+ $dir = utf8_encodeFN(str_replace(':', '/', $ns));
+ $data = array();
+ $opts['skipacl'] = 0; // no ACL skipping for XMLRPC
+ search($data, $conf['datadir'], 'search_allpages', $opts, $dir);
+ return $data;
+ }
+
+ /**
+ * List all pages in the given namespace (and below)
+ *
+ * @param string $query
+ * @return array
+ */
+ public function search($query)
+ {
+ $regex = array();
+ $data = ft_pageSearch($query, $regex);
+ $pages = array();
+
+ // prepare additional data
+ $idx = 0;
+ foreach ($data as $id => $score) {
+ $file = wikiFN($id);
+
+ if ($idx < FT_SNIPPET_NUMBER) {
+ $snippet = ft_snippet($id, $regex);
+ $idx++;
+ } else {
+ $snippet = '';
+ }
+
+ $pages[] = array(
+ 'id' => $id,
+ 'score' => intval($score),
+ 'rev' => filemtime($file),
+ 'mtime' => filemtime($file),
+ 'size' => filesize($file),
+ 'snippet' => $snippet,
+ 'title' => useHeading('navigation') ? p_get_first_heading($id) : $id
+ );
+ }
+ return $pages;
+ }
+
+ /**
+ * Returns the wiki title.
+ *
+ * @return string
+ */
+ public function getTitle()
+ {
+ global $conf;
+ return $conf['title'];
+ }
+
+ /**
+ * List all media files.
+ *
+ * Available options are 'recursive' for also including the subnamespaces
+ * in the listing, and 'pattern' for filtering the returned files against
+ * a regular expression matching their name.
+ *
+ * @author Gina Haeussge <osd@foosel.net>
+ *
+ * @param string $ns
+ * @param array $options
+ * $options['depth'] recursion level, 0 for all
+ * $options['showmsg'] shows message if invalid media id is used
+ * $options['pattern'] check given pattern
+ * $options['hash'] add hashes to result list
+ * @return array
+ * @throws AccessDeniedException no access to the media files
+ */
+ public function listAttachments($ns, $options = array())
+ {
+ global $conf;
+
+ $ns = cleanID($ns);
+
+ if (!is_array($options)) $options = array();
+ $options['skipacl'] = 0; // no ACL skipping for XMLRPC
+
+ if (auth_quickaclcheck($ns . ':*') >= AUTH_READ) {
+ $dir = utf8_encodeFN(str_replace(':', '/', $ns));
+
+ $data = array();
+ search($data, $conf['mediadir'], 'search_media', $options, $dir);
+ $len = count($data);
+ if (!$len) return array();
+
+ for ($i = 0; $i < $len; $i++) {
+ unset($data[$i]['meta']);
+ $data[$i]['perms'] = $data[$i]['perm'];
+ unset($data[$i]['perm']);
+ $data[$i]['lastModified'] = $this->api->toDate($data[$i]['mtime']);
+ }
+ return $data;
+ } else {
+ throw new AccessDeniedException('You are not allowed to list media files.', 215);
+ }
+ }
+
+ /**
+ * Return a list of backlinks
+ *
+ * @param string $id page id
+ * @return array
+ */
+ public function listBackLinks($id)
+ {
+ return ft_backlinks($this->resolvePageId($id));
+ }
+
+ /**
+ * Return some basic data about a page
+ *
+ * @param string $id page id
+ * @param string|int $rev revision timestamp or empty string
+ * @return array
+ * @throws AccessDeniedException no access for page
+ * @throws RemoteException page not exist
+ */
+ public function pageInfo($id, $rev = '')
+ {
+ $id = $this->resolvePageId($id);
+ if (auth_quickaclcheck($id) < AUTH_READ) {
+ throw new AccessDeniedException('You are not allowed to read this page', 111);
+ }
+ $file = wikiFN($id, $rev);
+ $time = @filemtime($file);
+ if (!$time) {
+ throw new RemoteException('The requested page does not exist', 121);
+ }
+
+ // set revision to current version if empty, use revision otherwise
+ // as the timestamps of old files are not necessarily correct
+ if ($rev === '') {
+ $rev = $time;
+ }
+
+ $pagelog = new PageChangeLog($id, 1024);
+ $info = $pagelog->getRevisionInfo($rev);
+
+ $data = array(
+ 'name' => $id,
+ 'lastModified' => $this->api->toDate($rev),
+ 'author' => is_array($info) ? (($info['user']) ? $info['user'] : $info['ip']) : null,
+ 'version' => $rev
+ );
+
+ return ($data);
+ }
+
+ /**
+ * Save a wiki page
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param string $id page id
+ * @param string $text wiki text
+ * @param array $params parameters: summary, minor edit
+ * @return bool
+ * @throws AccessDeniedException no write access for page
+ * @throws RemoteException no id, empty new page or locked
+ */
+ public function putPage($id, $text, $params = array())
+ {
+ global $TEXT;
+ global $lang;
+
+ $id = $this->resolvePageId($id);
+ $TEXT = cleanText($text);
+ $sum = $params['sum'];
+ $minor = $params['minor'];
+
+ if (empty($id)) {
+ throw new RemoteException('Empty page ID', 131);
+ }
+
+ if (!page_exists($id) && trim($TEXT) == '') {
+ throw new RemoteException('Refusing to write an empty new wiki page', 132);
+ }
+
+ if (auth_quickaclcheck($id) < AUTH_EDIT) {
+ throw new AccessDeniedException('You are not allowed to edit this page', 112);
+ }
+
+ // Check, if page is locked
+ if (checklock($id)) {
+ throw new RemoteException('The page is currently locked', 133);
+ }
+
+ // SPAM check
+ if (checkwordblock()) {
+ throw new RemoteException('Positive wordblock check', 134);
+ }
+
+ // autoset summary on new pages
+ if (!page_exists($id) && empty($sum)) {
+ $sum = $lang['created'];
+ }
+
+ // autoset summary on deleted pages
+ if (page_exists($id) && empty($TEXT) && empty($sum)) {
+ $sum = $lang['deleted'];
+ }
+
+ lock($id);
+
+ saveWikiText($id, $TEXT, $sum, $minor);
+
+ unlock($id);
+
+ // run the indexer if page wasn't indexed yet
+ idx_addPage($id);
+
+ return true;
+ }
+
+ /**
+ * Appends text to a wiki page.
+ *
+ * @param string $id page id
+ * @param string $text wiki text
+ * @param array $params such as summary,minor
+ * @return bool|string
+ * @throws RemoteException
+ */
+ public function appendPage($id, $text, $params = array())
+ {
+ $currentpage = $this->rawPage($id);
+ if (!is_string($currentpage)) {
+ return $currentpage;
+ }
+ return $this->putPage($id, $currentpage . $text, $params);
+ }
+
+ /**
+ * Remove one or more users from the list of registered users
+ *
+ * @param string[] $usernames List of usernames to remove
+ *
+ * @return bool
+ *
+ * @throws AccessDeniedException
+ */
+ public function deleteUsers($usernames)
+ {
+ if (!auth_isadmin()) {
+ throw new AccessDeniedException('Only admins are allowed to delete users', 114);
+ }
+ /** @var \dokuwiki\Extension\AuthPlugin $auth */
+ global $auth;
+ return (bool)$auth->triggerUserMod('delete', array($usernames));
+ }
+
+ /**
+ * Uploads a file to the wiki.
+ *
+ * Michael Klier <chi@chimeric.de>
+ *
+ * @param string $id page id
+ * @param string $file
+ * @param array $params such as overwrite
+ * @return false|string
+ * @throws RemoteException
+ */
+ public function putAttachment($id, $file, $params = array())
+ {
+ $id = cleanID($id);
+ $auth = auth_quickaclcheck(getNS($id) . ':*');
+
+ if (!isset($id)) {
+ throw new RemoteException('Filename not given.', 231);
+ }
+
+ global $conf;
+
+ $ftmp = $conf['tmpdir'] . '/' . md5($id . clientIP());
+
+ // save temporary file
+ @unlink($ftmp);
+ io_saveFile($ftmp, $file);
+
+ $res = media_save(array('name' => $ftmp), $id, $params['ow'], $auth, 'rename');
+ if (is_array($res)) {
+ throw new RemoteException($res[0], -$res[1]);
+ } else {
+ return $res;
+ }
+ }
+
+ /**
+ * Deletes a file from the wiki.
+ *
+ * @author Gina Haeussge <osd@foosel.net>
+ *
+ * @param string $id page id
+ * @return int
+ * @throws AccessDeniedException no permissions
+ * @throws RemoteException file in use or not deleted
+ */
+ public function deleteAttachment($id)
+ {
+ $id = cleanID($id);
+ $auth = auth_quickaclcheck(getNS($id) . ':*');
+ $res = media_delete($id, $auth);
+ if ($res & DOKU_MEDIA_DELETED) {
+ return 0;
+ } elseif ($res & DOKU_MEDIA_NOT_AUTH) {
+ throw new AccessDeniedException('You don\'t have permissions to delete files.', 212);
+ } elseif ($res & DOKU_MEDIA_INUSE) {
+ throw new RemoteException('File is still referenced', 232);
+ } else {
+ throw new RemoteException('Could not delete file', 233);
+ }
+ }
+
+ /**
+ * Returns the permissions of a given wiki page for the current user or another user
+ *
+ * @param string $id page id
+ * @param string|null $user username
+ * @param array|null $groups array of groups
+ * @return int permission level
+ */
+ public function aclCheck($id, $user = null, $groups = null)
+ {
+ /** @var \dokuwiki\Extension\AuthPlugin $auth */
+ global $auth;
+
+ $id = $this->resolvePageId($id);
+ if ($user === null) {
+ return auth_quickaclcheck($id);
+ } else {
+ if ($groups === null) {
+ $userinfo = $auth->getUserData($user);
+ if ($userinfo === false) {
+ $groups = array();
+ } else {
+ $groups = $userinfo['grps'];
+ }
+ }
+ return auth_aclcheck($id, $user, $groups);
+ }
+ }
+
+ /**
+ * Lists all links contained in a wiki page
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param string $id page id
+ * @return array
+ * @throws AccessDeniedException no read access for page
+ */
+ public function listLinks($id)
+ {
+ $id = $this->resolvePageId($id);
+ if (auth_quickaclcheck($id) < AUTH_READ) {
+ throw new AccessDeniedException('You are not allowed to read this page', 111);
+ }
+ $links = array();
+
+ // resolve page instructions
+ $ins = p_cached_instructions(wikiFN($id));
+
+ // instantiate new Renderer - needed for interwiki links
+ $Renderer = new Doku_Renderer_xhtml();
+ $Renderer->interwiki = getInterwiki();
+
+ // parse parse instructions
+ foreach ($ins as $in) {
+ $link = array();
+ switch ($in[0]) {
+ case 'internallink':
+ $link['type'] = 'local';
+ $link['page'] = $in[1][0];
+ $link['href'] = wl($in[1][0]);
+ array_push($links, $link);
+ break;
+ case 'externallink':
+ $link['type'] = 'extern';
+ $link['page'] = $in[1][0];
+ $link['href'] = $in[1][0];
+ array_push($links, $link);
+ break;
+ case 'interwikilink':
+ $url = $Renderer->_resolveInterWiki($in[1][2], $in[1][3]);
+ $link['type'] = 'extern';
+ $link['page'] = $url;
+ $link['href'] = $url;
+ array_push($links, $link);
+ break;
+ }
+ }
+
+ return ($links);
+ }
+
+ /**
+ * Returns a list of recent changes since give timestamp
+ *
+ * @author Michael Hamann <michael@content-space.de>
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param int $timestamp unix timestamp
+ * @return array
+ * @throws RemoteException no valid timestamp
+ */
+ public function getRecentChanges($timestamp)
+ {
+ if (strlen($timestamp) != 10) {
+ throw new RemoteException('The provided value is not a valid timestamp', 311);
+ }
+
+ $recents = getRecentsSince($timestamp);
+
+ $changes = array();
+
+ foreach ($recents as $recent) {
+ $change = array();
+ $change['name'] = $recent['id'];
+ $change['lastModified'] = $this->api->toDate($recent['date']);
+ $change['author'] = $recent['user'];
+ $change['version'] = $recent['date'];
+ $change['perms'] = $recent['perms'];
+ $change['size'] = @filesize(wikiFN($recent['id']));
+ array_push($changes, $change);
+ }
+
+ if (!empty($changes)) {
+ return $changes;
+ } else {
+ // in case we still have nothing at this point
+ throw new RemoteException('There are no changes in the specified timeframe', 321);
+ }
+ }
+
+ /**
+ * Returns a list of recent media changes since give timestamp
+ *
+ * @author Michael Hamann <michael@content-space.de>
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param int $timestamp unix timestamp
+ * @return array
+ * @throws RemoteException no valid timestamp
+ */
+ public function getRecentMediaChanges($timestamp)
+ {
+ if (strlen($timestamp) != 10)
+ throw new RemoteException('The provided value is not a valid timestamp', 311);
+
+ $recents = getRecentsSince($timestamp, null, '', RECENTS_MEDIA_CHANGES);
+
+ $changes = array();
+
+ foreach ($recents as $recent) {
+ $change = array();
+ $change['name'] = $recent['id'];
+ $change['lastModified'] = $this->api->toDate($recent['date']);
+ $change['author'] = $recent['user'];
+ $change['version'] = $recent['date'];
+ $change['perms'] = $recent['perms'];
+ $change['size'] = @filesize(mediaFN($recent['id']));
+ array_push($changes, $change);
+ }
+
+ if (!empty($changes)) {
+ return $changes;
+ } else {
+ // in case we still have nothing at this point
+ throw new RemoteException('There are no changes in the specified timeframe', 321);
+ }
+ }
+
+ /**
+ * Returns a list of available revisions of a given wiki page
+ * Number of returned pages is set by $conf['recent']
+ * However not accessible pages are skipped, so less than $conf['recent'] could be returned
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param string $id page id
+ * @param int $first skip the first n changelog lines
+ * 0 = from current(if exists)
+ * 1 = from 1st old rev
+ * 2 = from 2nd old rev, etc
+ * @return array
+ * @throws AccessDeniedException no read access for page
+ * @throws RemoteException empty id
+ */
+ public function pageVersions($id, $first = 0)
+ {
+ $id = $this->resolvePageId($id);
+ if (auth_quickaclcheck($id) < AUTH_READ) {
+ throw new AccessDeniedException('You are not allowed to read this page', 111);
+ }
+ global $conf;
+
+ $versions = array();
+
+ if (empty($id)) {
+ throw new RemoteException('Empty page ID', 131);
+ }
+
+ $first = (int) $first;
+ $first_rev = $first - 1;
+ $first_rev = $first_rev < 0 ? 0 : $first_rev;
+ $pagelog = new PageChangeLog($id);
+ $revisions = $pagelog->getRevisions($first_rev, $conf['recent']);
+
+ if ($first == 0) {
+ array_unshift($revisions, ''); // include current revision
+ if (count($revisions) > $conf['recent']) {
+ array_pop($revisions); // remove extra log entry
+ }
+ }
+
+ if (!empty($revisions)) {
+ foreach ($revisions as $rev) {
+ $file = wikiFN($id, $rev);
+ $time = @filemtime($file);
+ // we check if the page actually exists, if this is not the
+ // case this can lead to less pages being returned than
+ // specified via $conf['recent']
+ if ($time) {
+ $pagelog->setChunkSize(1024);
+ $info = $pagelog->getRevisionInfo($rev ? $rev : $time);
+ if (!empty($info)) {
+ $data = array();
+ $data['user'] = $info['user'];
+ $data['ip'] = $info['ip'];
+ $data['type'] = $info['type'];
+ $data['sum'] = $info['sum'];
+ $data['modified'] = $this->api->toDate($info['date']);
+ $data['version'] = $info['date'];
+ array_push($versions, $data);
+ }
+ }
+ }
+ return $versions;
+ } else {
+ return array();
+ }
+ }
+
+ /**
+ * The version of Wiki RPC API supported
+ */
+ public function wikiRpcVersion()
+ {
+ return 2;
+ }
+
+ /**
+ * Locks or unlocks a given batch of pages
+ *
+ * Give an associative array with two keys: lock and unlock. Both should contain a
+ * list of pages to lock or unlock
+ *
+ * Returns an associative array with the keys locked, lockfail, unlocked and
+ * unlockfail, each containing lists of pages.
+ *
+ * @param array[] $set list pages with array('lock' => array, 'unlock' => array)
+ * @return array
+ */
+ public function setLocks($set)
+ {
+ $locked = array();
+ $lockfail = array();
+ $unlocked = array();
+ $unlockfail = array();
+
+ foreach ((array) $set['lock'] as $id) {
+ $id = $this->resolvePageId($id);
+ if (auth_quickaclcheck($id) < AUTH_EDIT || checklock($id)) {
+ $lockfail[] = $id;
+ } else {
+ lock($id);
+ $locked[] = $id;
+ }
+ }
+
+ foreach ((array) $set['unlock'] as $id) {
+ $id = $this->resolvePageId($id);
+ if (auth_quickaclcheck($id) < AUTH_EDIT || !unlock($id)) {
+ $unlockfail[] = $id;
+ } else {
+ $unlocked[] = $id;
+ }
+ }
+
+ return array(
+ 'locked' => $locked,
+ 'lockfail' => $lockfail,
+ 'unlocked' => $unlocked,
+ 'unlockfail' => $unlockfail,
+ );
+ }
+
+ /**
+ * Return API version
+ *
+ * @return int
+ */
+ public function getAPIVersion()
+ {
+ return self::API_VERSION;
+ }
+
+ /**
+ * Login
+ *
+ * @param string $user
+ * @param string $pass
+ * @return int
+ */
+ public function login($user, $pass)
+ {
+ global $conf;
+ /** @var \dokuwiki\Extension\AuthPlugin $auth */
+ global $auth;
+
+ if (!$conf['useacl']) return 0;
+ if (!$auth) return 0;
+
+ @session_start(); // reopen session for login
+ $ok = null;
+ if ($auth->canDo('external')) {
+ $ok = $auth->trustExternal($user, $pass, false);
+ }
+ if ($ok === null){
+ $evdata = array(
+ 'user' => $user,
+ 'password' => $pass,
+ 'sticky' => false,
+ 'silent' => true,
+ );
+ $ok = Event::createAndTrigger('AUTH_LOGIN_CHECK', $evdata, 'auth_login_wrapper');
+ }
+ session_write_close(); // we're done with the session
+
+ return $ok;
+ }
+
+ /**
+ * Log off
+ *
+ * @return int
+ */
+ public function logoff()
+ {
+ global $conf;
+ global $auth;
+ if (!$conf['useacl']) return 0;
+ if (!$auth) return 0;
+
+ auth_logoff();
+
+ return 1;
+ }
+
+ /**
+ * Resolve page id
+ *
+ * @param string $id page id
+ * @return string
+ */
+ private function resolvePageId($id)
+ {
+ $id = cleanID($id);
+ if (empty($id)) {
+ global $conf;
+ $id = cleanID($conf['start']);
+ }
+ return $id;
+ }
+}
diff --git a/platform/www/inc/Remote/RemoteException.php b/platform/www/inc/Remote/RemoteException.php
new file mode 100644
index 0000000..129a6c2
--- /dev/null
+++ b/platform/www/inc/Remote/RemoteException.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace dokuwiki\Remote;
+
+/**
+ * Class RemoteException
+ */
+class RemoteException extends \Exception
+{
+}
diff --git a/platform/www/inc/Remote/XmlRpcServer.php b/platform/www/inc/Remote/XmlRpcServer.php
new file mode 100644
index 0000000..0a16af1
--- /dev/null
+++ b/platform/www/inc/Remote/XmlRpcServer.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace dokuwiki\Remote;
+
+/**
+ * Contains needed wrapper functions and registers all available XMLRPC functions.
+ */
+class XmlRpcServer extends \IXR_Server
+{
+ protected $remote;
+
+ /**
+ * Constructor. Register methods and run Server
+ */
+ public function __construct($wait=false)
+ {
+ $this->remote = new Api();
+ $this->remote->setDateTransformation(array($this, 'toDate'));
+ $this->remote->setFileTransformation(array($this, 'toFile'));
+ parent::__construct(false, false, $wait);
+ }
+
+ /**
+ * @inheritdoc
+ */
+ public function call($methodname, $args)
+ {
+ try {
+ $result = $this->remote->call($methodname, $args);
+ return $result;
+ } /** @noinspection PhpRedundantCatchClauseInspection */ catch (AccessDeniedException $e) {
+ if (!isset($_SERVER['REMOTE_USER'])) {
+ http_status(401);
+ return new \IXR_Error(-32603, "server error. not authorized to call method $methodname");
+ } else {
+ http_status(403);
+ return new \IXR_Error(-32604, "server error. forbidden to call the method $methodname");
+ }
+ } catch (RemoteException $e) {
+ return new \IXR_Error($e->getCode(), $e->getMessage());
+ }
+ }
+
+ /**
+ * @param string|int $data iso date(yyyy[-]mm[-]dd[ hh:mm[:ss]]) or timestamp
+ * @return \IXR_Date
+ */
+ public function toDate($data)
+ {
+ return new \IXR_Date($data);
+ }
+
+ /**
+ * @param string $data
+ * @return \IXR_Base64
+ */
+ public function toFile($data)
+ {
+ return new \IXR_Base64($data);
+ }
+}
diff --git a/platform/www/inc/SafeFN.class.php b/platform/www/inc/SafeFN.class.php
new file mode 100644
index 0000000..c5489b1
--- /dev/null
+++ b/platform/www/inc/SafeFN.class.php
@@ -0,0 +1,158 @@
+<?php
+
+/**
+ * Class to safely store UTF-8 in a Filename
+ *
+ * Encodes a utf8 string using only the following characters 0-9a-z_.-%
+ * characters 0-9a-z in the original string are preserved, "plain".
+ * all other characters are represented in a substring that starts
+ * with '%' are "converted".
+ * The transition from converted substrings to plain characters is
+ * marked with a '.'
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @date 2010-04-02
+ */
+class SafeFN {
+
+ // 'safe' characters are a superset of $plain, $pre_indicator and $post_indicator
+ private static $plain = '-./[_0123456789abcdefghijklmnopqrstuvwxyz'; // these characters aren't converted
+ private static $pre_indicator = '%';
+ private static $post_indicator = ']';
+
+ /**
+ * Convert an UTF-8 string to a safe ASCII String
+ *
+ * conversion process
+ * - if codepoint is a plain or post_indicator character,
+ * - if previous character was "converted", append post_indicator to output, clear "converted" flag
+ * - append ascii byte for character to output
+ * (continue to next character)
+ *
+ * - if codepoint is a pre_indicator character,
+ * - append ascii byte for character to output, set "converted" flag
+ * (continue to next character)
+ *
+ * (all remaining characters)
+ * - reduce codepoint value for non-printable ASCII characters (0x00 - 0x1f). Space becomes our zero.
+ * - convert reduced value to base36 (0-9a-z)
+ * - append $pre_indicator characater followed by base36 string to output, set converted flag
+ * (continue to next character)
+ *
+ * @param string $filename a utf8 string, should only include printable characters - not 0x00-0x1f
+ * @return string an encoded representation of $filename using only 'safe' ASCII characters
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+ public static function encode($filename) {
+ return self::unicodeToSafe(\dokuwiki\Utf8\Unicode::fromUtf8($filename));
+ }
+
+ /**
+ * decoding process
+ * - split the string into substrings at any occurrence of pre or post indicator characters
+ * - check the first character of the substring
+ * - if its not a pre_indicator character
+ * - if previous character was converted, skip over post_indicator character
+ * - copy codepoint values of remaining characters to the output array
+ * - clear any converted flag
+ * (continue to next substring)
+ *
+ * _ else (its a pre_indicator character)
+ * - if string length is 1, copy the post_indicator character to the output array
+ * (continue to next substring)
+ *
+ * - else (string length > 1)
+ * - skip the pre-indicator character and convert remaining string from base36 to base10
+ * - increase codepoint value for non-printable ASCII characters (add 0x20)
+ * - append codepoint to output array
+ * (continue to next substring)
+ *
+ * @param string $filename a 'safe' encoded ASCII string,
+ * @return string decoded utf8 representation of $filename
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+ public static function decode($filename) {
+ return \dokuwiki\Utf8\Unicode::toUtf8(self::safeToUnicode(strtolower($filename)));
+ }
+
+ public static function validatePrintableUtf8($printable_utf8) {
+ return !preg_match('#[\x01-\x1f]#',$printable_utf8);
+ }
+
+ public static function validateSafe($safe) {
+ return !preg_match('#[^'.self::$plain.self::$post_indicator.self::$pre_indicator.']#',$safe);
+ }
+
+ /**
+ * convert an array of unicode codepoints into 'safe_filename' format
+ *
+ * @param array int $unicode an array of unicode codepoints
+ * @return string the unicode represented in 'safe_filename' format
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+ private static function unicodeToSafe($unicode) {
+
+ $safe = '';
+ $converted = false;
+
+ foreach ($unicode as $codepoint) {
+ if ($codepoint < 127 && (strpos(self::$plain.self::$post_indicator,chr($codepoint))!==false)) {
+ if ($converted) {
+ $safe .= self::$post_indicator;
+ $converted = false;
+ }
+ $safe .= chr($codepoint);
+
+ } else if ($codepoint == ord(self::$pre_indicator)) {
+ $safe .= self::$pre_indicator;
+ $converted = true;
+ } else {
+ $safe .= self::$pre_indicator.base_convert((string)($codepoint-32),10,36);
+ $converted = true;
+ }
+ }
+ if($converted) $safe .= self::$post_indicator;
+ return $safe;
+ }
+
+ /**
+ * convert a 'safe_filename' string into an array of unicode codepoints
+ *
+ * @param string $safe a filename in 'safe_filename' format
+ * @return array int an array of unicode codepoints
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+ private static function safeToUnicode($safe) {
+
+ $unicode = array();
+ $split = preg_split('#(?=['.self::$post_indicator.self::$pre_indicator.'])#',$safe,-1,PREG_SPLIT_NO_EMPTY);
+
+ $converted = false;
+ foreach ($split as $sub) {
+ $len = strlen($sub);
+ if ($sub[0] != self::$pre_indicator) {
+ // plain (unconverted) characters, optionally starting with a post_indicator
+ // set initial value to skip any post_indicator
+ for ($i=($converted?1:0); $i < $len; $i++) {
+ $unicode[] = ord($sub[$i]);
+ }
+ $converted = false;
+ } else if ($len==1) {
+ // a pre_indicator character in the real data
+ $unicode[] = ord($sub);
+ $converted = true;
+ } else {
+ // a single codepoint in base36, adjusted for initial 32 non-printable chars
+ $unicode[] = 32 + (int)base_convert(substr($sub,1),36,10);
+ $converted = true;
+ }
+ }
+
+ return $unicode;
+ }
+
+}
diff --git a/platform/www/inc/Search/Indexer.php b/platform/www/inc/Search/Indexer.php
new file mode 100644
index 0000000..a29e5b2
--- /dev/null
+++ b/platform/www/inc/Search/Indexer.php
@@ -0,0 +1,1214 @@
+<?php
+
+namespace dokuwiki\Search;
+
+use dokuwiki\Extension\Event;
+
+/**
+ * Class that encapsulates operations on the indexer database.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+class Indexer {
+ /**
+ * @var array $pidCache Cache for getPID()
+ */
+ protected $pidCache = array();
+
+ /**
+ * Adds the contents of a page to the fulltext index
+ *
+ * The added text replaces previous words for the same page.
+ * An empty value erases the page.
+ *
+ * @param string $page a page name
+ * @param string $text the body of the page
+ * @return string|boolean the function completed successfully
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function addPageWords($page, $text) {
+ if (!$this->lock())
+ return "locked";
+
+ // load known documents
+ $pid = $this->getPIDNoLock($page);
+ if ($pid === false) {
+ $this->unlock();
+ return false;
+ }
+
+ $pagewords = array();
+ // get word usage in page
+ $words = $this->getPageWords($text);
+ if ($words === false) {
+ $this->unlock();
+ return false;
+ }
+
+ if (!empty($words)) {
+ foreach (array_keys($words) as $wlen) {
+ $index = $this->getIndex('i', $wlen);
+ foreach ($words[$wlen] as $wid => $freq) {
+ $idx = ($wid<count($index)) ? $index[$wid] : '';
+ $index[$wid] = $this->updateTuple($idx, $pid, $freq);
+ $pagewords[] = "$wlen*$wid";
+ }
+ if (!$this->saveIndex('i', $wlen, $index)) {
+ $this->unlock();
+ return false;
+ }
+ }
+ }
+
+ // Remove obsolete index entries
+ $pageword_idx = $this->getIndexKey('pageword', '', $pid);
+ if ($pageword_idx !== '') {
+ $oldwords = explode(':',$pageword_idx);
+ $delwords = array_diff($oldwords, $pagewords);
+ $upwords = array();
+ foreach ($delwords as $word) {
+ if ($word != '') {
+ list($wlen, $wid) = explode('*', $word);
+ $wid = (int)$wid;
+ $upwords[$wlen][] = $wid;
+ }
+ }
+ foreach ($upwords as $wlen => $widx) {
+ $index = $this->getIndex('i', $wlen);
+ foreach ($widx as $wid) {
+ $index[$wid] = $this->updateTuple($index[$wid], $pid, 0);
+ }
+ $this->saveIndex('i', $wlen, $index);
+ }
+ }
+ // Save the reverse index
+ $pageword_idx = join(':', $pagewords);
+ if (!$this->saveIndexKey('pageword', '', $pid, $pageword_idx)) {
+ $this->unlock();
+ return false;
+ }
+
+ $this->unlock();
+ return true;
+ }
+
+ /**
+ * Split the words in a page and add them to the index.
+ *
+ * @param string $text content of the page
+ * @return array list of word IDs and number of times used
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function getPageWords($text) {
+
+ $tokens = $this->tokenizer($text);
+ $tokens = array_count_values($tokens); // count the frequency of each token
+
+ $words = array();
+ foreach ($tokens as $w=>$c) {
+ $l = wordlen($w);
+ if (isset($words[$l])){
+ $words[$l][$w] = $c + (isset($words[$l][$w]) ? $words[$l][$w] : 0);
+ }else{
+ $words[$l] = array($w => $c);
+ }
+ }
+
+ // arrive here with $words = array(wordlen => array(word => frequency))
+ $word_idx_modified = false;
+ $index = array(); //resulting index
+ foreach (array_keys($words) as $wlen) {
+ $word_idx = $this->getIndex('w', $wlen);
+ foreach ($words[$wlen] as $word => $freq) {
+ $word = (string)$word;
+ $wid = array_search($word, $word_idx, true);
+ if ($wid === false) {
+ $wid = count($word_idx);
+ $word_idx[] = $word;
+ $word_idx_modified = true;
+ }
+ if (!isset($index[$wlen]))
+ $index[$wlen] = array();
+ $index[$wlen][$wid] = $freq;
+ }
+ // save back the word index
+ if ($word_idx_modified && !$this->saveIndex('w', $wlen, $word_idx))
+ return false;
+ }
+
+ return $index;
+ }
+
+ /**
+ * Add/update keys to/of the metadata index.
+ *
+ * Adding new keys does not remove other keys for the page.
+ * An empty value will erase the key.
+ * The $key parameter can be an array to add multiple keys. $value will
+ * not be used if $key is an array.
+ *
+ * @param string $page a page name
+ * @param mixed $key a key string or array of key=>value pairs
+ * @param mixed $value the value or list of values
+ * @return boolean|string the function completed successfully
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ * @author Michael Hamann <michael@content-space.de>
+ */
+ public function addMetaKeys($page, $key, $value=null) {
+ if (!is_array($key)) {
+ $key = array($key => $value);
+ } elseif (!is_null($value)) {
+ // $key is array, but $value is not null
+ trigger_error("array passed to addMetaKeys but value is not null", E_USER_WARNING);
+ }
+
+ if (!$this->lock())
+ return "locked";
+
+ // load known documents
+ $pid = $this->getPIDNoLock($page);
+ if ($pid === false) {
+ $this->unlock();
+ return false;
+ }
+
+ // Special handling for titles so the index file is simpler
+ if (array_key_exists('title', $key)) {
+ $value = $key['title'];
+ if (is_array($value)) {
+ $value = $value[0];
+ }
+ $this->saveIndexKey('title', '', $pid, $value);
+ unset($key['title']);
+ }
+
+ foreach ($key as $name => $values) {
+ $metaname = idx_cleanName($name);
+ $this->addIndexKey('metadata', '', $metaname);
+ $metaidx = $this->getIndex($metaname.'_i', '');
+ $metawords = $this->getIndex($metaname.'_w', '');
+ $addwords = false;
+
+ if (!is_array($values)) $values = array($values);
+
+ $val_idx = $this->getIndexKey($metaname.'_p', '', $pid);
+ if ($val_idx !== '') {
+ $val_idx = explode(':', $val_idx);
+ // -1 means remove, 0 keep, 1 add
+ $val_idx = array_combine($val_idx, array_fill(0, count($val_idx), -1));
+ } else {
+ $val_idx = array();
+ }
+
+ foreach ($values as $val) {
+ $val = (string)$val;
+ if ($val !== "") {
+ $id = array_search($val, $metawords, true);
+ if ($id === false) {
+ // didn't find $val, so we'll add it to the end of metawords and create a placeholder in metaidx
+ $id = count($metawords);
+ $metawords[$id] = $val;
+ $metaidx[$id] = '';
+ $addwords = true;
+ }
+ // test if value is already in the index
+ if (isset($val_idx[$id]) && $val_idx[$id] <= 0){
+ $val_idx[$id] = 0;
+ } else { // else add it
+ $val_idx[$id] = 1;
+ }
+ }
+ }
+
+ if ($addwords) {
+ $this->saveIndex($metaname.'_w', '', $metawords);
+ }
+ $vals_changed = false;
+ foreach ($val_idx as $id => $action) {
+ if ($action == -1) {
+ $metaidx[$id] = $this->updateTuple($metaidx[$id], $pid, 0);
+ $vals_changed = true;
+ unset($val_idx[$id]);
+ } elseif ($action == 1) {
+ $metaidx[$id] = $this->updateTuple($metaidx[$id], $pid, 1);
+ $vals_changed = true;
+ }
+ }
+
+ if ($vals_changed) {
+ $this->saveIndex($metaname.'_i', '', $metaidx);
+ $val_idx = implode(':', array_keys($val_idx));
+ $this->saveIndexKey($metaname.'_p', '', $pid, $val_idx);
+ }
+
+ unset($metaidx);
+ unset($metawords);
+ }
+
+ $this->unlock();
+ return true;
+ }
+
+ /**
+ * Rename a page in the search index without changing the indexed content. This function doesn't check if the
+ * old or new name exists in the filesystem. It returns an error if the old page isn't in the page list of the
+ * indexer and it deletes all previously indexed content of the new page.
+ *
+ * @param string $oldpage The old page name
+ * @param string $newpage The new page name
+ * @return string|bool If the page was successfully renamed, can be a message in the case of an error
+ */
+ public function renamePage($oldpage, $newpage) {
+ if (!$this->lock()) return 'locked';
+
+ $pages = $this->getPages();
+
+ $id = array_search($oldpage, $pages, true);
+ if ($id === false) {
+ $this->unlock();
+ return 'page is not in index';
+ }
+
+ $new_id = array_search($newpage, $pages, true);
+ if ($new_id !== false) {
+ // make sure the page is not in the index anymore
+ if ($this->deletePageNoLock($newpage) !== true) {
+ return false;
+ }
+
+ $pages[$new_id] = 'deleted:'.time().rand(0, 9999);
+ }
+
+ $pages[$id] = $newpage;
+
+ // update index
+ if (!$this->saveIndex('page', '', $pages)) {
+ $this->unlock();
+ return false;
+ }
+
+ // reset the pid cache
+ $this->pidCache = array();
+
+ $this->unlock();
+ return true;
+ }
+
+ /**
+ * Renames a meta value in the index. This doesn't change the meta value in the pages, it assumes that all pages
+ * will be updated.
+ *
+ * @param string $key The metadata key of which a value shall be changed
+ * @param string $oldvalue The old value that shall be renamed
+ * @param string $newvalue The new value to which the old value shall be renamed, if exists values will be merged
+ * @return bool|string If renaming the value has been successful, false or error message on error.
+ */
+ public function renameMetaValue($key, $oldvalue, $newvalue) {
+ if (!$this->lock()) return 'locked';
+
+ // change the relation references index
+ $metavalues = $this->getIndex($key, '_w');
+ $oldid = array_search($oldvalue, $metavalues, true);
+ if ($oldid !== false) {
+ $newid = array_search($newvalue, $metavalues, true);
+ if ($newid !== false) {
+ // free memory
+ unset ($metavalues);
+
+ // okay, now we have two entries for the same value. we need to merge them.
+ $indexline = $this->getIndexKey($key.'_i', '', $oldid);
+ if ($indexline != '') {
+ $newindexline = $this->getIndexKey($key.'_i', '', $newid);
+ $pagekeys = $this->getIndex($key.'_p', '');
+ $parts = explode(':', $indexline);
+ foreach ($parts as $part) {
+ list($id, $count) = explode('*', $part);
+ $newindexline = $this->updateTuple($newindexline, $id, $count);
+
+ $keyline = explode(':', $pagekeys[$id]);
+ // remove old meta value
+ $keyline = array_diff($keyline, array($oldid));
+ // add new meta value when not already present
+ if (!in_array($newid, $keyline)) {
+ array_push($keyline, $newid);
+ }
+ $pagekeys[$id] = implode(':', $keyline);
+ }
+ $this->saveIndex($key.'_p', '', $pagekeys);
+ unset($pagekeys);
+ $this->saveIndexKey($key.'_i', '', $oldid, '');
+ $this->saveIndexKey($key.'_i', '', $newid, $newindexline);
+ }
+ } else {
+ $metavalues[$oldid] = $newvalue;
+ if (!$this->saveIndex($key.'_w', '', $metavalues)) {
+ $this->unlock();
+ return false;
+ }
+ }
+ }
+
+ $this->unlock();
+ return true;
+ }
+
+ /**
+ * Remove a page from the index
+ *
+ * Erases entries in all known indexes.
+ *
+ * @param string $page a page name
+ * @return string|boolean the function completed successfully
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function deletePage($page) {
+ if (!$this->lock())
+ return "locked";
+
+ $result = $this->deletePageNoLock($page);
+
+ $this->unlock();
+
+ return $result;
+ }
+
+ /**
+ * Remove a page from the index without locking the index, only use this function if the index is already locked
+ *
+ * Erases entries in all known indexes.
+ *
+ * @param string $page a page name
+ * @return boolean the function completed successfully
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function deletePageNoLock($page) {
+ // load known documents
+ $pid = $this->getPIDNoLock($page);
+ if ($pid === false) {
+ return false;
+ }
+
+ // Remove obsolete index entries
+ $pageword_idx = $this->getIndexKey('pageword', '', $pid);
+ if ($pageword_idx !== '') {
+ $delwords = explode(':',$pageword_idx);
+ $upwords = array();
+ foreach ($delwords as $word) {
+ if ($word != '') {
+ list($wlen,$wid) = explode('*', $word);
+ $wid = (int)$wid;
+ $upwords[$wlen][] = $wid;
+ }
+ }
+ foreach ($upwords as $wlen => $widx) {
+ $index = $this->getIndex('i', $wlen);
+ foreach ($widx as $wid) {
+ $index[$wid] = $this->updateTuple($index[$wid], $pid, 0);
+ }
+ $this->saveIndex('i', $wlen, $index);
+ }
+ }
+ // Save the reverse index
+ if (!$this->saveIndexKey('pageword', '', $pid, "")) {
+ return false;
+ }
+
+ $this->saveIndexKey('title', '', $pid, "");
+ $keyidx = $this->getIndex('metadata', '');
+ foreach ($keyidx as $metaname) {
+ $val_idx = explode(':', $this->getIndexKey($metaname.'_p', '', $pid));
+ $meta_idx = $this->getIndex($metaname.'_i', '');
+ foreach ($val_idx as $id) {
+ if ($id === '') continue;
+ $meta_idx[$id] = $this->updateTuple($meta_idx[$id], $pid, 0);
+ }
+ $this->saveIndex($metaname.'_i', '', $meta_idx);
+ $this->saveIndexKey($metaname.'_p', '', $pid, '');
+ }
+
+ return true;
+ }
+
+ /**
+ * Clear the whole index
+ *
+ * @return bool If the index has been cleared successfully
+ */
+ public function clear() {
+ global $conf;
+
+ if (!$this->lock()) return false;
+
+ @unlink($conf['indexdir'].'/page.idx');
+ @unlink($conf['indexdir'].'/title.idx');
+ @unlink($conf['indexdir'].'/pageword.idx');
+ @unlink($conf['indexdir'].'/metadata.idx');
+ $dir = @opendir($conf['indexdir']);
+ if($dir!==false){
+ while(($f = readdir($dir)) !== false){
+ if(substr($f,-4)=='.idx' &&
+ (substr($f,0,1)=='i' || substr($f,0,1)=='w'
+ || substr($f,-6)=='_w.idx' || substr($f,-6)=='_i.idx' || substr($f,-6)=='_p.idx'))
+ @unlink($conf['indexdir']."/$f");
+ }
+ }
+ @unlink($conf['indexdir'].'/lengths.idx');
+
+ // clear the pid cache
+ $this->pidCache = array();
+
+ $this->unlock();
+ return true;
+ }
+
+ /**
+ * Split the text into words for fulltext search
+ *
+ * TODO: does this also need &$stopwords ?
+ *
+ * @triggers INDEXER_TEXT_PREPARE
+ * This event allows plugins to modify the text before it gets tokenized.
+ * Plugins intercepting this event should also intercept INDEX_VERSION_GET
+ *
+ * @param string $text plain text
+ * @param boolean $wc are wildcards allowed?
+ * @return array list of words in the text
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function tokenizer($text, $wc=false) {
+ $wc = ($wc) ? '' : '\*';
+ $stopwords =& idx_get_stopwords();
+
+ // prepare the text to be tokenized
+ $evt = new Event('INDEXER_TEXT_PREPARE', $text);
+ if ($evt->advise_before(true)) {
+ if (preg_match('/[^0-9A-Za-z ]/u', $text)) {
+ $text = \dokuwiki\Utf8\Asian::separateAsianWords($text);
+ }
+ }
+ $evt->advise_after();
+ unset($evt);
+
+ $text = strtr($text,
+ array(
+ "\r" => ' ',
+ "\n" => ' ',
+ "\t" => ' ',
+ "\xC2\xAD" => '', //soft-hyphen
+ )
+ );
+ if (preg_match('/[^0-9A-Za-z ]/u', $text))
+ $text = \dokuwiki\Utf8\Clean::stripspecials($text, ' ', '\._\-:'.$wc);
+
+ $wordlist = explode(' ', $text);
+ foreach ($wordlist as $i => $word) {
+ $wordlist[$i] = (preg_match('/[^0-9A-Za-z]/u', $word)) ?
+ \dokuwiki\Utf8\PhpString::strtolower($word) : strtolower($word);
+ }
+
+ foreach ($wordlist as $i => $word) {
+ if ((!is_numeric($word) && strlen($word) < IDX_MINWORDLENGTH)
+ || array_search($word, $stopwords, true) !== false)
+ unset($wordlist[$i]);
+ }
+ return array_values($wordlist);
+ }
+
+ /**
+ * Get the numeric PID of a page
+ *
+ * @param string $page The page to get the PID for
+ * @return bool|int The page id on success, false on error
+ */
+ public function getPID($page) {
+ // return PID without locking when it is in the cache
+ if (isset($this->pidCache[$page])) return $this->pidCache[$page];
+
+ if (!$this->lock())
+ return false;
+
+ // load known documents
+ $pid = $this->getPIDNoLock($page);
+ if ($pid === false) {
+ $this->unlock();
+ return false;
+ }
+
+ $this->unlock();
+ return $pid;
+ }
+
+ /**
+ * Get the numeric PID of a page without locking the index.
+ * Only use this function when the index is already locked.
+ *
+ * @param string $page The page to get the PID for
+ * @return bool|int The page id on success, false on error
+ */
+ protected function getPIDNoLock($page) {
+ // avoid expensive addIndexKey operation for the most recently requested pages by using a cache
+ if (isset($this->pidCache[$page])) return $this->pidCache[$page];
+ $pid = $this->addIndexKey('page', '', $page);
+ // limit cache to 10 entries by discarding the oldest element as in DokuWiki usually only the most recently
+ // added item will be requested again
+ if (count($this->pidCache) > 10) array_shift($this->pidCache);
+ $this->pidCache[$page] = $pid;
+ return $pid;
+ }
+
+ /**
+ * Get the page id of a numeric PID
+ *
+ * @param int $pid The PID to get the page id for
+ * @return string The page id
+ */
+ public function getPageFromPID($pid) {
+ return $this->getIndexKey('page', '', $pid);
+ }
+
+ /**
+ * Find pages in the fulltext index containing the words,
+ *
+ * The search words must be pre-tokenized, meaning only letters and
+ * numbers with an optional wildcard
+ *
+ * The returned array will have the original tokens as key. The values
+ * in the returned list is an array with the page names as keys and the
+ * number of times that token appears on the page as value.
+ *
+ * @param array $tokens list of words to search for
+ * @return array list of page names with usage counts
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function lookup(&$tokens) {
+ $result = array();
+ $wids = $this->getIndexWords($tokens, $result);
+ if (empty($wids)) return array();
+ // load known words and documents
+ $page_idx = $this->getIndex('page', '');
+ $docs = array();
+ foreach (array_keys($wids) as $wlen) {
+ $wids[$wlen] = array_unique($wids[$wlen]);
+ $index = $this->getIndex('i', $wlen);
+ foreach($wids[$wlen] as $ixid) {
+ if ($ixid < count($index))
+ $docs["$wlen*$ixid"] = $this->parseTuples($page_idx, $index[$ixid]);
+ }
+ }
+ // merge found pages into final result array
+ $final = array();
+ foreach ($result as $word => $res) {
+ $final[$word] = array();
+ foreach ($res as $wid) {
+ // handle the case when ($ixid < count($index)) has been false
+ // and thus $docs[$wid] hasn't been set.
+ if (!isset($docs[$wid])) continue;
+ $hits = &$docs[$wid];
+ foreach ($hits as $hitkey => $hitcnt) {
+ // make sure the document still exists
+ if (!page_exists($hitkey, '', false)) continue;
+ if (!isset($final[$word][$hitkey]))
+ $final[$word][$hitkey] = $hitcnt;
+ else
+ $final[$word][$hitkey] += $hitcnt;
+ }
+ }
+ }
+ return $final;
+ }
+
+ /**
+ * Find pages containing a metadata key.
+ *
+ * The metadata values are compared as case-sensitive strings. Pass a
+ * callback function that returns true or false to use a different
+ * comparison function. The function will be called with the $value being
+ * searched for as the first argument, and the word in the index as the
+ * second argument. The function preg_match can be used directly if the
+ * values are regexes.
+ *
+ * @param string $key name of the metadata key to look for
+ * @param string $value search term to look for, must be a string or array of strings
+ * @param callback $func comparison function
+ * @return array lists with page names, keys are query values if $value is array
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ * @author Michael Hamann <michael@content-space.de>
+ */
+ public function lookupKey($key, &$value, $func=null) {
+ if (!is_array($value))
+ $value_array = array($value);
+ else
+ $value_array =& $value;
+
+ // the matching ids for the provided value(s)
+ $value_ids = array();
+
+ $metaname = idx_cleanName($key);
+
+ // get all words in order to search the matching ids
+ if ($key == 'title') {
+ $words = $this->getIndex('title', '');
+ } else {
+ $words = $this->getIndex($metaname.'_w', '');
+ }
+
+ if (!is_null($func)) {
+ foreach ($value_array as $val) {
+ foreach ($words as $i => $word) {
+ if (call_user_func_array($func, array($val, $word)))
+ $value_ids[$i][] = $val;
+ }
+ }
+ } else {
+ foreach ($value_array as $val) {
+ $xval = $val;
+ $caret = '^';
+ $dollar = '$';
+ // check for wildcards
+ if (substr($xval, 0, 1) == '*') {
+ $xval = substr($xval, 1);
+ $caret = '';
+ }
+ if (substr($xval, -1, 1) == '*') {
+ $xval = substr($xval, 0, -1);
+ $dollar = '';
+ }
+ if (!$caret || !$dollar) {
+ $re = $caret.preg_quote($xval, '/').$dollar;
+ foreach(array_keys(preg_grep('/'.$re.'/', $words)) as $i)
+ $value_ids[$i][] = $val;
+ } else {
+ if (($i = array_search($val, $words, true)) !== false)
+ $value_ids[$i][] = $val;
+ }
+ }
+ }
+
+ unset($words); // free the used memory
+
+ // initialize the result so it won't be null
+ $result = array();
+ foreach ($value_array as $val) {
+ $result[$val] = array();
+ }
+
+ $page_idx = $this->getIndex('page', '');
+
+ // Special handling for titles
+ if ($key == 'title') {
+ foreach ($value_ids as $pid => $val_list) {
+ $page = $page_idx[$pid];
+ foreach ($val_list as $val) {
+ $result[$val][] = $page;
+ }
+ }
+ } else {
+ // load all lines and pages so the used lines can be taken and matched with the pages
+ $lines = $this->getIndex($metaname.'_i', '');
+
+ foreach ($value_ids as $value_id => $val_list) {
+ // parse the tuples of the form page_id*1:page2_id*1 and so on, return value
+ // is an array with page_id => 1, page2_id => 1 etc. so take the keys only
+ $pages = array_keys($this->parseTuples($page_idx, $lines[$value_id]));
+ foreach ($val_list as $val) {
+ $result[$val] = array_merge($result[$val], $pages);
+ }
+ }
+ }
+ if (!is_array($value)) $result = $result[$value];
+ return $result;
+ }
+
+ /**
+ * Find the index ID of each search term.
+ *
+ * The query terms should only contain valid characters, with a '*' at
+ * either the beginning or end of the word (or both).
+ * The $result parameter can be used to merge the index locations with
+ * the appropriate query term.
+ *
+ * @param array $words The query terms.
+ * @param array $result Set to word => array("length*id" ...)
+ * @return array Set to length => array(id ...)
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function getIndexWords(&$words, &$result) {
+ $tokens = array();
+ $tokenlength = array();
+ $tokenwild = array();
+ foreach ($words as $word) {
+ $result[$word] = array();
+ $caret = '^';
+ $dollar = '$';
+ $xword = $word;
+ $wlen = wordlen($word);
+
+ // check for wildcards
+ if (substr($xword, 0, 1) == '*') {
+ $xword = substr($xword, 1);
+ $caret = '';
+ $wlen -= 1;
+ }
+ if (substr($xword, -1, 1) == '*') {
+ $xword = substr($xword, 0, -1);
+ $dollar = '';
+ $wlen -= 1;
+ }
+ if ($wlen < IDX_MINWORDLENGTH && $caret && $dollar && !is_numeric($xword))
+ continue;
+ if (!isset($tokens[$xword]))
+ $tokenlength[$wlen][] = $xword;
+ if (!$caret || !$dollar) {
+ $re = $caret.preg_quote($xword, '/').$dollar;
+ $tokens[$xword][] = array($word, '/'.$re.'/');
+ if (!isset($tokenwild[$xword]))
+ $tokenwild[$xword] = $wlen;
+ } else {
+ $tokens[$xword][] = array($word, null);
+ }
+ }
+ asort($tokenwild);
+ // $tokens = array( base word => array( [ query term , regexp ] ... ) ... )
+ // $tokenlength = array( base word length => base word ... )
+ // $tokenwild = array( base word => base word length ... )
+ $length_filter = empty($tokenwild) ? $tokenlength : min(array_keys($tokenlength));
+ $indexes_known = $this->indexLengths($length_filter);
+ if (!empty($tokenwild)) sort($indexes_known);
+ // get word IDs
+ $wids = array();
+ foreach ($indexes_known as $ixlen) {
+ $word_idx = $this->getIndex('w', $ixlen);
+ // handle exact search
+ if (isset($tokenlength[$ixlen])) {
+ foreach ($tokenlength[$ixlen] as $xword) {
+ $wid = array_search($xword, $word_idx, true);
+ if ($wid !== false) {
+ $wids[$ixlen][] = $wid;
+ foreach ($tokens[$xword] as $w)
+ $result[$w[0]][] = "$ixlen*$wid";
+ }
+ }
+ }
+ // handle wildcard search
+ foreach ($tokenwild as $xword => $wlen) {
+ if ($wlen >= $ixlen) break;
+ foreach ($tokens[$xword] as $w) {
+ if (is_null($w[1])) continue;
+ foreach(array_keys(preg_grep($w[1], $word_idx)) as $wid) {
+ $wids[$ixlen][] = $wid;
+ $result[$w[0]][] = "$ixlen*$wid";
+ }
+ }
+ }
+ }
+ return $wids;
+ }
+
+ /**
+ * Return a list of all pages
+ * Warning: pages may not exist!
+ *
+ * @param string $key list only pages containing the metadata key (optional)
+ * @return array list of page names
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function getPages($key=null) {
+ $page_idx = $this->getIndex('page', '');
+ if (is_null($key)) return $page_idx;
+
+ $metaname = idx_cleanName($key);
+
+ // Special handling for titles
+ if ($key == 'title') {
+ $title_idx = $this->getIndex('title', '');
+ array_splice($page_idx, count($title_idx));
+ foreach ($title_idx as $i => $title)
+ if ($title === "") unset($page_idx[$i]);
+ return array_values($page_idx);
+ }
+
+ $pages = array();
+ $lines = $this->getIndex($metaname.'_i', '');
+ foreach ($lines as $line) {
+ $pages = array_merge($pages, $this->parseTuples($page_idx, $line));
+ }
+ return array_keys($pages);
+ }
+
+ /**
+ * Return a list of words sorted by number of times used
+ *
+ * @param int $min bottom frequency threshold
+ * @param int $max upper frequency limit. No limit if $max<$min
+ * @param int $minlen minimum length of words to count
+ * @param string $key metadata key to list. Uses the fulltext index if not given
+ * @return array list of words as the keys and frequency as values
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function histogram($min=1, $max=0, $minlen=3, $key=null) {
+ if ($min < 1)
+ $min = 1;
+ if ($max < $min)
+ $max = 0;
+
+ $result = array();
+
+ if ($key == 'title') {
+ $index = $this->getIndex('title', '');
+ $index = array_count_values($index);
+ foreach ($index as $val => $cnt) {
+ if ($cnt >= $min && (!$max || $cnt <= $max) && strlen($val) >= $minlen)
+ $result[$val] = $cnt;
+ }
+ }
+ elseif (!is_null($key)) {
+ $metaname = idx_cleanName($key);
+ $index = $this->getIndex($metaname.'_i', '');
+ $val_idx = array();
+ foreach ($index as $wid => $line) {
+ $freq = $this->countTuples($line);
+ if ($freq >= $min && (!$max || $freq <= $max))
+ $val_idx[$wid] = $freq;
+ }
+ if (!empty($val_idx)) {
+ $words = $this->getIndex($metaname.'_w', '');
+ foreach ($val_idx as $wid => $freq) {
+ if (strlen($words[$wid]) >= $minlen)
+ $result[$words[$wid]] = $freq;
+ }
+ }
+ }
+ else {
+ $lengths = idx_listIndexLengths();
+ foreach ($lengths as $length) {
+ if ($length < $minlen) continue;
+ $index = $this->getIndex('i', $length);
+ $words = null;
+ foreach ($index as $wid => $line) {
+ $freq = $this->countTuples($line);
+ if ($freq >= $min && (!$max || $freq <= $max)) {
+ if ($words === null)
+ $words = $this->getIndex('w', $length);
+ $result[$words[$wid]] = $freq;
+ }
+ }
+ }
+ }
+
+ arsort($result);
+ return $result;
+ }
+
+ /**
+ * Lock the indexer.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @return bool|string
+ */
+ protected function lock() {
+ global $conf;
+ $status = true;
+ $run = 0;
+ $lock = $conf['lockdir'].'/_indexer.lock';
+ while (!@mkdir($lock, $conf['dmode'])) {
+ usleep(50);
+ if(is_dir($lock) && time()-@filemtime($lock) > 60*5){
+ // looks like a stale lock - remove it
+ if (!@rmdir($lock)) {
+ $status = "removing the stale lock failed";
+ return false;
+ } else {
+ $status = "stale lock removed";
+ }
+ }elseif($run++ == 1000){
+ // we waited 5 seconds for that lock
+ return false;
+ }
+ }
+ if (!empty($conf['dperm'])) {
+ chmod($lock, $conf['dperm']);
+ }
+ return $status;
+ }
+
+ /**
+ * Release the indexer lock.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @return bool
+ */
+ protected function unlock() {
+ global $conf;
+ @rmdir($conf['lockdir'].'/_indexer.lock');
+ return true;
+ }
+
+ /**
+ * Retrieve the entire index.
+ *
+ * The $suffix argument is for an index that is split into
+ * multiple parts. Different index files should use different
+ * base names.
+ *
+ * @param string $idx name of the index
+ * @param string $suffix subpart identifier
+ * @return array list of lines without CR or LF
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function getIndex($idx, $suffix) {
+ global $conf;
+ $fn = $conf['indexdir'].'/'.$idx.$suffix.'.idx';
+ if (!file_exists($fn)) return array();
+ return file($fn, FILE_IGNORE_NEW_LINES);
+ }
+
+ /**
+ * Replace the contents of the index with an array.
+ *
+ * @param string $idx name of the index
+ * @param string $suffix subpart identifier
+ * @param array $lines list of lines without LF
+ * @return bool If saving succeeded
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function saveIndex($idx, $suffix, &$lines) {
+ global $conf;
+ $fn = $conf['indexdir'].'/'.$idx.$suffix;
+ $fh = @fopen($fn.'.tmp', 'w');
+ if (!$fh) return false;
+ fwrite($fh, join("\n", $lines));
+ if (!empty($lines))
+ fwrite($fh, "\n");
+ fclose($fh);
+ if ($conf['fperm'])
+ chmod($fn.'.tmp', $conf['fperm']);
+ io_rename($fn.'.tmp', $fn.'.idx');
+ return true;
+ }
+
+ /**
+ * Retrieve a line from the index.
+ *
+ * @param string $idx name of the index
+ * @param string $suffix subpart identifier
+ * @param int $id the line number
+ * @return string a line with trailing whitespace removed
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function getIndexKey($idx, $suffix, $id) {
+ global $conf;
+ $fn = $conf['indexdir'].'/'.$idx.$suffix.'.idx';
+ if (!file_exists($fn)) return '';
+ $fh = @fopen($fn, 'r');
+ if (!$fh) return '';
+ $ln = -1;
+ while (($line = fgets($fh)) !== false) {
+ if (++$ln == $id) break;
+ }
+ fclose($fh);
+ return rtrim((string)$line);
+ }
+
+ /**
+ * Write a line into the index.
+ *
+ * @param string $idx name of the index
+ * @param string $suffix subpart identifier
+ * @param int $id the line number
+ * @param string $line line to write
+ * @return bool If saving succeeded
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function saveIndexKey($idx, $suffix, $id, $line) {
+ global $conf;
+ if (substr($line, -1) != "\n")
+ $line .= "\n";
+ $fn = $conf['indexdir'].'/'.$idx.$suffix;
+ $fh = @fopen($fn.'.tmp', 'w');
+ if (!$fh) return false;
+ $ih = @fopen($fn.'.idx', 'r');
+ if ($ih) {
+ $ln = -1;
+ while (($curline = fgets($ih)) !== false) {
+ fwrite($fh, (++$ln == $id) ? $line : $curline);
+ }
+ if ($id > $ln) {
+ while ($id > ++$ln)
+ fwrite($fh, "\n");
+ fwrite($fh, $line);
+ }
+ fclose($ih);
+ } else {
+ $ln = -1;
+ while ($id > ++$ln)
+ fwrite($fh, "\n");
+ fwrite($fh, $line);
+ }
+ fclose($fh);
+ if ($conf['fperm'])
+ chmod($fn.'.tmp', $conf['fperm']);
+ io_rename($fn.'.tmp', $fn.'.idx');
+ return true;
+ }
+
+ /**
+ * Retrieve or insert a value in the index.
+ *
+ * @param string $idx name of the index
+ * @param string $suffix subpart identifier
+ * @param string $value line to find in the index
+ * @return int|bool line number of the value in the index or false if writing the index failed
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ protected function addIndexKey($idx, $suffix, $value) {
+ $index = $this->getIndex($idx, $suffix);
+ $id = array_search($value, $index, true);
+ if ($id === false) {
+ $id = count($index);
+ $index[$id] = $value;
+ if (!$this->saveIndex($idx, $suffix, $index)) {
+ trigger_error("Failed to write $idx index", E_USER_ERROR);
+ return false;
+ }
+ }
+ return $id;
+ }
+
+ /**
+ * Get the list of lengths indexed in the wiki.
+ *
+ * Read the index directory or a cache file and returns
+ * a sorted array of lengths of the words used in the wiki.
+ *
+ * @author YoBoY <yoboy.leguesh@gmail.com>
+ *
+ * @return array
+ */
+ protected function listIndexLengths() {
+ return idx_listIndexLengths();
+ }
+
+ /**
+ * Get the word lengths that have been indexed.
+ *
+ * Reads the index directory and returns an array of lengths
+ * that there are indices for.
+ *
+ * @author YoBoY <yoboy.leguesh@gmail.com>
+ *
+ * @param array|int $filter
+ * @return array
+ */
+ protected function indexLengths($filter) {
+ global $conf;
+ $idx = array();
+ if (is_array($filter)) {
+ // testing if index files exist only
+ $path = $conf['indexdir']."/i";
+ foreach ($filter as $key => $value) {
+ if (file_exists($path.$key.'.idx'))
+ $idx[] = $key;
+ }
+ } else {
+ $lengths = idx_listIndexLengths();
+ foreach ($lengths as $key => $length) {
+ // keep all the values equal or superior
+ if ((int)$length >= (int)$filter)
+ $idx[] = $length;
+ }
+ }
+ return $idx;
+ }
+
+ /**
+ * Insert or replace a tuple in a line.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $line
+ * @param string|int $id
+ * @param int $count
+ * @return string
+ */
+ protected function updateTuple($line, $id, $count) {
+ if ($line != ''){
+ $line = preg_replace('/(^|:)'.preg_quote($id,'/').'\*\d*/', '', $line);
+ }
+ $line = trim($line, ':');
+ if ($count) {
+ if ($line) {
+ return "$id*$count:".$line;
+ } else {
+ return "$id*$count";
+ }
+ }
+ return $line;
+ }
+
+ /**
+ * Split a line into an array of tuples.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $keys
+ * @param string $line
+ * @return array
+ */
+ protected function parseTuples(&$keys, $line) {
+ $result = array();
+ if ($line == '') return $result;
+ $parts = explode(':', $line);
+ foreach ($parts as $tuple) {
+ if ($tuple === '') continue;
+ list($key, $cnt) = explode('*', $tuple);
+ if (!$cnt) continue;
+ $key = $keys[$key];
+ if ($key === false || is_null($key)) continue;
+ $result[$key] = $cnt;
+ }
+ return $result;
+ }
+
+ /**
+ * Sum the counts in a list of tuples.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $line
+ * @return int
+ */
+ protected function countTuples($line) {
+ $freq = 0;
+ $parts = explode(':', $line);
+ foreach ($parts as $tuple) {
+ if ($tuple === '') continue;
+ list(/* $pid */, $cnt) = explode('*', $tuple);
+ $freq += (int)$cnt;
+ }
+ return $freq;
+ }
+}
diff --git a/platform/www/inc/Sitemap/Item.php b/platform/www/inc/Sitemap/Item.php
new file mode 100644
index 0000000..d11bfc1
--- /dev/null
+++ b/platform/www/inc/Sitemap/Item.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace dokuwiki\Sitemap;
+
+/**
+ * An item of a sitemap.
+ *
+ * @author Michael Hamann
+ */
+class Item {
+ public $url;
+ public $lastmod;
+ public $changefreq;
+ public $priority;
+
+ /**
+ * Create a new item.
+ *
+ * @param string $url The url of the item
+ * @param int $lastmod Timestamp of the last modification
+ * @param string $changefreq How frequently the item is likely to change.
+ * Valid values: always, hourly, daily, weekly, monthly, yearly, never.
+ * @param $priority float|string The priority of the item relative to other URLs on your site.
+ * Valid values range from 0.0 to 1.0.
+ */
+ public function __construct($url, $lastmod, $changefreq = null, $priority = null) {
+ $this->url = $url;
+ $this->lastmod = $lastmod;
+ $this->changefreq = $changefreq;
+ $this->priority = $priority;
+ }
+
+ /**
+ * Helper function for creating an item for a wikipage id.
+ *
+ * @param string $id A wikipage id.
+ * @param string $changefreq How frequently the item is likely to change.
+ * Valid values: always, hourly, daily, weekly, monthly, yearly, never.
+ * @param float|string $priority The priority of the item relative to other URLs on your site.
+ * Valid values range from 0.0 to 1.0.
+ * @return Item The sitemap item.
+ */
+ public static function createFromID($id, $changefreq = null, $priority = null) {
+ $id = trim($id);
+ $date = @filemtime(wikiFN($id));
+ if(!$date) return null;
+ return new Item(wl($id, '', true), $date, $changefreq, $priority);
+ }
+
+ /**
+ * Get the XML representation of the sitemap item.
+ *
+ * @return string The XML representation.
+ */
+ public function toXML() {
+ $result = ' <url>'.NL
+ .' <loc>'.hsc($this->url).'</loc>'.NL
+ .' <lastmod>'.date_iso8601($this->lastmod).'</lastmod>'.NL;
+ if ($this->changefreq !== null)
+ $result .= ' <changefreq>'.hsc($this->changefreq).'</changefreq>'.NL;
+ if ($this->priority !== null)
+ $result .= ' <priority>'.hsc($this->priority).'</priority>'.NL;
+ $result .= ' </url>'.NL;
+ return $result;
+ }
+}
diff --git a/platform/www/inc/Sitemap/Mapper.php b/platform/www/inc/Sitemap/Mapper.php
new file mode 100644
index 0000000..2f0567f
--- /dev/null
+++ b/platform/www/inc/Sitemap/Mapper.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ * Sitemap handling functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Michael Hamann <michael@content-space.de>
+ */
+
+namespace dokuwiki\Sitemap;
+
+use dokuwiki\HTTP\DokuHTTPClient;
+
+/**
+ * A class for building sitemaps and pinging search engines with the sitemap URL.
+ *
+ * @author Michael Hamann
+ */
+class Mapper {
+ /**
+ * Builds a Google Sitemap of all public pages known to the indexer
+ *
+ * The map is placed in the cache directory named sitemap.xml.gz - This
+ * file needs to be writable!
+ *
+ * @author Michael Hamann
+ * @author Andreas Gohr
+ * @link https://www.google.com/webmasters/sitemaps/docs/en/about.html
+ * @link http://www.sitemaps.org/
+ *
+ * @return bool
+ */
+ public static function generate(){
+ global $conf;
+ if($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) return false;
+
+ $sitemap = Mapper::getFilePath();
+
+ if(file_exists($sitemap)){
+ if(!is_writable($sitemap)) return false;
+ }else{
+ if(!is_writable(dirname($sitemap))) return false;
+ }
+
+ if(@filesize($sitemap) &&
+ @filemtime($sitemap) > (time()-($conf['sitemap']*86400))){ // 60*60*24=86400
+ dbglog('Sitemapper::generate(): Sitemap up to date');
+ return false;
+ }
+
+ dbglog("Sitemapper::generate(): using $sitemap");
+
+ $pages = idx_get_indexer()->getPages();
+ dbglog('Sitemapper::generate(): creating sitemap using '.count($pages).' pages');
+ $items = array();
+
+ // build the sitemap items
+ foreach($pages as $id){
+ //skip hidden, non existing and restricted files
+ if(isHiddenPage($id)) continue;
+ if(auth_aclcheck($id,'',array()) < AUTH_READ) continue;
+ $item = Item::createFromID($id);
+ if ($item !== null)
+ $items[] = $item;
+ }
+
+ $eventData = array('items' => &$items, 'sitemap' => &$sitemap);
+ $event = new \dokuwiki\Extension\Event('SITEMAP_GENERATE', $eventData);
+ if ($event->advise_before(true)) {
+ //save the new sitemap
+ $event->result = io_saveFile($sitemap, Mapper::getXML($items));
+ }
+ $event->advise_after();
+
+ return $event->result;
+ }
+
+ /**
+ * Builds the sitemap XML string from the given array auf SitemapItems.
+ *
+ * @param $items array The SitemapItems that shall be included in the sitemap.
+ * @return string The sitemap XML.
+ *
+ * @author Michael Hamann
+ */
+ private static function getXML($items) {
+ ob_start();
+ echo '<?xml version="1.0" encoding="UTF-8"?>'.NL;
+ echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'.NL;
+ foreach ($items as $item) {
+ /** @var Item $item */
+ echo $item->toXML();
+ }
+ echo '</urlset>'.NL;
+ $result = ob_get_contents();
+ ob_end_clean();
+ return $result;
+ }
+
+ /**
+ * Helper function for getting the path to the sitemap file.
+ *
+ * @return string The path to the sitemap file.
+ *
+ * @author Michael Hamann
+ */
+ public static function getFilePath() {
+ global $conf;
+
+ $sitemap = $conf['cachedir'].'/sitemap.xml';
+ if (self::sitemapIsCompressed()) {
+ $sitemap .= '.gz';
+ }
+
+ return $sitemap;
+ }
+
+ /**
+ * Helper function for checking if the sitemap is compressed
+ *
+ * @return bool If the sitemap file is compressed
+ */
+ public static function sitemapIsCompressed() {
+ global $conf;
+ return $conf['compression'] === 'bz2' || $conf['compression'] === 'gz';
+ }
+
+ /**
+ * Pings search engines with the sitemap url. Plugins can add or remove
+ * urls to ping using the SITEMAP_PING event.
+ *
+ * @author Michael Hamann
+ *
+ * @return bool
+ */
+ public static function pingSearchEngines() {
+ //ping search engines...
+ $http = new DokuHTTPClient();
+ $http->timeout = 8;
+
+ $encoded_sitemap_url = urlencode(wl('', array('do' => 'sitemap'), true, '&'));
+ $ping_urls = array(
+ 'google' => 'http://www.google.com/webmasters/sitemaps/ping?sitemap='.$encoded_sitemap_url,
+ 'microsoft' => 'http://www.bing.com/webmaster/ping.aspx?siteMap='.$encoded_sitemap_url,
+ 'yandex' => 'http://blogs.yandex.ru/pings/?status=success&url='.$encoded_sitemap_url
+ );
+
+ $data = array('ping_urls' => $ping_urls,
+ 'encoded_sitemap_url' => $encoded_sitemap_url
+ );
+ $event = new \dokuwiki\Extension\Event('SITEMAP_PING', $data);
+ if ($event->advise_before(true)) {
+ foreach ($data['ping_urls'] as $name => $url) {
+ dbglog("Sitemapper::PingSearchEngines(): pinging $name");
+ $resp = $http->get($url);
+ if($http->error) dbglog("Sitemapper:pingSearchengines(): $http->error");
+ dbglog('Sitemapper:pingSearchengines(): '.preg_replace('/[\n\r]/',' ',strip_tags($resp)));
+ }
+ }
+ $event->advise_after();
+
+ return true;
+ }
+}
+
diff --git a/platform/www/inc/StyleUtils.php b/platform/www/inc/StyleUtils.php
new file mode 100644
index 0000000..d9f19a5
--- /dev/null
+++ b/platform/www/inc/StyleUtils.php
@@ -0,0 +1,194 @@
+<?php
+
+namespace dokuwiki;
+
+/**
+ * Class StyleUtils
+ *
+ * Reads and applies the template's style.ini settings
+ */
+class StyleUtils
+{
+
+ /** @var string current template */
+ protected $tpl;
+ /** @var bool reinitialize styles config */
+ protected $reinit;
+ /** @var bool $preview preview mode */
+ protected $preview;
+ /** @var array default replacements to be merged with custom style configs */
+ protected $defaultReplacements = array(
+ '__text__' => "#000",
+ '__background__' => "#fff",
+ '__text_alt__' => "#999",
+ '__background_alt__' => "#eee",
+ '__text_neu__' => "#666",
+ '__background_neu__' => "#ddd",
+ '__border__' => "#ccc",
+ '__highlight__' => "#ff9",
+ '__link__' => "#00f",
+ );
+
+ /**
+ * StyleUtils constructor.
+ * @param string $tpl template name: if not passed as argument, the default value from $conf will be used
+ * @param bool $preview
+ * @param bool $reinit whether static style conf should be reinitialized
+ */
+ public function __construct($tpl = '', $preview = false, $reinit = false)
+ {
+ if (!$tpl) {
+ global $conf;
+ $tpl = $conf['template'];
+ }
+ $this->tpl = $tpl;
+ $this->reinit = $reinit;
+ $this->preview = $preview;
+ }
+
+ /**
+ * Load style ini contents
+ *
+ * Loads and merges style.ini files from template and config and prepares
+ * the stylesheet modes
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anna Dabrowska <info@cosmocode.de>
+ *
+ * @return array with keys 'stylesheets' and 'replacements'
+ */
+ public function cssStyleini()
+ {
+ static $combined = [];
+ if (!empty($combined) && !$this->reinit) {
+ return $combined;
+ }
+
+ global $conf;
+ global $config_cascade;
+ $stylesheets = array(); // mode, file => base
+
+ // guaranteed placeholder => value
+ $replacements = $this->defaultReplacements;
+
+ // merge all styles from config cascade
+ if (!is_array($config_cascade['styleini'])) {
+ trigger_error('Missing config cascade for styleini', E_USER_WARNING);
+ }
+
+ // allow replacement overwrites in preview mode
+ if ($this->preview) {
+ $config_cascade['styleini']['local'][] = $conf['cachedir'] . '/preview.ini';
+ }
+
+ $combined['stylesheets'] = [];
+ $combined['replacements'] = [];
+
+ foreach (array('default', 'local', 'protected') as $config_group) {
+ if (empty($config_cascade['styleini'][$config_group])) continue;
+
+ // set proper server dirs
+ $webbase = $this->getWebbase($config_group);
+
+ foreach ($config_cascade['styleini'][$config_group] as $inifile) {
+ // replace the placeholder with the name of the current template
+ $inifile = str_replace('%TEMPLATE%', $this->tpl, $inifile);
+
+ $incbase = dirname($inifile) . '/';
+
+ if (file_exists($inifile)) {
+ $config = parse_ini_file($inifile, true);
+
+ if (is_array($config['stylesheets'])) {
+ foreach ($config['stylesheets'] as $inifile => $mode) {
+ // validate and include style files
+ $stylesheets = array_merge(
+ $stylesheets,
+ $this->getValidatedStyles($stylesheets, $inifile, $mode, $incbase, $webbase)
+ );
+ $combined['stylesheets'] = array_merge($combined['stylesheets'], $stylesheets);
+ }
+ }
+
+ if (is_array($config['replacements'])) {
+ $replacements = array_replace(
+ $replacements,
+ $this->cssFixreplacementurls($config['replacements'], $webbase)
+ );
+ $combined['replacements'] = array_merge($combined['replacements'], $replacements);
+ }
+ }
+ }
+ }
+
+ return $combined;
+ }
+
+ /**
+ * Checks if configured style files exist and, if necessary, adjusts file extensions in config
+ *
+ * @param array $stylesheets
+ * @param string $file
+ * @param string $mode
+ * @param string $incbase
+ * @param string $webbase
+ * @return mixed
+ */
+ protected function getValidatedStyles($stylesheets, $file, $mode, $incbase, $webbase)
+ {
+ global $conf;
+ if (!file_exists($incbase . $file)) {
+ list($extension, $basename) = array_map('strrev', explode('.', strrev($file), 2));
+ $newExtension = $extension === 'css' ? 'less' : 'css';
+ if (file_exists($incbase . $basename . '.' . $newExtension)) {
+ $stylesheets[$mode][$incbase . $basename . '.' . $newExtension] = $webbase;
+ if ($conf['allowdebug']) {
+ msg("Stylesheet $file not found, using $basename.$newExtension instead. " .
+ "Please contact developer of \"$this->tpl\" template.", 2);
+ }
+ } elseif ($conf['allowdebug']) {
+ msg("Stylesheet $file not found, please contact the developer of \"$this->tpl\" template.", 2);
+ }
+ }
+ $stylesheets[$mode][fullpath($incbase . $file)] = $webbase;
+ return $stylesheets;
+ }
+
+ /**
+ * Returns the web base path for the given level/group in config cascade.
+ * Style resources are relative to the template directory for the main (default) styles
+ * but relative to DOKU_BASE for everything else"
+ *
+ * @param string $config_group
+ * @return string
+ */
+ protected function getWebbase($config_group)
+ {
+ if ($config_group === 'default') {
+ return tpl_basedir($this->tpl);
+ } else {
+ return DOKU_BASE;
+ }
+ }
+
+ /**
+ * Amend paths used in replacement relative urls, refer FS#2879
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param array $replacements with key-value pairs
+ * @param string $location
+ * @return array
+ */
+ protected function cssFixreplacementurls($replacements, $location)
+ {
+ foreach ($replacements as $key => $value) {
+ $replacements[$key] = preg_replace(
+ '#(url\([ \'"]*)(?!/|data:|http://|https://| |\'|")#',
+ '\\1' . $location,
+ $value
+ );
+ }
+ return $replacements;
+ }
+}
diff --git a/platform/www/inc/Subscriptions/BulkSubscriptionSender.php b/platform/www/inc/Subscriptions/BulkSubscriptionSender.php
new file mode 100644
index 0000000..672ef90
--- /dev/null
+++ b/platform/www/inc/Subscriptions/BulkSubscriptionSender.php
@@ -0,0 +1,261 @@
+<?php
+
+
+namespace dokuwiki\Subscriptions;
+
+
+use dokuwiki\ChangeLog\PageChangeLog;
+use dokuwiki\Input\Input;
+use DokuWiki_Auth_Plugin;
+
+class BulkSubscriptionSender extends SubscriptionSender
+{
+
+ /**
+ * Send digest and list subscriptions
+ *
+ * This sends mails to all subscribers that have a subscription for namespaces above
+ * the given page if the needed $conf['subscribe_time'] has passed already.
+ *
+ * This function is called form lib/exe/indexer.php
+ *
+ * @param string $page
+ *
+ * @return int number of sent mails
+ */
+ public function sendBulk($page)
+ {
+ $subscriberManager = new SubscriberManager();
+ if (!$subscriberManager->isenabled()) {
+ return 0;
+ }
+
+ /** @var DokuWiki_Auth_Plugin $auth */
+ global $auth;
+ global $conf;
+ global $USERINFO;
+ /** @var Input $INPUT */
+ global $INPUT;
+ $count = 0;
+
+ $subscriptions = $subscriberManager->subscribers($page, null, ['digest', 'list']);
+
+ // remember current user info
+ $olduinfo = $USERINFO;
+ $olduser = $INPUT->server->str('REMOTE_USER');
+
+ foreach ($subscriptions as $target => $users) {
+ if (!$this->lock($target)) {
+ continue;
+ }
+
+ foreach ($users as $user => $info) {
+ list($style, $lastupdate) = $info;
+
+ $lastupdate = (int)$lastupdate;
+ if ($lastupdate + $conf['subscribe_time'] > time()) {
+ // Less than the configured time period passed since last
+ // update.
+ continue;
+ }
+
+ // Work as the user to make sure ACLs apply correctly
+ $USERINFO = $auth->getUserData($user);
+ $INPUT->server->set('REMOTE_USER', $user);
+ if ($USERINFO === false) {
+ continue;
+ }
+ if (!$USERINFO['mail']) {
+ continue;
+ }
+
+ if (substr($target, -1, 1) === ':') {
+ // subscription target is a namespace, get all changes within
+ $changes = getRecentsSince($lastupdate, null, getNS($target));
+ } else {
+ // single page subscription, check ACL ourselves
+ if (auth_quickaclcheck($target) < AUTH_READ) {
+ continue;
+ }
+ $meta = p_get_metadata($target);
+ $changes = [$meta['last_change']];
+ }
+
+ // Filter out pages only changed in small and own edits
+ $change_ids = [];
+ foreach ($changes as $rev) {
+ $n = 0;
+ while (!is_null($rev) && $rev['date'] >= $lastupdate &&
+ ($INPUT->server->str('REMOTE_USER') === $rev['user'] ||
+ $rev['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT)) {
+ $pagelog = new PageChangeLog($rev['id']);
+ $rev = $pagelog->getRevisions($n++, 1);
+ $rev = (count($rev) > 0) ? $rev[0] : null;
+ }
+
+ if (!is_null($rev) && $rev['date'] >= $lastupdate) {
+ // Some change was not a minor one and not by myself
+ $change_ids[] = $rev['id'];
+ }
+ }
+
+ // send it
+ if ($style === 'digest') {
+ foreach ($change_ids as $change_id) {
+ $this->sendDigest(
+ $USERINFO['mail'],
+ $change_id,
+ $lastupdate
+ );
+ $count++;
+ }
+ } else {
+ if ($style === 'list') {
+ $this->sendList($USERINFO['mail'], $change_ids, $target);
+ $count++;
+ }
+ }
+ // TODO: Handle duplicate subscriptions.
+
+ // Update notification time.
+ $subscriberManager->add($target, $user, $style, time());
+ }
+ $this->unlock($target);
+ }
+
+ // restore current user info
+ $USERINFO = $olduinfo;
+ $INPUT->server->set('REMOTE_USER', $olduser);
+ return $count;
+ }
+
+ /**
+ * Lock subscription info
+ *
+ * We don't use io_lock() her because we do not wait for the lock and use a larger stale time
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ *
+ * @return bool true, if you got a succesful lock
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+ protected function lock($id)
+ {
+ global $conf;
+
+ $lock = $conf['lockdir'] . '/_subscr_' . md5($id) . '.lock';
+
+ if (is_dir($lock) && time() - @filemtime($lock) > 60 * 5) {
+ // looks like a stale lock - remove it
+ @rmdir($lock);
+ }
+
+ // try creating the lock directory
+ if (!@mkdir($lock, $conf['dmode'])) {
+ return false;
+ }
+
+ if (!empty($conf['dperm'])) {
+ chmod($lock, $conf['dperm']);
+ }
+ return true;
+ }
+
+ /**
+ * Unlock subscription info
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ *
+ * @return bool
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+ protected function unlock($id)
+ {
+ global $conf;
+ $lock = $conf['lockdir'] . '/_subscr_' . md5($id) . '.lock';
+ return @rmdir($lock);
+ }
+
+ /**
+ * Send a digest mail
+ *
+ * Sends a digest mail showing a bunch of changes of a single page. Basically the same as sendPageDiff()
+ * but determines the last known revision first
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param string $id The ID
+ * @param int $lastupdate Time of the last notification
+ *
+ * @return bool
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ */
+ protected function sendDigest($subscriber_mail, $id, $lastupdate)
+ {
+ $pagelog = new PageChangeLog($id);
+ $n = 0;
+ do {
+ $rev = $pagelog->getRevisions($n++, 1);
+ $rev = (count($rev) > 0) ? $rev[0] : null;
+ } while (!is_null($rev) && $rev > $lastupdate);
+
+ // TODO I'm not happy with the following line and passing $this->mailer around. Not sure how to solve it better
+ $pageSubSender = new PageSubscriptionSender($this->mailer);
+ return $pageSubSender->sendPageDiff(
+ $subscriber_mail,
+ 'subscr_digest',
+ $id,
+ $rev
+ );
+ }
+
+ /**
+ * Send a list mail
+ *
+ * Sends a list mail showing a list of changed pages.
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param array $ids Array of ids
+ * @param string $ns_id The id of the namespace
+ *
+ * @return bool true if a mail was sent
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ */
+ protected function sendList($subscriber_mail, $ids, $ns_id)
+ {
+ if (count($ids) === 0) {
+ return false;
+ }
+
+ $tlist = '';
+ $hlist = '<ul>';
+ foreach ($ids as $id) {
+ $link = wl($id, [], true);
+ $tlist .= '* ' . $link . NL;
+ $hlist .= '<li><a href="' . $link . '">' . hsc($id) . '</a></li>' . NL;
+ }
+ $hlist .= '</ul>';
+
+ $id = prettyprint_id($ns_id);
+ $trep = [
+ 'DIFF' => rtrim($tlist),
+ 'PAGE' => $id,
+ 'SUBSCRIBE' => wl($id, ['do' => 'subscribe'], true, '&'),
+ ];
+ $hrep = [
+ 'DIFF' => $hlist,
+ ];
+
+ return $this->send(
+ $subscriber_mail,
+ 'subscribe_list',
+ $ns_id,
+ 'subscr_list',
+ $trep,
+ $hrep
+ );
+ }
+}
diff --git a/platform/www/inc/Subscriptions/MediaSubscriptionSender.php b/platform/www/inc/Subscriptions/MediaSubscriptionSender.php
new file mode 100644
index 0000000..1757c2b
--- /dev/null
+++ b/platform/www/inc/Subscriptions/MediaSubscriptionSender.php
@@ -0,0 +1,47 @@
+<?php
+
+
+namespace dokuwiki\Subscriptions;
+
+
+class MediaSubscriptionSender extends SubscriptionSender
+{
+
+ /**
+ * Send the diff for some media change
+ *
+ * @fixme this should embed thumbnails of images in HTML version
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param string $template Mail template ('uploadmail', ...)
+ * @param string $id Media file for which the notification is
+ * @param int|bool $rev Old revision if any
+ * @param int|bool $current_rev New revision if any
+ */
+ public function sendMediaDiff($subscriber_mail, $template, $id, $rev = false, $current_rev = false)
+ {
+ global $conf;
+
+ $file = mediaFN($id);
+ list($mime, /* $ext */) = mimetype($id);
+
+ $trep = [
+ 'MIME' => $mime,
+ 'MEDIA' => ml($id, $current_rev?('rev='.$current_rev):'', true, '&', true),
+ 'SIZE' => filesize_h(filesize($file)),
+ ];
+
+ if ($rev && $conf['mediarevisions']) {
+ $trep['OLD'] = ml($id, "rev=$rev", true, '&', true);
+ } else {
+ $trep['OLD'] = '---';
+ }
+
+ $headers = ['Message-Id' => $this->getMessageID($id, @filemtime($file))];
+ if ($rev) {
+ $headers['In-Reply-To'] = $this->getMessageID($id, $rev);
+ }
+
+ $this->send($subscriber_mail, 'upload', $id, $template, $trep, null, $headers);
+ }
+}
diff --git a/platform/www/inc/Subscriptions/PageSubscriptionSender.php b/platform/www/inc/Subscriptions/PageSubscriptionSender.php
new file mode 100644
index 0000000..e5577c1
--- /dev/null
+++ b/platform/www/inc/Subscriptions/PageSubscriptionSender.php
@@ -0,0 +1,88 @@
+<?php
+
+
+namespace dokuwiki\Subscriptions;
+
+
+use Diff;
+use InlineDiffFormatter;
+use UnifiedDiffFormatter;
+
+class PageSubscriptionSender extends SubscriptionSender
+{
+
+ /**
+ * Send the diff for some page change
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param string $template Mail template ('subscr_digest', 'subscr_single', 'mailtext', ...)
+ * @param string $id Page for which the notification is
+ * @param int|null $rev Old revision if any
+ * @param string $summary Change summary if any
+ * @param int|null $current_rev New revision if any
+ *
+ * @return bool true if successfully sent
+ */
+ public function sendPageDiff($subscriber_mail, $template, $id, $rev = null, $summary = '', $current_rev = null)
+ {
+ global $DIFF_INLINESTYLES;
+
+ // prepare replacements (keys not set in hrep will be taken from trep)
+ $trep = [
+ 'PAGE' => $id,
+ 'NEWPAGE' => wl($id, $current_rev?('rev='.$current_rev):'', true, '&'),
+ 'SUMMARY' => $summary,
+ 'SUBSCRIBE' => wl($id, ['do' => 'subscribe'], true, '&'),
+ ];
+ $hrep = [];
+
+ if ($rev) {
+ $subject = 'changed';
+ $trep['OLDPAGE'] = wl($id, "rev=$rev", true, '&');
+
+ $old_content = rawWiki($id, $rev);
+ $new_content = rawWiki($id);
+
+ $df = new Diff(
+ explode("\n", $old_content),
+ explode("\n", $new_content)
+ );
+ $dformat = new UnifiedDiffFormatter();
+ $tdiff = $dformat->format($df);
+
+ $DIFF_INLINESTYLES = true;
+ $df = new Diff(
+ explode("\n", $old_content),
+ explode("\n", $new_content)
+ );
+ $dformat = new InlineDiffFormatter();
+ $hdiff = $dformat->format($df);
+ $hdiff = '<table>' . $hdiff . '</table>';
+ $DIFF_INLINESTYLES = false;
+ } else {
+ $subject = 'newpage';
+ $trep['OLDPAGE'] = '---';
+ $tdiff = rawWiki($id);
+ $hdiff = nl2br(hsc($tdiff));
+ }
+
+ $trep['DIFF'] = $tdiff;
+ $hrep['DIFF'] = $hdiff;
+
+ $headers = ['Message-Id' => $this->getMessageID($id)];
+ if ($rev) {
+ $headers['In-Reply-To'] = $this->getMessageID($id, $rev);
+ }
+
+ return $this->send(
+ $subscriber_mail,
+ $subject,
+ $id,
+ $template,
+ $trep,
+ $hrep,
+ $headers
+ );
+ }
+
+}
diff --git a/platform/www/inc/Subscriptions/RegistrationSubscriptionSender.php b/platform/www/inc/Subscriptions/RegistrationSubscriptionSender.php
new file mode 100644
index 0000000..bd48875
--- /dev/null
+++ b/platform/www/inc/Subscriptions/RegistrationSubscriptionSender.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace dokuwiki\Subscriptions;
+
+class RegistrationSubscriptionSender extends SubscriptionSender
+{
+
+ /**
+ * Send a notify mail on new registration
+ *
+ * @param string $login login name of the new user
+ * @param string $fullname full name of the new user
+ * @param string $email email address of the new user
+ *
+ * @return bool true if a mail was sent
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ */
+ public function sendRegister($login, $fullname, $email)
+ {
+ global $conf;
+ if (empty($conf['registernotify'])) {
+ return false;
+ }
+
+ $trep = [
+ 'NEWUSER' => $login,
+ 'NEWNAME' => $fullname,
+ 'NEWEMAIL' => $email,
+ ];
+
+ return $this->send(
+ $conf['registernotify'],
+ 'new_user',
+ $login,
+ 'registermail',
+ $trep
+ );
+ }
+}
diff --git a/platform/www/inc/Subscriptions/SubscriberManager.php b/platform/www/inc/Subscriptions/SubscriberManager.php
new file mode 100644
index 0000000..ded1390
--- /dev/null
+++ b/platform/www/inc/Subscriptions/SubscriberManager.php
@@ -0,0 +1,290 @@
+<?php
+
+namespace dokuwiki\Subscriptions;
+
+use dokuwiki\Input\Input;
+use DokuWiki_Auth_Plugin;
+use Exception;
+
+class SubscriberManager
+{
+
+ /**
+ * Check if subscription system is enabled
+ *
+ * @return bool
+ */
+ public function isenabled()
+ {
+ return actionOK('subscribe');
+ }
+
+ /**
+ * Adds a new subscription for the given page or namespace
+ *
+ * This will automatically overwrite any existent subscription for the given user on this
+ * *exact* page or namespace. It will *not* modify any subscription that may exist in higher namespaces.
+ *
+ * @throws Exception when user or style is empty
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ * @param string $user
+ * @param string $style
+ * @param string $data
+ *
+ * @return bool
+ */
+ public function add($id, $user, $style, $data = '')
+ {
+ if (!$this->isenabled()) {
+ return false;
+ }
+
+ // delete any existing subscription
+ $this->remove($id, $user);
+
+ $user = auth_nameencode(trim($user));
+ $style = trim($style);
+ $data = trim($data);
+
+ if (!$user) {
+ throw new Exception('no subscription user given');
+ }
+ if (!$style) {
+ throw new Exception('no subscription style given');
+ }
+ if (!$data) {
+ $data = time();
+ } //always add current time for new subscriptions
+
+ $line = "$user $style $data\n";
+ $file = $this->file($id);
+ return io_saveFile($file, $line, true);
+ }
+
+
+ /**
+ * Removes a subscription for the given page or namespace
+ *
+ * This removes all subscriptions matching the given criteria on the given page or
+ * namespace. It will *not* modify any subscriptions that may exist in higher
+ * namespaces.
+ *
+ * @param string $id The target object’s (namespace or page) id
+ * @param string|array $user
+ * @param string|array $style
+ * @param string|array $data
+ *
+ * @return bool
+ */
+ public function remove($id, $user = null, $style = null, $data = null)
+ {
+ if (!$this->isenabled()) {
+ return false;
+ }
+
+ $file = $this->file($id);
+ if (!file_exists($file)) {
+ return true;
+ }
+
+ $regexBuilder = new SubscriberRegexBuilder();
+ $re = $regexBuilder->buildRegex($user, $style, $data);
+ return io_deleteFromFile($file, $re, true);
+ }
+
+ /**
+ * Get data for $INFO['subscribed']
+ *
+ * $INFO['subscribed'] is either false if no subscription for the current page
+ * and user is in effect. Else it contains an array of arrays with the fields
+ * “targetâ€, “styleâ€, and optionally “dataâ€.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $id Page ID, defaults to global $ID
+ * @param string $user User, defaults to $_SERVER['REMOTE_USER']
+ *
+ * @return array|false
+ */
+ public function userSubscription($id = '', $user = '')
+ {
+ if (!$this->isenabled()) {
+ return false;
+ }
+
+ global $ID;
+ /** @var Input $INPUT */
+ global $INPUT;
+ if (!$id) {
+ $id = $ID;
+ }
+ if (!$user) {
+ $user = $INPUT->server->str('REMOTE_USER');
+ }
+
+ if (empty($user)) {
+ // not logged in
+ return false;
+ }
+
+ $subs = $this->subscribers($id, $user);
+ if (!count($subs)) {
+ return false;
+ }
+
+ $result = [];
+ foreach ($subs as $target => $info) {
+ $result[] = [
+ 'target' => $target,
+ 'style' => $info[$user][0],
+ 'data' => $info[$user][1],
+ ];
+ }
+
+ return $result;
+ }
+
+ /**
+ * Recursively search for matching subscriptions
+ *
+ * This function searches all relevant subscription files for a page or
+ * namespace.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $page The target object’s (namespace or page) id
+ * @param string|array $user
+ * @param string|array $style
+ * @param string|array $data
+ *
+ * @return array
+ */
+ public function subscribers($page, $user = null, $style = null, $data = null)
+ {
+ if (!$this->isenabled()) {
+ return [];
+ }
+
+ // Construct list of files which may contain relevant subscriptions.
+ $files = [':' => $this->file(':')];
+ do {
+ $files[$page] = $this->file($page);
+ $page = getNS(rtrim($page, ':')) . ':';
+ } while ($page !== ':');
+
+ $regexBuilder = new SubscriberRegexBuilder();
+ $re = $regexBuilder->buildRegex($user, $style, $data);
+
+ // Handle files.
+ $result = [];
+ foreach ($files as $target => $file) {
+ if (!file_exists($file)) {
+ continue;
+ }
+
+ $lines = file($file);
+ foreach ($lines as $line) {
+ // fix old style subscription files
+ if (strpos($line, ' ') === false) {
+ $line = trim($line) . " every\n";
+ }
+
+ // check for matching entries
+ if (!preg_match($re, $line, $m)) {
+ continue;
+ }
+
+ $u = rawurldecode($m[1]); // decode the user name
+ if (!isset($result[$target])) {
+ $result[$target] = [];
+ }
+ $result[$target][$u] = [$m[2], $m[3]]; // add to result
+ }
+ }
+ return array_reverse($result);
+ }
+
+ /**
+ * Default callback for COMMON_NOTIFY_ADDRESSLIST
+ *
+ * Aggregates all email addresses of user who have subscribed the given page with 'every' style
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @author Steven Danz <steven-danz@kc.rr.com>
+ *
+ * @todo move the whole functionality into this class, trigger SUBSCRIPTION_NOTIFY_ADDRESSLIST instead,
+ * use an array for the addresses within it
+ *
+ * @param array &$data Containing the entries:
+ * - $id (the page id),
+ * - $self (whether the author should be notified,
+ * - $addresslist (current email address list)
+ * - $replacements (array of additional string substitutions, @KEY@ to be replaced by value)
+ */
+ public function notifyAddresses(&$data)
+ {
+ if (!$this->isenabled()) {
+ return;
+ }
+
+ /** @var DokuWiki_Auth_Plugin $auth */
+ global $auth;
+ global $conf;
+ /** @var \Input $INPUT */
+ global $INPUT;
+
+ $id = $data['id'];
+ $self = $data['self'];
+ $addresslist = $data['addresslist'];
+
+ $subscriptions = $this->subscribers($id, null, 'every');
+
+ $result = [];
+ foreach ($subscriptions as $target => $users) {
+ foreach ($users as $user => $info) {
+ $userinfo = $auth->getUserData($user);
+ if ($userinfo === false) {
+ continue;
+ }
+ if (!$userinfo['mail']) {
+ continue;
+ }
+ if (!$self && $user == $INPUT->server->str('REMOTE_USER')) {
+ continue;
+ } //skip our own changes
+
+ $level = auth_aclcheck($id, $user, $userinfo['grps']);
+ if ($level >= AUTH_READ) {
+ if (strcasecmp($userinfo['mail'], $conf['notify']) != 0) { //skip user who get notified elsewhere
+ $result[$user] = $userinfo['mail'];
+ }
+ }
+ }
+ }
+ $data['addresslist'] = trim($addresslist . ',' . implode(',', $result), ',');
+ }
+
+ /**
+ * Return the subscription meta file for the given ID
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ *
+ * @return string
+ */
+ protected function file($id)
+ {
+ $meta_fname = '.mlist';
+ if ((substr($id, -1, 1) === ':')) {
+ $meta_froot = getNS($id);
+ $meta_fname = '/' . $meta_fname;
+ } else {
+ $meta_froot = $id;
+ }
+ return metaFN((string)$meta_froot, $meta_fname);
+ }
+}
diff --git a/platform/www/inc/Subscriptions/SubscriberRegexBuilder.php b/platform/www/inc/Subscriptions/SubscriberRegexBuilder.php
new file mode 100644
index 0000000..959702a
--- /dev/null
+++ b/platform/www/inc/Subscriptions/SubscriberRegexBuilder.php
@@ -0,0 +1,70 @@
+<?php
+
+namespace dokuwiki\Subscriptions;
+
+use Exception;
+
+class SubscriberRegexBuilder
+{
+
+ /**
+ * Construct a regular expression for parsing a subscription definition line
+ *
+ * @param string|array $user
+ * @param string|array $style
+ * @param string|array $data
+ *
+ * @return string complete regexp including delimiters
+ * @throws Exception when no data is passed
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ */
+ public function buildRegex($user = null, $style = null, $data = null)
+ {
+ // always work with arrays
+ $user = (array)$user;
+ $style = (array)$style;
+ $data = (array)$data;
+
+ // clean
+ $user = array_filter(array_map('trim', $user));
+ $style = array_filter(array_map('trim', $style));
+ $data = array_filter(array_map('trim', $data));
+
+ // user names are encoded
+ $user = array_map('auth_nameencode', $user);
+
+ // quote
+ $user = array_map('preg_quote_cb', $user);
+ $style = array_map('preg_quote_cb', $style);
+ $data = array_map('preg_quote_cb', $data);
+
+ // join
+ $user = join('|', $user);
+ $style = join('|', $style);
+ $data = join('|', $data);
+
+ // any data at all?
+ if ($user . $style . $data === '') {
+ throw new Exception('no data passed');
+ }
+
+ // replace empty values, set which ones are optional
+ $sopt = '';
+ $dopt = '';
+ if ($user === '') {
+ $user = '\S+';
+ }
+ if ($style === '') {
+ $style = '\S+';
+ $sopt = '?';
+ }
+ if ($data === '') {
+ $data = '\S+';
+ $dopt = '?';
+ }
+
+ // assemble
+ return "/^($user)(?:\\s+($style))$sopt(?:\\s+($data))$dopt$/";
+ }
+}
diff --git a/platform/www/inc/Subscriptions/SubscriptionSender.php b/platform/www/inc/Subscriptions/SubscriptionSender.php
new file mode 100644
index 0000000..afc05bf
--- /dev/null
+++ b/platform/www/inc/Subscriptions/SubscriptionSender.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace dokuwiki\Subscriptions;
+
+use Mailer;
+
+abstract class SubscriptionSender
+{
+ protected $mailer;
+
+ public function __construct(Mailer $mailer = null)
+ {
+ if ($mailer === null) {
+ $mailer = new Mailer();
+ }
+ $this->mailer = $mailer;
+ }
+
+ /**
+ * Get a valid message id for a certain $id and revision (or the current revision)
+ *
+ * @param string $id The id of the page (or media file) the message id should be for
+ * @param string $rev The revision of the page, set to the current revision of the page $id if not set
+ *
+ * @return string
+ */
+ protected function getMessageID($id, $rev = null)
+ {
+ static $listid = null;
+ if (is_null($listid)) {
+ $server = parse_url(DOKU_URL, PHP_URL_HOST);
+ $listid = join('.', array_reverse(explode('/', DOKU_BASE))) . $server;
+ $listid = urlencode($listid);
+ $listid = strtolower(trim($listid, '.'));
+ }
+
+ if (is_null($rev)) {
+ $rev = @filemtime(wikiFN($id));
+ }
+
+ return "<$id?rev=$rev@$listid>";
+ }
+
+ /**
+ * Helper function for sending a mail
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param string $subject The lang id of the mail subject (without the
+ * prefix “mail_â€)
+ * @param string $context The context of this mail, eg. page or namespace id
+ * @param string $template The name of the mail template
+ * @param array $trep Predefined parameters used to parse the
+ * template (in text format)
+ * @param array $hrep Predefined parameters used to parse the
+ * template (in HTML format), null to default to $trep
+ * @param array $headers Additional mail headers in the form 'name' => 'value'
+ *
+ * @return bool
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ */
+ protected function send($subscriber_mail, $subject, $context, $template, $trep, $hrep = null, $headers = [])
+ {
+ global $lang;
+ global $conf;
+
+ $text = rawLocale($template);
+ $subject = $lang['mail_' . $subject] . ' ' . $context;
+ $mail = $this->mailer;
+ $mail->bcc($subscriber_mail);
+ $mail->subject($subject);
+ $mail->setBody($text, $trep, $hrep);
+ if (in_array($template, ['subscr_list', 'subscr_digest'])) {
+ $mail->from($conf['mailfromnobody']);
+ }
+ if (isset($trep['SUBSCRIBE'])) {
+ $mail->setHeader('List-Unsubscribe', '<' . $trep['SUBSCRIBE'] . '>', false);
+ }
+
+ foreach ($headers as $header => $value) {
+ $mail->setHeader($header, $value);
+ }
+
+ return $mail->send();
+ }
+}
diff --git a/platform/www/inc/TaskRunner.php b/platform/www/inc/TaskRunner.php
new file mode 100644
index 0000000..c5de7e3
--- /dev/null
+++ b/platform/www/inc/TaskRunner.php
@@ -0,0 +1,240 @@
+<?php
+
+namespace dokuwiki;
+
+use dokuwiki\Extension\Event;
+use dokuwiki\Sitemap\Mapper;
+use dokuwiki\Subscriptions\BulkSubscriptionSender;
+
+/**
+ * Class TaskRunner
+ *
+ * Run an asynchronous task.
+ */
+class TaskRunner
+{
+ /**
+ * Run the next task
+ *
+ * @todo refactor to remove dependencies on globals
+ * @triggers INDEXER_TASKS_RUN
+ */
+ public function run()
+ {
+ global $INPUT, $conf, $ID;
+
+ // keep running after browser closes connection
+ @ignore_user_abort(true);
+
+ // check if user abort worked, if yes send output early
+ $defer = !@ignore_user_abort() || $conf['broken_iua'];
+ $output = $INPUT->has('debug') && $conf['allowdebug'];
+ if(!$defer && !$output){
+ $this->sendGIF();
+ }
+
+ $ID = cleanID($INPUT->str('id'));
+
+ // Catch any possible output (e.g. errors)
+ if(!$output) {
+ ob_start();
+ } else {
+ header('Content-Type: text/plain');
+ }
+
+ // run one of the jobs
+ $tmp = []; // No event data
+ $evt = new Event('INDEXER_TASKS_RUN', $tmp);
+ if ($evt->advise_before()) {
+ $this->runIndexer() or
+ $this->runSitemapper() or
+ $this->sendDigest() or
+ $this->runTrimRecentChanges() or
+ $this->runTrimRecentChanges(true) or
+ $evt->advise_after();
+ }
+
+ if(!$output) {
+ ob_end_clean();
+ if($defer) {
+ $this->sendGIF();
+ }
+ }
+ }
+
+ /**
+ * Just send a 1x1 pixel blank gif to the browser
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Harry Fuecks <fuecks@gmail.com>
+ */
+ protected function sendGIF()
+ {
+ $img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
+ header('Content-Type: image/gif');
+ header('Content-Length: '.strlen($img));
+ header('Connection: Close');
+ print $img;
+ tpl_flush();
+ // Browser should drop connection after this
+ // Thinks it's got the whole image
+ }
+
+ /**
+ * Trims the recent changes cache (or imports the old changelog) as needed.
+ *
+ * @param bool $media_changes If the media changelog shall be trimmed instead of
+ * the page changelog
+ *
+ * @return bool
+ * @triggers TASK_RECENTCHANGES_TRIM
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+ protected function runTrimRecentChanges($media_changes = false)
+ {
+ global $conf;
+
+ echo "runTrimRecentChanges($media_changes): started" . NL;
+
+ $fn = ($media_changes ? $conf['media_changelog'] : $conf['changelog']);
+
+ // Trim the Recent Changes
+ // Trims the recent changes cache to the last $conf['changes_days'] recent
+ // changes or $conf['recent'] items, which ever is larger.
+ // The trimming is only done once a day.
+ if (file_exists($fn) &&
+ (@filemtime($fn . '.trimmed') + 86400) < time() &&
+ !file_exists($fn . '_tmp')) {
+ @touch($fn . '.trimmed');
+ io_lock($fn);
+ $lines = file($fn);
+ if (count($lines) <= $conf['recent']) {
+ // nothing to trim
+ io_unlock($fn);
+ echo "runTrimRecentChanges($media_changes): finished" . NL;
+ return false;
+ }
+
+ io_saveFile($fn . '_tmp', ''); // presave tmp as 2nd lock
+ $trim_time = time() - $conf['recent_days'] * 86400;
+ $out_lines = [];
+ $old_lines = [];
+ for ($i = 0; $i < count($lines); $i++) {
+ $log = parseChangelogLine($lines[$i]);
+ if ($log === false) {
+ continue; // discard junk
+ }
+
+ if ($log['date'] < $trim_time) {
+ // keep old lines for now (append .$i to prevent key collisions)
+ $old_lines[$log['date'] . ".$i"] = $lines[$i];
+ } else {
+ // definitely keep these lines
+ $out_lines[$log['date'] . ".$i"] = $lines[$i];
+ }
+ }
+
+ if (count($lines) == count($out_lines)) {
+ // nothing to trim
+ @unlink($fn . '_tmp');
+ io_unlock($fn);
+ echo "runTrimRecentChanges($media_changes): finished" . NL;
+ return false;
+ }
+
+ // sort the final result, it shouldn't be necessary,
+ // however the extra robustness in making the changelog cache self-correcting is worth it
+ ksort($out_lines);
+ $extra = $conf['recent'] - count($out_lines); // do we need extra lines do bring us up to minimum
+ if ($extra > 0) {
+ ksort($old_lines);
+ $out_lines = array_merge(array_slice($old_lines, -$extra), $out_lines);
+ }
+
+ $eventData = [
+ 'isMedia' => $media_changes,
+ 'trimmedChangelogLines' => $out_lines,
+ 'removedChangelogLines' => $extra > 0 ? array_slice($old_lines, 0, -$extra) : $old_lines,
+ ];
+ Event::createAndTrigger('TASK_RECENTCHANGES_TRIM', $eventData);
+ $out_lines = $eventData['trimmedChangelogLines'];
+
+ // save trimmed changelog
+ io_saveFile($fn . '_tmp', implode('', $out_lines));
+ @unlink($fn);
+ if (!rename($fn . '_tmp', $fn)) {
+ // rename failed so try another way...
+ io_unlock($fn);
+ io_saveFile($fn, implode('', $out_lines));
+ @unlink($fn . '_tmp');
+ } else {
+ io_unlock($fn);
+ }
+ echo "runTrimRecentChanges($media_changes): finished" . NL;
+ return true;
+ }
+
+ // nothing done
+ echo "runTrimRecentChanges($media_changes): finished" . NL;
+ return false;
+ }
+
+
+ /**
+ * Runs the indexer for the current page
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function runIndexer()
+ {
+ global $ID;
+ print 'runIndexer(): started' . NL;
+
+ if ((string) $ID === '') {
+ return false;
+ }
+
+ // do the work
+ return idx_addPage($ID, true);
+ }
+
+ /**
+ * Builds a Google Sitemap of all public pages known to the indexer
+ *
+ * The map is placed in the root directory named sitemap.xml.gz - This
+ * file needs to be writable!
+ *
+ * @author Andreas Gohr
+ * @link https://www.google.com/webmasters/sitemaps/docs/en/about.html
+ */
+ protected function runSitemapper()
+ {
+ print 'runSitemapper(): started' . NL;
+ $result = Mapper::generate() && Mapper::pingSearchEngines();
+ print 'runSitemapper(): finished' . NL;
+ return $result;
+ }
+
+ /**
+ * Send digest and list mails for all subscriptions which are in effect for the
+ * current page
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+ protected function sendDigest()
+ {
+ global $ID;
+
+ echo 'sendDigest(): started' . NL;
+ if (!actionOK('subscribe')) {
+ echo 'sendDigest(): disabled' . NL;
+ return false;
+ }
+ $sub = new BulkSubscriptionSender();
+ $sent = $sub->sendBulk($ID);
+
+ echo "sendDigest(): sent $sent mails" . NL;
+ echo 'sendDigest(): finished' . NL;
+ return (bool)$sent;
+ }
+}
diff --git a/platform/www/inc/Ui/Admin.php b/platform/www/inc/Ui/Admin.php
new file mode 100644
index 0000000..fe319d4
--- /dev/null
+++ b/platform/www/inc/Ui/Admin.php
@@ -0,0 +1,167 @@
+<?php
+namespace dokuwiki\Ui;
+
+/**
+ * Class Admin
+ *
+ * Displays the Admin screen
+ *
+ * @package dokuwiki\Ui
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author HÃ¥kan Sandell <hakan.sandell@home.se>
+ */
+class Admin extends Ui {
+
+ protected $forAdmins = array('usermanager', 'acl', 'extension', 'config', 'styling');
+ protected $forManagers = array('revert', 'popularity');
+ /** @var array[] */
+ protected $menu;
+
+ /**
+ * Display the UI element
+ *
+ * @return void
+ */
+ public function show() {
+ $this->menu = $this->getPluginList();
+ echo '<div class="ui-admin">';
+ echo p_locale_xhtml('admin');
+ $this->showSecurityCheck();
+ $this->showMenu('admin');
+ $this->showMenu('manager');
+ $this->showVersion();
+ $this->showMenu('other');
+ echo '</div>';
+ }
+
+ /**
+ * Show the given menu of available plugins
+ *
+ * @param string $type admin|manager|other
+ */
+ protected function showMenu($type) {
+ if (!$this->menu[$type]) return;
+
+ if ($type === 'other') {
+ echo p_locale_xhtml('adminplugins');
+ $class = 'admin_plugins';
+ } else {
+ $class = 'admin_tasks';
+ }
+
+ echo "<ul class=\"$class\">";
+ foreach ($this->menu[$type] as $item) {
+ $this->showMenuItem($item);
+ }
+ echo '</ul>';
+ }
+
+ /**
+ * Display the DokuWiki version
+ */
+ protected function showVersion() {
+ echo '<div id="admin__version">';
+ echo getVersion();
+ echo '</div>';
+ }
+
+ /**
+ * data security check
+ *
+ * simple check if the 'savedir' is relative and accessible when appended to DOKU_URL
+ *
+ * it verifies either:
+ * 'savedir' has been moved elsewhere, or
+ * has protection to prevent the webserver serving files from it
+ */
+ protected function showSecurityCheck() {
+ global $conf;
+ if(substr($conf['savedir'], 0, 2) !== './') return;
+ $img = DOKU_URL . $conf['savedir'] .
+ '/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png';
+ echo '<a style="border:none; float:right;"
+ href="http://www.dokuwiki.org/security#web_access_security">
+ <img src="' . $img . '" alt="Your data directory seems to be protected properly."
+ onerror="this.parentNode.style.display=\'none\'" /></a>';
+ }
+
+ /**
+ * Display a single Admin menu item
+ *
+ * @param array $item
+ */
+ protected function showMenuItem($item) {
+ global $ID;
+ if(blank($item['prompt'])) return;
+ echo '<li><div class="li">';
+ echo '<a href="' . wl($ID, 'do=admin&amp;page=' . $item['plugin']) . '">';
+ echo '<span class="icon">';
+ echo inlineSVG($item['icon']);
+ echo '</span>';
+ echo '<span class="prompt">';
+ echo $item['prompt'];
+ echo '</span>';
+ echo '</a>';
+ echo '</div></li>';
+ }
+
+ /**
+ * Build list of admin functions from the plugins that handle them
+ *
+ * Checks the current permissions to decide on manager or admin plugins
+ *
+ * @return array list of plugins with their properties
+ */
+ protected function getPluginList() {
+ global $conf;
+
+ $pluginlist = plugin_list('admin');
+ $menu = ['admin' => [], 'manager' => [], 'other' => []];
+
+ foreach($pluginlist as $p) {
+ /** @var \dokuwiki\Extension\AdminPlugin $obj */
+ if(($obj = plugin_load('admin', $p)) === null) continue;
+
+ // check permissions
+ if (!$obj->isAccessibleByCurrentUser()) continue;
+
+ if (in_array($p, $this->forAdmins, true)) {
+ $type = 'admin';
+ } elseif (in_array($p, $this->forManagers, true)){
+ $type = 'manager';
+ } else {
+ $type = 'other';
+ }
+
+ $menu[$type][$p] = array(
+ 'plugin' => $p,
+ 'prompt' => $obj->getMenuText($conf['lang']),
+ 'icon' => $obj->getMenuIcon(),
+ 'sort' => $obj->getMenuSort(),
+ );
+ }
+
+ // sort by name, then sort
+ uasort($menu['admin'], [$this, 'menuSort']);
+ uasort($menu['manager'], [$this, 'menuSort']);
+ uasort($menu['other'], [$this, 'menuSort']);
+
+ return $menu;
+ }
+
+ /**
+ * Custom sorting for admin menu
+ *
+ * We sort alphabetically first, then by sort value
+ *
+ * @param array $a
+ * @param array $b
+ * @return int
+ */
+ protected function menuSort($a, $b) {
+ $strcmp = strcasecmp($a['prompt'], $b['prompt']);
+ if($strcmp != 0) return $strcmp;
+ if($a['sort'] === $b['sort']) return 0;
+ return ($a['sort'] < $b['sort']) ? -1 : 1;
+ }
+}
diff --git a/platform/www/inc/Ui/Search.php b/platform/www/inc/Ui/Search.php
new file mode 100644
index 0000000..e4eef67
--- /dev/null
+++ b/platform/www/inc/Ui/Search.php
@@ -0,0 +1,647 @@
+<?php
+
+namespace dokuwiki\Ui;
+
+use dokuwiki\Extension\Event;
+use dokuwiki\Form\Form;
+
+class Search extends Ui
+{
+ protected $query;
+ protected $parsedQuery;
+ protected $searchState;
+ protected $pageLookupResults = array();
+ protected $fullTextResults = array();
+ protected $highlight = array();
+
+ /**
+ * Search constructor.
+ *
+ * @param array $pageLookupResults pagename lookup results in the form [pagename => pagetitle]
+ * @param array $fullTextResults fulltext search results in the form [pagename => #hits]
+ * @param array $highlight array of strings to be highlighted
+ */
+ public function __construct(array $pageLookupResults, array $fullTextResults, $highlight)
+ {
+ global $QUERY;
+ $Indexer = idx_get_indexer();
+
+ $this->query = $QUERY;
+ $this->parsedQuery = ft_queryParser($Indexer, $QUERY);
+ $this->searchState = new SearchState($this->parsedQuery);
+
+ $this->pageLookupResults = $pageLookupResults;
+ $this->fullTextResults = $fullTextResults;
+ $this->highlight = $highlight;
+ }
+
+ /**
+ * display the search result
+ *
+ * @return void
+ */
+ public function show()
+ {
+ $searchHTML = '';
+
+ $searchHTML .= $this->getSearchIntroHTML($this->query);
+
+ $searchHTML .= $this->getSearchFormHTML($this->query);
+
+ $searchHTML .= $this->getPageLookupHTML($this->pageLookupResults);
+
+ $searchHTML .= $this->getFulltextResultsHTML($this->fullTextResults, $this->highlight);
+
+ echo $searchHTML;
+ }
+
+ /**
+ * Get a form which can be used to adjust/refine the search
+ *
+ * @param string $query
+ *
+ * @return string
+ */
+ protected function getSearchFormHTML($query)
+ {
+ global $lang, $ID, $INPUT;
+
+ $searchForm = (new Form(['method' => 'get'], true))->addClass('search-results-form');
+ $searchForm->setHiddenField('do', 'search');
+ $searchForm->setHiddenField('id', $ID);
+ $searchForm->setHiddenField('sf', '1');
+ if ($INPUT->has('min')) {
+ $searchForm->setHiddenField('min', $INPUT->str('min'));
+ }
+ if ($INPUT->has('max')) {
+ $searchForm->setHiddenField('max', $INPUT->str('max'));
+ }
+ if ($INPUT->has('srt')) {
+ $searchForm->setHiddenField('srt', $INPUT->str('srt'));
+ }
+ $searchForm->addFieldsetOpen()->addClass('search-form');
+ $searchForm->addTextInput('q')->val($query)->useInput(false);
+ $searchForm->addButton('', $lang['btn_search'])->attr('type', 'submit');
+
+ $this->addSearchAssistanceElements($searchForm);
+
+ $searchForm->addFieldsetClose();
+
+ Event::createAndTrigger('FORM_SEARCH_OUTPUT', $searchForm);
+
+ return $searchForm->toHTML();
+ }
+
+ /**
+ * Add elements to adjust how the results are sorted
+ *
+ * @param Form $searchForm
+ */
+ protected function addSortTool(Form $searchForm)
+ {
+ global $INPUT, $lang;
+
+ $options = [
+ 'hits' => [
+ 'label' => $lang['search_sort_by_hits'],
+ 'sort' => '',
+ ],
+ 'mtime' => [
+ 'label' => $lang['search_sort_by_mtime'],
+ 'sort' => 'mtime',
+ ],
+ ];
+ $activeOption = 'hits';
+
+ if ($INPUT->str('srt') === 'mtime') {
+ $activeOption = 'mtime';
+ }
+
+ $searchForm->addTagOpen('div')->addClass('toggle')->attr('aria-haspopup', 'true');
+ // render current
+ $currentWrapper = $searchForm->addTagOpen('div')->addClass('current');
+ if ($activeOption !== 'hits') {
+ $currentWrapper->addClass('changed');
+ }
+ $searchForm->addHTML($options[$activeOption]['label']);
+ $searchForm->addTagClose('div');
+
+ // render options list
+ $searchForm->addTagOpen('ul')->attr('aria-expanded', 'false');
+
+ foreach ($options as $key => $option) {
+ $listItem = $searchForm->addTagOpen('li');
+
+ if ($key === $activeOption) {
+ $listItem->addClass('active');
+ $searchForm->addHTML($option['label']);
+ } else {
+ $link = $this->searchState->withSorting($option['sort'])->getSearchLink($option['label']);
+ $searchForm->addHTML($link);
+ }
+ $searchForm->addTagClose('li');
+ }
+ $searchForm->addTagClose('ul');
+
+ $searchForm->addTagClose('div');
+
+ }
+
+ /**
+ * Check if the query is simple enough to modify its namespace limitations without breaking the rest of the query
+ *
+ * @param array $parsedQuery
+ *
+ * @return bool
+ */
+ protected function isNamespaceAssistanceAvailable(array $parsedQuery) {
+ if (preg_match('/[\(\)\|]/', $parsedQuery['query']) === 1) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Check if the query is simple enough to modify the fragment search behavior without breaking the rest of the query
+ *
+ * @param array $parsedQuery
+ *
+ * @return bool
+ */
+ protected function isFragmentAssistanceAvailable(array $parsedQuery) {
+ if (preg_match('/[\(\)\|]/', $parsedQuery['query']) === 1) {
+ return false;
+ }
+
+ if (!empty($parsedQuery['phrases'])) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Add the elements to be used for search assistance
+ *
+ * @param Form $searchForm
+ */
+ protected function addSearchAssistanceElements(Form $searchForm)
+ {
+ $searchForm->addTagOpen('div')
+ ->addClass('advancedOptions')
+ ->attr('style', 'display: none;')
+ ->attr('aria-hidden', 'true');
+
+ $this->addFragmentBehaviorLinks($searchForm);
+ $this->addNamespaceSelector($searchForm);
+ $this->addDateSelector($searchForm);
+ $this->addSortTool($searchForm);
+
+ $searchForm->addTagClose('div');
+ }
+
+ /**
+ * Add the elements to adjust the fragment search behavior
+ *
+ * @param Form $searchForm
+ */
+ protected function addFragmentBehaviorLinks(Form $searchForm)
+ {
+ if (!$this->isFragmentAssistanceAvailable($this->parsedQuery)) {
+ return;
+ }
+ global $lang;
+
+ $options = [
+ 'exact' => [
+ 'label' => $lang['search_exact_match'],
+ 'and' => array_map(function ($term) {
+ return trim($term, '*');
+ }, $this->parsedQuery['and']),
+ 'not' => array_map(function ($term) {
+ return trim($term, '*');
+ }, $this->parsedQuery['not']),
+ ],
+ 'starts' => [
+ 'label' => $lang['search_starts_with'],
+ 'and' => array_map(function ($term) {
+ return trim($term, '*') . '*';
+ }, $this->parsedQuery['and']),
+ 'not' => array_map(function ($term) {
+ return trim($term, '*') . '*';
+ }, $this->parsedQuery['not']),
+ ],
+ 'ends' => [
+ 'label' => $lang['search_ends_with'],
+ 'and' => array_map(function ($term) {
+ return '*' . trim($term, '*');
+ }, $this->parsedQuery['and']),
+ 'not' => array_map(function ($term) {
+ return '*' . trim($term, '*');
+ }, $this->parsedQuery['not']),
+ ],
+ 'contains' => [
+ 'label' => $lang['search_contains'],
+ 'and' => array_map(function ($term) {
+ return '*' . trim($term, '*') . '*';
+ }, $this->parsedQuery['and']),
+ 'not' => array_map(function ($term) {
+ return '*' . trim($term, '*') . '*';
+ }, $this->parsedQuery['not']),
+ ]
+ ];
+
+ // detect current
+ $activeOption = 'custom';
+ foreach ($options as $key => $option) {
+ if ($this->parsedQuery['and'] === $option['and']) {
+ $activeOption = $key;
+ }
+ }
+ if ($activeOption === 'custom') {
+ $options = array_merge(['custom' => [
+ 'label' => $lang['search_custom_match'],
+ ]], $options);
+ }
+
+ $searchForm->addTagOpen('div')->addClass('toggle')->attr('aria-haspopup', 'true');
+ // render current
+ $currentWrapper = $searchForm->addTagOpen('div')->addClass('current');
+ if ($activeOption !== 'exact') {
+ $currentWrapper->addClass('changed');
+ }
+ $searchForm->addHTML($options[$activeOption]['label']);
+ $searchForm->addTagClose('div');
+
+ // render options list
+ $searchForm->addTagOpen('ul')->attr('aria-expanded', 'false');
+
+ foreach ($options as $key => $option) {
+ $listItem = $searchForm->addTagOpen('li');
+
+ if ($key === $activeOption) {
+ $listItem->addClass('active');
+ $searchForm->addHTML($option['label']);
+ } else {
+ $link = $this->searchState
+ ->withFragments($option['and'], $option['not'])
+ ->getSearchLink($option['label'])
+ ;
+ $searchForm->addHTML($link);
+ }
+ $searchForm->addTagClose('li');
+ }
+ $searchForm->addTagClose('ul');
+
+ $searchForm->addTagClose('div');
+
+ // render options list
+ }
+
+ /**
+ * Add the elements for the namespace selector
+ *
+ * @param Form $searchForm
+ */
+ protected function addNamespaceSelector(Form $searchForm)
+ {
+ if (!$this->isNamespaceAssistanceAvailable($this->parsedQuery)) {
+ return;
+ }
+
+ global $lang;
+
+ $baseNS = empty($this->parsedQuery['ns']) ? '' : $this->parsedQuery['ns'][0];
+ $extraNS = $this->getAdditionalNamespacesFromResults($baseNS);
+
+ $searchForm->addTagOpen('div')->addClass('toggle')->attr('aria-haspopup', 'true');
+ // render current
+ $currentWrapper = $searchForm->addTagOpen('div')->addClass('current');
+ if ($baseNS) {
+ $currentWrapper->addClass('changed');
+ $searchForm->addHTML('@' . $baseNS);
+ } else {
+ $searchForm->addHTML($lang['search_any_ns']);
+ }
+ $searchForm->addTagClose('div');
+
+ // render options list
+ $searchForm->addTagOpen('ul')->attr('aria-expanded', 'false');
+
+ $listItem = $searchForm->addTagOpen('li');
+ if ($baseNS) {
+ $listItem->addClass('active');
+ $link = $this->searchState->withNamespace('')->getSearchLink($lang['search_any_ns']);
+ $searchForm->addHTML($link);
+ } else {
+ $searchForm->addHTML($lang['search_any_ns']);
+ }
+ $searchForm->addTagClose('li');
+
+ foreach ($extraNS as $ns => $count) {
+ $listItem = $searchForm->addTagOpen('li');
+ $label = $ns . ($count ? " <bdi>($count)</bdi>" : '');
+
+ if ($ns === $baseNS) {
+ $listItem->addClass('active');
+ $searchForm->addHTML($label);
+ } else {
+ $link = $this->searchState->withNamespace($ns)->getSearchLink($label);
+ $searchForm->addHTML($link);
+ }
+ $searchForm->addTagClose('li');
+ }
+ $searchForm->addTagClose('ul');
+
+ $searchForm->addTagClose('div');
+
+ }
+
+ /**
+ * Parse the full text results for their top namespaces below the given base namespace
+ *
+ * @param string $baseNS the namespace within which was searched, empty string for root namespace
+ *
+ * @return array an associative array with namespace => #number of found pages, sorted descending
+ */
+ protected function getAdditionalNamespacesFromResults($baseNS)
+ {
+ $namespaces = [];
+ $baseNSLength = strlen($baseNS);
+ foreach ($this->fullTextResults as $page => $numberOfHits) {
+ $namespace = getNS($page);
+ if (!$namespace) {
+ continue;
+ }
+ if ($namespace === $baseNS) {
+ continue;
+ }
+ $firstColon = strpos((string)$namespace, ':', $baseNSLength + 1) ?: strlen($namespace);
+ $subtopNS = substr($namespace, 0, $firstColon);
+ if (empty($namespaces[$subtopNS])) {
+ $namespaces[$subtopNS] = 0;
+ }
+ $namespaces[$subtopNS] += 1;
+ }
+ ksort($namespaces);
+ arsort($namespaces);
+ return $namespaces;
+ }
+
+ /**
+ * @ToDo: custom date input
+ *
+ * @param Form $searchForm
+ */
+ protected function addDateSelector(Form $searchForm)
+ {
+ global $INPUT, $lang;
+
+ $options = [
+ 'any' => [
+ 'before' => false,
+ 'after' => false,
+ 'label' => $lang['search_any_time'],
+ ],
+ 'week' => [
+ 'before' => false,
+ 'after' => '1 week ago',
+ 'label' => $lang['search_past_7_days'],
+ ],
+ 'month' => [
+ 'before' => false,
+ 'after' => '1 month ago',
+ 'label' => $lang['search_past_month'],
+ ],
+ 'year' => [
+ 'before' => false,
+ 'after' => '1 year ago',
+ 'label' => $lang['search_past_year'],
+ ],
+ ];
+ $activeOption = 'any';
+ foreach ($options as $key => $option) {
+ if ($INPUT->str('min') === $option['after']) {
+ $activeOption = $key;
+ break;
+ }
+ }
+
+ $searchForm->addTagOpen('div')->addClass('toggle')->attr('aria-haspopup', 'true');
+ // render current
+ $currentWrapper = $searchForm->addTagOpen('div')->addClass('current');
+ if ($INPUT->has('max') || $INPUT->has('min')) {
+ $currentWrapper->addClass('changed');
+ }
+ $searchForm->addHTML($options[$activeOption]['label']);
+ $searchForm->addTagClose('div');
+
+ // render options list
+ $searchForm->addTagOpen('ul')->attr('aria-expanded', 'false');
+
+ foreach ($options as $key => $option) {
+ $listItem = $searchForm->addTagOpen('li');
+
+ if ($key === $activeOption) {
+ $listItem->addClass('active');
+ $searchForm->addHTML($option['label']);
+ } else {
+ $link = $this->searchState
+ ->withTimeLimitations($option['after'], $option['before'])
+ ->getSearchLink($option['label'])
+ ;
+ $searchForm->addHTML($link);
+ }
+ $searchForm->addTagClose('li');
+ }
+ $searchForm->addTagClose('ul');
+
+ $searchForm->addTagClose('div');
+ }
+
+
+ /**
+ * Build the intro text for the search page
+ *
+ * @param string $query the search query
+ *
+ * @return string
+ */
+ protected function getSearchIntroHTML($query)
+ {
+ global $lang;
+
+ $intro = p_locale_xhtml('searchpage');
+
+ $queryPagename = $this->createPagenameFromQuery($this->parsedQuery);
+ $createQueryPageLink = html_wikilink($queryPagename . '?do=edit', $queryPagename);
+
+ $pagecreateinfo = '';
+ if (auth_quickaclcheck($queryPagename) >= AUTH_CREATE) {
+ $pagecreateinfo = sprintf($lang['searchcreatepage'], $createQueryPageLink);
+ }
+ $intro = str_replace(
+ array('@QUERY@', '@SEARCH@', '@CREATEPAGEINFO@'),
+ array(hsc(rawurlencode($query)), hsc($query), $pagecreateinfo),
+ $intro
+ );
+
+ return $intro;
+ }
+
+ /**
+ * Create a pagename based the parsed search query
+ *
+ * @param array $parsedQuery
+ *
+ * @return string pagename constructed from the parsed query
+ */
+ public function createPagenameFromQuery($parsedQuery)
+ {
+ $cleanedQuery = cleanID($parsedQuery['query']); // already strtolowered
+ if ($cleanedQuery === \dokuwiki\Utf8\PhpString::strtolower($parsedQuery['query'])) {
+ return ':' . $cleanedQuery;
+ }
+ $pagename = '';
+ if (!empty($parsedQuery['ns'])) {
+ $pagename .= ':' . cleanID($parsedQuery['ns'][0]);
+ }
+ $pagename .= ':' . cleanID(implode(' ' , $parsedQuery['highlight']));
+ return $pagename;
+ }
+
+ /**
+ * Build HTML for a list of pages with matching pagenames
+ *
+ * @param array $data search results
+ *
+ * @return string
+ */
+ protected function getPageLookupHTML($data)
+ {
+ if (empty($data)) {
+ return '';
+ }
+
+ global $lang;
+
+ $html = '<div class="search_quickresult">';
+ $html .= '<h2>' . $lang['quickhits'] . ':</h2>';
+ $html .= '<ul class="search_quickhits">';
+ foreach ($data as $id => $title) {
+ $name = null;
+ if (!useHeading('navigation') && $ns = getNS($id)) {
+ $name = shorten(noNS($id), ' (' . $ns . ')', 30);
+ }
+ $link = html_wikilink(':' . $id, $name);
+ $eventData = [
+ 'listItemContent' => [$link],
+ 'page' => $id,
+ ];
+ Event::createAndTrigger('SEARCH_RESULT_PAGELOOKUP', $eventData);
+ $html .= '<li>' . implode('', $eventData['listItemContent']) . '</li>';
+ }
+ $html .= '</ul> ';
+ //clear float (see http://www.complexspiral.com/publications/containing-floats/)
+ $html .= '<div class="clearer"></div>';
+ $html .= '</div>';
+
+ return $html;
+ }
+
+ /**
+ * Build HTML for fulltext search results or "no results" message
+ *
+ * @param array $data the results of the fulltext search
+ * @param array $highlight the terms to be highlighted in the results
+ *
+ * @return string
+ */
+ protected function getFulltextResultsHTML($data, $highlight)
+ {
+ global $lang;
+
+ if (empty($data)) {
+ return '<div class="nothing">' . $lang['nothingfound'] . '</div>';
+ }
+
+ $html = '<div class="search_fulltextresult">';
+ $html .= '<h2>' . $lang['search_fullresults'] . ':</h2>';
+
+ $html .= '<dl class="search_results">';
+ $num = 0;
+ $position = 0;
+
+ foreach ($data as $id => $cnt) {
+ $position += 1;
+ $resultLink = html_wikilink(':' . $id, null, $highlight);
+
+ $resultHeader = [$resultLink];
+
+
+ $restrictQueryToNSLink = $this->restrictQueryToNSLink(getNS($id));
+ if ($restrictQueryToNSLink) {
+ $resultHeader[] = $restrictQueryToNSLink;
+ }
+
+ $resultBody = [];
+ $mtime = filemtime(wikiFN($id));
+ $lastMod = '<span class="lastmod">' . $lang['lastmod'] . '</span> ';
+ $lastMod .= '<time datetime="' . date_iso8601($mtime) . '" title="' . dformat($mtime) . '">' .
+ dformat($mtime, '%f') .
+ '</time>';
+ $resultBody['meta'] = $lastMod;
+ if ($cnt !== 0) {
+ $num++;
+ $hits = '<span class="hits">' . $cnt . ' ' . $lang['hits'] . '</span>, ';
+ $resultBody['meta'] = $hits . $resultBody['meta'];
+ if ($num <= FT_SNIPPET_NUMBER) { // create snippets for the first number of matches only
+ $resultBody['snippet'] = ft_snippet($id, $highlight);
+ }
+ }
+
+ $eventData = [
+ 'resultHeader' => $resultHeader,
+ 'resultBody' => $resultBody,
+ 'page' => $id,
+ 'position' => $position,
+ ];
+ Event::createAndTrigger('SEARCH_RESULT_FULLPAGE', $eventData);
+ $html .= '<div class="search_fullpage_result">';
+ $html .= '<dt>' . implode(' ', $eventData['resultHeader']) . '</dt>';
+ foreach ($eventData['resultBody'] as $class => $htmlContent) {
+ $html .= "<dd class=\"$class\">$htmlContent</dd>";
+ }
+ $html .= '</div>';
+ }
+ $html .= '</dl>';
+
+ $html .= '</div>';
+
+ return $html;
+ }
+
+ /**
+ * create a link to restrict the current query to a namespace
+ *
+ * @param false|string $ns the namespace to which to restrict the query
+ *
+ * @return false|string
+ */
+ protected function restrictQueryToNSLink($ns)
+ {
+ if (!$ns) {
+ return false;
+ }
+ if (!$this->isNamespaceAssistanceAvailable($this->parsedQuery)) {
+ return false;
+ }
+ if (!empty($this->parsedQuery['ns']) && $this->parsedQuery['ns'][0] === $ns) {
+ return false;
+ }
+
+ $name = '@' . $ns;
+ return $this->searchState->withNamespace($ns)->getSearchLink($name);
+ }
+}
diff --git a/platform/www/inc/Ui/SearchState.php b/platform/www/inc/Ui/SearchState.php
new file mode 100644
index 0000000..eb3f7fa
--- /dev/null
+++ b/platform/www/inc/Ui/SearchState.php
@@ -0,0 +1,141 @@
+<?php
+
+namespace dokuwiki\Ui;
+
+class SearchState
+{
+ /**
+ * @var array
+ */
+ protected $parsedQuery = [];
+
+ /**
+ * SearchState constructor.
+ *
+ * @param array $parsedQuery
+ */
+ public function __construct(array $parsedQuery)
+ {
+ global $INPUT;
+
+ $this->parsedQuery = $parsedQuery;
+ if (!isset($parsedQuery['after'])) {
+ $this->parsedQuery['after'] = $INPUT->str('min');
+ }
+ if (!isset($parsedQuery['before'])) {
+ $this->parsedQuery['before'] = $INPUT->str('max');
+ }
+ if (!isset($parsedQuery['sort'])) {
+ $this->parsedQuery['sort'] = $INPUT->str('srt');
+ }
+ }
+
+ /**
+ * Get a search state for the current search limited to a new namespace
+ *
+ * @param string $ns the namespace to which to limit the search, falsy to remove the limitation
+ * @param array $notns
+ *
+ * @return SearchState
+ */
+ public function withNamespace($ns, array $notns = [])
+ {
+ $parsedQuery = $this->parsedQuery;
+ $parsedQuery['ns'] = $ns ? [$ns] : [];
+ $parsedQuery['notns'] = $notns;
+
+ return new SearchState($parsedQuery);
+ }
+
+ /**
+ * Get a search state for the current search with new search fragments and optionally phrases
+ *
+ * @param array $and
+ * @param array $not
+ * @param array $phrases
+ *
+ * @return SearchState
+ */
+ public function withFragments(array $and, array $not, array $phrases = [])
+ {
+ $parsedQuery = $this->parsedQuery;
+ $parsedQuery['and'] = $and;
+ $parsedQuery['not'] = $not;
+ $parsedQuery['phrases'] = $phrases;
+
+ return new SearchState($parsedQuery);
+ }
+
+ /**
+ * Get a search state for the current search with with adjusted time limitations
+ *
+ * @param $after
+ * @param $before
+ *
+ * @return SearchState
+ */
+ public function withTimeLimitations($after, $before)
+ {
+ $parsedQuery = $this->parsedQuery;
+ $parsedQuery['after'] = $after;
+ $parsedQuery['before'] = $before;
+
+ return new SearchState($parsedQuery);
+ }
+
+ /**
+ * Get a search state for the current search with adjusted sort preference
+ *
+ * @param $sort
+ *
+ * @return SearchState
+ */
+ public function withSorting($sort)
+ {
+ $parsedQuery = $this->parsedQuery;
+ $parsedQuery['sort'] = $sort;
+
+ return new SearchState($parsedQuery);
+ }
+
+ /**
+ * Get a link that represents the current search state
+ *
+ * Note that this represents only a simplified version of the search state.
+ * Grouping with braces and "OR" conditions are not supported.
+ *
+ * @param $label
+ *
+ * @return string
+ */
+ public function getSearchLink($label)
+ {
+ global $ID, $conf;
+ $parsedQuery = $this->parsedQuery;
+
+ $tagAttributes = [
+ 'target' => $conf['target']['wiki'],
+ ];
+
+ $newQuery = ft_queryUnparser_simple(
+ $parsedQuery['and'],
+ $parsedQuery['not'],
+ $parsedQuery['phrases'],
+ $parsedQuery['ns'],
+ $parsedQuery['notns']
+ );
+ $hrefAttributes = ['do' => 'search', 'sf' => '1', 'q' => $newQuery];
+ if ($parsedQuery['after']) {
+ $hrefAttributes['min'] = $parsedQuery['after'];
+ }
+ if ($parsedQuery['before']) {
+ $hrefAttributes['max'] = $parsedQuery['before'];
+ }
+ if ($parsedQuery['sort']) {
+ $hrefAttributes['srt'] = $parsedQuery['sort'];
+ }
+
+ $href = wl($ID, $hrefAttributes, false, '&');
+ return "<a href='$href' " . buildAttributes($tagAttributes, true) . ">$label</a>";
+ }
+}
diff --git a/platform/www/inc/Ui/Ui.php b/platform/www/inc/Ui/Ui.php
new file mode 100644
index 0000000..8aac0de
--- /dev/null
+++ b/platform/www/inc/Ui/Ui.php
@@ -0,0 +1,20 @@
+<?php
+namespace dokuwiki\Ui;
+
+/**
+ * Class Ui
+ *
+ * Abstract base class for all DokuWiki screens
+ *
+ * @package dokuwiki\Ui
+ */
+abstract class Ui {
+
+ /**
+ * Display the UI element
+ *
+ * @return void
+ */
+ abstract public function show();
+
+}
diff --git a/platform/www/inc/Utf8/Asian.php b/platform/www/inc/Utf8/Asian.php
new file mode 100644
index 0000000..c7baa30
--- /dev/null
+++ b/platform/www/inc/Utf8/Asian.php
@@ -0,0 +1,99 @@
+<?php
+
+namespace dokuwiki\Utf8;
+
+/**
+ * Methods and constants to handle Asian "words"
+ *
+ * This uses a crude regexp to determine which parts of an Asian string should be treated as words.
+ * This is necessary because in some Asian languages a single unicode char represents a whole idea
+ * without spaces separating them.
+ */
+class Asian
+{
+
+ /**
+ * This defines a non-capturing group for the use in regular expressions to match any asian character that
+ * needs to be treated as a word. Uses the Unicode-Ranges for Asian characters taken from
+ * http://en.wikipedia.org/wiki/Unicode_block
+ */
+ const REGEXP =
+ '(?:' .
+
+ '[\x{0E00}-\x{0E7F}]' . // Thai
+
+ '|' .
+
+ '[' .
+ '\x{2E80}-\x{3040}' . // CJK -> Hangul
+ '\x{309D}-\x{30A0}' .
+ '\x{30FD}-\x{31EF}\x{3200}-\x{D7AF}' .
+ '\x{F900}-\x{FAFF}' . // CJK Compatibility Ideographs
+ '\x{FE30}-\x{FE4F}' . // CJK Compatibility Forms
+ "\xF0\xA0\x80\x80-\xF0\xAA\x9B\x9F" . // CJK Extension B
+ "\xF0\xAA\x9C\x80-\xF0\xAB\x9C\xBF" . // CJK Extension C
+ "\xF0\xAB\x9D\x80-\xF0\xAB\xA0\x9F" . // CJK Extension D
+ "\xF0\xAF\xA0\x80-\xF0\xAF\xAB\xBF" . // CJK Compatibility Supplement
+ ']' .
+
+ '|' .
+
+ '[' . // Hiragana/Katakana (can be two characters)
+ '\x{3042}\x{3044}\x{3046}\x{3048}' .
+ '\x{304A}-\x{3062}\x{3064}-\x{3082}' .
+ '\x{3084}\x{3086}\x{3088}-\x{308D}' .
+ '\x{308F}-\x{3094}' .
+ '\x{30A2}\x{30A4}\x{30A6}\x{30A8}' .
+ '\x{30AA}-\x{30C2}\x{30C4}-\x{30E2}' .
+ '\x{30E4}\x{30E6}\x{30E8}-\x{30ED}' .
+ '\x{30EF}-\x{30F4}\x{30F7}-\x{30FA}' .
+ '][' .
+ '\x{3041}\x{3043}\x{3045}\x{3047}\x{3049}' .
+ '\x{3063}\x{3083}\x{3085}\x{3087}\x{308E}\x{3095}-\x{309C}' .
+ '\x{30A1}\x{30A3}\x{30A5}\x{30A7}\x{30A9}' .
+ '\x{30C3}\x{30E3}\x{30E5}\x{30E7}\x{30EE}\x{30F5}\x{30F6}\x{30FB}\x{30FC}' .
+ '\x{31F0}-\x{31FF}' .
+ ']?' .
+ ')';
+
+
+ /**
+ * Check if the given term contains Asian word characters
+ *
+ * @param string $term
+ * @return bool
+ */
+ public static function isAsianWords($term)
+ {
+ return (bool)preg_match('/' . self::REGEXP . '/u', $term);
+ }
+
+ /**
+ * Surround all Asian words in the given text with the given separator
+ *
+ * @param string $text Original text containing asian words
+ * @param string $sep the separator to use
+ * @return string Text with separated asian words
+ */
+ public static function separateAsianWords($text, $sep = ' ')
+ {
+ // handle asian chars as single words (may fail on older PHP version)
+ $asia = @preg_replace('/(' . self::REGEXP . ')/u', $sep . '\1' . $sep, $text);
+ if (!is_null($asia)) $text = $asia; // recover from regexp falure
+
+ return $text;
+ }
+
+ /**
+ * Split the given text into separate parts
+ *
+ * Each part is either a non-asian string, or a single asian word
+ *
+ * @param string $term
+ * @return string[]
+ */
+ public static function splitAsianWords($term)
+ {
+ return preg_split('/(' . self::REGEXP . '+)/u', $term, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+ }
+}
diff --git a/platform/www/inc/Utf8/Clean.php b/platform/www/inc/Utf8/Clean.php
new file mode 100644
index 0000000..0975ff5
--- /dev/null
+++ b/platform/www/inc/Utf8/Clean.php
@@ -0,0 +1,204 @@
+<?php
+
+namespace dokuwiki\Utf8;
+
+/**
+ * Methods to assess and clean UTF-8 strings
+ */
+class Clean
+{
+ /**
+ * Checks if a string contains 7bit ASCII only
+ *
+ * @author Andreas Haerter <andreas.haerter@dev.mail-node.com>
+ *
+ * @param string $str
+ * @return bool
+ */
+ public static function isASCII($str)
+ {
+ return (preg_match('/(?:[^\x00-\x7F])/', $str) !== 1);
+ }
+
+ /**
+ * Tries to detect if a string is in Unicode encoding
+ *
+ * @author <bmorel@ssi.fr>
+ * @link http://php.net/manual/en/function.utf8-encode.php
+ *
+ * @param string $str
+ * @return bool
+ */
+ public static function isUtf8($str)
+ {
+ $len = strlen($str);
+ for ($i = 0; $i < $len; $i++) {
+ $b = ord($str[$i]);
+ if ($b < 0x80) continue; # 0bbbbbbb
+ elseif (($b & 0xE0) === 0xC0) $n = 1; # 110bbbbb
+ elseif (($b & 0xF0) === 0xE0) $n = 2; # 1110bbbb
+ elseif (($b & 0xF8) === 0xF0) $n = 3; # 11110bbb
+ elseif (($b & 0xFC) === 0xF8) $n = 4; # 111110bb
+ elseif (($b & 0xFE) === 0xFC) $n = 5; # 1111110b
+ else return false; # Does not match any model
+
+ for ($j = 0; $j < $n; $j++) { # n bytes matching 10bbbbbb follow ?
+ if ((++$i === $len) || ((ord($str[$i]) & 0xC0) !== 0x80))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Strips all high byte chars
+ *
+ * Returns a pure ASCII7 string
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $str
+ * @return string
+ */
+ public static function strip($str)
+ {
+ $ascii = '';
+ $len = strlen($str);
+ for ($i = 0; $i < $len; $i++) {
+ if (ord($str[$i]) < 128) {
+ $ascii .= $str[$i];
+ }
+ }
+ return $ascii;
+ }
+
+ /**
+ * Removes special characters (nonalphanumeric) from a UTF-8 string
+ *
+ * This function adds the controlchars 0x00 to 0x19 to the array of
+ * stripped chars (they are not included in $UTF8_SPECIAL_CHARS)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $string The UTF8 string to strip of special chars
+ * @param string $repl Replace special with this string
+ * @param string $additional Additional chars to strip (used in regexp char class)
+ * @return string
+ */
+ public static function stripspecials($string, $repl = '', $additional = '')
+ {
+ static $specials = null;
+ if ($specials === null) {
+ $specials = preg_quote(Table::specialChars(), '/');
+ }
+
+ return preg_replace('/[' . $additional . '\x00-\x19' . $specials . ']/u', $repl, $string);
+ }
+
+ /**
+ * Replace bad bytes with an alternative character
+ *
+ * ASCII character is recommended for replacement char
+ *
+ * PCRE Pattern to locate bad bytes in a UTF-8 string
+ * Comes from W3 FAQ: Multilingual Forms
+ * Note: modified to include full ASCII range including control chars
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @see http://www.w3.org/International/questions/qa-forms-utf-8
+ *
+ * @param string $str to search
+ * @param string $replace to replace bad bytes with (defaults to '?') - use ASCII
+ * @return string
+ */
+ public static function replaceBadBytes($str, $replace = '')
+ {
+ $UTF8_BAD =
+ '([\x00-\x7F]' . # ASCII (including control chars)
+ '|[\xC2-\xDF][\x80-\xBF]' . # non-overlong 2-byte
+ '|\xE0[\xA0-\xBF][\x80-\xBF]' . # excluding overlongs
+ '|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}' . # straight 3-byte
+ '|\xED[\x80-\x9F][\x80-\xBF]' . # excluding surrogates
+ '|\xF0[\x90-\xBF][\x80-\xBF]{2}' . # planes 1-3
+ '|[\xF1-\xF3][\x80-\xBF]{3}' . # planes 4-15
+ '|\xF4[\x80-\x8F][\x80-\xBF]{2}' . # plane 16
+ '|(.{1}))'; # invalid byte
+ ob_start();
+ while (preg_match('/' . $UTF8_BAD . '/S', $str, $matches)) {
+ if (!isset($matches[2])) {
+ echo $matches[0];
+ } else {
+ echo $replace;
+ }
+ $str = substr($str, strlen($matches[0]));
+ }
+ return ob_get_clean();
+ }
+
+
+ /**
+ * Replace accented UTF-8 characters by unaccented ASCII-7 equivalents
+ *
+ * Use the optional parameter to just deaccent lower ($case = -1) or upper ($case = 1)
+ * letters. Default is to deaccent both cases ($case = 0)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $string
+ * @param int $case
+ * @return string
+ */
+ public static function deaccent($string, $case = 0)
+ {
+ if ($case <= 0) {
+ $string = strtr($string, Table::lowerAccents());
+ }
+ if ($case >= 0) {
+ $string = strtr($string, Table::upperAccents());
+ }
+ return $string;
+ }
+
+ /**
+ * Romanize a non-latin string
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function romanize($string)
+ {
+ if (self::isASCII($string)) return $string; //nothing to do
+
+ return strtr($string, Table::romanization());
+ }
+
+ /**
+ * adjust a byte index into a utf8 string to a utf8 character boundary
+ *
+ * @author chris smith <chris@jalakai.co.uk>
+ *
+ * @param string $str utf8 character string
+ * @param int $i byte index into $str
+ * @param bool $next direction to search for boundary, false = up (current character) true = down (next character)
+ * @return int byte index into $str now pointing to a utf8 character boundary
+ */
+ public static function correctIdx($str, $i, $next = false)
+ {
+
+ if ($i <= 0) return 0;
+
+ $limit = strlen($str);
+ if ($i >= $limit) return $limit;
+
+ if ($next) {
+ while (($i < $limit) && ((ord($str[$i]) & 0xC0) === 0x80)) $i++;
+ } else {
+ while ($i && ((ord($str[$i]) & 0xC0) === 0x80)) $i--;
+ }
+
+ return $i;
+ }
+
+}
diff --git a/platform/www/inc/Utf8/Conversion.php b/platform/www/inc/Utf8/Conversion.php
new file mode 100644
index 0000000..fad9cd0
--- /dev/null
+++ b/platform/www/inc/Utf8/Conversion.php
@@ -0,0 +1,162 @@
+<?php
+
+namespace dokuwiki\Utf8;
+
+/**
+ * Methods to convert from and to UTF-8 strings
+ */
+class Conversion
+{
+
+ /**
+ * Encodes UTF-8 characters to HTML entities
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ * @author <vpribish at shopping dot com>
+ * @link http://php.net/manual/en/function.utf8-decode.php
+ *
+ * @param string $str
+ * @param bool $all Encode non-utf8 char to HTML as well
+ * @return string
+ */
+ public static function toHtml($str, $all = false)
+ {
+ $ret = '';
+ foreach (Unicode::fromUtf8($str) as $cp) {
+ if ($cp < 0x80 && !$all) {
+ $ret .= chr($cp);
+ } elseif ($cp < 0x100) {
+ $ret .= "&#$cp;";
+ } else {
+ $ret .= '&#x' . dechex($cp) . ';';
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Decodes HTML entities to UTF-8 characters
+ *
+ * Convert any &#..; entity to a codepoint,
+ * The entities flag defaults to only decoding numeric entities.
+ * Pass HTML_ENTITIES and named entities, including &amp; &lt; etc.
+ * are handled as well. Avoids the problem that would occur if you
+ * had to decode "&amp;#38;&#38;amp;#38;"
+ *
+ * unhtmlspecialchars(\dokuwiki\Utf8\Conversion::fromHtml($s)) -> "&#38;&#38;"
+ * \dokuwiki\Utf8\Conversion::fromHtml(unhtmlspecialchars($s)) -> "&&amp#38;"
+ * what it should be -> "&#38;&amp#38;"
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $str UTF-8 encoded string
+ * @param boolean $entities decode name entities in addtition to numeric ones
+ * @return string UTF-8 encoded string with numeric (and named) entities replaced.
+ */
+ public static function fromHtml($str, $entities = false)
+ {
+ if (!$entities) {
+ return preg_replace_callback(
+ '/(&#([Xx])?([0-9A-Za-z]+);)/m',
+ [__CLASS__, 'decodeNumericEntity'],
+ $str
+ );
+ }
+
+ return preg_replace_callback(
+ '/&(#)?([Xx])?([0-9A-Za-z]+);/m',
+ [__CLASS__, 'decodeAnyEntity'],
+ $str
+ );
+ }
+
+ /**
+ * Decodes any HTML entity to it's correct UTF-8 char equivalent
+ *
+ * @param string $ent An entity
+ * @return string
+ */
+ protected static function decodeAnyEntity($ent)
+ {
+ // create the named entity lookup table
+ static $table = null;
+ if ($table === null) {
+ $table = get_html_translation_table(HTML_ENTITIES);
+ $table = array_flip($table);
+ $table = array_map(
+ static function ($c) {
+ return Unicode::toUtf8(array(ord($c)));
+ },
+ $table
+ );
+ }
+
+ if ($ent[1] === '#') {
+ return self::decodeNumericEntity($ent);
+ }
+
+ if (array_key_exists($ent[0], $table)) {
+ return $table[$ent[0]];
+ }
+
+ return $ent[0];
+ }
+
+ /**
+ * Decodes numeric HTML entities to their correct UTF-8 characters
+ *
+ * @param $ent string A numeric entity
+ * @return string|false
+ */
+ protected static function decodeNumericEntity($ent)
+ {
+ switch ($ent[2]) {
+ case 'X':
+ case 'x':
+ $cp = hexdec($ent[3]);
+ break;
+ default:
+ $cp = intval($ent[3]);
+ break;
+ }
+ return Unicode::toUtf8(array($cp));
+ }
+
+ /**
+ * UTF-8 to UTF-16BE conversion.
+ *
+ * Maybe really UCS-2 without mb_string due to utf8_to_unicode limits
+ *
+ * @param string $str
+ * @param bool $bom
+ * @return string
+ */
+ public static function toUtf16be($str, $bom = false)
+ {
+ $out = $bom ? "\xFE\xFF" : '';
+ if (UTF8_MBSTRING) {
+ return $out . mb_convert_encoding($str, 'UTF-16BE', 'UTF-8');
+ }
+
+ $uni = Unicode::fromUtf8($str);
+ foreach ($uni as $cp) {
+ $out .= pack('n', $cp);
+ }
+ return $out;
+ }
+
+ /**
+ * UTF-8 to UTF-16BE conversion.
+ *
+ * Maybe really UCS-2 without mb_string due to utf8_to_unicode limits
+ *
+ * @param string $str
+ * @return false|string
+ */
+ public static function fromUtf16be($str)
+ {
+ $uni = unpack('n*', $str);
+ return Unicode::toUtf8($uni);
+ }
+
+}
diff --git a/platform/www/inc/Utf8/PhpString.php b/platform/www/inc/Utf8/PhpString.php
new file mode 100644
index 0000000..5bcd601
--- /dev/null
+++ b/platform/www/inc/Utf8/PhpString.php
@@ -0,0 +1,383 @@
+<?php
+
+namespace dokuwiki\Utf8;
+
+/**
+ * UTF-8 aware equivalents to PHP's string functions
+ */
+class PhpString
+{
+
+ /**
+ * A locale independent basename() implementation
+ *
+ * works around a bug in PHP's basename() implementation
+ *
+ * @param string $path A path
+ * @param string $suffix If the name component ends in suffix this will also be cut off
+ * @return string
+ * @link https://bugs.php.net/bug.php?id=37738
+ *
+ * @see basename()
+ */
+ public static function basename($path, $suffix = '')
+ {
+ $path = trim($path, '\\/');
+ $rpos = max(strrpos($path, '/'), strrpos($path, '\\'));
+ if ($rpos) {
+ $path = substr($path, $rpos + 1);
+ }
+
+ $suflen = strlen($suffix);
+ if ($suflen && (substr($path, -$suflen) === $suffix)) {
+ $path = substr($path, 0, -$suflen);
+ }
+
+ return $path;
+ }
+
+ /**
+ * Unicode aware replacement for strlen()
+ *
+ * utf8_decode() converts characters that are not in ISO-8859-1
+ * to '?', which, for the purpose of counting, is alright - It's
+ * even faster than mb_strlen.
+ *
+ * @param string $string
+ * @return int
+ * @see utf8_decode()
+ *
+ * @author <chernyshevsky at hotmail dot com>
+ * @see strlen()
+ */
+ public static function strlen($string)
+ {
+ if (function_exists('utf8_decode')) {
+ return strlen(utf8_decode($string));
+ }
+
+ if (UTF8_MBSTRING) {
+ return mb_strlen($string, 'UTF-8');
+ }
+
+ if (function_exists('iconv_strlen')) {
+ return iconv_strlen($string, 'UTF-8');
+ }
+
+ return strlen($string);
+ }
+
+ /**
+ * UTF-8 aware alternative to substr
+ *
+ * Return part of a string given character offset (and optionally length)
+ *
+ * @param string $str
+ * @param int $offset number of UTF-8 characters offset (from left)
+ * @param int $length (optional) length in UTF-8 characters from offset
+ * @return string
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ */
+ public static function substr($str, $offset, $length = null)
+ {
+ if (UTF8_MBSTRING) {
+ if ($length === null) {
+ return mb_substr($str, $offset);
+ }
+
+ return mb_substr($str, $offset, $length);
+ }
+
+ /*
+ * Notes:
+ *
+ * no mb string support, so we'll use pcre regex's with 'u' flag
+ * pcre only supports repetitions of less than 65536, in order to accept up to MAXINT values for
+ * offset and length, we'll repeat a group of 65535 characters when needed (ok, up to MAXINT-65536)
+ *
+ * substr documentation states false can be returned in some cases (e.g. offset > string length)
+ * mb_substr never returns false, it will return an empty string instead.
+ *
+ * calculating the number of characters in the string is a relatively expensive operation, so
+ * we only carry it out when necessary. It isn't necessary for +ve offsets and no specified length
+ */
+
+ // cast parameters to appropriate types to avoid multiple notices/warnings
+ $str = (string)$str; // generates E_NOTICE for PHP4 objects, but not PHP5 objects
+ $offset = (int)$offset;
+ if ($length !== null) $length = (int)$length;
+
+ // handle trivial cases
+ if ($length === 0) return '';
+ if ($offset < 0 && $length < 0 && $length < $offset) return '';
+
+ $offset_pattern = '';
+ $length_pattern = '';
+
+ // normalise -ve offsets (we could use a tail anchored pattern, but they are horribly slow!)
+ if ($offset < 0) {
+ $strlen = self::strlen($str); // see notes
+ $offset = $strlen + $offset;
+ if ($offset < 0) $offset = 0;
+ }
+
+ // establish a pattern for offset, a non-captured group equal in length to offset
+ if ($offset > 0) {
+ $Ox = (int)($offset / 65535);
+ $Oy = $offset % 65535;
+
+ if ($Ox) $offset_pattern = '(?:.{65535}){' . $Ox . '}';
+ $offset_pattern = '^(?:' . $offset_pattern . '.{' . $Oy . '})';
+ } else {
+ $offset_pattern = '^'; // offset == 0; just anchor the pattern
+ }
+
+ // establish a pattern for length
+ if ($length === null) {
+ $length_pattern = '(.*)$'; // the rest of the string
+ } else {
+
+ if (!isset($strlen)) $strlen = self::strlen($str); // see notes
+ if ($offset > $strlen) return ''; // another trivial case
+
+ if ($length > 0) {
+
+ // reduce any length that would go past the end of the string
+ $length = min($strlen - $offset, $length);
+
+ $Lx = (int)($length / 65535);
+ $Ly = $length % 65535;
+
+ // +ve length requires ... a captured group of length characters
+ if ($Lx) $length_pattern = '(?:.{65535}){' . $Lx . '}';
+ $length_pattern = '(' . $length_pattern . '.{' . $Ly . '})';
+
+ } else if ($length < 0) {
+
+ if ($length < ($offset - $strlen)) return '';
+
+ $Lx = (int)((-$length) / 65535);
+ $Ly = (-$length) % 65535;
+
+ // -ve length requires ... capture everything except a group of -length characters
+ // anchored at the tail-end of the string
+ if ($Lx) $length_pattern = '(?:.{65535}){' . $Lx . '}';
+ $length_pattern = '(.*)(?:' . $length_pattern . '.{' . $Ly . '})$';
+ }
+ }
+
+ if (!preg_match('#' . $offset_pattern . $length_pattern . '#us', $str, $match)) return '';
+ return $match[1];
+ }
+
+ // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
+ /**
+ * Unicode aware replacement for substr_replace()
+ *
+ * @param string $string input string
+ * @param string $replacement the replacement
+ * @param int $start the replacing will begin at the start'th offset into string.
+ * @param int $length If given and is positive, it represents the length of the portion of string which is
+ * to be replaced. If length is zero then this function will have the effect of inserting
+ * replacement into string at the given start offset.
+ * @return string
+ * @see substr_replace()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public static function substr_replace($string, $replacement, $start, $length = 0)
+ {
+ $ret = '';
+ if ($start > 0) $ret .= self::substr($string, 0, $start);
+ $ret .= $replacement;
+ $ret .= self::substr($string, $start + $length);
+ return $ret;
+ }
+ // phpcs:enable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
+
+ /**
+ * Unicode aware replacement for ltrim()
+ *
+ * @param string $str
+ * @param string $charlist
+ * @return string
+ * @see ltrim()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public static function ltrim($str, $charlist = '')
+ {
+ if ($charlist === '') return ltrim($str);
+
+ //quote charlist for use in a characterclass
+ $charlist = preg_replace('!([\\\\\\-\\]\\[/])!', '\\\${1}', $charlist);
+
+ return preg_replace('/^[' . $charlist . ']+/u', '', $str);
+ }
+
+ /**
+ * Unicode aware replacement for rtrim()
+ *
+ * @param string $str
+ * @param string $charlist
+ * @return string
+ * @see rtrim()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public static function rtrim($str, $charlist = '')
+ {
+ if ($charlist === '') return rtrim($str);
+
+ //quote charlist for use in a characterclass
+ $charlist = preg_replace('!([\\\\\\-\\]\\[/])!', '\\\${1}', $charlist);
+
+ return preg_replace('/[' . $charlist . ']+$/u', '', $str);
+ }
+
+ /**
+ * Unicode aware replacement for trim()
+ *
+ * @param string $str
+ * @param string $charlist
+ * @return string
+ * @see trim()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public static function trim($str, $charlist = '')
+ {
+ if ($charlist === '') return trim($str);
+
+ return self::ltrim(self::rtrim($str, $charlist), $charlist);
+ }
+
+ /**
+ * This is a unicode aware replacement for strtolower()
+ *
+ * Uses mb_string extension if available
+ *
+ * @param string $string
+ * @return string
+ * @see \dokuwiki\Utf8\PhpString::strtoupper()
+ *
+ * @author Leo Feyer <leo@typolight.org>
+ * @see strtolower()
+ */
+ public static function strtolower($string)
+ {
+ if (UTF8_MBSTRING) {
+ if (class_exists('Normalizer', $autoload = false)) {
+ return \Normalizer::normalize(mb_strtolower($string, 'utf-8'));
+ }
+ return (mb_strtolower($string, 'utf-8'));
+ }
+ return strtr($string, Table::upperCaseToLowerCase());
+ }
+
+ /**
+ * This is a unicode aware replacement for strtoupper()
+ *
+ * Uses mb_string extension if available
+ *
+ * @param string $string
+ * @return string
+ * @see \dokuwiki\Utf8\PhpString::strtoupper()
+ *
+ * @author Leo Feyer <leo@typolight.org>
+ * @see strtoupper()
+ */
+ public static function strtoupper($string)
+ {
+ if (UTF8_MBSTRING) return mb_strtoupper($string, 'utf-8');
+
+ return strtr($string, Table::lowerCaseToUpperCase());
+ }
+
+
+ /**
+ * UTF-8 aware alternative to ucfirst
+ * Make a string's first character uppercase
+ *
+ * @param string $str
+ * @return string with first character as upper case (if applicable)
+ * @author Harry Fuecks
+ *
+ */
+ public static function ucfirst($str)
+ {
+ switch (self::strlen($str)) {
+ case 0:
+ return '';
+ case 1:
+ return self::strtoupper($str);
+ default:
+ preg_match('/^(.{1})(.*)$/us', $str, $matches);
+ return self::strtoupper($matches[1]) . $matches[2];
+ }
+ }
+
+ /**
+ * UTF-8 aware alternative to ucwords
+ * Uppercase the first character of each word in a string
+ *
+ * @param string $str
+ * @return string with first char of each word uppercase
+ * @author Harry Fuecks
+ * @see http://php.net/ucwords
+ *
+ */
+ public static function ucwords($str)
+ {
+ // Note: [\x0c\x09\x0b\x0a\x0d\x20] matches;
+ // form feeds, horizontal tabs, vertical tabs, linefeeds and carriage returns
+ // This corresponds to the definition of a "word" defined at http://php.net/ucwords
+ $pattern = '/(^|([\x0c\x09\x0b\x0a\x0d\x20]+))([^\x0c\x09\x0b\x0a\x0d\x20]{1})[^\x0c\x09\x0b\x0a\x0d\x20]*/u';
+
+ return preg_replace_callback(
+ $pattern,
+ function ($matches) {
+ $leadingws = $matches[2];
+ $ucfirst = self::strtoupper($matches[3]);
+ $ucword = self::substr_replace(ltrim($matches[0]), $ucfirst, 0, 1);
+ return $leadingws . $ucword;
+ },
+ $str
+ );
+ }
+
+ /**
+ * This is an Unicode aware replacement for strpos
+ *
+ * @param string $haystack
+ * @param string $needle
+ * @param integer $offset
+ * @return integer
+ * @author Leo Feyer <leo@typolight.org>
+ * @see strpos()
+ *
+ */
+ public static function strpos($haystack, $needle, $offset = 0)
+ {
+ $comp = 0;
+ $length = null;
+
+ while ($length === null || $length < $offset) {
+ $pos = strpos($haystack, $needle, $offset + $comp);
+
+ if ($pos === false)
+ return false;
+
+ $length = self::strlen(substr($haystack, 0, $pos));
+
+ if ($length < $offset)
+ $comp = $pos - $length;
+ }
+
+ return $length;
+ }
+
+
+}
diff --git a/platform/www/inc/Utf8/Table.php b/platform/www/inc/Utf8/Table.php
new file mode 100644
index 0000000..8683c92
--- /dev/null
+++ b/platform/www/inc/Utf8/Table.php
@@ -0,0 +1,93 @@
+<?php
+
+namespace dokuwiki\Utf8;
+
+/**
+ * Provides static access to the UTF-8 conversion tables
+ *
+ * Lazy-Loads tables on first access
+ */
+class Table
+{
+
+ /**
+ * Get the upper to lower case conversion table
+ *
+ * @return array
+ */
+ public static function upperCaseToLowerCase()
+ {
+ static $table = null;
+ if ($table === null) $table = include __DIR__ . '/tables/case.php';
+ return $table;
+ }
+
+ /**
+ * Get the lower to upper case conversion table
+ *
+ * @return array
+ */
+ public static function lowerCaseToUpperCase()
+ {
+ static $table = null;
+ if ($table === null) {
+ $uclc = self::upperCaseToLowerCase();
+ $table = array_flip($uclc);
+ }
+ return $table;
+ }
+
+ /**
+ * Get the lower case accent table
+ * @return array
+ */
+ public static function lowerAccents()
+ {
+ static $table = null;
+ if ($table === null) {
+ $table = include __DIR__ . '/tables/loweraccents.php';
+ }
+ return $table;
+ }
+
+ /**
+ * Get the lower case accent table
+ * @return array
+ */
+ public static function upperAccents()
+ {
+ static $table = null;
+ if ($table === null) {
+ $table = include __DIR__ . '/tables/upperaccents.php';
+ }
+ return $table;
+ }
+
+ /**
+ * Get the romanization table
+ * @return array
+ */
+ public static function romanization()
+ {
+ static $table = null;
+ if ($table === null) {
+ $table = include __DIR__ . '/tables/romanization.php';
+ }
+ return $table;
+ }
+
+ /**
+ * Get the special chars as a concatenated string
+ * @return string
+ */
+ public static function specialChars()
+ {
+ static $string = null;
+ if ($string === null) {
+ $table = include __DIR__ . '/tables/specials.php';
+ // FIXME should we cache this to file system?
+ $string = Unicode::toUtf8($table);
+ }
+ return $string;
+ }
+}
diff --git a/platform/www/inc/Utf8/Unicode.php b/platform/www/inc/Utf8/Unicode.php
new file mode 100644
index 0000000..4b64265
--- /dev/null
+++ b/platform/www/inc/Utf8/Unicode.php
@@ -0,0 +1,277 @@
+<?php
+
+namespace dokuwiki\Utf8;
+
+/**
+ * Convert between UTF-8 and a list of Unicode Code Points
+ */
+class Unicode
+{
+
+ /**
+ * Takes an UTF-8 string and returns an array of ints representing the
+ * Unicode characters. Astral planes are supported ie. the ints in the
+ * output can be > 0xFFFF. Occurrances of the BOM are ignored. Surrogates
+ * are not allowed.
+ *
+ * If $strict is set to true the function returns false if the input
+ * string isn't a valid UTF-8 octet sequence and raises a PHP error at
+ * level E_USER_WARNING
+ *
+ * Note: this function has been modified slightly in this library to
+ * trigger errors on encountering bad bytes
+ *
+ * @author <hsivonen@iki.fi>
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @see unicode_to_utf8
+ * @link http://hsivonen.iki.fi/php-utf8/
+ * @link http://sourceforge.net/projects/phputf8/
+ * @todo break into less complex chunks
+ * @todo use exceptions instead of user errors
+ *
+ * @param string $str UTF-8 encoded string
+ * @param boolean $strict Check for invalid sequences?
+ * @return mixed array of unicode code points or false if UTF-8 invalid
+ */
+ public static function fromUtf8($str, $strict = false)
+ {
+ $mState = 0; // cached expected number of octets after the current octet
+ // until the beginning of the next UTF8 character sequence
+ $mUcs4 = 0; // cached Unicode character
+ $mBytes = 1; // cached expected number of octets in the current sequence
+
+ $out = array();
+
+ $len = strlen($str);
+
+ for ($i = 0; $i < $len; $i++) {
+
+ $in = ord($str[$i]);
+
+ if ($mState === 0) {
+
+ // When mState is zero we expect either a US-ASCII character or a
+ // multi-octet sequence.
+ if (0 === (0x80 & $in)) {
+ // US-ASCII, pass straight through.
+ $out[] = $in;
+ $mBytes = 1;
+
+ } else if (0xC0 === (0xE0 & $in)) {
+ // First octet of 2 octet sequence
+ $mUcs4 = $in;
+ $mUcs4 = ($mUcs4 & 0x1F) << 6;
+ $mState = 1;
+ $mBytes = 2;
+
+ } else if (0xE0 === (0xF0 & $in)) {
+ // First octet of 3 octet sequence
+ $mUcs4 = $in;
+ $mUcs4 = ($mUcs4 & 0x0F) << 12;
+ $mState = 2;
+ $mBytes = 3;
+
+ } else if (0xF0 === (0xF8 & $in)) {
+ // First octet of 4 octet sequence
+ $mUcs4 = $in;
+ $mUcs4 = ($mUcs4 & 0x07) << 18;
+ $mState = 3;
+ $mBytes = 4;
+
+ } else if (0xF8 === (0xFC & $in)) {
+ /* First octet of 5 octet sequence.
+ *
+ * This is illegal because the encoded codepoint must be either
+ * (a) not the shortest form or
+ * (b) outside the Unicode range of 0-0x10FFFF.
+ * Rather than trying to resynchronize, we will carry on until the end
+ * of the sequence and let the later error handling code catch it.
+ */
+ $mUcs4 = $in;
+ $mUcs4 = ($mUcs4 & 0x03) << 24;
+ $mState = 4;
+ $mBytes = 5;
+
+ } else if (0xFC === (0xFE & $in)) {
+ // First octet of 6 octet sequence, see comments for 5 octet sequence.
+ $mUcs4 = $in;
+ $mUcs4 = ($mUcs4 & 1) << 30;
+ $mState = 5;
+ $mBytes = 6;
+
+ } elseif ($strict) {
+ /* Current octet is neither in the US-ASCII range nor a legal first
+ * octet of a multi-octet sequence.
+ */
+ trigger_error(
+ 'utf8_to_unicode: Illegal sequence identifier ' .
+ 'in UTF-8 at byte ' . $i,
+ E_USER_WARNING
+ );
+ return false;
+
+ }
+
+ } else {
+
+ // When mState is non-zero, we expect a continuation of the multi-octet
+ // sequence
+ if (0x80 === (0xC0 & $in)) {
+
+ // Legal continuation.
+ $shift = ($mState - 1) * 6;
+ $tmp = $in;
+ $tmp = ($tmp & 0x0000003F) << $shift;
+ $mUcs4 |= $tmp;
+
+ /**
+ * End of the multi-octet sequence. mUcs4 now contains the final
+ * Unicode codepoint to be output
+ */
+ if (0 === --$mState) {
+
+ /*
+ * Check for illegal sequences and codepoints.
+ */
+ // From Unicode 3.1, non-shortest form is illegal
+ if (((2 === $mBytes) && ($mUcs4 < 0x0080)) ||
+ ((3 === $mBytes) && ($mUcs4 < 0x0800)) ||
+ ((4 === $mBytes) && ($mUcs4 < 0x10000)) ||
+ (4 < $mBytes) ||
+ // From Unicode 3.2, surrogate characters are illegal
+ (($mUcs4 & 0xFFFFF800) === 0xD800) ||
+ // Codepoints outside the Unicode range are illegal
+ ($mUcs4 > 0x10FFFF)) {
+
+ if ($strict) {
+ trigger_error(
+ 'utf8_to_unicode: Illegal sequence or codepoint ' .
+ 'in UTF-8 at byte ' . $i,
+ E_USER_WARNING
+ );
+
+ return false;
+ }
+
+ }
+
+ if (0xFEFF !== $mUcs4) {
+ // BOM is legal but we don't want to output it
+ $out[] = $mUcs4;
+ }
+
+ //initialize UTF8 cache
+ $mState = 0;
+ $mUcs4 = 0;
+ $mBytes = 1;
+ }
+
+ } elseif ($strict) {
+ /**
+ *((0xC0 & (*in) != 0x80) && (mState != 0))
+ * Incomplete multi-octet sequence.
+ */
+ trigger_error(
+ 'utf8_to_unicode: Incomplete multi-octet ' .
+ ' sequence in UTF-8 at byte ' . $i,
+ E_USER_WARNING
+ );
+
+ return false;
+ }
+ }
+ }
+ return $out;
+ }
+
+ /**
+ * Takes an array of ints representing the Unicode characters and returns
+ * a UTF-8 string. Astral planes are supported ie. the ints in the
+ * input can be > 0xFFFF. Occurrances of the BOM are ignored. Surrogates
+ * are not allowed.
+ *
+ * If $strict is set to true the function returns false if the input
+ * array contains ints that represent surrogates or are outside the
+ * Unicode range and raises a PHP error at level E_USER_WARNING
+ *
+ * Note: this function has been modified slightly in this library to use
+ * output buffering to concatenate the UTF-8 string (faster) as well as
+ * reference the array by it's keys
+ *
+ * @param array $arr of unicode code points representing a string
+ * @param boolean $strict Check for invalid sequences?
+ * @return string|false UTF-8 string or false if array contains invalid code points
+ *
+ * @author <hsivonen@iki.fi>
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @see utf8_to_unicode
+ * @link http://hsivonen.iki.fi/php-utf8/
+ * @link http://sourceforge.net/projects/phputf8/
+ * @todo use exceptions instead of user errors
+ */
+ public static function toUtf8($arr, $strict = false)
+ {
+ if (!is_array($arr)) return '';
+ ob_start();
+
+ foreach (array_keys($arr) as $k) {
+
+ if (($arr[$k] >= 0) && ($arr[$k] <= 0x007f)) {
+ # ASCII range (including control chars)
+
+ echo chr($arr[$k]);
+
+ } else if ($arr[$k] <= 0x07ff) {
+ # 2 byte sequence
+
+ echo chr(0xc0 | ($arr[$k] >> 6));
+ echo chr(0x80 | ($arr[$k] & 0x003f));
+
+ } else if ($arr[$k] == 0xFEFF) {
+ # Byte order mark (skip)
+ // nop -- zap the BOM
+
+ } else if ($arr[$k] >= 0xD800 && $arr[$k] <= 0xDFFF) {
+ # Test for illegal surrogates
+
+ // found a surrogate
+ if ($strict) {
+ trigger_error(
+ 'unicode_to_utf8: Illegal surrogate ' .
+ 'at index: ' . $k . ', value: ' . $arr[$k],
+ E_USER_WARNING
+ );
+ return false;
+ }
+
+ } else if ($arr[$k] <= 0xffff) {
+ # 3 byte sequence
+
+ echo chr(0xe0 | ($arr[$k] >> 12));
+ echo chr(0x80 | (($arr[$k] >> 6) & 0x003f));
+ echo chr(0x80 | ($arr[$k] & 0x003f));
+
+ } else if ($arr[$k] <= 0x10ffff) {
+ # 4 byte sequence
+
+ echo chr(0xf0 | ($arr[$k] >> 18));
+ echo chr(0x80 | (($arr[$k] >> 12) & 0x3f));
+ echo chr(0x80 | (($arr[$k] >> 6) & 0x3f));
+ echo chr(0x80 | ($arr[$k] & 0x3f));
+
+ } elseif ($strict) {
+
+ trigger_error(
+ 'unicode_to_utf8: Codepoint out of Unicode range ' .
+ 'at index: ' . $k . ', value: ' . $arr[$k],
+ E_USER_WARNING
+ );
+
+ // out of range
+ return false;
+ }
+ }
+
+ return ob_get_clean();
+ }
+}
diff --git a/platform/www/inc/Utf8/tables/case.php b/platform/www/inc/Utf8/tables/case.php
new file mode 100644
index 0000000..6c41b58
--- /dev/null
+++ b/platform/www/inc/Utf8/tables/case.php
@@ -0,0 +1,659 @@
+<?php
+/**
+ * UTF-8 Case lookup table
+ *
+ * This lookuptable defines the lower case letters to their corresponding
+ * upper case letter in UTF-8
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+return [
+ 'A' => 'a',
+ 'B' => 'b',
+ 'C' => 'c',
+ 'D' => 'd',
+ 'E' => 'e',
+ 'F' => 'f',
+ 'G' => 'g',
+ 'H' => 'h',
+ 'I' => 'i',
+ 'J' => 'j',
+ 'K' => 'k',
+ 'L' => 'l',
+ 'M' => 'm',
+ 'N' => 'n',
+ 'O' => 'o',
+ 'P' => 'p',
+ 'Q' => 'q',
+ 'R' => 'r',
+ 'S' => 's',
+ 'T' => 't',
+ 'U' => 'u',
+ 'V' => 'v',
+ 'W' => 'w',
+ 'X' => 'x',
+ 'Y' => 'y',
+ 'Z' => 'z',
+ 'À' => 'à',
+ 'Ã' => 'á',
+ 'Â' => 'â',
+ 'Ã' => 'ã',
+ 'Ä' => 'ä',
+ 'Ã…' => 'Ã¥',
+ 'Æ' => 'æ',
+ 'Ç' => 'ç',
+ 'È' => 'è',
+ 'É' => 'é',
+ 'Ê' => 'ê',
+ 'Ë' => 'ë',
+ 'Ì' => 'ì',
+ 'Ã' => 'í',
+ 'Î' => 'î',
+ 'Ã' => 'ï',
+ 'Ã' => 'ð',
+ 'Ñ' => 'ñ',
+ 'Ò' => 'ò',
+ 'Ó' => 'ó',
+ 'Ô' => 'ô',
+ 'Õ' => 'õ',
+ 'Ö' => 'ö',
+ 'Ø' => 'ø',
+ 'Ù' => 'ù',
+ 'Ú' => 'ú',
+ 'Û' => 'û',
+ 'Ü' => 'ü',
+ 'Ã' => 'ý',
+ 'Þ' => 'þ',
+ 'Ä€' => 'Ä',
+ 'Ă' => 'ă',
+ 'Ä„' => 'Ä…',
+ 'Ć' => 'ć',
+ 'Ĉ' => 'ĉ',
+ 'ÄŠ' => 'Ä‹',
+ 'ÄŒ' => 'Ä',
+ 'ÄŽ' => 'Ä',
+ 'Ä' => 'Ä‘',
+ 'Ä’' => 'Ä“',
+ 'Ä”' => 'Ä•',
+ 'Ä–' => 'Ä—',
+ 'Ę' => 'ę',
+ 'Äš' => 'Ä›',
+ 'Äœ' => 'Ä',
+ 'Äž' => 'ÄŸ',
+ 'Ä ' => 'Ä¡',
+ 'Ä¢' => 'Ä£',
+ 'Ĥ' => 'ĥ',
+ 'Ħ' => 'ħ',
+ 'Ĩ' => 'ĩ',
+ 'Ī' => 'ī',
+ 'Ĭ' => 'ĭ',
+ 'Į' => 'į',
+ 'IJ' => 'ij',
+ 'Ĵ' => 'ĵ',
+ 'Ķ' => 'ķ',
+ 'Ĺ' => 'ĺ',
+ 'Ļ' => 'ļ',
+ 'Ľ' => 'ľ',
+ 'Ä¿' => 'Å€',
+ 'Å' => 'Å‚',
+ 'Ń' => 'ń',
+ 'Ņ' => 'ņ',
+ 'Ň' => 'ň',
+ 'ÅŠ' => 'Å‹',
+ 'ÅŒ' => 'Å',
+ 'ÅŽ' => 'Å',
+ 'Å' => 'Å‘',
+ 'Å’' => 'Å“',
+ 'Å”' => 'Å•',
+ 'Å–' => 'Å—',
+ 'Ř' => 'ř',
+ 'Åš' => 'Å›',
+ 'Åœ' => 'Å',
+ 'Åž' => 'ÅŸ',
+ 'Å ' => 'Å¡',
+ 'Å¢' => 'Å£',
+ 'Ť' => 'ť',
+ 'Ŧ' => 'ŧ',
+ 'Ũ' => 'ũ',
+ 'Ū' => 'ū',
+ 'Ŭ' => 'ŭ',
+ 'Ů' => 'ů',
+ 'Ű' => 'ű',
+ 'Ų' => 'ų',
+ 'Ŵ' => 'ŵ',
+ 'Ŷ' => 'ŷ',
+ 'Ÿ' => 'ÿ',
+ 'Ź' => 'ź',
+ 'Ż' => 'ż',
+ 'Ž' => 'ž',
+ 'Æ' => 'É“',
+ 'Ƃ' => 'ƃ',
+ 'Æ„' => 'Æ…',
+ 'Ɔ' => 'ɔ',
+ 'Ƈ' => 'ƈ',
+ 'Ɖ' => 'ɖ',
+ 'ÆŠ' => 'É—',
+ 'Ƌ' => 'ƌ',
+ 'ÆŽ' => 'Ç',
+ 'Æ' => 'É™',
+ 'Æ' => 'É›',
+ 'Æ‘' => 'Æ’',
+ 'Æ”' => 'É£',
+ 'Æ–' => 'É©',
+ 'Ɨ' => 'ɨ',
+ 'Ƙ' => 'ƙ',
+ 'Ɯ' => 'ɯ',
+ 'Æ' => 'ɲ',
+ 'Ɵ' => 'ɵ',
+ 'Æ ' => 'Æ¡',
+ 'Æ¢' => 'Æ£',
+ 'Ƥ' => 'ƥ',
+ 'Ʀ' => 'ʀ',
+ 'Ƨ' => 'ƨ',
+ 'Ʃ' => 'ʃ',
+ 'Ƭ' => 'ƭ',
+ 'Ʈ' => 'ʈ',
+ 'Ư' => 'ư',
+ 'Ʊ' => 'ʊ',
+ 'Ʋ' => 'ʋ',
+ 'Ƴ' => 'ƴ',
+ 'Ƶ' => 'ƶ',
+ 'Æ·' => 'Ê’',
+ 'Ƹ' => 'ƹ',
+ 'Ƽ' => 'ƽ',
+ 'Dž' => 'dž',
+ 'Lj' => 'lj',
+ 'Nj' => 'nj',
+ 'Ç' => 'ÇŽ',
+ 'Ç' => 'Ç',
+ 'Ç‘' => 'Ç’',
+ 'Ç“' => 'Ç”',
+ 'Ç•' => 'Ç–',
+ 'Ǘ' => 'ǘ',
+ 'Ç™' => 'Çš',
+ 'Ǜ' => 'ǜ',
+ 'Çž' => 'ÇŸ',
+ 'Ç ' => 'Ç¡',
+ 'Ç¢' => 'Ç£',
+ 'Ǥ' => 'ǥ',
+ 'Ǧ' => 'ǧ',
+ 'Ǩ' => 'ǩ',
+ 'Ǫ' => 'ǫ',
+ 'Ǭ' => 'ǭ',
+ 'Ǯ' => 'ǯ',
+ 'Dz' => 'dz',
+ 'Ǵ' => 'ǵ',
+ 'Ƕ' => 'ƕ',
+ 'Ç·' => 'Æ¿',
+ 'Ǹ' => 'ǹ',
+ 'Ǻ' => 'ǻ',
+ 'Ǽ' => 'ǽ',
+ 'Ǿ' => 'ǿ',
+ 'È€' => 'È',
+ 'Ȃ' => 'ȃ',
+ 'È„' => 'È…',
+ 'Ȇ' => 'ȇ',
+ 'Ȉ' => 'ȉ',
+ 'ÈŠ' => 'È‹',
+ 'ÈŒ' => 'È',
+ 'ÈŽ' => 'È',
+ 'È' => 'È‘',
+ 'È’' => 'È“',
+ 'È”' => 'È•',
+ 'È–' => 'È—',
+ 'Ș' => 'ș',
+ 'Èš' => 'È›',
+ 'Èœ' => 'È',
+ 'Èž' => 'ÈŸ',
+ 'È ' => 'Æž',
+ 'È¢' => 'È£',
+ 'Ȥ' => 'ȥ',
+ 'Ȧ' => 'ȧ',
+ 'Ȩ' => 'ȩ',
+ 'Ȫ' => 'ȫ',
+ 'Ȭ' => 'ȭ',
+ 'Ȯ' => 'ȯ',
+ 'Ȱ' => 'ȱ',
+ 'Ȳ' => 'ȳ',
+ 'Ά' => 'ά',
+ 'Έ' => 'έ',
+ 'Ή' => 'ή',
+ 'Ί' => 'ί',
+ 'Ό' => 'ό',
+ 'ÎŽ' => 'Ï',
+ 'Î' => 'ÏŽ',
+ 'Α' => 'α',
+ 'Β' => 'β',
+ 'Γ' => 'γ',
+ 'Δ' => 'δ',
+ 'Ε' => 'ε',
+ 'Ζ' => 'ζ',
+ 'Η' => 'η',
+ 'Θ' => 'θ',
+ 'Ι' => 'ι',
+ 'Κ' => 'κ',
+ 'Λ' => 'λ',
+ 'Μ' => 'μ',
+ 'Î' => 'ν',
+ 'Ξ' => 'ξ',
+ 'Ο' => 'ο',
+ 'Π' => 'π',
+ 'Ρ' => 'Ï',
+ 'Σ' => 'σ',
+ 'Τ' => 'τ',
+ 'Î¥' => 'Ï…',
+ 'Φ' => 'φ',
+ 'Χ' => 'χ',
+ 'Ψ' => 'ψ',
+ 'Ω' => 'ω',
+ 'Ϊ' => 'ϊ',
+ 'Ϋ' => 'ϋ',
+ 'Ϙ' => 'ϙ',
+ 'Ïš' => 'Ï›',
+ 'Ïœ' => 'Ï',
+ 'Ïž' => 'ÏŸ',
+ 'Ï ' => 'Ï¡',
+ 'Ï¢' => 'Ï£',
+ 'Ϥ' => 'ϥ',
+ 'Ϧ' => 'ϧ',
+ 'Ϩ' => 'ϩ',
+ 'Ϫ' => 'ϫ',
+ 'Ϭ' => 'ϭ',
+ 'Ϯ' => 'ϯ',
+ 'Ѐ' => 'Ñ',
+ 'Ð' => 'Ñ‘',
+ 'Ђ' => 'ђ',
+ 'Ѓ' => 'ѓ',
+ 'Є' => 'є',
+ 'Ð…' => 'Ñ•',
+ 'І' => 'і',
+ 'Ї' => 'ї',
+ 'Ј' => 'ј',
+ 'Љ' => 'љ',
+ 'Њ' => 'њ',
+ 'Ћ' => 'ћ',
+ 'Ќ' => 'ќ',
+ 'Ð' => 'Ñ',
+ 'ÐŽ' => 'Ñž',
+ 'Ð' => 'ÑŸ',
+ 'Ð' => 'а',
+ 'Б' => 'б',
+ 'В' => 'в',
+ 'Г' => 'г',
+ 'Д' => 'д',
+ 'Е' => 'е',
+ 'Ж' => 'ж',
+ 'З' => 'з',
+ 'И' => 'и',
+ 'Й' => 'й',
+ 'К' => 'к',
+ 'Л' => 'л',
+ 'М' => 'м',
+ 'Ð' => 'н',
+ 'О' => 'о',
+ 'П' => 'п',
+ 'Р' => 'р',
+ 'С' => 'Ñ',
+ 'Т' => 'т',
+ 'У' => 'у',
+ 'Ф' => 'ф',
+ 'Ð¥' => 'Ñ…',
+ 'Ц' => 'ц',
+ 'Ч' => 'ч',
+ 'Ш' => 'ш',
+ 'Щ' => 'щ',
+ 'Ъ' => 'ъ',
+ 'Ы' => 'ы',
+ 'Ь' => 'ь',
+ 'Э' => 'Ñ',
+ 'Ю' => 'ю',
+ 'Я' => 'Ñ',
+ 'Ñ ' => 'Ñ¡',
+ 'Ñ¢' => 'Ñ£',
+ 'Ѥ' => 'ѥ',
+ 'Ѧ' => 'ѧ',
+ 'Ѩ' => 'ѩ',
+ 'Ѫ' => 'ѫ',
+ 'Ѭ' => 'ѭ',
+ 'Ѯ' => 'ѯ',
+ 'Ѱ' => 'ѱ',
+ 'Ѳ' => 'ѳ',
+ 'Ѵ' => 'ѵ',
+ 'Ѷ' => 'ѷ',
+ 'Ѹ' => 'ѹ',
+ 'Ѻ' => 'ѻ',
+ 'Ѽ' => 'ѽ',
+ 'Ѿ' => 'ѿ',
+ 'Ò€' => 'Ò',
+ 'ÒŠ' => 'Ò‹',
+ 'ÒŒ' => 'Ò',
+ 'ÒŽ' => 'Ò',
+ 'Ò' => 'Ò‘',
+ 'Ò’' => 'Ò“',
+ 'Ò”' => 'Ò•',
+ 'Ò–' => 'Ò—',
+ 'Ò˜' => 'Ò™',
+ 'Òš' => 'Ò›',
+ 'Òœ' => 'Ò',
+ 'Òž' => 'ÒŸ',
+ 'Ò ' => 'Ò¡',
+ 'Ò¢' => 'Ò£',
+ 'Ò¤' => 'Ò¥',
+ 'Ò¦' => 'Ò§',
+ 'Ò¨' => 'Ò©',
+ 'Òª' => 'Ò«',
+ 'Ò¬' => 'Ò­',
+ 'Ò®' => 'Ò¯',
+ 'Ò°' => 'Ò±',
+ 'Ò²' => 'Ò³',
+ 'Ò´' => 'Òµ',
+ 'Ò¶' => 'Ò·',
+ 'Ò¸' => 'Ò¹',
+ 'Òº' => 'Ò»',
+ 'Ò¼' => 'Ò½',
+ 'Ò¾' => 'Ò¿',
+ 'Ó' => 'Ó‚',
+ 'Óƒ' => 'Ó„',
+ 'Ó…' => 'Ó†',
+ 'Ó‡' => 'Óˆ',
+ 'Ó‰' => 'ÓŠ',
+ 'Ӌ' => 'ӌ',
+ 'Ó' => 'ÓŽ',
+ 'Ó' => 'Ó‘',
+ 'Ó’' => 'Ó“',
+ 'Ó”' => 'Ó•',
+ 'Ó–' => 'Ó—',
+ 'Ó˜' => 'Ó™',
+ 'Óš' => 'Ó›',
+ 'Óœ' => 'Ó',
+ 'Óž' => 'ÓŸ',
+ 'Ó ' => 'Ó¡',
+ 'Ó¢' => 'Ó£',
+ 'Ó¤' => 'Ó¥',
+ 'Ó¦' => 'Ó§',
+ 'Ó¨' => 'Ó©',
+ 'Óª' => 'Ó«',
+ 'Ó¬' => 'Ó­',
+ 'Ó®' => 'Ó¯',
+ 'Ó°' => 'Ó±',
+ 'Ó²' => 'Ó³',
+ 'Ó´' => 'Óµ',
+ 'Ó¸' => 'Ó¹',
+ 'Ô€' => 'Ô',
+ 'Ô‚' => 'Ôƒ',
+ 'Ô„' => 'Ô…',
+ 'Ô†' => 'Ô‡',
+ 'Ôˆ' => 'Ô‰',
+ 'ÔŠ' => 'Ô‹',
+ 'ÔŒ' => 'Ô',
+ 'ÔŽ' => 'Ô',
+ 'Ô±' => 'Õ¡',
+ 'Ô²' => 'Õ¢',
+ 'Ô³' => 'Õ£',
+ 'Ô´' => 'Õ¤',
+ 'Ôµ' => 'Õ¥',
+ 'Ô¶' => 'Õ¦',
+ 'Ô·' => 'Õ§',
+ 'Ô¸' => 'Õ¨',
+ 'Ô¹' => 'Õ©',
+ 'Ôº' => 'Õª',
+ 'Ô»' => 'Õ«',
+ 'Ô¼' => 'Õ¬',
+ 'Ô½' => 'Õ­',
+ 'Ô¾' => 'Õ®',
+ 'Ô¿' => 'Õ¯',
+ 'Õ€' => 'Õ°',
+ 'Õ' => 'Õ±',
+ 'Õ‚' => 'Õ²',
+ 'Õƒ' => 'Õ³',
+ 'Õ„' => 'Õ´',
+ 'Õ…' => 'Õµ',
+ 'Õ†' => 'Õ¶',
+ 'Õ‡' => 'Õ·',
+ 'Õˆ' => 'Õ¸',
+ 'Õ‰' => 'Õ¹',
+ 'ÕŠ' => 'Õº',
+ 'Õ‹' => 'Õ»',
+ 'Ռ' => 'ռ',
+ 'Õ' => 'Õ½',
+ 'ÕŽ' => 'Õ¾',
+ 'Õ' => 'Õ¿',
+ 'Õ' => 'Ö€',
+ 'Õ‘' => 'Ö',
+ 'Õ’' => 'Ö‚',
+ 'Õ“' => 'Öƒ',
+ 'Õ”' => 'Ö„',
+ 'Õ•' => 'Ö…',
+ 'Õ–' => 'Ö†',
+ 'Ḁ' => 'á¸',
+ 'Ḃ' => 'ḃ',
+ 'Ḅ' => 'ḅ',
+ 'Ḇ' => 'ḇ',
+ 'Ḉ' => 'ḉ',
+ 'Ḋ' => 'ḋ',
+ 'Ḍ' => 'á¸',
+ 'Ḏ' => 'á¸',
+ 'á¸' => 'ḑ',
+ 'Ḓ' => 'ḓ',
+ 'Ḕ' => 'ḕ',
+ 'Ḗ' => 'ḗ',
+ 'Ḙ' => 'ḙ',
+ 'Ḛ' => 'ḛ',
+ 'Ḝ' => 'á¸',
+ 'Ḟ' => 'ḟ',
+ 'Ḡ' => 'ḡ',
+ 'Ḣ' => 'ḣ',
+ 'Ḥ' => 'ḥ',
+ 'Ḧ' => 'ḧ',
+ 'Ḩ' => 'ḩ',
+ 'Ḫ' => 'ḫ',
+ 'Ḭ' => 'ḭ',
+ 'Ḯ' => 'ḯ',
+ 'Ḱ' => 'ḱ',
+ 'Ḳ' => 'ḳ',
+ 'Ḵ' => 'ḵ',
+ 'Ḷ' => 'ḷ',
+ 'Ḹ' => 'ḹ',
+ 'Ḻ' => 'ḻ',
+ 'Ḽ' => 'ḽ',
+ 'Ḿ' => 'ḿ',
+ 'á¹€' => 'á¹',
+ 'Ṃ' => 'ṃ',
+ 'Ṅ' => 'ṅ',
+ 'Ṇ' => 'ṇ',
+ 'Ṉ' => 'ṉ',
+ 'Ṋ' => 'ṋ',
+ 'Ṍ' => 'á¹',
+ 'Ṏ' => 'á¹',
+ 'á¹' => 'ṑ',
+ 'Ṓ' => 'ṓ',
+ 'Ṕ' => 'ṕ',
+ 'á¹–' => 'á¹—',
+ 'Ṙ' => 'ṙ',
+ 'Ṛ' => 'ṛ',
+ 'Ṝ' => 'á¹',
+ 'Ṟ' => 'ṟ',
+ 'Ṡ' => 'ṡ',
+ 'á¹¢' => 'á¹£',
+ 'Ṥ' => 'ṥ',
+ 'Ṧ' => 'ṧ',
+ 'Ṩ' => 'ṩ',
+ 'Ṫ' => 'ṫ',
+ 'Ṭ' => 'ṭ',
+ 'Ṯ' => 'ṯ',
+ 'á¹°' => 'á¹±',
+ 'á¹²' => 'á¹³',
+ 'á¹´' => 'á¹µ',
+ 'Ṷ' => 'ṷ',
+ 'Ṹ' => 'ṹ',
+ 'Ṻ' => 'ṻ',
+ 'á¹¼' => 'á¹½',
+ 'Ṿ' => 'ṿ',
+ 'Ẁ' => 'áº',
+ 'Ẃ' => 'ẃ',
+ 'Ẅ' => 'ẅ',
+ 'Ẇ' => 'ẇ',
+ 'Ẉ' => 'ẉ',
+ 'Ẋ' => 'ẋ',
+ 'Ẍ' => 'áº',
+ 'Ẏ' => 'áº',
+ 'áº' => 'ẑ',
+ 'Ẓ' => 'ẓ',
+ 'Ẕ' => 'ẕ',
+ 'Ạ' => 'ạ',
+ 'Ả' => 'ả',
+ 'Ấ' => 'ấ',
+ 'Ầ' => 'ầ',
+ 'Ẩ' => 'ẩ',
+ 'Ẫ' => 'ẫ',
+ 'Ậ' => 'ậ',
+ 'Ắ' => 'ắ',
+ 'Ằ' => 'ằ',
+ 'Ẳ' => 'ẳ',
+ 'Ẵ' => 'ẵ',
+ 'Ặ' => 'ặ',
+ 'Ẹ' => 'ẹ',
+ 'Ẻ' => 'ẻ',
+ 'Ẽ' => 'ẽ',
+ 'Ế' => 'ế',
+ 'Ề' => 'á»',
+ 'Ể' => 'ể',
+ 'Ễ' => 'ễ',
+ 'Ệ' => 'ệ',
+ 'Ỉ' => 'ỉ',
+ 'Ị' => 'ị',
+ 'Ọ' => 'á»',
+ 'Ỏ' => 'á»',
+ 'á»' => 'ố',
+ 'Ồ' => 'ồ',
+ 'Ổ' => 'ổ',
+ 'á»–' => 'á»—',
+ 'Ộ' => 'ộ',
+ 'Ớ' => 'ớ',
+ 'Ờ' => 'á»',
+ 'Ở' => 'ở',
+ 'Ỡ' => 'ỡ',
+ 'Ợ' => 'ợ',
+ 'Ụ' => 'ụ',
+ 'Ủ' => 'ủ',
+ 'Ứ' => 'ứ',
+ 'Ừ' => 'ừ',
+ 'Ử' => 'ử',
+ 'Ữ' => 'ữ',
+ 'á»°' => 'á»±',
+ 'Ỳ' => 'ỳ',
+ 'Ỵ' => 'ỵ',
+ 'Ỷ' => 'ỷ',
+ 'Ỹ' => 'ỹ',
+ 'Ἀ' => 'ἀ',
+ 'Ἁ' => 'á¼',
+ 'Ἂ' => 'ἂ',
+ 'Ἃ' => 'ἃ',
+ 'Ἄ' => 'ἄ',
+ 'á¼' => 'á¼…',
+ 'Ἆ' => 'ἆ',
+ 'á¼' => 'ἇ',
+ 'Ἐ' => 'á¼',
+ 'Ἑ' => 'ἑ',
+ 'Ἒ' => 'ἒ',
+ 'Ἓ' => 'ἓ',
+ 'Ἔ' => 'ἔ',
+ 'á¼' => 'ἕ',
+ 'Ἡ' => 'ἡ',
+ 'Ἢ' => 'ἢ',
+ 'Ἣ' => 'ἣ',
+ 'Ἤ' => 'ἤ',
+ 'á¼­' => 'á¼¥',
+ 'Ἦ' => 'ἦ',
+ 'Ἧ' => 'ἧ',
+ 'Ἰ' => 'ἰ',
+ 'á¼¹' => 'á¼±',
+ 'Ἲ' => 'ἲ',
+ 'á¼»' => 'á¼³',
+ 'á¼¼' => 'á¼´',
+ 'á¼½' => 'á¼µ',
+ 'Ἶ' => 'ἶ',
+ 'Ἷ' => 'ἷ',
+ 'Ὀ' => 'ὀ',
+ 'Ὁ' => 'á½',
+ 'Ὂ' => 'ὂ',
+ 'Ὃ' => 'ὃ',
+ 'Ὄ' => 'ὄ',
+ 'á½' => 'á½…',
+ 'Ὑ' => 'ὑ',
+ 'Ὓ' => 'ὓ',
+ 'á½' => 'ὕ',
+ 'Ὗ' => 'ὗ',
+ 'Ὡ' => 'ὡ',
+ 'Ὢ' => 'ὢ',
+ 'Ὣ' => 'ὣ',
+ 'Ὤ' => 'ὤ',
+ 'á½­' => 'á½¥',
+ 'Ὦ' => 'ὦ',
+ 'Ὧ' => 'ὧ',
+ 'ᾈ' => 'ᾀ',
+ 'ᾉ' => 'á¾',
+ 'ᾊ' => 'ᾂ',
+ 'ᾋ' => 'ᾃ',
+ 'ᾌ' => 'ᾄ',
+ 'á¾' => 'á¾…',
+ 'ᾎ' => 'ᾆ',
+ 'á¾' => 'ᾇ',
+ 'ᾘ' => 'á¾',
+ 'ᾙ' => 'ᾑ',
+ 'ᾚ' => 'ᾒ',
+ 'ᾛ' => 'ᾓ',
+ 'ᾜ' => 'ᾔ',
+ 'á¾' => 'ᾕ',
+ 'ᾞ' => 'ᾖ',
+ 'ᾟ' => 'ᾗ',
+ 'ᾩ' => 'ᾡ',
+ 'ᾪ' => 'ᾢ',
+ 'ᾫ' => 'ᾣ',
+ 'ᾬ' => 'ᾤ',
+ 'á¾­' => 'á¾¥',
+ 'ᾮ' => 'ᾦ',
+ 'ᾯ' => 'ᾧ',
+ 'Ᾰ' => 'ᾰ',
+ 'á¾¹' => 'á¾±',
+ 'Ὰ' => 'ὰ',
+ 'á¾¼' => 'á¾³',
+ 'Ὲ' => 'ὲ',
+ 'á¿Š' => 'á½´',
+ 'ῌ' => 'ῃ',
+ 'Ῐ' => 'á¿',
+ 'á¿™' => 'á¿‘',
+ 'Ὶ' => 'ὶ',
+ 'á¿©' => 'á¿¡',
+ 'Ὺ' => 'ὺ',
+ 'Ῥ' => 'ῥ',
+ 'Ὸ' => 'ὸ',
+ 'Ὼ' => 'ὼ',
+ 'ῼ' => 'ῳ',
+ 'A' => 'ï½',
+ 'B' => 'b',
+ 'C' => 'c',
+ 'D' => 'd',
+ 'ï¼¥' => 'ï½…',
+ 'F' => 'f',
+ 'G' => 'g',
+ 'H' => 'h',
+ 'I' => 'i',
+ 'J' => 'j',
+ 'K' => 'k',
+ 'L' => 'l',
+ 'ï¼­' => 'ï½',
+ 'N' => 'n',
+ 'O' => 'ï½',
+ 'ï¼°' => 'ï½',
+ 'Q' => 'q',
+ 'ï¼²' => 'ï½’',
+ 'S' => 's',
+ 'ï¼´' => 'ï½”',
+ 'U' => 'u',
+ 'V' => 'v',
+ 'ï¼·' => 'ï½—',
+ 'X' => 'x',
+ 'ï¼¹' => 'ï½™',
+ 'Z' => 'z',
+];
diff --git a/platform/www/inc/Utf8/tables/loweraccents.php b/platform/www/inc/Utf8/tables/loweraccents.php
new file mode 100644
index 0000000..cc3ec8e
--- /dev/null
+++ b/platform/www/inc/Utf8/tables/loweraccents.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * UTF-8 lookup table for lower case accented letters
+ *
+ * This lookuptable defines replacements for accented characters from the ASCII-7
+ * range. This are lower case letters only.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see \dokuwiki\Utf8\Clean::deaccent()
+ */
+return [
+ 'á' => 'a',
+ 'à' => 'a',
+ 'ă' => 'a',
+ 'â' => 'a',
+ 'Ã¥' => 'a',
+ 'ä' => 'ae',
+ 'ã' => 'a',
+ 'Ä…' => 'a',
+ 'Ä' => 'a',
+ 'æ' => 'ae',
+ 'ḃ' => 'b',
+ 'ć' => 'c',
+ 'ĉ' => 'c',
+ 'Ä' => 'c',
+ 'Ä‹' => 'c',
+ 'ç' => 'c',
+ 'Ä' => 'd',
+ 'ḋ' => 'd',
+ 'Ä‘' => 'd',
+ 'ð' => 'dh',
+ 'é' => 'e',
+ 'è' => 'e',
+ 'Ä•' => 'e',
+ 'ê' => 'e',
+ 'Ä›' => 'e',
+ 'ë' => 'e',
+ 'Ä—' => 'e',
+ 'Ä™' => 'e',
+ 'Ä“' => 'e',
+ 'ḟ' => 'f',
+ 'Æ’' => 'f',
+ 'ÄŸ' => 'g',
+ 'Ä' => 'g',
+ 'Ä¡' => 'g',
+ 'Ä£' => 'g',
+ 'Ä¥' => 'h',
+ 'ħ' => 'h',
+ 'í' => 'i',
+ 'ì' => 'i',
+ 'î' => 'i',
+ 'ï' => 'i',
+ 'Ä©' => 'i',
+ 'į' => 'i',
+ 'Ä«' => 'i',
+ 'ĵ' => 'j',
+ 'Ä·' => 'k',
+ 'ĺ' => 'l',
+ 'ľ' => 'l',
+ 'ļ' => 'l',
+ 'Å‚' => 'l',
+ 'á¹' => 'm',
+ 'Å„' => 'n',
+ 'ň' => 'n',
+ 'ñ' => 'n',
+ 'ņ' => 'n',
+ 'ó' => 'o',
+ 'ò' => 'o',
+ 'ô' => 'o',
+ 'ö' => 'oe',
+ 'Å‘' => 'o',
+ 'õ' => 'o',
+ 'ø' => 'o',
+ 'Å' => 'o',
+ 'Æ¡' => 'o',
+ 'á¹—' => 'p',
+ 'Å•' => 'r',
+ 'Å™' => 'r',
+ 'Å—' => 'r',
+ 'Å›' => 's',
+ 'Å' => 's',
+ 'Å¡' => 's',
+ 'ṡ' => 's',
+ 'ÅŸ' => 's',
+ 'È™' => 's',
+ 'ß' => 'ss',
+ 'Å¥' => 't',
+ 'ṫ' => 't',
+ 'Å£' => 't',
+ 'È›' => 't',
+ 'ŧ' => 't',
+ 'ú' => 'u',
+ 'ù' => 'u',
+ 'Å­' => 'u',
+ 'û' => 'u',
+ 'ů' => 'u',
+ 'ü' => 'ue',
+ 'ű' => 'u',
+ 'Å©' => 'u',
+ 'ų' => 'u',
+ 'Å«' => 'u',
+ 'Æ°' => 'u',
+ 'ẃ' => 'w',
+ 'áº' => 'w',
+ 'ŵ' => 'w',
+ 'ẅ' => 'w',
+ 'ý' => 'y',
+ 'ỳ' => 'y',
+ 'Å·' => 'y',
+ 'ÿ' => 'y',
+ 'ź' => 'z',
+ 'ž' => 'z',
+ 'ż' => 'z',
+ 'þ' => 'th',
+ 'µ' => 'u',
+];
diff --git a/platform/www/inc/Utf8/tables/romanization.php b/platform/www/inc/Utf8/tables/romanization.php
new file mode 100644
index 0000000..e757b9c
--- /dev/null
+++ b/platform/www/inc/Utf8/tables/romanization.php
@@ -0,0 +1,1458 @@
+<?php
+/**
+ * Romanization lookup table
+ *
+ * This lookup tables provides a way to transform strings written in a language
+ * different from the ones based upon latin letters into plain ASCII.
+ *
+ * Please note: this is not a scientific transliteration table. It only works
+ * oneway from nonlatin to ASCII and it works by simple character replacement
+ * only. Specialities of each language are not supported.
+ *
+ * @todo some keys are used multiple times
+ * @todo remove or integrate commented pairs
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Vitaly Blokhin <vitinfo@vitn.com>
+ * @author Bisqwit <bisqwit@iki.fi>
+ * @author Arthit Suriyawongkul <arthit@gmail.com>
+ * @author Denis Scheither <amorphis@uni-bremen.de>
+ * @author Eivind Morland <eivind.morland@gmail.com>
+ * @link http://www.uconv.com/translit.htm
+ * @link http://kanjidict.stc.cx/hiragana.php?src=2
+ * @link http://www.translatum.gr/converter/greek-transliteration.htm
+ * @link http://en.wikipedia.org/wiki/Royal_Thai_General_System_of_Transcription
+ * @link http://www.btranslations.com/resources/romanization/korean.asp
+ */
+return [
+ // scandinavian - differs from what we do in deaccent
+ 'Ã¥' => 'a',
+ 'Ã…' => 'A',
+ 'ä' => 'a',
+ 'Ä' => 'A',
+ 'ö' => 'o',
+ 'Ö' => 'O',
+
+ //russian cyrillic
+ 'а' => 'a',
+ 'Ð' => 'A',
+ 'б' => 'b',
+ 'Б' => 'B',
+ 'в' => 'v',
+ 'Ð’' => 'V',
+ 'г' => 'g',
+ 'Г' => 'G',
+ 'д' => 'd',
+ 'Д' => 'D',
+ 'е' => 'e',
+ 'Е' => 'E',
+ 'Ñ‘' => 'jo',
+ 'Ð' => 'Jo',
+ 'ж' => 'zh',
+ 'Ж' => 'Zh',
+ 'з' => 'z',
+ 'З' => 'Z',
+ 'и' => 'i',
+ 'И' => 'I',
+ 'й' => 'j',
+ 'Й' => 'J',
+ 'к' => 'k',
+ 'К' => 'K',
+ 'л' => 'l',
+ 'Л' => 'L',
+ 'м' => 'm',
+ 'М' => 'M',
+ 'н' => 'n',
+ 'Ð' => 'N',
+ 'о' => 'o',
+ 'О' => 'O',
+ 'п' => 'p',
+ 'П' => 'P',
+ 'Ñ€' => 'r',
+ 'Р' => 'R',
+ 'Ñ' => 's',
+ 'С' => 'S',
+ 'Ñ‚' => 't',
+ 'Т' => 'T',
+ 'у' => 'u',
+ 'У' => 'U',
+ 'Ñ„' => 'f',
+ 'Ф' => 'F',
+ 'Ñ…' => 'x',
+ 'Ð¥' => 'X',
+ 'ц' => 'c',
+ 'Ц' => 'C',
+ 'ч' => 'ch',
+ 'Ч' => 'Ch',
+ 'ш' => 'sh',
+ 'Ш' => 'Sh',
+ 'щ' => 'sch',
+ 'Щ' => 'Sch',
+ 'ÑŠ' => '',
+ 'Ъ' => '',
+ 'Ñ‹' => 'y',
+ 'Ы' => 'Y',
+ 'ь' => '',
+ 'Ь' => '',
+ 'Ñ' => 'eh',
+ 'Э' => 'Eh',
+ 'ÑŽ' => 'ju',
+ 'Ю' => 'Ju',
+ 'Ñ' => 'ja',
+ 'Я' => 'Ja',
+
+ // Ukrainian cyrillic
+ 'Ò' => 'Gh',
+ 'Ò‘' => 'gh',
+ 'Є' => 'Je',
+ 'Ñ”' => 'je',
+ 'І' => 'I',
+ 'Ñ–' => 'i',
+ 'Ї' => 'Ji',
+ 'Ñ—' => 'ji',
+
+ // Georgian
+ 'áƒ' => 'a',
+ 'ბ' => 'b',
+ 'გ' => 'g',
+ 'დ' => 'd',
+ 'ე' => 'e',
+ 'ვ' => 'v',
+ 'ზ' => 'z',
+ 'თ' => 'th',
+ 'ი' => 'i',
+ 'კ' => 'p',
+ 'ლ' => 'l',
+ 'მ' => 'm',
+ 'ნ' => 'n',
+ 'áƒ' => 'o',
+ 'პ' => 'p',
+ 'ჟ' => 'zh',
+ 'რ' => 'r',
+ 'ს' => 's',
+ 'ტ' => 't',
+ 'უ' => 'u',
+ 'ფ' => 'ph',
+ 'ქ' => 'kh',
+ 'ღ' => 'gh',
+ 'ყ' => 'q',
+ 'შ' => 'sh',
+ 'ჩ' => 'ch',
+ 'ც' => 'c',
+ 'ძ' => 'dh',
+ 'წ' => 'w',
+ 'ჭ' => 'j',
+ 'ხ' => 'x',
+ 'ჯ' => 'jh',
+ 'ჰ' => 'xh',
+
+ //Sanskrit
+ 'अ' => 'a',
+ 'आ' => 'ah',
+ 'इ' => 'i',
+ 'ई' => 'ih',
+ 'उ' => 'u',
+ 'ऊ' => 'uh',
+ 'ऋ' => 'ry',
+ 'ॠ' => 'ryh',
+ 'ऌ' => 'ly',
+ 'ॡ' => 'lyh',
+ 'à¤' => 'e',
+ 'à¤' => 'ay',
+ 'ओ' => 'o',
+ 'औ' => 'aw',
+ 'अं' => 'amh',
+ 'अः' => 'aq',
+ 'क' => 'k',
+ 'ख' => 'kh',
+ 'ग' => 'g',
+ 'घ' => 'gh',
+ 'ङ' => 'nh',
+ 'च' => 'c',
+ 'छ' => 'ch',
+ 'ज' => 'j',
+ 'à¤' => 'jh',
+ 'ञ' => 'ny',
+ 'ट' => 'tq',
+ 'ठ' => 'tqh',
+ 'ड' => 'dq',
+ 'ढ' => 'dqh',
+ 'ण' => 'nq',
+ 'त' => 't',
+ 'थ' => 'th',
+ 'द' => 'd',
+ 'ध' => 'dh',
+ 'न' => 'n',
+ 'प' => 'p',
+ 'फ' => 'ph',
+ 'ब' => 'b',
+ 'भ' => 'bh',
+ 'म' => 'm',
+ 'य' => 'z',
+ 'र' => 'r',
+ 'ल' => 'l',
+ 'व' => 'v',
+ 'श' => 'sh',
+ 'ष' => 'sqh',
+ 'स' => 's',
+ 'ह' => 'x',
+
+ //Sanskrit diacritics
+ 'Ä€' => 'A',
+ 'Ī' => 'I',
+ 'Ū' => 'U',
+ 'Ṛ' => 'R',
+ 'Ṝ' => 'R',
+ 'Ṅ' => 'N',
+ 'Ñ' => 'N',
+ 'Ṭ' => 'T',
+ 'Ḍ' => 'D',
+ 'Ṇ' => 'N',
+ 'Åš' => 'S',
+ 'á¹¢' => 'S',
+ 'á¹€' => 'M',
+ 'Ṃ' => 'M',
+ 'Ḥ' => 'H',
+ 'Ḷ' => 'L',
+ 'Ḹ' => 'L',
+ 'Ä' => 'a',
+ 'Ä«' => 'i',
+ 'Å«' => 'u',
+ 'á¹›' => 'r',
+ 'á¹' => 'r',
+ 'á¹…' => 'n',
+ 'ñ' => 'n',
+ 'á¹­' => 't',
+ 'á¸' => 'd',
+ 'ṇ' => 'n',
+ 'Å›' => 's',
+ 'á¹£' => 's',
+ 'á¹' => 'm',
+ 'ṃ' => 'm',
+ 'ḥ' => 'h',
+ 'ḷ' => 'l',
+ 'ḹ' => 'l',
+
+ //Hebrew
+ '×' => 'a',
+ 'ב' => 'b',
+ '×’' => 'g',
+ 'ד' => 'd',
+ '×”' => 'h',
+ 'ו' => 'v',
+ '×–' => 'z',
+ '×—' => 'kh',
+ 'ט' => 'th',
+ '×™' => 'y',
+ 'ך' => 'h',
+ '×›' => 'k',
+ 'ל' => 'l',
+ '×' => 'm',
+ 'מ' => 'm',
+ 'ן' => 'n',
+ '× ' => 'n',
+ 'ס' => 's',
+ '×¢' => 'ah',
+ '×£' => 'f',
+ 'פ' => 'p',
+ '×¥' => 'c',
+ 'צ' => 'c',
+ 'ק' => 'q',
+ 'ר' => 'r',
+ 'ש' => 'sh',
+ 'ת' => 't',
+
+ //Arabic
+ 'ا' => 'a',
+ 'ب' => 'b',
+ 'ت' => 't',
+ 'Ø«' => 'th',
+ 'ج' => 'g',
+ 'Ø­' => 'xh',
+ 'Ø®' => 'x',
+ 'د' => 'd',
+ 'Ø°' => 'dh',
+ 'ر' => 'r',
+ 'ز' => 'z',
+ 'س' => 's',
+ 'Ø´' => 'sh',
+ 'ص' => 's\'',
+ 'ض' => 'd\'',
+ 'Ø·' => 't\'',
+ 'ظ' => 'z\'',
+ 'ع' => 'y',
+ 'غ' => 'gh',
+ 'Ù' => 'f',
+ 'Ù‚' => 'q',
+ 'Ùƒ' => 'k',
+ 'Ù„' => 'l',
+ 'Ù…' => 'm',
+ 'Ù†' => 'n',
+ 'Ù‡' => 'x\'',
+ 'Ùˆ' => 'u',
+ 'ÙŠ' => 'i',
+
+ // Japanese characters (last update: 2008-05-09)
+
+ // Japanese hiragana
+
+ // 3 character syllables, 㣠doubles the consonant after
+ 'ã£ã¡ã‚ƒ' => 'ccha',
+ 'ã£ã¡ã‡' => 'cche',
+ 'ã£ã¡ã‚‡' => 'ccho',
+ 'ã£ã¡ã‚…' => 'cchu',
+ 'ã£ã³ã‚ƒ' => 'bbya',
+ 'ã£ã³ã‡' => 'bbye',
+ 'ã£ã³ãƒ' => 'bbyi',
+ 'ã£ã³ã‚‡' => 'bbyo',
+ 'ã£ã³ã‚…' => 'bbyu',
+ 'ã£ã´ã‚ƒ' => 'ppya',
+ 'ã£ã´ã‡' => 'ppye',
+ 'ã£ã´ãƒ' => 'ppyi',
+ 'ã£ã´ã‚‡' => 'ppyo',
+ 'ã£ã´ã‚…' => 'ppyu',
+ 'ã£ã¡ã‚ƒ' => 'ccha',
+ 'ã£ã¡ã‡' => 'cche',
+ 'ã£ã¡' => 'cchi',
+ 'ã£ã¡ã‚‡' => 'ccho',
+ 'ã£ã¡ã‚…' => 'cchu',
+ // 'ã£ã²ã‚ƒ'=>'hya',
+ // 'ã£ã²ã‡'=>'hye',
+ // 'ã£ã²ãƒ'=>'hyi',
+ // 'ã£ã²ã‚‡'=>'hyo',
+ // 'ã£ã²ã‚…'=>'hyu',
+ 'ã£ãゃ' => 'kkya',
+ 'ã£ãã‡' => 'kkye',
+ 'ã£ããƒ' => 'kkyi',
+ 'ã£ãょ' => 'kkyo',
+ 'ã£ãã‚…' => 'kkyu',
+ 'ã£ãŽã‚ƒ' => 'ggya',
+ 'ã£ãŽã‡' => 'ggye',
+ 'ã£ãŽãƒ' => 'ggyi',
+ 'ã£ãŽã‚‡' => 'ggyo',
+ 'ã£ãŽã‚…' => 'ggyu',
+ 'ã£ã¿ã‚ƒ' => 'mmya',
+ 'ã£ã¿ã‡' => 'mmye',
+ 'ã£ã¿ãƒ' => 'mmyi',
+ 'ã£ã¿ã‚‡' => 'mmyo',
+ 'ã£ã¿ã‚…' => 'mmyu',
+ 'ã£ã«ã‚ƒ' => 'nnya',
+ 'ã£ã«ã‡' => 'nnye',
+ 'ã£ã«ãƒ' => 'nnyi',
+ 'ã£ã«ã‚‡' => 'nnyo',
+ 'ã£ã«ã‚…' => 'nnyu',
+ 'ã£ã‚Šã‚ƒ' => 'rrya',
+ 'ã£ã‚Šã‡' => 'rrye',
+ 'ã£ã‚Šãƒ' => 'rryi',
+ 'ã£ã‚Šã‚‡' => 'rryo',
+ 'ã£ã‚Šã‚…' => 'rryu',
+ 'ã£ã—ゃ' => 'ssha',
+ 'ã£ã—ã‡' => 'sshe',
+ 'ã£ã—' => 'sshi',
+ 'ã£ã—ょ' => 'ssho',
+ 'ã£ã—ã‚…' => 'sshu',
+
+ // seperate hiragana 'n' ('n' + 'i' != 'ni', normally we would write "kon'nichi wa" but the
+ // apostrophe would be converted to _ anyway)
+ 'ã‚“ã‚' => 'n_a',
+ 'ã‚“ãˆ' => 'n_e',
+ 'ã‚“ã„' => 'n_i',
+ 'ã‚“ãŠ' => 'n_o',
+ 'ã‚“ã†' => 'n_u',
+ 'ã‚“ã‚„' => 'n_ya',
+ 'んよ' => 'n_yo',
+ 'んゆ' => 'n_yu',
+
+ // 2 character syllables - normal
+ 'ãµã' => 'fa',
+ 'ãµã‡' => 'fe',
+ 'ãµãƒ' => 'fi',
+ 'ãµã‰' => 'fo',
+ 'ã¡ã‚ƒ' => 'cha',
+ 'ã¡ã‡' => 'che',
+ 'ã¡' => 'chi',
+ 'ã¡ã‚‡' => 'cho',
+ 'ã¡ã‚…' => 'chu',
+ 'ã²ã‚ƒ' => 'hya',
+ 'ã²ã‡' => 'hye',
+ 'ã²ãƒ' => 'hyi',
+ 'ã²ã‚‡' => 'hyo',
+ 'ã²ã‚…' => 'hyu',
+ 'ã³ã‚ƒ' => 'bya',
+ 'ã³ã‡' => 'bye',
+ 'ã³ãƒ' => 'byi',
+ 'ã³ã‚‡' => 'byo',
+ 'ã³ã‚…' => 'byu',
+ 'ã´ã‚ƒ' => 'pya',
+ 'ã´ã‡' => 'pye',
+ 'ã´ãƒ' => 'pyi',
+ 'ã´ã‚‡' => 'pyo',
+ 'ã´ã‚…' => 'pyu',
+ 'ãゃ' => 'kya',
+ 'ãã‡' => 'kye',
+ 'ããƒ' => 'kyi',
+ 'ãょ' => 'kyo',
+ 'ãã‚…' => 'kyu',
+ 'ãŽã‚ƒ' => 'gya',
+ 'ãŽã‡' => 'gye',
+ 'ãŽãƒ' => 'gyi',
+ 'ãŽã‚‡' => 'gyo',
+ 'ãŽã‚…' => 'gyu',
+ 'ã¿ã‚ƒ' => 'mya',
+ 'ã¿ã‡' => 'mye',
+ 'ã¿ãƒ' => 'myi',
+ 'ã¿ã‚‡' => 'myo',
+ 'ã¿ã‚…' => 'myu',
+ 'ã«ã‚ƒ' => 'nya',
+ 'ã«ã‡' => 'nye',
+ 'ã«ãƒ' => 'nyi',
+ 'ã«ã‚‡' => 'nyo',
+ 'ã«ã‚…' => 'nyu',
+ 'りゃ' => 'rya',
+ 'ã‚Šã‡' => 'rye',
+ 'ã‚Šãƒ' => 'ryi',
+ 'りょ' => 'ryo',
+ 'ã‚Šã‚…' => 'ryu',
+ 'ã—ゃ' => 'sha',
+ 'ã—ã‡' => 'she',
+ 'ã—' => 'shi',
+ 'ã—ょ' => 'sho',
+ 'ã—ã‚…' => 'shu',
+ 'ã˜ã‚ƒ' => 'ja',
+ 'ã˜ã‡' => 'je',
+ 'ã˜ã‚‡' => 'jo',
+ 'ã˜ã‚…' => 'ju',
+ 'ã†ã‡' => 'we',
+ 'ã†ãƒ' => 'wi',
+ 'ã„ã‡' => 'ye',
+
+ // 2 character syllables, 㣠doubles the consonant after
+ 'ã£ã°' => 'bba',
+ 'ã£ã¹' => 'bbe',
+ 'ã£ã³' => 'bbi',
+ 'ã£ã¼' => 'bbo',
+ 'ã£ã¶' => 'bbu',
+ 'ã£ã±' => 'ppa',
+ 'ã£ãº' => 'ppe',
+ 'ã£ã´' => 'ppi',
+ 'ã£ã½' => 'ppo',
+ 'ã£ã·' => 'ppu',
+ 'ã£ãŸ' => 'tta',
+ 'ã£ã¦' => 'tte',
+ 'ã£ã¡' => 'cchi',
+ 'ã£ã¨' => 'tto',
+ 'ã£ã¤' => 'ttsu',
+ 'ã£ã ' => 'dda',
+ 'ã£ã§' => 'dde',
+ 'ã£ã¢' => 'ddi',
+ 'ã£ã©' => 'ddo',
+ 'ã£ã¥' => 'ddu',
+ 'ã£ãŒ' => 'gga',
+ 'ã£ã’' => 'gge',
+ 'ã£ãŽ' => 'ggi',
+ 'ã£ã”' => 'ggo',
+ 'ã£ã' => 'ggu',
+ 'ã£ã‹' => 'kka',
+ 'ã£ã‘' => 'kke',
+ 'ã£ã' => 'kki',
+ 'ã£ã“' => 'kko',
+ 'ã£ã' => 'kku',
+ 'ã£ã¾' => 'mma',
+ 'ã£ã‚' => 'mme',
+ 'ã£ã¿' => 'mmi',
+ 'ã£ã‚‚' => 'mmo',
+ 'ã£ã‚€' => 'mmu',
+ 'ã£ãª' => 'nna',
+ 'ã£ã­' => 'nne',
+ 'ã£ã«' => 'nni',
+ 'ã£ã®' => 'nno',
+ 'ã£ã¬' => 'nnu',
+ 'ã£ã‚‰' => 'rra',
+ 'ã£ã‚Œ' => 'rre',
+ 'ã£ã‚Š' => 'rri',
+ 'ã£ã‚' => 'rro',
+ 'ã£ã‚‹' => 'rru',
+ 'ã£ã•' => 'ssa',
+ 'ã£ã›' => 'sse',
+ 'ã£ã—' => 'sshi',
+ 'ã£ã' => 'sso',
+ 'ã£ã™' => 'ssu',
+ 'ã£ã–' => 'zza',
+ 'ã£ãœ' => 'zze',
+ 'ã£ã˜' => 'jji',
+ 'ã£ãž' => 'zzo',
+ 'ã£ãš' => 'zzu',
+
+ // 1 character syllabels
+ 'ã‚' => 'a',
+ 'ãˆ' => 'e',
+ 'ã„' => 'i',
+ 'ãŠ' => 'o',
+ 'ã†' => 'u',
+ 'ã‚“' => 'n',
+ 'ã¯' => 'ha',
+ 'ã¸' => 'he',
+ 'ã²' => 'hi',
+ 'ã»' => 'ho',
+ 'ãµ' => 'fu',
+ 'ã°' => 'ba',
+ 'ã¹' => 'be',
+ 'ã³' => 'bi',
+ 'ã¼' => 'bo',
+ 'ã¶' => 'bu',
+ 'ã±' => 'pa',
+ 'ãº' => 'pe',
+ 'ã´' => 'pi',
+ 'ã½' => 'po',
+ 'ã·' => 'pu',
+ 'ãŸ' => 'ta',
+ 'ã¦' => 'te',
+ 'ã¡' => 'chi',
+ 'ã¨' => 'to',
+ 'ã¤' => 'tsu',
+ 'ã ' => 'da',
+ 'ã§' => 'de',
+ 'ã¢' => 'di',
+ 'ã©' => 'do',
+ 'ã¥' => 'du',
+ 'ãŒ' => 'ga',
+ 'ã’' => 'ge',
+ 'ãŽ' => 'gi',
+ 'ã”' => 'go',
+ 'ã' => 'gu',
+ 'ã‹' => 'ka',
+ 'ã‘' => 'ke',
+ 'ã' => 'ki',
+ 'ã“' => 'ko',
+ 'ã' => 'ku',
+ 'ã¾' => 'ma',
+ 'ã‚' => 'me',
+ 'ã¿' => 'mi',
+ 'ã‚‚' => 'mo',
+ 'ã‚€' => 'mu',
+ 'ãª' => 'na',
+ 'ã­' => 'ne',
+ 'ã«' => 'ni',
+ 'ã®' => 'no',
+ 'ã¬' => 'nu',
+ 'ら' => 'ra',
+ 'れ' => 're',
+ 'ã‚Š' => 'ri',
+ 'ã‚' => 'ro',
+ 'ã‚‹' => 'ru',
+ 'ã•' => 'sa',
+ 'ã›' => 'se',
+ 'ã—' => 'shi',
+ 'ã' => 'so',
+ 'ã™' => 'su',
+ 'ã‚' => 'wa',
+ 'ã‚’' => 'wo',
+ 'ã–' => 'za',
+ 'ãœ' => 'ze',
+ 'ã˜' => 'ji',
+ 'ãž' => 'zo',
+ 'ãš' => 'zu',
+ 'ã‚„' => 'ya',
+ 'よ' => 'yo',
+ 'ゆ' => 'yu',
+ // old characters
+ 'ã‚‘' => 'we',
+ 'ã‚' => 'wi',
+
+ // convert what's left (probably only kicks in when something's missing above)
+ // 'ã'=>'a','ã‡'=>'e','ãƒ'=>'i','ã‰'=>'o','ã…'=>'u',
+ // 'ゃ'=>'ya','ょ'=>'yo','ゅ'=>'yu',
+
+ // never seen one of those (disabled for the moment)
+ // 'ヴã'=>'va','ヴã‡'=>'ve','ヴãƒ'=>'vi','ヴã‰'=>'vo','ヴ'=>'vu',
+ // 'ã§ã‚ƒ'=>'dha','ã§ã‡'=>'dhe','ã§ãƒ'=>'dhi','ã§ã‚‡'=>'dho','ã§ã‚…'=>'dhu',
+ // 'ã©ã'=>'dwa','ã©ã‡'=>'dwe','ã©ãƒ'=>'dwi','ã©ã‰'=>'dwo','ã©ã…'=>'dwu',
+ // 'ã¢ã‚ƒ'=>'dya','ã¢ã‡'=>'dye','ã¢ãƒ'=>'dyi','ã¢ã‚‡'=>'dyo','ã¢ã‚…'=>'dyu',
+ // 'ãµã'=>'fwa','ãµã‡'=>'fwe','ãµãƒ'=>'fwi','ãµã‰'=>'fwo','ãµã…'=>'fwu',
+ // 'ãµã‚ƒ'=>'fya','ãµã‡'=>'fye','ãµãƒ'=>'fyi','ãµã‚‡'=>'fyo','ãµã‚…'=>'fyu',
+ // 'ã™ã'=>'swa','ã™ã‡'=>'swe','ã™ãƒ'=>'swi','ã™ã‰'=>'swo','ã™ã…'=>'swu',
+ // 'ã¦ã‚ƒ'=>'tha','ã¦ã‡'=>'the','ã¦ãƒ'=>'thi','ã¦ã‚‡'=>'tho','ã¦ã‚…'=>'thu',
+ // 'ã¤ã‚ƒ'=>'tsa','ã¤ã‡'=>'tse','ã¤ãƒ'=>'tsi','ã¤ã‚‡'=>'tso','ã¤'=>'tsu',
+ // 'ã¨ã'=>'twa','ã¨ã‡'=>'twe','ã¨ãƒ'=>'twi','ã¨ã‰'=>'two','ã¨ã…'=>'twu',
+ // 'ヴゃ'=>'vya','ヴã‡'=>'vye','ヴãƒ'=>'vyi','ヴょ'=>'vyo','ヴゅ'=>'vyu',
+ // 'ã†ã'=>'wha','ã†ã‡'=>'whe','ã†ãƒ'=>'whi','ã†ã‰'=>'who','ã†ã…'=>'whu',
+ // 'ã˜ã‚ƒ'=>'zha','ã˜ã‡'=>'zhe','ã˜ãƒ'=>'zhi','ã˜ã‚‡'=>'zho','ã˜ã‚…'=>'zhu',
+ // 'ã˜ã‚ƒ'=>'zya','ã˜ã‡'=>'zye','ã˜ãƒ'=>'zyi','ã˜ã‚‡'=>'zyo','ã˜ã‚…'=>'zyu',
+
+ // 'spare' characters from other romanization systems
+ // 'ã '=>'da','ã§'=>'de','ã¢'=>'di','ã©'=>'do','ã¥'=>'du',
+ // 'ら'=>'la','ã‚Œ'=>'le','ã‚Š'=>'li','ã‚'=>'lo','ã‚‹'=>'lu',
+ // 'ã•'=>'sa','ã›'=>'se','ã—'=>'si','ã'=>'so','ã™'=>'su',
+ // 'ã¡ã‚ƒ'=>'cya','ã¡ã‡'=>'cye','ã¡ãƒ'=>'cyi','ã¡ã‚‡'=>'cyo','ã¡ã‚…'=>'cyu',
+ //'ã˜ã‚ƒ'=>'jya','ã˜ã‡'=>'jye','ã˜ãƒ'=>'jyi','ã˜ã‚‡'=>'jyo','ã˜ã‚…'=>'jyu',
+ //'りゃ'=>'lya','ã‚Šã‡'=>'lye','ã‚Šãƒ'=>'lyi','りょ'=>'lyo','ã‚Šã‚…'=>'lyu',
+ //'ã—ゃ'=>'sya','ã—ã‡'=>'sye','ã—ãƒ'=>'syi','ã—ょ'=>'syo','ã—ã‚…'=>'syu',
+ //'ã¡ã‚ƒ'=>'tya','ã¡ã‡'=>'tye','ã¡ãƒ'=>'tyi','ã¡ã‚‡'=>'tyo','ã¡ã‚…'=>'tyu',
+ //'ã—'=>'ci',,ã„'=>'yi','ã¢'=>'dzi',
+ //'ã£ã˜ã‚ƒ'=>'jja','ã£ã˜ã‡'=>'jje','ã£ã˜'=>'jji','ã£ã˜ã‚‡'=>'jjo','ã£ã˜ã‚…'=>'jju',
+
+
+ // Japanese katakana
+
+ // 4 character syllables: ッ doubles the consonant after, ー doubles the vowel before
+ // (usualy written with macron, but we don't want that in our URLs)
+ 'ッビャー' => 'bbyaa',
+ 'ッビェー' => 'bbyee',
+ 'ッビィー' => 'bbyii',
+ 'ッビョー' => 'bbyoo',
+ 'ッビュー' => 'bbyuu',
+ 'ッピャー' => 'ppyaa',
+ 'ッピェー' => 'ppyee',
+ 'ッピィー' => 'ppyii',
+ 'ッピョー' => 'ppyoo',
+ 'ッピュー' => 'ppyuu',
+ 'ッキャー' => 'kkyaa',
+ 'ッキェー' => 'kkyee',
+ 'ッキィー' => 'kkyii',
+ 'ッキョー' => 'kkyoo',
+ 'ッキュー' => 'kkyuu',
+ 'ッギャー' => 'ggyaa',
+ 'ッギェー' => 'ggyee',
+ 'ッギィー' => 'ggyii',
+ 'ッギョー' => 'ggyoo',
+ 'ッギュー' => 'ggyuu',
+ 'ッミャー' => 'mmyaa',
+ 'ッミェー' => 'mmyee',
+ 'ッミィー' => 'mmyii',
+ 'ッミョー' => 'mmyoo',
+ 'ッミュー' => 'mmyuu',
+ 'ッニャー' => 'nnyaa',
+ 'ッニェー' => 'nnyee',
+ 'ッニィー' => 'nnyii',
+ 'ッニョー' => 'nnyoo',
+ 'ッニュー' => 'nnyuu',
+ 'ッリャー' => 'rryaa',
+ 'ッリェー' => 'rryee',
+ 'ッリィー' => 'rryii',
+ 'ッリョー' => 'rryoo',
+ 'ッリュー' => 'rryuu',
+ 'ッシャー' => 'sshaa',
+ 'ッシェー' => 'sshee',
+ 'ッシー' => 'sshii',
+ 'ッショー' => 'sshoo',
+ 'ッシュー' => 'sshuu',
+ 'ッãƒãƒ£ãƒ¼' => 'cchaa',
+ 'ッãƒã‚§ãƒ¼' => 'cchee',
+ 'ッãƒãƒ¼' => 'cchii',
+ 'ッãƒãƒ§ãƒ¼' => 'cchoo',
+ 'ッãƒãƒ¥ãƒ¼' => 'cchuu',
+ 'ッティー' => 'ttii',
+ 'ッヂィー' => 'ddii',
+
+ // 3 character syllables - doubled vowels
+ 'ファー' => 'faa',
+ 'フェー' => 'fee',
+ 'フィー' => 'fii',
+ 'フォー' => 'foo',
+ 'フャー' => 'fyaa',
+ 'フェー' => 'fyee',
+ 'フィー' => 'fyii',
+ 'フョー' => 'fyoo',
+ 'フュー' => 'fyuu',
+ 'ヒャー' => 'hyaa',
+ 'ヒェー' => 'hyee',
+ 'ヒィー' => 'hyii',
+ 'ヒョー' => 'hyoo',
+ 'ヒュー' => 'hyuu',
+ 'ビャー' => 'byaa',
+ 'ビェー' => 'byee',
+ 'ビィー' => 'byii',
+ 'ビョー' => 'byoo',
+ 'ビュー' => 'byuu',
+ 'ピャー' => 'pyaa',
+ 'ピェー' => 'pyee',
+ 'ピィー' => 'pyii',
+ 'ピョー' => 'pyoo',
+ 'ピュー' => 'pyuu',
+ 'キャー' => 'kyaa',
+ 'キェー' => 'kyee',
+ 'キィー' => 'kyii',
+ 'キョー' => 'kyoo',
+ 'キュー' => 'kyuu',
+ 'ギャー' => 'gyaa',
+ 'ギェー' => 'gyee',
+ 'ギィー' => 'gyii',
+ 'ギョー' => 'gyoo',
+ 'ギュー' => 'gyuu',
+ 'ミャー' => 'myaa',
+ 'ミェー' => 'myee',
+ 'ミィー' => 'myii',
+ 'ミョー' => 'myoo',
+ 'ミュー' => 'myuu',
+ 'ニャー' => 'nyaa',
+ 'ニェー' => 'nyee',
+ 'ニィー' => 'nyii',
+ 'ニョー' => 'nyoo',
+ 'ニュー' => 'nyuu',
+ 'リャー' => 'ryaa',
+ 'リェー' => 'ryee',
+ 'リィー' => 'ryii',
+ 'リョー' => 'ryoo',
+ 'リュー' => 'ryuu',
+ 'シャー' => 'shaa',
+ 'シェー' => 'shee',
+ 'シー' => 'shii',
+ 'ショー' => 'shoo',
+ 'シュー' => 'shuu',
+ 'ジャー' => 'jaa',
+ 'ジェー' => 'jee',
+ 'ジー' => 'jii',
+ 'ジョー' => 'joo',
+ 'ジュー' => 'juu',
+ 'スァー' => 'swaa',
+ 'スェー' => 'swee',
+ 'スィー' => 'swii',
+ 'スォー' => 'swoo',
+ 'スゥー' => 'swuu',
+ 'デァー' => 'daa',
+ 'デェー' => 'dee',
+ 'ディー' => 'dii',
+ 'デォー' => 'doo',
+ 'デゥー' => 'duu',
+ 'ãƒãƒ£ãƒ¼' => 'chaa',
+ 'ãƒã‚§ãƒ¼' => 'chee',
+ 'ãƒãƒ¼' => 'chii',
+ 'ãƒãƒ§ãƒ¼' => 'choo',
+ 'ãƒãƒ¥ãƒ¼' => 'chuu',
+ 'ヂャー' => 'dyaa',
+ 'ヂェー' => 'dyee',
+ 'ヂィー' => 'dyii',
+ 'ヂョー' => 'dyoo',
+ 'ヂュー' => 'dyuu',
+ 'ツャー' => 'tsaa',
+ 'ツェー' => 'tsee',
+ 'ツィー' => 'tsii',
+ 'ツョー' => 'tsoo',
+ 'ツー' => 'tsuu',
+ 'トァー' => 'twaa',
+ 'トェー' => 'twee',
+ 'トィー' => 'twii',
+ 'トォー' => 'twoo',
+ 'トゥー' => 'twuu',
+ 'ドァー' => 'dwaa',
+ 'ドェー' => 'dwee',
+ 'ドィー' => 'dwii',
+ 'ドォー' => 'dwoo',
+ 'ドゥー' => 'dwuu',
+ 'ウァー' => 'whaa',
+ 'ウェー' => 'whee',
+ 'ウィー' => 'whii',
+ 'ウォー' => 'whoo',
+ 'ウゥー' => 'whuu',
+ 'ヴャー' => 'vyaa',
+ 'ヴェー' => 'vyee',
+ 'ヴィー' => 'vyii',
+ 'ヴョー' => 'vyoo',
+ 'ヴュー' => 'vyuu',
+ 'ヴァー' => 'vaa',
+ 'ヴェー' => 'vee',
+ 'ヴィー' => 'vii',
+ 'ヴォー' => 'voo',
+ 'ヴー' => 'vuu',
+ 'ウェー' => 'wee',
+ 'ウィー' => 'wii',
+ 'イェー' => 'yee',
+ 'ティー' => 'tii',
+ 'ヂィー' => 'dii',
+
+ // 3 character syllables - doubled consonants
+ 'ッビャ' => 'bbya',
+ 'ッビェ' => 'bbye',
+ 'ッビィ' => 'bbyi',
+ 'ッビョ' => 'bbyo',
+ 'ッビュ' => 'bbyu',
+ 'ッピャ' => 'ppya',
+ 'ッピェ' => 'ppye',
+ 'ッピィ' => 'ppyi',
+ 'ッピョ' => 'ppyo',
+ 'ッピュ' => 'ppyu',
+ 'ッキャ' => 'kkya',
+ 'ッキェ' => 'kkye',
+ 'ッキィ' => 'kkyi',
+ 'ッキョ' => 'kkyo',
+ 'ッキュ' => 'kkyu',
+ 'ッギャ' => 'ggya',
+ 'ッギェ' => 'ggye',
+ 'ッギィ' => 'ggyi',
+ 'ッギョ' => 'ggyo',
+ 'ッギュ' => 'ggyu',
+ 'ッミャ' => 'mmya',
+ 'ッミェ' => 'mmye',
+ 'ッミィ' => 'mmyi',
+ 'ッミョ' => 'mmyo',
+ 'ッミュ' => 'mmyu',
+ 'ッニャ' => 'nnya',
+ 'ッニェ' => 'nnye',
+ 'ッニィ' => 'nnyi',
+ 'ッニョ' => 'nnyo',
+ 'ッニュ' => 'nnyu',
+ 'ッリャ' => 'rrya',
+ 'ッリェ' => 'rrye',
+ 'ッリィ' => 'rryi',
+ 'ッリョ' => 'rryo',
+ 'ッリュ' => 'rryu',
+ 'ッシャ' => 'ssha',
+ 'ッシェ' => 'sshe',
+ 'ッシ' => 'sshi',
+ 'ッショ' => 'ssho',
+ 'ッシュ' => 'sshu',
+ 'ッãƒãƒ£' => 'ccha',
+ 'ッãƒã‚§' => 'cche',
+ 'ッãƒ' => 'cchi',
+ 'ッãƒãƒ§' => 'ccho',
+ 'ッãƒãƒ¥' => 'cchu',
+ 'ッティ' => 'tti',
+ 'ッヂィ' => 'ddi',
+
+ // 3 character syllables - doubled vowel and consonants
+ 'ッãƒãƒ¼' => 'bbaa',
+ 'ッベー' => 'bbee',
+ 'ッビー' => 'bbii',
+ 'ッボー' => 'bboo',
+ 'ッブー' => 'bbuu',
+ 'ッパー' => 'ppaa',
+ 'ッペー' => 'ppee',
+ 'ッピー' => 'ppii',
+ 'ッãƒãƒ¼' => 'ppoo',
+ 'ップー' => 'ppuu',
+ 'ッケー' => 'kkee',
+ 'ッキー' => 'kkii',
+ 'ッコー' => 'kkoo',
+ 'ックー' => 'kkuu',
+ 'ッカー' => 'kkaa',
+ 'ッガー' => 'ggaa',
+ 'ッゲー' => 'ggee',
+ 'ッギー' => 'ggii',
+ 'ッゴー' => 'ggoo',
+ 'ッグー' => 'gguu',
+ 'ッマー' => 'maa',
+ 'ッメー' => 'mee',
+ 'ッミー' => 'mii',
+ 'ッモー' => 'moo',
+ 'ッムー' => 'muu',
+ 'ッナー' => 'nnaa',
+ 'ッãƒãƒ¼' => 'nnee',
+ 'ッニー' => 'nnii',
+ 'ッノー' => 'nnoo',
+ 'ッヌー' => 'nnuu',
+ 'ッラー' => 'rraa',
+ 'ッレー' => 'rree',
+ 'ッリー' => 'rrii',
+ 'ッロー' => 'rroo',
+ 'ッルー' => 'rruu',
+ 'ッサー' => 'ssaa',
+ 'ッセー' => 'ssee',
+ 'ッシー' => 'sshii',
+ 'ッソー' => 'ssoo',
+ 'ッスー' => 'ssuu',
+ 'ッザー' => 'zzaa',
+ 'ッゼー' => 'zzee',
+ 'ッジー' => 'jjii',
+ 'ッゾー' => 'zzoo',
+ 'ッズー' => 'zzuu',
+ 'ッター' => 'ttaa',
+ 'ッテー' => 'ttee',
+ 'ッãƒãƒ¼' => 'chii',
+ 'ットー' => 'ttoo',
+ 'ッツー' => 'ttsuu',
+ 'ッダー' => 'ddaa',
+ 'ッデー' => 'ddee',
+ 'ッヂー' => 'ddii',
+ 'ッドー' => 'ddoo',
+ 'ッヅー' => 'dduu',
+
+ // 2 character syllables - normal
+ 'ファ' => 'fa',
+ 'フェ' => 'fe',
+ 'フィ' => 'fi',
+ 'フォ' => 'fo',
+ 'フゥ' => 'fu',
+ // 'フャ'=>'fya',
+ // 'フェ'=>'fye',
+ // 'フィ'=>'fyi',
+ // 'フョ'=>'fyo',
+ // 'フュ'=>'fyu',
+ 'フャ' => 'fa',
+ 'フェ' => 'fe',
+ 'フィ' => 'fi',
+ 'フョ' => 'fo',
+ 'フュ' => 'fu',
+ 'ヒャ' => 'hya',
+ 'ヒェ' => 'hye',
+ 'ヒィ' => 'hyi',
+ 'ヒョ' => 'hyo',
+ 'ヒュ' => 'hyu',
+ 'ビャ' => 'bya',
+ 'ビェ' => 'bye',
+ 'ビィ' => 'byi',
+ 'ビョ' => 'byo',
+ 'ビュ' => 'byu',
+ 'ピャ' => 'pya',
+ 'ピェ' => 'pye',
+ 'ピィ' => 'pyi',
+ 'ピョ' => 'pyo',
+ 'ピュ' => 'pyu',
+ 'キャ' => 'kya',
+ 'キェ' => 'kye',
+ 'ã‚­ã‚£' => 'kyi',
+ 'キョ' => 'kyo',
+ 'キュ' => 'kyu',
+ 'ギャ' => 'gya',
+ 'ギェ' => 'gye',
+ 'ギィ' => 'gyi',
+ 'ギョ' => 'gyo',
+ 'ギュ' => 'gyu',
+ 'ミャ' => 'mya',
+ 'ミェ' => 'mye',
+ 'ミィ' => 'myi',
+ 'ミョ' => 'myo',
+ 'ミュ' => 'myu',
+ 'ニャ' => 'nya',
+ 'ニェ' => 'nye',
+ 'ニィ' => 'nyi',
+ 'ニョ' => 'nyo',
+ 'ニュ' => 'nyu',
+ 'リャ' => 'rya',
+ 'リェ' => 'rye',
+ 'リィ' => 'ryi',
+ 'リョ' => 'ryo',
+ 'リュ' => 'ryu',
+ 'シャ' => 'sha',
+ 'シェ' => 'she',
+ 'ショ' => 'sho',
+ 'シュ' => 'shu',
+ 'ジャ' => 'ja',
+ 'ジェ' => 'je',
+ 'ジョ' => 'jo',
+ 'ジュ' => 'ju',
+ 'スァ' => 'swa',
+ 'スェ' => 'swe',
+ 'スィ' => 'swi',
+ 'スォ' => 'swo',
+ 'スゥ' => 'swu',
+ 'デァ' => 'da',
+ 'デェ' => 'de',
+ 'ディ' => 'di',
+ 'デォ' => 'do',
+ 'デゥ' => 'du',
+ 'ãƒãƒ£' => 'cha',
+ 'ãƒã‚§' => 'che',
+ 'ãƒ' => 'chi',
+ 'ãƒãƒ§' => 'cho',
+ 'ãƒãƒ¥' => 'chu',
+ // 'ヂャ'=>'dya',
+ // 'ヂェ'=>'dye',
+ // 'ヂィ'=>'dyi',
+ // 'ヂョ'=>'dyo',
+ // 'ヂュ'=>'dyu',
+ 'ツャ' => 'tsa',
+ 'ツェ' => 'tse',
+ 'ツィ' => 'tsi',
+ 'ツョ' => 'tso',
+ 'ツ' => 'tsu',
+ 'トァ' => 'twa',
+ 'トェ' => 'twe',
+ 'トィ' => 'twi',
+ 'トォ' => 'two',
+ 'トゥ' => 'twu',
+ 'ドァ' => 'dwa',
+ 'ドェ' => 'dwe',
+ 'ドィ' => 'dwi',
+ 'ドォ' => 'dwo',
+ 'ドゥ' => 'dwu',
+ 'ウァ' => 'wha',
+ 'ウェ' => 'whe',
+ 'ウィ' => 'whi',
+ 'ウォ' => 'who',
+ 'ウゥ' => 'whu',
+ 'ヴャ' => 'vya',
+ 'ヴェ' => 'vye',
+ 'ヴィ' => 'vyi',
+ 'ヴョ' => 'vyo',
+ 'ヴュ' => 'vyu',
+ 'ヴァ' => 'va',
+ 'ヴェ' => 've',
+ 'ヴィ' => 'vi',
+ 'ヴォ' => 'vo',
+ 'ヴ' => 'vu',
+ 'ウェ' => 'we',
+ 'ウィ' => 'wi',
+ 'イェ' => 'ye',
+ 'ティ' => 'ti',
+ 'ヂィ' => 'di',
+
+ // 2 character syllables - doubled vocal
+ 'アー' => 'aa',
+ 'エー' => 'ee',
+ 'イー' => 'ii',
+ 'オー' => 'oo',
+ 'ウー' => 'uu',
+ 'ダー' => 'daa',
+ 'デー' => 'dee',
+ 'ヂー' => 'dii',
+ 'ドー' => 'doo',
+ 'ヅー' => 'duu',
+ 'ãƒãƒ¼' => 'haa',
+ 'ヘー' => 'hee',
+ 'ヒー' => 'hii',
+ 'ホー' => 'hoo',
+ 'フー' => 'fuu',
+ 'ãƒãƒ¼' => 'baa',
+ 'ベー' => 'bee',
+ 'ビー' => 'bii',
+ 'ボー' => 'boo',
+ 'ブー' => 'buu',
+ 'パー' => 'paa',
+ 'ペー' => 'pee',
+ 'ピー' => 'pii',
+ 'ãƒãƒ¼' => 'poo',
+ 'プー' => 'puu',
+ 'ケー' => 'kee',
+ 'キー' => 'kii',
+ 'コー' => 'koo',
+ 'クー' => 'kuu',
+ 'カー' => 'kaa',
+ 'ガー' => 'gaa',
+ 'ゲー' => 'gee',
+ 'ギー' => 'gii',
+ 'ゴー' => 'goo',
+ 'グー' => 'guu',
+ 'マー' => 'maa',
+ 'メー' => 'mee',
+ 'ミー' => 'mii',
+ 'モー' => 'moo',
+ 'ムー' => 'muu',
+ 'ナー' => 'naa',
+ 'ãƒãƒ¼' => 'nee',
+ 'ニー' => 'nii',
+ 'ノー' => 'noo',
+ 'ヌー' => 'nuu',
+ 'ラー' => 'raa',
+ 'レー' => 'ree',
+ 'リー' => 'rii',
+ 'ロー' => 'roo',
+ 'ルー' => 'ruu',
+ 'サー' => 'saa',
+ 'セー' => 'see',
+ 'シー' => 'shii',
+ 'ソー' => 'soo',
+ 'スー' => 'suu',
+ 'ザー' => 'zaa',
+ 'ゼー' => 'zee',
+ 'ジー' => 'jii',
+ 'ゾー' => 'zoo',
+ 'ズー' => 'zuu',
+ 'ター' => 'taa',
+ 'テー' => 'tee',
+ 'ãƒãƒ¼' => 'chii',
+ 'トー' => 'too',
+ 'ツー' => 'tsuu',
+ 'ワー' => 'waa',
+ 'ヲー' => 'woo',
+ 'ヤー' => 'yaa',
+ 'ヨー' => 'yoo',
+ 'ユー' => 'yuu',
+ 'ヵー' => 'kaa',
+ 'ヶー' => 'kee',
+ // old characters
+ 'ヱー' => 'wee',
+ 'ヰー' => 'wii',
+
+ // seperate katakana 'n'
+ 'ンア' => 'n_a',
+ 'ンエ' => 'n_e',
+ 'ンイ' => 'n_i',
+ 'ンオ' => 'n_o',
+ 'ンウ' => 'n_u',
+ 'ンヤ' => 'n_ya',
+ 'ンヨ' => 'n_yo',
+ 'ンユ' => 'n_yu',
+
+ // 2 character syllables - doubled consonants
+ 'ッãƒ' => 'bba',
+ 'ッベ' => 'bbe',
+ 'ッビ' => 'bbi',
+ 'ッボ' => 'bbo',
+ 'ッブ' => 'bbu',
+ 'ッパ' => 'ppa',
+ 'ッペ' => 'ppe',
+ 'ッピ' => 'ppi',
+ 'ッãƒ' => 'ppo',
+ 'ップ' => 'ppu',
+ 'ッケ' => 'kke',
+ 'ッキ' => 'kki',
+ 'ッコ' => 'kko',
+ 'ック' => 'kku',
+ 'ッカ' => 'kka',
+ 'ッガ' => 'gga',
+ 'ッゲ' => 'gge',
+ 'ッギ' => 'ggi',
+ 'ッゴ' => 'ggo',
+ 'ッグ' => 'ggu',
+ 'ッマ' => 'ma',
+ 'ッメ' => 'me',
+ 'ッミ' => 'mi',
+ 'ッモ' => 'mo',
+ 'ッム' => 'mu',
+ 'ッナ' => 'nna',
+ 'ッãƒ' => 'nne',
+ 'ッニ' => 'nni',
+ 'ッノ' => 'nno',
+ 'ッヌ' => 'nnu',
+ 'ッラ' => 'rra',
+ 'ッレ' => 'rre',
+ 'ッリ' => 'rri',
+ 'ッロ' => 'rro',
+ 'ッル' => 'rru',
+ 'ッサ' => 'ssa',
+ 'ッセ' => 'sse',
+ 'ッシ' => 'sshi',
+ 'ッソ' => 'sso',
+ 'ッス' => 'ssu',
+ 'ッザ' => 'zza',
+ 'ッゼ' => 'zze',
+ 'ッジ' => 'jji',
+ 'ッゾ' => 'zzo',
+ 'ッズ' => 'zzu',
+ 'ッタ' => 'tta',
+ 'ッテ' => 'tte',
+ 'ッãƒ' => 'cchi',
+ 'ット' => 'tto',
+ 'ッツ' => 'ttsu',
+ 'ッダ' => 'dda',
+ 'ッデ' => 'dde',
+ 'ッヂ' => 'ddi',
+ 'ッド' => 'ddo',
+ 'ッヅ' => 'ddu',
+
+ // 1 character syllables
+ 'ã‚¢' => 'a',
+ 'エ' => 'e',
+ 'イ' => 'i',
+ 'オ' => 'o',
+ 'ウ' => 'u',
+ 'ン' => 'n',
+ 'ãƒ' => 'ha',
+ 'ヘ' => 'he',
+ 'ヒ' => 'hi',
+ 'ホ' => 'ho',
+ 'フ' => 'fu',
+ 'ãƒ' => 'ba',
+ 'ベ' => 'be',
+ 'ビ' => 'bi',
+ 'ボ' => 'bo',
+ 'ブ' => 'bu',
+ 'パ' => 'pa',
+ 'ペ' => 'pe',
+ 'ピ' => 'pi',
+ 'ãƒ' => 'po',
+ 'プ' => 'pu',
+ 'ケ' => 'ke',
+ 'ã‚­' => 'ki',
+ 'コ' => 'ko',
+ 'ク' => 'ku',
+ 'ã‚«' => 'ka',
+ 'ガ' => 'ga',
+ 'ゲ' => 'ge',
+ 'ã‚®' => 'gi',
+ 'ã‚´' => 'go',
+ 'ã‚°' => 'gu',
+ 'マ' => 'ma',
+ 'メ' => 'me',
+ 'ミ' => 'mi',
+ 'モ' => 'mo',
+ 'ム' => 'mu',
+ 'ナ' => 'na',
+ 'ãƒ' => 'ne',
+ 'ニ' => 'ni',
+ 'ノ' => 'no',
+ 'ヌ' => 'nu',
+ 'ラ' => 'ra',
+ 'レ' => 're',
+ 'リ' => 'ri',
+ 'ロ' => 'ro',
+ 'ル' => 'ru',
+ 'サ' => 'sa',
+ 'ã‚»' => 'se',
+ 'ã‚·' => 'shi',
+ 'ソ' => 'so',
+ 'ス' => 'su',
+ 'ザ' => 'za',
+ 'ゼ' => 'ze',
+ 'ジ' => 'ji',
+ 'ゾ' => 'zo',
+ 'ズ' => 'zu',
+ 'ã‚¿' => 'ta',
+ 'テ' => 'te',
+ 'ãƒ' => 'chi',
+ 'ト' => 'to',
+ 'ツ' => 'tsu',
+ 'ダ' => 'da',
+ 'デ' => 'de',
+ 'ヂ' => 'di',
+ 'ド' => 'do',
+ 'ヅ' => 'du',
+ 'ワ' => 'wa',
+ 'ヲ' => 'wo',
+ 'ヤ' => 'ya',
+ 'ヨ' => 'yo',
+ 'ユ' => 'yu',
+ 'ヵ' => 'ka',
+ 'ヶ' => 'ke',
+ // old characters
+ 'ヱ' => 'we',
+ 'ヰ' => 'wi',
+
+ // convert what's left (probably only kicks in when something's missing above)
+ 'ã‚¡' => 'a',
+ 'ェ' => 'e',
+ 'ã‚£' => 'i',
+ 'ã‚©' => 'o',
+ 'ã‚¥' => 'u',
+ 'ャ' => 'ya',
+ 'ョ' => 'yo',
+ 'ュ' => 'yu',
+
+ // special characters
+ '・' => '_',
+ 'ã€' => '_',
+ 'ー' => '_',
+ // when used with hiragana (seldom), this character would not be converted otherwise
+
+ // 'ラ'=>'la',
+ // 'レ'=>'le',
+ // 'リ'=>'li',
+ // 'ロ'=>'lo',
+ // 'ル'=>'lu',
+ // 'ãƒãƒ£'=>'cya',
+ // 'ãƒã‚§'=>'cye',
+ // 'ãƒã‚£'=>'cyi',
+ // 'ãƒãƒ§'=>'cyo',
+ // 'ãƒãƒ¥'=>'cyu',
+ // 'デャ'=>'dha',
+ // 'デェ'=>'dhe',
+ // 'ディ'=>'dhi',
+ // 'デョ'=>'dho',
+ // 'デュ'=>'dhu',
+ // 'リャ'=>'lya',
+ // 'リェ'=>'lye',
+ // 'リィ'=>'lyi',
+ // 'リョ'=>'lyo',
+ // 'リュ'=>'lyu',
+ // 'テャ'=>'tha',
+ // 'テェ'=>'the',
+ // 'ティ'=>'thi',
+ // 'テョ'=>'tho',
+ // 'テュ'=>'thu',
+ // 'ファ'=>'fwa',
+ // 'フェ'=>'fwe',
+ // 'フィ'=>'fwi',
+ // 'フォ'=>'fwo',
+ // 'フゥ'=>'fwu',
+ // 'ãƒãƒ£'=>'tya',
+ // 'ãƒã‚§'=>'tye',
+ // 'ãƒã‚£'=>'tyi',
+ // 'ãƒãƒ§'=>'tyo',
+ // 'ãƒãƒ¥'=>'tyu',
+ // 'ジャ'=>'jya',
+ // 'ジェ'=>'jye',
+ // 'ジィ'=>'jyi',
+ // 'ジョ'=>'jyo',
+ // 'ジュ'=>'jyu',
+ // 'ジャ'=>'zha',
+ // 'ジェ'=>'zhe',
+ // 'ジィ'=>'zhi',
+ // 'ジョ'=>'zho',
+ // 'ジュ'=>'zhu',
+ // 'ジャ'=>'zya',
+ // 'ジェ'=>'zye',
+ // 'ジィ'=>'zyi',
+ // 'ジョ'=>'zyo',
+ // 'ジュ'=>'zyu',
+ // 'シャ'=>'sya',
+ // 'シェ'=>'sye',
+ // 'ã‚·ã‚£'=>'syi',
+ // 'ショ'=>'syo',
+ // 'シュ'=>'syu',
+ // 'ã‚·'=>'ci',
+ // 'フ'=>'hu',
+ // 'ã‚·'=>'si',
+ // 'ãƒ'=>'ti',
+ // 'ツ'=>'tu',
+ // 'イ'=>'yi',
+ // 'ヂ'=>'dzi',
+
+ // "Greeklish"
+ 'Γ' => 'G',
+ 'Δ' => 'E',
+ 'Θ' => 'Th',
+ 'Λ' => 'L',
+ 'Ξ' => 'X',
+ 'Π' => 'P',
+ 'Σ' => 'S',
+ 'Φ' => 'F',
+ 'Ψ' => 'Ps',
+ 'γ' => 'g',
+ 'δ' => 'e',
+ 'θ' => 'th',
+ 'λ' => 'l',
+ 'ξ' => 'x',
+ 'Ï€' => 'p',
+ 'σ' => 's',
+ 'φ' => 'f',
+ 'ψ' => 'ps',
+
+ // Thai
+ 'à¸' => 'k',
+ 'ข' => 'kh',
+ 'ฃ' => 'kh',
+ 'ค' => 'kh',
+ 'ฅ' => 'kh',
+ 'ฆ' => 'kh',
+ 'ง' => 'ng',
+ 'จ' => 'ch',
+ 'ฉ' => 'ch',
+ 'ช' => 'ch',
+ 'ซ' => 's',
+ 'ฌ' => 'ch',
+ 'à¸' => 'y',
+ 'ฎ' => 'd',
+ 'à¸' => 't',
+ 'à¸' => 'th',
+ 'ฑ' => 'd',
+ 'ฒ' => 'th',
+ 'ณ' => 'n',
+ 'ด' => 'd',
+ 'ต' => 't',
+ 'ถ' => 'th',
+ 'ท' => 'th',
+ 'ธ' => 'th',
+ 'น' => 'n',
+ 'บ' => 'b',
+ 'ป' => 'p',
+ 'ผ' => 'ph',
+ 'à¸' => 'f',
+ 'พ' => 'ph',
+ 'ฟ' => 'f',
+ 'ภ' => 'ph',
+ 'ม' => 'm',
+ 'ย' => 'y',
+ 'ร' => 'r',
+ 'ฤ' => 'rue',
+ 'ฤๅ' => 'rue',
+ 'ล' => 'l',
+ 'ฦ' => 'lue',
+ 'ฦๅ' => 'lue',
+ 'ว' => 'w',
+ 'ศ' => 's',
+ 'ษ' => 's',
+ 'ส' => 's',
+ 'ห' => 'h',
+ 'ฬ' => 'l',
+ 'ฮ' => 'h',
+ 'ะ' => 'a',
+ 'ั' => 'a',
+ 'รร' => 'a',
+ 'า' => 'a',
+ 'ๅ' => 'a',
+ 'ำ' => 'am',
+ 'à¹à¸²' => 'am',
+ 'ิ' => 'i',
+ 'ี' => 'i',
+ 'ึ' => 'ue',
+ 'ี' => 'ue',
+ 'ุ' => 'u',
+ 'ู' => 'u',
+ 'เ' => 'e',
+ 'à¹' => 'ae',
+ 'โ' => 'o',
+ 'อ' => 'o',
+ 'ียะ' => 'ia',
+ 'ีย' => 'ia',
+ 'ือะ' => 'uea',
+ 'ือ' => 'uea',
+ 'ัวะ' => 'ua',
+ 'ัว' => 'ua',
+ 'ใ' => 'ai',
+ 'ไ' => 'ai',
+ 'ัย' => 'ai',
+ 'าย' => 'ai',
+ 'าว' => 'ao',
+ 'ุย' => 'ui',
+ 'อย' => 'oi',
+ 'ือย' => 'ueai',
+ 'วย' => 'uai',
+ 'ิว' => 'io',
+ '็ว' => 'eo',
+ 'ียว' => 'iao',
+ '่' => '',
+ '้' => '',
+ '๊' => '',
+ '๋' => '',
+ '็' => '',
+ '์' => '',
+ '๎' => '',
+ 'à¹' => '',
+ 'ฺ' => '',
+ 'ๆ' => '2',
+ 'à¹' => 'o',
+ 'ฯ' => '-',
+ '๚' => '-',
+ '๛' => '-',
+ 'à¹' => '0',
+ '๑' => '1',
+ '๒' => '2',
+ '๓' => '3',
+ '๔' => '4',
+ '๕' => '5',
+ '๖' => '6',
+ '๗' => '7',
+ '๘' => '8',
+ '๙' => '9',
+
+ // Korean
+ 'ㄱ' => 'k', 'ㅋ' => 'kh',
+ 'ㄲ' => 'kk',
+ 'ã„·' => 't',
+ 'ㅌ' => 'th',
+ 'ㄸ' => 'tt',
+ 'ã…‚' => 'p',
+ 'ã…' => 'ph',
+ 'ã…ƒ' => 'pp',
+ 'ã…ˆ' => 'c',
+ 'ã…Š' => 'ch',
+ 'ã…‰' => 'cc',
+ 'ã……' => 's',
+ 'ã…†' => 'ss',
+ 'ã…Ž' => 'h',
+ 'ã…‡' => 'ng',
+ 'ã„´' => 'n',
+ 'ㄹ' => 'l',
+ 'ã…' => 'm',
+ 'ã…' => 'a',
+ 'ã…“' => 'e',
+ 'ã…—' => 'o',
+ 'ㅜ' => 'wu',
+ 'ã…¡' => 'u',
+ 'ã…£' => 'i',
+ 'ã…' => 'ay',
+ 'ã…”' => 'ey',
+ 'ã…š' => 'oy',
+ 'ã…˜' => 'wa',
+ 'ã…' => 'we',
+ 'ã…Ÿ' => 'wi',
+ 'ã…™' => 'way',
+ 'ã…ž' => 'wey',
+ 'ã…¢' => 'uy',
+ 'ã…‘' => 'ya',
+ 'ã…•' => 'ye',
+ 'ã…›' => 'oy',
+ 'ã… ' => 'yu',
+ 'ã…’' => 'yay',
+ 'ã…–' => 'yey',
+];
diff --git a/platform/www/inc/Utf8/tables/specials.php b/platform/www/inc/Utf8/tables/specials.php
new file mode 100644
index 0000000..f6243bc
--- /dev/null
+++ b/platform/www/inc/Utf8/tables/specials.php
@@ -0,0 +1,615 @@
+<?php
+/**
+ * UTF-8 array of common special characters
+ *
+ * This array should contain all special characters (not a letter or digit)
+ * defined in the various local charsets - it's not a complete list of non-alphanum
+ * characters in UTF-8. It's not perfect but should match most cases of special
+ * chars.
+ *
+ * The controlchars 0x00 to 0x19 are _not_ included in this array. The space 0x20 is!
+ * These chars are _not_ in the array either: _ (0x5f), : 0x3a, . 0x2e, - 0x2d, * 0x2a
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see \dokuwiki\Utf8\Clean::stripspecials()
+ */
+return [
+ 0x1a, // 
+ 0x1b, // 
+ 0x1c, // 
+ 0x1d, // 
+ 0x1e, // 
+ 0x1f, // 
+ 0x20, // <space>
+ 0x21, // !
+ 0x22, // "
+ 0x23, // #
+ 0x24, // $
+ 0x25, // %
+ 0x26, // &
+ 0x27, // '
+ 0x28, // (
+ 0x29, // )
+ 0x2b, // +
+ 0x2c, // ,
+ 0x2f, // /
+ 0x3b, // ;
+ 0x3c, // <
+ 0x3d, // =
+ 0x3e, // >
+ 0x3f, // ?
+ 0x40, // @
+ 0x5b, // [
+ 0x5c, // \
+ 0x5d, // ]
+ 0x5e, // ^
+ 0x60, // `
+ 0x7b, // {
+ 0x7c, // |
+ 0x7d, // }
+ 0x7e, // ~
+ 0x7f, // 
+ 0x80, // €
+ 0x81, // Â
+ 0x82, // ‚
+ 0x83, // ƒ
+ 0x84, // „
+ 0x85, // Â…
+ 0x86, // †
+ 0x87, // ‡
+ 0x88, // ˆ
+ 0x89, // ‰
+ 0x8a, // Š
+ 0x8b, // ‹
+ 0x8c, // Œ
+ 0x8d, // Â
+ 0x8e, // ÂŽ
+ 0x8f, // Â
+ 0x90, // Â
+ 0x91, // ‘
+ 0x92, // Â’
+ 0x93, // “
+ 0x94, // ”
+ 0x95, // •
+ 0x96, // –
+ 0x97, // —
+ 0x98, // ˜
+ 0x99, // ™
+ 0x9a, // š
+ 0x9b, // ›
+ 0x9c, // œ
+ 0x9d, // Â
+ 0x9e, // ž
+ 0x9f, // Ÿ
+ 0xa0, //  
+ 0xa1, // ¡
+ 0xa2, // ¢
+ 0xa3, // £
+ 0xa4, // ¤
+ 0xa5, // ¥
+ 0xa6, // ¦
+ 0xa7, // §
+ 0xa8, // ¨
+ 0xa9, // ©
+ 0xaa, // ª
+ 0xab, // «
+ 0xac, // ¬
+ 0xad, // ­
+ 0xae, // ®
+ 0xaf, // ¯
+ 0xb0, // °
+ 0xb1, // ±
+ 0xb2, // ²
+ 0xb3, // ³
+ 0xb4, // ´
+ 0xb5, // µ
+ 0xb6, // ¶
+ 0xb7, // ·
+ 0xb8, // ¸
+ 0xb9, // ¹
+ 0xba, // º
+ 0xbb, // »
+ 0xbc, // ¼
+ 0xbd, // ½
+ 0xbe, // ¾
+ 0xbf, // ¿
+ 0xd7, // ×
+ 0xf7, // ÷
+ 0x2c7, // ˇ
+ 0x2d8, // ˘
+ 0x2d9, // Ë™
+ 0x2da, // Ëš
+ 0x2db, // Ë›
+ 0x2dc, // ˜
+ 0x2dd, // Ë
+ 0x300, // ̀
+ 0x301, // Ì
+ 0x303, // ̃
+ 0x309, // ̉
+ 0x323, // ̣
+ 0x384, // ΄
+ 0x385, // Î…
+ 0x387, // ·
+ 0x5b0, // Ö°
+ 0x5b1, // Ö±
+ 0x5b2, // Ö²
+ 0x5b3, // Ö³
+ 0x5b4, // Ö´
+ 0x5b5, // Öµ
+ 0x5b6, // Ö¶
+ 0x5b7, // Ö·
+ 0x5b8, // Ö¸
+ 0x5b9, // Ö¹
+ 0x5bb, // Ö»
+ 0x5bc, // Ö¼
+ 0x5bd, // Ö½
+ 0x5be, // Ö¾
+ 0x5bf, // Ö¿
+ 0x5c0, // ×€
+ 0x5c1, // ×
+ 0x5c2, // ׂ
+ 0x5c3, // ׃
+ 0x5f3, // ׳
+ 0x5f4, // ×´
+ 0x60c, // ،
+ 0x61b, // Ø›
+ 0x61f, // ØŸ
+ 0x640, // Ù€
+ 0x64b, // Ù‹
+ 0x64c, // ٌ
+ 0x64d, // Ù
+ 0x64e, // ÙŽ
+ 0x64f, // Ù
+ 0x650, // Ù
+ 0x651, // Ù‘
+ 0x652, // Ù’
+ 0x66a, // Ùª
+ 0xe3f, // ฿
+ 0x200c, // ‌
+ 0x200d, // â€
+ 0x200e, // ‎
+ 0x200f, // â€
+ 0x2013, // –
+ 0x2014, // —
+ 0x2015, // ―
+ 0x2017, // ‗
+ 0x2018, // ‘
+ 0x2019, // ’
+ 0x201a, // ‚
+ 0x201c, // “
+ 0x201d, // â€
+ 0x201e, // „
+ 0x2020, // †
+ 0x2021, // ‡
+ 0x2022, // •
+ 0x2026, // …
+ 0x2030, // ‰
+ 0x2032, // ′
+ 0x2033, // ″
+ 0x2039, // ‹
+ 0x203a, // ›
+ 0x2044, // â„
+ 0x20a7, // ₧
+ 0x20aa, // ₪
+ 0x20ab, // â‚«
+ 0x20ac, // €
+ 0x2116, // â„–
+ 0x2118, // ℘
+ 0x2122, // â„¢
+ 0x2126, // Ω
+ 0x2135, // ℵ
+ 0x2190, // â†
+ 0x2191, // ↑
+ 0x2192, // →
+ 0x2193, // ↓
+ 0x2194, // ↔
+ 0x2195, // ↕
+ 0x21b5, // ↵
+ 0x21d0, // â‡
+ 0x21d1, // ⇑
+ 0x21d2, // ⇒
+ 0x21d3, // ⇓
+ 0x21d4, // ⇔
+ 0x2200, // ∀
+ 0x2202, // ∂
+ 0x2203, // ∃
+ 0x2205, // ∅
+ 0x2206, // ∆
+ 0x2207, // ∇
+ 0x2208, // ∈
+ 0x2209, // ∉
+ 0x220b, // ∋
+ 0x220f, // âˆ
+ 0x2211, // ∑
+ 0x2212, // −
+ 0x2215, // ∕
+ 0x2217, // ∗
+ 0x2219, // ∙
+ 0x221a, // √
+ 0x221d, // âˆ
+ 0x221e, // ∞
+ 0x2220, // ∠
+ 0x2227, // ∧
+ 0x2228, // ∨
+ 0x2229, // ∩
+ 0x222a, // ∪
+ 0x222b, // ∫
+ 0x2234, // ∴
+ 0x223c, // ∼
+ 0x2245, // ≅
+ 0x2248, // ≈
+ 0x2260, // ≠
+ 0x2261, // ≡
+ 0x2264, // ≤
+ 0x2265, // ≥
+ 0x2282, // ⊂
+ 0x2283, // ⊃
+ 0x2284, // ⊄
+ 0x2286, // ⊆
+ 0x2287, // ⊇
+ 0x2295, // ⊕
+ 0x2297, // ⊗
+ 0x22a5, // ⊥
+ 0x22c5, // â‹…
+ 0x2310, // âŒ
+ 0x2320, // ⌠
+ 0x2321, // ⌡
+ 0x2329, // 〈
+ 0x232a, // 〉
+ 0x2469, // â‘©
+ 0x2500, // ─
+ 0x2502, // │
+ 0x250c, // ┌
+ 0x2510, // â”
+ 0x2514, // â””
+ 0x2518, // ┘
+ 0x251c, // ├
+ 0x2524, // ┤
+ 0x252c, // ┬
+ 0x2534, // â”´
+ 0x253c, // ┼
+ 0x2550, // â•
+ 0x2551, // â•‘
+ 0x2552, // â•’
+ 0x2553, // â•“
+ 0x2554, // â•”
+ 0x2555, // â••
+ 0x2556, // â•–
+ 0x2557, // â•—
+ 0x2558, // ╘
+ 0x2559, // â•™
+ 0x255a, // â•š
+ 0x255b, // â•›
+ 0x255c, // ╜
+ 0x255d, // â•
+ 0x255e, // â•ž
+ 0x255f, // â•Ÿ
+ 0x2560, // â• 
+ 0x2561, // â•¡
+ 0x2562, // â•¢
+ 0x2563, // â•£
+ 0x2564, // ╤
+ 0x2565, // â•¥
+ 0x2566, // ╦
+ 0x2567, // ╧
+ 0x2568, // ╨
+ 0x2569, // â•©
+ 0x256a, // ╪
+ 0x256b, // â•«
+ 0x256c, // ╬
+ 0x2580, // â–€
+ 0x2584, // â–„
+ 0x2588, // â–ˆ
+ 0x258c, // ▌
+ 0x2590, // â–
+ 0x2591, // â–‘
+ 0x2592, // â–’
+ 0x2593, // â–“
+ 0x25a0, // â– 
+ 0x25b2, // â–²
+ 0x25bc, // â–¼
+ 0x25c6, // â—†
+ 0x25ca, // â—Š
+ 0x25cf, // â—
+ 0x25d7, // â——
+ 0x2605, // ★
+ 0x260e, // ☎
+ 0x261b, // ☛
+ 0x261e, // ☞
+ 0x2660, // â™ 
+ 0x2663, // ♣
+ 0x2665, // ♥
+ 0x2666, // ♦
+ 0x2701, // âœ
+ 0x2702, // ✂
+ 0x2703, // ✃
+ 0x2704, // ✄
+ 0x2706, // ✆
+ 0x2707, // ✇
+ 0x2708, // ✈
+ 0x2709, // ✉
+ 0x270c, // ✌
+ 0x270d, // âœ
+ 0x270e, // ✎
+ 0x270f, // âœ
+ 0x2710, // âœ
+ 0x2711, // ✑
+ 0x2712, // ✒
+ 0x2713, // ✓
+ 0x2714, // ✔
+ 0x2715, // ✕
+ 0x2716, // ✖
+ 0x2717, // ✗
+ 0x2718, // ✘
+ 0x2719, // ✙
+ 0x271a, // ✚
+ 0x271b, // ✛
+ 0x271c, // ✜
+ 0x271d, // âœ
+ 0x271e, // ✞
+ 0x271f, // ✟
+ 0x2720, // ✠
+ 0x2721, // ✡
+ 0x2722, // ✢
+ 0x2723, // ✣
+ 0x2724, // ✤
+ 0x2725, // ✥
+ 0x2726, // ✦
+ 0x2727, // ✧
+ 0x2729, // ✩
+ 0x272a, // ✪
+ 0x272b, // ✫
+ 0x272c, // ✬
+ 0x272d, // ✭
+ 0x272e, // ✮
+ 0x272f, // ✯
+ 0x2730, // ✰
+ 0x2731, // ✱
+ 0x2732, // ✲
+ 0x2733, // ✳
+ 0x2734, // ✴
+ 0x2735, // ✵
+ 0x2736, // ✶
+ 0x2737, // ✷
+ 0x2738, // ✸
+ 0x2739, // ✹
+ 0x273a, // ✺
+ 0x273b, // ✻
+ 0x273c, // ✼
+ 0x273d, // ✽
+ 0x273e, // ✾
+ 0x273f, // ✿
+ 0x2740, // â€
+ 0x2741, // â
+ 0x2742, // â‚
+ 0x2743, // âƒ
+ 0x2744, // â„
+ 0x2745, // â…
+ 0x2746, // â†
+ 0x2747, // â‡
+ 0x2748, // âˆ
+ 0x2749, // â‰
+ 0x274a, // âŠ
+ 0x274b, // â‹
+ 0x274d, // â
+ 0x274f, // â
+ 0x2750, // â
+ 0x2751, // â‘
+ 0x2752, // â’
+ 0x2756, // â–
+ 0x2758, // â˜
+ 0x2759, // â™
+ 0x275a, // âš
+ 0x275b, // â›
+ 0x275c, // âœ
+ 0x275d, // â
+ 0x275e, // âž
+ 0x2761, // â¡
+ 0x2762, // â¢
+ 0x2763, // â£
+ 0x2764, // â¤
+ 0x2765, // â¥
+ 0x2766, // â¦
+ 0x2767, // â§
+ 0x277f, // â¿
+ 0x2789, // ➉
+ 0x2793, // âž“
+ 0x2794, // âž”
+ 0x2798, // ➘
+ 0x2799, // âž™
+ 0x279a, // âžš
+ 0x279b, // âž›
+ 0x279c, // ➜
+ 0x279d, // âž
+ 0x279e, // âžž
+ 0x279f, // ➟
+ 0x27a0, // âž 
+ 0x27a1, // âž¡
+ 0x27a2, // ➢
+ 0x27a3, // ➣
+ 0x27a4, // ➤
+ 0x27a5, // ➥
+ 0x27a6, // ➦
+ 0x27a7, // ➧
+ 0x27a8, // ➨
+ 0x27a9, // âž©
+ 0x27aa, // ➪
+ 0x27ab, // âž«
+ 0x27ac, // ➬
+ 0x27ad, // âž­
+ 0x27ae, // âž®
+ 0x27af, // ➯
+ 0x27b1, // âž±
+ 0x27b2, // âž²
+ 0x27b3, // âž³
+ 0x27b4, // âž´
+ 0x27b5, // âžµ
+ 0x27b6, // ➶
+ 0x27b7, // âž·
+ 0x27b8, // ➸
+ 0x27b9, // âž¹
+ 0x27ba, // ➺
+ 0x27bb, // âž»
+ 0x27bc, // âž¼
+ 0x27bd, // âž½
+ 0x27be, // âž¾
+ 0x3000, //  
+ 0x3001, // ã€
+ 0x3002, // 。
+ 0x3003, // 〃
+ 0x3008, // 〈
+ 0x3009, // 〉
+ 0x300a, // 《
+ 0x300b, // 》
+ 0x300c, // 「
+ 0x300d, // ã€
+ 0x300e, // 『
+ 0x300f, // ã€
+ 0x3010, // ã€
+ 0x3011, // 】
+ 0x3012, // 〒
+ 0x3014, // 〔
+ 0x3015, // 〕
+ 0x3016, // 〖
+ 0x3017, // 〗
+ 0x3018, // 〘
+ 0x3019, // 〙
+ 0x301a, // 〚
+ 0x301b, // 〛
+ 0x3036, // 〶
+ 0xf6d9, // ï›™
+ 0xf6da, // 
+ 0xf6db, // ï››
+ 0xf8d7, // 
+ 0xf8d8, // 
+ 0xf8d9, // 
+ 0xf8da, // 
+ 0xf8db, // 
+ 0xf8dc, // 
+ 0xf8dd, // ï£
+ 0xf8de, // 
+ 0xf8df, // 
+ 0xf8e0, // 
+ 0xf8e1, // 
+ 0xf8e2, // 
+ 0xf8e3, // 
+ 0xf8e4, // 
+ 0xf8e5, // 
+ 0xf8e6, // 
+ 0xf8e7, // 
+ 0xf8e8, // 
+ 0xf8e9, // 
+ 0xf8ea, // 
+ 0xf8eb, // 
+ 0xf8ec, // 
+ 0xf8ed, // 
+ 0xf8ee, // 
+ 0xf8ef, // 
+ 0xf8f0, // 
+ 0xf8f1, // 
+ 0xf8f2, // 
+ 0xf8f3, // 
+ 0xf8f4, // 
+ 0xf8f5, // 
+ 0xf8f6, // 
+ 0xf8f7, // 
+ 0xf8f8, // 
+ 0xf8f9, // 
+ 0xf8fa, // 
+ 0xf8fb, // 
+ 0xf8fc, // 
+ 0xf8fd, // 
+ 0xf8fe, // 
+ 0xfe7c, // ï¹¼
+ 0xfe7d, // ï¹½
+ 0xff01, // ï¼
+ 0xff02, // "
+ 0xff03, // #
+ 0xff04, // $
+ 0xff05, // ï¼…
+ 0xff06, // &
+ 0xff07, // '
+ 0xff08, // (
+ 0xff09, // )
+ 0xff09, // )
+ 0xff0a, // *
+ 0xff0b, // +
+ 0xff0c, // ,
+ 0xff0d, // ï¼
+ 0xff0e, // .
+ 0xff0f, // ï¼
+ 0xff1a, // :
+ 0xff1b, // ï¼›
+ 0xff1c, // <
+ 0xff1d, // ï¼
+ 0xff1e, // >
+ 0xff1f, // ?
+ 0xff20, // ï¼ 
+ 0xff3b, // ï¼»
+ 0xff3c, // ï¼¼
+ 0xff3d, // ï¼½
+ 0xff3e, // ï¼¾
+ 0xff40, // ï½€
+ 0xff5b, // ï½›
+ 0xff5c, // |
+ 0xff5d, // ï½
+ 0xff5e, // ~
+ 0xff5f, // ⦅
+ 0xff60, // ï½ 
+ 0xff61, // 。
+ 0xff62, // ï½¢
+ 0xff63, // ï½£
+ 0xff64, // 、
+ 0xff65, // ï½¥
+ 0xffe0, // ï¿ 
+ 0xffe1, // ï¿¡
+ 0xffe2, // ï¿¢
+ 0xffe3, // ï¿£
+ 0xffe4, // ¦
+ 0xffe5, // ï¿¥
+ 0xffe6, // ₩
+ 0xffe8, // │
+ 0xffe9, // ï¿©
+ 0xffea, // ↑
+ 0xffeb, // ï¿«
+ 0xffec, // ↓
+ 0xffed, // ï¿­
+ 0xffee, // ï¿®
+ 0x1d6fc, // ð›¼
+ 0x1d6fd, // ð›½
+ 0x1d6fe, // ð›¾
+ 0x1d6ff, // ð›¿
+ 0x1d700, // ðœ€
+ 0x1d701, // ðœ
+ 0x1d702, // ðœ‚
+ 0x1d703, // ðœƒ
+ 0x1d704, // ðœ„
+ 0x1d705, // ðœ…
+ 0x1d706, // ðœ†
+ 0x1d707, // ðœ‡
+ 0x1d708, // ðœˆ
+ 0x1d709, // ðœ‰
+ 0x1d70a, // ðœŠ
+ 0x1d70b, // ðœ‹
+ 0x1d70c, // ðœŒ
+ 0x1d70d, // ðœ
+ 0x1d70e, // ðœŽ
+ 0x1d70f, // ðœ
+ 0x1d710, // ðœ
+ 0x1d711, // ðœ‘
+ 0x1d712, // ðœ’
+ 0x1d713, // ðœ“
+ 0x1d714, // ðœ”
+ 0x1d715, // ðœ•
+ 0x1d716, // ðœ–
+ 0x1d717, // ðœ—
+ 0x1d718, // ðœ˜
+ 0x1d719, // ðœ™
+ 0x1d71a, // ðœš
+ 0x1d71b, // ðœ›
+ 0xc2a0, // 슠
+ 0xe28087, //
+ 0xe280af, //
+ 0xe281a0, //
+ 0xefbbbf, //
+];
diff --git a/platform/www/inc/Utf8/tables/upperaccents.php b/platform/www/inc/Utf8/tables/upperaccents.php
new file mode 100644
index 0000000..e6e48de
--- /dev/null
+++ b/platform/www/inc/Utf8/tables/upperaccents.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ * UTF-8 lookup table for upper case accented letters
+ *
+ * This lookuptable defines replacements for accented characters from the ASCII-7
+ * range. This are upper case letters only.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see \dokuwiki\Utf8\Clean::deaccent()
+ */
+return [
+ 'Ã' => 'A',
+ 'À' => 'A',
+ 'Ä‚' => 'A',
+ 'Â' => 'A',
+ 'Ã…' => 'A',
+ 'Ä' => 'Ae',
+ 'Ã' => 'A',
+ 'Ä„' => 'A',
+ 'Ä€' => 'A',
+ 'Æ' => 'Ae',
+ 'Ḃ' => 'B',
+ 'Ć' => 'C',
+ 'Ĉ' => 'C',
+ 'Č' => 'C',
+ 'ÄŠ' => 'C',
+ 'Ç' => 'C',
+ 'ÄŽ' => 'D',
+ 'Ḋ' => 'D',
+ 'Ä' => 'D',
+ 'Ã' => 'Dh',
+ 'É' => 'E',
+ 'È' => 'E',
+ 'Ä”' => 'E',
+ 'Ê' => 'E',
+ 'Äš' => 'E',
+ 'Ë' => 'E',
+ 'Ä–' => 'E',
+ 'Ę' => 'E',
+ 'Ä’' => 'E',
+ 'Ḟ' => 'F',
+ 'Æ‘' => 'F',
+ 'Äž' => 'G',
+ 'Ĝ' => 'G',
+ 'Ä ' => 'G',
+ 'Ä¢' => 'G',
+ 'Ĥ' => 'H',
+ 'Ħ' => 'H',
+ 'Ã' => 'I',
+ 'Ì' => 'I',
+ 'ÃŽ' => 'I',
+ 'Ã' => 'I',
+ 'Ĩ' => 'I',
+ 'Ä®' => 'I',
+ 'Ī' => 'I',
+ 'Ä´' => 'J',
+ 'Ķ' => 'K',
+ 'Ĺ' => 'L',
+ 'Ľ' => 'L',
+ 'Ä»' => 'L',
+ 'Å' => 'L',
+ 'á¹€' => 'M',
+ 'Ń' => 'N',
+ 'Ň' => 'N',
+ 'Ñ' => 'N',
+ 'Å…' => 'N',
+ 'Ó' => 'O',
+ 'Ã’' => 'O',
+ 'Ô' => 'O',
+ 'Ö' => 'Oe',
+ 'Å' => 'O',
+ 'Õ' => 'O',
+ 'Ø' => 'O',
+ 'Ō' => 'O',
+ 'Æ ' => 'O',
+ 'á¹–' => 'P',
+ 'Å”' => 'R',
+ 'Ř' => 'R',
+ 'Å–' => 'R',
+ 'Åš' => 'S',
+ 'Ŝ' => 'S',
+ 'Å ' => 'S',
+ 'á¹ ' => 'S',
+ 'Åž' => 'S',
+ 'Ș' => 'S',
+ 'Ť' => 'T',
+ 'Ṫ' => 'T',
+ 'Å¢' => 'T',
+ 'Èš' => 'T',
+ 'Ŧ' => 'T',
+ 'Ú' => 'U',
+ 'Ù' => 'U',
+ 'Ŭ' => 'U',
+ 'Û' => 'U',
+ 'Å®' => 'U',
+ 'Ü' => 'Ue',
+ 'Å°' => 'U',
+ 'Ũ' => 'U',
+ 'Ų' => 'U',
+ 'Ū' => 'U',
+ 'Ư' => 'U',
+ 'Ẃ' => 'W',
+ 'Ẁ' => 'W',
+ 'Å´' => 'W',
+ 'Ẅ' => 'W',
+ 'Ã' => 'Y',
+ 'Ỳ' => 'Y',
+ 'Ŷ' => 'Y',
+ 'Ÿ' => 'Y',
+ 'Ź' => 'Z',
+ 'Ž' => 'Z',
+ 'Å»' => 'Z',
+ 'Þ' => 'Th',
+];
diff --git a/platform/www/inc/actions.php b/platform/www/inc/actions.php
new file mode 100644
index 0000000..4ea529d
--- /dev/null
+++ b/platform/www/inc/actions.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * DokuWiki Actions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Extension\Event;
+
+/**
+ * All action processing starts here
+ */
+function act_dispatch(){
+ // always initialize on first dispatch (test request may dispatch mutliple times on one request)
+ $router = \dokuwiki\ActionRouter::getInstance(true);
+
+ $headers = array('Content-Type: text/html; charset=utf-8');
+ Event::createAndTrigger('ACTION_HEADERS_SEND',$headers,'act_sendheaders');
+
+ // clear internal variables
+ unset($router);
+ unset($headers);
+ // make all globals available to the template
+ extract($GLOBALS);
+
+ include(template('main.php'));
+ // output for the commands is now handled in inc/templates.php
+ // in function tpl_content()
+}
+
+/**
+ * Send the given headers using header()
+ *
+ * @param array $headers The headers that shall be sent
+ */
+function act_sendheaders($headers) {
+ foreach ($headers as $hdr) header($hdr);
+}
+
+/**
+ * Sanitize the action command
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array|string $act
+ * @return string
+ */
+function act_clean($act){
+ // check if the action was given as array key
+ if(is_array($act)){
+ list($act) = array_keys($act);
+ }
+
+ //remove all bad chars
+ $act = strtolower($act);
+ $act = preg_replace('/[^1-9a-z_]+/','',$act);
+
+ if($act == 'export_html') $act = 'export_xhtml';
+ if($act == 'export_htmlbody') $act = 'export_xhtmlbody';
+
+ if($act === '') $act = 'show';
+ return $act;
+}
diff --git a/platform/www/inc/auth.php b/platform/www/inc/auth.php
new file mode 100644
index 0000000..96ae7c2
--- /dev/null
+++ b/platform/www/inc/auth.php
@@ -0,0 +1,1279 @@
+<?php
+/**
+ * Authentication library
+ *
+ * Including this file will automatically try to login
+ * a user by calling auth_login()
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Extension\AuthPlugin;
+use dokuwiki\Extension\Event;
+use dokuwiki\Extension\PluginController;
+use dokuwiki\PassHash;
+use dokuwiki\Subscriptions\RegistrationSubscriptionSender;
+
+/**
+ * Initialize the auth system.
+ *
+ * This function is automatically called at the end of init.php
+ *
+ * This used to be the main() of the auth.php
+ *
+ * @todo backend loading maybe should be handled by the class autoloader
+ * @todo maybe split into multiple functions at the XXX marked positions
+ * @triggers AUTH_LOGIN_CHECK
+ * @return bool
+ */
+function auth_setup() {
+ global $conf;
+ /* @var AuthPlugin $auth */
+ global $auth;
+ /* @var Input $INPUT */
+ global $INPUT;
+ global $AUTH_ACL;
+ global $lang;
+ /* @var PluginController $plugin_controller */
+ global $plugin_controller;
+ $AUTH_ACL = array();
+
+ if(!$conf['useacl']) return false;
+
+ // try to load auth backend from plugins
+ foreach ($plugin_controller->getList('auth') as $plugin) {
+ if ($conf['authtype'] === $plugin) {
+ $auth = $plugin_controller->load('auth', $plugin);
+ break;
+ }
+ }
+
+ if(!isset($auth) || !$auth){
+ msg($lang['authtempfail'], -1);
+ return false;
+ }
+
+ if ($auth->success == false) {
+ // degrade to unauthenticated user
+ unset($auth);
+ auth_logoff();
+ msg($lang['authtempfail'], -1);
+ return false;
+ }
+
+ // do the login either by cookie or provided credentials XXX
+ $INPUT->set('http_credentials', false);
+ if(!$conf['rememberme']) $INPUT->set('r', false);
+
+ // handle renamed HTTP_AUTHORIZATION variable (can happen when a fix like
+ // the one presented at
+ // http://www.besthostratings.com/articles/http-auth-php-cgi.html is used
+ // for enabling HTTP authentication with CGI/SuExec)
+ if(isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']))
+ $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
+ // streamline HTTP auth credentials (IIS/rewrite -> mod_php)
+ if(isset($_SERVER['HTTP_AUTHORIZATION'])) {
+ list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
+ explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
+ }
+
+ // if no credentials were given try to use HTTP auth (for SSO)
+ if(!$INPUT->str('u') && empty($_COOKIE[DOKU_COOKIE]) && !empty($_SERVER['PHP_AUTH_USER'])) {
+ $INPUT->set('u', $_SERVER['PHP_AUTH_USER']);
+ $INPUT->set('p', $_SERVER['PHP_AUTH_PW']);
+ $INPUT->set('http_credentials', true);
+ }
+
+ // apply cleaning (auth specific user names, remove control chars)
+ if (true === $auth->success) {
+ $INPUT->set('u', $auth->cleanUser(stripctl($INPUT->str('u'))));
+ $INPUT->set('p', stripctl($INPUT->str('p')));
+ }
+
+ $ok = null;
+ if (!is_null($auth) && $auth->canDo('external')) {
+ $ok = $auth->trustExternal($INPUT->str('u'), $INPUT->str('p'), $INPUT->bool('r'));
+ }
+
+ if ($ok === null) {
+ // external trust mechanism not in place, or returns no result,
+ // then attempt auth_login
+ $evdata = array(
+ 'user' => $INPUT->str('u'),
+ 'password' => $INPUT->str('p'),
+ 'sticky' => $INPUT->bool('r'),
+ 'silent' => $INPUT->bool('http_credentials')
+ );
+ Event::createAndTrigger('AUTH_LOGIN_CHECK', $evdata, 'auth_login_wrapper');
+ }
+
+ //load ACL into a global array XXX
+ $AUTH_ACL = auth_loadACL();
+
+ return true;
+}
+
+/**
+ * Loads the ACL setup and handle user wildcards
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return array
+ */
+function auth_loadACL() {
+ global $config_cascade;
+ global $USERINFO;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ if(!is_readable($config_cascade['acl']['default'])) return array();
+
+ $acl = file($config_cascade['acl']['default']);
+
+ $out = array();
+ foreach($acl as $line) {
+ $line = trim($line);
+ if(empty($line) || ($line[0] == '#')) continue; // skip blank lines & comments
+ list($id,$rest) = preg_split('/[ \t]+/',$line,2);
+
+ // substitute user wildcard first (its 1:1)
+ if(strstr($line, '%USER%')){
+ // if user is not logged in, this ACL line is meaningless - skip it
+ if (!$INPUT->server->has('REMOTE_USER')) continue;
+
+ $id = str_replace('%USER%',cleanID($INPUT->server->str('REMOTE_USER')),$id);
+ $rest = str_replace('%USER%',auth_nameencode($INPUT->server->str('REMOTE_USER')),$rest);
+ }
+
+ // substitute group wildcard (its 1:m)
+ if(strstr($line, '%GROUP%')){
+ // if user is not logged in, grps is empty, no output will be added (i.e. skipped)
+ if(isset($USERINFO['grps'])){
+ foreach((array) $USERINFO['grps'] as $grp){
+ $nid = str_replace('%GROUP%',cleanID($grp),$id);
+ $nrest = str_replace('%GROUP%','@'.auth_nameencode($grp),$rest);
+ $out[] = "$nid\t$nrest";
+ }
+ }
+ } else {
+ $out[] = "$id\t$rest";
+ }
+ }
+
+ return $out;
+}
+
+/**
+ * Event hook callback for AUTH_LOGIN_CHECK
+ *
+ * @param array $evdata
+ * @return bool
+ */
+function auth_login_wrapper($evdata) {
+ return auth_login(
+ $evdata['user'],
+ $evdata['password'],
+ $evdata['sticky'],
+ $evdata['silent']
+ );
+}
+
+/**
+ * This tries to login the user based on the sent auth credentials
+ *
+ * The authentication works like this: if a username was given
+ * a new login is assumed and user/password are checked. If they
+ * are correct the password is encrypted with blowfish and stored
+ * together with the username in a cookie - the same info is stored
+ * in the session, too. Additonally a browserID is stored in the
+ * session.
+ *
+ * If no username was given the cookie is checked: if the username,
+ * crypted password and browserID match between session and cookie
+ * no further testing is done and the user is accepted
+ *
+ * If a cookie was found but no session info was availabe the
+ * blowfish encrypted password from the cookie is decrypted and
+ * together with username rechecked by calling this function again.
+ *
+ * On a successful login $_SERVER[REMOTE_USER] and $USERINFO
+ * are set.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $user Username
+ * @param string $pass Cleartext Password
+ * @param bool $sticky Cookie should not expire
+ * @param bool $silent Don't show error on bad auth
+ * @return bool true on successful auth
+ */
+function auth_login($user, $pass, $sticky = false, $silent = false) {
+ global $USERINFO;
+ global $conf;
+ global $lang;
+ /* @var AuthPlugin $auth */
+ global $auth;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ $sticky ? $sticky = true : $sticky = false; //sanity check
+
+ if(!$auth) return false;
+
+ if(!empty($user)) {
+ //usual login
+ if(!empty($pass) && $auth->checkPass($user, $pass)) {
+ // make logininfo globally available
+ $INPUT->server->set('REMOTE_USER', $user);
+ $secret = auth_cookiesalt(!$sticky, true); //bind non-sticky to session
+ auth_setCookie($user, auth_encrypt($pass, $secret), $sticky);
+ return true;
+ } else {
+ //invalid credentials - log off
+ if(!$silent) {
+ http_status(403, 'Login failed');
+ msg($lang['badlogin'], -1);
+ }
+ auth_logoff();
+ return false;
+ }
+ } else {
+ // read cookie information
+ list($user, $sticky, $pass) = auth_getCookie();
+ if($user && $pass) {
+ // we got a cookie - see if we can trust it
+
+ // get session info
+ $session = $_SESSION[DOKU_COOKIE]['auth'];
+ if(isset($session) &&
+ $auth->useSessionCache($user) &&
+ ($session['time'] >= time() - $conf['auth_security_timeout']) &&
+ ($session['user'] == $user) &&
+ ($session['pass'] == sha1($pass)) && //still crypted
+ ($session['buid'] == auth_browseruid())
+ ) {
+
+ // he has session, cookie and browser right - let him in
+ $INPUT->server->set('REMOTE_USER', $user);
+ $USERINFO = $session['info']; //FIXME move all references to session
+ return true;
+ }
+ // no we don't trust it yet - recheck pass but silent
+ $secret = auth_cookiesalt(!$sticky, true); //bind non-sticky to session
+ $pass = auth_decrypt($pass, $secret);
+ return auth_login($user, $pass, $sticky, true);
+ }
+ }
+ //just to be sure
+ auth_logoff(true);
+ return false;
+}
+
+/**
+ * Builds a pseudo UID from browser and IP data
+ *
+ * This is neither unique nor unfakable - still it adds some
+ * security. Using the first part of the IP makes sure
+ * proxy farms like AOLs are still okay.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return string a MD5 sum of various browser headers
+ */
+function auth_browseruid() {
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ $ip = clientIP(true);
+ $uid = '';
+ $uid .= $INPUT->server->str('HTTP_USER_AGENT');
+ $uid .= $INPUT->server->str('HTTP_ACCEPT_CHARSET');
+ $uid .= substr($ip, 0, strpos($ip, '.'));
+ $uid = strtolower($uid);
+ return md5($uid);
+}
+
+/**
+ * Creates a random key to encrypt the password in cookies
+ *
+ * This function tries to read the password for encrypting
+ * cookies from $conf['metadir'].'/_htcookiesalt'
+ * if no such file is found a random key is created and
+ * and stored in this file.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param bool $addsession if true, the sessionid is added to the salt
+ * @param bool $secure if security is more important than keeping the old value
+ * @return string
+ */
+function auth_cookiesalt($addsession = false, $secure = false) {
+ if (defined('SIMPLE_TEST')) {
+ return 'test';
+ }
+ global $conf;
+ $file = $conf['metadir'].'/_htcookiesalt';
+ if ($secure || !file_exists($file)) {
+ $file = $conf['metadir'].'/_htcookiesalt2';
+ }
+ $salt = io_readFile($file);
+ if(empty($salt)) {
+ $salt = bin2hex(auth_randombytes(64));
+ io_saveFile($file, $salt);
+ }
+ if($addsession) {
+ $salt .= session_id();
+ }
+ return $salt;
+}
+
+/**
+ * Return cryptographically secure random bytes.
+ *
+ * @author Niklas Keller <me@kelunik.com>
+ *
+ * @param int $length number of bytes
+ * @return string cryptographically secure random bytes
+ */
+function auth_randombytes($length) {
+ return random_bytes($length);
+}
+
+/**
+ * Cryptographically secure random number generator.
+ *
+ * @author Niklas Keller <me@kelunik.com>
+ *
+ * @param int $min
+ * @param int $max
+ * @return int
+ */
+function auth_random($min, $max) {
+ return random_int($min, $max);
+}
+
+/**
+ * Encrypt data using the given secret using AES
+ *
+ * The mode is CBC with a random initialization vector, the key is derived
+ * using pbkdf2.
+ *
+ * @param string $data The data that shall be encrypted
+ * @param string $secret The secret/password that shall be used
+ * @return string The ciphertext
+ */
+function auth_encrypt($data, $secret) {
+ $iv = auth_randombytes(16);
+ $cipher = new \phpseclib\Crypt\AES();
+ $cipher->setPassword($secret);
+
+ /*
+ this uses the encrypted IV as IV as suggested in
+ http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf, Appendix C
+ for unique but necessarily random IVs. The resulting ciphertext is
+ compatible to ciphertext that was created using a "normal" IV.
+ */
+ return $cipher->encrypt($iv.$data);
+}
+
+/**
+ * Decrypt the given AES ciphertext
+ *
+ * The mode is CBC, the key is derived using pbkdf2
+ *
+ * @param string $ciphertext The encrypted data
+ * @param string $secret The secret/password that shall be used
+ * @return string The decrypted data
+ */
+function auth_decrypt($ciphertext, $secret) {
+ $iv = substr($ciphertext, 0, 16);
+ $cipher = new \phpseclib\Crypt\AES();
+ $cipher->setPassword($secret);
+ $cipher->setIV($iv);
+
+ return $cipher->decrypt(substr($ciphertext, 16));
+}
+
+/**
+ * Log out the current user
+ *
+ * This clears all authentication data and thus log the user
+ * off. It also clears session data.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param bool $keepbc - when true, the breadcrumb data is not cleared
+ */
+function auth_logoff($keepbc = false) {
+ global $conf;
+ global $USERINFO;
+ /* @var AuthPlugin $auth */
+ global $auth;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ // make sure the session is writable (it usually is)
+ @session_start();
+
+ if(isset($_SESSION[DOKU_COOKIE]['auth']['user']))
+ unset($_SESSION[DOKU_COOKIE]['auth']['user']);
+ if(isset($_SESSION[DOKU_COOKIE]['auth']['pass']))
+ unset($_SESSION[DOKU_COOKIE]['auth']['pass']);
+ if(isset($_SESSION[DOKU_COOKIE]['auth']['info']))
+ unset($_SESSION[DOKU_COOKIE]['auth']['info']);
+ if(!$keepbc && isset($_SESSION[DOKU_COOKIE]['bc']))
+ unset($_SESSION[DOKU_COOKIE]['bc']);
+ $INPUT->server->remove('REMOTE_USER');
+ $USERINFO = null; //FIXME
+
+ $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
+ setcookie(DOKU_COOKIE, '', time() - 600000, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true);
+
+ if($auth) $auth->logOff();
+}
+
+/**
+ * Check if a user is a manager
+ *
+ * Should usually be called without any parameters to check the current
+ * user.
+ *
+ * The info is available through $INFO['ismanager'], too
+ *
+ * @param string $user Username
+ * @param array $groups List of groups the user is in
+ * @param bool $adminonly when true checks if user is admin
+ * @param bool $recache set to true to refresh the cache
+ * @return bool
+ * @see auth_isadmin
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function auth_ismanager($user = null, $groups = null, $adminonly = false, $recache=false) {
+ global $conf;
+ global $USERINFO;
+ /* @var AuthPlugin $auth */
+ global $auth;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+
+ if(!$auth) return false;
+ if(is_null($user)) {
+ if(!$INPUT->server->has('REMOTE_USER')) {
+ return false;
+ } else {
+ $user = $INPUT->server->str('REMOTE_USER');
+ }
+ }
+ if(is_null($groups)) {
+ $groups = $USERINFO ? (array) $USERINFO['grps'] : array();
+ }
+
+ // prefer cached result
+ static $cache = [];
+ $cachekey = serialize([$user, $adminonly, $groups]);
+ if (!isset($cache[$cachekey]) || $recache) {
+ // check superuser match
+ $ok = auth_isMember($conf['superuser'], $user, $groups);
+
+ // check managers
+ if (!$ok && !$adminonly) {
+ $ok = auth_isMember($conf['manager'], $user, $groups);
+ }
+
+ $cache[$cachekey] = $ok;
+ }
+
+ return $cache[$cachekey];
+}
+
+/**
+ * Check if a user is admin
+ *
+ * Alias to auth_ismanager with adminonly=true
+ *
+ * The info is available through $INFO['isadmin'], too
+ *
+ * @param string $user Username
+ * @param array $groups List of groups the user is in
+ * @param bool $recache set to true to refresh the cache
+ * @return bool
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see auth_ismanager()
+ *
+ */
+function auth_isadmin($user = null, $groups = null, $recache=false) {
+ return auth_ismanager($user, $groups, true, $recache);
+}
+
+/**
+ * Match a user and his groups against a comma separated list of
+ * users and groups to determine membership status
+ *
+ * Note: all input should NOT be nameencoded.
+ *
+ * @param string $memberlist commaseparated list of allowed users and groups
+ * @param string $user user to match against
+ * @param array $groups groups the user is member of
+ * @return bool true for membership acknowledged
+ */
+function auth_isMember($memberlist, $user, array $groups) {
+ /* @var AuthPlugin $auth */
+ global $auth;
+ if(!$auth) return false;
+
+ // clean user and groups
+ if(!$auth->isCaseSensitive()) {
+ $user = \dokuwiki\Utf8\PhpString::strtolower($user);
+ $groups = array_map('utf8_strtolower', $groups);
+ }
+ $user = $auth->cleanUser($user);
+ $groups = array_map(array($auth, 'cleanGroup'), $groups);
+
+ // extract the memberlist
+ $members = explode(',', $memberlist);
+ $members = array_map('trim', $members);
+ $members = array_unique($members);
+ $members = array_filter($members);
+
+ // compare cleaned values
+ foreach($members as $member) {
+ if($member == '@ALL' ) return true;
+ if(!$auth->isCaseSensitive()) $member = \dokuwiki\Utf8\PhpString::strtolower($member);
+ if($member[0] == '@') {
+ $member = $auth->cleanGroup(substr($member, 1));
+ if(in_array($member, $groups)) return true;
+ } else {
+ $member = $auth->cleanUser($member);
+ if($member == $user) return true;
+ }
+ }
+
+ // still here? not a member!
+ return false;
+}
+
+/**
+ * Convinience function for auth_aclcheck()
+ *
+ * This checks the permissions for the current user
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page ID (needs to be resolved and cleaned)
+ * @return int permission level
+ */
+function auth_quickaclcheck($id) {
+ global $conf;
+ global $USERINFO;
+ /* @var Input $INPUT */
+ global $INPUT;
+ # if no ACL is used always return upload rights
+ if(!$conf['useacl']) return AUTH_UPLOAD;
+ return auth_aclcheck($id, $INPUT->server->str('REMOTE_USER'), is_array($USERINFO) ? $USERINFO['grps'] : array());
+}
+
+/**
+ * Returns the maximum rights a user has for the given ID or its namespace
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @triggers AUTH_ACL_CHECK
+ * @param string $id page ID (needs to be resolved and cleaned)
+ * @param string $user Username
+ * @param array|null $groups Array of groups the user is in
+ * @return int permission level
+ */
+function auth_aclcheck($id, $user, $groups) {
+ $data = array(
+ 'id' => $id,
+ 'user' => $user,
+ 'groups' => $groups
+ );
+
+ return Event::createAndTrigger('AUTH_ACL_CHECK', $data, 'auth_aclcheck_cb');
+}
+
+/**
+ * default ACL check method
+ *
+ * DO NOT CALL DIRECTLY, use auth_aclcheck() instead
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data event data
+ * @return int permission level
+ */
+function auth_aclcheck_cb($data) {
+ $id =& $data['id'];
+ $user =& $data['user'];
+ $groups =& $data['groups'];
+
+ global $conf;
+ global $AUTH_ACL;
+ /* @var AuthPlugin $auth */
+ global $auth;
+
+ // if no ACL is used always return upload rights
+ if(!$conf['useacl']) return AUTH_UPLOAD;
+ if(!$auth) return AUTH_NONE;
+
+ //make sure groups is an array
+ if(!is_array($groups)) $groups = array();
+
+ //if user is superuser or in superusergroup return 255 (acl_admin)
+ if(auth_isadmin($user, $groups)) {
+ return AUTH_ADMIN;
+ }
+
+ if(!$auth->isCaseSensitive()) {
+ $user = \dokuwiki\Utf8\PhpString::strtolower($user);
+ $groups = array_map('utf8_strtolower', $groups);
+ }
+ $user = auth_nameencode($auth->cleanUser($user));
+ $groups = array_map(array($auth, 'cleanGroup'), (array) $groups);
+
+ //prepend groups with @ and nameencode
+ foreach($groups as &$group) {
+ $group = '@'.auth_nameencode($group);
+ }
+
+ $ns = getNS($id);
+ $perm = -1;
+
+ //add ALL group
+ $groups[] = '@ALL';
+
+ //add User
+ if($user) $groups[] = $user;
+
+ //check exact match first
+ $matches = preg_grep('/^'.preg_quote($id, '/').'[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL);
+ if(count($matches)) {
+ foreach($matches as $match) {
+ $match = preg_replace('/#.*$/', '', $match); //ignore comments
+ $acl = preg_split('/[ \t]+/', $match);
+ if(!$auth->isCaseSensitive() && $acl[1] !== '@ALL') {
+ $acl[1] = \dokuwiki\Utf8\PhpString::strtolower($acl[1]);
+ }
+ if(!in_array($acl[1], $groups)) {
+ continue;
+ }
+ if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL!
+ if($acl[2] > $perm) {
+ $perm = $acl[2];
+ }
+ }
+ if($perm > -1) {
+ //we had a match - return it
+ return (int) $perm;
+ }
+ }
+
+ //still here? do the namespace checks
+ if($ns) {
+ $path = $ns.':*';
+ } else {
+ $path = '*'; //root document
+ }
+
+ do {
+ $matches = preg_grep('/^'.preg_quote($path, '/').'[ \t]+([^ \t]+)[ \t]+/', $AUTH_ACL);
+ if(count($matches)) {
+ foreach($matches as $match) {
+ $match = preg_replace('/#.*$/', '', $match); //ignore comments
+ $acl = preg_split('/[ \t]+/', $match);
+ if(!$auth->isCaseSensitive() && $acl[1] !== '@ALL') {
+ $acl[1] = \dokuwiki\Utf8\PhpString::strtolower($acl[1]);
+ }
+ if(!in_array($acl[1], $groups)) {
+ continue;
+ }
+ if($acl[2] > AUTH_DELETE) $acl[2] = AUTH_DELETE; //no admins in the ACL!
+ if($acl[2] > $perm) {
+ $perm = $acl[2];
+ }
+ }
+ //we had a match - return it
+ if($perm != -1) {
+ return (int) $perm;
+ }
+ }
+ //get next higher namespace
+ $ns = getNS($ns);
+
+ if($path != '*') {
+ $path = $ns.':*';
+ if($path == ':*') $path = '*';
+ } else {
+ //we did this already
+ //looks like there is something wrong with the ACL
+ //break here
+ msg('No ACL setup yet! Denying access to everyone.');
+ return AUTH_NONE;
+ }
+ } while(1); //this should never loop endless
+ return AUTH_NONE;
+}
+
+/**
+ * Encode ASCII special chars
+ *
+ * Some auth backends allow special chars in their user and groupnames
+ * The special chars are encoded with this function. Only ASCII chars
+ * are encoded UTF-8 multibyte are left as is (different from usual
+ * urlencoding!).
+ *
+ * Decoding can be done with rawurldecode
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ * @see rawurldecode()
+ *
+ * @param string $name
+ * @param bool $skip_group
+ * @return string
+ */
+function auth_nameencode($name, $skip_group = false) {
+ global $cache_authname;
+ $cache =& $cache_authname;
+ $name = (string) $name;
+
+ // never encode wildcard FS#1955
+ if($name == '%USER%') return $name;
+ if($name == '%GROUP%') return $name;
+
+ if(!isset($cache[$name][$skip_group])) {
+ if($skip_group && $name[0] == '@') {
+ $cache[$name][$skip_group] = '@'.preg_replace_callback(
+ '/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/',
+ 'auth_nameencode_callback', substr($name, 1)
+ );
+ } else {
+ $cache[$name][$skip_group] = preg_replace_callback(
+ '/([\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f])/',
+ 'auth_nameencode_callback', $name
+ );
+ }
+ }
+
+ return $cache[$name][$skip_group];
+}
+
+/**
+ * callback encodes the matches
+ *
+ * @param array $matches first complete match, next matching subpatterms
+ * @return string
+ */
+function auth_nameencode_callback($matches) {
+ return '%'.dechex(ord(substr($matches[1],-1)));
+}
+
+/**
+ * Create a pronouncable password
+ *
+ * The $foruser variable might be used by plugins to run additional password
+ * policy checks, but is not used by the default implementation
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @link http://www.phpbuilder.com/annotate/message.php3?id=1014451
+ * @triggers AUTH_PASSWORD_GENERATE
+ *
+ * @param string $foruser username for which the password is generated
+ * @return string pronouncable password
+ */
+function auth_pwgen($foruser = '') {
+ $data = array(
+ 'password' => '',
+ 'foruser' => $foruser
+ );
+
+ $evt = new Event('AUTH_PASSWORD_GENERATE', $data);
+ if($evt->advise_before(true)) {
+ $c = 'bcdfghjklmnprstvwz'; //consonants except hard to speak ones
+ $v = 'aeiou'; //vowels
+ $a = $c.$v; //both
+ $s = '!$%&?+*~#-_:.;,'; // specials
+
+ //use thre syllables...
+ for($i = 0; $i < 3; $i++) {
+ $data['password'] .= $c[auth_random(0, strlen($c) - 1)];
+ $data['password'] .= $v[auth_random(0, strlen($v) - 1)];
+ $data['password'] .= $a[auth_random(0, strlen($a) - 1)];
+ }
+ //... and add a nice number and special
+ $data['password'] .= $s[auth_random(0, strlen($s) - 1)].auth_random(10, 99);
+ }
+ $evt->advise_after();
+
+ return $data['password'];
+}
+
+/**
+ * Sends a password to the given user
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $user Login name of the user
+ * @param string $password The new password in clear text
+ * @return bool true on success
+ */
+function auth_sendPassword($user, $password) {
+ global $lang;
+ /* @var AuthPlugin $auth */
+ global $auth;
+ if(!$auth) return false;
+
+ $user = $auth->cleanUser($user);
+ $userinfo = $auth->getUserData($user, $requireGroups = false);
+
+ if(!$userinfo['mail']) return false;
+
+ $text = rawLocale('password');
+ $trep = array(
+ 'FULLNAME' => $userinfo['name'],
+ 'LOGIN' => $user,
+ 'PASSWORD' => $password
+ );
+
+ $mail = new Mailer();
+ $mail->to($mail->getCleanName($userinfo['name']).' <'.$userinfo['mail'].'>');
+ $mail->subject($lang['regpwmail']);
+ $mail->setBody($text, $trep);
+ return $mail->send();
+}
+
+/**
+ * Register a new user
+ *
+ * This registers a new user - Data is read directly from $_POST
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return bool true on success, false on any error
+ */
+function register() {
+ global $lang;
+ global $conf;
+ /* @var \dokuwiki\Extension\AuthPlugin $auth */
+ global $auth;
+ global $INPUT;
+
+ if(!$INPUT->post->bool('save')) return false;
+ if(!actionOK('register')) return false;
+
+ // gather input
+ $login = trim($auth->cleanUser($INPUT->post->str('login')));
+ $fullname = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $INPUT->post->str('fullname')));
+ $email = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $INPUT->post->str('email')));
+ $pass = $INPUT->post->str('pass');
+ $passchk = $INPUT->post->str('passchk');
+
+ if(empty($login) || empty($fullname) || empty($email)) {
+ msg($lang['regmissing'], -1);
+ return false;
+ }
+
+ if($conf['autopasswd']) {
+ $pass = auth_pwgen($login); // automatically generate password
+ } elseif(empty($pass) || empty($passchk)) {
+ msg($lang['regmissing'], -1); // complain about missing passwords
+ return false;
+ } elseif($pass != $passchk) {
+ msg($lang['regbadpass'], -1); // complain about misspelled passwords
+ return false;
+ }
+
+ //check mail
+ if(!mail_isvalid($email)) {
+ msg($lang['regbadmail'], -1);
+ return false;
+ }
+
+ //okay try to create the user
+ if(!$auth->triggerUserMod('create', array($login, $pass, $fullname, $email))) {
+ msg($lang['regfail'], -1);
+ return false;
+ }
+
+ // send notification about the new user
+ $subscription = new RegistrationSubscriptionSender();
+ $subscription->sendRegister($login, $fullname, $email);
+
+ // are we done?
+ if(!$conf['autopasswd']) {
+ msg($lang['regsuccess2'], 1);
+ return true;
+ }
+
+ // autogenerated password? then send password to user
+ if(auth_sendPassword($login, $pass)) {
+ msg($lang['regsuccess'], 1);
+ return true;
+ } else {
+ msg($lang['regmailfail'], -1);
+ return false;
+ }
+}
+
+/**
+ * Update user profile
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+function updateprofile() {
+ global $conf;
+ global $lang;
+ /* @var AuthPlugin $auth */
+ global $auth;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ if(!$INPUT->post->bool('save')) return false;
+ if(!checkSecurityToken()) return false;
+
+ if(!actionOK('profile')) {
+ msg($lang['profna'], -1);
+ return false;
+ }
+
+ $changes = array();
+ $changes['pass'] = $INPUT->post->str('newpass');
+ $changes['name'] = $INPUT->post->str('fullname');
+ $changes['mail'] = $INPUT->post->str('email');
+
+ // check misspelled passwords
+ if($changes['pass'] != $INPUT->post->str('passchk')) {
+ msg($lang['regbadpass'], -1);
+ return false;
+ }
+
+ // clean fullname and email
+ $changes['name'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $changes['name']));
+ $changes['mail'] = trim(preg_replace('/[\x00-\x1f:<>&%,;]+/', '', $changes['mail']));
+
+ // no empty name and email (except the backend doesn't support them)
+ if((empty($changes['name']) && $auth->canDo('modName')) ||
+ (empty($changes['mail']) && $auth->canDo('modMail'))
+ ) {
+ msg($lang['profnoempty'], -1);
+ return false;
+ }
+ if(!mail_isvalid($changes['mail']) && $auth->canDo('modMail')) {
+ msg($lang['regbadmail'], -1);
+ return false;
+ }
+
+ $changes = array_filter($changes);
+
+ // check for unavailable capabilities
+ if(!$auth->canDo('modName')) unset($changes['name']);
+ if(!$auth->canDo('modMail')) unset($changes['mail']);
+ if(!$auth->canDo('modPass')) unset($changes['pass']);
+
+ // anything to do?
+ if(!count($changes)) {
+ msg($lang['profnochange'], -1);
+ return false;
+ }
+
+ if($conf['profileconfirm']) {
+ if(!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) {
+ msg($lang['badpassconfirm'], -1);
+ return false;
+ }
+ }
+
+ if(!$auth->triggerUserMod('modify', array($INPUT->server->str('REMOTE_USER'), &$changes))) {
+ msg($lang['proffail'], -1);
+ return false;
+ }
+
+ if($changes['pass']) {
+ // update cookie and session with the changed data
+ list( /*user*/, $sticky, /*pass*/) = auth_getCookie();
+ $pass = auth_encrypt($changes['pass'], auth_cookiesalt(!$sticky, true));
+ auth_setCookie($INPUT->server->str('REMOTE_USER'), $pass, (bool) $sticky);
+ } else {
+ // make sure the session is writable
+ @session_start();
+ // invalidate session cache
+ $_SESSION[DOKU_COOKIE]['auth']['time'] = 0;
+ session_write_close();
+ }
+
+ return true;
+}
+
+/**
+ * Delete the current logged-in user
+ *
+ * @return bool true on success, false on any error
+ */
+function auth_deleteprofile(){
+ global $conf;
+ global $lang;
+ /* @var \dokuwiki\Extension\AuthPlugin $auth */
+ global $auth;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ if(!$INPUT->post->bool('delete')) return false;
+ if(!checkSecurityToken()) return false;
+
+ // action prevented or auth module disallows
+ if(!actionOK('profile_delete') || !$auth->canDo('delUser')) {
+ msg($lang['profnodelete'], -1);
+ return false;
+ }
+
+ if(!$INPUT->post->bool('confirm_delete')){
+ msg($lang['profconfdeletemissing'], -1);
+ return false;
+ }
+
+ if($conf['profileconfirm']) {
+ if(!$auth->checkPass($INPUT->server->str('REMOTE_USER'), $INPUT->post->str('oldpass'))) {
+ msg($lang['badpassconfirm'], -1);
+ return false;
+ }
+ }
+
+ $deleted = array();
+ $deleted[] = $INPUT->server->str('REMOTE_USER');
+ if($auth->triggerUserMod('delete', array($deleted))) {
+ // force and immediate logout including removing the sticky cookie
+ auth_logoff();
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * Send a new password
+ *
+ * This function handles both phases of the password reset:
+ *
+ * - handling the first request of password reset
+ * - validating the password reset auth token
+ *
+ * @author Benoit Chesneau <benoit@bchesneau.info>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return bool true on success, false on any error
+ */
+function act_resendpwd() {
+ global $lang;
+ global $conf;
+ /* @var AuthPlugin $auth */
+ global $auth;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ if(!actionOK('resendpwd')) {
+ msg($lang['resendna'], -1);
+ return false;
+ }
+
+ $token = preg_replace('/[^a-f0-9]+/', '', $INPUT->str('pwauth'));
+
+ if($token) {
+ // we're in token phase - get user info from token
+
+ $tfile = $conf['cachedir'].'/'.$token[0].'/'.$token.'.pwauth';
+ if(!file_exists($tfile)) {
+ msg($lang['resendpwdbadauth'], -1);
+ $INPUT->remove('pwauth');
+ return false;
+ }
+ // token is only valid for 3 days
+ if((time() - filemtime($tfile)) > (3 * 60 * 60 * 24)) {
+ msg($lang['resendpwdbadauth'], -1);
+ $INPUT->remove('pwauth');
+ @unlink($tfile);
+ return false;
+ }
+
+ $user = io_readfile($tfile);
+ $userinfo = $auth->getUserData($user, $requireGroups = false);
+ if(!$userinfo['mail']) {
+ msg($lang['resendpwdnouser'], -1);
+ return false;
+ }
+
+ if(!$conf['autopasswd']) { // we let the user choose a password
+ $pass = $INPUT->str('pass');
+
+ // password given correctly?
+ if(!$pass) return false;
+ if($pass != $INPUT->str('passchk')) {
+ msg($lang['regbadpass'], -1);
+ return false;
+ }
+
+ // change it
+ if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
+ msg($lang['proffail'], -1);
+ return false;
+ }
+
+ } else { // autogenerate the password and send by mail
+
+ $pass = auth_pwgen($user);
+ if(!$auth->triggerUserMod('modify', array($user, array('pass' => $pass)))) {
+ msg($lang['proffail'], -1);
+ return false;
+ }
+
+ if(auth_sendPassword($user, $pass)) {
+ msg($lang['resendpwdsuccess'], 1);
+ } else {
+ msg($lang['regmailfail'], -1);
+ }
+ }
+
+ @unlink($tfile);
+ return true;
+
+ } else {
+ // we're in request phase
+
+ if(!$INPUT->post->bool('save')) return false;
+
+ if(!$INPUT->post->str('login')) {
+ msg($lang['resendpwdmissing'], -1);
+ return false;
+ } else {
+ $user = trim($auth->cleanUser($INPUT->post->str('login')));
+ }
+
+ $userinfo = $auth->getUserData($user, $requireGroups = false);
+ if(!$userinfo['mail']) {
+ msg($lang['resendpwdnouser'], -1);
+ return false;
+ }
+
+ // generate auth token
+ $token = md5(auth_randombytes(16)); // random secret
+ $tfile = $conf['cachedir'].'/'.$token[0].'/'.$token.'.pwauth';
+ $url = wl('', array('do'=> 'resendpwd', 'pwauth'=> $token), true, '&');
+
+ io_saveFile($tfile, $user);
+
+ $text = rawLocale('pwconfirm');
+ $trep = array(
+ 'FULLNAME' => $userinfo['name'],
+ 'LOGIN' => $user,
+ 'CONFIRM' => $url
+ );
+
+ $mail = new Mailer();
+ $mail->to($userinfo['name'].' <'.$userinfo['mail'].'>');
+ $mail->subject($lang['regpwmail']);
+ $mail->setBody($text, $trep);
+ if($mail->send()) {
+ msg($lang['resendpwdconfirm'], 1);
+ } else {
+ msg($lang['regmailfail'], -1);
+ }
+ return true;
+ }
+ // never reached
+}
+
+/**
+ * Encrypts a password using the given method and salt
+ *
+ * If the selected method needs a salt and none was given, a random one
+ * is chosen.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $clear The clear text password
+ * @param string $method The hashing method
+ * @param string $salt A salt, null for random
+ * @return string The crypted password
+ */
+function auth_cryptPassword($clear, $method = '', $salt = null) {
+ global $conf;
+ if(empty($method)) $method = $conf['passcrypt'];
+
+ $pass = new PassHash();
+ $call = 'hash_'.$method;
+
+ if(!method_exists($pass, $call)) {
+ msg("Unsupported crypt method $method", -1);
+ return false;
+ }
+
+ return $pass->$call($clear, $salt);
+}
+
+/**
+ * Verifies a cleartext password against a crypted hash
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $clear The clear text password
+ * @param string $crypt The hash to compare with
+ * @return bool true if both match
+ */
+function auth_verifyPassword($clear, $crypt) {
+ $pass = new PassHash();
+ return $pass->verify_hash($clear, $crypt);
+}
+
+/**
+ * Set the authentication cookie and add user identification data to the session
+ *
+ * @param string $user username
+ * @param string $pass encrypted password
+ * @param bool $sticky whether or not the cookie will last beyond the session
+ * @return bool
+ */
+function auth_setCookie($user, $pass, $sticky) {
+ global $conf;
+ /* @var AuthPlugin $auth */
+ global $auth;
+ global $USERINFO;
+
+ if(!$auth) return false;
+ $USERINFO = $auth->getUserData($user);
+
+ // set cookie
+ $cookie = base64_encode($user).'|'.((int) $sticky).'|'.base64_encode($pass);
+ $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
+ $time = $sticky ? (time() + 60 * 60 * 24 * 365) : 0; //one year
+ setcookie(DOKU_COOKIE, $cookie, $time, $cookieDir, '', ($conf['securecookie'] && is_ssl()), true);
+
+ // set session
+ $_SESSION[DOKU_COOKIE]['auth']['user'] = $user;
+ $_SESSION[DOKU_COOKIE]['auth']['pass'] = sha1($pass);
+ $_SESSION[DOKU_COOKIE]['auth']['buid'] = auth_browseruid();
+ $_SESSION[DOKU_COOKIE]['auth']['info'] = $USERINFO;
+ $_SESSION[DOKU_COOKIE]['auth']['time'] = time();
+
+ return true;
+}
+
+/**
+ * Returns the user, (encrypted) password and sticky bit from cookie
+ *
+ * @returns array
+ */
+function auth_getCookie() {
+ if(!isset($_COOKIE[DOKU_COOKIE])) {
+ return array(null, null, null);
+ }
+ list($user, $sticky, $pass) = explode('|', $_COOKIE[DOKU_COOKIE], 3);
+ $sticky = (bool) $sticky;
+ $pass = base64_decode($pass);
+ $user = base64_decode($user);
+ return array($user, $sticky, $pass);
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/platform/www/inc/cache.php b/platform/www/inc/cache.php
new file mode 100644
index 0000000..b5793c2
--- /dev/null
+++ b/platform/www/inc/cache.php
@@ -0,0 +1,57 @@
+<?php
+// phpcs:ignoreFile
+use dokuwiki\Cache\CacheParser;
+use dokuwiki\Cache\CacheInstructions;
+use dokuwiki\Cache\CacheRenderer;
+use dokuwiki\Debug\DebugHelper;
+
+/**
+ * @deprecated since 2019-02-02 use \dokuwiki\Cache\Cache instead!
+ */
+class cache extends \dokuwiki\Cache\Cache
+{
+ public function __construct($key, $ext)
+ {
+ DebugHelper::dbgDeprecatedFunction(dokuwiki\Cache\Cache::class);
+ parent::__construct($key, $ext);
+ }
+}
+
+/**
+ * @deprecated since 2019-02-02 use \dokuwiki\Cache\CacheParser instead!
+ */
+class cache_parser extends \dokuwiki\Cache\CacheParser
+{
+
+ public function __construct($id, $file, $mode)
+ {
+ DebugHelper::dbgDeprecatedFunction(CacheParser::class);
+ parent::__construct($id, $file, $mode);
+ }
+
+}
+
+/**
+ * @deprecated since 2019-02-02 use \dokuwiki\Cache\CacheRenderer instead!
+ */
+class cache_renderer extends \dokuwiki\Cache\CacheRenderer
+{
+
+ public function __construct($id, $file, $mode)
+ {
+ DebugHelper::dbgDeprecatedFunction(CacheRenderer::class);
+ parent::__construct($id, $file, $mode);
+ }
+}
+
+/**
+ * @deprecated since 2019-02-02 use \dokuwiki\Cache\CacheInstructions instead!
+ */
+class cache_instructions extends \dokuwiki\Cache\CacheInstructions
+{
+ public function __construct($id, $file)
+ {
+ DebugHelper::dbgDeprecatedFunction(CacheInstructions::class);
+ parent::__construct($id, $file);
+ }
+}
diff --git a/platform/www/inc/changelog.php b/platform/www/inc/changelog.php
new file mode 100644
index 0000000..f02572e
--- /dev/null
+++ b/platform/www/inc/changelog.php
@@ -0,0 +1,403 @@
+<?php
+/**
+ * Changelog handling functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+/**
+ * parses a changelog line into it's components
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param string $line changelog line
+ * @return array|bool parsed line or false
+ */
+function parseChangelogLine($line) {
+ $line = rtrim($line, "\n");
+ $tmp = explode("\t", $line);
+ if ($tmp!==false && count($tmp)>1) {
+ $info = array();
+ $info['date'] = (int)$tmp[0]; // unix timestamp
+ $info['ip'] = $tmp[1]; // IPv4 address (127.0.0.1)
+ $info['type'] = $tmp[2]; // log line type
+ $info['id'] = $tmp[3]; // page id
+ $info['user'] = $tmp[4]; // user name
+ $info['sum'] = $tmp[5]; // edit summary (or action reason)
+ $info['extra'] = $tmp[6]; // extra data (varies by line type)
+ if(isset($tmp[7]) && $tmp[7] !== '') { //last item has line-end||
+ $info['sizechange'] = (int) $tmp[7];
+ } else {
+ $info['sizechange'] = null;
+ }
+ return $info;
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Add's an entry to the changelog and saves the metadata for the page
+ *
+ * @param int $date Timestamp of the change
+ * @param String $id Name of the affected page
+ * @param String $type Type of the change see DOKU_CHANGE_TYPE_*
+ * @param String $summary Summary of the change
+ * @param mixed $extra In case of a revert the revision (timestmp) of the reverted page
+ * @param array $flags Additional flags in a key value array.
+ * Available flags:
+ * - ExternalEdit - mark as an external edit.
+ * @param null|int $sizechange Change of filesize
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Esther Brunner <wikidesign@gmail.com>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function addLogEntry($date, $id, $type=DOKU_CHANGE_TYPE_EDIT, $summary='', $extra='', $flags=null, $sizechange = null){
+ global $conf, $INFO;
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ // check for special flags as keys
+ if (!is_array($flags)) { $flags = array(); }
+ $flagExternalEdit = isset($flags['ExternalEdit']);
+
+ $id = cleanid($id);
+ $file = wikiFN($id);
+ $created = @filectime($file);
+ $minor = ($type===DOKU_CHANGE_TYPE_MINOR_EDIT);
+ $wasRemoved = ($type===DOKU_CHANGE_TYPE_DELETE);
+
+ if(!$date) $date = time(); //use current time if none supplied
+ $remote = (!$flagExternalEdit)?clientIP(true):'127.0.0.1';
+ $user = (!$flagExternalEdit)?$INPUT->server->str('REMOTE_USER'):'';
+ if($sizechange === null) {
+ $sizechange = '';
+ } else {
+ $sizechange = (int) $sizechange;
+ }
+
+ $strip = array("\t", "\n");
+ $logline = array(
+ 'date' => $date,
+ 'ip' => $remote,
+ 'type' => str_replace($strip, '', $type),
+ 'id' => $id,
+ 'user' => $user,
+ 'sum' => \dokuwiki\Utf8\PhpString::substr(str_replace($strip, '', $summary), 0, 255),
+ 'extra' => str_replace($strip, '', $extra),
+ 'sizechange' => $sizechange
+ );
+
+ $wasCreated = ($type===DOKU_CHANGE_TYPE_CREATE);
+ $wasReverted = ($type===DOKU_CHANGE_TYPE_REVERT);
+ // update metadata
+ if (!$wasRemoved) {
+ $oldmeta = p_read_metadata($id);
+ $meta = array();
+ if (
+ $wasCreated && (
+ empty($oldmeta['persistent']['date']['created']) ||
+ $oldmeta['persistent']['date']['created'] === $created
+ )
+ ){
+ // newly created
+ $meta['date']['created'] = $created;
+ if ($user){
+ $meta['creator'] = isset($INFO) ? $INFO['userinfo']['name'] : null;
+ $meta['user'] = $user;
+ }
+ } elseif (($wasCreated || $wasReverted) && !empty($oldmeta['persistent']['date']['created'])) {
+ // re-created / restored
+ $meta['date']['created'] = $oldmeta['persistent']['date']['created'];
+ $meta['date']['modified'] = $created; // use the files ctime here
+ $meta['creator'] = $oldmeta['persistent']['creator'];
+ if ($user) $meta['contributor'][$user] = isset($INFO) ? $INFO['userinfo']['name'] : null;
+ } elseif (!$minor) { // non-minor modification
+ $meta['date']['modified'] = $date;
+ if ($user) $meta['contributor'][$user] = isset($INFO) ? $INFO['userinfo']['name'] : null;
+ }
+ $meta['last_change'] = $logline;
+ p_set_metadata($id, $meta);
+ }
+
+ // add changelog lines
+ $logline = implode("\t", $logline)."\n";
+ io_saveFile(metaFN($id,'.changes'),$logline,true); //page changelog
+ io_saveFile($conf['changelog'],$logline,true); //global changelog cache
+}
+
+/**
+ * Add's an entry to the media changelog
+ *
+ * @author Michael Hamann <michael@content-space.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Esther Brunner <wikidesign@gmail.com>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param int $date Timestamp of the change
+ * @param String $id Name of the affected page
+ * @param String $type Type of the change see DOKU_CHANGE_TYPE_*
+ * @param String $summary Summary of the change
+ * @param mixed $extra In case of a revert the revision (timestmp) of the reverted page
+ * @param array $flags Additional flags in a key value array.
+ * Available flags:
+ * - (none, so far)
+ * @param null|int $sizechange Change of filesize
+ */
+function addMediaLogEntry(
+ $date,
+ $id,
+ $type=DOKU_CHANGE_TYPE_EDIT,
+ $summary='',
+ $extra='',
+ $flags=null,
+ $sizechange = null)
+{
+ global $conf;
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ $id = cleanid($id);
+
+ if(!$date) $date = time(); //use current time if none supplied
+ $remote = clientIP(true);
+ $user = $INPUT->server->str('REMOTE_USER');
+ if($sizechange === null) {
+ $sizechange = '';
+ } else {
+ $sizechange = (int) $sizechange;
+ }
+
+ $strip = array("\t", "\n");
+ $logline = array(
+ 'date' => $date,
+ 'ip' => $remote,
+ 'type' => str_replace($strip, '', $type),
+ 'id' => $id,
+ 'user' => $user,
+ 'sum' => \dokuwiki\Utf8\PhpString::substr(str_replace($strip, '', $summary), 0, 255),
+ 'extra' => str_replace($strip, '', $extra),
+ 'sizechange' => $sizechange
+ );
+
+ // add changelog lines
+ $logline = implode("\t", $logline)."\n";
+ io_saveFile($conf['media_changelog'],$logline,true); //global media changelog cache
+ io_saveFile(mediaMetaFN($id,'.changes'),$logline,true); //media file's changelog
+}
+
+/**
+ * returns an array of recently changed files using the
+ * changelog
+ *
+ * The following constants can be used to control which changes are
+ * included. Add them together as needed.
+ *
+ * RECENTS_SKIP_DELETED - don't include deleted pages
+ * RECENTS_SKIP_MINORS - don't include minor changes
+ * RECENTS_ONLY_CREATION - only include new created pages and media
+ * RECENTS_SKIP_SUBSPACES - don't include subspaces
+ * RECENTS_MEDIA_CHANGES - return media changes instead of page changes
+ * RECENTS_MEDIA_PAGES_MIXED - return both media changes and page changes
+ *
+ * @param int $first number of first entry returned (for paginating
+ * @param int $num return $num entries
+ * @param string $ns restrict to given namespace
+ * @param int $flags see above
+ * @return array recently changed files
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function getRecents($first,$num,$ns='',$flags=0){
+ global $conf;
+ $recent = array();
+ $count = 0;
+
+ if(!$num)
+ return $recent;
+
+ // read all recent changes. (kept short)
+ if ($flags & RECENTS_MEDIA_CHANGES) {
+ $lines = @file($conf['media_changelog']) ?: [];
+ } else {
+ $lines = @file($conf['changelog']) ?: [];
+ }
+ if (!is_array($lines)) {
+ $lines = array();
+ }
+ $lines_position = count($lines)-1;
+ $media_lines_position = 0;
+ $media_lines = array();
+
+ if ($flags & RECENTS_MEDIA_PAGES_MIXED) {
+ $media_lines = @file($conf['media_changelog']) ?: [];
+ if (!is_array($media_lines)) {
+ $media_lines = array();
+ }
+ $media_lines_position = count($media_lines)-1;
+ }
+
+ $seen = array(); // caches seen lines, _handleRecent() skips them
+
+ // handle lines
+ while ($lines_position >= 0 || (($flags & RECENTS_MEDIA_PAGES_MIXED) && $media_lines_position >=0)) {
+ if (empty($rec) && $lines_position >= 0) {
+ $rec = _handleRecent(@$lines[$lines_position], $ns, $flags, $seen);
+ if (!$rec) {
+ $lines_position --;
+ continue;
+ }
+ }
+ if (($flags & RECENTS_MEDIA_PAGES_MIXED) && empty($media_rec) && $media_lines_position >= 0) {
+ $media_rec = _handleRecent(
+ @$media_lines[$media_lines_position],
+ $ns,
+ $flags | RECENTS_MEDIA_CHANGES,
+ $seen
+ );
+ if (!$media_rec) {
+ $media_lines_position --;
+ continue;
+ }
+ }
+ if (($flags & RECENTS_MEDIA_PAGES_MIXED) && @$media_rec['date'] >= @$rec['date']) {
+ $media_lines_position--;
+ $x = $media_rec;
+ $x['media'] = true;
+ $media_rec = false;
+ } else {
+ $lines_position--;
+ $x = $rec;
+ if ($flags & RECENTS_MEDIA_CHANGES) $x['media'] = true;
+ $rec = false;
+ }
+ if(--$first >= 0) continue; // skip first entries
+ $recent[] = $x;
+ $count++;
+ // break when we have enough entries
+ if($count >= $num){ break; }
+ }
+ return $recent;
+}
+
+/**
+ * returns an array of files changed since a given time using the
+ * changelog
+ *
+ * The following constants can be used to control which changes are
+ * included. Add them together as needed.
+ *
+ * RECENTS_SKIP_DELETED - don't include deleted pages
+ * RECENTS_SKIP_MINORS - don't include minor changes
+ * RECENTS_ONLY_CREATION - only include new created pages and media
+ * RECENTS_SKIP_SUBSPACES - don't include subspaces
+ * RECENTS_MEDIA_CHANGES - return media changes instead of page changes
+ *
+ * @param int $from date of the oldest entry to return
+ * @param int $to date of the newest entry to return (for pagination, optional)
+ * @param string $ns restrict to given namespace (optional)
+ * @param int $flags see above (optional)
+ * @return array of files
+ *
+ * @author Michael Hamann <michael@content-space.de>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function getRecentsSince($from,$to=null,$ns='',$flags=0){
+ global $conf;
+ $recent = array();
+
+ if($to && $to < $from)
+ return $recent;
+
+ // read all recent changes. (kept short)
+ if ($flags & RECENTS_MEDIA_CHANGES) {
+ $lines = @file($conf['media_changelog']);
+ } else {
+ $lines = @file($conf['changelog']);
+ }
+ if(!$lines) return $recent;
+
+ // we start searching at the end of the list
+ $lines = array_reverse($lines);
+
+ // handle lines
+ $seen = array(); // caches seen lines, _handleRecent() skips them
+
+ foreach($lines as $line){
+ $rec = _handleRecent($line, $ns, $flags, $seen);
+ if($rec !== false) {
+ if ($rec['date'] >= $from) {
+ if (!$to || $rec['date'] <= $to) {
+ $recent[] = $rec;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ return array_reverse($recent);
+}
+
+/**
+ * Internal function used by getRecents
+ *
+ * don't call directly
+ *
+ * @see getRecents()
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param string $line changelog line
+ * @param string $ns restrict to given namespace
+ * @param int $flags flags to control which changes are included
+ * @param array $seen listing of seen pages
+ * @return array|bool false or array with info about a change
+ */
+function _handleRecent($line,$ns,$flags,&$seen){
+ if(empty($line)) return false; //skip empty lines
+
+ // split the line into parts
+ $recent = parseChangelogLine($line);
+ if ($recent===false) { return false; }
+
+ // skip seen ones
+ if(isset($seen[$recent['id']])) return false;
+
+ // skip changes, of only new items are requested
+ if($recent['type']!==DOKU_CHANGE_TYPE_CREATE && ($flags & RECENTS_ONLY_CREATION)) return false;
+
+ // skip minors
+ if($recent['type']===DOKU_CHANGE_TYPE_MINOR_EDIT && ($flags & RECENTS_SKIP_MINORS)) return false;
+
+ // remember in seen to skip additional sights
+ $seen[$recent['id']] = 1;
+
+ // check if it's a hidden page
+ if(isHiddenPage($recent['id'])) return false;
+
+ // filter namespace
+ if (($ns) && (strpos($recent['id'],$ns.':') !== 0)) return false;
+
+ // exclude subnamespaces
+ if (($flags & RECENTS_SKIP_SUBSPACES) && (getNS($recent['id']) != $ns)) return false;
+
+ // check ACL
+ if ($flags & RECENTS_MEDIA_CHANGES) {
+ $recent['perms'] = auth_quickaclcheck(getNS($recent['id']).':*');
+ } else {
+ $recent['perms'] = auth_quickaclcheck($recent['id']);
+ }
+ if ($recent['perms'] < AUTH_READ) return false;
+
+ // check existance
+ if($flags & RECENTS_SKIP_DELETED){
+ $fn = (($flags & RECENTS_MEDIA_CHANGES) ? mediaFN($recent['id']) : wikiFN($recent['id']));
+ if(!file_exists($fn)) return false;
+ }
+
+ return $recent;
+}
diff --git a/platform/www/inc/cli.php b/platform/www/inc/cli.php
new file mode 100644
index 0000000..cb4dabf
--- /dev/null
+++ b/platform/www/inc/cli.php
@@ -0,0 +1,656 @@
+<?php
+
+/**
+ * Class DokuCLI
+ *
+ * All DokuWiki commandline scripts should inherit from this class and implement the abstract methods.
+ *
+ * @deprecated 2017-11-10
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+abstract class DokuCLI {
+ /** @var string the executed script itself */
+ protected $bin;
+ /** @var DokuCLI_Options the option parser */
+ protected $options;
+ /** @var DokuCLI_Colors */
+ public $colors;
+
+ /**
+ * constructor
+ *
+ * Initialize the arguments, set up helper classes and set up the CLI environment
+ */
+ public function __construct() {
+ set_exception_handler(array($this, 'fatal'));
+
+ $this->options = new DokuCLI_Options();
+ $this->colors = new DokuCLI_Colors();
+
+ dbg_deprecated('use \splitbrain\phpcli\CLI instead');
+ $this->error('DokuCLI is deprecated, use \splitbrain\phpcli\CLI instead.');
+ }
+
+ /**
+ * Register options and arguments on the given $options object
+ *
+ * @param DokuCLI_Options $options
+ * @return void
+ */
+ abstract protected function setup(DokuCLI_Options $options);
+
+ /**
+ * Your main program
+ *
+ * Arguments and options have been parsed when this is run
+ *
+ * @param DokuCLI_Options $options
+ * @return void
+ */
+ abstract protected function main(DokuCLI_Options $options);
+
+ /**
+ * Execute the CLI program
+ *
+ * Executes the setup() routine, adds default options, initiate the options parsing and argument checking
+ * and finally executes main()
+ */
+ public function run() {
+ if('cli' != php_sapi_name()) throw new DokuCLI_Exception('This has to be run from the command line');
+
+ // setup
+ $this->setup($this->options);
+ $this->options->registerOption(
+ 'no-colors',
+ 'Do not use any colors in output. Useful when piping output to other tools or files.'
+ );
+ $this->options->registerOption(
+ 'help',
+ 'Display this help screen and exit immediately.',
+ 'h'
+ );
+
+ // parse
+ $this->options->parseOptions();
+
+ // handle defaults
+ if($this->options->getOpt('no-colors')) {
+ $this->colors->disable();
+ }
+ if($this->options->getOpt('help')) {
+ echo $this->options->help();
+ exit(0);
+ }
+
+ // check arguments
+ $this->options->checkArguments();
+
+ // execute
+ $this->main($this->options);
+
+ exit(0);
+ }
+
+ /**
+ * Exits the program on a fatal error
+ *
+ * @param Exception|string $error either an exception or an error message
+ */
+ public function fatal($error) {
+ $code = 0;
+ if(is_object($error) && is_a($error, 'Exception')) {
+ /** @var Exception $error */
+ $code = $error->getCode();
+ $error = $error->getMessage();
+ }
+ if(!$code) $code = DokuCLI_Exception::E_ANY;
+
+ $this->error($error);
+ exit($code);
+ }
+
+ /**
+ * Print an error message
+ *
+ * @param string $string
+ */
+ public function error($string) {
+ $this->colors->ptln("E: $string", 'red', STDERR);
+ }
+
+ /**
+ * Print a success message
+ *
+ * @param string $string
+ */
+ public function success($string) {
+ $this->colors->ptln("S: $string", 'green', STDERR);
+ }
+
+ /**
+ * Print an info message
+ *
+ * @param string $string
+ */
+ public function info($string) {
+ $this->colors->ptln("I: $string", 'cyan', STDERR);
+ }
+
+}
+
+/**
+ * Class DokuCLI_Colors
+ *
+ * Handles color output on (Linux) terminals
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class DokuCLI_Colors {
+ /** @var array known color names */
+ protected $colors = array(
+ 'reset' => "\33[0m",
+ 'black' => "\33[0;30m",
+ 'darkgray' => "\33[1;30m",
+ 'blue' => "\33[0;34m",
+ 'lightblue' => "\33[1;34m",
+ 'green' => "\33[0;32m",
+ 'lightgreen' => "\33[1;32m",
+ 'cyan' => "\33[0;36m",
+ 'lightcyan' => "\33[1;36m",
+ 'red' => "\33[0;31m",
+ 'lightred' => "\33[1;31m",
+ 'purple' => "\33[0;35m",
+ 'lightpurple' => "\33[1;35m",
+ 'brown' => "\33[0;33m",
+ 'yellow' => "\33[1;33m",
+ 'lightgray' => "\33[0;37m",
+ 'white' => "\33[1;37m",
+ );
+
+ /** @var bool should colors be used? */
+ protected $enabled = true;
+
+ /**
+ * Constructor
+ *
+ * Tries to disable colors for non-terminals
+ */
+ public function __construct() {
+ if(function_exists('posix_isatty') && !posix_isatty(STDOUT)) {
+ $this->enabled = false;
+ return;
+ }
+ if(!getenv('TERM')) {
+ $this->enabled = false;
+ return;
+ }
+ }
+
+ /**
+ * enable color output
+ */
+ public function enable() {
+ $this->enabled = true;
+ }
+
+ /**
+ * disable color output
+ */
+ public function disable() {
+ $this->enabled = false;
+ }
+
+ /**
+ * Convenience function to print a line in a given color
+ *
+ * @param string $line
+ * @param string $color
+ * @param resource $channel
+ */
+ public function ptln($line, $color, $channel = STDOUT) {
+ $this->set($color);
+ fwrite($channel, rtrim($line)."\n");
+ $this->reset();
+ }
+
+ /**
+ * Set the given color for consecutive output
+ *
+ * @param string $color one of the supported color names
+ * @throws DokuCLI_Exception
+ */
+ public function set($color) {
+ if(!$this->enabled) return;
+ if(!isset($this->colors[$color])) throw new DokuCLI_Exception("No such color $color");
+ echo $this->colors[$color];
+ }
+
+ /**
+ * reset the terminal color
+ */
+ public function reset() {
+ $this->set('reset');
+ }
+}
+
+/**
+ * Class DokuCLI_Options
+ *
+ * Parses command line options passed to the CLI script. Allows CLI scripts to easily register all accepted options and
+ * commands and even generates a help text from this setup.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class DokuCLI_Options {
+ /** @var array keeps the list of options to parse */
+ protected $setup;
+
+ /** @var array store parsed options */
+ protected $options = array();
+
+ /** @var string current parsed command if any */
+ protected $command = '';
+
+ /** @var array passed non-option arguments */
+ public $args = array();
+
+ /** @var string the executed script */
+ protected $bin;
+
+ /**
+ * Constructor
+ */
+ public function __construct() {
+ $this->setup = array(
+ '' => array(
+ 'opts' => array(),
+ 'args' => array(),
+ 'help' => ''
+ )
+ ); // default command
+
+ $this->args = $this->readPHPArgv();
+ $this->bin = basename(array_shift($this->args));
+
+ $this->options = array();
+ }
+
+ /**
+ * Sets the help text for the tool itself
+ *
+ * @param string $help
+ */
+ public function setHelp($help) {
+ $this->setup['']['help'] = $help;
+ }
+
+ /**
+ * Register the names of arguments for help generation and number checking
+ *
+ * This has to be called in the order arguments are expected
+ *
+ * @param string $arg argument name (just for help)
+ * @param string $help help text
+ * @param bool $required is this a required argument
+ * @param string $command if theses apply to a sub command only
+ * @throws DokuCLI_Exception
+ */
+ public function registerArgument($arg, $help, $required = true, $command = '') {
+ if(!isset($this->setup[$command])) throw new DokuCLI_Exception("Command $command not registered");
+
+ $this->setup[$command]['args'][] = array(
+ 'name' => $arg,
+ 'help' => $help,
+ 'required' => $required
+ );
+ }
+
+ /**
+ * This registers a sub command
+ *
+ * Sub commands have their own options and use their own function (not main()).
+ *
+ * @param string $command
+ * @param string $help
+ * @throws DokuCLI_Exception
+ */
+ public function registerCommand($command, $help) {
+ if(isset($this->setup[$command])) throw new DokuCLI_Exception("Command $command already registered");
+
+ $this->setup[$command] = array(
+ 'opts' => array(),
+ 'args' => array(),
+ 'help' => $help
+ );
+
+ }
+
+ /**
+ * Register an option for option parsing and help generation
+ *
+ * @param string $long multi character option (specified with --)
+ * @param string $help help text for this option
+ * @param string|null $short one character option (specified with -)
+ * @param bool|string $needsarg does this option require an argument? give it a name here
+ * @param string $command what command does this option apply to
+ * @throws DokuCLI_Exception
+ */
+ public function registerOption($long, $help, $short = null, $needsarg = false, $command = '') {
+ if(!isset($this->setup[$command])) throw new DokuCLI_Exception("Command $command not registered");
+
+ $this->setup[$command]['opts'][$long] = array(
+ 'needsarg' => $needsarg,
+ 'help' => $help,
+ 'short' => $short
+ );
+
+ if($short) {
+ if(strlen($short) > 1) throw new DokuCLI_Exception("Short options should be exactly one ASCII character");
+
+ $this->setup[$command]['short'][$short] = $long;
+ }
+ }
+
+ /**
+ * Checks the actual number of arguments against the required number
+ *
+ * Throws an exception if arguments are missing. Called from parseOptions()
+ *
+ * @throws DokuCLI_Exception
+ */
+ public function checkArguments() {
+ $argc = count($this->args);
+
+ $req = 0;
+ foreach($this->setup[$this->command]['args'] as $arg) {
+ if(!$arg['required']) break; // last required arguments seen
+ $req++;
+ }
+
+ if($req > $argc) throw new DokuCLI_Exception("Not enough arguments", DokuCLI_Exception::E_OPT_ARG_REQUIRED);
+ }
+
+ /**
+ * Parses the given arguments for known options and command
+ *
+ * The given $args array should NOT contain the executed file as first item anymore! The $args
+ * array is stripped from any options and possible command. All found otions can be accessed via the
+ * getOpt() function
+ *
+ * Note that command options will overwrite any global options with the same name
+ *
+ * @throws DokuCLI_Exception
+ */
+ public function parseOptions() {
+ $non_opts = array();
+
+ $argc = count($this->args);
+ for($i = 0; $i < $argc; $i++) {
+ $arg = $this->args[$i];
+
+ // The special element '--' means explicit end of options. Treat the rest of the arguments as non-options
+ // and end the loop.
+ if($arg == '--') {
+ $non_opts = array_merge($non_opts, array_slice($this->args, $i + 1));
+ break;
+ }
+
+ // '-' is stdin - a normal argument
+ if($arg == '-') {
+ $non_opts = array_merge($non_opts, array_slice($this->args, $i));
+ break;
+ }
+
+ // first non-option
+ if($arg[0] != '-') {
+ $non_opts = array_merge($non_opts, array_slice($this->args, $i));
+ break;
+ }
+
+ // long option
+ if(strlen($arg) > 1 && $arg[1] == '-') {
+ list($opt, $val) = explode('=', substr($arg, 2), 2);
+
+ if(!isset($this->setup[$this->command]['opts'][$opt])) {
+ throw new DokuCLI_Exception("No such option $arg", DokuCLI_Exception::E_UNKNOWN_OPT);
+ }
+
+ // argument required?
+ if($this->setup[$this->command]['opts'][$opt]['needsarg']) {
+ if(is_null($val) && $i + 1 < $argc && !preg_match('/^--?[\w]/', $this->args[$i + 1])) {
+ $val = $this->args[++$i];
+ }
+ if(is_null($val)) {
+ throw new DokuCLI_Exception("Option $arg requires an argument", DokuCLI_Exception::E_OPT_ARG_REQUIRED);
+ }
+ $this->options[$opt] = $val;
+ } else {
+ $this->options[$opt] = true;
+ }
+
+ continue;
+ }
+
+ // short option
+ $opt = substr($arg, 1);
+ if(!isset($this->setup[$this->command]['short'][$opt])) {
+ throw new DokuCLI_Exception("No such option $arg", DokuCLI_Exception::E_UNKNOWN_OPT);
+ } else {
+ $opt = $this->setup[$this->command]['short'][$opt]; // store it under long name
+ }
+
+ // argument required?
+ if($this->setup[$this->command]['opts'][$opt]['needsarg']) {
+ $val = null;
+ if($i + 1 < $argc && !preg_match('/^--?[\w]/', $this->args[$i + 1])) {
+ $val = $this->args[++$i];
+ }
+ if(is_null($val)) {
+ throw new DokuCLI_Exception("Option $arg requires an argument", DokuCLI_Exception::E_OPT_ARG_REQUIRED);
+ }
+ $this->options[$opt] = $val;
+ } else {
+ $this->options[$opt] = true;
+ }
+ }
+
+ // parsing is now done, update args array
+ $this->args = $non_opts;
+
+ // if not done yet, check if first argument is a command and reexecute argument parsing if it is
+ if(!$this->command && $this->args && isset($this->setup[$this->args[0]])) {
+ // it is a command!
+ $this->command = array_shift($this->args);
+ $this->parseOptions(); // second pass
+ }
+ }
+
+ /**
+ * Get the value of the given option
+ *
+ * Please note that all options are accessed by their long option names regardless of how they were
+ * specified on commandline.
+ *
+ * Can only be used after parseOptions() has been run
+ *
+ * @param string $option
+ * @param bool|string $default what to return if the option was not set
+ * @return bool|string
+ */
+ public function getOpt($option, $default = false) {
+ if(isset($this->options[$option])) return $this->options[$option];
+ return $default;
+ }
+
+ /**
+ * Return the found command if any
+ *
+ * @return string
+ */
+ public function getCmd() {
+ return $this->command;
+ }
+
+ /**
+ * Builds a help screen from the available options. You may want to call it from -h or on error
+ *
+ * @return string
+ */
+ public function help() {
+ $text = '';
+
+ $hascommands = (count($this->setup) > 1);
+ foreach($this->setup as $command => $config) {
+ $hasopts = (bool) $this->setup[$command]['opts'];
+ $hasargs = (bool) $this->setup[$command]['args'];
+
+ if(!$command) {
+ $text .= 'USAGE: '.$this->bin;
+ } else {
+ $text .= "\n$command";
+ }
+
+ if($hasopts) $text .= ' <OPTIONS>';
+
+ foreach($this->setup[$command]['args'] as $arg) {
+ if($arg['required']) {
+ $text .= ' <'.$arg['name'].'>';
+ } else {
+ $text .= ' [<'.$arg['name'].'>]';
+ }
+ }
+ $text .= "\n";
+
+ if($this->setup[$command]['help']) {
+ $text .= "\n";
+ $text .= $this->tableFormat(
+ array(2, 72),
+ array('', $this->setup[$command]['help']."\n")
+ );
+ }
+
+ if($hasopts) {
+ $text .= "\n OPTIONS\n\n";
+ foreach($this->setup[$command]['opts'] as $long => $opt) {
+
+ $name = '';
+ if($opt['short']) {
+ $name .= '-'.$opt['short'];
+ if($opt['needsarg']) $name .= ' <'.$opt['needsarg'].'>';
+ $name .= ', ';
+ }
+ $name .= "--$long";
+ if($opt['needsarg']) $name .= ' <'.$opt['needsarg'].'>';
+
+ $text .= $this->tableFormat(
+ array(2, 20, 52),
+ array('', $name, $opt['help'])
+ );
+ $text .= "\n";
+ }
+ }
+
+ if($hasargs) {
+ $text .= "\n";
+ foreach($this->setup[$command]['args'] as $arg) {
+ $name = '<'.$arg['name'].'>';
+
+ $text .= $this->tableFormat(
+ array(2, 20, 52),
+ array('', $name, $arg['help'])
+ );
+ }
+ }
+
+ if($command == '' && $hascommands) {
+ $text .= "\nThis tool accepts a command as first parameter as outlined below:\n";
+ }
+ }
+
+ return $text;
+ }
+
+ /**
+ * Safely read the $argv PHP array across different PHP configurations.
+ * Will take care on register_globals and register_argc_argv ini directives
+ *
+ * @throws DokuCLI_Exception
+ * @return array the $argv PHP array or PEAR error if not registered
+ */
+ private function readPHPArgv() {
+ global $argv;
+ if(!is_array($argv)) {
+ if(!@is_array($_SERVER['argv'])) {
+ if(!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
+ throw new DokuCLI_Exception(
+ "Could not read cmd args (register_argc_argv=Off?)",
+ DOKU_CLI_OPTS_ARG_READ
+ );
+ }
+ return $GLOBALS['HTTP_SERVER_VARS']['argv'];
+ }
+ return $_SERVER['argv'];
+ }
+ return $argv;
+ }
+
+ /**
+ * Displays text in multiple word wrapped columns
+ *
+ * @param int[] $widths list of column widths (in characters)
+ * @param string[] $texts list of texts for each column
+ * @return string
+ */
+ private function tableFormat($widths, $texts) {
+ $wrapped = array();
+ $maxlen = 0;
+
+ foreach($widths as $col => $width) {
+ $wrapped[$col] = explode("\n", wordwrap($texts[$col], $width - 1, "\n", true)); // -1 char border
+ $len = count($wrapped[$col]);
+ if($len > $maxlen) $maxlen = $len;
+
+ }
+
+ $out = '';
+ for($i = 0; $i < $maxlen; $i++) {
+ foreach($widths as $col => $width) {
+ if(isset($wrapped[$col][$i])) {
+ $val = $wrapped[$col][$i];
+ } else {
+ $val = '';
+ }
+ $out .= sprintf('%-'.$width.'s', $val);
+ }
+ $out .= "\n";
+ }
+ return $out;
+ }
+}
+
+/**
+ * Class DokuCLI_Exception
+ *
+ * The code is used as exit code for the CLI tool. This should probably be extended. Many cases just fall back to the
+ * E_ANY code.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class DokuCLI_Exception extends Exception {
+ const E_ANY = -1; // no error code specified
+ const E_UNKNOWN_OPT = 1; //Unrecognized option
+ const E_OPT_ARG_REQUIRED = 2; //Option requires argument
+ const E_OPT_ARG_DENIED = 3; //Option not allowed argument
+ const E_OPT_ABIGUOUS = 4; //Option abiguous
+ const E_ARG_READ = 5; //Could not read argv
+
+ /**
+ * @param string $message The Exception message to throw.
+ * @param int $code The Exception code
+ * @param Exception $previous The previous exception used for the exception chaining.
+ */
+ public function __construct($message = "", $code = 0, Exception $previous = null) {
+ if(!$code) $code = DokuCLI_Exception::E_ANY;
+ parent::__construct($message, $code, $previous);
+ }
+}
diff --git a/platform/www/inc/common.php b/platform/www/inc/common.php
new file mode 100644
index 0000000..2910358
--- /dev/null
+++ b/platform/www/inc/common.php
@@ -0,0 +1,2132 @@
+<?php
+/**
+ * Common DokuWiki functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Cache\CacheInstructions;
+use dokuwiki\Cache\CacheRenderer;
+use dokuwiki\ChangeLog\PageChangeLog;
+use dokuwiki\Subscriptions\PageSubscriptionSender;
+use dokuwiki\Subscriptions\SubscriberManager;
+use dokuwiki\Extension\AuthPlugin;
+use dokuwiki\Extension\Event;
+
+/**
+ * Wrapper around htmlspecialchars()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see htmlspecialchars()
+ *
+ * @param string $string the string being converted
+ * @return string converted string
+ */
+function hsc($string) {
+ return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
+}
+
+/**
+ * Checks if the given input is blank
+ *
+ * This is similar to empty() but will return false for "0".
+ *
+ * Please note: when you pass uninitialized variables, they will implicitly be created
+ * with a NULL value without warning.
+ *
+ * To avoid this it's recommended to guard the call with isset like this:
+ *
+ * (isset($foo) && !blank($foo))
+ * (!isset($foo) || blank($foo))
+ *
+ * @param $in
+ * @param bool $trim Consider a string of whitespace to be blank
+ * @return bool
+ */
+function blank(&$in, $trim = false) {
+ if(is_null($in)) return true;
+ if(is_array($in)) return empty($in);
+ if($in === "\0") return true;
+ if($trim && trim($in) === '') return true;
+ if(strlen($in) > 0) return false;
+ return empty($in);
+}
+
+/**
+ * print a newline terminated string
+ *
+ * You can give an indention as optional parameter
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $string line of text
+ * @param int $indent number of spaces indention
+ */
+function ptln($string, $indent = 0) {
+ echo str_repeat(' ', $indent)."$string\n";
+}
+
+/**
+ * strips control characters (<32) from the given string
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $string being stripped
+ * @return string
+ */
+function stripctl($string) {
+ return preg_replace('/[\x00-\x1F]+/s', '', $string);
+}
+
+/**
+ * Return a secret token to be used for CSRF attack prevention
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @link http://en.wikipedia.org/wiki/Cross-site_request_forgery
+ * @link http://christ1an.blogspot.com/2007/04/preventing-csrf-efficiently.html
+ *
+ * @return string
+ */
+function getSecurityToken() {
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ $user = $INPUT->server->str('REMOTE_USER');
+ $session = session_id();
+
+ // CSRF checks are only for logged in users - do not generate for anonymous
+ if(trim($user) == '' || trim($session) == '') return '';
+ return \dokuwiki\PassHash::hmac('md5', $session.$user, auth_cookiesalt());
+}
+
+/**
+ * Check the secret CSRF token
+ *
+ * @param null|string $token security token or null to read it from request variable
+ * @return bool success if the token matched
+ */
+function checkSecurityToken($token = null) {
+ /** @var Input $INPUT */
+ global $INPUT;
+ if(!$INPUT->server->str('REMOTE_USER')) return true; // no logged in user, no need for a check
+
+ if(is_null($token)) $token = $INPUT->str('sectok');
+ if(getSecurityToken() != $token) {
+ msg('Security Token did not match. Possible CSRF attack.', -1);
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Print a hidden form field with a secret CSRF token
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param bool $print if true print the field, otherwise html of the field is returned
+ * @return string html of hidden form field
+ */
+function formSecurityToken($print = true) {
+ $ret = '<div class="no"><input type="hidden" name="sectok" value="'.getSecurityToken().'" /></div>'."\n";
+ if($print) echo $ret;
+ return $ret;
+}
+
+/**
+ * Determine basic information for a request of $id
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $id pageid
+ * @param bool $htmlClient add info about whether is mobile browser
+ * @return array with info for a request of $id
+ *
+ */
+function basicinfo($id, $htmlClient=true){
+ global $USERINFO;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ // set info about manager/admin status.
+ $info = array();
+ $info['isadmin'] = false;
+ $info['ismanager'] = false;
+ if($INPUT->server->has('REMOTE_USER')) {
+ $info['userinfo'] = $USERINFO;
+ $info['perm'] = auth_quickaclcheck($id);
+ $info['client'] = $INPUT->server->str('REMOTE_USER');
+
+ if($info['perm'] == AUTH_ADMIN) {
+ $info['isadmin'] = true;
+ $info['ismanager'] = true;
+ } elseif(auth_ismanager()) {
+ $info['ismanager'] = true;
+ }
+
+ // if some outside auth were used only REMOTE_USER is set
+ if(!$info['userinfo']['name']) {
+ $info['userinfo']['name'] = $INPUT->server->str('REMOTE_USER');
+ }
+
+ } else {
+ $info['perm'] = auth_aclcheck($id, '', null);
+ $info['client'] = clientIP(true);
+ }
+
+ $info['namespace'] = getNS($id);
+
+ // mobile detection
+ if ($htmlClient) {
+ $info['ismobile'] = clientismobile();
+ }
+
+ return $info;
+ }
+
+/**
+ * Return info about the current document as associative
+ * array.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return array with info about current document
+ */
+function pageinfo() {
+ global $ID;
+ global $REV;
+ global $RANGE;
+ global $lang;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ $info = basicinfo($ID);
+
+ // include ID & REV not redundant, as some parts of DokuWiki may temporarily change $ID, e.g. p_wiki_xhtml
+ // FIXME ... perhaps it would be better to ensure the temporary changes weren't necessary
+ $info['id'] = $ID;
+ $info['rev'] = $REV;
+
+ $subManager = new SubscriberManager();
+ $info['subscribed'] = $subManager->userSubscription();
+
+ $info['locked'] = checklock($ID);
+ $info['filepath'] = wikiFN($ID);
+ $info['exists'] = file_exists($info['filepath']);
+ $info['currentrev'] = @filemtime($info['filepath']);
+ if($REV) {
+ //check if current revision was meant
+ if($info['exists'] && ($info['currentrev'] == $REV)) {
+ $REV = '';
+ } elseif($RANGE) {
+ //section editing does not work with old revisions!
+ $REV = '';
+ $RANGE = '';
+ msg($lang['nosecedit'], 0);
+ } else {
+ //really use old revision
+ $info['filepath'] = wikiFN($ID, $REV);
+ $info['exists'] = file_exists($info['filepath']);
+ }
+ }
+ $info['rev'] = $REV;
+ if($info['exists']) {
+ $info['writable'] = (is_writable($info['filepath']) &&
+ ($info['perm'] >= AUTH_EDIT));
+ } else {
+ $info['writable'] = ($info['perm'] >= AUTH_CREATE);
+ }
+ $info['editable'] = ($info['writable'] && empty($info['locked']));
+ $info['lastmod'] = @filemtime($info['filepath']);
+
+ //load page meta data
+ $info['meta'] = p_get_metadata($ID);
+
+ //who's the editor
+ $pagelog = new PageChangeLog($ID, 1024);
+ if($REV) {
+ $revinfo = $pagelog->getRevisionInfo($REV);
+ } else {
+ if(!empty($info['meta']['last_change']) && is_array($info['meta']['last_change'])) {
+ $revinfo = $info['meta']['last_change'];
+ } else {
+ $revinfo = $pagelog->getRevisionInfo($info['lastmod']);
+ // cache most recent changelog line in metadata if missing and still valid
+ if($revinfo !== false) {
+ $info['meta']['last_change'] = $revinfo;
+ p_set_metadata($ID, array('last_change' => $revinfo));
+ }
+ }
+ }
+ //and check for an external edit
+ if($revinfo !== false && $revinfo['date'] != $info['lastmod']) {
+ // cached changelog line no longer valid
+ $revinfo = false;
+ $info['meta']['last_change'] = $revinfo;
+ p_set_metadata($ID, array('last_change' => $revinfo));
+ }
+
+ if($revinfo !== false){
+ $info['ip'] = $revinfo['ip'];
+ $info['user'] = $revinfo['user'];
+ $info['sum'] = $revinfo['sum'];
+ // See also $INFO['meta']['last_change'] which is the most recent log line for page $ID.
+ // Use $INFO['meta']['last_change']['type']===DOKU_CHANGE_TYPE_MINOR_EDIT in place of $info['minor'].
+
+ if($revinfo['user']) {
+ $info['editor'] = $revinfo['user'];
+ } else {
+ $info['editor'] = $revinfo['ip'];
+ }
+ }else{
+ $info['ip'] = null;
+ $info['user'] = null;
+ $info['sum'] = null;
+ $info['editor'] = null;
+ }
+
+ // draft
+ $draft = new \dokuwiki\Draft($ID, $info['client']);
+ if ($draft->isDraftAvailable()) {
+ $info['draft'] = $draft->getDraftFilename();
+ }
+
+ return $info;
+}
+
+/**
+ * Initialize and/or fill global $JSINFO with some basic info to be given to javascript
+ */
+function jsinfo() {
+ global $JSINFO, $ID, $INFO, $ACT;
+
+ if (!is_array($JSINFO)) {
+ $JSINFO = [];
+ }
+ //export minimal info to JS, plugins can add more
+ $JSINFO['id'] = $ID;
+ $JSINFO['namespace'] = isset($INFO) ? (string) $INFO['namespace'] : '';
+ $JSINFO['ACT'] = act_clean($ACT);
+ $JSINFO['useHeadingNavigation'] = (int) useHeading('navigation');
+ $JSINFO['useHeadingContent'] = (int) useHeading('content');
+}
+
+/**
+ * Return information about the current media item as an associative array.
+ *
+ * @return array with info about current media item
+ */
+function mediainfo(){
+ global $NS;
+ global $IMG;
+
+ $info = basicinfo("$NS:*");
+ $info['image'] = $IMG;
+
+ return $info;
+}
+
+/**
+ * Build an string of URL parameters
+ *
+ * @author Andreas Gohr
+ *
+ * @param array $params array with key-value pairs
+ * @param string $sep series of pairs are separated by this character
+ * @return string query string
+ */
+function buildURLparams($params, $sep = '&amp;') {
+ $url = '';
+ $amp = false;
+ foreach($params as $key => $val) {
+ if($amp) $url .= $sep;
+
+ $url .= rawurlencode($key).'=';
+ $url .= rawurlencode((string) $val);
+ $amp = true;
+ }
+ return $url;
+}
+
+/**
+ * Build an string of html tag attributes
+ *
+ * Skips keys starting with '_', values get HTML encoded
+ *
+ * @author Andreas Gohr
+ *
+ * @param array $params array with (attribute name-attribute value) pairs
+ * @param bool $skipEmptyStrings skip empty string values?
+ * @return string
+ */
+function buildAttributes($params, $skipEmptyStrings = false) {
+ $url = '';
+ $white = false;
+ foreach($params as $key => $val) {
+ if($key[0] == '_') continue;
+ if($val === '' && $skipEmptyStrings) continue;
+ if($white) $url .= ' ';
+
+ $url .= $key.'="';
+ $url .= htmlspecialchars($val);
+ $url .= '"';
+ $white = true;
+ }
+ return $url;
+}
+
+/**
+ * This builds the breadcrumb trail and returns it as array
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return string[] with the data: array(pageid=>name, ... )
+ */
+function breadcrumbs() {
+ // we prepare the breadcrumbs early for quick session closing
+ static $crumbs = null;
+ if($crumbs != null) return $crumbs;
+
+ global $ID;
+ global $ACT;
+ global $conf;
+ global $INFO;
+
+ //first visit?
+ $crumbs = isset($_SESSION[DOKU_COOKIE]['bc']) ? $_SESSION[DOKU_COOKIE]['bc'] : array();
+ //we only save on show and existing visible readable wiki documents
+ $file = wikiFN($ID);
+ if($ACT != 'show' || $INFO['perm'] < AUTH_READ || isHiddenPage($ID) || !file_exists($file)) {
+ $_SESSION[DOKU_COOKIE]['bc'] = $crumbs;
+ return $crumbs;
+ }
+
+ // page names
+ $name = noNSorNS($ID);
+ if(useHeading('navigation')) {
+ // get page title
+ $title = p_get_first_heading($ID, METADATA_RENDER_USING_SIMPLE_CACHE);
+ if($title) {
+ $name = $title;
+ }
+ }
+
+ //remove ID from array
+ if(isset($crumbs[$ID])) {
+ unset($crumbs[$ID]);
+ }
+
+ //add to array
+ $crumbs[$ID] = $name;
+ //reduce size
+ while(count($crumbs) > $conf['breadcrumbs']) {
+ array_shift($crumbs);
+ }
+ //save to session
+ $_SESSION[DOKU_COOKIE]['bc'] = $crumbs;
+ return $crumbs;
+}
+
+/**
+ * Filter for page IDs
+ *
+ * This is run on a ID before it is outputted somewhere
+ * currently used to replace the colon with something else
+ * on Windows (non-IIS) systems and to have proper URL encoding
+ *
+ * See discussions at https://github.com/splitbrain/dokuwiki/pull/84 and
+ * https://github.com/splitbrain/dokuwiki/pull/173 why we use a whitelist of
+ * unaffected servers instead of blacklisting affected servers here.
+ *
+ * Urlencoding is ommitted when the second parameter is false
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id pageid being filtered
+ * @param bool $ue apply urlencoding?
+ * @return string
+ */
+function idfilter($id, $ue = true) {
+ global $conf;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ if($conf['useslash'] && $conf['userewrite']) {
+ $id = strtr($id, ':', '/');
+ } elseif(strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' &&
+ $conf['userewrite'] &&
+ strpos($INPUT->server->str('SERVER_SOFTWARE'), 'Microsoft-IIS') === false
+ ) {
+ $id = strtr($id, ':', ';');
+ }
+ if($ue) {
+ $id = rawurlencode($id);
+ $id = str_replace('%3A', ':', $id); //keep as colon
+ $id = str_replace('%3B', ';', $id); //keep as semicolon
+ $id = str_replace('%2F', '/', $id); //keep as slash
+ }
+ return $id;
+}
+
+/**
+ * This builds a link to a wikipage
+ *
+ * It handles URL rewriting and adds additional parameters
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id, defaults to start page
+ * @param string|array $urlParameters URL parameters, associative array recommended
+ * @param bool $absolute request an absolute URL instead of relative
+ * @param string $separator parameter separator
+ * @return string
+ */
+function wl($id = '', $urlParameters = '', $absolute = false, $separator = '&amp;') {
+ global $conf;
+ if(is_array($urlParameters)) {
+ if(isset($urlParameters['rev']) && !$urlParameters['rev']) unset($urlParameters['rev']);
+ if(isset($urlParameters['at']) && $conf['date_at_format']) {
+ $urlParameters['at'] = date($conf['date_at_format'], $urlParameters['at']);
+ }
+ $urlParameters = buildURLparams($urlParameters, $separator);
+ } else {
+ $urlParameters = str_replace(',', $separator, $urlParameters);
+ }
+ if($id === '') {
+ $id = $conf['start'];
+ }
+ $id = idfilter($id);
+ if($absolute) {
+ $xlink = DOKU_URL;
+ } else {
+ $xlink = DOKU_BASE;
+ }
+
+ if($conf['userewrite'] == 2) {
+ $xlink .= DOKU_SCRIPT.'/'.$id;
+ if($urlParameters) $xlink .= '?'.$urlParameters;
+ } elseif($conf['userewrite']) {
+ $xlink .= $id;
+ if($urlParameters) $xlink .= '?'.$urlParameters;
+ } elseif($id !== '') {
+ $xlink .= DOKU_SCRIPT.'?id='.$id;
+ if($urlParameters) $xlink .= $separator.$urlParameters;
+ } else {
+ $xlink .= DOKU_SCRIPT;
+ if($urlParameters) $xlink .= '?'.$urlParameters;
+ }
+
+ return $xlink;
+}
+
+/**
+ * This builds a link to an alternate page format
+ *
+ * Handles URL rewriting if enabled. Follows the style of wl().
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @param string $id page id, defaults to start page
+ * @param string $format the export renderer to use
+ * @param string|array $urlParameters URL parameters, associative array recommended
+ * @param bool $abs request an absolute URL instead of relative
+ * @param string $sep parameter separator
+ * @return string
+ */
+function exportlink($id = '', $format = 'raw', $urlParameters = '', $abs = false, $sep = '&amp;') {
+ global $conf;
+ if(is_array($urlParameters)) {
+ $urlParameters = buildURLparams($urlParameters, $sep);
+ } else {
+ $urlParameters = str_replace(',', $sep, $urlParameters);
+ }
+
+ $format = rawurlencode($format);
+ $id = idfilter($id);
+ if($abs) {
+ $xlink = DOKU_URL;
+ } else {
+ $xlink = DOKU_BASE;
+ }
+
+ if($conf['userewrite'] == 2) {
+ $xlink .= DOKU_SCRIPT.'/'.$id.'?do=export_'.$format;
+ if($urlParameters) $xlink .= $sep.$urlParameters;
+ } elseif($conf['userewrite'] == 1) {
+ $xlink .= '_export/'.$format.'/'.$id;
+ if($urlParameters) $xlink .= '?'.$urlParameters;
+ } else {
+ $xlink .= DOKU_SCRIPT.'?do=export_'.$format.$sep.'id='.$id;
+ if($urlParameters) $xlink .= $sep.$urlParameters;
+ }
+
+ return $xlink;
+}
+
+/**
+ * Build a link to a media file
+ *
+ * Will return a link to the detail page if $direct is false
+ *
+ * The $more parameter should always be given as array, the function then
+ * will strip default parameters to produce even cleaner URLs
+ *
+ * @param string $id the media file id or URL
+ * @param mixed $more string or array with additional parameters
+ * @param bool $direct link to detail page if false
+ * @param string $sep URL parameter separator
+ * @param bool $abs Create an absolute URL
+ * @return string
+ */
+function ml($id = '', $more = '', $direct = true, $sep = '&amp;', $abs = false) {
+ global $conf;
+ $isexternalimage = media_isexternal($id);
+ if(!$isexternalimage) {
+ $id = cleanID($id);
+ }
+
+ if(is_array($more)) {
+ // add token for resized images
+ if(!empty($more['w']) || !empty($more['h']) || $isexternalimage){
+ $more['tok'] = media_get_token($id,$more['w'],$more['h']);
+ }
+ // strip defaults for shorter URLs
+ if(isset($more['cache']) && $more['cache'] == 'cache') unset($more['cache']);
+ if(empty($more['w'])) unset($more['w']);
+ if(empty($more['h'])) unset($more['h']);
+ if(isset($more['id']) && $direct) unset($more['id']);
+ if(isset($more['rev']) && !$more['rev']) unset($more['rev']);
+ $more = buildURLparams($more, $sep);
+ } else {
+ $matches = array();
+ if (preg_match_all('/\b(w|h)=(\d*)\b/',$more,$matches,PREG_SET_ORDER) || $isexternalimage){
+ $resize = array('w'=>0, 'h'=>0);
+ foreach ($matches as $match){
+ $resize[$match[1]] = $match[2];
+ }
+ $more .= $more === '' ? '' : $sep;
+ $more .= 'tok='.media_get_token($id,$resize['w'],$resize['h']);
+ }
+ $more = str_replace('cache=cache', '', $more); //skip default
+ $more = str_replace(',,', ',', $more);
+ $more = str_replace(',', $sep, $more);
+ }
+
+ if($abs) {
+ $xlink = DOKU_URL;
+ } else {
+ $xlink = DOKU_BASE;
+ }
+
+ // external URLs are always direct without rewriting
+ if($isexternalimage) {
+ $xlink .= 'lib/exe/fetch.php';
+ $xlink .= '?'.$more;
+ $xlink .= $sep.'media='.rawurlencode($id);
+ return $xlink;
+ }
+
+ $id = idfilter($id);
+
+ // decide on scriptname
+ if($direct) {
+ if($conf['userewrite'] == 1) {
+ $script = '_media';
+ } else {
+ $script = 'lib/exe/fetch.php';
+ }
+ } else {
+ if($conf['userewrite'] == 1) {
+ $script = '_detail';
+ } else {
+ $script = 'lib/exe/detail.php';
+ }
+ }
+
+ // build URL based on rewrite mode
+ if($conf['userewrite']) {
+ $xlink .= $script.'/'.$id;
+ if($more) $xlink .= '?'.$more;
+ } else {
+ if($more) {
+ $xlink .= $script.'?'.$more;
+ $xlink .= $sep.'media='.$id;
+ } else {
+ $xlink .= $script.'?media='.$id;
+ }
+ }
+
+ return $xlink;
+}
+
+/**
+ * Returns the URL to the DokuWiki base script
+ *
+ * Consider using wl() instead, unless you absoutely need the doku.php endpoint
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return string
+ */
+function script() {
+ return DOKU_BASE.DOKU_SCRIPT;
+}
+
+/**
+ * Spamcheck against wordlist
+ *
+ * Checks the wikitext against a list of blocked expressions
+ * returns true if the text contains any bad words
+ *
+ * Triggers COMMON_WORDBLOCK_BLOCKED
+ *
+ * Action Plugins can use this event to inspect the blocked data
+ * and gain information about the user who was blocked.
+ *
+ * Event data:
+ * data['matches'] - array of matches
+ * data['userinfo'] - information about the blocked user
+ * [ip] - ip address
+ * [user] - username (if logged in)
+ * [mail] - mail address (if logged in)
+ * [name] - real name (if logged in)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param string $text - optional text to check, if not given the globals are used
+ * @return bool - true if a spam word was found
+ */
+function checkwordblock($text = '') {
+ global $TEXT;
+ global $PRE;
+ global $SUF;
+ global $SUM;
+ global $conf;
+ global $INFO;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ if(!$conf['usewordblock']) return false;
+
+ if(!$text) $text = "$PRE $TEXT $SUF $SUM";
+
+ // we prepare the text a tiny bit to prevent spammers circumventing URL checks
+ // phpcs:disable Generic.Files.LineLength.TooLong
+ $text = preg_replace(
+ '!(\b)(www\.[\w.:?\-;,]+?\.[\w.:?\-;,]+?[\w/\#~:.?+=&%@\!\-.:?\-;,]+?)([.:?\-;,]*[^\w/\#~:.?+=&%@\!\-.:?\-;,])!i',
+ '\1http://\2 \2\3',
+ $text
+ );
+ // phpcs:enable
+
+ $wordblocks = getWordblocks();
+ // how many lines to read at once (to work around some PCRE limits)
+ if(version_compare(phpversion(), '4.3.0', '<')) {
+ // old versions of PCRE define a maximum of parenthesises even if no
+ // backreferences are used - the maximum is 99
+ // this is very bad performancewise and may even be too high still
+ $chunksize = 40;
+ } else {
+ // read file in chunks of 200 - this should work around the
+ // MAX_PATTERN_SIZE in modern PCRE
+ $chunksize = 200;
+ }
+ while($blocks = array_splice($wordblocks, 0, $chunksize)) {
+ $re = array();
+ // build regexp from blocks
+ foreach($blocks as $block) {
+ $block = preg_replace('/#.*$/', '', $block);
+ $block = trim($block);
+ if(empty($block)) continue;
+ $re[] = $block;
+ }
+ if(count($re) && preg_match('#('.join('|', $re).')#si', $text, $matches)) {
+ // prepare event data
+ $data = array();
+ $data['matches'] = $matches;
+ $data['userinfo']['ip'] = $INPUT->server->str('REMOTE_ADDR');
+ if($INPUT->server->str('REMOTE_USER')) {
+ $data['userinfo']['user'] = $INPUT->server->str('REMOTE_USER');
+ $data['userinfo']['name'] = $INFO['userinfo']['name'];
+ $data['userinfo']['mail'] = $INFO['userinfo']['mail'];
+ }
+ $callback = function () {
+ return true;
+ };
+ return Event::createAndTrigger('COMMON_WORDBLOCK_BLOCKED', $data, $callback, true);
+ }
+ }
+ return false;
+}
+
+/**
+ * Return the IP of the client
+ *
+ * Honours X-Forwarded-For and X-Real-IP Proxy Headers
+ *
+ * It returns a comma separated list of IPs if the above mentioned
+ * headers are set. If the single parameter is set, it tries to return
+ * a routable public address, prefering the ones suplied in the X
+ * headers
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param boolean $single If set only a single IP is returned
+ * @return string
+ */
+function clientIP($single = false) {
+ /* @var Input $INPUT */
+ global $INPUT, $conf;
+
+ $ip = array();
+ $ip[] = $INPUT->server->str('REMOTE_ADDR');
+ if($INPUT->server->str('HTTP_X_FORWARDED_FOR')) {
+ $ip = array_merge($ip, explode(',', str_replace(' ', '', $INPUT->server->str('HTTP_X_FORWARDED_FOR'))));
+ }
+ if($INPUT->server->str('HTTP_X_REAL_IP')) {
+ $ip = array_merge($ip, explode(',', str_replace(' ', '', $INPUT->server->str('HTTP_X_REAL_IP'))));
+ }
+
+ // some IPv4/v6 regexps borrowed from Feyd
+ // see: http://forums.devnetwork.net/viewtopic.php?f=38&t=53479
+ $dec_octet = '(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|[0-9])';
+ $hex_digit = '[A-Fa-f0-9]';
+ $h16 = "{$hex_digit}{1,4}";
+ $IPv4Address = "$dec_octet\\.$dec_octet\\.$dec_octet\\.$dec_octet";
+ $ls32 = "(?:$h16:$h16|$IPv4Address)";
+ $IPv6Address =
+ "(?:(?:{$IPv4Address})|(?:".
+ "(?:$h16:){6}$ls32".
+ "|::(?:$h16:){5}$ls32".
+ "|(?:$h16)?::(?:$h16:){4}$ls32".
+ "|(?:(?:$h16:){0,1}$h16)?::(?:$h16:){3}$ls32".
+ "|(?:(?:$h16:){0,2}$h16)?::(?:$h16:){2}$ls32".
+ "|(?:(?:$h16:){0,3}$h16)?::(?:$h16:){1}$ls32".
+ "|(?:(?:$h16:){0,4}$h16)?::$ls32".
+ "|(?:(?:$h16:){0,5}$h16)?::$h16".
+ "|(?:(?:$h16:){0,6}$h16)?::".
+ ")(?:\\/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))?)";
+
+ // remove any non-IP stuff
+ $cnt = count($ip);
+ $match = array();
+ for($i = 0; $i < $cnt; $i++) {
+ if(preg_match("/^$IPv4Address$/", $ip[$i], $match) || preg_match("/^$IPv6Address$/", $ip[$i], $match)) {
+ $ip[$i] = $match[0];
+ } else {
+ $ip[$i] = '';
+ }
+ if(empty($ip[$i])) unset($ip[$i]);
+ }
+ $ip = array_values(array_unique($ip));
+ if(!$ip[0]) $ip[0] = '0.0.0.0'; // for some strange reason we don't have a IP
+
+ if(!$single) return join(',', $ip);
+
+ // skip trusted local addresses
+ foreach($ip as $i) {
+ if(!empty($conf['trustedproxy']) && preg_match('/'.$conf['trustedproxy'].'/', $i)) {
+ continue;
+ } else {
+ return $i;
+ }
+ }
+
+ // still here? just use the last address
+ // this case all ips in the list are trusted
+ return $ip[count($ip)-1];
+}
+
+/**
+ * Check if the browser is on a mobile device
+ *
+ * Adapted from the example code at url below
+ *
+ * @link http://www.brainhandles.com/2007/10/15/detecting-mobile-browsers/#code
+ *
+ * @deprecated 2018-04-27 you probably want media queries instead anyway
+ * @return bool if true, client is mobile browser; otherwise false
+ */
+function clientismobile() {
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ if($INPUT->server->has('HTTP_X_WAP_PROFILE')) return true;
+
+ if(preg_match('/wap\.|\.wap/i', $INPUT->server->str('HTTP_ACCEPT'))) return true;
+
+ if(!$INPUT->server->has('HTTP_USER_AGENT')) return false;
+
+ $uamatches = join(
+ '|',
+ [
+ 'midp', 'j2me', 'avantg', 'docomo', 'novarra', 'palmos', 'palmsource', '240x320', 'opwv',
+ 'chtml', 'pda', 'windows ce', 'mmp\/', 'blackberry', 'mib\/', 'symbian', 'wireless', 'nokia',
+ 'hand', 'mobi', 'phone', 'cdm', 'up\.b', 'audio', 'SIE\-', 'SEC\-', 'samsung', 'HTC', 'mot\-',
+ 'mitsu', 'sagem', 'sony', 'alcatel', 'lg', 'erics', 'vx', 'NEC', 'philips', 'mmm', 'xx',
+ 'panasonic', 'sharp', 'wap', 'sch', 'rover', 'pocket', 'benq', 'java', 'pt', 'pg', 'vox',
+ 'amoi', 'bird', 'compal', 'kg', 'voda', 'sany', 'kdd', 'dbt', 'sendo', 'sgh', 'gradi', 'jb',
+ '\d\d\di', 'moto'
+ ]
+ );
+
+ if(preg_match("/$uamatches/i", $INPUT->server->str('HTTP_USER_AGENT'))) return true;
+
+ return false;
+}
+
+/**
+ * check if a given link is interwiki link
+ *
+ * @param string $link the link, e.g. "wiki>page"
+ * @return bool
+ */
+function link_isinterwiki($link){
+ if (preg_match('/^[a-zA-Z0-9\.]+>/u',$link)) return true;
+ return false;
+}
+
+/**
+ * Convert one or more comma separated IPs to hostnames
+ *
+ * If $conf['dnslookups'] is disabled it simply returns the input string
+ *
+ * @author Glen Harris <astfgl@iamnota.org>
+ *
+ * @param string $ips comma separated list of IP addresses
+ * @return string a comma separated list of hostnames
+ */
+function gethostsbyaddrs($ips) {
+ global $conf;
+ if(!$conf['dnslookups']) return $ips;
+
+ $hosts = array();
+ $ips = explode(',', $ips);
+
+ if(is_array($ips)) {
+ foreach($ips as $ip) {
+ $hosts[] = gethostbyaddr(trim($ip));
+ }
+ return join(',', $hosts);
+ } else {
+ return gethostbyaddr(trim($ips));
+ }
+}
+
+/**
+ * Checks if a given page is currently locked.
+ *
+ * removes stale lockfiles
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id
+ * @return bool page is locked?
+ */
+function checklock($id) {
+ global $conf;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ $lock = wikiLockFN($id);
+
+ //no lockfile
+ if(!file_exists($lock)) return false;
+
+ //lockfile expired
+ if((time() - filemtime($lock)) > $conf['locktime']) {
+ @unlink($lock);
+ return false;
+ }
+
+ //my own lock
+ @list($ip, $session) = explode("\n", io_readFile($lock));
+ if($ip == $INPUT->server->str('REMOTE_USER') || $ip == clientIP() || (session_id() && $session == session_id())) {
+ return false;
+ }
+
+ return $ip;
+}
+
+/**
+ * Lock a page for editing
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id to lock
+ */
+function lock($id) {
+ global $conf;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ if($conf['locktime'] == 0) {
+ return;
+ }
+
+ $lock = wikiLockFN($id);
+ if($INPUT->server->str('REMOTE_USER')) {
+ io_saveFile($lock, $INPUT->server->str('REMOTE_USER'));
+ } else {
+ io_saveFile($lock, clientIP()."\n".session_id());
+ }
+}
+
+/**
+ * Unlock a page if it was locked by the user
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id to unlock
+ * @return bool true if a lock was removed
+ */
+function unlock($id) {
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ $lock = wikiLockFN($id);
+ if(file_exists($lock)) {
+ @list($ip, $session) = explode("\n", io_readFile($lock));
+ if($ip == $INPUT->server->str('REMOTE_USER') || $ip == clientIP() || $session == session_id()) {
+ @unlink($lock);
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * convert line ending to unix format
+ *
+ * also makes sure the given text is valid UTF-8
+ *
+ * @see formText() for 2crlf conversion
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $text
+ * @return string
+ */
+function cleanText($text) {
+ $text = preg_replace("/(\015\012)|(\015)/", "\012", $text);
+
+ // if the text is not valid UTF-8 we simply assume latin1
+ // this won't break any worse than it breaks with the wrong encoding
+ // but might actually fix the problem in many cases
+ if(!\dokuwiki\Utf8\Clean::isUtf8($text)) $text = utf8_encode($text);
+
+ return $text;
+}
+
+/**
+ * Prepares text for print in Webforms by encoding special chars.
+ * It also converts line endings to Windows format which is
+ * pseudo standard for webforms.
+ *
+ * @see cleanText() for 2unix conversion
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $text
+ * @return string
+ */
+function formText($text) {
+ $text = str_replace("\012", "\015\012", $text);
+ return htmlspecialchars($text);
+}
+
+/**
+ * Returns the specified local text in raw format
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id
+ * @param string $ext extension of file being read, default 'txt'
+ * @return string
+ */
+function rawLocale($id, $ext = 'txt') {
+ return io_readFile(localeFN($id, $ext));
+}
+
+/**
+ * Returns the raw WikiText
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id
+ * @param string|int $rev timestamp when a revision of wikitext is desired
+ * @return string
+ */
+function rawWiki($id, $rev = '') {
+ return io_readWikiPage(wikiFN($id, $rev), $id, $rev);
+}
+
+/**
+ * Returns the pagetemplate contents for the ID's namespace
+ *
+ * @triggers COMMON_PAGETPL_LOAD
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id the id of the page to be created
+ * @return string parsed pagetemplate content
+ */
+function pageTemplate($id) {
+ global $conf;
+
+ if(is_array($id)) $id = $id[0];
+
+ // prepare initial event data
+ $data = array(
+ 'id' => $id, // the id of the page to be created
+ 'tpl' => '', // the text used as template
+ 'tplfile' => '', // the file above text was/should be loaded from
+ 'doreplace' => true // should wildcard replacements be done on the text?
+ );
+
+ $evt = new Event('COMMON_PAGETPL_LOAD', $data);
+ if($evt->advise_before(true)) {
+ // the before event might have loaded the content already
+ if(empty($data['tpl'])) {
+ // if the before event did not set a template file, try to find one
+ if(empty($data['tplfile'])) {
+ $path = dirname(wikiFN($id));
+ if(file_exists($path.'/_template.txt')) {
+ $data['tplfile'] = $path.'/_template.txt';
+ } else {
+ // search upper namespaces for templates
+ $len = strlen(rtrim($conf['datadir'], '/'));
+ while(strlen($path) >= $len) {
+ if(file_exists($path.'/__template.txt')) {
+ $data['tplfile'] = $path.'/__template.txt';
+ break;
+ }
+ $path = substr($path, 0, strrpos($path, '/'));
+ }
+ }
+ }
+ // load the content
+ $data['tpl'] = io_readFile($data['tplfile']);
+ }
+ if($data['doreplace']) parsePageTemplate($data);
+ }
+ $evt->advise_after();
+ unset($evt);
+
+ return $data['tpl'];
+}
+
+/**
+ * Performs common page template replacements
+ * This works on data from COMMON_PAGETPL_LOAD
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data array with event data
+ * @return string
+ */
+function parsePageTemplate(&$data) {
+ /**
+ * @var string $id the id of the page to be created
+ * @var string $tpl the text used as template
+ * @var string $tplfile the file above text was/should be loaded from
+ * @var bool $doreplace should wildcard replacements be done on the text?
+ */
+ extract($data);
+
+ global $USERINFO;
+ global $conf;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ // replace placeholders
+ $file = noNS($id);
+ $page = strtr($file, $conf['sepchar'], ' ');
+
+ $tpl = str_replace(
+ array(
+ '@ID@',
+ '@NS@',
+ '@CURNS@',
+ '@!CURNS@',
+ '@!!CURNS@',
+ '@!CURNS!@',
+ '@FILE@',
+ '@!FILE@',
+ '@!FILE!@',
+ '@PAGE@',
+ '@!PAGE@',
+ '@!!PAGE@',
+ '@!PAGE!@',
+ '@USER@',
+ '@NAME@',
+ '@MAIL@',
+ '@DATE@',
+ ),
+ array(
+ $id,
+ getNS($id),
+ curNS($id),
+ \dokuwiki\Utf8\PhpString::ucfirst(curNS($id)),
+ \dokuwiki\Utf8\PhpString::ucwords(curNS($id)),
+ \dokuwiki\Utf8\PhpString::strtoupper(curNS($id)),
+ $file,
+ \dokuwiki\Utf8\PhpString::ucfirst($file),
+ \dokuwiki\Utf8\PhpString::strtoupper($file),
+ $page,
+ \dokuwiki\Utf8\PhpString::ucfirst($page),
+ \dokuwiki\Utf8\PhpString::ucwords($page),
+ \dokuwiki\Utf8\PhpString::strtoupper($page),
+ $INPUT->server->str('REMOTE_USER'),
+ $USERINFO ? $USERINFO['name'] : '',
+ $USERINFO ? $USERINFO['mail'] : '',
+ $conf['dformat'],
+ ), $tpl
+ );
+
+ // we need the callback to work around strftime's char limit
+ $tpl = preg_replace_callback(
+ '/%./',
+ function ($m) {
+ return strftime($m[0]);
+ },
+ $tpl
+ );
+ $data['tpl'] = $tpl;
+ return $tpl;
+}
+
+/**
+ * Returns the raw Wiki Text in three slices.
+ *
+ * The range parameter needs to have the form "from-to"
+ * and gives the range of the section in bytes - no
+ * UTF-8 awareness is needed.
+ * The returned order is prefix, section and suffix.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $range in form "from-to"
+ * @param string $id page id
+ * @param string $rev optional, the revision timestamp
+ * @return string[] with three slices
+ */
+function rawWikiSlices($range, $id, $rev = '') {
+ $text = io_readWikiPage(wikiFN($id, $rev), $id, $rev);
+
+ // Parse range
+ list($from, $to) = explode('-', $range, 2);
+ // Make range zero-based, use defaults if marker is missing
+ $from = !$from ? 0 : ($from - 1);
+ $to = !$to ? strlen($text) : ($to - 1);
+
+ $slices = array();
+ $slices[0] = substr($text, 0, $from);
+ $slices[1] = substr($text, $from, $to - $from);
+ $slices[2] = substr($text, $to);
+ return $slices;
+}
+
+/**
+ * Joins wiki text slices
+ *
+ * function to join the text slices.
+ * When the pretty parameter is set to true it adds additional empty
+ * lines between sections if needed (used on saving).
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $pre prefix
+ * @param string $text text in the middle
+ * @param string $suf suffix
+ * @param bool $pretty add additional empty lines between sections
+ * @return string
+ */
+function con($pre, $text, $suf, $pretty = false) {
+ if($pretty) {
+ if($pre !== '' && substr($pre, -1) !== "\n" &&
+ substr($text, 0, 1) !== "\n"
+ ) {
+ $pre .= "\n";
+ }
+ if($suf !== '' && substr($text, -1) !== "\n" &&
+ substr($suf, 0, 1) !== "\n"
+ ) {
+ $text .= "\n";
+ }
+ }
+
+ return $pre.$text.$suf;
+}
+
+/**
+ * Checks if the current page version is newer than the last entry in the page's
+ * changelog. If so, we assume it has been an external edit and we create an
+ * attic copy and add a proper changelog line.
+ *
+ * This check is only executed when the page is about to be saved again from the
+ * wiki, triggered in @see saveWikiText()
+ *
+ * @param string $id the page ID
+ */
+function detectExternalEdit($id) {
+ global $lang;
+
+ $fileLastMod = wikiFN($id);
+ $lastMod = @filemtime($fileLastMod); // from page
+ $pagelog = new PageChangeLog($id, 1024);
+ $lastRev = $pagelog->getRevisions(-1, 1); // from changelog
+ $lastRev = (int) (empty($lastRev) ? 0 : $lastRev[0]);
+
+ if(!file_exists(wikiFN($id, $lastMod)) && file_exists($fileLastMod) && $lastMod >= $lastRev) {
+ // add old revision to the attic if missing
+ saveOldRevision($id);
+ // add a changelog entry if this edit came from outside dokuwiki
+ if($lastMod > $lastRev) {
+ $fileLastRev = wikiFN($id, $lastRev);
+ $revinfo = $pagelog->getRevisionInfo($lastRev);
+ if(empty($lastRev) || !file_exists($fileLastRev) || $revinfo['type'] == DOKU_CHANGE_TYPE_DELETE) {
+ $filesize_old = 0;
+ } else {
+ $filesize_old = io_getSizeFile($fileLastRev);
+ }
+ $filesize_new = filesize($fileLastMod);
+ $sizechange = $filesize_new - $filesize_old;
+
+ addLogEntry(
+ $lastMod,
+ $id,
+ DOKU_CHANGE_TYPE_EDIT,
+ $lang['external_edit'],
+ '',
+ array('ExternalEdit' => true),
+ $sizechange
+ );
+ // remove soon to be stale instructions
+ $cache = new CacheInstructions($id, $fileLastMod);
+ $cache->removeCache();
+ }
+ }
+}
+
+/**
+ * Saves a wikitext by calling io_writeWikiPage.
+ * Also directs changelog and attic updates.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param string $id page id
+ * @param string $text wikitext being saved
+ * @param string $summary summary of text update
+ * @param bool $minor mark this saved version as minor update
+ */
+function saveWikiText($id, $text, $summary, $minor = false) {
+ /* Note to developers:
+ This code is subtle and delicate. Test the behavior of
+ the attic and changelog with dokuwiki and external edits
+ after any changes. External edits change the wiki page
+ directly without using php or dokuwiki.
+ */
+ global $conf;
+ global $lang;
+ global $REV;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ // prepare data for event
+ $svdta = array();
+ $svdta['id'] = $id;
+ $svdta['file'] = wikiFN($id);
+ $svdta['revertFrom'] = $REV;
+ $svdta['oldRevision'] = @filemtime($svdta['file']);
+ $svdta['newRevision'] = 0;
+ $svdta['newContent'] = $text;
+ $svdta['oldContent'] = rawWiki($id);
+ $svdta['summary'] = $summary;
+ $svdta['contentChanged'] = ($svdta['newContent'] != $svdta['oldContent']);
+ $svdta['changeInfo'] = '';
+ $svdta['changeType'] = DOKU_CHANGE_TYPE_EDIT;
+ $svdta['sizechange'] = null;
+
+ // select changelog line type
+ if($REV) {
+ $svdta['changeType'] = DOKU_CHANGE_TYPE_REVERT;
+ $svdta['changeInfo'] = $REV;
+ } else if(!file_exists($svdta['file'])) {
+ $svdta['changeType'] = DOKU_CHANGE_TYPE_CREATE;
+ } else if(trim($text) == '') {
+ // empty or whitespace only content deletes
+ $svdta['changeType'] = DOKU_CHANGE_TYPE_DELETE;
+ // autoset summary on deletion
+ if(blank($svdta['summary'])) {
+ $svdta['summary'] = $lang['deleted'];
+ }
+ } else if($minor && $conf['useacl'] && $INPUT->server->str('REMOTE_USER')) {
+ //minor edits only for logged in users
+ $svdta['changeType'] = DOKU_CHANGE_TYPE_MINOR_EDIT;
+ }
+
+ $event = new Event('COMMON_WIKIPAGE_SAVE', $svdta);
+ if(!$event->advise_before()) return;
+
+ // if the content has not been changed, no save happens (plugins may override this)
+ if(!$svdta['contentChanged']) return;
+
+ detectExternalEdit($id);
+
+ if(
+ $svdta['changeType'] == DOKU_CHANGE_TYPE_CREATE ||
+ ($svdta['changeType'] == DOKU_CHANGE_TYPE_REVERT && !file_exists($svdta['file']))
+ ) {
+ $filesize_old = 0;
+ } else {
+ $filesize_old = filesize($svdta['file']);
+ }
+ if($svdta['changeType'] == DOKU_CHANGE_TYPE_DELETE) {
+ // Send "update" event with empty data, so plugins can react to page deletion
+ $data = array(array($svdta['file'], '', false), getNS($id), noNS($id), false);
+ Event::createAndTrigger('IO_WIKIPAGE_WRITE', $data);
+ // pre-save deleted revision
+ @touch($svdta['file']);
+ clearstatcache();
+ $svdta['newRevision'] = saveOldRevision($id);
+ // remove empty file
+ @unlink($svdta['file']);
+ $filesize_new = 0;
+ // don't remove old meta info as it should be saved, plugins can use
+ // IO_WIKIPAGE_WRITE for removing their metadata...
+ // purge non-persistant meta data
+ p_purge_metadata($id);
+ // remove empty namespaces
+ io_sweepNS($id, 'datadir');
+ io_sweepNS($id, 'mediadir');
+ } else {
+ // save file (namespace dir is created in io_writeWikiPage)
+ io_writeWikiPage($svdta['file'], $svdta['newContent'], $id);
+ // pre-save the revision, to keep the attic in sync
+ $svdta['newRevision'] = saveOldRevision($id);
+ $filesize_new = filesize($svdta['file']);
+ }
+ $svdta['sizechange'] = $filesize_new - $filesize_old;
+
+ $event->advise_after();
+
+ addLogEntry(
+ $svdta['newRevision'],
+ $svdta['id'],
+ $svdta['changeType'],
+ $svdta['summary'],
+ $svdta['changeInfo'],
+ null,
+ $svdta['sizechange']
+ );
+
+ // send notify mails
+ notify($svdta['id'], 'admin', $svdta['oldRevision'], $svdta['summary'], $minor, $svdta['newRevision']);
+ notify($svdta['id'], 'subscribers', $svdta['oldRevision'], $svdta['summary'], $minor, $svdta['newRevision']);
+
+ // update the purgefile (timestamp of the last time anything within the wiki was changed)
+ io_saveFile($conf['cachedir'].'/purgefile', time());
+
+ // if useheading is enabled, purge the cache of all linking pages
+ if(useHeading('content')) {
+ $pages = ft_backlinks($id, true);
+ foreach($pages as $page) {
+ $cache = new CacheRenderer($page, wikiFN($page), 'xhtml');
+ $cache->removeCache();
+ }
+ }
+}
+
+/**
+ * moves the current version to the attic and returns its
+ * revision date
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id
+ * @return int|string revision timestamp
+ */
+function saveOldRevision($id) {
+ $oldf = wikiFN($id);
+ if(!file_exists($oldf)) return '';
+ $date = filemtime($oldf);
+ $newf = wikiFN($id, $date);
+ io_writeWikiPage($newf, rawWiki($id), $id, $date);
+ return $date;
+}
+
+/**
+ * Sends a notify mail on page change or registration
+ *
+ * @param string $id The changed page
+ * @param string $who Who to notify (admin|subscribers|register)
+ * @param int|string $rev Old page revision
+ * @param string $summary What changed
+ * @param boolean $minor Is this a minor edit?
+ * @param string[] $replace Additional string substitutions, @KEY@ to be replaced by value
+ * @param int|string $current_rev New page revision
+ * @return bool
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function notify($id, $who, $rev = '', $summary = '', $minor = false, $replace = array(), $current_rev = false) {
+ global $conf;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ // decide if there is something to do, eg. whom to mail
+ if($who == 'admin') {
+ if(empty($conf['notify'])) return false; //notify enabled?
+ $tpl = 'mailtext';
+ $to = $conf['notify'];
+ } elseif($who == 'subscribers') {
+ if(!actionOK('subscribe')) return false; //subscribers enabled?
+ if($conf['useacl'] && $INPUT->server->str('REMOTE_USER') && $minor) return false; //skip minors
+ $data = array('id' => $id, 'addresslist' => '', 'self' => false, 'replacements' => $replace);
+ Event::createAndTrigger(
+ 'COMMON_NOTIFY_ADDRESSLIST', $data,
+ array(new SubscriberManager(), 'notifyAddresses')
+ );
+ $to = $data['addresslist'];
+ if(empty($to)) return false;
+ $tpl = 'subscr_single';
+ } else {
+ return false; //just to be safe
+ }
+
+ // prepare content
+ $subscription = new PageSubscriptionSender();
+ return $subscription->sendPageDiff($to, $tpl, $id, $rev, $summary, $current_rev);
+}
+
+/**
+ * extracts the query from a search engine referrer
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Todd Augsburger <todd@rollerorgans.com>
+ *
+ * @return array|string
+ */
+function getGoogleQuery() {
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ if(!$INPUT->server->has('HTTP_REFERER')) {
+ return '';
+ }
+ $url = parse_url($INPUT->server->str('HTTP_REFERER'));
+
+ // only handle common SEs
+ if(!preg_match('/(google|bing|yahoo|ask|duckduckgo|babylon|aol|yandex)/',$url['host'])) return '';
+
+ $query = array();
+ parse_str($url['query'], $query);
+
+ $q = '';
+ if(isset($query['q'])){
+ $q = $query['q'];
+ }elseif(isset($query['p'])){
+ $q = $query['p'];
+ }elseif(isset($query['query'])){
+ $q = $query['query'];
+ }
+ $q = trim($q);
+
+ if(!$q) return '';
+ // ignore if query includes a full URL
+ if(strpos($q, '//') !== false) return '';
+ $q = preg_split('/[\s\'"\\\\`()\]\[?:!\.{};,#+*<>\\/]+/', $q, -1, PREG_SPLIT_NO_EMPTY);
+ return $q;
+}
+
+/**
+ * Return the human readable size of a file
+ *
+ * @param int $size A file size
+ * @param int $dec A number of decimal places
+ * @return string human readable size
+ *
+ * @author Martin Benjamin <b.martin@cybernet.ch>
+ * @author Aidan Lister <aidan@php.net>
+ * @version 1.0.0
+ */
+function filesize_h($size, $dec = 1) {
+ $sizes = array('B', 'KB', 'MB', 'GB');
+ $count = count($sizes);
+ $i = 0;
+
+ while($size >= 1024 && ($i < $count - 1)) {
+ $size /= 1024;
+ $i++;
+ }
+
+ return round($size, $dec)."\xC2\xA0".$sizes[$i]; //non-breaking space
+}
+
+/**
+ * Return the given timestamp as human readable, fuzzy age
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ *
+ * @param int $dt timestamp
+ * @return string
+ */
+function datetime_h($dt) {
+ global $lang;
+
+ $ago = time() - $dt;
+ if($ago > 24 * 60 * 60 * 30 * 12 * 2) {
+ return sprintf($lang['years'], round($ago / (24 * 60 * 60 * 30 * 12)));
+ }
+ if($ago > 24 * 60 * 60 * 30 * 2) {
+ return sprintf($lang['months'], round($ago / (24 * 60 * 60 * 30)));
+ }
+ if($ago > 24 * 60 * 60 * 7 * 2) {
+ return sprintf($lang['weeks'], round($ago / (24 * 60 * 60 * 7)));
+ }
+ if($ago > 24 * 60 * 60 * 2) {
+ return sprintf($lang['days'], round($ago / (24 * 60 * 60)));
+ }
+ if($ago > 60 * 60 * 2) {
+ return sprintf($lang['hours'], round($ago / (60 * 60)));
+ }
+ if($ago > 60 * 2) {
+ return sprintf($lang['minutes'], round($ago / (60)));
+ }
+ return sprintf($lang['seconds'], $ago);
+}
+
+/**
+ * Wraps around strftime but provides support for fuzzy dates
+ *
+ * The format default to $conf['dformat']. It is passed to
+ * strftime - %f can be used to get the value from datetime_h()
+ *
+ * @see datetime_h
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ *
+ * @param int|null $dt timestamp when given, null will take current timestamp
+ * @param string $format empty default to $conf['dformat'], or provide format as recognized by strftime()
+ * @return string
+ */
+function dformat($dt = null, $format = '') {
+ global $conf;
+
+ if(is_null($dt)) $dt = time();
+ $dt = (int) $dt;
+ if(!$format) $format = $conf['dformat'];
+
+ $format = str_replace('%f', datetime_h($dt), $format);
+ return strftime($format, $dt);
+}
+
+/**
+ * Formats a timestamp as ISO 8601 date
+ *
+ * @author <ungu at terong dot com>
+ * @link http://php.net/manual/en/function.date.php#54072
+ *
+ * @param int $int_date current date in UNIX timestamp
+ * @return string
+ */
+function date_iso8601($int_date) {
+ $date_mod = date('Y-m-d\TH:i:s', $int_date);
+ $pre_timezone = date('O', $int_date);
+ $time_zone = substr($pre_timezone, 0, 3).":".substr($pre_timezone, 3, 2);
+ $date_mod .= $time_zone;
+ return $date_mod;
+}
+
+/**
+ * return an obfuscated email address in line with $conf['mailguard'] setting
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ *
+ * @param string $email email address
+ * @return string
+ */
+function obfuscate($email) {
+ global $conf;
+
+ switch($conf['mailguard']) {
+ case 'visible' :
+ $obfuscate = array('@' => ' [at] ', '.' => ' [dot] ', '-' => ' [dash] ');
+ return strtr($email, $obfuscate);
+
+ case 'hex' :
+ return \dokuwiki\Utf8\Conversion::toHtml($email, true);
+
+ case 'none' :
+ default :
+ return $email;
+ }
+}
+
+/**
+ * Removes quoting backslashes
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $string
+ * @param string $char backslashed character
+ * @return string
+ */
+function unslash($string, $char = "'") {
+ return str_replace('\\'.$char, $char, $string);
+}
+
+/**
+ * Convert php.ini shorthands to byte
+ *
+ * On 32 bit systems values >= 2GB will fail!
+ *
+ * -1 (infinite size) will be reported as -1
+ *
+ * @link https://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes
+ * @param string $value PHP size shorthand
+ * @return int
+ */
+function php_to_byte($value) {
+ switch (strtoupper(substr($value,-1))) {
+ case 'G':
+ $ret = intval(substr($value, 0, -1)) * 1024 * 1024 * 1024;
+ break;
+ case 'M':
+ $ret = intval(substr($value, 0, -1)) * 1024 * 1024;
+ break;
+ case 'K':
+ $ret = intval(substr($value, 0, -1)) * 1024;
+ break;
+ default:
+ $ret = intval($value);
+ break;
+ }
+ return $ret;
+}
+
+/**
+ * Wrapper around preg_quote adding the default delimiter
+ *
+ * @param string $string
+ * @return string
+ */
+function preg_quote_cb($string) {
+ return preg_quote($string, '/');
+}
+
+/**
+ * Shorten a given string by removing data from the middle
+ *
+ * You can give the string in two parts, the first part $keep
+ * will never be shortened. The second part $short will be cut
+ * in the middle to shorten but only if at least $min chars are
+ * left to display it. Otherwise it will be left off.
+ *
+ * @param string $keep the part to keep
+ * @param string $short the part to shorten
+ * @param int $max maximum chars you want for the whole string
+ * @param int $min minimum number of chars to have left for middle shortening
+ * @param string $char the shortening character to use
+ * @return string
+ */
+function shorten($keep, $short, $max, $min = 9, $char = '…') {
+ $max = $max - \dokuwiki\Utf8\PhpString::strlen($keep);
+ if($max < $min) return $keep;
+ $len = \dokuwiki\Utf8\PhpString::strlen($short);
+ if($len <= $max) return $keep.$short;
+ $half = floor($max / 2);
+ return $keep .
+ \dokuwiki\Utf8\PhpString::substr($short, 0, $half - 1) .
+ $char .
+ \dokuwiki\Utf8\PhpString::substr($short, $len - $half);
+}
+
+/**
+ * Return the users real name or e-mail address for use
+ * in page footer and recent changes pages
+ *
+ * @param string|null $username or null when currently logged-in user should be used
+ * @param bool $textonly true returns only plain text, true allows returning html
+ * @return string html or plain text(not escaped) of formatted user name
+ *
+ * @author Andy Webber <dokuwiki AT andywebber DOT com>
+ */
+function editorinfo($username, $textonly = false) {
+ return userlink($username, $textonly);
+}
+
+/**
+ * Returns users realname w/o link
+ *
+ * @param string|null $username or null when currently logged-in user should be used
+ * @param bool $textonly true returns only plain text, true allows returning html
+ * @return string html or plain text(not escaped) of formatted user name
+ *
+ * @triggers COMMON_USER_LINK
+ */
+function userlink($username = null, $textonly = false) {
+ global $conf, $INFO;
+ /** @var AuthPlugin $auth */
+ global $auth;
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ // prepare initial event data
+ $data = array(
+ 'username' => $username, // the unique user name
+ 'name' => '',
+ 'link' => array( //setting 'link' to false disables linking
+ 'target' => '',
+ 'pre' => '',
+ 'suf' => '',
+ 'style' => '',
+ 'more' => '',
+ 'url' => '',
+ 'title' => '',
+ 'class' => ''
+ ),
+ 'userlink' => '', // formatted user name as will be returned
+ 'textonly' => $textonly
+ );
+ if($username === null) {
+ $data['username'] = $username = $INPUT->server->str('REMOTE_USER');
+ if($textonly){
+ $data['name'] = $INFO['userinfo']['name']. ' (' . $INPUT->server->str('REMOTE_USER') . ')';
+ }else {
+ $data['name'] = '<bdi>' . hsc($INFO['userinfo']['name']) . '</bdi> '.
+ '(<bdi>' . hsc($INPUT->server->str('REMOTE_USER')) . '</bdi>)';
+ }
+ }
+
+ $evt = new Event('COMMON_USER_LINK', $data);
+ if($evt->advise_before(true)) {
+ if(empty($data['name'])) {
+ if($auth) $info = $auth->getUserData($username);
+ if($conf['showuseras'] != 'loginname' && isset($info) && $info) {
+ switch($conf['showuseras']) {
+ case 'username':
+ case 'username_link':
+ $data['name'] = $textonly ? $info['name'] : hsc($info['name']);
+ break;
+ case 'email':
+ case 'email_link':
+ $data['name'] = obfuscate($info['mail']);
+ break;
+ }
+ } else {
+ $data['name'] = $textonly ? $data['username'] : hsc($data['username']);
+ }
+ }
+
+ /** @var Doku_Renderer_xhtml $xhtml_renderer */
+ static $xhtml_renderer = null;
+
+ if(!$data['textonly'] && empty($data['link']['url'])) {
+
+ if(in_array($conf['showuseras'], array('email_link', 'username_link'))) {
+ if(!isset($info)) {
+ if($auth) $info = $auth->getUserData($username);
+ }
+ if(isset($info) && $info) {
+ if($conf['showuseras'] == 'email_link') {
+ $data['link']['url'] = 'mailto:' . obfuscate($info['mail']);
+ } else {
+ if(is_null($xhtml_renderer)) {
+ $xhtml_renderer = p_get_renderer('xhtml');
+ }
+ if(empty($xhtml_renderer->interwiki)) {
+ $xhtml_renderer->interwiki = getInterwiki();
+ }
+ $shortcut = 'user';
+ $exists = null;
+ $data['link']['url'] = $xhtml_renderer->_resolveInterWiki($shortcut, $username, $exists);
+ $data['link']['class'] .= ' interwiki iw_user';
+ if($exists !== null) {
+ if($exists) {
+ $data['link']['class'] .= ' wikilink1';
+ } else {
+ $data['link']['class'] .= ' wikilink2';
+ $data['link']['rel'] = 'nofollow';
+ }
+ }
+ }
+ } else {
+ $data['textonly'] = true;
+ }
+
+ } else {
+ $data['textonly'] = true;
+ }
+ }
+
+ if($data['textonly']) {
+ $data['userlink'] = $data['name'];
+ } else {
+ $data['link']['name'] = $data['name'];
+ if(is_null($xhtml_renderer)) {
+ $xhtml_renderer = p_get_renderer('xhtml');
+ }
+ $data['userlink'] = $xhtml_renderer->_formatLink($data['link']);
+ }
+ }
+ $evt->advise_after();
+ unset($evt);
+
+ return $data['userlink'];
+}
+
+/**
+ * Returns the path to a image file for the currently chosen license.
+ * When no image exists, returns an empty string
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $type - type of image 'badge' or 'button'
+ * @return string
+ */
+function license_img($type) {
+ global $license;
+ global $conf;
+ if(!$conf['license']) return '';
+ if(!is_array($license[$conf['license']])) return '';
+ $try = array();
+ $try[] = 'lib/images/license/'.$type.'/'.$conf['license'].'.png';
+ $try[] = 'lib/images/license/'.$type.'/'.$conf['license'].'.gif';
+ if(substr($conf['license'], 0, 3) == 'cc-') {
+ $try[] = 'lib/images/license/'.$type.'/cc.png';
+ }
+ foreach($try as $src) {
+ if(file_exists(DOKU_INC.$src)) return $src;
+ }
+ return '';
+}
+
+/**
+ * Checks if the given amount of memory is available
+ *
+ * If the memory_get_usage() function is not available the
+ * function just assumes $bytes of already allocated memory
+ *
+ * @author Filip Oscadal <webmaster@illusionsoftworks.cz>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param int $mem Size of memory you want to allocate in bytes
+ * @param int $bytes already allocated memory (see above)
+ * @return bool
+ */
+function is_mem_available($mem, $bytes = 1048576) {
+ $limit = trim(ini_get('memory_limit'));
+ if(empty($limit)) return true; // no limit set!
+ if($limit == -1) return true; // unlimited
+
+ // parse limit to bytes
+ $limit = php_to_byte($limit);
+
+ // get used memory if possible
+ if(function_exists('memory_get_usage')) {
+ $used = memory_get_usage();
+ } else {
+ $used = $bytes;
+ }
+
+ if($used + $mem > $limit) {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Send a HTTP redirect to the browser
+ *
+ * Works arround Microsoft IIS cookie sending bug. Exits the script.
+ *
+ * @link http://support.microsoft.com/kb/q176113/
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $url url being directed to
+ */
+function send_redirect($url) {
+ $url = stripctl($url); // defend against HTTP Response Splitting
+
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ //are there any undisplayed messages? keep them in session for display
+ global $MSG;
+ if(isset($MSG) && count($MSG) && !defined('NOSESSION')) {
+ //reopen session, store data and close session again
+ @session_start();
+ $_SESSION[DOKU_COOKIE]['msg'] = $MSG;
+ }
+
+ // always close the session
+ session_write_close();
+
+ // check if running on IIS < 6 with CGI-PHP
+ if($INPUT->server->has('SERVER_SOFTWARE') && $INPUT->server->has('GATEWAY_INTERFACE') &&
+ (strpos($INPUT->server->str('GATEWAY_INTERFACE'), 'CGI') !== false) &&
+ (preg_match('|^Microsoft-IIS/(\d)\.\d$|', trim($INPUT->server->str('SERVER_SOFTWARE')), $matches)) &&
+ $matches[1] < 6
+ ) {
+ header('Refresh: 0;url='.$url);
+ } else {
+ header('Location: '.$url);
+ }
+
+ // no exits during unit tests
+ if(defined('DOKU_UNITTEST')) {
+ // pass info about the redirect back to the test suite
+ $testRequest = TestRequest::getRunning();
+ if($testRequest !== null) {
+ $testRequest->addData('send_redirect', $url);
+ }
+ return;
+ }
+
+ exit;
+}
+
+/**
+ * Validate a value using a set of valid values
+ *
+ * This function checks whether a specified value is set and in the array
+ * $valid_values. If not, the function returns a default value or, if no
+ * default is specified, throws an exception.
+ *
+ * @param string $param The name of the parameter
+ * @param array $valid_values A set of valid values; Optionally a default may
+ * be marked by the key “defaultâ€.
+ * @param array $array The array containing the value (typically $_POST
+ * or $_GET)
+ * @param string $exc The text of the raised exception
+ *
+ * @throws Exception
+ * @return mixed
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function valid_input_set($param, $valid_values, $array, $exc = '') {
+ if(isset($array[$param]) && in_array($array[$param], $valid_values)) {
+ return $array[$param];
+ } elseif(isset($valid_values['default'])) {
+ return $valid_values['default'];
+ } else {
+ throw new Exception($exc);
+ }
+}
+
+/**
+ * Read a preference from the DokuWiki cookie
+ * (remembering both keys & values are urlencoded)
+ *
+ * @param string $pref preference key
+ * @param mixed $default value returned when preference not found
+ * @return string preference value
+ */
+function get_doku_pref($pref, $default) {
+ $enc_pref = urlencode($pref);
+ if(isset($_COOKIE['DOKU_PREFS']) && strpos($_COOKIE['DOKU_PREFS'], $enc_pref) !== false) {
+ $parts = explode('#', $_COOKIE['DOKU_PREFS']);
+ $cnt = count($parts);
+
+ // due to #2721 there might be duplicate entries,
+ // so we read from the end
+ for($i = $cnt-2; $i >= 0; $i -= 2) {
+ if($parts[$i] == $enc_pref) {
+ return urldecode($parts[$i + 1]);
+ }
+ }
+ }
+ return $default;
+}
+
+/**
+ * Add a preference to the DokuWiki cookie
+ * (remembering $_COOKIE['DOKU_PREFS'] is urlencoded)
+ * Remove it by setting $val to false
+ *
+ * @param string $pref preference key
+ * @param string $val preference value
+ */
+function set_doku_pref($pref, $val) {
+ global $conf;
+ $orig = get_doku_pref($pref, false);
+ $cookieVal = '';
+
+ if($orig !== false && ($orig !== $val)) {
+ $parts = explode('#', $_COOKIE['DOKU_PREFS']);
+ $cnt = count($parts);
+ // urlencode $pref for the comparison
+ $enc_pref = rawurlencode($pref);
+ $seen = false;
+ for ($i = 0; $i < $cnt; $i += 2) {
+ if ($parts[$i] == $enc_pref) {
+ if (!$seen){
+ if ($val !== false) {
+ $parts[$i + 1] = rawurlencode($val);
+ } else {
+ unset($parts[$i]);
+ unset($parts[$i + 1]);
+ }
+ $seen = true;
+ } else {
+ // no break because we want to remove duplicate entries
+ unset($parts[$i]);
+ unset($parts[$i + 1]);
+ }
+ }
+ }
+ $cookieVal = implode('#', $parts);
+ } else if ($orig === false && $val !== false) {
+ $cookieVal = ($_COOKIE['DOKU_PREFS'] ? $_COOKIE['DOKU_PREFS'] . '#' : '') .
+ rawurlencode($pref) . '#' . rawurlencode($val);
+ }
+
+ $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
+ if(defined('DOKU_UNITTEST')) {
+ $_COOKIE['DOKU_PREFS'] = $cookieVal;
+ }else{
+ setcookie('DOKU_PREFS', $cookieVal, time()+365*24*3600, $cookieDir, '', ($conf['securecookie'] && is_ssl()));
+ }
+}
+
+/**
+ * Strips source mapping declarations from given text #601
+ *
+ * @param string &$text reference to the CSS or JavaScript code to clean
+ */
+function stripsourcemaps(&$text){
+ $text = preg_replace('/^(\/\/|\/\*)[@#]\s+sourceMappingURL=.*?(\*\/)?$/im', '\\1\\2', $text);
+}
+
+/**
+ * Returns the contents of a given SVG file for embedding
+ *
+ * Inlining SVGs saves on HTTP requests and more importantly allows for styling them through
+ * CSS. However it should used with small SVGs only. The $maxsize setting ensures only small
+ * files are embedded.
+ *
+ * This strips unneeded headers, comments and newline. The result is not a vaild standalone SVG!
+ *
+ * @param string $file full path to the SVG file
+ * @param int $maxsize maximum allowed size for the SVG to be embedded
+ * @return string|false the SVG content, false if the file couldn't be loaded
+ */
+function inlineSVG($file, $maxsize = 2048) {
+ $file = trim($file);
+ if($file === '') return false;
+ if(!file_exists($file)) return false;
+ if(filesize($file) > $maxsize) return false;
+ if(!is_readable($file)) return false;
+ $content = file_get_contents($file);
+ $content = preg_replace('/<!--.*?(-->)/s','', $content); // comments
+ $content = preg_replace('/<\?xml .*?\?>/i', '', $content); // xml header
+ $content = preg_replace('/<!DOCTYPE .*?>/i', '', $content); // doc type
+ $content = preg_replace('/>\s+</s', '><', $content); // newlines between tags
+ $content = trim($content);
+ if(substr($content, 0, 5) !== '<svg ') return false;
+ return $content;
+}
+
+//Setup VIM: ex: et ts=2 :
diff --git a/platform/www/inc/compatibility.php b/platform/www/inc/compatibility.php
new file mode 100644
index 0000000..445f245
--- /dev/null
+++ b/platform/www/inc/compatibility.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * compatibility functions
+ *
+ * This file contains a few functions that might be missing from the PHP build
+ */
+
+if(!function_exists('ctype_space')) {
+ /**
+ * Check for whitespace character(s)
+ *
+ * @see ctype_space
+ * @param string $text
+ * @return bool
+ */
+ function ctype_space($text) {
+ if(!is_string($text)) return false; #FIXME original treats between -128 and 255 inclusive as ASCII chars
+ if(trim($text) === '') return true;
+ return false;
+ }
+}
+
+if(!function_exists('ctype_digit')) {
+ /**
+ * Check for numeric character(s)
+ *
+ * @see ctype_digit
+ * @param string $text
+ * @return bool
+ */
+ function ctype_digit($text) {
+ if(!is_string($text)) return false; #FIXME original treats between -128 and 255 inclusive as ASCII chars
+ if(preg_match('/^\d+$/', $text)) return true;
+ return false;
+ }
+}
+
+if(!function_exists('gzopen') && function_exists('gzopen64')) {
+ /**
+ * work around for PHP compiled against certain zlib versions #865
+ *
+ * @link http://stackoverflow.com/questions/23417519/php-zlib-gzopen-not-exists
+ *
+ * @param string $filename
+ * @param string $mode
+ * @param int $use_include_path
+ * @return mixed
+ */
+ function gzopen($filename, $mode, $use_include_path = 0) {
+ return gzopen64($filename, $mode, $use_include_path);
+ }
+}
+
+if(!function_exists('gzseek') && function_exists('gzseek64')) {
+ /**
+ * work around for PHP compiled against certain zlib versions #865
+ *
+ * @link http://stackoverflow.com/questions/23417519/php-zlib-gzopen-not-exists
+ *
+ * @param resource $zp
+ * @param int $offset
+ * @param int $whence
+ * @return int
+ */
+ function gzseek($zp, $offset, $whence = SEEK_SET) {
+ return gzseek64($zp, $offset, $whence);
+ }
+}
+
+if(!function_exists('gztell') && function_exists('gztell64')) {
+ /**
+ * work around for PHP compiled against certain zlib versions #865
+ *
+ * @link http://stackoverflow.com/questions/23417519/php-zlib-gzopen-not-exists
+ *
+ * @param resource $zp
+ * @return int
+ */
+ function gztell($zp) {
+ return gztell64($zp);
+ }
+}
+
diff --git a/platform/www/inc/config_cascade.php b/platform/www/inc/config_cascade.php
new file mode 100644
index 0000000..61d099c
--- /dev/null
+++ b/platform/www/inc/config_cascade.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * The default config cascade
+ *
+ * This array configures the default locations of various files in the
+ * DokuWiki directory hierarchy. It can be overriden in inc/preload.php
+ */
+$config_cascade = array_merge(
+ array(
+ 'main' => array(
+ 'default' => array(DOKU_CONF . 'dokuwiki.php'),
+ 'local' => array(DOKU_CONF . 'local.php'),
+ 'protected' => array(DOKU_CONF . 'local.protected.php'),
+ ),
+ 'acronyms' => array(
+ 'default' => array(DOKU_CONF . 'acronyms.conf'),
+ 'local' => array(DOKU_CONF . 'acronyms.local.conf'),
+ ),
+ 'entities' => array(
+ 'default' => array(DOKU_CONF . 'entities.conf'),
+ 'local' => array(DOKU_CONF . 'entities.local.conf'),
+ ),
+ 'interwiki' => array(
+ 'default' => array(DOKU_CONF . 'interwiki.conf'),
+ 'local' => array(DOKU_CONF . 'interwiki.local.conf'),
+ ),
+ 'license' => array(
+ 'default' => array(DOKU_CONF . 'license.php'),
+ 'local' => array(DOKU_CONF . 'license.local.php'),
+ ),
+ 'manifest' => array(
+ 'default' => array(DOKU_CONF . 'manifest.json'),
+ 'local' => array(DOKU_CONF . 'manifest.local.json'),
+ ),
+ 'mediameta' => array(
+ 'default' => array(DOKU_CONF . 'mediameta.php'),
+ 'local' => array(DOKU_CONF . 'mediameta.local.php'),
+ ),
+ 'mime' => array(
+ 'default' => array(DOKU_CONF . 'mime.conf'),
+ 'local' => array(DOKU_CONF . 'mime.local.conf'),
+ ),
+ 'scheme' => array(
+ 'default' => array(DOKU_CONF . 'scheme.conf'),
+ 'local' => array(DOKU_CONF . 'scheme.local.conf'),
+ ),
+ 'smileys' => array(
+ 'default' => array(DOKU_CONF . 'smileys.conf'),
+ 'local' => array(DOKU_CONF . 'smileys.local.conf'),
+ ),
+ 'wordblock' => array(
+ 'default' => array(DOKU_CONF . 'wordblock.conf'),
+ 'local' => array(DOKU_CONF . 'wordblock.local.conf'),
+ ),
+ 'userstyle' => array(
+ 'screen' => array(DOKU_CONF . 'userstyle.css', DOKU_CONF . 'userstyle.less'),
+ 'print' => array(DOKU_CONF . 'userprint.css', DOKU_CONF . 'userprint.less'),
+ 'feed' => array(DOKU_CONF . 'userfeed.css', DOKU_CONF . 'userfeed.less'),
+ 'all' => array(DOKU_CONF . 'userall.css', DOKU_CONF . 'userall.less')
+ ),
+ 'userscript' => array(
+ 'default' => array(DOKU_CONF . 'userscript.js')
+ ),
+ 'styleini' => array(
+ 'default' => array(DOKU_INC . 'lib/tpl/%TEMPLATE%/' . 'style.ini'),
+ 'local' => array(DOKU_CONF . 'tpl/%TEMPLATE%/' . 'style.ini')
+ ),
+ 'acl' => array(
+ 'default' => DOKU_CONF . 'acl.auth.php',
+ ),
+ 'plainauth.users' => array(
+ 'default' => DOKU_CONF . 'users.auth.php',
+ 'protected' => '' // not used by default
+ ),
+ 'plugins' => array(
+ 'default' => array(DOKU_CONF . 'plugins.php'),
+ 'local' => array(DOKU_CONF . 'plugins.local.php'),
+ 'protected' => array(
+ DOKU_CONF . 'plugins.required.php',
+ DOKU_CONF . 'plugins.protected.php',
+ ),
+ ),
+ 'lang' => array(
+ 'core' => array(DOKU_CONF . 'lang/'),
+ 'plugin' => array(DOKU_CONF . 'plugin_lang/'),
+ 'template' => array(DOKU_CONF . 'template_lang/')
+ )
+ ),
+ $config_cascade
+);
+
diff --git a/platform/www/inc/confutils.php b/platform/www/inc/confutils.php
new file mode 100644
index 0000000..31724d2
--- /dev/null
+++ b/platform/www/inc/confutils.php
@@ -0,0 +1,474 @@
+<?php
+/**
+ * Utilities for collecting data from config files
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+
+/*
+ * line prefix used to negate single value config items
+ * (scheme.conf & stopwords.conf), e.g.
+ * !gopher
+ */
+
+use dokuwiki\Extension\AuthPlugin;
+use dokuwiki\Extension\Event;
+const DOKU_CONF_NEGATION = '!';
+
+/**
+ * Returns the (known) extension and mimetype of a given filename
+ *
+ * If $knownonly is true (the default), then only known extensions
+ * are returned.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file file name
+ * @param bool $knownonly
+ * @return array with extension, mimetype and if it should be downloaded
+ */
+function mimetype($file, $knownonly=true){
+ $mtypes = getMimeTypes(); // known mimetypes
+ $ext = strrpos($file, '.');
+ if ($ext === false) {
+ return array(false, false, false);
+ }
+ $ext = strtolower(substr($file, $ext + 1));
+ if (!isset($mtypes[$ext])){
+ if ($knownonly) {
+ return array(false, false, false);
+ } else {
+ return array($ext, 'application/octet-stream', true);
+ }
+ }
+ if($mtypes[$ext][0] == '!'){
+ return array($ext, substr($mtypes[$ext],1), true);
+ }else{
+ return array($ext, $mtypes[$ext], false);
+ }
+}
+
+/**
+ * returns a hash of mimetypes
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function getMimeTypes() {
+ static $mime = null;
+ if ( !$mime ) {
+ $mime = retrieveConfig('mime','confToHash');
+ $mime = array_filter($mime);
+ }
+ return $mime;
+}
+
+/**
+ * returns a hash of acronyms
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+function getAcronyms() {
+ static $acronyms = null;
+ if ( !$acronyms ) {
+ $acronyms = retrieveConfig('acronyms','confToHash');
+ $acronyms = array_filter($acronyms, 'strlen');
+ }
+ return $acronyms;
+}
+
+/**
+ * returns a hash of smileys
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+function getSmileys() {
+ static $smileys = null;
+ if ( !$smileys ) {
+ $smileys = retrieveConfig('smileys','confToHash');
+ $smileys = array_filter($smileys, 'strlen');
+ }
+ return $smileys;
+}
+
+/**
+ * returns a hash of entities
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+function getEntities() {
+ static $entities = null;
+ if ( !$entities ) {
+ $entities = retrieveConfig('entities','confToHash');
+ $entities = array_filter($entities, 'strlen');
+ }
+ return $entities;
+}
+
+/**
+ * returns a hash of interwikilinks
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ */
+function getInterwiki() {
+ static $wikis = null;
+ if ( !$wikis ) {
+ $wikis = retrieveConfig('interwiki','confToHash',array(true));
+ $wikis = array_filter($wikis, 'strlen');
+
+ //add sepecial case 'this'
+ $wikis['this'] = DOKU_URL.'{NAME}';
+ }
+ return $wikis;
+}
+
+/**
+ * Returns the jquery script URLs for the versions defined in lib/scripts/jquery/versions
+ *
+ * @trigger CONFUTIL_CDN_SELECT
+ * @return array
+ */
+function getCdnUrls() {
+ global $conf;
+
+ // load version info
+ $versions = array();
+ $lines = file(DOKU_INC . 'lib/scripts/jquery/versions');
+ foreach($lines as $line) {
+ $line = trim(preg_replace('/#.*$/', '', $line));
+ if($line === '') continue;
+ list($key, $val) = explode('=', $line, 2);
+ $key = trim($key);
+ $val = trim($val);
+ $versions[$key] = $val;
+ }
+
+ $src = array();
+ $data = array(
+ 'versions' => $versions,
+ 'src' => &$src
+ );
+ $event = new Event('CONFUTIL_CDN_SELECT', $data);
+ if($event->advise_before()) {
+ if(!$conf['jquerycdn']) {
+ $jqmod = md5(join('-', $versions));
+ $src[] = DOKU_BASE . 'lib/exe/jquery.php' . '?tseed=' . $jqmod;
+ } elseif($conf['jquerycdn'] == 'jquery') {
+ $src[] = sprintf('https://code.jquery.com/jquery-%s.min.js', $versions['JQ_VERSION']);
+ $src[] = sprintf('https://code.jquery.com/ui/%s/jquery-ui.min.js', $versions['JQUI_VERSION']);
+ } elseif($conf['jquerycdn'] == 'cdnjs') {
+ $src[] = sprintf(
+ 'https://cdnjs.cloudflare.com/ajax/libs/jquery/%s/jquery.min.js',
+ $versions['JQ_VERSION']
+ );
+ $src[] = sprintf(
+ 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/%s/jquery-ui.min.js',
+ $versions['JQUI_VERSION']
+ );
+ }
+ }
+ $event->advise_after();
+
+ return $src;
+}
+
+/**
+ * returns array of wordblock patterns
+ *
+ */
+function getWordblocks() {
+ static $wordblocks = null;
+ if ( !$wordblocks ) {
+ $wordblocks = retrieveConfig('wordblock','file',null,'array_merge_with_removal');
+ }
+ return $wordblocks;
+}
+
+/**
+ * Gets the list of configured schemes
+ *
+ * @return array the schemes
+ */
+function getSchemes() {
+ static $schemes = null;
+ if ( !$schemes ) {
+ $schemes = retrieveConfig('scheme','file',null,'array_merge_with_removal');
+ $schemes = array_map('trim', $schemes);
+ $schemes = preg_replace('/^#.*/', '', $schemes);
+ $schemes = array_filter($schemes);
+ }
+ return $schemes;
+}
+
+/**
+ * Builds a hash from an array of lines
+ *
+ * If $lower is set to true all hash keys are converted to
+ * lower case.
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Gina Haeussge <gina@foosel.net>
+ *
+ * @param array $lines
+ * @param bool $lower
+ *
+ * @return array
+ */
+function linesToHash($lines, $lower = false) {
+ $conf = array();
+ // remove BOM
+ if(isset($lines[0]) && substr($lines[0], 0, 3) == pack('CCC', 0xef, 0xbb, 0xbf))
+ $lines[0] = substr($lines[0], 3);
+ foreach($lines as $line) {
+ //ignore comments (except escaped ones)
+ $line = preg_replace('/(?<![&\\\\])#.*$/', '', $line);
+ $line = str_replace('\\#', '#', $line);
+ $line = trim($line);
+ if($line === '') continue;
+ $line = preg_split('/\s+/', $line, 2);
+ $line = array_pad($line, 2, '');
+ // Build the associative array
+ if($lower) {
+ $conf[strtolower($line[0])] = $line[1];
+ } else {
+ $conf[$line[0]] = $line[1];
+ }
+ }
+
+ return $conf;
+}
+
+/**
+ * Builds a hash from a configfile
+ *
+ * If $lower is set to true all hash keys are converted to
+ * lower case.
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Gina Haeussge <gina@foosel.net>
+ *
+ * @param string $file
+ * @param bool $lower
+ *
+ * @return array
+ */
+function confToHash($file,$lower=false) {
+ $conf = array();
+ $lines = @file( $file );
+ if ( !$lines ) return $conf;
+
+ return linesToHash($lines, $lower);
+}
+
+/**
+ * Read a json config file into an array
+ *
+ * @param string $file
+ * @return array
+ */
+function jsonToArray($file)
+{
+ $json = file_get_contents($file);
+
+ $conf = json_decode($json, true);
+
+ if ($conf === null) {
+ return [];
+ }
+
+ return $conf;
+}
+
+/**
+ * Retrieve the requested configuration information
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $type the configuration settings to be read, must correspond to a key/array in $config_cascade
+ * @param callback $fn the function used to process the configuration file into an array
+ * @param array $params optional additional params to pass to the callback
+ * @param callback $combine the function used to combine arrays of values read from different configuration files;
+ * the function takes two parameters,
+ * $combined - the already read & merged configuration values
+ * $new - array of config values from the config cascade file being currently processed
+ * and returns an array of the merged configuration values.
+ * @return array configuration values
+ */
+function retrieveConfig($type,$fn,$params=null,$combine='array_merge') {
+ global $config_cascade;
+
+ if(!is_array($params)) $params = array();
+
+ $combined = array();
+ if (!is_array($config_cascade[$type])) trigger_error('Missing config cascade for "'.$type.'"',E_USER_WARNING);
+ foreach (array('default','local','protected') as $config_group) {
+ if (empty($config_cascade[$type][$config_group])) continue;
+ foreach ($config_cascade[$type][$config_group] as $file) {
+ if (file_exists($file)) {
+ $config = call_user_func_array($fn,array_merge(array($file),$params));
+ $combined = $combine($combined, $config);
+ }
+ }
+ }
+
+ return $combined;
+}
+
+/**
+ * Include the requested configuration information
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $type the configuration settings to be read, must correspond to a key/array in $config_cascade
+ * @return array list of files, default before local before protected
+ */
+function getConfigFiles($type) {
+ global $config_cascade;
+ $files = array();
+
+ if (!is_array($config_cascade[$type])) trigger_error('Missing config cascade for "'.$type.'"',E_USER_WARNING);
+ foreach (array('default','local','protected') as $config_group) {
+ if (empty($config_cascade[$type][$config_group])) continue;
+ $files = array_merge($files, $config_cascade[$type][$config_group]);
+ }
+
+ return $files;
+}
+
+/**
+ * check if the given action was disabled in config
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $action
+ * @returns boolean true if enabled, false if disabled
+ */
+function actionOK($action){
+ static $disabled = null;
+ if(is_null($disabled) || defined('SIMPLE_TEST')){
+ global $conf;
+ /** @var AuthPlugin $auth */
+ global $auth;
+
+ // prepare disabled actions array and handle legacy options
+ $disabled = explode(',',$conf['disableactions']);
+ $disabled = array_map('trim',$disabled);
+ if((isset($conf['openregister']) && !$conf['openregister']) || is_null($auth) || !$auth->canDo('addUser')) {
+ $disabled[] = 'register';
+ }
+ if((isset($conf['resendpasswd']) && !$conf['resendpasswd']) || is_null($auth) || !$auth->canDo('modPass')) {
+ $disabled[] = 'resendpwd';
+ }
+ if((isset($conf['subscribers']) && !$conf['subscribers']) || is_null($auth)) {
+ $disabled[] = 'subscribe';
+ }
+ if (is_null($auth) || !$auth->canDo('Profile')) {
+ $disabled[] = 'profile';
+ }
+ if (is_null($auth) || !$auth->canDo('delUser')) {
+ $disabled[] = 'profile_delete';
+ }
+ if (is_null($auth)) {
+ $disabled[] = 'login';
+ }
+ if (is_null($auth) || !$auth->canDo('logout')) {
+ $disabled[] = 'logout';
+ }
+ $disabled = array_unique($disabled);
+ }
+
+ return !in_array($action,$disabled);
+}
+
+/**
+ * check if headings should be used as link text for the specified link type
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $linktype 'content'|'navigation', content applies to links in wiki text
+ * navigation applies to all other links
+ * @return boolean true if headings should be used for $linktype, false otherwise
+ */
+function useHeading($linktype) {
+ static $useHeading = null;
+ if(defined('DOKU_UNITTEST')) $useHeading = null; // don't cache during unit tests
+
+ if (is_null($useHeading)) {
+ global $conf;
+
+ if (!empty($conf['useheading'])) {
+ switch ($conf['useheading']) {
+ case 'content':
+ $useHeading['content'] = true;
+ break;
+
+ case 'navigation':
+ $useHeading['navigation'] = true;
+ break;
+ default:
+ $useHeading['content'] = true;
+ $useHeading['navigation'] = true;
+ }
+ } else {
+ $useHeading = array();
+ }
+ }
+
+ return (!empty($useHeading[$linktype]));
+}
+
+/**
+ * obscure config data so information isn't plain text
+ *
+ * @param string $str data to be encoded
+ * @param string $code encoding method, values: plain, base64, uuencode.
+ * @return string the encoded value
+ */
+function conf_encodeString($str,$code) {
+ switch ($code) {
+ case 'base64' : return '<b>'.base64_encode($str);
+ case 'uuencode' : return '<u>'.convert_uuencode($str);
+ case 'plain':
+ default:
+ return $str;
+ }
+}
+/**
+ * return obscured data as plain text
+ *
+ * @param string $str encoded data
+ * @return string plain text
+ */
+function conf_decodeString($str) {
+ switch (substr($str,0,3)) {
+ case '<b>' : return base64_decode(substr($str,3));
+ case '<u>' : return convert_uudecode(substr($str,3));
+ default: // not encoded (or unknown)
+ return $str;
+ }
+}
+
+/**
+ * array combination function to remove negated values (prefixed by !)
+ *
+ * @param array $current
+ * @param array $new
+ *
+ * @return array the combined array, numeric keys reset
+ */
+function array_merge_with_removal($current, $new) {
+ foreach ($new as $val) {
+ if (substr($val,0,1) == DOKU_CONF_NEGATION) {
+ $idx = array_search(trim(substr($val,1)),$current);
+ if ($idx !== false) {
+ unset($current[$idx]);
+ }
+ } else {
+ $current[] = trim($val);
+ }
+ }
+
+ return array_slice($current,0);
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/inc/defines.php b/platform/www/inc/defines.php
new file mode 100644
index 0000000..d864f71
--- /dev/null
+++ b/platform/www/inc/defines.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Set up globally available constants
+ */
+
+/**
+ * Auth Levels
+ * @file inc/auth.php
+ */
+define('AUTH_NONE', 0);
+define('AUTH_READ', 1);
+define('AUTH_EDIT', 2);
+define('AUTH_CREATE', 4);
+define('AUTH_UPLOAD', 8);
+define('AUTH_DELETE', 16);
+define('AUTH_ADMIN', 255);
+
+/**
+ * Message types
+ * @see msg()
+ */
+define('MSG_PUBLIC', 0);
+define('MSG_USERS_ONLY', 1);
+define('MSG_MANAGERS_ONLY', 2);
+define('MSG_ADMINS_ONLY', 4);
+
+/**
+ * Lexer constants
+ * @see \dokuwiki\Parsing\Lexer\Lexer
+ */
+define('DOKU_LEXER_ENTER', 1);
+define('DOKU_LEXER_MATCHED', 2);
+define('DOKU_LEXER_UNMATCHED', 3);
+define('DOKU_LEXER_EXIT', 4);
+define('DOKU_LEXER_SPECIAL', 5);
+
+/**
+ * Constants for known core changelog line types.
+ * @file inc/changelog.php
+ */
+define('DOKU_CHANGE_TYPE_CREATE', 'C');
+define('DOKU_CHANGE_TYPE_EDIT', 'E');
+define('DOKU_CHANGE_TYPE_MINOR_EDIT', 'e');
+define('DOKU_CHANGE_TYPE_DELETE', 'D');
+define('DOKU_CHANGE_TYPE_REVERT', 'R');
+
+/**
+ * Changelog filter constants
+ * @file inc/changelog.php
+ */
+define('RECENTS_SKIP_DELETED', 2);
+define('RECENTS_SKIP_MINORS', 4);
+define('RECENTS_SKIP_SUBSPACES', 8);
+define('RECENTS_MEDIA_CHANGES', 16);
+define('RECENTS_MEDIA_PAGES_MIXED', 32);
+define('RECENTS_ONLY_CREATION', 64);
+
+/**
+ * Media error types
+ * @file inc/media.php
+ */
+define('DOKU_MEDIA_DELETED', 1);
+define('DOKU_MEDIA_NOT_AUTH', 2);
+define('DOKU_MEDIA_INUSE', 4);
+define('DOKU_MEDIA_EMPTY_NS', 8);
diff --git a/platform/www/inc/deprecated.php b/platform/www/inc/deprecated.php
new file mode 100644
index 0000000..2050373
--- /dev/null
+++ b/platform/www/inc/deprecated.php
@@ -0,0 +1,570 @@
+<?php
+// phpcs:ignoreFile -- this file violates PSR2 by definition
+/**
+ * These classes and functions are deprecated and will be removed in future releases
+ */
+
+use dokuwiki\Debug\DebugHelper;
+use dokuwiki\Subscriptions\BulkSubscriptionSender;
+use dokuwiki\Subscriptions\MediaSubscriptionSender;
+use dokuwiki\Subscriptions\PageSubscriptionSender;
+use dokuwiki\Subscriptions\RegistrationSubscriptionSender;
+use dokuwiki\Subscriptions\SubscriberManager;
+
+/**
+ * @inheritdoc
+ * @deprecated 2018-05-07
+ */
+class RemoteAccessDeniedException extends \dokuwiki\Remote\AccessDeniedException
+{
+ /** @inheritdoc */
+ public function __construct($message = "", $code = 0, Throwable $previous = null)
+ {
+ dbg_deprecated(\dokuwiki\Remote\AccessDeniedException::class);
+ parent::__construct($message, $code, $previous);
+ }
+
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2018-05-07
+ */
+class RemoteException extends \dokuwiki\Remote\RemoteException
+{
+ /** @inheritdoc */
+ public function __construct($message = "", $code = 0, Throwable $previous = null)
+ {
+ dbg_deprecated(\dokuwiki\Remote\RemoteException::class);
+ parent::__construct($message, $code, $previous);
+ }
+
+}
+
+/**
+ * Escapes regex characters other than (, ) and /
+ *
+ * @param string $str
+ * @return string
+ * @deprecated 2018-05-04
+ */
+function Doku_Lexer_Escape($str)
+{
+ dbg_deprecated('\\dokuwiki\\Parsing\\Lexer\\Lexer::escape()');
+ return \dokuwiki\Parsing\Lexer\Lexer::escape($str);
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2018-06-01
+ */
+class setting extends \dokuwiki\plugin\config\core\Setting\Setting
+{
+ /** @inheritdoc */
+ public function __construct($key, array $params = null)
+ {
+ dbg_deprecated(\dokuwiki\plugin\config\core\Setting\Setting::class);
+ parent::__construct($key, $params);
+ }
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2018-06-01
+ */
+class setting_authtype extends \dokuwiki\plugin\config\core\Setting\SettingAuthtype
+{
+ /** @inheritdoc */
+ public function __construct($key, array $params = null)
+ {
+ dbg_deprecated(\dokuwiki\plugin\config\core\Setting\SettingAuthtype::class);
+ parent::__construct($key, $params);
+ }
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2018-06-01
+ */
+class setting_string extends \dokuwiki\plugin\config\core\Setting\SettingString
+{
+ /** @inheritdoc */
+ public function __construct($key, array $params = null)
+ {
+ dbg_deprecated(\dokuwiki\plugin\config\core\Setting\SettingString::class);
+ parent::__construct($key, $params);
+ }
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2018-06-15
+ */
+class PageChangelog extends \dokuwiki\ChangeLog\PageChangeLog
+{
+ /** @inheritdoc */
+ public function __construct($id, $chunk_size = 8192)
+ {
+ dbg_deprecated(\dokuwiki\ChangeLog\PageChangeLog::class);
+ parent::__construct($id, $chunk_size);
+ }
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2018-06-15
+ */
+class MediaChangelog extends \dokuwiki\ChangeLog\MediaChangeLog
+{
+ /** @inheritdoc */
+ public function __construct($id, $chunk_size = 8192)
+ {
+ dbg_deprecated(\dokuwiki\ChangeLog\MediaChangeLog::class);
+ parent::__construct($id, $chunk_size);
+ }
+}
+
+/** Behavior switch for JSON::decode() */
+define('JSON_LOOSE_TYPE', 16);
+
+/** Behavior switch for JSON::decode() */
+define('JSON_STRICT_TYPE', 0);
+
+/**
+ * Encode/Decode JSON
+ * @deprecated 2018-07-27
+ */
+class JSON
+{
+ protected $use = 0;
+
+ /**
+ * @param int $use JSON_*_TYPE flag
+ * @deprecated 2018-07-27
+ */
+ public function __construct($use = JSON_STRICT_TYPE)
+ {
+ $this->use = $use;
+ }
+
+ /**
+ * Encode given structure to JSON
+ *
+ * @param mixed $var
+ * @return string
+ * @deprecated 2018-07-27
+ */
+ public function encode($var)
+ {
+ dbg_deprecated('json_encode');
+ return json_encode($var);
+ }
+
+ /**
+ * Alias for encode()
+ * @param $var
+ * @return string
+ * @deprecated 2018-07-27
+ */
+ public function enc($var) {
+ return $this->encode($var);
+ }
+
+ /**
+ * Decode given string from JSON
+ *
+ * @param string $str
+ * @return mixed
+ * @deprecated 2018-07-27
+ */
+ public function decode($str)
+ {
+ dbg_deprecated('json_encode');
+ return json_decode($str, ($this->use == JSON_LOOSE_TYPE));
+ }
+
+ /**
+ * Alias for decode
+ *
+ * @param $str
+ * @return mixed
+ * @deprecated 2018-07-27
+ */
+ public function dec($str) {
+ return $this->decode($str);
+ }
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2019-02-19
+ */
+class Input extends \dokuwiki\Input\Input {
+ /**
+ * @inheritdoc
+ * @deprecated 2019-02-19
+ */
+ public function __construct()
+ {
+ dbg_deprecated(\dokuwiki\Input\Input::class);
+ parent::__construct();
+ }
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2019-02-19
+ */
+class PostInput extends \dokuwiki\Input\Post {
+ /**
+ * @inheritdoc
+ * @deprecated 2019-02-19
+ */
+ public function __construct()
+ {
+ dbg_deprecated(\dokuwiki\Input\Post::class);
+ parent::__construct();
+ }
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2019-02-19
+ */
+class GetInput extends \dokuwiki\Input\Get {
+ /**
+ * @inheritdoc
+ * @deprecated 2019-02-19
+ */
+ public function __construct()
+ {
+ dbg_deprecated(\dokuwiki\Input\Get::class);
+ parent::__construct();
+ }
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2019-02-19
+ */
+class ServerInput extends \dokuwiki\Input\Server {
+ /**
+ * @inheritdoc
+ * @deprecated 2019-02-19
+ */
+ public function __construct()
+ {
+ dbg_deprecated(\dokuwiki\Input\Server::class);
+ parent::__construct();
+ }
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2019-03-06
+ */
+class PassHash extends \dokuwiki\PassHash {
+ /**
+ * @inheritdoc
+ * @deprecated 2019-03-06
+ */
+ public function __construct()
+ {
+ dbg_deprecated(\dokuwiki\PassHash::class);
+ }
+}
+
+/**
+ * @deprecated since 2019-03-17 use \dokuwiki\HTTP\HTTPClientException instead!
+ */
+class HTTPClientException extends \dokuwiki\HTTP\HTTPClientException {
+
+ /**
+ * @inheritdoc
+ * @deprecated 2019-03-17
+ */
+ public function __construct($message = '', $code = 0, $previous = null)
+ {
+ DebugHelper::dbgDeprecatedFunction(dokuwiki\HTTP\HTTPClientException::class);
+ parent::__construct($message, $code, $previous);
+ }
+}
+
+/**
+ * @deprecated since 2019-03-17 use \dokuwiki\HTTP\HTTPClient instead!
+ */
+class HTTPClient extends \dokuwiki\HTTP\HTTPClient {
+
+ /**
+ * @inheritdoc
+ * @deprecated 2019-03-17
+ */
+ public function __construct()
+ {
+ DebugHelper::dbgDeprecatedFunction(dokuwiki\HTTP\HTTPClient::class);
+ parent::__construct();
+ }
+}
+
+/**
+ * @deprecated since 2019-03-17 use \dokuwiki\HTTP\DokuHTTPClient instead!
+ */
+class DokuHTTPClient extends \dokuwiki\HTTP\DokuHTTPClient
+{
+
+ /**
+ * @inheritdoc
+ * @deprecated 2019-03-17
+ */
+ public function __construct()
+ {
+ DebugHelper::dbgDeprecatedFunction(dokuwiki\HTTP\DokuHTTPClient::class);
+ parent::__construct();
+ }
+}
+
+/**
+ * function wrapper to process (create, trigger and destroy) an event
+ *
+ * @param string $name name for the event
+ * @param mixed $data event data
+ * @param callback $action (optional, default=NULL) default action, a php callback function
+ * @param bool $canPreventDefault (optional, default=true) can hooks prevent the default action
+ *
+ * @return mixed the event results value after all event processing is complete
+ * by default this is the return value of the default action however
+ * it can be set or modified by event handler hooks
+ * @deprecated 2018-06-15
+ */
+function trigger_event($name, &$data, $action=null, $canPreventDefault=true) {
+ dbg_deprecated('\dokuwiki\Extension\Event::createAndTrigger');
+ return \dokuwiki\Extension\Event::createAndTrigger($name, $data, $action, $canPreventDefault);
+}
+
+/**
+ * @inheritdoc
+ * @deprecated 2018-06-15
+ */
+class Doku_Plugin_Controller extends \dokuwiki\Extension\PluginController {
+ /** @inheritdoc */
+ public function __construct()
+ {
+ dbg_deprecated(\dokuwiki\Extension\PluginController::class);
+ parent::__construct();
+ }
+}
+
+
+/**
+ * Class for handling (email) subscriptions
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @deprecated 2019-04-22 Use the classes in the \dokuwiki\Subscriptions namespace instead!
+ */
+class Subscription {
+
+ /**
+ * Check if subscription system is enabled
+ *
+ * @return bool
+ *
+ * @deprecated 2019-04-20 \dokuwiki\Subscriptions\SubscriberManager::isenabled
+ */
+ public function isenabled() {
+ DebugHelper::dbgDeprecatedFunction('\dokuwiki\Subscriptions\SubscriberManager::isenabled');
+ $subscriberManager = new SubscriberManager();
+ return $subscriberManager->isenabled();
+ }
+
+ /**
+ * Recursively search for matching subscriptions
+ *
+ * This function searches all relevant subscription files for a page or
+ * namespace.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $page The target object’s (namespace or page) id
+ * @param string|array $user
+ * @param string|array $style
+ * @param string|array $data
+ * @return array
+ *
+ * @deprecated 2019-04-20 \dokuwiki\Subscriptions\SubscriberManager::subscribers
+ */
+ public function subscribers($page, $user = null, $style = null, $data = null) {
+ DebugHelper::dbgDeprecatedFunction('\dokuwiki\Subscriptions\SubscriberManager::subscribers');
+ $manager = new SubscriberManager();
+ return $manager->subscribers($page, $user, $style, $data);
+ }
+
+ /**
+ * Adds a new subscription for the given page or namespace
+ *
+ * This will automatically overwrite any existent subscription for the given user on this
+ * *exact* page or namespace. It will *not* modify any subscription that may exist in higher namespaces.
+ *
+ * @param string $id The target page or namespace, specified by id; Namespaces
+ * are identified by appending a colon.
+ * @param string $user
+ * @param string $style
+ * @param string $data
+ * @throws Exception when user or style is empty
+ * @return bool
+ *
+ * @deprecated 2019-04-20 \dokuwiki\Subscriptions\SubscriberManager::add
+ */
+ public function add($id, $user, $style, $data = '') {
+ DebugHelper::dbgDeprecatedFunction('\dokuwiki\Subscriptions\SubscriberManager::add');
+ $manager = new SubscriberManager();
+ return $manager->add($id, $user, $style, $data);
+ }
+
+ /**
+ * Removes a subscription for the given page or namespace
+ *
+ * This removes all subscriptions matching the given criteria on the given page or
+ * namespace. It will *not* modify any subscriptions that may exist in higher
+ * namespaces.
+ *
+ * @param string $id The target object’s (namespace or page) id
+ * @param string|array $user
+ * @param string|array $style
+ * @param string|array $data
+ * @return bool
+ *
+ * @deprecated 2019-04-20 \dokuwiki\Subscriptions\SubscriberManager::remove
+ */
+ public function remove($id, $user = null, $style = null, $data = null) {
+ DebugHelper::dbgDeprecatedFunction('\dokuwiki\Subscriptions\SubscriberManager::remove');
+ $manager = new SubscriberManager();
+ return $manager->remove($id, $user, $style, $data);
+ }
+
+ /**
+ * Get data for $INFO['subscribed']
+ *
+ * $INFO['subscribed'] is either false if no subscription for the current page
+ * and user is in effect. Else it contains an array of arrays with the fields
+ * “targetâ€, “styleâ€, and optionally “dataâ€.
+ *
+ * @param string $id Page ID, defaults to global $ID
+ * @param string $user User, defaults to $_SERVER['REMOTE_USER']
+ * @return array|false
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @deprecated 2019-04-20 \dokuwiki\Subscriptions\SubscriberManager::userSubscription
+ */
+ public function user_subscription($id = '', $user = '') {
+ DebugHelper::dbgDeprecatedFunction('\dokuwiki\Subscriptions\SubscriberManager::userSubscription');
+ $manager = new SubscriberManager();
+ return $manager->userSubscription($id, $user);
+ }
+
+ /**
+ * Send digest and list subscriptions
+ *
+ * This sends mails to all subscribers that have a subscription for namespaces above
+ * the given page if the needed $conf['subscribe_time'] has passed already.
+ *
+ * This function is called form lib/exe/indexer.php
+ *
+ * @param string $page
+ * @return int number of sent mails
+ *
+ * @deprecated 2019-04-20 \dokuwiki\Subscriptions\BulkSubscriptionSender::sendBulk
+ */
+ public function send_bulk($page) {
+ DebugHelper::dbgDeprecatedFunction('\dokuwiki\Subscriptions\BulkSubscriptionSender::sendBulk');
+ $subscriptionSender = new BulkSubscriptionSender();
+ return $subscriptionSender->sendBulk($page);
+ }
+
+ /**
+ * Send the diff for some page change
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param string $template Mail template ('subscr_digest', 'subscr_single', 'mailtext', ...)
+ * @param string $id Page for which the notification is
+ * @param int|null $rev Old revision if any
+ * @param string $summary Change summary if any
+ * @return bool true if successfully sent
+ *
+ * @deprecated 2019-04-20 \dokuwiki\Subscriptions\PageSubscriptionSender::sendPageDiff
+ */
+ public function send_diff($subscriber_mail, $template, $id, $rev = null, $summary = '') {
+ DebugHelper::dbgDeprecatedFunction('\dokuwiki\Subscriptions\PageSubscriptionSender::sendPageDiff');
+ $subscriptionSender = new PageSubscriptionSender();
+ return $subscriptionSender->sendPageDiff($subscriber_mail, $template, $id, $rev, $summary);
+ }
+
+ /**
+ * Send the diff for some media change
+ *
+ * @fixme this should embed thumbnails of images in HTML version
+ *
+ * @param string $subscriber_mail The target mail address
+ * @param string $template Mail template ('uploadmail', ...)
+ * @param string $id Media file for which the notification is
+ * @param int|bool $rev Old revision if any
+ *
+ * @deprecated 2019-04-20 \dokuwiki\Subscriptions\MediaSubscriptionSender::sendMediaDiff
+ */
+ public function send_media_diff($subscriber_mail, $template, $id, $rev = false) {
+ DebugHelper::dbgDeprecatedFunction('\dokuwiki\Subscriptions\MediaSubscriptionSender::sendMediaDiff');
+ $subscriptionSender = new MediaSubscriptionSender();
+ return $subscriptionSender->sendMediaDiff($subscriber_mail, $template, $id, $rev);
+ }
+
+ /**
+ * Send a notify mail on new registration
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $login login name of the new user
+ * @param string $fullname full name of the new user
+ * @param string $email email address of the new user
+ * @return bool true if a mail was sent
+ *
+ * @deprecated 2019-04-20 \dokuwiki\Subscriptions\RegistrationSubscriptionSender::sendRegister
+ */
+ public function send_register($login, $fullname, $email) {
+ DebugHelper::dbgDeprecatedFunction('\dokuwiki\Subscriptions\RegistrationSubscriptionSender::sendRegister');
+ $subscriptionSender = new RegistrationSubscriptionSender();
+ return $subscriptionSender->sendRegister($login, $fullname, $email);
+ }
+
+
+ /**
+ * Default callback for COMMON_NOTIFY_ADDRESSLIST
+ *
+ * Aggregates all email addresses of user who have subscribed the given page with 'every' style
+ *
+ * @author Steven Danz <steven-danz@kc.rr.com>
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @todo move the whole functionality into this class, trigger SUBSCRIPTION_NOTIFY_ADDRESSLIST instead,
+ * use an array for the addresses within it
+ *
+ * @param array &$data Containing the entries:
+ * - $id (the page id),
+ * - $self (whether the author should be notified,
+ * - $addresslist (current email address list)
+ * - $replacements (array of additional string substitutions, @KEY@ to be replaced by value)
+ *
+ * @deprecated 2019-04-20 \dokuwiki\Subscriptions\SubscriberManager::notifyAddresses
+ */
+ public function notifyaddresses(&$data) {
+ DebugHelper::dbgDeprecatedFunction('\dokuwiki\Subscriptions\SubscriberManager::notifyAddresses');
+ $manager = new SubscriberManager();
+ $manager->notifyAddresses($data);
+ }
+}
+
+/**
+ * @deprecated 2019-12-29 use \dokuwiki\Search\Indexer
+ */
+class Doku_Indexer extends \dokuwiki\Search\Indexer {};
diff --git a/platform/www/inc/farm.php b/platform/www/inc/farm.php
new file mode 100644
index 0000000..03aa0eb
--- /dev/null
+++ b/platform/www/inc/farm.php
@@ -0,0 +1,150 @@
+<?php
+/**
+ * This overwrites DOKU_CONF. Each animal gets its own configuration and data directory.
+ * This can be used together with preload.php. See preload.php.dist for an example setup.
+ * For more information see http://www.dokuwiki.org/farms.
+ *
+ * The farm directory (constant DOKU_FARMDIR) can be any directory and needs to be set.
+ * Animals are direct subdirectories of the farm directory.
+ * There are two different approaches:
+ * * An .htaccess based setup can use any animal directory name:
+ * http://example.org/<path_to_farm>/subdir/ will need the subdirectory '$farm/subdir/'.
+ * * A virtual host based setup needs animal directory names which have to reflect
+ * the domain name: If an animal resides in http://www.example.org:8080/mysite/test/,
+ * directories that will match range from '$farm/8080.www.example.org.mysite.test/'
+ * to a simple '$farm/domain/'.
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author virtual host part of farm_confpath() based on conf_path() from Drupal.org's /includes/bootstrap.inc
+ * (see https://github.com/drupal/drupal/blob/7.x/includes/bootstrap.inc#L537)
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+// DOKU_FARMDIR needs to be set in preload.php, the fallback is the same as DOKU_INC would be (if it was set already)
+if(!defined('DOKU_FARMDIR')) define('DOKU_FARMDIR', fullpath(dirname(__FILE__).'/../').'/');
+if(!defined('DOKU_CONF')) define('DOKU_CONF', farm_confpath(DOKU_FARMDIR));
+if(!defined('DOKU_FARM')) define('DOKU_FARM', false);
+
+
+/**
+ * Find the appropriate configuration directory.
+ *
+ * If the .htaccess based setup is used, the configuration directory can be
+ * any subdirectory of the farm directory.
+ *
+ * Otherwise try finding a matching configuration directory by stripping the
+ * website's hostname from left to right and pathname from right to left. The
+ * first configuration file found will be used; the remaining will ignored.
+ * If no configuration file is found, return the default confdir './conf'.
+ *
+ * @param string $farm
+ *
+ * @return string
+ */
+function farm_confpath($farm) {
+
+ // htaccess based or cli
+ // cli usage example: animal=your_animal bin/indexer.php
+ if(isset($_REQUEST['animal']) || ('cli' == php_sapi_name() && isset($_SERVER['animal']))) {
+ $mode = isset($_REQUEST['animal']) ? 'htaccess' : 'cli';
+ $animal = $mode == 'htaccess' ? $_REQUEST['animal'] : $_SERVER['animal'];
+ // check that $animal is a string and just a directory name and not a path
+ if (!is_string($animal) || strpbrk($animal, '\\/') !== false)
+ nice_die('Sorry! Invalid animal name!');
+ if(!is_dir($farm.'/'.$animal))
+ nice_die("Sorry! This Wiki doesn't exist!");
+ if(!defined('DOKU_FARM')) define('DOKU_FARM', $mode);
+ return $farm.'/'.$animal.'/conf/';
+ }
+
+ // virtual host based
+ $uri = explode('/', $_SERVER['SCRIPT_NAME'] ? $_SERVER['SCRIPT_NAME'] : $_SERVER['SCRIPT_FILENAME']);
+ $server = explode('.', implode('.', array_reverse(explode(':', rtrim($_SERVER['HTTP_HOST'], '.')))));
+ for ($i = count($uri) - 1; $i > 0; $i--) {
+ for ($j = count($server); $j > 0; $j--) {
+ $dir = implode('.', array_slice($server, -$j)) . implode('.', array_slice($uri, 0, $i));
+ if(is_dir("$farm/$dir/conf/")) {
+ if(!defined('DOKU_FARM')) define('DOKU_FARM', 'virtual');
+ return "$farm/$dir/conf/";
+ }
+ }
+ }
+
+ // default conf directory in farm
+ if(is_dir("$farm/default/conf/")) {
+ if(!defined('DOKU_FARM')) define('DOKU_FARM', 'default');
+ return "$farm/default/conf/";
+ }
+ // farmer
+ return DOKU_INC.'conf/';
+}
+
+/* Use default config files and local animal config files */
+$config_cascade = array(
+ 'main' => array(
+ 'default' => array(DOKU_INC.'conf/dokuwiki.php'),
+ 'local' => array(DOKU_CONF.'local.php'),
+ 'protected' => array(DOKU_CONF.'local.protected.php'),
+ ),
+ 'acronyms' => array(
+ 'default' => array(DOKU_INC.'conf/acronyms.conf'),
+ 'local' => array(DOKU_CONF.'acronyms.local.conf'),
+ ),
+ 'entities' => array(
+ 'default' => array(DOKU_INC.'conf/entities.conf'),
+ 'local' => array(DOKU_CONF.'entities.local.conf'),
+ ),
+ 'interwiki' => array(
+ 'default' => array(DOKU_INC.'conf/interwiki.conf'),
+ 'local' => array(DOKU_CONF.'interwiki.local.conf'),
+ ),
+ 'license' => array(
+ 'default' => array(DOKU_INC.'conf/license.php'),
+ 'local' => array(DOKU_CONF.'license.local.php'),
+ ),
+ 'mediameta' => array(
+ 'default' => array(DOKU_INC.'conf/mediameta.php'),
+ 'local' => array(DOKU_CONF.'mediameta.local.php'),
+ ),
+ 'mime' => array(
+ 'default' => array(DOKU_INC.'conf/mime.conf'),
+ 'local' => array(DOKU_CONF.'mime.local.conf'),
+ ),
+ 'scheme' => array(
+ 'default' => array(DOKU_INC.'conf/scheme.conf'),
+ 'local' => array(DOKU_CONF.'scheme.local.conf'),
+ ),
+ 'smileys' => array(
+ 'default' => array(DOKU_INC.'conf/smileys.conf'),
+ 'local' => array(DOKU_CONF.'smileys.local.conf'),
+ ),
+ 'wordblock' => array(
+ 'default' => array(DOKU_INC.'conf/wordblock.conf'),
+ 'local' => array(DOKU_CONF.'wordblock.local.conf'),
+ ),
+ 'acl' => array(
+ 'default' => DOKU_CONF.'acl.auth.php',
+ ),
+ 'plainauth.users' => array(
+ 'default' => DOKU_CONF.'users.auth.php',
+ ),
+ 'plugins' => array( // needed since Angua
+ 'default' => array(DOKU_INC.'conf/plugins.php'),
+ 'local' => array(DOKU_CONF.'plugins.local.php'),
+ 'protected' => array(
+ DOKU_INC.'conf/plugins.required.php',
+ DOKU_CONF.'plugins.protected.php',
+ ),
+ ),
+ 'userstyle' => array(
+ 'screen' => array(DOKU_CONF . 'userstyle.css', DOKU_CONF . 'userstyle.less'),
+ 'print' => array(DOKU_CONF . 'userprint.css', DOKU_CONF . 'userprint.less'),
+ 'feed' => array(DOKU_CONF . 'userfeed.css', DOKU_CONF . 'userfeed.less'),
+ 'all' => array(DOKU_CONF . 'userall.css', DOKU_CONF . 'userall.less')
+ ),
+ 'userscript' => array(
+ 'default' => array(DOKU_CONF . 'userscript.js')
+ ),
+);
diff --git a/platform/www/inc/fetch.functions.php b/platform/www/inc/fetch.functions.php
new file mode 100644
index 0000000..6367262
--- /dev/null
+++ b/platform/www/inc/fetch.functions.php
@@ -0,0 +1,196 @@
+<?php
+/**
+ * Functions used by lib/exe/fetch.php
+ * (not included by other parts of dokuwiki)
+ */
+
+/**
+ * Set headers and send the file to the client
+ *
+ * The $cache parameter influences how long files may be kept in caches, the $public parameter
+ * influences if this caching may happen in public proxis or in the browser cache only FS#2734
+ *
+ * This function will abort the current script when a 304 is sent or file sending is handled
+ * through x-sendfile
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @author Gerry Weissbach <dokuwiki@gammaproduction.de>
+ *
+ * @param string $file local file to send
+ * @param string $mime mime type of the file
+ * @param bool $dl set to true to force a browser download
+ * @param int $cache remaining cache time in seconds (-1 for $conf['cache'], 0 for no-cache)
+ * @param bool $public is this a public ressource or a private one?
+ * @param string $orig original file to send - the file name will be used for the Content-Disposition
+ */
+function sendFile($file, $mime, $dl, $cache, $public = false, $orig = null) {
+ global $conf;
+ // send mime headers
+ header("Content-Type: $mime");
+
+ // calculate cache times
+ if($cache == -1) {
+ $maxage = max($conf['cachetime'], 3600); // cachetime or one hour
+ $expires = time() + $maxage;
+ } else if($cache > 0) {
+ $maxage = $cache; // given time
+ $expires = time() + $maxage;
+ } else { // $cache == 0
+ $maxage = 0;
+ $expires = 0; // 1970-01-01
+ }
+
+ // smart http caching headers
+ if($maxage) {
+ if($public) {
+ // cache publically
+ header('Expires: '.gmdate("D, d M Y H:i:s", $expires).' GMT');
+ header('Cache-Control: public, proxy-revalidate, no-transform, max-age='.$maxage);
+ } else {
+ // cache in browser
+ header('Expires: '.gmdate("D, d M Y H:i:s", $expires).' GMT');
+ header('Cache-Control: private, no-transform, max-age='.$maxage);
+ }
+ } else {
+ // no cache at all
+ header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
+ header('Cache-Control: no-cache, no-transform');
+ }
+
+ //send important headers first, script stops here if '304 Not Modified' response
+ $fmtime = @filemtime($file);
+ http_conditionalRequest($fmtime);
+
+ // Use the current $file if is $orig is not set.
+ if ( $orig == null ) {
+ $orig = $file;
+ }
+
+ //download or display?
+ if ($dl) {
+ header('Content-Disposition: attachment;' . rfc2231_encode(
+ 'filename', \dokuwiki\Utf8\PhpString::basename($orig)) . ';'
+ );
+ } else {
+ header('Content-Disposition: inline;' . rfc2231_encode(
+ 'filename', \dokuwiki\Utf8\PhpString::basename($orig)) . ';'
+ );
+ }
+
+ //use x-sendfile header to pass the delivery to compatible webservers
+ http_sendfile($file);
+
+ // send file contents
+ $fp = @fopen($file, "rb");
+ if($fp) {
+ http_rangeRequest($fp, filesize($file), $mime);
+ } else {
+ http_status(500);
+ print "Could not read $file - bad permissions?";
+ }
+}
+
+/**
+ * Try an rfc2231 compatible encoding. This ensures correct
+ * interpretation of filenames outside of the ASCII set.
+ * This seems to be needed for file names with e.g. umlauts that
+ * would otherwise decode wrongly in IE.
+ *
+ * There is no additional checking, just the encoding and setting the key=value for usage in headers
+ *
+ * @author Gerry Weissbach <gerry.w@gammaproduction.de>
+ * @param string $name name of the field to be set in the header() call
+ * @param string $value value of the field to be set in the header() call
+ * @param string $charset used charset for the encoding of value
+ * @param string $lang language used.
+ * @return string in the format " name=value" for values WITHOUT special characters
+ * @return string in the format " name*=charset'lang'value" for values WITH special characters
+ */
+function rfc2231_encode($name, $value, $charset='utf-8', $lang='en') {
+ $internal = preg_replace_callback(
+ '/[\x00-\x20*\'%()<>@,;:\\\\"\/[\]?=\x80-\xFF]/',
+ function ($match) {
+ return rawurlencode($match[0]);
+ },
+ $value
+ );
+ if ( $value != $internal ) {
+ return ' '.$name.'*='.$charset."'".$lang."'".$internal;
+ } else {
+ return ' '.$name.'="'.$value.'"';
+ }
+}
+
+/**
+ * Check for media for preconditions and return correct status code
+ *
+ * READ: MEDIA, MIME, EXT, CACHE
+ * WRITE: MEDIA, FILE, array( STATUS, STATUSMESSAGE )
+ *
+ * @author Gerry Weissbach <gerry.w@gammaproduction.de>
+ *
+ * @param string $media reference to the media id
+ * @param string $file reference to the file variable
+ * @param string $rev
+ * @param int $width
+ * @param int $height
+ * @return array as array(STATUS, STATUSMESSAGE)
+ */
+function checkFileStatus(&$media, &$file, $rev = '', $width=0, $height=0) {
+ global $MIME, $EXT, $CACHE, $INPUT;
+
+ //media to local file
+ if(media_isexternal($media)) {
+ //check token for external image and additional for resized and cached images
+ if(media_get_token($media, $width, $height) !== $INPUT->str('tok')) {
+ return array(412, 'Precondition Failed');
+ }
+ //handle external images
+ if(strncmp($MIME, 'image/', 6) == 0) $file = media_get_from_URL($media, $EXT, $CACHE);
+ if(!$file) {
+ //download failed - redirect to original URL
+ return array(302, $media);
+ }
+ } else {
+ $media = cleanID($media);
+ if(empty($media)) {
+ return array(400, 'Bad request');
+ }
+ // check token for resized images
+ if (($width || $height) && media_get_token($media, $width, $height) !== $INPUT->str('tok')) {
+ return array(412, 'Precondition Failed');
+ }
+
+ //check permissions (namespace only)
+ if(auth_quickaclcheck(getNS($media).':X') < AUTH_READ) {
+ return array(403, 'Forbidden');
+ }
+ $file = mediaFN($media, $rev);
+ }
+
+ //check file existance
+ if(!file_exists($file)) {
+ return array(404, 'Not Found');
+ }
+
+ return array(200, null);
+}
+
+/**
+ * Returns the wanted cachetime in seconds
+ *
+ * Resolves named constants
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $cache
+ * @return int cachetime in seconds
+ */
+function calc_cache($cache) {
+ global $conf;
+
+ if(strtolower($cache) == 'nocache') return 0; //never cache
+ if(strtolower($cache) == 'recache') return $conf['cachetime']; //use standard cache
+ return -1; //cache endless
+}
diff --git a/platform/www/inc/form.php b/platform/www/inc/form.php
new file mode 100644
index 0000000..7a4d737
--- /dev/null
+++ b/platform/www/inc/form.php
@@ -0,0 +1,1105 @@
+<?php
+/**
+ * DokuWiki XHTML Form
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+
+// phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
+// phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore
+
+
+/**
+ * Class for creating simple HTML forms.
+ *
+ * The forms is built from a list of pseudo-tags (arrays with expected keys).
+ * Every pseudo-tag must have the key '_elem' set to the name of the element.
+ * When printed, the form class calls functions named 'form_$type' for each
+ * element it contains.
+ *
+ * Standard practice is for non-attribute keys in a pseudo-element to start
+ * with '_'. Other keys are HTML attributes that will be included in the element
+ * tag. That way, the element output functions can pass the pseudo-element
+ * directly to buildAttributes.
+ *
+ * See the form_make* functions later in this file.
+ *
+ * Please note that even though this class is technically deprecated (use dokuwiki\Form instead),
+ * it is still widely used in the core and the related form events. Until those have been rewritten,
+ * this will continue to be used
+ *
+ * @deprecated 2019-07-14
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+class Doku_Form {
+
+ // Form id attribute
+ public $params = array();
+
+ // Draw a border around form fields.
+ // Adds <fieldset></fieldset> around the elements
+ public $_infieldset = false;
+
+ // Hidden form fields.
+ public $_hidden = array();
+
+ // Array of pseudo-tags
+ public $_content = array();
+
+ /**
+ * Constructor
+ *
+ * Sets parameters and autoadds a security token. The old calling convention
+ * with up to four parameters is deprecated, instead the first parameter
+ * should be an array with parameters.
+ *
+ * @param mixed $params Parameters for the HTML form element; Using the deprecated
+ * calling convention this is the ID attribute of the form
+ * @param bool|string $action (optional, deprecated) submit URL, defaults to current page
+ * @param bool|string $method (optional, deprecated) 'POST' or 'GET', default is POST
+ * @param bool|string $enctype (optional, deprecated) Encoding type of the data
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function __construct($params, $action=false, $method=false, $enctype=false) {
+ if(!is_array($params)) {
+ $this->params = array('id' => $params);
+ if ($action !== false) $this->params['action'] = $action;
+ if ($method !== false) $this->params['method'] = strtolower($method);
+ if ($enctype !== false) $this->params['enctype'] = $enctype;
+ } else {
+ $this->params = $params;
+ }
+
+ if (!isset($this->params['method'])) {
+ $this->params['method'] = 'post';
+ } else {
+ $this->params['method'] = strtolower($this->params['method']);
+ }
+
+ if (!isset($this->params['action'])) {
+ $this->params['action'] = '';
+ }
+
+ $this->addHidden('sectok', getSecurityToken());
+ }
+
+ /**
+ * startFieldset
+ *
+ * Add <fieldset></fieldset> tags around fields.
+ * Usually results in a border drawn around the form.
+ *
+ * @param string $legend Label that will be printed with the border.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function startFieldset($legend) {
+ if ($this->_infieldset) {
+ $this->addElement(array('_elem'=>'closefieldset'));
+ }
+ $this->addElement(array('_elem'=>'openfieldset', '_legend'=>$legend));
+ $this->_infieldset = true;
+ }
+
+ /**
+ * endFieldset
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function endFieldset() {
+ if ($this->_infieldset) {
+ $this->addElement(array('_elem'=>'closefieldset'));
+ }
+ $this->_infieldset = false;
+ }
+
+ /**
+ * addHidden
+ *
+ * Adds a name/value pair as a hidden field.
+ * The value of the field (but not the name) will be passed to
+ * formText() before printing.
+ *
+ * @param string $name Field name.
+ * @param string $value Field value. If null, remove a previously added field.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function addHidden($name, $value) {
+ if (is_null($value))
+ unset($this->_hidden[$name]);
+ else
+ $this->_hidden[$name] = $value;
+ }
+
+ /**
+ * addElement
+ *
+ * Appends a content element to the form.
+ * The element can be either a pseudo-tag or string.
+ * If string, it is printed without escaping special chars. *
+ *
+ * @param string|array $elem Pseudo-tag or string to add to the form.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function addElement($elem) {
+ $this->_content[] = $elem;
+ }
+
+ /**
+ * insertElement
+ *
+ * Inserts a content element at a position.
+ *
+ * @param string $pos 0-based index where the element will be inserted.
+ * @param string|array $elem Pseudo-tag or string to add to the form.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function insertElement($pos, $elem) {
+ array_splice($this->_content, $pos, 0, array($elem));
+ }
+
+ /**
+ * replaceElement
+ *
+ * Replace with NULL to remove an element.
+ *
+ * @param int $pos 0-based index the element will be placed at.
+ * @param string|array $elem Pseudo-tag or string to add to the form.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function replaceElement($pos, $elem) {
+ $rep = array();
+ if (!is_null($elem)) $rep[] = $elem;
+ array_splice($this->_content, $pos, 1, $rep);
+ }
+
+ /**
+ * findElementByType
+ *
+ * Gets the position of the first of a type of element.
+ *
+ * @param string $type Element type to look for.
+ * @return int|false position of element if found, otherwise false
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function findElementByType($type) {
+ foreach ($this->_content as $pos=>$elem) {
+ if (is_array($elem) && $elem['_elem'] == $type)
+ return $pos;
+ }
+ return false;
+ }
+
+ /**
+ * findElementById
+ *
+ * Gets the position of the element with an ID attribute.
+ *
+ * @param string $id ID of the element to find.
+ * @return int|false position of element if found, otherwise false
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function findElementById($id) {
+ foreach ($this->_content as $pos=>$elem) {
+ if (is_array($elem) && isset($elem['id']) && $elem['id'] == $id)
+ return $pos;
+ }
+ return false;
+ }
+
+ /**
+ * findElementByAttribute
+ *
+ * Gets the position of the first element with a matching attribute value.
+ *
+ * @param string $name Attribute name.
+ * @param string $value Attribute value.
+ * @return int|false position of element if found, otherwise false
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function findElementByAttribute($name, $value) {
+ foreach ($this->_content as $pos=>$elem) {
+ if (is_array($elem) && isset($elem[$name]) && $elem[$name] == $value)
+ return $pos;
+ }
+ return false;
+ }
+
+ /**
+ * getElementAt
+ *
+ * Returns a reference to the element at a position.
+ * A position out-of-bounds will return either the
+ * first (underflow) or last (overflow) element.
+ *
+ * @param int $pos 0-based index
+ * @return array reference pseudo-element
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+ public function &getElementAt($pos) {
+ if ($pos < 0) $pos = count($this->_content) + $pos;
+ if ($pos < 0) $pos = 0;
+ if ($pos >= count($this->_content)) $pos = count($this->_content) - 1;
+ return $this->_content[$pos];
+ }
+
+ /**
+ * Return the assembled HTML for the form.
+ *
+ * Each element in the form will be passed to a function named
+ * 'form_$type'. The function should return the HTML to be printed.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @return string html of the form
+ */
+ public function getForm() {
+ global $lang;
+ $form = '';
+ $this->params['accept-charset'] = $lang['encoding'];
+ $form .= '<form ' . buildAttributes($this->params,false) . '><div class="no">' . DOKU_LF;
+ if (!empty($this->_hidden)) {
+ foreach ($this->_hidden as $name=>$value)
+ $form .= form_hidden(array('name'=>$name, 'value'=>$value));
+ }
+ foreach ($this->_content as $element) {
+ if (is_array($element)) {
+ $elem_type = $element['_elem'];
+ if (function_exists('form_'.$elem_type)) {
+ $form .= call_user_func('form_'.$elem_type, $element).DOKU_LF;
+ }
+ } else {
+ $form .= $element;
+ }
+ }
+ if ($this->_infieldset) $form .= form_closefieldset().DOKU_LF;
+ $form .= '</div></form>'.DOKU_LF;
+
+ return $form;
+ }
+
+ /**
+ * Print the assembled form
+ *
+ * wraps around getForm()
+ */
+ public function printForm(){
+ echo $this->getForm();
+ }
+
+ /**
+ * Add a radio set
+ *
+ * This function adds a set of radio buttons to the form. If $_POST[$name]
+ * is set, this radio is preselected, else the first radio button.
+ *
+ * @param string $name The HTML field name
+ * @param array $entries An array of entries $value => $caption
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+
+ public function addRadioSet($name, $entries) {
+ global $INPUT;
+ $value = (array_key_exists($INPUT->post->str($name), $entries)) ?
+ $INPUT->str($name) : key($entries);
+ foreach($entries as $val => $cap) {
+ $data = ($value === $val) ? array('checked' => 'checked') : array();
+ $this->addElement(form_makeRadioField($name, $val, $cap, '', '', $data));
+ }
+ }
+
+}
+
+/**
+ * form_makeTag
+ *
+ * Create a form element for a non-specific empty tag.
+ *
+ * @param string $tag Tag name.
+ * @param array $attrs Optional attributes.
+ * @return array pseudo-tag
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+function form_makeTag($tag, $attrs=array()) {
+ $elem = array('_elem'=>'tag', '_tag'=>$tag);
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makeOpenTag
+ *
+ * Create a form element for a non-specific opening tag.
+ * Remember to put a matching close tag after this as well.
+ *
+ * @param string $tag Tag name.
+ * @param array $attrs Optional attributes.
+ * @return array pseudo-tag
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+function form_makeOpenTag($tag, $attrs=array()) {
+ $elem = array('_elem'=>'opentag', '_tag'=>$tag);
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makeCloseTag
+ *
+ * Create a form element for a non-specific closing tag.
+ * Careless use of this will result in invalid XHTML.
+ *
+ * @param string $tag Tag name.
+ * @return array pseudo-tag
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+function form_makeCloseTag($tag) {
+ return array('_elem'=>'closetag', '_tag'=>$tag);
+}
+
+/**
+ * form_makeWikiText
+ *
+ * Create a form element for a textarea containing wiki text.
+ * Only one wikitext element is allowed on a page. It will have
+ * a name of 'wikitext' and id 'wiki__text'. The text will
+ * be passed to formText() before printing.
+ *
+ * @param string $text Text to fill the field with.
+ * @param array $attrs Optional attributes.
+ * @return array pseudo-tag
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+function form_makeWikiText($text, $attrs=array()) {
+ $elem = array('_elem'=>'wikitext', '_text'=>$text,
+ 'class'=>'edit', 'cols'=>'80', 'rows'=>'10');
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makeButton
+ *
+ * Create a form element for an action button.
+ * A title will automatically be generated using the value and
+ * accesskey attributes, unless you provide one.
+ *
+ * @param string $type Type attribute. 'submit' or 'cancel'
+ * @param string $act Wiki action of the button, will be used as the do= parameter
+ * @param string $value (optional) Displayed label. Uses $act if not provided.
+ * @param array $attrs Optional attributes.
+ * @return array pseudo-tag
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+function form_makeButton($type, $act, $value='', $attrs=array()) {
+ if ($value == '') $value = $act;
+ $elem = array('_elem'=>'button', 'type'=>$type, '_action'=>$act,
+ 'value'=>$value);
+ if (!empty($attrs['accesskey']) && empty($attrs['title'])) {
+ $attrs['title'] = $value . ' ['.strtoupper($attrs['accesskey']).']';
+ }
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makeField
+ *
+ * Create a form element for a labelled input element.
+ * The label text will be printed before the input.
+ *
+ * @param string $type Type attribute of input.
+ * @param string $name Name attribute of the input.
+ * @param string $value (optional) Default value.
+ * @param string $class Class attribute of the label. If this is 'block',
+ * then a line break will be added after the field.
+ * @param string $label Label that will be printed before the input.
+ * @param string $id ID attribute of the input. If set, the label will
+ * reference it with a 'for' attribute.
+ * @param array $attrs Optional attributes.
+ * @return array pseudo-tag
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+function form_makeField($type, $name, $value='', $label=null, $id='', $class='', $attrs=array()) {
+ if (is_null($label)) $label = $name;
+ $elem = array('_elem'=>'field', '_text'=>$label, '_class'=>$class,
+ 'type'=>$type, 'id'=>$id, 'name'=>$name, 'value'=>$value);
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makeFieldRight
+ *
+ * Create a form element for a labelled input element.
+ * The label text will be printed after the input.
+ *
+ * @see form_makeField
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $type
+ * @param string $name
+ * @param string $value
+ * @param null|string $label
+ * @param string $id
+ * @param string $class
+ * @param array $attrs
+ *
+ * @return array
+ */
+function form_makeFieldRight($type, $name, $value='', $label=null, $id='', $class='', $attrs=array()) {
+ if (is_null($label)) $label = $name;
+ $elem = array('_elem'=>'fieldright', '_text'=>$label, '_class'=>$class,
+ 'type'=>$type, 'id'=>$id, 'name'=>$name, 'value'=>$value);
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makeTextField
+ *
+ * Create a form element for a text input element with label.
+ *
+ * @see form_makeField
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $name
+ * @param string $value
+ * @param null|string $label
+ * @param string $id
+ * @param string $class
+ * @param array $attrs
+ *
+ * @return array
+ */
+function form_makeTextField($name, $value='', $label=null, $id='', $class='', $attrs=array()) {
+ if (is_null($label)) $label = $name;
+ $elem = array('_elem'=>'textfield', '_text'=>$label, '_class'=>$class,
+ 'id'=>$id, 'name'=>$name, 'value'=>$value, 'class'=>'edit');
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makePasswordField
+ *
+ * Create a form element for a password input element with label.
+ * Password elements have no default value, for obvious reasons.
+ *
+ * @see form_makeField
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $name
+ * @param null|string $label
+ * @param string $id
+ * @param string $class
+ * @param array $attrs
+ *
+ * @return array
+ */
+function form_makePasswordField($name, $label=null, $id='', $class='', $attrs=array()) {
+ if (is_null($label)) $label = $name;
+ $elem = array('_elem'=>'passwordfield', '_text'=>$label, '_class'=>$class,
+ 'id'=>$id, 'name'=>$name, 'class'=>'edit');
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makeFileField
+ *
+ * Create a form element for a file input element with label
+ *
+ * @see form_makeField
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param string $name
+ * @param null|string $label
+ * @param string $id
+ * @param string $class
+ * @param array $attrs
+ *
+ * @return array
+ */
+function form_makeFileField($name, $label=null, $id='', $class='', $attrs=array()) {
+ if (is_null($label)) $label = $name;
+ $elem = array('_elem'=>'filefield', '_text'=>$label, '_class'=>$class,
+ 'id'=>$id, 'name'=>$name, 'class'=>'edit');
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makeCheckboxField
+ *
+ * Create a form element for a checkbox input element with label.
+ * If $value is an array, a hidden field with the same name and the value
+ * $value[1] is constructed as well.
+ *
+ * @see form_makeFieldRight
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $name
+ * @param string $value
+ * @param null|string $label
+ * @param string $id
+ * @param string $class
+ * @param array $attrs
+ *
+ * @return array
+ */
+function form_makeCheckboxField($name, $value='1', $label=null, $id='', $class='', $attrs=array()) {
+ if (is_null($label)) $label = $name;
+ if (is_null($value) || $value=='') $value='0';
+ $elem = array('_elem'=>'checkboxfield', '_text'=>$label, '_class'=>$class,
+ 'id'=>$id, 'name'=>$name, 'value'=>$value);
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makeRadioField
+ *
+ * Create a form element for a radio button input element with label.
+ *
+ * @see form_makeFieldRight
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $name
+ * @param string $value
+ * @param null|string $label
+ * @param string $id
+ * @param string $class
+ * @param array $attrs
+ *
+ * @return array
+ */
+function form_makeRadioField($name, $value='1', $label=null, $id='', $class='', $attrs=array()) {
+ if (is_null($label)) $label = $name;
+ if (is_null($value) || $value=='') $value='0';
+ $elem = array('_elem'=>'radiofield', '_text'=>$label, '_class'=>$class,
+ 'id'=>$id, 'name'=>$name, 'value'=>$value);
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makeMenuField
+ *
+ * Create a form element for a drop-down menu with label.
+ * The list of values can be strings, arrays of (value,text),
+ * or an associative array with the values as keys and labels as values.
+ * An item is selected by supplying its value or integer index.
+ * If the list of values is an associative array, the selected item must be
+ * a string.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $name Name attribute of the input.
+ * @param string[]|array[] $values The list of values can be strings, arrays of (value,text),
+ * or an associative array with the values as keys and labels as values.
+ * @param string|int $selected default selected value, string or index number
+ * @param string $class Class attribute of the label. If this is 'block',
+ * then a line break will be added after the field.
+ * @param string $label Label that will be printed before the input.
+ * @param string $id ID attribute of the input. If set, the label will
+ * reference it with a 'for' attribute.
+ * @param array $attrs Optional attributes.
+ * @return array pseudo-tag
+ */
+function form_makeMenuField($name, $values, $selected='', $label=null, $id='', $class='', $attrs=array()) {
+ if (is_null($label)) $label = $name;
+ $options = array();
+ reset($values);
+ // FIXME: php doesn't know the difference between a string and an integer
+ if (is_string(key($values))) {
+ foreach ($values as $val=>$text) {
+ $options[] = array($val,$text, (!is_null($selected) && $val==$selected));
+ }
+ } else {
+ if (is_integer($selected)) $selected = $values[$selected];
+ foreach ($values as $val) {
+ if (is_array($val))
+ @list($val,$text) = $val;
+ else
+ $text = null;
+ $options[] = array($val,$text,$val===$selected);
+ }
+ }
+ $elem = array('_elem'=>'menufield', '_options'=>$options, '_text'=>$label, '_class'=>$class,
+ 'id'=>$id, 'name'=>$name);
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_makeListboxField
+ *
+ * Create a form element for a list box with label.
+ * The list of values can be strings, arrays of (value,text),
+ * or an associative array with the values as keys and labels as values.
+ * Items are selected by supplying its value or an array of values.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $name Name attribute of the input.
+ * @param string[]|array[] $values The list of values can be strings, arrays of (value,text),
+ * or an associative array with the values as keys and labels as values.
+ * @param array|string $selected value or array of values of the items that need to be selected
+ * @param string $class Class attribute of the label. If this is 'block',
+ * then a line break will be added after the field.
+ * @param string $label Label that will be printed before the input.
+ * @param string $id ID attribute of the input. If set, the label will
+ * reference it with a 'for' attribute.
+ * @param array $attrs Optional attributes.
+ * @return array pseudo-tag
+ */
+function form_makeListboxField($name, $values, $selected='', $label=null, $id='', $class='', $attrs=array()) {
+ if (is_null($label)) $label = $name;
+ $options = array();
+ reset($values);
+ if (is_null($selected) || $selected == '') {
+ $selected = array();
+ } elseif (!is_array($selected)) {
+ $selected = array($selected);
+ }
+ // FIXME: php doesn't know the difference between a string and an integer
+ if (is_string(key($values))) {
+ foreach ($values as $val=>$text) {
+ $options[] = array($val,$text,in_array($val,$selected));
+ }
+ } else {
+ foreach ($values as $val) {
+ $disabled = false;
+ if (is_array($val)) {
+ @list($val,$text,$disabled) = $val;
+ } else {
+ $text = null;
+ }
+ $options[] = array($val,$text,in_array($val,$selected),$disabled);
+ }
+ }
+ $elem = array('_elem'=>'listboxfield', '_options'=>$options, '_text'=>$label, '_class'=>$class,
+ 'id'=>$id, 'name'=>$name);
+ return array_merge($elem, $attrs);
+}
+
+/**
+ * form_tag
+ *
+ * Print the HTML for a generic empty tag.
+ * Requires '_tag' key with name of the tag.
+ * Attributes are passed to buildAttributes()
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html of tag
+ */
+function form_tag($attrs) {
+ return '<'.$attrs['_tag'].' '.buildAttributes($attrs,true).'/>';
+}
+
+/**
+ * form_opentag
+ *
+ * Print the HTML for a generic opening tag.
+ * Requires '_tag' key with name of the tag.
+ * Attributes are passed to buildAttributes()
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html of tag
+ */
+function form_opentag($attrs) {
+ return '<'.$attrs['_tag'].' '.buildAttributes($attrs,true).'>';
+}
+
+/**
+ * form_closetag
+ *
+ * Print the HTML for a generic closing tag.
+ * Requires '_tag' key with name of the tag.
+ * There are no attributes.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html of tag
+ */
+function form_closetag($attrs) {
+ return '</'.$attrs['_tag'].'>';
+}
+
+/**
+ * form_openfieldset
+ *
+ * Print the HTML for an opening fieldset tag.
+ * Uses the '_legend' key.
+ * Attributes are passed to buildAttributes()
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_openfieldset($attrs) {
+ $s = '<fieldset '.buildAttributes($attrs,true).'>';
+ if (!is_null($attrs['_legend'])) $s .= '<legend>'.$attrs['_legend'].'</legend>';
+ return $s;
+}
+
+/**
+ * form_closefieldset
+ *
+ * Print the HTML for a closing fieldset tag.
+ * There are no attributes.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @return string html
+ */
+function form_closefieldset() {
+ return '</fieldset>';
+}
+
+/**
+ * form_hidden
+ *
+ * Print the HTML for a hidden input element.
+ * Uses only 'name' and 'value' attributes.
+ * Value is passed to formText()
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_hidden($attrs) {
+ return '<input type="hidden" name="'.$attrs['name'].'" value="'.formText($attrs['value']).'" />';
+}
+
+/**
+ * form_wikitext
+ *
+ * Print the HTML for the wiki textarea.
+ * Requires '_text' with default text of the field.
+ * Text will be passed to formText(), attributes to buildAttributes()
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_wikitext($attrs) {
+ // mandatory attributes
+ unset($attrs['name']);
+ unset($attrs['id']);
+ return '<textarea name="wikitext" id="wiki__text" dir="auto" '
+ .buildAttributes($attrs,true).'>'.DOKU_LF
+ .formText($attrs['_text'])
+ .'</textarea>';
+}
+
+/**
+ * form_button
+ *
+ * Print the HTML for a form button.
+ * If '_action' is set, the button name will be "do[_action]".
+ * Other attributes are passed to buildAttributes()
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_button($attrs) {
+ $p = (!empty($attrs['_action'])) ? 'name="do['.$attrs['_action'].']" ' : '';
+ $value = $attrs['value'];
+ unset($attrs['value']);
+ return '<button '.$p.buildAttributes($attrs,true).'>'.$value.'</button>';
+}
+
+/**
+ * form_field
+ *
+ * Print the HTML for a form input field.
+ * _class : class attribute used on the label tag
+ * _text : Text to display before the input. Not escaped.
+ * Other attributes are passed to buildAttributes() for the input tag.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_field($attrs) {
+ $s = '<label';
+ if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"';
+ if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
+ $s .= '><span>'.$attrs['_text'].'</span>';
+ $s .= ' <input '.buildAttributes($attrs,true).' /></label>';
+ if (preg_match('/(^| )block($| )/', $attrs['_class']))
+ $s .= '<br />';
+ return $s;
+}
+
+/**
+ * form_fieldright
+ *
+ * Print the HTML for a form input field. (right-aligned)
+ * _class : class attribute used on the label tag
+ * _text : Text to display after the input. Not escaped.
+ * Other attributes are passed to buildAttributes() for the input tag.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_fieldright($attrs) {
+ $s = '<label';
+ if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"';
+ if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
+ $s .= '><input '.buildAttributes($attrs,true).' />';
+ $s .= ' <span>'.$attrs['_text'].'</span></label>';
+ if (preg_match('/(^| )block($| )/', $attrs['_class']))
+ $s .= '<br />';
+ return $s;
+}
+
+/**
+ * form_textfield
+ *
+ * Print the HTML for a text input field.
+ * _class : class attribute used on the label tag
+ * _text : Text to display before the input. Not escaped.
+ * Other attributes are passed to buildAttributes() for the input tag.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_textfield($attrs) {
+ // mandatory attributes
+ unset($attrs['type']);
+ $s = '<label';
+ if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"';
+ if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
+ $s .= '><span>'.$attrs['_text'].'</span> ';
+ $s .= '<input type="text" '.buildAttributes($attrs,true).' /></label>';
+ if (preg_match('/(^| )block($| )/', $attrs['_class']))
+ $s .= '<br />';
+ return $s;
+}
+
+/**
+ * form_passwordfield
+ *
+ * Print the HTML for a password input field.
+ * _class : class attribute used on the label tag
+ * _text : Text to display before the input. Not escaped.
+ * Other attributes are passed to buildAttributes() for the input tag.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_passwordfield($attrs) {
+ // mandatory attributes
+ unset($attrs['type']);
+ $s = '<label';
+ if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"';
+ if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
+ $s .= '><span>'.$attrs['_text'].'</span> ';
+ $s .= '<input type="password" '.buildAttributes($attrs,true).' /></label>';
+ if (preg_match('/(^| )block($| )/', $attrs['_class']))
+ $s .= '<br />';
+ return $s;
+}
+
+/**
+ * form_filefield
+ *
+ * Print the HTML for a file input field.
+ * _class : class attribute used on the label tag
+ * _text : Text to display before the input. Not escaped
+ * _maxlength : Allowed size in byte
+ * _accept : Accepted mime-type
+ * Other attributes are passed to buildAttributes() for the input tag
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_filefield($attrs) {
+ $s = '<label';
+ if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"';
+ if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
+ $s .= '><span>'.$attrs['_text'].'</span> ';
+ $s .= '<input type="file" '.buildAttributes($attrs,true);
+ if (!empty($attrs['_maxlength'])) $s .= ' maxlength="'.$attrs['_maxlength'].'"';
+ if (!empty($attrs['_accept'])) $s .= ' accept="'.$attrs['_accept'].'"';
+ $s .= ' /></label>';
+ if (preg_match('/(^| )block($| )/', $attrs['_class']))
+ $s .= '<br />';
+ return $s;
+}
+
+/**
+ * form_checkboxfield
+ *
+ * Print the HTML for a checkbox input field.
+ * _class : class attribute used on the label tag
+ * _text : Text to display after the input. Not escaped.
+ * Other attributes are passed to buildAttributes() for the input tag.
+ * If value is an array, a hidden field with the same name and the value
+ * $attrs['value'][1] is constructed as well.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_checkboxfield($attrs) {
+ // mandatory attributes
+ unset($attrs['type']);
+ $s = '<label';
+ if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"';
+ if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
+ $s .= '>';
+ if (is_array($attrs['value'])) {
+ echo '<input type="hidden" name="' . hsc($attrs['name']) .'"'
+ . ' value="' . hsc($attrs['value'][1]) . '" />';
+ $attrs['value'] = $attrs['value'][0];
+ }
+ $s .= '<input type="checkbox" '.buildAttributes($attrs,true).' />';
+ $s .= ' <span>'.$attrs['_text'].'</span></label>';
+ if (preg_match('/(^| )block($| )/', $attrs['_class']))
+ $s .= '<br />';
+ return $s;
+}
+
+/**
+ * form_radiofield
+ *
+ * Print the HTML for a radio button input field.
+ * _class : class attribute used on the label tag
+ * _text : Text to display after the input. Not escaped.
+ * Other attributes are passed to buildAttributes() for the input tag.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_radiofield($attrs) {
+ // mandatory attributes
+ unset($attrs['type']);
+ $s = '<label';
+ if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"';
+ if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
+ $s .= '><input type="radio" '.buildAttributes($attrs,true).' />';
+ $s .= ' <span>'.$attrs['_text'].'</span></label>';
+ if (preg_match('/(^| )block($| )/', $attrs['_class']))
+ $s .= '<br />';
+ return $s;
+}
+
+/**
+ * form_menufield
+ *
+ * Print the HTML for a drop-down menu.
+ * _options : Array of (value,text,selected) for the menu.
+ * Text can be omitted. Text and value are passed to formText()
+ * Only one item can be selected.
+ * _class : class attribute used on the label tag
+ * _text : Text to display before the menu. Not escaped.
+ * Other attributes are passed to buildAttributes() for the input tag.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_menufield($attrs) {
+ $attrs['size'] = '1';
+ $s = '<label';
+ if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"';
+ if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
+ $s .= '><span>'.$attrs['_text'].'</span>';
+ $s .= ' <select '.buildAttributes($attrs,true).'>'.DOKU_LF;
+ if (!empty($attrs['_options'])) {
+ $selected = false;
+
+ $cnt = count($attrs['_options']);
+ for($n=0; $n < $cnt; $n++){
+ @list($value,$text,$select) = $attrs['_options'][$n];
+ $p = '';
+ if (!is_null($text))
+ $p .= ' value="'.formText($value).'"';
+ else
+ $text = $value;
+ if (!empty($select) && !$selected) {
+ $p .= ' selected="selected"';
+ $selected = true;
+ }
+ $s .= '<option'.$p.'>'.formText($text).'</option>';
+ }
+ } else {
+ $s .= '<option></option>';
+ }
+ $s .= DOKU_LF.'</select></label>';
+ if (preg_match('/(^| )block($| )/', $attrs['_class']))
+ $s .= '<br />';
+ return $s;
+}
+
+/**
+ * form_listboxfield
+ *
+ * Print the HTML for a list box.
+ * _options : Array of (value,text,selected) for the list.
+ * Text can be omitted. Text and value are passed to formText()
+ * _class : class attribute used on the label tag
+ * _text : Text to display before the menu. Not escaped.
+ * Other attributes are passed to buildAttributes() for the input tag.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param array $attrs attributes
+ * @return string html
+ */
+function form_listboxfield($attrs) {
+ $s = '<label';
+ if ($attrs['_class']) $s .= ' class="'.$attrs['_class'].'"';
+ if (!empty($attrs['id'])) $s .= ' for="'.$attrs['id'].'"';
+ $s .= '><span>'.$attrs['_text'].'</span> ';
+ $s .= '<select '.buildAttributes($attrs,true).'>'.DOKU_LF;
+ if (!empty($attrs['_options'])) {
+ foreach ($attrs['_options'] as $opt) {
+ @list($value,$text,$select,$disabled) = $opt;
+ $p = '';
+ if(is_null($text)) $text = $value;
+ $p .= ' value="'.formText($value).'"';
+ if (!empty($select)) $p .= ' selected="selected"';
+ if ($disabled) $p .= ' disabled="disabled"';
+ $s .= '<option'.$p.'>'.formText($text).'</option>';
+ }
+ } else {
+ $s .= '<option></option>';
+ }
+ $s .= DOKU_LF.'</select></label>';
+ if (preg_match('/(^| )block($| )/', $attrs['_class']))
+ $s .= '<br />';
+ return $s;
+}
diff --git a/platform/www/inc/fulltext.php b/platform/www/inc/fulltext.php
new file mode 100644
index 0000000..670f048
--- /dev/null
+++ b/platform/www/inc/fulltext.php
@@ -0,0 +1,933 @@
+<?php
+/**
+ * DokuWiki fulltextsearch functions using the index
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Extension\Event;
+
+/**
+ * create snippets for the first few results only
+ */
+if(!defined('FT_SNIPPET_NUMBER')) define('FT_SNIPPET_NUMBER',15);
+
+/**
+ * The fulltext search
+ *
+ * Returns a list of matching documents for the given query
+ *
+ * refactored into ft_pageSearch(), _ft_pageSearch() and trigger_event()
+ *
+ * @param string $query
+ * @param array $highlight
+ * @param string $sort
+ * @param int|string $after only show results with mtime after this date, accepts timestap or strtotime arguments
+ * @param int|string $before only show results with mtime before this date, accepts timestap or strtotime arguments
+ *
+ * @return array
+ */
+function ft_pageSearch($query,&$highlight, $sort = null, $after = null, $before = null){
+
+ if ($sort === null) {
+ $sort = 'hits';
+ }
+ $data = [
+ 'query' => $query,
+ 'sort' => $sort,
+ 'after' => $after,
+ 'before' => $before
+ ];
+ $data['highlight'] =& $highlight;
+
+ return Event::createAndTrigger('SEARCH_QUERY_FULLPAGE', $data, '_ft_pageSearch');
+}
+
+/**
+ * Returns a list of matching documents for the given query
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ *
+ * @param array $data event data
+ * @return array matching documents
+ */
+function _ft_pageSearch(&$data) {
+ $Indexer = idx_get_indexer();
+
+ // parse the given query
+ $q = ft_queryParser($Indexer, $data['query']);
+ $data['highlight'] = $q['highlight'];
+
+ if (empty($q['parsed_ary'])) return array();
+
+ // lookup all words found in the query
+ $lookup = $Indexer->lookup($q['words']);
+
+ // get all pages in this dokuwiki site (!: includes nonexistent pages)
+ $pages_all = array();
+ foreach ($Indexer->getPages() as $id) {
+ $pages_all[$id] = 0; // base: 0 hit
+ }
+
+ // process the query
+ $stack = array();
+ foreach ($q['parsed_ary'] as $token) {
+ switch (substr($token, 0, 3)) {
+ case 'W+:':
+ case 'W-:':
+ case 'W_:': // word
+ $word = substr($token, 3);
+ $stack[] = (array) $lookup[$word];
+ break;
+ case 'P+:':
+ case 'P-:': // phrase
+ $phrase = substr($token, 3);
+ // since phrases are always parsed as ((W1)(W2)...(P)),
+ // the end($stack) always points the pages that contain
+ // all words in this phrase
+ $pages = end($stack);
+ $pages_matched = array();
+ foreach(array_keys($pages) as $id){
+ $evdata = array(
+ 'id' => $id,
+ 'phrase' => $phrase,
+ 'text' => rawWiki($id)
+ );
+ $evt = new Event('FULLTEXT_PHRASE_MATCH',$evdata);
+ if ($evt->advise_before() && $evt->result !== true) {
+ $text = \dokuwiki\Utf8\PhpString::strtolower($evdata['text']);
+ if (strpos($text, $phrase) !== false) {
+ $evt->result = true;
+ }
+ }
+ $evt->advise_after();
+ if ($evt->result === true) {
+ $pages_matched[$id] = 0; // phrase: always 0 hit
+ }
+ }
+ $stack[] = $pages_matched;
+ break;
+ case 'N+:':
+ case 'N-:': // namespace
+ $ns = cleanID(substr($token, 3)) . ':';
+ $pages_matched = array();
+ foreach (array_keys($pages_all) as $id) {
+ if (strpos($id, $ns) === 0) {
+ $pages_matched[$id] = 0; // namespace: always 0 hit
+ }
+ }
+ $stack[] = $pages_matched;
+ break;
+ case 'AND': // and operation
+ list($pages1, $pages2) = array_splice($stack, -2);
+ $stack[] = ft_resultCombine(array($pages1, $pages2));
+ break;
+ case 'OR': // or operation
+ list($pages1, $pages2) = array_splice($stack, -2);
+ $stack[] = ft_resultUnite(array($pages1, $pages2));
+ break;
+ case 'NOT': // not operation (unary)
+ $pages = array_pop($stack);
+ $stack[] = ft_resultComplement(array($pages_all, $pages));
+ break;
+ }
+ }
+ $docs = array_pop($stack);
+
+ if (empty($docs)) return array();
+
+ // check: settings, acls, existence
+ foreach (array_keys($docs) as $id) {
+ if (isHiddenPage($id) || auth_quickaclcheck($id) < AUTH_READ || !page_exists($id, '', false)) {
+ unset($docs[$id]);
+ }
+ }
+
+ $docs = _ft_filterResultsByTime($docs, $data['after'], $data['before']);
+
+ if ($data['sort'] === 'mtime') {
+ uksort($docs, 'ft_pagemtimesorter');
+ } else {
+ // sort docs by count
+ arsort($docs);
+ }
+
+ return $docs;
+}
+
+/**
+ * Returns the backlinks for a given page
+ *
+ * Uses the metadata index.
+ *
+ * @param string $id The id for which links shall be returned
+ * @param bool $ignore_perms Ignore the fact that pages are hidden or read-protected
+ * @return array The pages that contain links to the given page
+ */
+function ft_backlinks($id, $ignore_perms = false){
+ $result = idx_get_indexer()->lookupKey('relation_references', $id);
+
+ if(!count($result)) return $result;
+
+ // check ACL permissions
+ foreach(array_keys($result) as $idx){
+ if(($ignore_perms !== true && (
+ isHiddenPage($result[$idx]) || auth_quickaclcheck($result[$idx]) < AUTH_READ
+ )) || !page_exists($result[$idx], '', false)){
+ unset($result[$idx]);
+ }
+ }
+
+ sort($result);
+ return $result;
+}
+
+/**
+ * Returns the pages that use a given media file
+ *
+ * Uses the relation media metadata property and the metadata index.
+ *
+ * Note that before 2013-07-31 the second parameter was the maximum number of results and
+ * permissions were ignored. That's why the parameter is now checked to be explicitely set
+ * to true (with type bool) in order to be compatible with older uses of the function.
+ *
+ * @param string $id The media id to look for
+ * @param bool $ignore_perms Ignore hidden pages and acls (optional, default: false)
+ * @return array A list of pages that use the given media file
+ */
+function ft_mediause($id, $ignore_perms = false){
+ $result = idx_get_indexer()->lookupKey('relation_media', $id);
+
+ if(!count($result)) return $result;
+
+ // check ACL permissions
+ foreach(array_keys($result) as $idx){
+ if(($ignore_perms !== true && (
+ isHiddenPage($result[$idx]) || auth_quickaclcheck($result[$idx]) < AUTH_READ
+ )) || !page_exists($result[$idx], '', false)){
+ unset($result[$idx]);
+ }
+ }
+
+ sort($result);
+ return $result;
+}
+
+
+/**
+ * Quicksearch for pagenames
+ *
+ * By default it only matches the pagename and ignores the
+ * namespace. This can be changed with the second parameter.
+ * The third parameter allows to search in titles as well.
+ *
+ * The function always returns titles as well
+ *
+ * @triggers SEARCH_QUERY_PAGELOOKUP
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $id page id
+ * @param bool $in_ns match against namespace as well?
+ * @param bool $in_title search in title?
+ * @param int|string $after only show results with mtime after this date, accepts timestap or strtotime arguments
+ * @param int|string $before only show results with mtime before this date, accepts timestap or strtotime arguments
+ *
+ * @return string[]
+ */
+function ft_pageLookup($id, $in_ns=false, $in_title=false, $after = null, $before = null){
+ $data = [
+ 'id' => $id,
+ 'in_ns' => $in_ns,
+ 'in_title' => $in_title,
+ 'after' => $after,
+ 'before' => $before
+ ];
+ $data['has_titles'] = true; // for plugin backward compatibility check
+ return Event::createAndTrigger('SEARCH_QUERY_PAGELOOKUP', $data, '_ft_pageLookup');
+}
+
+/**
+ * Returns list of pages as array(pageid => First Heading)
+ *
+ * @param array &$data event data
+ * @return string[]
+ */
+function _ft_pageLookup(&$data){
+ // split out original parameters
+ $id = $data['id'];
+ $Indexer = idx_get_indexer();
+ $parsedQuery = ft_queryParser($Indexer, $id);
+ if (count($parsedQuery['ns']) > 0) {
+ $ns = cleanID($parsedQuery['ns'][0]) . ':';
+ $id = implode(' ', $parsedQuery['highlight']);
+ }
+
+ $in_ns = $data['in_ns'];
+ $in_title = $data['in_title'];
+ $cleaned = cleanID($id);
+
+ $Indexer = idx_get_indexer();
+ $page_idx = $Indexer->getPages();
+
+ $pages = array();
+ if ($id !== '' && $cleaned !== '') {
+ foreach ($page_idx as $p_id) {
+ if ((strpos($in_ns ? $p_id : noNSorNS($p_id), $cleaned) !== false)) {
+ if (!isset($pages[$p_id]))
+ $pages[$p_id] = p_get_first_heading($p_id, METADATA_DONT_RENDER);
+ }
+ }
+ if ($in_title) {
+ foreach ($Indexer->lookupKey('title', $id, '_ft_pageLookupTitleCompare') as $p_id) {
+ if (!isset($pages[$p_id]))
+ $pages[$p_id] = p_get_first_heading($p_id, METADATA_DONT_RENDER);
+ }
+ }
+ }
+
+ if (isset($ns)) {
+ foreach (array_keys($pages) as $p_id) {
+ if (strpos($p_id, $ns) !== 0) {
+ unset($pages[$p_id]);
+ }
+ }
+ }
+
+ // discard hidden pages
+ // discard nonexistent pages
+ // check ACL permissions
+ foreach(array_keys($pages) as $idx){
+ if(!isVisiblePage($idx) || !page_exists($idx) ||
+ auth_quickaclcheck($idx) < AUTH_READ) {
+ unset($pages[$idx]);
+ }
+ }
+
+ $pages = _ft_filterResultsByTime($pages, $data['after'], $data['before']);
+
+ uksort($pages,'ft_pagesorter');
+ return $pages;
+}
+
+
+/**
+ * @param array $results search results in the form pageid => value
+ * @param int|string $after only returns results with mtime after this date, accepts timestap or strtotime arguments
+ * @param int|string $before only returns results with mtime after this date, accepts timestap or strtotime arguments
+ *
+ * @return array
+ */
+function _ft_filterResultsByTime(array $results, $after, $before) {
+ if ($after || $before) {
+ $after = is_int($after) ? $after : strtotime($after);
+ $before = is_int($before) ? $before : strtotime($before);
+
+ foreach ($results as $id => $value) {
+ $mTime = filemtime(wikiFN($id));
+ if ($after && $after > $mTime) {
+ unset($results[$id]);
+ continue;
+ }
+ if ($before && $before < $mTime) {
+ unset($results[$id]);
+ }
+ }
+ }
+
+ return $results;
+}
+
+/**
+ * Tiny helper function for comparing the searched title with the title
+ * from the search index. This function is a wrapper around stripos with
+ * adapted argument order and return value.
+ *
+ * @param string $search searched title
+ * @param string $title title from index
+ * @return bool
+ */
+function _ft_pageLookupTitleCompare($search, $title) {
+ return stripos($title, $search) !== false;
+}
+
+/**
+ * Sort pages based on their namespace level first, then on their string
+ * values. This makes higher hierarchy pages rank higher than lower hierarchy
+ * pages.
+ *
+ * @param string $a
+ * @param string $b
+ * @return int Returns < 0 if $a is less than $b; > 0 if $a is greater than $b, and 0 if they are equal.
+ */
+function ft_pagesorter($a, $b){
+ $ac = count(explode(':',$a));
+ $bc = count(explode(':',$b));
+ if($ac < $bc){
+ return -1;
+ }elseif($ac > $bc){
+ return 1;
+ }
+ return strcmp ($a,$b);
+}
+
+/**
+ * Sort pages by their mtime, from newest to oldest
+ *
+ * @param string $a
+ * @param string $b
+ *
+ * @return int Returns < 0 if $a is newer than $b, > 0 if $b is newer than $a and 0 if they are of the same age
+ */
+function ft_pagemtimesorter($a, $b) {
+ $mtimeA = filemtime(wikiFN($a));
+ $mtimeB = filemtime(wikiFN($b));
+ return $mtimeB - $mtimeA;
+}
+
+/**
+ * Creates a snippet extract
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @triggers FULLTEXT_SNIPPET_CREATE
+ *
+ * @param string $id page id
+ * @param array $highlight
+ * @return mixed
+ */
+function ft_snippet($id,$highlight){
+ $text = rawWiki($id);
+ $text = str_replace("\xC2\xAD",'',$text); // remove soft-hyphens
+ $evdata = array(
+ 'id' => $id,
+ 'text' => &$text,
+ 'highlight' => &$highlight,
+ 'snippet' => '',
+ );
+
+ $evt = new Event('FULLTEXT_SNIPPET_CREATE',$evdata);
+ if ($evt->advise_before()) {
+ $match = array();
+ $snippets = array();
+ $utf8_offset = $offset = $end = 0;
+ $len = \dokuwiki\Utf8\PhpString::strlen($text);
+
+ // build a regexp from the phrases to highlight
+ $re1 = '(' .
+ join(
+ '|',
+ array_map(
+ 'ft_snippet_re_preprocess',
+ array_map(
+ 'preg_quote_cb',
+ array_filter((array) $highlight)
+ )
+ )
+ ) .
+ ')';
+ $re2 = "$re1.{0,75}(?!\\1)$re1";
+ $re3 = "$re1.{0,45}(?!\\1)$re1.{0,45}(?!\\1)(?!\\2)$re1";
+
+ for ($cnt=4; $cnt--;) {
+ if (0) {
+ } else if (preg_match('/'.$re3.'/iu',$text,$match,PREG_OFFSET_CAPTURE,$offset)) {
+ } else if (preg_match('/'.$re2.'/iu',$text,$match,PREG_OFFSET_CAPTURE,$offset)) {
+ } else if (preg_match('/'.$re1.'/iu',$text,$match,PREG_OFFSET_CAPTURE,$offset)) {
+ } else {
+ break;
+ }
+
+ list($str,$idx) = $match[0];
+
+ // convert $idx (a byte offset) into a utf8 character offset
+ $utf8_idx = \dokuwiki\Utf8\PhpString::strlen(substr($text,0,$idx));
+ $utf8_len = \dokuwiki\Utf8\PhpString::strlen($str);
+
+ // establish context, 100 bytes surrounding the match string
+ // first look to see if we can go 100 either side,
+ // then drop to 50 adding any excess if the other side can't go to 50,
+ $pre = min($utf8_idx-$utf8_offset,100);
+ $post = min($len-$utf8_idx-$utf8_len,100);
+
+ if ($pre>50 && $post>50) {
+ $pre = $post = 50;
+ } else if ($pre>50) {
+ $pre = min($pre,100-$post);
+ } else if ($post>50) {
+ $post = min($post, 100-$pre);
+ } else if ($offset == 0) {
+ // both are less than 50, means the context is the whole string
+ // make it so and break out of this loop - there is no need for the
+ // complex snippet calculations
+ $snippets = array($text);
+ break;
+ }
+
+ // establish context start and end points, try to append to previous
+ // context if possible
+ $start = $utf8_idx - $pre;
+ $append = ($start < $end) ? $end : false; // still the end of the previous context snippet
+ $end = $utf8_idx + $utf8_len + $post; // now set it to the end of this context
+
+ if ($append) {
+ $snippets[count($snippets)-1] .= \dokuwiki\Utf8\PhpString::substr($text,$append,$end-$append);
+ } else {
+ $snippets[] = \dokuwiki\Utf8\PhpString::substr($text,$start,$end-$start);
+ }
+
+ // set $offset for next match attempt
+ // continue matching after the current match
+ // if the current match is not the longest possible match starting at the current offset
+ // this prevents further matching of this snippet but for possible matches of length
+ // smaller than match length + context (at least 50 characters) this match is part of the context
+ $utf8_offset = $utf8_idx + $utf8_len;
+ $offset = $idx + strlen(\dokuwiki\Utf8\PhpString::substr($text,$utf8_idx,$utf8_len));
+ $offset = \dokuwiki\Utf8\Clean::correctIdx($text,$offset);
+ }
+
+ $m = "\1";
+ $snippets = preg_replace('/'.$re1.'/iu',$m.'$1'.$m,$snippets);
+ $snippet = preg_replace(
+ '/' . $m . '([^' . $m . ']*?)' . $m . '/iu',
+ '<strong class="search_hit">$1</strong>',
+ hsc(join('... ', $snippets))
+ );
+
+ $evdata['snippet'] = $snippet;
+ }
+ $evt->advise_after();
+ unset($evt);
+
+ return $evdata['snippet'];
+}
+
+/**
+ * Wraps a search term in regex boundary checks.
+ *
+ * @param string $term
+ * @return string
+ */
+function ft_snippet_re_preprocess($term) {
+ // do not process asian terms where word boundaries are not explicit
+ if(\dokuwiki\Utf8\Asian::isAsianWords($term)) return $term;
+
+ if (UTF8_PROPERTYSUPPORT) {
+ // unicode word boundaries
+ // see http://stackoverflow.com/a/2449017/172068
+ $BL = '(?<!\pL)';
+ $BR = '(?!\pL)';
+ } else {
+ // not as correct as above, but at least won't break
+ $BL = '\b';
+ $BR = '\b';
+ }
+
+ if(substr($term,0,2) == '\\*'){
+ $term = substr($term,2);
+ }else{
+ $term = $BL.$term;
+ }
+
+ if(substr($term,-2,2) == '\\*'){
+ $term = substr($term,0,-2);
+ }else{
+ $term = $term.$BR;
+ }
+
+ if($term == $BL || $term == $BR || $term == $BL.$BR) $term = '';
+ return $term;
+}
+
+/**
+ * Combine found documents and sum up their scores
+ *
+ * This function is used to combine searched words with a logical
+ * AND. Only documents available in all arrays are returned.
+ *
+ * based upon PEAR's PHP_Compat function for array_intersect_key()
+ *
+ * @param array $args An array of page arrays
+ * @return array
+ */
+function ft_resultCombine($args){
+ $array_count = count($args);
+ if($array_count == 1){
+ return $args[0];
+ }
+
+ $result = array();
+ if ($array_count > 1) {
+ foreach ($args[0] as $key => $value) {
+ $result[$key] = $value;
+ for ($i = 1; $i !== $array_count; $i++) {
+ if (!isset($args[$i][$key])) {
+ unset($result[$key]);
+ break;
+ }
+ $result[$key] += $args[$i][$key];
+ }
+ }
+ }
+ return $result;
+}
+
+/**
+ * Unites found documents and sum up their scores
+ *
+ * based upon ft_resultCombine() function
+ *
+ * @param array $args An array of page arrays
+ * @return array
+ *
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+function ft_resultUnite($args) {
+ $array_count = count($args);
+ if ($array_count === 1) {
+ return $args[0];
+ }
+
+ $result = $args[0];
+ for ($i = 1; $i !== $array_count; $i++) {
+ foreach (array_keys($args[$i]) as $id) {
+ $result[$id] += $args[$i][$id];
+ }
+ }
+ return $result;
+}
+
+/**
+ * Computes the difference of documents using page id for comparison
+ *
+ * nearly identical to PHP5's array_diff_key()
+ *
+ * @param array $args An array of page arrays
+ * @return array
+ *
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ */
+function ft_resultComplement($args) {
+ $array_count = count($args);
+ if ($array_count === 1) {
+ return $args[0];
+ }
+
+ $result = $args[0];
+ foreach (array_keys($result) as $id) {
+ for ($i = 1; $i !== $array_count; $i++) {
+ if (isset($args[$i][$id])) unset($result[$id]);
+ }
+ }
+ return $result;
+}
+
+/**
+ * Parses a search query and builds an array of search formulas
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ *
+ * @param dokuwiki\Search\Indexer $Indexer
+ * @param string $query search query
+ * @return array of search formulas
+ */
+function ft_queryParser($Indexer, $query){
+ /**
+ * parse a search query and transform it into intermediate representation
+ *
+ * in a search query, you can use the following expressions:
+ *
+ * words:
+ * include
+ * -exclude
+ * phrases:
+ * "phrase to be included"
+ * -"phrase you want to exclude"
+ * namespaces:
+ * @include:namespace (or ns:include:namespace)
+ * ^exclude:namespace (or -ns:exclude:namespace)
+ * groups:
+ * ()
+ * -()
+ * operators:
+ * and ('and' is the default operator: you can always omit this)
+ * or (or pipe symbol '|', lower precedence than 'and')
+ *
+ * e.g. a query [ aa "bb cc" @dd:ee ] means "search pages which contain
+ * a word 'aa', a phrase 'bb cc' and are within a namespace 'dd:ee'".
+ * this query is equivalent to [ -(-aa or -"bb cc" or -ns:dd:ee) ]
+ * as long as you don't mind hit counts.
+ *
+ * intermediate representation consists of the following parts:
+ *
+ * ( ) - group
+ * AND - logical and
+ * OR - logical or
+ * NOT - logical not
+ * W+:, W-:, W_: - word (underscore: no need to highlight)
+ * P+:, P-: - phrase (minus sign: logically in NOT group)
+ * N+:, N-: - namespace
+ */
+ $parsed_query = '';
+ $parens_level = 0;
+ $terms = preg_split('/(-?".*?")/u', \dokuwiki\Utf8\PhpString::strtolower($query),
+ -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+
+ foreach ($terms as $term) {
+ $parsed = '';
+ if (preg_match('/^(-?)"(.+)"$/u', $term, $matches)) {
+ // phrase-include and phrase-exclude
+ $not = $matches[1] ? 'NOT' : '';
+ $parsed = $not.ft_termParser($Indexer, $matches[2], false, true);
+ } else {
+ // fix incomplete phrase
+ $term = str_replace('"', ' ', $term);
+
+ // fix parentheses
+ $term = str_replace(')' , ' ) ', $term);
+ $term = str_replace('(' , ' ( ', $term);
+ $term = str_replace('- (', ' -(', $term);
+
+ // treat pipe symbols as 'OR' operators
+ $term = str_replace('|', ' or ', $term);
+
+ // treat ideographic spaces (U+3000) as search term separators
+ // FIXME: some more separators?
+ $term = preg_replace('/[ \x{3000}]+/u', ' ', $term);
+ $term = trim($term);
+ if ($term === '') continue;
+
+ $tokens = explode(' ', $term);
+ foreach ($tokens as $token) {
+ if ($token === '(') {
+ // parenthesis-include-open
+ $parsed .= '(';
+ ++$parens_level;
+ } elseif ($token === '-(') {
+ // parenthesis-exclude-open
+ $parsed .= 'NOT(';
+ ++$parens_level;
+ } elseif ($token === ')') {
+ // parenthesis-any-close
+ if ($parens_level === 0) continue;
+ $parsed .= ')';
+ $parens_level--;
+ } elseif ($token === 'and') {
+ // logical-and (do nothing)
+ } elseif ($token === 'or') {
+ // logical-or
+ $parsed .= 'OR';
+ } elseif (preg_match('/^(?:\^|-ns:)(.+)$/u', $token, $matches)) {
+ // namespace-exclude
+ $parsed .= 'NOT(N+:'.$matches[1].')';
+ } elseif (preg_match('/^(?:@|ns:)(.+)$/u', $token, $matches)) {
+ // namespace-include
+ $parsed .= '(N+:'.$matches[1].')';
+ } elseif (preg_match('/^-(.+)$/', $token, $matches)) {
+ // word-exclude
+ $parsed .= 'NOT('.ft_termParser($Indexer, $matches[1]).')';
+ } else {
+ // word-include
+ $parsed .= ft_termParser($Indexer, $token);
+ }
+ }
+ }
+ $parsed_query .= $parsed;
+ }
+
+ // cleanup (very sensitive)
+ $parsed_query .= str_repeat(')', $parens_level);
+ do {
+ $parsed_query_old = $parsed_query;
+ $parsed_query = preg_replace('/(NOT)?\(\)/u', '', $parsed_query);
+ } while ($parsed_query !== $parsed_query_old);
+ $parsed_query = preg_replace('/(NOT|OR)+\)/u', ')' , $parsed_query);
+ $parsed_query = preg_replace('/(OR)+/u' , 'OR' , $parsed_query);
+ $parsed_query = preg_replace('/\(OR/u' , '(' , $parsed_query);
+ $parsed_query = preg_replace('/^OR|OR$/u' , '' , $parsed_query);
+ $parsed_query = preg_replace('/\)(NOT)?\(/u' , ')AND$1(', $parsed_query);
+
+ // adjustment: make highlightings right
+ $parens_level = 0;
+ $notgrp_levels = array();
+ $parsed_query_new = '';
+ $tokens = preg_split('/(NOT\(|[()])/u', $parsed_query, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+ foreach ($tokens as $token) {
+ if ($token === 'NOT(') {
+ $notgrp_levels[] = ++$parens_level;
+ } elseif ($token === '(') {
+ ++$parens_level;
+ } elseif ($token === ')') {
+ if ($parens_level-- === end($notgrp_levels)) array_pop($notgrp_levels);
+ } elseif (count($notgrp_levels) % 2 === 1) {
+ // turn highlight-flag off if terms are logically in "NOT" group
+ $token = preg_replace('/([WPN])\+\:/u', '$1-:', $token);
+ }
+ $parsed_query_new .= $token;
+ }
+ $parsed_query = $parsed_query_new;
+
+ /**
+ * convert infix notation string into postfix (Reverse Polish notation) array
+ * by Shunting-yard algorithm
+ *
+ * see: http://en.wikipedia.org/wiki/Reverse_Polish_notation
+ * see: http://en.wikipedia.org/wiki/Shunting-yard_algorithm
+ */
+ $parsed_ary = array();
+ $ope_stack = array();
+ $ope_precedence = array(')' => 1, 'OR' => 2, 'AND' => 3, 'NOT' => 4, '(' => 5);
+ $ope_regex = '/([()]|OR|AND|NOT)/u';
+
+ $tokens = preg_split($ope_regex, $parsed_query, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
+ foreach ($tokens as $token) {
+ if (preg_match($ope_regex, $token)) {
+ // operator
+ $last_ope = end($ope_stack);
+ while ($last_ope !== false && $ope_precedence[$token] <= $ope_precedence[$last_ope] && $last_ope != '(') {
+ $parsed_ary[] = array_pop($ope_stack);
+ $last_ope = end($ope_stack);
+ }
+ if ($token == ')') {
+ array_pop($ope_stack); // this array_pop always deletes '('
+ } else {
+ $ope_stack[] = $token;
+ }
+ } else {
+ // operand
+ $token_decoded = str_replace(array('OP', 'CP'), array('(', ')'), $token);
+ $parsed_ary[] = $token_decoded;
+ }
+ }
+ $parsed_ary = array_values(array_merge($parsed_ary, array_reverse($ope_stack)));
+
+ // cleanup: each double "NOT" in RPN array actually does nothing
+ $parsed_ary_count = count($parsed_ary);
+ for ($i = 1; $i < $parsed_ary_count; ++$i) {
+ if ($parsed_ary[$i] === 'NOT' && $parsed_ary[$i - 1] === 'NOT') {
+ unset($parsed_ary[$i], $parsed_ary[$i - 1]);
+ }
+ }
+ $parsed_ary = array_values($parsed_ary);
+
+ // build return value
+ $q = array();
+ $q['query'] = $query;
+ $q['parsed_str'] = $parsed_query;
+ $q['parsed_ary'] = $parsed_ary;
+
+ foreach ($q['parsed_ary'] as $token) {
+ if ($token[2] !== ':') continue;
+ $body = substr($token, 3);
+
+ switch (substr($token, 0, 3)) {
+ case 'N+:':
+ $q['ns'][] = $body; // for backward compatibility
+ break;
+ case 'N-:':
+ $q['notns'][] = $body; // for backward compatibility
+ break;
+ case 'W_:':
+ $q['words'][] = $body;
+ break;
+ case 'W-:':
+ $q['words'][] = $body;
+ $q['not'][] = $body; // for backward compatibility
+ break;
+ case 'W+:':
+ $q['words'][] = $body;
+ $q['highlight'][] = $body;
+ $q['and'][] = $body; // for backward compatibility
+ break;
+ case 'P-:':
+ $q['phrases'][] = $body;
+ break;
+ case 'P+:':
+ $q['phrases'][] = $body;
+ $q['highlight'][] = $body;
+ break;
+ }
+ }
+ foreach (array('words', 'phrases', 'highlight', 'ns', 'notns', 'and', 'not') as $key) {
+ $q[$key] = empty($q[$key]) ? array() : array_values(array_unique($q[$key]));
+ }
+
+ return $q;
+}
+
+/**
+ * Transforms given search term into intermediate representation
+ *
+ * This function is used in ft_queryParser() and not for general purpose use.
+ *
+ * @author Kazutaka Miyasaka <kazmiya@gmail.com>
+ *
+ * @param dokuwiki\Search\Indexer $Indexer
+ * @param string $term
+ * @param bool $consider_asian
+ * @param bool $phrase_mode
+ * @return string
+ */
+function ft_termParser($Indexer, $term, $consider_asian = true, $phrase_mode = false) {
+ $parsed = '';
+ if ($consider_asian) {
+ // successive asian characters need to be searched as a phrase
+ $words = \dokuwiki\Utf8\Asian::splitAsianWords($term);
+ foreach ($words as $word) {
+ $phrase_mode = $phrase_mode ? true : \dokuwiki\Utf8\Asian::isAsianWords($word);
+ $parsed .= ft_termParser($Indexer, $word, false, $phrase_mode);
+ }
+ } else {
+ $term_noparen = str_replace(array('(', ')'), ' ', $term);
+ $words = $Indexer->tokenizer($term_noparen, true);
+
+ // W_: no need to highlight
+ if (empty($words)) {
+ $parsed = '()'; // important: do not remove
+ } elseif ($words[0] === $term) {
+ $parsed = '(W+:'.$words[0].')';
+ } elseif ($phrase_mode) {
+ $term_encoded = str_replace(array('(', ')'), array('OP', 'CP'), $term);
+ $parsed = '((W_:'.implode(')(W_:', $words).')(P+:'.$term_encoded.'))';
+ } else {
+ $parsed = '((W+:'.implode(')(W+:', $words).'))';
+ }
+ }
+ return $parsed;
+}
+
+/**
+ * Recreate a search query string based on parsed parts, doesn't support negated phrases and `OR` searches
+ *
+ * @param array $and
+ * @param array $not
+ * @param array $phrases
+ * @param array $ns
+ * @param array $notns
+ *
+ * @return string
+ */
+function ft_queryUnparser_simple(array $and, array $not, array $phrases, array $ns, array $notns) {
+ $query = implode(' ', $and);
+ if (!empty($not)) {
+ $query .= ' -' . implode(' -', $not);
+ }
+
+ if (!empty($phrases)) {
+ $query .= ' "' . implode('" "', $phrases) . '"';
+ }
+
+ if (!empty($ns)) {
+ $query .= ' @' . implode(' @', $ns);
+ }
+
+ if (!empty($notns)) {
+ $query .= ' ^' . implode(' ^', $notns);
+ }
+
+ return $query;
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/inc/html.php b/platform/www/inc/html.php
new file mode 100644
index 0000000..1f494d4
--- /dev/null
+++ b/platform/www/inc/html.php
@@ -0,0 +1,2380 @@
+<?php
+/**
+ * HTML output functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\ChangeLog\MediaChangeLog;
+use dokuwiki\ChangeLog\PageChangeLog;
+use dokuwiki\Extension\AuthPlugin;
+use dokuwiki\Extension\Event;
+
+if (!defined('SEC_EDIT_PATTERN')) {
+ define('SEC_EDIT_PATTERN', '#<!-- EDIT({.*?}) -->#');
+}
+
+
+/**
+ * Convenience function to quickly build a wikilink
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $id id of the target page
+ * @param string $name the name of the link, i.e. the text that is displayed
+ * @param string|array $search search string(s) that shall be highlighted in the target page
+ * @return string the HTML code of the link
+ */
+function html_wikilink($id,$name=null,$search=''){
+ /** @var Doku_Renderer_xhtml $xhtml_renderer */
+ static $xhtml_renderer = null;
+ if(is_null($xhtml_renderer)){
+ $xhtml_renderer = p_get_renderer('xhtml');
+ }
+
+ return $xhtml_renderer->internallink($id,$name,$search,true,'navigation');
+}
+
+/**
+ * The loginform
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param bool $svg Whether to show svg icons in the register and resendpwd links or not
+ */
+function html_login($svg = false){
+ global $lang;
+ global $conf;
+ global $ID;
+ global $INPUT;
+
+ print p_locale_xhtml('login');
+ print '<div class="centeralign">'.NL;
+ $form = new Doku_Form(array('id' => 'dw__login', 'action'=>wl($ID)));
+ $form->startFieldset($lang['btn_login']);
+ $form->addHidden('id', $ID);
+ $form->addHidden('do', 'login');
+ $form->addElement(form_makeTextField(
+ 'u',
+ ((!$INPUT->bool('http_credentials')) ? $INPUT->str('u') : ''),
+ $lang['user'],
+ 'focus__this',
+ 'block')
+ );
+ $form->addElement(form_makePasswordField('p', $lang['pass'], '', 'block'));
+ if($conf['rememberme']) {
+ $form->addElement(form_makeCheckboxField('r', '1', $lang['remember'], 'remember__me', 'simple'));
+ }
+ $form->addElement(form_makeButton('submit', '', $lang['btn_login']));
+ $form->endFieldset();
+
+ if(actionOK('register')){
+ $registerLink = (new \dokuwiki\Menu\Item\Register())->asHtmlLink('', $svg);
+ $form->addElement('<p>'.$lang['reghere'].': '. $registerLink .'</p>');
+ }
+
+ if (actionOK('resendpwd')) {
+ $resendPwLink = (new \dokuwiki\Menu\Item\Resendpwd())->asHtmlLink('', $svg);
+ $form->addElement('<p>'.$lang['pwdforget'].': '. $resendPwLink .'</p>');
+ }
+
+ html_form('login', $form);
+ print '</div>'.NL;
+}
+
+
+/**
+ * Denied page content
+ *
+ * @return string html
+ */
+function html_denied() {
+ print p_locale_xhtml('denied');
+
+ if(empty($_SERVER['REMOTE_USER']) && actionOK('login')){
+ html_login();
+ }
+}
+
+/**
+ * inserts section edit buttons if wanted or removes the markers
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $text
+ * @param bool $show show section edit buttons?
+ * @return string
+ */
+function html_secedit($text,$show=true){
+ global $INFO;
+
+ if((isset($INFO) && !$INFO['writable']) || !$show || (isset($INFO) && $INFO['rev'])){
+ return preg_replace(SEC_EDIT_PATTERN,'',$text);
+ }
+
+ return preg_replace_callback(SEC_EDIT_PATTERN,
+ 'html_secedit_button', $text);
+}
+
+/**
+ * prepares section edit button data for event triggering
+ * used as a callback in html_secedit
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $matches matches with regexp
+ * @return string
+ * @triggers HTML_SECEDIT_BUTTON
+ */
+function html_secedit_button($matches){
+ $json = htmlspecialchars_decode($matches[1], ENT_QUOTES);
+ $data = json_decode($json, true);
+ if ($data == NULL) {
+ return;
+ }
+ $data ['target'] = strtolower($data['target']);
+ $data ['hid'] = strtolower($data['hid']);
+
+ return Event::createAndTrigger('HTML_SECEDIT_BUTTON', $data,
+ 'html_secedit_get_button');
+}
+
+/**
+ * prints a section editing button
+ * used as default action form HTML_SECEDIT_BUTTON
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param array $data name, section id and target
+ * @return string html
+ */
+function html_secedit_get_button($data) {
+ global $ID;
+ global $INFO;
+
+ if (!isset($data['name']) || $data['name'] === '') return '';
+
+ $name = $data['name'];
+ unset($data['name']);
+
+ $secid = $data['secid'];
+ unset($data['secid']);
+
+ return "<div class='secedit editbutton_" . $data['target'] .
+ " editbutton_" . $secid . "'>" .
+ html_btn('secedit', $ID, '',
+ array_merge(array('do' => 'edit',
+ 'rev' => $INFO['lastmod'],
+ 'summary' => '['.$name.'] '), $data),
+ 'post', $name) . '</div>';
+}
+
+/**
+ * Just the back to top button (in its own form)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return string html
+ */
+function html_topbtn(){
+ global $lang;
+
+ $ret = '<a class="nolink" href="#dokuwiki__top">' .
+ '<button class="button" onclick="window.scrollTo(0, 0)" title="' . $lang['btn_top'] . '">' .
+ $lang['btn_top'] .
+ '</button></a>';
+
+ return $ret;
+}
+
+/**
+ * Displays a button (using its own form)
+ * If tooltip exists, the access key tooltip is replaced.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $name
+ * @param string $id
+ * @param string $akey access key
+ * @param string[] $params key-value pairs added as hidden inputs
+ * @param string $method
+ * @param string $tooltip
+ * @param bool|string $label label text, false: lookup btn_$name in localization
+ * @param string $svg (optional) svg code, inserted into the button
+ * @return string
+ */
+function html_btn($name, $id, $akey, $params, $method='get', $tooltip='', $label=false, $svg=null){
+ global $conf;
+ global $lang;
+
+ if (!$label)
+ $label = $lang['btn_'.$name];
+
+ $ret = '';
+
+ //filter id (without urlencoding)
+ $id = idfilter($id,false);
+
+ //make nice URLs even for buttons
+ if($conf['userewrite'] == 2){
+ $script = DOKU_BASE.DOKU_SCRIPT.'/'.$id;
+ }elseif($conf['userewrite']){
+ $script = DOKU_BASE.$id;
+ }else{
+ $script = DOKU_BASE.DOKU_SCRIPT;
+ $params['id'] = $id;
+ }
+
+ $ret .= '<form class="button btn_'.$name.'" method="'.$method.'" action="'.$script.'"><div class="no">';
+
+ if(is_array($params)){
+ foreach($params as $key => $val) {
+ $ret .= '<input type="hidden" name="'.$key.'" ';
+ $ret .= 'value="'.hsc($val).'" />';
+ }
+ }
+
+ if ($tooltip!='') {
+ $tip = hsc($tooltip);
+ }else{
+ $tip = hsc($label);
+ }
+
+ $ret .= '<button type="submit" ';
+ if($akey){
+ $tip .= ' ['.strtoupper($akey).']';
+ $ret .= 'accesskey="'.$akey.'" ';
+ }
+ $ret .= 'title="'.$tip.'">';
+ if ($svg) {
+ $ret .= '<span>' . hsc($label) . '</span>';
+ $ret .= inlineSVG($svg);
+ } else {
+ $ret .= hsc($label);
+ }
+ $ret .= '</button>';
+ $ret .= '</div></form>';
+
+ return $ret;
+}
+/**
+ * show a revision warning
+ *
+ * @author Szymon Olewniczak <dokuwiki@imz.re>
+ */
+function html_showrev() {
+ print p_locale_xhtml('showrev');
+}
+
+/**
+ * Show a wiki page
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param null|string $txt wiki text or null for showing $ID
+ */
+function html_show($txt=null){
+ global $ID;
+ global $REV;
+ global $HIGH;
+ global $INFO;
+ global $DATE_AT;
+ //disable section editing for old revisions or in preview
+ if($txt || $REV){
+ $secedit = false;
+ }else{
+ $secedit = true;
+ }
+
+ if (!is_null($txt)){
+ //PreviewHeader
+ echo '<br id="scroll__here" />';
+ echo p_locale_xhtml('preview');
+ echo '<div class="preview"><div class="pad">';
+ $html = html_secedit(p_render('xhtml',p_get_instructions($txt),$info),$secedit);
+ if($INFO['prependTOC']) $html = tpl_toc(true).$html;
+ echo $html;
+ echo '<div class="clearer"></div>';
+ echo '</div></div>';
+
+ }else{
+ if ($REV||$DATE_AT){
+ $data = array('rev' => &$REV, 'date_at' => &$DATE_AT);
+ Event::createAndTrigger('HTML_SHOWREV_OUTPUT', $data, 'html_showrev');
+ }
+ $html = p_wiki_xhtml($ID,$REV,true,$DATE_AT);
+ $html = html_secedit($html,$secedit);
+ if($INFO['prependTOC']) $html = tpl_toc(true).$html;
+ $html = html_hilight($html,$HIGH);
+ echo $html;
+ }
+}
+
+/**
+ * ask the user about how to handle an exisiting draft
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_draft(){
+ global $INFO;
+ global $ID;
+ global $lang;
+ $draft = new \dokuwiki\Draft($ID, $INFO['client']);
+ $text = $draft->getDraftText();
+
+ print p_locale_xhtml('draft');
+ html_diff($text, false);
+ $form = new Doku_Form(array('id' => 'dw__editform'));
+ $form->addHidden('id', $ID);
+ $form->addHidden('date', $draft->getDraftDate());
+ $form->addHidden('wikitext', $text);
+ $form->addElement(form_makeOpenTag('div', array('id'=>'draft__status')));
+ $form->addElement($draft->getDraftMessage());
+ $form->addElement(form_makeCloseTag('div'));
+ $form->addElement(form_makeButton('submit', 'recover', $lang['btn_recover'], array('tabindex'=>'1')));
+ $form->addElement(form_makeButton('submit', 'draftdel', $lang['btn_draftdel'], array('tabindex'=>'2')));
+ $form->addElement(form_makeButton('submit', 'show', $lang['btn_cancel'], array('tabindex'=>'3')));
+ html_form('draft', $form);
+}
+
+/**
+ * Highlights searchqueries in HTML code
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ *
+ * @param string $html
+ * @param array|string $phrases
+ * @return string html
+ */
+function html_hilight($html,$phrases){
+ $phrases = (array) $phrases;
+ $phrases = array_map('preg_quote_cb', $phrases);
+ $phrases = array_map('ft_snippet_re_preprocess', $phrases);
+ $phrases = array_filter($phrases);
+ $regex = join('|',$phrases);
+
+ if ($regex === '') return $html;
+ if (!\dokuwiki\Utf8\Clean::isUtf8($regex)) return $html;
+ $html = @preg_replace_callback("/((<[^>]*)|$regex)/ui",'html_hilight_callback',$html);
+ return $html;
+}
+
+/**
+ * Callback used by html_hilight()
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ *
+ * @param array $m matches
+ * @return string html
+ */
+function html_hilight_callback($m) {
+ $hlight = unslash($m[0]);
+ if ( !isset($m[2])) {
+ $hlight = '<span class="search_hit">'.$hlight.'</span>';
+ }
+ return $hlight;
+}
+
+/**
+ * Display error on locked pages
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_locked(){
+ global $ID;
+ global $conf;
+ global $lang;
+ global $INFO;
+
+ $locktime = filemtime(wikiLockFN($ID));
+ $expire = dformat($locktime + $conf['locktime']);
+ $min = round(($conf['locktime'] - (time() - $locktime) )/60);
+
+ print p_locale_xhtml('locked');
+ print '<ul>';
+ print '<li><div class="li"><strong>'.$lang['lockedby'].'</strong> '.editorinfo($INFO['locked']).'</div></li>';
+ print '<li><div class="li"><strong>'.$lang['lockexpire'].'</strong> '.$expire.' ('.$min.' min)</div></li>';
+ print '</ul>';
+}
+
+/**
+ * list old revisions
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param int $first skip the first n changelog lines
+ * @param bool|string $media_id id of media, or false for current page
+ */
+function html_revisions($first=0, $media_id = false){
+ global $ID;
+ global $INFO;
+ global $conf;
+ global $lang;
+ $id = $ID;
+ if ($media_id) {
+ $id = $media_id;
+ $changelog = new MediaChangeLog($id);
+ } else {
+ $changelog = new PageChangeLog($id);
+ }
+
+ /* we need to get one additional log entry to be able to
+ * decide if this is the last page or is there another one.
+ * see html_recent()
+ */
+
+ $revisions = $changelog->getRevisions($first, $conf['recent']+1);
+
+ if(count($revisions)==0 && $first!=0){
+ $first=0;
+ $revisions = $changelog->getRevisions($first, $conf['recent']+1);
+ }
+ $hasNext = false;
+ if (count($revisions)>$conf['recent']) {
+ $hasNext = true;
+ array_pop($revisions); // remove extra log entry
+ }
+
+ if (!$media_id) print p_locale_xhtml('revisions');
+
+ $params = array('id' => 'page__revisions', 'class' => 'changes');
+ if($media_id) {
+ $params['action'] = media_managerURL(array('image' => $media_id), '&');
+ }
+
+ if(!$media_id) {
+ $exists = $INFO['exists'];
+ $display_name = useHeading('navigation') ? hsc(p_get_first_heading($id)) : $id;
+ if(!$display_name) {
+ $display_name = $id;
+ }
+ } else {
+ $exists = file_exists(mediaFN($id));
+ $display_name = $id;
+ }
+
+ $form = new Doku_Form($params);
+ $form->addElement(form_makeOpenTag('ul'));
+
+ if($exists && $first == 0) {
+ $minor = false;
+ if($media_id) {
+ $date = dformat(@filemtime(mediaFN($id)));
+ $href = media_managerURL(array('image' => $id, 'tab_details' => 'view'), '&');
+
+ $changelog->setChunkSize(1024);
+ $revinfo = $changelog->getRevisionInfo(@filemtime(fullpath(mediaFN($id))));
+
+ $summary = $revinfo['sum'];
+ if($revinfo['user']) {
+ $editor = $revinfo['user'];
+ } else {
+ $editor = $revinfo['ip'];
+ }
+ $sizechange = $revinfo['sizechange'];
+ } else {
+ $date = dformat($INFO['lastmod']);
+ if(isset($INFO['meta']) && isset($INFO['meta']['last_change'])) {
+ if($INFO['meta']['last_change']['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
+ $minor = true;
+ }
+ if(isset($INFO['meta']['last_change']['sizechange'])) {
+ $sizechange = $INFO['meta']['last_change']['sizechange'];
+ } else {
+ $sizechange = null;
+ }
+ }
+ $pagelog = new PageChangeLog($ID);
+ $latestrev = $pagelog->getRevisions(-1, 1);
+ $latestrev = array_pop($latestrev);
+ $href = wl($id,"rev=$latestrev",false,'&');
+ $summary = $INFO['sum'];
+ $editor = $INFO['editor'];
+ }
+
+ $form->addElement(form_makeOpenTag('li', array('class' => ($minor ? 'minor' : ''))));
+ $form->addElement(form_makeOpenTag('div', array('class' => 'li')));
+ $form->addElement(form_makeTag('input', array(
+ 'type' => 'checkbox',
+ 'name' => 'rev2[]',
+ 'value' => 'current')));
+
+ $form->addElement(form_makeOpenTag('span', array('class' => 'date')));
+ $form->addElement($date);
+ $form->addElement(form_makeCloseTag('span'));
+
+ $form->addElement('<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />');
+
+ $form->addElement(form_makeOpenTag('a', array(
+ 'class' => 'wikilink1',
+ 'href' => $href)));
+ $form->addElement($display_name);
+ $form->addElement(form_makeCloseTag('a'));
+
+ if ($media_id) $form->addElement(form_makeOpenTag('div'));
+
+ if($summary) {
+ $form->addElement(form_makeOpenTag('span', array('class' => 'sum')));
+ if(!$media_id) $form->addElement(' – ');
+ $form->addElement('<bdi>' . hsc($summary) . '</bdi>');
+ $form->addElement(form_makeCloseTag('span'));
+ }
+
+ $form->addElement(form_makeOpenTag('span', array('class' => 'user')));
+ $form->addElement((empty($editor))?('('.$lang['external_edit'].')'):'<bdi>'.editorinfo($editor).'</bdi>');
+ $form->addElement(form_makeCloseTag('span'));
+
+ html_sizechange($sizechange, $form);
+
+ $form->addElement('('.$lang['current'].')');
+
+ if ($media_id) $form->addElement(form_makeCloseTag('div'));
+
+ $form->addElement(form_makeCloseTag('div'));
+ $form->addElement(form_makeCloseTag('li'));
+ }
+
+ foreach($revisions as $rev) {
+ $date = dformat($rev);
+ $info = $changelog->getRevisionInfo($rev);
+ if($media_id) {
+ $exists = file_exists(mediaFN($id, $rev));
+ } else {
+ $exists = page_exists($id, $rev);
+ }
+
+ $class = '';
+ if($info['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
+ $class = 'minor';
+ }
+ $form->addElement(form_makeOpenTag('li', array('class' => $class)));
+ $form->addElement(form_makeOpenTag('div', array('class' => 'li')));
+ if($exists){
+ $form->addElement(form_makeTag('input', array(
+ 'type' => 'checkbox',
+ 'name' => 'rev2[]',
+ 'value' => $rev)));
+ }else{
+ $form->addElement('<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />');
+ }
+
+ $form->addElement(form_makeOpenTag('span', array('class' => 'date')));
+ $form->addElement($date);
+ $form->addElement(form_makeCloseTag('span'));
+
+ if($exists){
+ if (!$media_id) {
+ $href = wl($id,"rev=$rev,do=diff", false, '&');
+ } else {
+ $href = media_managerURL(array('image' => $id, 'rev' => $rev, 'mediado' => 'diff'), '&');
+ }
+ $form->addElement(form_makeOpenTag('a', array(
+ 'class' => 'diff_link',
+ 'href' => $href)));
+ $form->addElement(form_makeTag('img', array(
+ 'src' => DOKU_BASE.'lib/images/diff.png',
+ 'width' => 15,
+ 'height' => 11,
+ 'title' => $lang['diff'],
+ 'alt' => $lang['diff'])));
+ $form->addElement(form_makeCloseTag('a'));
+
+ if (!$media_id) {
+ $href = wl($id,"rev=$rev",false,'&');
+ } else {
+ $href = media_managerURL(array('image' => $id, 'tab_details' => 'view', 'rev' => $rev), '&');
+ }
+ $form->addElement(form_makeOpenTag('a', array(
+ 'class' => 'wikilink1',
+ 'href' => $href)));
+ $form->addElement($display_name);
+ $form->addElement(form_makeCloseTag('a'));
+ }else{
+ $form->addElement('<img src="'.DOKU_BASE.'lib/images/blank.gif" width="15" height="11" alt="" />');
+ $form->addElement($display_name);
+ }
+
+ if ($media_id) $form->addElement(form_makeOpenTag('div'));
+
+ if ($info['sum']) {
+ $form->addElement(form_makeOpenTag('span', array('class' => 'sum')));
+ if(!$media_id) $form->addElement(' – ');
+ $form->addElement('<bdi>'.hsc($info['sum']).'</bdi>');
+ $form->addElement(form_makeCloseTag('span'));
+ }
+
+ $form->addElement(form_makeOpenTag('span', array('class' => 'user')));
+ if($info['user']){
+ $form->addElement('<bdi>'.editorinfo($info['user']).'</bdi>');
+ if(auth_ismanager()){
+ $form->addElement(' <bdo dir="ltr">('.$info['ip'].')</bdo>');
+ }
+ }else{
+ $form->addElement('<bdo dir="ltr">'.$info['ip'].'</bdo>');
+ }
+ $form->addElement(form_makeCloseTag('span'));
+
+ html_sizechange($info['sizechange'], $form);
+
+ if ($media_id) $form->addElement(form_makeCloseTag('div'));
+
+ $form->addElement(form_makeCloseTag('div'));
+ $form->addElement(form_makeCloseTag('li'));
+ }
+ $form->addElement(form_makeCloseTag('ul'));
+ if (!$media_id) {
+ $form->addElement(form_makeButton('submit', 'diff', $lang['diff2']));
+ } else {
+ $form->addHidden('mediado', 'diff');
+ $form->addElement(form_makeButton('submit', '', $lang['diff2']));
+ }
+ html_form('revisions', $form);
+
+ print '<div class="pagenav">';
+ $last = $first + $conf['recent'];
+ if ($first > 0) {
+ $first -= $conf['recent'];
+ if ($first < 0) $first = 0;
+ print '<div class="pagenav-prev">';
+ if ($media_id) {
+ print html_btn('newer',$media_id,"p",media_managerURL(array('first' => $first), '&amp;', false, true));
+ } else {
+ print html_btn('newer',$id,"p",array('do' => 'revisions', 'first' => $first));
+ }
+ print '</div>';
+ }
+ if ($hasNext) {
+ print '<div class="pagenav-next">';
+ if ($media_id) {
+ print html_btn('older',$media_id,"n",media_managerURL(array('first' => $last), '&amp;', false, true));
+ } else {
+ print html_btn('older',$id,"n",array('do' => 'revisions', 'first' => $last));
+ }
+ print '</div>';
+ }
+ print '</div>';
+
+}
+
+/**
+ * display recent changes
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param int $first
+ * @param string $show_changes
+ */
+function html_recent($first = 0, $show_changes = 'both') {
+ global $conf;
+ global $lang;
+ global $ID;
+ /* we need to get one additionally log entry to be able to
+ * decide if this is the last page or is there another one.
+ * This is the cheapest solution to get this information.
+ */
+ $flags = 0;
+ if($show_changes == 'mediafiles' && $conf['mediarevisions']) {
+ $flags = RECENTS_MEDIA_CHANGES;
+ } elseif($show_changes == 'pages') {
+ $flags = 0;
+ } elseif($conf['mediarevisions']) {
+ $show_changes = 'both';
+ $flags = RECENTS_MEDIA_PAGES_MIXED;
+ }
+
+ $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
+ if(count($recents) == 0 && $first != 0) {
+ $first = 0;
+ $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags);
+ }
+ $hasNext = false;
+ if(count($recents) > $conf['recent']) {
+ $hasNext = true;
+ array_pop($recents); // remove extra log entry
+ }
+
+ print p_locale_xhtml('recent');
+
+ if(getNS($ID) != '') {
+ print '<div class="level1"><p>' .
+ sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent')) .
+ '</p></div>';
+ }
+
+ $form = new Doku_Form(array('id' => 'dw__recent', 'method' => 'GET', 'class' => 'changes', 'action'=>wl($ID)));
+ $form->addHidden('sectok', null);
+ $form->addHidden('do', 'recent');
+ $form->addHidden('id', $ID);
+
+ if($conf['mediarevisions']) {
+ $form->addElement('<div class="changeType">');
+ $form->addElement(form_makeListboxField(
+ 'show_changes',
+ array(
+ 'pages' => $lang['pages_changes'],
+ 'mediafiles' => $lang['media_changes'],
+ 'both' => $lang['both_changes']
+ ),
+ $show_changes,
+ $lang['changes_type'],
+ '', '',
+ array('class' => 'quickselect')));
+
+ $form->addElement(form_makeButton('submit', 'recent', $lang['btn_apply']));
+ $form->addElement('</div>');
+ }
+
+ $form->addElement(form_makeOpenTag('ul'));
+
+ foreach($recents as $recent) {
+ $date = dformat($recent['date']);
+
+ $class = '';
+ if($recent['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) {
+ $class = 'minor';
+ }
+ $form->addElement(form_makeOpenTag('li', array('class' => $class)));
+ $form->addElement(form_makeOpenTag('div', array('class' => 'li')));
+
+ if(!empty($recent['media'])) {
+ $form->addElement(media_printicon($recent['id']));
+ } else {
+ $icon = DOKU_BASE . 'lib/images/fileicons/file.png';
+ $form->addElement('<img src="' . $icon . '" alt="' . $recent['id'] . '" class="icon" />');
+ }
+
+ $form->addElement(form_makeOpenTag('span', array('class' => 'date')));
+ $form->addElement($date);
+ $form->addElement(form_makeCloseTag('span'));
+
+ $diff = false;
+ $href = '';
+
+ if(!empty($recent['media'])) {
+ $changelog = new MediaChangeLog($recent['id']);
+ $revs = $changelog->getRevisions(0, 1);
+ $diff = (count($revs) && file_exists(mediaFN($recent['id'])));
+ if($diff) {
+ $href = media_managerURL(array(
+ 'tab_details' => 'history',
+ 'mediado' => 'diff',
+ 'image' => $recent['id'],
+ 'ns' => getNS($recent['id'])
+ ), '&');
+ }
+ } else {
+ $href = wl($recent['id'], "do=diff", false, '&');
+ }
+
+ if(!empty($recent['media']) && !$diff) {
+ $form->addElement('<img src="' . DOKU_BASE . 'lib/images/blank.gif" width="15" height="11" alt="" />');
+ } else {
+ $form->addElement(form_makeOpenTag('a', array('class' => 'diff_link', 'href' => $href)));
+ $form->addElement(form_makeTag('img', array(
+ 'src' => DOKU_BASE . 'lib/images/diff.png',
+ 'width' => 15,
+ 'height' => 11,
+ 'title' => $lang['diff'],
+ 'alt' => $lang['diff']
+ )));
+ $form->addElement(form_makeCloseTag('a'));
+ }
+
+ if(!empty($recent['media'])) {
+ $href = media_managerURL(
+ array(
+ 'tab_details' => 'history',
+ 'image' => $recent['id'],
+ 'ns' => getNS($recent['id'])
+ ),
+ '&'
+ );
+ } else {
+ $href = wl($recent['id'], "do=revisions", false, '&');
+ }
+ $form->addElement(form_makeOpenTag('a', array(
+ 'class' => 'revisions_link',
+ 'href' => $href)));
+ $form->addElement(form_makeTag('img', array(
+ 'src' => DOKU_BASE . 'lib/images/history.png',
+ 'width' => 12,
+ 'height' => 14,
+ 'title' => $lang['btn_revs'],
+ 'alt' => $lang['btn_revs']
+ )));
+ $form->addElement(form_makeCloseTag('a'));
+
+ if(!empty($recent['media'])) {
+ $href = media_managerURL(
+ array(
+ 'tab_details' => 'view',
+ 'image' => $recent['id'],
+ 'ns' => getNS($recent['id'])
+ ),
+ '&'
+ );
+ $class = file_exists(mediaFN($recent['id'])) ? 'wikilink1' : 'wikilink2';
+ $form->addElement(form_makeOpenTag('a', array(
+ 'class' => $class,
+ 'href' => $href)));
+ $form->addElement($recent['id']);
+ $form->addElement(form_makeCloseTag('a'));
+ } else {
+ $form->addElement(html_wikilink(':' . $recent['id'], useHeading('navigation') ? null : $recent['id']));
+ }
+ $form->addElement(form_makeOpenTag('span', array('class' => 'sum')));
+ $form->addElement(' – ' . hsc($recent['sum']));
+ $form->addElement(form_makeCloseTag('span'));
+
+ $form->addElement(form_makeOpenTag('span', array('class' => 'user')));
+ if($recent['user']) {
+ $form->addElement('<bdi>' . editorinfo($recent['user']) . '</bdi>');
+ if(auth_ismanager()) {
+ $form->addElement(' <bdo dir="ltr">(' . $recent['ip'] . ')</bdo>');
+ }
+ } else {
+ $form->addElement('<bdo dir="ltr">' . $recent['ip'] . '</bdo>');
+ }
+ $form->addElement(form_makeCloseTag('span'));
+
+ html_sizechange($recent['sizechange'], $form);
+
+ $form->addElement(form_makeCloseTag('div'));
+ $form->addElement(form_makeCloseTag('li'));
+ }
+ $form->addElement(form_makeCloseTag('ul'));
+
+ $form->addElement(form_makeOpenTag('div', array('class' => 'pagenav')));
+ $last = $first + $conf['recent'];
+ if($first > 0) {
+ $first -= $conf['recent'];
+ if($first < 0) $first = 0;
+ $form->addElement(form_makeOpenTag('div', array('class' => 'pagenav-prev')));
+ $form->addElement(form_makeOpenTag('button', array(
+ 'type' => 'submit',
+ 'name' => 'first[' . $first . ']',
+ 'accesskey' => 'n',
+ 'title' => $lang['btn_newer'] . ' [N]',
+ 'class' => 'button show'
+ )));
+ $form->addElement($lang['btn_newer']);
+ $form->addElement(form_makeCloseTag('button'));
+ $form->addElement(form_makeCloseTag('div'));
+ }
+ if($hasNext) {
+ $form->addElement(form_makeOpenTag('div', array('class' => 'pagenav-next')));
+ $form->addElement(form_makeOpenTag('button', array(
+ 'type' => 'submit',
+ 'name' => 'first[' . $last . ']',
+ 'accesskey' => 'p',
+ 'title' => $lang['btn_older'] . ' [P]',
+ 'class' => 'button show'
+ )));
+ $form->addElement($lang['btn_older']);
+ $form->addElement(form_makeCloseTag('button'));
+ $form->addElement(form_makeCloseTag('div'));
+ }
+ $form->addElement(form_makeCloseTag('div'));
+ html_form('recent', $form);
+}
+
+/**
+ * Display page index
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $ns
+ */
+function html_index($ns){
+ global $conf;
+ global $ID;
+ $ns = cleanID($ns);
+ if(empty($ns)){
+ $ns = getNS($ID);
+ if($ns === false) $ns ='';
+ }
+ $ns = utf8_encodeFN(str_replace(':','/',$ns));
+
+ echo p_locale_xhtml('index');
+ echo '<div id="index__tree" class="index__tree">';
+
+ $data = array();
+ search($data,$conf['datadir'],'search_index',array('ns' => $ns));
+ echo html_buildlist($data,'idx','html_list_index','html_li_index');
+
+ echo '</div>';
+}
+
+/**
+ * Index item formatter
+ *
+ * User function for html_buildlist()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $item
+ * @return string
+ */
+function html_list_index($item){
+ global $ID, $conf;
+
+ // prevent searchbots needlessly following links
+ $nofollow = ($ID != $conf['start'] || $conf['sitemap']) ? 'rel="nofollow"' : '';
+
+ $ret = '';
+ $base = ':'.$item['id'];
+ $base = substr($base,strrpos($base,':')+1);
+ if($item['type']=='d'){
+ // FS#2766, no need for search bots to follow namespace links in the index
+ $link = wl($ID, 'idx=' . rawurlencode($item['id']));
+ $ret .= '<a href="' . $link . '" title="' . $item['id'] . '" class="idx_dir" ' . $nofollow . '><strong>';
+ $ret .= $base;
+ $ret .= '</strong></a>';
+ }else{
+ // default is noNSorNS($id), but we want noNS($id) when useheading is off FS#2605
+ $ret .= html_wikilink(':'.$item['id'], useHeading('navigation') ? null : noNS($item['id']));
+ }
+ return $ret;
+}
+
+/**
+ * Index List item
+ *
+ * This user function is used in html_buildlist to build the
+ * <li> tags for namespaces when displaying the page index
+ * it gives different classes to opened or closed "folders"
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $item
+ * @return string html
+ */
+function html_li_index($item){
+ global $INFO;
+ global $ACT;
+
+ $class = '';
+ $id = '';
+
+ if($item['type'] == "f"){
+ // scroll to the current item
+ if(isset($INFO) && $item['id'] == $INFO['id'] && $ACT == 'index') {
+ $id = ' id="scroll__here"';
+ $class = ' bounce';
+ }
+ return '<li class="level'.$item['level'].$class.'" '.$id.'>';
+ }elseif($item['open']){
+ return '<li class="open">';
+ }else{
+ return '<li class="closed">';
+ }
+}
+
+/**
+ * Default List item
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $item
+ * @return string html
+ */
+function html_li_default($item){
+ return '<li class="level'.$item['level'].'">';
+}
+
+/**
+ * Build an unordered list
+ *
+ * Build an unordered list from the given $data array
+ * Each item in the array has to have a 'level' property
+ * the item itself gets printed by the given $func user
+ * function. The second and optional function is used to
+ * print the <li> tag. Both user function need to accept
+ * a single item.
+ *
+ * Both user functions can be given as array to point to
+ * a member of an object.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data array with item arrays
+ * @param string $class class of ul wrapper
+ * @param callable $func callback to print an list item
+ * @param callable $lifunc callback to the opening li tag
+ * @param bool $forcewrapper Trigger building a wrapper ul if the first level is
+ * 0 (we have a root object) or 1 (just the root content)
+ * @return string html of an unordered list
+ */
+function html_buildlist($data,$class,$func,$lifunc='html_li_default',$forcewrapper=false){
+ if (count($data) === 0) {
+ return '';
+ }
+
+ $firstElement = reset($data);
+ $start_level = $firstElement['level'];
+ $level = $start_level;
+ $ret = '';
+ $open = 0;
+
+ foreach ($data as $item){
+
+ if( $item['level'] > $level ){
+ //open new list
+ for($i=0; $i<($item['level'] - $level); $i++){
+ if ($i) $ret .= "<li class=\"clear\">";
+ $ret .= "\n<ul class=\"$class\">\n";
+ $open++;
+ }
+ $level = $item['level'];
+
+ }elseif( $item['level'] < $level ){
+ //close last item
+ $ret .= "</li>\n";
+ while( $level > $item['level'] && $open > 0 ){
+ //close higher lists
+ $ret .= "</ul>\n</li>\n";
+ $level--;
+ $open--;
+ }
+ } elseif ($ret !== '') {
+ //close previous item
+ $ret .= "</li>\n";
+ }
+
+ //print item
+ $ret .= call_user_func($lifunc,$item);
+ $ret .= '<div class="li">';
+
+ $ret .= call_user_func($func,$item);
+ $ret .= '</div>';
+ }
+
+ //close remaining items and lists
+ $ret .= "</li>\n";
+ while($open-- > 0) {
+ $ret .= "</ul></li>\n";
+ }
+
+ if ($forcewrapper || $start_level < 2) {
+ // Trigger building a wrapper ul if the first level is
+ // 0 (we have a root object) or 1 (just the root content)
+ $ret = "\n<ul class=\"$class\">\n".$ret."</ul>\n";
+ }
+
+ return $ret;
+}
+
+/**
+ * display backlinks
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Klier <chi@chimeric.de>
+ */
+function html_backlinks(){
+ global $ID;
+ global $lang;
+
+ print p_locale_xhtml('backlinks');
+
+ $data = ft_backlinks($ID);
+
+ if(!empty($data)) {
+ print '<ul class="idx">';
+ foreach($data as $blink){
+ print '<li><div class="li">';
+ print html_wikilink(':'.$blink,useHeading('navigation')?null:$blink);
+ print '</div></li>';
+ }
+ print '</ul>';
+ } else {
+ print '<div class="level1"><p>' . $lang['nothingfound'] . '</p></div>';
+ }
+}
+
+/**
+ * Get header of diff HTML
+ *
+ * @param string $l_rev Left revisions
+ * @param string $r_rev Right revision
+ * @param string $id Page id, if null $ID is used
+ * @param bool $media If it is for media files
+ * @param bool $inline Return the header on a single line
+ * @return string[] HTML snippets for diff header
+ */
+function html_diff_head($l_rev, $r_rev, $id = null, $media = false, $inline = false) {
+ global $lang;
+ if ($id === null) {
+ global $ID;
+ $id = $ID;
+ }
+ $head_separator = $inline ? ' ' : '<br />';
+ $media_or_wikiFN = $media ? 'mediaFN' : 'wikiFN';
+ $ml_or_wl = $media ? 'ml' : 'wl';
+ $l_minor = $r_minor = '';
+
+ if($media) {
+ $changelog = new MediaChangeLog($id);
+ } else {
+ $changelog = new PageChangeLog($id);
+ }
+ if(!$l_rev){
+ $l_head = '&mdash;';
+ }else{
+ $l_info = $changelog->getRevisionInfo($l_rev);
+ if($l_info['user']){
+ $l_user = '<bdi>'.editorinfo($l_info['user']).'</bdi>';
+ if(auth_ismanager()) $l_user .= ' <bdo dir="ltr">('.$l_info['ip'].')</bdo>';
+ } else {
+ $l_user = '<bdo dir="ltr">'.$l_info['ip'].'</bdo>';
+ }
+ $l_user = '<span class="user">'.$l_user.'</span>';
+ $l_sum = ($l_info['sum']) ? '<span class="sum"><bdi>'.hsc($l_info['sum']).'</bdi></span>' : '';
+ if ($l_info['type']===DOKU_CHANGE_TYPE_MINOR_EDIT) $l_minor = 'class="minor"';
+
+ $l_head_title = ($media) ? dformat($l_rev) : $id.' ['.dformat($l_rev).']';
+ $l_head = '<bdi><a class="wikilink1" href="'.$ml_or_wl($id,"rev=$l_rev").'">'.
+ $l_head_title.'</a></bdi>'.
+ $head_separator.$l_user.' '.$l_sum;
+ }
+
+ if($r_rev){
+ $r_info = $changelog->getRevisionInfo($r_rev);
+ if($r_info['user']){
+ $r_user = '<bdi>'.editorinfo($r_info['user']).'</bdi>';
+ if(auth_ismanager()) $r_user .= ' <bdo dir="ltr">('.$r_info['ip'].')</bdo>';
+ } else {
+ $r_user = '<bdo dir="ltr">'.$r_info['ip'].'</bdo>';
+ }
+ $r_user = '<span class="user">'.$r_user.'</span>';
+ $r_sum = ($r_info['sum']) ? '<span class="sum"><bdi>'.hsc($r_info['sum']).'</bdi></span>' : '';
+ if ($r_info['type']===DOKU_CHANGE_TYPE_MINOR_EDIT) $r_minor = 'class="minor"';
+
+ $r_head_title = ($media) ? dformat($r_rev) : $id.' ['.dformat($r_rev).']';
+ $r_head = '<bdi><a class="wikilink1" href="'.$ml_or_wl($id,"rev=$r_rev").'">'.
+ $r_head_title.'</a></bdi>'.
+ $head_separator.$r_user.' '.$r_sum;
+ }elseif($_rev = @filemtime($media_or_wikiFN($id))){
+ $_info = $changelog->getRevisionInfo($_rev);
+ if($_info['user']){
+ $_user = '<bdi>'.editorinfo($_info['user']).'</bdi>';
+ if(auth_ismanager()) $_user .= ' <bdo dir="ltr">('.$_info['ip'].')</bdo>';
+ } else {
+ $_user = '<bdo dir="ltr">'.$_info['ip'].'</bdo>';
+ }
+ $_user = '<span class="user">'.$_user.'</span>';
+ $_sum = ($_info['sum']) ? '<span class="sum"><bdi>'.hsc($_info['sum']).'</span></bdi>' : '';
+ if ($_info['type']===DOKU_CHANGE_TYPE_MINOR_EDIT) $r_minor = 'class="minor"';
+
+ $r_head_title = ($media) ? dformat($_rev) : $id.' ['.dformat($_rev).']';
+ $r_head = '<bdi><a class="wikilink1" href="'.$ml_or_wl($id).'">'.
+ $r_head_title.'</a></bdi> '.
+ '('.$lang['current'].')'.
+ $head_separator.$_user.' '.$_sum;
+ }else{
+ $r_head = '&mdash; ('.$lang['current'].')';
+ }
+
+ return array($l_head, $r_head, $l_minor, $r_minor);
+}
+
+/**
+ * Show diff
+ * between current page version and provided $text
+ * or between the revisions provided via GET or POST
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $text when non-empty: compare with this text with most current version
+ * @param bool $intro display the intro text
+ * @param string $type type of the diff (inline or sidebyside)
+ */
+function html_diff($text = '', $intro = true, $type = null) {
+ global $ID;
+ global $REV;
+ global $lang;
+ global $INPUT;
+ global $INFO;
+ $pagelog = new PageChangeLog($ID);
+
+ /*
+ * Determine diff type
+ */
+ if(!$type) {
+ $type = $INPUT->str('difftype');
+ if(empty($type)) {
+ $type = get_doku_pref('difftype', $type);
+ if(empty($type) && $INFO['ismobile']) {
+ $type = 'inline';
+ }
+ }
+ }
+ if($type != 'inline') $type = 'sidebyside';
+
+ /*
+ * Determine requested revision(s)
+ */
+ // we're trying to be clever here, revisions to compare can be either
+ // given as rev and rev2 parameters, with rev2 being optional. Or in an
+ // array in rev2.
+ $rev1 = $REV;
+
+ $rev2 = $INPUT->ref('rev2');
+ if(is_array($rev2)) {
+ $rev1 = (int) $rev2[0];
+ $rev2 = (int) $rev2[1];
+
+ if(!$rev1) {
+ $rev1 = $rev2;
+ unset($rev2);
+ }
+ } else {
+ $rev2 = $INPUT->int('rev2');
+ }
+
+ /*
+ * Determine left and right revision, its texts and the header
+ */
+ $r_minor = '';
+ $l_minor = '';
+
+ if($text) { // compare text to the most current revision
+ $l_rev = '';
+ $l_text = rawWiki($ID, '');
+ $l_head = '<a class="wikilink1" href="' . wl($ID) . '">' .
+ $ID . ' ' . dformat((int) @filemtime(wikiFN($ID))) . '</a> ' .
+ $lang['current'];
+
+ $r_rev = '';
+ $r_text = cleanText($text);
+ $r_head = $lang['yours'];
+ } else {
+ if($rev1 && isset($rev2) && $rev2) { // two specific revisions wanted
+ // make sure order is correct (older on the left)
+ if($rev1 < $rev2) {
+ $l_rev = $rev1;
+ $r_rev = $rev2;
+ } else {
+ $l_rev = $rev2;
+ $r_rev = $rev1;
+ }
+ } elseif($rev1) { // single revision given, compare to current
+ $r_rev = '';
+ $l_rev = $rev1;
+ } else { // no revision was given, compare previous to current
+ $r_rev = '';
+ $revs = $pagelog->getRevisions(0, 1);
+ $l_rev = $revs[0];
+ $REV = $l_rev; // store revision back in $REV
+ }
+
+ // when both revisions are empty then the page was created just now
+ if(!$l_rev && !$r_rev) {
+ $l_text = '';
+ } else {
+ $l_text = rawWiki($ID, $l_rev);
+ }
+ $r_text = rawWiki($ID, $r_rev);
+
+ list($l_head, $r_head, $l_minor, $r_minor) = html_diff_head($l_rev, $r_rev, null, false, $type == 'inline');
+ }
+
+ /*
+ * Build navigation
+ */
+ $l_nav = '';
+ $r_nav = '';
+ if(!$text) {
+ list($l_nav, $r_nav) = html_diff_navigation($pagelog, $type, $l_rev, $r_rev);
+ }
+ /*
+ * Create diff object and the formatter
+ */
+ $diff = new Diff(explode("\n", $l_text), explode("\n", $r_text));
+
+ if($type == 'inline') {
+ $diffformatter = new InlineDiffFormatter();
+ } else {
+ $diffformatter = new TableDiffFormatter();
+ }
+ /*
+ * Display intro
+ */
+ if($intro) print p_locale_xhtml('diff');
+
+ /*
+ * Display type and exact reference
+ */
+ if(!$text) {
+ ptln('<div class="diffoptions group">');
+
+
+ $form = new Doku_Form(array('action' => wl()));
+ $form->addHidden('id', $ID);
+ $form->addHidden('rev2[0]', $l_rev);
+ $form->addHidden('rev2[1]', $r_rev);
+ $form->addHidden('do', 'diff');
+ $form->addElement(
+ form_makeListboxField(
+ 'difftype',
+ array(
+ 'sidebyside' => $lang['diff_side'],
+ 'inline' => $lang['diff_inline']
+ ),
+ $type,
+ $lang['diff_type'],
+ '', '',
+ array('class' => 'quickselect')
+ )
+ );
+ $form->addElement(form_makeButton('submit', 'diff', 'Go'));
+ $form->printForm();
+
+ ptln('<p>');
+ // link to exactly this view FS#2835
+ echo html_diff_navigationlink($type, 'difflink', $l_rev, $r_rev ? $r_rev : $INFO['currentrev']);
+ ptln('</p>');
+
+ ptln('</div>'); // .diffoptions
+ }
+
+ /*
+ * Display diff view table
+ */
+ ?>
+ <div class="table">
+ <table class="diff diff_<?php echo $type ?>">
+
+ <?php
+ //navigation and header
+ if($type == 'inline') {
+ if(!$text) { ?>
+ <tr>
+ <td class="diff-lineheader">-</td>
+ <td class="diffnav"><?php echo $l_nav ?></td>
+ </tr>
+ <tr>
+ <th class="diff-lineheader">-</th>
+ <th <?php echo $l_minor ?>>
+ <?php echo $l_head ?>
+ </th>
+ </tr>
+ <?php } ?>
+ <tr>
+ <td class="diff-lineheader">+</td>
+ <td class="diffnav"><?php echo $r_nav ?></td>
+ </tr>
+ <tr>
+ <th class="diff-lineheader">+</th>
+ <th <?php echo $r_minor ?>>
+ <?php echo $r_head ?>
+ </th>
+ </tr>
+ <?php } else {
+ if(!$text) { ?>
+ <tr>
+ <td colspan="2" class="diffnav"><?php echo $l_nav ?></td>
+ <td colspan="2" class="diffnav"><?php echo $r_nav ?></td>
+ </tr>
+ <?php } ?>
+ <tr>
+ <th colspan="2" <?php echo $l_minor ?>>
+ <?php echo $l_head ?>
+ </th>
+ <th colspan="2" <?php echo $r_minor ?>>
+ <?php echo $r_head ?>
+ </th>
+ </tr>
+ <?php }
+
+ //diff view
+ echo html_insert_softbreaks($diffformatter->format($diff)); ?>
+
+ </table>
+ </div>
+<?php
+}
+
+/**
+ * Create html for revision navigation
+ *
+ * @param PageChangeLog $pagelog changelog object of current page
+ * @param string $type inline vs sidebyside
+ * @param int $l_rev left revision timestamp
+ * @param int $r_rev right revision timestamp
+ * @return string[] html of left and right navigation elements
+ */
+function html_diff_navigation($pagelog, $type, $l_rev, $r_rev) {
+ global $INFO, $ID;
+
+ // last timestamp is not in changelog, retrieve timestamp from metadata
+ // note: when page is removed, the metadata timestamp is zero
+ if(!$r_rev) {
+ if(isset($INFO['meta']['last_change']['date'])) {
+ $r_rev = $INFO['meta']['last_change']['date'];
+ } else {
+ $r_rev = 0;
+ }
+ }
+
+ //retrieve revisions with additional info
+ list($l_revs, $r_revs) = $pagelog->getRevisionsAround($l_rev, $r_rev);
+ $l_revisions = array();
+ if(!$l_rev) {
+ $l_revisions[0] = array(0, "", false); //no left revision given, add dummy
+ }
+ foreach($l_revs as $rev) {
+ $info = $pagelog->getRevisionInfo($rev);
+ $l_revisions[$rev] = array(
+ $rev,
+ dformat($info['date']) . ' ' . editorinfo($info['user'], true) . ' ' . $info['sum'],
+ $r_rev ? $rev >= $r_rev : false //disable?
+ );
+ }
+ $r_revisions = array();
+ if(!$r_rev) {
+ $r_revisions[0] = array(0, "", false); //no right revision given, add dummy
+ }
+ foreach($r_revs as $rev) {
+ $info = $pagelog->getRevisionInfo($rev);
+ $r_revisions[$rev] = array(
+ $rev,
+ dformat($info['date']) . ' ' . editorinfo($info['user'], true) . ' ' . $info['sum'],
+ $rev <= $l_rev //disable?
+ );
+ }
+
+ //determine previous/next revisions
+ $l_index = array_search($l_rev, $l_revs);
+ $l_prev = $l_revs[$l_index + 1];
+ $l_next = $l_revs[$l_index - 1];
+ if($r_rev) {
+ $r_index = array_search($r_rev, $r_revs);
+ $r_prev = $r_revs[$r_index + 1];
+ $r_next = $r_revs[$r_index - 1];
+ } else {
+ //removed page
+ if($l_next) {
+ $r_prev = $r_revs[0];
+ } else {
+ $r_prev = null;
+ }
+ $r_next = null;
+ }
+
+ /*
+ * Left side:
+ */
+ $l_nav = '';
+ //move back
+ if($l_prev) {
+ $l_nav .= html_diff_navigationlink($type, 'diffbothprevrev', $l_prev, $r_prev);
+ $l_nav .= html_diff_navigationlink($type, 'diffprevrev', $l_prev, $r_rev);
+ }
+ //dropdown
+ $form = new Doku_Form(array('action' => wl()));
+ $form->addHidden('id', $ID);
+ $form->addHidden('difftype', $type);
+ $form->addHidden('rev2[1]', $r_rev);
+ $form->addHidden('do', 'diff');
+ $form->addElement(
+ form_makeListboxField(
+ 'rev2[0]',
+ $l_revisions,
+ $l_rev,
+ '', '', '',
+ array('class' => 'quickselect')
+ )
+ );
+ $form->addElement(form_makeButton('submit', 'diff', 'Go'));
+ $l_nav .= $form->getForm();
+ //move forward
+ if($l_next && ($l_next < $r_rev || !$r_rev)) {
+ $l_nav .= html_diff_navigationlink($type, 'diffnextrev', $l_next, $r_rev);
+ }
+
+ /*
+ * Right side:
+ */
+ $r_nav = '';
+ //move back
+ if($l_rev < $r_prev) {
+ $r_nav .= html_diff_navigationlink($type, 'diffprevrev', $l_rev, $r_prev);
+ }
+ //dropdown
+ $form = new Doku_Form(array('action' => wl()));
+ $form->addHidden('id', $ID);
+ $form->addHidden('rev2[0]', $l_rev);
+ $form->addHidden('difftype', $type);
+ $form->addHidden('do', 'diff');
+ $form->addElement(
+ form_makeListboxField(
+ 'rev2[1]',
+ $r_revisions,
+ $r_rev,
+ '', '', '',
+ array('class' => 'quickselect')
+ )
+ );
+ $form->addElement(form_makeButton('submit', 'diff', 'Go'));
+ $r_nav .= $form->getForm();
+ //move forward
+ if($r_next) {
+ if($pagelog->isCurrentRevision($r_next)) {
+ $r_nav .= html_diff_navigationlink($type, 'difflastrev', $l_rev); //last revision is diff with current page
+ } else {
+ $r_nav .= html_diff_navigationlink($type, 'diffnextrev', $l_rev, $r_next);
+ }
+ $r_nav .= html_diff_navigationlink($type, 'diffbothnextrev', $l_next, $r_next);
+ }
+ return array($l_nav, $r_nav);
+}
+
+/**
+ * Create html link to a diff defined by two revisions
+ *
+ * @param string $difftype display type
+ * @param string $linktype
+ * @param int $lrev oldest revision
+ * @param int $rrev newest revision or null for diff with current revision
+ * @return string html of link to a diff
+ */
+function html_diff_navigationlink($difftype, $linktype, $lrev, $rrev = null) {
+ global $ID, $lang;
+ if(!$rrev) {
+ $urlparam = array(
+ 'do' => 'diff',
+ 'rev' => $lrev,
+ 'difftype' => $difftype,
+ );
+ } else {
+ $urlparam = array(
+ 'do' => 'diff',
+ 'rev2[0]' => $lrev,
+ 'rev2[1]' => $rrev,
+ 'difftype' => $difftype,
+ );
+ }
+ return '<a class="' . $linktype . '" href="' . wl($ID, $urlparam) . '" title="' . $lang[$linktype] . '">' .
+ '<span>' . $lang[$linktype] . '</span>' .
+ '</a>' . "\n";
+}
+
+/**
+ * Insert soft breaks in diff html
+ *
+ * @param string $diffhtml
+ * @return string
+ */
+function html_insert_softbreaks($diffhtml) {
+ // search the diff html string for both:
+ // - html tags, so these can be ignored
+ // - long strings of characters without breaking characters
+ return preg_replace_callback('/<[^>]*>|[^<> ]{12,}/','html_softbreak_callback',$diffhtml);
+}
+
+/**
+ * callback which adds softbreaks
+ *
+ * @param array $match array with first the complete match
+ * @return string the replacement
+ */
+function html_softbreak_callback($match){
+ // if match is an html tag, return it intact
+ if ($match[0][0] == '<') return $match[0];
+
+ // its a long string without a breaking character,
+ // make certain characters into breaking characters by inserting a
+ // word break opportunity (<wbr> tag) in front of them.
+ $regex = <<< REGEX
+(?(?= # start a conditional expression with a positive look ahead ...
+&\#?\\w{1,6};) # ... for html entities - we don't want to split them (ok to catch some invalid combinations)
+&\#?\\w{1,6}; # yes pattern - a quicker match for the html entity, since we know we have one
+|
+[?/,&\#;:] # no pattern - any other group of 'special' characters to insert a breaking character after
+)+ # end conditional expression
+REGEX;
+
+ return preg_replace('<'.$regex.'>xu','\0<wbr>',$match[0]);
+}
+
+/**
+ * show warning on conflict detection
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $text
+ * @param string $summary
+ */
+function html_conflict($text,$summary){
+ global $ID;
+ global $lang;
+
+ print p_locale_xhtml('conflict');
+ $form = new Doku_Form(array('id' => 'dw__editform'));
+ $form->addHidden('id', $ID);
+ $form->addHidden('wikitext', $text);
+ $form->addHidden('summary', $summary);
+ $form->addElement(form_makeButton('submit', 'save', $lang['btn_save'], array('accesskey'=>'s')));
+ $form->addElement(form_makeButton('submit', 'cancel', $lang['btn_cancel']));
+ html_form('conflict', $form);
+ print '<br /><br /><br /><br />'.NL;
+}
+
+/**
+ * Prints the global message array
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_msgarea(){
+ global $MSG, $MSG_shown;
+ /** @var array $MSG */
+ // store if the global $MSG has already been shown and thus HTML output has been started
+ $MSG_shown = true;
+
+ if(!isset($MSG)) return;
+
+ $shown = array();
+ foreach($MSG as $msg){
+ $hash = md5($msg['msg']);
+ if(isset($shown[$hash])) continue; // skip double messages
+ if(info_msg_allowed($msg)){
+ print '<div class="'.$msg['lvl'].'">';
+ print $msg['msg'];
+ print '</div>';
+ }
+ $shown[$hash] = 1;
+ }
+
+ unset($GLOBALS['MSG']);
+}
+
+/**
+ * Prints the registration form
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_register(){
+ global $lang;
+ global $conf;
+ global $INPUT;
+
+ $base_attrs = array('size'=>50,'required'=>'required');
+ $email_attrs = $base_attrs + array('type'=>'email','class'=>'edit');
+
+ print p_locale_xhtml('register');
+ print '<div class="centeralign">'.NL;
+ $form = new Doku_Form(array('id' => 'dw__register'));
+ $form->startFieldset($lang['btn_register']);
+ $form->addHidden('do', 'register');
+ $form->addHidden('save', '1');
+ $form->addElement(
+ form_makeTextField(
+ 'login',
+ $INPUT->post->str('login'),
+ $lang['user'],
+ '',
+ 'block',
+ $base_attrs
+ )
+ );
+ if (!$conf['autopasswd']) {
+ $form->addElement(form_makePasswordField('pass', $lang['pass'], '', 'block', $base_attrs));
+ $form->addElement(form_makePasswordField('passchk', $lang['passchk'], '', 'block', $base_attrs));
+ }
+ $form->addElement(
+ form_makeTextField(
+ 'fullname',
+ $INPUT->post->str('fullname'),
+ $lang['fullname'],
+ '',
+ 'block',
+ $base_attrs
+ )
+ );
+ $form->addElement(
+ form_makeField(
+ 'email',
+ 'email',
+ $INPUT->post->str('email'),
+ $lang['email'],
+ '',
+ 'block',
+ $email_attrs
+ )
+ );
+ $form->addElement(form_makeButton('submit', '', $lang['btn_register']));
+ $form->endFieldset();
+ html_form('register', $form);
+
+ print '</div>'.NL;
+}
+
+/**
+ * Print the update profile form
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_updateprofile(){
+ global $lang;
+ global $conf;
+ global $INPUT;
+ global $INFO;
+ /** @var AuthPlugin $auth */
+ global $auth;
+
+ print p_locale_xhtml('updateprofile');
+ print '<div class="centeralign">'.NL;
+
+ $fullname = $INPUT->post->str('fullname', $INFO['userinfo']['name'], true);
+ $email = $INPUT->post->str('email', $INFO['userinfo']['mail'], true);
+ $form = new Doku_Form(array('id' => 'dw__register'));
+ $form->startFieldset($lang['profile']);
+ $form->addHidden('do', 'profile');
+ $form->addHidden('save', '1');
+ $form->addElement(
+ form_makeTextField(
+ 'login',
+ $_SERVER['REMOTE_USER'],
+ $lang['user'],
+ '',
+ 'block',
+ array('size' => '50', 'disabled' => 'disabled')
+ )
+ );
+ $attr = array('size'=>'50');
+ if (!$auth->canDo('modName')) $attr['disabled'] = 'disabled';
+ $form->addElement(form_makeTextField('fullname', $fullname, $lang['fullname'], '', 'block', $attr));
+ $attr = array('size'=>'50', 'class'=>'edit');
+ if (!$auth->canDo('modMail')) $attr['disabled'] = 'disabled';
+ $form->addElement(form_makeField('email','email', $email, $lang['email'], '', 'block', $attr));
+ $form->addElement(form_makeTag('br'));
+ if ($auth->canDo('modPass')) {
+ $form->addElement(form_makePasswordField('newpass', $lang['newpass'], '', 'block', array('size'=>'50')));
+ $form->addElement(form_makePasswordField('passchk', $lang['passchk'], '', 'block', array('size'=>'50')));
+ }
+ if ($conf['profileconfirm']) {
+ $form->addElement(form_makeTag('br'));
+ $form->addElement(
+ form_makePasswordField(
+ 'oldpass',
+ $lang['oldpass'],
+ '',
+ 'block',
+ array('size' => '50', 'required' => 'required')
+ )
+ );
+ }
+ $form->addElement(form_makeButton('submit', '', $lang['btn_save']));
+ $form->addElement(form_makeButton('reset', '', $lang['btn_reset']));
+
+ $form->endFieldset();
+ html_form('updateprofile', $form);
+
+ if ($auth->canDo('delUser') && actionOK('profile_delete')) {
+ $form_profiledelete = new Doku_Form(array('id' => 'dw__profiledelete'));
+ $form_profiledelete->startFieldset($lang['profdeleteuser']);
+ $form_profiledelete->addHidden('do', 'profile_delete');
+ $form_profiledelete->addHidden('delete', '1');
+ $form_profiledelete->addElement(
+ form_makeCheckboxField(
+ 'confirm_delete',
+ '1',
+ $lang['profconfdelete'],
+ 'dw__confirmdelete',
+ '',
+ array('required' => 'required')
+ )
+ );
+ if ($conf['profileconfirm']) {
+ $form_profiledelete->addElement(form_makeTag('br'));
+ $form_profiledelete->addElement(
+ form_makePasswordField(
+ 'oldpass',
+ $lang['oldpass'],
+ '',
+ 'block',
+ array('size' => '50', 'required' => 'required')
+ )
+ );
+ }
+ $form_profiledelete->addElement(form_makeButton('submit', '', $lang['btn_deleteuser']));
+ $form_profiledelete->endFieldset();
+
+ html_form('profiledelete', $form_profiledelete);
+ }
+
+ print '</div>'.NL;
+}
+
+/**
+ * Preprocess edit form data
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @triggers HTML_EDITFORM_OUTPUT
+ */
+function html_edit(){
+ global $INPUT;
+ global $ID;
+ global $REV;
+ global $DATE;
+ global $PRE;
+ global $SUF;
+ global $INFO;
+ global $SUM;
+ global $lang;
+ global $conf;
+ global $TEXT;
+
+ if ($INPUT->has('changecheck')) {
+ $check = $INPUT->str('changecheck');
+ } elseif(!$INFO['exists']){
+ // $TEXT has been loaded from page template
+ $check = md5('');
+ } else {
+ $check = md5($TEXT);
+ }
+ $mod = md5($TEXT) !== $check;
+
+ $wr = $INFO['writable'] && !$INFO['locked'];
+ $include = 'edit';
+ if($wr){
+ if ($REV) $include = 'editrev';
+ }else{
+ // check pseudo action 'source'
+ if(!actionOK('source')){
+ msg('Command disabled: source',-1);
+ return;
+ }
+ $include = 'read';
+ }
+
+ global $license;
+
+ $form = new Doku_Form(array('id' => 'dw__editform'));
+ $form->addHidden('id', $ID);
+ $form->addHidden('rev', $REV);
+ $form->addHidden('date', $DATE);
+ $form->addHidden('prefix', $PRE . '.');
+ $form->addHidden('suffix', $SUF);
+ $form->addHidden('changecheck', $check);
+
+ $data = array('form' => $form,
+ 'wr' => $wr,
+ 'media_manager' => true,
+ 'target' => ($INPUT->has('target') && $wr) ? $INPUT->str('target') : 'section',
+ 'intro_locale' => $include);
+
+ if ($data['target'] !== 'section') {
+ // Only emit event if page is writable, section edit data is valid and
+ // edit target is not section.
+ Event::createAndTrigger('HTML_EDIT_FORMSELECTION', $data, 'html_edit_form', true);
+ } else {
+ html_edit_form($data);
+ }
+ if (isset($data['intro_locale'])) {
+ echo p_locale_xhtml($data['intro_locale']);
+ }
+
+ $form->addHidden('target', $data['target']);
+ if ($INPUT->has('hid')) {
+ $form->addHidden('hid', $INPUT->str('hid'));
+ }
+ if ($INPUT->has('codeblockOffset')) {
+ $form->addHidden('codeblockOffset', $INPUT->str('codeblockOffset'));
+ }
+ $form->addElement(form_makeOpenTag('div', array('id'=>'wiki__editbar', 'class'=>'editBar')));
+ $form->addElement(form_makeOpenTag('div', array('id'=>'size__ctl')));
+ $form->addElement(form_makeCloseTag('div'));
+ if ($wr) {
+ $form->addElement(form_makeOpenTag('div', array('class'=>'editButtons')));
+ $form->addElement(
+ form_makeButton(
+ 'submit',
+ 'save',
+ $lang['btn_save'],
+ array('id' => 'edbtn__save', 'accesskey' => 's', 'tabindex' => '4')
+ )
+ );
+ $form->addElement(
+ form_makeButton(
+ 'submit',
+ 'preview',
+ $lang['btn_preview'],
+ array('id' => 'edbtn__preview', 'accesskey' => 'p', 'tabindex' => '5')
+ )
+ );
+ $form->addElement(form_makeButton('submit', 'cancel', $lang['btn_cancel'], array('tabindex'=>'6')));
+ $form->addElement(form_makeCloseTag('div'));
+ $form->addElement(form_makeOpenTag('div', array('class'=>'summary')));
+ $form->addElement(
+ form_makeTextField(
+ 'summary',
+ $SUM,
+ $lang['summary'],
+ 'edit__summary',
+ 'nowrap',
+ array('size' => '50', 'tabindex' => '2')
+ )
+ );
+ $elem = html_minoredit();
+ if ($elem) $form->addElement($elem);
+ $form->addElement(form_makeCloseTag('div'));
+ }
+ $form->addElement(form_makeCloseTag('div'));
+ if($wr && $conf['license']){
+ $form->addElement(form_makeOpenTag('div', array('class'=>'license')));
+ $out = $lang['licenseok'];
+ $out .= ' <a href="'.$license[$conf['license']]['url'].'" rel="license" class="urlextern"';
+ if($conf['target']['extern']) $out .= ' target="'.$conf['target']['extern'].'"';
+ $out .= '>'.$license[$conf['license']]['name'].'</a>';
+ $form->addElement($out);
+ $form->addElement(form_makeCloseTag('div'));
+ }
+
+ if ($wr) {
+ // sets changed to true when previewed
+ echo '<script>/*<![CDATA[*/'. NL;
+ echo 'textChanged = ' . ($mod ? 'true' : 'false');
+ echo '/*!]]>*/</script>' . NL;
+ } ?>
+ <div class="editBox" role="application">
+
+ <div class="toolbar group">
+ <div id="tool__bar" class="tool__bar"><?php
+ if ($wr && $data['media_manager']){
+ ?><a href="<?php echo DOKU_BASE?>lib/exe/mediamanager.php?ns=<?php echo $INFO['namespace']?>"
+ target="_blank"><?php echo $lang['mediaselect'] ?></a><?php
+ }?>
+ </div>
+ </div>
+ <div id="draft__status" class="draft__status">
+ <?php
+ $draft = new \dokuwiki\Draft($ID, $INFO['client']);
+ if ($draft->isDraftAvailable()) {
+ echo $draft->getDraftMessage();
+ }
+ ?>
+ </div>
+ <?php
+
+ html_form('edit', $form);
+ print '</div>'.NL;
+}
+
+/**
+ * Display the default edit form
+ *
+ * Is the default action for HTML_EDIT_FORMSELECTION.
+ *
+ * @param mixed[] $param
+ */
+function html_edit_form($param) {
+ global $TEXT;
+
+ if ($param['target'] !== 'section') {
+ msg('No editor for edit target ' . hsc($param['target']) . ' found.', -1);
+ }
+
+ $attr = array('tabindex'=>'1');
+ if (!$param['wr']) $attr['readonly'] = 'readonly';
+
+ $param['form']->addElement(form_makeWikiText($TEXT, $attr));
+}
+
+/**
+ * Adds a checkbox for minor edits for logged in users
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return array|bool
+ */
+function html_minoredit(){
+ global $conf;
+ global $lang;
+ global $INPUT;
+ // minor edits are for logged in users only
+ if(!$conf['useacl'] || !$_SERVER['REMOTE_USER']){
+ return false;
+ }
+
+ $p = array();
+ $p['tabindex'] = 3;
+ if($INPUT->bool('minor')) $p['checked']='checked';
+ return form_makeCheckboxField('minor', '1', $lang['minoredit'], 'minoredit', 'nowrap', $p);
+}
+
+/**
+ * prints some debug info
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function html_debug(){
+ global $conf;
+ global $lang;
+ /** @var AuthPlugin $auth */
+ global $auth;
+ global $INFO;
+
+ //remove sensitive data
+ $cnf = $conf;
+ debug_guard($cnf);
+ $nfo = $INFO;
+ debug_guard($nfo);
+ $ses = $_SESSION;
+ debug_guard($ses);
+
+ print '<html><body>';
+
+ print '<p>When reporting bugs please send all the following ';
+ print 'output as a mail to andi@splitbrain.org ';
+ print 'The best way to do this is to save this page in your browser</p>';
+
+ print '<b>$INFO:</b><pre>';
+ print_r($nfo);
+ print '</pre>';
+
+ print '<b>$_SERVER:</b><pre>';
+ print_r($_SERVER);
+ print '</pre>';
+
+ print '<b>$conf:</b><pre>';
+ print_r($cnf);
+ print '</pre>';
+
+ print '<b>DOKU_BASE:</b><pre>';
+ print DOKU_BASE;
+ print '</pre>';
+
+ print '<b>abs DOKU_BASE:</b><pre>';
+ print DOKU_URL;
+ print '</pre>';
+
+ print '<b>rel DOKU_BASE:</b><pre>';
+ print dirname($_SERVER['PHP_SELF']).'/';
+ print '</pre>';
+
+ print '<b>PHP Version:</b><pre>';
+ print phpversion();
+ print '</pre>';
+
+ print '<b>locale:</b><pre>';
+ print setlocale(LC_ALL,0);
+ print '</pre>';
+
+ print '<b>encoding:</b><pre>';
+ print $lang['encoding'];
+ print '</pre>';
+
+ if($auth){
+ print '<b>Auth backend capabilities:</b><pre>';
+ foreach ($auth->getCapabilities() as $cando){
+ print ' '.str_pad($cando,16) . ' => ' . (int)$auth->canDo($cando) . NL;
+ }
+ print '</pre>';
+ }
+
+ print '<b>$_SESSION:</b><pre>';
+ print_r($ses);
+ print '</pre>';
+
+ print '<b>Environment:</b><pre>';
+ print_r($_ENV);
+ print '</pre>';
+
+ print '<b>PHP settings:</b><pre>';
+ $inis = ini_get_all();
+ print_r($inis);
+ print '</pre>';
+
+ if (function_exists('apache_get_version')) {
+ $apache = array();
+ $apache['version'] = apache_get_version();
+
+ if (function_exists('apache_get_modules')) {
+ $apache['modules'] = apache_get_modules();
+ }
+ print '<b>Apache</b><pre>';
+ print_r($apache);
+ print '</pre>';
+ }
+
+ print '</body></html>';
+}
+
+/**
+ * Form to request a new password for an existing account
+ *
+ * @author Benoit Chesneau <benoit@bchesneau.info>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+function html_resendpwd() {
+ global $lang;
+ global $conf;
+ global $INPUT;
+
+ $token = preg_replace('/[^a-f0-9]+/','',$INPUT->str('pwauth'));
+
+ if(!$conf['autopasswd'] && $token){
+ print p_locale_xhtml('resetpwd');
+ print '<div class="centeralign">'.NL;
+ $form = new Doku_Form(array('id' => 'dw__resendpwd'));
+ $form->startFieldset($lang['btn_resendpwd']);
+ $form->addHidden('token', $token);
+ $form->addHidden('do', 'resendpwd');
+
+ $form->addElement(form_makePasswordField('pass', $lang['pass'], '', 'block', array('size'=>'50')));
+ $form->addElement(form_makePasswordField('passchk', $lang['passchk'], '', 'block', array('size'=>'50')));
+
+ $form->addElement(form_makeButton('submit', '', $lang['btn_resendpwd']));
+ $form->endFieldset();
+ html_form('resendpwd', $form);
+ print '</div>'.NL;
+ }else{
+ print p_locale_xhtml('resendpwd');
+ print '<div class="centeralign">'.NL;
+ $form = new Doku_Form(array('id' => 'dw__resendpwd'));
+ $form->startFieldset($lang['resendpwd']);
+ $form->addHidden('do', 'resendpwd');
+ $form->addHidden('save', '1');
+ $form->addElement(form_makeTag('br'));
+ $form->addElement(form_makeTextField('login', $INPUT->post->str('login'), $lang['user'], '', 'block'));
+ $form->addElement(form_makeTag('br'));
+ $form->addElement(form_makeTag('br'));
+ $form->addElement(form_makeButton('submit', '', $lang['btn_resendpwd']));
+ $form->endFieldset();
+ html_form('resendpwd', $form);
+ print '</div>'.NL;
+ }
+}
+
+/**
+ * Return the TOC rendered to XHTML
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $toc
+ * @return string html
+ */
+function html_TOC($toc){
+ if(!count($toc)) return '';
+ global $lang;
+ $out = '<!-- TOC START -->'.DOKU_LF;
+ $out .= '<div id="dw__toc" class="dw__toc">'.DOKU_LF;
+ $out .= '<h3 class="toggle">';
+ $out .= $lang['toc'];
+ $out .= '</h3>'.DOKU_LF;
+ $out .= '<div>'.DOKU_LF;
+ $out .= html_buildlist($toc,'toc','html_list_toc','html_li_default',true);
+ $out .= '</div>'.DOKU_LF.'</div>'.DOKU_LF;
+ $out .= '<!-- TOC END -->'.DOKU_LF;
+ return $out;
+}
+
+/**
+ * Callback for html_buildlist
+ *
+ * @param array $item
+ * @return string html
+ */
+function html_list_toc($item){
+ if(isset($item['hid'])){
+ $link = '#'.$item['hid'];
+ }else{
+ $link = $item['link'];
+ }
+
+ return '<a href="'.$link.'">'.hsc($item['title']).'</a>';
+}
+
+/**
+ * Helper function to build TOC items
+ *
+ * Returns an array ready to be added to a TOC array
+ *
+ * @param string $link - where to link (if $hash set to '#' it's a local anchor)
+ * @param string $text - what to display in the TOC
+ * @param int $level - nesting level
+ * @param string $hash - is prepended to the given $link, set blank if you want full links
+ * @return array the toc item
+ */
+function html_mktocitem($link, $text, $level, $hash='#'){
+ return array( 'link' => $hash.$link,
+ 'title' => $text,
+ 'type' => 'ul',
+ 'level' => $level);
+}
+
+/**
+ * Output a Doku_Form object.
+ * Triggers an event with the form name: HTML_{$name}FORM_OUTPUT
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $name The name of the form
+ * @param Doku_Form $form The form
+ */
+function html_form($name, &$form) {
+ // Safety check in case the caller forgets.
+ $form->endFieldset();
+ Event::createAndTrigger('HTML_'.strtoupper($name).'FORM_OUTPUT', $form, 'html_form_output', false);
+}
+
+/**
+ * Form print function.
+ * Just calls printForm() on the data object.
+ *
+ * @param Doku_Form $data The form
+ */
+function html_form_output($data) {
+ $data->printForm();
+}
+
+/**
+ * Embed a flash object in HTML
+ *
+ * This will create the needed HTML to embed a flash movie in a cross browser
+ * compatble way using valid XHTML
+ *
+ * The parameters $params, $flashvars and $atts need to be associative arrays.
+ * No escaping needs to be done for them. The alternative content *has* to be
+ * escaped because it is used as is. If no alternative content is given
+ * $lang['noflash'] is used.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @link http://latrine.dgx.cz/how-to-correctly-insert-a-flash-into-xhtml
+ *
+ * @param string $swf - the SWF movie to embed
+ * @param int $width - width of the flash movie in pixels
+ * @param int $height - height of the flash movie in pixels
+ * @param array $params - additional parameters (<param>)
+ * @param array $flashvars - parameters to be passed in the flashvar parameter
+ * @param array $atts - additional attributes for the <object> tag
+ * @param string $alt - alternative content (is NOT automatically escaped!)
+ * @return string - the XHTML markup
+ */
+function html_flashobject($swf,$width,$height,$params=null,$flashvars=null,$atts=null,$alt=''){
+ global $lang;
+
+ $out = '';
+
+ // prepare the object attributes
+ if(is_null($atts)) $atts = array();
+ $atts['width'] = (int) $width;
+ $atts['height'] = (int) $height;
+ if(!$atts['width']) $atts['width'] = 425;
+ if(!$atts['height']) $atts['height'] = 350;
+
+ // add object attributes for standard compliant browsers
+ $std = $atts;
+ $std['type'] = 'application/x-shockwave-flash';
+ $std['data'] = $swf;
+
+ // add object attributes for IE
+ $ie = $atts;
+ $ie['classid'] = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
+
+ // open object (with conditional comments)
+ $out .= '<!--[if !IE]> -->'.NL;
+ $out .= '<object '.buildAttributes($std).'>'.NL;
+ $out .= '<!-- <![endif]-->'.NL;
+ $out .= '<!--[if IE]>'.NL;
+ $out .= '<object '.buildAttributes($ie).'>'.NL;
+ $out .= ' <param name="movie" value="'.hsc($swf).'" />'.NL;
+ $out .= '<!--><!-- -->'.NL;
+
+ // print params
+ if(is_array($params)) foreach($params as $key => $val){
+ $out .= ' <param name="'.hsc($key).'" value="'.hsc($val).'" />'.NL;
+ }
+
+ // add flashvars
+ if(is_array($flashvars)){
+ $out .= ' <param name="FlashVars" value="'.buildURLparams($flashvars).'" />'.NL;
+ }
+
+ // alternative content
+ if($alt){
+ $out .= $alt.NL;
+ }else{
+ $out .= $lang['noflash'].NL;
+ }
+
+ // finish
+ $out .= '</object>'.NL;
+ $out .= '<!-- <![endif]-->'.NL;
+
+ return $out;
+}
+
+/**
+ * Prints HTML code for the given tab structure
+ *
+ * @param array $tabs tab structure
+ * @param string $current_tab the current tab id
+ */
+function html_tabs($tabs, $current_tab = null) {
+ echo '<ul class="tabs">'.NL;
+
+ foreach($tabs as $id => $tab) {
+ html_tab($tab['href'], $tab['caption'], $id === $current_tab);
+ }
+
+ echo '</ul>'.NL;
+}
+
+/**
+ * Prints a single tab
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ * @author Adrian Lang <mail@adrianlang.de>
+ *
+ * @param string $href - tab href
+ * @param string $caption - tab caption
+ * @param boolean $selected - is tab selected
+ */
+
+function html_tab($href, $caption, $selected=false) {
+ $tab = '<li>';
+ if ($selected) {
+ $tab .= '<strong>';
+ } else {
+ $tab .= '<a href="' . hsc($href) . '">';
+ }
+ $tab .= hsc($caption)
+ . '</' . ($selected ? 'strong' : 'a') . '>'
+ . '</li>'.NL;
+ echo $tab;
+}
+
+/**
+ * Display size change
+ *
+ * @param int $sizechange - size of change in Bytes
+ * @param Doku_Form $form - form to add elements to
+ */
+
+function html_sizechange($sizechange, Doku_Form $form) {
+ if(isset($sizechange)) {
+ $class = 'sizechange';
+ $value = filesize_h(abs($sizechange));
+ if($sizechange > 0) {
+ $class .= ' positive';
+ $value = '+' . $value;
+ } elseif($sizechange < 0) {
+ $class .= ' negative';
+ $value = '-' . $value;
+ } else {
+ $value = '±' . $value;
+ }
+ $form->addElement(form_makeOpenTag('span', array('class' => $class)));
+ $form->addElement($value);
+ $form->addElement(form_makeCloseTag('span'));
+ }
+}
diff --git a/platform/www/inc/httputils.php b/platform/www/inc/httputils.php
new file mode 100644
index 0000000..c365f4f
--- /dev/null
+++ b/platform/www/inc/httputils.php
@@ -0,0 +1,346 @@
+<?php
+/**
+ * Utilities for handling HTTP related tasks
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+define('HTTP_MULTIPART_BOUNDARY','D0KuW1K1B0uNDARY');
+define('HTTP_HEADER_LF',"\r\n");
+define('HTTP_CHUNK_SIZE',16*1024);
+
+/**
+ * Checks and sets HTTP headers for conditional HTTP requests
+ *
+ * @author Simon Willison <swillison@gmail.com>
+ * @link http://simonwillison.net/2003/Apr/23/conditionalGet/
+ *
+ * @param int $timestamp lastmodified time of the cache file
+ * @returns void or exits with previously header() commands executed
+ */
+function http_conditionalRequest($timestamp){
+ // A PHP implementation of conditional get, see
+ // http://fishbowl.pastiche.org/2002/10/21/http_conditional_get_for_rss_hackers/
+ $last_modified = substr(gmdate('r', $timestamp), 0, -5).'GMT';
+ $etag = '"'.md5($last_modified).'"';
+ // Send the headers
+ header("Last-Modified: $last_modified");
+ header("ETag: $etag");
+ // See if the client has provided the required headers
+ if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])){
+ $if_modified_since = stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']);
+ }else{
+ $if_modified_since = false;
+ }
+
+ if (isset($_SERVER['HTTP_IF_NONE_MATCH'])){
+ $if_none_match = stripslashes($_SERVER['HTTP_IF_NONE_MATCH']);
+ }else{
+ $if_none_match = false;
+ }
+
+ if (!$if_modified_since && !$if_none_match){
+ return;
+ }
+
+ // At least one of the headers is there - check them
+ if ($if_none_match && $if_none_match != $etag) {
+ return; // etag is there but doesn't match
+ }
+
+ if ($if_modified_since && $if_modified_since != $last_modified) {
+ return; // if-modified-since is there but doesn't match
+ }
+
+ // Nothing has changed since their last request - serve a 304 and exit
+ header('HTTP/1.0 304 Not Modified');
+
+ // don't produce output, even if compression is on
+ @ob_end_clean();
+ exit;
+}
+
+/**
+ * Let the webserver send the given file via x-sendfile method
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $file absolute path of file to send
+ * @returns void or exits with previous header() commands executed
+ */
+function http_sendfile($file) {
+ global $conf;
+
+ //use x-sendfile header to pass the delivery to compatible web servers
+ if($conf['xsendfile'] == 1){
+ header("X-LIGHTTPD-send-file: $file");
+ ob_end_clean();
+ exit;
+ }elseif($conf['xsendfile'] == 2){
+ header("X-Sendfile: $file");
+ ob_end_clean();
+ exit;
+ }elseif($conf['xsendfile'] == 3){
+ // FS#2388 nginx just needs the relative path.
+ $file = DOKU_REL.substr($file, strlen(fullpath(DOKU_INC)) + 1);
+ header("X-Accel-Redirect: $file");
+ ob_end_clean();
+ exit;
+ }
+}
+
+/**
+ * Send file contents supporting rangeRequests
+ *
+ * This function exits the running script
+ *
+ * @param resource $fh - file handle for an already open file
+ * @param int $size - size of the whole file
+ * @param int $mime - MIME type of the file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function http_rangeRequest($fh,$size,$mime){
+ $ranges = array();
+ $isrange = false;
+
+ header('Accept-Ranges: bytes');
+
+ if(!isset($_SERVER['HTTP_RANGE'])){
+ // no range requested - send the whole file
+ $ranges[] = array(0,$size,$size);
+ }else{
+ $t = explode('=', $_SERVER['HTTP_RANGE']);
+ if (!$t[0]=='bytes') {
+ // we only understand byte ranges - send the whole file
+ $ranges[] = array(0,$size,$size);
+ }else{
+ $isrange = true;
+ // handle multiple ranges
+ $r = explode(',',$t[1]);
+ foreach($r as $x){
+ $p = explode('-', $x);
+ $start = (int)$p[0];
+ $end = (int)$p[1];
+ if (!$end) $end = $size - 1;
+ if ($start > $end || $start > $size || $end > $size){
+ header('HTTP/1.1 416 Requested Range Not Satisfiable');
+ print 'Bad Range Request!';
+ exit;
+ }
+ $len = $end - $start + 1;
+ $ranges[] = array($start,$end,$len);
+ }
+ }
+ }
+ $parts = count($ranges);
+
+ // now send the type and length headers
+ if(!$isrange){
+ header("Content-Type: $mime",true);
+ }else{
+ header('HTTP/1.1 206 Partial Content');
+ if($parts == 1){
+ header("Content-Type: $mime",true);
+ }else{
+ header('Content-Type: multipart/byteranges; boundary='.HTTP_MULTIPART_BOUNDARY,true);
+ }
+ }
+
+ // send all ranges
+ for($i=0; $i<$parts; $i++){
+ list($start,$end,$len) = $ranges[$i];
+
+ // multipart or normal headers
+ if($parts > 1){
+ echo HTTP_HEADER_LF.'--'.HTTP_MULTIPART_BOUNDARY.HTTP_HEADER_LF;
+ echo "Content-Type: $mime".HTTP_HEADER_LF;
+ echo "Content-Range: bytes $start-$end/$size".HTTP_HEADER_LF;
+ echo HTTP_HEADER_LF;
+ }else{
+ header("Content-Length: $len");
+ if($isrange){
+ header("Content-Range: bytes $start-$end/$size");
+ }
+ }
+
+ // send file content
+ fseek($fh,$start); //seek to start of range
+ $chunk = ($len > HTTP_CHUNK_SIZE) ? HTTP_CHUNK_SIZE : $len;
+ while (!feof($fh) && $chunk > 0) {
+ @set_time_limit(30); // large files can take a lot of time
+ print fread($fh, $chunk);
+ flush();
+ $len -= $chunk;
+ $chunk = ($len > HTTP_CHUNK_SIZE) ? HTTP_CHUNK_SIZE : $len;
+ }
+ }
+ if($parts > 1){
+ echo HTTP_HEADER_LF.'--'.HTTP_MULTIPART_BOUNDARY.'--'.HTTP_HEADER_LF;
+ }
+
+ // everything should be done here, exit (or return if testing)
+ if (defined('SIMPLE_TEST')) return;
+ exit;
+}
+
+/**
+ * Check for a gzipped version and create if necessary
+ *
+ * return true if there exists a gzip version of the uncompressed file
+ * (samepath/samefilename.sameext.gz) created after the uncompressed file
+ *
+ * @author Chris Smith <chris.eureka@jalakai.co.uk>
+ *
+ * @param string $uncompressed_file
+ * @return bool
+ */
+function http_gzip_valid($uncompressed_file) {
+ if(!DOKU_HAS_GZIP) return false;
+
+ $gzip = $uncompressed_file.'.gz';
+ if (filemtime($gzip) < filemtime($uncompressed_file)) { // filemtime returns false (0) if file doesn't exist
+ return copy($uncompressed_file, 'compress.zlib://'.$gzip);
+ }
+
+ return true;
+}
+
+/**
+ * Set HTTP headers and echo cachefile, if useable
+ *
+ * This function handles output of cacheable resource files. It ses the needed
+ * HTTP headers. If a useable cache is present, it is passed to the web server
+ * and the script is terminated.
+ *
+ * @param string $cache cache file name
+ * @param bool $cache_ok if cache can be used
+ */
+function http_cached($cache, $cache_ok) {
+ global $conf;
+
+ // check cache age & handle conditional request
+ // since the resource files are timestamped, we can use a long max age: 1 year
+ header('Cache-Control: public, max-age=31536000');
+ header('Pragma: public');
+ if($cache_ok){
+ http_conditionalRequest(filemtime($cache));
+ if($conf['allowdebug']) header("X-CacheUsed: $cache");
+
+ // finally send output
+ if ($conf['gzip_output'] && http_gzip_valid($cache)) {
+ header('Vary: Accept-Encoding');
+ header('Content-Encoding: gzip');
+ readfile($cache.".gz");
+ } else {
+ http_sendfile($cache);
+ readfile($cache);
+ }
+ exit;
+ }
+
+ http_conditionalRequest(time());
+}
+
+/**
+ * Cache content and print it
+ *
+ * @param string $file file name
+ * @param string $content
+ */
+function http_cached_finish($file, $content) {
+ global $conf;
+
+ // save cache file
+ io_saveFile($file, $content);
+ if(DOKU_HAS_GZIP) io_saveFile("$file.gz",$content);
+
+ // finally send output
+ if ($conf['gzip_output'] && DOKU_HAS_GZIP) {
+ header('Vary: Accept-Encoding');
+ header('Content-Encoding: gzip');
+ print gzencode($content,9,FORCE_GZIP);
+ } else {
+ print $content;
+ }
+}
+
+/**
+ * Fetches raw, unparsed POST data
+ *
+ * @return string
+ */
+function http_get_raw_post_data() {
+ static $postData = null;
+ if ($postData === null) {
+ $postData = file_get_contents('php://input');
+ }
+ return $postData;
+}
+
+/**
+ * Set the HTTP response status and takes care of the used PHP SAPI
+ *
+ * Inspired by CodeIgniter's set_status_header function
+ *
+ * @param int $code
+ * @param string $text
+ */
+function http_status($code = 200, $text = '') {
+ static $stati = array(
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 307 => 'Temporary Redirect',
+
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported'
+ );
+
+ if($text == '' && isset($stati[$code])) {
+ $text = $stati[$code];
+ }
+
+ $server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : false;
+
+ if(substr(php_sapi_name(), 0, 3) == 'cgi' || defined('SIMPLE_TEST')) {
+ header("Status: {$code} {$text}", true);
+ } elseif($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0') {
+ header($server_protocol." {$code} {$text}", true, $code);
+ } else {
+ header("HTTP/1.1 {$code} {$text}", true, $code);
+ }
+}
diff --git a/platform/www/inc/indexer.php b/platform/www/inc/indexer.php
new file mode 100644
index 0000000..ab02b8e
--- /dev/null
+++ b/platform/www/inc/indexer.php
@@ -0,0 +1,369 @@
+<?php
+/**
+ * Functions to create the fulltext search index
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+
+use dokuwiki\Extension\Event;
+use dokuwiki\Search\Indexer;
+
+// Version tag used to force rebuild on upgrade
+define('INDEXER_VERSION', 8);
+
+// set the minimum token length to use in the index (note, this doesn't apply to numeric tokens)
+if (!defined('IDX_MINWORDLENGTH')) define('IDX_MINWORDLENGTH',2);
+
+/**
+ * Version of the indexer taking into consideration the external tokenizer.
+ * The indexer is only compatible with data written by the same version.
+ *
+ * @triggers INDEXER_VERSION_GET
+ * Plugins that modify what gets indexed should hook this event and
+ * add their version info to the event data like so:
+ * $data[$plugin_name] = $plugin_version;
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ * @author Michael Hamann <michael@content-space.de>
+ *
+ * @return int|string
+ */
+function idx_get_version(){
+ static $indexer_version = null;
+ if ($indexer_version == null) {
+ $version = INDEXER_VERSION;
+
+ // DokuWiki version is included for the convenience of plugins
+ $data = array('dokuwiki'=>$version);
+ Event::createAndTrigger('INDEXER_VERSION_GET', $data, null, false);
+ unset($data['dokuwiki']); // this needs to be first
+ ksort($data);
+ foreach ($data as $plugin=>$vers)
+ $version .= '+'.$plugin.'='.$vers;
+ $indexer_version = $version;
+ }
+ return $indexer_version;
+}
+
+/**
+ * Measure the length of a string.
+ * Differs from strlen in handling of asian characters.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $w
+ * @return int
+ */
+function wordlen($w){
+ $l = strlen($w);
+ // If left alone, all chinese "words" will get put into w3.idx
+ // So the "length" of a "word" is faked
+ if(preg_match_all('/[\xE2-\xEF]/',$w,$leadbytes)) {
+ foreach($leadbytes[0] as $b)
+ $l += ord($b) - 0xE1;
+ }
+ return $l;
+}
+
+/**
+ * Create an instance of the indexer.
+ *
+ * @return Indexer an Indexer
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+function idx_get_indexer() {
+ static $Indexer;
+ if (!isset($Indexer)) {
+ $Indexer = new Indexer();
+ }
+ return $Indexer;
+}
+
+/**
+ * Returns words that will be ignored.
+ *
+ * @return array list of stop words
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+function & idx_get_stopwords() {
+ static $stopwords = null;
+ if (is_null($stopwords)) {
+ global $conf;
+ $swfile = DOKU_INC.'inc/lang/'.$conf['lang'].'/stopwords.txt';
+ if(file_exists($swfile)){
+ $stopwords = file($swfile, FILE_IGNORE_NEW_LINES);
+ }else{
+ $stopwords = array();
+ }
+ }
+ return $stopwords;
+}
+
+/**
+ * Adds/updates the search index for the given page
+ *
+ * Locking is handled internally.
+ *
+ * @param string $page name of the page to index
+ * @param boolean $verbose print status messages
+ * @param boolean $force force reindexing even when the index is up to date
+ * @return string|boolean the function completed successfully
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ */
+function idx_addPage($page, $verbose=false, $force=false) {
+ $idxtag = metaFN($page,'.indexed');
+ // check if page was deleted but is still in the index
+ if (!page_exists($page)) {
+ if (!file_exists($idxtag)) {
+ if ($verbose) print("Indexer: $page does not exist, ignoring".DOKU_LF);
+ return false;
+ }
+ $Indexer = idx_get_indexer();
+ $result = $Indexer->deletePage($page);
+ if ($result === "locked") {
+ if ($verbose) print("Indexer: locked".DOKU_LF);
+ return false;
+ }
+ @unlink($idxtag);
+ return $result;
+ }
+
+ // check if indexing needed
+ if(!$force && file_exists($idxtag)){
+ if(trim(io_readFile($idxtag)) == idx_get_version()){
+ $last = @filemtime($idxtag);
+ if($last > @filemtime(wikiFN($page))){
+ if ($verbose) print("Indexer: index for $page up to date".DOKU_LF);
+ return false;
+ }
+ }
+ }
+
+ $indexenabled = p_get_metadata($page, 'internal index', METADATA_RENDER_UNLIMITED);
+ if ($indexenabled === false) {
+ $result = false;
+ if (file_exists($idxtag)) {
+ $Indexer = idx_get_indexer();
+ $result = $Indexer->deletePage($page);
+ if ($result === "locked") {
+ if ($verbose) print("Indexer: locked".DOKU_LF);
+ return false;
+ }
+ @unlink($idxtag);
+ }
+ if ($verbose) print("Indexer: index disabled for $page".DOKU_LF);
+ return $result;
+ }
+
+ $Indexer = idx_get_indexer();
+ $pid = $Indexer->getPID($page);
+ if ($pid === false) {
+ if ($verbose) print("Indexer: getting the PID failed for $page".DOKU_LF);
+ return false;
+ }
+ $body = '';
+ $metadata = array();
+ $metadata['title'] = p_get_metadata($page, 'title', METADATA_RENDER_UNLIMITED);
+ if (($references = p_get_metadata($page, 'relation references', METADATA_RENDER_UNLIMITED)) !== null)
+ $metadata['relation_references'] = array_keys($references);
+ else
+ $metadata['relation_references'] = array();
+
+ if (($media = p_get_metadata($page, 'relation media', METADATA_RENDER_UNLIMITED)) !== null)
+ $metadata['relation_media'] = array_keys($media);
+ else
+ $metadata['relation_media'] = array();
+
+ $data = compact('page', 'body', 'metadata', 'pid');
+ $evt = new Event('INDEXER_PAGE_ADD', $data);
+ if ($evt->advise_before()) $data['body'] = $data['body'] . " " . rawWiki($page);
+ $evt->advise_after();
+ unset($evt);
+ extract($data);
+
+ $result = $Indexer->addPageWords($page, $body);
+ if ($result === "locked") {
+ if ($verbose) print("Indexer: locked".DOKU_LF);
+ return false;
+ }
+
+ if ($result) {
+ $result = $Indexer->addMetaKeys($page, $metadata);
+ if ($result === "locked") {
+ if ($verbose) print("Indexer: locked".DOKU_LF);
+ return false;
+ }
+ }
+
+ if ($result)
+ io_saveFile(metaFN($page,'.indexed'), idx_get_version());
+ if ($verbose) {
+ print("Indexer: finished".DOKU_LF);
+ return true;
+ }
+ return $result;
+}
+
+/**
+ * Find tokens in the fulltext index
+ *
+ * Takes an array of words and will return a list of matching
+ * pages for each one.
+ *
+ * Important: No ACL checking is done here! All results are
+ * returned, regardless of permissions
+ *
+ * @param array $words list of words to search for
+ * @return array list of pages found, associated with the search terms
+ */
+function idx_lookup(&$words) {
+ $Indexer = idx_get_indexer();
+ return $Indexer->lookup($words);
+}
+
+/**
+ * Split a string into tokens
+ *
+ * @param string $string
+ * @param bool $wc
+ *
+ * @return array
+ */
+function idx_tokenizer($string, $wc=false) {
+ $Indexer = idx_get_indexer();
+ return $Indexer->tokenizer($string, $wc);
+}
+
+/* For compatibility */
+
+/**
+ * Read the list of words in an index (if it exists).
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $idx
+ * @param string $suffix
+ * @return array
+ */
+function idx_getIndex($idx, $suffix) {
+ global $conf;
+ $fn = $conf['indexdir'].'/'.$idx.$suffix.'.idx';
+ if (!file_exists($fn)) return array();
+ return file($fn);
+}
+
+/**
+ * Get the list of lengths indexed in the wiki.
+ *
+ * Read the index directory or a cache file and returns
+ * a sorted array of lengths of the words used in the wiki.
+ *
+ * @author YoBoY <yoboy.leguesh@gmail.com>
+ *
+ * @return array
+ */
+function idx_listIndexLengths() {
+ global $conf;
+ // testing what we have to do, create a cache file or not.
+ if ($conf['readdircache'] == 0) {
+ $docache = false;
+ } else {
+ clearstatcache();
+ if (file_exists($conf['indexdir'].'/lengths.idx')
+ && (time() < @filemtime($conf['indexdir'].'/lengths.idx') + $conf['readdircache'])) {
+ if (
+ ($lengths = @file($conf['indexdir'].'/lengths.idx', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES))
+ !== false
+ ) {
+ $idx = array();
+ foreach ($lengths as $length) {
+ $idx[] = (int)$length;
+ }
+ return $idx;
+ }
+ }
+ $docache = true;
+ }
+
+ if ($conf['readdircache'] == 0 || $docache) {
+ $dir = @opendir($conf['indexdir']);
+ if ($dir === false)
+ return array();
+ $idx = array();
+ while (($f = readdir($dir)) !== false) {
+ if (substr($f, 0, 1) == 'i' && substr($f, -4) == '.idx') {
+ $i = substr($f, 1, -4);
+ if (is_numeric($i))
+ $idx[] = (int)$i;
+ }
+ }
+ closedir($dir);
+ sort($idx);
+ // save this in a file
+ if ($docache) {
+ $handle = @fopen($conf['indexdir'].'/lengths.idx', 'w');
+ @fwrite($handle, implode("\n", $idx));
+ @fclose($handle);
+ }
+ return $idx;
+ }
+
+ return array();
+}
+
+/**
+ * Get the word lengths that have been indexed.
+ *
+ * Reads the index directory and returns an array of lengths
+ * that there are indices for.
+ *
+ * @author YoBoY <yoboy.leguesh@gmail.com>
+ *
+ * @param array|int $filter
+ * @return array
+ */
+function idx_indexLengths($filter) {
+ global $conf;
+ $idx = array();
+ if (is_array($filter)) {
+ // testing if index files exist only
+ $path = $conf['indexdir']."/i";
+ foreach ($filter as $key => $value) {
+ if (file_exists($path.$key.'.idx'))
+ $idx[] = $key;
+ }
+ } else {
+ $lengths = idx_listIndexLengths();
+ foreach ($lengths as $key => $length) {
+ // keep all the values equal or superior
+ if ((int)$length >= (int)$filter)
+ $idx[] = $length;
+ }
+ }
+ return $idx;
+}
+
+/**
+ * Clean a name of a key for use as a file name.
+ *
+ * Romanizes non-latin characters, then strips away anything that's
+ * not a letter, number, or underscore.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $name
+ * @return string
+ */
+function idx_cleanName($name) {
+ $name = \dokuwiki\Utf8\Clean::romanize(trim((string)$name));
+ $name = preg_replace('#[ \./\\:-]+#', '_', $name);
+ $name = preg_replace('/[^A-Za-z0-9_]/', '', $name);
+ return strtolower($name);
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/inc/infoutils.php b/platform/www/inc/infoutils.php
new file mode 100644
index 0000000..68d99ab
--- /dev/null
+++ b/platform/www/inc/infoutils.php
@@ -0,0 +1,527 @@
+<?php
+/**
+ * Information and debugging functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\HTTP\DokuHTTPClient;
+
+if(!defined('DOKU_MESSAGEURL')){
+ if(in_array('ssl', stream_get_transports())) {
+ define('DOKU_MESSAGEURL','https://update.dokuwiki.org/check/');
+ }else{
+ define('DOKU_MESSAGEURL','http://update.dokuwiki.org/check/');
+ }
+}
+
+/**
+ * Check for new messages from upstream
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function checkUpdateMessages(){
+ global $conf;
+ global $INFO;
+ global $updateVersion;
+ if(!$conf['updatecheck']) return;
+ if($conf['useacl'] && !$INFO['ismanager']) return;
+
+ $cf = getCacheName($updateVersion, '.updmsg');
+ $lm = @filemtime($cf);
+ $is_http = substr(DOKU_MESSAGEURL, 0, 5) != 'https';
+
+ // check if new messages needs to be fetched
+ if($lm < time()-(60*60*24) || $lm < @filemtime(DOKU_INC.DOKU_SCRIPT)){
+ @touch($cf);
+ dbglog("checkUpdateMessages(): downloading messages to ".$cf.($is_http?' (without SSL)':' (with SSL)'));
+ $http = new DokuHTTPClient();
+ $http->timeout = 12;
+ $resp = $http->get(DOKU_MESSAGEURL.$updateVersion);
+ if(is_string($resp) && ($resp == "" || substr(trim($resp), -1) == '%')) {
+ // basic sanity check that this is either an empty string response (ie "no messages")
+ // or it looks like one of our messages, not WiFi login or other interposed response
+ io_saveFile($cf,$resp);
+ } else {
+ dbglog("checkUpdateMessages(): unexpected HTTP response received");
+ }
+ }else{
+ dbglog("checkUpdateMessages(): messages up to date");
+ }
+
+ $data = io_readFile($cf);
+ // show messages through the usual message mechanism
+ $msgs = explode("\n%\n",$data);
+ foreach($msgs as $msg){
+ if($msg) msg($msg,2);
+ }
+}
+
+
+/**
+ * Return DokuWiki's version (split up in date and type)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function getVersionData(){
+ $version = array();
+ //import version string
+ if(file_exists(DOKU_INC.'VERSION')){
+ //official release
+ $version['date'] = trim(io_readFile(DOKU_INC.'VERSION'));
+ $version['type'] = 'Release';
+ }elseif(is_dir(DOKU_INC.'.git')){
+ $version['type'] = 'Git';
+ $version['date'] = 'unknown';
+
+ $inventory = DOKU_INC.'.git/logs/HEAD';
+ if(is_file($inventory)){
+ $sz = filesize($inventory);
+ $seek = max(0,$sz-2000); // read from back of the file
+ $fh = fopen($inventory,'rb');
+ fseek($fh,$seek);
+ $chunk = fread($fh,2000);
+ fclose($fh);
+ $chunk = trim($chunk);
+ $chunk = @array_pop(explode("\n",$chunk)); //last log line
+ $chunk = @array_shift(explode("\t",$chunk)); //strip commit msg
+ $chunk = explode(" ",$chunk);
+ array_pop($chunk); //strip timezone
+ $date = date('Y-m-d',array_pop($chunk));
+ if($date) $version['date'] = $date;
+ }
+ }else{
+ global $updateVersion;
+ $version['date'] = 'update version '.$updateVersion;
+ $version['type'] = 'snapshot?';
+ }
+ return $version;
+}
+
+/**
+ * Return DokuWiki's version (as a string)
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+function getVersion(){
+ $version = getVersionData();
+ return $version['type'].' '.$version['date'];
+}
+
+/**
+ * Run a few sanity checks
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function check(){
+ global $conf;
+ global $INFO;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ if ($INFO['isadmin'] || $INFO['ismanager']){
+ msg('DokuWiki version: '.getVersion(),1);
+
+ if(version_compare(phpversion(),'5.6.0','<')){
+ msg('Your PHP version is too old ('.phpversion().' vs. 5.6.0+ needed)',-1);
+ }else{
+ msg('PHP version '.phpversion(),1);
+ }
+ } else {
+ if(version_compare(phpversion(),'5.6.0','<')){
+ msg('Your PHP version is too old',-1);
+ }
+ }
+
+ $mem = (int) php_to_byte(ini_get('memory_limit'));
+ if($mem){
+ if ($mem === -1) {
+ msg('PHP memory is unlimited', 1);
+ } else if ($mem < 16777216) {
+ msg('PHP is limited to less than 16MB RAM (' . filesize_h($mem) . ').
+ Increase memory_limit in php.ini', -1);
+ } else if ($mem < 20971520) {
+ msg('PHP is limited to less than 20MB RAM (' . filesize_h($mem) . '),
+ you might encounter problems with bigger pages. Increase memory_limit in php.ini', -1);
+ } else if ($mem < 33554432) {
+ msg('PHP is limited to less than 32MB RAM (' . filesize_h($mem) . '),
+ but that should be enough in most cases. If not, increase memory_limit in php.ini', 0);
+ } else {
+ msg('More than 32MB RAM (' . filesize_h($mem) . ') available.', 1);
+ }
+ }
+
+ if(is_writable($conf['changelog'])){
+ msg('Changelog is writable',1);
+ }else{
+ if (file_exists($conf['changelog'])) {
+ msg('Changelog is not writable',-1);
+ }
+ }
+
+ if (isset($conf['changelog_old']) && file_exists($conf['changelog_old'])) {
+ msg('Old changelog exists', 0);
+ }
+
+ if (file_exists($conf['changelog'].'_failed')) {
+ msg('Importing old changelog failed', -1);
+ } else if (file_exists($conf['changelog'].'_importing')) {
+ msg('Importing old changelog now.', 0);
+ } else if (file_exists($conf['changelog'].'_import_ok')) {
+ msg('Old changelog imported', 1);
+ if (!plugin_isdisabled('importoldchangelog')) {
+ msg('Importoldchangelog plugin not disabled after import', -1);
+ }
+ }
+
+ if(is_writable(DOKU_CONF)){
+ msg('conf directory is writable',1);
+ }else{
+ msg('conf directory is not writable',-1);
+ }
+
+ if($conf['authtype'] == 'plain'){
+ global $config_cascade;
+ if(is_writable($config_cascade['plainauth.users']['default'])){
+ msg('conf/users.auth.php is writable',1);
+ }else{
+ msg('conf/users.auth.php is not writable',0);
+ }
+ }
+
+ if(function_exists('mb_strpos')){
+ if(defined('UTF8_NOMBSTRING')){
+ msg('mb_string extension is available but will not be used',0);
+ }else{
+ msg('mb_string extension is available and will be used',1);
+ if(ini_get('mbstring.func_overload') != 0){
+ msg('mb_string function overloading is enabled, this will cause problems and should be disabled',-1);
+ }
+ }
+ }else{
+ msg('mb_string extension not available - PHP only replacements will be used',0);
+ }
+
+ if (!UTF8_PREGSUPPORT) {
+ msg('PHP is missing UTF-8 support in Perl-Compatible Regular Expressions (PCRE)', -1);
+ }
+ if (!UTF8_PROPERTYSUPPORT) {
+ msg('PHP is missing Unicode properties support in Perl-Compatible Regular Expressions (PCRE)', -1);
+ }
+
+ $loc = setlocale(LC_ALL, 0);
+ if(!$loc){
+ msg('No valid locale is set for your PHP setup. You should fix this',-1);
+ }elseif(stripos($loc,'utf') === false){
+ msg('Your locale <code>'.hsc($loc).'</code> seems not to be a UTF-8 locale,
+ you should fix this if you encounter problems.',0);
+ }else{
+ msg('Valid locale '.hsc($loc).' found.', 1);
+ }
+
+ if($conf['allowdebug']){
+ msg('Debugging support is enabled. If you don\'t need it you should set $conf[\'allowdebug\'] = 0',-1);
+ }else{
+ msg('Debugging support is disabled',1);
+ }
+
+ if($INFO['userinfo']['name']){
+ msg('You are currently logged in as '.$INPUT->server->str('REMOTE_USER').' ('.$INFO['userinfo']['name'].')',0);
+ msg('You are part of the groups '.join($INFO['userinfo']['grps'],', '),0);
+ }else{
+ msg('You are currently not logged in',0);
+ }
+
+ msg('Your current permission for this page is '.$INFO['perm'],0);
+
+ if (file_exists($INFO['filepath']) && is_writable($INFO['filepath'])) {
+ msg('The current page is writable by the webserver', 1);
+ } elseif (!file_exists($INFO['filepath']) && is_writable(dirname($INFO['filepath']))) {
+ msg('The current page can be created by the webserver', 1);
+ } else {
+ msg('The current page is not writable by the webserver', -1);
+ }
+
+ if ($INFO['writable']) {
+ msg('The current page is writable by you', 1);
+ } else {
+ msg('The current page is not writable by you', -1);
+ }
+
+ // Check for corrupted search index
+ $lengths = idx_listIndexLengths();
+ $index_corrupted = false;
+ foreach ($lengths as $length) {
+ if (count(idx_getIndex('w', $length)) != count(idx_getIndex('i', $length))) {
+ $index_corrupted = true;
+ break;
+ }
+ }
+
+ foreach (idx_getIndex('metadata', '') as $index) {
+ if (count(idx_getIndex($index.'_w', '')) != count(idx_getIndex($index.'_i', ''))) {
+ $index_corrupted = true;
+ break;
+ }
+ }
+
+ if($index_corrupted) {
+ msg(
+ 'The search index is corrupted. It might produce wrong results and most
+ probably needs to be rebuilt. See
+ <a href="http://www.dokuwiki.org/faq:searchindex">faq:searchindex</a>
+ for ways to rebuild the search index.', -1
+ );
+ } elseif(!empty($lengths)) {
+ msg('The search index seems to be working', 1);
+ } else {
+ msg(
+ 'The search index is empty. See
+ <a href="http://www.dokuwiki.org/faq:searchindex">faq:searchindex</a>
+ for help on how to fix the search index. If the default indexer
+ isn\'t used or the wiki is actually empty this is normal.'
+ );
+ }
+
+ // rough time check
+ $http = new DokuHTTPClient();
+ $http->max_redirect = 0;
+ $http->timeout = 3;
+ $http->sendRequest('http://www.dokuwiki.org', '', 'HEAD');
+ $now = time();
+ if(isset($http->resp_headers['date'])) {
+ $time = strtotime($http->resp_headers['date']);
+ $diff = $time - $now;
+
+ if(abs($diff) < 4) {
+ msg("Server time seems to be okay. Diff: {$diff}s", 1);
+ } else {
+ msg("Your server's clock seems to be out of sync!
+ Consider configuring a sync with a NTP server. Diff: {$diff}s");
+ }
+ }
+
+}
+
+/**
+ * Display a message to the user
+ *
+ * If HTTP headers were not sent yet the message is added
+ * to the global message array else it's printed directly
+ * using html_msgarea()
+ *
+ * Triggers INFOUTIL_MSG_SHOW
+ *
+ * @see html_msgarea()
+ * @param string $message
+ * @param int $lvl -1 = error, 0 = info, 1 = success, 2 = notify
+ * @param string $line line number
+ * @param string $file file number
+ * @param int $allow who's allowed to see the message, see MSG_* constants
+ */
+function msg($message,$lvl=0,$line='',$file='',$allow=MSG_PUBLIC){
+ global $MSG, $MSG_shown;
+ static $errors = [
+ -1 => 'error',
+ 0 => 'info',
+ 1 => 'success',
+ 2 => 'notify',
+ ];
+
+ $msgdata = [
+ 'msg' => $message,
+ 'lvl' => $errors[$lvl],
+ 'allow' => $allow,
+ 'line' => $line,
+ 'file' => $file,
+ ];
+
+ $evt = new \dokuwiki\Extension\Event('INFOUTIL_MSG_SHOW', $msgdata);
+ if ($evt->advise_before()) {
+ /* Show msg normally - event could suppress message show */
+ if($msgdata['line'] || $msgdata['file']) {
+ $basename = \dokuwiki\Utf8\PhpString::basename($msgdata['file']);
+ $msgdata['msg'] .=' ['.$basename.':'.$msgdata['line'].']';
+ }
+
+ if(!isset($MSG)) $MSG = array();
+ $MSG[] = $msgdata;
+ if(isset($MSG_shown) || headers_sent()){
+ if(function_exists('html_msgarea')){
+ html_msgarea();
+ }else{
+ print "ERROR(".$msgdata['lvl'].") ".$msgdata['msg']."\n";
+ }
+ unset($GLOBALS['MSG']);
+ }
+ }
+ $evt->advise_after();
+ unset($evt);
+}
+/**
+ * Determine whether the current user is allowed to view the message
+ * in the $msg data structure
+ *
+ * @param $msg array dokuwiki msg structure
+ * msg => string, the message
+ * lvl => int, level of the message (see msg() function)
+ * allow => int, flag used to determine who is allowed to see the message
+ * see MSG_* constants
+ * @return bool
+ */
+function info_msg_allowed($msg){
+ global $INFO, $auth;
+
+ // is the message public? - everyone and anyone can see it
+ if (empty($msg['allow']) || ($msg['allow'] == MSG_PUBLIC)) return true;
+
+ // restricted msg, but no authentication
+ if (empty($auth)) return false;
+
+ switch ($msg['allow']){
+ case MSG_USERS_ONLY:
+ return !empty($INFO['userinfo']);
+
+ case MSG_MANAGERS_ONLY:
+ return $INFO['ismanager'];
+
+ case MSG_ADMINS_ONLY:
+ return $INFO['isadmin'];
+
+ default:
+ trigger_error('invalid msg allow restriction. msg="'.$msg['msg'].'" allow='.$msg['allow'].'"',
+ E_USER_WARNING);
+ return $INFO['isadmin'];
+ }
+
+ return false;
+}
+
+/**
+ * print debug messages
+ *
+ * little function to print the content of a var
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $msg
+ * @param bool $hidden
+ */
+function dbg($msg,$hidden=false){
+ if($hidden){
+ echo "<!--\n";
+ print_r($msg);
+ echo "\n-->";
+ }else{
+ echo '<pre class="dbg">';
+ echo hsc(print_r($msg,true));
+ echo '</pre>';
+ }
+}
+
+/**
+ * Print info to a log file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $msg
+ * @param string $header
+ */
+function dbglog($msg,$header=''){
+ global $conf;
+ /* @var Input $INPUT */
+ global $INPUT;
+
+ // The debug log isn't automatically cleaned thus only write it when
+ // debugging has been enabled by the user.
+ if($conf['allowdebug'] !== 1) return;
+ if(is_object($msg) || is_array($msg)){
+ $msg = print_r($msg,true);
+ }
+
+ if($header) $msg = "$header\n$msg";
+
+ $file = $conf['cachedir'].'/debug.log';
+ $fh = fopen($file,'a');
+ if($fh){
+ fwrite($fh,date('H:i:s ').$INPUT->server->str('REMOTE_ADDR').': '.$msg."\n");
+ fclose($fh);
+ }
+}
+
+/**
+ * Log accesses to deprecated fucntions to the debug log
+ *
+ * @param string $alternative The function or method that should be used instead
+ * @triggers INFO_DEPRECATION_LOG
+ */
+function dbg_deprecated($alternative = '') {
+ \dokuwiki\Debug\DebugHelper::dbgDeprecatedFunction($alternative, 2);
+}
+
+/**
+ * Print a reversed, prettyprinted backtrace
+ *
+ * @author Gary Owen <gary_owen@bigfoot.com>
+ */
+function dbg_backtrace(){
+ // Get backtrace
+ $backtrace = debug_backtrace();
+
+ // Unset call to debug_print_backtrace
+ array_shift($backtrace);
+
+ // Iterate backtrace
+ $calls = array();
+ $depth = count($backtrace) - 1;
+ foreach ($backtrace as $i => $call) {
+ $location = $call['file'] . ':' . $call['line'];
+ $function = (isset($call['class'])) ?
+ $call['class'] . $call['type'] . $call['function'] : $call['function'];
+
+ $params = array();
+ if (isset($call['args'])){
+ foreach($call['args'] as $arg){
+ if(is_object($arg)){
+ $params[] = '[Object '.get_class($arg).']';
+ }elseif(is_array($arg)){
+ $params[] = '[Array]';
+ }elseif(is_null($arg)){
+ $params[] = '[NULL]';
+ }else{
+ $params[] = (string) '"'.$arg.'"';
+ }
+ }
+ }
+ $params = implode(', ',$params);
+
+ $calls[$depth - $i] = sprintf('%s(%s) called at %s',
+ $function,
+ str_replace("\n", '\n', $params),
+ $location);
+ }
+ ksort($calls);
+
+ return implode("\n", $calls);
+}
+
+/**
+ * Remove all data from an array where the key seems to point to sensitive data
+ *
+ * This is used to remove passwords, mail addresses and similar data from the
+ * debug output
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data
+ */
+function debug_guard(&$data){
+ foreach($data as $key => $value){
+ if(preg_match('/(notify|pass|auth|secret|ftp|userinfo|token|buid|mail|proxy)/i',$key)){
+ $data[$key] = '***';
+ continue;
+ }
+ if(is_array($value)) debug_guard($data[$key]);
+ }
+}
diff --git a/platform/www/inc/init.php b/platform/www/inc/init.php
new file mode 100644
index 0000000..f9bb534
--- /dev/null
+++ b/platform/www/inc/init.php
@@ -0,0 +1,623 @@
+<?php
+/**
+ * Initialize some defaults needed for DokuWiki
+ */
+
+use dokuwiki\Extension\Event;
+use dokuwiki\Extension\EventHandler;
+
+/**
+ * timing Dokuwiki execution
+ *
+ * @param integer $start
+ *
+ * @return mixed
+ */
+function delta_time($start=0) {
+ return microtime(true)-((float)$start);
+}
+define('DOKU_START_TIME', delta_time());
+
+global $config_cascade;
+$config_cascade = array();
+
+// if available load a preload config file
+$preload = fullpath(dirname(__FILE__)).'/preload.php';
+if (file_exists($preload)) include($preload);
+
+// define the include path
+if(!defined('DOKU_INC')) define('DOKU_INC',fullpath(dirname(__FILE__).'/../').'/');
+
+// define Plugin dir
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+
+// define config path (packagers may want to change this to /etc/dokuwiki/)
+if(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/');
+
+// check for error reporting override or set error reporting to sane values
+if (!defined('DOKU_E_LEVEL') && file_exists(DOKU_CONF.'report_e_all')) {
+ define('DOKU_E_LEVEL', E_ALL);
+}
+if (!defined('DOKU_E_LEVEL')) {
+ error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT);
+} else {
+ error_reporting(DOKU_E_LEVEL);
+}
+
+// avoid caching issues #1594
+header('Vary: Cookie');
+
+// init memory caches
+global $cache_revinfo;
+ $cache_revinfo = array();
+global $cache_wikifn;
+ $cache_wikifn = array();
+global $cache_cleanid;
+ $cache_cleanid = array();
+global $cache_authname;
+ $cache_authname = array();
+global $cache_metadata;
+ $cache_metadata = array();
+
+// always include 'inc/config_cascade.php'
+// previously in preload.php set fields of $config_cascade will be merged with the defaults
+include(DOKU_INC.'inc/config_cascade.php');
+
+//prepare config array()
+global $conf;
+$conf = array();
+
+// load the global config file(s)
+foreach (array('default','local','protected') as $config_group) {
+ if (empty($config_cascade['main'][$config_group])) continue;
+ foreach ($config_cascade['main'][$config_group] as $config_file) {
+ if (file_exists($config_file)) {
+ include($config_file);
+ }
+ }
+}
+
+//prepare license array()
+global $license;
+$license = array();
+
+// load the license file(s)
+foreach (array('default','local') as $config_group) {
+ if (empty($config_cascade['license'][$config_group])) continue;
+ foreach ($config_cascade['license'][$config_group] as $config_file) {
+ if(file_exists($config_file)){
+ include($config_file);
+ }
+ }
+}
+
+// set timezone (as in pre 5.3.0 days)
+date_default_timezone_set(@date_default_timezone_get());
+
+// define baseURL
+if(!defined('DOKU_REL')) define('DOKU_REL',getBaseURL(false));
+if(!defined('DOKU_URL')) define('DOKU_URL',getBaseURL(true));
+if(!defined('DOKU_BASE')){
+ if($conf['canonical']){
+ define('DOKU_BASE',DOKU_URL);
+ }else{
+ define('DOKU_BASE',DOKU_REL);
+ }
+}
+
+// define whitespace
+if(!defined('NL')) define ('NL',"\n");
+if(!defined('DOKU_LF')) define ('DOKU_LF',"\n");
+if(!defined('DOKU_TAB')) define ('DOKU_TAB',"\t");
+
+// define cookie and session id, append server port when securecookie is configured FS#1664
+if (!defined('DOKU_COOKIE')) {
+ $serverPort = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : '';
+ define('DOKU_COOKIE', 'DW' . md5(DOKU_REL . (($conf['securecookie']) ? $serverPort : '')));
+ unset($serverPort);
+}
+
+// define main script
+if(!defined('DOKU_SCRIPT')) define('DOKU_SCRIPT','doku.php');
+
+if(!defined('DOKU_TPL')) {
+ /**
+ * @deprecated 2012-10-13 replaced by more dynamic method
+ * @see tpl_basedir()
+ */
+ define('DOKU_TPL', DOKU_BASE.'lib/tpl/'.$conf['template'].'/');
+}
+
+if(!defined('DOKU_TPLINC')) {
+ /**
+ * @deprecated 2012-10-13 replaced by more dynamic method
+ * @see tpl_incdir()
+ */
+ define('DOKU_TPLINC', DOKU_INC.'lib/tpl/'.$conf['template'].'/');
+}
+
+// make session rewrites XHTML compliant
+@ini_set('arg_separator.output', '&amp;');
+
+// make sure global zlib does not interfere FS#1132
+@ini_set('zlib.output_compression', 'off');
+
+// increase PCRE backtrack limit
+@ini_set('pcre.backtrack_limit', '20971520');
+
+// enable gzip compression if supported
+$httpAcceptEncoding = isset($_SERVER['HTTP_ACCEPT_ENCODING']) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : '';
+$conf['gzip_output'] &= (strpos($httpAcceptEncoding, 'gzip') !== false);
+global $ACT;
+if ($conf['gzip_output'] &&
+ !defined('DOKU_DISABLE_GZIP_OUTPUT') &&
+ function_exists('ob_gzhandler') &&
+ // Disable compression when a (compressed) sitemap might be delivered
+ // See https://bugs.dokuwiki.org/index.php?do=details&task_id=2576
+ $ACT != 'sitemap') {
+ ob_start('ob_gzhandler');
+}
+
+// init session
+if(!headers_sent() && !defined('NOSESSION')) {
+ if(!defined('DOKU_SESSION_NAME')) define ('DOKU_SESSION_NAME', "DokuWiki");
+ if(!defined('DOKU_SESSION_LIFETIME')) define ('DOKU_SESSION_LIFETIME', 0);
+ if(!defined('DOKU_SESSION_PATH')) {
+ $cookieDir = empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'];
+ define ('DOKU_SESSION_PATH', $cookieDir);
+ }
+ if(!defined('DOKU_SESSION_DOMAIN')) define ('DOKU_SESSION_DOMAIN', '');
+
+ // start the session
+ init_session();
+
+ // load left over messages
+ if(isset($_SESSION[DOKU_COOKIE]['msg'])) {
+ $MSG = $_SESSION[DOKU_COOKIE]['msg'];
+ unset($_SESSION[DOKU_COOKIE]['msg']);
+ }
+}
+
+// don't let cookies ever interfere with request vars
+$_REQUEST = array_merge($_GET,$_POST);
+
+// we don't want a purge URL to be digged
+if(isset($_REQUEST['purge']) && !empty($_SERVER['HTTP_REFERER'])) unset($_REQUEST['purge']);
+
+// precalculate file creation modes
+init_creationmodes();
+
+// make real paths and check them
+init_paths();
+init_files();
+
+// setup plugin controller class (can be overwritten in preload.php)
+global $plugin_controller_class, $plugin_controller;
+if (empty($plugin_controller_class)) $plugin_controller_class = dokuwiki\Extension\PluginController::class;
+
+// load libraries
+require_once(DOKU_INC.'vendor/autoload.php');
+require_once(DOKU_INC.'inc/load.php');
+
+// disable gzip if not available
+define('DOKU_HAS_BZIP', function_exists('bzopen'));
+define('DOKU_HAS_GZIP', function_exists('gzopen'));
+if($conf['compression'] == 'bz2' && !DOKU_HAS_BZIP) {
+ $conf['compression'] = 'gz';
+}
+if($conf['compression'] == 'gz' && !DOKU_HAS_GZIP) {
+ $conf['compression'] = 0;
+}
+
+// input handle class
+global $INPUT;
+$INPUT = new \dokuwiki\Input\Input();
+
+// initialize plugin controller
+$plugin_controller = new $plugin_controller_class();
+
+// initialize the event handler
+global $EVENT_HANDLER;
+$EVENT_HANDLER = new EventHandler();
+
+$local = $conf['lang'];
+Event::createAndTrigger('INIT_LANG_LOAD', $local, 'init_lang', true);
+
+
+// setup authentication system
+if (!defined('NOSESSION')) {
+ auth_setup();
+}
+
+// setup mail system
+mail_setup();
+
+/**
+ * Initializes the session
+ *
+ * Makes sure the passed session cookie is valid, invalid ones are ignored an a new session ID is issued
+ *
+ * @link http://stackoverflow.com/a/33024310/172068
+ * @link http://php.net/manual/en/session.configuration.php#ini.session.sid-length
+ */
+function init_session() {
+ global $conf;
+ session_name(DOKU_SESSION_NAME);
+ session_set_cookie_params(
+ DOKU_SESSION_LIFETIME,
+ DOKU_SESSION_PATH,
+ DOKU_SESSION_DOMAIN,
+ ($conf['securecookie'] && is_ssl()),
+ true
+ );
+
+ // make sure the session cookie contains a valid session ID
+ if(isset($_COOKIE[DOKU_SESSION_NAME]) && !preg_match('/^[-,a-zA-Z0-9]{22,256}$/', $_COOKIE[DOKU_SESSION_NAME])) {
+ unset($_COOKIE[DOKU_SESSION_NAME]);
+ }
+
+ session_start();
+}
+
+
+/**
+ * Checks paths from config file
+ */
+function init_paths(){
+ global $conf;
+
+ $paths = array('datadir' => 'pages',
+ 'olddir' => 'attic',
+ 'mediadir' => 'media',
+ 'mediaolddir' => 'media_attic',
+ 'metadir' => 'meta',
+ 'mediametadir' => 'media_meta',
+ 'cachedir' => 'cache',
+ 'indexdir' => 'index',
+ 'lockdir' => 'locks',
+ 'tmpdir' => 'tmp');
+
+ foreach($paths as $c => $p) {
+ $path = empty($conf[$c]) ? $conf['savedir'].'/'.$p : $conf[$c];
+ $conf[$c] = init_path($path);
+ if(empty($conf[$c]))
+ nice_die("The $c ('$p') at $path is not found, isn't accessible or writable.
+ You should check your config and permission settings.
+ Or maybe you want to <a href=\"install.php\">run the
+ installer</a>?");
+ }
+
+ // path to old changelog only needed for upgrading
+ $conf['changelog_old'] = init_path(
+ (isset($conf['changelog'])) ? ($conf['changelog']) : ($conf['savedir'] . '/changes.log')
+ );
+ if ($conf['changelog_old']=='') { unset($conf['changelog_old']); }
+ // hardcoded changelog because it is now a cache that lives in meta
+ $conf['changelog'] = $conf['metadir'].'/_dokuwiki.changes';
+ $conf['media_changelog'] = $conf['metadir'].'/_media.changes';
+}
+
+/**
+ * Load the language strings
+ *
+ * @param string $langCode language code, as passed by event handler
+ */
+function init_lang($langCode) {
+ //prepare language array
+ global $lang, $config_cascade;
+ $lang = array();
+
+ //load the language files
+ require(DOKU_INC.'inc/lang/en/lang.php');
+ foreach ($config_cascade['lang']['core'] as $config_file) {
+ if (file_exists($config_file . 'en/lang.php')) {
+ include($config_file . 'en/lang.php');
+ }
+ }
+
+ if ($langCode && $langCode != 'en') {
+ if (file_exists(DOKU_INC."inc/lang/$langCode/lang.php")) {
+ require(DOKU_INC."inc/lang/$langCode/lang.php");
+ }
+ foreach ($config_cascade['lang']['core'] as $config_file) {
+ if (file_exists($config_file . "$langCode/lang.php")) {
+ include($config_file . "$langCode/lang.php");
+ }
+ }
+ }
+}
+
+/**
+ * Checks the existence of certain files and creates them if missing.
+ */
+function init_files(){
+ global $conf;
+
+ $files = array($conf['indexdir'].'/page.idx');
+
+ foreach($files as $file){
+ if(!file_exists($file)){
+ $fh = @fopen($file,'a');
+ if($fh){
+ fclose($fh);
+ if($conf['fperm']) chmod($file, $conf['fperm']);
+ }else{
+ nice_die("$file is not writable. Check your permissions settings!");
+ }
+ }
+ }
+}
+
+/**
+ * Returns absolute path
+ *
+ * This tries the given path first, then checks in DOKU_INC.
+ * Check for accessibility on directories as well.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $path
+ *
+ * @return bool|string
+ */
+function init_path($path){
+ // check existence
+ $p = fullpath($path);
+ if(!file_exists($p)){
+ $p = fullpath(DOKU_INC.$path);
+ if(!file_exists($p)){
+ return '';
+ }
+ }
+
+ // check writability
+ if(!@is_writable($p)){
+ return '';
+ }
+
+ // check accessability (execute bit) for directories
+ if(@is_dir($p) && !file_exists("$p/.")){
+ return '';
+ }
+
+ return $p;
+}
+
+/**
+ * Sets the internal config values fperm and dperm which, when set,
+ * will be used to change the permission of a newly created dir or
+ * file with chmod. Considers the influence of the system's umask
+ * setting the values only if needed.
+ */
+function init_creationmodes(){
+ global $conf;
+
+ // Legacy support for old umask/dmask scheme
+ unset($conf['dmask']);
+ unset($conf['fmask']);
+ unset($conf['umask']);
+ unset($conf['fperm']);
+ unset($conf['dperm']);
+
+ // get system umask, fallback to 0 if none available
+ $umask = @umask();
+ if(!$umask) $umask = 0000;
+
+ // check what is set automatically by the system on file creation
+ // and set the fperm param if it's not what we want
+ $auto_fmode = $conf['fmode'] & ~$umask;
+ if($auto_fmode != $conf['fmode']) $conf['fperm'] = $conf['fmode'];
+
+ // check what is set automatically by the system on file creation
+ // and set the dperm param if it's not what we want
+ $auto_dmode = $conf['dmode'] & ~$umask;
+ if($auto_dmode != $conf['dmode']) $conf['dperm'] = $conf['dmode'];
+}
+
+/**
+ * Returns the full absolute URL to the directory where
+ * DokuWiki is installed in (includes a trailing slash)
+ *
+ * !! Can not access $_SERVER values through $INPUT
+ * !! here as this function is called before $INPUT is
+ * !! initialized.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param null|string $abs
+ *
+ * @return string
+ */
+function getBaseURL($abs=null){
+ global $conf;
+ //if canonical url enabled always return absolute
+ if(is_null($abs)) $abs = $conf['canonical'];
+
+ if(!empty($conf['basedir'])){
+ $dir = $conf['basedir'];
+ }elseif(substr($_SERVER['SCRIPT_NAME'],-4) == '.php'){
+ $dir = dirname($_SERVER['SCRIPT_NAME']);
+ }elseif(substr($_SERVER['PHP_SELF'],-4) == '.php'){
+ $dir = dirname($_SERVER['PHP_SELF']);
+ }elseif($_SERVER['DOCUMENT_ROOT'] && $_SERVER['SCRIPT_FILENAME']){
+ $dir = preg_replace ('/^'.preg_quote($_SERVER['DOCUMENT_ROOT'],'/').'/','',
+ $_SERVER['SCRIPT_FILENAME']);
+ $dir = dirname('/'.$dir);
+ }else{
+ $dir = '.'; //probably wrong
+ }
+
+ $dir = str_replace('\\','/',$dir); // bugfix for weird WIN behaviour
+ $dir = preg_replace('#//+#','/',"/$dir/"); // ensure leading and trailing slashes
+
+ //handle script in lib/exe dir
+ $dir = preg_replace('!lib/exe/$!','',$dir);
+
+ //handle script in lib/plugins dir
+ $dir = preg_replace('!lib/plugins/.*$!','',$dir);
+
+ //finish here for relative URLs
+ if(!$abs) return $dir;
+
+ //use config if available, trim any slash from end of baseurl to avoid multiple consecutive slashes in the path
+ if(!empty($conf['baseurl'])) return rtrim($conf['baseurl'],'/').$dir;
+
+ //split hostheader into host and port
+ if(isset($_SERVER['HTTP_HOST'])){
+ $parsed_host = parse_url('http://'.$_SERVER['HTTP_HOST']);
+ $host = isset($parsed_host['host']) ? $parsed_host['host'] : null;
+ $port = isset($parsed_host['port']) ? $parsed_host['port'] : null;
+ }elseif(isset($_SERVER['SERVER_NAME'])){
+ $parsed_host = parse_url('http://'.$_SERVER['SERVER_NAME']);
+ $host = isset($parsed_host['host']) ? $parsed_host['host'] : null;
+ $port = isset($parsed_host['port']) ? $parsed_host['port'] : null;
+ }else{
+ $host = php_uname('n');
+ $port = '';
+ }
+
+ if(is_null($port)){
+ $port = '';
+ }
+
+ if(!is_ssl()){
+ $proto = 'http://';
+ if ($port == '80') {
+ $port = '';
+ }
+ }else{
+ $proto = 'https://';
+ if ($port == '443') {
+ $port = '';
+ }
+ }
+
+ if($port !== '') $port = ':'.$port;
+
+ return $proto.$host.$port.$dir;
+}
+
+/**
+ * Check if accessed via HTTPS
+ *
+ * Apache leaves ,$_SERVER['HTTPS'] empty when not available, IIS sets it to 'off'.
+ * 'false' and 'disabled' are just guessing
+ *
+ * @returns bool true when SSL is active
+ */
+function is_ssl() {
+ // check if we are behind a reverse proxy
+ if(isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
+ if($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ if(!isset($_SERVER['HTTPS']) ||
+ preg_match('/^(|off|false|disabled)$/i', $_SERVER['HTTPS'])) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+/**
+ * checks it is windows OS
+ * @return bool
+ */
+function isWindows() {
+ return (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? true : false;
+}
+
+/**
+ * print a nice message even if no styles are loaded yet.
+ *
+ * @param integer|string $msg
+ */
+function nice_die($msg){
+ echo<<<EOT
+<!DOCTYPE html>
+<html>
+<head><title>DokuWiki Setup Error</title></head>
+<body style="font-family: Arial, sans-serif">
+ <div style="width:60%; margin: auto; background-color: #fcc;
+ border: 1px solid #faa; padding: 0.5em 1em;">
+ <h1 style="font-size: 120%">DokuWiki Setup Error</h1>
+ <p>$msg</p>
+ </div>
+</body>
+</html>
+EOT;
+ if(defined('DOKU_UNITTEST')) {
+ throw new RuntimeException('nice_die: '.$msg);
+ }
+ exit(1);
+}
+
+/**
+ * A realpath() replacement
+ *
+ * This function behaves similar to PHP's realpath() but does not resolve
+ * symlinks or accesses upper directories
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author <richpageau at yahoo dot co dot uk>
+ * @link http://php.net/manual/en/function.realpath.php#75992
+ *
+ * @param string $path
+ * @param bool $exists
+ *
+ * @return bool|string
+ */
+function fullpath($path,$exists=false){
+ static $run = 0;
+ $root = '';
+ $iswin = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' || !empty($GLOBALS['DOKU_UNITTEST_ASSUME_WINDOWS']));
+
+ // find the (indestructable) root of the path - keeps windows stuff intact
+ if($path[0] == '/'){
+ $root = '/';
+ }elseif($iswin){
+ // match drive letter and UNC paths
+ if(preg_match('!^([a-zA-z]:)(.*)!',$path,$match)){
+ $root = $match[1].'/';
+ $path = $match[2];
+ }else if(preg_match('!^(\\\\\\\\[^\\\\/]+\\\\[^\\\\/]+[\\\\/])(.*)!',$path,$match)){
+ $root = $match[1];
+ $path = $match[2];
+ }
+ }
+ $path = str_replace('\\','/',$path);
+
+ // if the given path wasn't absolute already, prepend the script path and retry
+ if(!$root){
+ $base = dirname($_SERVER['SCRIPT_FILENAME']);
+ $path = $base.'/'.$path;
+ if($run == 0){ // avoid endless recursion when base isn't absolute for some reason
+ $run++;
+ return fullpath($path,$exists);
+ }
+ }
+ $run = 0;
+
+ // canonicalize
+ $path=explode('/', $path);
+ $newpath=array();
+ foreach($path as $p) {
+ if ($p === '' || $p === '.') continue;
+ if ($p==='..') {
+ array_pop($newpath);
+ continue;
+ }
+ array_push($newpath, $p);
+ }
+ $finalpath = $root.implode('/', $newpath);
+
+ // check for existence when needed (except when unit testing)
+ if($exists && !defined('DOKU_UNITTEST') && !file_exists($finalpath)) {
+ return false;
+ }
+ return $finalpath;
+}
+
diff --git a/platform/www/inc/io.php b/platform/www/inc/io.php
new file mode 100644
index 0000000..1dfabe8
--- /dev/null
+++ b/platform/www/inc/io.php
@@ -0,0 +1,781 @@
+<?php
+/**
+ * File IO functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\HTTP\DokuHTTPClient;
+use dokuwiki\Extension\Event;
+
+/**
+ * Removes empty directories
+ *
+ * Sends IO_NAMESPACE_DELETED events for 'pages' and 'media' namespaces.
+ * Event data:
+ * $data[0] ns: The colon separated namespace path minus the trailing page name.
+ * $data[1] ns_type: 'pages' or 'media' namespace tree.
+ *
+ * @param string $id - a pageid, the namespace of that id will be tried to deleted
+ * @param string $basedir - the config name of the type to delete (datadir or mediadir usally)
+ * @return bool - true if at least one namespace was deleted
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+function io_sweepNS($id,$basedir='datadir'){
+ global $conf;
+ $types = array ('datadir'=>'pages', 'mediadir'=>'media');
+ $ns_type = (isset($types[$basedir])?$types[$basedir]:false);
+
+ $delone = false;
+
+ //scan all namespaces
+ while(($id = getNS($id)) !== false){
+ $dir = $conf[$basedir].'/'.utf8_encodeFN(str_replace(':','/',$id));
+
+ //try to delete dir else return
+ if(@rmdir($dir)) {
+ if ($ns_type!==false) {
+ $data = array($id, $ns_type);
+ $delone = true; // we deleted at least one dir
+ Event::createAndTrigger('IO_NAMESPACE_DELETED', $data);
+ }
+ } else { return $delone; }
+ }
+ return $delone;
+}
+
+/**
+ * Used to read in a DokuWiki page from file, and send IO_WIKIPAGE_READ events.
+ *
+ * Generates the action event which delegates to io_readFile().
+ * Action plugins are allowed to modify the page content in transit.
+ * The file path should not be changed.
+ *
+ * Event data:
+ * $data[0] The raw arguments for io_readFile as an array.
+ * $data[1] ns: The colon separated namespace path minus the trailing page name. (false if root ns)
+ * $data[2] page_name: The wiki page name.
+ * $data[3] rev: The page revision, false for current wiki pages.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param string $file filename
+ * @param string $id page id
+ * @param bool|int $rev revision timestamp
+ * @return string
+ */
+function io_readWikiPage($file, $id, $rev=false) {
+ if (empty($rev)) { $rev = false; }
+ $data = array(array($file, true), getNS($id), noNS($id), $rev);
+ return Event::createAndTrigger('IO_WIKIPAGE_READ', $data, '_io_readWikiPage_action', false);
+}
+
+/**
+ * Callback adapter for io_readFile().
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param array $data event data
+ * @return string
+ */
+function _io_readWikiPage_action($data) {
+ if (is_array($data) && is_array($data[0]) && count($data[0])===2) {
+ return call_user_func_array('io_readFile', $data[0]);
+ } else {
+ return ''; //callback error
+ }
+}
+
+/**
+ * Returns content of $file as cleaned string.
+ *
+ * Uses gzip if extension is .gz
+ *
+ * If you want to use the returned value in unserialize
+ * be sure to set $clean to false!
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename
+ * @param bool $clean
+ * @return string|bool the file contents or false on error
+ */
+function io_readFile($file,$clean=true){
+ $ret = '';
+ if(file_exists($file)){
+ if(substr($file,-3) == '.gz'){
+ if(!DOKU_HAS_GZIP) return false;
+ $ret = gzfile($file);
+ if(is_array($ret)) $ret = join('', $ret);
+ }else if(substr($file,-4) == '.bz2'){
+ if(!DOKU_HAS_BZIP) return false;
+ $ret = bzfile($file);
+ }else{
+ $ret = file_get_contents($file);
+ }
+ }
+ if($ret === null) return false;
+ if($ret !== false && $clean){
+ return cleanText($ret);
+ }else{
+ return $ret;
+ }
+}
+/**
+ * Returns the content of a .bz2 compressed file as string
+ *
+ * @author marcel senf <marcel@rucksackreinigung.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename
+ * @param bool $array return array of lines
+ * @return string|array|bool content or false on error
+ */
+function bzfile($file, $array=false) {
+ $bz = bzopen($file,"r");
+ if($bz === false) return false;
+
+ if($array) $lines = array();
+ $str = '';
+ while (!feof($bz)) {
+ //8192 seems to be the maximum buffersize?
+ $buffer = bzread($bz,8192);
+ if(($buffer === false) || (bzerrno($bz) !== 0)) {
+ return false;
+ }
+ $str = $str . $buffer;
+ if($array) {
+ $pos = strpos($str, "\n");
+ while($pos !== false) {
+ $lines[] = substr($str, 0, $pos+1);
+ $str = substr($str, $pos+1);
+ $pos = strpos($str, "\n");
+ }
+ }
+ }
+ bzclose($bz);
+ if($array) {
+ if($str !== '') $lines[] = $str;
+ return $lines;
+ }
+ return $str;
+}
+
+/**
+ * Used to write out a DokuWiki page to file, and send IO_WIKIPAGE_WRITE events.
+ *
+ * This generates an action event and delegates to io_saveFile().
+ * Action plugins are allowed to modify the page content in transit.
+ * The file path should not be changed.
+ * (The append parameter is set to false.)
+ *
+ * Event data:
+ * $data[0] The raw arguments for io_saveFile as an array.
+ * $data[1] ns: The colon separated namespace path minus the trailing page name. (false if root ns)
+ * $data[2] page_name: The wiki page name.
+ * $data[3] rev: The page revision, false for current wiki pages.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param string $file filename
+ * @param string $content
+ * @param string $id page id
+ * @param int|bool $rev timestamp of revision
+ * @return bool
+ */
+function io_writeWikiPage($file, $content, $id, $rev=false) {
+ if (empty($rev)) { $rev = false; }
+ if ($rev===false) { io_createNamespace($id); } // create namespaces as needed
+ $data = array(array($file, $content, false), getNS($id), noNS($id), $rev);
+ return Event::createAndTrigger('IO_WIKIPAGE_WRITE', $data, '_io_writeWikiPage_action', false);
+}
+
+/**
+ * Callback adapter for io_saveFile().
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param array $data event data
+ * @return bool
+ */
+function _io_writeWikiPage_action($data) {
+ if (is_array($data) && is_array($data[0]) && count($data[0])===3) {
+ $ok = call_user_func_array('io_saveFile', $data[0]);
+ // for attic files make sure the file has the mtime of the revision
+ if($ok && is_int($data[3]) && $data[3] > 0) {
+ @touch($data[0][0], $data[3]);
+ }
+ return $ok;
+ } else {
+ return false; //callback error
+ }
+}
+
+/**
+ * Internal function to save contents to a file.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename path to file
+ * @param string $content
+ * @param bool $append
+ * @return bool true on success, otherwise false
+ */
+function _io_saveFile($file, $content, $append) {
+ global $conf;
+ $mode = ($append) ? 'ab' : 'wb';
+ $fileexists = file_exists($file);
+
+ if(substr($file,-3) == '.gz'){
+ if(!DOKU_HAS_GZIP) return false;
+ $fh = @gzopen($file,$mode.'9');
+ if(!$fh) return false;
+ gzwrite($fh, $content);
+ gzclose($fh);
+ }else if(substr($file,-4) == '.bz2'){
+ if(!DOKU_HAS_BZIP) return false;
+ if($append) {
+ $bzcontent = bzfile($file);
+ if($bzcontent === false) return false;
+ $content = $bzcontent.$content;
+ }
+ $fh = @bzopen($file,'w');
+ if(!$fh) return false;
+ bzwrite($fh, $content);
+ bzclose($fh);
+ }else{
+ $fh = @fopen($file,$mode);
+ if(!$fh) return false;
+ fwrite($fh, $content);
+ fclose($fh);
+ }
+
+ if(!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']);
+ return true;
+}
+
+/**
+ * Saves $content to $file.
+ *
+ * If the third parameter is set to true the given content
+ * will be appended.
+ *
+ * Uses gzip if extension is .gz
+ * and bz2 if extension is .bz2
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename path to file
+ * @param string $content
+ * @param bool $append
+ * @return bool true on success, otherwise false
+ */
+function io_saveFile($file, $content, $append=false) {
+ io_makeFileDir($file);
+ io_lock($file);
+ if(!_io_saveFile($file, $content, $append)) {
+ msg("Writing $file failed",-1);
+ io_unlock($file);
+ return false;
+ }
+ io_unlock($file);
+ return true;
+}
+
+/**
+ * Replace one or more occurrences of a line in a file.
+ *
+ * The default, when $maxlines is 0 is to delete all matching lines then append a single line.
+ * A regex that matches any part of the line will remove the entire line in this mode.
+ * Captures in $newline are not available.
+ *
+ * Otherwise each line is matched and replaced individually, up to the first $maxlines lines
+ * or all lines if $maxlines is -1. If $regex is true then captures can be used in $newline.
+ *
+ * Be sure to include the trailing newline in $oldline when replacing entire lines.
+ *
+ * Uses gzip if extension is .gz
+ * and bz2 if extension is .bz2
+ *
+ * @author Steven Danz <steven-danz@kc.rr.com>
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Patrick Brown <ptbrown@whoopdedo.org>
+ *
+ * @param string $file filename
+ * @param string $oldline exact linematch to remove
+ * @param string $newline new line to insert
+ * @param bool $regex use regexp?
+ * @param int $maxlines number of occurrences of the line to replace
+ * @return bool true on success
+ */
+function io_replaceInFile($file, $oldline, $newline, $regex=false, $maxlines=0) {
+ if ((string)$oldline === '') {
+ trigger_error('$oldline parameter cannot be empty in io_replaceInFile()', E_USER_WARNING);
+ return false;
+ }
+
+ if (!file_exists($file)) return true;
+
+ io_lock($file);
+
+ // load into array
+ if(substr($file,-3) == '.gz'){
+ if(!DOKU_HAS_GZIP) return false;
+ $lines = gzfile($file);
+ }else if(substr($file,-4) == '.bz2'){
+ if(!DOKU_HAS_BZIP) return false;
+ $lines = bzfile($file, true);
+ }else{
+ $lines = file($file);
+ }
+
+ // make non-regexes into regexes
+ $pattern = $regex ? $oldline : '/^'.preg_quote($oldline,'/').'$/';
+ $replace = $regex ? $newline : addcslashes($newline, '\$');
+
+ // remove matching lines
+ if ($maxlines > 0) {
+ $count = 0;
+ $matched = 0;
+ foreach($lines as $i => $line) {
+ if($count >= $maxlines) break;
+ // $matched will be set to 0|1 depending on whether pattern is matched and line replaced
+ $lines[$i] = preg_replace($pattern, $replace, $line, -1, $matched);
+ if ($matched) $count++;
+ }
+ } else if ($maxlines == 0) {
+ $lines = preg_grep($pattern, $lines, PREG_GREP_INVERT);
+
+ if ((string)$newline !== ''){
+ $lines[] = $newline;
+ }
+ } else {
+ $lines = preg_replace($pattern, $replace, $lines);
+ }
+
+ if(count($lines)){
+ if(!_io_saveFile($file, join('',$lines), false)) {
+ msg("Removing content from $file failed",-1);
+ io_unlock($file);
+ return false;
+ }
+ }else{
+ @unlink($file);
+ }
+
+ io_unlock($file);
+ return true;
+}
+
+/**
+ * Delete lines that match $badline from $file.
+ *
+ * Be sure to include the trailing newline in $badline
+ *
+ * @author Patrick Brown <ptbrown@whoopdedo.org>
+ *
+ * @param string $file filename
+ * @param string $badline exact linematch to remove
+ * @param bool $regex use regexp?
+ * @return bool true on success
+ */
+function io_deleteFromFile($file,$badline,$regex=false){
+ return io_replaceInFile($file,$badline,null,$regex,0);
+}
+
+/**
+ * Tries to lock a file
+ *
+ * Locking is only done for io_savefile and uses directories
+ * inside $conf['lockdir']
+ *
+ * It waits maximal 3 seconds for the lock, after this time
+ * the lock is assumed to be stale and the function goes on
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename
+ */
+function io_lock($file){
+ global $conf;
+
+ $lockDir = $conf['lockdir'].'/'.md5($file);
+ @ignore_user_abort(1);
+
+ $timeStart = time();
+ do {
+ //waited longer than 3 seconds? -> stale lock
+ if ((time() - $timeStart) > 3) break;
+ $locked = @mkdir($lockDir, $conf['dmode']);
+ if($locked){
+ if(!empty($conf['dperm'])) chmod($lockDir, $conf['dperm']);
+ break;
+ }
+ usleep(50);
+ } while ($locked === false);
+}
+
+/**
+ * Unlocks a file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename
+ */
+function io_unlock($file){
+ global $conf;
+
+ $lockDir = $conf['lockdir'].'/'.md5($file);
+ @rmdir($lockDir);
+ @ignore_user_abort(0);
+}
+
+/**
+ * Create missing namespace directories and send the IO_NAMESPACE_CREATED events
+ * in the order of directory creation. (Parent directories first.)
+ *
+ * Event data:
+ * $data[0] ns: The colon separated namespace path minus the trailing page name.
+ * $data[1] ns_type: 'pages' or 'media' namespace tree.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param string $id page id
+ * @param string $ns_type 'pages' or 'media'
+ */
+function io_createNamespace($id, $ns_type='pages') {
+ // verify ns_type
+ $types = array('pages'=>'wikiFN', 'media'=>'mediaFN');
+ if (!isset($types[$ns_type])) {
+ trigger_error('Bad $ns_type parameter for io_createNamespace().');
+ return;
+ }
+ // make event list
+ $missing = array();
+ $ns_stack = explode(':', $id);
+ $ns = $id;
+ $tmp = dirname( $file = call_user_func($types[$ns_type], $ns) );
+ while (!@is_dir($tmp) && !(file_exists($tmp) && !is_dir($tmp))) {
+ array_pop($ns_stack);
+ $ns = implode(':', $ns_stack);
+ if (strlen($ns)==0) { break; }
+ $missing[] = $ns;
+ $tmp = dirname(call_user_func($types[$ns_type], $ns));
+ }
+ // make directories
+ io_makeFileDir($file);
+ // send the events
+ $missing = array_reverse($missing); // inside out
+ foreach ($missing as $ns) {
+ $data = array($ns, $ns_type);
+ Event::createAndTrigger('IO_NAMESPACE_CREATED', $data);
+ }
+}
+
+/**
+ * Create the directory needed for the given file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file file name
+ */
+function io_makeFileDir($file){
+ $dir = dirname($file);
+ if(!@is_dir($dir)){
+ io_mkdir_p($dir) || msg("Creating directory $dir failed",-1);
+ }
+}
+
+/**
+ * Creates a directory hierachy.
+ *
+ * @link http://php.net/manual/en/function.mkdir.php
+ * @author <saint@corenova.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $target filename
+ * @return bool|int|string
+ */
+function io_mkdir_p($target){
+ global $conf;
+ if (@is_dir($target)||empty($target)) return 1; // best case check first
+ if (file_exists($target) && !is_dir($target)) return 0;
+ //recursion
+ if (io_mkdir_p(substr($target,0,strrpos($target,'/')))){
+ $ret = @mkdir($target,$conf['dmode']); // crawl back up & create dir tree
+ if($ret && !empty($conf['dperm'])) chmod($target, $conf['dperm']);
+ return $ret;
+ }
+ return 0;
+}
+
+/**
+ * Recursively delete a directory
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $path
+ * @param bool $removefiles defaults to false which will delete empty directories only
+ * @return bool
+ */
+function io_rmdir($path, $removefiles = false) {
+ if(!is_string($path) || $path == "") return false;
+ if(!file_exists($path)) return true; // it's already gone or was never there, count as success
+
+ if(is_dir($path) && !is_link($path)) {
+ $dirs = array();
+ $files = array();
+
+ if(!$dh = @opendir($path)) return false;
+ while(false !== ($f = readdir($dh))) {
+ if($f == '..' || $f == '.') continue;
+
+ // collect dirs and files first
+ if(is_dir("$path/$f") && !is_link("$path/$f")) {
+ $dirs[] = "$path/$f";
+ } else if($removefiles) {
+ $files[] = "$path/$f";
+ } else {
+ return false; // abort when non empty
+ }
+
+ }
+ closedir($dh);
+
+ // now traverse into directories first
+ foreach($dirs as $dir) {
+ if(!io_rmdir($dir, $removefiles)) return false; // abort on any error
+ }
+
+ // now delete files
+ foreach($files as $file) {
+ if(!@unlink($file)) return false; //abort on any error
+ }
+
+ // remove self
+ return @rmdir($path);
+ } else if($removefiles) {
+ return @unlink($path);
+ }
+ return false;
+}
+
+/**
+ * Creates a unique temporary directory and returns
+ * its path.
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @return false|string path to new directory or false
+ */
+function io_mktmpdir() {
+ global $conf;
+
+ $base = $conf['tmpdir'];
+ $dir = md5(uniqid(mt_rand(), true));
+ $tmpdir = $base.'/'.$dir;
+
+ if(io_mkdir_p($tmpdir)) {
+ return($tmpdir);
+ } else {
+ return false;
+ }
+}
+
+/**
+ * downloads a file from the net and saves it
+ *
+ * if $useAttachment is false,
+ * - $file is the full filename to save the file, incl. path
+ * - if successful will return true, false otherwise
+ *
+ * if $useAttachment is true,
+ * - $file is the directory where the file should be saved
+ * - if successful will return the name used for the saved file, false otherwise
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $url url to download
+ * @param string $file path to file or directory where to save
+ * @param bool $useAttachment true: try to use name of download, uses otherwise $defaultName
+ * false: uses $file as path to file
+ * @param string $defaultName fallback for if using $useAttachment
+ * @param int $maxSize maximum file size
+ * @return bool|string if failed false, otherwise true or the name of the file in the given dir
+ */
+function io_download($url,$file,$useAttachment=false,$defaultName='',$maxSize=2097152){
+ global $conf;
+ $http = new DokuHTTPClient();
+ $http->max_bodysize = $maxSize;
+ $http->timeout = 25; //max. 25 sec
+ $http->keep_alive = false; // we do single ops here, no need for keep-alive
+
+ $data = $http->get($url);
+ if(!$data) return false;
+
+ $name = '';
+ if ($useAttachment) {
+ if (isset($http->resp_headers['content-disposition'])) {
+ $content_disposition = $http->resp_headers['content-disposition'];
+ $match=array();
+ if (is_string($content_disposition) &&
+ preg_match('/attachment;\s*filename\s*=\s*"([^"]*)"/i', $content_disposition, $match)) {
+
+ $name = \dokuwiki\Utf8\PhpString::basename($match[1]);
+ }
+
+ }
+
+ if (!$name) {
+ if (!$defaultName) return false;
+ $name = $defaultName;
+ }
+
+ $file = $file.$name;
+ }
+
+ $fileexists = file_exists($file);
+ $fp = @fopen($file,"w");
+ if(!$fp) return false;
+ fwrite($fp,$data);
+ fclose($fp);
+ if(!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']);
+ if ($useAttachment) return $name;
+ return true;
+}
+
+/**
+ * Windows compatible rename
+ *
+ * rename() can not overwrite existing files on Windows
+ * this function will use copy/unlink instead
+ *
+ * @param string $from
+ * @param string $to
+ * @return bool succes or fail
+ */
+function io_rename($from,$to){
+ global $conf;
+ if(!@rename($from,$to)){
+ if(@copy($from,$to)){
+ if($conf['fperm']) chmod($to, $conf['fperm']);
+ @unlink($from);
+ return true;
+ }
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Runs an external command with input and output pipes.
+ * Returns the exit code from the process.
+ *
+ * @author Tom N Harris <tnharris@whoopdedo.org>
+ *
+ * @param string $cmd
+ * @param string $input input pipe
+ * @param string $output output pipe
+ * @return int exit code from process
+ */
+function io_exec($cmd, $input, &$output){
+ $descspec = array(
+ 0=>array("pipe","r"),
+ 1=>array("pipe","w"),
+ 2=>array("pipe","w"));
+ $ph = proc_open($cmd, $descspec, $pipes);
+ if(!$ph) return -1;
+ fclose($pipes[2]); // ignore stderr
+ fwrite($pipes[0], $input);
+ fclose($pipes[0]);
+ $output = stream_get_contents($pipes[1]);
+ fclose($pipes[1]);
+ return proc_close($ph);
+}
+
+/**
+ * Search a file for matching lines
+ *
+ * This is probably not faster than file()+preg_grep() but less
+ * memory intensive because not the whole file needs to be loaded
+ * at once.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $file The file to search
+ * @param string $pattern PCRE pattern
+ * @param int $max How many lines to return (0 for all)
+ * @param bool $backref When true returns array with backreferences instead of lines
+ * @return array matching lines or backref, false on error
+ */
+function io_grep($file,$pattern,$max=0,$backref=false){
+ $fh = @fopen($file,'r');
+ if(!$fh) return false;
+ $matches = array();
+
+ $cnt = 0;
+ $line = '';
+ while (!feof($fh)) {
+ $line .= fgets($fh, 4096); // read full line
+ if(substr($line,-1) != "\n") continue;
+
+ // check if line matches
+ if(preg_match($pattern,$line,$match)){
+ if($backref){
+ $matches[] = $match;
+ }else{
+ $matches[] = $line;
+ }
+ $cnt++;
+ }
+ if($max && $max == $cnt) break;
+ $line = '';
+ }
+ fclose($fh);
+ return $matches;
+}
+
+
+/**
+ * Get size of contents of a file, for a compressed file the uncompressed size
+ * Warning: reading uncompressed size of content of bz-files requires uncompressing
+ *
+ * @author Gerrit Uitslag <klapinklapin@gmail.com>
+ *
+ * @param string $file filename path to file
+ * @return int size of file
+ */
+function io_getSizeFile($file) {
+ if (!file_exists($file)) return 0;
+
+ if(substr($file,-3) == '.gz'){
+ $fp = @fopen($file, "rb");
+ if($fp === false) return 0;
+
+ fseek($fp, -4, SEEK_END);
+ $buffer = fread($fp, 4);
+ fclose($fp);
+ $array = unpack("V", $buffer);
+ $uncompressedsize = end($array);
+ }else if(substr($file,-4) == '.bz2'){
+ if(!DOKU_HAS_BZIP) return 0;
+
+ $bz = bzopen($file,"r");
+ if($bz === false) return 0;
+
+ $uncompressedsize = 0;
+ while (!feof($bz)) {
+ //8192 seems to be the maximum buffersize?
+ $buffer = bzread($bz,8192);
+ if(($buffer === false) || (bzerrno($bz) !== 0)) {
+ return 0;
+ }
+ $uncompressedsize += strlen($buffer);
+ }
+ }else{
+ $uncompressedsize = filesize($file);
+ }
+
+ return $uncompressedsize;
+ }
diff --git a/platform/www/inc/lang/en/admin.txt b/platform/www/inc/lang/en/admin.txt
new file mode 100644
index 0000000..8998ca9
--- /dev/null
+++ b/platform/www/inc/lang/en/admin.txt
@@ -0,0 +1,3 @@
+====== Administration ======
+
+Below you can find a list of administrative tasks available in DokuWiki.
diff --git a/platform/www/inc/lang/en/adminplugins.txt b/platform/www/inc/lang/en/adminplugins.txt
new file mode 100644
index 0000000..3ec46cf
--- /dev/null
+++ b/platform/www/inc/lang/en/adminplugins.txt
@@ -0,0 +1,2 @@
+===== Additional Plugins =====
+
diff --git a/platform/www/inc/lang/en/backlinks.txt b/platform/www/inc/lang/en/backlinks.txt
new file mode 100644
index 0000000..55514bf
--- /dev/null
+++ b/platform/www/inc/lang/en/backlinks.txt
@@ -0,0 +1,3 @@
+====== Backlinks ======
+
+This is a list of pages that seem to link back to the current page.
diff --git a/platform/www/inc/lang/en/conflict.txt b/platform/www/inc/lang/en/conflict.txt
new file mode 100644
index 0000000..2586a2a
--- /dev/null
+++ b/platform/www/inc/lang/en/conflict.txt
@@ -0,0 +1,5 @@
+====== A newer version exists ======
+
+A newer version of the document you edited exists. This happens when another user changed the document while you were editing it.
+
+Examine the differences shown below thoroughly, then decide which version to keep. If you choose ''save'', your version will be saved. Hit ''cancel'' to keep the current version.
diff --git a/platform/www/inc/lang/en/denied.txt b/platform/www/inc/lang/en/denied.txt
new file mode 100644
index 0000000..e6fade4
--- /dev/null
+++ b/platform/www/inc/lang/en/denied.txt
@@ -0,0 +1,3 @@
+====== Permission Denied ======
+
+Sorry, you don't have enough rights to continue.
diff --git a/platform/www/inc/lang/en/diff.txt b/platform/www/inc/lang/en/diff.txt
new file mode 100644
index 0000000..46f0b34
--- /dev/null
+++ b/platform/www/inc/lang/en/diff.txt
@@ -0,0 +1,3 @@
+====== Differences ======
+
+This shows you the differences between two versions of the page.
diff --git a/platform/www/inc/lang/en/draft.txt b/platform/www/inc/lang/en/draft.txt
new file mode 100644
index 0000000..b6a930a
--- /dev/null
+++ b/platform/www/inc/lang/en/draft.txt
@@ -0,0 +1,5 @@
+====== Draft file found ======
+
+Your last edit session on this page was not completed correctly. DokuWiki automatically saved a draft during your work which you may now use to continue your editing. Below you can see the data that was saved from your last session.
+
+Please decide if you want to //recover// your lost edit session, //delete// the autosaved draft or //cancel// the editing process.
diff --git a/platform/www/inc/lang/en/edit.txt b/platform/www/inc/lang/en/edit.txt
new file mode 100644
index 0000000..0f395b5
--- /dev/null
+++ b/platform/www/inc/lang/en/edit.txt
@@ -0,0 +1 @@
+Edit the page and hit ''Save''. See [[wiki:syntax]] for Wiki syntax. Please edit the page only if you can **improve** it. If you want to test some things, learn to make your first steps on the [[playground:playground|playground]].
diff --git a/platform/www/inc/lang/en/editrev.txt b/platform/www/inc/lang/en/editrev.txt
new file mode 100644
index 0000000..638216b
--- /dev/null
+++ b/platform/www/inc/lang/en/editrev.txt
@@ -0,0 +1,2 @@
+**You've loaded an old revision of the document!** If you save it, you will create a new version with this data.
+----
diff --git a/platform/www/inc/lang/en/index.txt b/platform/www/inc/lang/en/index.txt
new file mode 100644
index 0000000..dced649
--- /dev/null
+++ b/platform/www/inc/lang/en/index.txt
@@ -0,0 +1,3 @@
+====== Sitemap ======
+
+This is a sitemap over all available pages ordered by [[doku>namespaces|namespaces]].
diff --git a/platform/www/inc/lang/en/install.html b/platform/www/inc/lang/en/install.html
new file mode 100644
index 0000000..fa6b99a
--- /dev/null
+++ b/platform/www/inc/lang/en/install.html
@@ -0,0 +1,7 @@
+<p>This page assists in the first time installation and configuration of <a href="http://dokuwiki.org">Dokuwiki</a>. More info on this installer is available on it's own <a href="http://dokuwiki.org/installer">documentation page</a>.</p>
+
+<p>DokuWiki uses ordinary files for the storage of wiki pages and other information associated with those pages (e.g. images, search indexes, old revisions, etc). In order to operate successfully DokuWiki <strong>must</strong> have write access to the directories that hold those files. This installer is not capable of setting up directory permissions. That normally needs to be done directly on a command shell or if you are using hosting, through FTP or your hosting control panel (e.g. cPanel).</p>
+
+<p>This installer will setup your DokuWiki configuration for <abbr title="access control list">ACL</abbr>, which in turn allows administrator login and access to DokuWiki's admin menu for installing plugins, managing users, managing access to wiki pages and alteration of configuration settings. It isn't required for DokuWiki to operate, however it will make Dokuwiki easier to administer.</p>
+
+<p>Experienced users or users with special setup requirements should use these links for details concerning <a href="http://dokuwiki.org/install">installation instructions</a> and <a href="http://dokuwiki.org/config">configuration settings</a>.</p>
diff --git a/platform/www/inc/lang/en/lang.php b/platform/www/inc/lang/en/lang.php
new file mode 100644
index 0000000..000368a
--- /dev/null
+++ b/platform/www/inc/lang/en/lang.php
@@ -0,0 +1,395 @@
+<?php
+/**
+ * english language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Matthias Schulte <mailinglist@lupo49.de>
+ */
+$lang['encoding'] = 'utf-8';
+$lang['direction'] = 'ltr';
+$lang['doublequoteopening'] = '“'; //&ldquo;
+$lang['doublequoteclosing'] = 'â€'; //&rdquo;
+$lang['singlequoteopening'] = '‘'; //&lsquo;
+$lang['singlequoteclosing'] = '’'; //&rsquo;
+$lang['apostrophe'] = '’'; //&rsquo;
+
+$lang['btn_edit'] = 'Edit this page';
+$lang['btn_source'] = 'Show pagesource';
+$lang['btn_show'] = 'Show page';
+$lang['btn_create'] = 'Create this page';
+$lang['btn_search'] = 'Search';
+$lang['btn_save'] = 'Save';
+$lang['btn_preview'] = 'Preview';
+$lang['btn_top'] = 'Back to top';
+$lang['btn_newer'] = '<< more recent';
+$lang['btn_older'] = 'less recent >>';
+$lang['btn_revs'] = 'Old revisions';
+$lang['btn_recent'] = 'Recent Changes';
+$lang['btn_upload'] = 'Upload';
+$lang['btn_cancel'] = 'Cancel';
+$lang['btn_index'] = 'Sitemap';
+$lang['btn_secedit'] = 'Edit';
+$lang['btn_login'] = 'Log In';
+$lang['btn_logout'] = 'Log Out';
+$lang['btn_admin'] = 'Admin';
+$lang['btn_update'] = 'Update';
+$lang['btn_delete'] = 'Delete';
+$lang['btn_back'] = 'Back';
+$lang['btn_backlink'] = 'Backlinks';
+$lang['btn_subscribe'] = 'Manage Subscriptions';
+$lang['btn_profile'] = 'Update Profile';
+$lang['btn_reset'] = 'Reset';
+$lang['btn_resendpwd'] = 'Set new password';
+$lang['btn_draft'] = 'Edit draft';
+$lang['btn_recover'] = 'Recover draft';
+$lang['btn_draftdel'] = 'Delete draft';
+$lang['btn_revert'] = 'Restore';
+$lang['btn_register'] = 'Register';
+$lang['btn_apply'] = 'Apply';
+$lang['btn_media'] = 'Media Manager';
+$lang['btn_deleteuser'] = 'Remove My Account';
+$lang['btn_img_backto'] = 'Back to %s';
+$lang['btn_mediaManager'] = 'View in media manager';
+
+$lang['loggedinas'] = 'Logged in as:';
+$lang['user'] = 'Username';
+$lang['pass'] = 'Password';
+$lang['newpass'] = 'New password';
+$lang['oldpass'] = 'Confirm current password';
+$lang['passchk'] = 'once again';
+$lang['remember'] = 'Remember me';
+$lang['fullname'] = 'Real name';
+$lang['email'] = 'E-Mail';
+$lang['profile'] = 'User Profile';
+$lang['badlogin'] = 'Sorry, username or password was wrong.';
+$lang['badpassconfirm'] = 'Sorry, the password was wrong';
+$lang['minoredit'] = 'Minor Changes';
+$lang['draftdate'] = 'Draft autosaved on'; // full dformat date will be added
+$lang['nosecedit'] = 'The page was changed in the meantime, section info was out of date loaded full page instead.';
+$lang['searchcreatepage'] = 'If you didn\'t find what you were looking for, you can create or edit the page %s, named after your query.';
+
+$lang['search_fullresults'] = 'Fulltext results';
+$lang['js']['search_toggle_tools'] = 'Toggle Search Tools';
+$lang['search_exact_match'] = 'Exact match';
+$lang['search_starts_with'] = 'Starts with';
+$lang['search_ends_with'] = 'Ends with';
+$lang['search_contains'] = 'Contains';
+$lang['search_custom_match'] = 'Custom';
+$lang['search_any_ns'] = 'Any namespace';
+$lang['search_any_time'] = 'Any time';
+$lang['search_past_7_days'] = 'Past week';
+$lang['search_past_month'] = 'Past month';
+$lang['search_past_year'] = 'Past year';
+$lang['search_sort_by_hits'] = 'Sort by hits';
+$lang['search_sort_by_mtime'] = 'Sort by last modified';
+
+$lang['regmissing'] = 'Sorry, you must fill in all fields.';
+$lang['reguexists'] = 'Sorry, a user with this login already exists.';
+$lang['regsuccess'] = 'The user has been created and the password was sent by email.';
+$lang['regsuccess2'] = 'The user has been created.';
+$lang['regfail'] = 'The user could not be created.';
+$lang['regmailfail'] = 'Looks like there was an error on sending the password mail. Please contact the admin!';
+$lang['regbadmail'] = 'The given email address looks invalid - if you think this is an error, contact the admin';
+$lang['regbadpass'] = 'The two given passwords are not identical, please try again.';
+$lang['regpwmail'] = 'Your DokuWiki password';
+$lang['reghere'] = 'You don\'t have an account yet? Just get one';
+
+$lang['profna'] = 'This wiki does not support profile modification';
+$lang['profnochange'] = 'No changes, nothing to do.';
+$lang['profnoempty'] = 'An empty name or email address is not allowed.';
+$lang['profchanged'] = 'User profile successfully updated.';
+$lang['profnodelete'] = 'This wiki does not support deleting users';
+$lang['profdeleteuser'] = 'Delete Account';
+$lang['profdeleted'] = 'Your user account has been deleted from this wiki';
+$lang['profconfdelete'] = 'I wish to remove my account from this wiki. <br/> This action can not be undone.';
+$lang['profconfdeletemissing'] = 'Confirmation check box not ticked';
+$lang['proffail'] = 'User profile was not updated.';
+
+$lang['pwdforget'] = 'Forgotten your password? Get a new one';
+$lang['resendna'] = 'This wiki does not support password resending.';
+$lang['resendpwd'] = 'Set new password for';
+$lang['resendpwdmissing'] = 'Sorry, you must fill in all fields.';
+$lang['resendpwdnouser'] = 'Sorry, we can\'t find this user in our database.';
+$lang['resendpwdbadauth'] = 'Sorry, this auth code is not valid. Make sure you used the complete confirmation link.';
+$lang['resendpwdconfirm'] = 'A confirmation link has been sent by email.';
+$lang['resendpwdsuccess'] = 'Your new password has been sent by email.';
+
+$lang['license'] = 'Except where otherwise noted, content on this wiki is licensed under the following license:';
+$lang['licenseok'] = 'Note: By editing this page you agree to license your content under the following license:';
+
+$lang['searchmedia'] = 'Search file name:';
+$lang['searchmedia_in'] = 'Search in %s';
+$lang['txt_upload'] = 'Select file to upload:';
+$lang['txt_filename'] = 'Upload as (optional):';
+$lang['txt_overwrt'] = 'Overwrite existing file';
+$lang['maxuploadsize'] = 'Upload max. %s per file.';
+$lang['allowedmime'] = 'List of allowed file extensions';
+$lang['lockedby'] = 'Currently locked by:';
+$lang['lockexpire'] = 'Lock expires at:';
+
+$lang['js']['willexpire'] = 'Your lock for editing this page is about to expire in a minute.\nTo avoid conflicts use the preview button to reset the locktimer.';
+$lang['js']['notsavedyet'] = 'Unsaved changes will be lost.';
+$lang['js']['searchmedia'] = 'Search for files';
+$lang['js']['keepopen'] = 'Keep window open on selection';
+$lang['js']['hidedetails'] = 'Hide Details';
+$lang['js']['mediatitle'] = 'Link settings';
+$lang['js']['mediadisplay'] = 'Link type';
+$lang['js']['mediaalign'] = 'Alignment';
+$lang['js']['mediasize'] = 'Image size';
+$lang['js']['mediatarget'] = 'Link target';
+$lang['js']['mediaclose'] = 'Close';
+$lang['js']['mediainsert'] = 'Insert';
+$lang['js']['mediadisplayimg'] = 'Show the image.';
+$lang['js']['mediadisplaylnk'] = 'Show only the link.';
+$lang['js']['mediasmall'] = 'Small version';
+$lang['js']['mediamedium'] = 'Medium version';
+$lang['js']['medialarge'] = 'Large version';
+$lang['js']['mediaoriginal'] = 'Original version';
+$lang['js']['medialnk'] = 'Link to detail page';
+$lang['js']['mediadirect'] = 'Direct link to original';
+$lang['js']['medianolnk'] = 'No link';
+$lang['js']['medianolink'] = 'Do not link the image';
+$lang['js']['medialeft'] = 'Align the image on the left.';
+$lang['js']['mediaright'] = 'Align the image on the right.';
+$lang['js']['mediacenter'] = 'Align the image in the middle.';
+$lang['js']['medianoalign'] = 'Use no align.';
+$lang['js']['nosmblinks'] = 'Linking to Windows shares only works in Microsoft Internet Explorer.\nYou still can copy and paste the link.';
+$lang['js']['linkwiz'] = 'Link Wizard';
+$lang['js']['linkto'] = 'Link to:';
+$lang['js']['del_confirm'] = 'Really delete selected item(s)?';
+$lang['js']['restore_confirm'] = 'Really restore this version?';
+$lang['js']['media_diff'] = 'View differences:';
+$lang['js']['media_diff_both'] = 'Side by Side';
+$lang['js']['media_diff_opacity'] = 'Shine-through';
+$lang['js']['media_diff_portions'] = 'Swipe';
+$lang['js']['media_select'] = 'Select files…';
+$lang['js']['media_upload_btn'] = 'Upload';
+$lang['js']['media_done_btn'] = 'Done';
+$lang['js']['media_drop'] = 'Drop files here to upload';
+$lang['js']['media_cancel'] = 'remove';
+$lang['js']['media_overwrt'] = 'Overwrite existing files';
+
+$lang['rssfailed'] = 'An error occurred while fetching this feed: ';
+$lang['nothingfound'] = 'Nothing was found.';
+
+$lang['mediaselect'] = 'Media Files';
+$lang['uploadsucc'] = 'Upload successful';
+$lang['uploadfail'] = 'Upload failed. Maybe wrong permissions?';
+$lang['uploadwrong'] = 'Upload denied. This file extension is forbidden!';
+$lang['uploadexist'] = 'File already exists. Nothing done.';
+$lang['uploadbadcontent'] = 'The uploaded content did not match the %s file extension.';
+$lang['uploadspam'] = 'The upload was blocked by the spam blacklist.';
+$lang['uploadxss'] = 'The upload was blocked for possibly malicious content.';
+$lang['uploadsize'] = 'The uploaded file was too big. (max. %s)';
+$lang['deletesucc'] = 'The file "%s" has been deleted.';
+$lang['deletefail'] = '"%s" couldn\'t be deleted - check permissions.';
+$lang['mediainuse'] = 'The file "%s" hasn\'t been deleted - it is still in use.';
+$lang['namespaces'] = 'Namespaces';
+$lang['mediafiles'] = 'Available files in';
+$lang['accessdenied'] = 'You are not allowed to view this page.';
+$lang['mediausage'] = 'Use the following syntax to reference this file:';
+$lang['mediaview'] = 'View original file';
+$lang['mediaroot'] = 'root';
+$lang['mediaupload'] = 'Upload a file to the current namespace here. To create subnamespaces, prepend them to your filename separated by colons after you selected the files. Files can also be selected by drag and drop.';
+$lang['mediaextchange'] = 'Filextension changed from .%s to .%s!';
+$lang['reference'] = 'References for';
+$lang['ref_inuse'] = 'The file can\'t be deleted, because it\'s still used by the following pages:';
+$lang['ref_hidden'] = 'Some references are on pages you don\'t have permission to read';
+
+$lang['hits'] = 'Hits';
+$lang['quickhits'] = 'Matching pagenames';
+$lang['toc'] = 'Table of Contents';
+$lang['current'] = 'current';
+$lang['yours'] = 'Your Version';
+$lang['diff'] = 'Show differences to current revisions';
+$lang['diff2'] = 'Show differences between selected revisions';
+$lang['difflink'] = 'Link to this comparison view';
+$lang['diff_type'] = 'View differences:';
+$lang['diff_inline'] = 'Inline';
+$lang['diff_side'] = 'Side by Side';
+$lang['diffprevrev'] = 'Previous revision';
+$lang['diffnextrev'] = 'Next revision';
+$lang['difflastrev'] = 'Last revision';
+$lang['diffbothprevrev'] = 'Both sides previous revision';
+$lang['diffbothnextrev'] = 'Both sides next revision';
+$lang['line'] = 'Line';
+$lang['breadcrumb'] = 'Trace:';
+$lang['youarehere'] = 'You are here:';
+$lang['lastmod'] = 'Last modified:';
+$lang['by'] = 'by';
+$lang['deleted'] = 'removed';
+$lang['created'] = 'created';
+$lang['restored'] = 'old revision restored (%s)';
+$lang['external_edit'] = 'external edit';
+$lang['summary'] = 'Edit summary';
+$lang['noflash'] = 'The <a href="http://get.adobe.com/flashplayer">Adobe Flash Plugin</a> is needed to display this content.';
+$lang['download'] = 'Download Snippet';
+$lang['tools'] = 'Tools';
+$lang['user_tools'] = 'User Tools';
+$lang['site_tools'] = 'Site Tools';
+$lang['page_tools'] = 'Page Tools';
+$lang['skip_to_content'] = 'skip to content';
+$lang['sidebar'] = 'Sidebar';
+
+$lang['mail_newpage'] = 'page added:';
+$lang['mail_changed'] = 'page changed:';
+$lang['mail_subscribe_list'] = 'pages changed in namespace:';
+$lang['mail_new_user'] = 'new user:';
+$lang['mail_upload'] = 'file uploaded:';
+
+$lang['changes_type'] = 'View changes of';
+$lang['pages_changes'] = 'Pages';
+$lang['media_changes'] = 'Media files';
+$lang['both_changes'] = 'Both pages and media files';
+
+$lang['qb_bold'] = 'Bold Text';
+$lang['qb_italic'] = 'Italic Text';
+$lang['qb_underl'] = 'Underlined Text';
+$lang['qb_code'] = 'Monospaced Text';
+$lang['qb_strike'] = 'Strike-through Text';
+$lang['qb_h1'] = 'Level 1 Headline';
+$lang['qb_h2'] = 'Level 2 Headline';
+$lang['qb_h3'] = 'Level 3 Headline';
+$lang['qb_h4'] = 'Level 4 Headline';
+$lang['qb_h5'] = 'Level 5 Headline';
+$lang['qb_h'] = 'Headline';
+$lang['qb_hs'] = 'Select Headline';
+$lang['qb_hplus'] = 'Higher Headline';
+$lang['qb_hminus'] = 'Lower Headline';
+$lang['qb_hequal'] = 'Same Level Headline';
+$lang['qb_link'] = 'Internal Link';
+$lang['qb_extlink'] = 'External Link';
+$lang['qb_hr'] = 'Horizontal Rule';
+$lang['qb_ol'] = 'Ordered List Item';
+$lang['qb_ul'] = 'Unordered List Item';
+$lang['qb_media'] = 'Add Images and other files (opens in a new window)';
+$lang['qb_sig'] = 'Insert Signature';
+$lang['qb_smileys'] = 'Smileys';
+$lang['qb_chars'] = 'Special Chars';
+
+$lang['upperns'] = 'jump to parent namespace';
+
+$lang['metaedit'] = 'Edit Metadata';
+$lang['metasaveerr'] = 'Writing metadata failed';
+$lang['metasaveok'] = 'Metadata saved';
+$lang['img_title'] = 'Title:';
+$lang['img_caption'] = 'Caption:';
+$lang['img_date'] = 'Date:';
+$lang['img_fname'] = 'Filename:';
+$lang['img_fsize'] = 'Size:';
+$lang['img_artist'] = 'Photographer:';
+$lang['img_copyr'] = 'Copyright:';
+$lang['img_format'] = 'Format:';
+$lang['img_camera'] = 'Camera:';
+$lang['img_keywords'] = 'Keywords:';
+$lang['img_width'] = 'Width:';
+$lang['img_height'] = 'Height:';
+
+$lang['subscr_subscribe_success'] = 'Added %s to subscription list for %s';
+$lang['subscr_subscribe_error'] = 'Error adding %s to subscription list for %s';
+$lang['subscr_subscribe_noaddress'] = 'There is no address associated with your login, you cannot be added to the subscription list';
+$lang['subscr_unsubscribe_success'] = 'Removed %s from subscription list for %s';
+$lang['subscr_unsubscribe_error'] = 'Error removing %s from subscription list for %s';
+$lang['subscr_already_subscribed'] = '%s is already subscribed to %s';
+$lang['subscr_not_subscribed'] = '%s is not subscribed to %s';
+// Manage page for subscriptions
+$lang['subscr_m_not_subscribed'] = 'You are currently not subscribed to the current page or namespace.';
+$lang['subscr_m_new_header'] = 'Add subscription';
+$lang['subscr_m_current_header'] = 'Current subscriptions';
+$lang['subscr_m_unsubscribe'] = 'Unsubscribe';
+$lang['subscr_m_subscribe'] = 'Subscribe';
+$lang['subscr_m_receive'] = 'Receive';
+$lang['subscr_style_every'] = 'email on every change';
+$lang['subscr_style_digest'] = 'digest email of changes for each page (every %.2f days)';
+$lang['subscr_style_list'] = 'list of changed pages since last email (every %.2f days)';
+
+/* auth.class language support */
+$lang['authtempfail'] = 'User authentication is temporarily unavailable. If this situation persists, please inform your Wiki Admin.';
+
+/* installer strings */
+$lang['i_chooselang'] = 'Choose your language';
+$lang['i_installer'] = 'DokuWiki Installer';
+$lang['i_wikiname'] = 'Wiki Name';
+$lang['i_enableacl'] = 'Enable ACL (recommended)';
+$lang['i_superuser'] = 'Superuser';
+$lang['i_problems'] = 'The installer found some problems, indicated below. You can not continue until you have fixed them.';
+$lang['i_modified'] = 'For security reasons this script will only work with a new and unmodified Dokuwiki installation.
+ You should either re-extract the files from the downloaded package or consult the complete
+ <a href="https://www.dokuwiki.org/install">Dokuwiki installation instructions</a>';
+$lang['i_funcna'] = 'PHP function <code>%s</code> is not available. Maybe your hosting provider disabled it for some reason?';
+$lang['i_disabled'] = 'It has been disabled by your provider.';
+$lang['i_funcnmail'] = '<b>Note:</b> The PHP mail function is not available. %s' .
+ ' If it remains unavailable, you may install the <a href="https://www.dokuwiki.org/plugin:smtp">smtp plugin</a>.';
+$lang['i_phpver'] = 'Your PHP version <code>%s</code> is lower than the needed <code>%s</code>. You need to upgrade your PHP install.';
+$lang['i_mbfuncoverload'] = 'mbstring.func_overload must be disabled in php.ini to run DokuWiki.';
+$lang['i_urandom'] = 'DokuWiki cannot create cryptographically secure numbers for cookies. You may want to check your open_basedir settings in php.ini for proper <code>/dev/urandom</code> access.';
+$lang['i_permfail'] = '<code>%s</code> is not writable by DokuWiki. You need to fix the permission settings of this directory!';
+$lang['i_confexists'] = '<code>%s</code> already exists';
+$lang['i_writeerr'] = 'Unable to create <code>%s</code>. You will need to check directory/file permissions and create the file manually.';
+$lang['i_badhash'] = 'unrecognised or modified dokuwiki.php (hash=<code>%s</code>)';
+$lang['i_badval'] = '<code>%s</code> - illegal or empty value';
+$lang['i_success'] = 'The configuration was finished successfully. You may delete the install.php file now. Continue to
+ <a href="doku.php?id=wiki:welcome">your new DokuWiki</a>.';
+$lang['i_failure'] = 'Some errors occurred while writing the configuration files. You may need to fix them manually before
+ you can use <a href="doku.php?id=wiki:welcome">your new DokuWiki</a>.';
+$lang['i_policy'] = 'Initial ACL policy';
+$lang['i_pol0'] = 'Open Wiki (read, write, upload for everyone)';
+$lang['i_pol1'] = 'Public Wiki (read for everyone, write and upload for registered users)';
+$lang['i_pol2'] = 'Closed Wiki (read, write, upload for registered users only)';
+$lang['i_allowreg'] = 'Allow users to register themselves';
+$lang['i_retry'] = 'Retry';
+$lang['i_license'] = 'Please choose the license you want to put your content under:';
+$lang['i_license_none'] = 'Do not show any license information';
+$lang['i_pop_field'] = 'Please, help us to improve the DokuWiki experience:';
+$lang['i_pop_label'] = 'Once a month, send anonymous usage data to the DokuWiki developers';
+
+$lang['recent_global'] = 'You\'re currently watching the changes inside the <b>%s</b> namespace. You can also <a href="%s">view the recent changes of the whole wiki</a>.';
+$lang['years'] = '%d years ago';
+$lang['months'] = '%d months ago';
+$lang['weeks'] = '%d weeks ago';
+$lang['days'] = '%d days ago';
+$lang['hours'] = '%d hours ago';
+$lang['minutes'] = '%d minutes ago';
+$lang['seconds'] = '%d seconds ago';
+
+$lang['wordblock'] = 'Your change was not saved because it contains blocked text (spam).';
+
+$lang['media_uploadtab'] = 'Upload';
+$lang['media_searchtab'] = 'Search';
+$lang['media_file'] = 'File';
+$lang['media_viewtab'] = 'View';
+$lang['media_edittab'] = 'Edit';
+$lang['media_historytab'] = 'History';
+$lang['media_list_thumbs'] = 'Thumbnails';
+$lang['media_list_rows'] = 'Rows';
+$lang['media_sort_name'] = 'Name';
+$lang['media_sort_date'] = 'Date';
+$lang['media_namespaces'] = 'Choose namespace';
+$lang['media_files'] = 'Files in %s';
+$lang['media_upload'] = 'Upload to %s';
+$lang['media_search'] = 'Search in %s';
+$lang['media_view'] = '%s';
+$lang['media_viewold'] = '%s at %s';
+$lang['media_edit'] = 'Edit %s';
+$lang['media_history'] = 'History of %s';
+$lang['media_meta_edited'] = 'metadata edited';
+$lang['media_perm_read'] = 'Sorry, you don\'t have enough rights to read files.';
+$lang['media_perm_upload'] = 'Sorry, you don\'t have enough rights to upload files.';
+$lang['media_update'] = 'Upload new version';
+$lang['media_restore'] = 'Restore this version';
+$lang['media_acl_warning'] = 'This list might not be complete due to ACL restrictions and hidden pages.';
+
+$lang['email_fail'] = 'PHP mail() missing or disabled. The following email was not sent: ';
+$lang['currentns'] = 'Current namespace';
+$lang['searchresult'] = 'Search Result';
+$lang['plainhtml'] = 'Plain HTML';
+$lang['wikimarkup'] = 'Wiki Markup';
+$lang['page_nonexist_rev'] = 'Page did not exist at %s. It was subsequently created at <a href="%s">%s</a>.';
+$lang['unable_to_parse_date'] = 'Unable to parse at parameter "%s".';
+$lang['email_signature_text'] = 'This mail was generated by DokuWiki at
+@DOKUWIKIURL@';
+#$lang['email_signature_html'] = ''; # the empty default will copy the text signature, you can override it in a local lang file
+
diff --git a/platform/www/inc/lang/en/locked.txt b/platform/www/inc/lang/en/locked.txt
new file mode 100644
index 0000000..af6347a
--- /dev/null
+++ b/platform/www/inc/lang/en/locked.txt
@@ -0,0 +1,3 @@
+====== Page locked ======
+
+This page is currently locked for editing by another user. You have to wait until this user finishes editing or the lock expires.
diff --git a/platform/www/inc/lang/en/login.txt b/platform/www/inc/lang/en/login.txt
new file mode 100644
index 0000000..151bf7f
--- /dev/null
+++ b/platform/www/inc/lang/en/login.txt
@@ -0,0 +1,3 @@
+====== Login ======
+
+You are currently not logged in! Enter your authentication credentials below to log in. You need to have cookies enabled to log in.
diff --git a/platform/www/inc/lang/en/mailtext.txt b/platform/www/inc/lang/en/mailtext.txt
new file mode 100644
index 0000000..eac4035
--- /dev/null
+++ b/platform/www/inc/lang/en/mailtext.txt
@@ -0,0 +1,15 @@
+A page in your DokuWiki was added or changed. Here are the details:
+
+Browser : @BROWSER@
+IP Address : @IPADDRESS@
+Hostname : @HOSTNAME@
+Old Revision : @OLDPAGE@
+New Revision : @NEWPAGE@
+Date of New Revision: @DATE@
+Edit Summary : @SUMMARY@
+User : @USER@
+
+There may be newer changes after this revision. If this
+happens, a message will be shown on the top of the rev page.
+
+@DIFF@
diff --git a/platform/www/inc/lang/en/mailwrap.html b/platform/www/inc/lang/en/mailwrap.html
new file mode 100644
index 0000000..7df0cdc
--- /dev/null
+++ b/platform/www/inc/lang/en/mailwrap.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+ <title>@TITLE@</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+</head>
+<body>
+
+@HTMLBODY@
+
+<br /><hr />
+<small>@EMAILSIGNATURE@</small>
+</body>
+</html>
diff --git a/platform/www/inc/lang/en/newpage.txt b/platform/www/inc/lang/en/newpage.txt
new file mode 100644
index 0000000..c9ae6e6
--- /dev/null
+++ b/platform/www/inc/lang/en/newpage.txt
@@ -0,0 +1,3 @@
+====== This topic does not exist yet ======
+
+You've followed a link to a topic that doesn't exist yet. If permissions allow, you may create it by clicking on **Create this page**.
diff --git a/platform/www/inc/lang/en/norev.txt b/platform/www/inc/lang/en/norev.txt
new file mode 100644
index 0000000..b24c792
--- /dev/null
+++ b/platform/www/inc/lang/en/norev.txt
@@ -0,0 +1,3 @@
+====== No such revision ======
+
+The specified revision doesn't exist. Click on "Old revisions" for a list of old revisions of this document.
diff --git a/platform/www/inc/lang/en/onceexisted.txt b/platform/www/inc/lang/en/onceexisted.txt
new file mode 100644
index 0000000..87cc057
--- /dev/null
+++ b/platform/www/inc/lang/en/onceexisted.txt
@@ -0,0 +1,3 @@
+======= This page does not exist anymore ======
+
+You've followed a link to a page that no longer exists. You can check the list of [[?do=revisions|old revisions]] to see when and why it was deleted, access old revisions or restore it. \ No newline at end of file
diff --git a/platform/www/inc/lang/en/password.txt b/platform/www/inc/lang/en/password.txt
new file mode 100644
index 0000000..0a0dfb5
--- /dev/null
+++ b/platform/www/inc/lang/en/password.txt
@@ -0,0 +1,6 @@
+Hi @FULLNAME@!
+
+Here is your userdata for @TITLE@ at @DOKUWIKIURL@
+
+Login : @LOGIN@
+Password : @PASSWORD@
diff --git a/platform/www/inc/lang/en/preview.txt b/platform/www/inc/lang/en/preview.txt
new file mode 100644
index 0000000..6727056
--- /dev/null
+++ b/platform/www/inc/lang/en/preview.txt
@@ -0,0 +1,3 @@
+====== Preview ======
+
+This is a preview of what your text will look like. **Remember: It is not saved yet**!
diff --git a/platform/www/inc/lang/en/pwconfirm.txt b/platform/www/inc/lang/en/pwconfirm.txt
new file mode 100644
index 0000000..44bdeb4
--- /dev/null
+++ b/platform/www/inc/lang/en/pwconfirm.txt
@@ -0,0 +1,9 @@
+Hi @FULLNAME@!
+
+Someone requested a new password for your @TITLE@ login at @DOKUWIKIURL@
+
+If you did not request a new password then just ignore this email.
+
+To confirm that the request was really sent by you please use the following link.
+
+@CONFIRM@
diff --git a/platform/www/inc/lang/en/read.txt b/platform/www/inc/lang/en/read.txt
new file mode 100644
index 0000000..6e2af13
--- /dev/null
+++ b/platform/www/inc/lang/en/read.txt
@@ -0,0 +1 @@
+This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong.
diff --git a/platform/www/inc/lang/en/recent.txt b/platform/www/inc/lang/en/recent.txt
new file mode 100644
index 0000000..0f9a7f6
--- /dev/null
+++ b/platform/www/inc/lang/en/recent.txt
@@ -0,0 +1,3 @@
+====== Recent Changes ======
+
+The following pages were changed recently:
diff --git a/platform/www/inc/lang/en/register.txt b/platform/www/inc/lang/en/register.txt
new file mode 100644
index 0000000..7778402
--- /dev/null
+++ b/platform/www/inc/lang/en/register.txt
@@ -0,0 +1,3 @@
+====== Register as new user ======
+
+Fill in all the information below to create a new account in this wiki. Make sure you supply a **valid e-mail address** - if you are not asked to enter a password here, a new one will be sent to that address. The login name should be a valid [[doku>pagename|pagename]].
diff --git a/platform/www/inc/lang/en/registermail.txt b/platform/www/inc/lang/en/registermail.txt
new file mode 100644
index 0000000..5517ca1
--- /dev/null
+++ b/platform/www/inc/lang/en/registermail.txt
@@ -0,0 +1,10 @@
+A new user has registered. Here are the details:
+
+User name : @NEWUSER@
+Full name : @NEWNAME@
+E-mail : @NEWEMAIL@
+
+Date : @DATE@
+Browser : @BROWSER@
+IP-Address : @IPADDRESS@
+Hostname : @HOSTNAME@
diff --git a/platform/www/inc/lang/en/resendpwd.txt b/platform/www/inc/lang/en/resendpwd.txt
new file mode 100644
index 0000000..2696fe4
--- /dev/null
+++ b/platform/www/inc/lang/en/resendpwd.txt
@@ -0,0 +1,3 @@
+====== Send new password ======
+
+Please enter your user name in the form below to request a new password for your account in this wiki. A confirmation link will be sent to your registered email address.
diff --git a/platform/www/inc/lang/en/resetpwd.txt b/platform/www/inc/lang/en/resetpwd.txt
new file mode 100644
index 0000000..5f59f0f
--- /dev/null
+++ b/platform/www/inc/lang/en/resetpwd.txt
@@ -0,0 +1,3 @@
+====== Set new password ======
+
+Please enter a new password for your account in this wiki.
diff --git a/platform/www/inc/lang/en/revisions.txt b/platform/www/inc/lang/en/revisions.txt
new file mode 100644
index 0000000..90b036a
--- /dev/null
+++ b/platform/www/inc/lang/en/revisions.txt
@@ -0,0 +1,3 @@
+====== Old Revisions ======
+
+These are the older revisons of the current document. To revert to an old revision, select it from below, click ''Edit this page'' and save it.
diff --git a/platform/www/inc/lang/en/searchpage.txt b/platform/www/inc/lang/en/searchpage.txt
new file mode 100644
index 0000000..0cd0160
--- /dev/null
+++ b/platform/www/inc/lang/en/searchpage.txt
@@ -0,0 +1,3 @@
+====== Search ======
+
+You can find the results of your search below. @CREATEPAGEINFO@
diff --git a/platform/www/inc/lang/en/showrev.txt b/platform/www/inc/lang/en/showrev.txt
new file mode 100644
index 0000000..3608de3
--- /dev/null
+++ b/platform/www/inc/lang/en/showrev.txt
@@ -0,0 +1,2 @@
+**This is an old revision of the document!**
+----
diff --git a/platform/www/inc/lang/en/stopwords.txt b/platform/www/inc/lang/en/stopwords.txt
new file mode 100644
index 0000000..afc3016
--- /dev/null
+++ b/platform/www/inc/lang/en/stopwords.txt
@@ -0,0 +1,39 @@
+# This is a list of words the indexer ignores, one word per line
+# When you edit this file be sure to use UNIX line endings (single newline)
+# No need to include words shorter than 3 chars - these are ignored anyway
+# This list is based upon the ones found at http://www.ranks.nl/stopwords/
+about
+are
+as
+an
+and
+you
+your
+them
+their
+com
+for
+from
+into
+if
+in
+is
+it
+how
+of
+on
+or
+that
+the
+this
+to
+was
+what
+when
+where
+who
+will
+with
+und
+the
+www
diff --git a/platform/www/inc/lang/en/subscr_digest.txt b/platform/www/inc/lang/en/subscr_digest.txt
new file mode 100644
index 0000000..cc42e08
--- /dev/null
+++ b/platform/www/inc/lang/en/subscr_digest.txt
@@ -0,0 +1,16 @@
+Hello!
+
+The page @PAGE@ in the @TITLE@ wiki changed.
+Here are the changes:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+Old Revision: @OLDPAGE@
+New Revision: @NEWPAGE@
+
+To cancel the page notifications, log into the wiki at
+@DOKUWIKIURL@ then visit
+@SUBSCRIBE@
+and unsubscribe page and/or namespace changes.
diff --git a/platform/www/inc/lang/en/subscr_form.txt b/platform/www/inc/lang/en/subscr_form.txt
new file mode 100644
index 0000000..d606508
--- /dev/null
+++ b/platform/www/inc/lang/en/subscr_form.txt
@@ -0,0 +1,3 @@
+====== Subscription Management ======
+
+This page allows you to manage your subscriptions for the current page and namespace.
diff --git a/platform/www/inc/lang/en/subscr_list.txt b/platform/www/inc/lang/en/subscr_list.txt
new file mode 100644
index 0000000..dcf8000
--- /dev/null
+++ b/platform/www/inc/lang/en/subscr_list.txt
@@ -0,0 +1,13 @@
+Hello!
+
+Pages in the namespace @PAGE@ of the @TITLE@ wiki changed.
+Here are the changed pages:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+To cancel the page notifications, log into the wiki at
+@DOKUWIKIURL@ then visit
+@SUBSCRIBE@
+and unsubscribe page and/or namespace changes.
diff --git a/platform/www/inc/lang/en/subscr_single.txt b/platform/www/inc/lang/en/subscr_single.txt
new file mode 100644
index 0000000..046b994
--- /dev/null
+++ b/platform/www/inc/lang/en/subscr_single.txt
@@ -0,0 +1,19 @@
+Hello!
+
+The page @PAGE@ in the @TITLE@ wiki changed.
+Here are the changes:
+
+--------------------------------------------------------
+@DIFF@
+--------------------------------------------------------
+
+User : @USER@
+Edit Summary : @SUMMARY@
+Old Revision : @OLDPAGE@
+New Revision : @NEWPAGE@
+Date of New Revision: @DATE@
+
+To cancel the page notifications, log into the wiki at
+@DOKUWIKIURL@ then visit
+@SUBSCRIBE@
+and unsubscribe page and/or namespace changes.
diff --git a/platform/www/inc/lang/en/updateprofile.txt b/platform/www/inc/lang/en/updateprofile.txt
new file mode 100644
index 0000000..73e53aa
--- /dev/null
+++ b/platform/www/inc/lang/en/updateprofile.txt
@@ -0,0 +1,3 @@
+====== Update your account profile ======
+
+You only need to complete those fields you wish to change. You may not change your user name.
diff --git a/platform/www/inc/lang/en/uploadmail.txt b/platform/www/inc/lang/en/uploadmail.txt
new file mode 100644
index 0000000..dca8e33
--- /dev/null
+++ b/platform/www/inc/lang/en/uploadmail.txt
@@ -0,0 +1,11 @@
+A file was uploaded to your DokuWiki. Here are the details:
+
+File : @MEDIA@
+Old revision: @OLD@
+Date : @DATE@
+Browser : @BROWSER@
+IP-Address : @IPADDRESS@
+Hostname : @HOSTNAME@
+Size : @SIZE@
+MIME Type : @MIME@
+User : @USER@
diff --git a/platform/www/inc/legacy.php b/platform/www/inc/legacy.php
new file mode 100644
index 0000000..fa72649
--- /dev/null
+++ b/platform/www/inc/legacy.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * We map legacy class names to the new namespaced versions here
+ *
+ * These are names that we will probably never change because they have been part of DokuWiki's
+ * public interface for years and renaming would break just too many plugins
+ */
+
+class_alias('\dokuwiki\Extension\EventHandler', 'Doku_Event_Handler');
+class_alias('\dokuwiki\Extension\Event', 'Doku_Event');
+
+class_alias('\dokuwiki\Extension\ActionPlugin', 'DokuWiki_Action_Plugin');
+class_alias('\dokuwiki\Extension\AdminPlugin', 'DokuWiki_Admin_Plugin');
+class_alias('\dokuwiki\Extension\AuthPlugin', 'DokuWiki_Auth_Plugin');
+class_alias('\dokuwiki\Extension\CLIPlugin', 'DokuWiki_CLI_Plugin');
+class_alias('\dokuwiki\Extension\Plugin', 'DokuWiki_Plugin');
+class_alias('\dokuwiki\Extension\RemotePlugin', 'DokuWiki_Remote_Plugin');
+class_alias('\dokuwiki\Extension\SyntaxPlugin', 'DokuWiki_Syntax_Plugin');
diff --git a/platform/www/inc/load.php b/platform/www/inc/load.php
new file mode 100644
index 0000000..46cd91f
--- /dev/null
+++ b/platform/www/inc/load.php
@@ -0,0 +1,153 @@
+<?php
+/**
+ * Load all internal libraries and setup class autoloader
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Extension\PluginController;
+
+// setup class autoloader
+spl_autoload_register('load_autoload');
+
+// require all the common libraries
+// for a few of these order does matter
+require_once(DOKU_INC.'inc/defines.php');
+require_once(DOKU_INC.'inc/actions.php');
+require_once(DOKU_INC.'inc/changelog.php');
+require_once(DOKU_INC.'inc/common.php');
+require_once(DOKU_INC.'inc/confutils.php');
+require_once(DOKU_INC.'inc/pluginutils.php');
+require_once(DOKU_INC.'inc/form.php');
+require_once(DOKU_INC.'inc/fulltext.php');
+require_once(DOKU_INC.'inc/html.php');
+require_once(DOKU_INC.'inc/httputils.php');
+require_once(DOKU_INC.'inc/indexer.php');
+require_once(DOKU_INC.'inc/infoutils.php');
+require_once(DOKU_INC.'inc/io.php');
+require_once(DOKU_INC.'inc/mail.php');
+require_once(DOKU_INC.'inc/media.php');
+require_once(DOKU_INC.'inc/pageutils.php');
+require_once(DOKU_INC.'inc/parserutils.php');
+require_once(DOKU_INC.'inc/search.php');
+require_once(DOKU_INC.'inc/template.php');
+require_once(DOKU_INC.'inc/toolbar.php');
+require_once(DOKU_INC.'inc/utf8.php');
+require_once(DOKU_INC.'inc/auth.php');
+require_once(DOKU_INC.'inc/compatibility.php');
+require_once(DOKU_INC.'inc/deprecated.php');
+require_once(DOKU_INC.'inc/legacy.php');
+
+/**
+ * spl_autoload_register callback
+ *
+ * Contains a static list of DokuWiki's core classes and automatically
+ * require()s their associated php files when an object is instantiated.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @todo add generic loading of renderers and auth backends
+ *
+ * @param string $name
+ *
+ * @return bool
+ */
+function load_autoload($name){
+ static $classes = null;
+ if($classes === null) $classes = array(
+ 'Diff' => DOKU_INC.'inc/DifferenceEngine.php',
+ 'UnifiedDiffFormatter' => DOKU_INC.'inc/DifferenceEngine.php',
+ 'TableDiffFormatter' => DOKU_INC.'inc/DifferenceEngine.php',
+ 'cache' => DOKU_INC.'inc/cache.php',
+ 'cache_parser' => DOKU_INC.'inc/cache.php',
+ 'cache_instructions' => DOKU_INC.'inc/cache.php',
+ 'cache_renderer' => DOKU_INC.'inc/cache.php',
+ 'Input' => DOKU_INC.'inc/Input.class.php',
+ 'JpegMeta' => DOKU_INC.'inc/JpegMeta.php',
+ 'SimplePie' => DOKU_INC.'inc/SimplePie.php',
+ 'FeedParser' => DOKU_INC.'inc/FeedParser.php',
+ 'IXR_Server' => DOKU_INC.'inc/IXR_Library.php',
+ 'IXR_Client' => DOKU_INC.'inc/IXR_Library.php',
+ 'IXR_Error' => DOKU_INC.'inc/IXR_Library.php',
+ 'IXR_IntrospectionServer' => DOKU_INC.'inc/IXR_Library.php',
+ 'SafeFN' => DOKU_INC.'inc/SafeFN.class.php',
+ 'Sitemapper' => DOKU_INC.'inc/Sitemapper.php',
+ 'Mailer' => DOKU_INC.'inc/Mailer.class.php',
+
+ 'Doku_Handler' => DOKU_INC.'inc/parser/handler.php',
+ 'Doku_Renderer' => DOKU_INC.'inc/parser/renderer.php',
+ 'Doku_Renderer_xhtml' => DOKU_INC.'inc/parser/xhtml.php',
+ 'Doku_Renderer_code' => DOKU_INC.'inc/parser/code.php',
+ 'Doku_Renderer_xhtmlsummary' => DOKU_INC.'inc/parser/xhtmlsummary.php',
+ 'Doku_Renderer_metadata' => DOKU_INC.'inc/parser/metadata.php',
+
+ 'DokuCLI' => DOKU_INC.'inc/cli.php',
+ 'DokuCLI_Options' => DOKU_INC.'inc/cli.php',
+ 'DokuCLI_Colors' => DOKU_INC.'inc/cli.php',
+
+ );
+
+ if(isset($classes[$name])){
+ require ($classes[$name]);
+ return true;
+ }
+
+ // namespace to directory conversion
+ $name = str_replace('\\', '/', $name);
+
+ // test namespace
+ if(substr($name, 0, 14) === 'dokuwiki/test/') {
+ $file = DOKU_INC . '_test/' . substr($name, 14) . '.php';
+ if(file_exists($file)) {
+ require $file;
+ return true;
+ }
+ }
+
+ // plugin namespace
+ if(substr($name, 0, 16) === 'dokuwiki/plugin/') {
+ $name = str_replace('/test/', '/_test/', $name); // no underscore in test namespace
+ $file = DOKU_PLUGIN . substr($name, 16) . '.php';
+ if(file_exists($file)) {
+ require $file;
+ return true;
+ }
+ }
+
+ // template namespace
+ if(substr($name, 0, 18) === 'dokuwiki/template/') {
+ $name = str_replace('/test/', '/_test/', $name); // no underscore in test namespace
+ $file = DOKU_INC.'lib/tpl/' . substr($name, 18) . '.php';
+ if(file_exists($file)) {
+ require $file;
+ return true;
+ }
+ }
+
+ // our own namespace
+ if(substr($name, 0, 9) === 'dokuwiki/') {
+ $file = DOKU_INC . 'inc/' . substr($name, 9) . '.php';
+ if(file_exists($file)) {
+ require $file;
+ return true;
+ }
+ }
+
+ // Plugin loading
+ if(preg_match(
+ '/^(' . implode('|', PluginController::PLUGIN_TYPES) . ')_plugin_(' .
+ DOKU_PLUGIN_NAME_REGEX .
+ ')(?:_([^_]+))?$/',
+ $name,
+ $m
+ )) {
+ // try to load the wanted plugin file
+ $c = ((count($m) === 4) ? "/{$m[3]}" : '');
+ $plg = DOKU_PLUGIN . "{$m[2]}/{$m[1]}$c.php";
+ if(file_exists($plg)){
+ require $plg;
+ }
+ return true;
+ }
+ return false;
+}
+
diff --git a/platform/www/inc/mail.php b/platform/www/inc/mail.php
new file mode 100644
index 0000000..ef4f440
--- /dev/null
+++ b/platform/www/inc/mail.php
@@ -0,0 +1,166 @@
+<?php
+/**
+ * Mail functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// end of line for mail lines - RFC822 says CRLF but postfix (and other MTAs?)
+// think different
+if(!defined('MAILHEADER_EOL')) define('MAILHEADER_EOL',"\n");
+#define('MAILHEADER_ASCIIONLY',1);
+
+/**
+ * Patterns for use in email detection and validation
+ *
+ * NOTE: there is an unquoted '/' in RFC2822_ATEXT, it must remain unquoted to be used in the parser
+ * the pattern uses non-capturing groups as captured groups aren't allowed in the parser
+ * select pattern delimiters with care!
+ *
+ * May not be completly RFC conform!
+ * @link http://www.faqs.org/rfcs/rfc2822.html (paras 3.4.1 & 3.2.4)
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * Check if a given mail address is valid
+ */
+if (!defined('RFC2822_ATEXT')) define('RFC2822_ATEXT',"0-9a-zA-Z!#$%&'*+/=?^_`{|}~-");
+if (!defined('PREG_PATTERN_VALID_EMAIL')) define(
+ 'PREG_PATTERN_VALID_EMAIL',
+ '['.RFC2822_ATEXT.']+(?:\.['.RFC2822_ATEXT.']+)*@(?i:[0-9a-z][0-9a-z-]*\.)+(?i:[a-z]{2,63})'
+);
+
+/**
+ * Prepare mailfrom replacement patterns
+ *
+ * Also prepares a mailfromnobody config that contains an autoconstructed address
+ * if the mailfrom one is userdependent and this might not be wanted (subscriptions)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function mail_setup(){
+ global $conf;
+ global $USERINFO;
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ // auto constructed address
+ $host = @parse_url(DOKU_URL,PHP_URL_HOST);
+ if(!$host) $host = 'example.com';
+ $noreply = 'noreply@'.$host;
+
+ $replace = array();
+ if(!empty($USERINFO['mail'])){
+ $replace['@MAIL@'] = $USERINFO['mail'];
+ }else{
+ $replace['@MAIL@'] = $noreply;
+ }
+
+ // use 'noreply' if no user
+ $replace['@USER@'] = $INPUT->server->str('REMOTE_USER', 'noreply', true);
+
+ if(!empty($USERINFO['name'])){
+ $replace['@NAME@'] = $USERINFO['name'];
+ }else{
+ $replace['@NAME@'] = '';
+ }
+
+ // apply replacements
+ $from = str_replace(array_keys($replace),
+ array_values($replace),
+ $conf['mailfrom']);
+
+ // any replacements done? set different mailfromnone
+ if($from != $conf['mailfrom']){
+ $conf['mailfromnobody'] = $noreply;
+ }else{
+ $conf['mailfromnobody'] = $from;
+ }
+ $conf['mailfrom'] = $from;
+}
+
+/**
+ * Check if a given mail address is valid
+ *
+ * @param string $email the address to check
+ * @return bool true if address is valid
+ */
+function mail_isvalid($email) {
+ return EmailAddressValidator::checkEmailAddress($email, true);
+}
+
+/**
+ * Quoted printable encoding
+ *
+ * @author umu <umuAThrz.tu-chemnitz.de>
+ * @link http://php.net/manual/en/function.imap-8bit.php#61216
+ *
+ * @param string $sText
+ * @param int $maxlen
+ * @param bool $bEmulate_imap_8bit
+ *
+ * @return string
+ */
+function mail_quotedprintable_encode($sText,$maxlen=74,$bEmulate_imap_8bit=true) {
+ // split text into lines
+ $aLines= preg_split("/(?:\r\n|\r|\n)/", $sText);
+ $cnt = count($aLines);
+
+ for ($i=0;$i<$cnt;$i++) {
+ $sLine =& $aLines[$i];
+ if (strlen($sLine)===0) continue; // do nothing, if empty
+
+ $sRegExp = '/[^\x09\x20\x21-\x3C\x3E-\x7E]/e';
+
+ // imap_8bit encodes x09 everywhere, not only at lineends,
+ // for EBCDIC safeness encode !"#$@[\]^`{|}~,
+ // for complete safeness encode every character :)
+ if ($bEmulate_imap_8bit)
+ $sRegExp = '/[^\x20\x21-\x3C\x3E-\x7E]/';
+
+ $sLine = preg_replace_callback( $sRegExp, 'mail_quotedprintable_encode_callback', $sLine );
+
+ // encode x09,x20 at lineends
+ {
+ $iLength = strlen($sLine);
+ $iLastChar = ord($sLine[$iLength-1]);
+
+ // !!!!!!!!
+ // imap_8_bit does not encode x20 at the very end of a text,
+ // here is, where I don't agree with imap_8_bit,
+ // please correct me, if I'm wrong,
+ // or comment next line for RFC2045 conformance, if you like
+ if (!($bEmulate_imap_8bit && ($i==count($aLines)-1))){
+ if (($iLastChar==0x09)||($iLastChar==0x20)) {
+ $sLine[$iLength-1]='=';
+ $sLine .= ($iLastChar==0x09)?'09':'20';
+ }
+ }
+ } // imap_8bit encodes x20 before chr(13), too
+ // although IMHO not requested by RFC2045, why not do it safer :)
+ // and why not encode any x20 around chr(10) or chr(13)
+ if ($bEmulate_imap_8bit) {
+ $sLine=str_replace(' =0D','=20=0D',$sLine);
+ //$sLine=str_replace(' =0A','=20=0A',$sLine);
+ //$sLine=str_replace('=0D ','=0D=20',$sLine);
+ //$sLine=str_replace('=0A ','=0A=20',$sLine);
+ }
+
+ // finally split into softlines no longer than $maxlen chars,
+ // for even more safeness one could encode x09,x20
+ // at the very first character of the line
+ // and after soft linebreaks, as well,
+ // but this wouldn't be caught by such an easy RegExp
+ if($maxlen){
+ preg_match_all( '/.{1,'.($maxlen - 2).'}([^=]{0,2})?/', $sLine, $aMatch );
+ $sLine = implode( '=' . MAILHEADER_EOL, $aMatch[0] ); // add soft crlf's
+ }
+ }
+
+ // join lines into text
+ return implode(MAILHEADER_EOL,$aLines);
+}
+
+function mail_quotedprintable_encode_callback($matches){
+ return sprintf( "=%02X", ord ( $matches[0] ) ) ;
+}
diff --git a/platform/www/inc/media.php b/platform/www/inc/media.php
new file mode 100644
index 0000000..3cdefcc
--- /dev/null
+++ b/platform/www/inc/media.php
@@ -0,0 +1,2541 @@
+<?php
+/**
+ * All output and handler function needed for the media management popup
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\ChangeLog\MediaChangeLog;
+use dokuwiki\HTTP\DokuHTTPClient;
+use dokuwiki\Subscriptions\MediaSubscriptionSender;
+use dokuwiki\Extension\Event;
+
+/**
+ * Lists pages which currently use a media file selected for deletion
+ *
+ * References uses the same visual as search results and share
+ * their CSS tags except pagenames won't be links.
+ *
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ *
+ * @param array $data
+ * @param string $id
+ */
+function media_filesinuse($data,$id){
+ global $lang;
+ echo '<h1>'.$lang['reference'].' <code>'.hsc(noNS($id)).'</code></h1>';
+ echo '<p>'.hsc($lang['ref_inuse']).'</p>';
+
+ $hidden=0; //count of hits without read permission
+ foreach($data as $row){
+ if(auth_quickaclcheck($row) >= AUTH_READ && isVisiblePage($row)){
+ echo '<div class="search_result">';
+ echo '<span class="mediaref_ref">'.hsc($row).'</span>';
+ echo '</div>';
+ }else
+ $hidden++;
+ }
+ if ($hidden){
+ print '<div class="mediaref_hidden">'.$lang['ref_hidden'].'</div>';
+ }
+}
+
+/**
+ * Handles the saving of image meta data
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $id media id
+ * @param int $auth permission level
+ * @param array $data
+ * @return false|string
+ */
+function media_metasave($id,$auth,$data){
+ if($auth < AUTH_UPLOAD) return false;
+ if(!checkSecurityToken()) return false;
+ global $lang;
+ global $conf;
+ $src = mediaFN($id);
+
+ $meta = new JpegMeta($src);
+ $meta->_parseAll();
+
+ foreach($data as $key => $val){
+ $val=trim($val);
+ if(empty($val)){
+ $meta->deleteField($key);
+ }else{
+ $meta->setField($key,$val);
+ }
+ }
+
+ $old = @filemtime($src);
+ if(!file_exists(mediaFN($id, $old)) && file_exists($src)) {
+ // add old revision to the attic
+ media_saveOldRevision($id);
+ }
+ $filesize_old = filesize($src);
+ if($meta->save()){
+ if($conf['fperm']) chmod($src, $conf['fperm']);
+ @clearstatcache(true, $src);
+ $new = @filemtime($src);
+ $filesize_new = filesize($src);
+ $sizechange = $filesize_new - $filesize_old;
+
+ // add a log entry to the media changelog
+ addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, $lang['media_meta_edited'], '', null, $sizechange);
+
+ msg($lang['metasaveok'],1);
+ return $id;
+ }else{
+ msg($lang['metasaveerr'],-1);
+ return false;
+ }
+}
+
+/**
+ * check if a media is external source
+ *
+ * @author Gerrit Uitslag <klapinklapin@gmail.com>
+ *
+ * @param string $id the media ID or URL
+ * @return bool
+ */
+function media_isexternal($id){
+ if (preg_match('#^(?:https?|ftp)://#i', $id)) return true;
+ return false;
+}
+
+/**
+ * Check if a media item is public (eg, external URL or readable by @ALL)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id the media ID or URL
+ * @return bool
+ */
+function media_ispublic($id){
+ if(media_isexternal($id)) return true;
+ $id = cleanID($id);
+ if(auth_aclcheck(getNS($id).':*', '', array()) >= AUTH_READ) return true;
+ return false;
+}
+
+/**
+ * Display the form to edit image meta data
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $id media id
+ * @param int $auth permission level
+ * @return bool
+ */
+function media_metaform($id,$auth){
+ global $lang;
+
+ if($auth < AUTH_UPLOAD) {
+ echo '<div class="nothing">'.$lang['media_perm_upload'].'</div>'.NL;
+ return false;
+ }
+
+ // load the field descriptions
+ static $fields = null;
+ if(is_null($fields)){
+ $config_files = getConfigFiles('mediameta');
+ foreach ($config_files as $config_file) {
+ if(file_exists($config_file)) include($config_file);
+ }
+ }
+
+ $src = mediaFN($id);
+
+ // output
+ $form = new Doku_Form(array('action' => media_managerURL(array('tab_details' => 'view'), '&'),
+ 'class' => 'meta'));
+ $form->addHidden('img', $id);
+ $form->addHidden('mediado', 'save');
+ foreach($fields as $key => $field){
+ // get current value
+ if (empty($field[0])) continue;
+ $tags = array($field[0]);
+ if(is_array($field[3])) $tags = array_merge($tags,$field[3]);
+ $value = tpl_img_getTag($tags,'',$src);
+ $value = cleanText($value);
+
+ // prepare attributes
+ $p = array();
+ $p['class'] = 'edit';
+ $p['id'] = 'meta__'.$key;
+ $p['name'] = 'meta['.$field[0].']';
+ $p_attrs = array('class' => 'edit');
+
+ $form->addElement('<div class="row">');
+ if($field[2] == 'text'){
+ $form->addElement(
+ form_makeField(
+ 'text',
+ $p['name'],
+ $value,
+ ($lang[$field[1]]) ? $lang[$field[1]] : $field[1] . ':',
+ $p['id'],
+ $p['class'],
+ $p_attrs
+ )
+ );
+ }else{
+ $att = buildAttributes($p);
+ $form->addElement('<label for="meta__'.$key.'">'.$lang[$field[1]].'</label>');
+ $form->addElement("<textarea $att rows=\"6\" cols=\"50\">".formText($value).'</textarea>');
+ }
+ $form->addElement('</div>'.NL);
+ }
+ $form->addElement('<div class="buttons">');
+ $form->addElement(
+ form_makeButton(
+ 'submit',
+ '',
+ $lang['btn_save'],
+ array('accesskey' => 's', 'name' => 'mediado[save]')
+ )
+ );
+ $form->addElement('</div>'.NL);
+ $form->printForm();
+
+ return true;
+}
+
+/**
+ * Convenience function to check if a media file is still in use
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param string $id media id
+ * @return array|bool
+ */
+function media_inuse($id) {
+ global $conf;
+
+ if($conf['refcheck']){
+ $mediareferences = ft_mediause($id,true);
+ if(!count($mediareferences)) {
+ return false;
+ } else {
+ return $mediareferences;
+ }
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Handles media file deletions
+ *
+ * If configured, checks for media references before deletion
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id media id
+ * @param int $auth no longer used
+ * @return int One of: 0,
+ * DOKU_MEDIA_DELETED,
+ * DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS,
+ * DOKU_MEDIA_NOT_AUTH,
+ * DOKU_MEDIA_INUSE
+ */
+function media_delete($id,$auth){
+ global $lang;
+ $auth = auth_quickaclcheck(ltrim(getNS($id).':*', ':'));
+ if($auth < AUTH_DELETE) return DOKU_MEDIA_NOT_AUTH;
+ if(media_inuse($id)) return DOKU_MEDIA_INUSE;
+
+ $file = mediaFN($id);
+
+ // trigger an event - MEDIA_DELETE_FILE
+ $data = array();
+ $data['id'] = $id;
+ $data['name'] = \dokuwiki\Utf8\PhpString::basename($file);
+ $data['path'] = $file;
+ $data['size'] = (file_exists($file)) ? filesize($file) : 0;
+
+ $data['unl'] = false;
+ $data['del'] = false;
+ $evt = new Event('MEDIA_DELETE_FILE',$data);
+ if ($evt->advise_before()) {
+ $old = @filemtime($file);
+ if(!file_exists(mediaFN($id, $old)) && file_exists($file)) {
+ // add old revision to the attic
+ media_saveOldRevision($id);
+ }
+
+ $data['unl'] = @unlink($file);
+ if($data['unl']) {
+ $sizechange = 0 - $data['size'];
+ addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE, $lang['deleted'], '', null, $sizechange);
+
+ $data['del'] = io_sweepNS($id, 'mediadir');
+ }
+ }
+ $evt->advise_after();
+ unset($evt);
+
+ if($data['unl'] && $data['del']){
+ return DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS;
+ }
+
+ return $data['unl'] ? DOKU_MEDIA_DELETED : 0;
+}
+
+/**
+ * Handle file uploads via XMLHttpRequest
+ *
+ * @param string $ns target namespace
+ * @param int $auth current auth check result
+ * @return false|string false on error, id of the new file on success
+ */
+function media_upload_xhr($ns,$auth){
+ if(!checkSecurityToken()) return false;
+ global $INPUT;
+
+ $id = $INPUT->get->str('qqfile');
+ list($ext,$mime) = mimetype($id);
+ $input = fopen("php://input", "r");
+ if (!($tmp = io_mktmpdir())) return false;
+ $path = $tmp.'/'.md5($id);
+ $target = fopen($path, "w");
+ $realSize = stream_copy_to_stream($input, $target);
+ fclose($target);
+ fclose($input);
+ if (isset($_SERVER["CONTENT_LENGTH"]) && ($realSize != (int)$_SERVER["CONTENT_LENGTH"])){
+ unlink($path);
+ return false;
+ }
+
+ $res = media_save(
+ array('name' => $path,
+ 'mime' => $mime,
+ 'ext' => $ext),
+ $ns.':'.$id,
+ (($INPUT->get->str('ow') == 'true') ? true : false),
+ $auth,
+ 'copy'
+ );
+ unlink($path);
+ if ($tmp) io_rmdir($tmp, true);
+ if (is_array($res)) {
+ msg($res[0], $res[1]);
+ return false;
+ }
+ return $res;
+}
+
+/**
+ * Handles media file uploads
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param string $ns target namespace
+ * @param int $auth current auth check result
+ * @param bool|array $file $_FILES member, $_FILES['upload'] if false
+ * @return false|string false on error, id of the new file on success
+ */
+function media_upload($ns,$auth,$file=false){
+ if(!checkSecurityToken()) return false;
+ global $lang;
+ global $INPUT;
+
+ // get file and id
+ $id = $INPUT->post->str('mediaid');
+ if (!$file) $file = $_FILES['upload'];
+ if(empty($id)) $id = $file['name'];
+
+ // check for errors (messages are done in lib/exe/mediamanager.php)
+ if($file['error']) return false;
+
+ // check extensions
+ list($fext,$fmime) = mimetype($file['name']);
+ list($iext,$imime) = mimetype($id);
+ if($fext && !$iext){
+ // no extension specified in id - read original one
+ $id .= '.'.$fext;
+ $imime = $fmime;
+ }elseif($fext && $fext != $iext){
+ // extension was changed, print warning
+ msg(sprintf($lang['mediaextchange'],$fext,$iext));
+ }
+
+ $res = media_save(array('name' => $file['tmp_name'],
+ 'mime' => $imime,
+ 'ext' => $iext), $ns.':'.$id,
+ $INPUT->post->bool('ow'), $auth, 'copy_uploaded_file');
+ if (is_array($res)) {
+ msg($res[0], $res[1]);
+ return false;
+ }
+ return $res;
+}
+
+/**
+ * An alternative to move_uploaded_file that copies
+ *
+ * Using copy, makes sure any setgid bits on the media directory are honored
+ *
+ * @see move_uploaded_file()
+ *
+ * @param string $from
+ * @param string $to
+ * @return bool
+ */
+function copy_uploaded_file($from, $to){
+ if(!is_uploaded_file($from)) return false;
+ $ok = copy($from, $to);
+ @unlink($from);
+ return $ok;
+}
+
+/**
+ * This generates an action event and delegates to _media_upload_action().
+ * Action plugins are allowed to pre/postprocess the uploaded file.
+ * (The triggered event is preventable.)
+ *
+ * Event data:
+ * $data[0] fn_tmp: the temporary file name (read from $_FILES)
+ * $data[1] fn: the file name of the uploaded file
+ * $data[2] id: the future directory id of the uploaded file
+ * $data[3] imime: the mimetype of the uploaded file
+ * $data[4] overwrite: if an existing file is going to be overwritten
+ * $data[5] move: name of function that performs move/copy/..
+ *
+ * @triggers MEDIA_UPLOAD_FINISH
+ *
+ * @param array $file
+ * @param string $id media id
+ * @param bool $ow overwrite?
+ * @param int $auth permission level
+ * @param string $move name of functions that performs move/copy/..
+ * @return false|array|string
+ */
+function media_save($file, $id, $ow, $auth, $move) {
+ if($auth < AUTH_UPLOAD) {
+ return array("You don't have permissions to upload files.", -1);
+ }
+
+ if (!isset($file['mime']) || !isset($file['ext'])) {
+ list($ext, $mime) = mimetype($id);
+ if (!isset($file['mime'])) {
+ $file['mime'] = $mime;
+ }
+ if (!isset($file['ext'])) {
+ $file['ext'] = $ext;
+ }
+ }
+
+ global $lang, $conf;
+
+ // get filename
+ $id = cleanID($id);
+ $fn = mediaFN($id);
+
+ // get filetype regexp
+ $types = array_keys(getMimeTypes());
+ $types = array_map(
+ function ($q) {
+ return preg_quote($q, "/");
+ },
+ $types
+ );
+ $regex = join('|',$types);
+
+ // because a temp file was created already
+ if(!preg_match('/\.('.$regex.')$/i',$fn)) {
+ return array($lang['uploadwrong'],-1);
+ }
+
+ //check for overwrite
+ $overwrite = file_exists($fn);
+ $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE);
+ if($overwrite && (!$ow || $auth < $auth_ow)) {
+ return array($lang['uploadexist'], 0);
+ }
+ // check for valid content
+ $ok = media_contentcheck($file['name'], $file['mime']);
+ if($ok == -1){
+ return array(sprintf($lang['uploadbadcontent'],'.' . $file['ext']),-1);
+ }elseif($ok == -2){
+ return array($lang['uploadspam'],-1);
+ }elseif($ok == -3){
+ return array($lang['uploadxss'],-1);
+ }
+
+ // prepare event data
+ $data = array();
+ $data[0] = $file['name'];
+ $data[1] = $fn;
+ $data[2] = $id;
+ $data[3] = $file['mime'];
+ $data[4] = $overwrite;
+ $data[5] = $move;
+
+ // trigger event
+ return Event::createAndTrigger('MEDIA_UPLOAD_FINISH', $data, '_media_upload_action', true);
+}
+
+/**
+ * Callback adapter for media_upload_finish() triggered by MEDIA_UPLOAD_FINISH
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param array $data event data
+ * @return false|array|string
+ */
+function _media_upload_action($data) {
+ // fixme do further sanity tests of given data?
+ if(is_array($data) && count($data)===6) {
+ return media_upload_finish($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]);
+ } else {
+ return false; //callback error
+ }
+}
+
+/**
+ * Saves an uploaded media file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $fn_tmp
+ * @param string $fn
+ * @param string $id media id
+ * @param string $imime mime type
+ * @param bool $overwrite overwrite existing?
+ * @param string $move function name
+ * @return array|string
+ */
+function media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite, $move = 'move_uploaded_file') {
+ global $conf;
+ global $lang;
+ global $REV;
+
+ $old = @filemtime($fn);
+ if(!file_exists(mediaFN($id, $old)) && file_exists($fn)) {
+ // add old revision to the attic if missing
+ media_saveOldRevision($id);
+ }
+
+ // prepare directory
+ io_createNamespace($id, 'media');
+
+ $filesize_old = file_exists($fn) ? filesize($fn) : 0;
+
+ if($move($fn_tmp, $fn)) {
+ @clearstatcache(true,$fn);
+ $new = @filemtime($fn);
+ // Set the correct permission here.
+ // Always chmod media because they may be saved with different permissions than expected from the php umask.
+ // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.)
+ chmod($fn, $conf['fmode']);
+ msg($lang['uploadsucc'],1);
+ media_notify($id,$fn,$imime,$old,$new);
+ // add a log entry to the media changelog
+ $filesize_new = filesize($fn);
+ $sizechange = $filesize_new - $filesize_old;
+ if($REV) {
+ addMediaLogEntry(
+ $new,
+ $id,
+ DOKU_CHANGE_TYPE_REVERT,
+ sprintf($lang['restored'], dformat($REV)),
+ $REV,
+ null,
+ $sizechange
+ );
+ } elseif($overwrite) {
+ addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange);
+ } else {
+ addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange);
+ }
+ return $id;
+ }else{
+ return array($lang['uploadfail'],-1);
+ }
+}
+
+/**
+ * Moves the current version of media file to the media_attic
+ * directory
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $id
+ * @return int - revision date
+ */
+function media_saveOldRevision($id){
+ global $conf, $lang;
+
+ $oldf = mediaFN($id);
+ if(!file_exists($oldf)) return '';
+ $date = filemtime($oldf);
+ if (!$conf['mediarevisions']) return $date;
+
+ $medialog = new MediaChangeLog($id);
+ if (!$medialog->getRevisionInfo($date)) {
+ // there was an external edit,
+ // there is no log entry for current version of file
+ $sizechange = filesize($oldf);
+ if(!file_exists(mediaMetaFN($id, '.changes'))) {
+ addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange);
+ } else {
+ $oldRev = $medialog->getRevisions(-1, 1); // from changelog
+ $oldRev = (int) (empty($oldRev) ? 0 : $oldRev[0]);
+ $filesize_old = filesize(mediaFN($id, $oldRev));
+ $sizechange = $sizechange - $filesize_old;
+
+ addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange);
+ }
+ }
+
+ $newf = mediaFN($id,$date);
+ io_makeFileDir($newf);
+ if(copy($oldf, $newf)) {
+ // Set the correct permission here.
+ // Always chmod media because they may be saved with different permissions than expected from the php umask.
+ // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.)
+ chmod($newf, $conf['fmode']);
+ }
+ return $date;
+}
+
+/**
+ * This function checks if the uploaded content is really what the
+ * mimetype says it is. We also do spam checking for text types here.
+ *
+ * We need to do this stuff because we can not rely on the browser
+ * to do this check correctly. Yes, IE is broken as usual.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @link http://www.splitbrain.org/blog/2007-02/12-internet_explorer_facilitates_cross_site_scripting
+ * @fixme check all 26 magic IE filetypes here?
+ *
+ * @param string $file path to file
+ * @param string $mime mimetype
+ * @return int
+ */
+function media_contentcheck($file,$mime){
+ global $conf;
+ if($conf['iexssprotect']){
+ $fh = @fopen($file, 'rb');
+ if($fh){
+ $bytes = fread($fh, 256);
+ fclose($fh);
+ if(preg_match('/<(script|a|img|html|body|iframe)[\s>]/i',$bytes)){
+ return -3; //XSS: possibly malicious content
+ }
+ }
+ }
+ if(substr($mime,0,6) == 'image/'){
+ $info = @getimagesize($file);
+ if($mime == 'image/gif' && $info[2] != 1){
+ return -1; // uploaded content did not match the file extension
+ }elseif($mime == 'image/jpeg' && $info[2] != 2){
+ return -1;
+ }elseif($mime == 'image/png' && $info[2] != 3){
+ return -1;
+ }
+ # fixme maybe check other images types as well
+ }elseif(substr($mime,0,5) == 'text/'){
+ global $TEXT;
+ $TEXT = io_readFile($file);
+ if(checkwordblock()){
+ return -2; //blocked by the spam blacklist
+ }
+ }
+ return 0;
+}
+
+/**
+ * Send a notify mail on uploads
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id media id
+ * @param string $file path to file
+ * @param string $mime mime type
+ * @param bool|int $old_rev revision timestamp or false
+ * @return bool
+ */
+function media_notify($id,$file,$mime,$old_rev=false,$current_rev=false){
+ global $conf;
+ if(empty($conf['notify'])) return false; //notify enabled?
+
+ $subscription = new MediaSubscriptionSender();
+ return $subscription->sendMediaDiff($conf['notify'], 'uploadmail', $id, $old_rev, $current_rev);
+}
+
+/**
+ * List all files in a given Media namespace
+ *
+ * @param string $ns namespace
+ * @param null|int $auth permission level
+ * @param string $jump id
+ * @param bool $fullscreenview
+ * @param bool|string $sort sorting order, false skips sorting
+ */
+function media_filelist($ns,$auth=null,$jump='',$fullscreenview=false,$sort=false){
+ global $conf;
+ global $lang;
+ $ns = cleanID($ns);
+
+ // check auth our self if not given (needed for ajax calls)
+ if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*");
+
+ if (!$fullscreenview) echo '<h1 id="media__ns">:'.hsc($ns).'</h1>'.NL;
+
+ if($auth < AUTH_READ){
+ // FIXME: print permission warning here instead?
+ echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL;
+ }else{
+ if (!$fullscreenview) {
+ media_uploadform($ns, $auth);
+ media_searchform($ns);
+ }
+
+ $dir = utf8_encodeFN(str_replace(':','/',$ns));
+ $data = array();
+ search($data,$conf['mediadir'],'search_media',
+ array('showmsg'=>true,'depth'=>1),$dir,1,$sort);
+
+ if(!count($data)){
+ echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL;
+ }else {
+ if ($fullscreenview) {
+ echo '<ul class="' . _media_get_list_type() . '">';
+ }
+ foreach($data as $item){
+ if (!$fullscreenview) {
+ media_printfile($item,$auth,$jump);
+ } else {
+ media_printfile_thumbs($item,$auth,$jump);
+ }
+ }
+ if ($fullscreenview) echo '</ul>'.NL;
+ }
+ }
+}
+
+/**
+ * Prints tabs for files list actions
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ * @author Adrian Lang <mail@adrianlang.de>
+ *
+ * @param string $selected_tab - opened tab
+ */
+
+function media_tabs_files($selected_tab = ''){
+ global $lang;
+ $tabs = array();
+ foreach(array('files' => 'mediaselect',
+ 'upload' => 'media_uploadtab',
+ 'search' => 'media_searchtab') as $tab => $caption) {
+ $tabs[$tab] = array('href' => media_managerURL(array('tab_files' => $tab), '&'),
+ 'caption' => $lang[$caption]);
+ }
+
+ html_tabs($tabs, $selected_tab);
+}
+
+/**
+ * Prints tabs for files details actions
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ * @param string $image filename of the current image
+ * @param string $selected_tab opened tab
+ */
+function media_tabs_details($image, $selected_tab = ''){
+ global $lang, $conf;
+
+ $tabs = array();
+ $tabs['view'] = array('href' => media_managerURL(array('tab_details' => 'view'), '&'),
+ 'caption' => $lang['media_viewtab']);
+
+ list(, $mime) = mimetype($image);
+ if ($mime == 'image/jpeg' && file_exists(mediaFN($image))) {
+ $tabs['edit'] = array('href' => media_managerURL(array('tab_details' => 'edit'), '&'),
+ 'caption' => $lang['media_edittab']);
+ }
+ if ($conf['mediarevisions']) {
+ $tabs['history'] = array('href' => media_managerURL(array('tab_details' => 'history'), '&'),
+ 'caption' => $lang['media_historytab']);
+ }
+
+ html_tabs($tabs, $selected_tab);
+}
+
+/**
+ * Prints options for the tab that displays a list of all files
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function media_tab_files_options(){
+ global $lang;
+ global $INPUT;
+ global $ID;
+ $form = new Doku_Form(array('class' => 'options', 'method' => 'get',
+ 'action' => wl($ID)));
+ $media_manager_params = media_managerURL(array(), '', false, true);
+ foreach($media_manager_params as $pKey => $pVal){
+ $form->addHidden($pKey, $pVal);
+ }
+ $form->addHidden('sectok', null);
+ if ($INPUT->has('q')) {
+ $form->addHidden('q', $INPUT->str('q'));
+ }
+ $form->addElement('<ul>'.NL);
+ foreach(array('list' => array('listType', array('thumbs', 'rows')),
+ 'sort' => array('sortBy', array('name', 'date')))
+ as $group => $content) {
+ $checked = "_media_get_${group}_type";
+ $checked = $checked();
+
+ $form->addElement('<li class="' . $content[0] . '">');
+ foreach($content[1] as $option) {
+ $attrs = array();
+ if ($checked == $option) {
+ $attrs['checked'] = 'checked';
+ }
+ $form->addElement(form_makeRadioField($group . '_dwmedia', $option,
+ $lang['media_' . $group . '_' . $option],
+ $content[0] . '__' . $option,
+ $option, $attrs));
+ }
+ $form->addElement('</li>'.NL);
+ }
+ $form->addElement('<li>');
+ $form->addElement(form_makeButton('submit', '', $lang['btn_apply']));
+ $form->addElement('</li>'.NL);
+ $form->addElement('</ul>'.NL);
+ $form->printForm();
+}
+
+/**
+ * Returns type of sorting for the list of files in media manager
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @return string - sort type
+ */
+function _media_get_sort_type() {
+ return _media_get_display_param('sort', array('default' => 'name', 'date'));
+}
+
+/**
+ * Returns type of listing for the list of files in media manager
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @return string - list type
+ */
+function _media_get_list_type() {
+ return _media_get_display_param('list', array('default' => 'thumbs', 'rows'));
+}
+
+/**
+ * Get display parameters
+ *
+ * @param string $param name of parameter
+ * @param array $values allowed values, where default value has index key 'default'
+ * @return string the parameter value
+ */
+function _media_get_display_param($param, $values) {
+ global $INPUT;
+ if (in_array($INPUT->str($param), $values)) {
+ // FIXME: Set cookie
+ return $INPUT->str($param);
+ } else {
+ $val = get_doku_pref($param, $values['default']);
+ if (!in_array($val, $values)) {
+ $val = $values['default'];
+ }
+ return $val;
+ }
+}
+
+/**
+ * Prints tab that displays a list of all files
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $ns
+ * @param null|int $auth permission level
+ * @param string $jump item id
+ */
+function media_tab_files($ns,$auth=null,$jump='') {
+ global $lang;
+ if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*");
+
+ if($auth < AUTH_READ){
+ echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL;
+ }else{
+ media_filelist($ns,$auth,$jump,true,_media_get_sort_type());
+ }
+}
+
+/**
+ * Prints tab that displays uploading form
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $ns
+ * @param null|int $auth permission level
+ * @param string $jump item id
+ */
+function media_tab_upload($ns,$auth=null,$jump='') {
+ global $lang;
+ if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*");
+
+ echo '<div class="upload">'.NL;
+ if ($auth >= AUTH_UPLOAD) {
+ echo '<p>' . $lang['mediaupload'] . '</p>';
+ }
+ media_uploadform($ns, $auth, true);
+ echo '</div>'.NL;
+}
+
+/**
+ * Prints tab that displays search form
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $ns
+ * @param null|int $auth permission level
+ */
+function media_tab_search($ns,$auth=null) {
+ global $INPUT;
+
+ $do = $INPUT->str('mediado');
+ $query = $INPUT->str('q');
+ echo '<div class="search">'.NL;
+
+ media_searchform($ns, $query, true);
+ if ($do == 'searchlist' || $query) {
+ media_searchlist($query,$ns,$auth,true,_media_get_sort_type());
+ }
+ echo '</div>'.NL;
+}
+
+/**
+ * Prints tab that displays mediafile details
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $image media id
+ * @param string $ns
+ * @param null|int $auth permission level
+ * @param string|int $rev revision timestamp or empty string
+ */
+function media_tab_view($image, $ns, $auth=null, $rev='') {
+ global $lang;
+ if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*");
+
+ if ($image && $auth >= AUTH_READ) {
+ $meta = new JpegMeta(mediaFN($image, $rev));
+ media_preview($image, $auth, $rev, $meta);
+ media_preview_buttons($image, $auth, $rev);
+ media_details($image, $auth, $rev, $meta);
+
+ } else {
+ echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL;
+ }
+}
+
+/**
+ * Prints tab that displays form for editing mediafile metadata
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $image media id
+ * @param string $ns
+ * @param null|int $auth permission level
+ */
+function media_tab_edit($image, $ns, $auth=null) {
+ if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*");
+
+ if ($image) {
+ list(, $mime) = mimetype($image);
+ if ($mime == 'image/jpeg') media_metaform($image,$auth);
+ }
+}
+
+/**
+ * Prints tab that displays mediafile revisions
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $image media id
+ * @param string $ns
+ * @param null|int $auth permission level
+ */
+function media_tab_history($image, $ns, $auth=null) {
+ global $lang;
+ global $INPUT;
+
+ if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*");
+ $do = $INPUT->str('mediado');
+
+ if ($auth >= AUTH_READ && $image) {
+ if ($do == 'diff'){
+ media_diff($image, $ns, $auth);
+ } else {
+ $first = $INPUT->int('first');
+ html_revisions($first, $image);
+ }
+ } else {
+ echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL;
+ }
+}
+
+/**
+ * Prints mediafile details
+ *
+ * @param string $image media id
+ * @param int $auth permission level
+ * @param int|string $rev revision timestamp or empty string
+ * @param JpegMeta|bool $meta
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function media_preview($image, $auth, $rev='', $meta=false) {
+
+ $size = media_image_preview_size($image, $rev, $meta);
+
+ if ($size) {
+ global $lang;
+ echo '<div class="image">';
+
+ $more = array();
+ if ($rev) {
+ $more['rev'] = $rev;
+ } else {
+ $t = @filemtime(mediaFN($image));
+ $more['t'] = $t;
+ }
+
+ $more['w'] = $size[0];
+ $more['h'] = $size[1];
+ $src = ml($image, $more);
+
+ echo '<a href="'.$src.'" target="_blank" title="'.$lang['mediaview'].'">';
+ echo '<img src="'.$src.'" alt="" style="max-width: '.$size[0].'px;" />';
+ echo '</a>';
+
+ echo '</div>'.NL;
+ }
+}
+
+/**
+ * Prints mediafile action buttons
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $image media id
+ * @param int $auth permission level
+ * @param string|int $rev revision timestamp, or empty string
+ */
+function media_preview_buttons($image, $auth, $rev='') {
+ global $lang, $conf;
+
+ echo '<ul class="actions">'.NL;
+
+ if($auth >= AUTH_DELETE && !$rev && file_exists(mediaFN($image))){
+
+ // delete button
+ $form = new Doku_Form(array('id' => 'mediamanager__btn_delete',
+ 'action'=>media_managerURL(array('delete' => $image), '&')));
+ $form->addElement(form_makeButton('submit','',$lang['btn_delete']));
+ echo '<li>';
+ $form->printForm();
+ echo '</li>'.NL;
+ }
+
+ $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE);
+ if($auth >= $auth_ow && !$rev){
+
+ // upload new version button
+ $form = new Doku_Form(array('id' => 'mediamanager__btn_update',
+ 'action'=>media_managerURL(array('image' => $image, 'mediado' => 'update'), '&')));
+ $form->addElement(form_makeButton('submit','',$lang['media_update']));
+ echo '<li>';
+ $form->printForm();
+ echo '</li>'.NL;
+ }
+
+ if($auth >= AUTH_UPLOAD && $rev && $conf['mediarevisions'] && file_exists(mediaFN($image, $rev))){
+
+ // restore button
+ $form = new Doku_Form(array('id' => 'mediamanager__btn_restore',
+ 'action'=>media_managerURL(array('image' => $image), '&')));
+ $form->addHidden('mediado','restore');
+ $form->addHidden('rev',$rev);
+ $form->addElement(form_makeButton('submit','',$lang['media_restore']));
+ echo '<li>';
+ $form->printForm();
+ echo '</li>'.NL;
+ }
+
+ echo '</ul>'.NL;
+}
+
+/**
+ * Returns image width and height for mediamanager preview panel
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ * @param string $image
+ * @param int|string $rev
+ * @param JpegMeta|bool $meta
+ * @param int $size
+ * @return array|false
+ */
+function media_image_preview_size($image, $rev, $meta, $size = 500) {
+ if (!preg_match("/\.(jpe?g|gif|png)$/", $image) || !file_exists(mediaFN($image, $rev))) return false;
+
+ $info = getimagesize(mediaFN($image, $rev));
+ $w = (int) $info[0];
+ $h = (int) $info[1];
+
+ if($meta && ($w > $size || $h > $size)){
+ $ratio = $meta->getResizeRatio($size, $size);
+ $w = floor($w * $ratio);
+ $h = floor($h * $ratio);
+ }
+ return array($w, $h);
+}
+
+/**
+ * Returns the requested EXIF/IPTC tag from the image meta
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param array $tags array with tags, first existing is returned
+ * @param JpegMeta $meta
+ * @param string $alt alternative value
+ * @return string
+ */
+function media_getTag($tags,$meta,$alt=''){
+ if($meta === false) return $alt;
+ $info = $meta->getField($tags);
+ if($info == false) return $alt;
+ return $info;
+}
+
+/**
+ * Returns mediafile tags
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param JpegMeta $meta
+ * @return array list of tags of the mediafile
+ */
+function media_file_tags($meta) {
+ // load the field descriptions
+ static $fields = null;
+ if(is_null($fields)){
+ $config_files = getConfigFiles('mediameta');
+ foreach ($config_files as $config_file) {
+ if(file_exists($config_file)) include($config_file);
+ }
+ }
+
+ $tags = array();
+
+ foreach($fields as $key => $tag){
+ $t = array();
+ if (!empty($tag[0])) $t = array($tag[0]);
+ if(isset($tag[3]) && is_array($tag[3])) $t = array_merge($t,$tag[3]);
+ $value = media_getTag($t, $meta);
+ $tags[] = array('tag' => $tag, 'value' => $value);
+ }
+
+ return $tags;
+}
+
+/**
+ * Prints mediafile tags
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $image image id
+ * @param int $auth permission level
+ * @param string|int $rev revision timestamp, or empty string
+ * @param bool|JpegMeta $meta image object, or create one if false
+ */
+function media_details($image, $auth, $rev='', $meta=false) {
+ global $lang;
+
+ if (!$meta) $meta = new JpegMeta(mediaFN($image, $rev));
+ $tags = media_file_tags($meta);
+
+ echo '<dl>'.NL;
+ foreach($tags as $tag){
+ if ($tag['value']) {
+ $value = cleanText($tag['value']);
+ echo '<dt>'.$lang[$tag['tag'][1]].'</dt><dd>';
+ if ($tag['tag'][2] == 'date') echo dformat($value);
+ else echo hsc($value);
+ echo '</dd>'.NL;
+ }
+ }
+ echo '</dl>'.NL;
+ echo '<dl>'.NL;
+ echo '<dt>'.$lang['reference'].':</dt>';
+ $media_usage = ft_mediause($image,true);
+ if(count($media_usage) > 0){
+ foreach($media_usage as $path){
+ echo '<dd>'.html_wikilink($path).'</dd>';
+ }
+ }else{
+ echo '<dd>'.$lang['nothingfound'].'</dd>';
+ }
+ echo '</dl>'.NL;
+
+}
+
+/**
+ * Shows difference between two revisions of file
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $image image id
+ * @param string $ns
+ * @param int $auth permission level
+ * @param bool $fromajax
+ * @return false|null|string
+ */
+function media_diff($image, $ns, $auth, $fromajax = false) {
+ global $conf;
+ global $INPUT;
+
+ if ($auth < AUTH_READ || !$image || !$conf['mediarevisions']) return '';
+
+ $rev1 = $INPUT->int('rev');
+
+ $rev2 = $INPUT->ref('rev2');
+ if(is_array($rev2)){
+ $rev1 = (int) $rev2[0];
+ $rev2 = (int) $rev2[1];
+
+ if(!$rev1){
+ $rev1 = $rev2;
+ unset($rev2);
+ }
+ }else{
+ $rev2 = $INPUT->int('rev2');
+ }
+
+ if ($rev1 && !file_exists(mediaFN($image, $rev1))) $rev1 = false;
+ if ($rev2 && !file_exists(mediaFN($image, $rev2))) $rev2 = false;
+
+ if($rev1 && $rev2){ // two specific revisions wanted
+ // make sure order is correct (older on the left)
+ if($rev1 < $rev2){
+ $l_rev = $rev1;
+ $r_rev = $rev2;
+ }else{
+ $l_rev = $rev2;
+ $r_rev = $rev1;
+ }
+ }elseif($rev1){ // single revision given, compare to current
+ $r_rev = '';
+ $l_rev = $rev1;
+ }else{ // no revision was given, compare previous to current
+ $r_rev = '';
+ $medialog = new MediaChangeLog($image);
+ $revs = $medialog->getRevisions(0, 1);
+ if (file_exists(mediaFN($image, $revs[0]))) {
+ $l_rev = $revs[0];
+ } else {
+ $l_rev = '';
+ }
+ }
+
+ // prepare event data
+ $data = array();
+ $data[0] = $image;
+ $data[1] = $l_rev;
+ $data[2] = $r_rev;
+ $data[3] = $ns;
+ $data[4] = $auth;
+ $data[5] = $fromajax;
+
+ // trigger event
+ return Event::createAndTrigger('MEDIA_DIFF', $data, '_media_file_diff', true);
+}
+
+/**
+ * Callback for media file diff
+ *
+ * @param array $data event data
+ * @return false|null
+ */
+function _media_file_diff($data) {
+ if(is_array($data) && count($data)===6) {
+ media_file_diff($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]);
+ } else {
+ return false;
+ }
+}
+
+/**
+ * Shows difference between two revisions of image
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $image
+ * @param string|int $l_rev revision timestamp, or empty string
+ * @param string|int $r_rev revision timestamp, or empty string
+ * @param string $ns
+ * @param int $auth permission level
+ * @param bool $fromajax
+ */
+function media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax){
+ global $lang;
+ global $INPUT;
+
+ $l_meta = new JpegMeta(mediaFN($image, $l_rev));
+ $r_meta = new JpegMeta(mediaFN($image, $r_rev));
+
+ $is_img = preg_match('/\.(jpe?g|gif|png)$/', $image);
+ if ($is_img) {
+ $l_size = media_image_preview_size($image, $l_rev, $l_meta);
+ $r_size = media_image_preview_size($image, $r_rev, $r_meta);
+ $is_img = ($l_size && $r_size && ($l_size[0] >= 30 || $r_size[0] >= 30));
+
+ $difftype = $INPUT->str('difftype');
+
+ if (!$fromajax) {
+ $form = new Doku_Form(array(
+ 'action' => media_managerURL(array(), '&'),
+ 'method' => 'get',
+ 'id' => 'mediamanager__form_diffview',
+ 'class' => 'diffView'
+ ));
+ $form->addHidden('sectok', null);
+ $form->addElement('<input type="hidden" name="rev2[]" value="'.$l_rev.'" ></input>');
+ $form->addElement('<input type="hidden" name="rev2[]" value="'.$r_rev.'" ></input>');
+ $form->addHidden('mediado', 'diff');
+ $form->printForm();
+
+ echo NL.'<div id="mediamanager__diff" >'.NL;
+ }
+
+ if ($difftype == 'opacity' || $difftype == 'portions') {
+ media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $difftype);
+ if (!$fromajax) echo '</div>';
+ return;
+ }
+ }
+
+ list($l_head, $r_head) = html_diff_head($l_rev, $r_rev, $image, true);
+
+ ?>
+ <div class="table">
+ <table>
+ <tr>
+ <th><?php echo $l_head; ?></th>
+ <th><?php echo $r_head; ?></th>
+ </tr>
+ <?php
+
+ echo '<tr class="image">';
+ echo '<td>';
+ media_preview($image, $auth, $l_rev, $l_meta);
+ echo '</td>';
+
+ echo '<td>';
+ media_preview($image, $auth, $r_rev, $r_meta);
+ echo '</td>';
+ echo '</tr>'.NL;
+
+ echo '<tr class="actions">';
+ echo '<td>';
+ media_preview_buttons($image, $auth, $l_rev);
+ echo '</td>';
+
+ echo '<td>';
+ media_preview_buttons($image, $auth, $r_rev);
+ echo '</td>';
+ echo '</tr>'.NL;
+
+ $l_tags = media_file_tags($l_meta);
+ $r_tags = media_file_tags($r_meta);
+ // FIXME r_tags-only stuff
+ foreach ($l_tags as $key => $l_tag) {
+ if ($l_tag['value'] != $r_tags[$key]['value']) {
+ $r_tags[$key]['highlighted'] = true;
+ $l_tags[$key]['highlighted'] = true;
+ } else if (!$l_tag['value'] || !$r_tags[$key]['value']) {
+ unset($r_tags[$key]);
+ unset($l_tags[$key]);
+ }
+ }
+
+ echo '<tr>';
+ foreach(array($l_tags,$r_tags) as $tags){
+ echo '<td>'.NL;
+
+ echo '<dl class="img_tags">';
+ foreach($tags as $tag){
+ $value = cleanText($tag['value']);
+ if (!$value) $value = '-';
+ echo '<dt>'.$lang[$tag['tag'][1]].'</dt>';
+ echo '<dd>';
+ if ($tag['highlighted']) {
+ echo '<strong>';
+ }
+ if ($tag['tag'][2] == 'date') echo dformat($value);
+ else echo hsc($value);
+ if ($tag['highlighted']) {
+ echo '</strong>';
+ }
+ echo '</dd>';
+ }
+ echo '</dl>'.NL;
+
+ echo '</td>';
+ }
+ echo '</tr>'.NL;
+
+ echo '</table>'.NL;
+ echo '</div>'.NL;
+
+ if ($is_img && !$fromajax) echo '</div>';
+}
+
+/**
+ * Prints two images side by side
+ * and slider
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $image image id
+ * @param int $l_rev revision timestamp, or empty string
+ * @param int $r_rev revision timestamp, or empty string
+ * @param array $l_size array with width and height
+ * @param array $r_size array with width and height
+ * @param string $type
+ */
+function media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type) {
+ if ($l_size != $r_size) {
+ if ($r_size[0] > $l_size[0]) {
+ $l_size = $r_size;
+ }
+ }
+
+ $l_more = array('rev' => $l_rev, 'h' => $l_size[1], 'w' => $l_size[0]);
+ $r_more = array('rev' => $r_rev, 'h' => $l_size[1], 'w' => $l_size[0]);
+
+ $l_src = ml($image, $l_more);
+ $r_src = ml($image, $r_more);
+
+ // slider
+ echo '<div class="slider" style="max-width: '.($l_size[0]-20).'px;" ></div>'.NL;
+
+ // two images in divs
+ echo '<div class="imageDiff ' . $type . '">'.NL;
+ echo '<div class="image1" style="max-width: '.$l_size[0].'px;">';
+ echo '<img src="'.$l_src.'" alt="" />';
+ echo '</div>'.NL;
+ echo '<div class="image2" style="max-width: '.$l_size[0].'px;">';
+ echo '<img src="'.$r_src.'" alt="" />';
+ echo '</div>'.NL;
+ echo '</div>'.NL;
+}
+
+/**
+ * Restores an old revision of a media file
+ *
+ * @param string $image media id
+ * @param int $rev revision timestamp or empty string
+ * @param int $auth
+ * @return string - file's id
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function media_restore($image, $rev, $auth){
+ global $conf;
+ if ($auth < AUTH_UPLOAD || !$conf['mediarevisions']) return false;
+ $removed = (!file_exists(mediaFN($image)) && file_exists(mediaMetaFN($image, '.changes')));
+ if (!$image || (!file_exists(mediaFN($image)) && !$removed)) return false;
+ if (!$rev || !file_exists(mediaFN($image, $rev))) return false;
+ list(,$imime,) = mimetype($image);
+ $res = media_upload_finish(mediaFN($image, $rev),
+ mediaFN($image),
+ $image,
+ $imime,
+ true,
+ 'copy');
+ if (is_array($res)) {
+ msg($res[0], $res[1]);
+ return false;
+ }
+ return $res;
+}
+
+/**
+ * List all files found by the search request
+ *
+ * @author Tobias Sarnowski <sarnowski@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ * @triggers MEDIA_SEARCH
+ *
+ * @param string $query
+ * @param string $ns
+ * @param null|int $auth
+ * @param bool $fullscreen
+ * @param string $sort
+ */
+function media_searchlist($query,$ns,$auth=null,$fullscreen=false,$sort='natural'){
+ global $conf;
+ global $lang;
+
+ $ns = cleanID($ns);
+ $evdata = array(
+ 'ns' => $ns,
+ 'data' => array(),
+ 'query' => $query
+ );
+ if (!blank($query)) {
+ $evt = new Event('MEDIA_SEARCH', $evdata);
+ if ($evt->advise_before()) {
+ $dir = utf8_encodeFN(str_replace(':','/',$evdata['ns']));
+ $quoted = preg_quote($evdata['query'],'/');
+ //apply globbing
+ $quoted = str_replace(array('\*', '\?'), array('.*', '.'), $quoted, $count);
+
+ //if we use globbing file name must match entirely but may be preceded by arbitrary namespace
+ if ($count > 0) $quoted = '^([^:]*:)*'.$quoted.'$';
+
+ $pattern = '/'.$quoted.'/i';
+ search($evdata['data'],
+ $conf['mediadir'],
+ 'search_media',
+ array('showmsg'=>false,'pattern'=>$pattern),
+ $dir,
+ 1,
+ $sort);
+ }
+ $evt->advise_after();
+ unset($evt);
+ }
+
+ if (!$fullscreen) {
+ echo '<h1 id="media__ns">'.sprintf($lang['searchmedia_in'],hsc($ns).':*').'</h1>'.NL;
+ media_searchform($ns,$query);
+ }
+
+ if(!count($evdata['data'])){
+ echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL;
+ }else {
+ if ($fullscreen) {
+ echo '<ul class="' . _media_get_list_type() . '">';
+ }
+ foreach($evdata['data'] as $item){
+ if (!$fullscreen) media_printfile($item,$item['perm'],'',true);
+ else media_printfile_thumbs($item,$item['perm'],false,true);
+ }
+ if ($fullscreen) echo '</ul>'.NL;
+ }
+}
+
+/**
+ * Formats and prints one file in the list
+ *
+ * @param array $item
+ * @param int $auth permission level
+ * @param string $jump item id
+ * @param bool $display_namespace
+ */
+function media_printfile($item,$auth,$jump,$display_namespace=false){
+ global $lang;
+
+ // Prepare zebra coloring
+ // I always wanted to use this variable name :-D
+ static $twibble = 1;
+ $twibble *= -1;
+ $zebra = ($twibble == -1) ? 'odd' : 'even';
+
+ // Automatically jump to recent action
+ if($jump == $item['id']) {
+ $jump = ' id="scroll__here" ';
+ }else{
+ $jump = '';
+ }
+
+ // Prepare fileicons
+ list($ext) = mimetype($item['file'],false);
+ $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext);
+ $class = 'select mediafile mf_'.$class;
+
+ // Prepare filename
+ $file = utf8_decodeFN($item['file']);
+
+ // Prepare info
+ $info = '';
+ if($item['isimg']){
+ $info .= (int) $item['meta']->getField('File.Width');
+ $info .= '&#215;';
+ $info .= (int) $item['meta']->getField('File.Height');
+ $info .= ' ';
+ }
+ $info .= '<i>'.dformat($item['mtime']).'</i>';
+ $info .= ' ';
+ $info .= filesize_h($item['size']);
+
+ // output
+ echo '<div class="'.$zebra.'"'.$jump.' title="'.hsc($item['id']).'">'.NL;
+ if (!$display_namespace) {
+ echo '<a id="h_:'.$item['id'].'" class="'.$class.'">'.hsc($file).'</a> ';
+ } else {
+ echo '<a id="h_:'.$item['id'].'" class="'.$class.'">'.hsc($item['id']).'</a><br/>';
+ }
+ echo '<span class="info">('.$info.')</span>'.NL;
+
+ // view button
+ $link = ml($item['id'],'',true);
+ echo ' <a href="'.$link.'" target="_blank"><img src="'.DOKU_BASE.'lib/images/magnifier.png" '.
+ 'alt="'.$lang['mediaview'].'" title="'.$lang['mediaview'].'" class="btn" /></a>';
+
+ // mediamanager button
+ $link = wl('',array('do'=>'media','image'=>$item['id'],'ns'=>getNS($item['id'])));
+ echo ' <a href="'.$link.'" target="_blank"><img src="'.DOKU_BASE.'lib/images/mediamanager.png" '.
+ 'alt="'.$lang['btn_media'].'" title="'.$lang['btn_media'].'" class="btn" /></a>';
+
+ // delete button
+ if($item['writable'] && $auth >= AUTH_DELETE){
+ $link = DOKU_BASE.'lib/exe/mediamanager.php?delete='.rawurlencode($item['id']).
+ '&amp;sectok='.getSecurityToken();
+ echo ' <a href="'.$link.'" class="btn_media_delete" title="'.$item['id'].'">'.
+ '<img src="'.DOKU_BASE.'lib/images/trash.png" alt="'.$lang['btn_delete'].'" '.
+ 'title="'.$lang['btn_delete'].'" class="btn" /></a>';
+ }
+
+ echo '<div class="example" id="ex_'.str_replace(':','_',$item['id']).'">';
+ echo $lang['mediausage'].' <code>{{:'.$item['id'].'}}</code>';
+ echo '</div>';
+ if($item['isimg']) media_printimgdetail($item);
+ echo '<div class="clearer"></div>'.NL;
+ echo '</div>'.NL;
+}
+
+/**
+ * Display a media icon
+ *
+ * @param string $filename media id
+ * @param string $size the size subfolder, if not specified 16x16 is used
+ * @return string html
+ */
+function media_printicon($filename, $size=''){
+ list($ext) = mimetype(mediaFN($filename),false);
+
+ if (file_exists(DOKU_INC.'lib/images/fileicons/'.$size.'/'.$ext.'.png')) {
+ $icon = DOKU_BASE.'lib/images/fileicons/'.$size.'/'.$ext.'.png';
+ } else {
+ $icon = DOKU_BASE.'lib/images/fileicons/'.$size.'/file.png';
+ }
+
+ return '<img src="'.$icon.'" alt="'.$filename.'" class="icon" />';
+}
+
+/**
+ * Formats and prints one file in the list in the thumbnails view
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param array $item
+ * @param int $auth permission level
+ * @param bool|string $jump item id
+ * @param bool $display_namespace
+ */
+function media_printfile_thumbs($item,$auth,$jump=false,$display_namespace=false){
+
+ // Prepare filename
+ $file = utf8_decodeFN($item['file']);
+
+ // output
+ echo '<li><dl title="'.hsc($item['id']).'">'.NL;
+
+ echo '<dt>';
+ if($item['isimg']) {
+ media_printimgdetail($item, true);
+
+ } else {
+ echo '<a id="d_:'.$item['id'].'" class="image" title="'.$item['id'].'" href="'.
+ media_managerURL(array('image' => hsc($item['id']), 'ns' => getNS($item['id']),
+ 'tab_details' => 'view')).'">';
+ echo media_printicon($item['id'], '32x32');
+ echo '</a>';
+ }
+ echo '</dt>'.NL;
+ if (!$display_namespace) {
+ $name = hsc($file);
+ } else {
+ $name = hsc($item['id']);
+ }
+ echo '<dd class="name"><a href="'.media_managerURL(array('image' => hsc($item['id']), 'ns' => getNS($item['id']),
+ 'tab_details' => 'view')).'" id="h_:'.$item['id'].'">'.$name.'</a></dd>'.NL;
+
+ if($item['isimg']){
+ $size = '';
+ $size .= (int) $item['meta']->getField('File.Width');
+ $size .= '&#215;';
+ $size .= (int) $item['meta']->getField('File.Height');
+ echo '<dd class="size">'.$size.'</dd>'.NL;
+ } else {
+ echo '<dd class="size">&#160;</dd>'.NL;
+ }
+ $date = dformat($item['mtime']);
+ echo '<dd class="date">'.$date.'</dd>'.NL;
+ $filesize = filesize_h($item['size']);
+ echo '<dd class="filesize">'.$filesize.'</dd>'.NL;
+ echo '</dl></li>'.NL;
+}
+
+/**
+ * Prints a thumbnail and metainfo
+ *
+ * @param array $item
+ * @param bool $fullscreen
+ */
+function media_printimgdetail($item, $fullscreen=false){
+ // prepare thumbnail
+ $size = $fullscreen ? 90 : 120;
+
+ $w = (int) $item['meta']->getField('File.Width');
+ $h = (int) $item['meta']->getField('File.Height');
+ if($w>$size || $h>$size){
+ if (!$fullscreen) {
+ $ratio = $item['meta']->getResizeRatio($size);
+ } else {
+ $ratio = $item['meta']->getResizeRatio($size,$size);
+ }
+ $w = floor($w * $ratio);
+ $h = floor($h * $ratio);
+ }
+ $src = ml($item['id'],array('w'=>$w,'h'=>$h,'t'=>$item['mtime']));
+ $p = array();
+ if (!$fullscreen) {
+ // In fullscreen mediamanager view, image resizing is done via CSS.
+ $p['width'] = $w;
+ $p['height'] = $h;
+ }
+ $p['alt'] = $item['id'];
+ $att = buildAttributes($p);
+
+ // output
+ if ($fullscreen) {
+ echo '<a id="l_:'.$item['id'].'" class="image thumb" href="'.
+ media_managerURL(['image' => hsc($item['id']), 'ns' => getNS($item['id']), 'tab_details' => 'view']).'">';
+ echo '<img src="'.$src.'" '.$att.' />';
+ echo '</a>';
+ }
+
+ if ($fullscreen) return;
+
+ echo '<div class="detail">';
+ echo '<div class="thumb">';
+ echo '<a id="d_:'.$item['id'].'" class="select">';
+ echo '<img src="'.$src.'" '.$att.' />';
+ echo '</a>';
+ echo '</div>';
+
+ // read EXIF/IPTC data
+ $t = $item['meta']->getField(array('IPTC.Headline','xmp.dc:title'));
+ $d = $item['meta']->getField(array('IPTC.Caption','EXIF.UserComment',
+ 'EXIF.TIFFImageDescription',
+ 'EXIF.TIFFUserComment'));
+ if(\dokuwiki\Utf8\PhpString::strlen($d) > 250) $d = \dokuwiki\Utf8\PhpString::substr($d,0,250).'...';
+ $k = $item['meta']->getField(array('IPTC.Keywords','IPTC.Category','xmp.dc:subject'));
+
+ // print EXIF/IPTC data
+ if($t || $d || $k ){
+ echo '<p>';
+ if($t) echo '<strong>'.hsc($t).'</strong><br />';
+ if($d) echo hsc($d).'<br />';
+ if($t) echo '<em>'.hsc($k).'</em>';
+ echo '</p>';
+ }
+ echo '</div>';
+}
+
+/**
+ * Build link based on the current, adding/rewriting parameters
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param array|bool $params
+ * @param string $amp separator
+ * @param bool $abs absolute url?
+ * @param bool $params_array return the parmeters array?
+ * @return string|array - link or link parameters
+ */
+function media_managerURL($params=false, $amp='&amp;', $abs=false, $params_array=false) {
+ global $ID;
+ global $INPUT;
+
+ $gets = array('do' => 'media');
+ $media_manager_params = array('tab_files', 'tab_details', 'image', 'ns', 'list', 'sort');
+ foreach ($media_manager_params as $x) {
+ if ($INPUT->has($x)) $gets[$x] = $INPUT->str($x);
+ }
+
+ if ($params) {
+ $gets = $params + $gets;
+ }
+ unset($gets['id']);
+ if (isset($gets['delete'])) {
+ unset($gets['image']);
+ unset($gets['tab_details']);
+ }
+
+ if ($params_array) return $gets;
+
+ return wl($ID,$gets,$abs,$amp);
+}
+
+/**
+ * Print the media upload form if permissions are correct
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $ns
+ * @param int $auth permission level
+ * @param bool $fullscreen
+ */
+function media_uploadform($ns, $auth, $fullscreen = false){
+ global $lang;
+ global $conf;
+ global $INPUT;
+
+ if($auth < AUTH_UPLOAD) {
+ echo '<div class="nothing">'.$lang['media_perm_upload'].'</div>'.NL;
+ return;
+ }
+ $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE);
+
+ $update = false;
+ $id = '';
+ if ($auth >= $auth_ow && $fullscreen && $INPUT->str('mediado') == 'update') {
+ $update = true;
+ $id = cleanID($INPUT->str('image'));
+ }
+
+ // The default HTML upload form
+ $params = array('id' => 'dw__upload',
+ 'enctype' => 'multipart/form-data');
+ if (!$fullscreen) {
+ $params['action'] = DOKU_BASE.'lib/exe/mediamanager.php';
+ } else {
+ $params['action'] = media_managerURL(array('tab_files' => 'files',
+ 'tab_details' => 'view'), '&');
+ }
+
+ $form = new Doku_Form($params);
+ if (!$fullscreen) echo '<div class="upload">' . $lang['mediaupload'] . '</div>';
+ $form->addElement(formSecurityToken());
+ $form->addHidden('ns', hsc($ns));
+ $form->addElement(form_makeOpenTag('p'));
+ $form->addElement(form_makeFileField('upload', $lang['txt_upload'], 'upload__file'));
+ $form->addElement(form_makeCloseTag('p'));
+ $form->addElement(form_makeOpenTag('p'));
+ $form->addElement(form_makeTextField('mediaid', noNS($id), $lang['txt_filename'], 'upload__name'));
+ $form->addElement(form_makeButton('submit', '', $lang['btn_upload']));
+ $form->addElement(form_makeCloseTag('p'));
+
+ if($auth >= $auth_ow){
+ $form->addElement(form_makeOpenTag('p'));
+ $attrs = array();
+ if ($update) $attrs['checked'] = 'checked';
+ $form->addElement(form_makeCheckboxField('ow', 1, $lang['txt_overwrt'], 'dw__ow', 'check', $attrs));
+ $form->addElement(form_makeCloseTag('p'));
+ }
+
+ echo NL.'<div id="mediamanager__uploader">'.NL;
+ html_form('upload', $form);
+
+ echo '</div>'.NL;
+
+ echo '<p class="maxsize">';
+ printf($lang['maxuploadsize'],filesize_h(media_getuploadsize()));
+ echo ' <a class="allowedmime" href="#">' . $lang['allowedmime'] . '</a>';
+ echo ' <span>' . implode(', ', array_keys(getMimeTypes())) .'</span>';
+ echo '</p>'.NL;
+}
+
+/**
+ * Returns the size uploaded files may have
+ *
+ * This uses a conservative approach using the lowest number found
+ * in any of the limiting ini settings
+ *
+ * @returns int size in bytes
+ */
+function media_getuploadsize(){
+ $okay = 0;
+
+ $post = (int) php_to_byte(@ini_get('post_max_size'));
+ $suho = (int) php_to_byte(@ini_get('suhosin.post.max_value_length'));
+ $upld = (int) php_to_byte(@ini_get('upload_max_filesize'));
+
+ if($post && ($post < $okay || $okay == 0)) $okay = $post;
+ if($suho && ($suho < $okay || $okay == 0)) $okay = $suho;
+ if($upld && ($upld < $okay || $okay == 0)) $okay = $upld;
+
+ return $okay;
+}
+
+/**
+ * Print the search field form
+ *
+ * @author Tobias Sarnowski <sarnowski@cosmocode.de>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $ns
+ * @param string $query
+ * @param bool $fullscreen
+ */
+function media_searchform($ns,$query='',$fullscreen=false){
+ global $lang;
+
+ // The default HTML search form
+ $params = array('id' => 'dw__mediasearch');
+ if (!$fullscreen) {
+ $params['action'] = DOKU_BASE.'lib/exe/mediamanager.php';
+ } else {
+ $params['action'] = media_managerURL(array(), '&');
+ }
+ $form = new Doku_Form($params);
+ $form->addHidden('ns', $ns);
+ $form->addHidden($fullscreen ? 'mediado' : 'do', 'searchlist');
+
+ $form->addElement(form_makeOpenTag('p'));
+ $form->addElement(
+ form_makeTextField(
+ 'q',
+ $query,
+ $lang['searchmedia'],
+ '',
+ '',
+ array('title' => sprintf($lang['searchmedia_in'], hsc($ns) . ':*'))
+ )
+ );
+ $form->addElement(form_makeButton('submit', '', $lang['btn_search']));
+ $form->addElement(form_makeCloseTag('p'));
+ html_form('searchmedia', $form);
+}
+
+/**
+ * Build a tree outline of available media namespaces
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $ns
+ */
+function media_nstree($ns){
+ global $conf;
+ global $lang;
+
+ // currently selected namespace
+ $ns = cleanID($ns);
+ if(empty($ns)){
+ global $ID;
+ $ns = (string)getNS($ID);
+ }
+
+ $ns_dir = utf8_encodeFN(str_replace(':','/',$ns));
+
+ $data = array();
+ search($data,$conf['mediadir'],'search_index',array('ns' => $ns_dir, 'nofiles' => true));
+
+ // wrap a list with the root level around the other namespaces
+ array_unshift($data, array('level' => 0, 'id' => '', 'open' =>'true',
+ 'label' => '['.$lang['mediaroot'].']'));
+
+ // insert the current ns into the hierarchy if it isn't already part of it
+ $ns_parts = explode(':', $ns);
+ $tmp_ns = '';
+ $pos = 0;
+ foreach ($ns_parts as $level => $part) {
+ if ($tmp_ns) $tmp_ns .= ':'.$part;
+ else $tmp_ns = $part;
+
+ // find the namespace parts or insert them
+ while ($data[$pos]['id'] != $tmp_ns) {
+ if (
+ $pos >= count($data) ||
+ (
+ $data[$pos]['level'] <= $level+1 &&
+ strnatcmp(utf8_encodeFN($data[$pos]['id']), utf8_encodeFN($tmp_ns)) > 0
+ )
+ ) {
+ array_splice($data, $pos, 0, array(array('level' => $level+1, 'id' => $tmp_ns, 'open' => 'true')));
+ break;
+ }
+ ++$pos;
+ }
+ }
+
+ echo html_buildlist($data,'idx','media_nstree_item','media_nstree_li');
+}
+
+/**
+ * Userfunction for html_buildlist
+ *
+ * Prints a media namespace tree item
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $item
+ * @return string html
+ */
+function media_nstree_item($item){
+ global $INPUT;
+ $pos = strrpos($item['id'], ':');
+ $label = substr($item['id'], $pos > 0 ? $pos + 1 : 0);
+ if(empty($item['label'])) $item['label'] = $label;
+
+ $ret = '';
+ if (!($INPUT->str('do') == 'media'))
+ $ret .= '<a href="'.DOKU_BASE.'lib/exe/mediamanager.php?ns='.idfilter($item['id']).'" class="idx_dir">';
+ else $ret .= '<a href="'.media_managerURL(array('ns' => idfilter($item['id'], false), 'tab_files' => 'files'))
+ .'" class="idx_dir">';
+ $ret .= $item['label'];
+ $ret .= '</a>';
+ return $ret;
+}
+
+/**
+ * Userfunction for html_buildlist
+ *
+ * Prints a media namespace tree item opener
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $item
+ * @return string html
+ */
+function media_nstree_li($item){
+ $class='media level'.$item['level'];
+ if($item['open']){
+ $class .= ' open';
+ $img = DOKU_BASE.'lib/images/minus.gif';
+ $alt = '−';
+ }else{
+ $class .= ' closed';
+ $img = DOKU_BASE.'lib/images/plus.gif';
+ $alt = '+';
+ }
+ // TODO: only deliver an image if it actually has a subtree...
+ return '<li class="'.$class.'">'.
+ '<img src="'.$img.'" alt="'.$alt.'" />';
+}
+
+/**
+ * Resizes the given image to the given size
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename, path to file
+ * @param string $ext extension
+ * @param int $w desired width
+ * @param int $h desired height
+ * @return string path to resized or original size if failed
+ */
+function media_resize_image($file, $ext, $w, $h=0){
+ global $conf;
+
+ $info = @getimagesize($file); //get original size
+ if($info == false) return $file; // that's no image - it's a spaceship!
+
+ if(!$h) $h = round(($w * $info[1]) / $info[0]);
+ if(!$w) $w = round(($h * $info[0]) / $info[1]);
+
+ // we wont scale up to infinity
+ if($w > 2000 || $h > 2000) return $file;
+
+ // resize necessary? - (w,h) = native dimensions
+ if(($w == $info[0]) && ($h == $info[1])) return $file;
+
+ //cache
+ $local = getCacheName($file,'.media.'.$w.'x'.$h.'.'.$ext);
+ $mtime = @filemtime($local); // 0 if not exists
+
+ if($mtime > filemtime($file) ||
+ media_resize_imageIM($ext, $file, $info[0], $info[1], $local, $w, $h) ||
+ media_resize_imageGD($ext, $file, $info[0], $info[1], $local, $w, $h)
+ ) {
+ if($conf['fperm']) @chmod($local, $conf['fperm']);
+ return $local;
+ }
+ //still here? resizing failed
+ return $file;
+}
+
+/**
+ * Crops the given image to the wanted ratio, then calls media_resize_image to scale it
+ * to the wanted size
+ *
+ * Crops are centered horizontally but prefer the upper third of an vertical
+ * image because most pics are more interesting in that area (rule of thirds)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename, path to file
+ * @param string $ext extension
+ * @param int $w desired width
+ * @param int $h desired height
+ * @return string path to resized or original size if failed
+ */
+function media_crop_image($file, $ext, $w, $h=0){
+ global $conf;
+
+ if(!$h) $h = $w;
+ $info = @getimagesize($file); //get original size
+ if($info == false) return $file; // that's no image - it's a spaceship!
+
+ // calculate crop size
+ $fr = $info[0]/$info[1];
+ $tr = $w/$h;
+
+ // check if the crop can be handled completely by resize,
+ // i.e. the specified width & height match the aspect ratio of the source image
+ if ($w == round($h*$fr)) {
+ return media_resize_image($file, $ext, $w);
+ }
+
+ if($tr >= 1){
+ if($tr > $fr){
+ $cw = $info[0];
+ $ch = (int) ($info[0]/$tr);
+ }else{
+ $cw = (int) ($info[1]*$tr);
+ $ch = $info[1];
+ }
+ }else{
+ if($tr < $fr){
+ $cw = (int) ($info[1]*$tr);
+ $ch = $info[1];
+ }else{
+ $cw = $info[0];
+ $ch = (int) ($info[0]/$tr);
+ }
+ }
+ // calculate crop offset
+ $cx = (int) (($info[0]-$cw)/2);
+ $cy = (int) (($info[1]-$ch)/3);
+
+ //cache
+ $local = getCacheName($file,'.media.'.$cw.'x'.$ch.'.crop.'.$ext);
+ $mtime = @filemtime($local); // 0 if not exists
+
+ if( $mtime > @filemtime($file) ||
+ media_crop_imageIM($ext,$file,$info[0],$info[1],$local,$cw,$ch,$cx,$cy) ||
+ media_resize_imageGD($ext,$file,$cw,$ch,$local,$cw,$ch,$cx,$cy) ){
+ if($conf['fperm']) @chmod($local, $conf['fperm']);
+ return media_resize_image($local,$ext, $w, $h);
+ }
+
+ //still here? cropping failed
+ return media_resize_image($file,$ext, $w, $h);
+}
+
+/**
+ * Calculate a token to be used to verify fetch requests for resized or
+ * cropped images have been internally generated - and prevent external
+ * DDOS attacks via fetch
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ *
+ * @param string $id id of the image
+ * @param int $w resize/crop width
+ * @param int $h resize/crop height
+ * @return string token or empty string if no token required
+ */
+function media_get_token($id,$w,$h){
+ // token is only required for modified images
+ if ($w || $h || media_isexternal($id)) {
+ $token = $id;
+ if ($w) $token .= '.'.$w;
+ if ($h) $token .= '.'.$h;
+
+ return substr(\dokuwiki\PassHash::hmac('md5', $token, auth_cookiesalt()),0,6);
+ }
+
+ return '';
+}
+
+/**
+ * Download a remote file and return local filename
+ *
+ * returns false if download fails. Uses cached file if available and
+ * wanted
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Pavel Vitis <Pavel.Vitis@seznam.cz>
+ *
+ * @param string $url
+ * @param string $ext extension
+ * @param int $cache cachetime in seconds
+ * @return false|string path to cached file
+ */
+function media_get_from_URL($url,$ext,$cache){
+ global $conf;
+
+ // if no cache or fetchsize just redirect
+ if ($cache==0) return false;
+ if (!$conf['fetchsize']) return false;
+
+ $local = getCacheName(strtolower($url),".media.$ext");
+ $mtime = @filemtime($local); // 0 if not exists
+
+ //decide if download needed:
+ if(($mtime == 0) || // cache does not exist
+ ($cache != -1 && $mtime < time() - $cache) // 'recache' and cache has expired
+ ) {
+ if(media_image_download($url, $local)) {
+ return $local;
+ } else {
+ return false;
+ }
+ }
+
+ //if cache exists use it else
+ if($mtime) return $local;
+
+ //else return false
+ return false;
+}
+
+/**
+ * Download image files
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $url
+ * @param string $file path to file in which to put the downloaded content
+ * @return bool
+ */
+function media_image_download($url,$file){
+ global $conf;
+ $http = new DokuHTTPClient();
+ $http->keep_alive = false; // we do single ops here, no need for keep-alive
+
+ $http->max_bodysize = $conf['fetchsize'];
+ $http->timeout = 25; //max. 25 sec
+ $http->header_regexp = '!\r\nContent-Type: image/(jpe?g|gif|png)!i';
+
+ $data = $http->get($url);
+ if(!$data) return false;
+
+ $fileexists = file_exists($file);
+ $fp = @fopen($file,"w");
+ if(!$fp) return false;
+ fwrite($fp,$data);
+ fclose($fp);
+ if(!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']);
+
+ // check if it is really an image
+ $info = @getimagesize($file);
+ if(!$info){
+ @unlink($file);
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * resize images using external ImageMagick convert program
+ *
+ * @author Pavel Vitis <Pavel.Vitis@seznam.cz>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $ext extension
+ * @param string $from filename path to file
+ * @param int $from_w original width
+ * @param int $from_h original height
+ * @param string $to path to resized file
+ * @param int $to_w desired width
+ * @param int $to_h desired height
+ * @return bool
+ */
+function media_resize_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){
+ global $conf;
+
+ // check if convert is configured
+ if(!$conf['im_convert']) return false;
+
+ // prepare command
+ $cmd = $conf['im_convert'];
+ $cmd .= ' -resize '.$to_w.'x'.$to_h.'!';
+ if ($ext == 'jpg' || $ext == 'jpeg') {
+ $cmd .= ' -quality '.$conf['jpg_quality'];
+ }
+ $cmd .= " $from $to";
+
+ @exec($cmd,$out,$retval);
+ if ($retval == 0) return true;
+ return false;
+}
+
+/**
+ * crop images using external ImageMagick convert program
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $ext extension
+ * @param string $from filename path to file
+ * @param int $from_w original width
+ * @param int $from_h original height
+ * @param string $to path to resized file
+ * @param int $to_w desired width
+ * @param int $to_h desired height
+ * @param int $ofs_x offset of crop centre
+ * @param int $ofs_y offset of crop centre
+ * @return bool
+ */
+function media_crop_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x,$ofs_y){
+ global $conf;
+
+ // check if convert is configured
+ if(!$conf['im_convert']) return false;
+
+ // prepare command
+ $cmd = $conf['im_convert'];
+ $cmd .= ' -crop '.$to_w.'x'.$to_h.'+'.$ofs_x.'+'.$ofs_y;
+ if ($ext == 'jpg' || $ext == 'jpeg') {
+ $cmd .= ' -quality '.$conf['jpg_quality'];
+ }
+ $cmd .= " $from $to";
+
+ @exec($cmd,$out,$retval);
+ if ($retval == 0) return true;
+ return false;
+}
+
+/**
+ * resize or crop images using PHP's libGD support
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Sebastian Wienecke <s_wienecke@web.de>
+ *
+ * @param string $ext extension
+ * @param string $from filename path to file
+ * @param int $from_w original width
+ * @param int $from_h original height
+ * @param string $to path to resized file
+ * @param int $to_w desired width
+ * @param int $to_h desired height
+ * @param int $ofs_x offset of crop centre
+ * @param int $ofs_y offset of crop centre
+ * @return bool
+ */
+function media_resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x=0,$ofs_y=0){
+ global $conf;
+
+ if($conf['gdlib'] < 1) return false; //no GDlib available or wanted
+
+ // check available memory
+ if(!is_mem_available(($from_w * $from_h * 4) + ($to_w * $to_h * 4))){
+ return false;
+ }
+
+ // create an image of the given filetype
+ $image = false;
+ if ($ext == 'jpg' || $ext == 'jpeg'){
+ if(!function_exists("imagecreatefromjpeg")) return false;
+ $image = @imagecreatefromjpeg($from);
+ }elseif($ext == 'png') {
+ if(!function_exists("imagecreatefrompng")) return false;
+ $image = @imagecreatefrompng($from);
+
+ }elseif($ext == 'gif') {
+ if(!function_exists("imagecreatefromgif")) return false;
+ $image = @imagecreatefromgif($from);
+ }
+ if(!$image) return false;
+
+ $newimg = false;
+ if(($conf['gdlib']>1) && function_exists("imagecreatetruecolor") && $ext != 'gif'){
+ $newimg = @imagecreatetruecolor ($to_w, $to_h);
+ }
+ if(!$newimg) $newimg = @imagecreate($to_w, $to_h);
+ if(!$newimg){
+ imagedestroy($image);
+ return false;
+ }
+
+ //keep png alpha channel if possible
+ if($ext == 'png' && $conf['gdlib']>1 && function_exists('imagesavealpha')){
+ imagealphablending($newimg, false);
+ imagesavealpha($newimg,true);
+ }
+
+ //keep gif transparent color if possible
+ if($ext == 'gif' && function_exists('imagefill') && function_exists('imagecolorallocate')) {
+ if(function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) {
+ $transcolorindex = @imagecolortransparent($image);
+ if($transcolorindex >= 0 ) { //transparent color exists
+ $transcolor = @imagecolorsforindex($image, $transcolorindex);
+ $transcolorindex = @imagecolorallocate(
+ $newimg,
+ $transcolor['red'],
+ $transcolor['green'],
+ $transcolor['blue']
+ );
+ @imagefill($newimg, 0, 0, $transcolorindex);
+ @imagecolortransparent($newimg, $transcolorindex);
+ }else{ //filling with white
+ $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255);
+ @imagefill($newimg, 0, 0, $whitecolorindex);
+ }
+ }else{ //filling with white
+ $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255);
+ @imagefill($newimg, 0, 0, $whitecolorindex);
+ }
+ }
+
+ //try resampling first
+ if(function_exists("imagecopyresampled")){
+ if(!@imagecopyresampled($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h)) {
+ imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h);
+ }
+ }else{
+ imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h);
+ }
+
+ $okay = false;
+ if ($ext == 'jpg' || $ext == 'jpeg'){
+ if(!function_exists('imagejpeg')){
+ $okay = false;
+ }else{
+ $okay = imagejpeg($newimg, $to, $conf['jpg_quality']);
+ }
+ }elseif($ext == 'png') {
+ if(!function_exists('imagepng')){
+ $okay = false;
+ }else{
+ $okay = imagepng($newimg, $to);
+ }
+ }elseif($ext == 'gif') {
+ if(!function_exists('imagegif')){
+ $okay = false;
+ }else{
+ $okay = imagegif($newimg, $to);
+ }
+ }
+
+ // destroy GD image ressources
+ if($image) imagedestroy($image);
+ if($newimg) imagedestroy($newimg);
+
+ return $okay;
+}
+
+/**
+ * Return other media files with the same base name
+ * but different extensions.
+ *
+ * @param string $src - ID of media file
+ * @param string[] $exts - alternative extensions to find other files for
+ * @return array - array(mime type => file ID)
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+function media_alternativefiles($src, $exts){
+
+ $files = array();
+ list($srcExt, /* $srcMime */) = mimetype($src);
+ $filebase = substr($src, 0, -1 * (strlen($srcExt)+1));
+
+ foreach($exts as $ext) {
+ $fileid = $filebase.'.'.$ext;
+ $file = mediaFN($fileid);
+ if(file_exists($file)) {
+ list(/* $fileExt */, $fileMime) = mimetype($file);
+ $files[$fileMime] = $fileid;
+ }
+ }
+ return $files;
+}
+
+/**
+ * Check if video/audio is supported to be embedded.
+ *
+ * @param string $mime - mimetype of media file
+ * @param string $type - type of media files to check ('video', 'audio', or null for all)
+ * @return boolean
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+function media_supportedav($mime, $type=NULL){
+ $supportedAudio = array(
+ 'ogg' => 'audio/ogg',
+ 'mp3' => 'audio/mpeg',
+ 'wav' => 'audio/wav',
+ );
+ $supportedVideo = array(
+ 'webm' => 'video/webm',
+ 'ogv' => 'video/ogg',
+ 'mp4' => 'video/mp4',
+ );
+ if ($type == 'audio') {
+ $supportedAv = $supportedAudio;
+ } elseif ($type == 'video') {
+ $supportedAv = $supportedVideo;
+ } else {
+ $supportedAv = array_merge($supportedAudio, $supportedVideo);
+ }
+ return in_array($mime, $supportedAv);
+}
+
+/**
+ * Return track media files with the same base name
+ * but extensions that indicate kind and lang.
+ * ie for foo.webm search foo.sub.lang.vtt, foo.cap.lang.vtt...
+ *
+ * @param string $src - ID of media file
+ * @return array - array(mediaID => array( kind, srclang ))
+ *
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ */
+function media_trackfiles($src){
+ $kinds=array(
+ 'sub' => 'subtitles',
+ 'cap' => 'captions',
+ 'des' => 'descriptions',
+ 'cha' => 'chapters',
+ 'met' => 'metadata'
+ );
+
+ $files = array();
+ $re='/\\.(sub|cap|des|cha|met)\\.([^.]+)\\.vtt$/';
+ $baseid=pathinfo($src, PATHINFO_FILENAME);
+ $pattern=mediaFN($baseid).'.*.*.vtt';
+ $list=glob($pattern);
+ foreach($list as $track) {
+ if(preg_match($re, $track, $matches)){
+ $files[$baseid.'.'.$matches[1].'.'.$matches[2].'.vtt']=array(
+ $kinds[$matches[1]],
+ $matches[2],
+ );
+ }
+ }
+ return $files;
+}
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
diff --git a/platform/www/inc/pageutils.php b/platform/www/inc/pageutils.php
new file mode 100644
index 0000000..d4a8bb7
--- /dev/null
+++ b/platform/www/inc/pageutils.php
@@ -0,0 +1,778 @@
+<?php
+/**
+ * Utilities for handling pagenames
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @todo Combine similar functions like {wiki,media,meta}FN()
+ */
+
+use dokuwiki\ChangeLog\MediaChangeLog;
+use dokuwiki\ChangeLog\PageChangeLog;
+
+/**
+ * Fetch the an ID from request
+ *
+ * Uses either standard $_REQUEST variable or extracts it from
+ * the full request URI when userewrite is set to 2
+ *
+ * For $param='id' $conf['start'] is returned if no id was found.
+ * If the second parameter is true (default) the ID is cleaned.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $param the $_REQUEST variable name, default 'id'
+ * @param bool $clean if true, ID is cleaned
+ * @return string
+ */
+function getID($param='id',$clean=true){
+ /** @var Input $INPUT */
+ global $INPUT;
+ global $conf;
+ global $ACT;
+
+ $id = $INPUT->str($param);
+
+ //construct page id from request URI
+ if(empty($id) && $conf['userewrite'] == 2){
+ $request = $INPUT->server->str('REQUEST_URI');
+ $script = '';
+
+ //get the script URL
+ if($conf['basedir']){
+ $relpath = '';
+ if($param != 'id') {
+ $relpath = 'lib/exe/';
+ }
+ $script = $conf['basedir'] . $relpath .
+ \dokuwiki\Utf8\PhpString::basename($INPUT->server->str('SCRIPT_FILENAME'));
+
+ }elseif($INPUT->server->str('PATH_INFO')){
+ $request = $INPUT->server->str('PATH_INFO');
+ }elseif($INPUT->server->str('SCRIPT_NAME')){
+ $script = $INPUT->server->str('SCRIPT_NAME');
+ }elseif($INPUT->server->str('DOCUMENT_ROOT') && $INPUT->server->str('SCRIPT_FILENAME')){
+ $script = preg_replace ('/^'.preg_quote($INPUT->server->str('DOCUMENT_ROOT'),'/').'/','',
+ $INPUT->server->str('SCRIPT_FILENAME'));
+ $script = '/'.$script;
+ }
+
+ //clean script and request (fixes a windows problem)
+ $script = preg_replace('/\/\/+/','/',$script);
+ $request = preg_replace('/\/\/+/','/',$request);
+
+ //remove script URL and Querystring to gain the id
+ if(preg_match('/^'.preg_quote($script,'/').'(.*)/',$request, $match)){
+ $id = preg_replace ('/\?.*/','',$match[1]);
+ }
+ $id = urldecode($id);
+ //strip leading slashes
+ $id = preg_replace('!^/+!','',$id);
+ }
+
+ // Namespace autolinking from URL
+ if(substr($id,-1) == ':' || ($conf['useslash'] && substr($id,-1) == '/')){
+ if(page_exists($id.$conf['start'])){
+ // start page inside namespace
+ $id = $id.$conf['start'];
+ }elseif(page_exists($id.noNS(cleanID($id)))){
+ // page named like the NS inside the NS
+ $id = $id.noNS(cleanID($id));
+ }elseif(page_exists($id)){
+ // page like namespace exists
+ $id = substr($id,0,-1);
+ }else{
+ // fall back to default
+ $id = $id.$conf['start'];
+ }
+ if (isset($ACT) && $ACT === 'show') {
+ $urlParameters = $_GET;
+ if (isset($urlParameters['id'])) {
+ unset($urlParameters['id']);
+ }
+ send_redirect(wl($id, $urlParameters, true, '&'));
+ }
+ }
+ if($clean) $id = cleanID($id);
+ if($id === '' && $param=='id') $id = $conf['start'];
+
+ return $id;
+}
+
+/**
+ * Remove unwanted chars from ID
+ *
+ * Cleans a given ID to only use allowed characters. Accented characters are
+ * converted to unaccented ones
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $raw_id The pageid to clean
+ * @param boolean $ascii Force ASCII
+ * @return string cleaned id
+ */
+function cleanID($raw_id,$ascii=false){
+ global $conf;
+ static $sepcharpat = null;
+
+ global $cache_cleanid;
+ $cache = & $cache_cleanid;
+
+ // check if it's already in the memory cache
+ if (!$ascii && isset($cache[(string)$raw_id])) {
+ return $cache[(string)$raw_id];
+ }
+
+ $sepchar = $conf['sepchar'];
+ if($sepcharpat == null) // build string only once to save clock cycles
+ $sepcharpat = '#\\'.$sepchar.'+#';
+
+ $id = trim((string)$raw_id);
+ $id = \dokuwiki\Utf8\PhpString::strtolower($id);
+
+ //alternative namespace seperator
+ if($conf['useslash']){
+ $id = strtr($id,';/','::');
+ }else{
+ $id = strtr($id,';/',':'.$sepchar);
+ }
+
+ if($conf['deaccent'] == 2 || $ascii) $id = \dokuwiki\Utf8\Clean::romanize($id);
+ if($conf['deaccent'] || $ascii) $id = \dokuwiki\Utf8\Clean::deaccent($id,-1);
+
+ //remove specials
+ $id = \dokuwiki\Utf8\Clean::stripspecials($id,$sepchar,'\*');
+
+ if($ascii) $id = \dokuwiki\Utf8\Clean::strip($id);
+
+ //clean up
+ $id = preg_replace($sepcharpat,$sepchar,$id);
+ $id = preg_replace('#:+#',':',$id);
+ $id = trim($id,':._-');
+ $id = preg_replace('#:[:\._\-]+#',':',$id);
+ $id = preg_replace('#[:\._\-]+:#',':',$id);
+
+ if (!$ascii) $cache[(string)$raw_id] = $id;
+ return($id);
+}
+
+/**
+ * Return namespacepart of a wiki ID
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id
+ * @return string|false the namespace part or false if the given ID has no namespace (root)
+ */
+function getNS($id){
+ $pos = strrpos((string)$id,':');
+ if($pos!==false){
+ return substr((string)$id,0,$pos);
+ }
+ return false;
+}
+
+/**
+ * Returns the ID without the namespace
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id
+ * @return string
+ */
+function noNS($id) {
+ $pos = strrpos($id, ':');
+ if ($pos!==false) {
+ return substr($id, $pos+1);
+ } else {
+ return $id;
+ }
+}
+
+/**
+ * Returns the current namespace
+ *
+ * @author Nathan Fritz <fritzn@crown.edu>
+ *
+ * @param string $id
+ * @return string
+ */
+function curNS($id) {
+ return noNS(getNS($id));
+}
+
+/**
+ * Returns the ID without the namespace or current namespace for 'start' pages
+ *
+ * @author Nathan Fritz <fritzn@crown.edu>
+ *
+ * @param string $id
+ * @return string
+ */
+function noNSorNS($id) {
+ global $conf;
+
+ $p = noNS($id);
+ if ($p === $conf['start'] || $p === false || $p === '') {
+ $p = curNS($id);
+ if ($p === false || $p === '') {
+ return $conf['start'];
+ }
+ }
+ return $p;
+}
+
+/**
+ * Creates a XHTML valid linkid from a given headline title
+ *
+ * @param string $title The headline title
+ * @param array|bool $check Existing IDs (title => number)
+ * @return string the title
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function sectionID($title,&$check) {
+ $title = str_replace(array(':','.'),'',cleanID($title));
+ $new = ltrim($title,'0123456789_-');
+ if(empty($new)){
+ $title = 'section'.preg_replace('/[^0-9]+/','',$title); //keep numbers from headline
+ }else{
+ $title = $new;
+ }
+
+ if(is_array($check)){
+ // make sure tiles are unique
+ if (!array_key_exists ($title,$check)) {
+ $check[$title] = 0;
+ } else {
+ $title .= ++ $check[$title];
+ }
+ }
+
+ return $title;
+}
+
+/**
+ * Wiki page existence check
+ *
+ * parameters as for wikiFN
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $id page id
+ * @param string|int $rev empty or revision timestamp
+ * @param bool $clean flag indicating that $id should be cleaned (see wikiFN as well)
+ * @param bool $date_at
+ * @return bool exists?
+ */
+function page_exists($id,$rev='',$clean=true, $date_at=false) {
+ if($rev !== '' && $date_at) {
+ $pagelog = new PageChangeLog($id);
+ $pagelog_rev = $pagelog->getLastRevisionAt($rev);
+ if($pagelog_rev !== false)
+ $rev = $pagelog_rev;
+ }
+ return file_exists(wikiFN($id,$rev,$clean));
+}
+
+/**
+ * returns the full path to the datafile specified by ID and optional revision
+ *
+ * The filename is URL encoded to protect Unicode chars
+ *
+ * @param $raw_id string id of wikipage
+ * @param $rev int|string page revision, empty string for current
+ * @param $clean bool flag indicating that $raw_id should be cleaned. Only set to false
+ * when $id is guaranteed to have been cleaned already.
+ * @return string full path
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function wikiFN($raw_id,$rev='',$clean=true){
+ global $conf;
+
+ global $cache_wikifn;
+ $cache = & $cache_wikifn;
+
+ $id = $raw_id;
+
+ if ($clean) $id = cleanID($id);
+ $id = str_replace(':','/',$id);
+
+ if (isset($cache[$id]) && isset($cache[$id][$rev])) {
+ return $cache[$id][$rev];
+ }
+
+ if(empty($rev)){
+ $fn = $conf['datadir'].'/'.utf8_encodeFN($id).'.txt';
+ }else{
+ $fn = $conf['olddir'].'/'.utf8_encodeFN($id).'.'.$rev.'.txt';
+ if($conf['compression']){
+ //test for extensions here, we want to read both compressions
+ if (file_exists($fn . '.gz')){
+ $fn .= '.gz';
+ }else if(file_exists($fn . '.bz2')){
+ $fn .= '.bz2';
+ }else{
+ //file doesnt exist yet, so we take the configured extension
+ $fn .= '.' . $conf['compression'];
+ }
+ }
+ }
+
+ if (!isset($cache[$id])) { $cache[$id] = array(); }
+ $cache[$id][$rev] = $fn;
+ return $fn;
+}
+
+/**
+ * Returns the full path to the file for locking the page while editing.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @param string $id page id
+ * @return string full path
+ */
+function wikiLockFN($id) {
+ global $conf;
+ return $conf['lockdir'].'/'.md5(cleanID($id)).'.lock';
+}
+
+
+/**
+ * returns the full path to the meta file specified by ID and extension
+ *
+ * @author Steven Danz <steven-danz@kc.rr.com>
+ *
+ * @param string $id page id
+ * @param string $ext file extension
+ * @return string full path
+ */
+function metaFN($id,$ext){
+ global $conf;
+ $id = cleanID($id);
+ $id = str_replace(':','/',$id);
+ $fn = $conf['metadir'].'/'.utf8_encodeFN($id).$ext;
+ return $fn;
+}
+
+/**
+ * returns the full path to the media's meta file specified by ID and extension
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $id media id
+ * @param string $ext extension of media
+ * @return string
+ */
+function mediaMetaFN($id,$ext){
+ global $conf;
+ $id = cleanID($id);
+ $id = str_replace(':','/',$id);
+ $fn = $conf['mediametadir'].'/'.utf8_encodeFN($id).$ext;
+ return $fn;
+}
+
+/**
+ * returns an array of full paths to all metafiles of a given ID
+ *
+ * @author Esther Brunner <esther@kaffeehaus.ch>
+ * @author Michael Hamann <michael@content-space.de>
+ *
+ * @param string $id page id
+ * @return array
+ */
+function metaFiles($id){
+ $basename = metaFN($id, '');
+ $files = glob($basename.'.*', GLOB_MARK);
+ // filter files like foo.bar.meta when $id == 'foo'
+ return $files ? preg_grep('/^'.preg_quote($basename, '/').'\.[^.\/]*$/u', $files) : array();
+}
+
+/**
+ * returns the full path to the mediafile specified by ID
+ *
+ * The filename is URL encoded to protect Unicode chars
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $id media id
+ * @param string|int $rev empty string or revision timestamp
+ * @param bool $clean
+ *
+ * @return string full path
+ */
+function mediaFN($id, $rev='', $clean=true){
+ global $conf;
+ if ($clean) $id = cleanID($id);
+ $id = str_replace(':','/',$id);
+ if(empty($rev)){
+ $fn = $conf['mediadir'].'/'.utf8_encodeFN($id);
+ }else{
+ $ext = mimetype($id);
+ $name = substr($id,0, -1*strlen($ext[0])-1);
+ $fn = $conf['mediaolddir'].'/'.utf8_encodeFN($name .'.'.( (int) $rev ).'.'.$ext[0]);
+ }
+ return $fn;
+}
+
+/**
+ * Returns the full filepath to a localized file if local
+ * version isn't found the english one is returned
+ *
+ * @param string $id The id of the local file
+ * @param string $ext The file extension (usually txt)
+ * @return string full filepath to localized file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function localeFN($id,$ext='txt'){
+ global $conf;
+ $file = DOKU_CONF.'lang/'.$conf['lang'].'/'.$id.'.'.$ext;
+ if(!file_exists($file)){
+ $file = DOKU_INC.'inc/lang/'.$conf['lang'].'/'.$id.'.'.$ext;
+ if(!file_exists($file)){
+ //fall back to english
+ $file = DOKU_INC.'inc/lang/en/'.$id.'.'.$ext;
+ }
+ }
+ return $file;
+}
+
+/**
+ * Resolve relative paths in IDs
+ *
+ * Do not call directly use resolve_mediaid or resolve_pageid
+ * instead
+ *
+ * Partyly based on a cleanPath function found at
+ * http://php.net/manual/en/function.realpath.php#57016
+ *
+ * @author <bart at mediawave dot nl>
+ *
+ * @param string $ns namespace which is context of id
+ * @param string $id relative id
+ * @param bool $clean flag indicating that id should be cleaned
+ * @return string
+ */
+function resolve_id($ns,$id,$clean=true){
+ global $conf;
+
+ // some pre cleaning for useslash:
+ if($conf['useslash']) $id = str_replace('/',':',$id);
+
+ // if the id starts with a dot we need to handle the
+ // relative stuff
+ if($id && $id[0] == '.'){
+ // normalize initial dots without a colon
+ $id = preg_replace('/^((\.+:)*)(\.+)(?=[^:\.])/','\1\3:',$id);
+ // prepend the current namespace
+ $id = $ns.':'.$id;
+
+ // cleanup relatives
+ $result = array();
+ $pathA = explode(':', $id);
+ if (!$pathA[0]) $result[] = '';
+ foreach ($pathA AS $key => $dir) {
+ if ($dir == '..') {
+ if (end($result) == '..') {
+ $result[] = '..';
+ } elseif (!array_pop($result)) {
+ $result[] = '..';
+ }
+ } elseif ($dir && $dir != '.') {
+ $result[] = $dir;
+ }
+ }
+ if (!end($pathA)) $result[] = '';
+ $id = implode(':', $result);
+ }elseif($ns !== false && strpos($id,':') === false){
+ //if link contains no namespace. add current namespace (if any)
+ $id = $ns.':'.$id;
+ }
+
+ if($clean) $id = cleanID($id);
+ return $id;
+}
+
+/**
+ * Returns a full media id
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $ns namespace which is context of id
+ * @param string &$page (reference) relative media id, updated to resolved id
+ * @param bool &$exists (reference) updated with existance of media
+ * @param int|string $rev
+ * @param bool $date_at
+ */
+function resolve_mediaid($ns,&$page,&$exists,$rev='',$date_at=false){
+ $page = resolve_id($ns,$page);
+ if($rev !== '' && $date_at){
+ $medialog = new MediaChangeLog($page);
+ $medialog_rev = $medialog->getLastRevisionAt($rev);
+ if($medialog_rev !== false) {
+ $rev = $medialog_rev;
+ }
+ }
+
+ $file = mediaFN($page,$rev);
+ $exists = file_exists($file);
+}
+
+/**
+ * Returns a full page id
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $ns namespace which is context of id
+ * @param string &$page (reference) relative page id, updated to resolved id
+ * @param bool &$exists (reference) updated with existance of media
+ * @param string $rev
+ * @param bool $date_at
+ */
+function resolve_pageid($ns,&$page,&$exists,$rev='',$date_at=false ){
+ global $conf;
+ global $ID;
+ $exists = false;
+
+ //empty address should point to current page
+ if ($page === "") {
+ $page = $ID;
+ }
+
+ //keep hashlink if exists then clean both parts
+ if (strpos($page,'#')) {
+ list($page,$hash) = explode('#',$page,2);
+ } else {
+ $hash = '';
+ }
+ $hash = cleanID($hash);
+ $page = resolve_id($ns,$page,false); // resolve but don't clean, yet
+
+ // get filename (calls clean itself)
+ if($rev !== '' && $date_at) {
+ $pagelog = new PageChangeLog($page);
+ $pagelog_rev = $pagelog->getLastRevisionAt($rev);
+ if($pagelog_rev !== false)//something found
+ $rev = $pagelog_rev;
+ }
+ $file = wikiFN($page,$rev);
+
+ // if ends with colon or slash we have a namespace link
+ if(in_array(substr($page,-1), array(':', ';')) ||
+ ($conf['useslash'] && substr($page,-1) == '/')){
+ if(page_exists($page.$conf['start'],$rev,true,$date_at)){
+ // start page inside namespace
+ $page = $page.$conf['start'];
+ $exists = true;
+ }elseif(page_exists($page.noNS(cleanID($page)),$rev,true,$date_at)){
+ // page named like the NS inside the NS
+ $page = $page.noNS(cleanID($page));
+ $exists = true;
+ }elseif(page_exists($page,$rev,true,$date_at)){
+ // page like namespace exists
+ $page = $page;
+ $exists = true;
+ }else{
+ // fall back to default
+ $page = $page.$conf['start'];
+ }
+ }else{
+ //check alternative plural/nonplural form
+ if(!file_exists($file)){
+ if( $conf['autoplural'] ){
+ if(substr($page,-1) == 's'){
+ $try = substr($page,0,-1);
+ }else{
+ $try = $page.'s';
+ }
+ if(page_exists($try,$rev,true,$date_at)){
+ $page = $try;
+ $exists = true;
+ }
+ }
+ }else{
+ $exists = true;
+ }
+ }
+
+ // now make sure we have a clean page
+ $page = cleanID($page);
+
+ //add hash if any
+ if(!empty($hash)) $page .= '#'.$hash;
+}
+
+/**
+ * Returns the name of a cachefile from given data
+ *
+ * The needed directory is created by this function!
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $data This data is used to create a unique md5 name
+ * @param string $ext This is appended to the filename if given
+ * @return string The filename of the cachefile
+ */
+function getCacheName($data,$ext=''){
+ global $conf;
+ $md5 = md5($data);
+ $file = $conf['cachedir'].'/'.$md5[0].'/'.$md5.$ext;
+ io_makeFileDir($file);
+ return $file;
+}
+
+/**
+ * Checks a pageid against $conf['hidepages']
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ *
+ * @param string $id page id
+ * @return bool
+ */
+function isHiddenPage($id){
+ $data = array(
+ 'id' => $id,
+ 'hidden' => false
+ );
+ \dokuwiki\Extension\Event::createAndTrigger('PAGEUTILS_ID_HIDEPAGE', $data, '_isHiddenPage');
+ return $data['hidden'];
+}
+
+/**
+ * callback checks if page is hidden
+ *
+ * @param array $data event data - see isHiddenPage()
+ */
+function _isHiddenPage(&$data) {
+ global $conf;
+ global $ACT;
+
+ if ($data['hidden']) return;
+ if(empty($conf['hidepages'])) return;
+ if($ACT == 'admin') return;
+
+ if(preg_match('/'.$conf['hidepages'].'/ui',':'.$data['id'])){
+ $data['hidden'] = true;
+ }
+}
+
+/**
+ * Reverse of isHiddenPage
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ *
+ * @param string $id page id
+ * @return bool
+ */
+function isVisiblePage($id){
+ return !isHiddenPage($id);
+}
+
+/**
+ * Format an id for output to a user
+ *
+ * Namespaces are denoted by a trailing “:*â€. The root namespace is
+ * “*â€. Output is escaped.
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ *
+ * @param string $id page id
+ * @return string
+ */
+function prettyprint_id($id) {
+ if (!$id || $id === ':') {
+ return '*';
+ }
+ if ((substr($id, -1, 1) === ':')) {
+ $id .= '*';
+ }
+ return hsc($id);
+}
+
+/**
+ * Encode a UTF-8 filename to use on any filesystem
+ *
+ * Uses the 'fnencode' option to determine encoding
+ *
+ * When the second parameter is true the string will
+ * be encoded only if non ASCII characters are detected -
+ * This makes it safe to run it multiple times on the
+ * same string (default is true)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see urlencode
+ *
+ * @param string $file file name
+ * @param bool $safe if true, only encoded when non ASCII characters detected
+ * @return string
+ */
+function utf8_encodeFN($file,$safe=true){
+ global $conf;
+ if($conf['fnencode'] == 'utf-8') return $file;
+
+ if($safe && preg_match('#^[a-zA-Z0-9/_\-\.%]+$#',$file)){
+ return $file;
+ }
+
+ if($conf['fnencode'] == 'safe'){
+ return SafeFN::encode($file);
+ }
+
+ $file = urlencode($file);
+ $file = str_replace('%2F','/',$file);
+ return $file;
+}
+
+/**
+ * Decode a filename back to UTF-8
+ *
+ * Uses the 'fnencode' option to determine encoding
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @see urldecode
+ *
+ * @param string $file file name
+ * @return string
+ */
+function utf8_decodeFN($file){
+ global $conf;
+ if($conf['fnencode'] == 'utf-8') return $file;
+
+ if($conf['fnencode'] == 'safe'){
+ return SafeFN::decode($file);
+ }
+
+ return urldecode($file);
+}
+
+/**
+ * Find a page in the current namespace (determined from $ID) or any
+ * higher namespace that can be accessed by the current user,
+ * this condition can be overriden by an optional parameter.
+ *
+ * Used for sidebars, but can be used other stuff as well
+ *
+ * @todo add event hook
+ *
+ * @param string $page the pagename you're looking for
+ * @param bool $useacl only return pages readable by the current user, false to ignore ACLs
+ * @return false|string the full page id of the found page, false if any
+ */
+function page_findnearest($page, $useacl = true){
+ if ((string) $page === '') return false;
+ global $ID;
+
+ $ns = $ID;
+ do {
+ $ns = getNS($ns);
+ $pageid = cleanID("$ns:$page");
+ if(page_exists($pageid) && (!$useacl || auth_quickaclcheck($pageid) >= AUTH_READ)){
+ return $pageid;
+ }
+ } while($ns !== false);
+
+ return false;
+}
diff --git a/platform/www/inc/parser/code.php b/platform/www/inc/parser/code.php
new file mode 100644
index 0000000..cded87d
--- /dev/null
+++ b/platform/www/inc/parser/code.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * A simple renderer that allows downloading of code and file snippets
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class Doku_Renderer_code extends Doku_Renderer {
+ protected $_codeblock = 0;
+
+ /**
+ * Send the wanted code block to the browser
+ *
+ * When the correct block was found it exits the script.
+ *
+ * @param string $text
+ * @param string $language
+ * @param string $filename
+ */
+ public function code($text, $language = null, $filename = '') {
+ global $INPUT;
+ if(!$language) $language = 'txt';
+ $language = preg_replace(PREG_PATTERN_VALID_LANGUAGE, '', $language);
+ if(!$filename) $filename = 'snippet.'.$language;
+ $filename = \dokuwiki\Utf8\PhpString::basename($filename);
+ $filename = \dokuwiki\Utf8\Clean::stripspecials($filename, '_');
+
+ // send CRLF to Windows clients
+ if(strpos($INPUT->server->str('HTTP_USER_AGENT'), 'Windows') !== false) {
+ $text = str_replace("\n", "\r\n", $text);
+ }
+
+ if($this->_codeblock == $INPUT->str('codeblock')) {
+ header("Content-Type: text/plain; charset=utf-8");
+ header("Content-Disposition: attachment; filename=$filename");
+ header("X-Robots-Tag: noindex");
+ echo trim($text, "\r\n");
+ exit;
+ }
+
+ $this->_codeblock++;
+ }
+
+ /**
+ * Wraps around code()
+ *
+ * @param string $text
+ * @param string $language
+ * @param string $filename
+ */
+ public function file($text, $language = null, $filename = '') {
+ $this->code($text, $language, $filename);
+ }
+
+ /**
+ * This should never be reached, if it is send a 404
+ */
+ public function document_end() {
+ http_status(404);
+ echo '404 - Not found';
+ exit;
+ }
+
+ /**
+ * Return the format of the renderer
+ *
+ * @returns string 'code'
+ */
+ public function getFormat() {
+ return 'code';
+ }
+}
diff --git a/platform/www/inc/parser/handler.php b/platform/www/inc/parser/handler.php
new file mode 100644
index 0000000..a360960
--- /dev/null
+++ b/platform/www/inc/parser/handler.php
@@ -0,0 +1,1157 @@
+<?php
+
+use dokuwiki\Extension\Event;
+use dokuwiki\Extension\SyntaxPlugin;
+use dokuwiki\Parsing\Handler\Block;
+use dokuwiki\Parsing\Handler\CallWriter;
+use dokuwiki\Parsing\Handler\CallWriterInterface;
+use dokuwiki\Parsing\Handler\Lists;
+use dokuwiki\Parsing\Handler\Nest;
+use dokuwiki\Parsing\Handler\Preformatted;
+use dokuwiki\Parsing\Handler\Quote;
+use dokuwiki\Parsing\Handler\Table;
+
+/**
+ * Class Doku_Handler
+ */
+class Doku_Handler {
+ /** @var CallWriterInterface */
+ protected $callWriter = null;
+
+ /** @var array The current CallWriter will write directly to this list of calls, Parser reads it */
+ public $calls = array();
+
+ /** @var array internal status holders for some modes */
+ protected $status = array(
+ 'section' => false,
+ 'doublequote' => 0,
+ );
+
+ /** @var bool should blocks be rewritten? FIXME seems to always be true */
+ protected $rewriteBlocks = true;
+
+ /**
+ * Doku_Handler constructor.
+ */
+ public function __construct() {
+ $this->callWriter = new CallWriter($this);
+ }
+
+ /**
+ * Add a new call by passing it to the current CallWriter
+ *
+ * @param string $handler handler method name (see mode handlers below)
+ * @param mixed $args arguments for this call
+ * @param int $pos byte position in the original source file
+ */
+ public function addCall($handler, $args, $pos) {
+ $call = array($handler,$args, $pos);
+ $this->callWriter->writeCall($call);
+ }
+
+ /**
+ * Accessor for the current CallWriter
+ *
+ * @return CallWriterInterface
+ */
+ public function getCallWriter() {
+ return $this->callWriter;
+ }
+
+ /**
+ * Set a new CallWriter
+ *
+ * @param CallWriterInterface $callWriter
+ */
+ public function setCallWriter($callWriter) {
+ $this->callWriter = $callWriter;
+ }
+
+ /**
+ * Return the current internal status of the given name
+ *
+ * @param string $status
+ * @return mixed|null
+ */
+ public function getStatus($status) {
+ if (!isset($this->status[$status])) return null;
+ return $this->status[$status];
+ }
+
+ /**
+ * Set a new internal status
+ *
+ * @param string $status
+ * @param mixed $value
+ */
+ public function setStatus($status, $value) {
+ $this->status[$status] = $value;
+ }
+
+ /** @deprecated 2019-10-31 use addCall() instead */
+ public function _addCall($handler, $args, $pos) {
+ dbg_deprecated('addCall');
+ $this->addCall($handler, $args, $pos);
+ }
+
+ /**
+ * Similar to addCall, but adds a plugin call
+ *
+ * @param string $plugin name of the plugin
+ * @param mixed $args arguments for this call
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @param string $match matched syntax
+ */
+ public function addPluginCall($plugin, $args, $state, $pos, $match) {
+ $call = array('plugin',array($plugin, $args, $state, $match), $pos);
+ $this->callWriter->writeCall($call);
+ }
+
+ /**
+ * Finishes handling
+ *
+ * Called from the parser. Calls finalise() on the call writer, closes open
+ * sections, rewrites blocks and adds document_start and document_end calls.
+ *
+ * @triggers PARSER_HANDLER_DONE
+ */
+ public function finalize(){
+ $this->callWriter->finalise();
+
+ if ( $this->status['section'] ) {
+ $last_call = end($this->calls);
+ array_push($this->calls,array('section_close',array(), $last_call[2]));
+ }
+
+ if ( $this->rewriteBlocks ) {
+ $B = new Block();
+ $this->calls = $B->process($this->calls);
+ }
+
+ Event::createAndTrigger('PARSER_HANDLER_DONE',$this);
+
+ array_unshift($this->calls,array('document_start',array(),0));
+ $last_call = end($this->calls);
+ array_push($this->calls,array('document_end',array(),$last_call[2]));
+ }
+
+ /**
+ * fetch the current call and advance the pointer to the next one
+ *
+ * @fixme seems to be unused?
+ * @return bool|mixed
+ */
+ public function fetch() {
+ $call = current($this->calls);
+ if($call !== false) {
+ next($this->calls); //advance the pointer
+ return $call;
+ }
+ return false;
+ }
+
+
+ /**
+ * Internal function for parsing highlight options.
+ * $options is parsed for key value pairs separated by commas.
+ * A value might also be missing in which case the value will simple
+ * be set to true. Commas in strings are ignored, e.g. option="4,56"
+ * will work as expected and will only create one entry.
+ *
+ * @param string $options space separated list of key-value pairs,
+ * e.g. option1=123, option2="456"
+ * @return array|null Array of key-value pairs $array['key'] = 'value';
+ * or null if no entries found
+ */
+ protected function parse_highlight_options($options) {
+ $result = array();
+ preg_match_all('/(\w+(?:="[^"]*"))|(\w+(?:=[^\s]*))|(\w+[^=\s\]])(?:\s*)/', $options, $matches, PREG_SET_ORDER);
+ foreach ($matches as $match) {
+ $equal_sign = strpos($match [0], '=');
+ if ($equal_sign === false) {
+ $key = trim($match[0]);
+ $result [$key] = 1;
+ } else {
+ $key = substr($match[0], 0, $equal_sign);
+ $value = substr($match[0], $equal_sign+1);
+ $value = trim($value, '"');
+ if (strlen($value) > 0) {
+ $result [$key] = $value;
+ } else {
+ $result [$key] = 1;
+ }
+ }
+ }
+
+ // Check for supported options
+ $result = array_intersect_key(
+ $result,
+ array_flip(array(
+ 'enable_line_numbers',
+ 'start_line_numbers_at',
+ 'highlight_lines_extra',
+ 'enable_keyword_links')
+ )
+ );
+
+ // Sanitize values
+ if(isset($result['enable_line_numbers'])) {
+ if($result['enable_line_numbers'] === 'false') {
+ $result['enable_line_numbers'] = false;
+ }
+ $result['enable_line_numbers'] = (bool) $result['enable_line_numbers'];
+ }
+ if(isset($result['highlight_lines_extra'])) {
+ $result['highlight_lines_extra'] = array_map('intval', explode(',', $result['highlight_lines_extra']));
+ $result['highlight_lines_extra'] = array_filter($result['highlight_lines_extra']);
+ $result['highlight_lines_extra'] = array_unique($result['highlight_lines_extra']);
+ }
+ if(isset($result['start_line_numbers_at'])) {
+ $result['start_line_numbers_at'] = (int) $result['start_line_numbers_at'];
+ }
+ if(isset($result['enable_keyword_links'])) {
+ if($result['enable_keyword_links'] === 'false') {
+ $result['enable_keyword_links'] = false;
+ }
+ $result['enable_keyword_links'] = (bool) $result['enable_keyword_links'];
+ }
+ if (count($result) == 0) {
+ return null;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Simplifies handling for the formatting tags which all behave the same
+ *
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @param string $name actual mode name
+ */
+ protected function nestingTag($match, $state, $pos, $name) {
+ switch ( $state ) {
+ case DOKU_LEXER_ENTER:
+ $this->addCall($name.'_open', array(), $pos);
+ break;
+ case DOKU_LEXER_EXIT:
+ $this->addCall($name.'_close', array(), $pos);
+ break;
+ case DOKU_LEXER_UNMATCHED:
+ $this->addCall('cdata', array($match), $pos);
+ break;
+ }
+ }
+
+
+ /**
+ * The following methods define the handlers for the different Syntax modes
+ *
+ * The handlers are called from dokuwiki\Parsing\Lexer\Lexer\invokeParser()
+ *
+ * @todo it might make sense to move these into their own class or merge them with the
+ * ParserMode classes some time.
+ */
+ // region mode handlers
+
+ /**
+ * Special plugin handler
+ *
+ * This handler is called for all modes starting with 'plugin_'.
+ * An additional parameter with the plugin name is passed. The plugin's handle()
+ * method is called here
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @param string $pluginname name of the plugin
+ * @return bool mode handled?
+ */
+ public function plugin($match, $state, $pos, $pluginname){
+ $data = array($match);
+ /** @var SyntaxPlugin $plugin */
+ $plugin = plugin_load('syntax',$pluginname);
+ if($plugin != null){
+ $data = $plugin->handle($match, $state, $pos, $this);
+ }
+ if ($data !== false) {
+ $this->addPluginCall($pluginname,$data,$state,$pos,$match);
+ }
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function base($match, $state, $pos) {
+ switch ( $state ) {
+ case DOKU_LEXER_UNMATCHED:
+ $this->addCall('cdata', array($match), $pos);
+ return true;
+ break;
+ }
+ return false;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function header($match, $state, $pos) {
+ // get level and title
+ $title = trim($match);
+ $level = 7 - strspn($title,'=');
+ if($level < 1) $level = 1;
+ $title = trim($title,'=');
+ $title = trim($title);
+
+ if ($this->status['section']) $this->addCall('section_close', array(), $pos);
+
+ $this->addCall('header', array($title, $level, $pos), $pos);
+
+ $this->addCall('section_open', array($level), $pos);
+ $this->status['section'] = true;
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function notoc($match, $state, $pos) {
+ $this->addCall('notoc', array(), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function nocache($match, $state, $pos) {
+ $this->addCall('nocache', array(), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function linebreak($match, $state, $pos) {
+ $this->addCall('linebreak', array(), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function eol($match, $state, $pos) {
+ $this->addCall('eol', array(), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function hr($match, $state, $pos) {
+ $this->addCall('hr', array(), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function strong($match, $state, $pos) {
+ $this->nestingTag($match, $state, $pos, 'strong');
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function emphasis($match, $state, $pos) {
+ $this->nestingTag($match, $state, $pos, 'emphasis');
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function underline($match, $state, $pos) {
+ $this->nestingTag($match, $state, $pos, 'underline');
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function monospace($match, $state, $pos) {
+ $this->nestingTag($match, $state, $pos, 'monospace');
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function subscript($match, $state, $pos) {
+ $this->nestingTag($match, $state, $pos, 'subscript');
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function superscript($match, $state, $pos) {
+ $this->nestingTag($match, $state, $pos, 'superscript');
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function deleted($match, $state, $pos) {
+ $this->nestingTag($match, $state, $pos, 'deleted');
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function footnote($match, $state, $pos) {
+ if (!isset($this->_footnote)) $this->_footnote = false;
+
+ switch ( $state ) {
+ case DOKU_LEXER_ENTER:
+ // footnotes can not be nested - however due to limitations in lexer it can't be prevented
+ // we will still enter a new footnote mode, we just do nothing
+ if ($this->_footnote) {
+ $this->addCall('cdata', array($match), $pos);
+ break;
+ }
+ $this->_footnote = true;
+
+ $this->callWriter = new Nest($this->callWriter, 'footnote_close');
+ $this->addCall('footnote_open', array(), $pos);
+ break;
+ case DOKU_LEXER_EXIT:
+ // check whether we have already exitted the footnote mode, can happen if the modes were nested
+ if (!$this->_footnote) {
+ $this->addCall('cdata', array($match), $pos);
+ break;
+ }
+
+ $this->_footnote = false;
+ $this->addCall('footnote_close', array(), $pos);
+
+ /** @var Nest $reWriter */
+ $reWriter = $this->callWriter;
+ $this->callWriter = $reWriter->process();
+ break;
+ case DOKU_LEXER_UNMATCHED:
+ $this->addCall('cdata', array($match), $pos);
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function listblock($match, $state, $pos) {
+ switch ( $state ) {
+ case DOKU_LEXER_ENTER:
+ $this->callWriter = new Lists($this->callWriter);
+ $this->addCall('list_open', array($match), $pos);
+ break;
+ case DOKU_LEXER_EXIT:
+ $this->addCall('list_close', array(), $pos);
+ /** @var Lists $reWriter */
+ $reWriter = $this->callWriter;
+ $this->callWriter = $reWriter->process();
+ break;
+ case DOKU_LEXER_MATCHED:
+ $this->addCall('list_item', array($match), $pos);
+ break;
+ case DOKU_LEXER_UNMATCHED:
+ $this->addCall('cdata', array($match), $pos);
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function unformatted($match, $state, $pos) {
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $this->addCall('unformatted', array($match), $pos);
+ }
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function php($match, $state, $pos) {
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $this->addCall('php', array($match), $pos);
+ }
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function phpblock($match, $state, $pos) {
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $this->addCall('phpblock', array($match), $pos);
+ }
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function html($match, $state, $pos) {
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $this->addCall('html', array($match), $pos);
+ }
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function htmlblock($match, $state, $pos) {
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $this->addCall('htmlblock', array($match), $pos);
+ }
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function preformatted($match, $state, $pos) {
+ switch ( $state ) {
+ case DOKU_LEXER_ENTER:
+ $this->callWriter = new Preformatted($this->callWriter);
+ $this->addCall('preformatted_start', array(), $pos);
+ break;
+ case DOKU_LEXER_EXIT:
+ $this->addCall('preformatted_end', array(), $pos);
+ /** @var Preformatted $reWriter */
+ $reWriter = $this->callWriter;
+ $this->callWriter = $reWriter->process();
+ break;
+ case DOKU_LEXER_MATCHED:
+ $this->addCall('preformatted_newline', array(), $pos);
+ break;
+ case DOKU_LEXER_UNMATCHED:
+ $this->addCall('preformatted_content', array($match), $pos);
+ break;
+ }
+
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function quote($match, $state, $pos) {
+
+ switch ( $state ) {
+
+ case DOKU_LEXER_ENTER:
+ $this->callWriter = new Quote($this->callWriter);
+ $this->addCall('quote_start', array($match), $pos);
+ break;
+
+ case DOKU_LEXER_EXIT:
+ $this->addCall('quote_end', array(), $pos);
+ /** @var Lists $reWriter */
+ $reWriter = $this->callWriter;
+ $this->callWriter = $reWriter->process();
+ break;
+
+ case DOKU_LEXER_MATCHED:
+ $this->addCall('quote_newline', array($match), $pos);
+ break;
+
+ case DOKU_LEXER_UNMATCHED:
+ $this->addCall('cdata', array($match), $pos);
+ break;
+
+ }
+
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function file($match, $state, $pos) {
+ return $this->code($match, $state, $pos, 'file');
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @param string $type either 'code' or 'file'
+ * @return bool mode handled?
+ */
+ public function code($match, $state, $pos, $type='code') {
+ if ( $state == DOKU_LEXER_UNMATCHED ) {
+ $matches = explode('>',$match,2);
+ // Cut out variable options enclosed in []
+ preg_match('/\[.*\]/', $matches[0], $options);
+ if (!empty($options[0])) {
+ $matches[0] = str_replace($options[0], '', $matches[0]);
+ }
+ $param = preg_split('/\s+/', $matches[0], 2, PREG_SPLIT_NO_EMPTY);
+ while(count($param) < 2) array_push($param, null);
+ // We shortcut html here.
+ if ($param[0] == 'html') $param[0] = 'html4strict';
+ if ($param[0] == '-') $param[0] = null;
+ array_unshift($param, $matches[1]);
+ if (!empty($options[0])) {
+ $param [] = $this->parse_highlight_options ($options[0]);
+ }
+ $this->addCall($type, $param, $pos);
+ }
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function acronym($match, $state, $pos) {
+ $this->addCall('acronym', array($match), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function smiley($match, $state, $pos) {
+ $this->addCall('smiley', array($match), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function wordblock($match, $state, $pos) {
+ $this->addCall('wordblock', array($match), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function entity($match, $state, $pos) {
+ $this->addCall('entity', array($match), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function multiplyentity($match, $state, $pos) {
+ preg_match_all('/\d+/',$match,$matches);
+ $this->addCall('multiplyentity', array($matches[0][0], $matches[0][1]), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function singlequoteopening($match, $state, $pos) {
+ $this->addCall('singlequoteopening', array(), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function singlequoteclosing($match, $state, $pos) {
+ $this->addCall('singlequoteclosing', array(), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function apostrophe($match, $state, $pos) {
+ $this->addCall('apostrophe', array(), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function doublequoteopening($match, $state, $pos) {
+ $this->addCall('doublequoteopening', array(), $pos);
+ $this->status['doublequote']++;
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function doublequoteclosing($match, $state, $pos) {
+ if ($this->status['doublequote'] <= 0) {
+ $this->doublequoteopening($match, $state, $pos);
+ } else {
+ $this->addCall('doublequoteclosing', array(), $pos);
+ $this->status['doublequote'] = max(0, --$this->status['doublequote']);
+ }
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function camelcaselink($match, $state, $pos) {
+ $this->addCall('camelcaselink', array($match), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function internallink($match, $state, $pos) {
+ // Strip the opening and closing markup
+ $link = preg_replace(array('/^\[\[/','/\]\]$/u'),'',$match);
+
+ // Split title from URL
+ $link = explode('|',$link,2);
+ if ( !isset($link[1]) ) {
+ $link[1] = null;
+ } else if ( preg_match('/^\{\{[^\}]+\}\}$/',$link[1]) ) {
+ // If the title is an image, convert it to an array containing the image details
+ $link[1] = Doku_Handler_Parse_Media($link[1]);
+ }
+ $link[0] = trim($link[0]);
+
+ //decide which kind of link it is
+
+ if ( link_isinterwiki($link[0]) ) {
+ // Interwiki
+ $interwiki = explode('>',$link[0],2);
+ $this->addCall(
+ 'interwikilink',
+ array($link[0],$link[1],strtolower($interwiki[0]),$interwiki[1]),
+ $pos
+ );
+ }elseif ( preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u',$link[0]) ) {
+ // Windows Share
+ $this->addCall(
+ 'windowssharelink',
+ array($link[0],$link[1]),
+ $pos
+ );
+ }elseif ( preg_match('#^([a-z0-9\-\.+]+?)://#i',$link[0]) ) {
+ // external link (accepts all protocols)
+ $this->addCall(
+ 'externallink',
+ array($link[0],$link[1]),
+ $pos
+ );
+ }elseif ( preg_match('<'.PREG_PATTERN_VALID_EMAIL.'>',$link[0]) ) {
+ // E-Mail (pattern above is defined in inc/mail.php)
+ $this->addCall(
+ 'emaillink',
+ array($link[0],$link[1]),
+ $pos
+ );
+ }elseif ( preg_match('!^#.+!',$link[0]) ){
+ // local link
+ $this->addCall(
+ 'locallink',
+ array(substr($link[0],1),$link[1]),
+ $pos
+ );
+ }else{
+ // internal link
+ $this->addCall(
+ 'internallink',
+ array($link[0],$link[1]),
+ $pos
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function filelink($match, $state, $pos) {
+ $this->addCall('filelink', array($match, null), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function windowssharelink($match, $state, $pos) {
+ $this->addCall('windowssharelink', array($match, null), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function media($match, $state, $pos) {
+ $p = Doku_Handler_Parse_Media($match);
+
+ $this->addCall(
+ $p['type'],
+ array($p['src'], $p['title'], $p['align'], $p['width'],
+ $p['height'], $p['cache'], $p['linking']),
+ $pos
+ );
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function rss($match, $state, $pos) {
+ $link = preg_replace(array('/^\{\{rss>/','/\}\}$/'),'',$match);
+
+ // get params
+ list($link,$params) = explode(' ',$link,2);
+
+ $p = array();
+ if(preg_match('/\b(\d+)\b/',$params,$match)){
+ $p['max'] = $match[1];
+ }else{
+ $p['max'] = 8;
+ }
+ $p['reverse'] = (preg_match('/rev/',$params));
+ $p['author'] = (preg_match('/\b(by|author)/',$params));
+ $p['date'] = (preg_match('/\b(date)/',$params));
+ $p['details'] = (preg_match('/\b(desc|detail)/',$params));
+ $p['nosort'] = (preg_match('/\b(nosort)\b/',$params));
+
+ if (preg_match('/\b(\d+)([dhm])\b/',$params,$match)) {
+ $period = array('d' => 86400, 'h' => 3600, 'm' => 60);
+ $p['refresh'] = max(600,$match[1]*$period[$match[2]]); // n * period in seconds, minimum 10 minutes
+ } else {
+ $p['refresh'] = 14400; // default to 4 hours
+ }
+
+ $this->addCall('rss', array($link, $p), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function externallink($match, $state, $pos) {
+ $url = $match;
+ $title = null;
+
+ // add protocol on simple short URLs
+ if(substr($url,0,3) == 'ftp' && (substr($url,0,6) != 'ftp://')){
+ $title = $url;
+ $url = 'ftp://'.$url;
+ }
+ if(substr($url,0,3) == 'www' && (substr($url,0,7) != 'http://')){
+ $title = $url;
+ $url = 'http://'.$url;
+ }
+
+ $this->addCall('externallink', array($url, $title), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function emaillink($match, $state, $pos) {
+ $email = preg_replace(array('/^</','/>$/'),'',$match);
+ $this->addCall('emaillink', array($email, null), $pos);
+ return true;
+ }
+
+ /**
+ * @param string $match matched syntax
+ * @param int $state a LEXER_STATE_* constant
+ * @param int $pos byte position in the original source file
+ * @return bool mode handled?
+ */
+ public function table($match, $state, $pos) {
+ switch ( $state ) {
+
+ case DOKU_LEXER_ENTER:
+
+ $this->callWriter = new Table($this->callWriter);
+
+ $this->addCall('table_start', array($pos + 1), $pos);
+ if ( trim($match) == '^' ) {
+ $this->addCall('tableheader', array(), $pos);
+ } else {
+ $this->addCall('tablecell', array(), $pos);
+ }
+ break;
+
+ case DOKU_LEXER_EXIT:
+ $this->addCall('table_end', array($pos), $pos);
+ /** @var Table $reWriter */
+ $reWriter = $this->callWriter;
+ $this->callWriter = $reWriter->process();
+ break;
+
+ case DOKU_LEXER_UNMATCHED:
+ if ( trim($match) != '' ) {
+ $this->addCall('cdata', array($match), $pos);
+ }
+ break;
+
+ case DOKU_LEXER_MATCHED:
+ if ( $match == ' ' ){
+ $this->addCall('cdata', array($match), $pos);
+ } else if ( preg_match('/:::/',$match) ) {
+ $this->addCall('rowspan', array($match), $pos);
+ } else if ( preg_match('/\t+/',$match) ) {
+ $this->addCall('table_align', array($match), $pos);
+ } else if ( preg_match('/ {2,}/',$match) ) {
+ $this->addCall('table_align', array($match), $pos);
+ } else if ( $match == "\n|" ) {
+ $this->addCall('table_row', array(), $pos);
+ $this->addCall('tablecell', array(), $pos);
+ } else if ( $match == "\n^" ) {
+ $this->addCall('table_row', array(), $pos);
+ $this->addCall('tableheader', array(), $pos);
+ } else if ( $match == '|' ) {
+ $this->addCall('tablecell', array(), $pos);
+ } else if ( $match == '^' ) {
+ $this->addCall('tableheader', array(), $pos);
+ }
+ break;
+ }
+ return true;
+ }
+
+ // endregion modes
+}
+
+//------------------------------------------------------------------------
+function Doku_Handler_Parse_Media($match) {
+
+ // Strip the opening and closing markup
+ $link = preg_replace(array('/^\{\{/','/\}\}$/u'),'',$match);
+
+ // Split title from URL
+ $link = explode('|',$link,2);
+
+ // Check alignment
+ $ralign = (bool)preg_match('/^ /',$link[0]);
+ $lalign = (bool)preg_match('/ $/',$link[0]);
+
+ // Logic = what's that ;)...
+ if ( $lalign & $ralign ) {
+ $align = 'center';
+ } else if ( $ralign ) {
+ $align = 'right';
+ } else if ( $lalign ) {
+ $align = 'left';
+ } else {
+ $align = null;
+ }
+
+ // The title...
+ if ( !isset($link[1]) ) {
+ $link[1] = null;
+ }
+
+ //remove aligning spaces
+ $link[0] = trim($link[0]);
+
+ //split into src and parameters (using the very last questionmark)
+ $pos = strrpos($link[0], '?');
+ if($pos !== false){
+ $src = substr($link[0],0,$pos);
+ $param = substr($link[0],$pos+1);
+ }else{
+ $src = $link[0];
+ $param = '';
+ }
+
+ //parse width and height
+ if(preg_match('#(\d+)(x(\d+))?#i',$param,$size)){
+ !empty($size[1]) ? $w = $size[1] : $w = null;
+ !empty($size[3]) ? $h = $size[3] : $h = null;
+ } else {
+ $w = null;
+ $h = null;
+ }
+
+ //get linking command
+ if(preg_match('/nolink/i',$param)){
+ $linking = 'nolink';
+ }else if(preg_match('/direct/i',$param)){
+ $linking = 'direct';
+ }else if(preg_match('/linkonly/i',$param)){
+ $linking = 'linkonly';
+ }else{
+ $linking = 'details';
+ }
+
+ //get caching command
+ if (preg_match('/(nocache|recache)/i',$param,$cachemode)){
+ $cache = $cachemode[1];
+ }else{
+ $cache = 'cache';
+ }
+
+ // Check whether this is a local or remote image or interwiki
+ if (media_isexternal($src) || link_isinterwiki($src)){
+ $call = 'externalmedia';
+ } else {
+ $call = 'internalmedia';
+ }
+
+ $params = array(
+ 'type'=>$call,
+ 'src'=>$src,
+ 'title'=>$link[1],
+ 'align'=>$align,
+ 'width'=>$w,
+ 'height'=>$h,
+ 'cache'=>$cache,
+ 'linking'=>$linking,
+ );
+
+ return $params;
+}
+
diff --git a/platform/www/inc/parser/metadata.php b/platform/www/inc/parser/metadata.php
new file mode 100644
index 0000000..849fffe
--- /dev/null
+++ b/platform/www/inc/parser/metadata.php
@@ -0,0 +1,751 @@
+<?php
+/**
+ * The MetaData Renderer
+ *
+ * Metadata is additional information about a DokuWiki page that gets extracted mainly from the page's content
+ * but also it's own filesystem data (like the creation time). All metadata is stored in the fields $meta and
+ * $persistent.
+ *
+ * Some simplified rendering to $doc is done to gather the page's (text-only) abstract.
+ *
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+class Doku_Renderer_metadata extends Doku_Renderer
+{
+ /** the approximate byte lenght to capture for the abstract */
+ const ABSTRACT_LEN = 250;
+
+ /** the maximum UTF8 character length for the abstract */
+ const ABSTRACT_MAX = 500;
+
+ /** @var array transient meta data, will be reset on each rendering */
+ public $meta = array();
+
+ /** @var array persistent meta data, will be kept until explicitly deleted */
+ public $persistent = array();
+
+ /** @var array the list of headers used to create unique link ids */
+ protected $headers = array();
+
+ /** @var string temporary $doc store */
+ protected $store = '';
+
+ /** @var string keeps the first image reference */
+ protected $firstimage = '';
+
+ /** @var bool whether or not data is being captured for the abstract, public to be accessible by plugins */
+ public $capturing = true;
+
+ /** @var bool determines if enough data for the abstract was collected, yet */
+ public $capture = true;
+
+ /** @var int number of bytes captured for abstract */
+ protected $captured = 0;
+
+ /**
+ * Returns the format produced by this renderer.
+ *
+ * @return string always 'metadata'
+ */
+ public function getFormat()
+ {
+ return 'metadata';
+ }
+
+ /**
+ * Initialize the document
+ *
+ * Sets up some of the persistent info about the page if it doesn't exist, yet.
+ */
+ public function document_start()
+ {
+ global $ID;
+
+ $this->headers = array();
+
+ // external pages are missing create date
+ if (!isset($this->persistent['date']['created']) || !$this->persistent['date']['created']) {
+ $this->persistent['date']['created'] = filectime(wikiFN($ID));
+ }
+ if (!isset($this->persistent['user'])) {
+ $this->persistent['user'] = '';
+ }
+ if (!isset($this->persistent['creator'])) {
+ $this->persistent['creator'] = '';
+ }
+ // reset metadata to persistent values
+ $this->meta = $this->persistent;
+ }
+
+ /**
+ * Finalize the document
+ *
+ * Stores collected data in the metadata
+ */
+ public function document_end()
+ {
+ global $ID;
+
+ // store internal info in metadata (notoc,nocache)
+ $this->meta['internal'] = $this->info;
+
+ if (!isset($this->meta['description']['abstract'])) {
+ // cut off too long abstracts
+ $this->doc = trim($this->doc);
+ if (strlen($this->doc) > self::ABSTRACT_MAX) {
+ $this->doc = \dokuwiki\Utf8\PhpString::substr($this->doc, 0, self::ABSTRACT_MAX).'…';
+ }
+ $this->meta['description']['abstract'] = $this->doc;
+ }
+
+ $this->meta['relation']['firstimage'] = $this->firstimage;
+
+ if (!isset($this->meta['date']['modified'])) {
+ $this->meta['date']['modified'] = filemtime(wikiFN($ID));
+ }
+ }
+
+ /**
+ * Render plain text data
+ *
+ * This function takes care of the amount captured data and will stop capturing when
+ * enough abstract data is available
+ *
+ * @param $text
+ */
+ public function cdata($text)
+ {
+ if (!$this->capture || !$this->capturing) {
+ return;
+ }
+
+ $this->doc .= $text;
+
+ $this->captured += strlen($text);
+ if ($this->captured > self::ABSTRACT_LEN) {
+ $this->capture = false;
+ }
+ }
+
+ /**
+ * Add an item to the TOC
+ *
+ * @param string $id the hash link
+ * @param string $text the text to display
+ * @param int $level the nesting level
+ */
+ public function toc_additem($id, $text, $level)
+ {
+ global $conf;
+
+ //only add items within configured levels
+ if ($level >= $conf['toptoclevel'] && $level <= $conf['maxtoclevel']) {
+ // the TOC is one of our standard ul list arrays ;-)
+ $this->meta['description']['tableofcontents'][] = array(
+ 'hid' => $id,
+ 'title' => $text,
+ 'type' => 'ul',
+ 'level' => $level - $conf['toptoclevel'] + 1
+ );
+ }
+ }
+
+ /**
+ * Render a heading
+ *
+ * @param string $text the text to display
+ * @param int $level header level
+ * @param int $pos byte position in the original source
+ */
+ public function header($text, $level, $pos)
+ {
+ if (!isset($this->meta['title'])) {
+ $this->meta['title'] = $text;
+ }
+
+ // add the header to the TOC
+ $hid = $this->_headerToLink($text, true);
+ $this->toc_additem($hid, $text, $level);
+
+ // add to summary
+ $this->cdata(DOKU_LF.$text.DOKU_LF);
+ }
+
+ /**
+ * Open a paragraph
+ */
+ public function p_open()
+ {
+ $this->cdata(DOKU_LF);
+ }
+
+ /**
+ * Close a paragraph
+ */
+ public function p_close()
+ {
+ $this->cdata(DOKU_LF);
+ }
+
+ /**
+ * Create a line break
+ */
+ public function linebreak()
+ {
+ $this->cdata(DOKU_LF);
+ }
+
+ /**
+ * Create a horizontal line
+ */
+ public function hr()
+ {
+ $this->cdata(DOKU_LF.'----------'.DOKU_LF);
+ }
+
+ /**
+ * Callback for footnote start syntax
+ *
+ * All following content will go to the footnote instead of
+ * the document. To achieve this the previous rendered content
+ * is moved to $store and $doc is cleared
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function footnote_open()
+ {
+ if ($this->capture) {
+ // move current content to store
+ // this is required to ensure safe behaviour of plugins accessed within footnotes
+ $this->store = $this->doc;
+ $this->doc = '';
+
+ // disable capturing
+ $this->capturing = false;
+ }
+ }
+
+ /**
+ * Callback for footnote end syntax
+ *
+ * All content rendered whilst within footnote syntax mode is discarded,
+ * the previously rendered content is restored and capturing is re-enabled.
+ *
+ * @author Andreas Gohr
+ */
+ public function footnote_close()
+ {
+ if ($this->capture) {
+ // re-enable capturing
+ $this->capturing = true;
+ // restore previously rendered content
+ $this->doc = $this->store;
+ $this->store = '';
+ }
+ }
+
+ /**
+ * Open an unordered list
+ */
+ public function listu_open()
+ {
+ $this->cdata(DOKU_LF);
+ }
+
+ /**
+ * Open an ordered list
+ */
+ public function listo_open()
+ {
+ $this->cdata(DOKU_LF);
+ }
+
+ /**
+ * Open a list item
+ *
+ * @param int $level the nesting level
+ * @param bool $node true when a node; false when a leaf
+ */
+ public function listitem_open($level, $node=false)
+ {
+ $this->cdata(str_repeat(DOKU_TAB, $level).'* ');
+ }
+
+ /**
+ * Close a list item
+ */
+ public function listitem_close()
+ {
+ $this->cdata(DOKU_LF);
+ }
+
+ /**
+ * Output preformatted text
+ *
+ * @param string $text
+ */
+ public function preformatted($text)
+ {
+ $this->cdata($text);
+ }
+
+ /**
+ * Start a block quote
+ */
+ public function quote_open()
+ {
+ $this->cdata(DOKU_LF.DOKU_TAB.'"');
+ }
+
+ /**
+ * Stop a block quote
+ */
+ public function quote_close()
+ {
+ $this->cdata('"'.DOKU_LF);
+ }
+
+ /**
+ * Display text as file content, optionally syntax highlighted
+ *
+ * @param string $text text to show
+ * @param string $lang programming language to use for syntax highlighting
+ * @param string $file file path label
+ */
+ public function file($text, $lang = null, $file = null)
+ {
+ $this->cdata(DOKU_LF.$text.DOKU_LF);
+ }
+
+ /**
+ * Display text as code content, optionally syntax highlighted
+ *
+ * @param string $text text to show
+ * @param string $language programming language to use for syntax highlighting
+ * @param string $file file path label
+ */
+ public function code($text, $language = null, $file = null)
+ {
+ $this->cdata(DOKU_LF.$text.DOKU_LF);
+ }
+
+ /**
+ * Format an acronym
+ *
+ * Uses $this->acronyms
+ *
+ * @param string $acronym
+ */
+ public function acronym($acronym)
+ {
+ $this->cdata($acronym);
+ }
+
+ /**
+ * Format a smiley
+ *
+ * Uses $this->smiley
+ *
+ * @param string $smiley
+ */
+ public function smiley($smiley)
+ {
+ $this->cdata($smiley);
+ }
+
+ /**
+ * Format an entity
+ *
+ * Entities are basically small text replacements
+ *
+ * Uses $this->entities
+ *
+ * @param string $entity
+ */
+ public function entity($entity)
+ {
+ $this->cdata($entity);
+ }
+
+ /**
+ * Typographically format a multiply sign
+ *
+ * Example: ($x=640, $y=480) should result in "640×480"
+ *
+ * @param string|int $x first value
+ * @param string|int $y second value
+ */
+ public function multiplyentity($x, $y)
+ {
+ $this->cdata($x.'×'.$y);
+ }
+
+ /**
+ * Render an opening single quote char (language specific)
+ */
+ public function singlequoteopening()
+ {
+ global $lang;
+ $this->cdata($lang['singlequoteopening']);
+ }
+
+ /**
+ * Render a closing single quote char (language specific)
+ */
+ public function singlequoteclosing()
+ {
+ global $lang;
+ $this->cdata($lang['singlequoteclosing']);
+ }
+
+ /**
+ * Render an apostrophe char (language specific)
+ */
+ public function apostrophe()
+ {
+ global $lang;
+ $this->cdata($lang['apostrophe']);
+ }
+
+ /**
+ * Render an opening double quote char (language specific)
+ */
+ public function doublequoteopening()
+ {
+ global $lang;
+ $this->cdata($lang['doublequoteopening']);
+ }
+
+ /**
+ * Render an closinging double quote char (language specific)
+ */
+ public function doublequoteclosing()
+ {
+ global $lang;
+ $this->cdata($lang['doublequoteclosing']);
+ }
+
+ /**
+ * Render a CamelCase link
+ *
+ * @param string $link The link name
+ * @see http://en.wikipedia.org/wiki/CamelCase
+ */
+ public function camelcaselink($link)
+ {
+ $this->internallink($link, $link);
+ }
+
+ /**
+ * Render a page local link
+ *
+ * @param string $hash hash link identifier
+ * @param string $name name for the link
+ */
+ public function locallink($hash, $name = null)
+ {
+ if (is_array($name)) {
+ $this->_firstimage($name['src']);
+ if ($name['type'] == 'internalmedia') {
+ $this->_recordMediaUsage($name['src']);
+ }
+ }
+ }
+
+ /**
+ * keep track of internal links in $this->meta['relation']['references']
+ *
+ * @param string $id page ID to link to. eg. 'wiki:syntax'
+ * @param string|array|null $name name for the link, array for media file
+ */
+ public function internallink($id, $name = null)
+ {
+ global $ID;
+
+ if (is_array($name)) {
+ $this->_firstimage($name['src']);
+ if ($name['type'] == 'internalmedia') {
+ $this->_recordMediaUsage($name['src']);
+ }
+ }
+
+ $parts = explode('?', $id, 2);
+ if (count($parts) === 2) {
+ $id = $parts[0];
+ }
+
+ $default = $this->_simpleTitle($id);
+
+ // first resolve and clean up the $id
+ resolve_pageid(getNS($ID), $id, $exists);
+ @list($page) = explode('#', $id, 2);
+
+ // set metadata
+ $this->meta['relation']['references'][$page] = $exists;
+ // $data = array('relation' => array('isreferencedby' => array($ID => true)));
+ // p_set_metadata($id, $data);
+
+ // add link title to summary
+ if ($this->capture) {
+ $name = $this->_getLinkTitle($name, $default, $id);
+ $this->doc .= $name;
+ }
+ }
+
+ /**
+ * Render an external link
+ *
+ * @param string $url full URL with scheme
+ * @param string|array|null $name name for the link, array for media file
+ */
+ public function externallink($url, $name = null)
+ {
+ if (is_array($name)) {
+ $this->_firstimage($name['src']);
+ if ($name['type'] == 'internalmedia') {
+ $this->_recordMediaUsage($name['src']);
+ }
+ }
+
+ if ($this->capture) {
+ $this->doc .= $this->_getLinkTitle($name, '<'.$url.'>');
+ }
+ }
+
+ /**
+ * Render an interwiki link
+ *
+ * You may want to use $this->_resolveInterWiki() here
+ *
+ * @param string $match original link - probably not much use
+ * @param string|array $name name for the link, array for media file
+ * @param string $wikiName indentifier (shortcut) for the remote wiki
+ * @param string $wikiUri the fragment parsed from the original link
+ */
+ public function interwikilink($match, $name, $wikiName, $wikiUri)
+ {
+ if (is_array($name)) {
+ $this->_firstimage($name['src']);
+ if ($name['type'] == 'internalmedia') {
+ $this->_recordMediaUsage($name['src']);
+ }
+ }
+
+ if ($this->capture) {
+ list($wikiUri) = explode('#', $wikiUri, 2);
+ $name = $this->_getLinkTitle($name, $wikiUri);
+ $this->doc .= $name;
+ }
+ }
+
+ /**
+ * Link to windows share
+ *
+ * @param string $url the link
+ * @param string|array $name name for the link, array for media file
+ */
+ public function windowssharelink($url, $name = null)
+ {
+ if (is_array($name)) {
+ $this->_firstimage($name['src']);
+ if ($name['type'] == 'internalmedia') {
+ $this->_recordMediaUsage($name['src']);
+ }
+ }
+
+ if ($this->capture) {
+ if ($name) {
+ $this->doc .= $name;
+ } else {
+ $this->doc .= '<'.$url.'>';
+ }
+ }
+ }
+
+ /**
+ * Render a linked E-Mail Address
+ *
+ * Should honor $conf['mailguard'] setting
+ *
+ * @param string $address Email-Address
+ * @param string|array $name name for the link, array for media file
+ */
+ public function emaillink($address, $name = null)
+ {
+ if (is_array($name)) {
+ $this->_firstimage($name['src']);
+ if ($name['type'] == 'internalmedia') {
+ $this->_recordMediaUsage($name['src']);
+ }
+ }
+
+ if ($this->capture) {
+ if ($name) {
+ $this->doc .= $name;
+ } else {
+ $this->doc .= '<'.$address.'>';
+ }
+ }
+ }
+
+ /**
+ * Render an internal media file
+ *
+ * @param string $src media ID
+ * @param string $title descriptive text
+ * @param string $align left|center|right
+ * @param int $width width of media in pixel
+ * @param int $height height of media in pixel
+ * @param string $cache cache|recache|nocache
+ * @param string $linking linkonly|detail|nolink
+ */
+ public function internalmedia($src, $title = null, $align = null, $width = null,
+ $height = null, $cache = null, $linking = null)
+ {
+ if ($this->capture && $title) {
+ $this->doc .= '['.$title.']';
+ }
+ $this->_firstimage($src);
+ $this->_recordMediaUsage($src);
+ }
+
+ /**
+ * Render an external media file
+ *
+ * @param string $src full media URL
+ * @param string $title descriptive text
+ * @param string $align left|center|right
+ * @param int $width width of media in pixel
+ * @param int $height height of media in pixel
+ * @param string $cache cache|recache|nocache
+ * @param string $linking linkonly|detail|nolink
+ */
+ public function externalmedia($src, $title = null, $align = null, $width = null,
+ $height = null, $cache = null, $linking = null)
+ {
+ if ($this->capture && $title) {
+ $this->doc .= '['.$title.']';
+ }
+ $this->_firstimage($src);
+ }
+
+ /**
+ * Render the output of an RSS feed
+ *
+ * @param string $url URL of the feed
+ * @param array $params Finetuning of the output
+ */
+ public function rss($url, $params)
+ {
+ $this->meta['relation']['haspart'][$url] = true;
+
+ $this->meta['date']['valid']['age'] =
+ isset($this->meta['date']['valid']['age']) ?
+ min($this->meta['date']['valid']['age'], $params['refresh']) :
+ $params['refresh'];
+ }
+
+ #region Utils
+
+ /**
+ * Removes any Namespace from the given name but keeps
+ * casing and special chars
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $name
+ *
+ * @return mixed|string
+ */
+ public function _simpleTitle($name)
+ {
+ global $conf;
+
+ if (is_array($name)) {
+ return '';
+ }
+
+ if ($conf['useslash']) {
+ $nssep = '[:;/]';
+ } else {
+ $nssep = '[:;]';
+ }
+ $name = preg_replace('!.*'.$nssep.'!', '', $name);
+ //if there is a hash we use the anchor name only
+ $name = preg_replace('!.*#!', '', $name);
+ return $name;
+ }
+
+ /**
+ * Construct a title and handle images in titles
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @param string|array|null $title either string title or media array
+ * @param string $default default title if nothing else is found
+ * @param null|string $id linked page id (used to extract title from first heading)
+ * @return string title text
+ */
+ public function _getLinkTitle($title, $default, $id = null)
+ {
+ if (is_array($title)) {
+ if ($title['title']) {
+ return '['.$title['title'].']';
+ } else {
+ return $default;
+ }
+ } elseif (is_null($title) || trim($title) == '') {
+ if (useHeading('content') && $id) {
+ $heading = p_get_first_heading($id, METADATA_DONT_RENDER);
+ if ($heading) {
+ return $heading;
+ }
+ }
+ return $default;
+ } else {
+ return $title;
+ }
+ }
+
+ /**
+ * Remember first image
+ *
+ * @param string $src image URL or ID
+ */
+ protected function _firstimage($src)
+ {
+ global $ID;
+
+ if ($this->firstimage) {
+ return;
+ }
+
+ list($src) = explode('#', $src, 2);
+ if (!media_isexternal($src)) {
+ resolve_mediaid(getNS($ID), $src, $exists);
+ }
+ if (preg_match('/.(jpe?g|gif|png)$/i', $src)) {
+ $this->firstimage = $src;
+ }
+ }
+
+ /**
+ * Store list of used media files in metadata
+ *
+ * @param string $src media ID
+ */
+ protected function _recordMediaUsage($src)
+ {
+ global $ID;
+
+ list ($src) = explode('#', $src, 2);
+ if (media_isexternal($src)) {
+ return;
+ }
+ resolve_mediaid(getNS($ID), $src, $exists);
+ $this->meta['relation']['media'][$src] = $exists;
+ }
+
+ #endregion
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/inc/parser/parser.php b/platform/www/inc/parser/parser.php
new file mode 100644
index 0000000..aee82f0
--- /dev/null
+++ b/platform/www/inc/parser/parser.php
@@ -0,0 +1,99 @@
+<?php
+
+use dokuwiki\Debug\PropertyDeprecationHelper;
+
+/**
+ * Define various types of modes used by the parser - they are used to
+ * populate the list of modes another mode accepts
+ */
+global $PARSER_MODES;
+$PARSER_MODES = array(
+ // containers are complex modes that can contain many other modes
+ // hr breaks the principle but they shouldn't be used in tables / lists
+ // so they are put here
+ 'container' => array('listblock', 'table', 'quote', 'hr'),
+
+ // some mode are allowed inside the base mode only
+ 'baseonly' => array('header'),
+
+ // modes for styling text -- footnote behaves similar to styling
+ 'formatting' => array(
+ 'strong', 'emphasis', 'underline', 'monospace',
+ 'subscript', 'superscript', 'deleted', 'footnote'
+ ),
+
+ // modes where the token is simply replaced - they can not contain any
+ // other modes
+ 'substition' => array(
+ 'acronym', 'smiley', 'wordblock', 'entity',
+ 'camelcaselink', 'internallink', 'media',
+ 'externallink', 'linebreak', 'emaillink',
+ 'windowssharelink', 'filelink', 'notoc',
+ 'nocache', 'multiplyentity', 'quotes', 'rss'
+ ),
+
+ // modes which have a start and end token but inside which
+ // no other modes should be applied
+ 'protected' => array('preformatted', 'code', 'file', 'php', 'html', 'htmlblock', 'phpblock'),
+
+ // inside this mode no wiki markup should be applied but lineendings
+ // and whitespace isn't preserved
+ 'disabled' => array('unformatted'),
+
+ // used to mark paragraph boundaries
+ 'paragraphs' => array('eol')
+);
+
+/**
+ * Class Doku_Parser
+ *
+ * @deprecated 2018-05-04
+ */
+class Doku_Parser extends \dokuwiki\Parsing\Parser {
+ use PropertyDeprecationHelper {
+ __set as protected deprecationHelperMagicSet;
+ __get as protected deprecationHelperMagicGet;
+ }
+
+ /** @inheritdoc */
+ public function __construct(Doku_Handler $handler = null) {
+ dbg_deprecated(\dokuwiki\Parsing\Parser::class);
+ $this->deprecatePublicProperty('modes', __CLASS__);
+ $this->deprecatePublicProperty('connected', __CLASS__);
+
+ if ($handler === null) {
+ $handler = new Doku_Handler();
+ }
+
+ parent::__construct($handler);
+ }
+
+ public function __set($name, $value)
+ {
+
+ if ($name === 'Handler') {
+ $this->handler = $value;
+ return;
+ }
+
+ if ($name === 'Lexer') {
+ $this->lexer = $value;
+ return;
+ }
+
+ $this->deprecationHelperMagicSet($name, $value);
+ }
+
+ public function __get($name)
+ {
+ if ($name === 'Handler') {
+ return $this->handler;
+ }
+
+ if ($name === 'Lexer') {
+ return $this->lexer;
+ }
+
+ return $this->deprecationHelperMagicGet($name);
+ }
+}
diff --git a/platform/www/inc/parser/renderer.php b/platform/www/inc/parser/renderer.php
new file mode 100644
index 0000000..e4eff2a
--- /dev/null
+++ b/platform/www/inc/parser/renderer.php
@@ -0,0 +1,910 @@
+<?php
+/**
+ * Renderer output base class
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Extension\Plugin;
+use dokuwiki\Extension\SyntaxPlugin;
+
+/**
+ * Allowed chars in $language for code highlighting
+ * @see GeSHi::set_language()
+ */
+define('PREG_PATTERN_VALID_LANGUAGE', '#[^a-zA-Z0-9\-_]#');
+
+/**
+ * An empty renderer, produces no output
+ *
+ * Inherits from dokuwiki\Plugin\DokuWiki_Plugin for giving additional functions to render plugins
+ *
+ * The renderer transforms the syntax instructions created by the parser and handler into the
+ * desired output format. For each instruction a corresponding method defined in this class will
+ * be called. That method needs to produce the desired output for the instruction and add it to the
+ * $doc field. When all instructions are processed, the $doc field contents will be cached by
+ * DokuWiki and sent to the user.
+ */
+abstract class Doku_Renderer extends Plugin {
+ /** @var array Settings, control the behavior of the renderer */
+ public $info = array(
+ 'cache' => true, // may the rendered result cached?
+ 'toc' => true, // render the TOC?
+ );
+
+ /** @var array contains the smiley configuration, set in p_render() */
+ public $smileys = array();
+ /** @var array contains the entity configuration, set in p_render() */
+ public $entities = array();
+ /** @var array contains the acronym configuration, set in p_render() */
+ public $acronyms = array();
+ /** @var array contains the interwiki configuration, set in p_render() */
+ public $interwiki = array();
+
+ /** @var array the list of headers used to create unique link ids */
+ protected $headers = array();
+
+ /**
+ * @var string the rendered document, this will be cached after the renderer ran through
+ */
+ public $doc = '';
+
+ /**
+ * clean out any per-use values
+ *
+ * This is called before each use of the renderer object and should be used to
+ * completely reset the state of the renderer to be reused for a new document
+ */
+ public function reset(){
+ $this->headers = array();
+ $this->doc = '';
+ $this->info['cache'] = true;
+ $this->info['toc'] = true;
+ }
+
+ /**
+ * Allow the plugin to prevent DokuWiki from reusing an instance
+ *
+ * Since most renderer plugins fail to implement Doku_Renderer::reset() we default
+ * to reinstantiating the renderer here
+ *
+ * @return bool false if the plugin has to be instantiated
+ */
+ public function isSingleton() {
+ return false;
+ }
+
+ /**
+ * Returns the format produced by this renderer.
+ *
+ * Has to be overidden by sub classes
+ *
+ * @return string
+ */
+ abstract public function getFormat();
+
+ /**
+ * Disable caching of this renderer's output
+ */
+ public function nocache() {
+ $this->info['cache'] = false;
+ }
+
+ /**
+ * Disable TOC generation for this renderer's output
+ *
+ * This might not be used for certain sub renderer
+ */
+ public function notoc() {
+ $this->info['toc'] = false;
+ }
+
+ /**
+ * Handle plugin rendering
+ *
+ * Most likely this needs NOT to be overwritten by sub classes
+ *
+ * @param string $name Plugin name
+ * @param mixed $data custom data set by handler
+ * @param string $state matched state if any
+ * @param string $match raw matched syntax
+ */
+ public function plugin($name, $data, $state = '', $match = '') {
+ /** @var SyntaxPlugin $plugin */
+ $plugin = plugin_load('syntax', $name);
+ if($plugin != null) {
+ $plugin->render($this->getFormat(), $this, $data);
+ }
+ }
+
+ /**
+ * handle nested render instructions
+ * this method (and nest_close method) should not be overloaded in actual renderer output classes
+ *
+ * @param array $instructions
+ */
+ public function nest($instructions) {
+ foreach($instructions as $instruction) {
+ // execute the callback against ourself
+ if(method_exists($this, $instruction[0])) {
+ call_user_func_array(array($this, $instruction[0]), $instruction[1] ? $instruction[1] : array());
+ }
+ }
+ }
+
+ /**
+ * dummy closing instruction issued by Doku_Handler_Nest
+ *
+ * normally the syntax mode should override this instruction when instantiating Doku_Handler_Nest -
+ * however plugins will not be able to - as their instructions require data.
+ */
+ public function nest_close() {
+ }
+
+ #region Syntax modes - sub classes will need to implement them to fill $doc
+
+ /**
+ * Initialize the document
+ */
+ public function document_start() {
+ }
+
+ /**
+ * Finalize the document
+ */
+ public function document_end() {
+ }
+
+ /**
+ * Render the Table of Contents
+ *
+ * @return string
+ */
+ public function render_TOC() {
+ return '';
+ }
+
+ /**
+ * Add an item to the TOC
+ *
+ * @param string $id the hash link
+ * @param string $text the text to display
+ * @param int $level the nesting level
+ */
+ public function toc_additem($id, $text, $level) {
+ }
+
+ /**
+ * Render a heading
+ *
+ * @param string $text the text to display
+ * @param int $level header level
+ * @param int $pos byte position in the original source
+ */
+ public function header($text, $level, $pos) {
+ }
+
+ /**
+ * Open a new section
+ *
+ * @param int $level section level (as determined by the previous header)
+ */
+ public function section_open($level) {
+ }
+
+ /**
+ * Close the current section
+ */
+ public function section_close() {
+ }
+
+ /**
+ * Render plain text data
+ *
+ * @param string $text
+ */
+ public function cdata($text) {
+ }
+
+ /**
+ * Open a paragraph
+ */
+ public function p_open() {
+ }
+
+ /**
+ * Close a paragraph
+ */
+ public function p_close() {
+ }
+
+ /**
+ * Create a line break
+ */
+ public function linebreak() {
+ }
+
+ /**
+ * Create a horizontal line
+ */
+ public function hr() {
+ }
+
+ /**
+ * Start strong (bold) formatting
+ */
+ public function strong_open() {
+ }
+
+ /**
+ * Stop strong (bold) formatting
+ */
+ public function strong_close() {
+ }
+
+ /**
+ * Start emphasis (italics) formatting
+ */
+ public function emphasis_open() {
+ }
+
+ /**
+ * Stop emphasis (italics) formatting
+ */
+ public function emphasis_close() {
+ }
+
+ /**
+ * Start underline formatting
+ */
+ public function underline_open() {
+ }
+
+ /**
+ * Stop underline formatting
+ */
+ public function underline_close() {
+ }
+
+ /**
+ * Start monospace formatting
+ */
+ public function monospace_open() {
+ }
+
+ /**
+ * Stop monospace formatting
+ */
+ public function monospace_close() {
+ }
+
+ /**
+ * Start a subscript
+ */
+ public function subscript_open() {
+ }
+
+ /**
+ * Stop a subscript
+ */
+ public function subscript_close() {
+ }
+
+ /**
+ * Start a superscript
+ */
+ public function superscript_open() {
+ }
+
+ /**
+ * Stop a superscript
+ */
+ public function superscript_close() {
+ }
+
+ /**
+ * Start deleted (strike-through) formatting
+ */
+ public function deleted_open() {
+ }
+
+ /**
+ * Stop deleted (strike-through) formatting
+ */
+ public function deleted_close() {
+ }
+
+ /**
+ * Start a footnote
+ */
+ public function footnote_open() {
+ }
+
+ /**
+ * Stop a footnote
+ */
+ public function footnote_close() {
+ }
+
+ /**
+ * Open an unordered list
+ */
+ public function listu_open() {
+ }
+
+ /**
+ * Close an unordered list
+ */
+ public function listu_close() {
+ }
+
+ /**
+ * Open an ordered list
+ */
+ public function listo_open() {
+ }
+
+ /**
+ * Close an ordered list
+ */
+ public function listo_close() {
+ }
+
+ /**
+ * Open a list item
+ *
+ * @param int $level the nesting level
+ * @param bool $node true when a node; false when a leaf
+ */
+ public function listitem_open($level,$node=false) {
+ }
+
+ /**
+ * Close a list item
+ */
+ public function listitem_close() {
+ }
+
+ /**
+ * Start the content of a list item
+ */
+ public function listcontent_open() {
+ }
+
+ /**
+ * Stop the content of a list item
+ */
+ public function listcontent_close() {
+ }
+
+ /**
+ * Output unformatted $text
+ *
+ * Defaults to $this->cdata()
+ *
+ * @param string $text
+ */
+ public function unformatted($text) {
+ $this->cdata($text);
+ }
+
+ /**
+ * Output inline PHP code
+ *
+ * If $conf['phpok'] is true this should evaluate the given code and append the result
+ * to $doc
+ *
+ * @param string $text The PHP code
+ */
+ public function php($text) {
+ }
+
+ /**
+ * Output block level PHP code
+ *
+ * If $conf['phpok'] is true this should evaluate the given code and append the result
+ * to $doc
+ *
+ * @param string $text The PHP code
+ */
+ public function phpblock($text) {
+ }
+
+ /**
+ * Output raw inline HTML
+ *
+ * If $conf['htmlok'] is true this should add the code as is to $doc
+ *
+ * @param string $text The HTML
+ */
+ public function html($text) {
+ }
+
+ /**
+ * Output raw block-level HTML
+ *
+ * If $conf['htmlok'] is true this should add the code as is to $doc
+ *
+ * @param string $text The HTML
+ */
+ public function htmlblock($text) {
+ }
+
+ /**
+ * Output preformatted text
+ *
+ * @param string $text
+ */
+ public function preformatted($text) {
+ }
+
+ /**
+ * Start a block quote
+ */
+ public function quote_open() {
+ }
+
+ /**
+ * Stop a block quote
+ */
+ public function quote_close() {
+ }
+
+ /**
+ * Display text as file content, optionally syntax highlighted
+ *
+ * @param string $text text to show
+ * @param string $lang programming language to use for syntax highlighting
+ * @param string $file file path label
+ */
+ public function file($text, $lang = null, $file = null) {
+ }
+
+ /**
+ * Display text as code content, optionally syntax highlighted
+ *
+ * @param string $text text to show
+ * @param string $lang programming language to use for syntax highlighting
+ * @param string $file file path label
+ */
+ public function code($text, $lang = null, $file = null) {
+ }
+
+ /**
+ * Format an acronym
+ *
+ * Uses $this->acronyms
+ *
+ * @param string $acronym
+ */
+ public function acronym($acronym) {
+ }
+
+ /**
+ * Format a smiley
+ *
+ * Uses $this->smiley
+ *
+ * @param string $smiley
+ */
+ public function smiley($smiley) {
+ }
+
+ /**
+ * Format an entity
+ *
+ * Entities are basically small text replacements
+ *
+ * Uses $this->entities
+ *
+ * @param string $entity
+ */
+ public function entity($entity) {
+ }
+
+ /**
+ * Typographically format a multiply sign
+ *
+ * Example: ($x=640, $y=480) should result in "640×480"
+ *
+ * @param string|int $x first value
+ * @param string|int $y second value
+ */
+ public function multiplyentity($x, $y) {
+ }
+
+ /**
+ * Render an opening single quote char (language specific)
+ */
+ public function singlequoteopening() {
+ }
+
+ /**
+ * Render a closing single quote char (language specific)
+ */
+ public function singlequoteclosing() {
+ }
+
+ /**
+ * Render an apostrophe char (language specific)
+ */
+ public function apostrophe() {
+ }
+
+ /**
+ * Render an opening double quote char (language specific)
+ */
+ public function doublequoteopening() {
+ }
+
+ /**
+ * Render an closinging double quote char (language specific)
+ */
+ public function doublequoteclosing() {
+ }
+
+ /**
+ * Render a CamelCase link
+ *
+ * @param string $link The link name
+ * @see http://en.wikipedia.org/wiki/CamelCase
+ */
+ public function camelcaselink($link) {
+ }
+
+ /**
+ * Render a page local link
+ *
+ * @param string $hash hash link identifier
+ * @param string $name name for the link
+ */
+ public function locallink($hash, $name = null) {
+ }
+
+ /**
+ * Render a wiki internal link
+ *
+ * @param string $link page ID to link to. eg. 'wiki:syntax'
+ * @param string|array $title name for the link, array for media file
+ */
+ public function internallink($link, $title = null) {
+ }
+
+ /**
+ * Render an external link
+ *
+ * @param string $link full URL with scheme
+ * @param string|array $title name for the link, array for media file
+ */
+ public function externallink($link, $title = null) {
+ }
+
+ /**
+ * Render the output of an RSS feed
+ *
+ * @param string $url URL of the feed
+ * @param array $params Finetuning of the output
+ */
+ public function rss($url, $params) {
+ }
+
+ /**
+ * Render an interwiki link
+ *
+ * You may want to use $this->_resolveInterWiki() here
+ *
+ * @param string $link original link - probably not much use
+ * @param string|array $title name for the link, array for media file
+ * @param string $wikiName indentifier (shortcut) for the remote wiki
+ * @param string $wikiUri the fragment parsed from the original link
+ */
+ public function interwikilink($link, $title, $wikiName, $wikiUri) {
+ }
+
+ /**
+ * Link to file on users OS
+ *
+ * @param string $link the link
+ * @param string|array $title name for the link, array for media file
+ */
+ public function filelink($link, $title = null) {
+ }
+
+ /**
+ * Link to windows share
+ *
+ * @param string $link the link
+ * @param string|array $title name for the link, array for media file
+ */
+ public function windowssharelink($link, $title = null) {
+ }
+
+ /**
+ * Render a linked E-Mail Address
+ *
+ * Should honor $conf['mailguard'] setting
+ *
+ * @param string $address Email-Address
+ * @param string|array $name name for the link, array for media file
+ */
+ public function emaillink($address, $name = null) {
+ }
+
+ /**
+ * Render an internal media file
+ *
+ * @param string $src media ID
+ * @param string $title descriptive text
+ * @param string $align left|center|right
+ * @param int $width width of media in pixel
+ * @param int $height height of media in pixel
+ * @param string $cache cache|recache|nocache
+ * @param string $linking linkonly|detail|nolink
+ */
+ public function internalmedia($src, $title = null, $align = null, $width = null,
+ $height = null, $cache = null, $linking = null) {
+ }
+
+ /**
+ * Render an external media file
+ *
+ * @param string $src full media URL
+ * @param string $title descriptive text
+ * @param string $align left|center|right
+ * @param int $width width of media in pixel
+ * @param int $height height of media in pixel
+ * @param string $cache cache|recache|nocache
+ * @param string $linking linkonly|detail|nolink
+ */
+ public function externalmedia($src, $title = null, $align = null, $width = null,
+ $height = null, $cache = null, $linking = null) {
+ }
+
+ /**
+ * Render a link to an internal media file
+ *
+ * @param string $src media ID
+ * @param string $title descriptive text
+ * @param string $align left|center|right
+ * @param int $width width of media in pixel
+ * @param int $height height of media in pixel
+ * @param string $cache cache|recache|nocache
+ */
+ public function internalmedialink($src, $title = null, $align = null,
+ $width = null, $height = null, $cache = null) {
+ }
+
+ /**
+ * Render a link to an external media file
+ *
+ * @param string $src media ID
+ * @param string $title descriptive text
+ * @param string $align left|center|right
+ * @param int $width width of media in pixel
+ * @param int $height height of media in pixel
+ * @param string $cache cache|recache|nocache
+ */
+ public function externalmedialink($src, $title = null, $align = null,
+ $width = null, $height = null, $cache = null) {
+ }
+
+ /**
+ * Start a table
+ *
+ * @param int $maxcols maximum number of columns
+ * @param int $numrows NOT IMPLEMENTED
+ * @param int $pos byte position in the original source
+ */
+ public function table_open($maxcols = null, $numrows = null, $pos = null) {
+ }
+
+ /**
+ * Close a table
+ *
+ * @param int $pos byte position in the original source
+ */
+ public function table_close($pos = null) {
+ }
+
+ /**
+ * Open a table header
+ */
+ public function tablethead_open() {
+ }
+
+ /**
+ * Close a table header
+ */
+ public function tablethead_close() {
+ }
+
+ /**
+ * Open a table body
+ */
+ public function tabletbody_open() {
+ }
+
+ /**
+ * Close a table body
+ */
+ public function tabletbody_close() {
+ }
+
+ /**
+ * Open a table footer
+ */
+ public function tabletfoot_open() {
+ }
+
+ /**
+ * Close a table footer
+ */
+ public function tabletfoot_close() {
+ }
+
+ /**
+ * Open a table row
+ */
+ public function tablerow_open() {
+ }
+
+ /**
+ * Close a table row
+ */
+ public function tablerow_close() {
+ }
+
+ /**
+ * Open a table header cell
+ *
+ * @param int $colspan
+ * @param string $align left|center|right
+ * @param int $rowspan
+ */
+ public function tableheader_open($colspan = 1, $align = null, $rowspan = 1) {
+ }
+
+ /**
+ * Close a table header cell
+ */
+ public function tableheader_close() {
+ }
+
+ /**
+ * Open a table cell
+ *
+ * @param int $colspan
+ * @param string $align left|center|right
+ * @param int $rowspan
+ */
+ public function tablecell_open($colspan = 1, $align = null, $rowspan = 1) {
+ }
+
+ /**
+ * Close a table cell
+ */
+ public function tablecell_close() {
+ }
+
+ #endregion
+
+ #region util functions, you probably won't need to reimplement them
+
+ /**
+ * Creates a linkid from a headline
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $title The headline title
+ * @param boolean $create Create a new unique ID?
+ * @return string
+ */
+ public function _headerToLink($title, $create = false) {
+ if($create) {
+ return sectionID($title, $this->headers);
+ } else {
+ $check = false;
+ return sectionID($title, $check);
+ }
+ }
+
+ /**
+ * Removes any Namespace from the given name but keeps
+ * casing and special chars
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $name
+ * @return string
+ */
+ public function _simpleTitle($name) {
+ global $conf;
+
+ //if there is a hash we use the ancor name only
+ @list($name, $hash) = explode('#', $name, 2);
+ if($hash) return $hash;
+
+ if($conf['useslash']) {
+ $name = strtr($name, ';/', ';:');
+ } else {
+ $name = strtr($name, ';', ':');
+ }
+
+ return noNSorNS($name);
+ }
+
+ /**
+ * Resolve an interwikilink
+ *
+ * @param string $shortcut identifier for the interwiki link
+ * @param string $reference fragment that refers the content
+ * @param null|bool $exists reference which returns if an internal page exists
+ * @return string interwikilink
+ */
+ public function _resolveInterWiki(&$shortcut, $reference, &$exists = null) {
+ //get interwiki URL
+ if(isset($this->interwiki[$shortcut])) {
+ $url = $this->interwiki[$shortcut];
+ }elseif(isset($this->interwiki['default'])) {
+ $shortcut = 'default';
+ $url = $this->interwiki[$shortcut];
+ }else{
+ // not parsable interwiki outputs '' to make sure string manipluation works
+ $shortcut = '';
+ $url = '';
+ }
+
+ //split into hash and url part
+ $hash = strrchr($reference, '#');
+ if($hash) {
+ $reference = substr($reference, 0, -strlen($hash));
+ $hash = substr($hash, 1);
+ }
+
+ //replace placeholder
+ if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#', $url)) {
+ //use placeholders
+ $url = str_replace('{URL}', rawurlencode($reference), $url);
+ //wiki names will be cleaned next, otherwise urlencode unsafe chars
+ $url = str_replace('{NAME}', ($url[0] === ':') ? $reference :
+ preg_replace_callback('/[[\\\\\]^`{|}#%]/', function($match) {
+ return rawurlencode($match[0]);
+ }, $reference), $url);
+ $parsed = parse_url($reference);
+ if (empty($parsed['scheme'])) $parsed['scheme'] = '';
+ if (empty($parsed['host'])) $parsed['host'] = '';
+ if (empty($parsed['port'])) $parsed['port'] = 80;
+ if (empty($parsed['path'])) $parsed['path'] = '';
+ if (empty($parsed['query'])) $parsed['query'] = '';
+ $url = strtr($url,[
+ '{SCHEME}' => $parsed['scheme'],
+ '{HOST}' => $parsed['host'],
+ '{PORT}' => $parsed['port'],
+ '{PATH}' => $parsed['path'],
+ '{QUERY}' => $parsed['query'] ,
+ ]);
+ } else if($url != '') {
+ // make sure when no url is defined, we keep it null
+ // default
+ $url = $url.rawurlencode($reference);
+ }
+ //handle as wiki links
+ if($url[0] === ':') {
+ $urlparam = null;
+ $id = $url;
+ if (strpos($url, '?') !== false) {
+ list($id, $urlparam) = explode('?', $url, 2);
+ }
+ $url = wl(cleanID($id), $urlparam);
+ $exists = page_exists($id);
+ }
+ if($hash) $url .= '#'.rawurlencode($hash);
+
+ return $url;
+ }
+
+ #endregion
+}
+
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/inc/parser/xhtml.php b/platform/www/inc/parser/xhtml.php
new file mode 100644
index 0000000..a135130
--- /dev/null
+++ b/platform/www/inc/parser/xhtml.php
@@ -0,0 +1,1999 @@
+<?php
+
+use dokuwiki\ChangeLog\MediaChangeLog;
+
+/**
+ * Renderer for XHTML output
+ *
+ * This is DokuWiki's main renderer used to display page content in the wiki
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ */
+class Doku_Renderer_xhtml extends Doku_Renderer {
+ /** @var array store the table of contents */
+ public $toc = array();
+
+ /** @var array A stack of section edit data */
+ protected $sectionedits = array();
+
+ /** @var string|int link pages and media against this revision */
+ public $date_at = '';
+
+ /** @var int last section edit id, used by startSectionEdit */
+ protected $lastsecid = 0;
+
+ /** @var array a list of footnotes, list starts at 1! */
+ protected $footnotes = array();
+
+ /** @var int current section level */
+ protected $lastlevel = 0;
+ /** @var array section node tracker */
+ protected $node = array(0, 0, 0, 0, 0);
+
+ /** @var string temporary $doc store */
+ protected $store = '';
+
+ /** @var array global counter, for table classes etc. */
+ protected $_counter = array(); //
+
+ /** @var int counts the code and file blocks, used to provide download links */
+ protected $_codeblock = 0;
+
+ /** @var array list of allowed URL schemes */
+ protected $schemes = null;
+
+ /**
+ * Register a new edit section range
+ *
+ * @param int $start The byte position for the edit start
+ * @param array $data Associative array with section data:
+ * Key 'name': the section name/title
+ * Key 'target': the target for the section edit,
+ * e.g. 'section' or 'table'
+ * Key 'hid': header id
+ * Key 'codeblockOffset': actual code block index
+ * Key 'start': set in startSectionEdit(),
+ * do not set yourself
+ * Key 'range': calculated from 'start' and
+ * $key in finishSectionEdit(),
+ * do not set yourself
+ * @return string A marker class for the starting HTML element
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+ public function startSectionEdit($start, $data) {
+ if (!is_array($data)) {
+ msg(
+ sprintf(
+ 'startSectionEdit: $data "%s" is NOT an array! One of your plugins needs an update.',
+ hsc((string) $data)
+ ), -1
+ );
+
+ // @deprecated 2018-04-14, backward compatibility
+ $args = func_get_args();
+ $data = array();
+ if(isset($args[1])) $data['target'] = $args[1];
+ if(isset($args[2])) $data['name'] = $args[2];
+ if(isset($args[3])) $data['hid'] = $args[3];
+ }
+ $data['secid'] = ++$this->lastsecid;
+ $data['start'] = $start;
+ $this->sectionedits[] = $data;
+ return 'sectionedit'.$data['secid'];
+ }
+
+ /**
+ * Finish an edit section range
+ *
+ * @param int $end The byte position for the edit end; null for the rest of the page
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+ public function finishSectionEdit($end = null, $hid = null) {
+ $data = array_pop($this->sectionedits);
+ if(!is_null($end) && $end <= $data['start']) {
+ return;
+ }
+ if(!is_null($hid)) {
+ $data['hid'] .= $hid;
+ }
+ $data['range'] = $data['start'].'-'.(is_null($end) ? '' : $end);
+ unset($data['start']);
+ $this->doc .= '<!-- EDIT'.hsc(json_encode ($data)).' -->';
+ }
+
+ /**
+ * Returns the format produced by this renderer.
+ *
+ * @return string always 'xhtml'
+ */
+ public function getFormat() {
+ return 'xhtml';
+ }
+
+ /**
+ * Initialize the document
+ */
+ public function document_start() {
+ //reset some internals
+ $this->toc = array();
+ }
+
+ /**
+ * Finalize the document
+ */
+ public function document_end() {
+ // Finish open section edits.
+ while(count($this->sectionedits) > 0) {
+ if($this->sectionedits[count($this->sectionedits) - 1]['start'] <= 1) {
+ // If there is only one section, do not write a section edit
+ // marker.
+ array_pop($this->sectionedits);
+ } else {
+ $this->finishSectionEdit();
+ }
+ }
+
+ if(count($this->footnotes) > 0) {
+ $this->doc .= '<div class="footnotes">'.DOKU_LF;
+
+ foreach($this->footnotes as $id => $footnote) {
+ // check its not a placeholder that indicates actual footnote text is elsewhere
+ if(substr($footnote, 0, 5) != "@@FNT") {
+
+ // open the footnote and set the anchor and backlink
+ $this->doc .= '<div class="fn">';
+ $this->doc .= '<sup><a href="#fnt__'.$id.'" id="fn__'.$id.'" class="fn_bot">';
+ $this->doc .= $id.')</a></sup> '.DOKU_LF;
+
+ // get any other footnotes that use the same markup
+ $alt = array_keys($this->footnotes, "@@FNT$id");
+
+ if(count($alt)) {
+ foreach($alt as $ref) {
+ // set anchor and backlink for the other footnotes
+ $this->doc .= ', <sup><a href="#fnt__'.($ref).'" id="fn__'.($ref).'" class="fn_bot">';
+ $this->doc .= ($ref).')</a></sup> '.DOKU_LF;
+ }
+ }
+
+ // add footnote markup and close this footnote
+ $this->doc .= '<div class="content">'.$footnote.'</div>';
+ $this->doc .= '</div>'.DOKU_LF;
+ }
+ }
+ $this->doc .= '</div>'.DOKU_LF;
+ }
+
+ // Prepare the TOC
+ global $conf;
+ if(
+ $this->info['toc'] &&
+ is_array($this->toc) &&
+ $conf['tocminheads'] && count($this->toc) >= $conf['tocminheads']
+ ) {
+ global $TOC;
+ $TOC = $this->toc;
+ }
+
+ // make sure there are no empty paragraphs
+ $this->doc = preg_replace('#<p>\s*</p>#', '', $this->doc);
+ }
+
+ /**
+ * Add an item to the TOC
+ *
+ * @param string $id the hash link
+ * @param string $text the text to display
+ * @param int $level the nesting level
+ */
+ public function toc_additem($id, $text, $level) {
+ global $conf;
+
+ //handle TOC
+ if($level >= $conf['toptoclevel'] && $level <= $conf['maxtoclevel']) {
+ $this->toc[] = html_mktocitem($id, $text, $level - $conf['toptoclevel'] + 1);
+ }
+ }
+
+ /**
+ * Render a heading
+ *
+ * @param string $text the text to display
+ * @param int $level header level
+ * @param int $pos byte position in the original source
+ */
+ public function header($text, $level, $pos) {
+ global $conf;
+
+ if(blank($text)) return; //skip empty headlines
+
+ $hid = $this->_headerToLink($text, true);
+
+ //only add items within configured levels
+ $this->toc_additem($hid, $text, $level);
+
+ // adjust $node to reflect hierarchy of levels
+ $this->node[$level - 1]++;
+ if($level < $this->lastlevel) {
+ for($i = 0; $i < $this->lastlevel - $level; $i++) {
+ $this->node[$this->lastlevel - $i - 1] = 0;
+ }
+ }
+ $this->lastlevel = $level;
+
+ if($level <= $conf['maxseclevel'] &&
+ count($this->sectionedits) > 0 &&
+ $this->sectionedits[count($this->sectionedits) - 1]['target'] === 'section'
+ ) {
+ $this->finishSectionEdit($pos - 1);
+ }
+
+ // write the header
+ $this->doc .= DOKU_LF.'<h'.$level;
+ if($level <= $conf['maxseclevel']) {
+ $data = array();
+ $data['target'] = 'section';
+ $data['name'] = $text;
+ $data['hid'] = $hid;
+ $data['codeblockOffset'] = $this->_codeblock;
+ $this->doc .= ' class="'.$this->startSectionEdit($pos, $data).'"';
+ }
+ $this->doc .= ' id="'.$hid.'">';
+ $this->doc .= $this->_xmlEntities($text);
+ $this->doc .= "</h$level>".DOKU_LF;
+ }
+
+ /**
+ * Open a new section
+ *
+ * @param int $level section level (as determined by the previous header)
+ */
+ public function section_open($level) {
+ $this->doc .= '<div class="level'.$level.'">'.DOKU_LF;
+ }
+
+ /**
+ * Close the current section
+ */
+ public function section_close() {
+ $this->doc .= DOKU_LF.'</div>'.DOKU_LF;
+ }
+
+ /**
+ * Render plain text data
+ *
+ * @param $text
+ */
+ public function cdata($text) {
+ $this->doc .= $this->_xmlEntities($text);
+ }
+
+ /**
+ * Open a paragraph
+ */
+ public function p_open() {
+ $this->doc .= DOKU_LF.'<p>'.DOKU_LF;
+ }
+
+ /**
+ * Close a paragraph
+ */
+ public function p_close() {
+ $this->doc .= DOKU_LF.'</p>'.DOKU_LF;
+ }
+
+ /**
+ * Create a line break
+ */
+ public function linebreak() {
+ $this->doc .= '<br/>'.DOKU_LF;
+ }
+
+ /**
+ * Create a horizontal line
+ */
+ public function hr() {
+ $this->doc .= '<hr />'.DOKU_LF;
+ }
+
+ /**
+ * Start strong (bold) formatting
+ */
+ public function strong_open() {
+ $this->doc .= '<strong>';
+ }
+
+ /**
+ * Stop strong (bold) formatting
+ */
+ public function strong_close() {
+ $this->doc .= '</strong>';
+ }
+
+ /**
+ * Start emphasis (italics) formatting
+ */
+ public function emphasis_open() {
+ $this->doc .= '<em>';
+ }
+
+ /**
+ * Stop emphasis (italics) formatting
+ */
+ public function emphasis_close() {
+ $this->doc .= '</em>';
+ }
+
+ /**
+ * Start underline formatting
+ */
+ public function underline_open() {
+ $this->doc .= '<em class="u">';
+ }
+
+ /**
+ * Stop underline formatting
+ */
+ public function underline_close() {
+ $this->doc .= '</em>';
+ }
+
+ /**
+ * Start monospace formatting
+ */
+ public function monospace_open() {
+ $this->doc .= '<code>';
+ }
+
+ /**
+ * Stop monospace formatting
+ */
+ public function monospace_close() {
+ $this->doc .= '</code>';
+ }
+
+ /**
+ * Start a subscript
+ */
+ public function subscript_open() {
+ $this->doc .= '<sub>';
+ }
+
+ /**
+ * Stop a subscript
+ */
+ public function subscript_close() {
+ $this->doc .= '</sub>';
+ }
+
+ /**
+ * Start a superscript
+ */
+ public function superscript_open() {
+ $this->doc .= '<sup>';
+ }
+
+ /**
+ * Stop a superscript
+ */
+ public function superscript_close() {
+ $this->doc .= '</sup>';
+ }
+
+ /**
+ * Start deleted (strike-through) formatting
+ */
+ public function deleted_open() {
+ $this->doc .= '<del>';
+ }
+
+ /**
+ * Stop deleted (strike-through) formatting
+ */
+ public function deleted_close() {
+ $this->doc .= '</del>';
+ }
+
+ /**
+ * Callback for footnote start syntax
+ *
+ * All following content will go to the footnote instead of
+ * the document. To achieve this the previous rendered content
+ * is moved to $store and $doc is cleared
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function footnote_open() {
+
+ // move current content to store and record footnote
+ $this->store = $this->doc;
+ $this->doc = '';
+ }
+
+ /**
+ * Callback for footnote end syntax
+ *
+ * All rendered content is moved to the $footnotes array and the old
+ * content is restored from $store again
+ *
+ * @author Andreas Gohr
+ */
+ public function footnote_close() {
+ /** @var $fnid int takes track of seen footnotes, assures they are unique even across multiple docs FS#2841 */
+ static $fnid = 0;
+ // assign new footnote id (we start at 1)
+ $fnid++;
+
+ // recover footnote into the stack and restore old content
+ $footnote = $this->doc;
+ $this->doc = $this->store;
+ $this->store = '';
+
+ // check to see if this footnote has been seen before
+ $i = array_search($footnote, $this->footnotes);
+
+ if($i === false) {
+ // its a new footnote, add it to the $footnotes array
+ $this->footnotes[$fnid] = $footnote;
+ } else {
+ // seen this one before, save a placeholder
+ $this->footnotes[$fnid] = "@@FNT".($i);
+ }
+
+ // output the footnote reference and link
+ $this->doc .= '<sup><a href="#fn__'.$fnid.'" id="fnt__'.$fnid.'" class="fn_top">'.$fnid.')</a></sup>';
+ }
+
+ /**
+ * Open an unordered list
+ *
+ * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input
+ */
+ public function listu_open($classes = null) {
+ $class = '';
+ if($classes !== null) {
+ if(is_array($classes)) $classes = join(' ', $classes);
+ $class = " class=\"$classes\"";
+ }
+ $this->doc .= "<ul$class>".DOKU_LF;
+ }
+
+ /**
+ * Close an unordered list
+ */
+ public function listu_close() {
+ $this->doc .= '</ul>'.DOKU_LF;
+ }
+
+ /**
+ * Open an ordered list
+ *
+ * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input
+ */
+ public function listo_open($classes = null) {
+ $class = '';
+ if($classes !== null) {
+ if(is_array($classes)) $classes = join(' ', $classes);
+ $class = " class=\"$classes\"";
+ }
+ $this->doc .= "<ol$class>".DOKU_LF;
+ }
+
+ /**
+ * Close an ordered list
+ */
+ public function listo_close() {
+ $this->doc .= '</ol>'.DOKU_LF;
+ }
+
+ /**
+ * Open a list item
+ *
+ * @param int $level the nesting level
+ * @param bool $node true when a node; false when a leaf
+ */
+ public function listitem_open($level, $node=false) {
+ $branching = $node ? ' node' : '';
+ $this->doc .= '<li class="level'.$level.$branching.'">';
+ }
+
+ /**
+ * Close a list item
+ */
+ public function listitem_close() {
+ $this->doc .= '</li>'.DOKU_LF;
+ }
+
+ /**
+ * Start the content of a list item
+ */
+ public function listcontent_open() {
+ $this->doc .= '<div class="li">';
+ }
+
+ /**
+ * Stop the content of a list item
+ */
+ public function listcontent_close() {
+ $this->doc .= '</div>'.DOKU_LF;
+ }
+
+ /**
+ * Output unformatted $text
+ *
+ * Defaults to $this->cdata()
+ *
+ * @param string $text
+ */
+ public function unformatted($text) {
+ $this->doc .= $this->_xmlEntities($text);
+ }
+
+ /**
+ * Execute PHP code if allowed
+ *
+ * @param string $text PHP code that is either executed or printed
+ * @param string $wrapper html element to wrap result if $conf['phpok'] is okff
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function php($text, $wrapper = 'code') {
+ global $conf;
+
+ if($conf['phpok']) {
+ ob_start();
+ eval($text);
+ $this->doc .= ob_get_contents();
+ ob_end_clean();
+ } else {
+ $this->doc .= p_xhtml_cached_geshi($text, 'php', $wrapper);
+ }
+ }
+
+ /**
+ * Output block level PHP code
+ *
+ * If $conf['phpok'] is true this should evaluate the given code and append the result
+ * to $doc
+ *
+ * @param string $text The PHP code
+ */
+ public function phpblock($text) {
+ $this->php($text, 'pre');
+ }
+
+ /**
+ * Insert HTML if allowed
+ *
+ * @param string $text html text
+ * @param string $wrapper html element to wrap result if $conf['htmlok'] is okff
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function html($text, $wrapper = 'code') {
+ global $conf;
+
+ if($conf['htmlok']) {
+ $this->doc .= $text;
+ } else {
+ $this->doc .= p_xhtml_cached_geshi($text, 'html4strict', $wrapper);
+ }
+ }
+
+ /**
+ * Output raw block-level HTML
+ *
+ * If $conf['htmlok'] is true this should add the code as is to $doc
+ *
+ * @param string $text The HTML
+ */
+ public function htmlblock($text) {
+ $this->html($text, 'pre');
+ }
+
+ /**
+ * Start a block quote
+ */
+ public function quote_open() {
+ $this->doc .= '<blockquote><div class="no">'.DOKU_LF;
+ }
+
+ /**
+ * Stop a block quote
+ */
+ public function quote_close() {
+ $this->doc .= '</div></blockquote>'.DOKU_LF;
+ }
+
+ /**
+ * Output preformatted text
+ *
+ * @param string $text
+ */
+ public function preformatted($text) {
+ $this->doc .= '<pre class="code">'.trim($this->_xmlEntities($text), "\n\r").'</pre>'.DOKU_LF;
+ }
+
+ /**
+ * Display text as file content, optionally syntax highlighted
+ *
+ * @param string $text text to show
+ * @param string $language programming language to use for syntax highlighting
+ * @param string $filename file path label
+ * @param array $options assoziative array with additional geshi options
+ */
+ public function file($text, $language = null, $filename = null, $options=null) {
+ $this->_highlight('file', $text, $language, $filename, $options);
+ }
+
+ /**
+ * Display text as code content, optionally syntax highlighted
+ *
+ * @param string $text text to show
+ * @param string $language programming language to use for syntax highlighting
+ * @param string $filename file path label
+ * @param array $options assoziative array with additional geshi options
+ */
+ public function code($text, $language = null, $filename = null, $options=null) {
+ $this->_highlight('code', $text, $language, $filename, $options);
+ }
+
+ /**
+ * Use GeSHi to highlight language syntax in code and file blocks
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $type code|file
+ * @param string $text text to show
+ * @param string $language programming language to use for syntax highlighting
+ * @param string $filename file path label
+ * @param array $options assoziative array with additional geshi options
+ */
+ public function _highlight($type, $text, $language = null, $filename = null, $options = null) {
+ global $ID;
+ global $lang;
+ global $INPUT;
+
+ $language = preg_replace(PREG_PATTERN_VALID_LANGUAGE, '', $language);
+
+ $language = preg_replace(PREG_PATTERN_VALID_LANGUAGE, '', $language);
+
+ if($filename) {
+ // add icon
+ list($ext) = mimetype($filename, false);
+ $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $ext);
+ $class = 'mediafile mf_'.$class;
+
+ $offset = 0;
+ if ($INPUT->has('codeblockOffset')) {
+ $offset = $INPUT->str('codeblockOffset');
+ }
+ $this->doc .= '<dl class="'.$type.'">'.DOKU_LF;
+ $this->doc .= '<dt><a href="' .
+ exportlink(
+ $ID,
+ 'code',
+ array('codeblock' => $offset + $this->_codeblock)
+ ) . '" title="' . $lang['download'] . '" class="' . $class . '">';
+ $this->doc .= hsc($filename);
+ $this->doc .= '</a></dt>'.DOKU_LF.'<dd>';
+ }
+
+ if($text[0] == "\n") {
+ $text = substr($text, 1);
+ }
+ if(substr($text, -1) == "\n") {
+ $text = substr($text, 0, -1);
+ }
+
+ if(empty($language)) { // empty is faster than is_null and can prevent '' string
+ $this->doc .= '<pre class="'.$type.'">'.$this->_xmlEntities($text).'</pre>'.DOKU_LF;
+ } else {
+ $class = 'code'; //we always need the code class to make the syntax highlighting apply
+ if($type != 'code') $class .= ' '.$type;
+
+ $this->doc .= "<pre class=\"$class $language\">" .
+ p_xhtml_cached_geshi($text, $language, '', $options) .
+ '</pre>' . DOKU_LF;
+ }
+
+ if($filename) {
+ $this->doc .= '</dd></dl>'.DOKU_LF;
+ }
+
+ $this->_codeblock++;
+ }
+
+ /**
+ * Format an acronym
+ *
+ * Uses $this->acronyms
+ *
+ * @param string $acronym
+ */
+ public function acronym($acronym) {
+
+ if(array_key_exists($acronym, $this->acronyms)) {
+
+ $title = $this->_xmlEntities($this->acronyms[$acronym]);
+
+ $this->doc .= '<abbr title="'.$title
+ .'">'.$this->_xmlEntities($acronym).'</abbr>';
+
+ } else {
+ $this->doc .= $this->_xmlEntities($acronym);
+ }
+ }
+
+ /**
+ * Format a smiley
+ *
+ * Uses $this->smiley
+ *
+ * @param string $smiley
+ */
+ public function smiley($smiley) {
+ if(array_key_exists($smiley, $this->smileys)) {
+ $this->doc .= '<img src="'.DOKU_BASE.'lib/images/smileys/'.$this->smileys[$smiley].
+ '" class="icon" alt="'.
+ $this->_xmlEntities($smiley).'" />';
+ } else {
+ $this->doc .= $this->_xmlEntities($smiley);
+ }
+ }
+
+ /**
+ * Format an entity
+ *
+ * Entities are basically small text replacements
+ *
+ * Uses $this->entities
+ *
+ * @param string $entity
+ */
+ public function entity($entity) {
+ if(array_key_exists($entity, $this->entities)) {
+ $this->doc .= $this->entities[$entity];
+ } else {
+ $this->doc .= $this->_xmlEntities($entity);
+ }
+ }
+
+ /**
+ * Typographically format a multiply sign
+ *
+ * Example: ($x=640, $y=480) should result in "640×480"
+ *
+ * @param string|int $x first value
+ * @param string|int $y second value
+ */
+ public function multiplyentity($x, $y) {
+ $this->doc .= "$x&times;$y";
+ }
+
+ /**
+ * Render an opening single quote char (language specific)
+ */
+ public function singlequoteopening() {
+ global $lang;
+ $this->doc .= $lang['singlequoteopening'];
+ }
+
+ /**
+ * Render a closing single quote char (language specific)
+ */
+ public function singlequoteclosing() {
+ global $lang;
+ $this->doc .= $lang['singlequoteclosing'];
+ }
+
+ /**
+ * Render an apostrophe char (language specific)
+ */
+ public function apostrophe() {
+ global $lang;
+ $this->doc .= $lang['apostrophe'];
+ }
+
+ /**
+ * Render an opening double quote char (language specific)
+ */
+ public function doublequoteopening() {
+ global $lang;
+ $this->doc .= $lang['doublequoteopening'];
+ }
+
+ /**
+ * Render an closinging double quote char (language specific)
+ */
+ public function doublequoteclosing() {
+ global $lang;
+ $this->doc .= $lang['doublequoteclosing'];
+ }
+
+ /**
+ * Render a CamelCase link
+ *
+ * @param string $link The link name
+ * @param bool $returnonly whether to return html or write to doc attribute
+ * @return void|string writes to doc attribute or returns html depends on $returnonly
+ *
+ * @see http://en.wikipedia.org/wiki/CamelCase
+ */
+ public function camelcaselink($link, $returnonly = false) {
+ if($returnonly) {
+ return $this->internallink($link, $link, null, true);
+ } else {
+ $this->internallink($link, $link);
+ }
+ }
+
+ /**
+ * Render a page local link
+ *
+ * @param string $hash hash link identifier
+ * @param string $name name for the link
+ * @param bool $returnonly whether to return html or write to doc attribute
+ * @return void|string writes to doc attribute or returns html depends on $returnonly
+ */
+ public function locallink($hash, $name = null, $returnonly = false) {
+ global $ID;
+ $name = $this->_getLinkTitle($name, $hash, $isImage);
+ $hash = $this->_headerToLink($hash);
+ $title = $ID.' ↵';
+
+ $doc = '<a href="#'.$hash.'" title="'.$title.'" class="wikilink1">';
+ $doc .= $name;
+ $doc .= '</a>';
+
+ if($returnonly) {
+ return $doc;
+ } else {
+ $this->doc .= $doc;
+ }
+ }
+
+ /**
+ * Render an internal Wiki Link
+ *
+ * $search,$returnonly & $linktype are not for the renderer but are used
+ * elsewhere - no need to implement them in other renderers
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $id pageid
+ * @param string|null $name link name
+ * @param string|null $search adds search url param
+ * @param bool $returnonly whether to return html or write to doc attribute
+ * @param string $linktype type to set use of headings
+ * @return void|string writes to doc attribute or returns html depends on $returnonly
+ */
+ public function internallink($id, $name = null, $search = null, $returnonly = false, $linktype = 'content') {
+ global $conf;
+ global $ID;
+ global $INFO;
+
+ $params = '';
+ $parts = explode('?', $id, 2);
+ if(count($parts) === 2) {
+ $id = $parts[0];
+ $params = $parts[1];
+ }
+
+ // For empty $id we need to know the current $ID
+ // We need this check because _simpleTitle needs
+ // correct $id and resolve_pageid() use cleanID($id)
+ // (some things could be lost)
+ if($id === '') {
+ $id = $ID;
+ }
+
+ // default name is based on $id as given
+ $default = $this->_simpleTitle($id);
+
+ // now first resolve and clean up the $id
+ resolve_pageid(getNS($ID), $id, $exists, $this->date_at, true);
+
+ $link = array();
+ $name = $this->_getLinkTitle($name, $default, $isImage, $id, $linktype);
+ if(!$isImage) {
+ if($exists) {
+ $class = 'wikilink1';
+ } else {
+ $class = 'wikilink2';
+ $link['rel'] = 'nofollow';
+ }
+ } else {
+ $class = 'media';
+ }
+
+ //keep hash anchor
+ @list($id, $hash) = explode('#', $id, 2);
+ if(!empty($hash)) $hash = $this->_headerToLink($hash);
+
+ //prepare for formating
+ $link['target'] = $conf['target']['wiki'];
+ $link['style'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = 'data-wiki-id="'.$id.'"'; // id is already cleaned
+ $link['class'] = $class;
+ if($this->date_at) {
+ $params = $params.'&at='.rawurlencode($this->date_at);
+ }
+ $link['url'] = wl($id, $params);
+ $link['name'] = $name;
+ $link['title'] = $id;
+ //add search string
+ if($search) {
+ ($conf['userewrite']) ? $link['url'] .= '?' : $link['url'] .= '&amp;';
+ if(is_array($search)) {
+ $search = array_map('rawurlencode', $search);
+ $link['url'] .= 's[]='.join('&amp;s[]=', $search);
+ } else {
+ $link['url'] .= 's='.rawurlencode($search);
+ }
+ }
+
+ //keep hash
+ if($hash) $link['url'] .= '#'.$hash;
+
+ //output formatted
+ if($returnonly) {
+ return $this->_formatLink($link);
+ } else {
+ $this->doc .= $this->_formatLink($link);
+ }
+ }
+
+ /**
+ * Render an external link
+ *
+ * @param string $url full URL with scheme
+ * @param string|array $name name for the link, array for media file
+ * @param bool $returnonly whether to return html or write to doc attribute
+ * @return void|string writes to doc attribute or returns html depends on $returnonly
+ */
+ public function externallink($url, $name = null, $returnonly = false) {
+ global $conf;
+
+ $name = $this->_getLinkTitle($name, $url, $isImage);
+
+ // url might be an attack vector, only allow registered protocols
+ if(is_null($this->schemes)) $this->schemes = getSchemes();
+ list($scheme) = explode('://', $url);
+ $scheme = strtolower($scheme);
+ if(!in_array($scheme, $this->schemes)) $url = '';
+
+ // is there still an URL?
+ if(!$url) {
+ if($returnonly) {
+ return $name;
+ } else {
+ $this->doc .= $name;
+ }
+ return;
+ }
+
+ // set class
+ if(!$isImage) {
+ $class = 'urlextern';
+ } else {
+ $class = 'media';
+ }
+
+ //prepare for formating
+ $link = array();
+ $link['target'] = $conf['target']['extern'];
+ $link['style'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = '';
+ $link['class'] = $class;
+ $link['url'] = $url;
+ $link['rel'] = '';
+
+ $link['name'] = $name;
+ $link['title'] = $this->_xmlEntities($url);
+ if($conf['relnofollow']) $link['rel'] .= ' ugc nofollow';
+ if($conf['target']['extern']) $link['rel'] .= ' noopener';
+
+ //output formatted
+ if($returnonly) {
+ return $this->_formatLink($link);
+ } else {
+ $this->doc .= $this->_formatLink($link);
+ }
+ }
+
+ /**
+ * Render an interwiki link
+ *
+ * You may want to use $this->_resolveInterWiki() here
+ *
+ * @param string $match original link - probably not much use
+ * @param string|array $name name for the link, array for media file
+ * @param string $wikiName indentifier (shortcut) for the remote wiki
+ * @param string $wikiUri the fragment parsed from the original link
+ * @param bool $returnonly whether to return html or write to doc attribute
+ * @return void|string writes to doc attribute or returns html depends on $returnonly
+ */
+ public function interwikilink($match, $name, $wikiName, $wikiUri, $returnonly = false) {
+ global $conf;
+
+ $link = array();
+ $link['target'] = $conf['target']['interwiki'];
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = '';
+ $link['name'] = $this->_getLinkTitle($name, $wikiUri, $isImage);
+ $link['rel'] = '';
+
+ //get interwiki URL
+ $exists = null;
+ $url = $this->_resolveInterWiki($wikiName, $wikiUri, $exists);
+
+ if(!$isImage) {
+ $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $wikiName);
+ $link['class'] = "interwiki iw_$class";
+ } else {
+ $link['class'] = 'media';
+ }
+
+ //do we stay at the same server? Use local target
+ if(strpos($url, DOKU_URL) === 0 OR strpos($url, DOKU_BASE) === 0) {
+ $link['target'] = $conf['target']['wiki'];
+ }
+ if($exists !== null && !$isImage) {
+ if($exists) {
+ $link['class'] .= ' wikilink1';
+ } else {
+ $link['class'] .= ' wikilink2';
+ $link['rel'] .= ' nofollow';
+ }
+ }
+ if($conf['target']['interwiki']) $link['rel'] .= ' noopener';
+
+ $link['url'] = $url;
+ $link['title'] = htmlspecialchars($link['url']);
+
+ // output formatted
+ if($returnonly) {
+ if($url == '') return $link['name'];
+ return $this->_formatLink($link);
+ } else {
+ if($url == '') $this->doc .= $link['name'];
+ else $this->doc .= $this->_formatLink($link);
+ }
+ }
+
+ /**
+ * Link to windows share
+ *
+ * @param string $url the link
+ * @param string|array $name name for the link, array for media file
+ * @param bool $returnonly whether to return html or write to doc attribute
+ * @return void|string writes to doc attribute or returns html depends on $returnonly
+ */
+ public function windowssharelink($url, $name = null, $returnonly = false) {
+ global $conf;
+
+ //simple setup
+ $link = array();
+ $link['target'] = $conf['target']['windows'];
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['style'] = '';
+
+ $link['name'] = $this->_getLinkTitle($name, $url, $isImage);
+ if(!$isImage) {
+ $link['class'] = 'windows';
+ } else {
+ $link['class'] = 'media';
+ }
+
+ $link['title'] = $this->_xmlEntities($url);
+ $url = str_replace('\\', '/', $url);
+ $url = 'file:///'.$url;
+ $link['url'] = $url;
+
+ //output formatted
+ if($returnonly) {
+ return $this->_formatLink($link);
+ } else {
+ $this->doc .= $this->_formatLink($link);
+ }
+ }
+
+ /**
+ * Render a linked E-Mail Address
+ *
+ * Honors $conf['mailguard'] setting
+ *
+ * @param string $address Email-Address
+ * @param string|array $name name for the link, array for media file
+ * @param bool $returnonly whether to return html or write to doc attribute
+ * @return void|string writes to doc attribute or returns html depends on $returnonly
+ */
+ public function emaillink($address, $name = null, $returnonly = false) {
+ global $conf;
+ //simple setup
+ $link = array();
+ $link['target'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['style'] = '';
+ $link['more'] = '';
+
+ $name = $this->_getLinkTitle($name, '', $isImage);
+ if(!$isImage) {
+ $link['class'] = 'mail';
+ } else {
+ $link['class'] = 'media';
+ }
+
+ $address = $this->_xmlEntities($address);
+ $address = obfuscate($address);
+ $title = $address;
+
+ if(empty($name)) {
+ $name = $address;
+ }
+
+ if($conf['mailguard'] == 'visible') $address = rawurlencode($address);
+
+ $link['url'] = 'mailto:'.$address;
+ $link['name'] = $name;
+ $link['title'] = $title;
+
+ //output formatted
+ if($returnonly) {
+ return $this->_formatLink($link);
+ } else {
+ $this->doc .= $this->_formatLink($link);
+ }
+ }
+
+ /**
+ * Render an internal media file
+ *
+ * @param string $src media ID
+ * @param string $title descriptive text
+ * @param string $align left|center|right
+ * @param int $width width of media in pixel
+ * @param int $height height of media in pixel
+ * @param string $cache cache|recache|nocache
+ * @param string $linking linkonly|detail|nolink
+ * @param bool $return return HTML instead of adding to $doc
+ * @return void|string writes to doc attribute or returns html depends on $return
+ */
+ public function internalmedia($src, $title = null, $align = null, $width = null,
+ $height = null, $cache = null, $linking = null, $return = false) {
+ global $ID;
+ if (strpos($src, '#') !== false) {
+ list($src, $hash) = explode('#', $src, 2);
+ }
+ resolve_mediaid(getNS($ID), $src, $exists, $this->date_at, true);
+
+ $noLink = false;
+ $render = ($linking == 'linkonly') ? false : true;
+ $link = $this->_getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render);
+
+ list($ext, $mime) = mimetype($src, false);
+ if(substr($mime, 0, 5) == 'image' && $render) {
+ $link['url'] = ml(
+ $src,
+ array(
+ 'id' => $ID,
+ 'cache' => $cache,
+ 'rev' => $this->_getLastMediaRevisionAt($src)
+ ),
+ ($linking == 'direct')
+ );
+ } elseif(($mime == 'application/x-shockwave-flash' || media_supportedav($mime)) && $render) {
+ // don't link movies
+ $noLink = true;
+ } else {
+ // add file icons
+ $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $ext);
+ $link['class'] .= ' mediafile mf_'.$class;
+ $link['url'] = ml(
+ $src,
+ array(
+ 'id' => $ID,
+ 'cache' => $cache,
+ 'rev' => $this->_getLastMediaRevisionAt($src)
+ ),
+ true
+ );
+ if($exists) $link['title'] .= ' ('.filesize_h(filesize(mediaFN($src))).')';
+ }
+
+ if (!empty($hash)) $link['url'] .= '#'.$hash;
+
+ //markup non existing files
+ if(!$exists) {
+ $link['class'] .= ' wikilink2';
+ }
+
+ //output formatted
+ if($return) {
+ if($linking == 'nolink' || $noLink) return $link['name'];
+ else return $this->_formatLink($link);
+ } else {
+ if($linking == 'nolink' || $noLink) $this->doc .= $link['name'];
+ else $this->doc .= $this->_formatLink($link);
+ }
+ }
+
+ /**
+ * Render an external media file
+ *
+ * @param string $src full media URL
+ * @param string $title descriptive text
+ * @param string $align left|center|right
+ * @param int $width width of media in pixel
+ * @param int $height height of media in pixel
+ * @param string $cache cache|recache|nocache
+ * @param string $linking linkonly|detail|nolink
+ * @param bool $return return HTML instead of adding to $doc
+ * @return void|string writes to doc attribute or returns html depends on $return
+ */
+ public function externalmedia($src, $title = null, $align = null, $width = null,
+ $height = null, $cache = null, $linking = null, $return = false) {
+ if(link_isinterwiki($src)){
+ list($shortcut, $reference) = explode('>', $src, 2);
+ $exists = null;
+ $src = $this->_resolveInterWiki($shortcut, $reference, $exists);
+ if($src == '' && empty($title)){
+ // make sure at least something will be shown in this case
+ $title = $reference;
+ }
+ }
+ list($src, $hash) = explode('#', $src, 2);
+ $noLink = false;
+ if($src == '') {
+ // only output plaintext without link if there is no src
+ $noLink = true;
+ }
+ $render = ($linking == 'linkonly') ? false : true;
+ $link = $this->_getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render);
+
+ $link['url'] = ml($src, array('cache' => $cache));
+
+ list($ext, $mime) = mimetype($src, false);
+ if(substr($mime, 0, 5) == 'image' && $render) {
+ // link only jpeg images
+ // if ($ext != 'jpg' && $ext != 'jpeg') $noLink = true;
+ } elseif(($mime == 'application/x-shockwave-flash' || media_supportedav($mime)) && $render) {
+ // don't link movies
+ $noLink = true;
+ } else {
+ // add file icons
+ $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $ext);
+ $link['class'] .= ' mediafile mf_'.$class;
+ }
+
+ if($hash) $link['url'] .= '#'.$hash;
+
+ //output formatted
+ if($return) {
+ if($linking == 'nolink' || $noLink) return $link['name'];
+ else return $this->_formatLink($link);
+ } else {
+ if($linking == 'nolink' || $noLink) $this->doc .= $link['name'];
+ else $this->doc .= $this->_formatLink($link);
+ }
+ }
+
+ /**
+ * Renders an RSS feed
+ *
+ * @param string $url URL of the feed
+ * @param array $params Finetuning of the output
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function rss($url, $params) {
+ global $lang;
+ global $conf;
+
+ require_once(DOKU_INC.'inc/FeedParser.php');
+ $feed = new FeedParser();
+ $feed->set_feed_url($url);
+
+ //disable warning while fetching
+ if(!defined('DOKU_E_LEVEL')) {
+ $elvl = error_reporting(E_ERROR);
+ }
+ $rc = $feed->init();
+ if(isset($elvl)) {
+ error_reporting($elvl);
+ }
+
+ if($params['nosort']) $feed->enable_order_by_date(false);
+
+ //decide on start and end
+ if($params['reverse']) {
+ $mod = -1;
+ $start = $feed->get_item_quantity() - 1;
+ $end = $start - ($params['max']);
+ $end = ($end < -1) ? -1 : $end;
+ } else {
+ $mod = 1;
+ $start = 0;
+ $end = $feed->get_item_quantity();
+ $end = ($end > $params['max']) ? $params['max'] : $end;
+ }
+
+ $this->doc .= '<ul class="rss">';
+ if($rc) {
+ for($x = $start; $x != $end; $x += $mod) {
+ $item = $feed->get_item($x);
+ $this->doc .= '<li><div class="li">';
+ // support feeds without links
+ $lnkurl = $item->get_permalink();
+ if($lnkurl) {
+ // title is escaped by SimplePie, we unescape here because it
+ // is escaped again in externallink() FS#1705
+ $this->externallink(
+ $item->get_permalink(),
+ html_entity_decode($item->get_title(), ENT_QUOTES, 'UTF-8')
+ );
+ } else {
+ $this->doc .= ' '.$item->get_title();
+ }
+ if($params['author']) {
+ $author = $item->get_author(0);
+ if($author) {
+ $name = $author->get_name();
+ if(!$name) $name = $author->get_email();
+ if($name) $this->doc .= ' '.$lang['by'].' '.hsc($name);
+ }
+ }
+ if($params['date']) {
+ $this->doc .= ' ('.$item->get_local_date($conf['dformat']).')';
+ }
+ if($params['details']) {
+ $this->doc .= '<div class="detail">';
+ if($conf['htmlok']) {
+ $this->doc .= $item->get_description();
+ } else {
+ $this->doc .= strip_tags($item->get_description());
+ }
+ $this->doc .= '</div>';
+ }
+
+ $this->doc .= '</div></li>';
+ }
+ } else {
+ $this->doc .= '<li><div class="li">';
+ $this->doc .= '<em>'.$lang['rssfailed'].'</em>';
+ $this->externallink($url);
+ if($conf['allowdebug']) {
+ $this->doc .= '<!--'.hsc($feed->error).'-->';
+ }
+ $this->doc .= '</div></li>';
+ }
+ $this->doc .= '</ul>';
+ }
+
+ /**
+ * Start a table
+ *
+ * @param int $maxcols maximum number of columns
+ * @param int $numrows NOT IMPLEMENTED
+ * @param int $pos byte position in the original source
+ * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input
+ */
+ public function table_open($maxcols = null, $numrows = null, $pos = null, $classes = null) {
+ // initialize the row counter used for classes
+ $this->_counter['row_counter'] = 0;
+ $class = 'table';
+ if($classes !== null) {
+ if(is_array($classes)) $classes = join(' ', $classes);
+ $class .= ' ' . $classes;
+ }
+ if($pos !== null) {
+ $hid = $this->_headerToLink($class, true);
+ $data = array();
+ $data['target'] = 'table';
+ $data['name'] = '';
+ $data['hid'] = $hid;
+ $class .= ' '.$this->startSectionEdit($pos, $data);
+ }
+ $this->doc .= '<div class="'.$class.'"><table class="inline">'.
+ DOKU_LF;
+ }
+
+ /**
+ * Close a table
+ *
+ * @param int $pos byte position in the original source
+ */
+ public function table_close($pos = null) {
+ $this->doc .= '</table></div>'.DOKU_LF;
+ if($pos !== null) {
+ $this->finishSectionEdit($pos);
+ }
+ }
+
+ /**
+ * Open a table header
+ */
+ public function tablethead_open() {
+ $this->doc .= DOKU_TAB.'<thead>'.DOKU_LF;
+ }
+
+ /**
+ * Close a table header
+ */
+ public function tablethead_close() {
+ $this->doc .= DOKU_TAB.'</thead>'.DOKU_LF;
+ }
+
+ /**
+ * Open a table body
+ */
+ public function tabletbody_open() {
+ $this->doc .= DOKU_TAB.'<tbody>'.DOKU_LF;
+ }
+
+ /**
+ * Close a table body
+ */
+ public function tabletbody_close() {
+ $this->doc .= DOKU_TAB.'</tbody>'.DOKU_LF;
+ }
+
+ /**
+ * Open a table footer
+ */
+ public function tabletfoot_open() {
+ $this->doc .= DOKU_TAB.'<tfoot>'.DOKU_LF;
+ }
+
+ /**
+ * Close a table footer
+ */
+ public function tabletfoot_close() {
+ $this->doc .= DOKU_TAB.'</tfoot>'.DOKU_LF;
+ }
+
+ /**
+ * Open a table row
+ *
+ * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input
+ */
+ public function tablerow_open($classes = null) {
+ // initialize the cell counter used for classes
+ $this->_counter['cell_counter'] = 0;
+ $class = 'row'.$this->_counter['row_counter']++;
+ if($classes !== null) {
+ if(is_array($classes)) $classes = join(' ', $classes);
+ $class .= ' ' . $classes;
+ }
+ $this->doc .= DOKU_TAB.'<tr class="'.$class.'">'.DOKU_LF.DOKU_TAB.DOKU_TAB;
+ }
+
+ /**
+ * Close a table row
+ */
+ public function tablerow_close() {
+ $this->doc .= DOKU_LF.DOKU_TAB.'</tr>'.DOKU_LF;
+ }
+
+ /**
+ * Open a table header cell
+ *
+ * @param int $colspan
+ * @param string $align left|center|right
+ * @param int $rowspan
+ * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input
+ */
+ public function tableheader_open($colspan = 1, $align = null, $rowspan = 1, $classes = null) {
+ $class = 'class="col'.$this->_counter['cell_counter']++;
+ if(!is_null($align)) {
+ $class .= ' '.$align.'align';
+ }
+ if($classes !== null) {
+ if(is_array($classes)) $classes = join(' ', $classes);
+ $class .= ' ' . $classes;
+ }
+ $class .= '"';
+ $this->doc .= '<th '.$class;
+ if($colspan > 1) {
+ $this->_counter['cell_counter'] += $colspan - 1;
+ $this->doc .= ' colspan="'.$colspan.'"';
+ }
+ if($rowspan > 1) {
+ $this->doc .= ' rowspan="'.$rowspan.'"';
+ }
+ $this->doc .= '>';
+ }
+
+ /**
+ * Close a table header cell
+ */
+ public function tableheader_close() {
+ $this->doc .= '</th>';
+ }
+
+ /**
+ * Open a table cell
+ *
+ * @param int $colspan
+ * @param string $align left|center|right
+ * @param int $rowspan
+ * @param string|string[] $classes css classes - have to be valid, do not pass unfiltered user input
+ */
+ public function tablecell_open($colspan = 1, $align = null, $rowspan = 1, $classes = null) {
+ $class = 'class="col'.$this->_counter['cell_counter']++;
+ if(!is_null($align)) {
+ $class .= ' '.$align.'align';
+ }
+ if($classes !== null) {
+ if(is_array($classes)) $classes = join(' ', $classes);
+ $class .= ' ' . $classes;
+ }
+ $class .= '"';
+ $this->doc .= '<td '.$class;
+ if($colspan > 1) {
+ $this->_counter['cell_counter'] += $colspan - 1;
+ $this->doc .= ' colspan="'.$colspan.'"';
+ }
+ if($rowspan > 1) {
+ $this->doc .= ' rowspan="'.$rowspan.'"';
+ }
+ $this->doc .= '>';
+ }
+
+ /**
+ * Close a table cell
+ */
+ public function tablecell_close() {
+ $this->doc .= '</td>';
+ }
+
+ /**
+ * Returns the current header level.
+ * (required e.g. by the filelist plugin)
+ *
+ * @return int The current header level
+ */
+ public function getLastlevel() {
+ return $this->lastlevel;
+ }
+
+ #region Utility functions
+
+ /**
+ * Build a link
+ *
+ * Assembles all parts defined in $link returns HTML for the link
+ *
+ * @param array $link attributes of a link
+ * @return string
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function _formatLink($link) {
+ //make sure the url is XHTML compliant (skip mailto)
+ if(substr($link['url'], 0, 7) != 'mailto:') {
+ $link['url'] = str_replace('&', '&amp;', $link['url']);
+ $link['url'] = str_replace('&amp;amp;', '&amp;', $link['url']);
+ }
+ //remove double encodings in titles
+ $link['title'] = str_replace('&amp;amp;', '&amp;', $link['title']);
+
+ // be sure there are no bad chars in url or title
+ // (we can't do this for name because it can contain an img tag)
+ $link['url'] = strtr($link['url'], array('>' => '%3E', '<' => '%3C', '"' => '%22'));
+ $link['title'] = strtr($link['title'], array('>' => '&gt;', '<' => '&lt;', '"' => '&quot;'));
+
+ $ret = '';
+ $ret .= $link['pre'];
+ $ret .= '<a href="'.$link['url'].'"';
+ if(!empty($link['class'])) $ret .= ' class="'.$link['class'].'"';
+ if(!empty($link['target'])) $ret .= ' target="'.$link['target'].'"';
+ if(!empty($link['title'])) $ret .= ' title="'.$link['title'].'"';
+ if(!empty($link['style'])) $ret .= ' style="'.$link['style'].'"';
+ if(!empty($link['rel'])) $ret .= ' rel="'.trim($link['rel']).'"';
+ if(!empty($link['more'])) $ret .= ' '.$link['more'];
+ $ret .= '>';
+ $ret .= $link['name'];
+ $ret .= '</a>';
+ $ret .= $link['suf'];
+ return $ret;
+ }
+
+ /**
+ * Renders internal and external media
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $src media ID
+ * @param string $title descriptive text
+ * @param string $align left|center|right
+ * @param int $width width of media in pixel
+ * @param int $height height of media in pixel
+ * @param string $cache cache|recache|nocache
+ * @param bool $render should the media be embedded inline or just linked
+ * @return string
+ */
+ public function _media($src, $title = null, $align = null, $width = null,
+ $height = null, $cache = null, $render = true) {
+
+ $ret = '';
+
+ list($ext, $mime) = mimetype($src);
+ if(substr($mime, 0, 5) == 'image') {
+ // first get the $title
+ if(!is_null($title)) {
+ $title = $this->_xmlEntities($title);
+ } elseif($ext == 'jpg' || $ext == 'jpeg') {
+ //try to use the caption from IPTC/EXIF
+ require_once(DOKU_INC.'inc/JpegMeta.php');
+ $jpeg = new JpegMeta(mediaFN($src));
+ if($jpeg !== false) $cap = $jpeg->getTitle();
+ if(!empty($cap)) {
+ $title = $this->_xmlEntities($cap);
+ }
+ }
+ if(!$render) {
+ // if the picture is not supposed to be rendered
+ // return the title of the picture
+ if($title === null || $title === "") {
+ // just show the sourcename
+ $title = $this->_xmlEntities(\dokuwiki\Utf8\PhpString::basename(noNS($src)));
+ }
+ return $title;
+ }
+ //add image tag
+ $ret .= '<img src="' . ml(
+ $src,
+ array(
+ 'w' => $width, 'h' => $height,
+ 'cache' => $cache,
+ 'rev' => $this->_getLastMediaRevisionAt($src)
+ )
+ ) . '"';
+ $ret .= ' class="media'.$align.'"';
+
+ if($title) {
+ $ret .= ' title="'.$title.'"';
+ $ret .= ' alt="'.$title.'"';
+ } else {
+ $ret .= ' alt=""';
+ }
+
+ if(!is_null($width))
+ $ret .= ' width="'.$this->_xmlEntities($width).'"';
+
+ if(!is_null($height))
+ $ret .= ' height="'.$this->_xmlEntities($height).'"';
+
+ $ret .= ' />';
+
+ } elseif(media_supportedav($mime, 'video') || media_supportedav($mime, 'audio')) {
+ // first get the $title
+ $title = !is_null($title) ? $title : false;
+ if(!$render) {
+ // if the file is not supposed to be rendered
+ // return the title of the file (just the sourcename if there is no title)
+ return $this->_xmlEntities($title ? $title : \dokuwiki\Utf8\PhpString::basename(noNS($src)));
+ }
+
+ $att = array();
+ $att['class'] = "media$align";
+ if($title) {
+ $att['title'] = $title;
+ }
+
+ if(media_supportedav($mime, 'video')) {
+ //add video
+ $ret .= $this->_video($src, $width, $height, $att);
+ }
+ if(media_supportedav($mime, 'audio')) {
+ //add audio
+ $ret .= $this->_audio($src, $att);
+ }
+
+ } elseif($mime == 'application/x-shockwave-flash') {
+ if(!$render) {
+ // if the flash is not supposed to be rendered
+ // return the title of the flash
+ if(!$title) {
+ // just show the sourcename
+ $title = \dokuwiki\Utf8\PhpString::basename(noNS($src));
+ }
+ return $this->_xmlEntities($title);
+ }
+
+ $att = array();
+ $att['class'] = "media$align";
+ if($align == 'right') $att['align'] = 'right';
+ if($align == 'left') $att['align'] = 'left';
+ $ret .= html_flashobject(
+ ml($src, array('cache' => $cache), true, '&'), $width, $height,
+ array('quality' => 'high'),
+ null,
+ $att,
+ $this->_xmlEntities($title)
+ );
+ } elseif($title) {
+ // well at least we have a title to display
+ $ret .= $this->_xmlEntities($title);
+ } else {
+ // just show the sourcename
+ $ret .= $this->_xmlEntities(\dokuwiki\Utf8\PhpString::basename(noNS($src)));
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Escape string for output
+ *
+ * @param $string
+ * @return string
+ */
+ public function _xmlEntities($string) {
+ return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
+ }
+
+
+
+ /**
+ * Construct a title and handle images in titles
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @param string|array $title either string title or media array
+ * @param string $default default title if nothing else is found
+ * @param bool $isImage will be set to true if it's a media file
+ * @param null|string $id linked page id (used to extract title from first heading)
+ * @param string $linktype content|navigation
+ * @return string HTML of the title, might be full image tag or just escaped text
+ */
+ public function _getLinkTitle($title, $default, &$isImage, $id = null, $linktype = 'content') {
+ $isImage = false;
+ if(is_array($title)) {
+ $isImage = true;
+ return $this->_imageTitle($title);
+ } elseif(is_null($title) || trim($title) == '') {
+ if(useHeading($linktype) && $id) {
+ $heading = p_get_first_heading($id);
+ if(!blank($heading)) {
+ return $this->_xmlEntities($heading);
+ }
+ }
+ return $this->_xmlEntities($default);
+ } else {
+ return $this->_xmlEntities($title);
+ }
+ }
+
+ /**
+ * Returns HTML code for images used in link titles
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param array $img
+ * @return string HTML img tag or similar
+ */
+ public function _imageTitle($img) {
+ global $ID;
+
+ // some fixes on $img['src']
+ // see internalmedia() and externalmedia()
+ list($img['src']) = explode('#', $img['src'], 2);
+ if($img['type'] == 'internalmedia') {
+ resolve_mediaid(getNS($ID), $img['src'], $exists ,$this->date_at, true);
+ }
+
+ return $this->_media(
+ $img['src'],
+ $img['title'],
+ $img['align'],
+ $img['width'],
+ $img['height'],
+ $img['cache']
+ );
+ }
+
+ /**
+ * helperfunction to return a basic link to a media
+ *
+ * used in internalmedia() and externalmedia()
+ *
+ * @author Pierre Spring <pierre.spring@liip.ch>
+ * @param string $src media ID
+ * @param string $title descriptive text
+ * @param string $align left|center|right
+ * @param int $width width of media in pixel
+ * @param int $height height of media in pixel
+ * @param string $cache cache|recache|nocache
+ * @param bool $render should the media be embedded inline or just linked
+ * @return array associative array with link config
+ */
+ public function _getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render) {
+ global $conf;
+
+ $link = array();
+ $link['class'] = 'media';
+ $link['style'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = '';
+ $link['target'] = $conf['target']['media'];
+ if($conf['target']['media']) $link['rel'] = 'noopener';
+ $link['title'] = $this->_xmlEntities($src);
+ $link['name'] = $this->_media($src, $title, $align, $width, $height, $cache, $render);
+
+ return $link;
+ }
+
+ /**
+ * Embed video(s) in HTML
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ *
+ * @param string $src - ID of video to embed
+ * @param int $width - width of the video in pixels
+ * @param int $height - height of the video in pixels
+ * @param array $atts - additional attributes for the <video> tag
+ * @return string
+ */
+ public function _video($src, $width, $height, $atts = null) {
+ // prepare width and height
+ if(is_null($atts)) $atts = array();
+ $atts['width'] = (int) $width;
+ $atts['height'] = (int) $height;
+ if(!$atts['width']) $atts['width'] = 320;
+ if(!$atts['height']) $atts['height'] = 240;
+
+ $posterUrl = '';
+ $files = array();
+ $tracks = array();
+ $isExternal = media_isexternal($src);
+
+ if ($isExternal) {
+ // take direct source for external files
+ list(/*ext*/, $srcMime) = mimetype($src);
+ $files[$srcMime] = $src;
+ } else {
+ // prepare alternative formats
+ $extensions = array('webm', 'ogv', 'mp4');
+ $files = media_alternativefiles($src, $extensions);
+ $poster = media_alternativefiles($src, array('jpg', 'png'));
+ $tracks = media_trackfiles($src);
+ if(!empty($poster)) {
+ $posterUrl = ml(reset($poster), '', true, '&');
+ }
+ }
+
+ $out = '';
+ // open video tag
+ $out .= '<video '.buildAttributes($atts).' controls="controls"';
+ if($posterUrl) $out .= ' poster="'.hsc($posterUrl).'"';
+ $out .= '>'.NL;
+ $fallback = '';
+
+ // output source for each alternative video format
+ foreach($files as $mime => $file) {
+ if ($isExternal) {
+ $url = $file;
+ $linkType = 'externalmedia';
+ } else {
+ $url = ml($file, '', true, '&');
+ $linkType = 'internalmedia';
+ }
+ $title = $atts['title'] ? $atts['title'] : $this->_xmlEntities(\dokuwiki\Utf8\PhpString::basename(noNS($file)));
+
+ $out .= '<source src="'.hsc($url).'" type="'.$mime.'" />'.NL;
+ // alternative content (just a link to the file)
+ $fallback .= $this->$linkType(
+ $file,
+ $title,
+ null,
+ null,
+ null,
+ $cache = null,
+ $linking = 'linkonly',
+ $return = true
+ );
+ }
+
+ // output each track if any
+ foreach( $tracks as $trackid => $info ) {
+ list( $kind, $srclang ) = array_map( 'hsc', $info );
+ $out .= "<track kind=\"$kind\" srclang=\"$srclang\" ";
+ $out .= "label=\"$srclang\" ";
+ $out .= 'src="'.ml($trackid, '', true).'">'.NL;
+ }
+
+ // finish
+ $out .= $fallback;
+ $out .= '</video>'.NL;
+ return $out;
+ }
+
+ /**
+ * Embed audio in HTML
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ *
+ * @param string $src - ID of audio to embed
+ * @param array $atts - additional attributes for the <audio> tag
+ * @return string
+ */
+ public function _audio($src, $atts = array()) {
+ $files = array();
+ $isExternal = media_isexternal($src);
+
+ if ($isExternal) {
+ // take direct source for external files
+ list(/*ext*/, $srcMime) = mimetype($src);
+ $files[$srcMime] = $src;
+ } else {
+ // prepare alternative formats
+ $extensions = array('ogg', 'mp3', 'wav');
+ $files = media_alternativefiles($src, $extensions);
+ }
+
+ $out = '';
+ // open audio tag
+ $out .= '<audio '.buildAttributes($atts).' controls="controls">'.NL;
+ $fallback = '';
+
+ // output source for each alternative audio format
+ foreach($files as $mime => $file) {
+ if ($isExternal) {
+ $url = $file;
+ $linkType = 'externalmedia';
+ } else {
+ $url = ml($file, '', true, '&');
+ $linkType = 'internalmedia';
+ }
+ $title = $atts['title'] ? $atts['title'] : $this->_xmlEntities(\dokuwiki\Utf8\PhpString::basename(noNS($file)));
+
+ $out .= '<source src="'.hsc($url).'" type="'.$mime.'" />'.NL;
+ // alternative content (just a link to the file)
+ $fallback .= $this->$linkType(
+ $file,
+ $title,
+ null,
+ null,
+ null,
+ $cache = null,
+ $linking = 'linkonly',
+ $return = true
+ );
+ }
+
+ // finish
+ $out .= $fallback;
+ $out .= '</audio>'.NL;
+ return $out;
+ }
+
+ /**
+ * _getLastMediaRevisionAt is a helperfunction to internalmedia() and _media()
+ * which returns an existing media revision less or equal to rev or date_at
+ *
+ * @author lisps
+ * @param string $media_id
+ * @access protected
+ * @return string revision ('' for current)
+ */
+ protected function _getLastMediaRevisionAt($media_id){
+ if(!$this->date_at || media_isexternal($media_id)) return '';
+ $pagelog = new MediaChangeLog($media_id);
+ return $pagelog->getLastRevisionAt($this->date_at);
+ }
+
+ #endregion
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/inc/parser/xhtmlsummary.php b/platform/www/inc/parser/xhtmlsummary.php
new file mode 100644
index 0000000..4641bf8
--- /dev/null
+++ b/platform/www/inc/parser/xhtmlsummary.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * The summary XHTML form selects either up to the first two paragraphs
+ * it find in a page or the first section (whichever comes first)
+ * It strips out the table of contents if one exists
+ * Section divs are not used - everything should be nested in a single
+ * div with CSS class "page"
+ * Headings have their a name link removed and section editing links
+ * removed
+ * It also attempts to capture the first heading in a page for
+ * use as the title of the page.
+ *
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @todo Is this currently used anywhere? Should it?
+ */
+class Doku_Renderer_xhtmlsummary extends Doku_Renderer_xhtml {
+
+ // Namespace these variables to
+ // avoid clashes with parent classes
+ protected $sum_paragraphs = 0;
+ protected $sum_capture = true;
+ protected $sum_inSection = false;
+ protected $sum_summary = '';
+ protected $sum_pageTitle = false;
+
+ /** @inheritdoc */
+ public function document_start() {
+ $this->doc .= DOKU_LF.'<div>'.DOKU_LF;
+ }
+
+ /** @inheritdoc */
+ public function document_end() {
+ $this->doc = $this->sum_summary;
+ $this->doc .= DOKU_LF.'</div>'.DOKU_LF;
+ }
+
+ /** @inheritdoc */
+ public function header($text, $level, $pos) {
+ if ( !$this->sum_pageTitle ) {
+ $this->info['sum_pagetitle'] = $text;
+ $this->sum_pageTitle = true;
+ }
+ $this->doc .= DOKU_LF.'<h'.$level.'>';
+ $this->doc .= $this->_xmlEntities($text);
+ $this->doc .= "</h$level>".DOKU_LF;
+ }
+
+ /** @inheritdoc */
+ public function section_open($level) {
+ if ( $this->sum_capture ) {
+ $this->sum_inSection = true;
+ }
+ }
+
+ /** @inheritdoc */
+ public function section_close() {
+ if ( $this->sum_capture && $this->sum_inSection ) {
+ $this->sum_summary .= $this->doc;
+ $this->sum_capture = false;
+ }
+ }
+
+ /** @inheritdoc */
+ public function p_open() {
+ if ( $this->sum_capture && $this->sum_paragraphs < 2 ) {
+ $this->sum_paragraphs++;
+ }
+ parent :: p_open();
+ }
+
+ /** @inheritdoc */
+ public function p_close() {
+ parent :: p_close();
+ if ( $this->sum_capture && $this->sum_paragraphs >= 2 ) {
+ $this->sum_summary .= $this->doc;
+ $this->sum_capture = false;
+ }
+ }
+
+}
+
+
+//Setup VIM: ex: et ts=2 :
diff --git a/platform/www/inc/parserutils.php b/platform/www/inc/parserutils.php
new file mode 100644
index 0000000..846be54
--- /dev/null
+++ b/platform/www/inc/parserutils.php
@@ -0,0 +1,809 @@
+<?php
+/**
+ * Utilities for accessing the parser
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Cache\CacheInstructions;
+use dokuwiki\Cache\CacheRenderer;
+use dokuwiki\ChangeLog\PageChangeLog;
+use dokuwiki\Extension\PluginController;
+use dokuwiki\Extension\Event;
+use dokuwiki\Parsing\Parser;
+
+/**
+ * How many pages shall be rendered for getting metadata during one request
+ * at maximum? Note that this limit isn't respected when METADATA_RENDER_UNLIMITED
+ * is passed as render parameter to p_get_metadata.
+ */
+if (!defined('P_GET_METADATA_RENDER_LIMIT')) define('P_GET_METADATA_RENDER_LIMIT', 5);
+
+/** Don't render metadata even if it is outdated or doesn't exist */
+define('METADATA_DONT_RENDER', 0);
+/**
+ * Render metadata when the page is really newer or the metadata doesn't exist.
+ * Uses just a simple check, but should work pretty well for loading simple
+ * metadata values like the page title and avoids rendering a lot of pages in
+ * one request. The P_GET_METADATA_RENDER_LIMIT is used in this mode.
+ * Use this if it is unlikely that the metadata value you are requesting
+ * does depend e.g. on pages that are included in the current page using
+ * the include plugin (this is very likely the case for the page title, but
+ * not for relation references).
+ */
+define('METADATA_RENDER_USING_SIMPLE_CACHE', 1);
+/**
+ * Render metadata using the metadata cache logic. The P_GET_METADATA_RENDER_LIMIT
+ * is used in this mode. Use this mode when you are requesting more complex
+ * metadata. Although this will cause rendering more often it might actually have
+ * the effect that less current metadata is returned as it is more likely than in
+ * the simple cache mode that metadata needs to be rendered for all pages at once
+ * which means that when the metadata for the page is requested that actually needs
+ * to be updated the limit might have been reached already.
+ */
+define('METADATA_RENDER_USING_CACHE', 2);
+/**
+ * Render metadata without limiting the number of pages for which metadata is
+ * rendered. Use this mode with care, normally it should only be used in places
+ * like the indexer or in cli scripts where the execution time normally isn't
+ * limited. This can be combined with the simple cache using
+ * METADATA_RENDER_USING_CACHE | METADATA_RENDER_UNLIMITED.
+ */
+define('METADATA_RENDER_UNLIMITED', 4);
+
+/**
+ * Returns the parsed Wikitext in XHTML for the given id and revision.
+ *
+ * If $excuse is true an explanation is returned if the file
+ * wasn't found
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id
+ * @param string|int $rev revision timestamp or empty string
+ * @param bool $excuse
+ * @param string $date_at
+ *
+ * @return null|string
+ */
+function p_wiki_xhtml($id, $rev='', $excuse=true,$date_at=''){
+ $file = wikiFN($id,$rev);
+ $ret = '';
+
+ //ensure $id is in global $ID (needed for parsing)
+ global $ID;
+ $keep = $ID;
+ $ID = $id;
+
+ if($rev || $date_at){
+ if(file_exists($file)){
+ //no caching on old revisions
+ $ret = p_render('xhtml',p_get_instructions(io_readWikiPage($file,$id,$rev)),$info,$date_at);
+ }elseif($excuse){
+ $ret = p_locale_xhtml('norev');
+ }
+ }else{
+ if(file_exists($file)){
+ $ret = p_cached_output($file,'xhtml',$id);
+ }elseif($excuse){
+ //check if the page once existed
+ $changelog = new PageChangeLog($id);
+ if($changelog->hasRevisions()) {
+ $ret = p_locale_xhtml('onceexisted');
+ } else {
+ $ret = p_locale_xhtml('newpage');
+ }
+ }
+ }
+
+ //restore ID (just in case)
+ $ID = $keep;
+
+ return $ret;
+}
+
+/**
+ * Returns the specified local text in parsed format
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id
+ * @return null|string
+ */
+function p_locale_xhtml($id){
+ //fetch parsed locale
+ $html = p_cached_output(localeFN($id));
+ return $html;
+}
+
+/**
+ * Returns the given file parsed into the requested output format
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $file filename, path to file
+ * @param string $format
+ * @param string $id page id
+ * @return null|string
+ */
+function p_cached_output($file, $format='xhtml', $id='') {
+ global $conf;
+
+ $cache = new CacheRenderer($id, $file, $format);
+ if ($cache->useCache()) {
+ $parsed = $cache->retrieveCache(false);
+ if($conf['allowdebug'] && $format=='xhtml') {
+ $parsed .= "\n<!-- cachefile {$cache->cache} used -->\n";
+ }
+ } else {
+ $parsed = p_render($format, p_cached_instructions($file,false,$id), $info);
+
+ if ($info['cache'] && $cache->storeCache($parsed)) { // storeCache() attempts to save cachefile
+ if($conf['allowdebug'] && $format=='xhtml') {
+ $parsed .= "\n<!-- no cachefile used, but created {$cache->cache} -->\n";
+ }
+ }else{
+ $cache->removeCache(); //try to delete cachefile
+ if($conf['allowdebug'] && $format=='xhtml') {
+ $parsed .= "\n<!-- no cachefile used, caching forbidden -->\n";
+ }
+ }
+ }
+
+ return $parsed;
+}
+
+/**
+ * Returns the render instructions for a file
+ *
+ * Uses and creates a serialized cache file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename, path to file
+ * @param bool $cacheonly
+ * @param string $id page id
+ * @return array|null
+ */
+function p_cached_instructions($file,$cacheonly=false,$id='') {
+ static $run = null;
+ if(is_null($run)) $run = array();
+
+ $cache = new CacheInstructions($id, $file);
+
+ if ($cacheonly || $cache->useCache() || (isset($run[$file]) && !defined('DOKU_UNITTEST'))) {
+ return $cache->retrieveCache();
+ } else if (file_exists($file)) {
+ // no cache - do some work
+ $ins = p_get_instructions(io_readWikiPage($file,$id));
+ if ($cache->storeCache($ins)) {
+ $run[$file] = true; // we won't rebuild these instructions in the same run again
+ } else {
+ msg('Unable to save cache file. Hint: disk full; file permissions; safe_mode setting.',-1);
+ }
+ return $ins;
+ }
+
+ return null;
+}
+
+/**
+ * turns a page into a list of instructions
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $text raw wiki syntax text
+ * @return array a list of instruction arrays
+ */
+function p_get_instructions($text){
+
+ $modes = p_get_parsermodes();
+
+ // Create the parser and handler
+ $Parser = new Parser(new Doku_Handler());
+
+ //add modes to parser
+ foreach($modes as $mode){
+ $Parser->addMode($mode['mode'],$mode['obj']);
+ }
+
+ // Do the parsing
+ Event::createAndTrigger('PARSER_WIKITEXT_PREPROCESS', $text);
+ $p = $Parser->parse($text);
+ // dbg($p);
+ return $p;
+}
+
+/**
+ * returns the metadata of a page
+ *
+ * @param string $id The id of the page the metadata should be returned from
+ * @param string $key The key of the metdata value that shall be read (by default everything)
+ * separate hierarchies by " " like "date created"
+ * @param int $render If the page should be rendererd - possible values:
+ * METADATA_DONT_RENDER, METADATA_RENDER_USING_SIMPLE_CACHE, METADATA_RENDER_USING_CACHE
+ * METADATA_RENDER_UNLIMITED (also combined with the previous two options),
+ * default: METADATA_RENDER_USING_CACHE
+ * @return mixed The requested metadata fields
+ *
+ * @author Esther Brunner <esther@kaffeehaus.ch>
+ * @author Michael Hamann <michael@content-space.de>
+ */
+function p_get_metadata($id, $key='', $render=METADATA_RENDER_USING_CACHE){
+ global $ID;
+ static $render_count = 0;
+ // track pages that have already been rendered in order to avoid rendering the same page
+ // again
+ static $rendered_pages = array();
+
+ // cache the current page
+ // Benchmarking shows the current page's metadata is generally the only page metadata
+ // accessed several times. This may catch a few other pages, but that shouldn't be an issue.
+ $cache = ($ID == $id);
+ $meta = p_read_metadata($id, $cache);
+
+ if (!is_numeric($render)) {
+ if ($render) {
+ $render = METADATA_RENDER_USING_SIMPLE_CACHE;
+ } else {
+ $render = METADATA_DONT_RENDER;
+ }
+ }
+
+ // prevent recursive calls in the cache
+ static $recursion = false;
+ if (!$recursion && $render != METADATA_DONT_RENDER && !isset($rendered_pages[$id])&& page_exists($id)){
+ $recursion = true;
+
+ $cachefile = new CacheRenderer($id, wikiFN($id), 'metadata');
+
+ $do_render = false;
+ if ($render & METADATA_RENDER_UNLIMITED || $render_count < P_GET_METADATA_RENDER_LIMIT) {
+ if ($render & METADATA_RENDER_USING_SIMPLE_CACHE) {
+ $pagefn = wikiFN($id);
+ $metafn = metaFN($id, '.meta');
+ if (!file_exists($metafn) || @filemtime($pagefn) > @filemtime($cachefile->cache)) {
+ $do_render = true;
+ }
+ } elseif (!$cachefile->useCache()){
+ $do_render = true;
+ }
+ }
+ if ($do_render) {
+ if (!defined('DOKU_UNITTEST')) {
+ ++$render_count;
+ $rendered_pages[$id] = true;
+ }
+ $old_meta = $meta;
+ $meta = p_render_metadata($id, $meta);
+ // only update the file when the metadata has been changed
+ if ($meta == $old_meta || p_save_metadata($id, $meta)) {
+ // store a timestamp in order to make sure that the cachefile is touched
+ // this timestamp is also stored when the meta data is still the same
+ $cachefile->storeCache(time());
+ } else {
+ msg('Unable to save metadata file. Hint: disk full; file permissions; safe_mode setting.',-1);
+ }
+ }
+
+ $recursion = false;
+ }
+
+ $val = $meta['current'];
+
+ // filter by $key
+ foreach(preg_split('/\s+/', $key, 2, PREG_SPLIT_NO_EMPTY) as $cur_key) {
+ if (!isset($val[$cur_key])) {
+ return null;
+ }
+ $val = $val[$cur_key];
+ }
+ return $val;
+}
+
+/**
+ * sets metadata elements of a page
+ *
+ * @see http://www.dokuwiki.org/devel:metadata#functions_to_get_and_set_metadata
+ *
+ * @param string $id is the ID of a wiki page
+ * @param array $data is an array with key ⇒ value pairs to be set in the metadata
+ * @param boolean $render whether or not the page metadata should be generated with the renderer
+ * @param boolean $persistent indicates whether or not the particular metadata value will persist through
+ * the next metadata rendering.
+ * @return boolean true on success
+ *
+ * @author Esther Brunner <esther@kaffeehaus.ch>
+ * @author Michael Hamann <michael@content-space.de>
+ */
+function p_set_metadata($id, $data, $render=false, $persistent=true){
+ if (!is_array($data)) return false;
+
+ global $ID, $METADATA_RENDERERS;
+
+ // if there is currently a renderer change the data in the renderer instead
+ if (isset($METADATA_RENDERERS[$id])) {
+ $orig =& $METADATA_RENDERERS[$id];
+ $meta = $orig;
+ } else {
+ // cache the current page
+ $cache = ($ID == $id);
+ $orig = p_read_metadata($id, $cache);
+
+ // render metadata first?
+ $meta = $render ? p_render_metadata($id, $orig) : $orig;
+ }
+
+ // now add the passed metadata
+ $protected = array('description', 'date', 'contributor');
+ foreach ($data as $key => $value){
+
+ // be careful with sub-arrays of $meta['relation']
+ if ($key == 'relation'){
+
+ foreach ($value as $subkey => $subvalue){
+ if(isset($meta['current'][$key][$subkey]) && is_array($meta['current'][$key][$subkey])) {
+ $meta['current'][$key][$subkey] = array_replace($meta['current'][$key][$subkey], (array)$subvalue);
+ } else {
+ $meta['current'][$key][$subkey] = $subvalue;
+ }
+ if($persistent) {
+ if(isset($meta['persistent'][$key][$subkey]) && is_array($meta['persistent'][$key][$subkey])) {
+ $meta['persistent'][$key][$subkey] = array_replace(
+ $meta['persistent'][$key][$subkey],
+ (array) $subvalue
+ );
+ } else {
+ $meta['persistent'][$key][$subkey] = $subvalue;
+ }
+ }
+ }
+
+ // be careful with some senisitive arrays of $meta
+ } elseif (in_array($key, $protected)){
+
+ // these keys, must have subkeys - a legitimate value must be an array
+ if (is_array($value)) {
+ $meta['current'][$key] = !empty($meta['current'][$key]) ?
+ array_replace((array)$meta['current'][$key],$value) :
+ $value;
+
+ if ($persistent) {
+ $meta['persistent'][$key] = !empty($meta['persistent'][$key]) ?
+ array_replace((array)$meta['persistent'][$key],$value) :
+ $value;
+ }
+ }
+
+ // no special treatment for the rest
+ } else {
+ $meta['current'][$key] = $value;
+ if ($persistent) $meta['persistent'][$key] = $value;
+ }
+ }
+
+ // save only if metadata changed
+ if ($meta == $orig) return true;
+
+ if (isset($METADATA_RENDERERS[$id])) {
+ // set both keys individually as the renderer has references to the individual keys
+ $METADATA_RENDERERS[$id]['current'] = $meta['current'];
+ $METADATA_RENDERERS[$id]['persistent'] = $meta['persistent'];
+ return true;
+ } else {
+ return p_save_metadata($id, $meta);
+ }
+}
+
+/**
+ * Purges the non-persistant part of the meta data
+ * used on page deletion
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ *
+ * @param string $id page id
+ * @return bool success / fail
+ */
+function p_purge_metadata($id) {
+ $meta = p_read_metadata($id);
+ foreach($meta['current'] as $key => $value) {
+ if(is_array($meta[$key])) {
+ $meta['current'][$key] = array();
+ } else {
+ $meta['current'][$key] = '';
+ }
+
+ }
+ return p_save_metadata($id, $meta);
+}
+
+/**
+ * read the metadata from source/cache for $id
+ * (internal use only - called by p_get_metadata & p_set_metadata)
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ *
+ * @param string $id absolute wiki page id
+ * @param bool $cache whether or not to cache metadata in memory
+ * (only use for metadata likely to be accessed several times)
+ *
+ * @return array metadata
+ */
+function p_read_metadata($id,$cache=false) {
+ global $cache_metadata;
+
+ if (isset($cache_metadata[(string)$id])) return $cache_metadata[(string)$id];
+
+ $file = metaFN($id, '.meta');
+ $meta = file_exists($file) ?
+ unserialize(io_readFile($file, false)) :
+ array('current'=>array(),'persistent'=>array());
+
+ if ($cache) {
+ $cache_metadata[(string)$id] = $meta;
+ }
+
+ return $meta;
+}
+
+/**
+ * This is the backend function to save a metadata array to a file
+ *
+ * @param string $id absolute wiki page id
+ * @param array $meta metadata
+ *
+ * @return bool success / fail
+ */
+function p_save_metadata($id, $meta) {
+ // sync cached copies, including $INFO metadata
+ global $cache_metadata, $INFO;
+
+ if (isset($cache_metadata[$id])) $cache_metadata[$id] = $meta;
+ if (!empty($INFO) && ($id == $INFO['id'])) { $INFO['meta'] = $meta['current']; }
+
+ return io_saveFile(metaFN($id, '.meta'), serialize($meta));
+}
+
+/**
+ * renders the metadata of a page
+ *
+ * @author Esther Brunner <esther@kaffeehaus.ch>
+ *
+ * @param string $id page id
+ * @param array $orig the original metadata
+ * @return array|null array('current'=> array,'persistent'=> array);
+ */
+function p_render_metadata($id, $orig){
+ // make sure the correct ID is in global ID
+ global $ID, $METADATA_RENDERERS;
+
+ // avoid recursive rendering processes for the same id
+ if (isset($METADATA_RENDERERS[$id])) {
+ return $orig;
+ }
+
+ // store the original metadata in the global $METADATA_RENDERERS so p_set_metadata can use it
+ $METADATA_RENDERERS[$id] =& $orig;
+
+ $keep = $ID;
+ $ID = $id;
+
+ // add an extra key for the event - to tell event handlers the page whose metadata this is
+ $orig['page'] = $id;
+ $evt = new Event('PARSER_METADATA_RENDER', $orig);
+ if ($evt->advise_before()) {
+
+ // get instructions
+ $instructions = p_cached_instructions(wikiFN($id),false,$id);
+ if(is_null($instructions)){
+ $ID = $keep;
+ unset($METADATA_RENDERERS[$id]);
+ return null; // something went wrong with the instructions
+ }
+
+ // set up the renderer
+ $renderer = new Doku_Renderer_metadata();
+ $renderer->meta =& $orig['current'];
+ $renderer->persistent =& $orig['persistent'];
+
+ // loop through the instructions
+ foreach ($instructions as $instruction){
+ // execute the callback against the renderer
+ call_user_func_array(array(&$renderer, $instruction[0]), (array) $instruction[1]);
+ }
+
+ $evt->result = array('current'=>&$renderer->meta,'persistent'=>&$renderer->persistent);
+ }
+ $evt->advise_after();
+
+ // clean up
+ $ID = $keep;
+ unset($METADATA_RENDERERS[$id]);
+ return $evt->result;
+}
+
+/**
+ * returns all available parser syntax modes in correct order
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return array[] with for each plugin the array('sort' => sortnumber, 'mode' => mode string, 'obj' => plugin object)
+ */
+function p_get_parsermodes(){
+ global $conf;
+
+ //reuse old data
+ static $modes = null;
+ if($modes != null && !defined('DOKU_UNITTEST')){
+ return $modes;
+ }
+
+ //import parser classes and mode definitions
+ require_once DOKU_INC . 'inc/parser/parser.php';
+
+ // we now collect all syntax modes and their objects, then they will
+ // be sorted and added to the parser in correct order
+ $modes = array();
+
+ // add syntax plugins
+ $pluginlist = plugin_list('syntax');
+ if(count($pluginlist)){
+ global $PARSER_MODES;
+ $obj = null;
+ foreach($pluginlist as $p){
+ /** @var \dokuwiki\Extension\SyntaxPlugin $obj */
+ if(!$obj = plugin_load('syntax',$p)) continue; //attempt to load plugin into $obj
+ $PARSER_MODES[$obj->getType()][] = "plugin_$p"; //register mode type
+ //add to modes
+ $modes[] = array(
+ 'sort' => $obj->getSort(),
+ 'mode' => "plugin_$p",
+ 'obj' => $obj,
+ );
+ unset($obj); //remove the reference
+ }
+ }
+
+ // add default modes
+ $std_modes = array('listblock','preformatted','notoc','nocache',
+ 'header','table','linebreak','footnote','hr',
+ 'unformatted','php','html','code','file','quote',
+ 'internallink','rss','media','externallink',
+ 'emaillink','windowssharelink','eol');
+ if($conf['typography']){
+ $std_modes[] = 'quotes';
+ $std_modes[] = 'multiplyentity';
+ }
+ foreach($std_modes as $m){
+ $class = 'dokuwiki\\Parsing\\ParserMode\\'.ucfirst($m);
+ $obj = new $class();
+ $modes[] = array(
+ 'sort' => $obj->getSort(),
+ 'mode' => $m,
+ 'obj' => $obj
+ );
+ }
+
+ // add formatting modes
+ $fmt_modes = array('strong','emphasis','underline','monospace',
+ 'subscript','superscript','deleted');
+ foreach($fmt_modes as $m){
+ $obj = new \dokuwiki\Parsing\ParserMode\Formatting($m);
+ $modes[] = array(
+ 'sort' => $obj->getSort(),
+ 'mode' => $m,
+ 'obj' => $obj
+ );
+ }
+
+ // add modes which need files
+ $obj = new \dokuwiki\Parsing\ParserMode\Smiley(array_keys(getSmileys()));
+ $modes[] = array('sort' => $obj->getSort(), 'mode' => 'smiley','obj' => $obj );
+ $obj = new \dokuwiki\Parsing\ParserMode\Acronym(array_keys(getAcronyms()));
+ $modes[] = array('sort' => $obj->getSort(), 'mode' => 'acronym','obj' => $obj );
+ $obj = new \dokuwiki\Parsing\ParserMode\Entity(array_keys(getEntities()));
+ $modes[] = array('sort' => $obj->getSort(), 'mode' => 'entity','obj' => $obj );
+
+ // add optional camelcase mode
+ if($conf['camelcase']){
+ $obj = new \dokuwiki\Parsing\ParserMode\Camelcaselink();
+ $modes[] = array('sort' => $obj->getSort(), 'mode' => 'camelcaselink','obj' => $obj );
+ }
+
+ //sort modes
+ usort($modes,'p_sort_modes');
+
+ return $modes;
+}
+
+/**
+ * Callback function for usort
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $a
+ * @param array $b
+ * @return int $a is lower/equal/higher than $b
+ */
+function p_sort_modes($a, $b){
+ if($a['sort'] == $b['sort']) return 0;
+ return ($a['sort'] < $b['sort']) ? -1 : 1;
+}
+
+/**
+ * Renders a list of instruction to the specified output mode
+ *
+ * In the $info array is information from the renderer returned
+ *
+ * @author Harry Fuecks <hfuecks@gmail.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $mode
+ * @param array|null|false $instructions
+ * @param array $info returns render info like enabled toc and cache
+ * @param string $date_at
+ * @return null|string rendered output
+ */
+function p_render($mode,$instructions,&$info,$date_at=''){
+ if(is_null($instructions)) return '';
+ if($instructions === false) return '';
+
+ $Renderer = p_get_renderer($mode);
+ if (is_null($Renderer)) return null;
+
+ $Renderer->reset();
+
+ if($date_at) {
+ $Renderer->date_at = $date_at;
+ }
+
+ $Renderer->smileys = getSmileys();
+ $Renderer->entities = getEntities();
+ $Renderer->acronyms = getAcronyms();
+ $Renderer->interwiki = getInterwiki();
+
+ // Loop through the instructions
+ foreach ( $instructions as $instruction ) {
+ // Execute the callback against the Renderer
+ if(method_exists($Renderer, $instruction[0])){
+ call_user_func_array(array(&$Renderer, $instruction[0]), $instruction[1] ? $instruction[1] : array());
+ }
+ }
+
+ //set info array
+ $info = $Renderer->info;
+
+ // Post process and return the output
+ $data = array($mode,& $Renderer->doc);
+ Event::createAndTrigger('RENDERER_CONTENT_POSTPROCESS',$data);
+ return $Renderer->doc;
+}
+
+/**
+ * Figure out the correct renderer class to use for $mode,
+ * instantiate and return it
+ *
+ * @param string $mode Mode of the renderer to get
+ * @return null|Doku_Renderer The renderer
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+function p_get_renderer($mode) {
+ /** @var PluginController $plugin_controller */
+ global $conf, $plugin_controller;
+
+ $rname = !empty($conf['renderer_'.$mode]) ? $conf['renderer_'.$mode] : $mode;
+ $rclass = "Doku_Renderer_$rname";
+
+ // if requested earlier or a bundled renderer
+ if( class_exists($rclass) ) {
+ $Renderer = new $rclass();
+ return $Renderer;
+ }
+
+ // not bundled, see if its an enabled renderer plugin & when $mode is 'xhtml', the renderer can supply that format.
+ /** @var Doku_Renderer $Renderer */
+ $Renderer = $plugin_controller->load('renderer',$rname);
+ if ($Renderer && is_a($Renderer, 'Doku_Renderer') && ($mode != 'xhtml' || $mode == $Renderer->getFormat())) {
+ return $Renderer;
+ }
+
+ // there is a configuration error!
+ // not bundled, not a valid enabled plugin, use $mode to try to fallback to a bundled renderer
+ $rclass = "Doku_Renderer_$mode";
+ if ( class_exists($rclass) ) {
+ // viewers should see renderered output, so restrict the warning to admins only
+ $msg = "No renderer '$rname' found for mode '$mode', check your plugins";
+ if ($mode == 'xhtml') {
+ $msg .= " and the 'renderer_xhtml' config setting";
+ }
+ $msg .= ".<br/>Attempting to fallback to the bundled renderer.";
+ msg($msg,-1,'','',MSG_ADMINS_ONLY);
+
+ $Renderer = new $rclass;
+ $Renderer->nocache(); // fallback only (and may include admin alerts), don't cache
+ return $Renderer;
+ }
+
+ // fallback failed, alert the world
+ msg("No renderer '$rname' found for mode '$mode'",-1);
+ return null;
+}
+
+/**
+ * Gets the first heading from a file
+ *
+ * @param string $id dokuwiki page id
+ * @param int $render rerender if first heading not known
+ * default: METADATA_RENDER_USING_SIMPLE_CACHE
+ * Possible values: METADATA_DONT_RENDER,
+ * METADATA_RENDER_USING_SIMPLE_CACHE,
+ * METADATA_RENDER_USING_CACHE,
+ * METADATA_RENDER_UNLIMITED
+ * @return string|null The first heading
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michael Hamann <michael@content-space.de>
+ */
+function p_get_first_heading($id, $render=METADATA_RENDER_USING_SIMPLE_CACHE){
+ return p_get_metadata(cleanID($id),'title',$render);
+}
+
+/**
+ * Wrapper for GeSHi Code Highlighter, provides caching of its output
+ *
+ * @param string $code source code to be highlighted
+ * @param string $language language to provide highlighting
+ * @param string $wrapper html element to wrap the returned highlighted text
+ * @return string xhtml code
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function p_xhtml_cached_geshi($code, $language, $wrapper='pre', array $options=null) {
+ global $conf, $config_cascade, $INPUT;
+ $language = strtolower($language);
+
+ // remove any leading or trailing blank lines
+ $code = preg_replace('/^\s*?\n|\s*?\n$/','',$code);
+
+ $optionsmd5 = md5(serialize($options));
+ $cache = getCacheName($language.$code.$optionsmd5,".code");
+ $ctime = @filemtime($cache);
+ if($ctime && !$INPUT->bool('purge') &&
+ $ctime > filemtime(DOKU_INC.'vendor/composer/installed.json') && // libraries changed
+ $ctime > filemtime(reset($config_cascade['main']['default']))){ // dokuwiki changed
+ $highlighted_code = io_readFile($cache, false);
+ } else {
+
+ $geshi = new GeSHi($code, $language);
+ $geshi->set_encoding('utf-8');
+ $geshi->enable_classes();
+ $geshi->set_header_type(GESHI_HEADER_PRE);
+ $geshi->set_link_target($conf['target']['extern']);
+ if($options !== null) {
+ foreach ($options as $function => $params) {
+ if(is_callable(array($geshi, $function))) {
+ $geshi->$function($params);
+ }
+ }
+ }
+
+ // remove GeSHi's wrapper element (we'll replace it with our own later)
+ // we need to use a GeSHi wrapper to avoid <BR> throughout the highlighted text
+ $highlighted_code = trim(preg_replace('!^<pre[^>]*>|</pre>$!','',$geshi->parse_code()),"\n\r");
+ io_saveFile($cache,$highlighted_code);
+ }
+
+ // add a wrapper element if required
+ if ($wrapper) {
+ return "<$wrapper class=\"code $language\">$highlighted_code</$wrapper>";
+ } else {
+ return $highlighted_code;
+ }
+}
+
diff --git a/platform/www/inc/pluginutils.php b/platform/www/inc/pluginutils.php
new file mode 100644
index 0000000..a93cd4f
--- /dev/null
+++ b/platform/www/inc/pluginutils.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * Utilities for handling plugins
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// plugin related constants
+use dokuwiki\Extension\AdminPlugin;
+use dokuwiki\Extension\PluginController;
+use dokuwiki\Extension\PluginInterface;
+
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+// note that only [a-z0-9]+ is officially supported,
+// this is only to support plugins that don't follow these conventions, too
+if(!defined('DOKU_PLUGIN_NAME_REGEX')) define('DOKU_PLUGIN_NAME_REGEX', '[a-zA-Z0-9\x7f-\xff]+');
+
+/**
+ * Original plugin functions, remain for backwards compatibility
+ */
+
+/**
+ * Return list of available plugins
+ *
+ * @param string $type type of plugins; empty string for all
+ * @param bool $all; true to retrieve all, false to retrieve only enabled plugins
+ * @return array with plugin names or plugin component names
+ */
+function plugin_list($type='',$all=false)
+{
+ /** @var $plugin_controller PluginController */
+ global $plugin_controller;
+ $plugins = $plugin_controller->getList($type,$all);
+ sort($plugins, SORT_NATURAL|SORT_FLAG_CASE);
+ return $plugins;
+}
+
+/**
+ * Returns plugin object
+ * Returns only new instances of a plugin when $new is true or if plugin is not Singleton,
+ * otherwise an already loaded instance.
+ *
+ * @param $type string type of plugin to load
+ * @param $name string name of the plugin to load
+ * @param $new bool true to return a new instance of the plugin, false to use an already loaded instance
+ * @param $disabled bool true to load even disabled plugins
+ * @return PluginInterface|null the plugin object or null on failure
+ */
+function plugin_load($type,$name,$new=false,$disabled=false)
+{
+ /** @var $plugin_controller PluginController */
+ global $plugin_controller;
+ return $plugin_controller->load($type,$name,$new,$disabled);
+}
+
+/**
+ * Whether plugin is disabled
+ *
+ * @param string $plugin name of plugin
+ * @return bool true disabled, false enabled
+ */
+function plugin_isdisabled($plugin)
+{
+ /** @var $plugin_controller PluginController */
+ global $plugin_controller;
+ return !$plugin_controller->isEnabled($plugin);
+}
+
+/**
+ * Enable the plugin
+ *
+ * @param string $plugin name of plugin
+ * @return bool true saving succeed, false saving failed
+ */
+function plugin_enable($plugin)
+{
+ /** @var $plugin_controller PluginController */
+ global $plugin_controller;
+ return $plugin_controller->enable($plugin);
+}
+
+/**
+ * Disable the plugin
+ *
+ * @param string $plugin name of plugin
+ * @return bool true saving succeed, false saving failed
+ */
+function plugin_disable($plugin)
+{
+ /** @var $plugin_controller PluginController */
+ global $plugin_controller;
+ return $plugin_controller->disable($plugin);
+}
+
+/**
+ * Returns directory name of plugin
+ *
+ * @param string $plugin name of plugin
+ * @return string name of directory
+ * @deprecated 2018-07-20
+ */
+function plugin_directory($plugin)
+{
+ dbg_deprecated('$plugin directly');
+ return $plugin;
+}
+
+/**
+ * Returns cascade of the config files
+ *
+ * @return array with arrays of plugin configs
+ */
+function plugin_getcascade()
+{
+ /** @var $plugin_controller PluginController */
+ global $plugin_controller;
+ return $plugin_controller->getCascade();
+}
+
+
+/**
+ * Return the currently operating admin plugin or null
+ * if not on an admin plugin page
+ *
+ * @return Doku_Plugin_Admin
+ */
+function plugin_getRequestAdminPlugin()
+{
+ static $admin_plugin = false;
+ global $ACT,$INPUT,$INFO;
+
+ if ($admin_plugin === false) {
+ if (($ACT == 'admin') && ($page = $INPUT->str('page', '', true)) != '') {
+ $pluginlist = plugin_list('admin');
+ if (in_array($page, $pluginlist)) {
+ // attempt to load the plugin
+ /** @var $admin_plugin AdminPlugin */
+ $admin_plugin = plugin_load('admin', $page);
+ // verify
+ if ($admin_plugin && !$admin_plugin->isAccessibleByCurrentUser()) {
+ $admin_plugin = null;
+ $INPUT->remove('page');
+ msg('For admins only',-1);
+ }
+ }
+ }
+ }
+
+ return $admin_plugin;
+}
diff --git a/platform/www/inc/preload.php b/platform/www/inc/preload.php
new file mode 100644
index 0000000..7146344
--- /dev/null
+++ b/platform/www/inc/preload.php
@@ -0,0 +1,5 @@
+<?php
+# farm setup by farmer plugin
+if(file_exists(__DIR__ . '/../lib/plugins/farmer/DokuWikiFarmCore.php')) {
+ include(__DIR__ . '/../lib/plugins/farmer/DokuWikiFarmCore.php');
+}
diff --git a/platform/www/inc/preload.php.dist b/platform/www/inc/preload.php.dist
new file mode 100644
index 0000000..7acda0e
--- /dev/null
+++ b/platform/www/inc/preload.php.dist
@@ -0,0 +1,17 @@
+<?php
+/**
+ * This is an example for a farm setup. Simply copy this file to preload.php and
+ * uncomment what you need. See http://www.dokuwiki.org/farms for more information.
+ * You can also use preload.php for other things than farming, e.g. for moving
+ * local configuration files out of the main ./conf directory.
+ */
+
+// set this to your farm directory
+//if(!defined('DOKU_FARMDIR')) define('DOKU_FARMDIR', '/var/www/farm');
+
+// include this after DOKU_FARMDIR if you want to use farms
+//include(fullpath(dirname(__FILE__)).'/farm.php');
+
+// you can overwrite the $config_cascade to your liking
+//$config_cascade = array(
+//);
diff --git a/platform/www/inc/search.php b/platform/www/inc/search.php
new file mode 100644
index 0000000..27efc65
--- /dev/null
+++ b/platform/www/inc/search.php
@@ -0,0 +1,518 @@
+<?php
+/**
+ * DokuWiki search functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+/**
+ * Recurse directory
+ *
+ * This function recurses into a given base directory
+ * and calls the supplied function for each file and directory
+ *
+ * @param array &$data The results of the search are stored here
+ * @param string $base Where to start the search
+ * @param callback $func Callback (function name or array with object,method)
+ * @param array $opts option array will be given to the Callback
+ * @param string $dir Current directory beyond $base
+ * @param int $lvl Recursion Level
+ * @param mixed $sort 'natural' to use natural order sorting (default);
+ * 'date' to sort by filemtime; leave empty to skip sorting.
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function search(&$data,$base,$func,$opts,$dir='',$lvl=1,$sort='natural'){
+ $dirs = array();
+ $files = array();
+ $filepaths = array();
+
+ // safeguard against runaways #1452
+ if($base == '' || $base == '/') {
+ throw new RuntimeException('No valid $base passed to search() - possible misconfiguration or bug');
+ }
+
+ //read in directories and files
+ $dh = @opendir($base.'/'.$dir);
+ if(!$dh) return;
+ while(($file = readdir($dh)) !== false){
+ if(preg_match('/^[\._]/',$file)) continue; //skip hidden files and upper dirs
+ if(is_dir($base.'/'.$dir.'/'.$file)){
+ $dirs[] = $dir.'/'.$file;
+ continue;
+ }
+ $files[] = $dir.'/'.$file;
+ $filepaths[] = $base.'/'.$dir.'/'.$file;
+ }
+ closedir($dh);
+ if (!empty($sort)) {
+ if ($sort == 'date') {
+ @array_multisort(array_map('filemtime', $filepaths), SORT_NUMERIC, SORT_DESC, $files);
+ } else /* natural */ {
+ natsort($files);
+ }
+ natsort($dirs);
+ }
+
+ //give directories to userfunction then recurse
+ foreach($dirs as $dir){
+ if (call_user_func_array($func, array(&$data,$base,$dir,'d',$lvl,$opts))){
+ search($data,$base,$func,$opts,$dir,$lvl+1,$sort);
+ }
+ }
+ //now handle the files
+ foreach($files as $file){
+ call_user_func_array($func, array(&$data,$base,$file,'f',$lvl,$opts));
+ }
+}
+
+/**
+ * The following functions are userfunctions to use with the search
+ * function above. This function is called for every found file or
+ * directory. When a directory is given to the function it has to
+ * decide if this directory should be traversed (true) or not (false)
+ * The function has to accept the following parameters:
+ *
+ * array &$data - Reference to the result data structure
+ * string $base - Base usually $conf['datadir']
+ * string $file - current file or directory relative to $base
+ * string $type - Type either 'd' for directory or 'f' for file
+ * int $lvl - Current recursion depht
+ * array $opts - option array as given to search()
+ *
+ * return values for files are ignored
+ *
+ * All functions should check the ACL for document READ rights
+ * namespaces (directories) are NOT checked (when sneaky_index is 0) as this
+ * would break the recursion (You can have an nonreadable dir over a readable
+ * one deeper nested) also make sure to check the file type (for example
+ * in case of lockfiles).
+ */
+
+/**
+ * Searches for pages beginning with the given query
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data
+ * @param string $base
+ * @param string $file
+ * @param string $type
+ * @param integer $lvl
+ * @param array $opts
+ *
+ * @return bool
+ */
+function search_qsearch(&$data,$base,$file,$type,$lvl,$opts){
+ $opts = array(
+ 'idmatch' => '(^|:)'.preg_quote($opts['query'],'/').'/',
+ 'listfiles' => true,
+ 'pagesonly' => true,
+ );
+ return search_universal($data,$base,$file,$type,$lvl,$opts);
+}
+
+/**
+ * Build the browsable index of pages
+ *
+ * $opts['ns'] is the currently viewed namespace
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data
+ * @param string $base
+ * @param string $file
+ * @param string $type
+ * @param integer $lvl
+ * @param array $opts
+ *
+ * @return bool
+ */
+function search_index(&$data,$base,$file,$type,$lvl,$opts){
+ global $conf;
+ $opts = array(
+ 'pagesonly' => true,
+ 'listdirs' => true,
+ 'listfiles' => empty($opts['nofiles']),
+ 'sneakyacl' => $conf['sneaky_index'],
+ // Hacky, should rather use recmatch
+ 'depth' => preg_match('#^'.preg_quote($file, '#').'(/|$)#','/'.$opts['ns']) ? 0 : -1
+ );
+
+ return search_universal($data, $base, $file, $type, $lvl, $opts);
+}
+
+/**
+ * List all namespaces
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data
+ * @param string $base
+ * @param string $file
+ * @param string $type
+ * @param integer $lvl
+ * @param array $opts
+ *
+ * @return bool
+ */
+function search_namespaces(&$data,$base,$file,$type,$lvl,$opts){
+ $opts = array(
+ 'listdirs' => true,
+ );
+ return search_universal($data,$base,$file,$type,$lvl,$opts);
+}
+
+/**
+ * List all mediafiles in a namespace
+ * $opts['depth'] recursion level, 0 for all
+ * $opts['showmsg'] shows message if invalid media id is used
+ * $opts['skipacl'] skip acl checking
+ * $opts['pattern'] check given pattern
+ * $opts['hash'] add hashes to result list
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data
+ * @param string $base
+ * @param string $file
+ * @param string $type
+ * @param integer $lvl
+ * @param array $opts
+ *
+ * @return bool
+ */
+function search_media(&$data,$base,$file,$type,$lvl,$opts){
+
+ //we do nothing with directories
+ if($type == 'd') {
+ if(empty($opts['depth'])) return true; // recurse forever
+ $depth = substr_count($file,'/');
+ if($depth >= $opts['depth']) return false; // depth reached
+ return true;
+ }
+
+ $info = array();
+ $info['id'] = pathID($file,true);
+ if($info['id'] != cleanID($info['id'])){
+ if($opts['showmsg'])
+ msg(hsc($info['id']).' is not a valid file name for DokuWiki - skipped',-1);
+ return false; // skip non-valid files
+ }
+
+ //check ACL for namespace (we have no ACL for mediafiles)
+ $info['perm'] = auth_quickaclcheck(getNS($info['id']).':*');
+ if(empty($opts['skipacl']) && $info['perm'] < AUTH_READ){
+ return false;
+ }
+
+ //check pattern filter
+ if(!empty($opts['pattern']) && !@preg_match($opts['pattern'], $info['id'])){
+ return false;
+ }
+
+ $info['file'] = \dokuwiki\Utf8\PhpString::basename($file);
+ $info['size'] = filesize($base.'/'.$file);
+ $info['mtime'] = filemtime($base.'/'.$file);
+ $info['writable'] = is_writable($base.'/'.$file);
+ if(preg_match("/\.(jpe?g|gif|png)$/",$file)){
+ $info['isimg'] = true;
+ $info['meta'] = new JpegMeta($base.'/'.$file);
+ }else{
+ $info['isimg'] = false;
+ }
+ if(!empty($opts['hash'])){
+ $info['hash'] = md5(io_readFile(mediaFN($info['id']),false));
+ }
+
+ $data[] = $info;
+
+ return false;
+}
+
+/**
+ * This function just lists documents (for RSS namespace export)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data
+ * @param string $base
+ * @param string $file
+ * @param string $type
+ * @param integer $lvl
+ * @param array $opts
+ *
+ * @return bool
+ */
+function search_list(&$data,$base,$file,$type,$lvl,$opts){
+ //we do nothing with directories
+ if($type == 'd') return false;
+ //only search txt files
+ if(substr($file,-4) == '.txt'){
+ //check ACL
+ $id = pathID($file);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return false;
+ }
+ $data[]['id'] = $id;
+ }
+ return false;
+}
+
+/**
+ * Quicksearch for searching matching pagenames
+ *
+ * $opts['query'] is the search query
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data
+ * @param string $base
+ * @param string $file
+ * @param string $type
+ * @param integer $lvl
+ * @param array $opts
+ *
+ * @return bool
+ */
+function search_pagename(&$data,$base,$file,$type,$lvl,$opts){
+ //we do nothing with directories
+ if($type == 'd') return true;
+ //only search txt files
+ if(substr($file,-4) != '.txt') return true;
+
+ //simple stringmatching
+ if (!empty($opts['query'])){
+ if(strpos($file,$opts['query']) !== false){
+ //check ACL
+ $id = pathID($file);
+ if(auth_quickaclcheck($id) < AUTH_READ){
+ return false;
+ }
+ $data[]['id'] = $id;
+ }
+ }
+ return true;
+}
+
+/**
+ * Just lists all documents
+ *
+ * $opts['depth'] recursion level, 0 for all
+ * $opts['hash'] do md5 sum of content?
+ * $opts['skipacl'] list everything regardless of ACL
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data
+ * @param string $base
+ * @param string $file
+ * @param string $type
+ * @param integer $lvl
+ * @param array $opts
+ *
+ * @return bool
+ */
+function search_allpages(&$data,$base,$file,$type,$lvl,$opts){
+ if(isset($opts['depth']) && $opts['depth']){
+ $parts = explode('/',ltrim($file,'/'));
+ if(($type == 'd' && count($parts) >= $opts['depth'])
+ || ($type != 'd' && count($parts) > $opts['depth'])){
+ return false; // depth reached
+ }
+ }
+
+ //we do nothing with directories
+ if($type == 'd'){
+ return true;
+ }
+
+ //only search txt files
+ if(substr($file,-4) != '.txt') return true;
+
+ $item = array();
+ $item['id'] = pathID($file);
+ if(empty($opts['skipacl']) && auth_quickaclcheck($item['id']) < AUTH_READ){
+ return false;
+ }
+
+ $item['rev'] = filemtime($base.'/'.$file);
+ $item['mtime'] = $item['rev'];
+ $item['size'] = filesize($base.'/'.$file);
+ if(!empty($opts['hash'])){
+ $item['hash'] = md5(trim(rawWiki($item['id'])));
+ }
+
+ $data[] = $item;
+ return true;
+}
+
+/* ------------- helper functions below -------------- */
+
+/**
+ * fulltext sort
+ *
+ * Callback sort function for use with usort to sort the data
+ * structure created by search_fulltext. Sorts descending by count
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $a
+ * @param array $b
+ *
+ * @return int
+ */
+function sort_search_fulltext($a,$b){
+ if($a['count'] > $b['count']){
+ return -1;
+ }elseif($a['count'] < $b['count']){
+ return 1;
+ }else{
+ return strcmp($a['id'],$b['id']);
+ }
+}
+
+/**
+ * translates a document path to an ID
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @todo move to pageutils
+ *
+ * @param string $path
+ * @param bool $keeptxt
+ *
+ * @return mixed|string
+ */
+function pathID($path,$keeptxt=false){
+ $id = utf8_decodeFN($path);
+ $id = str_replace('/',':',$id);
+ if(!$keeptxt) $id = preg_replace('#\.txt$#','',$id);
+ $id = trim($id, ':');
+ return $id;
+}
+
+
+/**
+ * This is a very universal callback for the search() function, replacing
+ * many of the former individual functions at the cost of a more complex
+ * setup.
+ *
+ * How the function behaves, depends on the options passed in the $opts
+ * array, where the following settings can be used.
+ *
+ * depth int recursion depth. 0 for unlimited (default: 0)
+ * keeptxt bool keep .txt extension for IDs (default: false)
+ * listfiles bool include files in listing (default: false)
+ * listdirs bool include namespaces in listing (default: false)
+ * pagesonly bool restrict files to pages (default: false)
+ * skipacl bool do not check for READ permission (default: false)
+ * sneakyacl bool don't recurse into nonreadable dirs (default: false)
+ * hash bool create MD5 hash for files (default: false)
+ * meta bool return file metadata (default: false)
+ * filematch string match files against this regexp (default: '', so accept everything)
+ * idmatch string match full ID against this regexp (default: '', so accept everything)
+ * dirmatch string match directory against this regexp when adding (default: '', so accept everything)
+ * nsmatch string match namespace against this regexp when adding (default: '', so accept everything)
+ * recmatch string match directory against this regexp when recursing (default: '', so accept everything)
+ * showmsg bool warn about non-ID files (default: false)
+ * showhidden bool show hidden files(e.g. by hidepages config) too (default: false)
+ * firsthead bool return first heading for pages (default: false)
+ *
+ * @param array &$data - Reference to the result data structure
+ * @param string $base - Base usually $conf['datadir']
+ * @param string $file - current file or directory relative to $base
+ * @param string $type - Type either 'd' for directory or 'f' for file
+ * @param int $lvl - Current recursion depht
+ * @param array $opts - option array as given to search()
+ * @return bool if this directory should be traversed (true) or not (false)
+ * return value is ignored for files
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+function search_universal(&$data,$base,$file,$type,$lvl,$opts){
+ $item = array();
+ $return = true;
+
+ // get ID and check if it is a valid one
+ $item['id'] = pathID($file,($type == 'd' || !empty($opts['keeptxt'])));
+ if($item['id'] != cleanID($item['id'])){
+ if(!empty($opts['showmsg'])){
+ msg(hsc($item['id']).' is not a valid file name for DokuWiki - skipped',-1);
+ }
+ return false; // skip non-valid files
+ }
+ $item['ns'] = getNS($item['id']);
+
+ if($type == 'd') {
+ // decide if to recursion into this directory is wanted
+ if(empty($opts['depth'])){
+ $return = true; // recurse forever
+ }else{
+ $depth = substr_count($file,'/');
+ if($depth >= $opts['depth']){
+ $return = false; // depth reached
+ }else{
+ $return = true;
+ }
+ }
+
+ if ($return) {
+ $match = empty($opts['recmatch']) || preg_match('/'.$opts['recmatch'].'/',$file);
+ if (!$match) {
+ return false; // doesn't match
+ }
+ }
+ }
+
+ // check ACL
+ if(empty($opts['skipacl'])){
+ if($type == 'd'){
+ $item['perm'] = auth_quickaclcheck($item['id'].':*');
+ }else{
+ $item['perm'] = auth_quickaclcheck($item['id']); //FIXME check namespace for media files
+ }
+ }else{
+ $item['perm'] = AUTH_DELETE;
+ }
+
+ // are we done here maybe?
+ if($type == 'd'){
+ if(empty($opts['listdirs'])) return $return;
+ //neither list nor recurse forbidden items:
+ if(empty($opts['skipacl']) && !empty($opts['sneakyacl']) && $item['perm'] < AUTH_READ) return false;
+ if(!empty($opts['dirmatch']) && !preg_match('/'.$opts['dirmatch'].'/',$file)) return $return;
+ if(!empty($opts['nsmatch']) && !preg_match('/'.$opts['nsmatch'].'/',$item['ns'])) return $return;
+ }else{
+ if(empty($opts['listfiles'])) return $return;
+ if(empty($opts['skipacl']) && $item['perm'] < AUTH_READ) return $return;
+ if(!empty($opts['pagesonly']) && (substr($file,-4) != '.txt')) return $return;
+ if(empty($opts['showhidden']) && isHiddenPage($item['id'])) return $return;
+ if(!empty($opts['filematch']) && !preg_match('/'.$opts['filematch'].'/',$file)) return $return;
+ if(!empty($opts['idmatch']) && !preg_match('/'.$opts['idmatch'].'/',$item['id'])) return $return;
+ }
+
+ // still here? prepare the item
+ $item['type'] = $type;
+ $item['level'] = $lvl;
+ $item['open'] = $return;
+
+ if(!empty($opts['meta'])){
+ $item['file'] = \dokuwiki\Utf8\PhpString::basename($file);
+ $item['size'] = filesize($base.'/'.$file);
+ $item['mtime'] = filemtime($base.'/'.$file);
+ $item['rev'] = $item['mtime'];
+ $item['writable'] = is_writable($base.'/'.$file);
+ $item['executable'] = is_executable($base.'/'.$file);
+ }
+
+ if($type == 'f'){
+ if(!empty($opts['hash'])) $item['hash'] = md5(io_readFile($base.'/'.$file,false));
+ if(!empty($opts['firsthead'])) $item['title'] = p_get_first_heading($item['id'],METADATA_DONT_RENDER);
+ }
+
+ // finally add the item
+ $data[] = $item;
+ return $return;
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/inc/template.php b/platform/www/inc/template.php
new file mode 100644
index 0000000..cb8f560
--- /dev/null
+++ b/platform/www/inc/template.php
@@ -0,0 +1,1895 @@
+<?php
+/**
+ * DokuWiki template functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Extension\AdminPlugin;
+use dokuwiki\Extension\Event;
+
+/**
+ * Access a template file
+ *
+ * Returns the path to the given file inside the current template, uses
+ * default template if the custom version doesn't exist.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $file
+ * @return string
+ */
+function template($file) {
+ global $conf;
+
+ if(@is_readable(DOKU_INC.'lib/tpl/'.$conf['template'].'/'.$file))
+ return DOKU_INC.'lib/tpl/'.$conf['template'].'/'.$file;
+
+ return DOKU_INC.'lib/tpl/dokuwiki/'.$file;
+}
+
+/**
+ * Convenience function to access template dir from local FS
+ *
+ * This replaces the deprecated DOKU_TPLINC constant
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $tpl The template to use, default to current one
+ * @return string
+ */
+function tpl_incdir($tpl='') {
+ global $conf;
+ if(!$tpl) $tpl = $conf['template'];
+ return DOKU_INC.'lib/tpl/'.$tpl.'/';
+}
+
+/**
+ * Convenience function to access template dir from web
+ *
+ * This replaces the deprecated DOKU_TPL constant
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $tpl The template to use, default to current one
+ * @return string
+ */
+function tpl_basedir($tpl='') {
+ global $conf;
+ if(!$tpl) $tpl = $conf['template'];
+ return DOKU_BASE.'lib/tpl/'.$tpl.'/';
+}
+
+/**
+ * Print the content
+ *
+ * This function is used for printing all the usual content
+ * (defined by the global $ACT var) by calling the appropriate
+ * outputfunction(s) from html.php
+ *
+ * Everything that doesn't use the main template file isn't
+ * handled by this function. ACL stuff is not done here either.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @triggers TPL_ACT_RENDER
+ * @triggers TPL_CONTENT_DISPLAY
+ * @param bool $prependTOC should the TOC be displayed here?
+ * @return bool true if any output
+ */
+function tpl_content($prependTOC = true) {
+ global $ACT;
+ global $INFO;
+ $INFO['prependTOC'] = $prependTOC;
+
+ ob_start();
+ Event::createAndTrigger('TPL_ACT_RENDER', $ACT, 'tpl_content_core');
+ $html_output = ob_get_clean();
+ Event::createAndTrigger('TPL_CONTENT_DISPLAY', $html_output, 'ptln');
+
+ return !empty($html_output);
+}
+
+/**
+ * Default Action of TPL_ACT_RENDER
+ *
+ * @return bool
+ */
+function tpl_content_core() {
+ $router = \dokuwiki\ActionRouter::getInstance();
+ try {
+ $router->getAction()->tplContent();
+ } catch(\dokuwiki\Action\Exception\FatalException $e) {
+ // there was no content for the action
+ msg(hsc($e->getMessage()), -1);
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Places the TOC where the function is called
+ *
+ * If you use this you most probably want to call tpl_content with
+ * a false argument
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param bool $return Should the TOC be returned instead to be printed?
+ * @return string
+ */
+function tpl_toc($return = false) {
+ global $TOC;
+ global $ACT;
+ global $ID;
+ global $REV;
+ global $INFO;
+ global $conf;
+ global $INPUT;
+ $toc = array();
+
+ if(is_array($TOC)) {
+ // if a TOC was prepared in global scope, always use it
+ $toc = $TOC;
+ } elseif(($ACT == 'show' || substr($ACT, 0, 6) == 'export') && !$REV && $INFO['exists']) {
+ // get TOC from metadata, render if neccessary
+ $meta = p_get_metadata($ID, '', METADATA_RENDER_USING_CACHE);
+ if(isset($meta['internal']['toc'])) {
+ $tocok = $meta['internal']['toc'];
+ } else {
+ $tocok = true;
+ }
+ $toc = isset($meta['description']['tableofcontents']) ? $meta['description']['tableofcontents'] : null;
+ if(!$tocok || !is_array($toc) || !$conf['tocminheads'] || count($toc) < $conf['tocminheads']) {
+ $toc = array();
+ }
+ } elseif($ACT == 'admin') {
+ // try to load admin plugin TOC
+ /** @var $plugin AdminPlugin */
+ if ($plugin = plugin_getRequestAdminPlugin()) {
+ $toc = $plugin->getTOC();
+ $TOC = $toc; // avoid later rebuild
+ }
+ }
+
+ Event::createAndTrigger('TPL_TOC_RENDER', $toc, null, false);
+ $html = html_TOC($toc);
+ if($return) return $html;
+ echo $html;
+ return '';
+}
+
+/**
+ * Handle the admin page contents
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return bool
+ */
+function tpl_admin() {
+ global $INFO;
+ global $TOC;
+ global $INPUT;
+
+ $plugin = null;
+ $class = $INPUT->str('page');
+ if(!empty($class)) {
+ $pluginlist = plugin_list('admin');
+
+ if(in_array($class, $pluginlist)) {
+ // attempt to load the plugin
+ /** @var $plugin AdminPlugin */
+ $plugin = plugin_load('admin', $class);
+ }
+ }
+
+ if($plugin !== null) {
+ if(!is_array($TOC)) $TOC = $plugin->getTOC(); //if TOC wasn't requested yet
+ if($INFO['prependTOC']) tpl_toc();
+ $plugin->html();
+ } else {
+ $admin = new dokuwiki\Ui\Admin();
+ $admin->show();
+ }
+ return true;
+}
+
+/**
+ * Print the correct HTML meta headers
+ *
+ * This has to go into the head section of your template.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @triggers TPL_METAHEADER_OUTPUT
+ * @param bool $alt Should feeds and alternative format links be added?
+ * @return bool
+ */
+function tpl_metaheaders($alt = true) {
+ global $ID;
+ global $REV;
+ global $INFO;
+ global $JSINFO;
+ global $ACT;
+ global $QUERY;
+ global $lang;
+ global $conf;
+ global $updateVersion;
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ // prepare the head array
+ $head = array();
+
+ // prepare seed for js and css
+ $tseed = $updateVersion;
+ $depends = getConfigFiles('main');
+ $depends[] = DOKU_CONF."tpl/".$conf['template']."/style.ini";
+ foreach($depends as $f) $tseed .= @filemtime($f);
+ $tseed = md5($tseed);
+
+ // the usual stuff
+ $head['meta'][] = array('name'=> 'generator', 'content'=> 'DokuWiki');
+ if(actionOK('search')) {
+ $head['link'][] = array(
+ 'rel' => 'search', 'type'=> 'application/opensearchdescription+xml',
+ 'href'=> DOKU_BASE.'lib/exe/opensearch.php', 'title'=> $conf['title']
+ );
+ }
+
+ $head['link'][] = array('rel'=> 'start', 'href'=> DOKU_BASE);
+ if(actionOK('index')) {
+ $head['link'][] = array(
+ 'rel' => 'contents', 'href'=> wl($ID, 'do=index', false, '&'),
+ 'title'=> $lang['btn_index']
+ );
+ }
+
+ if (actionOK('manifest')) {
+ $head['link'][] = array('rel'=> 'manifest', 'href'=> DOKU_BASE.'lib/exe/manifest.php');
+ }
+
+ $styleUtil = new \dokuwiki\StyleUtils();
+ $styleIni = $styleUtil->cssStyleini();
+ $replacements = $styleIni['replacements'];
+ if (!empty($replacements['__theme_color__'])) {
+ $head['meta'][] = array('name' => 'theme-color', 'content' => $replacements['__theme_color__']);
+ }
+
+ if($alt) {
+ if(actionOK('rss')) {
+ $head['link'][] = array(
+ 'rel' => 'alternate', 'type'=> 'application/rss+xml',
+ 'title'=> $lang['btn_recent'], 'href'=> DOKU_BASE.'feed.php'
+ );
+ $head['link'][] = array(
+ 'rel' => 'alternate', 'type'=> 'application/rss+xml',
+ 'title'=> $lang['currentns'],
+ 'href' => DOKU_BASE.'feed.php?mode=list&ns='.(isset($INFO) ? $INFO['namespace'] : '')
+ );
+ }
+ if(($ACT == 'show' || $ACT == 'search') && $INFO['writable']) {
+ $head['link'][] = array(
+ 'rel' => 'edit',
+ 'title'=> $lang['btn_edit'],
+ 'href' => wl($ID, 'do=edit', false, '&')
+ );
+ }
+
+ if(actionOK('rss') && $ACT == 'search') {
+ $head['link'][] = array(
+ 'rel' => 'alternate', 'type'=> 'application/rss+xml',
+ 'title'=> $lang['searchresult'],
+ 'href' => DOKU_BASE.'feed.php?mode=search&q='.$QUERY
+ );
+ }
+
+ if(actionOK('export_xhtml')) {
+ $head['link'][] = array(
+ 'rel' => 'alternate', 'type'=> 'text/html', 'title'=> $lang['plainhtml'],
+ 'href'=> exportlink($ID, 'xhtml', '', false, '&')
+ );
+ }
+
+ if(actionOK('export_raw')) {
+ $head['link'][] = array(
+ 'rel' => 'alternate', 'type'=> 'text/plain', 'title'=> $lang['wikimarkup'],
+ 'href'=> exportlink($ID, 'raw', '', false, '&')
+ );
+ }
+ }
+
+ // setup robot tags apropriate for different modes
+ if(($ACT == 'show' || $ACT == 'export_xhtml') && !$REV) {
+ if($INFO['exists']) {
+ //delay indexing:
+ if((time() - $INFO['lastmod']) >= $conf['indexdelay'] && !isHiddenPage($ID) ) {
+ $head['meta'][] = array('name'=> 'robots', 'content'=> 'index,follow');
+ } else {
+ $head['meta'][] = array('name'=> 'robots', 'content'=> 'noindex,nofollow');
+ }
+ $canonicalUrl = wl($ID, '', true, '&');
+ if ($ID == $conf['start']) {
+ $canonicalUrl = DOKU_URL;
+ }
+ $head['link'][] = array('rel'=> 'canonical', 'href'=> $canonicalUrl);
+ } else {
+ $head['meta'][] = array('name'=> 'robots', 'content'=> 'noindex,follow');
+ }
+ } elseif(defined('DOKU_MEDIADETAIL')) {
+ $head['meta'][] = array('name'=> 'robots', 'content'=> 'index,follow');
+ } else {
+ $head['meta'][] = array('name'=> 'robots', 'content'=> 'noindex,nofollow');
+ }
+
+ // set metadata
+ if($ACT == 'show' || $ACT == 'export_xhtml') {
+ // keywords (explicit or implicit)
+ if(!empty($INFO['meta']['subject'])) {
+ $head['meta'][] = array('name'=> 'keywords', 'content'=> join(',', $INFO['meta']['subject']));
+ } else {
+ $head['meta'][] = array('name'=> 'keywords', 'content'=> str_replace(':', ',', $ID));
+ }
+ }
+
+ // load stylesheets
+ $head['link'][] = array(
+ 'rel' => 'stylesheet',
+ 'href'=> DOKU_BASE.'lib/exe/css.php?t='.rawurlencode($conf['template']).'&tseed='.$tseed
+ );
+
+ $script = "var NS='".(isset($INFO)?$INFO['namespace']:'')."';";
+ if($conf['useacl'] && $INPUT->server->str('REMOTE_USER')) {
+ $script .= "var SIG=".toolbar_signature().";";
+ }
+ jsinfo();
+ $script .= 'var JSINFO = ' . json_encode($JSINFO).';';
+ $head['script'][] = array('_data'=> $script);
+
+ // load jquery
+ $jquery = getCdnUrls();
+ foreach($jquery as $src) {
+ $head['script'][] = array(
+ 'charset' => 'utf-8',
+ '_data' => '',
+ 'src' => $src,
+ ) + ($conf['defer_js'] ? [ 'defer' => 'defer'] : []);
+ }
+
+ // load our javascript dispatcher
+ $head['script'][] = array(
+ 'charset'=> 'utf-8', '_data'=> '',
+ 'src' => DOKU_BASE.'lib/exe/js.php'.'?t='.rawurlencode($conf['template']).'&tseed='.$tseed,
+ ) + ($conf['defer_js'] ? [ 'defer' => 'defer'] : []);
+
+ // trigger event here
+ Event::createAndTrigger('TPL_METAHEADER_OUTPUT', $head, '_tpl_metaheaders_action', true);
+ return true;
+}
+
+/**
+ * prints the array build by tpl_metaheaders
+ *
+ * $data is an array of different header tags. Each tag can have multiple
+ * instances. Attributes are given as key value pairs. Values will be HTML
+ * encoded automatically so they should be provided as is in the $data array.
+ *
+ * For tags having a body attribute specify the body data in the special
+ * attribute '_data'. This field will NOT BE ESCAPED automatically.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $data
+ */
+function _tpl_metaheaders_action($data) {
+ foreach($data as $tag => $inst) {
+ if($tag == 'script') {
+ echo "<!--[if gte IE 9]><!-->\n"; // no scripts for old IE
+ }
+ foreach($inst as $attr) {
+ if ( empty($attr) ) { continue; }
+ echo '<', $tag, ' ', buildAttributes($attr);
+ if(isset($attr['_data']) || $tag == 'script') {
+ if($tag == 'script' && $attr['_data'])
+ $attr['_data'] = "/*<![CDATA[*/".
+ $attr['_data'].
+ "\n/*!]]>*/";
+
+ echo '>', $attr['_data'], '</', $tag, '>';
+ } else {
+ echo '/>';
+ }
+ echo "\n";
+ }
+ if($tag == 'script') {
+ echo "<!--<![endif]-->\n";
+ }
+ }
+}
+
+/**
+ * Print a link
+ *
+ * Just builds a link.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $url
+ * @param string $name
+ * @param string $more
+ * @param bool $return if true return the link html, otherwise print
+ * @return bool|string html of the link, or true if printed
+ */
+function tpl_link($url, $name, $more = '', $return = false) {
+ $out = '<a href="'.$url.'" ';
+ if($more) $out .= ' '.$more;
+ $out .= ">$name</a>";
+ if($return) return $out;
+ print $out;
+ return true;
+}
+
+/**
+ * Prints a link to a WikiPage
+ *
+ * Wrapper around html_wikilink
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id
+ * @param string|null $name the name of the link
+ * @param bool $return
+ * @return true|string
+ */
+function tpl_pagelink($id, $name = null, $return = false) {
+ $out = '<bdi>'.html_wikilink($id, $name).'</bdi>';
+ if($return) return $out;
+ print $out;
+ return true;
+}
+
+/**
+ * get the parent page
+ *
+ * Tries to find out which page is parent.
+ * returns false if none is available
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id
+ * @return false|string
+ */
+function tpl_getparent($id) {
+ $parent = getNS($id).':';
+ resolve_pageid('', $parent, $exists);
+ if($parent == $id) {
+ $pos = strrpos(getNS($id), ':');
+ $parent = substr($parent, 0, $pos).':';
+ resolve_pageid('', $parent, $exists);
+ if($parent == $id) return false;
+ }
+ return $parent;
+}
+
+/**
+ * Print one of the buttons
+ *
+ * @author Adrian Lang <mail@adrianlang.de>
+ * @see tpl_get_action
+ *
+ * @param string $type
+ * @param bool $return
+ * @return bool|string html, or false if no data, true if printed
+ * @deprecated 2017-09-01 see devel:menus
+ */
+function tpl_button($type, $return = false) {
+ dbg_deprecated('see devel:menus');
+ $data = tpl_get_action($type);
+ if($data === false) {
+ return false;
+ } elseif(!is_array($data)) {
+ $out = sprintf($data, 'button');
+ } else {
+ /**
+ * @var string $accesskey
+ * @var string $id
+ * @var string $method
+ * @var array $params
+ */
+ extract($data);
+ if($id === '#dokuwiki__top') {
+ $out = html_topbtn();
+ } else {
+ $out = html_btn($type, $id, $accesskey, $params, $method);
+ }
+ }
+ if($return) return $out;
+ echo $out;
+ return true;
+}
+
+/**
+ * Like the action buttons but links
+ *
+ * @author Adrian Lang <mail@adrianlang.de>
+ * @see tpl_get_action
+ *
+ * @param string $type action command
+ * @param string $pre prefix of link
+ * @param string $suf suffix of link
+ * @param string $inner innerHML of link
+ * @param bool $return if true it returns html, otherwise prints
+ * @return bool|string html or false if no data, true if printed
+ * @deprecated 2017-09-01 see devel:menus
+ */
+function tpl_actionlink($type, $pre = '', $suf = '', $inner = '', $return = false) {
+ dbg_deprecated('see devel:menus');
+ global $lang;
+ $data = tpl_get_action($type);
+ if($data === false) {
+ return false;
+ } elseif(!is_array($data)) {
+ $out = sprintf($data, 'link');
+ } else {
+ /**
+ * @var string $accesskey
+ * @var string $id
+ * @var string $method
+ * @var bool $nofollow
+ * @var array $params
+ * @var string $replacement
+ */
+ extract($data);
+ if(strpos($id, '#') === 0) {
+ $linktarget = $id;
+ } else {
+ $linktarget = wl($id, $params);
+ }
+ $caption = $lang['btn_'.$type];
+ if(strpos($caption, '%s')){
+ $caption = sprintf($caption, $replacement);
+ }
+ $akey = $addTitle = '';
+ if($accesskey) {
+ $akey = 'accesskey="'.$accesskey.'" ';
+ $addTitle = ' ['.strtoupper($accesskey).']';
+ }
+ $rel = $nofollow ? 'rel="nofollow" ' : '';
+ $out = tpl_link(
+ $linktarget, $pre.(($inner) ? $inner : $caption).$suf,
+ 'class="action '.$type.'" '.
+ $akey.$rel.
+ 'title="'.hsc($caption).$addTitle.'"', true
+ );
+ }
+ if($return) return $out;
+ echo $out;
+ return true;
+}
+
+/**
+ * Check the actions and get data for buttons and links
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ * @author Adrian Lang <mail@adrianlang.de>
+ *
+ * @param string $type
+ * @return array|bool|string
+ * @deprecated 2017-09-01 see devel:menus
+ */
+function tpl_get_action($type) {
+ dbg_deprecated('see devel:menus');
+ if($type == 'history') $type = 'revisions';
+ if($type == 'subscription') $type = 'subscribe';
+ if($type == 'img_backto') $type = 'imgBackto';
+
+ $class = '\\dokuwiki\\Menu\\Item\\' . ucfirst($type);
+ if(class_exists($class)) {
+ try {
+ /** @var \dokuwiki\Menu\Item\AbstractItem $item */
+ $item = new $class;
+ $data = $item->getLegacyData();
+ $unknown = false;
+ } catch(\RuntimeException $ignored) {
+ return false;
+ }
+ } else {
+ global $ID;
+ $data = array(
+ 'accesskey' => null,
+ 'type' => $type,
+ 'id' => $ID,
+ 'method' => 'get',
+ 'params' => array('do' => $type),
+ 'nofollow' => true,
+ 'replacement' => '',
+ );
+ $unknown = true;
+ }
+
+ $evt = new Event('TPL_ACTION_GET', $data);
+ if($evt->advise_before()) {
+ //handle unknown types
+ if($unknown) {
+ $data = '[unknown %s type]';
+ }
+ }
+ $evt->advise_after();
+ unset($evt);
+
+ return $data;
+}
+
+/**
+ * Wrapper around tpl_button() and tpl_actionlink()
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ *
+ * @param string $type action command
+ * @param bool $link link or form button?
+ * @param string|bool $wrapper HTML element wrapper
+ * @param bool $return return or print
+ * @param string $pre prefix for links
+ * @param string $suf suffix for links
+ * @param string $inner inner HTML for links
+ * @return bool|string
+ * @deprecated 2017-09-01 see devel:menus
+ */
+function tpl_action($type, $link = false, $wrapper = false, $return = false, $pre = '', $suf = '', $inner = '') {
+ dbg_deprecated('see devel:menus');
+ $out = '';
+ if($link) {
+ $out .= tpl_actionlink($type, $pre, $suf, $inner, true);
+ } else {
+ $out .= tpl_button($type, true);
+ }
+ if($out && $wrapper) $out = "<$wrapper>$out</$wrapper>";
+
+ if($return) return $out;
+ print $out;
+ return $out ? true : false;
+}
+
+/**
+ * Print the search form
+ *
+ * If the first parameter is given a div with the ID 'qsearch_out' will
+ * be added which instructs the ajax pagequicksearch to kick in and place
+ * its output into this div. The second parameter controls the propritary
+ * attribute autocomplete. If set to false this attribute will be set with an
+ * value of "off" to instruct the browser to disable it's own built in
+ * autocompletion feature (MSIE and Firefox)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param bool $ajax
+ * @param bool $autocomplete
+ * @return bool
+ */
+function tpl_searchform($ajax = true, $autocomplete = true) {
+ global $lang;
+ global $ACT;
+ global $QUERY;
+ global $ID;
+
+ // don't print the search form if search action has been disabled
+ if(!actionOK('search')) return false;
+
+ $searchForm = new dokuwiki\Form\Form([
+ 'action' => wl(),
+ 'method' => 'get',
+ 'role' => 'search',
+ 'class' => 'search',
+ 'id' => 'dw__search',
+ ], true);
+ $searchForm->addTagOpen('div')->addClass('no');
+ $searchForm->setHiddenField('do', 'search');
+ $searchForm->setHiddenField('id', $ID);
+ $searchForm->addTextInput('q')
+ ->addClass('edit')
+ ->attrs([
+ 'title' => '[F]',
+ 'accesskey' => 'f',
+ 'placeholder' => $lang['btn_search'],
+ 'autocomplete' => $autocomplete ? 'on' : 'off',
+ ])
+ ->id('qsearch__in')
+ ->val($ACT === 'search' ? $QUERY : '')
+ ->useInput(false)
+ ;
+ $searchForm->addButton('', $lang['btn_search'])->attrs([
+ 'type' => 'submit',
+ 'title' => $lang['btn_search'],
+ ]);
+ if ($ajax) {
+ $searchForm->addTagOpen('div')->id('qsearch__out')->addClass('ajax_qsearch JSpopup');
+ $searchForm->addTagClose('div');
+ }
+ $searchForm->addTagClose('div');
+ Event::createAndTrigger('FORM_QUICKSEARCH_OUTPUT', $searchForm);
+
+ echo $searchForm->toHTML();
+
+ return true;
+}
+
+/**
+ * Print the breadcrumbs trace
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $sep Separator between entries
+ * @param bool $return return or print
+ * @return bool|string
+ */
+function tpl_breadcrumbs($sep = null, $return = false) {
+ global $lang;
+ global $conf;
+
+ //check if enabled
+ if(!$conf['breadcrumbs']) return false;
+
+ //set default
+ if(is_null($sep)) $sep = '•';
+
+ $out='';
+
+ $crumbs = breadcrumbs(); //setup crumb trace
+
+ $crumbs_sep = ' <span class="bcsep">'.$sep.'</span> ';
+
+ //render crumbs, highlight the last one
+ $out .= '<span class="bchead">'.$lang['breadcrumb'].'</span>';
+ $last = count($crumbs);
+ $i = 0;
+ foreach($crumbs as $id => $name) {
+ $i++;
+ $out .= $crumbs_sep;
+ if($i == $last) $out .= '<span class="curid">';
+ $out .= '<bdi>' . tpl_link(wl($id), hsc($name), 'class="breadcrumbs" title="'.$id.'"', true) . '</bdi>';
+ if($i == $last) $out .= '</span>';
+ }
+ if($return) return $out;
+ print $out;
+ return $out ? true : false;
+}
+
+/**
+ * Hierarchical breadcrumbs
+ *
+ * This code was suggested as replacement for the usual breadcrumbs.
+ * It only makes sense with a deep site structure.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Nigel McNie <oracle.shinoda@gmail.com>
+ * @author Sean Coates <sean@caedmon.net>
+ * @author <fredrik@averpil.com>
+ * @todo May behave strangely in RTL languages
+ *
+ * @param string $sep Separator between entries
+ * @param bool $return return or print
+ * @return bool|string
+ */
+function tpl_youarehere($sep = null, $return = false) {
+ global $conf;
+ global $ID;
+ global $lang;
+
+ // check if enabled
+ if(!$conf['youarehere']) return false;
+
+ //set default
+ if(is_null($sep)) $sep = ' » ';
+
+ $out = '';
+
+ $parts = explode(':', $ID);
+ $count = count($parts);
+
+ $out .= '<span class="bchead">'.$lang['youarehere'].' </span>';
+
+ // always print the startpage
+ $out .= '<span class="home">' . tpl_pagelink(':'.$conf['start'], null, true) . '</span>';
+
+ // print intermediate namespace links
+ $part = '';
+ for($i = 0; $i < $count - 1; $i++) {
+ $part .= $parts[$i].':';
+ $page = $part;
+ if($page == $conf['start']) continue; // Skip startpage
+
+ // output
+ $out .= $sep . tpl_pagelink($page, null, true);
+ }
+
+ // print current page, skipping start page, skipping for namespace index
+ resolve_pageid('', $page, $exists);
+ if (isset($page) && $page == $part.$parts[$i]) {
+ if($return) return $out;
+ print $out;
+ return true;
+ }
+ $page = $part.$parts[$i];
+ if($page == $conf['start']) {
+ if($return) return $out;
+ print $out;
+ return true;
+ }
+ $out .= $sep;
+ $out .= tpl_pagelink($page, null, true);
+ if($return) return $out;
+ print $out;
+ return $out ? true : false;
+}
+
+/**
+ * Print info if the user is logged in
+ * and show full name in that case
+ *
+ * Could be enhanced with a profile link in future?
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return bool
+ */
+function tpl_userinfo() {
+ global $lang;
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ if($INPUT->server->str('REMOTE_USER')) {
+ print $lang['loggedinas'].' '.userlink();
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Print some info about the current page
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param bool $ret return content instead of printing it
+ * @return bool|string
+ */
+function tpl_pageinfo($ret = false) {
+ global $conf;
+ global $lang;
+ global $INFO;
+ global $ID;
+
+ // return if we are not allowed to view the page
+ if(!auth_quickaclcheck($ID)) {
+ return false;
+ }
+
+ // prepare date and path
+ $fn = $INFO['filepath'];
+ if(!$conf['fullpath']) {
+ if($INFO['rev']) {
+ $fn = str_replace($conf['olddir'].'/', '', $fn);
+ } else {
+ $fn = str_replace($conf['datadir'].'/', '', $fn);
+ }
+ }
+ $fn = utf8_decodeFN($fn);
+ $date = dformat($INFO['lastmod']);
+
+ // print it
+ if($INFO['exists']) {
+ $out = '';
+ $out .= '<bdi>'.$fn.'</bdi>';
+ $out .= ' · ';
+ $out .= $lang['lastmod'];
+ $out .= ' ';
+ $out .= $date;
+ if($INFO['editor']) {
+ $out .= ' '.$lang['by'].' ';
+ $out .= '<bdi>'.editorinfo($INFO['editor']).'</bdi>';
+ } else {
+ $out .= ' ('.$lang['external_edit'].')';
+ }
+ if($INFO['locked']) {
+ $out .= ' · ';
+ $out .= $lang['lockedby'];
+ $out .= ' ';
+ $out .= '<bdi>'.editorinfo($INFO['locked']).'</bdi>';
+ }
+ if($ret) {
+ return $out;
+ } else {
+ echo $out;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Prints or returns the name of the given page (current one if none given).
+ *
+ * If useheading is enabled this will use the first headline else
+ * the given ID is used.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $id page id
+ * @param bool $ret return content instead of printing
+ * @return bool|string
+ */
+function tpl_pagetitle($id = null, $ret = false) {
+ global $ACT, $INPUT, $conf, $lang;
+
+ if(is_null($id)) {
+ global $ID;
+ $id = $ID;
+ }
+
+ $name = $id;
+ if(useHeading('navigation')) {
+ $first_heading = p_get_first_heading($id);
+ if($first_heading) $name = $first_heading;
+ }
+
+ // default page title is the page name, modify with the current action
+ switch ($ACT) {
+ // admin functions
+ case 'admin' :
+ $page_title = $lang['btn_admin'];
+ // try to get the plugin name
+ /** @var $plugin AdminPlugin */
+ if ($plugin = plugin_getRequestAdminPlugin()){
+ $plugin_title = $plugin->getMenuText($conf['lang']);
+ $page_title = $plugin_title ? $plugin_title : $plugin->getPluginName();
+ }
+ break;
+
+ // user functions
+ case 'login' :
+ case 'profile' :
+ case 'register' :
+ case 'resendpwd' :
+ $page_title = $lang['btn_'.$ACT];
+ break;
+
+ // wiki functions
+ case 'search' :
+ case 'index' :
+ $page_title = $lang['btn_'.$ACT];
+ break;
+
+ // page functions
+ case 'edit' :
+ case 'preview' :
+ $page_title = "✎ ".$name;
+ break;
+
+ case 'revisions' :
+ $page_title = $name . ' - ' . $lang['btn_revs'];
+ break;
+
+ case 'backlink' :
+ case 'recent' :
+ case 'subscribe' :
+ $page_title = $name . ' - ' . $lang['btn_'.$ACT];
+ break;
+
+ default : // SHOW and anything else not included
+ $page_title = $name;
+ }
+
+ if($ret) {
+ return hsc($page_title);
+ } else {
+ print hsc($page_title);
+ return true;
+ }
+}
+
+/**
+ * Returns the requested EXIF/IPTC tag from the current image
+ *
+ * If $tags is an array all given tags are tried until a
+ * value is found. If no value is found $alt is returned.
+ *
+ * Which texts are known is defined in the functions _exifTagNames
+ * and _iptcTagNames() in inc/jpeg.php (You need to prepend IPTC
+ * to the names of the latter one)
+ *
+ * Only allowed in: detail.php
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array|string $tags tag or array of tags to try
+ * @param string $alt alternative output if no data was found
+ * @param null|string $src the image src, uses global $SRC if not given
+ * @return string
+ */
+function tpl_img_getTag($tags, $alt = '', $src = null) {
+ // Init Exif Reader
+ global $SRC;
+
+ if(is_null($src)) $src = $SRC;
+
+ static $meta = null;
+ if(is_null($meta)) $meta = new JpegMeta($src);
+ if($meta === false) return $alt;
+ $info = cleanText($meta->getField($tags));
+ if($info == false) return $alt;
+ return $info;
+}
+
+/**
+ * Returns a description list of the metatags of the current image
+ *
+ * @return string html of description list
+ */
+function tpl_img_meta() {
+ global $lang;
+
+ $tags = tpl_get_img_meta();
+
+ echo '<dl>';
+ foreach($tags as $tag) {
+ $label = $lang[$tag['langkey']];
+ if(!$label) $label = $tag['langkey'] . ':';
+
+ echo '<dt>'.$label.'</dt><dd>';
+ if ($tag['type'] == 'date') {
+ echo dformat($tag['value']);
+ } else {
+ echo hsc($tag['value']);
+ }
+ echo '</dd>';
+ }
+ echo '</dl>';
+}
+
+/**
+ * Returns metadata as configured in mediameta config file, ready for creating html
+ *
+ * @return array with arrays containing the entries:
+ * - string langkey key to lookup in the $lang var, if not found printed as is
+ * - string type type of value
+ * - string value tag value (unescaped)
+ */
+function tpl_get_img_meta() {
+
+ $config_files = getConfigFiles('mediameta');
+ foreach ($config_files as $config_file) {
+ if(file_exists($config_file)) {
+ include($config_file);
+ }
+ }
+ /** @var array $fields the included array with metadata */
+
+ $tags = array();
+ foreach($fields as $tag){
+ $t = array();
+ if (!empty($tag[0])) {
+ $t = array($tag[0]);
+ }
+ if(is_array($tag[3])) {
+ $t = array_merge($t,$tag[3]);
+ }
+ $value = tpl_img_getTag($t);
+ if ($value) {
+ $tags[] = array('langkey' => $tag[1], 'type' => $tag[2], 'value' => $value);
+ }
+ }
+ return $tags;
+}
+
+/**
+ * Prints the image with a link to the full sized version
+ *
+ * Only allowed in: detail.php
+ *
+ * @triggers TPL_IMG_DISPLAY
+ * @param $maxwidth int - maximal width of the image
+ * @param $maxheight int - maximal height of the image
+ * @param $link bool - link to the orginal size?
+ * @param $params array - additional image attributes
+ * @return bool Result of TPL_IMG_DISPLAY
+ */
+function tpl_img($maxwidth = 0, $maxheight = 0, $link = true, $params = null) {
+ global $IMG;
+ /** @var Input $INPUT */
+ global $INPUT;
+ global $REV;
+ $w = (int) tpl_img_getTag('File.Width');
+ $h = (int) tpl_img_getTag('File.Height');
+
+ //resize to given max values
+ $ratio = 1;
+ if($w >= $h) {
+ if($maxwidth && $w >= $maxwidth) {
+ $ratio = $maxwidth / $w;
+ } elseif($maxheight && $h > $maxheight) {
+ $ratio = $maxheight / $h;
+ }
+ } else {
+ if($maxheight && $h >= $maxheight) {
+ $ratio = $maxheight / $h;
+ } elseif($maxwidth && $w > $maxwidth) {
+ $ratio = $maxwidth / $w;
+ }
+ }
+ if($ratio) {
+ $w = floor($ratio * $w);
+ $h = floor($ratio * $h);
+ }
+
+ //prepare URLs
+ $url = ml($IMG, array('cache'=> $INPUT->str('cache'),'rev'=>$REV), true, '&');
+ $src = ml($IMG, array('cache'=> $INPUT->str('cache'),'rev'=>$REV, 'w'=> $w, 'h'=> $h), true, '&');
+
+ //prepare attributes
+ $alt = tpl_img_getTag('Simple.Title');
+ if(is_null($params)) {
+ $p = array();
+ } else {
+ $p = $params;
+ }
+ if($w) $p['width'] = $w;
+ if($h) $p['height'] = $h;
+ $p['class'] = 'img_detail';
+ if($alt) {
+ $p['alt'] = $alt;
+ $p['title'] = $alt;
+ } else {
+ $p['alt'] = '';
+ }
+ $p['src'] = $src;
+
+ $data = array('url'=> ($link ? $url : null), 'params'=> $p);
+ return Event::createAndTrigger('TPL_IMG_DISPLAY', $data, '_tpl_img_action', true);
+}
+
+/**
+ * Default action for TPL_IMG_DISPLAY
+ *
+ * @param array $data
+ * @return bool
+ */
+function _tpl_img_action($data) {
+ global $lang;
+ $p = buildAttributes($data['params']);
+
+ if($data['url']) print '<a href="'.hsc($data['url']).'" title="'.$lang['mediaview'].'">';
+ print '<img '.$p.'/>';
+ if($data['url']) print '</a>';
+ return true;
+}
+
+/**
+ * This function inserts a small gif which in reality is the indexer function.
+ *
+ * Should be called somewhere at the very end of the main.php
+ * template
+ *
+ * @return bool
+ */
+function tpl_indexerWebBug() {
+ global $ID;
+
+ $p = array();
+ $p['src'] = DOKU_BASE.'lib/exe/taskrunner.php?id='.rawurlencode($ID).
+ '&'.time();
+ $p['width'] = 2; //no more 1x1 px image because we live in times of ad blockers...
+ $p['height'] = 1;
+ $p['alt'] = '';
+ $att = buildAttributes($p);
+ print "<img $att />";
+ return true;
+}
+
+/**
+ * tpl_getConf($id)
+ *
+ * use this function to access template configuration variables
+ *
+ * @param string $id name of the value to access
+ * @param mixed $notset what to return if the setting is not available
+ * @return mixed
+ */
+function tpl_getConf($id, $notset=false) {
+ global $conf;
+ static $tpl_configloaded = false;
+
+ $tpl = $conf['template'];
+
+ if(!$tpl_configloaded) {
+ $tconf = tpl_loadConfig();
+ if($tconf !== false) {
+ foreach($tconf as $key => $value) {
+ if(isset($conf['tpl'][$tpl][$key])) continue;
+ $conf['tpl'][$tpl][$key] = $value;
+ }
+ $tpl_configloaded = true;
+ }
+ }
+
+ if(isset($conf['tpl'][$tpl][$id])){
+ return $conf['tpl'][$tpl][$id];
+ }
+
+ return $notset;
+}
+
+/**
+ * tpl_loadConfig()
+ *
+ * reads all template configuration variables
+ * this function is automatically called by tpl_getConf()
+ *
+ * @return array
+ */
+function tpl_loadConfig() {
+
+ $file = tpl_incdir().'/conf/default.php';
+ $conf = array();
+
+ if(!file_exists($file)) return false;
+
+ // load default config file
+ include($file);
+
+ return $conf;
+}
+
+// language methods
+/**
+ * tpl_getLang($id)
+ *
+ * use this function to access template language variables
+ *
+ * @param string $id key of language string
+ * @return string
+ */
+function tpl_getLang($id) {
+ static $lang = array();
+
+ if(count($lang) === 0) {
+ global $conf, $config_cascade; // definitely don't invoke "global $lang"
+
+ $path = tpl_incdir() . 'lang/';
+
+ $lang = array();
+
+ // don't include once
+ @include($path . 'en/lang.php');
+ foreach($config_cascade['lang']['template'] as $config_file) {
+ if(file_exists($config_file . $conf['template'] . '/en/lang.php')) {
+ include($config_file . $conf['template'] . '/en/lang.php');
+ }
+ }
+
+ if($conf['lang'] != 'en') {
+ @include($path . $conf['lang'] . '/lang.php');
+ foreach($config_cascade['lang']['template'] as $config_file) {
+ if(file_exists($config_file . $conf['template'] . '/' . $conf['lang'] . '/lang.php')) {
+ include($config_file . $conf['template'] . '/' . $conf['lang'] . '/lang.php');
+ }
+ }
+ }
+ }
+ return $lang[$id];
+}
+
+/**
+ * Retrieve a language dependent file and pass to xhtml renderer for display
+ * template equivalent of p_locale_xhtml()
+ *
+ * @param string $id id of language dependent wiki page
+ * @return string parsed contents of the wiki page in xhtml format
+ */
+function tpl_locale_xhtml($id) {
+ return p_cached_output(tpl_localeFN($id));
+}
+
+/**
+ * Prepends appropriate path for a language dependent filename
+ *
+ * @param string $id id of localized text
+ * @return string wiki text
+ */
+function tpl_localeFN($id) {
+ $path = tpl_incdir().'lang/';
+ global $conf;
+ $file = DOKU_CONF.'template_lang/'.$conf['template'].'/'.$conf['lang'].'/'.$id.'.txt';
+ if (!file_exists($file)){
+ $file = $path.$conf['lang'].'/'.$id.'.txt';
+ if(!file_exists($file)){
+ //fall back to english
+ $file = $path.'en/'.$id.'.txt';
+ }
+ }
+ return $file;
+}
+
+/**
+ * prints the "main content" in the mediamanager popup
+ *
+ * Depending on the user's actions this may be a list of
+ * files in a namespace, the meta editing dialog or
+ * a message of referencing pages
+ *
+ * Only allowed in mediamanager.php
+ *
+ * @triggers MEDIAMANAGER_CONTENT_OUTPUT
+ * @param bool $fromajax - set true when calling this function via ajax
+ * @param string $sort
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_mediaContent($fromajax = false, $sort='natural') {
+ global $IMG;
+ global $AUTH;
+ global $INUSE;
+ global $NS;
+ global $JUMPTO;
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ $do = $INPUT->extract('do')->str('do');
+ if(in_array($do, array('save', 'cancel'))) $do = '';
+
+ if(!$do) {
+ if($INPUT->bool('edit')) {
+ $do = 'metaform';
+ } elseif(is_array($INUSE)) {
+ $do = 'filesinuse';
+ } else {
+ $do = 'filelist';
+ }
+ }
+
+ // output the content pane, wrapped in an event.
+ if(!$fromajax) ptln('<div id="media__content">');
+ $data = array('do' => $do);
+ $evt = new Event('MEDIAMANAGER_CONTENT_OUTPUT', $data);
+ if($evt->advise_before()) {
+ $do = $data['do'];
+ if($do == 'filesinuse') {
+ media_filesinuse($INUSE, $IMG);
+ } elseif($do == 'filelist') {
+ media_filelist($NS, $AUTH, $JUMPTO,false,$sort);
+ } elseif($do == 'searchlist') {
+ media_searchlist($INPUT->str('q'), $NS, $AUTH);
+ } else {
+ msg('Unknown action '.hsc($do), -1);
+ }
+ }
+ $evt->advise_after();
+ unset($evt);
+ if(!$fromajax) ptln('</div>');
+
+}
+
+/**
+ * Prints the central column in full-screen media manager
+ * Depending on the opened tab this may be a list of
+ * files in a namespace, upload form or search form
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function tpl_mediaFileList() {
+ global $AUTH;
+ global $NS;
+ global $JUMPTO;
+ global $lang;
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ $opened_tab = $INPUT->str('tab_files');
+ if(!$opened_tab || !in_array($opened_tab, array('files', 'upload', 'search'))) $opened_tab = 'files';
+ if($INPUT->str('mediado') == 'update') $opened_tab = 'upload';
+
+ echo '<h2 class="a11y">'.$lang['mediaselect'].'</h2>'.NL;
+
+ media_tabs_files($opened_tab);
+
+ echo '<div class="panelHeader">'.NL;
+ echo '<h3>';
+ $tabTitle = ($NS) ? $NS : '['.$lang['mediaroot'].']';
+ printf($lang['media_'.$opened_tab], '<strong>'.hsc($tabTitle).'</strong>');
+ echo '</h3>'.NL;
+ if($opened_tab === 'search' || $opened_tab === 'files') {
+ media_tab_files_options();
+ }
+ echo '</div>'.NL;
+
+ echo '<div class="panelContent">'.NL;
+ if($opened_tab == 'files') {
+ media_tab_files($NS, $AUTH, $JUMPTO);
+ } elseif($opened_tab == 'upload') {
+ media_tab_upload($NS, $AUTH, $JUMPTO);
+ } elseif($opened_tab == 'search') {
+ media_tab_search($NS, $AUTH);
+ }
+ echo '</div>'.NL;
+}
+
+/**
+ * Prints the third column in full-screen media manager
+ * Depending on the opened tab this may be details of the
+ * selected file, the meta editing dialog or
+ * list of file revisions
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ *
+ * @param string $image
+ * @param boolean $rev
+ */
+function tpl_mediaFileDetails($image, $rev) {
+ global $conf, $DEL, $lang;
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ $removed = (
+ !file_exists(mediaFN($image)) &&
+ file_exists(mediaMetaFN($image, '.changes')) &&
+ $conf['mediarevisions']
+ );
+ if(!$image || (!file_exists(mediaFN($image)) && !$removed) || $DEL) return;
+ if($rev && !file_exists(mediaFN($image, $rev))) $rev = false;
+ $ns = getNS($image);
+ $do = $INPUT->str('mediado');
+
+ $opened_tab = $INPUT->str('tab_details');
+
+ $tab_array = array('view');
+ list(, $mime) = mimetype($image);
+ if($mime == 'image/jpeg') {
+ $tab_array[] = 'edit';
+ }
+ if($conf['mediarevisions']) {
+ $tab_array[] = 'history';
+ }
+
+ if(!$opened_tab || !in_array($opened_tab, $tab_array)) $opened_tab = 'view';
+ if($INPUT->bool('edit')) $opened_tab = 'edit';
+ if($do == 'restore') $opened_tab = 'view';
+
+ media_tabs_details($image, $opened_tab);
+
+ echo '<div class="panelHeader"><h3>';
+ list($ext) = mimetype($image, false);
+ $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $ext);
+ $class = 'select mediafile mf_'.$class;
+ $attributes = $rev ? ['rev' => $rev] : [];
+ $tabTitle = '<strong><a href="'.ml($image, $attributes).'" class="'.$class.'" title="'.$lang['mediaview'].'">'.
+ $image.'</a>'.'</strong>';
+ if($opened_tab === 'view' && $rev) {
+ printf($lang['media_viewold'], $tabTitle, dformat($rev));
+ } else {
+ printf($lang['media_'.$opened_tab], $tabTitle);
+ }
+
+ echo '</h3></div>'.NL;
+
+ echo '<div class="panelContent">'.NL;
+
+ if($opened_tab == 'view') {
+ media_tab_view($image, $ns, null, $rev);
+
+ } elseif($opened_tab == 'edit' && !$removed) {
+ media_tab_edit($image, $ns);
+
+ } elseif($opened_tab == 'history' && $conf['mediarevisions']) {
+ media_tab_history($image, $ns);
+ }
+
+ echo '</div>'.NL;
+}
+
+/**
+ * prints the namespace tree in the mediamanager popup
+ *
+ * Only allowed in mediamanager.php
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_mediaTree() {
+ global $NS;
+ ptln('<div id="media__tree">');
+ media_nstree($NS);
+ ptln('</div>');
+}
+
+/**
+ * Print a dropdown menu with all DokuWiki actions
+ *
+ * Note: this will not use any pretty URLs
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $empty empty option label
+ * @param string $button submit button label
+ * @deprecated 2017-09-01 see devel:menus
+ */
+function tpl_actiondropdown($empty = '', $button = '&gt;') {
+ dbg_deprecated('see devel:menus');
+ $menu = new \dokuwiki\Menu\MobileMenu();
+ echo $menu->getDropdown($empty, $button);
+}
+
+/**
+ * Print a informational line about the used license
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $img print image? (|button|badge)
+ * @param bool $imgonly skip the textual description?
+ * @param bool $return when true don't print, but return HTML
+ * @param bool $wrap wrap in div with class="license"?
+ * @return string
+ */
+function tpl_license($img = 'badge', $imgonly = false, $return = false, $wrap = true) {
+ global $license;
+ global $conf;
+ global $lang;
+ if(!$conf['license']) return '';
+ if(!is_array($license[$conf['license']])) return '';
+ $lic = $license[$conf['license']];
+ $target = ($conf['target']['extern']) ? ' target="'.$conf['target']['extern'].'"' : '';
+
+ $out = '';
+ if($wrap) $out .= '<div class="license">';
+ if($img) {
+ $src = license_img($img);
+ if($src) {
+ $out .= '<a href="'.$lic['url'].'" rel="license"'.$target;
+ $out .= '><img src="'.DOKU_BASE.$src.'" alt="'.$lic['name'].'" /></a>';
+ if(!$imgonly) $out .= ' ';
+ }
+ }
+ if(!$imgonly) {
+ $out .= $lang['license'].' ';
+ $out .= '<bdi><a href="'.$lic['url'].'" rel="license" class="urlextern"'.$target;
+ $out .= '>'.$lic['name'].'</a></bdi>';
+ }
+ if($wrap) $out .= '</div>';
+
+ if($return) return $out;
+ echo $out;
+ return '';
+}
+
+/**
+ * Includes the rendered HTML of a given page
+ *
+ * This function is useful to populate sidebars or similar features in a
+ * template
+ *
+ * @param string $pageid The page name you want to include
+ * @param bool $print Should the content be printed or returned only
+ * @param bool $propagate Search higher namespaces, too?
+ * @param bool $useacl Include the page only if the ACLs check out?
+ * @return bool|null|string
+ */
+function tpl_include_page($pageid, $print = true, $propagate = false, $useacl = true) {
+ if($propagate) {
+ $pageid = page_findnearest($pageid, $useacl);
+ } elseif($useacl && auth_quickaclcheck($pageid) == AUTH_NONE) {
+ return false;
+ }
+ if(!$pageid) return false;
+
+ global $TOC;
+ $oldtoc = $TOC;
+ $html = p_wiki_xhtml($pageid, '', false);
+ $TOC = $oldtoc;
+
+ if($print) echo $html;
+ return $html;
+}
+
+/**
+ * Display the subscribe form
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+function tpl_subscribe() {
+ global $INFO;
+ global $ID;
+ global $lang;
+ global $conf;
+ $stime_days = $conf['subscribe_time'] / 60 / 60 / 24;
+
+ echo p_locale_xhtml('subscr_form');
+ echo '<h2>'.$lang['subscr_m_current_header'].'</h2>';
+ echo '<div class="level2">';
+ if($INFO['subscribed'] === false) {
+ echo '<p>'.$lang['subscr_m_not_subscribed'].'</p>';
+ } else {
+ echo '<ul>';
+ foreach($INFO['subscribed'] as $sub) {
+ echo '<li><div class="li">';
+ if($sub['target'] !== $ID) {
+ echo '<code class="ns">'.hsc(prettyprint_id($sub['target'])).'</code>';
+ } else {
+ echo '<code class="page">'.hsc(prettyprint_id($sub['target'])).'</code>';
+ }
+ $sstl = sprintf($lang['subscr_style_'.$sub['style']], $stime_days);
+ if(!$sstl) $sstl = hsc($sub['style']);
+ echo ' ('.$sstl.') ';
+
+ echo '<a href="'.wl(
+ $ID,
+ array(
+ 'do' => 'subscribe',
+ 'sub_target'=> $sub['target'],
+ 'sub_style' => $sub['style'],
+ 'sub_action'=> 'unsubscribe',
+ 'sectok' => getSecurityToken()
+ )
+ ).
+ '" class="unsubscribe">'.$lang['subscr_m_unsubscribe'].
+ '</a></div></li>';
+ }
+ echo '</ul>';
+ }
+ echo '</div>';
+
+ // Add new subscription form
+ echo '<h2>'.$lang['subscr_m_new_header'].'</h2>';
+ echo '<div class="level2">';
+ $ns = getNS($ID).':';
+ $targets = array(
+ $ID => '<code class="page">'.prettyprint_id($ID).'</code>',
+ $ns => '<code class="ns">'.prettyprint_id($ns).'</code>',
+ );
+ $styles = array(
+ 'every' => $lang['subscr_style_every'],
+ 'digest' => sprintf($lang['subscr_style_digest'], $stime_days),
+ 'list' => sprintf($lang['subscr_style_list'], $stime_days),
+ );
+
+ $form = new Doku_Form(array('id' => 'subscribe__form'));
+ $form->startFieldset($lang['subscr_m_subscribe']);
+ $form->addRadioSet('sub_target', $targets);
+ $form->startFieldset($lang['subscr_m_receive']);
+ $form->addRadioSet('sub_style', $styles);
+ $form->addHidden('sub_action', 'subscribe');
+ $form->addHidden('do', 'subscribe');
+ $form->addHidden('id', $ID);
+ $form->endFieldset();
+ $form->addElement(form_makeButton('submit', 'subscribe', $lang['subscr_m_subscribe']));
+ html_form('SUBSCRIBE', $form);
+ echo '</div>';
+}
+
+/**
+ * Tries to send already created content right to the browser
+ *
+ * Wraps around ob_flush() and flush()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_flush() {
+ if( ob_get_level() > 0 ) ob_flush();
+ flush();
+}
+
+/**
+ * Tries to find a ressource file in the given locations.
+ *
+ * If a given location starts with a colon it is assumed to be a media
+ * file, otherwise it is assumed to be relative to the current template
+ *
+ * @param string[] $search locations to look at
+ * @param bool $abs if to use absolute URL
+ * @param array &$imginfo filled with getimagesize()
+ * @param bool $fallback use fallback image if target isn't found or return 'false' if potential
+ * false result is required
+ * @return string
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tpl_getMediaFile($search, $abs = false, &$imginfo = null, $fallback = true) {
+ $img = '';
+ $file = '';
+ $ismedia = false;
+ // loop through candidates until a match was found:
+ foreach($search as $img) {
+ if(substr($img, 0, 1) == ':') {
+ $file = mediaFN($img);
+ $ismedia = true;
+ } else {
+ $file = tpl_incdir().$img;
+ $ismedia = false;
+ }
+
+ if(file_exists($file)) break;
+ }
+
+ // manage non existing target
+ if (!file_exists($file)) {
+ // give result for fallback image
+ if ($fallback === true) {
+ $file = DOKU_INC . 'lib/images/blank.gif';
+ // stop process if false result is required (if $fallback is false)
+ } else {
+ return false;
+ }
+ }
+
+ // fetch image data if requested
+ if(!is_null($imginfo)) {
+ $imginfo = getimagesize($file);
+ }
+
+ // build URL
+ if($ismedia) {
+ $url = ml($img, '', true, '', $abs);
+ } else {
+ $url = tpl_basedir().$img;
+ if($abs) $url = DOKU_URL.substr($url, strlen(DOKU_REL));
+ }
+
+ return $url;
+}
+
+/**
+ * PHP include a file
+ *
+ * either from the conf directory if it exists, otherwise use
+ * file in the template's root directory.
+ *
+ * The function honours config cascade settings and looks for the given
+ * file next to the ´main´ config files, in the order protected, local,
+ * default.
+ *
+ * Note: no escaping or sanity checking is done here. Never pass user input
+ * to this function!
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file
+ */
+function tpl_includeFile($file) {
+ global $config_cascade;
+ foreach(array('protected', 'local', 'default') as $config_group) {
+ if(empty($config_cascade['main'][$config_group])) continue;
+ foreach($config_cascade['main'][$config_group] as $conf_file) {
+ $dir = dirname($conf_file);
+ if(file_exists("$dir/$file")) {
+ include("$dir/$file");
+ return;
+ }
+ }
+ }
+
+ // still here? try the template dir
+ $file = tpl_incdir().$file;
+ if(file_exists($file)) {
+ include($file);
+ }
+}
+
+/**
+ * Returns <link> tag for various icon types (favicon|mobile|generic)
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ *
+ * @param array $types - list of icon types to display (favicon|mobile|generic)
+ * @return string
+ */
+function tpl_favicon($types = array('favicon')) {
+
+ $return = '';
+
+ foreach($types as $type) {
+ switch($type) {
+ case 'favicon':
+ $look = array(':wiki:favicon.ico', ':favicon.ico', 'images/favicon.ico');
+ $return .= '<link rel="shortcut icon" href="'.tpl_getMediaFile($look).'" />'.NL;
+ break;
+ case 'mobile':
+ $look = array(':wiki:apple-touch-icon.png', ':apple-touch-icon.png', 'images/apple-touch-icon.png');
+ $return .= '<link rel="apple-touch-icon" href="'.tpl_getMediaFile($look).'" />'.NL;
+ break;
+ case 'generic':
+ // ideal world solution, which doesn't work in any browser yet
+ $look = array(':wiki:favicon.svg', ':favicon.svg', 'images/favicon.svg');
+ $return .= '<link rel="icon" href="'.tpl_getMediaFile($look).'" type="image/svg+xml" />'.NL;
+ break;
+ }
+ }
+
+ return $return;
+}
+
+/**
+ * Prints full-screen media manager
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+function tpl_media() {
+ global $NS, $IMG, $JUMPTO, $REV, $lang, $fullscreen, $INPUT;
+ $fullscreen = true;
+ require_once DOKU_INC.'lib/exe/mediamanager.php';
+
+ $rev = '';
+ $image = cleanID($INPUT->str('image'));
+ if(isset($IMG)) $image = $IMG;
+ if(isset($JUMPTO)) $image = $JUMPTO;
+ if(isset($REV) && !$JUMPTO) $rev = $REV;
+
+ echo '<div id="mediamanager__page">'.NL;
+ echo '<h1>'.$lang['btn_media'].'</h1>'.NL;
+ html_msgarea();
+
+ echo '<div class="panel namespaces">'.NL;
+ echo '<h2>'.$lang['namespaces'].'</h2>'.NL;
+ echo '<div class="panelHeader">';
+ echo $lang['media_namespaces'];
+ echo '</div>'.NL;
+
+ echo '<div class="panelContent" id="media__tree">'.NL;
+ media_nstree($NS);
+ echo '</div>'.NL;
+ echo '</div>'.NL;
+
+ echo '<div class="panel filelist">'.NL;
+ tpl_mediaFileList();
+ echo '</div>'.NL;
+
+ echo '<div class="panel file">'.NL;
+ echo '<h2 class="a11y">'.$lang['media_file'].'</h2>'.NL;
+ tpl_mediaFileDetails($image, $rev);
+ echo '</div>'.NL;
+
+ echo '</div>'.NL;
+}
+
+/**
+ * Return useful layout classes
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ *
+ * @return string
+ */
+function tpl_classes() {
+ global $ACT, $conf, $ID, $INFO;
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ $classes = array(
+ 'dokuwiki',
+ 'mode_'.$ACT,
+ 'tpl_'.$conf['template'],
+ $INPUT->server->bool('REMOTE_USER') ? 'loggedIn' : '',
+ (isset($INFO) && $INFO['exists']) ? '' : 'notFound',
+ ($ID == $conf['start']) ? 'home' : '',
+ );
+ return join(' ', $classes);
+}
+
+/**
+ * Create event for tools menues
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ * @param string $toolsname name of menu
+ * @param array $items
+ * @param string $view e.g. 'main', 'detail', ...
+ * @deprecated 2017-09-01 see devel:menus
+ */
+function tpl_toolsevent($toolsname, $items, $view = 'main') {
+ dbg_deprecated('see devel:menus');
+ $data = array(
+ 'view' => $view,
+ 'items' => $items
+ );
+
+ $hook = 'TEMPLATE_' . strtoupper($toolsname) . '_DISPLAY';
+ $evt = new Event($hook, $data);
+ if($evt->advise_before()) {
+ foreach($evt->data['items'] as $k => $html) echo $html;
+ }
+ $evt->advise_after();
+}
+
+//Setup VIM: ex: et ts=4 :
+
diff --git a/platform/www/inc/toolbar.php b/platform/www/inc/toolbar.php
new file mode 100644
index 0000000..7151202
--- /dev/null
+++ b/platform/www/inc/toolbar.php
@@ -0,0 +1,277 @@
+<?php
+/**
+ * Editing toolbar functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */use dokuwiki\Extension\Event;
+
+/**
+ * Prepares and prints an JavaScript array with all toolbar buttons
+ *
+ * @emits TOOLBAR_DEFINE
+ * @param string $varname Name of the JS variable to fill
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function toolbar_JSdefines($varname){
+ global $lang;
+
+ $menu = array();
+
+ $evt = new Event('TOOLBAR_DEFINE', $menu);
+ if ($evt->advise_before()){
+
+ // build button array
+ $menu = array_merge($menu, array(
+ array(
+ 'type' => 'format',
+ 'title' => $lang['qb_bold'],
+ 'icon' => 'bold.png',
+ 'key' => 'b',
+ 'open' => '**',
+ 'close' => '**',
+ 'block' => false
+ ),
+ array(
+ 'type' => 'format',
+ 'title' => $lang['qb_italic'],
+ 'icon' => 'italic.png',
+ 'key' => 'i',
+ 'open' => '//',
+ 'close' => '//',
+ 'block' => false
+ ),
+ array(
+ 'type' => 'format',
+ 'title' => $lang['qb_underl'],
+ 'icon' => 'underline.png',
+ 'key' => 'u',
+ 'open' => '__',
+ 'close' => '__',
+ 'block' => false
+ ),
+ array(
+ 'type' => 'format',
+ 'title' => $lang['qb_code'],
+ 'icon' => 'mono.png',
+ 'key' => 'm',
+ 'open' => "''",
+ 'close' => "''",
+ 'block' => false
+ ),
+ array(
+ 'type' => 'format',
+ 'title' => $lang['qb_strike'],
+ 'icon' => 'strike.png',
+ 'key' => 'd',
+ 'open' => '<del>',
+ 'close' => '</del>',
+ 'block' => false
+ ),
+
+ array(
+ 'type' => 'autohead',
+ 'title' => $lang['qb_hequal'],
+ 'icon' => 'hequal.png',
+ 'key' => '8',
+ 'text' => $lang['qb_h'],
+ 'mod' => 0,
+ 'block' => true
+ ),
+ array(
+ 'type' => 'autohead',
+ 'title' => $lang['qb_hminus'],
+ 'icon' => 'hminus.png',
+ 'key' => '9',
+ 'text' => $lang['qb_h'],
+ 'mod' => 1,
+ 'block' => true
+ ),
+ array(
+ 'type' => 'autohead',
+ 'title' => $lang['qb_hplus'],
+ 'icon' => 'hplus.png',
+ 'key' => '0',
+ 'text' => $lang['qb_h'],
+ 'mod' => -1,
+ 'block' => true
+ ),
+
+ array(
+ 'type' => 'picker',
+ 'title' => $lang['qb_hs'],
+ 'icon' => 'h.png',
+ 'class' => 'pk_hl',
+ 'list' => array(
+ array(
+ 'type' => 'format',
+ 'title' => $lang['qb_h1'],
+ 'icon' => 'h1.png',
+ 'key' => '1',
+ 'open' => '====== ',
+ 'close' => ' ======\n',
+ ),
+ array(
+ 'type' => 'format',
+ 'title' => $lang['qb_h2'],
+ 'icon' => 'h2.png',
+ 'key' => '2',
+ 'open' => '===== ',
+ 'close' => ' =====\n',
+ ),
+ array(
+ 'type' => 'format',
+ 'title' => $lang['qb_h3'],
+ 'icon' => 'h3.png',
+ 'key' => '3',
+ 'open' => '==== ',
+ 'close' => ' ====\n',
+ ),
+ array(
+ 'type' => 'format',
+ 'title' => $lang['qb_h4'],
+ 'icon' => 'h4.png',
+ 'key' => '4',
+ 'open' => '=== ',
+ 'close' => ' ===\n',
+ ),
+ array(
+ 'type' => 'format',
+ 'title' => $lang['qb_h5'],
+ 'icon' => 'h5.png',
+ 'key' => '5',
+ 'open' => '== ',
+ 'close' => ' ==\n',
+ ),
+ ),
+ 'block' => true
+ ),
+
+ array(
+ 'type' => 'linkwiz',
+ 'title' => $lang['qb_link'],
+ 'icon' => 'link.png',
+ 'key' => 'l',
+ 'open' => '[[',
+ 'close' => ']]',
+ 'block' => false
+ ),
+ array(
+ 'type' => 'format',
+ 'title' => $lang['qb_extlink'],
+ 'icon' => 'linkextern.png',
+ 'open' => '[[',
+ 'close' => ']]',
+ 'sample' => 'http://example.com|'.$lang['qb_extlink'],
+ 'block' => false
+ ),
+ array(
+ 'type' => 'formatln',
+ 'title' => $lang['qb_ol'],
+ 'icon' => 'ol.png',
+ 'open' => ' - ',
+ 'close' => '',
+ 'key' => '-',
+ 'block' => true
+ ),
+ array(
+ 'type' => 'formatln',
+ 'title' => $lang['qb_ul'],
+ 'icon' => 'ul.png',
+ 'open' => ' * ',
+ 'close' => '',
+ 'key' => '.',
+ 'block' => true
+ ),
+ array(
+ 'type' => 'insert',
+ 'title' => $lang['qb_hr'],
+ 'icon' => 'hr.png',
+ 'insert' => '\n----\n',
+ 'block' => true
+ ),
+ array(
+ 'type' => 'mediapopup',
+ 'title' => $lang['qb_media'],
+ 'icon' => 'image.png',
+ 'url' => 'lib/exe/mediamanager.php?ns=',
+ 'name' => 'mediaselect',
+ 'options'=> 'width=750,height=500,left=20,top=20,scrollbars=yes,resizable=yes',
+ 'block' => false
+ ),
+ array(
+ 'type' => 'picker',
+ 'title' => $lang['qb_smileys'],
+ 'icon' => 'smiley.png',
+ 'list' => getSmileys(),
+ 'icobase'=> 'smileys',
+ 'block' => false
+ ),
+ array(
+ 'type' => 'picker',
+ 'title' => $lang['qb_chars'],
+ 'icon' => 'chars.png',
+ 'list' => [
+ 'À', 'à', 'Ã', 'á', 'Â', 'â', 'Ã', 'ã', 'Ä', 'ä', 'Ç', 'ÇŽ', 'Ä‚', 'ă', 'Ã…', 'Ã¥',
+ 'Ä€', 'Ä', 'Ä„', 'Ä…', 'Æ', 'æ', 'Ć', 'ć', 'Ç', 'ç', 'ÄŒ', 'Ä', 'Ĉ', 'ĉ', 'ÄŠ', 'Ä‹',
+ 'Ã', 'Ä‘', 'ð', 'ÄŽ', 'Ä', 'È', 'è', 'É', 'é', 'Ê', 'ê', 'Ë', 'ë', 'Äš', 'Ä›', 'Ä’',
+ 'Ä“', 'Ä–', 'Ä—', 'Ę', 'Ä™', 'Ä¢', 'Ä£', 'Äœ', 'Ä', 'Äž', 'ÄŸ', 'Ä ', 'Ä¡', 'Ĥ', 'Ä¥', 'ÃŒ',
+ 'ì', 'Ã', 'í', 'ÃŽ', 'î', 'Ã', 'ï', 'Ç', 'Ç', 'Ī', 'Ä«', 'Ä°', 'ı', 'Ä®', 'į', 'Ä´',
+ 'ĵ', 'Ķ', 'Ä·', 'Ĺ', 'ĺ', 'Ä»', 'ļ', 'Ľ', 'ľ', 'Å', 'Å‚', 'Ä¿', 'Å€', 'Ń', 'Å„', 'Ñ',
+ 'ñ', 'Ņ', 'ņ', 'Ň', 'ň', 'Ò', 'ò', 'Ó', 'ó', 'Ô', 'ô', 'Õ', 'õ', 'Ö', 'ö', 'Ǒ',
+ 'Ç’', 'ÅŒ', 'Å', 'Å', 'Å‘', 'Å’', 'Å“', 'Ø', 'ø', 'Å”', 'Å•', 'Å–', 'Å—', 'Ř', 'Å™', 'Åš',
+ 'Å›', 'Åž', 'ÅŸ', 'Å ', 'Å¡', 'Åœ', 'Å', 'Å¢', 'Å£', 'Ť', 'Å¥', 'Ù', 'ù', 'Ú', 'ú', 'Û',
+ 'û', 'Ü', 'ü', 'Ǔ', 'ǔ', 'Ŭ', 'ŭ', 'Ū', 'ū', 'Ů', 'ů', 'ǖ', 'ǘ', 'ǚ', 'ǜ', 'Ų',
+ 'ų', 'Å°', 'ű', 'Å´', 'ŵ', 'Ã', 'ý', 'Ÿ', 'ÿ', 'Ŷ', 'Å·', 'Ź', 'ź', 'Ž', 'ž', 'Å»',
+ 'ż', 'Þ', 'þ', 'ß', 'Ħ', 'ħ', '¿', '¡', '¢', '£', '¤', '¥', '€', '¦', '§', 'ª',
+ '¬', '¯', '°', '±', '÷', '‰', '¼', '½', '¾', '¹', '²', '³', 'µ', '¶', '†', '‡',
+ '·', '•', 'º', '∀', '∂', '∃', 'Æ', 'É™', '∅', '∇', '∈', '∉', '∋', 'âˆ', '∑', '‾',
+ '−', '∗', '×', 'â„', '√', 'âˆ', '∞', '∠', '∧', '∨', '∩', '∪', '∫', '∴', '∼', '≅',
+ '≈', '≠', '≡', '≤', '≥', '⊂', '⊃', '⊄', '⊆', '⊇', '⊕', '⊗', '⊥', '⋅', '◊', '℘',
+ 'ℑ', 'ℜ', 'ℵ', '♠', '♣', '♥', '♦', 'α', 'β', 'Γ', 'γ', 'Δ', 'δ', 'ε', 'ζ', 'η',
+ 'Θ', 'θ', 'ι', 'κ', 'Λ', 'λ', 'μ', 'Ξ', 'ξ', 'Π', 'Ï€', 'Ï', 'Σ', 'σ', 'Τ', 'Ï„',
+ 'Ï…', 'Φ', 'φ', 'χ', 'Ψ', 'ψ', 'Ω', 'ω', '★', '☆', '☎', '☚', '☛', '☜', 'â˜', '☞',
+ '☟', '☹', '☺', '✔', '✘', '„', '“', 'â€', '‚', '‘', '’', '«', '»', '‹', '›', '—',
+ '–', '…', 'â†', '↑', '→', '↓', '↔', 'â‡', '⇑', '⇒', '⇓', '⇔', '©', 'â„¢', '®', '′',
+ '″', '[', ']', '{', '}', '~', '(', ')', '%', '§', '$', '#', '|', '@'
+ ],
+ 'block' => false
+ ),
+ array(
+ 'type' => 'signature',
+ 'title' => $lang['qb_sig'],
+ 'icon' => 'sig.png',
+ 'key' => 'y',
+ 'block' => false
+ ),
+ ));
+ } // end event TOOLBAR_DEFINE default action
+ $evt->advise_after();
+ unset($evt);
+
+ // use JSON to build the JavaScript array
+ print "var $varname = ".json_encode($menu).";\n";
+}
+
+/**
+ * prepares the signature string as configured in the config
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function toolbar_signature(){
+ global $conf;
+ global $INFO;
+ /** @var Input $INPUT */
+ global $INPUT;
+
+ $sig = $conf['signature'];
+ $sig = dformat(null,$sig);
+ $sig = str_replace('@USER@',$INPUT->server->str('REMOTE_USER'),$sig);
+ $sig = str_replace('@NAME@',$INFO['userinfo']['name'],$sig);
+ $sig = str_replace('@MAIL@',$INFO['userinfo']['mail'],$sig);
+ $sig = str_replace('@DATE@',dformat(),$sig);
+ $sig = str_replace('\\\\n','\\n',$sig);
+ return json_encode($sig);
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/inc/utf8.php b/platform/www/inc/utf8.php
new file mode 100644
index 0000000..1227407
--- /dev/null
+++ b/platform/www/inc/utf8.php
@@ -0,0 +1,284 @@
+<?php
+/**
+ * UTF8 helper functions
+ *
+ * This file now only intitializes the UTF-8 capability detection and defines helper
+ * functions if needed. All actual code is in the \dokuwiki\Utf8 classes
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Utf8\Clean;
+use dokuwiki\Utf8\Conversion;
+use dokuwiki\Utf8\PhpString;
+use dokuwiki\Utf8\Unicode;
+
+/**
+ * check for mb_string support
+ */
+if (!defined('UTF8_MBSTRING')) {
+ if (function_exists('mb_substr') && !defined('UTF8_NOMBSTRING')) {
+ define('UTF8_MBSTRING', 1);
+ } else {
+ define('UTF8_MBSTRING', 0);
+ }
+}
+
+/**
+ * Check if PREG was compiled with UTF-8 support
+ *
+ * Without this many of the functions below will not work, so this is a minimal requirement
+ */
+if (!defined('UTF8_PREGSUPPORT')) {
+ define('UTF8_PREGSUPPORT', (bool)@preg_match('/^.$/u', 'ñ'));
+}
+
+/**
+ * Check if PREG was compiled with Unicode Property support
+ *
+ * This is not required for the functions below, but might be needed in a UTF-8 aware application
+ */
+if (!defined('UTF8_PROPERTYSUPPORT')) {
+ define('UTF8_PROPERTYSUPPORT', (bool)@preg_match('/^\pL$/u', 'ñ'));
+}
+
+
+if (UTF8_MBSTRING) {
+ mb_internal_encoding('UTF-8');
+}
+
+
+if (!function_exists('utf8_isASCII')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_isASCII($str)
+ {
+ dbg_deprecated(Clean::class . '::isASCII()');
+ return Clean::isASCII($str);
+ }
+}
+
+
+if (!function_exists('utf8_strip')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_strip($str)
+ {
+ dbg_deprecated(Clean::class . '::strip()');
+ return Clean::strip($str);
+ }
+}
+
+if (!function_exists('utf8_check')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_check($str)
+ {
+ dbg_deprecated(Clean::class . '::isUtf8()');
+ return Clean::isUtf8($str);
+ }
+}
+
+if (!function_exists('utf8_basename')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_basename($path, $suffix = '')
+ {
+ dbg_deprecated(PhpString::class . '::basename()');
+ return PhpString::basename($path, $suffix);
+ }
+}
+
+if (!function_exists('utf8_strlen')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_strlen($str)
+ {
+ dbg_deprecated(PhpString::class . '::strlen()');
+ return PhpString::strlen($str);
+ }
+}
+
+if (!function_exists('utf8_substr')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_substr($str, $offset, $length = null)
+ {
+ dbg_deprecated(PhpString::class . '::substr()');
+ return PhpString::substr($str, $offset, $length);
+ }
+}
+
+if (!function_exists('utf8_substr_replace')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_substr_replace($string, $replacement, $start, $length = 0)
+ {
+ dbg_deprecated(PhpString::class . '::substr_replace()');
+ return PhpString::substr_replace($string, $replacement, $start, $length);
+ }
+}
+
+if (!function_exists('utf8_ltrim')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_ltrim($str, $charlist = '')
+ {
+ dbg_deprecated(PhpString::class . '::ltrim()');
+ return PhpString::ltrim($str, $charlist);
+ }
+}
+
+if (!function_exists('utf8_rtrim')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_rtrim($str, $charlist = '')
+ {
+ dbg_deprecated(PhpString::class . '::rtrim()');
+ return PhpString::rtrim($str, $charlist);
+ }
+}
+
+if (!function_exists('utf8_trim')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_trim($str, $charlist = '')
+ {
+ dbg_deprecated(PhpString::class . '::trim()');
+ return PhpString::trim($str, $charlist);
+ }
+}
+
+if (!function_exists('utf8_strtolower')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_strtolower($str)
+ {
+ dbg_deprecated(PhpString::class . '::strtolower()');
+ return PhpString::strtolower($str);
+ }
+}
+
+if (!function_exists('utf8_strtoupper')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_strtoupper($str)
+ {
+ dbg_deprecated(PhpString::class . '::strtoupper()');
+ return PhpString::strtoupper($str);
+ }
+}
+
+if (!function_exists('utf8_ucfirst')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_ucfirst($str)
+ {
+ dbg_deprecated(PhpString::class . '::ucfirst()');
+ return PhpString::ucfirst($str);
+ }
+}
+
+if (!function_exists('utf8_ucwords')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_ucwords($str)
+ {
+ dbg_deprecated(PhpString::class . '::ucwords()');
+ return PhpString::ucwords($str);
+ }
+}
+
+if (!function_exists('utf8_deaccent')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_deaccent($str, $case = 0)
+ {
+ dbg_deprecated(Clean::class . '::deaccent()');
+ return Clean::deaccent($str, $case);
+ }
+}
+
+if (!function_exists('utf8_romanize')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_romanize($str)
+ {
+ dbg_deprecated(Clean::class . '::romanize()');
+ return Clean::romanize($str);
+ }
+}
+
+if (!function_exists('utf8_stripspecials')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_stripspecials($str, $repl = '', $additional = '')
+ {
+ dbg_deprecated(Clean::class . '::stripspecials()');
+ return Clean::stripspecials($str, $repl, $additional);
+ }
+}
+
+if (!function_exists('utf8_strpos')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_strpos($haystack, $needle, $offset = 0)
+ {
+ dbg_deprecated(PhpString::class . '::strpos()');
+ return PhpString::strpos($haystack, $needle, $offset);
+ }
+}
+
+if (!function_exists('utf8_tohtml')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_tohtml($str, $all = false)
+ {
+ dbg_deprecated(Conversion::class . '::toHtml()');
+ return Conversion::toHtml($str, $all);
+ }
+}
+
+if (!function_exists('utf8_unhtml')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_unhtml($str, $enties = false)
+ {
+ dbg_deprecated(Conversion::class . '::fromHtml()');
+ return Conversion::fromHtml($str, $enties);
+ }
+}
+
+if (!function_exists('utf8_to_unicode')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_to_unicode($str, $strict = false)
+ {
+ dbg_deprecated(Unicode::class . '::fromUtf8()');
+ return Unicode::fromUtf8($str, $strict);
+ }
+}
+
+if (!function_exists('unicode_to_utf8')) {
+ /** @deprecated 2019-06-09 */
+ function unicode_to_utf8($arr, $strict = false)
+ {
+ dbg_deprecated(Unicode::class . '::toUtf8()');
+ return Unicode::toUtf8($arr, $strict);
+ }
+}
+
+if (!function_exists('utf8_to_utf16be')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_to_utf16be($str, $bom = false)
+ {
+ dbg_deprecated(Conversion::class . '::toUtf16be()');
+ return Conversion::toUtf16be($str, $bom);
+ }
+}
+
+if (!function_exists('utf16be_to_utf8')) {
+ /** @deprecated 2019-06-09 */
+ function utf16be_to_utf8($str)
+ {
+ dbg_deprecated(Conversion::class . '::fromUtf16be()');
+ return Conversion::fromUtf16be($str);
+ }
+}
+
+if (!function_exists('utf8_bad_replace')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_bad_replace($str, $replace = '')
+ {
+ dbg_deprecated(Clean::class . '::replaceBadBytes()');
+ return Clean::replaceBadBytes($str, $replace);
+ }
+}
+
+if (!function_exists('utf8_correctIdx')) {
+ /** @deprecated 2019-06-09 */
+ function utf8_correctIdx($str, $i, $next = false)
+ {
+ dbg_deprecated(Clean::class . '::correctIdx()');
+ return Clean::correctIdx($str, $i, $next);
+ }
+}
diff --git a/platform/www/index.php b/platform/www/index.php
new file mode 100644
index 0000000..da3abe6
--- /dev/null
+++ b/platform/www/index.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Forwarder/Router to doku.php
+ *
+ * In normal usage, this script simply redirects to doku.php. However it can also be used as a routing
+ * script with PHP's builtin webserver. It takes care of .htaccess compatible rewriting, directory/file
+ * access permission checking and passing on static files.
+ *
+ * Usage example:
+ *
+ * php -S localhost:8000 index.php
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+if (php_sapi_name() != 'cli-server') {
+ if (!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/');
+ require_once(DOKU_INC . 'inc/init.php');
+
+ send_redirect(DOKU_URL . 'doku.php');
+}
+
+// ROUTER starts below
+
+// avoid path traversal
+$_SERVER['SCRIPT_NAME'] = str_replace('/../', '/', $_SERVER['SCRIPT_NAME']);
+
+// routing aka. rewriting
+if (preg_match('/^\/_media\/(.*)/', $_SERVER['SCRIPT_NAME'], $m)) {
+ // media dispatcher
+ $_GET['media'] = $m[1];
+ require $_SERVER['DOCUMENT_ROOT'] . '/lib/exe/fetch.php';
+
+} elseif (preg_match('/^\/_detail\/(.*)/', $_SERVER['SCRIPT_NAME'], $m)) {
+ // image detail view
+ $_GET['media'] = $m[1];
+ require $_SERVER['DOCUMENT_ROOT'] . '/lib/exe/detail.php';
+
+} elseif (preg_match('/^\/_export\/([^\/]+)\/(.*)/', $_SERVER['SCRIPT_NAME'], $m)) {
+ // exports
+ $_GET['do'] = 'export_' . $m[1];
+ $_GET['id'] = $m[2];
+ require $_SERVER['DOCUMENT_ROOT'] . '/doku.php';
+
+} elseif (
+ $_SERVER['SCRIPT_NAME'] !== '/index.php' &&
+ file_exists($_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME'])
+) {
+ // existing files
+
+ // access limitiations
+ if (preg_match('/\/([._]ht|README$|VERSION$|COPYING$)/', $_SERVER['SCRIPT_NAME']) or
+ preg_match('/^\/(data|conf|bin|inc)\//', $_SERVER['SCRIPT_NAME'])
+ ) {
+ header('HTTP/1.1 403 Forbidden');
+ die('Access denied');
+ }
+
+ if (substr($_SERVER['SCRIPT_NAME'], -4) == '.php') {
+ # php scripts
+ require $_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME'];
+ } else {
+ # static files
+ return false;
+ }
+} else {
+ // treat everything else as a potential wiki page
+ // working around https://bugs.php.net/bug.php?id=61286
+ $request_path = preg_split('/\?/', $_SERVER['REQUEST_URI'], 2)[0];
+ if (isset($_SERVER['PATH_INFO'])) {
+ $_GET['id'] = $_SERVER['PATH_INFO'];
+ } elseif ($request_path != '/' && $request_path != '/index.php') {
+ $_GET['id'] = $_SERVER['SCRIPT_NAME'];
+ }
+
+ require $_SERVER['DOCUMENT_ROOT'] . '/doku.php';
+}
diff --git a/platform/www/install.php b/platform/www/install.php
new file mode 100644
index 0000000..e8e9279
--- /dev/null
+++ b/platform/www/install.php
@@ -0,0 +1,663 @@
+<?php
+/*><div style="width:60%; margin: auto; background-color: #fcc;
+ border: 1px solid #faa; padding: 0.5em 1em;">
+ <h1 style="font-size: 120%">No PHP Support</h1>
+
+ It seems this server has no PHP support enabled. You will need to
+ enable PHP before you can install and run DokuWiki. Contact your hosting
+ provider if you're unsure what this means.
+
+</div>*/
+/**
+ * Dokuwiki installation assistance
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/');
+if(!defined('DOKU_CONF')) define('DOKU_CONF',DOKU_INC.'conf/');
+if(!defined('DOKU_LOCAL')) define('DOKU_LOCAL',DOKU_INC.'conf/');
+
+// load and initialize the core system
+require_once(DOKU_INC.'inc/init.php');
+
+// check for error reporting override or set error reporting to sane values
+if (!defined('DOKU_E_LEVEL')) { error_reporting(E_ALL ^ E_NOTICE); }
+else { error_reporting(DOKU_E_LEVEL); }
+
+// language strings
+require_once(DOKU_INC.'inc/lang/en/lang.php');
+if(isset($_REQUEST['l']) && !is_array($_REQUEST['l'])) {
+ $LC = preg_replace('/[^a-z\-]+/','',$_REQUEST['l']);
+}
+if(empty($LC)) $LC = 'en';
+if($LC && $LC != 'en' ) {
+ require_once(DOKU_INC.'inc/lang/'.$LC.'/lang.php');
+}
+
+// initialise variables ...
+$error = array();
+
+// begin output
+header('Content-Type: text/html; charset=utf-8');
+?>
+<!DOCTYPE html>
+<html lang="<?php echo $LC?>" dir="<?php echo $lang['direction']?>">
+<head>
+ <meta charset="utf-8" />
+ <title><?php echo $lang['i_installer']?></title>
+ <style>
+ body { width: 90%; margin: 0 auto; font: 84% Verdana, Helvetica, Arial, sans-serif; }
+ img { border: none }
+ br.cl { clear:both; }
+ code { font-size: 110%; color: #800000; }
+ fieldset { border: none }
+ label { display: block; margin-top: 0.5em; }
+ select.text, input.text { width: 30em; margin: 0 0.5em; }
+ a {text-decoration: none}
+ </style>
+ <script>
+ function acltoggle(){
+ var cb = document.getElementById('acl');
+ var fs = document.getElementById('acldep');
+ if(!cb || !fs) return;
+ if(cb.checked){
+ fs.style.display = '';
+ }else{
+ fs.style.display = 'none';
+ }
+ }
+ window.onload = function(){
+ acltoggle();
+ var cb = document.getElementById('acl');
+ if(cb) cb.onchange = acltoggle;
+ };
+ </script>
+</head>
+<body style="">
+ <h1 style="float:left">
+ <img src="lib/exe/fetch.php?media=wiki:dokuwiki-128.png"
+ style="vertical-align: middle;" alt="" height="64" width="64" />
+ <?php echo $lang['i_installer']?>
+ </h1>
+ <div style="float:right; margin: 1em;">
+ <?php langsel()?>
+ </div>
+ <br class="cl" />
+
+ <div style="float: right; width: 34%;">
+ <?php
+ if(file_exists(DOKU_INC.'inc/lang/'.$LC.'/install.html')){
+ include(DOKU_INC.'inc/lang/'.$LC.'/install.html');
+ }else{
+ print "<div lang=\"en\" dir=\"ltr\">\n";
+ include(DOKU_INC.'inc/lang/en/install.html');
+ print "</div>\n";
+ }
+ ?>
+ <a style="
+ background: transparent
+ url(data/dont-panic-if-you-see-this-in-your-logs-it-means-your-directory-permissions-are-correct.png)
+ left top no-repeat;
+ display: block; width:380px; height:73px; border:none; clear:both;"
+ target="_blank"
+ href="http://www.dokuwiki.org/security#web_access_security"></a>
+ </div>
+
+ <div style="float: left; width: 58%;">
+ <?php
+ try {
+ if(! (check_functions() && check_permissions()) ){
+ echo '<p>'.$lang['i_problems'].'</p>';
+ print_errors();
+ print_retry();
+ }elseif(!check_configs()){
+ echo '<p>'.$lang['i_modified'].'</p>';
+ print_errors();
+ }elseif(check_data($_REQUEST['d'])){
+ // check_data has sanitized all input parameters
+ if(!store_data($_REQUEST['d'])){
+ echo '<p>'.$lang['i_failure'].'</p>';
+ print_errors();
+ }else{
+ echo '<p>'.$lang['i_success'].'</p>';
+ }
+ }else{
+ print_errors();
+ print_form($_REQUEST['d']);
+ }
+ } catch (Exception $e) {
+ echo 'Caught exception: ', $e->getMessage(), "\n";
+ }
+ ?>
+ </div>
+
+
+<div style="clear: both">
+ <a href="http://dokuwiki.org/"><img src="lib/tpl/dokuwiki/images/button-dw.png" alt="driven by DokuWiki" /></a>
+ <a href="http://php.net"><img src="lib/tpl/dokuwiki/images/button-php.gif" alt="powered by PHP" /></a>
+</div>
+</body>
+</html>
+<?php
+
+/**
+ * Print the input form
+ *
+ * @param array $d submitted entry 'd' of request data
+ */
+function print_form($d){
+ global $lang;
+ global $LC;
+
+ include(DOKU_CONF.'license.php');
+
+ if(!is_array($d)) $d = array();
+ $d = array_map('hsc',$d);
+
+ if(!isset($d['acl'])) $d['acl']=1;
+ if(!isset($d['pop'])) $d['pop']=1;
+
+ ?>
+ <form action="" method="post">
+ <input type="hidden" name="l" value="<?php echo $LC ?>" />
+ <fieldset>
+ <label for="title"><?php echo $lang['i_wikiname']?>
+ <input type="text" name="d[title]" id="title" value="<?php echo $d['title'] ?>" style="width: 20em;" />
+ </label>
+
+ <fieldset style="margin-top: 1em;">
+ <label for="acl">
+ <input type="checkbox" name="d[acl]" id="acl" <?php echo(($d['acl'] ? ' checked="checked"' : ''));?> />
+ <?php echo $lang['i_enableacl']?></label>
+
+ <fieldset id="acldep">
+ <label for="superuser"><?php echo $lang['i_superuser']?></label>
+ <input class="text" type="text" name="d[superuser]" id="superuser"
+ value="<?php echo $d['superuser'] ?>" />
+
+ <label for="fullname"><?php echo $lang['fullname']?></label>
+ <input class="text" type="text" name="d[fullname]" id="fullname"
+ value="<?php echo $d['fullname'] ?>" />
+
+ <label for="email"><?php echo $lang['email']?></label>
+ <input class="text" type="text" name="d[email]" id="email" value="<?php echo $d['email'] ?>" />
+
+ <label for="password"><?php echo $lang['pass']?></label>
+ <input class="text" type="password" name="d[password]" id="password" />
+
+ <label for="confirm"><?php echo $lang['passchk']?></label>
+ <input class="text" type="password" name="d[confirm]" id="confirm" />
+
+ <label for="policy"><?php echo $lang['i_policy']?></label>
+ <select class="text" name="d[policy]" id="policy">
+ <option value="0" <?php echo ($d['policy'] == 0)?'selected="selected"':'' ?>><?php
+ echo $lang['i_pol0']?></option>
+ <option value="1" <?php echo ($d['policy'] == 1)?'selected="selected"':'' ?>><?php
+ echo $lang['i_pol1']?></option>
+ <option value="2" <?php echo ($d['policy'] == 2)?'selected="selected"':'' ?>><?php
+ echo $lang['i_pol2']?></option>
+ </select>
+
+ <label for="allowreg">
+ <input type="checkbox" name="d[allowreg]" id="allowreg" <?php
+ echo(($d['allowreg'] ? ' checked="checked"' : ''));?> />
+ <?php echo $lang['i_allowreg']?>
+ </label>
+ </fieldset>
+ </fieldset>
+
+ <fieldset>
+ <p><?php echo $lang['i_license']?></p>
+ <?php
+ array_push($license,array('name' => $lang['i_license_none'], 'url'=>''));
+ if(empty($d['license'])) $d['license'] = 'cc-by-sa';
+ foreach($license as $key => $lic){
+ echo '<label for="lic_'.$key.'">';
+ echo '<input type="radio" name="d[license]" value="'.hsc($key).'" id="lic_'.$key.'"'.
+ (($d['license'] === $key)?' checked="checked"':'').'>';
+ echo hsc($lic['name']);
+ if($lic['url']) echo ' <a href="'.$lic['url'].'" target="_blank"><sup>[?]</sup></a>';
+ echo '</label>';
+ }
+ ?>
+ </fieldset>
+
+ <fieldset>
+ <p><?php echo $lang['i_pop_field']?></p>
+ <label for="pop">
+ <input type="checkbox" name="d[pop]" id="pop" <?php
+ echo(($d['pop'] ? ' checked="checked"' : ''));?> />
+ <?php echo $lang['i_pop_label']?>
+ <a href="http://www.dokuwiki.org/popularity" target="_blank"><sup>[?]</sup></a>
+ </label>
+ </fieldset>
+
+ </fieldset>
+ <fieldset id="process">
+ <button type="submit" name="submit"><?php echo $lang['btn_save']?></button>
+ </fieldset>
+ </form>
+ <?php
+}
+
+function print_retry() {
+ global $lang;
+ global $LC;
+ ?>
+ <form action="" method="get">
+ <fieldset>
+ <input type="hidden" name="l" value="<?php echo $LC ?>" />
+ <button type="submit"><?php echo $lang['i_retry'];?></button>
+ </fieldset>
+ </form>
+ <?php
+}
+
+/**
+ * Check validity of data
+ *
+ * @author Andreas Gohr
+ *
+ * @param array $d
+ * @return bool ok?
+ */
+function check_data(&$d){
+ static $form_default = array(
+ 'title' => '',
+ 'acl' => '1',
+ 'superuser' => '',
+ 'fullname' => '',
+ 'email' => '',
+ 'password' => '',
+ 'confirm' => '',
+ 'policy' => '0',
+ 'allowreg' => '0',
+ 'license' => 'cc-by-sa'
+ );
+ global $lang;
+ global $error;
+
+ if(!is_array($d)) $d = array();
+ foreach($d as $k => $v) {
+ if(is_array($v))
+ unset($d[$k]);
+ else
+ $d[$k] = (string)$v;
+ }
+
+ //autolowercase the username
+ $d['superuser'] = isset($d['superuser']) ? strtolower($d['superuser']) : "";
+
+ $ok = false;
+
+ if(isset($_REQUEST['submit'])) {
+ $ok = true;
+
+ // check input
+ if(empty($d['title'])){
+ $error[] = sprintf($lang['i_badval'],$lang['i_wikiname']);
+ $ok = false;
+ }
+ if(isset($d['acl'])){
+ if(!preg_match('/^[a-z0-9_]+$/',$d['superuser'])){
+ $error[] = sprintf($lang['i_badval'],$lang['i_superuser']);
+ $ok = false;
+ }
+ if(empty($d['password'])){
+ $error[] = sprintf($lang['i_badval'],$lang['pass']);
+ $ok = false;
+ }
+ elseif(!isset($d['confirm']) || $d['confirm'] != $d['password']){
+ $error[] = sprintf($lang['i_badval'],$lang['passchk']);
+ $ok = false;
+ }
+ if(empty($d['fullname']) || strstr($d['fullname'],':')){
+ $error[] = sprintf($lang['i_badval'],$lang['fullname']);
+ $ok = false;
+ }
+ if(empty($d['email']) || strstr($d['email'],':') || !strstr($d['email'],'@')){
+ $error[] = sprintf($lang['i_badval'],$lang['email']);
+ $ok = false;
+ }
+ }else{
+ // Since default = 1, browser won't send acl=0 when user untick acl
+ $d['acl'] = '0';
+ }
+ }
+ $d = array_merge($form_default, $d);
+ return $ok;
+}
+
+/**
+ * Writes the data to the config files
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param array $d
+ * @return bool
+ */
+function store_data($d){
+ global $LC;
+ $ok = true;
+ $d['policy'] = (int) $d['policy'];
+
+ // create local.php
+ $now = gmdate('r');
+ $output = <<<EOT
+<?php
+/**
+ * Dokuwiki's Main Configuration File - Local Settings
+ * Auto-generated by install script
+ * Date: $now
+ */
+
+EOT;
+ // add any config options set by a previous installer
+ $preset = __DIR__.'/install.conf';
+ if(file_exists($preset)){
+ $output .= "# preset config options\n";
+ $output .= file_get_contents($preset);
+ $output .= "\n\n";
+ $output .= "# options selected in installer\n";
+ @unlink($preset);
+ }
+
+ $output .= '$conf[\'title\'] = \''.addslashes($d['title'])."';\n";
+ $output .= '$conf[\'lang\'] = \''.addslashes($LC)."';\n";
+ $output .= '$conf[\'license\'] = \''.addslashes($d['license'])."';\n";
+ if($d['acl']){
+ $output .= '$conf[\'useacl\'] = 1'.";\n";
+ $output .= "\$conf['superuser'] = '@admin';\n";
+ }
+ if(!$d['allowreg']){
+ $output .= '$conf[\'disableactions\'] = \'register\''.";\n";
+ }
+ $ok = $ok && fileWrite(DOKU_LOCAL.'local.php',$output);
+
+ if ($d['acl']) {
+ // hash the password
+ $phash = new \dokuwiki\PassHash();
+ $pass = $phash->hash_bcrypt($d['password']);
+
+ // create users.auth.php
+ $output = <<<EOT
+# users.auth.php
+# <?php exit()?>
+# Don't modify the lines above
+#
+# Userfile
+#
+# Auto-generated by install script
+# Date: $now
+#
+# Format:
+# login:passwordhash:Real Name:email:groups,comma,separated
+
+EOT;
+ // --- user:bcryptpasswordhash:Real Name:email:groups,comma,seperated
+ $output = $output."\n".join(":",array($d['superuser'], $pass, $d['fullname'], $d['email'], 'admin,user'))."\n";
+ $ok = $ok && fileWrite(DOKU_LOCAL.'users.auth.php', $output);
+
+ // create acl.auth.php
+ $output = <<<EOT
+# acl.auth.php
+# <?php exit()?>
+# Don't modify the lines above
+#
+# Access Control Lists
+#
+# Auto-generated by install script
+# Date: $now
+
+EOT;
+ if($d['policy'] == 2){
+ $output .= "* @ALL 0\n";
+ $output .= "* @user 8\n";
+ }elseif($d['policy'] == 1){
+ $output .= "* @ALL 1\n";
+ $output .= "* @user 8\n";
+ }else{
+ $output .= "* @ALL 8\n";
+ }
+ $ok = $ok && fileWrite(DOKU_LOCAL.'acl.auth.php', $output);
+ }
+
+ // enable popularity submission
+ if($d['pop']){
+ @touch(DOKU_INC.'data/cache/autosubmit.txt');
+ }
+
+ // disable auth plugins til needed
+ $output = <<<EOT
+<?php
+/*
+ * Local plugin enable/disable settings
+ *
+ * Auto-generated by install script
+ * Date: $now
+ */
+
+\$plugins['authad'] = 0;
+\$plugins['authldap'] = 0;
+\$plugins['authmysql'] = 0;
+\$plugins['authpgsql'] = 0;
+
+EOT;
+ $ok = $ok && fileWrite(DOKU_LOCAL.'plugins.local.php', $output);
+
+ return $ok;
+}
+
+/**
+ * Write the given content to a file
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $filename
+ * @param string $data
+ * @return bool
+ */
+function fileWrite($filename, $data) {
+ global $error;
+ global $lang;
+
+ if (($fp = @fopen($filename, 'wb')) === false) {
+ $filename = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}/', $filename);
+ $error[] = sprintf($lang['i_writeerr'],$filename);
+ return false;
+ }
+
+ if (!empty($data)) { fwrite($fp, $data); }
+ fclose($fp);
+ return true;
+}
+
+
+/**
+ * check installation dependent local config files and tests for a known
+ * unmodified main config file
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @return bool
+ */
+function check_configs(){
+ global $error;
+ global $lang;
+
+ $ok = true;
+
+ $config_files = array(
+ 'local' => DOKU_LOCAL.'local.php',
+ 'users' => DOKU_LOCAL.'users.auth.php',
+ 'auth' => DOKU_LOCAL.'acl.auth.php'
+ );
+
+ // configs shouldn't exist
+ foreach ($config_files as $file) {
+ if (file_exists($file) && filesize($file)) {
+ $file = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}/', $file);
+ $error[] = sprintf($lang['i_confexists'],$file);
+ $ok = false;
+ }
+ }
+ return $ok;
+}
+
+
+/**
+ * Check other installation dir/file permission requirements
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @return bool
+ */
+function check_permissions(){
+ global $error;
+ global $lang;
+
+ $dirs = array(
+ 'conf' => DOKU_LOCAL,
+ 'data' => DOKU_INC.'data',
+ 'pages' => DOKU_INC.'data/pages',
+ 'attic' => DOKU_INC.'data/attic',
+ 'media' => DOKU_INC.'data/media',
+ 'media_attic' => DOKU_INC.'data/media_attic',
+ 'media_meta' => DOKU_INC.'data/media_meta',
+ 'meta' => DOKU_INC.'data/meta',
+ 'cache' => DOKU_INC.'data/cache',
+ 'locks' => DOKU_INC.'data/locks',
+ 'index' => DOKU_INC.'data/index',
+ 'tmp' => DOKU_INC.'data/tmp'
+ );
+
+ $ok = true;
+ foreach($dirs as $dir){
+ if(!file_exists("$dir/.") || !is_writable($dir)){
+ $dir = str_replace($_SERVER['DOCUMENT_ROOT'],'{DOCUMENT_ROOT}', $dir);
+ $error[] = sprintf($lang['i_permfail'],$dir);
+ $ok = false;
+ }
+ }
+ return $ok;
+}
+
+/**
+ * Check the availability of functions used in DokuWiki and the PHP version
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return bool
+ */
+function check_functions(){
+ global $error;
+ global $lang;
+ $ok = true;
+
+ if(version_compare(phpversion(),'5.6.0','<')){
+ $error[] = sprintf($lang['i_phpver'],phpversion(),'5.6.0');
+ $ok = false;
+ }
+
+ if(ini_get('mbstring.func_overload') != 0){
+ $error[] = $lang['i_mbfuncoverload'];
+ $ok = false;
+ }
+
+ try {
+ random_bytes(1);
+ } catch (\Exception $th) {
+ // If an appropriate source of randomness cannot be found, an Exception will be thrown by PHP 7+
+ // this exception is also thrown by paragonie/random_compat for PHP 5.6 support
+ $error[] = $lang['i_urandom'];
+ $ok = false;
+ }
+
+ if(ini_get('mbstring.func_overload') != 0){
+ $error[] = $lang['i_mbfuncoverload'];
+ $ok = false;
+ }
+
+ $funcs = explode(' ','addslashes call_user_func chmod copy fgets '.
+ 'file file_exists fseek flush filesize ftell fopen '.
+ 'glob header ignore_user_abort ini_get mkdir '.
+ 'ob_start opendir parse_ini_file readfile realpath '.
+ 'rename rmdir serialize session_start unlink usleep '.
+ 'preg_replace file_get_contents htmlspecialchars_decode '.
+ 'spl_autoload_register stream_select fsockopen pack xml_parser_create');
+
+ if (!function_exists('mb_substr')) {
+ $funcs[] = 'utf8_encode';
+ $funcs[] = 'utf8_decode';
+ }
+
+ if(!function_exists('mail')){
+ if(strpos(ini_get('disable_functions'),'mail') !== false) {
+ $disabled = $lang['i_disabled'];
+ }
+ else {
+ $disabled = "";
+ }
+ $error[] = sprintf($lang['i_funcnmail'],$disabled);
+ }
+
+ foreach($funcs as $func){
+ if(!function_exists($func)){
+ $error[] = sprintf($lang['i_funcna'],$func);
+ $ok = false;
+ }
+ }
+ return $ok;
+}
+
+/**
+ * Print language selection
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function langsel(){
+ global $lang;
+ global $LC;
+
+ $dir = DOKU_INC.'inc/lang';
+ $dh = opendir($dir);
+ if(!$dh) return;
+
+ $langs = array();
+ while (($file = readdir($dh)) !== false) {
+ if(preg_match('/^[\._]/',$file)) continue;
+ if(is_dir($dir.'/'.$file) && file_exists($dir.'/'.$file.'/lang.php')){
+ $langs[] = $file;
+ }
+ }
+ closedir($dh);
+ sort($langs);
+
+ echo '<form action="">';
+ echo $lang['i_chooselang'];
+ echo ': <select name="l" onchange="submit()">';
+ foreach($langs as $l){
+ $sel = ($l == $LC) ? 'selected="selected"' : '';
+ echo '<option value="'.$l.'" '.$sel.'>'.$l.'</option>';
+ }
+ echo '</select> ';
+ echo '<button type="submit">'.$lang['btn_update'].'</button>';
+ echo '</form>';
+}
+
+/**
+ * Print global error array
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function print_errors(){
+ global $error;
+ if(!empty($error)) {
+ echo '<ul>';
+ foreach ($error as $err){
+ echo "<li>$err</li>";
+ }
+ echo '</ul>';
+ }
+}
diff --git a/platform/www/lib/exe/ajax.php b/platform/www/lib/exe/ajax.php
new file mode 100644
index 0000000..55f1c87
--- /dev/null
+++ b/platform/www/lib/exe/ajax.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * DokuWiki AJAX call handler
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/../../');
+require_once(DOKU_INC . 'inc/init.php');
+
+//close session
+session_write_close();
+
+// default header, ajax call may overwrite it later
+header('Content-Type: text/html; charset=utf-8');
+
+//call the requested function
+global $INPUT;
+if($INPUT->has('call')) {
+ $call = $INPUT->filter('utf8_stripspecials')->str('call');
+ new \dokuwiki\Ajax($call);
+} else {
+ http_status(404);
+}
diff --git a/platform/www/lib/exe/css.php b/platform/www/lib/exe/css.php
new file mode 100644
index 0000000..2ea2c09
--- /dev/null
+++ b/platform/www/lib/exe/css.php
@@ -0,0 +1,676 @@
+<?php
+/**
+ * DokuWiki StyleSheet creator
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Cache\Cache;
+use dokuwiki\Extension\Event;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', __DIR__ .'/../../');
+if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
+if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here
+if(!defined('NL')) define('NL',"\n");
+require_once(DOKU_INC.'inc/init.php');
+
+// Main (don't run when UNIT test)
+if(!defined('SIMPLE_TEST')){
+ header('Content-Type: text/css; charset=utf-8');
+ css_out();
+}
+
+
+// ---------------------- functions ------------------------------
+
+/**
+ * Output all needed Styles
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_out(){
+ global $conf;
+ global $lang;
+ global $config_cascade;
+ global $INPUT;
+
+ if ($INPUT->str('s') == 'feed') {
+ $mediatypes = array('feed');
+ $type = 'feed';
+ } else {
+ $mediatypes = array('screen', 'all', 'print', 'speech');
+ $type = '';
+ }
+
+ // decide from where to get the template
+ $tpl = trim(preg_replace('/[^\w-]+/','',$INPUT->str('t')));
+ if(!$tpl) $tpl = $conf['template'];
+
+ // load style.ini
+ $styleUtil = new \dokuwiki\StyleUtils($tpl, $INPUT->bool('preview'));
+ $styleini = $styleUtil->cssStyleini();
+
+ // cache influencers
+ $tplinc = tpl_incdir($tpl);
+ $cache_files = getConfigFiles('main');
+ $cache_files[] = $tplinc.'style.ini';
+ $cache_files[] = DOKU_CONF."tpl/$tpl/style.ini";
+ $cache_files[] = __FILE__;
+ if($INPUT->bool('preview')) $cache_files[] = $conf['cachedir'].'/preview.ini';
+
+ // Array of needed files and their web locations, the latter ones
+ // are needed to fix relative paths in the stylesheets
+ $media_files = array();
+ foreach($mediatypes as $mediatype) {
+ $files = array();
+
+ // load core styles
+ $files[DOKU_INC.'lib/styles/'.$mediatype.'.css'] = DOKU_BASE.'lib/styles/';
+
+ // load jQuery-UI theme
+ if ($mediatype == 'screen') {
+ $files[DOKU_INC.'lib/scripts/jquery/jquery-ui-theme/smoothness.css'] =
+ DOKU_BASE.'lib/scripts/jquery/jquery-ui-theme/';
+ }
+ // load plugin styles
+ $files = array_merge($files, css_pluginstyles($mediatype));
+ // load template styles
+ if (isset($styleini['stylesheets'][$mediatype])) {
+ $files = array_merge($files, $styleini['stylesheets'][$mediatype]);
+ }
+ // load user styles
+ if(is_array($config_cascade['userstyle'][$mediatype])) {
+ foreach($config_cascade['userstyle'][$mediatype] as $userstyle) {
+ $files[$userstyle] = DOKU_BASE;
+ }
+ }
+
+ // Let plugins decide to either put more styles here or to remove some
+ $media_files[$mediatype] = css_filewrapper($mediatype, $files);
+ $CSSEvt = new Event('CSS_STYLES_INCLUDED', $media_files[$mediatype]);
+
+ // Make it preventable.
+ if ( $CSSEvt->advise_before() ) {
+ $cache_files = array_merge($cache_files, array_keys($media_files[$mediatype]['files']));
+ } else {
+ // unset if prevented. Nothing will be printed for this mediatype.
+ unset($media_files[$mediatype]);
+ }
+
+ // finish event.
+ $CSSEvt->advise_after();
+ }
+
+ // The generated script depends on some dynamic options
+ $cache = new Cache(
+ 'styles' .
+ $_SERVER['HTTP_HOST'] .
+ $_SERVER['SERVER_PORT'] .
+ $INPUT->bool('preview') .
+ DOKU_BASE .
+ $tpl .
+ $type,
+ '.css'
+ );
+ $cache->setEvent('CSS_CACHE_USE');
+
+ // check cache age & handle conditional request
+ // This may exit if a cache can be used
+ $cache_ok = $cache->useCache(array('files' => $cache_files));
+ http_cached($cache->cache, $cache_ok);
+
+ // start output buffering
+ ob_start();
+
+ // Fire CSS_STYLES_INCLUDED for one last time to let the
+ // plugins decide whether to include the DW default styles.
+ // This can be done by preventing the Default.
+ $media_files['DW_DEFAULT'] = css_filewrapper('DW_DEFAULT');
+ Event::createAndTrigger('CSS_STYLES_INCLUDED', $media_files['DW_DEFAULT'], 'css_defaultstyles');
+
+ // build the stylesheet
+ foreach ($mediatypes as $mediatype) {
+
+ // Check if there is a wrapper set for this type.
+ if ( !isset($media_files[$mediatype]) ) {
+ continue;
+ }
+
+ $cssData = $media_files[$mediatype];
+
+ // Print the styles.
+ print NL;
+ if ( $cssData['encapsulate'] === true ) print $cssData['encapsulationPrefix'] . ' {';
+ print '/* START '.$cssData['mediatype'].' styles */'.NL;
+
+ // load files
+ foreach($cssData['files'] as $file => $location){
+ $display = str_replace(fullpath(DOKU_INC), '', fullpath($file));
+ print "\n/* XXXXXXXXX $display XXXXXXXXX */\n";
+ print css_loadfile($file, $location);
+ }
+
+ print NL;
+ if ( $cssData['encapsulate'] === true ) print '} /* /@media ';
+ else print '/*';
+ print ' END '.$cssData['mediatype'].' styles */'.NL;
+ }
+
+ // end output buffering and get contents
+ $css = ob_get_contents();
+ ob_end_clean();
+
+ // strip any source maps
+ stripsourcemaps($css);
+
+ // apply style replacements
+ $css = css_applystyle($css, $styleini['replacements']);
+
+ // parse less
+ $css = css_parseless($css);
+
+ // compress whitespace and comments
+ if($conf['compress']){
+ $css = css_compress($css);
+ }
+
+ // embed small images right into the stylesheet
+ if($conf['cssdatauri']){
+ $base = preg_quote(DOKU_BASE,'#');
+ $css = preg_replace_callback('#(url\([ \'"]*)('.$base.')(.*?(?:\.(png|gif)))#i','css_datauri',$css);
+ }
+
+ http_cached_finish($cache->cache, $css);
+}
+
+/**
+ * Uses phpless to parse LESS in our CSS
+ *
+ * most of this function is error handling to show a nice useful error when
+ * LESS compilation fails
+ *
+ * @param string $css
+ * @return string
+ */
+function css_parseless($css) {
+ global $conf;
+
+ $less = new lessc();
+ $less->importDir = array(DOKU_INC);
+ $less->setPreserveComments(!$conf['compress']);
+
+ if (defined('DOKU_UNITTEST')){
+ $less->importDir[] = TMP_DIR;
+ }
+
+ try {
+ return $less->compile($css);
+ } catch(Exception $e) {
+ // get exception message
+ $msg = str_replace(array("\n", "\r", "'"), array(), $e->getMessage());
+
+ // try to use line number to find affected file
+ if(preg_match('/line: (\d+)$/', $msg, $m)){
+ $msg = substr($msg, 0, -1* strlen($m[0])); //remove useless linenumber
+ $lno = $m[1];
+
+ // walk upwards to last include
+ $lines = explode("\n", $css);
+ for($i=$lno-1; $i>=0; $i--){
+ if(preg_match('/\/(\* XXXXXXXXX )(.*?)( XXXXXXXXX \*)\//', $lines[$i], $m)){
+ // we found it, add info to message
+ $msg .= ' in '.$m[2].' at line '.($lno-$i);
+ break;
+ }
+ }
+ }
+
+ // something went wrong
+ $error = 'A fatal error occured during compilation of the CSS files. '.
+ 'If you recently installed a new plugin or template it '.
+ 'might be broken and you should try disabling it again. ['.$msg.']';
+
+ echo ".dokuwiki:before {
+ content: '$error';
+ background-color: red;
+ display: block;
+ background-color: #fcc;
+ border-color: #ebb;
+ color: #000;
+ padding: 0.5em;
+ }";
+
+ exit;
+ }
+}
+
+/**
+ * Does placeholder replacements in the style according to
+ * the ones defined in a templates style.ini file
+ *
+ * This also adds the ini defined placeholders as less variables
+ * (sans the surrounding __ and with a ini_ prefix)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $css
+ * @param array $replacements array(placeholder => value)
+ * @return string
+ */
+function css_applystyle($css, $replacements) {
+ // we convert ini replacements to LESS variable names
+ // and build a list of variable: value; pairs
+ $less = '';
+ foreach((array) $replacements as $key => $value) {
+ $lkey = trim($key, '_');
+ $lkey = '@ini_'.$lkey;
+ $less .= "$lkey: $value;\n";
+
+ $replacements[$key] = $lkey;
+ }
+
+ // we now replace all old ini replacements with LESS variables
+ $css = strtr($css, $replacements);
+
+ // now prepend the list of LESS variables as the very first thing
+ $css = $less.$css;
+ return $css;
+}
+
+/**
+ * Wrapper for the files, content and mediatype for the event CSS_STYLES_INCLUDED
+ *
+ * @author Gerry Weißbach <gerry.w@gammaproduction.de>
+ *
+ * @param string $mediatype type ofthe current media files/content set
+ * @param array $files set of files that define the current mediatype
+ * @return array
+ */
+function css_filewrapper($mediatype, $files=array()){
+ return array(
+ 'files' => $files,
+ 'mediatype' => $mediatype,
+ 'encapsulate' => $mediatype != 'all',
+ 'encapsulationPrefix' => '@media '.$mediatype
+ );
+}
+
+/**
+ * Prints the @media encapsulated default styles of DokuWiki
+ *
+ * @author Gerry Weißbach <gerry.w@gammaproduction.de>
+ *
+ * This function is being called by a CSS_STYLES_INCLUDED event
+ * The event can be distinguished by the mediatype which is:
+ * DW_DEFAULT
+ */
+function css_defaultstyles(){
+ // print the default classes for interwiki links and file downloads
+ print '@media screen {';
+ css_interwiki();
+ css_filetypes();
+ print '}';
+}
+
+/**
+ * Prints classes for interwikilinks
+ *
+ * Interwiki links have two classes: 'interwiki' and 'iw_$name>' where
+ * $name is the identifier given in the config. All Interwiki links get
+ * an default style with a default icon. If a special icon is available
+ * for an interwiki URL it is set in it's own class. Both classes can be
+ * overwritten in the template or userstyles.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_interwiki(){
+
+ // default style
+ echo 'a.interwiki {';
+ echo ' background: transparent url('.DOKU_BASE.'lib/images/interwiki.png) 0px 1px no-repeat;';
+ echo ' padding: 1px 0px 1px 16px;';
+ echo '}';
+
+ // additional styles when icon available
+ $iwlinks = getInterwiki();
+ foreach(array_keys($iwlinks) as $iw){
+ $class = preg_replace('/[^_\-a-z0-9]+/i','_',$iw);
+ if(file_exists(DOKU_INC.'lib/images/interwiki/'.$iw.'.png')){
+ echo "a.iw_$class {";
+ echo ' background-image: url('.DOKU_BASE.'lib/images/interwiki/'.$iw.'.png)';
+ echo '}';
+ }elseif(file_exists(DOKU_INC.'lib/images/interwiki/'.$iw.'.gif')){
+ echo "a.iw_$class {";
+ echo ' background-image: url('.DOKU_BASE.'lib/images/interwiki/'.$iw.'.gif)';
+ echo '}';
+ }
+ }
+}
+
+/**
+ * Prints classes for file download links
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function css_filetypes(){
+
+ // default style
+ echo '.mediafile {';
+ echo ' background: transparent url('.DOKU_BASE.'lib/images/fileicons/file.png) 0px 1px no-repeat;';
+ echo ' padding-left: 18px;';
+ echo ' padding-bottom: 1px;';
+ echo '}';
+
+ // additional styles when icon available
+ // scan directory for all icons
+ $exts = array();
+ if($dh = opendir(DOKU_INC.'lib/images/fileicons')){
+ while(false !== ($file = readdir($dh))){
+ if(preg_match('/([_\-a-z0-9]+(?:\.[_\-a-z0-9]+)*?)\.(png|gif)/i',$file,$match)){
+ $ext = strtolower($match[1]);
+ $type = '.'.strtolower($match[2]);
+ if($ext!='file' && (!isset($exts[$ext]) || $type=='.png')){
+ $exts[$ext] = $type;
+ }
+ }
+ }
+ closedir($dh);
+ }
+ foreach($exts as $ext=>$type){
+ $class = preg_replace('/[^_\-a-z0-9]+/','_',$ext);
+ echo ".mf_$class {";
+ echo ' background-image: url('.DOKU_BASE.'lib/images/fileicons/'.$ext.$type.')';
+ echo '}';
+ }
+}
+
+/**
+ * Loads a given file and fixes relative URLs with the
+ * given location prefix
+ *
+ * @param string $file file system path
+ * @param string $location
+ * @return string
+ */
+function css_loadfile($file,$location=''){
+ $css_file = new DokuCssFile($file);
+ return $css_file->load($location);
+}
+
+/**
+ * Helper class to abstract loading of css/less files
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+class DokuCssFile {
+
+ protected $filepath; // file system path to the CSS/Less file
+ protected $location; // base url location of the CSS/Less file
+ protected $relative_path = null;
+
+ public function __construct($file) {
+ $this->filepath = $file;
+ }
+
+ /**
+ * Load the contents of the css/less file and adjust any relative paths/urls (relative to this file) to be
+ * relative to the dokuwiki root: the web root (DOKU_BASE) for most files; the file system root (DOKU_INC)
+ * for less files.
+ *
+ * @param string $location base url for this file
+ * @return string the CSS/Less contents of the file
+ */
+ public function load($location='') {
+ if (!file_exists($this->filepath)) return '';
+
+ $css = io_readFile($this->filepath);
+ if (!$location) return $css;
+
+ $this->location = $location;
+
+ $css = preg_replace_callback('#(url\( *)([\'"]?)(.*?)(\2)( *\))#',array($this,'replacements'),$css);
+ $css = preg_replace_callback('#(@import\s+)([\'"])(.*?)(\2)#',array($this,'replacements'),$css);
+
+ return $css;
+ }
+
+ /**
+ * Get the relative file system path of this file, relative to dokuwiki's root folder, DOKU_INC
+ *
+ * @return string relative file system path
+ */
+ protected function getRelativePath(){
+
+ if (is_null($this->relative_path)) {
+ $basedir = array(DOKU_INC);
+
+ // during testing, files may be found relative to a second base dir, TMP_DIR
+ if (defined('DOKU_UNITTEST')) {
+ $basedir[] = realpath(TMP_DIR);
+ }
+
+ $basedir = array_map('preg_quote_cb', $basedir);
+ $regex = '/^('.join('|',$basedir).')/';
+ $this->relative_path = preg_replace($regex, '', dirname($this->filepath));
+ }
+
+ return $this->relative_path;
+ }
+
+ /**
+ * preg_replace callback to adjust relative urls from relative to this file to relative
+ * to the appropriate dokuwiki root location as described in the code
+ *
+ * @param array see http://php.net/preg_replace_callback
+ * @return string see http://php.net/preg_replace_callback
+ */
+ public function replacements($match) {
+
+ if (preg_match('#^(/|data:|https?://)#', $match[3])) { // not a relative url? - no adjustment required
+ return $match[0];
+ } elseif (substr($match[3], -5) == '.less') { // a less file import? - requires a file system location
+ if ($match[3][0] != '/') {
+ $match[3] = $this->getRelativePath() . '/' . $match[3];
+ }
+ } else { // everything else requires a url adjustment
+ $match[3] = $this->location . $match[3];
+ }
+
+ return join('',array_slice($match,1));
+ }
+}
+
+/**
+ * Convert local image URLs to data URLs if the filesize is small
+ *
+ * Callback for preg_replace_callback
+ *
+ * @param array $match
+ * @return string
+ */
+function css_datauri($match){
+ global $conf;
+
+ $pre = unslash($match[1]);
+ $base = unslash($match[2]);
+ $url = unslash($match[3]);
+ $ext = unslash($match[4]);
+
+ $local = DOKU_INC.$url;
+ $size = @filesize($local);
+ if($size && $size < $conf['cssdatauri']){
+ $data = base64_encode(file_get_contents($local));
+ }
+ if (!empty($data)){
+ $url = 'data:image/'.$ext.';base64,'.$data;
+ }else{
+ $url = $base.$url;
+ }
+ return $pre.$url;
+}
+
+
+/**
+ * Returns a list of possible Plugin Styles (no existance check here)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $mediatype
+ * @return array
+ */
+function css_pluginstyles($mediatype='screen'){
+ $list = array();
+ $plugins = plugin_list();
+ foreach ($plugins as $p){
+ $list[DOKU_PLUGIN."$p/$mediatype.css"] = DOKU_BASE."lib/plugins/$p/";
+ $list[DOKU_PLUGIN."$p/$mediatype.less"] = DOKU_BASE."lib/plugins/$p/";
+ // alternative for screen.css
+ if ($mediatype=='screen') {
+ $list[DOKU_PLUGIN."$p/style.css"] = DOKU_BASE."lib/plugins/$p/";
+ $list[DOKU_PLUGIN."$p/style.less"] = DOKU_BASE."lib/plugins/$p/";
+ }
+ }
+ return $list;
+}
+
+/**
+ * Very simple CSS optimizer
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $css
+ * @return string
+ */
+function css_compress($css){
+ // replace quoted strings with placeholder
+ $quote_storage = [];
+
+ $quote_cb = function ($match) use (&$quote_storage) {
+ $quote_storage[] = $match[0];
+ return '"STR'.(count($quote_storage)-1).'"';
+ };
+
+ $css = preg_replace_callback('/(([\'"]).*?(?<!\\\\)\2)/', $quote_cb, $css);
+
+ // strip comments through a callback
+ $css = preg_replace_callback('#(/\*)(.*?)(\*/)#s','css_comment_cb',$css);
+
+ // strip (incorrect but common) one line comments
+ $css = preg_replace_callback('/^.*\/\/.*$/m','css_onelinecomment_cb',$css);
+
+ // strip whitespaces
+ $css = preg_replace('![\r\n\t ]+!',' ',$css);
+ $css = preg_replace('/ ?([;,{}\/]) ?/','\\1',$css);
+ $css = preg_replace('/ ?: /',':',$css);
+
+ // number compression
+ $css = preg_replace(
+ '/([: ])0+(\.\d+?)0*((?:pt|pc|in|mm|cm|em|ex|px)\b|%)(?=[^\{]*[;\}])/',
+ '$1$2$3',
+ $css
+ ); // "0.1em" to ".1em", "1.10em" to "1.1em"
+ $css = preg_replace(
+ '/([: ])\.(0)+((?:pt|pc|in|mm|cm|em|ex|px)\b|%)(?=[^\{]*[;\}])/',
+ '$1$2',
+ $css
+ ); // ".0em" to "0"
+ $css = preg_replace(
+ '/([: ]0)0*(\.0*)?((?:pt|pc|in|mm|cm|em|ex|px)(?=[^\{]*[;\}])\b|%)/',
+ '$1',
+ $css
+ ); // "0.0em" to "0"
+ $css = preg_replace(
+ '/([: ]\d+)(\.0*)((?:pt|pc|in|mm|cm|em|ex|px)(?=[^\{]*[;\}])\b|%)/',
+ '$1$3',
+ $css
+ ); // "1.0em" to "1em"
+ $css = preg_replace(
+ '/([: ])0+(\d+|\d*\.\d+)((?:pt|pc|in|mm|cm|em|ex|px)(?=[^\{]*[;\}])\b|%)/',
+ '$1$2$3',
+ $css
+ ); // "001em" to "1em"
+
+ // shorten attributes (1em 1em 1em 1em -> 1em)
+ $css = preg_replace(
+ '/(?<![\w\-])((?:margin|padding|border|border-(?:width|radius)):)([\w\.]+)( \2)+(?=[;\}]| !)/',
+ '$1$2',
+ $css
+ ); // "1em 1em 1em 1em" to "1em"
+ $css = preg_replace(
+ '/(?<![\w\-])((?:margin|padding|border|border-(?:width)):)([\w\.]+) ([\w\.]+) \2 \3(?=[;\}]| !)/',
+ '$1$2 $3',
+ $css
+ ); // "1em 2em 1em 2em" to "1em 2em"
+
+ // shorten colors
+ $css = preg_replace(
+ "/#([0-9a-fA-F]{1})\\1([0-9a-fA-F]{1})\\2([0-9a-fA-F]{1})\\3(?=[^\{]*[;\}])/",
+ "#\\1\\2\\3",
+ $css
+ );
+
+ // replace back protected strings
+ $quote_back_cb = function ($match) use (&$quote_storage) {
+ return $quote_storage[$match[1]];
+ };
+
+ $css = preg_replace_callback('/"STR(\d+)"/', $quote_back_cb, $css);
+ $css = trim($css);
+
+ return $css;
+}
+
+/**
+ * Callback for css_compress()
+ *
+ * Keeps short comments (< 5 chars) to maintain typical browser hacks
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param array $matches
+ * @return string
+ */
+function css_comment_cb($matches){
+ if(strlen($matches[2]) > 4) return '';
+ return $matches[0];
+}
+
+/**
+ * Callback for css_compress()
+ *
+ * Strips one line comments but makes sure it will not destroy url() constructs with slashes
+ *
+ * @param array $matches
+ * @return string
+ */
+function css_onelinecomment_cb($matches) {
+ $line = $matches[0];
+
+ $i = 0;
+ $len = strlen($line);
+
+ while ($i< $len){
+ $nextcom = strpos($line, '//', $i);
+ $nexturl = stripos($line, 'url(', $i);
+
+ if($nextcom === false) {
+ // no more comments, we're done
+ $i = $len;
+ break;
+ }
+
+ if($nexturl === false || $nextcom < $nexturl) {
+ // no url anymore, strip comment and be done
+ $i = $nextcom;
+ break;
+ }
+
+ // we have an upcoming url
+ $i = strpos($line, ')', $nexturl);
+ }
+
+ return substr($line, 0, $i);
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/exe/detail.php b/platform/www/lib/exe/detail.php
new file mode 100644
index 0000000..a6cffa7
--- /dev/null
+++ b/platform/www/lib/exe/detail.php
@@ -0,0 +1,42 @@
+<?php
+
+use dokuwiki\Extension\Event;
+
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+define('DOKU_MEDIADETAIL',1);
+require_once(DOKU_INC.'inc/init.php');
+
+$IMG = getID('media');
+$ID = cleanID($INPUT->str('id'));
+$REV = $INPUT->int('rev');
+
+// this makes some general info available as well as the info about the
+// "parent" page
+$INFO = array_merge(pageinfo(),mediainfo());
+
+$tmp = array();
+Event::createAndTrigger('DETAIL_STARTED', $tmp);
+
+//close session
+session_write_close();
+
+$ERROR = false;
+// check image permissions
+$AUTH = auth_quickaclcheck($IMG);
+if($AUTH >= AUTH_READ){
+ // check if image exists
+ $SRC = mediaFN($IMG,$REV);
+ if(!file_exists($SRC)){
+ //doesn't exist!
+ http_status(404);
+ $ERROR = 'File not found';
+ }
+}else{
+ // no auth
+ $ERROR = p_locale_xhtml('denied');
+}
+
+//start output and load template
+header('Content-Type: text/html; charset=utf-8');
+include(template('detail.php'));
+
diff --git a/platform/www/lib/exe/fetch.php b/platform/www/lib/exe/fetch.php
new file mode 100644
index 0000000..5026b80
--- /dev/null
+++ b/platform/www/lib/exe/fetch.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * DokuWiki media passthrough file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Extension\Event;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__).'/../../');
+if (!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT', 1);
+require_once(DOKU_INC.'inc/init.php');
+session_write_close(); //close session
+
+require_once(DOKU_INC.'inc/fetch.functions.php');
+
+if (defined('SIMPLE_TEST')) {
+ $INPUT = new \dokuwiki\Input\Input();
+}
+
+// BEGIN main
+ $mimetypes = getMimeTypes();
+
+ //get input
+ $MEDIA = stripctl(getID('media', false)); // no cleaning except control chars - maybe external
+ $CACHE = calc_cache($INPUT->str('cache'));
+ $WIDTH = $INPUT->int('w');
+ $HEIGHT = $INPUT->int('h');
+ $REV = & $INPUT->ref('rev');
+ //sanitize revision
+ $REV = preg_replace('/[^0-9]/', '', $REV);
+
+ list($EXT, $MIME, $DL) = mimetype($MEDIA, false);
+ if($EXT === false) {
+ $EXT = 'unknown';
+ $MIME = 'application/octet-stream';
+ $DL = true;
+ }
+
+ // check for permissions, preconditions and cache external files
+ list($STATUS, $STATUSMESSAGE) = checkFileStatus($MEDIA, $FILE, $REV, $WIDTH, $HEIGHT);
+
+ // prepare data for plugin events
+ $data = array(
+ 'media' => $MEDIA,
+ 'file' => $FILE,
+ 'orig' => $FILE,
+ 'mime' => $MIME,
+ 'download' => $DL,
+ 'cache' => $CACHE,
+ 'ext' => $EXT,
+ 'width' => $WIDTH,
+ 'height' => $HEIGHT,
+ 'status' => $STATUS,
+ 'statusmessage' => $STATUSMESSAGE,
+ 'ispublic' => media_ispublic($MEDIA),
+ );
+
+ // handle the file status
+ $evt = new Event('FETCH_MEDIA_STATUS', $data);
+ if($evt->advise_before()) {
+ // redirects
+ if($data['status'] > 300 && $data['status'] <= 304) {
+ if (defined('SIMPLE_TEST')) return; //TestResponse doesn't recognize redirects
+ send_redirect($data['statusmessage']);
+ }
+ // send any non 200 status
+ if($data['status'] != 200) {
+ http_status($data['status'], $data['statusmessage']);
+ }
+ // die on errors
+ if($data['status'] > 203) {
+ print $data['statusmessage'];
+ if (defined('SIMPLE_TEST')) return;
+ exit;
+ }
+ }
+ $evt->advise_after();
+ unset($evt);
+
+ //handle image resizing/cropping
+ $evt = new Event('MEDIA_RESIZE', $data);
+ if($evt->advise_before()) {
+ if((substr($MIME, 0, 5) == 'image') && ($WIDTH || $HEIGHT)) {
+ if($HEIGHT && $WIDTH) {
+ $data['file'] = $FILE = media_crop_image($data['file'], $EXT, $WIDTH, $HEIGHT);
+ } else {
+ $data['file'] = $FILE = media_resize_image($data['file'], $EXT, $WIDTH, $HEIGHT);
+ }
+ }
+ }
+ $evt->advise_after();
+ unset($evt);
+
+ // finally send the file to the client
+ $evt = new Event('MEDIA_SENDFILE', $data);
+ if($evt->advise_before()) {
+ sendFile($data['file'], $data['mime'], $data['download'], $data['cache'], $data['ispublic'], $data['orig']);
+ }
+ // Do something after the download finished.
+ $evt->advise_after(); // will not be emitted on 304 or x-sendfile
+
+// END DO main
+
+//Setup VIM: ex: et ts=2 :
diff --git a/platform/www/lib/exe/index.html b/platform/www/lib/exe/index.html
new file mode 100644
index 0000000..977f90e
--- /dev/null
+++ b/platform/www/lib/exe/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=../../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/platform/www/lib/exe/indexer.php b/platform/www/lib/exe/indexer.php
new file mode 100644
index 0000000..c5f6e40
--- /dev/null
+++ b/platform/www/lib/exe/indexer.php
@@ -0,0 +1,5 @@
+<?php
+/**
+ * @deprecated 2020-06-04 use taskrunner instead
+ */
+include __DIR__ . '/taskrunner.php';
diff --git a/platform/www/lib/exe/jquery.php b/platform/www/lib/exe/jquery.php
new file mode 100644
index 0000000..b8638ec
--- /dev/null
+++ b/platform/www/lib/exe/jquery.php
@@ -0,0 +1,44 @@
+<?php
+
+use dokuwiki\Cache\Cache;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/../../');
+if(!defined('NOSESSION')) define('NOSESSION', true); // we do not use a session or authentication here (better caching)
+if(!defined('NL')) define('NL', "\n");
+if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT', 1); // we gzip ourself here
+require_once(DOKU_INC . 'inc/init.php');
+
+// MAIN
+header('Content-Type: application/javascript; charset=utf-8');
+jquery_out();
+
+/**
+ * Delivers the jQuery JavaScript
+ *
+ * We do absolutely nothing fancy here but concatenating the different files
+ * and handling conditional and gzipped requests
+ *
+ * uses cache or fills it
+ */
+function jquery_out() {
+ $cache = new Cache('jquery', '.js');
+ $files = array(
+ DOKU_INC . 'lib/scripts/jquery/jquery.min.js',
+ DOKU_INC . 'lib/scripts/jquery/jquery-ui.min.js',
+ );
+ $cache_files = $files;
+ $cache_files[] = __FILE__;
+
+ // check cache age & handle conditional request
+ // This may exit if a cache can be used
+ $cache_ok = $cache->useCache(array('files' => $cache_files));
+ http_cached($cache->cache, $cache_ok);
+
+ $js = '';
+ foreach($files as $file) {
+ $js .= file_get_contents($file)."\n";
+ }
+ stripsourcemaps($js);
+
+ http_cached_finish($cache->cache, $js);
+}
diff --git a/platform/www/lib/exe/js.php b/platform/www/lib/exe/js.php
new file mode 100644
index 0000000..04abec6
--- /dev/null
+++ b/platform/www/lib/exe/js.php
@@ -0,0 +1,490 @@
+<?php
+/**
+ * DokuWiki JavaScript creator
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Cache\Cache;
+use dokuwiki\Extension\Event;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', __DIR__ .'/../../');
+if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
+if(!defined('NL')) define('NL',"\n");
+if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here
+require_once(DOKU_INC.'inc/init.php');
+
+// Main (don't run when UNIT test)
+if(!defined('SIMPLE_TEST')){
+ header('Content-Type: application/javascript; charset=utf-8');
+ js_out();
+}
+
+
+// ---------------------- functions ------------------------------
+
+/**
+ * Output all needed JavaScript
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function js_out(){
+ global $conf;
+ global $lang;
+ global $config_cascade;
+ global $INPUT;
+
+ // decide from where to get the template
+ $tpl = trim(preg_replace('/[^\w-]+/','',$INPUT->str('t')));
+ if(!$tpl) $tpl = $conf['template'];
+
+ // array of core files
+ $files = array(
+ DOKU_INC.'lib/scripts/jquery/jquery.cookie.js',
+ DOKU_INC.'inc/lang/'.$conf['lang'].'/jquery.ui.datepicker.js',
+ DOKU_INC."lib/scripts/fileuploader.js",
+ DOKU_INC."lib/scripts/fileuploaderextended.js",
+ DOKU_INC.'lib/scripts/helpers.js',
+ DOKU_INC.'lib/scripts/delay.js',
+ DOKU_INC.'lib/scripts/cookie.js',
+ DOKU_INC.'lib/scripts/script.js',
+ DOKU_INC.'lib/scripts/qsearch.js',
+ DOKU_INC.'lib/scripts/search.js',
+ DOKU_INC.'lib/scripts/tree.js',
+ DOKU_INC.'lib/scripts/index.js',
+ DOKU_INC.'lib/scripts/textselection.js',
+ DOKU_INC.'lib/scripts/toolbar.js',
+ DOKU_INC.'lib/scripts/edit.js',
+ DOKU_INC.'lib/scripts/editor.js',
+ DOKU_INC.'lib/scripts/locktimer.js',
+ DOKU_INC.'lib/scripts/linkwiz.js',
+ DOKU_INC.'lib/scripts/media.js',
+ DOKU_INC.'lib/scripts/compatibility.js',
+# disabled for FS#1958 DOKU_INC.'lib/scripts/hotkeys.js',
+ DOKU_INC.'lib/scripts/behaviour.js',
+ DOKU_INC.'lib/scripts/page.js',
+ tpl_incdir($tpl).'script.js',
+ );
+
+ // add possible plugin scripts and userscript
+ $files = array_merge($files,js_pluginscripts());
+ if(is_array($config_cascade['userscript']['default'])) {
+ foreach($config_cascade['userscript']['default'] as $userscript) {
+ $files[] = $userscript;
+ }
+ }
+
+ // Let plugins decide to either put more scripts here or to remove some
+ Event::createAndTrigger('JS_SCRIPT_LIST', $files);
+
+ // The generated script depends on some dynamic options
+ $cache = new Cache('scripts'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].md5(serialize($files)),'.js');
+ $cache->setEvent('JS_CACHE_USE');
+
+ $cache_files = array_merge($files, getConfigFiles('main'));
+ $cache_files[] = __FILE__;
+
+ // check cache age & handle conditional request
+ // This may exit if a cache can be used
+ $cache_ok = $cache->useCache(array('files' => $cache_files));
+ http_cached($cache->cache, $cache_ok);
+
+ // start output buffering and build the script
+ ob_start();
+
+ // add some global variables
+ print "var DOKU_BASE = '".DOKU_BASE."';";
+ print "var DOKU_TPL = '".tpl_basedir($tpl)."';";
+ print "var DOKU_COOKIE_PARAM = " . json_encode(
+ array(
+ 'path' => empty($conf['cookiedir']) ? DOKU_REL : $conf['cookiedir'],
+ 'secure' => $conf['securecookie'] && is_ssl()
+ )).";";
+ // FIXME: Move those to JSINFO
+ print "Object.defineProperty(window, 'DOKU_UHN', { get: function() {".
+ "console.warn('Using DOKU_UHN is deprecated. Please use JSINFO.useHeadingNavigation instead');".
+ "return JSINFO.useHeadingNavigation; } });";
+ print "Object.defineProperty(window, 'DOKU_UHC', { get: function() {".
+ "console.warn('Using DOKU_UHC is deprecated. Please use JSINFO.useHeadingContent instead');".
+ "return JSINFO.useHeadingContent; } });";
+
+ // load JS specific translations
+ $lang['js']['plugins'] = js_pluginstrings();
+ $templatestrings = js_templatestrings($tpl);
+ if(!empty($templatestrings)) {
+ $lang['js']['template'] = $templatestrings;
+ }
+ echo 'LANG = '.json_encode($lang['js']).";\n";
+
+ // load toolbar
+ toolbar_JSdefines('toolbar');
+
+ // load files
+ foreach($files as $file){
+ if(!file_exists($file)) continue;
+ $ismin = (substr($file,-7) == '.min.js');
+ $debugjs = ($conf['allowdebug'] && strpos($file, DOKU_INC.'lib/scripts/') !== 0);
+
+ echo "\n\n/* XXXXXXXXXX begin of ".str_replace(DOKU_INC, '', $file) ." XXXXXXXXXX */\n\n";
+ if($ismin) echo "\n/* BEGIN NOCOMPRESS */\n";
+ if ($debugjs) echo "\ntry {\n";
+ js_load($file);
+ if ($debugjs) echo "\n} catch (e) {\n logError(e, '".str_replace(DOKU_INC, '', $file)."');\n}\n";
+ if($ismin) echo "\n/* END NOCOMPRESS */\n";
+ echo "\n\n/* XXXXXXXXXX end of " . str_replace(DOKU_INC, '', $file) . " XXXXXXXXXX */\n\n";
+ }
+
+ // init stuff
+ if($conf['locktime'] != 0){
+ js_runonstart("dw_locktimer.init(".($conf['locktime'] - 60).",".$conf['usedraft'].")");
+ }
+ // init hotkeys - must have been done after init of toolbar
+# disabled for FS#1958 js_runonstart('initializeHotkeys()');
+
+ // end output buffering and get contents
+ $js = ob_get_contents();
+ ob_end_clean();
+
+ // strip any source maps
+ stripsourcemaps($js);
+
+ // compress whitespace and comments
+ if($conf['compress']){
+ $js = js_compress($js);
+ }
+
+ $js .= "\n"; // https://bugzilla.mozilla.org/show_bug.cgi?id=316033
+
+ http_cached_finish($cache->cache, $js);
+}
+
+/**
+ * Load the given file, handle include calls and print it
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $file filename path to file
+ */
+function js_load($file){
+ if(!file_exists($file)) return;
+ static $loaded = array();
+
+ $data = io_readFile($file);
+ while(preg_match('#/\*\s*DOKUWIKI:include(_once)?\s+([\w\.\-_/]+)\s*\*/#',$data,$match)){
+ $ifile = $match[2];
+
+ // is it a include_once?
+ if($match[1]){
+ $base = \dokuwiki\Utf8\PhpString::basename($ifile);
+ if(array_key_exists($base, $loaded) && $loaded[$base] === true){
+ $data = str_replace($match[0], '' ,$data);
+ continue;
+ }
+ $loaded[$base] = true;
+ }
+
+ if($ifile[0] != '/') $ifile = dirname($file).'/'.$ifile;
+
+ if(file_exists($ifile)){
+ $idata = io_readFile($ifile);
+ }else{
+ $idata = '';
+ }
+ $data = str_replace($match[0],$idata,$data);
+ }
+ echo "$data\n";
+}
+
+/**
+ * Returns a list of possible Plugin Scripts (no existance check here)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @return array
+ */
+function js_pluginscripts(){
+ $list = array();
+ $plugins = plugin_list();
+ foreach ($plugins as $p){
+ $list[] = DOKU_PLUGIN."$p/script.js";
+ }
+ return $list;
+}
+
+/**
+ * Return an two-dimensional array with strings from the language file of each plugin.
+ *
+ * - $lang['js'] must be an array.
+ * - Nothing is returned for plugins without an entry for $lang['js']
+ *
+ * @author Gabriel Birke <birke@d-scribe.de>
+ *
+ * @return array
+ */
+function js_pluginstrings() {
+ global $conf, $config_cascade;
+ $pluginstrings = array();
+ $plugins = plugin_list();
+ foreach($plugins as $p) {
+ $path = DOKU_PLUGIN . $p . '/lang/';
+
+ if(isset($lang)) unset($lang);
+ if(file_exists($path . "en/lang.php")) {
+ include $path . "en/lang.php";
+ }
+ foreach($config_cascade['lang']['plugin'] as $config_file) {
+ if(file_exists($config_file . $p . '/en/lang.php')) {
+ include($config_file . $p . '/en/lang.php');
+ }
+ }
+ if(isset($conf['lang']) && $conf['lang'] != 'en') {
+ if(file_exists($path . $conf['lang'] . "/lang.php")) {
+ include($path . $conf['lang'] . '/lang.php');
+ }
+ foreach($config_cascade['lang']['plugin'] as $config_file) {
+ if(file_exists($config_file . $p . '/' . $conf['lang'] . '/lang.php')) {
+ include($config_file . $p . '/' . $conf['lang'] . '/lang.php');
+ }
+ }
+ }
+
+ if(isset($lang['js'])) {
+ $pluginstrings[$p] = $lang['js'];
+ }
+ }
+ return $pluginstrings;
+}
+
+/**
+ * Return an two-dimensional array with strings from the language file of current active template.
+ *
+ * - $lang['js'] must be an array.
+ * - Nothing is returned for template without an entry for $lang['js']
+ *
+ * @param string $tpl
+ * @return array
+ */
+function js_templatestrings($tpl) {
+ global $conf, $config_cascade;
+
+ $path = tpl_incdir() . 'lang/';
+
+ $templatestrings = array();
+ if(file_exists($path . "en/lang.php")) {
+ include $path . "en/lang.php";
+ }
+ foreach($config_cascade['lang']['template'] as $config_file) {
+ if(file_exists($config_file . $conf['template'] . '/en/lang.php')) {
+ include($config_file . $conf['template'] . '/en/lang.php');
+ }
+ }
+ if(isset($conf['lang']) && $conf['lang'] != 'en' && file_exists($path . $conf['lang'] . "/lang.php")) {
+ include $path . $conf['lang'] . "/lang.php";
+ }
+ if(isset($conf['lang']) && $conf['lang'] != 'en') {
+ if(file_exists($path . $conf['lang'] . "/lang.php")) {
+ include $path . $conf['lang'] . "/lang.php";
+ }
+ foreach($config_cascade['lang']['template'] as $config_file) {
+ if(file_exists($config_file . $conf['template'] . '/' . $conf['lang'] . '/lang.php')) {
+ include($config_file . $conf['template'] . '/' . $conf['lang'] . '/lang.php');
+ }
+ }
+ }
+
+ if(isset($lang['js'])) {
+ $templatestrings[$tpl] = $lang['js'];
+ }
+ return $templatestrings;
+}
+
+/**
+ * Escapes a String to be embedded in a JavaScript call, keeps \n
+ * as newline
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $string
+ * @return string
+ */
+function js_escape($string){
+ return str_replace('\\\\n','\\n',addslashes($string));
+}
+
+/**
+ * Adds the given JavaScript code to the window.onload() event
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ *
+ * @param string $func
+ */
+function js_runonstart($func){
+ echo "jQuery(function(){ $func; });".NL;
+}
+
+/**
+ * Strip comments and whitespaces from given JavaScript Code
+ *
+ * This is a port of Nick Galbreath's python tool jsstrip.py which is
+ * released under BSD license. See link for original code.
+ *
+ * @author Nick Galbreath <nickg@modp.com>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @link http://code.google.com/p/jsstrip/
+ *
+ * @param string $s
+ * @return string
+ */
+function js_compress($s){
+ $s = ltrim($s); // strip all initial whitespace
+ $s .= "\n";
+ $i = 0; // char index for input string
+ $j = 0; // char forward index for input string
+ $line = 0; // line number of file (close to it anyways)
+ $slen = strlen($s); // size of input string
+ $lch = ''; // last char added
+ $result = ''; // we store the final result here
+
+ // items that don't need spaces next to them
+ $chars = "^&|!+\-*\/%=\?:;,{}()<>% \t\n\r'\"[]";
+
+ // items which need a space if the sign before and after whitespace is equal.
+ // E.g. '+ ++' may not be compressed to '+++' --> syntax error.
+ $ops = "+-";
+
+ $regex_starters = array("(", "=", "[", "," , ":", "!", "&", "|");
+
+ $whitespaces_chars = array(" ", "\t", "\n", "\r", "\0", "\x0B");
+
+ while($i < $slen){
+ // skip all "boring" characters. This is either
+ // reserved word (e.g. "for", "else", "if") or a
+ // variable/object/method (e.g. "foo.color")
+ while ($i < $slen && (strpos($chars,$s[$i]) === false) ){
+ $result .= $s[$i];
+ $i = $i + 1;
+ }
+
+ $ch = $s[$i];
+ // multiline comments (keeping IE conditionals)
+ if($ch == '/' && $s[$i+1] == '*' && $s[$i+2] != '@'){
+ $endC = strpos($s,'*/',$i+2);
+ if($endC === false) trigger_error('Found invalid /*..*/ comment', E_USER_ERROR);
+
+ // check if this is a NOCOMPRESS comment
+ if(substr($s, $i, $endC+2-$i) == '/* BEGIN NOCOMPRESS */'){
+ $endNC = strpos($s, '/* END NOCOMPRESS */', $endC+2);
+ if($endNC === false) trigger_error('Found invalid NOCOMPRESS comment', E_USER_ERROR);
+
+ // verbatim copy contents, trimming but putting it on its own line
+ $result .= "\n".trim(substr($s, $i + 22, $endNC - ($i + 22)))."\n"; // BEGIN comment = 22 chars
+ $i = $endNC + 20; // END comment = 20 chars
+ }else{
+ $i = $endC + 2;
+ }
+ continue;
+ }
+
+ // singleline
+ if($ch == '/' && $s[$i+1] == '/'){
+ $endC = strpos($s,"\n",$i+2);
+ if($endC === false) trigger_error('Invalid comment', E_USER_ERROR);
+ $i = $endC;
+ continue;
+ }
+
+ // tricky. might be an RE
+ if($ch == '/'){
+ // rewind, skip white space
+ $j = 1;
+ while(in_array($s[$i-$j], $whitespaces_chars)){
+ $j = $j + 1;
+ }
+ if( in_array($s[$i-$j], $regex_starters) ){
+ // yes, this is an re
+ // now move forward and find the end of it
+ $j = 1;
+ while($s[$i+$j] != '/'){
+ if($s[$i+$j] == '\\') $j = $j + 2;
+ else $j++;
+ }
+ $result .= substr($s,$i,$j+1);
+ $i = $i + $j + 1;
+ continue;
+ }
+ }
+
+ // double quote strings
+ if($ch == '"'){
+ $j = 1;
+ while( ($i+$j < $slen) && $s[$i+$j] != '"' ){
+ if( $s[$i+$j] == '\\' && ($s[$i+$j+1] == '"' || $s[$i+$j+1] == '\\') ){
+ $j += 2;
+ }else{
+ $j += 1;
+ }
+ }
+ $string = substr($s,$i,$j+1);
+ // remove multiline markers:
+ $string = str_replace("\\\n",'',$string);
+ $result .= $string;
+ $i = $i + $j + 1;
+ continue;
+ }
+
+ // single quote strings
+ if($ch == "'"){
+ $j = 1;
+ while( ($i+$j < $slen) && $s[$i+$j] != "'" ){
+ if( $s[$i+$j] == '\\' && ($s[$i+$j+1] == "'" || $s[$i+$j+1] == '\\') ){
+ $j += 2;
+ }else{
+ $j += 1;
+ }
+ }
+ $string = substr($s,$i,$j+1);
+ // remove multiline markers:
+ $string = str_replace("\\\n",'',$string);
+ $result .= $string;
+ $i = $i + $j + 1;
+ continue;
+ }
+
+ // whitespaces
+ if( $ch == ' ' || $ch == "\r" || $ch == "\n" || $ch == "\t" ){
+ $lch = substr($result,-1);
+
+ // Only consider deleting whitespace if the signs before and after
+ // are not equal and are not an operator which may not follow itself.
+ if ($i+1 < $slen && ((!$lch || $s[$i+1] == ' ')
+ || $lch != $s[$i+1]
+ || strpos($ops,$s[$i+1]) === false)) {
+ // leading spaces
+ if($i+1 < $slen && (strpos($chars,$s[$i+1]) !== false)){
+ $i = $i + 1;
+ continue;
+ }
+ // trailing spaces
+ // if this ch is space AND the last char processed
+ // is special, then skip the space
+ if($lch && (strpos($chars,$lch) !== false)){
+ $i = $i + 1;
+ continue;
+ }
+ }
+
+ // else after all of this convert the "whitespace" to
+ // a single space. It will get appended below
+ $ch = ' ';
+ }
+
+ // other chars
+ $result .= $ch;
+ $i = $i + 1;
+ }
+
+ return trim($result);
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/exe/manifest.php b/platform/www/lib/exe/manifest.php
new file mode 100644
index 0000000..e9a3528
--- /dev/null
+++ b/platform/www/lib/exe/manifest.php
@@ -0,0 +1,14 @@
+<?php
+
+if (!defined('DOKU_INC')) {
+ define('DOKU_INC', __DIR__ . '/../../');
+}
+require_once(DOKU_INC . 'inc/init.php');
+
+if (!actionOK('manifest')) {
+ http_status(404, 'Manifest has been disabled in DokuWiki configuration.');
+ exit();
+}
+
+$manifest = new \dokuwiki\Manifest();
+$manifest->sendManifest();
diff --git a/platform/www/lib/exe/mediamanager.php b/platform/www/lib/exe/mediamanager.php
new file mode 100644
index 0000000..b43cff7
--- /dev/null
+++ b/platform/www/lib/exe/mediamanager.php
@@ -0,0 +1,129 @@
+<?php
+
+use dokuwiki\Extension\Event;
+
+ if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+ define('DOKU_MEDIAMANAGER',1);
+
+ // for multi uploader:
+ @ini_set('session.use_only_cookies',0);
+
+ require_once(DOKU_INC.'inc/init.php');
+
+ global $INPUT;
+ global $lang;
+ global $conf;
+ // handle passed message
+ if($INPUT->str('msg1')) msg(hsc($INPUT->str('msg1')),1);
+ if($INPUT->str('err')) msg(hsc($INPUT->str('err')),-1);
+
+ global $DEL;
+ // get namespace to display (either direct or from deletion order)
+ if($INPUT->str('delete')){
+ $DEL = cleanID($INPUT->str('delete'));
+ $IMG = $DEL;
+ $NS = getNS($DEL);
+ }elseif($INPUT->str('edit')){
+ $IMG = cleanID($INPUT->str('edit'));
+ $NS = getNS($IMG);
+ }elseif($INPUT->str('img')){
+ $IMG = cleanID($INPUT->str('img'));
+ $NS = getNS($IMG);
+ }else{
+ $NS = cleanID($INPUT->str('ns'));
+ $IMG = null;
+ }
+
+ global $INFO, $JSINFO;
+ $INFO = !empty($INFO) ? array_merge($INFO, mediainfo()) : mediainfo();
+ $JSINFO['id'] = '';
+ $JSINFO['namespace'] = '';
+ $AUTH = $INFO['perm']; // shortcut for historical reasons
+
+ $tmp = array();
+ Event::createAndTrigger('MEDIAMANAGER_STARTED', $tmp);
+ session_write_close(); //close session
+
+ // do not display the manager if user does not have read access
+ if($AUTH < AUTH_READ && !$fullscreen) {
+ http_status(403);
+ die($lang['accessdenied']);
+ }
+
+ // handle flash upload
+ if(isset($_FILES['Filedata'])){
+ $_FILES['upload'] =& $_FILES['Filedata'];
+ $JUMPTO = media_upload($NS,$AUTH);
+ if($JUMPTO == false){
+ http_status(400);
+ echo 'Upload failed';
+ }
+ echo 'ok';
+ exit;
+ }
+
+ // give info on PHP caught upload errors
+ if(!empty($_FILES['upload']['error'])){
+ switch($_FILES['upload']['error']){
+ case 1:
+ case 2:
+ msg(sprintf($lang['uploadsize'],
+ filesize_h(php_to_byte(ini_get('upload_max_filesize')))),-1);
+ break;
+ default:
+ msg($lang['uploadfail'].' ('.$_FILES['upload']['error'].')',-1);
+ }
+ unset($_FILES['upload']);
+ }
+
+ // handle upload
+ if(!empty($_FILES['upload']['tmp_name'])){
+ $JUMPTO = media_upload($NS,$AUTH);
+ if($JUMPTO) $NS = getNS($JUMPTO);
+ }
+
+ // handle meta saving
+ if($IMG && @array_key_exists('save', $INPUT->arr('do'))){
+ $JUMPTO = media_metasave($IMG,$AUTH,$INPUT->arr('meta'));
+ }
+
+ if($IMG && ($INPUT->str('mediado') == 'save' || @array_key_exists('save', $INPUT->arr('mediado')))) {
+ $JUMPTO = media_metasave($IMG,$AUTH,$INPUT->arr('meta'));
+ }
+
+ if ($INPUT->int('rev') && $conf['mediarevisions']) $REV = $INPUT->int('rev');
+
+ if($INPUT->str('mediado') == 'restore' && $conf['mediarevisions']){
+ $JUMPTO = media_restore($INPUT->str('image'), $REV, $AUTH);
+ }
+
+ // handle deletion
+ if($DEL) {
+ $res = 0;
+ if(checkSecurityToken()) {
+ $res = media_delete($DEL,$AUTH);
+ }
+ if ($res & DOKU_MEDIA_DELETED) {
+ $msg = sprintf($lang['deletesucc'], noNS($DEL));
+ if ($res & DOKU_MEDIA_EMPTY_NS && !$fullscreen) {
+ // current namespace was removed. redirecting to root ns passing msg along
+ send_redirect(DOKU_URL.'lib/exe/mediamanager.php?msg1='.
+ rawurlencode($msg).'&edid='.$INPUT->str('edid'));
+ }
+ msg($msg,1);
+ } elseif ($res & DOKU_MEDIA_INUSE) {
+ if(!$conf['refshow']) {
+ msg(sprintf($lang['mediainuse'],noNS($DEL)),0);
+ }
+ } else {
+ msg(sprintf($lang['deletefail'],noNS($DEL)),-1);
+ }
+ }
+ // finished - start output
+
+ if (!$fullscreen) {
+ header('Content-Type: text/html; charset=utf-8');
+ include(template('mediamanager.php'));
+ }
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
diff --git a/platform/www/lib/exe/opensearch.php b/platform/www/lib/exe/opensearch.php
new file mode 100644
index 0000000..b00b2b7
--- /dev/null
+++ b/platform/www/lib/exe/opensearch.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * DokuWiki OpenSearch creator
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @link http://www.opensearch.org/
+ * @author Mike Frysinger <vapier@gentoo.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
+if(!defined('NL')) define('NL',"\n");
+require_once(DOKU_INC.'inc/init.php');
+
+// try to be clever about the favicon location
+if(file_exists(DOKU_INC.'favicon.ico')){
+ $ico = DOKU_URL.'favicon.ico';
+}elseif(file_exists(tpl_incdir().'images/favicon.ico')){
+ $ico = DOKU_URL.'lib/tpl/'.$conf['template'].'/images/favicon.ico';
+}elseif(file_exists(tpl_incdir().'favicon.ico')){
+ $ico = DOKU_URL.'lib/tpl/'.$conf['template'].'/favicon.ico';
+}else{
+ $ico = DOKU_URL.'lib/tpl/dokuwiki/images/favicon.ico';
+}
+
+// output
+header('Content-Type: application/opensearchdescription+xml; charset=utf-8');
+echo '<?xml version="1.0"?>'.NL;
+echo '<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">'.NL;
+echo ' <ShortName>'.hsc($conf['title']).'</ShortName>'.NL;
+echo ' <Image width="16" height="16" type="image/x-icon">'.$ico.'</Image>'.NL;
+echo ' <Url type="text/html" template="'.DOKU_URL.DOKU_SCRIPT.'?do=search&amp;id={searchTerms}" />'.NL;
+echo ' <Url type="application/x-suggestions+json" template="'.
+ DOKU_URL.'lib/exe/ajax.php?call=suggestions&amp;q={searchTerms}" />'.NL;
+echo '</OpenSearchDescription>'.NL;
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/exe/taskrunner.php b/platform/www/lib/exe/taskrunner.php
new file mode 100644
index 0000000..69ab445
--- /dev/null
+++ b/platform/www/lib/exe/taskrunner.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * DokuWiki indexer
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+if (!defined('DOKU_INC')) {
+ define('DOKU_INC', __DIR__ . '/../../');
+}
+define('DOKU_DISABLE_GZIP_OUTPUT',1);
+require_once DOKU_INC.'inc/init.php';
+session_write_close(); //close session
+
+$taskRunner = new \dokuwiki\TaskRunner();
+$taskRunner->run();
diff --git a/platform/www/lib/exe/xmlrpc.php b/platform/www/lib/exe/xmlrpc.php
new file mode 100644
index 0000000..dc0438e
--- /dev/null
+++ b/platform/www/lib/exe/xmlrpc.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * XMLRPC API backend
+ */
+
+use dokuwiki\Remote\XmlRpcServer;
+
+if(!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__).'/../../');
+
+require_once(DOKU_INC.'inc/init.php');
+session_write_close(); //close session
+
+if(!$conf['remote']) die((new IXR_Error(-32605, "XML-RPC server not enabled."))->getXml());
+
+$server = new XmlRpcServer();
diff --git a/platform/www/lib/images/README b/platform/www/lib/images/README
new file mode 100644
index 0000000..e2788b4
--- /dev/null
+++ b/platform/www/lib/images/README
@@ -0,0 +1,6 @@
+
+Icons: email.png, external-link.png, unc.png
+Icon set: Dusseldorf
+Designer: pc.de
+License: Creative Commons Attribution License [http://creativecommons.org/licenses/by/3.0/]
+URL: http://pc.de/icons/#Dusseldorf
diff --git a/platform/www/lib/images/_deprecated.txt b/platform/www/lib/images/_deprecated.txt
new file mode 100644
index 0000000..a347f8b
--- /dev/null
+++ b/platform/www/lib/images/_deprecated.txt
@@ -0,0 +1,2 @@
+
+(none)
diff --git a/platform/www/lib/images/admin/README b/platform/www/lib/images/admin/README
new file mode 100644
index 0000000..53e7d83
--- /dev/null
+++ b/platform/www/lib/images/admin/README
@@ -0,0 +1,4 @@
+These icons were taken from the nuvoX KDE icon theme and are GPL licensed
+See http://www.kde-look.org/content/show.php/nuvoX?content=38467
+
+styling.png from https://openclipart.org/detail/25595/brush Public Domain
diff --git a/platform/www/lib/images/admin/acl.png b/platform/www/lib/images/admin/acl.png
new file mode 100644
index 0000000..542e108
--- /dev/null
+++ b/platform/www/lib/images/admin/acl.png
Binary files differ
diff --git a/platform/www/lib/images/admin/config.png b/platform/www/lib/images/admin/config.png
new file mode 100644
index 0000000..679a673
--- /dev/null
+++ b/platform/www/lib/images/admin/config.png
Binary files differ
diff --git a/platform/www/lib/images/admin/plugin.png b/platform/www/lib/images/admin/plugin.png
new file mode 100644
index 0000000..27bd154
--- /dev/null
+++ b/platform/www/lib/images/admin/plugin.png
Binary files differ
diff --git a/platform/www/lib/images/admin/popularity.png b/platform/www/lib/images/admin/popularity.png
new file mode 100644
index 0000000..e18a8cb
--- /dev/null
+++ b/platform/www/lib/images/admin/popularity.png
Binary files differ
diff --git a/platform/www/lib/images/admin/revert.png b/platform/www/lib/images/admin/revert.png
new file mode 100644
index 0000000..c74c792
--- /dev/null
+++ b/platform/www/lib/images/admin/revert.png
Binary files differ
diff --git a/platform/www/lib/images/admin/styling.png b/platform/www/lib/images/admin/styling.png
new file mode 100644
index 0000000..859c8c9
--- /dev/null
+++ b/platform/www/lib/images/admin/styling.png
Binary files differ
diff --git a/platform/www/lib/images/admin/usermanager.png b/platform/www/lib/images/admin/usermanager.png
new file mode 100644
index 0000000..e6f72e0
--- /dev/null
+++ b/platform/www/lib/images/admin/usermanager.png
Binary files differ
diff --git a/platform/www/lib/images/blank.gif b/platform/www/lib/images/blank.gif
new file mode 100644
index 0000000..9935f82
--- /dev/null
+++ b/platform/www/lib/images/blank.gif
Binary files differ
diff --git a/platform/www/lib/images/bullet.png b/platform/www/lib/images/bullet.png
new file mode 100644
index 0000000..b8ec60c
--- /dev/null
+++ b/platform/www/lib/images/bullet.png
Binary files differ
diff --git a/platform/www/lib/images/closed-rtl.png b/platform/www/lib/images/closed-rtl.png
new file mode 100644
index 0000000..016a3c3
--- /dev/null
+++ b/platform/www/lib/images/closed-rtl.png
Binary files differ
diff --git a/platform/www/lib/images/closed.png b/platform/www/lib/images/closed.png
new file mode 100644
index 0000000..927bfc5
--- /dev/null
+++ b/platform/www/lib/images/closed.png
Binary files differ
diff --git a/platform/www/lib/images/diff.png b/platform/www/lib/images/diff.png
new file mode 100644
index 0000000..04fab07
--- /dev/null
+++ b/platform/www/lib/images/diff.png
Binary files differ
diff --git a/platform/www/lib/images/email.png b/platform/www/lib/images/email.png
new file mode 100644
index 0000000..575b831
--- /dev/null
+++ b/platform/www/lib/images/email.png
Binary files differ
diff --git a/platform/www/lib/images/error.png b/platform/www/lib/images/error.png
new file mode 100644
index 0000000..da06924
--- /dev/null
+++ b/platform/www/lib/images/error.png
Binary files differ
diff --git a/platform/www/lib/images/external-link.png b/platform/www/lib/images/external-link.png
new file mode 100644
index 0000000..fecac61
--- /dev/null
+++ b/platform/www/lib/images/external-link.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/7z.png b/platform/www/lib/images/fileicons/32x32/7z.png
new file mode 100644
index 0000000..2537cb9
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/7z.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/asm.png b/platform/www/lib/images/fileicons/32x32/asm.png
new file mode 100644
index 0000000..17e74d0
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/asm.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/bash.png b/platform/www/lib/images/fileicons/32x32/bash.png
new file mode 100644
index 0000000..a31ee68
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/bash.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/bz2.png b/platform/www/lib/images/fileicons/32x32/bz2.png
new file mode 100644
index 0000000..c780316
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/bz2.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/c.png b/platform/www/lib/images/fileicons/32x32/c.png
new file mode 100644
index 0000000..d8032d0
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/c.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/cc.png b/platform/www/lib/images/fileicons/32x32/cc.png
new file mode 100644
index 0000000..241ebd4
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/cc.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/conf.png b/platform/www/lib/images/fileicons/32x32/conf.png
new file mode 100644
index 0000000..9797c2a
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/conf.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/cpp.png b/platform/www/lib/images/fileicons/32x32/cpp.png
new file mode 100644
index 0000000..1289065
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/cpp.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/cs.png b/platform/www/lib/images/fileicons/32x32/cs.png
new file mode 100644
index 0000000..6c2aae2
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/cs.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/csh.png b/platform/www/lib/images/fileicons/32x32/csh.png
new file mode 100644
index 0000000..e43584c
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/csh.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/css.png b/platform/www/lib/images/fileicons/32x32/css.png
new file mode 100644
index 0000000..786f304
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/css.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/csv.png b/platform/www/lib/images/fileicons/32x32/csv.png
new file mode 100644
index 0000000..e5cdbf9
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/csv.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/deb.png b/platform/www/lib/images/fileicons/32x32/deb.png
new file mode 100644
index 0000000..e2828a3
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/deb.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/diff.png b/platform/www/lib/images/fileicons/32x32/diff.png
new file mode 100644
index 0000000..9e413cb
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/diff.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/doc.png b/platform/www/lib/images/fileicons/32x32/doc.png
new file mode 100644
index 0000000..43ec354
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/doc.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/docx.png b/platform/www/lib/images/fileicons/32x32/docx.png
new file mode 100644
index 0000000..a25f260
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/docx.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/file.png b/platform/www/lib/images/fileicons/32x32/file.png
new file mode 100644
index 0000000..7f6d51a
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/file.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/gif.png b/platform/www/lib/images/fileicons/32x32/gif.png
new file mode 100644
index 0000000..dde2d84
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/gif.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/gz.png b/platform/www/lib/images/fileicons/32x32/gz.png
new file mode 100644
index 0000000..5bddffb
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/gz.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/h.png b/platform/www/lib/images/fileicons/32x32/h.png
new file mode 100644
index 0000000..5c169a3
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/h.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/hpp.png b/platform/www/lib/images/fileicons/32x32/hpp.png
new file mode 100644
index 0000000..128110d
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/hpp.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/htm.png b/platform/www/lib/images/fileicons/32x32/htm.png
new file mode 100644
index 0000000..79096dc
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/htm.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/html.png b/platform/www/lib/images/fileicons/32x32/html.png
new file mode 100644
index 0000000..79096dc
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/html.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/ico.png b/platform/www/lib/images/fileicons/32x32/ico.png
new file mode 100644
index 0000000..60f73bd
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/ico.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/java.png b/platform/www/lib/images/fileicons/32x32/java.png
new file mode 100644
index 0000000..1d86949
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/java.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/jpeg.png b/platform/www/lib/images/fileicons/32x32/jpeg.png
new file mode 100644
index 0000000..4b5c425
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/jpeg.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/jpg.png b/platform/www/lib/images/fileicons/32x32/jpg.png
new file mode 100644
index 0000000..4b5c425
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/jpg.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/js.png b/platform/www/lib/images/fileicons/32x32/js.png
new file mode 100644
index 0000000..5a8dabe
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/js.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/json.png b/platform/www/lib/images/fileicons/32x32/json.png
new file mode 100644
index 0000000..e4a55e6
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/json.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/lua.png b/platform/www/lib/images/fileicons/32x32/lua.png
new file mode 100644
index 0000000..c8e0bf2
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/lua.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/mp3.png b/platform/www/lib/images/fileicons/32x32/mp3.png
new file mode 100644
index 0000000..9bf1695
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/mp3.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/mp4.png b/platform/www/lib/images/fileicons/32x32/mp4.png
new file mode 100644
index 0000000..071abc3
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/mp4.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/odc.png b/platform/www/lib/images/fileicons/32x32/odc.png
new file mode 100644
index 0000000..3ad6a3c
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/odc.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/odf.png b/platform/www/lib/images/fileicons/32x32/odf.png
new file mode 100644
index 0000000..8dd89ea
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/odf.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/odg.png b/platform/www/lib/images/fileicons/32x32/odg.png
new file mode 100644
index 0000000..7020d13
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/odg.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/odi.png b/platform/www/lib/images/fileicons/32x32/odi.png
new file mode 100644
index 0000000..9a08a42
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/odi.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/odp.png b/platform/www/lib/images/fileicons/32x32/odp.png
new file mode 100644
index 0000000..e6b538d
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/odp.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/ods.png b/platform/www/lib/images/fileicons/32x32/ods.png
new file mode 100644
index 0000000..cf4a226
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/ods.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/odt.png b/platform/www/lib/images/fileicons/32x32/odt.png
new file mode 100644
index 0000000..1eae19c
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/odt.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/ogg.png b/platform/www/lib/images/fileicons/32x32/ogg.png
new file mode 100644
index 0000000..d7b0553
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/ogg.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/ogv.png b/platform/www/lib/images/fileicons/32x32/ogv.png
new file mode 100644
index 0000000..4fdedba
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/ogv.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/pas.png b/platform/www/lib/images/fileicons/32x32/pas.png
new file mode 100644
index 0000000..8d2999e
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/pas.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/pdf.png b/platform/www/lib/images/fileicons/32x32/pdf.png
new file mode 100644
index 0000000..09ae62e
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/pdf.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/php.png b/platform/www/lib/images/fileicons/32x32/php.png
new file mode 100644
index 0000000..1f4cabf
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/php.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/pl.png b/platform/www/lib/images/fileicons/32x32/pl.png
new file mode 100644
index 0000000..038e9f3
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/pl.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/png.png b/platform/www/lib/images/fileicons/32x32/png.png
new file mode 100644
index 0000000..e3ea1c3
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/png.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/ppt.png b/platform/www/lib/images/fileicons/32x32/ppt.png
new file mode 100644
index 0000000..acee945
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/ppt.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/pptx.png b/platform/www/lib/images/fileicons/32x32/pptx.png
new file mode 100644
index 0000000..b57b091
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/pptx.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/ps.png b/platform/www/lib/images/fileicons/32x32/ps.png
new file mode 100644
index 0000000..523a0be
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/ps.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/py.png b/platform/www/lib/images/fileicons/32x32/py.png
new file mode 100644
index 0000000..ae6e06a
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/py.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/rar.png b/platform/www/lib/images/fileicons/32x32/rar.png
new file mode 100644
index 0000000..5b1cfcb
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/rar.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/rb.png b/platform/www/lib/images/fileicons/32x32/rb.png
new file mode 100644
index 0000000..398f208
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/rb.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/rpm.png b/platform/www/lib/images/fileicons/32x32/rpm.png
new file mode 100644
index 0000000..c66a907
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/rpm.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/rtf.png b/platform/www/lib/images/fileicons/32x32/rtf.png
new file mode 100644
index 0000000..43182f3
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/rtf.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/sh.png b/platform/www/lib/images/fileicons/32x32/sh.png
new file mode 100644
index 0000000..52e3f95
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/sh.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/sql.png b/platform/www/lib/images/fileicons/32x32/sql.png
new file mode 100644
index 0000000..bb23e56
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/sql.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/svg.png b/platform/www/lib/images/fileicons/32x32/svg.png
new file mode 100644
index 0000000..81a3644
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/svg.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/swf.png b/platform/www/lib/images/fileicons/32x32/swf.png
new file mode 100644
index 0000000..be8f546
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/swf.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/sxc.png b/platform/www/lib/images/fileicons/32x32/sxc.png
new file mode 100644
index 0000000..cc45ffa
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/sxc.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/sxd.png b/platform/www/lib/images/fileicons/32x32/sxd.png
new file mode 100644
index 0000000..26f44c2
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/sxd.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/sxi.png b/platform/www/lib/images/fileicons/32x32/sxi.png
new file mode 100644
index 0000000..62e90bc
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/sxi.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/sxw.png b/platform/www/lib/images/fileicons/32x32/sxw.png
new file mode 100644
index 0000000..5196307
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/sxw.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/tar.png b/platform/www/lib/images/fileicons/32x32/tar.png
new file mode 100644
index 0000000..8eb0ef4
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/tar.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/tgz.png b/platform/www/lib/images/fileicons/32x32/tgz.png
new file mode 100644
index 0000000..77faacb
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/tgz.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/txt.png b/platform/www/lib/images/fileicons/32x32/txt.png
new file mode 100644
index 0000000..5d09e3c
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/txt.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/wav.png b/platform/www/lib/images/fileicons/32x32/wav.png
new file mode 100644
index 0000000..37b871b
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/wav.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/webm.png b/platform/www/lib/images/fileicons/32x32/webm.png
new file mode 100644
index 0000000..9044845
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/webm.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/xls.png b/platform/www/lib/images/fileicons/32x32/xls.png
new file mode 100644
index 0000000..1c21a6e
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/xls.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/xlsx.png b/platform/www/lib/images/fileicons/32x32/xlsx.png
new file mode 100644
index 0000000..cba5937
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/xlsx.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/xml.png b/platform/www/lib/images/fileicons/32x32/xml.png
new file mode 100644
index 0000000..8eee583
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/xml.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/32x32/zip.png b/platform/www/lib/images/fileicons/32x32/zip.png
new file mode 100644
index 0000000..0ce83b6
--- /dev/null
+++ b/platform/www/lib/images/fileicons/32x32/zip.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/7z.png b/platform/www/lib/images/fileicons/7z.png
new file mode 100644
index 0000000..fa6abe3
--- /dev/null
+++ b/platform/www/lib/images/fileicons/7z.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/README b/platform/www/lib/images/fileicons/README
new file mode 100644
index 0000000..0538586
--- /dev/null
+++ b/platform/www/lib/images/fileicons/README
@@ -0,0 +1,2 @@
+For the generator of these files see
+https://github.com/splitbrain/file-icon-generator/blob/master/example-dokuwiki.php
diff --git a/platform/www/lib/images/fileicons/asm.png b/platform/www/lib/images/fileicons/asm.png
new file mode 100644
index 0000000..c22c451
--- /dev/null
+++ b/platform/www/lib/images/fileicons/asm.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/bash.png b/platform/www/lib/images/fileicons/bash.png
new file mode 100644
index 0000000..f352cfd
--- /dev/null
+++ b/platform/www/lib/images/fileicons/bash.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/bz2.png b/platform/www/lib/images/fileicons/bz2.png
new file mode 100644
index 0000000..a1b048f
--- /dev/null
+++ b/platform/www/lib/images/fileicons/bz2.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/c.png b/platform/www/lib/images/fileicons/c.png
new file mode 100644
index 0000000..51d9c7f
--- /dev/null
+++ b/platform/www/lib/images/fileicons/c.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/cc.png b/platform/www/lib/images/fileicons/cc.png
new file mode 100644
index 0000000..8aeae79
--- /dev/null
+++ b/platform/www/lib/images/fileicons/cc.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/conf.png b/platform/www/lib/images/fileicons/conf.png
new file mode 100644
index 0000000..c845d49
--- /dev/null
+++ b/platform/www/lib/images/fileicons/conf.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/cpp.png b/platform/www/lib/images/fileicons/cpp.png
new file mode 100644
index 0000000..1a04c32
--- /dev/null
+++ b/platform/www/lib/images/fileicons/cpp.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/cs.png b/platform/www/lib/images/fileicons/cs.png
new file mode 100644
index 0000000..740725a
--- /dev/null
+++ b/platform/www/lib/images/fileicons/cs.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/csh.png b/platform/www/lib/images/fileicons/csh.png
new file mode 100644
index 0000000..c0131c5
--- /dev/null
+++ b/platform/www/lib/images/fileicons/csh.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/css.png b/platform/www/lib/images/fileicons/css.png
new file mode 100644
index 0000000..89ac364
--- /dev/null
+++ b/platform/www/lib/images/fileicons/css.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/csv.png b/platform/www/lib/images/fileicons/csv.png
new file mode 100644
index 0000000..837ae29
--- /dev/null
+++ b/platform/www/lib/images/fileicons/csv.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/deb.png b/platform/www/lib/images/fileicons/deb.png
new file mode 100644
index 0000000..1db6fa5
--- /dev/null
+++ b/platform/www/lib/images/fileicons/deb.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/diff.png b/platform/www/lib/images/fileicons/diff.png
new file mode 100644
index 0000000..03e9af9
--- /dev/null
+++ b/platform/www/lib/images/fileicons/diff.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/doc.png b/platform/www/lib/images/fileicons/doc.png
new file mode 100644
index 0000000..dcc070f
--- /dev/null
+++ b/platform/www/lib/images/fileicons/doc.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/docx.png b/platform/www/lib/images/fileicons/docx.png
new file mode 100644
index 0000000..1a98a8d
--- /dev/null
+++ b/platform/www/lib/images/fileicons/docx.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/file.png b/platform/www/lib/images/fileicons/file.png
new file mode 100644
index 0000000..54fe8ab
--- /dev/null
+++ b/platform/www/lib/images/fileicons/file.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/gif.png b/platform/www/lib/images/fileicons/gif.png
new file mode 100644
index 0000000..38bdbf2
--- /dev/null
+++ b/platform/www/lib/images/fileicons/gif.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/gz.png b/platform/www/lib/images/fileicons/gz.png
new file mode 100644
index 0000000..422693a
--- /dev/null
+++ b/platform/www/lib/images/fileicons/gz.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/h.png b/platform/www/lib/images/fileicons/h.png
new file mode 100644
index 0000000..d65f2f5
--- /dev/null
+++ b/platform/www/lib/images/fileicons/h.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/hpp.png b/platform/www/lib/images/fileicons/hpp.png
new file mode 100644
index 0000000..6d314f5
--- /dev/null
+++ b/platform/www/lib/images/fileicons/hpp.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/htm.png b/platform/www/lib/images/fileicons/htm.png
new file mode 100644
index 0000000..f45847f
--- /dev/null
+++ b/platform/www/lib/images/fileicons/htm.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/html.png b/platform/www/lib/images/fileicons/html.png
new file mode 100644
index 0000000..f45847f
--- /dev/null
+++ b/platform/www/lib/images/fileicons/html.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/ico.png b/platform/www/lib/images/fileicons/ico.png
new file mode 100644
index 0000000..38aa34b
--- /dev/null
+++ b/platform/www/lib/images/fileicons/ico.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/index.php b/platform/www/lib/images/fileicons/index.php
new file mode 100644
index 0000000..d1f233e
--- /dev/null
+++ b/platform/www/lib/images/fileicons/index.php
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html lang="en" dir="ltr">
+<head>
+ <title>Filetype icons</title>
+
+ <style>
+ body {
+ background-color: #ccc;
+ font-family: Arial;
+ }
+
+ .box {
+ width: 200px;
+ float: left;
+ padding: 0.5em;
+ margin: 0;
+ }
+
+ .white {
+ background-color: #fff;
+ }
+
+ .black {
+ background-color: #000;
+ }
+ </style>
+
+</head>
+<body>
+
+<?php
+$fi_list = ''; $fi_list32 = '';
+foreach (glob('*.png') as $img) {
+ $fi_list .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
+}
+foreach (glob('32x32/*.png') as $img) {
+ $fi_list32 .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
+}
+echo '<div class="white box">
+'.$fi_list.'
+</div>
+
+<div class="black box">
+'.$fi_list.'
+</div>
+
+<br style="clear: left" />
+
+<div class="white box">
+'.$fi_list32.'
+</div>
+
+<div class="black box">
+'.$fi_list32;
+?>
+</div>
+
+</body>
+</html>
diff --git a/platform/www/lib/images/fileicons/java.png b/platform/www/lib/images/fileicons/java.png
new file mode 100644
index 0000000..0c62347
--- /dev/null
+++ b/platform/www/lib/images/fileicons/java.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/jpeg.png b/platform/www/lib/images/fileicons/jpeg.png
new file mode 100644
index 0000000..e446dd4
--- /dev/null
+++ b/platform/www/lib/images/fileicons/jpeg.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/jpg.png b/platform/www/lib/images/fileicons/jpg.png
new file mode 100644
index 0000000..e446dd4
--- /dev/null
+++ b/platform/www/lib/images/fileicons/jpg.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/js.png b/platform/www/lib/images/fileicons/js.png
new file mode 100644
index 0000000..bee428f
--- /dev/null
+++ b/platform/www/lib/images/fileicons/js.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/json.png b/platform/www/lib/images/fileicons/json.png
new file mode 100644
index 0000000..4d0a3cf
--- /dev/null
+++ b/platform/www/lib/images/fileicons/json.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/lua.png b/platform/www/lib/images/fileicons/lua.png
new file mode 100644
index 0000000..fcebe3d
--- /dev/null
+++ b/platform/www/lib/images/fileicons/lua.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/mp3.png b/platform/www/lib/images/fileicons/mp3.png
new file mode 100644
index 0000000..2be976f
--- /dev/null
+++ b/platform/www/lib/images/fileicons/mp3.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/mp4.png b/platform/www/lib/images/fileicons/mp4.png
new file mode 100644
index 0000000..dc6fd00
--- /dev/null
+++ b/platform/www/lib/images/fileicons/mp4.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/odc.png b/platform/www/lib/images/fileicons/odc.png
new file mode 100644
index 0000000..bf3b3a1
--- /dev/null
+++ b/platform/www/lib/images/fileicons/odc.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/odf.png b/platform/www/lib/images/fileicons/odf.png
new file mode 100644
index 0000000..fcfc58f
--- /dev/null
+++ b/platform/www/lib/images/fileicons/odf.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/odg.png b/platform/www/lib/images/fileicons/odg.png
new file mode 100644
index 0000000..0a8196c
--- /dev/null
+++ b/platform/www/lib/images/fileicons/odg.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/odi.png b/platform/www/lib/images/fileicons/odi.png
new file mode 100644
index 0000000..0fc8508
--- /dev/null
+++ b/platform/www/lib/images/fileicons/odi.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/odp.png b/platform/www/lib/images/fileicons/odp.png
new file mode 100644
index 0000000..75b1db8
--- /dev/null
+++ b/platform/www/lib/images/fileicons/odp.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/ods.png b/platform/www/lib/images/fileicons/ods.png
new file mode 100644
index 0000000..2017426
--- /dev/null
+++ b/platform/www/lib/images/fileicons/ods.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/odt.png b/platform/www/lib/images/fileicons/odt.png
new file mode 100644
index 0000000..6f8fae4
--- /dev/null
+++ b/platform/www/lib/images/fileicons/odt.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/ogg.png b/platform/www/lib/images/fileicons/ogg.png
new file mode 100644
index 0000000..8bb5080
--- /dev/null
+++ b/platform/www/lib/images/fileicons/ogg.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/ogv.png b/platform/www/lib/images/fileicons/ogv.png
new file mode 100644
index 0000000..e6b65ac
--- /dev/null
+++ b/platform/www/lib/images/fileicons/ogv.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/pas.png b/platform/www/lib/images/fileicons/pas.png
new file mode 100644
index 0000000..19f0a3c
--- /dev/null
+++ b/platform/www/lib/images/fileicons/pas.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/pdf.png b/platform/www/lib/images/fileicons/pdf.png
new file mode 100644
index 0000000..42fbfd2
--- /dev/null
+++ b/platform/www/lib/images/fileicons/pdf.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/php.png b/platform/www/lib/images/fileicons/php.png
new file mode 100644
index 0000000..de0d8ee
--- /dev/null
+++ b/platform/www/lib/images/fileicons/php.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/pl.png b/platform/www/lib/images/fileicons/pl.png
new file mode 100644
index 0000000..d95513d
--- /dev/null
+++ b/platform/www/lib/images/fileicons/pl.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/png.png b/platform/www/lib/images/fileicons/png.png
new file mode 100644
index 0000000..273476d
--- /dev/null
+++ b/platform/www/lib/images/fileicons/png.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/ppt.png b/platform/www/lib/images/fileicons/ppt.png
new file mode 100644
index 0000000..a03d3c0
--- /dev/null
+++ b/platform/www/lib/images/fileicons/ppt.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/pptx.png b/platform/www/lib/images/fileicons/pptx.png
new file mode 100644
index 0000000..9b5c633
--- /dev/null
+++ b/platform/www/lib/images/fileicons/pptx.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/ps.png b/platform/www/lib/images/fileicons/ps.png
new file mode 100644
index 0000000..3b7848c
--- /dev/null
+++ b/platform/www/lib/images/fileicons/ps.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/py.png b/platform/www/lib/images/fileicons/py.png
new file mode 100644
index 0000000..893019e
--- /dev/null
+++ b/platform/www/lib/images/fileicons/py.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/rar.png b/platform/www/lib/images/fileicons/rar.png
new file mode 100644
index 0000000..091a635
--- /dev/null
+++ b/platform/www/lib/images/fileicons/rar.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/rb.png b/platform/www/lib/images/fileicons/rb.png
new file mode 100644
index 0000000..9b58db0
--- /dev/null
+++ b/platform/www/lib/images/fileicons/rb.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/rpm.png b/platform/www/lib/images/fileicons/rpm.png
new file mode 100644
index 0000000..75da50e
--- /dev/null
+++ b/platform/www/lib/images/fileicons/rpm.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/rtf.png b/platform/www/lib/images/fileicons/rtf.png
new file mode 100644
index 0000000..2e5a6e5
--- /dev/null
+++ b/platform/www/lib/images/fileicons/rtf.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/sh.png b/platform/www/lib/images/fileicons/sh.png
new file mode 100644
index 0000000..bc48354
--- /dev/null
+++ b/platform/www/lib/images/fileicons/sh.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/sql.png b/platform/www/lib/images/fileicons/sql.png
new file mode 100644
index 0000000..c36f3a8
--- /dev/null
+++ b/platform/www/lib/images/fileicons/sql.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/svg.png b/platform/www/lib/images/fileicons/svg.png
new file mode 100644
index 0000000..a52132d
--- /dev/null
+++ b/platform/www/lib/images/fileicons/svg.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/swf.png b/platform/www/lib/images/fileicons/swf.png
new file mode 100644
index 0000000..5c88387
--- /dev/null
+++ b/platform/www/lib/images/fileicons/swf.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/sxc.png b/platform/www/lib/images/fileicons/sxc.png
new file mode 100644
index 0000000..3b5c71f
--- /dev/null
+++ b/platform/www/lib/images/fileicons/sxc.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/sxd.png b/platform/www/lib/images/fileicons/sxd.png
new file mode 100644
index 0000000..15390cd
--- /dev/null
+++ b/platform/www/lib/images/fileicons/sxd.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/sxi.png b/platform/www/lib/images/fileicons/sxi.png
new file mode 100644
index 0000000..a0fb654
--- /dev/null
+++ b/platform/www/lib/images/fileicons/sxi.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/sxw.png b/platform/www/lib/images/fileicons/sxw.png
new file mode 100644
index 0000000..865dc0c
--- /dev/null
+++ b/platform/www/lib/images/fileicons/sxw.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/tar.png b/platform/www/lib/images/fileicons/tar.png
new file mode 100644
index 0000000..8f9fd0f
--- /dev/null
+++ b/platform/www/lib/images/fileicons/tar.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/tgz.png b/platform/www/lib/images/fileicons/tgz.png
new file mode 100644
index 0000000..8423ef0
--- /dev/null
+++ b/platform/www/lib/images/fileicons/tgz.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/txt.png b/platform/www/lib/images/fileicons/txt.png
new file mode 100644
index 0000000..1619cc4
--- /dev/null
+++ b/platform/www/lib/images/fileicons/txt.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/wav.png b/platform/www/lib/images/fileicons/wav.png
new file mode 100644
index 0000000..80eac97
--- /dev/null
+++ b/platform/www/lib/images/fileicons/wav.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/webm.png b/platform/www/lib/images/fileicons/webm.png
new file mode 100644
index 0000000..cec3e6d
--- /dev/null
+++ b/platform/www/lib/images/fileicons/webm.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/xls.png b/platform/www/lib/images/fileicons/xls.png
new file mode 100644
index 0000000..be9b42f
--- /dev/null
+++ b/platform/www/lib/images/fileicons/xls.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/xlsx.png b/platform/www/lib/images/fileicons/xlsx.png
new file mode 100644
index 0000000..fd5d4f1
--- /dev/null
+++ b/platform/www/lib/images/fileicons/xlsx.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/xml.png b/platform/www/lib/images/fileicons/xml.png
new file mode 100644
index 0000000..2a96d8b
--- /dev/null
+++ b/platform/www/lib/images/fileicons/xml.png
Binary files differ
diff --git a/platform/www/lib/images/fileicons/zip.png b/platform/www/lib/images/fileicons/zip.png
new file mode 100644
index 0000000..4ce08bf
--- /dev/null
+++ b/platform/www/lib/images/fileicons/zip.png
Binary files differ
diff --git a/platform/www/lib/images/history.png b/platform/www/lib/images/history.png
new file mode 100644
index 0000000..f6af0f6
--- /dev/null
+++ b/platform/www/lib/images/history.png
Binary files differ
diff --git a/platform/www/lib/images/icon-list.png b/platform/www/lib/images/icon-list.png
new file mode 100644
index 0000000..4ae738a
--- /dev/null
+++ b/platform/www/lib/images/icon-list.png
Binary files differ
diff --git a/platform/www/lib/images/icon-sort.png b/platform/www/lib/images/icon-sort.png
new file mode 100644
index 0000000..190397e
--- /dev/null
+++ b/platform/www/lib/images/icon-sort.png
Binary files differ
diff --git a/platform/www/lib/images/index.html b/platform/www/lib/images/index.html
new file mode 100644
index 0000000..977f90e
--- /dev/null
+++ b/platform/www/lib/images/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=../../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/platform/www/lib/images/info.png b/platform/www/lib/images/info.png
new file mode 100644
index 0000000..5e23364
--- /dev/null
+++ b/platform/www/lib/images/info.png
Binary files differ
diff --git a/platform/www/lib/images/interwiki.png b/platform/www/lib/images/interwiki.png
new file mode 100644
index 0000000..10a2bbe
--- /dev/null
+++ b/platform/www/lib/images/interwiki.png
Binary files differ
diff --git a/platform/www/lib/images/interwiki/amazon.de.gif b/platform/www/lib/images/interwiki/amazon.de.gif
new file mode 100644
index 0000000..a0d2cd4
--- /dev/null
+++ b/platform/www/lib/images/interwiki/amazon.de.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/amazon.gif b/platform/www/lib/images/interwiki/amazon.gif
new file mode 100644
index 0000000..a0d2cd4
--- /dev/null
+++ b/platform/www/lib/images/interwiki/amazon.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/amazon.uk.gif b/platform/www/lib/images/interwiki/amazon.uk.gif
new file mode 100644
index 0000000..a0d2cd4
--- /dev/null
+++ b/platform/www/lib/images/interwiki/amazon.uk.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/callto.gif b/platform/www/lib/images/interwiki/callto.gif
new file mode 100644
index 0000000..60158c5
--- /dev/null
+++ b/platform/www/lib/images/interwiki/callto.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/doku.gif b/platform/www/lib/images/interwiki/doku.gif
new file mode 100644
index 0000000..3ccf012
--- /dev/null
+++ b/platform/www/lib/images/interwiki/doku.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/google.gif b/platform/www/lib/images/interwiki/google.gif
new file mode 100644
index 0000000..3a28437
--- /dev/null
+++ b/platform/www/lib/images/interwiki/google.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/paypal.gif b/platform/www/lib/images/interwiki/paypal.gif
new file mode 100644
index 0000000..633797f
--- /dev/null
+++ b/platform/www/lib/images/interwiki/paypal.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/phpfn.gif b/platform/www/lib/images/interwiki/phpfn.gif
new file mode 100644
index 0000000..89ac1db
--- /dev/null
+++ b/platform/www/lib/images/interwiki/phpfn.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/skype.gif b/platform/www/lib/images/interwiki/skype.gif
new file mode 100644
index 0000000..d9bd575
--- /dev/null
+++ b/platform/www/lib/images/interwiki/skype.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/tel.gif b/platform/www/lib/images/interwiki/tel.gif
new file mode 100644
index 0000000..60158c5
--- /dev/null
+++ b/platform/www/lib/images/interwiki/tel.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/user.png b/platform/www/lib/images/interwiki/user.png
new file mode 100644
index 0000000..da84e3d
--- /dev/null
+++ b/platform/www/lib/images/interwiki/user.png
Binary files differ
diff --git a/platform/www/lib/images/interwiki/wp.gif b/platform/www/lib/images/interwiki/wp.gif
new file mode 100644
index 0000000..b07fd89
--- /dev/null
+++ b/platform/www/lib/images/interwiki/wp.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/wpde.gif b/platform/www/lib/images/interwiki/wpde.gif
new file mode 100644
index 0000000..b07fd89
--- /dev/null
+++ b/platform/www/lib/images/interwiki/wpde.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/wpes.gif b/platform/www/lib/images/interwiki/wpes.gif
new file mode 100644
index 0000000..b07fd89
--- /dev/null
+++ b/platform/www/lib/images/interwiki/wpes.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/wpfr.gif b/platform/www/lib/images/interwiki/wpfr.gif
new file mode 100644
index 0000000..b07fd89
--- /dev/null
+++ b/platform/www/lib/images/interwiki/wpfr.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/wpjp.gif b/platform/www/lib/images/interwiki/wpjp.gif
new file mode 100644
index 0000000..b07fd89
--- /dev/null
+++ b/platform/www/lib/images/interwiki/wpjp.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/wpmeta.gif b/platform/www/lib/images/interwiki/wpmeta.gif
new file mode 100644
index 0000000..b07fd89
--- /dev/null
+++ b/platform/www/lib/images/interwiki/wpmeta.gif
Binary files differ
diff --git a/platform/www/lib/images/interwiki/wppl.gif b/platform/www/lib/images/interwiki/wppl.gif
new file mode 100644
index 0000000..b07fd89
--- /dev/null
+++ b/platform/www/lib/images/interwiki/wppl.gif
Binary files differ
diff --git a/platform/www/lib/images/larger.gif b/platform/www/lib/images/larger.gif
new file mode 100644
index 0000000..e137c92
--- /dev/null
+++ b/platform/www/lib/images/larger.gif
Binary files differ
diff --git a/platform/www/lib/images/license/badge/cc-by-nc-nd.png b/platform/www/lib/images/license/badge/cc-by-nc-nd.png
new file mode 100644
index 0000000..c84aff1
--- /dev/null
+++ b/platform/www/lib/images/license/badge/cc-by-nc-nd.png
Binary files differ
diff --git a/platform/www/lib/images/license/badge/cc-by-nc-sa.png b/platform/www/lib/images/license/badge/cc-by-nc-sa.png
new file mode 100644
index 0000000..e7b5784
--- /dev/null
+++ b/platform/www/lib/images/license/badge/cc-by-nc-sa.png
Binary files differ
diff --git a/platform/www/lib/images/license/badge/cc-by-nc.png b/platform/www/lib/images/license/badge/cc-by-nc.png
new file mode 100644
index 0000000..b422cdc
--- /dev/null
+++ b/platform/www/lib/images/license/badge/cc-by-nc.png
Binary files differ
diff --git a/platform/www/lib/images/license/badge/cc-by-nd.png b/platform/www/lib/images/license/badge/cc-by-nd.png
new file mode 100644
index 0000000..1832299
--- /dev/null
+++ b/platform/www/lib/images/license/badge/cc-by-nd.png
Binary files differ
diff --git a/platform/www/lib/images/license/badge/cc-by-sa.png b/platform/www/lib/images/license/badge/cc-by-sa.png
new file mode 100644
index 0000000..5749f65
--- /dev/null
+++ b/platform/www/lib/images/license/badge/cc-by-sa.png
Binary files differ
diff --git a/platform/www/lib/images/license/badge/cc-by.png b/platform/www/lib/images/license/badge/cc-by.png
new file mode 100644
index 0000000..700679a
--- /dev/null
+++ b/platform/www/lib/images/license/badge/cc-by.png
Binary files differ
diff --git a/platform/www/lib/images/license/badge/cc-zero.png b/platform/www/lib/images/license/badge/cc-zero.png
new file mode 100644
index 0000000..e6d82bf
--- /dev/null
+++ b/platform/www/lib/images/license/badge/cc-zero.png
Binary files differ
diff --git a/platform/www/lib/images/license/badge/cc.png b/platform/www/lib/images/license/badge/cc.png
new file mode 100644
index 0000000..e28f32c
--- /dev/null
+++ b/platform/www/lib/images/license/badge/cc.png
Binary files differ
diff --git a/platform/www/lib/images/license/badge/gnufdl.png b/platform/www/lib/images/license/badge/gnufdl.png
new file mode 100644
index 0000000..635de2b
--- /dev/null
+++ b/platform/www/lib/images/license/badge/gnufdl.png
Binary files differ
diff --git a/platform/www/lib/images/license/badge/publicdomain.png b/platform/www/lib/images/license/badge/publicdomain.png
new file mode 100644
index 0000000..fd742cc
--- /dev/null
+++ b/platform/www/lib/images/license/badge/publicdomain.png
Binary files differ
diff --git a/platform/www/lib/images/license/button/cc-by-nc-nd.png b/platform/www/lib/images/license/button/cc-by-nc-nd.png
new file mode 100644
index 0000000..994025f
--- /dev/null
+++ b/platform/www/lib/images/license/button/cc-by-nc-nd.png
Binary files differ
diff --git a/platform/www/lib/images/license/button/cc-by-nc-sa.png b/platform/www/lib/images/license/button/cc-by-nc-sa.png
new file mode 100644
index 0000000..3b896bd
--- /dev/null
+++ b/platform/www/lib/images/license/button/cc-by-nc-sa.png
Binary files differ
diff --git a/platform/www/lib/images/license/button/cc-by-nc.png b/platform/www/lib/images/license/button/cc-by-nc.png
new file mode 100644
index 0000000..d5be8f8
--- /dev/null
+++ b/platform/www/lib/images/license/button/cc-by-nc.png
Binary files differ
diff --git a/platform/www/lib/images/license/button/cc-by-nd.png b/platform/www/lib/images/license/button/cc-by-nd.png
new file mode 100644
index 0000000..e1918b0
--- /dev/null
+++ b/platform/www/lib/images/license/button/cc-by-nd.png
Binary files differ
diff --git a/platform/www/lib/images/license/button/cc-by-sa.png b/platform/www/lib/images/license/button/cc-by-sa.png
new file mode 100644
index 0000000..9b9b522
--- /dev/null
+++ b/platform/www/lib/images/license/button/cc-by-sa.png
Binary files differ
diff --git a/platform/www/lib/images/license/button/cc-by.png b/platform/www/lib/images/license/button/cc-by.png
new file mode 100644
index 0000000..53b1dea
--- /dev/null
+++ b/platform/www/lib/images/license/button/cc-by.png
Binary files differ
diff --git a/platform/www/lib/images/license/button/cc-zero.png b/platform/www/lib/images/license/button/cc-zero.png
new file mode 100644
index 0000000..e6a1a5b
--- /dev/null
+++ b/platform/www/lib/images/license/button/cc-zero.png
Binary files differ
diff --git a/platform/www/lib/images/license/button/cc.png b/platform/www/lib/images/license/button/cc.png
new file mode 100644
index 0000000..e04958a
--- /dev/null
+++ b/platform/www/lib/images/license/button/cc.png
Binary files differ
diff --git a/platform/www/lib/images/license/button/gnufdl.png b/platform/www/lib/images/license/button/gnufdl.png
new file mode 100644
index 0000000..b0e0793
--- /dev/null
+++ b/platform/www/lib/images/license/button/gnufdl.png
Binary files differ
diff --git a/platform/www/lib/images/license/button/publicdomain.png b/platform/www/lib/images/license/button/publicdomain.png
new file mode 100644
index 0000000..b301baf
--- /dev/null
+++ b/platform/www/lib/images/license/button/publicdomain.png
Binary files differ
diff --git a/platform/www/lib/images/magnifier.png b/platform/www/lib/images/magnifier.png
new file mode 100644
index 0000000..014fa92
--- /dev/null
+++ b/platform/www/lib/images/magnifier.png
Binary files differ
diff --git a/platform/www/lib/images/media_align_center.png b/platform/www/lib/images/media_align_center.png
new file mode 100644
index 0000000..8b30a05
--- /dev/null
+++ b/platform/www/lib/images/media_align_center.png
Binary files differ
diff --git a/platform/www/lib/images/media_align_left.png b/platform/www/lib/images/media_align_left.png
new file mode 100644
index 0000000..d32bbc2
--- /dev/null
+++ b/platform/www/lib/images/media_align_left.png
Binary files differ
diff --git a/platform/www/lib/images/media_align_noalign.png b/platform/www/lib/images/media_align_noalign.png
new file mode 100644
index 0000000..e6ce857
--- /dev/null
+++ b/platform/www/lib/images/media_align_noalign.png
Binary files differ
diff --git a/platform/www/lib/images/media_align_right.png b/platform/www/lib/images/media_align_right.png
new file mode 100644
index 0000000..32a5cb0
--- /dev/null
+++ b/platform/www/lib/images/media_align_right.png
Binary files differ
diff --git a/platform/www/lib/images/media_link_direct.png b/platform/www/lib/images/media_link_direct.png
new file mode 100644
index 0000000..13d24ad
--- /dev/null
+++ b/platform/www/lib/images/media_link_direct.png
Binary files differ
diff --git a/platform/www/lib/images/media_link_displaylnk.png b/platform/www/lib/images/media_link_displaylnk.png
new file mode 100644
index 0000000..102834e
--- /dev/null
+++ b/platform/www/lib/images/media_link_displaylnk.png
Binary files differ
diff --git a/platform/www/lib/images/media_link_lnk.png b/platform/www/lib/images/media_link_lnk.png
new file mode 100644
index 0000000..5db14ad
--- /dev/null
+++ b/platform/www/lib/images/media_link_lnk.png
Binary files differ
diff --git a/platform/www/lib/images/media_link_nolnk.png b/platform/www/lib/images/media_link_nolnk.png
new file mode 100644
index 0000000..d277ac9
--- /dev/null
+++ b/platform/www/lib/images/media_link_nolnk.png
Binary files differ
diff --git a/platform/www/lib/images/media_size_large.png b/platform/www/lib/images/media_size_large.png
new file mode 100644
index 0000000..c4f745e
--- /dev/null
+++ b/platform/www/lib/images/media_size_large.png
Binary files differ
diff --git a/platform/www/lib/images/media_size_medium.png b/platform/www/lib/images/media_size_medium.png
new file mode 100644
index 0000000..580c63e
--- /dev/null
+++ b/platform/www/lib/images/media_size_medium.png
Binary files differ
diff --git a/platform/www/lib/images/media_size_original.png b/platform/www/lib/images/media_size_original.png
new file mode 100644
index 0000000..60d1925
--- /dev/null
+++ b/platform/www/lib/images/media_size_original.png
Binary files differ
diff --git a/platform/www/lib/images/media_size_small.png b/platform/www/lib/images/media_size_small.png
new file mode 100644
index 0000000..8d5a629
--- /dev/null
+++ b/platform/www/lib/images/media_size_small.png
Binary files differ
diff --git a/platform/www/lib/images/mediamanager.png b/platform/www/lib/images/mediamanager.png
new file mode 100644
index 0000000..5093381
--- /dev/null
+++ b/platform/www/lib/images/mediamanager.png
Binary files differ
diff --git a/platform/www/lib/images/menu/00-default_checkbox-blank-circle-outline.svg b/platform/www/lib/images/menu/00-default_checkbox-blank-circle-outline.svg
new file mode 100644
index 0000000..e8f8c07
--- /dev/null
+++ b/platform/www/lib/images/menu/00-default_checkbox-blank-circle-outline.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 20a8 8 0 0 1-8-8 8 8 0 0 1 8-8 8 8 0 0 1 8 8 8 8 0 0 1-8 8m0-18A10 10 0 0 0 2 12a10 10 0 0 0 10 10 10 10 0 0 0 10-10A10 10 0 0 0 12 2z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/01-edit_pencil.svg b/platform/www/lib/images/menu/01-edit_pencil.svg
new file mode 100644
index 0000000..e3a4faa
--- /dev/null
+++ b/platform/www/lib/images/menu/01-edit_pencil.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75L3 17.25z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/02-create_pencil.svg b/platform/www/lib/images/menu/02-create_pencil.svg
new file mode 100644
index 0000000..4c30b49
--- /dev/null
+++ b/platform/www/lib/images/menu/02-create_pencil.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" height="24" width="24"><path d="M13.118 16.118h3v-3h2v3h3v2h-3v3h-2v-3h-3zM20.71 7.04c.39-.39.39-1.04 0-1.41l-2.34-2.34c-.37-.39-1.02-.39-1.41 0l-1.84 1.83 3.75 3.75M3 17.25V21h3.75L17.81 9.93l-3.75-3.75z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/03-draft_android-studio.svg b/platform/www/lib/images/menu/03-draft_android-studio.svg
new file mode 100644
index 0000000..589658d
--- /dev/null
+++ b/platform/www/lib/images/menu/03-draft_android-studio.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M11 2h2v2h.5A1.5 1.5 0 0 1 15 5.5V9l-.44.44 1.64 2.84C17.31 11.19 18 9.68 18 8h2c0 2.42-1.07 4.59-2.77 6.06l3.14 5.44.13 2.22-1.87-1.22-3.07-5.33c-1.06.53-2.28.83-3.56.83-1.28 0-2.5-.3-3.56-.83L5.37 20.5 3.5 21.72l.13-2.22L9.44 9.44 9 9V5.5A1.5 1.5 0 0 1 10.5 4h.5V2M9.44 13.43c.78.37 1.65.57 2.56.57.91 0 1.78-.2 2.56-.57L13.1 10.9h-.01c-.62.6-1.56.6-2.18 0h-.01l-1.46 2.53M12 6a1 1 0 0 0-1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0-1-1z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/04-show_file-document.svg b/platform/www/lib/images/menu/04-show_file-document.svg
new file mode 100644
index 0000000..0eed274
--- /dev/null
+++ b/platform/www/lib/images/menu/04-show_file-document.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m9 16v-2H6v2h9m3-4v-2H6v2h12z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/05-source_file-xml.svg b/platform/www/lib/images/menu/05-source_file-xml.svg
new file mode 100644
index 0000000..7e00342
--- /dev/null
+++ b/platform/www/lib/images/menu/05-source_file-xml.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M13 9h5.5L13 3.5V9M6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m.12 13.5l3.74 3.74 1.42-1.41-2.33-2.33 2.33-2.33-1.42-1.41-3.74 3.74m11.16 0l-3.74-3.74-1.42 1.41 2.33 2.33-2.33 2.33 1.42 1.41 3.74-3.74z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/06-revert_replay.svg b/platform/www/lib/images/menu/06-revert_replay.svg
new file mode 100644
index 0000000..0911e5b
--- /dev/null
+++ b/platform/www/lib/images/menu/06-revert_replay.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 5V1L7 6l5 5V7a6 6 0 0 1 6 6 6 6 0 0 1-6 6 6 6 0 0 1-6-6H4a8 8 0 0 0 8 8 8 8 0 0 0 8-8 8 8 0 0 0-8-8z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/07-revisions_history.svg b/platform/www/lib/images/menu/07-revisions_history.svg
new file mode 100644
index 0000000..cedbc1b
--- /dev/null
+++ b/platform/www/lib/images/menu/07-revisions_history.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M11 7v5.11l4.71 2.79.79-1.28-4-2.37V7m0-5C8.97 2 5.91 3.92 4.27 6.77L2 4.5V11h6.5L5.75 8.25C6.96 5.73 9.5 4 12.5 4a7.5 7.5 0 0 1 7.5 7.5 7.5 7.5 0 0 1-7.5 7.5c-3.27 0-6.03-2.09-7.06-5h-2.1c1.1 4.03 4.77 7 9.16 7 5.24 0 9.5-4.25 9.5-9.5A9.5 9.5 0 0 0 12.5 2z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/08-backlink_link-variant.svg b/platform/www/lib/images/menu/08-backlink_link-variant.svg
new file mode 100644
index 0000000..4d639a5
--- /dev/null
+++ b/platform/www/lib/images/menu/08-backlink_link-variant.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10.59 13.41c.41.39.41 1.03 0 1.42-.39.39-1.03.39-1.42 0a5.003 5.003 0 0 1 0-7.07l3.54-3.54a5.003 5.003 0 0 1 7.07 0 5.003 5.003 0 0 1 0 7.07l-1.49 1.49c.01-.82-.12-1.64-.4-2.42l.47-.48a2.982 2.982 0 0 0 0-4.24 2.982 2.982 0 0 0-4.24 0l-3.53 3.53a2.982 2.982 0 0 0 0 4.24m2.82-4.24c.39-.39 1.03-.39 1.42 0a5.003 5.003 0 0 1 0 7.07l-3.54 3.54a5.003 5.003 0 0 1-7.07 0 5.003 5.003 0 0 1 0-7.07l1.49-1.49c-.01.82.12 1.64.4 2.43l-.47.47a2.982 2.982 0 0 0 0 4.24 2.982 2.982 0 0 0 4.24 0l3.53-3.53a2.982 2.982 0 0 0 0-4.24.973.973 0 0 1 0-1.42z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/09-subscribe_email-outline.svg b/platform/www/lib/images/menu/09-subscribe_email-outline.svg
new file mode 100644
index 0000000..3b23dac
--- /dev/null
+++ b/platform/www/lib/images/menu/09-subscribe_email-outline.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2m0 14H4V8l8 5 8-5v10m0-12l-8 5-8-5h16z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/10-top_arrow-up.svg b/platform/www/lib/images/menu/10-top_arrow-up.svg
new file mode 100644
index 0000000..61003a8
--- /dev/null
+++ b/platform/www/lib/images/menu/10-top_arrow-up.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/11-mediamanager_folder-image.svg b/platform/www/lib/images/menu/11-mediamanager_folder-image.svg
new file mode 100644
index 0000000..4376fdf
--- /dev/null
+++ b/platform/www/lib/images/menu/11-mediamanager_folder-image.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M5 17l4.5-6 3.5 4.5 2.5-3L19 17m1-11h-8l-2-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/12-back_arrow-left.svg b/platform/www/lib/images/menu/12-back_arrow-left.svg
new file mode 100644
index 0000000..d8011b1
--- /dev/null
+++ b/platform/www/lib/images/menu/12-back_arrow-left.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/account-card-details.svg b/platform/www/lib/images/menu/account-card-details.svg
new file mode 100644
index 0000000..ba74256
--- /dev/null
+++ b/platform/www/lib/images/menu/account-card-details.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M2 3h20c1.05 0 2 .95 2 2v14c0 1.05-.95 2-2 2H2c-1.05 0-2-.95-2-2V5c0-1.05.95-2 2-2m12 3v1h8V6h-8m0 2v1h8V8h-8m0 2v1h7v-1h-7m-6 3.91C6 13.91 2 15 2 17v1h12v-1c0-2-4-3.09-6-3.09M8 6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/account-plus.svg b/platform/www/lib/images/menu/account-plus.svg
new file mode 100644
index 0000000..a978bf1
--- /dev/null
+++ b/platform/www/lib/images/menu/account-plus.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15 14c-2.67 0-8 1.33-8 4v2h16v-2c0-2.67-5.33-4-8-4m-9-4V7H4v3H1v2h3v3h2v-3h3v-2m6 2a4 4 0 0 0 4-4 4 4 0 0 0-4-4 4 4 0 0 0-4 4 4 4 0 0 0 4 4z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/calendar-clock.svg b/platform/www/lib/images/menu/calendar-clock.svg
new file mode 100644
index 0000000..b19735d
--- /dev/null
+++ b/platform/www/lib/images/menu/calendar-clock.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M15 13h1.5v2.82l2.44 1.41-.75 1.3L15 16.69V13m4-5H5v11h4.67c-.43-.91-.67-1.93-.67-3a7 7 0 0 1 7-7c1.07 0 2.09.24 3 .67V8M5 21a2 2 0 0 1-2-2V5c0-1.11.89-2 2-2h1V1h2v2h8V1h2v2h1a2 2 0 0 1 2 2v6.1c1.24 1.26 2 2.99 2 4.9a7 7 0 0 1-7 7c-1.91 0-3.64-.76-4.9-2H5m11-9.85A4.85 4.85 0 0 0 11.15 16c0 2.68 2.17 4.85 4.85 4.85A4.85 4.85 0 0 0 20.85 16c0-2.68-2.17-4.85-4.85-4.85z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/file-tree.svg b/platform/www/lib/images/menu/file-tree.svg
new file mode 100644
index 0000000..0f26188
--- /dev/null
+++ b/platform/www/lib/images/menu/file-tree.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M3 3h6v4H3V3m12 7h6v4h-6v-4m0 7h6v4h-6v-4m-2-4H7v5h6v2H5V9h2v2h6v2z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/folder-multiple-image.svg b/platform/www/lib/images/menu/folder-multiple-image.svg
new file mode 100644
index 0000000..f66aaad
--- /dev/null
+++ b/platform/www/lib/images/menu/folder-multiple-image.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M7 15l4.5-6 3.5 4.5 2.5-3L21 15m1-11h-8l-2-2H6a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2M2 6H0v14a2 2 0 0 0 2 2h18v-2H2V6z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/lock-reset.svg b/platform/www/lib/images/menu/lock-reset.svg
new file mode 100644
index 0000000..49693c6
--- /dev/null
+++ b/platform/www/lib/images/menu/lock-reset.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12.63 2c5.53 0 10.01 4.5 10.01 10s-4.48 10-10.01 10c-3.51 0-6.58-1.82-8.37-4.57l1.58-1.25C7.25 18.47 9.76 20 12.64 20a8 8 0 0 0 8-8 8 8 0 0 0-8-8C8.56 4 5.2 7.06 4.71 11h2.76l-3.74 3.73L0 11h2.69c.5-5.05 4.76-9 9.94-9m2.96 8.24c.5.01.91.41.91.92v4.61c0 .5-.41.92-.92.92h-5.53c-.51 0-.92-.42-.92-.92v-4.61c0-.51.41-.91.91-.92V9.23c0-1.53 1.25-2.77 2.77-2.77 1.53 0 2.78 1.24 2.78 2.77v1.01m-2.78-2.38c-.75 0-1.37.61-1.37 1.37v1.01h2.75V9.23c0-.76-.62-1.37-1.38-1.37z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/login.svg b/platform/www/lib/images/menu/login.svg
new file mode 100644
index 0000000..07a9896
--- /dev/null
+++ b/platform/www/lib/images/menu/login.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 17.25V14H3v-4h7V6.75L15.25 12 10 17.25M8 2h9a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2v-4h2v4h9V4H8v4H6V4a2 2 0 0 1 2-2z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/logout.svg b/platform/www/lib/images/menu/logout.svg
new file mode 100644
index 0000000..97d3158
--- /dev/null
+++ b/platform/www/lib/images/menu/logout.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M17 17.25V14h-7v-4h7V6.75L22.25 12 17 17.25M13 2a2 2 0 0 1 2 2v4h-2V4H4v16h9v-4h2v4a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/menu/settings.svg b/platform/www/lib/images/menu/settings.svg
new file mode 100644
index 0000000..ced9871
--- /dev/null
+++ b/platform/www/lib/images/menu/settings.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 15.5A3.5 3.5 0 0 1 8.5 12 3.5 3.5 0 0 1 12 8.5a3.5 3.5 0 0 1 3.5 3.5 3.5 3.5 0 0 1-3.5 3.5m7.43-2.53c.04-.32.07-.64.07-.97 0-.33-.03-.66-.07-1l2.11-1.63c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.31-.61-.22l-2.49 1c-.52-.39-1.06-.73-1.69-.98l-.37-2.65A.506.506 0 0 0 14 2h-4c-.25 0-.46.18-.5.42l-.37 2.65c-.63.25-1.17.59-1.69.98l-2.49-1c-.22-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64L4.57 11c-.04.34-.07.67-.07 1 0 .33.03.65.07.97l-2.11 1.66c-.19.15-.25.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1.01c.52.4 1.06.74 1.69.99l.37 2.65c.04.24.25.42.5.42h4c.25 0 .46-.18.5-.42l.37-2.65c.63-.26 1.17-.59 1.69-.99l2.49 1.01c.22.08.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.66z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/images/minus.gif b/platform/www/lib/images/minus.gif
new file mode 100644
index 0000000..7e8cbd7
--- /dev/null
+++ b/platform/www/lib/images/minus.gif
Binary files differ
diff --git a/platform/www/lib/images/notify.png b/platform/www/lib/images/notify.png
new file mode 100644
index 0000000..f6c56ee
--- /dev/null
+++ b/platform/www/lib/images/notify.png
Binary files differ
diff --git a/platform/www/lib/images/ns.png b/platform/www/lib/images/ns.png
new file mode 100644
index 0000000..77e03b1
--- /dev/null
+++ b/platform/www/lib/images/ns.png
Binary files differ
diff --git a/platform/www/lib/images/open.png b/platform/www/lib/images/open.png
new file mode 100644
index 0000000..b9e4fdf
--- /dev/null
+++ b/platform/www/lib/images/open.png
Binary files differ
diff --git a/platform/www/lib/images/page.png b/platform/www/lib/images/page.png
new file mode 100644
index 0000000..b1b7ebe
--- /dev/null
+++ b/platform/www/lib/images/page.png
Binary files differ
diff --git a/platform/www/lib/images/plus.gif b/platform/www/lib/images/plus.gif
new file mode 100644
index 0000000..3da3b94
--- /dev/null
+++ b/platform/www/lib/images/plus.gif
Binary files differ
diff --git a/platform/www/lib/images/resizecol.png b/platform/www/lib/images/resizecol.png
new file mode 100644
index 0000000..91ad7d1
--- /dev/null
+++ b/platform/www/lib/images/resizecol.png
Binary files differ
diff --git a/platform/www/lib/images/smaller.gif b/platform/www/lib/images/smaller.gif
new file mode 100644
index 0000000..66d3a51
--- /dev/null
+++ b/platform/www/lib/images/smaller.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/delete.gif b/platform/www/lib/images/smileys/delete.gif
new file mode 100644
index 0000000..e94c68c
--- /dev/null
+++ b/platform/www/lib/images/smileys/delete.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/facepalm.gif b/platform/www/lib/images/smileys/facepalm.gif
new file mode 100644
index 0000000..5bebb20
--- /dev/null
+++ b/platform/www/lib/images/smileys/facepalm.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/fixme.gif b/platform/www/lib/images/smileys/fixme.gif
new file mode 100644
index 0000000..e191413
--- /dev/null
+++ b/platform/www/lib/images/smileys/fixme.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_arrow.gif b/platform/www/lib/images/smileys/icon_arrow.gif
new file mode 100644
index 0000000..6771def
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_arrow.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_biggrin.gif b/platform/www/lib/images/smileys/icon_biggrin.gif
new file mode 100644
index 0000000..aa29c14
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_biggrin.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_confused.gif b/platform/www/lib/images/smileys/icon_confused.gif
new file mode 100644
index 0000000..0ea9ed2
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_confused.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_cool.gif b/platform/www/lib/images/smileys/icon_cool.gif
new file mode 100644
index 0000000..3469ad4
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_cool.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_cry.gif b/platform/www/lib/images/smileys/icon_cry.gif
new file mode 100644
index 0000000..25aea57
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_cry.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_doubt.gif b/platform/www/lib/images/smileys/icon_doubt.gif
new file mode 100644
index 0000000..b4afc6d
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_doubt.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_doubt2.gif b/platform/www/lib/images/smileys/icon_doubt2.gif
new file mode 100644
index 0000000..1f57eb9
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_doubt2.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_eek.gif b/platform/www/lib/images/smileys/icon_eek.gif
new file mode 100644
index 0000000..276b01d
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_eek.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_evil.gif b/platform/www/lib/images/smileys/icon_evil.gif
new file mode 100644
index 0000000..d756916
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_evil.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_exclaim.gif b/platform/www/lib/images/smileys/icon_exclaim.gif
new file mode 100644
index 0000000..215b32e
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_exclaim.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_frown.gif b/platform/www/lib/images/smileys/icon_frown.gif
new file mode 100644
index 0000000..d46caf7
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_frown.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_fun.gif b/platform/www/lib/images/smileys/icon_fun.gif
new file mode 100644
index 0000000..6d3c442
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_fun.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_idea.gif b/platform/www/lib/images/smileys/icon_idea.gif
new file mode 100644
index 0000000..41eaa06
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_idea.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_kaddi.gif b/platform/www/lib/images/smileys/icon_kaddi.gif
new file mode 100644
index 0000000..56344bb
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_kaddi.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_lol.gif b/platform/www/lib/images/smileys/icon_lol.gif
new file mode 100644
index 0000000..d1c20c0
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_lol.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_mrgreen.gif b/platform/www/lib/images/smileys/icon_mrgreen.gif
new file mode 100644
index 0000000..fc5d916
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_mrgreen.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_neutral.gif b/platform/www/lib/images/smileys/icon_neutral.gif
new file mode 100644
index 0000000..c82a974
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_neutral.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_question.gif b/platform/www/lib/images/smileys/icon_question.gif
new file mode 100644
index 0000000..4e30924
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_question.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_razz.gif b/platform/www/lib/images/smileys/icon_razz.gif
new file mode 100644
index 0000000..310655e
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_razz.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_redface.gif b/platform/www/lib/images/smileys/icon_redface.gif
new file mode 100644
index 0000000..160c20f
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_redface.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_rolleyes.gif b/platform/www/lib/images/smileys/icon_rolleyes.gif
new file mode 100644
index 0000000..502c5c1
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_rolleyes.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_sad.gif b/platform/www/lib/images/smileys/icon_sad.gif
new file mode 100644
index 0000000..d46caf7
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_sad.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_silenced.gif b/platform/www/lib/images/smileys/icon_silenced.gif
new file mode 100644
index 0000000..5f722e0
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_silenced.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_smile.gif b/platform/www/lib/images/smileys/icon_smile.gif
new file mode 100644
index 0000000..df125e2
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_smile.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_smile2.gif b/platform/www/lib/images/smileys/icon_smile2.gif
new file mode 100644
index 0000000..6b4909c
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_smile2.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_surprised.gif b/platform/www/lib/images/smileys/icon_surprised.gif
new file mode 100644
index 0000000..aaa94f1
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_surprised.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_twisted.gif b/platform/www/lib/images/smileys/icon_twisted.gif
new file mode 100644
index 0000000..eaec193
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_twisted.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/icon_wink.gif b/platform/www/lib/images/smileys/icon_wink.gif
new file mode 100644
index 0000000..78b6ad3
--- /dev/null
+++ b/platform/www/lib/images/smileys/icon_wink.gif
Binary files differ
diff --git a/platform/www/lib/images/smileys/index.php b/platform/www/lib/images/smileys/index.php
new file mode 100644
index 0000000..5749666
--- /dev/null
+++ b/platform/www/lib/images/smileys/index.php
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html lang="en" dir="ltr">
+<head>
+ <title>Smileys</title>
+
+ <style>
+ body {
+ background-color: #ccc;
+ font-family: Arial;
+ }
+
+ .box {
+ width: 200px;
+ float: left;
+ padding: 0.5em;
+ margin: 0;
+ }
+
+ .white {
+ background-color: #fff;
+ }
+
+ .black {
+ background-color: #000;
+ }
+ </style>
+
+</head>
+<body>
+
+<?php
+$smi_list = '';
+foreach (glob('*.gif') as $img) {
+ $smi_list .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
+}
+if(is_dir('local')) {
+ $smi_list .= '<hr />';
+ foreach (glob('local/*.gif') as $img) {
+ $smi_list .= '<img src="'.$img.'" alt="'.$img.'" title="'.$img.'" /> ';
+ }
+}
+
+echo '<div class="white box">
+'.$smi_list.'
+</div>
+
+<div class="black box">
+'.$smi_list;
+?>
+</div>
+
+</body>
+</html>
diff --git a/platform/www/lib/images/success.png b/platform/www/lib/images/success.png
new file mode 100644
index 0000000..200142f
--- /dev/null
+++ b/platform/www/lib/images/success.png
Binary files differ
diff --git a/platform/www/lib/images/throbber.gif b/platform/www/lib/images/throbber.gif
new file mode 100644
index 0000000..27178a8
--- /dev/null
+++ b/platform/www/lib/images/throbber.gif
Binary files differ
diff --git a/platform/www/lib/images/toolbar/bold.png b/platform/www/lib/images/toolbar/bold.png
new file mode 100644
index 0000000..8f425e9
--- /dev/null
+++ b/platform/www/lib/images/toolbar/bold.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/chars.png b/platform/www/lib/images/toolbar/chars.png
new file mode 100644
index 0000000..a906bc8
--- /dev/null
+++ b/platform/www/lib/images/toolbar/chars.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/h.png b/platform/www/lib/images/toolbar/h.png
new file mode 100644
index 0000000..7e43d64
--- /dev/null
+++ b/platform/www/lib/images/toolbar/h.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/h1.png b/platform/www/lib/images/toolbar/h1.png
new file mode 100644
index 0000000..9f1970f
--- /dev/null
+++ b/platform/www/lib/images/toolbar/h1.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/h2.png b/platform/www/lib/images/toolbar/h2.png
new file mode 100644
index 0000000..adec9ec
--- /dev/null
+++ b/platform/www/lib/images/toolbar/h2.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/h3.png b/platform/www/lib/images/toolbar/h3.png
new file mode 100644
index 0000000..a758b89
--- /dev/null
+++ b/platform/www/lib/images/toolbar/h3.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/h4.png b/platform/www/lib/images/toolbar/h4.png
new file mode 100644
index 0000000..9cd6061
--- /dev/null
+++ b/platform/www/lib/images/toolbar/h4.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/h5.png b/platform/www/lib/images/toolbar/h5.png
new file mode 100644
index 0000000..86b7259
--- /dev/null
+++ b/platform/www/lib/images/toolbar/h5.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/hequal.png b/platform/www/lib/images/toolbar/hequal.png
new file mode 100644
index 0000000..869a2dd
--- /dev/null
+++ b/platform/www/lib/images/toolbar/hequal.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/hminus.png b/platform/www/lib/images/toolbar/hminus.png
new file mode 100644
index 0000000..1a99ee4
--- /dev/null
+++ b/platform/www/lib/images/toolbar/hminus.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/hplus.png b/platform/www/lib/images/toolbar/hplus.png
new file mode 100644
index 0000000..92efcdb
--- /dev/null
+++ b/platform/www/lib/images/toolbar/hplus.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/hr.png b/platform/www/lib/images/toolbar/hr.png
new file mode 100644
index 0000000..40ae210
--- /dev/null
+++ b/platform/www/lib/images/toolbar/hr.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/image.png b/platform/www/lib/images/toolbar/image.png
new file mode 100644
index 0000000..5cc7afa
--- /dev/null
+++ b/platform/www/lib/images/toolbar/image.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/italic.png b/platform/www/lib/images/toolbar/italic.png
new file mode 100644
index 0000000..b37dc2d
--- /dev/null
+++ b/platform/www/lib/images/toolbar/italic.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/link.png b/platform/www/lib/images/toolbar/link.png
new file mode 100644
index 0000000..3d2180a
--- /dev/null
+++ b/platform/www/lib/images/toolbar/link.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/linkextern.png b/platform/www/lib/images/toolbar/linkextern.png
new file mode 100644
index 0000000..e854572
--- /dev/null
+++ b/platform/www/lib/images/toolbar/linkextern.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/mono.png b/platform/www/lib/images/toolbar/mono.png
new file mode 100644
index 0000000..a6f56d6
--- /dev/null
+++ b/platform/www/lib/images/toolbar/mono.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/ol.png b/platform/www/lib/images/toolbar/ol.png
new file mode 100644
index 0000000..c12229a
--- /dev/null
+++ b/platform/www/lib/images/toolbar/ol.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/sig.png b/platform/www/lib/images/toolbar/sig.png
new file mode 100644
index 0000000..72fdad0
--- /dev/null
+++ b/platform/www/lib/images/toolbar/sig.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/smiley.png b/platform/www/lib/images/toolbar/smiley.png
new file mode 100644
index 0000000..54f1e6f
--- /dev/null
+++ b/platform/www/lib/images/toolbar/smiley.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/strike.png b/platform/www/lib/images/toolbar/strike.png
new file mode 100644
index 0000000..5adbba4
--- /dev/null
+++ b/platform/www/lib/images/toolbar/strike.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/ul.png b/platform/www/lib/images/toolbar/ul.png
new file mode 100644
index 0000000..39e5d34
--- /dev/null
+++ b/platform/www/lib/images/toolbar/ul.png
Binary files differ
diff --git a/platform/www/lib/images/toolbar/underline.png b/platform/www/lib/images/toolbar/underline.png
new file mode 100644
index 0000000..57bf3e2
--- /dev/null
+++ b/platform/www/lib/images/toolbar/underline.png
Binary files differ
diff --git a/platform/www/lib/images/trash.png b/platform/www/lib/images/trash.png
new file mode 100644
index 0000000..350c5e1
--- /dev/null
+++ b/platform/www/lib/images/trash.png
Binary files differ
diff --git a/platform/www/lib/images/unc.png b/platform/www/lib/images/unc.png
new file mode 100644
index 0000000..145b728
--- /dev/null
+++ b/platform/www/lib/images/unc.png
Binary files differ
diff --git a/platform/www/lib/images/up.png b/platform/www/lib/images/up.png
new file mode 100644
index 0000000..dbacf3f
--- /dev/null
+++ b/platform/www/lib/images/up.png
Binary files differ
diff --git a/platform/www/lib/images/wrap.gif b/platform/www/lib/images/wrap.gif
new file mode 100644
index 0000000..f2253e4
--- /dev/null
+++ b/platform/www/lib/images/wrap.gif
Binary files differ
diff --git a/platform/www/lib/index.html b/platform/www/lib/index.html
new file mode 100644
index 0000000..885c954
--- /dev/null
+++ b/platform/www/lib/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/platform/www/lib/plugins/acl/action.php b/platform/www/lib/plugins/acl/action.php
new file mode 100644
index 0000000..86e5870
--- /dev/null
+++ b/platform/www/lib/plugins/acl/action.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * AJAX call handler for ACL plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+/**
+ * Register handler
+ */
+class action_plugin_acl extends DokuWiki_Action_Plugin
+{
+
+ /**
+ * Registers a callback function for a given event
+ *
+ * @param Doku_Event_Handler $controller DokuWiki's event controller object
+ * @return void
+ */
+ public function register(Doku_Event_Handler $controller)
+ {
+
+ $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handleAjaxCallAcl');
+ }
+
+ /**
+ * AJAX call handler for ACL plugin
+ *
+ * @param Doku_Event $event event object by reference
+ * @param mixed $param empty
+ * @return void
+ */
+ public function handleAjaxCallAcl(Doku_Event $event, $param)
+ {
+ if ($event->data !== 'plugin_acl') {
+ return;
+ }
+ $event->stopPropagation();
+ $event->preventDefault();
+
+ global $ID;
+ global $INPUT;
+
+ /** @var $acl admin_plugin_acl */
+ $acl = plugin_load('admin', 'acl');
+ if (!$acl->isAccessibleByCurrentUser()) {
+ echo 'for admins only';
+ return;
+ }
+ if (!checkSecurityToken()) {
+ echo 'CRSF Attack';
+ return;
+ }
+
+ $ID = getID();
+ $acl->handle();
+
+ $ajax = $INPUT->str('ajax');
+ header('Content-Type: text/html; charset=utf-8');
+
+ if ($ajax == 'info') {
+ $acl->printInfo();
+ } elseif ($ajax == 'tree') {
+ $ns = $INPUT->str('ns');
+ if ($ns == '*') {
+ $ns = '';
+ }
+ $ns = cleanID($ns);
+ $lvl = count(explode(':', $ns));
+ $ns = utf8_encodeFN(str_replace(':', '/', $ns));
+
+ $data = $acl->makeTree($ns, $ns);
+
+ foreach (array_keys($data) as $item) {
+ $data[$item]['level'] = $lvl + 1;
+ }
+ echo html_buildlist(
+ $data,
+ 'acl',
+ array($acl, 'makeTreeItem'),
+ array($acl, 'makeListItem')
+ );
+ }
+ }
+}
diff --git a/platform/www/lib/plugins/acl/admin.php b/platform/www/lib/plugins/acl/admin.php
new file mode 100644
index 0000000..02842fd
--- /dev/null
+++ b/platform/www/lib/plugins/acl/admin.php
@@ -0,0 +1,858 @@
+<?php
+/**
+ * ACL administration functions
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org> (concepts)
+ * @author Frank Schubert <frank@schokilade.de> (old version)
+ */
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_acl extends DokuWiki_Admin_Plugin
+{
+ public $acl = null;
+ protected $ns = null;
+ /**
+ * The currently selected item, associative array with id and type.
+ * Populated from (in this order):
+ * $_REQUEST['current_ns']
+ * $_REQUEST['current_id']
+ * $ns
+ * $ID
+ */
+ protected $current_item = null;
+ protected $who = '';
+ protected $usersgroups = array();
+ protected $specials = array();
+
+ /**
+ * return prompt for admin menu
+ */
+ public function getMenuText($language)
+ {
+ return $this->getLang('admin_acl');
+ }
+
+ /**
+ * return sort order for position in admin menu
+ */
+ public function getMenuSort()
+ {
+ return 1;
+ }
+
+ /**
+ * handle user request
+ *
+ * Initializes internal vars and handles modifications
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function handle()
+ {
+ global $AUTH_ACL;
+ global $ID;
+ global $auth;
+ global $config_cascade;
+ global $INPUT;
+
+ // fresh 1:1 copy without replacements
+ $AUTH_ACL = file($config_cascade['acl']['default']);
+
+ // namespace given?
+ if ($INPUT->str('ns') == '*') {
+ $this->ns = '*';
+ } else {
+ $this->ns = cleanID($INPUT->str('ns'));
+ }
+
+ if ($INPUT->str('current_ns')) {
+ $this->current_item = array('id' => cleanID($INPUT->str('current_ns')), 'type' => 'd');
+ } elseif ($INPUT->str('current_id')) {
+ $this->current_item = array('id' => cleanID($INPUT->str('current_id')), 'type' => 'f');
+ } elseif ($this->ns) {
+ $this->current_item = array('id' => $this->ns, 'type' => 'd');
+ } else {
+ $this->current_item = array('id' => $ID, 'type' => 'f');
+ }
+
+ // user or group choosen?
+ $who = trim($INPUT->str('acl_w'));
+ if ($INPUT->str('acl_t') == '__g__' && $who) {
+ $this->who = '@'.ltrim($auth->cleanGroup($who), '@');
+ } elseif ($INPUT->str('acl_t') == '__u__' && $who) {
+ $this->who = ltrim($who, '@');
+ if ($this->who != '%USER%' && $this->who != '%GROUP%') { #keep wildcard as is
+ $this->who = $auth->cleanUser($this->who);
+ }
+ } elseif ($INPUT->str('acl_t') &&
+ $INPUT->str('acl_t') != '__u__' &&
+ $INPUT->str('acl_t') != '__g__') {
+ $this->who = $INPUT->str('acl_t');
+ } elseif ($who) {
+ $this->who = $who;
+ }
+
+ // handle modifications
+ if ($INPUT->has('cmd') && checkSecurityToken()) {
+ $cmd = $INPUT->extract('cmd')->str('cmd');
+
+ // scope for modifications
+ if ($this->ns) {
+ if ($this->ns == '*') {
+ $scope = '*';
+ } else {
+ $scope = $this->ns.':*';
+ }
+ } else {
+ $scope = $ID;
+ }
+
+ if ($cmd == 'save' && $scope && $this->who && $INPUT->has('acl')) {
+ // handle additions or single modifications
+ $this->deleteACL($scope, $this->who);
+ $this->addOrUpdateACL($scope, $this->who, $INPUT->int('acl'));
+ } elseif ($cmd == 'del' && $scope && $this->who) {
+ // handle single deletions
+ $this->deleteACL($scope, $this->who);
+ } elseif ($cmd == 'update') {
+ $acl = $INPUT->arr('acl');
+
+ // handle update of the whole file
+ foreach ($INPUT->arr('del') as $where => $names) {
+ // remove all rules marked for deletion
+ foreach ($names as $who)
+ unset($acl[$where][$who]);
+ }
+ // prepare lines
+ $lines = array();
+ // keep header
+ foreach ($AUTH_ACL as $line) {
+ if ($line[0] == '#') {
+ $lines[] = $line;
+ } else {
+ break;
+ }
+ }
+ // re-add all rules
+ foreach ($acl as $where => $opt) {
+ foreach ($opt as $who => $perm) {
+ if ($who[0]=='@') {
+ if ($who!='@ALL') {
+ $who = '@'.ltrim($auth->cleanGroup($who), '@');
+ }
+ } elseif ($who != '%USER%' && $who != '%GROUP%') { #keep wildcard as is
+ $who = $auth->cleanUser($who);
+ }
+ $who = auth_nameencode($who, true);
+ $lines[] = "$where\t$who\t$perm\n";
+ }
+ }
+ // save it
+ io_saveFile($config_cascade['acl']['default'], join('', $lines));
+ }
+
+ // reload ACL config
+ $AUTH_ACL = file($config_cascade['acl']['default']);
+ }
+
+ // initialize ACL array
+ $this->initAclConfig();
+ }
+
+ /**
+ * ACL Output function
+ *
+ * print a table with all significant permissions for the
+ * current id
+ *
+ * @author Frank Schubert <frank@schokilade.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function html()
+ {
+ echo '<div id="acl_manager">'.NL;
+ echo '<h1>'.$this->getLang('admin_acl').'</h1>'.NL;
+ echo '<div class="level1">'.NL;
+
+ echo '<div id="acl__tree">'.NL;
+ $this->makeExplorer();
+ echo '</div>'.NL;
+
+ echo '<div id="acl__detail">'.NL;
+ $this->printDetail();
+ echo '</div>'.NL;
+ echo '</div>'.NL;
+
+ echo '<div class="clearer"></div>';
+ echo '<h2>'.$this->getLang('current').'</h2>'.NL;
+ echo '<div class="level2">'.NL;
+ $this->printAclTable();
+ echo '</div>'.NL;
+
+ echo '<div class="footnotes"><div class="fn">'.NL;
+ echo '<sup><a id="fn__1" class="fn_bot" href="#fnt__1">1)</a></sup>'.NL;
+ echo '<div class="content">'.$this->getLang('p_include').'</div>';
+ echo '</div></div>';
+
+ echo '</div>'.NL;
+ }
+
+ /**
+ * returns array with set options for building links
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function getLinkOptions($addopts = null)
+ {
+ $opts = array(
+ 'do'=>'admin',
+ 'page'=>'acl',
+ );
+ if ($this->ns) $opts['ns'] = $this->ns;
+ if ($this->who) $opts['acl_w'] = $this->who;
+
+ if (is_null($addopts)) return $opts;
+ return array_merge($opts, $addopts);
+ }
+
+ /**
+ * Display a tree menu to select a page or namespace
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function makeExplorer()
+ {
+ global $conf;
+ global $ID;
+ global $lang;
+
+ $ns = $this->ns;
+ if (empty($ns)) {
+ $ns = dirname(str_replace(':', '/', $ID));
+ if ($ns == '.') $ns ='';
+ } elseif ($ns == '*') {
+ $ns ='';
+ }
+ $ns = utf8_encodeFN(str_replace(':', '/', $ns));
+
+ $data = $this->makeTree($ns);
+
+ // wrap a list with the root level around the other namespaces
+ array_unshift($data, array( 'level' => 0, 'id' => '*', 'type' => 'd',
+ 'open' =>'true', 'label' => '['.$lang['mediaroot'].']'));
+
+ echo html_buildlist(
+ $data,
+ 'acl',
+ array($this, 'makeTreeItem'),
+ array($this, 'makeListItem')
+ );
+ }
+
+ /**
+ * get a combined list of media and page files
+ *
+ * also called via AJAX
+ *
+ * @param string $folder an already converted filesystem folder of the current namespace
+ * @param string $limit limit the search to this folder
+ * @return array
+ */
+ public function makeTree($folder, $limit = '')
+ {
+ global $conf;
+
+ // read tree structure from pages and media
+ $data = array();
+ search($data, $conf['datadir'], 'search_index', array('ns' => $folder), $limit);
+ $media = array();
+ search($media, $conf['mediadir'], 'search_index', array('ns' => $folder, 'nofiles' => true), $limit);
+ $data = array_merge($data, $media);
+ unset($media);
+
+ // combine by sorting and removing duplicates
+ usort($data, array($this, 'treeSort'));
+ $count = count($data);
+ if ($count>0) for ($i=1; $i<$count; $i++) {
+ if ($data[$i-1]['id'] == $data[$i]['id'] && $data[$i-1]['type'] == $data[$i]['type']) {
+ unset($data[$i]);
+ $i++; // duplicate found, next $i can't be a duplicate, so skip forward one
+ }
+ }
+ return $data;
+ }
+
+ /**
+ * usort callback
+ *
+ * Sorts the combined trees of media and page files
+ */
+ public function treeSort($a, $b)
+ {
+ // handle the trivial cases first
+ if ($a['id'] == '') return -1;
+ if ($b['id'] == '') return 1;
+ // split up the id into parts
+ $a_ids = explode(':', $a['id']);
+ $b_ids = explode(':', $b['id']);
+ // now loop through the parts
+ while (count($a_ids) && count($b_ids)) {
+ // compare each level from upper to lower
+ // until a non-equal component is found
+ $cur_result = strcmp(array_shift($a_ids), array_shift($b_ids));
+ if ($cur_result) {
+ // if one of the components is the last component and is a file
+ // and the other one is either of a deeper level or a directory,
+ // the file has to come after the deeper level or directory
+ if (empty($a_ids) && $a['type'] == 'f' && (count($b_ids) || $b['type'] == 'd')) return 1;
+ if (empty($b_ids) && $b['type'] == 'f' && (count($a_ids) || $a['type'] == 'd')) return -1;
+ return $cur_result;
+ }
+ }
+ // The two ids seem to be equal. One of them might however refer
+ // to a page, one to a namespace, the namespace needs to be first.
+ if (empty($a_ids) && empty($b_ids)) {
+ if ($a['type'] == $b['type']) return 0;
+ if ($a['type'] == 'f') return 1;
+ return -1;
+ }
+ // Now the empty part is either a page in the parent namespace
+ // that obviously needs to be after the namespace
+ // Or it is the namespace that contains the other part and should be
+ // before that other part.
+ if (empty($a_ids)) return ($a['type'] == 'd') ? -1 : 1;
+ if (empty($b_ids)) return ($b['type'] == 'd') ? 1 : -1;
+ return 0; //shouldn't happen
+ }
+
+ /**
+ * Display the current ACL for selected where/who combination with
+ * selectors and modification form
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function printDetail()
+ {
+ global $ID;
+
+ echo '<form action="'.wl().'" method="post" accept-charset="utf-8"><div class="no">'.NL;
+
+ echo '<div id="acl__user">';
+ echo $this->getLang('acl_perms').' ';
+ $inl = $this->makeSelect();
+ echo '<input type="text" name="acl_w" class="edit" value="'.(($inl)?'':hsc(ltrim($this->who, '@'))).'" />'.NL;
+ echo '<button type="submit">'.$this->getLang('btn_select').'</button>'.NL;
+ echo '</div>'.NL;
+
+ echo '<div id="acl__info">';
+ $this->printInfo();
+ echo '</div>';
+
+ echo '<input type="hidden" name="ns" value="'.hsc($this->ns).'" />'.NL;
+ echo '<input type="hidden" name="id" value="'.hsc($ID).'" />'.NL;
+ echo '<input type="hidden" name="do" value="admin" />'.NL;
+ echo '<input type="hidden" name="page" value="acl" />'.NL;
+ echo '<input type="hidden" name="sectok" value="'.getSecurityToken().'" />'.NL;
+ echo '</div></form>'.NL;
+ }
+
+ /**
+ * Print info and editor
+ *
+ * also loaded via Ajax
+ */
+ public function printInfo()
+ {
+ global $ID;
+
+ if ($this->who) {
+ $current = $this->getExactPermisson();
+
+ // explain current permissions
+ $this->printExplanation($current);
+ // load editor
+ $this->printAclEditor($current);
+ } else {
+ echo '<p>';
+ if ($this->ns) {
+ printf($this->getLang('p_choose_ns'), hsc($this->ns));
+ } else {
+ printf($this->getLang('p_choose_id'), hsc($ID));
+ }
+ echo '</p>';
+
+ echo $this->locale_xhtml('help');
+ }
+ }
+
+ /**
+ * Display the ACL editor
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function printAclEditor($current)
+ {
+ global $lang;
+
+ echo '<fieldset>';
+ if (is_null($current)) {
+ echo '<legend>'.$this->getLang('acl_new').'</legend>';
+ } else {
+ echo '<legend>'.$this->getLang('acl_mod').'</legend>';
+ }
+
+ echo $this->makeCheckboxes($current, empty($this->ns), 'acl');
+
+ if (is_null($current)) {
+ echo '<button type="submit" name="cmd[save]">'.$lang['btn_save'].'</button>'.NL;
+ } else {
+ echo '<button type="submit" name="cmd[save]">'.$lang['btn_update'].'</button>'.NL;
+ echo '<button type="submit" name="cmd[del]">'.$lang['btn_delete'].'</button>'.NL;
+ }
+
+ echo '</fieldset>';
+ }
+
+ /**
+ * Explain the currently set permissions in plain english/$lang
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function printExplanation($current)
+ {
+ global $ID;
+ global $auth;
+
+ $who = $this->who;
+ $ns = $this->ns;
+
+ // prepare where to check
+ if ($ns) {
+ if ($ns == '*') {
+ $check='*';
+ } else {
+ $check=$ns.':*';
+ }
+ } else {
+ $check = $ID;
+ }
+
+ // prepare who to check
+ if ($who[0] == '@') {
+ $user = '';
+ $groups = array(ltrim($who, '@'));
+ } else {
+ $user = $who;
+ $info = $auth->getUserData($user);
+ if ($info === false) {
+ $groups = array();
+ } else {
+ $groups = $info['grps'];
+ }
+ }
+
+ // check the permissions
+ $perm = auth_aclcheck($check, $user, $groups);
+
+ // build array of named permissions
+ $names = array();
+ if ($perm) {
+ if ($ns) {
+ if ($perm >= AUTH_DELETE) $names[] = $this->getLang('acl_perm16');
+ if ($perm >= AUTH_UPLOAD) $names[] = $this->getLang('acl_perm8');
+ if ($perm >= AUTH_CREATE) $names[] = $this->getLang('acl_perm4');
+ }
+ if ($perm >= AUTH_EDIT) $names[] = $this->getLang('acl_perm2');
+ if ($perm >= AUTH_READ) $names[] = $this->getLang('acl_perm1');
+ $names = array_reverse($names);
+ } else {
+ $names[] = $this->getLang('acl_perm0');
+ }
+
+ // print permission explanation
+ echo '<p>';
+ if ($user) {
+ if ($ns) {
+ printf($this->getLang('p_user_ns'), hsc($who), hsc($ns), join(', ', $names));
+ } else {
+ printf($this->getLang('p_user_id'), hsc($who), hsc($ID), join(', ', $names));
+ }
+ } else {
+ if ($ns) {
+ printf($this->getLang('p_group_ns'), hsc(ltrim($who, '@')), hsc($ns), join(', ', $names));
+ } else {
+ printf($this->getLang('p_group_id'), hsc(ltrim($who, '@')), hsc($ID), join(', ', $names));
+ }
+ }
+ echo '</p>';
+
+ // add note if admin
+ if ($perm == AUTH_ADMIN) {
+ echo '<p>'.$this->getLang('p_isadmin').'</p>';
+ } elseif (is_null($current)) {
+ echo '<p>'.$this->getLang('p_inherited').'</p>';
+ }
+ }
+
+
+ /**
+ * Item formatter for the tree view
+ *
+ * User function for html_buildlist()
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function makeTreeItem($item)
+ {
+ $ret = '';
+ // what to display
+ if (!empty($item['label'])) {
+ $base = $item['label'];
+ } else {
+ $base = ':'.$item['id'];
+ $base = substr($base, strrpos($base, ':')+1);
+ }
+
+ // highlight?
+ if (($item['type']== $this->current_item['type'] && $item['id'] == $this->current_item['id'])) {
+ $cl = ' cur';
+ } else {
+ $cl = '';
+ }
+
+ // namespace or page?
+ if ($item['type']=='d') {
+ if ($item['open']) {
+ $img = DOKU_BASE.'lib/images/minus.gif';
+ $alt = '−';
+ } else {
+ $img = DOKU_BASE.'lib/images/plus.gif';
+ $alt = '+';
+ }
+ $ret .= '<img src="'.$img.'" alt="'.$alt.'" />';
+ $ret .= '<a href="'.
+ wl('', $this->getLinkOptions(array('ns'=> $item['id'], 'sectok'=>getSecurityToken()))).
+ '" class="idx_dir'.$cl.'">';
+ $ret .= $base;
+ $ret .= '</a>';
+ } else {
+ $ret .= '<a href="'.
+ wl('', $this->getLinkOptions(array('id'=> $item['id'], 'ns'=>'', 'sectok'=>getSecurityToken()))).
+ '" class="wikilink1'.$cl.'">';
+ $ret .= noNS($item['id']);
+ $ret .= '</a>';
+ }
+ return $ret;
+ }
+
+ /**
+ * List Item formatter
+ *
+ * @param array $item
+ * @return string
+ */
+ public function makeListItem($item)
+ {
+ return '<li class="level' . $item['level'] . ' ' .
+ ($item['open'] ? 'open' : 'closed') . '">';
+ }
+
+
+ /**
+ * Get current ACL settings as multidim array
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function initAclConfig()
+ {
+ global $AUTH_ACL;
+ global $conf;
+ $acl_config=array();
+ $usersgroups = array();
+
+ // get special users and groups
+ $this->specials[] = '@ALL';
+ $this->specials[] = '@'.$conf['defaultgroup'];
+ if ($conf['manager'] != '!!not set!!') {
+ $this->specials = array_merge(
+ $this->specials,
+ array_map(
+ 'trim',
+ explode(',', $conf['manager'])
+ )
+ );
+ }
+ $this->specials = array_filter($this->specials);
+ $this->specials = array_unique($this->specials);
+ sort($this->specials);
+
+ foreach ($AUTH_ACL as $line) {
+ $line = trim(preg_replace('/#.*$/', '', $line)); //ignore comments
+ if (!$line) continue;
+
+ $acl = preg_split('/[ \t]+/', $line);
+ //0 is pagename, 1 is user, 2 is acl
+
+ $acl[1] = rawurldecode($acl[1]);
+ $acl_config[$acl[0]][$acl[1]] = $acl[2];
+
+ // store non-special users and groups for later selection dialog
+ $ug = $acl[1];
+ if (in_array($ug, $this->specials)) continue;
+ $usersgroups[] = $ug;
+ }
+
+ $usersgroups = array_unique($usersgroups);
+ sort($usersgroups);
+ ksort($acl_config);
+
+ $this->acl = $acl_config;
+ $this->usersgroups = $usersgroups;
+ }
+
+ /**
+ * Display all currently set permissions in a table
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function printAclTable()
+ {
+ global $lang;
+ global $ID;
+
+ echo '<form action="'.wl().'" method="post" accept-charset="utf-8"><div class="no">'.NL;
+ if ($this->ns) {
+ echo '<input type="hidden" name="ns" value="'.hsc($this->ns).'" />'.NL;
+ } else {
+ echo '<input type="hidden" name="id" value="'.hsc($ID).'" />'.NL;
+ }
+ echo '<input type="hidden" name="acl_w" value="'.hsc($this->who).'" />'.NL;
+ echo '<input type="hidden" name="do" value="admin" />'.NL;
+ echo '<input type="hidden" name="page" value="acl" />'.NL;
+ echo '<input type="hidden" name="sectok" value="'.getSecurityToken().'" />'.NL;
+ echo '<div class="table">';
+ echo '<table class="inline">';
+ echo '<tr>';
+ echo '<th>'.$this->getLang('where').'</th>';
+ echo '<th>'.$this->getLang('who').'</th>';
+ echo '<th>'.$this->getLang('perm').'<sup><a id="fnt__1" class="fn_top" href="#fn__1">1)</a></sup></th>';
+ echo '<th>'.$lang['btn_delete'].'</th>';
+ echo '</tr>';
+ foreach ($this->acl as $where => $set) {
+ foreach ($set as $who => $perm) {
+ echo '<tr>';
+ echo '<td>';
+ if (substr($where, -1) == '*') {
+ echo '<span class="aclns">'.hsc($where).'</span>';
+ $ispage = false;
+ } else {
+ echo '<span class="aclpage">'.hsc($where).'</span>';
+ $ispage = true;
+ }
+ echo '</td>';
+
+ echo '<td>';
+ if ($who[0] == '@') {
+ echo '<span class="aclgroup">'.hsc($who).'</span>';
+ } else {
+ echo '<span class="acluser">'.hsc($who).'</span>';
+ }
+ echo '</td>';
+
+ echo '<td>';
+ echo $this->makeCheckboxes($perm, $ispage, 'acl['.$where.']['.$who.']');
+ echo '</td>';
+
+ echo '<td class="check">';
+ echo '<input type="checkbox" name="del['.hsc($where).'][]" value="'.hsc($who).'" />';
+ echo '</td>';
+ echo '</tr>';
+ }
+ }
+
+ echo '<tr>';
+ echo '<th class="action" colspan="4">';
+ echo '<button type="submit" name="cmd[update]">'.$lang['btn_update'].'</button>';
+ echo '</th>';
+ echo '</tr>';
+ echo '</table>';
+ echo '</div>';
+ echo '</div></form>'.NL;
+ }
+
+ /**
+ * Returns the permission which were set for exactly the given user/group
+ * and page/namespace. Returns null if no exact match is available
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function getExactPermisson()
+ {
+ global $ID;
+ if ($this->ns) {
+ if ($this->ns == '*') {
+ $check = '*';
+ } else {
+ $check = $this->ns.':*';
+ }
+ } else {
+ $check = $ID;
+ }
+
+ if (isset($this->acl[$check][$this->who])) {
+ return $this->acl[$check][$this->who];
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * adds new acl-entry to conf/acl.auth.php
+ *
+ * @author Frank Schubert <frank@schokilade.de>
+ */
+ public function addOrUpdateACL($acl_scope, $acl_user, $acl_level)
+ {
+ global $config_cascade;
+
+ // first make sure we won't end up with 2 lines matching this user and scope. See issue #1115
+ $this->deleteACL($acl_scope, $acl_user);
+ $acl_user = auth_nameencode($acl_user, true);
+
+ // max level for pagenames is edit
+ if (strpos($acl_scope, '*') === false) {
+ if ($acl_level > AUTH_EDIT) $acl_level = AUTH_EDIT;
+ }
+
+ $new_acl = "$acl_scope\t$acl_user\t$acl_level\n";
+
+ return io_saveFile($config_cascade['acl']['default'], $new_acl, true);
+ }
+
+ /**
+ * remove acl-entry from conf/acl.auth.php
+ *
+ * @author Frank Schubert <frank@schokilade.de>
+ */
+ public function deleteACL($acl_scope, $acl_user)
+ {
+ global $config_cascade;
+ $acl_user = auth_nameencode($acl_user, true);
+
+ $acl_pattern = '^'.preg_quote($acl_scope, '/').'[ \t]+'.$acl_user.'[ \t]+[0-8].*$';
+
+ return io_deleteFromFile($config_cascade['acl']['default'], "/$acl_pattern/", true);
+ }
+
+ /**
+ * print the permission radio boxes
+ *
+ * @author Frank Schubert <frank@schokilade.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function makeCheckboxes($setperm, $ispage, $name)
+ {
+ global $lang;
+
+ static $label = 0; //number labels
+ $ret = '';
+
+ if ($ispage && $setperm > AUTH_EDIT) $setperm = AUTH_EDIT;
+
+ foreach (array(AUTH_NONE,AUTH_READ,AUTH_EDIT,AUTH_CREATE,AUTH_UPLOAD,AUTH_DELETE) as $perm) {
+ $label += 1;
+
+ //general checkbox attributes
+ $atts = array( 'type' => 'radio',
+ 'id' => 'pbox'.$label,
+ 'name' => $name,
+ 'value' => $perm );
+ //dynamic attributes
+ if (!is_null($setperm) && $setperm == $perm) $atts['checked'] = 'checked';
+ if ($ispage && $perm > AUTH_EDIT) {
+ $atts['disabled'] = 'disabled';
+ $class = ' class="disabled"';
+ } else {
+ $class = '';
+ }
+
+ //build code
+ $ret .= '<label for="pbox'.$label.'"'.$class.'>';
+ $ret .= '<input '.buildAttributes($atts).' />&#160;';
+ $ret .= $this->getLang('acl_perm'.$perm);
+ $ret .= '</label>'.NL;
+ }
+ return $ret;
+ }
+
+ /**
+ * Print a user/group selector (reusing already used users and groups)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function makeSelect()
+ {
+ $inlist = false;
+ $usel = '';
+ $gsel = '';
+
+ if ($this->who &&
+ !in_array($this->who, $this->usersgroups) &&
+ !in_array($this->who, $this->specials)) {
+ if ($this->who[0] == '@') {
+ $gsel = ' selected="selected"';
+ } else {
+ $usel = ' selected="selected"';
+ }
+ } else {
+ $inlist = true;
+ }
+
+ echo '<select name="acl_t" class="edit">'.NL;
+ echo ' <option value="__g__" class="aclgroup"'.$gsel.'>'.$this->getLang('acl_group').'</option>'.NL;
+ echo ' <option value="__u__" class="acluser"'.$usel.'>'.$this->getLang('acl_user').'</option>'.NL;
+ if (!empty($this->specials)) {
+ echo ' <optgroup label="&#160;">'.NL;
+ foreach ($this->specials as $ug) {
+ if ($ug == $this->who) {
+ $sel = ' selected="selected"';
+ $inlist = true;
+ } else {
+ $sel = '';
+ }
+
+ if ($ug[0] == '@') {
+ echo ' <option value="'.hsc($ug).'" class="aclgroup"'.$sel.'>'.hsc($ug).'</option>'.NL;
+ } else {
+ echo ' <option value="'.hsc($ug).'" class="acluser"'.$sel.'>'.hsc($ug).'</option>'.NL;
+ }
+ }
+ echo ' </optgroup>'.NL;
+ }
+ if (!empty($this->usersgroups)) {
+ echo ' <optgroup label="&#160;">'.NL;
+ foreach ($this->usersgroups as $ug) {
+ if ($ug == $this->who) {
+ $sel = ' selected="selected"';
+ $inlist = true;
+ } else {
+ $sel = '';
+ }
+
+ if ($ug[0] == '@') {
+ echo ' <option value="'.hsc($ug).'" class="aclgroup"'.$sel.'>'.hsc($ug).'</option>'.NL;
+ } else {
+ echo ' <option value="'.hsc($ug).'" class="acluser"'.$sel.'>'.hsc($ug).'</option>'.NL;
+ }
+ }
+ echo ' </optgroup>'.NL;
+ }
+ echo '</select>'.NL;
+ return $inlist;
+ }
+}
diff --git a/platform/www/lib/plugins/acl/admin.svg b/platform/www/lib/plugins/acl/admin.svg
new file mode 100644
index 0000000..b5cf001
--- /dev/null
+++ b/platform/www/lib/plugins/acl/admin.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M22 18v4h-4v-3h-3v-3h-3l-2.26-2.26c-.55.17-1.13.26-1.74.26a6 6 0 0 1-6-6 6 6 0 0 1 6-6 6 6 0 0 1 6 6c0 .61-.09 1.19-.26 1.74L22 18M7 5a2 2 0 0 0-2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0-2-2z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/plugins/acl/lang/en/help.txt b/platform/www/lib/plugins/acl/lang/en/help.txt
new file mode 100644
index 0000000..e865bbb
--- /dev/null
+++ b/platform/www/lib/plugins/acl/lang/en/help.txt
@@ -0,0 +1,9 @@
+=== Quick Help: ===
+
+On this page you can add and remove permissions for namespaces and pages in your wiki.
+ * The left pane displays all available namespaces and pages.
+ * The form above allows you to see and modify the permissions of a selected user or group.
+ * In the table below all currently set access control rules are shown. You can use it to quickly delete or change multiple rules.
+
+Reading the [[doku>acl|official documentation on ACL]] might help you to fully understand how access control works in DokuWiki.
+
diff --git a/platform/www/lib/plugins/acl/lang/en/lang.php b/platform/www/lib/plugins/acl/lang/en/lang.php
new file mode 100644
index 0000000..0c86489
--- /dev/null
+++ b/platform/www/lib/plugins/acl/lang/en/lang.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * english language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ */
+
+$lang['admin_acl'] = 'Access Control List Management';
+$lang['acl_group'] = 'Group:';
+$lang['acl_user'] = 'User:';
+$lang['acl_perms'] = 'Permissions for';
+$lang['page'] = 'Page';
+$lang['namespace'] = 'Namespace';
+
+$lang['btn_select'] = 'Select';
+
+$lang['p_user_id'] = 'User <b class="acluser">%s</b> currently has the following permissions on page <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_user_ns'] = 'User <b class="acluser">%s</b> currently has the following permissions in namespace <b class="aclns">%s</b>: <i>%s</i>.';
+$lang['p_group_id'] = 'Members of group <b class="aclgroup">%s</b> currently have the following permissions on page <b class="aclpage">%s</b>: <i>%s</i>.';
+$lang['p_group_ns'] = 'Members of group <b class="aclgroup">%s</b> currently have the following permissions in namespace <b class="aclns">%s</b>: <i>%s</i>.';
+
+$lang['p_choose_id'] = 'Please <b>enter a user or group</b> in the form above to view or edit the permissions set for the page <b class="aclpage">%s</b>.';
+$lang['p_choose_ns'] = 'Please <b>enter a user or group</b> in the form above to view or edit the permissions set for the namespace <b class="aclns">%s</b>.';
+
+
+$lang['p_inherited'] = 'Note: Those permissions were not set explicitly but were inherited from other groups or higher namespaces.';
+$lang['p_isadmin'] = 'Note: The selected group or user has always full permissions because it is configured as superuser.';
+$lang['p_include'] = 'Higher permissions include lower ones. Create, Upload and Delete permissions only apply to namespaces, not pages.';
+
+$lang['current'] = 'Current ACL Rules';
+$lang['where'] = 'Page/Namespace';
+$lang['who'] = 'User/Group';
+$lang['perm'] = 'Permissions';
+
+$lang['acl_perm0'] = 'None';
+$lang['acl_perm1'] = 'Read';
+$lang['acl_perm2'] = 'Edit';
+$lang['acl_perm4'] = 'Create';
+$lang['acl_perm8'] = 'Upload';
+$lang['acl_perm16'] = 'Delete';
+$lang['acl_new'] = 'Add new Entry';
+$lang['acl_mod'] = 'Modify Entry';
+//Setup VIM: ex: et ts=2 :
diff --git a/platform/www/lib/plugins/acl/pix/group.png b/platform/www/lib/plugins/acl/pix/group.png
new file mode 100644
index 0000000..348d4e5
--- /dev/null
+++ b/platform/www/lib/plugins/acl/pix/group.png
Binary files differ
diff --git a/platform/www/lib/plugins/acl/pix/ns.png b/platform/www/lib/plugins/acl/pix/ns.png
new file mode 100644
index 0000000..77e03b1
--- /dev/null
+++ b/platform/www/lib/plugins/acl/pix/ns.png
Binary files differ
diff --git a/platform/www/lib/plugins/acl/pix/page.png b/platform/www/lib/plugins/acl/pix/page.png
new file mode 100644
index 0000000..b1b7ebe
--- /dev/null
+++ b/platform/www/lib/plugins/acl/pix/page.png
Binary files differ
diff --git a/platform/www/lib/plugins/acl/pix/user.png b/platform/www/lib/plugins/acl/pix/user.png
new file mode 100644
index 0000000..8d5d1c2
--- /dev/null
+++ b/platform/www/lib/plugins/acl/pix/user.png
Binary files differ
diff --git a/platform/www/lib/plugins/acl/plugin.info.txt b/platform/www/lib/plugins/acl/plugin.info.txt
new file mode 100644
index 0000000..1b2c82c
--- /dev/null
+++ b/platform/www/lib/plugins/acl/plugin.info.txt
@@ -0,0 +1,7 @@
+base acl
+author Andreas Gohr
+email andi@splitbrain.org
+date 2015-07-25
+name ACL Manager
+desc Manage Page Access Control Lists
+url http://dokuwiki.org/plugin:acl
diff --git a/platform/www/lib/plugins/acl/remote.php b/platform/www/lib/plugins/acl/remote.php
new file mode 100644
index 0000000..8d19add
--- /dev/null
+++ b/platform/www/lib/plugins/acl/remote.php
@@ -0,0 +1,102 @@
+<?php
+
+use dokuwiki\Remote\AccessDeniedException;
+
+/**
+ * Class remote_plugin_acl
+ */
+class remote_plugin_acl extends DokuWiki_Remote_Plugin
+{
+
+ /**
+ * Returns details about the remote plugin methods
+ *
+ * @return array Information about all provided methods. {@see dokuwiki\Remote\RemoteAPI}
+ */
+ public function _getMethods()
+ {
+ return array(
+ 'listAcls' => array(
+ 'args' => array(),
+ 'return' => 'Array of ACLs {scope, user, permission}',
+ 'name' => 'listAcls',
+ 'doc' => 'Get the list of all ACLs',
+ ),'addAcl' => array(
+ 'args' => array('string','string','int'),
+ 'return' => 'int',
+ 'name' => 'addAcl',
+ 'doc' => 'Adds a new ACL rule.'
+ ), 'delAcl' => array(
+ 'args' => array('string','string'),
+ 'return' => 'int',
+ 'name' => 'delAcl',
+ 'doc' => 'Delete an existing ACL rule.'
+ ),
+ );
+ }
+
+ /**
+ * List all ACL config entries
+ *
+ * @throws AccessDeniedException
+ * @return dictionary {Scope: ACL}, where ACL = dictionnary {user/group: permissions_int}
+ */
+ public function listAcls()
+ {
+ if (!auth_isadmin()) {
+ throw new AccessDeniedException(
+ 'You are not allowed to access ACLs, superuser permission is required',
+ 114
+ );
+ }
+ /** @var admin_plugin_acl $apa */
+ $apa = plugin_load('admin', 'acl');
+ $apa->initAclConfig();
+ return $apa->acl;
+ }
+
+ /**
+ * Add a new entry to ACL config
+ *
+ * @param string $scope
+ * @param string $user
+ * @param int $level see also inc/auth.php
+ * @throws AccessDeniedException
+ * @return bool
+ */
+ public function addAcl($scope, $user, $level)
+ {
+ if (!auth_isadmin()) {
+ throw new AccessDeniedException(
+ 'You are not allowed to access ACLs, superuser permission is required',
+ 114
+ );
+ }
+
+ /** @var admin_plugin_acl $apa */
+ $apa = plugin_load('admin', 'acl');
+ return $apa->addOrUpdateACL($scope, $user, $level);
+ }
+
+ /**
+ * Remove an entry from ACL config
+ *
+ * @param string $scope
+ * @param string $user
+ * @throws AccessDeniedException
+ * @return bool
+ */
+ public function delAcl($scope, $user)
+ {
+ if (!auth_isadmin()) {
+ throw new AccessDeniedException(
+ 'You are not allowed to access ACLs, superuser permission is required',
+ 114
+ );
+ }
+
+ /** @var admin_plugin_acl $apa */
+ $apa = plugin_load('admin', 'acl');
+ return $apa->deleteACL($scope, $user);
+ }
+}
diff --git a/platform/www/lib/plugins/acl/script.js b/platform/www/lib/plugins/acl/script.js
new file mode 100644
index 0000000..95621a2
--- /dev/null
+++ b/platform/www/lib/plugins/acl/script.js
@@ -0,0 +1,121 @@
+/**
+ * ACL Manager AJAX enhancements
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+var dw_acl = {
+ /**
+ * Initialize the object and attach the event handlers
+ */
+ init: function () {
+ var $tree;
+
+ //FIXME only one underscore!!
+ if (jQuery('#acl_manager').length === 0) {
+ return;
+ }
+
+ jQuery('#acl__user select').on('change', dw_acl.userselhandler);
+ jQuery('#acl__user button').on('click', dw_acl.loadinfo);
+
+ $tree = jQuery('#acl__tree');
+ $tree.dw_tree({toggle_selector: 'img',
+ load_data: function (show_sublist, $clicky) {
+ // get the enclosed link and the edit form
+ var $frm = jQuery('#acl__detail form');
+
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ jQuery.extend(dw_acl.parseatt($clicky.parent().find('a')[0].search),
+ {call: 'plugin_acl',
+ ajax: 'tree',
+ current_ns: $frm.find('input[name=ns]').val(),
+ current_id: $frm.find('input[name=id]').val()}),
+ show_sublist,
+ 'html'
+ );
+ },
+
+ toggle_display: function ($clicky, opening) {
+ $clicky.attr('src',
+ DOKU_BASE + 'lib/images/' +
+ (opening ? 'minus' : 'plus') + '.gif');
+ }});
+ $tree.delegate('a', 'click', dw_acl.treehandler);
+ },
+
+ /**
+ * Handle user dropdown
+ *
+ * Hides or shows the user/group entry box depending on what was selected in the
+ * dropdown element
+ */
+ userselhandler: function () {
+ // make entry field visible/invisible
+ jQuery('#acl__user input').toggle(this.value === '__g__' ||
+ this.value === '__u__');
+ dw_acl.loadinfo();
+ },
+
+ /**
+ * Load the current permission info and edit form
+ */
+ loadinfo: function () {
+ jQuery('#acl__info')
+ .attr('role', 'alert')
+ .html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="..." />')
+ .load(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ jQuery('#acl__detail form').serialize() + '&call=plugin_acl&ajax=info'
+ );
+ return false;
+ },
+
+ /**
+ * parse URL attributes into a associative array
+ *
+ * @todo put into global script lib?
+ */
+ parseatt: function (str) {
+ if (str[0] === '?') {
+ str = str.substr(1);
+ }
+ var attributes = {};
+ var all = str.split('&');
+ for (var i = 0; i < all.length; i++) {
+ var att = all[i].split('=');
+ attributes[att[0]] = decodeURIComponent(att[1]);
+ }
+ return attributes;
+ },
+
+ /**
+ * Handles clicks to the tree nodes
+ */
+ treehandler: function () {
+ var $link, $frm;
+
+ $link = jQuery(this);
+
+ // remove highlighting
+ jQuery('#acl__tree a.cur').removeClass('cur');
+
+ // add new highlighting
+ $link.addClass('cur');
+
+ // set new page to detail form
+ $frm = jQuery('#acl__detail form');
+ if ($link.hasClass('wikilink1')) {
+ $frm.find('input[name=ns]').val('');
+ $frm.find('input[name=id]').val(dw_acl.parseatt($link[0].search).id);
+ } else if ($link.hasClass('idx_dir')) {
+ $frm.find('input[name=ns]').val(dw_acl.parseatt($link[0].search).ns);
+ $frm.find('input[name=id]').val('');
+ }
+ dw_acl.loadinfo();
+
+ return false;
+ }
+};
+
+jQuery(dw_acl.init);
diff --git a/platform/www/lib/plugins/acl/style.css b/platform/www/lib/plugins/acl/style.css
new file mode 100644
index 0000000..4233cd3
--- /dev/null
+++ b/platform/www/lib/plugins/acl/style.css
@@ -0,0 +1,135 @@
+#acl__tree {
+ font-size: 90%;
+ width: 25%;
+ height: 300px;
+ float: left;
+ overflow: auto;
+ border: 1px solid __border__;
+ text-align: left;
+}
+[dir=rtl] #acl__tree {
+ float: right;
+ text-align: right;
+}
+
+#acl__tree a.cur {
+ background-color: __highlight__;
+ font-weight: bold;
+}
+
+#acl__tree ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+
+#acl__tree li {
+ padding-left: 1em;
+ list-style-image: none;
+}
+[dir=rtl] #acl__tree li {
+ padding-left: 0em;
+ padding-right: 1em;
+}
+
+#acl__tree ul img {
+ margin-right: 0.25em;
+ cursor: pointer;
+}
+[dir=rtl] #acl__tree ul img {
+ margin-left: 0.25em;
+ margin-right: 0em;
+}
+
+#acl__detail {
+ width: 73%;
+ height: 300px;
+ float: right;
+ overflow: auto;
+}
+[dir=rtl] #acl__detail {
+ float: left;
+}
+
+#acl__detail fieldset {
+ width: 90%;
+}
+
+#acl__detail div#acl__user {
+ border: 1px solid __border__;
+ padding: 0.5em;
+ margin-bottom: 0.6em;
+}
+
+#acl_manager table.inline {
+ width: 100%;
+ margin: 0;
+}
+
+#acl_manager table .check {
+ text-align: center;
+}
+
+#acl_manager table .action {
+ text-align: right;
+}
+
+#acl_manager .aclgroup {
+ background: transparent url(pix/group.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+[dir=rtl] #acl_manager .aclgroup {
+ background: transparent url(pix/group.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
+#acl_manager .acluser {
+ background: transparent url(pix/user.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+[dir=rtl] #acl_manager .acluser {
+ background: transparent url(pix/user.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
+#acl_manager .aclpage {
+ background: transparent url(pix/page.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+[dir=rtl] #acl_manager .aclpage {
+ background: transparent url(pix/page.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
+#acl_manager .aclns {
+ background: transparent url(pix/ns.png) 0px 1px no-repeat;
+ padding: 1px 0px 1px 18px;
+}
+[dir=rtl] #acl_manager .aclns {
+ background: transparent url(pix/ns.png) right 1px no-repeat;
+ padding: 1px 18px 1px 0px;
+}
+
+#acl_manager label.disabled {
+ opacity: .5;
+ cursor: auto;
+}
+
+#acl_manager label {
+ text-align: left;
+ font-weight: normal;
+ display: inline;
+}
+
+#acl_manager table {
+ margin-left: 10%;
+ width: 80%;
+}
+
+#acl_manager table tr {
+ background-color: inherit;
+}
+
+#acl_manager table tr:hover {
+ background-color: __background_alt__;
+}
diff --git a/platform/www/lib/plugins/action.php b/platform/www/lib/plugins/action.php
new file mode 100644
index 0000000..a3cbec7
--- /dev/null
+++ b/platform/www/lib/plugins/action.php
@@ -0,0 +1,2 @@
+<?php
+dbg_deprecated('Autoloading. Do not require() files yourself.');
diff --git a/platform/www/lib/plugins/admin.php b/platform/www/lib/plugins/admin.php
new file mode 100644
index 0000000..a3cbec7
--- /dev/null
+++ b/platform/www/lib/plugins/admin.php
@@ -0,0 +1,2 @@
+<?php
+dbg_deprecated('Autoloading. Do not require() files yourself.');
diff --git a/platform/www/lib/plugins/auth.php b/platform/www/lib/plugins/auth.php
new file mode 100644
index 0000000..a3cbec7
--- /dev/null
+++ b/platform/www/lib/plugins/auth.php
@@ -0,0 +1,2 @@
+<?php
+dbg_deprecated('Autoloading. Do not require() files yourself.');
diff --git a/platform/www/lib/plugins/authad/action.php b/platform/www/lib/plugins/authad/action.php
new file mode 100644
index 0000000..a9fc01c
--- /dev/null
+++ b/platform/www/lib/plugins/authad/action.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * DokuWiki Plugin addomain (Action Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+/**
+ * Class action_plugin_addomain
+ */
+class action_plugin_authad extends DokuWiki_Action_Plugin
+{
+
+ /**
+ * Registers a callback function for a given event
+ */
+ public function register(Doku_Event_Handler $controller)
+ {
+
+ $controller->register_hook('AUTH_LOGIN_CHECK', 'BEFORE', $this, 'handleAuthLoginCheck');
+ $controller->register_hook('HTML_LOGINFORM_OUTPUT', 'BEFORE', $this, 'handleHtmlLoginformOutput');
+ }
+
+ /**
+ * Adds the selected domain as user postfix when attempting a login
+ *
+ * @param Doku_Event $event
+ * @param array $param
+ */
+ public function handleAuthLoginCheck(Doku_Event $event, $param)
+ {
+ global $INPUT;
+
+ /** @var auth_plugin_authad $auth */
+ global $auth;
+ if (!is_a($auth, 'auth_plugin_authad')) return; // AD not even used
+
+ if ($INPUT->str('dom')) {
+ $usr = $auth->cleanUser($event->data['user']);
+ $dom = $auth->getUserDomain($usr);
+ if (!$dom) {
+ $usr = "$usr@".$INPUT->str('dom');
+ }
+ $INPUT->post->set('u', $usr);
+ $event->data['user'] = $usr;
+ }
+ }
+
+ /**
+ * Shows a domain selection in the login form when more than one domain is configured
+ *
+ * @param Doku_Event $event
+ * @param array $param
+ */
+ public function handleHtmlLoginformOutput(Doku_Event $event, $param)
+ {
+ global $INPUT;
+ /** @var auth_plugin_authad $auth */
+ global $auth;
+ if (!is_a($auth, 'auth_plugin_authad')) return; // AD not even used
+ $domains = $auth->getConfiguredDomains();
+ if (count($domains) <= 1) return; // no choice at all
+
+ /** @var Doku_Form $form */
+ $form =& $event->data;
+
+ // any default?
+ $dom = '';
+ if ($INPUT->has('u')) {
+ $usr = $auth->cleanUser($INPUT->str('u'));
+ $dom = $auth->getUserDomain($usr);
+
+ // update user field value
+ if ($dom) {
+ $usr = $auth->getUserName($usr);
+ $pos = $form->findElementByAttribute('name', 'u');
+ $ele =& $form->getElementAt($pos);
+ $ele['value'] = $usr;
+ }
+ }
+
+ // add select box
+ $element = form_makeListboxField('dom', $domains, $dom, $this->getLang('domain'), '', 'block');
+ $pos = $form->findElementByAttribute('name', 'p');
+ $form->insertElement($pos + 1, $element);
+ }
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/authad/adLDAP/adLDAP.php b/platform/www/lib/plugins/authad/adLDAP/adLDAP.php
new file mode 100644
index 0000000..c84a4f4
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/adLDAP.php
@@ -0,0 +1,949 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 169 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+ */
+
+/**
+* Main adLDAP class
+*
+* Can be initialised using $adldap = new adLDAP();
+*
+* Something to keep in mind is that Active Directory is a permissions
+* based directory. If you bind as a domain user, you can't fetch as
+* much information on other users as you could as a domain admin.
+*
+* Before asking questions, please read the Documentation at
+* http://adldap.sourceforge.net/wiki/doku.php?id=api
+*/
+require_once(dirname(__FILE__) . '/collections/adLDAPCollection.php');
+require_once(dirname(__FILE__) . '/classes/adLDAPGroups.php');
+require_once(dirname(__FILE__) . '/classes/adLDAPUsers.php');
+require_once(dirname(__FILE__) . '/classes/adLDAPFolders.php');
+require_once(dirname(__FILE__) . '/classes/adLDAPUtils.php');
+require_once(dirname(__FILE__) . '/classes/adLDAPContacts.php');
+require_once(dirname(__FILE__) . '/classes/adLDAPExchange.php');
+require_once(dirname(__FILE__) . '/classes/adLDAPComputers.php');
+
+class adLDAP {
+
+ /**
+ * Define the different types of account in AD
+ */
+ const ADLDAP_NORMAL_ACCOUNT = 805306368;
+ const ADLDAP_WORKSTATION_TRUST = 805306369;
+ const ADLDAP_INTERDOMAIN_TRUST = 805306370;
+ const ADLDAP_SECURITY_GLOBAL_GROUP = 268435456;
+ const ADLDAP_DISTRIBUTION_GROUP = 268435457;
+ const ADLDAP_SECURITY_LOCAL_GROUP = 536870912;
+ const ADLDAP_DISTRIBUTION_LOCAL_GROUP = 536870913;
+ const ADLDAP_FOLDER = 'OU';
+ const ADLDAP_CONTAINER = 'CN';
+
+ /**
+ * The default port for LDAP non-SSL connections
+ */
+ const ADLDAP_LDAP_PORT = '389';
+ /**
+ * The default port for LDAPS SSL connections
+ */
+ const ADLDAP_LDAPS_PORT = '636';
+
+ /**
+ * The account suffix for your domain, can be set when the class is invoked
+ *
+ * @var string
+ */
+ protected $accountSuffix = "@mydomain.local";
+
+ /**
+ * The base dn for your domain
+ *
+ * If this is set to null then adLDAP will attempt to obtain this automatically from the rootDSE
+ *
+ * @var string
+ */
+ protected $baseDn = "DC=mydomain,DC=local";
+
+ /**
+ * Port used to talk to the domain controllers.
+ *
+ * @var int
+ */
+ protected $adPort = self::ADLDAP_LDAP_PORT;
+
+ /**
+ * Array of domain controllers. Specifiy multiple controllers if you
+ * would like the class to balance the LDAP queries amongst multiple servers
+ *
+ * @var array
+ */
+ protected $domainControllers = array("dc01.mydomain.local");
+
+ /**
+ * Optional account with higher privileges for searching
+ * This should be set to a domain admin account
+ *
+ * @var string
+ * @var string
+ */
+ protected $adminUsername = NULL;
+ protected $adminPassword = NULL;
+
+ /**
+ * AD does not return the primary group. http://support.microsoft.com/?kbid=321360
+ * This tweak will resolve the real primary group.
+ * Setting to false will fudge "Domain Users" and is much faster. Keep in mind though that if
+ * someone's primary group is NOT domain users, this is obviously going to mess up the results
+ *
+ * @var bool
+ */
+ protected $realPrimaryGroup = true;
+
+ /**
+ * Use SSL (LDAPS), your server needs to be setup, please see
+ * http://adldap.sourceforge.net/wiki/doku.php?id=ldap_over_ssl
+ *
+ * @var bool
+ */
+ protected $useSSL = false;
+
+ /**
+ * Use TLS
+ * If you wish to use TLS you should ensure that $useSSL is set to false and vice-versa
+ *
+ * @var bool
+ */
+ protected $useTLS = false;
+
+ /**
+ * Use SSO
+ * To indicate to adLDAP to reuse password set by the brower through NTLM or Kerberos
+ *
+ * @var bool
+ */
+ protected $useSSO = false;
+
+ /**
+ * When querying group memberships, do it recursively
+ * eg. User Fred is a member of Group A, which is a member of Group B, which is a member of Group C
+ * user_ingroup("Fred","C") will returns true with this option turned on, false if turned off
+ *
+ * @var bool
+ */
+ protected $recursiveGroups = true;
+
+ // You should not need to edit anything below this line
+ //******************************************************************************************
+
+ /**
+ * Connection and bind default variables
+ *
+ * @var mixed
+ * @var mixed
+ */
+ protected $ldapConnection;
+ protected $ldapBind;
+
+ /**
+ * Get the active LDAP Connection
+ *
+ * @return resource
+ */
+ public function getLdapConnection() {
+ if ($this->ldapConnection) {
+ return $this->ldapConnection;
+ }
+ return false;
+ }
+
+ /**
+ * Get the bind status
+ *
+ * @return bool
+ */
+ public function getLdapBind() {
+ return $this->ldapBind;
+ }
+
+ /**
+ * Get the current base DN
+ *
+ * @return string
+ */
+ public function getBaseDn() {
+ return $this->baseDn;
+ }
+
+ /**
+ * The group class
+ *
+ * @var adLDAPGroups
+ */
+ protected $groupClass;
+
+ /**
+ * Get the group class interface
+ *
+ * @return adLDAPGroups
+ */
+ public function group() {
+ if (!$this->groupClass) {
+ $this->groupClass = new adLDAPGroups($this);
+ }
+ return $this->groupClass;
+ }
+
+ /**
+ * The user class
+ *
+ * @var adLDAPUsers
+ */
+ protected $userClass;
+
+ /**
+ * Get the userclass interface
+ *
+ * @return adLDAPUsers
+ */
+ public function user() {
+ if (!$this->userClass) {
+ $this->userClass = new adLDAPUsers($this);
+ }
+ return $this->userClass;
+ }
+
+ /**
+ * The folders class
+ *
+ * @var adLDAPFolders
+ */
+ protected $folderClass;
+
+ /**
+ * Get the folder class interface
+ *
+ * @return adLDAPFolders
+ */
+ public function folder() {
+ if (!$this->folderClass) {
+ $this->folderClass = new adLDAPFolders($this);
+ }
+ return $this->folderClass;
+ }
+
+ /**
+ * The utils class
+ *
+ * @var adLDAPUtils
+ */
+ protected $utilClass;
+
+ /**
+ * Get the utils class interface
+ *
+ * @return adLDAPUtils
+ */
+ public function utilities() {
+ if (!$this->utilClass) {
+ $this->utilClass = new adLDAPUtils($this);
+ }
+ return $this->utilClass;
+ }
+
+ /**
+ * The contacts class
+ *
+ * @var adLDAPContacts
+ */
+ protected $contactClass;
+
+ /**
+ * Get the contacts class interface
+ *
+ * @return adLDAPContacts
+ */
+ public function contact() {
+ if (!$this->contactClass) {
+ $this->contactClass = new adLDAPContacts($this);
+ }
+ return $this->contactClass;
+ }
+
+ /**
+ * The exchange class
+ *
+ * @var adLDAPExchange
+ */
+ protected $exchangeClass;
+
+ /**
+ * Get the exchange class interface
+ *
+ * @return adLDAPExchange
+ */
+ public function exchange() {
+ if (!$this->exchangeClass) {
+ $this->exchangeClass = new adLDAPExchange($this);
+ }
+ return $this->exchangeClass;
+ }
+
+ /**
+ * The computers class
+ *
+ * @var adLDAPComputers
+ */
+ protected $computersClass;
+
+ /**
+ * Get the computers class interface
+ *
+ * @return adLDAPComputers
+ */
+ public function computer() {
+ if (!$this->computerClass) {
+ $this->computerClass = new adLDAPComputers($this);
+ }
+ return $this->computerClass;
+ }
+
+ /**
+ * Getters and Setters
+ */
+
+ /**
+ * Set the account suffix
+ *
+ * @param string $accountSuffix
+ * @return void
+ */
+ public function setAccountSuffix($accountSuffix)
+ {
+ $this->accountSuffix = $accountSuffix;
+ }
+
+ /**
+ * Get the account suffix
+ *
+ * @return string
+ */
+ public function getAccountSuffix()
+ {
+ return $this->accountSuffix;
+ }
+
+ /**
+ * Set the domain controllers array
+ *
+ * @param array $domainControllers
+ * @return void
+ */
+ public function setDomainControllers(array $domainControllers)
+ {
+ $this->domainControllers = $domainControllers;
+ }
+
+ /**
+ * Get the list of domain controllers
+ *
+ * @return void
+ */
+ public function getDomainControllers()
+ {
+ return $this->domainControllers;
+ }
+
+ /**
+ * Sets the port number your domain controller communicates over
+ *
+ * @param int $adPort
+ */
+ public function setPort($adPort)
+ {
+ $this->adPort = $adPort;
+ }
+
+ /**
+ * Gets the port number your domain controller communicates over
+ *
+ * @return int
+ */
+ public function getPort()
+ {
+ return $this->adPort;
+ }
+
+ /**
+ * Set the username of an account with higher priviledges
+ *
+ * @param string $adminUsername
+ * @return void
+ */
+ public function setAdminUsername($adminUsername)
+ {
+ $this->adminUsername = $adminUsername;
+ }
+
+ /**
+ * Get the username of the account with higher priviledges
+ *
+ * This will throw an exception for security reasons
+ */
+ public function getAdminUsername()
+ {
+ throw new adLDAPException('For security reasons you cannot access the domain administrator account details');
+ }
+
+ /**
+ * Set the password of an account with higher priviledges
+ *
+ * @param string $adminPassword
+ * @return void
+ */
+ public function setAdminPassword($adminPassword)
+ {
+ $this->adminPassword = $adminPassword;
+ }
+
+ /**
+ * Get the password of the account with higher priviledges
+ *
+ * This will throw an exception for security reasons
+ */
+ public function getAdminPassword()
+ {
+ throw new adLDAPException('For security reasons you cannot access the domain administrator account details');
+ }
+
+ /**
+ * Set whether to detect the true primary group
+ *
+ * @param bool $realPrimaryGroup
+ * @return void
+ */
+ public function setRealPrimaryGroup($realPrimaryGroup)
+ {
+ $this->realPrimaryGroup = $realPrimaryGroup;
+ }
+
+ /**
+ * Get the real primary group setting
+ *
+ * @return bool
+ */
+ public function getRealPrimaryGroup()
+ {
+ return $this->realPrimaryGroup;
+ }
+
+ /**
+ * Set whether to use SSL
+ *
+ * @param bool $useSSL
+ * @return void
+ */
+ public function setUseSSL($useSSL)
+ {
+ $this->useSSL = $useSSL;
+ // Set the default port correctly
+ if($this->useSSL) {
+ $this->setPort(self::ADLDAP_LDAPS_PORT);
+ }
+ else {
+ $this->setPort(self::ADLDAP_LDAP_PORT);
+ }
+ }
+
+ /**
+ * Get the SSL setting
+ *
+ * @return bool
+ */
+ public function getUseSSL()
+ {
+ return $this->useSSL;
+ }
+
+ /**
+ * Set whether to use TLS
+ *
+ * @param bool $useTLS
+ * @return void
+ */
+ public function setUseTLS($useTLS)
+ {
+ $this->useTLS = $useTLS;
+ }
+
+ /**
+ * Get the TLS setting
+ *
+ * @return bool
+ */
+ public function getUseTLS()
+ {
+ return $this->useTLS;
+ }
+
+ /**
+ * Set whether to use SSO
+ * Requires ldap_sasl_bind support. Be sure --with-ldap-sasl is used when configuring PHP otherwise this function will be undefined.
+ *
+ * @param bool $useSSO
+ * @return void
+ */
+ public function setUseSSO($useSSO)
+ {
+ if ($useSSO === true && !$this->ldapSaslSupported()) {
+ throw new adLDAPException('No LDAP SASL support for PHP. See: http://php.net/ldap_sasl_bind');
+ }
+ $this->useSSO = $useSSO;
+ }
+
+ /**
+ * Get the SSO setting
+ *
+ * @return bool
+ */
+ public function getUseSSO()
+ {
+ return $this->useSSO;
+ }
+
+ /**
+ * Set whether to lookup recursive groups
+ *
+ * @param bool $recursiveGroups
+ * @return void
+ */
+ public function setRecursiveGroups($recursiveGroups)
+ {
+ $this->recursiveGroups = $recursiveGroups;
+ }
+
+ /**
+ * Get the recursive groups setting
+ *
+ * @return bool
+ */
+ public function getRecursiveGroups()
+ {
+ return $this->recursiveGroups;
+ }
+
+ /**
+ * Default Constructor
+ *
+ * Tries to bind to the AD domain over LDAP or LDAPs
+ *
+ * @param array $options Array of options to pass to the constructor
+ * @throws Exception - if unable to bind to Domain Controller
+ * @return bool
+ */
+ function __construct($options = array()) {
+ // You can specifically overide any of the default configuration options setup above
+ if (count($options) > 0) {
+ if (array_key_exists("account_suffix",$options)){ $this->accountSuffix = $options["account_suffix"]; }
+ if (array_key_exists("base_dn",$options)){ $this->baseDn = $options["base_dn"]; }
+ if (array_key_exists("domain_controllers",$options)){
+ if (!is_array($options["domain_controllers"])) {
+ throw new adLDAPException('[domain_controllers] option must be an array');
+ }
+ $this->domainControllers = $options["domain_controllers"];
+ }
+ if (array_key_exists("admin_username",$options)){ $this->adminUsername = $options["admin_username"]; }
+ if (array_key_exists("admin_password",$options)){ $this->adminPassword = $options["admin_password"]; }
+ if (array_key_exists("real_primarygroup",$options)){ $this->realPrimaryGroup = $options["real_primarygroup"]; }
+ if (array_key_exists("use_ssl",$options)){ $this->setUseSSL($options["use_ssl"]); }
+ if (array_key_exists("use_tls",$options)){ $this->useTLS = $options["use_tls"]; }
+ if (array_key_exists("recursive_groups",$options)){ $this->recursiveGroups = $options["recursive_groups"]; }
+ if (array_key_exists("ad_port",$options)){ $this->setPort($options["ad_port"]); }
+ if (array_key_exists("sso",$options)) {
+ $this->setUseSSO($options["sso"]);
+ if (!$this->ldapSaslSupported()) {
+ $this->setUseSSO(false);
+ }
+ }
+ }
+
+ if ($this->ldapSupported() === false) {
+ throw new adLDAPException('No LDAP support for PHP. See: http://php.net/ldap');
+ }
+
+ return $this->connect();
+ }
+
+ /**
+ * Default Destructor
+ *
+ * Closes the LDAP connection
+ *
+ * @return void
+ */
+ function __destruct() {
+ $this->close();
+ }
+
+ /**
+ * Connects and Binds to the Domain Controller
+ *
+ * @return bool
+ */
+ public function connect()
+ {
+ // Connect to the AD/LDAP server as the username/password
+ $domainController = $this->randomController();
+ if ($this->useSSL) {
+ $this->ldapConnection = ldap_connect("ldaps://" . $domainController, $this->adPort);
+ } else {
+ $this->ldapConnection = ldap_connect($domainController, $this->adPort);
+ }
+
+ // Set some ldap options for talking to AD
+ ldap_set_option($this->ldapConnection, LDAP_OPT_PROTOCOL_VERSION, 3);
+ ldap_set_option($this->ldapConnection, LDAP_OPT_REFERRALS, 0);
+
+ if ($this->useTLS) {
+ ldap_start_tls($this->ldapConnection);
+ }
+
+ // Bind as a domain admin if they've set it up
+ if ($this->adminUsername !== NULL && $this->adminPassword !== NULL) {
+ $this->ldapBind = @ldap_bind($this->ldapConnection, $this->adminUsername . $this->accountSuffix, $this->adminPassword);
+ if (!$this->ldapBind) {
+ if ($this->useSSL && !$this->useTLS) {
+ // If you have problems troubleshooting, remove the @ character from the ldapldapBind command above to get the actual error message
+ throw new adLDAPException('Bind to Active Directory failed. Either the LDAPs connection failed or the login credentials are incorrect. AD said: ' . $this->getLastError());
+ }
+ else {
+ throw new adLDAPException('Bind to Active Directory failed. Check the login credentials and/or server details. AD said: ' . $this->getLastError());
+ }
+ }
+ }
+ if ($this->useSSO && $_SERVER['REMOTE_USER'] && $this->adminUsername === null && $_SERVER['KRB5CCNAME']) {
+ putenv("KRB5CCNAME=" . $_SERVER['KRB5CCNAME']);
+ $this->ldapBind = @ldap_sasl_bind($this->ldapConnection, NULL, NULL, "GSSAPI");
+ if (!$this->ldapBind){
+ throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError());
+ }
+ else {
+ return true;
+ }
+ }
+
+
+ if ($this->baseDn == NULL) {
+ $this->baseDn = $this->findBaseDn();
+ }
+
+ return true;
+ }
+
+ /**
+ * Closes the LDAP connection
+ *
+ * @return void
+ */
+ public function close() {
+ if ($this->ldapConnection) {
+ @ldap_close($this->ldapConnection);
+ }
+ }
+
+ /**
+ * Validate a user's login credentials
+ *
+ * @param string $username A user's AD username
+ * @param string $password A user's AD password
+ * @param bool optional $preventRebind
+ * @return bool
+ */
+ public function authenticate($username, $password, $preventRebind = false) {
+ // Prevent null binding
+ if ($username === NULL || $password === NULL) { return false; }
+ if (empty($username) || empty($password)) { return false; }
+
+ // Allow binding over SSO for Kerberos
+ if ($this->useSSO && $_SERVER['REMOTE_USER'] && $_SERVER['REMOTE_USER'] == $username && $this->adminUsername === NULL && $_SERVER['KRB5CCNAME']) {
+ putenv("KRB5CCNAME=" . $_SERVER['KRB5CCNAME']);
+ $this->ldapBind = @ldap_sasl_bind($this->ldapConnection, NULL, NULL, "GSSAPI");
+ if (!$this->ldapBind) {
+ throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError());
+ }
+ else {
+ return true;
+ }
+ }
+
+ // Bind as the user
+ $ret = true;
+ $this->ldapBind = @ldap_bind($this->ldapConnection, $username . $this->accountSuffix, $password);
+ if (!$this->ldapBind){
+ $ret = false;
+ }
+
+ // Cnce we've checked their details, kick back into admin mode if we have it
+ if ($this->adminUsername !== NULL && !$preventRebind) {
+ $this->ldapBind = @ldap_bind($this->ldapConnection, $this->adminUsername . $this->accountSuffix , $this->adminPassword);
+ if (!$this->ldapBind){
+ // This should never happen in theory
+ throw new adLDAPException('Rebind to Active Directory failed. AD said: ' . $this->getLastError());
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Find the Base DN of your domain controller
+ *
+ * @return string
+ */
+ public function findBaseDn()
+ {
+ $namingContext = $this->getRootDse(array('defaultnamingcontext'));
+ return $namingContext[0]['defaultnamingcontext'][0];
+ }
+
+ /**
+ * Get the RootDSE properties from a domain controller
+ *
+ * @param array $attributes The attributes you wish to query e.g. defaultnamingcontext
+ * @return array
+ */
+ public function getRootDse($attributes = array("*", "+")) {
+ if (!$this->ldapBind){ return (false); }
+
+ $sr = @ldap_read($this->ldapConnection, NULL, 'objectClass=*', $attributes);
+ $entries = @ldap_get_entries($this->ldapConnection, $sr);
+ return $entries;
+ }
+
+ /**
+ * Get last error from Active Directory
+ *
+ * This function gets the last message from Active Directory
+ * This may indeed be a 'Success' message but if you get an unknown error
+ * it might be worth calling this function to see what errors were raised
+ *
+ * return string
+ */
+ public function getLastError() {
+ return @ldap_error($this->ldapConnection);
+ }
+
+ /**
+ * Detect LDAP support in php
+ *
+ * @return bool
+ */
+ protected function ldapSupported()
+ {
+ if (!function_exists('ldap_connect')) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Detect ldap_sasl_bind support in PHP
+ *
+ * @return bool
+ */
+ protected function ldapSaslSupported()
+ {
+ if (!function_exists('ldap_sasl_bind')) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Schema
+ *
+ * @param array $attributes Attributes to be queried
+ * @return array
+ */
+ public function adldap_schema($attributes){
+
+ // LDAP doesn't like NULL attributes, only set them if they have values
+ // If you wish to remove an attribute you should set it to a space
+ // TO DO: Adapt user_modify to use ldap_mod_delete to remove a NULL attribute
+ $mod=array();
+
+ // Check every attribute to see if it contains 8bit characters and then UTF8 encode them
+ array_walk($attributes, array($this, 'encode8bit'));
+
+ if ($attributes["address_city"]){ $mod["l"][0]=$attributes["address_city"]; }
+ if ($attributes["address_code"]){ $mod["postalCode"][0]=$attributes["address_code"]; }
+ //if ($attributes["address_country"]){ $mod["countryCode"][0]=$attributes["address_country"]; } // use country codes?
+ if ($attributes["address_country"]){ $mod["c"][0]=$attributes["address_country"]; }
+ if ($attributes["address_pobox"]){ $mod["postOfficeBox"][0]=$attributes["address_pobox"]; }
+ if ($attributes["address_state"]){ $mod["st"][0]=$attributes["address_state"]; }
+ if ($attributes["address_street"]){ $mod["streetAddress"][0]=$attributes["address_street"]; }
+ if ($attributes["company"]){ $mod["company"][0]=$attributes["company"]; }
+ if ($attributes["change_password"]){ $mod["pwdLastSet"][0]=0; }
+ if ($attributes["department"]){ $mod["department"][0]=$attributes["department"]; }
+ if ($attributes["description"]){ $mod["description"][0]=$attributes["description"]; }
+ if ($attributes["display_name"]){ $mod["displayName"][0]=$attributes["display_name"]; }
+ if ($attributes["email"]){ $mod["mail"][0]=$attributes["email"]; }
+ if ($attributes["expires"]){ $mod["accountExpires"][0]=$attributes["expires"]; } //unix epoch format?
+ if ($attributes["firstname"]){ $mod["givenName"][0]=$attributes["firstname"]; }
+ if ($attributes["home_directory"]){ $mod["homeDirectory"][0]=$attributes["home_directory"]; }
+ if ($attributes["home_drive"]){ $mod["homeDrive"][0]=$attributes["home_drive"]; }
+ if ($attributes["initials"]){ $mod["initials"][0]=$attributes["initials"]; }
+ if ($attributes["logon_name"]){ $mod["userPrincipalName"][0]=$attributes["logon_name"]; }
+ if ($attributes["manager"]){ $mod["manager"][0]=$attributes["manager"]; } //UNTESTED ***Use DistinguishedName***
+ if ($attributes["office"]){ $mod["physicalDeliveryOfficeName"][0]=$attributes["office"]; }
+ if ($attributes["password"]){ $mod["unicodePwd"][0]=$this->user()->encodePassword($attributes["password"]); }
+ if ($attributes["profile_path"]){ $mod["profilepath"][0]=$attributes["profile_path"]; }
+ if ($attributes["script_path"]){ $mod["scriptPath"][0]=$attributes["script_path"]; }
+ if ($attributes["surname"]){ $mod["sn"][0]=$attributes["surname"]; }
+ if ($attributes["title"]){ $mod["title"][0]=$attributes["title"]; }
+ if ($attributes["telephone"]){ $mod["telephoneNumber"][0]=$attributes["telephone"]; }
+ if ($attributes["mobile"]){ $mod["mobile"][0]=$attributes["mobile"]; }
+ if ($attributes["pager"]){ $mod["pager"][0]=$attributes["pager"]; }
+ if ($attributes["ipphone"]){ $mod["ipphone"][0]=$attributes["ipphone"]; }
+ if ($attributes["web_page"]){ $mod["wWWHomePage"][0]=$attributes["web_page"]; }
+ if ($attributes["fax"]){ $mod["facsimileTelephoneNumber"][0]=$attributes["fax"]; }
+ if ($attributes["enabled"]){ $mod["userAccountControl"][0]=$attributes["enabled"]; }
+ if ($attributes["homephone"]){ $mod["homephone"][0]=$attributes["homephone"]; }
+
+ // Distribution List specific schema
+ if ($attributes["group_sendpermission"]){ $mod["dlMemSubmitPerms"][0]=$attributes["group_sendpermission"]; }
+ if ($attributes["group_rejectpermission"]){ $mod["dlMemRejectPerms"][0]=$attributes["group_rejectpermission"]; }
+
+ // Exchange Schema
+ if ($attributes["exchange_homemdb"]){ $mod["homeMDB"][0]=$attributes["exchange_homemdb"]; }
+ if ($attributes["exchange_mailnickname"]){ $mod["mailNickname"][0]=$attributes["exchange_mailnickname"]; }
+ if ($attributes["exchange_proxyaddress"]){ $mod["proxyAddresses"][0]=$attributes["exchange_proxyaddress"]; }
+ if ($attributes["exchange_usedefaults"]){ $mod["mDBUseDefaults"][0]=$attributes["exchange_usedefaults"]; }
+ if ($attributes["exchange_policyexclude"]){ $mod["msExchPoliciesExcluded"][0]=$attributes["exchange_policyexclude"]; }
+ if ($attributes["exchange_policyinclude"]){ $mod["msExchPoliciesIncluded"][0]=$attributes["exchange_policyinclude"]; }
+ if ($attributes["exchange_addressbook"]){ $mod["showInAddressBook"][0]=$attributes["exchange_addressbook"]; }
+ if ($attributes["exchange_altrecipient"]){ $mod["altRecipient"][0]=$attributes["exchange_altrecipient"]; }
+ if ($attributes["exchange_deliverandredirect"]){ $mod["deliverAndRedirect"][0]=$attributes["exchange_deliverandredirect"]; }
+
+ // This schema is designed for contacts
+ if ($attributes["exchange_hidefromlists"]){ $mod["msExchHideFromAddressLists"][0]=$attributes["exchange_hidefromlists"]; }
+ if ($attributes["contact_email"]){ $mod["targetAddress"][0]=$attributes["contact_email"]; }
+
+ //echo ("<pre>"); print_r($mod);
+ /*
+ // modifying a name is a bit fiddly
+ if ($attributes["firstname"] && $attributes["surname"]){
+ $mod["cn"][0]=$attributes["firstname"]." ".$attributes["surname"];
+ $mod["displayname"][0]=$attributes["firstname"]." ".$attributes["surname"];
+ $mod["name"][0]=$attributes["firstname"]." ".$attributes["surname"];
+ }
+ */
+
+ if (count($mod)==0){ return (false); }
+ return ($mod);
+ }
+
+ /**
+ * Convert 8bit characters e.g. accented characters to UTF8 encoded characters
+ */
+ protected function encode8Bit(&$item, $key) {
+ $encode = false;
+ if (is_string($item)) {
+ for ($i=0; $i<strlen($item); $i++) {
+ if (ord($item[$i]) >> 7) {
+ $encode = true;
+ }
+ }
+ }
+ if ($encode === true && $key != 'password') {
+ $item = utf8_encode($item);
+ }
+ }
+
+ /**
+ * Select a random domain controller from your domain controller array
+ *
+ * @return string
+ */
+ protected function randomController()
+ {
+ mt_srand(doubleval(microtime()) * 100000000); // For older PHP versions
+ /*if (sizeof($this->domainControllers) > 1) {
+ $adController = $this->domainControllers[array_rand($this->domainControllers)];
+ // Test if the controller is responding to pings
+ $ping = $this->pingController($adController);
+ if ($ping === false) {
+ // Find the current key in the domain controllers array
+ $key = array_search($adController, $this->domainControllers);
+ // Remove it so that we don't end up in a recursive loop
+ unset($this->domainControllers[$key]);
+ // Select a new controller
+ return $this->randomController();
+ }
+ else {
+ return ($adController);
+ }
+ } */
+ return $this->domainControllers[array_rand($this->domainControllers)];
+ }
+
+ /**
+ * Test basic connectivity to controller
+ *
+ * @return bool
+ */
+ protected function pingController($host) {
+ $port = $this->adPort;
+ fsockopen($host, $port, $errno, $errstr, 10);
+ if ($errno > 0) {
+ return false;
+ }
+ return true;
+ }
+
+}
+
+/**
+* adLDAP Exception Handler
+*
+* Exceptions of this type are thrown on bind failure or when SSL is required but not configured
+* Example:
+* try {
+* $adldap = new adLDAP();
+* }
+* catch (adLDAPException $e) {
+* echo $e;
+* exit();
+* }
+*/
+class adLDAPException extends Exception {}
diff --git a/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPComputers.php b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPComputers.php
new file mode 100644
index 0000000..aabd88f
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPComputers.php
@@ -0,0 +1,153 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage Computers
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+ */
+require_once(dirname(__FILE__) . '/../adLDAP.php');
+require_once(dirname(__FILE__) . '/../collections/adLDAPComputerCollection.php');
+
+/**
+* COMPUTER MANAGEMENT FUNCTIONS
+*/
+class adLDAPComputers {
+
+ /**
+ * The current adLDAP connection via dependency injection
+ *
+ * @var adLDAP
+ */
+ protected $adldap;
+
+ public function __construct(adLDAP $adldap) {
+ $this->adldap = $adldap;
+ }
+
+ /**
+ * Get information about a specific computer. Returned in a raw array format from AD
+ *
+ * @param string $computerName The name of the computer
+ * @param array $fields Attributes to return
+ * @return array
+ */
+ public function info($computerName, $fields = NULL)
+ {
+ if ($computerName === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ $filter = "(&(objectClass=computer)(cn=" . $computerName . "))";
+ if ($fields === NULL) {
+ $fields = array("memberof","cn","displayname","dnshostname","distinguishedname","objectcategory","operatingsystem","operatingsystemservicepack","operatingsystemversion");
+ }
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ return $entries;
+ }
+
+ /**
+ * Find information about the computers. Returned in a raw array format from AD
+ *
+ * @param string $computerName The name of the computer
+ * @param array $fields Array of parameters to query
+ * @return mixed
+ */
+ public function infoCollection($computerName, $fields = NULL)
+ {
+ if ($computerName === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ $info = $this->info($computerName, $fields);
+
+ if ($info !== false) {
+ $collection = new adLDAPComputerCollection($info, $this->adldap);
+ return $collection;
+ }
+ return false;
+ }
+
+ /**
+ * Check if a computer is in a group
+ *
+ * @param string $computerName The name of the computer
+ * @param string $group The group to check
+ * @param bool $recursive Whether to check recursively
+ * @return array
+ */
+ public function inGroup($computerName, $group, $recursive = NULL)
+ {
+ if ($computerName === NULL) { return false; }
+ if ($group === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+ if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } // use the default option if they haven't set it
+
+ //get a list of the groups
+ $groups = $this->groups($computerName, array("memberof"), $recursive);
+
+ //return true if the specified group is in the group list
+ if (in_array($group, $groups)){
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the groups a computer is in
+ *
+ * @param string $computerName The name of the computer
+ * @param bool $recursive Whether to check recursively
+ * @return array
+ */
+ public function groups($computerName, $recursive = NULL)
+ {
+ if ($computerName === NULL) { return false; }
+ if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it
+ if (!$this->adldap->getLdapBind()){ return false; }
+
+ //search the directory for their information
+ $info = @$this->info($computerName, array("memberof", "primarygroupid"));
+ $groups = $this->adldap->utilities()->niceNames($info[0]["memberof"]); //presuming the entry returned is our guy (unique usernames)
+
+ if ($recursive === true) {
+ foreach ($groups as $id => $groupName){
+ $extraGroups = $this->adldap->group()->recursiveGroups($groupName);
+ $groups = array_merge($groups, $extraGroups);
+ }
+ }
+
+ return $groups;
+ }
+
+}
+?> \ No newline at end of file
diff --git a/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPContacts.php b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPContacts.php
new file mode 100644
index 0000000..42a0d75
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPContacts.php
@@ -0,0 +1,294 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage Contacts
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+ */
+
+require_once(dirname(__FILE__) . '/../adLDAP.php');
+require_once(dirname(__FILE__) . '/../collections/adLDAPContactCollection.php');
+
+class adLDAPContacts {
+ /**
+ * The current adLDAP connection via dependency injection
+ *
+ * @var adLDAP
+ */
+ protected $adldap;
+
+ public function __construct(adLDAP $adldap) {
+ $this->adldap = $adldap;
+ }
+
+ //*****************************************************************************************************************
+ // CONTACT FUNCTIONS
+ // * Still work to do in this area, and new functions to write
+
+ /**
+ * Create a contact
+ *
+ * @param array $attributes The attributes to set to the contact
+ * @return bool
+ */
+ public function create($attributes)
+ {
+ // Check for compulsory fields
+ if (!array_key_exists("display_name", $attributes)) { return "Missing compulsory field [display_name]"; }
+ if (!array_key_exists("email", $attributes)) { return "Missing compulsory field [email]"; }
+ if (!array_key_exists("container", $attributes)) { return "Missing compulsory field [container]"; }
+ if (!is_array($attributes["container"])) { return "Container attribute must be an array."; }
+
+ // Translate the schema
+ $add = $this->adldap->adldap_schema($attributes);
+
+ // Additional stuff only used for adding contacts
+ $add["cn"][0] = $attributes["display_name"];
+ $add["objectclass"][0] = "top";
+ $add["objectclass"][1] = "person";
+ $add["objectclass"][2] = "organizationalPerson";
+ $add["objectclass"][3] = "contact";
+ if (!isset($attributes['exchange_hidefromlists'])) {
+ $add["msExchHideFromAddressLists"][0] = "TRUE";
+ }
+
+ // Determine the container
+ $attributes["container"] = array_reverse($attributes["container"]);
+ $container= "OU=" . implode(",OU=", $attributes["container"]);
+
+ // Add the entry
+ $result = @ldap_add($this->adldap->getLdapConnection(), "CN=" . $this->adldap->utilities()->escapeCharacters($add["cn"][0]) . ", " . $container . "," . $this->adldap->getBaseDn(), $add);
+ if ($result != true) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Determine the list of groups a contact is a member of
+ *
+ * @param string $distinguisedname The full DN of a contact
+ * @param bool $recursive Recursively check groups
+ * @return array
+ */
+ public function groups($distinguishedName, $recursive = NULL)
+ {
+ if ($distinguishedName === NULL) { return false; }
+ if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it
+ if (!$this->adldap->getLdapBind()){ return false; }
+
+ // Search the directory for their information
+ $info = @$this->info($distinguishedName, array("memberof", "primarygroupid"));
+ $groups = $this->adldap->utilities()->niceNames($info[0]["memberof"]); //presuming the entry returned is our contact
+
+ if ($recursive === true){
+ foreach ($groups as $id => $groupName){
+ $extraGroups = $this->adldap->group()->recursiveGroups($groupName);
+ $groups = array_merge($groups, $extraGroups);
+ }
+ }
+
+ return $groups;
+ }
+
+ /**
+ * Get contact information. Returned in a raw array format from AD
+ *
+ * @param string $distinguisedname The full DN of a contact
+ * @param array $fields Attributes to be returned
+ * @return array
+ */
+ public function info($distinguishedName, $fields = NULL)
+ {
+ if ($distinguishedName === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ $filter = "distinguishedName=" . $distinguishedName;
+ if ($fields === NULL) {
+ $fields = array("distinguishedname", "mail", "memberof", "department", "displayname", "telephonenumber", "primarygroupid", "objectsid");
+ }
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ if ($entries[0]['count'] >= 1) {
+ // AD does not return the primary group in the ldap query, we may need to fudge it
+ if ($this->adldap->getRealPrimaryGroup() && isset($entries[0]["primarygroupid"][0]) && isset($entries[0]["primarygroupid"][0])){
+ //$entries[0]["memberof"][]=$this->group_cn($entries[0]["primarygroupid"][0]);
+ $entries[0]["memberof"][] = $this->adldap->group()->getPrimaryGroup($entries[0]["primarygroupid"][0], $entries[0]["objectsid"][0]);
+ } else {
+ $entries[0]["memberof"][] = "CN=Domain Users,CN=Users," . $this->adldap->getBaseDn();
+ }
+ }
+
+ $entries[0]["memberof"]["count"]++;
+ return $entries;
+ }
+
+ /**
+ * Find information about the contacts. Returned in a raw array format from AD
+ *
+ * @param string $distinguishedName The full DN of a contact
+ * @param array $fields Array of parameters to query
+ * @return mixed
+ */
+ public function infoCollection($distinguishedName, $fields = NULL)
+ {
+ if ($distinguishedName === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ $info = $this->info($distinguishedName, $fields);
+
+ if ($info !== false) {
+ $collection = new adLDAPContactCollection($info, $this->adldap);
+ return $collection;
+ }
+ return false;
+ }
+
+ /**
+ * Determine if a contact is a member of a group
+ *
+ * @param string $distinguisedName The full DN of a contact
+ * @param string $group The group name to query
+ * @param bool $recursive Recursively check groups
+ * @return bool
+ */
+ public function inGroup($distinguisedName, $group, $recursive = NULL)
+ {
+ if ($distinguisedName === NULL) { return false; }
+ if ($group === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+ if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it
+
+ // Get a list of the groups
+ $groups = $this->groups($distinguisedName, array("memberof"), $recursive);
+
+ // Return true if the specified group is in the group list
+ if (in_array($group, $groups)){
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Modify a contact
+ *
+ * @param string $distinguishedName The contact to query
+ * @param array $attributes The attributes to modify. Note if you set the enabled attribute you must not specify any other attributes
+ * @return bool
+ */
+ public function modify($distinguishedName, $attributes) {
+ if ($distinguishedName === NULL) { return "Missing compulsory field [distinguishedname]"; }
+
+ // Translate the update to the LDAP schema
+ $mod = $this->adldap->adldap_schema($attributes);
+
+ // Check to see if this is an enabled status update
+ if (!$mod) {
+ return false;
+ }
+
+ // Do the update
+ $result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod);
+ if ($result == false) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Delete a contact
+ *
+ * @param string $distinguishedName The contact dn to delete (please be careful here!)
+ * @return array
+ */
+ public function delete($distinguishedName)
+ {
+ $result = $this->folder()->delete($distinguishedName);
+ if ($result != true) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Return a list of all contacts
+ *
+ * @param bool $includeDescription Include a description of a contact
+ * @param string $search The search parameters
+ * @param bool $sorted Whether to sort the results
+ * @return array
+ */
+ public function all($includeDescription = false, $search = "*", $sorted = true) {
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ // Perform the search and grab all their details
+ $filter = "(&(objectClass=contact)(cn=" . $search . "))";
+ $fields = array("displayname","distinguishedname");
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ $usersArray = array();
+ for ($i=0; $i<$entries["count"]; $i++){
+ if ($includeDescription && strlen($entries[$i]["displayname"][0])>0){
+ $usersArray[$entries[$i]["distinguishedname"][0]] = $entries[$i]["displayname"][0];
+ } elseif ($includeDescription){
+ $usersArray[$entries[$i]["distinguishedname"][0]] = $entries[$i]["distinguishedname"][0];
+ } else {
+ array_push($usersArray, $entries[$i]["distinguishedname"][0]);
+ }
+ }
+ if ($sorted) {
+ asort($usersArray);
+ }
+ return $usersArray;
+ }
+
+ /**
+ * Mail enable a contact
+ * Allows email to be sent to them through Exchange
+ *
+ * @param string $distinguishedname The contact to mail enable
+ * @param string $emailaddress The email address to allow emails to be sent through
+ * @param string $mailnickname The mailnickname for the contact in Exchange. If NULL this will be set to the display name
+ * @return bool
+ */
+ public function contactMailEnable($distinguishedName, $emailAddress, $mailNickname = NULL){
+ return $this->adldap->exchange()->contactMailEnable($distinguishedName, $emailAddress, $mailNickname);
+ }
+
+
+}
+?>
diff --git a/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPExchange.php b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPExchange.php
new file mode 100644
index 0000000..d70aac7
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPExchange.php
@@ -0,0 +1,390 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage Exchange
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+ */
+require_once(dirname(__FILE__) . '/../adLDAP.php');
+
+/**
+* MICROSOFT EXCHANGE FUNCTIONS
+*/
+class adLDAPExchange {
+ /**
+ * The current adLDAP connection via dependency injection
+ *
+ * @var adLDAP
+ */
+ protected $adldap;
+
+ public function __construct(adLDAP $adldap) {
+ $this->adldap = $adldap;
+ }
+
+ /**
+ * Create an Exchange account
+ *
+ * @param string $username The username of the user to add the Exchange account to
+ * @param array $storageGroup The mailbox, Exchange Storage Group, for the user account, this must be a full CN
+ * If the storage group has a different base_dn to the adLDAP configuration, set it using $base_dn
+ * @param string $emailAddress The primary email address to add to this user
+ * @param string $mailNickname The mail nick name. If mail nickname is blank, the username will be used
+ * @param bool $mdbUseDefaults Indicates whether the store should use the default quota, rather than the per-mailbox quota.
+ * @param string $baseDn Specify an alternative base_dn for the Exchange storage group
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function createMailbox($username, $storageGroup, $emailAddress, $mailNickname=NULL, $useDefaults=TRUE, $baseDn=NULL, $isGUID=false)
+ {
+ if ($username === NULL){ return "Missing compulsory field [username]"; }
+ if ($storageGroup === NULL) { return "Missing compulsory array [storagegroup]"; }
+ if (!is_array($storageGroup)) { return "[storagegroup] must be an array"; }
+ if ($emailAddress === NULL) { return "Missing compulsory field [emailAddress]"; }
+
+ if ($baseDn === NULL) {
+ $baseDn = $this->adldap->getBaseDn();
+ }
+
+ $container = "CN=" . implode(",CN=", $storageGroup);
+
+ if ($mailNickname === NULL) {
+ $mailNickname = $username;
+ }
+ $mdbUseDefaults = $this->adldap->utilities()->boolToString($useDefaults);
+
+ $attributes = array(
+ 'exchange_homemdb'=>$container.",".$baseDn,
+ 'exchange_proxyaddress'=>'SMTP:' . $emailAddress,
+ 'exchange_mailnickname'=>$mailNickname,
+ 'exchange_usedefaults'=>$mdbUseDefaults
+ );
+ $result = $this->adldap->user()->modify($username, $attributes, $isGUID);
+ if ($result == false) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Add an X400 address to Exchange
+ * See http://tools.ietf.org/html/rfc1685 for more information.
+ * An X400 Address looks similar to this X400:c=US;a= ;p=Domain;o=Organization;s=Doe;g=John;
+ *
+ * @param string $username The username of the user to add the X400 to to
+ * @param string $country Country
+ * @param string $admd Administration Management Domain
+ * @param string $pdmd Private Management Domain (often your AD domain)
+ * @param string $org Organization
+ * @param string $surname Surname
+ * @param string $givenName Given name
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function addX400($username, $country, $admd, $pdmd, $org, $surname, $givenName, $isGUID=false)
+ {
+ if ($username === NULL){ return "Missing compulsory field [username]"; }
+
+ $proxyValue = 'X400:';
+
+ // Find the dn of the user
+ $user = $this->adldap->user()->info($username, array("cn","proxyaddresses"), $isGUID);
+ if ($user[0]["dn"] === NULL) { return false; }
+ $userDn = $user[0]["dn"];
+
+ // We do not have to demote an email address from the default so we can just add the new proxy address
+ $attributes['exchange_proxyaddress'] = $proxyValue . 'c=' . $country . ';a=' . $admd . ';p=' . $pdmd . ';o=' . $org . ';s=' . $surname . ';g=' . $givenName . ';';
+
+ // Translate the update to the LDAP schema
+ $add = $this->adldap->adldap_schema($attributes);
+
+ if (!$add) { return false; }
+
+ // Do the update
+ // Take out the @ to see any errors, usually this error might occur because the address already
+ // exists in the list of proxyAddresses
+ $result = @ldap_mod_add($this->adldap->getLdapConnection(), $userDn, $add);
+ if ($result == false) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Add an address to Exchange
+ *
+ * @param string $username The username of the user to add the Exchange account to
+ * @param string $emailAddress The email address to add to this user
+ * @param bool $default Make this email address the default address, this is a bit more intensive as we have to demote any existing default addresses
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function addAddress($username, $emailAddress, $default = FALSE, $isGUID = false)
+ {
+ if ($username === NULL) { return "Missing compulsory field [username]"; }
+ if ($emailAddress === NULL) { return "Missing compulsory fields [emailAddress]"; }
+
+ $proxyValue = 'smtp:';
+ if ($default === true) {
+ $proxyValue = 'SMTP:';
+ }
+
+ // Find the dn of the user
+ $user = $this->adldap->user()->info($username, array("cn","proxyaddresses"), $isGUID);
+ if ($user[0]["dn"] === NULL){ return false; }
+ $userDn = $user[0]["dn"];
+
+ // We need to scan existing proxy addresses and demote the default one
+ if (is_array($user[0]["proxyaddresses"]) && $default === true) {
+ $modAddresses = array();
+ for ($i=0;$i<sizeof($user[0]['proxyaddresses']);$i++) {
+ if (strstr($user[0]['proxyaddresses'][$i], 'SMTP:') !== false) {
+ $user[0]['proxyaddresses'][$i] = str_replace('SMTP:', 'smtp:', $user[0]['proxyaddresses'][$i]);
+ }
+ if ($user[0]['proxyaddresses'][$i] != '') {
+ $modAddresses['proxyAddresses'][$i] = $user[0]['proxyaddresses'][$i];
+ }
+ }
+ $modAddresses['proxyAddresses'][(sizeof($user[0]['proxyaddresses'])-1)] = 'SMTP:' . $emailAddress;
+
+ $result = @ldap_mod_replace($this->adldap->getLdapConnection(), $userDn, $modAddresses);
+ if ($result == false) {
+ return false;
+ }
+
+ return true;
+ }
+ else {
+ // We do not have to demote an email address from the default so we can just add the new proxy address
+ $attributes['exchange_proxyaddress'] = $proxyValue . $emailAddress;
+
+ // Translate the update to the LDAP schema
+ $add = $this->adldap->adldap_schema($attributes);
+
+ if (!$add) {
+ return false;
+ }
+
+ // Do the update
+ // Take out the @ to see any errors, usually this error might occur because the address already
+ // exists in the list of proxyAddresses
+ $result = @ldap_mod_add($this->adldap->getLdapConnection(), $userDn,$add);
+ if ($result == false) {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ /**
+ * Remove an address to Exchange
+ * If you remove a default address the account will no longer have a default,
+ * we recommend changing the default address first
+ *
+ * @param string $username The username of the user to add the Exchange account to
+ * @param string $emailAddress The email address to add to this user
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function deleteAddress($username, $emailAddress, $isGUID=false)
+ {
+ if ($username === NULL) { return "Missing compulsory field [username]"; }
+ if ($emailAddress === NULL) { return "Missing compulsory fields [emailAddress]"; }
+
+ // Find the dn of the user
+ $user = $this->adldap->user()->info($username, array("cn","proxyaddresses"), $isGUID);
+ if ($user[0]["dn"] === NULL) { return false; }
+ $userDn = $user[0]["dn"];
+
+ if (is_array($user[0]["proxyaddresses"])) {
+ $mod = array();
+ for ($i=0;$i<sizeof($user[0]['proxyaddresses']);$i++) {
+ if (strstr($user[0]['proxyaddresses'][$i], 'SMTP:') !== false && $user[0]['proxyaddresses'][$i] == 'SMTP:' . $emailAddress) {
+ $mod['proxyAddresses'][0] = 'SMTP:' . $emailAddress;
+ }
+ elseif (strstr($user[0]['proxyaddresses'][$i], 'smtp:') !== false && $user[0]['proxyaddresses'][$i] == 'smtp:' . $emailAddress) {
+ $mod['proxyAddresses'][0] = 'smtp:' . $emailAddress;
+ }
+ }
+
+ $result = @ldap_mod_del($this->adldap->getLdapConnection(), $userDn,$mod);
+ if ($result == false) {
+ return false;
+ }
+
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+ /**
+ * Change the default address
+ *
+ * @param string $username The username of the user to add the Exchange account to
+ * @param string $emailAddress The email address to make default
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function primaryAddress($username, $emailAddress, $isGUID = false)
+ {
+ if ($username === NULL) { return "Missing compulsory field [username]"; }
+ if ($emailAddress === NULL) { return "Missing compulsory fields [emailAddress]"; }
+
+ // Find the dn of the user
+ $user = $this->adldap->user()->info($username, array("cn","proxyaddresses"), $isGUID);
+ if ($user[0]["dn"] === NULL){ return false; }
+ $userDn = $user[0]["dn"];
+
+ if (is_array($user[0]["proxyaddresses"])) {
+ $modAddresses = array();
+ for ($i=0;$i<sizeof($user[0]['proxyaddresses']);$i++) {
+ if (strstr($user[0]['proxyaddresses'][$i], 'SMTP:') !== false) {
+ $user[0]['proxyaddresses'][$i] = str_replace('SMTP:', 'smtp:', $user[0]['proxyaddresses'][$i]);
+ }
+ if ($user[0]['proxyaddresses'][$i] == 'smtp:' . $emailAddress) {
+ $user[0]['proxyaddresses'][$i] = str_replace('smtp:', 'SMTP:', $user[0]['proxyaddresses'][$i]);
+ }
+ if ($user[0]['proxyaddresses'][$i] != '') {
+ $modAddresses['proxyAddresses'][$i] = $user[0]['proxyaddresses'][$i];
+ }
+ }
+
+ $result = @ldap_mod_replace($this->adldap->getLdapConnection(), $userDn, $modAddresses);
+ if ($result == false) {
+ return false;
+ }
+
+ return true;
+ }
+
+ }
+
+ /**
+ * Mail enable a contact
+ * Allows email to be sent to them through Exchange
+ *
+ * @param string $distinguishedName The contact to mail enable
+ * @param string $emailAddress The email address to allow emails to be sent through
+ * @param string $mailNickname The mailnickname for the contact in Exchange. If NULL this will be set to the display name
+ * @return bool
+ */
+ public function contactMailEnable($distinguishedName, $emailAddress, $mailNickname = NULL)
+ {
+ if ($distinguishedName === NULL) { return "Missing compulsory field [distinguishedName]"; }
+ if ($emailAddress === NULL) { return "Missing compulsory field [emailAddress]"; }
+
+ if ($mailNickname !== NULL) {
+ // Find the dn of the user
+ $user = $this->adldap->contact()->info($distinguishedName, array("cn","displayname"));
+ if ($user[0]["displayname"] === NULL) { return false; }
+ $mailNickname = $user[0]['displayname'][0];
+ }
+
+ $attributes = array("email"=>$emailAddress,"contact_email"=>"SMTP:" . $emailAddress,"exchange_proxyaddress"=>"SMTP:" . $emailAddress,"exchange_mailnickname" => $mailNickname);
+
+ // Translate the update to the LDAP schema
+ $mod = $this->adldap->adldap_schema($attributes);
+
+ // Check to see if this is an enabled status update
+ if (!$mod) { return false; }
+
+ // Do the update
+ $result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod);
+ if ($result == false) { return false; }
+
+ return true;
+ }
+
+ /**
+ * Returns a list of Exchange Servers in the ConfigurationNamingContext of the domain
+ *
+ * @param array $attributes An array of the AD attributes you wish to return
+ * @return array
+ */
+ public function servers($attributes = array('cn','distinguishedname','serialnumber'))
+ {
+ if (!$this->adldap->getLdapBind()){ return false; }
+
+ $configurationNamingContext = $this->adldap->getRootDse(array('configurationnamingcontext'));
+ $sr = @ldap_search($this->adldap->getLdapConnection(), $configurationNamingContext[0]['configurationnamingcontext'][0],'(&(objectCategory=msExchExchangeServer))', $attributes);
+ $entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+ return $entries;
+ }
+
+ /**
+ * Returns a list of Storage Groups in Exchange for a given mail server
+ *
+ * @param string $exchangeServer The full DN of an Exchange server. You can use exchange_servers() to find the DN for your server
+ * @param array $attributes An array of the AD attributes you wish to return
+ * @param bool $recursive If enabled this will automatically query the databases within a storage group
+ * @return array
+ */
+ public function storageGroups($exchangeServer, $attributes = array('cn','distinguishedname'), $recursive = NULL)
+ {
+ if (!$this->adldap->getLdapBind()){ return false; }
+ if ($exchangeServer === NULL) { return "Missing compulsory field [exchangeServer]"; }
+ if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); }
+
+ $filter = '(&(objectCategory=msExchStorageGroup))';
+ $sr = @ldap_search($this->adldap->getLdapConnection(), $exchangeServer, $filter, $attributes);
+ $entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ if ($recursive === true) {
+ for ($i=0; $i<$entries['count']; $i++) {
+ $entries[$i]['msexchprivatemdb'] = $this->storageDatabases($entries[$i]['distinguishedname'][0]);
+ }
+ }
+
+ return $entries;
+ }
+
+ /**
+ * Returns a list of Databases within any given storage group in Exchange for a given mail server
+ *
+ * @param string $storageGroup The full DN of an Storage Group. You can use exchange_storage_groups() to find the DN
+ * @param array $attributes An array of the AD attributes you wish to return
+ * @return array
+ */
+ public function storageDatabases($storageGroup, $attributes = array('cn','distinguishedname','displayname')) {
+ if (!$this->adldap->getLdapBind()){ return false; }
+ if ($storageGroup === NULL) { return "Missing compulsory field [storageGroup]"; }
+
+ $filter = '(&(objectCategory=msExchPrivateMDB))';
+ $sr = @ldap_search($this->adldap->getLdapConnection(), $storageGroup, $filter, $attributes);
+ $entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+ return $entries;
+ }
+}
+?> \ No newline at end of file
diff --git a/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPFolders.php b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPFolders.php
new file mode 100644
index 0000000..67b1474
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPFolders.php
@@ -0,0 +1,179 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage Folders
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+ */
+require_once(dirname(__FILE__) . '/../adLDAP.php');
+
+/**
+* FOLDER / OU MANAGEMENT FUNCTIONS
+*/
+class adLDAPFolders {
+ /**
+ * The current adLDAP connection via dependency injection
+ *
+ * @var adLDAP
+ */
+ protected $adldap;
+
+ public function __construct(adLDAP $adldap) {
+ $this->adldap = $adldap;
+ }
+
+ /**
+ * Delete a distinguished name from Active Directory
+ * You should never need to call this yourself, just use the wrapper functions user_delete and contact_delete
+ *
+ * @param string $dn The distinguished name to delete
+ * @return bool
+ */
+ public function delete($dn){
+ $result = ldap_delete($this->adldap->getLdapConnection(), $dn);
+ if ($result != true) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Returns a folder listing for a specific OU
+ * See http://adldap.sourceforge.net/wiki/doku.php?id=api_folder_functions
+ *
+ * @param array $folderName An array to the OU you wish to list.
+ * If set to NULL will list the root, strongly recommended to set
+ * $recursive to false in that instance!
+ * @param string $dnType The type of record to list. This can be ADLDAP_FOLDER or ADLDAP_CONTAINER.
+ * @param bool $recursive Recursively search sub folders
+ * @param bool $type Specify a type of object to search for
+ * @return array
+ */
+ public function listing($folderName = NULL, $dnType = adLDAP::ADLDAP_FOLDER, $recursive = NULL, $type = NULL)
+ {
+ if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ $filter = '(&';
+ if ($type !== NULL) {
+ switch ($type) {
+ case 'contact':
+ $filter .= '(objectClass=contact)';
+ break;
+ case 'computer':
+ $filter .= '(objectClass=computer)';
+ break;
+ case 'group':
+ $filter .= '(objectClass=group)';
+ break;
+ case 'folder':
+ $filter .= '(objectClass=organizationalUnit)';
+ break;
+ case 'container':
+ $filter .= '(objectClass=container)';
+ break;
+ case 'domain':
+ $filter .= '(objectClass=builtinDomain)';
+ break;
+ default:
+ $filter .= '(objectClass=user)';
+ break;
+ }
+ }
+ else {
+ $filter .= '(objectClass=*)';
+ }
+ // If the folder name is null then we will search the root level of AD
+ // This requires us to not have an OU= part, just the base_dn
+ $searchOu = $this->adldap->getBaseDn();
+ if (is_array($folderName)) {
+ $ou = $dnType . "=" . implode("," . $dnType . "=", $folderName);
+ $filter .= '(!(distinguishedname=' . $ou . ',' . $this->adldap->getBaseDn() . ')))';
+ $searchOu = $ou . ',' . $this->adldap->getBaseDn();
+ }
+ else {
+ $filter .= '(!(distinguishedname=' . $this->adldap->getBaseDn() . ')))';
+ }
+
+ if ($recursive === true) {
+ $sr = ldap_search($this->adldap->getLdapConnection(), $searchOu, $filter, array('objectclass', 'distinguishedname', 'samaccountname'));
+ $entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+ if (is_array($entries)) {
+ return $entries;
+ }
+ }
+ else {
+ $sr = ldap_list($this->adldap->getLdapConnection(), $searchOu, $filter, array('objectclass', 'distinguishedname', 'samaccountname'));
+ $entries = @ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+ if (is_array($entries)) {
+ return $entries;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Create an organizational unit
+ *
+ * @param array $attributes Default attributes of the ou
+ * @return bool
+ */
+ public function create($attributes)
+ {
+ if (!is_array($attributes)){ return "Attributes must be an array"; }
+ if (!is_array($attributes["container"])) { return "Container attribute must be an array."; }
+ if (!array_key_exists("ou_name",$attributes)) { return "Missing compulsory field [ou_name]"; }
+ if (!array_key_exists("container",$attributes)) { return "Missing compulsory field [container]"; }
+
+ $attributes["container"] = array_reverse($attributes["container"]);
+
+ $add=array();
+ $add["objectClass"] = "organizationalUnit";
+ $add["OU"] = $attributes['ou_name'];
+ $containers = "";
+ if (count($attributes['container']) > 0) {
+ $containers = "OU=" . implode(",OU=", $attributes["container"]) . ",";
+ }
+
+ $containers = "OU=" . implode(",OU=", $attributes["container"]);
+ $result = ldap_add($this->adldap->getLdapConnection(), "OU=" . $add["OU"] . ", " . $containers . $this->adldap->getBaseDn(), $add);
+ if ($result != true) {
+ return false;
+ }
+
+ return true;
+ }
+
+}
+
+?> \ No newline at end of file
diff --git a/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPGroups.php b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPGroups.php
new file mode 100644
index 0000000..94bc048
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPGroups.php
@@ -0,0 +1,631 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage Groups
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+ */
+require_once(dirname(__FILE__) . '/../adLDAP.php');
+require_once(dirname(__FILE__) . '/../collections/adLDAPGroupCollection.php');
+
+/**
+* GROUP FUNCTIONS
+*/
+class adLDAPGroups {
+ /**
+ * The current adLDAP connection via dependency injection
+ *
+ * @var adLDAP
+ */
+ protected $adldap;
+
+ public function __construct(adLDAP $adldap) {
+ $this->adldap = $adldap;
+ }
+
+ /**
+ * Add a group to a group
+ *
+ * @param string $parent The parent group name
+ * @param string $child The child group name
+ * @return bool
+ */
+ public function addGroup($parent,$child){
+
+ // Find the parent group's dn
+ $parentGroup = $this->ginfo($parent, array("cn"));
+ if ($parentGroup[0]["dn"] === NULL){
+ return false;
+ }
+ $parentDn = $parentGroup[0]["dn"];
+
+ // Find the child group's dn
+ $childGroup = $this->info($child, array("cn"));
+ if ($childGroup[0]["dn"] === NULL){
+ return false;
+ }
+ $childDn = $childGroup[0]["dn"];
+
+ $add = array();
+ $add["member"] = $childDn;
+
+ $result = @ldap_mod_add($this->adldap->getLdapConnection(), $parentDn, $add);
+ if ($result == false) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Add a user to a group
+ *
+ * @param string $group The group to add the user to
+ * @param string $user The user to add to the group
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function addUser($group, $user, $isGUID = false)
+ {
+ // Adding a user is a bit fiddly, we need to get the full DN of the user
+ // and add it using the full DN of the group
+
+ // Find the user's dn
+ $userDn = $this->adldap->user()->dn($user, $isGUID);
+ if ($userDn === false) {
+ return false;
+ }
+
+ // Find the group's dn
+ $groupInfo = $this->info($group, array("cn"));
+ if ($groupInfo[0]["dn"] === NULL) {
+ return false;
+ }
+ $groupDn = $groupInfo[0]["dn"];
+
+ $add = array();
+ $add["member"] = $userDn;
+
+ $result = @ldap_mod_add($this->adldap->getLdapConnection(), $groupDn, $add);
+ if ($result == false) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Add a contact to a group
+ *
+ * @param string $group The group to add the contact to
+ * @param string $contactDn The DN of the contact to add
+ * @return bool
+ */
+ public function addContact($group, $contactDn)
+ {
+ // To add a contact we take the contact's DN
+ // and add it using the full DN of the group
+
+ // Find the group's dn
+ $groupInfo = $this->info($group, array("cn"));
+ if ($groupInfo[0]["dn"] === NULL) {
+ return false;
+ }
+ $groupDn = $groupInfo[0]["dn"];
+
+ $add = array();
+ $add["member"] = $contactDn;
+
+ $result = @ldap_mod_add($this->adldap->getLdapConnection(), $groupDn, $add);
+ if ($result == false) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Create a group
+ *
+ * @param array $attributes Default attributes of the group
+ * @return bool
+ */
+ public function create($attributes)
+ {
+ if (!is_array($attributes)){ return "Attributes must be an array"; }
+ if (!array_key_exists("group_name", $attributes)){ return "Missing compulsory field [group_name]"; }
+ if (!array_key_exists("container", $attributes)){ return "Missing compulsory field [container]"; }
+ if (!array_key_exists("description", $attributes)){ return "Missing compulsory field [description]"; }
+ if (!is_array($attributes["container"])){ return "Container attribute must be an array."; }
+ $attributes["container"] = array_reverse($attributes["container"]);
+
+ //$member_array = array();
+ //$member_array[0] = "cn=user1,cn=Users,dc=yourdomain,dc=com";
+ //$member_array[1] = "cn=administrator,cn=Users,dc=yourdomain,dc=com";
+
+ $add = array();
+ $add["cn"] = $attributes["group_name"];
+ $add["samaccountname"] = $attributes["group_name"];
+ $add["objectClass"] = "Group";
+ $add["description"] = $attributes["description"];
+ //$add["member"] = $member_array; UNTESTED
+
+ $container = "OU=" . implode(",OU=", $attributes["container"]);
+ $result = ldap_add($this->adldap->getLdapConnection(), "CN=" . $add["cn"] . ", " . $container . "," . $this->adldap->getBaseDn(), $add);
+ if ($result != true) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Delete a group account
+ *
+ * @param string $group The group to delete (please be careful here!)
+ *
+ * @return array
+ */
+ public function delete($group) {
+ if (!$this->adldap->getLdapBind()){ return false; }
+ if ($group === null){ return "Missing compulsory field [group]"; }
+
+ $groupInfo = $this->info($group, array("*"));
+ $dn = $groupInfo[0]['distinguishedname'][0];
+ $result = $this->adldap->folder()->delete($dn);
+ if ($result !== true) {
+ return false;
+ } return true;
+ }
+
+ /**
+ * Remove a group from a group
+ *
+ * @param string $parent The parent group name
+ * @param string $child The child group name
+ * @return bool
+ */
+ public function removeGroup($parent , $child)
+ {
+
+ // Find the parent dn
+ $parentGroup = $this->info($parent, array("cn"));
+ if ($parentGroup[0]["dn"] === NULL) {
+ return false;
+ }
+ $parentDn = $parentGroup[0]["dn"];
+
+ // Find the child dn
+ $childGroup = $this->info($child, array("cn"));
+ if ($childGroup[0]["dn"] === NULL) {
+ return false;
+ }
+ $childDn = $childGroup[0]["dn"];
+
+ $del = array();
+ $del["member"] = $childDn;
+
+ $result = @ldap_mod_del($this->adldap->getLdapConnection(), $parentDn, $del);
+ if ($result == false) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Remove a user from a group
+ *
+ * @param string $group The group to remove a user from
+ * @param string $user The AD user to remove from the group
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function removeUser($group, $user, $isGUID = false)
+ {
+
+ // Find the parent dn
+ $groupInfo = $this->info($group, array("cn"));
+ if ($groupInfo[0]["dn"] === NULL){
+ return false;
+ }
+ $groupDn = $groupInfo[0]["dn"];
+
+ // Find the users dn
+ $userDn = $this->adldap->user()->dn($user, $isGUID);
+ if ($userDn === false) {
+ return false;
+ }
+
+ $del = array();
+ $del["member"] = $userDn;
+
+ $result = @ldap_mod_del($this->adldap->getLdapConnection(), $groupDn, $del);
+ if ($result == false) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Remove a contact from a group
+ *
+ * @param string $group The group to remove a user from
+ * @param string $contactDn The DN of a contact to remove from the group
+ * @return bool
+ */
+ public function removeContact($group, $contactDn)
+ {
+
+ // Find the parent dn
+ $groupInfo = $this->info($group, array("cn"));
+ if ($groupInfo[0]["dn"] === NULL) {
+ return false;
+ }
+ $groupDn = $groupInfo[0]["dn"];
+
+ $del = array();
+ $del["member"] = $contactDn;
+
+ $result = @ldap_mod_del($this->adldap->getLdapConnection(), $groupDn, $del);
+ if ($result == false) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Return a list of groups in a group
+ *
+ * @param string $group The group to query
+ * @param bool $recursive Recursively get groups
+ * @return array
+ */
+ public function inGroup($group, $recursive = NULL)
+ {
+ if (!$this->adldap->getLdapBind()){ return false; }
+ if ($recursive === NULL){ $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it
+
+ // Search the directory for the members of a group
+ $info = $this->info($group, array("member","cn"));
+ $groups = $info[0]["member"];
+ if (!is_array($groups)) {
+ return false;
+ }
+
+ $groupArray = array();
+
+ for ($i=0; $i<$groups["count"]; $i++){
+ $filter = "(&(objectCategory=group)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($groups[$i]) . "))";
+ $fields = array("samaccountname", "distinguishedname", "objectClass");
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ // not a person, look for a group
+ if ($entries['count'] == 0 && $recursive == true) {
+ $filter = "(&(objectCategory=group)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($groups[$i]) . "))";
+ $fields = array("distinguishedname");
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+ if (!isset($entries[0]['distinguishedname'][0])) {
+ continue;
+ }
+ $subGroups = $this->inGroup($entries[0]['distinguishedname'][0], $recursive);
+ if (is_array($subGroups)) {
+ $groupArray = array_merge($groupArray, $subGroups);
+ $groupArray = array_unique($groupArray);
+ }
+ continue;
+ }
+
+ $groupArray[] = $entries[0]['distinguishedname'][0];
+ }
+ return $groupArray;
+ }
+
+ /**
+ * Return a list of members in a group
+ *
+ * @param string $group The group to query
+ * @param bool $recursive Recursively get group members
+ * @return array
+ */
+ public function members($group, $recursive = NULL)
+ {
+ if (!$this->adldap->getLdapBind()){ return false; }
+ if ($recursive === NULL){ $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it
+ // Search the directory for the members of a group
+ $info = $this->info($group, array("member","cn"));
+ $users = $info[0]["member"];
+ if (!is_array($users)) {
+ return false;
+ }
+
+ $userArray = array();
+
+ for ($i=0; $i<$users["count"]; $i++){
+ $filter = "(&(objectCategory=person)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($users[$i]) . "))";
+ $fields = array("samaccountname", "distinguishedname", "objectClass");
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ // not a person, look for a group
+ if ($entries['count'] == 0 && $recursive == true) {
+ $filter = "(&(objectCategory=group)(distinguishedName=" . $this->adldap->utilities()->ldapSlashes($users[$i]) . "))";
+ $fields = array("samaccountname");
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+ if (!isset($entries[0]['samaccountname'][0])) {
+ continue;
+ }
+ $subUsers = $this->members($entries[0]['samaccountname'][0], $recursive);
+ if (is_array($subUsers)) {
+ $userArray = array_merge($userArray, $subUsers);
+ $userArray = array_unique($userArray);
+ }
+ continue;
+ }
+ else if ($entries['count'] == 0) {
+ continue;
+ }
+
+ if ((!isset($entries[0]['samaccountname'][0]) || $entries[0]['samaccountname'][0] === NULL) && $entries[0]['distinguishedname'][0] !== NULL) {
+ $userArray[] = $entries[0]['distinguishedname'][0];
+ }
+ else if ($entries[0]['samaccountname'][0] !== NULL) {
+ $userArray[] = $entries[0]['samaccountname'][0];
+ }
+ }
+ return $userArray;
+ }
+
+ /**
+ * Group Information. Returns an array of raw information about a group.
+ * The group name is case sensitive
+ *
+ * @param string $groupName The group name to retrieve info about
+ * @param array $fields Fields to retrieve
+ * @return array
+ */
+ public function info($groupName, $fields = NULL)
+ {
+ if ($groupName === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ if (stristr($groupName, '+')) {
+ $groupName = stripslashes($groupName);
+ }
+
+ $filter = "(&(objectCategory=group)(name=" . $this->adldap->utilities()->ldapSlashes($groupName) . "))";
+ if ($fields === NULL) {
+ $fields = array("member","memberof","cn","description","distinguishedname","objectcategory","samaccountname");
+ }
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ return $entries;
+ }
+
+ /**
+ * Group Information. Returns an collection
+ * The group name is case sensitive
+ *
+ * @param string $groupName The group name to retrieve info about
+ * @param array $fields Fields to retrieve
+ * @return adLDAPGroupCollection
+ */
+ public function infoCollection($groupName, $fields = NULL)
+ {
+ if ($groupName === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ $info = $this->info($groupName, $fields);
+ if ($info !== false) {
+ $collection = new adLDAPGroupCollection($info, $this->adldap);
+ return $collection;
+ }
+ return false;
+ }
+
+ /**
+ * Return a complete list of "groups in groups"
+ *
+ * @param string $group The group to get the list from
+ * @return array
+ */
+ public function recursiveGroups($group)
+ {
+ if ($group === NULL) { return false; }
+
+ $stack = array();
+ $processed = array();
+ $retGroups = array();
+
+ array_push($stack, $group); // Initial Group to Start with
+ while (count($stack) > 0) {
+ $parent = array_pop($stack);
+ array_push($processed, $parent);
+
+ $info = $this->info($parent, array("memberof"));
+
+ if (isset($info[0]["memberof"]) && is_array($info[0]["memberof"])) {
+ $groups = $info[0]["memberof"];
+ if ($groups) {
+ $groupNames = $this->adldap->utilities()->niceNames($groups);
+ $retGroups = array_merge($retGroups, $groupNames); //final groups to return
+ foreach ($groupNames as $id => $groupName) {
+ if (!in_array($groupName, $processed)) {
+ array_push($stack, $groupName);
+ }
+ }
+ }
+ }
+ }
+
+ return $retGroups;
+ }
+
+ /**
+ * Returns a complete list of the groups in AD based on a SAM Account Type
+ *
+ * @param string $sAMAaccountType The account type to return
+ * @param bool $includeDescription Whether to return a description
+ * @param string $search Search parameters
+ * @param bool $sorted Whether to sort the results
+ * @return array
+ */
+ public function search($sAMAaccountType = adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP, $includeDescription = false, $search = "*", $sorted = true) {
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ $filter = '(&(objectCategory=group)';
+ if ($sAMAaccountType !== null) {
+ $filter .= '(samaccounttype='. $sAMAaccountType .')';
+ }
+ $filter .= '(cn=' . $search . '))';
+ // Perform the search and grab all their details
+ $fields = array("samaccountname", "description");
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ $groupsArray = array();
+ for ($i=0; $i<$entries["count"]; $i++){
+ if ($includeDescription && strlen($entries[$i]["description"][0]) > 0 ) {
+ $groupsArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["description"][0];
+ }
+ else if ($includeDescription){
+ $groupsArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["samaccountname"][0];
+ }
+ else {
+ array_push($groupsArray, $entries[$i]["samaccountname"][0]);
+ }
+ }
+ if ($sorted) {
+ asort($groupsArray);
+ }
+ return $groupsArray;
+ }
+
+ /**
+ * Returns a complete list of all groups in AD
+ *
+ * @param bool $includeDescription Whether to return a description
+ * @param string $search Search parameters
+ * @param bool $sorted Whether to sort the results
+ * @return array
+ */
+ public function all($includeDescription = false, $search = "*", $sorted = true){
+ $groupsArray = $this->search(null, $includeDescription, $search, $sorted);
+ return $groupsArray;
+ }
+
+ /**
+ * Returns a complete list of security groups in AD
+ *
+ * @param bool $includeDescription Whether to return a description
+ * @param string $search Search parameters
+ * @param bool $sorted Whether to sort the results
+ * @return array
+ */
+ public function allSecurity($includeDescription = false, $search = "*", $sorted = true){
+ $groupsArray = $this->search(adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP, $includeDescription, $search, $sorted);
+ return $groupsArray;
+ }
+
+ /**
+ * Returns a complete list of distribution lists in AD
+ *
+ * @param bool $includeDescription Whether to return a description
+ * @param string $search Search parameters
+ * @param bool $sorted Whether to sort the results
+ * @return array
+ */
+ public function allDistribution($includeDescription = false, $search = "*", $sorted = true){
+ $groupsArray = $this->search(adLDAP::ADLDAP_DISTRIBUTION_GROUP, $includeDescription, $search, $sorted);
+ return $groupsArray;
+ }
+
+ /**
+ * Coping with AD not returning the primary group
+ * http://support.microsoft.com/?kbid=321360
+ *
+ * This is a re-write based on code submitted by Bruce which prevents the
+ * need to search each security group to find the true primary group
+ *
+ * @param string $gid Group ID
+ * @param string $usersid User's Object SID
+ * @return mixed
+ */
+ public function getPrimaryGroup($gid, $usersid)
+ {
+ if ($gid === NULL || $usersid === NULL) { return false; }
+ $sr = false;
+
+ $gsid = substr_replace($usersid, pack('V',$gid), strlen($usersid)-4,4);
+ $filter = '(objectsid=' . $this->adldap->utilities()->getTextSID($gsid).')';
+ $fields = array("samaccountname","distinguishedname");
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ if (isset($entries[0]['distinguishedname'][0])) {
+ return $entries[0]['distinguishedname'][0];
+ }
+ return false;
+ }
+
+ /**
+ * Coping with AD not returning the primary group
+ * http://support.microsoft.com/?kbid=321360
+ *
+ * For some reason it's not possible to search on primarygrouptoken=XXX
+ * If someone can show otherwise, I'd like to know about it :)
+ * this way is resource intensive and generally a pain in the @#%^
+ *
+ * @deprecated deprecated since version 3.1, see get get_primary_group
+ * @param string $gid Group ID
+ * @return string
+ */
+ public function cn($gid){
+ if ($gid === NULL) { return false; }
+ $sr = false;
+ $r = '';
+
+ $filter = "(&(objectCategory=group)(samaccounttype=" . adLDAP::ADLDAP_SECURITY_GLOBAL_GROUP . "))";
+ $fields = array("primarygrouptoken", "samaccountname", "distinguishedname");
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ for ($i=0; $i<$entries["count"]; $i++){
+ if ($entries[$i]["primarygrouptoken"][0] == $gid) {
+ $r = $entries[$i]["distinguishedname"][0];
+ $i = $entries["count"];
+ }
+ }
+
+ return $r;
+ }
+}
+?>
diff --git a/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPUsers.php b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPUsers.php
new file mode 100644
index 0000000..dc3ebd7
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPUsers.php
@@ -0,0 +1,682 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage User
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+ */
+require_once(dirname(__FILE__) . '/../adLDAP.php');
+require_once(dirname(__FILE__) . '/../collections/adLDAPUserCollection.php');
+
+/**
+* USER FUNCTIONS
+*/
+class adLDAPUsers {
+ /**
+ * The current adLDAP connection via dependency injection
+ *
+ * @var adLDAP
+ */
+ protected $adldap;
+
+ public function __construct(adLDAP $adldap) {
+ $this->adldap = $adldap;
+ }
+
+ /**
+ * Validate a user's login credentials
+ *
+ * @param string $username A user's AD username
+ * @param string $password A user's AD password
+ * @param bool optional $prevent_rebind
+ * @return bool
+ */
+ public function authenticate($username, $password, $preventRebind = false) {
+ return $this->adldap->authenticate($username, $password, $preventRebind);
+ }
+
+ /**
+ * Create a user
+ *
+ * If you specify a password here, this can only be performed over SSL
+ *
+ * @param array $attributes The attributes to set to the user account
+ * @return bool
+ */
+ public function create($attributes)
+ {
+ // Check for compulsory fields
+ if (!array_key_exists("username", $attributes)){ return "Missing compulsory field [username]"; }
+ if (!array_key_exists("firstname", $attributes)){ return "Missing compulsory field [firstname]"; }
+ if (!array_key_exists("surname", $attributes)){ return "Missing compulsory field [surname]"; }
+ if (!array_key_exists("email", $attributes)){ return "Missing compulsory field [email]"; }
+ if (!array_key_exists("container", $attributes)){ return "Missing compulsory field [container]"; }
+ if (!is_array($attributes["container"])){ return "Container attribute must be an array."; }
+
+ if (array_key_exists("password",$attributes) && (!$this->adldap->getUseSSL() && !$this->adldap->getUseTLS())){
+ throw new adLDAPException('SSL must be configured on your webserver and enabled in the class to set passwords.');
+ }
+
+ if (!array_key_exists("display_name", $attributes)) {
+ $attributes["display_name"] = $attributes["firstname"] . " " . $attributes["surname"];
+ }
+
+ // Translate the schema
+ $add = $this->adldap->adldap_schema($attributes);
+
+ // Additional stuff only used for adding accounts
+ $add["cn"][0] = $attributes["display_name"];
+ $add["samaccountname"][0] = $attributes["username"];
+ $add["objectclass"][0] = "top";
+ $add["objectclass"][1] = "person";
+ $add["objectclass"][2] = "organizationalPerson";
+ $add["objectclass"][3] = "user"; //person?
+ //$add["name"][0]=$attributes["firstname"]." ".$attributes["surname"];
+
+ // Set the account control attribute
+ $control_options = array("NORMAL_ACCOUNT");
+ if (!$attributes["enabled"]) {
+ $control_options[] = "ACCOUNTDISABLE";
+ }
+ $add["userAccountControl"][0] = $this->accountControl($control_options);
+
+ // Determine the container
+ $attributes["container"] = array_reverse($attributes["container"]);
+ $container = "OU=" . implode(", OU=",$attributes["container"]);
+
+ // Add the entry
+ $result = @ldap_add($this->adldap->getLdapConnection(), "CN=" . $add["cn"][0] . ", " . $container . "," . $this->adldap->getBaseDn(), $add);
+ if ($result != true) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Account control options
+ *
+ * @param array $options The options to convert to int
+ * @return int
+ */
+ protected function accountControl($options)
+ {
+ $val=0;
+
+ if (is_array($options)) {
+ if (in_array("SCRIPT",$options)){ $val=$val+1; }
+ if (in_array("ACCOUNTDISABLE",$options)){ $val=$val+2; }
+ if (in_array("HOMEDIR_REQUIRED",$options)){ $val=$val+8; }
+ if (in_array("LOCKOUT",$options)){ $val=$val+16; }
+ if (in_array("PASSWD_NOTREQD",$options)){ $val=$val+32; }
+ //PASSWD_CANT_CHANGE Note You cannot assign this permission by directly modifying the UserAccountControl attribute.
+ //For information about how to set the permission programmatically, see the "Property flag descriptions" section.
+ if (in_array("ENCRYPTED_TEXT_PWD_ALLOWED",$options)){ $val=$val+128; }
+ if (in_array("TEMP_DUPLICATE_ACCOUNT",$options)){ $val=$val+256; }
+ if (in_array("NORMAL_ACCOUNT",$options)){ $val=$val+512; }
+ if (in_array("INTERDOMAIN_TRUST_ACCOUNT",$options)){ $val=$val+2048; }
+ if (in_array("WORKSTATION_TRUST_ACCOUNT",$options)){ $val=$val+4096; }
+ if (in_array("SERVER_TRUST_ACCOUNT",$options)){ $val=$val+8192; }
+ if (in_array("DONT_EXPIRE_PASSWORD",$options)){ $val=$val+65536; }
+ if (in_array("MNS_LOGON_ACCOUNT",$options)){ $val=$val+131072; }
+ if (in_array("SMARTCARD_REQUIRED",$options)){ $val=$val+262144; }
+ if (in_array("TRUSTED_FOR_DELEGATION",$options)){ $val=$val+524288; }
+ if (in_array("NOT_DELEGATED",$options)){ $val=$val+1048576; }
+ if (in_array("USE_DES_KEY_ONLY",$options)){ $val=$val+2097152; }
+ if (in_array("DONT_REQ_PREAUTH",$options)){ $val=$val+4194304; }
+ if (in_array("PASSWORD_EXPIRED",$options)){ $val=$val+8388608; }
+ if (in_array("TRUSTED_TO_AUTH_FOR_DELEGATION",$options)){ $val=$val+16777216; }
+ }
+ return $val;
+ }
+
+ /**
+ * Delete a user account
+ *
+ * @param string $username The username to delete (please be careful here!)
+ * @param bool $isGUID Is the username a GUID or a samAccountName
+ * @return array
+ */
+ public function delete($username, $isGUID = false)
+ {
+ $userinfo = $this->info($username, array("*"), $isGUID);
+ $dn = $userinfo[0]['distinguishedname'][0];
+ $result = $this->adldap->folder()->delete($dn);
+ if ($result != true) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Groups the user is a member of
+ *
+ * @param string $username The username to query
+ * @param bool $recursive Recursive list of groups
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return array
+ */
+ public function groups($username, $recursive = NULL, $isGUID = false)
+ {
+ if ($username === NULL) { return false; }
+ if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ // Search the directory for their information
+ $info = @$this->info($username, array("memberof", "primarygroupid"), $isGUID);
+ $groups = $this->adldap->utilities()->niceNames($info[0]["memberof"]); // Presuming the entry returned is our guy (unique usernames)
+
+ if ($recursive === true){
+ foreach ($groups as $id => $groupName){
+ $extraGroups = $this->adldap->group()->recursiveGroups($groupName);
+ $groups = array_merge($groups, $extraGroups);
+ }
+ }
+
+ return $groups;
+ }
+
+ /**
+ * Find information about the users. Returned in a raw array format from AD
+ *
+ * @param string $username The username to query
+ * @param array $fields Array of parameters to query
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return array
+ */
+ public function info($username, $fields = NULL, $isGUID = false)
+ {
+ if ($username === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ if ($isGUID === true) {
+ $username = $this->adldap->utilities()->strGuidToHex($username);
+ $filter = "objectguid=" . $username;
+ }
+ else if (strstr($username, "@")) {
+ $filter = "userPrincipalName=" . $username;
+ }
+ else {
+ $filter = "samaccountname=" . $username;
+ }
+ $filter = "(&(objectCategory=person)({$filter}))";
+ if ($fields === NULL) {
+ $fields = array("samaccountname","mail","memberof","department","displayname","telephonenumber","primarygroupid","objectsid");
+ }
+ if (!in_array("objectsid", $fields)) {
+ $fields[] = "objectsid";
+ }
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ if (isset($entries[0])) {
+ if ($entries[0]['count'] >= 1) {
+ if (in_array("memberof", $fields)) {
+ // AD does not return the primary group in the ldap query, we may need to fudge it
+ if ($this->adldap->getRealPrimaryGroup() && isset($entries[0]["primarygroupid"][0]) && isset($entries[0]["objectsid"][0])){
+ //$entries[0]["memberof"][]=$this->group_cn($entries[0]["primarygroupid"][0]);
+ $entries[0]["memberof"][] = $this->adldap->group()->getPrimaryGroup($entries[0]["primarygroupid"][0], $entries[0]["objectsid"][0]);
+ } else {
+ $entries[0]["memberof"][] = "CN=Domain Users,CN=Users," . $this->adldap->getBaseDn();
+ }
+ if (!isset($entries[0]["memberof"]["count"])) {
+ $entries[0]["memberof"]["count"] = 0;
+ }
+ $entries[0]["memberof"]["count"]++;
+ }
+ }
+
+ return $entries;
+ }
+ return false;
+ }
+
+ /**
+ * Find information about the users. Returned in a raw array format from AD
+ *
+ * @param string $username The username to query
+ * @param array $fields Array of parameters to query
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return mixed
+ */
+ public function infoCollection($username, $fields = NULL, $isGUID = false)
+ {
+ if ($username === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ $info = $this->info($username, $fields, $isGUID);
+
+ if ($info !== false) {
+ $collection = new adLDAPUserCollection($info, $this->adldap);
+ return $collection;
+ }
+ return false;
+ }
+
+ /**
+ * Determine if a user is in a specific group
+ *
+ * @param string $username The username to query
+ * @param string $group The name of the group to check against
+ * @param bool $recursive Check groups recursively
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function inGroup($username, $group, $recursive = NULL, $isGUID = false)
+ {
+ if ($username === NULL) { return false; }
+ if ($group === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+ if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it
+
+ // Get a list of the groups
+ $groups = $this->groups($username, $recursive, $isGUID);
+
+ // Return true if the specified group is in the group list
+ if (in_array($group, $groups)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Determine a user's password expiry date
+ *
+ * @param string $username The username to query
+ * @param book $isGUID Is the username passed a GUID or a samAccountName
+ * @requires bcmath http://php.net/manual/en/book.bc.php
+ * @return array
+ */
+ public function passwordExpiry($username, $isGUID = false)
+ {
+ if ($username === NULL) { return "Missing compulsory field [username]"; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+ if (!function_exists('bcmod')) { throw new adLDAPException("Missing function support [bcmod] http://php.net/manual/en/book.bc.php"); };
+
+ $userInfo = $this->info($username, array("pwdlastset", "useraccountcontrol"), $isGUID);
+ $pwdLastSet = $userInfo[0]['pwdlastset'][0];
+ $status = array();
+
+ if ($userInfo[0]['useraccountcontrol'][0] == '66048') {
+ // Password does not expire
+ return "Does not expire";
+ }
+ if ($pwdLastSet === '0') {
+ // Password has already expired
+ return "Password has expired";
+ }
+
+ // Password expiry in AD can be calculated from TWO values:
+ // - User's own pwdLastSet attribute: stores the last time the password was changed
+ // - Domain's maxPwdAge attribute: how long passwords last in the domain
+ //
+ // Although Microsoft chose to use a different base and unit for time measurements.
+ // This function will convert them to Unix timestamps
+ $sr = ldap_read($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), 'objectclass=*', array('maxPwdAge'));
+ if (!$sr) {
+ return false;
+ }
+ $info = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+ $maxPwdAge = $info[0]['maxpwdage'][0];
+
+
+ // See MSDN: http://msdn.microsoft.com/en-us/library/ms974598.aspx
+ //
+ // pwdLastSet contains the number of 100 nanosecond intervals since January 1, 1601 (UTC),
+ // stored in a 64 bit integer.
+ //
+ // The number of seconds between this date and Unix epoch is 11644473600.
+ //
+ // maxPwdAge is stored as a large integer that represents the number of 100 nanosecond
+ // intervals from the time the password was set before the password expires.
+ //
+ // We also need to scale this to seconds but also this value is a _negative_ quantity!
+ //
+ // If the low 32 bits of maxPwdAge are equal to 0 passwords do not expire
+ //
+ // Unfortunately the maths involved are too big for PHP integers, so I've had to require
+ // BCMath functions to work with arbitrary precision numbers.
+ if (bcmod($maxPwdAge, 4294967296) === '0') {
+ return "Domain does not expire passwords";
+ }
+
+ // Add maxpwdage and pwdlastset and we get password expiration time in Microsoft's
+ // time units. Because maxpwd age is negative we need to subtract it.
+ $pwdExpire = bcsub($pwdLastSet, $maxPwdAge);
+
+ // Convert MS's time to Unix time
+ $status['expiryts'] = bcsub(bcdiv($pwdExpire, '10000000'), '11644473600');
+ $status['expiryformat'] = date('Y-m-d H:i:s', bcsub(bcdiv($pwdExpire, '10000000'), '11644473600'));
+
+ return $status;
+ }
+
+ /**
+ * Modify a user
+ *
+ * @param string $username The username to query
+ * @param array $attributes The attributes to modify. Note if you set the enabled attribute you must not specify any other attributes
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function modify($username, $attributes, $isGUID = false)
+ {
+ if ($username === NULL) { return "Missing compulsory field [username]"; }
+ if (array_key_exists("password", $attributes) && !$this->adldap->getUseSSL() && !$this->adldap->getUseTLS()) {
+ throw new adLDAPException('SSL/TLS must be configured on your webserver and enabled in the class to set passwords.');
+ }
+
+ // Find the dn of the user
+ $userDn = $this->dn($username, $isGUID);
+ if ($userDn === false) {
+ return false;
+ }
+
+ // Translate the update to the LDAP schema
+ $mod = $this->adldap->adldap_schema($attributes);
+
+ // Check to see if this is an enabled status update
+ if (!$mod && !array_key_exists("enabled", $attributes)){
+ return false;
+ }
+
+ // Set the account control attribute (only if specified)
+ if (array_key_exists("enabled", $attributes)){
+ if ($attributes["enabled"]){
+ $controlOptions = array("NORMAL_ACCOUNT");
+ }
+ else {
+ $controlOptions = array("NORMAL_ACCOUNT", "ACCOUNTDISABLE");
+ }
+ $mod["userAccountControl"][0] = $this->accountControl($controlOptions);
+ }
+
+ // Do the update
+ $result = @ldap_modify($this->adldap->getLdapConnection(), $userDn, $mod);
+ if ($result == false) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Disable a user account
+ *
+ * @param string $username The username to disable
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function disable($username, $isGUID = false)
+ {
+ if ($username === NULL) { return "Missing compulsory field [username]"; }
+ $attributes = array("enabled" => 0);
+ $result = $this->modify($username, $attributes, $isGUID);
+ if ($result == false) { return false; }
+
+ return true;
+ }
+
+ /**
+ * Enable a user account
+ *
+ * @param string $username The username to enable
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function enable($username, $isGUID = false)
+ {
+ if ($username === NULL) { return "Missing compulsory field [username]"; }
+ $attributes = array("enabled" => 1);
+ $result = $this->modify($username, $attributes, $isGUID);
+ if ($result == false) { return false; }
+
+ return true;
+ }
+
+ /**
+ * Set the password of a user - This must be performed over SSL
+ *
+ * @param string $username The username to modify
+ * @param string $password The new password
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return bool
+ */
+ public function password($username, $password, $isGUID = false)
+ {
+ if ($username === NULL) { return false; }
+ if ($password === NULL) { return false; }
+ if (!$this->adldap->getLdapBind()) { return false; }
+ if (!$this->adldap->getUseSSL() && !$this->adldap->getUseTLS()) {
+ throw new adLDAPException('SSL must be configured on your webserver and enabled in the class to set passwords.');
+ }
+
+ $userDn = $this->dn($username, $isGUID);
+ if ($userDn === false) {
+ return false;
+ }
+
+ $add=array();
+ $add["unicodePwd"][0] = $this->encodePassword($password);
+
+ $result = @ldap_mod_replace($this->adldap->getLdapConnection(), $userDn, $add);
+ if ($result === false){
+ $err = ldap_errno($this->adldap->getLdapConnection());
+ if ($err) {
+ $msg = 'Error ' . $err . ': ' . ldap_err2str($err) . '.';
+ if($err == 53) {
+ $msg .= ' Your password might not match the password policy.';
+ }
+ throw new adLDAPException($msg);
+ }
+ else {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Encode a password for transmission over LDAP
+ *
+ * @param string $password The password to encode
+ * @return string
+ */
+ public function encodePassword($password)
+ {
+ $password="\"".$password."\"";
+ $encoded="";
+ for ($i=0; $i <strlen($password); $i++){ $encoded.="{$password{$i}}\000"; }
+ return $encoded;
+ }
+
+ /**
+ * Obtain the user's distinguished name based on their userid
+ *
+ *
+ * @param string $username The username
+ * @param bool $isGUID Is the username passed a GUID or a samAccountName
+ * @return string
+ */
+ public function dn($username, $isGUID=false)
+ {
+ $user = $this->info($username, array("cn"), $isGUID);
+ if ($user[0]["dn"] === NULL) {
+ return false;
+ }
+ $userDn = $user[0]["dn"];
+ return $userDn;
+ }
+
+ /**
+ * Return a list of all users in AD
+ *
+ * @param bool $includeDescription Return a description of the user
+ * @param string $search Search parameter
+ * @param bool $sorted Sort the user accounts
+ * @return array
+ */
+ public function all($includeDescription = false, $search = "*", $sorted = true)
+ {
+ if (!$this->adldap->getLdapBind()) { return false; }
+
+ // Perform the search and grab all their details
+ $filter = "(&(objectClass=user)(samaccounttype=" . adLDAP::ADLDAP_NORMAL_ACCOUNT .")(objectCategory=person)(cn=" . $search . "))";
+ $fields = array("samaccountname","displayname");
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ $usersArray = array();
+ for ($i=0; $i<$entries["count"]; $i++){
+ if ($includeDescription && strlen($entries[$i]["displayname"][0])>0){
+ $usersArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["displayname"][0];
+ } elseif ($includeDescription){
+ $usersArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["samaccountname"][0];
+ } else {
+ array_push($usersArray, $entries[$i]["samaccountname"][0]);
+ }
+ }
+ if ($sorted) {
+ asort($usersArray);
+ }
+ return $usersArray;
+ }
+
+ /**
+ * Converts a username (samAccountName) to a GUID
+ *
+ * @param string $username The username to query
+ * @return string
+ */
+ public function usernameToGuid($username)
+ {
+ if (!$this->adldap->getLdapBind()){ return false; }
+ if ($username === null){ return "Missing compulsory field [username]"; }
+
+ $filter = "samaccountname=" . $username;
+ $fields = array("objectGUID");
+ $sr = @ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ if (ldap_count_entries($this->adldap->getLdapConnection(), $sr) > 0) {
+ $entry = @ldap_first_entry($this->adldap->getLdapConnection(), $sr);
+ $guid = @ldap_get_values_len($this->adldap->getLdapConnection(), $entry, 'objectGUID');
+ $strGUID = $this->adldap->utilities()->binaryToText($guid[0]);
+ return $strGUID;
+ }
+ return false;
+ }
+
+ /**
+ * Return a list of all users in AD that have a specific value in a field
+ *
+ * @param bool $includeDescription Return a description of the user
+ * @param string $searchField Field to search search for
+ * @param string $searchFilter Value to search for in the specified field
+ * @param bool $sorted Sort the user accounts
+ * @return array
+ */
+ public function find($includeDescription = false, $searchField = false, $searchFilter = false, $sorted = true){
+ if (!$this->adldap->getLdapBind()){ return false; }
+
+ // Perform the search and grab all their details
+ $searchParams = "";
+ if ($searchField) {
+ $searchParams = "(" . $searchField . "=" . $searchFilter . ")";
+ }
+ $filter = "(&(objectClass=user)(samaccounttype=" . adLDAP::ADLDAP_NORMAL_ACCOUNT .")(objectCategory=person)" . $searchParams . ")";
+ $fields = array("samaccountname","displayname");
+ $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
+ $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
+
+ $usersArray = array();
+ for ($i=0; $i < $entries["count"]; $i++) {
+ if ($includeDescription && strlen($entries[$i]["displayname"][0]) > 0) {
+ $usersArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["displayname"][0];
+ }
+ else if ($includeDescription) {
+ $usersArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["samaccountname"][0];
+ }
+ else {
+ array_push($usersArray, $entries[$i]["samaccountname"][0]);
+ }
+ }
+ if ($sorted){
+ asort($usersArray);
+ }
+ return ($usersArray);
+ }
+
+ /**
+ * Move a user account to a different OU
+ *
+ * @param string $username The username to move (please be careful here!)
+ * @param array $container The container or containers to move the user to (please be careful here!).
+ * accepts containers in 1. parent 2. child order
+ * @return array
+ */
+ public function move($username, $container)
+ {
+ if (!$this->adldap->getLdapBind()) { return false; }
+ if ($username === null) { return "Missing compulsory field [username]"; }
+ if ($container === null) { return "Missing compulsory field [container]"; }
+ if (!is_array($container)) { return "Container must be an array"; }
+
+ $userInfo = $this->info($username, array("*"));
+ $dn = $userInfo[0]['distinguishedname'][0];
+ $newRDn = "cn=" . $username;
+ $container = array_reverse($container);
+ $newContainer = "ou=" . implode(",ou=",$container);
+ $newBaseDn = strtolower($newContainer) . "," . $this->adldap->getBaseDn();
+ $result = @ldap_rename($this->adldap->getLdapConnection(), $dn, $newRDn, $newBaseDn, true);
+ if ($result !== true) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Get the last logon time of any user as a Unix timestamp
+ *
+ * @param string $username
+ * @return long $unixTimestamp
+ */
+ public function getLastLogon($username) {
+ if (!$this->adldap->getLdapBind()) { return false; }
+ if ($username === null) { return "Missing compulsory field [username]"; }
+ $userInfo = $this->info($username, array("lastLogonTimestamp"));
+ $lastLogon = adLDAPUtils::convertWindowsTimeToUnixTime($userInfo[0]['lastLogonTimestamp'][0]);
+ return $lastLogon;
+ }
+
+}
+?>
diff --git a/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPUtils.php b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPUtils.php
new file mode 100644
index 0000000..6f94fe2
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/classes/adLDAPUtils.php
@@ -0,0 +1,268 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage Utils
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+ */
+require_once(dirname(__FILE__) . '/../adLDAP.php');
+
+/**
+* UTILITY FUNCTIONS
+*/
+class adLDAPUtils {
+ const ADLDAP_VERSION = '4.0.4';
+
+ /**
+ * The current adLDAP connection via dependency injection
+ *
+ * @var adLDAP
+ */
+ protected $adldap;
+
+ public function __construct(adLDAP $adldap) {
+ $this->adldap = $adldap;
+ }
+
+
+ /**
+ * Take an LDAP query and return the nice names, without all the LDAP prefixes (eg. CN, DN)
+ *
+ * @param array $groups
+ * @return array
+ */
+ public function niceNames($groups)
+ {
+
+ $groupArray = array();
+ for ($i=0; $i<$groups["count"]; $i++){ // For each group
+ $line = $groups[$i];
+
+ if (strlen($line)>0) {
+ // More presumptions, they're all prefixed with CN=
+ // so we ditch the first three characters and the group
+ // name goes up to the first comma
+ $bits=explode(",", $line);
+ $groupArray[] = substr($bits[0], 3, (strlen($bits[0])-3));
+ }
+ }
+ return $groupArray;
+ }
+
+ /**
+ * Escape characters for use in an ldap_create function
+ *
+ * @param string $str
+ * @return string
+ */
+ public function escapeCharacters($str) {
+ $str = str_replace(",", "\,", $str);
+ return $str;
+ }
+
+ /**
+ * Escape strings for the use in LDAP filters
+ *
+ * DEVELOPERS SHOULD BE DOING PROPER FILTERING IF THEY'RE ACCEPTING USER INPUT
+ * Ported from Perl's Net::LDAP::Util escape_filter_value
+ *
+ * @param string $str The string the parse
+ * @author Port by Andreas Gohr <andi@splitbrain.org>
+ * @return string
+ */
+ public function ldapSlashes($str) {
+ // see https://github.com/adldap/adLDAP/issues/22
+ return preg_replace_callback(
+ '/([\x00-\x1F\*\(\)\\\\])/',
+ function ($matches) {
+ return "\\".join("", unpack("H2", $matches[1]));
+ },
+ $str
+ );
+ }
+ /**
+ * Converts a string GUID to a hexdecimal value so it can be queried
+ *
+ * @param string $strGUID A string representation of a GUID
+ * @return string
+ */
+ public function strGuidToHex($strGUID)
+ {
+ $strGUID = str_replace('-', '', $strGUID);
+
+ $octet_str = '\\' . substr($strGUID, 6, 2);
+ $octet_str .= '\\' . substr($strGUID, 4, 2);
+ $octet_str .= '\\' . substr($strGUID, 2, 2);
+ $octet_str .= '\\' . substr($strGUID, 0, 2);
+ $octet_str .= '\\' . substr($strGUID, 10, 2);
+ $octet_str .= '\\' . substr($strGUID, 8, 2);
+ $octet_str .= '\\' . substr($strGUID, 14, 2);
+ $octet_str .= '\\' . substr($strGUID, 12, 2);
+ //$octet_str .= '\\' . substr($strGUID, 16, strlen($strGUID));
+ for ($i=16; $i<=(strlen($strGUID)-2); $i++) {
+ if (($i % 2) == 0) {
+ $octet_str .= '\\' . substr($strGUID, $i, 2);
+ }
+ }
+
+ return $octet_str;
+ }
+
+ /**
+ * Convert a binary SID to a text SID
+ *
+ * @param string $binsid A Binary SID
+ * @return string
+ */
+ public function getTextSID($binsid) {
+ $hex_sid = bin2hex($binsid);
+ $rev = hexdec(substr($hex_sid, 0, 2));
+ $subcount = hexdec(substr($hex_sid, 2, 2));
+ $auth = hexdec(substr($hex_sid, 4, 12));
+ $result = "$rev-$auth";
+
+ for ($x=0;$x < $subcount; $x++) {
+ $subauth[$x] =
+ hexdec($this->littleEndian(substr($hex_sid, 16 + ($x * 8), 8)));
+ $result .= "-" . $subauth[$x];
+ }
+
+ // Cheat by tacking on the S-
+ return 'S-' . $result;
+ }
+
+ /**
+ * Converts a little-endian hex number to one that hexdec() can convert
+ *
+ * @param string $hex A hex code
+ * @return string
+ */
+ public function littleEndian($hex)
+ {
+ $result = '';
+ for ($x = strlen($hex) - 2; $x >= 0; $x = $x - 2) {
+ $result .= substr($hex, $x, 2);
+ }
+ return $result;
+ }
+
+ /**
+ * Converts a binary attribute to a string
+ *
+ * @param string $bin A binary LDAP attribute
+ * @return string
+ */
+ public function binaryToText($bin)
+ {
+ $hex_guid = bin2hex($bin);
+ $hex_guid_to_guid_str = '';
+ for($k = 1; $k <= 4; ++$k) {
+ $hex_guid_to_guid_str .= substr($hex_guid, 8 - 2 * $k, 2);
+ }
+ $hex_guid_to_guid_str .= '-';
+ for($k = 1; $k <= 2; ++$k) {
+ $hex_guid_to_guid_str .= substr($hex_guid, 12 - 2 * $k, 2);
+ }
+ $hex_guid_to_guid_str .= '-';
+ for($k = 1; $k <= 2; ++$k) {
+ $hex_guid_to_guid_str .= substr($hex_guid, 16 - 2 * $k, 2);
+ }
+ $hex_guid_to_guid_str .= '-' . substr($hex_guid, 16, 4);
+ $hex_guid_to_guid_str .= '-' . substr($hex_guid, 20);
+ return strtoupper($hex_guid_to_guid_str);
+ }
+
+ /**
+ * Converts a binary GUID to a string GUID
+ *
+ * @param string $binaryGuid The binary GUID attribute to convert
+ * @return string
+ */
+ public function decodeGuid($binaryGuid)
+ {
+ if ($binaryGuid === null){ return "Missing compulsory field [binaryGuid]"; }
+
+ $strGUID = $this->binaryToText($binaryGuid);
+ return $strGUID;
+ }
+
+ /**
+ * Convert a boolean value to a string
+ * You should never need to call this yourself
+ *
+ * @param bool $bool Boolean value
+ * @return string
+ */
+ public function boolToStr($bool)
+ {
+ return ($bool) ? 'TRUE' : 'FALSE';
+ }
+
+ /**
+ * Convert 8bit characters e.g. accented characters to UTF8 encoded characters
+ */
+ public function encode8Bit(&$item, $key) {
+ $encode = false;
+ if (is_string($item)) {
+ for ($i=0; $i<strlen($item); $i++) {
+ if (ord($item[$i]) >> 7) {
+ $encode = true;
+ }
+ }
+ }
+ if ($encode === true && $key != 'password') {
+ $item = utf8_encode($item);
+ }
+ }
+
+ /**
+ * Get the current class version number
+ *
+ * @return string
+ */
+ public function getVersion() {
+ return self::ADLDAP_VERSION;
+ }
+
+ /**
+ * Round a Windows timestamp down to seconds and remove the seconds between 1601-01-01 and 1970-01-01
+ *
+ * @param long $windowsTime
+ * @return long $unixTime
+ */
+ public static function convertWindowsTimeToUnixTime($windowsTime) {
+ $unixTime = round($windowsTime / 10000000) - 11644477200;
+ return $unixTime;
+ }
+}
+
+?>
diff --git a/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPCollection.php b/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPCollection.php
new file mode 100644
index 0000000..433d39f
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPCollection.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage Collection
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+*/
+
+abstract class adLDAPCollection
+{
+ /**
+ * The current adLDAP connection via dependency injection
+ *
+ * @var adLDAP
+ */
+ protected $adldap;
+
+ /**
+ * The current object being modifed / called
+ *
+ * @var mixed
+ */
+ protected $currentObject;
+
+ /**
+ * The raw info array from Active Directory
+ *
+ * @var array
+ */
+ protected $info;
+
+ public function __construct($info, adLDAP $adldap)
+ {
+ $this->setInfo($info);
+ $this->adldap = $adldap;
+ }
+
+ /**
+ * Set the raw info array from Active Directory
+ *
+ * @param array $info
+ */
+ public function setInfo(array $info)
+ {
+ if ($this->info && sizeof($info) >= 1) {
+ unset($this->info);
+ }
+ $this->info = $info;
+ }
+
+ /**
+ * Magic get method to retrieve data from the raw array in a formatted way
+ *
+ * @param string $attribute
+ * @return mixed
+ */
+ public function __get($attribute)
+ {
+ if (isset($this->info[0]) && is_array($this->info[0])) {
+ foreach ($this->info[0] as $keyAttr => $valueAttr) {
+ if (strtolower($keyAttr) == strtolower($attribute)) {
+ if ($this->info[0][strtolower($attribute)]['count'] == 1) {
+ return $this->info[0][strtolower($attribute)][0];
+ }
+ else {
+ $array = array();
+ foreach ($this->info[0][strtolower($attribute)] as $key => $value) {
+ if ((string)$key != 'count') {
+ $array[$key] = $value;
+ }
+ }
+ return $array;
+ }
+ }
+ }
+ }
+ else {
+ return NULL;
+ }
+ }
+
+ /**
+ * Magic set method to update an attribute
+ *
+ * @param string $attribute
+ * @param string $value
+ * @return bool
+ */
+ abstract public function __set($attribute, $value);
+
+ /**
+ * Magic isset method to check for the existence of an attribute
+ *
+ * @param string $attribute
+ * @return bool
+ */
+ public function __isset($attribute) {
+ if (isset($this->info[0]) && is_array($this->info[0])) {
+ foreach ($this->info[0] as $keyAttr => $valueAttr) {
+ if (strtolower($keyAttr) == strtolower($attribute)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
+?>
diff --git a/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPComputerCollection.php b/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPComputerCollection.php
new file mode 100644
index 0000000..09f82ca
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPComputerCollection.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage ComputerCollection
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+*/
+
+class adLDAPComputerCollection extends adLDAPCollection
+{
+
+ public function __set($attribute, $value)
+ {
+
+ }
+}
+?>
diff --git a/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPContactCollection.php b/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPContactCollection.php
new file mode 100644
index 0000000..a9efad5
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPContactCollection.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage ContactCollection
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+*/
+
+class adLDAPContactCollection extends adLDAPCollection
+{
+
+ public function __set($attribute, $value)
+ {
+
+ }
+}
+?>
diff --git a/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPGroupCollection.php b/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPGroupCollection.php
new file mode 100644
index 0000000..ef4af8d
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPGroupCollection.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage GroupCollection
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+*/
+
+class adLDAPGroupCollection extends adLDAPCollection
+{
+
+ public function __set($attribute, $value)
+ {
+
+ }
+}
+?>
diff --git a/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPUserCollection.php b/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPUserCollection.php
new file mode 100644
index 0000000..63fce5f
--- /dev/null
+++ b/platform/www/lib/plugins/authad/adLDAP/collections/adLDAPUserCollection.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
+ * Version 4.0.4
+ *
+ * PHP Version 5 with SSL and LDAP support
+ *
+ * Written by Scott Barnett, Richard Hyland
+ * email: scott@wiggumworld.com, adldap@richardhyland.com
+ * http://adldap.sourceforge.net/
+ *
+ * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ *
+ * We'd appreciate any improvements or additions to be submitted back
+ * to benefit the entire community :)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * @category ToolsAndUtilities
+ * @package adLDAP
+ * @subpackage UserCollection
+ * @author Scott Barnett, Richard Hyland
+ * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
+ * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
+ * @revision $Revision: 97 $
+ * @version 4.0.4
+ * @link http://adldap.sourceforge.net/
+*/
+
+class adLDAPUserCollection extends adLDAPCollection
+{
+
+ public function __set($attribute, $value)
+ {
+
+ }
+}
+?>
diff --git a/platform/www/lib/plugins/authad/auth.php b/platform/www/lib/plugins/authad/auth.php
new file mode 100644
index 0000000..27a6b22
--- /dev/null
+++ b/platform/www/lib/plugins/authad/auth.php
@@ -0,0 +1,786 @@
+<?php
+
+/**
+ * Active Directory authentication backend for DokuWiki
+ *
+ * This makes authentication with a Active Directory server much easier
+ * than when using the normal LDAP backend by utilizing the adLDAP library
+ *
+ * Usage:
+ * Set DokuWiki's local.protected.php auth setting to read
+ *
+ * $conf['authtype'] = 'authad';
+ *
+ * $conf['plugin']['authad']['account_suffix'] = '@my.domain.org';
+ * $conf['plugin']['authad']['base_dn'] = 'DC=my,DC=domain,DC=org';
+ * $conf['plugin']['authad']['domain_controllers'] = 'srv1.domain.org,srv2.domain.org';
+ *
+ * //optional:
+ * $conf['plugin']['authad']['sso'] = 1;
+ * $conf['plugin']['authad']['admin_username'] = 'root';
+ * $conf['plugin']['authad']['admin_password'] = 'pass';
+ * $conf['plugin']['authad']['real_primarygroup'] = 1;
+ * $conf['plugin']['authad']['use_ssl'] = 1;
+ * $conf['plugin']['authad']['use_tls'] = 1;
+ * $conf['plugin']['authad']['debug'] = 1;
+ * // warn user about expiring password this many days in advance:
+ * $conf['plugin']['authad']['expirywarn'] = 5;
+ *
+ * // get additional information to the userinfo array
+ * // add a list of comma separated ldap contact fields.
+ * $conf['plugin']['authad']['additional'] = 'field1,field2';
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author James Van Lommel <jamesvl@gmail.com>
+ * @link http://www.nosq.com/blog/2005/08/ldap-activedirectory-and-dokuwiki/
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Jan Schumann <js@schumann-it.com>
+ */
+class auth_plugin_authad extends DokuWiki_Auth_Plugin
+{
+
+ /**
+ * @var array hold connection data for a specific AD domain
+ */
+ protected $opts = array();
+
+ /**
+ * @var array open connections for each AD domain, as adLDAP objects
+ */
+ protected $adldap = array();
+
+ /**
+ * @var bool message state
+ */
+ protected $msgshown = false;
+
+ /**
+ * @var array user listing cache
+ */
+ protected $users = array();
+
+ /**
+ * @var array filter patterns for listing users
+ */
+ protected $pattern = array();
+
+ protected $grpsusers = array();
+
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ global $INPUT;
+ parent::__construct();
+
+ require_once(DOKU_PLUGIN.'authad/adLDAP/adLDAP.php');
+ require_once(DOKU_PLUGIN.'authad/adLDAP/classes/adLDAPUtils.php');
+
+ // we load the config early to modify it a bit here
+ $this->loadConfig();
+
+ // additional information fields
+ if (isset($this->conf['additional'])) {
+ $this->conf['additional'] = str_replace(' ', '', $this->conf['additional']);
+ $this->conf['additional'] = explode(',', $this->conf['additional']);
+ } else $this->conf['additional'] = array();
+
+ // ldap extension is needed
+ if (!function_exists('ldap_connect')) {
+ if ($this->conf['debug'])
+ msg("AD Auth: PHP LDAP extension not found.", -1);
+ $this->success = false;
+ return;
+ }
+
+ // Prepare SSO
+ if (!empty($_SERVER['REMOTE_USER'])) {
+ // make sure the right encoding is used
+ if ($this->getConf('sso_charset')) {
+ $_SERVER['REMOTE_USER'] = iconv($this->getConf('sso_charset'), 'UTF-8', $_SERVER['REMOTE_USER']);
+ } elseif (!\dokuwiki\Utf8\Clean::isUtf8($_SERVER['REMOTE_USER'])) {
+ $_SERVER['REMOTE_USER'] = utf8_encode($_SERVER['REMOTE_USER']);
+ }
+
+ // trust the incoming user
+ if ($this->conf['sso']) {
+ $_SERVER['REMOTE_USER'] = $this->cleanUser($_SERVER['REMOTE_USER']);
+
+ // we need to simulate a login
+ if (empty($_COOKIE[DOKU_COOKIE])) {
+ $INPUT->set('u', $_SERVER['REMOTE_USER']);
+ $INPUT->set('p', 'sso_only');
+ }
+ }
+ }
+
+ // other can do's are changed in $this->_loadServerConfig() base on domain setup
+ $this->cando['modName'] = (bool)$this->conf['update_name'];
+ $this->cando['modMail'] = (bool)$this->conf['update_mail'];
+ $this->cando['getUserCount'] = true;
+ }
+
+ /**
+ * Load domain config on capability check
+ *
+ * @param string $cap
+ * @return bool
+ */
+ public function canDo($cap)
+ {
+ //capabilities depend on config, which may change depending on domain
+ $domain = $this->getUserDomain($_SERVER['REMOTE_USER']);
+ $this->loadServerConfig($domain);
+ return parent::canDo($cap);
+ }
+
+ /**
+ * Check user+password [required auth function]
+ *
+ * Checks if the given user exists and the given
+ * plaintext password is correct by trying to bind
+ * to the LDAP server
+ *
+ * @author James Van Lommel <james@nosq.com>
+ * @param string $user
+ * @param string $pass
+ * @return bool
+ */
+ public function checkPass($user, $pass)
+ {
+ if ($_SERVER['REMOTE_USER'] &&
+ $_SERVER['REMOTE_USER'] == $user &&
+ $this->conf['sso']
+ ) return true;
+
+ $adldap = $this->initAdLdap($this->getUserDomain($user));
+ if (!$adldap) return false;
+
+ try {
+ return $adldap->authenticate($this->getUserName($user), $pass);
+ } catch (adLDAPException $e) {
+ // shouldn't really happen
+ return false;
+ }
+ }
+
+ /**
+ * Return user info [required auth function]
+ *
+ * Returns info about the given user needs to contain
+ * at least these fields:
+ *
+ * name string full name of the user
+ * mail string email address of the user
+ * grps array list of groups the user is in
+ *
+ * This AD specific function returns the following
+ * addional fields:
+ *
+ * dn string distinguished name (DN)
+ * uid string samaccountname
+ * lastpwd int timestamp of the date when the password was set
+ * expires true if the password expires
+ * expiresin int seconds until the password expires
+ * any fields specified in the 'additional' config option
+ *
+ * @author James Van Lommel <james@nosq.com>
+ * @param string $user
+ * @param bool $requireGroups (optional) - ignored, groups are always supplied by this plugin
+ * @return array
+ */
+ public function getUserData($user, $requireGroups = true)
+ {
+ global $conf;
+ global $lang;
+ global $ID;
+ $adldap = $this->initAdLdap($this->getUserDomain($user));
+ if (!$adldap) return array();
+
+ if ($user == '') return array();
+
+ $fields = array('mail', 'displayname', 'samaccountname', 'lastpwd', 'pwdlastset', 'useraccountcontrol');
+
+ // add additional fields to read
+ $fields = array_merge($fields, $this->conf['additional']);
+ $fields = array_unique($fields);
+ $fields = array_filter($fields);
+
+ //get info for given user
+ $result = $adldap->user()->info($this->getUserName($user), $fields);
+ if ($result == false) {
+ return array();
+ }
+
+ //general user info
+ $info = array();
+ $info['name'] = $result[0]['displayname'][0];
+ $info['mail'] = $result[0]['mail'][0];
+ $info['uid'] = $result[0]['samaccountname'][0];
+ $info['dn'] = $result[0]['dn'];
+ //last password set (Windows counts from January 1st 1601)
+ $info['lastpwd'] = $result[0]['pwdlastset'][0] / 10000000 - 11644473600;
+ //will it expire?
+ $info['expires'] = !($result[0]['useraccountcontrol'][0] & 0x10000); //ADS_UF_DONT_EXPIRE_PASSWD
+
+ // additional information
+ foreach ($this->conf['additional'] as $field) {
+ if (isset($result[0][strtolower($field)])) {
+ $info[$field] = $result[0][strtolower($field)][0];
+ }
+ }
+
+ // handle ActiveDirectory memberOf
+ $info['grps'] = $adldap->user()->groups($this->getUserName($user), (bool) $this->opts['recursive_groups']);
+
+ if (is_array($info['grps'])) {
+ foreach ($info['grps'] as $ndx => $group) {
+ $info['grps'][$ndx] = $this->cleanGroup($group);
+ }
+ }
+
+ // always add the default group to the list of groups
+ if (!is_array($info['grps']) || !in_array($conf['defaultgroup'], $info['grps'])) {
+ $info['grps'][] = $conf['defaultgroup'];
+ }
+
+ // add the user's domain to the groups
+ $domain = $this->getUserDomain($user);
+ if ($domain && !in_array("domain-$domain", (array) $info['grps'])) {
+ $info['grps'][] = $this->cleanGroup("domain-$domain");
+ }
+
+ // check expiry time
+ if ($info['expires'] && $this->conf['expirywarn']) {
+ try {
+ $expiry = $adldap->user()->passwordExpiry($user);
+ if (is_array($expiry)) {
+ $info['expiresat'] = $expiry['expiryts'];
+ $info['expiresin'] = round(($info['expiresat'] - time())/(24*60*60));
+
+ // if this is the current user, warn him (once per request only)
+ if (($_SERVER['REMOTE_USER'] == $user) &&
+ ($info['expiresin'] <= $this->conf['expirywarn']) &&
+ !$this->msgshown
+ ) {
+ $msg = sprintf($this->getLang('authpwdexpire'), $info['expiresin']);
+ if ($this->canDo('modPass')) {
+ $url = wl($ID, array('do'=> 'profile'));
+ $msg .= ' <a href="'.$url.'">'.$lang['btn_profile'].'</a>';
+ }
+ msg($msg);
+ $this->msgshown = true;
+ }
+ }
+ } catch (adLDAPException $e) {
+ // ignore. should usually not happen
+ }
+ }
+
+ return $info;
+ }
+
+ /**
+ * Make AD group names usable by DokuWiki.
+ *
+ * Removes backslashes ('\'), pound signs ('#'), and converts spaces to underscores.
+ *
+ * @author James Van Lommel (jamesvl@gmail.com)
+ * @param string $group
+ * @return string
+ */
+ public function cleanGroup($group)
+ {
+ $group = str_replace('\\', '', $group);
+ $group = str_replace('#', '', $group);
+ $group = preg_replace('[\s]', '_', $group);
+ $group = \dokuwiki\Utf8\PhpString::strtolower(trim($group));
+ return $group;
+ }
+
+ /**
+ * Sanitize user names
+ *
+ * Normalizes domain parts, does not modify the user name itself (unlike cleanGroup)
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ * @param string $user
+ * @return string
+ */
+ public function cleanUser($user)
+ {
+ $domain = '';
+
+ // get NTLM or Kerberos domain part
+ list($dom, $user) = explode('\\', $user, 2);
+ if (!$user) $user = $dom;
+ if ($dom) $domain = $dom;
+ list($user, $dom) = explode('@', $user, 2);
+ if ($dom) $domain = $dom;
+
+ // clean up both
+ $domain = \dokuwiki\Utf8\PhpString::strtolower(trim($domain));
+ $user = \dokuwiki\Utf8\PhpString::strtolower(trim($user));
+
+ // is this a known, valid domain or do we work without account suffix? if not discard
+ if (!is_array($this->conf[$domain]) && $this->conf['account_suffix'] !== '') {
+ $domain = '';
+ }
+
+ // reattach domain
+ if ($domain) $user = "$user@$domain";
+ return $user;
+ }
+
+ /**
+ * Most values in LDAP are case-insensitive
+ *
+ * @return bool
+ */
+ public function isCaseSensitive()
+ {
+ return false;
+ }
+
+ /**
+ * Create a Search-String useable by adLDAPUsers::all($includeDescription = false, $search = "*", $sorted = true)
+ *
+ * @param array $filter
+ * @return string
+ */
+ protected function constructSearchString($filter)
+ {
+ if (!$filter) {
+ return '*';
+ }
+ $adldapUtils = new adLDAPUtils($this->initAdLdap(null));
+ $result = '*';
+ if (isset($filter['name'])) {
+ $result .= ')(displayname=*' . $adldapUtils->ldapSlashes($filter['name']) . '*';
+ unset($filter['name']);
+ }
+
+ if (isset($filter['user'])) {
+ $result .= ')(samAccountName=*' . $adldapUtils->ldapSlashes($filter['user']) . '*';
+ unset($filter['user']);
+ }
+
+ if (isset($filter['mail'])) {
+ $result .= ')(mail=*' . $adldapUtils->ldapSlashes($filter['mail']) . '*';
+ unset($filter['mail']);
+ }
+ return $result;
+ }
+
+ /**
+ * Return a count of the number of user which meet $filter criteria
+ *
+ * @param array $filter $filter array of field/pattern pairs, empty array for no filter
+ * @return int number of users
+ */
+ public function getUserCount($filter = array())
+ {
+ $adldap = $this->initAdLdap(null);
+ if (!$adldap) {
+ dbglog("authad/auth.php getUserCount(): _adldap not set.");
+ return -1;
+ }
+ if ($filter == array()) {
+ $result = $adldap->user()->all();
+ } else {
+ $searchString = $this->constructSearchString($filter);
+ $result = $adldap->user()->all(false, $searchString);
+ if (isset($filter['grps'])) {
+ $this->users = array_fill_keys($result, false);
+ /** @var admin_plugin_usermanager $usermanager */
+ $usermanager = plugin_load("admin", "usermanager", false);
+ $usermanager->setLastdisabled(true);
+ if (!isset($this->grpsusers[$this->filterToString($filter)])) {
+ $this->fillGroupUserArray($filter, $usermanager->getStart() + 3*$usermanager->getPagesize());
+ } elseif (count($this->grpsusers[$this->filterToString($filter)]) <
+ $usermanager->getStart() + 3*$usermanager->getPagesize()
+ ) {
+ $this->fillGroupUserArray(
+ $filter,
+ $usermanager->getStart() +
+ 3*$usermanager->getPagesize() -
+ count($this->grpsusers[$this->filterToString($filter)])
+ );
+ }
+ $result = $this->grpsusers[$this->filterToString($filter)];
+ } else {
+ /** @var admin_plugin_usermanager $usermanager */
+ $usermanager = plugin_load("admin", "usermanager", false);
+ $usermanager->setLastdisabled(false);
+ }
+ }
+
+ if (!$result) {
+ return 0;
+ }
+ return count($result);
+ }
+
+ /**
+ *
+ * create a unique string for each filter used with a group
+ *
+ * @param array $filter
+ * @return string
+ */
+ protected function filterToString($filter)
+ {
+ $result = '';
+ if (isset($filter['user'])) {
+ $result .= 'user-' . $filter['user'];
+ }
+ if (isset($filter['name'])) {
+ $result .= 'name-' . $filter['name'];
+ }
+ if (isset($filter['mail'])) {
+ $result .= 'mail-' . $filter['mail'];
+ }
+ if (isset($filter['grps'])) {
+ $result .= 'grps-' . $filter['grps'];
+ }
+ return $result;
+ }
+
+ /**
+ * Create an array of $numberOfAdds users passing a certain $filter, including belonging
+ * to a certain group and save them to a object-wide array. If the array
+ * already exists try to add $numberOfAdds further users to it.
+ *
+ * @param array $filter
+ * @param int $numberOfAdds additional number of users requested
+ * @return int number of Users actually add to Array
+ */
+ protected function fillGroupUserArray($filter, $numberOfAdds)
+ {
+ if (isset($this->grpsusers[$this->filterToString($filter)])) {
+ $actualstart = count($this->grpsusers[$this->filterToString($filter)]);
+ } else {
+ $this->grpsusers[$this->filterToString($filter)] = [];
+ $actualstart = 0;
+ }
+
+ $i=0;
+ $count = 0;
+ $this->constructPattern($filter);
+ foreach ($this->users as $user => &$info) {
+ if ($i++ < $actualstart) {
+ continue;
+ }
+ if ($info === false) {
+ $info = $this->getUserData($user);
+ }
+ if ($this->filter($user, $info)) {
+ $this->grpsusers[$this->filterToString($filter)][$user] = $info;
+ if (($numberOfAdds > 0) && (++$count >= $numberOfAdds)) break;
+ }
+ }
+ return $count;
+ }
+
+ /**
+ * Bulk retrieval of user data
+ *
+ * @author Dominik Eckelmann <dokuwiki@cosmocode.de>
+ *
+ * @param int $start index of first user to be returned
+ * @param int $limit max number of users to be returned
+ * @param array $filter array of field/pattern pairs, null for no filter
+ * @return array userinfo (refer getUserData for internal userinfo details)
+ */
+ public function retrieveUsers($start = 0, $limit = 0, $filter = array())
+ {
+ $adldap = $this->initAdLdap(null);
+ if (!$adldap) return array();
+
+ //if (!$this->users) {
+ //get info for given user
+ $result = $adldap->user()->all(false, $this->constructSearchString($filter));
+ if (!$result) return array();
+ $this->users = array_fill_keys($result, false);
+ //}
+
+ $i = 0;
+ $count = 0;
+ $result = array();
+
+ if (!isset($filter['grps'])) {
+ /** @var admin_plugin_usermanager $usermanager */
+ $usermanager = plugin_load("admin", "usermanager", false);
+ $usermanager->setLastdisabled(false);
+ $this->constructPattern($filter);
+ foreach ($this->users as $user => &$info) {
+ if ($i++ < $start) {
+ continue;
+ }
+ if ($info === false) {
+ $info = $this->getUserData($user);
+ }
+ $result[$user] = $info;
+ if (($limit > 0) && (++$count >= $limit)) break;
+ }
+ } else {
+ /** @var admin_plugin_usermanager $usermanager */
+ $usermanager = plugin_load("admin", "usermanager", false);
+ $usermanager->setLastdisabled(true);
+ if (!isset($this->grpsusers[$this->filterToString($filter)]) ||
+ count($this->grpsusers[$this->filterToString($filter)]) < ($start+$limit)
+ ) {
+ if(!isset($this->grpsusers[$this->filterToString($filter)])) {
+ $this->grpsusers[$this->filterToString($filter)] = [];
+ }
+
+ $this->fillGroupUserArray(
+ $filter,
+ $start+$limit - count($this->grpsusers[$this->filterToString($filter)]) +1
+ );
+ }
+ if (!$this->grpsusers[$this->filterToString($filter)]) return array();
+ foreach ($this->grpsusers[$this->filterToString($filter)] as $user => &$info) {
+ if ($i++ < $start) {
+ continue;
+ }
+ $result[$user] = $info;
+ if (($limit > 0) && (++$count >= $limit)) break;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Modify user data
+ *
+ * @param string $user nick of the user to be changed
+ * @param array $changes array of field/value pairs to be changed
+ * @return bool
+ */
+ public function modifyUser($user, $changes)
+ {
+ $return = true;
+ $adldap = $this->initAdLdap($this->getUserDomain($user));
+ if (!$adldap) {
+ msg($this->getLang('connectfail'), -1);
+ return false;
+ }
+
+ // password changing
+ if (isset($changes['pass'])) {
+ try {
+ $return = $adldap->user()->password($this->getUserName($user), $changes['pass']);
+ } catch (adLDAPException $e) {
+ if ($this->conf['debug']) msg('AD Auth: '.$e->getMessage(), -1);
+ $return = false;
+ }
+ if (!$return) msg($this->getLang('passchangefail'), -1);
+ }
+
+ // changing user data
+ $adchanges = array();
+ if (isset($changes['name'])) {
+ // get first and last name
+ $parts = explode(' ', $changes['name']);
+ $adchanges['surname'] = array_pop($parts);
+ $adchanges['firstname'] = join(' ', $parts);
+ $adchanges['display_name'] = $changes['name'];
+ }
+ if (isset($changes['mail'])) {
+ $adchanges['email'] = $changes['mail'];
+ }
+ if (count($adchanges)) {
+ try {
+ $return = $return & $adldap->user()->modify($this->getUserName($user), $adchanges);
+ } catch (adLDAPException $e) {
+ if ($this->conf['debug']) msg('AD Auth: '.$e->getMessage(), -1);
+ $return = false;
+ }
+ if (!$return) msg($this->getLang('userchangefail'), -1);
+ }
+
+ return $return;
+ }
+
+ /**
+ * Initialize the AdLDAP library and connect to the server
+ *
+ * When you pass null as domain, it will reuse any existing domain.
+ * Eg. the one of the logged in user. It falls back to the default
+ * domain if no current one is available.
+ *
+ * @param string|null $domain The AD domain to use
+ * @return adLDAP|bool true if a connection was established
+ */
+ protected function initAdLdap($domain)
+ {
+ if (is_null($domain) && is_array($this->opts)) {
+ $domain = $this->opts['domain'];
+ }
+
+ $this->opts = $this->loadServerConfig((string) $domain);
+ if (isset($this->adldap[$domain])) return $this->adldap[$domain];
+
+ // connect
+ try {
+ $this->adldap[$domain] = new adLDAP($this->opts);
+ return $this->adldap[$domain];
+ } catch (Exception $e) {
+ if ($this->conf['debug']) {
+ msg('AD Auth: '.$e->getMessage(), -1);
+ }
+ $this->success = false;
+ $this->adldap[$domain] = null;
+ }
+ return false;
+ }
+
+ /**
+ * Get the domain part from a user
+ *
+ * @param string $user
+ * @return string
+ */
+ public function getUserDomain($user)
+ {
+ list(, $domain) = explode('@', $user, 2);
+ return $domain;
+ }
+
+ /**
+ * Get the user part from a user
+ *
+ * When an account suffix is set, we strip the domain part from the user
+ *
+ * @param string $user
+ * @return string
+ */
+ public function getUserName($user)
+ {
+ if ($this->conf['account_suffix'] !== '') {
+ list($user) = explode('@', $user, 2);
+ }
+ return $user;
+ }
+
+ /**
+ * Fetch the configuration for the given AD domain
+ *
+ * @param string $domain current AD domain
+ * @return array
+ */
+ protected function loadServerConfig($domain)
+ {
+ // prepare adLDAP standard configuration
+ $opts = $this->conf;
+
+ $opts['domain'] = $domain;
+
+ // add possible domain specific configuration
+ if ($domain && is_array($this->conf[$domain])) foreach ($this->conf[$domain] as $key => $val) {
+ $opts[$key] = $val;
+ }
+
+ // handle multiple AD servers
+ $opts['domain_controllers'] = explode(',', $opts['domain_controllers']);
+ $opts['domain_controllers'] = array_map('trim', $opts['domain_controllers']);
+ $opts['domain_controllers'] = array_filter($opts['domain_controllers']);
+
+ // compatibility with old option name
+ if (empty($opts['admin_username']) && !empty($opts['ad_username'])) {
+ $opts['admin_username'] = $opts['ad_username'];
+ }
+ if (empty($opts['admin_password']) && !empty($opts['ad_password'])) {
+ $opts['admin_password'] = $opts['ad_password'];
+ }
+ $opts['admin_password'] = conf_decodeString($opts['admin_password']); // deobfuscate
+
+ // we can change the password if SSL is set
+ if ($opts['use_ssl'] || $opts['use_tls']) {
+ $this->cando['modPass'] = true;
+ } else {
+ $this->cando['modPass'] = false;
+ }
+
+ // adLDAP expects empty user/pass as NULL, we're less strict FS#2781
+ if (empty($opts['admin_username'])) $opts['admin_username'] = null;
+ if (empty($opts['admin_password'])) $opts['admin_password'] = null;
+
+ // user listing needs admin priviledges
+ if (!empty($opts['admin_username']) && !empty($opts['admin_password'])) {
+ $this->cando['getUsers'] = true;
+ } else {
+ $this->cando['getUsers'] = false;
+ }
+
+ return $opts;
+ }
+
+ /**
+ * Returns a list of configured domains
+ *
+ * The default domain has an empty string as key
+ *
+ * @return array associative array(key => domain)
+ */
+ public function getConfiguredDomains()
+ {
+ $domains = array();
+ if (empty($this->conf['account_suffix'])) return $domains; // not configured yet
+
+ // add default domain, using the name from account suffix
+ $domains[''] = ltrim($this->conf['account_suffix'], '@');
+
+ // find additional domains
+ foreach ($this->conf as $key => $val) {
+ if (is_array($val) && isset($val['account_suffix'])) {
+ $domains[$key] = ltrim($val['account_suffix'], '@');
+ }
+ }
+ ksort($domains);
+
+ return $domains;
+ }
+
+ /**
+ * Check provided user and userinfo for matching patterns
+ *
+ * The patterns are set up with $this->_constructPattern()
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $user
+ * @param array $info
+ * @return bool
+ */
+ protected function filter($user, $info)
+ {
+ foreach ($this->pattern as $item => $pattern) {
+ if ($item == 'user') {
+ if (!preg_match($pattern, $user)) return false;
+ } elseif ($item == 'grps') {
+ if (!count(preg_grep($pattern, $info['grps']))) return false;
+ } else {
+ if (!preg_match($pattern, $info[$item])) return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Create a pattern for $this->_filter()
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param array $filter
+ */
+ protected function constructPattern($filter)
+ {
+ $this->pattern = array();
+ foreach ($filter as $item => $pattern) {
+ $this->pattern[$item] = '/'.str_replace('/', '\/', $pattern).'/i'; // allow regex characters
+ }
+ }
+}
diff --git a/platform/www/lib/plugins/authad/conf/default.php b/platform/www/lib/plugins/authad/conf/default.php
new file mode 100644
index 0000000..84094cc
--- /dev/null
+++ b/platform/www/lib/plugins/authad/conf/default.php
@@ -0,0 +1,18 @@
+<?php
+
+$conf['account_suffix'] = '';
+$conf['base_dn'] = '';
+$conf['domain_controllers'] = '';
+$conf['sso'] = 0;
+$conf['sso_charset'] = '';
+$conf['admin_username'] = '';
+$conf['admin_password'] = '';
+$conf['real_primarygroup'] = 0;
+$conf['use_ssl'] = 0;
+$conf['use_tls'] = 0;
+$conf['debug'] = 0;
+$conf['expirywarn'] = 0;
+$conf['additional'] = '';
+$conf['update_name'] = 0;
+$conf['update_mail'] = 0;
+$conf['recursive_groups'] = 0;
diff --git a/platform/www/lib/plugins/authad/conf/metadata.php b/platform/www/lib/plugins/authad/conf/metadata.php
new file mode 100644
index 0000000..945474c
--- /dev/null
+++ b/platform/www/lib/plugins/authad/conf/metadata.php
@@ -0,0 +1,18 @@
+<?php
+
+$meta['account_suffix'] = array('string','_caution' => 'danger');
+$meta['base_dn'] = array('string','_caution' => 'danger');
+$meta['domain_controllers'] = array('string','_caution' => 'danger');
+$meta['sso'] = array('onoff','_caution' => 'danger');
+$meta['sso_charset'] = array('string','_caution' => 'danger');
+$meta['admin_username'] = array('string','_caution' => 'danger');
+$meta['admin_password'] = array('password','_caution' => 'danger','_code' => 'base64');
+$meta['real_primarygroup'] = array('onoff','_caution' => 'danger');
+$meta['use_ssl'] = array('onoff','_caution' => 'danger');
+$meta['use_tls'] = array('onoff','_caution' => 'danger');
+$meta['debug'] = array('onoff','_caution' => 'security');
+$meta['expirywarn'] = array('numeric', '_min'=>0,'_caution' => 'danger');
+$meta['additional'] = array('string','_caution' => 'danger');
+$meta['update_name'] = array('onoff','_caution' => 'danger');
+$meta['update_mail'] = array('onoff','_caution' => 'danger');
+$meta['recursive_groups'] = array('onoff','_caution' => 'danger');
diff --git a/platform/www/lib/plugins/authad/lang/en/lang.php b/platform/www/lib/plugins/authad/lang/en/lang.php
new file mode 100644
index 0000000..3e8a9e2
--- /dev/null
+++ b/platform/www/lib/plugins/authad/lang/en/lang.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * English language file for addomain plugin
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+$lang['domain'] = 'Logon Domain';
+$lang['authpwdexpire'] = 'Your password will expire in %d days, you should change it soon.';
+$lang['passchangefail'] = 'Failed to change the password. Maybe the password policy was not met?';
+$lang['userchangefail'] = 'Failed to change user attributes. Maybe your account does not have permissions to make changes?';
+$lang['connectfail'] = 'Failed to connect to Active Directory server.';
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/authad/lang/en/settings.php b/platform/www/lib/plugins/authad/lang/en/settings.php
new file mode 100644
index 0000000..3de9a72
--- /dev/null
+++ b/platform/www/lib/plugins/authad/lang/en/settings.php
@@ -0,0 +1,18 @@
+<?php
+
+$lang['account_suffix'] = 'Your account suffix. Eg. <code>@my.domain.org</code>';
+$lang['base_dn'] = 'Your base DN. Eg. <code>DC=my,DC=domain,DC=org</code>';
+$lang['domain_controllers'] = 'A comma separated list of Domain controllers. Eg. <code>srv1.domain.org,srv2.domain.org</code>';
+$lang['admin_username'] = 'A privileged Active Directory user with access to all other user\'s data. Optional, but needed for certain actions like sending subscription mails.';
+$lang['admin_password'] = 'The password of the above user.';
+$lang['sso'] = 'Should Single-Sign-On via Kerberos or NTLM be used?';
+$lang['sso_charset'] = 'The charset your webserver will pass the Kerberos or NTLM username in. Empty for UTF-8 or latin-1. Requires the iconv extension.';
+$lang['real_primarygroup'] = 'Should the real primary group be resolved instead of assuming "Domain Users" (slower).';
+$lang['use_ssl'] = 'Use SSL connection? If used, do not enable TLS below.';
+$lang['use_tls'] = 'Use TLS connection? If used, do not enable SSL above.';
+$lang['debug'] = 'Display additional debugging output on errors?';
+$lang['expirywarn'] = 'Days in advance to warn user about expiring password. 0 to disable.';
+$lang['additional'] = 'A comma separated list of additional AD attributes to fetch from user data. Used by some plugins.';
+$lang['update_name'] = 'Allow users to update their AD display name?';
+$lang['update_mail'] = 'Allow users to update their email address?';
+$lang['recursive_groups'] = 'Resolve nested groups to their respective members (slower).';
diff --git a/platform/www/lib/plugins/authad/plugin.info.txt b/platform/www/lib/plugins/authad/plugin.info.txt
new file mode 100644
index 0000000..57e1387
--- /dev/null
+++ b/platform/www/lib/plugins/authad/plugin.info.txt
@@ -0,0 +1,7 @@
+base authad
+author Andreas Gohr
+email andi@splitbrain.org
+date 2015-07-13
+name Active Directory Auth Plugin
+desc Provides user authentication against a Microsoft Active Directory
+url http://www.dokuwiki.org/plugin:authad
diff --git a/platform/www/lib/plugins/authldap/auth.php b/platform/www/lib/plugins/authldap/auth.php
new file mode 100644
index 0000000..68d1dad
--- /dev/null
+++ b/platform/www/lib/plugins/authldap/auth.php
@@ -0,0 +1,698 @@
+<?php
+
+/**
+ * LDAP authentication backend
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakaic.co.uk>
+ * @author Jan Schumann <js@schumann-it.com>
+ */
+class auth_plugin_authldap extends DokuWiki_Auth_Plugin
+{
+ /* @var resource $con holds the LDAP connection */
+ protected $con = null;
+
+ /* @var int $bound What type of connection does already exist? */
+ protected $bound = 0; // 0: anonymous, 1: user, 2: superuser
+
+ /* @var array $users User data cache */
+ protected $users = null;
+
+ /* @var array $pattern User filter pattern */
+ protected $pattern = null;
+
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ parent::__construct();
+
+ // ldap extension is needed
+ if (!function_exists('ldap_connect')) {
+ $this->debug("LDAP err: PHP LDAP extension not found.", -1, __LINE__, __FILE__);
+ $this->success = false;
+ return;
+ }
+
+ // Add the capabilities to change the password
+ $this->cando['modPass'] = $this->getConf('modPass');
+ }
+
+ /**
+ * Check user+password
+ *
+ * Checks if the given user exists and the given
+ * plaintext password is correct by trying to bind
+ * to the LDAP server
+ *
+ * @param string $user
+ * @param string $pass
+ * @return bool
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ public function checkPass($user, $pass)
+ {
+ // reject empty password
+ if (empty($pass)) return false;
+ if (!$this->openLDAP()) return false;
+
+ // indirect user bind
+ if ($this->getConf('binddn') && $this->getConf('bindpw')) {
+ // use superuser credentials
+ if (!@ldap_bind($this->con, $this->getConf('binddn'), conf_decodeString($this->getConf('bindpw')))) {
+ $this->debug('LDAP bind as superuser: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ return false;
+ }
+ $this->bound = 2;
+ } elseif ($this->getConf('binddn') &&
+ $this->getConf('usertree') &&
+ $this->getConf('userfilter')
+ ) {
+ // special bind string
+ $dn = $this->makeFilter(
+ $this->getConf('binddn'),
+ array('user' => $user, 'server' => $this->getConf('server'))
+ );
+ } elseif (strpos($this->getConf('usertree'), '%{user}')) {
+ // direct user bind
+ $dn = $this->makeFilter(
+ $this->getConf('usertree'),
+ array('user' => $user, 'server' => $this->getConf('server'))
+ );
+ } else {
+ // Anonymous bind
+ if (!@ldap_bind($this->con)) {
+ msg("LDAP: can not bind anonymously", -1);
+ $this->debug('LDAP anonymous bind: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ return false;
+ }
+ }
+
+ // Try to bind to with the dn if we have one.
+ if (!empty($dn)) {
+ // User/Password bind
+ if (!@ldap_bind($this->con, $dn, $pass)) {
+ $this->debug("LDAP: bind with $dn failed", -1, __LINE__, __FILE__);
+ $this->debug('LDAP user dn bind: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ return false;
+ }
+ $this->bound = 1;
+ return true;
+ } else {
+ // See if we can find the user
+ $info = $this->fetchUserData($user, true);
+ if (empty($info['dn'])) {
+ return false;
+ } else {
+ $dn = $info['dn'];
+ }
+
+ // Try to bind with the dn provided
+ if (!@ldap_bind($this->con, $dn, $pass)) {
+ $this->debug("LDAP: bind with $dn failed", -1, __LINE__, __FILE__);
+ $this->debug('LDAP user bind: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ return false;
+ }
+ $this->bound = 1;
+ return true;
+ }
+ }
+
+ /**
+ * Return user info
+ *
+ * Returns info about the given user needs to contain
+ * at least these fields:
+ *
+ * name string full name of the user
+ * mail string email addres of the user
+ * grps array list of groups the user is in
+ *
+ * This LDAP specific function returns the following
+ * addional fields:
+ *
+ * dn string distinguished name (DN)
+ * uid string Posix User ID
+ * inbind bool for internal use - avoid loop in binding
+ *
+ * @param string $user
+ * @param bool $requireGroups (optional) - ignored, groups are always supplied by this plugin
+ * @return array containing user data or false
+ * @author <evaldas.auryla@pheur.org>
+ * @author Stephane Chazelas <stephane.chazelas@emerson.com>
+ * @author Steffen Schoch <schoch@dsb.net>
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Trouble
+ * @author Dan Allen <dan.j.allen@gmail.com>
+ */
+ public function getUserData($user, $requireGroups = true)
+ {
+ return $this->fetchUserData($user);
+ }
+
+ /**
+ * @param string $user
+ * @param bool $inbind authldap specific, true if in bind phase
+ * @return array containing user data or false
+ */
+ protected function fetchUserData($user, $inbind = false)
+ {
+ global $conf;
+ if (!$this->openLDAP()) return array();
+
+ // force superuser bind if wanted and not bound as superuser yet
+ if ($this->getConf('binddn') && $this->getConf('bindpw') && $this->bound < 2) {
+ // use superuser credentials
+ if (!@ldap_bind($this->con, $this->getConf('binddn'), conf_decodeString($this->getConf('bindpw')))) {
+ $this->debug('LDAP bind as superuser: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ return array();
+ }
+ $this->bound = 2;
+ } elseif ($this->bound == 0 && !$inbind) {
+ // in some cases getUserData is called outside the authentication workflow
+ // eg. for sending email notification on subscribed pages. This data might not
+ // be accessible anonymously, so we try to rebind the current user here
+ list($loginuser, $loginsticky, $loginpass) = auth_getCookie();
+ if ($loginuser && $loginpass) {
+ $loginpass = auth_decrypt($loginpass, auth_cookiesalt(!$loginsticky, true));
+ $this->checkPass($loginuser, $loginpass);
+ }
+ }
+
+ $info = array();
+ $info['user'] = $user;
+ $this->debug('LDAP user to find: ' . hsc($info['user']), 0, __LINE__, __FILE__);
+
+ $info['server'] = $this->getConf('server');
+ $this->debug('LDAP Server: ' . hsc($info['server']), 0, __LINE__, __FILE__);
+
+ //get info for given user
+ $base = $this->makeFilter($this->getConf('usertree'), $info);
+ if ($this->getConf('userfilter')) {
+ $filter = $this->makeFilter($this->getConf('userfilter'), $info);
+ } else {
+ $filter = "(ObjectClass=*)";
+ }
+
+ $this->debug('LDAP Filter: ' . hsc($filter), 0, __LINE__, __FILE__);
+
+ $this->debug('LDAP user search: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ $this->debug('LDAP search at: ' . hsc($base . ' ' . $filter), 0, __LINE__, __FILE__);
+ $sr = $this->ldapSearch($this->con, $base, $filter, $this->getConf('userscope'), $this->getConf('attributes'));
+
+
+ $result = @ldap_get_entries($this->con, $sr);
+
+ // if result is not an array
+ if (!is_array($result)) {
+ // no objects found
+ $this->debug('LDAP search returned non-array result: ' . hsc(print($result)), -1, __LINE__, __FILE__);
+ return array();
+ }
+
+ // Don't accept more or less than one response
+ if ($result['count'] != 1) {
+ $this->debug(
+ 'LDAP search returned ' . hsc($result['count']) . ' results while it should return 1!',
+ -1,
+ __LINE__,
+ __FILE__
+ );
+ //for($i = 0; $i < $result["count"]; $i++) {
+ //$this->_debug('result: '.hsc(print_r($result[$i])), 0, __LINE__, __FILE__);
+ //}
+ return array();
+ }
+
+ $this->debug('LDAP search found single result !', 0, __LINE__, __FILE__);
+
+ $user_result = $result[0];
+ ldap_free_result($sr);
+
+ // general user info
+ $info['dn'] = $user_result['dn'];
+ $info['gid'] = $user_result['gidnumber'][0];
+ $info['mail'] = $user_result['mail'][0];
+ $info['name'] = $user_result['cn'][0];
+ $info['grps'] = array();
+
+ // overwrite if other attribs are specified.
+ if (is_array($this->getConf('mapping'))) {
+ foreach ($this->getConf('mapping') as $localkey => $key) {
+ if (is_array($key)) {
+ // use regexp to clean up user_result
+ // $key = array($key=>$regexp), only handles the first key-value
+ $regexp = current($key);
+ $key = key($key);
+ if ($user_result[$key]) foreach ($user_result[$key] as $grpkey => $grp) {
+ if ($grpkey !== 'count' && preg_match($regexp, $grp, $match)) {
+ if ($localkey == 'grps') {
+ $info[$localkey][] = $match[1];
+ } else {
+ $info[$localkey] = $match[1];
+ }
+ }
+ }
+ } else {
+ $info[$localkey] = $user_result[$key][0];
+ }
+ }
+ }
+ $user_result = array_merge($info, $user_result);
+
+ //get groups for given user if grouptree is given
+ if ($this->getConf('grouptree') || $this->getConf('groupfilter')) {
+ $base = $this->makeFilter($this->getConf('grouptree'), $user_result);
+ $filter = $this->makeFilter($this->getConf('groupfilter'), $user_result);
+ $sr = $this->ldapSearch(
+ $this->con,
+ $base,
+ $filter,
+ $this->getConf('groupscope'),
+ array($this->getConf('groupkey'))
+ );
+ $this->debug('LDAP group search: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ $this->debug('LDAP search at: ' . hsc($base . ' ' . $filter), 0, __LINE__, __FILE__);
+
+ if (!$sr) {
+ msg("LDAP: Reading group memberships failed", -1);
+ return array();
+ }
+ $result = ldap_get_entries($this->con, $sr);
+ ldap_free_result($sr);
+
+ if (is_array($result)) foreach ($result as $grp) {
+ if (!empty($grp[$this->getConf('groupkey')])) {
+ $group = $grp[$this->getConf('groupkey')];
+ if (is_array($group)) {
+ $group = $group[0];
+ } else {
+ $this->debug('groupkey did not return a detailled result', 0, __LINE__, __FILE__);
+ }
+ if ($group === '') continue;
+
+ $this->debug('LDAP usergroup: ' . hsc($group), 0, __LINE__, __FILE__);
+ $info['grps'][] = $group;
+ }
+ }
+ }
+
+ // always add the default group to the list of groups
+ if (!$info['grps'] or !in_array($conf['defaultgroup'], $info['grps'])) {
+ $info['grps'][] = $conf['defaultgroup'];
+ }
+ return $info;
+ }
+
+ /**
+ * Definition of the function modifyUser in order to modify the password
+ *
+ * @param string $user nick of the user to be changed
+ * @param array $changes array of field/value pairs to be changed (password will be clear text)
+ * @return bool true on success, false on error
+ */
+ public function modifyUser($user, $changes)
+ {
+
+ // open the connection to the ldap
+ if (!$this->openLDAP()) {
+ $this->debug('LDAP cannot connect: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ return false;
+ }
+
+ // find the information about the user, in particular the "dn"
+ $info = $this->getUserData($user, true);
+ if (empty($info['dn'])) {
+ $this->debug('LDAP cannot find your user dn', 0, __LINE__, __FILE__);
+ return false;
+ }
+ $dn = $info['dn'];
+
+ // find the old password of the user
+ list($loginuser, $loginsticky, $loginpass) = auth_getCookie();
+ if ($loginuser !== null) { // the user is currently logged in
+ $secret = auth_cookiesalt(!$loginsticky, true);
+ $pass = auth_decrypt($loginpass, $secret);
+
+ // bind with the ldap
+ if (!@ldap_bind($this->con, $dn, $pass)) {
+ $this->debug(
+ 'LDAP user bind failed: ' . hsc($dn) . ': ' . hsc(ldap_error($this->con)),
+ 0,
+ __LINE__,
+ __FILE__
+ );
+ return false;
+ }
+ } elseif ($this->getConf('binddn') && $this->getConf('bindpw')) {
+ // we are changing the password on behalf of the user (eg: forgotten password)
+ // bind with the superuser ldap
+ if (!@ldap_bind($this->con, $this->getConf('binddn'), conf_decodeString($this->getConf('bindpw')))) {
+ $this->debug('LDAP bind as superuser: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ return false;
+ }
+ } else {
+ return false; // no otherway
+ }
+
+ // Generate the salted hashed password for LDAP
+ $phash = new \dokuwiki\PassHash();
+ $hash = $phash->hash_ssha($changes['pass']);
+
+ // change the password
+ if (!@ldap_mod_replace($this->con, $dn, array('userpassword' => $hash))) {
+ $this->debug(
+ 'LDAP mod replace failed: ' . hsc($dn) . ': ' . hsc(ldap_error($this->con)),
+ 0,
+ __LINE__,
+ __FILE__
+ );
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Most values in LDAP are case-insensitive
+ *
+ * @return bool
+ */
+ public function isCaseSensitive()
+ {
+ return false;
+ }
+
+ /**
+ * Bulk retrieval of user data
+ *
+ * @param int $start index of first user to be returned
+ * @param int $limit max number of users to be returned
+ * @param array $filter array of field/pattern pairs, null for no filter
+ * @return array of userinfo (refer getUserData for internal userinfo details)
+ * @author Dominik Eckelmann <dokuwiki@cosmocode.de>
+ */
+ public function retrieveUsers($start = 0, $limit = 0, $filter = array())
+ {
+ if (!$this->openLDAP()) return array();
+
+ if (is_null($this->users)) {
+ // Perform the search and grab all their details
+ if ($this->getConf('userfilter')) {
+ $all_filter = str_replace('%{user}', '*', $this->getConf('userfilter'));
+ } else {
+ $all_filter = "(ObjectClass=*)";
+ }
+ $sr = ldap_search($this->con, $this->getConf('usertree'), $all_filter);
+ $entries = ldap_get_entries($this->con, $sr);
+ $users_array = array();
+ $userkey = $this->getConf('userkey');
+ for ($i = 0; $i < $entries["count"]; $i++) {
+ array_push($users_array, $entries[$i][$userkey][0]);
+ }
+ asort($users_array);
+ $result = $users_array;
+ if (!$result) return array();
+ $this->users = array_fill_keys($result, false);
+ }
+ $i = 0;
+ $count = 0;
+ $this->constructPattern($filter);
+ $result = array();
+
+ foreach ($this->users as $user => &$info) {
+ if ($i++ < $start) {
+ continue;
+ }
+ if ($info === false) {
+ $info = $this->getUserData($user);
+ }
+ if ($this->filter($user, $info)) {
+ $result[$user] = $info;
+ if (($limit > 0) && (++$count >= $limit)) break;
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * Make LDAP filter strings.
+ *
+ * Used by auth_getUserData to make the filter
+ * strings for grouptree and groupfilter
+ *
+ * @param string $filter ldap search filter with placeholders
+ * @param array $placeholders placeholders to fill in
+ * @return string
+ * @author Troels Liebe Bentsen <tlb@rapanden.dk>
+ */
+ protected function makeFilter($filter, $placeholders)
+ {
+ preg_match_all("/%{([^}]+)/", $filter, $matches, PREG_PATTERN_ORDER);
+ //replace each match
+ foreach ($matches[1] as $match) {
+ //take first element if array
+ if (is_array($placeholders[$match])) {
+ $value = $placeholders[$match][0];
+ } else {
+ $value = $placeholders[$match];
+ }
+ $value = $this->filterEscape($value);
+ $filter = str_replace('%{' . $match . '}', $value, $filter);
+ }
+ return $filter;
+ }
+
+ /**
+ * return true if $user + $info match $filter criteria, false otherwise
+ *
+ * @param string $user the user's login name
+ * @param array $info the user's userinfo array
+ * @return bool
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ */
+ protected function filter($user, $info)
+ {
+ foreach ($this->pattern as $item => $pattern) {
+ if ($item == 'user') {
+ if (!preg_match($pattern, $user)) return false;
+ } elseif ($item == 'grps') {
+ if (!count(preg_grep($pattern, $info['grps']))) return false;
+ } else {
+ if (!preg_match($pattern, $info[$item])) return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Set the filter pattern
+ *
+ * @param $filter
+ * @return void
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ */
+ protected function constructPattern($filter)
+ {
+ $this->pattern = array();
+ foreach ($filter as $item => $pattern) {
+ $this->pattern[$item] = '/' . str_replace('/', '\/', $pattern) . '/i'; // allow regex characters
+ }
+ }
+
+ /**
+ * Escape a string to be used in a LDAP filter
+ *
+ * Ported from Perl's Net::LDAP::Util escape_filter_value
+ *
+ * @param string $string
+ * @return string
+ * @author Andreas Gohr
+ */
+ protected function filterEscape($string)
+ {
+ // see https://github.com/adldap/adLDAP/issues/22
+ return preg_replace_callback(
+ '/([\x00-\x1F\*\(\)\\\\])/',
+ function ($matches) {
+ return "\\" . join("", unpack("H2", $matches[1]));
+ },
+ $string
+ );
+ }
+
+ /**
+ * Opens a connection to the configured LDAP server and sets the wanted
+ * option on the connection
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function openLDAP()
+ {
+ if ($this->con) return true; // connection already established
+
+ if ($this->getConf('debug')) {
+ ldap_set_option(null, LDAP_OPT_DEBUG_LEVEL, 7);
+ }
+
+ $this->bound = 0;
+
+ $port = $this->getConf('port');
+ $bound = false;
+ $servers = explode(',', $this->getConf('server'));
+ foreach ($servers as $server) {
+ $server = trim($server);
+ $this->con = @ldap_connect($server, $port);
+ if (!$this->con) {
+ continue;
+ }
+
+ /*
+ * When OpenLDAP 2.x.x is used, ldap_connect() will always return a resource as it does
+ * not actually connect but just initializes the connecting parameters. The actual
+ * connect happens with the next calls to ldap_* funcs, usually with ldap_bind().
+ *
+ * So we should try to bind to server in order to check its availability.
+ */
+
+ //set protocol version and dependend options
+ if ($this->getConf('version')) {
+ if (!@ldap_set_option(
+ $this->con,
+ LDAP_OPT_PROTOCOL_VERSION,
+ $this->getConf('version')
+ )
+ ) {
+ msg('Setting LDAP Protocol version ' . $this->getConf('version') . ' failed', -1);
+ $this->debug('LDAP version set: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ } else {
+ //use TLS (needs version 3)
+ if ($this->getConf('starttls')) {
+ if (!@ldap_start_tls($this->con)) {
+ msg('Starting TLS failed', -1);
+ $this->debug('LDAP TLS set: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ }
+ }
+ // needs version 3
+ if ($this->getConf('referrals') > -1) {
+ if (!@ldap_set_option(
+ $this->con,
+ LDAP_OPT_REFERRALS,
+ $this->getConf('referrals')
+ )
+ ) {
+ msg('Setting LDAP referrals failed', -1);
+ $this->debug('LDAP referal set: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ }
+ }
+ }
+ }
+
+ //set deref mode
+ if ($this->getConf('deref')) {
+ if (!@ldap_set_option($this->con, LDAP_OPT_DEREF, $this->getConf('deref'))) {
+ msg('Setting LDAP Deref mode ' . $this->getConf('deref') . ' failed', -1);
+ $this->debug('LDAP deref set: ' . hsc(ldap_error($this->con)), 0, __LINE__, __FILE__);
+ }
+ }
+ /* As of PHP 5.3.0 we can set timeout to speedup skipping of invalid servers */
+ if (defined('LDAP_OPT_NETWORK_TIMEOUT')) {
+ ldap_set_option($this->con, LDAP_OPT_NETWORK_TIMEOUT, 1);
+ }
+
+ if ($this->getConf('binddn') && $this->getConf('bindpw')) {
+ $bound = @ldap_bind($this->con, $this->getConf('binddn'), conf_decodeString($this->getConf('bindpw')));
+ $this->bound = 2;
+ } else {
+ $bound = @ldap_bind($this->con);
+ }
+ if ($bound) {
+ break;
+ }
+ }
+
+ if (!$bound) {
+ msg("LDAP: couldn't connect to LDAP server", -1);
+ $this->debug(ldap_error($this->con), 0, __LINE__, __FILE__);
+ return false;
+ }
+
+ $this->cando['getUsers'] = true;
+ return true;
+ }
+
+ /**
+ * Wraps around ldap_search, ldap_list or ldap_read depending on $scope
+ *
+ * @param resource $link_identifier
+ * @param string $base_dn
+ * @param string $filter
+ * @param string $scope can be 'base', 'one' or 'sub'
+ * @param null|array $attributes
+ * @param int $attrsonly
+ * @param int $sizelimit
+ * @return resource
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function ldapSearch(
+ $link_identifier,
+ $base_dn,
+ $filter,
+ $scope = 'sub',
+ $attributes = null,
+ $attrsonly = 0,
+ $sizelimit = 0
+ )
+ {
+ if (is_null($attributes)) $attributes = array();
+
+ if ($scope == 'base') {
+ return @ldap_read(
+ $link_identifier,
+ $base_dn,
+ $filter,
+ $attributes,
+ $attrsonly,
+ $sizelimit
+ );
+ } elseif ($scope == 'one') {
+ return @ldap_list(
+ $link_identifier,
+ $base_dn,
+ $filter,
+ $attributes,
+ $attrsonly,
+ $sizelimit
+ );
+ } else {
+ return @ldap_search(
+ $link_identifier,
+ $base_dn,
+ $filter,
+ $attributes,
+ $attrsonly,
+ $sizelimit
+ );
+ }
+ }
+
+ /**
+ * Wrapper around msg() but outputs only when debug is enabled
+ *
+ * @param string $message
+ * @param int $err
+ * @param int $line
+ * @param string $file
+ * @return void
+ */
+ protected function debug($message, $err, $line, $file)
+ {
+ if (!$this->getConf('debug')) return;
+ msg($message, $err, $line, $file);
+ }
+}
diff --git a/platform/www/lib/plugins/authldap/conf/default.php b/platform/www/lib/plugins/authldap/conf/default.php
new file mode 100644
index 0000000..52fa1e6
--- /dev/null
+++ b/platform/www/lib/plugins/authldap/conf/default.php
@@ -0,0 +1,23 @@
+<?php
+
+$conf['server'] = '';
+$conf['port'] = 389;
+$conf['usertree'] = '';
+$conf['grouptree'] = '';
+$conf['userfilter'] = '';
+$conf['groupfilter'] = '';
+$conf['version'] = 2;
+$conf['starttls'] = 0;
+$conf['referrals'] = -1;
+$conf['deref'] = 0;
+$conf['binddn'] = '';
+$conf['bindpw'] = '';
+//$conf['mapping']['name'] unsupported in config manager
+//$conf['mapping']['grps'] unsupported in config manager
+$conf['userscope'] = 'sub';
+$conf['groupscope'] = 'sub';
+$conf['userkey'] = 'uid';
+$conf['groupkey'] = 'cn';
+$conf['debug'] = 0;
+$conf['modPass'] = 1;
+$conf['attributes'] = array();
diff --git a/platform/www/lib/plugins/authldap/conf/metadata.php b/platform/www/lib/plugins/authldap/conf/metadata.php
new file mode 100644
index 0000000..3a58590
--- /dev/null
+++ b/platform/www/lib/plugins/authldap/conf/metadata.php
@@ -0,0 +1,22 @@
+<?php
+$meta['server'] = array('string','_caution' => 'danger');
+$meta['port'] = array('numeric','_caution' => 'danger');
+$meta['usertree'] = array('string','_caution' => 'danger');
+$meta['grouptree'] = array('string','_caution' => 'danger');
+$meta['userfilter'] = array('string','_caution' => 'danger');
+$meta['groupfilter'] = array('string','_caution' => 'danger');
+$meta['version'] = array('numeric','_caution' => 'danger');
+$meta['starttls'] = array('onoff','_caution' => 'danger');
+$meta['referrals'] = array('multichoice','_choices' => array(-1,0,1),'_caution' => 'danger');
+$meta['deref'] = array('multichoice','_choices' => array(0,1,2,3),'_caution' => 'danger');
+$meta['binddn'] = array('string','_caution' => 'danger');
+$meta['bindpw'] = array('password','_caution' => 'danger','_code'=>'base64');
+$meta['attributes'] = array('array');
+//$meta['mapping']['name'] unsupported in config manager
+//$meta['mapping']['grps'] unsupported in config manager
+$meta['userscope'] = array('multichoice','_choices' => array('sub','one','base'),'_caution' => 'danger');
+$meta['groupscope'] = array('multichoice','_choices' => array('sub','one','base'),'_caution' => 'danger');
+$meta['userkey'] = array('string','_caution' => 'danger');
+$meta['groupkey'] = array('string','_caution' => 'danger');
+$meta['debug'] = array('onoff','_caution' => 'security');
+$meta['modPass'] = array('onoff');
diff --git a/platform/www/lib/plugins/authldap/lang/en/lang.php b/platform/www/lib/plugins/authldap/lang/en/lang.php
new file mode 100644
index 0000000..8185a84
--- /dev/null
+++ b/platform/www/lib/plugins/authldap/lang/en/lang.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ * English language file for authldap plugin
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ */
+
+$lang['connectfail'] = 'LDAP cannot connect: %s';
+$lang['domainfail'] = 'LDAP cannot find your user dn';
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/authldap/lang/en/settings.php b/platform/www/lib/plugins/authldap/lang/en/settings.php
new file mode 100644
index 0000000..9988474
--- /dev/null
+++ b/platform/www/lib/plugins/authldap/lang/en/settings.php
@@ -0,0 +1,30 @@
+<?php
+$lang['server'] = 'Your LDAP server. Either hostname (<code>localhost</code>) or full qualified URL (<code>ldap://server.tld:389</code>)';
+$lang['port'] = 'LDAP server port if no full URL was given above';
+$lang['usertree'] = 'Where to find the user accounts. Eg. <code>ou=People, dc=server, dc=tld</code>';
+$lang['grouptree'] = 'Where to find the user groups. Eg. <code>ou=Group, dc=server, dc=tld</code>';
+$lang['userfilter'] = 'LDAP filter to search for user accounts. Eg. <code>(&amp;(uid=%{user})(objectClass=posixAccount))</code>';
+$lang['groupfilter'] = 'LDAP filter to search for groups. Eg. <code>(&amp;(objectClass=posixGroup)(|(gidNumber=%{gid})(memberUID=%{user})))</code>';
+$lang['version'] = 'The protocol version to use. You may need to set this to <code>3</code>';
+$lang['starttls'] = 'Use TLS connections?';
+$lang['referrals'] = 'Shall referrals be followed?';
+$lang['deref'] = 'How to dereference aliases?';
+$lang['binddn'] = 'DN of an optional bind user if anonymous bind is not sufficient. Eg. <code>cn=admin, dc=my, dc=home</code>';
+$lang['bindpw'] = 'Password of above user';
+$lang['attributes'] = 'Attributes to retrieve with the LDAP search.';
+$lang['userscope'] = 'Limit search scope for user search';
+$lang['groupscope'] = 'Limit search scope for group search';
+$lang['userkey'] = 'Attribute denoting the username; must be consistent to userfilter.';
+$lang['groupkey'] = 'Group membership from any user attribute (instead of standard AD groups) e.g. group from department or telephone number';
+$lang['modPass'] = 'Can the LDAP password be changed via dokuwiki?';
+$lang['debug'] = 'Display additional debug information on errors';
+
+
+$lang['deref_o_0'] = 'LDAP_DEREF_NEVER';
+$lang['deref_o_1'] = 'LDAP_DEREF_SEARCHING';
+$lang['deref_o_2'] = 'LDAP_DEREF_FINDING';
+$lang['deref_o_3'] = 'LDAP_DEREF_ALWAYS';
+
+$lang['referrals_o_-1'] = 'use default';
+$lang['referrals_o_0'] = 'don\'t follow referrals';
+$lang['referrals_o_1'] = 'follow referrals'; \ No newline at end of file
diff --git a/platform/www/lib/plugins/authldap/plugin.info.txt b/platform/www/lib/plugins/authldap/plugin.info.txt
new file mode 100644
index 0000000..e0c6144
--- /dev/null
+++ b/platform/www/lib/plugins/authldap/plugin.info.txt
@@ -0,0 +1,7 @@
+base authldap
+author Andreas Gohr
+email andi@splitbrain.org
+date 2015-07-13
+name LDAP Auth Plugin
+desc Provides user authentication against an LDAP server
+url http://www.dokuwiki.org/plugin:authldap
diff --git a/platform/www/lib/plugins/authpdo/README b/platform/www/lib/plugins/authpdo/README
new file mode 100644
index 0000000..c99bfbf
--- /dev/null
+++ b/platform/www/lib/plugins/authpdo/README
@@ -0,0 +1,27 @@
+authpdo Plugin for DokuWiki
+
+Authenticate against a database via PDO
+
+All documentation for this plugin can be found at
+https://www.dokuwiki.org/plugin:authpdo
+
+If you install this plugin manually, make sure it is installed in
+lib/plugins/authpdo/ - if the folder is called different it
+will not work!
+
+Please refer to http://www.dokuwiki.org/plugins for additional info
+on how to install plugins in DokuWiki.
+
+----
+Copyright (C) Andreas Gohr <andi@splitbrain.org>
+
+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; version 2 of the License
+
+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.
+
+See the COPYING file in your DokuWiki folder for details
diff --git a/platform/www/lib/plugins/authpdo/auth.php b/platform/www/lib/plugins/authpdo/auth.php
new file mode 100644
index 0000000..9c0968e
--- /dev/null
+++ b/platform/www/lib/plugins/authpdo/auth.php
@@ -0,0 +1,826 @@
+<?php
+/**
+ * DokuWiki Plugin authpdo (Auth Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+/**
+ * Class auth_plugin_authpdo
+ */
+class auth_plugin_authpdo extends DokuWiki_Auth_Plugin
+{
+
+ /** @var PDO */
+ protected $pdo;
+
+ /** @var null|array The list of all groups */
+ protected $groupcache = null;
+
+ /**
+ * Constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct(); // for compatibility
+
+ if (!class_exists('PDO')) {
+ $this->debugMsg('PDO extension for PHP not found.', -1, __LINE__);
+ $this->success = false;
+ return;
+ }
+
+ if (!$this->getConf('dsn')) {
+ $this->debugMsg('No DSN specified', -1, __LINE__);
+ $this->success = false;
+ return;
+ }
+
+ try {
+ $this->pdo = new PDO(
+ $this->getConf('dsn'),
+ $this->getConf('user'),
+ conf_decodeString($this->getConf('pass')),
+ array(
+ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // always fetch as array
+ PDO::ATTR_EMULATE_PREPARES => true, // emulating prepares allows us to reuse param names
+ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // we want exceptions, not error codes
+ )
+ );
+ } catch (PDOException $e) {
+ $this->debugMsg($e);
+ msg($this->getLang('connectfail'), -1);
+ $this->success = false;
+ return;
+ }
+
+ // can Users be created?
+ $this->cando['addUser'] = $this->checkConfig(
+ array(
+ 'select-user',
+ 'select-user-groups',
+ 'select-groups',
+ 'insert-user',
+ 'insert-group',
+ 'join-group'
+ )
+ );
+
+ // can Users be deleted?
+ $this->cando['delUser'] = $this->checkConfig(
+ array(
+ 'select-user',
+ 'select-user-groups',
+ 'select-groups',
+ 'leave-group',
+ 'delete-user'
+ )
+ );
+
+ // can login names be changed?
+ $this->cando['modLogin'] = $this->checkConfig(
+ array(
+ 'select-user',
+ 'select-user-groups',
+ 'update-user-login'
+ )
+ );
+
+ // can passwords be changed?
+ $this->cando['modPass'] = $this->checkConfig(
+ array(
+ 'select-user',
+ 'select-user-groups',
+ 'update-user-pass'
+ )
+ );
+
+ // can real names be changed?
+ $this->cando['modName'] = $this->checkConfig(
+ array(
+ 'select-user',
+ 'select-user-groups',
+ 'update-user-info:name'
+ )
+ );
+
+ // can real email be changed?
+ $this->cando['modMail'] = $this->checkConfig(
+ array(
+ 'select-user',
+ 'select-user-groups',
+ 'update-user-info:mail'
+ )
+ );
+
+ // can groups be changed?
+ $this->cando['modGroups'] = $this->checkConfig(
+ array(
+ 'select-user',
+ 'select-user-groups',
+ 'select-groups',
+ 'leave-group',
+ 'join-group',
+ 'insert-group'
+ )
+ );
+
+ // can a filtered list of users be retrieved?
+ $this->cando['getUsers'] = $this->checkConfig(
+ array(
+ 'list-users'
+ )
+ );
+
+ // can the number of users be retrieved?
+ $this->cando['getUserCount'] = $this->checkConfig(
+ array(
+ 'count-users'
+ )
+ );
+
+ // can a list of available groups be retrieved?
+ $this->cando['getGroups'] = $this->checkConfig(
+ array(
+ 'select-groups'
+ )
+ );
+
+ $this->success = true;
+ }
+
+ /**
+ * Check user+password
+ *
+ * @param string $user the user name
+ * @param string $pass the clear text password
+ * @return bool
+ */
+ public function checkPass($user, $pass)
+ {
+
+ $userdata = $this->selectUser($user);
+ if ($userdata == false) return false;
+
+ // password checking done in SQL?
+ if ($this->checkConfig(array('check-pass'))) {
+ $userdata['clear'] = $pass;
+ $userdata['hash'] = auth_cryptPassword($pass);
+ $result = $this->query($this->getConf('check-pass'), $userdata);
+ if ($result === false) return false;
+ return (count($result) == 1);
+ }
+
+ // we do password checking on our own
+ if (isset($userdata['hash'])) {
+ // hashed password
+ $passhash = new \dokuwiki\PassHash();
+ return $passhash->verify_hash($pass, $userdata['hash']);
+ } else {
+ // clear text password in the database O_o
+ return ($pass === $userdata['clear']);
+ }
+ }
+
+ /**
+ * Return user info
+ *
+ * Returns info about the given user needs to contain
+ * at least these fields:
+ *
+ * name string full name of the user
+ * mail string email addres of the user
+ * grps array list of groups the user is in
+ *
+ * @param string $user the user name
+ * @param bool $requireGroups whether or not the returned data must include groups
+ * @return array|bool containing user data or false
+ */
+ public function getUserData($user, $requireGroups = true)
+ {
+ $data = $this->selectUser($user);
+ if ($data == false) return false;
+
+ if (isset($data['hash'])) unset($data['hash']);
+ if (isset($data['clean'])) unset($data['clean']);
+
+ if ($requireGroups) {
+ $data['grps'] = $this->selectUserGroups($data);
+ if ($data['grps'] === false) return false;
+ }
+
+ return $data;
+ }
+
+ /**
+ * Create a new User [implement only where required/possible]
+ *
+ * Returns false if the user already exists, null when an error
+ * occurred and true if everything went well.
+ *
+ * The new user HAS TO be added to the default group by this
+ * function!
+ *
+ * Set addUser capability when implemented
+ *
+ * @param string $user
+ * @param string $clear
+ * @param string $name
+ * @param string $mail
+ * @param null|array $grps
+ * @return bool|null
+ */
+ public function createUser($user, $clear, $name, $mail, $grps = null)
+ {
+ global $conf;
+
+ if (($info = $this->getUserData($user, false)) !== false) {
+ msg($this->getLang('userexists'), -1);
+ return false; // user already exists
+ }
+
+ // prepare data
+ if ($grps == null) $grps = array();
+ array_unshift($grps, $conf['defaultgroup']);
+ $grps = array_unique($grps);
+ $hash = auth_cryptPassword($clear);
+ $userdata = compact('user', 'clear', 'hash', 'name', 'mail');
+
+ // action protected by transaction
+ $this->pdo->beginTransaction();
+ {
+ // insert the user
+ $ok = $this->query($this->getConf('insert-user'), $userdata);
+ if ($ok === false) goto FAIL;
+ $userdata = $this->getUserData($user, false);
+ if ($userdata === false) goto FAIL;
+
+ // create all groups that do not exist, the refetch the groups
+ $allgroups = $this->selectGroups();
+ foreach ($grps as $group) {
+ if (!isset($allgroups[$group])) {
+ $ok = $this->addGroup($group);
+ if ($ok === false) goto FAIL;
+ }
+ }
+ $allgroups = $this->selectGroups();
+
+ // add user to the groups
+ foreach ($grps as $group) {
+ $ok = $this->joinGroup($userdata, $allgroups[$group]);
+ if ($ok === false) goto FAIL;
+ }
+ }
+ $this->pdo->commit();
+ return true;
+
+ // something went wrong, rollback
+ FAIL:
+ $this->pdo->rollBack();
+ $this->debugMsg('Transaction rolled back', 0, __LINE__);
+ msg($this->getLang('writefail'), -1);
+ return null; // return error
+ }
+
+ /**
+ * Modify user data
+ *
+ * @param string $user nick of the user to be changed
+ * @param array $changes array of field/value pairs to be changed (password will be clear text)
+ * @return bool
+ */
+ public function modifyUser($user, $changes)
+ {
+ // secure everything in transaction
+ $this->pdo->beginTransaction();
+ {
+ $olddata = $this->getUserData($user);
+ $oldgroups = $olddata['grps'];
+ unset($olddata['grps']);
+
+ // changing the user name?
+ if (isset($changes['user'])) {
+ if ($this->getUserData($changes['user'], false)) goto FAIL;
+ $params = $olddata;
+ $params['newlogin'] = $changes['user'];
+
+ $ok = $this->query($this->getConf('update-user-login'), $params);
+ if ($ok === false) goto FAIL;
+ }
+
+ // changing the password?
+ if (isset($changes['pass'])) {
+ $params = $olddata;
+ $params['clear'] = $changes['pass'];
+ $params['hash'] = auth_cryptPassword($changes['pass']);
+
+ $ok = $this->query($this->getConf('update-user-pass'), $params);
+ if ($ok === false) goto FAIL;
+ }
+
+ // changing info?
+ if (isset($changes['mail']) || isset($changes['name'])) {
+ $params = $olddata;
+ if (isset($changes['mail'])) $params['mail'] = $changes['mail'];
+ if (isset($changes['name'])) $params['name'] = $changes['name'];
+
+ $ok = $this->query($this->getConf('update-user-info'), $params);
+ if ($ok === false) goto FAIL;
+ }
+
+ // changing groups?
+ if (isset($changes['grps'])) {
+ $allgroups = $this->selectGroups();
+
+ // remove membership for previous groups
+ foreach ($oldgroups as $group) {
+ if (!in_array($group, $changes['grps']) && isset($allgroups[$group])) {
+ $ok = $this->leaveGroup($olddata, $allgroups[$group]);
+ if ($ok === false) goto FAIL;
+ }
+ }
+
+ // create all new groups that are missing
+ $added = 0;
+ foreach ($changes['grps'] as $group) {
+ if (!isset($allgroups[$group])) {
+ $ok = $this->addGroup($group);
+ if ($ok === false) goto FAIL;
+ $added++;
+ }
+ }
+ // reload group info
+ if ($added > 0) $allgroups = $this->selectGroups();
+
+ // add membership for new groups
+ foreach ($changes['grps'] as $group) {
+ if (!in_array($group, $oldgroups)) {
+ $ok = $this->joinGroup($olddata, $allgroups[$group]);
+ if ($ok === false) goto FAIL;
+ }
+ }
+ }
+
+ }
+ $this->pdo->commit();
+ return true;
+
+ // something went wrong, rollback
+ FAIL:
+ $this->pdo->rollBack();
+ $this->debugMsg('Transaction rolled back', 0, __LINE__);
+ msg($this->getLang('writefail'), -1);
+ return false; // return error
+ }
+
+ /**
+ * Delete one or more users
+ *
+ * Set delUser capability when implemented
+ *
+ * @param array $users
+ * @return int number of users deleted
+ */
+ public function deleteUsers($users)
+ {
+ $count = 0;
+ foreach ($users as $user) {
+ if ($this->deleteUser($user)) $count++;
+ }
+ return $count;
+ }
+
+ /**
+ * Bulk retrieval of user data [implement only where required/possible]
+ *
+ * Set getUsers capability when implemented
+ *
+ * @param int $start index of first user to be returned
+ * @param int $limit max number of users to be returned
+ * @param array $filter array of field/pattern pairs, null for no filter
+ * @return array list of userinfo (refer getUserData for internal userinfo details)
+ */
+ public function retrieveUsers($start = 0, $limit = -1, $filter = null)
+ {
+ if ($limit < 0) $limit = 10000; // we don't support no limit
+ if (is_null($filter)) $filter = array();
+
+ if (isset($filter['grps'])) $filter['group'] = $filter['grps'];
+ foreach (array('user', 'name', 'mail', 'group') as $key) {
+ if (!isset($filter[$key])) {
+ $filter[$key] = '%';
+ } else {
+ $filter[$key] = '%' . $filter[$key] . '%';
+ }
+ }
+ $filter['start'] = (int)$start;
+ $filter['end'] = (int)$start + $limit;
+ $filter['limit'] = (int)$limit;
+
+ $result = $this->query($this->getConf('list-users'), $filter);
+ if (!$result) return array();
+ $users = array();
+ if (is_array($result)) {
+ foreach ($result as $row) {
+ if (!isset($row['user'])) {
+ $this->debugMsg("list-users statement did not return 'user' attribute", -1, __LINE__);
+ return array();
+ }
+ $users[] = $this->getUserData($row['user']);
+ }
+ } else {
+ $this->debugMsg("list-users statement did not return a list of result", -1, __LINE__);
+ }
+ return $users;
+ }
+
+ /**
+ * Return a count of the number of user which meet $filter criteria
+ *
+ * @param array $filter array of field/pattern pairs, empty array for no filter
+ * @return int
+ */
+ public function getUserCount($filter = array())
+ {
+ if (is_null($filter)) $filter = array();
+
+ if (isset($filter['grps'])) $filter['group'] = $filter['grps'];
+ foreach (array('user', 'name', 'mail', 'group') as $key) {
+ if (!isset($filter[$key])) {
+ $filter[$key] = '%';
+ } else {
+ $filter[$key] = '%' . $filter[$key] . '%';
+ }
+ }
+
+ $result = $this->query($this->getConf('count-users'), $filter);
+ if (!$result || !isset($result[0]['count'])) {
+ $this->debugMsg("Statement did not return 'count' attribute", -1, __LINE__);
+ }
+ return (int)$result[0]['count'];
+ }
+
+ /**
+ * Create a new group with the given name
+ *
+ * @param string $group
+ * @return bool
+ */
+ public function addGroup($group)
+ {
+ $sql = $this->getConf('insert-group');
+
+ $result = $this->query($sql, array(':group' => $group));
+ $this->clearGroupCache();
+ if ($result === false) return false;
+ return true;
+ }
+
+ /**
+ * Retrieve groups
+ *
+ * Set getGroups capability when implemented
+ *
+ * @param int $start
+ * @param int $limit
+ * @return array
+ */
+ public function retrieveGroups($start = 0, $limit = 0)
+ {
+ $groups = array_keys($this->selectGroups());
+ if ($groups === false) return array();
+
+ if (!$limit) {
+ return array_splice($groups, $start);
+ } else {
+ return array_splice($groups, $start, $limit);
+ }
+ }
+
+ /**
+ * Select data of a specified user
+ *
+ * @param string $user the user name
+ * @return bool|array user data, false on error
+ */
+ protected function selectUser($user)
+ {
+ $sql = $this->getConf('select-user');
+
+ $result = $this->query($sql, array(':user' => $user));
+ if (!$result) return false;
+
+ if (count($result) > 1) {
+ $this->debugMsg('Found more than one matching user', -1, __LINE__);
+ return false;
+ }
+
+ $data = array_shift($result);
+ $dataok = true;
+
+ if (!isset($data['user'])) {
+ $this->debugMsg("Statement did not return 'user' attribute", -1, __LINE__);
+ $dataok = false;
+ }
+ if (!isset($data['hash']) && !isset($data['clear']) && !$this->checkConfig(array('check-pass'))) {
+ $this->debugMsg("Statement did not return 'clear' or 'hash' attribute", -1, __LINE__);
+ $dataok = false;
+ }
+ if (!isset($data['name'])) {
+ $this->debugMsg("Statement did not return 'name' attribute", -1, __LINE__);
+ $dataok = false;
+ }
+ if (!isset($data['mail'])) {
+ $this->debugMsg("Statement did not return 'mail' attribute", -1, __LINE__);
+ $dataok = false;
+ }
+
+ if (!$dataok) return false;
+ return $data;
+ }
+
+ /**
+ * Delete a user after removing all their group memberships
+ *
+ * @param string $user
+ * @return bool true when the user was deleted
+ */
+ protected function deleteUser($user)
+ {
+ $this->pdo->beginTransaction();
+ {
+ $userdata = $this->getUserData($user);
+ if ($userdata === false) goto FAIL;
+ $allgroups = $this->selectGroups();
+
+ // remove group memberships (ignore errors)
+ foreach ($userdata['grps'] as $group) {
+ if (isset($allgroups[$group])) {
+ $this->leaveGroup($userdata, $allgroups[$group]);
+ }
+ }
+
+ $ok = $this->query($this->getConf('delete-user'), $userdata);
+ if ($ok === false) goto FAIL;
+ }
+ $this->pdo->commit();
+ return true;
+
+ FAIL:
+ $this->pdo->rollBack();
+ return false;
+ }
+
+ /**
+ * Select all groups of a user
+ *
+ * @param array $userdata The userdata as returned by _selectUser()
+ * @return array|bool list of group names, false on error
+ */
+ protected function selectUserGroups($userdata)
+ {
+ global $conf;
+ $sql = $this->getConf('select-user-groups');
+ $result = $this->query($sql, $userdata);
+ if ($result === false) return false;
+
+ $groups = array($conf['defaultgroup']); // always add default config
+ if (is_array($result)) {
+ foreach ($result as $row) {
+ if (!isset($row['group'])) {
+ $this->debugMsg("No 'group' field returned in select-user-groups statement", -1, __LINE__);
+ return false;
+ }
+ $groups[] = $row['group'];
+ }
+ } else {
+ $this->debugMsg("select-user-groups statement did not return a list of result", -1, __LINE__);
+ }
+
+ $groups = array_unique($groups);
+ sort($groups);
+ return $groups;
+ }
+
+ /**
+ * Select all available groups
+ *
+ * @return array|bool list of all available groups and their properties
+ */
+ protected function selectGroups()
+ {
+ if ($this->groupcache) return $this->groupcache;
+
+ $sql = $this->getConf('select-groups');
+ $result = $this->query($sql);
+ if ($result === false) return false;
+
+ $groups = array();
+ if (is_array($result)) {
+ foreach ($result as $row) {
+ if (!isset($row['group'])) {
+ $this->debugMsg("No 'group' field returned from select-groups statement", -1, __LINE__);
+ return false;
+ }
+
+ // relayout result with group name as key
+ $group = $row['group'];
+ $groups[$group] = $row;
+ }
+ } else {
+ $this->debugMsg("select-groups statement did not return a list of result", -1, __LINE__);
+ }
+
+ ksort($groups);
+ return $groups;
+ }
+
+ /**
+ * Remove all entries from the group cache
+ */
+ protected function clearGroupCache()
+ {
+ $this->groupcache = null;
+ }
+
+ /**
+ * Adds the user to the group
+ *
+ * @param array $userdata all the user data
+ * @param array $groupdata all the group data
+ * @return bool
+ */
+ protected function joinGroup($userdata, $groupdata)
+ {
+ $data = array_merge($userdata, $groupdata);
+ $sql = $this->getConf('join-group');
+ $result = $this->query($sql, $data);
+ if ($result === false) return false;
+ return true;
+ }
+
+ /**
+ * Removes the user from the group
+ *
+ * @param array $userdata all the user data
+ * @param array $groupdata all the group data
+ * @return bool
+ */
+ protected function leaveGroup($userdata, $groupdata)
+ {
+ $data = array_merge($userdata, $groupdata);
+ $sql = $this->getConf('leave-group');
+ $result = $this->query($sql, $data);
+ if ($result === false) return false;
+ return true;
+ }
+
+ /**
+ * Executes a query
+ *
+ * @param string $sql The SQL statement to execute
+ * @param array $arguments Named parameters to be used in the statement
+ * @return array|int|bool The result as associative array for SELECTs, affected rows for others, false on error
+ */
+ protected function query($sql, $arguments = array())
+ {
+ $sql = trim($sql);
+ if (empty($sql)) {
+ $this->debugMsg('No SQL query given', -1, __LINE__);
+ return false;
+ }
+
+ // execute
+ $params = array();
+ $sth = $this->pdo->prepare($sql);
+ $result = false;
+ try {
+ // prepare parameters - we only use those that exist in the SQL
+ foreach ($arguments as $key => $value) {
+ if (is_array($value)) continue;
+ if (is_object($value)) continue;
+ if ($key[0] != ':') $key = ":$key"; // prefix with colon if needed
+ if (strpos($sql, $key) === false) continue; // skip if parameter is missing
+
+ if (is_int($value)) {
+ $sth->bindValue($key, $value, PDO::PARAM_INT);
+ } else {
+ $sth->bindValue($key, $value);
+ }
+ $params[$key] = $value; //remember for debugging
+ }
+
+ $sth->execute();
+ // only report last line's result
+ $hasnextrowset = true;
+ $currentsql = $sql;
+ while ($hasnextrowset) {
+ if (strtolower(substr($currentsql, 0, 6)) == 'select') {
+ $result = $sth->fetchAll();
+ } else {
+ $result = $sth->rowCount();
+ }
+ $semi_pos = strpos($currentsql, ';');
+ if ($semi_pos) {
+ $currentsql = trim(substr($currentsql, $semi_pos + 1));
+ }
+ try {
+ $hasnextrowset = $sth->nextRowset(); // run next rowset
+ } catch (PDOException $rowset_e) {
+ $hasnextrowset = false; // driver does not support multi-rowset, should be executed in one time
+ }
+ }
+ } catch (Exception $e) {
+ // report the caller's line
+ $trace = debug_backtrace();
+ $line = $trace[0]['line'];
+ $dsql = $this->debugSQL($sql, $params, !defined('DOKU_UNITTEST'));
+ $this->debugMsg($e, -1, $line);
+ $this->debugMsg("SQL: <pre>$dsql</pre>", -1, $line);
+ }
+ $sth->closeCursor();
+ $sth = null;
+
+ return $result;
+ }
+
+ /**
+ * Wrapper around msg() but outputs only when debug is enabled
+ *
+ * @param string|Exception $message
+ * @param int $err
+ * @param int $line
+ */
+ protected function debugMsg($message, $err = 0, $line = 0)
+ {
+ if (!$this->getConf('debug')) return;
+ if (is_a($message, 'Exception')) {
+ $err = -1;
+ $msg = $message->getMessage();
+ if (!$line) $line = $message->getLine();
+ } else {
+ $msg = $message;
+ }
+
+ if (defined('DOKU_UNITTEST')) {
+ printf("\n%s, %s:%d\n", $msg, __FILE__, $line);
+ } else {
+ msg('authpdo: ' . $msg, $err, $line, __FILE__);
+ }
+ }
+
+ /**
+ * Check if the given config strings are set
+ *
+ * @param string[] $keys
+ * @return bool
+ * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net>
+ *
+ */
+ protected function checkConfig($keys)
+ {
+ foreach ($keys as $key) {
+ $params = explode(':', $key);
+ $key = array_shift($params);
+ $sql = trim($this->getConf($key));
+
+ // check if sql is set
+ if (!$sql) return false;
+ // check if needed params are there
+ foreach ($params as $param) {
+ if (strpos($sql, ":$param") === false) return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * create an approximation of the SQL string with parameters replaced
+ *
+ * @param string $sql
+ * @param array $params
+ * @param bool $htmlescape Should the result be escaped for output in HTML?
+ * @return string
+ */
+ protected function debugSQL($sql, $params, $htmlescape = true)
+ {
+ foreach ($params as $key => $val) {
+ if (is_int($val)) {
+ $val = $this->pdo->quote($val, PDO::PARAM_INT);
+ } elseif (is_bool($val)) {
+ $val = $this->pdo->quote($val, PDO::PARAM_BOOL);
+ } elseif (is_null($val)) {
+ $val = 'NULL';
+ } else {
+ $val = $this->pdo->quote($val);
+ }
+ $sql = str_replace($key, $val, $sql);
+ }
+ if ($htmlescape) $sql = hsc($sql);
+ return $sql;
+ }
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/authpdo/conf/default.php b/platform/www/lib/plugins/authpdo/conf/default.php
new file mode 100644
index 0000000..138ca2f
--- /dev/null
+++ b/platform/www/lib/plugins/authpdo/conf/default.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * Default settings for the authpdo plugin
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+$conf['debug'] = 0;
+$conf['dsn'] = '';
+$conf['user'] = '';
+$conf['pass'] = '';
+
+/**
+ * statement to select a single user identified by its login name
+ *
+ * input: :user
+ * return: user, name, mail, (clear|hash), [uid], [*]
+ */
+$conf['select-user'] = '';
+
+/**
+ * statement to check the password in SQL, optional when above returned clear or hash
+ *
+ * input: :user, :clear, :hash, [uid], [*]
+ * return: *
+ */
+$conf['check-pass'] = '';
+
+/**
+ * statement to select a single user identified by its login name
+ *
+ * input: :user, [uid]
+ * return: group
+ */
+$conf['select-user-groups'] = '';
+
+/**
+ * Select all the existing group names
+ *
+ * return: group, [gid], [*]
+ */
+$conf['select-groups'] = '';
+
+/**
+ * Create a new user
+ *
+ * input: :user, :name, :mail, (:clear|:hash)
+ */
+$conf['insert-user'] = '';
+
+/**
+ * Remove a user
+ *
+ * input: :user, [:uid], [*]
+ */
+$conf['delete-user'] = '';
+
+/**
+ * list user names matching the given criteria
+ *
+ * Make sure the list is distinct and sorted by user name. Apply the given limit and offset
+ *
+ * input: :user, :name, :mail, :group, :start, :end, :limit
+ * out: user
+ */
+$conf['list-users'] = '';
+
+/**
+ * count user names matching the given criteria
+ *
+ * Make sure the counted list is distinct
+ *
+ * input: :user, :name, :mail, :group
+ * out: count
+ */
+$conf['count-users'] = '';
+
+/**
+ * Update user data (except password and user name)
+ *
+ * input: :user, :name, :mail, [:uid], [*]
+ */
+$conf['update-user-info'] = '';
+
+/**
+ * Update user name aka login
+ *
+ * input: :user, :newlogin, [:uid], [*]
+ */
+$conf['update-user-login'] = '';
+
+/**
+ * Update user password
+ *
+ * input: :user, :clear, :hash, [:uid], [*]
+ */
+$conf['update-user-pass'] = '';
+
+/**
+ * Create a new group
+ *
+ * input: :group
+ */
+$conf['insert-group'] = '';
+
+/**
+ * Make user join group
+ *
+ * input: :user, [:uid], group, [:gid], [*]
+ */
+$conf['join-group'] = '';
+
+/**
+ * Make user leave group
+ *
+ * input: :user, [:uid], group, [:gid], [*]
+ */
+$conf['leave-group'] = '';
diff --git a/platform/www/lib/plugins/authpdo/conf/metadata.php b/platform/www/lib/plugins/authpdo/conf/metadata.php
new file mode 100644
index 0000000..34e60a4
--- /dev/null
+++ b/platform/www/lib/plugins/authpdo/conf/metadata.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Options for the authpdo plugin
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+$meta['debug'] = array('onoff', '_caution' => 'security');
+$meta['dsn'] = array('string', '_caution' => 'danger');
+$meta['user'] = array('string', '_caution' => 'danger');
+$meta['pass'] = array('password', '_caution' => 'danger', '_code' => 'base64');
+$meta['select-user'] = array('', '_caution' => 'danger');
+$meta['check-pass'] = array('', '_caution' => 'danger');
+$meta['select-user-groups'] = array('', '_caution' => 'danger');
+$meta['select-groups'] = array('', '_caution' => 'danger');
+$meta['insert-user'] = array('', '_caution' => 'danger');
+$meta['delete-user'] = array('', '_caution' => 'danger');
+$meta['list-users'] = array('', '_caution' => 'danger');
+$meta['count-users'] = array('', '_caution' => 'danger');
+$meta['update-user-info'] = array('', '_caution' => 'danger');
+$meta['update-user-login'] = array('', '_caution' => 'danger');
+$meta['update-user-pass'] = array('', '_caution' => 'danger');
+$meta['insert-group'] = array('', '_caution' => 'danger');
+$meta['join-group'] = array('', '_caution' => 'danger');
+$meta['leave-group'] = array('', '_caution' => 'danger');
diff --git a/platform/www/lib/plugins/authpdo/lang/en/lang.php b/platform/www/lib/plugins/authpdo/lang/en/lang.php
new file mode 100644
index 0000000..3e1482e
--- /dev/null
+++ b/platform/www/lib/plugins/authpdo/lang/en/lang.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * English language file for authpdo plugin
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ */
+
+$lang['connectfail'] = 'Failed to connect to database.';
+$lang['userexists'] = 'Sorry, a user with this login already exists.';
+$lang['writefail'] = 'Unable to modify user data. Please inform the Wiki-Admin';
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/authpdo/lang/en/settings.php b/platform/www/lib/plugins/authpdo/lang/en/settings.php
new file mode 100644
index 0000000..1aaaec0
--- /dev/null
+++ b/platform/www/lib/plugins/authpdo/lang/en/settings.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * english language file for authpdo plugin
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+$lang['debug'] = 'Print out detailed error messages. Should be disabled after setup.';
+$lang['dsn'] = 'The DSN to connect to the database.';
+$lang['user'] = 'The user for the above database connection (empty for sqlite)';
+$lang['pass'] = 'The password for the above database connection (empty for sqlite)';
+$lang['select-user'] = 'SQL Statement to select the data of a single user';
+$lang['select-user-groups'] = 'SQL Statement to select all groups of a single user';
+$lang['select-groups'] = 'SQL Statement to select all available groups';
+$lang['insert-user'] = 'SQL Statement to insert a new user into the database';
+$lang['delete-user'] = 'SQL Statement to remove a single user from the database';
+$lang['list-users'] = 'SQL Statement to list users matching a filter';
+$lang['count-users'] = 'SQL Statement to count users matching a filter';
+$lang['update-user-info'] = 'SQL Statement to update the full name and email address of a single user';
+$lang['update-user-login'] = 'SQL Statement to update the login name of a single user';
+$lang['update-user-pass'] = 'SQL Statement to update the password of a single user';
+$lang['insert-group'] = 'SQL Statement to insert a new group into the database';
+$lang['join-group'] = 'SQL Statement to add a user to an existing group';
+$lang['leave-group'] = 'SQL Statement to remove a user from a group';
+$lang['check-pass'] = 'SQL Statement to check the password for a user. Can be left empty if password info is fetched in select-user.';
diff --git a/platform/www/lib/plugins/authpdo/plugin.info.txt b/platform/www/lib/plugins/authpdo/plugin.info.txt
new file mode 100644
index 0000000..e60ff0b
--- /dev/null
+++ b/platform/www/lib/plugins/authpdo/plugin.info.txt
@@ -0,0 +1,7 @@
+base authpdo
+author Andreas Gohr
+email andi@splitbrain.org
+date 2016-08-20
+name authpdo plugin
+desc Authenticate against a database via PDO
+url https://www.dokuwiki.org/plugin:authpdo
diff --git a/platform/www/lib/plugins/authplain/auth.php b/platform/www/lib/plugins/authplain/auth.php
new file mode 100644
index 0000000..421af88
--- /dev/null
+++ b/platform/www/lib/plugins/authplain/auth.php
@@ -0,0 +1,494 @@
+<?php
+
+/**
+ * Plaintext authentication backend
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Jan Schumann <js@schumann-it.com>
+ */
+class auth_plugin_authplain extends DokuWiki_Auth_Plugin
+{
+ /** @var array user cache */
+ protected $users = null;
+
+ /** @var array filter pattern */
+ protected $pattern = array();
+
+ /** @var bool safe version of preg_split */
+ protected $pregsplit_safe = false;
+
+ /**
+ * Constructor
+ *
+ * Carry out sanity checks to ensure the object is
+ * able to operate. Set capabilities.
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ global $config_cascade;
+
+ if (!@is_readable($config_cascade['plainauth.users']['default'])) {
+ $this->success = false;
+ } else {
+ if (@is_writable($config_cascade['plainauth.users']['default'])) {
+ $this->cando['addUser'] = true;
+ $this->cando['delUser'] = true;
+ $this->cando['modLogin'] = true;
+ $this->cando['modPass'] = true;
+ $this->cando['modName'] = true;
+ $this->cando['modMail'] = true;
+ $this->cando['modGroups'] = true;
+ }
+ $this->cando['getUsers'] = true;
+ $this->cando['getUserCount'] = true;
+ $this->cando['getGroups'] = true;
+ }
+
+ $this->pregsplit_safe = version_compare(PCRE_VERSION, '6.7', '>=');
+ }
+
+ /**
+ * Check user+password
+ *
+ * Checks if the given user exists and the given
+ * plaintext password is correct
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $user
+ * @param string $pass
+ * @return bool
+ */
+ public function checkPass($user, $pass)
+ {
+ $userinfo = $this->getUserData($user);
+ if ($userinfo === false) return false;
+
+ return auth_verifyPassword($pass, $this->users[$user]['pass']);
+ }
+
+ /**
+ * Return user info
+ *
+ * Returns info about the given user needs to contain
+ * at least these fields:
+ *
+ * name string full name of the user
+ * mail string email addres of the user
+ * grps array list of groups the user is in
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $user
+ * @param bool $requireGroups (optional) ignored by this plugin, grps info always supplied
+ * @return array|false
+ */
+ public function getUserData($user, $requireGroups = true)
+ {
+ if ($this->users === null) $this->loadUserData();
+ return isset($this->users[$user]) ? $this->users[$user] : false;
+ }
+
+ /**
+ * Creates a string suitable for saving as a line
+ * in the file database
+ * (delimiters escaped, etc.)
+ *
+ * @param string $user
+ * @param string $pass
+ * @param string $name
+ * @param string $mail
+ * @param array $grps list of groups the user is in
+ * @return string
+ */
+ protected function createUserLine($user, $pass, $name, $mail, $grps)
+ {
+ $groups = join(',', $grps);
+ $userline = array($user, $pass, $name, $mail, $groups);
+ $userline = str_replace('\\', '\\\\', $userline); // escape \ as \\
+ $userline = str_replace(':', '\\:', $userline); // escape : as \:
+ $userline = join(':', $userline)."\n";
+ return $userline;
+ }
+
+ /**
+ * Create a new User
+ *
+ * Returns false if the user already exists, null when an error
+ * occurred and true if everything went well.
+ *
+ * The new user will be added to the default group by this
+ * function if grps are not specified (default behaviour).
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $user
+ * @param string $pwd
+ * @param string $name
+ * @param string $mail
+ * @param array $grps
+ * @return bool|null|string
+ */
+ public function createUser($user, $pwd, $name, $mail, $grps = null)
+ {
+ global $conf;
+ global $config_cascade;
+
+ // user mustn't already exist
+ if ($this->getUserData($user) !== false) {
+ msg($this->getLang('userexists'), -1);
+ return false;
+ }
+
+ $pass = auth_cryptPassword($pwd);
+
+ // set default group if no groups specified
+ if (!is_array($grps)) $grps = array($conf['defaultgroup']);
+
+ // prepare user line
+ $userline = $this->createUserLine($user, $pass, $name, $mail, $grps);
+
+ if (!io_saveFile($config_cascade['plainauth.users']['default'], $userline, true)) {
+ msg($this->getLang('writefail'), -1);
+ return null;
+ }
+
+ $this->users[$user] = compact('pass', 'name', 'mail', 'grps');
+ return $pwd;
+ }
+
+ /**
+ * Modify user data
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @param string $user nick of the user to be changed
+ * @param array $changes array of field/value pairs to be changed (password will be clear text)
+ * @return bool
+ */
+ public function modifyUser($user, $changes)
+ {
+ global $ACT;
+ global $config_cascade;
+
+ // sanity checks, user must already exist and there must be something to change
+ if (($userinfo = $this->getUserData($user)) === false) {
+ msg($this->getLang('usernotexists'), -1);
+ return false;
+ }
+
+ // don't modify protected users
+ if (!empty($userinfo['protected'])) {
+ msg(sprintf($this->getLang('protected'), hsc($user)), -1);
+ return false;
+ }
+
+ if (!is_array($changes) || !count($changes)) return true;
+
+ // update userinfo with new data, remembering to encrypt any password
+ $newuser = $user;
+ foreach ($changes as $field => $value) {
+ if ($field == 'user') {
+ $newuser = $value;
+ continue;
+ }
+ if ($field == 'pass') $value = auth_cryptPassword($value);
+ $userinfo[$field] = $value;
+ }
+
+ $userline = $this->createUserLine(
+ $newuser,
+ $userinfo['pass'],
+ $userinfo['name'],
+ $userinfo['mail'],
+ $userinfo['grps']
+ );
+
+ if (!io_replaceInFile($config_cascade['plainauth.users']['default'], '/^'.$user.':/', $userline, true)) {
+ msg('There was an error modifying your user data. You may need to register again.', -1);
+ // FIXME, io functions should be fail-safe so existing data isn't lost
+ $ACT = 'register';
+ return false;
+ }
+
+ $this->users[$newuser] = $userinfo;
+ return true;
+ }
+
+ /**
+ * Remove one or more users from the list of registered users
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @param array $users array of users to be deleted
+ * @return int the number of users deleted
+ */
+ public function deleteUsers($users)
+ {
+ global $config_cascade;
+
+ if (!is_array($users) || empty($users)) return 0;
+
+ if ($this->users === null) $this->loadUserData();
+
+ $deleted = array();
+ foreach ($users as $user) {
+ // don't delete protected users
+ if (!empty($this->users[$user]['protected'])) {
+ msg(sprintf($this->getLang('protected'), hsc($user)), -1);
+ continue;
+ }
+ if (isset($this->users[$user])) $deleted[] = preg_quote($user, '/');
+ }
+
+ if (empty($deleted)) return 0;
+
+ $pattern = '/^('.join('|', $deleted).'):/';
+ if (!io_deleteFromFile($config_cascade['plainauth.users']['default'], $pattern, true)) {
+ msg($this->getLang('writefail'), -1);
+ return 0;
+ }
+
+ // reload the user list and count the difference
+ $count = count($this->users);
+ $this->loadUserData();
+ $count -= count($this->users);
+ return $count;
+ }
+
+ /**
+ * Return a count of the number of user which meet $filter criteria
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param array $filter
+ * @return int
+ */
+ public function getUserCount($filter = array())
+ {
+
+ if ($this->users === null) $this->loadUserData();
+
+ if (!count($filter)) return count($this->users);
+
+ $count = 0;
+ $this->constructPattern($filter);
+
+ foreach ($this->users as $user => $info) {
+ $count += $this->filter($user, $info);
+ }
+
+ return $count;
+ }
+
+ /**
+ * Bulk retrieval of user data
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param int $start index of first user to be returned
+ * @param int $limit max number of users to be returned
+ * @param array $filter array of field/pattern pairs
+ * @return array userinfo (refer getUserData for internal userinfo details)
+ */
+ public function retrieveUsers($start = 0, $limit = 0, $filter = array())
+ {
+
+ if ($this->users === null) $this->loadUserData();
+
+ ksort($this->users);
+
+ $i = 0;
+ $count = 0;
+ $out = array();
+ $this->constructPattern($filter);
+
+ foreach ($this->users as $user => $info) {
+ if ($this->filter($user, $info)) {
+ if ($i >= $start) {
+ $out[$user] = $info;
+ $count++;
+ if (($limit > 0) && ($count >= $limit)) break;
+ }
+ $i++;
+ }
+ }
+
+ return $out;
+ }
+
+ /**
+ * Retrieves groups.
+ * Loads complete user data into memory before searching for groups.
+ *
+ * @param int $start index of first group to be returned
+ * @param int $limit max number of groups to be returned
+ * @return array
+ */
+ public function retrieveGroups($start = 0, $limit = 0)
+ {
+ $groups = [];
+
+ if ($this->users === null) $this->loadUserData();
+ foreach($this->users as $user => $info) {
+ $groups = array_merge($groups, array_diff($info['grps'], $groups));
+ }
+
+ if($limit > 0) {
+ return array_splice($groups, $start, $limit);
+ }
+ return array_splice($groups, $start);
+ }
+
+ /**
+ * Only valid pageid's (no namespaces) for usernames
+ *
+ * @param string $user
+ * @return string
+ */
+ public function cleanUser($user)
+ {
+ global $conf;
+ return cleanID(str_replace(':', $conf['sepchar'], $user));
+ }
+
+ /**
+ * Only valid pageid's (no namespaces) for groupnames
+ *
+ * @param string $group
+ * @return string
+ */
+ public function cleanGroup($group)
+ {
+ global $conf;
+ return cleanID(str_replace(':', $conf['sepchar'], $group));
+ }
+
+ /**
+ * Load all user data
+ *
+ * loads the user file into a datastructure
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ protected function loadUserData()
+ {
+ global $config_cascade;
+
+ $this->users = $this->readUserFile($config_cascade['plainauth.users']['default']);
+
+ // support protected users
+ if (!empty($config_cascade['plainauth.users']['protected'])) {
+ $protected = $this->readUserFile($config_cascade['plainauth.users']['protected']);
+ foreach (array_keys($protected) as $key) {
+ $protected[$key]['protected'] = true;
+ }
+ $this->users = array_merge($this->users, $protected);
+ }
+ }
+
+ /**
+ * Read user data from given file
+ *
+ * ignores non existing files
+ *
+ * @param string $file the file to load data from
+ * @return array
+ */
+ protected function readUserFile($file)
+ {
+ $users = array();
+ if (!file_exists($file)) return $users;
+
+ $lines = file($file);
+ foreach ($lines as $line) {
+ $line = preg_replace('/#.*$/', '', $line); //ignore comments
+ $line = trim($line);
+ if (empty($line)) continue;
+
+ $row = $this->splitUserData($line);
+ $row = str_replace('\\:', ':', $row);
+ $row = str_replace('\\\\', '\\', $row);
+
+ $groups = array_values(array_filter(explode(",", $row[4])));
+
+ $users[$row[0]]['pass'] = $row[1];
+ $users[$row[0]]['name'] = urldecode($row[2]);
+ $users[$row[0]]['mail'] = $row[3];
+ $users[$row[0]]['grps'] = $groups;
+ }
+ return $users;
+ }
+
+ /**
+ * Get the user line split into it's parts
+ *
+ * @param string $line
+ * @return string[]
+ */
+ protected function splitUserData($line)
+ {
+ // due to a bug in PCRE 6.6, preg_split will fail with the regex we use here
+ // refer github issues 877 & 885
+ if ($this->pregsplit_safe) {
+ return preg_split('/(?<![^\\\\]\\\\)\:/', $line, 5); // allow for : escaped as \:
+ }
+
+ $row = array();
+ $piece = '';
+ $len = strlen($line);
+ for ($i=0; $i<$len; $i++) {
+ if ($line[$i]=='\\') {
+ $piece .= $line[$i];
+ $i++;
+ if ($i>=$len) break;
+ } elseif ($line[$i]==':') {
+ $row[] = $piece;
+ $piece = '';
+ continue;
+ }
+ $piece .= $line[$i];
+ }
+ $row[] = $piece;
+
+ return $row;
+ }
+
+ /**
+ * return true if $user + $info match $filter criteria, false otherwise
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $user User login
+ * @param array $info User's userinfo array
+ * @return bool
+ */
+ protected function filter($user, $info)
+ {
+ foreach ($this->pattern as $item => $pattern) {
+ if ($item == 'user') {
+ if (!preg_match($pattern, $user)) return false;
+ } elseif ($item == 'grps') {
+ if (!count(preg_grep($pattern, $info['grps']))) return false;
+ } else {
+ if (!preg_match($pattern, $info[$item])) return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * construct a filter pattern
+ *
+ * @param array $filter
+ */
+ protected function constructPattern($filter)
+ {
+ $this->pattern = array();
+ foreach ($filter as $item => $pattern) {
+ $this->pattern[$item] = '/'.str_replace('/', '\/', $pattern).'/i'; // allow regex characters
+ }
+ }
+}
diff --git a/platform/www/lib/plugins/authplain/lang/en/lang.php b/platform/www/lib/plugins/authplain/lang/en/lang.php
new file mode 100644
index 0000000..7108f38
--- /dev/null
+++ b/platform/www/lib/plugins/authplain/lang/en/lang.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ */
+$lang['userexists'] = 'Sorry, a user with this login already exists.';
+$lang['usernotexists'] = 'Sorry, that user doesn\'t exist.';
+$lang['writefail'] = 'Unable to modify user data. Please inform the Wiki-Admin';
+$lang['protected'] = 'Data for user %s is protected and can not be modified or deleted.';
diff --git a/platform/www/lib/plugins/authplain/plugin.info.txt b/platform/www/lib/plugins/authplain/plugin.info.txt
new file mode 100644
index 0000000..c09dbcb
--- /dev/null
+++ b/platform/www/lib/plugins/authplain/plugin.info.txt
@@ -0,0 +1,7 @@
+base authplain
+author Andreas Gohr
+email andi@splitbrain.org
+date 2015-07-18
+name Plain Auth Plugin
+desc Provides user authentication against DokuWiki's local password storage
+url http://www.dokuwiki.org/plugin:authplain
diff --git a/platform/www/lib/plugins/cli.php b/platform/www/lib/plugins/cli.php
new file mode 100644
index 0000000..a3cbec7
--- /dev/null
+++ b/platform/www/lib/plugins/cli.php
@@ -0,0 +1,2 @@
+<?php
+dbg_deprecated('Autoloading. Do not require() files yourself.');
diff --git a/platform/www/lib/plugins/config/admin.php b/platform/www/lib/plugins/config/admin.php
new file mode 100644
index 0000000..219612c
--- /dev/null
+++ b/platform/www/lib/plugins/config/admin.php
@@ -0,0 +1,282 @@
+<?php
+/**
+ * Configuration Manager admin plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ */
+
+use dokuwiki\plugin\config\core\Configuration;
+use dokuwiki\plugin\config\core\Setting\Setting;
+use dokuwiki\plugin\config\core\Setting\SettingFieldset;
+use dokuwiki\plugin\config\core\Setting\SettingHidden;
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_config extends DokuWiki_Admin_Plugin {
+
+ const IMGDIR = DOKU_BASE . 'lib/plugins/config/images/';
+
+ /** @var Configuration */
+ protected $configuration;
+
+ /** @var bool were there any errors in the submitted data? */
+ protected $hasErrors = false;
+
+ /** @var bool have the settings translations been loaded? */
+ protected $promptsLocalized = false;
+
+
+ /**
+ * handle user request
+ */
+ public function handle() {
+ global $ID, $INPUT;
+
+ // always initialize the configuration
+ $this->configuration = new Configuration();
+
+ if(!$INPUT->bool('save') || !checkSecurityToken()) {
+ return;
+ }
+
+ // don't go any further if the configuration is locked
+ if($this->configuration->isLocked()) return;
+
+ // update settings and redirect of successful
+ $ok = $this->configuration->updateSettings($INPUT->arr('config'));
+ if($ok) { // no errors
+ try {
+ if($this->configuration->hasChanged()) {
+ $this->configuration->save();
+ } else {
+ $this->configuration->touch();
+ }
+ msg($this->getLang('updated'), 1);
+ } catch(Exception $e) {
+ msg($this->getLang('error'), -1);
+ }
+ send_redirect(wl($ID, array('do' => 'admin', 'page' => 'config'), true, '&'));
+ } else {
+ $this->hasErrors = true;
+ }
+ }
+
+ /**
+ * output appropriate html
+ */
+ public function html() {
+ $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here.
+ global $lang;
+ global $ID;
+
+ $this->setupLocale(true);
+
+ echo $this->locale_xhtml('intro');
+
+ echo '<div id="config__manager">';
+
+ if($this->configuration->isLocked()) {
+ echo '<div class="info">' . $this->getLang('locked') . '</div>';
+ }
+
+ // POST to script() instead of wl($ID) so config manager still works if
+ // rewrite config is broken. Add $ID as hidden field to remember
+ // current ID in most cases.
+ echo '<form id="dw__configform" action="' . script() . '" method="post">';
+ echo '<div class="no"><input type="hidden" name="id" value="' . $ID . '" /></div>';
+ formSecurityToken();
+ $this->printH1('dokuwiki_settings', $this->getLang('_header_dokuwiki'));
+
+ $in_fieldset = false;
+ $first_plugin_fieldset = true;
+ $first_template_fieldset = true;
+ foreach($this->configuration->getSettings() as $setting) {
+ if(is_a($setting, SettingHidden::class)) {
+ continue;
+ } else if(is_a($setting, settingFieldset::class)) {
+ // config setting group
+ if($in_fieldset) {
+ echo '</table>';
+ echo '</div>';
+ echo '</fieldset>';
+ } else {
+ $in_fieldset = true;
+ }
+ if($first_plugin_fieldset && $setting->getType() == 'plugin') {
+ $this->printH1('plugin_settings', $this->getLang('_header_plugin'));
+ $first_plugin_fieldset = false;
+ } else if($first_template_fieldset && $setting->getType() == 'template') {
+ $this->printH1('template_settings', $this->getLang('_header_template'));
+ $first_template_fieldset = false;
+ }
+ echo '<fieldset id="' . $setting->getKey() . '">';
+ echo '<legend>' . $setting->prompt($this) . '</legend>';
+ echo '<div class="table">';
+ echo '<table class="inline">';
+ } else {
+ // config settings
+ list($label, $input) = $setting->html($this, $this->hasErrors);
+
+ $class = $setting->isDefault()
+ ? ' class="default"'
+ : ($setting->isProtected() ? ' class="protected"' : '');
+ $error = $setting->hasError()
+ ? ' class="value error"'
+ : ' class="value"';
+ $icon = $setting->caution()
+ ? '<img src="' . self::IMGDIR . $setting->caution() . '.png" ' .
+ 'alt="' . $setting->caution() . '" title="' . $this->getLang($setting->caution()) . '" />'
+ : '';
+
+ echo '<tr' . $class . '>';
+ echo '<td class="label">';
+ echo '<span class="outkey">' . $setting->getPrettyKey() . '</span>';
+ echo $icon . $label;
+ echo '</td>';
+ echo '<td' . $error . '>' . $input . '</td>';
+ echo '</tr>';
+ }
+ }
+
+ echo '</table>';
+ echo '</div>';
+ if($in_fieldset) {
+ echo '</fieldset>';
+ }
+
+ // show undefined settings list
+ $undefined_settings = $this->configuration->getUndefined();
+ if($allow_debug && !empty($undefined_settings)) {
+ /**
+ * Callback for sorting settings
+ *
+ * @param Setting $a
+ * @param Setting $b
+ * @return int if $a is lower/equal/higher than $b
+ */
+ function settingNaturalComparison($a, $b) {
+ return strnatcmp($a->getKey(), $b->getKey());
+ }
+
+ usort($undefined_settings, 'settingNaturalComparison');
+ $this->printH1('undefined_settings', $this->getLang('_header_undefined'));
+ echo '<fieldset>';
+ echo '<div class="table">';
+ echo '<table class="inline">';
+ foreach($undefined_settings as $setting) {
+ list($label, $input) = $setting->html($this);
+ echo '<tr>';
+ echo '<td class="label">' . $label . '</td>';
+ echo '<td>' . $input . '</td>';
+ echo '</tr>';
+ }
+ echo '</table>';
+ echo '</div>';
+ echo '</fieldset>';
+ }
+
+ // finish up form
+ echo '<p>';
+ echo '<input type="hidden" name="do" value="admin" />';
+ echo '<input type="hidden" name="page" value="config" />';
+
+ if(!$this->configuration->isLocked()) {
+ echo '<input type="hidden" name="save" value="1" />';
+ echo '<button type="submit" name="submit" accesskey="s">' . $lang['btn_save'] . '</button>';
+ echo '<button type="reset">' . $lang['btn_reset'] . '</button>';
+ }
+
+ echo '</p>';
+
+ echo '</form>';
+ echo '</div>';
+ }
+
+ /**
+ * @param bool $prompts
+ */
+ public function setupLocale($prompts = false) {
+ parent::setupLocale();
+ if(!$prompts || $this->promptsLocalized) return;
+ $this->lang = array_merge($this->lang, $this->configuration->getLangs());
+ $this->promptsLocalized = true;
+ }
+
+ /**
+ * Generates a two-level table of contents for the config plugin.
+ *
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ *
+ * @return array
+ */
+ public function getTOC() {
+ $this->setupLocale(true);
+
+ $allow_debug = $GLOBALS['conf']['allowdebug']; // avoid global $conf; here.
+ $toc = array();
+ $check = false;
+
+ // gather settings data into three sub arrays
+ $labels = ['dokuwiki' => [], 'plugin' => [], 'template' => []];
+ foreach($this->configuration->getSettings() as $setting) {
+ if(is_a($setting, SettingFieldset::class)) {
+ $labels[$setting->getType()][] = $setting;
+ }
+ }
+
+ // top header
+ $title = $this->getLang('_configuration_manager');
+ $toc[] = html_mktocitem(sectionID($title, $check), $title, 1);
+
+ // main entries
+ foreach(['dokuwiki', 'plugin', 'template'] as $section) {
+ if(empty($labels[$section])) continue; // no entries, skip
+
+ // create main header
+ $toc[] = html_mktocitem(
+ $section . '_settings',
+ $this->getLang('_header_' . $section),
+ 1
+ );
+
+ // create sub headers
+ foreach($labels[$section] as $setting) {
+ /** @var SettingFieldset $setting */
+ $name = $setting->prompt($this);
+ $toc[] = html_mktocitem($setting->getKey(), $name, 2);
+ }
+ }
+
+ // undefined settings if allowed
+ if(count($this->configuration->getUndefined()) && $allow_debug) {
+ $toc[] = html_mktocitem('undefined_settings', $this->getLang('_header_undefined'), 1);
+ }
+
+ return $toc;
+ }
+
+ /**
+ * @param string $id
+ * @param string $text
+ */
+ protected function printH1($id, $text) {
+ echo '<h1 id="' . $id . '">' . $text . '</h1>';
+ }
+
+ /**
+ * Adds a translation to this plugin's language array
+ *
+ * Used by some settings to set up dynamic translations
+ *
+ * @param string $key
+ * @param string $value
+ */
+ public function addLang($key, $value) {
+ if(!$this->localised) $this->setupLocale();
+ $this->lang[$key] = $value;
+ }
+}
diff --git a/platform/www/lib/plugins/config/admin.svg b/platform/www/lib/plugins/config/admin.svg
new file mode 100644
index 0000000..ced9871
--- /dev/null
+++ b/platform/www/lib/plugins/config/admin.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 15.5A3.5 3.5 0 0 1 8.5 12 3.5 3.5 0 0 1 12 8.5a3.5 3.5 0 0 1 3.5 3.5 3.5 3.5 0 0 1-3.5 3.5m7.43-2.53c.04-.32.07-.64.07-.97 0-.33-.03-.66-.07-1l2.11-1.63c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.31-.61-.22l-2.49 1c-.52-.39-1.06-.73-1.69-.98l-.37-2.65A.506.506 0 0 0 14 2h-4c-.25 0-.46.18-.5.42l-.37 2.65c-.63.25-1.17.59-1.69.98l-2.49-1c-.22-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64L4.57 11c-.04.34-.07.67-.07 1 0 .33.03.65.07.97l-2.11 1.66c-.19.15-.25.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1.01c.52.4 1.06.74 1.69.99l.37 2.65c.04.24.25.42.5.42h4c.25 0 .46-.18.5-.42l.37-2.65c.63-.26 1.17-.59 1.69-.99l2.49 1.01c.22.08.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.66z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/plugins/config/core/ConfigParser.php b/platform/www/lib/plugins/config/core/ConfigParser.php
new file mode 100644
index 0000000..9e79b96
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/ConfigParser.php
@@ -0,0 +1,90 @@
+<?php
+
+namespace dokuwiki\plugin\config\core;
+
+/**
+ * A naive PHP file parser
+ *
+ * This parses our very simple config file in PHP format. We use this instead of simply including
+ * the file, because we want to keep expressions such as 24*60*60 as is.
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+class ConfigParser {
+ /** @var string variable to parse from the file */
+ protected $varname = 'conf';
+ /** @var string the key to mark sub arrays */
+ protected $keymarker = Configuration::KEYMARKER;
+
+ /**
+ * Parse the given PHP file into an array
+ *
+ * When the given files does not exist, this returns an empty array
+ *
+ * @param string $file
+ * @return array
+ */
+ public function parse($file) {
+ if(!file_exists($file)) return array();
+
+ $config = array();
+ $contents = @php_strip_whitespace($file);
+ $pattern = '/\$' . $this->varname . '\[[\'"]([^=]+)[\'"]\] ?= ?(.*?);(?=[^;]*(?:\$' . $this->varname . '|$))/s';
+ $matches = array();
+ preg_match_all($pattern, $contents, $matches, PREG_SET_ORDER);
+
+ for($i = 0; $i < count($matches); $i++) {
+ $value = $matches[$i][2];
+
+ // merge multi-dimensional array indices using the keymarker
+ $key = preg_replace('/.\]\[./', $this->keymarker, $matches[$i][1]);
+
+ // handle arrays
+ if(preg_match('/^array ?\((.*)\)/', $value, $match)) {
+ $arr = explode(',', $match[1]);
+
+ // remove quotes from quoted strings & unescape escaped data
+ $len = count($arr);
+ for($j = 0; $j < $len; $j++) {
+ $arr[$j] = trim($arr[$j]);
+ $arr[$j] = $this->readValue($arr[$j]);
+ }
+
+ $value = $arr;
+ } else {
+ $value = $this->readValue($value);
+ }
+
+ $config[$key] = $value;
+ }
+
+ return $config;
+ }
+
+ /**
+ * Convert php string into value
+ *
+ * @param string $value
+ * @return bool|string
+ */
+ protected function readValue($value) {
+ $removequotes_pattern = '/^(\'|")(.*)(?<!\\\\)\1$/s';
+ $unescape_pairs = array(
+ '\\\\' => '\\',
+ '\\\'' => '\'',
+ '\\"' => '"'
+ );
+
+ if($value == 'true') {
+ $value = true;
+ } elseif($value == 'false') {
+ $value = false;
+ } else {
+ // remove quotes from quoted strings & unescape escaped data
+ $value = preg_replace($removequotes_pattern, '$2', $value);
+ $value = strtr($value, $unescape_pairs);
+ }
+ return $value;
+ }
+
+}
diff --git a/platform/www/lib/plugins/config/core/Configuration.php b/platform/www/lib/plugins/config/core/Configuration.php
new file mode 100644
index 0000000..c58645c
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Configuration.php
@@ -0,0 +1,219 @@
+<?php
+
+namespace dokuwiki\plugin\config\core;
+
+use dokuwiki\plugin\config\core\Setting\Setting;
+use dokuwiki\plugin\config\core\Setting\SettingNoClass;
+use dokuwiki\plugin\config\core\Setting\SettingNoDefault;
+use dokuwiki\plugin\config\core\Setting\SettingNoKnownClass;
+use dokuwiki\plugin\config\core\Setting\SettingUndefined;
+
+/**
+ * Holds all the current settings and proxies the Loader and Writer
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class Configuration {
+
+ const KEYMARKER = '____';
+
+ /** @var Setting[] metadata as array of Settings objects */
+ protected $settings = array();
+ /** @var Setting[] undefined and problematic settings */
+ protected $undefined = array();
+
+ /** @var array all metadata */
+ protected $metadata;
+ /** @var array all default settings */
+ protected $default;
+ /** @var array all local settings */
+ protected $local;
+ /** @var array all protected settings */
+ protected $protected;
+
+ /** @var bool have the settings been changed since loading from disk? */
+ protected $changed = false;
+
+ /** @var Loader */
+ protected $loader;
+ /** @var Writer */
+ protected $writer;
+
+ /**
+ * ConfigSettings constructor.
+ */
+ public function __construct() {
+ $this->loader = new Loader(new ConfigParser());
+ $this->writer = new Writer();
+
+ $this->metadata = $this->loader->loadMeta();
+ $this->default = $this->loader->loadDefaults();
+ $this->local = $this->loader->loadLocal();
+ $this->protected = $this->loader->loadProtected();
+
+ $this->initSettings();
+ }
+
+ /**
+ * Get all settings
+ *
+ * @return Setting[]
+ */
+ public function getSettings() {
+ return $this->settings;
+ }
+
+ /**
+ * Get all unknown or problematic settings
+ *
+ * @return Setting[]
+ */
+ public function getUndefined() {
+ return $this->undefined;
+ }
+
+ /**
+ * Have the settings been changed since loading from disk?
+ *
+ * @return bool
+ */
+ public function hasChanged() {
+ return $this->changed;
+ }
+
+ /**
+ * Check if the config can be written
+ *
+ * @return bool
+ */
+ public function isLocked() {
+ return $this->writer->isLocked();
+ }
+
+ /**
+ * Update the settings using the data provided
+ *
+ * @param array $input as posted
+ * @return bool true if all updates went through, false on errors
+ */
+ public function updateSettings($input) {
+ $ok = true;
+
+ foreach($this->settings as $key => $obj) {
+ $value = isset($input[$key]) ? $input[$key] : null;
+ if($obj->update($value)) {
+ $this->changed = true;
+ }
+ if($obj->hasError()) $ok = false;
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Save the settings
+ *
+ * This save the current state as defined in this object, including the
+ * undefined settings
+ *
+ * @throws \Exception
+ */
+ public function save() {
+ // only save the undefined settings that have not been handled in settings
+ $undefined = array_diff_key($this->undefined, $this->settings);
+ $this->writer->save(array_merge($this->settings, $undefined));
+ }
+
+ /**
+ * Touch the settings
+ *
+ * @throws \Exception
+ */
+ public function touch() {
+ $this->writer->touch();
+ }
+
+ /**
+ * Load the extension language strings
+ *
+ * @return array
+ */
+ public function getLangs() {
+ return $this->loader->loadLangs();
+ }
+
+ /**
+ * Initalizes the $settings and $undefined properties
+ */
+ protected function initSettings() {
+ $keys = array_merge(
+ array_keys($this->metadata),
+ array_keys($this->default),
+ array_keys($this->local),
+ array_keys($this->protected)
+ );
+ $keys = array_unique($keys);
+
+ foreach($keys as $key) {
+ $obj = $this->instantiateClass($key);
+
+ if($obj->shouldHaveDefault() && !isset($this->default[$key])) {
+ $this->undefined[$key] = new SettingNoDefault($key);
+ }
+
+ $d = isset($this->default[$key]) ? $this->default[$key] : null;
+ $l = isset($this->local[$key]) ? $this->local[$key] : null;
+ $p = isset($this->protected[$key]) ? $this->protected[$key] : null;
+
+ $obj->initialize($d, $l, $p);
+ }
+ }
+
+ /**
+ * Instantiates the proper class for the given config key
+ *
+ * The class is added to the $settings or $undefined arrays and returned
+ *
+ * @param string $key
+ * @return Setting
+ */
+ protected function instantiateClass($key) {
+ if(isset($this->metadata[$key])) {
+ $param = $this->metadata[$key];
+ $class = $this->determineClassName(array_shift($param), $key); // first param is class
+ $obj = new $class($key, $param);
+ $this->settings[$key] = $obj;
+ } else {
+ $obj = new SettingUndefined($key);
+ $this->undefined[$key] = $obj;
+ }
+ return $obj;
+ }
+
+ /**
+ * Return the class to load
+ *
+ * @param string $class the class name as given in the meta file
+ * @param string $key the settings key
+ * @return string
+ */
+ protected function determineClassName($class, $key) {
+ // try namespaced class first
+ if(is_string($class)) {
+ $modern = str_replace('_', '', ucwords($class, '_'));
+ $modern = '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting' . $modern;
+ if($modern && class_exists($modern)) return $modern;
+ // try class as given
+ if(class_exists($class)) return $class;
+ // class wasn't found add to errors
+ $this->undefined[$key] = new SettingNoKnownClass($key);
+ } else {
+ // no class given, add to errors
+ $this->undefined[$key] = new SettingNoClass($key);
+ }
+ return '\\dokuwiki\\plugin\\config\\core\\Setting\\Setting';
+ }
+
+}
diff --git a/platform/www/lib/plugins/config/core/Loader.php b/platform/www/lib/plugins/config/core/Loader.php
new file mode 100644
index 0000000..90ad0f5
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Loader.php
@@ -0,0 +1,269 @@
+<?php
+
+namespace dokuwiki\plugin\config\core;
+
+use dokuwiki\Extension\Event;
+
+/**
+ * Configuration loader
+ *
+ * Loads configuration meta data and settings from the various files. Honors the
+ * configuration cascade and installed plugins.
+ */
+class Loader {
+ /** @var ConfigParser */
+ protected $parser;
+
+ /** @var string[] list of enabled plugins */
+ protected $plugins;
+ /** @var string current template */
+ protected $template;
+
+ /**
+ * Loader constructor.
+ * @param ConfigParser $parser
+ * @triggers PLUGIN_CONFIG_PLUGINLIST
+ */
+ public function __construct(ConfigParser $parser) {
+ global $conf;
+ $this->parser = $parser;
+ $this->plugins = plugin_list();
+ $this->template = $conf['template'];
+ // allow plugins to remove configurable plugins
+ Event::createAndTrigger('PLUGIN_CONFIG_PLUGINLIST', $this->plugins);
+ }
+
+ /**
+ * Read the settings meta data
+ *
+ * Reads the main file, plugins and template settings meta data
+ *
+ * @return array
+ */
+ public function loadMeta() {
+ // load main file
+ $meta = array();
+ include DOKU_PLUGIN . 'config/settings/config.metadata.php';
+
+ // plugins
+ foreach($this->plugins as $plugin) {
+ $meta = array_merge(
+ $meta,
+ $this->loadExtensionMeta(
+ DOKU_PLUGIN . $plugin . '/conf/metadata.php',
+ 'plugin',
+ $plugin
+ )
+ );
+ }
+
+ // current template
+ $meta = array_merge(
+ $meta,
+ $this->loadExtensionMeta(
+ tpl_incdir() . '/conf/metadata.php',
+ 'tpl',
+ $this->template
+ )
+ );
+
+ return $meta;
+ }
+
+ /**
+ * Read the default values
+ *
+ * Reads the main file, plugins and template defaults
+ *
+ * @return array
+ */
+ public function loadDefaults() {
+ // load main files
+ global $config_cascade;
+ $conf = $this->loadConfigs($config_cascade['main']['default']);
+
+ // plugins
+ foreach($this->plugins as $plugin) {
+ $conf = array_merge(
+ $conf,
+ $this->loadExtensionConf(
+ DOKU_PLUGIN . $plugin . '/conf/default.php',
+ 'plugin',
+ $plugin
+ )
+ );
+ }
+
+ // current template
+ $conf = array_merge(
+ $conf,
+ $this->loadExtensionConf(
+ tpl_incdir() . '/conf/default.php',
+ 'tpl',
+ $this->template
+ )
+ );
+
+ return $conf;
+ }
+
+ /**
+ * Reads the language strings
+ *
+ * Only reads extensions, main one is loaded the usual way
+ *
+ * @return array
+ */
+ public function loadLangs() {
+ $lang = array();
+
+ // plugins
+ foreach($this->plugins as $plugin) {
+ $lang = array_merge(
+ $lang,
+ $this->loadExtensionLang(
+ DOKU_PLUGIN . $plugin . '/',
+ 'plugin',
+ $plugin
+ )
+ );
+ }
+
+ // current template
+ $lang = array_merge(
+ $lang,
+ $this->loadExtensionLang(
+ tpl_incdir() . '/',
+ 'tpl',
+ $this->template
+ )
+ );
+
+ return $lang;
+ }
+
+ /**
+ * Read the local settings
+ *
+ * @return array
+ */
+ public function loadLocal() {
+ global $config_cascade;
+ return $this->loadConfigs($config_cascade['main']['local']);
+ }
+
+ /**
+ * Read the protected settings
+ *
+ * @return array
+ */
+ public function loadProtected() {
+ global $config_cascade;
+ return $this->loadConfigs($config_cascade['main']['protected']);
+ }
+
+ /**
+ * Read the config values from the given files
+ *
+ * @param string[] $files paths to config php's
+ * @return array
+ */
+ protected function loadConfigs($files) {
+ $conf = array();
+ foreach($files as $file) {
+ $conf = array_merge($conf, $this->parser->parse($file));
+ }
+ return $conf;
+ }
+
+ /**
+ * Read settings file from an extension
+ *
+ * This is used to read the settings.php files of plugins and templates
+ *
+ * @param string $file php file to read
+ * @param string $type should be 'plugin' or 'tpl'
+ * @param string $extname name of the extension
+ * @return array
+ */
+ protected function loadExtensionMeta($file, $type, $extname) {
+ if(!file_exists($file)) return array();
+ $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER;
+
+ // include file
+ $meta = array();
+ include $file;
+ if(empty($meta)) return array();
+
+ // read data
+ $data = array();
+ $data[$prefix . $type . '_settings_name'] = ['fieldset'];
+ foreach($meta as $key => $value) {
+ if($value[0] == 'fieldset') continue; //plugins only get one fieldset
+ $data[$prefix . $key] = $value;
+ }
+
+ return $data;
+ }
+
+ /**
+ * Read a default file from an extension
+ *
+ * This is used to read the default.php files of plugins and templates
+ *
+ * @param string $file php file to read
+ * @param string $type should be 'plugin' or 'tpl'
+ * @param string $extname name of the extension
+ * @return array
+ */
+ protected function loadExtensionConf($file, $type, $extname) {
+ if(!file_exists($file)) return array();
+ $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER;
+
+ // parse file
+ $conf = $this->parser->parse($file);
+ if(empty($conf)) return array();
+
+ // read data
+ $data = array();
+ foreach($conf as $key => $value) {
+ $data[$prefix . $key] = $value;
+ }
+
+ return $data;
+ }
+
+ /**
+ * Read the language file of an extension
+ *
+ * @param string $dir directory of the extension
+ * @param string $type should be 'plugin' or 'tpl'
+ * @param string $extname name of the extension
+ * @return array
+ */
+ protected function loadExtensionLang($dir, $type, $extname) {
+ global $conf;
+ $ll = $conf['lang'];
+ $prefix = $type . Configuration::KEYMARKER . $extname . Configuration::KEYMARKER;
+
+ // include files
+ $lang = array();
+ if(file_exists($dir . 'lang/en/settings.php')) {
+ include $dir . 'lang/en/settings.php';
+ }
+ if($ll != 'en' && file_exists($dir . 'lang/' . $ll . '/settings.php')) {
+ include $dir . 'lang/' . $ll . '/settings.php';
+ }
+
+ // set up correct keys
+ $strings = array();
+ foreach($lang as $key => $val) {
+ $strings[$prefix . $key] = $val;
+ }
+
+ // add fieldset key
+ $strings[$prefix . $type . '_settings_name'] = ucwords(str_replace('_', ' ', $extname));
+
+ return $strings;
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/Setting.php b/platform/www/lib/plugins/config/core/Setting/Setting.php
new file mode 100644
index 0000000..d64f684
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/Setting.php
@@ -0,0 +1,294 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+use dokuwiki\plugin\config\core\Configuration;
+
+/**
+ * Class Setting
+ */
+class Setting {
+ /** @var string unique identifier of this setting */
+ protected $key = '';
+
+ /** @var mixed the default value of this setting */
+ protected $default = null;
+ /** @var mixed the local value of this setting */
+ protected $local = null;
+ /** @var mixed the protected value of this setting */
+ protected $protected = null;
+
+ /** @var array valid alerts, images matching the alerts are in the plugin's images directory */
+ static protected $validCautions = array('warning', 'danger', 'security');
+
+ protected $pattern = '';
+ protected $error = false; // only used by those classes which error check
+ protected $input = null; // only used by those classes which error check
+ protected $caution = null; // used by any setting to provide an alert along with the setting
+
+ /**
+ * Constructor.
+ *
+ * The given parameters will be set up as class properties
+ *
+ * @see initialize() to set the actual value of the setting
+ *
+ * @param string $key
+ * @param array|null $params array with metadata of setting
+ */
+ public function __construct($key, $params = null) {
+ $this->key = $key;
+
+ if(is_array($params)) {
+ foreach($params as $property => $value) {
+ $property = trim($property, '_'); // we don't use underscores anymore
+ $this->$property = $value;
+ }
+ }
+ }
+
+ /**
+ * Set the current values for the setting $key
+ *
+ * This is used to initialize the setting with the data read form the config files.
+ *
+ * @see update() to set a new value
+ * @param mixed $default default setting value
+ * @param mixed $local local setting value
+ * @param mixed $protected protected setting value
+ */
+ public function initialize($default = null, $local = null, $protected = null) {
+ $this->default = $this->cleanValue($default);
+ $this->local = $this->cleanValue($local);
+ $this->protected = $this->cleanValue($protected);
+ }
+
+ /**
+ * update changed setting with validated user provided value $input
+ * - if changed value fails validation check, save it to $this->input (to allow echoing later)
+ * - if changed value passes validation check, set $this->local to the new value
+ *
+ * @param mixed $input the new value
+ * @return boolean true if changed, false otherwise
+ */
+ public function update($input) {
+ if(is_null($input)) return false;
+ if($this->isProtected()) return false;
+ $input = $this->cleanValue($input);
+
+ $value = is_null($this->local) ? $this->default : $this->local;
+ if($value == $input) return false;
+
+ // validate new value
+ if($this->pattern && !preg_match($this->pattern, $input)) {
+ $this->error = true;
+ $this->input = $input;
+ return false;
+ }
+
+ // update local copy of this setting with new value
+ $this->local = $input;
+
+ // setting ready for update
+ return true;
+ }
+
+ /**
+ * Clean a value read from a config before using it internally
+ *
+ * Default implementation returns $value as is. Subclasses can override.
+ * Note: null should always be returned as null!
+ *
+ * This is applied in initialize() and update()
+ *
+ * @param mixed $value
+ * @return mixed
+ */
+ protected function cleanValue($value) {
+ return $value;
+ }
+
+ /**
+ * Should this type of config have a default?
+ *
+ * @return bool
+ */
+ public function shouldHaveDefault() {
+ return true;
+ }
+
+ /**
+ * Get this setting's unique key
+ *
+ * @return string
+ */
+ public function getKey() {
+ return $this->key;
+ }
+
+ /**
+ * Get the key of this setting marked up human readable
+ *
+ * @param bool $url link to dokuwiki.org manual?
+ * @return string
+ */
+ public function getPrettyKey($url = true) {
+ $out = str_replace(Configuration::KEYMARKER, "»", $this->key);
+ if($url && !strstr($out, '»')) {//provide no urls for plugins, etc.
+ if($out == 'start') {
+ // exception, because this config name is clashing with our actual start page
+ return '<a href="http://www.dokuwiki.org/config:startpage">' . $out . '</a>';
+ } else {
+ return '<a href="http://www.dokuwiki.org/config:' . $out . '">' . $out . '</a>';
+ }
+ }
+ return $out;
+ }
+
+ /**
+ * Returns setting key as an array key separator
+ *
+ * This is used to create form output
+ *
+ * @return string key
+ */
+ public function getArrayKey() {
+ return str_replace(Configuration::KEYMARKER, "']['", $this->key);
+ }
+
+ /**
+ * What type of configuration is this
+ *
+ * Returns one of
+ *
+ * 'plugin' for plugin configuration
+ * 'template' for template configuration
+ * 'dokuwiki' for core configuration
+ *
+ * @return string
+ */
+ public function getType() {
+ if(substr($this->getKey(), 0, 10) == 'plugin' . Configuration::KEYMARKER) {
+ return 'plugin';
+ } else if(substr($this->getKey(), 0, 7) == 'tpl' . Configuration::KEYMARKER) {
+ return 'template';
+ } else {
+ return 'dokuwiki';
+ }
+ }
+
+ /**
+ * Build html for label and input of setting
+ *
+ * @param \admin_plugin_config $plugin object of config plugin
+ * @param bool $echo true: show inputted value, when error occurred, otherwise the stored setting
+ * @return string[] with content array(string $label_html, string $input_html)
+ */
+ public function html(\admin_plugin_config $plugin, $echo = false) {
+ $disable = '';
+
+ if($this->isProtected()) {
+ $value = $this->protected;
+ $disable = 'disabled="disabled"';
+ } else {
+ if($echo && $this->error) {
+ $value = $this->input;
+ } else {
+ $value = is_null($this->local) ? $this->default : $this->local;
+ }
+ }
+
+ $key = htmlspecialchars($this->key);
+ $value = formText($value);
+
+ $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
+ $input = '<textarea rows="3" cols="40" id="config___' . $key .
+ '" name="config[' . $key . ']" class="edit" ' . $disable . '>' . $value . '</textarea>';
+ return array($label, $input);
+ }
+
+ /**
+ * Should the current local value be saved?
+ *
+ * @see out() to run when this returns true
+ * @return bool
+ */
+ public function shouldBeSaved() {
+ if($this->isProtected()) return false;
+ if($this->local === null) return false;
+ if($this->default == $this->local) return false;
+ return true;
+ }
+
+ /**
+ * Generate string to save local setting value to file according to $fmt
+ *
+ * @see shouldBeSaved() to check if this should be called
+ * @param string $var name of variable
+ * @param string $fmt save format
+ * @return string
+ */
+ public function out($var, $fmt = 'php') {
+ if($fmt != 'php') return '';
+
+ $tr = array("\\" => '\\\\', "'" => '\\\''); // escape the value
+ $out = '$' . $var . "['" . $this->getArrayKey() . "'] = '" . strtr(cleanText($this->local), $tr) . "';\n";
+
+ return $out;
+ }
+
+ /**
+ * Returns the localized prompt
+ *
+ * @param \admin_plugin_config $plugin object of config plugin
+ * @return string text
+ */
+ public function prompt(\admin_plugin_config $plugin) {
+ $prompt = $plugin->getLang($this->key);
+ if(!$prompt) $prompt = htmlspecialchars(str_replace(array('____', '_'), ' ', $this->key));
+ return $prompt;
+ }
+
+ /**
+ * Is setting protected
+ *
+ * @return bool
+ */
+ public function isProtected() {
+ return !is_null($this->protected);
+ }
+
+ /**
+ * Is setting the default?
+ *
+ * @return bool
+ */
+ public function isDefault() {
+ return !$this->isProtected() && is_null($this->local);
+ }
+
+ /**
+ * Has an error?
+ *
+ * @return bool
+ */
+ public function hasError() {
+ return $this->error;
+ }
+
+ /**
+ * Returns caution
+ *
+ * @return false|string caution string, otherwise false for invalid caution
+ */
+ public function caution() {
+ if(empty($this->caution)) return false;
+ if(!in_array($this->caution, Setting::$validCautions)) {
+ throw new \RuntimeException(
+ 'Invalid caution string (' . $this->caution . ') in metadata for setting "' . $this->key . '"'
+ );
+ }
+ return $this->caution;
+ }
+
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingArray.php b/platform/www/lib/plugins/config/core/Setting/SettingArray.php
new file mode 100644
index 0000000..c48dc76
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingArray.php
@@ -0,0 +1,105 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_array
+ */
+class SettingArray extends Setting {
+
+ /**
+ * Create an array from a string
+ *
+ * @param string $string
+ * @return array
+ */
+ protected function fromString($string) {
+ $array = explode(',', $string);
+ $array = array_map('trim', $array);
+ $array = array_filter($array);
+ $array = array_unique($array);
+ return $array;
+ }
+
+ /**
+ * Create a string from an array
+ *
+ * @param array $array
+ * @return string
+ */
+ protected function fromArray($array) {
+ return join(', ', (array) $array);
+ }
+
+ /**
+ * update setting with user provided value $input
+ * if value fails error check, save it
+ *
+ * @param string $input
+ * @return bool true if changed, false otherwise (incl. on error)
+ */
+ public function update($input) {
+ if(is_null($input)) return false;
+ if($this->isProtected()) return false;
+
+ $input = $this->fromString($input);
+
+ $value = is_null($this->local) ? $this->default : $this->local;
+ if($value == $input) return false;
+
+ foreach($input as $item) {
+ if($this->pattern && !preg_match($this->pattern, $item)) {
+ $this->error = true;
+ $this->input = $input;
+ return false;
+ }
+ }
+
+ $this->local = $input;
+ return true;
+ }
+
+ /**
+ * Escaping
+ *
+ * @param string $string
+ * @return string
+ */
+ protected function escape($string) {
+ $tr = array("\\" => '\\\\', "'" => '\\\'');
+ return "'" . strtr(cleanText($string), $tr) . "'";
+ }
+
+ /** @inheritdoc */
+ public function out($var, $fmt = 'php') {
+ if($fmt != 'php') return '';
+
+ $vals = array_map(array($this, 'escape'), $this->local);
+ $out = '$' . $var . "['" . $this->getArrayKey() . "'] = array(" . join(', ', $vals) . ");\n";
+ return $out;
+ }
+
+ /** @inheritdoc */
+ public function html(\admin_plugin_config $plugin, $echo = false) {
+ $disable = '';
+
+ if($this->isProtected()) {
+ $value = $this->protected;
+ $disable = 'disabled="disabled"';
+ } else {
+ if($echo && $this->error) {
+ $value = $this->input;
+ } else {
+ $value = is_null($this->local) ? $this->default : $this->local;
+ }
+ }
+
+ $key = htmlspecialchars($this->key);
+ $value = htmlspecialchars($this->fromArray($value));
+
+ $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
+ $input = '<input id="config___' . $key . '" name="config[' . $key .
+ ']" type="text" class="edit" value="' . $value . '" ' . $disable . '/>';
+ return array($label, $input);
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingAuthtype.php b/platform/www/lib/plugins/config/core/Setting/SettingAuthtype.php
new file mode 100644
index 0000000..3a6df6f
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingAuthtype.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_authtype
+ */
+class SettingAuthtype extends SettingMultichoice {
+
+ /** @inheritdoc */
+ public function initialize($default = null, $local = null, $protected = null) {
+ /** @var $plugin_controller \dokuwiki\Extension\PluginController */
+ global $plugin_controller;
+
+ // retrieve auth types provided by plugins
+ foreach($plugin_controller->getList('auth') as $plugin) {
+ $this->choices[] = $plugin;
+ }
+
+ parent::initialize($default, $local, $protected);
+ }
+
+ /** @inheritdoc */
+ public function update($input) {
+ /** @var $plugin_controller \dokuwiki\Extension\PluginController */
+ global $plugin_controller;
+
+ // is an update possible/requested?
+ $local = $this->local; // save this, parent::update() may change it
+ if(!parent::update($input)) return false; // nothing changed or an error caught by parent
+ $this->local = $local; // restore original, more error checking to come
+
+ // attempt to load the plugin
+ $auth_plugin = $plugin_controller->load('auth', $input);
+
+ // @TODO: throw an error in plugin controller instead of returning null
+ if(is_null($auth_plugin)) {
+ $this->error = true;
+ msg('Cannot load Auth Plugin "' . $input . '"', -1);
+ return false;
+ }
+
+ // verify proper instantiation (is this really a plugin?) @TODO use instanceof? implement interface?
+ if(is_object($auth_plugin) && !method_exists($auth_plugin, 'getPluginName')) {
+ $this->error = true;
+ msg('Cannot create Auth Plugin "' . $input . '"', -1);
+ return false;
+ }
+
+ // did we change the auth type? logout
+ global $conf;
+ if($conf['authtype'] != $input) {
+ msg('Authentication system changed. Please re-login.');
+ auth_logoff();
+ }
+
+ $this->local = $input;
+ return true;
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingCompression.php b/platform/www/lib/plugins/config/core/Setting/SettingCompression.php
new file mode 100644
index 0000000..f97d828
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingCompression.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_compression
+ */
+class SettingCompression extends SettingMultichoice {
+
+ protected $choices = array('0'); // 0 = no compression, always supported
+
+ /** @inheritdoc */
+ public function initialize($default = null, $local = null, $protected = null) {
+
+ // populate _choices with the compression methods supported by this php installation
+ if(function_exists('gzopen')) $this->choices[] = 'gz';
+ if(function_exists('bzopen')) $this->choices[] = 'bz2';
+
+ parent::initialize($default, $local, $protected);
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingDirchoice.php b/platform/www/lib/plugins/config/core/Setting/SettingDirchoice.php
new file mode 100644
index 0000000..dfb27f5
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingDirchoice.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_dirchoice
+ */
+class SettingDirchoice extends SettingMultichoice {
+
+ protected $dir = '';
+
+ /** @inheritdoc */
+ public function initialize($default = null, $local = null, $protected = null) {
+
+ // populate $this->_choices with a list of directories
+ $list = array();
+
+ if($dh = @opendir($this->dir)) {
+ while(false !== ($entry = readdir($dh))) {
+ if($entry == '.' || $entry == '..') continue;
+ if($this->pattern && !preg_match($this->pattern, $entry)) continue;
+
+ $file = (is_link($this->dir . $entry)) ? readlink($this->dir . $entry) : $this->dir . $entry;
+ if(is_dir($file)) $list[] = $entry;
+ }
+ closedir($dh);
+ }
+ sort($list);
+ $this->choices = $list;
+
+ parent::initialize($default, $local, $protected);
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingDisableactions.php b/platform/www/lib/plugins/config/core/Setting/SettingDisableactions.php
new file mode 100644
index 0000000..2553175
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingDisableactions.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_disableactions
+ */
+class SettingDisableactions extends SettingMulticheckbox {
+
+ /** @inheritdoc */
+ public function html(\admin_plugin_config $plugin, $echo = false) {
+ global $lang;
+
+ // make some language adjustments (there must be a better way)
+ // transfer some DokuWiki language strings to the plugin
+ $plugin->addLang($this->key . '_revisions', $lang['btn_revs']);
+ foreach($this->choices as $choice) {
+ if(isset($lang['btn_' . $choice])) $plugin->addLang($this->key . '_' . $choice, $lang['btn_' . $choice]);
+ }
+
+ return parent::html($plugin, $echo);
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingEmail.php b/platform/www/lib/plugins/config/core/Setting/SettingEmail.php
new file mode 100644
index 0000000..25a0c0e
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingEmail.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_email
+ */
+class SettingEmail extends SettingString {
+ protected $multiple = false;
+ protected $placeholders = false;
+
+ /** @inheritdoc */
+ public function update($input) {
+ if(is_null($input)) return false;
+ if($this->isProtected()) return false;
+
+ $value = is_null($this->local) ? $this->default : $this->local;
+ if($value == $input) return false;
+ if($input === '') {
+ $this->local = $input;
+ return true;
+ }
+ $mail = $input;
+
+ if($this->placeholders) {
+ // replace variables with pseudo values
+ $mail = str_replace('@USER@', 'joe', $mail);
+ $mail = str_replace('@NAME@', 'Joe Schmoe', $mail);
+ $mail = str_replace('@MAIL@', 'joe@example.com', $mail);
+ }
+
+ // multiple mail addresses?
+ if($this->multiple) {
+ $mails = array_filter(array_map('trim', explode(',', $mail)));
+ } else {
+ $mails = array($mail);
+ }
+
+ // check them all
+ foreach($mails as $mail) {
+ // only check the address part
+ if(preg_match('#(.*?)<(.*?)>#', $mail, $matches)) {
+ $addr = $matches[2];
+ } else {
+ $addr = $mail;
+ }
+
+ if(!mail_isvalid($addr)) {
+ $this->error = true;
+ $this->input = $input;
+ return false;
+ }
+ }
+
+ $this->local = $input;
+ return true;
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingFieldset.php b/platform/www/lib/plugins/config/core/Setting/SettingFieldset.php
new file mode 100644
index 0000000..4e86189
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingFieldset.php
@@ -0,0 +1,17 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * A do-nothing class used to detect the 'fieldset' type.
+ *
+ * Used to start a new settings "display-group".
+ */
+class SettingFieldset extends Setting {
+
+ /** @inheritdoc */
+ public function shouldHaveDefault() {
+ return false;
+ }
+
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingHidden.php b/platform/www/lib/plugins/config/core/Setting/SettingHidden.php
new file mode 100644
index 0000000..ca8a03e
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingHidden.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_hidden
+ */
+class SettingHidden extends Setting {
+ // Used to explicitly ignore a setting in the configuration manager.
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingImConvert.php b/platform/www/lib/plugins/config/core/Setting/SettingImConvert.php
new file mode 100644
index 0000000..8740d94
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingImConvert.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_im_convert
+ */
+class SettingImConvert extends SettingString {
+
+ /** @inheritdoc */
+ public function update($input) {
+ if($this->isProtected()) return false;
+
+ $input = trim($input);
+
+ $value = is_null($this->local) ? $this->default : $this->local;
+ if($value == $input) return false;
+
+ if($input && !file_exists($input)) {
+ $this->error = true;
+ $this->input = $input;
+ return false;
+ }
+
+ $this->local = $input;
+ return true;
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingLicense.php b/platform/www/lib/plugins/config/core/Setting/SettingLicense.php
new file mode 100644
index 0000000..8dacf8e
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingLicense.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_license
+ */
+class SettingLicense extends SettingMultichoice {
+
+ protected $choices = array(''); // none choosen
+
+ /** @inheritdoc */
+ public function initialize($default = null, $local = null, $protected = null) {
+ global $license;
+
+ foreach($license as $key => $data) {
+ $this->choices[] = $key;
+ $this->lang[$this->key . '_o_' . $key] = $data['name']; // stored in setting
+ }
+
+ parent::initialize($default, $local, $protected);
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingMulticheckbox.php b/platform/www/lib/plugins/config/core/Setting/SettingMulticheckbox.php
new file mode 100644
index 0000000..df212cc
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingMulticheckbox.php
@@ -0,0 +1,163 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_multicheckbox
+ */
+class SettingMulticheckbox extends SettingString {
+
+ protected $choices = array();
+ protected $combine = array();
+ protected $other = 'always';
+
+ /** @inheritdoc */
+ public function update($input) {
+ if($this->isProtected()) return false;
+
+ // split any combined values + convert from array to comma separated string
+ $input = ($input) ? $input : array();
+ $input = $this->array2str($input);
+
+ $value = is_null($this->local) ? $this->default : $this->local;
+ if($value == $input) return false;
+
+ if($this->pattern && !preg_match($this->pattern, $input)) {
+ $this->error = true;
+ $this->input = $input;
+ return false;
+ }
+
+ $this->local = $input;
+ return true;
+ }
+
+ /** @inheritdoc */
+ public function html(\admin_plugin_config $plugin, $echo = false) {
+
+ $disable = '';
+
+ if($this->isProtected()) {
+ $value = $this->protected;
+ $disable = 'disabled="disabled"';
+ } else {
+ if($echo && $this->error) {
+ $value = $this->input;
+ } else {
+ $value = is_null($this->local) ? $this->default : $this->local;
+ }
+ }
+
+ $key = htmlspecialchars($this->key);
+
+ // convert from comma separated list into array + combine complimentary actions
+ $value = $this->str2array($value);
+ $default = $this->str2array($this->default);
+
+ $input = '';
+ foreach($this->choices as $choice) {
+ $idx = array_search($choice, $value);
+ $idx_default = array_search($choice, $default);
+
+ $checked = ($idx !== false) ? 'checked="checked"' : '';
+
+ // @todo ideally this would be handled using a second class of "default"
+ $class = (($idx !== false) == (false !== $idx_default)) ? " selectiondefault" : "";
+
+ $prompt = ($plugin->getLang($this->key . '_' . $choice) ?
+ $plugin->getLang($this->key . '_' . $choice) : htmlspecialchars($choice));
+
+ $input .= '<div class="selection' . $class . '">' . "\n";
+ $input .= '<label for="config___' . $key . '_' . $choice . '">' . $prompt . "</label>\n";
+ $input .= '<input id="config___' . $key . '_' . $choice . '" name="config[' . $key .
+ '][]" type="checkbox" class="checkbox" value="' . $choice . '" ' . $disable . ' ' . $checked . "/>\n";
+ $input .= "</div>\n";
+
+ // remove this action from the disabledactions array
+ if($idx !== false) unset($value[$idx]);
+ if($idx_default !== false) unset($default[$idx_default]);
+ }
+
+ // handle any remaining values
+ if($this->other != 'never') {
+ $other = join(',', $value);
+ // test equivalent to ($this->_other == 'always' || ($other && $this->_other == 'exists')
+ // use != 'exists' rather than == 'always' to ensure invalid values default to 'always'
+ if($this->other != 'exists' || $other) {
+
+ $class = (
+ (count($default) == count($value)) &&
+ (count($value) == count(array_intersect($value, $default)))
+ ) ?
+ " selectiondefault" : "";
+
+ $input .= '<div class="other' . $class . '">' . "\n";
+ $input .= '<label for="config___' . $key . '_other">' .
+ $plugin->getLang($key . '_other') .
+ "</label>\n";
+ $input .= '<input id="config___' . $key . '_other" name="config[' . $key .
+ '][other]" type="text" class="edit" value="' . htmlspecialchars($other) .
+ '" ' . $disable . " />\n";
+ $input .= "</div>\n";
+ }
+ }
+ $label = '<label>' . $this->prompt($plugin) . '</label>';
+ return array($label, $input);
+ }
+
+ /**
+ * convert comma separated list to an array and combine any complimentary values
+ *
+ * @param string $str
+ * @return array
+ */
+ protected function str2array($str) {
+ $array = explode(',', $str);
+
+ if(!empty($this->combine)) {
+ foreach($this->combine as $key => $combinators) {
+ $idx = array();
+ foreach($combinators as $val) {
+ if(($idx[] = array_search($val, $array)) === false) break;
+ }
+
+ if(count($idx) && $idx[count($idx) - 1] !== false) {
+ foreach($idx as $i) unset($array[$i]);
+ $array[] = $key;
+ }
+ }
+ }
+
+ return $array;
+ }
+
+ /**
+ * convert array of values + other back to a comma separated list, incl. splitting any combined values
+ *
+ * @param array $input
+ * @return string
+ */
+ protected function array2str($input) {
+
+ // handle other
+ $other = trim($input['other']);
+ $other = !empty($other) ? explode(',', str_replace(' ', '', $input['other'])) : array();
+ unset($input['other']);
+
+ $array = array_unique(array_merge($input, $other));
+
+ // deconstruct any combinations
+ if(!empty($this->combine)) {
+ foreach($this->combine as $key => $combinators) {
+
+ $idx = array_search($key, $array);
+ if($idx !== false) {
+ unset($array[$idx]);
+ $array = array_merge($array, $combinators);
+ }
+ }
+ }
+
+ return join(',', array_unique($array));
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingMultichoice.php b/platform/www/lib/plugins/config/core/Setting/SettingMultichoice.php
new file mode 100644
index 0000000..3a50857
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingMultichoice.php
@@ -0,0 +1,71 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_multichoice
+ */
+class SettingMultichoice extends SettingString {
+ protected $choices = array();
+ public $lang; //some custom language strings are stored in setting
+
+ /** @inheritdoc */
+ public function html(\admin_plugin_config $plugin, $echo = false) {
+ $disable = '';
+ $nochoice = '';
+
+ if($this->isProtected()) {
+ $value = $this->protected;
+ $disable = ' disabled="disabled"';
+ } else {
+ $value = is_null($this->local) ? $this->default : $this->local;
+ }
+
+ // ensure current value is included
+ if(!in_array($value, $this->choices)) {
+ $this->choices[] = $value;
+ }
+ // disable if no other choices
+ if(!$this->isProtected() && count($this->choices) <= 1) {
+ $disable = ' disabled="disabled"';
+ $nochoice = $plugin->getLang('nochoice');
+ }
+
+ $key = htmlspecialchars($this->key);
+
+ $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
+
+ $input = "<div class=\"input\">\n";
+ $input .= '<select class="edit" id="config___' . $key . '" name="config[' . $key . ']"' . $disable . '>' . "\n";
+ foreach($this->choices as $choice) {
+ $selected = ($value == $choice) ? ' selected="selected"' : '';
+ $option = $plugin->getLang($this->key . '_o_' . $choice);
+ if(!$option && isset($this->lang[$this->key . '_o_' . $choice])) {
+ $option = $this->lang[$this->key . '_o_' . $choice];
+ }
+ if(!$option) $option = $choice;
+
+ $choice = htmlspecialchars($choice);
+ $option = htmlspecialchars($option);
+ $input .= ' <option value="' . $choice . '"' . $selected . ' >' . $option . '</option>' . "\n";
+ }
+ $input .= "</select> $nochoice \n";
+ $input .= "</div>\n";
+
+ return array($label, $input);
+ }
+
+ /** @inheritdoc */
+ public function update($input) {
+ if(is_null($input)) return false;
+ if($this->isProtected()) return false;
+
+ $value = is_null($this->local) ? $this->default : $this->local;
+ if($value == $input) return false;
+
+ if(!in_array($input, $this->choices)) return false;
+
+ $this->local = $input;
+ return true;
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingNoClass.php b/platform/www/lib/plugins/config/core/Setting/SettingNoClass.php
new file mode 100644
index 0000000..8efff21
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingNoClass.php
@@ -0,0 +1,12 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_no_class
+ * A do-nothing class used to detect settings with a missing setting class.
+ * Used internaly to hide undefined settings, and generate the undefined settings list.
+ */
+class SettingNoClass extends SettingUndefined {
+ protected $errorMessage = '_msg_setting_no_class';
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingNoDefault.php b/platform/www/lib/plugins/config/core/Setting/SettingNoDefault.php
new file mode 100644
index 0000000..07b8412
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingNoDefault.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_no_default
+ *
+ * A do-nothing class used to detect settings with no default value.
+ * Used internaly to hide undefined settings, and generate the undefined settings list.
+ */
+class SettingNoDefault extends SettingUndefined {
+ protected $errorMessage = '_msg_setting_no_default';
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingNoKnownClass.php b/platform/www/lib/plugins/config/core/Setting/SettingNoKnownClass.php
new file mode 100644
index 0000000..3c527e1
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingNoKnownClass.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * A do-nothing class used to detect settings with a missing setting class.
+ * Used internaly to hide undefined settings, and generate the undefined settings list.
+ */
+class SettingNoKnownClass extends SettingUndefined {
+ protected $errorMessage = '_msg_setting_no_known_class';
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingNumeric.php b/platform/www/lib/plugins/config/core/Setting/SettingNumeric.php
new file mode 100644
index 0000000..8a6b179
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingNumeric.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_numeric
+ */
+class SettingNumeric extends SettingString {
+ // This allows for many PHP syntax errors...
+ // var $_pattern = '/^[-+\/*0-9 ]*$/';
+ // much more restrictive, but should eliminate syntax errors.
+ protected $pattern = '/^[-+]? *[0-9]+ *(?:[-+*] *[0-9]+ *)*$/';
+ protected $min = null;
+ protected $max = null;
+
+ /** @inheritdoc */
+ public function update($input) {
+ $local = $this->local;
+ $valid = parent::update($input);
+ if($valid && !(is_null($this->min) && is_null($this->max))) {
+ $numeric_local = (int) eval('return ' . $this->local . ';');
+ if((!is_null($this->min) && $numeric_local < $this->min) ||
+ (!is_null($this->max) && $numeric_local > $this->max)) {
+ $this->error = true;
+ $this->input = $input;
+ $this->local = $local;
+ $valid = false;
+ }
+ }
+ return $valid;
+ }
+
+ /** @inheritdoc */
+ public function out($var, $fmt = 'php') {
+ if($fmt != 'php') return '';
+
+ $local = $this->local === '' ? "''" : $this->local;
+ $out = '$' . $var . "['" . $this->getArrayKey() . "'] = " . $local . ";\n";
+
+ return $out;
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingNumericopt.php b/platform/www/lib/plugins/config/core/Setting/SettingNumericopt.php
new file mode 100644
index 0000000..a486e18
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingNumericopt.php
@@ -0,0 +1,25 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_numericopt
+ */
+class SettingNumericopt extends SettingNumeric {
+ // just allow an empty config
+ protected $pattern = '/^(|[-]?[0-9]+(?:[-+*][0-9]+)*)$/';
+
+ /**
+ * @inheritdoc
+ * Empty string is valid for numericopt
+ */
+ public function update($input) {
+ if($input === '') {
+ if($input == $this->local) return false;
+ $this->local = $input;
+ return true;
+ }
+
+ return parent::update($input);
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingOnoff.php b/platform/www/lib/plugins/config/core/Setting/SettingOnoff.php
new file mode 100644
index 0000000..780778b
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingOnoff.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_onoff
+ */
+class SettingOnoff extends SettingNumeric {
+
+ /**
+ * We treat the strings 'false' and 'off' as false
+ * @inheritdoc
+ */
+ protected function cleanValue($value) {
+ if($value === null) return null;
+
+ if(is_string($value)) {
+ if(strtolower($value) === 'false') return 0;
+ if(strtolower($value) === 'off') return 0;
+ if(trim($value) === '') return 0;
+ }
+
+ return (int) (bool) $value;
+ }
+
+ /** @inheritdoc */
+ public function html(\admin_plugin_config $plugin, $echo = false) {
+ $disable = '';
+
+ if($this->isProtected()) {
+ $value = $this->protected;
+ $disable = ' disabled="disabled"';
+ } else {
+ $value = is_null($this->local) ? $this->default : $this->local;
+ }
+
+ $key = htmlspecialchars($this->key);
+ $checked = ($value) ? ' checked="checked"' : '';
+
+ $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
+ $input = '<div class="input"><input id="config___' . $key . '" name="config[' . $key .
+ ']" type="checkbox" class="checkbox" value="1"' . $checked . $disable . '/></div>';
+ return array($label, $input);
+ }
+
+ /** @inheritdoc */
+ public function update($input) {
+ if($this->isProtected()) return false;
+
+ $input = ($input) ? 1 : 0;
+ $value = is_null($this->local) ? $this->default : $this->local;
+ if($value == $input) return false;
+
+ $this->local = $input;
+ return true;
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingPassword.php b/platform/www/lib/plugins/config/core/Setting/SettingPassword.php
new file mode 100644
index 0000000..9d9c533
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingPassword.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_password
+ */
+class SettingPassword extends SettingString {
+
+ protected $code = 'plain'; // mechanism to be used to obscure passwords
+
+ /** @inheritdoc */
+ public function update($input) {
+ if($this->isProtected()) return false;
+ if(!$input) return false;
+
+ if($this->pattern && !preg_match($this->pattern, $input)) {
+ $this->error = true;
+ $this->input = $input;
+ return false;
+ }
+
+ $this->local = conf_encodeString($input, $this->code);
+ return true;
+ }
+
+ /** @inheritdoc */
+ public function html(\admin_plugin_config $plugin, $echo = false) {
+
+ $disable = $this->isProtected() ? 'disabled="disabled"' : '';
+
+ $key = htmlspecialchars($this->key);
+
+ $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
+ $input = '<input id="config___' . $key . '" name="config[' . $key .
+ ']" autocomplete="off" type="password" class="edit" value="" ' . $disable . ' />';
+ return array($label, $input);
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingRegex.php b/platform/www/lib/plugins/config/core/Setting/SettingRegex.php
new file mode 100644
index 0000000..b38f0a5
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingRegex.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_regex
+ */
+class SettingRegex extends SettingString {
+
+ protected $delimiter = '/'; // regex delimiter to be used in testing input
+ protected $pregflags = 'ui'; // regex pattern modifiers to be used in testing input
+
+ /** @inheritdoc */
+ public function update($input) {
+
+ // let parent do basic checks, value, not changed, etc.
+ $local = $this->local;
+ if(!parent::update($input)) return false;
+ $this->local = $local;
+
+ // see if the regex compiles and runs (we don't check for effectiveness)
+ $regex = $this->delimiter . $input . $this->delimiter . $this->pregflags;
+ $lastError = error_get_last();
+ @preg_match($regex, 'testdata');
+ if(preg_last_error() != PREG_NO_ERROR || error_get_last() != $lastError) {
+ $this->input = $input;
+ $this->error = true;
+ return false;
+ }
+
+ $this->local = $input;
+ return true;
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingRenderer.php b/platform/www/lib/plugins/config/core/Setting/SettingRenderer.php
new file mode 100644
index 0000000..37ba9c7
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingRenderer.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * additional setting classes specific to these settings
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_renderer
+ */
+class SettingRenderer extends SettingMultichoice {
+ protected $prompts = array();
+ protected $format = null;
+
+ /** @inheritdoc */
+ public function initialize($default = null, $local = null, $protected = null) {
+ $format = $this->format;
+
+ foreach(plugin_list('renderer') as $plugin) {
+ $renderer = plugin_load('renderer', $plugin);
+ if(method_exists($renderer, 'canRender') && $renderer->canRender($format)) {
+ $this->choices[] = $plugin;
+
+ $info = $renderer->getInfo();
+ $this->prompts[$plugin] = $info['name'];
+ }
+ }
+
+ parent::initialize($default, $local, $protected);
+ }
+
+ /** @inheritdoc */
+ public function html(\admin_plugin_config $plugin, $echo = false) {
+
+ // make some language adjustments (there must be a better way)
+ // transfer some plugin names to the config plugin
+ foreach($this->choices as $choice) {
+ if(!$plugin->getLang($this->key . '_o_' . $choice)) {
+ if(!isset($this->prompts[$choice])) {
+ $plugin->addLang(
+ $this->key . '_o_' . $choice,
+ sprintf($plugin->getLang('renderer__core'), $choice)
+ );
+ } else {
+ $plugin->addLang(
+ $this->key . '_o_' . $choice,
+ sprintf($plugin->getLang('renderer__plugin'), $this->prompts[$choice])
+ );
+ }
+ }
+ }
+ return parent::html($plugin, $echo);
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingSavedir.php b/platform/www/lib/plugins/config/core/Setting/SettingSavedir.php
new file mode 100644
index 0000000..43e428d
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingSavedir.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_savedir
+ */
+class SettingSavedir extends SettingString {
+
+ /** @inheritdoc */
+ public function update($input) {
+ if($this->isProtected()) return false;
+
+ $value = is_null($this->local) ? $this->default : $this->local;
+ if($value == $input) return false;
+
+ if(!init_path($input)) {
+ $this->error = true;
+ $this->input = $input;
+ return false;
+ }
+
+ $this->local = $input;
+ return true;
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingSepchar.php b/platform/www/lib/plugins/config/core/Setting/SettingSepchar.php
new file mode 100644
index 0000000..57cd0ae
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingSepchar.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_sepchar
+ */
+class SettingSepchar extends SettingMultichoice {
+
+ /** @inheritdoc */
+ public function __construct($key, $param = null) {
+ $str = '_-.';
+ for($i = 0; $i < strlen($str); $i++) $this->choices[] = $str[$i];
+
+ // call foundation class constructor
+ parent::__construct($key, $param);
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingString.php b/platform/www/lib/plugins/config/core/Setting/SettingString.php
new file mode 100644
index 0000000..b819407
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingString.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+/**
+ * Class setting_string
+ */
+class SettingString extends Setting {
+ /** @inheritdoc */
+ public function html(\admin_plugin_config $plugin, $echo = false) {
+ $disable = '';
+
+ if($this->isProtected()) {
+ $value = $this->protected;
+ $disable = 'disabled="disabled"';
+ } else {
+ if($echo && $this->error) {
+ $value = $this->input;
+ } else {
+ $value = is_null($this->local) ? $this->default : $this->local;
+ }
+ }
+
+ $key = htmlspecialchars($this->key);
+ $value = htmlspecialchars($value);
+
+ $label = '<label for="config___' . $key . '">' . $this->prompt($plugin) . '</label>';
+ $input = '<input id="config___' . $key . '" name="config[' . $key .
+ ']" type="text" class="edit" value="' . $value . '" ' . $disable . '/>';
+ return array($label, $input);
+ }
+}
diff --git a/platform/www/lib/plugins/config/core/Setting/SettingUndefined.php b/platform/www/lib/plugins/config/core/Setting/SettingUndefined.php
new file mode 100644
index 0000000..fa46a9f
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Setting/SettingUndefined.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace dokuwiki\plugin\config\core\Setting;
+
+use dokuwiki\plugin\config\core\Configuration;
+
+/**
+ * A do-nothing class used to detect settings with no metadata entry.
+ * Used internaly to hide undefined settings, and generate the undefined settings list.
+ */
+class SettingUndefined extends SettingHidden {
+
+ protected $errorMessage = '_msg_setting_undefined';
+
+ /** @inheritdoc */
+ public function shouldHaveDefault() {
+ return false;
+ }
+
+ /** @inheritdoc */
+ public function html(\admin_plugin_config $plugin, $echo = false) {
+ // determine the name the meta key would be called
+ if(preg_match(
+ '/^(?:plugin|tpl)' . Configuration::KEYMARKER . '.*?' . Configuration::KEYMARKER . '(.*)$/',
+ $this->getKey(),
+ $undefined_setting_match
+ )) {
+ $undefined_setting_key = $undefined_setting_match[1];
+ } else {
+ $undefined_setting_key = $this->getKey();
+ }
+
+ $label = '<span title="$meta[\'' . $undefined_setting_key . '\']">$' .
+ 'conf' . '[\'' . $this->getArrayKey() . '\']</span>';
+ $input = $plugin->getLang($this->errorMessage);
+
+ return array($label, $input);
+ }
+
+}
diff --git a/platform/www/lib/plugins/config/core/Writer.php b/platform/www/lib/plugins/config/core/Writer.php
new file mode 100644
index 0000000..56de621
--- /dev/null
+++ b/platform/www/lib/plugins/config/core/Writer.php
@@ -0,0 +1,116 @@
+<?php
+
+namespace dokuwiki\plugin\config\core;
+use dokuwiki\plugin\config\core\Setting\Setting;
+
+/**
+ * Writes the settings to the correct local file
+ */
+class Writer {
+ /** @var string header info */
+ protected $header = 'Dokuwiki\'s Main Configuration File - Local Settings';
+
+ /** @var string the file where the config will be saved to */
+ protected $savefile;
+
+ /**
+ * Writer constructor.
+ */
+ public function __construct() {
+ global $config_cascade;
+ $this->savefile = end($config_cascade['main']['local']);
+ }
+
+ /**
+ * Save the given settings
+ *
+ * @param Setting[] $settings
+ * @throws \Exception
+ */
+ public function save($settings) {
+ global $conf;
+ if($this->isLocked()) throw new \Exception('no save');
+
+ // backup current file (remove any existing backup)
+ if(file_exists($this->savefile)) {
+ if(file_exists($this->savefile . '.bak.php')) @unlink($this->savefile . '.bak.php');
+ if(!io_rename($this->savefile, $this->savefile . '.bak.php')) throw new \Exception('no backup');
+ }
+
+ if(!$fh = @fopen($this->savefile, 'wb')) {
+ io_rename($this->savefile . '.bak.php', $this->savefile); // problem opening, restore the backup
+ throw new \Exception('no save');
+ }
+
+ $out = $this->getHeader();
+ foreach($settings as $setting) {
+ if($setting->shouldBeSaved()) {
+ $out .= $setting->out('conf', 'php');
+ }
+ }
+
+ fwrite($fh, $out);
+ fclose($fh);
+ if($conf['fperm']) chmod($this->savefile, $conf['fperm']);
+ $this->opcacheUpdate($this->savefile);
+ }
+
+ /**
+ * Update last modified time stamp of the config file
+ *
+ * Will invalidate all DokuWiki caches
+ *
+ * @throws \Exception when the config isn't writable
+ */
+ public function touch() {
+ if($this->isLocked()) throw new \Exception('no save');
+ @touch($this->savefile);
+ $this->opcacheUpdate($this->savefile);
+ }
+
+ /**
+ * Invalidate the opcache of the given file
+ *
+ * @todo this should probably be moved to core
+ * @param string $file
+ */
+ protected function opcacheUpdate($file) {
+ if(!function_exists('opcache_invalidate')) return;
+ opcache_invalidate($file);
+ }
+
+ /**
+ * Configuration is considered locked if there is no local settings filename
+ * or the directory its in is not writable or the file exists and is not writable
+ *
+ * @return bool true: locked, false: writable
+ */
+ public function isLocked() {
+ if(!$this->savefile) return true;
+ if(!is_writable(dirname($this->savefile))) return true;
+ if(file_exists($this->savefile) && !is_writable($this->savefile)) return true;
+ return false;
+ }
+
+ /**
+ * Returns the PHP intro header for the config file
+ *
+ * @return string
+ */
+ protected function getHeader() {
+ return join(
+ "\n",
+ array(
+ '<?php',
+ '/*',
+ ' * ' . $this->header,
+ ' * Auto-generated by config plugin',
+ ' * Run for user: ' . $_SERVER['REMOTE_USER'],
+ ' * Date: ' . date('r'),
+ ' */',
+ '',
+ ''
+ )
+ );
+ }
+}
diff --git a/platform/www/lib/plugins/config/images/danger.png b/platform/www/lib/plugins/config/images/danger.png
new file mode 100644
index 0000000..da06924
--- /dev/null
+++ b/platform/www/lib/plugins/config/images/danger.png
Binary files differ
diff --git a/platform/www/lib/plugins/config/images/security.png b/platform/www/lib/plugins/config/images/security.png
new file mode 100644
index 0000000..3ee8476
--- /dev/null
+++ b/platform/www/lib/plugins/config/images/security.png
Binary files differ
diff --git a/platform/www/lib/plugins/config/images/warning.png b/platform/www/lib/plugins/config/images/warning.png
new file mode 100644
index 0000000..c1af79f
--- /dev/null
+++ b/platform/www/lib/plugins/config/images/warning.png
Binary files differ
diff --git a/platform/www/lib/plugins/config/lang/en/intro.txt b/platform/www/lib/plugins/config/lang/en/intro.txt
new file mode 100644
index 0000000..0108987
--- /dev/null
+++ b/platform/www/lib/plugins/config/lang/en/intro.txt
@@ -0,0 +1,7 @@
+====== Configuration Manager ======
+
+Use this page to control the settings of your DokuWiki installation. For help on individual settings refer to [[doku>config]]. For more details about this plugin see [[doku>plugin:config]].
+
+Settings shown with a light red background are protected and can not be altered with this plugin. Settings shown with a blue background are the default values and settings shown with a white background have been set locally for this particular installation. Both blue and white settings can be altered.
+
+Remember to press the **Save** button before leaving this page otherwise your changes will be lost.
diff --git a/platform/www/lib/plugins/config/lang/en/lang.php b/platform/www/lib/plugins/config/lang/en/lang.php
new file mode 100644
index 0000000..fb8186c
--- /dev/null
+++ b/platform/www/lib/plugins/config/lang/en/lang.php
@@ -0,0 +1,277 @@
+<?php
+/**
+ * english language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Matthias Schulte <dokuwiki@lupo49.de>
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ */
+
+// for admin plugins, the menu prompt to be displayed in the admin menu
+// if set here, the plugin doesn't need to override the getMenuText() method
+$lang['menu'] = 'Configuration Settings';
+
+$lang['error'] = 'Settings not updated due to an invalid value, please review your changes and resubmit.
+ <br />The incorrect value(s) will be shown surrounded by a red border.';
+$lang['updated'] = 'Settings updated successfully.';
+$lang['nochoice'] = '(no other choices available)';
+$lang['locked'] = 'The settings file can not be updated, if this is unintentional, <br />
+ ensure the local settings file name and permissions are correct.';
+
+$lang['danger'] = 'Danger: Changing this option could make your wiki and the configuration menu inaccessible.';
+$lang['warning'] = 'Warning: Changing this option could cause unintended behaviour.';
+$lang['security'] = 'Security Warning: Changing this option could present a security risk.';
+
+/* --- Config Setting Headers --- */
+$lang['_configuration_manager'] = 'Configuration Manager'; //same as heading in intro.txt
+$lang['_header_dokuwiki'] = 'DokuWiki';
+$lang['_header_plugin'] = 'Plugin';
+$lang['_header_template'] = 'Template';
+$lang['_header_undefined'] = 'Undefined Settings';
+
+/* --- Config Setting Groups --- */
+$lang['_basic'] = 'Basic';
+$lang['_display'] = 'Display';
+$lang['_authentication'] = 'Authentication';
+$lang['_anti_spam'] = 'Anti-Spam';
+$lang['_editing'] = 'Editing';
+$lang['_links'] = 'Links';
+$lang['_media'] = 'Media';
+$lang['_notifications'] = 'Notification';
+$lang['_syndication'] = 'Syndication (RSS)';
+$lang['_advanced'] = 'Advanced';
+$lang['_network'] = 'Network';
+
+/* --- Undefined Setting Messages --- */
+$lang['_msg_setting_undefined'] = 'No setting metadata.';
+$lang['_msg_setting_no_class'] = 'No setting class.';
+$lang['_msg_setting_no_known_class'] = 'Setting class not available.';
+$lang['_msg_setting_no_default'] = 'No default value.';
+
+/* -------------------- Config Options --------------------------- */
+
+/* Basic Settings */
+$lang['title'] = 'Wiki title aka. your wiki\'s name';
+$lang['start'] = 'Page name to use as the starting point for each namespace';
+$lang['lang'] = 'Interface language';
+$lang['template'] = 'Template aka. the design of the wiki.';
+$lang['tagline'] = 'Tagline (if template supports it)';
+$lang['sidebar'] = 'Sidebar page name (if template supports it), empty field disables the sidebar';
+$lang['license'] = 'Under which license should your content be released?';
+$lang['savedir'] = 'Directory for saving data';
+$lang['basedir'] = 'Server path (eg. <code>/dokuwiki/</code>). Leave blank for autodetection.';
+$lang['baseurl'] = 'Server URL (eg. <code>http://www.yourserver.com</code>). Leave blank for autodetection.';
+$lang['cookiedir'] = 'Cookie path. Leave blank for using baseurl.';
+$lang['dmode'] = 'Directory creation mode';
+$lang['fmode'] = 'File creation mode';
+$lang['allowdebug'] = 'Allow debug. <b>Disable if not needed!</b>';
+
+/* Display Settings */
+$lang['recent'] = 'Number of entries per page in the recent changes';
+$lang['recent_days'] = 'How many recent changes to keep (days)';
+$lang['breadcrumbs'] = 'Number of "trace" breadcrumbs. Set to 0 to disable.';
+$lang['youarehere'] = 'Use hierarchical breadcrumbs (you probably want to disable the above option then)';
+$lang['fullpath'] = 'Reveal full path of pages in the footer';
+$lang['typography'] = 'Do typographical replacements';
+$lang['dformat'] = 'Date format (see PHP\'s <a href="http://php.net/strftime">strftime</a> function)';
+$lang['signature'] = 'What to insert with the signature button in the editor';
+$lang['showuseras'] = 'What to display when showing the user that last edited a page';
+$lang['toptoclevel'] = 'Top level for table of contents';
+$lang['tocminheads'] = 'Minimum amount of headlines that determines whether the TOC is built';
+$lang['maxtoclevel'] = 'Maximum level for table of contents';
+$lang['maxseclevel'] = 'Maximum section edit level';
+$lang['camelcase'] = 'Use CamelCase for links';
+$lang['deaccent'] = 'How to clean pagenames';
+$lang['useheading'] = 'Use first heading for pagenames';
+$lang['sneaky_index'] = 'By default, DokuWiki will show all namespaces in the sitemap. Enabling this option will hide those where the user doesn\'t have read permissions. This might result in hiding of accessable subnamespaces which may make the index unusable with certain ACL setups.';
+$lang['hidepages'] = 'Hide pages matching this regular expression from search, the sitemap and other automatic indexes';
+
+/* Authentication Settings */
+$lang['useacl'] = 'Use access control lists';
+$lang['autopasswd'] = 'Autogenerate passwords';
+$lang['authtype'] = 'Authentication backend';
+$lang['passcrypt'] = 'Password encryption method';
+$lang['defaultgroup']= 'Default group, all new users will be placed in this group';
+$lang['superuser'] = 'Superuser - group, user or comma separated list user1,@group1,user2 with full access to all pages and functions regardless of the ACL settings';
+$lang['manager'] = 'Manager - group, user or comma separated list user1,@group1,user2 with access to certain management functions';
+$lang['profileconfirm'] = 'Confirm profile changes with password';
+$lang['rememberme'] = 'Allow permanent login cookies (remember me)';
+$lang['disableactions'] = 'Disable DokuWiki actions';
+$lang['disableactions_check'] = 'Check';
+$lang['disableactions_subscription'] = 'Subscribe/Unsubscribe';
+$lang['disableactions_wikicode'] = 'View source/Export Raw';
+$lang['disableactions_profile_delete'] = 'Delete Own Account';
+$lang['disableactions_other'] = 'Other actions (comma separated)';
+$lang['disableactions_rss'] = 'XML Syndication (RSS)';
+$lang['auth_security_timeout'] = 'Authentication Security Timeout (seconds)';
+$lang['securecookie'] = 'Should cookies set via HTTPS only be sent via HTTPS by the browser? Disable this option when only the login of your wiki is secured with SSL but browsing the wiki is done unsecured.';
+$lang['remote'] = 'Enable the remote API system. This allows other applications to access the wiki via XML-RPC or other mechanisms.';
+$lang['remoteuser'] = 'Restrict remote API access to the comma separated groups or users given here. Leave empty to give access to everyone.';
+
+/* Anti-Spam Settings */
+$lang['usewordblock']= 'Block spam based on wordlist';
+$lang['relnofollow'] = 'Use rel="ugc nofollow" on external links';
+$lang['indexdelay'] = 'Time delay before indexing (sec)';
+$lang['mailguard'] = 'Obfuscate email addresses';
+$lang['iexssprotect']= 'Check uploaded files for possibly malicious JavaScript or HTML code';
+
+/* Editing Settings */
+$lang['usedraft'] = 'Automatically save a draft while editing';
+$lang['htmlok'] = 'Allow embedded HTML';
+$lang['phpok'] = 'Allow embedded PHP';
+$lang['locktime'] = 'Maximum age for lock files (sec)';
+$lang['cachetime'] = 'Maximum age for cache (sec)';
+
+/* Link settings */
+$lang['target____wiki'] = 'Target window for internal links';
+$lang['target____interwiki'] = 'Target window for interwiki links';
+$lang['target____extern'] = 'Target window for external links';
+$lang['target____media'] = 'Target window for media links';
+$lang['target____windows'] = 'Target window for windows links';
+
+/* Media Settings */
+$lang['mediarevisions'] = 'Enable Mediarevisions?';
+$lang['refcheck'] = 'Check if a media file is still in use before deleting it';
+$lang['gdlib'] = 'GD Lib version';
+$lang['im_convert'] = 'Path to ImageMagick\'s convert tool';
+$lang['jpg_quality'] = 'JPG compression quality (0-100)';
+$lang['fetchsize'] = 'Maximum size (bytes) fetch.php may download from external URLs, eg. to cache and resize external images.';
+
+/* Notification Settings */
+$lang['subscribers'] = 'Allow users to subscribe to page changes by email';
+$lang['subscribe_time'] = 'Time after which subscription lists and digests are sent (sec); This should be smaller than the time specified in recent_days.';
+$lang['notify'] = 'Always send change notifications to this email address';
+$lang['registernotify'] = 'Always send info on newly registered users to this email address';
+$lang['mailfrom'] = 'Sender email address to use for automatic mails';
+$lang['mailreturnpath'] = 'Recipient email address for non delivery notifications';
+$lang['mailprefix'] = 'Email subject prefix to use for automatic mails. Leave blank to use the wiki title';
+$lang['htmlmail'] = 'Send better looking, but larger in size HTML multipart emails. Disable for plain text only mails.';
+
+/* Syndication Settings */
+$lang['sitemap'] = 'Generate Google sitemap this often (in days). 0 to disable';
+$lang['rss_type'] = 'XML feed type';
+$lang['rss_linkto'] = 'XML feed links to';
+$lang['rss_content'] = 'What to display in the XML feed items?';
+$lang['rss_update'] = 'XML feed update interval (sec)';
+$lang['rss_show_summary'] = 'XML feed show summary in title';
+$lang['rss_show_deleted'] = 'XML feed Show deleted feeds';
+$lang['rss_media'] = 'What kind of changes should be listed in the XML feed?';
+$lang['rss_media_o_both'] = 'both';
+$lang['rss_media_o_pages'] = 'pages';
+$lang['rss_media_o_media'] = 'media';
+
+
+/* Advanced Options */
+$lang['updatecheck'] = 'Check for updates and security warnings? DokuWiki needs to contact update.dokuwiki.org for this feature.';
+$lang['userewrite'] = 'Use nice URLs';
+$lang['useslash'] = 'Use slash as namespace separator in URLs';
+$lang['sepchar'] = 'Page name word separator';
+$lang['canonical'] = 'Use fully canonical URLs';
+$lang['fnencode'] = 'Method for encoding non-ASCII filenames.';
+$lang['autoplural'] = 'Check for plural forms in links';
+$lang['compression'] = 'Compression method for attic files';
+$lang['gzip_output'] = 'Use gzip Content-Encoding for xhtml';
+$lang['compress'] = 'Compact CSS and javascript output';
+$lang['cssdatauri'] = 'Size in bytes up to which images referenced in CSS files should be embedded right into the stylesheet to reduce HTTP request header overhead. <code>400</code> to <code>600</code> bytes is a good value. Set <code>0</code> to disable.';
+$lang['send404'] = 'Send "HTTP 404/Page Not Found" for non existing pages';
+$lang['broken_iua'] = 'Is the ignore_user_abort function broken on your system? This could cause a non working search index. IIS+PHP/CGI is known to be broken. See <a href="http://bugs.dokuwiki.org/?do=details&amp;task_id=852">Bug 852</a> for more info.';
+$lang['xsendfile'] = 'Use the X-Sendfile header to let the webserver deliver static files? Your webserver needs to support this.';
+$lang['renderer_xhtml'] = 'Renderer to use for main (xhtml) wiki output';
+$lang['renderer__core'] = '%s (dokuwiki core)';
+$lang['renderer__plugin'] = '%s (plugin)';
+$lang['search_nslimit'] = 'Limit the search to the current X namespaces. When a search is executed from a page within a deeper namespace, the first X namespaces will be added as filter';
+$lang['search_fragment'] = 'Specify the default fragment search behavior';
+$lang['search_fragment_o_exact'] = 'exact';
+$lang['search_fragment_o_starts_with'] = 'starts with';
+$lang['search_fragment_o_ends_with'] = 'ends with';
+$lang['search_fragment_o_contains'] = 'contains';
+$lang['trustedproxy'] = 'Trust forwarding proxies matching this regular expression about the true client IP they report. The default matches local networks. Leave empty to trust no proxy.';
+
+$lang['_feature_flags'] = 'Feature Flags';
+$lang['defer_js'] = 'Defer javascript to be execute after the page\'s HTML has been parsed. Improves perceived page speed but could break a small number of plugins.';
+
+/* Network Options */
+$lang['dnslookups'] = 'DokuWiki will lookup hostnames for remote IP addresses of users editing pages. If you have a slow or non working DNS server or don\'t want this feature, disable this option';
+$lang['jquerycdn'] = 'Should the jQuery and jQuery UI script files be loaded from a CDN? This adds additional HTTP requests, but files may load faster and users may have them cached already.';
+
+/* jQuery CDN options */
+$lang['jquerycdn_o_0'] = 'No CDN, local delivery only';
+$lang['jquerycdn_o_jquery'] = 'CDN at code.jquery.com';
+$lang['jquerycdn_o_cdnjs'] = 'CDN at cdnjs.com';
+
+/* Proxy Options */
+$lang['proxy____host'] = 'Proxy servername';
+$lang['proxy____port'] = 'Proxy port';
+$lang['proxy____user'] = 'Proxy user name';
+$lang['proxy____pass'] = 'Proxy password';
+$lang['proxy____ssl'] = 'Use SSL to connect to proxy';
+$lang['proxy____except'] = 'Regular expression to match URLs for which the proxy should be skipped.';
+
+/* License Options */
+$lang['license_o_'] = 'None chosen';
+
+/* typography options */
+$lang['typography_o_0'] = 'none';
+$lang['typography_o_1'] = 'excluding single quotes';
+$lang['typography_o_2'] = 'including single quotes (might not always work)';
+
+/* userewrite options */
+$lang['userewrite_o_0'] = 'none';
+$lang['userewrite_o_1'] = '.htaccess';
+$lang['userewrite_o_2'] = 'DokuWiki internal';
+
+/* deaccent options */
+$lang['deaccent_o_0'] = 'off';
+$lang['deaccent_o_1'] = 'remove accents';
+$lang['deaccent_o_2'] = 'romanize';
+
+/* gdlib options */
+$lang['gdlib_o_0'] = 'GD Lib not available';
+$lang['gdlib_o_1'] = 'Version 1.x';
+$lang['gdlib_o_2'] = 'Autodetection';
+
+/* rss_type options */
+$lang['rss_type_o_rss'] = 'RSS 0.91';
+$lang['rss_type_o_rss1'] = 'RSS 1.0';
+$lang['rss_type_o_rss2'] = 'RSS 2.0';
+$lang['rss_type_o_atom'] = 'Atom 0.3';
+$lang['rss_type_o_atom1'] = 'Atom 1.0';
+
+/* rss_content options */
+$lang['rss_content_o_abstract'] = 'Abstract';
+$lang['rss_content_o_diff'] = 'Unified Diff';
+$lang['rss_content_o_htmldiff'] = 'HTML formatted diff table';
+$lang['rss_content_o_html'] = 'Full HTML page content';
+
+/* rss_linkto options */
+$lang['rss_linkto_o_diff'] = 'difference view';
+$lang['rss_linkto_o_page'] = 'the revised page';
+$lang['rss_linkto_o_rev'] = 'list of revisions';
+$lang['rss_linkto_o_current'] = 'the current page';
+
+/* compression options */
+$lang['compression_o_0'] = 'none';
+$lang['compression_o_gz'] = 'gzip';
+$lang['compression_o_bz2'] = 'bz2';
+
+/* xsendfile header */
+$lang['xsendfile_o_0'] = "don't use";
+$lang['xsendfile_o_1'] = 'Proprietary lighttpd header (before release 1.5)';
+$lang['xsendfile_o_2'] = 'Standard X-Sendfile header';
+$lang['xsendfile_o_3'] = 'Proprietary Nginx X-Accel-Redirect header';
+
+/* Display user info */
+$lang['showuseras_o_loginname'] = 'Login name';
+$lang['showuseras_o_username'] = "User's full name";
+$lang['showuseras_o_username_link'] = "User's full name as interwiki user link";
+$lang['showuseras_o_email'] = "User's e-mail addresss (obfuscated according to mailguard setting)";
+$lang['showuseras_o_email_link'] = "User's e-mail addresss as a mailto: link";
+
+/* useheading options */
+$lang['useheading_o_0'] = 'Never';
+$lang['useheading_o_navigation'] = 'Navigation Only';
+$lang['useheading_o_content'] = 'Wiki Content Only';
+$lang['useheading_o_1'] = 'Always';
+
+$lang['readdircache'] = 'Maximum age for readdir cache (sec)';
diff --git a/platform/www/lib/plugins/config/plugin.info.txt b/platform/www/lib/plugins/config/plugin.info.txt
new file mode 100644
index 0000000..ddd7265
--- /dev/null
+++ b/platform/www/lib/plugins/config/plugin.info.txt
@@ -0,0 +1,7 @@
+base config
+author Christopher Smith
+email chris@jalakai.co.uk
+date 2015-07-18
+name Configuration Manager
+desc Manage Dokuwiki's Configuration Settings
+url http://dokuwiki.org/plugin:config
diff --git a/platform/www/lib/plugins/config/settings/config.metadata.php b/platform/www/lib/plugins/config/settings/config.metadata.php
new file mode 100644
index 0000000..6fdd64d
--- /dev/null
+++ b/platform/www/lib/plugins/config/settings/config.metadata.php
@@ -0,0 +1,245 @@
+<?php
+/**
+ * Metadata for configuration manager plugin
+ *
+ * Note: This file is loaded in Loader::loadMeta().
+ *
+ * Format:
+ * $meta[<setting name>] = array(<handler class id>,<param name> => <param value>);
+ *
+ * <handler class id> is the handler class name without the "setting_" prefix
+ *
+ * Defined classes (see core/Setting/*):
+ * Generic
+ * -------------------------------------------
+ * '' - default class ('setting'), textarea, minimal input validation, setting output in quotes
+ * 'string' - single line text input, minimal input validation, setting output in quotes
+ * 'numeric' - text input, accepts numbers and arithmetic operators, setting output without quotes
+ * if given the '_min' and '_max' parameters are used for validation
+ * 'numericopt' - like above, but accepts empty values
+ * 'onoff' - checkbox input, setting output 0|1
+ * 'multichoice' - select input (single choice), setting output with quotes, required _choices parameter
+ * 'email' - text input, input must conform to email address format, supports optional '_multiple'
+ * parameter for multiple comma separated email addresses
+ * 'password' - password input, minimal input validation, setting output text in quotes, maybe encoded
+ * according to the _code parameter
+ * 'dirchoice' - as multichoice, selection choices based on folders found at location specified in _dir
+ * parameter (required). A pattern can be used to restrict the folders to only those which
+ * match the pattern.
+ * 'multicheckbox'- a checkbox for each choice plus an "other" string input, config file setting is a comma
+ * separated list of checked choices
+ * 'fieldset' - used to group configuration settings, but is not itself a setting. To make this clear in
+ * the language files the keys for this type should start with '_'.
+ * 'array' - a simple (one dimensional) array of string values, shown as comma separated list in the
+ * config manager but saved as PHP array(). Values may not contain commas themselves.
+ * _pattern matching on the array values supported.
+ * 'regex' - regular expression string, normally without delimiters; as for string, in addition tested
+ * to see if will compile & run as a regex. in addition to _pattern, also accepts _delimiter
+ * (default '/') and _pregflags (default 'ui')
+ *
+ * Single Setting
+ * -------------------------------------------------
+ * 'savedir' - as 'setting', input tested against initpath() (inc/init.php)
+ * 'sepchar' - as multichoice, selection constructed from string of valid values
+ * 'authtype' - as 'setting', input validated against a valid php file at expected location for auth files
+ * 'im_convert' - as 'setting', input must exist and be an im_convert module
+ * 'disableactions' - as 'setting'
+ * 'compression' - no additional parameters. checks php installation supports possible compression alternatives
+ * 'licence' - as multichoice, selection constructed from licence strings in language files
+ * 'renderer' - as multichoice, selection constructed from enabled renderer plugins which canRender()
+ * 'authtype' - as multichoice, selection constructed from the enabled auth plugins
+ *
+ * Any setting commented or missing will use 'setting' class - text input, minimal validation, quoted output
+ *
+ * Defined parameters:
+ * '_caution' - no value (default) or 'warning', 'danger', 'security'. display an alert along with the setting
+ * '_pattern' - string, a preg pattern. input is tested against this pattern before being accepted
+ * optional all classes, except onoff & multichoice which ignore it
+ * '_choices' - array of choices. used to populate a selection box. choice will be replaced by a localised
+ * language string, indexed by <setting name>_o_<choice>, if one exists
+ * required by 'multichoice' & 'multicheckbox' classes, ignored by others
+ * '_dir' - location of directory to be used to populate choice list
+ * required by 'dirchoice' class, ignored by other classes
+ * '_combine' - complimentary output setting values which can be combined into a single display checkbox
+ * optional for 'multicheckbox', ignored by other classes
+ * '_code' - encoding method to use, accepted values: 'base64','uuencode','plain'. defaults to plain.
+ * '_min' - minimum numeric value, optional for 'numeric' and 'numericopt', ignored by others
+ * '_max' - maximum numeric value, optional for 'numeric' and 'numericopt', ignored by others
+ * '_delimiter' - string, default '/', a single character used as a delimiter for testing regex input values
+ * '_pregflags' - string, default 'ui', valid preg pattern modifiers used when testing regex input values, for more
+ * information see http://php.net/manual/en/reference.pcre.pattern.modifiers.php
+ * '_multiple' - bool, allow multiple comma separated email values; optional for 'email', ignored by others
+ * '_other' - how to handle other values (not listed in _choices). accepted values: 'always','exists','never'
+ * default value 'always'. 'exists' only shows 'other' input field when the setting contains value(s)
+ * not listed in choices (e.g. due to manual editing or update changing _choices). This is safer than
+ * 'never' as it will not discard unknown/other values.
+ * optional for 'multicheckbox', ignored by others
+ *
+ * The order of the settings influences the order in which they apppear in the config manager
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+$meta['_basic'] = array('fieldset');
+$meta['title'] = array('string');
+$meta['start'] = array('string','_caution' => 'warning','_pattern' => '!^[^:;/]+$!'); // don't accept namespaces
+$meta['lang'] = array('dirchoice','_dir' => DOKU_INC.'inc/lang/');
+$meta['template'] = array('dirchoice','_dir' => DOKU_INC.'lib/tpl/','_pattern' => '/^[\w-]+$/');
+$meta['tagline'] = array('string');
+$meta['sidebar'] = array('string');
+$meta['license'] = array('license');
+$meta['savedir'] = array('savedir','_caution' => 'danger');
+$meta['basedir'] = array('string','_caution' => 'danger');
+$meta['baseurl'] = array('string','_caution' => 'danger');
+$meta['cookiedir'] = array('string','_caution' => 'danger');
+$meta['dmode'] = array('numeric','_pattern' => '/0[0-7]{3,4}/'); // only accept octal representation
+$meta['fmode'] = array('numeric','_pattern' => '/0[0-7]{3,4}/'); // only accept octal representation
+$meta['allowdebug'] = array('onoff','_caution' => 'security');
+
+$meta['_display'] = array('fieldset');
+$meta['recent'] = array('numeric');
+$meta['recent_days'] = array('numeric');
+$meta['breadcrumbs'] = array('numeric','_min' => 0);
+$meta['youarehere'] = array('onoff');
+$meta['fullpath'] = array('onoff','_caution' => 'security');
+$meta['typography'] = array('multichoice','_choices' => array(0,1,2));
+$meta['dformat'] = array('string');
+$meta['signature'] = array('string');
+$meta['showuseras'] = array(
+ 'multichoice',
+ '_choices' => array('loginname', 'username', 'username_link', 'email', 'email_link')
+);
+$meta['toptoclevel'] = array('multichoice','_choices' => array(1,2,3,4,5)); // 5 toc levels
+$meta['tocminheads'] = array('multichoice','_choices' => array(0,1,2,3,4,5,10,15,20));
+$meta['maxtoclevel'] = array('multichoice','_choices' => array(0,1,2,3,4,5));
+$meta['maxseclevel'] = array('multichoice','_choices' => array(0,1,2,3,4,5)); // 0 for no sec edit buttons
+$meta['camelcase'] = array('onoff','_caution' => 'warning');
+$meta['deaccent'] = array('multichoice','_choices' => array(0,1,2),'_caution' => 'warning');
+$meta['useheading'] = array('multichoice','_choices' => array(0,'navigation','content',1));
+$meta['sneaky_index'] = array('onoff');
+$meta['hidepages'] = array('regex');
+
+$meta['_authentication'] = array('fieldset');
+$meta['useacl'] = array('onoff','_caution' => 'danger');
+$meta['autopasswd'] = array('onoff');
+$meta['authtype'] = array('authtype','_caution' => 'danger');
+$meta['passcrypt'] = array('multichoice','_choices' => array(
+ 'smd5','md5','apr1','sha1','ssha','lsmd5','crypt','mysql','my411','kmd5','pmd5','hmd5',
+ 'mediawiki','bcrypt','djangomd5','djangosha1','djangopbkdf2_sha1','djangopbkdf2_sha256',
+ 'sha512','argon2i','argon2id'
+));
+$meta['defaultgroup']= array('string');
+$meta['superuser'] = array('string','_caution' => 'danger');
+$meta['manager'] = array('string');
+$meta['profileconfirm'] = array('onoff');
+$meta['rememberme'] = array('onoff');
+$meta['disableactions'] = array(
+ 'disableactions',
+ '_choices' => array(
+ 'backlink',
+ 'index',
+ 'recent',
+ 'revisions',
+ 'search',
+ 'subscription',
+ 'register',
+ 'resendpwd',
+ 'profile',
+ 'profile_delete',
+ 'edit',
+ 'wikicode',
+ 'check',
+ 'rss'
+ ),
+ '_combine' => array(
+ 'subscription' => array('subscribe', 'unsubscribe'),
+ 'wikicode' => array('source', 'export_raw')
+ )
+);
+$meta['auth_security_timeout'] = array('numeric');
+$meta['securecookie'] = array('onoff');
+$meta['remote'] = array('onoff','_caution' => 'security');
+$meta['remoteuser'] = array('string');
+
+$meta['_anti_spam'] = array('fieldset');
+$meta['usewordblock']= array('onoff');
+$meta['relnofollow'] = array('onoff');
+$meta['indexdelay'] = array('numeric');
+$meta['mailguard'] = array('multichoice','_choices' => array('visible','hex','none'));
+$meta['iexssprotect']= array('onoff','_caution' => 'security');
+
+$meta['_editing'] = array('fieldset');
+$meta['usedraft'] = array('onoff');
+$meta['htmlok'] = array('onoff','_caution' => 'security');
+$meta['phpok'] = array('onoff','_caution' => 'security');
+$meta['locktime'] = array('numeric');
+$meta['cachetime'] = array('numeric');
+
+$meta['_links'] = array('fieldset');
+$meta['target____wiki'] = array('string');
+$meta['target____interwiki'] = array('string');
+$meta['target____extern'] = array('string');
+$meta['target____media'] = array('string');
+$meta['target____windows'] = array('string');
+
+$meta['_media'] = array('fieldset');
+$meta['mediarevisions'] = array('onoff');
+$meta['gdlib'] = array('multichoice','_choices' => array(0,1,2));
+$meta['im_convert'] = array('im_convert');
+$meta['jpg_quality'] = array('numeric','_pattern' => '/^100$|^[1-9]?[0-9]$/'); //(0-100)
+$meta['fetchsize'] = array('numeric');
+$meta['refcheck'] = array('onoff');
+
+$meta['_notifications'] = array('fieldset');
+$meta['subscribers'] = array('onoff');
+$meta['subscribe_time'] = array('numeric');
+$meta['notify'] = array('email', '_multiple' => true);
+$meta['registernotify'] = array('email', '_multiple' => true);
+$meta['mailfrom'] = array('email', '_placeholders' => true);
+$meta['mailreturnpath'] = array('email', '_placeholders' => true);
+$meta['mailprefix'] = array('string');
+$meta['htmlmail'] = array('onoff');
+
+$meta['_syndication'] = array('fieldset');
+$meta['sitemap'] = array('numeric');
+$meta['rss_type'] = array('multichoice','_choices' => array('rss','rss1','rss2','atom','atom1'));
+$meta['rss_linkto'] = array('multichoice','_choices' => array('diff','page','rev','current'));
+$meta['rss_content'] = array('multichoice','_choices' => array('abstract','diff','htmldiff','html'));
+$meta['rss_media'] = array('multichoice','_choices' => array('both','pages','media'));
+$meta['rss_update'] = array('numeric');
+$meta['rss_show_summary'] = array('onoff');
+$meta['rss_show_deleted'] = array('onoff');
+
+$meta['_advanced'] = array('fieldset');
+$meta['updatecheck'] = array('onoff');
+$meta['userewrite'] = array('multichoice','_choices' => array(0,1,2),'_caution' => 'danger');
+$meta['useslash'] = array('onoff');
+$meta['sepchar'] = array('sepchar','_caution' => 'warning');
+$meta['canonical'] = array('onoff');
+$meta['fnencode'] = array('multichoice','_choices' => array('url','safe','utf-8'),'_caution' => 'warning');
+$meta['autoplural'] = array('onoff');
+$meta['compress'] = array('onoff');
+$meta['cssdatauri'] = array('numeric','_pattern' => '/^\d+$/');
+$meta['gzip_output'] = array('onoff');
+$meta['send404'] = array('onoff');
+$meta['compression'] = array('compression','_caution' => 'warning');
+$meta['broken_iua'] = array('onoff');
+$meta['xsendfile'] = array('multichoice','_choices' => array(0,1,2,3),'_caution' => 'warning');
+$meta['renderer_xhtml'] = array('renderer','_format' => 'xhtml','_choices' => array('xhtml'),'_caution' => 'warning');
+$meta['readdircache'] = array('numeric');
+$meta['search_nslimit'] = array('numeric', '_min' => 0);
+$meta['search_fragment'] = array('multichoice','_choices' => array('exact', 'starts_with', 'ends_with', 'contains'),);
+$meta['trustedproxy'] = array('regex');
+
+$meta['_feature_flags'] = ['fieldset'];
+$meta['defer_js'] = ['onoff'];
+
+$meta['_network'] = array('fieldset');
+$meta['dnslookups'] = array('onoff');
+$meta['jquerycdn'] = array('multichoice', '_choices' => array(0,'jquery', 'cdnjs'));
+$meta['proxy____host'] = array('string','_pattern' => '#^(|[a-z0-9\-\.+]+)$#i');
+$meta['proxy____port'] = array('numericopt');
+$meta['proxy____user'] = array('string');
+$meta['proxy____pass'] = array('password','_code' => 'base64');
+$meta['proxy____ssl'] = array('onoff');
+$meta['proxy____except'] = array('string');
diff --git a/platform/www/lib/plugins/config/style.css b/platform/www/lib/plugins/config/style.css
new file mode 100644
index 0000000..054021e
--- /dev/null
+++ b/platform/www/lib/plugins/config/style.css
@@ -0,0 +1,167 @@
+/* plugin:configmanager */
+#config__manager div.success,
+#config__manager div.error,
+#config__manager div.info {
+ background-position: 0.5em;
+ padding: 0.5em;
+ text-align: center;
+}
+
+#config__manager fieldset {
+ margin: 1em;
+ width: auto;
+ margin-bottom: 2em;
+ background-color: __background_alt__;
+ color: __text__;
+ padding: 0 1em;
+}
+[dir=rtl] #config__manager fieldset {
+ clear: both;
+}
+#config__manager legend {
+ font-size: 1.25em;
+}
+
+#config__manager form { }
+#config__manager table {
+ margin: 1em 0;
+ width: 100%;
+}
+
+#config__manager fieldset td {
+ text-align: left;
+}
+[dir=rtl] #config__manager fieldset td {
+ text-align: right;
+}
+#config__manager fieldset td.value {
+ /* fixed data column width */
+ width: 31em;
+}
+
+[dir=rtl] #config__manager label {
+ text-align: right;
+}
+[dir=rtl] #config__manager td.value input.checkbox {
+ float: right;
+ padding-left: 0;
+ padding-right: 0.7em;
+}
+[dir=rtl] #config__manager td.value label {
+ float: left;
+}
+
+#config__manager td.label {
+ padding: 0.8em 0 0.6em 1em;
+ vertical-align: top;
+}
+[dir=rtl] #config__manager td.label {
+ padding: 0.8em 1em 0.6em 0;
+}
+
+#config__manager td.label label {
+ clear: left;
+ display: block;
+}
+[dir=rtl] #config__manager td.label label {
+ clear: right;
+}
+#config__manager td.label img {
+ padding: 0 10px;
+ vertical-align: middle;
+ float: right;
+}
+[dir=rtl] #config__manager td.label img {
+ float: left;
+}
+
+#config__manager td.label span.outkey {
+ font-size: 70%;
+ margin-top: -1.7em;
+ margin-left: -1em;
+ display: block;
+ background-color: __background__;
+ color: __text_neu__;
+ float: left;
+ padding: 0 0.1em;
+ position: relative;
+ z-index: 1;
+}
+[dir=rtl] #config__manager td.label span.outkey {
+ float: right;
+ margin-right: 1em;
+}
+
+#config__manager td input.edit {
+ width: 30em;
+}
+#config__manager td .input {
+ width: 30.8em;
+}
+#config__manager td select.edit { }
+#config__manager td textarea.edit {
+ width: 27.5em;
+ height: 4em;
+}
+
+#config__manager td textarea.edit:focus {
+ height: 10em;
+}
+
+#config__manager tr .input,
+#config__manager tr input,
+#config__manager tr textarea,
+#config__manager tr select {
+ background-color: #fff;
+ color: #000;
+}
+
+#config__manager tr.default .input,
+#config__manager tr.default input,
+#config__manager tr.default textarea,
+#config__manager tr.default select,
+#config__manager .selectiondefault {
+ background-color: #ccddff;
+ color: #000;
+}
+
+#config__manager tr.protected .input,
+#config__manager tr.protected input,
+#config__manager tr.protected textarea,
+#config__manager tr.protected select,
+#config__manager tr.protected .selection {
+ background-color: #ffcccc!important;
+ color: #000 !important;
+}
+
+#config__manager td.error { background-color: red; color: #000; }
+
+#config__manager .selection {
+ width: 14.8em;
+ float: left;
+ margin: 0 0.3em 2px 0;
+}
+[dir=rtl] #config__manager .selection {
+ width: 14.8em;
+ float: right;
+ margin: 0 0 2px 0.3em;
+}
+
+#config__manager .selection label {
+ float: right;
+ width: 14em;
+ font-size: 90%;
+}
+
+
+#config__manager .other {
+ clear: both;
+ padding-top: 0.5em;
+}
+
+#config__manager .other label {
+ padding-left: 2px;
+ font-size: 90%;
+}
+
+/* end plugin:configmanager */
diff --git a/platform/www/lib/plugins/extension/action.php b/platform/www/lib/plugins/extension/action.php
new file mode 100644
index 0000000..3bb0448
--- /dev/null
+++ b/platform/www/lib/plugins/extension/action.php
@@ -0,0 +1,82 @@
+<?php
+/** DokuWiki Plugin extension (Action Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+class action_plugin_extension extends DokuWiki_Action_Plugin
+{
+
+ /**
+ * Registers a callback function for a given event
+ *
+ * @param Doku_Event_Handler $controller DokuWiki's event controller object
+ * @return void
+ */
+ public function register(Doku_Event_Handler $controller)
+ {
+ $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'info');
+ }
+
+ /**
+ * Create the detail info for a single plugin
+ *
+ * @param Doku_Event $event
+ * @param $param
+ */
+ public function info(Doku_Event $event, $param)
+ {
+ global $USERINFO;
+ global $INPUT;
+
+ if ($event->data != 'plugin_extension') return;
+ $event->preventDefault();
+ $event->stopPropagation();
+
+ /** @var admin_plugin_extension $admin */
+ $admin = plugin_load('admin', 'extension');
+ if (!$admin->isAccessibleByCurrentUser()) {
+ http_status(403);
+ echo 'Forbidden';
+ exit;
+ }
+
+ $ext = $INPUT->str('ext');
+ if (!$ext) {
+ http_status(400);
+ echo 'no extension given';
+ return;
+ }
+
+ /** @var helper_plugin_extension_extension $extension */
+ $extension = plugin_load('helper', 'extension_extension');
+ $extension->setExtension($ext);
+
+ $act = $INPUT->str('act');
+ switch ($act) {
+ case 'enable':
+ case 'disable':
+ $extension->$act(); //enables/disables
+
+ $reverse = ($act == 'disable') ? 'enable' : 'disable';
+
+ $return = array(
+ 'state' => $act.'d', // isn't English wonderful? :-)
+ 'reverse' => $reverse,
+ 'label' => $extension->getLang('btn_'.$reverse)
+ );
+
+ header('Content-Type: application/json');
+ echo json_encode($return);
+ break;
+
+ case 'info':
+ default:
+ /** @var helper_plugin_extension_list $list */
+ $list = plugin_load('helper', 'extension_list');
+ header('Content-Type: text/html; charset=utf-8');
+ echo $list->makeInfo($extension);
+ }
+ }
+}
diff --git a/platform/www/lib/plugins/extension/admin.php b/platform/www/lib/plugins/extension/admin.php
new file mode 100644
index 0000000..7e7eb60
--- /dev/null
+++ b/platform/www/lib/plugins/extension/admin.php
@@ -0,0 +1,185 @@
+<?php
+/**
+ * DokuWiki Plugin extension (Admin Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Hamann <michael@content-space.de>
+ */
+
+/**
+ * Admin part of the extension manager
+ */
+class admin_plugin_extension extends DokuWiki_Admin_Plugin
+{
+ protected $infoFor = null;
+ /** @var helper_plugin_extension_gui */
+ protected $gui;
+
+ /**
+ * Constructor
+ *
+ * loads additional helpers
+ */
+ public function __construct()
+ {
+ $this->gui = plugin_load('helper', 'extension_gui');
+ }
+
+ /**
+ * @return int sort number in admin menu
+ */
+ public function getMenuSort()
+ {
+ return 0;
+ }
+
+ /**
+ * @return bool true if only access for superuser, false is for superusers and moderators
+ */
+ public function forAdminOnly()
+ {
+ return true;
+ }
+
+ /**
+ * Execute the requested action(s) and initialize the plugin repository
+ */
+ public function handle()
+ {
+ global $INPUT;
+ // initialize the remote repository
+ /* @var helper_plugin_extension_repository $repository */
+ $repository = $this->loadHelper('extension_repository');
+
+ if (!$repository->hasAccess(!$INPUT->bool('purge'))) {
+ $url = $this->gui->tabURL('', ['purge' => 1], '&');
+ msg($this->getLang('repo_error').
+ ' [<a href="'.$url.'">'.$this->getLang('repo_retry').'</a>]', -1
+ );
+ }
+
+ if (!in_array('ssl', stream_get_transports())) {
+ msg($this->getLang('nossl'), -1);
+ }
+
+ /* @var helper_plugin_extension_extension $extension */
+ $extension = $this->loadHelper('extension_extension');
+
+ try {
+ if ($INPUT->post->has('fn') && checkSecurityToken()) {
+ $actions = $INPUT->post->arr('fn');
+ foreach ($actions as $action => $extensions) {
+ foreach ($extensions as $extname => $label) {
+ switch ($action) {
+ case 'install':
+ case 'reinstall':
+ case 'update':
+ $extension->setExtension($extname);
+ $installed = $extension->installOrUpdate();
+ foreach ($installed as $ext => $info) {
+ msg(sprintf(
+ $this->getLang('msg_'.$info['type'].'_'.$info['action'].'_success'),
+ $info['base']), 1
+ );
+ }
+ break;
+ case 'uninstall':
+ $extension->setExtension($extname);
+ $status = $extension->uninstall();
+ if ($status) {
+ msg(sprintf(
+ $this->getLang('msg_delete_success'),
+ hsc($extension->getDisplayName())), 1
+ );
+ } else {
+ msg(sprintf(
+ $this->getLang('msg_delete_failed'),
+ hsc($extension->getDisplayName())), -1
+ );
+ }
+ break;
+ case 'enable':
+ $extension->setExtension($extname);
+ $status = $extension->enable();
+ if ($status !== true) {
+ msg($status, -1);
+ } else {
+ msg(sprintf(
+ $this->getLang('msg_enabled'),
+ hsc($extension->getDisplayName())), 1
+ );
+ }
+ break;
+ case 'disable':
+ $extension->setExtension($extname);
+ $status = $extension->disable();
+ if ($status !== true) {
+ msg($status, -1);
+ } else {
+ msg(sprintf(
+ $this->getLang('msg_disabled'),
+ hsc($extension->getDisplayName())), 1
+ );
+ }
+ break;
+ }
+ }
+ }
+ send_redirect($this->gui->tabURL('', [], '&', true));
+ } elseif ($INPUT->post->str('installurl') && checkSecurityToken()) {
+ $installed = $extension->installFromURL(
+ $INPUT->post->str('installurl'),
+ $INPUT->post->bool('overwrite'));
+ foreach ($installed as $ext => $info) {
+ msg(sprintf(
+ $this->getLang('msg_'.$info['type'].'_'.$info['action'].'_success'),
+ $info['base']), 1
+ );
+ }
+ send_redirect($this->gui->tabURL('', [], '&', true));
+ } elseif (isset($_FILES['installfile']) && checkSecurityToken()) {
+ $installed = $extension->installFromUpload('installfile', $INPUT->post->bool('overwrite'));
+ foreach ($installed as $ext => $info) {
+ msg(sprintf(
+ $this->getLang('msg_'.$info['type'].'_'.$info['action'].'_success'),
+ $info['base']), 1
+ );
+ }
+ send_redirect($this->gui->tabURL('', [], '&', true));
+ }
+ } catch (Exception $e) {
+ msg($e->getMessage(), -1);
+ send_redirect($this->gui->tabURL('', [], '&', true));
+ }
+ }
+
+ /**
+ * Render HTML output
+ */
+ public function html()
+ {
+ echo '<h1>'.$this->getLang('menu').'</h1>'.DOKU_LF;
+ echo '<div id="extension__manager">'.DOKU_LF;
+
+ $this->gui->tabNavigation();
+
+ switch ($this->gui->currentTab()) {
+ case 'search':
+ $this->gui->tabSearch();
+ break;
+ case 'templates':
+ $this->gui->tabTemplates();
+ break;
+ case 'install':
+ $this->gui->tabInstall();
+ break;
+ case 'plugins':
+ default:
+ $this->gui->tabPlugins();
+ }
+
+ echo '</div>'.DOKU_LF;
+ }
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/extension/admin.svg b/platform/www/lib/plugins/extension/admin.svg
new file mode 100644
index 0000000..6bd7c0d
--- /dev/null
+++ b/platform/www/lib/plugins/extension/admin.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M20.5 11H19V7a2 2 0 0 0-2-2h-4V3.5A2.5 2.5 0 0 0 10.5 1 2.5 2.5 0 0 0 8 3.5V5H4a2 2 0 0 0-2 2v3.8h1.5c1.5 0 2.7 1.2 2.7 2.7 0 1.5-1.2 2.7-2.7 2.7H2V20a2 2 0 0 0 2 2h3.8v-1.5c0-1.5 1.2-2.7 2.7-2.7 1.5 0 2.7 1.2 2.7 2.7V22H17a2 2 0 0 0 2-2v-4h1.5a2.5 2.5 0 0 0 2.5-2.5 2.5 2.5 0 0 0-2.5-2.5z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/plugins/extension/all.less b/platform/www/lib/plugins/extension/all.less
new file mode 100644
index 0000000..3d9688e
--- /dev/null
+++ b/platform/www/lib/plugins/extension/all.less
@@ -0,0 +1,37 @@
+
+@media only screen and (max-width: 600px) {
+
+#extension__list .legend {
+ > div {
+ padding-left: 0;
+ }
+
+ div.screenshot {
+ margin: 0 .5em .5em 0;
+ }
+
+ h2 {
+ width: auto;
+ float: none;
+ }
+
+ div.linkbar {
+ clear: left;
+ }
+}
+
+[dir=rtl] #extension__list .legend {
+ > div {
+ padding-right: 0;
+ }
+
+ div.screenshot {
+ margin: 0 0 .5em .5em;
+ }
+
+ div.linkbar {
+ clear: right;
+ }
+}
+
+} /* /@media */
diff --git a/platform/www/lib/plugins/extension/cli.php b/platform/www/lib/plugins/extension/cli.php
new file mode 100644
index 0000000..a293f87
--- /dev/null
+++ b/platform/www/lib/plugins/extension/cli.php
@@ -0,0 +1,372 @@
+<?php
+
+use splitbrain\phpcli\Colors;
+
+/**
+ * Class cli_plugin_extension
+ *
+ * Command Line component for the extension manager
+ *
+ * @license GPL2
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class cli_plugin_extension extends DokuWiki_CLI_Plugin
+{
+ /** @inheritdoc */
+ protected function setup(\splitbrain\phpcli\Options $options)
+ {
+ // general setup
+ $options->setHelp(
+ "Manage plugins and templates for this DokuWiki instance\n\n" .
+ "Status codes:\n" .
+ " i - installed\n" .
+ " b - bundled with DokuWiki\n" .
+ " g - installed via git\n" .
+ " d - disabled\n" .
+ " u - update available\n"
+ );
+
+ // search
+ $options->registerCommand('search', 'Search for an extension');
+ $options->registerOption('max', 'Maximum number of results (default 10)', 'm', 'number', 'search');
+ $options->registerOption('verbose', 'Show detailed extension information', 'v', false, 'search');
+ $options->registerArgument('query', 'The keyword(s) to search for', true, 'search');
+
+ // list
+ $options->registerCommand('list', 'List installed extensions');
+ $options->registerOption('verbose', 'Show detailed extension information', 'v', false, 'list');
+ $options->registerOption('filter', 'Filter by this status', 'f', 'status', 'list');
+
+ // upgrade
+ $options->registerCommand('upgrade', 'Update all installed extensions to their latest versions');
+
+ // install
+ $options->registerCommand('install', 'Install or upgrade extensions');
+ $options->registerArgument('extensions...', 'One or more extensions to install', true, 'install');
+
+ // uninstall
+ $options->registerCommand('uninstall', 'Uninstall a new extension');
+ $options->registerArgument('extensions...', 'One or more extensions to install', true, 'uninstall');
+
+ // enable
+ $options->registerCommand('enable', 'Enable installed extensions');
+ $options->registerArgument('extensions...', 'One or more extensions to enable', true, 'enable');
+
+ // disable
+ $options->registerCommand('disable', 'Disable installed extensions');
+ $options->registerArgument('extensions...', 'One or more extensions to disable', true, 'disable');
+
+
+ }
+
+ /** @inheritdoc */
+ protected function main(\splitbrain\phpcli\Options $options)
+ {
+ /** @var helper_plugin_extension_repository $repo */
+ $repo = plugin_load('helper', 'extension_repository');
+ if (!$repo->hasAccess(false)) {
+ $this->warning('Extension Repository API is not accessible, no remote info available!');
+ }
+
+ switch ($options->getCmd()) {
+ case 'list':
+ $ret = $this->cmdList($options->getOpt('verbose'), $options->getOpt('filter', ''));
+ break;
+ case 'search':
+ $ret = $this->cmdSearch(
+ implode(' ', $options->getArgs()),
+ $options->getOpt('verbose'),
+ (int)$options->getOpt('max', 10)
+ );
+ break;
+ case 'install':
+ $ret = $this->cmdInstall($options->getArgs());
+ break;
+ case 'uninstall':
+ $ret = $this->cmdUnInstall($options->getArgs());
+ break;
+ case 'enable':
+ $ret = $this->cmdEnable(true, $options->getArgs());
+ break;
+ case 'disable':
+ $ret = $this->cmdEnable(false, $options->getArgs());
+ break;
+ case 'upgrade':
+ $ret = $this->cmdUpgrade();
+ break;
+ default:
+ echo $options->help();
+ $ret = 0;
+ }
+
+ exit($ret);
+ }
+
+ /**
+ * Upgrade all extensions
+ *
+ * @return int
+ */
+ protected function cmdUpgrade()
+ {
+ /* @var helper_plugin_extension_extension $ext */
+ $ext = $this->loadHelper('extension_extension');
+ $list = $this->getInstalledExtensions();
+
+ $ok = 0;
+ foreach ($list as $extname) {
+ $ext->setExtension($extname);
+ $date = $ext->getInstalledVersion();
+ $avail = $ext->getLastUpdate();
+ if ($avail && $avail > $date) {
+ $ok += $this->cmdInstall([$extname]);
+ }
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Enable or disable one or more extensions
+ *
+ * @param bool $set
+ * @param string[] $extensions
+ * @return int
+ */
+ protected function cmdEnable($set, $extensions)
+ {
+ /* @var helper_plugin_extension_extension $ext */
+ $ext = $this->loadHelper('extension_extension');
+
+ $ok = 0;
+ foreach ($extensions as $extname) {
+ $ext->setExtension($extname);
+ if (!$ext->isInstalled()) {
+ $this->error(sprintf('Extension %s is not installed', $ext->getID()));
+ $ok += 1;
+ continue;
+ }
+
+ if ($set) {
+ $status = $ext->enable();
+ $msg = 'msg_enabled';
+ } else {
+ $status = $ext->disable();
+ $msg = 'msg_disabled';
+ }
+
+ if ($status !== true) {
+ $this->error($status);
+ $ok += 1;
+ continue;
+ } else {
+ $this->success(sprintf($this->getLang($msg), $ext->getID()));
+ }
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Uninstall one or more extensions
+ *
+ * @param string[] $extensions
+ * @return int
+ */
+ protected function cmdUnInstall($extensions)
+ {
+ /* @var helper_plugin_extension_extension $ext */
+ $ext = $this->loadHelper('extension_extension');
+
+ $ok = 0;
+ foreach ($extensions as $extname) {
+ $ext->setExtension($extname);
+ if (!$ext->isInstalled()) {
+ $this->error(sprintf('Extension %s is not installed', $ext->getID()));
+ $ok += 1;
+ continue;
+ }
+
+ $status = $ext->uninstall();
+ if ($status) {
+ $this->success(sprintf($this->getLang('msg_delete_success'), $ext->getID()));
+ } else {
+ $this->error(sprintf($this->getLang('msg_delete_failed'), hsc($ext->getID())));
+ $ok = 1;
+ }
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Install one or more extensions
+ *
+ * @param string[] $extensions
+ * @return int
+ */
+ protected function cmdInstall($extensions)
+ {
+ /* @var helper_plugin_extension_extension $ext */
+ $ext = $this->loadHelper('extension_extension');
+
+ $ok = 0;
+ foreach ($extensions as $extname) {
+ $ext->setExtension($extname);
+
+ if (!$ext->getDownloadURL()) {
+ $ok += 1;
+ $this->error(
+ sprintf('Could not find download for %s', $ext->getID())
+ );
+ continue;
+ }
+
+ try {
+ $installed = $ext->installOrUpdate();
+ foreach ($installed as $name => $info) {
+ $this->success(sprintf(
+ $this->getLang('msg_' . $info['type'] . '_' . $info['action'] . '_success'),
+ $info['base'])
+ );
+ }
+ } catch (Exception $e) {
+ $this->error($e->getMessage());
+ $ok += 1;
+ }
+ }
+ return $ok;
+ }
+
+ /**
+ * Search for an extension
+ *
+ * @param string $query
+ * @param bool $showdetails
+ * @param int $max
+ * @return int
+ * @throws \splitbrain\phpcli\Exception
+ */
+ protected function cmdSearch($query, $showdetails, $max)
+ {
+ /** @var helper_plugin_extension_repository $repository */
+ $repository = $this->loadHelper('extension_repository');
+ $result = $repository->search($query);
+ if ($max) {
+ $result = array_slice($result, 0, $max);
+ }
+
+ $this->listExtensions($result, $showdetails);
+ return 0;
+ }
+
+ /**
+ * @param bool $showdetails
+ * @param string $filter
+ * @return int
+ * @throws \splitbrain\phpcli\Exception
+ */
+ protected function cmdList($showdetails, $filter)
+ {
+ $list = $this->getInstalledExtensions();
+ $this->listExtensions($list, $showdetails, $filter);
+
+ return 0;
+ }
+
+ /**
+ * Get all installed extensions
+ *
+ * @return array
+ */
+ protected function getInstalledExtensions()
+ {
+ /** @var Doku_Plugin_Controller $plugin_controller */
+ global $plugin_controller;
+ $pluginlist = $plugin_controller->getList('', true);
+ $tpllist = glob(DOKU_INC . 'lib/tpl/*', GLOB_ONLYDIR);
+ $tpllist = array_map(function ($path) {
+ return 'template:' . basename($path);
+ }, $tpllist);
+ $list = array_merge($pluginlist, $tpllist);
+ sort($list);
+ return $list;
+ }
+
+ /**
+ * List the given extensions
+ *
+ * @param string[] $list
+ * @param bool $details display details
+ * @param string $filter filter for this status
+ * @throws \splitbrain\phpcli\Exception
+ */
+ protected function listExtensions($list, $details, $filter = '')
+ {
+ /** @var helper_plugin_extension_extension $ext */
+ $ext = $this->loadHelper('extension_extension');
+ $tr = new \splitbrain\phpcli\TableFormatter($this->colors);
+
+
+ foreach ($list as $name) {
+ $ext->setExtension($name);
+
+ $status = '';
+ if ($ext->isInstalled()) {
+ $date = $ext->getInstalledVersion();
+ $avail = $ext->getLastUpdate();
+ $status = 'i';
+ if ($avail && $avail > $date) {
+ $vcolor = Colors::C_RED;
+ $status .= 'u';
+ } else {
+ $vcolor = Colors::C_GREEN;
+ }
+ if ($ext->isGitControlled()) $status = 'g';
+ if ($ext->isBundled()) $status = 'b';
+ if ($ext->isEnabled()) {
+ $ecolor = Colors::C_BROWN;
+ } else {
+ $ecolor = Colors::C_DARKGRAY;
+ $status .= 'd';
+ }
+ } else {
+ $ecolor = null;
+ $date = $ext->getLastUpdate();
+ $vcolor = null;
+ }
+
+ if ($filter && strpos($status, $filter) === false) {
+ continue;
+ }
+
+ echo $tr->format(
+ [20, 3, 12, '*'],
+ [
+ $ext->getID(),
+ $status,
+ $date,
+ strip_tags(sprintf(
+ $this->getLang('extensionby'),
+ $ext->getDisplayName(),
+ $this->colors->wrap($ext->getAuthor(), Colors::C_PURPLE))
+ )
+ ],
+ [
+ $ecolor,
+ Colors::C_YELLOW,
+ $vcolor,
+ null,
+ ]
+ );
+
+ if (!$details) continue;
+
+ echo $tr->format(
+ [5, '*'],
+ ['', $ext->getDescription()],
+ [null, Colors::C_CYAN]
+ );
+ }
+ }
+}
diff --git a/platform/www/lib/plugins/extension/helper/extension.php b/platform/www/lib/plugins/extension/helper/extension.php
new file mode 100644
index 0000000..5ddf332
--- /dev/null
+++ b/platform/www/lib/plugins/extension/helper/extension.php
@@ -0,0 +1,1298 @@
+<?php
+/**
+ * DokuWiki Plugin extension (Helper Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Hamann <michael@content-space.de>
+ */
+
+use dokuwiki\HTTP\DokuHTTPClient;
+use dokuwiki\Extension\PluginController;
+
+/**
+ * Class helper_plugin_extension_extension represents a single extension (plugin or template)
+ */
+class helper_plugin_extension_extension extends DokuWiki_Plugin
+{
+ private $id;
+ private $base;
+ private $is_template = false;
+ private $localInfo;
+ private $remoteInfo;
+ private $managerData;
+ /** @var helper_plugin_extension_repository $repository */
+ private $repository = null;
+
+ /** @var array list of temporary directories */
+ private $temporary = array();
+
+ /** @var string where templates are installed to */
+ private $tpllib = '';
+
+ /**
+ * helper_plugin_extension_extension constructor.
+ */
+ public function __construct()
+ {
+ $this->tpllib = dirname(tpl_incdir()).'/';
+ }
+
+ /**
+ * Destructor
+ *
+ * deletes any dangling temporary directories
+ */
+ public function __destruct()
+ {
+ foreach ($this->temporary as $dir) {
+ io_rmdir($dir, true);
+ }
+ }
+
+ /**
+ * @return bool false, this component is not a singleton
+ */
+ public function isSingleton()
+ {
+ return false;
+ }
+
+ /**
+ * Set the name of the extension this instance shall represents, triggers loading the local and remote data
+ *
+ * @param string $id The id of the extension (prefixed with template: for templates)
+ * @return bool If some (local or remote) data was found
+ */
+ public function setExtension($id)
+ {
+ $id = cleanID($id);
+ $this->id = $id;
+ $this->base = $id;
+
+ if (substr($id, 0, 9) == 'template:') {
+ $this->base = substr($id, 9);
+ $this->is_template = true;
+ } else {
+ $this->is_template = false;
+ }
+
+ $this->localInfo = array();
+ $this->managerData = array();
+ $this->remoteInfo = array();
+
+ if ($this->isInstalled()) {
+ $this->readLocalData();
+ $this->readManagerData();
+ }
+
+ if ($this->repository == null) {
+ $this->repository = $this->loadHelper('extension_repository');
+ }
+
+ $this->remoteInfo = $this->repository->getData($this->getID());
+
+ return ($this->localInfo || $this->remoteInfo);
+ }
+
+ /**
+ * If the extension is installed locally
+ *
+ * @return bool If the extension is installed locally
+ */
+ public function isInstalled()
+ {
+ return is_dir($this->getInstallDir());
+ }
+
+ /**
+ * If the extension is under git control
+ *
+ * @return bool
+ */
+ public function isGitControlled()
+ {
+ if (!$this->isInstalled()) return false;
+ return is_dir($this->getInstallDir().'/.git');
+ }
+
+ /**
+ * If the extension is bundled
+ *
+ * @return bool If the extension is bundled
+ */
+ public function isBundled()
+ {
+ if (!empty($this->remoteInfo['bundled'])) return $this->remoteInfo['bundled'];
+ return in_array(
+ $this->id,
+ array(
+ 'authad', 'authldap', 'authpdo', 'authplain',
+ 'acl', 'config', 'extension', 'info', 'popularity', 'revert',
+ 'safefnrecode', 'styling', 'testing', 'usermanager',
+ 'template:dokuwiki',
+ )
+ );
+ }
+
+ /**
+ * If the extension is protected against any modification (disable/uninstall)
+ *
+ * @return bool if the extension is protected
+ */
+ public function isProtected()
+ {
+ // never allow deinstalling the current auth plugin:
+ global $conf;
+ if ($this->id == $conf['authtype']) return true;
+
+ /** @var PluginController $plugin_controller */
+ global $plugin_controller;
+ $cascade = $plugin_controller->getCascade();
+ return (isset($cascade['protected'][$this->id]) && $cascade['protected'][$this->id]);
+ }
+
+ /**
+ * If the extension is installed in the correct directory
+ *
+ * @return bool If the extension is installed in the correct directory
+ */
+ public function isInWrongFolder()
+ {
+ return $this->base != $this->getBase();
+ }
+
+ /**
+ * If the extension is enabled
+ *
+ * @return bool If the extension is enabled
+ */
+ public function isEnabled()
+ {
+ global $conf;
+ if ($this->isTemplate()) {
+ return ($conf['template'] == $this->getBase());
+ }
+
+ /* @var PluginController $plugin_controller */
+ global $plugin_controller;
+ return $plugin_controller->isEnabled($this->base);
+ }
+
+ /**
+ * If the extension should be updated, i.e. if an updated version is available
+ *
+ * @return bool If an update is available
+ */
+ public function updateAvailable()
+ {
+ if (!$this->isInstalled()) return false;
+ if ($this->isBundled()) return false;
+ $lastupdate = $this->getLastUpdate();
+ if ($lastupdate === false) return false;
+ $installed = $this->getInstalledVersion();
+ if ($installed === false || $installed === $this->getLang('unknownversion')) return true;
+ return $this->getInstalledVersion() < $this->getLastUpdate();
+ }
+
+ /**
+ * If the extension is a template
+ *
+ * @return bool If this extension is a template
+ */
+ public function isTemplate()
+ {
+ return $this->is_template;
+ }
+
+ /**
+ * Get the ID of the extension
+ *
+ * This is the same as getName() for plugins, for templates it's getName() prefixed with 'template:'
+ *
+ * @return string
+ */
+ public function getID()
+ {
+ return $this->id;
+ }
+
+ /**
+ * Get the name of the installation directory
+ *
+ * @return string The name of the installation directory
+ */
+ public function getInstallName()
+ {
+ return $this->base;
+ }
+
+ // Data from plugin.info.txt/template.info.txt or the repo when not available locally
+ /**
+ * Get the basename of the extension
+ *
+ * @return string The basename
+ */
+ public function getBase()
+ {
+ if (!empty($this->localInfo['base'])) return $this->localInfo['base'];
+ return $this->base;
+ }
+
+ /**
+ * Get the display name of the extension
+ *
+ * @return string The display name
+ */
+ public function getDisplayName()
+ {
+ if (!empty($this->localInfo['name'])) return $this->localInfo['name'];
+ if (!empty($this->remoteInfo['name'])) return $this->remoteInfo['name'];
+ return $this->base;
+ }
+
+ /**
+ * Get the author name of the extension
+ *
+ * @return string|bool The name of the author or false if there is none
+ */
+ public function getAuthor()
+ {
+ if (!empty($this->localInfo['author'])) return $this->localInfo['author'];
+ if (!empty($this->remoteInfo['author'])) return $this->remoteInfo['author'];
+ return false;
+ }
+
+ /**
+ * Get the email of the author of the extension if there is any
+ *
+ * @return string|bool The email address or false if there is none
+ */
+ public function getEmail()
+ {
+ // email is only in the local data
+ if (!empty($this->localInfo['email'])) return $this->localInfo['email'];
+ return false;
+ }
+
+ /**
+ * Get the email id, i.e. the md5sum of the email
+ *
+ * @return string|bool The md5sum of the email if there is any, false otherwise
+ */
+ public function getEmailID()
+ {
+ if (!empty($this->remoteInfo['emailid'])) return $this->remoteInfo['emailid'];
+ if (!empty($this->localInfo['email'])) return md5($this->localInfo['email']);
+ return false;
+ }
+
+ /**
+ * Get the description of the extension
+ *
+ * @return string The description
+ */
+ public function getDescription()
+ {
+ if (!empty($this->localInfo['desc'])) return $this->localInfo['desc'];
+ if (!empty($this->remoteInfo['description'])) return $this->remoteInfo['description'];
+ return '';
+ }
+
+ /**
+ * Get the URL of the extension, usually a page on dokuwiki.org
+ *
+ * @return string The URL
+ */
+ public function getURL()
+ {
+ if (!empty($this->localInfo['url'])) return $this->localInfo['url'];
+ return 'https://www.dokuwiki.org/'.
+ ($this->isTemplate() ? 'template' : 'plugin').':'.$this->getBase();
+ }
+
+ /**
+ * Get the installed version of the extension
+ *
+ * @return string|bool The version, usually in the form yyyy-mm-dd if there is any
+ */
+ public function getInstalledVersion()
+ {
+ if (!empty($this->localInfo['date'])) return $this->localInfo['date'];
+ if ($this->isInstalled()) return $this->getLang('unknownversion');
+ return false;
+ }
+
+ /**
+ * Get the install date of the current version
+ *
+ * @return string|bool The date of the last update or false if not available
+ */
+ public function getUpdateDate()
+ {
+ if (!empty($this->managerData['updated'])) return $this->managerData['updated'];
+ return $this->getInstallDate();
+ }
+
+ /**
+ * Get the date of the installation of the plugin
+ *
+ * @return string|bool The date of the installation or false if not available
+ */
+ public function getInstallDate()
+ {
+ if (!empty($this->managerData['installed'])) return $this->managerData['installed'];
+ return false;
+ }
+
+ /**
+ * Get the names of the dependencies of this extension
+ *
+ * @return array The base names of the dependencies
+ */
+ public function getDependencies()
+ {
+ if (!empty($this->remoteInfo['dependencies'])) return $this->remoteInfo['dependencies'];
+ return array();
+ }
+
+ /**
+ * Get the names of the missing dependencies
+ *
+ * @return array The base names of the missing dependencies
+ */
+ public function getMissingDependencies()
+ {
+ /* @var PluginController $plugin_controller */
+ global $plugin_controller;
+ $dependencies = $this->getDependencies();
+ $missing_dependencies = array();
+ foreach ($dependencies as $dependency) {
+ if (!$plugin_controller->isEnabled($dependency)) {
+ $missing_dependencies[] = $dependency;
+ }
+ }
+ return $missing_dependencies;
+ }
+
+ /**
+ * Get the names of all conflicting extensions
+ *
+ * @return array The names of the conflicting extensions
+ */
+ public function getConflicts()
+ {
+ if (!empty($this->remoteInfo['conflicts'])) return $this->remoteInfo['conflicts'];
+ return array();
+ }
+
+ /**
+ * Get the names of similar extensions
+ *
+ * @return array The names of similar extensions
+ */
+ public function getSimilarExtensions()
+ {
+ if (!empty($this->remoteInfo['similar'])) return $this->remoteInfo['similar'];
+ return array();
+ }
+
+ /**
+ * Get the names of the tags of the extension
+ *
+ * @return array The names of the tags of the extension
+ */
+ public function getTags()
+ {
+ if (!empty($this->remoteInfo['tags'])) return $this->remoteInfo['tags'];
+ return array();
+ }
+
+ /**
+ * Get the popularity information as floating point number [0,1]
+ *
+ * @return float|bool The popularity information or false if it isn't available
+ */
+ public function getPopularity()
+ {
+ if (!empty($this->remoteInfo['popularity'])) return $this->remoteInfo['popularity'];
+ return false;
+ }
+
+
+ /**
+ * Get the text of the security warning if there is any
+ *
+ * @return string|bool The security warning if there is any, false otherwise
+ */
+ public function getSecurityWarning()
+ {
+ if (!empty($this->remoteInfo['securitywarning'])) return $this->remoteInfo['securitywarning'];
+ return false;
+ }
+
+ /**
+ * Get the text of the security issue if there is any
+ *
+ * @return string|bool The security issue if there is any, false otherwise
+ */
+ public function getSecurityIssue()
+ {
+ if (!empty($this->remoteInfo['securityissue'])) return $this->remoteInfo['securityissue'];
+ return false;
+ }
+
+ /**
+ * Get the URL of the screenshot of the extension if there is any
+ *
+ * @return string|bool The screenshot URL if there is any, false otherwise
+ */
+ public function getScreenshotURL()
+ {
+ if (!empty($this->remoteInfo['screenshoturl'])) return $this->remoteInfo['screenshoturl'];
+ return false;
+ }
+
+ /**
+ * Get the URL of the thumbnail of the extension if there is any
+ *
+ * @return string|bool The thumbnail URL if there is any, false otherwise
+ */
+ public function getThumbnailURL()
+ {
+ if (!empty($this->remoteInfo['thumbnailurl'])) return $this->remoteInfo['thumbnailurl'];
+ return false;
+ }
+ /**
+ * Get the last used download URL of the extension if there is any
+ *
+ * @return string|bool The previously used download URL, false if the extension has been installed manually
+ */
+ public function getLastDownloadURL()
+ {
+ if (!empty($this->managerData['downloadurl'])) return $this->managerData['downloadurl'];
+ return false;
+ }
+
+ /**
+ * Get the download URL of the extension if there is any
+ *
+ * @return string|bool The download URL if there is any, false otherwise
+ */
+ public function getDownloadURL()
+ {
+ if (!empty($this->remoteInfo['downloadurl'])) return $this->remoteInfo['downloadurl'];
+ return false;
+ }
+
+ /**
+ * If the download URL has changed since the last download
+ *
+ * @return bool If the download URL has changed
+ */
+ public function hasDownloadURLChanged()
+ {
+ $lasturl = $this->getLastDownloadURL();
+ $currenturl = $this->getDownloadURL();
+ return ($lasturl && $currenturl && $lasturl != $currenturl);
+ }
+
+ /**
+ * Get the bug tracker URL of the extension if there is any
+ *
+ * @return string|bool The bug tracker URL if there is any, false otherwise
+ */
+ public function getBugtrackerURL()
+ {
+ if (!empty($this->remoteInfo['bugtracker'])) return $this->remoteInfo['bugtracker'];
+ return false;
+ }
+
+ /**
+ * Get the URL of the source repository if there is any
+ *
+ * @return string|bool The URL of the source repository if there is any, false otherwise
+ */
+ public function getSourcerepoURL()
+ {
+ if (!empty($this->remoteInfo['sourcerepo'])) return $this->remoteInfo['sourcerepo'];
+ return false;
+ }
+
+ /**
+ * Get the donation URL of the extension if there is any
+ *
+ * @return string|bool The donation URL if there is any, false otherwise
+ */
+ public function getDonationURL()
+ {
+ if (!empty($this->remoteInfo['donationurl'])) return $this->remoteInfo['donationurl'];
+ return false;
+ }
+
+ /**
+ * Get the extension type(s)
+ *
+ * @return array The type(s) as array of strings
+ */
+ public function getTypes()
+ {
+ if (!empty($this->remoteInfo['types'])) return $this->remoteInfo['types'];
+ if ($this->isTemplate()) return array(32 => 'template');
+ return array();
+ }
+
+ /**
+ * Get a list of all DokuWiki versions this extension is compatible with
+ *
+ * @return array The versions in the form yyyy-mm-dd => ('label' => label, 'implicit' => implicit)
+ */
+ public function getCompatibleVersions()
+ {
+ if (!empty($this->remoteInfo['compatible'])) return $this->remoteInfo['compatible'];
+ return array();
+ }
+
+ /**
+ * Get the date of the last available update
+ *
+ * @return string|bool The last available update in the form yyyy-mm-dd if there is any, false otherwise
+ */
+ public function getLastUpdate()
+ {
+ if (!empty($this->remoteInfo['lastupdate'])) return $this->remoteInfo['lastupdate'];
+ return false;
+ }
+
+ /**
+ * Get the base path of the extension
+ *
+ * @return string The base path of the extension
+ */
+ public function getInstallDir()
+ {
+ if ($this->isTemplate()) {
+ return $this->tpllib.$this->base;
+ } else {
+ return DOKU_PLUGIN.$this->base;
+ }
+ }
+
+ /**
+ * The type of extension installation
+ *
+ * @return string One of "none", "manual", "git" or "automatic"
+ */
+ public function getInstallType()
+ {
+ if (!$this->isInstalled()) return 'none';
+ if (!empty($this->managerData)) return 'automatic';
+ if (is_dir($this->getInstallDir().'/.git')) return 'git';
+ return 'manual';
+ }
+
+ /**
+ * If the extension can probably be installed/updated or uninstalled
+ *
+ * @return bool|string True or error string
+ */
+ public function canModify()
+ {
+ if ($this->isInstalled()) {
+ if (!is_writable($this->getInstallDir())) {
+ return 'noperms';
+ }
+ }
+
+ if ($this->isTemplate() && !is_writable($this->tpllib)) {
+ return 'notplperms';
+ } elseif (!is_writable(DOKU_PLUGIN)) {
+ return 'nopluginperms';
+ }
+ return true;
+ }
+
+ /**
+ * Install an extension from a user upload
+ *
+ * @param string $field name of the upload file
+ * @param boolean $overwrite overwrite folder if the extension name is the same
+ * @throws Exception when something goes wrong
+ * @return array The list of installed extensions
+ */
+ public function installFromUpload($field, $overwrite = true)
+ {
+ if ($_FILES[$field]['error']) {
+ throw new Exception($this->getLang('msg_upload_failed').' ('.$_FILES[$field]['error'].')');
+ }
+
+ $tmp = $this->mkTmpDir();
+ if (!$tmp) throw new Exception($this->getLang('error_dircreate'));
+
+ // filename may contain the plugin name for old style plugins...
+ $basename = basename($_FILES[$field]['name']);
+ $basename = preg_replace('/\.(tar\.gz|tar\.bz|tar\.bz2|tar|tgz|tbz|zip)$/', '', $basename);
+ $basename = preg_replace('/[\W]+/', '', $basename);
+
+ if (!move_uploaded_file($_FILES[$field]['tmp_name'], "$tmp/upload.archive")) {
+ throw new Exception($this->getLang('msg_upload_failed'));
+ }
+
+ try {
+ $installed = $this->installArchive("$tmp/upload.archive", $overwrite, $basename);
+ $this->updateManagerData('', $installed);
+ $this->removeDeletedfiles($installed);
+ // purge cache
+ $this->purgeCache();
+ } catch (Exception $e) {
+ throw $e;
+ }
+ return $installed;
+ }
+
+ /**
+ * Install an extension from a remote URL
+ *
+ * @param string $url
+ * @param boolean $overwrite overwrite folder if the extension name is the same
+ * @throws Exception when something goes wrong
+ * @return array The list of installed extensions
+ */
+ public function installFromURL($url, $overwrite = true)
+ {
+ try {
+ $path = $this->download($url);
+ $installed = $this->installArchive($path, $overwrite);
+ $this->updateManagerData($url, $installed);
+ $this->removeDeletedfiles($installed);
+
+ // purge cache
+ $this->purgeCache();
+ } catch (Exception $e) {
+ throw $e;
+ }
+ return $installed;
+ }
+
+ /**
+ * Install or update the extension
+ *
+ * @throws \Exception when something goes wrong
+ * @return array The list of installed extensions
+ */
+ public function installOrUpdate()
+ {
+ $url = $this->getDownloadURL();
+ $path = $this->download($url);
+ $installed = $this->installArchive($path, $this->isInstalled(), $this->getBase());
+ $this->updateManagerData($url, $installed);
+
+ // refresh extension information
+ if (!isset($installed[$this->getID()])) {
+ throw new Exception('Error, the requested extension hasn\'t been installed or updated');
+ }
+ $this->removeDeletedfiles($installed);
+ $this->setExtension($this->getID());
+ $this->purgeCache();
+ return $installed;
+ }
+
+ /**
+ * Uninstall the extension
+ *
+ * @return bool If the plugin was sucessfully uninstalled
+ */
+ public function uninstall()
+ {
+ $this->purgeCache();
+ return io_rmdir($this->getInstallDir(), true);
+ }
+
+ /**
+ * Enable the extension
+ *
+ * @return bool|string True or an error message
+ */
+ public function enable()
+ {
+ if ($this->isTemplate()) return $this->getLang('notimplemented');
+ if (!$this->isInstalled()) return $this->getLang('notinstalled');
+ if ($this->isEnabled()) return $this->getLang('alreadyenabled');
+
+ /* @var PluginController $plugin_controller */
+ global $plugin_controller;
+ if ($plugin_controller->enable($this->base)) {
+ $this->purgeCache();
+ return true;
+ } else {
+ return $this->getLang('pluginlistsaveerror');
+ }
+ }
+
+ /**
+ * Disable the extension
+ *
+ * @return bool|string True or an error message
+ */
+ public function disable()
+ {
+ if ($this->isTemplate()) return $this->getLang('notimplemented');
+
+ /* @var PluginController $plugin_controller */
+ global $plugin_controller;
+ if (!$this->isInstalled()) return $this->getLang('notinstalled');
+ if (!$this->isEnabled()) return $this->getLang('alreadydisabled');
+ if ($plugin_controller->disable($this->base)) {
+ $this->purgeCache();
+ return true;
+ } else {
+ return $this->getLang('pluginlistsaveerror');
+ }
+ }
+
+ /**
+ * Purge the cache by touching the main configuration file
+ */
+ protected function purgeCache()
+ {
+ global $config_cascade;
+
+ // expire dokuwiki caches
+ // touching local.php expires wiki page, JS and CSS caches
+ @touch(reset($config_cascade['main']['local']));
+ }
+
+ /**
+ * Read local extension data either from info.txt or getInfo()
+ */
+ protected function readLocalData()
+ {
+ if ($this->isTemplate()) {
+ $infopath = $this->getInstallDir().'/template.info.txt';
+ } else {
+ $infopath = $this->getInstallDir().'/plugin.info.txt';
+ }
+
+ if (is_readable($infopath)) {
+ $this->localInfo = confToHash($infopath);
+ } elseif (!$this->isTemplate() && $this->isEnabled()) {
+ $path = $this->getInstallDir().'/';
+ $plugin = null;
+
+ foreach (PluginController::PLUGIN_TYPES as $type) {
+ if (file_exists($path.$type.'.php')) {
+ $plugin = plugin_load($type, $this->base);
+ if ($plugin) break;
+ }
+
+ if ($dh = @opendir($path.$type.'/')) {
+ while (false !== ($cp = readdir($dh))) {
+ if ($cp == '.' || $cp == '..' || strtolower(substr($cp, -4)) != '.php') continue;
+
+ $plugin = plugin_load($type, $this->base.'_'.substr($cp, 0, -4));
+ if ($plugin) break;
+ }
+ if ($plugin) break;
+ closedir($dh);
+ }
+ }
+
+ if ($plugin) {
+ /* @var DokuWiki_Plugin $plugin */
+ $this->localInfo = $plugin->getInfo();
+ }
+ }
+ }
+
+ /**
+ * Save the given URL and current datetime in the manager.dat file of all installed extensions
+ *
+ * @param string $url Where the extension was downloaded from. (empty for manual installs via upload)
+ * @param array $installed Optional list of installed plugins
+ */
+ protected function updateManagerData($url = '', $installed = null)
+ {
+ $origID = $this->getID();
+
+ if (is_null($installed)) {
+ $installed = array($origID);
+ }
+
+ foreach ($installed as $ext => $info) {
+ if ($this->getID() != $ext) $this->setExtension($ext);
+ if ($url) {
+ $this->managerData['downloadurl'] = $url;
+ } elseif (isset($this->managerData['downloadurl'])) {
+ unset($this->managerData['downloadurl']);
+ }
+ if (isset($this->managerData['installed'])) {
+ $this->managerData['updated'] = date('r');
+ } else {
+ $this->managerData['installed'] = date('r');
+ }
+ $this->writeManagerData();
+ }
+
+ if ($this->getID() != $origID) $this->setExtension($origID);
+ }
+
+ /**
+ * Read the manager.dat file
+ */
+ protected function readManagerData()
+ {
+ $managerpath = $this->getInstallDir().'/manager.dat';
+ if (is_readable($managerpath)) {
+ $file = @file($managerpath);
+ if (!empty($file)) {
+ foreach ($file as $line) {
+ list($key, $value) = explode('=', trim($line, DOKU_LF), 2);
+ $key = trim($key);
+ $value = trim($value);
+ // backwards compatible with old plugin manager
+ if ($key == 'url') $key = 'downloadurl';
+ $this->managerData[$key] = $value;
+ }
+ }
+ }
+ }
+
+ /**
+ * Write the manager.data file
+ */
+ protected function writeManagerData()
+ {
+ $managerpath = $this->getInstallDir().'/manager.dat';
+ $data = '';
+ foreach ($this->managerData as $k => $v) {
+ $data .= $k.'='.$v.DOKU_LF;
+ }
+ io_saveFile($managerpath, $data);
+ }
+
+ /**
+ * Returns a temporary directory
+ *
+ * The directory is registered for cleanup when the class is destroyed
+ *
+ * @return false|string
+ */
+ protected function mkTmpDir()
+ {
+ $dir = io_mktmpdir();
+ if (!$dir) return false;
+ $this->temporary[] = $dir;
+ return $dir;
+ }
+
+ /**
+ * downloads a file from the net and saves it
+ *
+ * - $file is the directory where the file should be saved
+ * - if successful will return the name used for the saved file, false otherwise
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ *
+ * @param string $url url to download
+ * @param string $file path to file or directory where to save
+ * @param string $defaultName fallback for name of download
+ * @return bool|string if failed false, otherwise true or the name of the file in the given dir
+ */
+ protected function downloadToFile($url, $file, $defaultName = '')
+ {
+ global $conf;
+ $http = new DokuHTTPClient();
+ $http->max_bodysize = 0;
+ $http->timeout = 25; //max. 25 sec
+ $http->keep_alive = false; // we do single ops here, no need for keep-alive
+ $http->agent = 'DokuWiki HTTP Client (Extension Manager)';
+
+ $data = $http->get($url);
+ if ($data === false) return false;
+
+ $name = '';
+ if (isset($http->resp_headers['content-disposition'])) {
+ $content_disposition = $http->resp_headers['content-disposition'];
+ $match = array();
+ if (is_string($content_disposition) &&
+ preg_match('/attachment;\s*filename\s*=\s*"([^"]*)"/i', $content_disposition, $match)
+ ) {
+ $name = \dokuwiki\Utf8\PhpString::basename($match[1]);
+ }
+
+ }
+
+ if (!$name) {
+ if (!$defaultName) return false;
+ $name = $defaultName;
+ }
+
+ $file = $file.$name;
+
+ $fileexists = file_exists($file);
+ $fp = @fopen($file,"w");
+ if (!$fp) return false;
+ fwrite($fp, $data);
+ fclose($fp);
+ if (!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']);
+ return $name;
+ }
+
+ /**
+ * Download an archive to a protected path
+ *
+ * @param string $url The url to get the archive from
+ * @throws Exception when something goes wrong
+ * @return string The path where the archive was saved
+ */
+ public function download($url)
+ {
+ // check the url
+ if (!preg_match('/https?:\/\//i', $url)) {
+ throw new Exception($this->getLang('error_badurl'));
+ }
+
+ // try to get the file from the path (used as plugin name fallback)
+ $file = parse_url($url, PHP_URL_PATH);
+ if (is_null($file)) {
+ $file = md5($url);
+ } else {
+ $file = \dokuwiki\Utf8\PhpString::basename($file);
+ }
+
+ // create tmp directory for download
+ if (!($tmp = $this->mkTmpDir())) {
+ throw new Exception($this->getLang('error_dircreate'));
+ }
+
+ // download
+ if (!$file = $this->downloadToFile($url, $tmp.'/', $file)) {
+ io_rmdir($tmp, true);
+ throw new Exception(sprintf($this->getLang('error_download'),
+ '<bdi>'.hsc($url).'</bdi>')
+ );
+ }
+
+ return $tmp.'/'.$file;
+ }
+
+ /**
+ * @param string $file The path to the archive that shall be installed
+ * @param bool $overwrite If an already installed plugin should be overwritten
+ * @param string $base The basename of the plugin if it's known
+ * @throws Exception when something went wrong
+ * @return array list of installed extensions
+ */
+ public function installArchive($file, $overwrite = false, $base = '')
+ {
+ $installed_extensions = array();
+
+ // create tmp directory for decompression
+ if (!($tmp = $this->mkTmpDir())) {
+ throw new Exception($this->getLang('error_dircreate'));
+ }
+
+ // add default base folder if specified to handle case where zip doesn't contain this
+ if ($base && !@mkdir($tmp.'/'.$base)) {
+ throw new Exception($this->getLang('error_dircreate'));
+ }
+
+ // decompress
+ $this->decompress($file, "$tmp/".$base);
+
+ // search $tmp/$base for the folder(s) that has been created
+ // move the folder(s) to lib/..
+ $result = array('old'=>array(), 'new'=>array());
+ $default = ($this->isTemplate() ? 'template' : 'plugin');
+ if (!$this->findFolders($result, $tmp.'/'.$base, $default)) {
+ throw new Exception($this->getLang('error_findfolder'));
+ }
+
+ // choose correct result array
+ if (count($result['new'])) {
+ $install = $result['new'];
+ } else {
+ $install = $result['old'];
+ }
+
+ if (!count($install)) {
+ throw new Exception($this->getLang('error_findfolder'));
+ }
+
+ // now install all found items
+ foreach ($install as $item) {
+ // where to install?
+ if ($item['type'] == 'template') {
+ $target_base_dir = $this->tpllib;
+ } else {
+ $target_base_dir = DOKU_PLUGIN;
+ }
+
+ if (!empty($item['base'])) {
+ // use base set in info.txt
+ } elseif ($base && count($install) == 1) {
+ $item['base'] = $base;
+ } else {
+ // default - use directory as found in zip
+ // plugins from github/master without *.info.txt will install in wrong folder
+ // but using $info->id will make 'code3' fail (which should install in lib/code/..)
+ $item['base'] = basename($item['tmp']);
+ }
+
+ // check to make sure we aren't overwriting anything
+ $target = $target_base_dir.$item['base'];
+ if (!$overwrite && file_exists($target)) {
+ // this info message is not being exposed via exception,
+ // so that it's not interrupting the installation
+ msg(sprintf($this->getLang('msg_nooverwrite'), $item['base']));
+ continue;
+ }
+
+ $action = file_exists($target) ? 'update' : 'install';
+
+ // copy action
+ if ($this->dircopy($item['tmp'], $target)) {
+ // return info
+ $id = $item['base'];
+ if ($item['type'] == 'template') {
+ $id = 'template:'.$id;
+ }
+ $installed_extensions[$id] = array(
+ 'base' => $item['base'],
+ 'type' => $item['type'],
+ 'action' => $action
+ );
+ } else {
+ throw new Exception(sprintf($this->getLang('error_copy').DOKU_LF,
+ '<bdi>'.$item['base'].'</bdi>')
+ );
+ }
+ }
+
+ // cleanup
+ if ($tmp) io_rmdir($tmp, true);
+
+ return $installed_extensions;
+ }
+
+ /**
+ * Find out what was in the extracted directory
+ *
+ * Correct folders are searched recursively using the "*.info.txt" configs
+ * as indicator for a root folder. When such a file is found, it's base
+ * setting is used (when set). All folders found by this method are stored
+ * in the 'new' key of the $result array.
+ *
+ * For backwards compatibility all found top level folders are stored as
+ * in the 'old' key of the $result array.
+ *
+ * When no items are found in 'new' the copy mechanism should fall back
+ * the 'old' list.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param array $result - results are stored here
+ * @param string $directory - the temp directory where the package was unpacked to
+ * @param string $default_type - type used if no info.txt available
+ * @param string $subdir - a subdirectory. do not set. used by recursion
+ * @return bool - false on error
+ */
+ protected function findFolders(&$result, $directory, $default_type = 'plugin', $subdir = '')
+ {
+ $this_dir = "$directory$subdir";
+ $dh = @opendir($this_dir);
+ if (!$dh) return false;
+
+ $found_dirs = array();
+ $found_files = 0;
+ $found_template_parts = 0;
+ while (false !== ($f = readdir($dh))) {
+ if ($f == '.' || $f == '..') continue;
+
+ if (is_dir("$this_dir/$f")) {
+ $found_dirs[] = "$subdir/$f";
+ } else {
+ // it's a file -> check for config
+ $found_files++;
+ switch ($f) {
+ case 'plugin.info.txt':
+ case 'template.info.txt':
+ // we have found a clear marker, save and return
+ $info = array();
+ $type = explode('.', $f, 2);
+ $info['type'] = $type[0];
+ $info['tmp'] = $this_dir;
+ $conf = confToHash("$this_dir/$f");
+ $info['base'] = basename($conf['base']);
+ $result['new'][] = $info;
+ return true;
+
+ case 'main.php':
+ case 'details.php':
+ case 'mediamanager.php':
+ case 'style.ini':
+ $found_template_parts++;
+ break;
+ }
+ }
+ }
+ closedir($dh);
+
+ // files where found but no info.txt - use old method
+ if ($found_files) {
+ $info = array();
+ $info['tmp'] = $this_dir;
+ // does this look like a template or should we use the default type?
+ if ($found_template_parts >= 2) {
+ $info['type'] = 'template';
+ } else {
+ $info['type'] = $default_type;
+ }
+
+ $result['old'][] = $info;
+ return true;
+ }
+
+ // we have no files yet -> recurse
+ foreach ($found_dirs as $found_dir) {
+ $this->findFolders($result, $directory, $default_type, "$found_dir");
+ }
+ return true;
+ }
+
+ /**
+ * Decompress a given file to the given target directory
+ *
+ * Determines the compression type from the file extension
+ *
+ * @param string $file archive to extract
+ * @param string $target directory to extract to
+ * @throws Exception
+ * @return bool
+ */
+ private function decompress($file, $target)
+ {
+ // decompression library doesn't like target folders ending in "/"
+ if (substr($target, -1) == "/") $target = substr($target, 0, -1);
+
+ $ext = $this->guessArchiveType($file);
+ if (in_array($ext, array('tar', 'bz', 'gz'))) {
+ try {
+ $tar = new \splitbrain\PHPArchive\Tar();
+ $tar->open($file);
+ $tar->extract($target);
+ } catch (\splitbrain\PHPArchive\ArchiveIOException $e) {
+ throw new Exception($this->getLang('error_decompress').' '.$e->getMessage());
+ }
+
+ return true;
+ } elseif ($ext == 'zip') {
+ try {
+ $zip = new \splitbrain\PHPArchive\Zip();
+ $zip->open($file);
+ $zip->extract($target);
+ } catch (\splitbrain\PHPArchive\ArchiveIOException $e) {
+ throw new Exception($this->getLang('error_decompress').' '.$e->getMessage());
+ }
+
+ return true;
+ }
+
+ // the only case when we don't get one of the recognized archive types is
+ // when the archive file can't be read
+ throw new Exception($this->getLang('error_decompress').' Couldn\'t read archive file');
+ }
+
+ /**
+ * Determine the archive type of the given file
+ *
+ * Reads the first magic bytes of the given file for content type guessing,
+ * if neither bz, gz or zip are recognized, tar is assumed.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param string $file The file to analyze
+ * @return string|false false if the file can't be read, otherwise an "extension"
+ */
+ private function guessArchiveType($file)
+ {
+ $fh = fopen($file, 'rb');
+ if (!$fh) return false;
+ $magic = fread($fh, 5);
+ fclose($fh);
+
+ if (strpos($magic, "\x42\x5a") === 0) return 'bz';
+ if (strpos($magic, "\x1f\x8b") === 0) return 'gz';
+ if (strpos($magic, "\x50\x4b\x03\x04") === 0) return 'zip';
+ return 'tar';
+ }
+
+ /**
+ * Copy with recursive sub-directory support
+ *
+ * @param string $src filename path to file
+ * @param string $dst filename path to file
+ * @return bool|int|string
+ */
+ private function dircopy($src, $dst)
+ {
+ global $conf;
+
+ if (is_dir($src)) {
+ if (!$dh = @opendir($src)) return false;
+
+ if ($ok = io_mkdir_p($dst)) {
+ while ($ok && (false !== ($f = readdir($dh)))) {
+ if ($f == '..' || $f == '.') continue;
+ $ok = $this->dircopy("$src/$f", "$dst/$f");
+ }
+ }
+
+ closedir($dh);
+ return $ok;
+ } else {
+ $existed = file_exists($dst);
+
+ if (!@copy($src, $dst)) return false;
+ if (!$existed && $conf['fperm']) chmod($dst, $conf['fperm']);
+ @touch($dst, filemtime($src));
+ }
+
+ return true;
+ }
+
+ /**
+ * Delete outdated files from updated plugins
+ *
+ * @param array $installed
+ */
+ private function removeDeletedfiles($installed)
+ {
+ foreach ($installed as $id => $extension) {
+ // only on update
+ if ($extension['action'] == 'install') continue;
+
+ // get definition file
+ if ($extension['type'] == 'template') {
+ $extensiondir = $this->tpllib;
+ } else {
+ $extensiondir = DOKU_PLUGIN;
+ }
+ $extensiondir = $extensiondir . $extension['base'] .'/';
+ $definitionfile = $extensiondir . 'deleted.files';
+ if (!file_exists($definitionfile)) continue;
+
+ // delete the old files
+ $list = file($definitionfile);
+
+ foreach ($list as $line) {
+ $line = trim(preg_replace('/#.*$/', '', $line));
+ if (!$line) continue;
+ $file = $extensiondir . $line;
+ if (!file_exists($file)) continue;
+
+ io_rmdir($file, true);
+ }
+ }
+ }
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/extension/helper/gui.php b/platform/www/lib/plugins/extension/helper/gui.php
new file mode 100644
index 0000000..919eb2c
--- /dev/null
+++ b/platform/www/lib/plugins/extension/helper/gui.php
@@ -0,0 +1,237 @@
+<?php
+/**
+ * DokuWiki Plugin extension (Helper Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+use dokuwiki\Form\Form;
+
+/**
+ * Class helper_plugin_extension_list takes care of the overall GUI
+ */
+class helper_plugin_extension_gui extends DokuWiki_Plugin
+{
+ protected $tabs = array('plugins', 'templates', 'search', 'install');
+
+ /** @var string the extension that should have an open info window FIXME currently broken */
+ protected $infoFor = '';
+
+ /**
+ * Constructor
+ *
+ * initializes requested info window
+ */
+ public function __construct()
+ {
+ global $INPUT;
+ $this->infoFor = $INPUT->str('info');
+ }
+
+ /**
+ * display the plugin tab
+ */
+ public function tabPlugins()
+ {
+ echo '<div class="panelHeader">';
+ echo $this->locale_xhtml('intro_plugins');
+ echo '</div>';
+
+ $pluginlist = plugin_list('', true);
+ /* @var helper_plugin_extension_extension $extension */
+ $extension = $this->loadHelper('extension_extension');
+ /* @var helper_plugin_extension_list $list */
+ $list = $this->loadHelper('extension_list');
+
+ $form = new Form([
+ 'action' => $this->tabURL('', [], '&'),
+ 'id' => 'extension__list',
+ ]);
+ $list->startForm();
+ foreach ($pluginlist as $name) {
+ $extension->setExtension($name);
+ $list->addRow($extension, $extension->getID() == $this->infoFor);
+ }
+ $list->endForm();
+ $form->addHTML($list->render(true));
+ echo $form->toHTML();
+ }
+
+ /**
+ * Display the template tab
+ */
+ public function tabTemplates()
+ {
+ echo '<div class="panelHeader">';
+ echo $this->locale_xhtml('intro_templates');
+ echo '</div>';
+
+ // FIXME do we have a real way?
+ $tpllist = glob(DOKU_INC.'lib/tpl/*', GLOB_ONLYDIR);
+ $tpllist = array_map('basename', $tpllist);
+ sort($tpllist);
+
+ /* @var helper_plugin_extension_extension $extension */
+ $extension = $this->loadHelper('extension_extension');
+ /* @var helper_plugin_extension_list $list */
+ $list = $this->loadHelper('extension_list');
+
+ $form = new Form([
+ 'action' => $this->tabURL('', [], '&'),
+ 'id' => 'extension__list',
+ ]);
+ $list->startForm();
+ foreach ($tpllist as $name) {
+ $extension->setExtension("template:$name");
+ $list->addRow($extension, $extension->getID() == $this->infoFor);
+ }
+ $list->endForm();
+ $form->addHTML($list->render(true));
+ echo $form->toHTML();
+ }
+
+ /**
+ * Display the search tab
+ */
+ public function tabSearch()
+ {
+ global $INPUT;
+ echo '<div class="panelHeader">';
+ echo $this->locale_xhtml('intro_search');
+ echo '</div>';
+
+ $form = new Form([
+ 'action' => $this->tabURL('', [], '&'),
+ 'class' => 'search',
+ ]);
+ $form->addTagOpen('div')->addClass('no');
+ $form->addTextInput('q', $this->getLang('search_for'))
+ ->addClass('edit')
+ ->val($INPUT->str('q'));
+ $form->addButton('submit', $this->getLang('search'))
+ ->attrs(['type' => 'submit', 'title' => $this->getLang('search')]);
+ $form->addTagClose('div');
+ echo $form->toHTML();
+
+ if (!$INPUT->bool('q')) return;
+
+ /* @var helper_plugin_extension_repository $repository FIXME should we use some gloabl instance? */
+ $repository = $this->loadHelper('extension_repository');
+ $result = $repository->search($INPUT->str('q'));
+
+ /* @var helper_plugin_extension_extension $extension */
+ $extension = $this->loadHelper('extension_extension');
+ /* @var helper_plugin_extension_list $list */
+ $list = $this->loadHelper('extension_list');
+
+ $form = new Form([
+ 'action' => $this->tabURL('', [], '&'),
+ 'id' => 'extension__list',
+ ]);
+ $list->startForm();
+ if ($result) {
+ foreach ($result as $name) {
+ $extension->setExtension($name);
+ $list->addRow($extension, $extension->getID() == $this->infoFor);
+ }
+ } else {
+ $list->nothingFound();
+ }
+ $list->endForm();
+ $form->addHTML($list->render(true));
+ echo $form->toHTML();
+ }
+
+ /**
+ * Display the template tab
+ */
+ public function tabInstall()
+ {
+ global $lang;
+ echo '<div class="panelHeader">';
+ echo $this->locale_xhtml('intro_install');
+ echo '</div>';
+
+ $form = new Form([
+ 'action' => $this->tabURL('', [], '&'),
+ 'enctype' => 'multipart/form-data',
+ 'class' => 'install',
+ ]);
+ $form->addTagOpen('div')->addClass('no');
+ $form->addTextInput('installurl', $this->getLang('install_url'))
+ ->addClass('block')
+ ->attrs(['type' => 'url']);
+ $form->addTag('br');
+ $form->addTextInput('installfile', $this->getLang('install_upload'))
+ ->addClass('block')
+ ->attrs(['type' => 'file']);
+ $form->addTag('br');
+ $form->addCheckbox('overwrite', $lang['js']['media_overwrt'])
+ ->addClass('block');
+ $form->addTag('br');
+ $form->addButton('', $this->getLang('btn_install'))
+ ->attrs(['type' => 'submit', 'title' => $this->getLang('btn_install')]);
+ $form->addTagClose('div');
+ echo $form->toHTML();
+ }
+
+ /**
+ * Print the tab navigation
+ *
+ * @fixme style active one
+ */
+ public function tabNavigation()
+ {
+ echo '<ul class="tabs">';
+ foreach ($this->tabs as $tab) {
+ $url = $this->tabURL($tab);
+ if ($this->currentTab() == $tab) {
+ $class = ' active';
+ } else {
+ $class = '';
+ }
+ echo '<li class="'.$tab.$class.'"><a href="'.$url.'">'.$this->getLang('tab_'.$tab).'</a></li>';
+ }
+ echo '</ul>';
+ }
+
+ /**
+ * Return the currently selected tab
+ *
+ * @return string
+ */
+ public function currentTab()
+ {
+ global $INPUT;
+
+ $tab = $INPUT->str('tab', 'plugins', true);
+ if (!in_array($tab, $this->tabs)) $tab = 'plugins';
+ return $tab;
+ }
+
+ /**
+ * Create an URL inside the extension manager
+ *
+ * @param string $tab tab to load, empty for current tab
+ * @param array $params associative array of parameter to set
+ * @param string $sep seperator to build the URL
+ * @param bool $absolute create absolute URLs?
+ * @return string
+ */
+ public function tabURL($tab = '', $params = [], $sep = '&', $absolute = false)
+ {
+ global $ID;
+ global $INPUT;
+
+ if (!$tab) $tab = $this->currentTab();
+ $defaults = array(
+ 'do' => 'admin',
+ 'page' => 'extension',
+ 'tab' => $tab,
+ );
+ if ($tab == 'search') $defaults['q'] = $INPUT->str('q');
+
+ return wl($ID, array_merge($defaults, $params), $absolute, $sep);
+ }
+}
diff --git a/platform/www/lib/plugins/extension/helper/list.php b/platform/www/lib/plugins/extension/helper/list.php
new file mode 100644
index 0000000..647575b
--- /dev/null
+++ b/platform/www/lib/plugins/extension/helper/list.php
@@ -0,0 +1,674 @@
+<?php
+/**
+ * DokuWiki Plugin extension (Helper Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Hamann <michael@content-space.de>
+ */
+
+/**
+ * Class helper_plugin_extension_list takes care of creating a HTML list of extensions
+ */
+class helper_plugin_extension_list extends DokuWiki_Plugin
+{
+ protected $form = '';
+ /** @var helper_plugin_extension_gui */
+ protected $gui;
+
+ /**
+ * Constructor
+ *
+ * loads additional helpers
+ */
+ public function __construct()
+ {
+ $this->gui = plugin_load('helper', 'extension_gui');
+ }
+
+ /**
+ * Initialize the extension table form
+ */
+ public function startForm()
+ {
+ $this->form .= '<ul class="extensionList">';
+ }
+
+ /**
+ * Build single row of extension table
+ *
+ * @param helper_plugin_extension_extension $extension The extension that shall be added
+ * @param bool $showinfo Show the info area
+ */
+ public function addRow(helper_plugin_extension_extension $extension, $showinfo = false)
+ {
+ $this->startRow($extension);
+ $this->populateColumn('legend', $this->makeLegend($extension, $showinfo));
+ $this->populateColumn('actions', $this->makeActions($extension));
+ $this->endRow();
+ }
+
+ /**
+ * Adds a header to the form
+ *
+ * @param string $id The id of the header
+ * @param string $header The content of the header
+ * @param int $level The level of the header
+ */
+ public function addHeader($id, $header, $level = 2)
+ {
+ $this->form .='<h'.$level.' id="'.$id.'">'.hsc($header).'</h'.$level.'>'.DOKU_LF;
+ }
+
+ /**
+ * Adds a paragraph to the form
+ *
+ * @param string $data The content
+ */
+ public function addParagraph($data)
+ {
+ $this->form .= '<p>'.hsc($data).'</p>'.DOKU_LF;
+ }
+
+ /**
+ * Add hidden fields to the form with the given data
+ *
+ * @param array $data key-value list of fields and their values to add
+ */
+ public function addHidden(array $data)
+ {
+ $this->form .= '<div class="no">';
+ foreach ($data as $key => $value) {
+ $this->form .= '<input type="hidden" name="'.hsc($key).'" value="'.hsc($value).'" />';
+ }
+ $this->form .= '</div>'.DOKU_LF;
+ }
+
+ /**
+ * Add closing tags
+ */
+ public function endForm()
+ {
+ $this->form .= '</ul>';
+ }
+
+ /**
+ * Show message when no results are found
+ */
+ public function nothingFound()
+ {
+ global $lang;
+ $this->form .= '<li class="notfound">'.$lang['nothingfound'].'</li>';
+ }
+
+ /**
+ * Print the form
+ *
+ * @param bool $returnonly whether to return html or print
+ */
+ public function render($returnonly = false)
+ {
+ if ($returnonly) return $this->form;
+ echo $this->form;
+ }
+
+ /**
+ * Start the HTML for the row for the extension
+ *
+ * @param helper_plugin_extension_extension $extension The extension
+ */
+ private function startRow(helper_plugin_extension_extension $extension)
+ {
+ $this->form .= '<li id="extensionplugin__'.hsc($extension->getID()).
+ '" class="'.$this->makeClass($extension).'">';
+ }
+
+ /**
+ * Add a column with the given class and content
+ * @param string $class The class name
+ * @param string $html The content
+ */
+ private function populateColumn($class, $html)
+ {
+ $this->form .= '<div class="'.$class.' col">'.$html.'</div>'.DOKU_LF;
+ }
+
+ /**
+ * End the row
+ */
+ private function endRow()
+ {
+ $this->form .= '</li>'.DOKU_LF;
+ }
+
+ /**
+ * Generate the link to the plugin homepage
+ *
+ * @param helper_plugin_extension_extension $extension The extension
+ * @return string The HTML code
+ */
+ public function makeHomepageLink(helper_plugin_extension_extension $extension)
+ {
+ global $conf;
+ $url = $extension->getURL();
+ if (strtolower(parse_url($url, PHP_URL_HOST)) == 'www.dokuwiki.org') {
+ $linktype = 'interwiki';
+ } else {
+ $linktype = 'extern';
+ }
+ $param = array(
+ 'href' => $url,
+ 'title' => $url,
+ 'class' => ($linktype == 'extern') ? 'urlextern' : 'interwiki iw_doku',
+ 'target' => $conf['target'][$linktype],
+ 'rel' => ($linktype == 'extern') ? 'noopener' : '',
+ );
+ if ($linktype == 'extern' && $conf['relnofollow']) {
+ $param['rel'] = implode(' ', [$param['rel'], 'ugc nofollow']);
+ }
+ $html = ' <a '. buildAttributes($param, true).'>'.
+ $this->getLang('homepage_link').'</a>';
+ return $html;
+ }
+
+ /**
+ * Generate the class name for the row of the extension
+ *
+ * @param helper_plugin_extension_extension $extension The extension object
+ * @return string The class name
+ */
+ public function makeClass(helper_plugin_extension_extension $extension)
+ {
+ $class = ($extension->isTemplate()) ? 'template' : 'plugin';
+ if ($extension->isInstalled()) {
+ $class.=' installed';
+ $class.= ($extension->isEnabled()) ? ' enabled':' disabled';
+ if ($extension->updateAvailable()) $class .= ' updatable';
+ }
+ if (!$extension->canModify()) $class.= ' notselect';
+ if ($extension->isProtected()) $class.= ' protected';
+ //if($this->showinfo) $class.= ' showinfo';
+ return $class;
+ }
+
+ /**
+ * Generate a link to the author of the extension
+ *
+ * @param helper_plugin_extension_extension $extension The extension object
+ * @return string The HTML code of the link
+ */
+ public function makeAuthor(helper_plugin_extension_extension $extension)
+ {
+ if ($extension->getAuthor()) {
+ $mailid = $extension->getEmailID();
+ if ($mailid) {
+ $url = $this->gui->tabURL('search', array('q' => 'authorid:'.$mailid));
+ $html = '<a href="'.$url.'" class="author" title="'.$this->getLang('author_hint').'" >'.
+ '<img src="//www.gravatar.com/avatar/'.$mailid.
+ '?s=20&amp;d=mm" width="20" height="20" alt="" /> '.
+ hsc($extension->getAuthor()).'</a>';
+ } else {
+ $html = '<span class="author">'.hsc($extension->getAuthor()).'</span>';
+ }
+ $html = '<bdi>'.$html.'</bdi>';
+ } else {
+ $html = '<em class="author">'.$this->getLang('unknown_author').'</em>'.DOKU_LF;
+ }
+ return $html;
+ }
+
+ /**
+ * Get the link and image tag for the screenshot/thumbnail
+ *
+ * @param helper_plugin_extension_extension $extension The extension object
+ * @return string The HTML code
+ */
+ public function makeScreenshot(helper_plugin_extension_extension $extension)
+ {
+ $screen = $extension->getScreenshotURL();
+ $thumb = $extension->getThumbnailURL();
+
+ if ($screen) {
+ // use protocol independent URLs for images coming from us #595
+ $screen = str_replace('http://www.dokuwiki.org', '//www.dokuwiki.org', $screen);
+ $thumb = str_replace('http://www.dokuwiki.org', '//www.dokuwiki.org', $thumb);
+
+ $title = sprintf($this->getLang('screenshot'), hsc($extension->getDisplayName()));
+ $img = '<a href="'.hsc($screen).'" target="_blank" class="extension_screenshot">'.
+ '<img alt="'.$title.'" width="120" height="70" src="'.hsc($thumb).'" />'.
+ '</a>';
+ } elseif ($extension->isTemplate()) {
+ $img = '<img alt="" width="120" height="70" src="'.DOKU_BASE.
+ 'lib/plugins/extension/images/template.png" />';
+ } else {
+ $img = '<img alt="" width="120" height="70" src="'.DOKU_BASE.
+ 'lib/plugins/extension/images/plugin.png" />';
+ }
+ $html = '<div class="screenshot" >'.$img.'<span></span></div>'.DOKU_LF;
+ return $html;
+ }
+
+ /**
+ * Extension main description
+ *
+ * @param helper_plugin_extension_extension $extension The extension object
+ * @param bool $showinfo Show the info section
+ * @return string The HTML code
+ */
+ public function makeLegend(helper_plugin_extension_extension $extension, $showinfo = false)
+ {
+ $html = '<div>';
+ $html .= '<h2>';
+ $html .= sprintf(
+ $this->getLang('extensionby'),
+ '<bdi>'.hsc($extension->getDisplayName()).'</bdi>',
+ $this->makeAuthor($extension)
+ );
+ $html .= '</h2>'.DOKU_LF;
+
+ $html .= $this->makeScreenshot($extension);
+
+ $popularity = $extension->getPopularity();
+ if ($popularity !== false && !$extension->isBundled()) {
+ $popularityText = sprintf($this->getLang('popularity'), round($popularity*100, 2));
+ $html .= '<div class="popularity" title="'.$popularityText.'">'.
+ '<div style="width: '.($popularity * 100).'%;">'.
+ '<span class="a11y">'.$popularityText.'</span>'.
+ '</div></div>'.DOKU_LF;
+ }
+
+ if ($extension->getDescription()) {
+ $html .= '<p><bdi>';
+ $html .= hsc($extension->getDescription()).' ';
+ $html .= '</bdi></p>'.DOKU_LF;
+ }
+
+ $html .= $this->makeLinkbar($extension);
+
+ if ($showinfo) {
+ $url = $this->gui->tabURL('');
+ $class = 'close';
+ } else {
+ $url = $this->gui->tabURL('', array('info' => $extension->getID()));
+ $class = '';
+ }
+ $html .= ' <a href="'.$url.'#extensionplugin__'.$extension->getID().
+ '" class="info '.$class.'" title="'.$this->getLang('btn_info').
+ '" data-extid="'.$extension->getID().'">'.$this->getLang('btn_info').'</a>';
+
+ if ($showinfo) {
+ $html .= $this->makeInfo($extension);
+ }
+ $html .= $this->makeNoticeArea($extension);
+ $html .= '</div>'.DOKU_LF;
+ return $html;
+ }
+
+ /**
+ * Generate the link bar HTML code
+ *
+ * @param helper_plugin_extension_extension $extension The extension instance
+ * @return string The HTML code
+ */
+ public function makeLinkbar(helper_plugin_extension_extension $extension)
+ {
+ global $conf;
+ $html = '<div class="linkbar">';
+ $html .= $this->makeHomepageLink($extension);
+
+ $bugtrackerURL = $extension->getBugtrackerURL();
+ if ($bugtrackerURL) {
+ if (strtolower(parse_url($bugtrackerURL, PHP_URL_HOST)) == 'www.dokuwiki.org') {
+ $linktype = 'interwiki';
+ } else {
+ $linktype = 'extern';
+ }
+ $param = array(
+ 'href' => $bugtrackerURL,
+ 'title' => $bugtrackerURL,
+ 'class' => 'bugs',
+ 'target' => $conf['target'][$linktype],
+ 'rel' => ($linktype == 'extern') ? 'noopener' : '',
+ );
+ if ($conf['relnofollow']) {
+ $param['rel'] = implode(' ', [$param['rel'], 'ugc nofollow']);
+ }
+ $html .= ' <a '.buildAttributes($param, true).'>'.
+ $this->getLang('bugs_features').'</a>';
+ }
+ if ($extension->getTags()) {
+ $first = true;
+ $html .= ' <span class="tags">'.$this->getLang('tags').' ';
+ foreach ($extension->getTags() as $tag) {
+ if (!$first) {
+ $html .= ', ';
+ } else {
+ $first = false;
+ }
+ $url = $this->gui->tabURL('search', ['q' => 'tag:'.$tag]);
+ $html .= '<bdi><a href="'.$url.'">'.hsc($tag).'</a></bdi>';
+ }
+ $html .= '</span>';
+ }
+ $html .= '</div>'.DOKU_LF;
+ return $html;
+ }
+
+ /**
+ * Notice area
+ *
+ * @param helper_plugin_extension_extension $extension The extension
+ * @return string The HTML code
+ */
+ public function makeNoticeArea(helper_plugin_extension_extension $extension)
+ {
+ $html = '';
+ $missing_dependencies = $extension->getMissingDependencies();
+ if (!empty($missing_dependencies)) {
+ $html .= '<div class="msg error">' .
+ sprintf(
+ $this->getLang('missing_dependency'),
+ '<bdi>' . implode(', ', $missing_dependencies) . '</bdi>'
+ ) .
+ '</div>';
+ }
+ if ($extension->isInWrongFolder()) {
+ $html .= '<div class="msg error">' .
+ sprintf(
+ $this->getLang('wrong_folder'),
+ '<bdi>' . hsc($extension->getInstallName()) . '</bdi>',
+ '<bdi>' . hsc($extension->getBase()) . '</bdi>'
+ ) .
+ '</div>';
+ }
+ if (($securityissue = $extension->getSecurityIssue()) !== false) {
+ $html .= '<div class="msg error">'.
+ sprintf($this->getLang('security_issue'), '<bdi>'.hsc($securityissue).'</bdi>').
+ '</div>';
+ }
+ if (($securitywarning = $extension->getSecurityWarning()) !== false) {
+ $html .= '<div class="msg notify">'.
+ sprintf($this->getLang('security_warning'), '<bdi>'.hsc($securitywarning).'</bdi>').
+ '</div>';
+ }
+ if ($extension->updateAvailable()) {
+ $html .= '<div class="msg notify">'.
+ sprintf($this->getLang('update_available'), hsc($extension->getLastUpdate())).
+ '</div>';
+ }
+ if ($extension->hasDownloadURLChanged()) {
+ $html .= '<div class="msg notify">' .
+ sprintf(
+ $this->getLang('url_change'),
+ '<bdi>' . hsc($extension->getDownloadURL()) . '</bdi>',
+ '<bdi>' . hsc($extension->getLastDownloadURL()) . '</bdi>'
+ ) .
+ '</div>';
+ }
+ return $html.DOKU_LF;
+ }
+
+ /**
+ * Create a link from the given URL
+ *
+ * Shortens the URL for display
+ *
+ * @param string $url
+ * @return string HTML link
+ */
+ public function shortlink($url)
+ {
+ $link = parse_url($url);
+
+ $base = $link['host'];
+ if (!empty($link['port'])) $base .= $base.':'.$link['port'];
+ $long = $link['path'];
+ if (!empty($link['query'])) $long .= $link['query'];
+
+ $name = shorten($base, $long, 55);
+
+ $html = '<a href="'.hsc($url).'" class="urlextern">'.hsc($name).'</a>';
+ return $html;
+ }
+
+ /**
+ * Plugin/template details
+ *
+ * @param helper_plugin_extension_extension $extension The extension
+ * @return string The HTML code
+ */
+ public function makeInfo(helper_plugin_extension_extension $extension)
+ {
+ $default = $this->getLang('unknown');
+ $html = '<dl class="details">';
+
+ $html .= '<dt>'.$this->getLang('status').'</dt>';
+ $html .= '<dd>'.$this->makeStatus($extension).'</dd>';
+
+ if ($extension->getDonationURL()) {
+ $html .= '<dt>'.$this->getLang('donate').'</dt>';
+ $html .= '<dd>';
+ $html .= '<a href="'.$extension->getDonationURL().'" class="donate">'.
+ $this->getLang('donate_action').'</a>';
+ $html .= '</dd>';
+ }
+
+ if (!$extension->isBundled()) {
+ $html .= '<dt>'.$this->getLang('downloadurl').'</dt>';
+ $html .= '<dd><bdi>';
+ $html .= ($extension->getDownloadURL()
+ ? $this->shortlink($extension->getDownloadURL())
+ : $default);
+ $html .= '</bdi></dd>';
+
+ $html .= '<dt>'.$this->getLang('repository').'</dt>';
+ $html .= '<dd><bdi>';
+ $html .= ($extension->getSourcerepoURL()
+ ? $this->shortlink($extension->getSourcerepoURL())
+ : $default);
+ $html .= '</bdi></dd>';
+ }
+
+ if ($extension->isInstalled()) {
+ if ($extension->getInstalledVersion()) {
+ $html .= '<dt>'.$this->getLang('installed_version').'</dt>';
+ $html .= '<dd>';
+ $html .= hsc($extension->getInstalledVersion());
+ $html .= '</dd>';
+ }
+ if (!$extension->isBundled()) {
+ $html .= '<dt>'.$this->getLang('install_date').'</dt>';
+ $html .= '<dd>';
+ $html .= ($extension->getUpdateDate()
+ ? hsc($extension->getUpdateDate())
+ : $this->getLang('unknown'));
+ $html .= '</dd>';
+ }
+ }
+ if (!$extension->isInstalled() || $extension->updateAvailable()) {
+ $html .= '<dt>'.$this->getLang('available_version').'</dt>';
+ $html .= '<dd>';
+ $html .= ($extension->getLastUpdate()
+ ? hsc($extension->getLastUpdate())
+ : $this->getLang('unknown'));
+ $html .= '</dd>';
+ }
+
+ $html .= '<dt>'.$this->getLang('provides').'</dt>';
+ $html .= '<dd><bdi>';
+ $html .= ($extension->getTypes()
+ ? hsc(implode(', ', $extension->getTypes()))
+ : $default);
+ $html .= '</bdi></dd>';
+
+ if (!$extension->isBundled() && $extension->getCompatibleVersions()) {
+ $html .= '<dt>'.$this->getLang('compatible').'</dt>';
+ $html .= '<dd>';
+ foreach ($extension->getCompatibleVersions() as $date => $version) {
+ $html .= '<bdi>'.$version['label'].' ('.$date.')</bdi>, ';
+ }
+ $html = rtrim($html, ', ');
+ $html .= '</dd>';
+ }
+ if ($extension->getDependencies()) {
+ $html .= '<dt>'.$this->getLang('depends').'</dt>';
+ $html .= '<dd>';
+ $html .= $this->makeLinkList($extension->getDependencies());
+ $html .= '</dd>';
+ }
+
+ if ($extension->getSimilarExtensions()) {
+ $html .= '<dt>'.$this->getLang('similar').'</dt>';
+ $html .= '<dd>';
+ $html .= $this->makeLinkList($extension->getSimilarExtensions());
+ $html .= '</dd>';
+ }
+
+ if ($extension->getConflicts()) {
+ $html .= '<dt>'.$this->getLang('conflicts').'</dt>';
+ $html .= '<dd>';
+ $html .= $this->makeLinkList($extension->getConflicts());
+ $html .= '</dd>';
+ }
+ $html .= '</dl>'.DOKU_LF;
+ return $html;
+ }
+
+ /**
+ * Generate a list of links for extensions
+ *
+ * @param array $ext The extensions
+ * @return string The HTML code
+ */
+ public function makeLinkList($ext)
+ {
+ $html = '';
+ foreach ($ext as $link) {
+ $html .= '<bdi><a href="'.
+ $this->gui->tabURL('search', array('q'=>'ext:'.$link)).'">'.
+ hsc($link).'</a></bdi>, ';
+ }
+ return rtrim($html, ', ');
+ }
+
+ /**
+ * Display the action buttons if they are possible
+ *
+ * @param helper_plugin_extension_extension $extension The extension
+ * @return string The HTML code
+ */
+ public function makeActions(helper_plugin_extension_extension $extension)
+ {
+ global $conf;
+ $html = '';
+ $errors = '';
+
+ if ($extension->isInstalled()) {
+ if (($canmod = $extension->canModify()) === true) {
+ if (!$extension->isProtected()) {
+ $html .= $this->makeAction('uninstall', $extension);
+ }
+ if ($extension->getDownloadURL()) {
+ if ($extension->updateAvailable()) {
+ $html .= $this->makeAction('update', $extension);
+ } else {
+ $html .= $this->makeAction('reinstall', $extension);
+ }
+ }
+ } else {
+ $errors .= '<p class="permerror">'.$this->getLang($canmod).'</p>';
+ }
+
+ if (!$extension->isProtected() && !$extension->isTemplate()) { // no enable/disable for templates
+ if ($extension->isEnabled()) {
+ $html .= $this->makeAction('disable', $extension);
+ } else {
+ $html .= $this->makeAction('enable', $extension);
+ }
+ }
+
+ if ($extension->isGitControlled()) {
+ $errors .= '<p class="permerror">'.$this->getLang('git').'</p>';
+ }
+
+ if ($extension->isEnabled() &&
+ in_array('Auth', $extension->getTypes()) &&
+ $conf['authtype'] != $extension->getID()
+ ) {
+ $errors .= '<p class="permerror">'.$this->getLang('auth').'</p>';
+ }
+ } else {
+ if (($canmod = $extension->canModify()) === true) {
+ if ($extension->getDownloadURL()) {
+ $html .= $this->makeAction('install', $extension);
+ }
+ } else {
+ $errors .= '<div class="permerror">'.$this->getLang($canmod).'</div>';
+ }
+ }
+
+ if (!$extension->isInstalled() && $extension->getDownloadURL()) {
+ $html .= ' <span class="version">'.$this->getLang('available_version').' ';
+ $html .= ($extension->getLastUpdate()
+ ? hsc($extension->getLastUpdate())
+ : $this->getLang('unknown')).'</span>';
+ }
+
+ return $html.' '.$errors.DOKU_LF;
+ }
+
+ /**
+ * Display an action button for an extension
+ *
+ * @param string $action The action
+ * @param helper_plugin_extension_extension $extension The extension
+ * @return string The HTML code
+ */
+ public function makeAction($action, $extension)
+ {
+ $title = '';
+
+ switch ($action) {
+ case 'install':
+ case 'reinstall':
+ $title = 'title="'.hsc($extension->getDownloadURL()).'"';
+ break;
+ }
+
+ $classes = 'button '.$action;
+ $name = 'fn['.$action.']['.hsc($extension->getID()).']';
+
+ $html = '<button class="'.$classes.'" name="'.$name.'" type="submit" '.$title.'>'.
+ $this->getLang('btn_'.$action).'</button> ';
+ return $html;
+ }
+
+ /**
+ * Plugin/template status
+ *
+ * @param helper_plugin_extension_extension $extension The extension
+ * @return string The description of all relevant statusses
+ */
+ public function makeStatus(helper_plugin_extension_extension $extension)
+ {
+ $status = array();
+
+ if ($extension->isInstalled()) {
+ $status[] = $this->getLang('status_installed');
+ if ($extension->isProtected()) {
+ $status[] = $this->getLang('status_protected');
+ } else {
+ $status[] = $extension->isEnabled()
+ ? $this->getLang('status_enabled')
+ : $this->getLang('status_disabled');
+ }
+ } else {
+ $status[] = $this->getLang('status_not_installed');
+ }
+ if (!$extension->canModify()) $status[] = $this->getLang('status_unmodifiable');
+ if ($extension->isBundled()) $status[] = $this->getLang('status_bundled');
+ $status[] = $extension->isTemplate()
+ ? $this->getLang('status_template')
+ : $this->getLang('status_plugin');
+ return implode(', ', $status);
+ }
+}
diff --git a/platform/www/lib/plugins/extension/helper/repository.php b/platform/www/lib/plugins/extension/helper/repository.php
new file mode 100644
index 0000000..712baa0
--- /dev/null
+++ b/platform/www/lib/plugins/extension/helper/repository.php
@@ -0,0 +1,203 @@
+<?php
+/**
+ * DokuWiki Plugin extension (Helper Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Hamann <michael@content-space.de>
+ */
+
+use dokuwiki\Cache\Cache;
+use dokuwiki\HTTP\DokuHTTPClient;
+use dokuwiki\Extension\PluginController;
+
+/**
+ * Class helper_plugin_extension_repository provides access to the extension repository on dokuwiki.org
+ */
+class helper_plugin_extension_repository extends DokuWiki_Plugin
+{
+
+ const EXTENSION_REPOSITORY_API = 'http://www.dokuwiki.org/lib/plugins/pluginrepo/api.php';
+
+ private $loaded_extensions = array();
+ private $has_access = null;
+
+ /**
+ * Initialize the repository (cache), fetches data for all installed plugins
+ */
+ public function init()
+ {
+ /* @var PluginController $plugin_controller */
+ global $plugin_controller;
+ if ($this->hasAccess()) {
+ $list = $plugin_controller->getList('', true);
+ $request_data = array('fmt' => 'php');
+ $request_needed = false;
+ foreach ($list as $name) {
+ $cache = new Cache('##extension_manager##'.$name, '.repo');
+
+ if (!isset($this->loaded_extensions[$name]) &&
+ $this->hasAccess() &&
+ !$cache->useCache(array('age' => 3600 * 24))
+ ) {
+ $this->loaded_extensions[$name] = true;
+ $request_data['ext'][] = $name;
+ $request_needed = true;
+ }
+ }
+
+ if ($request_needed) {
+ $httpclient = new DokuHTTPClient();
+ $data = $httpclient->post(self::EXTENSION_REPOSITORY_API, $request_data);
+ if ($data !== false) {
+ $extensions = unserialize($data);
+ foreach ($extensions as $extension) {
+ $cache = new Cache('##extension_manager##'.$extension['plugin'], '.repo');
+ $cache->storeCache(serialize($extension));
+ }
+ } else {
+ $this->has_access = false;
+ }
+ }
+ }
+ }
+
+ /**
+ * If repository access is available
+ *
+ * @param bool $usecache use cached result if still valid
+ * @return bool If repository access is available
+ */
+ public function hasAccess($usecache = true) {
+ if ($this->has_access === null) {
+ $cache = new Cache('##extension_manager###hasAccess', '.repo');
+
+ if (!$cache->useCache(array('age' => 60*10, 'purge' => !$usecache))) {
+ $httpclient = new DokuHTTPClient();
+ $httpclient->timeout = 5;
+ $data = $httpclient->get(self::EXTENSION_REPOSITORY_API.'?cmd=ping');
+ if ($data !== false) {
+ $this->has_access = true;
+ $cache->storeCache(1);
+ } else {
+ $this->has_access = false;
+ $cache->storeCache(0);
+ }
+ } else {
+ $this->has_access = ($cache->retrieveCache(false) == 1);
+ }
+ }
+ return $this->has_access;
+ }
+
+ /**
+ * Get the remote data of an individual plugin or template
+ *
+ * @param string $name The plugin name to get the data for, template names need to be prefix by 'template:'
+ * @return array The data or null if nothing was found (possibly no repository access)
+ */
+ public function getData($name)
+ {
+ $cache = new Cache('##extension_manager##'.$name, '.repo');
+
+ if (!isset($this->loaded_extensions[$name]) &&
+ $this->hasAccess() &&
+ !$cache->useCache(array('age' => 3600 * 24))
+ ) {
+ $this->loaded_extensions[$name] = true;
+ $httpclient = new DokuHTTPClient();
+ $data = $httpclient->get(self::EXTENSION_REPOSITORY_API.'?fmt=php&ext[]='.urlencode($name));
+ if ($data !== false) {
+ $result = unserialize($data);
+ $cache->storeCache(serialize($result[0]));
+ return $result[0];
+ } else {
+ $this->has_access = false;
+ }
+ }
+ if (file_exists($cache->cache)) {
+ return unserialize($cache->retrieveCache(false));
+ }
+ return array();
+ }
+
+ /**
+ * Search for plugins or templates using the given query string
+ *
+ * @param string $q the query string
+ * @return array a list of matching extensions
+ */
+ public function search($q)
+ {
+ $query = $this->parseQuery($q);
+ $query['fmt'] = 'php';
+
+ $httpclient = new DokuHTTPClient();
+ $data = $httpclient->post(self::EXTENSION_REPOSITORY_API, $query);
+ if ($data === false) return array();
+ $result = unserialize($data);
+
+ $ids = array();
+
+ // store cache info for each extension
+ foreach ($result as $ext) {
+ $name = $ext['plugin'];
+ $cache = new Cache('##extension_manager##'.$name, '.repo');
+ $cache->storeCache(serialize($ext));
+ $ids[] = $name;
+ }
+
+ return $ids;
+ }
+
+ /**
+ * Parses special queries from the query string
+ *
+ * @param string $q
+ * @return array
+ */
+ protected function parseQuery($q)
+ {
+ $parameters = array(
+ 'tag' => array(),
+ 'mail' => array(),
+ 'type' => array(),
+ 'ext' => array()
+ );
+
+ // extract tags
+ if (preg_match_all('/(^|\s)(tag:([\S]+))/', $q, $matches, PREG_SET_ORDER)) {
+ foreach ($matches as $m) {
+ $q = str_replace($m[2], '', $q);
+ $parameters['tag'][] = $m[3];
+ }
+ }
+ // extract author ids
+ if (preg_match_all('/(^|\s)(authorid:([\S]+))/', $q, $matches, PREG_SET_ORDER)) {
+ foreach ($matches as $m) {
+ $q = str_replace($m[2], '', $q);
+ $parameters['mail'][] = $m[3];
+ }
+ }
+ // extract extensions
+ if (preg_match_all('/(^|\s)(ext:([\S]+))/', $q, $matches, PREG_SET_ORDER)) {
+ foreach ($matches as $m) {
+ $q = str_replace($m[2], '', $q);
+ $parameters['ext'][] = $m[3];
+ }
+ }
+ // extract types
+ if (preg_match_all('/(^|\s)(type:([\S]+))/', $q, $matches, PREG_SET_ORDER)) {
+ foreach ($matches as $m) {
+ $q = str_replace($m[2], '', $q);
+ $parameters['type'][] = $m[3];
+ }
+ }
+
+ // FIXME make integer from type value
+
+ $parameters['q'] = trim($q);
+ return $parameters;
+ }
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/extension/images/bug.gif b/platform/www/lib/plugins/extension/images/bug.gif
new file mode 100644
index 0000000..08c1ca1
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/bug.gif
Binary files differ
diff --git a/platform/www/lib/plugins/extension/images/disabled.png b/platform/www/lib/plugins/extension/images/disabled.png
new file mode 100644
index 0000000..9c18b04
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/disabled.png
Binary files differ
diff --git a/platform/www/lib/plugins/extension/images/donate.png b/platform/www/lib/plugins/extension/images/donate.png
new file mode 100644
index 0000000..a76dfaa
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/donate.png
Binary files differ
diff --git a/platform/www/lib/plugins/extension/images/down.png b/platform/www/lib/plugins/extension/images/down.png
new file mode 100644
index 0000000..8e399a9
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/down.png
Binary files differ
diff --git a/platform/www/lib/plugins/extension/images/enabled.png b/platform/www/lib/plugins/extension/images/enabled.png
new file mode 100644
index 0000000..edbbb5b
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/enabled.png
Binary files differ
diff --git a/platform/www/lib/plugins/extension/images/icons.xcf b/platform/www/lib/plugins/extension/images/icons.xcf
new file mode 100644
index 0000000..ab69b30
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/icons.xcf
Binary files differ
diff --git a/platform/www/lib/plugins/extension/images/license.txt b/platform/www/lib/plugins/extension/images/license.txt
new file mode 100644
index 0000000..44e176a
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/license.txt
@@ -0,0 +1,4 @@
+enabled.png - CC0, (c) Tanguy Ortolo
+disabled.png - public domain, (c) Tango Desktop Project http://commons.wikimedia.org/wiki/File:Dialog-information.svg
+plugin.png - public domain, (c) nicubunu, http://openclipart.org/detail/15093/blue-jigsaw-piece-07-by-nicubunu
+template.png - public domain, (c) mathec, http://openclipart.org/detail/166596/palette-by-mathec
diff --git a/platform/www/lib/plugins/extension/images/overlay.png b/platform/www/lib/plugins/extension/images/overlay.png
new file mode 100644
index 0000000..5414206
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/overlay.png
Binary files differ
diff --git a/platform/www/lib/plugins/extension/images/plugin.png b/platform/www/lib/plugins/extension/images/plugin.png
new file mode 100644
index 0000000..62424b2
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/plugin.png
Binary files differ
diff --git a/platform/www/lib/plugins/extension/images/tag.png b/platform/www/lib/plugins/extension/images/tag.png
new file mode 100644
index 0000000..1b1dd75
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/tag.png
Binary files differ
diff --git a/platform/www/lib/plugins/extension/images/template.png b/platform/www/lib/plugins/extension/images/template.png
new file mode 100644
index 0000000..67240d1
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/template.png
Binary files differ
diff --git a/platform/www/lib/plugins/extension/images/up.png b/platform/www/lib/plugins/extension/images/up.png
new file mode 100644
index 0000000..531b2dd
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/up.png
Binary files differ
diff --git a/platform/www/lib/plugins/extension/images/warning.png b/platform/www/lib/plugins/extension/images/warning.png
new file mode 100644
index 0000000..c1af79f
--- /dev/null
+++ b/platform/www/lib/plugins/extension/images/warning.png
Binary files differ
diff --git a/platform/www/lib/plugins/extension/lang/en/intro_install.txt b/platform/www/lib/plugins/extension/lang/en/intro_install.txt
new file mode 100644
index 0000000..a5d5ab0
--- /dev/null
+++ b/platform/www/lib/plugins/extension/lang/en/intro_install.txt
@@ -0,0 +1 @@
+Here you can manually install plugins and templates by either uploading them or providing a direct download URL.
diff --git a/platform/www/lib/plugins/extension/lang/en/intro_plugins.txt b/platform/www/lib/plugins/extension/lang/en/intro_plugins.txt
new file mode 100644
index 0000000..4e42efe
--- /dev/null
+++ b/platform/www/lib/plugins/extension/lang/en/intro_plugins.txt
@@ -0,0 +1 @@
+These are the plugins currently installed in your DokuWiki. You can enable or disable or even completely uninstall them here. Plugin updates are shown here as well, be sure to read the plugin's documentation before updating. \ No newline at end of file
diff --git a/platform/www/lib/plugins/extension/lang/en/intro_search.txt b/platform/www/lib/plugins/extension/lang/en/intro_search.txt
new file mode 100644
index 0000000..81aa431
--- /dev/null
+++ b/platform/www/lib/plugins/extension/lang/en/intro_search.txt
@@ -0,0 +1 @@
+This tab gives you access to all available 3rd party [[doku>plugins|plugins]] and [[doku>template|templates]] for DokuWiki. Please be aware that installing 3rd party code may pose a **security risk**, you may want to read about [[doku>security#plugin_security|plugin security]] first.
diff --git a/platform/www/lib/plugins/extension/lang/en/intro_templates.txt b/platform/www/lib/plugins/extension/lang/en/intro_templates.txt
new file mode 100644
index 0000000..012a749
--- /dev/null
+++ b/platform/www/lib/plugins/extension/lang/en/intro_templates.txt
@@ -0,0 +1 @@
+These are the templates currently installed in your DokuWiki. You can select the template to be used in the [[?do=admin&page=config|Configuration Manager]].
diff --git a/platform/www/lib/plugins/extension/lang/en/lang.php b/platform/www/lib/plugins/extension/lang/en/lang.php
new file mode 100644
index 0000000..f9753ae
--- /dev/null
+++ b/platform/www/lib/plugins/extension/lang/en/lang.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * English language file for extension plugin
+ *
+ * @author Michael Hamann <michael@content-space.de>
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ */
+
+$lang['menu'] = 'Extension Manager';
+
+$lang['tab_plugins'] = 'Installed Plugins';
+$lang['tab_templates'] = 'Installed Templates';
+$lang['tab_search'] = 'Search and Install';
+$lang['tab_install'] = 'Manual Install';
+
+$lang['notimplemented'] = 'This feature hasn\'t been implemented yet';
+$lang['notinstalled'] = 'This extension is not installed';
+$lang['alreadyenabled'] = 'This extension has already been enabled';
+$lang['alreadydisabled'] = 'This extension has already been disabled';
+$lang['pluginlistsaveerror'] = 'There was an error saving the plugin list';
+$lang['unknownauthor'] = 'Unknown author';
+$lang['unknownversion'] = 'Unknown version';
+
+$lang['btn_info'] = 'Show more info';
+$lang['btn_update'] = 'Update';
+$lang['btn_uninstall'] = 'Uninstall';
+$lang['btn_enable'] = 'Enable';
+$lang['btn_disable'] = 'Disable';
+$lang['btn_install'] = 'Install';
+$lang['btn_reinstall'] = 'Re-install';
+
+$lang['js']['reallydel'] = 'Really uninstall this extension?';
+
+$lang['search_for'] = 'Search Extension:';
+$lang['search'] = 'Search';
+
+$lang['extensionby'] = '<strong>%s</strong> by %s';
+$lang['screenshot'] = 'Screenshot of %s';
+$lang['popularity'] = 'Popularity: %s%%';
+$lang['homepage_link'] = 'Docs';
+$lang['bugs_features'] = 'Bugs';
+$lang['tags'] = 'Tags:';
+$lang['author_hint'] = 'Search extensions by this author';
+$lang['installed'] = 'Installed:';
+$lang['downloadurl'] = 'Download URL:';
+$lang['repository'] = 'Repository:';
+$lang['unknown'] = '<em>unknown</em>';
+$lang['installed_version'] = 'Installed version:';
+$lang['install_date'] = 'Your last update:';
+$lang['available_version'] = 'Available version:';
+$lang['compatible'] = 'Compatible with:';
+$lang['depends'] = 'Depends on:';
+$lang['similar'] = 'Similar to:';
+$lang['conflicts'] = 'Conflicts with:';
+$lang['donate'] = 'Like this?';
+$lang['donate_action'] = 'Buy the author a coffee!';
+$lang['repo_retry'] = 'Retry';
+$lang['provides'] = 'Provides:';
+$lang['status'] = 'Status:';
+$lang['status_installed'] = 'installed';
+$lang['status_not_installed'] = 'not installed';
+$lang['status_protected'] = 'protected';
+$lang['status_enabled'] = 'enabled';
+$lang['status_disabled'] = 'disabled';
+$lang['status_unmodifiable'] = 'unmodifiable';
+$lang['status_plugin'] = 'plugin';
+$lang['status_template'] = 'template';
+$lang['status_bundled'] = 'bundled';
+
+$lang['msg_enabled'] = 'Plugin %s enabled';
+$lang['msg_disabled'] = 'Plugin %s disabled';
+$lang['msg_delete_success'] = 'Extension %s uninstalled';
+$lang['msg_delete_failed'] = 'Uninstalling Extension %s failed';
+$lang['msg_template_install_success'] = 'Template %s installed successfully';
+$lang['msg_template_update_success'] = 'Template %s updated successfully';
+$lang['msg_plugin_install_success'] = 'Plugin %s installed successfully';
+$lang['msg_plugin_update_success'] = 'Plugin %s updated successfully';
+$lang['msg_upload_failed'] = 'Uploading the file failed';
+$lang['msg_nooverwrite'] = 'Extension %s already exists so it is not being overwritten; to overwrite, tick the overwrite option';
+
+$lang['missing_dependency'] = '<strong>Missing or disabled dependency:</strong> %s';
+$lang['security_issue'] = '<strong>Security Issue:</strong> %s';
+$lang['security_warning'] = '<strong>Security Warning:</strong> %s';
+$lang['update_available'] = '<strong>Update:</strong> New version %s is available.';
+$lang['wrong_folder'] = '<strong>Plugin installed incorrectly:</strong> Rename plugin directory "%s" to "%s".';
+$lang['url_change'] = '<strong>URL changed:</strong> Download URL has changed since last download. Check if the new URL is valid before updating the extension.<br />New: %s<br />Old: %s';
+
+$lang['error_badurl'] = 'URLs should start with http or https';
+$lang['error_dircreate'] = 'Unable to create temporary folder to receive download';
+$lang['error_download'] = 'Unable to download the file: %s';
+$lang['error_decompress'] = 'Unable to decompress the downloaded file. This maybe as a result of a bad download, in which case you should try again; or the compression format may be unknown, in which case you will need to download and install manually.';
+$lang['error_findfolder'] = 'Unable to identify extension directory, you need to download and install manually';
+$lang['error_copy'] = 'There was a file copy error while attempting to install files for directory <em>%s</em>: the disk could be full or file access permissions may be incorrect. This may have resulted in a partially installed plugin and leave your wiki installation unstable';
+
+$lang['noperms'] = 'Extension directory is not writable';
+$lang['notplperms'] = 'Template directory is not writable';
+$lang['nopluginperms'] = 'Plugin directory is not writable';
+$lang['git'] = 'This extension was installed via git, you may not want to update it here.';
+$lang['auth'] = 'This auth plugin is not enabled in configuration, consider disabling it.';
+
+$lang['install_url'] = 'Install from URL:';
+$lang['install_upload'] = 'Upload Extension:';
+
+$lang['repo_error'] = 'The plugin repository could not be contacted. Make sure your server is allowed to contact www.dokuwiki.org and check your proxy settings.';
+$lang['nossl'] = 'Your PHP seems to miss SSL support. Downloading will not work for many DokuWiki extensions.';
+
+$lang['js']['display_viewoptions'] = 'View Options:';
+$lang['js']['display_enabled'] = 'enabled';
+$lang['js']['display_disabled'] = 'disabled';
+$lang['js']['display_updatable'] = 'updatable';
diff --git a/platform/www/lib/plugins/extension/plugin.info.txt b/platform/www/lib/plugins/extension/plugin.info.txt
new file mode 100644
index 0000000..7ee84dc
--- /dev/null
+++ b/platform/www/lib/plugins/extension/plugin.info.txt
@@ -0,0 +1,7 @@
+base extension
+author Michael Hamann
+email michael@content-space.de
+date 2015-07-26
+name Extension Manager
+desc Allows managing and installing plugins and templates
+url https://www.dokuwiki.org/plugin:extension
diff --git a/platform/www/lib/plugins/extension/script.js b/platform/www/lib/plugins/extension/script.js
new file mode 100644
index 0000000..7c91580
--- /dev/null
+++ b/platform/www/lib/plugins/extension/script.js
@@ -0,0 +1,145 @@
+jQuery(function(){
+
+ var $extmgr = jQuery('#extension__manager');
+
+ /**
+ * Confirm uninstalling
+ */
+ $extmgr.find('button.uninstall').on('click', function(e){
+ if(!window.confirm(LANG.plugins.extension.reallydel)){
+ e.preventDefault();
+ return false;
+ }
+ return true;
+ });
+
+ /**
+ * very simple lightbox
+ * @link http://webdesign.tutsplus.com/tutorials/htmlcss-tutorials/super-simple-lightbox-with-css-and-jquery/
+ */
+ $extmgr.find('a.extension_screenshot').on('click', function(e) {
+ e.preventDefault();
+
+ //Get clicked link href
+ var image_href = jQuery(this).attr("href");
+
+ // create lightbox if needed
+ var $lightbox = jQuery('#plugin__extensionlightbox');
+ if(!$lightbox.length){
+ $lightbox = jQuery('<div id="plugin__extensionlightbox"><p>Click to close</p><div></div></div>')
+ .appendTo(jQuery('body'))
+ .hide()
+ .on('click', function(){
+ $lightbox.hide();
+ });
+ }
+
+ // fill and show it
+ $lightbox
+ .show()
+ .find('div').html('<img src="' + image_href + '" />');
+
+
+ return false;
+ });
+
+ /**
+ * Enable/Disable extension via AJAX
+ */
+ $extmgr.find('button.disable, button.enable').on('click', function (e) {
+ e.preventDefault();
+ var $btn = jQuery(this);
+
+ // get current state
+ var extension = $btn.attr('name').split('[')[2];
+ extension = extension.substr(0, extension.length - 1);
+ var act = ($btn.hasClass('disable')) ? 'disable' : 'enable';
+
+ // disable while we wait
+ $btn.attr('disabled', 'disabled');
+ $btn.css('cursor', 'wait');
+
+ // execute
+ jQuery.get(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'plugin_extension',
+ ext: extension,
+ act: act
+ },
+ function (data) {
+ $btn.css('cursor', '')
+ .removeAttr('disabled')
+ .removeClass('disable')
+ .removeClass('enable')
+ .text(data.label)
+ .addClass(data.reverse)
+ .parents('li')
+ .removeClass('disabled')
+ .removeClass('enabled')
+ .addClass(data.state);
+ }
+ );
+ });
+
+ /**
+ * AJAX detail infos
+ */
+ $extmgr.find('a.info').on('click', function(e){
+ e.preventDefault();
+
+ var $link = jQuery(this);
+ var $details = $link.parent().find('dl.details');
+ if($details.length){
+ $link.toggleClass('close');
+ $details.toggle();
+ return;
+ }
+
+ $link.addClass('close');
+ jQuery.get(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'plugin_extension',
+ ext: $link.data('extid'),
+ act: 'info'
+ },
+ function(data){
+ $link.parent().append(data);
+ }
+ );
+ });
+
+ /**
+ Create section for enabling/disabling viewing options
+ */
+ if ( $extmgr.find('.plugins, .templates').hasClass('active') ) {
+ var $extlist = jQuery('#extension__list');
+ $extlist.addClass('hasDisplayOptions');
+
+ var $displayOpts = jQuery('<p>', { id: 'extension__viewoptions'} ).appendTo($extmgr.find( '.panelHeader' ));
+ $displayOpts.append(LANG.plugins.extension.display_viewoptions);
+
+ var displayOptionsHandler = function(){
+ $extlist.toggleClass( this.name );
+ DokuCookie.setValue('ext_'+this.name, $extlist.hasClass(this.name) ? '1' : '0');
+ };
+
+ jQuery(['enabled', 'disabled', 'updatable']).each(function(index, chkName){
+ var $label = jQuery( '<label></label>' )
+ .appendTo($displayOpts);
+ var $input = jQuery( '<input />', { type: 'checkbox', name: chkName })
+ .on('change', displayOptionsHandler)
+ .appendTo($label);
+
+ var previous = DokuCookie.getValue('ext_'+chkName);
+ if(typeof previous === "undefined" || previous == '1') {
+ $input.trigger('click');
+ }
+
+ jQuery( '<span/>' )
+ .append(' '+LANG.plugins.extension['display_'+chkName])
+ .appendTo($label);
+ });
+ }
+});
diff --git a/platform/www/lib/plugins/extension/style.less b/platform/www/lib/plugins/extension/style.less
new file mode 100644
index 0000000..261fa1c
--- /dev/null
+++ b/platform/www/lib/plugins/extension/style.less
@@ -0,0 +1,386 @@
+/*
+ * Extension plugin styles
+ *
+ * @author Christopher Smith <chris@jalakai.co.uk>
+ * @author Piyush Mishra <me@piyushmishra.com>
+ * @author HÃ¥kan Sandell <sandell.hakan@gmail.com>
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+
+/**
+ * very simple lightbox
+ * @link http://webdesign.tutsplus.com/tutorials/htmlcss-tutorials/super-simple-lightbox-with-css-and-jquery/
+ */
+#plugin__extensionlightbox {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: url(images/overlay.png) repeat;
+ text-align: center;
+ cursor: pointer;
+ z-index: 9999;
+
+ p {
+ text-align: right;
+ color: #fff;
+ margin-right: 20px;
+ font-size: 12px;
+ }
+
+ img {
+ box-shadow: 0 0 25px #111;
+ max-width: 90%;
+ max-height: 90%;
+ }
+}
+
+/**
+ * general styles
+ */
+#extension__manager {
+ // tab layout - most of it is in the main template
+ ul.tabs li.active a {
+ background-color: @ini_background_alt;
+ border-bottom: solid 1px @ini_background_alt;
+ z-index: 2;
+ }
+ .panelHeader {
+ background-color: @ini_background_alt;
+ margin: 0 0 10px 0;
+ padding: 10px 10px 8px;
+ overflow: hidden;
+ }
+
+ // message spacing
+ div.msg {
+ margin: 0.4em 0 0 0;
+ }
+}
+
+/*
+ * extensions table
+ */
+#extension__list {
+ ul.extensionList {
+ margin-left: 0;
+ margin-right: 0;
+ padding: 0;
+ list-style: none;
+ }
+
+ ul.extensionList li {
+ margin: 0 0 .5em;
+ padding: 0 0 .5em;
+ color: @ini_text;
+ border-bottom: 1px solid @ini_border;
+ overflow: hidden;
+ }
+
+ button {
+ margin-bottom: .3em;
+ }
+}
+
+/**
+ * extension table left column
+ */
+#extension__list .legend {
+ position: relative;
+ width: 75%;
+ float: left;
+
+ // padding
+ > div {
+ padding: 0 .5em 0 132px;
+ border-right: 1px solid @ini_background_alt;
+ overflow: hidden;
+ }
+
+ // screenshot
+ div.screenshot {
+ margin-top: 4px;
+ margin-left: -132px;
+ max-width: 120px;
+ float: left;
+ position: relative;
+
+ img {
+ width: 120px;
+ height: 70px;
+ border-radius: 5px;
+ box-shadow: 2px 2px 2px #666;
+ }
+
+ span {
+ min-height: 24px;
+ min-width: 24px;
+ position: absolute;
+ left: 0;
+ top: 0;
+ }
+ }
+
+ // plugin headline
+ h2 {
+ width: 100%;
+ float: right;
+ margin: 0.2em 0 0.5em;
+ font-size: 100%;
+ font-weight: normal;
+ border: none;
+
+ strong {
+ font-size: 120%;
+ font-weight: bold;
+ vertical-align: baseline;
+ }
+ }
+
+ // description
+ p {
+ margin: 0 0 0.6em 0;
+ }
+
+ // popularity bar
+ div.popularity {
+ background-color: @ini_background;
+ border: 1px solid silver;
+ height: .4em;
+ margin: 0 auto;
+ padding: 1px;
+ width: 5.5em;
+ position: absolute;
+ right: .5em;
+ top: 0.2em;
+
+ div {
+ background-color: @ini_border;
+ height: 100%;
+ }
+ }
+
+ // Docs, Bugs, Tags
+ div.linkbar {
+ font-size: 85%;
+
+ span.tags {
+ padding-left: 18px;
+ background: transparent url(images/tag.png) no-repeat 0 0;
+ }
+
+ a.bugs {
+ padding-left: 18px;
+ background: transparent url(images/bug.gif) no-repeat 0 0;
+ }
+ }
+
+ // more info button
+ a.info {
+ background: transparent url(images/down.png) no-repeat 0 0;
+ border-width: 0;
+ height: 13px;
+ width: 13px;
+ text-indent: -9999px;
+ float: right;
+ margin: .5em 0 0;
+ overflow: hidden;
+
+ &.close {
+ background: transparent url(images/up.png) no-repeat 0 0;
+ }
+ }
+
+ // detailed info box
+ dl.details {
+ margin: 0.4em 0 0 0;
+ font-size: 85%;
+ border-top: 1px solid @ini_background_alt;
+ clear: both;
+
+ dt {
+ clear: left;
+ float: left;
+ width: 25%;
+ margin: 0;
+ text-align: right;
+ font-weight: normal;
+ padding: 0.2em 5px 0 0;
+ font-weight: bold;
+ }
+
+ dd {
+ margin-left: 25%;
+ padding: 0.2em 0 0 5px;
+
+ a.donate {
+ padding-left: 18px;
+ background: transparent url(images/donate.png) left center no-repeat;
+ }
+ }
+ }
+}
+
+[dir=rtl] #extension__list .legend {
+ float: right;
+
+ > div {
+ padding: 0 132px 0 .5em;
+ border-left: 1px solid @ini_background_alt;
+ border-right-width: 0;
+ }
+
+ div.screenshot {
+ margin-left: 0;
+ margin-right: -132px;
+ float: right;
+
+ span {
+ left: auto;
+ right: 0;
+ }
+ }
+
+ h2 {
+ float: left;
+ }
+
+ div.popularity {
+ right: auto;
+ left: .5em;
+ }
+
+ div.linkbar span.tags,
+ dl.details dd a.donate {
+ padding-left: 0;
+ padding-right: 18px;
+ background-position: top right;
+ }
+
+ a.info {
+ float: left;
+ }
+
+ dl.details {
+ dt {
+ clear: right;
+ float: right;
+ text-align: left;
+ padding-left: 5px;
+ padding-right: 0;
+ }
+
+ dd {
+ margin-left: 0;
+ margin-right: 25%;
+ padding-left: 0;
+ padding-right: 5px;
+ }
+ }
+}
+
+/*
+ * Enabled/Disabled overrides
+ */
+#extension__list {
+
+ &.hasDisplayOptions {
+ .enabled,
+ .disabled,
+ .updatable {
+ display: none;
+ }
+
+ &.enabled .enabled,
+ &.disabled .disabled,
+ &.updatable .updatable {
+ display: block;
+ }
+ }
+
+ .enabled div.screenshot span {
+ background: transparent url(images/enabled.png) no-repeat 2px 2px;
+ }
+
+ .disabled div.screenshot span {
+ background: transparent url(images/disabled.png) no-repeat 2px 2px;
+ }
+
+ .disabled .legend {
+ opacity: 0.7;
+ }
+}
+
+/**
+ * extension table right column
+ */
+#extension__manager .actions {
+ padding: 0;
+ font-size: 95%;
+ width: 25%;
+ float: right;
+ text-align: right;
+
+ .version {
+ display: block;
+ }
+
+ p {
+ margin: 0.2em 0;
+ text-align: center;
+ }
+
+ p.permerror {
+ margin-left: 0.4em;
+ text-align: left;
+ padding-left: 19px;
+ background: transparent url(images/warning.png) center left no-repeat;
+ line-height: 18px;
+ font-size: 12px;
+ }
+}
+
+[dir=rtl] #extension__manager .actions {
+ float: left;
+ text-align: left;
+
+ p.permerror {
+ margin-left: 0;
+ margin-right: 0.4em;
+ text-align: right;
+ padding-left: 0;
+ padding-right: 19px;
+ background-position: center right;
+ }
+}
+
+/**
+ * Search form
+ */
+#extension__manager form.search {
+ display: block;
+ margin-bottom: 2em;
+
+ span {
+ font-weight: bold;
+ }
+
+ input.edit {
+ width: 25em;
+ }
+}
+
+/**
+ * Install form
+ */
+#extension__manager form.install {
+ text-align: center;
+ display: block;
+ width: 60%;
+}
+
+#extension__viewoptions label {
+ margin-left: 1em;
+ vertical-align: baseline;
+}
diff --git a/platform/www/lib/plugins/farmer/.github/auto-comment.yml b/platform/www/lib/plugins/farmer/.github/auto-comment.yml
new file mode 100644
index 0000000..f6a72e3
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/.github/auto-comment.yml
@@ -0,0 +1,9 @@
+# auto replies used by probot/auto-comment
+
+issuesOpened: >
+ Thank you for opening this issue.
+
+ [CosmoCode](https://www.cosmocode.de) is a software company in Berlin providing services for wiki, app and web development. As such we can't guarantee quick responses for issues opened on our Open Source projects.
+
+ If you require certain features or bugs fixed, you can always hire us. Feel free to contact us at dokuwiki@cosmocode.de for an offer.
+
diff --git a/platform/www/lib/plugins/farmer/.travis.yml b/platform/www/lib/plugins/farmer/.travis.yml
new file mode 100644
index 0000000..6814beb
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/.travis.yml
@@ -0,0 +1,15 @@
+# Config file for travis-ci.org
+
+language: php
+php:
+ - "7.3"
+ - "7.2"
+ - "7.1"
+ - "7.0"
+ - "5.6"
+env:
+ - DOKUWIKI=master
+ - DOKUWIKI=stable
+before_install: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh
+install: sh travis.sh
+script: cd _test && ./phpunit.phar --stderr --group plugin_farmer
diff --git a/platform/www/lib/plugins/farmer/3rdparty/PHPIco.php b/platform/www/lib/plugins/farmer/3rdparty/PHPIco.php
new file mode 100644
index 0000000..17b3b55
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/3rdparty/PHPIco.php
@@ -0,0 +1,248 @@
+<?php
+/*
+Copyright 2011-2013 Chris Jean & iThemes
+Licensed under GPLv2 or above
+
+Version 1.0.2
+
+Adjusted for DokuWiki Farmer Plugin
+*/
+
+namespace chrisbliss18\phpico;
+
+class PHPIco {
+ /**
+ * Images in the BMP format.
+ *
+ * @var array
+ * @access private
+ */
+ var $_images = array();
+
+ /**
+ * Constructor - Create a new ICO generator.
+ *
+ * If the constructor is not passed a file, a file will need to be supplied using the {@link PHP_ICO::add_image}
+ * function in order to generate an ICO file.
+ *
+ * @param bool|string $file Optional. Path to the source image file.
+ * @param array $sizes Optional. An array of sizes (each size is an array with a width and height) that the source image should be rendered at in the generated ICO file. If sizes are not supplied, the size of the source image will be used.
+ * @throws \Exception
+ */
+ function __construct( $file = false, $sizes = array() ) {
+ $required_functions = array(
+ 'getimagesize',
+ 'imagecreatefromstring',
+ 'imagecreatetruecolor',
+ 'imagecolortransparent',
+ 'imagecolorallocatealpha',
+ 'imagealphablending',
+ 'imagesavealpha',
+ 'imagesx',
+ 'imagesy',
+ 'imagecopyresampled',
+ );
+
+ foreach ( $required_functions as $function ) {
+ if ( ! function_exists( $function ) ) {
+ throw new \Exception( "The PHP_ICO class was unable to find the $function function, which is part of the GD library. Ensure that the system has the GD library installed and that PHP has access to it through a PHP interface, such as PHP's GD module. Since this function was not found, the library will be unable to create ICO files." );
+ }
+ }
+
+ if ( false != $file )
+ $this->add_image( $file, $sizes );
+ }
+
+ /**
+ * Add an image to the generator.
+ *
+ * This function adds a source image to the generator. It serves two main purposes: add a source image if one was
+ * not supplied to the constructor and to add additional source images so that different images can be supplied for
+ * different sized images in the resulting ICO file. For instance, a small source image can be used for the small
+ * resolutions while a larger source image can be used for large resolutions.
+ *
+ * @param string $file Path to the source image file.
+ * @param array $sizes Optional. An array of sizes (each size is an array with a width and height) that the source image should be rendered at in the generated ICO file. If sizes are not supplied, the size of the source image will be used.
+ * @return boolean true on success and false on failure.
+ */
+ function add_image( $file, $sizes = array() ) {
+ if ( false === ( $im = $this->_load_image_file( $file ) ) )
+ return false;
+
+
+ if ( empty( $sizes ) )
+ $sizes = array( imagesx( $im ), imagesy( $im ) );
+
+ // If just a single size was passed, put it in array.
+ if ( ! is_array( $sizes[0] ) )
+ $sizes = array( $sizes );
+
+ foreach ( (array) $sizes as $size ) {
+ list( $width, $height ) = $size;
+
+ $new_im = imagecreatetruecolor( $width, $height );
+
+ imagecolortransparent( $new_im, imagecolorallocatealpha( $new_im, 0, 0, 0, 127 ) );
+ imagealphablending( $new_im, false );
+ imagesavealpha( $new_im, true );
+
+ $source_width = imagesx( $im );
+ $source_height = imagesy( $im );
+
+ if ( false === imagecopyresampled( $new_im, $im, 0, 0, 0, 0, $width, $height, $source_width, $source_height ) )
+ continue;
+
+ $this->_add_image_data( $new_im );
+ }
+
+ return true;
+ }
+
+ /**
+ * Write the ICO file data to a file path.
+ *
+ * @param string $file Path to save the ICO file data into.
+ * @return boolean true on success and false on failure.
+ */
+ function save_ico( $file ) {
+ if ( false === ( $data = $this->_get_ico_data() ) )
+ return false;
+
+ if ( false === ( $fh = fopen( $file, 'w' ) ) )
+ return false;
+
+ if ( false === ( fwrite( $fh, $data ) ) ) {
+ fclose( $fh );
+ return false;
+ }
+
+ fclose( $fh );
+
+ return true;
+ }
+
+ /**
+ * Generate the final ICO data by creating a file header and adding the image data.
+ */
+ protected function _get_ico_data() {
+ if ( ! is_array( $this->_images ) || empty( $this->_images ) )
+ return false;
+
+
+ $data = pack( 'vvv', 0, 1, count( $this->_images ) );
+ $pixel_data = '';
+
+ $icon_dir_entry_size = 16;
+
+ $offset = 6 + ( $icon_dir_entry_size * count( $this->_images ) );
+
+ foreach ( $this->_images as $image ) {
+ $data .= pack( 'CCCCvvVV', $image['width'], $image['height'], $image['color_palette_colors'], 0, 1, $image['bits_per_pixel'], $image['size'], $offset );
+ $pixel_data .= $image['data'];
+
+ $offset += $image['size'];
+ }
+
+ $data .= $pixel_data;
+ unset( $pixel_data );
+
+
+ return $data;
+ }
+
+ /**
+ * Take a GD image resource and change it into a raw BMP format.
+ *
+ * @param resource $im
+ */
+ protected function _add_image_data( $im ) {
+ $width = imagesx( $im );
+ $height = imagesy( $im );
+
+
+ $pixel_data = array();
+
+ $opacity_data = array();
+ $current_opacity_val = 0;
+
+ for ( $y = $height - 1; $y >= 0; $y-- ) {
+ for ( $x = 0; $x < $width; $x++ ) {
+ $color = imagecolorat( $im, $x, $y );
+
+ $alpha = ( $color & 0x7F000000 ) >> 24;
+ $alpha = ( 1 - ( $alpha / 127 ) ) * 255;
+
+ $color &= 0xFFFFFF;
+ $color |= 0xFF000000 & ( $alpha << 24 );
+
+ $pixel_data[] = $color;
+
+
+ $opacity = ( $alpha <= 127 ) ? 1 : 0;
+
+ $current_opacity_val = ( $current_opacity_val << 1 ) | $opacity;
+
+ if ( ( ( $x + 1 ) % 32 ) == 0 ) {
+ $opacity_data[] = $current_opacity_val;
+ $current_opacity_val = 0;
+ }
+ }
+
+ if ( ( $x % 32 ) > 0 ) {
+ while ( ( $x++ % 32 ) > 0 )
+ $current_opacity_val = $current_opacity_val << 1;
+
+ $opacity_data[] = $current_opacity_val;
+ $current_opacity_val = 0;
+ }
+ }
+
+ $image_header_size = 40;
+ $color_mask_size = $width * $height * 4;
+ $opacity_mask_size = ( ceil( $width / 32 ) * 4 ) * $height;
+
+
+ $data = pack( 'VVVvvVVVVVV', 40, $width, ( $height * 2 ), 1, 32, 0, 0, 0, 0, 0, 0 );
+
+ foreach ( $pixel_data as $color )
+ $data .= pack( 'V', $color );
+
+ foreach ( $opacity_data as $opacity )
+ $data .= pack( 'N', $opacity );
+
+
+ $image = array(
+ 'width' => $width,
+ 'height' => $height,
+ 'color_palette_colors' => 0,
+ 'bits_per_pixel' => 32,
+ 'size' => $image_header_size + $color_mask_size + $opacity_mask_size,
+ 'data' => $data,
+ );
+
+ $this->_images[] = $image;
+ }
+
+ /**
+ * Read in the source image file and convert it into a GD image resource.
+ *
+ * @param string $file
+ * @return bool|resource
+ */
+ protected function _load_image_file( $file ) {
+ // Run a cheap check to verify that it is an image file.
+ if ( false === ( $size = getimagesize( $file ) ) )
+ return false;
+
+ if ( false === ( $file_data = file_get_contents( $file ) ) )
+ return false;
+
+ if ( false === ( $im = imagecreatefromstring( $file_data ) ) )
+ return false;
+
+ unset( $file_data );
+
+
+ return $im;
+ }
+}
diff --git a/platform/www/lib/plugins/farmer/3rdparty/RingIcon.php b/platform/www/lib/plugins/farmer/3rdparty/RingIcon.php
new file mode 100644
index 0000000..c8dfdbc
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/3rdparty/RingIcon.php
@@ -0,0 +1,186 @@
+<?php
+
+namespace splitbrain\RingIcon;
+
+/**
+ * Class RingIcon
+ *
+ * Generates a identicon/visiglyph like image based on concentric rings
+ *
+ * @todo add a mono color version
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @license MIT
+ * @package splitbrain\RingIcon
+ */
+class RingIcon
+{
+
+ protected $size;
+ protected $fullsize;
+ protected $rings;
+ protected $center;
+ protected $ringwidth;
+ protected $seed;
+ protected $ismono = false;
+ protected $monocolor = null;
+
+ /**
+ * RingIcon constructor.
+ * @param int $size width and height of the resulting image
+ * @param int $rings number of rings
+ */
+ public function __construct($size, $rings = 3)
+ {
+ $this->size = $size;
+ $this->fullsize = $this->size * 5;
+ $this->rings = 4;
+
+ $this->center = floor($this->fullsize / 2);
+ $this->ringwidth = floor($this->fullsize / $rings);
+
+ $this->seed = mt_rand() . time();
+ }
+
+ /**
+ * Generates an ring image
+ *
+ * If a seed is given, the image will be based on that seed
+ *
+ * @param string $seed initialize the genrator with this string
+ * @param string $file if given, the image is saved at that path, otherwise is printed to browser
+ */
+ public function createImage($seed = '', $file = '')
+ {
+ if (!$seed) {
+ $seed = mt_rand() . time();
+ }
+ $this->seed = $seed;
+
+ // monochrome wanted?
+ if($this->ismono) {
+ $this->monocolor = array(
+ $this->rand(20,255),
+ $this->rand(20,255),
+ $this->rand(20,255)
+ );
+ } else {
+ $this->monocolor = null;
+ }
+
+ // create
+ $image = $this->createTransparentImage($this->fullsize, $this->fullsize);
+ $arcwidth = $this->fullsize;
+ for ($i = $this->rings; $i > 0; $i--) {
+ $this->drawRing($image, $arcwidth);
+ $arcwidth -= $this->ringwidth;
+ }
+
+ // resample for antialiasing
+ $out = $this->createTransparentImage($this->size, $this->size);
+ imagecopyresampled($out, $image, 0, 0, 0, 0, $this->size, $this->size, $this->fullsize, $this->fullsize);
+ if ($file) {
+ imagepng($out, $file);
+ } else {
+ header("Content-type: image/png");
+ imagepng($out);
+ }
+ imagedestroy($out);
+ imagedestroy($image);
+ }
+
+ /**
+ * When set to true a monochrome version is returned
+ *
+ * @param bool $ismono
+ */
+ public function setMono($ismono) {
+ $this->ismono = $ismono;
+ }
+
+ /**
+ * Generate number from seed
+ *
+ * Each call runs MD5 on the seed again
+ *
+ * @param int $min
+ * @param int $max
+ * @return int
+ */
+ protected function rand($min, $max)
+ {
+ $this->seed = md5($this->seed);
+ $rand = hexdec(substr($this->seed, 0, 8));
+ return ($rand % ($max - $min + 1)) + $min;
+ }
+
+ /**
+ * Drawas a single ring
+ *
+ * @param resource $image
+ * @param int $arcwidth outer width of the ring
+ */
+ protected function drawRing($image, $arcwidth)
+ {
+ $color = $this->randomColor($image);
+ $transparency = $this->transparentColor($image);
+
+ $start = $this->rand(20, 360);
+ $stop = $this->rand(20, 360);
+ if($stop < $start) list($start, $stop) = array($stop, $start);
+
+ imagefilledarc($image, $this->center, $this->center, $arcwidth, $arcwidth, $stop, $start, $color, IMG_ARC_PIE);
+ imagefilledellipse($image, $this->center, $this->center, $arcwidth - $this->ringwidth,
+ $arcwidth - $this->ringwidth, $transparency);
+
+ imagecolordeallocate($image, $color);
+ imagecolordeallocate($image, $transparency);
+ }
+
+ /**
+ * Allocate a transparent color
+ *
+ * @param resource $image
+ * @return int
+ */
+ protected function transparentColor($image)
+ {
+ return imagecolorallocatealpha($image, 0, 0, 0, 127);
+ }
+
+ /**
+ * Allocate a random color
+ *
+ * @param $image
+ * @return int
+ */
+ protected function randomColor($image)
+ {
+ if($this->ismono) {
+ return imagecolorallocatealpha($image, $this->monocolor[0], $this->monocolor[1], $this->monocolor[2], $this->rand(0, 96));
+ }
+ return imagecolorallocate($image, $this->rand(0, 255), $this->rand(0, 255), $this->rand(0, 255));
+ }
+
+ /**
+ * Create a transparent image
+ *
+ * @param int $width
+ * @param int $height
+ * @return resource
+ * @throws \Exception
+ */
+ protected function createTransparentImage($width, $height)
+ {
+ $image = @imagecreatetruecolor($width, $height);
+ if (!$image) {
+ throw new \Exception('Missing libgd support');
+ }
+ imagealphablending($image, false);
+ $transparency = $this->transparentColor($image);
+ imagefill($image, 0, 0, $transparency);
+ imagecolordeallocate($image, $transparency);
+ imagesavealpha($image, true);
+ return $image;
+ }
+
+}
diff --git a/platform/www/lib/plugins/farmer/DokuWikiFarmCore.php b/platform/www/lib/plugins/farmer/DokuWikiFarmCore.php
new file mode 100644
index 0000000..6c8547a
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/DokuWikiFarmCore.php
@@ -0,0 +1,375 @@
+<?php
+
+/**
+ * Core Manager for the Farm functionality
+ *
+ * This class is initialized before any other DokuWiki code runs. Therefore it is
+ * completely selfcontained and does not use any of DokuWiki's utility functions.
+ *
+ * It's registered as a global $FARMCORE variable but you should not interact with
+ * it directly. Instead use the Farmer plugin's helper component.
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+class DokuWikiFarmCore {
+ /**
+ * @var array The default config - changed by loadConfig
+ */
+ protected $config = array(
+ 'base' => array(
+ 'farmdir' => '',
+ 'farmhost' => '',
+ 'basedomain' => '',
+ ),
+ 'notfound' => array(
+ 'show' => 'farmer',
+ 'url' => ''
+ ),
+ 'inherit' => array(
+ 'main' => 1,
+ 'acronyms' => 1,
+ 'entities' => 1,
+ 'interwiki' => 1,
+ 'license' => 1,
+ 'mime' => 1,
+ 'scheme' => 1,
+ 'smileys' => 1,
+ 'wordblock' => 1,
+ 'users' => 0,
+ 'plugins' => 0,
+ 'userstyle' => 0,
+ 'userscript' => 0,
+ 'styleini' => 0
+ )
+ );
+
+ /** @var string|false The current animal, false for farmer */
+ protected $animal = false;
+ /** @var bool true if an animal was requested but was not found */
+ protected $notfound = false;
+ /** @var bool true if the current animal was requested by host */
+ protected $hostbased = false;
+
+ /**
+ * DokuWikiFarmCore constructor.
+ *
+ * This initializes the whole farm by loading the configuration and setting
+ * DOKU_CONF depending on the requested animal
+ */
+ public function __construct() {
+ $this->loadConfig();
+ if($this->config['base']['farmdir'] === '') return; // farm setup not complete
+ $this->config['base']['farmdir'] = rtrim($this->config['base']['farmdir'], '/').'/'; // trailing slash always
+ define('DOKU_FARMDIR', $this->config['base']['farmdir']);
+
+ // animal?
+ $this->detectAnimal();
+
+ // setup defines
+ define('DOKU_FARM_ANIMAL', $this->animal);
+ if($this->animal) {
+ define('DOKU_CONF', DOKU_FARMDIR . $this->animal . '/conf/');
+ } else {
+ define('DOKU_CONF', DOKU_INC . '/conf/');
+ }
+
+ $this->setupCascade();
+ $this->adjustCascade();
+ }
+
+ /**
+ * @return array the current farm configuration
+ */
+ public function getConfig() {
+ return $this->config;
+ }
+
+ /**
+ * @return false|string
+ */
+ public function getAnimal() {
+ return $this->animal;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function isHostbased() {
+ return $this->hostbased;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function wasNotfound() {
+ return $this->notfound;
+ }
+
+ /**
+ * @return string
+ */
+ public function getAnimalDataDir() {
+ return DOKU_FARMDIR . $this->getAnimal() . '/data/';
+ }
+
+ /**
+ * @return string
+ */
+ public function getAnimalBaseDir() {
+ if($this->isHostbased()) return '/';
+ return getBaseURL() . '!' . $this->getAnimal();
+ }
+
+ /**
+ * Detect the current animal
+ *
+ * Sets internal members $animal, $notfound and $hostbased
+ *
+ * This borrows form DokuWiki's inc/farm.php but does not support a default conf dir
+ */
+ protected function detectAnimal() {
+ $farmdir = $this->config['base']['farmdir'];
+ $farmhost = $this->config['base']['farmhost'];
+
+ // check if animal was set via parameter (rewrite or CLI)
+ $animal = '';
+ if(isset($_REQUEST['animal'])) $animal = $_REQUEST['animal'];
+ if('cli' == php_sapi_name() && isset($_SERVER['animal'])) $animal = $_SERVER['animal'];
+ if($animal) {
+ // check that $animal is a string and just a directory name and not a path
+ if(!is_string($animal) || strpbrk($animal, '\\/') !== false) {
+ $this->notfound = true;
+ return;
+ };
+ $animal = strtolower($animal);
+
+ // check if animal exists
+ if(is_dir("$farmdir/$animal/conf")) {
+ $this->animal = $animal;
+ return;
+ } else {
+ $this->notfound = true;
+ return;
+ }
+ }
+
+ // no host - no host based setup. if we're still here then it's the farmer
+ if(!isset($_SERVER['HTTP_HOST'])) return;
+
+ // is this the farmer?
+ if(strtolower($_SERVER['HTTP_HOST']) == $farmhost) {
+ return;
+ }
+
+ // still here? check for host based
+ $this->hostbased = true;
+ $possible = $this->getAnimalNamesForHost($_SERVER['HTTP_HOST']);
+ foreach($possible as $animal) {
+ if(is_dir("$farmdir/$animal/conf/")) {
+ $this->animal = $animal;
+ return;
+ }
+ }
+
+ // no hit
+ $this->notfound = true;
+ return;
+ }
+
+ /**
+ * Return a list of possible animal names for the given host
+ *
+ * @param string $host the HTTP_HOST header
+ * @return array
+ */
+ protected function getAnimalNamesForHost($host) {
+ $animals = array();
+ $parts = explode('.', implode('.', explode(':', rtrim($host, '.'))));
+ for($j = count($parts); $j > 0; $j--) {
+ // strip from the end
+ $animals[] = implode('.', array_slice($parts, 0, $j));
+ // strip from the end without host part
+ $animals[] = implode('.', array_slice($parts, 1, $j));
+ }
+ $animals = array_unique($animals);
+ $animals = array_filter($animals);
+ usort(
+ $animals,
+ // compare by length, then alphabet
+ function ($a, $b) {
+ $ret = strlen($b) - strlen($a);
+ if($ret != 0) return $ret;
+ return $a > $b;
+ }
+ );
+ return $animals;
+ }
+
+ /**
+ * This sets up the default farming config cascade
+ */
+ protected function setupCascade() {
+ global $config_cascade;
+ $config_cascade = array(
+ 'main' => array(
+ 'default' => array(DOKU_INC . 'conf/dokuwiki.php',),
+ 'local' => array(DOKU_CONF . 'local.php',),
+ 'protected' => array(DOKU_CONF . 'local.protected.php',),
+ ),
+ 'acronyms' => array(
+ 'default' => array(DOKU_INC . 'conf/acronyms.conf',),
+ 'local' => array(DOKU_CONF . 'acronyms.local.conf',),
+ ),
+ 'entities' => array(
+ 'default' => array(DOKU_INC . 'conf/entities.conf',),
+ 'local' => array(DOKU_CONF . 'entities.local.conf',),
+ ),
+ 'interwiki' => array(
+ 'default' => array(DOKU_INC . 'conf/interwiki.conf',),
+ 'local' => array(DOKU_CONF . 'interwiki.local.conf',),
+ ),
+ 'license' => array(
+ 'default' => array(DOKU_INC . 'conf/license.php',),
+ 'local' => array(DOKU_CONF . 'license.local.php',),
+ ),
+ 'manifest' => array(
+ 'default' => array(DOKU_INC . 'conf/manifest.json',),
+ 'local' => array(DOKU_CONF . 'manifest.local.json',),
+ ),
+ 'mediameta' => array(
+ 'default' => array(DOKU_INC . 'conf/mediameta.php',),
+ 'local' => array(DOKU_CONF . 'mediameta.local.php',),
+ ),
+ 'mime' => array(
+ 'default' => array(DOKU_INC . 'conf/mime.conf',),
+ 'local' => array(DOKU_CONF . 'mime.local.conf',),
+ ),
+ 'scheme' => array(
+ 'default' => array(DOKU_INC . 'conf/scheme.conf',),
+ 'local' => array(DOKU_CONF . 'scheme.local.conf',),
+ ),
+ 'smileys' => array(
+ 'default' => array(DOKU_INC . 'conf/smileys.conf',),
+ 'local' => array(DOKU_CONF . 'smileys.local.conf',),
+ ),
+ 'wordblock' => array(
+ 'default' => array(DOKU_INC . 'conf/wordblock.conf',),
+ 'local' => array(DOKU_CONF . 'wordblock.local.conf',),
+ ),
+ 'acl' => array(
+ 'default' => DOKU_CONF . 'acl.auth.php',
+ ),
+ 'plainauth.users' => array(
+ 'default' => DOKU_CONF . 'users.auth.php',
+ ),
+ 'plugins' => array(
+ 'default' => array(DOKU_INC . 'conf/plugins.php',),
+ 'local' => array(DOKU_CONF . 'plugins.local.php',),
+ 'protected' => array(
+ DOKU_INC . 'conf/plugins.required.php',
+ DOKU_CONF . 'plugins.protected.php',
+ ),
+ ),
+ 'userstyle' => array(
+ 'screen' => array(DOKU_CONF . 'userstyle.css', DOKU_CONF . 'userstyle.less',),
+ 'print' => array(DOKU_CONF . 'userprint.css', DOKU_CONF . 'userprint.less',),
+ 'feed' => array(DOKU_CONF . 'userfeed.css', DOKU_CONF . 'userfeed.less',),
+ 'all' => array(DOKU_CONF . 'userall.css', DOKU_CONF . 'userall.less',),
+ ),
+ 'userscript' => array(
+ 'default' => array(DOKU_CONF . 'userscript.js',),
+ ),
+ 'styleini' => array(
+ 'default' => array(DOKU_INC . 'lib/tpl/%TEMPLATE%/' . 'style.ini'),
+ 'local' => array(DOKU_CONF . 'tpl/%TEMPLATE%/' . 'style.ini')
+ ),
+ );
+ }
+
+ /**
+ * This adds additional files to the config cascade based on the inheritence settings
+ *
+ * These are only added for animals, not the farmer
+ */
+ protected function adjustCascade() {
+ // nothing to do when on the farmer:
+ if(!$this->animal) return;
+
+ global $config_cascade;
+ foreach($this->config['inherit'] as $key => $val) {
+ if(!$val) continue;
+
+ // prepare what is to append or prepend
+ $append = array();
+ $prepend = array();
+ if($key == 'main') {
+ $append = array(
+ 'default' => array(DOKU_INC . 'conf/local.php'),
+ 'protected' => array(DOKU_INC . 'lib/plugins/farmer/includes/config.php')
+ );
+ } elseif($key == 'license') {
+ $append = array('default' => array(DOKU_INC . 'conf/' . $key . '.local.php'));
+ } elseif($key == 'userscript') {
+ $prepend = array('default' => array(DOKU_INC . 'conf/userscript.js'));
+ } elseif($key == 'userstyle') {
+ $prepend = array(
+ 'screen' => array(DOKU_INC . 'conf/userstyle.css', DOKU_INC . 'conf/userstyle.less',),
+ 'print' => array(DOKU_INC . 'conf/userprint.css', DOKU_INC . 'conf/userprint.less',),
+ 'feed' => array(DOKU_INC . 'conf/userfeed.css', DOKU_INC . 'conf/userfeed.less',),
+ 'all' => array(DOKU_INC . 'conf/userall.css', DOKU_INC . 'conf/userall.less',),
+ );
+ } elseif ($key == 'styleini') {
+ $append = array(
+ 'local' => array(
+ DOKU_INC . 'conf/tpl/%TEMPLATE%/style.ini'
+ )
+ );
+ } elseif($key == 'users') {
+ $config_cascade['plainauth.users']['protected'] = DOKU_INC . 'conf/users.auth.php';
+ } elseif($key == 'plugins') {
+ $append = array('default' => array(DOKU_INC . 'conf/plugins.local.php'));
+ } else {
+ $append = array('default' => array(DOKU_INC . 'conf/' . $key . '.local.conf'));
+ }
+
+ // add to cascade
+ foreach($prepend as $section => $data) {
+ $config_cascade[$key][$section] = array_merge($data, $config_cascade[$key][$section]);
+ }
+ foreach($append as $section => $data) {
+ $config_cascade[$key][$section] = array_merge($config_cascade[$key][$section], $data);
+ }
+ }
+
+ // add plugin overrides
+ $config_cascade['plugins']['protected'][] = DOKU_INC . 'lib/plugins/farmer/includes/plugins.php';
+ }
+
+ /**
+ * Loads the farm config
+ */
+ protected function loadConfig() {
+ $ini = DOKU_INC . 'conf/farm.ini';
+ if(!file_exists($ini)) return;
+ $config = parse_ini_file($ini, true);
+ foreach(array_keys($this->config) as $section) {
+ if(isset($config[$section])) {
+ $this->config[$section] = array_merge(
+ $this->config[$section],
+ $config[$section]
+ );
+ }
+ }
+
+ $this->config['base']['farmdir'] = trim($this->config['base']['farmdir']);
+ $this->config['base']['farmhost'] = strtolower(trim($this->config['base']['farmhost']));
+ }
+
+}
+
+// initialize it globally
+if(!defined('DOKU_UNITTEST')) {
+ global $FARMCORE;
+ $FARMCORE = new DokuWikiFarmCore();
+}
diff --git a/platform/www/lib/plugins/farmer/README b/platform/www/lib/plugins/farmer/README
new file mode 100644
index 0000000..0515a92
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/README
@@ -0,0 +1,27 @@
+farmer Plugin for DokuWiki
+
+A plugin to help with creating and administring wiki farm animals
+
+All documentation for this plugin can be found at
+https://dokuwiki.org/plugin:farmer
+
+If you install this plugin manually, make sure it is installed in
+lib/plugins/farmer/ - if the folder is called different it
+will not work!
+
+Please refer to http://www.dokuwiki.org/plugins for additional info
+on how to install plugins in DokuWiki.
+
+----
+Copyright (C) Michael Große, Andreas Gohr <dokuwiki@cosmocode.de>
+
+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; version 2 of the License
+
+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.
+
+See the COPYING file in your DokuWiki folder for details
diff --git a/platform/www/lib/plugins/farmer/_animal/conf/acl.auth.php b/platform/www/lib/plugins/farmer/_animal/conf/acl.auth.php
new file mode 100644
index 0000000..14344d7
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/conf/acl.auth.php
@@ -0,0 +1,21 @@
+# acl.auth.php
+# <?php exit()?>
+# Don't modify the lines above
+#
+# Access Control Lists
+#
+# Editing this file by hand shouldn't be necessary. Use the ACL
+# Manager interface instead.
+#
+# If your auth backend allows special char like spaces in groups
+# or user names you need to urlencode them (only chars <128, leave
+# UTF-8 multibyte chars as is)
+#
+# none 0
+# read 1
+# edit 2
+# create 4
+# upload 8
+# delete 16
+
+* @ALL 8
diff --git a/platform/www/lib/plugins/farmer/_animal/conf/local.php b/platform/www/lib/plugins/farmer/_animal/conf/local.php
new file mode 100644
index 0000000..109a33a
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/conf/local.php
@@ -0,0 +1,6 @@
+<?php
+/**
+ * Minimal local config
+ */
+$conf['useacl'] = 1;
+$conf['superuser'] = '@admin';
diff --git a/platform/www/lib/plugins/farmer/_animal/data/_dummy b/platform/www/lib/plugins/farmer/_animal/data/_dummy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/_dummy
diff --git a/platform/www/lib/plugins/farmer/_animal/data/attic/_dummy b/platform/www/lib/plugins/farmer/_animal/data/attic/_dummy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/attic/_dummy
diff --git a/platform/www/lib/plugins/farmer/_animal/data/cache/_dummy b/platform/www/lib/plugins/farmer/_animal/data/cache/_dummy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/cache/_dummy
diff --git a/platform/www/lib/plugins/farmer/_animal/data/index/_dummy b/platform/www/lib/plugins/farmer/_animal/data/index/_dummy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/index/_dummy
diff --git a/platform/www/lib/plugins/farmer/_animal/data/locks/_dummy b/platform/www/lib/plugins/farmer/_animal/data/locks/_dummy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/locks/_dummy
diff --git a/platform/www/lib/plugins/farmer/_animal/data/log/_dummy b/platform/www/lib/plugins/farmer/_animal/data/log/_dummy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/log/_dummy
diff --git a/platform/www/lib/plugins/farmer/_animal/data/media/wiki/dokuwiki-128.png b/platform/www/lib/plugins/farmer/_animal/data/media/wiki/dokuwiki-128.png
new file mode 100644
index 0000000..b2306ac
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/media/wiki/dokuwiki-128.png
Binary files differ
diff --git a/platform/www/lib/plugins/farmer/_animal/data/media_attic/_dummy b/platform/www/lib/plugins/farmer/_animal/data/media_attic/_dummy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/media_attic/_dummy
diff --git a/platform/www/lib/plugins/farmer/_animal/data/media_meta/_dummy b/platform/www/lib/plugins/farmer/_animal/data/media_meta/_dummy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/media_meta/_dummy
diff --git a/platform/www/lib/plugins/farmer/_animal/data/meta/_dummy b/platform/www/lib/plugins/farmer/_animal/data/meta/_dummy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/meta/_dummy
diff --git a/platform/www/lib/plugins/farmer/_animal/data/pages/wiki/dokuwiki.txt b/platform/www/lib/plugins/farmer/_animal/data/pages/wiki/dokuwiki.txt
new file mode 100644
index 0000000..e6fac5b
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/pages/wiki/dokuwiki.txt
@@ -0,0 +1,64 @@
+====== DokuWiki ======
+
+[[doku>wiki:dokuwiki|{{wiki:dokuwiki-128.png }}]] DokuWiki is a standards compliant, simple to use [[wp>Wiki]], mainly aimed at creating documentation of any kind. It is targeted at developer teams, workgroups and small companies. It has a simple but powerful [[wiki:syntax]] which makes sure the datafiles remain readable outside the Wiki and eases the creation of structured texts. All data is stored in plain text files -- no database is required.
+
+Read the [[doku>manual|DokuWiki Manual]] to unleash the full power of DokuWiki.
+
+===== Download =====
+
+DokuWiki is available at http://www.splitbrain.org/go/dokuwiki
+
+
+===== Read More =====
+
+All documentation and additional information besides the [[syntax|syntax description]] is maintained in the DokuWiki at [[doku>|www.dokuwiki.org]].
+
+**About DokuWiki**
+
+ * [[doku>features|A feature list]] :!:
+ * [[doku>users|Happy Users]]
+ * [[doku>press|Who wrote about it]]
+ * [[doku>blogroll|What Bloggers think]]
+ * [[http://www.wikimatrix.org/show/DokuWiki|Compare it with other wiki software]]
+
+**Installing DokuWiki**
+
+ * [[doku>requirements|System Requirements]]
+ * [[http://www.splitbrain.org/go/dokuwiki|Download DokuWiki]] :!:
+ * [[doku>changes|Change Log]]
+ * [[doku>Install|How to install or upgrade]] :!:
+ * [[doku>config|Configuration]]
+
+**Using DokuWiki**
+
+ * [[doku>syntax|Wiki Syntax]]
+ * [[doku>manual|The manual]] :!:
+ * [[doku>FAQ|Frequently Asked Questions (FAQ)]]
+ * [[doku>glossary|Glossary]]
+ * [[http://search.dokuwiki.org|Search for DokuWiki help and documentation]]
+
+**Customizing DokuWiki**
+
+ * [[doku>tips|Tips and Tricks]]
+ * [[doku>Template|How to create and use templates]]
+ * [[doku>plugins|Installing plugins]]
+ * [[doku>development|Development Resources]]
+
+**DokuWiki Feedback and Community**
+
+ * [[doku>newsletter|Subscribe to the newsletter]] :!:
+ * [[doku>mailinglist|Join the mailing list]]
+ * [[http://forum.dokuwiki.org|Check out the user forum]]
+ * [[doku>irc|Talk to other users in the IRC channel]]
+ * [[http://bugs.splitbrain.org/index.php?project=1|Submit bugs and feature wishes]]
+ * [[http://www.wikimatrix.org/forum/viewforum.php?id=10|Share your experiences in the WikiMatrix forum]]
+ * [[doku>thanks|Some humble thanks]]
+
+
+===== Copyright =====
+
+2004-2010 (c) Andreas Gohr <andi@splitbrain.org>((Please do not contact me for help and support -- use the [[doku>mailinglist]] or [[http://forum.dokuwiki.org|forum]] instead)) and the DokuWiki Community
+
+The DokuWiki engine is licensed under [[http://www.gnu.org/licenses/gpl.html|GNU General Public License]] Version 2. If you use DokuWiki in your company, consider [[doku>donate|donating]] a few bucks ;-).
+
+Not sure what this means? See the [[doku>faq:license|FAQ on the Licenses]].
diff --git a/platform/www/lib/plugins/farmer/_animal/data/pages/wiki/syntax.txt b/platform/www/lib/plugins/farmer/_animal/data/pages/wiki/syntax.txt
new file mode 100644
index 0000000..dd3154e
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/pages/wiki/syntax.txt
@@ -0,0 +1,486 @@
+====== Formatting Syntax ======
+
+[[doku>DokuWiki]] supports some simple markup language, which tries to make the datafiles to be as readable as possible. This page contains all possible syntax you may use when editing the pages. Simply have a look at the source of this page by pressing the //Edit this page// button at the top or bottom of the page. If you want to try something, just use the [[playground:playground|playground]] page. The simpler markup is easily accessible via [[doku>toolbar|quickbuttons]], too.
+
+===== Basic Text Formatting =====
+
+DokuWiki supports **bold**, //italic//, __underlined__ and ''monospaced'' texts. Of course you can **__//''combine''//__** all these.
+
+ DokuWiki supports **bold**, //italic//, __underlined__ and ''monospaced'' texts.
+ Of course you can **__//''combine''//__** all these.
+
+You can use <sub>subscript</sub> and <sup>superscript</sup>, too.
+
+ You can use <sub>subscript</sub> and <sup>superscript</sup>, too.
+
+You can mark something as <del>deleted</del> as well.
+
+ You can mark something as <del>deleted</del> as well.
+
+**Paragraphs** are created from blank lines. If you want to **force a newline** without a paragraph, you can use two backslashes followed by a whitespace or the end of line.
+
+This is some text with some linebreaks\\ Note that the
+two backslashes are only recognized at the end of a line\\
+or followed by\\ a whitespace \\this happens without it.
+
+ This is some text with some linebreaks\\ Note that the
+ two backslashes are only recognized at the end of a line\\
+ or followed by\\ a whitespace \\this happens without it.
+
+You should use forced newlines only if really needed.
+
+===== Links =====
+
+DokuWiki supports multiple ways of creating links.
+
+==== External ====
+
+External links are recognized automagically: http://www.google.com or simply www.google.com - You can set the link text as well: [[http://www.google.com|This Link points to google]]. Email addresses like this one: <andi@splitbrain.org> are recognized, too.
+
+ DokuWiki supports multiple ways of creating links. External links are recognized
+ automagically: http://www.google.com or simply www.google.com - You can set
+ link text as well: [[http://www.google.com|This Link points to google]]. Email
+ addresses like this one: <andi@splitbrain.org> are recognized, too.
+
+==== Internal ====
+
+Internal links are created by using square brackets. You can either just give a [[pagename]] or use an additional [[pagename|link text]].
+
+ Internal links are created by using square brackets. You can either just give
+ a [[pagename]] or use an additional [[pagename|link text]].
+
+[[doku>pagename|Wiki pagenames]] are converted to lowercase automatically, special characters are not allowed.
+
+You can use [[some:namespaces]] by using a colon in the pagename.
+
+ You can use [[some:namespaces]] by using a colon in the pagename.
+
+For details about namespaces see [[doku>namespaces]].
+
+Linking to a specific section is possible, too. Just add the section name behind a hash character as known from HTML. This links to [[syntax#internal|this Section]].
+
+ This links to [[syntax#internal|this Section]].
+
+Notes:
+
+ * Links to [[syntax|existing pages]] are shown in a different style from [[nonexisting]] ones.
+ * DokuWiki does not use [[wp>CamelCase]] to automatically create links by default, but this behavior can be enabled in the [[doku>config]] file. Hint: If DokuWiki is a link, then it's enabled.
+ * When a section's heading is changed, its bookmark changes, too. So don't rely on section linking too much.
+
+==== Interwiki ====
+
+DokuWiki supports [[doku>Interwiki]] links. These are quick links to other Wikis. For example this is a link to Wikipedia's page about Wikis: [[wp>Wiki]].
+
+ DokuWiki supports [[doku>Interwiki]] links. These are quick links to other Wikis.
+ For example this is a link to Wikipedia's page about Wikis: [[wp>Wiki]].
+
+==== Windows Shares ====
+
+Windows shares like [[\\server\share|this]] are recognized, too. Please note that these only make sense in a homogeneous user group like a corporate [[wp>Intranet]].
+
+ Windows Shares like [[\\server\share|this]] are recognized, too.
+
+Notes:
+
+ * For security reasons direct browsing of windows shares only works in Microsoft Internet Explorer per default (and only in the "local zone").
+ * For Mozilla and Firefox it can be enabled through different workaround mentioned in the [[http://kb.mozillazine.org/Links_to_local_pages_do_not_work|Mozilla Knowledge Base]]. However, there will still be a JavaScript warning about trying to open a Windows Share. To remove this warning (for all users), put the following line in ''conf/local.protected.php'':
+
+ $lang['js']['nosmblinks'] = '';
+
+==== Image Links ====
+
+You can also use an image to link to another internal or external page by combining the syntax for links and [[#images_and_other_files|images]] (see below) like this:
+
+ [[http://www.php.net|{{wiki:dokuwiki-128.png}}]]
+
+[[http://www.php.net|{{wiki:dokuwiki-128.png}}]]
+
+Please note: The image formatting is the only formatting syntax accepted in link names.
+
+The whole [[#images_and_other_files|image]] and [[#links|link]] syntax is supported (including image resizing, internal and external images and URLs and interwiki links).
+
+===== Footnotes =====
+
+You can add footnotes ((This is a footnote)) by using double parentheses.
+
+ You can add footnotes ((This is a footnote)) by using double parentheses.
+
+===== Sectioning =====
+
+You can use up to five different levels of headlines to structure your content. If you have more than three headlines, a table of contents is generated automatically -- this can be disabled by including the string ''<nowiki>~~NOTOC~~</nowiki>'' in the document.
+
+==== Headline Level 3 ====
+=== Headline Level 4 ===
+== Headline Level 5 ==
+
+ ==== Headline Level 3 ====
+ === Headline Level 4 ===
+ == Headline Level 5 ==
+
+By using four or more dashes, you can make a horizontal line:
+
+----
+
+===== Images and Other Files =====
+
+You can include external and internal [[doku>images]] with curly brackets. Optionally you can specify the size of them.
+
+Real size: {{wiki:dokuwiki-128.png}}
+
+Resize to given width: {{wiki:dokuwiki-128.png?50}}
+
+Resize to given width and height((when the aspect ratio of the given width and height doesn't match that of the image, it will be cropped to the new ratio before resizing)): {{wiki:dokuwiki-128.png?200x50}}
+
+Resized external image: {{http://de3.php.net/images/php.gif?200x50}}
+
+ Real size: {{wiki:dokuwiki-128.png}}
+ Resize to given width: {{wiki:dokuwiki-128.png?50}}
+ Resize to given width and height: {{wiki:dokuwiki-128.png?200x50}}
+ Resized external image: {{http://de3.php.net/images/php.gif?200x50}}
+
+
+By using left or right whitespaces you can choose the alignment.
+
+{{ wiki:dokuwiki-128.png}}
+
+{{wiki:dokuwiki-128.png }}
+
+{{ wiki:dokuwiki-128.png }}
+
+ {{ wiki:dokuwiki-128.png}}
+ {{wiki:dokuwiki-128.png }}
+ {{ wiki:dokuwiki-128.png }}
+
+Of course, you can add a title (displayed as a tooltip by most browsers), too.
+
+{{ wiki:dokuwiki-128.png |This is the caption}}
+
+ {{ wiki:dokuwiki-128.png |This is the caption}}
+
+If you specify a filename (external or internal) that is not an image (''gif, jpeg, png''), then it will be displayed as a link instead.
+
+For linking an image to another page see [[#Image Links]] above.
+
+===== Lists =====
+
+Dokuwiki supports ordered and unordered lists. To create a list item, indent your text by two spaces and use a ''*'' for unordered lists or a ''-'' for ordered ones.
+
+ * This is a list
+ * The second item
+ * You may have different levels
+ * Another item
+
+ - The same list but ordered
+ - Another item
+ - Just use indention for deeper levels
+ - That's it
+
+<code>
+ * This is a list
+ * The second item
+ * You may have different levels
+ * Another item
+
+ - The same list but ordered
+ - Another item
+ - Just use indention for deeper levels
+ - That's it
+</code>
+
+Also take a look at the [[doku>faq:lists|FAQ on list items]].
+
+===== Text Conversions =====
+
+DokuWiki can convert certain pre-defined characters or strings into images or other text or HTML.
+
+The text to image conversion is mainly done for smileys. And the text to HTML conversion is used for typography replacements, but can be configured to use other HTML as well.
+
+==== Text to Image Conversions ====
+
+DokuWiki converts commonly used [[wp>emoticon]]s to their graphical equivalents. Those [[doku>Smileys]] and other images can be configured and extended. Here is an overview of Smileys included in DokuWiki:
+
+ * 8-) %% 8-) %%
+ * 8-O %% 8-O %%
+ * :-( %% :-( %%
+ * :-) %% :-) %%
+ * =) %% =) %%
+ * :-/ %% :-/ %%
+ * :-\ %% :-\ %%
+ * :-? %% :-? %%
+ * :-D %% :-D %%
+ * :-P %% :-P %%
+ * :-O %% :-O %%
+ * :-X %% :-X %%
+ * :-| %% :-| %%
+ * ;-) %% ;-) %%
+ * ^_^ %% ^_^ %%
+ * :?: %% :?: %%
+ * :!: %% :!: %%
+ * LOL %% LOL %%
+ * FIXME %% FIXME %%
+ * DELETEME %% DELETEME %%
+
+==== Text to HTML Conversions ====
+
+Typography: [[DokuWiki]] can convert simple text characters to their typographically correct entities. Here is an example of recognized characters.
+
+-> <- <-> => <= <=> >> << -- --- 640x480 (c) (tm) (r)
+"He thought 'It's a man's world'..."
+
+<code>
+-> <- <-> => <= <=> >> << -- --- 640x480 (c) (tm) (r)
+"He thought 'It's a man's world'..."
+</code>
+
+The same can be done to produce any kind of HTML, it just needs to be added to the [[doku>entities|pattern file]].
+
+There are three exceptions which do not come from that pattern file: multiplication entity (640x480), 'single' and "double quotes". They can be turned off through a [[doku>config:typography|config option]].
+
+===== Quoting =====
+
+Some times you want to mark some text to show it's a reply or comment. You can use the following syntax:
+
+ I think we should do it
+
+ > No we shouldn't
+
+ >> Well, I say we should
+
+ > Really?
+
+ >> Yes!
+
+ >>> Then lets do it!
+
+I think we should do it
+
+> No we shouldn't
+
+>> Well, I say we should
+
+> Really?
+
+>> Yes!
+
+>>> Then lets do it!
+
+===== Tables =====
+
+DokuWiki supports a simple syntax to create tables.
+
+^ Heading 1 ^ Heading 2 ^ Heading 3 ^
+| Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
+| Row 2 Col 1 | some colspan (note the double pipe) ||
+| Row 3 Col 1 | Row 3 Col 2 | Row 3 Col 3 |
+
+Table rows have to start and end with a ''|'' for normal rows or a ''^'' for headers.
+
+ ^ Heading 1 ^ Heading 2 ^ Heading 3 ^
+ | Row 1 Col 1 | Row 1 Col 2 | Row 1 Col 3 |
+ | Row 2 Col 1 | some colspan (note the double pipe) ||
+ | Row 3 Col 1 | Row 3 Col 2 | Row 3 Col 3 |
+
+To connect cells horizontally, just make the next cell completely empty as shown above. Be sure to have always the same amount of cell separators!
+
+Vertical tableheaders are possible, too.
+
+| ^ Heading 1 ^ Heading 2 ^
+^ Heading 3 | Row 1 Col 2 | Row 1 Col 3 |
+^ Heading 4 | no colspan this time | |
+^ Heading 5 | Row 2 Col 2 | Row 2 Col 3 |
+
+As you can see, it's the cell separator before a cell which decides about the formatting:
+
+ | ^ Heading 1 ^ Heading 2 ^
+ ^ Heading 3 | Row 1 Col 2 | Row 1 Col 3 |
+ ^ Heading 4 | no colspan this time | |
+ ^ Heading 5 | Row 2 Col 2 | Row 2 Col 3 |
+
+You can have rowspans (vertically connected cells) by adding '':::'' into the cells below the one to which they should connect.
+
+^ Heading 1 ^ Heading 2 ^ Heading 3 ^
+| Row 1 Col 1 | this cell spans vertically | Row 1 Col 3 |
+| Row 2 Col 1 | ::: | Row 2 Col 3 |
+| Row 3 Col 1 | ::: | Row 2 Col 3 |
+
+Apart from the rowspan syntax those cells should not contain anything else.
+
+ ^ Heading 1 ^ Heading 2 ^ Heading 3 ^
+ | Row 1 Col 1 | this cell spans vertically | Row 1 Col 3 |
+ | Row 2 Col 1 | ::: | Row 2 Col 3 |
+ | Row 3 Col 1 | ::: | Row 2 Col 3 |
+
+You can align the table contents, too. Just add at least two whitespaces at the opposite end of your text: Add two spaces on the left to align right, two spaces on the right to align left and two spaces at least at both ends for centered text.
+
+^ Table with alignment ^^^
+| right| center |left |
+|left | right| center |
+| xxxxxxxxxxxx | xxxxxxxxxxxx | xxxxxxxxxxxx |
+
+This is how it looks in the source:
+
+ ^ Table with alignment ^^^
+ | right| center |left |
+ |left | right| center |
+ | xxxxxxxxxxxx | xxxxxxxxxxxx | xxxxxxxxxxxx |
+
+Note: Vertical alignment is not supported.
+
+===== No Formatting =====
+
+If you need to display text exactly like it is typed (without any formatting), enclose the area either with ''%%<nowiki>%%'' tags or even simpler, with double percent signs ''<nowiki>%%</nowiki>''.
+
+<nowiki>
+This is some text which contains addresses like this: http://www.splitbrain.org and **formatting**, but nothing is done with it.
+</nowiki>
+The same is true for %%//__this__ text// with a smiley ;-)%%.
+
+ <nowiki>
+ This is some text which contains addresses like this: http://www.splitbrain.org and **formatting**, but nothing is done with it.
+ </nowiki>
+ The same is true for %%//__this__ text// with a smiley ;-)%%.
+
+===== Code Blocks =====
+
+You can include code blocks into your documents by either indenting them by at least two spaces (like used for the previous examples) or by using the tags ''%%<code>%%'' or ''%%<file>%%''.
+
+ This is text is indented by two spaces.
+
+<code>
+This is preformatted code all spaces are preserved: like <-this
+</code>
+
+<file>
+This is pretty much the same, but you could use it to show that you quoted a file.
+</file>
+
+Those blocks were created by this source:
+
+ This is text is indented by two spaces.
+
+ <code>
+ This is preformatted code all spaces are preserved: like <-this
+ </code>
+
+ <file>
+ This is pretty much the same, but you could use it to show that you quoted a file.
+ </file>
+
+==== Syntax Highlighting ====
+
+[[wiki:DokuWiki]] can highlight sourcecode, which makes it easier to read. It uses the [[http://qbnz.com/highlighter/|GeSHi]] Generic Syntax Highlighter -- so any language supported by GeSHi is supported. The syntax uses the same code and file blocks described in the previous section, but this time the name of the language syntax to be highlighted is included inside the tag, e.g. ''<nowiki><code java></nowiki>'' or ''<nowiki><file java></nowiki>''.
+
+<code java>
+/**
+ * The HelloWorldApp class implements an application that
+ * simply displays "Hello World!" to the standard output.
+ */
+class HelloWorldApp {
+ public static void main(String[] args) {
+ System.out.println("Hello World!"); //Display the string.
+ }
+}
+</code>
+
+The following language strings are currently recognized: //4cs, 6502acme, 6502kickass, 6502tasm, 68000devpac, abap, actionscript-french, actionscript, actionscript3, ada, algol68, apache, applescript, asm, asp, autoconf, autohotkey, autoit, avisynth, awk, bascomavr, bash, basic4gl, bf, bibtex, blitzbasic, bnf, boo, c, c_loadrunner, c_mac, caddcl, cadlisp, cfdg, cfm, chaiscript, cil, clojure, cmake, cobol, coffeescript, cpp, cpp-qt, csharp, css, cuesheet, d, dcs, delphi, diff, div, dos, dot, e, epc, ecmascript, eiffel, email, erlang, euphoria, f1, falcon, fo, fortran, freebasic, fsharp, gambas, genero, genie, gdb, glsl, gml, gnuplot, go, groovy, gettext, gwbasic, haskell, hicest, hq9plus, html, html5, icon, idl, ini, inno, intercal, io, j, java5, java, javascript, jquery, kixtart, klonec, klonecpp, latex, lb, lisp, llvm, locobasic, logtalk, lolcode, lotusformulas, lotusscript, lscript, lsl2, lua, m68k, magiksf, make, mapbasic, matlab, mirc, modula2, modula3, mmix, mpasm, mxml, mysql, newlisp, nsis, oberon2, objc, objeck, ocaml-brief, ocaml, oobas, oracle8, oracle11, oxygene, oz, pascal, pcre, perl, perl6, per, pf, php-brief, php, pike, pic16, pixelbender, pli, plsql, postgresql, povray, powerbuilder, powershell, proftpd, progress, prolog, properties, providex, purebasic, pycon, python, q, qbasic, rails, rebol, reg, robots, rpmspec, rsplus, ruby, sas, scala, scheme, scilab, sdlbasic, smalltalk, smarty, sql, systemverilog, tcl, teraterm, text, thinbasic, tsql, typoscript, unicon, uscript, vala, vbnet, vb, verilog, vhdl, vim, visualfoxpro, visualprolog, whitespace, winbatch, whois, xbasic, xml, xorg_conf, xpp, yaml, z80, zxbasic//
+
+==== Downloadable Code Blocks ====
+
+When you use the ''%%<code>%%'' or ''%%<file>%%'' syntax as above, you might want to make the shown code available for download as well. You can do this by specifying a file name after language code like this:
+
+<code>
+<file php myexample.php>
+<?php echo "hello world!"; ?>
+</file>
+</code>
+
+<file php myexample.php>
+<?php echo "hello world!"; ?>
+</file>
+
+If you don't want any highlighting but want a downloadable file, specify a dash (''-'') as the language code: ''%%<code - myfile.foo>%%''.
+
+
+===== Embedding HTML and PHP =====
+
+You can embed raw HTML or PHP code into your documents by using the ''%%<html>%%'' or ''%%<php>%%'' tags. (Use uppercase tags if you need to enclose block level elements.)
+
+HTML example:
+
+<code>
+<html>
+This is some <span style="color:red;font-size:150%;">inline HTML</span>
+</html>
+<HTML>
+<p style="border:2px dashed red;">And this is some block HTML</p>
+</HTML>
+</code>
+
+<html>
+This is some <span style="color:red;font-size:150%;">inline HTML</span>
+</html>
+<HTML>
+<p style="border:2px dashed red;">And this is some block HTML</p>
+</HTML>
+
+PHP example:
+
+<code>
+<php>
+echo 'A logo generated by PHP:';
+echo '<img src="' . $_SERVER['PHP_SELF'] . '?=' . php_logo_guid() . '" alt="PHP Logo !" />';
+echo '(generated inline HTML)';
+</php>
+<PHP>
+echo '<table class="inline"><tr><td>The same, but inside a block level element:</td>';
+echo '<td><img src="' . $_SERVER['PHP_SELF'] . '?=' . php_logo_guid() . '" alt="PHP Logo !" /></td>';
+echo '</tr></table>';
+</PHP>
+</code>
+
+<php>
+echo 'A logo generated by PHP:';
+echo '<img src="' . $_SERVER['PHP_SELF'] . '?=' . php_logo_guid() . '" alt="PHP Logo !" />';
+echo '(inline HTML)';
+</php>
+<PHP>
+echo '<table class="inline"><tr><td>The same, but inside a block level element:</td>';
+echo '<td><img src="' . $_SERVER['PHP_SELF'] . '?=' . php_logo_guid() . '" alt="PHP Logo !" /></td>';
+echo '</tr></table>';
+</PHP>
+
+**Please Note**: HTML and PHP embedding is disabled by default in the configuration. If disabled, the code is displayed instead of executed.
+
+===== RSS/ATOM Feed Aggregation =====
+[[DokuWiki]] can integrate data from external XML feeds. For parsing the XML feeds, [[http://simplepie.org/|SimplePie]] is used. All formats understood by SimplePie can be used in DokuWiki as well. You can influence the rendering by multiple additional space separated parameters:
+
+^ Parameter ^ Description ^
+| any number | will be used as maximum number items to show, defaults to 8 |
+| reverse | display the last items in the feed first |
+| author | show item authors names |
+| date | show item dates |
+| description| show the item description. If [[doku>config:htmlok|HTML]] is disabled all tags will be stripped |
+| //n//[dhm] | refresh period, where d=days, h=hours, m=minutes. (e.g. 12h = 12 hours). |
+
+The refresh period defaults to 4 hours. Any value below 10 minutes will be treated as 10 minutes. [[wiki:DokuWiki]] will generally try to supply a cached version of a page, obviously this is inappropriate when the page contains dynamic external content. The parameter tells [[wiki:DokuWiki]] to re-render the page if it is more than //refresh period// since the page was last rendered.
+
+**Example:**
+
+ {{rss>http://slashdot.org/index.rss 5 author date 1h }}
+
+{{rss>http://slashdot.org/index.rss 5 author date 1h }}
+
+
+===== Control Macros =====
+
+Some syntax influences how DokuWiki renders a page without creating any output it self. The following control macros are availble:
+
+^ Macro ^ Description |
+| %%~~NOTOC~~%% | If this macro is found on the page, no table of contents will be created |
+| %%~~NOCACHE~~%% | DokuWiki caches all output by default. Sometimes this might not be wanted (eg. when the %%<php>%% syntax above is used), adding this macro will force DokuWiki to rerender a page on every call |
+
+===== Syntax Plugins =====
+
+DokuWiki's syntax can be extended by [[doku>plugins|Plugins]]. How the installed plugins are used is described on their appropriate description pages. The following syntax plugins are available in this particular DokuWiki installation:
+
+~~INFO:syntaxplugins~~
diff --git a/platform/www/lib/plugins/farmer/_animal/data/tmp/_dummy b/platform/www/lib/plugins/farmer/_animal/data/tmp/_dummy
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_animal/data/tmp/_dummy
diff --git a/platform/www/lib/plugins/farmer/_test/core.test.php b/platform/www/lib/plugins/farmer/_test/core.test.php
new file mode 100644
index 0000000..d6a1dab
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_test/core.test.php
@@ -0,0 +1,40 @@
+<?php
+namespace plugin\struct\test;
+
+require_once(__DIR__ . '/../DokuWikiFarmCore.php');
+
+class DokuWikiFarmCore extends \DokuWikiFarmCore {
+ public function getAnimalNamesForHost($host) {
+ return parent::getAnimalNamesForHost($host);
+ }
+}
+
+
+/**
+ * @group plugin_farmer
+ * @group plugins
+ */
+class core_plugin_farmer_test extends \DokuWikiTest {
+
+ protected $pluginsEnabled = array('farmer');
+
+
+ public function test_hostsAnimals() {
+ $core = new DokuWikiFarmCore();
+
+ $input = 'www.foobar.example.com:8000';
+ $expect = array(
+ 'www.foobar.example.com.8000',
+ 'foobar.example.com.8000',
+ 'www.foobar.example.com',
+ 'foobar.example.com',
+ 'www.foobar.example',
+ 'foobar.example',
+ 'www.foobar',
+ 'foobar',
+ 'www',
+ );
+
+ $this->assertEquals($expect, $core->getAnimalNamesForHost($input));
+ }
+}
diff --git a/platform/www/lib/plugins/farmer/_test/general.test.php b/platform/www/lib/plugins/farmer/_test/general.test.php
new file mode 100644
index 0000000..af45139
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_test/general.test.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * General tests for the farmer plugin
+ *
+ * @group plugin_farmer
+ * @group plugins
+ */
+class general_plugin_farmer_test extends DokuWikiTest {
+
+ protected $pluginsEnabled = array('farmer');
+
+ /**
+ * Simple test to make sure the plugin.info.txt is in correct format
+ */
+ public function test_plugininfo() {
+ $file = __DIR__ . '/../plugin.info.txt';
+ $this->assertFileExists($file);
+
+ $info = confToHash($file);
+
+ $this->assertArrayHasKey('base', $info);
+ $this->assertArrayHasKey('author', $info);
+ $this->assertArrayHasKey('email', $info);
+ $this->assertArrayHasKey('date', $info);
+ $this->assertArrayHasKey('name', $info);
+ $this->assertArrayHasKey('desc', $info);
+ $this->assertArrayHasKey('url', $info);
+
+ $this->assertEquals('farmer', $info['base']);
+ $this->assertRegExp('/^https?:\/\//', $info['url']);
+ $this->assertTrue(mail_isvalid($info['email']));
+ $this->assertRegExp('/^\d\d\d\d-\d\d-\d\d$/', $info['date']);
+ $this->assertTrue(false !== strtotime($info['date']));
+ }
+}
diff --git a/platform/www/lib/plugins/farmer/_test/getUserLine.test.php b/platform/www/lib/plugins/farmer/_test/getUserLine.test.php
new file mode 100644
index 0000000..8f228cb
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_test/getUserLine.test.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace plugin\struct\test;
+
+class admin_plugin_farmer_new extends \admin_plugin_farmer_new {
+ public function getAdminLine() {
+ return parent::getAdminLine();
+ }
+
+}
+
+
+/**
+ * Tests for the validation functionality of the farmer plugin
+ *
+ * @group plugin_farmer
+ * @group plugins
+ */
+class getUserLine_plugin_farmer_test extends \DokuWikiTest {
+
+ protected $pluginsEnabled = array('farmer',);
+ private $usersfile;
+
+ public function setUp() {
+ parent::setUp();
+ $this->usersfile = DOKU_CONF . 'users.auth.php';
+ copy($this->usersfile, $this->usersfile . "org");
+ unlink($this->usersfile);
+ }
+
+ public function tearDown() {
+ parent::tearDown();
+ unlink($this->usersfile);
+ copy($this->usersfile . "org", $this->usersfile);
+ unlink($this->usersfile . "org");
+ }
+
+
+ public function test_getUserLine_oneUser () {
+ $helper = new admin_plugin_farmer_new();
+ $usersfileData = "# users.auth.php
+# <?php exit()?>
+# Don't modify the lines above
+#
+# Userfile
+#
+# Format:
+#
+# user:MD5password:Real Name:email:groups,comma,seperated
+#
+# testuser : testpass
+testuser:179ad45c6ce2cb97cf1029e212046e81:Arthur Dent:arthur@example.com:\n";
+ file_put_contents($this->usersfile,$usersfileData);
+
+ $_SERVER['REMOTE_USER'] = 'testuser';
+ $expected_result = 'testuser:179ad45c6ce2cb97cf1029e212046e81:Arthur Dent:arthur@example.com:' . "\n";
+ $actual_result = $helper->getAdminLine();
+
+ $this->assertSame($expected_result, $actual_result);
+ }
+
+ public function test_getUserLine_manyUser () {
+ $helper = new admin_plugin_farmer_new();
+ $usersfileData = "# users.auth.php
+# <?php exit()?>
+# Don't modify the lines above
+#
+# Userfile
+#
+# Format:
+#
+# user:MD5password:Real Name:email:groups,comma,seperated
+#
+# testuser : testpass
+1testuser:179ad45c6ce43897cf1029e212046e81:Arthur Dent:brthur@example.com:admin
+testuser:179ad45c6ce2cb97cf1029e212046e81:Arthur Dent:arthur@example.com:
+2testuser:179ad45c6ce2cb97cf10214712046e81:Arthur inDent:crthur@example.com:admin\n";
+ file_put_contents($this->usersfile,$usersfileData);
+
+ $_SERVER['REMOTE_USER'] = 'testuser';
+ $expected_result = 'testuser:179ad45c6ce2cb97cf1029e212046e81:Arthur Dent:arthur@example.com:' . "\n";
+ $actual_result = $helper->getAdminLine();
+
+ $this->assertSame($expected_result, $actual_result);
+ }
+}
diff --git a/platform/www/lib/plugins/farmer/_test/helper.test.php b/platform/www/lib/plugins/farmer/_test/helper.test.php
new file mode 100644
index 0000000..3fc689b
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/_test/helper.test.php
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * Tests for the validation functionality of the farmer plugin
+ *
+ * @group plugin_farmer
+ * @group plugins
+ */
+class helper_plugin_farmer_test extends DokuWikiTest {
+
+ protected $pluginsEnabled = array('farmer',);
+
+ public function validationProvider() {
+ return array(
+ array('ant', true),
+ array('ant.lion', true),
+ array('ant.lion.cow', true),
+ array('ant-lion', true),
+ array('ant-lion.cow', true),
+ array('4ant', true),
+ array('ant4', true),
+ array('ant44lion', true),
+ array('44', true),
+
+ array('ant.', false),
+ array('.ant', false),
+ array('ant-', false),
+ array('-ant', false),
+ array('ant--lion', false),
+ array('ant..lion', false),
+ array('ant.-lion', false),
+ array('ant/lion', false),
+ array('!ant', false),
+ array('ant lion', false),
+ );
+ }
+
+ /**
+ * @dataProvider validationProvider
+ * @param $input
+ * @param $expect
+ */
+ public function test_validateAnimalName($input, $expect) {
+ /** @var helper_plugin_farmer $helper */
+ $helper = plugin_load('helper', 'farmer');
+ $this->assertEquals($expect, $helper->validateAnimalName($input));
+ }
+
+ public function test_isInPath() {
+ /** @var helper_plugin_farmer $helper */
+ $helper = plugin_load('helper', 'farmer');
+
+ $this->assertTrue($helper->isInPath('/var/www/foo', '/var/www'));
+ $this->assertFalse($helper->isInPath('/var/www/../foo', '/var/www'));
+
+ // same dir should return false, too
+ $this->assertFalse($helper->isInPath('/var/www/foo', '/var/www/foo'));
+ $this->assertFalse($helper->isInPath('/var/www/foo/', '/var/www/foo'));
+ $this->assertFalse($helper->isInPath('/var/www/foo/bar/../', '/var/www/foo'));
+
+ // https://github.com/cosmocode/dokuwiki-plugin-farmer/issues/30
+ $this->assertFalse($helper->isInPath('/var/lib/dokuwiki.animals', '/var/lib/dokuwiki'));
+ }
+}
diff --git a/platform/www/lib/plugins/farmer/action/ajax.php b/platform/www/lib/plugins/farmer/action/ajax.php
new file mode 100644
index 0000000..ac20eae
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/action/ajax.php
@@ -0,0 +1,267 @@
+<?php
+/**
+ * DokuWiki Plugin farmer (Action Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Manage AJAX features
+ */
+class action_plugin_farmer_ajax extends DokuWiki_Action_Plugin {
+
+ /**
+ * plugin should use this method to register its handlers with the DokuWiki's event controller
+ *
+ * @param Doku_Event_Handler $controller DokuWiki's event controller object. Also available as global $EVENT_HANDLER
+ *
+ */
+ public function register(Doku_Event_Handler $controller) {
+ $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, '_ajax_call');
+ }
+
+ /**
+ * handle ajax requests
+ *
+ * @param Doku_Event $event
+ * @param $param
+ */
+ public function _ajax_call(Doku_Event $event, $param) {
+ if(substr($event->data, 0, 13) !== 'plugin_farmer') {
+ return;
+ }
+ //no other ajax call handlers needed
+ $event->stopPropagation();
+ $event->preventDefault();
+
+ if(!auth_isadmin()) die('Only admins allowed');
+
+ if(substr($event->data, 14) === 'getPluginMatrix') {
+ $this->get_plugin_matrix($event, $param);
+ return;
+ }
+ if(substr($event->data, 14) === 'modPlugin') {
+ $this->plugin_mod($event, $param);
+ return;
+ }
+ if(substr($event->data, 14, 10) === 'getPlugins') {
+ $this->get_animal_plugins($event, $param);
+ return;
+ }
+ if(substr($event->data, 14, 10) === 'checkSetup') {
+ $this->check_setup($event, $param);
+ }
+ }
+
+ /**
+ * This function exists in order to provide a positive (i.e. 200) response to an ajax request to a non-existing animal.
+ *
+ * @param Doku_Event $event
+ * @param $param
+ */
+ public function check_setup(Doku_Event $event, $param) {
+ $data = '';
+ $json = new JSON();
+ header('Content-Type: application/json');
+ echo $json->encode($data);
+ }
+
+ public function plugin_mod(Doku_Event $event, $param) {
+ global $INPUT;
+
+ /** @var helper_plugin_farmer $helper */
+ $helper = plugin_load('helper', 'farmer');
+
+ $pname = $INPUT->str('plugin');
+ $animal = $INPUT->str('ani');
+
+
+ $plugins = $helper->getAnimalPluginRealState($animal);
+ if(!isset($plugins[$pname])) die('no such plugin');
+ $plugin = $plugins[$pname];
+
+ // figure out what to toggle to
+ if($plugin['isdefault']) {
+ $new = (int) !$plugin['actual'];
+ } else {
+ $new = -1;
+ }
+ $helper->setPluginState($pname, $animal, $new);
+
+ // show new state
+ $plugins = $helper->getAnimalPluginRealState($animal);
+ $plugin = $plugins[$pname];
+ header('Content-Type: text/html; charset=utf-8');
+ echo $this->plugin_matrix_cell($plugin, $animal);
+ }
+
+ /**
+ * Create a matrix of all animals and plugin states
+ *
+ * @param Doku_Event $event
+ * @param $param
+ */
+ public function get_plugin_matrix(Doku_Event $event, $param) {
+ /** @var helper_plugin_farmer $helper */
+ $helper = plugin_load('helper', 'farmer');
+
+ $animals = $helper->getAllAnimals();
+ $plugins = $helper->getAnimalPluginRealState($animals[0]);
+
+ header('Content-Type: text/html; charset=utf-8');
+
+ echo '<div class="table pluginmatrix">';
+ echo '<table>';
+ echo '<thead>';
+ echo '<tr>';
+ echo '<th></th>';
+ foreach($plugins as $plugin) {
+ echo '<th><div>' . hsc($plugin['name']) . '</div></th>';
+ }
+ echo '</tr>';
+ echo '</thead>';
+
+ echo '<tbody>';
+
+ echo '<tr>';
+ echo '<th>Default</th>';
+ foreach($plugins as $plugin) {
+ echo $this->plugin_matrix_cell($plugin, $this->getLang('plugin_default'), true);
+ }
+ echo '</tr>';
+
+ foreach($animals as $animal) {
+ $plugins = $helper->getAnimalPluginRealState($animal);
+ echo '<tr>';
+ echo '<th>' . hsc($animal) . '</th>';
+ foreach($plugins as $plugin) {
+ echo $this->plugin_matrix_cell($plugin, $animal);
+ }
+ echo '</tr>';
+ }
+ echo '</tbody>';
+ echo '</table>';
+ echo '</div>';
+ }
+
+ /**
+ * create a single cell in the matrix
+ *
+ * @param array $plugin
+ * @param string $animal
+ * @param bool $defaults show the defaults
+ * @return string
+ */
+ protected function plugin_matrix_cell($plugin, $animal, $defaults=false) {
+ if($defaults) {
+ $current = $plugin['default'];
+ $isdefault = true;
+ $td = 'th';
+ } else {
+ $current = $plugin['actual'];
+ $isdefault = $plugin['isdefault'];
+ $td = 'td';
+ }
+
+ if($current) {
+ $class = 'on';
+ $lbl = '✓';
+ } else {
+ $class = 'off';
+ $lbl = '✗';
+ }
+ if($isdefault) $class .= ' default';
+
+
+ $attrs = array(
+ 'class' => $class,
+ 'title' => $animal . ': ' . $plugin['name'],
+ 'data-animal' => $animal,
+ 'data-plugin' => $plugin['name']
+ );
+ $attr = buildAttributes($attrs);
+
+ return "<$td $attr>$lbl</$td>";
+ }
+
+ /**
+ * @param Doku_Event $event
+ * @param $param
+ */
+ public function get_animal_plugins(Doku_Event $event, $param) {
+ $animal = substr($event->data, 25);
+ /** @var helper_plugin_farmer $helper */
+ $helper = plugin_load('helper', 'farmer');
+
+ $plugins = $helper->getAnimalPluginRealState($animal);
+
+ header('Content-Type: text/html; charset=utf-8');
+
+ echo '<table>';
+ echo '<tr>';
+ echo '<th>' . $this->getLang('plugin') . '</th>';
+ echo '<th>' . $this->getLang('plugin_default') . '</th>';
+ echo '<th>' . $this->getLang('plugin_enabled') . '</th>';
+ echo '<th>' . $this->getLang('plugin_disabled') . '</th>';
+ echo '</tr>';
+
+ foreach($plugins as $plugin) {
+ echo '<tr>';
+ echo '<th>' . hsc($plugin['name']) . '</th>';
+
+ echo '<td>';
+ $attr = array();
+ $attr['type'] = 'radio';
+ $attr['name'] = 'bulk_plugins[' . $plugin['name'] . ']';
+ $attr['value'] = '-1';
+ if($plugin['isdefault']) {
+ $attr['checked'] = 'checked';
+ }
+ echo '<label>';
+ echo '<input ' . buildAttributes($attr) . ' />';
+ if($plugin['default']) {
+ echo ' (' . $this->getLang('plugin_on') . ')';
+ } else {
+ echo ' (' . $this->getLang('plugin_off') . ')';
+ }
+ echo '</label>';
+ echo '</td>';
+
+ echo '<td>';
+ $attr = array();
+ $attr['type'] = 'radio';
+ $attr['name'] = 'bulk_plugins[' . $plugin['name'] . ']';
+ $attr['value'] = '1';
+ if(!$plugin['isdefault'] && $plugin['actual']) {
+ $attr['checked'] = 'checked';
+ }
+ echo '<label>';
+ echo '<input ' . buildAttributes($attr) . ' />';
+ echo ' ' . $this->getLang('plugin_on');
+ echo '</label>';
+ echo '</td>';
+
+ echo '<td>';
+ $attr = array();
+ $attr['type'] = 'radio';
+ $attr['name'] = 'bulk_plugins[' . $plugin['name'] . ']';
+ $attr['value'] = '0';
+ if(!$plugin['isdefault'] && !$plugin['actual']) {
+ $attr['checked'] = 'checked';
+ }
+ echo '<label>';
+ echo '<input ' . buildAttributes($attr) . ' />';
+ echo ' ' . $this->getLang('plugin_off');
+ echo '</label>';
+ echo '</td>';
+
+ echo '</tr>';
+ }
+ }
+
+}
+
diff --git a/platform/www/lib/plugins/farmer/action/disable.php b/platform/www/lib/plugins/farmer/action/disable.php
new file mode 100644
index 0000000..bf0c48a
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/action/disable.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * DokuWiki Plugin farmer (Action Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Disable Plugins on install
+ */
+class action_plugin_farmer_disable extends DokuWiki_Action_Plugin {
+
+ /**
+ * plugin should use this method to register its handlers with the DokuWiki's event controller
+ *
+ * @param Doku_Event_Handler $controller DokuWiki's event controller object. Also available as global $EVENT_HANDLER
+ *
+ */
+ public function register(Doku_Event_Handler $controller) {
+ /** @var helper_plugin_farmer $farmer */
+ $farmer = plugin_load('helper', 'farmer');
+ if($farmer->getAnimal()) return;
+
+ if($this->getConf('disable_new_plugins')) {
+ $controller->register_hook('PLUGIN_EXTENSION_CHANGE', 'AFTER', $this, 'handle_install');
+ }
+ }
+
+ /**
+ * handle install of new plugin
+ *
+ * @param Doku_Event $event
+ * @param $param
+ */
+ public function handle_install(Doku_Event $event, $param) {
+ if($event->data['action'] != 'install') return;
+
+ /* @var Doku_Plugin_Controller $plugin_controller */
+ global $plugin_controller;
+ $plugin_controller = new Doku_Plugin_Controller(); // we need to refresh the status
+
+ /** @var helper_plugin_extension_extension $ext */
+ $ext = $event->data['extension'];
+ $disabled = $ext->disable();
+ if($disabled === true) {
+ msg($this->getLang('disable_new_plugins'));
+ } else {
+ msg(hsc($disabled), -1);
+ }
+ }
+}
+
diff --git a/platform/www/lib/plugins/farmer/action/startup.php b/platform/www/lib/plugins/farmer/action/startup.php
new file mode 100644
index 0000000..4b9d38e
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/action/startup.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * DokuWiki Plugin farmer (Action Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Handles Farm mechanisms on DokuWiki startup
+ */
+class action_plugin_farmer_startup extends DokuWiki_Action_Plugin {
+
+ /** @var helper_plugin_farmer */
+ protected $helper;
+
+ /**
+ * action_plugin_farmer_startup constructor.
+ */
+ public function __construct() {
+ $this->helper = plugin_load('helper', 'farmer');
+ }
+
+ /**
+ * plugin should use this method to register its handlers with the DokuWiki's event controller
+ *
+ * @param Doku_Event_Handler $controller DokuWiki's event controller object. Also available as global $EVENT_HANDLER
+ *
+ */
+ public function register(Doku_Event_Handler $controller) {
+ $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'before_start');
+ }
+
+ public function before_start(Doku_Event $event, $param) {
+ if($this->helper->wasNotfound()) $this->handleNotFound();
+ }
+
+ /**
+ * Handles the animal not found case
+ *
+ * Will abort the current script unless the farmer is wanted
+ */
+ protected function handleNotFound() {
+ /** @noinspection PhpUnusedLocalVariableInspection */
+ global $conf, $lang;
+ $config = $this->helper->getConfig();
+ $show = $config['notfound']['show'];
+ $url = $config['notfound']['url'];
+ if($show == 'farmer') return;
+
+ if($show == '404' || $show == 'list') {
+ http_status(404);
+ $body = $this->locale_xhtml('notfound_' . $show);
+ /** @noinspection PhpUnusedLocalVariableInspection */
+ $title = '404';
+ if($show == 'list') {
+ /** @noinspection PhpUnusedLocalVariableInspection */
+ $body .= $this->animalList();
+ }
+
+ include __DIR__ . '/../includes/template.php';
+ exit;
+ }
+
+ if($show == 'redirect' && $url) {
+ send_redirect($url);
+ }
+ }
+
+ /**
+ * Retrun a HTML list of animals
+ *
+ * @return string
+ */
+ protected function animalList() {
+ $html = '<ul>';
+ $animals = $this->helper->getAllAnimals();
+ foreach($animals as $animal) {
+ $link = $this->helper->getAnimalURL($animal);
+ $html .= '<li><div class="li"><a href="' . $link . '">' . hsc($animal) . '</a></div></li>';
+ }
+ $html .= '</ul>';
+ return $html;
+ }
+
+}
+
diff --git a/platform/www/lib/plugins/farmer/admin.php b/platform/www/lib/plugins/farmer/admin.php
new file mode 100644
index 0000000..6f00039
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/admin.php
@@ -0,0 +1,115 @@
+<?php
+
+/**
+ * DokuWiki Plugin farmer (Admin Component)
+ *
+ * This is the main admin page. It displays the tabs and then loads the sub components
+ * according to the selected tab
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+class admin_plugin_farmer extends DokuWiki_Admin_Plugin {
+
+ /** @var helper_plugin_farmer */
+ protected $helper;
+ /** @var array The available pages for the current user in the current wiki */
+ protected $pages;
+ /** @var string The currently selected page */
+ protected $page;
+ /** @var DokuWiki_Admin_Plugin the plugin to use for the current page */
+ protected $adminplugin;
+
+ /**
+ * @return bool we're available for managers and admins
+ */
+ public function forAdminOnly() {
+ return false;
+ }
+
+ /**
+ * Initialize current page
+ */
+ public function __construct() {
+ global $INPUT;
+ $this->helper = plugin_load('helper', 'farmer');
+
+ // set available pages depending on user and animal
+ $isanimal = (bool) $this->helper->getAnimal();
+ if($isanimal || !auth_isadmin()) {
+ $this->pages = array(
+ 'info'
+ );
+ } else {
+ if(!$this->helper->checkFarmSetup()) {
+ $this->pages = array(
+ 'setup'
+ );
+ } else {
+ $this->pages = array(
+ 'info',
+ 'config',
+ 'new',
+ 'plugins',
+ 'delete'
+ );
+ }
+ }
+
+ // make sure current page requested is available
+ $this->page = $INPUT->str('sub');
+ if(!in_array($this->page, $this->pages)) {
+ $this->page = $this->pages[0];
+ }
+
+ // load the sub component
+ $this->adminplugin = plugin_load('admin', 'farmer_' . $this->page);
+ if(!$this->adminplugin) nice_die('Something went wrong loading the plugin component for ' . hsc($this->page));
+ }
+
+ /**
+ * handle user request
+ */
+ public function handle() {
+ $this->adminplugin->handle();
+ }
+
+ /**
+ * output appropriate tab
+ */
+ public function html() {
+ global $ID;
+
+ echo '<div id="plugin__farmer_admin">';
+ echo '<h1>' . $this->getLang('menu') . '</h1>';
+
+ echo '<ul class="tabs" id="plugin__farmer_tabs">';
+ foreach($this->pages as $page) {
+ $link = wl($ID, array('do' => 'admin', 'page' => 'farmer', 'sub' => $page));
+ $class = ($page == $this->page) ? 'active' : '';
+
+ echo '<li class="' . $class . '"><a href="' . $link . '">' . $this->getLang('tab_' . $page) . '</a></li>';
+ }
+ echo '</ul>';
+ echo '<div class="panelHeader">';
+ echo $this->locale_xhtml('tab_' . $this->page);
+ echo '</div>';
+ echo '<div class="panelMain">';
+ $this->adminplugin->html();
+ echo '</div>';
+ echo '<div class="panelFooter">';
+ echo $this->locale_xhtml('tab_' . $this->page . '_help');
+ echo '</div>';
+ echo '</div>';
+ }
+
+ /**
+ * @return int
+ */
+ public function getMenuSort() {
+ return 42;
+ }
+
+}
+
diff --git a/platform/www/lib/plugins/farmer/admin.svg b/platform/www/lib/plugins/farmer/admin.svg
new file mode 100644
index 0000000..e774207
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/admin.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10.5 18a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5.5.5 0 0 1-.5-.5.5.5 0 0 1 .5-.5m3 0a.5.5 0 0 1 .5.5.5.5 0 0 1-.5.5.5.5 0 0 1-.5-.5.5.5 0 0 1 .5-.5M10 11a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m4 0a1 1 0 0 1 1 1 1 1 0 0 1-1 1 1 1 0 0 1-1-1 1 1 0 0 1 1-1m4 7c0 2.21-2.69 4-6 4s-6-1.79-6-4c0-.9.45-1.73 1.2-2.4-.75-1-1.2-2.25-1.2-3.6l.12-1.22c-.54.15-1.19.15-1.72 0-1.02-.28-2.56-1.43-2.33-2.23.23-.8 2.14-.95 3.16-.65.59.17 1.22.6 1.59 1.06l.57-.81C6.79 7.05 7 4 10 3l-.09.14c-.28.44-1 1.83-.24 3.33a6.02 6.02 0 0 1 4.66 0c.76-1.5.04-2.89-.24-3.33L14 3c3 1 3.21 4.05 2.61 5.15l.57.81c.37-.46 1-.89 1.59-1.06 1.02-.3 2.93-.15 3.16.65.23.8-1.31 1.95-2.33 2.23-.53.15-1.18.15-1.72 0L18 12c0 1.35-.45 2.6-1.2 3.6.75.67 1.2 1.5 1.2 2.4m-6-2c-2.21 0-4 .9-4 2s1.79 2 4 2 4-.9 4-2-1.79-2-4-2m0-2c1.12 0 2.17.21 3.07.56.58-.69.93-1.56.93-2.56a4 4 0 0 0-4-4 4 4 0 0 0-4 4c0 1 .35 1.87.93 2.56.9-.35 1.95-.56 3.07-.56m2.09-10.86z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/plugins/farmer/admin/config.php b/platform/www/lib/plugins/farmer/admin/config.php
new file mode 100644
index 0000000..7d79970
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/admin/config.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * DokuWiki Plugin farmer (Admin Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+use dokuwiki\Form\Form;
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Configuration Interface for farm.ini
+ */
+class admin_plugin_farmer_config extends DokuWiki_Admin_Plugin {
+
+ /** @var helper_plugin_farmer */
+ protected $helper;
+
+ /**
+ * @return bool admin only!
+ */
+ public function forAdminOnly() {
+ return false;
+ }
+
+ /**
+ * admin_plugin_farmer_config constructor.
+ */
+ public function __construct() {
+ $this->helper = plugin_load('helper', 'farmer');
+ }
+
+ /**
+ * Should carry out any processing required by the plugin.
+ */
+ public function handle() {
+ global $INPUT;
+ global $ID;
+ if(!$INPUT->has('farmconf')) return;
+ if(!checkSecurityToken()) return;
+
+ $farmconf = $this->helper->getConfig();
+ $farmdir = $farmconf['base']['farmdir'];
+ $farmconf = array_merge($farmconf, $INPUT->arr('farmconf'));
+ $farmconf['base']['farmdir'] = $farmdir;
+
+ $farmconf['base']['basedomain'] = trim(trim($farmconf['base']['basedomain'], '.'));
+
+ $ini = DOKU_INC . 'conf/farm.ini';
+ $data = "; Farm config created by the farmer plugin\n";
+ $data .= $this->createIni($farmconf);
+ io_saveFile($ini, $data);
+
+ $self = wl($ID, array('do' => 'admin', 'page' => 'farmer', 'sub' => 'config'), true, '&');
+ send_redirect($self);
+ }
+
+ /**
+ * Render HTML output, e.g. helpful text and a form
+ */
+ public function html() {
+ $farmconf = $this->helper->getConfig();
+
+ $form = new Form(array('method' => 'post'));
+
+ $form->addFieldsetOpen($this->getLang('base'));
+ $form->addHTML('<label><span>' . $this->getLang('farm dir') . '</span>' . DOKU_FARMDIR);
+ $form->addTextInput('farmconf[base][farmhost]', $this->getLang('farm host'))->val($farmconf['base']['farmhost']);
+ $form->addTextInput('farmconf[base][basedomain]', $this->getLang('base domain'))->val($farmconf['base']['basedomain']);
+ $form->addFieldsetClose();
+
+ $form->addFieldsetOpen($this->getLang('conf_inherit'));
+ foreach($farmconf['inherit'] as $key => $val) {
+ $form->setHiddenField("farmconf[inherit][$key]", 0);
+ $chk = $form->addCheckbox("farmconf[inherit][$key]", $this->getLang('conf_inherit_' . $key))->useInput(false);
+ if($val) $chk->attr('checked', 'checked');
+ }
+ $form->addFieldsetClose();
+
+ $options = array(
+ 'farmer' => $this->getLang('conf_notfound_farmer'),
+ '404' => $this->getLang('conf_notfound_404'),
+ 'list' => $this->getLang('conf_notfound_list'),
+ 'redirect' => $this->getLang('conf_notfound_redirect')
+ );
+
+ $form->addFieldsetOpen($this->getLang('conf_notfound'));
+ $form->addDropdown('farmconf[notfound][show]', $options, $this->getLang('conf_notfound'))->val($farmconf['notfound']['show']);
+ $form->addTextInput('farmconf[notfound][url]', $this->getLang('conf_notfound_url'))->val($farmconf['notfound']['url']);
+ $form->addFieldsetClose();
+
+ $form->addButton('save', $this->getLang('save'));
+ echo $form->toHTML();
+ }
+
+ /**
+ * Simple function to create an ini file
+ *
+ * Does no escaping, but should suffice for our use case
+ *
+ * @link http://stackoverflow.com/a/5695202/172068
+ * @param array $data The data to transform
+ * @return string
+ */
+ public function createIni($data) {
+ $res = array();
+ foreach($data as $key => $val) {
+ if(is_array($val)) {
+ $res[] = '';
+ $res[] = "[$key]";
+ foreach($val as $skey => $sval) {
+ $res[] = "$skey = " . (is_numeric($sval) ? $sval : '"' . $sval . '"');
+ }
+ } else {
+ $res[] = "$key = " . (is_numeric($val) ? $val : '"' . $val . '"');
+ }
+ }
+ $res[] = '';
+ return join("\n", $res);
+ }
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/farmer/admin/delete.php b/platform/www/lib/plugins/farmer/admin/delete.php
new file mode 100644
index 0000000..d8b3450
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/admin/delete.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * DokuWiki Plugin farmer (Admin Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+// must be run within Dokuwiki
+use dokuwiki\Form\Form;
+
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Information about the farm and the current instance
+ */
+class admin_plugin_farmer_delete extends DokuWiki_Admin_Plugin {
+
+ /** @var helper_plugin_farmer */
+ protected $helper;
+
+ /**
+ * admin_plugin_farmer_info constructor.
+ */
+ public function __construct() {
+ $this->helper = plugin_load('helper', 'farmer');
+ }
+
+ /**
+ * @return bool admin only!
+ */
+ public function forAdminOnly() {
+ return true;
+ }
+
+ /**
+ * Should carry out any processing required by the plugin.
+ */
+ public function handle() {
+ global $INPUT;
+ global $ID;
+ if(!$INPUT->has('delete')) return;
+
+ if($INPUT->filter('trim')->str('delanimal') === '') {
+ msg($this->getLang('delete_noanimal'), -1);
+ return;
+ }
+
+ if($INPUT->str('delanimal') != $INPUT->str('confirm')) {
+ msg($this->getLang('delete_mismatch'), -1);
+ return;
+ }
+
+ $animaldir = DOKU_FARMDIR . $INPUT->str('delanimal');
+
+ if(!$this->helper->isInPath($animaldir, DOKU_FARMDIR) || !is_dir($animaldir)) {
+ msg($this->getLang('delete_invalid'), -1);
+ return;
+ }
+
+ // let's delete it
+ $ok = io_rmdir($animaldir, true);
+ if($ok) {
+ msg($this->getLang('delete_success'), 1);
+ } else {
+ msg($this->getLang('delete_fail'), -1);
+ }
+
+ $link = wl($ID, array('do'=>'admin', 'page'=>'farmer', 'sub' => 'delete'), true, '&');
+ send_redirect($link);
+ }
+
+ /**
+ * Render HTML output, e.g. helpful text and a form
+ */
+ public function html() {
+
+ $form = new Form();
+ $form->addFieldsetOpen($this->getLang('delete_animal'));
+
+ $animals = $this->helper->getAllAnimals();
+ array_unshift($animals, '');
+ $form->addDropdown('delanimal', $animals)->addClass('farmer_chosen_animals');
+ $form->addTextInput('confirm', $this->getLang('delete_confirm'));
+ $form->addButton('delete', $this->getLang('delete'));
+ $form->addFieldsetClose();
+ echo $form->toHTML();
+
+ }
+
+
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/farmer/admin/info.php b/platform/www/lib/plugins/farmer/admin/info.php
new file mode 100644
index 0000000..3bf2938
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/admin/info.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * DokuWiki Plugin farmer (Admin Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Information about the farm and the current instance
+ */
+class admin_plugin_farmer_info extends DokuWiki_Admin_Plugin {
+
+ /** @var helper_plugin_farmer */
+ protected $helper;
+
+ /**
+ * admin_plugin_farmer_info constructor.
+ */
+ public function __construct() {
+ $this->helper = plugin_load('helper', 'farmer');
+ }
+
+ /**
+ * @return bool admin only!
+ */
+ public function forAdminOnly() {
+ return false;
+ }
+
+ /**
+ * Should carry out any processing required by the plugin.
+ */
+ public function handle() {
+ }
+
+ /**
+ * Render HTML output, e.g. helpful text and a form
+ */
+ public function html() {
+ global $conf;
+ global $INPUT;
+
+ $animal = $this->helper->getAnimal();
+ $config = $this->helper->getConfig();
+
+ echo '<table class="inline">';
+
+ $this->line('thisis', $animal ? $this->getLang('thisis.animal') : $this->getLang('thisis.farmer'));
+ if($animal) {
+ $this->line('animal', $animal);
+ }
+ $this->line('confdir', fullpath(DOKU_CONF) . '/');
+ $this->line('savedir', fullpath($conf['savedir']) . '/');
+ $this->line('baseinstall', DOKU_INC);
+ $this->line('farm host', $config['base']['farmhost']);
+ $this->line('farm dir', DOKU_FARMDIR);
+
+ $this->line('animals', $this->animals($INPUT->bool('list')));
+
+ foreach($config['inherit'] as $key => $value) {
+ $this->line('conf_inherit_' . $key, $this->getLang($value ? 'conf_inherit_yes' : 'conf_inherit_no'));
+ }
+
+ $this->line('plugins', join(', ', $this->helper->getAllPlugins(false)));
+
+ echo '</table>';
+ }
+
+ /**
+ * List or count the animals
+ *
+ * @param bool $list
+ * @return string
+ */
+ protected function animals($list) {
+ global $ID;
+
+ $animals = $this->helper->getAllAnimals();
+ $html = '';
+ if(!$list) {
+ $html = count($animals);
+ $self = wl($ID, array('do' => 'admin', 'page' => 'farmer', 'sub' => 'info', 'list' => 1));
+ $html .= ' [<a href="' . $self . '">' . $this->getLang('conf_notfound_list') . '</a>]';
+ return $html;
+ }
+
+ $html .= '<ol>';
+ foreach($animals as $animal) {
+ $link = $this->helper->getAnimalURL($animal);
+ $html .= '<li><div class="li"><a href="' . $link . '">' . $animal . '</a></div></li>';
+ }
+ $html .= '</ol>';
+ return $html;
+ }
+
+ /**
+ * Output a table line
+ *
+ * @param string $langkey
+ * @param string $value
+ */
+ protected function line($langkey, $value) {
+ echo '<tr>';
+ echo '<th>' . $this->getLang($langkey) . '</th>';
+ echo '<td>' . $value . '</td>';
+ echo '</tr>';
+ }
+
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/farmer/admin/new.php b/platform/www/lib/plugins/farmer/admin/new.php
new file mode 100644
index 0000000..8cbf94f
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/admin/new.php
@@ -0,0 +1,338 @@
+<?php
+/**
+ * DokuWiki Plugin farmer (Admin Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ */
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+class admin_plugin_farmer_new extends DokuWiki_Admin_Plugin {
+
+ /** @var helper_plugin_farmer $helper */
+ protected $helper;
+
+ /**
+ * @return bool true if only access for superuser, false is for superusers and moderators
+ */
+ public function forAdminOnly() {
+ return true;
+ }
+
+ /**
+ * admin_plugin_farmer_new constructor.
+ */
+ public function __construct() {
+ $this->helper = plugin_load('helper', 'farmer');
+ }
+
+ /**
+ * Should carry out any processing required by the plugin.
+ */
+ public function handle() {
+ global $INPUT;
+ global $ID;
+ if(!$INPUT->has('farmer__submit')) return;
+
+ $data = $this->validateAnimalData();
+ if(!$data) return;
+ if($this->createNewAnimal($data['name'], $data['admin'], $data['pass'], $data['template'], $data['aclpolicy'], $data['allowreg'])) {
+ $url = $this->helper->getAnimalURL($data['name']);
+ $link = '<a href="' . $url . '">' . hsc($data['name']) . '</a>';
+
+ msg(sprintf($this->getLang('animal creation success'), $link), 1);
+ $link = wl($ID, array('do' => 'admin', 'page' => 'farmer', 'sub' => 'new'), true, '&');
+ send_redirect($link);
+ }
+ }
+
+ /**
+ * Render HTML output, e.g. helpful text and a form
+ */
+ public function html() {
+ global $lang;
+ $farmconfig = $this->helper->getConfig();
+
+ $form = new \dokuwiki\Form\Form();
+ $form->addClass('plugin_farmer')->id('farmer__create_animal_form');
+
+ $form->addFieldsetOpen($this->getLang('animal configuration'));
+ $form->addTextInput('animalname', $this->getLang('animal'));
+ $form->addFieldsetClose();
+
+ $animals = $this->helper->getAllAnimals();
+ array_unshift($animals, '');
+ $form->addFieldsetOpen($this->getLang('animal template'));
+ $form->addDropdown('animaltemplate', $animals)->addClass('farmer_chosen_animals');
+ $form->addFieldsetClose();
+
+ $form->addFieldsetOpen($lang['i_policy'])->attr('id', 'aclPolicyFieldset');
+ $policyOptions = array('open' => $lang['i_pol0'],'public' => $lang['i_pol1'], 'closed' => $lang['i_pol2']);
+ $form->addDropdown('aclpolicy', $policyOptions)->addClass('acl_chosen');
+ if ($farmconfig['inherit']['main']) {
+ $form->addRadioButton('allowreg',$this->getLang('inherit user registration'))->val('inherit')->attr('checked', 'checked');
+ $form->addRadioButton('allowreg',$this->getLang('enable user registration'))->val('allow');
+ $form->addRadioButton('allowreg',$this->getLang('disable user registration'))->val('disable');
+ } else {
+ $form->addCheckbox('allowreg', $lang['i_allowreg'])->attr('checked', 'checked');
+ }
+
+ $form->addFieldsetClose();
+
+ $form->addFieldsetOpen($this->getLang('animal administrator'));
+ $btn = $form->addRadioButton('adminsetup', $this->getLang('noUsers'))->val('noUsers');
+ if($farmconfig['inherit']['users']) {
+ $btn->attr('checked', 'checked'); // default when inherit available
+ } else {
+ // no user copying when inheriting
+ $form->addRadioButton('adminsetup', $this->getLang('importUsers'))->val('importUsers');
+ $form->addRadioButton('adminsetup', $this->getLang('currentAdmin'))->val('currentAdmin');
+ }
+ $btn = $form->addRadioButton('adminsetup', $this->getLang('newAdmin'))->val('newAdmin');
+ if(!$farmconfig['inherit']['users']) {
+ $btn->attr('checked', 'checked'); // default when inherit not available
+ }
+ $form->addPasswordInput('adminPassword', $this->getLang('admin password'));
+ $form->addFieldsetClose();
+
+ $form->addButton('farmer__submit', $this->getLang('submit'))->attr('type', 'submit')->val('newAnimal');
+ echo $form->toHTML();
+ }
+
+ /**
+ * Validate the data for a new animal
+ *
+ * @return array|bool false on errors, clean data otherwise
+ */
+ protected function validateAnimalData() {
+ global $INPUT;
+
+ $animalname = $INPUT->filter('trim')->str('animalname');
+ $adminsetup = $INPUT->str('adminsetup');
+ $adminpass = $INPUT->filter('trim')->str('adminPassword');
+ $template = $INPUT->filter('trim')->str('animaltemplate');
+ $aclpolicy = $INPUT->filter('trim')->str('aclpolicy');
+ $allowreg = $INPUT->str('allowreg');
+
+ $errors = array();
+
+ if($animalname === '') {
+ $errors[] = $this->getLang('animalname_missing');
+ } elseif(!$this->helper->validateAnimalName($animalname)) {
+ $errors[] = $this->getLang('animalname_invalid');
+ }
+
+ if($adminsetup === 'newAdmin' && $adminpass === '') {
+ $errors[] = $this->getLang('adminPassword_empty');
+ }
+
+ if($animalname !== '' && file_exists(DOKU_FARMDIR . '/' . $animalname)) {
+ $errors[] = $this->getLang('animalname_preexisting');
+ }
+
+ if (!is_dir(DOKU_FARMDIR . $template) && !in_array($aclpolicy,array('open', 'public', 'closed'))) {
+ $errors[] = $this->getLang('aclpolicy missing/bad');
+ }
+
+ if($errors) {
+ foreach($errors as $error) {
+ msg($error, -1);
+ }
+ return false;
+ }
+
+ if(!is_dir(DOKU_FARMDIR . $template)) {
+ $template = '';
+ }
+ if ($template != '') {
+ $aclpolicy = '';
+ }
+
+ return array(
+ 'name' => $animalname,
+ 'admin' => $adminsetup,
+ 'pass' => $adminpass,
+ 'template' => $template,
+ 'aclpolicy' => $aclpolicy,
+ 'allowreg' => $allowreg
+ );
+ }
+
+ /**
+ * Create a new animal
+ *
+ * @param string $name name/title of the animal, will be the directory name for htaccess setup
+ * @param string $adminSetup newAdmin, currentAdmin or importUsers
+ * @param string $adminPassword required if $adminSetup is newAdmin
+ * @param string $template name of animal to copy
+ * @param $aclpolicy
+ * @param $userreg
+ * @return bool true if successful
+ * @throws Exception
+ */
+ protected function createNewAnimal($name, $adminSetup, $adminPassword, $template, $aclpolicy, $userreg) {
+ $animaldir = DOKU_FARMDIR . $name;
+
+ // copy basic template
+ $ok = $this->helper->io_copyDir(__DIR__ . '/../_animal', $animaldir);
+ if(!$ok) {
+ msg($this->getLang('animal creation error'), -1);
+ return false;
+ }
+
+ // copy animal template
+ if($template != '') {
+ foreach(array('conf', 'data/pages', 'data/media', 'data/meta', 'data/media_meta', 'index') as $dir) {
+ $templatedir = DOKU_FARMDIR . $template . '/' . $dir;
+ if(!is_dir($templatedir)) continue;
+ // do not copy changelogs in meta
+ if(substr($dir, -4) == 'meta') {
+ $exclude = '/\.changes$/';
+ } else {
+ $exclude = '';
+ }
+ if(!$this->helper->io_copyDir($templatedir, $animaldir . '/' . $dir, $exclude)) {
+ msg(sprintf($this->getLang('animal template copy error'), $dir), -1);
+ // we go on anyway
+ }
+ }
+ }
+
+ // append title to local config
+ $ok &= io_saveFile($animaldir . '/conf/local.php', "\n" . '$conf[\'title\'] = \'' . $name . '\';' . "\n", true);
+
+ // create a random logo and favicon
+ if(!class_exists('\splitbrain\RingIcon\RingIcon', false)) {
+ require(__DIR__ . '/../3rdparty/RingIcon.php');
+ }
+ if(!class_exists('\chrisbliss18\phpico\PHPIco', false)) {
+ require(__DIR__ . '/../3rdparty/PHPIco.php');
+ }
+ try {
+ if(function_exists('imagecreatetruecolor')) {
+ $logo = $animaldir . '/data/media/wiki/logo.png';
+ if(!file_exists($logo)) {
+ $ringicon = new \splitbrain\RingIcon\RingIcon(64);
+ $ringicon->createImage($animaldir, $logo);
+ }
+
+ $icon = $animaldir . '/data/media/wiki/favicon.ico';
+ if(!file_exists($icon)) {
+ $icongen = new \chrisbliss18\phpico\PHPIco($logo);
+ $icongen->save_ico($icon);
+ }
+ }
+ } catch(\Exception $ignore) {
+ // something went wrong, but we don't care. this is a nice to have feature only
+ }
+
+ // create admin user
+ if($adminSetup === 'newAdmin') {
+ $users = "# <?php exit()?>\n" . $this->makeAdminLine($adminPassword) . "\n";
+ } elseif($adminSetup === 'currentAdmin') {
+ $users = "# <?php exit()?>\n" . $this->getAdminLine() . "\n";
+ } elseif($adminSetup === 'noUsers') {
+ if(file_exists($animaldir . '/conf/users.auth.php')) {
+ // a user file exists already, probably from animal template - don't overwrite
+ $users = '';
+ } else {
+ // create empty user file
+ $users = "# <?php exit()?>\n";
+ }
+ } else {
+ $users = io_readFile(DOKU_CONF . 'users.auth.php');
+ }
+ if($users) {
+ $ok &= io_saveFile($animaldir . '/conf/users.auth.php', $users);
+ }
+
+ if ($aclpolicy != '') {
+ $aclfile = file($animaldir . '/conf/acl.auth.php');
+ $aclfile = array_map('trim', $aclfile);
+ array_pop($aclfile);
+ switch ($aclpolicy) {
+ case 'open':
+ $aclfile[] = "* @ALL 8";
+ break;
+ case 'public':
+ $aclfile[] = "* @ALL 1";
+ $aclfile[] = "* @user 8";
+ break;
+ case 'closed':
+ $aclfile[] = "* @ALL 0";
+ $aclfile[] = "* @user 8";
+ break;
+ default:
+ throw new Exception('Undefined aclpolicy given');
+ }
+ $ok &= io_saveFile($animaldir . '/conf/acl.auth.php', join("\n", $aclfile)."\n");
+
+ global $conf;
+ switch ($userreg) {
+ case 'allow':
+ $disableactions = join(',', array_diff(explode(',', $conf['disableactions']), array('register')));
+ $ok &= io_saveFile($animaldir . '/conf/local.php', "\n" . '$conf[\'disableactions\'] = \''.$disableactions.'\';' . "\n", true);
+ break;
+ case 'disable':
+ $disableactions = join(',', array_merge(explode(',', $conf['disableactions']), array('register')));
+ $ok &= io_saveFile($animaldir . '/conf/local.php', "\n" . '$conf[\'disableactions\'] = \''.$disableactions.'\';' . "\n", true);
+ break;
+ case 'inherit':
+ case true:
+ // nothing needs to be done
+ break;
+ default:
+ $ok &= io_saveFile($animaldir . '/conf/local.php', "\n" . '$conf[\'disableactions\'] = \'register\';' . "\n", true);
+ }
+ }
+
+ // deactivate plugins by default FIXME this should be nicer
+ $deactivatedPluginsList = explode(',', $this->getConf('deactivated plugins'));
+ $deactivatedPluginsList = array_map('trim', $deactivatedPluginsList);
+ $deactivatedPluginsList = array_unique($deactivatedPluginsList);
+ $deactivatedPluginsList = array_filter($deactivatedPluginsList);
+ foreach($deactivatedPluginsList as $plugin) {
+ $this->helper->setPluginState(trim($plugin), $name, 0);
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Creates a new user line
+ *
+ * @param $password
+ * @return string
+ */
+ protected function makeAdminLine($password) {
+ $pass = auth_cryptPassword($password);
+ $line = join(
+ ':', array(
+ 'admin',
+ $pass,
+ 'Administrator',
+ 'admin@example.org',
+ 'admin,user'
+ )
+ );
+ return $line;
+ }
+
+ /**
+ * Copies the current user as new admin line
+ *
+ * @return string
+ */
+ protected function getAdminLine() {
+ $currentAdmin = $_SERVER['REMOTE_USER'];
+ $masterUsers = file_get_contents(DOKU_CONF . 'users.auth.php');
+ $masterUsers = ltrim(strstr($masterUsers, "\n" . $currentAdmin . ":"));
+ $newAdmin = substr($masterUsers, 0, strpos($masterUsers, "\n") + 1);
+ return $newAdmin;
+ }
+
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/farmer/admin/plugins.php b/platform/www/lib/plugins/farmer/admin/plugins.php
new file mode 100644
index 0000000..74f0e60
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/admin/plugins.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * DokuWiki Plugin farmer (Admin Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Manage Animal Plugin settings
+ */
+class admin_plugin_farmer_plugins extends DokuWiki_Admin_Plugin {
+
+ /** @var helper_plugin_farmer $helper */
+ private $helper;
+
+ public function __construct() {
+ $this->helper = plugin_load('helper', 'farmer');
+ }
+
+ /**
+ * handle user request
+ */
+ public function handle() {
+ global $INPUT;
+ global $ID;
+
+ $self = wl($ID, array('do' => 'admin', 'page' => 'farmer', 'sub' => 'plugins'), true, '&');
+
+ if($INPUT->has('bulk_plugin') && $INPUT->has('state')) {
+ $animals = $this->helper->getAllAnimals();
+ $plugin = $INPUT->str('bulk_plugin');
+ foreach($animals as $animal) {
+ $this->helper->setPluginState($plugin, $animal, $INPUT->int('state'));
+ }
+ msg($this->getLang('plugindone'), 1);
+ send_redirect($self);
+ }
+
+ if($INPUT->has('bulk_animal') && $INPUT->has('bulk_plugins')) {
+ $animal = $INPUT->str('bulk_animal');
+ $activePlugins = $INPUT->arr('bulk_plugins');
+ foreach($activePlugins as $plugin => $state) {
+ $this->helper->setPluginState($plugin, $animal, $state);
+ }
+ msg($this->getLang('plugindone'), 1);
+ send_redirect($self);
+ }
+ }
+
+ /**
+ * output appropriate html
+ */
+ public function html() {
+
+ echo $this->locale_xhtml('plugins');
+ $switchForm = new \dokuwiki\Form\Form();
+ $switchForm->addClass('plugin_farmer');
+ $switchForm->addFieldsetOpen($this->getLang('bulkSingleSwitcher'));
+ $switchForm->addRadioButton('bulkSingleSwitch', $this->getLang('bulkEdit'))->id('farmer__bulk')->attr('type', 'radio');
+ $switchForm->addRadioButton('bulkSingleSwitch', $this->getLang('singleEdit'))->id('farmer__single')->attr('type', 'radio');
+ $switchForm->addRadioButton('bulkSingleSwitch', $this->getLang('matrixEdit'))->id('farmer__matrix')->attr('type', 'radio');
+ $switchForm->addFieldsetClose();
+ echo $switchForm->toHTML();
+
+ /** @var helper_plugin_farmer $helper */
+ $helper = plugin_load('helper', 'farmer');
+ $plugins = $helper->getAllPlugins();
+ array_unshift($plugins, '');
+
+ // All Animals at once
+ $bulkForm = new \dokuwiki\Form\Form();
+ $bulkForm->id('farmer__pluginsforall');
+ $bulkForm->addFieldsetOpen($this->getLang('bulkEditForm'));
+ $bulkForm->addDropdown('bulk_plugin', $plugins);
+ $bulkForm->addButton('state', $this->getLang('default'))->attr('value', '-1')->attr('type', 'submit')->attr('disabled', 'disabled');
+ $bulkForm->addButton('state', $this->getLang('activate'))->attr('value', '1')->attr('type', 'submit')->attr('disabled', 'disabled');
+ $bulkForm->addButton('state', $this->getLang('deactivate'))->attr('value', '0')->attr('type', 'submit')->attr('disabled', 'disabled');
+ $bulkForm->addFieldsetClose();
+ echo $bulkForm->toHTML();
+
+ $animals = $helper->getAllAnimals();
+ array_unshift($animals, '');
+
+ // One Animal, all the plugins
+ $singleForm = new \dokuwiki\Form\Form();
+ $singleForm->id('farmer__pluginsforone');
+ $singleForm->addFieldsetOpen($this->getLang('singleEditForm'));
+ $singleForm->addDropdown('bulk_animal', $animals);
+ $singleForm->addTagOpen('div')->addClass('output');
+ $singleForm->addTagClose('div');
+ $singleForm->addButton('save', $this->getLang('save'))->attr('disabled', 'disabled');
+
+ echo $singleForm->toHTML();
+
+
+ echo '<div id="farmer__pluginmatrix"></div>';
+ }
+}
+
diff --git a/platform/www/lib/plugins/farmer/admin/setup.php b/platform/www/lib/plugins/farmer/admin/setup.php
new file mode 100644
index 0000000..f836ae5
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/admin/setup.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * DokuWiki Plugin farmer (Admin Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Setup the farm by creating preload.php etc
+ */
+class admin_plugin_farmer_setup extends DokuWiki_Admin_Plugin {
+
+ /** @var helper_plugin_farmer $helper */
+ private $helper;
+
+ /**
+ * @return bool admin only!
+ */
+ public function forAdminOnly() {
+ return true;
+ }
+
+ /**
+ * Should carry out any processing required by the plugin.
+ */
+ public function handle() {
+ global $INPUT;
+ global $ID;
+
+ if(!$INPUT->bool('farmdir')) return;
+ if(!checkSecurityToken()) return;
+
+ $this->helper = plugin_load('helper', 'farmer');
+
+ $farmdir = trim($INPUT->str('farmdir', ''));
+ if($farmdir[0] !== '/') $farmdir = DOKU_INC . $farmdir;
+ $farmdir = fullpath($farmdir);
+
+ $errors = array();
+ if($farmdir === '') {
+ $errors[] = $this->getLang('farmdir_missing');
+ } elseif($this->helper->isInPath($farmdir, DOKU_INC) !== false) {
+ $errors[] = sprintf($this->getLang('farmdir_in_dokuwiki'), hsc($farmdir), hsc(DOKU_INC));
+ } elseif(!io_mkdir_p($farmdir)) {
+ $errors[] = sprintf($this->getLang('farmdir_uncreatable'), hsc($farmdir));
+ } elseif(!is_writeable($farmdir)) {
+ $errors[] = sprintf($this->getLang('farmdir_unwritable'), hsc($farmdir));
+ } elseif(count(scandir($farmdir)) > 2) {
+ $errors[] = sprintf($this->getLang('farmdir_notEmpty'), hsc($farmdir));
+ }
+
+ if($errors) {
+ foreach($errors as $error) {
+ msg($error, -1);
+ }
+ return;
+ }
+
+ // create the files
+ $ok = $this->createPreloadPHP();
+ if($ok && $INPUT->bool('htaccess')) $ok &= $this->createHtaccess();
+ if($ok) $ok &= $this->createFarmIni($farmdir);
+
+ if($ok) {
+ msg($this->getLang('preload creation success'), 1);
+ $link = wl($ID, array('do' => 'admin', 'page' => 'farmer', 'sub' => 'config'), true, '&');
+ send_redirect($link);
+ } else {
+ msg($this->getLang('preload creation error'), -1);
+ }
+ }
+
+ /**
+ * Render HTML output, e.g. helpful text and a form
+ */
+ public function html() {
+ // Is preload.php already enabled?
+ if(file_exists(DOKU_INC . 'inc/preload.php')) {
+ msg($this->getLang('overwrite_preload'), -1);
+ }
+
+ $form = new \dokuwiki\Form\Form();
+ $form->addClass('plugin_farmer');
+ $form->addFieldsetOpen($this->getLang('preloadPHPForm'));
+ $form->addTextInput('farmdir', $this->getLang('farm dir'));
+ $form->addCheckbox('htaccess', $this->getLang('htaccess setup'))->attr('checked', 'checked');
+ $form->addButton('farmer__submit', $this->getLang('submit'))->attr('type', 'submit');
+ $form->addFieldsetClose();
+ echo $form->toHTML();
+
+ }
+
+ /**
+ * Creates the preload that loads our farm controller
+ * @return bool true if saving was successful
+ */
+ protected function createPreloadPHP() {
+ $content = "<?php\n";
+ $content .= "# farm setup by farmer plugin\n";
+ $content .= "if(file_exists(__DIR__ . '/../lib/plugins/farmer/DokuWikiFarmCore.php')) {\n";
+ $content .= " include(__DIR__ . '/../lib/plugins/farmer/DokuWikiFarmCore.php');\n";
+ $content .= "}\n";
+ return io_saveFile(DOKU_INC . 'inc/preload.php', $content);
+ }
+
+ /**
+ * Prepends the needed config to the main .htaccess for htaccess type setups
+ *
+ * @return bool true if saving was successful
+ */
+ protected function createHtaccess() {
+ // load existing or template
+ if(file_exists(DOKU_INC . '.htaccess')) {
+ $old = io_readFile(DOKU_INC . '.htaccess');
+ } elseif(file_exists(DOKU_INC . '.htaccess.dist')) {
+ $old = io_readFile(DOKU_INC . '.htaccess.dist');
+ } else {
+ $old = '';
+ }
+
+ $content = "# Options added for farm setup by farmer plugin:\n";
+ $content .= "RewriteEngine On\n";
+ $content .= 'RewriteRule ^!([^/]+)/(.*) $2?animal=$1 [QSA,DPI]' . "\n";
+ $content .= 'RewriteRule ^!([^/]+)$ ?animal=$1 [QSA,DPI]' . "\n";
+ $content .= 'Options +FollowSymLinks' . "\n";
+ $content .= '# end of farm configuration' . "\n\n";
+ $content .= $old;
+ return io_saveFile(DOKU_INC . '.htaccess', $content);
+ }
+
+ /**
+ * Creates the initial configuration
+ *
+ * @param $animalpath
+ * @return bool true if saving was successful
+ */
+ protected function createFarmIni($animalpath) {
+ $content = "; farm config created by the farmer plugin\n\n";
+ $content .= "[base]\n";
+ $content .= "farmdir = $animalpath\n";
+ $content .= "farmhost = {$_SERVER['HTTP_HOST']}\n";
+ return io_saveFile(DOKU_INC . 'conf/farm.ini', $content);
+ }
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/farmer/all.less b/platform/www/lib/plugins/farmer/all.less
new file mode 100644
index 0000000..effff6f
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/all.less
@@ -0,0 +1,13 @@
+@import "css/chosen.less";
+
+.chosen-container-single .chosen-single abbr,
+.chosen-container-single .chosen-single div b,
+.chosen-container-single .chosen-search input[type="text"],
+.chosen-container-multi .chosen-choices li.search-choice .search-choice-close,
+.chosen-rtl .chosen-search input[type="text"] {
+ background-image: url(css/chosen-sprite.png);
+}
+
+@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi), only screen and (min-resolution: 1.5dppx) {
+ background-image: url(css/chosen-sprite.png);
+}
diff --git a/platform/www/lib/plugins/farmer/conf/default.php b/platform/www/lib/plugins/farmer/conf/default.php
new file mode 100644
index 0000000..33e10d4
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/conf/default.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Default settings for the farmer plugin
+ *
+ * @author Michael Große <grosse@cosmocode.de>
+ */
+
+$conf['deactivated plugins'] = '';
+$conf['disable_new_plugins'] = 0;
diff --git a/platform/www/lib/plugins/farmer/conf/metadata.php b/platform/www/lib/plugins/farmer/conf/metadata.php
new file mode 100644
index 0000000..9b81338
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/conf/metadata.php
@@ -0,0 +1,9 @@
+<?php
+/**
+ * Options for the farmer plugin
+ *
+ * @author Michael Große <grosse@cosmocode.de>
+ */
+
+$meta['deactivated plugins'] = array('string');
+$meta['disable_new_plugins'] = array('onoff');
diff --git a/platform/www/lib/plugins/farmer/css/chosen-sprite.png b/platform/www/lib/plugins/farmer/css/chosen-sprite.png
new file mode 100644
index 0000000..c57da70
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/css/chosen-sprite.png
Binary files differ
diff --git a/platform/www/lib/plugins/farmer/css/chosen.less b/platform/www/lib/plugins/farmer/css/chosen.less
new file mode 100644
index 0000000..e7ea092
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/css/chosen.less
@@ -0,0 +1,450 @@
+/*!
+Chosen, a Select Box Enhancer for jQuery and Prototype
+by Patrick Filler for Harvest, http://getharvest.com
+
+Version 1.4.2
+Full source at https://github.com/harvesthq/chosen
+Copyright (c) 2011-2015 Harvest http://getharvest.com
+
+MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
+This file is generated by `grunt build`, do not edit it by hand.
+*/
+
+/* @group Base */
+.chosen-container {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+ font-size: 13px;
+ zoom: 1;
+ *display: inline;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+}
+.chosen-container * {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.chosen-container .chosen-drop {
+ position: absolute;
+ top: 100%;
+ left: -9999px;
+ z-index: 1010;
+ width: 100%;
+ border: 1px solid #aaa;
+ border-top: 0;
+ background: #fff;
+ box-shadow: 0 4px 5px rgba(0, 0, 0, 0.15);
+}
+.chosen-container.chosen-with-drop .chosen-drop {
+ left: 0;
+}
+.chosen-container a {
+ cursor: pointer;
+}
+.chosen-container .search-choice .group-name, .chosen-container .chosen-single .group-name {
+ margin-right: 4px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ font-weight: normal;
+ color: #999999;
+}
+.chosen-container .search-choice .group-name:after, .chosen-container .chosen-single .group-name:after {
+ content: ":";
+ padding-left: 2px;
+ vertical-align: top;
+}
+
+/* @end */
+/* @group Single Chosen */
+.chosen-container-single .chosen-single {
+ position: relative;
+ display: block;
+ overflow: hidden;
+ padding: 0 0 0 8px;
+ height: 25px;
+ border: 1px solid #aaa;
+ border-radius: 5px;
+ background-color: #fff;
+ background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
+ background: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+ background: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+ background: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+ background: linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
+ background-clip: padding-box;
+ box-shadow: 0 0 3px white inset, 0 1px 1px rgba(0, 0, 0, 0.1);
+ color: #444;
+ text-decoration: none;
+ white-space: nowrap;
+ line-height: 24px;
+}
+.chosen-container-single .chosen-default {
+ color: #999;
+}
+.chosen-container-single .chosen-single span {
+ display: block;
+ overflow: hidden;
+ margin-right: 26px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.chosen-container-single .chosen-single-with-deselect span {
+ margin-right: 38px;
+}
+.chosen-container-single .chosen-single abbr {
+ position: absolute;
+ top: 6px;
+ right: 26px;
+ display: block;
+ width: 12px;
+ height: 12px;
+ background: url('chosen-sprite.png') -42px 1px no-repeat;
+ font-size: 1px;
+}
+.chosen-container-single .chosen-single abbr:hover {
+ background-position: -42px -10px;
+}
+.chosen-container-single.chosen-disabled .chosen-single abbr:hover {
+ background-position: -42px -10px;
+}
+.chosen-container-single .chosen-single div {
+ position: absolute;
+ top: 0;
+ right: 0;
+ display: block;
+ width: 18px;
+ height: 100%;
+}
+.chosen-container-single .chosen-single div b {
+ display: block;
+ width: 100%;
+ height: 100%;
+ background: url('chosen-sprite.png') no-repeat 0px 2px;
+}
+.chosen-container-single .chosen-search {
+ position: relative;
+ z-index: 1010;
+ margin: 0;
+ padding: 3px 4px;
+ white-space: nowrap;
+}
+.chosen-container-single .chosen-search input[type="text"] {
+ margin: 1px 0;
+ padding: 4px 20px 4px 5px;
+ width: 100%;
+ height: auto;
+ outline: 0;
+ border: 1px solid #aaa;
+ background: white url('chosen-sprite.png') no-repeat 100% -20px;
+ background: url('chosen-sprite.png') no-repeat 100% -20px;
+ font-size: 1em;
+ font-family: sans-serif;
+ line-height: normal;
+ border-radius: 0;
+}
+.chosen-container-single .chosen-drop {
+ margin-top: -1px;
+ border-radius: 0 0 4px 4px;
+ background-clip: padding-box;
+}
+.chosen-container-single.chosen-container-single-nosearch .chosen-search {
+ position: absolute;
+ left: -9999px;
+}
+
+/* @end */
+/* @group Results */
+.chosen-container .chosen-results {
+ color: #444;
+ position: relative;
+ overflow-x: hidden;
+ overflow-y: auto;
+ margin: 0 4px 4px 0;
+ padding: 0 0 0 4px;
+ max-height: 240px;
+ -webkit-overflow-scrolling: touch;
+}
+.chosen-container .chosen-results li {
+ display: none;
+ margin: 0;
+ padding: 5px 6px;
+ list-style: none;
+ line-height: 15px;
+ word-wrap: break-word;
+ -webkit-touch-callout: none;
+}
+.chosen-container .chosen-results li.active-result {
+ display: list-item;
+ cursor: pointer;
+}
+.chosen-container .chosen-results li.disabled-result {
+ display: list-item;
+ color: #ccc;
+ cursor: default;
+}
+.chosen-container .chosen-results li.highlighted {
+ background-color: #3875d7;
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
+ background-image: -webkit-linear-gradient(#3875d7 20%, #2a62bc 90%);
+ background-image: -moz-linear-gradient(#3875d7 20%, #2a62bc 90%);
+ background-image: -o-linear-gradient(#3875d7 20%, #2a62bc 90%);
+ background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
+ color: #fff;
+}
+.chosen-container .chosen-results li.no-results {
+ color: #777;
+ display: list-item;
+ background: #f4f4f4;
+}
+.chosen-container .chosen-results li.group-result {
+ display: list-item;
+ font-weight: bold;
+ cursor: default;
+}
+.chosen-container .chosen-results li.group-option {
+ padding-left: 15px;
+}
+.chosen-container .chosen-results li em {
+ font-style: normal;
+ text-decoration: underline;
+}
+
+/* @end */
+/* @group Multi Chosen */
+.chosen-container-multi .chosen-choices {
+ position: relative;
+ overflow: hidden;
+ margin: 0;
+ padding: 0 5px;
+ width: 100%;
+ height: auto !important;
+ height: 1%;
+ border: 1px solid #aaa;
+ background-color: #fff;
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
+ background-image: -webkit-linear-gradient(#eeeeee 1%, #ffffff 15%);
+ background-image: -moz-linear-gradient(#eeeeee 1%, #ffffff 15%);
+ background-image: -o-linear-gradient(#eeeeee 1%, #ffffff 15%);
+ background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
+ cursor: text;
+}
+.chosen-container-multi .chosen-choices li {
+ float: left;
+ list-style: none;
+}
+.chosen-container-multi .chosen-choices li.search-field {
+ margin: 0;
+ padding: 0;
+ white-space: nowrap;
+}
+.chosen-container-multi .chosen-choices li.search-field input[type="text"] {
+ margin: 1px 0;
+ padding: 0;
+ height: 25px;
+ outline: 0;
+ border: 0 !important;
+ background: transparent !important;
+ box-shadow: none;
+ color: #999;
+ font-size: 100%;
+ font-family: sans-serif;
+ line-height: normal;
+ border-radius: 0;
+}
+.chosen-container-multi .chosen-choices li.search-choice {
+ position: relative;
+ margin: 3px 5px 3px 0;
+ padding: 3px 20px 3px 5px;
+ border: 1px solid #aaa;
+ max-width: 100%;
+ border-radius: 3px;
+ background-color: #eeeeee;
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
+ background-image: -webkit-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: -moz-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: -o-linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-size: 100% 19px;
+ background-repeat: repeat-x;
+ background-clip: padding-box;
+ box-shadow: 0 0 2px white inset, 0 1px 0 rgba(0, 0, 0, 0.05);
+ color: #333;
+ line-height: 13px;
+ cursor: default;
+}
+.chosen-container-multi .chosen-choices li.search-choice span {
+ word-wrap: break-word;
+}
+.chosen-container-multi .chosen-choices li.search-choice .search-choice-close {
+ position: absolute;
+ top: 4px;
+ right: 3px;
+ display: block;
+ width: 12px;
+ height: 12px;
+ background: url('chosen-sprite.png') -42px 1px no-repeat;
+ font-size: 1px;
+}
+.chosen-container-multi .chosen-choices li.search-choice .search-choice-close:hover {
+ background-position: -42px -10px;
+}
+.chosen-container-multi .chosen-choices li.search-choice-disabled {
+ padding-right: 5px;
+ border: 1px solid #ccc;
+ background-color: #e4e4e4;
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
+ background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
+ color: #666;
+}
+.chosen-container-multi .chosen-choices li.search-choice-focus {
+ background: #d4d4d4;
+}
+.chosen-container-multi .chosen-choices li.search-choice-focus .search-choice-close {
+ background-position: -42px -10px;
+}
+.chosen-container-multi .chosen-results {
+ margin: 0;
+ padding: 0;
+}
+.chosen-container-multi .chosen-drop .result-selected {
+ display: list-item;
+ color: #ccc;
+ cursor: default;
+}
+
+/* @end */
+/* @group Active */
+.chosen-container-active .chosen-single {
+ border: 1px solid #5897fb;
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
+}
+.chosen-container-active.chosen-with-drop .chosen-single {
+ border: 1px solid #aaa;
+ -moz-border-radius-bottomright: 0;
+ border-bottom-right-radius: 0;
+ -moz-border-radius-bottomleft: 0;
+ border-bottom-left-radius: 0;
+ background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
+ background-image: -webkit-linear-gradient(#eeeeee 20%, #ffffff 80%);
+ background-image: -moz-linear-gradient(#eeeeee 20%, #ffffff 80%);
+ background-image: -o-linear-gradient(#eeeeee 20%, #ffffff 80%);
+ background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
+ box-shadow: 0 1px 0 #fff inset;
+}
+.chosen-container-active.chosen-with-drop .chosen-single div {
+ border-left: none;
+ background: transparent;
+}
+.chosen-container-active.chosen-with-drop .chosen-single div b {
+ background-position: -18px 2px;
+}
+.chosen-container-active .chosen-choices {
+ border: 1px solid #5897fb;
+ box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
+}
+.chosen-container-active .chosen-choices li.search-field input[type="text"] {
+ color: #222 !important;
+}
+
+/* @end */
+/* @group Disabled Support */
+.chosen-disabled {
+ opacity: 0.5 !important;
+ cursor: default;
+}
+.chosen-disabled .chosen-single {
+ cursor: default;
+}
+.chosen-disabled .chosen-choices .search-choice .search-choice-close {
+ cursor: default;
+}
+
+/* @end */
+/* @group Right to Left */
+.chosen-rtl {
+ text-align: right;
+}
+.chosen-rtl .chosen-single {
+ overflow: visible;
+ padding: 0 8px 0 0;
+}
+.chosen-rtl .chosen-single span {
+ margin-right: 0;
+ margin-left: 26px;
+ direction: rtl;
+}
+.chosen-rtl .chosen-single-with-deselect span {
+ margin-left: 38px;
+}
+.chosen-rtl .chosen-single div {
+ right: auto;
+ left: 3px;
+}
+.chosen-rtl .chosen-single abbr {
+ right: auto;
+ left: 26px;
+}
+.chosen-rtl .chosen-choices li {
+ float: right;
+}
+.chosen-rtl .chosen-choices li.search-field input[type="text"] {
+ direction: rtl;
+}
+.chosen-rtl .chosen-choices li.search-choice {
+ margin: 3px 5px 3px 0;
+ padding: 3px 5px 3px 19px;
+}
+.chosen-rtl .chosen-choices li.search-choice .search-choice-close {
+ right: auto;
+ left: 4px;
+}
+.chosen-rtl.chosen-container-single-nosearch .chosen-search,
+.chosen-rtl .chosen-drop {
+ left: 9999px;
+}
+.chosen-rtl.chosen-container-single .chosen-results {
+ margin: 0 0 4px 4px;
+ padding: 0 4px 0 0;
+}
+.chosen-rtl .chosen-results li.group-option {
+ padding-right: 15px;
+ padding-left: 0;
+}
+.chosen-rtl.chosen-container-active.chosen-with-drop .chosen-single div {
+ border-right: none;
+}
+.chosen-rtl .chosen-search input[type="text"] {
+ padding: 4px 5px 4px 20px;
+ background: white url('chosen-sprite.png') no-repeat -30px -20px;
+ background: url('chosen-sprite.png') no-repeat -30px -20px;
+ direction: rtl;
+}
+.chosen-rtl.chosen-container-single .chosen-single div b {
+ background-position: 6px 2px;
+}
+.chosen-rtl.chosen-container-single.chosen-with-drop .chosen-single div b {
+ background-position: -12px 2px;
+}
+
+/* @end */
+/* @group Retina compatibility */
+@media only screen and (-webkit-min-device-pixel-ratio: 1.5), only screen and (min-resolution: 144dpi), only screen and (min-resolution: 1.5dppx) {
+ .chosen-rtl .chosen-search input[type="text"],
+ .chosen-container-single .chosen-single abbr,
+ .chosen-container-single .chosen-single div b,
+ .chosen-container-single .chosen-search input[type="text"],
+ .chosen-container-multi .chosen-choices .search-choice .search-choice-close,
+ .chosen-container .chosen-results-scroll-down span,
+ .chosen-container .chosen-results-scroll-up span {
+ background-image: url('chosen-sprite@2x.png') !important;
+ background-size: 52px 37px !important;
+ background-repeat: no-repeat !important;
+ }
+}
+/* @end */
diff --git a/platform/www/lib/plugins/farmer/deleted.files b/platform/www/lib/plugins/farmer/deleted.files
new file mode 100644
index 0000000..fea8b5e
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/deleted.files
@@ -0,0 +1,11 @@
+# This is a list of files that were present in previous plugin releases
+# but were removed later. An up to date plugin should not have any of
+# the files installed
+_test/validation.test.php
+action/handleAjax.php
+admin/createAnimal.php
+farm.php
+lang/en/createAnimal.txt
+lang/en/preload.txt
+scripts/plugins.js
+style.css
diff --git a/platform/www/lib/plugins/farmer/helper.php b/platform/www/lib/plugins/farmer/helper.php
new file mode 100644
index 0000000..53e7153
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/helper.php
@@ -0,0 +1,334 @@
+<?php
+/**
+ * DokuWiki Plugin farmer (Helper Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+class helper_plugin_farmer extends DokuWiki_Plugin {
+
+ protected $defaultPluginState = null;
+ protected $animalPluginState = array();
+
+ /**
+ * Returns the name of the current animal if any, false otherwise
+ *
+ * @return string|false
+ */
+ public function getAnimal() {
+ if(!isset($GLOBALS['FARMCORE'])) return false;
+ return $GLOBALS['FARMCORE']->getAnimal();
+ }
+
+ /**
+ * Get the farm config
+ *
+ * @return array
+ */
+ public function getConfig() {
+ if(!isset($GLOBALS['FARMCORE'])) return array();
+ return $GLOBALS['FARMCORE']->getConfig();
+ }
+
+ /**
+ * Was the current animal requested by host?
+ *
+ * @return bool
+ */
+ public function isHostbased() {
+ if(!isset($GLOBALS['FARMCORE'])) return false;
+ return $GLOBALS['FARMCORE']->isHostbased();
+ }
+
+ /**
+ * Was an animal requested that could not be found?
+ *
+ * @return bool
+ */
+ public function wasNotfound() {
+ if(!isset($GLOBALS['FARMCORE'])) return false;
+ return $GLOBALS['FARMCORE']->wasNotfound();
+ }
+
+ /**
+ * Guess the URL for an animal
+ *
+ * @param $animal
+ * @return string
+ */
+ public function getAnimalURL($animal) {
+ $config = $this->getConfig();
+
+ if(strpos($animal, '.') !== false) {
+ return 'http://' . $animal;
+ } elseif($config['base']['basedomain']) {
+ return 'http://' . $animal . '.' . $config['base']['basedomain'];
+ } else {
+ return DOKU_URL . '!' . $animal . '/';
+ }
+ }
+
+ /**
+ * List of all animals, i.e. directories within DOKU_FARMDIR without the template.
+ *
+ * @return array
+ */
+ public function getAllAnimals() {
+ $animals = array();
+ $list = glob(DOKU_FARMDIR . '*/conf/', GLOB_ONLYDIR);
+ foreach($list as $path) {
+ $animal = basename(dirname($path));
+ if($animal == '_animal') continue; // old template
+ $animals[] = $animal;
+ }
+ sort($animals);
+ return $animals;
+ }
+
+ /**
+ * checks wether $path is in under $container
+ *
+ * Also returns false if $path and $container are the same directory
+ *
+ * @param string $path
+ * @param string $container
+ * @return bool
+ */
+ public function isInPath($path, $container) {
+ $path = fullpath($path).'/';
+ $container = fullpath($container).'/';
+ if($path == $container) return false;
+ return (strpos($path, $container) === 0);
+ }
+
+ /**
+ * Check if the farm is correctly configured for this farmer plugin
+ *
+ * @return bool
+ */
+ public function checkFarmSetup() {
+ return defined('DOKU_FARMDIR') && isset($GLOBALS['FARMCORE']);
+ }
+
+ /**
+ * @param string $animalname
+ *
+ * @return bool
+ */
+ public function validateAnimalName($animalname) {
+ return preg_match("/^[a-z0-9]+([\\.\\-][a-z0-9]+)*$/i", $animalname) === 1;
+ }
+
+ /**
+ * Copy a file, or recursively copy a folder and its contents. Adapted for DokuWiki.
+ *
+ * @todo: needs tests
+ *
+ * @author Aidan Lister <aidan@php.net>
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ * @link http://aidanlister.com/2004/04/recursively-copying-directories-in-php/
+ *
+ * @param string $source Source path
+ * @param string $destination Destination path
+ * @param string $exclude Regular expression to exclude files or directories (complete with delimiters)
+ * @return bool Returns TRUE on success, FALSE on failure
+ */
+ function io_copyDir($source, $destination, $exclude = '') {
+ if($exclude && preg_match($exclude, $source)) {
+ return true;
+ }
+
+ if(is_link($source)) {
+ io_lock($destination);
+ $result = symlink(readlink($source), $destination);
+ io_unlock($destination);
+ return $result;
+ }
+
+ if(is_file($source)) {
+ io_lock($destination);
+ $result = copy($source, $destination);
+ io_unlock($destination);
+ return $result;
+ }
+
+ if(!is_dir($destination)) {
+ io_mkdir_p($destination);
+ }
+
+ $dir = @dir($source);
+ if($dir === false) return false;
+ while(false !== ($entry = $dir->read())) {
+ if($entry == '.' || $entry == '..') {
+ continue;
+ }
+
+ // recurse into directories
+ $this->io_copyDir("$source/$entry", "$destination/$entry", $exclude);
+ }
+
+ $dir->close();
+ return true;
+ }
+
+ /**
+ * get a list of all Plugins installed in the farmer wiki, regardless whether they are active or not.
+ *
+ * @param bool $all get all plugins, even disabled ones
+ * @return array
+ */
+ public function getAllPlugins($all = true) {
+
+ /** @var Doku_Plugin_Controller $plugin_controller */
+ global $plugin_controller;
+
+ $plugins = $plugin_controller->getList('', $all);
+
+ // filter out a few plugins
+ $plugins = array_filter(
+ $plugins, function ($item) {
+ if($item == 'farmer') return false;
+ if($item == 'extension') return false;
+ if($item == 'upgrade') return false;
+ if($item == 'testing') return false;
+ return true;
+ }
+ );
+
+ sort($plugins);
+ return $plugins;
+ }
+
+ /**
+ * Get the plugin states configured locally in the given animal
+ *
+ * Response is cached
+ *
+ * @param $animal
+ * @return array
+ */
+ public function getAnimalPluginLocalStates($animal) {
+ if(isset($this->animalPluginState[$animal])) return $this->animalPluginState[$animal];
+
+ $localfile = DOKU_FARMDIR . $animal . '/conf/plugins.local.php';
+ $plugins = array();
+ if(file_exists($localfile)) {
+ include($localfile);
+ }
+
+ $this->animalPluginState[$animal] = $plugins;
+ return $plugins;
+ }
+
+ /**
+ * Return the default state plugins would have in animals
+ *
+ * Response is cached
+ *
+ * @return array
+ */
+ public function getDefaultPluginStates() {
+ if(!is_null($this->defaultPluginState)) return $this->defaultPluginState;
+
+ $farmconf = $this->getConfig();
+ $all = $this->getAllPlugins();
+
+ $plugins = array();
+ foreach($all as $one) {
+ if($farmconf['inherit']['plugins']) {
+ $plugins[$one] = !plugin_isdisabled($one);
+ } else {
+ $plugins[$one] = true; // default state is enabled
+ }
+ }
+
+ ksort($plugins);
+ $this->defaultPluginState = $plugins;
+ return $plugins;
+ }
+
+ /**
+ * Return a structure giving detailed info about the state of all plugins in an animal
+ *
+ * @param $animal
+ * @return array
+ */
+ public function getAnimalPluginRealState($animal) {
+ $info = array();
+
+ $defaults = $this->getDefaultPluginStates();
+ $local = $this->getAnimalPluginLocalStates($animal);
+
+ foreach($defaults as $plugin => $set) {
+ $current = array(
+ 'name' => $plugin,
+ 'default' => $set,
+ 'actual' => $set,
+ 'isdefault' => true
+ );
+
+ if(isset($local[$plugin])) {
+ $current['actual'] = (bool) $local[$plugin];
+ $current['isdefault'] = false;
+ }
+
+ $info[$plugin] = $current;
+ }
+
+ ksort($info);
+ return $info;
+ }
+
+ /**
+ * Set the state of a plugin in an animal
+ *
+ * @param string $plugin
+ * @param string $animal
+ * @param int $state -1 = default, 1 = enabled, 0 = disabled
+ */
+ public function setPluginState($plugin, $animal, $state) {
+ $state = (int) $state;
+
+ $plugins = $this->getAnimalPluginLocalStates($animal);
+ if($state < 0) {
+ if(isset($plugins[$plugin])) unset($plugins[$plugin]);
+ } else {
+ $plugins[$plugin] = $state;
+ }
+
+ $this->writePluginConf($plugins, $animal);
+
+ // clear state cache
+ if(isset($this->animalPluginState[$animal])) unset($this->animalPluginState[$animal]);
+ }
+
+ /**
+ * Write the list of (deactivated) plugins as plugin configuration of an animal to file
+ *
+ * updates the plugin state cache
+ *
+ * @param array $plugins associative array with the key being the plugin name and the value 0 or 1
+ * @param string $animal Directory of the animal within DOKU_FARMDIR
+ */
+ public function writePluginConf($plugins, $animal) {
+ $pluginConf = '<?php' . "\n# plugins enabled and disabled by the farmer plugin\n";
+ foreach($plugins as $plugin => $status) {
+ $pluginConf .= '$plugins[\'' . $plugin . '\'] = ' . $status . ";\n";
+ }
+ io_saveFile(DOKU_FARMDIR . $animal . '/conf/plugins.local.php', $pluginConf);
+ touch(DOKU_FARMDIR . $animal . '/conf/local.php');
+
+ if(function_exists('opcache_invalidate')) {
+ opcache_invalidate(DOKU_FARMDIR . $animal . '/conf/plugins.local.php');
+ opcache_invalidate(DOKU_FARMDIR . $animal . '/conf/local.php');
+ }
+
+ $this->animalPluginState[$animal] = $plugins;
+ }
+}
diff --git a/platform/www/lib/plugins/farmer/includes/config.php b/platform/www/lib/plugins/farmer/includes/config.php
new file mode 100644
index 0000000..cd9aa67
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/includes/config.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * This overrides some values for the animals without having to configure it
+ *
+ * This file is added to the protected cascade for animals only.
+ * You should not edit it!
+ */
+global $FARMCORE;
+$conf['savedir'] = $FARMCORE->getAnimalDataDir();
+$conf['basedir'] = $FARMCORE->getAnimalBaseDir();
+$conf['upgradecheck'] = 0;
+
+
diff --git a/platform/www/lib/plugins/farmer/includes/plugins.php b/platform/www/lib/plugins/farmer/includes/plugins.php
new file mode 100644
index 0000000..cd8d7b2
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/includes/plugins.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * This overrides some values for the animals without having to configure it
+ *
+ * This file is added to the protected cascade for animals only.
+ * You should not edit it!
+ */
+$plugins['extension'] = 0;
+$plugins['upgrade'] = 0;
+$plugins['testing'] = 0;
+$plugins['farmer'] = 1;
+$plugins['farmsync'] = 0;
diff --git a/platform/www/lib/plugins/farmer/includes/template.php b/platform/www/lib/plugins/farmer/includes/template.php
new file mode 100644
index 0000000..1b0075c
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/includes/template.php
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html lang="<?php echo $conf['lang'] ?>" dir="<?php echo $lang['direction'] ?>" class="popup no-js">
+<head>
+ <meta charset="utf-8"/>
+ <title>
+ <?php echo $title ?>
+ </title>
+ <script>(function (H) {
+ H.className = H.className.replace(/\bno-js\b/, 'js')
+ })(document.documentElement)</script>
+ <?php tpl_metaheaders() ?>
+ <meta name="viewport" content="width=device-width,initial-scale=1"/>
+ <?php echo tpl_favicon(array('favicon', 'mobile')) ?>
+ <?php tpl_includeFile('meta.html') ?>
+</head>
+
+<body>
+<!--[if lte IE 8 ]>
+<div id="IE8"><![endif]-->
+<div class="dokuwiki">
+ <div class="page">
+ <?php echo $body ?>
+ </div>
+</div>
+<!--[if lte IE 8 ]></div><![endif]-->
+</body>
+</html>
diff --git a/platform/www/lib/plugins/farmer/lang/de/lang.php b/platform/www/lib/plugins/farmer/lang/de/lang.php
new file mode 100644
index 0000000..b97a850
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/de/lang.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * German language file for farmer plugin
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+// menu entry for admin plugins
+$lang['menu'] = 'Farming';
+
+// tabs
+$lang['tab_setup'] = 'Farm Setup';
+$lang['tab_info'] = 'Info';
+$lang['tab_config'] = 'Konfiguration';
+$lang['tab_plugins'] = 'Plugins verwalten';
+$lang['tab_new'] = 'Neues Animal hinzufügen';
+$lang['tab_delete'] = 'Animal löschen';
+
+// setup
+$lang['preloadPHPForm'] = 'Farm aufsetzen';
+$lang['farm dir'] = 'Animal-Verzeichnis';
+$lang['htaccess setup'] = 'Farm code zu .htaccess hinzufügen?';
+$lang['submit'] = 'Abschicken';
+$lang['farmdir_missing'] = 'Bitte geben Sie das Verzeichnis an in dem die Animals gespeichert werden sollen.';
+$lang['farmdir_in_dokuwiki'] = 'Das Animal-Verzeichnis (%s) muss außerhalb des Farm-DokuWikis (%s) liegen.';
+$lang['farmdir_uncreatable'] = 'Das Animal-Verzeichnis (%s) konnte nicht erzeugt werden. Sind die Dateiberechtigungen korrekt?';
+$lang['farmdir_unwritable'] = 'Bitte stellen Sie sicher, dass der Webserver in das Animal-Verzeichnis (%s) schreiben darf!';
+$lang['farmdir_notEmpty'] = 'Das Animal-Verzeichnis (%s) muss leer sein!';
+$lang['preload creation success'] = 'Die Farm wurde erfolgreich angelegt.';
+$lang['preload creation error'] = 'Es ist ein Fehler beim Aufsetzen der Farm ausfgetreten.';
+$lang['overwrite_preload'] = 'Achtung: Ihre existierende: inc/preload.php wird überschrieben, wenn Sie diesen hier weitermachen!';
+
+// info
+$lang['animal'] = 'Animal Name / Domain';
+$lang['thisis'] = 'Diese Instanz ist';
+$lang['thisis.farmer'] = 'Der Farmer!';
+$lang['thisis.animal'] = 'Ein Animal!';
+$lang['baseinstall'] = 'Farmer Installation';
+$lang['animals'] = 'Animals';
+$lang['confdir'] = 'Konfigurationsverzeichnis dieser Instanz';
+$lang['savedir'] = 'data-Verzeichnis dieser Instanz';
+$lang['plugins'] = 'In dieser Instanz aktivierte Plugins';
+
+// config
+$lang['base'] = 'Grundkonfiguration';
+$lang['farm host'] = 'Farmer Host Name';
+$lang['base domain'] = 'Basis-Domain für Subdomain-Animals';
+$lang['conf_inherit'] = 'Farmer-Einstellungen die von Animals geerbt werden sollen';
+$lang['conf_inherit_main'] = 'Konfigurationseinstellungen';
+$lang['conf_inherit_acronyms'] = 'Abkürzungs-Definitionen';
+$lang['conf_inherit_entities'] = 'Entity-Definitionionen';
+$lang['conf_inherit_interwiki'] = 'Interwiki-Definitionen';
+$lang['conf_inherit_license'] = 'Lizenz-Definitionen';
+$lang['conf_inherit_mime'] = 'MIME-Type-Definitionen';
+$lang['conf_inherit_scheme'] = 'URL-Scheme-Definitionen';
+$lang['conf_inherit_smileys'] = 'Smiley-Definitionen';
+$lang['conf_inherit_wordblock'] = 'Spamfiltereinträge';
+$lang['conf_inherit_userstyle'] = 'Nutzer-Styles';
+$lang['conf_inherit_userscript'] = 'Nutzer-Scripts';
+$lang['conf_inherit_styleini'] = 'Anpassungen an Template-Styles';
+$lang['conf_inherit_users'] = 'Benutzer (nur Plain Auth)';
+$lang['conf_inherit_plugins'] = 'Plugin-Zustand';
+$lang['conf_inherit_yes'] = 'vom Farmer geerbt';
+$lang['conf_inherit_no'] = 'unabhängig vom Farmer';
+$lang['conf_notfound'] = 'Verhalten bei zugriff auf nicht-existierende Animals';
+$lang['conf_notfound_farmer'] = 'Zeige das Farmer-Wiki';
+$lang['conf_notfound_404'] = 'Zeige eine 404-Fehlerseite';
+$lang['conf_notfound_list'] = 'Zeige eine Liste der existierenden Animals';
+$lang['conf_notfound_redirect'] = 'Leite auf untenstehende URL um';
+$lang['conf_notfound_url'] = 'URL auf die umgeleitet werden soll wenn oben ausgewählt';
+$lang['save'] = 'Speichern';
+
+// new
+$lang['animal template'] = 'Bestehendes Animal kopieren';
+$lang['animal creation success'] = 'Das Animal "%s" wurde erfolgreich angelegt.';
+$lang['animal creation error'] = 'Es gab einen Fehler beim Anlegen des Animals.';
+$lang['animal configuration'] = 'Animal Grundkonfiguration';
+$lang['animal administrator'] = 'Animal Administrator';
+$lang['noUsers'] = 'Keine Benutzer erzeugen';
+$lang['importUsers'] = 'Alle Benutzeraccounts des Farmers in das neue Animal kopieren';
+$lang['currentAdmin'] = 'Den aktuellen Benutzer als Admin setzen';
+$lang['newAdmin'] = 'Neuen Benutzer "admin" anlegen';
+$lang['admin password'] = 'Passwort für den neuen Administrator';
+$lang['animalname_missing'] = 'Bitte geben Sie einen Namen für das neue Animal an.';
+$lang['animalname_invalid'] = ' Der Name des Animals darf nur aus Buchstaben und Ziffern sowie aus Bindestrichen und Punkten (nicht am Anfang oder Ende) bestehen.';
+$lang['animalname_preexisting'] = 'Ein Animal mit diesem Namen existiert bereits.';
+$lang['adminPassword_empty'] = 'Das Passwort für den neuen Administrator darf nicht leer sein.';
+$lang['animal template copy error'] = 'Es gab ein Problem beim Kopieren von %s aus dem existierenden Animal in das neue.';
+
+// plugins
+$lang['bulkSingleSwitcher'] = 'Ein einzelnes Animal bearbeiten oder alle aufeinmal?';
+$lang['bulkEdit'] = 'Alle Animals bearbeiten';
+$lang['singleEdit'] = 'Ein einzelnes Animal bearbeiten';
+$lang['bulkEditForm'] = 'Plugins in allen Animals ein- oder ausschalten';
+$lang['activate'] = 'Aktivieren';
+$lang['deactivate'] = 'Deaktivieren';
+$lang['singleEditForm'] = 'Plugins eines spezifischen Animals bearbeiten';
+$lang['plugindone'] = 'Plugin states updated';
+$lang['plugin'] = 'Plugin';
+$lang['plugin_on'] = 'an';
+$lang['plugin_off'] = 'aus';
+$lang['plugin_default'] = 'Voreinstellung';
+$lang['plugin_enabled'] = 'Aktiviert';
+$lang['plugin_disabled'] = 'Deaktiviert';
+$lang['js']['animalSelect'] = 'Wählen Sie ein Animal';
+$lang['js']['pluginSelect'] = 'Wählen Sie ein Plugin';
+
+// delete
+$lang['delete_animal'] = 'Animal zum Löschen auswählen';
+$lang['delete_confirm'] = 'Name des Animals erneut eingeben, um Löschen zu bestätigen';
+$lang['delete'] = 'Animal und alle darin gespeicherten Daten löschen';
+$lang['delete_noanimal'] = 'Bitte wählen sie ein Animal zum Löschen aus';
+$lang['delete_mismatch'] = 'Bestätigung stimmt nicht mit Animalnamen überein. Nicht gelöscht.';
+$lang['delete_invalid'] = 'Invalider Animalname. Nicht gelöscht.';
+$lang['delete_success'] = 'Animal erfolgreich gelöscht.';
+$lang['delete_fail'] = 'Einige Dateien konnten nicht gelöscht werden. Sie sollten diese manuell entfernen.';
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/farmer/lang/de/notfound_404.txt b/platform/www/lib/plugins/farmer/lang/de/notfound_404.txt
new file mode 100644
index 0000000..bac18d9
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/de/notfound_404.txt
@@ -0,0 +1,3 @@
+====== 404 Nicht gefunden ======
+
+Die angeforderte Ressource konnte nicht gefunden werden
diff --git a/platform/www/lib/plugins/farmer/lang/de/notfound_list.txt b/platform/www/lib/plugins/farmer/lang/de/notfound_list.txt
new file mode 100644
index 0000000..300ba7f
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/de/notfound_list.txt
@@ -0,0 +1,3 @@
+====== Wiki nicht gefunden ======
+
+Das angeforderte Wiki konnte nicht gefunden werden. Bitte wählen Sie aus der folgenden Liste der vorhandenen Wikis.
diff --git a/platform/www/lib/plugins/farmer/lang/de/settings.php b/platform/www/lib/plugins/farmer/lang/de/settings.php
new file mode 100644
index 0000000..661a3ec
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/de/settings.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * German language file for farmer plugin
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+// keys need to match the config setting name
+$lang['deactivated plugins'] = 'Kommaseparierte Liste an Plugins die in neuen Animals automatisch deaktiviert werden sollen.';
+
+
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/farmer/lang/de/tab_config.txt b/platform/www/lib/plugins/farmer/lang/de/tab_config.txt
new file mode 100644
index 0000000..299c979
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/de/tab_config.txt
@@ -0,0 +1 @@
+Hier können die grundlegenden Eigenschaften der Farm konfiguriert werden. Beachten Sie, dass alle Einstellungen hier alle Animals beeinflussen werden.
diff --git a/platform/www/lib/plugins/farmer/lang/de/tab_delete.txt b/platform/www/lib/plugins/farmer/lang/de/tab_delete.txt
new file mode 100644
index 0000000..795487a
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/de/tab_delete.txt
@@ -0,0 +1 @@
+Sie können bestehende Animals hier löschen. Dies löscht **alle Daten, inklusive Seiten und Medieninhalte** des gewählten Animals. **Dies kann nicht rückgängig gemacht werden!**
diff --git a/platform/www/lib/plugins/farmer/lang/de/tab_info.txt b/platform/www/lib/plugins/farmer/lang/de/tab_info.txt
new file mode 100644
index 0000000..11faab9
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/de/tab_info.txt
@@ -0,0 +1 @@
+Dieses Wiki ist Teil eines Farm-Setups. Nähere Details finden Sie unten.
diff --git a/platform/www/lib/plugins/farmer/lang/de/tab_new.txt b/platform/www/lib/plugins/farmer/lang/de/tab_new.txt
new file mode 100644
index 0000000..a62ef02
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/de/tab_new.txt
@@ -0,0 +1 @@
+Hier können Sie ein neues Animal anlegen.
diff --git a/platform/www/lib/plugins/farmer/lang/de/tab_plugins.txt b/platform/www/lib/plugins/farmer/lang/de/tab_plugins.txt
new file mode 100644
index 0000000..8277c98
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/de/tab_plugins.txt
@@ -0,0 +1 @@
+Hier können Sie Plugins für einzelne oder alle Animals ein- oder ausschalten.
diff --git a/platform/www/lib/plugins/farmer/lang/de/tab_setup.txt b/platform/www/lib/plugins/farmer/lang/de/tab_setup.txt
new file mode 100644
index 0000000..e0dc63b
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/de/tab_setup.txt
@@ -0,0 +1 @@
+Ihr Wiki ist noch nicht für Farming mit dem Farmer-Plugin eingerichtet. Bitte nutzen Sie den folgenden Dialog zum Aufsetzen der Farm.
diff --git a/platform/www/lib/plugins/farmer/lang/en/lang.php b/platform/www/lib/plugins/farmer/lang/en/lang.php
new file mode 100644
index 0000000..da49836
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/lang.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * English language file for farmer plugin
+ *
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+
+// menu entry for admin plugins
+$lang['menu'] = 'Farming';
+
+// tabs
+$lang['tab_setup'] = 'Farm Setup';
+$lang['tab_info'] = 'Info';
+$lang['tab_config'] = 'Configuration';
+$lang['tab_plugins'] = 'Manage Plugins';
+$lang['tab_new'] = 'Add new Animal';
+$lang['tab_delete'] = 'Delete Animal';
+
+// setup
+$lang['preloadPHPForm'] = 'Initialize Farming';
+$lang['farm dir'] = 'Animal directory';
+$lang['htaccess setup'] = 'Add farm code to .htaccess?';
+$lang['submit'] = 'Submit';
+$lang['farmdir_missing'] = 'Please enter a directory where the Animals should be stored.';
+$lang['farmdir_in_dokuwiki'] = 'The Animal directory (%s) must be outside of the Farm dokuwiki (%s).';
+$lang['farmdir_uncreatable'] = 'The Animal directory (%s) could not be created. Are the permissions correct?';
+$lang['farmdir_unwritable'] = 'Please make sure that the webserver has write access in the Animal directory (%s)!';
+$lang['farmdir_notEmpty'] = 'The Animal directory (%s) must be empty.';
+$lang['preload creation success'] = 'Farming has been succesfully initialized.';
+$lang['preload creation error'] = 'There was an error during Farming initialization.';
+$lang['overwrite_preload'] = 'Warning: Your existing inc/preload.php will be overwritten when continuing here!';
+
+// info
+$lang['animal'] = 'Animal Name / Domain';
+$lang['thisis'] = 'Instance is';
+$lang['thisis.farmer'] = 'The farmer!';
+$lang['thisis.animal'] = 'An Animal!';
+$lang['baseinstall'] = 'Farmer Install';
+$lang['animals'] = 'Animals';
+$lang['confdir'] = 'Instance Configuration Directory';
+$lang['savedir'] = 'Instance Data Directory';
+$lang['plugins'] = 'Plugins active in this instance';
+
+// config
+$lang['base'] = 'Base Configuration';
+$lang['farm host'] = 'Farmer Host Name';
+$lang['base domain'] = 'Base Domain for subdomain Animals';
+$lang['conf_inherit'] = 'Farmer Settings Animals should inherit';
+$lang['conf_inherit_main'] = 'Configuration Settings';
+$lang['conf_inherit_acronyms'] = 'Acronym Definitions';
+$lang['conf_inherit_entities'] = 'Entity Definitions';
+$lang['conf_inherit_interwiki'] = 'Interwiki Definitions';
+$lang['conf_inherit_license'] = 'License Definitions';
+$lang['conf_inherit_mime'] = 'MIME Type Definitions';
+$lang['conf_inherit_scheme'] = 'URL Scheme Definitions';
+$lang['conf_inherit_smileys'] = 'Smiley Definitions';
+$lang['conf_inherit_wordblock'] = 'Spam Blacklist Entries';
+$lang['conf_inherit_userstyle'] = 'User Styles';
+$lang['conf_inherit_userscript'] = 'User Scripts';
+$lang['conf_inherit_styleini'] = 'Template style customizations';
+$lang['conf_inherit_users'] = 'Users (Plain Auth only)';
+$lang['conf_inherit_plugins'] = 'Plugin State';
+$lang['conf_inherit_yes'] = 'inherited from farmer';
+$lang['conf_inherit_no'] = 'independent from farmer';
+$lang['conf_notfound'] = 'Behavior on accessing nonexistent Animals';
+$lang['conf_notfound_farmer'] = 'Show the farmer wiki';
+$lang['conf_notfound_404'] = 'Show a 404 error page';
+$lang['conf_notfound_list'] = 'Show a list of available animals';
+$lang['conf_notfound_redirect'] = 'Redirect to the URL below';
+$lang['conf_notfound_url'] = 'URL to redirect to if selected above';
+$lang['save'] = 'Save';
+
+// new
+$lang['animal template'] = 'Copy existing Animal';
+$lang['animal creation success'] = 'The Animal "%s" has been successfully created.';
+$lang['animal creation error'] = 'There was an error while creating the Animal.';
+$lang['animal configuration'] = 'Basic Animal configuration';
+$lang['inherit user registration'] = 'Inherit user registration setting from farmer';
+$lang['enable user registration'] = 'Allow users to register themselves';
+$lang['disable user registration'] = 'Disable user register';
+$lang['animal administrator'] = 'Animal administrator';
+$lang['noUsers'] = 'Do not create any users';
+$lang['importUsers'] = 'Import all users of the Farmer to the new Animal';
+$lang['currentAdmin'] = 'Set the current user as admin';
+$lang['newAdmin'] = 'Create new admin user "admin"';
+$lang['admin password'] = 'Password for the new admin';
+$lang['animalname_missing'] = 'Please enter a name for the new Animal.';
+$lang['animalname_invalid'] = 'The Animal name may only contain alphanumeric characters and dots/hyphens (but not as first or last character).';
+$lang['animalname_preexisting'] = 'An Animal with that name already exists.';
+$lang['adminPassword_empty'] = 'The password for the new admin account must not be empty.';
+$lang['animal template copy error'] = 'There was a problem copying %s from the existing Animal to the new one.';
+$lang['aclpolicy missing/bad'] = 'Please choose an initial ACL policy from the dropdown.';
+
+// plugins
+$lang['bulkSingleSwitcher'] = 'Edit a single Animal or all at once?';
+$lang['bulkEdit'] = 'Bulk edit all Animals';
+$lang['singleEdit'] = 'Edit a single Animal';
+$lang['bulkEditForm'] = 'Activate or deactivate a plugin in all Animals';
+$lang['matrixEdit'] = 'Edit Animal/Plugin matrix';
+$lang['default'] = 'Set to default';
+$lang['activate'] = 'Activate';
+$lang['deactivate'] = 'Deactivate';
+$lang['singleEditForm'] = 'Edit the plugins of a specific Animal';
+$lang['plugindone'] = 'Plugin states updated';
+$lang['plugin'] = 'Plugin';
+$lang['plugin_on'] = 'on';
+$lang['plugin_off'] = 'off';
+$lang['plugin_default'] = 'Default';
+$lang['plugin_enabled'] = 'Enabled';
+$lang['plugin_disabled'] = 'Disabled';
+$lang['js']['animalSelect'] = 'Select an animal';
+$lang['js']['pluginSelect'] = 'Select a plugin';
+$lang['disable_new_plugins'] = 'The plugin has been disabled by default. You can enable it here or in specific animals only.';
+
+
+// delete
+$lang['delete_animal'] = 'Select Animal to delete';
+$lang['delete_confirm'] = 'Please type the Animal name to confirm';
+$lang['delete'] = 'Delete the Animal and all its data';
+
+$lang['delete_noanimal'] = 'Please select an Animal to delete';
+$lang['delete_mismatch'] = 'Confirmation does not match Animal name. Not deleted.';
+$lang['delete_invalid'] = 'Invalid Animal name. Not deleted.';
+$lang['delete_success'] = 'Animal successfully deleted.';
+$lang['delete_fail'] = 'Some files could not be deleted, you should clean up manuallly.';
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/farmer/lang/en/notfound_404.txt b/platform/www/lib/plugins/farmer/lang/en/notfound_404.txt
new file mode 100644
index 0000000..b023e79
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/notfound_404.txt
@@ -0,0 +1,3 @@
+====== 404 Not Found ======
+
+The requested resource could not be found.
diff --git a/platform/www/lib/plugins/farmer/lang/en/notfound_list.txt b/platform/www/lib/plugins/farmer/lang/en/notfound_list.txt
new file mode 100644
index 0000000..9e4633a
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/notfound_list.txt
@@ -0,0 +1,3 @@
+====== Wiki Not Found ======
+
+The requested Wiki could not be found. Please refer to the list of available Wikis below.
diff --git a/platform/www/lib/plugins/farmer/lang/en/settings.php b/platform/www/lib/plugins/farmer/lang/en/settings.php
new file mode 100644
index 0000000..0e854ac
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/settings.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * english language file for farmer plugin
+ *
+ * @author Michael Große <grosse@cosmocode.de>
+ */
+
+// keys need to match the config setting name
+$lang['deactivated plugins'] = 'Comma-separated list of plugins which are deactivated by default in new animals.';
+$lang['disable_new_plugins'] = 'Automatically disable plugins after they have been newly installed in the farmer? (only when installed via extension manager)';
+
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/farmer/lang/en/tab_config.txt b/platform/www/lib/plugins/farmer/lang/en/tab_config.txt
new file mode 100644
index 0000000..cedf536
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/tab_config.txt
@@ -0,0 +1 @@
+Here the basic behavior of the farm is configured. Please be aware that changing options here will affect all animals.
diff --git a/platform/www/lib/plugins/farmer/lang/en/tab_config_help.txt b/platform/www/lib/plugins/farmer/lang/en/tab_config_help.txt
new file mode 100644
index 0000000..0ebf7c2
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/tab_config_help.txt
@@ -0,0 +1,26 @@
+===== Farm Configuration =====
+
+All settings made here are saved to the Farmer's ''conf/farm.ini''.
+
+==== Base Configuration ====
+
+The **Farmer's host name** was set automatically during the setup, but you can change it here. It
+will be used to detect if a request was made directly to the Farmer when using host based farms. This
+should be a full qualified hostname (''foo.example.com'' instead of just ''foo'').
+
+When using a subdomain wildcard setup you should specify the main domain in the **Base Domain** setting.
+Eg. if you specify ''example.com'' it is assumed an animal named ''foo'' is reachable via ''foo.example.com''.
+The base domain is only appended to animal names not containing any dots.
+
+==== Inheritence ====
+
+Here you can specify what configuration settings made in the farmer should be used as defaults in the animals.
+Animals can still override the Farmer settings in their own configuration files. When inheritance is disabled,
+DokuWiki's default settings are the defaults for all animals as well.
+
+==== Non Existing Animals ====
+
+By default, when accessing a non-existing animal no error message is shown. You can pick between different
+behavior here. Be sure that your Farmer's host name is set up correctly above, before switching away from the
+default.
+
diff --git a/platform/www/lib/plugins/farmer/lang/en/tab_delete.txt b/platform/www/lib/plugins/farmer/lang/en/tab_delete.txt
new file mode 100644
index 0000000..cd7f67c
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/tab_delete.txt
@@ -0,0 +1 @@
+You can delete existing animals here. This deletes **all data, including pages and media files** of the selected animal. **This is irreversible!**
diff --git a/platform/www/lib/plugins/farmer/lang/en/tab_info.txt b/platform/www/lib/plugins/farmer/lang/en/tab_info.txt
new file mode 100644
index 0000000..f3d7a83
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/tab_info.txt
@@ -0,0 +1 @@
+This wiki is part of a farm setup. Check the details below.
diff --git a/platform/www/lib/plugins/farmer/lang/en/tab_new.txt b/platform/www/lib/plugins/farmer/lang/en/tab_new.txt
new file mode 100644
index 0000000..ffe899c
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/tab_new.txt
@@ -0,0 +1 @@
+You can create a new animal here.
diff --git a/platform/www/lib/plugins/farmer/lang/en/tab_new_help.txt b/platform/www/lib/plugins/farmer/lang/en/tab_new_help.txt
new file mode 100644
index 0000000..0445e82
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/tab_new_help.txt
@@ -0,0 +1,31 @@
+===== Animal Creation =====
+
+Animals are the independent subwikis of a Dokuwiki farm. To create a new animal a name has to be assigned.
+
+==== Animal Names ====
+
+For .htaccess based setups this should be a single word. For domain based setups you should provide either a full qualified domain name.
+If you use a wildcard subdomain setup you can also just provide the hostname part if you set a base domain in the configuration.
+
+Examples:
+
+ * .htaccess based: ''foo'' for an animal accessible at ''%%http://example.org/dokuwiki/!foo/%%''
+ * domain based: ''%%www.foo.com%%'' for an animal accessible at ''%%http://www.foo.com/%%''
+ * sub domain based: ''foo'' for an animal accessible at ''%%http://foo.example.com/%%''
+
+The latter two require the appropriate DNS setup!
+
+==== Copy Animal ====
+
+You can select an existing animal to base the new one on. All configuration, page, media and meta data will be copied
+to the new animal. Page and media revisions will not be copied.
+
+The title and logo image will be overwritten to make sure you can distinguish the new from the old wiki.
+
+==== Animal Administrator ====
+
+The Animal will be a fully functional wiki with it's own user base. You will need at least one administrative user
+to configure it. You can copy your current user or all users from the farmer or create a completely new user for the Animal.
+
+You can choose to not create any users. This should only be chosen when inheriting users from the Farmer was enabled in the
+configuration tab or you copied a different animal with existing users.
diff --git a/platform/www/lib/plugins/farmer/lang/en/tab_plugins.txt b/platform/www/lib/plugins/farmer/lang/en/tab_plugins.txt
new file mode 100644
index 0000000..78e8021
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/tab_plugins.txt
@@ -0,0 +1 @@
+You can activate or deactivate either a plugin for all animals in a single bulk operation or you can edit the plugins of a specific animal.
diff --git a/platform/www/lib/plugins/farmer/lang/en/tab_plugins_help.txt b/platform/www/lib/plugins/farmer/lang/en/tab_plugins_help.txt
new file mode 100644
index 0000000..44af5fc
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/tab_plugins_help.txt
@@ -0,0 +1,16 @@
+===== Plugin Management =====
+
+The extension manager is disabled in all Animals. Plugins can only be installed in the Farmer and only the Farmer
+may control what plugins are enabled or disabled in all Animals. This is done through this interface.
+
+A plugin can have three states in an Animal. It can be enabled (on) or disabled (off), or it can have the default state. The
+default means that the state of a Plugin was not explicitly set for an Animal. Normally the default state is on.
+
+When Animals are configured to inherit the Plugin state of the Farmer, a plugin in default state will have the same
+state as in the Farmer. Eg. when you disable a plugin in the Farmer it will disable the plugin for all Animals which
+did not have the state of this plugin explicitly set.
+
+There are three ways to manage plugins: You can either pick a single plugin and set its state to the same value in all animals
+or you can pick a specific animal and configure all the plugin states within that animal only. The third option allows you to
+see and edit the state of all plugins in all animals at once. This option may not be feasible of you have a large amount
+of animals.
diff --git a/platform/www/lib/plugins/farmer/lang/en/tab_setup.txt b/platform/www/lib/plugins/farmer/lang/en/tab_setup.txt
new file mode 100644
index 0000000..19ae730
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/tab_setup.txt
@@ -0,0 +1 @@
+Your Wiki is not set up as a farm managed by the Farmer Plugin, yet. Please use the wizard below to enable farming.
diff --git a/platform/www/lib/plugins/farmer/lang/en/tab_setup_help.txt b/platform/www/lib/plugins/farmer/lang/en/tab_setup_help.txt
new file mode 100644
index 0000000..f81532f
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/en/tab_setup_help.txt
@@ -0,0 +1,37 @@
+===== About Farms =====
+
+Farms allow you to have a single DokuWiki installation (The "Farmer") that powers an arbitrary number of
+other wikis (The "Animals"). You install plugins and templates in the Farmer only and then make them available
+through to the animals. You only need to keep one wiki uptodate and all other wikis just use the same code base.
+
+After completing this setup step your current DokuWiki (the one you're looking at) will be known as the "Farmer".
+
+===== What does this Setup do? =====
+
+This setup wizard will do three things:
+
+ - create a ''inc/preload.php'' file
+ - create a ''conf/farm.ini'' file
+ - optionally append to the ''.htaccess'' file
+
+The ''preload.php'' is a file that is loaded at the very beginning of loading DokuWiki. Here the farm mechanism is
+inititialized. The Farmer plugin will detect if the current request should access an Animal or the Farmer and
+reconfigure everything accordingly.
+
+The ''conf/farm.ini'' contains the basic configuration of the farm setup. Most importantly it will contain the
+location where all the animal's data will be stored.
+
+The ''.htaccess'' modification makes animals accessible through the //bang!// mechanism. (See below)
+
+===== What to fill in? =====
+
+The **Animal Directory** is where a new directory is created for each Animal you create. This directory has to be
+outside your current DokuWiki. You can specify a relative directory like ''../animals''.
+
+Enabling the **.htaccess** support is recommended. This feature requires Apache with mod_rewrite and .htaccess support.
+
+When enabled, your animals will be accessible under the farmer's URL using the //bang!// mechanism. Eg. if your farmer is
+running at ''%%http://www.example.com/dokuwiki/%%'', an animal will be accessible at
+''%%http://www.example.com/dokuwiki/!animal%%''.
+
+If you do not enable this, you will have to configure your Webserver and DNS to access the animals.
diff --git a/platform/www/lib/plugins/farmer/lang/fr/lang.php b/platform/www/lib/plugins/farmer/lang/fr/lang.php
new file mode 100644
index 0000000..8171952
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/lang.php
@@ -0,0 +1,109 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Schplurtz le Déboulonné <schplurtz@laposte.net>
+ * @author ubibene <services.m@benard.info>
+ */
+$lang['menu'] = 'Élevage';
+$lang['tab_setup'] = 'Configuration de la ferme';
+$lang['tab_info'] = 'Info';
+$lang['tab_config'] = 'Configuration';
+$lang['tab_plugins'] = 'Gestion des greffons';
+$lang['tab_new'] = 'Ajouter un animal';
+$lang['tab_delete'] = 'Supprimer un animal';
+$lang['preloadPHPForm'] = 'Initialiser la ferme';
+$lang['farm dir'] = 'Dossier des animaux';
+$lang['htaccess setup'] = 'Ajouter le code d\'élevage au .htaccess ?';
+$lang['submit'] = 'Envoyer';
+$lang['farmdir_missing'] = 'Veuillez entrer un dossier où stocker les animaux.';
+$lang['farmdir_in_dokuwiki'] = 'Le dossier des animaux (%s) doit se trouver hors de la ferme DokuWiki (%s).';
+$lang['farmdir_uncreatable'] = 'Impossible de créer le dossier (%s). Les permissions sont-elles correctes ?';
+$lang['farmdir_unwritable'] = 'Veuillez vous assurer que le serveur web dispose d\'un accès en écriture au dossier des animaux (%s) !';
+$lang['farmdir_notEmpty'] = 'Le dossier des animaux (%s) doit être vide.';
+$lang['preload creation success'] = 'Configuration de la ferme réalisée.';
+$lang['preload creation error'] = 'Il y a eu une erreur lors de l\'initialisation de l\'élevage.';
+$lang['overwrite_preload'] = 'Attention, votre fichier existant inc/preload.php va être écrasé si vous continuez !';
+$lang['animal'] = 'Nom d\'animal / Domaine';
+$lang['thisis'] = 'L\'instance est';
+$lang['thisis.farmer'] = 'Le fermier!';
+$lang['thisis.animal'] = 'Un animal!';
+$lang['baseinstall'] = 'Installation de la ferme';
+$lang['animals'] = 'Animaux';
+$lang['confdir'] = 'Dossier de configuration de l\'instance';
+$lang['savedir'] = 'Dossier des données de l\'instance';
+$lang['plugins'] = 'Greffons actifs dans cette instance';
+$lang['base'] = 'Configuration de base';
+$lang['farm host'] = 'Nom d\'hôte du fermier';
+$lang['base domain'] = 'Domaine de base pour les animaux par sous-domaine';
+$lang['conf_inherit'] = 'Réglage dont les animaux vont hériter';
+$lang['conf_inherit_main'] = 'Options de configuraton';
+$lang['conf_inherit_acronyms'] = 'Définitions des acronymes';
+$lang['conf_inherit_entities'] = 'Définitions des entités';
+$lang['conf_inherit_interwiki'] = 'Liens interwiki';
+$lang['conf_inherit_license'] = 'Licence du contenu';
+$lang['conf_inherit_mime'] = 'Types MIME';
+$lang['conf_inherit_scheme'] = 'Schémas d\'URL';
+$lang['conf_inherit_smileys'] = 'Frimousses';
+$lang['conf_inherit_wordblock'] = 'Liste noire des spammeurs';
+$lang['conf_inherit_userstyle'] = 'Styles utilisateur';
+$lang['conf_inherit_userscript'] = 'Scripts utilisateur';
+$lang['conf_inherit_styleini'] = 'Personnalisations du style du thème ';
+$lang['conf_inherit_users'] = 'utilisateurs (Auth texte seulement)';
+$lang['conf_inherit_plugins'] = 'État des greffons';
+$lang['conf_inherit_yes'] = 'hérité du fermier';
+$lang['conf_inherit_no'] = 'indépendant du fermier';
+$lang['conf_notfound'] = 'Comportement lors d\'un accès à un animal inexistant';
+$lang['conf_notfound_farmer'] = 'Montrer le wiki fermier';
+$lang['conf_notfound_404'] = 'Montrer une page 404';
+$lang['conf_notfound_list'] = 'Montrer la liste des animaux disponibles';
+$lang['conf_notfound_redirect'] = 'Rediriger vers l\'URL ci-dessous';
+$lang['conf_notfound_url'] = 'URL de redirection si sélectionné ci-dessus';
+$lang['save'] = 'Enregistrer';
+$lang['animal template'] = 'Copier un animal existant';
+$lang['animal creation success'] = 'L\'animal "%s" a été créé avec succès.';
+$lang['animal creation error'] = 'Il y a eu une erreur lors de la création de l\'animal.';
+$lang['animal configuration'] = 'Configuration de base de l\'animal';
+$lang['inherit user registration'] = 'Hériter le réglage d\'enregistrement des utilisateurs.';
+$lang['enable user registration'] = 'Autoriser les utilisateurs à s\'enregistrer';
+$lang['disable user registration'] = 'Désactiver l\'enregistrement des utilisateurs';
+$lang['animal administrator'] = 'Administrateur d\'animal';
+$lang['noUsers'] = 'Ne pas créer d\'utilisateur';
+$lang['importUsers'] = 'Exporter les utilisateurs du fermier vers l\'animal';
+$lang['currentAdmin'] = 'Définir l\'utilisateur courant comme admin';
+$lang['newAdmin'] = 'Créer un nouvel administrateur "admin"';
+$lang['admin password'] = 'Mot de passe du nouvel admin';
+$lang['animalname_missing'] = 'Veuillez saisir le nom du nouvel animal.';
+$lang['animalname_invalid'] = 'Le nom de l\'animal ne doit contenir que des caractères alphanumériques et les points et tirets (mais pas en premier ou en dernier).';
+$lang['animalname_preexisting'] = 'Un animal avec ce nom existe déjà.';
+$lang['adminPassword_empty'] = 'Le mot de passe du nouvel administrateur ne peux pas être vide.';
+$lang['animal template copy error'] = 'Il y a eu un problème en copiant %s de l\'animal existant vers le nouveau.';
+$lang['aclpolicy missing/bad'] = 'Veuillez choisir une politique d\'ACL initiale.';
+$lang['bulkSingleSwitcher'] = 'Modifier un seul animal ou tout le troupeau ?';
+$lang['bulkEdit'] = 'Modifier tout le troupeau';
+$lang['singleEdit'] = 'Modifier un seul animal';
+$lang['bulkEditForm'] = 'Activer ou désactiver un greffon sur tout le troupeau.';
+$lang['matrixEdit'] = 'Modifier la matrice Animal/Greffon';
+$lang['default'] = 'Hériter du fermier';
+$lang['activate'] = 'Activer';
+$lang['deactivate'] = 'Désactiver';
+$lang['singleEditForm'] = 'Éditer les greffons d\'un animal particulier';
+$lang['plugindone'] = 'État du greffon mis à jour';
+$lang['plugin'] = 'Greffon';
+$lang['plugin_on'] = 'marche';
+$lang['plugin_off'] = 'arrêt';
+$lang['plugin_default'] = 'Herité';
+$lang['plugin_enabled'] = 'Activé';
+$lang['plugin_disabled'] = 'Désactivé';
+$lang['js']['animalSelect'] = 'Sélectionnez un animal';
+$lang['js']['pluginSelect'] = 'Sélectionnez un greffon';
+$lang['disable_new_plugins'] = 'Le greffon est par défaut désactivé. Vous pouvez l\'activer ici ou pour certains animaux spécifiques seulement.';
+$lang['delete_animal'] = 'Sélectionnez l\'animal à détruire';
+$lang['delete_confirm'] = 'Veuillez taper le nom de l\'animal pour confirmer';
+$lang['delete'] = 'Détruire l\'animal et toutes ses données';
+$lang['delete_noanimal'] = 'Veuillez sélectionner l\'animal à détruire';
+$lang['delete_mismatch'] = 'La confirmation ne correspond pas à l\'animal. Destruction annulée.';
+$lang['delete_invalid'] = 'Nom d\'animal invalide. Destruction annulée';
+$lang['delete_success'] = 'Animal supprimé avec succès.';
+$lang['delete_fail'] = 'Impossible de supprimer certains fichiers. Vous devriez faire le ménage à la main.';
diff --git a/platform/www/lib/plugins/farmer/lang/fr/notfound_404.txt b/platform/www/lib/plugins/farmer/lang/fr/notfound_404.txt
new file mode 100644
index 0000000..5aaa62d
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/notfound_404.txt
@@ -0,0 +1,3 @@
+====== 404 Non trouvé ======
+
+La ressource demandée ne peut être trouvée.
diff --git a/platform/www/lib/plugins/farmer/lang/fr/notfound_list.txt b/platform/www/lib/plugins/farmer/lang/fr/notfound_list.txt
new file mode 100644
index 0000000..3a6acc7
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/notfound_list.txt
@@ -0,0 +1,4 @@
+====== Wiki non trouvé ======
+
+Impossible de trouver le wiki que vous avez demandé. Veuillez
+vous référer à la liste ci-dessous.
diff --git a/platform/www/lib/plugins/farmer/lang/fr/settings.php b/platform/www/lib/plugins/farmer/lang/fr/settings.php
new file mode 100644
index 0000000..ed4465c
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/settings.php
@@ -0,0 +1,9 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Schplurtz le Déboulonné <Schplurtz@laposte.net>
+ */
+$lang['deactivated plugins'] = 'Liste à virgule des greffons qui sont désactivés par défaut dans les nouveaux animaux.';
+$lang['disable_new_plugins'] = 'Désactiver automatiquement les greffons après qu\'il sont installés dans le fermier. Valable seulement pour les greffons installés par le gestionnaire d\'extensions.';
diff --git a/platform/www/lib/plugins/farmer/lang/fr/tab_config.txt b/platform/www/lib/plugins/farmer/lang/fr/tab_config.txt
new file mode 100644
index 0000000..edee83f
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/tab_config.txt
@@ -0,0 +1 @@
+Ici, le comportement de base de la ferme est configurée. Veuillez garder à l'esprit que changer des options ici affecte tous les animaux.
diff --git a/platform/www/lib/plugins/farmer/lang/fr/tab_config_help.txt b/platform/www/lib/plugins/farmer/lang/fr/tab_config_help.txt
new file mode 100644
index 0000000..28790e4
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/tab_config_help.txt
@@ -0,0 +1,37 @@
+===== Configuration de la ferme =====
+
+Tous les réglages faits ici sont enregistrés dans le fichier ''conf/farm.ini'' du fermier.
+
+==== Configuration de base ====
+
+Le réglage de **Nom d'hôte du fermier** a été effectué automatiquement
+pendant l'initialisation, mais on peut le changer ici. Il sera utilisé
+pour déterminer si une requête est dirigée directement vers le fermier,
+lors de l'utilisation d'une ferme par nom. Ce devrait être un FQDN,
+''toto.example.com'' au lieu de simplement ''toto''.
+
+Lors de l'utilisation d'une configuration avec sous domaine
+générique((//wildcard subdomain//)), vous devez spécifier le
+nom principal dans le réglage **Domaine de base pour les animaux
+par sous domaine**. Par exemple, si vous indiquez ''example.com'',
+on part du principe qu'un animal nommé ''toto'' est joignable via
+''toto.example.com''. Le **Domaine de base** est simplement ajouté aux
+noms des animaux ne contenant aucun point.
+
+==== Héritage ====
+
+Vous pouvez indiquer ici quels réglages de configuration réalisés dans
+le fermier devraient être utilisés comme défaut dans les animaux.
+les animaux peuvent toujours écraser ces réglages dans leurs propres
+fichiers de configuration. Lorsque l'héritage est désactivé, les
+valeurs par défaut de DokuWiki sont également les valeurs par défaut
+pour les nouveaux animaux.
+
+==== Animaux non existant ====
+
+Par défaut, lors d'une tentative d'accès à un animal inexistant,
+aucun message d'erreur n'est affiché. Ici, vous pouvez choisir entre
+différents comportements. Assurez vous que le nom d'hôte du fermier
+soit correctement réglé ci-dessus avant de vous écarter des valeurs
+par défaut.
+
diff --git a/platform/www/lib/plugins/farmer/lang/fr/tab_delete.txt b/platform/www/lib/plugins/farmer/lang/fr/tab_delete.txt
new file mode 100644
index 0000000..73fb7ff
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/tab_delete.txt
@@ -0,0 +1 @@
+Vous pouvez détruire les animaux existant ici. Cela détruit **toutes les données, y compris les pages et médias** des animaux sélectionnés. **Ceci est irréversible** !
diff --git a/platform/www/lib/plugins/farmer/lang/fr/tab_info.txt b/platform/www/lib/plugins/farmer/lang/fr/tab_info.txt
new file mode 100644
index 0000000..e1a4ee0
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/tab_info.txt
@@ -0,0 +1 @@
+Ce wiki fait partie d'une ferme. Consultez les détails ci-dessous.
diff --git a/platform/www/lib/plugins/farmer/lang/fr/tab_new.txt b/platform/www/lib/plugins/farmer/lang/fr/tab_new.txt
new file mode 100644
index 0000000..269260d
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/tab_new.txt
@@ -0,0 +1 @@
+Vous pouvez créer un nouvel animal ici.
diff --git a/platform/www/lib/plugins/farmer/lang/fr/tab_new_help.txt b/platform/www/lib/plugins/farmer/lang/fr/tab_new_help.txt
new file mode 100644
index 0000000..7405a3b
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/tab_new_help.txt
@@ -0,0 +1,43 @@
+===== Création d'animaux =====
+
+Les animaux sont des sous-wikis indépendants d'une ferme de DokuWiki. Pour créer un nouvel animal, il faut lui assigner un nom.
+
+==== Les noms d'animaux ====
+
+Pour les fermes basées sur la réécriture par fichier .htaccess
+cela devrait être un seul mot.
+Pour les configurations basées sur les noms de domaine vous devriez indiquer
+un nom de domaine totalement qualifié (FQDN).
+Pour les fermes à base de sous domaine générique((//wildcard subdomain//
+en bon anglais)), un nom d'hôte suffit, à condition
+d'indiquer également un domaine de base.
+
+Exemples:
+
+ * basé sur .htaccess : ''toto'' pour un animal accessible à ''%%http://example.org/dokuwiki/!toto/%%''
+ * basé sur le domaine : ''%%www.toto.com%%'' pour un animal accessible à ''%%http://www.toto.com/%%''
+ * basé sur le sous domaine : ''toto'' pour un animal accessible à ''%%http://toto.example.com/%%''
+
+Les deux derniers nécessitent un réglage du DNS approprié !
+
+==== Copie d'animal ====
+
+Vous pouvez sélectionner un animal existant comme base d'un
+nouvel animal. Toute la configuration, toutes les pages et fichiers
+médias, ainsi que les méta données seront copiés vers le nouvel
+animal. L'historique des pages et médias ne sera pas copié.
+
+Le titre et l'image de logo seront modifiés de manière à être certain
+que vous pourrez distinguer la nouvelle copie de l'ancien.
+
+==== Administrateur de l'animal ====
+
+L'animal sera un wiki complètement fonctionnel, avec sa propre base
+d'utilisateurs. Vous aurez besoin d'au moins un administrateur pour le
+gérer. Vous pouvez copier l'utilisateur courant, tous les utilisateurs
+du fermier, ou créer un tout nouvel utilisateur pour l'animal.
+
+Vous pouvez choisir de ne pas créer d'utilisateur. Vous ne devriez
+choisir cette possibilité que si l'héritage d'utilisateurs du fermier
+est activé dans l'onglet de configuration, ou si vous avez copié un
+animal déjà muni d'utilisateurs.
diff --git a/platform/www/lib/plugins/farmer/lang/fr/tab_plugins.txt b/platform/www/lib/plugins/farmer/lang/fr/tab_plugins.txt
new file mode 100644
index 0000000..f7c49e5
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/tab_plugins.txt
@@ -0,0 +1 @@
+Vous pouvez activer ou désactiver soit un même greffon pour tous les animaux en une seule opération de masse, soit les greffons d'un animal particulier.
diff --git a/platform/www/lib/plugins/farmer/lang/fr/tab_plugins_help.txt b/platform/www/lib/plugins/farmer/lang/fr/tab_plugins_help.txt
new file mode 100644
index 0000000..179ab63
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/tab_plugins_help.txt
@@ -0,0 +1,22 @@
+===== Gestion des greffons =====
+
+Le gestionnaire d'extensions est désactivé dans tous les animaux. On peut
+uniquement installer les thèmes et greffons dans le fermier.
+Seul le fermier peut contrôler quels greffons
+sont activés dans les animaux. La présente interface permet d'effectuer
+ces réglages.
+
+Un greffon peut avoir trois états dans un animal. Il peut être activé, ou désactivé. Il peut également avoir l'état par défaut. Cette dernière option signifie que l'état du greffon n'est pas explicitement choisi pour un animal. Habituellement, l'état par défaut est <<activé>>.
+
+Lorsque les animaux sont configurés pour hériter l'état du fermier, un
+greffon dans l'état par défaut aura le même état que dans le fermier.
+C'est à dire que désactiver un greffon dans le fermier le désactivera
+aussi dans tous les animaux pour lesquels l'état du greffon n'a pas été
+explicitement spécifié. Si vous l'activez à nouveau dans le fermier,
+le greffon s'activera de la même manière dans tous les animaux
+concernés.
+
+Il existe trois manières de gérer les greffons :
+ - Choisir un greffon et fixer son état à la même valeur dans tous les animaux,
+ - Choisir un animal particulier et gérer l'état de chacun de ses greffons.
+ - Voir et éditer l'état de tous les greffons dans tous les animaux d'un seul coup. Cette option pourrait ne pas être praticable si vous avez un grand nombre d'animaux.
diff --git a/platform/www/lib/plugins/farmer/lang/fr/tab_setup.txt b/platform/www/lib/plugins/farmer/lang/fr/tab_setup.txt
new file mode 100644
index 0000000..f6dbdb3
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/tab_setup.txt
@@ -0,0 +1 @@
+Votre Wiki est pas configuré pour l'élevage avec le greffon //farmer//. Veuillez utiliser la boîte de dialogue suivante pour la mise en place de la ferme.
diff --git a/platform/www/lib/plugins/farmer/lang/fr/tab_setup_help.txt b/platform/www/lib/plugins/farmer/lang/fr/tab_setup_help.txt
new file mode 100644
index 0000000..66a3ccc
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/fr/tab_setup_help.txt
@@ -0,0 +1,52 @@
+===== À propos de l'élevage =====
+
+L'élevage est une technique qui permet, à partir d'une unique
+installation de DokuWiki, connue comme le <<fermier>>, de propulser
+un nombre quelconque d'autres wikis appelés les animaux. Vous installez les
+greffons et thèmes uniquement dans le fermier, et les rendez disponibles
+à votre guise dans des animaux. Il suffit de mettre à jour le wiki principal et
+tous les autres wikis, qui partagent la même base de code, sont également mis
+à jour.
+
+Après avoir complété cette étape de configuration, votre wiki actuel,
+celui que vous lisez en ce moment même, sera connu comme le <<fermier>>.
+
+===== Que fait cette initialisation ? =====
+
+Cet assistant de configuration fera trois choses :
+
+ - Créer un fichier ''inc/preload.php'',
+ - créer un fichier ''conf/farm.ini''
+ - facultativement, ajouter un fichier ''.htaccess''.
+
+''preload.php'' est un fichier qui est chargé au tout début du chargement de DokuWiki.
+Là, le mécanisme de ferme est initialisé. Le greffon //farmer// détectera si la requête
+doit être adressée à un animal ou au fermier, et reconfigurera l'ensemble de manière
+appropriée.
+
+''conf/farm.ini'' contient les configurations de base du système de ferme. En particulier,
+ce fichier contient l'emplacement où les données des animaux seront
+enregistrées.
+
+La modification du fichier ''.htaccess'' permet de rendre accessible les animaux via
+le mécanisme ''!bang'' (voir ci-dessous).
+
+===== Que remplir ? =====
+
+Le **Dossier des animaux** est le dossier où un nouveau dossier est créé pour
+chaque nouvel animal. Ce dossier **doit** se trouver en dehors de l'arborescence
+de votre DokuWiki actuel. Vous pouvez utiliser un dossier relatif, tel que
+''../animaux'' ou un chemin absolu.
+
+Il est recommandé d'activer l'utilisation du fichier ''.htaccess''. Cette fonctionnalité
+nécessite un serveur [[https://httpd.apache.org/|Apache]] avec le module
+mod_rewrite et la prise en charge des fichiers .htaccess.
+
+Lorsque vous activez le .htaccess, les animaux sont accessibles sous l'URL du
+wiki fermier en utilisant le suffixe //!bang//. Par exemple, si votre fermier
+est accessible à l'URL
+''%%http://www.example.com/dokuwiki/%%'', l'animal toto sera accessible à
+l'URL ''%%http://www.example.com/dokuwiki/!toto%%''.
+
+Si vous n'activez pas ce mécanisme, vous devrez configurer votre serveur web
+et votre DNS pour pouvoir accéder aux animaux.
diff --git a/platform/www/lib/plugins/farmer/lang/ja/lang.php b/platform/www/lib/plugins/farmer/lang/ja/lang.php
new file mode 100644
index 0000000..f837a3a
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/lang.php
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Hideaki SAWADA <chuno@live.jp>
+ */
+$lang['menu'] = '牧場設定';
+$lang['tab_setup'] = '牧場設定';
+$lang['tab_info'] = '情報';
+$lang['tab_config'] = '設定';
+$lang['tab_plugins'] = 'プラグイン管ç†';
+$lang['tab_new'] = 'æ–°ã—ã„動物ã®è¿½åŠ ';
+$lang['tab_delete'] = '動物ã®å‰Šé™¤';
+$lang['preloadPHPForm'] = '牧場ã®åˆæœŸåŒ–';
+$lang['farm dir'] = '動物用ディレクトリ';
+$lang['htaccess setup'] = '.htaccess ã«ç‰§å ´ç”¨ã®ã‚³ãƒ¼ãƒ‰ã‚’追加ã—ã¾ã™ã‹ï¼Ÿ';
+$lang['submit'] = '実行';
+$lang['farmdir_missing'] = '動物をä¿å­˜ã™ã‚‹ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’入力ã—ã¦ãã ã•ã„。';
+$lang['farmdir_in_dokuwiki'] = '動物用ディレクトリã¯ç‰§å ´ dokuwiki ã®å¤–ã«ã‚ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚';
+$lang['farmdir_uncreatable'] = '動物用ディレクトリを作æˆã§ãã¾ã›ã‚“ã§ã—ãŸã€‚権é™ã¯é©åˆ‡ã§ã™ã‹ï¼Ÿ';
+$lang['farmdir_unwritable'] = 'Web サーãƒãŒå‹•ç‰©ç”¨ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã«æ›¸ãè¾¼ã¿æ¨©ã‚’æŒã£ã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„ï¼';
+$lang['farmdir_notEmpty'] = '動物用ディレクトリã¯ç©ºã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。';
+$lang['preload creation success'] = '牧場ã¯æ­£å¸¸ã«åˆæœŸåŒ–ã•ã‚Œã¾ã—ãŸã€‚';
+$lang['preload creation error'] = '牧場ã®åˆæœŸåŒ–中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚';
+$lang['overwrite_preload'] = '警告:続行ã™ã‚‹ã¨ã€æ—¢å­˜ã® inc/preload.php ãŒä¸Šæ›¸ãã•ã‚Œã¾ã™ï¼';
+$lang['animal'] = '動物å・ドメイン';
+$lang['thisis'] = 'インスタンスã¯';
+$lang['thisis.farmer'] = '牧場主ã§ã™ï¼';
+$lang['thisis.animal'] = '動物ã§ã™ï¼';
+$lang['baseinstall'] = '牧場主ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«å…ˆ';
+$lang['animals'] = '動物';
+$lang['confdir'] = 'インスタンスã®è¨­å®šãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª';
+$lang['savedir'] = 'インスタンスã®ãƒ‡ãƒ¼ã‚¿ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª';
+$lang['plugins'] = 'ã“ã®ã‚¤ãƒ³ã‚¹ã‚¿ãƒ³ã‚¹ã§æœ‰åŠ¹ãªãƒ—ラグイン';
+$lang['base'] = '基本設定';
+$lang['farm host'] = '牧場主ホストå';
+$lang['base domain'] = '動物サブドメイン用ã®ãƒ™ãƒ¼ã‚¹ãƒ‰ãƒ¡ã‚¤ãƒ³';
+$lang['conf_inherit'] = '動物ãŒç¶™æ‰¿ã™ã‚‹ç‰§å ´ä¸»è¨­å®š';
+$lang['conf_inherit_main'] = 'DokuWiki 設定';
+$lang['conf_inherit_acronyms'] = '略字ã¨é ­å­—語';
+$lang['conf_inherit_entities'] = '記å·ã¸ã®å¤‰æ›';
+$lang['conf_inherit_interwiki'] = 'InterWiki リンク';
+$lang['conf_inherit_license'] = 'ライセンス';
+$lang['conf_inherit_mime'] = 'MIME ã®è¨­å®š';
+$lang['conf_inherit_scheme'] = 'URL スキーム';
+$lang['conf_inherit_smileys'] = 'スマイリー';
+$lang['conf_inherit_wordblock'] = 'ブラックリスト';
+$lang['conf_inherit_userstyle'] = 'ユーザースタイル';
+$lang['conf_inherit_users'] = 'ユーザー(テキストèªè¨¼ã®å ´åˆã®ã¿ï¼‰';
+$lang['conf_inherit_plugins'] = 'プラグインã®çŠ¶æ…‹';
+$lang['conf_inherit_yes'] = '牧場主ã‹ã‚‰ç¶™æ‰¿';
+$lang['conf_inherit_no'] = '牧場主ã‹ã‚‰ç‹¬ç«‹';
+$lang['conf_notfound'] = '実在ã—ãªã„動物ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹æ™‚ã®å‹•ä½œ';
+$lang['conf_notfound_farmer'] = '牧場主を表示';
+$lang['conf_notfound_404'] = '404 エラーページを表示';
+$lang['conf_notfound_list'] = '利用å¯èƒ½ãªå‹•ç‰©ä¸€è¦§ã‚’表示';
+$lang['conf_notfound_redirect'] = '以下㮠URL ã¸è»¢é€';
+$lang['conf_notfound_url'] = '上記é¸æŠžã—ãŸå ´åˆã€è»¢é€å…ˆã® URL';
+$lang['save'] = 'ä¿å­˜';
+$lang['animal template'] = '既存ã®å‹•ç‰©ã‚’コピーã™ã‚‹';
+$lang['animal creation success'] = '動物 "%s" ã¯æ­£å¸¸ã«ä½œæˆã•ã‚Œã¾ã—ãŸã€‚';
+$lang['animal creation error'] = '動物ã®ä½œæˆä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚';
+$lang['animal configuration'] = '基本的ãªå‹•ç‰©è¨­å®š';
+$lang['inherit user registration'] = '牧場主ã‹ã‚‰ãƒ¦ãƒ¼ã‚¶ãƒ¼ç™»éŒ²è¨­å®šã‚’継承ã™ã‚‹';
+$lang['enable user registration'] = '自分ã§ãƒ¦ãƒ¼ã‚¶ãƒ¼ç™»éŒ²ã™ã‚‹ã“ã¨ã‚’許å¯ã™ã‚‹';
+$lang['disable user registration'] = 'ユーザー登録を無効化ã™ã‚‹';
+$lang['animal administrator'] = '動物ã®ç®¡ç†è€…';
+$lang['noUsers'] = 'ユーザーを作æˆã—ãªã„';
+$lang['importUsers'] = '牧場主ã®å…¨ã¦ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’æ–°ã—ã„動物ã«å…¥åŠ›ã™ã‚‹';
+$lang['currentAdmin'] = 'ç¾åœ¨ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’ admin ã¨ã—ã¦è¨­å®šã™ã‚‹';
+$lang['newAdmin'] = 'æ–°ã—ã„管ç†è€…ユーザー "admin" を作æˆã™ã‚‹';
+$lang['admin password'] = 'æ–°ã—ã„管ç†è€…ã®ãƒ‘スワード';
+$lang['animalname_missing'] = 'æ–°ã—ã„動物ã®åå‰ã‚’入力ã—ã¦ãã ã•ã„。';
+$lang['animalname_invalid'] = '動物ã®åå‰ã«ã¯ã€è‹±æ•°å­—ã¨ãƒ‰ãƒƒãƒˆãƒ»ãƒã‚¤ãƒ•ãƒ³ï¼ˆæœ€åˆã¾ãŸã¯æœ€å¾Œã®æ–‡å­—以外)ã®ã¿ã‚’使用ã§ãã¾ã™ã€‚';
+$lang['animalname_preexisting'] = 'ãã®åå‰ã®å‹•ç‰©ã¯ã™ã§ã«å­˜åœ¨ã—ã¦ã„ã¾ã™ã€‚';
+$lang['adminPassword_empty'] = 'æ–°ã—ã„管ç†è€…アカウントã®ãƒ‘スワードã¯ç©ºã§ã¯ã„ã‘ã¾ã›ã‚“。';
+$lang['animal template copy error'] = '既存ã®å‹•ç‰©ã‹ã‚‰ %s をコピーã™ã‚‹éš›ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚';
+$lang['aclpolicy missing/bad'] = 'ドロップダウンã‹ã‚‰æœ€åˆã® ACL ãƒãƒªã‚·ãƒ¼ã‚’é¸æŠžã—ã¦ãã ã•ã„。';
+$lang['bulkSingleSwitcher'] = '特定ã®å‹•ç‰©ã‚’設定ã—ã¾ã™ã‹ï¼Ÿå…¨å‹•ç‰©ã‚’一括設定ã—ã¾ã™ã‹ï¼Ÿ';
+$lang['bulkEdit'] = '全動物を一括設定ã™ã‚‹';
+$lang['singleEdit'] = '特定ã®å‹•ç‰©ã‚’設定ã™ã‚‹';
+$lang['bulkEditForm'] = '特定ã®ãƒ—ラグインを全動物一括ã§è¨­å®šã™ã‚‹';
+$lang['matrixEdit'] = '一覧(動物×プラグイン)ã§è¨­å®šã™ã‚‹';
+$lang['default'] = 'デフォルト値を設定';
+$lang['activate'] = '有効化';
+$lang['deactivate'] = '無効化';
+$lang['singleEditForm'] = '特定ã®å‹•ç‰©ã®ãƒ—ラグインを設定ã™ã‚‹';
+$lang['plugindone'] = 'プラグインã®çŠ¶æ…‹ã¯æ›´æ–°ã•ã‚Œã¾ã—ãŸ';
+$lang['plugin'] = 'プラグイン';
+$lang['plugin_on'] = '有効';
+$lang['plugin_off'] = '無効';
+$lang['plugin_default'] = 'デフォルト値';
+$lang['plugin_enabled'] = '個別ã«æœ‰åŠ¹åŒ–';
+$lang['plugin_disabled'] = '個別ã«ç„¡åŠ¹åŒ–';
+$lang['js']['animalSelect'] = '動物をé¸æŠžã™ã‚‹';
+$lang['js']['pluginSelect'] = 'プラグインをé¸æŠžã™ã‚‹';
+$lang['disable_new_plugins'] = 'プラグインã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚デフォルト値を有効ã«ã™ã‚‹ã‹ç‰¹å®šã®å‹•ç‰©ã«å¯¾ã—ã¦æœ‰åŠ¹ã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚';
+$lang['delete_animal'] = 'é¸æŠžã—ãŸå‹•ç‰©ã®å‰Šé™¤';
+$lang['delete_confirm'] = '確èªã®ãŸã‚ã«å‹•ç‰©ã®åå‰ã‚’入力ã—ã¦ãã ã•ã„';
+$lang['delete'] = '動物ã¨ãã®ã™ã¹ã¦ã®ãƒ‡ãƒ¼ã‚¿ã‚’削除ã—ã¾ã™';
+$lang['delete_noanimal'] = '削除ã™ã‚‹å‹•ç‰©ã‚’é¸æŠžã—ã¦ãã ã•ã„';
+$lang['delete_mismatch'] = '確èªå…¥åŠ›ã¯å‹•ç‰©ã®åå‰ã¨ä¸€è‡´ã—ã¾ã›ã‚“。 削除ã•ã‚Œã¾ã›ã‚“。';
+$lang['delete_invalid'] = '無効ãªå‹•ç‰©ã®åå‰ã§ã™ã€‚ 削除ã•ã‚Œã¾ã›ã‚“。';
+$lang['delete_success'] = '動物ã¯æ­£å¸¸ã«å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚';
+$lang['delete_fail'] = '一部ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’削除ã§ããªã‹ã£ãŸãŸã‚ã€æ‰‹å‹•ã§ãã‚Œã„ã«ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚';
diff --git a/platform/www/lib/plugins/farmer/lang/ja/notfound_404.txt b/platform/www/lib/plugins/farmer/lang/ja/notfound_404.txt
new file mode 100644
index 0000000..3f575d6
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/notfound_404.txt
@@ -0,0 +1,3 @@
+====== 404 ã‚ã‚Šã¾ã›ã‚“ ======
+
+è¦æ±‚ã•ã‚ŒãŸãƒªã‚½ãƒ¼ã‚¹ãŒã‚ã‚Šã¾ã›ã‚“。
diff --git a/platform/www/lib/plugins/farmer/lang/ja/notfound_list.txt b/platform/www/lib/plugins/farmer/lang/ja/notfound_list.txt
new file mode 100644
index 0000000..f3e633c
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/notfound_list.txt
@@ -0,0 +1,3 @@
+====== Wiki ãŒã‚ã‚Šã¾ã›ã‚“ ======
+
+è¦æ±‚ã•ã‚ŒãŸ Wiki ãŒã‚ã‚Šã¾ã›ã‚“。以下ã®åˆ©ç”¨å¯èƒ½ãª Wiki ã®ä¸€è¦§ã‚’å‚ç…§ã—ã¦ãã ã•ã„。
diff --git a/platform/www/lib/plugins/farmer/lang/ja/settings.php b/platform/www/lib/plugins/farmer/lang/ja/settings.php
new file mode 100644
index 0000000..dd9b6a6
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/settings.php
@@ -0,0 +1,9 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Hideaki SAWADA <chuno@live.jp>
+ */
+$lang['deactivated plugins'] = 'æ–°ã—ã„動物を作æˆã—ãŸå ´åˆã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ç„¡åŠ¹ã¨ã™ã‚‹ãƒ—ラグインã®ã‚«ãƒ³ãƒžåŒºåˆ‡ã‚Šä¸€è¦§ã€‚';
+$lang['disable_new_plugins'] = '牧場ã«ãƒ—ラグインを新è¦ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ãŸå¾Œã€ãƒ—ラグインを自動的ã«ç„¡åŠ¹åŒ–ã—ã¾ã™ã‹ï¼Ÿ(拡張機能管ç†ã§ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ãŸå ´åˆã®ã¿)';
diff --git a/platform/www/lib/plugins/farmer/lang/ja/tab_config.txt b/platform/www/lib/plugins/farmer/lang/ja/tab_config.txt
new file mode 100644
index 0000000..4d3619b
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/tab_config.txt
@@ -0,0 +1 @@
+牧場ã®åŸºæœ¬çš„ãªå‹•ä½œã‚’設定ã—ã¾ã™ã€‚ ã“ã“ã®ã‚ªãƒ—ションを変更ã™ã‚‹ã¨ã€å…¨ã¦ã®å‹•ç‰©ã«å½±éŸ¿ãŒåŠã¶ã®ã§ã”注æ„ãã ã•ã„。 \ No newline at end of file
diff --git a/platform/www/lib/plugins/farmer/lang/ja/tab_config_help.txt b/platform/www/lib/plugins/farmer/lang/ja/tab_config_help.txt
new file mode 100644
index 0000000..5e9e4b8
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/tab_config_help.txt
@@ -0,0 +1,25 @@
+===== 牧場設定 =====
+
+ã“ã“ã§å…¥åŠ›ã—ãŸè¨­å®šå†…容ã¯ã™ã¹ã¦ç‰§å ´ä¸»ã® ''conf/farm.ini'' ã«ä¿å­˜ã•ã‚Œã¾ã™ã€‚
+
+==== 基本設定 ====
+
+**牧場主ホストå**ã¯ã€è¨­å®šæ™‚ã«è‡ªå‹•çš„ã«è¨­å®šã•ã‚Œã¾ã™ãŒã€ã“ã“ã§å¤‰æ›´ã§ãã¾ã™ã€‚
+ホスト方å¼ç‰§å ´ã‚’使用ã™ã‚‹å ´åˆã€ç‰§å ´ä¸»ã«ç›´æŽ¥è¦æ±‚ã•ã‚ŒãŸã‹ã©ã†ã‹ã®æ¤œå‡ºã«ä½¿ç”¨ã—ã¾ã™ã€‚
+ã“ã‚Œã¯å®Œå…¨ä¿®é£¾ãƒ›ã‚¹ãƒˆåã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。(''foo'' ã®ã¿ã§ã¯ãªã ''foo.example.com'')
+
+サブドメインã®ãƒ¯ã‚¤ãƒ«ãƒ‰ã‚«ãƒ¼ãƒ‰è¨­å®šã‚’使用ã™ã‚‹å ´åˆã€**ベースドメイン**設定ã§ãƒ¡ã‚¤ãƒ³ãƒ‰ãƒ¡ã‚¤ãƒ³ã‚’指定ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+例ãˆã° ''example.com'' を指定ã—ãŸå ´åˆã€''foo'' ã¨ã„ã†åã®å‹•ç‰©ã¯ ''foo.example.com'' 経由ã§å±Šã想定ã—ã¾ã™ã€‚
+ベースドメインã«ã¯ãƒ‰ãƒƒãƒˆã‚’å«ã¾ãªã„動物åã ã‘ãŒä»˜åŠ ã•ã‚Œã¾ã™ã€‚
+
+==== 継承 ====
+
+ã“ã“ã§ã¯ã€ç‰§å ´ä¸»ä¸Šã§ä½œæˆã—ãŸã©ã®è¨­å®šã‚’動物内ã§ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã‹ã‚’指定ã§ãã¾ã™ã€‚
+動物ã¯ã€ç‹¬è‡ªã®è¨­å®šãƒ•ã‚¡ã‚¤ãƒ«ã§ç‰§å ´ä¸»ã®è¨­å®šã‚’上書ãã™ã‚‹ã“ã¨ã‚‚ã§ãã¾ã™ã€‚
+継承ãŒç„¡åŠ¹ã«ãªã£ã¦ã„ã‚‹å ´åˆã€DokuWiki ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆè¨­å®šãŒã€ã™ã¹ã¦ã®å‹•ç‰©ã®ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã§ã™ã€‚
+
+==== 実在ã—ãªã„動物 ====
+
+デフォルトã§ã¯ã€å®Ÿåœ¨ã—ãªã„動物ã¸ã®ã‚¢ã‚¯ã‚»ã‚¹æ™‚ã«ã‚¨ãƒ©ãƒ¼ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚’表示ã—ã¾ã›ã‚“。
+ã“ã“ã§ç•°ãªã‚‹å‹•ä½œã‚’é¸ã¶ã“ã¨ãŒã§ãã¾ã™ã€‚
+デフォルトã‹ã‚‰åˆ‡æ›¿ãˆã‚‹å‰ã«ã€ç‰§å ´ä¸»ãƒ›ã‚¹ãƒˆåãŒä¸Šè¨˜ã«æ­£ã—ã設定ã•ã‚Œã¦ã„ã‚‹ã“ã¨ã‚’確èªã—ã¦ä¸‹ã•ã„。
diff --git a/platform/www/lib/plugins/farmer/lang/ja/tab_delete.txt b/platform/www/lib/plugins/farmer/lang/ja/tab_delete.txt
new file mode 100644
index 0000000..bde0596
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/tab_delete.txt
@@ -0,0 +1 @@
+既存ã®å‹•ç‰©ã‚’削除ã§ãã¾ã™ã€‚ é¸æŠžã—ãŸå‹•ç‰©ã®**ページやメディアファイルをå«ã‚€å…¨ã¦ã®ãƒ‡ãƒ¼ã‚¿**を削除ã—ã¾ã™ã€‚ **å…ƒã«æˆ»ã›ãªã„ã®ã§æ³¨æ„ã—ã¦ä¸‹ã•ã„ï¼** \ No newline at end of file
diff --git a/platform/www/lib/plugins/farmer/lang/ja/tab_info.txt b/platform/www/lib/plugins/farmer/lang/ja/tab_info.txt
new file mode 100644
index 0000000..78ea6c7
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/tab_info.txt
@@ -0,0 +1 @@
+ã“ã® Wiki ã¯ã€ç‰§å ´è¨­å®šã®ä¸€éƒ¨åˆ†ã§ã™ã€‚ 以下ã®è©³ç´°ã‚’確èªã—ã¦ãã ã•ã„。 \ No newline at end of file
diff --git a/platform/www/lib/plugins/farmer/lang/ja/tab_new.txt b/platform/www/lib/plugins/farmer/lang/ja/tab_new.txt
new file mode 100644
index 0000000..78d5975
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/tab_new.txt
@@ -0,0 +1 @@
+æ–°ã—ã„動物を作æˆã§ãã¾ã™ã€‚ \ No newline at end of file
diff --git a/platform/www/lib/plugins/farmer/lang/ja/tab_new_help.txt b/platform/www/lib/plugins/farmer/lang/ja/tab_new_help.txt
new file mode 100644
index 0000000..9287e1f
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/tab_new_help.txt
@@ -0,0 +1,38 @@
+===== 動物ã®ä½œæˆ =====
+
+動物ã¯ã€Dokuwiki 牧場ã®ç‹¬ç«‹ã—ãŸã‚µãƒ– wiki ã§ã™ã€‚
+æ–°ã—ã„動物を作æˆã™ã‚‹ã«ã¯åå‰ã‚’割り当ã¦ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。
+
+==== 動物å ====
+
+.htaccess æ–¹å¼ã®è¨­å®šã®å ´åˆã€å‹•ç‰©åã¯ä¸€ã¤ã®å˜èªžã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。
+ドメイン方å¼ã®è¨­å®šã®å ´åˆã€å®Œå…¨ä¿®é£¾ãƒ‰ãƒ¡ã‚¤ãƒ³åã‚’æä¾›ã™ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
+ワイルドカードサブドメインã®è¨­å®šã‚’使用ã—ã¦ã„ã‚‹å ´åˆã€ãƒ™ãƒ¼ã‚¹ãƒ‰ãƒ¡ã‚¤ãƒ³ãŒè¨­å®šæ¸ˆã¿ã§ã‚ã‚Œã°ã€å˜ã«ãƒ›ã‚¹ãƒˆå部分をæä¾›ã™ã‚‹ã ã‘ã§ã™ã€‚
+
+例:
+
+ * .htaccess æ–¹å¼ï¼š''%%http://example.org/dokuwiki/!foo/%%'' ã«ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ãªå‹•ç‰©ç”¨ã® ''foo''
+ * ドメイン方å¼ï¼š''%%http://www.foo.com/%%'' ã«ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ãªå‹•ç‰©ç”¨ã® ''%%www.foo.com%%''
+ * サブドメイン方å¼ï¼š ''%%http://foo.example.com/%%'' ã«ã‚¢ã‚¯ã‚»ã‚¹å¯èƒ½ãªå‹•ç‰©ç”¨ã® ''foo''
+
+後ã®äºŒã¤ã¯ã€é©åˆ‡ãª DNS 設定ãŒå¿…è¦ã§ã™ï¼
+
+==== 動物ã®ã‚³ãƒ”ー ====
+
+æ–°ã—ã„動物ã®åŸºç¤Žã«ã™ã‚‹ãŸã‚ã«æ—¢å­˜ã®å‹•ç‰©ã‚’é¸æŠžã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚
+ã™ã¹ã¦ã®è¨­å®šã€ãƒšãƒ¼ã‚¸ã€ãƒ¡ãƒ‡ã‚£ã‚¢ã€ãƒ¡ã‚¿ãƒ‡ãƒ¼ã‚¿ãŒæ–°ã—ã„動物ã«ã‚³ãƒ”ーã•ã‚Œã¾ã™ã€‚
+ページやメディアã®å±¥æ­´ã¯ã‚³ãƒ”ーã•ã‚Œã¾ã›ã‚“。
+
+タイトルã¨ãƒ­ã‚´ã‚¤ãƒ¡ãƒ¼ã‚¸ã¯ä¸Šæ›¸ãã—ã¦ã€ã‚³ãƒ”ー元ã¨åŒºåˆ¥ã§ãã‚‹ã“ã¨ã‚’確èªã—ã¦ãã ã•ã„。
+
+==== 動物ã®ç®¡ç†è€… ====
+
+動物ã¯ç‹¬è‡ªã®ãƒ¦ãƒ¼ã‚¶ãƒ¼åŸºæº–ã§å®Œå…¨ãªæ©Ÿèƒ½ã® wiki ã«ãªã‚Šã¾ã™ã€‚
+ユーザーを設定ã™ã‚‹ãŸã‚ã«å°‘ãªãã¨ã‚‚1ã¤ã®ç®¡ç†ãƒ¦ãƒ¼ã‚¶ãƒ¼ãŒå¿…è¦ã«ãªã‚Šã¾ã™ã€‚
+牧場主ã‹ã‚‰ç¾åœ¨ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã¾ãŸã¯ã™ã¹ã¦ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’コピーã—ãŸã‚Šã€å‹•ç‰©ã®ãŸã‚ã«å®Œå…¨ã«æ–°ã—ã„ユーザーを作æˆã§ãã¾ã™ã€‚
+
+ユーザーを作æˆã—ãªã„ã“ã¨ã‚‚é¸æŠžã§ãã¾ã™ã€‚
+設定タブã§ç‰§å ´ä¸»ã‹ã‚‰ãƒ¦ãƒ¼ã‚¶ãƒ¼ã®ç¶™æ‰¿ã‚’有効ã«ã—ãŸå ´åˆã€æ—¢å­˜ã®ãƒ¦ãƒ¼ã‚¶ãƒ¼ã‚’別ã®å‹•ç‰©ã‹ã‚‰ã‚³ãƒ”ーã—ãŸå ´åˆã®ã¿ã“れをé¸æŠžã™ã¹ãã§ã™ã€‚
+
+/lang/en/tab_plugins.txt
+一括æ“作ã§å…¨ã¦ã®å‹•ç‰©ã«å¯¾ã™ã‚‹ãƒ—ラグインã®æœ‰åŠ¹åŒ–・無効化やã€ç‰¹å®šã®å‹•ç‰©ã«å¯¾ã™ã‚‹ãƒ—ラグインã®ç·¨é›†ãŒã§ãã¾ã™ã€‚
diff --git a/platform/www/lib/plugins/farmer/lang/ja/tab_plugins.txt b/platform/www/lib/plugins/farmer/lang/ja/tab_plugins.txt
new file mode 100644
index 0000000..ee4acd5
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/tab_plugins.txt
@@ -0,0 +1 @@
+一度ã®æ“作ã§å…¨ã¦ã®å‹•ç‰©ã®ãƒ—ラグインを有効ã¾ãŸã¯ç„¡åŠ¹ã«ã™ã‚‹ã“ã¨ã‚„ã€å€‹ã€…ã®å‹•ç‰©ã®ãƒ—ラグインを編集ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚ \ No newline at end of file
diff --git a/platform/www/lib/plugins/farmer/lang/ja/tab_plugins_help.txt b/platform/www/lib/plugins/farmer/lang/ja/tab_plugins_help.txt
new file mode 100644
index 0000000..fe4aa72
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/tab_plugins_help.txt
@@ -0,0 +1,17 @@
+===== ãƒ—ãƒ©ã‚°ã‚¤ãƒ³ç®¡ç† =====
+
+拡張機能管ç†ã¯ã€ã™ã¹ã¦ã®å‹•ç‰©ã®ä¸­ã§ç„¡åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚
+プラグインã¯ç‰§å ´ä¸»ã«ã®ã¿ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã™ã‚‹ã“ã¨ãŒã§ãã€ç‰§å ´ä¸»ã ã‘ãŒã™ã¹ã¦ã®å‹•ç‰©ã®ä¸­ã§ã©ã®ãƒ—ラグインを有効ã«ã™ã‚‹ã‹ç„¡åŠ¹ã«ã™ã‚‹ã‹ã‚’制御ã§ãã¾ã™ã€‚
+ã“ã®ç”»é¢ã‚’使ã£ã¦ã“ã®åˆ¶å¾¡ã‚’è¡Œã„ã¾ã™ã€‚
+
+å„プラグインã¯å‹•ç‰©æ¯Žã«ä¸‰ã¤ã®çŠ¶æ…‹ã‚’指定ã§ãã¾ã™ã€‚
+有効ã€ç„¡åŠ¹ã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆçŠ¶æ…‹ã§ã™ã€‚
+デフォルトã¯å‹•ç‰©ã«å¯¾ã—ã¦ãƒ—ラグインã®çŠ¶æ…‹ã‚’明示的ã«è¨­å®šã—ã¦ã„ãªã„ã“ã¨ã‚’æ„味ã—ã¾ã™ã€‚
+通常ã¯ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆã®çŠ¶æ…‹ã¯æœ‰åŠ¹ã«ãªã£ã¦ã„ã¾ã™ã€‚
+
+動物ãŒç‰§å ´ä¸»ã®ãƒ—ラグインã®çŠ¶æ…‹ã‚’継承ã™ã‚‹ã‚ˆã†ã«è¨­å®šã—ãŸå ´åˆã€ãƒ‡ãƒ•ã‚©ãƒ«ãƒˆçŠ¶æ…‹ã®ãƒ—ラグインã¯ç‰§å ´ä¸»ã¨åŒã˜çŠ¶æ…‹ã«ãªã‚Šã¾ã™ã€‚
+例ãˆã°ã€ç‰§å ´ä¸»ã®ãƒ—ラグインを無効ã«ã—ãŸå ´åˆã€ã“ã®ãƒ—ラグインã®çŠ¶æ…‹ã‚’明示的ã«è¨­å®šã—ã¦ã„ãªã‹ã£ãŸã™ã¹ã¦ã®å‹•ç‰©å†…ã§ãƒ—ラグインを無効ã«ã—ã¾ã™ã€‚
+
+プラグイン管ç†ã«ã¯äºŒç¨®é¡žã®æ–¹æ³•ãŒã‚ã‚Šã¾ã™ï¼š
+ * 一ã¤ã®ãƒ—ラグインをé¸æŠžã—ã€ã™ã¹ã¦ã®å‹•ç‰©ã«å¯¾ã—ã¦åŒã˜çŠ¶æ…‹ã‚’設定ã™ã‚‹ã€‚
+ * 特定ã®å‹•ç‰©ã‚’é¸ã³ã€ãã®å‹•ç‰©å†…ã®ã¿ã«å¯¾ã™ã‚‹ã™ã¹ã¦ã®ãƒ—ラグインã®çŠ¶æ…‹ã‚’設定ã™ã‚‹ã€‚
diff --git a/platform/www/lib/plugins/farmer/lang/ja/tab_setup.txt b/platform/www/lib/plugins/farmer/lang/ja/tab_setup.txt
new file mode 100644
index 0000000..a5cf09c
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/tab_setup.txt
@@ -0,0 +1 @@
+ã“ã® Wiki ã¯ç‰§å ´ä¸»ãƒ—ラグインã®ç‰§å ´è¨­å®šã‚’ã•ã‚Œã¦ã„ã¾ã›ã‚“。以下ã®å…¥åŠ›ç”»é¢ã§ç‰§å ´è¨­å®šã‚’ã—ã¦ä¸‹ã•ã„。 \ No newline at end of file
diff --git a/platform/www/lib/plugins/farmer/lang/ja/tab_setup_help.txt b/platform/www/lib/plugins/farmer/lang/ja/tab_setup_help.txt
new file mode 100644
index 0000000..d2cd61f
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/ja/tab_setup_help.txt
@@ -0,0 +1,38 @@
+===== 牧場ã«ã¤ã„㦠=====
+
+牧場ã¯è¤‡æ•°ã®ä»–ã® wiki(「動物〠"Animals")を動ã‹ã™å˜ä¸€ã® DokuWiki インストール(「牧場主〠"Farmer")を使ãˆã‚‹ã‚ˆã†ã«ã—ã¾ã™ã€‚
+プラグインã¨ãƒ†ãƒ³ãƒ—レートã¯ç‰§å ´ä¸»ã«ã ã‘インストールã™ã‚Œã°ã€å‹•ç‰©ã‚‚ãれらを利用ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚
+一ã¤ã® wiki ã ã‘を最新状態ã«ä¿ã¤å¿…è¦ãŒã‚ã‚Šã€ä»–ã®ã™ã¹ã¦ã® wiki ã¯åŒã˜ã‚³ãƒ¼ãƒ‰ãƒ™ãƒ¼ã‚¹ã‚’使用ã™ã‚‹ã ã‘ã«ãªã‚Šã¾ã™ã€‚
+
+ã“ã®è¨­å®šæ‰‹é †ã‚’完了ã—ãŸå¾Œã€ç¾åœ¨ã® DokuWiki(ã‚ãªãŸãŒè¦‹ã¦ã„ã‚‹ DokuWiki)ãŒã€ã€Œç‰§å ´ä¸»ã€ã¨ã—ã¦èªè­˜ã•ã‚Œã‚‹ã‚ˆã†ã«ãªã‚Šã¾ã™ã€‚
+
+===== ã“ã®è¨­å®šã¯ä½•ã‚’ã—ã¾ã™ã‹ï¼Ÿ =====
+
+ã“ã®è¨­å®šã‚¦ã‚£ã‚¶ãƒ¼ãƒ‰ã§ã¯ã€ä»¥ä¸‹ã®ä¸‰ã¤ã‚’è¡Œã„ã¾ã™ï¼š
+
+ - ''inc/preload.php'' ファイルã®ä½œæˆ
+ - ''conf/farm.ini'' ファイルã®ä½œæˆ
+ - å¿…è¦ã«å¿œã˜ã¦ ''.htaccess'' ファイルã«è¿½åŠ 
+
+''preload.php'' 㯠DokuWiki 読込ã¿æ™‚ã®æœ€åˆã«èª­ã¿è¾¼ã¾ã‚Œã‚‹ãƒ•ã‚¡ã‚¤ãƒ«ã§ã™ã€‚
+ã“ã“ã§ç‰§å ´æ©Ÿèƒ½ãŒåˆæœŸåŒ–ã•ã‚Œã¾ã™ã€‚
+ç¾åœ¨ã®è¦æ±‚ãŒå‹•ç‰©ã‹ç‰§å ´ä¸»ã‚’アクセスã—ã€ãã‚Œã«å¿œã˜ã¦å…¨ã¦ã‚’å†æ§‹æˆã™ã‚‹å¿…è¦ãŒã‚ã‚‹å ´åˆã€ç‰§å ´ä¸»ãƒ—ラグインを検出ã—ã¾ã™ã€‚
+
+''conf/farm.ini'' ã«ã¯ç‰§å ´ã®åŸºæœ¬çš„ãªè¨­å®šãŒå«ã¾ã‚Œã¦ã„ã¾ã™ã€‚
+最もé‡è¦ãªã“ã¨ã¯ã€ã™ã¹ã¦ã®å‹•ç‰©ãƒ‡ãƒ¼ã‚¿ãŒæ ¼ç´ã•ã‚Œã‚‹å ´æ‰€ãŒå«ã¾ã‚Œã¦ã„ã‚‹ã“ã¨ã§ã™ã€‚
+
+''.htaccess'' を変更ã™ã‚‹ã“ã¨ã§ //ãƒãƒ³ !// 機能を使ã£ã¦å‹•ç‰©ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚(下記å‚照)
+
+===== 入力方法? =====
+
+**動物用ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒª**ã¯ã€å„動物用ã«æ–°ã—ã„ディレクトリを作æˆã™ã‚‹å ´æ‰€ã§ã™ã€‚
+ã“ã®ãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã¯ã€ç¾åœ¨ã® DokuWiki ã®å¤–ã§ãªã‘ã‚Œã°ãªã‚Šã¾ã›ã‚“。
+''../animals'' ã®ã‚ˆã†ãªç›¸å¯¾çš„ãªãƒ‡ã‚£ãƒ¬ã‚¯ãƒˆãƒªã‚’指定ã§ãã¾ã™ã€‚
+
+**.htaccess** 対応を有効ã«ã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™ã€‚
+ã“ã®æ©Ÿèƒ½ã¯ã€Apache ã® mod_rewrite 㨠.htaccess 対応ãŒå¿…è¦ã§ã™ã€‚
+
+有効ã«ã™ã‚‹ã¨ã€å‹•ç‰©ã¯ //ãƒãƒ³ !// 機能を使ã£ã¦ç‰§å ´ä¸»ã® URL ã®ä¸‹ã§ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚
+例ãˆã°ã€''%%http://www.example.com/dokuwiki/%%'' ã§ç‰§å ´ä¸»ãŒå®Ÿè¡Œã•ã‚Œã¦ã„ã‚‹å ´åˆã€''%%http://www.example.com/dokuwiki/!animal%%'' ã§å‹•ç‰©ã«ã‚¢ã‚¯ã‚»ã‚¹ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚
+
+ã“ã®ã‚ªãƒ—ションを有効ã«ã—ãªã„å ´åˆã€å‹•ç‰©ã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹ã«ã¯ã€Web サーãƒãƒ¼ã‚„ DNS を設定ã™ã‚‹ãŒå¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚
diff --git a/platform/www/lib/plugins/farmer/lang/nl/lang.php b/platform/www/lib/plugins/farmer/lang/nl/lang.php
new file mode 100644
index 0000000..cef0c84
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/nl/lang.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Harriet Neitz <harrietneitz@gmail.com>
+ */
+$lang['tab_info'] = 'Info';
+$lang['tab_config'] = 'Configuratie';
+$lang['tab_plugins'] = 'Beheer plugins';
+$lang['tab_new'] = 'Voeg nieuw dier toe';
+$lang['tab_delete'] = 'Verwijder dier';
+$lang['farmdir_in_dokuwiki'] = 'De dier directory (%s) moet buiten de Boerderij dokuwiki (%s) staan.';
+$lang['farmdir_unwritable'] = 'Controleer dat de webserver schrijf-toegang heeft tot de dier directory (%s)!';
+$lang['overwrite_preload'] = 'Waarschuwing: Je bestaande inc/preload.php wordt overschreven wanneer je hier doorgaat!';
+$lang['conf_notfound_404'] = 'Toon een 404 fout pagina';
+$lang['conf_notfound_list'] = 'Toon een lijst van bestaande dieren';
+$lang['conf_notfound_redirect'] = 'Redirect naar onderstaande URL';
+$lang['save'] = 'Opslaan';
+$lang['animal template'] = 'Kopieer bestaand dier';
diff --git a/platform/www/lib/plugins/farmer/lang/pl/lang.php b/platform/www/lib/plugins/farmer/lang/pl/lang.php
new file mode 100644
index 0000000..375d919
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/lang/pl/lang.php
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Bartek S <sadupl@gmail.com>
+ */
+$lang['menu'] = 'Farma';
+$lang['tab_setup'] = 'Ustawienia Farmy';
+$lang['tab_info'] = 'Informacje';
+$lang['tab_config'] = 'Konfiguracja';
+$lang['tab_plugins'] = 'ZarzÄ…dzaj pluginami';
+$lang['tab_new'] = 'Dodaj nowe zwierzÄ™';
+$lang['tab_delete'] = 'Usuń zwierzę';
+$lang['preloadPHPForm'] = 'Zainicjuj FarmÄ™';
+$lang['farm dir'] = 'Katalog zwierzÄ…t';
+$lang['htaccess setup'] = 'Dodać kod farmy do .htaccess?';
+$lang['submit'] = 'Zatwierdź';
+$lang['farmdir_missing'] = 'Proszę podać katalog gdzie Zwierzęta powinny być przechowywane.';
+$lang['farmdir_in_dokuwiki'] = 'Katalog Zwierząt (%s) musi być poza Farmą dokuwiki (%s).';
+$lang['farmdir_uncreatable'] = 'Katalog Zwierząt (%s) nie został stworzony. Czy uprawnienia są prawidłowe?';
+$lang['farmdir_unwritable'] = 'Proszę się upenić, że webserver posiada prawa zapisu do katalogu Zwierząt.';
+$lang['farmdir_notEmpty'] = 'Katalog Zwierząt (%s) musi być pusty.';
+$lang['preload creation success'] = 'Farma została zainicjowana pomyślnie.';
+$lang['preload creation error'] = 'Wystąpił błąd podczas inicjowania Farmy.';
+$lang['overwrite_preload'] = 'Uwaga: Dotychczasowy plik inc/preload.php będzie zastąpiony podczas kontynuowania!';
+$lang['animal'] = 'Imię Zwierzęta / Domeny';
+$lang['thisis'] = 'Instancja to';
+$lang['thisis.farmer'] = 'Farmer!';
+$lang['thisis.animal'] = 'ZwierzÄ™!';
+$lang['baseinstall'] = 'Instalacja Farmera';
+$lang['animals'] = 'Zwierzęta';
+$lang['confdir'] = 'Katalog konfiguracji instancji';
+$lang['savedir'] = 'Katalog danych instancji';
+$lang['plugins'] = 'Aktywne pluginy tej instancji';
+$lang['base'] = 'Konfiguracja Bazy';
+$lang['farm host'] = 'Host Name Farmera';
+$lang['base domain'] = 'Domena podstawowa dla subdomeny Zwierzęta';
+$lang['conf_inherit'] = 'Zwierzęta powinny dziedziczyć ustawienia farmera';
+$lang['conf_inherit_main'] = 'Ustawienia konfiguracji';
+$lang['conf_inherit_acronyms'] = 'Definicje akronimów';
+$lang['conf_inherit_entities'] = 'Definicje jednostek';
+$lang['conf_inherit_interwiki'] = 'Definicje Interwiki';
+$lang['conf_inherit_license'] = 'Definicje licencji';
+$lang['conf_inherit_smileys'] = 'Definicje uśmieszków';
+$lang['conf_inherit_wordblock'] = 'Wpisy SPAM na czarnej liście';
+$lang['conf_inherit_userstyle'] = 'Style użytkownika';
+$lang['conf_inherit_userscript'] = 'Skrypty użytkownika';
+$lang['conf_inherit_styleini'] = 'Dostosowanie stylu szablonu';
+$lang['conf_inherit_users'] = 'Użytkownicy (tylko zwykłe uwierzytelnianie)';
+$lang['conf_inherit_plugins'] = 'Stan wtyczki';
+$lang['conf_inherit_yes'] = 'odziedziczony po farmerze';
+$lang['conf_inherit_no'] = 'niezależny od farmera';
+$lang['conf_notfound'] = 'Zachowanie podczas uzyskiwania dostępu do nieistniejących zwierząt';
+$lang['conf_notfound_farmer'] = 'Pokaż wiki farmera';
+$lang['conf_notfound_404'] = 'Pokaż stronę błędu 404';
+$lang['conf_notfound_list'] = 'Pokaż listę dostępnych zwierząt';
+$lang['conf_notfound_redirect'] = 'Przekieruj na poniższy adres URL';
+$lang['conf_notfound_url'] = 'Adres URL do przekierowania, jeśli wybrano powyżej';
+$lang['save'] = 'Zapisz';
+$lang['animal template'] = 'Kopiuj istniejÄ…ce ZwierzÄ™';
+$lang['animal creation success'] = 'Zwierzę "%s" zostało pomyślnie utworzone.';
+$lang['animal creation error'] = 'Wystąpił błąd podczas tworzenia zwierzęcia.';
+$lang['animal configuration'] = 'Podstawowa konfiguracja ZwierzÄ…t';
+$lang['inherit user registration'] = 'Dziedzicz ustawienia rejestracji użytkownika od farmera';
+$lang['enable user registration'] = 'Pozwól użytkownikom się zarejestrować';
+$lang['disable user registration'] = 'Wyłącz rejestrację użytkowników';
+$lang['animal administrator'] = 'Administrator zwięrząt';
+$lang['noUsers'] = 'Nie twórz żadnych użytkowników';
+$lang['importUsers'] = 'Zaimportuj wszystkich użytkowników Farmera do nowego zwierzęcia';
+$lang['currentAdmin'] = 'Ustaw bieżącego użytkownika jako admin';
+$lang['newAdmin'] = 'Utwórz nowego administratora „adminâ€';
+$lang['admin password'] = 'Hasło dla nowego administratora';
+$lang['animalname_missing'] = 'Wprowadź nazwę nowego zwierzęcia.';
+$lang['animalname_preexisting'] = 'Zwierzę o tej nazwie już istnieje.';
+$lang['adminPassword_empty'] = 'Hasło do nowego konta administratora nie może być puste.';
+$lang['bulkSingleSwitcher'] = 'Edytować jedno Zwierzę czy wszystkie naraz?';
+$lang['bulkEdit'] = 'Zbiorcza edycja wszystkich ZwierzÄ…t';
+$lang['singleEdit'] = 'Edytuj jedno ZwierzÄ™';
+$lang['bulkEditForm'] = 'Aktywuj lub dezaktywuj wtyczkę we wszystkich Zwierzętach';
+$lang['default'] = 'Ustaw na domyślny';
+$lang['activate'] = 'Aktywuj';
+$lang['deactivate'] = 'Dezaktywuj';
+$lang['singleEditForm'] = 'Edytuj wtyczki określonego Zwierzęcia';
+$lang['plugindone'] = 'Stany wtyczek zaktualizowane';
+$lang['plugin'] = 'Plugin';
+$lang['plugin_on'] = 'on
+(it means \'włączone\', but in PL we use also ON/OFF)';
+$lang['plugin_off'] = 'off
+(it means \'wyłączone\', but in PL we use also ON/OFF)';
+$lang['plugin_default'] = 'Domyślne';
+$lang['plugin_enabled'] = 'WÅ‚Ä…czone';
+$lang['plugin_disabled'] = 'Wyłączone';
+$lang['js']['animalSelect'] = 'Wybierz zwierzÄ™';
+$lang['js']['pluginSelect'] = 'Wybierz plugin';
+$lang['delete_animal'] = 'Wybierz Zwierzę do usunięcia';
+$lang['delete_confirm'] = 'Wpisz nazwę Zwierzęcia, aby potwierdzić';
+$lang['delete'] = 'Usuń Zwierzę i wszystkie jego dane';
+$lang['delete_noanimal'] = 'Proszę wybrać Zwierzę do usunięcia';
+$lang['delete_mismatch'] = 'Potwierdzenie nie pasuje do nazwy Zwierzęcia. Nie usunięte.';
+$lang['delete_invalid'] = 'Nieprawidłowa nazwa Zwierzęcia. Nie usunięte';
+$lang['delete_success'] = 'Zwierzę zostało pomyślnie usunięte.';
diff --git a/platform/www/lib/plugins/farmer/plugin.info.txt b/platform/www/lib/plugins/farmer/plugin.info.txt
new file mode 100644
index 0000000..2a26566
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/plugin.info.txt
@@ -0,0 +1,7 @@
+base farmer
+author Michael Große, Andreas Gohr
+email dokuwiki@cosmocode.de
+date 2021-01-08
+name farmer plugin
+desc A plugin to help with creating and administring wiki farm animals
+url https://dokuwiki.org/plugin:farmer
diff --git a/platform/www/lib/plugins/farmer/script.js b/platform/www/lib/plugins/farmer/script.js
new file mode 100644
index 0000000..d5cea10
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/script.js
@@ -0,0 +1,2 @@
+/* DOKUWIKI:include_once script/jquery.chosen.js */
+/* DOKUWIKI:include script/plugins.js */
diff --git a/platform/www/lib/plugins/farmer/script/jquery.chosen.js b/platform/www/lib/plugins/farmer/script/jquery.chosen.js
new file mode 100644
index 0000000..929a9ca
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/script/jquery.chosen.js
@@ -0,0 +1,1257 @@
+/*!
+Chosen, a Select Box Enhancer for jQuery and Prototype
+by Patrick Filler for Harvest, http://getharvest.com
+
+Version 1.4.2
+Full source at https://github.com/harvesthq/chosen
+Copyright (c) 2011-2015 Harvest http://getharvest.com
+
+MIT License, https://github.com/harvesthq/chosen/blob/master/LICENSE.md
+This file is generated by `grunt build`, do not edit it by hand.
+*/
+
+(function() {
+ var $, AbstractChosen, Chosen, SelectParser, _ref,
+ __hasProp = {}.hasOwnProperty,
+ __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
+
+ SelectParser = (function() {
+ function SelectParser() {
+ this.options_index = 0;
+ this.parsed = [];
+ }
+
+ SelectParser.prototype.add_node = function(child) {
+ if (child.nodeName.toUpperCase() === "OPTGROUP") {
+ return this.add_group(child);
+ } else {
+ return this.add_option(child);
+ }
+ };
+
+ SelectParser.prototype.add_group = function(group) {
+ var group_position, option, _i, _len, _ref, _results;
+ group_position = this.parsed.length;
+ this.parsed.push({
+ array_index: group_position,
+ group: true,
+ label: this.escapeExpression(group.label),
+ title: group.title ? group.title : void 0,
+ children: 0,
+ disabled: group.disabled,
+ classes: group.className
+ });
+ _ref = group.childNodes;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ option = _ref[_i];
+ _results.push(this.add_option(option, group_position, group.disabled));
+ }
+ return _results;
+ };
+
+ SelectParser.prototype.add_option = function(option, group_position, group_disabled) {
+ if (option.nodeName.toUpperCase() === "OPTION") {
+ if (option.text !== "") {
+ if (group_position != null) {
+ this.parsed[group_position].children += 1;
+ }
+ this.parsed.push({
+ array_index: this.parsed.length,
+ options_index: this.options_index,
+ value: option.value,
+ text: option.text,
+ html: option.innerHTML,
+ title: option.title ? option.title : void 0,
+ selected: option.selected,
+ disabled: group_disabled === true ? group_disabled : option.disabled,
+ group_array_index: group_position,
+ group_label: group_position != null ? this.parsed[group_position].label : null,
+ classes: option.className,
+ style: option.style.cssText
+ });
+ } else {
+ this.parsed.push({
+ array_index: this.parsed.length,
+ options_index: this.options_index,
+ empty: true
+ });
+ }
+ return this.options_index += 1;
+ }
+ };
+
+ SelectParser.prototype.escapeExpression = function(text) {
+ var map, unsafe_chars;
+ if ((text == null) || text === false) {
+ return "";
+ }
+ if (!/[\&\<\>\"\'\`]/.test(text)) {
+ return text;
+ }
+ map = {
+ "<": "&lt;",
+ ">": "&gt;",
+ '"': "&quot;",
+ "'": "&#x27;",
+ "`": "&#x60;"
+ };
+ unsafe_chars = /&(?!\w+;)|[\<\>\"\'\`]/g;
+ return text.replace(unsafe_chars, function(chr) {
+ return map[chr] || "&amp;";
+ });
+ };
+
+ return SelectParser;
+
+ })();
+
+ SelectParser.select_to_array = function(select) {
+ var child, parser, _i, _len, _ref;
+ parser = new SelectParser();
+ _ref = select.childNodes;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ child = _ref[_i];
+ parser.add_node(child);
+ }
+ return parser.parsed;
+ };
+
+ AbstractChosen = (function() {
+ function AbstractChosen(form_field, options) {
+ this.form_field = form_field;
+ this.options = options != null ? options : {};
+ if (!AbstractChosen.browser_is_supported()) {
+ return;
+ }
+ this.is_multiple = this.form_field.multiple;
+ this.set_default_text();
+ this.set_default_values();
+ this.setup();
+ this.set_up_html();
+ this.register_observers();
+ this.on_ready();
+ }
+
+ AbstractChosen.prototype.set_default_values = function() {
+ var _this = this;
+ this.click_test_action = function(evt) {
+ return _this.test_active_click(evt);
+ };
+ this.activate_action = function(evt) {
+ return _this.activate_field(evt);
+ };
+ this.active_field = false;
+ this.mouse_on_container = false;
+ this.results_showing = false;
+ this.result_highlighted = null;
+ this.allow_single_deselect = (this.options.allow_single_deselect != null) && (this.form_field.options[0] != null) && this.form_field.options[0].text === "" ? this.options.allow_single_deselect : false;
+ this.disable_search_threshold = this.options.disable_search_threshold || 0;
+ this.disable_search = this.options.disable_search || false;
+ this.enable_split_word_search = this.options.enable_split_word_search != null ? this.options.enable_split_word_search : true;
+ this.group_search = this.options.group_search != null ? this.options.group_search : true;
+ this.search_contains = this.options.search_contains || false;
+ this.single_backstroke_delete = this.options.single_backstroke_delete != null ? this.options.single_backstroke_delete : true;
+ this.max_selected_options = this.options.max_selected_options || Infinity;
+ this.inherit_select_classes = this.options.inherit_select_classes || false;
+ this.display_selected_options = this.options.display_selected_options != null ? this.options.display_selected_options : true;
+ this.display_disabled_options = this.options.display_disabled_options != null ? this.options.display_disabled_options : true;
+ return this.include_group_label_in_selected = this.options.include_group_label_in_selected || false;
+ };
+
+ AbstractChosen.prototype.set_default_text = function() {
+ if (this.form_field.getAttribute("data-placeholder")) {
+ this.default_text = this.form_field.getAttribute("data-placeholder");
+ } else if (this.is_multiple) {
+ this.default_text = this.options.placeholder_text_multiple || this.options.placeholder_text || AbstractChosen.default_multiple_text;
+ } else {
+ this.default_text = this.options.placeholder_text_single || this.options.placeholder_text || AbstractChosen.default_single_text;
+ }
+ return this.results_none_found = this.form_field.getAttribute("data-no_results_text") || this.options.no_results_text || AbstractChosen.default_no_result_text;
+ };
+
+ AbstractChosen.prototype.choice_label = function(item) {
+ if (this.include_group_label_in_selected && (item.group_label != null)) {
+ return "<b class='group-name'>" + item.group_label + "</b>" + item.html;
+ } else {
+ return item.html;
+ }
+ };
+
+ AbstractChosen.prototype.mouse_enter = function() {
+ return this.mouse_on_container = true;
+ };
+
+ AbstractChosen.prototype.mouse_leave = function() {
+ return this.mouse_on_container = false;
+ };
+
+ AbstractChosen.prototype.input_focus = function(evt) {
+ var _this = this;
+ if (this.is_multiple) {
+ if (!this.active_field) {
+ return setTimeout((function() {
+ return _this.container_mousedown();
+ }), 50);
+ }
+ } else {
+ if (!this.active_field) {
+ return this.activate_field();
+ }
+ }
+ };
+
+ AbstractChosen.prototype.input_blur = function(evt) {
+ var _this = this;
+ if (!this.mouse_on_container) {
+ this.active_field = false;
+ return setTimeout((function() {
+ return _this.blur_test();
+ }), 100);
+ }
+ };
+
+ AbstractChosen.prototype.results_option_build = function(options) {
+ var content, data, _i, _len, _ref;
+ content = '';
+ _ref = this.results_data;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ data = _ref[_i];
+ if (data.group) {
+ content += this.result_add_group(data);
+ } else {
+ content += this.result_add_option(data);
+ }
+ if (options != null ? options.first : void 0) {
+ if (data.selected && this.is_multiple) {
+ this.choice_build(data);
+ } else if (data.selected && !this.is_multiple) {
+ this.single_set_selected_text(this.choice_label(data));
+ }
+ }
+ }
+ return content;
+ };
+
+ AbstractChosen.prototype.result_add_option = function(option) {
+ var classes, option_el;
+ if (!option.search_match) {
+ return '';
+ }
+ if (!this.include_option_in_results(option)) {
+ return '';
+ }
+ classes = [];
+ if (!option.disabled && !(option.selected && this.is_multiple)) {
+ classes.push("active-result");
+ }
+ if (option.disabled && !(option.selected && this.is_multiple)) {
+ classes.push("disabled-result");
+ }
+ if (option.selected) {
+ classes.push("result-selected");
+ }
+ if (option.group_array_index != null) {
+ classes.push("group-option");
+ }
+ if (option.classes !== "") {
+ classes.push(option.classes);
+ }
+ option_el = document.createElement("li");
+ option_el.className = classes.join(" ");
+ option_el.style.cssText = option.style;
+ option_el.setAttribute("data-option-array-index", option.array_index);
+ option_el.innerHTML = option.search_text;
+ if (option.title) {
+ option_el.title = option.title;
+ }
+ return this.outerHTML(option_el);
+ };
+
+ AbstractChosen.prototype.result_add_group = function(group) {
+ var classes, group_el;
+ if (!(group.search_match || group.group_match)) {
+ return '';
+ }
+ if (!(group.active_options > 0)) {
+ return '';
+ }
+ classes = [];
+ classes.push("group-result");
+ if (group.classes) {
+ classes.push(group.classes);
+ }
+ group_el = document.createElement("li");
+ group_el.className = classes.join(" ");
+ group_el.innerHTML = group.search_text;
+ if (group.title) {
+ group_el.title = group.title;
+ }
+ return this.outerHTML(group_el);
+ };
+
+ AbstractChosen.prototype.results_update_field = function() {
+ this.set_default_text();
+ if (!this.is_multiple) {
+ this.results_reset_cleanup();
+ }
+ this.result_clear_highlight();
+ this.results_build();
+ if (this.results_showing) {
+ return this.winnow_results();
+ }
+ };
+
+ AbstractChosen.prototype.reset_single_select_options = function() {
+ var result, _i, _len, _ref, _results;
+ _ref = this.results_data;
+ _results = [];
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ result = _ref[_i];
+ if (result.selected) {
+ _results.push(result.selected = false);
+ } else {
+ _results.push(void 0);
+ }
+ }
+ return _results;
+ };
+
+ AbstractChosen.prototype.results_toggle = function() {
+ if (this.results_showing) {
+ return this.results_hide();
+ } else {
+ return this.results_show();
+ }
+ };
+
+ AbstractChosen.prototype.results_search = function(evt) {
+ if (this.results_showing) {
+ return this.winnow_results();
+ } else {
+ return this.results_show();
+ }
+ };
+
+ AbstractChosen.prototype.winnow_results = function() {
+ var escapedSearchText, option, regex, results, results_group, searchText, startpos, text, zregex, _i, _len, _ref;
+ this.no_results_clear();
+ results = 0;
+ searchText = this.get_search_text();
+ escapedSearchText = searchText.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
+ zregex = new RegExp(escapedSearchText, 'i');
+ regex = this.get_search_regex(escapedSearchText);
+ _ref = this.results_data;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ option = _ref[_i];
+ option.search_match = false;
+ results_group = null;
+ if (this.include_option_in_results(option)) {
+ if (option.group) {
+ option.group_match = false;
+ option.active_options = 0;
+ }
+ if ((option.group_array_index != null) && this.results_data[option.group_array_index]) {
+ results_group = this.results_data[option.group_array_index];
+ if (results_group.active_options === 0 && results_group.search_match) {
+ results += 1;
+ }
+ results_group.active_options += 1;
+ }
+ option.search_text = option.group ? option.label : option.html;
+ if (!(option.group && !this.group_search)) {
+ option.search_match = this.search_string_match(option.search_text, regex);
+ if (option.search_match && !option.group) {
+ results += 1;
+ }
+ if (option.search_match) {
+ if (searchText.length) {
+ startpos = option.search_text.search(zregex);
+ text = option.search_text.substr(0, startpos + searchText.length) + '</em>' + option.search_text.substr(startpos + searchText.length);
+ option.search_text = text.substr(0, startpos) + '<em>' + text.substr(startpos);
+ }
+ if (results_group != null) {
+ results_group.group_match = true;
+ }
+ } else if ((option.group_array_index != null) && this.results_data[option.group_array_index].search_match) {
+ option.search_match = true;
+ }
+ }
+ }
+ }
+ this.result_clear_highlight();
+ if (results < 1 && searchText.length) {
+ this.update_results_content("");
+ return this.no_results(searchText);
+ } else {
+ this.update_results_content(this.results_option_build());
+ return this.winnow_results_set_highlight();
+ }
+ };
+
+ AbstractChosen.prototype.get_search_regex = function(escaped_search_string) {
+ var regex_anchor;
+ regex_anchor = this.search_contains ? "" : "^";
+ return new RegExp(regex_anchor + escaped_search_string, 'i');
+ };
+
+ AbstractChosen.prototype.search_string_match = function(search_string, regex) {
+ var part, parts, _i, _len;
+ if (regex.test(search_string)) {
+ return true;
+ } else if (this.enable_split_word_search && (search_string.indexOf(" ") >= 0 || search_string.indexOf("[") === 0)) {
+ parts = search_string.replace(/\[|\]/g, "").split(" ");
+ if (parts.length) {
+ for (_i = 0, _len = parts.length; _i < _len; _i++) {
+ part = parts[_i];
+ if (regex.test(part)) {
+ return true;
+ }
+ }
+ }
+ }
+ };
+
+ AbstractChosen.prototype.choices_count = function() {
+ var option, _i, _len, _ref;
+ if (this.selected_option_count != null) {
+ return this.selected_option_count;
+ }
+ this.selected_option_count = 0;
+ _ref = this.form_field.options;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ option = _ref[_i];
+ if (option.selected) {
+ this.selected_option_count += 1;
+ }
+ }
+ return this.selected_option_count;
+ };
+
+ AbstractChosen.prototype.choices_click = function(evt) {
+ evt.preventDefault();
+ if (!(this.results_showing || this.is_disabled)) {
+ return this.results_show();
+ }
+ };
+
+ AbstractChosen.prototype.keyup_checker = function(evt) {
+ var stroke, _ref;
+ stroke = (_ref = evt.which) != null ? _ref : evt.keyCode;
+ this.search_field_scale();
+ switch (stroke) {
+ case 8:
+ if (this.is_multiple && this.backstroke_length < 1 && this.choices_count() > 0) {
+ return this.keydown_backstroke();
+ } else if (!this.pending_backstroke) {
+ this.result_clear_highlight();
+ return this.results_search();
+ }
+ break;
+ case 13:
+ evt.preventDefault();
+ if (this.results_showing) {
+ return this.result_select(evt);
+ }
+ break;
+ case 27:
+ if (this.results_showing) {
+ this.results_hide();
+ }
+ return true;
+ case 9:
+ case 38:
+ case 40:
+ case 16:
+ case 91:
+ case 17:
+ break;
+ default:
+ return this.results_search();
+ }
+ };
+
+ AbstractChosen.prototype.clipboard_event_checker = function(evt) {
+ var _this = this;
+ return setTimeout((function() {
+ return _this.results_search();
+ }), 50);
+ };
+
+ AbstractChosen.prototype.container_width = function() {
+ if (this.options.width != null) {
+ return this.options.width;
+ } else {
+ return "" + this.form_field.offsetWidth + "px";
+ }
+ };
+
+ AbstractChosen.prototype.include_option_in_results = function(option) {
+ if (this.is_multiple && (!this.display_selected_options && option.selected)) {
+ return false;
+ }
+ if (!this.display_disabled_options && option.disabled) {
+ return false;
+ }
+ if (option.empty) {
+ return false;
+ }
+ return true;
+ };
+
+ AbstractChosen.prototype.search_results_touchstart = function(evt) {
+ this.touch_started = true;
+ return this.search_results_mouseover(evt);
+ };
+
+ AbstractChosen.prototype.search_results_touchmove = function(evt) {
+ this.touch_started = false;
+ return this.search_results_mouseout(evt);
+ };
+
+ AbstractChosen.prototype.search_results_touchend = function(evt) {
+ if (this.touch_started) {
+ return this.search_results_mouseup(evt);
+ }
+ };
+
+ AbstractChosen.prototype.outerHTML = function(element) {
+ var tmp;
+ if (element.outerHTML) {
+ return element.outerHTML;
+ }
+ tmp = document.createElement("div");
+ tmp.appendChild(element);
+ return tmp.innerHTML;
+ };
+
+ AbstractChosen.browser_is_supported = function() {
+ if (window.navigator.appName === "Microsoft Internet Explorer") {
+ return document.documentMode >= 8;
+ }
+ if (/iP(od|hone)/i.test(window.navigator.userAgent)) {
+ return false;
+ }
+ if (/Android/i.test(window.navigator.userAgent)) {
+ if (/Mobile/i.test(window.navigator.userAgent)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ AbstractChosen.default_multiple_text = "Select Some Options";
+
+ AbstractChosen.default_single_text = "Select an Option";
+
+ AbstractChosen.default_no_result_text = "No results match";
+
+ return AbstractChosen;
+
+ })();
+
+ $ = jQuery;
+
+ $.fn.extend({
+ chosen: function(options) {
+ if (!AbstractChosen.browser_is_supported()) {
+ return this;
+ }
+ return this.each(function(input_field) {
+ var $this, chosen;
+ $this = $(this);
+ chosen = $this.data('chosen');
+ if (options === 'destroy' && chosen instanceof Chosen) {
+ chosen.destroy();
+ } else if (!(chosen instanceof Chosen)) {
+ $this.data('chosen', new Chosen(this, options));
+ }
+ });
+ }
+ });
+
+ Chosen = (function(_super) {
+ __extends(Chosen, _super);
+
+ function Chosen() {
+ _ref = Chosen.__super__.constructor.apply(this, arguments);
+ return _ref;
+ }
+
+ Chosen.prototype.setup = function() {
+ this.form_field_jq = $(this.form_field);
+ this.current_selectedIndex = this.form_field.selectedIndex;
+ return this.is_rtl = this.form_field_jq.hasClass("chosen-rtl");
+ };
+
+ Chosen.prototype.set_up_html = function() {
+ var container_classes, container_props;
+ container_classes = ["chosen-container"];
+ container_classes.push("chosen-container-" + (this.is_multiple ? "multi" : "single"));
+ if (this.inherit_select_classes && this.form_field.className) {
+ container_classes.push(this.form_field.className);
+ }
+ if (this.is_rtl) {
+ container_classes.push("chosen-rtl");
+ }
+ container_props = {
+ 'class': container_classes.join(' '),
+ 'style': "width: " + (this.container_width()) + ";",
+ 'title': this.form_field.title
+ };
+ if (this.form_field.id.length) {
+ container_props.id = this.form_field.id.replace(/[^\w]/g, '_') + "_chosen";
+ }
+ this.container = $("<div />", container_props);
+ if (this.is_multiple) {
+ this.container.html('<ul class="chosen-choices"><li class="search-field"><input type="text" value="' + this.default_text + '" class="default" autocomplete="off" style="width:25px;" /></li></ul><div class="chosen-drop"><ul class="chosen-results"></ul></div>');
+ } else {
+ this.container.html('<a class="chosen-single chosen-default" tabindex="-1"><span>' + this.default_text + '</span><div><b></b></div></a><div class="chosen-drop"><div class="chosen-search"><input type="text" autocomplete="off" /></div><ul class="chosen-results"></ul></div>');
+ }
+ this.form_field_jq.hide().after(this.container);
+ this.dropdown = this.container.find('div.chosen-drop').first();
+ this.search_field = this.container.find('input').first();
+ this.search_results = this.container.find('ul.chosen-results').first();
+ this.search_field_scale();
+ this.search_no_results = this.container.find('li.no-results').first();
+ if (this.is_multiple) {
+ this.search_choices = this.container.find('ul.chosen-choices').first();
+ this.search_container = this.container.find('li.search-field').first();
+ } else {
+ this.search_container = this.container.find('div.chosen-search').first();
+ this.selected_item = this.container.find('.chosen-single').first();
+ }
+ this.results_build();
+ this.set_tab_index();
+ return this.set_label_behavior();
+ };
+
+ Chosen.prototype.on_ready = function() {
+ return this.form_field_jq.trigger("chosen:ready", {
+ chosen: this
+ });
+ };
+
+ Chosen.prototype.register_observers = function() {
+ var _this = this;
+ this.container.bind('touchstart.chosen', function(evt) {
+ _this.container_mousedown(evt);
+ return evt.preventDefault();
+ });
+ this.container.bind('touchend.chosen', function(evt) {
+ _this.container_mouseup(evt);
+ return evt.preventDefault();
+ });
+ this.container.bind('mousedown.chosen', function(evt) {
+ _this.container_mousedown(evt);
+ });
+ this.container.bind('mouseup.chosen', function(evt) {
+ _this.container_mouseup(evt);
+ });
+ this.container.bind('mouseenter.chosen', function(evt) {
+ _this.mouse_enter(evt);
+ });
+ this.container.bind('mouseleave.chosen', function(evt) {
+ _this.mouse_leave(evt);
+ });
+ this.search_results.bind('mouseup.chosen', function(evt) {
+ _this.search_results_mouseup(evt);
+ });
+ this.search_results.bind('mouseover.chosen', function(evt) {
+ _this.search_results_mouseover(evt);
+ });
+ this.search_results.bind('mouseout.chosen', function(evt) {
+ _this.search_results_mouseout(evt);
+ });
+ this.search_results.bind('mousewheel.chosen DOMMouseScroll.chosen', function(evt) {
+ _this.search_results_mousewheel(evt);
+ });
+ this.search_results.bind('touchstart.chosen', function(evt) {
+ _this.search_results_touchstart(evt);
+ });
+ this.search_results.bind('touchmove.chosen', function(evt) {
+ _this.search_results_touchmove(evt);
+ });
+ this.search_results.bind('touchend.chosen', function(evt) {
+ _this.search_results_touchend(evt);
+ });
+ this.form_field_jq.bind("chosen:updated.chosen", function(evt) {
+ _this.results_update_field(evt);
+ });
+ this.form_field_jq.bind("chosen:activate.chosen", function(evt) {
+ _this.activate_field(evt);
+ });
+ this.form_field_jq.bind("chosen:open.chosen", function(evt) {
+ _this.container_mousedown(evt);
+ });
+ this.form_field_jq.bind("chosen:close.chosen", function(evt) {
+ _this.input_blur(evt);
+ });
+ this.search_field.bind('blur.chosen', function(evt) {
+ _this.input_blur(evt);
+ });
+ this.search_field.bind('keyup.chosen', function(evt) {
+ _this.keyup_checker(evt);
+ });
+ this.search_field.bind('keydown.chosen', function(evt) {
+ _this.keydown_checker(evt);
+ });
+ this.search_field.bind('focus.chosen', function(evt) {
+ _this.input_focus(evt);
+ });
+ this.search_field.bind('cut.chosen', function(evt) {
+ _this.clipboard_event_checker(evt);
+ });
+ this.search_field.bind('paste.chosen', function(evt) {
+ _this.clipboard_event_checker(evt);
+ });
+ if (this.is_multiple) {
+ return this.search_choices.bind('click.chosen', function(evt) {
+ _this.choices_click(evt);
+ });
+ } else {
+ return this.container.bind('click.chosen', function(evt) {
+ evt.preventDefault();
+ });
+ }
+ };
+
+ Chosen.prototype.destroy = function() {
+ $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
+ if (this.search_field[0].tabIndex) {
+ this.form_field_jq[0].tabIndex = this.search_field[0].tabIndex;
+ }
+ this.container.remove();
+ this.form_field_jq.removeData('chosen');
+ return this.form_field_jq.show();
+ };
+
+ Chosen.prototype.search_field_disabled = function() {
+ this.is_disabled = this.form_field_jq[0].disabled;
+ if (this.is_disabled) {
+ this.container.addClass('chosen-disabled');
+ this.search_field[0].disabled = true;
+ if (!this.is_multiple) {
+ this.selected_item.unbind("focus.chosen", this.activate_action);
+ }
+ return this.close_field();
+ } else {
+ this.container.removeClass('chosen-disabled');
+ this.search_field[0].disabled = false;
+ if (!this.is_multiple) {
+ return this.selected_item.bind("focus.chosen", this.activate_action);
+ }
+ }
+ };
+
+ Chosen.prototype.container_mousedown = function(evt) {
+ if (!this.is_disabled) {
+ if (evt && evt.type === "mousedown" && !this.results_showing) {
+ evt.preventDefault();
+ }
+ if (!((evt != null) && ($(evt.target)).hasClass("search-choice-close"))) {
+ if (!this.active_field) {
+ if (this.is_multiple) {
+ this.search_field.val("");
+ }
+ $(this.container[0].ownerDocument).bind('click.chosen', this.click_test_action);
+ this.results_show();
+ } else if (!this.is_multiple && evt && (($(evt.target)[0] === this.selected_item[0]) || $(evt.target).parents("a.chosen-single").length)) {
+ evt.preventDefault();
+ this.results_toggle();
+ }
+ return this.activate_field();
+ }
+ }
+ };
+
+ Chosen.prototype.container_mouseup = function(evt) {
+ if (evt.target.nodeName === "ABBR" && !this.is_disabled) {
+ return this.results_reset(evt);
+ }
+ };
+
+ Chosen.prototype.search_results_mousewheel = function(evt) {
+ var delta;
+ if (evt.originalEvent) {
+ delta = evt.originalEvent.deltaY || -evt.originalEvent.wheelDelta || evt.originalEvent.detail;
+ }
+ if (delta != null) {
+ evt.preventDefault();
+ if (evt.type === 'DOMMouseScroll') {
+ delta = delta * 40;
+ }
+ return this.search_results.scrollTop(delta + this.search_results.scrollTop());
+ }
+ };
+
+ Chosen.prototype.blur_test = function(evt) {
+ if (!this.active_field && this.container.hasClass("chosen-container-active")) {
+ return this.close_field();
+ }
+ };
+
+ Chosen.prototype.close_field = function() {
+ $(this.container[0].ownerDocument).unbind("click.chosen", this.click_test_action);
+ this.active_field = false;
+ this.results_hide();
+ this.container.removeClass("chosen-container-active");
+ this.clear_backstroke();
+ this.show_search_field_default();
+ return this.search_field_scale();
+ };
+
+ Chosen.prototype.activate_field = function() {
+ this.container.addClass("chosen-container-active");
+ this.active_field = true;
+ this.search_field.val(this.search_field.val());
+ return this.search_field.focus();
+ };
+
+ Chosen.prototype.test_active_click = function(evt) {
+ var active_container;
+ active_container = $(evt.target).closest('.chosen-container');
+ if (active_container.length && this.container[0] === active_container[0]) {
+ return this.active_field = true;
+ } else {
+ return this.close_field();
+ }
+ };
+
+ Chosen.prototype.results_build = function() {
+ this.parsing = true;
+ this.selected_option_count = null;
+ this.results_data = SelectParser.select_to_array(this.form_field);
+ if (this.is_multiple) {
+ this.search_choices.find("li.search-choice").remove();
+ } else if (!this.is_multiple) {
+ this.single_set_selected_text();
+ if (this.disable_search || this.form_field.options.length <= this.disable_search_threshold) {
+ this.search_field[0].readOnly = true;
+ this.container.addClass("chosen-container-single-nosearch");
+ } else {
+ this.search_field[0].readOnly = false;
+ this.container.removeClass("chosen-container-single-nosearch");
+ }
+ }
+ this.update_results_content(this.results_option_build({
+ first: true
+ }));
+ this.search_field_disabled();
+ this.show_search_field_default();
+ this.search_field_scale();
+ return this.parsing = false;
+ };
+
+ Chosen.prototype.result_do_highlight = function(el) {
+ var high_bottom, high_top, maxHeight, visible_bottom, visible_top;
+ if (el.length) {
+ this.result_clear_highlight();
+ this.result_highlight = el;
+ this.result_highlight.addClass("highlighted");
+ maxHeight = parseInt(this.search_results.css("maxHeight"), 10);
+ visible_top = this.search_results.scrollTop();
+ visible_bottom = maxHeight + visible_top;
+ high_top = this.result_highlight.position().top + this.search_results.scrollTop();
+ high_bottom = high_top + this.result_highlight.outerHeight();
+ if (high_bottom >= visible_bottom) {
+ return this.search_results.scrollTop((high_bottom - maxHeight) > 0 ? high_bottom - maxHeight : 0);
+ } else if (high_top < visible_top) {
+ return this.search_results.scrollTop(high_top);
+ }
+ }
+ };
+
+ Chosen.prototype.result_clear_highlight = function() {
+ if (this.result_highlight) {
+ this.result_highlight.removeClass("highlighted");
+ }
+ return this.result_highlight = null;
+ };
+
+ Chosen.prototype.results_show = function() {
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
+ this.form_field_jq.trigger("chosen:maxselected", {
+ chosen: this
+ });
+ return false;
+ }
+ this.container.addClass("chosen-with-drop");
+ this.results_showing = true;
+ this.search_field.focus();
+ this.search_field.val(this.search_field.val());
+ this.winnow_results();
+ return this.form_field_jq.trigger("chosen:showing_dropdown", {
+ chosen: this
+ });
+ };
+
+ Chosen.prototype.update_results_content = function(content) {
+ return this.search_results.html(content);
+ };
+
+ Chosen.prototype.results_hide = function() {
+ if (this.results_showing) {
+ this.result_clear_highlight();
+ this.container.removeClass("chosen-with-drop");
+ this.form_field_jq.trigger("chosen:hiding_dropdown", {
+ chosen: this
+ });
+ }
+ return this.results_showing = false;
+ };
+
+ Chosen.prototype.set_tab_index = function(el) {
+ var ti;
+ if (this.form_field.tabIndex) {
+ ti = this.form_field.tabIndex;
+ this.form_field.tabIndex = -1;
+ return this.search_field[0].tabIndex = ti;
+ }
+ };
+
+ Chosen.prototype.set_label_behavior = function() {
+ var _this = this;
+ this.form_field_label = this.form_field_jq.parents("label");
+ if (!this.form_field_label.length && this.form_field.id.length) {
+ this.form_field_label = $("label[for='" + this.form_field.id + "']");
+ }
+ if (this.form_field_label.length > 0) {
+ return this.form_field_label.bind('click.chosen', function(evt) {
+ if (_this.is_multiple) {
+ return _this.container_mousedown(evt);
+ } else {
+ return _this.activate_field();
+ }
+ });
+ }
+ };
+
+ Chosen.prototype.show_search_field_default = function() {
+ if (this.is_multiple && this.choices_count() < 1 && !this.active_field) {
+ this.search_field.val(this.default_text);
+ return this.search_field.addClass("default");
+ } else {
+ this.search_field.val("");
+ return this.search_field.removeClass("default");
+ }
+ };
+
+ Chosen.prototype.search_results_mouseup = function(evt) {
+ var target;
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
+ if (target.length) {
+ this.result_highlight = target;
+ this.result_select(evt);
+ return this.search_field.focus();
+ }
+ };
+
+ Chosen.prototype.search_results_mouseover = function(evt) {
+ var target;
+ target = $(evt.target).hasClass("active-result") ? $(evt.target) : $(evt.target).parents(".active-result").first();
+ if (target) {
+ return this.result_do_highlight(target);
+ }
+ };
+
+ Chosen.prototype.search_results_mouseout = function(evt) {
+ if ($(evt.target).hasClass("active-result" || $(evt.target).parents('.active-result').first())) {
+ return this.result_clear_highlight();
+ }
+ };
+
+ Chosen.prototype.choice_build = function(item) {
+ var choice, close_link,
+ _this = this;
+ choice = $('<li />', {
+ "class": "search-choice"
+ }).html("<span>" + (this.choice_label(item)) + "</span>");
+ if (item.disabled) {
+ choice.addClass('search-choice-disabled');
+ } else {
+ close_link = $('<a />', {
+ "class": 'search-choice-close',
+ 'data-option-array-index': item.array_index
+ });
+ close_link.bind('click.chosen', function(evt) {
+ return _this.choice_destroy_link_click(evt);
+ });
+ choice.append(close_link);
+ }
+ return this.search_container.before(choice);
+ };
+
+ Chosen.prototype.choice_destroy_link_click = function(evt) {
+ evt.preventDefault();
+ evt.stopPropagation();
+ if (!this.is_disabled) {
+ return this.choice_destroy($(evt.target));
+ }
+ };
+
+ Chosen.prototype.choice_destroy = function(link) {
+ if (this.result_deselect(link[0].getAttribute("data-option-array-index"))) {
+ this.show_search_field_default();
+ if (this.is_multiple && this.choices_count() > 0 && this.search_field.val().length < 1) {
+ this.results_hide();
+ }
+ link.parents('li').first().remove();
+ return this.search_field_scale();
+ }
+ };
+
+ Chosen.prototype.results_reset = function() {
+ this.reset_single_select_options();
+ this.form_field.options[0].selected = true;
+ this.single_set_selected_text();
+ this.show_search_field_default();
+ this.results_reset_cleanup();
+ this.form_field_jq.trigger("change");
+ if (this.active_field) {
+ return this.results_hide();
+ }
+ };
+
+ Chosen.prototype.results_reset_cleanup = function() {
+ this.current_selectedIndex = this.form_field.selectedIndex;
+ return this.selected_item.find("abbr").remove();
+ };
+
+ Chosen.prototype.result_select = function(evt) {
+ var high, item;
+ if (this.result_highlight) {
+ high = this.result_highlight;
+ this.result_clear_highlight();
+ if (this.is_multiple && this.max_selected_options <= this.choices_count()) {
+ this.form_field_jq.trigger("chosen:maxselected", {
+ chosen: this
+ });
+ return false;
+ }
+ if (this.is_multiple) {
+ high.removeClass("active-result");
+ } else {
+ this.reset_single_select_options();
+ }
+ high.addClass("result-selected");
+ item = this.results_data[high[0].getAttribute("data-option-array-index")];
+ item.selected = true;
+ this.form_field.options[item.options_index].selected = true;
+ this.selected_option_count = null;
+ if (this.is_multiple) {
+ this.choice_build(item);
+ } else {
+ this.single_set_selected_text(this.choice_label(item));
+ }
+ if (!((evt.metaKey || evt.ctrlKey) && this.is_multiple)) {
+ this.results_hide();
+ }
+ this.search_field.val("");
+ if (this.is_multiple || this.form_field.selectedIndex !== this.current_selectedIndex) {
+ this.form_field_jq.trigger("change", {
+ 'selected': this.form_field.options[item.options_index].value
+ });
+ }
+ this.current_selectedIndex = this.form_field.selectedIndex;
+ evt.preventDefault();
+ return this.search_field_scale();
+ }
+ };
+
+ Chosen.prototype.single_set_selected_text = function(text) {
+ if (text == null) {
+ text = this.default_text;
+ }
+ if (text === this.default_text) {
+ this.selected_item.addClass("chosen-default");
+ } else {
+ this.single_deselect_control_build();
+ this.selected_item.removeClass("chosen-default");
+ }
+ return this.selected_item.find("span").html(text);
+ };
+
+ Chosen.prototype.result_deselect = function(pos) {
+ var result_data;
+ result_data = this.results_data[pos];
+ if (!this.form_field.options[result_data.options_index].disabled) {
+ result_data.selected = false;
+ this.form_field.options[result_data.options_index].selected = false;
+ this.selected_option_count = null;
+ this.result_clear_highlight();
+ if (this.results_showing) {
+ this.winnow_results();
+ }
+ this.form_field_jq.trigger("change", {
+ deselected: this.form_field.options[result_data.options_index].value
+ });
+ this.search_field_scale();
+ return true;
+ } else {
+ return false;
+ }
+ };
+
+ Chosen.prototype.single_deselect_control_build = function() {
+ if (!this.allow_single_deselect) {
+ return;
+ }
+ if (!this.selected_item.find("abbr").length) {
+ this.selected_item.find("span").first().after("<abbr class=\"search-choice-close\"></abbr>");
+ }
+ return this.selected_item.addClass("chosen-single-with-deselect");
+ };
+
+ Chosen.prototype.get_search_text = function() {
+ return $('<div/>').text($.trim(this.search_field.val())).html();
+ };
+
+ Chosen.prototype.winnow_results_set_highlight = function() {
+ var do_high, selected_results;
+ selected_results = !this.is_multiple ? this.search_results.find(".result-selected.active-result") : [];
+ do_high = selected_results.length ? selected_results.first() : this.search_results.find(".active-result").first();
+ if (do_high != null) {
+ return this.result_do_highlight(do_high);
+ }
+ };
+
+ Chosen.prototype.no_results = function(terms) {
+ var no_results_html;
+ no_results_html = $('<li class="no-results">' + this.results_none_found + ' "<span></span>"</li>');
+ no_results_html.find("span").first().html(terms);
+ this.search_results.append(no_results_html);
+ return this.form_field_jq.trigger("chosen:no_results", {
+ chosen: this
+ });
+ };
+
+ Chosen.prototype.no_results_clear = function() {
+ return this.search_results.find(".no-results").remove();
+ };
+
+ Chosen.prototype.keydown_arrow = function() {
+ var next_sib;
+ if (this.results_showing && this.result_highlight) {
+ next_sib = this.result_highlight.nextAll("li.active-result").first();
+ if (next_sib) {
+ return this.result_do_highlight(next_sib);
+ }
+ } else {
+ return this.results_show();
+ }
+ };
+
+ Chosen.prototype.keyup_arrow = function() {
+ var prev_sibs;
+ if (!this.results_showing && !this.is_multiple) {
+ return this.results_show();
+ } else if (this.result_highlight) {
+ prev_sibs = this.result_highlight.prevAll("li.active-result");
+ if (prev_sibs.length) {
+ return this.result_do_highlight(prev_sibs.first());
+ } else {
+ if (this.choices_count() > 0) {
+ this.results_hide();
+ }
+ return this.result_clear_highlight();
+ }
+ }
+ };
+
+ Chosen.prototype.keydown_backstroke = function() {
+ var next_available_destroy;
+ if (this.pending_backstroke) {
+ this.choice_destroy(this.pending_backstroke.find("a").first());
+ return this.clear_backstroke();
+ } else {
+ next_available_destroy = this.search_container.siblings("li.search-choice").last();
+ if (next_available_destroy.length && !next_available_destroy.hasClass("search-choice-disabled")) {
+ this.pending_backstroke = next_available_destroy;
+ if (this.single_backstroke_delete) {
+ return this.keydown_backstroke();
+ } else {
+ return this.pending_backstroke.addClass("search-choice-focus");
+ }
+ }
+ }
+ };
+
+ Chosen.prototype.clear_backstroke = function() {
+ if (this.pending_backstroke) {
+ this.pending_backstroke.removeClass("search-choice-focus");
+ }
+ return this.pending_backstroke = null;
+ };
+
+ Chosen.prototype.keydown_checker = function(evt) {
+ var stroke, _ref1;
+ stroke = (_ref1 = evt.which) != null ? _ref1 : evt.keyCode;
+ this.search_field_scale();
+ if (stroke !== 8 && this.pending_backstroke) {
+ this.clear_backstroke();
+ }
+ switch (stroke) {
+ case 8:
+ this.backstroke_length = this.search_field.val().length;
+ break;
+ case 9:
+ if (this.results_showing && !this.is_multiple) {
+ this.result_select(evt);
+ }
+ this.mouse_on_container = false;
+ break;
+ case 13:
+ if (this.results_showing) {
+ evt.preventDefault();
+ }
+ break;
+ case 32:
+ if (this.disable_search) {
+ evt.preventDefault();
+ }
+ break;
+ case 38:
+ evt.preventDefault();
+ this.keyup_arrow();
+ break;
+ case 40:
+ evt.preventDefault();
+ this.keydown_arrow();
+ break;
+ }
+ };
+
+ Chosen.prototype.search_field_scale = function() {
+ var div, f_width, h, style, style_block, styles, w, _i, _len;
+ if (this.is_multiple) {
+ h = 0;
+ w = 0;
+ style_block = "position:absolute; left: -1000px; top: -1000px; display:none;";
+ styles = ['font-size', 'font-style', 'font-weight', 'font-family', 'line-height', 'text-transform', 'letter-spacing'];
+ for (_i = 0, _len = styles.length; _i < _len; _i++) {
+ style = styles[_i];
+ style_block += style + ":" + this.search_field.css(style) + ";";
+ }
+ div = $('<div />', {
+ 'style': style_block
+ });
+ div.text(this.search_field.val());
+ $('body').append(div);
+ w = div.width() + 25;
+ div.remove();
+ f_width = this.container.outerWidth();
+ if (w > f_width - 10) {
+ w = f_width - 10;
+ }
+ return this.search_field.css({
+ 'width': w + 'px'
+ });
+ }
+ };
+
+ return Chosen;
+
+ })(AbstractChosen);
+
+}).call(this);
diff --git a/platform/www/lib/plugins/farmer/script/plugins.js b/platform/www/lib/plugins/farmer/script/plugins.js
new file mode 100644
index 0000000..f092b39
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/script/plugins.js
@@ -0,0 +1,149 @@
+/**
+ * DokuWiki Plugin farmer (JS for plugin management)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Michael Große <grosse@cosmocode.de>
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+(function () {
+ 'use strict';
+
+ jQuery(function () {
+ // general animal select
+ var $animalSelect = jQuery('select.farmer_chosen_animals');
+ $animalSelect.chosen({
+ width: '100%',
+ search_contains: true,
+ allow_single_deselect: true,
+ "placeholder_text_single": LANG.plugins.farmer.animalSelect
+ });
+
+ jQuery('select.acl_chosen').chosen({
+ disable_search: true,
+ width: '100%'
+ });
+
+
+ // Plugin Management for all Animals
+ var $formAllAnimals = jQuery('#farmer__pluginsforall');
+ $formAllAnimals.find('select')
+ .change(function () {
+ $formAllAnimals.find('button').prop('disabled', false);
+ })
+ .chosen({
+ width: '100%',
+ search_contains: true,
+ "placeholder_text_single": LANG.plugins.farmer.pluginSelect
+ })
+ ;
+
+ // Plugin Management for single Animals
+ var $formSingleAnimal = jQuery('#farmer__pluginsforone');
+ $formSingleAnimal.find('select')
+ .change(function () {
+ var animal = jQuery(this).val();
+ $formSingleAnimal.find('button').prop('disabled', true);
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'plugin_farmer_getPlugins_' + animal
+ },
+ function (data) {
+ $formSingleAnimal.find('div.output').html(data);
+ $formSingleAnimal.find('button').prop('disabled', false);
+ },
+ 'html'
+ )}
+ )
+ .chosen({
+ width: '100%',
+ search_contains: true,
+ "placeholder_text_single": LANG.plugins.farmer.animalSelect
+ })
+ ;
+
+ /**
+ * Handle clicks on the matrix
+ */
+ var $formPluginMatrix = jQuery('#farmer__pluginmatrix').hide();
+ $formPluginMatrix.on('click', 'td', function () {
+ var $td = jQuery(this);
+ $td.html('⌛').css('background-color','transparent');
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'plugin_farmer_modPlugin',
+ plugin: $td.data('plugin'),
+ ani: $td.data('animal')
+ },
+ function (data) {
+ $td.replaceWith(data);
+ },
+ 'html'
+ );
+ });
+
+ /**
+ * show the matrix interface
+ */
+ function showMatrix() {
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'plugin_farmer_getPluginMatrix'
+ },
+ function (data) {
+ $formPluginMatrix.html(data);
+ $formPluginMatrix.show();
+ },
+ 'html'
+ )
+ }
+
+ // make sure there's enough space for the dropdown
+ $animalSelect.on('chosen:showing_dropdown', function (evt, params) {
+ jQuery(evt.target).parent('fieldset').animate({
+ "padding-bottom": '20em'
+ }, 400);
+ }).on('chosen:hiding_dropdown', function (evt, params) {
+ jQuery(evt.target).parent('fieldset').animate({
+ "padding-bottom": '7px'
+ }, 400);
+ });
+
+ var $aclPolicyFieldset = jQuery('#aclPolicyFieldset');
+ if ($aclPolicyFieldset.length) {
+ $animalSelect.on('change', function (evt, params) {
+ var $this = jQuery(this);
+ if ($this.val() === '') {
+ $aclPolicyFieldset.slideDown();
+ } else {
+ $aclPolicyFieldset.slideUp();
+ }
+ });
+ }
+
+
+
+
+ jQuery("input[name=bulkSingleSwitch]:radio").change(function () {
+ if (jQuery('#farmer__bulk').prop("checked")) {
+ $formAllAnimals.show();
+ $formSingleAnimal.hide();
+ $formPluginMatrix.hide();
+ } else if (jQuery('#farmer__single').prop("checked")) {
+ $formAllAnimals.hide();
+ $formSingleAnimal.show();
+ $formPluginMatrix.hide();
+ } else {
+ $formAllAnimals.hide();
+ $formSingleAnimal.hide();
+ showMatrix();
+ }
+ });
+ jQuery('#farmer__bulk').click();
+
+
+ });
+
+})();
diff --git a/platform/www/lib/plugins/farmer/style.less b/platform/www/lib/plugins/farmer/style.less
new file mode 100644
index 0000000..905078c
--- /dev/null
+++ b/platform/www/lib/plugins/farmer/style.less
@@ -0,0 +1,104 @@
+#plugin__farmer_admin {
+
+ .panelHeader {
+ background-color: #eee;
+ margin: 0;
+ padding: 10px 10px 8px;
+ overflow: hidden;
+ border-right: 1px solid @ini_border;
+ border-left: 1px solid @ini_border;
+ }
+
+ .panelMain,
+ .panelFooter {
+ padding: 1em;
+ border-right: 1px solid @ini_border;
+ border-left: 1px solid @ini_border;
+ }
+
+ .panelFooter {
+ border-bottom: 1px solid @ini_border;
+ }
+
+ form {
+ display: block;
+ text-align: center;
+
+ fieldset {
+ width: 80%;
+ padding: 1em;
+ }
+
+ label {
+ text-align: left;
+ display: block;
+ margin-bottom: 0.5em;
+
+ &:hover {
+ background-color: @ini_background_alt;
+ }
+
+ span {
+ display: inline-block;
+ width: 40%;
+ }
+ }
+
+ .chosen-container {
+ margin-bottom: 0.5em;
+ }
+
+ button {
+ margin: 1em;
+ }
+ }
+
+ .pluginmatrix {
+ width: 80%;
+ margin: 1em auto;
+
+ table {
+ thead th {
+ position: relative;
+ height: 8em;
+ vertical-align: bottom;
+ overflow: visible;
+ background-color: transparent;
+ border: none;
+
+ div {
+ transform-origin: bottom left;
+ transform: rotate(-60deg);
+ position: absolute;
+ left: 1em;
+ bottom: 0;
+ z-index: 5;
+ }
+ }
+
+ tbody {
+ position: relative;
+
+ td {
+ cursor: pointer;
+ }
+
+ th.off,
+ td.off {
+ background-color: #c33;
+ }
+
+ th.on,
+ td.on {
+ background-color: #3c3;
+ }
+
+ th.default,
+ td.default {
+ opacity: 0.5;
+ }
+ }
+ }
+ }
+
+}
diff --git a/platform/www/lib/plugins/fastwiki b/platform/www/lib/plugins/fastwiki
new file mode 160000
+Subproject 82b64eac47dbf50c2668b11eeaf901be63994a8
diff --git a/platform/www/lib/plugins/index.html b/platform/www/lib/plugins/index.html
new file mode 100644
index 0000000..977f90e
--- /dev/null
+++ b/platform/www/lib/plugins/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=../../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/platform/www/lib/plugins/info/plugin.info.txt b/platform/www/lib/plugins/info/plugin.info.txt
new file mode 100644
index 0000000..f4c6201
--- /dev/null
+++ b/platform/www/lib/plugins/info/plugin.info.txt
@@ -0,0 +1,7 @@
+base info
+author Andreas Gohr
+email andi@splitbrain.org
+date 2020-06-04
+name Info Plugin
+desc Displays information about various DokuWiki internals
+url http://dokuwiki.org/plugin:info
diff --git a/platform/www/lib/plugins/info/syntax.php b/platform/www/lib/plugins/info/syntax.php
new file mode 100644
index 0000000..0d1e389
--- /dev/null
+++ b/platform/www/lib/plugins/info/syntax.php
@@ -0,0 +1,302 @@
+<?php
+/**
+ * Info Plugin: Displays information about various DokuWiki internals
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Esther Brunner <wikidesign@gmail.com>
+ */
+class syntax_plugin_info extends DokuWiki_Syntax_Plugin
+{
+
+ /**
+ * What kind of syntax are we?
+ */
+ public function getType()
+ {
+ return 'substition';
+ }
+
+ /**
+ * What about paragraphs?
+ */
+ public function getPType()
+ {
+ return 'block';
+ }
+
+ /**
+ * Where to sort in?
+ */
+ public function getSort()
+ {
+ return 155;
+ }
+
+
+ /**
+ * Connect pattern to lexer
+ */
+ public function connectTo($mode)
+ {
+ $this->Lexer->addSpecialPattern('~~INFO:\w+~~', $mode, 'plugin_info');
+ }
+
+ /**
+ * Handle the match
+ *
+ * @param string $match The text matched by the patterns
+ * @param int $state The lexer state for the match
+ * @param int $pos The character position of the matched text
+ * @param Doku_Handler $handler The Doku_Handler object
+ * @return array Return an array with all data you want to use in render
+ */
+ public function handle($match, $state, $pos, Doku_Handler $handler)
+ {
+ $match = substr($match, 7, -2); //strip ~~INFO: from start and ~~ from end
+ return array(strtolower($match));
+ }
+
+ /**
+ * Create output
+ *
+ * @param string $format string output format being rendered
+ * @param Doku_Renderer $renderer the current renderer object
+ * @param array $data data created by handler()
+ * @return boolean rendered correctly?
+ */
+ public function render($format, Doku_Renderer $renderer, $data)
+ {
+ if ($format == 'xhtml') {
+ /** @var Doku_Renderer_xhtml $renderer */
+ //handle various info stuff
+ switch ($data[0]) {
+ case 'syntaxmodes':
+ $renderer->doc .= $this->renderSyntaxModes();
+ break;
+ case 'syntaxtypes':
+ $renderer->doc .= $this->renderSyntaxTypes();
+ break;
+ case 'syntaxplugins':
+ $this->renderPlugins('syntax', $renderer);
+ break;
+ case 'adminplugins':
+ $this->renderPlugins('admin', $renderer);
+ break;
+ case 'actionplugins':
+ $this->renderPlugins('action', $renderer);
+ break;
+ case 'rendererplugins':
+ $this->renderPlugins('renderer', $renderer);
+ break;
+ case 'helperplugins':
+ $this->renderPlugins('helper', $renderer);
+ break;
+ case 'authplugins':
+ $this->renderPlugins('auth', $renderer);
+ break;
+ case 'remoteplugins':
+ $this->renderPlugins('remote', $renderer);
+ break;
+ case 'helpermethods':
+ $this->renderHelperMethods($renderer);
+ break;
+ case 'datetime':
+ $renderer->doc .= date('r');
+ break;
+ default:
+ $renderer->doc .= "no info about ".htmlspecialchars($data[0]);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * list all installed plugins
+ *
+ * uses some of the original renderer methods
+ *
+ * @param string $type
+ * @param Doku_Renderer_xhtml $renderer
+ */
+ protected function renderPlugins($type, Doku_Renderer_xhtml $renderer)
+ {
+ global $lang;
+ $renderer->doc .= '<ul>';
+
+ $plugins = plugin_list($type);
+ $plginfo = array();
+
+ // remove subparts
+ foreach ($plugins as $p) {
+ if (!$po = plugin_load($type, $p)) continue;
+ list($name,/* $part */) = explode('_', $p, 2);
+ $plginfo[$name] = $po->getInfo();
+ }
+
+ // list them
+ foreach ($plginfo as $info) {
+ $renderer->doc .= '<li><div class="li">';
+ $renderer->externallink($info['url'], $info['name']);
+ $renderer->doc .= ' ';
+ $renderer->doc .= '<em>'.$info['date'].'</em>';
+ $renderer->doc .= ' ';
+ $renderer->doc .= $lang['by'];
+ $renderer->doc .= ' ';
+ $renderer->emaillink($info['email'], $info['author']);
+ $renderer->doc .= '<br />';
+ $renderer->doc .= strtr(hsc($info['desc']), array("\n"=>"<br />"));
+ $renderer->doc .= '</div></li>';
+ unset($po);
+ }
+
+ $renderer->doc .= '</ul>';
+ }
+
+ /**
+ * list all installed plugins
+ *
+ * uses some of the original renderer methods
+ *
+ * @param Doku_Renderer_xhtml $renderer
+ */
+ protected function renderHelperMethods(Doku_Renderer_xhtml $renderer)
+ {
+ $plugins = plugin_list('helper');
+ foreach ($plugins as $p) {
+ if (!$po = plugin_load('helper', $p)) continue;
+
+ if (!method_exists($po, 'getMethods')) continue;
+ $methods = $po->getMethods();
+ $info = $po->getInfo();
+
+ $hid = $this->addToToc($info['name'], 2, $renderer);
+ $doc = '<h2><a name="'.$hid.'" id="'.$hid.'">'.hsc($info['name']).'</a></h2>';
+ $doc .= '<div class="level2">';
+ $doc .= '<p>'.strtr(hsc($info['desc']), array("\n"=>"<br />")).'</p>';
+ $doc .= '<pre class="code">$'.$p." = plugin_load('helper', '".$p."');</pre>";
+ $doc .= '</div>';
+ foreach ($methods as $method) {
+ $title = '$'.$p.'->'.$method['name'].'()';
+ $hid = $this->addToToc($title, 3, $renderer);
+ $doc .= '<h3><a name="'.$hid.'" id="'.$hid.'">'.hsc($title).'</a></h3>';
+ $doc .= '<div class="level3">';
+ $doc .= '<div class="table"><table class="inline"><tbody>';
+ $doc .= '<tr><th>Description</th><td colspan="2">'.$method['desc'].
+ '</td></tr>';
+ if ($method['params']) {
+ $c = count($method['params']);
+ $doc .= '<tr><th rowspan="'.$c.'">Parameters</th><td>';
+ $params = array();
+ foreach ($method['params'] as $desc => $type) {
+ $params[] = hsc($desc).'</td><td>'.hsc($type);
+ }
+ $doc .= join('</td></tr><tr><td>', $params).'</td></tr>';
+ }
+ if ($method['return']) {
+ $doc .= '<tr><th>Return value</th><td>'.hsc(key($method['return'])).
+ '</td><td>'.hsc(current($method['return'])).'</td></tr>';
+ }
+ $doc .= '</tbody></table></div>';
+ $doc .= '</div>';
+ }
+ unset($po);
+
+ $renderer->doc .= $doc;
+ }
+ }
+
+ /**
+ * lists all known syntax types and their registered modes
+ *
+ * @return string
+ */
+ protected function renderSyntaxTypes()
+ {
+ global $PARSER_MODES;
+ $doc = '';
+
+ $doc .= '<div class="table"><table class="inline"><tbody>';
+ foreach ($PARSER_MODES as $mode => $modes) {
+ $doc .= '<tr>';
+ $doc .= '<td class="leftalign">';
+ $doc .= $mode;
+ $doc .= '</td>';
+ $doc .= '<td class="leftalign">';
+ $doc .= join(', ', $modes);
+ $doc .= '</td>';
+ $doc .= '</tr>';
+ }
+ $doc .= '</tbody></table></div>';
+ return $doc;
+ }
+
+ /**
+ * lists all known syntax modes and their sorting value
+ *
+ * @return string
+ */
+ protected function renderSyntaxModes()
+ {
+ $modes = p_get_parsermodes();
+
+ $compactmodes = array();
+ foreach ($modes as $mode) {
+ $compactmodes[$mode['sort']][] = $mode['mode'];
+ }
+ $doc = '';
+ $doc .= '<div class="table"><table class="inline"><tbody>';
+
+ foreach ($compactmodes as $sort => $modes) {
+ $rowspan = '';
+ if (count($modes) > 1) {
+ $rowspan = ' rowspan="'.count($modes).'"';
+ }
+
+ foreach ($modes as $index => $mode) {
+ $doc .= '<tr>';
+ $doc .= '<td class="leftalign">';
+ $doc .= $mode;
+ $doc .= '</td>';
+
+ if ($index === 0) {
+ $doc .= '<td class="rightalign" '.$rowspan.'>';
+ $doc .= $sort;
+ $doc .= '</td>';
+ }
+ $doc .= '</tr>';
+ }
+ }
+
+ $doc .= '</tbody></table></div>';
+ return $doc;
+ }
+
+ /**
+ * Adds a TOC item
+ *
+ * @param string $text
+ * @param int $level
+ * @param Doku_Renderer_xhtml $renderer
+ * @return string
+ */
+ protected function addToToc($text, $level, Doku_Renderer_xhtml $renderer)
+ {
+ global $conf;
+
+ $hid = '';
+ if (($level >= $conf['toptoclevel']) && ($level <= $conf['maxtoclevel'])) {
+ $hid = $renderer->_headerToLink($text, true);
+ $renderer->toc[] = array(
+ 'hid' => $hid,
+ 'title' => $text,
+ 'type' => 'ul',
+ 'level' => $level - $conf['toptoclevel'] + 1
+ );
+ }
+ return $hid;
+ }
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/markdowku/LICENSE b/platform/www/lib/plugins/markdowku/LICENSE
new file mode 100644
index 0000000..40ff04a
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/LICENSE
@@ -0,0 +1,27 @@
+BSD 2-Clause License
+
+Copyright (c) 2017, Julian Fagir <gnrp@komkon2.de>
+Copyright (c) 2020, Raphael Wimmer <raphael.wimmer@ur.de>
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/platform/www/lib/plugins/markdowku/README.md b/platform/www/lib/plugins/markdowku/README.md
new file mode 100644
index 0000000..d5b199a
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/README.md
@@ -0,0 +1,2 @@
+# dokuwiki-plugin-markdowku
+Markdowku - markdown syntax plugin for DokuWiki
diff --git a/platform/www/lib/plugins/markdowku/manager.dat b/platform/www/lib/plugins/markdowku/manager.dat
new file mode 100644
index 0000000..664b6c7
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/manager.dat
@@ -0,0 +1,2 @@
+downloadurl=https://github.com/Medieninformatik-Regensburg/dokuwiki-plugin-markdowku/archive/refs/heads/master.zip
+installed=Sun, 06 Mar 2022 22:47:06 +0000
diff --git a/platform/www/lib/plugins/markdowku/plugin.info.txt b/platform/www/lib/plugins/markdowku/plugin.info.txt
new file mode 100644
index 0000000..7682646
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/plugin.info.txt
@@ -0,0 +1,7 @@
+base markdowku
+author Julian Fagir, Raphael Wimmer (maintainer)
+email raphael.wimmer@ur.de
+date 2021-12-04
+name Markdowku
+desc Integrates Markdown into Dokuwiki syntax
+url https://www.dokuwiki.org/plugin:markdowku
diff --git a/platform/www/lib/plugins/markdowku/syntax/anchorsinline.php b/platform/www/lib/plugins/markdowku/syntax/anchorsinline.php
new file mode 100644
index 0000000..b16f2b4
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/anchorsinline.php
@@ -0,0 +1,46 @@
+<?php
+/*
+ * Inline links [name](target "title")
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_anchorsinline extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'substition'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 102; }
+
+ function connectTo($mode) {
+ $this->nested_brackets_re =
+ str_repeat('(?>[^\[\]]+|\[', 6).
+ str_repeat('\])*', 6);
+ $this->Lexer->addSpecialPattern(
+ '\['.$this->nested_brackets_re.'\]\([ \t]*<?.+?>?[ \t]*(?:[\'"].*?[\'"])?\)',
+ $mode,
+ 'plugin_markdowku_anchorsinline'
+ );
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ if ($state == DOKU_LEXER_SPECIAL) {
+ $text = preg_match(
+ '/^\[('.$this->nested_brackets_re.')\]\([ \t]*<?(.+?)>?[ \t]*(?:[\'"](.*?)[\'"])?[ \t]*?\)$/',
+ $match,
+ $matches);
+ $target = $matches[2] == '' ? $matches[3] : $matches[2];
+ $title = $matches[1];
+
+ $target = preg_replace('/^mailto:/', '', $target);
+ $handler->internallink($target.'|'.$title, $state, $pos);
+ }
+ return true;
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/anchorsreference.php b/platform/www/lib/plugins/markdowku/syntax/anchorsreference.php
new file mode 100644
index 0000000..be8cdd6
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/anchorsreference.php
@@ -0,0 +1,62 @@
+<?php
+/*
+ * Reference links, i.e.
+ * ... [name][id] ...
+ * ... [id][] ...
+ * ...
+ * [id]: http://example.com (handled by markdowku_references)
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_anchorsreference extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'substition'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 102; }
+
+ function connectTo($mode) {
+ $this->nested_brackets_re =
+ str_repeat('(?>[^\[\]]+|\[', 3).
+ str_repeat('\])*', 3);
+ $this->Lexer->addSpecialPattern(
+ '\['.$this->nested_brackets_re.'\][ ]?(?:\n[ ]*)?\[[^\[\]\n]*?\]',
+ $mode,
+ 'plugin_markdowku_anchorsreference');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($state, $match);
+ }
+
+ function render($mode, Doku_Renderer$renderer, $data) {
+ global $ID;
+ preg_match(
+ '/^\[('.$this->nested_brackets_re.')\][ ]?(?:\n[ ]*)?\[(.*?)\]$/',
+ $data[1],
+ $matches);
+
+ $title = $matches[1];
+
+ if ($matches[2] == '')
+ $rid = $matches[1];
+ else
+ $rid = $matches[2];
+
+ $rid = preg_replace("/ /", ".", $rid);
+ $target = p_get_metadata($ID, 'markdowku_references_'.$rid, METADATA_RENDER_USING_CACHE);
+ if ($target == '') {
+ $renderer->cdata($data[1]);
+ } else if (preg_match('/^mailto:/', $target) or
+ preg_match('<'.PREG_PATTERN_VALID_EMAIL.'>', $target)) {
+ $target = preg_replace('/^mailto:/', '', $target);
+ $renderer->emaillink($target, $title);
+ } else {
+ $renderer->externallink($target, $title);
+ }
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/autolinks.php b/platform/www/lib/plugins/markdowku/syntax/autolinks.php
new file mode 100644
index 0000000..b6ed523
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/autolinks.php
@@ -0,0 +1,40 @@
+<?php
+/*
+ * Autolinks enclosed in <...>
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_autolinks extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'substition'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 102; }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '<(?:https?|ftp|mailto):[^\'">\s]+?>',
+ $mode,
+ 'plugin_markdowku_autolinks'
+ );
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ if (preg_match('/^<mailto:/', $match)) {
+ $match = substr($match, 8, -1);
+ $handler->_addCall('emaillink', array($match, NULL), $pos);
+ } else {
+ $match = substr($match, 1, -1);
+ $handler->_addCall('externallink', array($match, NULL), $pos);
+ }
+
+ return true;
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/blockquotes.php b/platform/www/lib/plugins/markdowku/syntax/blockquotes.php
new file mode 100644
index 0000000..463c049
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/blockquotes.php
@@ -0,0 +1,115 @@
+<?php
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+include_once('headeratx.php');
+
+use dokuwiki\Parsing\Handler\Quote;
+
+class syntax_plugin_markdowku_blockquotes extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'container'; }
+ function getPType() { return 'block'; }
+ function getSort() { return 219; }
+ function getAllowedTypes() {
+ return array('formatting', 'substition', 'disabled', 'protected',
+ 'container');
+ }
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern(
+ // (?<=\n)[ \t]*>[ \t]?(?=(?:\n[ ]*[^>]|\Z))
+// '\n[ \t]*>[ \t]?.+?\n(?:.+\n)*',
+// '(?:\n|\A)[ \t]*>(?:[ >\t]*)?', //[ \t]?(?=[^\n]+?\n)',
+ '(?:\n|\A)[ \t]*>(?:[ >\t]*)?.*?(?=\n)', //[ \t]?(?=[^\n]+?\n)',
+ $mode,
+ 'plugin_markdowku_blockquotes');
+
+ /* Setext headers need two lines */
+ $this->Lexer->addPattern(
+ '\n[ \t]*>(?:[ \t>]*>)?[ \t]?[^\n]+?[ \t]*\n[ \t]*>(?:[ \t>]*>)?[ \t]?=+[ \t]*',
+ 'plugin_markdowku_blockquotes');
+
+ $this->Lexer->addPattern(
+ '\n[ \t]*>(?:[ \t>]*>)?[ \t]?[^\n]+?[ \t]*\n[ \t]*>(?:[ \t>]*>)?[ \t]?-+[ \t]*',
+ 'plugin_markdowku_blockquotes');
+
+ $this->Lexer->addPattern(
+// '\n[ \t]*>(?:[ \t>]*>)?[ \t]?', //[ \t]?(?=[^\n]+?\n)',
+ '\n[ \t]*>(?:[ \t>]*>)?[ \t]?.*?(?=\n)', //[ \t]?(?=[^\n]+?\n)',
+ 'plugin_markdowku_blockquotes');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern(
+ '(?:\n[^>]|\Z)',
+ 'plugin_markdowku_blockquotes');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ global $DOKU_PLUGINS;
+
+ preg_match('/^\n[ \t]*>(?:[ \t>]*>)?[ \t]?/', $match, $quotearg);
+ $quoteinarg = preg_replace('/^\n[ \t]*>(?:[ \t>]*>)?[ \t]?/', '', $match);
+
+ if ($state == DOKU_LEXER_ENTER) {
+ $ReWriter = new Doku_Handler_Markdown_Quote($handler->getCallWriter());
+ $handler->setCallWriter($ReWriter);
+ $handler->_addCall('quote_start', $quotearg, $pos);
+ } elseif ($state == DOKU_LEXER_EXIT) {
+ $handler->_addCall('quote_end', array(), $pos);
+ $handler->getCallWriter()->process();
+ $ReWriter = & $handler->getCallWriter();
+ $handler->setCallWriter($ReWriter->getCallWriter());
+ }
+
+ if ($quoteinarg == '') {
+ $handler->_addCall('quote_newline', $quotearg, $pos);
+ /* ATX headers (headeratx) */
+ } elseif (preg_match('/^\#{1,6}[ \t]*.+?[ \t]*\#*/', $quoteinarg)) {
+ $plugin =& plugin_load('syntax', 'markdowku_headeratx');
+ $plugin->handle($quoteinarg, $state, $pos, $handler);
+ /* Horizontal rulers (hr) */
+ } elseif (preg_match('/[ ]{0,2}(?:[ ]?_[ ]?){3,}[ \t]*/', $quoteinarg)
+ or preg_match('/[ ]{0,2}(?:[ ]?-[ ]?){3,}[ \t]*/', $quoteinarg)
+ or preg_match('/[ ]{0,2}(?:[ ]?\*[ ]?){3,}[ \t]*/', $quoteinarg)) {
+ $plugin =& plugin_load('syntax', 'markdowku_hr');
+ $plugin->handle($quoteinarg, $state, $pos, $handler);
+ /* Setext headers (headersetext) */
+ } elseif (preg_match('/^[^\n]+?[ \t]*\n[ \t]*>(?:[ \t>]*>)?[ \t]?=+[ \t]*/', $quoteinarg)
+ or preg_match('/^[^\n]+?[ \t]*\n[ \t]*>(?:[ \t>]*>)?[ \t]?-+[ \t]*/', $quoteinarg)) {
+ $quoteinarg = preg_replace('/(?<=\n)[ \t]*>(?:[ \t>]*>)?[ \t]?/', '', $quoteinarg);
+ $plugin =& plugin_load('syntax', 'markdowku_headersetext');
+ $plugin->handle($quoteinarg, $state, $pos, $handler);
+ } else {
+ $handler->_addCall('cdata', array($quoteinarg), $pos);
+ }
+
+ return true;
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ return true;
+ }
+}
+
+class Doku_Handler_Markdown_Quote extends Quote {
+ function getDepth($marker) {
+ $quoteLength = 0;
+ $position = 0;
+ $text = preg_replace('/^\n*/', '', $marker);
+ while (TRUE) {
+ if (preg_match('/^[ \t]/', substr($text, $position)) > 0) {
+ $position++;
+ } elseif (preg_match('/^>/', substr($text, $position)) > 0) {
+ $position++;
+ $quoteLength++;
+ } else {
+ break;
+ }
+ }
+ return $quoteLength;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/boldasterisk.php b/platform/www/lib/plugins/markdowku/syntax/boldasterisk.php
new file mode 100644
index 0000000..0dcad52
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/boldasterisk.php
@@ -0,0 +1,45 @@
+<?php
+/*
+ * Bold text enclosed in asterisks: **...**
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_boldasterisk extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'formatting'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 69; }
+ function getAllowedTypes() { return array('formatting', 'substition'); }
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern(
+ '(?<![\\\\*])\*\*(?![ ])(?=(?:(?!\n\n).)+?[^\\\\ ]\*\*)',
+ $mode,
+ 'plugin_markdowku_boldasterisk');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern(
+ '(?<![\\\\ ])\*\*',
+ 'plugin_markdowku_boldasterisk');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($state, $match);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ if ($data[0] == DOKU_LEXER_ENTER)
+ $renderer->strong_open();
+ elseif ($data[0] == DOKU_LEXER_EXIT)
+ $renderer->strong_close();
+ else
+ $renderer->cdata($data[1]);
+
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/codeblocks.php b/platform/www/lib/plugins/markdowku/syntax/codeblocks.php
new file mode 100644
index 0000000..bbda567
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/codeblocks.php
@@ -0,0 +1,63 @@
+<?php
+/*
+ * Codeblocks, indented by four spaces
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+use dokuwiki\Parsing\Handler\Preformatted;
+
+class syntax_plugin_markdowku_codeblocks extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'protected'; }
+ function getPType() { return 'block'; }
+ function getSort() { return 199; }
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern(
+ '(?:\n\n|\A\n?) ',
+ $mode,
+ 'plugin_markdowku_codeblocks');
+
+ $this->Lexer->addPattern(
+ '\n ',
+ 'plugin_markdowku_codeblocks');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern(
+ '\n(?:(?=\n*[ ]{0,3}\S)|\Z)',
+ 'plugin_markdowku_codeblocks');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ switch ($state) {
+ case DOKU_LEXER_ENTER:
+ $ReWriter = new Preformatted($handler->getCallWriter());
+ $handler->setCallWriter($ReWriter);
+ $handler->_addCall('preformatted_start', array($match), $pos);
+ break;
+ case DOKU_LEXER_MATCHED:
+ $handler->_addCall('preformatted_newline', array($match), $pos);
+ break;
+ case DOKU_LEXER_UNMATCHED:
+ $handler->_addCall('preformatted_content', array($match), $pos);
+ break;
+ case DOKU_LEXER_EXIT:
+ $handler->_addCall('preformatted_end', array(), $pos);
+ $handler->_addCall('preformatted_content', array($match), $pos);
+ $handler->getCallWriter()->process();
+ $ReWriter = & $handler->getCallWriter();
+ $handler->setCallWriter($ReWriter->getCallWriter());
+ break;
+ }
+ return true;
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ return false;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/codespans1.php b/platform/www/lib/plugins/markdowku/syntax/codespans1.php
new file mode 100644
index 0000000..6465288
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/codespans1.php
@@ -0,0 +1,35 @@
+<?php
+/*
+ * Codespans enclosed with one backtick: `...`
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_codespans1 extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'formatting'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 99; }
+ function getAllowedTypes() { return array(); }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '(?<!`)`(?!`).+?(?<!`)`(?!`)',
+ $mode,
+ 'plugin_markdowku_codespans1');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($match);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ $renderer->monospace_open();
+ $renderer->cdata(substr($data[0], 1, -1));
+ $renderer->monospace_close();
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/codespans2.php b/platform/www/lib/plugins/markdowku/syntax/codespans2.php
new file mode 100644
index 0000000..596fc28
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/codespans2.php
@@ -0,0 +1,34 @@
+<?php
+/*
+ * Codespans enclosed with two backticks: ``...``
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_codespans2 extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'formatting'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 98; }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '(?<!`)``(?!`).+?(?<!`)``(?!`)',
+ $mode,
+ 'plugin_markdowku_codespans2');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($match);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ $renderer->monospace_open();
+ $renderer->cdata(substr($data[0], 2, -2));
+ $renderer->monospace_close();
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/codespans3.php b/platform/www/lib/plugins/markdowku/syntax/codespans3.php
new file mode 100644
index 0000000..b6b342b
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/codespans3.php
@@ -0,0 +1,34 @@
+<?php
+/*
+ * Codespans enclosed within three backticks: ```...```
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_codespans3 extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'formatting'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 97; }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '(?<!`)```(?!`).+?(?<!`)```(?!`)',
+ $mode,
+ 'plugin_markdowku_codespans3');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($match);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ $renderer->monospace_open();
+ $renderer->cdata(substr($data[0], 3, -3));
+ $renderer->monospace_close();
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/codespans4.php b/platform/www/lib/plugins/markdowku/syntax/codespans4.php
new file mode 100644
index 0000000..4166d7f
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/codespans4.php
@@ -0,0 +1,34 @@
+<?php
+/*
+ * Codespans enclosed within four backticks: ````...````
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_codespans4 extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'formatting'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 96; }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '(?<!`)````(?!`).+?(?<!`)````(?!`)',
+ $mode,
+ 'plugin_markdowku_codespans4');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($match);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ $renderer->monospace_open();
+ $renderer->cdata(substr($data[0], 4, -4));
+ $renderer->monospace_close();
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/codespans5.php b/platform/www/lib/plugins/markdowku/syntax/codespans5.php
new file mode 100644
index 0000000..00f33d2
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/codespans5.php
@@ -0,0 +1,34 @@
+<?php
+/*
+ * Codespans enclosed within five brackets: `````...`````
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_codespans5 extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'formatting'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 95; }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '(?<!`)`````(?!`).+?(?<!`)`````(?!`)',
+ $mode,
+ 'plugin_markdowku_codespans5');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($match);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ $renderer->monospace_open();
+ $renderer->cdata(substr($data[0], 5, -5));
+ $renderer->monospace_close();
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/escapespecialchars.php b/platform/www/lib/plugins/markdowku/syntax/escapespecialchars.php
new file mode 100644
index 0000000..b27b7c0
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/escapespecialchars.php
@@ -0,0 +1,94 @@
+<?php
+/*
+ * Unescape escaped backslash. \\\\ -> \
+ * This is in a separate class as it needs a higher priority than the other
+ * escapes.
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_escapespecialchars extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'substition'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 61; }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\`',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\*',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\_',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\{',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\}',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\[',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\]',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\(',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\)',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\>',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\#',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\+',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\-',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\-',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\\.',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ $this->Lexer->addSpecialPattern(
+ '(?<!\\\\)\\\\!',
+ $mode,
+ 'plugin_markdowku_escapespecialchars');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($state, $match);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ $renderer->doc .= substr($data[1], -1);
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/githubcodeblocks.php b/platform/www/lib/plugins/markdowku/syntax/githubcodeblocks.php
new file mode 100644
index 0000000..c715c55
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/githubcodeblocks.php
@@ -0,0 +1,48 @@
+<?php
+/*
+ * Github style codeblocks, starting and ending with three backticks, optionally
+ * providing a language to be used for syntax highlighting.
+ *
+ * ```php
+ * ...
+ * ```
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_githubcodeblocks extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'protected'; }
+ function getPType() { return 'block'; }
+ function getSort() { return 91; }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '\n```[a-z0-9_]*\n.+?\n```(?=\n)',
+ $mode,
+ 'plugin_markdowku_githubcodeblocks');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ if (preg_match('/^\n```([a-z0-9_]+)\n/', $match, $matches) > 0) {
+ $lang = $matches[1];
+ } else {
+ $lang = NULL;
+ }
+
+ $text = preg_replace('/^```[a-z0-9_]+\n/m', '', $match);
+ $text = preg_replace('/^```$/m', '', $text);
+ if ($lang)
+ $handler->_addCall('file', array($text, $lang, 'snippet.'.$lang), $pos);
+ else
+ $handler->_addCall('code', array($text, $lang), $pos);
+ return true;
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/headeratx.php b/platform/www/lib/plugins/markdowku/syntax/headeratx.php
new file mode 100644
index 0000000..b55c38c
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/headeratx.php
@@ -0,0 +1,57 @@
+<?php
+/*
+ * Header in ATX style, i.e. '# Header1', '## Header2', ...
+ */
+
+if (!defined('DOKU_INC')) die();
+if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
+require_once (DOKU_PLUGIN . 'syntax.php');
+
+class syntax_plugin_markdowku_headeratx extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'baseonly'; }
+ function getPType() { return 'block'; }
+ function getSort() { return 49; }
+ function getAllowedTypes() {
+ return array('formatting', 'substition', 'disabled', 'protected');
+ }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '\n\#{1,6}[ \t]*.+?[ \t]*\#*(?=\n+)',
+ 'base',
+ 'plugin_markdowku_headeratx');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ global $conf;
+
+ $title = trim($match);
+ $level = strspn($title, '#');
+ $title = trim($title, '#');
+ $title = trim($title);
+
+ if ($level < 1)
+ $level = 1;
+ elseif ($level > 6)
+ $level = 6;
+
+ if ($handler->getStatus('section'))
+ $handler->_addCall('section_close', array(), $pos);
+ if ($level <= $conf['maxseclevel']) {
+ $handler->setStatus('section_edit_start', $pos);
+ $handler->setStatus('section_edit_level', $level);
+ $handler->setStatus('section_edit_title', $title);
+ }
+ $handler->_addCall('header', array($title, $level, $pos), $pos);
+ $handler->_addCall('section_open', array($level), $pos);
+ $handler->setStatus('section', true);
+
+ return true;
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/headersetext.php b/platform/www/lib/plugins/markdowku/syntax/headersetext.php
new file mode 100644
index 0000000..43e9551
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/headersetext.php
@@ -0,0 +1,56 @@
+<?php
+/*
+ * Setext style headers:
+ * Header
+ * ======
+ */
+
+if (!defined('DOKU_INC')) die();
+if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
+require_once (DOKU_PLUGIN . 'syntax.php');
+
+class syntax_plugin_markdowku_headersetext extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'baseonly'; }
+ function getPType() { return 'block'; }
+ function getSort() { return 49; }
+ function getAllowedTypes() {
+ return array('formatting', 'substition', 'disabled', 'protected');
+ }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '\n[^\n]+[ \t]*\n=+[ \t]*(?=\n)',
+ 'base',
+ 'plugin_markdowku_headersetext');
+
+ $this->Lexer->addSpecialPattern(
+ '\n[^\n]+[ \t]*\n-+[ \t]*(?=\n)',
+ 'base',
+ 'plugin_markdowku_headersetext');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ $title = preg_replace('/^\n(.+?)[ \t]*\n.*/', '\1', $match);
+ $title = trim($title);
+ if (preg_match('/^\n(.+?)[ \t]*\n=/', $match))
+ $level = 1;
+ if (preg_match('/^\n(.+?)[ \t]*\n-/', $match))
+ $level = 2;
+
+ if ($handler->getStatus('section'))
+ $handler->_addCall('section_close', array(), $pos);
+ $handler->setStatus('section_edit_start', $pos);
+ $handler->setStatus('section_edit_level', $level);
+ $handler->setStatus('section_edit_title', $title);
+ $handler->_addCall('header', array($title, $level, $pos), $pos);
+ $handler->_addCall('section_open', array($level), $pos);
+ $handler->setStatus('section', true);
+ return true;
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/hr.php b/platform/www/lib/plugins/markdowku/syntax/hr.php
new file mode 100644
index 0000000..f9da2c0
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/hr.php
@@ -0,0 +1,47 @@
+<?php
+/*
+ * Horizontal rulers:
+ * * * *
+ * ---
+ * ___
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_hr extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'container'; }
+ function getPType() { return 'block'; }
+ function getSort() { return 8; } /* Before list block parsing. */
+
+ function connectTo($mode) {
+ /* We use two newlines, as we don't want to conflict with setext header
+ * parsing, but also have to be before list blocks. */
+ $this->Lexer->addSpecialPattern(
+ '\n[ ]{0,2}(?:[ ]?\*[ ]?){3,}[ \t]*(?=\n)',
+ $mode,
+ 'plugin_markdowku_hr');
+
+ $this->Lexer->addSpecialPattern(
+ '\n[ ]{0,2}(?:[ ]?-[ ]?){3,}[ \t]*(?=\n)',
+ $mode,
+ 'plugin_markdowku_hr');
+
+ $this->Lexer->addSpecialPattern(
+ '\n[ ]{0,2}(?:[ ]?_[ ]?){3,}[ \t]*(?=\n)',
+ $mode,
+ 'plugin_markdowku_hr');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ $handler->_addCall('hr', array(), $pos);
+ return true;
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/imagesinline.php b/platform/www/lib/plugins/markdowku/syntax/imagesinline.php
new file mode 100644
index 0000000..28b7d75
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/imagesinline.php
@@ -0,0 +1,43 @@
+<?php
+/*
+ * Inline images: ![source](description "title")
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_imagesinline extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'substition'; }
+ function getPType() { return 'block'; }
+ function getSort() { return 101; }
+
+ function connectTo($mode) {
+ $this->nested_brackets_re =
+ str_repeat('(?>[^\[\]]+|\[', 6).
+ str_repeat('\])*', 6);
+ $this->Lexer->addSpecialPattern(
+ '\!\['.$this->nested_brackets_re.'\]\([ \t]*<?.+?>?[ \t]*(?:[\'"].*?[\'"])?\)',
+ $mode,
+ 'plugin_markdowku_imagesinline');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ if ($state == DOKU_LEXER_SPECIAL) {
+ $text = preg_match(
+ '/^\!\[('.$this->nested_brackets_re.')\]\([ \t]*<?(.+?)>?[ \t]*(?:[\'"](.*?)[\'"])?[ \t]*?\)$/',
+ $match,
+ $matches);
+ $target = $matches[2] == '' ? $matches[3] : $matches[2];
+ $title = $matches[1];
+ $handler->media($target.'|'.$title, $state, $pos);
+ }
+ return true;
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/imagesreference.php b/platform/www/lib/plugins/markdowku/syntax/imagesreference.php
new file mode 100644
index 0000000..9382d2a
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/imagesreference.php
@@ -0,0 +1,58 @@
+<?php
+/*
+ * Reference links, i.e.
+ * ... [name][id] ...
+ * ... [id][] ...
+ * ...
+ * [id]: http://example.com (handled by markdowku_references)
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_imagesreference extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'substition'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 102; }
+
+ function connectTo($mode) {
+ $this->nested_brackets_re =
+ str_repeat('(?>[^\[\]]+|\[', 3).
+ str_repeat('\])*', 3);
+ $this->Lexer->addSpecialPattern(
+ '\!\['.$this->nested_brackets_re.'\][ ]?(?:\n[ ]*)?\[[^\n]*?\]',
+ $mode,
+ 'plugin_markdowku_imagesreference');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($state, $match);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ global $ID;
+ preg_match(
+ '/^\!\[('.$this->nested_brackets_re.')\][ ]?(?:\n[ ]*)?\[(.*?)\]$/',
+ $data[1],
+ $matches);
+
+ $title = $matches[1];
+
+ if ($matches[2] == '')
+ $rid = $matches[1];
+ else
+ $rid = $matches[2];
+
+ $rid = preg_replace("/ /", ".", $rid);
+ $target = p_get_metadata($ID, 'markdowku_references_'.$rid, METADATA_RENDER_USING_CACHE);
+ if ($target == '')
+ $renderer->cdata($data[1]);
+ else
+ $renderer->_media($target, $title);
+
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/italicasterisk.php b/platform/www/lib/plugins/markdowku/syntax/italicasterisk.php
new file mode 100644
index 0000000..bebc45f
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/italicasterisk.php
@@ -0,0 +1,49 @@
+<?php
+/*
+ * Italic text enclosed by asterisks, i.e. *...*
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+# Fix for Hogfather RC2 - see https://github.com/dwp-forge/columns/issues/5#issuecomment-638467603
+require_once(DOKU_INC.'inc/Parsing/Lexer/Lexer.php');
+
+class syntax_plugin_markdowku_italicasterisk extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'formatting'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 79; }
+ function getAllowedTypes() {
+ return Array('formatting', 'substition');
+ }
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern(
+ '(?<![\\\\])\*(?![ *])(?=(?:(?!\n\n).)+?(?<![\\\\ *])\*)',
+ $mode,
+ 'plugin_markdowku_italicasterisk');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern(
+ '(?<![\\\\* ])\*',
+ 'plugin_markdowku_italicasterisk');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($state, $match);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ if ($data[0] == DOKU_LEXER_ENTER)
+ $renderer->emphasis_open();
+ elseif ($data[0] == DOKU_LEXER_EXIT)
+ $renderer->emphasis_close();
+ else
+ $renderer->cdata($data[1]);
+
+ return true;
+ }
+}
diff --git a/platform/www/lib/plugins/markdowku/syntax/italicunderline.php b/platform/www/lib/plugins/markdowku/syntax/italicunderline.php
new file mode 100644
index 0000000..13a5a02
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/italicunderline.php
@@ -0,0 +1,56 @@
+<?php
+/*
+ * Italic text enclosed in underlines: _..._
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+# Fix for Hogfather RC2 - see https://github.com/dwp-forge/columns/issues/5#issuecomment-638467603
+require_once(DOKU_INC.'inc/Parsing/Lexer/Lexer.php');
+
+class syntax_plugin_markdowku_italicunderline extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'formatting'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 79; }
+ function getAllowedTypes() {
+ return Array('formatting', 'substition');
+ }
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern(
+ '(?<![\\\\])_(?![ _])(?=(?:(?!\n\n).)+?[^\\\\ _]_)',
+ $mode,
+ 'plugin_markdowku_italicunderline');
+// $this->Lexer->addSpecialPattern(
+// '\w+_\w+_\w[\w_]*',
+// $mode,
+// 'plugin_markdowku_italicunderline');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern(
+ '(?<![\\\\_ ])_',
+ 'plugin_markdowku_italicunderline');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($state, $match);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+
+ if ($data[0] == DOKU_LEXER_ENTER)
+ $renderer->emphasis_open();
+ elseif ($data[0] == DOKU_LEXER_EXIT)
+ $renderer->emphasis_close();
+ elseif ($data[0] == DOKU_LEXER_UNMATCHED)
+ $renderer->cdata($data[1]);
+ elseif ($data[0] == DOKU_LEXER_SPECIAL)
+ $renderer->cdata($data[1]);
+
+ return true;
+ }
+}
diff --git a/platform/www/lib/plugins/markdowku/syntax/linebreak.php b/platform/www/lib/plugins/markdowku/syntax/linebreak.php
new file mode 100644
index 0000000..ef2f1df
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/linebreak.php
@@ -0,0 +1,32 @@
+<?php
+/*
+ * Linebreaks, determined by two spaces at the line end.
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_linebreak extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'substition'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 139; }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '[ ]{2,}\n',
+ $mode,
+ 'plugin_markdowku_linebreak');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($match, $state, $pos);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ $renderer->linebreak();
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/olists.php b/platform/www/lib/plugins/markdowku/syntax/olists.php
new file mode 100644
index 0000000..853232a
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/olists.php
@@ -0,0 +1,98 @@
+<?php
+/*
+ * Ordered lists:
+ * 1. ...
+ * 2. ...
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+use dokuwiki\Parsing\Handler\Lists;
+
+class syntax_plugin_markdowku_olists extends DokuWiki_Syntax_Plugin {
+ function getType() { return 'container'; }
+ function getPType() { return 'block'; }
+ function getSort() { return 9; }
+ function getAllowedTypes() {
+ return array('formatting', 'substition', 'paragraphs', 'baseonly');
+ }
+
+ function connectTo($mode) {
+ $this->Lexer->addEntryPattern(
+ '\n\n[ ]{0,3}\d+\.[ \t]',
+ $mode,
+ 'plugin_markdowku_olists');
+
+ $this->Lexer->addPattern(
+ '\n^[ \t]*\d+\.[ \t]',
+ 'plugin_markdowku_olists');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern(
+ '(?:\Z|\n{1,}(?=\n\S)(?!\n[ \t]*\d+\.[ \t]))',
+ 'plugin_markdowku_olists');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ switch ($state) {
+ case DOKU_LEXER_ENTER:
+ $ReWriter = new Doku_Handler_Markdown_Ordered_List($handler->getCallWriter());
+ $handler->setCallWriter($ReWriter);
+ $handler->_addCall('list_open', array($match), $pos);
+ break;
+ case DOKU_LEXER_MATCHED:
+ $handler->_addCall('list_item', array($match), $pos);
+ break;
+ case DOKU_LEXER_UNMATCHED:
+ $handler->_addCall('cdata', array($match), $pos);
+ break;
+ case DOKU_LEXER_EXIT:
+ $handler->_addCall('list_close', array(), $pos);
+ $handler->getCallWriter()->process();
+ $ReWriter = & $handler->getCallWriter();
+ $handler->setCallWriter($ReWriter->getCallWriter());
+ break;
+ }
+ return true;
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ return true;
+ }
+}
+
+class Doku_Handler_Markdown_Ordered_List extends Lists {
+ private $depth = array(0, 4);
+
+ function interpretSyntax($match, &$type) {
+ $type="o";
+ $listlevel = 1;
+ $real_position = 0;
+ $logical_position = 0;
+ $text = preg_replace('/^\n*/', '', $match);
+
+ while (TRUE) {
+ if (preg_match('/^[ ]{'.$this->depth[$listlevel].'}/', substr($text, $real_position)) > 0) {
+ $real_position += $this->depth[$listlevel];
+ $logical_position += $this->depth[$listlevel];
+ $listlevel += 1;
+ continue;
+ }
+ if (preg_match('/^\t/', substr($text, $real_position)) > 0) {
+ $real_position += 1;
+ $logical_position += 4;
+ $listlevel += 1;
+ continue;
+ }
+ if (preg_match('/^[ ]{0,3}\d+\.[ \t]/', substr($text, $real_position)) > 0) {
+ $this->depth[$listlevel] = strlen(substr($text, $real_position)) - 1;
+ }
+ break;
+ }
+ return $listlevel;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/references.php b/platform/www/lib/plugins/markdowku/syntax/references.php
new file mode 100644
index 0000000..fe50a09
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/references.php
@@ -0,0 +1,41 @@
+<?php
+/*
+ * References for links or images, i.e.
+ * [id]: http://example.com
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+class syntax_plugin_markdowku_references extends DokuWiki_Syntax_Plugin {
+
+ function getType() { return 'substition'; }
+ function getPType() { return 'normal'; }
+ function getSort() { return 100; }
+
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern(
+ '\n[ ]{0,3}\[[^\n]+?\]:[ \t]*\n?[ \t]*<?\S+?>?[ \t]*\n?[ \t]*(?:(?<=\s)["(].+?[")][\t]*)?(?=\n)',
+ $mode,
+ 'plugin_markdowku_references');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array($state, $match);
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ if ($mode != 'metadata')
+ return false;
+
+ preg_match(
+ '/\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+)>?[ \t]*\n?[ \t]*(?:(?<=\s)["(](.+?)[")][\t]*)?/',
+ $data[1],
+ $matches);
+ $key = 'markdowku_references_'.preg_replace("/ /", ".", $matches[1]);
+ $renderer->meta[$key] = $matches[2];
+ return true;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/markdowku/syntax/ulists.php b/platform/www/lib/plugins/markdowku/syntax/ulists.php
new file mode 100644
index 0000000..79393c2
--- /dev/null
+++ b/platform/www/lib/plugins/markdowku/syntax/ulists.php
@@ -0,0 +1,99 @@
+<?php
+/*
+ * Unorderd lists:
+ * * ...
+ * * ...
+ */
+
+if(!defined('DOKU_INC')) die();
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+
+use dokuwiki\Parsing\Handler\Lists;
+
+class syntax_plugin_markdowku_ulists extends DokuWiki_Syntax_Plugin {
+ function getType() { return 'container'; }
+ function getPType() { return 'block'; }
+ function getSort() { return 9; }
+ function getAllowedTypes() {
+ return array('formatting', 'substition', 'paragraphs', 'baseonly', 'container');
+ }
+
+ function connectTo($mode) {
+ /* The negative lookahead is for not conflicting with hrs. */
+ $this->Lexer->addEntryPattern(
+ '\n\n[ ]{0,3}[*+-][ \t](?!(?:[ ]?[*+-][ ]?){2,}[ \t]*\n)',
+ $mode,
+ 'plugin_markdowku_ulists');
+
+ $this->Lexer->addPattern(
+ '\n[ \t]*[*+-][ \t](?!(?:[ ]?[*+-][ ]?){2,}[ \t]*\n)',
+ 'plugin_markdowku_ulists');
+ }
+
+ function postConnect() {
+ $this->Lexer->addExitPattern(
+ '(?:\Z|\n{1,}(?=\n\S)(?!\n[ \t]*[*+-][ \t]))',
+ 'plugin_markdowku_ulists');
+ }
+
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ switch ($state) {
+ case DOKU_LEXER_ENTER:
+ $ReWriter = new Doku_Handler_Markdown_Unordered_List($handler->getCallWriter());
+ $handler->setCallWriter($ReWriter);
+ $handler->_addCall('list_open', array($match), $pos);
+ break;
+ case DOKU_LEXER_MATCHED:
+ $handler->_addCall('list_item', array($match), $pos);
+ break;
+ case DOKU_LEXER_UNMATCHED:
+ $handler->_addCall('cdata', array($match), $pos);
+ break;
+ case DOKU_LEXER_EXIT:
+ $handler->_addCall('list_close', array(), $pos);
+ $handler->getCallWriter()->process();
+ $ReWriter = & $handler->getCallWriter();
+ $handler->setCallWriter($ReWriter->getCallWriter());
+ break;
+ }
+ return true;
+ }
+
+ function render($mode, Doku_Renderer $renderer, $data) {
+ return true;
+ }
+}
+
+class Doku_Handler_Markdown_Unordered_List extends Lists {
+ private $depth = array(0, 4);
+
+ function interpretSyntax($match, &$type) {
+ $type="u";
+ $listlevel = 1;
+ $real_position = 0;
+ $logical_position = 0;
+ $text = preg_replace('/^\n*/', '', $match);
+
+ while (TRUE) {
+ if (preg_match('/^[ ]{'.$this->depth[$listlevel].'}/', substr($text, $real_position)) > 0) {
+ $real_position += $this->depth[$listlevel];
+ $logical_position += $this->depth[$listlevel];
+ $listlevel += 1;
+ continue;
+ }
+ if (preg_match('/^\t/', substr($text, $real_position)) > 0) {
+ $real_position += 1;
+ $logical_position += 4;
+ $listlevel += 1;
+ continue;
+ }
+ if (preg_match('/^[ ]{0,3}[*+-][ \t]/', substr($text, $real_position)) > 0) {
+ $this->depth[$listlevel] = strlen(substr($text, $real_position)) - 1;
+ }
+ break;
+ }
+ return $listlevel + 1;
+ }
+}
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/master.zip b/platform/www/lib/plugins/master.zip
new file mode 100644
index 0000000..0c9a008
--- /dev/null
+++ b/platform/www/lib/plugins/master.zip
Binary files differ
diff --git a/platform/www/lib/plugins/popularity/action.php b/platform/www/lib/plugins/popularity/action.php
new file mode 100644
index 0000000..fac6107
--- /dev/null
+++ b/platform/www/lib/plugins/popularity/action.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Popularity Feedback Plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+class action_plugin_popularity extends DokuWiki_Action_Plugin
+{
+
+ /**
+ * @var helper_plugin_popularity
+ */
+ protected $helper;
+
+ public function __construct()
+ {
+ $this->helper = $this->loadHelper('popularity', false);
+ }
+
+ /** @inheritdoc */
+ public function register(Doku_Event_Handler $controller)
+ {
+ $controller->register_hook('INDEXER_TASKS_RUN', 'AFTER', $this, 'autosubmit', array());
+ }
+
+ /**
+ * Event handler
+ *
+ * @param Doku_Event $event
+ * @param $param
+ */
+ public function autosubmit(Doku_Event &$event, $param)
+ {
+ //Do we have to send the data now
+ if (!$this->helper->isAutosubmitEnabled() || $this->isTooEarlyToSubmit()) {
+ return;
+ }
+
+ //Actually send it
+ $status = $this->helper->sendData($this->helper->gatherAsString());
+
+ if ($status !== '') {
+ //If an error occured, log it
+ io_saveFile($this->helper->autosubmitErrorFile, $status);
+ } else {
+ //If the data has been sent successfully, previous log of errors are useless
+ @unlink($this->helper->autosubmitErrorFile);
+ //Update the last time we sent data
+ touch($this->helper->autosubmitFile);
+ }
+
+ $event->stopPropagation();
+ $event->preventDefault();
+ }
+
+ /**
+ * Check if it's time to send autosubmit data
+ * (we should have check if autosubmit is enabled first)
+ */
+ protected function isTooEarlyToSubmit()
+ {
+ $lastSubmit = $this->helper->lastSentTime();
+ return $lastSubmit + 24*60*60*30 > time();
+ }
+}
diff --git a/platform/www/lib/plugins/popularity/admin.php b/platform/www/lib/plugins/popularity/admin.php
new file mode 100644
index 0000000..61d8cc3
--- /dev/null
+++ b/platform/www/lib/plugins/popularity/admin.php
@@ -0,0 +1,157 @@
+<?php
+/**
+ * Popularity Feedback Plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class admin_plugin_popularity extends DokuWiki_Admin_Plugin
+{
+
+ /** @var helper_plugin_popularity */
+ protected $helper;
+ protected $sentStatus = null;
+
+ /**
+ * admin_plugin_popularity constructor.
+ */
+ public function __construct()
+ {
+ $this->helper = $this->loadHelper('popularity', false);
+ }
+
+ /**
+ * return prompt for admin menu
+ * @param $language
+ * @return string
+ */
+ public function getMenuText($language)
+ {
+ return $this->getLang('name');
+ }
+
+ /**
+ * return sort order for position in admin menu
+ */
+ public function getMenuSort()
+ {
+ return 2000;
+ }
+
+ /**
+ * Accessible for managers
+ */
+ public function forAdminOnly()
+ {
+ return false;
+ }
+
+
+ /**
+ * handle user request
+ */
+ public function handle()
+ {
+ global $INPUT;
+
+ //Send the data
+ if ($INPUT->has('data')) {
+ $this->sentStatus = $this->helper->sendData($INPUT->str('data'));
+ if ($this->sentStatus === '') {
+ //Update the last time we sent the data
+ touch($this->helper->popularityLastSubmitFile);
+ }
+ //Deal with the autosubmit option
+ $this->enableAutosubmit($INPUT->has('autosubmit'));
+ }
+ }
+
+ /**
+ * Enable or disable autosubmit
+ * @param bool $enable If TRUE, it will enable autosubmit. Else, it will disable it.
+ */
+ protected function enableAutosubmit($enable)
+ {
+ if ($enable) {
+ io_saveFile($this->helper->autosubmitFile, ' ');
+ } else {
+ @unlink($this->helper->autosubmitFile);
+ }
+ }
+
+ /**
+ * Output HTML form
+ */
+ public function html()
+ {
+ global $INPUT;
+
+ if (! $INPUT->has('data')) {
+ echo $this->locale_xhtml('intro');
+
+ //If there was an error the last time we tried to autosubmit, warn the user
+ if ($this->helper->isAutoSubmitEnabled()) {
+ if (file_exists($this->helper->autosubmitErrorFile)) {
+ echo $this->getLang('autosubmitError');
+ echo io_readFile($this->helper->autosubmitErrorFile);
+ }
+ }
+
+ flush();
+ echo $this->buildForm('server');
+
+ //Print the last time the data was sent
+ $lastSent = $this->helper->lastSentTime();
+ if ($lastSent !== 0) {
+ echo $this->getLang('lastSent') . ' ' . datetime_h($lastSent);
+ }
+ } else {
+ //If we just submitted the form
+ if ($this->sentStatus === '') {
+ //If we successfully sent the data
+ echo $this->locale_xhtml('submitted');
+ } else {
+ //If we failed to submit the data, try directly with the browser
+ echo $this->getLang('submissionFailed') . $this->sentStatus . '<br />';
+ echo $this->getLang('submitDirectly');
+ echo $this->buildForm('browser', $INPUT->str('data'));
+ }
+ }
+ }
+
+
+ /**
+ * Build the form which presents the data to be sent
+ * @param string $submissionMode How is the data supposed to be sent? (may be: 'browser' or 'server')
+ * @param string $data The popularity data, if it has already been computed. NULL otherwise.
+ * @return string The form, as an html string
+ */
+ protected function buildForm($submissionMode, $data = null)
+ {
+ $url = ($submissionMode === 'browser' ? $this->helper->submitUrl : script());
+ if (is_null($data)) {
+ $data = $this->helper->gatherAsString();
+ }
+
+ $form = '<form method="post" action="'. $url .'" accept-charset="utf-8">'
+ .'<fieldset style="width: 60%;">'
+ .'<textarea class="edit" rows="10" cols="80" readonly="readonly" name="data">'
+ .$data
+ .'</textarea><br />';
+
+ //If we submit via the server, we give the opportunity to suscribe to the autosubmission option
+ if ($submissionMode !== 'browser') {
+ $form .= '<label for="autosubmit">'
+ .'<input type="checkbox" name="autosubmit" id="autosubmit" '
+ .($this->helper->isAutosubmitEnabled() ? 'checked' : '' )
+ .'/> ' . $this->getLang('autosubmit') .'<br />'
+ .'</label>'
+ .'<input type="hidden" name="do" value="admin" />'
+ .'<input type="hidden" name="page" value="popularity" />';
+ }
+ $form .= '<button type="submit">'.$this->getLang('submit').'</button>'
+ .'</fieldset>'
+ .'</form>';
+ return $form;
+ }
+}
diff --git a/platform/www/lib/plugins/popularity/admin.svg b/platform/www/lib/plugins/popularity/admin.svg
new file mode 100644
index 0000000..820fc8c
--- /dev/null
+++ b/platform/www/lib/plugins/popularity/admin.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M2 21l21-9L2 3v7l15 2-15 2v7z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/plugins/popularity/helper.php b/platform/www/lib/plugins/popularity/helper.php
new file mode 100644
index 0000000..4537976
--- /dev/null
+++ b/platform/www/lib/plugins/popularity/helper.php
@@ -0,0 +1,292 @@
+<?php
+
+use dokuwiki\HTTP\DokuHTTPClient;
+use dokuwiki\Extension\Event;
+
+/**
+ * Popularity Feedback Plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+class helper_plugin_popularity extends Dokuwiki_Plugin
+{
+ /**
+ * The url where the data should be sent
+ */
+ public $submitUrl = 'http://update.dokuwiki.org/popularity.php';
+
+ /**
+ * Name of the file which determine if the the autosubmit is enabled,
+ * and when it was submited for the last time
+ */
+ public $autosubmitFile;
+
+ /**
+ * File where the last error which happened when we tried to autosubmit, will be log
+ */
+ public $autosubmitErrorFile;
+
+ /**
+ * Name of the file which determine when the popularity data was manually
+ * submitted for the last time
+ * (If this file doesn't exist, the data has never been sent)
+ */
+ public $popularityLastSubmitFile;
+
+ /**
+ * helper_plugin_popularity constructor.
+ */
+ public function __construct()
+ {
+ global $conf;
+ $this->autosubmitFile = $conf['cachedir'].'/autosubmit.txt';
+ $this->autosubmitErrorFile = $conf['cachedir'].'/autosubmitError.txt';
+ $this->popularityLastSubmitFile = $conf['cachedir'].'/lastSubmitTime.txt';
+ }
+
+ /**
+ * Check if autosubmit is enabled
+ *
+ * @return boolean TRUE if we should send data once a month, FALSE otherwise
+ */
+ public function isAutoSubmitEnabled()
+ {
+ return file_exists($this->autosubmitFile);
+ }
+
+ /**
+ * Send the data, to the submit url
+ *
+ * @param string $data The popularity data
+ * @return string An empty string if everything worked fine, a string describing the error otherwise
+ */
+ public function sendData($data)
+ {
+ $error = '';
+ $httpClient = new DokuHTTPClient();
+ $status = $httpClient->sendRequest($this->submitUrl, array('data' => $data), 'POST');
+ if (! $status) {
+ $error = $httpClient->error;
+ }
+ return $error;
+ }
+
+ /**
+ * Compute the last time the data was sent. If it has never been sent, we return 0.
+ *
+ * @return int
+ */
+ public function lastSentTime()
+ {
+ $manualSubmission = @filemtime($this->popularityLastSubmitFile);
+ $autoSubmission = @filemtime($this->autosubmitFile);
+
+ return max((int) $manualSubmission, (int) $autoSubmission);
+ }
+
+ /**
+ * Gather all information
+ *
+ * @return string The popularity data as a string
+ */
+ public function gatherAsString()
+ {
+ $data = $this->gather();
+ $string = '';
+ foreach ($data as $key => $val) {
+ if (is_array($val)) foreach ($val as $v) {
+ $string .= hsc($key)."\t".hsc($v)."\n";
+ } else {
+ $string .= hsc($key)."\t".hsc($val)."\n";
+ }
+ }
+ return $string;
+ }
+
+ /**
+ * Gather all information
+ *
+ * @return array The popularity data as an array
+ */
+ protected function gather()
+ {
+ global $conf;
+ /** @var $auth DokuWiki_Auth_Plugin */
+ global $auth;
+ $data = array();
+ $phptime = ini_get('max_execution_time');
+ @set_time_limit(0);
+ $pluginInfo = $this->getInfo();
+
+ // version
+ $data['anon_id'] = md5(auth_cookiesalt());
+ $data['version'] = getVersion();
+ $data['popversion'] = $pluginInfo['date'];
+ $data['language'] = $conf['lang'];
+ $data['now'] = time();
+ $data['popauto'] = (int) $this->isAutoSubmitEnabled();
+
+ // some config values
+ $data['conf_useacl'] = $conf['useacl'];
+ $data['conf_authtype'] = $conf['authtype'];
+ $data['conf_template'] = $conf['template'];
+
+ // number and size of pages
+ $list = array();
+ search($list, $conf['datadir'], array($this, 'searchCountCallback'), array('all'=>false), '');
+ $data['page_count'] = $list['file_count'];
+ $data['page_size'] = $list['file_size'];
+ $data['page_biggest'] = $list['file_max'];
+ $data['page_smallest'] = $list['file_min'];
+ $data['page_nscount'] = $list['dir_count'];
+ $data['page_nsnest'] = $list['dir_nest'];
+ if ($list['file_count']) $data['page_avg'] = $list['file_size'] / $list['file_count'];
+ $data['page_oldest'] = $list['file_oldest'];
+ unset($list);
+
+ // number and size of media
+ $list = array();
+ search($list, $conf['mediadir'], array($this, 'searchCountCallback'), array('all'=>true));
+ $data['media_count'] = $list['file_count'];
+ $data['media_size'] = $list['file_size'];
+ $data['media_biggest'] = $list['file_max'];
+ $data['media_smallest'] = $list['file_min'];
+ $data['media_nscount'] = $list['dir_count'];
+ $data['media_nsnest'] = $list['dir_nest'];
+ if ($list['file_count']) $data['media_avg'] = $list['file_size'] / $list['file_count'];
+ unset($list);
+
+ // number and size of cache
+ $list = array();
+ search($list, $conf['cachedir'], array($this, 'searchCountCallback'), array('all'=>true));
+ $data['cache_count'] = $list['file_count'];
+ $data['cache_size'] = $list['file_size'];
+ $data['cache_biggest'] = $list['file_max'];
+ $data['cache_smallest'] = $list['file_min'];
+ if ($list['file_count']) $data['cache_avg'] = $list['file_size'] / $list['file_count'];
+ unset($list);
+
+ // number and size of index
+ $list = array();
+ search($list, $conf['indexdir'], array($this, 'searchCountCallback'), array('all'=>true));
+ $data['index_count'] = $list['file_count'];
+ $data['index_size'] = $list['file_size'];
+ $data['index_biggest'] = $list['file_max'];
+ $data['index_smallest'] = $list['file_min'];
+ if ($list['file_count']) $data['index_avg'] = $list['file_size'] / $list['file_count'];
+ unset($list);
+
+ // number and size of meta
+ $list = array();
+ search($list, $conf['metadir'], array($this, 'searchCountCallback'), array('all'=>true));
+ $data['meta_count'] = $list['file_count'];
+ $data['meta_size'] = $list['file_size'];
+ $data['meta_biggest'] = $list['file_max'];
+ $data['meta_smallest'] = $list['file_min'];
+ if ($list['file_count']) $data['meta_avg'] = $list['file_size'] / $list['file_count'];
+ unset($list);
+
+ // number and size of attic
+ $list = array();
+ search($list, $conf['olddir'], array($this, 'searchCountCallback'), array('all'=>true));
+ $data['attic_count'] = $list['file_count'];
+ $data['attic_size'] = $list['file_size'];
+ $data['attic_biggest'] = $list['file_max'];
+ $data['attic_smallest'] = $list['file_min'];
+ if ($list['file_count']) $data['attic_avg'] = $list['file_size'] / $list['file_count'];
+ $data['attic_oldest'] = $list['file_oldest'];
+ unset($list);
+
+ // user count
+ if ($auth && $auth->canDo('getUserCount')) {
+ $data['user_count'] = $auth->getUserCount();
+ }
+
+ // calculate edits per day
+ $list = @file($conf['metadir'].'/_dokuwiki.changes');
+ $count = count($list);
+ if ($count > 2) {
+ $first = (int) substr(array_shift($list), 0, 10);
+ $last = (int) substr(array_pop($list), 0, 10);
+ $dur = ($last - $first)/(60*60*24); // number of days in the changelog
+ $data['edits_per_day'] = $count/$dur;
+ }
+ unset($list);
+
+ // plugins
+ $data['plugin'] = plugin_list();
+
+ // pcre info
+ if (defined('PCRE_VERSION')) $data['pcre_version'] = PCRE_VERSION;
+ $data['pcre_backtrack'] = ini_get('pcre.backtrack_limit');
+ $data['pcre_recursion'] = ini_get('pcre.recursion_limit');
+
+ // php info
+ $data['os'] = PHP_OS;
+ $data['webserver'] = $_SERVER['SERVER_SOFTWARE'];
+ $data['php_version'] = phpversion();
+ $data['php_sapi'] = php_sapi_name();
+ $data['php_memory'] = php_to_byte(ini_get('memory_limit'));
+ $data['php_exectime'] = $phptime;
+ $data['php_extension'] = get_loaded_extensions();
+
+ // plugin usage data
+ $this->addPluginUsageData($data);
+
+ return $data;
+ }
+
+ /**
+ * Triggers event to let plugins add their own data
+ *
+ * @param $data
+ */
+ protected function addPluginUsageData(&$data)
+ {
+ $pluginsData = array();
+ Event::createAndTrigger('PLUGIN_POPULARITY_DATA_SETUP', $pluginsData);
+ foreach ($pluginsData as $plugin => $d) {
+ if (is_array($d)) {
+ foreach ($d as $key => $value) {
+ $data['plugin_' . $plugin . '_' . $key] = $value;
+ }
+ } else {
+ $data['plugin_' . $plugin] = $d;
+ }
+ }
+ }
+
+ /**
+ * Callback to search and count the content of directories in DokuWiki
+ *
+ * @param array &$data Reference to the result data structure
+ * @param string $base Base usually $conf['datadir']
+ * @param string $file current file or directory relative to $base
+ * @param string $type Type either 'd' for directory or 'f' for file
+ * @param int $lvl Current recursion depht
+ * @param array $opts option array as given to search()
+ * @return bool
+ */
+ public function searchCountCallback(&$data, $base, $file, $type, $lvl, $opts)
+ {
+ // traverse
+ if ($type == 'd') {
+ if ($data['dir_nest'] < $lvl) $data['dir_nest'] = $lvl;
+ $data['dir_count']++;
+ return true;
+ }
+
+ //only search txt files if 'all' option not set
+ if ($opts['all'] || substr($file, -4) == '.txt') {
+ $size = filesize($base.'/'.$file);
+ $date = filemtime($base.'/'.$file);
+ $data['file_count']++;
+ $data['file_size'] += $size;
+ if (!isset($data['file_min']) || $data['file_min'] > $size) $data['file_min'] = $size;
+ if ($data['file_max'] < $size) $data['file_max'] = $size;
+ if (!isset($data['file_oldest']) || $data['file_oldest'] > $date) $data['file_oldest'] = $date;
+ }
+
+ return false;
+ }
+}
diff --git a/platform/www/lib/plugins/popularity/lang/en/intro.txt b/platform/www/lib/plugins/popularity/lang/en/intro.txt
new file mode 100644
index 0000000..e1d6d94
--- /dev/null
+++ b/platform/www/lib/plugins/popularity/lang/en/intro.txt
@@ -0,0 +1,11 @@
+====== Popularity Feedback ======
+
+This [[doku>popularity|tool]] gathers anonymous data about your wiki and allows you to send it back to the DokuWiki developers. This helps them to understand them how DokuWiki is used by its users and makes sure future development decisions are backed up by real world usage statistics.
+
+You are encouraged to repeat this step from time to time to keep developers informed when your wiki grows. Your repeated data sets will be identified by an anonymous ID.
+
+Data collected contains information like your DokuWiki version, the number and size of your pages and files, installed plugins and information about your PHP install.
+
+The raw data that will be send is shown below. Please use the "Send Data" button to transfer the information.
+
+
diff --git a/platform/www/lib/plugins/popularity/lang/en/lang.php b/platform/www/lib/plugins/popularity/lang/en/lang.php
new file mode 100644
index 0000000..af6797c
--- /dev/null
+++ b/platform/www/lib/plugins/popularity/lang/en/lang.php
@@ -0,0 +1,9 @@
+<?php
+
+$lang['name'] = 'Popularity Feedback (may take some time to load)';
+$lang['submit'] = 'Send Data';
+$lang['autosubmit'] = 'Automatically send data once a month';
+$lang['submissionFailed'] = 'The data couldn\'t be sent due to the following error:';
+$lang['submitDirectly'] = 'You can send the data manually by submitting the following form.';
+$lang['autosubmitError'] = 'The last autosubmit failed, because of the following error: ';
+$lang['lastSent'] = 'The data has been sent';
diff --git a/platform/www/lib/plugins/popularity/lang/en/submitted.txt b/platform/www/lib/plugins/popularity/lang/en/submitted.txt
new file mode 100644
index 0000000..30f2784
--- /dev/null
+++ b/platform/www/lib/plugins/popularity/lang/en/submitted.txt
@@ -0,0 +1,3 @@
+====== Popularity Feedback ======
+
+The data has been sent succesfully.
diff --git a/platform/www/lib/plugins/popularity/plugin.info.txt b/platform/www/lib/plugins/popularity/plugin.info.txt
new file mode 100644
index 0000000..8ffc136
--- /dev/null
+++ b/platform/www/lib/plugins/popularity/plugin.info.txt
@@ -0,0 +1,7 @@
+base popularity
+author Andreas Gohr
+email andi@splitbrain.org
+date 2015-07-15
+name Popularity Feedback Plugin
+desc Send anonymous data about your wiki to the DokuWiki developers
+url http://www.dokuwiki.org/plugin:popularity
diff --git a/platform/www/lib/plugins/remote.php b/platform/www/lib/plugins/remote.php
new file mode 100644
index 0000000..a3cbec7
--- /dev/null
+++ b/platform/www/lib/plugins/remote.php
@@ -0,0 +1,2 @@
+<?php
+dbg_deprecated('Autoloading. Do not require() files yourself.');
diff --git a/platform/www/lib/plugins/revert/admin.php b/platform/www/lib/plugins/revert/admin.php
new file mode 100644
index 0000000..2d11dc0
--- /dev/null
+++ b/platform/www/lib/plugins/revert/admin.php
@@ -0,0 +1,193 @@
+<?php
+
+use dokuwiki\ChangeLog\PageChangeLog;
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_revert extends DokuWiki_Admin_Plugin
+{
+ protected $cmd;
+ // some vars which might need tuning later
+ protected $max_lines = 800; // lines to read from changelog
+ protected $max_revs = 20; // numer of old revisions to check
+
+
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ $this->setupLocale();
+ }
+
+ /**
+ * access for managers
+ */
+ public function forAdminOnly()
+ {
+ return false;
+ }
+
+ /**
+ * return sort order for position in admin menu
+ */
+ public function getMenuSort()
+ {
+ return 40;
+ }
+
+ /**
+ * handle user request
+ */
+ public function handle()
+ {
+ }
+
+ /**
+ * output appropriate html
+ */
+ public function html()
+ {
+ global $INPUT;
+
+ echo $this->locale_xhtml('intro');
+
+ $this->printSearchForm();
+
+ if (is_array($INPUT->param('revert')) && checkSecurityToken()) {
+ $this->revertEdits($INPUT->arr('revert'), $INPUT->str('filter'));
+ } elseif ($INPUT->has('filter')) {
+ $this->listEdits($INPUT->str('filter'));
+ }
+ }
+
+ /**
+ * Display the form for searching spam pages
+ */
+ protected function printSearchForm()
+ {
+ global $lang, $INPUT;
+ echo '<form action="" method="post"><div class="no">';
+ echo '<label>'.$this->getLang('filter').': </label>';
+ echo '<input type="text" name="filter" class="edit" value="'.hsc($INPUT->str('filter')).'" /> ';
+ echo '<button type="submit">'.$lang['btn_search'].'</button> ';
+ echo '<span>'.$this->getLang('note1').'</span>';
+ echo '</div></form><br /><br />';
+ }
+
+ /**
+ * Start the reversion process
+ */
+ protected function revertEdits($revert, $filter)
+ {
+ echo '<hr /><br />';
+ echo '<p>'.$this->getLang('revstart').'</p>';
+
+ echo '<ul>';
+ foreach ($revert as $id) {
+ global $REV;
+
+ // find the last non-spammy revision
+ $data = '';
+ $pagelog = new PageChangeLog($id);
+ $old = $pagelog->getRevisions(0, $this->max_revs);
+ if (count($old)) {
+ foreach ($old as $REV) {
+ $data = rawWiki($id, $REV);
+ if (strpos($data, $filter) === false) break;
+ }
+ }
+
+ if ($data) {
+ saveWikiText($id, $data, 'old revision restored', false);
+ printf('<li><div class="li">'.$this->getLang('reverted').'</div></li>', $id, $REV);
+ } else {
+ saveWikiText($id, '', '', false);
+ printf('<li><div class="li">'.$this->getLang('removed').'</div></li>', $id);
+ }
+ @set_time_limit(10);
+ flush();
+ }
+ echo '</ul>';
+
+ echo '<p>'.$this->getLang('revstop').'</p>';
+ }
+
+ /**
+ * List recent edits matching the given filter
+ */
+ protected function listEdits($filter)
+ {
+ global $conf;
+ global $lang;
+ echo '<hr /><br />';
+ echo '<form action="" method="post"><div class="no">';
+ echo '<input type="hidden" name="filter" value="'.hsc($filter).'" />';
+ formSecurityToken();
+
+ $recents = getRecents(0, $this->max_lines);
+ echo '<ul>';
+
+ $cnt = 0;
+ foreach ($recents as $recent) {
+ if ($filter) {
+ if (strpos(rawWiki($recent['id']), $filter) === false) continue;
+ }
+
+ $cnt++;
+ $date = dformat($recent['date']);
+
+ echo ($recent['type']===DOKU_CHANGE_TYPE_MINOR_EDIT) ? '<li class="minor">' : '<li>';
+ echo '<div class="li">';
+ echo '<input type="checkbox" name="revert[]" value="'.hsc($recent['id']).
+ '" checked="checked" id="revert__'.$cnt.'" />';
+ echo ' <label for="revert__'.$cnt.'">'.$date.'</label> ';
+
+ echo '<a href="'.wl($recent['id'], "do=diff").'">';
+ $p = array();
+ $p['src'] = DOKU_BASE.'lib/images/diff.png';
+ $p['width'] = 15;
+ $p['height'] = 11;
+ $p['title'] = $lang['diff'];
+ $p['alt'] = $lang['diff'];
+ $att = buildAttributes($p);
+ echo "<img $att />";
+ echo '</a> ';
+
+ echo '<a href="'.wl($recent['id'], "do=revisions").'">';
+ $p = array();
+ $p['src'] = DOKU_BASE.'lib/images/history.png';
+ $p['width'] = 12;
+ $p['height'] = 14;
+ $p['title'] = $lang['btn_revs'];
+ $p['alt'] = $lang['btn_revs'];
+ $att = buildAttributes($p);
+ echo "<img $att />";
+ echo '</a> ';
+
+ echo html_wikilink(':'.$recent['id'], (useHeading('navigation'))?null:$recent['id']);
+ echo ' – '.htmlspecialchars($recent['sum']);
+
+ echo ' <span class="user">';
+ echo $recent['user'].' '.$recent['ip'];
+ echo '</span>';
+
+ echo '</div>';
+ echo '</li>';
+
+ @set_time_limit(10);
+ flush();
+ }
+ echo '</ul>';
+
+ echo '<p>';
+ echo '<button type="submit">'.$this->getLang('revert').'</button> ';
+ printf($this->getLang('note2'), hsc($filter));
+ echo '</p>';
+
+ echo '</div></form>';
+ }
+}
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/revert/admin.svg b/platform/www/lib/plugins/revert/admin.svg
new file mode 100644
index 0000000..2129d2d
--- /dev/null
+++ b/platform/www/lib/plugins/revert/admin.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M13.5 7a6.5 6.5 0 0 1 6.5 6.5 6.5 6.5 0 0 1-6.5 6.5H10v-2h3.5c2.5 0 4.5-2 4.5-4.5S16 9 13.5 9H7.83l3.08 3.09L9.5 13.5 4 8l5.5-5.5 1.42 1.41L7.83 7h5.67M6 18h2v2H6v-2z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/plugins/revert/lang/en/intro.txt b/platform/www/lib/plugins/revert/lang/en/intro.txt
new file mode 100644
index 0000000..b8f3558
--- /dev/null
+++ b/platform/www/lib/plugins/revert/lang/en/intro.txt
@@ -0,0 +1,3 @@
+====== Revert Manager ======
+
+This page helps you with the automatic reversion of a spam attack. To find a list of spammy pages first enter a search string (eg. a spam URL), then confirm that the found pages are really spam and revert the edits.
diff --git a/platform/www/lib/plugins/revert/lang/en/lang.php b/platform/www/lib/plugins/revert/lang/en/lang.php
new file mode 100644
index 0000000..6bf867d
--- /dev/null
+++ b/platform/www/lib/plugins/revert/lang/en/lang.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ * english language file
+ */
+
+// for admin plugins, the menu prompt to be displayed in the admin menu
+// if set here, the plugin doesn't need to override the getMenuText() method
+$lang['menu'] = 'Revert Manager';
+
+// custom language strings for the plugin
+
+$lang['filter'] = 'Search spammy pages';
+$lang['revert'] = 'Revert selected pages';
+$lang['reverted'] = '%s reverted to revision %s';
+$lang['removed'] = '%s removed';
+$lang['revstart'] = 'Reversion process started. This can take a long time. If the
+ script times out before finishing, you need to revert in smaller
+ chunks.';
+$lang['revstop'] = 'Reversion process finished successfully.';
+$lang['note1'] = 'Note: this search is case sensitive';
+$lang['note2'] = 'Note: the page will be reverted to the last version not containing the given spam term <i>%s</i>.';
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/revert/plugin.info.txt b/platform/www/lib/plugins/revert/plugin.info.txt
new file mode 100644
index 0000000..bba939d
--- /dev/null
+++ b/platform/www/lib/plugins/revert/plugin.info.txt
@@ -0,0 +1,7 @@
+base revert
+author Andreas Gohr
+email andi@splitbrain.org
+date 2015-07-15
+name Revert Manager
+desc Allows you to mass revert recent edits to remove Spam or vandalism
+url http://dokuwiki.org/plugin:revert
diff --git a/platform/www/lib/plugins/safefnrecode/action.php b/platform/www/lib/plugins/safefnrecode/action.php
new file mode 100644
index 0000000..952d95c
--- /dev/null
+++ b/platform/www/lib/plugins/safefnrecode/action.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * DokuWiki Plugin safefnrecode (Action Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+class action_plugin_safefnrecode extends DokuWiki_Action_Plugin
+{
+
+ /** @inheritdoc */
+ public function register(Doku_Event_Handler $controller)
+ {
+ $controller->register_hook('INDEXER_TASKS_RUN', 'BEFORE', $this, 'handleIndexerTasksRun');
+ }
+
+ /**
+ * Handle indexer event
+ *
+ * @param Doku_Event $event
+ * @param $param
+ */
+ public function handleIndexerTasksRun(Doku_Event $event, $param)
+ {
+ global $conf;
+ if ($conf['fnencode'] != 'safe') return;
+
+ if (!file_exists($conf['datadir'].'_safefn.recoded')) {
+ $this->recode($conf['datadir']);
+ touch($conf['datadir'].'_safefn.recoded');
+ }
+
+ if (!file_exists($conf['olddir'].'_safefn.recoded')) {
+ $this->recode($conf['olddir']);
+ touch($conf['olddir'].'_safefn.recoded');
+ }
+
+ if (!file_exists($conf['metadir'].'_safefn.recoded')) {
+ $this->recode($conf['metadir']);
+ touch($conf['metadir'].'_safefn.recoded');
+ }
+
+ if (!file_exists($conf['mediadir'].'_safefn.recoded')) {
+ $this->recode($conf['mediadir']);
+ touch($conf['mediadir'].'_safefn.recoded');
+ }
+ }
+
+ /**
+ * Recursive function to rename all safe encoded files to use the new
+ * square bracket post indicator
+ */
+ private function recode($dir)
+ {
+ $dh = opendir($dir);
+ if (!$dh) return;
+ while (($file = readdir($dh)) !== false) {
+ if ($file == '.' || $file == '..') continue; # cur and upper dir
+ if (is_dir("$dir/$file")) $this->recode("$dir/$file"); #recurse
+ if (strpos($file, '%') === false) continue; # no encoding used
+ $new = preg_replace('/(%[^\]]*?)\./', '\1]', $file); # new post indicator
+ if (preg_match('/%[^\]]+$/', $new)) $new .= ']'; # fix end FS#2122
+ rename("$dir/$file", "$dir/$new"); # rename it
+ }
+ closedir($dh);
+ }
+}
diff --git a/platform/www/lib/plugins/safefnrecode/plugin.info.txt b/platform/www/lib/plugins/safefnrecode/plugin.info.txt
new file mode 100644
index 0000000..3c6249d
--- /dev/null
+++ b/platform/www/lib/plugins/safefnrecode/plugin.info.txt
@@ -0,0 +1,7 @@
+base safefnrecode
+author Andreas Gohr
+email andi@splitbrain.org
+date 2012-07-28
+name safefnrecode plugin
+desc Changes existing page and foldernames for the change in the safe filename encoding
+url http://www.dokuwiki.org/plugin:safefnrecode
diff --git a/platform/www/lib/plugins/styling/README b/platform/www/lib/plugins/styling/README
new file mode 100644
index 0000000..a1a5e89
--- /dev/null
+++ b/platform/www/lib/plugins/styling/README
@@ -0,0 +1,27 @@
+styling Plugin for DokuWiki
+
+Allows to edit style.ini replacements
+
+All documentation for this plugin can be found at
+https://www.dokuwiki.org/plugin:styling
+
+If you install this plugin manually, make sure it is installed in
+lib/plugins/styling/ - if the folder is called different it
+will not work!
+
+Please refer to http://www.dokuwiki.org/plugins for additional info
+on how to install plugins in DokuWiki.
+
+----
+Copyright (C) Andreas Gohr <andi@splitbrain.org>
+
+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; version 2 of the License
+
+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.
+
+See the COPYING file in your DokuWiki folder for details
diff --git a/platform/www/lib/plugins/styling/action.php b/platform/www/lib/plugins/styling/action.php
new file mode 100644
index 0000000..46245ca
--- /dev/null
+++ b/platform/www/lib/plugins/styling/action.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * DokuWiki Plugin styling (Action Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class action_plugin_styling extends DokuWiki_Action_Plugin
+{
+
+ /**
+ * Registers a callback functions
+ *
+ * @param Doku_Event_Handler $controller DokuWiki's event controller object
+ * @return void
+ */
+ public function register(Doku_Event_Handler $controller)
+ {
+ $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleHeader');
+ }
+
+ /**
+ * Adds the preview parameter to the stylesheet loading in non-js mode
+ *
+ * @param Doku_Event $event event object by reference
+ * @param mixed $param [the parameters passed as fifth argument to register_hook() when this
+ * handler was registered]
+ * @return void
+ */
+ public function handleHeader(Doku_Event &$event, $param)
+ {
+ global $ACT;
+ global $INPUT;
+ if ($ACT != 'admin' || $INPUT->str('page') != 'styling') return;
+ /** @var admin_plugin_styling $admin */
+ $admin = plugin_load('admin', 'styling');
+ if (!$admin->isAccessibleByCurrentUser()) return;
+
+ // set preview
+ $len = count($event->data['link']);
+ for ($i = 0; $i < $len; $i++) {
+ if ($event->data['link'][$i]['rel'] == 'stylesheet' &&
+ strpos($event->data['link'][$i]['href'], 'lib/exe/css.php') !== false
+ ) {
+ $event->data['link'][$i]['href'] .= '&preview=1&tseed='.time();
+ }
+ }
+ }
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/styling/admin.php b/platform/www/lib/plugins/styling/admin.php
new file mode 100644
index 0000000..d454422
--- /dev/null
+++ b/platform/www/lib/plugins/styling/admin.php
@@ -0,0 +1,224 @@
+<?php
+/**
+ * DokuWiki Plugin styling (Admin Component)
+ *
+ * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+class admin_plugin_styling extends DokuWiki_Admin_Plugin
+{
+
+ public $ispopup = false;
+
+ /**
+ * @return int sort number in admin menu
+ */
+ public function getMenuSort()
+ {
+ return 1000;
+ }
+
+ /**
+ * @return bool true if only access for superuser, false is for superusers and moderators
+ */
+ public function forAdminOnly()
+ {
+ return true;
+ }
+
+ /**
+ * handle the different actions (also called from ajax)
+ */
+ public function handle()
+ {
+ global $INPUT;
+ $run = $INPUT->extract('run')->str('run');
+ if (!$run) return;
+ $run = 'run'.ucfirst($run);
+ $this->$run();
+ }
+
+ /**
+ * Render HTML output, e.g. helpful text and a form
+ */
+ public function html()
+ {
+ $class = 'nopopup';
+ if ($this->ispopup) $class = 'ispopup page';
+
+ echo '<div id="plugin__styling" class="'.$class.'">';
+ ptln('<h1>'.$this->getLang('menu').'</h1>');
+ $this->form();
+ echo '</div>';
+ }
+
+ /**
+ * Create the actual editing form
+ */
+ public function form()
+ {
+ global $conf;
+ global $ID;
+
+ $styleUtil = new \dokuwiki\StyleUtils($conf['template'], true, true);
+ $styleini = $styleUtil->cssStyleini();
+ $replacements = $styleini['replacements'];
+
+ if ($this->ispopup) {
+ $target = DOKU_BASE.'lib/plugins/styling/popup.php';
+ } else {
+ $target = wl($ID, array('do' => 'admin', 'page' => 'styling'));
+ }
+
+ if (empty($replacements)) {
+ echo '<p class="error">'.$this->getLang('error').'</p>';
+ } else {
+ echo $this->locale_xhtml('intro');
+
+ echo '<form class="styling" method="post" action="'.$target.'">';
+
+ echo '<table><tbody>';
+ foreach ($replacements as $key => $value) {
+ $name = tpl_getLang($key);
+ if (empty($name)) $name = $this->getLang($key);
+ if (empty($name)) $name = $key;
+
+ echo '<tr>';
+ echo '<td><label for="tpl__'.hsc($key).'">'.$name.'</label></td>';
+ echo '<td><input type="'.$this->colorType($value).'" name="tpl['.hsc($key).']" id="tpl__'.hsc($key).'"
+ value="'.hsc($this->colorValue($value)).'" dir="ltr" /></td>';
+ echo '</tr>';
+ }
+ echo '</tbody></table>';
+
+ echo '<p>';
+ echo '<button type="submit" name="run[preview]" class="btn_preview primary">'.
+ $this->getLang('btn_preview').'</button> ';
+ #FIXME only if preview.ini exists:
+ echo '<button type="submit" name="run[reset]">'.$this->getLang('btn_reset').'</button>';
+ echo '</p>';
+
+ echo '<p>';
+ echo '<button type="submit" name="run[save]" class="primary">'.$this->getLang('btn_save').'</button>';
+ echo '</p>';
+
+ echo '<p>';
+ #FIXME only if local.ini exists:
+ echo '<button type="submit" name="run[revert]">'.$this->getLang('btn_revert').'</button>';
+ echo '</p>';
+
+ echo '</form>';
+
+ echo tpl_locale_xhtml('style');
+ }
+ }
+
+ /**
+ * Adjust three char color codes to the 6 char one supported by browser's color input
+ *
+ * @param string $value
+ * @return string
+ */
+ protected function colorValue($value)
+ {
+ if (preg_match('/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/', $value, $match)) {
+ return '#' . $match[1] . $match[1] . $match[2] . $match[2] . $match[3] . $match[3];
+ }
+ return $value;
+ }
+
+ /**
+ * Decide the input type based on the value
+ *
+ * @param string $value
+ * @return string color|text
+ */
+ protected function colorType($value)
+ {
+ if (preg_match('/^#([0-9a-fA-F]{3}){1,2}$/', $value)) {
+ return 'color';
+ } else {
+ return 'text';
+ }
+ }
+
+ /**
+ * saves the preview.ini (alos called from ajax directly)
+ */
+ public function runPreview()
+ {
+ global $conf;
+ $ini = $conf['cachedir'].'/preview.ini';
+ io_saveFile($ini, $this->makeini());
+ }
+
+ /**
+ * deletes the preview.ini
+ */
+ protected function runReset()
+ {
+ global $conf;
+ $ini = $conf['cachedir'].'/preview.ini';
+ io_saveFile($ini, '');
+ }
+
+ /**
+ * deletes the local style.ini replacements
+ */
+ protected function runRevert()
+ {
+ $this->replaceIni('');
+ $this->runReset();
+ }
+
+ /**
+ * save the local style.ini replacements
+ */
+ protected function runSave()
+ {
+ $this->replaceIni($this->makeini());
+ $this->runReset();
+ }
+
+ /**
+ * create the replacement part of a style.ini from submitted data
+ *
+ * @return string
+ */
+ protected function makeini()
+ {
+ global $INPUT;
+
+ $ini = "[replacements]\n";
+ $ini .= ";These overwrites have been generated from the Template styling Admin interface\n";
+ $ini .= ";Any values in this section will be overwritten by that tool again\n";
+ foreach ($INPUT->arr('tpl') as $key => $val) {
+ $ini .= $key.' = "'.addslashes($val).'"'."\n";
+ }
+
+ return $ini;
+ }
+
+ /**
+ * replaces the replacement parts in the local ini
+ *
+ * @param string $new the new ini contents
+ */
+ protected function replaceIni($new)
+ {
+ global $conf;
+ $ini = DOKU_CONF."tpl/".$conf['template']."/style.ini";
+ if (file_exists($ini)) {
+ $old = io_readFile($ini);
+ $old = preg_replace('/\[replacements\]\n.*?(\n\[.*]|$)/s', '\\1', $old);
+ $old = trim($old);
+ } else {
+ $old = '';
+ }
+
+ io_makeFileDir($ini);
+ io_saveFile($ini, "$old\n\n$new");
+ }
+}
+
+// vim:ts=4:sw=4:et:
diff --git a/platform/www/lib/plugins/styling/admin.svg b/platform/www/lib/plugins/styling/admin.svg
new file mode 100644
index 0000000..5d73870
--- /dev/null
+++ b/platform/www/lib/plugins/styling/admin.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M17.5 12a1.5 1.5 0 0 1-1.5-1.5A1.5 1.5 0 0 1 17.5 9a1.5 1.5 0 0 1 1.5 1.5 1.5 1.5 0 0 1-1.5 1.5m-3-4A1.5 1.5 0 0 1 13 6.5 1.5 1.5 0 0 1 14.5 5 1.5 1.5 0 0 1 16 6.5 1.5 1.5 0 0 1 14.5 8m-5 0A1.5 1.5 0 0 1 8 6.5 1.5 1.5 0 0 1 9.5 5 1.5 1.5 0 0 1 11 6.5 1.5 1.5 0 0 1 9.5 8m-3 4A1.5 1.5 0 0 1 5 10.5 1.5 1.5 0 0 1 6.5 9 1.5 1.5 0 0 1 8 10.5 1.5 1.5 0 0 1 6.5 12M12 3a9 9 0 0 0-9 9 9 9 0 0 0 9 9 1.5 1.5 0 0 0 1.5-1.5c0-.39-.15-.74-.39-1-.23-.27-.38-.62-.38-1a1.5 1.5 0 0 1 1.5-1.5H16a5 5 0 0 0 5-5c0-4.42-4.03-8-9-8z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/plugins/styling/lang/en/intro.txt b/platform/www/lib/plugins/styling/lang/en/intro.txt
new file mode 100644
index 0000000..4ea5517
--- /dev/null
+++ b/platform/www/lib/plugins/styling/lang/en/intro.txt
@@ -0,0 +1,2 @@
+This tool allows you to change certain style settings of your currently selected template.
+All changes are stored in a local configuration file and are upgrade safe. \ No newline at end of file
diff --git a/platform/www/lib/plugins/styling/lang/en/lang.php b/platform/www/lib/plugins/styling/lang/en/lang.php
new file mode 100644
index 0000000..e0011eb
--- /dev/null
+++ b/platform/www/lib/plugins/styling/lang/en/lang.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * English language file for styling plugin
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// menu entry for admin plugins
+$lang['menu'] = 'Template Style Settings';
+
+$lang['js']['loader'] = 'Preview is loading...<br />if this does not goes away, your values may be faulty';
+$lang['js']['popup'] = 'Open as a popup';
+
+// custom language strings for the plugin
+$lang['error'] = 'Sorry, this template does not support this functionality.';
+
+$lang['btn_preview'] = 'Preview changes';
+$lang['btn_save'] = 'Save changes';
+$lang['btn_reset'] = 'Reset current changes';
+$lang['btn_revert'] = 'Revert styles back to template\'s default';
+
+// default guaranteed placeholders
+$lang['__text__'] = 'Main text color';
+$lang['__background__'] = 'Main background color';
+$lang['__text_alt__'] = 'Alternative text color';
+$lang['__background_alt__'] = 'Alternative background color';
+$lang['__text_neu__'] = 'Neutral text color';
+$lang['__background_neu__'] = 'Neutral background color';
+$lang['__border__'] = 'Border color';
+$lang['__highlight__'] = 'Highlight color (for search results mainly)';
+
+
+
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/styling/plugin.info.txt b/platform/www/lib/plugins/styling/plugin.info.txt
new file mode 100644
index 0000000..e374eaf
--- /dev/null
+++ b/platform/www/lib/plugins/styling/plugin.info.txt
@@ -0,0 +1,7 @@
+base styling
+author Andreas Gohr
+email andi@splitbrain.org
+date 2020-06-14
+name styling plugin
+desc Allows to edit style.ini replacements
+url https://www.dokuwiki.org/plugin:styling
diff --git a/platform/www/lib/plugins/styling/popup.php b/platform/www/lib/plugins/styling/popup.php
new file mode 100644
index 0000000..079062e
--- /dev/null
+++ b/platform/www/lib/plugins/styling/popup.php
@@ -0,0 +1,31 @@
+<?php
+// phpcs:disable PSR1.Files.SideEffects
+if (!defined('DOKU_INC')) define('DOKU_INC', dirname(__FILE__) . '/../../../');
+require_once(DOKU_INC . 'inc/init.php');
+//close session
+session_write_close();
+header('Content-Type: text/html; charset=utf-8');
+header('X-UA-Compatible: IE=edge,chrome=1');
+
+/** @var admin_plugin_styling $plugin */
+$plugin = plugin_load('admin', 'styling');
+if (!$plugin->isAccessibleByCurrentUser()) die('only admins allowed');
+$plugin->ispopup = true;
+
+// handle posts
+$plugin->handle();
+
+// output plugin in a very minimal template:
+?><!DOCTYPE html>
+<html lang="<?php echo $conf['lang'] ?>" dir="<?php echo $lang['direction'] ?>">
+<head>
+ <meta charset="utf-8" />
+ <title><?php echo $plugin->getLang('menu') ?></title>
+ <?php tpl_metaheaders(false) ?>
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
+ <?php echo tpl_favicon(array('favicon')) ?>
+</head>
+<body class="dokuwiki">
+ <?php $plugin->html() ?>
+</body>
+</html>
diff --git a/platform/www/lib/plugins/styling/script.js b/platform/www/lib/plugins/styling/script.js
new file mode 100644
index 0000000..7fa8b25
--- /dev/null
+++ b/platform/www/lib/plugins/styling/script.js
@@ -0,0 +1,92 @@
+jQuery(function () {
+
+ /**
+ * Function to reload the preview styles in the main window
+ *
+ * @param {Window} target the main window
+ */
+ function applyPreview(target) {
+ // remove style
+ var $style = target.jQuery('link[rel=stylesheet][href*="lib/exe/css.php"]');
+ $style.attr('href', '');
+
+ // append the loader screen
+ var $loader = target.jQuery('#plugin__styling_loader');
+ if (!$loader.length) {
+ $loader = target.jQuery('<div id="plugin__styling_loader">' + LANG.plugins.styling.loader + '</div>');
+ $loader.css({
+ 'position': 'absolute',
+ 'width': '100%',
+ 'height': '100%',
+ 'top': 0,
+ 'left': 0,
+ 'z-index': 5000,
+ 'background-color': '#fff',
+ 'opacity': '0.7',
+ 'color': '#000',
+ 'font-size': '2.5em',
+ 'text-align': 'center',
+ 'line-height': 1.5,
+ 'padding-top': '2em'
+ });
+ target.jQuery('body').append($loader);
+ }
+
+ // load preview in main window (timeout works around chrome updating CSS weirdness)
+ setTimeout(function () {
+ var now = new Date().getTime();
+ $style.attr('href', DOKU_BASE + 'lib/exe/css.php?preview=1&tseed=' + now);
+ }, 500);
+ }
+
+ var doreload = 1;
+ var $styling_plugin = jQuery('#plugin__styling');
+
+ // if we are not on the plugin page (either main or popup)
+ if (!$styling_plugin.length) {
+ // handle the preview cookie
+ if(DokuCookie.getValue('styling_plugin') == 1) {
+ applyPreview(window);
+ }
+ return; // nothing more to do here
+ }
+
+ /* ---- from here on we're in the popup or admin page ---- */
+
+ // add button on main page
+ if (!$styling_plugin.hasClass('ispopup')) {
+ var $form = $styling_plugin.find('form.styling').first();
+ var $btn = jQuery('<button>' + LANG.plugins.styling.popup + '</button>');
+ $form.prepend($btn);
+
+ $btn.on('click', function (e) {
+ var windowFeatures = "menubar=no,location=no,resizable=yes,scrollbars=yes,status=false,width=500,height=500";
+ window.open(DOKU_BASE + 'lib/plugins/styling/popup.php', 'styling_popup', windowFeatures);
+ e.preventDefault();
+ e.stopPropagation();
+ }).wrap('<p></p>');
+ return; // we exit here if this is not the popup
+ }
+
+ /* ---- from here on we're in the popup only ---- */
+
+ // reload the main page on close
+ window.onunload = function(e) {
+ if(doreload) {
+ DokuCookie.setValue('styling_plugin', 0);
+ if(window.opener) window.opener.document.location.reload();
+ }
+ return null;
+ };
+
+ // don't reload on our own buttons
+ jQuery(':button').click(function(e){
+ doreload = false;
+ });
+
+ // on first load apply preview
+ if(window.opener) applyPreview(window.opener);
+
+ // enable the preview cookie
+ DokuCookie.setValue('styling_plugin', 1);
+});
diff --git a/platform/www/lib/plugins/styling/style.less b/platform/www/lib/plugins/styling/style.less
new file mode 100644
index 0000000..be0e16a
--- /dev/null
+++ b/platform/www/lib/plugins/styling/style.less
@@ -0,0 +1,13 @@
+#plugin__styling {
+ button.primary {
+ font-weight: bold;
+ }
+
+ [dir=rtl] & table input {
+ text-align: right;
+ }
+}
+
+#plugin__styling_loader {
+ display: none;
+}
diff --git a/platform/www/lib/plugins/syntax.php b/platform/www/lib/plugins/syntax.php
new file mode 100644
index 0000000..a3cbec7
--- /dev/null
+++ b/platform/www/lib/plugins/syntax.php
@@ -0,0 +1,2 @@
+<?php
+dbg_deprecated('Autoloading. Do not require() files yourself.');
diff --git a/platform/www/lib/plugins/textinsert/README b/platform/www/lib/plugins/textinsert/README
new file mode 100644
index 0000000..ed0c173
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/README
@@ -0,0 +1,55 @@
+This is a macro substitution plugin which enables substitutions of both words and longer
+strings of text.
+
+Basic Syntax: #@Macro_Name@#
+
+It provides an administrative panel which makes for simple adding, editing and deletion
+of macros.
+
+Much of the functionality of this plugin can be more easily implemented with Dokuwiki's
+own entities facility: http://www.dokuwiki.org/entities. The advantage of TextInsert
+comes when dealing with extended blocks of text and with its ability to include other
+macros inside the primary macro definition. That is, it can accept:
+
+MACRO_1 This macro can include #@MACR0_2@# inside it.
+MACRO_2 a second macro
+
+The result is:
+ This macro can include a second macro inside it.
+
+It accepts only one level of macro inclusion, so that if MACRO_3 were included in
+MACRO_2, MACRO_3 would not be rendered.
+
+The macro definitions will also accept entities defined dokuwiki's conf/entities.conf and
+user-defined entities conf/entities.local.conf. Entities will be replaced in both the
+primary and the included macros.
+
+HTML Support
+#Macro_HTML@#
+A macro name with the _HTML suffix will be output as HTML, whereas without the _HTML suffix the
+HTML markup will be treated as literals. With it, <p> creates a paragraph; wthout it the <p>
+markup is printed to the screen.
+
+Translation Support
+#@LANG_name@#
+If a macro has this format, textinsert checks the file's namespace for a language specified
+as an ISO abbreviation, for instance nl for Dutch or de for German -- as in de:my_file. If it finds
+a language specification, it will check the textinsert/lang directory for either macros.php or a lang.php
+file in the relevant language directory, for instance lang/de/lang.php. It will then look for a
+$lang['name'] entry in lang.php or a $lang_<iso>['name'] entry in macros.php, and if
+it finds one, it will substitute this for the macro. Otherwise, it will substitute the entry for
+LANG_name in the textinsert database. So, there must be a default entry in that database.
+
+Translation macros can be embeded in other macros, including other translation macros.
+And other macros can emdedded in translation macros. They also accept entities, as
+described above.
+
+For HTML output, HTML tags are accepted in translation macros, but for the HTML
+to become effective, these must be included in a standard HTML macro definition
+string. In effect, they must be doubly bound to the HTML
+
+See http://dokuwiki.org/plugin:textinsert for further information.
+
+
+
+
diff --git a/platform/www/lib/plugins/textinsert/admin.php b/platform/www/lib/plugins/textinsert/admin.php
new file mode 100644
index 0000000..3d85347
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/admin.php
@@ -0,0 +1,292 @@
+<?php
+/**
+ *
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Myron Turner <turnermm02@shaw.ca>
+ */
+if(!defined('DOKU_INC')) die();
+
+define('REPLACE_DIR', DOKU_INC . 'data/meta/macros/');
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_textinsert extends DokuWiki_Admin_Plugin {
+
+ var $output = false;
+ var $macros_file;
+ var $macros_data; //used for html listings
+ /**
+ * handle user request
+ */
+ function __construct() {
+ if(!$this->getConf('farm')) {
+ define('MACROS_FILE', REPLACE_DIR . 'macros.ser');
+ }
+ else {
+ define('MACROS_FILE', metaFN('macros','.ser'));
+ }
+
+ }
+ function handle() {
+
+ $this->macros_file=MACROS_FILE;
+
+ if (!isset($_REQUEST['cmd'])) return; // first time - nothing to do
+
+ $this->output = '';
+ if (!checkSecurityToken()) return;
+ if (!is_array($_REQUEST['cmd'])) return;
+ $action = "";
+
+ // verify valid values
+ switch (key($_REQUEST['cmd'])) {
+ case 'add' :
+ $action = 'add';
+ $a = $this->add();
+ break;
+
+ case 'delete' :
+ $a = $this->del();
+ break;
+ case 'edit':
+ $a = $this->edit();
+ break;
+ }
+ // $this->output = print_r($a,true);
+ // $this->output .= print_r($_REQUEST,true);
+ }
+
+ function add() {
+ $a = $this->get_macros();
+ $macros = $_REQUEST['macro'];
+ $words = $_REQUEST['word'];
+
+ foreach ($macros AS $key=>$value) {
+ if(isset($value) && trim($value)) {
+ if(isset($words[$key]) && trim($words[$key])) {
+ $value = utf8_deaccent($value);
+ $a[$value] = htmlspecialchars (($words[$key]),ENT_NOQUOTES, 'UTF-8');
+ }
+ }
+ }
+
+ io_saveFile(MACROS_FILE,serialize($a));
+ return $a;
+ }
+
+ function del() {
+ $macros = $this->get_macros();
+
+ $deletions = $_REQUEST['delete'];
+ $keys = array_keys($deletions);
+ foreach ($keys AS $_key) {
+ unset($macros[$_key]);
+ }
+
+ io_saveFile(MACROS_FILE,serialize($macros));
+ return $macros;
+ }
+
+ function edit() {
+ $macros = $this->get_macros();
+
+ $encoded = $_REQUEST['encoded'];
+ $encoded = array_map('urldecode',$encoded);
+ foreach($encoded AS $k=>$val) {
+ $macros[$k] = htmlspecialchars ($val,ENT_NOQUOTES, 'UTF-8', false);
+ }
+ io_saveFile(MACROS_FILE,serialize($macros));
+ return $macros;
+ }
+
+ function get_macros() {
+ if(file_exists(MACROS_FILE)) {
+ $a = unserialize(file_get_contents(MACROS_FILE));
+ if(!is_array($a)) return array();
+ ksort($a);
+ return $a;
+ }
+ return array();
+ }
+
+ function get_delete_list() {
+ $macros = $this->macros_data;
+ ptln('<table cellspacing="4px" width="90%">');
+ foreach($macros as $macro=>$subst) {
+ ptln("<tr><td><input type='checkbox' name='delete[$macro]' value='$subst'>");
+ ptln( "<td style='padding:4px;'>$macro<td>$subst</td>");
+
+ }
+ ptln('</table>');
+ }
+
+ function get_edit_list() {
+ $macros = $this->macros_data;
+ ptln('<table cellspacing="4"><tr><th align="center">Macro</th><th align="center">' . $this->getLang('col_subst') .'</th></tr>');
+ foreach($macros as $macro=>$subst) {
+ ptln("<tr><td align='center'>$macro&nbsp;</td><td>");
+ $encoded = urlencode($subst);
+ if($subst != $encoded) {
+ ptln("<input type = 'hidden' name='encoded[$macro]' value='$encoded'>");
+ }
+ if(strlen($subst) > 80) {
+ ptln ("<textarea cols='55' rows='3' name='edit[$macro]' onchange='replace_encode(this)'>$subst</textarea></td></tr>");
+
+ }
+ else {
+ ptln ("<input type='text' size='80' name='edit[$macro]' onchange='replace_encode(this)' value='$subst'></td></tr>");
+ }
+
+ }
+ ptln('</table>');
+ }
+
+ function view_entries() {
+ $macros = $this->macros_data;
+ ptln('<table cellpadding="8px" width="90%">');
+ foreach($macros as $macro=>$subst) {
+ ptln( "<tr><td align='center'>$macro<td style='padding: 4px; border-bottom: 1px solid black;'>$subst</tr>");
+
+ }
+ ptln('</table>');
+ }
+
+ function js() {
+
+echo <<<JSFN
+
+ <script type="text/javascript">
+ //<![CDATA[
+ var replace_divs= new Array('macro_add','macro_del','macro_edit','ti_info','macro_list');
+ /**
+ * Edit onChange handler
+ * @param el input element which has been changed
+ * @desc if an encode hidden input already exists, its value
+ * is re-encoded from the text input's value
+ * If not, a new encoded hidden input is created with the encoded
+ * value. The encode input value is used to substitute the new edit values
+ * in the php edit() function
+ */
+ function replace_encode (el) {
+ var matches = el.name.match(/\[(.*)\]/);
+ if(matches[1]) {
+ var name = 'encoded['+matches[1]+']';
+ var val = el.value;
+ val = val.replace(/>/g,"&gt;");
+ val = val.replace(/</g,"&lt;");
+ if(!el.form[name]) {
+ var encoder = document.createElement('input');
+ encoder.type = 'hidden';
+ encoder.name = name;
+ encoder.value = encodeURIComponent(val);
+ el.form.appendChild(encoder);
+ }
+ else if(el.form[name]) {
+ el.form[name].value = encodeURIComponent(val);
+ }
+ }
+ }
+
+ function ti_getEL(n) {
+ return document.getElementById(n);
+ }
+
+ function replace_show(which) {
+ for(var i in replace_divs) {
+ ti_getEL(replace_divs[i]).style.display='none';
+ }
+ ti_getEL(which).style.display='block';
+ ti_getEL('ti_info_btn').style.display='inline';
+ }
+//]]>
+ </script>
+JSFN;
+
+ }
+ /**
+ * output appropriate html
+ */
+ function html() {
+ $this->macros_data = $this->get_macros();
+ $this->js();
+ if($this->output) {
+ ptln('<pre>' . $this->output . '</pre>');
+ }
+ ptln('<div style="padding:4px" id="ti_info">');
+ ptln('<div style="text-align:right;">');
+ ptln('<button class="button" style="padding:0px;margin:0px;" onclick="replace_show(\'ti_info_btn\');">');
+ ptln($this->getLang('hide_info') .'</button>&nbsp;&nbsp;&nbsp;&nbsp;');
+ ptln('</div>');
+ ptln('<h2>Info</h2>');
+ ptln( $this->locale_xhtml('intro') . '</div>');
+
+ ptln('<div style="padding-bottom:8px;">');
+ ptln('<button class="button" onclick="replace_show(\'macro_add\'); ">');
+ ptln($this->getLang('add_macros') .'</button>&nbsp;&nbsp;');
+
+ ptln('<button class="button" onclick="replace_show(\'macro_del\'); ">');
+ ptln($this->getLang('delete_macros') .'</button>&nbsp;&nbsp;');
+
+ ptln('<button class="button" onclick="replace_show(\'macro_edit\'); ">');
+ ptln($this->getLang('edit_macros') .'</button>&nbsp;&nbsp;');
+
+ ptln('<button class="button" onclick="ti_getEL(\'macro_list\').style.display=\'block\';ti_getEL(\'macro_list\').scrollIntoView();">');
+ ptln($this->getLang('view_macros') .'</button>&nbsp;&nbsp;');
+
+ ptln('<button class="button" onclick="ti_getEL(\'macro_list\').style.display=\'none\';">');
+ ptln($this->getLang('hide_macros') .'</button>&nbsp;&nbsp;');
+
+ ptln('<button class="button" id="ti_info_btn" style="display:none" onclick="ti_getEL(\'ti_info\').style.display=\'block\';">');
+ ptln($this->getLang('show_info') .'</button>');
+
+ ptln('</div>');
+ ptln('<form action="'.wl($ID).'" method="post">');
+
+ // output hidden values to ensure dokuwiki will return back to this plugin
+ ptln(' <input type="hidden" name="do" value="admin" />');
+ ptln(' <input type="hidden" name="page" value="'.$this->getPluginName().'" />');
+ formSecurityToken();
+
+ ptln('<div id="macro_add" style="display:none">');
+ ptln('<h2>' . $this->getLang('label_add') . '</h2>');
+ ptln( '<table cellspacing="8px"><tr><th>Macro</th><th>' . $this->getLang('col_subst') . '</th></tr>');
+ ptln('<tr><td> <input type="text" name="macro[A]" id="m_A" value="" /></td>');
+ ptln('<td> <input type="text" name="word[A]" size="80" id="w_A" value="" /></td></tr>');
+ ptln('<tr><td> <input type="text" name="macro[B]" id="m_B" value="" /></td>');
+ ptln('<td> <input type="text" name="word[B]" size="80" id="w_B" value="" /></td></tr>');
+ ptln('<tr><td> <input type="text" name="macro[C]" id="m_C" value="" /></td>');
+ ptln('<td> <input type="text" name="word[C]" size="80" id="w_C" value="" /></td></tr>');
+ ptln('<tr><td> <input type="text" name="macro[D]" id="m_D" value="" /></td>');
+ ptln('<td> <input type="text" name="word[D]" size="80" id="w_C" value="" /></td></tr>');
+ ptln('<tr><td> <input type="text" name="macro[E]" id="m_E" value="" /></td>');
+ ptln('<td> <input type="text" name="word[E]" size="80" id="w_E" value="" /></td>');
+ ptln('<tr><td> <input type="text" name="macro[F]" id="m_F" value="" /></td>');
+ ptln('<td> <textarea cols="45" name="word[F]" rows="4" id="w_F"></textarea></td>');
+ ptln('</table>');
+ ptln(' <input type="submit" name="cmd[add]" value="'.$this->getLang('btn_add').'" />');
+ ptln('</div><br />');
+
+ ptln('<div id="macro_del" style="display:none">');
+ ptln('<h2>' . $this->getLang('label_del') . '</h2>');
+ $this->get_delete_list();
+ ptln('<br /><input type="submit" name="cmd[delete]" value="'.$this->getLang('btn_del').'" />');
+ ptln('</div>');
+
+ ptln('<div id="macro_edit" style="display:none; padding: 8px;">');
+ ptln('<h2>' . $this->getLang('label_edit') . '</h2>');
+ $this->get_edit_list();
+ ptln('<br /><input type="submit" name="cmd[edit]" value="'.$this->getLang('btn_edit').'" />');
+ ptln('</div>');
+
+ ptln('</form>');
+
+ ptln('<br /><div id="macro_list" style="overflow:auto;display:block;">');
+ ptln('<h2>' . $this->getLang('label_list') . '</h2>');
+ $this->view_entries();
+ ptln('</div>');
+ }
+
+}
diff --git a/platform/www/lib/plugins/textinsert/conf/default.php b/platform/www/lib/plugins/textinsert/conf/default.php
new file mode 100644
index 0000000..efe3db4
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/conf/default.php
@@ -0,0 +1,5 @@
+<?php
+$conf['stdreplace'] = 1;
+$conf['farm'] = 0;
+
+
diff --git a/platform/www/lib/plugins/textinsert/conf/metadata.php b/platform/www/lib/plugins/textinsert/conf/metadata.php
new file mode 100644
index 0000000..56168e8
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/conf/metadata.php
@@ -0,0 +1,3 @@
+<?php
+$meta['stdreplace'] = array('onoff');
+$meta['farm'] = array('onoff'); \ No newline at end of file
diff --git a/platform/www/lib/plugins/textinsert/lang/de/lang.php b/platform/www/lib/plugins/textinsert/lang/de/lang.php
new file mode 100644
index 0000000..907fe6f
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/de/lang.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Thor Weinreich <thorweinreich@nefkom.net>
+ */
+$lang['btn_add'] = 'Hinzufügen';
+$lang['btn_del'] = 'Löschen';
+$lang['btn_edit'] = 'Änderungen speichern';
+$lang['label_list'] = 'Makro-Liste';
+$lang['label_add'] = 'Makros hinzufügen';
+$lang['label_del'] = 'Makros löschen';
+$lang['label_edit'] = 'Makros bearbeiten';
+$lang['col_subst'] = 'Makros ersetzen';
+$lang['add_macros'] = 'Makros hinzufügen';
+$lang['delete_macros'] = 'Makros löschen';
+$lang['edit_macros'] = 'Makros bearbeiten';
+$lang['view_macros'] = 'Makro-Liste anzeigen';
+$lang['hide_macros'] = 'Makro-Liste verbergen';
+$lang['hide_info'] = 'Info schließen';
+$lang['show_info'] = 'Info anzeigen';
diff --git a/platform/www/lib/plugins/textinsert/lang/de/settings.php b/platform/www/lib/plugins/textinsert/lang/de/settings.php
new file mode 100644
index 0000000..ca9e0e1
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/de/settings.php
@@ -0,0 +1,8 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Thor Weinreich <thorweinreich@nefkom.net>
+ */
+$lang['stdreplace'] = 'Standard Makro-Ersetzungen annehmen, wie sie in Namensraum-Templates benutzt werden';
diff --git a/platform/www/lib/plugins/textinsert/lang/en/intro.txt b/platform/www/lib/plugins/textinsert/lang/en/intro.txt
new file mode 100644
index 0000000..a89d5e5
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/en/intro.txt
@@ -0,0 +1,16 @@
+This panel enables you to add and delete macros and their replacement texts, and to edit them after they have been saved. A macro name can contain letters, numbers, underscores, hyphens and periods. For example: ''Macro_one.txt''. The replacement texts can accept HTML and can be of any length.
+
+You can add up to six macros at a time. The sixth is a text area which will allow for extended texts.
+Enter the macro name in the **Macro** column and the texts which they represent in the
+**Substitution** column.
+
+
+Deletions are unlimited; check off the box(es) next the macro(s) to be deleted and click
+the **Delete** button at the bottom of the screen. Editing is done through the Edit screen, where you are presented
+with all your macros. You can edit the texts of any number of macros.
+
+
+The macro list will not refresh until after you have submitted your edits, additions, or deletions
+by clicking the appropriate button at the bottom of the screen.
+
+
diff --git a/platform/www/lib/plugins/textinsert/lang/en/lang.php b/platform/www/lib/plugins/textinsert/lang/en/lang.php
new file mode 100644
index 0000000..7a01bc6
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/en/lang.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * English language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Myron turner <turnermm02@shaw.ca>
+ */
+
+// for admin plugins, the menu prompt to be displayed in the admin menu
+// if set here, the plugin doesn't need to override the getMenuText() method
+$lang['menu'] = 'TextInsert Macro Replacement Plugin';
+
+$lang['btn_add'] = 'Add';
+$lang['btn_del'] = 'Delete';
+$lang['btn_edit'] = 'Submit Edits';
+
+$lang['label_list'] = "Macro List";
+$lang['label_add'] = "Add Macros";
+$lang['label_del'] = "Delete Macros";
+$lang['label_edit'] = "Edit Macros";
+
+$lang['col_subst'] = 'Macro Substitution';
+$lang['add_macros'] = 'Add Macros';
+$lang['delete_macros'] = 'Delete Macros';
+$lang['edit_macros'] = 'Edit Macros';
+$lang['view_macros'] = 'View Macro List';
+$lang['hide_macros'] = 'Hide Macro List';
+$lang['hide_info'] = 'Close Info';
+$lang['show_info'] = 'Show Info';
+$lang['not_found'] = 'macro was not found in the macros database';
+
diff --git a/platform/www/lib/plugins/textinsert/lang/en/macros.php b/platform/www/lib/plugins/textinsert/lang/en/macros.php
new file mode 120000
index 0000000..21b1645
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/en/macros.php
@@ -0,0 +1 @@
+../../../../../../i18n/textinsert_strings.php \ No newline at end of file
diff --git a/platform/www/lib/plugins/textinsert/lang/en/settings.php b/platform/www/lib/plugins/textinsert/lang/en/settings.php
new file mode 100644
index 0000000..4083a83
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/en/settings.php
@@ -0,0 +1,3 @@
+<?php
+$lang['stdreplace'] = 'Accept standard macro replacements as used in namespace templates';
+$lang['farm'] = 'If this is a farm and you and would like each animal to have its own macro database, please select this option; otherwise all animals will share the same (i.e. the farmer\'s) database.';
diff --git a/platform/www/lib/plugins/textinsert/lang/es/intro.txt b/platform/www/lib/plugins/textinsert/lang/es/intro.txt
new file mode 100644
index 0000000..a89d5e5
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/es/intro.txt
@@ -0,0 +1,16 @@
+This panel enables you to add and delete macros and their replacement texts, and to edit them after they have been saved. A macro name can contain letters, numbers, underscores, hyphens and periods. For example: ''Macro_one.txt''. The replacement texts can accept HTML and can be of any length.
+
+You can add up to six macros at a time. The sixth is a text area which will allow for extended texts.
+Enter the macro name in the **Macro** column and the texts which they represent in the
+**Substitution** column.
+
+
+Deletions are unlimited; check off the box(es) next the macro(s) to be deleted and click
+the **Delete** button at the bottom of the screen. Editing is done through the Edit screen, where you are presented
+with all your macros. You can edit the texts of any number of macros.
+
+
+The macro list will not refresh until after you have submitted your edits, additions, or deletions
+by clicking the appropriate button at the bottom of the screen.
+
+
diff --git a/platform/www/lib/plugins/textinsert/lang/es/lang.php b/platform/www/lib/plugins/textinsert/lang/es/lang.php
new file mode 100644
index 0000000..7a01bc6
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/es/lang.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * English language file
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Myron turner <turnermm02@shaw.ca>
+ */
+
+// for admin plugins, the menu prompt to be displayed in the admin menu
+// if set here, the plugin doesn't need to override the getMenuText() method
+$lang['menu'] = 'TextInsert Macro Replacement Plugin';
+
+$lang['btn_add'] = 'Add';
+$lang['btn_del'] = 'Delete';
+$lang['btn_edit'] = 'Submit Edits';
+
+$lang['label_list'] = "Macro List";
+$lang['label_add'] = "Add Macros";
+$lang['label_del'] = "Delete Macros";
+$lang['label_edit'] = "Edit Macros";
+
+$lang['col_subst'] = 'Macro Substitution';
+$lang['add_macros'] = 'Add Macros';
+$lang['delete_macros'] = 'Delete Macros';
+$lang['edit_macros'] = 'Edit Macros';
+$lang['view_macros'] = 'View Macro List';
+$lang['hide_macros'] = 'Hide Macro List';
+$lang['hide_info'] = 'Close Info';
+$lang['show_info'] = 'Show Info';
+$lang['not_found'] = 'macro was not found in the macros database';
+
diff --git a/platform/www/lib/plugins/textinsert/lang/es/macros.php b/platform/www/lib/plugins/textinsert/lang/es/macros.php
new file mode 120000
index 0000000..21b1645
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/es/macros.php
@@ -0,0 +1 @@
+../../../../../../i18n/textinsert_strings.php \ No newline at end of file
diff --git a/platform/www/lib/plugins/textinsert/lang/es/settings.php b/platform/www/lib/plugins/textinsert/lang/es/settings.php
new file mode 100644
index 0000000..4083a83
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/es/settings.php
@@ -0,0 +1,3 @@
+<?php
+$lang['stdreplace'] = 'Accept standard macro replacements as used in namespace templates';
+$lang['farm'] = 'If this is a farm and you and would like each animal to have its own macro database, please select this option; otherwise all animals will share the same (i.e. the farmer\'s) database.';
diff --git a/platform/www/lib/plugins/textinsert/lang/fr/intro.txt b/platform/www/lib/plugins/textinsert/lang/fr/intro.txt
new file mode 100644
index 0000000..ce05cbd
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/fr/intro.txt
@@ -0,0 +1,10 @@
+Ce panneau vous permet d'ajouter et supprimer des macros et leur textes de remplacement, de les modifier après leur enregistrement. Un nom de macro peut contenir des lettres, des nombres, des tirets bas, traits d'union et points. Par exemple : ''Macro_one.txt''. Le texte de remplacement peut accepter le HTML et peut être de n'importe quelle longueur.
+
+Vous pouvez ajouter jusqu'à six macros à la fois. Le sixième est une zone de texte qui permettra de longs textes.
+Entrez le nom de la macro dans la colonne **Macro** et les textes qu'ils représentent dans la colonne **Remplacement**.
+
+
+Les suppressions sont illimitées ; cochez la devant la macro à supprimer et cliquez sur le bouton **Supprimer** en bas de l'écran. La modification se fait à travers l'écran de modification, où vous sont présenté toutes vos macros. Vous pouvez modifier les textes de n'importe quel nombre de macros.
+
+
+La liste macro ne s'actualise pas jusqu'à ce que vous avez envoyer vos modifications, ajouts ou suppressions en cliquant sur le bouton approprié en bas de l'écran. \ No newline at end of file
diff --git a/platform/www/lib/plugins/textinsert/lang/fr/lang.php b/platform/www/lib/plugins/textinsert/lang/fr/lang.php
new file mode 100644
index 0000000..2570f93
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/fr/lang.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Hérisson grognon <dodoperso@laposte.net>
+ * @author Ner0lph <forums@ner0lph.tk>
+ */
+$lang['menu'] = 'TextInsert Macro Replacement Plugin';
+$lang['btn_add'] = 'Ajouter';
+$lang['btn_del'] = 'Supprimer';
+$lang['btn_edit'] = 'Envoyer les modifications';
+$lang['label_list'] = 'Liste des macros';
+$lang['label_add'] = 'Ajouter des macros';
+$lang['label_del'] = 'Supprimer des macros';
+$lang['label_edit'] = 'Modifier des macros';
+$lang['col_subst'] = 'Substitution de macro';
+$lang['add_macros'] = 'Ajouter des macros';
+$lang['delete_macros'] = 'Supprimer des macros';
+$lang['edit_macros'] = 'Modifier des macros';
+$lang['view_macros'] = 'Afficher la liste des macros';
+$lang['hide_macros'] = 'Cacher la liste des macros';
+$lang['hide_info'] = 'Fermer les informations';
+$lang['show_info'] = 'Montrer les informations';
+$lang['not_found'] = 'Le macro n\'a pas été trouvé dans la base de données des macros.';
diff --git a/platform/www/lib/plugins/textinsert/lang/fr/settings.php b/platform/www/lib/plugins/textinsert/lang/fr/settings.php
new file mode 100644
index 0000000..92bd788
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/fr/settings.php
@@ -0,0 +1,10 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Ner0lph <forums@ner0lph.tk>
+ * @author ubibene <services.m@benard.info>
+ */
+$lang['stdreplace'] = 'Accepter des remplacements standards de macros en tant que modèles de catégorie';
+$lang['farm'] = 'Si ceci était une ferme et que vous souhaitez que chaque animal ait sa propre base de macros, sélectionnez cette option; sinon tous les animaux partageront la même base de données (c\'est à dire celle du fermier).';
diff --git a/platform/www/lib/plugins/textinsert/lang/ja/intro.txt b/platform/www/lib/plugins/textinsert/lang/ja/intro.txt
new file mode 100644
index 0000000..ef806fd
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/ja/intro.txt
@@ -0,0 +1,16 @@
+ã“ã®ç”»é¢ã§ã¯ã€ãƒžã‚¯ãƒ­ã¨ä»£æ›¿ãƒ†ã‚­ã‚¹ãƒˆã®è¿½åŠ ã¨å‰Šé™¤ã€ä¿å­˜å¾Œã®ç·¨é›†ãŒã§ãã¾ã™ã€‚
+マクロåã¯ã€æ–‡å­—・数字・アンダースコア・ãƒã‚¤ãƒ•ãƒ³ãƒ»ãƒ”リオドを使用ã—ã¾ã™ã€‚
+例:''Macro_one.txt''
+代替テキスト㯠HTML も許容ã—ã¾ã™ã—ã€ä»»æ„é•·ã§ã™ã€‚
+
+一度㫠6 マクロを追加ã§ãã¾ã™ã€‚
+テキスト欄ã¯æ‹¡å¼µãƒ†ã‚­ã‚¹ãƒˆã‚’入力ã§ãã¾ã™ã€‚
+**マクロ**欄ã«ãƒžã‚¯ãƒ­åã€**ç½®æ›**欄ã«ä»£æ›¿ãƒ†ã‚­ã‚¹ãƒˆã‚’入力ã—ã¾ã™ã€‚
+
+削除ã«åˆ¶é™ã¯ã‚ã‚Šã¾ã›ã‚“。
+削除ã™ã‚‹ãƒžã‚¯ãƒ­ã®éš£ã«ã‚ã‚‹ãƒã‚§ãƒƒã‚¯ã‚’外ã—ã€ç”»é¢ä¸‹ã®**削除**ボタンをクリックã—ã¾ã™ã€‚
+編集ã¯ç·¨é›†ç”»é¢ã§è¡Œã„ã¾ã™ã€‚
+編集画é¢ã«ã¯ç™»éŒ²ã•ã‚ŒãŸãƒžã‚¯ãƒ­ã‚’ã™ã¹ã¦è¡¨ç¤ºã•ã‚Œã¦ã„ã¾ã™ã€‚
+複数ã®ãƒžã‚¯ãƒ­ã®ãƒ†ã‚­ã‚¹ãƒˆç·¨é›†ã‚‚å¯èƒ½ã§ã™ã€‚
+
+ç”»é¢ä¸‹ã«ã‚るボタンをクリックã—ã¦ç·¨é›†ãƒ»è¿½åŠ ãƒ»å‰Šé™¤ã‚’実行ã™ã‚‹ã¾ã§ãƒžã‚¯ãƒ­ä¸€è¦§ã¯æ›´æ–°ã•ã‚Œã¾ã›ã‚“。 \ No newline at end of file
diff --git a/platform/www/lib/plugins/textinsert/lang/ja/lang.php b/platform/www/lib/plugins/textinsert/lang/ja/lang.php
new file mode 100644
index 0000000..f9b95ba
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/ja/lang.php
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Hideaki SAWADA <chuno@live.jp>
+ */
+$lang['menu'] = 'TextInsert マクロ置æ›ãƒ—ラグイン';
+$lang['btn_add'] = '追加';
+$lang['btn_del'] = '削除';
+$lang['btn_edit'] = '編集ã®å®Ÿè¡Œ';
+$lang['label_list'] = 'マクロ一覧';
+$lang['label_add'] = 'マクロ追加';
+$lang['label_del'] = 'マクロ削除';
+$lang['label_edit'] = 'マクロ編集';
+$lang['col_subst'] = 'マクロ置æ›';
+$lang['add_macros'] = 'マクロ追加';
+$lang['delete_macros'] = 'マクロ削除';
+$lang['edit_macros'] = 'マクロ編集';
+$lang['view_macros'] = 'マクロ一覧を表示';
+$lang['hide_macros'] = 'マクロ一覧をéžè¡¨ç¤º';
+$lang['hide_info'] = '解説をéžè¡¨ç¤º';
+$lang['show_info'] = '解説を表示';
diff --git a/platform/www/lib/plugins/textinsert/lang/ja/settings.php b/platform/www/lib/plugins/textinsert/lang/ja/settings.php
new file mode 100644
index 0000000..c5ef2c1
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/ja/settings.php
@@ -0,0 +1,9 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Hideaki SAWADA <chuno@live.jp>
+ */
+$lang['stdreplace'] = 'åå‰ç©ºé–“テンプレートã§ä½¿ç”¨ã•ã‚Œã¦ã„る標準マクロ置æ›ã‚’許容ã™ã‚‹';
+$lang['farm'] = 'ã“ã® Wiki ãŒç‰§å ´ã§å„動物ã«ç‹¬è‡ªã®ãƒžã‚¯ãƒ­ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’æŒãŸã›ãŸã„å ´åˆã€ã“ã®ã‚ªãƒ—ションをé¸æŠžã—ã¦ãã ã•ã„。é¸æŠžã—ãªã„å ´åˆã€å…¨ã¦ã®å‹•ç‰©ã¯åŒä¸€ã®ï¼ˆã¤ã¾ã‚Šç‰§å ´ä¸»ã®ï¼‰ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’共有ã™ã‚‹ã“ã¨ã«ãªã‚Šã¾ã™ã€‚';
diff --git a/platform/www/lib/plugins/textinsert/lang/nl/intro.txt b/platform/www/lib/plugins/textinsert/lang/nl/intro.txt
new file mode 100644
index 0000000..8e35a1e
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/nl/intro.txt
@@ -0,0 +1,11 @@
+Met dit luik kan je macro's en hun vervangingsteksten onderhouden: aanmaken, schrappen en bewerken nadat ze opgeslagen zijn. Een macro naam kan letters, cijfers, onderlijningsstreepjes, koppeltekens en punten bevatten. Voorbeeld: ''Macro_one.txt''. De vervangtekst kan in HTML zijn en gelijk welke lengte.
+
+Zes macro's tegelijk kan je toevoegen. De zesde is de tekstzone waar je uitgebreide teksten kan invoeren.
+Geef een macro naam in de **Macro** kolom en de tekst die hier aan gekoppeld is in de **Vervangteksten** kolom.
+
+Schrappen kan je onbeperkt uitvoeren. Vink het vakje of de vakjes aan naast de macro's die geschrapt moeten
+worden. Klik daarna op de **Schrappen** knop onderaan het scherm. Bewerken doe je via het bewerkingsscherm waar
+je alle macro's ziet staan. Je bewerkt teksten van zoveel macro's als je maar wil.
+
+De macro lijst wordt niet hernieuwd zolang de wijzigingen, toevoegingen, schrappingen niet doorgevoerd zijn
+door te klikken op de voorziene knop onderaan het scherm. \ No newline at end of file
diff --git a/platform/www/lib/plugins/textinsert/lang/nl/lang.php b/platform/www/lib/plugins/textinsert/lang/nl/lang.php
new file mode 100644
index 0000000..ce1b255
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/nl/lang.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Myron turner <turnermm02@shaw.ca>
+ * @author hugo smet <hugo.smet@scarlet.be>
+ */
+$lang['menu'] = 'TextInsert Macro Substitutie Plugin';
+$lang['btn_add'] = 'Toevoegen';
+$lang['btn_del'] = 'Schrappen';
+$lang['btn_edit'] = 'Wijzigingen doorvoeren';
+$lang['label_list'] = 'Macro Lijst';
+$lang['label_add'] = 'Macro\'s Toevoegen';
+$lang['label_del'] = 'Macro\'s Schrappen';
+$lang['label_edit'] = 'Macro\'s Bewerken';
+$lang['col_subst'] = 'Macro Vervangteksten';
+$lang['add_macros'] = 'Toevoegen';
+$lang['delete_macros'] = 'Schrappen';
+$lang['edit_macros'] = 'Bewerken';
+$lang['view_macros'] = 'Lijst Tonen';
+$lang['hide_macros'] = 'Lijst Verbergen';
+$lang['hide_info'] = 'Info Sluiten';
+$lang['show_info'] = 'Info Tonen';
diff --git a/platform/www/lib/plugins/textinsert/lang/nl/settings.php b/platform/www/lib/plugins/textinsert/lang/nl/settings.php
new file mode 100644
index 0000000..afb2901
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/nl/settings.php
@@ -0,0 +1,8 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Hugo Smet <hugo.smet@scarlet.be>
+ */
+$lang['stdreplace'] = 'Standaard macro substituties aanvaarden zoals deze in naamruimte sjablonen gebruikt worden';
diff --git a/platform/www/lib/plugins/textinsert/lang/pt-br/intro.txt b/platform/www/lib/plugins/textinsert/lang/pt-br/intro.txt
new file mode 100644
index 0000000..974e84c
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/pt-br/intro.txt
@@ -0,0 +1,13 @@
+Esse painel permite adicionar e excluir macros e seus textos de substituição e editá-los depois de salvos. Um nome de macro pode conter letras, números, sublinhados, hífens e pontos. Por exemplo: '' Macro_one.txt ''. Os textos de substituição podem aceitar HTML e podem ser de qualquer tamanho.
+
+Você pode adicionar até seis macros por vez. A sexta é uma área de texto que permitirá textos estendidos.
+Insira o nome da macro na coluna ** Macro ** e os textos que eles representam na
+** Substituição ** coluna.
+
+Deleções são ilimitadas; marque a caixa ao lado da(s) macro(s) a ser (em) excluída(s) e clique
+no botão ** Excluir ** na parte inferior da tela. A edição é feita através da tela Editar, onde você é apresentado
+com todas as suas macros. Você pode editar os textos de qualquer número de macros.
+
+
+A lista de macros não será atualizada até que você tenha enviado suas edições, adições ou exclusões
+clicando no botão apropriado na parte inferior da tela. \ No newline at end of file
diff --git a/platform/www/lib/plugins/textinsert/lang/pt-br/lang.php b/platform/www/lib/plugins/textinsert/lang/pt-br/lang.php
new file mode 100644
index 0000000..874bb9d
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/pt-br/lang.php
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Alexandre Belchior <alexbelchior@gmail.com>
+ */
+$lang['menu'] = 'Plugin de Substituição de Macro TextInsert';
+$lang['btn_add'] = 'Adicionar';
+$lang['btn_del'] = 'Delete';
+$lang['btn_edit'] = 'Enviar edições';
+$lang['label_list'] = 'Lista de Macro';
+$lang['label_add'] = 'Adicionar macros';
+$lang['label_del'] = 'Deletar macros';
+$lang['label_edit'] = 'Editar macros';
+$lang['col_subst'] = 'Substituição de macro';
+$lang['add_macros'] = 'Adicionar macros';
+$lang['delete_macros'] = 'Deletar macros';
+$lang['edit_macros'] = 'Editar macros';
+$lang['view_macros'] = 'Visualizar lista de macro';
+$lang['hide_macros'] = 'Ocultar lista de macro';
+$lang['hide_info'] = 'Fechar informação';
+$lang['show_info'] = 'Mostrar informação';
diff --git a/platform/www/lib/plugins/textinsert/lang/pt-br/settings.php b/platform/www/lib/plugins/textinsert/lang/pt-br/settings.php
new file mode 100644
index 0000000..db02fd6
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/pt-br/settings.php
@@ -0,0 +1,9 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Alexandre Belchior <alexbelchior@gmail.com>
+ */
+$lang['stdreplace'] = 'Aceite substituições de macro padrão como usadas em modelos de namespace';
+$lang['farm'] = 'Se isto é uma fazenda e você e gostaria que cada animal tivesse seu próprio banco de dados de macros, selecione essa opção; caso contrário, todos os animais compartilharão o mesmo banco de dados (ou seja, do fazendeiro).';
diff --git a/platform/www/lib/plugins/textinsert/lang/ru/intro.txt b/platform/www/lib/plugins/textinsert/lang/ru/intro.txt
new file mode 100644
index 0000000..e432c6b
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/ru/intro.txt
@@ -0,0 +1,10 @@
+Панель позволÑет добавлÑÑ‚ÑŒ, редактировать и удалÑÑ‚ÑŒ макроÑÑ‹ и их подÑтановки. Имена макроÑов могут Ñодержать буквы, цифры, Ñимвол подчёркиваниÑ, Ð´ÐµÑ„Ð¸Ñ Ð¸Â Ñ‚Ð¾Ñ‡ÐºÑƒ. Пример: ''Macro_one.txt''. ПодÑтановки неограничены в длине и могут Ñодержать HTML-разметку.
+
+В режиме //добавлениÑ// можно Ñоздать до шеÑти макроÑов. ШеÑтое текÑтовое поле предназначено Ð´Ð»Ñ Ð´Ð»Ð¸Ð½Ð½Ñ‹Ñ… текÑтов. В колонке **Macro** введите Ð¸Ð¼Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ макроÑа, а в колонке **ПодÑтановки** --- замещающий текÑÑ‚.
+
+В режиме //удалениÑ// поÑвлÑÑŽÑ‚ÑÑ Ñ„Ð»Ð°Ð¶ÐºÐ¸ Ð´Ð»Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð° удалÑемых макроÑов. Разовое количеÑтво удалений не ограничено.
+
+В режиме //редактированиÑ// вÑе Ð¿Ð¾Ð»Ñ Ð¿Ð¾Ð´Ñтановок открываютÑÑ Ð´Ð»Ñ Ð¸ÑправлениÑ. Разовое количеÑтво иÑправлений не ограничено.
+
+СпиÑок макроÑов обновитÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ поÑле Ð½Ð°Ð¶Ð°Ñ‚Ð¸Ñ ÑоответÑтвующей функциональной кнопки внизу ÑпиÑка.
+
diff --git a/platform/www/lib/plugins/textinsert/lang/ru/lang.php b/platform/www/lib/plugins/textinsert/lang/ru/lang.php
new file mode 100644
index 0000000..25e2fe7
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/ru/lang.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Aleksandr Selivanov <alexgearbox@yandex.ru>
+ * @author RainbowSpike <1@2.ru>
+ */
+$lang['menu'] = 'Плагин макрозамен TextInsert';
+$lang['btn_add'] = 'Добавить';
+$lang['btn_del'] = 'Удалить';
+$lang['btn_edit'] = 'Подтвердить изменениÑ';
+$lang['label_list'] = 'СпиÑок макроÑов';
+$lang['label_add'] = 'Добавить макроÑÑ‹';
+$lang['label_del'] = 'Удалить макроÑÑ‹';
+$lang['label_edit'] = 'Изменить макроÑÑ‹';
+$lang['col_subst'] = 'ПодÑтановки';
+$lang['add_macros'] = 'Добавить макроÑÑ‹';
+$lang['delete_macros'] = 'Удалить макроÑÑ‹';
+$lang['edit_macros'] = 'Изменить макроÑÑ‹';
+$lang['view_macros'] = 'Показать ÑпиÑок макроÑов';
+$lang['hide_macros'] = 'Скрыть ÑпиÑок макроÑов';
+$lang['hide_info'] = 'Скрыть Ñправку';
+$lang['show_info'] = 'Показать Ñправку';
+$lang['not_found'] = 'ÐœÐ°ÐºÑ€Ð¾Ñ Ð½Ðµ найден в перечне макроÑов';
diff --git a/platform/www/lib/plugins/textinsert/lang/ru/settings.php b/platform/www/lib/plugins/textinsert/lang/ru/settings.php
new file mode 100644
index 0000000..07a8850
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/ru/settings.php
@@ -0,0 +1,9 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author RainbowSpike <1@2.ru>
+ * @author Aleksandr Selivanov <alexgearbox@yandex.ru>
+ */
+$lang['stdreplace'] = 'ДопуÑкать Ñтандартные переменные, иÑпользуемые Ð´Ð»Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð¾Ð² проÑтранÑтв имён';
diff --git a/platform/www/lib/plugins/textinsert/lang/zh/intro.txt b/platform/www/lib/plugins/textinsert/lang/zh/intro.txt
new file mode 100644
index 0000000..8846119
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/zh/intro.txt
@@ -0,0 +1,11 @@
+通过此é¢æ¿ï¼Œæ‚¨å¯ä»¥æ·»åŠ ã€åˆ é™¤å®åŠå…¶æ›¿æ¢æ–‡æœ¬ï¼Œä¿å­˜åŽä¹Ÿå¯ä»¥åœ¨æ¬¡å¯¹å…¶è¿›è¡Œç¼–辑。 å®å称å¯ä»¥åŒ…å«å­—æ¯ï¼Œæ•°å­—,下划线,连字符和å¥å·ã€‚ 例如:''Macro_one.txt''。替æ¢æ–‡æœ¬æ”¯æŒ HTML,且ä¸é™åˆ¶é•¿åº¦ã€‚
+
+您一次最多å¯ä»¥æ·»åŠ å…­ä¸ªå®ã€‚ 第六个是å…许扩展文本的文本区域。
+在**å®**列表中输入å®çš„å称,并在å¦ä¸€è¾¹ä¸­è¾“入它们的**替æ¢**文本。
+
+
+选中è¦åˆ é™¤çš„å®æ—边的框,然åŽå•å‡»å±å¹•åº•éƒ¨çš„**删除**按钮,å³å¯åˆ é™¤å®ã€‚
+编辑是通过编辑界é¢å®Œæˆçš„,这个界é¢ä¼šæ˜¾ç¤ºä½ æ‰€æœ‰çš„å®ã€‚您å¯ä»¥ç¼–辑任æ„æ•°é‡çš„å®çš„内容。
+
+
+在您通过å±å¹•åº•éƒ¨çš„相应按钮æ交编辑ã€æ·»åŠ æˆ–删除之åŽï¼Œå®åˆ—表æ‰ä¼šåˆ·æ–°ã€‚ \ No newline at end of file
diff --git a/platform/www/lib/plugins/textinsert/lang/zh/lang.php b/platform/www/lib/plugins/textinsert/lang/zh/lang.php
new file mode 100644
index 0000000..09d578a
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/lang/zh/lang.php
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author RainSlide <RainSlide@outlook.com>
+ */
+$lang['menu'] = 'TextInsert å®æ’件';
+$lang['btn_add'] = '添加';
+$lang['btn_del'] = '删除';
+$lang['btn_edit'] = 'æ交编辑';
+$lang['label_list'] = 'å®åˆ—表';
+$lang['label_add'] = '添加å®';
+$lang['label_del'] = '删除å®';
+$lang['label_edit'] = '编辑å®';
+$lang['col_subst'] = '替æ¢æ–‡æœ¬';
+$lang['add_macros'] = '添加å®';
+$lang['delete_macros'] = '删除å®';
+$lang['edit_macros'] = '编辑å®';
+$lang['view_macros'] = '显示å®åˆ—表';
+$lang['hide_macros'] = 'éšè—å®åˆ—表';
+$lang['hide_info'] = '关闭信æ¯';
+$lang['show_info'] = '显示信æ¯';
diff --git a/platform/www/lib/plugins/textinsert/manager.dat b/platform/www/lib/plugins/textinsert/manager.dat
new file mode 100644
index 0000000..a12c912
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/manager.dat
@@ -0,0 +1,2 @@
+downloadurl=https://github.com/turnermm/TextInsert/zipball/master
+installed=Thu, 29 Apr 2021 06:46:29 -0300
diff --git a/platform/www/lib/plugins/textinsert/plugin.info.txt b/platform/www/lib/plugins/textinsert/plugin.info.txt
new file mode 100644
index 0000000..ae031d0
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/plugin.info.txt
@@ -0,0 +1,9 @@
+base textinsert
+author Myron Turner
+email turnermm02@shaw.ca
+date 2019-10-03
+name textinsert Plugin
+desc replace macros with text subsitutions
+url https://www.dokuwiki.org/plugin:textinsert
+
+
diff --git a/platform/www/lib/plugins/textinsert/syntax.php b/platform/www/lib/plugins/textinsert/syntax.php
new file mode 100644
index 0000000..82a60b6
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/syntax.php
@@ -0,0 +1,261 @@
+<?php
+/**
+ *
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Myron Turner <turnermm02@shaw.ca>
+ *
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
+require_once(DOKU_PLUGIN.'syntax.php');
+define('REPLACE_DIR', DOKU_INC . 'data/meta/macros/');
+define('MACROS_FILE', REPLACE_DIR . 'macros.ser');
+
+
+/**
+ * All DokuWiki plugins to extend the parser/rendering mechanism
+ * need to inherit from this class
+ */
+class syntax_plugin_textinsert extends DokuWiki_Syntax_Plugin {
+ var $macros;
+ var $translations;
+ var $ns;
+ /**
+ * return some info
+ */
+
+ /**
+ * What kind of syntax are we?
+ */
+ function getType(){
+ return 'substition';
+ }
+
+ /**
+ * Where to sort in?
+ */
+ function getSort(){
+ return 155;
+ }
+
+
+ /**
+ * Connect pattern to lexer
+ */
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('#@\!?[\w\-\._]+\!?@#',$mode,'plugin_textinsert');
+ $this->Lexer->addSpecialPattern('#@\!\![\w\-\._]+@#',$mode,'plugin_textinsert');
+ $this->Lexer->addSpecialPattern('#@[\w\-\._]+~.*?~@#',$mode,'plugin_textinsert');
+ $this->Lexer->addSpecialPattern('#@[\w\-\._]+[\r\n]+~[^\r\n]+~@#',$mode,'plugin_textinsert');
+ }
+
+
+ /**
+ * Handle the match
+ */
+ function handle($match, $state, $pos, Doku_Handler $handler){
+
+ $html=false;
+ $translation = false;
+ $match = substr($match,2,-2);
+ $match = trim($match);
+ if(strpos($match, 'HTML')) $html=true;
+ if(strpos($match, 'LANG_') !== false) {
+ $translation=true;
+ list($prefix,$trans) = explode('_',$match,2);
+ }
+
+ global $ID;
+ list($ns,$rest) = explode(':',$ID,2);
+ if(@file_exists($filename = DOKU_PLUGIN . "textinsert/lang/$ns/lang.php")) {
+ include $filename;
+ $this->translations = $lang;
+
+ }
+
+ if(@file_exists($filename = DOKU_PLUGIN . "textinsert/lang/$ns/macros.php")) {
+ include $filename;
+ $ar = 'lang_' .$ns;
+ $tr = $$ar;
+ if($this->translations) {
+ $this->translations = array_merge($lang,$tr);
+ }
+ else $this->translations = $tr;
+ }
+
+ if(!empty($ns)) {
+ $this->ns = $ns;
+ }
+ $this->macros = $this->get_macros();
+
+
+
+ while(preg_match('#(\*\*|//|__|\'\').*?\1#m',$match )) {
+ $match = preg_replace_callback(
+ '#(\*\*|//|__|\'\')(.*?)(\1)#',
+ function($matches) {
+ $matches[1] = str_replace(array('**','//','__','\'\'',),array('<b>','<em>','<u>','<code>'),$matches[1]);
+ $matches[3] = str_replace(array('**','//','__','\'\''),array('</b>','</em>','</u>','</code>'),$matches[3]);
+ return $matches[1] . $matches[2] . $matches[3];
+ },$match );
+ }
+
+ if(preg_match('/(.*?)~([\s\S]+)~$/',$match,$subtitution)) {
+ $match=$subtitution[1];
+ $subtitution[2] = str_replace('\\,','&#44;',$subtitution[2]);
+ $substitutions=explode(',',$subtitution[2]);
+ $substitutions = preg_replace('#\/\/.+#',"",$substitutions);
+ $substitutions = preg_replace('#\\\n#',"<br />",$substitutions);
+ }
+
+ if(!array_key_exists($match, $this->macros) ) {
+ $err = $this->getLang('not_found');
+ msg("$match $err", -1);
+ $match = "";
+ }
+ else {
+ if($translation && isset($this->translations[$trans])){
+ $match = $this->translations[$trans];
+ }
+ else {
+ $match =$this->macros[$match];
+ }
+ }
+
+ if(!is_array($substitutions)) $substitutions = array();
+ for($i=0; $i<count($substitutions); $i++) {
+ $search = '%' . ($i+1);
+ $match = str_replace ($search , trim($substitutions[$i]), $match);
+ }
+
+ $match = $this->get_inserts($match,$translation);
+
+ if($html) {
+ $match = str_replace('&lt;','<',$match);
+ $match = str_replace('&gt;','>',$match);
+ }
+
+ return array($state,$match);
+ }
+
+ /**
+ * Create output
+ */
+ function render($mode, Doku_Renderer $renderer, $data) {
+ global $INFO;
+ if($mode == 'xhtml'){
+ list($state, $word) = $data;
+ If(strpos($word,'_ID_') !== false ) {
+ $word = str_replace('_ID_',$INFO['id'], $word);
+ }
+ $renderer->doc .= $word;
+ return true;
+ }
+ return false;
+ }
+
+ function get_macros() {
+ $a = array();
+ if(file_exists(MACROS_FILE)) {
+ $a = unserialize(file_get_contents(MACROS_FILE));
+ }
+ else if($this->getConf('farm')) {
+ $a = unserialize(file_get_contents(metaFN('macros','.ser')));
+ }
+ $r = $this->get_std_replacements() ;
+ $result = array_merge($r,$a);
+ return array_merge($r,$a);
+ }
+
+ function get_inserts($match,$translation) {
+ $inserts = array();
+
+ // replace embedded macros
+ if(preg_match_all('/#@(.*?)@#/',$match,$inserts)) {
+ $keys = $inserts[1];
+ $pats = $inserts[0];
+
+ for($i=0; $i<count($keys); $i++) {
+ $insert = $this->macros[$keys[$i]];
+ if($translation ||strpos($keys[$i], 'LANG_') !== false) {
+ list($prefix,$trans) = explode('_',$keys[$i],2);
+ $_insert = $this->translations[$trans];
+ if($_insert) $insert =$_insert;
+ }
+ $match = str_replace($pats[$i],$insert,$match);
+ }
+
+ } // end replace embedded macros
+
+
+ $entities = getEntities();
+ $e_keys = array_keys($entities);
+ $e_values = array_values($entities);
+ $match = str_replace($e_keys,$e_values,$match);
+
+ return $match;
+ }
+
+ function get_std_replacements() {
+ if(!$this->getConf('stdreplace')) return array();
+ global $conf;
+ global $INFO;
+ global $ID;
+
+ $file = noNS($ID);
+ $page = cleanID($file) ;
+
+ $names =array(
+ 'ID',
+ 'NS',
+ 'FILE',
+ '!FILE',
+ '!FILE!',
+ 'PAGE',
+ '!PAGE',
+ '!!PAGE',
+ '!PAGE!',
+ 'USER',
+ 'DATE',
+ '_ID_'
+ );
+
+ $values = array(
+ $ID,
+ getNS($ID),
+ $file,
+ utf8_ucfirst($file),
+ utf8_strtoupper($file),
+ $page,
+ utf8_ucfirst($page),
+ utf8_ucwords($page),
+ utf8_strtoupper($page),
+ $_SERVER['REMOTE_USER'],
+ strftime($conf['dformat'], time()),
+ '_ID_'
+ );
+ $std_replacements = array();
+ for($i=0; $i<count($names) ; $i++) {
+ $std_replacements[$names[$i]] = $values[$i];
+ }
+
+ return $std_replacements;
+}
+
+ function write_debug($what, $screen = false) {
+ return;
+ $what=print_r($what,true);
+ if($screen) {
+ msg('<pre>' . $what . '</pre>');
+ return;
+ }
+ $handle=fopen("textinsert.txt",'a');
+ fwrite($handle,"$what\n");
+ fclose($handle);
+ }
+}
+
+
diff --git a/platform/www/lib/plugins/textinsert/version b/platform/www/lib/plugins/textinsert/version
new file mode 100644
index 0000000..4fb8186
--- /dev/null
+++ b/platform/www/lib/plugins/textinsert/version
@@ -0,0 +1,2 @@
+19-Oct_03-20_19
+
diff --git a/platform/www/lib/plugins/translation/.travis.yml b/platform/www/lib/plugins/translation/.travis.yml
new file mode 100644
index 0000000..c7eb5a6
--- /dev/null
+++ b/platform/www/lib/plugins/translation/.travis.yml
@@ -0,0 +1,13 @@
+# Config file for travis-ci.org
+
+language: php
+php:
+ - "7.1"
+ - "7.0"
+ - "5.6"
+env:
+ - DOKUWIKI=master
+ - DOKUWIKI=stable
+before_install: wget https://raw.github.com/splitbrain/dokuwiki-travis/master/travis.sh
+install: sh travis.sh
+script: cd _test && phpunit --stderr --group plugin_translation
diff --git a/platform/www/lib/plugins/translation/README b/platform/www/lib/plugins/translation/README
new file mode 100644
index 0000000..1a5b5ef
--- /dev/null
+++ b/platform/www/lib/plugins/translation/README
@@ -0,0 +1,25 @@
+translation Plugin for DokuWiki
+
+All documentation for this plugin can be found at
+http://www.dokuwiki.org/plugin:translation
+
+If you install this plugin manually, make sure it is installed in
+lib/plugins/translation/ - if the folder is called different it
+will not work!
+
+Please refer to http://www.dokuwiki.org/plugins for additional info
+on how to install plugins in DokuWiki.
+
+----
+Copyright (C) Andreas Gohr <andi@splitbrain.org>
+
+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; version 2 of the License
+
+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.
+
+See the COPYING file in your DokuWiki folder for details
diff --git a/platform/www/lib/plugins/translation/_test/basic.test.php b/platform/www/lib/plugins/translation/_test/basic.test.php
new file mode 100644
index 0000000..870c7a7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/_test/basic.test.php
@@ -0,0 +1,113 @@
+<?php
+
+/**
+ * General tests for the translation plugin
+ *
+ * @group plugin_translation
+ * @group plugins
+ */
+class basic_plugin_translation_test extends DokuWikiTest {
+
+ protected $pluginsEnabled = array('translation');
+
+ public static function buildTransID_testdata() {
+ return array(
+ array(
+ 'en',
+ 'ns:page',
+ 'de es',
+ array(':ns:page', 'en'),
+ ),
+ array(
+ '',
+ 'ns:page',
+ 'de es',
+ array(':ns:page', 'en'),
+ ),
+ array(
+ 'de',
+ 'ns:page',
+ 'de es',
+ array(':de:ns:page', 'de'),
+ ),
+ );
+ }
+
+ /**
+ * @dataProvider buildTransID_testdata
+ *
+ * @param $inputLang
+ * @param $inputID
+ * @param $translationsOption
+ * @param $expected
+ */
+ public function test_buildTransID($inputLang, $inputID, $translationsOption, $expected) {
+ global $conf;
+ $conf['plugin']['translation']['translations'] = $translationsOption;
+ /** @var helper_plugin_translation $helper */
+ $helper = plugin_load('helper', 'translation', true);
+
+ $actual_result = $helper->buildTransID($inputLang, $inputID);
+
+ $this->assertEquals($expected, $actual_result);
+ }
+
+
+ public static function redirectStart_testdata() {
+ return array(
+ array(
+ 'start',
+ 'de es',
+ 'de,en-US;q=0.8,en;q=0.5,fr;q=0.3',
+ ':de:start',
+ 'redirect to translated page',
+ ),
+ array(
+ 'start',
+ 'de es',
+ 'en-US,de;q=0.8,en;q=0.5,fr;q=0.3',
+ array(),
+ 'do not redirect if basic namespace is correct lang',
+ ),
+ array(
+ 'de:start',
+ 'en de es',
+ 'en-US,en;q=0.8,fr;q=0.5',
+ array(),
+ 'do not redirect anything other than exactly $conf[\'start\']',
+ ),
+ );
+ }
+
+
+ /**
+ * @dataProvider redirectStart_testdata
+ *
+ * @param $input
+ * @param $translationsOption
+ * @param $httpAcceptHeader
+ * @param $expected
+ */
+ public function test_redirectStart($input, $translationsOption, $httpAcceptHeader, $expected, $msg) {
+ global $conf;
+ $conf['plugin']['translation']['translations'] = $translationsOption;
+ $conf['plugin']['translation']['redirectstart'] = 1;
+
+ /** @var helper_plugin_translation $helper */
+ $helper = plugin_load('helper', 'translation');
+ $helper->loadTranslationNamespaces();
+
+ $request = new TestRequest();
+ $request->setServer('HTTP_ACCEPT_LANGUAGE', $httpAcceptHeader);
+
+ $response = $request->get(array('id' => $input));
+ $actual = $response->getHeader('Location');
+
+ if (is_string($actual)) {
+ list(, $actual) = explode('doku.php?id=', $actual);
+ }
+
+ $this->assertEquals($expected, $actual, $msg);
+ }
+
+}
diff --git a/platform/www/lib/plugins/translation/_test/general.test.php b/platform/www/lib/plugins/translation/_test/general.test.php
new file mode 100644
index 0000000..ec1675c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/_test/general.test.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * General tests for the translation plugin
+ *
+ * @group plugin_translation
+ * @group plugins
+ */
+class general_plugin_translation_test extends DokuWikiTest {
+
+ /**
+ * Simple test to make sure the plugin.info.txt is in correct format
+ */
+ public function test_plugininfo() {
+ $file = __DIR__.'/../plugin.info.txt';
+ $this->assertFileExists($file);
+
+ $info = confToHash($file);
+
+ $this->assertArrayHasKey('base', $info);
+ $this->assertArrayHasKey('author', $info);
+ $this->assertArrayHasKey('email', $info);
+ $this->assertArrayHasKey('date', $info);
+ $this->assertArrayHasKey('name', $info);
+ $this->assertArrayHasKey('desc', $info);
+ $this->assertArrayHasKey('url', $info);
+
+ $this->assertEquals('translation', $info['base']);
+ $this->assertRegExp('/^https?:\/\//', $info['url']);
+ $this->assertTrue(mail_isvalid($info['email']));
+ $this->assertRegExp('/^\d\d\d\d-\d\d-\d\d$/', $info['date']);
+ $this->assertTrue(false !== strtotime($info['date']));
+ }
+
+ /**
+ * Test to ensure that every conf['...'] entry in conf/default.php has a corresponding meta['...'] entry in
+ * conf/metadata.php.
+ */
+ public function test_plugin_conf() {
+ $conf_file = __DIR__.'/../conf/default.php';
+ if (file_exists($conf_file)){
+ include($conf_file);
+ }
+ $meta_file = __DIR__.'/../conf/metadata.php';
+ if (file_exists($meta_file)) {
+ include($meta_file);
+ }
+
+ $this->assertEquals(gettype($conf), gettype($meta),'Both ' . DOKU_PLUGIN . 'translation/conf/default.php and ' . DOKU_PLUGIN . 'translation/conf/metadata.php have to exist and contain the same keys.');
+
+ if (gettype($conf) != 'NULL' && gettype($meta) != 'NULL') {
+ foreach($conf as $key => $value) {
+ $this->assertArrayHasKey($key, $meta, 'Key $meta[\'' . $key . '\'] missing in ' . DOKU_PLUGIN . 'translation/conf/metadata.php');
+ }
+
+ foreach($meta as $key => $value) {
+ $this->assertArrayHasKey($key, $conf, 'Key $conf[\'' . $key . '\'] missing in ' . DOKU_PLUGIN . 'translation/conf/default.php');
+ }
+ }
+
+ }
+}
diff --git a/platform/www/lib/plugins/translation/action.php b/platform/www/lib/plugins/translation/action.php
new file mode 100644
index 0000000..6c79a70
--- /dev/null
+++ b/platform/www/lib/plugins/translation/action.php
@@ -0,0 +1,302 @@
+<?php
+/**
+ * Translation Plugin: Simple multilanguage plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Guy Brand <gb@isis.u-strasbg.fr>
+ */
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Class action_plugin_translation
+ */
+class action_plugin_translation extends DokuWiki_Action_Plugin {
+
+ /**
+ * For the helper plugin
+ * @var helper_plugin_translation
+ */
+ var $helper = null;
+
+ var $locale;
+
+ /**
+ * Constructor. Load helper plugin
+ */
+ function __construct() {
+ $this->helper = plugin_load('helper', 'translation');
+ }
+
+ /**
+ * Registers a callback function for a given event
+ *
+ * @param Doku_Event_Handler $controller
+ */
+ function register(Doku_Event_Handler $controller) {
+ $scriptName = basename($_SERVER['PHP_SELF']);
+
+ // should the lang be applied to UI?
+ if($this->getConf('translateui')) {
+ switch($scriptName) {
+ case 'js.php':
+ $controller->register_hook('INIT_LANG_LOAD', 'BEFORE', $this, 'translation_js');
+ $controller->register_hook('JS_CACHE_USE', 'BEFORE', $this, 'translation_jscache');
+ break;
+
+ case 'ajax.php':
+ $controller->register_hook('INIT_LANG_LOAD', 'BEFORE', $this, 'translate_media_manager');
+ break;
+
+ case 'mediamanager.php':
+ $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'setJsCacheKey');
+ break;
+
+ default:
+ $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'setJsCacheKey');
+ }
+ }
+
+ if($scriptName !== 'js.php' && $scriptName !== 'ajax.php') {
+ $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'translation_hook');
+ $controller->register_hook('DETAIL_STARTED', 'BEFORE', $this, 'translation_hook');
+ $controller->register_hook('MEDIAMANAGER_STARTED', 'BEFORE', $this, 'translation_hook');
+ }
+
+ $controller->register_hook('SEARCH_QUERY_PAGELOOKUP', 'AFTER', $this, 'translation_search');
+ $controller->register_hook('COMMON_PAGETPL_LOAD', 'AFTER', $this, 'page_template_replacement');
+ }
+
+ /**
+ * Hook Callback. Make current language available as page template placeholder and handle
+ * original language copying
+ *
+ * @param Doku_Event $event
+ * @param $args
+ */
+ function page_template_replacement(Doku_Event $event, $args) {
+ global $ID;
+
+ // load orginal content as template?
+ if($this->getConf('copytrans') && $this->helper->istranslatable($ID, false)) {
+ // look for existing translations
+ $translations = $this->helper->getAvailableTranslations($ID);
+ if($translations) {
+ // find original language (might've been provided via parameter or use first translation)
+ $orig = (string) $_REQUEST['fromlang'];
+ if(!$orig) $orig = array_shift(array_keys($translations));
+
+ // load file
+ $origfile = $translations[$orig];
+ $event->data['tpl'] = io_readFile(wikiFN($origfile));
+
+ // prefix with warning
+ $warn = io_readFile($this->localFN('totranslate'));
+ if($warn) $warn .= "\n\n";
+ $event->data['tpl'] = $warn . $event->data['tpl'];
+
+ // show user a choice of translations if any
+ if(count($translations) > 1) {
+ $links = array();
+ foreach($translations as $t => $l) {
+ $links[] = '<a href="' . wl($ID, array('do' => 'edit', 'fromlang' => $t)) . '">' . $this->helper->getLocalName($t) . '</a>';
+ }
+
+ msg(
+ sprintf(
+ $this->getLang('transloaded'),
+ $this->helper->getLocalName($orig),
+ join(', ', $links)
+ )
+ );
+ }
+
+ }
+ }
+
+ // apply placeholders
+ $event->data['tpl'] = str_replace('@LANG@', $this->helper->realLC(''), $event->data['tpl']);
+ $event->data['tpl'] = str_replace('@TRANS@', $this->helper->getLangPart($ID), $event->data['tpl']);
+ }
+
+ /**
+ * Hook Callback. Load correct translation when loading JavaScript
+ *
+ * @param Doku_Event $event
+ * @param $args
+ */
+ function translation_js(Doku_Event $event, $args) {
+ global $conf;
+ if(!isset($_GET['lang'])) return;
+ if(!in_array($_GET['lang'], $this->helper->translations)) return;
+ $lang = $_GET['lang'];
+ $event->data = $lang;
+ $conf['lang'] = $lang;
+ }
+
+ /**
+ * Hook Callback. Pass language code to JavaScript dispatcher
+ *
+ * @param Doku_Event $event
+ * @param $args
+ * @return bool
+ */
+ function setJsCacheKey(Doku_Event $event, $args) {
+ if(!isset($this->locale)) return false;
+ $count = count($event->data['script']);
+ for($i = 0; $i < $count; $i++) {
+ if(strpos($event->data['script'][$i]['src'], '/lib/exe/js.php') !== false) {
+ $event->data['script'][$i]['src'] .= '&lang=' . hsc($this->locale);
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Hook Callback. Make sure the JavaScript is translation dependent
+ *
+ * @param Doku_Event $event
+ * @param $args
+ */
+ function translation_jscache(Doku_Event $event, $args) {
+ if(!isset($_GET['lang'])) return;
+ if(!in_array($_GET['lang'], $this->helper->translations)) return;
+
+ $lang = $_GET['lang'];
+ // reuse the constructor to reinitialize the cache key
+ if(method_exists($event->data, '__construct')) {
+ // New PHP 5 style constructor
+ $event->data->__construct(
+ $event->data->key . $lang,
+ $event->data->ext
+ );
+ } else {
+ // Old PHP 4 style constructor - deprecated
+ $event->data->cache(
+ $event->data->key . $lang,
+ $event->data->ext
+ );
+ }
+ }
+
+ /**
+ * Hook Callback. Translate the AJAX loaded media manager
+ *
+ * @param Doku_Event $event
+ * @param $args
+ */
+ function translate_media_manager(Doku_Event $event, $args) {
+ global $conf;
+ if(isset($_REQUEST['ID'])) {
+ $id = getID();
+ $lc = $this->helper->getLangPart($id);
+ } elseif(isset($_SESSION[DOKU_COOKIE]['translationlc'])) {
+ $lc = $_SESSION[DOKU_COOKIE]['translationlc'];
+ } else {
+ return;
+ }
+ if(!$lc) return;
+
+ $conf['lang'] = $lc;
+ $event->data = $lc;
+ }
+
+ /**
+ * Hook Callback. Change the UI language in foreign language namespaces
+ *
+ * @param Doku_Event $event
+ * @param $args
+ * @return bool
+ */
+ function translation_hook(Doku_Event $event, $args) {
+ global $ID;
+ /** @noinspection PhpUnusedLocalVariableInspection we include the language file later on */
+ global $lang;
+ global $conf;
+ global $ACT;
+ // redirect away from start page?
+ if($this->getConf('redirectstart') && $ID == $conf['start'] && $ACT == 'show') {
+ $lc = $this->helper->getBrowserLang();
+
+ list($translatedStartpage,) = $this->helper->buildTransID($lc, $conf['start']);
+ if (cleanID($translatedStartpage) !== cleanID($ID)) {
+ send_redirect(wl($translatedStartpage, '', true));
+ }
+ }
+
+ // check if we are in a foreign language namespace
+ $lc = $this->helper->getLangPart($ID);
+
+ // store language in session (for page related views only)
+ if(in_array($ACT, array('show', 'recent', 'diff', 'edit', 'preview', 'source', 'subscribe'))) {
+ $_SESSION[DOKU_COOKIE]['translationlc'] = $lc;
+ }
+ if(!$lc) $lc = $_SESSION[DOKU_COOKIE]['translationlc'];
+ if(!$lc) return false;
+ $this->locale = $lc;
+
+ if(!$this->getConf('translateui')) {
+ return true;
+ }
+
+ if(file_exists(DOKU_INC . 'inc/lang/' . $lc . '/lang.php')) {
+ require(DOKU_INC . 'inc/lang/' . $lc . '/lang.php');
+ }
+ $conf['lang_before_translation'] = $conf['lang']; //store for later access in syntax plugin
+ $conf['lang'] = $lc;
+
+ return true;
+ }
+
+ /**
+ * Hook Callback. Resort page match results so that results are ordered by translation, having the
+ * default language first
+ *
+ * @param Doku_Event $event
+ * @param $args
+ */
+ function translation_search(Doku_Event $event, $args) {
+
+ if($event->data['has_titles']) {
+ // sort into translation slots
+ $res = array();
+ foreach($event->result as $r => $t) {
+ $tr = $this->helper->getLangPart($r);
+ if(!is_array($res["x$tr"])) $res["x$tr"] = array();
+ $res["x$tr"][] = array($r, $t);
+ }
+ // sort by translations
+ ksort($res);
+ // combine
+ $event->result = array();
+ foreach($res as $r) {
+ foreach($r as $l) {
+ $event->result[$l[0]] = $l[1];
+ }
+ }
+ } else {
+ # legacy support for old DokuWiki hooks
+
+ // sort into translation slots
+ $res = array();
+ foreach($event->result as $r) {
+ $tr = $this->helper->getLangPart($r);
+ if(!is_array($res["x$tr"])) $res["x$tr"] = array();
+ $res["x$tr"][] = $r;
+ }
+ // sort by translations
+ ksort($res);
+ // combine
+ $event->result = array();
+ foreach($res as $r) {
+ $event->result = array_merge($event->result, $r);
+ }
+ }
+ }
+
+}
+
+//Setup VIM: ex: et ts=4 :
diff --git a/platform/www/lib/plugins/translation/admin.php b/platform/www/lib/plugins/translation/admin.php
new file mode 100644
index 0000000..f8d95a1
--- /dev/null
+++ b/platform/www/lib/plugins/translation/admin.php
@@ -0,0 +1,101 @@
+<?php
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+class admin_plugin_translation extends DokuWiki_Admin_Plugin {
+ function forAdminOnly() {
+ return false;
+ }
+
+ function handle() {
+ }
+
+ function html() {
+
+ /** @var helper_plugin_translation $helper */
+ $helper = plugin_load('helper', "translation");
+ $default_language = $helper->defaultlang;
+
+ /** @var Doku_Renderer_xhtml $xhtml_renderer */
+ $xhtml_renderer = p_get_renderer('xhtml');
+
+ echo "<h1>" . $this->getLang("menu") . "</h1>";
+ echo "<table id='outdated_translations' class=\"inline\">";
+ echo "<tr><th>default: $default_language</th>";
+ if ($this->getConf('show_path')) {
+ echo "<th>" . $this->getLang('path') . "</th>";
+ }
+ foreach ($helper->translations as $t) {
+ if($t === $default_language) {
+ continue;
+ }
+ echo "<th>$t</th>";
+ }
+ echo "</tr>";
+
+ $pages = $this->getAllPages();
+ foreach ($pages as $page) {
+ if (!$helper->getLangPart($page["id"]) === $default_language ||
+ !$helper->istranslatable($page["id"], false) ||
+ !page_exists($page["id"])
+ ) {
+ continue;
+ }
+ // We have an existing and translatable page in the default language
+ $showRow = false;
+ $row = "<tr><td>" . $xhtml_renderer->internallink($page['id'],null,null,true) . "</td>";
+ if ($this->getConf('show_path')) {
+ $row .= "<td>" . $xhtml_renderer->internallink($page['id'],$page['id'],null,true) . "</td>";
+ }
+
+ list($lc, $idpart) = $helper->getTransParts($page["id"]);
+
+ foreach ($helper->translations as $t) {
+ if ($t === $default_language) {
+ continue;
+ }
+
+ list($translID, $name) = $helper->buildTransID($t, $idpart);
+
+
+ $difflink = '';
+ if(!page_exists($translID)) {
+ $class = "missing";
+ $title = $this->getLang("missing");
+ $showRow = true;
+ } else {
+ $translfn = wikiFN($translID);
+ if($page['mtime'] > filemtime($translfn)) {
+ $class = "outdated";
+ $difflink = " <a href='";
+ $difflink .= $helper->getOldDiffLink($page["id"], $page['mtime']);
+ $difflink .= "'>(diff)</a>";
+ $title = $this->getLang('old');
+ $showRow = true;
+ } else {
+ $class = "current";
+ $title = $this->getLang('current');
+ }
+ }
+ $row .= "<td class='$class'>" . $xhtml_renderer->internallink($translID,$title,null,true) . $difflink . "</td>";
+ }
+ $row .= "</tr>";
+
+ if ($showRow) {
+ echo $row;
+ }
+
+ }
+ echo "</table>";
+
+ }
+
+ function getAllPages() {
+ $namespace = $this->getConf("translationns");
+ $dir = dirname(wikiFN("$namespace:foo"));
+ $pages = array();
+ search($pages, $dir, 'search_allpages',array());
+ return $pages;
+ }
+}
diff --git a/platform/www/lib/plugins/translation/admin.svg b/platform/www/lib/plugins/translation/admin.svg
new file mode 100644
index 0000000..c3d51ee
--- /dev/null
+++ b/platform/www/lib/plugins/translation/admin.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12.87 15.07l-2.54-2.51.03-.03A17.52 17.52 0 0 0 14.07 6H17V4h-7V2H8v2H1v2h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04M18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12m-2.62 7l1.62-4.33L19.12 17h-3.24z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/conf/default.php b/platform/www/lib/plugins/translation/conf/default.php
new file mode 100644
index 0000000..3a20131
--- /dev/null
+++ b/platform/www/lib/plugins/translation/conf/default.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Default options for the translation plugin
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+$conf['translations'] = '';
+$conf['translationns'] = '';
+$conf['skiptrans'] = '';
+$conf['dropdown'] = 0;
+$conf['translateui'] = 0;
+$conf['redirectstart'] = 0;
+$conf['checkage'] = 0;
+$conf['about'] = '';
+$conf['localabout'] = 0;
+$conf['display'] = 'langcode,title';
+$conf['copytrans'] = 0;
+$conf['show_path'] = 1;
diff --git a/platform/www/lib/plugins/translation/conf/metadata.php b/platform/www/lib/plugins/translation/conf/metadata.php
new file mode 100644
index 0000000..d9c4d22
--- /dev/null
+++ b/platform/www/lib/plugins/translation/conf/metadata.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Options for the translation plugin
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+$meta['translations'] = array('string','_pattern' => '/^(|[a-zA-Z\- ,]+)$/');
+$meta['translationns'] = array('string','_pattern' => '/^(|[\w:\-]+)$/');
+$meta['skiptrans'] = array('string');
+$meta['dropdown'] = array('onoff');
+$meta['display'] = array('multicheckbox',
+ '_choices' => array('langcode','name','flag','title','twolines'));
+$meta['translateui'] = array('onoff');
+$meta['redirectstart'] = array('onoff');
+$meta['checkage'] = array('onoff');
+$meta['about'] = array('string','_pattern' => '/^(|[\w:\-]+)$/');
+$meta['localabout'] = array('onoff');
+$meta['copytrans'] = array('onoff');
+$meta['show_path'] = array('onoff');
+
diff --git a/platform/www/lib/plugins/translation/flags/af.gif b/platform/www/lib/plugins/translation/flags/af.gif
new file mode 100644
index 0000000..9889408
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/af.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/ar.gif b/platform/www/lib/plugins/translation/flags/ar.gif
new file mode 100644
index 0000000..179961b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/ar.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/da.gif b/platform/www/lib/plugins/translation/flags/da.gif
new file mode 100644
index 0000000..03e75bd
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/da.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/de.gif b/platform/www/lib/plugins/translation/flags/de.gif
new file mode 100644
index 0000000..75728dd
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/de.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/el.gif b/platform/www/lib/plugins/translation/flags/el.gif
new file mode 100644
index 0000000..b4c8c04
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/el.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/en.gif b/platform/www/lib/plugins/translation/flags/en.gif
new file mode 100644
index 0000000..3c6bce1
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/en.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/es.gif b/platform/www/lib/plugins/translation/flags/es.gif
new file mode 100644
index 0000000..c27d65e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/es.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/et.gif b/platform/www/lib/plugins/translation/flags/et.gif
new file mode 100644
index 0000000..9397a2d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/et.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/fa.gif b/platform/www/lib/plugins/translation/flags/fa.gif
new file mode 100644
index 0000000..156040f
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/fa.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/fr.gif b/platform/www/lib/plugins/translation/flags/fr.gif
new file mode 100644
index 0000000..43d0b80
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/fr.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/ga.gif b/platform/www/lib/plugins/translation/flags/ga.gif
new file mode 100644
index 0000000..506ad28
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/ga.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/he.gif b/platform/www/lib/plugins/translation/flags/he.gif
new file mode 100644
index 0000000..c8483ae
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/he.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/hu.gif b/platform/www/lib/plugins/translation/flags/hu.gif
new file mode 100644
index 0000000..6142d86
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/hu.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/it.gif b/platform/www/lib/plugins/translation/flags/it.gif
new file mode 100644
index 0000000..d79e90e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/it.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/ja.gif b/platform/www/lib/plugins/translation/flags/ja.gif
new file mode 100644
index 0000000..444c1d0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/ja.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/ko.gif b/platform/www/lib/plugins/translation/flags/ko.gif
new file mode 100644
index 0000000..1cddbe7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/ko.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ad.gif b/platform/www/lib/plugins/translation/flags/more/ad.gif
new file mode 100644
index 0000000..57b4997
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ad.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ae.gif b/platform/www/lib/plugins/translation/flags/more/ae.gif
new file mode 100644
index 0000000..78d15b6
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ae.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ag.gif b/platform/www/lib/plugins/translation/flags/more/ag.gif
new file mode 100644
index 0000000..48f8e7b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ag.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ai.gif b/platform/www/lib/plugins/translation/flags/more/ai.gif
new file mode 100644
index 0000000..1cbc579
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ai.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/al.gif b/platform/www/lib/plugins/translation/flags/more/al.gif
new file mode 100644
index 0000000..c44fe0a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/al.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/am.gif b/platform/www/lib/plugins/translation/flags/more/am.gif
new file mode 100644
index 0000000..2915e30
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/am.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/an.gif b/platform/www/lib/plugins/translation/flags/more/an.gif
new file mode 100644
index 0000000..cb570c6
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/an.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ao.gif b/platform/www/lib/plugins/translation/flags/more/ao.gif
new file mode 100644
index 0000000..8c854fa
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ao.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ar.gif b/platform/www/lib/plugins/translation/flags/more/ar.gif
new file mode 100644
index 0000000..a9f71f7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ar.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/as.gif b/platform/www/lib/plugins/translation/flags/more/as.gif
new file mode 100644
index 0000000..d776ec2
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/as.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/at.gif b/platform/www/lib/plugins/translation/flags/more/at.gif
new file mode 100644
index 0000000..87e1217
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/at.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/au.gif b/platform/www/lib/plugins/translation/flags/more/au.gif
new file mode 100644
index 0000000..5269c6a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/au.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/aw.gif b/platform/www/lib/plugins/translation/flags/more/aw.gif
new file mode 100644
index 0000000..27fdb4d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/aw.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ax.gif b/platform/www/lib/plugins/translation/flags/more/ax.gif
new file mode 100644
index 0000000..0ceb684
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ax.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/az.gif b/platform/www/lib/plugins/translation/flags/more/az.gif
new file mode 100644
index 0000000..d771618
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/az.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ba.gif b/platform/www/lib/plugins/translation/flags/more/ba.gif
new file mode 100644
index 0000000..9bf5f0a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ba.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bb.gif b/platform/www/lib/plugins/translation/flags/more/bb.gif
new file mode 100644
index 0000000..b7d08e5
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bb.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bd.gif b/platform/www/lib/plugins/translation/flags/more/bd.gif
new file mode 100644
index 0000000..0fd27ec
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bd.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/be.gif b/platform/www/lib/plugins/translation/flags/more/be.gif
new file mode 100644
index 0000000..ae09bfb
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/be.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bf.gif b/platform/www/lib/plugins/translation/flags/more/bf.gif
new file mode 100644
index 0000000..9d6772c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bf.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bg.gif b/platform/www/lib/plugins/translation/flags/more/bg.gif
new file mode 100644
index 0000000..11cf8ff
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bg.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bh.gif b/platform/www/lib/plugins/translation/flags/more/bh.gif
new file mode 100644
index 0000000..56aa72b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bh.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bi.gif b/platform/www/lib/plugins/translation/flags/more/bi.gif
new file mode 100644
index 0000000..6e2cbe1
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bi.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bj.gif b/platform/www/lib/plugins/translation/flags/more/bj.gif
new file mode 100644
index 0000000..e676116
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bj.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/blankflag.gif b/platform/www/lib/plugins/translation/flags/more/blankflag.gif
new file mode 100644
index 0000000..9935f82
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/blankflag.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bm.gif b/platform/www/lib/plugins/translation/flags/more/bm.gif
new file mode 100644
index 0000000..9feb87b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bn.gif b/platform/www/lib/plugins/translation/flags/more/bn.gif
new file mode 100644
index 0000000..b7b6b0f
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bn.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bo.gif b/platform/www/lib/plugins/translation/flags/more/bo.gif
new file mode 100644
index 0000000..4844f85
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bo.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bs.gif b/platform/www/lib/plugins/translation/flags/more/bs.gif
new file mode 100644
index 0000000..c0a741e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bs.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bt.gif b/platform/www/lib/plugins/translation/flags/more/bt.gif
new file mode 100644
index 0000000..abe2f3c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bt.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bv.gif b/platform/www/lib/plugins/translation/flags/more/bv.gif
new file mode 100644
index 0000000..6202d1f
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bv.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bw.gif b/platform/www/lib/plugins/translation/flags/more/bw.gif
new file mode 100644
index 0000000..986ab63
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bw.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/by.gif b/platform/www/lib/plugins/translation/flags/more/by.gif
new file mode 100644
index 0000000..43ffcd4
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/by.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/bz.gif b/platform/www/lib/plugins/translation/flags/more/bz.gif
new file mode 100644
index 0000000..791737f
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/bz.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ca.gif b/platform/www/lib/plugins/translation/flags/more/ca.gif
new file mode 100644
index 0000000..457d966
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ca.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/catalonia.gif b/platform/www/lib/plugins/translation/flags/more/catalonia.gif
new file mode 100644
index 0000000..73df9a0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/catalonia.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cc.gif b/platform/www/lib/plugins/translation/flags/more/cc.gif
new file mode 100644
index 0000000..3f78327
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cc.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cd.gif b/platform/www/lib/plugins/translation/flags/more/cd.gif
new file mode 100644
index 0000000..1df717a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cd.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cf.gif b/platform/www/lib/plugins/translation/flags/more/cf.gif
new file mode 100644
index 0000000..35787ca
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cf.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cg.gif b/platform/www/lib/plugins/translation/flags/more/cg.gif
new file mode 100644
index 0000000..e0a62a5
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cg.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ch.gif b/platform/www/lib/plugins/translation/flags/more/ch.gif
new file mode 100644
index 0000000..d5c0e5b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ch.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ci.gif b/platform/www/lib/plugins/translation/flags/more/ci.gif
new file mode 100644
index 0000000..844120a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ci.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ck.gif b/platform/www/lib/plugins/translation/flags/more/ck.gif
new file mode 100644
index 0000000..2edb739
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ck.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cl.gif b/platform/www/lib/plugins/translation/flags/more/cl.gif
new file mode 100644
index 0000000..cbc370e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cl.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cm.gif b/platform/www/lib/plugins/translation/flags/more/cm.gif
new file mode 100644
index 0000000..1fb102b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/co.gif b/platform/www/lib/plugins/translation/flags/more/co.gif
new file mode 100644
index 0000000..d0e15ca
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/co.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cr.gif b/platform/www/lib/plugins/translation/flags/more/cr.gif
new file mode 100644
index 0000000..0728dd6
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cr.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cs.gif b/platform/www/lib/plugins/translation/flags/more/cs.gif
new file mode 100644
index 0000000..101db64
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cs.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cu.gif b/platform/www/lib/plugins/translation/flags/more/cu.gif
new file mode 100644
index 0000000..291255c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cu.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cv.gif b/platform/www/lib/plugins/translation/flags/more/cv.gif
new file mode 100644
index 0000000..43c6c6c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cv.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cx.gif b/platform/www/lib/plugins/translation/flags/more/cx.gif
new file mode 100644
index 0000000..a5b4308
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cx.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cy.gif b/platform/www/lib/plugins/translation/flags/more/cy.gif
new file mode 100644
index 0000000..35c661e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cy.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/cz.gif b/platform/www/lib/plugins/translation/flags/more/cz.gif
new file mode 100644
index 0000000..0a605e5
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/cz.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/dj.gif b/platform/www/lib/plugins/translation/flags/more/dj.gif
new file mode 100644
index 0000000..212406d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/dj.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/dm.gif b/platform/www/lib/plugins/translation/flags/more/dm.gif
new file mode 100644
index 0000000..2f87f3c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/dm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/do.gif b/platform/www/lib/plugins/translation/flags/more/do.gif
new file mode 100644
index 0000000..f7d0bad
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/do.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/dz.gif b/platform/www/lib/plugins/translation/flags/more/dz.gif
new file mode 100644
index 0000000..ed580a7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/dz.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ec.gif b/platform/www/lib/plugins/translation/flags/more/ec.gif
new file mode 100644
index 0000000..9e41e0e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ec.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/eg.gif b/platform/www/lib/plugins/translation/flags/more/eg.gif
new file mode 100644
index 0000000..6857c7d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/eg.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/eh.gif b/platform/www/lib/plugins/translation/flags/more/eh.gif
new file mode 100644
index 0000000..dd0391c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/eh.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/england.gif b/platform/www/lib/plugins/translation/flags/more/england.gif
new file mode 100644
index 0000000..933a4f0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/england.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/er.gif b/platform/www/lib/plugins/translation/flags/more/er.gif
new file mode 100644
index 0000000..3d4d612
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/er.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/et.gif b/platform/www/lib/plugins/translation/flags/more/et.gif
new file mode 100644
index 0000000..f77995d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/et.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/europeanunion.gif b/platform/www/lib/plugins/translation/flags/more/europeanunion.gif
new file mode 100644
index 0000000..28a762a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/europeanunion.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/fam.gif b/platform/www/lib/plugins/translation/flags/more/fam.gif
new file mode 100644
index 0000000..7d52885
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/fam.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/fi.gif b/platform/www/lib/plugins/translation/flags/more/fi.gif
new file mode 100644
index 0000000..8d3a191
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/fi.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/fj.gif b/platform/www/lib/plugins/translation/flags/more/fj.gif
new file mode 100644
index 0000000..486151c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/fj.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/fk.gif b/platform/www/lib/plugins/translation/flags/more/fk.gif
new file mode 100644
index 0000000..37b5ecf
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/fk.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/fm.gif b/platform/www/lib/plugins/translation/flags/more/fm.gif
new file mode 100644
index 0000000..7f8723b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/fm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/fo.gif b/platform/www/lib/plugins/translation/flags/more/fo.gif
new file mode 100644
index 0000000..4a90fc0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/fo.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ga.gif b/platform/www/lib/plugins/translation/flags/more/ga.gif
new file mode 100644
index 0000000..23fd5f0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ga.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gd.gif b/platform/www/lib/plugins/translation/flags/more/gd.gif
new file mode 100644
index 0000000..25ea312
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gd.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ge.gif b/platform/www/lib/plugins/translation/flags/more/ge.gif
new file mode 100644
index 0000000..faa7f12
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ge.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gf.gif b/platform/www/lib/plugins/translation/flags/more/gf.gif
new file mode 100644
index 0000000..43d0b80
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gf.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gh.gif b/platform/www/lib/plugins/translation/flags/more/gh.gif
new file mode 100644
index 0000000..273fb7d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gh.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gi.gif b/platform/www/lib/plugins/translation/flags/more/gi.gif
new file mode 100644
index 0000000..7b1984b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gi.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gl.gif b/platform/www/lib/plugins/translation/flags/more/gl.gif
new file mode 100644
index 0000000..ef445be
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gl.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gm.gif b/platform/www/lib/plugins/translation/flags/more/gm.gif
new file mode 100644
index 0000000..6847c5a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gn.gif b/platform/www/lib/plugins/translation/flags/more/gn.gif
new file mode 100644
index 0000000..a982ac6
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gn.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gp.gif b/platform/www/lib/plugins/translation/flags/more/gp.gif
new file mode 100644
index 0000000..31166db
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gp.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gq.gif b/platform/www/lib/plugins/translation/flags/more/gq.gif
new file mode 100644
index 0000000..8b4e0cc
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gq.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gs.gif b/platform/www/lib/plugins/translation/flags/more/gs.gif
new file mode 100644
index 0000000..ccc96ec
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gs.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gt.gif b/platform/www/lib/plugins/translation/flags/more/gt.gif
new file mode 100644
index 0000000..7e94d1d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gt.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gu.gif b/platform/www/lib/plugins/translation/flags/more/gu.gif
new file mode 100644
index 0000000..eafef68
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gu.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gw.gif b/platform/www/lib/plugins/translation/flags/more/gw.gif
new file mode 100644
index 0000000..55f7571
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gw.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/gy.gif b/platform/www/lib/plugins/translation/flags/more/gy.gif
new file mode 100644
index 0000000..1cb4cd7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/gy.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/hk.gif b/platform/www/lib/plugins/translation/flags/more/hk.gif
new file mode 100644
index 0000000..798af96
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/hk.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/hm.gif b/platform/www/lib/plugins/translation/flags/more/hm.gif
new file mode 100644
index 0000000..5269c6a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/hm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/hn.gif b/platform/www/lib/plugins/translation/flags/more/hn.gif
new file mode 100644
index 0000000..6c4ffe8
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/hn.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/hr.gif b/platform/www/lib/plugins/translation/flags/more/hr.gif
new file mode 100644
index 0000000..557c660
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/hr.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ht.gif b/platform/www/lib/plugins/translation/flags/more/ht.gif
new file mode 100644
index 0000000..059604a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ht.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/id.gif b/platform/www/lib/plugins/translation/flags/more/id.gif
new file mode 100644
index 0000000..865161b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/id.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/in.gif b/platform/www/lib/plugins/translation/flags/more/in.gif
new file mode 100644
index 0000000..1cd8027
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/in.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/io.gif b/platform/www/lib/plugins/translation/flags/more/io.gif
new file mode 100644
index 0000000..de7e7ab
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/io.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/iq.gif b/platform/www/lib/plugins/translation/flags/more/iq.gif
new file mode 100644
index 0000000..c34fe3c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/iq.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/is.gif b/platform/www/lib/plugins/translation/flags/more/is.gif
new file mode 100644
index 0000000..b42502d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/is.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ja.gif b/platform/www/lib/plugins/translation/flags/more/ja.gif
new file mode 100644
index 0000000..444c1d0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ja.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/jm.gif b/platform/www/lib/plugins/translation/flags/more/jm.gif
new file mode 100644
index 0000000..0bed67c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/jm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/jo.gif b/platform/www/lib/plugins/translation/flags/more/jo.gif
new file mode 100644
index 0000000..03daf8a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/jo.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ke.gif b/platform/www/lib/plugins/translation/flags/more/ke.gif
new file mode 100644
index 0000000..c2b5d45
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ke.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/kg.gif b/platform/www/lib/plugins/translation/flags/more/kg.gif
new file mode 100644
index 0000000..72a4d41
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/kg.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/kh.gif b/platform/www/lib/plugins/translation/flags/more/kh.gif
new file mode 100644
index 0000000..30a1831
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/kh.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ki.gif b/platform/www/lib/plugins/translation/flags/more/ki.gif
new file mode 100644
index 0000000..4a0751a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ki.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/km.gif b/platform/www/lib/plugins/translation/flags/more/km.gif
new file mode 100644
index 0000000..5859595
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/km.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/kn.gif b/platform/www/lib/plugins/translation/flags/more/kn.gif
new file mode 100644
index 0000000..bb9cc34
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/kn.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ko.gif b/platform/www/lib/plugins/translation/flags/more/ko.gif
new file mode 100644
index 0000000..1cddbe7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ko.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/kp.gif b/platform/www/lib/plugins/translation/flags/more/kp.gif
new file mode 100644
index 0000000..6e0ca09
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/kp.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/kw.gif b/platform/www/lib/plugins/translation/flags/more/kw.gif
new file mode 100644
index 0000000..1efc734
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/kw.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ky.gif b/platform/www/lib/plugins/translation/flags/more/ky.gif
new file mode 100644
index 0000000..d3d02ee
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ky.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/kz.gif b/platform/www/lib/plugins/translation/flags/more/kz.gif
new file mode 100644
index 0000000..24baebe
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/kz.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/la.gif b/platform/www/lib/plugins/translation/flags/more/la.gif
new file mode 100644
index 0000000..d14cf4d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/la.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/lb.gif b/platform/www/lib/plugins/translation/flags/more/lb.gif
new file mode 100644
index 0000000..003d83a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/lb.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/lc.gif b/platform/www/lib/plugins/translation/flags/more/lc.gif
new file mode 100644
index 0000000..f5fe5bf
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/lc.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/li.gif b/platform/www/lib/plugins/translation/flags/more/li.gif
new file mode 100644
index 0000000..713c58e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/li.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/lk.gif b/platform/www/lib/plugins/translation/flags/more/lk.gif
new file mode 100644
index 0000000..1b3ee7f
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/lk.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/lr.gif b/platform/www/lib/plugins/translation/flags/more/lr.gif
new file mode 100644
index 0000000..435af9e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/lr.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ls.gif b/platform/www/lib/plugins/translation/flags/more/ls.gif
new file mode 100644
index 0000000..427ae95
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ls.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/lt.gif b/platform/www/lib/plugins/translation/flags/more/lt.gif
new file mode 100644
index 0000000..dee9c60
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/lt.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/lu.gif b/platform/www/lib/plugins/translation/flags/more/lu.gif
new file mode 100644
index 0000000..7d7293e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/lu.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/lv.gif b/platform/www/lib/plugins/translation/flags/more/lv.gif
new file mode 100644
index 0000000..17e71b7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/lv.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ly.gif b/platform/www/lib/plugins/translation/flags/more/ly.gif
new file mode 100644
index 0000000..a654c30
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ly.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ma.gif b/platform/www/lib/plugins/translation/flags/more/ma.gif
new file mode 100644
index 0000000..fc78411
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ma.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mc.gif b/platform/www/lib/plugins/translation/flags/more/mc.gif
new file mode 100644
index 0000000..02a7c8e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mc.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/md.gif b/platform/www/lib/plugins/translation/flags/more/md.gif
new file mode 100644
index 0000000..e4b8a7e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/md.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/me.gif b/platform/www/lib/plugins/translation/flags/more/me.gif
new file mode 100644
index 0000000..a260453
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/me.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mg.gif b/platform/www/lib/plugins/translation/flags/more/mg.gif
new file mode 100644
index 0000000..a91b577
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mg.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mh.gif b/platform/www/lib/plugins/translation/flags/more/mh.gif
new file mode 100644
index 0000000..92f5f48
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mh.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mk.gif b/platform/www/lib/plugins/translation/flags/more/mk.gif
new file mode 100644
index 0000000..7aeb831
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mk.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ml.gif b/platform/www/lib/plugins/translation/flags/more/ml.gif
new file mode 100644
index 0000000..53d6f49
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ml.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mm.gif b/platform/www/lib/plugins/translation/flags/more/mm.gif
new file mode 100644
index 0000000..9e0a275
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mn.gif b/platform/www/lib/plugins/translation/flags/more/mn.gif
new file mode 100644
index 0000000..dff8ea5
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mn.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mo.gif b/platform/www/lib/plugins/translation/flags/more/mo.gif
new file mode 100644
index 0000000..66cf5b4
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mo.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mp.gif b/platform/www/lib/plugins/translation/flags/more/mp.gif
new file mode 100644
index 0000000..73b7147
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mp.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mq.gif b/platform/www/lib/plugins/translation/flags/more/mq.gif
new file mode 100644
index 0000000..570bc5d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mq.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mr.gif b/platform/www/lib/plugins/translation/flags/more/mr.gif
new file mode 100644
index 0000000..f52fcf0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mr.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ms.gif b/platform/www/lib/plugins/translation/flags/more/ms.gif
new file mode 100644
index 0000000..5e5a67a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ms.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mt.gif b/platform/www/lib/plugins/translation/flags/more/mt.gif
new file mode 100644
index 0000000..45c709f
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mt.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mu.gif b/platform/www/lib/plugins/translation/flags/more/mu.gif
new file mode 100644
index 0000000..081ab45
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mu.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mv.gif b/platform/www/lib/plugins/translation/flags/more/mv.gif
new file mode 100644
index 0000000..46b6387
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mv.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mw.gif b/platform/www/lib/plugins/translation/flags/more/mw.gif
new file mode 100644
index 0000000..ad045a0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mw.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mx.gif b/platform/www/lib/plugins/translation/flags/more/mx.gif
new file mode 100644
index 0000000..ddc75d0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mx.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/my.gif b/platform/www/lib/plugins/translation/flags/more/my.gif
new file mode 100644
index 0000000..fc7d523
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/my.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/mz.gif b/platform/www/lib/plugins/translation/flags/more/mz.gif
new file mode 100644
index 0000000..7d63508
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/mz.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/na.gif b/platform/www/lib/plugins/translation/flags/more/na.gif
new file mode 100644
index 0000000..c0babe7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/na.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/nc.gif b/platform/www/lib/plugins/translation/flags/more/nc.gif
new file mode 100644
index 0000000..b1e91b9
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/nc.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ne.gif b/platform/www/lib/plugins/translation/flags/more/ne.gif
new file mode 100644
index 0000000..ff4eaf0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ne.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/nf.gif b/platform/www/lib/plugins/translation/flags/more/nf.gif
new file mode 100644
index 0000000..c83424c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/nf.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ng.gif b/platform/www/lib/plugins/translation/flags/more/ng.gif
new file mode 100644
index 0000000..bdde7cb
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ng.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ni.gif b/platform/www/lib/plugins/translation/flags/more/ni.gif
new file mode 100644
index 0000000..d05894d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ni.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/np.gif b/platform/www/lib/plugins/translation/flags/more/np.gif
new file mode 100644
index 0000000..1096893
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/np.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/nr.gif b/platform/www/lib/plugins/translation/flags/more/nr.gif
new file mode 100644
index 0000000..2e4c0c5
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/nr.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/nu.gif b/platform/www/lib/plugins/translation/flags/more/nu.gif
new file mode 100644
index 0000000..618210a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/nu.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/nz.gif b/platform/www/lib/plugins/translation/flags/more/nz.gif
new file mode 100644
index 0000000..028a5dc
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/nz.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/om.gif b/platform/www/lib/plugins/translation/flags/more/om.gif
new file mode 100644
index 0000000..2b8c775
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/om.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/pa.gif b/platform/www/lib/plugins/translation/flags/more/pa.gif
new file mode 100644
index 0000000..d518b2f
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/pa.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/pe.gif b/platform/www/lib/plugins/translation/flags/more/pe.gif
new file mode 100644
index 0000000..3bc7639
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/pe.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/pf.gif b/platform/www/lib/plugins/translation/flags/more/pf.gif
new file mode 100644
index 0000000..849297a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/pf.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/pg.gif b/platform/www/lib/plugins/translation/flags/more/pg.gif
new file mode 100644
index 0000000..2d20b07
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/pg.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ph.gif b/platform/www/lib/plugins/translation/flags/more/ph.gif
new file mode 100644
index 0000000..12b380a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ph.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/pk.gif b/platform/www/lib/plugins/translation/flags/more/pk.gif
new file mode 100644
index 0000000..f3f62c2
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/pk.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/pl.gif b/platform/www/lib/plugins/translation/flags/more/pl.gif
new file mode 100644
index 0000000..bf10646
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/pl.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/pm.gif b/platform/www/lib/plugins/translation/flags/more/pm.gif
new file mode 100644
index 0000000..99bf6fd
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/pm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/pn.gif b/platform/www/lib/plugins/translation/flags/more/pn.gif
new file mode 100644
index 0000000..4bc86a1
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/pn.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/pr.gif b/platform/www/lib/plugins/translation/flags/more/pr.gif
new file mode 100644
index 0000000..6d5d589
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/pr.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ps.gif b/platform/www/lib/plugins/translation/flags/more/ps.gif
new file mode 100644
index 0000000..6afa3b7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ps.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/pw.gif b/platform/www/lib/plugins/translation/flags/more/pw.gif
new file mode 100644
index 0000000..5854510
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/pw.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/py.gif b/platform/www/lib/plugins/translation/flags/more/py.gif
new file mode 100644
index 0000000..f2e66af
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/py.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/qa.gif b/platform/www/lib/plugins/translation/flags/more/qa.gif
new file mode 100644
index 0000000..2e843ff
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/qa.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/re.gif b/platform/www/lib/plugins/translation/flags/more/re.gif
new file mode 100644
index 0000000..43d0b80
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/re.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/rs.gif b/platform/www/lib/plugins/translation/flags/more/rs.gif
new file mode 100644
index 0000000..3bd1fb2
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/rs.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/rw.gif b/platform/www/lib/plugins/translation/flags/more/rw.gif
new file mode 100644
index 0000000..0d095f7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/rw.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sb.gif b/platform/www/lib/plugins/translation/flags/more/sb.gif
new file mode 100644
index 0000000..8f5ff83
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sb.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sc.gif b/platform/www/lib/plugins/translation/flags/more/sc.gif
new file mode 100644
index 0000000..31b4767
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sc.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/scotland.gif b/platform/www/lib/plugins/translation/flags/more/scotland.gif
new file mode 100644
index 0000000..03f3f1d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/scotland.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sd.gif b/platform/www/lib/plugins/translation/flags/more/sd.gif
new file mode 100644
index 0000000..53ae214
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sd.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sg.gif b/platform/www/lib/plugins/translation/flags/more/sg.gif
new file mode 100644
index 0000000..5663d39
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sg.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sh.gif b/platform/www/lib/plugins/translation/flags/more/sh.gif
new file mode 100644
index 0000000..dcc7f3b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sh.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/si.gif b/platform/www/lib/plugins/translation/flags/more/si.gif
new file mode 100644
index 0000000..23852b5
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/si.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sj.gif b/platform/www/lib/plugins/translation/flags/more/sj.gif
new file mode 100644
index 0000000..6202d1f
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sj.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sk.gif b/platform/www/lib/plugins/translation/flags/more/sk.gif
new file mode 100644
index 0000000..1b3f22b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sk.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sl.gif b/platform/www/lib/plugins/translation/flags/more/sl.gif
new file mode 100644
index 0000000..f0f3492
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sl.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sm.gif b/platform/www/lib/plugins/translation/flags/more/sm.gif
new file mode 100644
index 0000000..04d98de
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sn.gif b/platform/www/lib/plugins/translation/flags/more/sn.gif
new file mode 100644
index 0000000..6dac870
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sn.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/so.gif b/platform/www/lib/plugins/translation/flags/more/so.gif
new file mode 100644
index 0000000..f196169
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/so.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sr.gif b/platform/www/lib/plugins/translation/flags/more/sr.gif
new file mode 100644
index 0000000..0f7499a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sr.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/st.gif b/platform/www/lib/plugins/translation/flags/more/st.gif
new file mode 100644
index 0000000..4f1e6e0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/st.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sv.gif b/platform/www/lib/plugins/translation/flags/more/sv.gif
new file mode 100644
index 0000000..2d7b159
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sv.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sy.gif b/platform/www/lib/plugins/translation/flags/more/sy.gif
new file mode 100644
index 0000000..dc8bd50
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sy.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/sz.gif b/platform/www/lib/plugins/translation/flags/more/sz.gif
new file mode 100644
index 0000000..f37aaf8
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/sz.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tc.gif b/platform/www/lib/plugins/translation/flags/more/tc.gif
new file mode 100644
index 0000000..11a8c23
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tc.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/td.gif b/platform/www/lib/plugins/translation/flags/more/td.gif
new file mode 100644
index 0000000..7aa8a10
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/td.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tf.gif b/platform/www/lib/plugins/translation/flags/more/tf.gif
new file mode 100644
index 0000000..51a4325
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tf.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tg.gif b/platform/www/lib/plugins/translation/flags/more/tg.gif
new file mode 100644
index 0000000..ca6b4e7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tg.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tj.gif b/platform/www/lib/plugins/translation/flags/more/tj.gif
new file mode 100644
index 0000000..2fe38d4
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tj.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tk.gif b/platform/www/lib/plugins/translation/flags/more/tk.gif
new file mode 100644
index 0000000..3d3a727
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tk.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tl.gif b/platform/www/lib/plugins/translation/flags/more/tl.gif
new file mode 100644
index 0000000..df22d58
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tl.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tm.gif b/platform/www/lib/plugins/translation/flags/more/tm.gif
new file mode 100644
index 0000000..36d0994
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tn.gif b/platform/www/lib/plugins/translation/flags/more/tn.gif
new file mode 100644
index 0000000..917d428
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tn.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/to.gif b/platform/www/lib/plugins/translation/flags/more/to.gif
new file mode 100644
index 0000000..d7ed4d1
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/to.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tt.gif b/platform/www/lib/plugins/translation/flags/more/tt.gif
new file mode 100644
index 0000000..47d3b80
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tt.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tv.gif b/platform/www/lib/plugins/translation/flags/more/tv.gif
new file mode 100644
index 0000000..3c33827
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tv.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tw.gif b/platform/www/lib/plugins/translation/flags/more/tw.gif
new file mode 100644
index 0000000..cacfd9b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tw.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/tz.gif b/platform/www/lib/plugins/translation/flags/more/tz.gif
new file mode 100644
index 0000000..82b52ca
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/tz.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ua.gif b/platform/www/lib/plugins/translation/flags/more/ua.gif
new file mode 100644
index 0000000..5d6cd83
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ua.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ug.gif b/platform/www/lib/plugins/translation/flags/more/ug.gif
new file mode 100644
index 0000000..58b731a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ug.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/um.gif b/platform/www/lib/plugins/translation/flags/more/um.gif
new file mode 100644
index 0000000..3b4c848
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/um.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/us.gif b/platform/www/lib/plugins/translation/flags/more/us.gif
new file mode 100644
index 0000000..8f198f7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/us.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/uy.gif b/platform/www/lib/plugins/translation/flags/more/uy.gif
new file mode 100644
index 0000000..12848c7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/uy.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/uz.gif b/platform/www/lib/plugins/translation/flags/more/uz.gif
new file mode 100644
index 0000000..dc9daec
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/uz.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/va.gif b/platform/www/lib/plugins/translation/flags/more/va.gif
new file mode 100644
index 0000000..2bd7446
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/va.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/vc.gif b/platform/www/lib/plugins/translation/flags/more/vc.gif
new file mode 100644
index 0000000..4821381
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/vc.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ve.gif b/platform/www/lib/plugins/translation/flags/more/ve.gif
new file mode 100644
index 0000000..19ce6c1
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ve.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/vg.gif b/platform/www/lib/plugins/translation/flags/more/vg.gif
new file mode 100644
index 0000000..1fc0f96
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/vg.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/vi.gif b/platform/www/lib/plugins/translation/flags/more/vi.gif
new file mode 100644
index 0000000..66f9e74
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/vi.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/vu.gif b/platform/www/lib/plugins/translation/flags/more/vu.gif
new file mode 100644
index 0000000..8a8b2b0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/vu.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/wales.gif b/platform/www/lib/plugins/translation/flags/more/wales.gif
new file mode 100644
index 0000000..901d175
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/wales.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/wf.gif b/platform/www/lib/plugins/translation/flags/more/wf.gif
new file mode 100644
index 0000000..eaa954b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/wf.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ws.gif b/platform/www/lib/plugins/translation/flags/more/ws.gif
new file mode 100644
index 0000000..a51f939
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ws.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/ye.gif b/platform/www/lib/plugins/translation/flags/more/ye.gif
new file mode 100644
index 0000000..7b0183d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/ye.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/yt.gif b/platform/www/lib/plugins/translation/flags/more/yt.gif
new file mode 100644
index 0000000..a2267c0
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/yt.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/za.gif b/platform/www/lib/plugins/translation/flags/more/za.gif
new file mode 100644
index 0000000..ede5258
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/za.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/zm.gif b/platform/www/lib/plugins/translation/flags/more/zm.gif
new file mode 100644
index 0000000..b2851d2
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/zm.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/more/zw.gif b/platform/www/lib/plugins/translation/flags/more/zw.gif
new file mode 100644
index 0000000..02901f6
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/more/zw.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/nl.gif b/platform/www/lib/plugins/translation/flags/nl.gif
new file mode 100644
index 0000000..c1c8f46
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/nl.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/no.gif b/platform/www/lib/plugins/translation/flags/no.gif
new file mode 100644
index 0000000..6202d1f
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/no.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/pt-br.gif b/platform/www/lib/plugins/translation/flags/pt-br.gif
new file mode 100644
index 0000000..8c86616
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/pt-br.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/pt.gif b/platform/www/lib/plugins/translation/flags/pt.gif
new file mode 100644
index 0000000..e735f74
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/pt.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/ro.gif b/platform/www/lib/plugins/translation/flags/ro.gif
new file mode 100644
index 0000000..f5d5f12
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/ro.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/ru.gif b/platform/www/lib/plugins/translation/flags/ru.gif
new file mode 100644
index 0000000..b525c46
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/ru.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/sv.gif b/platform/www/lib/plugins/translation/flags/sv.gif
new file mode 100644
index 0000000..80f6285
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/sv.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/th.gif b/platform/www/lib/plugins/translation/flags/th.gif
new file mode 100644
index 0000000..0130792
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/th.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/tr.gif b/platform/www/lib/plugins/translation/flags/tr.gif
new file mode 100644
index 0000000..e407d55
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/tr.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/vi.gif b/platform/www/lib/plugins/translation/flags/vi.gif
new file mode 100644
index 0000000..f1e20c9
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/vi.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/flags/zh.gif b/platform/www/lib/plugins/translation/flags/zh.gif
new file mode 100644
index 0000000..b052530
--- /dev/null
+++ b/platform/www/lib/plugins/translation/flags/zh.gif
Binary files differ
diff --git a/platform/www/lib/plugins/translation/helper.php b/platform/www/lib/plugins/translation/helper.php
new file mode 100644
index 0000000..e6bc3b5
--- /dev/null
+++ b/platform/www/lib/plugins/translation/helper.php
@@ -0,0 +1,446 @@
+<?php
+/**
+ * Translation Plugin: Simple multilanguage plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Class helper_plugin_translation
+ */
+class helper_plugin_translation extends DokuWiki_Plugin {
+ var $translations = array();
+ var $translationNs = '';
+ var $defaultlang = '';
+ var $LN = array(); // hold native names
+ var $opts = array(); // display options
+
+ /**
+ * Initialize
+ */
+ function __construct() {
+ global $conf;
+ require_once(DOKU_INC . 'inc/pageutils.php');
+ require_once(DOKU_INC . 'inc/utf8.php');
+
+ $this->loadTranslationNamespaces();
+
+ // load language names
+ $this->LN = confToHash(dirname(__FILE__) . '/lang/langnames.txt');
+
+ // display options
+ $this->opts = $this->getConf('display');
+ $this->opts = explode(',', $this->opts);
+ $this->opts = array_map('trim', $this->opts);
+ $this->opts = array_fill_keys($this->opts, true);
+
+ // get default translation
+ if(!empty($conf['lang_before_translation'])) {
+ $dfl = $conf['lang'];
+ } else {
+ $dfl = $conf['lang_before_translation'];
+ }
+ if(in_array($dfl, $this->translations)) {
+ $this->defaultlang = $dfl;
+ } else {
+ $this->defaultlang = '';
+ array_unshift($this->translations, '');
+ }
+
+ $this->translationNs = cleanID($this->getConf('translationns'));
+ if($this->translationNs) $this->translationNs .= ':';
+ }
+
+ /**
+ * Parse 'translations'-setting into $this->translations
+ */
+ public function loadTranslationNamespaces() {
+ // load wanted translation into array
+ $this->translations = strtolower(str_replace(',', ' ', $this->getConf('translations')));
+ $this->translations = array_unique(array_filter(explode(' ', $this->translations)));
+ sort($this->translations);
+ }
+
+ /**
+ * Check if the given ID is a translation and return the language code.
+ *
+ * @param string $id
+ * @return string
+ */
+ function getLangPart($id) {
+ list($lng) = $this->getTransParts($id);
+ return $lng;
+ }
+
+ /**
+ * Check if the given ID is a translation and return the language code and
+ * the id part.
+ *
+ * @param string $id
+ * @return array
+ */
+ function getTransParts($id) {
+ $rx = '/^' . $this->translationNs . '(' . join('|', $this->translations) . '):(.*)/';
+ if(preg_match($rx, $id, $match)) {
+ return array($match[1], $match[2]);
+ }
+ return array('', $id);
+ }
+
+ /**
+ * Returns the browser language if it matches with one of the configured
+ * languages
+ */
+ function getBrowserLang() {
+ global $conf;
+ $langs = $this->translations;
+ if (!in_array($conf['lang'], $langs)) {
+ $langs[] = $conf['lang'];
+ }
+ $rx = '/(^|,|:|;|-)(' . join('|', $langs) . ')($|,|:|;|-)/i';
+ if(preg_match($rx, $_SERVER['HTTP_ACCEPT_LANGUAGE'], $match)) {
+ return strtolower($match[2]);
+ }
+ return false;
+ }
+
+ /**
+ * Returns the ID and name to the wanted translation, empty
+ * $lng is default lang
+ *
+ * @param string $lng
+ * @param string $idpart
+ * @return array
+ */
+ function buildTransID($lng, $idpart) {
+ if($lng && in_array($lng, $this->translations)) {
+ $link = ':' . $this->translationNs . $lng . ':' . $idpart;
+ $name = $lng;
+ } else {
+ $link = ':' . $this->translationNs . $idpart;
+ $name = $this->realLC('');
+ }
+ return array($link, $name);
+ }
+
+ /**
+ * Returns the real language code, even when an empty one is given
+ * (eg. resolves th default language)
+ *
+ * @param string $lc
+ * @return string
+ */
+ function realLC($lc) {
+ global $conf;
+ if($lc) {
+ return $lc;
+ } elseif(!$conf['lang_before_translation']) {
+ return $conf['lang'];
+ } else {
+ return $conf['lang_before_translation'];
+ }
+ }
+
+ /**
+ * Check if current ID should be translated and any GUI
+ * should be shown
+ *
+ * @param string $id
+ * @param bool $checkact
+ * @return bool
+ */
+ function istranslatable($id, $checkact = true) {
+ global $ACT;
+
+ if($checkact && $ACT != 'show') return false;
+ if($this->translationNs && strpos($id, $this->translationNs) !== 0) return false;
+ $skiptrans = trim($this->getConf('skiptrans'));
+ if($skiptrans && preg_match('/' . $skiptrans . '/ui', ':' . $id)) return false;
+ $meta = p_get_metadata($id);
+ if(!empty($meta['plugin']['translation']['notrans'])) return false;
+
+ return true;
+ }
+
+ /**
+ * Return the (localized) about link
+ */
+ function showAbout() {
+ global $ID;
+
+ $curlc = $this->getLangPart($ID);
+
+ $about = $this->getConf('about');
+ if($this->getConf('localabout')) {
+ list(/* $lc */, $idpart) = $this->getTransParts($about);
+ list($about, /* $name */) = $this->buildTransID($curlc, $idpart);
+ $about = cleanID($about);
+ }
+
+ $out = '';
+ $out .= '<sup>';
+ $out .= html_wikilink($about, '?');
+ $out .= '</sup>';
+
+ return $out;
+ }
+
+ /**
+ * Returns a list of (lc => link) for all existing translations of a page
+ *
+ * @param $id
+ * @return array
+ */
+ function getAvailableTranslations($id) {
+ $result = array();
+
+ list($lc, $idpart) = $this->getTransParts($id);
+
+ foreach($this->translations as $t) {
+ if($t == $lc) continue; //skip self
+ list($link, $name) = $this->buildTransID($t, $idpart);
+ if(page_exists($link)) {
+ $result[$name] = $link;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Creates an UI for linking to the available and configured translations
+ *
+ * Can be called from the template or via the ~~TRANS~~ syntax component.
+ */
+ public function showTranslations() {
+ global $conf;
+ global $INFO;
+
+ if(!$this->istranslatable($INFO['id'])) return '';
+ $this->checkage();
+
+ list($lc, $idpart) = $this->getTransParts($INFO['id']);
+ $lang = $this->realLC($lc);
+
+ $out = '<div class="plugin_translation">';
+
+ //show title and about
+ if(isset($this->opts['title'])) {
+ $out .= '<span>' . $this->getLang('translations');
+ if($this->getConf('about')) $out .= $this->showAbout();
+ $out .= ':</span> ';
+ if(isset($this->opts['twolines'])) $out .= '<br />';
+ }
+
+ // open wrapper
+ if($this->getConf('dropdown')) {
+ // select needs its own styling
+ if($INFO['exists']) {
+ $class = 'wikilink1';
+ } else {
+ $class = 'wikilink2';
+ }
+ if(isset($this->opts['flag'])) {
+ $flag = DOKU_BASE . 'lib/plugins/translation/flags/' . hsc($lang) . '.gif';
+ }else{
+ $flag = '';
+ }
+
+ if($conf['userewrite']) {
+ $action = wl();
+ } else {
+ $action = script();
+ }
+
+ $out .= '<form action="' . $action . '" id="translation__dropdown">';
+ if($flag) $out .= '<img src="' . $flag . '" alt="' . hsc($lang) . '" height="11" class="' . $class . '" /> ';
+ $out .= '<select name="id" class="' . $class . '">';
+ } else {
+ $out .= '<ul>';
+ }
+
+ // insert items
+
+ array_shift($this->translations);
+ foreach($this->translations as $t) {
+ $out .= $this->getTransItem($t, $idpart);
+ }
+
+ // close wrapper
+ if($this->getConf('dropdown')) {
+ $out .= '</select>';
+ $out .= '<input name="go" type="submit" value="&rarr;" />';
+ $out .= '</form>';
+ } else {
+ $out .= '</ul>';
+ }
+
+ // show about if not already shown
+ if(!isset($this->opts['title']) && $this->getConf('about')) {
+ $out .= '&nbsp';
+ $out .= $this->showAbout();
+ }
+
+ $out .= '</div>';
+
+ return $out;
+ }
+
+ /**
+ * Return the local name
+ *
+ * @param $lang
+ * @return string
+ */
+ function getLocalName($lang) {
+ if($this->LN[$lang]) {
+ return $this->LN[$lang];
+ }
+ return $lang;
+ }
+
+ /**
+ * Create the link or option for a single translation
+ *
+ * @param $lc string The language code
+ * @param $idpart string The ID of the translated page
+ * @returns string The item
+ */
+ function getTransItem($lc, $idpart) {
+ global $ID;
+ global $conf;
+
+ list($link, $lang) = $this->buildTransID($lc, $idpart);
+ $link = cleanID($link);
+
+ // class
+ if(page_exists($link, '', false)) {
+ $class = 'wikilink1';
+ } else {
+ $class = 'wikilink2';
+ }
+
+ // local language name
+ $localname = $this->getLocalName($lang);
+
+ $divClass = 'li';
+ // current?
+ if($ID == $link) {
+ $sel = ' selected="selected"';
+ $class .= ' cur';
+ $divClass .= ' cur';
+ } else {
+ $sel = '';
+ }
+
+ // flag
+ $flag = false;
+ $style = '';
+ if(isset($this->opts['flag'])) {
+ $flag = DOKU_BASE . 'lib/plugins/translation/flags/' . hsc($lang) . '.gif';
+ $style = ' style="background-image: url(\'' . $flag . '\')"';
+ $class .= ' flag';
+ }
+
+ // what to display as name
+ if(isset($this->opts['name'])) {
+ $display = hsc($localname);
+ if(isset($this->opts['langcode'])) $display .= ' (' . hsc($lang) . ')';
+ } elseif(isset($this->opts['langcode'])) {
+ $display = hsc($lang);
+ } else {
+ $display = '&nbsp;';
+ }
+
+ // prepare output
+ $out = '';
+ if($this->getConf('dropdown')) {
+ if($conf['useslash']) $link = str_replace(':', '/', $link);
+
+ $out .= '<option class="' . $class . '" title="' . hsc($localname) . '" value="' . $link . '"' . $sel . $style . '>';
+ $out .= $display;
+ $out .= '</option>';
+ } else {
+ $out .= "<li><div class='$divClass'>";
+ $out .= '<a href="' . wl($link) . '" class="' . $class . '" title="' . hsc($localname) . '">';
+ if($flag) $out .= '<img src="' . $flag . '" alt="' . hsc($lang) . '" height="11" />';
+ $out .= $display;
+ $out .= '</a>';
+ $out .= '</div></li>';
+ }
+
+ return $out;
+ }
+
+ /**
+ * Checks if the current page is a translation of a page
+ * in the default language. Displays a notice when it is
+ * older than the original page. Tries to link to a diff
+ * with changes on the original since the translation
+ */
+ function checkage() {
+ global $ID;
+ global $INFO;
+ if(!$this->getConf('checkage')) return;
+ if(!$INFO['exists']) return;
+ $lng = $this->getLangPart($ID);
+ if($lng == $this->defaultlang) return;
+
+ $rx = '/^' . $this->translationNs . '((' . join('|', $this->translations) . '):)?/';
+ $idpart = preg_replace($rx, '', $ID);
+
+ // compare modification times
+ list($orig, /* $name */) = $this->buildTransID($this->defaultlang, $idpart);
+ $origfn = wikiFN($orig);
+ if($INFO['lastmod'] >= @filemtime($origfn)) return;
+
+ // get revision from before translation
+ $orev = 0;
+
+ $changelog = new PageChangelog($orig);
+ $revs = $changelog->getRevisions(0, 100);
+ foreach($revs as $rev) {
+ if($rev < $INFO['lastmod']) {
+ $orev = $rev;
+ break;
+ }
+ }
+
+ // see if the found revision still exists
+ if($orev && !page_exists($orig, $orev)) $orev = 0;
+
+ // build the message and display it
+ $orig = cleanID($orig);
+ $msg = sprintf($this->getLang('outdated'), wl($orig));
+
+ $difflink = $this->getOldDiffLink($orig, $INFO['lastmod']);
+ if ($difflink) {
+ $msg .= sprintf(' ' . $this->getLang('diff'), $difflink);
+ }
+
+ echo '<div class="notify">' . $msg . '</div>';
+ }
+
+ function getOldDiffLink($id, $lastmod) {
+ // get revision from before translation
+ $orev = false;
+ $changelog = new PageChangelog($id);
+ $revs = $changelog->getRevisions(0, 100);
+ foreach($revs as $rev) {
+ if($rev < $lastmod) {
+ $orev = $rev;
+ break;
+ }
+ }
+ if($orev && !page_exists($id, $orev)) {
+ return false;
+ }
+ $id = cleanID($id);
+ return wl($id, array('do' => 'diff', 'rev' => $orev));
+
+ }
+}
diff --git a/platform/www/lib/plugins/translation/lang/be/lang.php b/platform/www/lib/plugins/translation/lang/be/lang.php
new file mode 100644
index 0000000..dd9d9ae
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/be/lang.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * Belarusian language file
+ *
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['translations'] = 'Пераклад гÑтай Ñтаронкі';
+$lang['outdated'] = 'ГÑÑ‚Ñ‹ пераклад ÑтарÑй, чым <a href="%s" class="wikilink1">Ð°Ñ€Ñ‹Ð³Ñ–Ð½Ð°Ð»ÑŒÐ½Ð°Ñ Ñтаронка</a> Ñ– можа быць не актуальным.';
+$lang['diff'] = 'ГлÑдзіце <a href="%s" class="wikilink1">было зменена</a>.';
+$lang['transloaded'] = 'СÑÐ½Ñ Ð¿ÐµÑ€Ð°ÐºÐ»Ð°Ð´Ñƒ гÑтай Ñтаронкі %s быў папÑÑ€Ñдне загружаны Ð´Ð»Ñ Ð·Ñ€ÑƒÑ‡Ð½Ð°Ñці перакладу. <br /> ТакÑама можаце выкарыÑтоўваць наÑÑ‚ÑƒÐ¿Ð½Ñ‹Ñ Ð¿ÐµÑ€Ð°ÐºÐ»Ð°Ð´Ñ‹: %s.';
+$lang['menu'] = 'ÑаÑтарÑÐ»Ñ‹Ñ Ñ– адÑÑƒÑ‚Ð½Ñ‹Ñ Ð¿ÐµÑ€Ð°ÐºÐ»Ð°Ð´Ñ‹';
+$lang['missing'] = 'ÐдÑутнічае!';
+$lang['old'] = 'заÑтарÑлы';
+$lang['current'] = 'бÑгучы';
+$lang['path'] = 'ШлÑÑ…';
diff --git a/platform/www/lib/plugins/translation/lang/be/settings.php b/platform/www/lib/plugins/translation/lang/be/settings.php
new file mode 100644
index 0000000..9627847
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/be/settings.php
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * Belarusian language file
+ *
+ * @author Rainbow-Spike <rainbow_spike@derpy.ru>
+ */
+
+$lang['translations'] = 'Ð¡Ð¿Ñ–Ñ Ð¿Ð°Ð´Ñ‚Ñ€Ñ‹Ð¼Ð¾ÑžÐ²Ð°Ð½Ñ‹Ñ… моў перакладу (двохÑимвольні коды ISO). ПадзÑлÑйце значÑÐ½Ð½Ñ ÐºÐ¾Ñкамі або прабеламі.';
+$lang['translationns'] = 'Калі вы хочаце перавеÑці толькі пÑўны ПраÑтору імёнаў, тады ўпішыце тут Ñго імÑ.';
+$lang['skiptrans'] = 'Калі Ñ–Ð¼Ñ Ñтаронкі адпавÑдае гÑтаму Ñ€ÑгулÑрнаму выразу, тады не адлюÑтроўваць меню перакладаў.';
+$lang['dropdown'] = 'ВыкарыÑтаць выпадальны ÑÐ¿Ñ–Ñ Ð´Ð»Ñ Ð°Ð´Ð»ÑŽÑÑ‚Ñ€Ð°Ð²Ð°Ð½Ð½Ñ Ð´Ð°Ñтупных перакладаў (Ñ€Ñкамендуецца, калі больш за 5 перакладаў)';
+$lang['translateui'] = 'Павінна мова інтÑрфейÑу карыÑтальніка такÑама перамыкацца мовы ПраÑторы імёнаў?';
+$lang['redirectstart'] = 'Павінна ÑÑ‚Ð°Ñ€Ñ‚Ð°Ð²Ð°Ñ Ñтаронка аўтаматычна перенаправлÑтиÑÑŒ на ПраÑтору імёнаў мовы, выкарыÑтоўваючы детектекцію мовы аглÑдальніка?';
+$lang['about'] = 'Калі лаÑка, УвÑдзіце Ñ–Ð¼Ñ Ñтаронкі, на Ñкой будзе руж\'раÑтлумачана функцыі перакладу Ð´Ð»Ñ Ð²Ð°ÑˆÑ‹Ñ… карыÑтальнікаў. Яна будзе звÑзана з выбарам мовы.';
+$lang['localabout'] = 'ВыкарыÑтаць лакалізаваную верÑÑ–ÑŽ Ñтаронкі руж\'тлумачÑннÑÑž (замеÑÑ‚ адной глабальнай Ñтаронкі руж\'тлумачÑннÑÑž).';
+$lang['checkage'] = 'ÐдлюÑтроўваць папÑÑ€Ñджанне аб магчымай не актуальнаÑць перакладу Ñтаронак?';
+$lang['display'] = 'ÐбÑрыце што б вы хацелі адлюÑтроўваць у перамыкачы моў. Заўвага: выкарыÑтоўваць ÑцÑг краіны Ð´Ð»Ñ Ð¿ÐµÑ€Ð°ÐºÐ»ÑŽÑ‡Ð°Ð»ÑŒÐ½Ñ–ÐºÐ° моў не Ñ€Ñкамендуецца ÑкÑпертамі па выгодзе выкарыÑÑ‚Ð°Ð½Ð½Ñ Ñ–Ð½Ñ‚ÑрфейÑу.';
+
+$lang['copytrans'] = 'СкапіÑваць Ñ‚ÑкÑÑ‚ на мове арыгінала да Ñ€Ñдактара Ñž пачатку новага перакладу?';
+$lang['show_path'] = 'Паказаць шлÑÑ… адÑутнічае на Ñтаронцы перакладу?';
diff --git a/platform/www/lib/plugins/translation/lang/be/totranslate.txt b/platform/www/lib/plugins/translation/lang/be/totranslate.txt
new file mode 100644
index 0000000..07eadbc
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/be/totranslate.txt
@@ -0,0 +1 @@
+FIXME **ГÑÑ‚Ð°Ñ Ñтаронка ÑÑˆÑ‡Ñ Ð½Ðµ цалкам перакладзенаÑ. Калі лаÑка, дапамажыце завÑршыць пераклад.**\\ //(выдаліце гÑÑ‚Ñ‹ абзац паÑÐ»Ñ Ð·Ð°Ð²ÑршÑÐ½Ð½Ñ Ð¿ÐµÑ€Ð°ÐºÐ»Ð°Ð´Ñƒ)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/bn/lang.php b/platform/www/lib/plugins/translation/lang/bn/lang.php
new file mode 100644
index 0000000..5bfc73b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/bn/lang.php
@@ -0,0 +1,10 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author ninetailz <ninetailz1125@gmail.com>
+ */
+$lang['translations'] = 'à¦à¦‡ পাতার অনà§à¦¬à¦¾à¦¦';
+$lang['outdated'] = 'à¦à¦‡ অনà§à¦¬à¦¾à¦¦ <a href="%s" class="wiki link1">মূল পাতা</ a> তà§à¦²à¦¨à¦¾à¦¯à¦¼ পà§à¦°à§‹à¦¨à§‹ হয় à¦à¦¬à¦‚ পà§à¦°à¦¾à¦¨ হতে পারে.';
+$lang['diff'] = 'দেখà§à¦¨ কি <a href="%s" class="wikilink1">পরিবরà§à¦¤à¦¨</ a> হয়েছে';
diff --git a/platform/www/lib/plugins/translation/lang/bn/settings.php b/platform/www/lib/plugins/translation/lang/bn/settings.php
new file mode 100644
index 0000000..d1df06b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/bn/settings.php
@@ -0,0 +1,10 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author ninetailz <ninetailz1125@gmail.com>
+ */
+$lang['about'] = 'à¦à¦–ানে à¦à¦•à¦Ÿà¦¿ পৃষà§à¦ à¦¾à¦¯à¦¼ নাম লিখà§à¦¨ যেখানে অনà§à¦¬à¦¾à¦¦à§‡à¦° বৈশিষà§à¦Ÿà§à¦¯à¦Ÿà¦¿ বà§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€à¦¦à§‡à¦° জনà§à¦¯ বà§à¦¯à¦¾à¦–à§à¦¯à¦¾ করা আছে. à¦à¦Ÿà¦¾ ভাষা নিরà§à¦¬à¦¾à¦šà¦• থেকে লিঙà§à¦• করা হবে.';
+$lang['checkage'] = 'সমà§à¦­à¦¬à¦¤ পà§à¦°à§‹à¦¨à§‹ অনà§à¦¬à¦¾à¦¦à§‡à¦° বিষয়ে সাবধান.';
+$lang['copytrans'] = 'à¦à¦•à¦Ÿà¦¿ নতà§à¦¨ অনà§à¦¬à¦¾à¦¦ শà§à¦°à§ যখন সমà§à¦ªà¦¾à¦¦à¦• মধà§à¦¯à§‡ মূল ভাষা টেকà§à¦¸à¦Ÿ কপি করà§à¦¨?';
diff --git a/platform/www/lib/plugins/translation/lang/bn/totranslate.txt b/platform/www/lib/plugins/translation/lang/bn/totranslate.txt
new file mode 100644
index 0000000..46e5f1c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/bn/totranslate.txt
@@ -0,0 +1 @@
+FixMe ** à¦à¦‡ পাতা সমà§à¦ªà§‚রà§à¦£à¦°à§‚পে à¦à¦–নো অনà§à¦¬à¦¾à¦¦ করা হয়নি. অনà§à¦¬à¦¾à¦¦ সমাপà§à¦¤à¦¿à¦° সাহাযà§à¦¯ করà§à¦¨. ** \ \ / / (অনà§à¦¬à¦¾à¦¦ সমাপà§à¦¤ হয় à¦à¦•à¦¬à¦¾à¦° à¦à¦‡ অনà§à¦šà§à¦›à§‡à¦¦ মà§à¦›à§‡ ফেলà§à¦¨) / / \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/ca/lang.php b/platform/www/lib/plugins/translation/lang/ca/lang.php
new file mode 100644
index 0000000..c74c568
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ca/lang.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Jordi Robert Sancho <jrobertsancho@gmail.com>
+ */
+$lang['translations'] = 'Traduccions d\'aquesta pàgina';
+$lang['outdated'] = 'Aquesta traducció és més antiga que la <a href="%s" class="wikilink1">pàgina original</a> i pot estar desactualitzada.';
+$lang['diff'] = 'Veure que ha <a href="%s" class="wikilink1">canviat</a>.';
+$lang['transloaded'] = 'Els continguts de la traducció d\'aquesta pàgina a %s han sigut pre-carregats per facilitar la traducció.<br>Però pots basar la teva traducció en les següents traduccions: %s';
+$lang['menu'] = 'traduccions desactualitzades i que falten';
+$lang['missing'] = 'Falta!';
+$lang['old'] = 'desactualitzat';
+$lang['current'] = 'actualitzat';
+$lang['path'] = 'Ruta';
diff --git a/platform/www/lib/plugins/translation/lang/ca/settings.php b/platform/www/lib/plugins/translation/lang/ca/settings.php
new file mode 100644
index 0000000..4a356cc
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ca/settings.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Jordi Robert Sancho <jrobertsancho@gmail.com>
+ */
+$lang['translations'] = 'Llista separada per espais d\'idiomes de traducció';
+$lang['translationns'] = 'Si només vols traduccions sota un cert espai de noms, posa\'l aquí.';
+$lang['skiptrans'] = 'Quan el nom de la pàgina coincideix amb aquesta expressió regular, no mostris el menú de traducció.';
+$lang['dropdown'] = 'Utilitzar una llista desplegable per mostrar les traduccions (recomanat per a més de 5 idiomes).';
+$lang['translateui'] = 'L\'idioma de la interfície d\'usuari s\'hauria de canviar també en els espais de noms en llengües estrangeres?';
+$lang['redirectstart'] = 'La pàgina d\'inici hauria de redirigir a un espai de noms d\'idioma mitjançant la detecció d\'idioma del navegador?';
+$lang['about'] = 'Introdueix un nom de pàgina aquí, on la funció de traducció s\'explica als usuaris. Estarà connectat des del selector d\'idioma.';
+$lang['localabout'] = 'Utilitzar versions localitzades de la pàgina \'quant a\' (en lloc d\'un \'quant a\' global).';
+$lang['checkage'] = 'Advertir sobre possibles traduccions obsoletes.';
+$lang['display'] = 'Selecciona el que vulguis que es mostri al seleccionador d\'idioma. Recorda que els experts en usabilitat no recomanen fer servir banderes de país.';
+$lang['copytrans'] = 'Copiar el text en l\'idioma original en l\'editor quan s\'inicia una nova traducció?';
+$lang['show_path'] = 'Mostrar la ruta a la pàgina de traducció que falta?';
diff --git a/platform/www/lib/plugins/translation/lang/ca/totranslate.txt b/platform/www/lib/plugins/translation/lang/ca/totranslate.txt
new file mode 100644
index 0000000..96820e8
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ca/totranslate.txt
@@ -0,0 +1 @@
+ARREGLA'M **Aquesta pàgina encara no està totalment traduïda. Si us plau, ajuda completant la traducció.**\\//(treu aquest paràgraf en acabar la traducció)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/cs/lang.php b/platform/www/lib/plugins/translation/lang/cs/lang.php
new file mode 100644
index 0000000..faca1ae
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/cs/lang.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Jaroslav Lichtblau <jlichtblau@seznam.cz>
+ */
+$lang['translations'] = 'Překlady této stránky';
+$lang['outdated'] = 'Tento překlad je starší než <a href="%s" class="wikilink1">originální stránka</a> a nejspíše i zastaralý.';
+$lang['diff'] = 'Zobrazit <a href="%s" class="wikilink1">změny</a>.';
+$lang['transloaded'] = 'Text pro pÅ™eklad této stránky do %s byl pro ulehÄení pÅ™ekládání automaticky naÄten.<br />Můžete ale použít pÅ™edeÅ¡lé dostupné pÅ™eklady: %s.';
+$lang['menu'] = 'zastaralé a chybějící překlady';
+$lang['missing'] = 'Chybí!';
+$lang['old'] = 'zastaralý';
+$lang['current'] = 'aktuální';
+$lang['path'] = 'Cesta';
diff --git a/platform/www/lib/plugins/translation/lang/cs/settings.php b/platform/www/lib/plugins/translation/lang/cs/settings.php
new file mode 100644
index 0000000..f24ab34
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/cs/settings.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Jaroslav Lichtblau <jlichtblau@seznam.cz>
+ */
+$lang['translations'] = 'Seznam přeložených jazyků (ISO kódů) oddělený mezerami. Nezahrnujte defaultní jazyk!';
+$lang['translationns'] = 'Chcete-li udržovat překlad jen pro konkrétní jmenný prostor, vložte jeho jméno sem.';
+$lang['skiptrans'] = 'Pokud jméno stránky obsahuje tento regulární výraz, nezobrazovat překladové menu.';
+$lang['dropdown'] = 'Použít rozbalovací seznam dostupných pÅ™ekladů (doporuÄeno pro 5 a více jazyků).';
+$lang['translateui'] = 'Mělo by se přeložit i uživatelské rozhraní při změně překladu stránky?';
+$lang['redirectstart'] = 'Má hlavní stránka automaticky pÅ™esmÄ›rovávat na dostupnou jazykovou verzi jmenného prostoru dle nastavení jazyka prohlížeÄe?';
+$lang['about'] = 'Vložte jméno stránky s nápovědou ohledně možnosti překládat stránky na DokuWiki s pomoci Translation pluginu. Tento odkaz bude k dispozici z výběru přeložených jazyků.';
+$lang['localabout'] = 'Použít přeložené verze stran o aplikaci (namísto té globální).';
+$lang['checkage'] = 'Upozorňovat na možné zastaralé překlady.';
+$lang['display'] = 'Vybrat co se má zobrazovat v menu pro výbÄ›r jazyka. Experti na použitelnost webu nedoporuÄují zobrazování obrázků vlajek zemí pro výbÄ›r jazyka.';
+$lang['copytrans'] = 'Kopírovat výchozí jazykovou verzi do editoru pro nový překlad?';
+$lang['show_path'] = 'Zobrazit cestu na chybějící stránku překladu?';
diff --git a/platform/www/lib/plugins/translation/lang/cs/totranslate.txt b/platform/www/lib/plugins/translation/lang/cs/totranslate.txt
new file mode 100644
index 0000000..5cdeee6
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/cs/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Tato stránka jeÅ¡tÄ› není plnÄ› pÅ™eložena. Pomozte s dokonÄením pÅ™ekladu.**\\ //(odstraňte tento odstavec, jakmile je pÅ™eklad dokonÄen)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/cy/lang.php b/platform/www/lib/plugins/translation/lang/cy/lang.php
new file mode 100644
index 0000000..18e12e7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/cy/lang.php
@@ -0,0 +1,11 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Alan Davies <ben.brynsadler@gmail.com>
+ */
+$lang['translations'] = 'Cyfieithiadau\'r dudalen hon';
+$lang['outdated'] = 'Mae\'r cyfieithiad hwn yn hÅ·n na\'r <a href="%s" class="wikilink1">dudalen wreiddiol</a> a gall fod wedi dyddio.';
+$lang['diff'] = 'Gweld beth sydd wedi <a href="%s" class="wikilink1">newid</a>.';
+$lang['transloaded'] = 'Cafodd cynnwys y dudalen hon mewn %s ei raglwytho er mwyn hwyluso\'r cyfieithu.<br />Er gallwch chi seilio\'ch cyfieithiad ar y cyfieithiadau canlynol sy\'n bodoli\'n barod: %s';
diff --git a/platform/www/lib/plugins/translation/lang/cy/settings.php b/platform/www/lib/plugins/translation/lang/cy/settings.php
new file mode 100644
index 0000000..21d5315
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/cy/settings.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Alan Davies <ben.brynsadler@gmail.com>
+ */
+$lang['translations'] = 'Rhestr gwahanwyd gan goma o iaith gyfieithu (codau ISO)';
+$lang['translationns'] = 'Os ydych chi am osod y cyfieithiadau o dan namespace penodol yn unig, rhowch e yma.';
+$lang['skiptrans'] = 'Pan fydd enw\'r dudalen yn bodloni\'r mynegiad rheolaidd, paid dangos y dewislen cyfieithu.';
+$lang['dropdown'] = 'Defnyddio cwymprestr i ddangos y cyfieithiadau (awgrymir am fwy na 5 iaith).';
+$lang['translateui'] = 'A ddylai iaith rhyngwyneb y defnyddiwr gael ei newid mewn namespaces ieithoedd estron hefyd?';
+$lang['redirectstart'] = 'A ddylai\'r dudalen gychwyn ailgyfeirio yn awtomatig i mewn i namespace iaith gan ddefnyddio datgeliad iaith y porwr?';
+$lang['about'] = 'Rhowch enw tudalen yma lle caiff y nodwedd cyfieithu ei esbonio ar gyfer eich defnyddwyr. Caiff ei gysylltu o\'r dewisydd iaith.';
+$lang['localabout'] = 'Defnyddio fersiynau lleoledig o\'r dudalen \'ynghylch\' (yn hytrach nag un dudalen \'ynghylch\' gyffredinol).';
+$lang['checkage'] = 'Rhybuddio ynghylch cyfieithiadau sydd efallai wedi dyddio.';
+$lang['display'] = 'Dewiswch yr hyn hoffech chi weld yn y dewisydd iaith. \'Dyw defnyddio baneri gwlad ddim i\'w awgrymu yn ôl arbenigwyr.';
+$lang['copytrans'] = 'Copïo testun y iaith wreiddiol i\'r golygydd wrth ddechrau cyfieithiad newydd?';
diff --git a/platform/www/lib/plugins/translation/lang/cy/totranslate.txt b/platform/www/lib/plugins/translation/lang/cy/totranslate.txt
new file mode 100644
index 0000000..da8bfaa
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/cy/totranslate.txt
@@ -0,0 +1 @@
+FIXME **'Dyw'r dudalen heb ei chyfieithu'n llawn eto. Cynorthwywch gan gyflawni'r cyfieithiad.**\\ //(tynnych y paragraff hwn unwaith i chi orffen y cyfieithu)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/da/lang.php b/platform/www/lib/plugins/translation/lang/da/lang.php
new file mode 100644
index 0000000..af5f450
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/da/lang.php
@@ -0,0 +1,12 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Markus Petersen <markus@mdev.dk>
+ * @author Soren Birk <soer9648@eucl.dk>
+ */
+$lang['translations'] = 'Oversættelser af denne side';
+$lang['outdated'] = 'Denne oversættelse er ældre end den <a href="%s" class="wikilink1">originale side</a> og er muligvis forældet.';
+$lang['diff'] = 'Se hvad der er <a href="%s" class="wikilink1">ændret</a>.';
+$lang['transloaded'] = 'Indholdet af denne sides oversættelse i %s er blevet præ-indlæst for lettere oversættelse. <br />Du kan basere din oversættelse på følgende nuværende oversættelser: %s.';
diff --git a/platform/www/lib/plugins/translation/lang/da/settings.php b/platform/www/lib/plugins/translation/lang/da/settings.php
new file mode 100644
index 0000000..7b43734
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/da/settings.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Markus Petersen <markus@mdev.dk>
+ * @author Soren Birk <soer9648@eucl.dk>
+ * @author Jacob Palm <mail@jacobpalm.dk>
+ */
+$lang['translations'] = 'Mellemrums-separeret liste a oversættelsessprog (ISO koder). Lad være med at inkludere standardsproget.';
+$lang['translationns'] = 'Hvis du kun vil have oversættelser under et bestemt navnerum, indsæt det her.';
+$lang['skiptrans'] = 'Hvis navnet på siden matcher dette regulære udtryk, så lad være med at vise oversættelsesmenuen.';
+$lang['dropdown'] = 'Benyt en rulleliste til at vise oversættelserne (anbefales til 5 sprog eller mere).';
+$lang['translateui'] = 'Skal brugerfladens sprog også skiftes i fremmedsprogets navnerum?';
+$lang['redirectstart'] = 'Skal startsiden automatisk henvise til et sprog-navnerum vha browserens sprog-genkendelse?';
+$lang['about'] = 'Skriv et sidenavn her hvor oversættelsesfunktionen er forklaret for dine brugere. Siden vil blive linket til fra sprogvælgeren.';
+$lang['localabout'] = 'Anvend lokaliserede versions af "Om" siden (i stedet for en global "Om" side)';
+$lang['checkage'] = 'Advar om mulige forældede oversættelser.';
+$lang['display'] = 'Angiv hvad du ønsker der skal vises menuen til valg af sprog. Bemærk venligst, at det frarådes at benytte landeflag til sprogvalg.';
+$lang['copytrans'] = 'Kopier tekst fra originalt sporg ind i editorern når en ny oversættelse påbegyndes?';
diff --git a/platform/www/lib/plugins/translation/lang/da/totranslate.txt b/platform/www/lib/plugins/translation/lang/da/totranslate.txt
new file mode 100644
index 0000000..3109105
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/da/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Denne side er endnu ikke fuldt oversat. Måske kan du hjælpe med at færdiggøre oversættelsen?**\\ //(fjern dette afsnit når siden er oversat)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/de-informal/lang.php b/platform/www/lib/plugins/translation/lang/de-informal/lang.php
new file mode 100644
index 0000000..83c73aa
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/de-informal/lang.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author F. Mueller-Donath <j.felix@mueller-donath.de>
+ */
+$lang['translations'] = 'Ãœbersetzungen dieser Seite';
+$lang['outdated'] = 'Diese Übersetzung ist älter als das <a href="%s" class="wikilink1">Original</a> und ist eventuell veraltet.';
+$lang['diff'] = '<a href="%s" class="wikilink1">Änderungen</a> zeigen.';
+$lang['transloaded'] = 'Der Inhalt dieser Seite auf %s wurde in den Editor geladen um die Ãœbersetzung zu erleichtern.<br />Du kannst deine Arbeit auch mit einer der folgenden vorhandenen Ãœbersetzungen beginnen: %s.';
+$lang['menu'] = 'veraltete und fehlende Ãœbersetzungen';
+$lang['missing'] = 'Fehlt!';
+$lang['old'] = 'veraltet';
+$lang['current'] = 'aktuell';
+$lang['path'] = 'Pfad';
diff --git a/platform/www/lib/plugins/translation/lang/de-informal/settings.php b/platform/www/lib/plugins/translation/lang/de-informal/settings.php
new file mode 100644
index 0000000..a0db7a2
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/de-informal/settings.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author F. Mueller-Donath <j.felix@mueller-donath.de>
+ */
+$lang['translations'] = 'Liste der Sprachen (ISO codes), mittels Leerzeichen separiert. Die Default-Sprache nicht angeben.';
+$lang['translationns'] = 'Wenn die Ãœbersetzung nur unterhalb eines Namensraumes gelten soll, diesen hier angeben.';
+$lang['skiptrans'] = 'Wenn der Seitennamen dem regulären Ausdruck entspricht, dann den Sprachumschalter nicht anzeigen.';
+$lang['dropdown'] = 'Eine Auswahlliste benutzen, um die Übersetzungen anzuzeigen (zu bevorzugen bei mehr als fünf Sprachen).';
+$lang['translateui'] = 'Soll die Sprache der Benutzerschnittstelle auch in die jeweilige Fremdspache umgeschaltet werden?';
+$lang['redirectstart'] = 'Anhand des Browsers des Benutzers erkennen, welche Sprache angezeigt werden soll. (Startseite leitet in den passenden Namensraum um).';
+$lang['about'] = 'Gebe hier eine Seite an, welche den Mechanismus der Übersetzung erklärt. Sie wird vom Sprachumschalter verlinkt.';
+$lang['localabout'] = 'Sprachspezifische Versionen der oben angegebenen Seite (anstelle einer globalen) nutzen.';
+$lang['checkage'] = 'Warnungen von möglicherweise veralteten Übersetzungen anzeigen.';
+$lang['display'] = 'Gib hier an welches/r Symbol/Text im Sprachumschalter angezeigt werden soll. (Die Nutzung von länderspezifischen Flaggen wird aus Gründen der Benutzbarkeit nicht empfohlen.)';
+$lang['copytrans'] = 'Original Sprachversion in den Editor kopieren wenn eine neue Ãœbersetzung begonnen wird?';
+$lang['show_path'] = 'Seitenpfad in der Ãœbersicht der fehlenden Ãœbersetzungen anzeigen?';
diff --git a/platform/www/lib/plugins/translation/lang/de-informal/totranslate.txt b/platform/www/lib/plugins/translation/lang/de-informal/totranslate.txt
new file mode 100644
index 0000000..934a71e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/de-informal/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Diese Seite wurde noch nicht vollständig übersetzt. Bitte hilf bei der Übersetzung.**\\ //(diesen Absatz entfernen, wenn die Übersetzung abgeschlossen wurde)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/de/lang.php b/platform/www/lib/plugins/translation/lang/de/lang.php
new file mode 100644
index 0000000..750b6c6
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/de/lang.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+$lang['translations'] = 'Ãœbersetzungen dieser Seite';
+$lang['outdated'] = 'Diese Übersetzung ist älter als das <a href="%s" class="wikilink1">Original</a> und ist eventuell veraltet.';
+$lang['diff'] = '<a href="%s" class="wikilink1">Änderungen</a> zeigen.';
+$lang['transloaded'] = 'Der Inhalt dieser Seite auf %s wurde in den Editor geladen um die Übersetzung zu erleichtern.<br />Sie können Ihre Arbeit auch mit einer der folgenden vorhandenen Übersetzungen beginnen: %s.';
+$lang['menu'] = "veraltete und fehlende Ãœbersetzungen";
+$lang['missing'] = 'Fehlt!';
+$lang['old'] = 'veraltet';
+$lang['current'] = 'aktuell';
+$lang['path'] = 'Pfad';
diff --git a/platform/www/lib/plugins/translation/lang/de/settings.php b/platform/www/lib/plugins/translation/lang/de/settings.php
new file mode 100644
index 0000000..ce7fbda
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/de/settings.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+$lang['translations'] = 'Liste der Sprachen (ISO codes), mittels Leerzeichen separiert. Die Default-Sprache nicht angeben.';
+$lang['translationns'] = 'Wenn die Ãœbersetzung nur unterhalb eines Namensraumes gelten soll, diesen hier angeben.';
+$lang['skiptrans'] = 'Wenn der Seitennamen dem regulären Ausdruck entspricht, dann den Sprachumschalter nicht anzeigen.';
+$lang['dropdown'] = 'Eine Auswahlliste benutzen, um die Übersetzungen anzuzeigen (zu bevorzugen bei mehr als fünf Sprachen).';
+$lang['translateui'] = 'Soll die Sprache der Benutzerschnittstelle auch in die jeweilige Fremdspache umgeschaltet werden?';
+$lang['redirectstart'] = 'Anhand des Browsers des Benutzers erkennen, welche Sprache angezeigt werden soll. (Startseite leitet in den passenden Namensraum um).';
+$lang['about'] = 'Geben Sie hier eine Seite an, welche den Mechanismus der Übersetzung erklärt. Sie wird vom Sprachumschalter verlinkt.';
+$lang['localabout'] = 'Sprachspezifische Versionen der oben angegebenen Seite (anstelle einer globalen) nutzen.';
+$lang['checkage'] = 'Warnungen von möglicherweise veralteten Übersetzungen anzeigen.';
+$lang['display'] = 'Geben Sie an welches/r Symbol/Text im Sprachumschalter angezeigt werden soll. (Die Nutzung von länderspezifischen Flaggen wird aus Gründen der Benutzbarkeit nicht empfohlen.)';
+$lang['copytrans'] = 'Original Sprachversion in den Editor kopieren wenn eine neue Ãœbersetzung begonnen wird?';
+$lang['show_path'] = 'Seitenpfad in der Ãœbersicht der fehlenden Ãœbersetzungen anzeigen?';
diff --git a/platform/www/lib/plugins/translation/lang/de/totranslate.txt b/platform/www/lib/plugins/translation/lang/de/totranslate.txt
new file mode 100644
index 0000000..37d03ae
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/de/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Diese Seite wurde noch nicht vollständig übersetzt. Bitte helfen Sie bei der Übersetzung.**\\ //(diesen Absatz entfernen, wenn die Übersetzung abgeschlossen wurde)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/en/lang.php b/platform/www/lib/plugins/translation/lang/en/lang.php
new file mode 100644
index 0000000..304d298
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/en/lang.php
@@ -0,0 +1,11 @@
+<?php
+
+$lang['translations'] = 'Translations of this page';
+$lang['outdated'] = 'This translation is older than the <a href="%s" class="wikilink1">original page</a> and might be outdated.';
+$lang['diff'] = 'See what has <a href="%s" class="wikilink1">changed</a>.';
+$lang['transloaded'] = 'The contents of this page\'s translation in %s have been pre-loaded for easy translation.<br />But you can base your translation on the following existing translations: %s.';
+$lang['menu'] = "outdated and missing translations";
+$lang['missing'] = 'Missing!';
+$lang['old'] = 'outdated';
+$lang['current'] = 'up-to-date';
+$lang['path'] = 'Path';
diff --git a/platform/www/lib/plugins/translation/lang/en/settings.php b/platform/www/lib/plugins/translation/lang/en/settings.php
new file mode 100644
index 0000000..bda50a6
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/en/settings.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * English language file
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+$lang['translations'] = 'Space separated list of translation languages (ISO codes).';
+$lang['translationns'] = 'If you only want translations below a certain namespace, put it here.';
+$lang['skiptrans'] = 'When the pagename matches this regular expression, don\'t show the translation menu.';
+$lang['dropdown'] = 'Use a dropdown list to display the translations (recommended for more than 5 languages).';
+$lang['translateui'] = 'Should the language of the user interface be switched in foreign language namespaces, too?';
+$lang['redirectstart'] = 'Should the start page automatically redirect into a language namespace using browser language detection?';
+$lang['about'] = 'Enter a pagename here where the translation feature is explained for your users. It will be linked from the language selector.';
+$lang['localabout'] = 'Use localized versions of about page (instead of one global about page).';
+$lang['checkage'] = 'Warn about possibly outdated translations.';
+$lang['display'] = 'Select what you\'d like to have shown in the language selector. Note that using country flags for language selection is not recommended by usability experts.';
+
+$lang['copytrans'] = 'Copy original language text into the editor when starting a new translation?';
+$lang['show_path'] = 'Show path on the missing translation page?'; \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/en/totranslate.txt b/platform/www/lib/plugins/translation/lang/en/totranslate.txt
new file mode 100644
index 0000000..ab42d5f
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/en/totranslate.txt
@@ -0,0 +1 @@
+FIXME **This page is not fully translated, yet. Please help completing the translation.**\\ //(remove this paragraph once the translation is finished)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/eo/lang.php b/platform/www/lib/plugins/translation/lang/eo/lang.php
new file mode 100644
index 0000000..3b325da
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/eo/lang.php
@@ -0,0 +1,11 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Robert Bogenschneider <bogi@uea.org>
+ */
+$lang['translations'] = 'Tradukoj de tiu paÄo';
+$lang['outdated'] = 'Tiu traduko estas pli malnova ol la <a href="%s" class="wikilink1">origina paÄo</a> kaj povus esti malaktuala.';
+$lang['diff'] = 'Vidi kio <a href="%s" class="wikilink1">ÅanÄiÄis</a>.';
+$lang['transloaded'] = 'La enhavo de la paÄtraduko en %s disponeblas por facila tradukado.<br />Sed vi povas bazi vian tradukon sur la sekvaj tradukoj: %s.';
diff --git a/platform/www/lib/plugins/translation/lang/eo/settings.php b/platform/www/lib/plugins/translation/lang/eo/settings.php
new file mode 100644
index 0000000..6edf642
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/eo/settings.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Robert Bogenschneider <bogi@uea.org>
+ */
+$lang['translations'] = 'Spaco-disigita listo de tradukaj lingvoj (ISO-kodoj).';
+$lang['translationns'] = 'Se vi volas traduki nur ene de certa nomspaco, indiku Äin.';
+$lang['skiptrans'] = 'Ne montri la tradukmenuon, kiam la paÄnomo kongruas al tiu regula esprimo.';
+$lang['dropdown'] = 'Uzi falmenuon por montri la tradukojn (rekomendata por pli ol 5 lingvoj).';
+$lang['translateui'] = 'Ĉu ankaÅ­ ÅanÄi la lingvon de la uzanto-interfaco en alilingvaj nomspacoj?';
+$lang['redirectstart'] = 'Ĉu la startpaÄo aÅ­tomate redirektiÄu al lingva nomspaco laÅ­ foliumila rekonado?';
+$lang['about'] = 'PaÄnomo, kie klariÄas la tradukad-funkcio al uzantoj. La lingvo-selektilo ligos tien.';
+$lang['localabout'] = 'Uzi lokajn versiojn de la pri-paÄo (anstataÅ­ unu Äenerala pri-paÄo).';
+$lang['checkage'] = 'Averti pri eble malaktualaj tradukoj.';
+$lang['display'] = 'Kion montri en la lingvo-selektilo. Notu ke uzeblec-fakuloj ne rekomendas uzi landajn flagetojn por lingvo-elekto.';
+$lang['copytrans'] = 'Ĉu kopii la originlingvan tekston en la redaktokampon por komenci novan tradukon?';
diff --git a/platform/www/lib/plugins/translation/lang/eo/totranslate.txt b/platform/www/lib/plugins/translation/lang/eo/totranslate.txt
new file mode 100644
index 0000000..1987959
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/eo/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Tiu paÄo ankoraÅ­ ne plene tradukiÄis. Bv. helpi kompletigi la tradukon.**\\ //(forigu tiun alineon post fintraduko)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/es/lang.php b/platform/www/lib/plugins/translation/lang/es/lang.php
new file mode 100644
index 0000000..f4786c2
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/es/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Domingo Redal <docxml@gmail.com>
+ * @author Camilo Sampedro <sampedro1903@gmail.com>
+ * @author carlos <carloscyb@gmail.com>
+ */
+$lang['translations'] = 'Traducciones de esta página';
+$lang['outdated'] = 'Esta traducción es más antigua que la <a href="%s" class="wikilink1">página original</a> y podría estar obsoleta.';
+$lang['diff'] = 'Ver lo que <a href="%s" class="wikilink1">ha cambiado</a>.';
+$lang['transloaded'] = 'Los contenidos de la traducción de esta página en %s han sido precargados para facilitar la traducción.<br />Pero puedes basar tu traducción en las siguientes traducciones existentes: %s.';
+$lang['menu'] = 'traducciones obsoletas y ausentes';
+$lang['missing'] = '¡Ausente!';
+$lang['old'] = 'obsoleta';
+$lang['current'] = 'actualizado';
+$lang['path'] = 'ruta';
diff --git a/platform/www/lib/plugins/translation/lang/es/settings.php b/platform/www/lib/plugins/translation/lang/es/settings.php
new file mode 100644
index 0000000..723fb12
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/es/settings.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Domingo Redal <docxml@gmail.com>
+ * @author Cristina Amor <princesa.7@gmail.com>
+ * @author Camilo Sampedro <sampedro1903@gmail.com>
+ * @author carlos <carloscyb@gmail.com>
+ */
+$lang['translations'] = 'Lista de lenguajes para traducción (Códigos ISO), separados por espacios. No incluir el lenguaje por defecto.';
+$lang['translationns'] = 'Si sólo quieres traducciones en determinados espacios de nombre, indícalos aquí.';
+$lang['skiptrans'] = 'Cuando el nombre de la página concuerda con esta expresión regular, no mostrar el menú de traducción.';
+$lang['dropdown'] = 'Utiliza una lista desplegable para mostrar las traducciones (recomendado para más de 5 idiomas).';
+$lang['translateui'] = '¿También debería el lenguaje del interfaz de usuario cambiarse en los espacios de nombre foráneos?';
+$lang['redirectstart'] = '¿Debería la página principal redireccionar automáticamente a una página de un idioma según sea detectado por el navegador?';
+$lang['about'] = 'Introduce aquí un nombre de página donde se explique a tus usuarios la funcionalidad de traducción. Se enlazará desde el selector de lenguaje.';
+$lang['localabout'] = 'Utiliza versiones localizadas de la página \'acerca de\' (en lugar de una página \'acerca de\' global)';
+$lang['checkage'] = 'Alertar sobre posibles traducciones obsoletas.';
+$lang['display'] = 'Selecciona lo que quieras que sea mostrado en el selector de idioma. Ten en cuenta que el uso de parámetros de país para la selección de idioma no está recomendada por los expertos en usabilidad.';
+$lang['copytrans'] = '¿Mostrar el texto en el idioma original en el editor cuando se comienza una nueva traducción?';
+$lang['show_path'] = '¿Muestra la ruta en la página de traducción ausente?';
diff --git a/platform/www/lib/plugins/translation/lang/es/totranslate.txt b/platform/www/lib/plugins/translation/lang/es/totranslate.txt
new file mode 100644
index 0000000..6dc2803
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/es/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Esta página no está completamente traducida, aún. Por favor, contribuye a su traducción.**\\ //(Elimina este párrafo una vez la traducción esté completa)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/fa/lang.php b/platform/www/lib/plugins/translation/lang/fa/lang.php
new file mode 100644
index 0000000..2abecd7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/fa/lang.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Sam01 <m.sajad079@gmail.com>
+ */
+$lang['translations'] = 'ترجمه‌های این صÙحه';
+$lang['outdated'] = 'این ترجمه از a href="%s" class="wikilink1">صÙحه‌ی اصلی</a> قدیمی‌تر است Ùˆ ممکن است منسوخ شده باشد.';
+$lang['diff'] = 'ببینید چه چیزی <a href="%s" class="wikilink1">تغییر کرده</a>.';
+$lang['transloaded'] = 'محتویات این ترجمه‌ی صÙحه در %s برای ترجمه‌ی آسان از قبل پر شده‌است. <br />اما شما می‌توانید پایه‌ی ترجمه‌هایتان را در ترجمه‌های موجود زیر ببینید: %s.';
+$lang['menu'] = 'ترجمه‌های منسوخ‌ شده و پیدا نشده';
+$lang['missing'] = 'پیدا نشده!';
+$lang['old'] = 'منسوخ شده';
+$lang['current'] = 'به روز';
+$lang['path'] = 'مسیر';
diff --git a/platform/www/lib/plugins/translation/lang/fa/settings.php b/platform/www/lib/plugins/translation/lang/fa/settings.php
new file mode 100644
index 0000000..2331783
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/fa/settings.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Sam01 <m.sajad079@gmail.com>
+ */
+$lang['translations'] = 'Ùضای لیست جداشده‌ی زبان‌های ترجمه شده (کدهای آی‌اس‌او)';
+$lang['translationns'] = 'اگر شما Ùقط می‌خواهید ترجمه‌ها زیر یک Ùضای‌نام خاص باشند، اینجا قرار دهید.';
+$lang['skiptrans'] = 'وقتی نام‌صÙحه با عبارات منظم هم‌خوانی داشت، منوی ترجمه را نشان نده.';
+$lang['dropdown'] = 'استÙاده از یک لیست کشویی برای نمایش ترجمه (توصیه شده برای بیشتر از Ûµ زبان)';
+$lang['translateui'] = 'باید زبان رابط کاربر در زبان‌های خارجی Ùضای‌نام تغییر یابد، همچنین؟';
+$lang['redirectstart'] = 'باید صÙحه‌ی آغازین به‌طور خودکار به زبانی Ú©Ù‡ Ùضای‌نام توسط مرورگر کش٠شده، تغییرمسیر کند؟';
+$lang['about'] = 'وارد کردن یک نام‌صÙحه جایی Ú©Ù‡ ';
+$lang['localabout'] = 'استÙاده از نسخه‌های متمرکز شده‌ی درباره صÙحه (به جای یک جهانی درباره صÙحه)';
+$lang['checkage'] = 'هشدار درمورد ترجمه‌های احتمالا منسوخ شده.';
+$lang['display'] = 'انتخاب این‌که شما Ú†Ù‡ چیزی را می‌پسندید تا در انتخابگر زبان نمایش داده شود. توجه داشته‌باشید Ú©Ù‡ استÙاده از پرچم کشورها برای انتخابگر زبان توسط کارشناسان توصیه نمی‌شود.';
+$lang['copytrans'] = 'کپی‌کردن زبان اصلی متن داخل ویرایشگر وقتی که یک ترجمه جدید آغار می‌شود؟';
+$lang['show_path'] = 'نمایش مسیر در ترجمه‌ی پیدانشده‌ی صÙحه‌‌ها؟';
diff --git a/platform/www/lib/plugins/translation/lang/fa/totranslate.txt b/platform/www/lib/plugins/translation/lang/fa/totranslate.txt
new file mode 100644
index 0000000..665eb5b
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/fa/totranslate.txt
@@ -0,0 +1 @@
+تعمیرم Ú©Ù† **این صÙحه کامل ترجمه نشده، اکنون. لطÙا برای کامل‌شدنش Ú©Ù…Ú© کنید.**\\ //(بعد از پایان ترجمه این بند را از ترجمه حذ٠کنید)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/fr/lang.php b/platform/www/lib/plugins/translation/lang/fr/lang.php
new file mode 100644
index 0000000..d8a8b9d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/fr/lang.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author NicolasFriedli <nicolas@theologique.ch>
+ * @author Gilles-Philippe Morin <gilles.philippe.morin@gmail.com>
+ * @author Schplurtz le Déboulonné <schplurtz@laposte.net>
+ */
+$lang['translations'] = 'Traductions de cette page';
+$lang['outdated'] = 'Cette traduction est plus ancienne que <a href="%s" class="wikilink1">la page originale</a> et est peut-être dépassée.';
+$lang['old'] = 'dépassée';
+$lang['diff'] = 'Voir ce qui a <a href="%s" class="wikilink1">changé</a>.';
+$lang['transloaded'] = 'Le contenu de cette page en %s a été pré-chargé pour faciliter la traduction.<br/> Mais vous pouvez baser votre traduction sur les traductions existantes: %s';
+$lang['menu'] = 'traductions dépassées et manquantes';
+$lang['missing'] = 'Manquante!';
+$lang['current'] = 'à jour';
+$lang['path'] = 'Chemin';
diff --git a/platform/www/lib/plugins/translation/lang/fr/settings.php b/platform/www/lib/plugins/translation/lang/fr/settings.php
new file mode 100644
index 0000000..74869ce
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/fr/settings.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Guy Brand <gb@isis.u-strasbg.fr>
+ * @author Vincent Feltz <psycho@feltzv.fr>
+ * @author NicolasFriedli <nicolas@theologique.ch>
+ * @author Schplurtz le Déboulonné <schplurtz@laposte.net>
+ */
+$lang['translations'] = 'Liste des langues disponibles séparées par des espaces (codes ISO).';
+$lang['translationns'] = 'Si vous souhaitez ne traduire qu\'une certaine catégorie, indiquez-la ici.';
+$lang['skiptrans'] = 'Quand le nom de la page correspond à cette expression régulière, ne pas montrer le menu de traduction.';
+$lang['dropdown'] = 'Utiliser un menu déroulant pour afficher les traductions (recommandé pour plus de 5 langues).';
+$lang['translateui'] = 'Faut-il changer la langue de l\'interface utilisateur dans les catégories traduites ?';
+$lang['redirectstart'] = 'La page de départ devrait-elle rediriger vers une catégorie traduite en utilisant la détection de langue du navigateur ?';
+$lang['about'] = 'Entrez ici un nom de page où la fonctionnalité de traduction est expliquée aux utilisateurs. Elle sera accessible depuis le sélecteur de langue.';
+$lang['localabout'] = 'Utiliser des versions traduites de la page à propos (au lieu d\'une page à propos globale).';
+$lang['checkage'] = 'Avertir de la possibilité de traductions dépassées.';
+$lang['display'] = 'Sélectionnez ce que vous voudriez afficher dans le sélecteur de langue. Notez qu\'utiliser les drapeaux de pays pour la sélection de langue n\'est pas recommandé par les experts en ergonomie.';
+$lang['copytrans'] = 'Copier le texte en langue source dans l\'éditeur quand une nouvelle traduction est lancée ?';
+$lang['show_path'] = 'Montrer les chemins sur la page des traductions manquantes ?';
diff --git a/platform/www/lib/plugins/translation/lang/fr/totranslate.txt b/platform/www/lib/plugins/translation/lang/fr/totranslate.txt
new file mode 100644
index 0000000..3603d4e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/fr/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Cette page n'est pas encore traduite entièrement. Merci de terminer la traduction**\\ //(supprimez ce paragraphe une fois la traduction terminée)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/hr/lang.php b/platform/www/lib/plugins/translation/lang/hr/lang.php
new file mode 100644
index 0000000..80e9399
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/hr/lang.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Davor Turkalj <turki.bsc@gmail.com>
+ */
+$lang['translations'] = 'Prijevodi ove stranice';
+$lang['outdated'] = 'Prijevod ove stranice je stariji od <a href="%s" class="wikilink1">originalne stranice</a> i može biti zastario.';
+$lang['diff'] = 'Pogledajte Å¡to je <a href="%s" class="wikilink1">izmijenjeno</a>.';
+$lang['transloaded'] = 'Sadržaj ove stranice u jeziku %s je napunjeno radi lakšeg prevođenja.<br />Ali možete bazirati Vaš prijevod i prema slijedećim raspoloživim prijevodima: %s.';
+$lang['menu'] = 'zastarjeli i nedostajući prijevodi';
+$lang['missing'] = 'Nedostaje!';
+$lang['old'] = 'zastarjelo';
+$lang['current'] = 'ažuran';
+$lang['path'] = 'Staza';
diff --git a/platform/www/lib/plugins/translation/lang/hr/settings.php b/platform/www/lib/plugins/translation/lang/hr/settings.php
new file mode 100644
index 0000000..d1769cc
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/hr/settings.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Davor Turkalj <turki.bsc@gmail.com>
+ */
+$lang['translations'] = 'Razmacima odvojena lista podržanih jezika (ISO oznake).';
+$lang['translationns'] = 'Ako želite prijevode samo ispod određenog imenskog prostora, navedite ga ovdje.';
+$lang['skiptrans'] = 'Kada ime stranice odgovara ovom regularnom izrazu, ne prikazujte meni za prijevode.';
+$lang['dropdown'] = 'Koristi padajuću listu za prikaz prijevoda (preporuÄeno kada ima viÅ¡e od 5 jezika).';
+$lang['translateui'] = 'Da li da jezik korisniÄkog suÄelja takoÄ‘er bude prebaÄen u jezik stranog imenskog prostora ?';
+$lang['redirectstart'] = 'Da li da se poÄetna strana automatski preusmjeri na imenski prostor koristeći detektirani jezik preglednika?';
+$lang['about'] = 'Unesi naziv stranice gdje je korisnicima pojašnjene mogućnosti prevođenja. Ona će biti povezana na izbornik jezika.';
+$lang['localabout'] = 'Koristi lokaliziranu inaÄicu "about" stranice (umjesto jedinstvene globalne)';
+$lang['checkage'] = 'Upozori o mogućem zastarjelom prijevodu.';
+$lang['display'] = 'Odaberite Å¡to želite da bude prikazano u izborniku jezika. Budite svjesni da koriÅ¡tenje zastava za odabir jezika nije preporuÄeno od strane eksperata.';
+$lang['copytrans'] = 'Kopirati originalni tekst u editor kada otvorite novi prijevod ?';
+$lang['show_path'] = 'Prikaži stazu do nedostajuće stranice s prijevodom?';
diff --git a/platform/www/lib/plugins/translation/lang/hr/totranslate.txt b/platform/www/lib/plugins/translation/lang/hr/totranslate.txt
new file mode 100644
index 0000000..b49e869
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/hr/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Ova stranica još nije prevedena u cijelosti. Molimo pomognite u njenom prijevodu.**\\ //(uklonite ovaj paragraf jednom kada je prevođenje završeno)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/hu/lang.php b/platform/www/lib/plugins/translation/lang/hu/lang.php
new file mode 100644
index 0000000..6a576ff
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/hu/lang.php
@@ -0,0 +1,11 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Marina Vladi <deldadam@gmail.com>
+ */
+$lang['translations'] = 'Oldal fordításai';
+$lang['outdated'] = 'A fordítás régebbi, mint az <a href="%s" class="wikilink1">eredeti oldal</a>, ezért lehet, hogy már elavult.';
+$lang['diff'] = 'Módosítások <a href="%s" class="wikilink1">megtekintése</a>.';
+$lang['transloaded'] = 'Az oldal tartalmának %s nyelvi fordítását előre betöltöttem a könnyebb módosítás érdekében.<br />Ugyanakkor a fordítást elvégezhetjük a már létező %s fordítás alapján is.';
diff --git a/platform/www/lib/plugins/translation/lang/hu/settings.php b/platform/www/lib/plugins/translation/lang/hu/settings.php
new file mode 100644
index 0000000..5a27108
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/hu/settings.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Marina Vladi <deldadam@gmail.com>
+ */
+$lang['translations'] = 'Szóközzel elválasztott lista a nyelvi fordításokról (ISO-kódokkal).';
+$lang['translationns'] = 'Ha csak egy bizonyos névtér alatt lévő fordítást szeretnénk, tegyük ide.';
+$lang['skiptrans'] = 'Ha az oldal neve illeszkedik ehhez a reguláris kifejezéshez, ne jelenjen meg a fordítások menüje.';
+$lang['dropdown'] = 'Legördülő lista használata a fordításokhoz (5 nyelvnél több esetén javasolt).';
+$lang['translateui'] = 'Módosuljon a felhasználói felület nyelve is idegen nyelvi névterek alatt?';
+$lang['redirectstart'] = 'Ãtirányítsuk automatikusan a kezdÅ‘oldalt abba a nyelvi névtérbe, amely nyelv a böngészÅ‘ben van beállítva?';
+$lang['about'] = 'Itt adhatjuk meg annak az oldalnak a nevét, amelyen a fordítási lehetőségeket ismertetjük a felhasználókkal. Erre fog hivatkozni a nyelvkiválasztó képernyőelem.';
+$lang['localabout'] = 'A névjegy oldal fordított változátanak használata (a globális névjegy oldal helyett).';
+$lang['checkage'] = 'Figyelmeztetés az esetlegesen elavult fordításokra.';
+$lang['display'] = 'Válasszuk ki, mi jelenjen meg a nyelvi kiválasztó képernyőelemében. Jegyezzük meg: az országzászlókat nem javasolják a használhatósági szakértők.';
+$lang['copytrans'] = 'Ãtmásoljuk az eredeti nyelvi szöveget a szövegszerkesztÅ‘be új fordítás indításakor?';
diff --git a/platform/www/lib/plugins/translation/lang/hu/totranslate.txt b/platform/www/lib/plugins/translation/lang/hu/totranslate.txt
new file mode 100644
index 0000000..e072d8a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/hu/totranslate.txt
@@ -0,0 +1 @@
+JAVÃTANDÓ **Az oldal még nincs teljesen lefordítva. Kérjük, segítsen a befejezésében!**\\ //(Töröljük ezt a bekezdést a fordítás elkészültekor.)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/it/lang.php b/platform/www/lib/plugins/translation/lang/it/lang.php
new file mode 100644
index 0000000..23d3bd6
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/it/lang.php
@@ -0,0 +1,10 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Torpedo <dgtorpedo@gmail.com>
+ */
+$lang['translations'] = 'Traduzioni di questa pagina';
+$lang['outdated'] = 'Questa traduzione è più vecchia di quella della <a href="%s" class="wikilink1">pagina originale</a> è potrebbe essere superata.';
+$lang['diff'] = 'Vedi cosa è <a href="%s" class="wikilink1">cambiato</a>.';
diff --git a/platform/www/lib/plugins/translation/lang/it/settings.php b/platform/www/lib/plugins/translation/lang/it/settings.php
new file mode 100644
index 0000000..775fbf7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/it/settings.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Diego Pierotto <ita.translations@tiscali.it>
+ * @author Sebastiano Pistore <olatusrooc@virgilio.it>
+ * @author Sebastiano Pistore <sebastiano.pistore.info@aol.com>
+ * @author OlatusRooc <olatusrooc@virgilio.it>
+ */
+$lang['translations'] = 'Elenco delle lingue di traduzione separati da spazi (codici ISO). Non includere la lingua predefinita';
+$lang['translationns'] = 'Scrivi qui solo se vuoi le traduzioni all\'interno di una certa categoria.';
+$lang['skiptrans'] = 'Quando i nomi delle pagine corrispondono a questa espressione regolare non mostrare il menu di traduzione.';
+$lang['dropdown'] = 'Utilizza un menu a tendina per visualizzare le traduzioni (consigliato quando si lavora con più di cinque lingue).';
+$lang['translateui'] = 'Vuoi che anche la lingua dell\'interfaccia utente sia modificata in categorie della stessa lingua?';
+$lang['about'] = 'Inserisci qui una pagina dove la funzione di traduzione viene spiegata agli utenti. Sarà collegata al selettore lingua.';
+$lang['localabout'] = 'Mostra le versioni localizzate della pagina About.';
+$lang['checkage'] = 'Avvisa della possibile presenza di traduzioni obsolete.';
+$lang['copytrans'] = 'Copia nell\'editor il testo in lingua originale quando viene iniziata una nuova traduzione?';
diff --git a/platform/www/lib/plugins/translation/lang/it/totranslate.txt b/platform/www/lib/plugins/translation/lang/it/totranslate.txt
new file mode 100644
index 0000000..e83c52a
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/it/totranslate.txt
@@ -0,0 +1 @@
+FIXME ** Questa pagina non è ancora completamente tradotta. Chi può potrebbe aiutarne il completamento. ** \\ // (Rimuovere questo paragrafo a lavoro completato) // \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/ja/lang.php b/platform/www/lib/plugins/translation/lang/ja/lang.php
new file mode 100644
index 0000000..b438bc6
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ja/lang.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Hideaki SAWADA <chuno@live.jp>
+ */
+$lang['translations'] = 'ã“ã®ãƒšãƒ¼ã‚¸ã®ç¿»è¨³';
+$lang['outdated'] = 'ã“ã®ç¿»è¨³ã¯<a href="%s" class="wikilink1">å…ƒã®ãƒšãƒ¼ã‚¸</a>よりも更新日ãŒå¤ãã€å†…容ãŒå¤ã„å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚';
+$lang['diff'] = '<a href="%s" class="wikilink1">変更点</a>ã‚’å‚ç…§ã—ã¦ä¸‹ã•ã„。';
+$lang['transloaded'] = '翻訳ã—易ãã™ã‚‹ãŸã‚ã« %s ã«ã‚ã‚‹ã“ã®ãƒšãƒ¼ã‚¸ã®ç¿»è¨³å†…容を事å‰ã«èª­ã¿è¾¼ã¿ã¾ã—ãŸã€‚<br />以下ã®æ—¢å­˜ã®ç¿»è¨³ã‚’翻訳ã®åŸºã«ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ï¼š%s。';
+$lang['menu'] = 'å¤ã„翻訳ã¨æ¬ è½ã—ã¦ã„る翻訳';
+$lang['missing'] = '欠è½';
+$lang['old'] = '内容ãŒå¤ã„';
+$lang['current'] = '最新';
+$lang['path'] = 'パス';
diff --git a/platform/www/lib/plugins/translation/lang/ja/settings.php b/platform/www/lib/plugins/translation/lang/ja/settings.php
new file mode 100644
index 0000000..b8c8899
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ja/settings.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Hideaki SAWADA <chuno@live.jp>
+ */
+$lang['translations'] = '翻訳言語(ISOコード)ã®ã‚¹ãƒšãƒ¼ã‚¹åŒºåˆ‡ã‚Šä¸€è¦§';
+$lang['translationns'] = '特定ã®åå‰ç©ºé–“以下ã®ã¿ã‚’翻訳ã—ãŸã„å ´åˆã€åå‰ç©ºé–“を記入ã™ã‚‹ã€‚';
+$lang['skiptrans'] = 'ページåãŒã“ã®æ­£è¦è¡¨ç¾ã¨ä¸€è‡´ã™ã‚‹ã¨ã€ç¿»è¨³ãƒ¡ãƒ‹ãƒ¥ãƒ¼ãŒè¡¨ç¤ºã•ã‚Œã¾ã›ã‚“。';
+$lang['dropdown'] = '翻訳を表示ã™ã‚‹ãŸã‚ã«ãƒ‰ãƒ­ãƒƒãƒ—ダウン一覧を使用ã™ã‚‹ï¼ˆï¼•è¨€èªžä»¥ä¸Šã®å ´åˆæŽ¨å¥¨ï¼‰ã€‚';
+$lang['translateui'] = 'ユーザーインターフェイスã®è¨€èªžã‚‚ã€åå‰ç©ºé–“ã®è¨€èªžã«åˆ‡ã‚Šæ›¿ãˆã‚‹ã‹ï¼Ÿ';
+$lang['redirectstart'] = 'ブラウザーã®è¨€èªžè¨­å®šã‚’利用ã—ã¦ã€ã‚¹ã‚¿ãƒ¼ãƒˆãƒšãƒ¼ã‚¸ã‚’å„言語ã®åå‰ç©ºé–“ã«è‡ªå‹•çš„ã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã™ã‚‹ã‹ï¼Ÿ';
+$lang['about'] = '翻訳機能をユーザーã«èª¬æ˜Žã™ã‚‹ãƒšãƒ¼ã‚¸åを入力ã—ã¦ä¸‹ã•ã„。言語セレクタã‹ã‚‰ãƒªãƒ³ã‚¯ã•ã‚Œã¾ã™ã€‚';
+$lang['localabout'] = '(包括的ãªæ¦‚è¦ãƒšãƒ¼ã‚¸ã®ä»£ã‚ã‚Šã«ï¼‰ç¿»è¨³ç‰ˆã®æ¦‚è¦ãƒšãƒ¼ã‚¸ã‚’使用ã™ã‚‹ã€‚';
+$lang['checkage'] = 'å¤ã„翻訳ã«ã¤ã„ã¦è­¦å‘Šã™ã‚‹ã€‚';
+$lang['display'] = '言語セレクタã«ä½•ã‚’表示ã™ã‚‹ã‹ã‚’é¸æŠžã™ã‚‹ã€‚言語é¸æŠžã«å›½æ——を使用ã™ã‚‹ã“ã¨ã‚’ユーザビリティ専門家ã¯å¥¨åŠ±ã—ãªã„ã®ã§æ³¨æ„ã—ã¦ãã ã•ã„。';
+$lang['copytrans'] = 'æ–°ã—ã翻訳を開始ã™ã‚‹æ™‚ã€ã‚¨ãƒ‡ã‚£ã‚¿ã«å…ƒã®è¨€èªžã®æ–‡ç« ã‚’コピーã—ã¾ã™ã‹ï¼Ÿ';
+$lang['show_path'] = '欠è½ã—ã¦ã„る翻訳ページã®ãƒ‘スを表示ã—ã¾ã™ã€‚';
diff --git a/platform/www/lib/plugins/translation/lang/ja/totranslate.txt b/platform/www/lib/plugins/translation/lang/ja/totranslate.txt
new file mode 100644
index 0000000..05ac184
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ja/totranslate.txt
@@ -0,0 +1 @@
+FIXME **ã“ã®ãƒšãƒ¼ã‚¸ã¯ã¾ã å®Œå…¨ã«ã¯ã€ç¿»è¨³ã•ã‚Œã¾ã›ã‚“。翻訳ã®å®Œäº†ã‚’支æ´ã—ã¦ä¸‹ã•ã„。**\\ //(翻訳ãŒå®Œäº†ã—ãŸã‚‰ã“ã®æ®µè½ã‚’削除ã—ã¦ä¸‹ã•ã„)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/ko/lang.php b/platform/www/lib/plugins/translation/lang/ko/lang.php
new file mode 100644
index 0000000..d99d64d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ko/lang.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Myeongjin <aranet100@gmail.com>
+ */
+$lang['translations'] = 'ì´ ë¬¸ì„œì˜ ë²ˆì—­';
+$lang['outdated'] = 'ì´ ë²ˆì—­ì€ <a href="%s" class="wikilink1">ì›ëž˜ 문서</a>보다 오래ë˜ì—ˆê³  ì˜¤ëž˜ëœ ë²ˆì—­ì¼ ìˆ˜ 있습니다.';
+$lang['diff'] = 'ë¬´ì—‡ì´ <a href="%s" class="wikilink1">바뀌었는지</a> 보세요.';
+$lang['transloaded'] = '%sì— ìžˆëŠ” ì´ ë¬¸ì„œì˜ ë²ˆì—­ì˜ ë‚´ìš©ì„ ì‰½ê²Œ 번역하기 위해 미리 불러왔습니다.<br />하지만 ë‹¤ìŒ ê¸°ì¡´ ë²ˆì—­ì— ë‹¹ì‹ ì˜ ë²ˆì—­ì„ ë°”íƒ•ìœ¼ë¡œ í•  수 있습니다: %s.';
+$lang['menu'] = '오래ë˜ì—ˆê³  없는 번역';
+$lang['missing'] = 'ì—†ìŒ!';
+$lang['old'] = '오래ë¨';
+$lang['current'] = '최신';
+$lang['path'] = '경로';
diff --git a/platform/www/lib/plugins/translation/lang/ko/settings.php b/platform/www/lib/plugins/translation/lang/ko/settings.php
new file mode 100644
index 0000000..ccf6d1c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ko/settings.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Myeongjin <aranet100@gmail.com>
+ */
+$lang['translations'] = '번역 ì–¸ì–´ì˜ ê³µë°±ìœ¼ë¡œ 구분한 ëª©ë¡ (ISO 코드).';
+$lang['translationns'] = '특정 ì´ë¦„ê³µê°„ì— ë”°ë¼ ë²ˆì—­ì„ ì›í•˜ë©´, ì—¬ê¸°ì— ë„£ìœ¼ì„¸ìš”.';
+$lang['skiptrans'] = '문서 ì´ë¦„ì´ ì •ê·œ 표현ì‹ê³¼ ì¼ì¹˜í•˜ë©´, 번역 메뉴를 보여주지 마세요.';
+$lang['dropdown'] = 'ë²ˆì—­ì„ í‘œì‹œí•  드롭다운 목ë¡ì„ 사용합니다. (5ê°œ ì´ìƒì˜ ì–¸ì–´ì— ê¶Œìž¥)';
+$lang['translateui'] = 'ì‚¬ìš©ìž ì¸í„°íŽ˜ì´ìŠ¤ì˜ ì–¸ì–´ë„ ì™¸êµ­ì–´ ì´ë¦„공간으로 전환해야 합니까?';
+$lang['redirectstart'] = '시작 문서가 ìžë™ìœ¼ë¡œ 브ë¼ìš°ì € 언어 ê°ì§€ë¥¼ 사용해 언어 ì´ë¦„공간으로 넘겨줘야 합니까?';
+$lang['about'] = '사용ìžì—게 설명할 번역 ê¸°ëŠ¥ì´ ì–´ë””ì— ìžˆëŠ”ì§€ ì—¬ê¸°ì— ë¬¸ì„œ ì´ë¦„ì„ ìž…ë ¥í•˜ì„¸ìš”.';
+$lang['localabout'] = '(í•˜ë‚˜ì˜ ì „ì—­ 소개 문서 대신) 소개 ë¬¸ì„œì˜ ì§€ì—­í™”ëœ ë²„ì „ì„ ì‚¬ìš©í•©ë‹ˆë‹¤.';
+$lang['checkage'] = '가능하면 ì˜¤ëž˜ëœ ë²ˆì—­ì— ëŒ€í•´ 경고합니다.';
+$lang['display'] = '언어 ì„ íƒê¸°ì— 보여주고 ì‹¶ì€ ê²ƒì„ ì„ íƒí•˜ì„¸ìš”. 언어 ì„ íƒì— 국기를 사용하는 ê²ƒì€ ì‚¬ìš©ì„± 전문가ì—게 권장하지 ì•ŠìŒì„ 참고하세요.';
+$lang['copytrans'] = '새 ë²ˆì—­ì„ ì‹œìž‘í•  ë•Œ íŽ¸ì§‘ê¸°ì— ì›ëž˜ 언어 ë¬¸ìž¥ì„ ë³µì‚¬í•˜ê² ìŠµë‹ˆê¹Œ?';
+$lang['show_path'] = '없는 번역 문서ì—ì„œì˜ ê²½ë¡œë¥¼ 보여줄까요?';
diff --git a/platform/www/lib/plugins/translation/lang/ko/totranslate.txt b/platform/www/lib/plugins/translation/lang/ko/totranslate.txt
new file mode 100644
index 0000000..9a19833
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ko/totranslate.txt
@@ -0,0 +1 @@
+FIXME **ì´ ë¬¸ì„œëŠ” ì•„ì§ ì™„ì „ížˆ 번역ë˜ì§€ 않았습니다. ë²ˆì—­ì„ ì™„ë£Œí•˜ëŠ” ë° ë„와주세요.**\\ //(ë²ˆì—­ì„ ë§ˆì¹˜ë©´ ì´ ë‹¨ë½ì„ 지우세요)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/langnames.txt b/platform/www/lib/plugins/translation/lang/langnames.txt
new file mode 100644
index 0000000..90992ee
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/langnames.txt
@@ -0,0 +1,188 @@
+# Native language names
+# extracted from http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
+
+aa Afaraf
+ab ÐÒ§Ñуа
+ae Avesta
+af Afrikaans
+ak Akan
+am አማርኛ
+an Aragonés
+ar |العربية
+as অসমীয়া
+av Ðвар мацӀ
+ay Aymar aru
+az Azərbaycan dili
+ba Башҡорт теле
+be БеларуÑкаÑ
+bg БългарÑки език
+bh भोजपà¥à¤°à¥€
+bi Bislama
+bm Bamanankan
+bn বাংলা
+bo བོད་ཡིག
+br Brezhoneg
+bs Bosanski Jezik
+ca Català
+ce Ðохчийн Мотт
+ch Chamoru
+co Corsu
+cr á“€á¦áƒá”­ááá£
+cs ÄŒesky
+cu Ѩзыкъ СловѣньÑкъ
+cv Чӑваш Чӗлхи
+cy Cymraeg
+da Dansk
+de Deutsch
+dv Þ‹Þ¨ÞˆÞ¬Þ€Þ¨
+dz རྫོང་à½
+ee EÊ‹egbe
+el Ελληνικά
+en English
+eo Esperanto
+es Español
+et Eesti
+eu Euskara
+fa Ùارسی
+ff Fulfulde
+fi Suomi
+fj Vosa Vakaviti
+fo Føroyskt
+fr Français
+fy Frysk
+ga Gaeilge
+gd Gaelic
+gl Galego
+gn Avañe'ẽ
+gu ગà«àªœàª°àª¾àª¤à«€
+gv Gaelg, Gailck
+ha Ù‡ÙŽÙˆÙسَ
+he עברית
+hi हिनà¥à¤¦à¥€, हिंदी
+ho Hiri Motu
+hr Hrvatski
+ht Kreyòl Ayisyen
+hu Magyar
+hy Õ€Õ¡ÕµÕ¥Ö€Õ¥Õ¶
+hz Otjiherero
+ia Interlingua
+id Bahasa Indonesia
+ie Interlingue
+ig Igbo
+ii ꆇꉙ
+ik Iñupiaq
+io Ido
+is Ãslenska
+it Italiano
+iu áƒá“„ᒃᑎá‘ᑦ
+ja 日本語
+jv Basa Jawa
+ka ქáƒáƒ áƒ—ული
+kg KiKongo
+ki Gĩkũyũ
+kj Kuanyama
+kk Қазақ тілі
+kl kalaallisut
+km ភាសាážáŸ’មែរ
+kn ಕನà³à²¨à²¡
+ko 한국어
+kr Kanuri
+ks कशà¥à¤®à¥€à¤°à¥€}}
+ku Kurdî
+kv Коми Кыв
+kw Kernewek
+ky Кыргыз Тили
+la Latine
+lb Lëtzebuergesch
+lg Luganda
+li Limburgs
+ln Lingála
+lo ພາສາລາວ
+lt Lietuvių Kalba
+lv Latviešu Valoda
+mg Malagasy Fiteny
+mh Kajin M̧ajeļ
+mi Te Reo MÄori
+mk МакедонÑки Јазик
+ml മലയാളം
+mn Монгол
+mr मराठी
+ms بهاس ملايو
+mt Malti
+my ဗမာစာ
+na Ekakairũ Naoero
+nb Norsk bokmål
+nd isiNdebele
+ne नेपाली
+ng Owambo
+nl Nederlands
+nn Norsk nynorsk
+no Norsk
+nr IsiNdebele
+nv Diné bizaad
+ny ChiCheŵa
+oc Occitan
+oj áŠá“‚ᔑᓈá¯á’§áŽá“
+om Afaan Oromoo
+or ଓଡ଼ିଆ
+os Ирон æвзаг
+pa ਪੰਜਾਬੀ,
+pi पाऴि
+pl Polski
+ps پښتو
+pt Português
+pt-br Português
+qu Runa Simi
+rm Rumantsch Grischun
+rn KiRundi
+ro Română
+ru РуÑÑкий
+rw Ikinyarwanda
+sa संसà¥à¤•à¥ƒà¤¤à¤®à¥
+sc Sardu
+sd सिनà¥à¤§à¥€}}
+se Davvisámegiella
+sg Yângâ Tî Sängö
+si සිංහල
+sk SlovenÄina
+sl SlovenÅ¡Äina
+sm Gagana fa'a Samoa
+sn ChiShona
+so Soomaaliga
+sq Shqip
+sr СрпÑки Језик
+ss SiSwati
+st Sesotho
+su Basa Sunda
+sv Svenska
+sw Kiswahili
+ta தமிழà¯
+te తెలà±à°—à±
+tg Тоҷикӣ
+th ไทย
+ti ትáŒáˆ­áŠ›
+tk Türkmen
+tl Wikang Tagalog
+tn Setswana
+to Faka Tonga
+tr Türkçe
+ts Xitsonga
+tt Татарча
+tw Twi
+ty Reo MÄ`ohi
+ug Uyƣurqə
+uk УкраїнÑька
+ur اردو
+uz O'zbek
+ve Tshivenḓa
+vi Tiếng Việt
+vo Volapük
+wa Walon
+wo Wollof
+xh IsiXhosa
+yi ייִדיש
+yo Yorùbá
+za Saɯ cueŋƅ
+zh 中文
+zh-tw ç¹é«”中文
+zu IsiZulu
diff --git a/platform/www/lib/plugins/translation/lang/lv/lang.php b/platform/www/lib/plugins/translation/lang/lv/lang.php
new file mode 100644
index 0000000..af85894
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/lv/lang.php
@@ -0,0 +1,11 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['translations'] = 'CitÄs valodÄs';
+$lang['outdated'] = 'Å is tulkojums ir vecÄks par <a href="%s" class="wikilink1">oriÄ£inÄlo lapu</a> un varbÅ«t ir novecojis.';
+$lang['diff'] = 'Redzēt, ka ir <a href="%s" class="wikilink1">mainījies</a>.';
+$lang['transloaded'] = 'VieglÄkai tulkoÅ¡anai ir ielÄdÄ“ts lapas saturs no %s .<br />Bet varat balstÄ«ties arÄ« uz Å¡Ädiem tulkojumiem: %s.';
diff --git a/platform/www/lib/plugins/translation/lang/lv/settings.php b/platform/www/lib/plugins/translation/lang/lv/settings.php
new file mode 100644
index 0000000..1b61b46
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/lv/settings.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Aivars Miška <allefm@gmail.com>
+ * @author Aivars Miška <allefm@gmail.com>
+ */
+$lang['translations'] = 'Ar atstarpēm atdalīts tulkojumu valodu saraksts (ISO kodi). Izņemot noklusēto valodu.';
+$lang['translationns'] = 'Ja tulkojumus vajag tikai noteiktÄ nodaļÄ, ieraksti to Å¡eit.';
+$lang['skiptrans'] = 'Ja lapas nosaukums atbilst regulÄrajai izteiksmei, tulkoÅ¡anas izvÄ“lni nerÄdÄ«t.';
+$lang['dropdown'] = 'Lietot izkrÄ«toÅ¡o izvÄ“lni tulkojumu parÄdÄ«Å¡anai (ieteikt, ja ir vairÄk par 5 valodÄm). ';
+$lang['translateui'] = 'Vai sveÅ¡valodu nodaļÄs jÄpÄrslÄ“dz arÄ« lietotÄja sakarnes valoda?';
+$lang['redirectstart'] = 'Vai sÄkuma lapai automÄtiski jÄpÄrslÄ“dzas atkarÄ«bÄ no pÄrlÅ«kprogrammas noteiktÄs valodas?';
+$lang['about'] = 'Ieraksti Å¡eit lapu, kurÄ lietotÄjiem izskaidrotas tulkoÅ¡as iespÄ“jas. TÄ tiks piesaistÄ«ta valodu izvÄ“lei.';
+$lang['localabout'] = 'Lietot "par" lapas lokalizÄ“to versiju, nevis globÄlo "par" lapu.';
+$lang['checkage'] = 'BrÄ«dinÄt pa varbÅ«t novecojuÅ¡iem tulkojumiem. ';
+$lang['display'] = 'NorÄdiet, ko lietot valodas izvÄ“lei. Å…emiet vÄ“rÄ, ka valodÄm izmantot valstu karogus neiesaka.';
+$lang['copytrans'] = 'SÄkot tulkojumu, iekopÄ“t redaktorÄ oriÄ£inÄltekstu?';
diff --git a/platform/www/lib/plugins/translation/lang/lv/totranslate.txt b/platform/www/lib/plugins/translation/lang/lv/totranslate.txt
new file mode 100644
index 0000000..c46c14e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/lv/totranslate.txt
@@ -0,0 +1 @@
+IZLABO **Lapa nav pilnÄ«bÄ pÄrtulkota. LÅ«dzu palÄ«dzi pabeigt tulkojumu!** \\ //(IzdzÄ“s Å¡o rindkopu, kad tulkojums pabeigts!)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/nl/lang.php b/platform/www/lib/plugins/translation/lang/nl/lang.php
new file mode 100644
index 0000000..1864f07
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/nl/lang.php
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Gerrit Uitslag <klapinklapin@gmail.com>
+ * @author Marcel Bachus <marcel.bachus@ziggo.nl>
+ */
+$lang['translations'] = 'Vertaling van deze pagina';
+$lang['outdated'] = 'Deze vertaling is ouder dan de <a href="%s" class="wikilink1">originele pagina</a> en kan verouderd zijn.';
+$lang['diff'] = 'Kijk wat er is <a href="%s" class="wikilink1">veranderd</a>.';
+$lang['transloaded'] = 'De inhoud van vertaling van deze pagina in %s is al geladen om vertalen makkelijker te maken.<br />Maar je kunt je vertaling ook baseren op één van de volgende bestaande vertalingen: %s.';
+$lang['menu'] = 'verouderde of missende vertaling';
+$lang['missing'] = 'Niet gevonden!';
+$lang['old'] = 'verouderd';
+$lang['current'] = 'laatste stand van zaken';
+$lang['path'] = 'Pad';
diff --git a/platform/www/lib/plugins/translation/lang/nl/settings.php b/platform/www/lib/plugins/translation/lang/nl/settings.php
new file mode 100644
index 0000000..88dbe98
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/nl/settings.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Gerrit <klapinklapin@gmail.com>
+ * @author Gerrit Uitslag <klapinklapin@gmail.com>
+ * @author Marcel Bachus <marcel.bachus@ziggo.nl>
+ */
+$lang['translations'] = 'Spatiegescheiden lijst van vertalingen (ISO codes).';
+$lang['translationns'] = 'Als je alleen vertalingen in een bepaalde namespace wenst, plaatst die dan hier.';
+$lang['skiptrans'] = 'Wanneer een paginanaam overeenstemt met deze reguliere expressie, wordt het vertaalmenu niet getoond.';
+$lang['dropdown'] = 'Gebruik een dropdownlijst om vertalingen weer te geven (aanbevolen bij meer dan 5 talen).';
+$lang['translateui'] = 'Moet de taal van de gebruikersinterface ook veranderen naar de taal van vertaalde namespace?';
+$lang['redirectstart'] = 'Moet de startpagina automatisch doorverwijzen naar de namespace van de taal die de taaldetectie van de browser doorgeeft?';
+$lang['about'] = 'Geef een paginanaam waar de vertaalfunctie wordt uitgelegd voor je gebruikers. Het zal worden gelinkt vanuit de talenkiezer.';
+$lang['localabout'] = 'Gebruik vertaalde versies van bovengenoemde vertalingsuitlegpagina (in plaats van één globale uitlegpagina).';
+$lang['checkage'] = 'Waarschuw voor mogelijk gedateerde vertalingen.';
+$lang['display'] = 'Selecteer wat je wil zien in de talenkiezer. Let op dat het gebruik van landenvlaggen in de talenkiezer niet altijd gebruiksvriendelijkheid is.';
+$lang['copytrans'] = 'De tekst in de oorspronkelijke taal naar het bewerkvenster kopiëren als er een nieuwe vertaling wordt begonnen.';
+$lang['show_path'] = 'Toon het pad naar de missende vertalings pagina?';
diff --git a/platform/www/lib/plugins/translation/lang/nl/totranslate.txt b/platform/www/lib/plugins/translation/lang/nl/totranslate.txt
new file mode 100644
index 0000000..d5f8cee
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/nl/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Deze pagina is nog niet volledig vertaald. Help alsjeblieft de vertaling compleet te maken.**\\ //(verwijder deze paragraaf als de vertaling is voltooid)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/pt-br/lang.php b/platform/www/lib/plugins/translation/lang/pt-br/lang.php
new file mode 100644
index 0000000..c6fa3f7
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/pt-br/lang.php
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Edney Rossi <edneyrossi@gmail.com>
+ */
+$lang['translations'] = 'Traduções desta página';
+$lang['outdated'] = 'Esta tradução é mais antiga que a <a href="%s" class="wikilink1"> página original </a> e pode estar desatualizada.';
+$lang['diff'] = 'Veja o que foi <a href="%s" class="wikilink1">mudado</a>.';
+$lang['transloaded'] = 'O conteúdo da tradução desta página em %s foi pré-carregado para facilitar o trabalho.< br/>Mas você pode basear sua tradução nas seguintes traduções existentes: %s.';
+$lang['menu'] = 'traduções desatualizadas e inexistentes';
+$lang['missing'] = 'Inexistente!';
+$lang['old'] = 'desatualizado';
+$lang['current'] = 'atualizada';
+$lang['path'] = 'Caminho';
diff --git a/platform/www/lib/plugins/translation/lang/pt-br/settings.php b/platform/www/lib/plugins/translation/lang/pt-br/settings.php
new file mode 100644
index 0000000..e053e13
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/pt-br/settings.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Paulino Michelazzo <paulino@michelazzo.com.br>
+ * @author Felipe Castro <fefcas@gmail.com>
+ * @author Edney Rossi <edneyrossi@gmail.com>
+ */
+$lang['translations'] = 'Lista de idiomas separados por espaço (códigos ISO).';
+$lang['translationns'] = 'Se você deseja traduções apenas para certo idioma, coloque-o aqui.';
+$lang['skiptrans'] = 'Quando o nome-de-página estiver de acordo com esta expressão regular, não mostre o menu de tradução.';
+$lang['dropdown'] = 'Usar listagem desdobrada para mostrar as traduções (recomendado para mais que 5 línguas).';
+$lang['translateui'] = 'A interface do usuário deve ser trocada para o idioma, também?';
+$lang['redirectstart'] = 'A página inicial deve redirecionar automaticamente para o "namespace" da língua usando a detecção de idiomas no navegador?';
+$lang['about'] = 'Digite um nome de página aqui onde o recurso de tradução é explicado para seus usuários. Ele será vinculado a partir do seletor de idioma.';
+$lang['localabout'] = 'Usar versões localizadas da página "a respeito de" (em vez de uma página global "a respeito de").';
+$lang['checkage'] = 'Avisar sobre possíveis traduções desatualizadas.';
+$lang['display'] = 'Selecionar o que você gostaria de mostrar no seletor de línguas. Note que usar bandeirinhas de países para selecionar línguas não é recomendado por especialistas em usabilidade.';
+$lang['copytrans'] = 'Copiar o texto da língua original no editor quando começar uma nova tradução?';
+$lang['show_path'] = 'Mostrar o caminho na página com tradução inexistente?';
diff --git a/platform/www/lib/plugins/translation/lang/pt-br/totranslate.txt b/platform/www/lib/plugins/translation/lang/pt-br/totranslate.txt
new file mode 100644
index 0000000..5329cda
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/pt-br/totranslate.txt
@@ -0,0 +1 @@
+FIXME ** Esta página não está completamente traduzida ainda. Por favor ajude a completar sua tradução.**\\ //(remova este parágrafo assim que a tradução tenha terminado)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/pt/lang.php b/platform/www/lib/plugins/translation/lang/pt/lang.php
new file mode 100644
index 0000000..a17ab35
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/pt/lang.php
@@ -0,0 +1,11 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author André Neves <drakferion@gmail.com>
+ * @author Alfredo Silva <alfredo.silva@sky.com>
+ */
+$lang['translations'] = 'Traduções para esta página';
+$lang['outdated'] = 'Esta tradução é mais antiga do que a <a href="%s" class="wikilink1">página original</a> e poderá estar desatualizada.';
+$lang['diff'] = 'Veja o que foi <a href="%s" class="wikilink1">alterado</a>.';
diff --git a/platform/www/lib/plugins/translation/lang/pt/settings.php b/platform/www/lib/plugins/translation/lang/pt/settings.php
new file mode 100644
index 0000000..4cdd114
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/pt/settings.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author André Neves <drakferion@gmail.com>
+ * @author Alfredo Silva <alfredo.silva@sky.com>
+ */
+$lang['translations'] = 'Lista de idiomas de tradução (códigos ISO) separada por espaço.';
+$lang['translationns'] = 'Se pretender apenas as traduções abaixo de um determinado espaço de nome, coloque-as aqui.';
+$lang['skiptrans'] = 'Quando o nome da página corresponder com esta expressão regular, não mostrar o menu de tradução.';
+$lang['dropdown'] = 'Utilizar uma lista de menu para exibir as traduções (recomendado para mais de 5 idiomas).';
+$lang['translateui'] = 'O idioma da interface do utilizador também deverá ser alterado nos espaços de nome do idioma estrangeiro?';
+$lang['redirectstart'] = 'A página inicial deve redirecionar automaticamente para um espaço de nome do idioma utilizando a deteção de idioma do navegador?';
+$lang['about'] = 'Insira aqui um nome de página onde a funcionalidade de tradução é explicada aos seus utilizadores. O seletor de língua terá uma ligação para lá.';
+$lang['localabout'] = 'Utilizar versões localizadas da página sobre (em vez de uma página global sobre).';
+$lang['checkage'] = 'Avisar sobre as possíveis traduções desatualizadas.';
+$lang['display'] = 'Selecione o que gostaria de ver mostrado no seletor de linguagem. Note que usar bandeiras de países para seleção de linguagem não é recomendado por peritos de usabilidade.';
+$lang['copytrans'] = 'Copiar o texto do idioma original no editor quando iniciar uma nova tradução?';
diff --git a/platform/www/lib/plugins/translation/lang/ru/lang.php b/platform/www/lib/plugins/translation/lang/ru/lang.php
new file mode 100644
index 0000000..dc85abc
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ru/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Vasilyy Balyasnyy <v.balyasnyy@gmail.com>
+ * @author Anotheroneuser <w20151222@ya.ru>
+ */
+$lang['translations'] = 'Перевод Ñтой Ñтраницы';
+$lang['outdated'] = 'Этот перевод Ñтарее, чем <a href="%s" class="wikilink1">Ð¾Ñ€Ð¸Ð³Ð¸Ð½Ð°Ð»ÑŒÐ½Ð°Ñ Ñтраница</a>, и может быть неактуальным.';
+$lang['diff'] = 'Смотрите, что <a href="%s" class="wikilink1">было изменено</a>.';
+$lang['transloaded'] = 'Содержание перевода Ñтой Ñтраницы в %s было предварительно загружено Ð´Ð»Ñ ÑƒÐ¿Ñ€Ð¾Ñ‰ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ²Ð¾Ð´Ð°.<br />Ðо вы можете переводить на оÑнове Ñледующего ÑущеÑтвующего перевода: %s.';
+$lang['menu'] = 'УÑтаревшие или отÑутÑтвующие переводы';
+$lang['missing'] = 'ОтÑутÑтвует! ';
+$lang['old'] = 'уÑтарело';
+$lang['current'] = 'обновить (привеÑти в актуальное ÑоÑтоÑние)';
+$lang['path'] = 'Путь';
diff --git a/platform/www/lib/plugins/translation/lang/ru/settings.php b/platform/www/lib/plugins/translation/lang/ru/settings.php
new file mode 100644
index 0000000..a974b68
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ru/settings.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Oleksiy Zagorskyi <zalex_ua@i.ua>
+ * @author Aleksandr Selivanov <alexgearbox@gmail.com>
+ * @author Anotheroneuser <w20151222@ya.ru>
+ */
+$lang['translations'] = 'СпиÑок поддерживаемых Ñзыков перевода (двухÑимвольные коды ISO). Разделите Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð±ÐµÐ»Ð°Ð¼Ð¸.';
+$lang['translationns'] = 'ЕÑли вы хотите перевеÑти только определённое проÑтранÑтво имён, тогда впишите здеÑÑŒ его имÑ.';
+$lang['skiptrans'] = 'ЕÑли Ð¸Ð¼Ñ Ñтраницы ÑоответÑтвует Ñтому регулÑрному выражению, тогда не отображать меню перевода.';
+$lang['dropdown'] = 'ИÑпользовать выпадающий ÑпиÑок Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¾Ñтупных переводов (рекомендуетÑÑ, еÑли более 5 переводов)';
+$lang['translateui'] = 'Должен ли Ñзык интерфейÑа Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ Ñ‚Ð°ÐºÐ¶Ðµ переключатьÑÑ ÑоглаÑно Ñзыку проÑтранÑтва имён?';
+$lang['redirectstart'] = 'Должна ли ÑÑ‚Ð°Ñ€Ñ‚Ð¾Ð²Ð°Ñ Ñтраница автоматичеÑки перенаправлÑÑ‚ÑŒÑÑ Ð½Ð° проÑтранÑтво имён Ñзыка, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð°Ð²Ñ‚Ð¾Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ðµ Ñзыка браузера?';
+$lang['about'] = 'Введите здеÑÑŒ Ð¸Ð¼Ñ Ñтраницы, на которой будут разъÑÑнены функции перевода Ð´Ð»Ñ Ð²Ð°ÑˆÐ¸Ñ… пользователей. Она будет ÑвÑзана Ñ Ð²Ñ‹Ð±Ð¾Ñ€Ð¾Ð¼ Ñзыка.';
+$lang['localabout'] = 'ИÑпользовать локализованную верÑию Ñтраницы разъÑÑнений (вмеÑто одной глобальной Ñтраницы разъÑÑнений).';
+$lang['checkage'] = 'Отображать предупреждение о возможной неактуальноÑти перевода?';
+$lang['display'] = 'Выберите, что бы вы хотели видеть в поле выбора Ñзыков. Имейте в виду, что иÑпользование Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ Ð³Ð¾ÑударÑтвенного флага в поле выбора Ñзыков не было рекомендовано ÑкÑпертами в облаÑти потребительÑкого удобÑтва. ';
+$lang['copytrans'] = 'Копировать текÑÑ‚ оригинала в окно Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ Ð¿Ñ€Ð¸ Ñоздании нового перевода?';
+$lang['show_path'] = 'Показывать путь на непереведённых Ñтраницах? ';
diff --git a/platform/www/lib/plugins/translation/lang/ru/totranslate.txt b/platform/www/lib/plugins/translation/lang/ru/totranslate.txt
new file mode 100644
index 0000000..b34588e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/ru/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Эта Ñтраница пока что не переведена полноÑтью. ПожалуйÑта, помогите завершить перевод.**\\ //(Сотрите Ñто Ñообщение по окончании перевода.)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/sl/lang.php b/platform/www/lib/plugins/translation/lang/sl/lang.php
new file mode 100644
index 0000000..be8a195
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/sl/lang.php
@@ -0,0 +1,9 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ */
+$lang['translations'] = 'Prevod trenutne strani';
+$lang['outdated'] = 'Prevod je starejši od <a href="%s" class="wikilink1">izvorne strani</a> in je zato lahko zastarel.';
+$lang['diff'] = 'Oglejte si <a href="%s" class="wikilink1">spremembe</a>.';
diff --git a/platform/www/lib/plugins/translation/lang/sl/settings.php b/platform/www/lib/plugins/translation/lang/sl/settings.php
new file mode 100644
index 0000000..6bdcff4
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/sl/settings.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Matej UrbanÄiÄ <mateju@svn.gnome.org>
+ */
+$lang['translations'] = 'Space separated list of translation languages (ISO codes).';
+$lang['translationns'] = 'If you only want translations below a certain namespace, put it here.';
+$lang['skiptrans'] = 'When the pagename matches this regular expression, don\'t show the translation menu.';
+$lang['dropdown'] = 'Use a dropdown list to display the translations (recommended for more than 5 languages).';
+$lang['translateui'] = 'Should the language of the user interface be switched in foreign language namespaces, too?';
+$lang['redirectstart'] = 'Should the start page automatically redirect into a language namespace using browser language detection?';
+$lang['about'] = 'Enter a pagename here where the translation feature is explained for your users. It will be linked from the language selector.';
+$lang['localabout'] = 'Uporabi prevedeno razliÄico strani o vstavku (namesto sploÅ¡ne strani).';
+$lang['checkage'] = 'Opozori o zastarelem prevodu.';
+$lang['display'] = 'Izbor možnosti za prikaz jezika v izbirniku jezika. Izbor zastave jezika v izbiri ni priporoÄen.';
diff --git a/platform/www/lib/plugins/translation/lang/sv/lang.php b/platform/www/lib/plugins/translation/lang/sv/lang.php
new file mode 100644
index 0000000..6f40f58
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/sv/lang.php
@@ -0,0 +1,16 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Tor Härnqvist <tor@harnqvist.se>
+ */
+$lang['translations'] = 'Översättningar av denna sida';
+$lang['outdated'] = 'Denna översättning är äldre än <a href="%s" class="wikilink1">orginalsidan</a> och kan vara daterad.';
+$lang['diff'] = 'Se vad som har <a href="%s" class="wikilink1">ändrats</a>.';
+$lang['transloaded'] = 'Innehållet på denna sidas översättning på %s har blivit förinläst för enklare översättning.<br />Du kan dock basera din översättning på följande redan existerande översättningar: %s.';
+$lang['menu'] = 'daterade och saknade översättningar';
+$lang['missing'] = 'Saknas!';
+$lang['old'] = 'daterad';
+$lang['current'] = 'uppdaterad';
+$lang['path'] = 'Sökväg';
diff --git a/platform/www/lib/plugins/translation/lang/sv/settings.php b/platform/www/lib/plugins/translation/lang/sv/settings.php
new file mode 100644
index 0000000..4cd67f4
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/sv/settings.php
@@ -0,0 +1,19 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Tor Härnqvist <tor@harnqvist.se>
+ */
+$lang['translations'] = 'Blankstegsseparerad lista över översatta språk (ISO-koder).';
+$lang['translationns'] = 'Om du bara önskar översättningar under en specifik namnrymd, placera den här.';
+$lang['skiptrans'] = 'När sidnamnet matchar detta reguljära uttryck, visa ej översättningsmenyn.';
+$lang['dropdown'] = 'Använd en rullista för att visa översättningarna (rekommenderat till fem eller fler språk).';
+$lang['translateui'] = 'Skall språket för användargränssnittet växlas även för namnrymder på främmande språk?';
+$lang['redirectstart'] = 'Skall startsidan automatiskt omdirigeras till en språkspecifik namnrymd baserat på webbläsarens språkdetektion?';
+$lang['about'] = 'Fyll i ett sidnamn här där översättningsfunktionen förklaras för dina användare. Sidan kommer att länkas från språkväljaren.';
+$lang['localabout'] = 'Använd översatt version av "Om"-sidan (istället för en global "Om"-sida).';
+$lang['checkage'] = 'Varna för möjligt daterade översättningar.';
+$lang['display'] = 'Ange vad du önskar visas i menyn för språkval. Vänligen notera att nationsfanor för språkval ej är rekommenderat.';
+$lang['copytrans'] = 'Kopiera texten på originalspråket till textredigeraren när en ny översättning inleds?';
+$lang['show_path'] = 'Visa sökväg på sidan för den saknade översättningen?';
diff --git a/platform/www/lib/plugins/translation/lang/sv/totranslate.txt b/platform/www/lib/plugins/translation/lang/sv/totranslate.txt
new file mode 100644
index 0000000..d4f7a53
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/sv/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Denna sida är inte helt översatt än. Var god hjälp till att avsluta översättningen.**\\ //(ta bort detta stycke när översättningen är färdig)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/tr/lang.php b/platform/www/lib/plugins/translation/lang/tr/lang.php
new file mode 100644
index 0000000..6f8f617
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/tr/lang.php
@@ -0,0 +1,10 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author İlker R. Kapaç <irifat@gmail.com>
+ */
+$lang['translations'] = 'Bu sayfanın çevirileri';
+$lang['outdated'] = 'Bu çeviri <a href="%s" class="wikilink1">orjinal sayfadan</a> daha eski tarihli. Dolayısıyla güncel olmayabilir.';
+$lang['diff'] = 'Nelerin değiştiğini görmek için <a href="%s" class="wikilink1">tıklayın</a>.';
diff --git a/platform/www/lib/plugins/translation/lang/tr/settings.php b/platform/www/lib/plugins/translation/lang/tr/settings.php
new file mode 100644
index 0000000..bad9dbc
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/tr/settings.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author İlker R. Kapaç <irifat@gmail.com>
+ */
+$lang['translations'] = 'Tercüme dillerinin listesi. (boşluk ile ayrılmış, ISO kodları)';
+$lang['translationns'] = 'Eğer tercümelerin bir isim alanın (namespace) altında olmasını istiyorsanız, buraya yazın.';
+$lang['skiptrans'] = 'İsim alanı (Namespace) buradaki tanıma uyduğunda, tercüme arayüzünü gösterme.';
+$lang['dropdown'] = 'Dilleri listelemek için açılır arayüz kullan. (5\'ten fazla dil olduğunda kullanılması önerilir)';
+$lang['localabout'] = 'Bir tane genel "hakkında" sayfası kullanmak yerine, yerelleştirilmiş "hakkında" sayfaları kullan. ';
+$lang['checkage'] = 'Eski tarihli tercümeler hakkında uyarı göster.';
+$lang['display'] = 'Dil seçiminde görünmesini istediklerinizi seçin. Lütfen unutmayın, dil seçiminde ülke bayrağı kullanmak, erişilebilirlik uzmanları tarafından tavsiye edilmez.';
+$lang['copytrans'] = 'Yeni tercümeye başlarken orjinal dildeki metin, düzenleme ekranına kopyalansın mı?';
diff --git a/platform/www/lib/plugins/translation/lang/tr/totranslate.txt b/platform/www/lib/plugins/translation/lang/tr/totranslate.txt
new file mode 100644
index 0000000..e281874
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/tr/totranslate.txt
@@ -0,0 +1 @@
+FIXME **Bu sayfanın çevirisi henüz tamamlanmadı. Lütfen çevirinin tamamlanmasına yardımcı olun.**\\ //(Çeviri tamamlandığında bu paragrafı silin)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/uk/lang.php b/platform/www/lib/plugins/translation/lang/uk/lang.php
new file mode 100644
index 0000000..8be6648
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/uk/lang.php
@@ -0,0 +1,17 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author ОлекÑій <alexey.furashev@gmail.com>
+ * @author Vitaly <vitaly.balashov@smuzzy.com.ua>
+ */
+$lang['translations'] = 'Переклад цієї Ñторінки';
+$lang['outdated'] = 'Цей переклад Ñтаріший ніж <a href="%s" class="wikilink1">оригінальна Ñторінка</a> Ñ– може бути не актуальним.';
+$lang['diff'] = 'ДивітьÑÑ Ñ‰Ð¾ <a href="%s" class="wikilink1">було змінено</a>.';
+$lang['transloaded'] = 'ЗміÑÑ‚ перекладу цієї Ñторінки %s був попередньо завантажений Ð´Ð»Ñ Ð·Ñ€ÑƒÑ‡Ð½Ð¾ÑÑ‚Ñ– перекладу. <br /> Також можете викориÑтовувати наÑтупні переклади: %s.';
+$lang['menu'] = 'заÑтарілі та відÑутні переклади';
+$lang['missing'] = 'ВідÑутній!';
+$lang['old'] = 'заÑтарілий';
+$lang['current'] = 'поточний';
+$lang['path'] = 'ШлÑÑ…';
diff --git a/platform/www/lib/plugins/translation/lang/uk/settings.php b/platform/www/lib/plugins/translation/lang/uk/settings.php
new file mode 100644
index 0000000..51ec6d4
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/uk/settings.php
@@ -0,0 +1,23 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * Ukrainian language file
+ *
+ * @author ОлекÑій <alexey.furashev@gmail.com>
+ * @author Vitaly <vitaly.balashov@smuzzy.com.ua>
+ * @author Oleksiy Zagorskyi <zalex_ua@i.ua>
+ */
+$lang['translations'] = 'СпиÑок підтримуваних мов перекладу (двохÑимвольні коди ISO). Розділіть Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ð°Ð¼Ð¸ або пробілами.';
+$lang['translationns'] = 'Якщо ви хочете переклаÑти тільки визначений ПроÑÑ‚Ñ–Ñ€ імен, тоді впишіть тут його ім\'Ñ.';
+$lang['skiptrans'] = 'Якщо ім\'Ñ Ñторінки відповідає цьому регулÑрному виразу, тоді не відображувати меню перекладів.';
+$lang['dropdown'] = 'ВикориÑтовувати випадаючий ÑпиÑок Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð¾Ñтупних перекладів (рекомендуєтьÑÑ, Ñкщо більше 5 перекладів)';
+$lang['translateui'] = 'Чи повинна мова інтерфейÑу кориÑтувача також перемикатиÑÑŒ відповідно до мови ПроÑтору імен?';
+$lang['redirectstart'] = 'Чи повинна Ñтартова Ñторінка автоматично перенаправлÑтиÑÑŒ на ПроÑÑ‚Ñ–Ñ€ імен мови, викориÑтовуючи детектекцію мови оглÑдача?';
+$lang['about'] = 'Введіть тут ім\'Ñ Ñторінки, на Ñкій буде роз\'ÑÑнено функції перекладу Ð´Ð»Ñ Ð²Ð°ÑˆÐ¸Ñ… кориÑтувачів. Вона буде пов\'Ñзана з вибором мови.';
+$lang['localabout'] = 'ВикориÑтовувати локалізовану верÑÑ–ÑŽ Ñторінки роз\'ÑÑнень (заміÑÑ‚ÑŒ однієї глобальної Ñторінки роз\'ÑÑнень).';
+$lang['checkage'] = 'Відображувати Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ можливу не актуальніÑÑ‚ÑŒ перекладу Ñторінок?';
+$lang['display'] = 'Оберіть що б ви хотіли відображувати в перемикачі мов. Примітка: викориÑтовувати прапор країни Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ñ‡Ð° мов не рекомендуєтьÑÑ ÐµÐºÑпертами по зручноÑÑ‚Ñ– викориÑÑ‚Ð°Ð½Ð½Ñ Ñ–Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñу.';
+$lang['copytrans'] = 'Зкопіювати текÑÑ‚ мовою оригіналу до редактора на початку нового перекладу?';
+$lang['show_path'] = 'Показати шлÑÑ… на відÑутній Ñторінці перекладу?';
diff --git a/platform/www/lib/plugins/translation/lang/uk/totranslate.txt b/platform/www/lib/plugins/translation/lang/uk/totranslate.txt
new file mode 100644
index 0000000..ee2d980
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/uk/totranslate.txt
@@ -0,0 +1 @@
+FIXME ** Ð¦Ñ Ñторінка ще не повніÑÑ‚ÑŽ переведена. Будь-лаÑка, допоможіть завершити переклад. ** \\ //(видаліть цей абзац піÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÐºÐ»Ð°Ð´Ñƒ)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/lang/zh-tw/lang.php b/platform/www/lib/plugins/translation/lang/zh-tw/lang.php
new file mode 100644
index 0000000..7b9f694
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/zh-tw/lang.php
@@ -0,0 +1,6 @@
+<?php
+
+$lang['translations'] = '本é ä¹‹ç¿»è­¯';
+$lang['outdated'] = '這份翻譯較<a href="%s" class="wikilink1">原始é é¢</a>舊,å¯èƒ½å·²éŽæ™‚。';
+$lang['diff'] = '檢視<a href="%s" class="wikilink1">變更</a>。';
+
diff --git a/platform/www/lib/plugins/translation/lang/zh-tw/settings.php b/platform/www/lib/plugins/translation/lang/zh-tw/settings.php
new file mode 100644
index 0000000..7cc76dc
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/zh-tw/settings.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Traditional Chinese language file
+ */
+
+$lang['translations'] = '空白分隔的翻譯語言列表 (ISO 碼)。ä¸å¡«é è¨­èªžè¨€å°‡ä½¿ç”¨æ ¹å‘½å空間。';
+$lang['translationns'] = '如果你åªæƒ³ç¿»è­¯æŸäº›å‘½å空間,請寫在這裡。';
+$lang['skiptrans'] = 'é é¢å稱若符åˆæ­¤æ­£è¦å¼å°±ä¸é¡¯ç¤ºç¿»è­¯é¸å–®ã€‚';
+$lang['dropdown'] = '用下拉å¼é¸å–®é¡¯ç¤º (多於 5 個語言時建議使用)。';
+$lang['translateui'] = '在外語的命å空間時,也轉æ›ä½¿ç”¨è€…介é¢å—Žï¼Ÿ';
+$lang['redirectstart'] = 'è¦åµæ¸¬è¦½å™¨èªžè¨€ï¼ŒæŠŠé–‹å§‹é é¢é‡æ–°å°Žå‘到語言的命å空間嗎?';
+$lang['about'] = '用於解釋翻譯機制的é é¢å稱,它的連çµæœƒå‡ºç¾åœ¨èªžè¨€é¸å–®ã€‚';
+$lang['localabout'] = '解釋é ä½¿ç”¨ç¿»è­¯ç‰ˆæœ¬ (而éžä¸€å€‹é€šç”¨é )。';
+$lang['checkage'] = '警告å¯èƒ½éŽæ™‚的翻譯。';
+$lang['display'] = 'é¸æ“‡ä½ å¸Œæœ›åœ¨èªžè¨€é¸å–®ä¸­é¡¯ç¤ºçš„項目。注æ„國旗 (flag) é¸é …是ä¸è¢«æ˜“用性專家建議的。';
+
diff --git a/platform/www/lib/plugins/translation/lang/zh/lang.php b/platform/www/lib/plugins/translation/lang/zh/lang.php
new file mode 100644
index 0000000..4aaa2d3
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/zh/lang.php
@@ -0,0 +1,18 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author hfl <huangfeilong@gmail.com>
+ * @author oott123 <ip.192.168.1.1@qq.com>
+ * @author kuma <kuma000@qq.com>
+ */
+$lang['translations'] = '本页é¢çš„其他翻译';
+$lang['outdated'] = '翻译跟<a href="%s" class="wikilink1">原始页é¢</a>比较起æ¥æ˜¾å¾—有些陈旧,所以å¯èƒ½å¤±æ•ˆã€‚';
+$lang['diff'] = '查看<a href="%s" class="wikilink1">更新</a>';
+$lang['transloaded'] = '此页é¢çš„ %s å·²ç»ç”± easy translation 预翻译。<br />但你å¯ä»¥ä»¥ä»¥ä¸‹çŽ°å­˜çš„语言为基础翻译你的版本。%s';
+$lang['menu'] = '过时的和缺失的翻译';
+$lang['missing'] = '缺失!';
+$lang['old'] = '过时';
+$lang['current'] = '最新的';
+$lang['path'] = '路径';
diff --git a/platform/www/lib/plugins/translation/lang/zh/settings.php b/platform/www/lib/plugins/translation/lang/zh/settings.php
new file mode 100644
index 0000000..6ca6666
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/zh/settings.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author ZDYX <zhangduyixiong@gmail.com>
+ * @author oott123 <ip.192.168.1.1@qq.com>
+ * @author kuma <kuma000@qq.com>
+ */
+$lang['translations'] = '使用空格分隔的翻译语言列表(ISO ç ï¼‰ã€‚请勿填入默认语言。';
+$lang['translationns'] = '如果您åªå¸Œæœ›æœ¬æ’件作用于æŸä¸ªç‰¹å®šçš„å称空间,请在这里写上其å称。';
+$lang['skiptrans'] = '当页é¢å称与此正则匹é…时,ä¸è¦æ˜¾ç¤ºç¿»è¯‘èœå•ã€‚';
+$lang['dropdown'] = '使用下拉列表显示翻译语言(5+语言时建议å¯ç”¨ï¼‰';
+$lang['translateui'] = '整个用户界é¢ä¹Ÿè·ŸéšæŸä¸ªé¡µé¢çš„翻译语言而改å˜å—?';
+$lang['redirectstart'] = '首页是å¦æ ¹æ®æµè§ˆå™¨è¯­è¨€è‡ªåŠ¨åˆ‡æ¢åˆ°ç›¸åº”语言?';
+$lang['about'] = '请在此输入å‘用户解释翻译功能的页é¢çš„å称空间。它的链接将出现在语言选择器上。';
+$lang['localabout'] = '使用本地化的关于页é¢ï¼ˆè€Œä¸æ˜¯ä¸€ä¸ªå…¨å±€å…³äºŽé¡µé¢ï¼‰ã€‚';
+$lang['checkage'] = '警告:å¯èƒ½è¿‡æ—¶äº†çš„翻译。';
+$lang['display'] = '选择你想在选择器中显示什么。注æ„å¯ç”¨æ€§ä¸“家并ä¸æŽ¨è使用国旗选择语言。';
+$lang['copytrans'] = '开始新翻译的时候在编辑器中å¤åˆ¶åŽŸå§‹è¯­è¨€ç‰ˆæœ¬ï¼Ÿ';
+$lang['show_path'] = '缺失的翻译页é¢ä¸Šæ˜¾ç¤ºè·¯å¾„?';
diff --git a/platform/www/lib/plugins/translation/lang/zh/totranslate.txt b/platform/www/lib/plugins/translation/lang/zh/totranslate.txt
new file mode 100644
index 0000000..aaa32f9
--- /dev/null
+++ b/platform/www/lib/plugins/translation/lang/zh/totranslate.txt
@@ -0,0 +1 @@
+ç­‰å¾…ä¿®å¤ **此页é¢æ²¡æœ‰è¢«ç¿»è¯‘完全。请帮助翻译本页。**\\ //(当全文翻译完时请移除这个段è½ã€‚)// \ No newline at end of file
diff --git a/platform/www/lib/plugins/translation/manager.dat b/platform/www/lib/plugins/translation/manager.dat
new file mode 100644
index 0000000..29afe7c
--- /dev/null
+++ b/platform/www/lib/plugins/translation/manager.dat
@@ -0,0 +1,2 @@
+downloadurl=https://github.com/splitbrain/dokuwiki-plugin-translation/zipball/master
+installed=Wed, 23 Jan 2019 14:38:38 -0300
diff --git a/platform/www/lib/plugins/translation/plugin.info.txt b/platform/www/lib/plugins/translation/plugin.info.txt
new file mode 100644
index 0000000..9424ec9
--- /dev/null
+++ b/platform/www/lib/plugins/translation/plugin.info.txt
@@ -0,0 +1,8 @@
+# General Plugin Info do not edit
+base translation
+author Andreas Gohr
+email andi@splitbrain.org
+date 2018-08-17
+name Translation Plugin
+desc Supports the easy setup of a multi-language wiki.
+url http://www.dokuwiki.org/plugin:translation
diff --git a/platform/www/lib/plugins/translation/print.css b/platform/www/lib/plugins/translation/print.css
new file mode 100644
index 0000000..c2fd328
--- /dev/null
+++ b/platform/www/lib/plugins/translation/print.css
@@ -0,0 +1 @@
+.dokuwiki div.plugin_translation { display: none }
diff --git a/platform/www/lib/plugins/translation/script.js b/platform/www/lib/plugins/translation/script.js
new file mode 100644
index 0000000..819b80e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/script.js
@@ -0,0 +1,20 @@
+/**
+ * Remove go button from translation dropdown
+ */
+jQuery(function(){
+ var $frm = jQuery('#translation__dropdown');
+ if(!$frm.length) return;
+ $frm.find('input[name=go]').hide();
+ $frm.find('select[name=id]').change(function(){
+ var id = jQuery(this).val();
+ // this should hopefully detect rewriting good enough:
+ var action = $frm.attr('action');
+ if(action.substr(action.length-1) == '/'){
+ var link = action + id;
+ }else{
+ var link = action + '?id=' + id;
+ }
+
+ window.location.href= link;
+ });
+});
diff --git a/platform/www/lib/plugins/translation/style.css b/platform/www/lib/plugins/translation/style.css
new file mode 100644
index 0000000..4ace94d
--- /dev/null
+++ b/platform/www/lib/plugins/translation/style.css
@@ -0,0 +1,114 @@
+.dokuwiki div.plugin_translation {
+ font-size: 95%;
+ padding-right: 0.1em;
+ margin : 0.0em 0 0.3em 0;
+}
+
+/* List */
+
+.dokuwiki div.plugin_translation ul {
+ padding: 0;
+ margin: 0;
+ display: inline-block;
+}
+.dokuwiki div.plugin_translation ul li {
+ float: left;
+ list-style-type: none;
+ padding: 0;
+ margin: 0.2em 0 0 0;
+}
+.dokuwiki div.plugin_translation ul li img {
+ margin: -0.1em 0.2em;
+}
+
+#dokuwiki__footer .plugin_translation ul li a.wikilink1:link,
+#dokuwiki__footer .plugin_translation ul li a.wikilink1:active,
+#dokuwiki__footer .plugin_translation ul li a.wikilink1:visited {
+ background-color: #fff;
+ color: #505050;
+ text-decoration:none;
+ padding: 0.1em 0.4em;
+ margin: 0.1em 0.2em;
+ border: none !important;
+}
+
+#dokuwiki__footer .plugin_translation ul li a.wikilink1:hover {
+ background-color: #eee;
+}
+
+
+#dokuwiki__footer .plugin_translation ul li a.wikilink2:link,
+#dokuwiki__footer .plugin_translation ul li a.wikilink2:hover,
+#dokuwiki__footer .plugin_translation ul li a.wikilink2:active,
+#dokuwiki__footer .plugin_translation ul li a.wikilink2:visited {
+ background-color: #fff;
+ color: #ccc;
+ text-decoration:none;
+ padding: 0.1em 0.4em;
+ margin: 0.1em 0.2em;
+ border: none !important;
+}
+
+#dokuwiki__footer .plugin_translation ul li a.wikilink1.cur:link,
+#dokuwiki__footer .plugin_translation ul li a.wikilink1.cur:hover,
+#dokuwiki__footer .plugin_translation ul li a.wikilink1.cur:active,
+#dokuwiki__footer .plugin_translation ul li a.wikilink1.cur:visited,
+#dokuwiki__footer .plugin_translation ul li a.wikilink2.cur:link,
+#dokuwiki__footer .plugin_translation ul li a.wikilink2.cur:hover,
+#dokuwiki__footer .plugin_translation ul li a.wikilink2.cur:active,
+#dokuwiki__footer .plugin_translation ul li a.wikilink2.cur:visited {
+ background-color: #505050 !important;
+ color: #fff !important;
+ border-radius: 3px;
+
+}
+
+
+/* Dropdown */
+
+.dokuwiki div.plugin_translation select,
+.dokuwiki div.plugin_translation input {
+ border: none;
+ background-color: #ccc;
+}
+
+.dokuwiki div.plugin_translation option.flag {
+ padding-left: 18px;
+ background-repeat: no-repeat;
+ background-position: left center;
+}
+
+.dokuwiki div.plugin_translation select.wikilink1,
+.dokuwiki div.plugin_translation option.wikilink1 {
+ color: #000080;
+ text-align: center;
+}
+
+.dokuwiki div.plugin_translation select.wikilink2,
+.dokuwiki div.plugin_translation option.wikilink2 {
+ color: #808080;
+ text-align: center;
+}
+
+/* flags for non-existing pages */
+.dokuwiki div.plugin_translation img.wikilink2,
+.dokuwiki div.plugin_translation .wikilink2 img {
+ opacity: 0.5;
+}
+
+table#outdated_translations td {
+ padding-left: 3px;
+ padding-right: 3px;
+}
+
+table#outdated_translations td.missing {
+ background-color: #ff6666;
+}
+
+table#outdated_translations td.outdated {
+ background-color: #ffff66;
+}
+
+table#outdated_translations td.current {
+ background-color: #00CC00;
+}
diff --git a/platform/www/lib/plugins/translation/syntax/notrans.php b/platform/www/lib/plugins/translation/syntax/notrans.php
new file mode 100644
index 0000000..0d04671
--- /dev/null
+++ b/platform/www/lib/plugins/translation/syntax/notrans.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ * Translation Plugin: Simple multilanguage plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Class syntax_plugin_translation_notrans
+ */
+class syntax_plugin_translation_notrans extends DokuWiki_Syntax_Plugin {
+
+ /**
+ * for th helper plugin
+ * @var helper_plugin_translation
+ */
+ var $hlp = null;
+
+ /**
+ * Constructor. Load helper plugin
+ */
+ function __construct(){
+ $this->hlp = plugin_load('helper', 'translation');
+ }
+
+ /**
+ * What kind of syntax are we?
+ */
+ function getType(){
+ return 'substition';
+ }
+
+ /**
+ * Where to sort in?
+ */
+ function getSort(){
+ return 155;
+ }
+
+ /**
+ * Connect pattern to lexer
+ *
+ * @param string $mode
+ */
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('~~NOTRANS~~',$mode,'plugin_translation_notrans');
+ }
+
+ /**
+ * Handler to prepare matched data for the rendering process
+ *
+ * @param string $match The text matched by the patterns
+ * @param int $state The lexer state for the match
+ * @param int $pos The character position of the matched text
+ * @param Doku_Handler $handler The Doku_Handler object
+ * @return bool|array Return an array with all data you want to use in render, false don't add an instruction
+ */
+ function handle($match, $state, $pos, Doku_Handler $handler){
+ return array('notrans');
+ }
+
+ /**
+ * Create output
+ *
+ * @param string $format
+ * @param Doku_Renderer $renderer
+ * @param array $data
+ * @return bool
+ */
+ function render($format, Doku_Renderer $renderer, $data) {
+ // store info in metadata
+ if($format == 'metadata'){
+ /** @var Doku_Renderer_metadata $renderer */
+ $renderer->meta['plugin']['translation']['notrans'] = true;
+ }
+ return false;
+ }
+
+ // for backward compatibility
+ /**
+ * @return string
+ */
+ function _showTranslations(){
+ return $this->hlp->showTranslations();
+ }
+
+}
+
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/translation/syntax/trans.php b/platform/www/lib/plugins/translation/syntax/trans.php
new file mode 100644
index 0000000..152276e
--- /dev/null
+++ b/platform/www/lib/plugins/translation/syntax/trans.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Translation Plugin: Simple multilanguage plugin
+ *
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+// must be run within Dokuwiki
+if(!defined('DOKU_INC')) die();
+
+/**
+ * Class syntax_plugin_translation_trans
+ */
+class syntax_plugin_translation_trans extends DokuWiki_Syntax_Plugin {
+ /**
+ * What kind of syntax are we?
+ */
+ function getType() {
+ return 'substition';
+ }
+
+ /**
+ * Where to sort in?
+ */
+ function getSort() {
+ return 155;
+ }
+
+ /**
+ * Connect pattern to lexer
+ *
+ * @param string $mode
+ */
+ function connectTo($mode) {
+ $this->Lexer->addSpecialPattern('~~TRANS~~', $mode, 'plugin_translation_trans');
+ }
+
+ /**
+ * Handler to prepare matched data for the rendering process
+ *
+ * @param string $match The text matched by the patterns
+ * @param int $state The lexer state for the match
+ * @param int $pos The character position of the matched text
+ * @param Doku_Handler $handler The Doku_Handler object
+ * @return bool|array Return an array with all data you want to use in render, false don't add an instruction
+ */
+ function handle($match, $state, $pos, Doku_Handler $handler) {
+ return array();
+ }
+
+ /**
+ * Handles the actual output creation.
+ *
+ * @param string $format output format being rendered
+ * @param Doku_Renderer $renderer the current renderer object
+ * @param array $data data created by handler()
+ * @return boolean rendered correctly? (however, returned value is not used at the moment)
+ */
+ function render($format, Doku_Renderer $renderer, $data) {
+ if($format != 'xhtml') return false;
+ // disable caching
+ $renderer->nocache();
+
+ /** @var helper_plugin_translation $hlp */
+ $hlp = plugin_load('helper', 'translation');
+ $renderer->doc .= $hlp->showTranslations();
+ return true;
+ }
+
+}
+
+//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/platform/www/lib/plugins/usermanager/admin.php b/platform/www/lib/plugins/usermanager/admin.php
new file mode 100644
index 0000000..4234671
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/admin.php
@@ -0,0 +1,1235 @@
+<?php
+/*
+ * User Manager
+ *
+ * Dokuwiki Admin Plugin
+ *
+ * This version of the user manager has been modified to only work with
+ * objectified version of auth system
+ *
+ * @author neolao <neolao@neolao.com>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+/**
+ * All DokuWiki plugins to extend the admin function
+ * need to inherit from this class
+ */
+class admin_plugin_usermanager extends DokuWiki_Admin_Plugin
+{
+ const IMAGE_DIR = DOKU_BASE.'lib/plugins/usermanager/images/';
+
+ protected $auth = null; // auth object
+ protected $users_total = 0; // number of registered users
+ protected $filter = array(); // user selection filter(s)
+ protected $start = 0; // index of first user to be displayed
+ protected $last = 0; // index of the last user to be displayed
+ protected $pagesize = 20; // number of users to list on one page
+ protected $edit_user = ''; // set to user selected for editing
+ protected $edit_userdata = array();
+ protected $disabled = ''; // if disabled set to explanatory string
+ protected $import_failures = array();
+ protected $lastdisabled = false; // set to true if last user is unknown and last button is hence buggy
+
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ /** @var DokuWiki_Auth_Plugin $auth */
+ global $auth;
+
+ $this->setupLocale();
+
+ if (!isset($auth)) {
+ $this->disabled = $this->lang['noauth'];
+ } elseif (!$auth->canDo('getUsers')) {
+ $this->disabled = $this->lang['nosupport'];
+ } else {
+ // we're good to go
+ $this->auth = & $auth;
+ }
+
+ // attempt to retrieve any import failures from the session
+ if (!empty($_SESSION['import_failures'])) {
+ $this->import_failures = $_SESSION['import_failures'];
+ }
+ }
+
+ /**
+ * Return prompt for admin menu
+ *
+ * @param string $language
+ * @return string
+ */
+ public function getMenuText($language)
+ {
+
+ if (!is_null($this->auth))
+ return parent::getMenuText($language);
+
+ return $this->getLang('menu').' '.$this->disabled;
+ }
+
+ /**
+ * return sort order for position in admin menu
+ *
+ * @return int
+ */
+ public function getMenuSort()
+ {
+ return 2;
+ }
+
+ /**
+ * @return int current start value for pageination
+ */
+ public function getStart()
+ {
+ return $this->start;
+ }
+
+ /**
+ * @return int number of users per page
+ */
+ public function getPagesize()
+ {
+ return $this->pagesize;
+ }
+
+ /**
+ * @param boolean $lastdisabled
+ */
+ public function setLastdisabled($lastdisabled)
+ {
+ $this->lastdisabled = $lastdisabled;
+ }
+
+ /**
+ * Handle user request
+ *
+ * @return bool
+ */
+ public function handle()
+ {
+ global $INPUT;
+ if (is_null($this->auth)) return false;
+
+ // extract the command and any specific parameters
+ // submit button name is of the form - fn[cmd][param(s)]
+ $fn = $INPUT->param('fn');
+
+ if (is_array($fn)) {
+ $cmd = key($fn);
+ $param = is_array($fn[$cmd]) ? key($fn[$cmd]) : null;
+ } else {
+ $cmd = $fn;
+ $param = null;
+ }
+
+ if ($cmd != "search") {
+ $this->start = $INPUT->int('start', 0);
+ $this->filter = $this->retrieveFilter();
+ }
+
+ switch ($cmd) {
+ case "add":
+ $this->addUser();
+ break;
+ case "delete":
+ $this->deleteUser();
+ break;
+ case "modify":
+ $this->modifyUser();
+ break;
+ case "edit":
+ $this->editUser($param);
+ break;
+ case "search":
+ $this->setFilter($param);
+ $this->start = 0;
+ break;
+ case "export":
+ $this->exportCSV();
+ break;
+ case "import":
+ $this->importCSV();
+ break;
+ case "importfails":
+ $this->downloadImportFailures();
+ break;
+ }
+
+ $this->users_total = $this->auth->canDo('getUserCount') ? $this->auth->getUserCount($this->filter) : -1;
+
+ // page handling
+ switch ($cmd) {
+ case 'start':
+ $this->start = 0;
+ break;
+ case 'prev':
+ $this->start -= $this->pagesize;
+ break;
+ case 'next':
+ $this->start += $this->pagesize;
+ break;
+ case 'last':
+ $this->start = $this->users_total;
+ break;
+ }
+ $this->validatePagination();
+ return true;
+ }
+
+ /**
+ * Output appropriate html
+ *
+ * @return bool
+ */
+ public function html()
+ {
+ global $ID;
+
+ if (is_null($this->auth)) {
+ print $this->lang['badauth'];
+ return false;
+ }
+
+ $user_list = $this->auth->retrieveUsers($this->start, $this->pagesize, $this->filter);
+
+ $page_buttons = $this->pagination();
+ $delete_disable = $this->auth->canDo('delUser') ? '' : 'disabled="disabled"';
+
+ $editable = $this->auth->canDo('UserMod');
+ $export_label = empty($this->filter) ? $this->lang['export_all'] : $this->lang['export_filtered'];
+
+ print $this->locale_xhtml('intro');
+ print $this->locale_xhtml('list');
+
+ ptln("<div id=\"user__manager\">");
+ ptln("<div class=\"level2\">");
+
+ if ($this->users_total > 0) {
+ ptln(
+ "<p>" . sprintf(
+ $this->lang['summary'],
+ $this->start + 1,
+ $this->last,
+ $this->users_total,
+ $this->auth->getUserCount()
+ ) . "</p>"
+ );
+ } else {
+ if ($this->users_total < 0) {
+ $allUserTotal = 0;
+ } else {
+ $allUserTotal = $this->auth->getUserCount();
+ }
+ ptln("<p>".sprintf($this->lang['nonefound'], $allUserTotal)."</p>");
+ }
+ ptln("<form action=\"".wl($ID)."\" method=\"post\">");
+ formSecurityToken();
+ ptln(" <div class=\"table\">");
+ ptln(" <table class=\"inline\">");
+ ptln(" <thead>");
+ ptln(" <tr>");
+ ptln(" <th>&#160;</th>
+ <th>".$this->lang["user_id"]."</th>
+ <th>".$this->lang["user_name"]."</th>
+ <th>".$this->lang["user_mail"]."</th>
+ <th>".$this->lang["user_groups"]."</th>");
+ ptln(" </tr>");
+
+ ptln(" <tr>");
+ ptln(" <td class=\"rightalign\"><input type=\"image\" src=\"".
+ self::IMAGE_DIR."search.png\" name=\"fn[search][new]\" title=\"".
+ $this->lang['search_prompt']."\" alt=\"".$this->lang['search']."\" class=\"button\" /></td>");
+ ptln(" <td><input type=\"text\" name=\"userid\" class=\"edit\" value=\"".
+ $this->htmlFilter('user')."\" /></td>");
+ ptln(" <td><input type=\"text\" name=\"username\" class=\"edit\" value=\"".
+ $this->htmlFilter('name')."\" /></td>");
+ ptln(" <td><input type=\"text\" name=\"usermail\" class=\"edit\" value=\"".
+ $this->htmlFilter('mail')."\" /></td>");
+ ptln(" <td><input type=\"text\" name=\"usergroups\" class=\"edit\" value=\"".
+ $this->htmlFilter('grps')."\" /></td>");
+ ptln(" </tr>");
+ ptln(" </thead>");
+
+ if ($this->users_total) {
+ ptln(" <tbody>");
+ foreach ($user_list as $user => $userinfo) {
+ extract($userinfo);
+ /**
+ * @var string $name
+ * @var string $pass
+ * @var string $mail
+ * @var array $grps
+ */
+ $groups = join(', ', $grps);
+ ptln(" <tr class=\"user_info\">");
+ ptln(" <td class=\"centeralign\"><input type=\"checkbox\" name=\"delete[".hsc($user).
+ "]\" ".$delete_disable." /></td>");
+ if ($editable) {
+ ptln(" <td><a href=\"".wl($ID, array('fn[edit]['.$user.']' => 1,
+ 'do' => 'admin',
+ 'page' => 'usermanager',
+ 'sectok' => getSecurityToken())).
+ "\" title=\"".$this->lang['edit_prompt']."\">".hsc($user)."</a></td>");
+ } else {
+ ptln(" <td>".hsc($user)."</td>");
+ }
+ ptln(" <td>".hsc($name)."</td><td>".hsc($mail)."</td><td>".hsc($groups)."</td>");
+ ptln(" </tr>");
+ }
+ ptln(" </tbody>");
+ }
+
+ ptln(" <tbody>");
+ ptln(" <tr><td colspan=\"5\" class=\"centeralign\">");
+ ptln(" <span class=\"medialeft\">");
+ ptln(" <button type=\"submit\" name=\"fn[delete]\" id=\"usrmgr__del\" ".$delete_disable.">".
+ $this->lang['delete_selected']."</button>");
+ ptln(" </span>");
+ ptln(" <span class=\"mediaright\">");
+ ptln(" <button type=\"submit\" name=\"fn[start]\" ".$page_buttons['start'].">".
+ $this->lang['start']."</button>");
+ ptln(" <button type=\"submit\" name=\"fn[prev]\" ".$page_buttons['prev'].">".
+ $this->lang['prev']."</button>");
+ ptln(" <button type=\"submit\" name=\"fn[next]\" ".$page_buttons['next'].">".
+ $this->lang['next']."</button>");
+ ptln(" <button type=\"submit\" name=\"fn[last]\" ".$page_buttons['last'].">".
+ $this->lang['last']."</button>");
+ ptln(" </span>");
+ if (!empty($this->filter)) {
+ ptln(" <button type=\"submit\" name=\"fn[search][clear]\">".$this->lang['clear']."</button>");
+ }
+ ptln(" <button type=\"submit\" name=\"fn[export]\">".$export_label."</button>");
+ ptln(" <input type=\"hidden\" name=\"do\" value=\"admin\" />");
+ ptln(" <input type=\"hidden\" name=\"page\" value=\"usermanager\" />");
+
+ $this->htmlFilterSettings(2);
+
+ ptln(" </td></tr>");
+ ptln(" </tbody>");
+ ptln(" </table>");
+ ptln(" </div>");
+
+ ptln("</form>");
+ ptln("</div>");
+
+ $style = $this->edit_user ? " class=\"edit_user\"" : "";
+
+ if ($this->auth->canDo('addUser')) {
+ ptln("<div".$style.">");
+ print $this->locale_xhtml('add');
+ ptln(" <div class=\"level2\">");
+
+ $this->htmlUserForm('add', null, array(), 4);
+
+ ptln(" </div>");
+ ptln("</div>");
+ }
+
+ if ($this->edit_user && $this->auth->canDo('UserMod')) {
+ ptln("<div".$style." id=\"scroll__here\">");
+ print $this->locale_xhtml('edit');
+ ptln(" <div class=\"level2\">");
+
+ $this->htmlUserForm('modify', $this->edit_user, $this->edit_userdata, 4);
+
+ ptln(" </div>");
+ ptln("</div>");
+ }
+
+ if ($this->auth->canDo('addUser')) {
+ $this->htmlImportForm();
+ }
+ ptln("</div>");
+ return true;
+ }
+
+ /**
+ * User Manager is only available if the auth backend supports it
+ *
+ * @inheritdoc
+ * @return bool
+ */
+ public function isAccessibleByCurrentUser()
+ {
+ /** @var DokuWiki_Auth_Plugin $auth */
+ global $auth;
+ if(!$auth || !$auth->canDo('getUsers') ) {
+ return false;
+ }
+
+ return parent::isAccessibleByCurrentUser();
+ }
+
+
+ /**
+ * Display form to add or modify a user
+ *
+ * @param string $cmd 'add' or 'modify'
+ * @param string $user id of user
+ * @param array $userdata array with name, mail, pass and grps
+ * @param int $indent
+ */
+ protected function htmlUserForm($cmd, $user = '', $userdata = array(), $indent = 0)
+ {
+ global $conf;
+ global $ID;
+ global $lang;
+
+ $name = $mail = $groups = '';
+ $notes = array();
+
+ if ($user) {
+ extract($userdata);
+ if (!empty($grps)) $groups = join(',', $grps);
+ } else {
+ $notes[] = sprintf($this->lang['note_group'], $conf['defaultgroup']);
+ }
+
+ ptln("<form action=\"".wl($ID)."\" method=\"post\">", $indent);
+ formSecurityToken();
+ ptln(" <div class=\"table\">", $indent);
+ ptln(" <table class=\"inline\">", $indent);
+ ptln(" <thead>", $indent);
+ ptln(" <tr><th>".$this->lang["field"]."</th><th>".$this->lang["value"]."</th></tr>", $indent);
+ ptln(" </thead>", $indent);
+ ptln(" <tbody>", $indent);
+
+ $this->htmlInputField(
+ $cmd . "_userid",
+ "userid",
+ $this->lang["user_id"],
+ $user,
+ $this->auth->canDo("modLogin"),
+ true,
+ $indent + 6
+ );
+ $this->htmlInputField(
+ $cmd . "_userpass",
+ "userpass",
+ $this->lang["user_pass"],
+ "",
+ $this->auth->canDo("modPass"),
+ false,
+ $indent + 6
+ );
+ $this->htmlInputField(
+ $cmd . "_userpass2",
+ "userpass2",
+ $lang["passchk"],
+ "",
+ $this->auth->canDo("modPass"),
+ false,
+ $indent + 6
+ );
+ $this->htmlInputField(
+ $cmd . "_username",
+ "username",
+ $this->lang["user_name"],
+ $name,
+ $this->auth->canDo("modName"),
+ true,
+ $indent + 6
+ );
+ $this->htmlInputField(
+ $cmd . "_usermail",
+ "usermail",
+ $this->lang["user_mail"],
+ $mail,
+ $this->auth->canDo("modMail"),
+ true,
+ $indent + 6
+ );
+ $this->htmlInputField(
+ $cmd . "_usergroups",
+ "usergroups",
+ $this->lang["user_groups"],
+ $groups,
+ $this->auth->canDo("modGroups"),
+ false,
+ $indent + 6
+ );
+
+ if ($this->auth->canDo("modPass")) {
+ if ($cmd == 'add') {
+ $notes[] = $this->lang['note_pass'];
+ }
+ if ($user) {
+ $notes[] = $this->lang['note_notify'];
+ }
+
+ ptln("<tr><td><label for=\"".$cmd."_usernotify\" >".
+ $this->lang["user_notify"].": </label></td>
+ <td><input type=\"checkbox\" id=\"".$cmd."_usernotify\" name=\"usernotify\" value=\"1\" />
+ </td></tr>", $indent);
+ }
+
+ ptln(" </tbody>", $indent);
+ ptln(" <tbody>", $indent);
+ ptln(" <tr>", $indent);
+ ptln(" <td colspan=\"2\">", $indent);
+ ptln(" <input type=\"hidden\" name=\"do\" value=\"admin\" />", $indent);
+ ptln(" <input type=\"hidden\" name=\"page\" value=\"usermanager\" />", $indent);
+
+ // save current $user, we need this to access details if the name is changed
+ if ($user)
+ ptln(" <input type=\"hidden\" name=\"userid_old\" value=\"".hsc($user)."\" />", $indent);
+
+ $this->htmlFilterSettings($indent+10);
+
+ ptln(" <button type=\"submit\" name=\"fn[".$cmd."]\">".$this->lang[$cmd]."</button>", $indent);
+ ptln(" </td>", $indent);
+ ptln(" </tr>", $indent);
+ ptln(" </tbody>", $indent);
+ ptln(" </table>", $indent);
+
+ if ($notes) {
+ ptln(" <ul class=\"notes\">");
+ foreach ($notes as $note) {
+ ptln(" <li><span class=\"li\">".$note."</li>", $indent);
+ }
+ ptln(" </ul>");
+ }
+ ptln(" </div>", $indent);
+ ptln("</form>", $indent);
+ }
+
+ /**
+ * Prints a inputfield
+ *
+ * @param string $id
+ * @param string $name
+ * @param string $label
+ * @param string $value
+ * @param bool $cando whether auth backend is capable to do this action
+ * @param bool $required is this field required?
+ * @param int $indent
+ */
+ protected function htmlInputField($id, $name, $label, $value, $cando, $required, $indent = 0)
+ {
+ $class = $cando ? '' : ' class="disabled"';
+ echo str_pad('', $indent);
+
+ if ($name == 'userpass' || $name == 'userpass2') {
+ $fieldtype = 'password';
+ $autocomp = 'autocomplete="off"';
+ } elseif ($name == 'usermail') {
+ $fieldtype = 'email';
+ $autocomp = '';
+ } else {
+ $fieldtype = 'text';
+ $autocomp = '';
+ }
+ $value = hsc($value);
+
+ echo "<tr $class>";
+ echo "<td><label for=\"$id\" >$label: </label></td>";
+ echo "<td>";
+ if ($cando) {
+ $req = '';
+ if ($required) $req = 'required="required"';
+ echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\"
+ value=\"$value\" class=\"edit\" $autocomp $req />";
+ } else {
+ echo "<input type=\"hidden\" name=\"$name\" value=\"$value\" />";
+ echo "<input type=\"$fieldtype\" id=\"$id\" name=\"$name\"
+ value=\"$value\" class=\"edit disabled\" disabled=\"disabled\" />";
+ }
+ echo "</td>";
+ echo "</tr>";
+ }
+
+ /**
+ * Returns htmlescaped filter value
+ *
+ * @param string $key name of search field
+ * @return string html escaped value
+ */
+ protected function htmlFilter($key)
+ {
+ if (empty($this->filter)) return '';
+ return (isset($this->filter[$key]) ? hsc($this->filter[$key]) : '');
+ }
+
+ /**
+ * Print hidden inputs with the current filter values
+ *
+ * @param int $indent
+ */
+ protected function htmlFilterSettings($indent = 0)
+ {
+
+ ptln("<input type=\"hidden\" name=\"start\" value=\"".$this->start."\" />", $indent);
+
+ foreach ($this->filter as $key => $filter) {
+ ptln("<input type=\"hidden\" name=\"filter[".$key."]\" value=\"".hsc($filter)."\" />", $indent);
+ }
+ }
+
+ /**
+ * Print import form and summary of previous import
+ *
+ * @param int $indent
+ */
+ protected function htmlImportForm($indent = 0)
+ {
+ global $ID;
+
+ $failure_download_link = wl($ID, array('do'=>'admin','page'=>'usermanager','fn[importfails]'=>1));
+
+ ptln('<div class="level2 import_users">', $indent);
+ print $this->locale_xhtml('import');
+ ptln(' <form action="'.wl($ID).'" method="post" enctype="multipart/form-data">', $indent);
+ formSecurityToken();
+ ptln(' <label>'.$this->lang['import_userlistcsv'].'<input type="file" name="import" /></label>', $indent);
+ ptln(' <button type="submit" name="fn[import]">'.$this->lang['import'].'</button>', $indent);
+ ptln(' <input type="hidden" name="do" value="admin" />', $indent);
+ ptln(' <input type="hidden" name="page" value="usermanager" />', $indent);
+
+ $this->htmlFilterSettings($indent+4);
+ ptln(' </form>', $indent);
+ ptln('</div>');
+
+ // list failures from the previous import
+ if ($this->import_failures) {
+ $digits = strlen(count($this->import_failures));
+ ptln('<div class="level3 import_failures">', $indent);
+ ptln(' <h3>'.$this->lang['import_header'].'</h3>');
+ ptln(' <table class="import_failures">', $indent);
+ ptln(' <thead>', $indent);
+ ptln(' <tr>', $indent);
+ ptln(' <th class="line">'.$this->lang['line'].'</th>', $indent);
+ ptln(' <th class="error">'.$this->lang['error'].'</th>', $indent);
+ ptln(' <th class="userid">'.$this->lang['user_id'].'</th>', $indent);
+ ptln(' <th class="username">'.$this->lang['user_name'].'</th>', $indent);
+ ptln(' <th class="usermail">'.$this->lang['user_mail'].'</th>', $indent);
+ ptln(' <th class="usergroups">'.$this->lang['user_groups'].'</th>', $indent);
+ ptln(' </tr>', $indent);
+ ptln(' </thead>', $indent);
+ ptln(' <tbody>', $indent);
+ foreach ($this->import_failures as $line => $failure) {
+ ptln(' <tr>', $indent);
+ ptln(' <td class="lineno"> '.sprintf('%0'.$digits.'d', $line).' </td>', $indent);
+ ptln(' <td class="error">' .$failure['error'].' </td>', $indent);
+ ptln(' <td class="field userid"> '.hsc($failure['user'][0]).' </td>', $indent);
+ ptln(' <td class="field username"> '.hsc($failure['user'][2]).' </td>', $indent);
+ ptln(' <td class="field usermail"> '.hsc($failure['user'][3]).' </td>', $indent);
+ ptln(' <td class="field usergroups"> '.hsc($failure['user'][4]).' </td>', $indent);
+ ptln(' </tr>', $indent);
+ }
+ ptln(' </tbody>', $indent);
+ ptln(' </table>', $indent);
+ ptln(' <p><a href="'.$failure_download_link.'">'.$this->lang['import_downloadfailures'].'</a></p>');
+ ptln('</div>');
+ }
+ }
+
+ /**
+ * Add an user to auth backend
+ *
+ * @return bool whether succesful
+ */
+ protected function addUser()
+ {
+ global $INPUT;
+ if (!checkSecurityToken()) return false;
+ if (!$this->auth->canDo('addUser')) return false;
+
+ list($user,$pass,$name,$mail,$grps,$passconfirm) = $this->retrieveUser();
+ if (empty($user)) return false;
+
+ if ($this->auth->canDo('modPass')) {
+ if (empty($pass)) {
+ if ($INPUT->has('usernotify')) {
+ $pass = auth_pwgen($user);
+ } else {
+ msg($this->lang['add_fail'], -1);
+ msg($this->lang['addUser_error_missing_pass'], -1);
+ return false;
+ }
+ } else {
+ if (!$this->verifyPassword($pass, $passconfirm)) {
+ msg($this->lang['add_fail'], -1);
+ msg($this->lang['addUser_error_pass_not_identical'], -1);
+ return false;
+ }
+ }
+ } else {
+ if (!empty($pass)) {
+ msg($this->lang['add_fail'], -1);
+ msg($this->lang['addUser_error_modPass_disabled'], -1);
+ return false;
+ }
+ }
+
+ if ($this->auth->canDo('modName')) {
+ if (empty($name)) {
+ msg($this->lang['add_fail'], -1);
+ msg($this->lang['addUser_error_name_missing'], -1);
+ return false;
+ }
+ } else {
+ if (!empty($name)) {
+ msg($this->lang['add_fail'], -1);
+ msg($this->lang['addUser_error_modName_disabled'], -1);
+ return false;
+ }
+ }
+
+ if ($this->auth->canDo('modMail')) {
+ if (empty($mail)) {
+ msg($this->lang['add_fail'], -1);
+ msg($this->lang['addUser_error_mail_missing'], -1);
+ return false;
+ }
+ } else {
+ if (!empty($mail)) {
+ msg($this->lang['add_fail'], -1);
+ msg($this->lang['addUser_error_modMail_disabled'], -1);
+ return false;
+ }
+ }
+
+ if ($ok = $this->auth->triggerUserMod('create', array($user, $pass, $name, $mail, $grps))) {
+ msg($this->lang['add_ok'], 1);
+
+ if ($INPUT->has('usernotify') && $pass) {
+ $this->notifyUser($user, $pass);
+ }
+ } else {
+ msg($this->lang['add_fail'], -1);
+ msg($this->lang['addUser_error_create_event_failed'], -1);
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Delete user from auth backend
+ *
+ * @return bool whether succesful
+ */
+ protected function deleteUser()
+ {
+ global $conf, $INPUT;
+
+ if (!checkSecurityToken()) return false;
+ if (!$this->auth->canDo('delUser')) return false;
+
+ $selected = $INPUT->arr('delete');
+ if (empty($selected)) return false;
+ $selected = array_keys($selected);
+
+ if (in_array($_SERVER['REMOTE_USER'], $selected)) {
+ msg("You can't delete yourself!", -1);
+ return false;
+ }
+
+ $count = $this->auth->triggerUserMod('delete', array($selected));
+ if ($count == count($selected)) {
+ $text = str_replace('%d', $count, $this->lang['delete_ok']);
+ msg("$text.", 1);
+ } else {
+ $part1 = str_replace('%d', $count, $this->lang['delete_ok']);
+ $part2 = str_replace('%d', (count($selected)-$count), $this->lang['delete_fail']);
+ msg("$part1, $part2", -1);
+ }
+
+ // invalidate all sessions
+ io_saveFile($conf['cachedir'].'/sessionpurge', time());
+
+ return true;
+ }
+
+ /**
+ * Edit user (a user has been selected for editing)
+ *
+ * @param string $param id of the user
+ * @return bool whether succesful
+ */
+ protected function editUser($param)
+ {
+ if (!checkSecurityToken()) return false;
+ if (!$this->auth->canDo('UserMod')) return false;
+ $user = $this->auth->cleanUser(preg_replace('/.*[:\/]/', '', $param));
+ $userdata = $this->auth->getUserData($user);
+
+ // no user found?
+ if (!$userdata) {
+ msg($this->lang['edit_usermissing'], -1);
+ return false;
+ }
+
+ $this->edit_user = $user;
+ $this->edit_userdata = $userdata;
+
+ return true;
+ }
+
+ /**
+ * Modify user in the auth backend (modified user data has been recieved)
+ *
+ * @return bool whether succesful
+ */
+ protected function modifyUser()
+ {
+ global $conf, $INPUT;
+
+ if (!checkSecurityToken()) return false;
+ if (!$this->auth->canDo('UserMod')) return false;
+
+ // get currently valid user data
+ $olduser = $this->auth->cleanUser(preg_replace('/.*[:\/]/', '', $INPUT->str('userid_old')));
+ $oldinfo = $this->auth->getUserData($olduser);
+
+ // get new user data subject to change
+ list($newuser,$newpass,$newname,$newmail,$newgrps,$passconfirm) = $this->retrieveUser();
+ if (empty($newuser)) return false;
+
+ $changes = array();
+ if ($newuser != $olduser) {
+ if (!$this->auth->canDo('modLogin')) { // sanity check, shouldn't be possible
+ msg($this->lang['update_fail'], -1);
+ return false;
+ }
+
+ // check if $newuser already exists
+ if ($this->auth->getUserData($newuser)) {
+ msg(sprintf($this->lang['update_exists'], $newuser), -1);
+ $re_edit = true;
+ } else {
+ $changes['user'] = $newuser;
+ }
+ }
+ if ($this->auth->canDo('modPass')) {
+ if ($newpass || $passconfirm) {
+ if ($this->verifyPassword($newpass, $passconfirm)) {
+ $changes['pass'] = $newpass;
+ } else {
+ return false;
+ }
+ } else {
+ // no new password supplied, check if we need to generate one (or it stays unchanged)
+ if ($INPUT->has('usernotify')) {
+ $changes['pass'] = auth_pwgen($olduser);
+ }
+ }
+ }
+
+ if (!empty($newname) && $this->auth->canDo('modName') && $newname != $oldinfo['name']) {
+ $changes['name'] = $newname;
+ }
+ if (!empty($newmail) && $this->auth->canDo('modMail') && $newmail != $oldinfo['mail']) {
+ $changes['mail'] = $newmail;
+ }
+ if (!empty($newgrps) && $this->auth->canDo('modGroups') && $newgrps != $oldinfo['grps']) {
+ $changes['grps'] = $newgrps;
+ }
+
+ if ($ok = $this->auth->triggerUserMod('modify', array($olduser, $changes))) {
+ msg($this->lang['update_ok'], 1);
+
+ if ($INPUT->has('usernotify') && !empty($changes['pass'])) {
+ $notify = empty($changes['user']) ? $olduser : $newuser;
+ $this->notifyUser($notify, $changes['pass']);
+ }
+
+ // invalidate all sessions
+ io_saveFile($conf['cachedir'].'/sessionpurge', time());
+ } else {
+ msg($this->lang['update_fail'], -1);
+ }
+
+ if (!empty($re_edit)) {
+ $this->editUser($olduser);
+ }
+
+ return $ok;
+ }
+
+ /**
+ * Send password change notification email
+ *
+ * @param string $user id of user
+ * @param string $password plain text
+ * @param bool $status_alert whether status alert should be shown
+ * @return bool whether succesful
+ */
+ protected function notifyUser($user, $password, $status_alert = true)
+ {
+
+ if ($sent = auth_sendPassword($user, $password)) {
+ if ($status_alert) {
+ msg($this->lang['notify_ok'], 1);
+ }
+ } else {
+ if ($status_alert) {
+ msg($this->lang['notify_fail'], -1);
+ }
+ }
+
+ return $sent;
+ }
+
+ /**
+ * Verify password meets minimum requirements
+ * :TODO: extend to support password strength
+ *
+ * @param string $password candidate string for new password
+ * @param string $confirm repeated password for confirmation
+ * @return bool true if meets requirements, false otherwise
+ */
+ protected function verifyPassword($password, $confirm)
+ {
+ global $lang;
+
+ if (empty($password) && empty($confirm)) {
+ return false;
+ }
+
+ if ($password !== $confirm) {
+ msg($lang['regbadpass'], -1);
+ return false;
+ }
+
+ // :TODO: test password for required strength
+
+ // if we make it this far the password is good
+ return true;
+ }
+
+ /**
+ * Retrieve & clean user data from the form
+ *
+ * @param bool $clean whether the cleanUser method of the authentication backend is applied
+ * @return array (user, password, full name, email, array(groups))
+ */
+ protected function retrieveUser($clean = true)
+ {
+ /** @var DokuWiki_Auth_Plugin $auth */
+ global $auth;
+ global $INPUT;
+
+ $user = array();
+ $user[0] = ($clean) ? $auth->cleanUser($INPUT->str('userid')) : $INPUT->str('userid');
+ $user[1] = $INPUT->str('userpass');
+ $user[2] = $INPUT->str('username');
+ $user[3] = $INPUT->str('usermail');
+ $user[4] = explode(',', $INPUT->str('usergroups'));
+ $user[5] = $INPUT->str('userpass2'); // repeated password for confirmation
+
+ $user[4] = array_map('trim', $user[4]);
+ if ($clean) $user[4] = array_map(array($auth,'cleanGroup'), $user[4]);
+ $user[4] = array_filter($user[4]);
+ $user[4] = array_unique($user[4]);
+ if (!count($user[4])) $user[4] = null;
+
+ return $user;
+ }
+
+ /**
+ * Set the filter with the current search terms or clear the filter
+ *
+ * @param string $op 'new' or 'clear'
+ */
+ protected function setFilter($op)
+ {
+
+ $this->filter = array();
+
+ if ($op == 'new') {
+ list($user,/* $pass */,$name,$mail,$grps) = $this->retrieveUser(false);
+
+ if (!empty($user)) $this->filter['user'] = $user;
+ if (!empty($name)) $this->filter['name'] = $name;
+ if (!empty($mail)) $this->filter['mail'] = $mail;
+ if (!empty($grps)) $this->filter['grps'] = join('|', $grps);
+ }
+ }
+
+ /**
+ * Get the current search terms
+ *
+ * @return array
+ */
+ protected function retrieveFilter()
+ {
+ global $INPUT;
+
+ $t_filter = $INPUT->arr('filter');
+
+ // messy, but this way we ensure we aren't getting any additional crap from malicious users
+ $filter = array();
+
+ if (isset($t_filter['user'])) $filter['user'] = $t_filter['user'];
+ if (isset($t_filter['name'])) $filter['name'] = $t_filter['name'];
+ if (isset($t_filter['mail'])) $filter['mail'] = $t_filter['mail'];
+ if (isset($t_filter['grps'])) $filter['grps'] = $t_filter['grps'];
+
+ return $filter;
+ }
+
+ /**
+ * Validate and improve the pagination values
+ */
+ protected function validatePagination()
+ {
+
+ if ($this->start >= $this->users_total) {
+ $this->start = $this->users_total - $this->pagesize;
+ }
+ if ($this->start < 0) $this->start = 0;
+
+ $this->last = min($this->users_total, $this->start + $this->pagesize);
+ }
+
+ /**
+ * Return an array of strings to enable/disable pagination buttons
+ *
+ * @return array with enable/disable attributes
+ */
+ protected function pagination()
+ {
+
+ $disabled = 'disabled="disabled"';
+
+ $buttons = array();
+ $buttons['start'] = $buttons['prev'] = ($this->start == 0) ? $disabled : '';
+
+ if ($this->users_total == -1) {
+ $buttons['last'] = $disabled;
+ $buttons['next'] = '';
+ } else {
+ $buttons['last'] = $buttons['next'] =
+ (($this->start + $this->pagesize) >= $this->users_total) ? $disabled : '';
+ }
+
+ if ($this->lastdisabled) {
+ $buttons['last'] = $disabled;
+ }
+
+ return $buttons;
+ }
+
+ /**
+ * Export a list of users in csv format using the current filter criteria
+ */
+ protected function exportCSV()
+ {
+ // list of users for export - based on current filter criteria
+ $user_list = $this->auth->retrieveUsers(0, 0, $this->filter);
+ $column_headings = array(
+ $this->lang["user_id"],
+ $this->lang["user_name"],
+ $this->lang["user_mail"],
+ $this->lang["user_groups"]
+ );
+
+ // ==============================================================================================
+ // GENERATE OUTPUT
+ // normal headers for downloading...
+ header('Content-type: text/csv;charset=utf-8');
+ header('Content-Disposition: attachment; filename="wikiusers.csv"');
+# // for debugging assistance, send as text plain to the browser
+# header('Content-type: text/plain;charset=utf-8');
+
+ // output the csv
+ $fd = fopen('php://output', 'w');
+ fputcsv($fd, $column_headings);
+ foreach ($user_list as $user => $info) {
+ $line = array($user, $info['name'], $info['mail'], join(',', $info['grps']));
+ fputcsv($fd, $line);
+ }
+ fclose($fd);
+ if (defined('DOKU_UNITTEST')) {
+ return;
+ }
+
+ die;
+ }
+
+ /**
+ * Import a file of users in csv format
+ *
+ * csv file should have 4 columns, user_id, full name, email, groups (comma separated)
+ *
+ * @return bool whether successful
+ */
+ protected function importCSV()
+ {
+ // check we are allowed to add users
+ if (!checkSecurityToken()) return false;
+ if (!$this->auth->canDo('addUser')) return false;
+
+ // check file uploaded ok.
+ if (empty($_FILES['import']['size']) ||
+ !empty($_FILES['import']['error']) && $this->isUploadedFile($_FILES['import']['tmp_name'])
+ ) {
+ msg($this->lang['import_error_upload'], -1);
+ return false;
+ }
+ // retrieve users from the file
+ $this->import_failures = array();
+ $import_success_count = 0;
+ $import_fail_count = 0;
+ $line = 0;
+ $fd = fopen($_FILES['import']['tmp_name'], 'r');
+ if ($fd) {
+ while ($csv = fgets($fd)) {
+ if (!\dokuwiki\Utf8\Clean::isUtf8($csv)) {
+ $csv = utf8_encode($csv);
+ }
+ $raw = str_getcsv($csv);
+ $error = ''; // clean out any errors from the previous line
+ // data checks...
+ if (1 == ++$line) {
+ if ($raw[0] == 'user_id' || $raw[0] == $this->lang['user_id']) continue; // skip headers
+ }
+ if (count($raw) < 4) { // need at least four fields
+ $import_fail_count++;
+ $error = sprintf($this->lang['import_error_fields'], count($raw));
+ $this->import_failures[$line] = array('error' => $error, 'user' => $raw, 'orig' => $csv);
+ continue;
+ }
+ array_splice($raw, 1, 0, auth_pwgen()); // splice in a generated password
+ $clean = $this->cleanImportUser($raw, $error);
+ if ($clean && $this->importUser($clean, $error)) {
+ $sent = $this->notifyUser($clean[0], $clean[1], false);
+ if (!$sent) {
+ msg(sprintf($this->lang['import_notify_fail'], $clean[0], $clean[3]), -1);
+ }
+ $import_success_count++;
+ } else {
+ $import_fail_count++;
+ array_splice($raw, 1, 1); // remove the spliced in password
+ $this->import_failures[$line] = array('error' => $error, 'user' => $raw, 'orig' => $csv);
+ }
+ }
+ msg(
+ sprintf(
+ $this->lang['import_success_count'],
+ ($import_success_count + $import_fail_count),
+ $import_success_count
+ ),
+ ($import_success_count ? 1 : -1)
+ );
+ if ($import_fail_count) {
+ msg(sprintf($this->lang['import_failure_count'], $import_fail_count), -1);
+ }
+ } else {
+ msg($this->lang['import_error_readfail'], -1);
+ }
+
+ // save import failures into the session
+ if (!headers_sent()) {
+ session_start();
+ $_SESSION['import_failures'] = $this->import_failures;
+ session_write_close();
+ }
+ return true;
+ }
+
+ /**
+ * Returns cleaned user data
+ *
+ * @param array $candidate raw values of line from input file
+ * @param string $error
+ * @return array|false cleaned data or false
+ */
+ protected function cleanImportUser($candidate, & $error)
+ {
+ global $INPUT;
+
+ // FIXME kludgy ....
+ $INPUT->set('userid', $candidate[0]);
+ $INPUT->set('userpass', $candidate[1]);
+ $INPUT->set('username', $candidate[2]);
+ $INPUT->set('usermail', $candidate[3]);
+ $INPUT->set('usergroups', $candidate[4]);
+
+ $cleaned = $this->retrieveUser();
+ list($user,/* $pass */,$name,$mail,/* $grps */) = $cleaned;
+ if (empty($user)) {
+ $error = $this->lang['import_error_baduserid'];
+ return false;
+ }
+
+ // no need to check password, handled elsewhere
+
+ if (!($this->auth->canDo('modName') xor empty($name))) {
+ $error = $this->lang['import_error_badname'];
+ return false;
+ }
+
+ if ($this->auth->canDo('modMail')) {
+ if (empty($mail) || !mail_isvalid($mail)) {
+ $error = $this->lang['import_error_badmail'];
+ return false;
+ }
+ } else {
+ if (!empty($mail)) {
+ $error = $this->lang['import_error_badmail'];
+ return false;
+ }
+ }
+
+ return $cleaned;
+ }
+
+ /**
+ * Adds imported user to auth backend
+ *
+ * Required a check of canDo('addUser') before
+ *
+ * @param array $user data of user
+ * @param string &$error reference catched error message
+ * @return bool whether successful
+ */
+ protected function importUser($user, &$error)
+ {
+ if (!$this->auth->triggerUserMod('create', $user)) {
+ $error = $this->lang['import_error_create'];
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Downloads failures as csv file
+ */
+ protected function downloadImportFailures()
+ {
+
+ // ==============================================================================================
+ // GENERATE OUTPUT
+ // normal headers for downloading...
+ header('Content-type: text/csv;charset=utf-8');
+ header('Content-Disposition: attachment; filename="importfails.csv"');
+# // for debugging assistance, send as text plain to the browser
+# header('Content-type: text/plain;charset=utf-8');
+
+ // output the csv
+ $fd = fopen('php://output', 'w');
+ foreach ($this->import_failures as $fail) {
+ fputs($fd, $fail['orig']);
+ }
+ fclose($fd);
+ die;
+ }
+
+ /**
+ * wrapper for is_uploaded_file to facilitate overriding by test suite
+ *
+ * @param string $file filename
+ * @return bool
+ */
+ protected function isUploadedFile($file)
+ {
+ return is_uploaded_file($file);
+ }
+}
diff --git a/platform/www/lib/plugins/usermanager/admin.svg b/platform/www/lib/plugins/usermanager/admin.svg
new file mode 100644
index 0000000..74a72c0
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/admin.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16 13c-.29 0-.62 0-.97.05C16.19 13.89 17 15 17 16.5V19h6v-2.5c0-2.33-4.67-3.5-7-3.5m-8 0c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5m0-2a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m8 0a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3z"/></svg> \ No newline at end of file
diff --git a/platform/www/lib/plugins/usermanager/images/search.png b/platform/www/lib/plugins/usermanager/images/search.png
new file mode 100644
index 0000000..3f2a0b5
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/images/search.png
Binary files differ
diff --git a/platform/www/lib/plugins/usermanager/lang/en/add.txt b/platform/www/lib/plugins/usermanager/lang/en/add.txt
new file mode 100644
index 0000000..9afecb5
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/lang/en/add.txt
@@ -0,0 +1 @@
+===== Add user =====
diff --git a/platform/www/lib/plugins/usermanager/lang/en/delete.txt b/platform/www/lib/plugins/usermanager/lang/en/delete.txt
new file mode 100644
index 0000000..c3ca90d
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/lang/en/delete.txt
@@ -0,0 +1 @@
+===== Delete user =====
diff --git a/platform/www/lib/plugins/usermanager/lang/en/edit.txt b/platform/www/lib/plugins/usermanager/lang/en/edit.txt
new file mode 100644
index 0000000..4d02dfd
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/lang/en/edit.txt
@@ -0,0 +1 @@
+===== Edit user =====
diff --git a/platform/www/lib/plugins/usermanager/lang/en/import.txt b/platform/www/lib/plugins/usermanager/lang/en/import.txt
new file mode 100644
index 0000000..3a1cf99
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/lang/en/import.txt
@@ -0,0 +1,9 @@
+===== Bulk User Import =====
+
+Requires a CSV file of users with at least four columns.
+The columns must contain, in order: user-id, full name, email address and groups.
+The CSV fields should be separated by commas (,) and strings delimited by quotation marks (%%""%%). Backslash (\) can be used for escaping.
+For an example of a suitable file, try the "Export Users" function above.
+Duplicate user-ids will be ignored.
+
+A password will be generated and emailed to each successfully imported user.
diff --git a/platform/www/lib/plugins/usermanager/lang/en/intro.txt b/platform/www/lib/plugins/usermanager/lang/en/intro.txt
new file mode 100644
index 0000000..73bf556
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/lang/en/intro.txt
@@ -0,0 +1 @@
+====== User Manager ======
diff --git a/platform/www/lib/plugins/usermanager/lang/en/lang.php b/platform/www/lib/plugins/usermanager/lang/en/lang.php
new file mode 100644
index 0000000..5f47673
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/lang/en/lang.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * English language file
+ *
+ * @author Chris Smith <chris@jalakai.co.uk>
+ */
+
+$lang['menu'] = 'User Manager';
+
+// custom language strings for the plugin
+$lang['noauth'] = '(user authentication not available)';
+$lang['nosupport'] = '(user management not supported)';
+
+$lang['badauth'] = 'invalid auth mechanism'; // should never be displayed!
+
+$lang['user_id'] = 'User';
+$lang['user_pass'] = 'Password';
+$lang['user_name'] = 'Real Name';
+$lang['user_mail'] = 'Email';
+$lang['user_groups'] = 'Groups';
+
+$lang['field'] = 'Field';
+$lang['value'] = 'Value';
+$lang['add'] = 'Add';
+$lang['delete'] = 'Delete';
+$lang['delete_selected'] = 'Delete Selected';
+$lang['edit'] = 'Edit';
+$lang['edit_prompt'] = 'Edit this user';
+$lang['modify'] = 'Save Changes';
+$lang['search'] = 'Search';
+$lang['search_prompt'] = 'Perform search';
+$lang['clear'] = 'Reset Search Filter';
+$lang['filter'] = 'Filter';
+$lang['export_all'] = 'Export All Users (CSV)';
+$lang['export_filtered'] = 'Export Filtered User list (CSV)';
+$lang['import'] = 'Import New Users';
+$lang['line'] = 'Line no.';
+$lang['error'] = 'Error message';
+
+$lang['summary'] = 'Displaying users %1$d-%2$d of %3$d found. %4$d users total.';
+$lang['nonefound'] = 'No users found. %d users total.';
+$lang['delete_ok'] = '%d users deleted';
+$lang['delete_fail'] = '%d failed deleting.';
+$lang['update_ok'] = 'User updated successfully';
+$lang['update_fail'] = 'User update failed';
+$lang['update_exists'] = 'User name change failed, the specified user name (%s) already exists (any other changes will be applied).';
+
+$lang['start'] = 'start';
+$lang['prev'] = 'previous';
+$lang['next'] = 'next';
+$lang['last'] = 'last';
+
+// added after 2006-03-09 release
+$lang['edit_usermissing'] = 'Selected user not found, the specified user name may have been deleted or changed elsewhere.';
+$lang['user_notify'] = 'Notify user';
+$lang['note_notify'] = 'Notification emails are only sent if the user is given a new password.';
+$lang['note_group'] = 'New users will be added to the default group (%s) if no group is specified.';
+$lang['note_pass'] = 'The password will be autogenerated if the field is left empty and notification of the user is enabled.';
+$lang['add_ok'] = 'User added successfully';
+$lang['add_fail'] = 'User addition failed';
+$lang['notify_ok'] = 'Notification email sent';
+$lang['notify_fail'] = 'Notification email could not be sent';
+
+// import & errors
+$lang['import_userlistcsv'] = 'User list file (CSV): ';
+$lang['import_header'] = 'Most Recent Import - Failures';
+$lang['import_success_count'] = 'User Import: %d users found, %d imported successfully.';
+$lang['import_failure_count'] = 'User Import: %d failed. Failures are listed below.';
+$lang['import_error_fields'] = "Insufficient fields, found %d, require 4.";
+$lang['import_error_baduserid'] = "User-id missing";
+$lang['import_error_badname'] = 'Bad name';
+$lang['import_error_badmail'] = 'Bad email address';
+$lang['import_error_upload'] = 'Import Failed. The csv file could not be uploaded or is empty.';
+$lang['import_error_readfail'] = 'Import Failed. Unable to read uploaded file.';
+$lang['import_error_create'] = 'Unable to create the user';
+$lang['import_notify_fail'] = 'Notification message could not be sent for imported user, %s with email %s.';
+$lang['import_downloadfailures'] = 'Download Failures as CSV for correction';
+
+$lang['addUser_error_missing_pass'] = 'Please either set a password or activate user notification to enable password generation.';
+$lang['addUser_error_pass_not_identical'] = 'The entered passwords were not identical.';
+$lang['addUser_error_modPass_disabled'] = 'Modifing passwords is currently disabled';
+$lang['addUser_error_name_missing'] = 'Please enter a name for the new user.';
+$lang['addUser_error_modName_disabled'] = 'Modifing names is currently disabled.';
+$lang['addUser_error_mail_missing'] = 'Please enter an Email-Adress for the new user.';
+$lang['addUser_error_modMail_disabled'] = 'Modifing Email-Adresses is currently disabled.';
+$lang['addUser_error_create_event_failed'] = 'A plugin prevented the new user being added. Review possible other messages for more information.';
diff --git a/platform/www/lib/plugins/usermanager/lang/en/list.txt b/platform/www/lib/plugins/usermanager/lang/en/list.txt
new file mode 100644
index 0000000..54c45ca
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/lang/en/list.txt
@@ -0,0 +1 @@
+===== User List =====
diff --git a/platform/www/lib/plugins/usermanager/plugin.info.txt b/platform/www/lib/plugins/usermanager/plugin.info.txt
new file mode 100644
index 0000000..607eca7
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/plugin.info.txt
@@ -0,0 +1,7 @@
+base usermanager
+author Chris Smith
+email chris@jalakai.co.uk
+date 2015-07-15
+name User Manager
+desc Manage DokuWiki user accounts
+url http://dokuwiki.org/plugin:usermanager
diff --git a/platform/www/lib/plugins/usermanager/script.js b/platform/www/lib/plugins/usermanager/script.js
new file mode 100644
index 0000000..3b7ad09
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/script.js
@@ -0,0 +1,8 @@
+/**
+ * Add JavaScript confirmation to the User Delete button
+ */
+jQuery(function(){
+ jQuery('#usrmgr__del').on('click', function(){
+ return confirm(LANG.del_confirm);
+ });
+});
diff --git a/platform/www/lib/plugins/usermanager/style.css b/platform/www/lib/plugins/usermanager/style.css
new file mode 100644
index 0000000..9028fed
--- /dev/null
+++ b/platform/www/lib/plugins/usermanager/style.css
@@ -0,0 +1,33 @@
+/* User Manager specific styles */
+#user__manager tr.disabled {
+ color: #6f6f6f;
+ background: #e4e4e4;
+}
+#user__manager tr.user_info {
+ vertical-align: top;
+}
+#user__manager div.edit_user {
+ width: 46%;
+ float: left;
+}
+#user__manager table {
+ margin-bottom: 1em;
+}
+#user__manager ul.notes {
+ padding-left: 0;
+ padding-right: 1.4em;
+}
+#user__manager button[disabled] {
+ color: #ccc!important;
+ border-color: #ccc!important;
+}
+#user__manager .import_users {
+ margin-top: 1.4em;
+}
+#user__manager .import_failures {
+ margin-top: 1.4em;
+}
+#user__manager .import_failures td.lineno {
+ text-align: center;
+}
+/* IE won't understand but doesn't require it */
diff --git a/platform/www/lib/scripts/behaviour.js b/platform/www/lib/scripts/behaviour.js
new file mode 100644
index 0000000..f9aad3d
--- /dev/null
+++ b/platform/www/lib/scripts/behaviour.js
@@ -0,0 +1,195 @@
+/**
+ * Hides elements with a slide animation
+ *
+ * @param {function} fn optional callback to run after hiding
+ * @param {bool} noaria supress aria-expanded state setting
+ * @author Adrian Lang <mail@adrianlang.de>
+ */
+jQuery.fn.dw_hide = function(fn, noaria) {
+ if(!noaria) this.attr('aria-expanded', 'false');
+ return this.slideUp('fast', fn);
+};
+
+/**
+ * Unhides elements with a slide animation
+ *
+ * @param {function} fn optional callback to run after hiding
+ * @param {bool} noaria supress aria-expanded state setting
+ * @author Adrian Lang <mail@adrianlang.de>
+ */
+jQuery.fn.dw_show = function(fn, noaria) {
+ if(!noaria) this.attr('aria-expanded', 'true');
+ return this.slideDown('fast', fn);
+};
+
+/**
+ * Toggles visibility of an element using a slide element
+ *
+ * @param {bool} state the current state of the element (optional)
+ * @param {function} fn callback after the state has been toggled
+ * @param {bool} noaria supress aria-expanded state setting
+ */
+jQuery.fn.dw_toggle = function(state, fn, noaria) {
+ return this.each(function() {
+ var $this = jQuery(this);
+ if (typeof state === 'undefined') {
+ state = $this.is(':hidden');
+ }
+ $this[state ? "dw_show" : "dw_hide" ](fn, noaria);
+ });
+};
+
+/**
+ * Automatic behaviours
+ *
+ * This class wraps various JavaScript functionalities that are triggered
+ * automatically whenever a certain object is in the DOM or a certain CSS
+ * class was found
+ */
+var dw_behaviour = {
+
+ init: function(){
+ dw_behaviour.focusMarker();
+ dw_behaviour.scrollToMarker();
+ dw_behaviour.removeHighlightOnClick();
+ dw_behaviour.quickSelect();
+ dw_behaviour.checkWindowsShares();
+ dw_behaviour.subscription();
+
+ dw_behaviour.revisionBoxHandler();
+ jQuery(document).on('click','#page__revisions input[type=checkbox]',
+ dw_behaviour.revisionBoxHandler
+ );
+
+ jQuery('.bounce').effect('bounce', {times:10}, 2000 );
+ },
+
+ /**
+ * Looks for an element with the ID scroll__here at scrolls to it
+ */
+ scrollToMarker: function(){
+ var $obj = jQuery('#scroll__here');
+ if($obj.length) {
+ if($obj.offset().top != 0) {
+ jQuery('html, body').animate({
+ scrollTop: $obj.offset().top - 100
+ }, 500);
+ } else {
+ // hidden object have no offset but can still be scrolled into view
+ $obj[0].scrollIntoView();
+ }
+ }
+ },
+
+ /**
+ * Looks for an element with the ID focus__this at sets focus to it
+ */
+ focusMarker: function(){
+ jQuery('#focus__this').trigger('focus');
+ },
+
+ /**
+ * Remove all search highlighting when clicking on a highlighted term
+ */
+ removeHighlightOnClick: function(){
+ jQuery('span.search_hit').on('click',
+ function(e){
+ jQuery(e.target).removeClass('search_hit', 1000);
+ }
+ );
+ },
+
+ /**
+ * Autosubmit quick select forms
+ *
+ * When a <select> tag has the class "quickselect", this script will
+ * automatically submit its parent form when the select value changes.
+ * It also hides the submit button of the form.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ quickSelect: function(){
+ jQuery('select.quickselect')
+ .on('change', function(e){ e.target.form.submit(); })
+ .closest('form').find(':button').not('.show').hide();
+ },
+
+ /**
+ * Display error for Windows Shares on browsers other than IE
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ */
+ checkWindowsShares: function() {
+ if(!LANG.nosmblinks || navigator.userAgent.match(/(Trident|MSIE|Edge)/)) {
+ // No warning requested or none necessary
+ return;
+ }
+
+ jQuery('a.windows').on('click', function(){
+ alert(LANG.nosmblinks.replace(/\\n/,"\n"));
+ });
+ },
+
+ /**
+ * Hide list subscription style if target is a page
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ subscription: function(){
+ var $form, $list, $digest;
+
+ $form = jQuery('#subscribe__form');
+ if (0 === $form.length) return;
+
+ $list = $form.find("input[name='sub_style'][value='list']");
+ $digest = $form.find("input[name='sub_style'][value='digest']");
+
+ $form.find("input[name='sub_target']")
+ .on('click',
+ function () {
+ var $this = jQuery(this), show_list;
+ if (!$this.prop('checked')) {
+ return;
+ }
+
+ show_list = $this.val().match(/:$/);
+ $list.parent().dw_toggle(show_list);
+ if (!show_list && $list.prop('checked')) {
+ $digest.prop('checked', 'checked');
+ }
+ }
+ )
+ .filter(':checked')
+ .trigger('click');
+ },
+
+ /**
+ * disable multiple revisions checkboxes if two are checked
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+ revisionBoxHandler: function() {
+ var $revisions = jQuery('#page__revisions');
+ var $all = jQuery('input[type=checkbox]', $revisions);
+ var $checked = $all.filter(':checked');
+ var $button = jQuery('button', $revisions);
+
+ if($checked.length < 2) {
+ $all.prop('disabled', false);
+ $button.prop('disabled', true);
+ } else {
+ $all.prop('disabled', true);
+ $button.prop('disabled', false);
+ $checked.each(function(i) {
+ jQuery(this).prop('disabled', false);
+ if(i>1) {
+ jQuery(this).prop('checked', false);
+ }
+ });
+ }
+ }
+};
+
+jQuery(dw_behaviour.init);
diff --git a/platform/www/lib/scripts/compatibility.js b/platform/www/lib/scripts/compatibility.js
new file mode 100644
index 0000000..154aead
--- /dev/null
+++ b/platform/www/lib/scripts/compatibility.js
@@ -0,0 +1,42 @@
+/**
+ * Mark a JavaScript function as deprecated
+ *
+ * This will print a warning to the JavaScript console (if available) in
+ * Firebug and Chrome and a stack trace (if available) to easily locate the
+ * problematic function call.
+ *
+ * @param msg optional message to print
+ */
+function DEPRECATED(msg){
+ if(!window.console) return;
+ if(!msg) msg = '';
+
+ var func;
+ if(arguments.callee) func = arguments.callee.caller.name;
+ if(func) func = ' '+func+'()';
+ var line = 'DEPRECATED function call'+func+'. '+msg;
+
+ if(console.warn){
+ console.warn(line);
+ }else{
+ console.log(line);
+ }
+
+ if(console.trace) console.trace();
+}
+
+/**
+ * Construct a wrapper function for deprecated function names
+ *
+ * This function returns a wrapper function which just calls DEPRECATED
+ * and the new function.
+ *
+ * @param func The new function
+ * @param context Optional; The context (`this`) of the call
+ */
+function DEPRECATED_WRAP(func, context) {
+ return function () {
+ DEPRECATED();
+ return func.apply(context || this, arguments);
+ };
+}
diff --git a/platform/www/lib/scripts/cookie.js b/platform/www/lib/scripts/cookie.js
new file mode 100644
index 0000000..e260e59
--- /dev/null
+++ b/platform/www/lib/scripts/cookie.js
@@ -0,0 +1,71 @@
+/**
+* Handles the cookie used by several JavaScript functions
+*
+* Only a single cookie is written and read. You may only save
+* simple name-value pairs - no complex types!
+*
+* You should only use the getValue and setValue methods
+*
+* @author Andreas Gohr <andi@splitbrain.org>
+* @author Michal Rezler <m.rezler@centrum.cz>
+*/
+var DokuCookie = {
+ data: {},
+ name: 'DOKU_PREFS',
+
+ /**
+ * Save a value to the cookie
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ setValue: function(key,val){
+ var text = [],
+ _this = this;
+ this.init();
+ if (val === false){
+ delete this.data[key];
+ }else{
+ val = val + "";
+ this.data[key] = val;
+ }
+
+
+ //save the whole data array
+ jQuery.each(_this.data, function (key, val) {
+ if (_this.data.hasOwnProperty(key)) {
+ text.push(encodeURIComponent(key)+'#'+encodeURIComponent(val));
+ }
+ });
+ jQuery.cookie(this.name, text.join('#'), {expires: 365, path: DOKU_COOKIE_PARAM.path, secure: DOKU_COOKIE_PARAM.secure});
+ },
+
+ /**
+ * Get a Value from the Cookie
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param def default value if key does not exist; if not set, returns undefined by default
+ */
+ getValue: function(key, def){
+ this.init();
+ return this.data.hasOwnProperty(key) ? this.data[key] : def;
+ },
+
+ /**
+ * Loads the current set cookie
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ init: function(){
+ var text, parts, i;
+ if(!jQuery.isEmptyObject(this.data)) {
+ return;
+ }
+ text = jQuery.cookie(this.name);
+ if(text){
+ parts = text.split('#');
+ for(i = 0; i < parts.length; i += 2){
+ this.data[decodeURIComponent(parts[i])] = decodeURIComponent(parts[i+1]);
+ }
+ }
+ }
+};
diff --git a/platform/www/lib/scripts/delay.js b/platform/www/lib/scripts/delay.js
new file mode 100644
index 0000000..edd53de
--- /dev/null
+++ b/platform/www/lib/scripts/delay.js
@@ -0,0 +1,70 @@
+/**
+ * Manage delayed and timed actions
+ *
+ * @license GPL2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Adrian Lang <lang@cosmocode.de>
+ */
+
+/**
+ * Provide a global callback for window.setTimeout
+ *
+ * To get a timeout for non-global functions, just call
+ * delay.add(func, timeout).
+ */
+var timer = {
+ _cur_id: 0,
+ _handlers: {},
+
+ execDispatch: function (id) {
+ timer._handlers[id]();
+ },
+
+ add: function (func, timeout) {
+ var id = ++timer._cur_id;
+ timer._handlers[id] = func;
+ return window.setTimeout('timer.execDispatch(' + id + ')', timeout);
+ }
+};
+
+/**
+ * Provide a delayed start
+ *
+ * To call a function with a delay, just create a new Delay(func, timeout) and
+ * call that object’s method “startâ€.
+ */
+function Delay (func, timeout) {
+ this.func = func;
+ if (timeout) {
+ this.timeout = timeout;
+ }
+}
+
+Delay.prototype = {
+ func: null,
+ timeout: 500,
+
+ delTimer: function () {
+ if (this.timer !== null) {
+ window.clearTimeout(this.timer);
+ this.timer = null;
+ }
+ },
+
+ start: function () {
+ DEPRECATED('don\'t use the Delay object, use window.timeout with a callback instead');
+ this.delTimer();
+ var _this = this;
+ this.timer = timer.add(function () { _this.exec.call(_this); },
+ this.timeout);
+
+ this._data = {
+ _this: arguments[0],
+ _params: Array.prototype.slice.call(arguments, 2)
+ };
+ },
+
+ exec: function () {
+ this.delTimer();
+ this.func.call(this._data._this, this._data._params);
+ }
+};
diff --git a/platform/www/lib/scripts/edit.js b/platform/www/lib/scripts/edit.js
new file mode 100644
index 0000000..f53a6d4
--- /dev/null
+++ b/platform/www/lib/scripts/edit.js
@@ -0,0 +1,307 @@
+/**
+ * Functions for text editing (toolbar stuff)
+ *
+ * @todo most of the stuff in here should be revamped and then moved to toolbar.js
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+/**
+ * Creates a toolbar button through the DOM
+ * Called for each entry of toolbar definition array (built by inc/toolbar.php and extended via js)
+ *
+ * Style the buttons through the toolbutton class
+ *
+ * @param {string} icon image filename, relative to folder lib/images/toolbar/
+ * @param {string} label title of button, show on mouseover
+ * @param {string} key hint in title of button for access key
+ * @param {string} id id of button, and '<id>_ico' of icon
+ * @param {string} classname for styling buttons
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michal Rezler <m.rezler@centrum.cz>
+ */
+function createToolButton(icon,label,key,id,classname){
+ var $btn = jQuery(document.createElement('button')),
+ $ico = jQuery(document.createElement('img'));
+
+ // prepare the basic button stuff
+ $btn.addClass('toolbutton');
+ if(classname){
+ $btn.addClass(classname);
+ }
+
+ $btn.attr('title', label).attr('aria-controls', 'wiki__text');
+ if(key){
+ $btn.attr('title', label + ' ['+key.toUpperCase()+']')
+ .attr('accessKey', key);
+ }
+
+ // set IDs if given
+ if(id){
+ $btn.attr('id', id);
+ $ico.attr('id', id+'_ico');
+ }
+
+ // create the icon and add it to the button
+ if(icon.substr(0,1) !== '/'){
+ icon = DOKU_BASE + 'lib/images/toolbar/' + icon;
+ }
+ $ico.attr('src', icon);
+ $ico.attr('alt', '');
+ $ico.attr('width', 16);
+ $ico.attr('height', 16);
+ $btn.append($ico);
+
+ // we have to return a DOM object (for compatibility reasons)
+ return $btn[0];
+}
+
+/**
+ * Creates a picker window for inserting text
+ *
+ * The given list can be an associative array with text,icon pairs
+ * or a simple list of text. Style the picker window through the picker
+ * class or the picker buttons with the pickerbutton class. Picker
+ * windows are appended to the body and created invisible.
+ *
+ * @param {string} id the ID to assign to the picker
+ * @param {Array} props the properties for the picker
+ * @param {string} edid the ID of the textarea
+ * @return DOMobject the created picker
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function createPicker(id,props,edid){
+ // create the wrapping div
+ var $picker = jQuery(document.createElement('div'));
+
+ $picker.addClass('picker a11y');
+ if(props['class']){
+ $picker.addClass(props['class']);
+ }
+
+ $picker.attr('id', id).css('position', 'absolute');
+
+ function $makebutton(title) {
+ var $btn = jQuery(document.createElement('button'))
+ .addClass('pickerbutton').attr('title', title)
+ .attr('aria-controls', edid)
+ .on('click', bind(pickerInsert, title, edid))
+ .appendTo($picker);
+ return $btn;
+ }
+
+ jQuery.each(props.list, function (key, item) {
+ if (!props.list.hasOwnProperty(key)) {
+ return;
+ }
+
+ if(isNaN(key)){
+ // associative array -> treat as text => image pairs
+ if (item.substr(0,1) !== '/') {
+ item = DOKU_BASE+'lib/images/'+props.icobase+'/'+item;
+ }
+ jQuery(document.createElement('img'))
+ .attr('src', item)
+ .attr('alt', '')
+ .appendTo($makebutton(key));
+ }else if (typeof item == 'string'){
+ // a list of text -> treat as text picker
+ $makebutton(item).text(item);
+ }else{
+ // a list of lists -> treat it as subtoolbar
+ initToolbar($picker,edid,props.list);
+ return false; // all buttons handled already
+ }
+
+ });
+ jQuery('body').append($picker);
+
+ // we have to return a DOM object (for compatibility reasons)
+ return $picker[0];
+}
+
+/**
+ * Called by picker buttons to insert Text and close the picker again
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function pickerInsert(text,edid){
+ insertAtCarret(edid,text);
+ pickerClose();
+}
+
+/**
+ * Add button action for signature button
+ *
+ * @param {jQuery} $btn Button element to add the action to
+ * @param {Array} props Associative array of button properties
+ * @param {string} edid ID of the editor textarea
+ * @return {string} picker id for aria-controls attribute
+ * @author Gabriel Birke <birke@d-scribe.de>
+ */
+function addBtnActionSignature($btn, props, edid) {
+ if(typeof SIG != 'undefined' && SIG != ''){
+ $btn.on('click', function (e) {
+ insertAtCarret(edid,SIG);
+ e.preventDefault();
+ });
+ return edid;
+ }
+ return '';
+}
+
+/**
+ * Determine the current section level while editing
+ *
+ * @param {string} textboxId ID of the text field
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+function currentHeadlineLevel(textboxId){
+ var field = jQuery('#' + textboxId)[0],
+ s = false,
+ opts = [field.value.substr(0,DWgetSelection(field).start)];
+ if (field.form && field.form.prefix) {
+ // we need to look in prefix context
+ opts.push(field.form.prefix.value);
+ }
+
+ jQuery.each(opts, function (_, opt) {
+ // Check whether there is a headline in the given string
+ var str = "\n" + opt,
+ lasthl = str.lastIndexOf("\n==");
+ if (lasthl !== -1) {
+ s = str.substr(lasthl+1,6);
+ return false;
+ }
+ });
+ if (s === false) {
+ return 0;
+ }
+ return 7 - s.match(/^={2,6}/)[0].length;
+}
+
+
+/**
+ * global var used for not saved yet warning
+ */
+window.textChanged = false;
+
+/**
+ * global var which stores original editor content
+ */
+window.doku_edit_text_content = '';
+/**
+ * Delete the draft before leaving the page
+ */
+function deleteDraft() {
+ if (is_opera || window.keepDraft) {
+ return;
+ }
+
+ var $dwform = jQuery('#dw__editform');
+
+ if($dwform.length === 0) {
+ return;
+ }
+
+ // remove a possibly saved draft using ajax
+ jQuery.post(DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'draftdel',
+ id: $dwform.find('input[name=id]').val()
+ }
+ );
+}
+
+/**
+ * Activate "not saved" dialog, add draft deletion to page unload,
+ * add handlers to monitor changes
+ * Note: textChanged could be set by e.g. html_edit() as well
+ *
+ * Sets focus to the editbox as well
+ */
+jQuery(function () {
+ var $editform = jQuery('#dw__editform');
+ if ($editform.length == 0) {
+ return;
+ }
+
+ var $edit_text = jQuery('#wiki__text');
+ if ($edit_text.length > 0) {
+ if($edit_text.attr('readOnly')) {
+ return;
+ }
+
+ // set focus and place cursor at the start
+ var sel = DWgetSelection($edit_text[0]);
+ sel.start = 0;
+ sel.end = 0;
+ DWsetSelection(sel);
+ $edit_text.trigger('focus');
+
+ doku_edit_text_content = $edit_text.val();
+ }
+
+ var changeHandler = function() {
+ doku_hasTextBeenModified();
+
+ doku_summaryCheck();
+ };
+
+ $editform.change(changeHandler);
+ $editform.keydown(changeHandler);
+
+ window.onbeforeunload = function(){
+ if(window.textChanged) {
+ return LANG.notsavedyet;
+ }
+ };
+ window.onunload = deleteDraft;
+
+ // reset change memory var on submit
+ jQuery('#edbtn__save').on('click',
+ function() {
+ window.onbeforeunload = '';
+ textChanged = false;
+ }
+ );
+ jQuery('#edbtn__preview').on('click',
+ function() {
+ window.onbeforeunload = '';
+ textChanged = false;
+ window.keepDraft = true; // needed to keep draft on page unload
+ }
+ );
+
+ var $summary = jQuery('#edit__summary');
+ $summary.on('change keyup', doku_summaryCheck);
+
+ if (textChanged) doku_summaryCheck();
+});
+
+/**
+ * Updates textChanged variable if content of the editor has been modified
+ */
+function doku_hasTextBeenModified() {
+ if (!textChanged) {
+ var $edit_text = jQuery('#wiki__text');
+
+ if ($edit_text.length > 0) {
+ textChanged = doku_edit_text_content != $edit_text.val();
+ } else {
+ textChanged = true;
+ }
+ }
+}
+
+/**
+ * Checks if a summary was entered - if not the style is changed
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function doku_summaryCheck(){
+ var $sum = jQuery('#edit__summary'),
+ missing = $sum.val() === '';
+ $sum.toggleClass('missing', missing).toggleClass('edit', !missing);
+}
diff --git a/platform/www/lib/scripts/editor.js b/platform/www/lib/scripts/editor.js
new file mode 100644
index 0000000..0df5561
--- /dev/null
+++ b/platform/www/lib/scripts/editor.js
@@ -0,0 +1,205 @@
+/**
+ * The DokuWiki editor features
+ *
+ * These are the advanced features of the editor. It does NOT contain any
+ * code for the toolbar buttons and it functions. See toolbar.js for that.
+ */
+
+var dw_editor = {
+
+ /**
+ * initialize the default editor functionality
+ *
+ * All other functions can also be called separately for non-default
+ * textareas
+ */
+ init: function(){
+ var $editor = jQuery('#wiki__text');
+ if($editor.length === 0) {
+ return;
+ }
+
+ dw_editor.initSizeCtl('#size__ctl',$editor);
+
+ if($editor.attr('readOnly')) {
+ return;
+ }
+
+ $editor.keydown(dw_editor.keyHandler);
+
+ },
+
+ /**
+ * Add the edit window size and wrap controls
+ *
+ * Initial values are read from cookie if it exists
+ *
+ * @param selector ctlarea the div to place the controls
+ * @param selector editor the textarea to control
+ */
+ initSizeCtl: function(ctlarea,editor){
+ var $ctl = jQuery(ctlarea),
+ $textarea = jQuery(editor);
+
+ if($ctl.length === 0 || $textarea.length === 0) {
+ return;
+ }
+
+ $textarea.css('height', DokuCookie.getValue('sizeCtl') || '300px');
+
+ var wrp = DokuCookie.getValue('wrapCtl');
+ if(wrp){
+ dw_editor.setWrap($textarea[0], wrp);
+ } // else use default value
+
+ jQuery.each([
+ ['larger', function(){dw_editor.sizeCtl(editor,100);}],
+ ['smaller', function(){dw_editor.sizeCtl(editor,-100);}],
+ ['wrap', function(){dw_editor.toggleWrap(editor);}]
+ ], function (_, img) {
+ jQuery(document.createElement('img'))
+ .attr('src', DOKU_BASE+'lib/images/' + img[0] + '.gif')
+ .attr('alt', '')
+ .on('click', img[1])
+ .appendTo($ctl);
+ });
+ },
+
+ /**
+ * This sets the vertical size of the editbox and adjusts the cookie
+ *
+ * @param selector editor the textarea to control
+ * @param int val the relative value to resize in pixel
+ */
+ sizeCtl: function(editor,val){
+ var $textarea = jQuery(editor),
+ height = parseInt($textarea.css('height')) + val;
+ $textarea.css('height', height+'px');
+ DokuCookie.setValue('sizeCtl',$textarea.css('height'));
+ },
+
+ /**
+ * Toggle the wrapping mode of the editor textarea and adjusts the
+ * cookie
+ *
+ * @param selector editor the textarea to control
+ */
+ toggleWrap: function(editor){
+ var $textarea = jQuery(editor),
+ wrap = $textarea.attr('wrap');
+ dw_editor.setWrap($textarea[0],
+ (wrap && wrap.toLowerCase() == 'off') ? 'soft' : 'off');
+ DokuCookie.setValue('wrapCtl',$textarea.attr('wrap'));
+ },
+
+ /**
+ * Set the wrapping mode of a textarea
+ *
+ * @author Fluffy Convict <fluffyconvict@hotmail.com>
+ * @author <shutdown@flashmail.com>
+ * @link http://news.hping.org/comp.lang.javascript.archive/12265.html
+ * @link https://bugzilla.mozilla.org/show_bug.cgi?id=41464
+ * @param DomObject textarea
+ * @param string wrapAttrValue
+ */
+ setWrap: function(textarea, wrapAttrValue){
+ textarea.setAttribute('wrap', wrapAttrValue);
+
+ // Fix display for mozilla
+ var parNod = textarea.parentNode;
+ var nxtSib = textarea.nextSibling;
+ parNod.removeChild(textarea);
+ parNod.insertBefore(textarea, nxtSib);
+ },
+
+ /**
+ * Make intended formattings easier to handle
+ *
+ * Listens to all key inputs and handle indentions
+ * of lists and code blocks
+ *
+ * Currently handles space, backspace, enter and
+ * ctrl-enter presses
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @fixme handle tabs
+ * @param event e - the key press event object
+ */
+ keyHandler: function(e){
+ if(jQuery.inArray(e.keyCode,[8, 10, 13, 32]) === -1) {
+ return;
+ }
+ var selection = DWgetSelection(this);
+ if(selection.getLength() > 0) {
+ return; //there was text selected, keep standard behavior
+ }
+ var search = "\n"+this.value.substr(0,selection.start);
+ var linestart = Math.max(search.lastIndexOf("\n"),
+ search.lastIndexOf("\r")); //IE workaround
+ search = search.substr(linestart);
+
+ if((e.keyCode == 13 || e.keyCode == 10) && e.ctrlKey) { // Ctrl-Enter (With Chrome workaround)
+ // Submit current edit
+ jQuery('#edbtn__save').trigger('click');
+ e.preventDefault(); // prevent enter key
+ return false;
+ }else if(e.keyCode == 13){ // Enter
+ // keep current indention for lists and code
+ var match = search.match(/(\n +([\*-] ?)?)/);
+ if(match){
+ var scroll = this.scrollHeight;
+ var match2 = search.match(/^\n +[\*-]\s*$/);
+ // Cancel list if the last item is empty (i. e. two times enter)
+ if (match2 && this.value.substr(selection.start).match(/^($|\r?\n)/)) {
+ this.value = this.value.substr(0, linestart) + "\n" +
+ this.value.substr(selection.start);
+ selection.start = linestart + 1;
+ selection.end = linestart + 1;
+ DWsetSelection(selection);
+ } else {
+ insertAtCarret(this.id,match[1]);
+ }
+ this.scrollTop += (this.scrollHeight - scroll);
+ e.preventDefault(); // prevent enter key
+ return false;
+ }
+ }else if(e.keyCode == 8){ // Backspace
+ // unindent lists
+ var match = search.match(/(\n +)([*-] ?)$/);
+ if(match){
+ var spaces = match[1].length-1;
+
+ if(spaces > 3){ // unindent one level
+ this.value = this.value.substr(0,linestart)+
+ this.value.substr(linestart+2);
+ selection.start = selection.start - 2;
+ selection.end = selection.start;
+ }else{ // delete list point
+ this.value = this.value.substr(0,linestart)+
+ this.value.substr(selection.start);
+ selection.start = linestart;
+ selection.end = linestart;
+ }
+ DWsetSelection(selection);
+ e.preventDefault(); // prevent backspace
+ return false;
+ }
+ }else if(e.keyCode == 32){ // Space
+ // intend list item
+ var match = search.match(/(\n +)([*-] )$/);
+ if(match){
+ this.value = this.value.substr(0,linestart)+' '+
+ this.value.substr(linestart);
+ selection.start = selection.start + 2;
+ selection.end = selection.start;
+ DWsetSelection(selection);
+ e.preventDefault(); // prevent space
+ return false;
+ }
+ }
+ }
+
+
+};
+
+jQuery(dw_editor.init);
diff --git a/platform/www/lib/scripts/fileuploader.js b/platform/www/lib/scripts/fileuploader.js
new file mode 100644
index 0000000..d627895
--- /dev/null
+++ b/platform/www/lib/scripts/fileuploader.js
@@ -0,0 +1,1249 @@
+/**
+ * http://github.com/valums/file-uploader
+ *
+ * Multiple file upload component with progress-bar, drag-and-drop.
+ * © 2010 Andrew Valums ( andrew(at)valums.com )
+ *
+ * Licensed under GNU GPL 2 or later and GNU LGPL 2 or later, see license.txt.
+ */
+
+//
+// Helper functions
+//
+
+var qq = qq || {};
+
+/**
+ * Adds all missing properties from second obj to first obj
+ */
+qq.extend = function(first, second){
+ for (var prop in second){
+ first[prop] = second[prop];
+ }
+};
+
+/**
+ * Searches for a given element in the array, returns -1 if it is not present.
+ * @param {Number} [from] The index at which to begin the search
+ */
+qq.indexOf = function(arr, elt, from){
+ if (arr.indexOf) return arr.indexOf(elt, from);
+
+ from = from || 0;
+ var len = arr.length;
+
+ if (from < 0) from += len;
+
+ for (; from < len; from++){
+ if (from in arr && arr[from] === elt){
+ return from;
+ }
+ }
+ return -1;
+};
+
+qq.getUniqueId = (function(){
+ var id = 0;
+ return function(){ return id++; };
+})();
+
+//
+// Events
+
+qq.attach = function(element, type, fn){
+ if (element.addEventListener){
+ element.addEventListener(type, fn, false);
+ } else if (element.attachEvent){
+ element.attachEvent('on' + type, fn);
+ }
+};
+qq.detach = function(element, type, fn){
+ if (element.removeEventListener){
+ element.removeEventListener(type, fn, false);
+ } else if (element.attachEvent){
+ element.detachEvent('on' + type, fn);
+ }
+};
+
+qq.preventDefault = function(e){
+ if (e.preventDefault){
+ e.preventDefault();
+ } else{
+ e.returnValue = false;
+ }
+};
+
+//
+// Node manipulations
+
+/**
+ * Insert node a before node b.
+ */
+qq.insertBefore = function(a, b){
+ b.parentNode.insertBefore(a, b);
+};
+qq.remove = function(element){
+ element.parentNode.removeChild(element);
+};
+
+qq.contains = function(parent, descendant){
+ // compareposition returns false in this case
+ if (parent == descendant) return true;
+
+ if (parent.contains){
+ return parent.contains(descendant);
+ } else {
+ return !!(descendant.compareDocumentPosition(parent) & 8);
+ }
+};
+
+/**
+ * Creates and returns element from html string
+ * Uses innerHTML to create an element
+ */
+qq.toElement = (function(){
+ var div = document.createElement('div');
+ return function(html){
+ div.innerHTML = html;
+ var element = div.firstChild;
+ div.removeChild(element);
+ return element;
+ };
+})();
+
+//
+// Node properties and attributes
+
+/**
+ * Sets styles for an element.
+ * Fixes opacity in IE6-8.
+ */
+qq.css = function(element, styles){
+ if (styles.opacity != null){
+ if (typeof element.style.opacity != 'string' && typeof(element.filters) != 'undefined'){
+ styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')';
+ }
+ }
+ qq.extend(element.style, styles);
+};
+qq.hasClass = function(element, name){
+ var re = new RegExp('(^| )' + name + '( |$)');
+ return re.test(element.className);
+};
+qq.addClass = function(element, name){
+ if (!qq.hasClass(element, name)){
+ element.className += ' ' + name;
+ }
+};
+qq.removeClass = function(element, name){
+ var re = new RegExp('(^| )' + name + '( |$)');
+ element.className = element.className.replace(re, ' ').replace(/^\s+|\s+$/g, "");
+};
+qq.setText = function(element, text){
+ element.innerText = text;
+ element.textContent = text;
+};
+
+//
+// Selecting elements
+
+qq.children = function(element){
+ var children = [],
+ child = element.firstChild;
+
+ while (child){
+ if (child.nodeType == 1){
+ children.push(child);
+ }
+ child = child.nextSibling;
+ }
+
+ return children;
+};
+
+qq.getByClass = function(element, className){
+ if (element.querySelectorAll){
+ return element.querySelectorAll('.' + className);
+ }
+
+ var result = [];
+ var candidates = element.getElementsByTagName("*");
+ var len = candidates.length;
+
+ for (var i = 0; i < len; i++){
+ if (qq.hasClass(candidates[i], className)){
+ result.push(candidates[i]);
+ }
+ }
+ return result;
+};
+
+/**
+ * obj2url() takes a json-object as argument and generates
+ * a querystring. pretty much like jQuery.param()
+ *
+ * how to use:
+ *
+ * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`
+ *
+ * will result in:
+ *
+ * `http://any.url/upload?otherParam=value&a=b&c=d`
+ *
+ * @param Object JSON-Object
+ * @param String current querystring-part
+ * @return String encoded querystring
+ */
+qq.obj2url = function(obj, temp, prefixDone){
+ var uristrings = [],
+ prefix = '&',
+ add = function(nextObj, i){
+ var nextTemp = temp
+ ? (/\[\]$/.test(temp)) // prevent double-encoding
+ ? temp
+ : temp+'['+i+']'
+ : i;
+ if ((nextTemp != 'undefined') && (i != 'undefined')) {
+ uristrings.push(
+ (typeof nextObj === 'object')
+ ? qq.obj2url(nextObj, nextTemp, true)
+ : (Object.prototype.toString.call(nextObj) === '[object Function]')
+ ? encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj())
+ : encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj)
+ );
+ }
+ };
+
+ if (!prefixDone && temp) {
+ prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?';
+ uristrings.push(temp);
+ uristrings.push(qq.obj2url(obj));
+ } else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj != 'undefined') ) {
+ // we wont use a for-in-loop on an array (performance)
+ for (var i = 0, len = obj.length; i < len; ++i){
+ add(obj[i], i);
+ }
+ } else if ((typeof obj != 'undefined') && (obj !== null) && (typeof obj === "object")){
+ // for anything else but a scalar, we will use for-in-loop
+ for (var i in obj){
+ if(obj.hasOwnProperty(i) && typeof obj[i] != 'function') {
+ add(obj[i], i);
+ }
+ }
+ } else {
+ uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj));
+ }
+
+ return uristrings.join(prefix)
+ .replace(/^&/, '')
+ .replace(/%20/g, '+');
+};
+
+//
+//
+// Uploader Classes
+//
+//
+
+var qq = qq || {};
+
+/**
+ * Creates upload button, validates upload, but doesn't create file list or dd.
+ */
+qq.FileUploaderBasic = function(o){
+ this._options = {
+ // set to true to see the server response
+ debug: false,
+ action: '/server/upload',
+ params: {},
+ button: null,
+ multiple: true,
+ maxConnections: 3,
+ // validation
+ allowedExtensions: [],
+ sizeLimit: 0,
+ minSizeLimit: 0,
+ // events
+ // return false to cancel submit
+ onSubmit: function(id, fileName){},
+ onProgress: function(id, fileName, loaded, total){},
+ onComplete: function(id, fileName, responseJSON){},
+ onCancel: function(id, fileName){},
+ // messages
+ messages: {
+ typeError: "{file} has invalid extension. Only {extensions} are allowed.",
+ sizeError: "{file} is too large, maximum file size is {sizeLimit}.",
+ minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
+ emptyError: "{file} is empty, please select files again without it.",
+ onLeave: "The files are being uploaded, if you leave now the upload will be cancelled."
+ },
+ showMessage: function(message){
+ alert(message);
+ }
+ };
+ qq.extend(this._options, o);
+
+ // number of files being uploaded
+ this._filesInProgress = 0;
+ this._handler = this._createUploadHandler();
+
+ if (this._options.button){
+ this._button = this._createUploadButton(this._options.button);
+ }
+
+ this._preventLeaveInProgress();
+};
+
+qq.FileUploaderBasic.prototype = {
+ setParams: function(params){
+ this._options.params = params;
+ },
+ getInProgress: function(){
+ return this._filesInProgress;
+ },
+ _createUploadButton: function(element){
+ var self = this;
+
+ return new qq.UploadButton({
+ element: element,
+ multiple: this._options.multiple && qq.UploadHandlerXhr.isSupported(),
+ onChange: function(input){
+ self._onInputChange(input);
+ }
+ });
+ },
+ _createUploadHandler: function(){
+ var self = this,
+ handlerClass;
+
+ if(qq.UploadHandlerXhr.isSupported()){
+ handlerClass = 'UploadHandlerXhr';
+ } else {
+ handlerClass = 'UploadHandlerForm';
+ }
+
+ var handler = new qq[handlerClass]({
+ debug: this._options.debug,
+ action: this._options.action,
+ maxConnections: this._options.maxConnections,
+ onProgress: function(id, fileName, loaded, total){
+ self._onProgress(id, fileName, loaded, total);
+ self._options.onProgress(id, fileName, loaded, total);
+ },
+ onComplete: function(id, fileName, result){
+ self._onComplete(id, fileName, result);
+ self._options.onComplete(id, fileName, result);
+ },
+ onCancel: function(id, fileName){
+ self._onCancel(id, fileName);
+ self._options.onCancel(id, fileName);
+ }
+ });
+
+ return handler;
+ },
+ _preventLeaveInProgress: function(){
+ var self = this;
+
+ qq.attach(window, 'beforeunload', function(e){
+ if (!self._filesInProgress){return;}
+
+ var e = e || window.event;
+ // for ie, ff
+ e.returnValue = self._options.messages.onLeave;
+ // for webkit
+ return self._options.messages.onLeave;
+ });
+ },
+ _onSubmit: function(id, fileName){
+ this._filesInProgress++;
+ },
+ _onProgress: function(id, fileName, loaded, total){
+ },
+ _onComplete: function(id, fileName, result){
+ this._filesInProgress--;
+ if (result.error){
+ this._options.showMessage(result.error);
+ }
+ },
+ _onCancel: function(id, fileName){
+ this._filesInProgress--;
+ },
+ _onInputChange: function(input){
+ if (this._handler instanceof qq.UploadHandlerXhr){
+ this._uploadFileList(input.files);
+ } else {
+ if (this._validateFile(input)){
+ this._uploadFile(input);
+ }
+ }
+ this._button.reset();
+ },
+ _uploadFileList: function(files){
+ for (var i=0; i<files.length; i++){
+ if ( !this._validateFile(files[i])){
+ return;
+ }
+ }
+
+ for (var i=0; i<files.length; i++){
+ this._uploadFile(files[i]);
+ }
+ },
+ _uploadFile: function(fileContainer){
+ var id = this._handler.add(fileContainer);
+ var fileName = this._handler.getName(id);
+
+ if (this._options.onSubmit(id, fileName) !== false){
+ this._onSubmit(id, fileName);
+ this._handler.upload(id, this._options.params);
+ }
+ },
+ _validateFile: function(file){
+ var name, size;
+
+ if (file.value){
+ // it is a file input
+ // get input value and remove path to normalize
+ name = file.value.replace(/.*(\/|\\)/, "");
+ } else {
+ // fix missing properties in Safari
+ name = file.fileName != null ? file.fileName : file.name;
+ size = file.fileSize != null ? file.fileSize : file.size;
+ }
+
+ if (! this._isAllowedExtension(name)){
+ this._error('typeError', name);
+ return false;
+
+ } else if (size === 0){
+ this._error('emptyError', name);
+ return false;
+
+ } else if (size && this._options.sizeLimit && size > this._options.sizeLimit){
+ this._error('sizeError', name);
+ return false;
+
+ } else if (size && size < this._options.minSizeLimit){
+ this._error('minSizeError', name);
+ return false;
+ }
+
+ return true;
+ },
+ _error: function(code, fileName){
+ var message = this._options.messages[code];
+ function r(name, replacement){ message = message.replace(name, replacement); }
+
+ r('{file}', this._formatFileName(fileName));
+ r('{extensions}', this._options.allowedExtensions.join(', '));
+ r('{sizeLimit}', this._formatSize(this._options.sizeLimit));
+ r('{minSizeLimit}', this._formatSize(this._options.minSizeLimit));
+
+ this._options.showMessage(message);
+ },
+ _formatFileName: function(name){
+ if (name.length > 33){
+ name = name.slice(0, 19) + '...' + name.slice(-13);
+ }
+ return name;
+ },
+ _isAllowedExtension: function(fileName){
+ var ext = (-1 !== fileName.indexOf('.')) ? fileName.replace(/.*[.]/, '').toLowerCase() : '';
+ var allowed = this._options.allowedExtensions;
+
+ if (!allowed.length){return true;}
+
+ for (var i=0; i<allowed.length; i++){
+ if (allowed[i].toLowerCase() == ext){ return true;}
+ }
+
+ return false;
+ },
+ _formatSize: function(bytes){
+ var i = -1;
+ do {
+ bytes = bytes / 1024;
+ i++;
+ } while (bytes > 99);
+
+ return Math.max(bytes, 0.1).toFixed(1) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
+ }
+};
+
+
+/**
+ * Class that creates upload widget with drag-and-drop and file list
+ * @inherits qq.FileUploaderBasic
+ */
+qq.FileUploader = function(o){
+ // call parent constructor
+ qq.FileUploaderBasic.apply(this, arguments);
+
+ // additional options
+ qq.extend(this._options, {
+ element: null,
+ // if set, will be used instead of qq-upload-list in template
+ listElement: null,
+
+ template: '<div class="qq-uploader">' +
+ '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
+ '<div class="qq-upload-button">Upload a file</div>' +
+ '<ul class="qq-upload-list"></ul>' +
+ '</div>',
+
+ // template for one item in file list
+ fileTemplate: '<li>' +
+ '<span class="qq-upload-file"></span>' +
+ '<span class="qq-upload-spinner"></span>' +
+ '<span class="qq-upload-size"></span>' +
+ '<a class="qq-upload-cancel" href="#">Cancel</a>' +
+ '<span class="qq-upload-failed-text">Failed</span>' +
+ '</li>',
+
+ classes: {
+ // used to get elements from templates
+ button: 'qq-upload-button',
+ drop: 'qq-upload-drop-area',
+ dropActive: 'qq-upload-drop-area-active',
+ list: 'qq-upload-list',
+
+ file: 'qq-upload-file',
+ spinner: 'qq-upload-spinner',
+ size: 'qq-upload-size',
+ cancel: 'qq-upload-cancel',
+
+ // added to list item when upload completes
+ // used in css to hide progress spinner
+ success: 'qq-upload-success',
+ fail: 'qq-upload-fail'
+ }
+ });
+ // overwrite options with user supplied
+ qq.extend(this._options, o);
+
+ this._element = this._options.element;
+ this._element.innerHTML = this._options.template;
+ this._listElement = this._options.listElement || this._find(this._element, 'list');
+
+ this._classes = this._options.classes;
+
+ this._button = this._createUploadButton(this._find(this._element, 'button'));
+
+ this._bindCancelEvent();
+ this._setupDragDrop();
+};
+
+// inherit from Basic Uploader
+qq.extend(qq.FileUploader.prototype, qq.FileUploaderBasic.prototype);
+
+qq.extend(qq.FileUploader.prototype, {
+ /**
+ * Gets one of the elements listed in this._options.classes
+ **/
+ _find: function(parent, type){
+ var element = qq.getByClass(parent, this._options.classes[type])[0];
+ if (!element){
+ throw new Error('element not found ' + type);
+ }
+
+ return element;
+ },
+ _setupDragDrop: function(){
+ var self = this,
+ dropArea = this._find(this._element, 'drop');
+
+ var dz = new qq.UploadDropZone({
+ element: dropArea,
+ onEnter: function(e){
+ qq.addClass(dropArea, self._classes.dropActive);
+ e.stopPropagation();
+ },
+ onLeave: function(e){
+ e.stopPropagation();
+ },
+ onLeaveNotDescendants: function(e){
+ qq.removeClass(dropArea, self._classes.dropActive);
+ },
+ onDrop: function(e){
+ dropArea.style.display = 'none';
+ qq.removeClass(dropArea, self._classes.dropActive);
+ self._uploadFileList(e.dataTransfer.files);
+ }
+ });
+
+ dropArea.style.display = 'none';
+
+ qq.attach(document, 'dragenter', function(e){
+ if (!dz._isValidFileDrag(e)) return;
+
+ dropArea.style.display = 'block';
+ });
+ qq.attach(document, 'dragleave', function(e){
+ if (!dz._isValidFileDrag(e)) return;
+
+ var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
+ // only fire when leaving document out
+ if ( ! relatedTarget || relatedTarget.nodeName == "HTML"){
+ dropArea.style.display = 'none';
+ }
+ });
+ },
+ _onSubmit: function(id, fileName){
+ qq.FileUploaderBasic.prototype._onSubmit.apply(this, arguments);
+ this._addToList(id, fileName);
+ },
+ _onProgress: function(id, fileName, loaded, total){
+ qq.FileUploaderBasic.prototype._onProgress.apply(this, arguments);
+
+ var item = this._getItemByFileId(id);
+ var size = this._find(item, 'size');
+ size.style.display = 'inline';
+
+ var text;
+ if (loaded != total){
+ text = Math.round(loaded / total * 100) + '% from ' + this._formatSize(total);
+ } else {
+ text = this._formatSize(total);
+ }
+
+ qq.setText(size, text);
+ },
+ _onComplete: function(id, fileName, result){
+ qq.FileUploaderBasic.prototype._onComplete.apply(this, arguments);
+
+ // mark completed
+ var item = this._getItemByFileId(id);
+ qq.remove(this._find(item, 'cancel'));
+ qq.remove(this._find(item, 'spinner'));
+
+ if (result.success){
+ qq.addClass(item, this._classes.success);
+ } else {
+ qq.addClass(item, this._classes.fail);
+ }
+ },
+ _addToList: function(id, fileName){
+ var item = qq.toElement(this._options.fileTemplate);
+ item.qqFileId = id;
+
+ var fileElement = this._find(item, 'file');
+ qq.setText(fileElement, this._formatFileName(fileName));
+ this._find(item, 'size').style.display = 'none';
+
+ this._listElement.appendChild(item);
+ },
+ _getItemByFileId: function(id){
+ var item = this._listElement.firstChild;
+
+ // there can't be txt nodes in dynamically created list
+ // and we can use nextSibling
+ while (item){
+ if (item.qqFileId == id) return item;
+ item = item.nextSibling;
+ }
+ },
+ /**
+ * delegate click event for cancel link
+ **/
+ _bindCancelEvent: function(){
+ var self = this,
+ list = this._listElement;
+
+ qq.attach(list, 'click', function(e){
+ e = e || window.event;
+ var target = e.target || e.srcElement;
+
+ if (qq.hasClass(target, self._classes.cancel)){
+ qq.preventDefault(e);
+
+ var item = target.parentNode;
+ self._handler.cancel(item.qqFileId);
+ qq.remove(item);
+ }
+ });
+ }
+});
+
+qq.UploadDropZone = function(o){
+ this._options = {
+ element: null,
+ onEnter: function(e){},
+ onLeave: function(e){},
+ // is not fired when leaving element by hovering descendants
+ onLeaveNotDescendants: function(e){},
+ onDrop: function(e){}
+ };
+ qq.extend(this._options, o);
+
+ this._element = this._options.element;
+
+ this._disableDropOutside();
+ this._attachEvents();
+};
+
+qq.UploadDropZone.prototype = {
+ _disableDropOutside: function(e){
+ // run only once for all instances
+ if (!qq.UploadDropZone.dropOutsideDisabled ){
+
+ qq.attach(document, 'dragover', function(e){
+ if (e.dataTransfer){
+ e.dataTransfer.dropEffect = 'none';
+ e.preventDefault();
+ }
+ });
+
+ qq.UploadDropZone.dropOutsideDisabled = true;
+ }
+ },
+ _attachEvents: function(){
+ var self = this;
+
+ qq.attach(self._element, 'dragover', function(e){
+ if (!self._isValidFileDrag(e)) return;
+
+ var effect = e.dataTransfer.effectAllowed;
+ if (effect == 'move' || effect == 'linkMove'){
+ e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)
+ } else {
+ e.dataTransfer.dropEffect = 'copy'; // for Chrome
+ }
+
+ e.stopPropagation();
+ e.preventDefault();
+ });
+
+ qq.attach(self._element, 'dragenter', function(e){
+ if (!self._isValidFileDrag(e)) return;
+
+ self._options.onEnter(e);
+ });
+
+ qq.attach(self._element, 'dragleave', function(e){
+ if (!self._isValidFileDrag(e)) return;
+
+ self._options.onLeave(e);
+
+ var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
+ // do not fire when moving a mouse over a descendant
+ if (qq.contains(this, relatedTarget)) return;
+
+ self._options.onLeaveNotDescendants(e);
+ });
+
+ qq.attach(self._element, 'drop', function(e){
+ if (!self._isValidFileDrag(e)) return;
+
+ e.preventDefault();
+ self._options.onDrop(e);
+ });
+ },
+ _isValidFileDrag: function(e){
+ var dt = e.dataTransfer,
+ // do not check dt.types.contains in webkit, because it crashes safari 4
+ isWebkit = navigator.userAgent.indexOf("AppleWebKit") > -1;
+
+ // dt.effectAllowed is none in Safari 5
+ // dt.types.contains check is for firefox
+ return dt && dt.effectAllowed != 'none' &&
+ (dt.files || (!isWebkit && dt.types.contains && dt.types.contains('Files')));
+
+ }
+};
+
+qq.UploadButton = function(o){
+ this._options = {
+ element: null,
+ // if set to true adds multiple attribute to file input
+ multiple: false,
+ // name attribute of file input
+ name: 'file',
+ onChange: function(input){},
+ hoverClass: 'qq-upload-button-hover',
+ focusClass: 'qq-upload-button-focus'
+ };
+
+ qq.extend(this._options, o);
+
+ this._element = this._options.element;
+
+ // make button suitable container for input
+ qq.css(this._element, {
+ position: 'relative',
+ overflow: 'hidden',
+ // Make sure browse button is in the right side
+ // in Internet Explorer
+ direction: 'ltr'
+ });
+
+ this._input = this._createInput();
+};
+
+qq.UploadButton.prototype = {
+ /* returns file input element */
+ getInput: function(){
+ return this._input;
+ },
+ /* cleans/recreates the file input */
+ reset: function(){
+ if (this._input.parentNode){
+ qq.remove(this._input);
+ }
+
+ qq.removeClass(this._element, this._options.focusClass);
+ this._input = this._createInput();
+ },
+ _createInput: function(){
+ var input = document.createElement("input");
+
+ if (this._options.multiple){
+ input.setAttribute("multiple", "multiple");
+ }
+
+ input.setAttribute("type", "file");
+ input.setAttribute("name", this._options.name);
+
+ qq.css(input, {
+ position: 'absolute',
+ // in Opera only 'browse' button
+ // is clickable and it is located at
+ // the right side of the input
+ right: 0,
+ top: 0,
+ fontFamily: 'Arial',
+ // 4 persons reported this, the max values that worked for them were 243, 236, 236, 118
+ fontSize: '118px',
+ margin: 0,
+ padding: 0,
+ cursor: 'pointer',
+ opacity: 0
+ });
+
+ this._element.appendChild(input);
+
+ var self = this;
+ qq.attach(input, 'change', function(){
+ self._options.onChange(input);
+ });
+
+ qq.attach(input, 'mouseover', function(){
+ qq.addClass(self._element, self._options.hoverClass);
+ });
+ qq.attach(input, 'mouseout', function(){
+ qq.removeClass(self._element, self._options.hoverClass);
+ });
+ qq.attach(input, 'focus', function(){
+ qq.addClass(self._element, self._options.focusClass);
+ });
+ qq.attach(input, 'blur', function(){
+ qq.removeClass(self._element, self._options.focusClass);
+ });
+
+ // IE and Opera, unfortunately have 2 tab stops on file input
+ // which is unacceptable in our case, disable keyboard access
+ if (window.attachEvent){
+ // it is IE or Opera
+ input.setAttribute('tabIndex', "-1");
+ }
+
+ return input;
+ }
+};
+
+/**
+ * Class for uploading files, uploading itself is handled by child classes
+ */
+qq.UploadHandlerAbstract = function(o){
+ this._options = {
+ debug: false,
+ action: '/upload.php',
+ // maximum number of concurrent uploads
+ maxConnections: 999,
+ onProgress: function(id, fileName, loaded, total){},
+ onComplete: function(id, fileName, response){},
+ onCancel: function(id, fileName){}
+ };
+ qq.extend(this._options, o);
+
+ this._queue = [];
+ // params for files in queue
+ this._params = [];
+};
+qq.UploadHandlerAbstract.prototype = {
+ log: function(str){
+ if (this._options.debug && window.console) console.log('[uploader] ' + str);
+ },
+ /**
+ * Adds file or file input to the queue
+ * @returns id
+ **/
+ add: function(file){},
+ /**
+ * Sends the file identified by id and additional query params to the server
+ */
+ upload: function(id, params){
+ var len = this._queue.push(id);
+
+ var copy = {};
+ qq.extend(copy, params);
+ this._params[id] = copy;
+
+ // if too many active uploads, wait...
+ if (len <= this._options.maxConnections){
+ this._upload(id, this._params[id]);
+ }
+ },
+ /**
+ * Cancels file upload by id
+ */
+ cancel: function(id){
+ this._cancel(id);
+ this._dequeue(id);
+ },
+ /**
+ * Cancells all uploads
+ */
+ cancelAll: function(){
+ for (var i=0; i<this._queue.length; i++){
+ this._cancel(this._queue[i]);
+ }
+ this._queue = [];
+ },
+ /**
+ * Returns name of the file identified by id
+ */
+ getName: function(id){},
+ /**
+ * Returns size of the file identified by id
+ */
+ getSize: function(id){},
+ /**
+ * Returns id of files being uploaded or
+ * waiting for their turn
+ */
+ getQueue: function(){
+ return this._queue;
+ },
+ /**
+ * Actual upload method
+ */
+ _upload: function(id){},
+ /**
+ * Actual cancel method
+ */
+ _cancel: function(id){},
+ /**
+ * Removes element from queue, starts upload of next
+ */
+ _dequeue: function(id){
+ var i = qq.indexOf(this._queue, id);
+ this._queue.splice(i, 1);
+
+ var max = this._options.maxConnections;
+
+ if (this._queue.length >= max && i < max){
+ var nextId = this._queue[max-1];
+ this._upload(nextId, this._params[nextId]);
+ }
+ }
+};
+
+/**
+ * Class for uploading files using form and iframe
+ * @inherits qq.UploadHandlerAbstract
+ */
+qq.UploadHandlerForm = function(o){
+ qq.UploadHandlerAbstract.apply(this, arguments);
+
+ this._inputs = {};
+};
+// @inherits qq.UploadHandlerAbstract
+qq.extend(qq.UploadHandlerForm.prototype, qq.UploadHandlerAbstract.prototype);
+
+qq.extend(qq.UploadHandlerForm.prototype, {
+ add: function(fileInput){
+ fileInput.setAttribute('name', 'qqfile');
+ var id = 'qq-upload-handler-iframe' + qq.getUniqueId();
+
+ this._inputs[id] = fileInput;
+
+ // remove file input from DOM
+ if (fileInput.parentNode){
+ qq.remove(fileInput);
+ }
+
+ return id;
+ },
+ getName: function(id){
+ // get input value and remove path to normalize
+ return this._inputs[id].value.replace(/.*(\/|\\)/, "");
+ },
+ _cancel: function(id){
+ this._options.onCancel(id, this.getName(id));
+
+ delete this._inputs[id];
+
+ var iframe = document.getElementById(id);
+ if (iframe){
+ // to cancel request set src to something else
+ // we use src="javascript:false;" because it doesn't
+ // trigger ie6 prompt on https
+ iframe.setAttribute('src', 'javascript:false;');
+
+ qq.remove(iframe);
+ }
+ },
+ _upload: function(id, params){
+ var input = this._inputs[id];
+
+ if (!input){
+ throw new Error('file with passed id was not added, or already uploaded or cancelled');
+ }
+
+ var fileName = this.getName(id);
+
+ var iframe = this._createIframe(id);
+ var form = this._createForm(iframe, params);
+ form.appendChild(input);
+
+ var self = this;
+ this._attachLoadEvent(iframe, function(){
+ self.log('iframe loaded');
+
+ var response = self._getIframeContentJSON(iframe);
+
+ self._options.onComplete(id, fileName, response);
+ self._dequeue(id);
+
+ delete self._inputs[id];
+ // timeout added to fix busy state in FF3.6
+ setTimeout(function(){
+ qq.remove(iframe);
+ }, 1);
+ });
+
+ form.submit();
+ qq.remove(form);
+
+ return id;
+ },
+ _attachLoadEvent: function(iframe, callback){
+ qq.attach(iframe, 'load', function(){
+ // when we remove iframe from dom
+ // the request stops, but in IE load
+ // event fires
+ if (!iframe.parentNode){
+ return;
+ }
+
+ // fixing Opera 10.53
+ if (iframe.contentDocument &&
+ iframe.contentDocument.body &&
+ iframe.contentDocument.body.innerHTML == "false"){
+ // In Opera event is fired second time
+ // when body.innerHTML changed from false
+ // to server response approx. after 1 sec
+ // when we upload file with iframe
+ return;
+ }
+
+ callback();
+ });
+ },
+ /**
+ * Returns json object received by iframe from server.
+ */
+ _getIframeContentJSON: function(iframe){
+ // iframe.contentWindow.document - for IE<7
+ var doc = iframe.contentDocument ? iframe.contentDocument: iframe.contentWindow.document,
+ response;
+
+ this.log("converting iframe's innerHTML to JSON");
+ this.log("innerHTML = " + doc.body.innerHTML);
+
+ try {
+ response = eval("(" + doc.body.innerHTML + ")");
+ } catch(err){
+ response = {};
+ }
+
+ return response;
+ },
+ /**
+ * Creates iframe with unique name
+ */
+ _createIframe: function(id){
+ // We can't use following code as the name attribute
+ // won't be properly registered in IE6, and new window
+ // on form submit will open
+ // var iframe = document.createElement('iframe');
+ // iframe.setAttribute('name', id);
+
+ var iframe = qq.toElement('<iframe src="javascript:false;" name="' + id + '" />');
+ // src="javascript:false;" removes ie6 prompt on https
+
+ iframe.setAttribute('id', id);
+
+ iframe.style.display = 'none';
+ document.body.appendChild(iframe);
+
+ return iframe;
+ },
+ /**
+ * Creates form, that will be submitted to iframe
+ */
+ _createForm: function(iframe, params){
+ // We can't use the following code in IE6
+ // var form = document.createElement('form');
+ // form.setAttribute('method', 'post');
+ // form.setAttribute('enctype', 'multipart/form-data');
+ // Because in this case file won't be attached to request
+ var form = qq.toElement('<form method="post" enctype="multipart/form-data"></form>');
+
+ var queryString = qq.obj2url(params, this._options.action);
+
+ form.setAttribute('action', queryString);
+ form.setAttribute('target', iframe.name);
+ form.style.display = 'none';
+ document.body.appendChild(form);
+
+ return form;
+ }
+});
+
+/**
+ * Class for uploading files using xhr
+ * @inherits qq.UploadHandlerAbstract
+ */
+qq.UploadHandlerXhr = function(o){
+ qq.UploadHandlerAbstract.apply(this, arguments);
+
+ this._files = [];
+ this._xhrs = [];
+
+ // current loaded size in bytes for each file
+ this._loaded = [];
+};
+
+// static method
+qq.UploadHandlerXhr.isSupported = function(){
+ var input = document.createElement('input');
+ input.type = 'file';
+
+ return (
+ 'multiple' in input &&
+ typeof File != "undefined" &&
+ typeof (new XMLHttpRequest()).upload != "undefined" );
+};
+
+// @inherits qq.UploadHandlerAbstract
+qq.extend(qq.UploadHandlerXhr.prototype, qq.UploadHandlerAbstract.prototype);
+
+qq.extend(qq.UploadHandlerXhr.prototype, {
+ /**
+ * Adds file to the queue
+ * Returns id to use with upload, cancel
+ **/
+ add: function(file){
+ if (!(file instanceof File)){
+ throw new Error('Passed obj in not a File (in qq.UploadHandlerXhr)');
+ }
+
+ return this._files.push(file) - 1;
+ },
+ getName: function(id){
+ var file = this._files[id];
+ // fix missing name in Safari 4
+ return file.fileName != null ? file.fileName : file.name;
+ },
+ getSize: function(id){
+ var file = this._files[id];
+ return file.fileSize != null ? file.fileSize : file.size;
+ },
+ /**
+ * Returns uploaded bytes for file identified by id
+ */
+ getLoaded: function(id){
+ return this._loaded[id] || 0;
+ },
+ /**
+ * Sends the file identified by id and additional query params to the server
+ * @param {Object} params name-value string pairs
+ */
+ _upload: function(id, params){
+ var file = this._files[id],
+ name = this.getName(id),
+ size = this.getSize(id);
+
+ this._loaded[id] = 0;
+
+ var xhr = this._xhrs[id] = new XMLHttpRequest();
+ var self = this;
+
+ xhr.upload.onprogress = function(e){
+ if (e.lengthComputable){
+ self._loaded[id] = e.loaded;
+ self._options.onProgress(id, name, e.loaded, e.total);
+ }
+ };
+
+ xhr.onreadystatechange = function(){
+ if (xhr.readyState == 4){
+ self._onComplete(id, xhr);
+ }
+ };
+
+ // build query string
+ params = params || {};
+ params['qqfile'] = name;
+ var queryString = qq.obj2url(params, this._options.action);
+
+ xhr.open("POST", queryString, true);
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
+ xhr.setRequestHeader("Content-Type", "application/octet-stream");
+ xhr.send(file);
+ },
+ _onComplete: function(id, xhr){
+ // the request was aborted/cancelled
+ if (!this._files[id]) return;
+
+ var name = this.getName(id);
+ var size = this.getSize(id);
+
+ this._options.onProgress(id, name, size, size);
+
+ if (xhr.status == 200){
+ this.log("xhr - server response received");
+ this.log("responseText = " + xhr.responseText);
+
+ var response;
+
+ try {
+ response = eval("(" + xhr.responseText + ")");
+ } catch(err){
+ response = {};
+ }
+
+ this._options.onComplete(id, name, response);
+
+ } else {
+ this._options.onComplete(id, name, {});
+ }
+
+ this._files[id] = null;
+ this._xhrs[id] = null;
+ this._dequeue(id);
+ },
+ _cancel: function(id){
+ this._options.onCancel(id, this.getName(id));
+
+ this._files[id] = null;
+
+ if (this._xhrs[id]){
+ this._xhrs[id].abort();
+ this._xhrs[id] = null;
+ }
+ }
+}); \ No newline at end of file
diff --git a/platform/www/lib/scripts/fileuploaderextended.js b/platform/www/lib/scripts/fileuploaderextended.js
new file mode 100644
index 0000000..b7f9f5f
--- /dev/null
+++ b/platform/www/lib/scripts/fileuploaderextended.js
@@ -0,0 +1,345 @@
+qq.extend(qq.FileUploader.prototype, {
+ _createUploadHandler: function(){
+ var self = this,
+ handlerClass;
+
+ if(qq.UploadHandlerXhr.isSupported()){
+ handlerClass = 'UploadHandlerXhr';
+ //handlerClass = 'UploadHandlerForm';
+ } else {
+ handlerClass = 'UploadHandlerForm';
+ }
+
+ var handler = new qq[handlerClass]({
+ debug: this._options.debug,
+ action: this._options.action,
+ maxConnections: this._options.maxConnections,
+ onProgress: function(id, fileName, loaded, total){
+ self._onProgress(id, fileName, loaded, total);
+ self._options.onProgress(id, fileName, loaded, total);
+ },
+ onComplete: function(id, fileName, result){
+ self._onComplete(id, fileName, result);
+ self._options.onComplete(id, fileName, result);
+ },
+ onCancel: function(id, fileName){
+ self._onCancel(id, fileName);
+ self._options.onCancel(id, fileName);
+ },
+ onUpload: function(){
+ self._onUpload();
+ }
+ });
+
+ return handler;
+ },
+
+ _onUpload: function(){
+ this._handler.uploadAll(this._options.params);
+ },
+
+ _uploadFile: function(fileContainer){
+ var id = this._handler.add(fileContainer);
+ var fileName = this._handler.getName(id);
+
+ if (this._options.onSubmit(id, fileName) !== false){
+ this._onSubmit(id, fileName);
+ }
+ },
+
+ _addToList: function(id, fileName){
+ var item = qq.toElement(this._options.fileTemplate);
+ item.qqFileId = id;
+
+ var fileElement = this._find(item, 'file');
+ qq.setText(fileElement, fileName);
+ this._find(item, 'size').style.display = 'none';
+
+ // name suggestion (simplified cleanID)
+ var nameElement = this._find(item, 'nameInput');
+ fileName = fileName.toLowerCase();
+ fileName = fileName.replace(/([ !"#$%&\'()+,\/;<=>?@[\]^`{|}~:]+)/g, '_');
+ fileName = fileName.replace(/^_+/,'');
+ nameElement.value = fileName;
+ nameElement.id = 'mediamanager__upload_item'+id;
+
+ this._listElement.appendChild(item);
+ }
+
+});
+
+qq.FileUploaderExtended = function(o){
+ // call parent constructor
+ qq.FileUploaderBasic.apply(this, arguments);
+
+ qq.extend(this._options, {
+ element: null,
+ // if set, will be used instead of qq-upload-list in template
+ listElement: null,
+
+ template: '<div class="qq-uploader">' +
+ '<div class="qq-upload-drop-area"><span>' + LANG.media_drop + '</span></div>' +
+ '<div class="qq-upload-button">' + LANG.media_select + '</div>' +
+ '<ul class="qq-upload-list"></ul>' +
+ '<div class="qq-action-container">' +
+ ' <button class="qq-upload-action" type="submit" id="mediamanager__upload_button">' + LANG.media_upload_btn + '</button>' +
+ ' <label class="qq-overwrite-check"><input type="checkbox" value="1" name="ow" class="dw__ow"> <span>' + LANG.media_overwrt + '</span></label>' +
+ '</div>' +
+ '</div>',
+
+ // template for one item in file list
+ fileTemplate: '<li>' +
+ '<span class="qq-upload-file hidden"></span>' +
+ ' <input class="qq-upload-name-input edit" type="text" value="" />' +
+ ' <span class="qq-upload-spinner hidden"></span>' +
+ ' <span class="qq-upload-size"></span>' +
+ ' <a class="qq-upload-cancel" href="#">' + LANG.media_cancel + '</a>' +
+ ' <span class="qq-upload-failed-text error">Failed</span>' +
+ '</li>',
+
+ classes: {
+ // used to get elements from templates
+ button: 'qq-upload-button',
+ drop: 'qq-upload-drop-area',
+ dropActive: 'qq-upload-drop-area-active',
+ list: 'qq-upload-list',
+ nameInput: 'qq-upload-name-input',
+ overwriteInput: 'qq-overwrite-check',
+ uploadButton: 'qq-upload-action',
+ file: 'qq-upload-file',
+
+ spinner: 'qq-upload-spinner',
+ size: 'qq-upload-size',
+ cancel: 'qq-upload-cancel',
+
+ // added to list item when upload completes
+ // used in css to hide progress spinner
+ success: 'qq-upload-success',
+ fail: 'qq-upload-fail',
+ failedText: 'qq-upload-failed-text'
+ }
+ });
+
+ qq.extend(this._options, o);
+
+ this._element = this._options.element;
+ this._element.innerHTML = this._options.template;
+ this._listElement = this._options.listElement || this._find(this._element, 'list');
+
+ this._classes = this._options.classes;
+
+ this._button = this._createUploadButton(this._find(this._element, 'button'));
+
+ this._bindCancelEvent();
+ this._bindUploadEvent();
+ this._setupDragDrop();
+};
+
+qq.extend(qq.FileUploaderExtended.prototype, qq.FileUploader.prototype);
+
+qq.extend(qq.FileUploaderExtended.prototype, {
+ _bindUploadEvent: function(){
+ var self = this,
+ list = this._listElement;
+
+ qq.attach(document.getElementById('mediamanager__upload_button'), 'click', function(e){
+ e = e || window.event;
+ var target = e.target || e.srcElement;
+ qq.preventDefault(e);
+ self._handler._options.onUpload();
+
+ jQuery(".qq-upload-name-input").each(function (i) {
+ jQuery(this).prop('disabled', true);
+ });
+ });
+ },
+
+ _onComplete: function(id, fileName, result){
+ this._filesInProgress--;
+
+ // mark completed
+ var item = this._getItemByFileId(id);
+ qq.remove(this._find(item, 'cancel'));
+ qq.remove(this._find(item, 'spinner'));
+
+ var nameInput = this._find(item, 'nameInput');
+ var fileElement = this._find(item, 'file');
+ qq.setText(fileElement, nameInput.value);
+ qq.removeClass(fileElement, 'hidden');
+ qq.remove(nameInput);
+ jQuery('.qq-upload-button, #mediamanager__upload_button').remove();
+ jQuery('.dw__ow').parent().hide();
+ jQuery('.qq-upload-drop-area').remove();
+
+ if (result.success){
+ qq.addClass(item, this._classes.success);
+ $link = '<a href="' + result.link + '" id="h_:' + result.id + '" class="select">' + nameInput.value + '</a>';
+ jQuery(fileElement).html($link);
+
+ } else {
+ qq.addClass(item, this._classes.fail);
+ var fail = this._find(item, 'failedText');
+ if (result.error) qq.setText(fail, result.error);
+ }
+
+ if (document.getElementById('media__content') && !document.getElementById('mediamanager__done_form')) {
+ var action = document.location.href;
+ var i = action.indexOf('?');
+ if (i) action = action.substr(0, i);
+ var button = '<form method="post" action="' + action + '" id="mediamanager__done_form"><div>';
+ button += '<input type="hidden" value="' + result.ns + '" name="ns">';
+ button += '<input type="hidden" value="1" name="recent">';
+ button += '<button type="submit">' + LANG.media_done_btn + '</button></div></form>';
+ jQuery('#mediamanager__uploader').append(button);
+ }
+ }
+
+});
+
+qq.extend(qq.UploadHandlerForm.prototype, {
+ uploadAll: function(params){
+ this._uploadAll(params);
+ },
+
+ getName: function(id){
+ var file = this._inputs[id];
+ var name = document.getElementById('mediamanager__upload_item'+id);
+ if (name != null) {
+ return name.value;
+ } else {
+ if (file != null) {
+ // get input value and remove path to normalize
+ return file.value.replace(/.*(\/|\\)/, "");
+ } else {
+ return null;
+ }
+ }
+ },
+
+ _uploadAll: function(params){
+ jQuery(".qq-upload-spinner").each(function (i) {
+ jQuery(this).removeClass('hidden');
+ });
+ for (key in this._inputs) {
+ this.upload(key, params);
+ }
+
+ },
+
+ _upload: function(id, params){
+ var input = this._inputs[id];
+
+ if (!input){
+ throw new Error('file with passed id was not added, or already uploaded or cancelled');
+ }
+
+ var fileName = this.getName(id);
+
+ var iframe = this._createIframe(id);
+ var form = this._createForm(iframe, params);
+ form.appendChild(input);
+
+ var nameInput = qq.toElement('<input name="mediaid" value="' + fileName + '" type="text">');
+ form.appendChild(nameInput);
+
+ var checked = jQuery('.dw__ow').is(':checked');
+ var owCheckbox = jQuery('.dw__ow').clone();
+ owCheckbox.attr('checked', checked);
+ jQuery(form).append(owCheckbox);
+
+ var self = this;
+ this._attachLoadEvent(iframe, function(){
+ self.log('iframe loaded');
+
+ var response = self._getIframeContentJSON(iframe);
+
+ self._options.onComplete(id, fileName, response);
+ self._dequeue(id);
+
+ delete self._inputs[id];
+ // timeout added to fix busy state in FF3.6
+ setTimeout(function(){
+ qq.remove(iframe);
+ }, 1);
+ });
+
+ form.submit();
+ qq.remove(form);
+
+ return id;
+ }
+});
+
+qq.extend(qq.UploadHandlerXhr.prototype, {
+ uploadAll: function(params){
+ this._uploadAll(params);
+ },
+
+ getName: function(id){
+ var file = this._files[id];
+ var name = document.getElementById('mediamanager__upload_item'+id);
+ if (name != null) {
+ return name.value;
+ } else {
+ if (file != null) {
+ // fix missing name in Safari 4
+ return file.fileName != null ? file.fileName : file.name;
+ } else {
+ return null;
+ }
+ }
+ },
+
+ getSize: function(id){
+ var file = this._files[id];
+ if (file == null) return null;
+ return file.fileSize != null ? file.fileSize : file.size;
+ },
+
+ _upload: function(id, params){
+ var file = this._files[id],
+ name = this.getName(id),
+ size = this.getSize(id);
+ if (name == null || size == null) return;
+
+ this._loaded[id] = 0;
+
+ var xhr = this._xhrs[id] = new XMLHttpRequest();
+ var self = this;
+
+ xhr.upload.onprogress = function(e){
+ if (e.lengthComputable){
+ self._loaded[id] = e.loaded;
+ self._options.onProgress(id, name, e.loaded, e.total);
+ }
+ };
+
+ xhr.onreadystatechange = function(){
+ if (xhr.readyState == 4){
+ self._onComplete(id, xhr);
+ }
+ };
+
+ // build query string
+ params = params || {};
+ params['qqfile'] = name;
+ params['ow'] = jQuery('.dw__ow').is(':checked');
+ var queryString = qq.obj2url(params, this._options.action);
+
+ xhr.open("POST", queryString, true);
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ xhr.setRequestHeader("X-File-Name", encodeURIComponent(name));
+ xhr.setRequestHeader("Content-Type", "application/octet-stream");
+ xhr.send(file);
+ },
+
+ _uploadAll: function(params){
+ jQuery(".qq-upload-spinner").each(function (i) {
+ jQuery(this).removeClass('hidden');
+ });
+ for (key in this._files) {
+ this.upload(key, params);
+ }
+
+ }
+});
diff --git a/platform/www/lib/scripts/helpers.js b/platform/www/lib/scripts/helpers.js
new file mode 100644
index 0000000..99137c5
--- /dev/null
+++ b/platform/www/lib/scripts/helpers.js
@@ -0,0 +1,69 @@
+/**
+ * Various helper functions
+ */
+
+/**
+ * A PHP-style substr_replace
+ *
+ * Supports negative start and length and omitting length, but not
+ * str and replace arrays.
+ * See http://php.net/substr-replace for further documentation.
+ */
+function substr_replace(str, replace, start, length) {
+ var a2, b1;
+ a2 = (start < 0 ? str.length : 0) + start;
+ if (typeof length === 'undefined') {
+ length = str.length - a2;
+ } else if (length < 0 && start < 0 && length <= start) {
+ length = 0;
+ }
+ b1 = (length < 0 ? str.length : a2) + length;
+ return str.substring(0, a2) + replace + str.substring(b1);
+}
+
+/**
+ * Bind variables to a function call creating a closure
+ *
+ * Use this to circumvent variable scope problems when creating closures
+ * inside a loop
+ *
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @link http://www.cosmocode.de/en/blog/gohr/2009-10/15-javascript-fixing-the-closure-scope-in-loops
+ * @param functionref fnc - the function to be called
+ * @param mixed - any arguments to be passed to the function
+ * @returns functionref
+ */
+function bind(fnc/*, ... */) {
+ var Aps = Array.prototype.slice,
+ // Store passed arguments in this scope.
+ // Since arguments is no Array nor has an own slice method,
+ // we have to apply the slice method from the Array.prototype
+ static_args = Aps.call(arguments, 1);
+
+ // Return a function evaluating the passed function with the
+ // given args and optional arguments passed on invocation.
+ return function (/* ... */) {
+ // Same here, but we use Array.prototype.slice solely for
+ // converting arguments to an Array.
+ return fnc.apply(this,
+ static_args.concat(Aps.call(arguments, 0)));
+ };
+}
+
+/**
+ * Report an error from a JS file to the console
+ *
+ * @param e The error object
+ * @param file The file in which the error occurred
+ */
+function logError(e, file) {
+ if (window.console && console.error) {
+ console.error('The error "%s: %s" occurred in file "%s". ' +
+ 'If this is in a plugin try updating or disabling the plugin, ' +
+ 'if this is in a template try updating the template or switching to the "dokuwiki" template.',
+ e.name, e.message, file);
+ if(e.stack) {
+ console.error(e.stack);
+ }
+ }
+}
diff --git a/platform/www/lib/scripts/hotkeys.js b/platform/www/lib/scripts/hotkeys.js
new file mode 100644
index 0000000..76a277a
--- /dev/null
+++ b/platform/www/lib/scripts/hotkeys.js
@@ -0,0 +1,302 @@
+/**
+ * Some of these scripts were taken from TinyMCE (http://tinymce.moxiecode.com/) and were modified for DokuWiki
+ *
+ * Class handles accesskeys using javascript and also provides ability
+ * to register and use other hotkeys as well.
+ *
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ */
+function Hotkeys() {
+
+ this.shortcuts = new Array();
+
+ /**
+ * Set modifier keys, for instance:
+ * this.modifier = 'ctrl';
+ * this.modifier = 'ctrl+shift';
+ * this.modifier = 'ctrl+alt+shift';
+ * this.modifier = 'alt';
+ * this.modifier = 'alt+shift';
+ *
+ * overwritten in intitialize (see below)
+ */
+ this.modifier = 'ctrl+alt';
+
+ /**
+ * Initialization
+ *
+ * This function looks up all the accesskeys used in the current page
+ * (at anchor elements and button elements [type="submit"]) and registers
+ * appropriate shortcuts.
+ *
+ * Secondly, initialization registers listeners on document to catch all
+ * keyboard events.
+ *
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ */
+ this.initialize = function() {
+ var t = this;
+
+ //switch modifier key based on OS FS#1958
+ if(is_macos){
+ t.modifier = 'ctrl+alt';
+ }else{
+ t.modifier = 'alt';
+ }
+
+ /**
+ * Lookup all anchors with accesskey and register event - go to anchor
+ * target.
+ */
+ var anchors = document.getElementsByTagName("a");
+ t.each(anchors, function(a) {
+ if (a.accessKey != "") {
+ t.addShortcut(t.modifier + '+' + a.accessKey, function() {
+ location.href = a.href;
+ });
+ a.accessKey = '';
+ }
+ });
+
+ /**
+ * Lookup all button [type="submit"] with accesskey and register event -
+ * perform "click" on a button.
+ */
+ var inputs = document.getElementsByTagName("button");
+ t.each(inputs, function(i) {
+ if (i.type == "submit" && i.accessKey != "") {
+ t.addShortcut(t.modifier + '+' + i.accessKey, function() {
+ i.click();
+ });
+ i.accessKey = '';
+ }
+ });
+
+ /**
+ * Lookup all buttons with accesskey and register event -
+ * perform "click" on a button.
+ */
+ var buttons = document.getElementsByTagName("button");
+ t.each(buttons, function(b) {
+ if (b.accessKey != "") {
+ t.addShortcut(t.modifier + '+' + b.accessKey, function() {
+ b.click();
+ });
+ b.accessKey = '';
+ }
+ });
+
+ /**
+ * Register listeners on document to catch keyboard events.
+ */
+
+ addEvent(document,'keyup',function (e) {
+ return t.onkeyup.call(t,e);
+ });
+
+ addEvent(document,'keypress',function (e) {
+ return t.onkeypress.call(t,e);
+ });
+
+ addEvent(document,'keydown',function (e) {
+ return t.onkeydown.call(t,e);
+ });
+ };
+
+ /**
+ * Keyup processing function
+ * Function returns true if keyboard event has registered handler, and
+ * executes the handler function.
+ *
+ * @param e KeyboardEvent
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @return b boolean
+ */
+ this.onkeyup = function(e) {
+ var t = this;
+ var v = t.findShortcut(e);
+ if (v != null && v != false) {
+ v.func.call(t);
+ return false;
+ }
+ return true;
+ };
+
+ /**
+ * Keydown processing function
+ * Function returns true if keyboard event has registered handler
+ *
+ * @param e KeyboardEvent
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @return b boolean
+ */
+ this.onkeydown = function(e) {
+ var t = this;
+ var v = t.findShortcut(e);
+ if (v != null && v != false) {
+ return false;
+ }
+ return true;
+ };
+
+ /**
+ * Keypress processing function
+ * Function returns true if keyboard event has registered handler
+ *
+ * @param e KeyboardEvent
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @return b
+ */
+ this.onkeypress = function(e) {
+ var t = this;
+ var v = t.findShortcut(e);
+ if (v != null && v != false) {
+ return false;
+ }
+ return true;
+ };
+
+ /**
+ * Register new shortcut
+ *
+ * This function registers new shortcuts, each shortcut is defined by its
+ * modifier keys and a key (with + as delimiter). If shortcut is pressed
+ * cmd_function is performed.
+ *
+ * For example:
+ * pa = "ctrl+alt+p";
+ * pa = "shift+alt+s";
+ *
+ * Full example of method usage:
+ * hotkeys.addShortcut('ctrl+s',function() {
+ * document.getElementByID('form_1').submit();
+ * });
+ *
+ * @param pa String description of the shortcut (ctrl+a, ctrl+shift+p, .. )
+ * @param cmd_func Function to be called if shortcut is pressed
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ */
+ this.addShortcut = function(pa, cmd_func) {
+ var t = this;
+
+ var o = {
+ func : cmd_func,
+ alt : false,
+ ctrl : false,
+ shift : false
+ };
+
+ t.each(t.explode(pa, '+'), function(v) {
+ switch (v) {
+ case 'alt':
+ case 'ctrl':
+ case 'shift':
+ o[v] = true;
+ break;
+
+ default:
+ o.charCode = v.charCodeAt(0);
+ o.keyCode = v.toUpperCase().charCodeAt(0);
+ }
+ });
+
+ t.shortcuts.push((o.ctrl ? 'ctrl' : '') + ',' + (o.alt ? 'alt' : '') + ',' + (o.shift ? 'shift' : '') + ',' + o.keyCode, o);
+
+ return true;
+ };
+
+ /**
+ * @property isMac
+ */
+ this.isMac = is_macos;
+
+ /**
+ * Apply function cb on each element of o in the namespace of s
+ * @param o Array of objects
+ * @param cb Function to be called on each object
+ * @param s Namespace to be used during call of cb (default namespace is o)
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ */
+ this.each = function(o, cb, s) {
+ var n, l;
+
+ if (!o)
+ return 0;
+
+ s = s || o;
+
+ if (o.length !== undefined) {
+ // Indexed arrays, needed for Safari
+ for (n=0, l = o.length; n < l; n++) {
+ if (cb.call(s, o[n], n, o) === false)
+ return 0;
+ }
+ } else {
+ // Hashtables
+ for (n in o) {
+ if (o.hasOwnProperty(n)) {
+ if (cb.call(s, o[n], n, o) === false)
+ return 0;
+ }
+ }
+ }
+
+ return 1;
+ };
+
+ /**
+ * Explode string according to delimiter
+ * @param s String
+ * @param d Delimiter (default ',')
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @return a Array of tokens
+ */
+ this.explode = function(s, d) {
+ return s.split(d || ',');
+ };
+
+ /**
+ * Find if the shortcut was registered
+ *
+ * @param e KeyboardEvent
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ * @return v Shortcut structure or null if not found
+ */
+ this.findShortcut = function (e) {
+ var t = this;
+ var v = null;
+
+ /* No modifier key used - shortcut does not exist */
+ if (!e.altKey && !e.ctrlKey && !e.metaKey) {
+ return v;
+ }
+
+ t.each(t.shortcuts, function(o) {
+ if (o.ctrl != e.ctrlKey)
+ return;
+
+ if (o.alt != e.altKey)
+ return;
+
+ if (o.shift != e.shiftKey)
+ return;
+
+ if (e.keyCode == o.keyCode || (e.charCode && e.charCode == o.charCode)) {
+ v = o;
+ return;
+ }
+ });
+ return v;
+ };
+}
+
+/**
+ * Init function for hotkeys. Called from js.php, to ensure hotkyes are initialized after toolbar.
+ * Call of addInitEvent(initializeHotkeys) is unnecessary now.
+ *
+ * @author Marek Sacha <sachamar@fel.cvut.cz>
+ */
+function initializeHotkeys() {
+ var hotkeys = new Hotkeys();
+ hotkeys.initialize();
+}
diff --git a/platform/www/lib/scripts/index.html b/platform/www/lib/scripts/index.html
new file mode 100644
index 0000000..977f90e
--- /dev/null
+++ b/platform/www/lib/scripts/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=../../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/platform/www/lib/scripts/index.js b/platform/www/lib/scripts/index.js
new file mode 100644
index 0000000..4b67a0b
--- /dev/null
+++ b/platform/www/lib/scripts/index.js
@@ -0,0 +1,16 @@
+var dw_index = jQuery('#index__tree').dw_tree({deferInit: true,
+ load_data: function (show_sublist, $clicky) {
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ $clicky[0].search.substr(1) + '&call=index',
+ show_sublist, 'html'
+ );
+ }
+});
+jQuery(function () {
+ var $tree = jQuery('#index__tree');
+
+ dw_index.$obj = $tree;
+
+ dw_index.init();
+});
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.png b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.png
new file mode 100644
index 0000000..6b1f24d
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_55_fbf9ee_1x400.png
Binary files differ
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.png b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.png
new file mode 100644
index 0000000..5f6fc57
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_65_ffffff_1x400.png
Binary files differ
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.png b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.png
new file mode 100644
index 0000000..8bc2c8b
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_dadada_1x400.png
Binary files differ
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.png b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.png
new file mode 100644
index 0000000..be993d5
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_75_e6e6e6_1x400.png
Binary files differ
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.png b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.png
new file mode 100644
index 0000000..b9356a2
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_glass_95_fef1ec_1x400.png
Binary files differ
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png
new file mode 100644
index 0000000..9e3afb5
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png
Binary files differ
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.png b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.png
new file mode 100644
index 0000000..6ba300b
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_222222_256x240.png
Binary files differ
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.png b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.png
new file mode 100644
index 0000000..1c7b633
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_2e83ff_256x240.png
Binary files differ
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.png b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.png
new file mode 100644
index 0000000..bd90b26
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_454545_256x240.png
Binary files differ
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.png b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.png
new file mode 100644
index 0000000..813f18d
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_888888_256x240.png
Binary files differ
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.png b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.png
new file mode 100644
index 0000000..cfb3d44
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/images/ui-icons_cd0a0a_256x240.png
Binary files differ
diff --git a/platform/www/lib/scripts/jquery/jquery-ui-theme/smoothness.css b/platform/www/lib/scripts/jquery/jquery-ui-theme/smoothness.css
new file mode 100644
index 0000000..eab564a
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui-theme/smoothness.css
@@ -0,0 +1,1311 @@
+/*! jQuery UI - v1.12.1 - 2016-09-14
+* http://jqueryui.com
+* Includes: core.css, accordion.css, autocomplete.css, menu.css, button.css, controlgroup.css, checkboxradio.css, datepicker.css, dialog.css, draggable.css, resizable.css, progressbar.css, selectable.css, selectmenu.css, slider.css, sortable.css, spinner.css, tabs.css, tooltip.css, theme.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=highlight_soft&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=flat&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=glass&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=glass&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=glass&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=glass&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=flat&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+ display: none;
+}
+.ui-helper-hidden-accessible {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px;
+}
+.ui-helper-reset {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ line-height: 1.3;
+ text-decoration: none;
+ font-size: 100%;
+ list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+ content: "";
+ display: table;
+ border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+ clear: both;
+}
+.ui-helper-zfix {
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ position: absolute;
+ opacity: 0;
+ filter:Alpha(Opacity=0); /* support: IE8 */
+}
+
+.ui-front {
+ z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+ cursor: default !important;
+ pointer-events: none;
+}
+
+
+/* Icons
+----------------------------------*/
+.ui-icon {
+ display: inline-block;
+ vertical-align: middle;
+ margin-top: -.25em;
+ position: relative;
+ text-indent: -99999px;
+ overflow: hidden;
+ background-repeat: no-repeat;
+}
+
+.ui-widget-icon-block {
+ left: 50%;
+ margin-left: -8px;
+ display: block;
+}
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
+.ui-accordion .ui-accordion-header {
+ display: block;
+ cursor: pointer;
+ position: relative;
+ margin: 2px 0 0 0;
+ padding: .5em .5em .5em .7em;
+ font-size: 100%;
+}
+.ui-accordion .ui-accordion-content {
+ padding: 1em 2.2em;
+ border-top: 0;
+ overflow: auto;
+}
+.ui-autocomplete {
+ position: absolute;
+ top: 0;
+ left: 0;
+ cursor: default;
+}
+.ui-menu {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: block;
+ outline: 0;
+}
+.ui-menu .ui-menu {
+ position: absolute;
+}
+.ui-menu .ui-menu-item {
+ margin: 0;
+ cursor: pointer;
+ /* support: IE10, see #8844 */
+ list-style-image: url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7");
+}
+.ui-menu .ui-menu-item-wrapper {
+ position: relative;
+ padding: 3px 1em 3px .4em;
+}
+.ui-menu .ui-menu-divider {
+ margin: 5px 0;
+ height: 0;
+ font-size: 0;
+ line-height: 0;
+ border-width: 1px 0 0 0;
+}
+.ui-menu .ui-state-focus,
+.ui-menu .ui-state-active {
+ margin: -1px;
+}
+
+/* icon support */
+.ui-menu-icons {
+ position: relative;
+}
+.ui-menu-icons .ui-menu-item-wrapper {
+ padding-left: 2em;
+}
+
+/* left-aligned */
+.ui-menu .ui-icon {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: .2em;
+ margin: auto 0;
+}
+
+/* right-aligned */
+.ui-menu .ui-menu-icon {
+ left: auto;
+ right: 0;
+}
+.ui-button {
+ padding: .4em 1em;
+ display: inline-block;
+ position: relative;
+ line-height: normal;
+ margin-right: .1em;
+ cursor: pointer;
+ vertical-align: middle;
+ text-align: center;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+
+ /* Support: IE <= 11 */
+ overflow: visible;
+}
+
+.ui-button,
+.ui-button:link,
+.ui-button:visited,
+.ui-button:hover,
+.ui-button:active {
+ text-decoration: none;
+}
+
+/* to make room for the icon, a width needs to be set here */
+.ui-button-icon-only {
+ width: 2em;
+ box-sizing: border-box;
+ text-indent: -9999px;
+ white-space: nowrap;
+}
+
+/* no icon support for input elements */
+input.ui-button.ui-button-icon-only {
+ text-indent: 0;
+}
+
+/* button icon element(s) */
+.ui-button-icon-only .ui-icon {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ margin-top: -8px;
+ margin-left: -8px;
+}
+
+.ui-button.ui-icon-notext .ui-icon {
+ padding: 0;
+ width: 2.1em;
+ height: 2.1em;
+ text-indent: -9999px;
+ white-space: nowrap;
+
+}
+
+input.ui-button.ui-icon-notext .ui-icon {
+ width: auto;
+ height: auto;
+ text-indent: 0;
+ white-space: normal;
+ padding: .4em 1em;
+}
+
+/* workarounds */
+/* Support: Firefox 5 - 40 */
+input.ui-button::-moz-focus-inner,
+button.ui-button::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+.ui-controlgroup {
+ vertical-align: middle;
+ display: inline-block;
+}
+.ui-controlgroup > .ui-controlgroup-item {
+ float: left;
+ margin-left: 0;
+ margin-right: 0;
+}
+.ui-controlgroup > .ui-controlgroup-item:focus,
+.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus {
+ z-index: 9999;
+}
+.ui-controlgroup-vertical > .ui-controlgroup-item {
+ display: block;
+ float: none;
+ width: 100%;
+ margin-top: 0;
+ margin-bottom: 0;
+ text-align: left;
+}
+.ui-controlgroup-vertical .ui-controlgroup-item {
+ box-sizing: border-box;
+}
+.ui-controlgroup .ui-controlgroup-label {
+ padding: .4em 1em;
+}
+.ui-controlgroup .ui-controlgroup-label span {
+ font-size: 80%;
+}
+.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item {
+ border-left: none;
+}
+.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item {
+ border-top: none;
+}
+.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content {
+ border-right: none;
+}
+.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content {
+ border-bottom: none;
+}
+
+/* Spinner specific style fixes */
+.ui-controlgroup-vertical .ui-spinner-input {
+
+ /* Support: IE8 only, Android < 4.4 only */
+ width: 75%;
+ width: calc( 100% - 2.4em );
+}
+.ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
+ border-top-style: solid;
+}
+
+.ui-checkboxradio-label .ui-icon-background {
+ box-shadow: inset 1px 1px 1px #ccc;
+ border-radius: .12em;
+ border: none;
+}
+.ui-checkboxradio-radio-label .ui-icon-background {
+ width: 16px;
+ height: 16px;
+ border-radius: 1em;
+ overflow: visible;
+ border: none;
+}
+.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,
+.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon {
+ background-image: none;
+ width: 8px;
+ height: 8px;
+ border-width: 4px;
+ border-style: solid;
+}
+.ui-checkboxradio-disabled {
+ pointer-events: none;
+}
+.ui-datepicker {
+ width: 17em;
+ padding: .2em .2em 0;
+ display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+ position: relative;
+ padding: .2em 0;
+}
+.ui-datepicker .ui-datepicker-prev,
+.ui-datepicker .ui-datepicker-next {
+ position: absolute;
+ top: 2px;
+ width: 1.8em;
+ height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-prev-hover,
+.ui-datepicker .ui-datepicker-next-hover {
+ top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+ left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+ right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+ left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+ right: 1px;
+}
+.ui-datepicker .ui-datepicker-prev span,
+.ui-datepicker .ui-datepicker-next span {
+ display: block;
+ position: absolute;
+ left: 50%;
+ margin-left: -8px;
+ top: 50%;
+ margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+ margin: 0 2.3em;
+ line-height: 1.8em;
+ text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+ font-size: 1em;
+ margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+ width: 45%;
+}
+.ui-datepicker table {
+ width: 100%;
+ font-size: .9em;
+ border-collapse: collapse;
+ margin: 0 0 .4em;
+}
+.ui-datepicker th {
+ padding: .7em .3em;
+ text-align: center;
+ font-weight: bold;
+ border: 0;
+}
+.ui-datepicker td {
+ border: 0;
+ padding: 1px;
+}
+.ui-datepicker td span,
+.ui-datepicker td a {
+ display: block;
+ padding: .2em;
+ text-align: right;
+ text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+ background-image: none;
+ margin: .7em 0 0 0;
+ padding: 0 .2em;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+ float: right;
+ margin: .5em .2em .4em;
+ cursor: pointer;
+ padding: .2em .6em .3em .6em;
+ width: auto;
+ overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+ float: left;
+}
+
+/* with multiple calendars */
+.ui-datepicker.ui-datepicker-multi {
+ width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+ float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+ width: 95%;
+ margin: 0 auto .4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+ width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+ width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+ width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+ border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+ clear: left;
+}
+.ui-datepicker-row-break {
+ clear: both;
+ width: 100%;
+ font-size: 0;
+}
+
+/* RTL support */
+.ui-datepicker-rtl {
+ direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+ right: 2px;
+ left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+ left: 2px;
+ right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+ right: 1px;
+ left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+ left: 1px;
+ right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+ clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+ float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+ float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+ border-right-width: 0;
+ border-left-width: 1px;
+}
+
+/* Icons */
+.ui-datepicker .ui-icon {
+ display: block;
+ text-indent: -99999px;
+ overflow: hidden;
+ background-repeat: no-repeat;
+ left: .5em;
+ top: .3em;
+}
+.ui-dialog {
+ position: absolute;
+ top: 0;
+ left: 0;
+ padding: .2em;
+ outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+ padding: .4em 1em;
+ position: relative;
+}
+.ui-dialog .ui-dialog-title {
+ float: left;
+ margin: .1em 0;
+ white-space: nowrap;
+ width: 90%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+ position: absolute;
+ right: .3em;
+ top: 50%;
+ width: 20px;
+ margin: -10px 0 0 0;
+ padding: 1px;
+ height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+ position: relative;
+ border: 0;
+ padding: .5em 1em;
+ background: none;
+ overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+ text-align: left;
+ border-width: 1px 0 0 0;
+ background-image: none;
+ margin-top: .5em;
+ padding: .3em 1em .5em .4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+ float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+ margin: .5em .4em .5em 0;
+ cursor: pointer;
+}
+.ui-dialog .ui-resizable-n {
+ height: 2px;
+ top: 0;
+}
+.ui-dialog .ui-resizable-e {
+ width: 2px;
+ right: 0;
+}
+.ui-dialog .ui-resizable-s {
+ height: 2px;
+ bottom: 0;
+}
+.ui-dialog .ui-resizable-w {
+ width: 2px;
+ left: 0;
+}
+.ui-dialog .ui-resizable-se,
+.ui-dialog .ui-resizable-sw,
+.ui-dialog .ui-resizable-ne,
+.ui-dialog .ui-resizable-nw {
+ width: 7px;
+ height: 7px;
+}
+.ui-dialog .ui-resizable-se {
+ right: 0;
+ bottom: 0;
+}
+.ui-dialog .ui-resizable-sw {
+ left: 0;
+ bottom: 0;
+}
+.ui-dialog .ui-resizable-ne {
+ right: 0;
+ top: 0;
+}
+.ui-dialog .ui-resizable-nw {
+ left: 0;
+ top: 0;
+}
+.ui-draggable .ui-dialog-titlebar {
+ cursor: move;
+}
+.ui-draggable-handle {
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.ui-resizable {
+ position: relative;
+}
+.ui-resizable-handle {
+ position: absolute;
+ font-size: 0.1px;
+ display: block;
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.ui-resizable-disabled .ui-resizable-handle,
+.ui-resizable-autohide .ui-resizable-handle {
+ display: none;
+}
+.ui-resizable-n {
+ cursor: n-resize;
+ height: 7px;
+ width: 100%;
+ top: -5px;
+ left: 0;
+}
+.ui-resizable-s {
+ cursor: s-resize;
+ height: 7px;
+ width: 100%;
+ bottom: -5px;
+ left: 0;
+}
+.ui-resizable-e {
+ cursor: e-resize;
+ width: 7px;
+ right: -5px;
+ top: 0;
+ height: 100%;
+}
+.ui-resizable-w {
+ cursor: w-resize;
+ width: 7px;
+ left: -5px;
+ top: 0;
+ height: 100%;
+}
+.ui-resizable-se {
+ cursor: se-resize;
+ width: 12px;
+ height: 12px;
+ right: 1px;
+ bottom: 1px;
+}
+.ui-resizable-sw {
+ cursor: sw-resize;
+ width: 9px;
+ height: 9px;
+ left: -5px;
+ bottom: -5px;
+}
+.ui-resizable-nw {
+ cursor: nw-resize;
+ width: 9px;
+ height: 9px;
+ left: -5px;
+ top: -5px;
+}
+.ui-resizable-ne {
+ cursor: ne-resize;
+ width: 9px;
+ height: 9px;
+ right: -5px;
+ top: -5px;
+}
+.ui-progressbar {
+ height: 2em;
+ text-align: left;
+ overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+ margin: -1px;
+ height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+ background: url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");
+ height: 100%;
+ filter: alpha(opacity=25); /* support: IE8 */
+ opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+ background-image: none;
+}
+.ui-selectable {
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.ui-selectable-helper {
+ position: absolute;
+ z-index: 100;
+ border: 1px dotted black;
+}
+.ui-selectmenu-menu {
+ padding: 0;
+ margin: 0;
+ position: absolute;
+ top: 0;
+ left: 0;
+ display: none;
+}
+.ui-selectmenu-menu .ui-menu {
+ overflow: auto;
+ overflow-x: hidden;
+ padding-bottom: 1px;
+}
+.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
+ font-size: 1em;
+ font-weight: bold;
+ line-height: 1.5;
+ padding: 2px 0.4em;
+ margin: 0.5em 0 0 0;
+ height: auto;
+ border: 0;
+}
+.ui-selectmenu-open {
+ display: block;
+}
+.ui-selectmenu-text {
+ display: block;
+ margin-right: 20px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.ui-selectmenu-button.ui-button {
+ text-align: left;
+ white-space: nowrap;
+ width: 14em;
+}
+.ui-selectmenu-icon.ui-icon {
+ float: right;
+ margin-top: 0;
+}
+.ui-slider {
+ position: relative;
+ text-align: left;
+}
+.ui-slider .ui-slider-handle {
+ position: absolute;
+ z-index: 2;
+ width: 1.2em;
+ height: 1.2em;
+ cursor: default;
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.ui-slider .ui-slider-range {
+ position: absolute;
+ z-index: 1;
+ font-size: .7em;
+ display: block;
+ border: 0;
+ background-position: 0 0;
+}
+
+/* support: IE8 - See #6727 */
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+ filter: inherit;
+}
+
+.ui-slider-horizontal {
+ height: .8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+ top: -.3em;
+ margin-left: -.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+ top: 0;
+ height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+ left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+ right: 0;
+}
+
+.ui-slider-vertical {
+ width: .8em;
+ height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+ left: -.3em;
+ margin-left: 0;
+ margin-bottom: -.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+ left: 0;
+ width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+ bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+ top: 0;
+}
+.ui-sortable-handle {
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.ui-spinner {
+ position: relative;
+ display: inline-block;
+ overflow: hidden;
+ padding: 0;
+ vertical-align: middle;
+}
+.ui-spinner-input {
+ border: none;
+ background: none;
+ color: inherit;
+ padding: .222em 0;
+ margin: .2em 0;
+ vertical-align: middle;
+ margin-left: .4em;
+ margin-right: 2em;
+}
+.ui-spinner-button {
+ width: 1.6em;
+ height: 50%;
+ font-size: .5em;
+ padding: 0;
+ margin: 0;
+ text-align: center;
+ position: absolute;
+ cursor: default;
+ display: block;
+ overflow: hidden;
+ right: 0;
+}
+/* more specificity required here to override default borders */
+.ui-spinner a.ui-spinner-button {
+ border-top-style: none;
+ border-bottom-style: none;
+ border-right-style: none;
+}
+.ui-spinner-up {
+ top: 0;
+}
+.ui-spinner-down {
+ bottom: 0;
+}
+.ui-tabs {
+ position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+ padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+ margin: 0;
+ padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+ list-style: none;
+ float: left;
+ position: relative;
+ top: 0;
+ margin: 1px .2em 0 0;
+ border-bottom-width: 0;
+ padding: 0;
+ white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
+ float: left;
+ padding: .5em 1em;
+ text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+ margin-bottom: -1px;
+ padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
+ cursor: text;
+}
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
+ cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+ display: block;
+ border-width: 0;
+ padding: 1em 1.4em;
+ background: none;
+}
+.ui-tooltip {
+ padding: 8px;
+ position: absolute;
+ z-index: 9999;
+ max-width: 300px;
+}
+body .ui-tooltip {
+ border-width: 2px;
+}
+/* Component containers
+----------------------------------*/
+.ui-widget {
+
+ font-size: 1.1em;
+}
+.ui-widget .ui-widget {
+ font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+
+ font-size: 1em;
+}
+.ui-widget.ui-widget-content {
+ border: 1px solid #d3d3d3;
+}
+.ui-widget-content {
+ border: 1px solid #aaaaaa;
+ background: #ffffff;
+ color: #222222;
+}
+.ui-widget-content a {
+ color: #222222;
+}
+.ui-widget-header {
+ border: 1px solid #aaaaaa;
+ background: #cccccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;
+ color: #222222;
+ font-weight: bold;
+}
+.ui-widget-header a {
+ color: #222222;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default,
+.ui-button,
+
+/* We use html here because we need a greater specificity to make sure disabled
+works properly when clicked or hovered */
+html .ui-button.ui-state-disabled:hover,
+html .ui-button.ui-state-disabled:active {
+ border: 1px solid #d3d3d3;
+ background: #e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;
+ font-weight: normal;
+ color: #555555;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited,
+a.ui-button,
+a:link.ui-button,
+a:visited.ui-button,
+.ui-button {
+ color: #555555;
+ text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus,
+.ui-button:hover,
+.ui-button:focus {
+ border: 1px solid #999999;
+ background: #dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;
+ font-weight: normal;
+ color: #212121;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited,
+.ui-state-focus a,
+.ui-state-focus a:hover,
+.ui-state-focus a:link,
+.ui-state-focus a:visited,
+a.ui-button:hover,
+a.ui-button:focus {
+ color: #212121;
+ text-decoration: none;
+}
+
+.ui-visual-focus {
+ box-shadow: 0 0 3px 1px rgb(94, 158, 214);
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active,
+a.ui-button:active,
+.ui-button:active,
+.ui-button.ui-state-active:hover {
+ border: 1px solid #aaaaaa;
+ background: #ffffff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;
+ font-weight: normal;
+ color: #212121;
+}
+.ui-icon-background,
+.ui-state-active .ui-icon-background {
+ border: #aaaaaa;
+ background-color: #212121;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+ color: #212121;
+ text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+ border: 1px solid #fcefa1;
+ background: #fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;
+ color: #363636;
+}
+.ui-state-checked {
+ border: 1px solid #fcefa1;
+ background: #fbf9ee;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+ color: #363636;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+ border: 1px solid #cd0a0a;
+ background: #fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;
+ color: #cd0a0a;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+ color: #cd0a0a;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+ color: #cd0a0a;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+ font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+ opacity: .7;
+ filter:Alpha(Opacity=70); /* support: IE8 */
+ font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+ opacity: .35;
+ filter:Alpha(Opacity=35); /* support: IE8 */
+ background-image: none;
+}
+.ui-state-disabled .ui-icon {
+ filter:Alpha(Opacity=35); /* support: IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+ width: 16px;
+ height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+ background-image: url("images/ui-icons_222222_256x240.png");
+}
+.ui-widget-header .ui-icon {
+ background-image: url("images/ui-icons_222222_256x240.png");
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon,
+.ui-button:hover .ui-icon,
+.ui-button:focus .ui-icon {
+ background-image: url("images/ui-icons_454545_256x240.png");
+}
+.ui-state-active .ui-icon,
+.ui-button:active .ui-icon {
+ background-image: url("images/ui-icons_454545_256x240.png");
+}
+.ui-state-highlight .ui-icon,
+.ui-button .ui-state-highlight.ui-icon {
+ background-image: url("images/ui-icons_2e83ff_256x240.png");
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+ background-image: url("images/ui-icons_cd0a0a_256x240.png");
+}
+.ui-button .ui-icon {
+ background-image: url("images/ui-icons_888888_256x240.png");
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-caret-1-n { background-position: 0 0; }
+.ui-icon-caret-1-ne { background-position: -16px 0; }
+.ui-icon-caret-1-e { background-position: -32px 0; }
+.ui-icon-caret-1-se { background-position: -48px 0; }
+.ui-icon-caret-1-s { background-position: -65px 0; }
+.ui-icon-caret-1-sw { background-position: -80px 0; }
+.ui-icon-caret-1-w { background-position: -96px 0; }
+.ui-icon-caret-1-nw { background-position: -112px 0; }
+.ui-icon-caret-2-n-s { background-position: -128px 0; }
+.ui-icon-caret-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -65px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -65px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 1px -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+ border-top-left-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+ border-top-right-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+ border-bottom-left-radius: 4px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+ border-bottom-right-radius: 4px;
+}
+
+/* Overlays */
+.ui-widget-overlay {
+ background: #aaaaaa;
+ opacity: .3;
+ filter: Alpha(Opacity=30); /* support: IE8 */
+}
+.ui-widget-shadow {
+ -webkit-box-shadow: -8px -8px 8px #aaaaaa;
+ box-shadow: -8px -8px 8px #aaaaaa;
+}
diff --git a/platform/www/lib/scripts/jquery/jquery-ui.min.js b/platform/www/lib/scripts/jquery/jquery-ui.min.js
new file mode 100644
index 0000000..117cb35
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery-ui.min.js
@@ -0,0 +1,13 @@
+/*! jQuery UI - v1.12.1 - 2016-09-14
+* http://jqueryui.com
+* Includes: widget.js, position.js, data.js, disable-selection.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/accordion.js, widgets/autocomplete.js, widgets/button.js, widgets/checkboxradio.js, widgets/controlgroup.js, widgets/datepicker.js, widgets/dialog.js, widgets/draggable.js, widgets/droppable.js, widgets/menu.js, widgets/mouse.js, widgets/progressbar.js, widgets/resizable.js, widgets/selectable.js, widgets/selectmenu.js, widgets/slider.js, widgets/sortable.js, widgets/spinner.js, widgets/tabs.js, widgets/tooltip.js
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){function e(t){for(var e=t.css("visibility");"inherit"===e;)t=t.parent(),e=t.css("visibility");return"hidden"!==e}function i(t){for(var e,i;t.length&&t[0]!==document;){if(e=t.css("position"),("absolute"===e||"relative"===e||"fixed"===e)&&(i=parseInt(t.css("zIndex"),10),!isNaN(i)&&0!==i))return i;t=t.parent()}return 0}function s(){this._curInst=null,this._keyEvent=!1,this._disabledInputs=[],this._datepickerShowing=!1,this._inDialog=!1,this._mainDivId="ui-datepicker-div",this._inlineClass="ui-datepicker-inline",this._appendClass="ui-datepicker-append",this._triggerClass="ui-datepicker-trigger",this._dialogClass="ui-datepicker-dialog",this._disableClass="ui-datepicker-disabled",this._unselectableClass="ui-datepicker-unselectable",this._currentClass="ui-datepicker-current-day",this._dayOverClass="ui-datepicker-days-cell-over",this.regional=[],this.regional[""]={closeText:"Done",prevText:"Prev",nextText:"Next",currentText:"Today",monthNames:["January","February","March","April","May","June","July","August","September","October","November","December"],monthNamesShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],dayNames:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],dayNamesShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],dayNamesMin:["Su","Mo","Tu","We","Th","Fr","Sa"],weekHeader:"Wk",dateFormat:"mm/dd/yy",firstDay:0,isRTL:!1,showMonthAfterYear:!1,yearSuffix:""},this._defaults={showOn:"focus",showAnim:"fadeIn",showOptions:{},defaultDate:null,appendText:"",buttonText:"...",buttonImage:"",buttonImageOnly:!1,hideIfNoPrevNext:!1,navigationAsDateFormat:!1,gotoCurrent:!1,changeMonth:!1,changeYear:!1,yearRange:"c-10:c+10",showOtherMonths:!1,selectOtherMonths:!1,showWeek:!1,calculateWeek:this.iso8601Week,shortYearCutoff:"+10",minDate:null,maxDate:null,duration:"fast",beforeShowDay:null,beforeShow:null,onSelect:null,onChangeMonthYear:null,onClose:null,numberOfMonths:1,showCurrentAtPos:0,stepMonths:1,stepBigMonths:12,altField:"",altFormat:"",constrainInput:!0,showButtonPanel:!1,autoSize:!1,disabled:!1},t.extend(this._defaults,this.regional[""]),this.regional.en=t.extend(!0,{},this.regional[""]),this.regional["en-US"]=t.extend(!0,{},this.regional.en),this.dpDiv=n(t("<div id='"+this._mainDivId+"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"))}function n(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.on("mouseout",i,function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).on("mouseover",i,o)}function o(){t.datepicker._isDisabledDatepicker(m.inline?m.dpDiv.parent()[0]:m.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))}function a(e,i){t.extend(e,i);for(var s in i)null==i[s]&&(e[s]=i[s]);return e}function r(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.ui=t.ui||{},t.ui.version="1.12.1";var h=0,l=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},n=t[h][e],o=t[h][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var i,s,n=l.call(arguments,1),o=0,a=n.length;a>o;o++)for(i in n[o])s=n[o][i],n[o].hasOwnProperty(i)&&void 0!==s&&(e[i]=t.isPlainObject(s)?t.isPlainObject(e[i])?t.widget.extend({},e[i],s):t.widget.extend({},s):s);return e},t.widget.bridge=function(e,i){var s=i.prototype.widgetFullName||e;t.fn[e]=function(n){var o="string"==typeof n,a=l.call(arguments,1),r=this;return o?this.length||"instance"!==n?this.each(function(){var i,o=t.data(this,s);return"instance"===n?(r=o,!1):o?t.isFunction(o[n])&&"_"!==n.charAt(0)?(i=o[n].apply(o,a),i!==o&&void 0!==i?(r=i&&i.jquery?r.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+n+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+n+"'")}):r=void 0:(a.length&&(n=t.widget.extend.apply(null,[n].concat(a))),this.each(function(){var e=t.data(this,s);e?(e.option(n||{}),e._init&&e._init()):t.data(this,s,new i(n,this))})),r}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,i){i=t(i||this.defaultElement||this)[0],this.element=t(i),this.uuid=h++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},i!==this&&(t.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===i&&this.destroy()}}),this.document=t(i.style?i.ownerDocument:i.document||i),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,o="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:o?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]),n=!!i[0]&&9===i[0].nodeType,o=!s&&!n;return{element:i,isWindow:s,isDocument:n,offset:o?t(e).offset():{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:i.outerWidth(),height:i.outerHeight()}}},t.fn.position=function(n){if(!n||!n.of)return d.apply(this,arguments);n=t.extend({},n);var u,p,f,g,m,_,v=t(n.of),b=t.position.getWithinInfo(n.within),y=t.position.getScrollInfo(b),w=(n.collision||"flip").split(" "),k={};return _=s(v),v[0].preventDefault&&(n.at="left top"),p=_.width,f=_.height,g=_.offset,m=t.extend({},g),t.each(["my","at"],function(){var t,e,i=(n[this]||"").split(" ");1===i.length&&(i=r.test(i[0])?i.concat(["center"]):h.test(i[0])?["center"].concat(i):["center","center"]),i[0]=r.test(i[0])?i[0]:"center",i[1]=h.test(i[1])?i[1]:"center",t=l.exec(i[0]),e=l.exec(i[1]),k[this]=[t?t[0]:0,e?e[0]:0],n[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===w.length&&(w[1]=w[0]),"right"===n.at[0]?m.left+=p:"center"===n.at[0]&&(m.left+=p/2),"bottom"===n.at[1]?m.top+=f:"center"===n.at[1]&&(m.top+=f/2),u=e(k.at,p,f),m.left+=u[0],m.top+=u[1],this.each(function(){var s,r,h=t(this),l=h.outerWidth(),c=h.outerHeight(),d=i(this,"marginLeft"),_=i(this,"marginTop"),x=l+d+i(this,"marginRight")+y.width,C=c+_+i(this,"marginBottom")+y.height,D=t.extend({},m),I=e(k.my,h.outerWidth(),h.outerHeight());"right"===n.my[0]?D.left-=l:"center"===n.my[0]&&(D.left-=l/2),"bottom"===n.my[1]?D.top-=c:"center"===n.my[1]&&(D.top-=c/2),D.left+=I[0],D.top+=I[1],s={marginLeft:d,marginTop:_},t.each(["left","top"],function(e,i){t.ui.position[w[e]]&&t.ui.position[w[e]][i](D,{targetWidth:p,targetHeight:f,elemWidth:l,elemHeight:c,collisionPosition:s,collisionWidth:x,collisionHeight:C,offset:[u[0]+I[0],u[1]+I[1]],my:n.my,at:n.at,within:b,elem:h})}),n.using&&(r=function(t){var e=g.left-D.left,i=e+p-l,s=g.top-D.top,r=s+f-c,u={target:{element:v,left:g.left,top:g.top,width:p,height:f},element:{element:h,left:D.left,top:D.top,width:l,height:c},horizontal:0>i?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-h,(i>0||u>a(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}});var c="ui-effects-",u="ui-effects-style",d="ui-effects-animated",p=t;t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:0>t?0:t>s.max?s.max:t)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(t,o){var a,r=o.re.exec(i),h=r&&o.parse(r),l=o.space||"rgba";return h?(a=s[l](h),s[c[l].cache]=a[c[l].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return i=(i+1)%1,1>6*i?t+6*(e-t)*i:1>2*i?e:2>3*i?t+6*(e-t)*(2/3-i):t}var o,a="backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],l=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={"byte":{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=t("<p>")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=p.style.backgroundColor.indexOf("rgba")>-1,f(c,function(t,e){e.cache="_"+t,e.props.alpha={idx:3,type:"percent",def:1}}),l.fn=t.extend(l.prototype,{parse:function(n,a,r,h){if(n===e)return this._rgba=[null,null,null,null],this;(n.jquery||n.nodeType)&&(n=t(n).css(a),a=e);var u=this,d=t.type(n),p=this._rgba=[];return a!==e&&(n=[n,a,r,h],d="array"),"string"===d?this.parse(s(n)||o._default):"array"===d?(f(c.rgba.props,function(t,e){p[e.idx]=i(n[e.idx],e)}),this):"object"===d?(n instanceof l?f(c,function(t,e){n[e.cache]&&(u[e.cache]=n[e.cache].slice())}):f(c,function(e,s){var o=s.cache;f(s.props,function(t,e){if(!u[o]&&s.to){if("alpha"===t||null==n[t])return;u[o]=s.to(u._rgba)}u[o][e.idx]=i(n[t],e,!0)}),u[o]&&0>t.inArray(null,u[o].slice(0,3))&&(u[o][3]=1,s.from&&(u._rgba=s.from(u[o])))}),this):e},is:function(t){var i=l(t),s=!0,n=this;return f(c,function(t,o){var a,r=i[o.cache];return r&&(a=n[o.cache]||o.to&&o.to(n._rgba)||[],f(o.props,function(t,i){return null!=r[i.idx]?s=r[i.idx]===a[i.idx]:e})),s}),s},_space:function(){var t=[],e=this;return f(c,function(i,s){e[s.cache]&&t.push(i)}),t.pop()},transition:function(t,e){var s=l(t),n=s._space(),o=c[n],a=0===this.alpha()?l("transparent"):this,r=a[o.cache]||o.to(a._rgba),h=r.slice();return s=s[o.cache],f(o.props,function(t,n){var o=n.idx,a=r[o],l=s[o],c=u[n.type]||{};null!==l&&(null===a?h[o]=l:(c.mod&&(l-a>c.mod/2?a+=c.mod:a-l>c.mod/2&&(a-=c.mod)),h[o]=i((l-a)*e+a,n)))}),this[n](h)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(e)._rgba;return l(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?e>2?1:0:t});return 1===i[3]&&(i.pop(),e="rgb("),e+i.join()+")"},toHslaString:function(){var e="hsla(",i=t.map(this.hsla(),function(t,e){return null==t&&(t=e>2?1:0),e&&3>e&&(t=Math.round(100*t)+"%"),t});return 1===i[3]&&(i.pop(),e="hsl("),e+i.join()+")"},toHexString:function(e){var i=this._rgba.slice(),s=i.pop();return e&&i.push(~~(255*s)),"#"+t.map(i,function(t){return t=(t||0).toString(16),1===t.length?"0"+t:t}).join("")},toString:function(){return 0===this._rgba[3]?"transparent":this.toRgbaString()}}),l.fn.parse.prototype=l.fn,c.hsla.to=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e,i,s=t[0]/255,n=t[1]/255,o=t[2]/255,a=t[3],r=Math.max(s,n,o),h=Math.min(s,n,o),l=r-h,c=r+h,u=.5*c;return e=h===r?0:s===r?60*(n-o)/l+360:n===r?60*(o-s)/l+120:60*(s-n)/l+240,i=0===l?0:.5>=u?l/c:l/(2-c),[Math.round(e)%360,i,u,null==a?1:a]},c.hsla.from=function(t){if(null==t[0]||null==t[1]||null==t[2])return[null,null,null,t[3]];var e=t[0]/360,i=t[1],s=t[2],o=t[3],a=.5>=s?s*(1+i):s+i-s*i,r=2*s-a;return[Math.round(255*n(r,a,e+1/3)),Math.round(255*n(r,a,e)),Math.round(255*n(r,a,e-1/3)),o]},f(c,function(s,n){var o=n.props,a=n.cache,h=n.to,c=n.from;l.fn[s]=function(s){if(h&&!this[a]&&(this[a]=h(this._rgba)),s===e)return this[a].slice();var n,r=t.type(s),u="array"===r||"object"===r?s:arguments,d=this[a].slice();return f(o,function(t,e){var s=u["object"===r?t:e.idx];null==s&&(s=d[e.idx]),d[e.idx]=i(s,e)}),c?(n=l(c(d)),n[a]=d,n):l(d)},f(o,function(e,i){l.fn[e]||(l.fn[e]=function(n){var o,a=t.type(n),h="alpha"===e?this._hsla?"hsla":"rgba":s,l=this[h](),c=l[i.idx];return"undefined"===a?c:("function"===a&&(n=n.call(this,c),a=t.type(n)),null==n&&i.empty?this:("string"===a&&(o=r.exec(n),o&&(n=c+parseFloat(o[2])*("+"===o[1]?1:-1))),l[i.idx]=n,this[h](l)))})})}),l.hook=function(e){var i=e.split(" ");f(i,function(e,i){t.cssHooks[i]={set:function(e,n){var o,a,r="";if("transparent"!==n&&("string"!==t.type(n)||(o=s(n)))){if(n=l(o||n),!d.rgba&&1!==n._rgba[3]){for(a="backgroundColor"===i?e.parentNode:e;(""===r||"transparent"===r)&&a&&a.style;)try{r=t.css(a,"backgroundColor"),a=a.parentNode}catch(h){}n=n.blend(r&&"transparent"!==r?r:"_default")}n=n.toRgbaString()}try{e.style[i]=n}catch(h){}}},t.fx.step[i]=function(e){e.colorInit||(e.start=l(e.elem,i),e.end=l(e.end),e.colorInit=!0),t.cssHooks[i].set(e.elem,e.start.transition(e.end,e.pos))}})},l.hook(a),t.cssHooks.borderColor={expand:function(t){var e={};return f(["Top","Right","Bottom","Left"],function(i,s){e["border"+s+"Color"]=t}),e}},o=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(p),function(){function e(e){var i,s,n=e.ownerDocument.defaultView?e.ownerDocument.defaultView.getComputedStyle(e,null):e.currentStyle,o={};if(n&&n.length&&n[0]&&n[n[0]])for(s=n.length;s--;)i=n[s],"string"==typeof n[i]&&(o[t.camelCase(i)]=n[i]);else for(i in n)"string"==typeof n[i]&&(o[i]=n[i]);return o}function i(e,i){var s,o,a={};for(s in i)o=i[s],e[s]!==o&&(n[s]||(t.fx.step[s]||!isNaN(parseFloat(o)))&&(a[s]=o));return a}var s=["add","remove","toggle"],n={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};t.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(e,i){t.fx.step[i]=function(t){("none"!==t.end&&!t.setAttr||1===t.pos&&!t.setAttr)&&(p.style(t.elem,i,t.end),t.setAttr=!0)}}),t.fn.addBack||(t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.effects.animateClass=function(n,o,a,r){var h=t.speed(o,a,r);return this.queue(function(){var o,a=t(this),r=a.attr("class")||"",l=h.children?a.find("*").addBack():a;l=l.map(function(){var i=t(this);return{el:i,start:e(this)}}),o=function(){t.each(s,function(t,e){n[e]&&a[e+"Class"](n[e])})},o(),l=l.map(function(){return this.end=e(this.el[0]),this.diff=i(this.start,this.end),this}),a.attr("class",r),l=l.map(function(){var e=this,i=t.Deferred(),s=t.extend({},h,{queue:!1,complete:function(){i.resolve(e)}});return this.el.animate(this.diff,s),i.promise()}),t.when.apply(t,l.get()).done(function(){o(),t.each(arguments,function(){var e=this.el;t.each(this.diff,function(t){e.css(t,"")})}),h.complete.call(a[0])})})},t.fn.extend({addClass:function(e){return function(i,s,n,o){return s?t.effects.animateClass.call(this,{add:i},s,n,o):e.apply(this,arguments)}}(t.fn.addClass),removeClass:function(e){return function(i,s,n,o){return arguments.length>1?t.effects.animateClass.call(this,{remove:i},s,n,o):e.apply(this,arguments)}}(t.fn.removeClass),toggleClass:function(e){return function(i,s,n,o,a){return"boolean"==typeof s||void 0===s?n?t.effects.animateClass.call(this,s?{add:i}:{remove:i},n,o,a):e.apply(this,arguments):t.effects.animateClass.call(this,{toggle:i},s,n,o)}}(t.fn.toggleClass),switchClass:function(e,i,s,n,o){return t.effects.animateClass.call(this,{add:i,remove:e},s,n,o)}})}(),function(){function e(e,i,s,n){return t.isPlainObject(e)&&(i=e,e=e.effect),e={effect:e},null==i&&(i={}),t.isFunction(i)&&(n=i,s=null,i={}),("number"==typeof i||t.fx.speeds[i])&&(n=s,s=i,i={}),t.isFunction(s)&&(n=s,s=null),i&&t.extend(e,i),s=s||i.duration,e.duration=t.fx.off?0:"number"==typeof s?s:s in t.fx.speeds?t.fx.speeds[s]:t.fx.speeds._default,e.complete=n||i.complete,e}function i(e){return!e||"number"==typeof e||t.fx.speeds[e]?!0:"string"!=typeof e||t.effects.effect[e]?t.isFunction(e)?!0:"object"!=typeof e||e.effect?!1:!0:!0}function s(t,e){var i=e.outerWidth(),s=e.outerHeight(),n=/^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,o=n.exec(t)||["",0,i,s,0];return{top:parseFloat(o[1])||0,right:"auto"===o[2]?i:parseFloat(o[2]),bottom:"auto"===o[3]?s:parseFloat(o[3]),left:parseFloat(o[4])||0}}t.expr&&t.expr.filters&&t.expr.filters.animated&&(t.expr.filters.animated=function(e){return function(i){return!!t(i).data(d)||e(i)}}(t.expr.filters.animated)),t.uiBackCompat!==!1&&t.extend(t.effects,{save:function(t,e){for(var i=0,s=e.length;s>i;i++)null!==e[i]&&t.data(c+e[i],t[0].style[e[i]])},restore:function(t,e){for(var i,s=0,n=e.length;n>s;s++)null!==e[s]&&(i=t.data(c+e[s]),t.css(e[s],i))},setMode:function(t,e){return"toggle"===e&&(e=t.is(":hidden")?"show":"hide"),e},createWrapper:function(e){if(e.parent().is(".ui-effects-wrapper"))return e.parent();var i={width:e.outerWidth(!0),height:e.outerHeight(!0),"float":e.css("float")},s=t("<div></div>").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).trigger("focus"),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).trigger("focus")),e}}),t.extend(t.effects,{version:"1.12.1",define:function(e,i,s){return s||(s=i,i="effect"),t.effects.effect[e]=s,t.effects.effect[e].mode=i,s},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,n="vertical"!==i?(e||100)/100:1;return{height:t.height()*n,width:t.width()*s,outerHeight:t.outerHeight()*n,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();e>1&&s.splice.apply(s,[1,0].concat(s.splice(e,i))),t.dequeue()},saveStyle:function(t){t.data(u,t[0].style.cssText)},restoreStyle:function(t){t[0].style.cssText=t.data(u)||"",t.removeData(u)},mode:function(t,e){var i=t.is(":hidden");return"toggle"===e&&(e=i?"show":"hide"),(i?"hide"===e:"show"===e)&&(e="none"),e},getBaseline:function(t,e){var i,s;switch(t[0]){case"top":i=0;break;case"middle":i=.5;break;case"bottom":i=1;break;default:i=t[0]/e.height}switch(t[1]){case"left":s=0;break;case"center":s=.5;break;case"right":s=1;break;default:s=t[1]/e.width}return{x:s,y:i}},createPlaceholder:function(e){var i,s=e.css("position"),n=e.position();return e.css({marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()),/^(static|relative)/.test(s)&&(s="absolute",i=t("<"+e[0].nodeName+">").insertAfter(e).css({display:/^(inline|ruby)/.test(e.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight"),"float":e.css("float")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).addClass("ui-effects-placeholder"),e.data(c+"placeholder",i)),e.css({position:s,left:n.left,top:n.top}),i},removePlaceholder:function(t){var e=c+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(e){t.effects.restoreStyle(e),t.effects.removePlaceholder(e)},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);o[0]>0&&(n[i]=o[0]*s+o[1])}),n}}),t.fn.extend({effect:function(){function i(e){function i(){r.removeData(d),t.effects.cleanUp(r),"hide"===s.mode&&r.hide(),a()}function a(){t.isFunction(h)&&h.call(r[0]),t.isFunction(e)&&e()}var r=t(this);s.mode=c.shift(),t.uiBackCompat===!1||o?"none"===s.mode?(r[l](),a()):n.call(r[0],s,i):(r.is(":hidden")?"hide"===l:"show"===l)?(r[l](),a()):n.call(r[0],s,a)}var s=e.apply(this,arguments),n=t.effects.effect[s.effect],o=n.mode,a=s.queue,r=a||"fx",h=s.complete,l=s.mode,c=[],u=function(e){var i=t(this),s=t.effects.mode(i,l)||o;i.data(d,!0),c.push(s),o&&("show"===s||s===o&&"hide"===s)&&i.show(),o&&"none"===s||t.effects.saveStyle(i),t.isFunction(e)&&e()};return t.fx.off||!n?l?this[l](s.duration,h):this.each(function(){h&&h.call(this)}):a===!1?this.each(u).each(i):this.queue(r,u).queue(r,i)},show:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="show",this.effect.call(this,n)
+}}(t.fn.show),hide:function(t){return function(s){if(i(s))return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="hide",this.effect.call(this,n)}}(t.fn.hide),toggle:function(t){return function(s){if(i(s)||"boolean"==typeof s)return t.apply(this,arguments);var n=e.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)}}(t.fn.toggle),cssUnit:function(e){var i=this.css(e),s=[];return t.each(["em","px","%","pt"],function(t,e){i.indexOf(e)>0&&(s=[parseFloat(i),e])}),s},cssClip:function(t){return t?this.css("clip","rect("+t.top+"px "+t.right+"px "+t.bottom+"px "+t.left+"px)"):s(this.css("clip"),this)},transfer:function(e,i){var s=t(this),n=t(e.to),o="fixed"===n.css("position"),a=t("body"),r=o?a.scrollTop():0,h=o?a.scrollLeft():0,l=n.offset(),c={top:l.top-r,left:l.left-h,height:n.innerHeight(),width:n.innerWidth()},u=s.offset(),d=t("<div class='ui-effects-transfer'></div>").appendTo("body").addClass(e.className).css({top:u.top-r,left:u.left-h,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),t.isFunction(i)&&i()})}}),t.fx.step.clip=function(e){e.clipInit||(e.start=t(e.elem).cssClip(),"string"==typeof e.end&&(e.end=s(e.end,e.elem)),e.clipInit=!0),t(e.elem).cssClip({top:e.pos*(e.end.top-e.start.top)+e.start.top,right:e.pos*(e.end.right-e.start.right)+e.start.right,bottom:e.pos*(e.end.bottom-e.start.bottom)+e.start.bottom,left:e.pos*(e.end.left-e.start.left)+e.start.left})}}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return.5>t?i(2*t)/2:1-i(-2*t+2)/2}})}();var f=t.effects;t.effects.define("blind","hide",function(e,i){var s={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},n=t(this),o=e.direction||"up",a=n.cssClip(),r={clip:t.extend({},a)},h=t.effects.createPlaceholder(n);r.clip[s[o][0]]=r.clip[s[o][1]],"show"===e.mode&&(n.cssClip(r.clip),h&&h.css(t.effects.clipToBox(r)),r.clip=a),h&&h.animate(t.effects.clipToBox(r),e.duration,e.easing),n.animate(r,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("bounce",function(e,i){var s,n,o,a=t(this),r=e.mode,h="hide"===r,l="show"===r,c=e.direction||"up",u=e.distance,d=e.times||5,p=2*d+(l||h?1:0),f=e.duration/p,g=e.easing,m="up"===c||"down"===c?"top":"left",_="up"===c||"left"===c,v=0,b=a.queue().length;for(t.effects.createPlaceholder(a),o=a.css(m),u||(u=a["top"===m?"outerHeight":"outerWidth"]()/3),l&&(n={opacity:1},n[m]=o,a.css("opacity",0).css(m,_?2*-u:2*u).animate(n,f,g)),h&&(u/=Math.pow(2,d-1)),n={},n[m]=o;d>v;v++)s={},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g).animate(n,f,g),u=h?2*u:u/2;h&&(s={opacity:0},s[m]=(_?"-=":"+=")+u,a.animate(s,f,g)),a.queue(i),t.effects.unshift(a,b,p+1)}),t.effects.define("clip","hide",function(e,i){var s,n={},o=t(this),a=e.direction||"vertical",r="both"===a,h=r||"horizontal"===a,l=r||"vertical"===a;s=o.cssClip(),n.clip={top:l?(s.bottom-s.top)/2:s.top,right:h?(s.right-s.left)/2:s.right,bottom:l?(s.bottom-s.top)/2:s.bottom,left:h?(s.right-s.left)/2:s.left},t.effects.createPlaceholder(o),"show"===e.mode&&(o.cssClip(n.clip),n.clip=s),o.animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("drop","hide",function(e,i){var s,n=t(this),o=e.mode,a="show"===o,r=e.direction||"left",h="up"===r||"down"===r?"top":"left",l="up"===r||"left"===r?"-=":"+=",c="+="===l?"-=":"+=",u={opacity:0};t.effects.createPlaceholder(n),s=e.distance||n["top"===h?"outerHeight":"outerWidth"](!0)/2,u[h]=l+s,a&&(n.css(u),u[h]=c+s,u.opacity=1),n.animate(u,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("explode","hide",function(e,i){function s(){b.push(this),b.length===u*d&&n()}function n(){p.css({visibility:"visible"}),t(b).remove(),i()}var o,a,r,h,l,c,u=e.pieces?Math.round(Math.sqrt(e.pieces)):3,d=u,p=t(this),f=e.mode,g="show"===f,m=p.show().css("visibility","hidden").offset(),_=Math.ceil(p.outerWidth()/d),v=Math.ceil(p.outerHeight()/u),b=[];for(o=0;u>o;o++)for(h=m.top+o*v,c=o-(u-1)/2,a=0;d>a;a++)r=m.left+a*_,l=a-(d-1)/2,p.clone().appendTo("body").wrap("<div></div>").css({position:"absolute",visibility:"visible",left:-a*_,top:-o*v}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:_,height:v,left:r+(g?l*_:0),top:h+(g?c*v:0),opacity:g?0:1}).animate({left:r+(g?0:l*_),top:h+(g?0:c*v),opacity:g?1:0},e.duration||500,e.easing,s)}),t.effects.define("fade","toggle",function(e,i){var s="show"===e.mode;t(this).css("opacity",s?0:1).animate({opacity:s?1:0},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fold","hide",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=e.size||15,h=/([0-9]+)%/.exec(r),l=!!e.horizFirst,c=l?["right","bottom"]:["bottom","right"],u=e.duration/2,d=t.effects.createPlaceholder(s),p=s.cssClip(),f={clip:t.extend({},p)},g={clip:t.extend({},p)},m=[p[c[0]],p[c[1]]],_=s.queue().length;h&&(r=parseInt(h[1],10)/100*m[a?0:1]),f.clip[c[0]]=r,g.clip[c[0]]=r,g.clip[c[1]]=0,o&&(s.cssClip(g.clip),d&&d.css(t.effects.clipToBox(g)),g.clip=p),s.queue(function(i){d&&d.animate(t.effects.clipToBox(f),u,e.easing).animate(t.effects.clipToBox(g),u,e.easing),i()}).animate(f,u,e.easing).animate(g,u,e.easing).queue(i),t.effects.unshift(s,_,4)}),t.effects.define("highlight","show",function(e,i){var s=t(this),n={backgroundColor:s.css("backgroundColor")};"hide"===e.mode&&(n.opacity=0),t.effects.saveStyle(s),s.css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("size",function(e,i){var s,n,o,a=t(this),r=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],l=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],c=e.mode,u="effect"!==c,d=e.scale||"both",p=e.origin||["middle","center"],f=a.css("position"),g=a.position(),m=t.effects.scaledDimensions(a),_=e.from||m,v=e.to||t.effects.scaledDimensions(a,0);t.effects.createPlaceholder(a),"show"===c&&(o=_,_=v,v=o),n={from:{y:_.height/m.height,x:_.width/m.width},to:{y:v.height/m.height,x:v.width/m.width}},("box"===d||"both"===d)&&(n.from.y!==n.to.y&&(_=t.effects.setTransition(a,h,n.from.y,_),v=t.effects.setTransition(a,h,n.to.y,v)),n.from.x!==n.to.x&&(_=t.effects.setTransition(a,l,n.from.x,_),v=t.effects.setTransition(a,l,n.to.x,v))),("content"===d||"both"===d)&&n.from.y!==n.to.y&&(_=t.effects.setTransition(a,r,n.from.y,_),v=t.effects.setTransition(a,r,n.to.y,v)),p&&(s=t.effects.getBaseline(p,m),_.top=(m.outerHeight-_.outerHeight)*s.y+g.top,_.left=(m.outerWidth-_.outerWidth)*s.x+g.left,v.top=(m.outerHeight-v.outerHeight)*s.y+g.top,v.left=(m.outerWidth-v.outerWidth)*s.x+g.left),a.css(_),("content"===d||"both"===d)&&(h=h.concat(["marginTop","marginBottom"]).concat(r),l=l.concat(["marginLeft","marginRight"]),a.find("*[width]").each(function(){var i=t(this),s=t.effects.scaledDimensions(i),o={height:s.height*n.from.y,width:s.width*n.from.x,outerHeight:s.outerHeight*n.from.y,outerWidth:s.outerWidth*n.from.x},a={height:s.height*n.to.y,width:s.width*n.to.x,outerHeight:s.height*n.to.y,outerWidth:s.width*n.to.x};n.from.y!==n.to.y&&(o=t.effects.setTransition(i,h,n.from.y,o),a=t.effects.setTransition(i,h,n.to.y,a)),n.from.x!==n.to.x&&(o=t.effects.setTransition(i,l,n.from.x,o),a=t.effects.setTransition(i,l,n.to.x,a)),u&&t.effects.saveStyle(i),i.css(o),i.animate(a,e.duration,e.easing,function(){u&&t.effects.restoreStyle(i)})})),a.animate(v,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){var e=a.offset();0===v.opacity&&a.css("opacity",_.opacity),u||(a.css("position","static"===f?"relative":f).offset(e),t.effects.saveStyle(a)),i()}})}),t.effects.define("scale",function(e,i){var s=t(this),n=e.mode,o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"effect"!==n?0:100),a=t.extend(!0,{from:t.effects.scaledDimensions(s),to:t.effects.scaledDimensions(s,o,e.direction||"both"),origin:e.origin||["middle","center"]},e);e.fade&&(a.from.opacity=1,a.to.opacity=0),t.effects.effect.size.call(this,a,i)}),t.effects.define("puff","hide",function(e,i){var s=t.extend(!0,{},e,{fade:!0,percent:parseInt(e.percent,10)||150});t.effects.effect.scale.call(this,s,i)}),t.effects.define("pulsate","show",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=o||a,h=2*(e.times||5)+(r?1:0),l=e.duration/h,c=0,u=1,d=s.queue().length;for((o||!s.is(":visible"))&&(s.css("opacity",0).show(),c=1);h>u;u++)s.animate({opacity:c},l,e.easing),c=1-c;s.animate({opacity:c},l,e.easing),s.queue(i),t.effects.unshift(s,d,h+1)}),t.effects.define("shake",function(e,i){var s=1,n=t(this),o=e.direction||"left",a=e.distance||20,r=e.times||3,h=2*r+1,l=Math.round(e.duration/h),c="up"===o||"down"===o?"top":"left",u="up"===o||"left"===o,d={},p={},f={},g=n.queue().length;for(t.effects.createPlaceholder(n),d[c]=(u?"-=":"+=")+a,p[c]=(u?"+=":"-=")+2*a,f[c]=(u?"-=":"+=")+2*a,n.animate(d,l,e.easing);r>s;s++)n.animate(p,l,e.easing).animate(f,l,e.easing);n.animate(p,l,e.easing).animate(d,l/2,e.easing).queue(i),t.effects.unshift(n,g,h+1)}),t.effects.define("slide","show",function(e,i){var s,n,o=t(this),a={up:["bottom","top"],down:["top","bottom"],left:["right","left"],right:["left","right"]},r=e.mode,h=e.direction||"left",l="up"===h||"down"===h?"top":"left",c="up"===h||"left"===h,u=e.distance||o["top"===l?"outerHeight":"outerWidth"](!0),d={};t.effects.createPlaceholder(o),s=o.cssClip(),n=o.position()[l],d[l]=(c?-1:1)*u+n,d.clip=o.cssClip(),d.clip[a[h][1]]=d.clip[a[h][0]],"show"===r&&(o.cssClip(d.clip),o.css(l,d[l]),d.clip=s,d[l]=n),o.animate(d,{queue:!1,duration:e.duration,easing:e.easing,complete:i})});var f;t.uiBackCompat!==!1&&(f=t.effects.define("transfer",function(e,i){t(this).transfer(e,i)})),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.widget("ui.accordion",{version:"1.12.1",options:{active:0,animate:{},classes:{"ui-accordion-header":"ui-corner-top","ui-accordion-header-collapsed":"ui-corner-all","ui-accordion-content":"ui-corner-bottom"},collapsible:!1,event:"click",header:"> li > :first-child, > :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),e.collapsible||e.active!==!1&&null!=e.active||(e.active=0),this._processPanels(),0>e.active&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t()}},_createIcons:function(){var e,i,s=this.options.icons;s&&(e=t("<span>"),this._addClass(e,"ui-accordion-header-icon","ui-icon "+s.header),e.prependTo(this.headers),i=this.active.children(".ui-accordion-header-icon"),this._removeClass(i,s.header)._addClass(i,null,s.activeHeader)._addClass(this.headers,"ui-accordion-icons"))},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||this.options.active!==!1||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons()),void 0)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),o=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:o=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:o=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:o=this.headers[0];break;case i.END:o=this.headers[s-1]}o&&(t(e.target).attr("tabIndex",-1),t(o).attr("tabIndex",0),t(o).trigger("focus"),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().trigger("focus")},refresh:function(){var e=this.options;this._processPanels(),e.active===!1&&e.collapsible===!0||!this.headers.length?(e.active=!1,this.active=t()):e.active===!1?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var e,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var e=t(this),i=e.uniqueId().attr("id"),s=e.next(),n=s.uniqueId().attr("id");e.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(e=n.height(),this.element.siblings(":visible").each(function(){var i=t(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(e-=i.outerHeight(!0))}),this.headers.each(function(){e-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,e-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===s&&(e=0,this.headers.next().each(function(){var i=t(this).is(":visible");i||t(this).show(),e=Math.max(e,t(this).css("height","").height()),i||t(this).hide()}).height(e))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i,s,n=this.options,o=this.active,a=t(e.currentTarget),r=a[0]===o[0],h=r&&n.collapsible,l=h?t():a.next(),c=o.next(),u={oldHeader:o,oldPanel:c,newHeader:h?t():a,newPanel:l};e.preventDefault(),r&&!n.collapsible||this._trigger("beforeActivate",e,u)===!1||(n.active=h?!1:this.headers.index(a),this.active=r?t():a,this._toggle(u),this._removeClass(o,"ui-accordion-header-active","ui-state-active"),n.icons&&(i=o.children(".ui-accordion-header-icon"),this._removeClass(i,null,n.icons.activeHeader)._addClass(i,null,n.icons.header)),r||(this._removeClass(a,"ui-accordion-header-collapsed")._addClass(a,"ui-accordion-header-active","ui-state-active"),n.icons&&(s=a.children(".ui-accordion-header-icon"),this._removeClass(s,null,n.icons.header)._addClass(s,null,n.icons.activeHeader)),this._addClass(a.next(),"ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(t(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,e,i){var s,n,o,a=this,r=0,h=t.css("box-sizing"),l=t.length&&(!e.length||t.index()<e.index()),c=this.options.animate||{},u=l&&c.down||c,d=function(){a._toggleComplete(i)};return"number"==typeof u&&(o=u),"string"==typeof u&&(n=u),n=n||u.easing||c.easing,o=o||u.duration||c.duration,e.length?t.length?(s=t.show().outerHeight(),e.animate(this.hideProps,{duration:o,easing:n,step:function(t,e){e.now=Math.round(t)}}),t.hide().animate(this.showProps,{duration:o,easing:n,complete:d,step:function(t,i){i.now=Math.round(t),"height"!==i.prop?"content-box"===h&&(r+=i.now):"content"!==a.options.heightStyle&&(i.now=Math.round(s-e.outerHeight()-r),r=0)}}),void 0):e.animate(this.hideProps,o,n,d):t.animate(this.showProps,o,n,d)},_toggleComplete:function(t){var e=t.oldPanel,i=e.prev();this._removeClass(e,"ui-accordion-content-active"),this._removeClass(i,"ui-accordion-header-active")._addClass(i,"ui-accordion-header-collapsed"),e.length&&(e.parent()[0].className=e.parent()[0].className),this._trigger("activate",null,t)}}),t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.widget("ui.menu",{version:"1.12.1",defaultElement:"<ul>",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(e){var i=t(e.target),s=t(t.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&s.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){if(!this.previousFilter){var i=t(e.target).closest(".ui-menu-item"),s=t(e.currentTarget);i[0]===s[0]&&(this._removeClass(s.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(e,s))}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){var i=!t.contains(this.element[0],t.ui.safeActiveElement(this.document[0]));i&&this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){var e=this.element.find(".ui-menu-item").removeAttr("role aria-disabled"),i=e.children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),i.children().each(function(){var e=t(this);e.data("ui-menu-submenu-caret")&&e.remove()})},_keydown:function(e){var i,s,n,o,a=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:a=!1,s=this.previousFilter||"",o=!1,n=e.keyCode>=96&&105>=e.keyCode?""+(e.keyCode-96):String.fromCharCode(e.keyCode),clearTimeout(this.filterTimer),n===s?o=!0:n=s+n,i=this._filterMenuItems(n),i=o&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(e.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(e,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}a&&e.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i,s,n,o,a=this,r=this.options.icons.submenu,h=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),s=h.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),i=e.prev(),s=t("<span>").data("ui-menu-submenu-caret",!0);a._addClass(s,"ui-menu-icon","ui-icon "+r),i.attr("aria-haspopup","true").prepend(s),e.attr("aria-labelledby",i.attr("id"))}),this._addClass(s,"ui-menu","ui-widget ui-widget-content ui-front"),e=h.add(this.element),i=e.find(this.options.items),i.not(".ui-menu-item").each(function(){var e=t(this);a._isDivider(e)&&a._addClass(e,"ui-menu-divider","ui-widget-content")}),n=i.not(".ui-menu-item, .ui-menu-divider"),o=n.children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(n,"ui-menu-item")._addClass(o,"ui-menu-item-wrapper"),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){if("icons"===t){var i=this.element.find(".ui-menu-icon");this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)}this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t+""),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i,s,n;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.outerHeight(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",t,{item:this.active}),this.active=null)},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this._removeClass(s.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(e){return!t(e.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(e),void 0)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items).first())),void 0):(this.next(e),void 0)},_hasScroll:function(){return this.element.outerHeight()<this.element.prop("scrollHeight")},select:function(e){this.active=this.active||t(e.target).closest(".ui-menu-item");var i={item:this.active};this.active.has(".ui-menu").length||this.collapseAll(e,!0),this._trigger("select",e,i)},_filterMenuItems:function(e){var i=e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&"),s=RegExp("^"+i,"i");return this.activeMenu.find(this.options.items).filter(".ui-menu-item").filter(function(){return s.test(t.trim(t(this).children(".ui-menu-item-wrapper").text()))})}}),t.widget("ui.autocomplete",{version:"1.12.1",defaultElement:"<input>",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n;
+this.isMultiLine=o||!a&&this._isContentEditable(this.element),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,void 0;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),void 0):(this._searchTimeout(t),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(t),this._change(t),void 0)}}),this._initSource(),this.menu=t("<ul>").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,this.element[0]!==t.ui.safeActiveElement(this.document[0])&&this.element.trigger("focus")})},menufocus:function(e,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",e,{item:n})&&e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&t.trim(s).length&&(this.liveRegion.children().hide(),t("<div>").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,i){var s=i.item.data("ui-autocomplete-item"),n=this.previous;this.element[0]!==t.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=n,this._delay(function(){this.previous=n,this.selectedItem=s})),!1!==this._trigger("select",e,{item:s})&&this._value(s.value),this.term=this._value(),this.close(e),this.selectedItem=s}}),this.liveRegion=t("<div>",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(e){var i=this.menu.element[0];return e.target===this.element[0]||e.target===i||t.contains(i,e.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){var e=this.term===this._value(),i=this.menu.element.is(":visible"),s=t.altKey||t.ctrlKey||t.metaKey||t.shiftKey;(!e||e&&!i&&!s)&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length<this.options.minLength?this.close(e):this._trigger("search",e)!==!1?this._search(t):void 0},_search:function(t){this.pending++,this._addClass("ui-autocomplete-loading"),this.cancelSearch=!1,this.source({term:t},this._response())},_response:function(){var e=++this.requestIndex;return t.proxy(function(t){e===this.requestIndex&&this.__response(t),this.pending--,this.pending||this._removeClass("ui-autocomplete-loading")},this)},__response:function(t){t&&(t=this._normalize(t)),this._trigger("response",null,{content:t}),!this.options.disabled&&t&&t.length&&!this.cancelSearch?(this._suggest(t),this._trigger("open")):this._close()},close:function(t){this.cancelSearch=!0,this._close(t)},_close:function(t){this._off(this.document,"mousedown"),this.menu.element.is(":visible")&&(this.menu.element.hide(),this.menu.blur(),this.isNewMenu=!0,this._trigger("close",t))},_change:function(t){this.previous!==this._value()&&this._trigger("change",t,{item:this.selectedItem})},_normalize:function(e){return e.length&&e[0].label&&e[0].value?e:t.map(e,function(e){return"string"==typeof e?{label:e,value:e}:t.extend({},e,{label:e.label||e.value,value:e.value||e.label})})},_suggest:function(e){var i=this.menu.element.empty();this._renderMenu(i,e),this.isNewMenu=!0,this.menu.refresh(),i.show(),this._resizeMenu(),i.position(t.extend({of:this.element},this.options.position)),this.options.autoFocus&&this.menu.next(),this._on(this.document,{mousedown:"_closeOnClickOutside"})},_resizeMenu:function(){var t=this.menu.element;t.outerWidth(Math.max(t.width("").outerWidth()+1,this.element.outerWidth()))},_renderMenu:function(e,i){var s=this;t.each(i,function(t,i){s._renderItemData(e,i)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-autocomplete-item",e)},_renderItem:function(e,i){return t("<li>").append(t("<div>").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[t](e),void 0):(this.search(null,e),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.children().hide(),t("<div>").text(i).appendTo(this.liveRegion))}}),t.ui.autocomplete;var g=/ui-corner-([a-z]){2,6}/g;t.widget("ui.controlgroup",{version:"1.12.1",defaultElement:"<div>",options:{direction:"horizontal",disabled:null,onlyVisible:!0,items:{button:"input[type=button], input[type=submit], input[type=reset], button, a",controlgroupLabel:".ui-controlgroup-label",checkboxradio:"input[type='checkbox'], input[type='radio']",selectmenu:"select",spinner:".ui-spinner-input"}},_create:function(){this._enhance()},_enhance:function(){this.element.attr("role","toolbar"),this.refresh()},_destroy:function(){this._callChildMethod("destroy"),this.childWidgets.removeData("ui-controlgroup-data"),this.element.removeAttr("role"),this.options.items.controlgroupLabel&&this.element.find(this.options.items.controlgroupLabel).find(".ui-controlgroup-label-contents").contents().unwrap()},_initWidgets:function(){var e=this,i=[];t.each(this.options.items,function(s,n){var o,a={};return n?"controlgroupLabel"===s?(o=e.element.find(n),o.each(function(){var e=t(this);e.children(".ui-controlgroup-label-contents").length||e.contents().wrapAll("<span class='ui-controlgroup-label-contents'></span>")}),e._addClass(o,null,"ui-widget ui-widget-content ui-state-default"),i=i.concat(o.get()),void 0):(t.fn[s]&&(a=e["_"+s+"Options"]?e["_"+s+"Options"]("middle"):{classes:{}},e.element.find(n).each(function(){var n=t(this),o=n[s]("instance"),r=t.widget.extend({},a);if("button"!==s||!n.parent(".ui-spinner").length){o||(o=n[s]()[s]("instance")),o&&(r.classes=e._resolveClassesValues(r.classes,o)),n[s](r);var h=n[s]("widget");t.data(h[0],"ui-controlgroup-data",o?o:n[s]("instance")),i.push(h[0])}})),void 0):void 0}),this.childWidgets=t(t.unique(i)),this._addClass(this.childWidgets,"ui-controlgroup-item")},_callChildMethod:function(e){this.childWidgets.each(function(){var i=t(this),s=i.data("ui-controlgroup-data");s&&s[e]&&s[e]()})},_updateCornerClass:function(t,e){var i="ui-corner-top ui-corner-bottom ui-corner-left ui-corner-right ui-corner-all",s=this._buildSimpleOptions(e,"label").classes.label;this._removeClass(t,null,i),this._addClass(t,null,s)},_buildSimpleOptions:function(t,e){var i="vertical"===this.options.direction,s={classes:{}};return s.classes[e]={middle:"",first:"ui-corner-"+(i?"top":"left"),last:"ui-corner-"+(i?"bottom":"right"),only:"ui-corner-all"}[t],s},_spinnerOptions:function(t){var e=this._buildSimpleOptions(t,"ui-spinner");return e.classes["ui-spinner-up"]="",e.classes["ui-spinner-down"]="",e},_buttonOptions:function(t){return this._buildSimpleOptions(t,"ui-button")},_checkboxradioOptions:function(t){return this._buildSimpleOptions(t,"ui-checkboxradio-label")},_selectmenuOptions:function(t){var e="vertical"===this.options.direction;return{width:e?"auto":!1,classes:{middle:{"ui-selectmenu-button-open":"","ui-selectmenu-button-closed":""},first:{"ui-selectmenu-button-open":"ui-corner-"+(e?"top":"tl"),"ui-selectmenu-button-closed":"ui-corner-"+(e?"top":"left")},last:{"ui-selectmenu-button-open":e?"":"ui-corner-tr","ui-selectmenu-button-closed":"ui-corner-"+(e?"bottom":"right")},only:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"}}[t]}},_resolveClassesValues:function(e,i){var s={};return t.each(e,function(n){var o=i.options.classes[n]||"";o=t.trim(o.replace(g,"")),s[n]=(o+" "+e[n]).replace(/\s+/g," ")}),s},_setOption:function(t,e){return"direction"===t&&this._removeClass("ui-controlgroup-"+this.options.direction),this._super(t,e),"disabled"===t?(this._callChildMethod(e?"disable":"enable"),void 0):(this.refresh(),void 0)},refresh:function(){var e,i=this;this._addClass("ui-controlgroup ui-controlgroup-"+this.options.direction),"horizontal"===this.options.direction&&this._addClass(null,"ui-helper-clearfix"),this._initWidgets(),e=this.childWidgets,this.options.onlyVisible&&(e=e.filter(":visible")),e.length&&(t.each(["first","last"],function(t,s){var n=e[s]().data("ui-controlgroup-data");if(n&&i["_"+n.widgetName+"Options"]){var o=i["_"+n.widgetName+"Options"](1===e.length?"only":s);o.classes=i._resolveClassesValues(o.classes,n),n.element[n.widgetName](o)}else i._updateCornerClass(e[s](),s)}),this._callChildMethod("refresh"))}}),t.widget("ui.checkboxradio",[t.ui.formResetMixin,{version:"1.12.1",options:{disabled:null,label:null,icon:!0,classes:{"ui-checkboxradio-label":"ui-corner-all","ui-checkboxradio-icon":"ui-corner-all"}},_getCreateOptions:function(){var e,i,s=this,n=this._super()||{};return this._readType(),i=this.element.labels(),this.label=t(i[i.length-1]),this.label.length||t.error("No label found for checkboxradio widget"),this.originalLabel="",this.label.contents().not(this.element[0]).each(function(){s.originalLabel+=3===this.nodeType?t(this).text():this.outerHTML}),this.originalLabel&&(n.label=this.originalLabel),e=this.element[0].disabled,null!=e&&(n.disabled=e),n},_create:function(){var t=this.element[0].checked;this._bindFormResetHandler(),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled),this._setOption("disabled",this.options.disabled),this._addClass("ui-checkboxradio","ui-helper-hidden-accessible"),this._addClass(this.label,"ui-checkboxradio-label","ui-button ui-widget"),"radio"===this.type&&this._addClass(this.label,"ui-checkboxradio-radio-label"),this.options.label&&this.options.label!==this.originalLabel?this._updateLabel():this.originalLabel&&(this.options.label=this.originalLabel),this._enhance(),t&&(this._addClass(this.label,"ui-checkboxradio-checked","ui-state-active"),this.icon&&this._addClass(this.icon,null,"ui-state-hover")),this._on({change:"_toggleClasses",focus:function(){this._addClass(this.label,null,"ui-state-focus ui-visual-focus")},blur:function(){this._removeClass(this.label,null,"ui-state-focus ui-visual-focus")}})},_readType:function(){var e=this.element[0].nodeName.toLowerCase();this.type=this.element[0].type,"input"===e&&/radio|checkbox/.test(this.type)||t.error("Can't create checkboxradio on element.nodeName="+e+" and element.type="+this.type)},_enhance:function(){this._updateIcon(this.element[0].checked)},widget:function(){return this.label},_getRadioGroup:function(){var e,i=this.element[0].name,s="input[name='"+t.ui.escapeSelector(i)+"']";return i?(e=this.form.length?t(this.form[0].elements).filter(s):t(s).filter(function(){return 0===t(this).form().length}),e.not(this.element)):t([])},_toggleClasses:function(){var e=this.element[0].checked;this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",e),this.options.icon&&"checkbox"===this.type&&this._toggleClass(this.icon,null,"ui-icon-check ui-state-checked",e)._toggleClass(this.icon,null,"ui-icon-blank",!e),"radio"===this.type&&this._getRadioGroup().each(function(){var e=t(this).checkboxradio("instance");e&&e._removeClass(e.label,"ui-checkboxradio-checked","ui-state-active")})},_destroy:function(){this._unbindFormResetHandler(),this.icon&&(this.icon.remove(),this.iconSpace.remove())},_setOption:function(t,e){return"label"!==t||e?(this._super(t,e),"disabled"===t?(this._toggleClass(this.label,null,"ui-state-disabled",e),this.element[0].disabled=e,void 0):(this.refresh(),void 0)):void 0},_updateIcon:function(e){var i="ui-icon ui-icon-background ";this.options.icon?(this.icon||(this.icon=t("<span>"),this.iconSpace=t("<span> </span>"),this._addClass(this.iconSpace,"ui-checkboxradio-icon-space")),"checkbox"===this.type?(i+=e?"ui-icon-check ui-state-checked":"ui-icon-blank",this._removeClass(this.icon,null,e?"ui-icon-blank":"ui-icon-check")):i+="ui-icon-blank",this._addClass(this.icon,"ui-checkboxradio-icon",i),e||this._removeClass(this.icon,null,"ui-icon-check ui-state-checked"),this.icon.prependTo(this.label).after(this.iconSpace)):void 0!==this.icon&&(this.icon.remove(),this.iconSpace.remove(),delete this.icon)},_updateLabel:function(){var t=this.label.contents().not(this.element[0]);this.icon&&(t=t.not(this.icon[0])),this.iconSpace&&(t=t.not(this.iconSpace[0])),t.remove(),this.label.append(this.options.label)},refresh:function(){var t=this.element[0].checked,e=this.element[0].disabled;this._updateIcon(t),this._toggleClass(this.label,"ui-checkboxradio-checked","ui-state-active",t),null!==this.options.label&&this._updateLabel(),e!==this.options.disabled&&this._setOptions({disabled:e})}}]),t.ui.checkboxradio,t.widget("ui.button",{version:"1.12.1",defaultElement:"<button>",options:{classes:{"ui-button":"ui-corner-all"},disabled:null,icon:null,iconPosition:"beginning",label:null,showLabel:!0},_getCreateOptions:function(){var t,e=this._super()||{};return this.isInput=this.element.is("input"),t=this.element[0].disabled,null!=t&&(e.disabled=t),this.originalLabel=this.isInput?this.element.val():this.element.html(),this.originalLabel&&(e.label=this.originalLabel),e},_create:function(){!this.option.showLabel&!this.options.icon&&(this.options.showLabel=!0),null==this.options.disabled&&(this.options.disabled=this.element[0].disabled||!1),this.hasTitle=!!this.element.attr("title"),this.options.label&&this.options.label!==this.originalLabel&&(this.isInput?this.element.val(this.options.label):this.element.html(this.options.label)),this._addClass("ui-button","ui-widget"),this._setOption("disabled",this.options.disabled),this._enhance(),this.element.is("a")&&this._on({keyup:function(e){e.keyCode===t.ui.keyCode.SPACE&&(e.preventDefault(),this.element[0].click?this.element[0].click():this.element.trigger("click"))}})},_enhance:function(){this.element.is("button")||this.element.attr("role","button"),this.options.icon&&(this._updateIcon("icon",this.options.icon),this._updateTooltip())},_updateTooltip:function(){this.title=this.element.attr("title"),this.options.showLabel||this.title||this.element.attr("title",this.options.label)},_updateIcon:function(e,i){var s="iconPosition"!==e,n=s?this.options.iconPosition:i,o="top"===n||"bottom"===n;this.icon?s&&this._removeClass(this.icon,null,this.options.icon):(this.icon=t("<span>"),this._addClass(this.icon,"ui-button-icon","ui-icon"),this.options.showLabel||this._addClass("ui-button-icon-only")),s&&this._addClass(this.icon,null,i),this._attachIcon(n),o?(this._addClass(this.icon,null,"ui-widget-icon-block"),this.iconSpace&&this.iconSpace.remove()):(this.iconSpace||(this.iconSpace=t("<span> </span>"),this._addClass(this.iconSpace,"ui-button-icon-space")),this._removeClass(this.icon,null,"ui-wiget-icon-block"),this._attachIconSpace(n))},_destroy:function(){this.element.removeAttr("role"),this.icon&&this.icon.remove(),this.iconSpace&&this.iconSpace.remove(),this.hasTitle||this.element.removeAttr("title")},_attachIconSpace:function(t){this.icon[/^(?:end|bottom)/.test(t)?"before":"after"](this.iconSpace)},_attachIcon:function(t){this.element[/^(?:end|bottom)/.test(t)?"append":"prepend"](this.icon)},_setOptions:function(t){var e=void 0===t.showLabel?this.options.showLabel:t.showLabel,i=void 0===t.icon?this.options.icon:t.icon;e||i||(t.showLabel=!0),this._super(t)},_setOption:function(t,e){"icon"===t&&(e?this._updateIcon(t,e):this.icon&&(this.icon.remove(),this.iconSpace&&this.iconSpace.remove())),"iconPosition"===t&&this._updateIcon(t,e),"showLabel"===t&&(this._toggleClass("ui-button-icon-only",null,!e),this._updateTooltip()),"label"===t&&(this.isInput?this.element.val(e):(this.element.html(e),this.icon&&(this._attachIcon(this.options.iconPosition),this._attachIconSpace(this.options.iconPosition)))),this._super(t,e),"disabled"===t&&(this._toggleClass(null,"ui-state-disabled",e),this.element[0].disabled=e,e&&this.element.blur())},refresh:function(){var t=this.element.is("input, button")?this.element[0].disabled:this.element.hasClass("ui-button-disabled");t!==this.options.disabled&&this._setOptions({disabled:t}),this._updateTooltip()}}),t.uiBackCompat!==!1&&(t.widget("ui.button",t.ui.button,{options:{text:!0,icons:{primary:null,secondary:null}},_create:function(){this.options.showLabel&&!this.options.text&&(this.options.showLabel=this.options.text),!this.options.showLabel&&this.options.text&&(this.options.text=this.options.showLabel),this.options.icon||!this.options.icons.primary&&!this.options.icons.secondary?this.options.icon&&(this.options.icons.primary=this.options.icon):this.options.icons.primary?this.options.icon=this.options.icons.primary:(this.options.icon=this.options.icons.secondary,this.options.iconPosition="end"),this._super()},_setOption:function(t,e){return"text"===t?(this._super("showLabel",e),void 0):("showLabel"===t&&(this.options.text=e),"icon"===t&&(this.options.icons.primary=e),"icons"===t&&(e.primary?(this._super("icon",e.primary),this._super("iconPosition","beginning")):e.secondary&&(this._super("icon",e.secondary),this._super("iconPosition","end"))),this._superApply(arguments),void 0)}}),t.fn.button=function(e){return function(){return!this.length||this.length&&"INPUT"!==this[0].tagName||this.length&&"INPUT"===this[0].tagName&&"checkbox"!==this.attr("type")&&"radio"!==this.attr("type")?e.apply(this,arguments):(t.ui.checkboxradio||t.error("Checkboxradio widget missing"),0===arguments.length?this.checkboxradio({icon:!1}):this.checkboxradio.apply(this,arguments))}}(t.fn.button),t.fn.buttonset=function(){return t.ui.controlgroup||t.error("Controlgroup widget missing"),"option"===arguments[0]&&"items"===arguments[1]&&arguments[2]?this.controlgroup.apply(this,[arguments[0],"items.button",arguments[2]]):"option"===arguments[0]&&"items"===arguments[1]?this.controlgroup.apply(this,[arguments[0],"items.button"]):("object"==typeof arguments[0]&&arguments[0].items&&(arguments[0].items={button:arguments[0].items}),this.controlgroup.apply(this,arguments))}),t.ui.button,t.extend(t.ui,{datepicker:{version:"1.12.1"}});var m;t.extend(s.prototype,{markerClassName:"hasDatepicker",maxRows:4,_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(t){return a(this._defaults,t||{}),this},_attachDatepicker:function(e,i){var s,n,o;s=e.nodeName.toLowerCase(),n="div"===s||"span"===s,e.id||(this.uuid+=1,e.id="dp"+this.uuid),o=this._newInst(t(e),n),o.settings=t.extend({},i||{}),"input"===s?this._connectDatepicker(e,o):n&&this._inlineDatepicker(e,o)},_newInst:function(e,i){var s=e[0].id.replace(/([^A-Za-z0-9_\-])/g,"\\\\$1");return{id:s,input:e,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:i,dpDiv:i?n(t("<div class='"+this._inlineClass+" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")):this.dpDiv}},_connectDatepicker:function(e,i){var s=t(e);i.append=t([]),i.trigger=t([]),s.hasClass(this.markerClassName)||(this._attachments(s,i),s.addClass(this.markerClassName).on("keydown",this._doKeyDown).on("keypress",this._doKeyPress).on("keyup",this._doKeyUp),this._autoSize(i),t.data(e,"datepicker",i),i.settings.disabled&&this._disableDatepicker(e))},_attachments:function(e,i){var s,n,o,a=this._get(i,"appendText"),r=this._get(i,"isRTL");i.append&&i.append.remove(),a&&(i.append=t("<span class='"+this._appendClass+"'>"+a+"</span>"),e[r?"before":"after"](i.append)),e.off("focus",this._showDatepicker),i.trigger&&i.trigger.remove(),s=this._get(i,"showOn"),("focus"===s||"both"===s)&&e.on("focus",this._showDatepicker),("button"===s||"both"===s)&&(n=this._get(i,"buttonText"),o=this._get(i,"buttonImage"),i.trigger=t(this._get(i,"buttonImageOnly")?t("<img/>").addClass(this._triggerClass).attr({src:o,alt:n,title:n}):t("<button type='button'></button>").addClass(this._triggerClass).html(o?t("<img/>").attr({src:o,alt:n,title:n}):n)),e[r?"before":"after"](i.trigger),i.trigger.on("click",function(){return t.datepicker._datepickerShowing&&t.datepicker._lastInput===e[0]?t.datepicker._hideDatepicker():t.datepicker._datepickerShowing&&t.datepicker._lastInput!==e[0]?(t.datepicker._hideDatepicker(),t.datepicker._showDatepicker(e[0])):t.datepicker._showDatepicker(e[0]),!1}))},_autoSize:function(t){if(this._get(t,"autoSize")&&!t.inline){var e,i,s,n,o=new Date(2009,11,20),a=this._get(t,"dateFormat");a.match(/[DM]/)&&(e=function(t){for(i=0,s=0,n=0;t.length>n;n++)t[n].length>i&&(i=t[n].length,s=n);return s},o.setMonth(e(this._get(t,a.match(/MM/)?"monthNames":"monthNamesShort"))),o.setDate(e(this._get(t,a.match(/DD/)?"dayNames":"dayNamesShort"))+20-o.getDay())),t.input.attr("size",this._formatDate(t,o).length)}},_inlineDatepicker:function(e,i){var s=t(e);s.hasClass(this.markerClassName)||(s.addClass(this.markerClassName).append(i.dpDiv),t.data(e,"datepicker",i),this._setDate(i,this._getDefaultDate(i),!0),this._updateDatepicker(i),this._updateAlternate(i),i.settings.disabled&&this._disableDatepicker(e),i.dpDiv.css("display","block"))},_dialogDatepicker:function(e,i,s,n,o){var r,h,l,c,u,d=this._dialogInst;return d||(this.uuid+=1,r="dp"+this.uuid,this._dialogInput=t("<input type='text' id='"+r+"' style='position: absolute; top: -100px; width: 0px;'/>"),this._dialogInput.on("keydown",this._doKeyDown),t("body").append(this._dialogInput),d=this._dialogInst=this._newInst(this._dialogInput,!1),d.settings={},t.data(this._dialogInput[0],"datepicker",d)),a(d.settings,n||{}),i=i&&i.constructor===Date?this._formatDate(d,i):i,this._dialogInput.val(i),this._pos=o?o.length?o:[o.pageX,o.pageY]:null,this._pos||(h=document.documentElement.clientWidth,l=document.documentElement.clientHeight,c=document.documentElement.scrollLeft||document.body.scrollLeft,u=document.documentElement.scrollTop||document.body.scrollTop,this._pos=[h/2-100+c,l/2-150+u]),this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+"px"),d.settings.onSelect=s,this._inDialog=!0,this.dpDiv.addClass(this._dialogClass),this._showDatepicker(this._dialogInput[0]),t.blockUI&&t.blockUI(this.dpDiv),t.data(this._dialogInput[0],"datepicker",d),this},_destroyDatepicker:function(e){var i,s=t(e),n=t.data(e,"datepicker");s.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),t.removeData(e,"datepicker"),"input"===i?(n.append.remove(),n.trigger.remove(),s.removeClass(this.markerClassName).off("focus",this._showDatepicker).off("keydown",this._doKeyDown).off("keypress",this._doKeyPress).off("keyup",this._doKeyUp)):("div"===i||"span"===i)&&s.removeClass(this.markerClassName).empty(),m===n&&(m=null))},_enableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!1,o.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().removeClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!1)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}))},_disableDatepicker:function(e){var i,s,n=t(e),o=t.data(e,"datepicker");n.hasClass(this.markerClassName)&&(i=e.nodeName.toLowerCase(),"input"===i?(e.disabled=!0,o.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"})):("div"===i||"span"===i)&&(s=n.children("."+this._inlineClass),s.children().addClass("ui-state-disabled"),s.find("select.ui-datepicker-month, select.ui-datepicker-year").prop("disabled",!0)),this._disabledInputs=t.map(this._disabledInputs,function(t){return t===e?null:t}),this._disabledInputs[this._disabledInputs.length]=e)},_isDisabledDatepicker:function(t){if(!t)return!1;for(var e=0;this._disabledInputs.length>e;e++)if(this._disabledInputs[e]===t)return!0;return!1},_getInst:function(e){try{return t.data(e,"datepicker")}catch(i){throw"Missing instance data for this datepicker"}},_optionDatepicker:function(e,i,s){var n,o,r,h,l=this._getInst(e);return 2===arguments.length&&"string"==typeof i?"defaults"===i?t.extend({},t.datepicker._defaults):l?"all"===i?t.extend({},l.settings):this._get(l,i):null:(n=i||{},"string"==typeof i&&(n={},n[i]=s),l&&(this._curInst===l&&this._hideDatepicker(),o=this._getDateDatepicker(e,!0),r=this._getMinMaxDate(l,"min"),h=this._getMinMaxDate(l,"max"),a(l.settings,n),null!==r&&void 0!==n.dateFormat&&void 0===n.minDate&&(l.settings.minDate=this._formatDate(l,r)),null!==h&&void 0!==n.dateFormat&&void 0===n.maxDate&&(l.settings.maxDate=this._formatDate(l,h)),"disabled"in n&&(n.disabled?this._disableDatepicker(e):this._enableDatepicker(e)),this._attachments(t(e),l),this._autoSize(l),this._setDate(l,o),this._updateAlternate(l),this._updateDatepicker(l)),void 0)},_changeDatepicker:function(t,e,i){this._optionDatepicker(t,e,i)},_refreshDatepicker:function(t){var e=this._getInst(t);e&&this._updateDatepicker(e)},_setDateDatepicker:function(t,e){var i=this._getInst(t);i&&(this._setDate(i,e),this._updateDatepicker(i),this._updateAlternate(i))},_getDateDatepicker:function(t,e){var i=this._getInst(t);return i&&!i.inline&&this._setDateFromField(i,e),i?this._getDate(i):null},_doKeyDown:function(e){var i,s,n,o=t.datepicker._getInst(e.target),a=!0,r=o.dpDiv.is(".ui-datepicker-rtl");if(o._keyEvent=!0,t.datepicker._datepickerShowing)switch(e.keyCode){case 9:t.datepicker._hideDatepicker(),a=!1;break;case 13:return n=t("td."+t.datepicker._dayOverClass+":not(."+t.datepicker._currentClass+")",o.dpDiv),n[0]&&t.datepicker._selectDay(e.target,o.selectedMonth,o.selectedYear,n[0]),i=t.datepicker._get(o,"onSelect"),i?(s=t.datepicker._formatDate(o),i.apply(o.input?o.input[0]:null,[s,o])):t.datepicker._hideDatepicker(),!1;case 27:t.datepicker._hideDatepicker();break;case 33:t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 34:t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 35:(e.ctrlKey||e.metaKey)&&t.datepicker._clearDate(e.target),a=e.ctrlKey||e.metaKey;break;case 36:(e.ctrlKey||e.metaKey)&&t.datepicker._gotoToday(e.target),a=e.ctrlKey||e.metaKey;break;case 37:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?1:-1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?-t.datepicker._get(o,"stepBigMonths"):-t.datepicker._get(o,"stepMonths"),"M");break;case 38:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,-7,"D"),a=e.ctrlKey||e.metaKey;break;case 39:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,r?-1:1,"D"),a=e.ctrlKey||e.metaKey,e.originalEvent.altKey&&t.datepicker._adjustDate(e.target,e.ctrlKey?+t.datepicker._get(o,"stepBigMonths"):+t.datepicker._get(o,"stepMonths"),"M");break;case 40:(e.ctrlKey||e.metaKey)&&t.datepicker._adjustDate(e.target,7,"D"),a=e.ctrlKey||e.metaKey;break;default:a=!1}else 36===e.keyCode&&e.ctrlKey?t.datepicker._showDatepicker(this):a=!1;a&&(e.preventDefault(),e.stopPropagation())},_doKeyPress:function(e){var i,s,n=t.datepicker._getInst(e.target);return t.datepicker._get(n,"constrainInput")?(i=t.datepicker._possibleChars(t.datepicker._get(n,"dateFormat")),s=String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),e.ctrlKey||e.metaKey||" ">s||!i||i.indexOf(s)>-1):void 0},_doKeyUp:function(e){var i,s=t.datepicker._getInst(e.target);if(s.input.val()!==s.lastVal)try{i=t.datepicker.parseDate(t.datepicker._get(s,"dateFormat"),s.input?s.input.val():null,t.datepicker._getFormatConfig(s)),i&&(t.datepicker._setDateFromField(s),t.datepicker._updateAlternate(s),t.datepicker._updateDatepicker(s))}catch(n){}return!0},_showDatepicker:function(e){if(e=e.target||e,"input"!==e.nodeName.toLowerCase()&&(e=t("input",e.parentNode)[0]),!t.datepicker._isDisabledDatepicker(e)&&t.datepicker._lastInput!==e){var s,n,o,r,h,l,c;s=t.datepicker._getInst(e),t.datepicker._curInst&&t.datepicker._curInst!==s&&(t.datepicker._curInst.dpDiv.stop(!0,!0),s&&t.datepicker._datepickerShowing&&t.datepicker._hideDatepicker(t.datepicker._curInst.input[0])),n=t.datepicker._get(s,"beforeShow"),o=n?n.apply(e,[e,s]):{},o!==!1&&(a(s.settings,o),s.lastVal=null,t.datepicker._lastInput=e,t.datepicker._setDateFromField(s),t.datepicker._inDialog&&(e.value=""),t.datepicker._pos||(t.datepicker._pos=t.datepicker._findPos(e),t.datepicker._pos[1]+=e.offsetHeight),r=!1,t(e).parents().each(function(){return r|="fixed"===t(this).css("position"),!r}),h={left:t.datepicker._pos[0],top:t.datepicker._pos[1]},t.datepicker._pos=null,s.dpDiv.empty(),s.dpDiv.css({position:"absolute",display:"block",top:"-1000px"}),t.datepicker._updateDatepicker(s),h=t.datepicker._checkOffset(s,h,r),s.dpDiv.css({position:t.datepicker._inDialog&&t.blockUI?"static":r?"fixed":"absolute",display:"none",left:h.left+"px",top:h.top+"px"}),s.inline||(l=t.datepicker._get(s,"showAnim"),c=t.datepicker._get(s,"duration"),s.dpDiv.css("z-index",i(t(e))+1),t.datepicker._datepickerShowing=!0,t.effects&&t.effects.effect[l]?s.dpDiv.show(l,t.datepicker._get(s,"showOptions"),c):s.dpDiv[l||"show"](l?c:null),t.datepicker._shouldFocusInput(s)&&s.input.trigger("focus"),t.datepicker._curInst=s))
+}},_updateDatepicker:function(e){this.maxRows=4,m=e,e.dpDiv.empty().append(this._generateHTML(e)),this._attachHandlers(e);var i,s=this._getNumberOfMonths(e),n=s[1],a=17,r=e.dpDiv.find("."+this._dayOverClass+" a");r.length>0&&o.apply(r.get(0)),e.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width(""),n>1&&e.dpDiv.addClass("ui-datepicker-multi-"+n).css("width",a*n+"em"),e.dpDiv[(1!==s[0]||1!==s[1]?"add":"remove")+"Class"]("ui-datepicker-multi"),e.dpDiv[(this._get(e,"isRTL")?"add":"remove")+"Class"]("ui-datepicker-rtl"),e===t.datepicker._curInst&&t.datepicker._datepickerShowing&&t.datepicker._shouldFocusInput(e)&&e.input.trigger("focus"),e.yearshtml&&(i=e.yearshtml,setTimeout(function(){i===e.yearshtml&&e.yearshtml&&e.dpDiv.find("select.ui-datepicker-year:first").replaceWith(e.yearshtml),i=e.yearshtml=null},0))},_shouldFocusInput:function(t){return t.input&&t.input.is(":visible")&&!t.input.is(":disabled")&&!t.input.is(":focus")},_checkOffset:function(e,i,s){var n=e.dpDiv.outerWidth(),o=e.dpDiv.outerHeight(),a=e.input?e.input.outerWidth():0,r=e.input?e.input.outerHeight():0,h=document.documentElement.clientWidth+(s?0:t(document).scrollLeft()),l=document.documentElement.clientHeight+(s?0:t(document).scrollTop());return i.left-=this._get(e,"isRTL")?n-a:0,i.left-=s&&i.left===e.input.offset().left?t(document).scrollLeft():0,i.top-=s&&i.top===e.input.offset().top+r?t(document).scrollTop():0,i.left-=Math.min(i.left,i.left+n>h&&h>n?Math.abs(i.left+n-h):0),i.top-=Math.min(i.top,i.top+o>l&&l>o?Math.abs(o+r):0),i},_findPos:function(e){for(var i,s=this._getInst(e),n=this._get(s,"isRTL");e&&("hidden"===e.type||1!==e.nodeType||t.expr.filters.hidden(e));)e=e[n?"previousSibling":"nextSibling"];return i=t(e).offset(),[i.left,i.top]},_hideDatepicker:function(e){var i,s,n,o,a=this._curInst;!a||e&&a!==t.data(e,"datepicker")||this._datepickerShowing&&(i=this._get(a,"showAnim"),s=this._get(a,"duration"),n=function(){t.datepicker._tidyDialog(a)},t.effects&&(t.effects.effect[i]||t.effects[i])?a.dpDiv.hide(i,t.datepicker._get(a,"showOptions"),s,n):a.dpDiv["slideDown"===i?"slideUp":"fadeIn"===i?"fadeOut":"hide"](i?s:null,n),i||n(),this._datepickerShowing=!1,o=this._get(a,"onClose"),o&&o.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a]),this._lastInput=null,this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),t.blockUI&&(t.unblockUI(),t("body").append(this.dpDiv))),this._inDialog=!1)},_tidyDialog:function(t){t.dpDiv.removeClass(this._dialogClass).off(".ui-datepicker-calendar")},_checkExternalClick:function(e){if(t.datepicker._curInst){var i=t(e.target),s=t.datepicker._getInst(i[0]);(i[0].id!==t.datepicker._mainDivId&&0===i.parents("#"+t.datepicker._mainDivId).length&&!i.hasClass(t.datepicker.markerClassName)&&!i.closest("."+t.datepicker._triggerClass).length&&t.datepicker._datepickerShowing&&(!t.datepicker._inDialog||!t.blockUI)||i.hasClass(t.datepicker.markerClassName)&&t.datepicker._curInst!==s)&&t.datepicker._hideDatepicker()}},_adjustDate:function(e,i,s){var n=t(e),o=this._getInst(n[0]);this._isDisabledDatepicker(n[0])||(this._adjustInstDate(o,i+("M"===s?this._get(o,"showCurrentAtPos"):0),s),this._updateDatepicker(o))},_gotoToday:function(e){var i,s=t(e),n=this._getInst(s[0]);this._get(n,"gotoCurrent")&&n.currentDay?(n.selectedDay=n.currentDay,n.drawMonth=n.selectedMonth=n.currentMonth,n.drawYear=n.selectedYear=n.currentYear):(i=new Date,n.selectedDay=i.getDate(),n.drawMonth=n.selectedMonth=i.getMonth(),n.drawYear=n.selectedYear=i.getFullYear()),this._notifyChange(n),this._adjustDate(s)},_selectMonthYear:function(e,i,s){var n=t(e),o=this._getInst(n[0]);o["selected"+("M"===s?"Month":"Year")]=o["draw"+("M"===s?"Month":"Year")]=parseInt(i.options[i.selectedIndex].value,10),this._notifyChange(o),this._adjustDate(n)},_selectDay:function(e,i,s,n){var o,a=t(e);t(n).hasClass(this._unselectableClass)||this._isDisabledDatepicker(a[0])||(o=this._getInst(a[0]),o.selectedDay=o.currentDay=t("a",n).html(),o.selectedMonth=o.currentMonth=i,o.selectedYear=o.currentYear=s,this._selectDate(e,this._formatDate(o,o.currentDay,o.currentMonth,o.currentYear)))},_clearDate:function(e){var i=t(e);this._selectDate(i,"")},_selectDate:function(e,i){var s,n=t(e),o=this._getInst(n[0]);i=null!=i?i:this._formatDate(o),o.input&&o.input.val(i),this._updateAlternate(o),s=this._get(o,"onSelect"),s?s.apply(o.input?o.input[0]:null,[i,o]):o.input&&o.input.trigger("change"),o.inline?this._updateDatepicker(o):(this._hideDatepicker(),this._lastInput=o.input[0],"object"!=typeof o.input[0]&&o.input.trigger("focus"),this._lastInput=null)},_updateAlternate:function(e){var i,s,n,o=this._get(e,"altField");o&&(i=this._get(e,"altFormat")||this._get(e,"dateFormat"),s=this._getDate(e),n=this.formatDate(i,s,this._getFormatConfig(e)),t(o).val(n))},noWeekends:function(t){var e=t.getDay();return[e>0&&6>e,""]},iso8601Week:function(t){var e,i=new Date(t.getTime());return i.setDate(i.getDate()+4-(i.getDay()||7)),e=i.getTime(),i.setMonth(0),i.setDate(1),Math.floor(Math.round((e-i)/864e5)/7)+1},parseDate:function(e,i,s){if(null==e||null==i)throw"Invalid arguments";if(i="object"==typeof i?""+i:i+"",""===i)return null;var n,o,a,r,h=0,l=(s?s.shortYearCutoff:null)||this._defaults.shortYearCutoff,c="string"!=typeof l?l:(new Date).getFullYear()%100+parseInt(l,10),u=(s?s.dayNamesShort:null)||this._defaults.dayNamesShort,d=(s?s.dayNames:null)||this._defaults.dayNames,p=(s?s.monthNamesShort:null)||this._defaults.monthNamesShort,f=(s?s.monthNames:null)||this._defaults.monthNames,g=-1,m=-1,_=-1,v=-1,b=!1,y=function(t){var i=e.length>n+1&&e.charAt(n+1)===t;return i&&n++,i},w=function(t){var e=y(t),s="@"===t?14:"!"===t?20:"y"===t&&e?4:"o"===t?3:2,n="y"===t?s:1,o=RegExp("^\\d{"+n+","+s+"}"),a=i.substring(h).match(o);if(!a)throw"Missing number at position "+h;return h+=a[0].length,parseInt(a[0],10)},k=function(e,s,n){var o=-1,a=t.map(y(e)?n:s,function(t,e){return[[e,t]]}).sort(function(t,e){return-(t[1].length-e[1].length)});if(t.each(a,function(t,e){var s=e[1];return i.substr(h,s.length).toLowerCase()===s.toLowerCase()?(o=e[0],h+=s.length,!1):void 0}),-1!==o)return o+1;throw"Unknown name at position "+h},x=function(){if(i.charAt(h)!==e.charAt(n))throw"Unexpected literal at position "+h;h++};for(n=0;e.length>n;n++)if(b)"'"!==e.charAt(n)||y("'")?x():b=!1;else switch(e.charAt(n)){case"d":_=w("d");break;case"D":k("D",u,d);break;case"o":v=w("o");break;case"m":m=w("m");break;case"M":m=k("M",p,f);break;case"y":g=w("y");break;case"@":r=new Date(w("@")),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"!":r=new Date((w("!")-this._ticksTo1970)/1e4),g=r.getFullYear(),m=r.getMonth()+1,_=r.getDate();break;case"'":y("'")?x():b=!0;break;default:x()}if(i.length>h&&(a=i.substr(h),!/^\s+/.test(a)))throw"Extra/unparsed characters found in date: "+a;if(-1===g?g=(new Date).getFullYear():100>g&&(g+=(new Date).getFullYear()-(new Date).getFullYear()%100+(c>=g?0:-100)),v>-1)for(m=1,_=v;;){if(o=this._getDaysInMonth(g,m-1),o>=_)break;m++,_-=o}if(r=this._daylightSavingAdjust(new Date(g,m-1,_)),r.getFullYear()!==g||r.getMonth()+1!==m||r.getDate()!==_)throw"Invalid date";return r},ATOM:"yy-mm-dd",COOKIE:"D, dd M yy",ISO_8601:"yy-mm-dd",RFC_822:"D, d M y",RFC_850:"DD, dd-M-y",RFC_1036:"D, d M y",RFC_1123:"D, d M yy",RFC_2822:"D, d M yy",RSS:"D, d M y",TICKS:"!",TIMESTAMP:"@",W3C:"yy-mm-dd",_ticksTo1970:1e7*60*60*24*(718685+Math.floor(492.5)-Math.floor(19.7)+Math.floor(4.925)),formatDate:function(t,e,i){if(!e)return"";var s,n=(i?i.dayNamesShort:null)||this._defaults.dayNamesShort,o=(i?i.dayNames:null)||this._defaults.dayNames,a=(i?i.monthNamesShort:null)||this._defaults.monthNamesShort,r=(i?i.monthNames:null)||this._defaults.monthNames,h=function(e){var i=t.length>s+1&&t.charAt(s+1)===e;return i&&s++,i},l=function(t,e,i){var s=""+e;if(h(t))for(;i>s.length;)s="0"+s;return s},c=function(t,e,i,s){return h(t)?s[e]:i[e]},u="",d=!1;if(e)for(s=0;t.length>s;s++)if(d)"'"!==t.charAt(s)||h("'")?u+=t.charAt(s):d=!1;else switch(t.charAt(s)){case"d":u+=l("d",e.getDate(),2);break;case"D":u+=c("D",e.getDay(),n,o);break;case"o":u+=l("o",Math.round((new Date(e.getFullYear(),e.getMonth(),e.getDate()).getTime()-new Date(e.getFullYear(),0,0).getTime())/864e5),3);break;case"m":u+=l("m",e.getMonth()+1,2);break;case"M":u+=c("M",e.getMonth(),a,r);break;case"y":u+=h("y")?e.getFullYear():(10>e.getFullYear()%100?"0":"")+e.getFullYear()%100;break;case"@":u+=e.getTime();break;case"!":u+=1e4*e.getTime()+this._ticksTo1970;break;case"'":h("'")?u+="'":d=!0;break;default:u+=t.charAt(s)}return u},_possibleChars:function(t){var e,i="",s=!1,n=function(i){var s=t.length>e+1&&t.charAt(e+1)===i;return s&&e++,s};for(e=0;t.length>e;e++)if(s)"'"!==t.charAt(e)||n("'")?i+=t.charAt(e):s=!1;else switch(t.charAt(e)){case"d":case"m":case"y":case"@":i+="0123456789";break;case"D":case"M":return null;case"'":n("'")?i+="'":s=!0;break;default:i+=t.charAt(e)}return i},_get:function(t,e){return void 0!==t.settings[e]?t.settings[e]:this._defaults[e]},_setDateFromField:function(t,e){if(t.input.val()!==t.lastVal){var i=this._get(t,"dateFormat"),s=t.lastVal=t.input?t.input.val():null,n=this._getDefaultDate(t),o=n,a=this._getFormatConfig(t);try{o=this.parseDate(i,s,a)||n}catch(r){s=e?"":s}t.selectedDay=o.getDate(),t.drawMonth=t.selectedMonth=o.getMonth(),t.drawYear=t.selectedYear=o.getFullYear(),t.currentDay=s?o.getDate():0,t.currentMonth=s?o.getMonth():0,t.currentYear=s?o.getFullYear():0,this._adjustInstDate(t)}},_getDefaultDate:function(t){return this._restrictMinMax(t,this._determineDate(t,this._get(t,"defaultDate"),new Date))},_determineDate:function(e,i,s){var n=function(t){var e=new Date;return e.setDate(e.getDate()+t),e},o=function(i){try{return t.datepicker.parseDate(t.datepicker._get(e,"dateFormat"),i,t.datepicker._getFormatConfig(e))}catch(s){}for(var n=(i.toLowerCase().match(/^c/)?t.datepicker._getDate(e):null)||new Date,o=n.getFullYear(),a=n.getMonth(),r=n.getDate(),h=/([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,l=h.exec(i);l;){switch(l[2]||"d"){case"d":case"D":r+=parseInt(l[1],10);break;case"w":case"W":r+=7*parseInt(l[1],10);break;case"m":case"M":a+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a));break;case"y":case"Y":o+=parseInt(l[1],10),r=Math.min(r,t.datepicker._getDaysInMonth(o,a))}l=h.exec(i)}return new Date(o,a,r)},a=null==i||""===i?s:"string"==typeof i?o(i):"number"==typeof i?isNaN(i)?s:n(i):new Date(i.getTime());return a=a&&"Invalid Date"==""+a?s:a,a&&(a.setHours(0),a.setMinutes(0),a.setSeconds(0),a.setMilliseconds(0)),this._daylightSavingAdjust(a)},_daylightSavingAdjust:function(t){return t?(t.setHours(t.getHours()>12?t.getHours()+2:0),t):null},_setDate:function(t,e,i){var s=!e,n=t.selectedMonth,o=t.selectedYear,a=this._restrictMinMax(t,this._determineDate(t,e,new Date));t.selectedDay=t.currentDay=a.getDate(),t.drawMonth=t.selectedMonth=t.currentMonth=a.getMonth(),t.drawYear=t.selectedYear=t.currentYear=a.getFullYear(),n===t.selectedMonth&&o===t.selectedYear||i||this._notifyChange(t),this._adjustInstDate(t),t.input&&t.input.val(s?"":this._formatDate(t))},_getDate:function(t){var e=!t.currentYear||t.input&&""===t.input.val()?null:this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return e},_attachHandlers:function(e){var i=this._get(e,"stepMonths"),s="#"+e.id.replace(/\\\\/g,"\\");e.dpDiv.find("[data-handler]").map(function(){var e={prev:function(){t.datepicker._adjustDate(s,-i,"M")},next:function(){t.datepicker._adjustDate(s,+i,"M")},hide:function(){t.datepicker._hideDatepicker()},today:function(){t.datepicker._gotoToday(s)},selectDay:function(){return t.datepicker._selectDay(s,+this.getAttribute("data-month"),+this.getAttribute("data-year"),this),!1},selectMonth:function(){return t.datepicker._selectMonthYear(s,this,"M"),!1},selectYear:function(){return t.datepicker._selectMonthYear(s,this,"Y"),!1}};t(this).on(this.getAttribute("data-event"),e[this.getAttribute("data-handler")])})},_generateHTML:function(t){var e,i,s,n,o,a,r,h,l,c,u,d,p,f,g,m,_,v,b,y,w,k,x,C,D,I,T,P,M,S,H,z,O,A,N,W,E,F,L,R=new Date,B=this._daylightSavingAdjust(new Date(R.getFullYear(),R.getMonth(),R.getDate())),Y=this._get(t,"isRTL"),j=this._get(t,"showButtonPanel"),q=this._get(t,"hideIfNoPrevNext"),K=this._get(t,"navigationAsDateFormat"),U=this._getNumberOfMonths(t),V=this._get(t,"showCurrentAtPos"),$=this._get(t,"stepMonths"),X=1!==U[0]||1!==U[1],G=this._daylightSavingAdjust(t.currentDay?new Date(t.currentYear,t.currentMonth,t.currentDay):new Date(9999,9,9)),Q=this._getMinMaxDate(t,"min"),J=this._getMinMaxDate(t,"max"),Z=t.drawMonth-V,te=t.drawYear;if(0>Z&&(Z+=12,te--),J)for(e=this._daylightSavingAdjust(new Date(J.getFullYear(),J.getMonth()-U[0]*U[1]+1,J.getDate())),e=Q&&Q>e?Q:e;this._daylightSavingAdjust(new Date(te,Z,1))>e;)Z--,0>Z&&(Z=11,te--);for(t.drawMonth=Z,t.drawYear=te,i=this._get(t,"prevText"),i=K?this.formatDate(i,this._daylightSavingAdjust(new Date(te,Z-$,1)),this._getFormatConfig(t)):i,s=this._canAdjustMonth(t,-1,te,Z)?"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>":q?"":"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+i+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"e":"w")+"'>"+i+"</span></a>",n=this._get(t,"nextText"),n=K?this.formatDate(n,this._daylightSavingAdjust(new Date(te,Z+$,1)),this._getFormatConfig(t)):n,o=this._canAdjustMonth(t,1,te,Z)?"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>":q?"":"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+n+"'><span class='ui-icon ui-icon-circle-triangle-"+(Y?"w":"e")+"'>"+n+"</span></a>",a=this._get(t,"currentText"),r=this._get(t,"gotoCurrent")&&t.currentDay?G:B,a=K?this.formatDate(a,r,this._getFormatConfig(t)):a,h=t.inline?"":"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>"+this._get(t,"closeText")+"</button>",l=j?"<div class='ui-datepicker-buttonpane ui-widget-content'>"+(Y?h:"")+(this._isInRange(t,r)?"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'>"+a+"</button>":"")+(Y?"":h)+"</div>":"",c=parseInt(this._get(t,"firstDay"),10),c=isNaN(c)?0:c,u=this._get(t,"showWeek"),d=this._get(t,"dayNames"),p=this._get(t,"dayNamesMin"),f=this._get(t,"monthNames"),g=this._get(t,"monthNamesShort"),m=this._get(t,"beforeShowDay"),_=this._get(t,"showOtherMonths"),v=this._get(t,"selectOtherMonths"),b=this._getDefaultDate(t),y="",k=0;U[0]>k;k++){for(x="",this.maxRows=4,C=0;U[1]>C;C++){if(D=this._daylightSavingAdjust(new Date(te,Z,t.selectedDay)),I=" ui-corner-all",T="",X){if(T+="<div class='ui-datepicker-group",U[1]>1)switch(C){case 0:T+=" ui-datepicker-group-first",I=" ui-corner-"+(Y?"right":"left");break;case U[1]-1:T+=" ui-datepicker-group-last",I=" ui-corner-"+(Y?"left":"right");break;default:T+=" ui-datepicker-group-middle",I=""}T+="'>"}for(T+="<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix"+I+"'>"+(/all|left/.test(I)&&0===k?Y?o:s:"")+(/all|right/.test(I)&&0===k?Y?s:o:"")+this._generateMonthYearHeader(t,Z,te,Q,J,k>0||C>0,f,g)+"</div><table class='ui-datepicker-calendar'><thead>"+"<tr>",P=u?"<th class='ui-datepicker-week-col'>"+this._get(t,"weekHeader")+"</th>":"",w=0;7>w;w++)M=(w+c)%7,P+="<th scope='col'"+((w+c+6)%7>=5?" class='ui-datepicker-week-end'":"")+">"+"<span title='"+d[M]+"'>"+p[M]+"</span></th>";for(T+=P+"</tr></thead><tbody>",S=this._getDaysInMonth(te,Z),te===t.selectedYear&&Z===t.selectedMonth&&(t.selectedDay=Math.min(t.selectedDay,S)),H=(this._getFirstDayOfMonth(te,Z)-c+7)%7,z=Math.ceil((H+S)/7),O=X?this.maxRows>z?this.maxRows:z:z,this.maxRows=O,A=this._daylightSavingAdjust(new Date(te,Z,1-H)),N=0;O>N;N++){for(T+="<tr>",W=u?"<td class='ui-datepicker-week-col'>"+this._get(t,"calculateWeek")(A)+"</td>":"",w=0;7>w;w++)E=m?m.apply(t.input?t.input[0]:null,[A]):[!0,""],F=A.getMonth()!==Z,L=F&&!v||!E[0]||Q&&Q>A||J&&A>J,W+="<td class='"+((w+c+6)%7>=5?" ui-datepicker-week-end":"")+(F?" ui-datepicker-other-month":"")+(A.getTime()===D.getTime()&&Z===t.selectedMonth&&t._keyEvent||b.getTime()===A.getTime()&&b.getTime()===D.getTime()?" "+this._dayOverClass:"")+(L?" "+this._unselectableClass+" ui-state-disabled":"")+(F&&!_?"":" "+E[1]+(A.getTime()===G.getTime()?" "+this._currentClass:"")+(A.getTime()===B.getTime()?" ui-datepicker-today":""))+"'"+(F&&!_||!E[2]?"":" title='"+E[2].replace(/'/g,"&#39;")+"'")+(L?"":" data-handler='selectDay' data-event='click' data-month='"+A.getMonth()+"' data-year='"+A.getFullYear()+"'")+">"+(F&&!_?"&#xa0;":L?"<span class='ui-state-default'>"+A.getDate()+"</span>":"<a class='ui-state-default"+(A.getTime()===B.getTime()?" ui-state-highlight":"")+(A.getTime()===G.getTime()?" ui-state-active":"")+(F?" ui-priority-secondary":"")+"' href='#'>"+A.getDate()+"</a>")+"</td>",A.setDate(A.getDate()+1),A=this._daylightSavingAdjust(A);T+=W+"</tr>"}Z++,Z>11&&(Z=0,te++),T+="</tbody></table>"+(X?"</div>"+(U[0]>0&&C===U[1]-1?"<div class='ui-datepicker-row-break'></div>":""):""),x+=T}y+=x}return y+=l,t._keyEvent=!1,y},_generateMonthYearHeader:function(t,e,i,s,n,o,a,r){var h,l,c,u,d,p,f,g,m=this._get(t,"changeMonth"),_=this._get(t,"changeYear"),v=this._get(t,"showMonthAfterYear"),b="<div class='ui-datepicker-title'>",y="";if(o||!m)y+="<span class='ui-datepicker-month'>"+a[e]+"</span>";else{for(h=s&&s.getFullYear()===i,l=n&&n.getFullYear()===i,y+="<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>",c=0;12>c;c++)(!h||c>=s.getMonth())&&(!l||n.getMonth()>=c)&&(y+="<option value='"+c+"'"+(c===e?" selected='selected'":"")+">"+r[c]+"</option>");y+="</select>"}if(v||(b+=y+(!o&&m&&_?"":"&#xa0;")),!t.yearshtml)if(t.yearshtml="",o||!_)b+="<span class='ui-datepicker-year'>"+i+"</span>";else{for(u=this._get(t,"yearRange").split(":"),d=(new Date).getFullYear(),p=function(t){var e=t.match(/c[+\-].*/)?i+parseInt(t.substring(1),10):t.match(/[+\-].*/)?d+parseInt(t,10):parseInt(t,10);return isNaN(e)?d:e},f=p(u[0]),g=Math.max(f,p(u[1]||"")),f=s?Math.max(f,s.getFullYear()):f,g=n?Math.min(g,n.getFullYear()):g,t.yearshtml+="<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";g>=f;f++)t.yearshtml+="<option value='"+f+"'"+(f===i?" selected='selected'":"")+">"+f+"</option>";t.yearshtml+="</select>",b+=t.yearshtml,t.yearshtml=null}return b+=this._get(t,"yearSuffix"),v&&(b+=(!o&&m&&_?"":"&#xa0;")+y),b+="</div>"},_adjustInstDate:function(t,e,i){var s=t.selectedYear+("Y"===i?e:0),n=t.selectedMonth+("M"===i?e:0),o=Math.min(t.selectedDay,this._getDaysInMonth(s,n))+("D"===i?e:0),a=this._restrictMinMax(t,this._daylightSavingAdjust(new Date(s,n,o)));t.selectedDay=a.getDate(),t.drawMonth=t.selectedMonth=a.getMonth(),t.drawYear=t.selectedYear=a.getFullYear(),("M"===i||"Y"===i)&&this._notifyChange(t)},_restrictMinMax:function(t,e){var i=this._getMinMaxDate(t,"min"),s=this._getMinMaxDate(t,"max"),n=i&&i>e?i:e;return s&&n>s?s:n},_notifyChange:function(t){var e=this._get(t,"onChangeMonthYear");e&&e.apply(t.input?t.input[0]:null,[t.selectedYear,t.selectedMonth+1,t])},_getNumberOfMonths:function(t){var e=this._get(t,"numberOfMonths");return null==e?[1,1]:"number"==typeof e?[1,e]:e},_getMinMaxDate:function(t,e){return this._determineDate(t,this._get(t,e+"Date"),null)},_getDaysInMonth:function(t,e){return 32-this._daylightSavingAdjust(new Date(t,e,32)).getDate()},_getFirstDayOfMonth:function(t,e){return new Date(t,e,1).getDay()},_canAdjustMonth:function(t,e,i,s){var n=this._getNumberOfMonths(t),o=this._daylightSavingAdjust(new Date(i,s+(0>e?e:n[0]*n[1]),1));return 0>e&&o.setDate(this._getDaysInMonth(o.getFullYear(),o.getMonth())),this._isInRange(t,o)},_isInRange:function(t,e){var i,s,n=this._getMinMaxDate(t,"min"),o=this._getMinMaxDate(t,"max"),a=null,r=null,h=this._get(t,"yearRange");return h&&(i=h.split(":"),s=(new Date).getFullYear(),a=parseInt(i[0],10),r=parseInt(i[1],10),i[0].match(/[+\-].*/)&&(a+=s),i[1].match(/[+\-].*/)&&(r+=s)),(!n||e.getTime()>=n.getTime())&&(!o||e.getTime()<=o.getTime())&&(!a||e.getFullYear()>=a)&&(!r||r>=e.getFullYear())},_getFormatConfig:function(t){var e=this._get(t,"shortYearCutoff");return e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),{shortYearCutoff:e,dayNamesShort:this._get(t,"dayNamesShort"),dayNames:this._get(t,"dayNames"),monthNamesShort:this._get(t,"monthNamesShort"),monthNames:this._get(t,"monthNames")}},_formatDate:function(t,e,i,s){e||(t.currentDay=t.selectedDay,t.currentMonth=t.selectedMonth,t.currentYear=t.selectedYear);var n=e?"object"==typeof e?e:this._daylightSavingAdjust(new Date(s,i,e)):this._daylightSavingAdjust(new Date(t.currentYear,t.currentMonth,t.currentDay));return this.formatDate(this._get(t,"dateFormat"),n,this._getFormatConfig(t))}}),t.fn.datepicker=function(e){if(!this.length)return this;t.datepicker.initialized||(t(document).on("mousedown",t.datepicker._checkExternalClick),t.datepicker.initialized=!0),0===t("#"+t.datepicker._mainDivId).length&&t("body").append(t.datepicker.dpDiv);var i=Array.prototype.slice.call(arguments,1);return"string"!=typeof e||"isDisabled"!==e&&"getDate"!==e&&"widget"!==e?"option"===e&&2===arguments.length&&"string"==typeof arguments[1]?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i)):this.each(function(){"string"==typeof e?t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this].concat(i)):t.datepicker._attachDatepicker(this,e)}):t.datepicker["_"+e+"Datepicker"].apply(t.datepicker,[this[0]].concat(i))},t.datepicker=new s,t.datepicker.initialized=!1,t.datepicker.uuid=(new Date).getTime(),t.datepicker.version="1.12.1",t.datepicker,t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var _=!1;t(document).on("mouseup",function(){_=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!_){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,n="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!n&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),_=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,_=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.ui.safeBlur=function(e){e&&"body"!==e.nodeName.toLowerCase()&&t(e).trigger("blur")},t.widget("ui.draggable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1,drag:null,start:null,stop:null},_create:function(){"original"===this.options.helper&&this._setPositionRelative(),this.options.addClasses&&this._addClass("ui-draggable"),this._setHandleClassName(),this._mouseInit()},_setOption:function(t,e){this._super(t,e),"handle"===t&&(this._removeHandleClassName(),this._setHandleClassName())},_destroy:function(){return(this.helper||this.element).is(".ui-draggable-dragging")?(this.destroyOnClear=!0,void 0):(this._removeHandleClassName(),this._mouseDestroy(),void 0)},_mouseCapture:function(e){var i=this.options;return this.helper||i.disabled||t(e.target).closest(".ui-resizable-handle").length>0?!1:(this.handle=this._getHandle(e),this.handle?(this._blurActiveElement(e),this._blockFrames(i.iframeFix===!0?"iframe":i.iframeFix),!0):!1)},_blockFrames:function(e){this.iframeBlocks=this.document.find(e).map(function(){var e=t(this);return t("<div>").css("position","absolute").appendTo(e.parent()).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_blurActiveElement:function(e){var i=t.ui.safeActiveElement(this.document[0]),s=t(e.target);s.closest(i).length||t.ui.safeBlur(i)},_mouseStart:function(e){var i=this.options;return this.helper=this._createHelper(e),this._addClass(this.helper,"ui-draggable-dragging"),this._cacheHelperProportions(),t.ui.ddmanager&&(t.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(!0),this.offsetParent=this.helper.offsetParent(),this.hasFixedAncestor=this.helper.parents().filter(function(){return"fixed"===t(this).css("position")}).length>0,this.positionAbs=this.element.offset(),this._refreshOffsets(e),this.originalPosition=this.position=this._generatePosition(e,!1),this.originalPageX=e.pageX,this.originalPageY=e.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this._setContainment(),this._trigger("start",e)===!1?(this._clear(),!1):(this._cacheHelperProportions(),t.ui.ddmanager&&!i.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this._mouseDrag(e,!0),t.ui.ddmanager&&t.ui.ddmanager.dragStart(this,e),!0)},_refreshOffsets:function(t){this.offset={top:this.positionAbs.top-this.margins.top,left:this.positionAbs.left-this.margins.left,scroll:!1,parent:this._getParentOffset(),relative:this._getRelativeOffset()},this.offset.click={left:t.pageX-this.offset.left,top:t.pageY-this.offset.top}},_mouseDrag:function(e,i){if(this.hasFixedAncestor&&(this.offset.parent=this._getParentOffset()),this.position=this._generatePosition(e,!0),this.positionAbs=this._convertPositionTo("absolute"),!i){var s=this._uiHash();if(this._trigger("drag",e,s)===!1)return this._mouseUp(new t.Event("mouseup",e)),!1;this.position=s.position}return this.helper[0].style.left=this.position.left+"px",this.helper[0].style.top=this.position.top+"px",t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),!1},_mouseStop:function(e){var i=this,s=!1;return t.ui.ddmanager&&!this.options.dropBehaviour&&(s=t.ui.ddmanager.drop(this,e)),this.dropped&&(s=this.dropped,this.dropped=!1),"invalid"===this.options.revert&&!s||"valid"===this.options.revert&&s||this.options.revert===!0||t.isFunction(this.options.revert)&&this.options.revert.call(this.element,s)?t(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){i._trigger("stop",e)!==!1&&i._clear()}):this._trigger("stop",e)!==!1&&this._clear(),!1},_mouseUp:function(e){return this._unblockFrames(),t.ui.ddmanager&&t.ui.ddmanager.dragStop(this,e),this.handleElement.is(e.target)&&this.element.trigger("focus"),t.ui.mouse.prototype._mouseUp.call(this,e)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp(new t.Event("mouseup",{target:this.element[0]})):this._clear(),this},_getHandle:function(e){return this.options.handle?!!t(e.target).closest(this.element.find(this.options.handle)).length:!0},_setHandleClassName:function(){this.handleElement=this.options.handle?this.element.find(this.options.handle):this.element,this._addClass(this.handleElement,"ui-draggable-handle")},_removeHandleClassName:function(){this._removeClass(this.handleElement,"ui-draggable-handle")},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper),n=s?t(i.helper.apply(this.element[0],[e])):"clone"===i.helper?this.element.clone().removeAttr("id"):this.element;return n.parents("body").length||n.appendTo("parent"===i.appendTo?this.element[0].parentNode:i.appendTo),s&&n[0]===this.element[0]&&this._setPositionRelative(),n[0]===this.element[0]||/(fixed|absolute)/.test(n.css("position"))||n.css("position","absolute"),n},_setPositionRelative:function(){/^(?:r|a|f)/.test(this.element.css("position"))||(this.element[0].style.position="relative")},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_isRootNode:function(t){return/(html|body)/i.test(t.tagName)||t===this.document[0]},_getParentOffset:function(){var e=this.offsetParent.offset(),i=this.document[0];return"absolute"===this.cssPosition&&this.scrollParent[0]!==i&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),this._isRootNode(this.offsetParent[0])&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"!==this.cssPosition)return{top:0,left:0};var t=this.element.position(),e=this._isRootNode(this.scrollParent[0]);return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+(e?0:this.scrollParent.scrollTop()),left:t.left-(parseInt(this.helper.css("left"),10)||0)+(e?0:this.scrollParent.scrollLeft())}
+},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options,o=this.document[0];return this.relativeContainer=null,n.containment?"window"===n.containment?(this.containment=[t(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,t(window).scrollLeft()+t(window).width()-this.helperProportions.width-this.margins.left,t(window).scrollTop()+(t(window).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):"document"===n.containment?(this.containment=[0,0,t(o).width()-this.helperProportions.width-this.margins.left,(t(o).height()||o.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top],void 0):n.containment.constructor===Array?(this.containment=n.containment,void 0):("parent"===n.containment&&(n.containment=this.helper[0].parentNode),i=t(n.containment),s=i[0],s&&(e=/(scroll|auto)/.test(i.css("overflow")),this.containment=[(parseInt(i.css("borderLeftWidth"),10)||0)+(parseInt(i.css("paddingLeft"),10)||0),(parseInt(i.css("borderTopWidth"),10)||0)+(parseInt(i.css("paddingTop"),10)||0),(e?Math.max(s.scrollWidth,s.offsetWidth):s.offsetWidth)-(parseInt(i.css("borderRightWidth"),10)||0)-(parseInt(i.css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(e?Math.max(s.scrollHeight,s.offsetHeight):s.offsetHeight)-(parseInt(i.css("borderBottomWidth"),10)||0)-(parseInt(i.css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relativeContainer=i),void 0):(this.containment=null,void 0)},_convertPositionTo:function(t,e){e||(e=this.position);var i="absolute"===t?1:-1,s=this._isRootNode(this.scrollParent[0]);return{top:e.top+this.offset.relative.top*i+this.offset.parent.top*i-("fixed"===this.cssPosition?-this.offset.scroll.top:s?0:this.offset.scroll.top)*i,left:e.left+this.offset.relative.left*i+this.offset.parent.left*i-("fixed"===this.cssPosition?-this.offset.scroll.left:s?0:this.offset.scroll.left)*i}},_generatePosition:function(t,e){var i,s,n,o,a=this.options,r=this._isRootNode(this.scrollParent[0]),h=t.pageX,l=t.pageY;return r&&this.offset.scroll||(this.offset.scroll={top:this.scrollParent.scrollTop(),left:this.scrollParent.scrollLeft()}),e&&(this.containment&&(this.relativeContainer?(s=this.relativeContainer.offset(),i=[this.containment[0]+s.left,this.containment[1]+s.top,this.containment[2]+s.left,this.containment[3]+s.top]):i=this.containment,t.pageX-this.offset.click.left<i[0]&&(h=i[0]+this.offset.click.left),t.pageY-this.offset.click.top<i[1]&&(l=i[1]+this.offset.click.top),t.pageX-this.offset.click.left>i[2]&&(h=i[2]+this.offset.click.left),t.pageY-this.offset.click.top>i[3]&&(l=i[3]+this.offset.click.top)),a.grid&&(n=a.grid[1]?this.originalPageY+Math.round((l-this.originalPageY)/a.grid[1])*a.grid[1]:this.originalPageY,l=i?n-this.offset.click.top>=i[1]||n-this.offset.click.top>i[3]?n:n-this.offset.click.top>=i[1]?n-a.grid[1]:n+a.grid[1]:n,o=a.grid[0]?this.originalPageX+Math.round((h-this.originalPageX)/a.grid[0])*a.grid[0]:this.originalPageX,h=i?o-this.offset.click.left>=i[0]||o-this.offset.click.left>i[2]?o:o-this.offset.click.left>=i[0]?o-a.grid[0]:o+a.grid[0]:o),"y"===a.axis&&(h=this.originalPageX),"x"===a.axis&&(l=this.originalPageY)),{top:l-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.offset.scroll.top:r?0:this.offset.scroll.top),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.offset.scroll.left:r?0:this.offset.scroll.left)}},_clear:function(){this._removeClass(this.helper,"ui-draggable-dragging"),this.helper[0]===this.element[0]||this.cancelHelperRemoval||this.helper.remove(),this.helper=null,this.cancelHelperRemoval=!1,this.destroyOnClear&&this.destroy()},_trigger:function(e,i,s){return s=s||this._uiHash(),t.ui.plugin.call(this,e,[i,s,this],!0),/^(drag|start|stop)/.test(e)&&(this.positionAbs=this._convertPositionTo("absolute"),s.offset=this.positionAbs),t.Widget.prototype._trigger.call(this,e,i,s)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}}),t.ui.plugin.add("draggable","connectToSortable",{start:function(e,i,s){var n=t.extend({},i,{item:s.element});s.sortables=[],t(s.options.connectToSortable).each(function(){var i=t(this).sortable("instance");i&&!i.options.disabled&&(s.sortables.push(i),i.refreshPositions(),i._trigger("activate",e,n))})},stop:function(e,i,s){var n=t.extend({},i,{item:s.element});s.cancelHelperRemoval=!1,t.each(s.sortables,function(){var t=this;t.isOver?(t.isOver=0,s.cancelHelperRemoval=!0,t.cancelHelperRemoval=!1,t._storedCSS={position:t.placeholder.css("position"),top:t.placeholder.css("top"),left:t.placeholder.css("left")},t._mouseStop(e),t.options.helper=t.options._helper):(t.cancelHelperRemoval=!0,t._trigger("deactivate",e,n))})},drag:function(e,i,s){t.each(s.sortables,function(){var n=!1,o=this;o.positionAbs=s.positionAbs,o.helperProportions=s.helperProportions,o.offset.click=s.offset.click,o._intersectsWith(o.containerCache)&&(n=!0,t.each(s.sortables,function(){return this.positionAbs=s.positionAbs,this.helperProportions=s.helperProportions,this.offset.click=s.offset.click,this!==o&&this._intersectsWith(this.containerCache)&&t.contains(o.element[0],this.element[0])&&(n=!1),n})),n?(o.isOver||(o.isOver=1,s._parent=i.helper.parent(),o.currentItem=i.helper.appendTo(o.element).data("ui-sortable-item",!0),o.options._helper=o.options.helper,o.options.helper=function(){return i.helper[0]},e.target=o.currentItem[0],o._mouseCapture(e,!0),o._mouseStart(e,!0,!0),o.offset.click.top=s.offset.click.top,o.offset.click.left=s.offset.click.left,o.offset.parent.left-=s.offset.parent.left-o.offset.parent.left,o.offset.parent.top-=s.offset.parent.top-o.offset.parent.top,s._trigger("toSortable",e),s.dropped=o.element,t.each(s.sortables,function(){this.refreshPositions()}),s.currentItem=s.element,o.fromOutside=s),o.currentItem&&(o._mouseDrag(e),i.position=o.position)):o.isOver&&(o.isOver=0,o.cancelHelperRemoval=!0,o.options._revert=o.options.revert,o.options.revert=!1,o._trigger("out",e,o._uiHash(o)),o._mouseStop(e,!0),o.options.revert=o.options._revert,o.options.helper=o.options._helper,o.placeholder&&o.placeholder.remove(),i.helper.appendTo(s._parent),s._refreshOffsets(e),i.position=s._generatePosition(e,!0),s._trigger("fromSortable",e),s.dropped=!1,t.each(s.sortables,function(){this.refreshPositions()}))})}}),t.ui.plugin.add("draggable","cursor",{start:function(e,i,s){var n=t("body"),o=s.options;n.css("cursor")&&(o._cursor=n.css("cursor")),n.css("cursor",o.cursor)},stop:function(e,i,s){var n=s.options;n._cursor&&t("body").css("cursor",n._cursor)}}),t.ui.plugin.add("draggable","opacity",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("opacity")&&(o._opacity=n.css("opacity")),n.css("opacity",o.opacity)},stop:function(e,i,s){var n=s.options;n._opacity&&t(i.helper).css("opacity",n._opacity)}}),t.ui.plugin.add("draggable","scroll",{start:function(t,e,i){i.scrollParentNotHidden||(i.scrollParentNotHidden=i.helper.scrollParent(!1)),i.scrollParentNotHidden[0]!==i.document[0]&&"HTML"!==i.scrollParentNotHidden[0].tagName&&(i.overflowOffset=i.scrollParentNotHidden.offset())},drag:function(e,i,s){var n=s.options,o=!1,a=s.scrollParentNotHidden[0],r=s.document[0];a!==r&&"HTML"!==a.tagName?(n.axis&&"x"===n.axis||(s.overflowOffset.top+a.offsetHeight-e.pageY<n.scrollSensitivity?a.scrollTop=o=a.scrollTop+n.scrollSpeed:e.pageY-s.overflowOffset.top<n.scrollSensitivity&&(a.scrollTop=o=a.scrollTop-n.scrollSpeed)),n.axis&&"y"===n.axis||(s.overflowOffset.left+a.offsetWidth-e.pageX<n.scrollSensitivity?a.scrollLeft=o=a.scrollLeft+n.scrollSpeed:e.pageX-s.overflowOffset.left<n.scrollSensitivity&&(a.scrollLeft=o=a.scrollLeft-n.scrollSpeed))):(n.axis&&"x"===n.axis||(e.pageY-t(r).scrollTop()<n.scrollSensitivity?o=t(r).scrollTop(t(r).scrollTop()-n.scrollSpeed):t(window).height()-(e.pageY-t(r).scrollTop())<n.scrollSensitivity&&(o=t(r).scrollTop(t(r).scrollTop()+n.scrollSpeed))),n.axis&&"y"===n.axis||(e.pageX-t(r).scrollLeft()<n.scrollSensitivity?o=t(r).scrollLeft(t(r).scrollLeft()-n.scrollSpeed):t(window).width()-(e.pageX-t(r).scrollLeft())<n.scrollSensitivity&&(o=t(r).scrollLeft(t(r).scrollLeft()+n.scrollSpeed)))),o!==!1&&t.ui.ddmanager&&!n.dropBehaviour&&t.ui.ddmanager.prepareOffsets(s,e)}}),t.ui.plugin.add("draggable","snap",{start:function(e,i,s){var n=s.options;s.snapElements=[],t(n.snap.constructor!==String?n.snap.items||":data(ui-draggable)":n.snap).each(function(){var e=t(this),i=e.offset();this!==s.element[0]&&s.snapElements.push({item:this,width:e.outerWidth(),height:e.outerHeight(),top:i.top,left:i.left})})},drag:function(e,i,s){var n,o,a,r,h,l,c,u,d,p,f=s.options,g=f.snapTolerance,m=i.offset.left,_=m+s.helperProportions.width,v=i.offset.top,b=v+s.helperProportions.height;for(d=s.snapElements.length-1;d>=0;d--)h=s.snapElements[d].left-s.margins.left,l=h+s.snapElements[d].width,c=s.snapElements[d].top-s.margins.top,u=c+s.snapElements[d].height,h-g>_||m>l+g||c-g>b||v>u+g||!t.contains(s.snapElements[d].item.ownerDocument,s.snapElements[d].item)?(s.snapElements[d].snapping&&s.options.snap.release&&s.options.snap.release.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=!1):("inner"!==f.snapMode&&(n=g>=Math.abs(c-b),o=g>=Math.abs(u-v),a=g>=Math.abs(h-_),r=g>=Math.abs(l-m),n&&(i.position.top=s._convertPositionTo("relative",{top:c-s.helperProportions.height,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h-s.helperProportions.width}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l}).left)),p=n||o||a||r,"outer"!==f.snapMode&&(n=g>=Math.abs(c-v),o=g>=Math.abs(u-b),a=g>=Math.abs(h-m),r=g>=Math.abs(l-_),n&&(i.position.top=s._convertPositionTo("relative",{top:c,left:0}).top),o&&(i.position.top=s._convertPositionTo("relative",{top:u-s.helperProportions.height,left:0}).top),a&&(i.position.left=s._convertPositionTo("relative",{top:0,left:h}).left),r&&(i.position.left=s._convertPositionTo("relative",{top:0,left:l-s.helperProportions.width}).left)),!s.snapElements[d].snapping&&(n||o||a||r||p)&&s.options.snap.snap&&s.options.snap.snap.call(s.element,e,t.extend(s._uiHash(),{snapItem:s.snapElements[d].item})),s.snapElements[d].snapping=n||o||a||r||p)}}),t.ui.plugin.add("draggable","stack",{start:function(e,i,s){var n,o=s.options,a=t.makeArray(t(o.stack)).sort(function(e,i){return(parseInt(t(e).css("zIndex"),10)||0)-(parseInt(t(i).css("zIndex"),10)||0)});a.length&&(n=parseInt(t(a[0]).css("zIndex"),10)||0,t(a).each(function(e){t(this).css("zIndex",n+e)}),this.css("zIndex",n+a.length))}}),t.ui.plugin.add("draggable","zIndex",{start:function(e,i,s){var n=t(i.helper),o=s.options;n.css("zIndex")&&(o._zIndex=n.css("zIndex")),n.css("zIndex",o.zIndex)},stop:function(e,i,s){var n=s.options;n._zIndex&&t(i.helper).css("zIndex",n._zIndex)}}),t.ui.draggable,t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("<div>"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,n=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,o=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,g=s.maxWidth&&p>s.maxWidth,m=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),g&&(p-=l),m&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable,t.widget("ui.dialog",{version:"1.12.1",options:{appendTo:"body",autoOpen:!0,buttons:[],classes:{"ui-dialog":"ui-corner-all","ui-dialog-titlebar":"ui-corner-all"},closeOnEscape:!0,closeText:"Close",draggable:!0,hide:null,height:"auto",maxHeight:null,maxWidth:null,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(e){var i=t(this).css(e).offset().top;0>i&&t(this).css("top",e.top-i)}},resizable:!0,show:null,title:null,width:300,beforeClose:null,close:null,drag:null,dragStart:null,dragStop:null,focus:null,open:null,resize:null,resizeStart:null,resizeStop:null},sizeRelatedOptions:{buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},resizableRelatedOptions:{maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},_create:function(){this.originalCss={display:this.element[0].style.display,width:this.element[0].style.width,minHeight:this.element[0].style.minHeight,maxHeight:this.element[0].style.maxHeight,height:this.element[0].style.height},this.originalPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.originalTitle=this.element.attr("title"),null==this.options.title&&null!=this.originalTitle&&(this.options.title=this.originalTitle),this.options.disabled&&(this.options.disabled=!1),this._createWrapper(),this.element.show().removeAttr("title").appendTo(this.uiDialog),this._addClass("ui-dialog-content","ui-widget-content"),this._createTitlebar(),this._createButtonPane(),this.options.draggable&&t.fn.draggable&&this._makeDraggable(),this.options.resizable&&t.fn.resizable&&this._makeResizable(),this._isOpen=!1,this._trackFocus()},_init:function(){this.options.autoOpen&&this.open()},_appendTo:function(){var e=this.options.appendTo;return e&&(e.jquery||e.nodeType)?t(e):this.document.find(e||"body").eq(0)},_destroy:function(){var t,e=this.originalPosition;this._untrackInstance(),this._destroyOverlay(),this.element.removeUniqueId().css(this.originalCss).detach(),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),t=e.parent.children().eq(e.index),t.length&&t[0]!==this.element[0]?t.before(this.element):e.parent.append(this.element)},widget:function(){return this.uiDialog
+},disable:t.noop,enable:t.noop,close:function(e){var i=this;this._isOpen&&this._trigger("beforeClose",e)!==!1&&(this._isOpen=!1,this._focusedElement=null,this._destroyOverlay(),this._untrackInstance(),this.opener.filter(":focusable").trigger("focus").length||t.ui.safeBlur(t.ui.safeActiveElement(this.document[0])),this._hide(this.uiDialog,this.options.hide,function(){i._trigger("close",e)}))},isOpen:function(){return this._isOpen},moveToTop:function(){this._moveToTop()},_moveToTop:function(e,i){var s=!1,n=this.uiDialog.siblings(".ui-front:visible").map(function(){return+t(this).css("z-index")}).get(),o=Math.max.apply(null,n);return o>=+this.uiDialog.css("z-index")&&(this.uiDialog.css("z-index",o+1),s=!0),s&&!i&&this._trigger("focus",e),s},open:function(){var e=this;return this._isOpen?(this._moveToTop()&&this._focusTabbable(),void 0):(this._isOpen=!0,this.opener=t(t.ui.safeActiveElement(this.document[0])),this._size(),this._position(),this._createOverlay(),this._moveToTop(null,!0),this.overlay&&this.overlay.css("z-index",this.uiDialog.css("z-index")-1),this._show(this.uiDialog,this.options.show,function(){e._focusTabbable(),e._trigger("focus")}),this._makeFocusTarget(),this._trigger("open"),void 0)},_focusTabbable:function(){var t=this._focusedElement;t||(t=this.element.find("[autofocus]")),t.length||(t=this.element.find(":tabbable")),t.length||(t=this.uiDialogButtonPane.find(":tabbable")),t.length||(t=this.uiDialogTitlebarClose.filter(":tabbable")),t.length||(t=this.uiDialog),t.eq(0).trigger("focus")},_keepFocus:function(e){function i(){var e=t.ui.safeActiveElement(this.document[0]),i=this.uiDialog[0]===e||t.contains(this.uiDialog[0],e);i||this._focusTabbable()}e.preventDefault(),i.call(this),this._delay(i)},_createWrapper:function(){this.uiDialog=t("<div>").hide().attr({tabIndex:-1,role:"dialog"}).appendTo(this._appendTo()),this._addClass(this.uiDialog,"ui-dialog","ui-widget ui-widget-content ui-front"),this._on(this.uiDialog,{keydown:function(e){if(this.options.closeOnEscape&&!e.isDefaultPrevented()&&e.keyCode&&e.keyCode===t.ui.keyCode.ESCAPE)return e.preventDefault(),this.close(e),void 0;if(e.keyCode===t.ui.keyCode.TAB&&!e.isDefaultPrevented()){var i=this.uiDialog.find(":tabbable"),s=i.filter(":first"),n=i.filter(":last");e.target!==n[0]&&e.target!==this.uiDialog[0]||e.shiftKey?e.target!==s[0]&&e.target!==this.uiDialog[0]||!e.shiftKey||(this._delay(function(){n.trigger("focus")}),e.preventDefault()):(this._delay(function(){s.trigger("focus")}),e.preventDefault())}},mousedown:function(t){this._moveToTop(t)&&this._focusTabbable()}}),this.element.find("[aria-describedby]").length||this.uiDialog.attr({"aria-describedby":this.element.uniqueId().attr("id")})},_createTitlebar:function(){var e;this.uiDialogTitlebar=t("<div>"),this._addClass(this.uiDialogTitlebar,"ui-dialog-titlebar","ui-widget-header ui-helper-clearfix"),this._on(this.uiDialogTitlebar,{mousedown:function(e){t(e.target).closest(".ui-dialog-titlebar-close")||this.uiDialog.trigger("focus")}}),this.uiDialogTitlebarClose=t("<button type='button'></button>").button({label:t("<a>").text(this.options.closeText).html(),icon:"ui-icon-closethick",showLabel:!1}).appendTo(this.uiDialogTitlebar),this._addClass(this.uiDialogTitlebarClose,"ui-dialog-titlebar-close"),this._on(this.uiDialogTitlebarClose,{click:function(t){t.preventDefault(),this.close(t)}}),e=t("<span>").uniqueId().prependTo(this.uiDialogTitlebar),this._addClass(e,"ui-dialog-title"),this._title(e),this.uiDialogTitlebar.prependTo(this.uiDialog),this.uiDialog.attr({"aria-labelledby":e.attr("id")})},_title:function(t){this.options.title?t.text(this.options.title):t.html("&#160;")},_createButtonPane:function(){this.uiDialogButtonPane=t("<div>"),this._addClass(this.uiDialogButtonPane,"ui-dialog-buttonpane","ui-widget-content ui-helper-clearfix"),this.uiButtonSet=t("<div>").appendTo(this.uiDialogButtonPane),this._addClass(this.uiButtonSet,"ui-dialog-buttonset"),this._createButtons()},_createButtons:function(){var e=this,i=this.options.buttons;return this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),t.isEmptyObject(i)||t.isArray(i)&&!i.length?(this._removeClass(this.uiDialog,"ui-dialog-buttons"),void 0):(t.each(i,function(i,s){var n,o;s=t.isFunction(s)?{click:s,text:i}:s,s=t.extend({type:"button"},s),n=s.click,o={icon:s.icon,iconPosition:s.iconPosition,showLabel:s.showLabel,icons:s.icons,text:s.text},delete s.click,delete s.icon,delete s.iconPosition,delete s.showLabel,delete s.icons,"boolean"==typeof s.text&&delete s.text,t("<button></button>",s).button(o).appendTo(e.uiButtonSet).on("click",function(){n.apply(e.element[0],arguments)})}),this._addClass(this.uiDialog,"ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog),void 0)},_makeDraggable:function(){function e(t){return{position:t.position,offset:t.offset}}var i=this,s=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(s,n){i._addClass(t(this),"ui-dialog-dragging"),i._blockFrames(),i._trigger("dragStart",s,e(n))},drag:function(t,s){i._trigger("drag",t,e(s))},stop:function(n,o){var a=o.offset.left-i.document.scrollLeft(),r=o.offset.top-i.document.scrollTop();s.position={my:"left top",at:"left"+(a>=0?"+":"")+a+" "+"top"+(r>=0?"+":"")+r,of:i.window},i._removeClass(t(this),"ui-dialog-dragging"),i._unblockFrames(),i._trigger("dragStop",n,e(o))}})},_makeResizable:function(){function e(t){return{originalPosition:t.originalPosition,originalSize:t.originalSize,position:t.position,size:t.size}}var i=this,s=this.options,n=s.resizable,o=this.uiDialog.css("position"),a="string"==typeof n?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:s.maxWidth,maxHeight:s.maxHeight,minWidth:s.minWidth,minHeight:this._minHeight(),handles:a,start:function(s,n){i._addClass(t(this),"ui-dialog-resizing"),i._blockFrames(),i._trigger("resizeStart",s,e(n))},resize:function(t,s){i._trigger("resize",t,e(s))},stop:function(n,o){var a=i.uiDialog.offset(),r=a.left-i.document.scrollLeft(),h=a.top-i.document.scrollTop();s.height=i.uiDialog.height(),s.width=i.uiDialog.width(),s.position={my:"left top",at:"left"+(r>=0?"+":"")+r+" "+"top"+(h>=0?"+":"")+h,of:i.window},i._removeClass(t(this),"ui-dialog-resizing"),i._unblockFrames(),i._trigger("resizeStop",n,e(o))}}).css("position",o)},_trackFocus:function(){this._on(this.widget(),{focusin:function(e){this._makeFocusTarget(),this._focusedElement=t(e.target)}})},_makeFocusTarget:function(){this._untrackInstance(),this._trackingInstances().unshift(this)},_untrackInstance:function(){var e=this._trackingInstances(),i=t.inArray(this,e);-1!==i&&e.splice(i,1)},_trackingInstances:function(){var t=this.document.data("ui-dialog-instances");return t||(t=[],this.document.data("ui-dialog-instances",t)),t},_minHeight:function(){var t=this.options;return"auto"===t.height?t.minHeight:Math.min(t.minHeight,t.height)},_position:function(){var t=this.uiDialog.is(":visible");t||this.uiDialog.show(),this.uiDialog.position(this.options.position),t||this.uiDialog.hide()},_setOptions:function(e){var i=this,s=!1,n={};t.each(e,function(t,e){i._setOption(t,e),t in i.sizeRelatedOptions&&(s=!0),t in i.resizableRelatedOptions&&(n[t]=e)}),s&&(this._size(),this._position()),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option",n)},_setOption:function(e,i){var s,n,o=this.uiDialog;"disabled"!==e&&(this._super(e,i),"appendTo"===e&&this.uiDialog.appendTo(this._appendTo()),"buttons"===e&&this._createButtons(),"closeText"===e&&this.uiDialogTitlebarClose.button({label:t("<a>").text(""+this.options.closeText).html()}),"draggable"===e&&(s=o.is(":data(ui-draggable)"),s&&!i&&o.draggable("destroy"),!s&&i&&this._makeDraggable()),"position"===e&&this._position(),"resizable"===e&&(n=o.is(":data(ui-resizable)"),n&&!i&&o.resizable("destroy"),n&&"string"==typeof i&&o.resizable("option","handles",i),n||i===!1||this._makeResizable()),"title"===e&&this._title(this.uiDialogTitlebar.find(".ui-dialog-title")))},_size:function(){var t,e,i,s=this.options;this.element.show().css({width:"auto",minHeight:0,maxHeight:"none",height:0}),s.minWidth>s.width&&(s.width=s.minWidth),t=this.uiDialog.css({height:"auto",width:s.width}).outerHeight(),e=Math.max(0,s.minHeight-t),i="number"==typeof s.maxHeight?Math.max(0,s.maxHeight-t):"none","auto"===s.height?this.element.css({minHeight:e,maxHeight:i,height:"auto"}):this.element.height(Math.max(0,s.height-t)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())},_blockFrames:function(){this.iframeBlocks=this.document.find("iframe").map(function(){var e=t(this);return t("<div>").css({position:"absolute",width:e.outerWidth(),height:e.outerHeight()}).appendTo(e.parent()).offset(e.offset())[0]})},_unblockFrames:function(){this.iframeBlocks&&(this.iframeBlocks.remove(),delete this.iframeBlocks)},_allowInteraction:function(e){return t(e.target).closest(".ui-dialog").length?!0:!!t(e.target).closest(".ui-datepicker").length},_createOverlay:function(){if(this.options.modal){var e=!0;this._delay(function(){e=!1}),this.document.data("ui-dialog-overlays")||this._on(this.document,{focusin:function(t){e||this._allowInteraction(t)||(t.preventDefault(),this._trackingInstances()[0]._focusTabbable())}}),this.overlay=t("<div>").appendTo(this._appendTo()),this._addClass(this.overlay,null,"ui-widget-overlay ui-front"),this._on(this.overlay,{mousedown:"_keepFocus"}),this.document.data("ui-dialog-overlays",(this.document.data("ui-dialog-overlays")||0)+1)}},_destroyOverlay:function(){if(this.options.modal&&this.overlay){var t=this.document.data("ui-dialog-overlays")-1;t?this.document.data("ui-dialog-overlays",t):(this._off(this.document,"focusin"),this.document.removeData("ui-dialog-overlays")),this.overlay.remove(),this.overlay=null}}}),t.uiBackCompat!==!1&&t.widget("ui.dialog",t.ui.dialog,{options:{dialogClass:""},_createWrapper:function(){this._super(),this.uiDialog.addClass(this.options.dialogClass)},_setOption:function(t,e){"dialogClass"===t&&this.uiDialog.removeClass(this.options.dialogClass).addClass(e),this._superApply(arguments)}}),t.ui.dialog,t.widget("ui.droppable",{version:"1.12.1",widgetEventPrefix:"drop",options:{accept:"*",addClasses:!0,greedy:!1,scope:"default",tolerance:"intersect",activate:null,deactivate:null,drop:null,out:null,over:null},_create:function(){var e,i=this.options,s=i.accept;this.isover=!1,this.isout=!0,this.accept=t.isFunction(s)?s:function(t){return t.is(s)},this.proportions=function(){return arguments.length?(e=arguments[0],void 0):e?e:e={width:this.element[0].offsetWidth,height:this.element[0].offsetHeight}},this._addToManager(i.scope),i.addClasses&&this._addClass("ui-droppable")},_addToManager:function(e){t.ui.ddmanager.droppables[e]=t.ui.ddmanager.droppables[e]||[],t.ui.ddmanager.droppables[e].push(this)},_splice:function(t){for(var e=0;t.length>e;e++)t[e]===this&&t.splice(e,1)},_destroy:function(){var e=t.ui.ddmanager.droppables[this.options.scope];this._splice(e)},_setOption:function(e,i){if("accept"===e)this.accept=t.isFunction(i)?i:function(t){return t.is(i)};else if("scope"===e){var s=t.ui.ddmanager.droppables[this.options.scope];this._splice(s),this._addToManager(i)}this._super(e,i)},_activate:function(e){var i=t.ui.ddmanager.current;this._addActiveClass(),i&&this._trigger("activate",e,this.ui(i))},_deactivate:function(e){var i=t.ui.ddmanager.current;this._removeActiveClass(),i&&this._trigger("deactivate",e,this.ui(i))},_over:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._addHoverClass(),this._trigger("over",e,this.ui(i)))},_out:function(e){var i=t.ui.ddmanager.current;i&&(i.currentItem||i.element)[0]!==this.element[0]&&this.accept.call(this.element[0],i.currentItem||i.element)&&(this._removeHoverClass(),this._trigger("out",e,this.ui(i)))},_drop:function(e,i){var s=i||t.ui.ddmanager.current,n=!1;return s&&(s.currentItem||s.element)[0]!==this.element[0]?(this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function(){var i=t(this).droppable("instance");return i.options.greedy&&!i.options.disabled&&i.options.scope===s.options.scope&&i.accept.call(i.element[0],s.currentItem||s.element)&&v(s,t.extend(i,{offset:i.element.offset()}),i.options.tolerance,e)?(n=!0,!1):void 0}),n?!1:this.accept.call(this.element[0],s.currentItem||s.element)?(this._removeActiveClass(),this._removeHoverClass(),this._trigger("drop",e,this.ui(s)),this.element):!1):!1},ui:function(t){return{draggable:t.currentItem||t.element,helper:t.helper,position:t.position,offset:t.positionAbs}},_addHoverClass:function(){this._addClass("ui-droppable-hover")},_removeHoverClass:function(){this._removeClass("ui-droppable-hover")},_addActiveClass:function(){this._addClass("ui-droppable-active")},_removeActiveClass:function(){this._removeClass("ui-droppable-active")}});var v=t.ui.intersect=function(){function t(t,e,i){return t>=e&&e+i>t}return function(e,i,s,n){if(!i.offset)return!1;var o=(e.positionAbs||e.position.absolute).left+e.margins.left,a=(e.positionAbs||e.position.absolute).top+e.margins.top,r=o+e.helperProportions.width,h=a+e.helperProportions.height,l=i.offset.left,c=i.offset.top,u=l+i.proportions().width,d=c+i.proportions().height;switch(s){case"fit":return o>=l&&u>=r&&a>=c&&d>=h;case"intersect":return o+e.helperProportions.width/2>l&&u>r-e.helperProportions.width/2&&a+e.helperProportions.height/2>c&&d>h-e.helperProportions.height/2;case"pointer":return t(n.pageY,c,i.proportions().height)&&t(n.pageX,l,i.proportions().width);case"touch":return(a>=c&&d>=a||h>=c&&d>=h||c>a&&h>d)&&(o>=l&&u>=o||r>=l&&u>=r||l>o&&r>u);default:return!1}}}();t.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,i){var s,n,o=t.ui.ddmanager.droppables[e.options.scope]||[],a=i?i.type:null,r=(e.currentItem||e.element).find(":data(ui-droppable)").addBack();t:for(s=0;o.length>s;s++)if(!(o[s].options.disabled||e&&!o[s].accept.call(o[s].element[0],e.currentItem||e.element))){for(n=0;r.length>n;n++)if(r[n]===o[s].element[0]){o[s].proportions().height=0;continue t}o[s].visible="none"!==o[s].element.css("display"),o[s].visible&&("mousedown"===a&&o[s]._activate.call(o[s],i),o[s].offset=o[s].element.offset(),o[s].proportions({width:o[s].element[0].offsetWidth,height:o[s].element[0].offsetHeight}))}},drop:function(e,i){var s=!1;return t.each((t.ui.ddmanager.droppables[e.options.scope]||[]).slice(),function(){this.options&&(!this.options.disabled&&this.visible&&v(e,this,this.options.tolerance,i)&&(s=this._drop.call(this,i)||s),!this.options.disabled&&this.visible&&this.accept.call(this.element[0],e.currentItem||e.element)&&(this.isout=!0,this.isover=!1,this._deactivate.call(this,i)))}),s},dragStart:function(e,i){e.element.parentsUntil("body").on("scroll.droppable",function(){e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)})},drag:function(e,i){e.options.refreshPositions&&t.ui.ddmanager.prepareOffsets(e,i),t.each(t.ui.ddmanager.droppables[e.options.scope]||[],function(){if(!this.options.disabled&&!this.greedyChild&&this.visible){var s,n,o,a=v(e,this,this.options.tolerance,i),r=!a&&this.isover?"isout":a&&!this.isover?"isover":null;r&&(this.options.greedy&&(n=this.options.scope,o=this.element.parents(":data(ui-droppable)").filter(function(){return t(this).droppable("instance").options.scope===n}),o.length&&(s=t(o[0]).droppable("instance"),s.greedyChild="isover"===r)),s&&"isover"===r&&(s.isover=!1,s.isout=!0,s._out.call(s,i)),this[r]=!0,this["isout"===r?"isover":"isout"]=!1,this["isover"===r?"_over":"_out"].call(this,i),s&&"isout"===r&&(s.isout=!1,s.isover=!0,s._over.call(s,i)))}})},dragStop:function(e,i){e.element.parentsUntil("body").off("scroll.droppable"),e.options.refreshPositions||t.ui.ddmanager.prepareOffsets(e,i)}},t.uiBackCompat!==!1&&t.widget("ui.droppable",t.ui.droppable,{options:{hoverClass:!1,activeClass:!1},_addActiveClass:function(){this._super(),this.options.activeClass&&this.element.addClass(this.options.activeClass)},_removeActiveClass:function(){this._super(),this.options.activeClass&&this.element.removeClass(this.options.activeClass)},_addHoverClass:function(){this._super(),this.options.hoverClass&&this.element.addClass(this.options.hoverClass)},_removeHoverClass:function(){this._super(),this.options.hoverClass&&this.element.removeClass(this.options.hoverClass)}}),t.ui.droppable,t.widget("ui.progressbar",{version:"1.12.1",options:{classes:{"ui-progressbar":"ui-corner-all","ui-progressbar-value":"ui-corner-left","ui-progressbar-complete":"ui-corner-right"},max:100,value:0,change:null,complete:null},min:0,_create:function(){this.oldValue=this.options.value=this._constrainedValue(),this.element.attr({role:"progressbar","aria-valuemin":this.min}),this._addClass("ui-progressbar","ui-widget ui-widget-content"),this.valueDiv=t("<div>").appendTo(this.element),this._addClass(this.valueDiv,"ui-progressbar-value","ui-widget-header"),this._refreshValue()},_destroy:function(){this.element.removeAttr("role aria-valuemin aria-valuemax aria-valuenow"),this.valueDiv.remove()},value:function(t){return void 0===t?this.options.value:(this.options.value=this._constrainedValue(t),this._refreshValue(),void 0)},_constrainedValue:function(t){return void 0===t&&(t=this.options.value),this.indeterminate=t===!1,"number"!=typeof t&&(t=0),this.indeterminate?!1:Math.min(this.options.max,Math.max(this.min,t))},_setOptions:function(t){var e=t.value;delete t.value,this._super(t),this.options.value=this._constrainedValue(e),this._refreshValue()},_setOption:function(t,e){"max"===t&&(e=Math.max(this.min,e)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t)},_percentage:function(){return this.indeterminate?100:100*(this.options.value-this.min)/(this.options.max-this.min)},_refreshValue:function(){var e=this.options.value,i=this._percentage();this.valueDiv.toggle(this.indeterminate||e>this.min).width(i.toFixed(0)+"%"),this._toggleClass(this.valueDiv,"ui-progressbar-complete",null,e===this.options.max)._toggleClass("ui-progressbar-indeterminate",null,this.indeterminate),this.indeterminate?(this.element.removeAttr("aria-valuenow"),this.overlayDiv||(this.overlayDiv=t("<div>").appendTo(this.valueDiv),this._addClass(this.overlayDiv,"ui-progressbar-overlay"))):(this.element.attr({"aria-valuemax":this.options.max,"aria-valuenow":e}),this.overlayDiv&&(this.overlayDiv.remove(),this.overlayDiv=null)),this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),e===this.options.max&&this._trigger("complete")}}),t.widget("ui.selectable",t.ui.mouse,{version:"1.12.1",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch",selected:null,selecting:null,start:null,stop:null,unselected:null,unselecting:null},_create:function(){var e=this;this._addClass("ui-selectable"),this.dragged=!1,this.refresh=function(){e.elementPos=t(e.element[0]).offset(),e.selectees=t(e.options.filter,e.element[0]),e._addClass(e.selectees,"ui-selectee"),e.selectees.each(function(){var i=t(this),s=i.offset(),n={left:s.left-e.elementPos.left,top:s.top-e.elementPos.top};t.data(this,"selectable-item",{element:this,$element:i,left:n.left,top:n.top,right:n.left+i.outerWidth(),bottom:n.top+i.outerHeight(),startselected:!1,selected:i.hasClass("ui-selected"),selecting:i.hasClass("ui-selecting"),unselecting:i.hasClass("ui-unselecting")})})},this.refresh(),this._mouseInit(),this.helper=t("<div>"),this._addClass(this.helper,"ui-selectable-helper")},_destroy:function(){this.selectees.removeData("selectable-item"),this._mouseDestroy()},_mouseStart:function(e){var i=this,s=this.options;this.opos=[e.pageX,e.pageY],this.elementPos=t(this.element[0]).offset(),this.options.disabled||(this.selectees=t(s.filter,this.element[0]),this._trigger("start",e),t(s.appendTo).append(this.helper),this.helper.css({left:e.pageX,top:e.pageY,width:0,height:0}),s.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var s=t.data(this,"selectable-item");s.startselected=!0,e.metaKey||e.ctrlKey||(i._removeClass(s.$element,"ui-selected"),s.selected=!1,i._addClass(s.$element,"ui-unselecting"),s.unselecting=!0,i._trigger("unselecting",e,{unselecting:s.element}))}),t(e.target).parents().addBack().each(function(){var s,n=t.data(this,"selectable-item");return n?(s=!e.metaKey&&!e.ctrlKey||!n.$element.hasClass("ui-selected"),i._removeClass(n.$element,s?"ui-unselecting":"ui-selected")._addClass(n.$element,s?"ui-selecting":"ui-unselecting"),n.unselecting=!s,n.selecting=s,n.selected=s,s?i._trigger("selecting",e,{selecting:n.element}):i._trigger("unselecting",e,{unselecting:n.element}),!1):void 0}))},_mouseDrag:function(e){if(this.dragged=!0,!this.options.disabled){var i,s=this,n=this.options,o=this.opos[0],a=this.opos[1],r=e.pageX,h=e.pageY;return o>r&&(i=r,r=o,o=i),a>h&&(i=h,h=a,a=i),this.helper.css({left:o,top:a,width:r-o,height:h-a}),this.selectees.each(function(){var i=t.data(this,"selectable-item"),l=!1,c={};i&&i.element!==s.element[0]&&(c.left=i.left+s.elementPos.left,c.right=i.right+s.elementPos.left,c.top=i.top+s.elementPos.top,c.bottom=i.bottom+s.elementPos.top,"touch"===n.tolerance?l=!(c.left>r||o>c.right||c.top>h||a>c.bottom):"fit"===n.tolerance&&(l=c.left>o&&r>c.right&&c.top>a&&h>c.bottom),l?(i.selected&&(s._removeClass(i.$element,"ui-selected"),i.selected=!1),i.unselecting&&(s._removeClass(i.$element,"ui-unselecting"),i.unselecting=!1),i.selecting||(s._addClass(i.$element,"ui-selecting"),i.selecting=!0,s._trigger("selecting",e,{selecting:i.element}))):(i.selecting&&((e.metaKey||e.ctrlKey)&&i.startselected?(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,s._addClass(i.$element,"ui-selected"),i.selected=!0):(s._removeClass(i.$element,"ui-selecting"),i.selecting=!1,i.startselected&&(s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0),s._trigger("unselecting",e,{unselecting:i.element}))),i.selected&&(e.metaKey||e.ctrlKey||i.startselected||(s._removeClass(i.$element,"ui-selected"),i.selected=!1,s._addClass(i.$element,"ui-unselecting"),i.unselecting=!0,s._trigger("unselecting",e,{unselecting:i.element})))))}),!1}},_mouseStop:function(e){var i=this;return this.dragged=!1,t(".ui-unselecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-unselecting"),s.unselecting=!1,s.startselected=!1,i._trigger("unselected",e,{unselected:s.element})}),t(".ui-selecting",this.element[0]).each(function(){var s=t.data(this,"selectable-item");i._removeClass(s.$element,"ui-selecting")._addClass(s.$element,"ui-selected"),s.selecting=!1,s.selected=!0,s.startselected=!0,i._trigger("selected",e,{selected:s.element})}),this._trigger("stop",e),this.helper.remove(),!1}}),t.widget("ui.selectmenu",[t.ui.formResetMixin,{version:"1.12.1",defaultElement:"<select>",options:{appendTo:null,classes:{"ui-selectmenu-button-open":"ui-corner-top","ui-selectmenu-button-closed":"ui-corner-all"},disabled:null,icons:{button:"ui-icon-triangle-1-s"},position:{my:"left top",at:"left bottom",collision:"none"},width:!1,change:null,close:null,focus:null,open:null,select:null},_create:function(){var e=this.element.uniqueId().attr("id");this.ids={element:e,button:e+"-button",menu:e+"-menu"},this._drawButton(),this._drawMenu(),this._bindFormResetHandler(),this._rendered=!1,this.menuItems=t()},_drawButton:function(){var e,i=this,s=this._parseOption(this.element.find("option:selected"),this.element[0].selectedIndex);this.labels=this.element.labels().attr("for",this.ids.button),this._on(this.labels,{click:function(t){this.button.focus(),t.preventDefault()}}),this.element.hide(),this.button=t("<span>",{tabindex:this.options.disabled?-1:0,id:this.ids.button,role:"combobox","aria-expanded":"false","aria-autocomplete":"list","aria-owns":this.ids.menu,"aria-haspopup":"true",title:this.element.attr("title")}).insertAfter(this.element),this._addClass(this.button,"ui-selectmenu-button ui-selectmenu-button-closed","ui-button ui-widget"),e=t("<span>").appendTo(this.button),this._addClass(e,"ui-selectmenu-icon","ui-icon "+this.options.icons.button),this.buttonItem=this._renderButtonItem(s).appendTo(this.button),this.options.width!==!1&&this._resizeButton(),this._on(this.button,this._buttonEvents),this.button.one("focusin",function(){i._rendered||i._refreshMenu()})},_drawMenu:function(){var e=this;this.menu=t("<ul>",{"aria-hidden":"true","aria-labelledby":this.ids.button,id:this.ids.menu}),this.menuWrap=t("<div>").append(this.menu),this._addClass(this.menuWrap,"ui-selectmenu-menu","ui-front"),this.menuWrap.appendTo(this._appendTo()),this.menuInstance=this.menu.menu({classes:{"ui-menu":"ui-corner-bottom"},role:"listbox",select:function(t,i){t.preventDefault(),e._setSelection(),e._select(i.item.data("ui-selectmenu-item"),t)},focus:function(t,i){var s=i.item.data("ui-selectmenu-item");null!=e.focusIndex&&s.index!==e.focusIndex&&(e._trigger("focus",t,{item:s}),e.isOpen||e._select(s,t)),e.focusIndex=s.index,e.button.attr("aria-activedescendant",e.menuItems.eq(s.index).attr("id"))}}).menu("instance"),this.menuInstance._off(this.menu,"mouseleave"),this.menuInstance._closeOnDocumentClick=function(){return!1},this.menuInstance._isDivider=function(){return!1}},refresh:function(){this._refreshMenu(),this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(this._getSelectedItem().data("ui-selectmenu-item")||{})),null===this.options.width&&this._resizeButton()},_refreshMenu:function(){var t,e=this.element.find("option");this.menu.empty(),this._parseOptions(e),this._renderMenu(this.menu,this.items),this.menuInstance.refresh(),this.menuItems=this.menu.find("li").not(".ui-selectmenu-optgroup").find(".ui-menu-item-wrapper"),this._rendered=!0,e.length&&(t=this._getSelectedItem(),this.menuInstance.focus(null,t),this._setAria(t.data("ui-selectmenu-item")),this._setOption("disabled",this.element.prop("disabled")))},open:function(t){this.options.disabled||(this._rendered?(this._removeClass(this.menu.find(".ui-state-active"),null,"ui-state-active"),this.menuInstance.focus(null,this._getSelectedItem())):this._refreshMenu(),this.menuItems.length&&(this.isOpen=!0,this._toggleAttr(),this._resizeMenu(),this._position(),this._on(this.document,this._documentClick),this._trigger("open",t)))},_position:function(){this.menuWrap.position(t.extend({of:this.button},this.options.position))},close:function(t){this.isOpen&&(this.isOpen=!1,this._toggleAttr(),this.range=null,this._off(this.document),this._trigger("close",t))},widget:function(){return this.button},menuWidget:function(){return this.menu},_renderButtonItem:function(e){var i=t("<span>");return this._setText(i,e.label),this._addClass(i,"ui-selectmenu-text"),i},_renderMenu:function(e,i){var s=this,n="";t.each(i,function(i,o){var a;o.optgroup!==n&&(a=t("<li>",{text:o.optgroup}),s._addClass(a,"ui-selectmenu-optgroup","ui-menu-divider"+(o.element.parent("optgroup").prop("disabled")?" ui-state-disabled":"")),a.appendTo(e),n=o.optgroup),s._renderItemData(e,o)})},_renderItemData:function(t,e){return this._renderItem(t,e).data("ui-selectmenu-item",e)},_renderItem:function(e,i){var s=t("<li>"),n=t("<div>",{title:i.element.attr("title")});return i.disabled&&this._addClass(s,null,"ui-state-disabled"),this._setText(n,i.label),s.append(n).appendTo(e)},_setText:function(t,e){e?t.text(e):t.html("&#160;")},_move:function(t,e){var i,s,n=".ui-menu-item";this.isOpen?i=this.menuItems.eq(this.focusIndex).parent("li"):(i=this.menuItems.eq(this.element[0].selectedIndex).parent("li"),n+=":not(.ui-state-disabled)"),s="first"===t||"last"===t?i["first"===t?"prevAll":"nextAll"](n).eq(-1):i[t+"All"](n).eq(0),s.length&&this.menuInstance.focus(e,s)},_getSelectedItem:function(){return this.menuItems.eq(this.element[0].selectedIndex).parent("li")},_toggle:function(t){this[this.isOpen?"close":"open"](t)},_setSelection:function(){var t;this.range&&(window.getSelection?(t=window.getSelection(),t.removeAllRanges(),t.addRange(this.range)):this.range.select(),this.button.focus())},_documentClick:{mousedown:function(e){this.isOpen&&(t(e.target).closest(".ui-selectmenu-menu, #"+t.ui.escapeSelector(this.ids.button)).length||this.close(e))}},_buttonEvents:{mousedown:function(){var t;window.getSelection?(t=window.getSelection(),t.rangeCount&&(this.range=t.getRangeAt(0))):this.range=document.selection.createRange()},click:function(t){this._setSelection(),this._toggle(t)},keydown:function(e){var i=!0;switch(e.keyCode){case t.ui.keyCode.TAB:case t.ui.keyCode.ESCAPE:this.close(e),i=!1;break;case t.ui.keyCode.ENTER:this.isOpen&&this._selectFocusedItem(e);break;case t.ui.keyCode.UP:e.altKey?this._toggle(e):this._move("prev",e);break;case t.ui.keyCode.DOWN:e.altKey?this._toggle(e):this._move("next",e);break;case t.ui.keyCode.SPACE:this.isOpen?this._selectFocusedItem(e):this._toggle(e);break;case t.ui.keyCode.LEFT:this._move("prev",e);break;case t.ui.keyCode.RIGHT:this._move("next",e);break;case t.ui.keyCode.HOME:case t.ui.keyCode.PAGE_UP:this._move("first",e);break;case t.ui.keyCode.END:case t.ui.keyCode.PAGE_DOWN:this._move("last",e);break;default:this.menu.trigger(e),i=!1}i&&e.preventDefault()}},_selectFocusedItem:function(t){var e=this.menuItems.eq(this.focusIndex).parent("li");e.hasClass("ui-state-disabled")||this._select(e.data("ui-selectmenu-item"),t)},_select:function(t,e){var i=this.element[0].selectedIndex;this.element[0].selectedIndex=t.index,this.buttonItem.replaceWith(this.buttonItem=this._renderButtonItem(t)),this._setAria(t),this._trigger("select",e,{item:t}),t.index!==i&&this._trigger("change",e,{item:t}),this.close(e)},_setAria:function(t){var e=this.menuItems.eq(t.index).attr("id");this.button.attr({"aria-labelledby":e,"aria-activedescendant":e}),this.menu.attr("aria-activedescendant",e)},_setOption:function(t,e){if("icons"===t){var i=this.button.find("span.ui-icon");this._removeClass(i,null,this.options.icons.button)._addClass(i,null,e.button)}this._super(t,e),"appendTo"===t&&this.menuWrap.appendTo(this._appendTo()),"width"===t&&this._resizeButton()},_setOptionDisabled:function(t){this._super(t),this.menuInstance.option("disabled",t),this.button.attr("aria-disabled",t),this._toggleClass(this.button,null,"ui-state-disabled",t),this.element.prop("disabled",t),t?(this.button.attr("tabindex",-1),this.close()):this.button.attr("tabindex",0)},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_toggleAttr:function(){this.button.attr("aria-expanded",this.isOpen),this._removeClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"closed":"open"))._addClass(this.button,"ui-selectmenu-button-"+(this.isOpen?"open":"closed"))._toggleClass(this.menuWrap,"ui-selectmenu-open",null,this.isOpen),this.menu.attr("aria-hidden",!this.isOpen)},_resizeButton:function(){var t=this.options.width;return t===!1?(this.button.css("width",""),void 0):(null===t&&(t=this.element.show().outerWidth(),this.element.hide()),this.button.outerWidth(t),void 0)},_resizeMenu:function(){this.menu.outerWidth(Math.max(this.button.outerWidth(),this.menu.width("").outerWidth()+1))},_getCreateOptions:function(){var t=this._super();return t.disabled=this.element.prop("disabled"),t},_parseOptions:function(e){var i=this,s=[];e.each(function(e,n){s.push(i._parseOption(t(n),e))}),this.items=s},_parseOption:function(t,e){var i=t.parent("optgroup");return{element:t,index:e,value:t.val(),label:t.text(),optgroup:i.attr("label")||"",disabled:i.prop("disabled")||t.prop("disabled")}},_destroy:function(){this._unbindFormResetHandler(),this.menuWrap.remove(),this.button.remove(),this.element.show(),this.element.removeUniqueId(),this.labels.attr("for",this.ids.element)}}]),t.widget("ui.slider",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"slide",options:{animate:!1,classes:{"ui-slider":"ui-corner-all","ui-slider-handle":"ui-corner-all","ui-slider-range":"ui-corner-all ui-widget-header"},distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this._addClass("ui-slider ui-slider-"+this.orientation,"ui-widget ui-widget-content"),this._refresh(),this._animateOff=!1
+},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle"),o="<span tabindex='0'></span>",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this._addClass(this.handles,"ui-slider-handle","ui-state-default"),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e).attr("tabIndex",0)})},_createRange:function(){var e=this.options;e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?(this._removeClass(this.range,"ui-slider-range-min ui-slider-range-max"),this.range.css({left:"",bottom:""})):(this.range=t("<div>").appendTo(this.element),this._addClass(this.range,"ui-slider-range")),("min"===e.range||"max"===e.range)&&this._addClass(this.range,"ui-slider-range-"+e.range)):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,h,l,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,this._addClass(o,null,"ui-state-active"),o.trigger("focus"),h=o.offset(),l=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=l?{left:0,top:0}:{left:e.pageX-h.left-o.width()/2,top:e.pageY-h.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this._removeClass(this.handles,null,"ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_uiHash:function(t,e,i){var s={handle:this.handles[t],handleIndex:t,value:void 0!==e?e:this.value()};return this._hasMultipleValues()&&(s.value=void 0!==e?e:this.values(t),s.values=i||this.values()),s},_hasMultipleValues:function(){return this.options.values&&this.options.values.length},_start:function(t,e){return this._trigger("start",t,this._uiHash(e))},_slide:function(t,e,i){var s,n,o=this.value(),a=this.values();this._hasMultipleValues()&&(n=this.values(e?0:1),o=this.values(e),2===this.options.values.length&&this.options.range===!0&&(i=0===e?Math.min(n,i):Math.max(n,i)),a[e]=i),i!==o&&(s=this._trigger("slide",t,this._uiHash(e,i,a)),s!==!1&&(this._hasMultipleValues()?this.values(e,i):this.value(i)))},_stop:function(t,e){this._trigger("stop",t,this._uiHash(e))},_change:function(t,e){this._keySliding||this._mouseSliding||(this._lastChangedValue=e,this._trigger("change",t,this._uiHash(e)))},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),void 0;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this._hasMultipleValues()?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),this._super(e,i),e){case"orientation":this._detectOrientation(),this._removeClass("ui-slider-horizontal ui-slider-vertical")._addClass("ui-slider-"+this.orientation),this._refreshValue(),this.options.range&&this._refreshRange(i),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=n-1;s>=0;s--)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_setOptionDisabled:function(t){this._super(t),this._toggleClass(null,"ui-state-disabled",!!t)},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this._hasMultipleValues()){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var t=this.options.max,e=this._valueMin(),i=this.options.step,s=Math.round((t-e)/i)*i;t=s+e,t>this.options.max&&(t-=i),this.max=parseFloat(t.toFixed(this._precision()))},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshRange:function(t){"vertical"===t&&this.range.css({width:"",left:""}),"horizontal"===t&&this.range.css({height:"",bottom:""})},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,h=this,l=this._animateOff?!1:r.animate,c={};this._hasMultipleValues()?this.handles.each(function(s){i=100*((h.values(s)-h._valueMin())/(h._valueMax()-h._valueMin())),c["horizontal"===h.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[l?"animate":"css"](c,r.animate),h.options.range===!0&&("horizontal"===h.orientation?(0===s&&h.range.stop(1,1)[l?"animate":"css"]({left:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&h.range.stop(1,1)[l?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&h.range[l?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[l?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({width:100-i+"%"},r.animate),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[l?"animate":"css"]({height:100-i+"%"},r.animate))},_handleEvents:{keydown:function(e){var i,s,n,o,a=t(e.target).data("ui-slider-handle-index");switch(e.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(e.preventDefault(),!this._keySliding&&(this._keySliding=!0,this._addClass(t(e.target),null,"ui-state-active"),i=this._start(e,a),i===!1))return}switch(o=this.options.step,s=n=this._hasMultipleValues()?this.values(a):this.value(),e.keyCode){case t.ui.keyCode.HOME:n=this._valueMin();break;case t.ui.keyCode.END:n=this._valueMax();break;case t.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+o);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-o)}this._slide(e,a,n)},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),this._removeClass(t(e.target),null,"ui-state-active"))}}}),t.widget("ui.sortable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"sort",ready:!1,options:{appendTo:"parent",axis:!1,connectWith:!1,containment:!1,cursor:"auto",cursorAt:!1,dropOnEmpty:!0,forcePlaceholderSize:!1,forceHelperSize:!1,grid:!1,handle:!1,helper:"original",items:"> *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3,activate:null,beforeStop:null,change:null,deactivate:null,out:null,over:null,receive:null,remove:null,sort:null,start:null,stop:null,update:null},_isOverAxis:function(t,e,i){return t>=e&&e+i>t},_isFloating:function(t){return/left|right/.test(t.css("float"))||/inline|table-cell/.test(t.css("display"))},_create:function(){this.containerCache={},this._addClass("ui-sortable"),this.refresh(),this.offset=this.element.offset(),this._mouseInit(),this._setHandleClassName(),this.ready=!0},_setOption:function(t,e){this._super(t,e),"handle"===t&&this._setHandleClassName()},_setHandleClassName:function(){var e=this;this._removeClass(this.element.find(".ui-sortable-handle"),"ui-sortable-handle"),t.each(this.items,function(){e._addClass(this.instance.options.handle?this.item.find(this.instance.options.handle):this.item,"ui-sortable-handle")})},_destroy:function(){this._mouseDestroy();for(var t=this.items.length-1;t>=0;t--)this.items[t].item.removeData(this.widgetName+"-item");return this},_mouseCapture:function(e,i){var s=null,n=!1,o=this;return this.reverting?!1:this.options.disabled||"static"===this.options.type?!1:(this._refreshItems(e),t(e.target).parents().each(function(){return t.data(this,o.widgetName+"-item")===o?(s=t(this),!1):void 0}),t.data(e.target,o.widgetName+"-item")===o&&(s=t(e.target)),s?!this.options.handle||i||(t(this.options.handle,s).find("*").addBack().each(function(){this===e.target&&(n=!0)}),n)?(this.currentItem=s,this._removeCurrentsFromItems(),!0):!1:!1)},_mouseStart:function(e,i,s){var n,o,a=this.options;if(this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(e),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},t.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(e),this.originalPageX=e.pageX,this.originalPageY=e.pageY,a.cursorAt&&this._adjustOffsetFromHelper(a.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!==this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),a.containment&&this._setContainment(),a.cursor&&"auto"!==a.cursor&&(o=this.document.find("body"),this.storedCursor=o.css("cursor"),o.css("cursor",a.cursor),this.storedStylesheet=t("<style>*{ cursor: "+a.cursor+" !important; }</style>").appendTo(o)),a.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",a.opacity)),a.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",a.zIndex)),this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",e,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions(),!s)for(n=this.containers.length-1;n>=0;n--)this.containers[n]._trigger("activate",e,this._uiHash(this));return t.ui.ddmanager&&(t.ui.ddmanager.current=this),t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e),this.dragging=!0,this._addClass(this.helper,"ui-sortable-helper"),this._mouseDrag(e),!0},_mouseDrag:function(e){var i,s,n,o,a=this.options,r=!1;for(this.position=this._generatePosition(e),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs),this.options.scroll&&(this.scrollParent[0]!==this.document[0]&&"HTML"!==this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-e.pageY<a.scrollSensitivity?this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop+a.scrollSpeed:e.pageY-this.overflowOffset.top<a.scrollSensitivity&&(this.scrollParent[0].scrollTop=r=this.scrollParent[0].scrollTop-a.scrollSpeed),this.overflowOffset.left+this.scrollParent[0].offsetWidth-e.pageX<a.scrollSensitivity?this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft+a.scrollSpeed:e.pageX-this.overflowOffset.left<a.scrollSensitivity&&(this.scrollParent[0].scrollLeft=r=this.scrollParent[0].scrollLeft-a.scrollSpeed)):(e.pageY-this.document.scrollTop()<a.scrollSensitivity?r=this.document.scrollTop(this.document.scrollTop()-a.scrollSpeed):this.window.height()-(e.pageY-this.document.scrollTop())<a.scrollSensitivity&&(r=this.document.scrollTop(this.document.scrollTop()+a.scrollSpeed)),e.pageX-this.document.scrollLeft()<a.scrollSensitivity?r=this.document.scrollLeft(this.document.scrollLeft()-a.scrollSpeed):this.window.width()-(e.pageX-this.document.scrollLeft())<a.scrollSensitivity&&(r=this.document.scrollLeft(this.document.scrollLeft()+a.scrollSpeed))),r!==!1&&t.ui.ddmanager&&!a.dropBehaviour&&t.ui.ddmanager.prepareOffsets(this,e)),this.positionAbs=this._convertPositionTo("absolute"),this.options.axis&&"y"===this.options.axis||(this.helper[0].style.left=this.position.left+"px"),this.options.axis&&"x"===this.options.axis||(this.helper[0].style.top=this.position.top+"px"),i=this.items.length-1;i>=0;i--)if(s=this.items[i],n=s.item[0],o=this._intersectsWithPointer(s),o&&s.instance===this.currentContainer&&n!==this.currentItem[0]&&this.placeholder[1===o?"next":"prev"]()[0]!==n&&!t.contains(this.placeholder[0],n)&&("semi-dynamic"===this.options.type?!t.contains(this.element[0],n):!0)){if(this.direction=1===o?"down":"up","pointer"!==this.options.tolerance&&!this._intersectsWithSides(s))break;this._rearrange(e,s),this._trigger("change",e,this._uiHash());break}return this._contactContainers(e),t.ui.ddmanager&&t.ui.ddmanager.drag(this,e),this._trigger("sort",e,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(e,i){if(e){if(t.ui.ddmanager&&!this.options.dropBehaviour&&t.ui.ddmanager.drop(this,e),this.options.revert){var s=this,n=this.placeholder.offset(),o=this.options.axis,a={};o&&"x"!==o||(a.left=n.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollLeft)),o&&"y"!==o||(a.top=n.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]===this.document[0].body?0:this.offsetParent[0].scrollTop)),this.reverting=!0,t(this.helper).animate(a,parseInt(this.options.revert,10)||500,function(){s._clear(e)})}else this._clear(e,i);return!1}},cancel:function(){if(this.dragging){this._mouseUp(new t.Event("mouseup",{target:null})),"original"===this.options.helper?(this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")):this.currentItem.show();for(var e=this.containers.length-1;e>=0;e--)this.containers[e]._trigger("deactivate",null,this._uiHash(this)),this.containers[e].containerCache.over&&(this.containers[e]._trigger("out",null,this._uiHash(this)),this.containers[e].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),"original"!==this.options.helper&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),t.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?t(this.domPosition.prev).after(this.currentItem):t(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},t(i).each(function(){var i=(t(e.item||this).attr(e.attribute||"id")||"").match(e.expression||/(.+)[\-=_](.+)/);i&&s.push((e.key||i[1]+"[]")+"="+(e.key&&e.expression?i[1]:i[2]))}),!s.length&&e.key&&s.push(e.key+"="),s.join("&")},toArray:function(e){var i=this._getItemsAsjQuery(e&&e.connected),s=[];return e=e||{},i.each(function(){s.push(t(e.item||this).attr(e.attribute||"id")||"")}),s},_intersectsWith:function(t){var e=this.positionAbs.left,i=e+this.helperProportions.width,s=this.positionAbs.top,n=s+this.helperProportions.height,o=t.left,a=o+t.width,r=t.top,h=r+t.height,l=this.offset.click.top,c=this.offset.click.left,u="x"===this.options.axis||s+l>r&&h>s+l,d="y"===this.options.axis||e+c>o&&a>e+c,p=u&&d;return"pointer"===this.options.tolerance||this.options.forcePointerForContainers||"pointer"!==this.options.tolerance&&this.helperProportions[this.floating?"width":"height"]>t[this.floating?"width":"height"]?p:e+this.helperProportions.width/2>o&&a>i-this.helperProportions.width/2&&s+this.helperProportions.height/2>r&&h>n-this.helperProportions.height/2},_intersectsWithPointer:function(t){var e,i,s="x"===this.options.axis||this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top,t.height),n="y"===this.options.axis||this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left,t.width),o=s&&n;return o?(e=this._getDragVerticalDirection(),i=this._getDragHorizontalDirection(),this.floating?"right"===i||"down"===e?2:1:e&&("down"===e?2:1)):!1},_intersectsWithSides:function(t){var e=this._isOverAxis(this.positionAbs.top+this.offset.click.top,t.top+t.height/2,t.height),i=this._isOverAxis(this.positionAbs.left+this.offset.click.left,t.left+t.width/2,t.width),s=this._getDragVerticalDirection(),n=this._getDragHorizontalDirection();return this.floating&&n?"right"===n&&i||"left"===n&&!i:s&&("down"===s&&e||"up"===s&&!e)},_getDragVerticalDirection:function(){var t=this.positionAbs.top-this.lastPositionAbs.top;return 0!==t&&(t>0?"down":"up")},_getDragHorizontalDirection:function(){var t=this.positionAbs.left-this.lastPositionAbs.left;return 0!==t&&(t>0?"right":"left")},refresh:function(t){return this._refreshItems(t),this._setHandleClassName(),this.refreshPositions(),this},_connectWith:function(){var t=this.options;return t.connectWith.constructor===String?[t.connectWith]:t.connectWith},_getItemsAsjQuery:function(e){function i(){r.push(this)}var s,n,o,a,r=[],h=[],l=this._connectWith();if(l&&e)for(s=l.length-1;s>=0;s--)for(o=t(l[s],this.document[0]),n=o.length-1;n>=0;n--)a=t.data(o[n],this.widgetFullName),a&&a!==this&&!a.options.disabled&&h.push([t.isFunction(a.options.items)?a.options.items.call(a.element):t(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a]);for(h.push([t.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):t(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]),s=h.length-1;s>=0;s--)h[s][0].each(i);return t(r)},_removeCurrentsFromItems:function(){var e=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=t.grep(this.items,function(t){for(var i=0;e.length>i;i++)if(e[i]===t.item[0])return!1;return!0})},_refreshItems:function(e){this.items=[],this.containers=[this];var i,s,n,o,a,r,h,l,c=this.items,u=[[t.isFunction(this.options.items)?this.options.items.call(this.element[0],e,{item:this.currentItem}):t(this.options.items,this.element),this]],d=this._connectWith();if(d&&this.ready)for(i=d.length-1;i>=0;i--)for(n=t(d[i],this.document[0]),s=n.length-1;s>=0;s--)o=t.data(n[s],this.widgetFullName),o&&o!==this&&!o.options.disabled&&(u.push([t.isFunction(o.options.items)?o.options.items.call(o.element[0],e,{item:this.currentItem}):t(o.options.items,o.element),o]),this.containers.push(o));for(i=u.length-1;i>=0;i--)for(a=u[i][1],r=u[i][0],s=0,l=r.length;l>s;s++)h=t(r[s]),h.data(this.widgetName+"-item",a),c.push({item:h,instance:a,width:0,height:0,left:0,top:0})},refreshPositions:function(e){this.floating=this.items.length?"x"===this.options.axis||this._isFloating(this.items[0].item):!1,this.offsetParent&&this.helper&&(this.offset.parent=this._getParentOffset());var i,s,n,o;for(i=this.items.length-1;i>=0;i--)s=this.items[i],s.instance!==this.currentContainer&&this.currentContainer&&s.item[0]!==this.currentItem[0]||(n=this.options.toleranceElement?t(this.options.toleranceElement,s.item):s.item,e||(s.width=n.outerWidth(),s.height=n.outerHeight()),o=n.offset(),s.left=o.left,s.top=o.top);if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(i=this.containers.length-1;i>=0;i--)o=this.containers[i].element.offset(),this.containers[i].containerCache.left=o.left,this.containers[i].containerCache.top=o.top,this.containers[i].containerCache.width=this.containers[i].element.outerWidth(),this.containers[i].containerCache.height=this.containers[i].element.outerHeight();return this},_createPlaceholder:function(e){e=e||this;var i,s=e.options;s.placeholder&&s.placeholder.constructor!==String||(i=s.placeholder,s.placeholder={element:function(){var s=e.currentItem[0].nodeName.toLowerCase(),n=t("<"+s+">",e.document[0]);return e._addClass(n,"ui-sortable-placeholder",i||e.currentItem[0].className)._removeClass(n,"ui-sortable-helper"),"tbody"===s?e._createTrPlaceholder(e.currentItem.find("tr").eq(0),t("<tr>",e.document[0]).appendTo(n)):"tr"===s?e._createTrPlaceholder(e.currentItem,n):"img"===s&&n.attr("src",e.currentItem.attr("src")),i||n.css("visibility","hidden"),n},update:function(t,n){(!i||s.forcePlaceholderSize)&&(n.height()||n.height(e.currentItem.innerHeight()-parseInt(e.currentItem.css("paddingTop")||0,10)-parseInt(e.currentItem.css("paddingBottom")||0,10)),n.width()||n.width(e.currentItem.innerWidth()-parseInt(e.currentItem.css("paddingLeft")||0,10)-parseInt(e.currentItem.css("paddingRight")||0,10)))}}),e.placeholder=t(s.placeholder.element.call(e.element,e.currentItem)),e.currentItem.after(e.placeholder),s.placeholder.update(e,e.placeholder)},_createTrPlaceholder:function(e,i){var s=this;e.children().each(function(){t("<td>&#160;</td>",s.document[0]).attr("colspan",t(this).attr("colspan")||1).appendTo(i)})},_contactContainers:function(e){var i,s,n,o,a,r,h,l,c,u,d=null,p=null;for(i=this.containers.length-1;i>=0;i--)if(!t.contains(this.currentItem[0],this.containers[i].element[0]))if(this._intersectsWith(this.containers[i].containerCache)){if(d&&t.contains(this.containers[i].element[0],d.element[0]))continue;d=this.containers[i],p=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",e,this._uiHash(this)),this.containers[i].containerCache.over=0);if(d)if(1===this.containers.length)this.containers[p].containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1);else{for(n=1e4,o=null,c=d.floating||this._isFloating(this.currentItem),a=c?"left":"top",r=c?"width":"height",u=c?"pageX":"pageY",s=this.items.length-1;s>=0;s--)t.contains(this.containers[p].element[0],this.items[s].item[0])&&this.items[s].item[0]!==this.currentItem[0]&&(h=this.items[s].item.offset()[a],l=!1,e[u]-h>this.items[s][r]/2&&(l=!0),n>Math.abs(e[u]-h)&&(n=Math.abs(e[u]-h),o=this.items[s],this.direction=l?"up":"down"));if(!o&&!this.options.dropOnEmpty)return;if(this.currentContainer===this.containers[p])return this.currentContainer.containerCache.over||(this.containers[p]._trigger("over",e,this._uiHash()),this.currentContainer.containerCache.over=1),void 0;o?this._rearrange(e,o,null,!0):this._rearrange(e,null,this.containers[p].element,!0),this._trigger("change",e,this._uiHash()),this.containers[p]._trigger("change",e,this._uiHash(this)),this.currentContainer=this.containers[p],this.options.placeholder.update(this.currentContainer,this.placeholder),this.containers[p]._trigger("over",e,this._uiHash(this)),this.containers[p].containerCache.over=1}},_createHelper:function(e){var i=this.options,s=t.isFunction(i.helper)?t(i.helper.apply(this.element[0],[e,this.currentItem])):"clone"===i.helper?this.currentItem.clone():this.currentItem;return s.parents("body").length||t("parent"!==i.appendTo?i.appendTo:this.currentItem[0].parentNode)[0].appendChild(s[0]),s[0]===this.currentItem[0]&&(this._storedCSS={width:this.currentItem[0].style.width,height:this.currentItem[0].style.height,position:this.currentItem.css("position"),top:this.currentItem.css("top"),left:this.currentItem.css("left")}),(!s[0].style.width||i.forceHelperSize)&&s.width(this.currentItem.width()),(!s[0].style.height||i.forceHelperSize)&&s.height(this.currentItem.height()),s},_adjustOffsetFromHelper:function(e){"string"==typeof e&&(e=e.split(" ")),t.isArray(e)&&(e={left:+e[0],top:+e[1]||0}),"left"in e&&(this.offset.click.left=e.left+this.margins.left),"right"in e&&(this.offset.click.left=this.helperProportions.width-e.right+this.margins.left),"top"in e&&(this.offset.click.top=e.top+this.margins.top),"bottom"in e&&(this.offset.click.top=this.helperProportions.height-e.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var e=this.offsetParent.offset();return"absolute"===this.cssPosition&&this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])&&(e.left+=this.scrollParent.scrollLeft(),e.top+=this.scrollParent.scrollTop()),(this.offsetParent[0]===this.document[0].body||this.offsetParent[0].tagName&&"html"===this.offsetParent[0].tagName.toLowerCase()&&t.ui.ie)&&(e={top:0,left:0}),{top:e.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:e.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"===this.cssPosition){var t=this.currentItem.position();return{top:t.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:t.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.currentItem.css("marginLeft"),10)||0,top:parseInt(this.currentItem.css("marginTop"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e,i,s,n=this.options;"parent"===n.containment&&(n.containment=this.helper[0].parentNode),("document"===n.containment||"window"===n.containment)&&(this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,"document"===n.containment?this.document.width():this.window.width()-this.helperProportions.width-this.margins.left,("document"===n.containment?this.document.height()||document.body.parentNode.scrollHeight:this.window.height()||this.document[0].body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]),/^(document|window|parent)$/.test(n.containment)||(e=t(n.containment)[0],i=t(n.containment).offset(),s="hidden"!==t(e).css("overflow"),this.containment=[i.left+(parseInt(t(e).css("borderLeftWidth"),10)||0)+(parseInt(t(e).css("paddingLeft"),10)||0)-this.margins.left,i.top+(parseInt(t(e).css("borderTopWidth"),10)||0)+(parseInt(t(e).css("paddingTop"),10)||0)-this.margins.top,i.left+(s?Math.max(e.scrollWidth,e.offsetWidth):e.offsetWidth)-(parseInt(t(e).css("borderLeftWidth"),10)||0)-(parseInt(t(e).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,i.top+(s?Math.max(e.scrollHeight,e.offsetHeight):e.offsetHeight)-(parseInt(t(e).css("borderTopWidth"),10)||0)-(parseInt(t(e).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top])},_convertPositionTo:function(e,i){i||(i=this.position);var s="absolute"===e?1:-1,n="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(n[0].tagName);return{top:i.top+this.offset.relative.top*s+this.offset.parent.top*s-("fixed"===this.cssPosition?-this.scrollParent.scrollTop():o?0:n.scrollTop())*s,left:i.left+this.offset.relative.left*s+this.offset.parent.left*s-("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():o?0:n.scrollLeft())*s}},_generatePosition:function(e){var i,s,n=this.options,o=e.pageX,a=e.pageY,r="absolute"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&t.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,h=/(html|body)/i.test(r[0].tagName);return"relative"!==this.cssPosition||this.scrollParent[0]!==this.document[0]&&this.scrollParent[0]!==this.offsetParent[0]||(this.offset.relative=this._getRelativeOffset()),this.originalPosition&&(this.containment&&(e.pageX-this.offset.click.left<this.containment[0]&&(o=this.containment[0]+this.offset.click.left),e.pageY-this.offset.click.top<this.containment[1]&&(a=this.containment[1]+this.offset.click.top),e.pageX-this.offset.click.left>this.containment[2]&&(o=this.containment[2]+this.offset.click.left),e.pageY-this.offset.click.top>this.containment[3]&&(a=this.containment[3]+this.offset.click.top)),n.grid&&(i=this.originalPageY+Math.round((a-this.originalPageY)/n.grid[1])*n.grid[1],a=this.containment?i-this.offset.click.top>=this.containment[1]&&i-this.offset.click.top<=this.containment[3]?i:i-this.offset.click.top>=this.containment[1]?i-n.grid[1]:i+n.grid[1]:i,s=this.originalPageX+Math.round((o-this.originalPageX)/n.grid[0])*n.grid[0],o=this.containment?s-this.offset.click.left>=this.containment[0]&&s-this.offset.click.left<=this.containment[2]?s:s-this.offset.click.left>=this.containment[0]?s-n.grid[0]:s+n.grid[0]:s)),{top:a-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+("fixed"===this.cssPosition?-this.scrollParent.scrollTop():h?0:r.scrollTop()),left:o-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+("fixed"===this.cssPosition?-this.scrollParent.scrollLeft():h?0:r.scrollLeft())}},_rearrange:function(t,e,i,s){i?i[0].appendChild(this.placeholder[0]):e.item[0].parentNode.insertBefore(this.placeholder[0],"down"===this.direction?e.item[0]:e.item[0].nextSibling),this.counter=this.counter?++this.counter:1;var n=this.counter;
+this._delay(function(){n===this.counter&&this.refreshPositions(!s)})},_clear:function(t,e){function i(t,e,i){return function(s){i._trigger(t,s,e._uiHash(e))}}this.reverting=!1;var s,n=[];if(!this._noFinalSort&&this.currentItem.parent().length&&this.placeholder.before(this.currentItem),this._noFinalSort=null,this.helper[0]===this.currentItem[0]){for(s in this._storedCSS)("auto"===this._storedCSS[s]||"static"===this._storedCSS[s])&&(this._storedCSS[s]="");this.currentItem.css(this._storedCSS),this._removeClass(this.currentItem,"ui-sortable-helper")}else this.currentItem.show();for(this.fromOutside&&!e&&n.push(function(t){this._trigger("receive",t,this._uiHash(this.fromOutside))}),!this.fromOutside&&this.domPosition.prev===this.currentItem.prev().not(".ui-sortable-helper")[0]&&this.domPosition.parent===this.currentItem.parent()[0]||e||n.push(function(t){this._trigger("update",t,this._uiHash())}),this!==this.currentContainer&&(e||(n.push(function(t){this._trigger("remove",t,this._uiHash())}),n.push(function(t){return function(e){t._trigger("receive",e,this._uiHash(this))}}.call(this,this.currentContainer)),n.push(function(t){return function(e){t._trigger("update",e,this._uiHash(this))}}.call(this,this.currentContainer)))),s=this.containers.length-1;s>=0;s--)e||n.push(i("deactivate",this,this.containers[s])),this.containers[s].containerCache.over&&(n.push(i("out",this,this.containers[s])),this.containers[s].containerCache.over=0);if(this.storedCursor&&(this.document.find("body").css("cursor",this.storedCursor),this.storedStylesheet.remove()),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex","auto"===this._storedZIndex?"":this._storedZIndex),this.dragging=!1,e||this._trigger("beforeStop",t,this._uiHash()),this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.cancelHelperRemoval||(this.helper[0]!==this.currentItem[0]&&this.helper.remove(),this.helper=null),!e){for(s=0;n.length>s;s++)n[s].call(this,t);this._trigger("stop",t,this._uiHash())}return this.fromOutside=!1,!this.cancelHelperRemoval},_trigger:function(){t.Widget.prototype._trigger.apply(this,arguments)===!1&&this.cancel()},_uiHash:function(e){var i=e||this;return{helper:i.helper,placeholder:i.placeholder||t([]),position:i.position,originalPosition:i.originalPosition,offset:i.positionAbs,item:i.currentItem,sender:e?e.element:null}}}),t.widget("ui.spinner",{version:"1.12.1",defaultElement:"<input>",widgetEventPrefix:"spin",options:{classes:{"ui-spinner":"ui-corner-all","ui-spinner-down":"ui-corner-br","ui-spinner-up":"ui-corner-tr"},culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),""!==this.value()&&this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var e=this._super(),i=this.element;return t.each(["min","max","step"],function(t,s){var n=i.attr(s);null!=n&&n.length&&(e[s]=n)}),e},_events:{keydown:function(t){this._start(t)&&this._keydown(t)&&t.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(this._stop(),this._refresh(),this.previous!==this.element.val()&&this._trigger("change",t),void 0)},mousewheel:function(t,e){if(e){if(!this.spinning&&!this._start(t))return!1;this._spin((e>0?1:-1)*this.options.step,t),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(t)},100),t.preventDefault()}},"mousedown .ui-spinner-button":function(e){function i(){var e=this.element[0]===t.ui.safeActiveElement(this.document[0]);e||(this.element.trigger("focus"),this.previous=s,this._delay(function(){this.previous=s}))}var s;s=this.element[0]===t.ui.safeActiveElement(this.document[0])?this.previous:this.element.val(),e.preventDefault(),i.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,i.call(this)}),this._start(e)!==!1&&this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(e){return t(e.currentTarget).hasClass("ui-state-active")?this._start(e)===!1?!1:(this._repeat(null,t(e.currentTarget).hasClass("ui-spinner-up")?1:-1,e),void 0):void 0},"mouseleave .ui-spinner-button":"_stop"},_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap("<span>").parent().append("<a></a><a></a>")},_draw:function(){this._enhance(),this._addClass(this.uiSpinner,"ui-spinner","ui-widget ui-widget-content"),this._addClass("ui-spinner-input"),this.element.attr("role","spinbutton"),this.buttons=this.uiSpinner.children("a").attr("tabIndex",-1).attr("aria-hidden",!0).button({classes:{"ui-button":""}}),this._removeClass(this.buttons,"ui-corner-all"),this._addClass(this.buttons.first(),"ui-spinner-button ui-spinner-up"),this._addClass(this.buttons.last(),"ui-spinner-button ui-spinner-down"),this.buttons.first().button({icon:this.options.icons.up,showLabel:!1}),this.buttons.last().button({icon:this.options.icons.down,showLabel:!1}),this.buttons.height()>Math.ceil(.5*this.uiSpinner.height())&&this.uiSpinner.height()>0&&this.uiSpinner.height(this.uiSpinner.height())},_keydown:function(e){var i=this.options,s=t.ui.keyCode;switch(e.keyCode){case s.UP:return this._repeat(null,1,e),!0;case s.DOWN:return this._repeat(null,-1,e),!0;case s.PAGE_UP:return this._repeat(null,i.page,e),!0;case s.PAGE_DOWN:return this._repeat(null,-i.page,e),!0}return!1},_start:function(t){return this.spinning||this._trigger("start",t)!==!1?(this.counter||(this.counter=1),this.spinning=!0,!0):!1},_repeat:function(t,e,i){t=t||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,e,i)},t),this._spin(e*this.options.step,i)},_spin:function(t,e){var i=this.value()||0;this.counter||(this.counter=1),i=this._adjustValue(i+t*this._increment(this.counter)),this.spinning&&this._trigger("spin",e,{value:i})===!1||(this._value(i),this.counter++)},_increment:function(e){var i=this.options.incremental;return i?t.isFunction(i)?i(e):Math.floor(e*e*e/5e4-e*e/500+17*e/200+1):1},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_adjustValue:function(t){var e,i,s=this.options;return e=null!==s.min?s.min:0,i=t-e,i=Math.round(i/s.step)*s.step,t=e+i,t=parseFloat(t.toFixed(this._precision())),null!==s.max&&t>s.max?s.max:null!==s.min&&s.min>t?s.min:t},_stop:function(t){this.spinning&&(clearTimeout(this.timer),clearTimeout(this.mousewheelTimer),this.counter=0,this.spinning=!1,this._trigger("stop",t))},_setOption:function(t,e){var i,s,n;return"culture"===t||"numberFormat"===t?(i=this._parse(this.element.val()),this.options[t]=e,this.element.val(this._format(i)),void 0):(("max"===t||"min"===t||"step"===t)&&"string"==typeof e&&(e=this._parse(e)),"icons"===t&&(s=this.buttons.first().find(".ui-icon"),this._removeClass(s,null,this.options.icons.up),this._addClass(s,null,e.up),n=this.buttons.last().find(".ui-icon"),this._removeClass(n,null,this.options.icons.down),this._addClass(n,null,e.down)),this._super(t,e),void 0)},_setOptionDisabled:function(t){this._super(t),this._toggleClass(this.uiSpinner,null,"ui-state-disabled",!!t),this.element.prop("disabled",!!t),this.buttons.button(t?"disable":"enable")},_setOptions:r(function(t){this._super(t)}),_parse:function(t){return"string"==typeof t&&""!==t&&(t=window.Globalize&&this.options.numberFormat?Globalize.parseFloat(t,10,this.options.culture):+t),""===t||isNaN(t)?null:t},_format:function(t){return""===t?"":window.Globalize&&this.options.numberFormat?Globalize.format(t,this.options.numberFormat,this.options.culture):t},_refresh:function(){this.element.attr({"aria-valuemin":this.options.min,"aria-valuemax":this.options.max,"aria-valuenow":this._parse(this.element.val())})},isValid:function(){var t=this.value();return null===t?!1:t===this._adjustValue(t)},_value:function(t,e){var i;""!==t&&(i=this._parse(t),null!==i&&(e||(i=this._adjustValue(i)),t=this._format(i))),this.element.val(t),this._refresh()},_destroy:function(){this.element.prop("disabled",!1).removeAttr("autocomplete role aria-valuemin aria-valuemax aria-valuenow"),this.uiSpinner.replaceWith(this.element)},stepUp:r(function(t){this._stepUp(t)}),_stepUp:function(t){this._start()&&(this._spin((t||1)*this.options.step),this._stop())},stepDown:r(function(t){this._stepDown(t)}),_stepDown:function(t){this._start()&&(this._spin((t||1)*-this.options.step),this._stop())},pageUp:r(function(t){this._stepUp((t||1)*this.options.page)}),pageDown:r(function(t){this._stepDown((t||1)*this.options.page)}),value:function(t){return arguments.length?(r(this._value).call(this,t),void 0):this._parse(this.element.val())},widget:function(){return this.uiSpinner}}),t.uiBackCompat!==!1&&t.widget("ui.spinner",t.ui.spinner,{_enhance:function(){this.uiSpinner=this.element.attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml())},_uiSpinnerHtml:function(){return"<span>"},_buttonHtml:function(){return"<a></a><a></a>"}}),t.ui.spinner,t.widget("ui.tabs",{version:"1.12.1",delay:300,options:{active:null,classes:{"ui-tabs":"ui-corner-all","ui-tabs-nav":"ui-corner-all","ui-tabs-panel":"ui-corner-bottom","ui-tabs-tab":"ui-corner-top"},collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_isLocal:function(){var t=/#.*$/;return function(e){var i,s;i=e.href.replace(t,""),s=location.href.replace(t,"");try{i=decodeURIComponent(i)}catch(n){}try{s=decodeURIComponent(s)}catch(n){}return e.hash.length>1&&i===s}}(),_create:function(){var e=this,i=this.options;this.running=!1,this._addClass("ui-tabs","ui-widget ui-widget-content"),this._toggleClass("ui-tabs-collapsible",null,i.collapsible),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var e=this.options.active,i=this.options.collapsible,s=location.hash.substring(1);return null===e&&(s&&this.tabs.each(function(i,n){return t(n).attr("aria-controls")===s?(e=i,!1):void 0}),null===e&&(e=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===e||-1===e)&&(e=this.tabs.length?0:!1)),e!==!1&&(e=this.tabs.index(this.tabs.eq(e)),-1===e&&(e=i?!1:0)),!i&&e===!1&&this.anchors.length&&(e=0),e},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(e){var i=t(t.ui.safeActiveElement(this.document[0])).closest("li"),s=this.tabs.index(i),n=!0;if(!this._handlePageNav(e)){switch(e.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:s++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:n=!1,s--;break;case t.ui.keyCode.END:s=this.anchors.length-1;break;case t.ui.keyCode.HOME:s=0;break;case t.ui.keyCode.SPACE:return e.preventDefault(),clearTimeout(this.activating),this._activate(s),void 0;case t.ui.keyCode.ENTER:return e.preventDefault(),clearTimeout(this.activating),this._activate(s===this.options.active?!1:s),void 0;default:return}e.preventDefault(),clearTimeout(this.activating),s=this._focusNextTab(s,n),e.ctrlKey||e.metaKey||(i.attr("aria-selected","false"),this.tabs.eq(s).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",s)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.trigger("focus"))},_handlePageNav:function(e){return e.altKey&&e.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):e.altKey&&e.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):void 0},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).trigger("focus"),t},_setOption:function(t,e){return"active"===t?(this._activate(e),void 0):(this._super(t,e),"collapsible"===t&&(this._toggleClass("ui-tabs-collapsible",null,e),e||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(e),"heightStyle"===t&&this._setupHeightStyle(e),void 0)},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setOptionDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-hidden":"true"}),this.active.length?(this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}),this._addClass(this.active,"ui-tabs-active","ui-state-active"),this._getPanelForTab(this.active).show().attr({"aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this,i=this.tabs,s=this.anchors,n=this.panels;this.tablist=this._getList().attr("role","tablist"),this._addClass(this.tablist,"ui-tabs-nav","ui-helper-reset ui-helper-clearfix ui-widget-header"),this.tablist.on("mousedown"+this.eventNamespace,"> li",function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).on("focus"+this.eventNamespace,".ui-tabs-anchor",function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this.tabs=this.tablist.find("> li:has(a[href])").attr({role:"tab",tabIndex:-1}),this._addClass(this.tabs,"ui-tabs-tab","ui-state-default"),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).attr({role:"presentation",tabIndex:-1}),this._addClass(this.anchors,"ui-tabs-anchor"),this.panels=t(),this.anchors.each(function(i,s){var n,o,a,r=t(s).uniqueId().attr("id"),h=t(s).closest("li"),l=h.attr("aria-controls");e._isLocal(s)?(n=s.hash,a=n.substring(1),o=e.element.find(e._sanitizeSelector(n))):(a=h.attr("aria-controls")||t({}).uniqueId()[0].id,n="#"+a,o=e.element.find(n),o.length||(o=e._createPanel(a),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),l&&h.data("ui-tabs-aria-controls",l),h.attr({"aria-controls":a,"aria-labelledby":r}),o.attr("aria-labelledby",r)}),this.panels.attr("role","tabpanel"),this._addClass(this.panels,"ui-tabs-panel","ui-widget-content"),i&&(this._off(i.not(this.tabs)),this._off(s.not(this.anchors)),this._off(n.not(this.panels)))},_getList:function(){return this.tablist||this.element.find("ol, ul").eq(0)},_createPanel:function(e){return t("<div>").attr("id",e).data("ui-tabs-destroy",!0)},_setOptionDisabled:function(e){var i,s,n;for(t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1),n=0;s=this.tabs[n];n++)i=t(s),e===!0||-1!==t.inArray(n,e)?(i.attr("aria-disabled","true"),this._addClass(i,null,"ui-state-disabled")):(i.removeAttr("aria-disabled"),this._removeClass(i,null,"ui-state-disabled"));this.options.disabled=e,this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,e===!0)},_setupEvents:function(e){var i={};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(!0,this.anchors,{click:function(t){t.preventDefault()}}),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),o=n.closest("li"),a=o[0]===s[0],r=a&&i.collapsible,h=r?t():this._getPanelForTab(o),l=s.length?this._getPanelForTab(s):t(),c={oldTab:s,oldPanel:l,newTab:r?t():o,newPanel:h};e.preventDefault(),o.hasClass("ui-state-disabled")||o.hasClass("ui-tabs-loading")||this.running||a&&!i.collapsible||this._trigger("beforeActivate",e,c)===!1||(i.active=r?!1:this.tabs.index(o),this.active=a?t():o,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(o),e),this._toggle(e,c))},_toggle:function(e,i){function s(){o.running=!1,o._trigger("activate",e,i)}function n(){o._addClass(i.newTab.closest("li"),"ui-tabs-active","ui-state-active"),a.length&&o.options.show?o._show(a,o.options.show,s):(a.show(),s())}var o=this,a=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){o._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),n()}):(this._removeClass(i.oldTab.closest("li"),"ui-tabs-active","ui-state-active"),r.hide(),n()),r.attr("aria-hidden","true"),i.oldTab.attr({"aria-selected":"false","aria-expanded":"false"}),a.length&&r.length?i.oldTab.attr("tabIndex",-1):a.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),a.attr("aria-hidden","false"),i.newTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(e){return"string"==typeof e&&(e=this.anchors.index(this.anchors.filter("[href$='"+t.ui.escapeSelector(e)+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.tablist.removeAttr("role").off(this.eventNamespace),this.anchors.removeAttr("role tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeAttr("role tabIndex aria-live aria-busy aria-selected aria-labelledby aria-hidden aria-expanded")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(e){var i=this.options.disabled;i!==!1&&(void 0===e?i=!1:(e=this._getIndex(e),i=t.isArray(i)?t.map(i,function(t){return t!==e?t:null}):t.map(this.tabs,function(t,i){return i!==e?i:null})),this._setOptionDisabled(i))},disable:function(e){var i=this.options.disabled;if(i!==!0){if(void 0===e)i=!0;else{if(e=this._getIndex(e),-1!==t.inArray(e,i))return;i=t.isArray(i)?t.merge([e],i).sort():[e]}this._setOptionDisabled(i)}},load:function(e,i){e=this._getIndex(e);var s=this,n=this.tabs.eq(e),o=n.find(".ui-tabs-anchor"),a=this._getPanelForTab(n),r={tab:n,panel:a},h=function(t,e){"abort"===e&&s.panels.stop(!1,!0),s._removeClass(n,"ui-tabs-loading"),a.removeAttr("aria-busy"),t===s.xhr&&delete s.xhr};this._isLocal(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,r)),this.xhr&&"canceled"!==this.xhr.statusText&&(this._addClass(n,"ui-tabs-loading"),a.attr("aria-busy","true"),this.xhr.done(function(t,e,n){setTimeout(function(){a.html(t),s._trigger("load",i,r),h(n,e)},1)}).fail(function(t,e){setTimeout(function(){h(t,e)},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href").replace(/#.*$/,""),beforeSend:function(e,o){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:o},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}}),t.uiBackCompat!==!1&&t.widget("ui.tabs",t.ui.tabs,{_processTabs:function(){this._superApply(arguments),this._addClass(this.tabs,"ui-tab")}}),t.ui.tabs,t.widget("ui.tooltip",{version:"1.12.1",options:{classes:{"ui-tooltip":"ui-corner-all ui-widget-shadow"},content:function(){var e=t(this).attr("title")||"";return t("<a>").text(e).html()},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,track:!1,close:null,open:null},_addDescribedBy:function(e,i){var s=(e.attr("aria-describedby")||"").split(/\s+/);s.push(i),e.data("ui-tooltip-id",i).attr("aria-describedby",t.trim(s.join(" ")))},_removeDescribedBy:function(e){var i=e.data("ui-tooltip-id"),s=(e.attr("aria-describedby")||"").split(/\s+/),n=t.inArray(i,s);-1!==n&&s.splice(n,1),e.removeData("ui-tooltip-id"),s=t.trim(s.join(" ")),s?e.attr("aria-describedby",s):e.removeAttr("aria-describedby")},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.liveRegion=t("<div>").attr({role:"log","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this.disabledTitles=t([])},_setOption:function(e,i){var s=this;this._super(e,i),"content"===e&&t.each(this.tooltips,function(t,e){s._updateContent(e.element)})},_setOptionDisabled:function(t){this[t?"_disable":"_enable"]()},_disable:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur");n.target=n.currentTarget=s.element[0],e.close(n,!0)}),this.disabledTitles=this.disabledTitles.add(this.element.find(this.options.items).addBack().filter(function(){var e=t(this);return e.is("[title]")?e.data("ui-tooltip-title",e.attr("title")).removeAttr("title"):void 0}))},_enable:function(){this.disabledTitles.each(function(){var e=t(this);e.data("ui-tooltip-title")&&e.attr("title",e.data("ui-tooltip-title"))}),this.disabledTitles=t([])},open:function(e){var i=this,s=t(e?e.target:this.element).closest(this.options.items);s.length&&!s.data("ui-tooltip-id")&&(s.attr("title")&&s.data("ui-tooltip-title",s.attr("title")),s.data("ui-tooltip-open",!0),e&&"mouseover"===e.type&&s.parents().each(function(){var e,s=t(this);s.data("ui-tooltip-open")&&(e=t.Event("blur"),e.target=e.currentTarget=this,i.close(e,!0)),s.attr("title")&&(s.uniqueId(),i.parents[this.id]={element:this,title:s.attr("title")},s.attr("title",""))}),this._registerCloseHandlers(e,s),this._updateContent(s,e))},_updateContent:function(t,e){var i,s=this.options.content,n=this,o=e?e.type:null;return"string"==typeof s||s.nodeType||s.jquery?this._open(e,t,s):(i=s.call(t[0],function(i){n._delay(function(){t.data("ui-tooltip-open")&&(e&&(e.type=o),this._open(e,t,i))})}),i&&this._open(e,t,i),void 0)},_open:function(e,i,s){function n(t){l.of=t,a.is(":hidden")||a.position(l)}var o,a,r,h,l=t.extend({},this.options.position);if(s){if(o=this._find(i))return o.tooltip.find(".ui-tooltip-content").html(s),void 0;i.is("[title]")&&(e&&"mouseover"===e.type?i.attr("title",""):i.removeAttr("title")),o=this._tooltip(i),a=o.tooltip,this._addDescribedBy(i,a.attr("id")),a.find(".ui-tooltip-content").html(s),this.liveRegion.children().hide(),h=t("<div>").html(a.find(".ui-tooltip-content").html()),h.removeAttr("name").find("[name]").removeAttr("name"),h.removeAttr("id").find("[id]").removeAttr("id"),h.appendTo(this.liveRegion),this.options.track&&e&&/^mouse/.test(e.type)?(this._on(this.document,{mousemove:n}),n(e)):a.position(t.extend({of:i},this.options.position)),a.hide(),this._show(a,this.options.show),this.options.track&&this.options.show&&this.options.show.delay&&(r=this.delayedShow=setInterval(function(){a.is(":visible")&&(n(l.of),clearInterval(r))},t.fx.interval)),this._trigger("open",e,{tooltip:a})}},_registerCloseHandlers:function(e,i){var s={keyup:function(e){if(e.keyCode===t.ui.keyCode.ESCAPE){var s=t.Event(e);s.currentTarget=i[0],this.close(s,!0)}}};i[0]!==this.element[0]&&(s.remove=function(){this._removeTooltip(this._find(i).tooltip)}),e&&"mouseover"!==e.type||(s.mouseleave="close"),e&&"focusin"!==e.type||(s.focusout="close"),this._on(!0,i,s)},close:function(e){var i,s=this,n=t(e?e.currentTarget:this.element),o=this._find(n);return o?(i=o.tooltip,o.closing||(clearInterval(this.delayedShow),n.data("ui-tooltip-title")&&!n.attr("title")&&n.attr("title",n.data("ui-tooltip-title")),this._removeDescribedBy(n),o.hiding=!0,i.stop(!0),this._hide(i,this.options.hide,function(){s._removeTooltip(t(this))}),n.removeData("ui-tooltip-open"),this._off(n,"mouseleave focusout keyup"),n[0]!==this.element[0]&&this._off(n,"remove"),this._off(this.document,"mousemove"),e&&"mouseleave"===e.type&&t.each(this.parents,function(e,i){t(i.element).attr("title",i.title),delete s.parents[e]}),o.closing=!0,this._trigger("close",e,{tooltip:i}),o.hiding||(o.closing=!1)),void 0):(n.removeData("ui-tooltip-open"),void 0)},_tooltip:function(e){var i=t("<div>").attr("role","tooltip"),s=t("<div>").appendTo(i),n=i.uniqueId().attr("id");return this._addClass(s,"ui-tooltip-content"),this._addClass(i,"ui-tooltip","ui-widget ui-widget-content"),i.appendTo(this._appendTo(e)),this.tooltips[n]={element:e,tooltip:i}},_find:function(t){var e=t.data("ui-tooltip-id");return e?this.tooltips[e]:null},_removeTooltip:function(t){t.remove(),delete this.tooltips[t.attr("id")]},_appendTo:function(t){var e=t.closest(".ui-front, dialog");return e.length||(e=this.document[0].body),e},_destroy:function(){var e=this;t.each(this.tooltips,function(i,s){var n=t.Event("blur"),o=s.element;n.target=n.currentTarget=o[0],e.close(n,!0),t("#"+i).remove(),o.data("ui-tooltip-title")&&(o.attr("title")||o.attr("title",o.data("ui-tooltip-title")),o.removeData("ui-tooltip-title"))}),this.liveRegion.remove()}}),t.uiBackCompat!==!1&&t.widget("ui.tooltip",t.ui.tooltip,{options:{tooltipClass:null},_tooltip:function(){var t=this._superApply(arguments);return this.options.tooltipClass&&t.tooltip.addClass(this.options.tooltipClass),t}}),t.ui.tooltip}); \ No newline at end of file
diff --git a/platform/www/lib/scripts/jquery/jquery.cookie.js b/platform/www/lib/scripts/jquery/jquery.cookie.js
new file mode 100644
index 0000000..c7f3a59
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery.cookie.js
@@ -0,0 +1,117 @@
+/*!
+ * jQuery Cookie Plugin v1.4.1
+ * https://github.com/carhartl/jquery-cookie
+ *
+ * Copyright 2013 Klaus Hartl
+ * Released under the MIT license
+ */
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD
+ define(['jquery'], factory);
+ } else if (typeof exports === 'object') {
+ // CommonJS
+ factory(require('jquery'));
+ } else {
+ // Browser globals
+ factory(jQuery);
+ }
+}(function ($) {
+
+ var pluses = /\+/g;
+
+ function encode(s) {
+ return config.raw ? s : encodeURIComponent(s);
+ }
+
+ function decode(s) {
+ return config.raw ? s : decodeURIComponent(s);
+ }
+
+ function stringifyCookieValue(value) {
+ return encode(config.json ? JSON.stringify(value) : String(value));
+ }
+
+ function parseCookieValue(s) {
+ if (s.indexOf('"') === 0) {
+ // This is a quoted cookie as according to RFC2068, unescape...
+ s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
+ }
+
+ try {
+ // Replace server-side written pluses with spaces.
+ // If we can't decode the cookie, ignore it, it's unusable.
+ // If we can't parse the cookie, ignore it, it's unusable.
+ s = decodeURIComponent(s.replace(pluses, ' '));
+ return config.json ? JSON.parse(s) : s;
+ } catch(e) {}
+ }
+
+ function read(s, converter) {
+ var value = config.raw ? s : parseCookieValue(s);
+ return $.isFunction(converter) ? converter(value) : value;
+ }
+
+ var config = $.cookie = function (key, value, options) {
+
+ // Write
+
+ if (value !== undefined && !$.isFunction(value)) {
+ options = $.extend({}, config.defaults, options);
+
+ if (typeof options.expires === 'number') {
+ var days = options.expires, t = options.expires = new Date();
+ t.setTime(+t + days * 864e+5);
+ }
+
+ return (document.cookie = [
+ encode(key), '=', stringifyCookieValue(value),
+ options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
+ options.path ? '; path=' + options.path : '',
+ options.domain ? '; domain=' + options.domain : '',
+ options.secure ? '; secure' : ''
+ ].join(''));
+ }
+
+ // Read
+
+ var result = key ? undefined : {};
+
+ // To prevent the for loop in the first place assign an empty array
+ // in case there are no cookies at all. Also prevents odd result when
+ // calling $.cookie().
+ var cookies = document.cookie ? document.cookie.split('; ') : [];
+
+ for (var i = 0, l = cookies.length; i < l; i++) {
+ var parts = cookies[i].split('=');
+ var name = decode(parts.shift());
+ var cookie = parts.join('=');
+
+ if (key && key === name) {
+ // If second argument (value) is a function it's a converter...
+ result = read(cookie, value);
+ break;
+ }
+
+ // Prevent storing a cookie that we couldn't decode.
+ if (!key && (cookie = read(cookie)) !== undefined) {
+ result[name] = cookie;
+ }
+ }
+
+ return result;
+ };
+
+ config.defaults = {};
+
+ $.removeCookie = function (key, options) {
+ if ($.cookie(key) === undefined) {
+ return false;
+ }
+
+ // Must not alter options, thus extending a fresh object...
+ $.cookie(key, '', $.extend({}, options, { expires: -1 }));
+ return !$.cookie(key);
+ };
+
+}));
diff --git a/platform/www/lib/scripts/jquery/jquery.min.js b/platform/www/lib/scripts/jquery/jquery.min.js
new file mode 100644
index 0000000..b061403
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/jquery.min.js
@@ -0,0 +1,2 @@
+/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */
+!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",B=new RegExp(M+"+","g"),$=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&j.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(B," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,"$1"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[S]&&(v=Ce(v)),y&&!y[S]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace($,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=S.split("").sort(D).join("")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[":"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(D(this,e||[],!1))},not:function(e){return this.pushStack(D(this,e||[],!0))},is:function(e){return!!D(this,"string"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var j,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[["notify","progress",S.Callbacks("memory"),S.Callbacks("memory"),2],["resolve","done",S.Callbacks("once memory"),S.Callbacks("once memory"),0,"resolved"],["reject","fail",S.Callbacks("once memory"),S.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),S.ready()}S.fn.ready=function(e){return F.then(e)["catch"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===S.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,"")},u=s(),l=n&&n[3]||(S.cssNumber[t]?"":"px"),c=e.nodeType&&(S.cssNumber[t]||"px"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",y.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,y.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^key/,we=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Te=/^([^.]*)(?:\.(.+)|)/;function Ce(){return!0}function Ee(){return!1}function Se(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function ke(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)ke(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ee;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Ae(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,Ce)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=Te.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=Te.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||S.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ae(t,"click",Ce),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ae(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ce:Ee,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Ee,isPropagationStopped:Ee,isImmediatePropagationStopped:Ee,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ce,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ce,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ce,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&be.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&we.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},S.event.addProp),S.each({focus:"focusin",blur:"focusout"},function(e,t){S.event.special[e]={setup:function(){return Ae(this,e,Se),!1},trigger:function(){return Ae(this,e),!0},delegateType:t}}),S.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return ke(this,e,t,n,r)},one:function(e,t,n,r){return ke(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Ee),this.each(function(){S.event.remove(this,e,n,t)})}});var Ne=/<script|<style|<link/i,De=/checked\s*(?:[^=]|=\s*.checked.)/i,je=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function Pe(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&De.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Pe(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ve(e,"script"),Le)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,He),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&S.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(je,""),u,l))}return n}function Re(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ve(r)),r.parentNode&&(n&&ie(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Oe(o[r],a[r]);else Oe(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Re(this,e,!0)},remove:function(e){return Re(this,e)},text:function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Pe(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||qe(this,e).appendChild(e)})},prepend:function(){return Pe(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=qe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ne.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Pe(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Me=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Ie=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},We=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Fe=new RegExp(ne.join("|"),"i");function Be(e,t,n){var r,i,o,a,s=e.style;return(n=n||Ie(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=S.style(e,t)),!y.pixelBoxStyles()&&Me.test(a)&&Fe.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function $e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement("div"),l=E.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===l.style.backgroundClip,S.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement("table"),t=E.createElement("tr"),n=E.createElement("div"),e.style.cssText="position:absolute;left:-11111px",t.style.height="1px",n.style.height="9px",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=3<parseInt(r.height),re.removeChild(e)),a}}))}();var _e=["Webkit","Moz","ms"],ze=E.createElement("div").style,Ue={};function Xe(e){var t=S.cssProps[e]||Ue[e];return t||(e in ze?e:Ue[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=_e.length;while(n--)if((e=_e[n]+t)in ze)return e}(e)||e)}var Ve=/^(none|table(?!-c[ea]).+)/,Ge=/^--/,Ye={position:"absolute",visibility:"hidden",display:"block"},Qe={letterSpacing:"0",fontWeight:"400"};function Je(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ke(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=S.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=S.css(e,"border"+ne[a]+"Width",!0,i))):(u+=S.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=S.css(e,"border"+ne[a]+"Width",!0,i):s+=S.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Ze(e,t,n){var r=Ie(e),i=(!y.boxSizingReliable()||n)&&"border-box"===S.css(e,"boxSizing",!1,r),o=i,a=Be(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Me.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===S.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===S.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ke(e,t,n||(i?"border":"content"),o,r,a)+"px"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Ge.test(t),l=e.style;if(u||(t=Xe(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Ge.test(t)||(t=Xe(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),"normal"===i&&t in Qe&&(i=Qe[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each(["height","width"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ve.test(S.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Ze(e,u,n):We(e,Ye,function(){return Ze(e,u,n)})},set:function(e,t,n){var r,i=Ie(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===S.css(e,"boxSizing",!1,i),s=n?Ke(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Ke(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=S.css(e,u)),Je(0,t,s)}}}),S.cssHooks.marginLeft=$e(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Be(e,"marginLeft"))||e.getBoundingClientRect().left-We(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),S.each({margin:"",padding:"",border:"Width"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(S.cssHooks[i+o].set=Je)}),S.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Ie(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=et).prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?"":"px")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}}).init.prototype=et.prototype,(et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[Xe(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},S.fx=et.prototype.init,S.fx.step={};var tt,nt,rt,it,ot=/^(?:toggle|show|hide)$/,at=/queueHooks$/;function st(){nt&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(st):C.setTimeout(st,S.fx.interval),S.fx.tick())}function ut(){return C.setTimeout(function(){tt=void 0}),tt=Date.now()}function lt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ct(e,t,n){for(var r,i=(ft.tweeners[t]||[]).concat(ft.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ft(o,e,t){var n,a,r=0,i=ft.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=tt||ut(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:tt||ut(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=ft.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ct,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(ft,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],ft.tweeners[n]=ft.tweeners[n]||[],ft.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),v=Y.get(e,"fxshow");for(r in n.queue||(null==(a=S._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],ot.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Y.get(e,"display")),"none"===(c=S.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===S.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Y.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)S.style(e,r,d[r])})),u=ct(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?ft.prefilters.unshift(e):ft.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&"object"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=ft(this,S.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&at.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each(["toggle","show","hide"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(lt(r,!0),e,t,n)}}),S.each({slideDown:lt("show"),slideUp:lt("hide"),slideToggle:lt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(tt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),tt=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){nt||(nt=!0,st())},S.fx.stop=function(){nt=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},rt=E.createElement("input"),it=E.createElement("select").appendChild(E.createElement("option")),rt.type="checkbox",y.checkOn=""!==rt.value,y.optSelected=it.selected,(rt=E.createElement("input")).value="t",rt.type="radio",y.radioValue="t"===rt.value;var pt,dt=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return $(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?pt:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),pt={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\w+/g),function(e,t){var a=dt[t]||S.find.attr;dt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=dt[o],dt[o]=r,r=null!=a(e,t,n)?o:null,dt[o]=i),r}});var ht=/^(?:input|select|textarea|button)$/i,gt=/^(?:a|area)$/i;function vt(e){return(e.match(P)||[]).join(" ")}function yt(e){return e.getAttribute&&e.getAttribute("class")||""}function mt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return $(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,"tabindex");return t?parseInt(t,10):ht.test(e.nodeName)||gt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).addClass(t.call(this,e,yt(this)))});if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).removeClass(t.call(this,e,yt(this)))});if(!arguments.length)return this.attr("class","");if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){S(this).toggleClass(i.call(this,e,yt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=S(this),r=mt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=yt(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Y.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+vt(yt(n))+" ").indexOf(t))return!0;return!1}});var xt=/\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?"":e+""})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(xt,""):null==e?"":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,"value");return null!=t?t:vt(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each(["radio","checkbox"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},y.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var bt=/^(?:focusinfocus|focusoutblur)$/,wt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!bt.test(d+S.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[S.expando]?e:new S.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,bt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,wt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,wt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),y.focusin||S.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var Tt=C.location,Ct={guid:Date.now()},Et=/\?/;S.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||S.error("Invalid XML: "+e),t};var St=/\[\]$/,kt=/\r?\n/g,At=/^(?:submit|button|image|reset|file)$/i,Nt=/^(?:input|select|textarea|keygen)/i;function Dt(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||St.test(n)?i(n,t):Dt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)Dt(n+"["+t+"]",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)Dt(n,e[n],t,i);return r.join("&")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,"elements");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(":disabled")&&Nt.test(this.nodeName)&&!At.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(kt,"\r\n")}}):{name:t.name,value:n.replace(kt,"\r\n")}}).get()}});var jt=/%20/g,qt=/#.*$/,Lt=/([?&])_=[^&]*/,Ht=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ot=/^(?:GET|HEAD)$/,Pt=/^\/\//,Rt={},Mt={},It="*/".concat("*"),Wt=E.createElement("a");function Ft(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Bt(t,i,o,a){var s={},u=t===Mt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function $t(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Wt.href=Tt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Tt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Tt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":It,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?$t($t(e,S.ajaxSettings),t):$t(S.ajaxSettings,e)},ajaxPrefilter:Ft(Rt),ajaxTransport:Ft(Mt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=S.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?S(y):S.event,x=S.Deferred(),b=S.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Ht.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Tt.href)+"").replace(Pt,Tt.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(P)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Wt.protocol+"//"+Wt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=S.param(v.data,v.traditional)),Bt(Rt,v,t,T),h)return T;for(i in(g=S.event&&v.global)&&0==S.active++&&S.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Ot.test(v.type),f=v.url.replace(qt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(jt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(Et.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Lt,"$1"),o=(Et.test(f)?"&":"?")+"_="+Ct.guid+++o),v.url=f+o),v.ifModified&&(S.lastModified[f]&&T.setRequestHeader("If-Modified-Since",S.lastModified[f]),S.etag[f]&&T.setRequestHeader("If-None-Match",S.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+It+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Bt(Mt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<S.inArray("script",v.dataTypes)&&(v.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(S.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(S.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--S.active||S.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,"json")},getScript:function(e,t){return S.get(e,void 0,t,"script")}}),S.each(["get","post"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},zt=S.ajaxSettings.xhr();y.cors=!!zt&&"withCredentials"in zt,y.ajax=zt=!!zt,S.ajaxTransport(function(i){var o,a;if(y.cors||zt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(_t[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),S.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=vt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&S.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?S("<div>").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Gt=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?"":(e+"").replace(Gt,"")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return S});var Yt=C.jQuery,Qt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Qt),e&&C.jQuery===S&&(C.jQuery=Yt),S},"undefined"==typeof e&&(C.jQuery=C.$=S),S});
diff --git a/platform/www/lib/scripts/jquery/update.sh b/platform/www/lib/scripts/jquery/update.sh
new file mode 100755
index 0000000..10c29c4
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/update.sh
@@ -0,0 +1,48 @@
+#!/usr/bin/env sh
+#
+# This script loads the latest jQuery and jQuery-UI 1.* versions from jQuery's CDN
+#
+# It also loads the 'smoothness' jQuery-UI theme and all referenced images.
+#
+# @author Andreas Gohr <andi@splitbrain.org>
+# @author Stefan Grönke <stefan@gronke.net>
+# @link http://code.jquery.com/
+
+# load version infor from external file
+source ./versions
+JQUI_HOST="https://code.jquery.com/ui/$JQUI_VERSION"
+JQUI_GIT="https://raw.githubusercontent.com/jquery/jquery-ui/$JQUI_VERSION/ui"
+
+# load jQuery
+wget -nv https://code.jquery.com/jquery-${JQ_VERSION}.min.js -O jquery.min.js
+# load jQuery-UI
+wget -nv "$JQUI_HOST/jquery-ui.min.js" -O jquery-ui.min.js
+
+# load the smoothness theme
+mkdir -p jquery-ui-theme/images
+wget -nv -qO- "$JQUI_HOST/themes/smoothness/jquery-ui.css" | sed "s/font-family:[^;]*;//" > jquery-ui-theme/smoothness.css
+images=`gawk 'match($0, /url\("?(images\/[^\)"]+)"?\)/, m) { print m[1] }' jquery-ui-theme/smoothness.css`
+for img in $images
+do
+ wget -nv "$JQUI_HOST/themes/smoothness/$img" -O jquery-ui-theme/$img
+done
+
+# load the localization data for jquery ui
+for LNG in ../../../inc/lang/*
+do
+ CODE=`basename $LNG`
+ wget -nv "$JQUI_GIT/i18n/datepicker-$CODE.js" -O $LNG/jquery.ui.datepicker.js
+ if [ ! -s "$LNG/jquery.ui.datepicker.js" ]; then
+ rm -f $LNG/jquery.ui.datepicker.js
+ fi
+done
+
+# some custom language codes
+wget -nv "$JQUI_GIT/i18n/datepicker-de.js" -O ../../../inc/lang/de-informal/jquery.ui.datepicker.js
+wget -nv "$JQUI_GIT/i18n/datepicker-pt-BR.js" -O ../../../inc/lang/pt-br/jquery.ui.datepicker.js
+wget -nv "$JQUI_GIT/i18n/datepicker-zh-CN.js" -O ../../../inc/lang/zh/jquery.ui.datepicker.js
+wget -nv "$JQUI_GIT/i18n/datepicker-zh-TW.js" -O ../../../inc/lang/zh-tw/jquery.ui.datepicker.js
+wget -nv "$JQUI_GIT/i18n/datepicker-cy-GB.js" -O ../../../inc/lang/cy/jquery.ui.datepicker.js
+
+# strip source maps
+sed -i '/sourceMappingURL/d' *.min.js
diff --git a/platform/www/lib/scripts/jquery/versions b/platform/www/lib/scripts/jquery/versions
new file mode 100644
index 0000000..6ff062a
--- /dev/null
+++ b/platform/www/lib/scripts/jquery/versions
@@ -0,0 +1,3 @@
+# this is loaded from the update.sh script and our PHP code
+JQ_VERSION=3.5.1
+JQUI_VERSION=1.12.1
diff --git a/platform/www/lib/scripts/linkwiz.js b/platform/www/lib/scripts/linkwiz.js
new file mode 100644
index 0000000..d82ca96
--- /dev/null
+++ b/platform/www/lib/scripts/linkwiz.js
@@ -0,0 +1,339 @@
+/**
+ * The Link Wizard
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+var dw_linkwiz = {
+ $wiz: null,
+ $entry: null,
+ result: null,
+ timer: null,
+ textArea: null,
+ selected: null,
+ selection: null,
+
+ /**
+ * Initialize the dw_linkwizard by creating the needed HTML
+ * and attaching the eventhandlers
+ */
+ init: function($editor){
+ // position relative to the text area
+ var pos = $editor.position();
+
+ // create HTML Structure
+ if(dw_linkwiz.$wiz)
+ return;
+ dw_linkwiz.$wiz = jQuery(document.createElement('div'))
+ .dialog({
+ autoOpen: false,
+ draggable: true,
+ title: LANG.linkwiz,
+ resizable: false
+ })
+ .html(
+ '<div>'+LANG.linkto+' <input type="text" class="edit" id="link__wiz_entry" autocomplete="off" /></div>'+
+ '<div id="link__wiz_result"></div>'
+ )
+ .parent()
+ .attr('id','link__wiz')
+ .css({
+ 'position': 'absolute',
+ 'top': (pos.top+20)+'px',
+ 'left': (pos.left+80)+'px'
+ })
+ .hide()
+ .appendTo('.dokuwiki:first');
+
+ dw_linkwiz.textArea = $editor[0];
+ dw_linkwiz.result = jQuery('#link__wiz_result')[0];
+
+ // scrollview correction on arrow up/down gets easier
+ jQuery(dw_linkwiz.result).css('position', 'relative');
+
+ dw_linkwiz.$entry = jQuery('#link__wiz_entry');
+ if(JSINFO.namespace){
+ dw_linkwiz.$entry.val(JSINFO.namespace+':');
+ }
+
+ // attach event handlers
+ jQuery('#link__wiz .ui-dialog-titlebar-close').on('click', dw_linkwiz.hide);
+ dw_linkwiz.$entry.keyup(dw_linkwiz.onEntry);
+ jQuery(dw_linkwiz.result).on('click', 'a', dw_linkwiz.onResultClick);
+ },
+
+ /**
+ * handle all keyup events in the entry field
+ */
+ onEntry: function(e){
+ if(e.keyCode == 37 || e.keyCode == 39){ //left/right
+ return true; //ignore
+ }
+ if(e.keyCode == 27){ //Escape
+ dw_linkwiz.hide();
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 38){ //Up
+ dw_linkwiz.select(dw_linkwiz.selected -1);
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 40){ //Down
+ dw_linkwiz.select(dw_linkwiz.selected +1);
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ if(e.keyCode == 13){ //Enter
+ if(dw_linkwiz.selected > -1){
+ var $obj = dw_linkwiz.$getResult(dw_linkwiz.selected);
+ if($obj.length > 0){
+ dw_linkwiz.resultClick($obj.find('a')[0]);
+ }
+ }else if(dw_linkwiz.$entry.val()){
+ dw_linkwiz.insertLink(dw_linkwiz.$entry.val());
+ }
+
+ e.preventDefault();
+ e.stopPropagation();
+ return false;
+ }
+ dw_linkwiz.autocomplete();
+ },
+
+ /**
+ * Get one of the results by index
+ *
+ * @param num int result div to return
+ * @returns DOMObject or null
+ */
+ getResult: function(num){
+ DEPRECATED('use dw_linkwiz.$getResult()[0] instead');
+ return dw_linkwiz.$getResult()[0] || null;
+ },
+
+ /**
+ * Get one of the results by index
+ *
+ * @param num int result div to return
+ * @returns jQuery object
+ */
+ $getResult: function(num) {
+ return jQuery(dw_linkwiz.result).find('div').eq(num);
+ },
+
+ /**
+ * Select the given result
+ */
+ select: function(num){
+ if(num < 0){
+ dw_linkwiz.deselect();
+ return;
+ }
+
+ var $obj = dw_linkwiz.$getResult(num);
+ if ($obj.length === 0) {
+ return;
+ }
+
+ dw_linkwiz.deselect();
+ $obj.addClass('selected');
+
+ // make sure the item is viewable in the scroll view
+
+ //getting child position within the parent
+ var childPos = $obj.position().top;
+ //getting difference between the childs top and parents viewable area
+ var yDiff = childPos + $obj.outerHeight() - jQuery(dw_linkwiz.result).innerHeight();
+
+ if (childPos < 0) {
+ //if childPos is above viewable area (that's why it goes negative)
+ jQuery(dw_linkwiz.result)[0].scrollTop += childPos;
+ } else if(yDiff > 0) {
+ // if difference between childs top and parents viewable area is
+ // greater than the height of a childDiv
+ jQuery(dw_linkwiz.result)[0].scrollTop += yDiff;
+ }
+
+ dw_linkwiz.selected = num;
+ },
+
+ /**
+ * deselect a result if any is selected
+ */
+ deselect: function(){
+ if(dw_linkwiz.selected > -1){
+ dw_linkwiz.$getResult(dw_linkwiz.selected).removeClass('selected');
+ }
+ dw_linkwiz.selected = -1;
+ },
+
+ /**
+ * Handle clicks in the result set an dispatch them to
+ * resultClick()
+ */
+ onResultClick: function(e){
+ if(!jQuery(this).is('a')) {
+ return;
+ }
+ e.stopPropagation();
+ e.preventDefault();
+ dw_linkwiz.resultClick(this);
+ return false;
+ },
+
+ /**
+ * Handles the "click" on a given result anchor
+ */
+ resultClick: function(a){
+ dw_linkwiz.$entry.val(a.title);
+ if(a.title == '' || a.title.substr(a.title.length-1) == ':'){
+ dw_linkwiz.autocomplete_exec();
+ }else{
+ if (jQuery(a.nextSibling).is('span')) {
+ dw_linkwiz.insertLink(a.nextSibling.innerHTML);
+ }else{
+ dw_linkwiz.insertLink('');
+ }
+ }
+ },
+
+ /**
+ * Insert the id currently in the entry box to the textarea,
+ * replacing the current selection or at the cursor position.
+ * When no selection is available the given title will be used
+ * as link title instead
+ */
+ insertLink: function(title){
+ var link = dw_linkwiz.$entry.val(),
+ sel, stxt;
+ if(!link) {
+ return;
+ }
+
+ sel = DWgetSelection(dw_linkwiz.textArea);
+ if(sel.start == 0 && sel.end == 0) {
+ sel = dw_linkwiz.selection;
+ }
+
+ stxt = sel.getText();
+
+ // don't include trailing space in selection
+ if(stxt.charAt(stxt.length - 1) == ' '){
+ sel.end--;
+ stxt = sel.getText();
+ }
+
+ if(!stxt && !DOKU_UHC) {
+ stxt=title;
+ }
+
+ // prepend colon inside namespaces for non namespace pages
+ if(dw_linkwiz.textArea.form.id.value.indexOf(':') != -1 &&
+ link.indexOf(':') == -1){
+ link = ':' + link;
+ }
+
+ var so = link.length;
+ var eo = 0;
+ if(dw_linkwiz.val){
+ if(dw_linkwiz.val.open) {
+ so += dw_linkwiz.val.open.length;
+ link = dw_linkwiz.val.open+link;
+ }
+ link += '|';
+ so += 1;
+ if(stxt) {
+ link += stxt;
+ }
+ if(dw_linkwiz.val.close) {
+ link += dw_linkwiz.val.close;
+ eo = dw_linkwiz.val.close.length;
+ }
+ }
+
+ pasteText(sel,link,{startofs: so, endofs: eo});
+ dw_linkwiz.hide();
+
+ // reset the entry to the parent namespace
+ var externallinkpattern = new RegExp('^((f|ht)tps?:)?//', 'i'),
+ entry_value;
+ if (externallinkpattern.test(dw_linkwiz.$entry.val())) {
+ if (JSINFO.namespace) {
+ entry_value = JSINFO.namespace + ':';
+ } else {
+ entry_value = ''; //reset whole external links
+ }
+ } else {
+ entry_value = dw_linkwiz.$entry.val().replace(/[^:]*$/, '')
+ }
+ dw_linkwiz.$entry.val(entry_value);
+ },
+
+ /**
+ * Start the page/namespace lookup timer
+ *
+ * Calls autocomplete_exec when the timer runs out
+ */
+ autocomplete: function(){
+ if(dw_linkwiz.timer !== null){
+ window.clearTimeout(dw_linkwiz.timer);
+ dw_linkwiz.timer = null;
+ }
+
+ dw_linkwiz.timer = window.setTimeout(dw_linkwiz.autocomplete_exec,350);
+ },
+
+ /**
+ * Executes the AJAX call for the page/namespace lookup
+ */
+ autocomplete_exec: function(){
+ var $res = jQuery(dw_linkwiz.result);
+ dw_linkwiz.deselect();
+ $res.html('<img src="'+DOKU_BASE+'lib/images/throbber.gif" alt="" width="16" height="16" />')
+ .load(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'linkwiz',
+ q: dw_linkwiz.$entry.val()
+ }
+ );
+ },
+
+ /**
+ * Show the link wizard
+ */
+ show: function(){
+ dw_linkwiz.selection = DWgetSelection(dw_linkwiz.textArea);
+ dw_linkwiz.$wiz.show();
+ dw_linkwiz.$entry.focus();
+ dw_linkwiz.autocomplete();
+
+ // Move the cursor to the end of the input
+ var temp = dw_linkwiz.$entry.val();
+ dw_linkwiz.$entry.val('');
+ dw_linkwiz.$entry.val(temp);
+ },
+
+ /**
+ * Hide the link wizard
+ */
+ hide: function(){
+ dw_linkwiz.$wiz.hide();
+ dw_linkwiz.textArea.focus();
+ },
+
+ /**
+ * Toggle the link wizard
+ */
+ toggle: function(){
+ if(dw_linkwiz.$wiz.css('display') == 'none'){
+ dw_linkwiz.show();
+ }else{
+ dw_linkwiz.hide();
+ }
+ }
+};
diff --git a/platform/www/lib/scripts/locktimer.js b/platform/www/lib/scripts/locktimer.js
new file mode 100644
index 0000000..7bc8a39
--- /dev/null
+++ b/platform/www/lib/scripts/locktimer.js
@@ -0,0 +1,151 @@
+/**
+ * Class managing the timer to display a warning on a expiring lock
+ */
+var dw_locktimer = {
+ timeout: 0,
+ draft: false,
+ timerID: null,
+ lasttime: null,
+ msg: LANG.willexpire,
+ pageid: '',
+ fieldsToSaveAsDraft: [
+ 'input[name=prefix]',
+ 'textarea[name=wikitext]',
+ 'input[name=suffix]',
+ 'input[name=date]',
+ ],
+ callbacks: [],
+
+ /**
+ * Initialize the lock timer
+ *
+ * @param {int} timeout Length of timeout in seconds
+ * @param {bool} draft Whether to save drafts
+ * @param {string} edid Optional; ID of an edit object which has to be present
+ */
+ init: function(timeout,draft,edid){
+ var $edit;
+
+ edid = edid || 'wiki__text';
+
+ $edit = jQuery('#' + edid);
+ if($edit.length === 0 || $edit.attr('readonly')) {
+ return;
+ }
+
+ // init values
+ dw_locktimer.timeout = timeout*1000;
+ dw_locktimer.draft = draft;
+ dw_locktimer.lasttime = new Date();
+
+ dw_locktimer.pageid = jQuery('#dw__editform').find('input[name=id]').val();
+ if(!dw_locktimer.pageid) {
+ return;
+ }
+
+ // register refresh event
+ $edit.keypress(dw_locktimer.refresh);
+ // start timer
+ dw_locktimer.reset();
+ },
+
+ /**
+ * Add another field of the editform to be posted to the server when a draft is saved
+ */
+ addField: function(selector) {
+ dw_locktimer.fieldsToSaveAsDraft.push(selector);
+ },
+
+ /**
+ * Add a callback that is executed when the post request to renew the lock and save the draft returns successfully
+ *
+ * If the user types into the edit-area, then dw_locktimer will regularly send a post request to the DokuWiki server
+ * to extend the page's lock and update the draft. When this request returns successfully, then the draft__status
+ * is updated. This method can be used to add further callbacks to be executed at that moment.
+ *
+ * @param {function} callback the only param is the data returned by the server
+ */
+ addRefreshCallback: function(callback) {
+ dw_locktimer.callbacks.push(callback);
+ },
+
+ /**
+ * (Re)start the warning timer
+ */
+ reset: function(){
+ dw_locktimer.clear();
+ dw_locktimer.timerID = window.setTimeout(dw_locktimer.warning, dw_locktimer.timeout);
+ },
+
+ /**
+ * Display the warning about the expiring lock
+ */
+ warning: function(){
+ dw_locktimer.clear();
+ alert(fixtxt(dw_locktimer.msg));
+ },
+
+ /**
+ * Remove the current warning timer
+ */
+ clear: function(){
+ if(dw_locktimer.timerID !== null){
+ window.clearTimeout(dw_locktimer.timerID);
+ dw_locktimer.timerID = null;
+ }
+ },
+
+ /**
+ * Refresh the lock via AJAX
+ *
+ * Called on keypresses in the edit area
+ */
+ refresh: function(){
+ var now = new Date(),
+ params = 'call=lock&id=' + dw_locktimer.pageid + '&';
+
+ // refresh every half minute only
+ if(now.getTime() - dw_locktimer.lasttime.getTime() <= 30*1000) {
+ return;
+ }
+
+ // POST everything necessary for draft saving
+ if(dw_locktimer.draft && jQuery('#dw__editform').find('textarea[name=wikitext]').length > 0){
+ params += jQuery('#dw__editform').find(dw_locktimer.fieldsToSaveAsDraft.join(', ')).serialize();
+ }
+
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ params,
+ null,
+ 'json'
+ ).done(function dwLocktimerRefreshDoneHandler(data) {
+ dw_locktimer.callbacks.forEach(
+ function (callback) {
+ callback(data);
+ }
+ );
+ });
+ dw_locktimer.lasttime = now;
+ },
+
+ /**
+ * Callback. Resets the warning timer
+ */
+ refreshed: function(data){
+ if (data.errors.length) {
+ data.errors.forEach(function(error) {
+ jQuery('#draft__status').after(
+ jQuery('<div class="error"></div>').text(error)
+ );
+ })
+ }
+
+ jQuery('#draft__status').html(data.draft);
+ if(data.lock !== '1') {
+ return; // locking failed
+ }
+ dw_locktimer.reset();
+ }
+};
+dw_locktimer.callbacks.push(dw_locktimer.refreshed);
diff --git a/platform/www/lib/scripts/media.js b/platform/www/lib/scripts/media.js
new file mode 100644
index 0000000..fda6463
--- /dev/null
+++ b/platform/www/lib/scripts/media.js
@@ -0,0 +1,974 @@
+/**
+ * JavaScript functionality for the media management popup
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+
+var dw_mediamanager = {
+ keepopen: false,
+ hide: false,
+ popup: false,
+ display: false,
+ ext: false,
+ $popup: null,
+
+ // Image insertion opts
+ align: false,
+ link: false,
+ size: false,
+ forbidden_opts: {},
+
+ // File list options
+ view_opts: {list: false, sort: false},
+
+ layout_width: 0,
+
+ // The minimum height of the full-screen mediamanager in px
+ minHeights: {thumbs: 200, rows: 100},
+
+ init: function () {
+ var $content, $tree;
+ $content = jQuery('#media__content');
+ $tree = jQuery('#media__tree');
+ if (!$tree.length) return;
+
+ dw_mediamanager.prepare_content($content);
+
+ dw_mediamanager.attachoptions();
+ dw_mediamanager.initpopup();
+
+ // add the action to autofill the "upload as" field
+ $content
+ .on('change', '#upload__file', dw_mediamanager.suggest)
+ // Attach the image selector action to all links
+ .on('click', 'a.select', dw_mediamanager.select)
+ // Attach deletion confirmation dialog to the delete buttons
+ .on('click', '#media__content a.btn_media_delete', dw_mediamanager.confirmattach)
+ .on('submit', '#mediamanager__done_form', dw_mediamanager.list);
+
+ $tree.dw_tree({
+ toggle_selector: 'img',
+ load_data: function (show_sublist, $clicky) {
+ // get the enclosed link (is always the first one)
+ var $link = $clicky.parent().find('div.li a.idx_dir');
+
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ $link[0].search.substr(1) + '&call=medians',
+ show_sublist,
+ 'html'
+ );
+ },
+
+ toggle_display: function ($clicky, opening) {
+ $clicky.attr('src', DOKU_BASE + 'lib/images/' + (opening ? 'minus' : 'plus') + '.gif');
+ }
+ });
+ $tree.on('click', 'a', dw_mediamanager.list);
+
+ // Init view property
+ dw_mediamanager.set_fileview_list();
+
+ dw_mediamanager.init_options();
+
+ dw_mediamanager.image_diff();
+ dw_mediamanager.init_ajax_uploader();
+
+ // changing opened tab in the file list panel
+ var $page = jQuery('#mediamanager__page');
+ $page.find('div.filelist')
+ .on('click', 'ul.tabs a', dw_mediamanager.list)
+ // loading file details
+ .on('click', 'div.panelContent a', dw_mediamanager.details)
+ // search form
+ .on('submit', '#dw__mediasearch', dw_mediamanager.list)
+ // "upload as" field autofill
+ .on('change', '#upload__file', dw_mediamanager.suggest)
+ // uploaded images
+ .on('click', '.qq-upload-file a', dw_mediamanager.details);
+
+ // changing opened tab in the file details panel
+ $page.find('div.file')
+ .on('click', 'ul.tabs a', dw_mediamanager.details)
+ // "update new version" button
+ .on('submit', '#mediamanager__btn_update', dw_mediamanager.list)
+ // revisions form
+ .on('submit', '#page__revisions', dw_mediamanager.details)
+ .on('click', '#page__revisions a', dw_mediamanager.details)
+ // meta edit form
+ .on('submit', '#mediamanager__save_meta', dw_mediamanager.details)
+ // delete button
+ .on('submit', '#mediamanager__btn_delete', dw_mediamanager.details)
+ // "restore this version" button
+ .on('submit', '#mediamanager__btn_restore', dw_mediamanager.details)
+ // less/more recent buttons in media revisions form
+ .on('submit', '.btn_newer, .btn_older', dw_mediamanager.details);
+
+ dw_mediamanager.update_resizable();
+ dw_mediamanager.layout_width = $page.width();
+ jQuery(window).on('resize', dw_mediamanager.window_resize);
+ },
+
+ init_options: function () {
+ var $options = jQuery('div.filelist div.panelHeader form.options'),
+ $listType, $sortBy, $both;
+ if ($options.length === 0) {
+ return;
+ }
+
+ $listType = $options.find('li.listType');
+ $sortBy = $options.find('li.sortBy');
+ $both = $listType.add($sortBy);
+
+ // Remove the submit button
+ $options.find('button[type=submit]').parent().hide();
+
+ // Prepare HTML for jQuery UI buttonset
+ $both.find('label').each(function () {
+ var $this = jQuery(this);
+ $this.children('input').appendTo($this.parent());
+ });
+
+ // Init buttonset
+ $both.find("input[type='radio']").checkboxradio({icon: false});
+ $both.controlgroup();
+
+ // Change handlers
+ $listType.children('input').change(function () {
+ dw_mediamanager.set_fileview_list();
+ });
+ $sortBy.children('input').change(function (event) {
+ dw_mediamanager.set_fileview_sort();
+ dw_mediamanager.list.call(jQuery('#dw__mediasearch')[0] || this, event);
+ });
+ },
+
+ /**
+ * build the popup window
+ *
+ * @author Dominik Eckelmann <eckelmann@cosmocode.de>
+ */
+ initpopup: function () {
+ var opts, $insp, $insbtn;
+
+ dw_mediamanager.$popup = jQuery(document.createElement('div'))
+ .attr('id', 'media__popup_content')
+ .dialog({
+ autoOpen: false, width: 280, modal: true,
+ draggable: true, title: LANG.mediatitle,
+ resizable: false
+ });
+
+ opts = [
+ {
+ id: 'link', label: LANG.mediatarget,
+ btns: ['lnk', 'direct', 'nolnk', 'displaylnk']
+ },
+ {
+ id: 'align', label: LANG.mediaalign,
+ btns: ['noalign', 'left', 'center', 'right']
+ },
+ {
+ id: 'size', label: LANG.mediasize,
+ btns: ['small', 'medium', 'large', 'original']
+ }
+ ];
+
+ jQuery.each(opts, function (_, opt) {
+ var $p, $l;
+ $p = jQuery(document.createElement('p'))
+ .attr('id', 'media__' + opt.id);
+
+ if (dw_mediamanager.display === "2") {
+ $p.hide();
+ }
+
+ $l = jQuery(document.createElement('label'))
+ .text(opt.label);
+ $p.append($l);
+
+ jQuery.each(opt.btns, function (i, text) {
+ var $btn, $img;
+ $btn = jQuery(document.createElement('button'))
+ .addClass('button')
+ .attr('id', "media__" + opt.id + "btn" + (i + 1))
+ .attr('title', LANG['media' + text])
+ .on('click', bind(dw_mediamanager.setOpt, opt.id));
+
+ $img = jQuery(document.createElement('img'))
+ .attr('src', DOKU_BASE + 'lib/images/media_' + opt.id + '_' + text + '.png');
+
+ $btn.append($img);
+ $p.append($btn);
+ });
+
+ dw_mediamanager.$popup.append($p);
+ });
+
+ // insert button
+ $insp = jQuery(document.createElement('p'));
+ dw_mediamanager.$popup.append($insp);
+
+ $insbtn = jQuery(document.createElement('input'))
+ .attr('id', 'media__sendbtn')
+ .attr('type', 'button')
+ .addClass('button')
+ .val(LANG.mediainsert);
+ $insp.append($insbtn);
+ },
+
+ /**
+ * Insert the clicked image into the opener's textarea
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Dominik Eckelmann <eckelmann@cosmocode.de>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ insert: function (id) {
+ var opts, cb, edid, s;
+
+ // set syntax options
+ dw_mediamanager.$popup.dialog('close');
+
+ opts = '';
+
+ if ({img: 1, swf: 1}[dw_mediamanager.ext] === 1) {
+
+ if (dw_mediamanager.link === '4') {
+ opts = '?linkonly';
+ } else {
+
+ if (dw_mediamanager.link === "3" && dw_mediamanager.ext === 'img') {
+ opts = '?nolink';
+ } else if (dw_mediamanager.link === "2" && dw_mediamanager.ext === 'img') {
+ opts = '?direct';
+ }
+
+ s = parseInt(dw_mediamanager.size, 10);
+ var size = s * 200;
+
+ if (s && s >= 1 && s < 4) {
+ opts += (opts.length) ? '&' : '?';
+ opts += size;
+ if (dw_mediamanager.ext === 'swf') {
+ switch (s) {
+ case 1:
+ opts += 'x62';
+ break;
+ case 2:
+ opts += 'x123';
+ break;
+ case 3:
+ opts += 'x185';
+ break;
+ }
+ }
+ }
+ }
+ }
+ edid = String.prototype.match.call(document.location, /&edid=([^&]+)/);
+ edid = edid ? edid[1] : 'wiki__text';
+ cb = String.prototype.match.call(document.location, /&onselect=([^&]+)/);
+ cb = cb ? cb[1].replace(/[^\w]+/, '') : 'dw_mediamanager_item_select';
+
+ // arguments here only match the dw_mediamanager_item_select function, these will need to change if you override cb with onselect GET param
+ opener[cb](edid, id, opts, dw_mediamanager.align, dw_mediamanager.keepopen);
+ if (!dw_mediamanager.keepopen) {
+ window.close();
+ }
+ opener.focus();
+ return false;
+ },
+
+
+ /**
+ * Prefills the wikiname.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ suggest: function () {
+ var $file, $name, text;
+
+ $file = jQuery(this);
+ $name = jQuery('#upload__name');
+
+ if ($name.val() != '') return;
+
+ if (!$file.length || !$name.length) {
+ return;
+ }
+
+ text = $file.val();
+ text = text.substr(text.lastIndexOf('/') + 1);
+ text = text.substr(text.lastIndexOf('\\') + 1);
+ $name.val(text);
+ },
+
+ /**
+ * list the content of a namespace using AJAX
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ list: function (event) {
+ var $link, $content, params;
+
+ if (event) {
+ event.preventDefault();
+ }
+
+ jQuery('div.success, div.info, div.error, div.notify').remove();
+
+ $link = jQuery(this);
+
+ //popup
+ $content = jQuery('#media__content');
+
+ if ($content.length === 0) {
+ //fullscreen media manager
+ $content = jQuery('div.filelist');
+
+ if ($link.hasClass('idx_dir')) {
+ //changing namespace
+ jQuery('div.file').empty();
+ jQuery('div.namespaces .selected').removeClass('selected');
+ $link.addClass('selected');
+ }
+ }
+
+ params = 'call=medialist&';
+
+ if ($link[0].search) {
+ params += $link[0].search.substr(1);
+ } else if ($link.is('form')) {
+ params += dw_mediamanager.form_params($link);
+ } else if ($link.closest('form').length > 0) {
+ params += dw_mediamanager.form_params($link.closest('form'));
+ }
+
+ // fetch the subtree
+ dw_mediamanager.update_content($content, params);
+ },
+
+ /**
+ * Returns form parameters
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ form_params: function ($form) {
+ if (!$form.length) return;
+
+ var action = '';
+ var i = $form[0].action.indexOf('?');
+ if (i >= 0) {
+ action = $form[0].action.substr(i + 1);
+ }
+ return action + '&' + $form.serialize();
+ },
+
+ set_fileview_list: function (new_type) {
+ dw_mediamanager.set_fileview_opt(['list', 'listType', function (new_type) {
+ jQuery('div.filelist div.panelContent ul')
+ .toggleClass('rows', new_type === 'rows')
+ .toggleClass('thumbs', new_type === 'thumbs');
+ }], new_type);
+
+ // FIXME: Move to onchange handler (opt[2])?
+ dw_mediamanager.resize();
+ },
+
+ set_fileview_sort: function (new_sort) {
+ dw_mediamanager.set_fileview_opt(['sort', 'sortBy', function (new_sort) {
+ // FIXME
+ }], new_sort);
+ },
+
+ set_fileview_opt: function (opt, new_val) {
+ if (typeof new_val === 'undefined') {
+ new_val = jQuery('form.options li.' + opt[1] + ' input')
+ .filter(':checked').val();
+ // if new_val is still undefined (because form.options is not in active tab), set to most spacious option
+ if (typeof new_val === 'undefined') {
+ new_val = 'thumbs';
+ }
+ }
+
+ if (new_val !== dw_mediamanager.view_opts[opt[0]]) {
+ opt[2](new_val);
+
+ DokuCookie.setValue(opt[0], new_val);
+
+ dw_mediamanager.view_opts[opt[0]] = new_val;
+ }
+ },
+
+ /**
+ * Lists the content of the right column (image details) using AJAX
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ details: function (event) {
+ var $link, $content, params, update_list;
+ $link = jQuery(this);
+ event.preventDefault();
+
+ jQuery('div.success, div.info, div.error, div.notify').remove();
+
+ if ($link[0].id == 'mediamanager__btn_delete' && !confirm(LANG.del_confirm)) {
+ return false;
+ }
+ if ($link[0].id == 'mediamanager__btn_restore' && !confirm(LANG.restore_confirm)) {
+ return false;
+ }
+
+ $content = jQuery('div.file');
+ params = 'call=mediadetails&';
+
+ if ($link[0].search) {
+ params += $link[0].search.substr(1);
+ } else if ($link.is('form')) {
+ params += dw_mediamanager.form_params($link);
+ } else if ($link.closest('form').length > 0) {
+ params += dw_mediamanager.form_params($link.closest('form'));
+ }
+
+ update_list = ($link[0].id == 'mediamanager__btn_delete' ||
+ $link[0].id == 'mediamanager__btn_restore');
+
+ dw_mediamanager.update_content($content, params, update_list);
+ },
+
+ update_content: function ($content, params, update_list) {
+ var $container;
+
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ params,
+ function (data) {
+ dw_mediamanager.$resizables().resizable('destroy');
+
+ if (update_list) {
+ dw_mediamanager.list.call(jQuery('#mediamanager__page').find('form.options button[type="submit"]')[0]);
+ }
+
+ $content.html(data);
+
+ dw_mediamanager.prepare_content($content);
+ dw_mediamanager.updatehide();
+
+ dw_mediamanager.update_resizable();
+ dw_behaviour.revisionBoxHandler();
+
+ // Make sure that the list view style stays the same
+ dw_mediamanager.set_fileview_list(dw_mediamanager.view_opts.list);
+
+ dw_mediamanager.image_diff();
+ dw_mediamanager.init_ajax_uploader();
+ dw_mediamanager.init_options();
+
+ },
+ 'html'
+ );
+ $container = $content.find('div.panelContent');
+ if ($container.length === 0) {
+ $container = $content;
+ }
+ $container.html('<img src="' + DOKU_BASE + 'lib/images/throbber.gif" alt="..." class="load" />');
+ },
+
+ window_resize: function () {
+ dw_mediamanager.resize();
+
+ dw_mediamanager.opacity_slider();
+ dw_mediamanager.portions_slider();
+ },
+
+ $resizables: function () {
+ return jQuery('#mediamanager__page').find('div.namespaces, div.filelist');
+ },
+
+ /**
+ * Updates mediamanager layout
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ update_resizable: function () {
+ var $resizables = dw_mediamanager.$resizables();
+
+ $resizables.resizable({
+ handles: (jQuery('html[dir=rtl]').length ? 'w' : 'e'),
+ resize: function (event, ui) {
+ var $page = jQuery('#mediamanager__page');
+ var widthFull = $page.width();
+ var widthResizables = 0;
+ $resizables.each(function () {
+ widthResizables += jQuery(this).width();
+ });
+ var $filePanel = $page.find('div.panel.file');
+
+ // set max width of resizable column
+ var widthOtherResizable = widthResizables - jQuery(this).width();
+ var minWidthNonResizable = parseFloat($filePanel.css("min-width"));
+ var maxWidth = widthFull - (widthOtherResizable + minWidthNonResizable) - 1;
+ $resizables.resizable("option", "maxWidth", maxWidth);
+
+ // width of file panel in % = 100% - width of resizables in %
+ // this calculates with 99.9 and not 100 to overcome rounding errors
+ var relWidthNonResizable = 99.9 - (100 * widthResizables / widthFull);
+ // set width of file panel
+ $filePanel.width(relWidthNonResizable + '%');
+
+ dw_mediamanager.resize();
+
+ dw_mediamanager.opacity_slider();
+ dw_mediamanager.portions_slider();
+ }
+ });
+
+ dw_mediamanager.resize();
+ },
+
+ resize: function () {
+ var $contents = jQuery('#mediamanager__page').find('div.panelContent'),
+ height = jQuery(window).height() - jQuery(document.body).height() +
+ Math.max.apply(null, jQuery.map($contents, function (v) {
+ return jQuery(v).height();
+ }));
+
+ // If the screen is too small, don’t try to resize
+ if (height < dw_mediamanager.minHeights[dw_mediamanager.view_opts.list]) {
+ $contents.add(dw_mediamanager.$resizables()).height('auto');
+ } else {
+ $contents.height(height);
+ dw_mediamanager.$resizables().each(function () {
+ var $this = jQuery(this);
+ $this.height(height + $this.find('div.panelContent').offset().top - $this.offset().top);
+ });
+ }
+ },
+
+ /**
+ * Prints 'select' for image difference representation type
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ image_diff: function () {
+ if (jQuery('#mediamanager__difftype').length) return;
+
+ var $form = jQuery('#mediamanager__form_diffview');
+ if (!$form.length) return;
+
+ var $label = jQuery(document.createElement('label'));
+ $label.append('<span>' + LANG.media_diff + '</span> ');
+ var $select = jQuery(document.createElement('select'))
+ .attr('id', 'mediamanager__difftype')
+ .attr('name', 'difftype')
+ .change(dw_mediamanager.change_diff_type);
+ $select.append(new Option(LANG.media_diff_both, "both"));
+ $select.append(new Option(LANG.media_diff_opacity, "opacity"));
+ $select.append(new Option(LANG.media_diff_portions, "portions"));
+ $label.append($select);
+ $form.append($label);
+
+ // for IE
+ var select = document.getElementById('mediamanager__difftype');
+ select.options[0].text = LANG.media_diff_both;
+ select.options[1].text = LANG.media_diff_opacity;
+ select.options[2].text = LANG.media_diff_portions;
+ },
+
+ /**
+ * Handles selection of image difference representation type
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ change_diff_type: function () {
+ var $select = jQuery('#mediamanager__difftype');
+ var $content = jQuery('#mediamanager__diff');
+
+ var params = dw_mediamanager.form_params($select.closest('form')) + '&call=mediadiff';
+ jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ params,
+ function (data) {
+ $content.html(data);
+ dw_mediamanager.portions_slider();
+ dw_mediamanager.opacity_slider();
+ },
+ 'html'
+ );
+ },
+
+ /**
+ * Sets options for opacity diff slider
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ opacity_slider: function () {
+ var $diff = jQuery("#mediamanager__diff");
+ var $slider = $diff.find("div.slider");
+ if (!$slider.length) return;
+
+ var $image = $diff.find('div.imageDiff.opacity div.image1 img');
+ if (!$image.length) return;
+ $slider.width($image.width() - 20);
+
+ $slider.slider();
+ $slider.slider("option", "min", 0);
+ $slider.slider("option", "max", 0.999);
+ $slider.slider("option", "step", 0.001);
+ $slider.slider("option", "value", 0.5);
+ $slider.on("slide", function (event, ui) {
+ jQuery('#mediamanager__diff').find('div.imageDiff.opacity div.image2 img').css({opacity: $slider.slider("option", "value")});
+ });
+ },
+
+ /**
+ * Sets options for red line diff slider
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ portions_slider: function () {
+ var $diff = jQuery("#mediamanager__diff");
+ if (!$diff.length) return;
+
+ var $image1 = $diff.find('div.imageDiff.portions div.image1 img');
+ var $image2 = $diff.find('div.imageDiff.portions div.image2 img');
+ if (!$image1.length || !$image2.length) return;
+
+ $diff.width('100%');
+ $image2.parent().width('97%');
+ $image1.width('100%');
+ $image2.width('100%');
+
+ if ($image1.width() < $diff.width()) {
+ $diff.width($image1.width());
+ }
+
+ $image2.parent().width('50%');
+ $image2.width($image1.width());
+ $image1.width($image1.width());
+
+ var $slider = $diff.find("div.slider");
+ if (!$slider.length) return;
+ $slider.width($image1.width() - 20);
+
+ $slider.slider();
+ $slider.slider("option", "min", 0);
+ $slider.slider("option", "max", 97);
+ $slider.slider("option", "step", 1);
+ $slider.slider("option", "value", 50);
+ $slider.on("slide", function (event, ui) {
+ jQuery('#mediamanager__diff').find('div.imageDiff.portions div.image2').css({width: $slider.slider("option", "value") + '%'});
+ });
+ },
+
+ /**
+ * Parse a URI query string to an associative array
+ *
+ * @author Kate Arzamastseva <pshns@ukr.net>
+ */
+ params_toarray: function (str) {
+ var vars = [], hash;
+ var hashes = str.split('&');
+ for (var i = 0; i < hashes.length; i++) {
+ hash = hashes[i].split('=');
+ vars[decodeURIComponent(hash[0])] = decodeURIComponent(hash[1]);
+ }
+ return vars;
+ },
+
+ init_ajax_uploader: function () {
+ if (!jQuery('#mediamanager__uploader').length) return;
+ if (jQuery('.qq-upload-list').length) return;
+
+ var params = dw_mediamanager.form_params(jQuery('#dw__upload')) + '&call=mediaupload';
+ params = dw_mediamanager.params_toarray(params);
+
+ var uploader = new qq.FileUploaderExtended({
+ element: document.getElementById('mediamanager__uploader'),
+ action: DOKU_BASE + 'lib/exe/ajax.php',
+ params: params
+ });
+ },
+
+ prepare_content: function ($content) {
+ // hide syntax example
+ $content.find('div.example:visible').hide();
+ // toggle list of allowed mime types
+ $content.find('a.allowedmime').on('click', function (event) {
+ event.preventDefault();
+ $toggle = jQuery(this);
+ $list = $toggle.next('span');
+ $list.toggle();
+ }).next('span').hide();
+
+ },
+
+ /**
+ * shows the popup for a image link
+ */
+ select: function (event) {
+ var $link, id, dot, ext;
+
+ event.preventDefault();
+
+ $link = jQuery(this);
+ id = $link.attr('id').substr(2);
+
+ if (!opener) {
+ // if we don't run in popup display example
+ // the id's are a bit wierd and jQuery('#ex_wiki_dokuwiki-128.png')
+ // will not be found by Sizzle (the CSS Selector Engine
+ // used by jQuery), hence the document.getElementById() call
+ jQuery(document.getElementById('ex_' + id.replace(/:/g, '_').replace(/^_/, ''))).dw_toggle();
+ return;
+ }
+
+ dw_mediamanager.ext = false;
+ dot = id.lastIndexOf(".");
+
+ if (-1 === dot) {
+ dw_mediamanager.insert(id);
+ return;
+ }
+
+ ext = id.substr(dot);
+
+ if ({'.jpg': 1, '.jpeg': 1, '.png': 1, '.gif': 1, '.swf': 1}[ext] !== 1) {
+ dw_mediamanager.insert(id);
+ return;
+ }
+
+ // remove old callback from the insert button and set the new one.
+ var $sendbtn = jQuery('#media__sendbtn');
+ $sendbtn.off().on('click', bind(dw_mediamanager.insert, id));
+
+ dw_mediamanager.unforbid('ext');
+ if (ext === '.swf') {
+ dw_mediamanager.ext = 'swf';
+ dw_mediamanager.forbid('ext', {
+ link: ['1', '2'],
+ size: ['4']
+ });
+ } else {
+ dw_mediamanager.ext = 'img';
+ }
+
+ // Set to defaults
+ dw_mediamanager.setOpt('link');
+ dw_mediamanager.setOpt('align');
+ dw_mediamanager.setOpt('size');
+
+ // toggle buttons for detail and linked image, original size
+ jQuery('#media__linkbtn1, #media__linkbtn2, #media__sizebtn4')
+ .toggle(dw_mediamanager.ext === 'img');
+
+ dw_mediamanager.$popup.dialog('open');
+
+ $sendbtn.focus();
+ },
+
+ /**
+ * Deletion confirmation dialog to the delete buttons.
+ *
+ * @author Michael Klier <chi@chimeric.de>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ confirmattach: function (e) {
+ if (!confirm(LANG.del_confirm + "\n" + jQuery(this).attr('title'))) {
+ e.preventDefault();
+ }
+ },
+
+ /**
+ * Creates checkboxes for additional options
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ attachoptions: function () {
+ var $obj, opts;
+
+ $obj = jQuery('#media__opts');
+ if ($obj.length === 0) {
+ return;
+ }
+
+ opts = [];
+ // keep open
+ if (opener) {
+ opts.push(['keepopen', 'keepopen']);
+ }
+ opts.push(['hide', 'hidedetails']);
+
+ jQuery.each(opts,
+ function (_, opt) {
+ var $box, $lbl;
+ $box = jQuery(document.createElement('input'))
+ .attr('type', 'checkbox')
+ .attr('id', 'media__' + opt[0])
+ .on('click', bind(dw_mediamanager.toggleOption, opt[0]));
+
+ if (DokuCookie.getValue(opt[0])) {
+ $box.prop('checked', true);
+ dw_mediamanager[opt[0]] = true;
+ }
+
+ $lbl = jQuery(document.createElement('label'))
+ .attr('for', 'media__' + opt[0])
+ .text(LANG[opt[1]]);
+
+ $obj.append($box, $lbl, document.createElement('br'));
+ });
+
+ dw_mediamanager.updatehide();
+ },
+
+ /**
+ * Generalized toggler
+ *
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ toggleOption: function (variable) {
+ if (jQuery(this).prop('checked')) {
+ DokuCookie.setValue(variable, 1);
+ dw_mediamanager[variable] = true;
+ } else {
+ DokuCookie.setValue(variable, '');
+ dw_mediamanager[variable] = false;
+ }
+ if (variable === 'hide') {
+ dw_mediamanager.updatehide();
+ }
+ },
+
+ /**
+ * Sets the visibility of the image details accordingly to the
+ * chosen hide state
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ updatehide: function () {
+ jQuery('#media__content').find('div.detail').dw_toggle(!dw_mediamanager.hide);
+ },
+
+ /**
+ * set media insertion option
+ *
+ * @author Dominik Eckelmann <eckelmann@cosmocode.de>
+ */
+ setOpt: function (opt, e) {
+ var val, i;
+ if (typeof e !== 'undefined') {
+ val = this.id.substring(this.id.length - 1);
+ } else {
+ val = dw_mediamanager.getOpt(opt);
+ }
+
+ if (val === false) {
+ DokuCookie.setValue(opt, '');
+ dw_mediamanager[opt] = false;
+ return;
+ }
+
+ if (opt === 'link') {
+ if (val !== '4' && dw_mediamanager.link === '4') {
+ dw_mediamanager.unforbid('linkonly');
+ dw_mediamanager.setOpt('align');
+ dw_mediamanager.setOpt('size');
+ } else if (val === '4') {
+ dw_mediamanager.forbid('linkonly', {align: false, size: false});
+ }
+
+ jQuery("#media__size, #media__align").dw_toggle(val !== '4');
+ }
+
+ DokuCookie.setValue(opt, val);
+ dw_mediamanager[opt] = val;
+
+ for (i = 1; i <= 4; i++) {
+ jQuery("#media__" + opt + "btn" + i).removeClass('selected');
+ }
+ jQuery('#media__' + opt + 'btn' + val).addClass('selected');
+ },
+
+ unforbid: function (group) {
+ delete dw_mediamanager.forbidden_opts[group];
+ },
+
+ forbid: function (group, forbids) {
+ dw_mediamanager.forbidden_opts[group] = forbids;
+ },
+
+ allowedOpt: function (opt, val) {
+ var ret = true;
+ jQuery.each(dw_mediamanager.forbidden_opts,
+ function (_, forbids) {
+ ret = forbids[opt] !== false &&
+ jQuery.inArray(val, forbids[opt]) === -1;
+ return ret;
+ });
+ return ret;
+ },
+
+ getOpt: function (opt) {
+ var allowed = bind(dw_mediamanager.allowedOpt, opt);
+
+ // Current value
+ if (dw_mediamanager[opt] !== false && allowed(dw_mediamanager[opt])) {
+ return dw_mediamanager[opt];
+ }
+
+ // From cookie
+ if (DokuCookie.getValue(opt) && allowed(DokuCookie.getValue(opt))) {
+ return DokuCookie.getValue(opt);
+ }
+
+ // size default
+ if (opt === 'size' && allowed('2')) {
+ return '2';
+ }
+
+ // Whatever is allowed, and be it false
+ return jQuery.grep(['1', '2', '3', '4'], allowed)[0] || false;
+ }
+};
+
+/**
+ * Default implementation for the media manager's select action
+ *
+ * Can be overriden with the onselect URL parameter. Is called on the opener context
+ *
+ * @param {string} edid
+ * @param {string} mediaid
+ * @param {string} opts
+ * @param {string} align [none, left, center, right]
+ */
+function dw_mediamanager_item_select(edid, mediaid, opts, align, keepopen) {
+ var alignleft = '';
+ var alignright = '';
+
+ // Get the 2 characters after the cursor to check if we're currently inside an image tag
+ var cursorInImageTag = false;
+ var textArea = jQuery('#' + edid)[0];
+ var selection = DWgetSelection(textArea);
+ selection.end = selection.end + 2;
+ var charsAfterCursor = selection.getText();
+ if (charsAfterCursor === '}}') {
+ cursorInImageTag = true;
+ }
+
+ if (align !== '1') {
+ alignleft = align === '2' ? '' : ' ';
+ alignright = align === '4' ? '' : ' ';
+ }
+ if (keepopen && cursorInImageTag) {
+ selection.start = selection.start + 2;
+ DWsetSelection(selection);
+ }
+ insertTags(edid, '{{' + alignleft + mediaid + opts + alignright + '|', '}}', '');
+}
+
+jQuery(dw_mediamanager.init);
diff --git a/platform/www/lib/scripts/page.js b/platform/www/lib/scripts/page.js
new file mode 100644
index 0000000..77d644a
--- /dev/null
+++ b/platform/www/lib/scripts/page.js
@@ -0,0 +1,201 @@
+/**
+ * Page behaviours
+ *
+ * This class adds various behaviours to the rendered page
+ */
+dw_page = {
+ /**
+ * initialize page behaviours
+ */
+ init: function(){
+ dw_page.sectionHighlight();
+ dw_page.currentIDHighlight();
+ jQuery('a.fn_top').on('mouseover', dw_page.footnoteDisplay);
+ dw_page.makeToggle('#dw__toc h3','#dw__toc > div');
+ },
+
+ /**
+ * Highlight the section when hovering over the appropriate section edit button
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+ sectionHighlight: function() {
+ jQuery('form.btn_secedit')
+ .on('mouseover', function(){
+ var $tgt = jQuery(this).parent(),
+ nr = $tgt.attr('class').match(/(\s+|^)editbutton_(\d+)(\s+|$)/)[2],
+ $highlight = jQuery(), // holder for elements in the section to be highlighted
+ $highlightWrap = jQuery('<div class="section_highlight"></div>'); // section highlight wrapper
+
+ // Walk the dom tree in reverse to find the sibling which is or contains the section edit marker
+ while($tgt.length > 0 && !($tgt.hasClass('sectionedit' + nr) || $tgt.find('.sectionedit' + nr).length)) {
+ $tgt = $tgt.prev();
+ $highlight = $highlight.add($tgt);
+ }
+ // insert the section highlight wrapper before the last element added to $highlight
+ $highlight.filter(':last').before($highlightWrap);
+ // and move the elements to be highlighted inside the section highlight wrapper
+ $highlight.detach().appendTo($highlightWrap);
+ })
+ .on('mouseout', function(){
+ // find the section highlight wrapper...
+ var $highlightWrap = jQuery('.section_highlight');
+ // ...move its children in front of it (as siblings)...
+ $highlightWrap.before($highlightWrap.children().detach());
+ // ...and remove the section highlight wrapper
+ $highlightWrap.detach();
+ });
+ },
+
+
+ /**
+ * Highlight internal link pointing to current page
+ *
+ * @author Henry Pan <dokuwiki@phy25.com>
+ */
+ currentIDHighlight: function(){
+ jQuery('a.wikilink1, a.wikilink2').filter('[data-wiki-id="'+JSINFO.id+'"]').wrap('<span class="curid"></div>');
+ },
+
+ /**
+ * Create/get a insitu popup used by the footnotes
+ *
+ * @param target - the DOM element at which the popup should be aligned at
+ * @param popup_id - the ID of the (new) DOM popup
+ * @return the Popup jQuery object
+ */
+ insituPopup: function(target, popup_id) {
+ // get or create the popup div
+ var $fndiv = jQuery('#' + popup_id);
+
+ // popup doesn't exist, yet -> create it
+ if($fndiv.length === 0){
+ $fndiv = jQuery(document.createElement('div'))
+ .attr('id', popup_id)
+ .addClass('insitu-footnote JSpopup')
+ .attr('aria-hidden', 'true')
+ .on('mouseleave', function () {jQuery(this).hide().attr('aria-hidden', 'true');})
+ .attr('role', 'tooltip');
+ jQuery('.dokuwiki:first').append($fndiv);
+ }
+
+ // position() does not support hidden elements
+ $fndiv.show().position({
+ my: 'left top',
+ at: 'left center',
+ of: target
+ }).hide();
+
+ return $fndiv;
+ },
+
+ /**
+ * Display an insitu footnote popup
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Chris Smith <chris@jalakai.co.uk>
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+ footnoteDisplay: function () {
+ var $content = jQuery(jQuery(this).attr('href')) // Footnote text anchor
+ .parent().siblings('.content').clone();
+
+ if (!$content.length) {
+ return;
+ }
+
+ // prefix ids on any elements with "insitu__" to ensure they remain unique
+ jQuery('[id]', $content).each(function(){
+ var id = jQuery(this).attr('id');
+ jQuery(this).attr('id', 'insitu__' + id);
+ });
+
+ var content = $content.html().trim();
+ // now put the content into the wrapper
+ dw_page.insituPopup(this, 'insitu__fn').html(content)
+ .show().attr('aria-hidden', 'false');
+ },
+
+ /**
+ * Makes an element foldable by clicking its handle
+ *
+ * This is used for the TOC toggling, but can be used for other elements
+ * as well. A state indicator is inserted into the handle and can be styled
+ * by CSS.
+ *
+ * To properly reserve space for the expanded element, the sliding animation is
+ * done on the children of the content. To make that look good and to make sure aria
+ * attributes are assigned correctly, it's recommended to make sure that the content
+ * element contains a single child element only.
+ *
+ * @param {selector} handle What should be clicked to toggle
+ * @param {selector} content This element will be toggled
+ * @param {int} state initial state (-1 = open, 1 = closed)
+ */
+ makeToggle: function(handle, content, state){
+ var $handle, $content, $clicky, $child, setClicky;
+ $handle = jQuery(handle);
+ if(!$handle.length) return;
+ $content = jQuery(content);
+ if(!$content.length) return;
+
+ // we animate the children
+ $child = $content.children();
+
+ // class/display toggling
+ setClicky = function(hiding){
+ if(hiding){
+ $clicky.html('<span>+</span>');
+ $handle.addClass('closed');
+ $handle.removeClass('open');
+ }else{
+ $clicky.html('<span>−</span>');
+ $handle.addClass('open');
+ $handle.removeClass('closed');
+ }
+ };
+
+ $handle[0].setState = function(state){
+ var hidden;
+ if(!state) state = 1;
+
+ // Assert that content instantly takes the whole space
+ $content.css('min-height', $content.height()).show();
+
+ // stop any running animation
+ $child.stop(true, true);
+
+ // was a state given or do we toggle?
+ if(state === -1) {
+ hidden = false;
+ } else if(state === 1) {
+ hidden = true;
+ } else {
+ hidden = $child.is(':hidden');
+ }
+
+ // update the state
+ setClicky(!hidden);
+
+ // Start animation and assure that $toc is hidden/visible
+ $child.dw_toggle(hidden, function () {
+ $content.toggle(hidden);
+ $content.attr('aria-expanded', hidden);
+ $content.css('min-height',''); // remove min-height again
+ }, true);
+ };
+
+ // the state indicator
+ $clicky = jQuery(document.createElement('strong'));
+
+ // click function
+ $handle.css('cursor','pointer')
+ .on('click', $handle[0].setState)
+ .prepend($clicky);
+
+ // initial state
+ $handle[0].setState(state);
+ }
+};
+
+jQuery(dw_page.init);
diff --git a/platform/www/lib/scripts/qsearch.js b/platform/www/lib/scripts/qsearch.js
new file mode 100644
index 0000000..f95515b
--- /dev/null
+++ b/platform/www/lib/scripts/qsearch.js
@@ -0,0 +1,191 @@
+/**
+ * AJAX functions for the pagename quicksearch
+ *
+ * @license GPL2 (http://www.gnu.org/licenses/gpl.html)
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Adrian Lang <lang@cosmocode.de>
+ * @author Michal Rezler <m.rezler@centrum.cz>
+ */
+jQuery.fn.dw_qsearch = function (overrides) {
+
+ var dw_qsearch = {
+
+ output: '#qsearch__out',
+
+ $inObj: this,
+ $outObj: null,
+ timer: null,
+ curRequest: null,
+
+ /**
+ * initialize the quick search
+ *
+ * Attaches the event handlers
+ *
+ */
+ init: function () {
+ var do_qsearch;
+
+ dw_qsearch.$outObj = jQuery(dw_qsearch.output);
+
+ // objects found?
+ if (dw_qsearch.$inObj.length === 0 ||
+ dw_qsearch.$outObj.length === 0) {
+ return;
+ }
+
+ // attach eventhandler to search field
+ do_qsearch = function () {
+ // abort any previous request
+ if (dw_qsearch.curRequest != null) {
+ dw_qsearch.curRequest.abort();
+ }
+ var value = dw_qsearch.getSearchterm();
+ if (value === '') {
+ dw_qsearch.clear_results();
+ return;
+ }
+ dw_qsearch.$inObj.parents('form').addClass('searching');
+ dw_qsearch.curRequest = jQuery.post(
+ DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'qsearch',
+ q: encodeURI(value)
+ },
+ dw_qsearch.onCompletion,
+ 'html'
+ );
+ };
+
+ dw_qsearch.$inObj.on('keyup',
+ function () {
+ if (dw_qsearch.timer) {
+ window.clearTimeout(dw_qsearch.timer);
+ dw_qsearch.timer = null;
+ }
+ dw_qsearch.timer = window.setTimeout(do_qsearch, 500);
+ }
+ );
+
+ // attach eventhandler to output field
+ dw_qsearch.$outObj.on('click', dw_qsearch.clear_results);
+ },
+
+ /**
+ * Read search term from input
+ */
+ getSearchterm: function() {
+ return dw_qsearch.$inObj.val();
+ },
+
+ /**
+ * Empty and hide the output div
+ */
+ clear_results: function () {
+ dw_qsearch.$inObj.parents('form').removeClass('searching');
+ dw_qsearch.$outObj.hide();
+ dw_qsearch.$outObj.text('');
+ },
+
+ /**
+ * Callback. Reformat and display the results.
+ *
+ * Namespaces are shortened here to keep the results from overflowing
+ * or wrapping
+ *
+ * @param data The result HTML
+ */
+ onCompletion: function (data) {
+ var max, $links, too_big;
+ dw_qsearch.$inObj.parents('form').removeClass('searching');
+
+ dw_qsearch.curRequest = null;
+
+ if (data === '') {
+ dw_qsearch.clear_results();
+ return;
+ }
+
+ dw_qsearch.$outObj
+ .html(data)
+ .show()
+ .css('white-space', 'nowrap');
+
+ // disable overflow during shortening
+ dw_qsearch.$outObj.find('li').css('overflow', 'visible');
+
+ $links = dw_qsearch.$outObj.find('a');
+ max = dw_qsearch.$outObj[0].clientWidth; // maximum width allowed (but take away paddings below)
+ if (document.documentElement.dir === 'rtl') {
+ max -= parseInt(dw_qsearch.$outObj.css('padding-left'));
+ too_big = function (l) {
+ return l.offsetLeft < 0;
+ };
+ } else {
+ max -= parseInt(dw_qsearch.$outObj.css('padding-right'));
+ too_big = function (l) {
+ return l.offsetWidth + l.offsetLeft > max;
+ };
+ }
+
+ $links.each(function () {
+ var start, length, replace, nsL, nsR, eli, runaway;
+
+ if (!too_big(this)) {
+ return;
+ }
+
+ nsL = this.textContent.indexOf('(');
+ nsR = this.textContent.indexOf(')');
+ eli = 0;
+ runaway = 0;
+
+ while ((nsR - nsL > 3) && too_big(this) && runaway++ < 500) {
+ if (eli !== 0) {
+ // elipsis already inserted
+ if ((eli - nsL) > (nsR - eli)) {
+ // cut left
+ start = eli - 2;
+ length = 2;
+ } else {
+ // cut right
+ start = eli + 1;
+ length = 1;
+ }
+ replace = '';
+ } else {
+ // replace middle with ellipsis
+ start = Math.floor(nsL + ((nsR - nsL) / 2));
+ length = 1;
+ replace = '…';
+ }
+ this.textContent = substr_replace(this.textContent,
+ replace, start, length);
+
+ eli = this.textContent.indexOf('…');
+ nsL = this.textContent.indexOf('(');
+ nsR = this.textContent.indexOf(')');
+ }
+ });
+
+ // reenable overflow
+ dw_qsearch.$outObj.find('li').css('overflow', 'hidden').css('text-overflow', 'ellipsis');
+ }
+
+
+ };
+
+ jQuery.extend(dw_qsearch, overrides);
+
+ if (!overrides.deferInit) {
+ dw_qsearch.init();
+ }
+
+ return dw_qsearch;
+};
+
+jQuery(function () {
+ jQuery('#qsearch__in').dw_qsearch({
+ output: '#qsearch__out'
+ });
+});
diff --git a/platform/www/lib/scripts/script.js b/platform/www/lib/scripts/script.js
new file mode 100644
index 0000000..0e03dcf
--- /dev/null
+++ b/platform/www/lib/scripts/script.js
@@ -0,0 +1,30 @@
+// if jQuery was loaded, let's make it noConflict here.
+if ('function' === typeof jQuery && 'function' === typeof jQuery.noConflict) {
+ jQuery.noConflict();
+}
+
+/**
+ * Some browser detection
+ */
+var clientPC = navigator.userAgent.toLowerCase(); // Get client info
+var is_macos = navigator.appVersion.indexOf('Mac') != -1;
+var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1) &&
+ (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
+var is_safari = ((clientPC.indexOf('applewebkit')!=-1) && (clientPC.indexOf('spoofer')==-1));
+var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
+if (clientPC.indexOf('opera')!=-1) {
+ var is_opera = true;
+ var is_opera_preseven = (window.opera && !document.childNodes);
+ var is_opera_seven = (window.opera && document.childNodes);
+}
+
+/**
+ * Handler to close all open Popups
+ */
+function closePopups(){
+ jQuery('div.JSpopup').hide();
+}
+
+jQuery(function () {
+ jQuery(document).on('click', closePopups);
+});
diff --git a/platform/www/lib/scripts/search.js b/platform/www/lib/scripts/search.js
new file mode 100644
index 0000000..111dca9
--- /dev/null
+++ b/platform/www/lib/scripts/search.js
@@ -0,0 +1,48 @@
+jQuery(function () {
+ 'use strict';
+
+ var $searchForm = jQuery('.search-results-form');
+ if (!$searchForm.length) {
+ return;
+ }
+
+ var $toggleAssistanceButton = jQuery('<button>')
+ .addClass('toggleAssistant')
+ .attr('type', 'button')
+ .attr('aria-expanded', 'false')
+ .text(LANG.search_toggle_tools)
+ .prependTo($searchForm.find('fieldset'))
+ ;
+
+ $toggleAssistanceButton.on('click', function () {
+ jQuery('.advancedOptions').toggle(0, function () {
+ var $me = jQuery(this);
+ if ($me.attr('aria-hidden')) {
+ $me.removeAttr('aria-hidden');
+ $toggleAssistanceButton.attr('aria-expanded', 'true');
+ DokuCookie.setValue('sa', 'on');
+ } else {
+ $me.attr('aria-hidden', 'true');
+ $toggleAssistanceButton.attr('aria-expanded', 'false');
+ DokuCookie.setValue('sa', 'off');
+ }
+ });
+ });
+
+ if (DokuCookie.getValue('sa') === 'on') {
+ $toggleAssistanceButton.trigger('click');
+ }
+
+ $searchForm.find('.advancedOptions .toggle div.current').on('click', function () {
+ var $me = jQuery(this);
+ $me.parent().siblings().removeClass('open');
+ $me.parent().siblings().find('ul:first').attr('aria-expanded', 'false');
+ $me.parent().toggleClass('open');
+ if ($me.parent().hasClass('open')) {
+ $me.parent().find('ul:first').attr('aria-expanded', 'true');
+ } else {
+ $me.parent().find('ul:first').attr('aria-expanded', 'false');
+ }
+ });
+
+});
diff --git a/platform/www/lib/scripts/textselection.js b/platform/www/lib/scripts/textselection.js
new file mode 100644
index 0000000..16874ba
--- /dev/null
+++ b/platform/www/lib/scripts/textselection.js
@@ -0,0 +1,152 @@
+/**
+ * Text selection related functions.
+ */
+
+/**
+ * selection prototype
+ *
+ * Object that capsulates the selection in a textarea. Returned by DWgetSelection.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function selection_class(){
+ this.start = 0;
+ this.end = 0;
+ this.obj = null;
+ this.scroll = 0;
+ this.fix = 0;
+
+ this.getLength = function(){
+ return this.end - this.start;
+ };
+
+ this.getText = function(){
+ return (!this.obj) ? '' : this.obj.value.substring(this.start,this.end);
+ };
+}
+
+/**
+ * Get current selection/cursor position in a given textArea
+ *
+ * @link http://groups.drupal.org/node/1210
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @link http://linebyline.blogspot.com/2006/11/textarea-cursor-position-in-internet.html
+ * @returns object - a selection object
+ */
+function DWgetSelection(textArea) {
+ var sel = new selection_class();
+
+ textArea.focus();
+ sel.obj = textArea;
+ sel.start = textArea.selectionStart;
+ sel.end = textArea.selectionEnd;
+ sel.scroll = textArea.scrollTop;
+ return sel;
+}
+
+/**
+ * Set the selection
+ *
+ * You need to get a selection object via DWgetSelection() first, then modify the
+ * start and end properties and pass it back to this function.
+ *
+ * @link http://groups.drupal.org/node/1210
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param {selection_class} selection a selection object as returned by DWgetSelection()
+ */
+function DWsetSelection(selection){
+ selection.obj.setSelectionRange(selection.start, selection.end);
+ if(selection.scroll) selection.obj.scrollTop = selection.scroll;
+}
+
+/**
+ * Inserts the given text at the current cursor position or replaces the current
+ * selection
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @param {string} text the new text to be pasted
+ * @param {selection_class} selection selection object returned by DWgetSelection
+ * @param {int} opts.startofs number of charcters at the start to skip from new selection
+ * @param {int} opts.endofs number of characters at the end to skip from new selection
+ * @param {boolean} opts.nosel set true if new text should not be selected
+ */
+function pasteText(selection,text,opts){
+ if(!opts) opts = {};
+ // replace the content
+
+ selection.obj.value =
+ selection.obj.value.substring(0, selection.start) + text +
+ selection.obj.value.substring(selection.end, selection.obj.value.length);
+
+ // set new selection
+ if (is_opera) {
+ // Opera replaces \n by \r\n when inserting text.
+ selection.end = selection.start + text.replace(/\r?\n/g, '\r\n').length;
+ } else {
+ selection.end = selection.start + text.length;
+ }
+
+
+ // modify the new selection if wanted
+ if(opts.startofs) selection.start += opts.startofs;
+ if(opts.endofs) selection.end -= opts.endofs;
+
+ // no selection wanted? set cursor to end position
+ if(opts.nosel) selection.start = selection.end;
+
+ DWsetSelection(selection);
+}
+
+
+/**
+ * Format selection
+ *
+ * Apply tagOpen/tagClose to selection in textarea, use sampleText instead
+ * of selection if there is none.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function insertTags(textAreaID, tagOpen, tagClose, sampleText){
+ var txtarea = jQuery('#' + textAreaID)[0];
+
+ var selection = DWgetSelection(txtarea);
+ var text = selection.getText();
+ var opts;
+
+ // don't include trailing space in selection
+ if(text.charAt(text.length - 1) == ' '){
+ selection.end--;
+ text = selection.getText();
+ }
+
+ if(!text){
+ // nothing selected, use the sample text and select it
+ text = sampleText;
+ opts = {
+ startofs: tagOpen.length,
+ endofs: tagClose.length
+ };
+ }else{
+ // place cursor at the end
+ opts = {
+ nosel: true
+ };
+ }
+
+ // surround with tags
+ text = tagOpen + text + tagClose;
+
+ // do it
+ pasteText(selection,text,opts);
+}
+
+/**
+ * Wraps around pasteText() for backward compatibility
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function insertAtCarret(textAreaID, text){
+ var txtarea = jQuery('#' + textAreaID)[0];
+ var selection = DWgetSelection(txtarea);
+ pasteText(selection,text,{nosel: true});
+}
diff --git a/platform/www/lib/scripts/toolbar.js b/platform/www/lib/scripts/toolbar.js
new file mode 100644
index 0000000..b766f8b
--- /dev/null
+++ b/platform/www/lib/scripts/toolbar.js
@@ -0,0 +1,282 @@
+// used to identify pickers
+var pickercounter=0;
+
+/**
+ * Create a toolbar
+ *
+ * @param string tbid ID of the element where to insert the toolbar
+ * @param string edid ID of the editor textarea
+ * @param array tb Associative array defining the buttons
+ * @param bool allowblock Allow buttons creating multiline content
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function initToolbar(tbid,edid,tb, allowblock){
+ var $toolbar, $edit;
+ if (typeof tbid == 'string') {
+ $toolbar = jQuery('#' + tbid);
+ } else {
+ $toolbar = jQuery(tbid);
+ }
+
+ $edit = jQuery('#' + edid);
+
+ if ($toolbar.length == 0 || $edit.length == 0 || $edit.attr('readOnly')) {
+ return;
+ }
+
+ if (typeof allowblock === 'undefined') {
+ allowblock = true;
+ }
+
+ //empty the toolbar area:
+ $toolbar.html('');
+
+ jQuery.each(tb, function (k, val) {
+ if (!tb.hasOwnProperty(k) || (!allowblock && val.block === true)) {
+ return;
+ }
+ var actionFunc, $btn;
+
+ // create new button (jQuery object)
+ $btn = jQuery(createToolButton(val.icon, val.title, val.key, val.id,
+ val['class']));
+
+ // type is a tb function -> assign it as onclick
+ actionFunc = 'tb_'+val.type;
+ if( jQuery.isFunction(window[actionFunc]) ){
+ $btn.on('click', bind(window[actionFunc],$btn,val,edid) );
+ $toolbar.append($btn);
+ return;
+ }
+
+ // type is a init function -> execute it
+ actionFunc = 'addBtnAction'+val.type.charAt(0).toUpperCase()+val.type.substring(1);
+ if( jQuery.isFunction(window[actionFunc]) ){
+ var pickerid = window[actionFunc]($btn, val, edid);
+ if(pickerid !== ''){
+ $toolbar.append($btn);
+ $btn.attr('aria-controls', pickerid);
+ if (actionFunc === 'addBtnActionPicker') {
+ $btn.attr('aria-haspopup', 'true');
+ }
+ }
+ return;
+ }
+
+ alert('unknown toolbar type: '+val.type+' '+actionFunc);
+ });
+}
+
+/**
+ * Button action for format buttons
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @author Gabriel Birke <birke@d-scribe.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tb_format(btn, props, edid) {
+ var sample = props.sample || props.title;
+ insertTags(edid,
+ fixtxt(props.open),
+ fixtxt(props.close),
+ fixtxt(sample));
+ pickerClose();
+ return false;
+}
+
+/**
+ * Button action for format buttons
+ *
+ * This works exactly as tb_format() except that, if multiple lines
+ * are selected, each line will be formatted seperately
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @author Gabriel Birke <birke@d-scribe.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tb_formatln(btn, props, edid) {
+ var sample = props.sample || props.title,
+ opts,
+ selection = DWgetSelection(jQuery('#'+edid)[0]);
+
+ sample = fixtxt(sample);
+ props.open = fixtxt(props.open);
+ props.close = fixtxt(props.close);
+
+ // is something selected?
+ if(selection.getLength()){
+ sample = selection.getText();
+ opts = {nosel: true};
+ }else{
+ opts = {
+ startofs: props.open.length,
+ endofs: props.close.length
+ };
+ }
+
+ sample = sample.split("\n").join(props.close+"\n"+props.open);
+ sample = props.open+sample+props.close;
+
+ pasteText(selection,sample,opts);
+
+ pickerClose();
+ return false;
+}
+
+/**
+ * Button action for insert buttons
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @author Gabriel Birke <birke@d-scribe.de>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tb_insert(btn, props, edid) {
+ insertAtCarret(edid,fixtxt(props.insert));
+ pickerClose();
+ return false;
+}
+
+/**
+ * Button action for the media popup
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tb_mediapopup(btn, props, edid) {
+ window.open(
+ DOKU_BASE+props.url+encodeURIComponent(NS)+'&edid='+encodeURIComponent(edid),
+ props.name,
+ props.options);
+ return false;
+}
+
+/**
+ * Button action for automatic headlines
+ *
+ * Insert a new headline based on the current section level
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function tb_autohead(btn, props, edid){
+ var lvl = currentHeadlineLevel(edid),
+ tags;
+
+ // determine new level
+ lvl += props.mod;
+ if(lvl < 1) lvl = 1;
+ if(lvl > 5) lvl = 5;
+
+ tags = (new Array(8 - lvl)).join('=');
+ insertTags(edid, tags+' ', ' '+tags+"\n", props.text);
+ pickerClose();
+ return false;
+}
+
+
+/**
+ * Add button action for picker buttons and create picker element
+ *
+ * @param jQuery btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @return boolean If button should be appended
+ * @author Gabriel Birke <birke@d-scribe.de>
+ */
+function addBtnActionPicker($btn, props, edid) {
+ var pickerid = 'picker'+(pickercounter++);
+ var picker = createPicker(pickerid, props, edid);
+ jQuery(picker).attr('aria-hidden', 'true');
+
+ $btn.click(
+ function(e) {
+ pickerToggle(pickerid,$btn);
+ e.preventDefault();
+ return '';
+ }
+ );
+
+ return pickerid;
+}
+
+/**
+ * Add button action for the link wizard button
+ *
+ * @param DOMElement btn Button element to add the action to
+ * @param array props Associative array of button properties
+ * @param string edid ID of the editor textarea
+ * @return boolean If button should be appended
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+function addBtnActionLinkwiz($btn, props, edid) {
+ dw_linkwiz.init(jQuery('#'+edid));
+ jQuery($btn).click(function(e){
+ dw_linkwiz.val = props;
+ dw_linkwiz.toggle();
+ e.preventDefault();
+ return '';
+ });
+ return 'link__wiz';
+}
+
+
+/**
+ * Show/Hide a previously created picker window
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function pickerToggle(pickerid,$btn){
+ var $picker = jQuery('#' + pickerid),
+ pos = $btn.offset();
+ if ($picker.hasClass('a11y')) {
+ $picker.removeClass('a11y').attr('aria-hidden', 'false');
+ } else {
+ $picker.addClass('a11y').attr('aria-hidden', 'true');
+ }
+ var picker_left = pos.left + 3,
+ picker_width = $picker.width(),
+ window_width = jQuery(window).width();
+ if (picker_width > 300) {
+ $picker.css("max-width", "300");
+ picker_width = 300;
+ }
+ if ((picker_left + picker_width + 40) > window_width) {
+ picker_left = window_width - picker_width - 40;
+ }
+ if (picker_left < 0) {
+ picker_left = 0;
+ }
+ $picker.offset({left: picker_left, top: pos.top+$btn[0].offsetHeight+3});
+}
+
+/**
+ * Close all open pickers
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function pickerClose(){
+ jQuery('.picker').addClass('a11y');
+}
+
+
+/**
+ * Replaces \n with linebreaks
+ */
+function fixtxt(str){
+ return str.replace(/\\n/g,"\n");
+}
+
+jQuery(function () {
+ initToolbar('tool__bar','wiki__text',toolbar);
+ jQuery('#tool__bar').attr('role', 'toolbar');
+});
diff --git a/platform/www/lib/scripts/tree.js b/platform/www/lib/scripts/tree.js
new file mode 100644
index 0000000..9b2d245
--- /dev/null
+++ b/platform/www/lib/scripts/tree.js
@@ -0,0 +1,107 @@
+jQuery.fn.dw_tree = function(overrides) {
+ var dw_tree = {
+
+ /**
+ * Delay in ms before showing the throbber.
+ * Used to skip the throbber for fast AJAX calls.
+ */
+ throbber_delay: 500,
+
+ $obj: this,
+
+ toggle_selector: 'a.idx_dir',
+
+ init: function () {
+ this.$obj.on('click', this.toggle_selector, this,
+ this.toggle);
+ jQuery('ul:first', this.$obj).attr('role', 'tree');
+ jQuery('ul', this.$obj).not(':first').attr('role', 'group');
+ jQuery('li', this.$obj).attr('role', 'treeitem');
+ jQuery('li.open > ul', this.$obj).attr('aria-expanded', 'true');
+ jQuery('li.closed > ul', this.$obj).attr('aria-expanded', 'false');
+ jQuery('li.closed', this.$obj).attr('aria-live', 'assertive');
+ },
+
+ /**
+ * Open or close a subtree using AJAX
+ * The contents of subtrees are "cached" until the page is reloaded.
+ * A "loading" indicator is shown only when the AJAX call is slow.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Ben Coburn <btcoburn@silicodon.net>
+ * @author Pierre Spring <pierre.spring@caillou.ch>
+ */
+ toggle: function (e) {
+ var $listitem, $sublist, timeout, $clicky, show_sublist, dw_tree, opening;
+
+ e.preventDefault();
+
+ dw_tree = e.data;
+ $clicky = jQuery(this);
+ $listitem = $clicky.closest('li');
+ $sublist = $listitem.find('ul').first();
+ opening = $listitem.hasClass('closed');
+ dw_tree.toggle_display($clicky, opening);
+ if ($sublist.is(':visible')) {
+ $listitem.removeClass('open').addClass('closed');
+ $sublist.attr('aria-expanded', 'false');
+ } else {
+ $listitem.removeClass('closed').addClass('open');
+ $sublist.attr('aria-expanded', 'true');
+ }
+
+ // if already open, close by hiding the sublist
+ if (!opening) {
+ $sublist.dw_hide();
+ return;
+ }
+
+ show_sublist = function (data) {
+ $sublist.hide();
+ if (typeof data !== 'undefined') {
+ $sublist.html(data);
+ $sublist.parent().attr('aria-busy', 'false').removeAttr('aria-live');
+ jQuery('li.closed', $sublist).attr('aria-live', 'assertive');
+ }
+ if ($listitem.hasClass('open')) {
+ // Only show if user didn’t close the list since starting
+ // to load the content
+ $sublist.dw_show();
+ }
+ };
+
+ // just show if already loaded
+ if ($sublist.length > 0) {
+ show_sublist();
+ return;
+ }
+
+ //prepare the new ul
+ $sublist = jQuery('<ul class="idx" role="group"/>');
+ $listitem.append($sublist);
+
+ timeout = window.setTimeout(
+ bind(show_sublist, '<li aria-busy="true"><img src="' + DOKU_BASE + 'lib/images/throbber.gif" alt="loading..." title="loading..." /></li>'), dw_tree.throbber_delay);
+
+ dw_tree.load_data(function (data) {
+ window.clearTimeout(timeout);
+ show_sublist(data);
+ }, $clicky);
+ },
+
+ toggle_display: function ($clicky, opening) {
+ },
+
+ load_data: function (show_data, $clicky) {
+ show_data();
+ }
+ };
+
+ jQuery.extend(dw_tree, overrides);
+
+ if (!overrides.deferInit) {
+ dw_tree.init();
+ }
+
+ return dw_tree;
+};
diff --git a/platform/www/lib/styles/all.css b/platform/www/lib/styles/all.css
new file mode 100644
index 0000000..1ae9a02
--- /dev/null
+++ b/platform/www/lib/styles/all.css
@@ -0,0 +1,68 @@
+/**
+ * Basic screen and print styles. These styles are needed for basic DokuWiki functions
+ * regardless of the used template. Templates can override them of course
+ */
+
+div.clearer {
+ clear: both;
+ font-size: 0;
+ line-height: 0;
+ height: 0;
+ overflow: hidden;
+}
+
+/* one of the many clearfix versions */
+.group {
+ display: inline-block;
+}
+.group {
+ display: block;
+}
+.group:before,
+.group:after {
+ content: "";
+ display: table;
+}
+.group:after {
+ clear: both;
+}
+
+div.no {
+ display: inline;
+ margin: 0;
+ padding: 0;
+}
+
+.hidden {
+ display: none;
+}
+
+/* image alignment */
+.medialeft {
+ float: left;
+}
+.mediaright {
+ float: right;
+}
+.mediacenter {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+/* table cell alignment */
+.leftalign { text-align: left; }
+.centeralign { text-align: center; }
+.rightalign { text-align: right; }
+[dir=rtl] .leftalign { text-align: left; }
+[dir=rtl] .centeralign { text-align: center; }
+[dir=rtl] .rightalign { text-align: right; }
+
+/* underline */
+em.u {
+ font-style: normal;
+ text-decoration: underline;
+}
+em em.u {
+ font-style: italic;
+}
diff --git a/platform/www/lib/styles/feed.css b/platform/www/lib/styles/feed.css
new file mode 100644
index 0000000..44b72d7
--- /dev/null
+++ b/platform/www/lib/styles/feed.css
@@ -0,0 +1,63 @@
+rss channel, feed, RDF {
+ font: 80% "Lucida Grande", Verdana, Lucida, Helvetica, Arial, sans-serif;
+ background-color: __background__;
+ color: __text__;
+ margin: 0;
+ padding: 0;
+}
+
+
+link, description, language, managingEditor, copyright, lastBuildDate, date,
+pubDate, generator, webMaster, ttl, docs, tagline, author, copyright,
+generator, content, created, issued, modified, subject, id, format, creator,
+category, image {
+ display: none;
+}
+
+item link, entry id {
+ display: block;
+ color: __extern__;
+ text-decoration: underline;
+}
+
+channel title, feed title {
+ display: block;
+ font-size: 200%;
+ font-weight: bolder;
+ color: __extern__;
+ text-decoration: none;
+ border-bottom: 20px solid __background_alt__;
+}
+
+:root:before {
+ content: "This data file is meant to be read in a XML feed reader. See document source."
+}
+
+item, entry {
+ display: block;
+ margin: 1em 180px 1em 1em;
+ border-bottom: 1px solid __border__;
+ padding-bottom: 1em;
+}
+
+item title, entry title {
+ display: block;
+ background: transparent none;
+ border: 0px solid __background_other__;
+ padding: 0;
+ color: __text_alt__;
+ font-size: 1.4em;
+ font-weight: bold;
+}
+
+item pubDate, entry modified, item date {
+ display: inline;
+ color: __text_neu__;
+ font: 1em trebuchet ms, arial, helvetica, sans-serif;
+}
+
+item description, entry summary {
+ display: block;
+ clear: both;
+ padding-top: 0.5em;
+}
diff --git a/platform/www/lib/styles/geshi.less b/platform/www/lib/styles/geshi.less
new file mode 100644
index 0000000..69749e8
--- /dev/null
+++ b/platform/www/lib/styles/geshi.less
@@ -0,0 +1,144 @@
+/**
+ * GeSHi syntax highlighting styles
+ *
+ * Generated with https://www.dokuwiki.org/tips:geshi_style_builder
+ * Cleaned up with http://cleancss.com/
+ * Manulally LESSified
+ */
+.code {
+ .co0 {
+ color: #666666;
+ font-style: italic;
+ }
+
+ .co4 {
+ color: #cc0000;
+ font-style: italic;
+ }
+
+ .es5 {
+ color: #006699;
+ font-weight: bold;
+ }
+
+ .es6 {
+ color: #009933;
+ font-weight: bold;
+ }
+
+ .kw2 {
+ color: #000000;
+ font-weight: bold;
+ }
+
+ .kw5 {
+ color: #008000;
+ }
+
+ .kw6 {
+ color: #f08;
+ font-weight: bold;
+ }
+
+ .me0 {
+ color: #004000;
+ }
+
+ .nu0 {
+ color: #cc66cc;
+ }
+
+ .re0 {
+ color: #0000ff;
+ }
+
+ .re3 {
+ color: #ff3333;
+ font-weight: bold;
+ }
+
+ .re4 {
+ color: #009999;
+ }
+
+ .re5 {
+ color: #660033;
+ }
+
+ .re7 {
+ color: #991111;
+ }
+
+ .re8 {
+ color: #00b000;
+ }
+
+ .sc-2 {
+ color: #404040;
+ }
+
+ .sy3 {
+ color: #000040;
+ }
+
+ .br0, .sy0 {
+ color: #66cc66;
+ }
+
+ .co1, .coMULTI, .sc-1 {
+ color: #808080;
+ font-style: italic;
+ }
+
+ .co2, .sy1 {
+ color: #339933;
+ }
+
+ .co3, .sy4 {
+ color: #008080;
+ }
+
+ .es0, .es1, .esHARD {
+ color: #000099;
+ font-weight: bold;
+ }
+
+ .es2, .es3, .es4 {
+ color: #660099;
+ font-weight: bold;
+ }
+
+ .kw1, .kw8 {
+ color: #b1b100;
+ }
+
+ .kw10, .kw11, .kw12, .kw9 {
+ color: #003399;
+ font-weight: bold;
+ }
+
+ .kw13, .kw14, .kw15, .kw16, .me1, .me2 {
+ color: #006600;
+ }
+
+ .kw3, .kw7, .sy2 {
+ color: #000066;
+ }
+
+ .kw4, .re2 {
+ color: #993333;
+ }
+
+ .re1, .st0, .st_h {
+ color: #ff0000;
+ }
+
+ li, .li1 {
+ font-weight: normal;
+ vertical-align:top;
+ }
+
+ .ln-xtra {
+ background-color: #ffc;
+ }
+}
diff --git a/platform/www/lib/styles/index.html b/platform/www/lib/styles/index.html
new file mode 100644
index 0000000..977f90e
--- /dev/null
+++ b/platform/www/lib/styles/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=../../" />
+<meta name="robots" content="noindex" />
+<title>nothing here...</title>
+</head>
+<body>
+<!-- this is just here to prevent directory browsing -->
+</body>
+</html>
diff --git a/platform/www/lib/styles/print.css b/platform/www/lib/styles/print.css
new file mode 100644
index 0000000..a5c39e8
--- /dev/null
+++ b/platform/www/lib/styles/print.css
@@ -0,0 +1,15 @@
+/**
+ * Basic print styles. These styles are needed for basic DokuWiki functions
+ * regardless of the used template. Templates can override them of course
+ */
+
+div.error, /* messages with msg() */
+div.info,
+div.success,
+div.notify,
+.secedit, /* section edit button */
+.a11y, /* accessibly hidden text */
+.JSpopup, /* modal windows */
+#link__wiz {
+ display: none;
+}
diff --git a/platform/www/lib/styles/screen.css b/platform/www/lib/styles/screen.css
new file mode 100644
index 0000000..bbc1e86
--- /dev/null
+++ b/platform/www/lib/styles/screen.css
@@ -0,0 +1,96 @@
+/**
+ * Basic screen styles. These styles are needed for basic DokuWiki functions
+ * regardless of the used template. Templates can override them of course
+ */
+
+/* messages with msg() */
+div.error,
+div.info,
+div.success,
+div.notify {
+ color: #000;
+ background-repeat: no-repeat;
+ background-position: 8px 50%;
+ border: 1px solid;
+ font-size: 90%;
+ margin: 0 0 0.5em;
+ padding: 0.4em;
+ padding-left: 32px;
+ overflow: hidden;
+ border-radius: 5px;
+}
+
+[dir=rtl] div.error,
+[dir=rtl] div.info,
+[dir=rtl] div.success,
+[dir=rtl] div.notify {
+ background-position: 99% 50%;
+ padding-left: .4em;
+ padding-right: 32px;
+}
+
+div.error {
+ background-color: #fcc;
+ background-image: url(../images/error.png);
+ border-color: #ebb;
+}
+
+div.info {
+ background-color: #ccf;
+ background-image: url(../images/info.png);
+ border-color: #bbe;
+}
+
+div.success {
+ background-color: #cfc;
+ background-image: url(../images/success.png);
+ border-color: #beb;
+}
+
+div.notify {
+ background-color: #ffc;
+ background-image: url(../images/notify.png);
+ border-color: #eeb;
+}
+
+/* modal windows */
+.JSpopup,
+#link__wiz {
+ position: absolute;
+ background-color: #fff;
+ color: #000;
+ z-index: 20;
+ overflow: hidden;
+}
+
+#link__wiz .ui-dialog-content {
+ padding-left: 0;
+ padding-right: 0;
+}
+
+/* media manager popup toggle buttons */
+
+#media__popup_content button.button {
+ border: 1px outset;
+}
+
+#media__popup_content button.selected {
+ border-style: inset;
+}
+
+/* hide something accessibly
+ (e.g. for screen readers or to keep access keys working) */
+.a11y {
+ position: absolute !important;
+ left: -99999em !important;
+ top: auto !important;
+ width: 1px !important;
+ height: 1px !important;
+ overflow: hidden !important;
+}
+[dir=rtl] .a11y {
+ left: auto !important;
+ right: -99999em !important;
+}
+
+@import "geshi.less";
diff --git a/platform/www/lib/tpl/acervus/COPYING b/platform/www/lib/tpl/acervus/COPYING
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/COPYING
@@ -0,0 +1,339 @@
+ 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/platform/www/lib/tpl/acervus/README.md b/platform/www/lib/tpl/acervus/README.md
new file mode 100644
index 0000000..63ba921
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/README.md
@@ -0,0 +1,3 @@
+# gta-dokuwiki-theme
+
+GTA's dokuwiki theme code, based in White Theme.
diff --git a/platform/www/lib/tpl/acervus/conf/default.php b/platform/www/lib/tpl/acervus/conf/default.php
new file mode 100644
index 0000000..089c8d1
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/conf/default.php
@@ -0,0 +1,11 @@
+<?php
+/*
+ * default configuration settings
+ *
+ * @author Lee, Kwangyoung <ipari@leaflette.com>
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+$conf['numberedHeading'] = 0;
+$conf['tocPosition'] = 'wikipedia';
+$conf['footer'] = '';
diff --git a/platform/www/lib/tpl/acervus/conf/metadata.php b/platform/www/lib/tpl/acervus/conf/metadata.php
new file mode 100644
index 0000000..e85feee
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/conf/metadata.php
@@ -0,0 +1,11 @@
+<?php
+/*
+ * default configuration settings
+ *
+ * @author Lee, Kwangyoung <ipari@leaflette.com>
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+$meta['numberedHeading'] = array('onoff');
+$meta['tocPosition'] = array('multichoice', '_choices' => array('dokuwiki', 'wikipedia'));
+$meta['footer'] = array('string');
diff --git a/platform/www/lib/tpl/acervus/css/basic.less b/platform/www/lib/tpl/acervus/css/basic.less
new file mode 100644
index 0000000..9bce960
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/css/basic.less
@@ -0,0 +1,506 @@
+
+// @font-face {
+// font-family: 'Norwester';
+// src: url('css/fonts/Norwester-Regular.eot');
+// src: url('css/fonts/Norwester-Regular.eot?#iefix') format('embedded-opentype'),
+// url('css/fonts/Norwester-Regular.woff') format('woff'),
+// url('css/fonts/Norwester-Regular.ttf') format('truetype');
+// font-weight: normal;
+// font-style: normal;
+// }
+
+
+/**
+ * This file provides the most basic styles.
+ */
+
+html,
+body {
+ margin: 0;
+ padding: 0;
+ background-color: @ini_background;
+ color: @ini_text;
+}
+
+body {
+ font: normal @ini_font_size/@ini_line_height 'EB Garamond','Segoe UI', Roboto, Helvetica, Arial, sans-serif;
+ /* default font size: 100% => 16px; 93.75% => 15px; 87.5% => 14px; 81.25% => 13px; 75% => 12px */
+ -webkit-text-size-adjust: 100%;
+ -moz-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+ text-size-adjust: 100%;
+}
+
+/* headers */
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font: normal @ini_font_size/@ini_line_height 'EB Garamond','Segoe UI', Roboto, Helvetica, Arial, sans-serif;
+ padding: 0;
+ clear: left;
+ font-weight: 600;
+}
+
+
+[dir=rtl] h1,
+[dir=rtl] h2,
+[dir=rtl] h3,
+[dir=rtl] h4,
+[dir=rtl] h5,
+[dir=rtl] h6 {
+ clear: right;
+}
+
+h1 {
+ font-size: 2em;
+ margin: 0 0 0.444em;
+}
+h2 {
+ font-size: 1.666em;
+ margin: 0 0 0.5em;
+ border-bottom: 1px solid @ini_border;
+}
+h3 {
+ font-size: 1.4em;
+ margin: 0 0 0.5em;
+ border-bottom: 1px solid @ini_border;
+}
+h4 {
+ font-size: 1.2em;
+ margin: 0 0 0.4em;
+}
+h5 {
+ font-size: 1em;
+ margin: 0 0 0.4em;
+}
+h6 {
+ font-size: 0.8em;
+ margin: 0 0 0.4em;
+}
+
+/* basic bargins and paddings */
+p,
+ul,
+ol,
+dl,
+pre,
+table,
+hr,
+blockquote,
+figure,
+details,
+fieldset,
+address {
+ margin: 0 0 1.4em 0; /* bottom margin = line-height */
+ padding: 0;
+}
+
+blockquote blockquote {
+ margin: 0;
+ padding: 0 0.5em;
+}
+
+div,
+video,
+audio {
+ margin: 0;
+ padding: 0;
+}
+
+/* lists */
+li,
+dd {
+ padding: 0;
+ margin: 0 0 0 1.5em;
+}
+[dir=rtl] li,
+[dir=rtl] dd {
+ margin: 0 1.5em 0 0;
+}
+dt {
+ font-weight: bold;
+ margin: 0;
+ padding: 0;
+}
+
+li ul,
+li ol,
+li dl,
+dl ul,
+dl ol,
+dl dl {
+ margin-bottom: 0;
+ padding: 0;
+}
+li li {
+ font-size: 100%;
+}
+
+ul { list-style: square outside; }
+ol { list-style: decimal outside; }
+ol ol { list-style-type: lower-alpha; }
+ol ol ol { list-style-type: upper-roman; }
+ol ol ol ol { list-style-type: upper-alpha; }
+ol ol ol ol ol { list-style-type: lower-roman; }
+
+/*____________ tables ____________*/
+
+table {
+ border-collapse: collapse;
+ empty-cells: show;
+ border-spacing: 0;
+ border: 1px solid @ini_border;
+}
+
+caption {
+ caption-side: top;
+ text-align: left;
+}
+[dir=rtl] caption {
+ text-align: right;
+}
+
+th,
+td {
+ padding: .3em .5em;
+ margin: 0;
+ vertical-align: top;
+ border: 1px solid @ini_border;
+}
+th {
+ font-weight: bold;
+ background-color: @ini_background_alt;
+ text-align: left;
+}
+[dir=rtl] th {
+ text-align: right;
+}
+
+
+/*____________ links ____________*/
+
+a {
+ outline: none;
+ word-wrap: break-word;
+}
+a:link,
+a:visited {
+ text-decoration: none;
+ color: @ini_link;
+}
+a:link:hover,
+a:visited:hover,
+a:link:focus,
+a:visited:focus,
+a:link:active,
+a:visited:active {
+ text-decoration: underline;
+}
+
+
+/* misc */
+img {
+ border-width: 0;
+ vertical-align: bottom;
+ height: auto;
+}
+
+img,
+object,
+iframe,
+video,
+audio,
+select {
+ max-width: 100%;
+}
+
+hr {
+ border-top: solid @ini_border;
+ border-bottom: solid @ini_background;
+ border-width: 1px 0;
+ height: 0;
+ text-align: center;
+ clear: both;
+}
+
+del {
+ color: @ini_text_alt;
+}
+
+pre {
+ overflow: auto;
+ word-wrap: normal;
+ direction: ltr;
+ unicode-bidi: bidi-override;
+ text-align: left;
+}
+
+
+acronym,
+abbr {
+ cursor: help;
+ border-bottom: 1px dotted;
+ font-style: normal;
+ text-decoration: none;
+}
+em acronym,
+em abbr {
+ font-style: italic;
+}
+
+mark {
+ background-color: @ini_highlight;
+ color: inherit;
+}
+
+pre,
+code,
+samp,
+kbd {
+ font-family: Consolas, "Andale Mono WT", "Andale Mono", "Bitstream Vera Sans Mono", "Nimbus Mono L", Monaco, "Courier New", monospace;
+ /* same font stack should be used for ".dokuwiki table.diff td" in _diff.css */
+ font-size: 1em;
+ padding: 0 4px;
+ border: 1px solid @ini_border;
+ direction: ltr;
+ text-align: left;
+ background-color: @ini_background_alt;
+ color: @ini_text
+}
+pre {
+ overflow: auto;
+ word-wrap: normal;
+ border: 1px solid @ini_border;
+ padding: .7em 1em;
+}
+
+blockquote {
+ padding: 0.5em;
+ border: solid @ini_border;
+ background-color: @ini_background_alt;
+ border-width: 0 0 0 .25em;
+}
+[dir=rtl] blockquote {
+ border-width: 0 .25em 0 0;
+}
+q:before,
+q:after {
+ content: '';
+}
+
+sub,
+sup {
+ font-size: .8em;
+ line-height: 1;
+}
+sub {
+ vertical-align: sub;
+}
+sup {
+ vertical-align: super;
+}
+
+small {
+ font-size: .8em;
+}
+
+/*____________ forms ____________*/
+
+/* for all of the form styles, style.ini colours are not used on purpose (except for fieldset border) */
+
+form {
+ display: inline;
+ margin: 0;
+ padding: 0;
+}
+fieldset {
+ padding: .7em 1em 0;
+ padding: .7rem 1rem; /* for those browsers understanding :last-child */
+ border: 1px solid @ini_text_alt;
+}
+fieldset > :last-child {
+ margin-bottom: 0;
+}
+legend {
+ margin: 0;
+ padding: 0 .1em;
+}
+label {
+ vertical-align: middle;
+ cursor: pointer;
+}
+
+input,
+textarea,
+button,
+select,
+optgroup,
+option,
+keygen,
+output,
+meter,
+progress {
+ font: inherit;
+ font-weight: normal;
+ color: #333;
+ background-color: #fff;
+ line-height: normal;
+ margin: 0;
+ vertical-align: middle;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+select {
+ max-width: 100%;
+}
+optgroup {
+ font-style: italic;
+ font-weight: bold;
+}
+option {
+ font-style: normal;
+ font-weight: normal;
+}
+
+input,
+textarea,
+select,
+keygen {
+ border: 1px solid #ccc;
+ box-shadow: inset 0 0 1px #eee;
+ border-radius: 2px;
+}
+input:active,
+input:focus,
+textarea:active,
+textarea:focus,
+select:active,
+select:focus,
+keygen:active,
+keygen:focus {
+ border-color: #999;
+}
+input[type=radio],
+input[type=checkbox],
+input[type=image] {
+ padding: 0;
+ border-style: none;
+ box-shadow: none;
+}
+
+/* all types of buttons */
+input[type=submit],
+input[type=button],
+input[type=reset],
+input.button,
+a.button,
+button,
+.qq-upload-button {
+ color: #333;
+ background-color: #eee;
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPgo8bGluZWFyR3JhZGllbnQgaWQ9Imc4MjQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkZGRkYiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNGNEY0RjQiIG9mZnNldD0iMC4zIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0VFRUVFRSIgb2Zmc2V0PSIwLjk5Ii8+PHN0b3Agc3RvcC1jb2xvcj0iI0NDQ0NDQyIgb2Zmc2V0PSIuOTkiLz4KPC9saW5lYXJHcmFkaWVudD4KPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNnODI0KSIgLz4KPC9zdmc+);
+ background-image: linear-gradient(to bottom, #ffffff 0%, #f4f4f4 30%, #eeeeee 99%, #cccccc 99%);
+ border: 1px solid #ccc;
+ border-radius: 2px;
+ padding: .1em .5em;
+ cursor: pointer;
+}
+
+input[type=submit]:hover,
+input[type=submit]:active,
+input[type=submit]:focus,
+input[type=button]:hover,
+input[type=button]:active,
+input[type=button]:hover,
+input[type=reset]:hover,
+input[type=reset]:active,
+input[type=reset]:hover,
+input.button:hover,
+input.button:active,
+input.button:focus,
+a.button:hover,
+a.button:active,
+a.button:focus,
+button:hover,
+button:active,
+button:focus,
+.qq-upload-button:hover {
+ border-color: #999;
+ background-color: #ddd;
+ background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPgo8bGluZWFyR3JhZGllbnQgaWQ9Imc2NzAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkZGRkYiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNGNEY0RjQiIG9mZnNldD0iMC4zIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0RERERERCIgb2Zmc2V0PSIwLjk5Ii8+PHN0b3Agc3RvcC1jb2xvcj0iI0JCQkJCQiIgb2Zmc2V0PSIuOTkiLz4KPC9saW5lYXJHcmFkaWVudD4KPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNnNjcwKSIgLz4KPC9zdmc+);
+ background-image: linear-gradient(to bottom, #ffffff 0%, #f4f4f4 30%, #dddddd 99%, #bbbbbb 99%);
+}
+
+input::-moz-focus-inner,
+button::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+input[disabled],
+button[disabled],
+select[disabled],
+textarea[disabled],
+option[disabled],
+input[readonly],
+button[readonly],
+select[readonly],
+textarea[readonly] {
+ cursor: auto;
+ opacity: .5;
+ background-color: #eee;
+}
+
+
+.img-reporte {
+ width: 30%;
+ float: right;
+ margin: 0 0 10px 10px;
+ padding: 5px;
+ border: #ccc 1px solid;
+ /*background: #E2E1E0;*/
+}
+
+@media (max-width: 600px) {
+.img-reporte {
+ width: 100%;
+ float: right;
+ margin: 0 0 10px 10px;
+ padding: 5px;
+ border: #ccc 1px solid;
+ /*background: #E2E1E0;*/
+}
+
+
+}
+
+
+/* CAMBIOS VARIOS */
+
+.dokuwiki textarea.edit, textarea.widearea-fullscreen {
+ font-family: monospace !important;
+ font-size: 1em !important;
+}
+
+#dokuwiki__content {
+ text-align: justify;
+}
+
+.footnotes {
+ font-size: 80%;
+}
+
+.fn {
+ border-bottom: 1px #e9e9e9 solid;
+ padding: 5px;
+ opacity: 0.8;
+}
+
+li.level1, li.level2, li.level3, li.level4, li.level5 {
+ text-align: left;
+}
diff --git a/platform/www/lib/tpl/acervus/css/content.less b/platform/www/lib/tpl/acervus/css/content.less
new file mode 100644
index 0000000..4d72c5d
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/css/content.less
@@ -0,0 +1,361 @@
+/* content */
+#dokuwiki__content {
+ /* existing wikipage */
+ a.wikilink1 {
+ color: @ini_existing;
+ }
+ /* not existing wikipage */
+ a.wikilink2 {
+ border-bottom: 1px dashed @ini_missing;
+ color: @ini_missing !important;
+ }
+ /*a.wikilink2:link,
+ a.wikilink2:visited {
+ border-bottom: none;
+ }*/
+ a.wikilink2:hover,
+ a.wikilink2:active,
+ a.wikilink2:focus {
+ /* border-bottom-width: 0; */
+ text-decoration: none;
+ color: #31363B !important;
+ border-bottom: 1px dashed #31363B;
+
+ }
+
+ /*____________ Numbered Headings ____________*/
+
+ .page.numbered_heading {
+ /* TOC */
+
+ // counter-reset: toc-level0;
+ // #dw__toc ul {
+ //
+ // }
+ //
+ //
+ // #dw__toc li.level1 > div > a:before {
+ // color: @ini_numbered_heading;
+ // content: counter(toc-level0) ". ";
+ // counter-increment: toc-level0;
+ // }
+ //
+ // #dw__toc li.level1 {
+ // counter-reset: toc-level1;
+ // }
+ //
+ // #dw__toc li.level2 > div > a:before {
+ // color: @ini_numbered_heading;
+ // content: counter(toc-level0) "." counter(toc-level1) ". ";
+ // counter-increment: toc-level1;
+ // }
+ // #dw__toc li.level2 {
+ // counter-reset: toc-level2;
+ // }
+ // #dw__toc li.level3 > div > a:before {
+ // color: @ini_numbered_heading;
+ // content: counter(toc-level0) "." counter(toc-level1) "." counter(toc-level2) ". ";
+ // counter-increment: toc-level2;
+ // }
+ // #dw__toc li.level3 {
+ // counter-reset: toc-level3;
+ // }
+ // #dw__toc li.level4 > div > a:before {
+ // color: @ini_numbered_heading;
+ // content: counter(toc-level0) "." counter(toc-level1) "." counter(toc-level2) "." counter(toc-level3) ". ";
+ // counter-increment: toc-level3;
+ // }
+
+ /* Contents */
+ counter-reset: level1;
+ h2:before {
+ color: @ini_numbered_heading;
+ content: counter(level1) ". ";
+ counter-increment: level1;
+ }
+ h2 {
+ counter-reset: level2;
+ }
+ h3:before {
+ color: @ini_numbered_heading;
+ content: counter(level1) "." counter(level2) ". ";
+ counter-increment: level2;
+ }
+ h3 {
+ counter-reset: level3;
+ }
+ h4:before {
+ color: @ini_numbered_heading;
+ content: counter(level1) "." counter(level2) "." counter(level3) ". ";
+ counter-increment: level3;
+ }
+ h2:before,
+ h3:before,
+ h4:before {
+ font-size: 90%;
+ }
+
+ #dw__toc h3:before {
+ content: '';
+ }
+ }
+
+ div.license {
+ margin: 0 -1em;
+ padding: .4em 1em;
+ background-color: @ini_background_alt;
+ }
+ .medialeft {
+ margin-right: .6em;
+ }
+ .mediaright {
+ margin-left: .6em;
+ }
+}
+
+/* table of contents */
+#dw__toc {
+ float: inherit;
+ display: inline-block;
+ width: auto;
+ margin: 0 0 1.4em 0;
+ border: 1px solid @ini_border;
+ background-color: @ini_background;
+
+ span {
+ float: right;
+ }
+ h3,
+ div {
+ padding: .4em .8em;
+ }
+ h3.toggle {
+ margin: 0;
+ font-size: 1em;
+ }
+ h3.closed {
+ border: none;
+ }
+ a {
+ color: @ini_text;
+ }
+}
+
+/* any link to current page */
+.dokuwiki span.curid a {
+ font-weight: bold;
+}
+
+/* undo "clever" styling from fileuploader.js */
+.qq-upload-button {
+ cursor: inherit !important;
+ direction: inherit !important;
+}
+.qq-upload-button input {
+ font-family: inherit !important;
+ font-size: 1em !important;
+ margin: inherit !important;
+ opacity: 1 !important;
+ padding: inherit !important;
+ position: static !important;
+}
+
+.JSpopup {
+ padding: 0.2em 0.4em;
+ border: 1px solid @ini_border;
+}
+
+/* editor */
+.dokuwiki .editBar {
+ .editButtons,
+ .summary {
+ display: block !important;
+ margin-bottom: .6em;
+ }
+}
+
+
+/* fields */
+.dokuwiki fieldset {
+ width: auto;
+ text-align:left;
+ margin: 0 0 1em 0;
+ padding: 1em;
+ border: none;
+ background: @ini_background_alt;
+
+ legend {
+ display: block;
+ padding: 0;
+ font-weight: bold;
+ font-size: 1.4em;
+ }
+
+ span {
+ display: inline-block;
+ margin: 0 0 .2em 0;
+ vertical-align: top;
+ }
+
+ label.block {
+ text-align: left;
+
+ span {
+ display: block;
+ }
+
+ input.edit {
+ width: 100%;
+ max-width: 400px;
+ }
+ }
+}
+
+/* login */
+#dw__login,
+#dw__register {
+ label.simple {
+ margin-left: 0;
+ }
+}
+
+/* admin */
+/* _admin.less in default template */
+
+/* main task grouped in two columns */
+.dokuwiki div.ui-admin {
+ ul.admin_tasks,
+ ul.admin_plugins {
+ float: left;
+ width: 40%;
+ list-style-type: none;
+
+ /* general menu item styling */
+ li {
+ margin: 0 0 0.5em 0;
+ white-space: nowrap;
+
+ a span {
+ display: inline-block;
+
+ &.icon {
+ vertical-align: top;
+ margin-right: 0.5em;
+
+ svg {
+ width: 1.5em;
+ height: 1.5em;
+ }
+ }
+
+ &.prompt {
+ white-space: normal;
+ }
+ }
+ }
+ }
+ [dir=rtl] & ul.admin_tasks,
+ [dir=rtl] & ul.admin_plugins {
+ float: right;
+ }
+}
+
+
+/* DokuWiki version */
+#admin__version {
+ clear: left;
+ margin-bottom: 2em;
+ color: @ini_text_alt;
+}
+[dir=rtl] & #admin__version {
+ clear: right;
+ float: left;
+}
+
+
+/* config */
+#config__manager {
+ fieldset {
+ margin: 0 0 2em 0;
+ padding: 0;
+ border: none;
+ background: none;
+
+ legend {
+ text-align: left;
+ font-size: 1.666em; // same as h3
+ }
+ div.table {
+ width: 100%;
+ padding: 0;
+ background: @ini_background_alt;
+ }
+ table {
+ width: 100%;
+ }
+ td.label {
+ padding: .4em .4em 1em;
+ span.outkey {
+ margin-top: -1.2em;
+ }
+ }
+ td {
+ div.input {
+ width: auto;
+ padding: 2px 4px;
+ }
+ input.edit {
+ padding: 4px 6px;
+ }
+ input.edit,
+ select.edit,
+ textarea.edit {
+ width: 100%;
+ border: none;
+ }
+ }
+ div.selection {
+ width: 40%;
+ padding: 2px 4px;
+
+ label {
+ width: 90%;
+ }
+ }
+ div.other {
+ background: none;
+ }
+ }
+}
+
+/* media manager */
+#mediamanager__page {
+ min-width: 0 !important;
+
+ .namespaces {
+ min-width: 0;
+ }
+ .filelist {
+ min-width: 0;
+ .rows li {
+ dt a {
+ vertical-align: top;
+ }
+ dt a img {
+ max-width: 100%;
+ }
+ .name,
+ .size,
+ .filesize,
+ .date {
+ white-space: normal;
+ word-wrap: break-word;
+ }
+ }
+ }
+ .file {
+ min-width: 0;
+ }
+}
+
+pre {white-space: pre-wrap;}
diff --git a/platform/www/lib/tpl/acervus/css/design.less b/platform/www/lib/tpl/acervus/css/design.less
new file mode 100644
index 0000000..182721a
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/css/design.less
@@ -0,0 +1,301 @@
+/* general */
+.btn_icon {
+ text-indent: -9999px;
+}
+
+.sidebar,
+.breadcrumbs {
+ a,
+ a.wikilink1 {
+ color: @ini_text;
+ }
+ a:hover,
+ a.wikilink1:hover {
+ color: @ini_existing;
+ text-decoration: none;
+ }
+ a.wikilink2,
+ a.wikilink2:link {
+ color: @ini_missing;
+ border: none;
+ }
+}
+
+/* header */
+#dokuwiki__header {
+ background: @ini_background;
+ border-bottom: 1px solid @ini_border;
+
+ h1 {
+ margin: 2px 0 0 0;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font: 1.6em 'Source Sans Pro', 'Segoe UI', 'Times new roman', Times, serif;
+ white-space: nowrap;
+ font-weight: 600;
+ }
+ a,
+ a:link,
+ a:hover,
+ a:active {
+ color: @ini_text;
+ text-decoration: none;
+ }
+ button {
+ width: 30px;
+ height: 30px;
+ margin: 5px 0;
+ border: 0 none;
+ outline: none;
+ background: transparent url('images/ipari-simpleline.png') no-repeat;
+ background-size: 30px;
+ text-indent: -9999px;
+ }
+ div.left {
+ button:first-child {
+ margin-left: 16px;
+ }
+ button {
+ margin-left: 8px;
+ }
+ }
+ div.right {
+ button:last-child {
+ margin-right: 16px;
+ }
+ button {
+ margin-right: 4px;
+ }
+ }
+ div.search {
+ display: none;
+ padding: 6px 10px;
+
+ button {
+ display: none;
+ }
+ input[type=text] {
+ padding: 4px 6px;
+ }
+ }
+ .btn_left {
+ background-position: 0 0;
+ }
+ .btn_right {
+ background-position: 0 -90px;
+ }
+ .btn_search {
+ background-position: 0 -45px;
+ }
+}
+
+/* nav */
+#dokuwiki__aside,
+#dokuwiki__tools {
+ display: none;
+ background-color: @ini_background;
+}
+#sidebar_bg {
+ display: none;
+ background-color: rgba(0, 0, 0, .75);
+}
+
+#dokuwiki__aside {
+ > h1,
+ > h2,
+ > div.level1,
+ > div.level2 {
+ padding-left: 8px;
+ padding-right: 8px;
+ margin: 0 0 8px;
+ }
+ p,
+ pre,
+ table,
+ hr,
+ blockquote,
+ figure,
+ details,
+ fieldset,
+ address {
+ margin: 0 0 .4em 0;
+ }
+ p + p {
+ margin-top: 1em;
+ }
+}
+
+.sidebar {
+ overflow-x: hidden;
+ overflow-y: auto;
+ h3 {
+ font-size: 16px;
+ margin-bottom: 0;
+ padding: 9px 12px;
+ border-bottom: 1px solid @ini_border;
+ }
+ ul {
+ list-style-type: none;
+ margin: 0 0 .4em 0;
+ }
+ li {
+ margin: 0;
+ }
+ li li {
+ margin-left: 1em;
+ }
+ li a {
+ display: block;
+ padding: 8px 10px;
+ }
+ li a.urlextern {
+ padding: 10px 12px 10px 30px;
+ background-position: 10px 10px;
+ }
+ li a:hover {
+ background-color: @ini_background_alt !important;
+ }
+
+ div.user {
+ padding: 6px 12px;
+ }
+}
+
+#dokuwiki__tools {
+ li a {
+ height: 30px;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+ li a:before {
+ content: url('images/ipari-simpleline.png');
+ display: inline-block;
+ font-size: 0;
+ line-height: 0;
+ }
+ li a span {
+ display: inline-block;
+ vertical-align: top;
+ padding: .2em .6em;
+ }
+ li a,
+ li a:hover,
+ li a:active,
+ li a:visited {
+ background-image: none !important;
+ }
+ a.action.admin:before {
+ margin-top: -720px;
+ }
+ a.action.profile:before {
+ margin-top: -540px;
+ }
+ a.action.login:before {
+ margin-top: -630px;
+ }
+ a.action.logout:before {
+ margin-top: -675px;
+ }
+ a.action.register:before {
+ margin-top: -585px;
+ }
+ a.action.create:before {
+ margin-top: -135px;
+ }
+ a.action.show:before {
+ margin-top: -225px;
+ }
+ a.action.source:before {
+ margin-top: -180px;
+ }
+ a.action.edit:before {
+ margin-top: -90px;
+ }
+ a.action.revs:before {
+ margin-top: -495px;
+ }
+ a.action.backlink:before {
+ margin-top: -450px;
+ }
+ a.action.top:before {
+ margin-top: -405px;
+ }
+ a.action.recent:before {
+ margin-top: -270px;
+ }
+ a.action.media:before {
+ margin-top: -315px;
+ }
+ a.action.index:before {
+ margin-top: -360px;
+ }
+ // icons for plugins
+ a.action.plugin_export_pdf:before {
+ margin-top: -765px;
+ }
+}
+
+
+#to_top {
+ input.button {
+ width: 48px;
+ height: 48px;
+ border: 0;
+ background: transparent url('images/top.png') no-repeat;
+ opacity: 0.2;
+ text-indent: -9999px;
+ }
+}
+
+/* content */
+#dokuwiki__content {
+ margin-top: 40px;
+
+ div.breadcrumbs {
+ margin-bottom: 1em;
+ padding: 0.4em 1em;
+ opacity: 0.4;
+ }
+ div.breadcrumbs:hover {
+ opacity: 1.0;
+ }
+ div.page {
+ padding: 1em;
+ }
+}
+
+/* footer */
+#dokuwiki__footer {
+ border-top: 1px solid @ini_border;
+ padding: 0.5em 1em;
+
+ div.doc {
+ margin-bottom: 1em;
+ }
+ div.license {
+ margin-bottom: 1em;
+ font-size: 85%;
+
+ > a {
+ float: left;
+ margin-right: .5em;
+ padding-top: .3em;
+ }
+ a.urlextern {
+ float: left;
+ display: block;
+ background-position: 0 0.2em;
+ }
+ :after {
+ content: '';
+ display: block;
+ clear: both;
+ }
+ }
+ div.footer {
+ margin: 0 -1em;
+ padding: 0.5em 1em;
+ }
+}
+
+/* icons */
diff --git a/platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.eot b/platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.eot
new file mode 100644
index 0000000..95bb006
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.eot
Binary files differ
diff --git a/platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.ttf b/platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.ttf
new file mode 100644
index 0000000..091f756
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.ttf
Binary files differ
diff --git a/platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.woff b/platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.woff
new file mode 100644
index 0000000..4a52852
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/css/fonts/Norwester-Regular.woff
Binary files differ
diff --git a/platform/www/lib/tpl/acervus/css/hacks.css b/platform/www/lib/tpl/acervus/css/hacks.css
new file mode 100644
index 0000000..3349974
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/css/hacks.css
@@ -0,0 +1,187 @@
+#dokuwiki__site {
+ background: #f8f8f8cc;
+}
+
+#dokuwiki__header {
+ background: #fff;
+ border-bottom: 1px solid #ddd;
+ box-shadow: 1px 1px 24px #dadada94;
+}
+
+#dokuwiki__header strong {
+ color: darkred;
+}
+
+#dokuwiki__header em {
+ font-weight: 400;
+}
+
+#dokuwiki__content div.breadcrumbs {
+ margin-bottom: 1em;
+ padding: 2em 1em 0em;
+ opacity: 0.4;
+}
+
+#dokuwiki__content div.download {
+ /* margin-bottom: 1em; */
+ padding: 0.6em 1em 0em;
+ opacity: 0.6;
+}
+
+
+#dokuwiki__content div.page a:link, a:visited {
+ color: #A00;
+}
+
+h1#sitetitle:hover {
+ text-shadow: 0px 0px 5px #ccc;
+}
+
+#dokuwiki__footer div.doc {
+ margin-bottom: 1em;
+ text-align: center;
+ font-size: 80%;
+ color: #5a5a5a;
+}
+
+.dokuwiki form.bureaucracy__plugin fieldset {
+ width: 100%;
+}
+
+.dokuwiki form.bureaucracy__plugin label input[type=checkbox] {
+ width: 5%;
+ margin-right: 45%;
+ vertical-align: -webkit-baseline-middle;
+}
+
+.dokuwiki form.bureaucracy__plugin label>span {
+ vertical-align: middle;
+ padding-right: 5px;
+}
+
+.dokuwiki form.bureaucracy__plugin {
+ margin: 0;
+}
+
+.dokuwiki div.bureaucracy__plugin {
+ width: 100%;
+ font-size: 100%;
+ padding: 0em;
+ border-radius: 3px;
+ animation: highlight 10000ms ease-in;
+}
+
+.dokuwiki div.bureaucracy__plugin:target {
+
+}
+@keyframes highlight {
+ 0% {
+ background-color: white;
+ }
+ 50% {
+ background-color: yellow;
+ }
+ 100% {
+ background-color: white;
+ }
+}
+
+
+input[type=text], textarea {
+ -webkit-transition: all 0.30s ease-in-out;
+ -moz-transition: all 0.30s ease-in-out;
+ -ms-transition: all 0.30s ease-in-out;
+ -o-transition: all 0.30s ease-in-out;
+ outline: none;
+ padding: 3px 0px 3px 3px;
+ margin: 5px 1px 3px 0px;
+ border: 1px solid #DDDDDD;
+}
+
+input[type=text]:focus, textarea:focus {
+ box-shadow: 0 0 5px rgba(81, 203, 238, 1);
+ padding: 3px 0px 3px 3px;
+ margin: 5px 1px 3px 0px;
+ border: 1px solid rgba(81, 203, 238, 1);
+}
+
+.anchorjs-link{
+color: #c5c5c5 !important;
+ transition: all .25s linear;
+}
+p a.anchorjs-link:hover {
+ margin-left: -1.125em !important;
+color: red !important;
+text-decoration:none !important;
+}
+
+h2 a.anchorjs-link, h3 a.anchorjs-link, h4 a.anchorjs-link, h5 a.anchorjs-link, li a.anchorjs-link {
+ margin-left: -1.8em !important;
+}
+
+h2 a.anchorjs-link:hover, h3 a.anchorjs-link:hover, h4 a.anchorjs-link:hover, h5 a.anchorjs-link:hover {
+ margin-left: -1.9em !important;
+color: red !important;
+text-decoration:none !important;
+}
+
+.dw__toc .anchorjs-link {
+ display: none;
+}
+
+#dokuwiki__content {
+ counter-reset: paragraph;
+}
+
+.page p a.anchorjs-link:before {
+ position: absolute;
+ right: 22px;
+ color: #c5c5c5;
+ content: counter(paragraph);
+ counter-increment: paragraph;
+ text-align: right;
+ font-size: 12pt;
+ top: 1px;
+}
+
+
+
+.numbered_heading .page {counter-reset: level1;}
+.numbered_heading #dw__toc:before,
+.numbered_heading #dw__toc:after {counter-reset: level1; content: "";}
+.numbered_heading #dw__toc h3:before{content: ""}
+
+.numbered_heading ul.toc li.level1 {counter-reset: level2;}
+.numbered_heading ul.toc li.level2 {counter-reset: level3;}
+.numbered_heading ul.toc li.level3 {counter-reset: level4;}
+.numbered_heading ul.toc li.level4 {counter-reset: level5;}
+.numbered_heading ul.toc li.level5 {}
+
+.numbered_heading ul.toc li.level1 a:before {
+ content: counter(level1) ". ";
+ counter-increment: level1;
+}
+
+.numbered_heading ul.toc li.level1:first-child a:before {
+ /* content: none; */
+}
+
+.numbered_heading ul.toc li.level2 a:before {
+ content: counter(level1) "." counter(level2) ". ";
+ counter-increment: level2;
+}
+
+.numbered_heading ul.toc li.level3 a:before {
+ content: counter(level1) "." counter(level2) "." counter(level3) ". ";
+ counter-increment: level3;
+}
+
+.numbered_heading ul.toc li.level4 a:before {
+ content: counter(level1) "." counter(level2) "." counter(level3) "." counter(level4) ". ";
+ counter-increment: level4;
+}
+
+.numbered_heading ul.toc li.level5 a:before {
+ content: counter(level1) "." counter(level2) "." counter(level3) "." counter(level4) "." counter(level5) ". ";
+ counter-increment: level5;
+}
diff --git a/platform/www/lib/tpl/acervus/css/mobile.less b/platform/www/lib/tpl/acervus/css/mobile.less
new file mode 100644
index 0000000..79f5888
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/css/mobile.less
@@ -0,0 +1,136 @@
+@media only screen and (max-width: 760px) {
+
+/* admin */
+.dokuwiki div.ui-admin {
+ ul.admin_tasks,
+ ul.admin_plugins {
+ float: none;
+ width: 90%;
+ margin: 0;
+ }
+}
+// before "Frusterick Manners"
+.dokuwiki ul.admin_tasks {
+ float: none;
+ width: auto;
+ margin: 0;
+}
+
+/* config */
+#config__manager {
+ fieldset {
+ legend {
+ padding: 0;
+ }
+ td.label,
+ td.value {
+ display: block;
+ width: auto !important;
+ }
+ td.label {
+ padding: .2em .4em;
+ border: none;
+ }
+ td.value {
+ padding: .4em .4em 1.2em;
+ border: none;
+ background: @ini_background;
+ }
+ div.selection {
+ float: none;
+ width: auto;
+ margin-right: 0;
+ }
+ }
+}
+
+/* media manager */
+#mediamanager__page {
+ .panel {
+ float: none;
+ }
+ .namespaces {
+ width: auto;
+ }
+ .filelist {
+ width: auto;
+ min-width: 0;
+ ul {
+ margin: 0;
+ }
+ ul.rows li {
+ display: inline-block;
+ float: left;
+ width: 50%;
+ max-height: none !important;
+
+ dt,
+ dd {
+ float: none !important;
+ width: auto !important;
+ }
+ dt {
+ height: 60px;
+ }
+ dt a {
+ text-align: left;
+ vertical-align: top;
+ width: auto;
+ height: 60px;
+ padding: 0;
+ }
+ dt a img {
+ max-width: none;
+ max-height: 60px;
+ }
+ }
+ ul.rows li:nth-child(2n+1) {
+ background: none;
+ }
+ ul.rows li:hover {
+ background: @ini_background_alt;
+ }
+ }
+ .panelHeader {
+ margin-right: 0;
+ h3 {
+ float: none;
+ }
+ form.options {
+ float: none;
+ }
+ ul li.listType {
+ margin-left: -2px;
+ }
+ }
+ .panelContent {
+ margin: 0 0 20px 0;
+ }
+ .file {
+ width: auto;
+
+ }
+ .ui-resizable-e {
+ display: none !important;
+ }
+}
+
+} /* @media for 760px */
+
+
+@media only screen and (max-width: 480px) {
+ /* TOC */
+ #dw__toc {
+ display: block;
+ }
+
+ /* WRAP plugin */
+ .dokuwiki .wrap_left,
+ .dokuwiki .wrap_right,
+ .dokuwiki .wrap_center,
+ .dokuwiki .wrap_column {
+ float: inherit;
+ width: 100% !important;
+ margin: 0;
+ }
+} /* @media for 480px */
diff --git a/platform/www/lib/tpl/acervus/css/print.less b/platform/www/lib/tpl/acervus/css/print.less
new file mode 100644
index 0000000..6fe15d4
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/css/print.less
@@ -0,0 +1,94 @@
+/**
+ * This file provides the styles for printing.
+ */
+
+/* hide certain sections */
+audio,
+video,
+.sidebar,
+.breadcrumbs,
+#dokuwiki__header .left,
+#dokuwiki__header .right,
+#dokuwiki__header .search,
+#dw__toc span,
+#dokuwiki__footer .doc,
+#to_top {
+ display: none;
+}
+
+a:link,
+a:visited {
+ text-decoration: none;
+ border-bottom: 1pt dotted;
+ color: #333;
+ background-color: inherit;
+}
+
+#dokuwiki__header,
+#dw__toc {
+ a:link,
+ a:visited {
+ border: none;
+ }
+}
+
+/* code blocks */
+pre {
+ font-family: monospace;
+}
+dl.code dt,
+dl.file dt {
+ font-weight: bold;
+}
+
+/* images */
+img {
+ border-width: 0;
+ vertical-align: middle;
+}
+.medialeft {
+ margin-right: .6em;
+}
+.mediaright {
+ margin-left: .6em;
+}
+
+/* tables */
+table {
+ border-collapse: collapse;
+}
+th,
+td {
+ text-align: left;
+ border-bottom: 1px solid #999;
+}
+
+
+/*____________ a bit of layout ____________*/
+
+#dokuwiki__header {
+ border-bottom: 1pt solid #999;
+
+ h1 {
+ font-size: 1.5em;
+ }
+}
+
+#dokuwiki__footer {
+ border-top: 1pt solid #999;
+ div.license {
+ padding-top: .5em;
+ > a {
+ display: inline-block;
+ float: left;
+ margin: .2em .5em 0 0;
+ }
+ }
+}
+
+.dokuwiki div.footnotes {
+ clear: both;
+ border-top: 1pt solid #000;
+ margin-top: 10pt;
+ padding: 1em 0;
+}
diff --git a/platform/www/lib/tpl/acervus/css/responsive.css b/platform/www/lib/tpl/acervus/css/responsive.css
new file mode 100644
index 0000000..ecb8db4
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/css/responsive.css
@@ -0,0 +1,13 @@
+h1#sitetitle-short p, h1#sitetitle p {margin: 0;}
+
+@media (min-width: 768px) {
+ h1#sitetitle-short {display:none;}
+ h1#sitetitle {display:inline-block;}
+
+}
+
+@media (max-width: 768px) {
+ h1#sitetitle-short {display:inline-block;}
+ h1#sitetitle {display:none;}
+
+}
diff --git a/platform/www/lib/tpl/acervus/css/structure.less b/platform/www/lib/tpl/acervus/css/structure.less
new file mode 100644
index 0000000..9b8dab4
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/css/structure.less
@@ -0,0 +1,64 @@
+/* header */
+#dokuwiki__header {
+ position: fixed;
+ z-index: 102;
+ top: 0;
+ width: 100%;
+ max-height: 40px;
+
+ h1 {
+ display: inline-block;
+ width: 50%;
+ text-align: center;
+ }
+ div.left {
+ width: 25%;
+ float: left;
+ /* trick for keep width when aside is deactivated */
+ min-height: 1px;
+ }
+ div.right {
+ width: 25%;
+ float: right;
+ text-align: right;
+ }
+ div.search {
+ float: right;
+ }
+}
+
+/* nav */
+.sidebar {
+ position: fixed;
+ z-index: 104;
+ width: @ini_sidebar_width;
+ max-width: 66%;
+ height: 100%;
+}
+
+#dokuwiki__aside {
+ left: 0;
+}
+#dokuwiki__tools {
+ right: 0;
+}
+#sidebar_bg {
+ position: fixed;
+ z-index: 103;
+ width: 100%;
+ height: 100%;
+}
+#to_top {
+ position: fixed;
+ z-index: 101;
+ right: 10px;
+ bottom: 10px;
+}
+
+/* content */
+.wrapper {
+ margin: 0 auto;
+ max-width: @ini_body_width;
+}
+
+/* footer */
diff --git a/platform/www/lib/tpl/acervus/detail.php b/platform/www/lib/tpl/acervus/detail.php
new file mode 100644
index 0000000..e1b4900
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/detail.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * DokuWiki Image Detail Page
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+// must be run from within DokuWiki
+if (!defined('DOKU_INC')) die();
+@require_once(dirname(__FILE__).'/tpl_functions.php');
+header('X-UA-Compatible: IE=edge,chrome=1');
+
+?><!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>"
+ lang="<?php echo $conf['lang']?>" dir="<?php echo $lang['direction'] ?>" class="no-js">
+<head>
+ <meta charset="UTF-8" />
+ <title>
+ <?php echo hsc(tpl_img_getTag('IPTC.Headline',$IMG))?>
+ [<?php echo strip_tags($conf['title'])?>]
+ </title>
+ <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
+ <?php tpl_metaheaders()?>
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
+ <?php echo tpl_favicon(array('favicon', 'mobile')) ?>
+ <?php tpl_includeFile('meta.html') ?>
+</head>
+
+<body>
+ <div id="dokuwiki__detail" class="<?php echo tpl_classes(); ?>">
+ <?php html_msgarea() ?>
+
+ <?php if($ERROR): print $ERROR; ?>
+ <?php else: ?>
+
+ <?php if($REV) echo p_locale_xhtml('showrev');?>
+ <h1><?php echo hsc(tpl_img_getTag('IPTC.Headline', $IMG))?></h1>
+
+ <div class="content group">
+ <?php tpl_img(900, 700); ?>
+
+ <div class="img_detail">
+ <h2><?php print nl2br(hsc(tpl_img_getTag('simple.title'))); ?></h2>
+
+ <?php if(function_exists('tpl_img_meta')): ?>
+ <?php tpl_img_meta(); ?>
+ <?php else: /* deprecated since Release 2014-05-05 */ ?>
+ <dl>
+ <?php
+ $config_files = getConfigFiles('mediameta');
+ foreach ($config_files as $config_file) {
+ if(@file_exists($config_file)) {
+ include($config_file);
+ }
+ }
+
+ foreach($fields as $key => $tag){
+ $t = array();
+ if (!empty($tag[0])) {
+ $t = array($tag[0]);
+ }
+ if(is_array($tag[3])) {
+ $t = array_merge($t,$tag[3]);
+ }
+ $value = tpl_img_getTag($t);
+ if ($value) {
+ echo '<dt>'.$lang[$tag[1]].':</dt><dd>';
+ if ($tag[2] == 'date') {
+ echo dformat($value);
+ } else {
+ echo hsc($value);
+ }
+ echo '</dd>';
+ }
+ }
+ ?>
+ </dl>
+ <?php endif; ?>
+ <?php //Comment in for Debug// dbg(tpl_img_getTag('Simple.Raw')); ?>
+ </div>
+ </div><!-- /.content -->
+
+ <p class="back">
+ <?php tpl_action('mediaManager', 1) ?><br />
+ &larr; <?php tpl_action('img_backto', 1) ?>
+ </p>
+
+ <?php endif; ?>
+ </div>
+</body>
+</html>
diff --git a/platform/www/lib/tpl/acervus/images/apple-touch-icon.png b/platform/www/lib/tpl/acervus/images/apple-touch-icon.png
new file mode 100644
index 0000000..73d2601
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/images/apple-touch-icon.png
Binary files differ
diff --git a/platform/www/lib/tpl/acervus/images/bg.png b/platform/www/lib/tpl/acervus/images/bg.png
new file mode 100644
index 0000000..007b812
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/images/bg.png
Binary files differ
diff --git a/platform/www/lib/tpl/acervus/images/bg2.png b/platform/www/lib/tpl/acervus/images/bg2.png
new file mode 100644
index 0000000..4b1f61e
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/images/bg2.png
Binary files differ
diff --git a/platform/www/lib/tpl/acervus/images/bg3.png b/platform/www/lib/tpl/acervus/images/bg3.png
new file mode 100644
index 0000000..1ea6e1e
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/images/bg3.png
Binary files differ
diff --git a/platform/www/lib/tpl/acervus/images/favicon.ico b/platform/www/lib/tpl/acervus/images/favicon.ico
new file mode 100644
index 0000000..ecbf22f
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/images/favicon.ico
Binary files differ
diff --git a/platform/www/lib/tpl/acervus/images/ipari-simpleline.png b/platform/www/lib/tpl/acervus/images/ipari-simpleline.png
new file mode 100644
index 0000000..e48025e
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/images/ipari-simpleline.png
Binary files differ
diff --git a/platform/www/lib/tpl/acervus/images/top.png b/platform/www/lib/tpl/acervus/images/top.png
new file mode 100644
index 0000000..1d43e0c
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/images/top.png
Binary files differ
diff --git a/platform/www/lib/tpl/acervus/lang/de/lang.php b/platform/www/lib/tpl/acervus/lang/de/lang.php
new file mode 100644
index 0000000..7a8b91b
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/de/lang.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author LarsDW223
+ */
+$lang['__link__'] = 'Allgemeine Linkfarbe';
+$lang['__existing__'] = 'Farbe für Links zu existierenden Seiten';
+$lang['__missing__'] = 'Farbe für Links zu nicht-existierenden Seiten';
+$lang['__numbered_heading__'] = 'Farbe für nummerierte Überschriften';
+$lang['__font_size__'] = 'Globale Schriftgröße (%, px, pt)';
+$lang['__line_height__'] = 'Globale Zeilenhöhe (x.x, %)';
+$lang['__body_width__'] = 'Breite der Seite (%, px, em, ...)';
+$lang['__sidebar_width__'] = 'Breite der Sidebar, falls vorhanden (%, px, em, ...)';
diff --git a/platform/www/lib/tpl/acervus/lang/de/settings.php b/platform/www/lib/tpl/acervus/lang/de/settings.php
new file mode 100644
index 0000000..671f49e
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/de/settings.php
@@ -0,0 +1,6 @@
+<?php
+
+$lang['numberedHeading'] = 'Ãœberschriften nummerieren';
+$lang['tocPosition'] = 'Position des Inhaltsverzeichnisses';
+$lang['tocPosition_o_dokuwiki'] = 'DokuWiki';
+$lang['tocPosition_o_wikipedia'] = 'Wikipedia';
diff --git a/platform/www/lib/tpl/acervus/lang/de/style.txt b/platform/www/lib/tpl/acervus/lang/de/style.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/de/style.txt
@@ -0,0 +1 @@
+
diff --git a/platform/www/lib/tpl/acervus/lang/en/lang.php b/platform/www/lib/tpl/acervus/lang/en/lang.php
new file mode 100644
index 0000000..1583452
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/en/lang.php
@@ -0,0 +1,13 @@
+<?php
+
+// style.ini values
+
+$lang['download'] = 'Download';
+$lang['__link__'] = 'The general link color';
+$lang['__existing__'] = 'The color for links to existing pages';
+$lang['__missing__'] = 'The color for links to non-existing pages';
+$lang['__numbered_heading__'] = 'The color for numbered heading';
+$lang['__font_size__'] = 'The global font size (%, px, pt)';
+$lang['__line_height__'] = 'The global line height (x.x, %)';
+$lang['__body_width__'] = 'The width of the body (%, px, em, ...)';
+$lang['__sidebar_width__'] = 'The width of the sidebar, if any (%, px, em, ...)';
diff --git a/platform/www/lib/tpl/acervus/lang/en/settings.php b/platform/www/lib/tpl/acervus/lang/en/settings.php
new file mode 100644
index 0000000..18fa82c
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/en/settings.php
@@ -0,0 +1,7 @@
+<?php
+
+$lang['numberedHeading'] = 'Numbering headings';
+$lang['tocPosition'] = 'Position of TOC';
+$lang['tocPosition_o_dokuwiki'] = 'DokuWiki';
+$lang['tocPosition_o_wikipedia'] = 'Wikipedia';
+$lang['footer'] = 'Footer page name, empty field disables the footer';
diff --git a/platform/www/lib/tpl/acervus/lang/en/style.txt b/platform/www/lib/tpl/acervus/lang/en/style.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/en/style.txt
@@ -0,0 +1 @@
+
diff --git a/platform/www/lib/tpl/acervus/lang/es/lang.php b/platform/www/lib/tpl/acervus/lang/es/lang.php
new file mode 100644
index 0000000..c0e1f6f
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/es/lang.php
@@ -0,0 +1,5 @@
+<?php
+
+// style.ini values
+
+$lang['download'] = 'Descargar';
diff --git a/platform/www/lib/tpl/acervus/lang/ko/lang.php b/platform/www/lib/tpl/acervus/lang/ko/lang.php
new file mode 100644
index 0000000..09e149a
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/ko/lang.php
@@ -0,0 +1,15 @@
+<?php
+
+/**
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ *
+ * @author Myeongjin <aranet100@gmail.com>
+ */
+$lang['__link__'] = 'ì¼ë°˜ ë§í¬ 색';
+$lang['__existing__'] = '문서가 존재하는 ë§í¬ì˜ 색';
+$lang['__missing__'] = '문서가 존재하지 않는 ë§í¬ì˜ 색';
+$lang['__numbered_heading__'] = '제목 번호 색';
+$lang['__font_size__'] = 'ì „ì²´ 사ì´íŠ¸ ê¸€ìž í¬ê¸° (%, px, pt)';
+$lang['__line_height__'] = 'ì „ì²´ 사ì´íŠ¸ 줄 간격 (x.x, %)';
+$lang['__body_width__'] = '본문 너비 (%, px, em, ...)';
+$lang['__sidebar_width__'] = '사ì´ë“œë°”ê°€ 있다면, ê·¸ê²ƒì˜ ë„ˆë¹„ (%, px, em, ...)';
diff --git a/platform/www/lib/tpl/acervus/lang/ko/settings.php b/platform/www/lib/tpl/acervus/lang/ko/settings.php
new file mode 100644
index 0000000..089d158
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/ko/settings.php
@@ -0,0 +1,7 @@
+<?php
+
+$lang['numberedHeading'] = '제목 ìˆ˜ì¤€ì— ë²ˆí˜¸ë¥¼ 붙힙니다.';
+$lang['tocPosition'] = 'ëª©ì°¨ì˜ ìœ„ì¹˜';
+$lang['tocPosition_o_dokuwiki'] = 'ë„쿠위키 기본';
+$lang['tocPosition_o_wikipedia'] = '위키백과 스타ì¼';
+$lang['footer'] = '바닥글 문서 ì´ë¦„, 필드를 비우면 바닥글 비활성화';
diff --git a/platform/www/lib/tpl/acervus/lang/ko/style.txt b/platform/www/lib/tpl/acervus/lang/ko/style.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/ko/style.txt
@@ -0,0 +1 @@
+
diff --git a/platform/www/lib/tpl/acervus/lang/ru/lang.php b/platform/www/lib/tpl/acervus/lang/ru/lang.php
new file mode 100644
index 0000000..2cec63d
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/ru/lang.php
@@ -0,0 +1,12 @@
+<?php
+
+// style.ini values
+
+$lang['__link__'] = 'ОÑновной цвет ÑÑылок';
+$lang['__existing__'] = 'Цвет ÑÑылок на ÑущеÑтвующие Ñтраницы';
+$lang['__missing__'] = 'Цвет ÑÑылок на не ÑущеÑтвующие Ñтраницы';
+$lang['__numbered_heading__'] = 'Цвет Ð´Ð»Ñ Ð½ÑƒÐ¼ÐµÑ€Ð¾Ð²Ð°Ð½Ð½Ð¾Ð³Ð¾ заголовка';
+$lang['__font_size__'] = 'ОÑновной размер шрифта (%, px, pt)';
+$lang['__line_height__'] = 'ОÑÐ½Ð¾Ð²Ð½Ð°Ñ Ð²Ñ‹Ñота Ñтроки (x.x, %)';
+$lang['__body_width__'] = 'Ширина Ñтраницы (%, px, em, ...)';
+$lang['__sidebar_width__'] = 'Ширина боковой панели, еÑли она еÑÑ‚ÑŒ (%, px, em, ...)';
diff --git a/platform/www/lib/tpl/acervus/lang/ru/settings.php b/platform/www/lib/tpl/acervus/lang/ru/settings.php
new file mode 100644
index 0000000..0be18f8
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/ru/settings.php
@@ -0,0 +1,3 @@
+<?php
+
+$lang['numberedHeading'] = 'ÐÑƒÐ¼ÐµÑ€Ð°Ñ†Ð¸Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ¾Ð²';
diff --git a/platform/www/lib/tpl/acervus/lang/ru/style.txt b/platform/www/lib/tpl/acervus/lang/ru/style.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/lang/ru/style.txt
@@ -0,0 +1 @@
+
diff --git a/platform/www/lib/tpl/acervus/main.php b/platform/www/lib/tpl/acervus/main.php
new file mode 100644
index 0000000..c4dfd1c
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/main.php
@@ -0,0 +1,265 @@
+<?php
+/**
+ * DokuWiki Starter Template
+ *
+ * @link http://dokuwiki.org/template:ipari
+ * @author Kwangyoung Lee <ipari@leaflette.com>
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+if (!defined('DOKU_INC')) die();
+@require_once(dirname(__FILE__).'/tpl_functions.php');
+header('X-UA-Compatible: IE=edge,chrome=1');
+$showSidebar = page_findnearest($conf['sidebar']);
+?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang'] ?>"
+ lang="<?php echo $conf['lang'] ?>" dir="<?php echo $lang['direction'] ?>" class="no-js">
+<head>
+ <meta charset="UTF-8" />
+ <title><?php tpl_pagetitle() ?> [<?php echo strip_tags($conf['title']) ?>]</title>
+ <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
+ <?php tpl_metaheaders() ?>
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
+ <?php echo tpl_favicon(array('favicon', 'mobile')) ?>
+ <?php tpl_includeFile('meta.html') ?>
+
+<script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script>
+<!-- <link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,wght@0,200;0,300;0,400;0,600;0,700;0,900;1,200;1,300;1,400;1,600;1,700;1,900&display=swap" rel="stylesheet"> -->
+
+<link rel="preconnect" href="https://fonts.googleapis.com">
+<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+<link href="https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,500;0,600;0,700;0,800;1,400;1,500;1,600;1,700;1,800&display=swap" rel="stylesheet">
+
+<?php
+$translation = plugin_load('helper','translation');
+global $ID;
+$startpage = $conf['start'];
+$lang2 = $translation->getLangPart($ID);
+if ($lang2 != '') {
+ $startpage = $lang2 .':'.$startpage;
+}
+?>
+
+</head>
+
+<body id="dokuwiki__top">
+ <div id="dokuwiki__site" class="<?php echo tpl_classes(); ?> <?php echo ($showSidebar) ? 'hasSidebar' : ''; ?>">
+ <?php html_msgarea() ?>
+ <?php tpl_includeFile('header.html') ?>
+
+ <!-- ********** HEADER ********** -->
+ <div id="dokuwiki__header">
+ <div class="group">
+ <!-- <h1 id="sitetitle"><?php tpl_link('/'.$startpage,$title_text,'accesskey="h" title="[H]"') ?></h1> -->
+ <h1><?php tpl_link('/'.$startpage,$conf['title'],'accesskey="h" title="[H]"') ?></h1>
+ <div class="left">
+ <?php if ($showSidebar): ?>
+ <button class="btn_left" accesskey="s", title="[S]">Nav</button>
+ <?php endif; ?>
+ </div>
+ <div class="right">
+ <button class="btn_search">Search</button>
+ <button class="btn_right" accesskey="m", title="[M]">Edit</button>
+ </div>
+ </div>
+ <div class="search">
+ <?php tpl_searchform(); ?>
+ </div>
+
+
+ </div><!-- /header -->
+
+ <!-- ********** sidebar ********** -->
+ <div id="sidebar_wrapper">
+ <!-- ********** ASIDE ********** -->
+ <?php if ($showSidebar): ?>
+ <div id="dokuwiki__aside" class="sidebar">
+ <?php tpl_includeFile('sidebarheader.html') ?>
+ <?php tpl_include_page($conf['sidebar'], 1, 1) ?>
+ <?php tpl_includeFile('sidebarfooter.html') ?>
+ </div><!-- /dokuwiki__aside -->
+ <?php endif; ?>
+
+ <div id="dokuwiki__tools" class="sidebar left">
+ <!-- PAGE TOOLS -->
+ <div id="dokuwiki__pagetools">
+ <h3><?php echo $lang['page_tools'] ?></h3>
+ <ul>
+ <?php white_toolsevent('pagetools', array(
+ 'edit' => tpl_action('edit', 1, 'li', 1, '<span>', '</span>'),
+ 'revisions' => tpl_action('revisions', 1, 'li', 1, '<span>', '</span>'),
+ 'backlink' => tpl_action('backlink', 1, 'li', 1, '<span>', '</span>'),
+ 'subscribe' => tpl_action('subscribe', 1, 'li', 1, '<span>', '</span>'),
+ 'revert' => tpl_action('revert', 1, 'li', 1, '<span>', '</span>'),
+ )); ?>
+ </ul>
+ </div><!-- /dokuwiki__pagetools -->
+
+ <!-- SITE TOOLS -->
+ <div id="dokuwiki__sitetools">
+ <h3><?php echo $lang['site_tools'] ?></h3>
+ <ul>
+ <?php white_toolsevent('sitetools', array(
+ 'recent' => tpl_action('recent', 1, 'li', 1, '<span>', '</span>'),
+ 'media' => tpl_action('media', 1, 'li', 1, '<span>', '</span>'),
+ 'index' => tpl_action('index', 1, 'li', 1, '<span>', '</span>'),
+ )); ?>
+ </ul>
+ </div><!-- /dokuwiki__sitetools -->
+
+ <!-- USER TOOLS -->
+ <?php if ($conf['useacl']): ?>
+ <div id="dokuwiki__usertools">
+ <h3><?php echo $lang['user_tools'] ?></h3>
+ <ul>
+ <?php white_toolsevent('usertools', array(
+ 'admin' => tpl_action('admin', 1, 'li', 1, '<span>', '</span>'),
+ 'profile' => tpl_action('profile', 1, 'li', 1, '<span>', '</span>'),
+ 'register' => tpl_action('register', 1, 'li', 1, '<span>', '</span>'),
+ 'login' => tpl_action('login', 1, 'li', 1, '<span>', '</span>'),
+ )); ?>
+ </ul>
+ <?php
+ if (!empty($_SERVER['REMOTE_USER'])) {
+ echo '<div class="user">';
+ tpl_userinfo();
+ echo '</div>';
+ }
+ ?>
+ </div><!-- /dokuwiki__usertools -->
+ <?php endif ?>
+ </div><!-- /dokuwiki__tools -->
+
+ <div id="sidebar_bg">
+ </div>
+
+ <div id="to_top">
+ <?php tpl_action('top') ?>
+ </div>
+ </div><!-- /sidebar_wrapper -->
+
+ <div class="wrapper group">
+ <!-- ********** CONTENT ********** -->
+ <div id="dokuwiki__content"><div class="group">
+ <?php tpl_flush() ?>
+ <?php tpl_includeFile('pageheader.html') ?>
+
+ <!-- BREADCRUMBS -->
+ <?php if($conf['breadcrumbs']){ ?>
+ <div class="breadcrumbs"><?php tpl_breadcrumbs($ret='›') ?></div>
+ <?php } ?>
+ <?php if($conf['youarehere']){ ?>
+ <div class="breadcrumbs"><?php tpl_youarehere() ?></div>
+ <?php } ?>
+
+ <?php
+ $filepath = $INFO['filepath'];
+ $file_markdown = $filepath;
+ $file_pdf = str_replace('.txt','.pdf',$filepath);
+ $file_epub = str_replace('.txt','.epub',$filepath);
+
+ if (file_exists($file_pdf)) {
+ $file_pdf_url = str_replace('/srv/acerv.us/platform/www','',$file_pdf);
+ $download_link .= '<a href="'. $file_pdf_url .'">pdf</a> | ';
+ }
+
+ if (file_exists($file_epub)) {
+ $file_epub_url = str_replace('/srv/acerv.us/platform/www','',$file_epub);
+ $download_link .= '<a href="'. $file_epub_url .'">epub</a> | ';
+ }
+
+ if ($download_link) {
+ $file_markdown_url = str_replace('/srv/acerv.us/platform','',$file_markdown);
+ echo '<div class="download">' . tpl_getLang('download') . ': ' . $download_link . '</div>';
+ $download_link .= '<a href="'. $file_markdown_url .'">markdown</a>';
+ }
+
+
+ ?>
+
+
+ <div class="page group
+ <?php if(tpl_getConf('numberedHeading')): ?> numbered_heading<?php endif ?>
+ <?php if(tpl_getConf('tocPosition')): ?> toc_<?php echo tpl_getConf('tocPosition') ?><?php endif ?>
+ ">
+ <!-- wikipage start -->
+ <?php tpl_content() ?>
+ <!-- wikipage stop -->
+ </div>
+
+ <?php tpl_flush() ?>
+ <?php tpl_includeFile('pagefooter.html') ?>
+ </div></div><!-- /content -->
+
+ <!-- ********** FOOTER ********** -->
+ <div id="dokuwiki__footer">
+ <?php if($INFO['exists']): ?>
+ <div class="doc"><?php white_pageinfo() ?></div>
+ <?php endif ?>
+ <?php tpl_includeFile('sidebarfooter.html') ?>
+ <?php tpl_license('badge', false, false) ?>
+ <div class="footer">
+ <?php tpl_include_page(tpl_getConf('footer'), 1, 1) ?>
+ </div>
+
+ <center><?php
+ if ($translation) echo $translation->showTranslations();
+ ?></center>
+ </div><!-- /footer -->
+
+ <?php tpl_includeFile('footer.html') ?>
+ </div><!-- /wrapper -->
+
+ </div><!-- /site -->
+
+ <div class="no"><?php tpl_indexerWebBug() /* provide DokuWiki housekeeping, required in all templates */ ?></div>
+
+<script>
+
+function getAnchor() {
+ // alert(decodeURI(document.URL));
+ return (decodeURI(document.URL).split('#').length > 1) ? decodeURI(document.URL).split('#')[1] : null;
+}
+
+if (document.URL.toLowerCase().indexOf("index") === -1) { // not show on index
+ if (document.URL.includes(':en') ||
+ document.URL.includes(':es') ||
+ document.URL.includes(':fr') ||
+ document.URL.includes(':script') ||
+ document.URL.includes(':article')
+ ) { // only shows number of paragraph in books, articles and scripts pages
+ anchors.options = {
+ placement: 'left',
+ visible: 'always',
+ icon: '¶'
+ };
+ //anchors.add('');
+ anchors.add('#dokuwiki__content p');
+ anchors.add('#dokuwiki__content li');
+ anchors.add('#dokuwiki__content tr');
+
+ // highlight referenced paragraph
+ anchor = getAnchor();
+ if (anchor !== null) {
+ var anchor_element = document.getElementById(anchor);
+ anchor_element.style.backgroundColor = "#ffff0033";
+ (function($) {
+ $([document.documentElement, document.body]).animate({
+ scrollTop: $("#" + anchor).offset().top-50
+ }, 2000);
+ })(jQuery);
+
+
+ }
+
+ }
+
+}
+
+
+</script>
+
+
+</body>
+</html>
diff --git a/platform/www/lib/tpl/acervus/manager.dat b/platform/www/lib/tpl/acervus/manager.dat
new file mode 100644
index 0000000..7a94e4b
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/manager.dat
@@ -0,0 +1,2 @@
+downloadurl=https://github.com/ipari/dokuwiki-template-white/zipball/master
+installed=Thu, 07 Jun 2018 20:52:40 -0400
diff --git a/platform/www/lib/tpl/acervus/mediamanager.php b/platform/www/lib/tpl/acervus/mediamanager.php
new file mode 100644
index 0000000..d6faf42
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/mediamanager.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * DokuWiki Media Manager Popup
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+// must be run from within DokuWiki
+if (!defined('DOKU_INC')) die();
+@require_once(dirname(__FILE__).'/tpl_functions.php');
+header('X-UA-Compatible: IE=edge,chrome=1');
+
+?><!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo $conf['lang']?>"
+ lang="<?php echo $conf['lang']?>" dir="<?php echo $lang['direction'] ?>" class="popup no-js">
+<head>
+ <meta charset="UTF-8" />
+ <title>
+ <?php echo hsc($lang['mediaselect'])?>
+ [<?php echo strip_tags($conf['title'])?>]
+ </title>
+ <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
+ <?php tpl_metaheaders()?>
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
+ <?php echo tpl_favicon(array('favicon', 'mobile')) ?>
+ <?php tpl_includeFile('meta.html') ?>
+</head>
+
+<body>
+ <div id="media__manager" class="<?php echo tpl_classes(); ?>">
+ <?php html_msgarea() ?>
+ <div id="mediamgr__aside"><div class="group">
+ <h1><?php echo hsc($lang['mediaselect'])?></h1>
+
+ <?php /* keep the id! additional elements are inserted via JS here */?>
+ <div id="media__opts"></div>
+
+ <?php tpl_mediaTree() ?>
+ </div></div>
+
+ <div id="mediamgr__content"><div class="group">
+ <?php tpl_mediaContent() ?>
+ </div></div>
+ </div>
+</body>
+</html>
diff --git a/platform/www/lib/tpl/acervus/script.js b/platform/www/lib/tpl/acervus/script.js
new file mode 100644
index 0000000..503b135
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/script.js
@@ -0,0 +1,81 @@
+(function($) {
+ var fadeOption = {duration: 150};
+
+ function toggleLeft() {
+ $('#sidebar_bg').show('fade', fadeOption);
+ $('#dokuwiki__aside').show();
+ }
+
+ function toggleRight() {
+ $('#sidebar_bg').show('fade', fadeOption);
+ $('#dokuwiki__tools').show();
+ }
+
+ function preventParentWheel(e) {
+ var curScrollPos = $(this).scrollTop();
+ var scrollableDist = $(this).prop('scrollHeight') - $(this).outerHeight();
+ var wheelEvent = e.originalEvent;
+ var dY = wheelEvent.deltaY;
+
+ if (dY < 0 && curScrollPos <= 0) {
+ return false;
+ }
+ if (dY > 0 && curScrollPos >= scrollableDist) {
+ return false;
+ }
+ }
+
+ function showSearch() {
+ $('div.search').toggle();
+ $('div.search').find('input.edit').select();
+ }
+
+ function bindEvents() {
+ $('.sidebar').on('wheel scroll', preventParentWheel);
+ $('.btn_left').click(function() {
+ toggleLeft();
+ });
+ $('.btn_right').click(function() {
+ toggleRight();
+ });
+ $('#sidebar_bg').click(function() {
+ $(this).hide('fade', fadeOption);
+ $('#dokuwiki__aside').hide();
+ $('#dokuwiki__tools').hide();
+ });
+ $('.btn_search').click(function() {
+ showSearch();
+ });
+ $(document).keydown(function(e) {
+ if (e.which == 70 && e.altKey) {
+ showSearch();
+ e.preventDefault();
+ }
+ });
+ }
+
+ function initUI() {
+ // Move TOC
+ if ($('.page h2').length > 0) {
+ $('.toc_wikipedia').find('#dw__toc').insertBefore($('.page h2:first'));
+ } else {
+ $('.toc_wikipedia').find('#dw__toc').insertAfter($('.page h1:first').next('.level1'));
+ }
+ if ($('.page > .level1 > blockquote').length > 0) {
+ $('.toc_dokuwiki').find('#dw__toc').insertAfter($('.page > .level1 > blockquote'));
+ } else {
+ $('.toc_dokuwiki').find('#dw__toc').insertAfter($('.page h1:first'));
+ }
+ // $('.toc_dokuwiki').find('blockquote:first').insertAfter($('.page h1:first'));
+
+ // Anchor link should be shifted by header pixel
+ $(window).on("hashchange", function () {
+ window.scrollTo(window.scrollX, window.scrollY - 48);
+ });
+ }
+
+ $(function() {
+ initUI();
+ bindEvents();
+ });
+})(jQuery);
diff --git a/platform/www/lib/tpl/acervus/style.ini b/platform/www/lib/tpl/acervus/style.ini
new file mode 100644
index 0000000..48e316d
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/style.ini
@@ -0,0 +1,86 @@
+; Please see http://www.php.net/manual/en/function.parse-ini-file.php
+; for limitations of the ini format used here
+
+; To extend this file or make changes to it, it is recommended to create
+; a local conf/tpl/<template-folder-name>/style.ini file to prevent losing
+; any changes after an upgrade.
+; Please don't forget to copy the section your changes should be under
+; (i.e. [stylesheets] or [replacements]) into that file as well.
+
+; Define the stylesheets your template uses here. The second value
+; defines for which output media the style should be loaded. Currently
+; print, screen and all are supported.
+; You can reference CSS and LESS files here. Files referenced here will
+; be checked for updates when considering a cache rebuild while files
+; included through LESS' @import statements are not
+
+[stylesheets]
+
+../dokuwiki/css/_imgdetail.css = screen
+../dokuwiki/css/_media_popup.css = screen
+../dokuwiki/css/_media_fullscreen.css = screen
+../dokuwiki/css/_fileuploader.css = screen
+../dokuwiki/css/_tabs.css = screen
+../dokuwiki/css/_links.css = screen
+../dokuwiki/css/_toc.css = screen
+../dokuwiki/css/_footnotes.css = screen
+../dokuwiki/css/_search.less = screen
+../dokuwiki/css/_recent.css = screen
+../dokuwiki/css/_diff.css = screen
+../dokuwiki/css/_edit.css = screen
+../dokuwiki/css/_modal.css = screen
+../dokuwiki/css/_forms.css = screen
+../dokuwiki/css/_admin.less = screen
+
+css/basic.less = screen
+css/structure.less = screen
+css/design.less = screen
+css/content.less = screen
+css/responsive.css = screen
+css/hacks.css = screen
+
+css/mobile.less = all
+css/print.less = print
+
+
+; This section is used to configure some placeholder values used in
+; the stylesheets. Changing this file is the simplest method to
+; give your wiki a new look.
+; Placeholders defined here will also be made available as LESS variables
+; (with surrounding underscores removed, and the prefix @ini_ added)
+
+[replacements]
+
+;--------------------------------------------------------------------------
+;------ guaranteed dokuwiki color placeholders that every plugin can use
+
+; main text and background colors
+__text__ = "#333" ; @ini_text
+__background__ = "#fff" ; @ini_background
+; alternative text and background colors
+__text_alt__ = "#999" ; @ini_text_alt
+__background_alt__ = "#f6f6f6" ; @ini_background_alt
+; neutral text and background colors
+__text_neu__ = "#666" ; @ini_text_neu
+__background_neu__ = "#ddd" ; @ini_background_neu
+; border color
+__border__ = "#ddd" ; @ini_border
+
+; highlighted text (e.g. search snippets)
+__highlight__ = "#ff9" ; @ini_highlight
+
+; these are used for links
+__link__ = "#AA0000" ; @ini_link
+__existing__ = "#800000" ; @ini_existing
+__missing__ = "#858585" ; @ini_missing
+
+__numbered_heading__ = "#ff00cc" ; @ini_numbered_heading
+
+;--------------------------------------------------------------------------
+; fonts
+__font_size__ = "13pt" ; @ini_font_size
+__line_height__ = "1.6" ; @ini_line_height
+
+; widths
+__body_width__ = "56em" ; @ini_body_width
+__sidebar_width__ = "16em" ; @ini_sidebar_width
diff --git a/platform/www/lib/tpl/acervus/template.info.txt b/platform/www/lib/tpl/acervus/template.info.txt
new file mode 100644
index 0000000..7c68a3e
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/template.info.txt
@@ -0,0 +1,6 @@
+base acervus
+author Franco Augusto
+email franco@reevo.org
+date 2022
+name Illich theme
+desc Theme for Acervus platform. Simple, minimal and responsive template, based in 'White Template'
diff --git a/platform/www/lib/tpl/acervus/tpl_functions.php b/platform/www/lib/tpl/acervus/tpl_functions.php
new file mode 100644
index 0000000..ae82ea5
--- /dev/null
+++ b/platform/www/lib/tpl/acervus/tpl_functions.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Template Functions
+ *
+ * This file provides template specific custom functions that are
+ * not provided by the DokuWiki core.
+ * It is common practice to start each function with an underscore
+ * to make sure it won't interfere with future core functions.
+ */
+
+// must be run from within DokuWiki
+if (!defined('DOKU_INC')) die();
+
+/**
+ * copied to core (available since Detritus)
+ */
+function white_toolsevent($toolsname, $items, $view='main') {
+ $data = array(
+ 'view' => $view,
+ 'items' => $items
+ );
+
+ $hook = 'TEMPLATE_'.strtoupper($toolsname).'_DISPLAY';
+ $evt = new Doku_Event($hook, $data);
+ if($evt->advise_before()){
+ $actions = array('export_pdf');
+ foreach($evt->data['items'] as $k => $html) {
+ if (in_array($k, $actions)) {
+ $html = str_replace(' '.$k, ' plugin_'.$k, $html);
+ }
+ echo $html;
+ }
+ }
+ $evt->advise_after();
+}
+
+function white_breadcrumbs() {
+ global $lang;
+ global $conf;
+
+ //check if enabled
+ if(!$conf['breadcrumbs']) return false;
+
+ $crumbs = breadcrumbs(); //setup crumb trace
+
+ $crumbs_sep = ' <span class="bcsep">'.$sep.'</span> ';
+
+ //render crumbs, highlight the last one
+ print '<h3>'.$lang['breadcrumb'].'</h3>';
+ $last = count($crumbs);
+ $i = 0;
+ print '<ul>';
+ foreach($crumbs as $id => $name) {
+ $i++;
+ print '<li>';
+ if($i == $last) print '<span class="curid">';
+ tpl_link(wl($id), hsc($name), 'class="breadcrumbs" title="'.$id.'"');
+ if($i == $last) print '</span>';
+ print '</li>';
+ }
+ print '</ul>';
+ return true;
+}
+
+function white_pageinfo($ret = false) {
+ global $conf;
+ global $lang;
+ global $INFO;
+ global $ID;
+
+ // return if we are not allowed to view the page
+ if(!auth_quickaclcheck($ID)) {
+ return false;
+ }
+ $date = dformat($INFO['lastmod']);
+
+ // print it
+ if($INFO['exists']) {
+ $out = '';
+ $out .= $lang['lastmod'];
+ $out .= ' ';
+ $out .= $date;
+ if($ret) {
+ return $out;
+ } else {
+ echo $out;
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_admin.less b/platform/www/lib/tpl/dokuwiki/css/_admin.less
new file mode 100644
index 0000000..38ca4bc
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_admin.less
@@ -0,0 +1,64 @@
+.dokuwiki div.ui-admin {
+
+ /* main task grouped in two columns */
+ ul.admin_tasks {
+ float: left;
+ width: 40%;
+ list-style-type: none;
+ font-size: 1.125em;
+ }
+ [dir=rtl] & ul.admin_tasks {
+ float: right;
+ }
+
+ /* general menu item styling */
+ ul {
+ padding: 0;
+ li {
+ margin: 0 0 1em 0;
+ font-weight: bold;
+ list-style-type: none;
+ white-space: nowrap;
+
+ a {
+ display: flex;
+ span {
+ display: inline-block;
+
+ &.icon {
+ width: 1.5em;
+ min-height: 1.5em;
+ margin: 0 0.5em;
+ vertical-align: top;
+
+ svg {
+ width: 1.5em;
+ height: 1.5em;
+ fill: @ini_link;
+ display: inline-block;
+ path {
+ fill: @ini_link;
+ }
+ }
+ }
+
+ &.prompt {
+ white-space: normal;
+ }
+ }
+ }
+ }
+ }
+
+ /* DokuWiki version */
+ #admin__version {
+ clear: left;
+ float: right;
+ color: @ini_text_neu;
+ background-color: inherit;
+ }
+ [dir=rtl] & #admin__version {
+ clear: right;
+ float: left;
+ }
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_diff.css b/platform/www/lib/tpl/dokuwiki/css/_diff.css
new file mode 100644
index 0000000..bc56a37
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_diff.css
@@ -0,0 +1,137 @@
+/**
+ * This file provides styles for the diff view, which shows you
+ * differences between two versions of a page (?do=diff).
+ */
+
+.dokuwiki table.diff {
+ width: 100%;
+ border-width: 0;
+}
+.dokuwiki table.diff th,
+.dokuwiki table.diff td {
+ vertical-align: top;
+ padding: 0;
+ border-width: 0;
+ /* no style.ini colours because deleted and added lines have a fixed background colour */
+ background-color: #fff;
+ color: #333;
+}
+
+/* table header */
+.dokuwiki table.diff th {
+ border-bottom: 1px solid @ini_border;
+ font-size: 110%;
+ font-weight: normal;
+}
+.dokuwiki table.diff th a {
+ font-weight: bold;
+}
+.dokuwiki table.diff th span.user {
+ font-size: .9em;
+}
+.dokuwiki table.diff th span.sum {
+ font-size: .9em;
+ font-weight: bold;
+}
+.dokuwiki table.diff th.minor {
+ color: #999;
+}
+.dokuwiki table.diff_sidebyside th {
+ width: 50%;
+}
+
+/* table body */
+.dokuwiki table.diff .diff-lineheader {
+ width: .7em;
+ text-align: right;
+}
+[dir=rtl] .dokuwiki table.diff .diff-lineheader {
+ text-align: left;
+}
+.dokuwiki table.diff .diff-lineheader,
+.dokuwiki table.diff td {
+ font-family: Consolas, "Andale Mono WT", "Andale Mono", "Bitstream Vera Sans Mono", "Nimbus Mono L", Monaco, "Courier New", monospace;
+}
+.dokuwiki table.diff td.diff-blockheader {
+ font-weight: bold;
+}
+.dokuwiki table.diff .diff-addedline {
+ background-color: #cfc;
+ color: inherit;
+}
+.dokuwiki table.diff .diff-deletedline {
+ background-color: #fdd;
+ color: inherit;
+}
+.dokuwiki table.diff td.diff-context {
+ background-color: #eee;
+ color: inherit;
+}
+.dokuwiki table.diff td.diff-addedline strong,
+.dokuwiki table.diff td.diff-deletedline strong {
+ color: #f00;
+ background-color: inherit;
+ font-weight: bold;
+}
+
+/* diff options */
+
+.dokuwiki .diffoptions form {
+ float: left;
+}
+.dokuwiki .diffoptions p {
+ float: right;
+}
+
+/* diff nav */
+
+.dokuwiki table.diff_sidebyside td.diffnav {
+ padding-bottom: .7em;
+}
+.dokuwiki .diffnav a {
+ display: inline-block;
+ vertical-align: middle;
+}
+.dokuwiki .diffnav a span {
+ display: none;
+}
+
+.dokuwiki .diffnav a:hover,
+.dokuwiki .diffnav a:active,
+.dokuwiki .diffnav a:focus {
+ background-color: @ini_background_alt;
+ text-decoration: none;
+}
+
+.dokuwiki .diffnav a:before {
+ display: inline-block;
+ line-height: 1;
+ padding: .2em .4em;
+ border: 1px solid @ini_border;
+ border-radius: 2px;
+ color: @ini_text;
+}
+
+.dokuwiki .diffnav a.diffprevrev:before {
+ content: '\25C0'; /* left triangle */
+}
+.dokuwiki .diffnav a.diffnextrev:before,
+.dokuwiki .diffnav a.difflastrev:before {
+ content: '\25B6'; /* right triangle */
+}
+.dokuwiki .diffnav a.diffbothprevrev:before {
+ content: '\25C0\25C0';
+}
+.dokuwiki .diffnav a.diffbothnextrev:before {
+ content: '\25B6\25B6';
+}
+
+.dokuwiki .diffnav select {
+ width: 60%;
+ min-width: 9em;
+ height: 1.5em; /* height is necessary for longer options in Webkit */
+}
+
+.dokuwiki .diffnav select option[selected] {
+ font-weight: bold;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_edit.css b/platform/www/lib/tpl/dokuwiki/css/_edit.css
new file mode 100644
index 0000000..30926be
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_edit.css
@@ -0,0 +1,141 @@
+/**
+ * This file provides styles for the edit view (?do=edit), preview
+ * and section edit buttons.
+ */
+
+/* edit view
+********************************************************************/
+
+.dokuwiki div.editBox {
+}
+
+/*____________ toolbar ____________*/
+
+.dokuwiki div.toolbar {
+ display: inline-block;
+ margin-bottom: .5em;
+}
+#draft__status {
+ float: right;
+ color: @ini_text_alt;
+ background-color: inherit;
+}
+[dir=rtl] #draft__status {
+ float: left;
+}
+#tool__bar {
+ float: left;
+}
+[dir=rtl] #tool__bar {
+ float: right;
+}
+
+/* buttons inside of toolbar */
+.dokuwiki div.toolbar button.toolbutton {
+}
+/* picker popups (outside of .dokuwiki) */
+div.picker {
+ width: 300px;
+ border: 1px solid @ini_border;
+ background-color: @ini_background_alt;
+ color: inherit;
+}
+/* picker for headlines */
+div.picker.pk_hl {
+ width: auto;
+}
+
+/* buttons inside of picker */
+div.picker button.pickerbutton,
+div.picker button.toolbutton {
+ padding: .1em .35em;
+ border-width: 0;
+}
+
+/*____________ edit textarea ____________*/
+
+.dokuwiki textarea.edit {
+ width: 100%;
+ margin-bottom: .5em;
+}
+
+/*____________ below the textarea ____________*/
+
+.dokuwiki div.editBar {
+ overflow: hidden;
+ margin-bottom: .5em;
+}
+
+/* size and wrap controls */
+#size__ctl {
+ float: right;
+}
+[dir=rtl] #size__ctl {
+ float: left;
+}
+#size__ctl img {
+ cursor: pointer;
+}
+
+/* edit buttons */
+.dokuwiki .editBar .editButtons {
+ display: inline;
+ margin-right: 1em;
+}
+[dir=rtl] .dokuwiki .editBar .editButtons {
+ margin-right: 0;
+ margin-left: 1em;
+}
+.dokuwiki .editBar .editButtons button {
+}
+
+/* summary input and minor changes checkbox */
+.dokuwiki .editBar .summary {
+ display: inline;
+}
+.dokuwiki .editBar .summary label {
+ vertical-align: middle;
+ white-space: nowrap;
+}
+.dokuwiki .editBar .summary label span {
+ vertical-align: middle;
+}
+.dokuwiki .editBar .summary input {
+}
+/* change background colour if summary is missing */
+.dokuwiki .editBar .summary input.missing {
+ color: @ini_text;
+ background-color: #ffcccc;
+}
+
+/* preview
+********************************************************************/
+
+.dokuwiki div.preview {
+ border: dotted @ini_border;
+ border-width: .2em 0;
+ padding: 1.4em 0;
+ margin-bottom: 1.4em;
+}
+
+/* section edit buttons
+********************************************************************/
+
+.dokuwiki .secedit {
+ float: right;
+ margin-top: -1.4em;
+}
+[dir=rtl] .dokuwiki .secedit {
+ float: left;
+}
+.dokuwiki .secedit button {
+ font-size: 75%;
+}
+
+/* style for section highlighting */
+.dokuwiki div.section_highlight {
+ margin: 0 -1em; /* negative side margin = side padding + side border */
+ padding: 0 .5em;
+ border: solid @ini_background_alt;
+ border-width: 0 .5em;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_fileuploader.css b/platform/www/lib/tpl/dokuwiki/css/_fileuploader.css
new file mode 100644
index 0000000..f300396
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_fileuploader.css
@@ -0,0 +1,107 @@
+/**
+ * This file provides the styles for the file uploader
+ * used in the media manager (both fullscreen and popup).
+ */
+
+.qq-uploader {
+ position: relative;
+ width: 100%;
+}
+
+.qq-uploader .error {
+ color: #f00;
+ background-color: #fff;
+}
+
+/* select file button */
+
+.qq-upload-button {
+ display: inline-block;
+ text-decoration: none;
+ font-size: 100%;
+ cursor: pointer;
+ margin: 1px 1px 5px;
+}
+
+.qq-upload-button-focus {
+ outline: 1px dotted;
+}
+
+/* drop area */
+
+.qq-upload-drop-area {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ min-height: 70px;
+ z-index: 2;
+ background: @ini_background_neu;
+ color: @ini_text;
+ text-align: center;
+}
+
+.qq-upload-drop-area span {
+ display: block;
+ position: absolute;
+ top: 50%;
+ width: 100%;
+ margin-top: -8px;
+ font-size: 120%;
+}
+
+.qq-upload-drop-area-active {
+ background: @ini_background_alt;
+}
+
+/* list of files to upload */
+
+div.qq-uploader ul {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.qq-uploader li {
+ margin: 0 0 5px;
+ color: @ini_text;
+}
+
+.qq-uploader li span,
+.qq-uploader li input,
+.qq-uploader li a {
+ margin-right: 5px;
+}
+
+.qq-upload-file {
+ display: block;
+ font-weight: bold;
+}
+
+.qq-upload-spinner {
+ display: inline-block;
+ background: url("../../images/throbber.gif");
+ width: 15px;
+ height: 15px;
+ vertical-align: text-bottom;
+}
+
+.qq-upload-size,
+.qq-upload-cancel {
+ font-size: 85%;
+}
+
+.qq-upload-failed-text {
+ display: none;
+}
+.qq-upload-fail .qq-upload-failed-text {
+ display: inline;
+}
+
+.qq-action-container * {
+ vertical-align: middle;
+}
+.qq-overwrite-check input {
+ margin-left: 10px;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_footnotes.css b/platform/www/lib/tpl/dokuwiki/css/_footnotes.css
new file mode 100644
index 0000000..a57dfb9
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_footnotes.css
@@ -0,0 +1,31 @@
+/**
+ * This file provides styles for footnotes.
+ */
+
+/*____________ footnotes inside the text ____________*/
+
+/* link to footnote inside the text */
+.dokuwiki sup a.fn_top {
+}
+/* JSpopup */
+div.insitu-footnote {
+ max-width: 40%;
+ min-width: 5em;
+}
+
+/*____________ footnotes at the bottom of the page ____________*/
+
+.dokuwiki div.footnotes {
+ border-top: 1px solid @ini_border;
+ padding: .5em 0 0 0;
+ margin: 1em 0 0 0;
+ clear: both;
+}
+.dokuwiki div.footnotes div.fn {
+}
+.dokuwiki div.footnotes div.fn div.content {
+ display: inline;
+}
+.dokuwiki div.footnotes div.fn sup a.fn_bot {
+ font-weight: bold;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_forms.css b/platform/www/lib/tpl/dokuwiki/css/_forms.css
new file mode 100644
index 0000000..bf70fa2
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_forms.css
@@ -0,0 +1,106 @@
+/* TODO: this file is not up to the best standards and will be fixed after an overhaul of the form code */
+
+/**
+ * This file provides styles for forms in general and specifically
+ * for ?do=
+ * - login
+ * - resendpwd
+ * - register
+ * - profile
+ * - subscribe
+ */
+
+/* ---------------- forms ------------------------ */
+
+.dokuwiki form {
+ border: none;
+ display: inline;
+}
+
+.dokuwiki label.block {
+ display: block;
+ text-align: right;
+ font-weight: bold;
+}
+[dir=rtl] .dokuwiki label.block {
+ text-align: left;
+}
+
+.dokuwiki label.simple {
+ display: block;
+ text-align: left;
+ font-weight: normal;
+}
+[dir=rtl] .dokuwiki label.simple {
+ text-align: right;
+}
+
+.dokuwiki label.block select,
+.dokuwiki label.block input.edit {
+ width: 50%;
+}
+
+.dokuwiki label span {
+ vertical-align: middle;
+}
+
+.dokuwiki fieldset {
+ width: 400px;
+ text-align: center;
+ border: 1px solid @ini_border;
+ padding: 0.5em;
+ margin: auto;
+}
+
+
+.dokuwiki input.edit,
+.dokuwiki select.edit {
+ vertical-align: middle;
+}
+.dokuwiki select.edit {
+ padding: 0.1em 0;
+}
+
+
+.dokuwiki button {
+ vertical-align: middle;
+}
+/**
+ * Styles for auth forms
+ */
+#dw__login label[for="remember__me"] {
+ margin-left: 50%;
+ margin-bottom: 1.4em;
+}
+#dw__login fieldset,
+#dw__resendpwd fieldset,
+#dw__register fieldset {
+ padding-bottom: 0.7em;
+}
+#dw__profiledelete {
+ display: block;
+ margin-top: 2.8em;
+}
+
+/**
+ * Styles for the subscription page
+ */
+
+#subscribe__form {
+ display: block;
+ width: 400px;
+ text-align: center;
+}
+
+#subscribe__form fieldset {
+ text-align: left;
+ margin: 0.5em 0;
+}
+[dir=rtl] #subscribe__form fieldset {
+ text-align: right;
+}
+
+#subscribe__form label {
+ display: block;
+ margin: 0 0.5em 0.5em;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_imgdetail.css b/platform/www/lib/tpl/dokuwiki/css/_imgdetail.css
new file mode 100644
index 0000000..a074000
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_imgdetail.css
@@ -0,0 +1,38 @@
+/**
+ * This file provides styles for the image detail page (detail.php).
+ */
+
+#dokuwiki__detail {
+ padding: 1em;
+}
+#dokuwiki__detail h1 {
+}
+
+#dokuwiki__detail img {
+ float: left;
+ margin: 0 1.5em .5em 0;
+}
+[dir=rtl] #dokuwiki__detail div.content img {
+ float: right;
+ margin-right: 0;
+ margin-left: 1.5em;
+}
+#dokuwiki__detail div.img_detail {
+ float: left;
+}
+[dir=rtl] #dokuwiki__detail div.content div.img_detail {
+ float: right
+}
+
+#dokuwiki__detail div.img_detail h2 {
+}
+#dokuwiki__detail div.img_detail dl {
+}
+#dokuwiki__detail div.img_detail dl dt {
+}
+#dokuwiki__detail div.img_detail dl dd {
+}
+
+#dokuwiki__detail p.back {
+ clear: both;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_links.css b/platform/www/lib/tpl/dokuwiki/css/_links.css
new file mode 100644
index 0000000..695f4b8
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_links.css
@@ -0,0 +1,69 @@
+/**
+ * This file provides styles for all types of links.
+ */
+
+/*____________ links to wiki pages ____________*/
+
+/* existing wikipage */
+.dokuwiki a.wikilink1 {
+}
+/* not existing wikipage */
+.dokuwiki a.wikilink2 {
+ text-decoration: none;
+}
+.dokuwiki a.wikilink2:link,
+.dokuwiki a.wikilink2:visited {
+ border-bottom: 1px dashed;
+}
+.dokuwiki a.wikilink2:hover,
+.dokuwiki a.wikilink2:active,
+.dokuwiki a.wikilink2:focus {
+ border-bottom-width: 0;
+}
+
+/* any link to current page */
+.dokuwiki span.curid a {
+ font-weight: bold;
+}
+
+/*____________ other link types ____________*/
+
+.dokuwiki a.urlextern,
+.dokuwiki a.windows,
+.dokuwiki a.mail,
+.dokuwiki a.mediafile,
+.dokuwiki a.interwiki {
+ background-repeat: no-repeat;
+ background-position: 0 center;
+ padding: 0 0 0 18px;
+}
+/* external link */
+.dokuwiki a.urlextern {
+ background-image: url(../../images/external-link.png);
+}
+/* windows share */
+.dokuwiki a.windows {
+ background-image: url(../../images/unc.png);
+}
+/* email link */
+.dokuwiki a.mail {
+ background-image: url(../../images/email.png);
+}
+
+/* icons of the following are set by dokuwiki in lib/exe/css.php */
+/* link to some embedded media */
+.dokuwiki a.mediafile {
+}
+/* interwiki link */
+.dokuwiki a.interwiki {
+}
+
+/* RTL corrections; if link icons don't work as expected, remove the following lines */
+[dir=rtl] .dokuwiki a.urlextern,
+[dir=rtl] .dokuwiki a.windows,
+[dir=rtl] .dokuwiki a.mail,
+[dir=rtl] .dokuwiki a.interwiki,
+[dir=rtl] .dokuwiki a.mediafile {
+ background-position: right center;
+ padding: 0 18px 0 0;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_media_fullscreen.css b/platform/www/lib/tpl/dokuwiki/css/_media_fullscreen.css
new file mode 100644
index 0000000..9a00d4d
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_media_fullscreen.css
@@ -0,0 +1,541 @@
+/**
+ * This file provides the styles for the fullscreen media manager
+ * (?do=media).
+ *
+ * What most templates would probably need to change (depending on
+ * their site width) are the 4 min-width's (search for @change).
+ */
+
+
+/*____________ structure ____________*/
+
+#mediamanager__page h1 {
+ margin-bottom: .5em;
+}
+
+#mediamanager__page {
+ /* min-width must be summary of all 3 panels' min-widths */
+ min-width: 50em; /* @change */
+ width: 100%;
+ text-align: left;
+}
+[dir=rtl] #mediamanager__page {
+ text-align: right;
+}
+#mediamanager__page .panel {
+ float: left;
+}
+[dir=rtl] #mediamanager__page .panel {
+ float: right;
+}
+
+#mediamanager__page .namespaces {
+ width: 20%;
+ min-width: 10em; /* @change */
+ left:0 !important; /* overrules jQuery UI resizable in rtl */
+}
+#mediamanager__page .filelist {
+ width: 50%;
+ min-width: 25em; /* @change */
+ left:0 !important; /* overrules jQuery UI resizable in rtl */
+}
+#mediamanager__page .file {
+ width: 30%;
+ min-width: 15em; /* @change */
+}
+
+#mediamanager__page .tabs li {
+ white-space: nowrap;
+}
+
+#mediamanager__page .panelHeader {
+ background-color: @ini_background_alt;
+ margin: 0 10px 10px 0;
+ padding: 10px 10px 8px;
+ text-align: left;
+ min-height: 20px;
+ overflow: hidden;
+}
+[dir=rtl] #mediamanager__page .panelHeader {
+ text-align: right;
+ margin: 0 0 10px 10px;
+}
+#mediamanager__page .panelContent {
+ overflow-y: auto;
+ overflow-x: hidden;
+ padding: 0;
+ margin: 0 10px 10px 0;
+ position: relative;
+}
+[dir=rtl] #mediamanager__page .panelContent {
+ text-align: right;
+ margin: 0 0 10px 10px;
+}
+
+#mediamanager__page .file .panelHeader,
+#mediamanager__page .file .panelContent {
+ margin-right: 0;
+}
+[dir=rtl] #mediamanager__page .file .panelHeader,
+[dir=rtl] #mediamanager__page .file .panelContent {
+ margin-left: 0;
+}
+
+#mediamanager__page .ui-resizable-e {
+ width: 6px;
+ right: 2px;
+ background: transparent url(../../images/resizecol.png) center center no-repeat;
+}
+#mediamanager__page .ui-resizable-e:hover {
+ background-color: @ini_background_alt;
+}
+[dir=rtl] #mediamanager__page .ui-resizable-w {
+ width: 6px;
+ left: 2px;
+ background: transparent url(../../images/resizecol.png) center center no-repeat;
+}
+[dir=rtl] #mediamanager__page .ui-resizable-w:hover {
+ background-color: @ini_background_alt;
+}
+
+
+#mediamanager__page dd {
+ margin: 0;
+}
+
+#mediamanager__page .panelHeader h3 {
+ float: left;
+ font-weight: normal;
+ font-size: 1em;
+ padding: 0;
+ margin: 0 0 3px;
+}
+[dir=rtl] #mediamanager__page .panelHeader h3 {
+ float : right
+}
+
+
+/*____________ namespaces panel ____________*/
+
+[dir=rtl] #mediamanager__page .namespaces {
+ text-align: right;
+}
+
+/* make it look like a tab (as in _tabs.css) */
+#mediamanager__page .namespaces h2 {
+ font-size: 1em;
+ display: inline-block;
+ padding: .3em .8em;
+ margin: 0 0 0 .3em;
+ border-radius: .5em .5em 0 0;
+ font-weight: normal;
+ background-color: @ini_background_alt;
+ color: @ini_text;
+ border: 1px solid @ini_border;
+ border-bottom-color: @ini_background_alt;
+ line-height: 1.4em;
+ position: relative;
+ bottom: -1px;
+ z-index: 2;
+}
+[dir=rtl] #mediamanager__page .namespaces h2 {
+ margin: 0 .3em 0 0;
+ position: relative;
+ right: 10px;
+}
+#mediamanager__page .namespaces .panelHeader {
+ border-top: 1px solid @ini_border;
+ z-index: 1;
+}
+
+#mediamanager__page .namespaces ul {
+ margin-left: .2em;
+ margin-bottom: 0;
+ padding: 0;
+ list-style: none;
+}
+[dir=rtl] #mediamanager__page .namespaces ul {
+ margin-left: 0;
+ margin-right: .2em;
+}
+#mediamanager__page .namespaces ul ul {
+ margin-left: 1em;
+}
+[dir=rtl] #mediamanager__page .namespaces ul ul {
+ margin-left: 0;
+ margin-right: 1em;
+}
+#mediamanager__page .namespaces ul ul li {
+ margin: 0;
+}
+
+#mediamanager__page .namespaces ul .selected {
+ background-color: __highlight__;
+ font-weight: bold;
+}
+
+
+/*____________ file list panel ____________*/
+
+/* file list header */
+
+#mediamanager__page .panelHeader form.options {
+ float: right;
+ margin-top: -3px;
+}
+[dir=rtl] #mediamanager__page .panelHeader form.options {
+ float : left
+}
+#mediamanager__page .panelHeader ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+#mediamanager__page .panelHeader ul li {
+ color: @ini_text;
+ float: left;
+ line-height: 1;
+ padding-left: 3px;
+}
+[dir=rtl] #mediamanager__page .panelHeader ul li {
+ padding-right: 3px;
+ padding-left: 0;
+ float: right;
+}
+
+#mediamanager__page .panelHeader ul li.ui-controlgroup-horizontal {
+ padding-left: 30px;
+ margin: 0 0 0 5px;
+}
+#mediamanager__page .panelHeader ul li.listType {
+ background: url('../../images/icon-list.png') 3px 1px no-repeat;
+}
+#mediamanager__page .panelHeader ul li.sortBy {
+ background: url('../../images/icon-sort.png') 3px 1px no-repeat;
+}
+[dir=rtl] #mediamanager__page .panelHeader ul li.ui-controlgroup-horizontal {
+ padding-left: 0;
+ padding-right: 30px;
+ margin: 0 5px 0 0;
+ background-position: right 1px;
+}
+
+#mediamanager__page .panelHeader form.options .ui-controlgroup-horizontal label{
+ font-size: 90%;
+ margin-right: -0.4em;
+ padding: .3em .5em;
+ line-height: 1;
+}
+
+/* file list content */
+
+#mediamanager__page .filelist ul {
+ padding: 0;
+ margin: 0 10px 0 0;
+}
+[dir=rtl] #mediamanager__page .filelist ul {
+ margin: 0 0 0 10px;
+}
+#mediamanager__page .filelist ul.rows {
+ margin: 0;
+}
+#mediamanager__page .filelist .panelContent ul li:hover {
+ background-color: @ini_background_alt;
+}
+
+#mediamanager__page .filelist li dt a {
+ vertical-align: middle;
+ display: table-cell;
+ overflow: hidden;
+}
+
+/* file list as thumbs */
+
+#mediamanager__page .filelist .thumbs li {
+ width: 100px;
+ min-height: 130px;
+ display: inline-block;
+ /* the right margin should visually be 10px, but because of its inline-block nature the whitespace inbetween is about 4px more */
+ margin: 0 6px 10px 0;
+ background-color: @ini_background_neu;
+ color: @ini_text;
+ padding: 5px;
+ vertical-align: top;
+ text-align: center;
+ position: relative;
+ line-height: 1.2;
+}
+[dir=rtl] #mediamanager__page .filelist .thumbs li {
+ margin-right: 0;
+ margin-left: 6px;
+}
+
+#mediamanager__page .filelist .thumbs li dt a {
+ width: 100px;
+ height: 90px;
+}
+
+#mediamanager__page .filelist .thumbs li dt a img {
+ max-width: 90px;
+ max-height: 90px;
+}
+
+#mediamanager__page .filelist .thumbs li .name,
+#mediamanager__page .filelist .thumbs li .size,
+#mediamanager__page .filelist .thumbs li .filesize,
+#mediamanager__page .filelist .thumbs li .date {
+ display: block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ width: 90px;
+ white-space: nowrap;
+}
+#mediamanager__page .filelist .thumbs li .name {
+ padding: 5px 0;
+ font-weight: bold;
+}
+#mediamanager__page .filelist .thumbs li .date {
+ font-style: italic;
+ white-space: normal;
+}
+
+/* file list as rows */
+
+#mediamanager__page .filelist .rows li {
+ list-style: none;
+ display: block;
+ position: relative;
+ max-height: 50px;
+ margin: 0 0 3px 0;
+ background-color: @ini_background;
+ color: @ini_text;
+ overflow: hidden;
+}
+
+#mediamanager__page .filelist .rows li:nth-child(2n+1) {
+ background-color: @ini_background_neu;
+}
+
+#mediamanager__page .filelist .rows li dt {
+ float: left;
+ width: 10%;
+ height: 40px;
+ text-align: center;
+}
+[dir=rtl] #mediamanager__page .filelist .rows li dt {
+ float: right;
+}
+#mediamanager__page .filelist .rows li dt a {
+ width: 100px;
+ height: 40px;
+}
+
+#mediamanager__page .filelist .rows li dt a img {
+ max-width: 40px;
+ max-height: 40px;
+}
+
+#mediamanager__page .filelist .rows li .name,
+#mediamanager__page .filelist .rows li .size,
+#mediamanager__page .filelist .rows li .filesize,
+#mediamanager__page .filelist .rows li .date {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ float: left;
+ margin-left: 1%;
+ white-space: nowrap;
+}
+[dir=rtl] #mediamanager__page .filelist .rows li .name,
+[dir=rtl] #mediamanager__page .filelist .rows li .size,
+[dir=rtl] #mediamanager__page .filelist .rows li .filesize,
+[dir=rtl] #mediamanager__page .filelist .rows li .date {
+ float: right;
+ margin-left: 0;
+ margin-right: 1%;
+}
+
+#mediamanager__page .filelist .rows li .name {
+ width: 30%;
+ font-weight: bold;
+}
+#mediamanager__page .filelist .rows li .size,
+#mediamanager__page .filelist .rows li .filesize {
+ width: 15%;
+}
+#mediamanager__page .filelist .rows li .date {
+ width: 20%;
+ font-style: italic;
+ white-space: normal;
+}
+
+/* upload form */
+
+#mediamanager__page div.upload {
+ padding-bottom: 0.5em;
+}
+
+/*____________ file panel ____________*/
+
+#mediamanager__page .file ul.actions {
+ text-align: center;
+ margin: 0 0 5px;
+ padding: 0;
+ list-style: none;
+}
+#mediamanager__page .file ul.actions li {
+ display: inline;
+ margin: 0;
+}
+
+#mediamanager__page .file div.image {
+ margin-bottom: 5px;
+ text-align: center;
+}
+
+#mediamanager__page .file div.image img {
+ width: 100%;
+}
+
+#mediamanager__page .file dl {
+ margin-bottom: 0;
+}
+#mediamanager__page .file dl dt {
+ font-weight: bold;
+ display: block;
+ background-color: @ini_background_alt;
+}
+#mediamanager__page .file dl dd {
+ display: block;
+ background-color: @ini_background_neu;
+}
+
+
+/* file meta data edit form */
+
+#mediamanager__page form.meta div.row {
+ margin-bottom: 5px;
+}
+
+#mediamanager__page form.meta label span {
+ display: block;
+}
+
+#mediamanager__page form.meta input {
+ width: 50%;
+}
+
+#mediamanager__page form.meta button {
+ width: auto;
+}
+
+#mediamanager__page form.meta textarea.edit {
+ height: 6em;
+ width: 95%;
+ min-width: 95%;
+ max-width: 95%;
+}
+
+/* file revisions form */
+
+#mediamanager__page form.changes ul {
+ margin-left: 10px;
+ padding: 0;
+ list-style-type: none;
+}
+[dir=rtl] #mediamanager__page form.changes ul {
+ margin-left: 0;
+ margin-right: 10px;
+}
+
+#mediamanager__page form.changes ul li div.li div {
+ font-size: 90%;
+ color: @ini_text_neu;
+ padding-left: 18px;
+}
+[dir=rtl] #mediamanager__page form.changes ul li div.li div {
+ padding-left: 0;
+ padding-right: 18px;
+}
+#mediamanager__page form.changes ul li div.li input {
+ position: relative;
+ top: 1px;
+}
+
+/* file diff view */
+
+#mediamanager__diff table {
+ table-layout: fixed;
+ border-width: 0;
+}
+
+#mediamanager__diff td,
+#mediamanager__diff th {
+ width: 48%;
+ margin: 0 5px 10px 0;
+ padding: 0;
+ vertical-align: top;
+ text-align: left;
+ border-color: @ini_background;
+}
+[dir=rtl] #mediamanager__diff td,
+[dir=rtl] #mediamanager__diff th {
+ margin: 0 0 10px 5px;
+ text-align: right;
+}
+
+#mediamanager__diff th {
+ font-weight: normal;
+ background-color: @ini_background;
+ line-height: 1.2;
+}
+#mediamanager__diff th a {
+ font-weight: bold;
+}
+#mediamanager__diff th span {
+ font-size: 90%;
+}
+
+#mediamanager__diff dl dd strong{
+ background-color: __highlight__;
+ color: @ini_text;
+ font-weight: normal;
+}
+
+/* image diff views */
+
+#mediamanager__page .file form.diffView {
+ margin-bottom: 10px;
+ display: block;
+}
+
+#mediamanager__diff div.slider {
+ margin: 10px;
+ width: 95%;
+}
+
+#mediamanager__diff .imageDiff {
+ position: relative;
+}
+#mediamanager__diff .imageDiff .image2 {
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+
+#mediamanager__diff .imageDiff.opacity .image2 {
+ opacity: 0.5;
+}
+
+#mediamanager__diff .imageDiff.portions .image2 {
+ border-right: 1px solid red;
+ overflow: hidden;
+}
+
+#mediamanager__diff .imageDiff.portions img {
+ float: left;
+}
+
+#mediamanager__diff .imageDiff img {
+ width: 100%;
+ max-width: none;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_media_popup.css b/platform/www/lib/tpl/dokuwiki/css/_media_popup.css
new file mode 100644
index 0000000..0be5c49
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_media_popup.css
@@ -0,0 +1,208 @@
+/**
+ * This file provides styles for the media manager popup
+ * (mediamanager.php).
+ */
+
+/*____________ structure ____________*/
+
+html.popup {
+ overflow: auto;
+}
+
+#media__manager {
+ height: 100%;
+ overflow: hidden;
+}
+
+#mediamgr__aside {
+ width: 30%;
+ height: 100%;
+ overflow: auto;
+ position: absolute;
+ left: 0;
+ border-right: 1px solid @ini_border;
+}
+[dir=rtl] #mediamgr__aside {
+ left: auto;
+ right: 0;
+ border-right-width: 0;
+ border-left: 1px solid @ini_border;
+}
+#mediamgr__aside .pad {
+ padding: .5em;
+}
+
+#mediamgr__content {
+ width: 69.7%;
+ height: 100%;
+ overflow: auto;
+ position: absolute;
+ right: 0;
+}
+[dir=rtl] #mediamgr__content {
+ right: auto;
+ left: 0;
+}
+#mediamgr__content .pad {
+ padding: .5em;
+}
+
+#media__manager h1,
+#media__manager h2 {
+ font-size: 1.5em;
+ margin-bottom: .5em;
+ padding-bottom: .2em;
+ border-bottom: 1px solid @ini_border;
+}
+
+/* left side
+********************************************************************/
+
+/*____________ options ____________*/
+
+#media__opts {
+ margin-bottom: .5em;
+}
+
+#media__opts input {
+ margin-right: .3em;
+}
+[dir=rtl] #media__opts input {
+ margin-right: 0;
+ margin-left: .3em;
+}
+#media__opts label {
+}
+
+/*____________ tree ____________*/
+
+#media__tree ul {
+ padding-left: .2em;
+}
+[dir=rtl] #media__tree ul {
+ padding-left: 0;
+ padding-right: .2em;
+}
+#media__tree ul li {
+ clear: left;
+ list-style-type: none;
+ list-style-image: none;
+ margin-left: 0;
+}
+[dir=rtl] #media__tree ul li {
+ clear: right;
+ margin-right: 0;
+}
+#media__tree ul li img {
+ float: left;
+ padding: .5em .3em 0 0;
+}
+[dir=rtl] #media__tree ul li img {
+ float: right;
+ padding: .5em 0 0 .3em;
+}
+#media__tree ul li div.li {
+ display: inline;
+}
+#media__tree ul li li {
+ margin-left: 1.5em;
+}
+[dir=rtl] #media__tree ul li li {
+ margin-left: 0;
+ margin-right: 1.5em;
+}
+
+/* right side
+********************************************************************/
+
+/*____________ upload form ____________*/
+
+/* upload info */
+#media__content div.upload {
+ font-size: .9em;
+ margin-bottom: .5em;
+}
+
+#mediamanager__uploader {
+ margin-bottom: 1em;
+}
+#mediamanager__uploader p {
+ margin-bottom: .5em;
+}
+
+/*____________ file list ____________*/
+
+#media__content img.load {
+ margin: 1em auto;
+}
+
+#media__content .odd,
+#media__content .even {
+ padding: .5em;
+}
+#media__content .odd {
+ background-color: @ini_background_alt;
+}
+#media__content .even {
+}
+/* highlight newly uploaded or edited file */
+#media__content #scroll__here {
+ border: 1px dashed @ini_border;
+}
+
+/* link which inserts media file */
+#media__content a.mediafile {
+ margin-right: 1.5em;
+ font-weight: bold;
+ cursor: pointer;
+}
+[dir=rtl] #media__content a.mediafile {
+ margin-right: 0;
+ margin-left: 1.5em;
+}
+#media__content span.info {
+}
+#media__content img.btn {
+ vertical-align: text-bottom;
+}
+
+/* info how to insert media, if JS disabled */
+#media__content div.example {
+ color: @ini_text_neu;
+ margin-left: 1em;
+}
+
+#media__content div.detail {
+ padding: .2em 0;
+}
+#media__content div.detail div.thumb {
+ float: left;
+ margin: 0 .5em 0 18px;
+}
+[dir=rtl] #media__content div.detail div.thumb {
+ float: right;
+ margin: 0 18px 0 .5em;
+}
+#media__content div.detail div.thumb a {
+ display: block;
+ cursor: pointer;
+}
+#media__content div.detail p {
+ margin-bottom: 0;
+}
+
+
+/*____________ media search ____________*/
+
+#dw__mediasearch {
+}
+#dw__mediasearch p {
+}
+#dw__mediasearch label {
+}
+#dw__mediasearch label span {
+}
+#dw__mediasearch input.edit {
+}
+#dw__mediasearch button {
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_modal.css b/platform/www/lib/tpl/dokuwiki/css/_modal.css
new file mode 100644
index 0000000..37f6483
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_modal.css
@@ -0,0 +1,94 @@
+/**
+ * This file provides styles for modal dialogues.
+ */
+
+.dokuwiki .ui-widget {
+ font-size: 100%;
+}
+
+
+/* link wizard (opens from the link button in the edit toolbar)
+********************************************************************/
+
+#link__wiz {
+}
+
+[dir=rtl] #link__wiz_close {
+ float: left;
+}
+
+#link__wiz_result {
+ background-color: @ini_background;
+ width: 293px;
+ height: 193px;
+ overflow: auto;
+ border: 1px solid @ini_border;
+ margin: 3px auto;
+ text-align: left;
+ line-height: 1;
+}
+[dir=rtl] #link__wiz_result {
+ text-align: right;
+}
+
+#link__wiz_result div {
+ padding: 3px 3px 3px 0;
+}
+
+#link__wiz_result div a {
+ display: block;
+ padding-left: 22px;
+ min-height: 16px;
+ background: transparent 3px center no-repeat;
+}
+[dir=rtl] #link__wiz_result div a {
+ padding: 3px 22px 3px 3px;
+ background-position: 257px 3px;
+}
+
+#link__wiz_result div.type_u a {
+ background-image: url(../../images/up.png);
+}
+#link__wiz_result div.type_f a {
+ background-image: url(../../images/page.png);
+}
+#link__wiz_result div.type_d a {
+ background-image: url(../../images/ns.png);
+}
+
+#link__wiz_result div.even {
+ background-color: @ini_background_neu;
+}
+
+#link__wiz_result div.selected {
+ background-color: @ini_background_alt;
+}
+
+#link__wiz_result span {
+ display: block;
+ color: @ini_text_neu;
+ margin-left: 22px;
+}
+
+
+/* media option wizard (opens when inserting media in the media popup)
+********************************************************************/
+
+#media__popup {
+ /* for backwards compatibility (not needed since Rincewind) */
+ display: none;
+}
+
+#media__popup_content p {
+ margin: 0 0 .5em;
+}
+
+#media__popup_content label {
+ margin-right: .5em;
+ cursor: default;
+}
+
+#media__popup_content button {
+ margin-right: 1px;
+ cursor: pointer;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_recent.css b/platform/www/lib/tpl/dokuwiki/css/_recent.css
new file mode 100644
index 0000000..f1be15f
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_recent.css
@@ -0,0 +1,75 @@
+/**
+ * This file provides styles for the recent changes (?do=recent) and
+ * old revisions (?do=revisions).
+ */
+
+/*____________ list of revisions / recent changes ____________*/
+
+/* select type of revisions (media/pages) */
+.dokuwiki .changeType {
+ margin-bottom: .5em;
+}
+
+.dokuwiki form.changes ul li {
+ list-style: none;
+ margin-left: 0;
+}
+[dir=rtl] .dokuwiki form.changes ul li {
+ margin-right: 0;
+}
+.dokuwiki form.changes ul li span,
+.dokuwiki form.changes ul li a {
+ vertical-align: middle;
+}
+.dokuwiki form.changes ul li span.user a {
+ vertical-align: bottom;
+}
+.dokuwiki form.changes ul li.minor {
+ opacity: .7;
+}
+
+.dokuwiki form.changes li span.date {
+}
+.dokuwiki form.changes li a.diff_link {
+ vertical-align: baseline;
+}
+.dokuwiki form.changes li a.revisions_link {
+ vertical-align: baseline;
+}
+.dokuwiki form.changes li a.wikilink1,
+.dokuwiki form.changes li a.wikilink2 {
+}
+.dokuwiki form.changes li span.sum {
+ font-weight: bold;
+}
+.dokuwiki form.changes li span.user {
+}
+
+/*____________ size differences ____________*/
+
+.dokuwiki form.changes li .sizechange {
+ font-size: 80%;
+ border-radius: .2em;
+ padding: .1em .2em;
+ /* cannot use non-guaranteed style.ini colour placeholders, dark templates need to overwrite */
+ background-color: #ddd;
+}
+
+.dokuwiki form.changes li .sizechange.positive {
+ background-color: #cfc;;
+}
+.dokuwiki form.changes li .sizechange.negative {
+ background-color: #fdd;
+}
+
+/*____________ page navigator ____________*/
+
+.dokuwiki div.pagenav {
+ text-align: center;
+ margin: 1.4em 0;
+}
+.dokuwiki div.pagenav-prev,
+.dokuwiki div.pagenav-next {
+ display: inline;
+ margin: 0 .5em;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_search.less b/platform/www/lib/tpl/dokuwiki/css/_search.less
new file mode 100644
index 0000000..59400f9
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_search.less
@@ -0,0 +1,204 @@
+/**
+ * This file provides styles for the search results page (?do=search)
+ * and the AJAX search popup.
+ */
+
+/* general
+********************************************************************/
+
+/* search hit in normal text */
+.dokuwiki .search_hit {
+ color: @ini_text;
+ background-color: __highlight__;
+}
+
+/* "nothing found" at search + media */
+.dokuwiki div.nothing {
+ margin-bottom: 1.4em;
+}
+
+/* search results page
+********************************************************************/
+
+/*____________ advanced search form ____________*/
+.dokuwiki .search-results-form fieldset.search-form {
+ width: 100%;
+ margin: 1em 0;
+
+ input[name="q"] {
+ width: 50%;
+ }
+
+ button.toggleAssistant {
+ float: right;
+ }
+
+ .advancedOptions {
+ padding: 1em 0;
+
+ > div {
+ display: inline-block;
+ position: relative;
+ margin: 0 0.5em;
+ }
+
+ div.toggle {
+ // default closed toggle state
+ div.current {
+ cursor: pointer;
+ max-width: 10em;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ &::after {
+ content: 'â–¼';
+ font-size: smaller;
+ color: @ini_text_alt;
+ }
+ }
+ div.changed {
+ font-weight: bold;
+ }
+ ul {
+ display: none;
+ position: absolute;
+ border: 1px solid @ini_border;
+ background-color: @ini_background;
+ padding: 0.25em 0.5em;
+ text-align: left;
+ min-width: 10em;
+ max-width: 15em;
+ max-height: 50vh;
+ overflow: auto;
+ z-index: 100;
+ li {
+ margin: 0.25em 0;
+ list-style: none;
+
+ a {
+ display: block;
+ }
+ }
+ }
+
+ // open toggle state
+ &.open {
+ div.current::after {
+ content: 'â–²';
+ }
+
+ ul {
+ display: block;
+ }
+ }
+ }
+ }
+}
+
+[dir=rtl] .search-results-form fieldset.search-form .advancedOptions {
+ div.toggle ul {
+ text-align: right;
+ }
+}
+
+
+/*____________ matching pagenames ____________*/
+
+.dokuwiki div.search_quickresult {
+ margin-bottom: 1.4em;
+
+ ul {
+ padding: 0;
+
+ li {
+ float: left;
+ width: 12em;
+ margin: 0 1.5em;
+ }
+ }
+}
+
+[dir=rtl] .dokuwiki div.search_quickresult ul li {
+ float: right;
+}
+
+/*____________ search results ____________*/
+
+.dokuwiki dl.search_results {
+ margin-bottom: 1.2em;
+
+ /* search heading */
+ dt {
+ font-weight: normal;
+ margin-bottom: .2em;
+ }
+
+ /* last modified line */
+ dd.meta {
+ margin: 0 0 .2em 0;
+ }
+
+ /* search snippet */
+ dd.snippet {
+ color: @ini_text_alt;
+ background-color: inherit;
+ margin: 0 0 1.2em 0;
+
+ /* search hit in search results */
+ strong.search_hit {
+ font-weight: normal;
+ /* color is set in general */
+ }
+
+ /* ellipsis separating snippets */
+ .search_sep {
+ color: @ini_text;
+ background-color: inherit;
+ }
+ }
+}
+
+/* AJAX quicksearch popup
+********************************************************************/
+
+.dokuwiki form.search {
+ div.no {
+ position: relative;
+ }
+
+ /* .JSpopup */
+ div.ajax_qsearch {
+ position: absolute;
+ top: 0;
+ left: -13.5em; /* -( width of #qsearch__in + padding of .ajax_qsearch + a bit more ) */
+ width: 12em;
+ padding: 0.5em;
+ font-size: .9em;
+ z-index: 20;
+ text-align: left;
+ display: none;
+
+ strong {
+ display: block;
+ margin-bottom: .3em;
+ }
+
+ ul {
+ margin: 0 !important;
+ padding: 0 !important;
+
+ li {
+ margin: 0;
+ padding: 0;
+ display: block !important;
+ }
+ }
+ }
+}
+
+[dir=rtl] .dokuwiki form.search div.ajax_qsearch {
+ left: auto;
+ right: -13.5em;
+ text-align: right;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_tabs.css b/platform/www/lib/tpl/dokuwiki/css/_tabs.css
new file mode 100644
index 0000000..507f49e
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_tabs.css
@@ -0,0 +1,84 @@
+/**
+ * This file provides the styles for general tabs.
+ */
+
+.dokuwiki .tabs > ul,
+.dokuwiki ul.tabs {
+ padding: 0;
+ margin: 0;
+ overflow: hidden;
+ position: relative;
+}
+/* border underneath */
+.dokuwiki .tabs > ul:after,
+.dokuwiki ul.tabs:after {
+ position: absolute;
+ content: "";
+ width: 100%;
+ bottom: 0;
+ left: 0;
+ border-bottom: 1px solid @ini_border;
+}
+
+.dokuwiki .tabs > ul li,
+.dokuwiki ul.tabs li {
+ float: left;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+[dir=rtl] .dokuwiki .tabs > ul li,
+[dir=rtl] .dokuwiki ul.tabs li {
+ float: right;
+}
+
+.dokuwiki .tabs > ul li a,
+.dokuwiki ul.tabs li strong,
+.dokuwiki ul.tabs li a {
+ display: inline-block;
+ padding: .3em .8em;
+ margin: 0 0 0 .3em;
+ background-color: @ini_background_neu;
+ color: @ini_text;
+ border: 1px solid @ini_border;
+ border-radius: .5em .5em 0 0;
+ position: relative;
+ z-index: 0;
+}
+[dir=rtl] .dokuwiki .tabs > ul li a,
+[dir=rtl] .dokuwiki ul.tabs li strong,
+[dir=rtl] .dokuwiki ul.tabs li a {
+ margin: 0 .3em 0 0;
+}
+
+.dokuwiki ul.tabs li strong {
+ font-weight: normal;
+}
+
+.dokuwiki ul.tabs li a:link,
+.dokuwiki ul.tabs li a:visited {
+}
+.dokuwiki .tabs > ul li a:hover,
+.dokuwiki .tabs > ul li a:active,
+.dokuwiki .tabs > ul li a:focus,
+.dokuwiki .tabs > ul li .curid a,
+.dokuwiki .tabs > ul .active a,
+.dokuwiki ul.tabs li a:hover,
+.dokuwiki ul.tabs li a:active,
+.dokuwiki ul.tabs li a:focus,
+.dokuwiki ul.tabs li.active a,
+.dokuwiki ul.tabs li strong {
+ background-color: @ini_background_alt;
+ color: @ini_text;
+ text-decoration: none;
+ font-weight: normal;
+}
+
+.dokuwiki .tabs > ul li .curid a,
+.dokuwiki .tabs > ul li .active a,
+.dokuwiki .tabs > ul li .active a,
+.dokuwiki ul.tabs li.active a,
+.dokuwiki ul.tabs li strong {
+ z-index: 2;
+ border-bottom-color: @ini_background_alt;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/_toc.css b/platform/www/lib/tpl/dokuwiki/css/_toc.css
new file mode 100644
index 0000000..469e927
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/_toc.css
@@ -0,0 +1,93 @@
+/**
+ * This file provides styles for the TOC (table of contents), the
+ * sitemap (?do=index) and backlinks (?do=backlink).
+ */
+
+/* toc
+********************************************************************/
+
+/* toc container */
+#dw__toc {
+ float: right;
+ margin: 0 0 1.4em 1.4em;
+ width: 12em;
+ background-color: @ini_background_alt;
+ color: inherit;
+}
+[dir=rtl] #dw__toc {
+ float: left;
+ margin: 0 1.4em 1.4em 0;
+}
+
+/*____________ toc header ____________*/
+
+.dokuwiki h3.toggle {
+ padding: .2em .5em;
+ font-weight: bold;
+}
+
+.dokuwiki .toggle strong {
+ float: right;
+ margin: 0 .2em;
+}
+[dir=rtl] .dokuwiki .toggle strong {
+ float: left;
+}
+
+/*____________ toc list ____________*/
+
+#dw__toc > div {
+ padding: .2em .5em;
+}
+#dw__toc ul {
+ padding: 0;
+ margin: 0;
+}
+#dw__toc ul li {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ line-height: 1.1;
+}
+#dw__toc ul li div.li {
+ padding: .15em 0;
+}
+#dw__toc ul ul {
+ padding-left: 1em;
+}
+[dir=rtl] #dw__toc ul ul {
+ padding-left: 0;
+ padding-right: 1em;
+}
+#dw__toc ul ul li {
+}
+#dw__toc ul li a {
+}
+
+/* in case of toc list jumping one level
+ (e.g. if heading level 3 follows directly after heading level 1) */
+#dw__toc ul li.clear {
+}
+
+
+/* sitemap (and backlinks)
+********************************************************************/
+
+.dokuwiki ul.idx {
+ padding-left: 0;
+}
+[dir=rtl] .dokuwiki ul.idx {
+ padding-right: 0;
+}
+.dokuwiki ul.idx li {
+ list-style-image: url(../../images/bullet.png);
+}
+.dokuwiki ul.idx li.open {
+ list-style-image: url(../../images/open.png);
+}
+.dokuwiki ul.idx li.closed {
+ list-style-image: url(../../images/closed.png);
+}
+[dir=rtl] .dokuwiki ul.idx li.closed {
+ list-style-image: url(../../images/closed-rtl.png);
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/basic.less b/platform/www/lib/tpl/dokuwiki/css/basic.less
new file mode 100644
index 0000000..abb330a
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/basic.less
@@ -0,0 +1,464 @@
+/**
+ * This file provides the most basic styles.
+ *
+ * If you integrate DokuWiki into another project, you might either
+ * want to integrate this file into the other project as well, or use
+ * the other project's basic CSS for DokuWiki instead of this one.
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+
+html {
+ overflow-x: auto;
+ overflow-y: scroll;
+}
+html,
+body {
+ color: @ini_text;
+ background: @ini_background_site url(images/page-gradient.png) top left repeat-x;
+ margin: 0;
+ padding: 0;
+}
+body {
+ font: normal 87.5%/1.4 Arial, sans-serif;
+ /* default font size: 100% => 16px; 93.75% => 15px; 87.5% => 14px; 81.25% => 13px; 75% => 12px */
+ -webkit-text-size-adjust: 100%;
+}
+
+
+/*____________ headers ____________*/
+
+caption,
+figcaption,
+summary,
+legend {
+ padding: 0;
+ margin: 0 0 .35em;
+ line-height: 1.2;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-weight: bold;
+ padding: 0;
+ line-height: 1.2;
+ clear: left; /* ideally 'both', but problems with toc */
+}
+[dir=rtl] h1,
+[dir=rtl] h2,
+[dir=rtl] h3,
+[dir=rtl] h4,
+[dir=rtl] h5,
+[dir=rtl] h6 {
+ clear: right;
+}
+
+h1 {
+ font-size: 2em;
+ margin: 0 0 0.444em;
+}
+h2 {
+ font-size: 1.5em;
+ margin: 0 0 0.666em;
+}
+h3 {
+ font-size: 1.125em;
+ margin: 0 0 0.888em;
+}
+h4 {
+ font-size: 1em;
+ margin: 0 0 1.0em;
+}
+h5 {
+ font-size: .875em;
+ margin: 0 0 1.1428em;
+}
+h6 {
+ font-size: .75em;
+ margin: 0 0 1.333em;
+}
+/* bottom margin = 1 / font-size */
+
+
+/*____________ basic margins and paddings ____________*/
+
+p,
+ul,
+ol,
+dl,
+pre,
+table,
+hr,
+blockquote,
+figure,
+details,
+fieldset,
+address {
+ margin: 0 0 1.4em 0; /* bottom margin = line-height */
+ padding: 0;
+}
+
+div,
+video,
+audio {
+ margin: 0;
+ padding: 0;
+}
+
+
+/*____________ lists ____________*/
+
+ul,
+ol {
+ padding: 0 0 0 1.5em;
+}
+[dir=rtl] ul,
+[dir=rtl] ol {
+ padding: 0 1.5em 0 0;
+}
+
+li,
+dd {
+ padding: 0;
+ margin: 0 0 0 1.5em;
+}
+[dir=rtl] li,
+[dir=rtl] dd {
+ margin: 0 1.5em 0 0;
+}
+dt {
+ font-weight: bold;
+ margin: 0;
+ padding: 0;
+}
+
+li ul,
+li ol,
+li dl,
+dl ul,
+dl ol,
+dl dl {
+ margin-bottom: 0;
+ padding: 0;
+}
+li li {
+ font-size: 100%;
+}
+
+ul { list-style: square outside; }
+ol { list-style: decimal outside; }
+ol ol { list-style-type: lower-alpha; }
+ol ol ol { list-style-type: upper-roman; }
+ol ol ol ol { list-style-type: upper-alpha; }
+ol ol ol ol ol { list-style-type: lower-roman; }
+
+
+/*____________ tables ____________*/
+
+table {
+ border-collapse: collapse;
+ empty-cells: show;
+ border-spacing: 0;
+ border: 1px solid @ini_border;
+}
+
+caption {
+ caption-side: top;
+ text-align: left;
+}
+[dir=rtl] caption {
+ text-align: right;
+}
+
+th,
+td {
+ padding: .3em .5em;
+ margin: 0;
+ vertical-align: top;
+ border: 1px solid @ini_border;
+}
+th {
+ font-weight: bold;
+ background-color: @ini_background_alt;
+ text-align: left;
+}
+[dir=rtl] th {
+ text-align: right;
+}
+
+
+/*____________ links ____________*/
+
+a {
+ outline: none;
+}
+a:link,
+a:visited {
+ text-decoration: none;
+ color: @ini_link;
+}
+a:link:hover,
+a:visited:hover,
+a:link:focus,
+a:visited:focus,
+a:link:active,
+a:visited:active {
+ text-decoration: underline;
+}
+
+
+/*____________ misc ____________*/
+
+img {
+ border-width: 0;
+ vertical-align: middle;
+ color: #666;
+ background-color: transparent;
+ font-style: italic;
+ height: auto;
+}
+video {
+ height: auto;
+}
+img,
+object,
+embed,
+iframe,
+video,
+audio {
+ max-width: 100%;
+}
+button img {
+ max-width: none;
+}
+
+hr {
+ border-top: solid @ini_border;
+ border-bottom: solid @ini_background;
+ border-width: 1px 0;
+ height: 0;
+ text-align: center;
+ clear: both;
+}
+
+acronym,
+abbr {
+ cursor: help;
+ border-bottom: 1px dotted;
+ font-style: normal;
+}
+em acronym,
+em abbr {
+ font-style: italic;
+}
+
+mark {
+ background-color: @ini_highlight;
+ color: inherit;
+}
+
+pre,
+code,
+samp,
+kbd {
+ font-family: Consolas, "Andale Mono WT", "Andale Mono", "Bitstream Vera Sans Mono", "Nimbus Mono L", Monaco, "Courier New", monospace;
+ /* same font stack should be used for ".dokuwiki table.diff td" in _diff.css */
+ font-size: 1em;
+ direction: ltr;
+ text-align: left;
+ background-color: @ini_background_site;
+ color: @ini_text;
+ box-shadow: inset 0 0 .3em @ini_border;
+ border-radius: 2px;
+}
+pre {
+ overflow: auto;
+ word-wrap: normal;
+ border: 1px solid @ini_border;
+ border-radius: 2px;
+ box-shadow: inset 0 0 .5em @ini_border;
+ padding: .7em 1em;
+}
+
+blockquote {
+ padding: 0 .5em;
+ border: solid @ini_border;
+ border-width: 0 0 0 .25em;
+}
+[dir=rtl] blockquote {
+ border-width: 0 .25em 0 0;
+}
+q:before,
+q:after {
+ content: '';
+}
+
+sub,
+sup {
+ font-size: .8em;
+ line-height: 1;
+}
+sub {
+ vertical-align: sub;
+}
+sup {
+ vertical-align: super;
+}
+
+small {
+ font-size: .8em;
+}
+
+wbr {
+ display: inline-block; /* for IE 11 */
+}
+
+/*____________ forms ____________*/
+
+/* for all of the form styles, style.ini colours are not used on purpose (except for fieldset border) */
+
+form {
+ display: inline;
+ margin: 0;
+ padding: 0;
+}
+fieldset {
+ padding: .7em 1em 0;
+ padding: .7rem 1rem; /* for those browsers understanding :last-child */
+ border: 1px solid @ini_text_alt;
+}
+fieldset > :last-child {
+ margin-bottom: 0;
+}
+legend {
+ margin: 0;
+ padding: 0 .1em;
+}
+label {
+ vertical-align: middle;
+ cursor: pointer;
+}
+
+input,
+textarea,
+button,
+select,
+optgroup,
+option,
+keygen,
+output,
+meter,
+progress {
+ font: inherit;
+ font-weight: normal;
+ color: #333;
+ background-color: #fff;
+ line-height: normal;
+ margin: 0;
+ vertical-align: middle;
+ box-sizing: border-box;
+}
+
+select {
+ max-width: 100%;
+}
+optgroup {
+ font-style: italic;
+ font-weight: bold;
+}
+option {
+ font-style: normal;
+ font-weight: normal;
+}
+
+input,
+textarea,
+select,
+keygen {
+ border: 1px solid #ccc;
+ box-shadow: inset 0 0 1px #eee;
+ border-radius: 2px;
+}
+input:active,
+input:focus,
+textarea:active,
+textarea:focus,
+select:active,
+select:focus,
+keygen:active,
+keygen:focus {
+ border-color: #999;
+}
+input[type=radio],
+input[type=checkbox],
+input[type=image] {
+ padding: 0;
+ border-style: none;
+ box-shadow: none;
+}
+
+/* all types of buttons */
+input[type=submit],
+input[type=button],
+input[type=reset],
+input.button,
+a.button,
+button,
+.qq-upload-button {
+ color: #333;
+ background-color: #eee;
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPgo8bGluZWFyR3JhZGllbnQgaWQ9Imc4MjQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkZGRkYiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNGNEY0RjQiIG9mZnNldD0iMC4zIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0VFRUVFRSIgb2Zmc2V0PSIwLjk5Ii8+PHN0b3Agc3RvcC1jb2xvcj0iI0NDQ0NDQyIgb2Zmc2V0PSIuOTkiLz4KPC9saW5lYXJHcmFkaWVudD4KPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNnODI0KSIgLz4KPC9zdmc+);
+ background-image: linear-gradient(to bottom, #ffffff 0%, #f4f4f4 30%, #eeeeee 99%, #cccccc 99%);
+ border: 1px solid #ccc;
+ border-radius: 2px;
+ padding: .1em .5em;
+ cursor: pointer;
+}
+
+input[type=submit]:hover,
+input[type=submit]:active,
+input[type=submit]:focus,
+input[type=button]:hover,
+input[type=button]:active,
+input[type=button]:hover,
+input[type=reset]:hover,
+input[type=reset]:active,
+input[type=reset]:hover,
+input.button:hover,
+input.button:active,
+input.button:focus,
+a.button:hover,
+a.button:active,
+a.button:focus,
+button:hover,
+button:active,
+button:focus,
+.qq-upload-button:hover {
+ border-color: #999;
+ background-color: #ddd;
+ background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIHZpZXdCb3g9IjAgMCAxIDEiIHByZXNlcnZlQXNwZWN0UmF0aW89Im5vbmUiPgo8bGluZWFyR3JhZGllbnQgaWQ9Imc2NzAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMCUiIHkxPSIwJSIgeDI9IjAlIiB5Mj0iMTAwJSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkZGRkYiIG9mZnNldD0iMCIvPjxzdG9wIHN0b3AtY29sb3I9IiNGNEY0RjQiIG9mZnNldD0iMC4zIi8+PHN0b3Agc3RvcC1jb2xvcj0iI0RERERERCIgb2Zmc2V0PSIwLjk5Ii8+PHN0b3Agc3RvcC1jb2xvcj0iI0JCQkJCQiIgb2Zmc2V0PSIuOTkiLz4KPC9saW5lYXJHcmFkaWVudD4KPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNnNjcwKSIgLz4KPC9zdmc+);
+ background-image: linear-gradient(to bottom, #ffffff 0%, #f4f4f4 30%, #dddddd 99%, #bbbbbb 99%);
+}
+
+input::-moz-focus-inner,
+button::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+
+input[disabled],
+button[disabled],
+select[disabled],
+textarea[disabled],
+option[disabled],
+input[readonly],
+button[readonly],
+select[readonly],
+textarea[readonly] {
+ cursor: auto;
+ opacity: .5;
+ background-color: #eee;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/content.less b/platform/www/lib/tpl/dokuwiki/css/content.less
new file mode 100644
index 0000000..d300393
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/content.less
@@ -0,0 +1,393 @@
+/**
+ * This file provides the main design styles for the page content.
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Clarence Lee <clarencedglee@gmail.com>
+ */
+
+/*____________ section indenting ____________
+
+.dokuwiki .page h1 {margin-left: 0;}
+.dokuwiki .page h2 {margin-left: .666em;}
+.dokuwiki .page h3 {margin-left: 1.776em;}
+.dokuwiki .page h4 {margin-left: 3em;}
+.dokuwiki .page h5 {margin-left: 4.5712em;}
+.dokuwiki .page div.level1 {margin-left: 0;}
+.dokuwiki .page div.level2 {margin-left: 1em;}
+.dokuwiki .page div.level3 {margin-left: 2em;}
+.dokuwiki .page div.level4 {margin-left: 3em;}
+.dokuwiki .page div.level5 {margin-left: 4em;}
+
+[dir=rtl] .dokuwiki .page h1 {margin-left: 0; margin-right: 0;}
+[dir=rtl] .dokuwiki .page h2 {margin-left: 0; margin-right: .666em;}
+[dir=rtl] .dokuwiki .page h3 {margin-left: 0; margin-right: 1.776em;}
+[dir=rtl] .dokuwiki .page h4 {margin-left: 0; margin-right: 3em;}
+[dir=rtl] .dokuwiki .page h5 {margin-left: 0; margin-right: 4.5712em;}
+[dir=rtl] .dokuwiki .page div.level1 {margin-left: 0; margin-right: 0;}
+[dir=rtl] .dokuwiki .page div.level2 {margin-left: 0; margin-right: 1em;}
+[dir=rtl] .dokuwiki .page div.level3 {margin-left: 0; margin-right: 2em;}
+[dir=rtl] .dokuwiki .page div.level4 {margin-left: 0; margin-right: 3em;}
+[dir=rtl] .dokuwiki .page div.level5 {margin-left: 0; margin-right: 4em;}
+*/
+/* hx margin-left = (1 / font-size) * .levelx-margin */
+
+/*____________ links to wiki pages (addition to _links) ____________*/
+
+/* existing wikipage */
+.dokuwiki a.wikilink1 {
+ color: @ini_existing;
+ background-color: inherit;
+}
+
+/* not existing wikipage */
+.dokuwiki a.wikilink2 {
+ color: @ini_missing;
+ background-color: inherit;
+}
+
+/*____________ images ____________*/
+
+/* embedded images (styles are already partly set in lib/styles/all.css) */
+.dokuwiki img.media {
+ margin: .2em 0;
+}
+
+.dokuwiki img.medialeft {
+ margin: .2em 1em .2em 0;
+}
+
+.dokuwiki img.mediaright {
+ margin: .2em 0 .2em 1em;
+}
+
+.dokuwiki img.mediacenter {
+ margin: .2em auto;
+}
+
+/*____________ lists ____________*/
+
+.dokuwiki .page,
+.dokuwiki .aside {
+ ul li {
+ color: @ini_text_alt;
+ }
+
+ ol li {
+ color: @ini_text_neu;
+ }
+
+ li .li {
+ color: @ini_text;
+ }
+}
+
+/*____________ tables ____________*/
+
+/* div around each table */
+.dokuwiki div.table {
+ overflow-x: auto;
+ margin-bottom: 1.4em;
+}
+
+.dokuwiki div.table table {
+ margin-bottom: 0;
+}
+
+.dokuwiki table.inline {
+ min-width: 50%;
+}
+
+.dokuwiki table.inline tr:hover td {
+ background-color: @ini_background_alt;
+}
+
+.dokuwiki table.inline tr:hover th {
+ background-color: @ini_border;
+}
+
+/*____________ code ____________*/
+
+/* fix if background-color hides underlining */
+.dokuwiki em.u code {
+ text-decoration: underline;
+}
+
+/* filenames for downloadable file and code blocks */
+.dokuwiki dl.code,
+.dokuwiki dl.file {
+ dt {
+ background-color: @ini_background_site;
+ background: linear-gradient(to bottom, @ini_background_alt 0%, @ini_background_site 100%);
+ color: inherit;
+ border: 1px solid @ini_border;
+ border-bottom-color: @ini_background_site;
+ border-top-left-radius: .3em;
+ border-top-right-radius: .3em;
+ padding: .3em .6em .1em;
+ margin-bottom: -1px;
+ float: left;
+
+ a {
+ background-color: transparent;
+ font-size: 0.875em;
+ font-weight: normal;
+ display: block;
+ min-height: 16px;
+ }
+ }
+
+ dd {
+ margin: 0;
+ clear: left;
+ }
+
+ pre {
+ box-shadow: inset -4px -4px .5em -.3em @ini_border;
+ }
+}
+
+[dir=rtl] .dokuwiki dl.code,
+[dir=rtl] .dokuwiki dl.file {
+ dt {
+ float: right;
+ }
+
+ dd {
+ clear: right;
+ }
+}
+
+/* for code in <file> */
+.dokuwiki dl.file {
+ pre,
+ dt {
+ border-style: dashed;
+ }
+ dt {
+ border-bottom-style: solid;
+ }
+}
+
+/*____________ JS popup ____________*/
+
+.JSpopup {
+ background-color: @ini_background;
+ color: @ini_text;
+ border: 1px solid @ini_border;
+ box-shadow: .1em .1em .1em @ini_border;
+ border-radius: 2px;
+ padding: .3em .5em;
+ font-size: .9em;
+}
+
+.dokuwiki form.search div.ajax_qsearch {
+ top: -.35em;
+ font-size: 1em;
+ text-overflow: ellipsis;
+}
+
+.JSpopup ul,
+.JSpopup ol {
+ padding-left: 0;
+}
+
+[dir=rtl] .JSpopup ul,
+[dir=rtl] .JSpopup ol {
+ padding-right: 0;
+}
+
+/* changes to underscored CSS files
+********************************************************************/
+
+#acl__tree li {
+ margin: 0;
+}
+
+#dokuwiki__content span.curid a {
+ font-weight: normal;
+}
+
+#dokuwiki__content strong span.curid a {
+ font-weight: bold;
+}
+
+/*____________ changes to _edit ____________*/
+
+.dokuwiki div.toolbar {
+ button.toolbutton {
+ border-radius: 0;
+ border-left-width: 0;
+ padding: .1em .35em;
+ }
+
+ button.toolbutton:first-child {
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ border-left-width: 1px;
+ }
+
+ button.toolbutton:last-child {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ }
+}
+
+[dir=rtl] .dokuwiki div.toolbar {
+ button.toolbutton:last-child {
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border-left-width: 1px;
+ }
+
+ button.toolbutton:first-child {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ border-left-width: 0;
+ border-right-width: 1px;
+ }
+}
+
+.dokuwiki div.section_highlight {
+ margin: 0 -2em;
+ padding: 0 1em;
+ border-width: 0 1em;
+}
+
+.dokuwiki textarea.edit {
+ font-family: Consolas, "Andale Mono WT", "Andale Mono", "Bitstream Vera Sans Mono", "Nimbus Mono L", Monaco, "Courier New", monospace;
+}
+
+.dokuwiki div.preview {
+ margin: 0 -2em;
+ padding: 0 2em;
+}
+
+.dokuwiki.hasSidebar div.preview {
+ border-right: @ini_sidebar_width solid @ini_background_alt;
+}
+
+[dir=rtl] .dokuwiki.hasSidebar div.preview {
+ border-right-width: 0;
+ border-left: @ini_sidebar_width solid @ini_background_alt;
+}
+
+.dokuwiki div.preview div.pad {
+ padding: 1.556em 0 2em;
+}
+
+/*____________ changes to _toc ____________*/
+
+#dw__toc {
+ margin: -1.556em -2em .5em 1.4em;
+ width: @ini_sidebar_width;
+ border-left: 1px solid @ini_border;
+ background: @ini_background;
+ color: inherit;
+}
+
+[dir=rtl] #dw__toc {
+ margin: -1.556em 1.4em .5em -2em;
+ border-left-width: 0;
+ border-right: 1px solid @ini_border;
+}
+
+.dokuwiki h3.toggle {
+ padding: .5em 1em;
+ margin-bottom: 0;
+ font-size: .875em;
+ letter-spacing: .1em;
+}
+
+#dokuwiki__aside h3.toggle {
+ display: none;
+}
+
+.dokuwiki .toggle strong {
+ background: transparent url(images/toc-arrows.png) 0 0;
+ width: 8px;
+ height: 5px;
+ margin: .4em 0 0;
+}
+
+.dokuwiki .toggle.closed strong {
+ background-position: 0 -5px;
+}
+
+.dokuwiki .toggle strong span {
+ display: none;
+}
+
+#dw__toc {
+ > div {
+ font-size: 0.875em;
+ padding: .5em 1em 1em;
+ }
+
+ ul {
+ padding: 0 0 0 1.2em;
+
+ li {
+ list-style-image: url(images/toc-bullet.png);
+ }
+ }
+
+ ul li.clear {
+ list-style: none;
+ }
+
+ ul li div.li {
+ padding: .2em 0;
+ }
+}
+
+[dir=rtl] #dw__toc ul {
+ padding: 0 1.5em 0 0;
+}
+
+/*____________ changes to _imgdetail ____________*/
+
+#dokuwiki__detail {
+ padding: 0;
+
+ img {
+ float: none;
+ margin-bottom: 1.4em;
+ }
+
+ div.img_detail {
+ float: none;
+ }
+
+ div.img_detail dl {
+ overflow: hidden;
+ }
+
+ div.img_detail dl dt {
+ float: left;
+ width: 9em;
+ text-align: right;
+ clear: left;
+ }
+
+ div.img_detail dl dd {
+ margin-left: 9.5em;
+ }
+}
+
+[dir=rtl] #dokuwiki__detail div.img_detail {
+ dl dt {
+ float: right;
+ text-align: left;
+ clear: right;
+ }
+
+ dl dd {
+ margin-left: 0;
+ margin-right: 9.5em;
+ }
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/design.less b/platform/www/lib/tpl/dokuwiki/css/design.less
new file mode 100644
index 0000000..86315d2
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/design.less
@@ -0,0 +1,354 @@
+/**
+ * This file provides the main design styles for the
+ * bits that surround the content.
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Clarence Lee <clarencedglee@gmail.com>
+ */
+
+/* header
+********************************************************************/
+
+#dokuwiki__header {
+ padding: 2em 0 1.5em;
+
+ .headings,
+ .tools {
+ margin-bottom: 1.5em;
+ width: 49%;
+ }
+ .tools {
+ margin-top: .2em;
+ }
+
+ h1 {
+ margin: 0;
+ font-size: 1.5em;
+ font-weight: normal;
+
+ img {
+ float: left;
+ margin-right: .5em;
+ }
+
+ span {
+ display: block;
+ padding-top: 10px;
+ }
+
+ a {
+ text-decoration: none;
+ color: @ini_text;
+ background-color: inherit;
+ }
+ }
+
+ p.claim {
+ margin-bottom: 0;
+ font-size: 0.875em;
+ }
+
+ /* make all links in header (including breadcrumb and interwiki) same colour as the rest */
+ a {
+ color: @ini_link;
+ background-color: inherit;
+ }
+}
+
+[dir=rtl] #dokuwiki__header h1 img {
+ float: right;
+ margin-left: .5em;
+ margin-right: 0;
+}
+
+/* tools
+********************************************************************/
+
+/* highlight selected tool */
+.mode_admin .action.admin a,
+.mode_login .action.login a,
+.mode_register .action.register a,
+.mode_profile .action.profile a,
+.mode_recent .action.recent a,
+.mode_index .action.index a,
+.mode_media .action.media a,
+.mode_revisions .action.revs a,
+.mode_backlink .action.backlink a,
+.mode_subscribe .action.subscribe a {
+ font-weight: bold;
+}
+
+#dokuwiki__header .tools {
+ ul {
+ padding-left: 0;
+ margin-bottom: 0;
+ }
+
+ li {
+ font-size: 0.875em;
+ margin-left: 1em;
+ list-style: none;
+ display: inline;
+ }
+
+ form.search div.ajax_qsearch li {
+ font-size: 1em;
+ margin-left: 0;
+ display: block;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+}
+
+[dir=rtl] #dokuwiki__header .tools li {
+ margin-right: 1em;
+ margin-left: 0;
+}
+
+#dokuwiki__header .mobileTools {
+ display: none; /* hide mobile tools dropdown to only show in mobile view */
+}
+
+/*____________ site tools ____________*/
+
+#dokuwiki__sitetools {
+ text-align: right;
+
+ form.search {
+ font-size: 0.875em;
+ }
+}
+
+[dir=rtl] #dokuwiki__sitetools {
+ text-align: left;
+}
+
+form.search {
+ display: block;
+ position: relative;
+ margin-bottom: 0.5em;
+
+ input {
+ width: 18em;
+ padding: .35em 22px .35em .1em;
+ }
+
+ button {
+ background: transparent url(images/search.png) no-repeat 0 0;
+ border-width: 0;
+ width: 19px;
+ height: 14px;
+ text-indent: -99999px;
+ margin-left: -20px;
+ box-shadow: none;
+ padding: 0;
+ }
+}
+
+[dir=rtl] form.search {
+ input {
+ padding: .35em .1em .35em 22px;
+ }
+
+ button {
+ background-position: 5px 0;
+ margin-left: 0;
+ margin-right: -20px;
+ position: relative;
+ }
+}
+
+/*____________ breadcrumbs ____________*/
+
+.dokuwiki div.breadcrumbs {
+ border-top: 1px solid @ini_border;
+ border-bottom: 1px solid @ini_background;
+ margin-bottom: .5em;
+ font-size: 0.875em;
+ clear: both;
+
+ div {
+ padding: .1em .35em;
+ }
+
+ div:only-child {
+ border-top: 1px solid @ini_background;
+ border-bottom: 1px solid @ini_border;
+ }
+
+ div:first-child {
+ border-top: 1px solid @ini_background;
+ }
+
+ div:last-child {
+ border-bottom: 1px solid @ini_border;
+ }
+
+ .bcsep {
+ font-size: 0.75em;
+ }
+}
+
+/* sidebar
+********************************************************************/
+
+.dokuwiki .aside {
+ font-size: 0.875em;
+ overflow: hidden;
+ word-wrap: break-word;
+
+ /* make sidebar more condensed */
+
+ h1 {
+ font-size: 1.714em;
+ margin-bottom: .292em;
+ }
+
+ h2 {
+ margin-bottom: .333em;
+ }
+
+ h3 {
+ margin-bottom: .444em;
+ }
+
+ h4 {
+ margin-bottom: .5em;
+ }
+
+ h5 {
+ margin-bottom: .5714em;
+ }
+
+ p,
+ ul,
+ ol,
+ dl,
+ pre,
+ table,
+ fieldset,
+ hr,
+ blockquote,
+ address {
+ margin-bottom: .7em;
+ }
+
+ ul,
+ ol {
+ padding-left: .5em;
+ }
+
+ li ul,
+ li ol {
+ margin-bottom: 0;
+ padding: 0;
+ }
+
+ a:link,
+ a:visited {
+ color: @ini_link;
+ background-color: inherit;
+ }
+}
+
+[dir=rtl] .dokuwiki .aside ul,
+[dir=rtl] .dokuwiki .aside ol {
+ padding-right: .5em;
+}
+
+/* content
+********************************************************************/
+
+.dokuwiki .pageId {
+ float: right;
+ margin-right: -1em;
+ margin-bottom: -1px;
+ margin-top: -1.5em;
+ overflow: hidden;
+ padding: 0.5em 1em 0;
+
+ span {
+ font-size: 0.875em;
+ border: solid @ini_background_alt;
+ border-width: 1px 1px 0;
+ background-color: @ini_background;
+ color: @ini_text_alt;
+ padding: .1em .35em;
+ border-top-left-radius: 2px;
+ border-top-right-radius: 2px;
+ box-shadow: 0 0 .5em @ini_text_alt;
+ display: block;
+ }
+}
+
+.dokuwiki div.page {
+ clear: both;
+ background: @ini_background;
+ color: inherit;
+ border: 1px solid @ini_background_alt;
+ box-shadow: 0 0 .5em @ini_text_alt;
+ border-radius: 2px;
+ padding: 1.556em 2em 2em;
+ margin-bottom: .5em;
+ overflow: hidden;
+ word-wrap: break-word;
+}
+
+.dokuwiki .docInfo {
+ font-size: 0.875em;
+ text-align: right;
+}
+
+/* license note under edit window */
+.dokuwiki div.license {
+ font-size: 93.75%;
+}
+
+[dir=rtl] .dokuwiki .docInfo {
+ text-align: left;
+}
+
+[dir=rtl] .dokuwiki .pageId {
+ float: left;
+ margin-left: -1em;
+ margin-right: 0;
+}
+
+/* footer
+********************************************************************/
+
+.dokuwiki .wrapper {
+ margin-bottom: 1.4em;
+}
+
+#dokuwiki__footer {
+ margin-bottom: 1em;
+ text-align: center;
+
+ > .pad {
+ font-size: 0.875em;
+ }
+
+ div.license {
+ margin-bottom: 0.5em;
+ font-size: 100%;
+ }
+
+ div.buttons a {
+ img {
+ opacity: 0.5;
+ }
+
+ &:hover img,
+ &:active img,
+ &:focus img {
+ opacity: 1;
+ }
+ }
+
+}
+
+[dir=rtl] #dokuwiki__footer .license img {
+ margin: 0 0 0 .5em;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/mobile.less b/platform/www/lib/tpl/dokuwiki/css/mobile.less
new file mode 100644
index 0000000..a52c723
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/mobile.less
@@ -0,0 +1,332 @@
+/**
+ * This file provides styles for mobile devices
+ * and smaller screens (up to 480px and 768px width).
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+
+/* for detecting media queries in JavaScript (see script.js): */
+#screen__mode {
+ position: relative;
+ z-index: 0;
+}
+
+/* for screen widths in the tablet range
+********************************************************************/
+@media only screen and (max-width: @ini_tablet_width) {
+
+#screen__mode {
+ z-index: 1; /* for detecting media queries in JavaScript (see script.js) */
+}
+
+/* structure */
+#dokuwiki__aside {
+ width: 100%;
+ float: none;
+ margin-bottom: 1.5em;
+}
+
+#dokuwiki__aside > .pad,
+[dir=rtl] #dokuwiki__aside > .pad {
+ margin: 0 0 .5em;
+ /* style like .page */
+ background: @ini_background;
+ color: inherit;
+ border: 1px solid #eee;
+ box-shadow: 0 0 .5em @ini_text_alt;
+ border-radius: 2px;
+ padding: 1em;
+ margin-bottom: .5em;
+}
+
+#dokuwiki__aside h3.toggle {
+ font-size: 1em;
+
+ &.closed {
+ margin-bottom: 0;
+ padding-bottom: 0;
+ }
+ &.open {
+ border-bottom: 1px solid @ini_border;
+ }
+}
+
+.showSidebar #dokuwiki__content {
+ float: none;
+ margin-left: 0;
+ width: 100%;
+
+ > .pad {
+ margin-left: 0;
+ }
+}
+
+[dir=rtl] .showSidebar #dokuwiki__content,
+[dir=rtl] .showSidebar #dokuwiki__content > .pad {
+ margin-right: 0;
+}
+
+/* preview */
+.dokuwiki.hasSidebar div.preview {
+ border-right: none;
+}
+
+[dir=rtl] .dokuwiki.hasSidebar div.preview {
+ border-left: none;
+}
+
+/* toc */
+#dw__toc {
+ float: none;
+ margin: 0 0 1em 0;
+ width: auto;
+ border-left-width: 0;
+ border-bottom: 1px solid @ini_border;
+}
+[dir=rtl] #dw__toc {
+ float: none;
+ margin: 0 0 1em 0;
+ border-right-width: 0;
+}
+
+.dokuwiki h3.toggle {
+ padding: 0 .5em .5em 0;
+}
+#dw__toc > div,
+#dokuwiki__aside div.content {
+ padding: .2em 0 .5em;
+}
+
+/* page */
+.dokuwiki div.page {
+ padding: 1em;
+}
+/* enable horizontal scrolling in media manager */
+.mode_media div.page {
+ overflow: auto;
+}
+
+/* push pagetools closer to content */
+#dokuwiki__pagetools {
+ top: 0;
+}
+.showSidebar #dokuwiki__pagetools {
+ top: 3.5em;
+}
+
+
+/* _edit */
+.dokuwiki div.section_highlight {
+ margin: 0 -1em;
+ padding: 0 .5em;
+ border-width: 0 .5em;
+}
+.dokuwiki div.preview {
+ margin: 0 -1em;
+ padding: 1em;
+}
+
+/* _recent */
+.dokuwiki form.changes ul {
+ padding-left: 0;
+}
+[dir=rtl] .dokuwiki form.changes ul {
+ padding-right: 0;
+}
+
+
+} /* /@media */
+
+
+/* for screen widths in the smartphone range
+********************************************************************/
+@media only screen and (max-width: @ini_phone_width) {
+
+#screen__mode {
+ z-index: 2; /* for detecting media queries in JavaScript (see script.js) */
+}
+
+body {
+ font-size: 100%;
+}
+
+/*____________ structure ____________*/
+
+#dokuwiki__site {
+ max-width: 100%;
+
+ > .site {
+ padding: 0 .5em;
+ }
+}
+
+#dokuwiki__aside {
+ margin-bottom: 0;
+}
+
+#dokuwiki__header {
+ padding: .5em 0;
+}
+
+
+/*____________ header ____________*/
+
+#dokuwiki__header ul.a11y.skip {
+ position: static !important;
+ left: 0 !important;
+ width: auto !important;
+ height: auto !important;
+ float: right;
+ font-size: 0.875em;
+ list-style: none;
+ padding-left: 0;
+ margin: 0;
+
+ li {
+ margin-left: .35em;
+ display: inline;
+ }
+}
+[dir=rtl] #dokuwiki__header ul.a11y.skip {
+ left: auto !important;
+ right: 0 !important;
+ float: left;
+ padding-right: 0;
+
+ li {
+ margin: 0 .35em 0 0;
+ }
+}
+
+#dokuwiki__header .headings,
+#dokuwiki__header .tools {
+ float: none;
+ text-align: left;
+ width: auto;
+ margin-bottom: .5em;
+}
+[dir=rtl] #dokuwiki__header .headings,
+[dir=rtl] #dokuwiki__header .tools {
+ float: none;
+ text-align: right;
+ width: auto;
+}
+#dokuwiki__sitetools {
+ text-align: left;
+}
+[dir=rtl] #dokuwiki__sitetools {
+ text-align: right;
+}
+#dokuwiki__usertools,
+#dokuwiki__sitetools ul,
+#dokuwiki__sitetools h3,
+#dokuwiki__pagetools,
+.dokuwiki div.breadcrumbs, /* @todo: maybe move breadcrumbs to the bottom? */
+.dokuwiki .pageId {
+ display: none;
+}
+
+/* search form */
+#dokuwiki__sitetools form.search {
+ float: left;
+ margin: 0 .2em .2em 0;
+ width: 49%;
+}
+[dir=rtl] #dokuwiki__sitetools form.search {
+ float: right;
+ margin: 0 0 .2em .2em;
+}
+
+#dokuwiki__sitetools form.search input {
+ width: 100% !important;
+}
+.dokuwiki form.search div.ajax_qsearch {
+ display: none !important;
+}
+
+/* action dropdown is alternative for all hidden tools */
+#dokuwiki__header .mobileTools {
+ display: block;
+ font-size: 0.875em;
+ margin: 0 0 .2em 0;
+ float: right;
+ width: 49%;
+}
+[dir=rtl] #dokuwiki__header .mobileTools {
+ float: left;
+}
+#dokuwiki__header .mobileTools select {
+ padding: .3em .1em;
+ width: 100% !important;
+}
+
+/* force same height on search input and tools select */
+#dokuwiki__sitetools form.search input,
+#dokuwiki__header .mobileTools select {
+ height: 2.1em;
+ line-height: 2.1em;
+ overflow: visible;
+}
+
+
+/*____________ content ____________*/
+
+#dokuwiki__aside > .pad,
+.dokuwiki div.page {
+ padding: .5em;
+}
+
+/* form elements */
+#config__manager fieldset td.value,
+#config__manager td .input,
+.dokuwiki fieldset,
+.dokuwiki input.edit,
+.dokuwiki textarea {
+ width: auto !important;
+ max-width: 100% !important;
+}
+.dokuwiki select {
+ max-width: 100% !important;
+}
+#config__manager fieldset {
+ margin-left: 0;
+ margin-right: 0;
+}
+
+.dokuwiki label.block {
+ text-align: left;
+
+ span {
+ display: block;
+ }
+}
+[dir=rtl] .dokuwiki label.block {
+ text-align: right;
+}
+
+/* _edit */
+.dokuwiki div.section_highlight {
+ margin: 0;
+ padding: 0;
+ border-width: 0;
+}
+.dokuwiki div.preview {
+ margin: 0 -.5em;
+ padding: .5em;
+}
+
+
+} /* /@media */
+
+
+/* for screen heights smaller than the pagetools permit
+********************************************************************/
+@media only screen and (max-height: 400px) {
+// 400px is only roughly the required value, this may be wrong under non-standard circumstances
+
+#dokuwiki__pagetools div.tools {
+ position: static;
+}
+
+
+} /* /@media */
diff --git a/platform/www/lib/tpl/dokuwiki/css/pagetools.less b/platform/www/lib/tpl/dokuwiki/css/pagetools.less
new file mode 100644
index 0000000..5473594
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/pagetools.less
@@ -0,0 +1,124 @@
+/**
+ * This file provides the styles for the page tools
+ * (fly out navigation beside the page to edit, etc).
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+#dokuwiki__site > .site {
+ /* give space to the right so the tools won't disappear on smaller screens */
+ /* it's 40px because the 30px wide icons will have 5px more spacing to the left and right */
+ padding-right: 40px;
+ /* give the same space to the left to balance it out */
+ padding-left: 40px;
+}
+
+.dokuwiki div.page {
+ height: 190px;
+ min-height: 190px; /* 30 (= height of icons) x 6 (= maximum number of possible tools) + 2x5 */
+ height: auto;
+}
+
+#dokuwiki__pagetools {
+ @ico-width: 28px;
+ @ico-margin: 8px;
+ @item-width: (@ico-width + @ico-margin + @ico-margin);
+ @item-height: (@ico-width + @ico-margin);
+
+ position: absolute;
+ right: (-1 * @item-width);
+ /* on same vertical level as first headline, because .page has 2em padding */
+ top: 2em;
+ width: @item-width;
+
+ div.tools {
+ position: fixed;
+ width: @item-width;
+
+ ul {
+ position: absolute;
+ right: 0;
+ text-align: right;
+ margin: 0;
+ padding: 0;
+ /* add transparent border to prevent jumping when proper border is added on hover */
+ border: 1px solid transparent;
+ z-index: 10;
+
+ li {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+ font-size: 0.875em;
+
+ a {
+
+ display: block;
+ /* add transparent border to prevent jumping when proper border is added on focus */
+ border: 1px solid transparent;
+ white-space: nowrap;
+ line-height: @item-height;
+ vertical-align: middle;
+ height: @item-height;
+
+ span {
+ display: none; // hide label until hover
+ margin: 0 @ico-margin;
+ }
+
+ svg {
+ width: @ico-width;
+ height: @ico-width;
+ margin: 0 @ico-margin;
+ display: inline-block;
+ vertical-align: middle;
+ fill: @ini_border;
+ }
+ }
+
+ // on interaction show the full item
+ a:active,
+ a:focus,
+ a:hover {
+ background-color: @ini_background_alt;
+
+ span {
+ display: inline-block;
+ }
+
+ svg {
+ fill: @ini_link;
+ }
+ }
+ }
+ }
+ }
+
+ [dir=rtl] & {
+ right: auto;
+ left: (-1 * @item-width);
+
+ div.tools {
+ ul {
+ right: auto;
+ left: 0;
+ text-align: left;
+ }
+ }
+ }
+}
+
+// on hover or focus show all items
+#dokuwiki__pagetools:hover, #dokuwiki__pagetools:focus-within {
+ div.tools ul {
+ background-color: @ini_background;
+ border-color: @ini_border;
+ border-radius: 2px;
+ box-shadow: 2px 2px 2px @ini_text_alt;
+
+ li a span {
+ display: inline-block;
+ }
+ }
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/print.css b/platform/www/lib/tpl/dokuwiki/css/print.css
new file mode 100644
index 0000000..7197ac1
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/print.css
@@ -0,0 +1,177 @@
+/**
+ * This file provides the styles for printing.
+ *
+ * @todo: improve and finish
+ */
+
+body {
+ font: normal 87.5%/1.3 Garamond, Baskerville, "Hoefler Text", "Nimbus Roman No9 L", serif;
+ background-color: #fff;
+ color: #000;
+}
+
+/* hide certain sections */
+.a11y,
+audio,
+video,
+#dokuwiki__header .tools,
+#dokuwiki__aside,
+.dokuwiki .breadcrumbs,
+.dokuwiki .pageId,
+#dw__toc,
+h3.toggle,
+#dokuwiki__pagetools,
+#dokuwiki__footer {
+ display: none;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+caption,
+legend {
+ clear: both;
+}
+ul {
+ list-style: disc outside;
+}
+ol {
+ list-style: decimal outside;
+}
+ol ol {
+ list-style-type: lower-alpha;
+}
+ol ol ol {
+ list-style-type: upper-roman;
+}
+ol ol ol ol {
+ list-style-type: upper-alpha;
+}
+ol ol ol ol ol {
+ list-style-type: lower-roman;
+}
+
+a:link,
+a:visited {
+ text-decoration: none;
+ border-bottom: 1pt dotted;
+ color: #333;
+ background-color: inherit;
+}
+
+/* display href after link */
+a.urlextern:after,
+a.interwiki:after,
+a.mail:after {
+ content: " [" attr(href) "]";
+ font-size: 90%;
+}
+
+/* code blocks */
+pre {
+ font-family: monospace;
+}
+dl.code dt,
+dl.file dt {
+ font-weight: bold;
+}
+
+mark {
+ font-weight: bold;
+}
+
+/* images */
+img {
+ border-width: 0;
+ vertical-align: middle;
+}
+img.media {
+ margin: .2em 0;
+}
+img.medialeft {
+ margin: .2em 1em .2em 0;
+}
+img.mediaright {
+ margin: .2em 0 .2em 1em;
+}
+img.mediacenter {
+ margin: .2em auto;
+}
+
+blockquote {
+ padding: 0 10pt;
+ margin: 0;
+ border: solid #ccc;
+ border-width: 0 0 0 2pt;
+}
+[dir=rtl] blockquote {
+ border-width: 0 2pt 0 0;
+}
+
+/* tables */
+.dokuwiki div.table {
+ margin-bottom: 1.4em;
+}
+table {
+ border-collapse: collapse;
+ empty-cells: show;
+ border-spacing: 0;
+ border: 1pt solid #ccc;
+}
+th,
+td {
+ padding: 3pt 5pt;
+ margin: 0;
+ vertical-align: top;
+ border: 1pt solid #666;
+}
+th {
+ font-weight: bold;
+ text-align: left;
+}
+[dir=rtl] th {
+ text-align: right;
+}
+
+
+/*____________ a bit of layout ____________*/
+
+#dokuwiki__header {
+ border-bottom: 2pt solid #ccc;
+}
+#dokuwiki__header h1 {
+ font-size: 1.5em;
+}
+#dokuwiki__header h1 a {
+ text-decoration: none;
+ border-width: 0;
+}
+#dokuwiki__header h1 img {
+ float: left;
+ margin-right: .5em;
+}
+[dir=rtl] #dokuwiki__header h1 img {
+ float: right;
+ margin-right: 0;
+ margin-left: .5em;
+}
+
+.dokuwiki div.footnotes {
+ clear: both;
+ border-top: 1pt dotted #999;
+ margin-top: 10pt;
+}
+
+.dokuwiki div.docInfo {
+ font-size: 90%;
+ text-align: right;
+ clear: both;
+ padding-top: 2pt;
+ border-top: 1pt solid #999;
+ margin-top: 10pt;
+}
+[dir=rtl] .dokuwiki div.docInfo {
+ text-align: left;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/structure.less b/platform/www/lib/tpl/dokuwiki/css/structure.less
new file mode 100644
index 0000000..3ea2f83
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/structure.less
@@ -0,0 +1,89 @@
+/**
+ * This file provides styles for the general layout structure.
+ *
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+body {
+ margin: 0 auto;
+}
+
+#dokuwiki__site {
+ margin: 0 auto;
+ max-width: @ini_site_width;
+}
+
+#dokuwiki__site > .site {
+ padding: 0 .5em;
+}
+
+#dokuwiki__header {
+ width: 100%;
+
+ .headings {
+ float: left;
+ }
+
+ .tools {
+ float: right;
+ text-align: right;
+ }
+}
+
+[dir=rtl] #dokuwiki__header {
+ .headings {
+ float: right;
+ text-align: right;
+ }
+
+ .tools {
+ float: left;
+ text-align: left;
+ }
+}
+
+#dokuwiki__site .wrapper {
+ position: relative;
+}
+
+#dokuwiki__aside {
+ width: @ini_sidebar_width;
+ float: left;
+ position: relative;
+ display: block;
+
+ > .pad {
+ margin: 0 1.5em 0 0;
+ }
+}
+
+[dir=rtl] #dokuwiki__aside {
+ float: right;
+ > .pad {
+ margin: 0 0 0 1.5em;
+ }
+}
+
+.showSidebar #dokuwiki__content {
+ float: right;
+ margin-left: (-1 * @ini_sidebar_width);
+ width: 100%;
+
+ > .pad {
+ margin-left: @ini_sidebar_width;
+ }
+}
+
+[dir=rtl] .showSidebar #dokuwiki__content {
+ float: left;
+ margin-left: 0;
+ margin-right: (-1 * @ini_sidebar_width);
+
+ > .pad {
+ margin-left: 0;
+ margin-right: @ini_sidebar_width;
+ }
+}
+
+#dokuwiki__footer {
+ clear: both;
+}
diff --git a/platform/www/lib/tpl/dokuwiki/css/usertools.less b/platform/www/lib/tpl/dokuwiki/css/usertools.less
new file mode 100644
index 0000000..efdf16c
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/css/usertools.less
@@ -0,0 +1,50 @@
+#dokuwiki__usertools {
+ position: absolute;
+ top: .5em;
+ right: 40px; // pagetool width
+ text-align: right;
+ width: 100%;
+
+ ul {
+ margin: 0 auto;
+ padding: 0;
+ max-width: @ini_site_width;
+ }
+
+ li.action a {
+ display: inline-flex;
+ flex-direction: row-reverse;
+ flex-wrap: nowrap;
+
+ svg {
+ height: 1.4em;
+ width: 1.4em;
+ vertical-align: middle;
+ fill: @ini_border;
+ margin-right: 0.2em;
+ }
+ }
+
+ li.action a:hover,
+ li.action a:active {
+ svg {
+ fill: @ini_link;
+ }
+ }
+
+}
+
+[dir=rtl] #dokuwiki__usertools {
+ text-align: left;
+ left: 40px; // pagetool width
+ right: auto;
+
+
+ li.action a {
+
+ svg {
+ margin-right: 0;
+ margin-left: 0.2em;
+ }
+ }
+}
diff --git a/platform/www/lib/tpl/dokuwiki/detail.php b/platform/www/lib/tpl/dokuwiki/detail.php
new file mode 100644
index 0000000..8e65410
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/detail.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ * DokuWiki Image Detail Page
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+// must be run from within DokuWiki
+if (!defined('DOKU_INC')) die();
+header('X-UA-Compatible: IE=edge,chrome=1');
+
+?><!DOCTYPE html>
+<html lang="<?php echo $conf['lang']?>" dir="<?php echo $lang['direction'] ?>" class="no-js">
+<head>
+ <meta charset="utf-8" />
+ <title>
+ <?php echo hsc(tpl_img_getTag('IPTC.Headline',$IMG))?>
+ [<?php echo strip_tags($conf['title'])?>]
+ </title>
+ <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
+ <?php tpl_metaheaders()?>
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
+ <?php echo tpl_favicon(array('favicon', 'mobile')) ?>
+ <?php tpl_includeFile('meta.html') ?>
+</head>
+
+<body>
+ <div id="dokuwiki__site"><div id="dokuwiki__top" class="site <?php echo tpl_classes(); ?>">
+
+ <?php include('tpl_header.php') ?>
+
+ <div class="wrapper group" id="dokuwiki__detail">
+
+ <!-- ********** CONTENT ********** -->
+ <div id="dokuwiki__content"><div class="pad group">
+ <?php html_msgarea() ?>
+
+ <?php if(!$ERROR): ?>
+ <div class="pageId"><span><?php echo hsc(tpl_img_getTag('IPTC.Headline',$IMG)); ?></span></div>
+ <?php endif; ?>
+
+ <div class="page group">
+ <?php tpl_flush() ?>
+ <?php tpl_includeFile('pageheader.html') ?>
+ <!-- detail start -->
+ <?php
+ if($ERROR):
+ echo '<h1>'.$ERROR.'</h1>';
+ else: ?>
+ <?php if($REV) echo p_locale_xhtml('showrev');?>
+ <h1><?php echo nl2br(hsc(tpl_img_getTag('simple.title'))); ?></h1>
+
+ <?php tpl_img(900,700); /* parameters: maximum width, maximum height (and more) */ ?>
+
+ <div class="img_detail">
+ <?php tpl_img_meta(); ?>
+ <dl>
+ <?php
+ echo '<dt>'.$lang['reference'].':</dt>';
+ $media_usage = ft_mediause($IMG,true);
+ if(count($media_usage) > 0){
+ foreach($media_usage as $path){
+ echo '<dd>'.html_wikilink($path).'</dd>';
+ }
+ }else{
+ echo '<dd>'.$lang['nothingfound'].'</dd>';
+ }
+ ?>
+ </dl>
+ <p><?php echo $lang['media_acl_warning']; ?></p>
+ </div>
+ <?php //Comment in for Debug// dbg(tpl_img_getTag('Simple.Raw'));?>
+ <?php endif; ?>
+ </div>
+ <!-- detail stop -->
+ <?php tpl_includeFile('pagefooter.html') ?>
+ <?php tpl_flush() ?>
+
+ <?php /* doesn't make sense like this; @todo: maybe add tpl_imginfo()?
+ <div class="docInfo"><?php tpl_pageinfo(); ?></div>
+ */ ?>
+
+ </div></div><!-- /content -->
+
+ <hr class="a11y" />
+
+ <!-- PAGE ACTIONS -->
+ <?php if (!$ERROR): ?>
+ <div id="dokuwiki__pagetools">
+ <h3 class="a11y"><?php echo $lang['page_tools']; ?></h3>
+ <div class="tools">
+ <ul>
+ <?php echo (new \dokuwiki\Menu\DetailMenu())->getListItems(); ?>
+ </ul>
+ </div>
+ </div>
+ <?php endif; ?>
+ </div><!-- /wrapper -->
+
+ <?php include('tpl_footer.php') ?>
+ </div></div><!-- /site -->
+</body>
+</html>
diff --git a/platform/www/lib/tpl/dokuwiki/images/apple-touch-icon.png b/platform/www/lib/tpl/dokuwiki/images/apple-touch-icon.png
new file mode 100644
index 0000000..87c99a9
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/apple-touch-icon.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/button-css.png b/platform/www/lib/tpl/dokuwiki/images/button-css.png
new file mode 100644
index 0000000..5c0f5a9
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/button-css.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/button-donate.gif b/platform/www/lib/tpl/dokuwiki/images/button-donate.gif
new file mode 100644
index 0000000..bba284e
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/button-donate.gif
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/button-dw.png b/platform/www/lib/tpl/dokuwiki/images/button-dw.png
new file mode 100644
index 0000000..8d6aea8
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/button-dw.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/button-html5.png b/platform/www/lib/tpl/dokuwiki/images/button-html5.png
new file mode 100644
index 0000000..f7b0688
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/button-html5.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/button-php.gif b/platform/www/lib/tpl/dokuwiki/images/button-php.gif
new file mode 100644
index 0000000..19aefb0
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/button-php.gif
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/button-rss.png b/platform/www/lib/tpl/dokuwiki/images/button-rss.png
new file mode 100644
index 0000000..aa6b7fc
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/button-rss.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/favicon.ico b/platform/www/lib/tpl/dokuwiki/images/favicon.ico
new file mode 100644
index 0000000..8b9616a
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/favicon.ico
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/license.txt b/platform/www/lib/tpl/dokuwiki/images/license.txt
new file mode 100644
index 0000000..7d12604
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/license.txt
@@ -0,0 +1,5 @@
+Icons for: sitetools.png
+Icon set: Dusseldorf
+Designer: pc.de
+License: Creative Commons Attribution License [http://creativecommons.org/licenses/by/3.0/]
+URL: http://pc.de/icons/#Dusseldorf
diff --git a/platform/www/lib/tpl/dokuwiki/images/logo.png b/platform/www/lib/tpl/dokuwiki/images/logo.png
new file mode 100644
index 0000000..a1f4995
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/logo.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/page-background.svg b/platform/www/lib/tpl/dokuwiki/images/page-background.svg
new file mode 100644
index 0000000..086341d
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/page-background.svg
@@ -0,0 +1,8 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
+ <linearGradient id="g" x1="0%" y1="0%" x2="0%" y2="100%">
+ <stop offset="0" stop-color="#dddddd" />
+ <stop offset="0.1" stop-color="#eeeeee" />
+ <stop offset="0.4" stop-color="#fbfaf9" />
+ </linearGradient>
+ <rect x="0" y="0" width="100%" height="100%" fill="url(#g)" />
+</svg> \ No newline at end of file
diff --git a/platform/www/lib/tpl/dokuwiki/images/page-gradient.png b/platform/www/lib/tpl/dokuwiki/images/page-gradient.png
new file mode 100644
index 0000000..38c7419
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/page-gradient.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools-build.php b/platform/www/lib/tpl/dokuwiki/images/pagetools-build.php
new file mode 100644
index 0000000..e19d750
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools-build.php
@@ -0,0 +1,125 @@
+<?php
+// phpcs:ignoreFile -- deprecated and will be removed
+/**
+ * This script generates a sprite from the unprocessed pagetool icons by combining them
+ * and overlaying a color layer for the active state.
+ *
+ * This script requires a current libGD to be available.
+ *
+ * The color for the active state is read from the style.ini's __link__ replacement
+ *
+ * The final sprite is optimized with optipng if available.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @deprecated 2018-06-15 we no longer use PNG based icons
+ * @todo Maybe add some more error checking
+ */
+$GAMMA = 0.8;
+$OPTIPNG = '/usr/bin/optipng';
+
+if('cli' != php_sapi_name()) die('please run from commandline');
+
+// load input images
+$input = glob('pagetools/*.png');
+sort($input);
+$cnt = count($input);
+if(!$cnt){
+ die("No input images found. This script needs to be called from within the image directory!\n");
+}
+
+// create destination image
+$DST = imagecreatetruecolor(30,$cnt*45*2);
+imagesavealpha($DST, true);
+$C_trans = imagecolorallocatealpha($DST, 0, 0, 0, 127);
+imagefill($DST, 0, 0, $C_trans);
+
+// load highlight color from style.ini
+$ini = parse_ini_file('../style.ini',true);
+$COLOR = hex2rgb($ini['replacements']['__link__']);
+$C_active = imagecolorallocate($DST, $COLOR['r'],$COLOR['g'],$COLOR['b']);
+
+// add all the icons to the sprite image
+for($i=0; $i<$cnt; $i++){
+ $base = $i*90;
+
+ $IN = imagecreatefrompng($input[$i]);
+ imagesavealpha($IN, true);
+ imagecolorscale($IN,$GAMMA);
+ imagecopy($DST,$IN, 0,$base, 0,0, 30,30);
+ imagedestroy($IN);
+
+ $IN = imagecreatefrompng($input[$i]);
+ imagesavealpha($IN, true);
+ imagecolorscale($IN,$GAMMA);
+ imagecopy($DST,$IN, 0,$base+45, 0,0, 30,30);
+ imagedestroy($IN);
+
+ imagelayereffect($DST, IMG_EFFECT_OVERLAY);
+ imagefilledrectangle($DST, 0,$base+45, 30,$base+45+30, $C_active);
+ imagelayereffect($DST, IMG_EFFECT_NORMAL);
+}
+
+// output sprite
+imagepng($DST,'pagetools-sprite.png');
+imagedestroy($DST);
+
+// optimize if possible
+if(is_executable($OPTIPNG)){
+ system("$OPTIPNG -o5 'pagetools-sprite.png'");
+}
+
+/**
+ * Convert a hex color code to an rgb array
+ */
+function hex2rgb($hex) {
+ // strip hash
+ $hex = str_replace('#', '', $hex);
+
+ // normalize short codes
+ if(strlen($hex) == 3){
+ $hex = substr($hex,0,1).
+ substr($hex,0,1).
+ substr($hex,1,1).
+ substr($hex,1,1).
+ substr($hex,2,1).
+ substr($hex,2,1);
+ }
+
+ // calc rgb
+ return array(
+ 'r' => hexdec(substr($hex, 0, 2)),
+ 'g' => hexdec(substr($hex, 2, 2)),
+ 'b' => hexdec(substr($hex, 4, 2))
+ );
+}
+
+/**
+ * Scale (darken/lighten) a given image
+ *
+ * @param resource $img The truetype GD image to work on
+ * @param float $scale Scale the colors by this value ( <1 darkens, >1 lightens)
+ */
+function imagecolorscale(&$img, $scale){
+ $w = imagesx($img);
+ $h = imagesy($img);
+
+ imagealphablending($img, false);
+ for($x = 0; $x < $w; $x++){
+ for($y = 0; $y < $h; $y++){
+ $rgba = imagecolorat($img, $x, $y);
+ $a = ($rgba >> 24) & 0xFF;
+ $r = ($rgba >> 16) & 0xFF;
+ $g = ($rgba >> 8) & 0xFF;
+ $b = $rgba & 0xFF;
+
+ $r = max(min(round($r*$scale),255),0);
+ $g = max(min(round($g*$scale),255),0);
+ $b = max(min(round($b*$scale),255),0);
+
+ $color = imagecolorallocatealpha($img, $r, $g, $b, $a);
+ imagesetpixel($img, $x, $y, $color);
+ }
+ }
+ imagealphablending($img, true);
+}
+
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools-sprite.png b/platform/www/lib/tpl/dokuwiki/images/pagetools-sprite.png
new file mode 100644
index 0000000..8e7f7f8
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools-sprite.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/00_default.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/00_default.png
new file mode 100644
index 0000000..bcb2de0
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/00_default.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/01_edit.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/01_edit.png
new file mode 100644
index 0000000..99f3093
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/01_edit.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/02_create.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/02_create.png
new file mode 100644
index 0000000..57fa68d
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/02_create.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/03_draft.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/03_draft.png
new file mode 100644
index 0000000..ce1c6cf
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/03_draft.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/04_show.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/04_show.png
new file mode 100644
index 0000000..1ced340
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/04_show.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/05_source.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/05_source.png
new file mode 100644
index 0000000..dffe193
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/05_source.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/06_revert.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/06_revert.png
new file mode 100644
index 0000000..18c6444
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/06_revert.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/07_revisions.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/07_revisions.png
new file mode 100644
index 0000000..e599d01
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/07_revisions.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/08_backlink.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/08_backlink.png
new file mode 100644
index 0000000..aa34e27
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/08_backlink.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/09_subscribe.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/09_subscribe.png
new file mode 100644
index 0000000..36254ff
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/09_subscribe.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/10_top.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/10_top.png
new file mode 100644
index 0000000..b930fd2
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/10_top.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/11_mediamanager.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/11_mediamanager.png
new file mode 100644
index 0000000..71b5a33
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/11_mediamanager.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/12_back.png b/platform/www/lib/tpl/dokuwiki/images/pagetools/12_back.png
new file mode 100644
index 0000000..6d6093e
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/12_back.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/pagetools/license.txt b/platform/www/lib/tpl/dokuwiki/images/pagetools/license.txt
new file mode 100644
index 0000000..299624c
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/pagetools/license.txt
@@ -0,0 +1,4 @@
+Icon set: iPhone toolbar icons
+Designer: TheWorkingGroup.ca
+License: Creative Commons Attribution-Share Alike License [http://creativecommons.org/licenses/by-sa/3.0/]
+URL: http://blog.twg.ca/2009/09/free-iphone-toolbar-icons/
diff --git a/platform/www/lib/tpl/dokuwiki/images/search.png b/platform/www/lib/tpl/dokuwiki/images/search.png
new file mode 100644
index 0000000..a07a721
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/search.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/toc-arrows.png b/platform/www/lib/tpl/dokuwiki/images/toc-arrows.png
new file mode 100644
index 0000000..4a353e4
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/toc-arrows.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/toc-bullet.png b/platform/www/lib/tpl/dokuwiki/images/toc-bullet.png
new file mode 100644
index 0000000..a2dfa47
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/toc-bullet.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/images/usertools.png b/platform/www/lib/tpl/dokuwiki/images/usertools.png
new file mode 100644
index 0000000..6810227
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/images/usertools.png
Binary files differ
diff --git a/platform/www/lib/tpl/dokuwiki/lang/en/lang.php b/platform/www/lib/tpl/dokuwiki/lang/en/lang.php
new file mode 100644
index 0000000..7c890c6
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/lang/en/lang.php
@@ -0,0 +1,13 @@
+<?php
+
+// style.ini values
+
+$lang['__background_site__'] = 'Color for the very background (behind the content box)';
+$lang['__link__'] = 'The general link color';
+$lang['__existing__'] = 'The color for links to existing pages';
+$lang['__missing__'] = 'The color for links to non-existing pages';
+$lang['__site_width__'] = 'The width of the full site (can be any length unit: %, px, em, ...)';
+$lang['__sidebar_width__'] = 'The width of the sidebar, if any (can be any length unit: %, px, em, ...)';
+$lang['__tablet_width__'] = 'Below screensizes of this width, the site switches to tablet mode';
+$lang['__phone_width__'] = 'Below screensizes of this width, the site switches to phone mode';
+$lang['__theme_color__'] = 'Theme color of the web app';
diff --git a/platform/www/lib/tpl/dokuwiki/lang/en/style.txt b/platform/www/lib/tpl/dokuwiki/lang/en/style.txt
new file mode 100644
index 0000000..7bf3e1a
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/lang/en/style.txt
@@ -0,0 +1,4 @@
+If you want to adjust the logo, simply use the Media Manager to upload a ''logo.png'' into the ''wiki'' or the root namespace and it
+will be automatically used. You can also upload a ''favicon.ico'' there. If you use a closed
+wiki it is recommended to make the ''wiki'' (or root) namespace world readable in the ACL settings or
+your logo is not shown to not logged in users.
diff --git a/platform/www/lib/tpl/dokuwiki/main.php b/platform/www/lib/tpl/dokuwiki/main.php
new file mode 100644
index 0000000..67b6e61
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/main.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * DokuWiki Default Template 2012
+ *
+ * @link http://dokuwiki.org/template
+ * @author Anika Henke <anika@selfthinker.org>
+ * @author Clarence Lee <clarencedglee@gmail.com>
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+
+if (!defined('DOKU_INC')) die(); /* must be run from within DokuWiki */
+
+$hasSidebar = page_findnearest($conf['sidebar']);
+$showSidebar = $hasSidebar && ($ACT=='show');
+?><!DOCTYPE html>
+<html lang="<?php echo $conf['lang'] ?>" dir="<?php echo $lang['direction'] ?>" class="no-js">
+<head>
+ <meta charset="utf-8" />
+ <title><?php tpl_pagetitle() ?> [<?php echo strip_tags($conf['title']) ?>]</title>
+ <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
+ <?php tpl_metaheaders() ?>
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
+ <?php echo tpl_favicon(array('favicon', 'mobile')) ?>
+ <?php tpl_includeFile('meta.html') ?>
+</head>
+
+<body>
+ <div id="dokuwiki__site"><div id="dokuwiki__top" class="site <?php echo tpl_classes(); ?> <?php
+ echo ($showSidebar) ? 'showSidebar' : ''; ?> <?php echo ($hasSidebar) ? 'hasSidebar' : ''; ?>">
+
+ <?php include('tpl_header.php') ?>
+
+ <div class="wrapper group">
+
+ <?php if($showSidebar): ?>
+ <!-- ********** ASIDE ********** -->
+ <div id="dokuwiki__aside"><div class="pad aside include group">
+ <h3 class="toggle"><?php echo $lang['sidebar'] ?></h3>
+ <div class="content"><div class="group">
+ <?php tpl_flush() ?>
+ <?php tpl_includeFile('sidebarheader.html') ?>
+ <?php tpl_include_page($conf['sidebar'], true, true) ?>
+ <?php tpl_includeFile('sidebarfooter.html') ?>
+ </div></div>
+ </div></div><!-- /aside -->
+ <?php endif; ?>
+
+ <!-- ********** CONTENT ********** -->
+ <div id="dokuwiki__content"><div class="pad group">
+ <?php html_msgarea() ?>
+
+ <div class="pageId"><span><?php echo hsc($ID) ?></span></div>
+
+ <div class="page group">
+ <?php tpl_flush() ?>
+ <?php tpl_includeFile('pageheader.html') ?>
+ <!-- wikipage start -->
+ <?php tpl_content() ?>
+ <!-- wikipage stop -->
+ <?php tpl_includeFile('pagefooter.html') ?>
+ </div>
+
+ <div class="docInfo"><?php tpl_pageinfo() ?></div>
+
+ <?php tpl_flush() ?>
+ </div></div><!-- /content -->
+
+ <hr class="a11y" />
+
+ <!-- PAGE ACTIONS -->
+ <div id="dokuwiki__pagetools">
+ <h3 class="a11y"><?php echo $lang['page_tools']; ?></h3>
+ <div class="tools">
+ <ul>
+ <?php echo (new \dokuwiki\Menu\PageMenu())->getListItems(); ?>
+ </ul>
+ </div>
+ </div>
+ </div><!-- /wrapper -->
+
+ <?php include('tpl_footer.php') ?>
+ </div></div><!-- /site -->
+
+ <div class="no"><?php tpl_indexerWebBug() /* provide DokuWiki housekeeping, required in all templates */ ?></div>
+ <div id="screen__mode" class="no"></div><?php /* helper to detect CSS media query in script.js */ ?>
+</body>
+</html>
diff --git a/platform/www/lib/tpl/dokuwiki/mediamanager.php b/platform/www/lib/tpl/dokuwiki/mediamanager.php
new file mode 100644
index 0000000..53ed062
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/mediamanager.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * DokuWiki Media Manager Popup
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
+ */
+// must be run from within DokuWiki
+if (!defined('DOKU_INC')) die();
+header('X-UA-Compatible: IE=edge,chrome=1');
+
+?><!DOCTYPE html>
+<html lang="<?php echo $conf['lang']?>" dir="<?php echo $lang['direction'] ?>" class="popup no-js">
+<head>
+ <meta charset="utf-8" />
+ <title>
+ <?php echo hsc($lang['mediaselect'])?>
+ [<?php echo strip_tags($conf['title'])?>]
+ </title>
+ <script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
+ <?php tpl_metaheaders()?>
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
+ <?php echo tpl_favicon(array('favicon', 'mobile')) ?>
+ <?php tpl_includeFile('meta.html') ?>
+</head>
+
+<body>
+ <div id="media__manager" class="dokuwiki">
+ <?php html_msgarea() ?>
+ <div id="mediamgr__aside"><div class="pad">
+ <h1><?php echo hsc($lang['mediaselect'])?></h1>
+
+ <?php /* keep the id! additional elements are inserted via JS here */?>
+ <div id="media__opts"></div>
+
+ <?php tpl_mediaTree() ?>
+ </div></div>
+
+ <div id="mediamgr__content"><div class="pad">
+ <?php tpl_mediaContent() ?>
+ </div></div>
+ </div>
+</body>
+</html>
diff --git a/platform/www/lib/tpl/dokuwiki/script.js b/platform/www/lib/tpl/dokuwiki/script.js
new file mode 100644
index 0000000..88dae90
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/script.js
@@ -0,0 +1,89 @@
+/**
+ * We handle several device classes based on browser width.
+ *
+ * - desktop: > __tablet_width__ (as set in style.ini)
+ * - mobile:
+ * - tablet <= __tablet_width__
+ * - phone <= __phone_width__
+ */
+var device_class = ''; // not yet known
+var device_classes = 'desktop mobile tablet phone';
+
+function tpl_dokuwiki_mobile(){
+
+ // the z-index in mobile.css is (mis-)used purely for detecting the screen mode here
+ var screen_mode = jQuery('#screen__mode').css('z-index') + '';
+
+ // determine our device pattern
+ // TODO: consider moving into dokuwiki core
+ switch (screen_mode) {
+ case '1':
+ if (device_class.match(/tablet/)) return;
+ device_class = 'mobile tablet';
+ break;
+ case '2':
+ if (device_class.match(/phone/)) return;
+ device_class = 'mobile phone';
+ break;
+ default:
+ if (device_class == 'desktop') return;
+ device_class = 'desktop';
+ }
+
+ jQuery('html').removeClass(device_classes).addClass(device_class);
+
+ // handle some layout changes based on change in device
+ var $handle = jQuery('#dokuwiki__aside h3.toggle');
+ var $toc = jQuery('#dw__toc h3');
+
+ if (device_class == 'desktop') {
+ // reset for desktop mode
+ if($handle.length) {
+ $handle[0].setState(1);
+ $handle.hide();
+ }
+ if($toc.length) {
+ $toc[0].setState(1);
+ }
+ }
+ if (device_class.match(/mobile/)){
+ // toc and sidebar hiding
+ if($handle.length) {
+ $handle.show();
+ $handle[0].setState(-1);
+ }
+ if($toc.length) {
+ $toc[0].setState(-1);
+ }
+ }
+}
+
+jQuery(function(){
+ var resizeTimer;
+ dw_page.makeToggle('#dokuwiki__aside h3.toggle','#dokuwiki__aside div.content');
+
+ tpl_dokuwiki_mobile();
+ jQuery(window).on('resize',
+ function(){
+ if (resizeTimer) clearTimeout(resizeTimer);
+ resizeTimer = setTimeout(tpl_dokuwiki_mobile,200);
+ }
+ );
+
+ // increase sidebar length to match content (desktop mode only)
+ var sidebar_height = jQuery('.desktop #dokuwiki__aside').height();
+ var pagetool_height = jQuery('.desktop #dokuwiki__pagetools ul:first').height();
+ // pagetools div has no height; ul has a height
+ var content_min = Math.max(sidebar_height || 0, pagetool_height || 0);
+
+ var content_height = jQuery('#dokuwiki__content div.page').height();
+ if(content_min && content_min > content_height) {
+ var $content = jQuery('#dokuwiki__content div.page');
+ $content.css('min-height', content_min);
+ }
+
+ // blur when clicked
+ jQuery('#dokuwiki__pagetools div.tools>ul>li>a').on('click', function(){
+ this.blur();
+ });
+});
diff --git a/platform/www/lib/tpl/dokuwiki/style.ini b/platform/www/lib/tpl/dokuwiki/style.ini
new file mode 100644
index 0000000..723e8bc
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/style.ini
@@ -0,0 +1,89 @@
+; Please see http://php.net/manual/en/function.parse-ini-file.php
+; for limitations of the ini format used here
+
+; To extend this file or make changes to it, it is recommended to create
+; a local conf/tpl/<template-folder-name>/style.ini file to prevent losing
+; any changes after an upgrade.
+; Please don't forget to copy the section your changes should be under
+; (i.e. [stylesheets] or [replacements]) into that file as well.
+
+; Define the stylesheets your template uses here. The second value
+; defines for which output media the style should be loaded. Currently
+; print, screen and all are supported.
+; You can reference CSS and LESS files here. Files referenced here will
+; be checked for updates when considering a cache rebuild while files
+; included through LESS' @import statements are not
+
+[stylesheets]
+
+css/basic.less = screen
+css/_imgdetail.css = screen
+css/_media_popup.css = screen
+css/_media_fullscreen.css = screen
+css/_fileuploader.css = screen
+css/_tabs.css = screen
+css/_links.css = screen
+css/_toc.css = screen
+css/_footnotes.css = screen
+css/_search.less = screen
+css/_recent.css = screen
+css/_diff.css = screen
+css/_edit.css = screen
+css/_modal.css = screen
+css/_forms.css = screen
+css/_admin.less = screen
+css/structure.less = screen
+css/design.less = screen
+css/usertools.less = screen
+css/pagetools.less = screen
+css/content.less = screen
+
+css/mobile.less = all
+css/print.css = print
+
+
+; This section is used to configure some placeholder values used in
+; the stylesheets. Changing this file is the simplest method to
+; give your wiki a new look.
+; Placeholders defined here will also be made available as LESS variables
+; (with surrounding underscores removed, and the prefix @ini_ added)
+
+[replacements]
+
+;--------------------------------------------------------------------------
+;------ guaranteed dokuwiki color placeholders that every plugin can use
+
+; main text and background colors
+__text__ = "#333" ; @ini_text
+__background__ = "#fff" ; @ini_background
+; alternative text and background colors
+__text_alt__ = "#999" ; @ini_text_alt
+__background_alt__ = "#eee" ; @ini_background_alt
+; neutral text and background colors
+__text_neu__ = "#666" ; @ini_text_neu
+__background_neu__ = "#ddd" ; @ini_background_neu
+; border color
+__border__ = "#ccc" ; @ini_border
+
+; highlighted text (e.g. search snippets)
+__highlight__ = "#ff9" ; @ini_highlight
+
+; default link color
+__link__ = "#2b73b7" ; @ini_link
+
+;--------------------------------------------------------------------------
+
+__background_site__ = "#fbfaf9" ; @ini_background_site
+
+; these are used for wiki links
+__existing__ = "#080" ; @ini_existing
+__missing__ = "#d30" ; @ini_missing
+
+; site and sidebar widths
+__site_width__ = "75em" ; @ini_site_width
+__sidebar_width__ = "16em" ; @ini_sidebar_width
+; cut off points for mobile devices
+__tablet_width__ = "800px" ; @ini_tablet_width
+__phone_width__ = "480px" ; @ini_phone_width
+
+__theme_color__ = "#008800" ; @_ini_theme_color: theme_color of the web app
diff --git a/platform/www/lib/tpl/dokuwiki/template.info.txt b/platform/www/lib/tpl/dokuwiki/template.info.txt
new file mode 100644
index 0000000..73ad939
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/template.info.txt
@@ -0,0 +1,7 @@
+base dokuwiki
+author Anika Henke
+email anika@selfthinker.org
+date 2015-07-26
+name DokuWiki Template
+desc DokuWiki's default template since 2012
+url http://www.dokuwiki.org/template:dokuwiki
diff --git a/platform/www/lib/tpl/dokuwiki/tpl_footer.php b/platform/www/lib/tpl/dokuwiki/tpl_footer.php
new file mode 100644
index 0000000..c7a04e1
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/tpl_footer.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Template footer, included in the main and detail files
+ */
+
+// must be run from within DokuWiki
+if (!defined('DOKU_INC')) die();
+?>
+
+<!-- ********** FOOTER ********** -->
+<div id="dokuwiki__footer"><div class="pad">
+ <?php tpl_license(''); // license text ?>
+
+ <div class="buttons">
+ <?php
+ tpl_license('button', true, false, false); // license button, no wrapper
+ $target = ($conf['target']['extern']) ? 'target="'.$conf['target']['extern'].'"' : '';
+ ?>
+ <a href="https://www.dokuwiki.org/donate" title="Donate" <?php echo $target?>><img
+ src="<?php echo tpl_basedir(); ?>images/button-donate.gif" width="80" height="15" alt="Donate" /></a>
+ <a href="https://php.net" title="Powered by PHP" <?php echo $target?>><img
+ src="<?php echo tpl_basedir(); ?>images/button-php.gif" width="80" height="15" alt="Powered by PHP" /></a>
+ <a href="//validator.w3.org/check/referer" title="Valid HTML5" <?php echo $target?>><img
+ src="<?php echo tpl_basedir(); ?>images/button-html5.png" width="80" height="15" alt="Valid HTML5" /></a>
+ <a href="//jigsaw.w3.org/css-validator/check/referer?profile=css3" title="Valid CSS" <?php echo $target?>><img
+ src="<?php echo tpl_basedir(); ?>images/button-css.png" width="80" height="15" alt="Valid CSS" /></a>
+ <a href="https://dokuwiki.org/" title="Driven by DokuWiki" <?php echo $target?>><img
+ src="<?php echo tpl_basedir(); ?>images/button-dw.png" width="80" height="15"
+ alt="Driven by DokuWiki" /></a>
+ </div>
+</div></div><!-- /footer -->
+
+<?php
+tpl_includeFile('footer.html');
diff --git a/platform/www/lib/tpl/dokuwiki/tpl_header.php b/platform/www/lib/tpl/dokuwiki/tpl_header.php
new file mode 100644
index 0000000..bb8732b
--- /dev/null
+++ b/platform/www/lib/tpl/dokuwiki/tpl_header.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Template header, included in the main and detail files
+ */
+
+// must be run from within DokuWiki
+if (!defined('DOKU_INC')) die();
+?>
+
+<!-- ********** HEADER ********** -->
+<div id="dokuwiki__header"><div class="pad group">
+
+ <?php tpl_includeFile('header.html') ?>
+
+ <div class="headings group">
+ <ul class="a11y skip">
+ <li><a href="#dokuwiki__content"><?php echo $lang['skip_to_content']; ?></a></li>
+ </ul>
+
+ <h1><?php
+ // get logo either out of the template images folder or data/media folder
+ $logoSize = array();
+ $logo = tpl_getMediaFile(array(':wiki:logo.png', ':logo.png', 'images/logo.png'), false, $logoSize);
+
+ // display logo and wiki title in a link to the home page
+ tpl_link(
+ wl(),
+ '<img src="'.$logo.'" '.$logoSize[3].' alt="" /> <span>'.$conf['title'].'</span>',
+ 'accesskey="h" title="[H]"'
+ );
+ ?></h1>
+ <?php if ($conf['tagline']): ?>
+ <p class="claim"><?php echo $conf['tagline']; ?></p>
+ <?php endif ?>
+ </div>
+
+ <div class="tools group">
+ <!-- USER TOOLS -->
+ <?php if ($conf['useacl']): ?>
+ <div id="dokuwiki__usertools">
+ <h3 class="a11y"><?php echo $lang['user_tools']; ?></h3>
+ <ul>
+ <?php
+ if (!empty($_SERVER['REMOTE_USER'])) {
+ echo '<li class="user">';
+ tpl_userinfo(); /* 'Logged in as ...' */
+ echo '</li>';
+ }
+ echo (new \dokuwiki\Menu\UserMenu())->getListItems('action ');
+ ?>
+ </ul>
+ </div>
+ <?php endif ?>
+
+ <!-- SITE TOOLS -->
+ <div id="dokuwiki__sitetools">
+ <h3 class="a11y"><?php echo $lang['site_tools']; ?></h3>
+ <?php tpl_searchform(); ?>
+ <div class="mobileTools">
+ <?php echo (new \dokuwiki\Menu\MobileMenu())->getDropdown($lang['tools']); ?>
+ </div>
+ <ul>
+ <?php echo (new \dokuwiki\Menu\SiteMenu())->getListItems('action ', false); ?>
+ </ul>
+ </div>
+
+ </div>
+
+ <!-- BREADCRUMBS -->
+ <?php if($conf['breadcrumbs'] || $conf['youarehere']): ?>
+ <div class="breadcrumbs">
+ <?php if($conf['youarehere']): ?>
+ <div class="youarehere"><?php tpl_youarehere() ?></div>
+ <?php endif ?>
+ <?php if($conf['breadcrumbs']): ?>
+ <div class="trace"><?php tpl_breadcrumbs() ?></div>
+ <?php endif ?>
+ </div>
+ <?php endif ?>
+
+
+
+ <hr class="a11y" />
+</div></div><!-- /header -->
diff --git a/platform/www/lib/tpl/index.php b/platform/www/lib/tpl/index.php
new file mode 100644
index 0000000..4d48d51
--- /dev/null
+++ b/platform/www/lib/tpl/index.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * This file reads the style.ini of the used template and displays the
+ * replacements defined in it. Color replacements will be displayed
+ * visually. This should help with adjusting and using the styles
+ * specified in the style.ini
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Anika Henke <anika@selfthinker.org>
+ */
+// phpcs:disable PSR1.Files.SideEffects
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+if(!defined('NOSESSION')) define('NOSESSION',1);
+require_once(DOKU_INC.'inc/init.php');
+?>
+<!DOCTYPE html>
+<html lang="en" dir="ltr">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Template Replacements</title>
+ <style>
+ body {
+ background-color: #fff;
+ color: #000;
+ }
+ caption {
+ font-weight: bold;
+ }
+ td {
+ margin: 0;
+ padding: 0.5em 2em;
+ font-family: monospace;
+ font-size: 120%;
+ border: 1px solid #fff;
+ }
+ tr:hover td {
+ border: 1px solid #ccc;
+ }
+ .color {
+ padding: 0.25em 1em;
+ border: 1px #000 solid;
+ }
+ </style>
+</head>
+<body>
+<?php
+// get merged style.ini
+$styleUtils = new \dokuwiki\StyleUtils($conf['template']);
+$ini = $styleUtils->cssStyleini();
+
+if (!empty($ini)) {
+ echo '<table>';
+ echo "<caption>".hsc($conf['template'])."'s style.ini</caption>";
+ foreach($ini['replacements'] as $key => $val){
+ echo '<tr>';
+ echo '<td>'.hsc($key).'</td>';
+ echo '<td>'.hsc($val).'</td>';
+ echo '<td>';
+ if(preg_match('/^#[0-f]{3,6}$/i',$val)){
+ echo '<div class="color" style="background-color:'.$val.';">&#160;</div>';
+ }
+ echo '</td>';
+ echo '</tr>';
+ }
+ echo '</table>';
+} else {
+ echo "<p>Non-existent or invalid template or style.ini: <strong>".hsc($conf['template'])."</strong></p>";
+}
+?>
+</body>
+</html>
diff --git a/platform/www/vendor/.htaccess b/platform/www/vendor/.htaccess
new file mode 100644
index 0000000..7625314
--- /dev/null
+++ b/platform/www/vendor/.htaccess
@@ -0,0 +1,7 @@
+<IfModule mod_authz_core.c>
+ Require all denied
+</IfModule>
+<IfModule !mod_authz_core.c>
+ Order allow,deny
+ Deny from all
+</IfModule>
diff --git a/platform/www/vendor/README b/platform/www/vendor/README
new file mode 100644
index 0000000..e4027f4
--- /dev/null
+++ b/platform/www/vendor/README
@@ -0,0 +1,6 @@
+====== composer managed libraries ======
+
+All file within here are manged through composer and should not be
+edited directly. Instead provide upstream patches.
+
+Learn more about Composer at http://getcomposer.org
diff --git a/platform/www/vendor/autoload.php b/platform/www/vendor/autoload.php
new file mode 100644
index 0000000..521b485
--- /dev/null
+++ b/platform/www/vendor/autoload.php
@@ -0,0 +1,7 @@
+<?php
+
+// autoload.php @generated by Composer
+
+require_once __DIR__ . '/composer/autoload_real.php';
+
+return ComposerAutoloaderInita19a915ee98347a0c787119619d2ff9b::getLoader();
diff --git a/platform/www/vendor/aziraphale/email-address-validator/EmailAddressValidator.php b/platform/www/vendor/aziraphale/email-address-validator/EmailAddressValidator.php
new file mode 100644
index 0000000..21285bc
--- /dev/null
+++ b/platform/www/vendor/aziraphale/email-address-validator/EmailAddressValidator.php
@@ -0,0 +1,183 @@
+<?php
+
+/**
+ * Class EmailAddressValidator
+ *
+ * @link https://github.com/aziraphale/email-address-validator
+ * @link http://code.google.com/p/php-email-address-validation/
+ * @license New BSD license http://www.opensource.org/licenses/bsd-license.php
+ * @example if (EmailAddressValidator::checkEmailAddress('test@example.org')) {
+ * @example // Email address is technically valid
+ * @example }
+ */
+class EmailAddressValidator
+{
+ /**
+ * Check email address validity
+ * @param string $emailAddress Email address to be checked
+ * @param bool $allowLocal allow local domains
+ * @return bool Whether email is valid
+ */
+ public static function checkEmailAddress($emailAddress, $allowLocal = false)
+ {
+ // If magic quotes is "on", email addresses with quote marks will
+ // fail validation because of added escape characters. Uncommenting
+ // the next three lines will allow for this issue.
+ //if (get_magic_quotes_gpc()) {
+ // $emailAddress = stripslashes($emailAddress);
+ //}
+
+ // Control characters are not allowed
+ if (preg_match('/[\x00-\x1F\x7F-\xFF]/', $emailAddress)) {
+ return false;
+ }
+
+ // Check email length - min 3 (a@a), max 256
+ if (!self::checkTextLength($emailAddress, 3, 256)) {
+ return false;
+ }
+
+ // Split it into sections using last instance of "@"
+ $atSymbol = strrpos($emailAddress, '@');
+ if ($atSymbol === false) {
+ // No "@" symbol in email.
+ return false;
+ }
+ $emailAddressParts[0] = substr($emailAddress, 0, $atSymbol);
+ $emailAddressParts[1] = substr($emailAddress, $atSymbol + 1);
+
+ // Count the "@" symbols. Only one is allowed, except where
+ // contained in quote marks in the local part. Quickest way to
+ // check this is to remove anything in quotes. We also remove
+ // characters escaped with backslash, and the backslash
+ // character.
+ $tempAddressParts[0] = preg_replace('/\./', '', $emailAddressParts[0]);
+ $tempAddressParts[0] = preg_replace('/"[^"]+"/', '', $tempAddressParts[0]);
+ $tempAddressParts[1] = $emailAddressParts[1];
+ $tempAddress = $tempAddressParts[0] . $tempAddressParts[1];
+ // Then check - should be no "@" symbols.
+ if (strrpos($tempAddress, '@') !== false) {
+ // "@" symbol found
+ return false;
+ }
+
+ // Check local portion
+ if (!self::checkLocalPortion($emailAddressParts[0])) {
+ return false;
+ }
+
+ // Check domain portion
+ if (!self::checkDomainPortion($emailAddressParts[1], $allowLocal)) {
+ return false;
+ }
+
+ // If we're still here, all checks above passed. Email is valid.
+ return true;
+ }
+
+ /**
+ * Checks email section before "@" symbol for validity
+ * @param string $localPortion Text to be checked
+ * @return bool Whether local portion is valid
+ */
+ public static function checkLocalPortion($localPortion)
+ {
+ // Local portion can only be from 1 to 64 characters, inclusive.
+ // Please note that servers are encouraged to accept longer local
+ // parts than 64 characters.
+ if (!self::checkTextLength($localPortion, 1, 64)) {
+ return false;
+ }
+ // Local portion must be:
+ // 1) a dot-atom (strings separated by periods)
+ // 2) a quoted string
+ // 3) an obsolete format string (combination of the above)
+ $localPortionParts = explode('.', $localPortion);
+ for ($i = 0, $max = sizeof($localPortionParts); $i < $max; $i++) {
+ if (!preg_match('.^('
+ . '([A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]'
+ . '[A-Za-z0-9!#$%&\'*+/=?^_`{|}~-]{0,63})'
+ .'|'
+ . '("[^\\\"]{0,62}")'
+ .')$.'
+ ,$localPortionParts[$i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Checks email section after "@" symbol for validity
+ * @param string $domainPortion Text to be checked
+ * @param bool $allowLocal allow local domains?
+ * @return bool Whether domain portion is valid
+ */
+ public static function checkDomainPortion($domainPortion, $allowLocal = false)
+ {
+ // Total domain can only be from 1 to 255 characters, inclusive
+ if (!self::checkTextLength($domainPortion, 1, 255)) {
+ return false;
+ }
+
+ // some IPv4/v6 regexps borrowed from Feyd
+ // see: http://forums.devnetwork.net/viewtopic.php?f=38&t=53479
+ $dec_octet = '(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|[0-9])';
+ $hex_digit = '[A-Fa-f0-9]';
+ $h16 = "{$hex_digit}{1,4}";
+ $IPv4Address = "$dec_octet\\.$dec_octet\\.$dec_octet\\.$dec_octet";
+ $ls32 = "(?:$h16:$h16|$IPv4Address)";
+ $IPv6Address =
+ "(?:(?:{$IPv4Address})|(?:" .
+ "(?:$h16:){6}$ls32" .
+ "|::(?:$h16:){5}$ls32" .
+ "|(?:$h16)?::(?:$h16:){4}$ls32" .
+ "|(?:(?:$h16:){0,1}$h16)?::(?:$h16:){3}$ls32" .
+ "|(?:(?:$h16:){0,2}$h16)?::(?:$h16:){2}$ls32" .
+ "|(?:(?:$h16:){0,3}$h16)?::(?:$h16:){1}$ls32" .
+ "|(?:(?:$h16:){0,4}$h16)?::$ls32" .
+ "|(?:(?:$h16:){0,5}$h16)?::$h16" .
+ "|(?:(?:$h16:){0,6}$h16)?::" .
+ ")(?:\\/(?:12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9]))?)";
+
+ if (preg_match("/^($IPv4Address|\\[$IPv4Address\\]|\\[$IPv6Address\\])$/",
+ $domainPortion)){
+ return true;
+ } else {
+ $domainPortionParts = explode('.', $domainPortion);
+ if (!$allowLocal && sizeof($domainPortionParts) < 2) {
+ return false; // Not enough parts to domain
+ }
+ for ($i = 0, $max = sizeof($domainPortionParts); $i < $max; $i++) {
+ // Each portion must be between 1 and 63 characters, inclusive
+ if (!self::checkTextLength($domainPortionParts[$i], 1, 63)) {
+ return false;
+ }
+ if (!preg_match('/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|'
+ .'([A-Za-z0-9]+))$/', $domainPortionParts[$i])) {
+ return false;
+ }
+ if ($i == $max - 1) { // TLD cannot be only numbers
+ if (strlen(preg_replace('/[0-9]/', '', $domainPortionParts[$i])) <= 0) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Check given text length is between defined bounds
+ * @param string $text Text to be checked
+ * @param int $minimum Minimum acceptable length
+ * @param int $maximum Maximum acceptable length
+ * @return bool Whether string is within bounds (inclusive)
+ */
+ protected static function checkTextLength($text, $minimum, $maximum)
+ {
+ // Minimum and maximum are both inclusive
+ $textLength = strlen($text);
+ return ($textLength >= $minimum && $textLength <= $maximum);
+ }
+}
diff --git a/platform/www/vendor/aziraphale/email-address-validator/README.md b/platform/www/vendor/aziraphale/email-address-validator/README.md
new file mode 100644
index 0000000..60bff60
--- /dev/null
+++ b/platform/www/vendor/aziraphale/email-address-validator/README.md
@@ -0,0 +1,59 @@
+Email-Address-Validator
+=======================
+
+This is a fork of [AddedBytes' EmailAddressValidator class](https://code.google.com/p/php-email-address-validation/).
+
+## Changes ##
+Changes include:
+
+- [Composer](https://getcomposer.org/) support
+- Refactored the class to be purely static
+- Opened up methods for checking the "local part" (the bit before the `@`) and the "domain part" (after the `@`)
+to be public methods
+- Additional code style and docblock fixing to properly follow the [PHP-FIG PSR-1](http://www.php-fig.org/psr/psr-1/)
+and [PSR-2](http://www.php-fig.org/psr/psr-2/) documents
+
+Note that this class is still **un-namespaced** - i.e. it's still declared in the global namespace. The `composer.json`
+file is still set up to correctly load it when required, so this shouldn't be a problem in practice - it's just perhaps
+not best-practice.
+
+## Installation ##
+Use [Composer](https://getcomposer.org/):
+```
+php composer.phar require aziraphale/email-address-validator:^2
+```
+
+If you don't want to use Composer (why not?!), just download the `EmailAddressValidator.php` file, save it with your project, and `require` it where needed.
+
+Note that this updated version is **version 2.0.0**. I have kept the original class tagged as **version 1.0.10** (it was the 10th commit to the Google Code svn repository). If you want to use Composer to install the **old** class, simply specify `^1` as the version constraint (which will allow for backwards-compatible changes to be installed, if any get made, while never jumping to my modified class without your direct action):
+```
+php composer.phar require aziraphale/email-address-validator:^1
+```
+
+## Usage ##
+Due to the aforementioned changes, the way of using this class has completely changed. However it has such a small and simple interface that these changes shouldn't be problematic.
+
+As a recap, the **old usage** was like this:
+```php
+$validator = new EmailAddressValidator;
+if ($validator->check_email_address('test@example.org')) {
+ // Email address is technically valid
+}
+```
+
+The **new syntax** is as follows (ensure you have already included Composer's `autoload.php` file!):
+```php
+if (EmailAddressValidator::checkEmailAddress("test@example.org")) {
+ // Email address is technically valid
+}
+```
+
+with a couple of additional methods in case they're helpful:
+```php
+if (EmailAddressValidator::checkLocalPortion("test")) {
+ // "test" is technically a valid string to have before the "@" in an email address
+}
+if (EmailAddressValidator::checkDomainPotion("example.org")) {
+ // "example.org" is technically a valid email address host
+}
+```
diff --git a/platform/www/vendor/composer/ClassLoader.php b/platform/www/vendor/composer/ClassLoader.php
new file mode 100644
index 0000000..fce8549
--- /dev/null
+++ b/platform/www/vendor/composer/ClassLoader.php
@@ -0,0 +1,445 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ * Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Composer\Autoload;
+
+/**
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
+ *
+ * $loader = new \Composer\Autoload\ClassLoader();
+ *
+ * // register classes with namespaces
+ * $loader->add('Symfony\Component', __DIR__.'/component');
+ * $loader->add('Symfony', __DIR__.'/framework');
+ *
+ * // activate the autoloader
+ * $loader->register();
+ *
+ * // to enable searching the include path (eg. for PEAR packages)
+ * $loader->setUseIncludePath(true);
+ *
+ * In this example, if you try to use a class in the Symfony\Component
+ * namespace or one of its children (Symfony\Component\Console for instance),
+ * the autoloader will first look for the class under the component/
+ * directory, and it will then fallback to the framework/ directory if not
+ * found before giving up.
+ *
+ * This class is loosely based on the Symfony UniversalClassLoader.
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ * @see http://www.php-fig.org/psr/psr-0/
+ * @see http://www.php-fig.org/psr/psr-4/
+ */
+class ClassLoader
+{
+ // PSR-4
+ private $prefixLengthsPsr4 = array();
+ private $prefixDirsPsr4 = array();
+ private $fallbackDirsPsr4 = array();
+
+ // PSR-0
+ private $prefixesPsr0 = array();
+ private $fallbackDirsPsr0 = array();
+
+ private $useIncludePath = false;
+ private $classMap = array();
+ private $classMapAuthoritative = false;
+ private $missingClasses = array();
+ private $apcuPrefix;
+
+ public function getPrefixes()
+ {
+ if (!empty($this->prefixesPsr0)) {
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
+ }
+
+ return array();
+ }
+
+ public function getPrefixesPsr4()
+ {
+ return $this->prefixDirsPsr4;
+ }
+
+ public function getFallbackDirs()
+ {
+ return $this->fallbackDirsPsr0;
+ }
+
+ public function getFallbackDirsPsr4()
+ {
+ return $this->fallbackDirsPsr4;
+ }
+
+ public function getClassMap()
+ {
+ return $this->classMap;
+ }
+
+ /**
+ * @param array $classMap Class to filename map
+ */
+ public function addClassMap(array $classMap)
+ {
+ if ($this->classMap) {
+ $this->classMap = array_merge($this->classMap, $classMap);
+ } else {
+ $this->classMap = $classMap;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix, either
+ * appending or prepending to the ones previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 root directories
+ * @param bool $prepend Whether to prepend the directories
+ */
+ public function add($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ if ($prepend) {
+ $this->fallbackDirsPsr0 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr0
+ );
+ } else {
+ $this->fallbackDirsPsr0 = array_merge(
+ $this->fallbackDirsPsr0,
+ (array) $paths
+ );
+ }
+
+ return;
+ }
+
+ $first = $prefix[0];
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
+
+ return;
+ }
+ if ($prepend) {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixesPsr0[$first][$prefix]
+ );
+ } else {
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
+ $this->prefixesPsr0[$first][$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace, either
+ * appending or prepending to the ones previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ * @param bool $prepend Whether to prepend the directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function addPsr4($prefix, $paths, $prepend = false)
+ {
+ if (!$prefix) {
+ // Register directories for the root namespace.
+ if ($prepend) {
+ $this->fallbackDirsPsr4 = array_merge(
+ (array) $paths,
+ $this->fallbackDirsPsr4
+ );
+ } else {
+ $this->fallbackDirsPsr4 = array_merge(
+ $this->fallbackDirsPsr4,
+ (array) $paths
+ );
+ }
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
+ // Register directories for a new namespace.
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ } elseif ($prepend) {
+ // Prepend directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ (array) $paths,
+ $this->prefixDirsPsr4[$prefix]
+ );
+ } else {
+ // Append directories for an already registered namespace.
+ $this->prefixDirsPsr4[$prefix] = array_merge(
+ $this->prefixDirsPsr4[$prefix],
+ (array) $paths
+ );
+ }
+ }
+
+ /**
+ * Registers a set of PSR-0 directories for a given prefix,
+ * replacing any others previously set for this prefix.
+ *
+ * @param string $prefix The prefix
+ * @param array|string $paths The PSR-0 base directories
+ */
+ public function set($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr0 = (array) $paths;
+ } else {
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Registers a set of PSR-4 directories for a given namespace,
+ * replacing any others previously set for this namespace.
+ *
+ * @param string $prefix The prefix/namespace, with trailing '\\'
+ * @param array|string $paths The PSR-4 base directories
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function setPsr4($prefix, $paths)
+ {
+ if (!$prefix) {
+ $this->fallbackDirsPsr4 = (array) $paths;
+ } else {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
+ }
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
+ }
+ }
+
+ /**
+ * Turns on searching the include path for class files.
+ *
+ * @param bool $useIncludePath
+ */
+ public function setUseIncludePath($useIncludePath)
+ {
+ $this->useIncludePath = $useIncludePath;
+ }
+
+ /**
+ * Can be used to check if the autoloader uses the include path to check
+ * for classes.
+ *
+ * @return bool
+ */
+ public function getUseIncludePath()
+ {
+ return $this->useIncludePath;
+ }
+
+ /**
+ * Turns off searching the prefix and fallback directories for classes
+ * that have not been registered with the class map.
+ *
+ * @param bool $classMapAuthoritative
+ */
+ public function setClassMapAuthoritative($classMapAuthoritative)
+ {
+ $this->classMapAuthoritative = $classMapAuthoritative;
+ }
+
+ /**
+ * Should class lookup fail if not found in the current class map?
+ *
+ * @return bool
+ */
+ public function isClassMapAuthoritative()
+ {
+ return $this->classMapAuthoritative;
+ }
+
+ /**
+ * APCu prefix to use to cache found/not-found classes, if the extension is enabled.
+ *
+ * @param string|null $apcuPrefix
+ */
+ public function setApcuPrefix($apcuPrefix)
+ {
+ $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
+ }
+
+ /**
+ * The APCu prefix in use, or null if APCu caching is not enabled.
+ *
+ * @return string|null
+ */
+ public function getApcuPrefix()
+ {
+ return $this->apcuPrefix;
+ }
+
+ /**
+ * Registers this instance as an autoloader.
+ *
+ * @param bool $prepend Whether to prepend the autoloader or not
+ */
+ public function register($prepend = false)
+ {
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
+ }
+
+ /**
+ * Unregisters this instance as an autoloader.
+ */
+ public function unregister()
+ {
+ spl_autoload_unregister(array($this, 'loadClass'));
+ }
+
+ /**
+ * Loads the given class or interface.
+ *
+ * @param string $class The name of the class
+ * @return bool|null True if loaded, null otherwise
+ */
+ public function loadClass($class)
+ {
+ if ($file = $this->findFile($class)) {
+ includeFile($file);
+
+ return true;
+ }
+ }
+
+ /**
+ * Finds the path to the file where the class is defined.
+ *
+ * @param string $class The name of the class
+ *
+ * @return string|false The path if found, false otherwise
+ */
+ public function findFile($class)
+ {
+ // class map lookup
+ if (isset($this->classMap[$class])) {
+ return $this->classMap[$class];
+ }
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
+ return false;
+ }
+ if (null !== $this->apcuPrefix) {
+ $file = apcu_fetch($this->apcuPrefix.$class, $hit);
+ if ($hit) {
+ return $file;
+ }
+ }
+
+ $file = $this->findFileWithExtension($class, '.php');
+
+ // Search for Hack files if we are running on HHVM
+ if (false === $file && defined('HHVM_VERSION')) {
+ $file = $this->findFileWithExtension($class, '.hh');
+ }
+
+ if (null !== $this->apcuPrefix) {
+ apcu_add($this->apcuPrefix.$class, $file);
+ }
+
+ if (false === $file) {
+ // Remember that this class does not exist.
+ $this->missingClasses[$class] = true;
+ }
+
+ return $file;
+ }
+
+ private function findFileWithExtension($class, $ext)
+ {
+ // PSR-4 lookup
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
+
+ $first = $class[0];
+ if (isset($this->prefixLengthsPsr4[$first])) {
+ $subPath = $class;
+ while (false !== $lastPos = strrpos($subPath, '\\')) {
+ $subPath = substr($subPath, 0, $lastPos);
+ $search = $subPath . '\\';
+ if (isset($this->prefixDirsPsr4[$search])) {
+ $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
+ foreach ($this->prefixDirsPsr4[$search] as $dir) {
+ if (file_exists($file = $dir . $pathEnd)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-4 fallback dirs
+ foreach ($this->fallbackDirsPsr4 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 lookup
+ if (false !== $pos = strrpos($class, '\\')) {
+ // namespaced class name
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
+ } else {
+ // PEAR-like class name
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
+ }
+
+ if (isset($this->prefixesPsr0[$first])) {
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
+ if (0 === strpos($class, $prefix)) {
+ foreach ($dirs as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+ }
+ }
+ }
+
+ // PSR-0 fallback dirs
+ foreach ($this->fallbackDirsPsr0 as $dir) {
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
+ return $file;
+ }
+ }
+
+ // PSR-0 include paths.
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
+ return $file;
+ }
+
+ return false;
+ }
+}
+
+/**
+ * Scope isolated include.
+ *
+ * Prevents access to $this/self from included files.
+ */
+function includeFile($file)
+{
+ include $file;
+}
diff --git a/platform/www/vendor/composer/LICENSE b/platform/www/vendor/composer/LICENSE
new file mode 100644
index 0000000..f27399a
--- /dev/null
+++ b/platform/www/vendor/composer/LICENSE
@@ -0,0 +1,21 @@
+
+Copyright (c) Nils Adermann, Jordi Boggiano
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is furnished
+to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
diff --git a/platform/www/vendor/composer/autoload_classmap.php b/platform/www/vendor/composer/autoload_classmap.php
new file mode 100644
index 0000000..5380367
--- /dev/null
+++ b/platform/www/vendor/composer/autoload_classmap.php
@@ -0,0 +1,35 @@
+<?php
+
+// autoload_classmap.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'AtomCreator03' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/AtomCreator03.php',
+ 'AtomCreator10' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/AtomCreator10.php',
+ 'FeedCreator' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/FeedCreator.php',
+ 'FeedDate' => $vendorDir . '/openpsa/universalfeedcreator/lib/Element/FeedDate.php',
+ 'FeedHtmlField' => $vendorDir . '/openpsa/universalfeedcreator/lib/Element/FeedHtmlField.php',
+ 'FeedImage' => $vendorDir . '/openpsa/universalfeedcreator/lib/Element/FeedImage.php',
+ 'FeedItem' => $vendorDir . '/openpsa/universalfeedcreator/lib/Element/FeedItem.php',
+ 'GPXCreator' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/GPXCreator.php',
+ 'GeSHi' => $vendorDir . '/geshi/geshi/src/geshi.php',
+ 'HTMLCreator' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/HTMLCreator.php',
+ 'HtmlDescribable' => $vendorDir . '/openpsa/universalfeedcreator/lib/Element/HtmlDescribable.php',
+ 'JSCreator' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/JSCreator.php',
+ 'KMLCreator' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/KMLCreator.php',
+ 'MBOXCreator' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/MBOXCreator.php',
+ 'OPMLCreator' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/OPMLCreator.php',
+ 'PHPCreator' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/PHPCreator.php',
+ 'PIECreator01' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/PIECreator01.php',
+ 'RSSCreator091' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/RSSCreator091.php',
+ 'RSSCreator10' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/RSSCreator10.php',
+ 'RSSCreator20' => $vendorDir . '/openpsa/universalfeedcreator/lib/Creator/RSSCreator20.php',
+ 'UniversalFeedCreator' => $vendorDir . '/openpsa/universalfeedcreator/lib/UniversalFeedCreator.php',
+ 'lessc' => $vendorDir . '/marcusschwarz/lesserphp/lessc.inc.php',
+ 'lessc_formatter_classic' => $vendorDir . '/marcusschwarz/lesserphp/lessc.inc.php',
+ 'lessc_formatter_compressed' => $vendorDir . '/marcusschwarz/lesserphp/lessc.inc.php',
+ 'lessc_formatter_lessjs' => $vendorDir . '/marcusschwarz/lesserphp/lessc.inc.php',
+ 'lessc_parser' => $vendorDir . '/marcusschwarz/lesserphp/lessc.inc.php',
+);
diff --git a/platform/www/vendor/composer/autoload_files.php b/platform/www/vendor/composer/autoload_files.php
new file mode 100644
index 0000000..403be68
--- /dev/null
+++ b/platform/www/vendor/composer/autoload_files.php
@@ -0,0 +1,12 @@
+<?php
+
+// autoload_files.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'fdc0e9724ddc47859c8bf0c1ea0a623a' => $vendorDir . '/openpsa/universalfeedcreator/lib/constants.php',
+ '5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
+ 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
+);
diff --git a/platform/www/vendor/composer/autoload_namespaces.php b/platform/www/vendor/composer/autoload_namespaces.php
new file mode 100644
index 0000000..6a43fa5
--- /dev/null
+++ b/platform/www/vendor/composer/autoload_namespaces.php
@@ -0,0 +1,11 @@
+<?php
+
+// autoload_namespaces.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'SimplePie' => array($vendorDir . '/simplepie/simplepie/library'),
+ 'EmailAddressValidator' => array($vendorDir . '/aziraphale/email-address-validator'),
+);
diff --git a/platform/www/vendor/composer/autoload_psr4.php b/platform/www/vendor/composer/autoload_psr4.php
new file mode 100644
index 0000000..3a072f7
--- /dev/null
+++ b/platform/www/vendor/composer/autoload_psr4.php
@@ -0,0 +1,12 @@
+<?php
+
+// autoload_psr4.php @generated by Composer
+
+$vendorDir = dirname(dirname(__FILE__));
+$baseDir = dirname($vendorDir);
+
+return array(
+ 'splitbrain\\phpcli\\' => array($vendorDir . '/splitbrain/php-cli/src'),
+ 'splitbrain\\PHPArchive\\' => array($vendorDir . '/splitbrain/php-archive/src'),
+ 'phpseclib\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
+);
diff --git a/platform/www/vendor/composer/autoload_real.php b/platform/www/vendor/composer/autoload_real.php
new file mode 100644
index 0000000..99e063b
--- /dev/null
+++ b/platform/www/vendor/composer/autoload_real.php
@@ -0,0 +1,73 @@
+<?php
+
+// autoload_real.php @generated by Composer
+
+class ComposerAutoloaderInita19a915ee98347a0c787119619d2ff9b
+{
+ private static $loader;
+
+ public static function loadClassLoader($class)
+ {
+ if ('Composer\Autoload\ClassLoader' === $class) {
+ require __DIR__ . '/ClassLoader.php';
+ }
+ }
+
+ /**
+ * @return \Composer\Autoload\ClassLoader
+ */
+ public static function getLoader()
+ {
+ if (null !== self::$loader) {
+ return self::$loader;
+ }
+
+ spl_autoload_register(array('ComposerAutoloaderInita19a915ee98347a0c787119619d2ff9b', 'loadClassLoader'), true, true);
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
+ spl_autoload_unregister(array('ComposerAutoloaderInita19a915ee98347a0c787119619d2ff9b', 'loadClassLoader'));
+
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
+ if ($useStaticLoader) {
+ require_once __DIR__ . '/autoload_static.php';
+
+ call_user_func(\Composer\Autoload\ComposerStaticInita19a915ee98347a0c787119619d2ff9b::getInitializer($loader));
+ } else {
+ $map = require __DIR__ . '/autoload_namespaces.php';
+ foreach ($map as $namespace => $path) {
+ $loader->set($namespace, $path);
+ }
+
+ $map = require __DIR__ . '/autoload_psr4.php';
+ foreach ($map as $namespace => $path) {
+ $loader->setPsr4($namespace, $path);
+ }
+
+ $classMap = require __DIR__ . '/autoload_classmap.php';
+ if ($classMap) {
+ $loader->addClassMap($classMap);
+ }
+ }
+
+ $loader->register(true);
+
+ if ($useStaticLoader) {
+ $includeFiles = Composer\Autoload\ComposerStaticInita19a915ee98347a0c787119619d2ff9b::$files;
+ } else {
+ $includeFiles = require __DIR__ . '/autoload_files.php';
+ }
+ foreach ($includeFiles as $fileIdentifier => $file) {
+ composerRequirea19a915ee98347a0c787119619d2ff9b($fileIdentifier, $file);
+ }
+
+ return $loader;
+ }
+}
+
+function composerRequirea19a915ee98347a0c787119619d2ff9b($fileIdentifier, $file)
+{
+ if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
+ require $file;
+
+ $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
+ }
+}
diff --git a/platform/www/vendor/composer/autoload_static.php b/platform/www/vendor/composer/autoload_static.php
new file mode 100644
index 0000000..db89c9e
--- /dev/null
+++ b/platform/www/vendor/composer/autoload_static.php
@@ -0,0 +1,98 @@
+<?php
+
+// autoload_static.php @generated by Composer
+
+namespace Composer\Autoload;
+
+class ComposerStaticInita19a915ee98347a0c787119619d2ff9b
+{
+ public static $files = array (
+ 'fdc0e9724ddc47859c8bf0c1ea0a623a' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/constants.php',
+ '5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
+ 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php',
+ );
+
+ public static $prefixLengthsPsr4 = array (
+ 's' =>
+ array (
+ 'splitbrain\\phpcli\\' => 18,
+ 'splitbrain\\PHPArchive\\' => 22,
+ ),
+ 'p' =>
+ array (
+ 'phpseclib\\' => 10,
+ ),
+ );
+
+ public static $prefixDirsPsr4 = array (
+ 'splitbrain\\phpcli\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/splitbrain/php-cli/src',
+ ),
+ 'splitbrain\\PHPArchive\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/splitbrain/php-archive/src',
+ ),
+ 'phpseclib\\' =>
+ array (
+ 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib',
+ ),
+ );
+
+ public static $prefixesPsr0 = array (
+ 'S' =>
+ array (
+ 'SimplePie' =>
+ array (
+ 0 => __DIR__ . '/..' . '/simplepie/simplepie/library',
+ ),
+ ),
+ 'E' =>
+ array (
+ 'EmailAddressValidator' =>
+ array (
+ 0 => __DIR__ . '/..' . '/aziraphale/email-address-validator',
+ ),
+ ),
+ );
+
+ public static $classMap = array (
+ 'AtomCreator03' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/AtomCreator03.php',
+ 'AtomCreator10' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/AtomCreator10.php',
+ 'FeedCreator' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/FeedCreator.php',
+ 'FeedDate' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Element/FeedDate.php',
+ 'FeedHtmlField' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Element/FeedHtmlField.php',
+ 'FeedImage' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Element/FeedImage.php',
+ 'FeedItem' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Element/FeedItem.php',
+ 'GPXCreator' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/GPXCreator.php',
+ 'GeSHi' => __DIR__ . '/..' . '/geshi/geshi/src/geshi.php',
+ 'HTMLCreator' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/HTMLCreator.php',
+ 'HtmlDescribable' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Element/HtmlDescribable.php',
+ 'JSCreator' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/JSCreator.php',
+ 'KMLCreator' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/KMLCreator.php',
+ 'MBOXCreator' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/MBOXCreator.php',
+ 'OPMLCreator' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/OPMLCreator.php',
+ 'PHPCreator' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/PHPCreator.php',
+ 'PIECreator01' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/PIECreator01.php',
+ 'RSSCreator091' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/RSSCreator091.php',
+ 'RSSCreator10' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/RSSCreator10.php',
+ 'RSSCreator20' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/Creator/RSSCreator20.php',
+ 'UniversalFeedCreator' => __DIR__ . '/..' . '/openpsa/universalfeedcreator/lib/UniversalFeedCreator.php',
+ 'lessc' => __DIR__ . '/..' . '/marcusschwarz/lesserphp/lessc.inc.php',
+ 'lessc_formatter_classic' => __DIR__ . '/..' . '/marcusschwarz/lesserphp/lessc.inc.php',
+ 'lessc_formatter_compressed' => __DIR__ . '/..' . '/marcusschwarz/lesserphp/lessc.inc.php',
+ 'lessc_formatter_lessjs' => __DIR__ . '/..' . '/marcusschwarz/lesserphp/lessc.inc.php',
+ 'lessc_parser' => __DIR__ . '/..' . '/marcusschwarz/lesserphp/lessc.inc.php',
+ );
+
+ public static function getInitializer(ClassLoader $loader)
+ {
+ return \Closure::bind(function () use ($loader) {
+ $loader->prefixLengthsPsr4 = ComposerStaticInita19a915ee98347a0c787119619d2ff9b::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInita19a915ee98347a0c787119619d2ff9b::$prefixDirsPsr4;
+ $loader->prefixesPsr0 = ComposerStaticInita19a915ee98347a0c787119619d2ff9b::$prefixesPsr0;
+ $loader->classMap = ComposerStaticInita19a915ee98347a0c787119619d2ff9b::$classMap;
+
+ }, null, ClassLoader::class);
+ }
+}
diff --git a/platform/www/vendor/composer/installed.json b/platform/www/vendor/composer/installed.json
new file mode 100644
index 0000000..0f7031d
--- /dev/null
+++ b/platform/www/vendor/composer/installed.json
@@ -0,0 +1,531 @@
+[
+ {
+ "name": "aziraphale/email-address-validator",
+ "version": "2.0.1",
+ "version_normalized": "2.0.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/aziraphale/email-address-validator.git",
+ "reference": "fa25bc22c1c0b6491657c91473fae3e40719a650"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/aziraphale/email-address-validator/zipball/fa25bc22c1c0b6491657c91473fae3e40719a650",
+ "reference": "fa25bc22c1c0b6491657c91473fae3e40719a650",
+ "shasum": ""
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7"
+ },
+ "time": "2017-05-22T14:05:57+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "EmailAddressValidator": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Dave Child",
+ "email": "dave@addedbytes.com"
+ },
+ {
+ "name": "Andrew Gillard",
+ "email": "andrew@lorddeath.net"
+ }
+ ],
+ "description": "Fork of AddedBytes' PHP EmailAddressValidator script, now with Composer support!",
+ "homepage": "https://github.com/aziraphale/email-address-validator"
+ },
+ {
+ "name": "geshi/geshi",
+ "version": "dev-master",
+ "version_normalized": "9999999-dev",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/GeSHi/geshi-1.0.git",
+ "reference": "3c12a7931d509c5e3557c5ed44c9a32e9c917c7d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/GeSHi/geshi-1.0/zipball/3c12a7931d509c5e3557c5ed44c9a32e9c917c7d",
+ "reference": "3c12a7931d509c5e3557c5ed44c9a32e9c917c7d",
+ "shasum": ""
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.2"
+ },
+ "time": "2020-06-22T15:46:04+00:00",
+ "type": "library",
+ "installation-source": "source",
+ "autoload": {
+ "classmap": [
+ "src/geshi/",
+ "src/geshi.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "GPL-2.0+"
+ ],
+ "authors": [
+ {
+ "name": "Benny Baumann",
+ "email": "BenBE@geshi.org",
+ "homepage": "http://blog.benny-baumann.de/",
+ "role": "Developer"
+ }
+ ],
+ "description": "Generic Syntax Highlighter",
+ "homepage": "http://qbnz.com/highlighter/"
+ },
+ {
+ "name": "marcusschwarz/lesserphp",
+ "version": "v0.5.4",
+ "version_normalized": "0.5.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/MarcusSchwarz/lesserphp.git",
+ "reference": "3a0f5ae0d63cbb661b5f4afd2f96875e73b3ad7e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/MarcusSchwarz/lesserphp/zipball/3a0f5ae0d63cbb661b5f4afd2f96875e73b3ad7e",
+ "reference": "3a0f5ae0d63cbb661b5f4afd2f96875e73b3ad7e",
+ "shasum": ""
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.3"
+ },
+ "time": "2020-01-19T19:18:49+00:00",
+ "bin": [
+ "plessc"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.5.1-dev"
+ }
+ },
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "lessc.inc.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT",
+ "GPL-3.0"
+ ],
+ "authors": [
+ {
+ "name": "Leaf Corcoran",
+ "email": "leafot@gmail.com",
+ "homepage": "http://leafo.net"
+ },
+ {
+ "name": "Marcus Schwarz",
+ "email": "github@maswaba.de",
+ "homepage": "https://www.maswaba.de"
+ }
+ ],
+ "description": "lesserphp is a compiler for LESS written in PHP based on leafo's lessphp.",
+ "homepage": "http://leafo.net/lessphp/"
+ },
+ {
+ "name": "openpsa/universalfeedcreator",
+ "version": "v1.8.3.2",
+ "version_normalized": "1.8.3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/flack/UniversalFeedCreator.git",
+ "reference": "906745196469b13ceefa6523ef04851a78ad10f4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/flack/UniversalFeedCreator/zipball/906745196469b13ceefa6523ef04851a78ad10f4",
+ "reference": "906745196469b13ceefa6523ef04851a78ad10f4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "*"
+ },
+ "time": "2019-09-01T17:49:46+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "classmap": [
+ "lib"
+ ],
+ "files": [
+ "lib/constants.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Andreas Flack",
+ "email": "flack@contentcontrol-berlin.de",
+ "homepage": "http://www.contentcontrol-berlin.de/"
+ }
+ ],
+ "description": "RSS and Atom feed generator by Kai Blankenhorn",
+ "keywords": [
+ "atom",
+ "georss",
+ "gpx",
+ "opml",
+ "pie",
+ "rss"
+ ]
+ },
+ {
+ "name": "paragonie/random_compat",
+ "version": "v2.0.18",
+ "version_normalized": "2.0.18.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/paragonie/random_compat.git",
+ "reference": "0a58ef6e3146256cc3dc7cc393927bcc7d1b72db"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/0a58ef6e3146256cc3dc7cc393927bcc7d1b72db",
+ "reference": "0a58ef6e3146256cc3dc7cc393927bcc7d1b72db",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.*|5.*"
+ },
+ "suggest": {
+ "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
+ },
+ "time": "2019-01-03T20:59:08+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "files": [
+ "lib/random.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paragon Initiative Enterprises",
+ "email": "security@paragonie.com",
+ "homepage": "https://paragonie.com"
+ }
+ ],
+ "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
+ "keywords": [
+ "csprng",
+ "polyfill",
+ "pseudorandom",
+ "random"
+ ]
+ },
+ {
+ "name": "phpseclib/phpseclib",
+ "version": "2.0.27",
+ "version_normalized": "2.0.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpseclib/phpseclib.git",
+ "reference": "34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc",
+ "reference": "34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phing/phing": "~2.7",
+ "phpunit/phpunit": "^4.8.35|^5.7|^6.0",
+ "sami/sami": "~2.0",
+ "squizlabs/php_codesniffer": "~2.0"
+ },
+ "suggest": {
+ "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.",
+ "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.",
+ "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.",
+ "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations."
+ },
+ "time": "2020-04-04T23:17:33+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "files": [
+ "phpseclib/bootstrap.php"
+ ],
+ "psr-4": {
+ "phpseclib\\": "phpseclib/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jim Wigginton",
+ "email": "terrafrost@php.net",
+ "role": "Lead Developer"
+ },
+ {
+ "name": "Patrick Monnerat",
+ "email": "pm@datasphere.ch",
+ "role": "Developer"
+ },
+ {
+ "name": "Andreas Fischer",
+ "email": "bantu@phpbb.com",
+ "role": "Developer"
+ },
+ {
+ "name": "Hans-Jürgen Petrich",
+ "email": "petrich@tronic-media.com",
+ "role": "Developer"
+ },
+ {
+ "name": "Graham Campbell",
+ "email": "graham@alt-three.com",
+ "role": "Developer"
+ }
+ ],
+ "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.",
+ "homepage": "http://phpseclib.sourceforge.net",
+ "keywords": [
+ "BigInteger",
+ "aes",
+ "asn.1",
+ "asn1",
+ "blowfish",
+ "crypto",
+ "cryptography",
+ "encryption",
+ "rsa",
+ "security",
+ "sftp",
+ "signature",
+ "signing",
+ "ssh",
+ "twofish",
+ "x.509",
+ "x509"
+ ],
+ "funding": [
+ {
+ "url": "https://github.com/terrafrost",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/phpseclib",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib",
+ "type": "tidelift"
+ }
+ ]
+ },
+ {
+ "name": "simplepie/simplepie",
+ "version": "1.5.5",
+ "version_normalized": "1.5.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/simplepie/simplepie.git",
+ "reference": "ae49e2201b6da9c808e5dac437aca356a11831b4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/simplepie/simplepie/zipball/ae49e2201b6da9c808e5dac437aca356a11831b4",
+ "reference": "ae49e2201b6da9c808e5dac437aca356a11831b4",
+ "shasum": ""
+ },
+ "require": {
+ "ext-pcre": "*",
+ "ext-xml": "*",
+ "ext-xmlreader": "*",
+ "php": ">=5.6.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~5.4.3 || ~6.5"
+ },
+ "suggest": {
+ "ext-curl": "",
+ "ext-iconv": "",
+ "ext-intl": "",
+ "ext-mbstring": "",
+ "mf2/mf2": "Microformat module that allows for parsing HTML for microformats"
+ },
+ "time": "2020-05-01T12:23:14+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-0": {
+ "SimplePie": "library"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Ryan Parman",
+ "homepage": "http://ryanparman.com/",
+ "role": "Creator, alumnus developer"
+ },
+ {
+ "name": "Sam Sneddon",
+ "homepage": "https://gsnedders.com/",
+ "role": "Alumnus developer"
+ },
+ {
+ "name": "Ryan McCue",
+ "email": "me@ryanmccue.info",
+ "homepage": "http://ryanmccue.info/",
+ "role": "Developer"
+ }
+ ],
+ "description": "A simple Atom/RSS parsing library for PHP",
+ "homepage": "http://simplepie.org/",
+ "keywords": [
+ "atom",
+ "feeds",
+ "rss"
+ ]
+ },
+ {
+ "name": "splitbrain/php-archive",
+ "version": "1.1.1",
+ "version_normalized": "1.1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/splitbrain/php-archive.git",
+ "reference": "10d89013572ba1f4d4ad7fcb74860242f4c3860b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/splitbrain/php-archive/zipball/10d89013572ba1f4d4ad7fcb74860242f4c3860b",
+ "reference": "10d89013572ba1f4d4ad7fcb74860242f4c3860b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4"
+ },
+ "require-dev": {
+ "ext-bz2": "*",
+ "ext-zip": "*",
+ "mikey179/vfsstream": "^1.6",
+ "phpunit/phpunit": "^4.8"
+ },
+ "suggest": {
+ "ext-iconv": "Used for proper filename encode handling",
+ "ext-mbstring": "Can be used alternatively for handling filename encoding"
+ },
+ "time": "2018-09-09T12:13:53+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "splitbrain\\PHPArchive\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Andreas Gohr",
+ "email": "andi@splitbrain.org"
+ }
+ ],
+ "description": "Pure-PHP implementation to read and write TAR and ZIP archives",
+ "keywords": [
+ "archive",
+ "extract",
+ "tar",
+ "unpack",
+ "unzip",
+ "zip"
+ ]
+ },
+ {
+ "name": "splitbrain/php-cli",
+ "version": "1.1.7",
+ "version_normalized": "1.1.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/splitbrain/php-cli.git",
+ "reference": "fb4f888866d090b10e3e68292d197ca274cea626"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/splitbrain/php-cli/zipball/fb4f888866d090b10e3e68292d197ca274cea626",
+ "reference": "fb4f888866d090b10e3e68292d197ca274cea626",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.5.*"
+ },
+ "suggest": {
+ "psr/log": "Allows you to make the CLI available as PSR-3 logger"
+ },
+ "time": "2019-12-12T08:24:54+00:00",
+ "type": "library",
+ "installation-source": "dist",
+ "autoload": {
+ "psr-4": {
+ "splitbrain\\phpcli\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Andreas Gohr",
+ "email": "andi@splitbrain.org"
+ }
+ ],
+ "description": "Easy command line scripts for PHP with opt parsing and color output. No dependencies",
+ "keywords": [
+ "argparse",
+ "cli",
+ "command line",
+ "console",
+ "getopt",
+ "optparse",
+ "terminal"
+ ]
+ }
+]
diff --git a/platform/www/vendor/geshi/geshi/BUGS b/platform/www/vendor/geshi/geshi/BUGS
new file mode 100644
index 0000000..8a5cf04
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/BUGS
@@ -0,0 +1,29 @@
+
+ BUGS - list of known bugs in GeSHi
+ Version 1.0.8
+
+- Number highlighting is quite poor [possibly better now]
+- I'm not happy with URLS - there still could be extra bugs, and it's rather unflexible
+ (see TODO for a possible fix)
+- "Important" sections for some reason seem to have their spans added after every
+ newline up until the next lexic, instead of stopping at the <END GeSHi> part. In fact,
+ context sensitiveness is quite poor...
+- Using the extra line number highlighting feature without actually using line numbers
+ will result in malformed XHTML (not sure about this one though...)
+- Slow!!! Especially for source with lots of strings in it. GeSHi will work acceptably
+ for sourcecode under 5K (for simple language files like SQL, a 100K file can be
+ highlighted in just 6 seconds), but above about 25K things get a little slow... If
+ you're using this as part of some larger software, you may want to think about
+ making some sort of "cache" effect to speed things up and reduce server load.
+- The result is built by string replacement instead of by building another string based
+ on the source, that would be much safer. The focus of releases beyond 1.0.7 will be on
+ changing this behaviour, which may well fix some of the other bugs mentioned above.
+- As of 1.0.7.1, dots (.) are allowed before keywords. This may change highlighting of some
+ things slightly, if you notice anything odd about the highlighting then please report
+ it to me.
+- Perl/Javascript /.../ regex syntax is only supported basically and there's no
+ guarantee it is working all the time.
+- The <pre> header output is not XHTML compliant. Please use the <div> header instead.
+
+Send any bug reports to BenBE@omorphia.de, or submit them via the bug tracker at
+sourceforge (http://sourceforge.net/tracker/?group_id=114997&atid=670231)
diff --git a/platform/www/vendor/geshi/geshi/CHANGELOG b/platform/www/vendor/geshi/geshi/CHANGELOG
new file mode 100644
index 0000000..93fa76c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/CHANGELOG
@@ -0,0 +1,1033 @@
+
+ CHANGES - Changelog for GeSHi (geshi.php only)
+
+Changes to the code are listed under the version they occurred in, with who suggested
+it by each one (if there's nobody listed as suggesting it I dreamed it up :)). Users
+who suggested an idea often also provided the code that was used as a basis for the
+changes - thanks to all who suggested these ideas and gave me the code to show me how!
+
+Language files listed under each version were made by the author beside them, and then
+modified by me for consistency/bug fixing.
+
+Please send any bug reports to BenBE@omorphia.de, or use the bug report tracker
+at sourceforge (http://sourceforge.net/tracker/?group_id=114997&atid=670231)
+
+Version 1.0.9.1
+ - Added language files
+ * OpenSSH config (Kevin Ernst)
+ * roff (Artur Iwicki)
+ * Wolfram (Mysterious Light)
+ - Some minor tweaks for RFC822 email support (BenBE)
+ - Introduce strip_language function (phy25)
+ - Recognize additional file extensions (RealityRipple)
+ - Code style update by avoiding create_function (cweiske)
+ - Backported CLI tool from GeSHi 1.1 branch (cweiske)
+ - Improvements to language files
+ * bash: Update list of keywords (apjanke)
+ * Haskell: Updated doc links and types from Prelude (Jeremy Singer)
+ * INI files: support single quotes (peterdd)
+ * Matlab: Add keywords and functions from recent Matlab releases (apjanke)
+ * MySQL: Some missing keywords (Abu3safeer)
+ * MySQL: Updated documentation links (splitbrain)
+ * R/S+: Fix broken linking of keywords (BenBE)
+ * SciLab: Fix broken linking of keywords (BenBE)
+ * SQL: Some missing keywords (peterdd)
+Version 1.0.9.0
+ - Add public/protected method & property visibility.
+ THIS MAY BREAK YOUR CODE
+ - Restructure git repository
+ - Compatible with PHP7
+ - Remove PHP4 compatibility code
+Version 1.0.8.13
+ - Added language files
+ * Ceylon (Lucas Werkmeister)
+ * eggdrop (CrazyCat)
+ * Julia (Curtis Vogt)
+ * Kotlin (Ole Kristian Sandum)
+ * Mathematica (Connor Glosser)
+ * Mercury (Sebastian Godelet)
+ * MetaPost (Maxime Chupin)
+ * phix (Pete Lomax)
+ * SASS (Javier Eguiluz)
+ * Swift (Ken Woo)
+ * TeXgraph (Patrick Fradin)
+ * Twig templates (Javier Eguiluz)
+ * windows batch (Lev)
+ * Xojo (Massimo Zappino)
+ - Improvements to language files
+ * AutoIt: new version (Jonathan Bennett)
+ * C++11 keywords (Streusel)
+ * CSS attributes (BenBE)
+ * CSS: SVG fill styles (peterdd)
+ * Haskell: Non-standard string highlighting (Evan Czaplicki)
+ * Haskell: Quote mark handling (Sidharth Kapur)
+ * Lua: match comments non-greedily (Jerry)
+ * PowerBuilder: additional encoding constants (Doug Porter)
+ * QML updates (Thibaut Cuvelier)
+ * Qt5 API for C++ language file (neochapay)
+ * SQL: ELSEIF keyword (Kris)
+ * YAML numbers specification (BenBE)
+ - Fix compatibility for PHP 7 (pazuzu156)
+ - Automatically run langcheck when committing code
+Version 1.0.8.12
+ - Added language files
+ * AIMMS (Guido Diepen)
+ * C with WinAPI (BenBE)
+ * C++ with WinAPI (BenBE)
+ * Chapel (Richard Molitor)
+ * Dart (Edward Hart)
+ * EZT (Ramesh Vishveshwar)
+ * ISPF Panel (Ramesh Vishveshwar)
+ * Job Control Language (Ramesh Vishveshwar)
+ * nginx (Cliff Wells, Deoren Moor, Thomas Joiner)
+ * Nimrod (Dennis Felsing)
+ * PostScript (BenBE)
+ * QML (J-P Nurmi)
+ * Racket (Tim Brown)
+ * RBScript (Deng Wen Gang)
+ * Rust (Dave Hodder)
+ * SCL (Leonhard Hösch)
+ * StandardML (eldesh)
+ * VBScript (Rory Prendergast)
+ - Allow for global setup of all keyword and comments style at once using '*' (BenBE)
+ - Non-persistent XSS in example contrib script (BenBE, present in intermediate dev versions)
+ - Fix short tag usage to allow for configurations where short tags are disabled (BenBE)
+ - Updated COPYING to use updated version of GPL 2.0 (BenBE)
+ - Improvements to language files (BenBE)
+ * Updated Documentation Link for LaTeX (Johannes Ähling)
+ * Fix some highlighting problems with Octave (Carnë Draug, Juan Pablo Carbajal)
+ * Fix a minor issue with comments in Visual Basic (Plançon, BenBE)
+ * Some LangCheck issues with Visual Basic (BenBE)
+ * Fix a minor issue with keywords in SQL (Gerrit, BenBE)
+ * Force comments in INI files to be their own line (BenBE)
+ * Fix problem with T-SQL keyword highlighting (James Horsley, BenBE)
+ * Some more keywords for Bash (BenBE)
+ * Updated LSL2 language file (BenBE, Sei Lisa)
+ * Fixed langcheck errors in Lua langfile (BenBE)
+ * Fixed double quotes in Tcl (BenBE, stecue)
+ * Updated PARI/GP language file (Charles R Greathouse IV, BenBE)
+ * Updated Cobol language file (Edward Hart, BenBE)
+ * Updated Verilog language file (Tony Carrillo, BenBE)
+ * Updated Lisp language file (Edward Hart, BenBE)
+ * Updated list of Debian and Ubuntu releases (BenBE)
+ * Implemented C++11 string literal support (BenBE)
+ * Updated list of commands on Bash language file (BenBE)
+ * Updated PHP language file (Levi Morrisson)
+ * Updated Haskell language file (duplode)
+ * Updated NSIS language file (Jan T. Scott, BenBE)
+ * Add raw string support for Rust (mbrown1413)
+ * Fix LangCheck issues with LOLcode language file (mudhailess, BenBE)
+ * Updated LSL2 language file (Sei Lisa, BenBE)
+ * Updated Oxygene language file (Carlo Kok, BenBE)
+ * Fixed TCL comment processing (Sei Lisa)
+ * Fixed C++ (Qt) documentation links (Sei Lisa)
+ * Updated CSS language file to include CSS3 keywords (Zéfling, BenBE))
+Version 1.0.8.11
+ - Added language files
+ * ARM (Marat Dukhan)
+ * Asymptote (Manuel Yguel)
+ * DCL (Petr Hendl)
+ * DCPU-16 (Benny Baumann)
+ * FreeSWITCH (James Rose)
+ * Haxe (Andy Li, John Liao)
+ * LDIF (Bruno Harbulot)
+ * Nagios (Albéric de Pertat)
+ * Octave (Carnë Draug, Juan Pablo Carbajal)
+ * ParaSail (sttaft)
+ * PARI/GP (Charles R Greathouse IV)
+ * Python for S60 (Sohan Basak)
+ * Rexx (Jon Wolfers)
+ * SPARK (Phil Thornley)
+ * SPARQL (Karima Rafes)
+ * StoneScript (Archimmersion)
+ * UPC (Viraj Sinha)
+ * Urbi (Alexandre Morgand)
+ * Vedit (Pauli Lindgren)
+ - Updated aliasd.php contrib script (SF#3073275, count)
+ - Fallback to "text" when extension is unknown (SF#3514714, murkymark, BenBE)
+ - detect extensions case-insensitive (SF#3514714, murkymark, BenBE)
+ - Fixed two bugs within contrib scripts included with each release (BenBE)
+ - Improvements to language files (BenBE)
+ * Symbol and char literal handling for Scala (Paul Butcher, BenBE)
+ * Multiline comments of F# weren't actually multiline (BenBE)
+ * Support for IPv6 addresses in RFC822 messages (BenBE)
+ * Properly handle retrieving names from language files (MikeSee, BenBE)
+ * Changes for improved highlighting of signle line comments and end-of-code indicators
+ * Missing keywords and improved highlighting of comments
+ * Problem with DOS/Batch highlighting breaking out at variables (BenBE)
+ * Addition of MMX/SSE/x86-64 registers and MMX/SSE instructions for
+ ASM language file(up to 4.2) (Dennis Yurichev)
+ * Further improvements to ASM language file to introduce all latest
+ already documented x86 architecture instructions (Marat Dukhan)
+ * Fixed links for R/S+ language file (Fernando H.F.P. da Rosa)
+ * Fix a problem with Delphi/Pascal regarding hex numbers/chars (BenBE)
+ * Fixed a typo and missing keywords for HTML4 and HTML5 (SF#3365452, BenBE)
+ * Fixed a typo in Modula-3 language file (SF#3358216, BenBE)
+ * Added missing keywords for MySQL (SF#3290998, ct-bob, BenBE)
+ * Added missing keywords for Pascal (SF#3176749, BenBE)
+ * Properly detect the keyword that is to be linked (BenBE)
+ * Updated VHDL language file (Kevin Thibedeau)
+ * Added missing keyword for Verilog (SF#3557903, BenBE)
+ * Fixed typo in Haskell causing a keyword to be missing (SF#3529439, BenBE)
+ * Fixed Long String handling for Lua (SF#3541510, Tim Starling)
+ * Updated JavaDoc links for Java language files (SF#3538552, jeneag, BenBE)
+ * CSS keywords incorrectly highlighted as part of identifiers (SF#3554101, BenBE)
+ * CSS3 keywords missing from highlighting (SF#3525084, vlaKoff, BenBE)
+ * Make variable handling compatible to PHP (SF#3489142, BenBE)
+ * Fixed obsolete MySQL documentation links (SF#3441642, BenBE)
+ * Add mising keywords for T-SQL (SF#3435026, BenBE)
+ * Fix discarded text when highlighting TypoScript (SF#3160238, BenBE)
+Version 1.0.8.10
+ - Added language files
+ * BASCOM AVR (Michal Goralczyk)
+ * C: Loadrunner dialect (Stuart Moncrieff)
+ * CoffeeScript (Trevor Burnham)
+ * EPC (Thorsten Muehlfelder)
+ * Euphoria (Nicholas Koceja)
+ * Falcon (billykater)
+ * HTML5 (Robert Lidberg)
+ * LLVM (Azriel Fasten)
+ * PL/I (Robert Prins)
+ * ProFTPd (Benny Baumann)
+ * PyCon (Benny Baumann)
+ * UnrealScript (pospi)
+ * YAML (Josh Ventura)
+ - Small bugfix in LangCheck when looking for language files
+ - Added '-' to list of RX chars that require explicit escaping (SF#3056454, BenBE)
+ - Minor changes to boundary checks (SF#3077256, BenBE)
+ - Improvements to language files (BenBE)
+ * Major rework of the ALGOL68 language file (Neville Dempsey)
+ * LangCheck warnings from GO language file (BenBE)
+ * Some additions to the Objeck language file (Randy Hollines)
+ * Properly highlight infinity as numbers for J (Ric Sherlock)
+ * Improved GDB Backtrace language file (Milian Wolff)
+ * Updated Liberty BASIC language file (Chris Iverson)
+ * Fixed a small issue with detection of division vs. regular expressions
+ for ActionScript 3 and JavaScript (Kevin Day)
+ * Fixed Escape handling for CSS (SF#3080513, yecril71pl, BenBE)
+ * Additional comment styles for SAS (SF#3024708, ahnolds, BenBE)
+ * Updated keyword list for TeraTerm (Boris Maisuradze)
+ * Incorrect handling of /**/ comments in Javascript (BenBE)
+ * Support for mod_upload_progress in Apache Config files (BenBE)
+ * Prefix operator handling in F# was broken (BenBE)
+ * CDATA handling for html4strict (BenBE)
+ * Common subcommands for Apache, APT, CVS, Git, SVN and YUM for Bash (BenBE)
+ * Limited support for prompt detection in single line Bash snippets (BenBE)
+ * Added functions of the C standard library (BenBE)
+ * Rework of Lua to use GeSHi's features better (BenBE)
+ * Language file improvements for Python (Zbyszek Szmek)
+ * Fixed documentation links for Groovy (SF#3152356, lifeisfoo)
+ * Fixed incorrect highlighting of certain keywords in Erlang (SF#3138853, BenBE)
+ * Escape chars in C++/C++Qt handled incorrectly (SF#3122706, C. Pötsch)
+ * Empty parameters of LaTeX commands tipped the highlighting off (SF#3098329, James Oldfield, BenBE)
+ * Additional Keywords and minor tweaks to Logtalk (Paulo Moura)
+Version 1.0.8.9
+ - Added language files
+ * Algol68 (Neville Dempsey)
+ * E (Kevin Reid)
+ * FormulaOne (Juro Bystricky)
+ * Go (Markus Jarderot)
+ * Liberty BASIC (Chris Iverson)
+ * MOS 6502/6510 Assemblers (Warren Willmey)
+ * Motorola 68k assembler (Warren Willmey)
+ * Objeck Programming Language (Randy Hollines)
+ * ZXBasic (Jose Rodriguez)
+ - Added support for $-prefixed hex numbers and @-prefixed octal numbers
+ - Added Parser Control for languages to tell when numbers are present
+ inside of non-string parts
+ - Introduced querying supported/known languages directly
+ - Introduced querying full language names without loading the language file
+ - Improvements to language files (BenBE)
+ * Added loads of keywords for generic SQL highlighting (Jürgen Thomas)
+Version 1.0.8.8
+ - Added language files
+ * ChaiScript (Jason Turner & Jonathan Turner)
+ * Genie (Nicolas Joseph)
+ * GwBasic (José Gabriel Moya Yangüela)
+ * HicEst (Georg Petrich)
+ * Icon (Matt Oates)
+ * MagikSF (Sjoerd van Leent)
+ * Modula 2 (Benjamin Kowarsch)
+ * Oz (Wolfgang Meyer)
+ * PCRE (BenBE)
+ * PostgreSQL (Christophe Chauvet)
+ * q/kdb+ (Ian Roddis)
+ * RPM Specification Files (Paul Grinberg)
+ * Unicon (Matt Oates)
+ * Vala (Nicolas Joseph)
+ * XBasic (José Gabriel Moya Yangüela)
+ - Improvements to language files (BenBE)
+ * Major reworks and improvements to OCaml language file (BenBE)
+ * Removed duplicate entries from keyword groups of VIM language file (Segaja)
+ * Properly protect Regexps against GeSHi Black Magic in Matlab (BenBE)
+ * Added support for Block Comments in PowerShell (BenBE)
+ * Added some keywords for VB; split into multiple groups (leejkennedy, BenBE)
+ * Basic Heredoc Support for Ruby (BenBE)
+Version 1.0.8.7
+ - Added language files
+ * Autoconf (Mihai Vasilian)
+ * ECMAScript (Michel Mariani)
+ * J (Ric Sherlock)
+ * OpenBSD Packet Filter (David Berard)
+ * Oxygene / Delphi Prism (Carlo Kok)
+ - Minor change in INT_BASIC number regexp to support '..' range operator
+ as to be found in most Pascal-like languages (BenBE)
+ - Fixed an issue with Hardquotes for empty strings (like '' in Delphi) (BenBE)
+ - Introduced a fix for improved performance when matching numbers (BenBE)
+ - Improvements to language files (BenBE)
+ * Fixed broken links in Prolog language file (BenBE)
+ * Fixed keywords in generics expressions in Java5 (BenBE)
+ * Added support for import static in Java5 (BenBE)
+ * Added Standard Integer Types for C and c++ (BenBE)
+ * Fixed some regexp issues in Erlang (BenBE)
+ * Added some missing keywords for Clojure (BenBE)
+ * Added some missing keywords for Lisp (BenBE)
+ * Fixed a problem with variable names in Prolog (BenBE)
+ * Some color changes for AutoIt (BenBE)
+ * Added support for basic include directive processing for AutoIt (BenBE)
+ * Added support for ::-style labels as comments (SF#2947393, BenBE)
+ * Removed backslash as Escape Char in T-SQL (SF#2939199, Bruno Braga)
+ * Added Nested Comments Support for Haskell (SF#2922317, BenBE)
+ * Fixed Comments for VIM, added some keywords, proposed porting of
+ Regular Expression markup from Perl (SF#2818047, psycojoker, BenBE)
+ * Fixed warnings for Language Check of Tcl (BenBE)
+Version 1.0.8.6
+ - Added language files
+ * Clojure (Jess Johnson)
+ * Cuesheet (Benny Baumann)
+ * F# (Julien Ortin)
+ * GAMBAS (Jesus Guardon)
+ * Logtalk (Paulo Moura)
+ * MapBasic (Tomasz Berus)
+ * NewLisp (cormullion)
+ * Perl 6 (Kodi Arfer)
+ * Pike (Rick E.)
+ * SystemVerilog (Sean O'Boyle)
+ - Reworked parts of the number support (BenBE)
+ - Improvements to language files (BenBE)
+ * Fixed broken links in R/S+ language file (BenBE)
+ * Fixed an issue with if= argument for dd command (BenBE)
+ * T-SQL should use GESHI_CAPS_NO_CHANGE for keywords (BenBE)
+ * Fixed missed shorthand arg references in Bash (BenBE)
+ * Fixed first line not getting highlighted in diff language (BenBE)
+ * Added some keywords for csharp (RC)
+Version 1.0.8.5
+ - Added language files
+ * AutoHotkey (Naveen Garg)
+ * Awk (George Pollard)
+ * GADV 4CS (Jason Curl)
+ * jQuery (Rob Loach)
+ * PowerBuilder (Doug Porter)
+ * PureBasic (Gustavo Julio Fiorenza)
+ * R / S+ (Ron Fredericks, Benilton Carvalho)
+ - Fixed legitimate numbers sometimes missing from highlighting (BenBE)
+ - Fixed a problem with URLs allowing to break highlighting (BenBE)
+ - Allowed for String and Number Styles to be set by the API (BenBE)
+ - Produce valid CSS when languages start with underscore (BenBE)
+ - Duplicate newlines with PRE_TABLE-Header but w/o linenumbers (SF#2838958, BenBE)
+ - Improvements to language files (BenBE)
+ * Fixed case-insensitively duplicate keywords (BenBE)
+ * DCS language file contained HARDQUOTE section but no hardquotes (BenBE)
+ * Some additional headers for Email\mbox highlighting (BenBE)
+ * Added some more Keywords for robots.txt highlighting (BenBE)
+ * Added Git commands for bash, ifup/ifdown (BenBE)
+ * Added support for C# and VB.net delegates (SF#2832253, BenBE)
+ * Added support for line numbers, file handles and hex\octal numbers for QBasic (BenBE)
+Version 1.0.8.4
+ - Added language files
+ * BibTeX (Quinn Taylor)
+ * CMake (Daniel Nelson)
+ * Erlang (Benny Baumann, Dan Forest-Barbier, Uwe Dauernheim)
+ * FO (abas-ERP) (Tan-Vinh Nguyen)
+ * Property Files (Edy Hinzen)
+ * Whois (RPSL format) entries (Benny Baumann)
+ - Changed INT_BASIC number format to allow numbers followed . at EOL (BenBE)
+ - Higher prority for keywords over regexps (BenBE)
+ - Added missing set_script_style API function (BenBE)
+ - Fixed missing check for comment_regexp preference in HardQuotes (BenBE)
+ - Fixed a problem with Strict Block Detection if the Strict Block Regexp
+ requires matching groups for itself (BenBE)
+ - Improvements to language files (BenBE)
+ * Added PCRE regexp support for Action script (SF#2655644, BenBE)
+ * Removed some superfluous keywords from ABAP (BenBE)
+ * Removed duplicate keywords for Progress (BenBE)
+ * Removed duplicate keywords for T-SQL (BenBE)
+ * Linking for PowerShell special variables revised (BenBE)
+ * Fixed linking in ColdFusion (BenBE)
+ * Fixed linking in LaTeX (BenBE)
+ * Fixed linking in mIRC Scripting language (BenBE)
+ * Fixed escape char regexp for C-style languages (BenBE)
+ * Fixed @""-string handling for C# (SF#2789371, BenBE)
+ * Fixed Strict Block Detection for PHP blocks (BenBE)
+ * Changed allowed chars around Powershell operators (SF#2688863, BenBE)
+ * Minor reordering inside of PHP language file (BenBE)
+ * Added missing keywords for ActionScript3 language file (SF#2795005, BenBE)
+ * Added .xrc file extension for XML highlighting (BenBE)
+Version 1.0.8.3
+ - Added language files
+ * DCS (Stelio Passaris)
+ * Locomotive Basic (Nacho Cabanes)
+ * LSL2 (Linden Scripting Language) (William Fry)
+ * Modula-3 (Martin Bishop)
+ * Oberon-2 (Mike Mol)
+ * Rebol (Lecanu Guillaume)
+ - Fixed a problem where HardEscapes weren't working when no escape char was given (BenBE)
+ - Added a PARSER_CONTROL setting to treat whitespace inside of keywords in
+ the language file as "any whitespace" in the source (i.e. "CREATE TABLE"
+ in SQL will match "CREATE\s+TABLE" instead of literally matching) (BenBE)
+ - Added a possibility to allow setting the style for escape characters (BenBE)
+ - Improvements to language files (BenBE)
+ * Added some missing Perl keywords and obscure default variables (BenBE)
+ * Allow for escaped colons to appear in CSS names (BenBE, simon)
+ * Added multiline continuation suppoert of preprocessor defines for
+ C, C for Mac, C++ and CC++ with Qt support (BenBE)
+ * keywords for C-based languages are case-sensitive (BenBE)
+ * Broken AutoIt highlighting (BenBE)
+ * Problem with escaped backslash in PHP and D (BenBE)
+ * Added some more functions for PHP (BenBE)
+ * Some changes for AppleScript (Stefan Klieme)
+ * Forbid highlighting keywords followed by / in bash (BenBE)
+ * Updated the LaTeX file to link some keywords (BenBE)
+ * Additional text rendered when matching special variables for PowerShell (BenBE)
+ * Added some more keywords for ABAP (BenBE, Sandra Rossi, Jacob Laursen)
+Version 1.0.8.2
+ - Added language files
+ * Brainfuck \ Brainfork (Benny Baumann)
+ * HQ9+ (Benny Baumann)
+ * INTERCAL (Benny Baumann)
+ * LOLcode (Benny Baumann)
+ * LScript (Beau McGuigan)
+ * Pixel Bender (Richard Olsson)
+ * ProvideX (Jeff Wilder)
+ * VIM Script (Swaroop C H)
+ * Visual Prolog (Thomas Linder Puls)
+ * Whitespace (Benny Baumann)
+ - Changed priority for COMMENT_REGEXP compared to String highlighting (BenBE)
+ - Fixed correct escaping of spaces inside of URLs (BenBE)
+ - Updated the list of common file extensions (BenBE)
+ - Updated the language file check script in contrib/ (BenBE)
+ - Fixed a problem with link targets resulting in unclickable links (SF#2379120, BenBE)
+ - Fixed an undefined variable issue in langcheck.php (BenBE)
+ - Improvements to language files (BenBE)
+ * eMail Header highlighting now uses the correct delimiters for keywords (BenBE)
+ * eMail (RFC822\mbox) highlighting now highlights IPs, MIME types and
+ subfield assignments correctly (BenBE)
+ * Minor style changes in COBOL to improve loading performance (BenBE)
+ * Added some missing keywords for D (BenBE)
+ * Removed duplicate keywords from Progres, SAS and TSQL (BenBE)
+ * Fixed Heredoc Syntax for Bash (SF#2185319, BenBE)
+ * Moved symbol-lookalike sequences from keyword groups to separate symbol group
+ for languages asp, klonec, klonecpp, php, php-brief (BenBE)
+ * Fixed a lot of duplicate keyword warnings (BenBE)
+ * Added missing keywords to the Python language file,
+ introducing support for Python 3.0. (SF#2441839, milian)
+ * Updated documentation links for TypoScript (SF#2014276, BenBE)
+ * Fixed a problem with tag and attribute names in XML highlighting (SF#2276119, BenBE)
+ * Improved MySQL language file (BenBE, JavaWoman)
+ * Some commentss accidentially mistaken for DocComments (SF#2454897, BenBE)
+ * Added improved Escape Char handling for c, c_mac, cpp and cpp_qt (SF#2458743, BenBE)
+Version 1.0.8.1
+ - Added language files
+ * AviSynth (Ryan Jones)
+ * eMail \ mbox (Benny Baumann)
+ * GNU Make (Neil Bird)
+ * Oracle 11i support (Simon Redhead)
+ * Prolog (Benny Baumann)
+ * SciLab (Christophe David)
+ * TeraTerm macro language (Boris Maisuradze)
+ - Added support for Escape Regular Expressions (BenBE)
+ * Implemented C-style Escapes in PHP (BenBE)
+ * Introduced support for \xAB and \007 style Char Escapes in PHP (BenBE)
+ * Implemented Variable Highlighting in PHP (BenBE)
+ * Implemented Variable Highlighting in Bash (milian)
+ - Fixed a problem with PCRE patterns for Keyword matching sometimes producing
+ very large strings, that could not be handled by some versions of PCRE lib,
+ causing broken highlighting an Regexp Compile errors (BenBE, milian)
+ - Fixed broken highlighting of bash commands like `dbus-send --dest=org.....`,
+ i.e. the dest was highlighted as variable declaration (milian)
+ - Fixed broken highlighting of some symbols in their escaped form (BenBE)
+ (<SEMI> and <PIPE> were accidentially filtered even though they are valid)
+ - Fixed a "memory leak" in the *_regexp_caches (milian)
+ - Fixed broken Escape chars if classes were disabled
+ - start_line_numbers_at() was ignored when GESHI_HEADER_PRE_TABLE was set (revulo)
+ - Fixed a problem allowing Remote Code Inclusion under certain circumstances (BenBE)
+ - Changes to default CSS in order to make the GESHI_HEADER_PRE_TABLE align properly,
+ even on Windows / Mac systems with strange fonts (milian, revulo, ^RT)
+ - Minor style changes to the following languages:
+ * cpp-qt (milian)
+ * MySQL (BenBE)
+ * PHP (BenBE)
+ - Improvements to language files (BenBE, milian)
+ * Added MinSpareThread\MaxSpareThreads to Apache highlighter (BenBE)
+ * Added new Keyword group for APT sources.list highlighter (BenBE)
+ * Fixed highlighting in LaTeX for \begin{} and \end{}, i.e. the stuff inside
+ the curly braces. (milian, thanks for the report go to Matthias Pospiech)
+ * Improved String support for D (BenBE)
+ * MySQL was seriously broken (BenBE)
+ * Reworked Keyword groups for MySQL to allow for more configuration (BenBE)
+ * Improved Mirc script language file (milian)
+ * Improved C++ Qt language file (milian)
+ * Minor bug with Transpose Operator in Matlab (BenBE, Daniele de Rigo)
+ * Highlighting of Batch Files for Windows (BenBE)
+ * Updated AutoIt to include latest changes for AutoIt v3.2.12.1 (BenBE, Thierry)
+ * Fixed duplicate keyword warnings for Perl, Tcl and Typoscript (BenBE)
+ * Fixed Doc-URL getting reparsed by highlighted keywords of other groups (BenBE, Jordi Boggiano)
+Version 1.0.8
+ - Added language files
+ * APT sources.list (milian)
+ * Boo (Marcus Griep)
+ * CIL (Common Intermediate Language, .NET Assembly) (Marcus Griep)
+ * COBOL (Benny Baumann)
+ * Gnuplot (milian)
+ * KLoneC (Mickael Auger)
+ * KLoneC++ (Mickael Auger)
+ * PIC16xxx assembler (Phil Mattison)
+ * POV-Ray (Carl Fürstenberg)
+ * PowerShell (Frode Aarebrot)
+ * Progress (Marco Aurelio de Pasqual)
+ * TypoScript (Jan-Philipp Halle)
+ * Xorg configuration (milian)
+ - Make GeSHi's constructor arguments optional, so something like `$foo = new GeSHi;` is possible. (milian)
+ - Added an optimizer for lists to regular expressions. Using these cached lists results in a speedup of approx. 50%.
+ The slightly increased memory consumption (~150KB for PHP language file) is more than worth it! (milian)
+ - Some more memory & speed optimizations all over GeSHi (milian)
+ * Reduced memory overhead when highlighting keywords (BenBE)
+ * Keyword Linking now uses considerably less strtolower calls (milian)
+ * Cache Symbol Search Regexp and make Symbol Highlighting faster (milian)
+ * Use more native functions like substr_replace and strcasecmp to speed things up (milian)
+ * Use considerably less strlen() calls on various points by caching the results (milian)
+ * Properly set comments to be case insensitive where appropriate to increase performance (milian)
+ * Improve the performance of the strict mode tokenizer, making highlighting of languages like
+ HTML, ColdFusion or XML faster (milian)
+ * Setup caches for parsing on demand to make stylesheet generators fast (milian)
+ - Various improvements to Strict Block Handling (BenBE, milian)
+ * Added support for RegExp-based Strict Blocks (BenBE)
+ * Fixed highlighting incorrectly stopping at ?> in PHP (SF#1330968, BenBE)
+ * Languages with STRICT_MODE_APPLIES = GESHI_MAYBE default to strict mode now. When no highlightable
+ code is found in this mode, we fallback to the same setting as if GESHI_NEVER was set. That way it
+ should not be needed to call enable_strictmode() manually. (milian)
+ - Added new GESHI_HEADER_PRE_VALID type which uses the following markup: (milian)
+ * With line numbers: <div>header<ol><li><pre>...</pre></li>...</ol></div>
+ * Without line numbers: <pre>header...CODE...</pre>
+ => valid HTML and no need for &nbsp; indentation
+ - Added new GESHI_HEADER_PRE_TABLE type which can be used to prevent linenumber-selection in Firefox
+ on copy'n'paste. (milian)
+ - set_language will not reset any language settings by default anymore.
+ * Added $force_reset param for to force full reload of a language. (milian)
+ * Make sure strict_mode is set properly when doing repeated set_language calls (milian)
+ - Fixed some problems with old PHP versions (SF#1975625, milian, BenBE)
+ - Fixed broken use with Suhosin Patch when /e modifier was disabled (SF#2021800, BenBE)
+ - Added support for external style information files to override language defaults without modifying language files (BenBE)
+ - The overall_class is now up to the user, and the language-code is _always_ added as a class (milian)
+ - Fixed Economy Mode for GeSHi::get_stylesheet() - now it just makes so much more sense! (milian)
+ - Fixed Economy Mode when COMMENT_REGEXP are used (BenBE)
+ - Changed the default encoding to use UTF-8, due to SF#2037598, BenBE)
+ - Improved overall string support:
+ * Added support for multichar string delimiters (SF#1932083, BenBE)
+ * Fixed problems of unfinished strings and comments producing invalid XHTML (SF#1996353, BenBE)
+ * Multichar Quotemarks sometimes had inconsistent behaviour (BenBE)
+ * Support for multiple styles of strings depending on the starter (BenBE)
+ * Properly handle escapes in strings, i.e. '\\' was not working properly before (milian)
+ * Fixed escape char support when an escape char is followed by multi-byte chars (SF#2037598, BenBE)
+ - Improved flexibility in language files (BenBE, milian)
+ * Added PARSER_CONTROL for OOLANG method highlighting (SF#1923060, BenBE)
+ * Added possibility to define strict blocks using an Regexp (BenBE)
+ * Removed explicit escaping of / in Regular Expressions (BenBE)
+ * Ignoring empty keyword groups when highlighting (milian)
+ * Make language_permissions configurable in language files via ['PARSER_CONTROL']['ENABLE_FLAGS']
+ this makes is_a calls unneeded and thus prevents PHP notices in PHP 5.x (milian)
+ * Extended support for number formats now covering the most common formats (SF#1923058, BenBE)
+ * Lifted a limitation that keywords had to have at least 2 subsequent letters (BenBE)
+ * Changed behaviour of PARSER_CONTROL now allowing to provide the full Lookahead and Lookbehind
+ expressions used as delimiters inside keywords instead of a simple char group (BenBE)
+ * Fixed improper handling of newlines in REGEXPS so this does not produce invalid html anylonger (milian)
+ - Some typos and mistakes in the documentation (BenBE)
+ - Added a script to contrib/ to verify language files are correct (BenBE)
+ - Fixed loads of compliancy warnings detected with that automated compliance testing script (BenBE)
+ - Many other improvements to various language files (BenBE, milian)
+ * Reduce strict errors & notices for language files (milian)
+ * Fixed symbol highlighting with C++ sometimes missing keywords after ; and comments (BenBE)
+ * Improved comment handling with TCL (Lars Hellström, BenBE)
+ * Fixed broken handling with XML comments (BenBE, SF#1849233)
+ * Fixed HTML comments spawning multiple lines producing invalid XHTML output (SF#1738173, BenBE)
+ * Added support for parameters beginning with dash in BASH language (BenBE)
+ * Support Apache's configuration sections, see http://httpd.apache.org/docs/2.2/sections.html (milian)
+ * Minor issue with PHP Heredoc and Nowdoc syntax sometimes not getting highlighted (BenBE)
+ * Updated Objective-C language file (SF#2013961, Quinn Taylor, BenBE)
+ * Added some keywords for VHDL (beshig, BenBE)
+ * Fixed severly broken ColdFusion language file (milian)
+ * Fixed some incorrectly highlighted things with the CSS language file (milian, BenBE)
+ * Improved Smarty language file (milian)
+ * Improved CSS language file (milian)
+ * Improved Pascal language file (milian)
+ * Improved LaTeX language file (Ðндрей Парамонов, BenBE)
+ * Fixed a regular expression in mIRC language file that caused a warning message to be issued (BenBE)
+ * Removed <, > and / from HTML names, now only containing the real tag names (BenBE)
+ * Use spaces instead of tabs for indendation in language files to have a consistent
+ coding standard accross geshi files (milian)
+ * Added some comment styles, keywords and added index highlighting (Chusslove Illich, ЧаÑлав Илић)
+ - Removed some private methods which were only called at exactly one place (milian)
+ * format_header_content
+ * format_footer_content
+ * get_attributes
+ - Second part of default style changes. Affected in this release:
+ * C++
+ * C++ (Qt)
+ * CSS
+ * VHDL
+Version 1.0.7.22
+ - Added language files
+ * glSlang (BenBE)
+ * KiXtart (Riley McArdle)
+ * Lotus Notes @Formulas (Richard Civil)
+ * LotusScript (Richard Civil)
+ * MXML (David Spurr)
+ * Scala (Franco Lombardo)
+ * ActionScript 3 (Jordi Boggiano)
+ * GNU Gettext .po/.pot (Milian Wolff)
+ * Verilog (Günter Dannoritzer)
+ - Fixed a problem not yet addressed in 1.0.7.21 regarding highlighting of
+ symbols that caused some extra characters to be added in the output or
+ broke highlighting and standard compliance due to missing escaping of
+ internally used characters (SF#192320 and SF#1926259, BenBE)
+ - Fixed missing style information for ocaml language file (The_PHP_Jedi)
+ - Fixed a bug causing masses of warnings in rendered output if language file
+ miss style information (The_PHP_Jedi, BenBE)
+ - Missing tab width information could lead to warnings (BenBE)
+ - Missing symbol information for ASP (SF#1952038, nfsupport, BenBE)
+ - Empty delimiter message with OOoBasic (BenBE, Ccornell)
+ - Escaping of comments in LaTeX ignored (SF#1749806, BenBE)
+ - Modified Math environment $$ in LaTeX to be non-greedy (BenBE)
+ - Added possibility to match a regexp as comment (SF#1914640, SF#1945301, SF#1934832, BenBE)
+ - Introduced C-Style multiline continuation comments (SF#1914640, SF#1945301, BenBE)
+ - Introduced Fortran Comments (SF#1914640, SF#1934832, BenBE)
+ - Implemented Heredoc and Nowdoc Syntax for PHP and Perl (SF#1914640, BenBE)
+ - Implemented Compiler Directives for Delphi (SF#1914640, BenBE)
+ - Implemented minimalistic support for JavaScript \ Perl Regular Expressions (SF#1786665, SF#1754333, SF#1956631, BenBE)
+ - Fixed Strings in Matlab to be handled as comments instead of regexps, to prevent keywords being linked (BenBE)
+ - Applied PARSER_CONTROL fix of C++ for C++-Qt-Derivative (BenBE)
+ - Fixed incorrect treatment of unequally long multiline comment separators (related to SF #1891630, BenBE)
+ - Added PARSER_CONTROL settings for keywords in ASM language file (SF#1835148, BenBE)
+ - Fixed missing CASSE_SENSITIVE entry for DOS language file (SF#1956314, BenBE)
+ - Fixed accidential highlighting of keywords in argument names (SF#1956456, Milian Wolff, BenBE)
+ - Fixed yet again some #-related bash problem (SF#1956459, Milian Wolff, BenBE)
+ - Added backticks as symbols (Milian Wolff)
+ - Example script remembers selections and source submitted (Milian Wolff)
+ - Example script allows remembered source and preselected language to be cleared (Milian Wolff)
+ - Example script now properly includes geshi and doesn't suppress error messages anylonger. (Milian Wolff)
+ - Code cleanup by using direct string indexing instead of substr with length 1 (Milian Wolff)
+ - Optimized generation of code parts in strict mode (Milian Wolff)
+ - Optimized COMMENT_REGEXP by using an incremental regexp cache (Milian Wolff, BenBE)
+ - Fixed a problem that rarely skipped highlighting of escaped chars which usually should have gotten highlighted (BenBE)
+ - Optimized generation of highlighted strings to use fast skip forward while highlighting them (Milian Wolff, BenBE)
+ - Optimization using basic rework of indent function improving tab expansion performance (BenBE)
+ - Lots of other minor optimizations based on coding style improvements (Milian Wolff)
+ - Implemented setting to force spans to be closed before newlines, see SF#1727398 (Milian Wolff)
+ - Added missing credits for D language file to THANKS file (SF#1720899, BenBE)
+ - Optimization to prevent loading the current language file twice (Milian Wolff)
+ - Optimization: Use file_get_contents() to load sourcecode from files.
+ Even if GeSHi worked with PHP 4.1 before, it doesn't now. (Milian Wolff)
+ - Added description of extra language features (SF#1970248, BenBE)
+ - Added support for highlighting the C# using and namespace directives (SF #1395677, BenBE)
+ - Added support for highlighting the Java import and package directives (SF #1395677, BenBE)
+ - Fixed minor problem in Haskell cuasing accidential start of comment (SF#1987221, BenBE)
+ - Fixed minor issue causing loads of warnings if a language files defines no symbols (BenBE)
+ - Updated some aspects of the documentation and included further hints (BenBE)
+ - First of series of color scheme changes. Affected languages (sofar):
+ * Assembler (x86)
+ * Bash
+ * C
+ * C#
+ * Delphi
+ * Fortran77
+ * glSlang
+ * Java & Java 5
+ * JavaScript
+ * OCaml
+ * OpenOffice.org Basic
+ * Pascal
+ * Perl
+ * PHP and PHP-Brief
+Version 1.0.7.21
+ - Added language files
+ * Basic4GL (Matthew Webb)
+ - Fixed problem with mIRC language highlighting spaces only (BenBE)
+ - Language files can now specify a function to be called to decide the
+ colour of a regular expression match
+ - Added single quote to Lua (Darrin Roenfanz)
+ - Compare comments case insensitively (fixes AutoIT comments somewhat)
+ (Daniel Gordon)
+ - Fixed symbols not being highlighted at all (SF #1767953, BenBE)
+ - Fixed brackets not correctly managed (SF #1767954, BenBE)
+ - Changed default languages for some extensions
+ - Included color and character information for symbol highlighting in some languages (BenBE)
+ - Fixed a problem with extension detection if default was used (BenBE)
+ - Fixed a highlighting problem with the LaTeX language (SF #1776182, BenBE)
+ - Added a new parameter for enable_highlighting to reduce source duplication (SF #1786104, BenBE)
+ - Updated doxygen documentation to include since tags and some missing parameters
+ - Disabled symbol highlighting by default (doesn't affect brackets, cf. documentation) (BenBE)
+ - Added a check for set_case_keywords for the given param to be supported (BenBE)
+ - Minor rework of the HTML documentation layout \ W3C compliance (BenBE)
+ - Fixed highlighting error in bash language avoiding keywords in comments (SF #1786314, SF #1564839, BenBE)
+ - Fixed template params for C++ and C# not being highlighted (SF #1772919, BenBE)
+ - Fixed more reported problems about mirc highlighting
+ - Added some missing keywords for VB.NET
+ - Fixed some warnings in DOS language file (Florian Angehrn)
+ - Add possibility to handle more than one extra line style (SF #1698255, German Rumm, BenBE)
+ - Fixed handling of URLs when output case differs from URL case (SF #1815504, Tom Samstag, BenBE)
+ - Fixed POD (Plain Old Documentation) format problems breaking highlighting of Perl (SF #1891630, Shannon Wynter, BenBE)
+ - Fixed a problem with mIRC when & was used for identifiers (SF #1875552, BenBE)
+Version 1.0.7.20
+ - Added language files
+ * Genero (logic) and Per (forms) (FOURJ's Genero 4GL) (Lars Gersmann)
+ * Haskell (Dagit)
+ * ABAP (Andres Picazo)
+ * Motorola 68k Assembler (for MC68HC908GP32 Microcontroller) (BenBE)
+ * Dot (Adrien Friggeri)
+ - Fixed java documentation search for keywords to actually go to the
+ documentation (spaze)
+ - Applied fix for bug 1688864 (bad regexes) (Tim Starling)
+ - Fixed comment CSS rule in visualfoxpro
+ - ThinBASIC language update (Eros Olmi)
+ - mIRC language update (BenBE)
+ - Fixed outdated documentation URL of Perl language file (RuralMoon by BenBE)
+ - Fixed tab replacement code not generating the correct number of spaces in
+ some cases (Guillermo Calvo)
+ - Fixed two typos in Z80 language file
+ - Applied fix for bug 1730168 (Daniel Naber)
+ - Applied fix for bug 1705482 (Jason Frame)
+ * Configurable line endings (Replace \n by custom string)
+ * per-language tab-widths (Adjustable for width>=1)
+ * Included defaults for ASM (x86, m68k, z80), C, C (Mac), C++, C++ (Qt), C#,
+ Delphi, CSS,, HTML, PHP, PHP (Brief), QBasic, Ruby, XML
+ - Added a possibility to force generation of a surrounding tag around
+ the highlighted source
+ - Applied fix for additional keywords for the bash language
+ (cf. http://bash.thefreebizhost.com/bash_geshi.php, BenBE / Jan G)
+ - Fix bad colour definition in GML language (Andreas Gohr)
+ - Fixed phpdoc comments not being indented one space if they should be (Andy
+ Hassall)
+Version 1.0.7.19
+ - Added language files
+ * X++ (Simon Butcher)
+ * Rails (Moises Deniz)
+ - Fixed invalid HTML being generated and doctypes not being highlighted over
+ multiple lines properly when line numbers are on (Validome)
+ - Improved the ruby syntax highlighting by basing it off the Rails file
+ - Changed some regular expressions to possibly help with badly performing
+ regex support in PHP (Tim Starling)
+ - Allow {TIME}, {LANGUAGE} and {VERSION} to be used in the header as well as
+ the normal <TIME>/<LANGUAGE>/<VERSION> (AthanD)
+ - Changed comment regex in bash to prevent malformed XHTML (rv1971)
+Version 1.0.7.18
+ - Added language files
+ * ZiLOG Z80 Assembly (BenBE)
+ - Fixed incorrect highlighting when the starter of a multiline comment is
+ longer than the ender (Robert Anthony).
+ - Fixed "</span" generated if a multiline comment is the last thing in the
+ source (related to the above).
+ - Added #cs => #ce comment markers to AutoIT (Robert Anthony)
+ - Fixed spelling mistake for keyword in Python (wd3)
+ - Added a method to enable/disable keyword linking (Ian McKellar)
+ - Improved empty line detection for HTML output (BenBE)
+ - Changed code style of geshi.php, and removed tabs
+Version 1.0.7.17
+ - Fixed up ends of files having too many newlines (binarygroop)
+ - Removed background colour on keyword group in eiffel (Julian Tschannen)
+ - Removed GESHI_DIR_SEPARATOR constant usage, it's unnecessary (Aleksey Zapparov)
+ - Added /* ... */ comments to coldfusion (Jeff Howden)
+Version 1.0.7.16
+ - Added language files
+ * ActionScript (Steffen Krause)
+ * C++/Qt (Iulian M)
+ * PL/SQL (Victor Engmark)
+ - Fixed up my e-mail address everywhere
+ - Fixed notice with "error" property (IZIU Zielona Góra)
+ - Added some entries to the get_language_name_from_extension table
+ (Stebastian Schuberth)
+Version 1.0.7.15
+ - Added language files
+ * BNF (Rowan Rodrik van der Molen)
+ * IO (me, thanks to Johnathan Wright)
+ * mIRC (Alberto de Areba Sánchez)
+ - Fixed use of colon in XML (Grigory Rubtsov)
+ - Fixed notices in text.php, reg.php and latex.php when $this is not
+ available (Clemens Weiß)
+ - Made third parameter of geshi_highlight optional (Gaetano Giunta)
+ - Fix incorrect highlighting of the $# variable in bash (Michael Knight)
+ - Fixed single line comment mistake in thinbasic.php (Eros Olmi)
+Version 1.0.7.14
+ - Added language files
+ * thinBasic (Eros Olmi)
+ * LaTeX (Matthais Pospiech)
+ - Removed extra newlines at the end of some files
+ - Fixed SF bug 1556404 - check before using $this in language files
+ (Clemens Weiß)
+Version 1.0.7.13
+ - Added language files
+ * Uno IDL (Cedric Bosdonnat)
+ - Fixed add_ids causing odd XHTML (RyanJ)
+ - Fixed extra newline being added to end of result (Andreas Gohr)
+Version 1.0.7.12
+ - Fixed lines being collapsed when they contain just a space (artlover)
+ - Allowed matching for regexes using start/end matchers at the start/end
+ of the code (Sheri)
+ - Added (dubious) fix for google "I'm feeling lucky" search for java keywords
+ (dubious in that it doesn't work for me)
+ - mysql - Made the symbols into their own keyword group as the symbol group
+ isn't used. Added a style for multiline comments.
+ - Added a couple of php5 keywords to the php language files.
+ - Allow XML tags to have dashes.
+ - Changed LANG_NAME for many languages to be more sensible/correct case
+ (Matthias Mohr)
+ - Added case-sensitivity indices to python
+Version 1.0.7.11
+ - Added language files
+ * Smalltalk (Bananeweizen)
+ - Minor style improvements to matlab
+ - Moved a couple of functions to the correct group in smarty (arwan)
+Version 1.0.7.10
+ - Added language files
+ * TCL (Reid van Melle)
+ * Winbatch (Craig Storey)
+ * Groovy (Ivan F. Villanueva B.)
+ * Text (SmokingRope)
+ * Reg (SmokingRope)
+ - Removed \ as an escape character in T-SQL (Dave Jackson)
+ - Reset extra lines to highlight if source is changed (Diogo Resende)
+ - Allow setting of lexic permissions in language files (SmokingRope)
+ - Allow regexes to set a CSS class name (SmokingRope)
+ - Added URL support to DOS language (mastrboy)
+Version 1.0.7.9
+ - Added language files
+ * Fortran (Cedric Arrabie)
+ * SAS (Galen Johnson)
+ * CFDG (John Horigan)
+ - Fixed & in URL in java5 (Clemens Weiß)
+ - Added MD5 and SHA1 to mysql keywords (polarina)
+ - Fixes for highlight_lines_extra with line numbers (ithcy)
+ - Fixed backslash characters being removed (ArTourter)
+Version 1.0.7.8
+ - Fixed blank at start of MySQL file (W. Tasin)
+ - Fixed smarty functions being broken (ultrabob)
+ - Changed keyword and regexp detection and parsing
+ slightly to allow more "meta characters" (like #) in
+ keywords
+ - Minor fixes for XML and GML
+Version 1.0.7.7
+ - Added language files
+ * T-SQL (Duncan Lock)
+ * Robots.txt (Christian Lescuyer)
+ * AutoIT (mastrboy)
+ * Java 5 (Clemens Bruckmann)
+ * ColdFusion (Diego)
+ - A few keyword changes in java, removed :: object splitter (amphi)
+ - Now using a simpler regular expression for numbers (Brice Bernard)
+ - Fixed ah, bh etc. regs being highlighted as numbers (Unknown)
+Version 1.0.7.6
+ - Fix backtick-string highlighting in ruby (Juan J. Martínez)
+ - Add =begin multiline comments in ruby (Juan J. Martínez)
+ - Added support for :keywords and ::access in lisp (Denis Mashkevich)
+ - Prevented number highlighting if they are just after underscores (Joce)
+ - Removed escape characters for strings in XML and HTML (floele)
+ - Added instanceof keyword to java (jgottschling)
+ - Fixed comments in ASP (SBD)
+ - Removed unnecessary keyword style index from ini
+ - Added support for " strings in ini
+ - Removed unnecessary regex style index from blitzbasic
+ - Keyword case of URL-ed keywords should be defined by language file (Benny Baumann)
+ - Added "Hardquote" feature, provides more accurate string highlighting (Cliff Stanford)
+ - Used hardquote support for @"..." strings in C# (Cliff Stanford)
+ - Used hardquote support for ' strings in perl (Cliff Stanford)
+ - Fixed setting of language path (Cliff Stanford)
+ - Display source correctly formatted with line numbers (if requested) if an error
+ has occurred (several people)
+ - Having no source to highlight is not an error condition anymore
+ - Delphi language updated to include more keywords and types (BenBE)
+ - Updated NSIS to version 2.11 (deguix)
+Version 1.0.7.5
+ - Fix for using escape characters to escape newlines breaking XHTML compliance (Yves Goergen)
+ - Fixed method highlighting in VB (Matt Beale)
+ - Fixed multiline comment highlighting in SQL (MrBaseball34)
+ - Fixed two ">" symbols being outputted when using a footer but not CSS classes (MrBaseball34)
+ - Marked important block stuff as deprecated
+ - Some documentation tidyup
+ - Updated GML language file (Jos? Jorge Enr?quez Rodr?guez)
+ - THANKS file tidied up
+ - Fixed double </a> for elements in HTML (Yves Goergen)
+ - Added some keywords for ASM (Dreuzzo)
+Version 1.0.7.4
+ - Added language files
+ * MySQL (Carl Fürstenberg)
+ * BlitzBasic (Pàdraig O`Connel)
+ - Fixed up geshi_highlight function: it now correctly uses <code> instead of <div> (Remi Faure)
+ - When using GESHI_HEADER_NONE, remove the <ol> if line numbering is not enabled
+ - Commented example.php so people can use it as a guide better
+ - Fixed extra newline being generated if a comment is at the end
+ of the source (many people, including Yves Goergen)
+ - Fixed up some documentation issues
+ - Some minor language file fixes (C++, Lua) (Lua fixes by chromix)
+ - Fixed up no </span> in XML and other strict languages (regression from 1.0.7.3 fix: removed
+ unnecessary </span> when using strict mode) (Daniel Ecer, drskrud),
+Version 1.0.7.3
+ - Added language files
+ * Scheme (Jon Raphaelson)
+ * Ocaml and Ocaml-brief (Flaie)
+ * Ruby (Amit Gupta)
+ - Make urls generated for java highlighting XHTML compliant (Tim Van Wassenhove)
+ - Removed unnecessary </span> when using strict mode (Tim Van Wassenhove)
+ - Fixed warning in dos.php about undefined constant (Tim Van Wassenhove)
+ - Fixed security hole in contrib/example.php - able to view any file if source
+ not set and language is set to wierd value (Maksymilian Arciemowicz)
+Version 1.0.7.2
+ - Added language files
+ * Inno (Thomas Klinger)
+ * Ini (Deguix)
+ * DOS (Batchfile) (Alessandro Staltali)
+ * Applescript (Stephan Klimek)
+ * Freebasic (Roberto Rossi)
+ * SDLBasic (Roberto Rossi)
+ * ActionScript (links to French documentation) (NikO)
+ - NSIS language file updated (deguix)
+ - Lua language file updated (Roberto Rossi)
+ - Bugfix: Styles incorrectly overriding default styles instead of being merged
+ in set_*_styles methods (Stebastian Werner)
+ - Added GESHI_HEADER_NONE as valid header type. This still allows header content.
+Version 1.0.7.1
+ - Added language files:
+ * Div (Gabriel Lorenzo)
+ * GML (José Jorge Enríquez Rodríguez)
+ * Eiffel (Zoran Simic)
+ - Minor change to rules regarding when keywords can appear - now dots (.) are
+ allowed before keywords. (NikO)
+ - Bugfix: the line style for non-fancy lines when fancy highlighting is enabled
+ is now applied (Amit Gupta)
+Version 1.0.7
+ - Added language files:
+ * Diff (Conny Brunnkvist)
+ * VHDL (Alexander Krause)
+ * D (Thomas Kuehne)
+ * Matlab (Florian Knorn)
+ - Python highlighting improved (thither, Federico Quagliata)
+ - Changed file comments to use phpdoc syntax, and changed code style to be more
+ like PEAR
+ - Fixed bug in set_code_style: Second parameter is now optional
+ - The $_GESHI_ERRORS array is gone, error messages are internal to the GeSHi class
+ - Changed name of XML language to XML from HTML
+ - Removed min and max tab width checks
+ - Backported GeSHi 1.1.X's automatic language file path detection so you no longer
+ need to use the third parameter of the constructor or set_language_path except for
+ special circumstances.
+ - Source is checked to make sure it is not empty else an error occurs
+ - Removed excess characters after ?> in ada.php, apache.php and cpp.php that caused
+ http headers to be sent (psichron)
+ - Removed second "foreach" keyword for smarty language file that was causing
+ duplication (Iss)
+ - Added underscore to allowed characters in match for XML tags (anonymous)
+ - Added some missing java keywords like "abstract" and "transient"
+ - Added "list" and "continue" PHP keywords
+ - set_language resets error status and strict mode (Andrew Black)
+ - Removed margin:0 declaration from cssgen.php (Andrzej Kubaszek)
+ - Fixed multiline comment selector in cssgen.php (Andrzej Kubaszek)
+Version 1.0.6
+ - Added support for smart tabs - tabs that behave just like normal tabs when in
+ GESHI_HEADER_DIV mode.
+ - Partial patch for UTF-8 encoding applied (doesn't quite work however...)
+Version 1.0.5
+ - Added language files:
+ * MPASM (Bakalex)
+ * Oracle 8 (Guy Wicks)
+ - Fixed bug where not using an encoding type would sometime result in warnings (although
+ there still seems to be issues with encoding in general that I'm trying to gather more
+ data on) (Alexander Spennemann)
+ - Removed "margin: 0" from <ol> in an attempt to make line numbers visible in IE again
+ by default (untested, but I don't really care if it works... get firefox! ;))
+ - Added note on php5 support (Karim Scheik)
+ - Added two new methods: load_from_file and get_language_name_from_extension, that can
+ help automate file highlighting (though the extension array at this time is quite bare)
+ (David Gartner, Brian Cheesman)
+Version 1.0.4
+ - Fixed many version-reporting bugs (Jack Lloyd)
+ - Fixed bug where methods were not having the correct CSS generated for them
+ by get_stylesheet() (Jack Lloyd)
+ - Added new keywords to C and C++ files (Jack Lloyd)
+ - Added section on case sensitivity to documentation that wasn't in the other versions
+Version 1.0.3
+ - Added language files:
+ * Smarty (Alan Juden)
+ * C# (Alan Juden)
+ * VB.NET (Alan Juden)
+ * C for Macs (M. Uli Kusterer)
+ * Objective C (M. Uli Kusterer)
+ - Links can have a target attribute (Andreas Gohr)
+ - Fixed multiline string bug if not using classes
+ - Added method set_encoding that allows you to set the character
+ set used by calls to htmlentities() in GeSHi
+ - You can now specify an array of object splitters, and each
+ type of method separated by each object splitter can be highlighted
+ differently
+ - If a language uses a case sensitive keyword group and that group
+ has a URL associated with it, the keyword will not be lowercased
+ in the URL (M. Uli Kusterer)
+Version 1.0.2
+ - Added language files:
+ * Actionscript (Steffen Krause)
+ * ASP (Amit Gupta)
+ * Bash (Andreas Gohr)
+ * CADDCL (Roberto Rossi)
+ * CadLisp (Roberto Rossi)
+ * C++ (Dennis Bayer)
+ * Delphi (Járja Norbert)
+ * Javascript (Ben Keen)
+ * Lisp (Roberto Rossi)
+ * OpenOffice.org BASIC (Roberto Rossi)
+ * Perl (Andreas Gohr and Ben Keen)
+ * Python (Roberto Rossi)
+ * VisualFoxPro (Roberto Armellin)
+ * XML (Nigel McNie, from an idea/file by Christian Weiske)
+ - Added contrib/ directory with script to create one external stylesheet
+ from many languages(base script by Andreas Gohr, modified by Nigel McNie),
+ and an example script (needs lotsa work...)
+ - Code lines can have their own unique ID (for use with javascript)
+ (suggested by Andreas von Oettingen)
+ - Certain rows can be specified to be highlighted differently (suggested by
+ Andreas von Oettingen)
+ - Getter available for human-readable language name (suggested by Simon Patterson)
+ - Line numbers aren't highlighted when a user selects the code
+ - Contextual highlighting with <BEGIN GeSHi> ... <END GeSHi> in the code (which
+ can be disabled)
+ - Functions can be made into URLs to appropriate documentation (suggested
+ by cybot_tm). Also thanks to Marcin Gryszkalis for the links for C, Java
+ and Perl.
+ - Code can have a header and footer
+ - Time taken to parse the code is recorded and made available with the get_time()
+ method
+ - error() now returns a human-readable error message
+ - Function geshi_highlight added to make it even easier to highlight on the fly
+ - Advanced regular expression handling
+ - Bug fixes to lexic_permission handling
+Version 1.0.1
+ - Added methods set_symbols_style() and set_symbols_highlighting(). These should be used
+ instead of set_brackets_style and set_brackets_highlighting respectively.
+ - Added a new field - language_path - that can be set either when the constructor is
+ called, or by the new method set_language_path(), that specifies a path to the directory
+ containing the language files (bug reported by bbspliff)
+ - Added a new method set_case_keywords(), that allows the auto-casing feature to be
+ changed on the fly instead of simply being specified in the language file
+ - If there is an error the source that is outputted is now handled much better
+ - Lines are broken in the source only by \n now, not by \r\n (to save on output source)
+ - Indentation moved into its own method
+ - Method header() modified to allow the user to choose whether the code is surrounded in
+ a <div> or a <pre> (see documentation for benefits of both). Method footer() likewise
+ modified.
+ - Method get_stylesheet() modified so that a smaller comment is outputted in economy mode,
+ and bugs with when line number classes are outputted in economy mode have been fixed
+ - Bug where spans had two quotes at the end of the attributes fixed (ie. <span style=".."">)
+ - Added language files:
+ * Ada (Tux)
+ * Apache log file (Tux)
+ * ASM (Tux)
+ * NSIS (Tux)
+ * Pascal (Tux)
+Version 1.0.0
+ - Initial Release
diff --git a/platform/www/vendor/geshi/geshi/LICENSE b/platform/www/vendor/geshi/geshi/LICENSE
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/LICENSE
@@ -0,0 +1,339 @@
+ 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/platform/www/vendor/geshi/geshi/README.md b/platform/www/vendor/geshi/geshi/README.md
new file mode 100644
index 0000000..6c49bc1
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/README.md
@@ -0,0 +1,36 @@
+GeSHi - Generic Syntax Highlighter
+==================================
+### Version 1.0.9.1
+
+Author: [Benny Baumann](http://blog.benny-baumann.de/), [Nigel McNie](http://nigel.mcnie.name/)
+Email: <BenBE@geshi.org>, <nigel@geshi.org>
+GeSHi Website: <http://qbnz.com/highlighter>
+
+GeSHi is a generic syntax highlighter, written in PHP. You simply
+input the source code you wish to highlight with the language you
+wish to use, and the output will be a file syntax highlighted to
+XHTML standards.
+
+Documentation
+-------------
+For more information on how to use GeSHi, please consult the
+documentation. If you got this readme from a GeSHi package, then
+the documentation is available in the [docs](https://github.com/GeSHi/geshi-1.0/tree/master/docs)
+directory. Documentation is also available [online](http://qbnz.com/highlighter/documentation.php).
+
+If you think you've found a bug in GeSHi, contact me with a bug
+report at <BenBE@geshi.org>, submit to the [bug tracker at GitHub](https://github.com/GeSHi/geshi-1.0/issues).
+Be aware that minor highlighting errors may well just be incorrect
+language files, but if you do find something major please contact me.
+
+And if you're using GeSHi as a plugin/mod for some other software,
+please tell me about it! It's worth a link to you, and I can give
+you specialist help if you need it.
+
+License
+-------
+GeSHi is free software, released under the GNU GPL. Please see the
+[LICENSE](https://github.com/GeSHi/geshi-1.0/blob/master/LICENSE)
+file for more information. If you do modify this program, please tell
+me about it! Perhaps you've made a good improvement that I can learn
+from :)
diff --git a/platform/www/vendor/geshi/geshi/THANKS b/platform/www/vendor/geshi/geshi/THANKS
new file mode 100644
index 0000000..1ed6e88
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/THANKS
@@ -0,0 +1,287 @@
+
+ THANKS - List of credits for GeSHi
+
+I owe these people/groups my thanks for help with GeSHi. Thanks, guys!
+
+- Amit Gupta - Thanks for all that constructive criticism - it's
+ a great help for making GeSHi even better. And
+ thanks for the Wordpress plugin! (Anyone who is
+ interested in the plugin can visit:
+ http://blog.igeek.info/still-fresh/category/wp-plugins/igsyntax-hiliter/)
+- Andreas Gohr - Thanks for language files and for using GeSHi for DokuWiki
+ (http://www.splitbrain.org/dokuwiki/wiki:dokuwiki). And thanks
+ for all your criticisms and for that stylesheet-maker code :).
+ Also, thanks for the UTF-8 patch.
+- Andreas von Oettingen - Thanks for those great ideas! :)
+- bbspliff - Thanks for pointing out that bug (pity I already
+ found it though ;))
+- Benny Baumann - Thanks for your innumerable suggestions for improvements, and your
+ work on Delphi support :)
+- Ben Keen - Thanks for the language files and pointing out some
+ ideas for future releases. Lookin' forward to seeing that
+ software soon! ;)
+- Brian Cheesman - Thanks for using GeSHi in phpCvsView, and for the suggestion about
+ extension => language lookup
+- Christian Weiske - Thanks for the inspiration for creating advanced regexp
+ highlighting :D
+- Cliff Stanford - Thanks for the hardquote support for C# and Perl (can be used elsewhere
+ I'm sure)
+- David Gartner - Thanks for using GeSHi in net2ftp, and for the idea about a load_from_file
+ method
+- forum.qbasicnews.com - Thanks for putting up with the crappy versions
+ that I "forced" on you guys before ;)
+- Gizmore - Providing some patch to query supported languages
+- Jack Lloyd - Thanks for pointing out the versioning and method CSS bugs, and giving
+ me the extra C/C++ keywords
+- Karim Scheik - Thanks for the php5 support report
+- Marcin Gryszkalis - Thanks for those links for C, Java, Perl
+- M. Uli Kusterer - Thanks for the idea about URL case conversion
+- Milian Wolff - Thanks for the loads of optimizations
+ - Thanks for helping with implementation of various features
+- Roberto Armellin - Thanks for pointing out some flaws in GeSHi (that will be solved
+ in 1.2 guaranteed)
+- Sterling Christensen - Thanks for those links to language specs
+- Tux - Thanks for making all those language files :D
+- zbw - Thanks for proving a phpBB port was possible
+
+PEOPE WHO MADE LANGUAGE FILES
+
+- ABAP Andres Picazo
+- Actionscript Steffen Krause (french translation by NikO)
+- ActionScript 3 Jordi Boggiano (version for ActionScript3 and MXML)
+- Ada Tux
+- AIMMS Guido Diepen
+- Algol68 Neville Dempsey
+- Apache Tux
+- Applescript Stephan Klimek
+- Apt sources.list Milian Wolff
+- ARM Marat Dukhan
+- ASM Tux, Dennis Yurichev, Marat Dukhan
+- ASP Amit Gupta
+- Asymptote Manuel Yguel
+- Autoconf Mihai Vasilian
+- AutoHotkey Naveen Garg
+- AutoIt mastrboy
+- AviSynth Ryan Jones
+- Awk George Pollard
+- BASCOM AVR Michal Goralczyk
+- Bash Andreas Gohr
+- Basic4GL Matthew Webb
+- Biblatex Maïeul Rouquette
+- BibTeX Quinn Taylor
+- BlitzBasic Padraig O`Connel
+- BNF Rowan Rodrik van der Molen
+- Boo Marcus Griep
+- Brainfuck \ Brainfork Benny Baumann
+- C for Loadrunner Stuart Moncrieff
+- C for Macs M. Uli Kusterer
+- C for Windows Benny Baumann
+- C# Alan Juden
+- C++ Dennis Bayer, M. Uli Kusterer
+- C++ (Qt) Iulian M
+- C++ for Windows Benny Baumann
+- CADDCL Roberto Rossi
+- CadLisp Roberto Rossi
+- CDFG John Horigan
+- Ceylon Lucas Werkmeister
+- ChaiScript Jason Turner, Jonathan Turner
+- Chapel Richard Molitor
+- CIL Marcus Griep
+- Clojure Jess Johnson
+- CMake Daniel Nelson
+- COBOL Benny Baumann, Edward Hart
+- CoffeeScript Trevor Burnham
+- ColdFusion Diego
+- CSS Nigel McNie, Zéfling, peterdd
+- Cuesheet Benny Baumann
+- D Thomas Kuehne
+- Dart Edward Hart
+- DCL Petr Hendl
+- DCPU-16 Benny Baumann
+- DCS Stelio Passaris
+- Delphi Járja Norbert, Benny Baumann
+- Div Gabriel Lorenzo
+- DOS Alessandro Staltari
+- E Kevin Reid
+- ECMAScript Michel Mariani
+- Eiffel Zoran Simic
+- eMail \ mbox Benny Baumann
+- EPC Thorsten Muehlfelder
+- Erlang Benny Baumann, Dan Forest-Barbier, Uwe Dauernheim
+- Euphoria Nicholas Koceja
+- EZT Ramesh Vishveshwar
+- F# Julien Ortin
+- Falcon billykater
+- FO (abas-ERP) Tan-Vinh Nguyen
+- FormulaOne Juro Bystricky
+- Fortran Cedric Arrabie
+- FreeBasic Roberto Rossi
+- FreeSWITCH James Rose
+- GADV 4CS Jason Curl
+- GAMBAS Jesus Guardon
+- Genie Nicolas Joseph
+- Gettext Milian Wolff
+- glSlang Benny Baumann
+- GML José Jorge Enríquez Rodríguez, Timon Knigge
+- GNU make Neil Bird
+- Gnuplot Milian Wolff
+- Go Markus Jarderot
+- Groovy Ivan F. Villanueva B.
+- GwBasic José Gabriel Moya Yangüela
+- Haskell Dagit
+- Haxe Andy Li, John Liao
+- HicEst Georg Petrich
+- HQ9+ Benny Baumann
+- HTML5 Robert Lidberg
+- Icon Matt Oates
+- Ini Deguix
+- Inno Thomas Klinger
+- INTERCAL Benny Baumann
+- ISPF Panel Ramesh Vishveshwar
+- J Ric Sherlock
+- Java 5 Clemens Bruckmann
+- Javascript Ben Keen
+- Job Control Language Ramesh Vishveshwar
+- jQuery Rob Loach
+- Julia John Lynch
+- KiXtart Riley McArdle
+- KLone C Mickael Auger
+- KLone C++ Mickael Auger
+- Kotlin Ole Sandum
+- LaTeX Matthais Pospiech
+- LDIF Bruno Harbulot
+- Liberty BASIC Chris Iverson
+- Lisp Roberto Rossi
+- LLVM Azriel Fasten
+- Locomotive Basic Nacho Cabanes
+- Logtalk Paulo Moura
+- LOLcode Benny Baumann
+- LScript Beau McGuigan
+- LSL2 William Fry
+- Lua Roberto Rossi
+- m86k Benny Baumann
+- MagikSF Sjoerd van Leent
+- Mathematica Connor Glosser
+- MapBasic Tomasz Berus
+- MetaPost Maxime Chupin
+- Mercury Sebastian Godelet
+- mIRC Alberto de Areba Sánchez
+- МК-61 Russkiy
+- Modula 2 Benjamin Kowarsch
+- Modula-3 Martin Bishop
+- Motorola 6502 ASM Warren Willmey
+- Motorola 68k ASM Warren Willmey
+- MPASM Bakalex
+- MXML David Spurr
+- MySQL Carl Fürstenberg, Marjolein Katsma
+- Nagios Albéric de Pertat
+- NewLisp cormullion
+- nginx Cliff Wells, Deoren Moor, Thomas Joiner
+- Nimrod Dennis Felsing
+- NSIS Tux, Deguix
+- Oberon-2 Mike Mol
+- Objeck Progr. Lang. Randy Hollines
+- Objective C M. Uli Kusterer
+- Ocaml Flaie
+- Ocaml-brief Flaie
+- Octave Carnë Draug, Juan Pablo Carbajal
+- OpenBSD Packet Filter David Berard
+- OpenOffice.org BASIC Roberto Rossi
+- OpenSSH config Kevin Ernst
+- Oracle 8 Guy Wicks
+- Oracle 11i Simon Redhead
+- Oxygene (Delphi Prism) Carlo Kok
+- Oz Wolfgang Meyer
+- ParaSail sttaft
+- PARI/GP Charles R Greathouse IV
+- Pascal Tux
+- PCRE Benny Baumann
+- Perl Andreas Gohr, Ben Keen
+- Perl6 Kodi Arfer
+- Phix Pete Lomax
+- PIC16xxx assembler Phil Mattison
+- Pike Rick E.
+- Pixel Bender Richard Olsson
+- PL/I Robert Prins
+- PL/SQL Victor Engmark
+- PostgreSQL Christophe Chauvet
+- PostScript Benny Baumann
+- POV-Ray Carl Fürstenberg
+- PowerBuilder Doug Porter
+- PowerShell Frode Aarebrot
+- ProFTPd Benny Baumann
+- Progress Marco Aurelio de Pasqual
+- Prolog Benny Baumann
+- Property Files Edy Hinzen
+- ProvideX Jeff Wilder
+- PureBasic Gustavo Julio Fiorenza
+- Python Roberto Rossi
+- Python for S60 Sohan Basak
+- PyCon Benny Baumann
+- q/kdb+ Ian Roddis
+- QML J-P Nurmi
+- R / S+ Ron Fredericks, Fernando H.F.P. da Rosa
+- Racket Tim Brown
+- Rails Moises Deniz
+- RBScript Deng Wen Gang
+- Rebol Lecanu Guillaume
+- Reg SmokingRope
+- Rexx Jon Wolfers
+- Robots Christian Lescuyer
+- roff Artur Iwicki
+- RPM Specification File Paul Grinberg
+- Ruby Amit Gupta, Moises Deniz
+- Rust Dave Hodder
+- SAS Galen Johnson
+- SASS Javier Eguiluz
+- Scheme Jon Raphaelson
+- SciLab Christophe David
+- SCL Leonhard Hösch
+- SDLBasic Roberto Rossi
+- Smalltalk Bananeweizen
+- Smarty Alan Juden
+- SPARK Phil Thornley
+- SPARQL Karima Rafes
+- StandardML eldesh
+- StoneScript Archimmersion
+- Swift Ken Woo
+- SystemVerilog Sean O'Boyle
+- TCL Reid van Melle
+- TCL/eggdrop Reid van Melle
+- TeraTerm Boris Maisuradze
+- TexGraph Patrick Fradin
+- Text SmokingRope
+- thinBasic Eros Olmi
+- T-SQL Duncan Lock
+- TypoScript Jan-Philipp Halle
+- Twig Keyvan Akbary
+- Unicon Matt Oates
+- Uno IDL Cedric Bosdonnat
+- UnrealScript pospi
+- UPC Viraj Sinha
+- Urbi Alexandre Morgand
+- Vala Nicolas Joseph
+- VB Roberto Rossi
+- VB.NET Alan Juden
+- VBScript Rory Prendergast
+- Vedit Pauli Lindgren
+- Verilog Günter Dannoritzer, Tony Carrillo
+- VHDL Alexander 'E-Razor' Krause, Kevin Thibedeau
+- VIM Script Swaroop C H
+- Visual FoxPro Roberto Armellin
+- Visual Prolog Thomas Linder Puls
+- Whitespace Benny Baumann
+- Whois \ RPSL format Benny Baumann
+- Winbatch Craig Storey
+- Windows Batch FraidZZ
+- Wolfram Mysterious Light
+- X++ Simon Butcher
+- XBasic José Gabriel Moya Yangüela
+- Xojo Garry Pettet
+- Xorg config Milian Wolff
+- YAML Josh Ventura
+- Z80 Assembler Benny Baumann
+- ZXBasic Jose Rodriguez
+
+Do you want your name in here? Help me out! Make a language file, or suggest a new
+feature, or make a plugin for GeSHi for some other software, then tell me about it!
diff --git a/platform/www/vendor/geshi/geshi/build.properties.dist b/platform/www/vendor/geshi/geshi/build.properties.dist
new file mode 100644
index 0000000..dd270fe
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/build.properties.dist
@@ -0,0 +1 @@
+sfuser=
diff --git a/platform/www/vendor/geshi/geshi/build.xml b/platform/www/vendor/geshi/geshi/build.xml
new file mode 100644
index 0000000..198db13
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/build.xml
@@ -0,0 +1,216 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project name="GeSHi" default="pack" basedir=".">
+ <!--
+ GeSHi - Generic Syntax Highlighter - phing build file.
+ Works for 1.0.x
+ Packs up a new version of geshi, tags it in git and releases it on
+ sourceforge.net
+ -->
+ <property file="build.properties" />
+
+ <property name="version" value="1.0.9.1" />
+ <property name="stability" value="stable" />
+ <property name="zipfile" value="${phing.project.name}-${version}.zip" />
+ <property name="gzfile" value="${phing.project.name}-${version}.tar.gz" />
+ <property name="bz2file" value="${phing.project.name}-${version}.tar.bz2" />
+ <property name="pkgfile" value="geshi-${version}.tgz" />
+ <property name="fileprefix" value="geshi/" />
+ <property name="sfproject" value="GeSHi" />
+ <property name="sffilepath" value="g/ge/geshi/" />
+
+ <property name="releasenotes" value="
+Version 1.0.9.1
+" />
+
+
+ <fileset dir="src" id="files">
+ <include name="**"/>
+ <exclude name="**/.gitignore/"/>
+ </fileset>
+
+ <fileset dir="." id="extra">
+ <include name="contrib/**"/>
+ <include name="docs/**"/>
+ </fileset>
+
+ <taskdef name="d51pearpkg2" classname="phing.tasks.ext.d51PearPkg2Task" />
+
+
+
+ <target name="pack" depends=""
+ description="Create zip and tar files for release"
+ >
+ <mkdir dir="dist" />
+ <echo msg="Creating distribution files for ${phing.project.name} ${version}"/>
+
+ <delete file="dist/${zipfile}" failonerror="false"/>
+ <delete file="dist/${gzfile}" failonerror="false"/>
+ <delete file="dist/${bz2file}" failonerror="false"/>
+
+ <zip destfile="dist/${zipfile}" prefix="${fileprefix}">
+ <fileset refid="files" />
+ <fileset refid="extra" />
+ </zip>
+ <tar destfile="dist/${gzfile}" prefix="${fileprefix}" compression="gzip">
+ <fileset refid="files" />
+ <fileset refid="extra" />
+ </tar>
+ <tar destfile="dist/${bz2file}" prefix="${fileprefix}" compression="bzip2">
+ <fileset refid="files" />
+ <fileset refid="extra" />
+ </tar>
+ </target>
+
+
+
+ <target name="pack-pear" depends=""
+ description="Creates the PEAR package"
+ >
+ <mkdir dir="dist/pear" />
+ <delete file="src/package.xml" failonerror="false" />
+ <d51pearpkg2 dir="src" baseinstalldir="/">
+ <name>geshi</name>
+ <summary>Generic syntax highlighter, written in PHP.</summary>
+ <description>
+ GeSHi is a generic syntax highlighter, written in PHP. You simply
+ input the source code you wish to highlight with the language you
+ wish to use, and the output will be a file syntax highlighted to
+ XHTML standards.
+ </description>
+ <channel>pear.geshi.org</channel>
+
+ <lead user="benbe" name="Benny Baumann" email="benbe@geshi.org" />
+ <license>AGPL</license>
+
+ <version release="${version}" api="${version}" />
+ <stability release="${stability}" api="${stability}" />
+
+ <notes>${releasenotes}</notes>
+
+ <dependencies>
+ <php minimum_version="5.3.0" />
+ <pear minimum_version="1.9.0" />
+ </dependencies>
+
+ <!-- map directory (key) to role -->
+ <dirroles key="src">.</dirroles>
+
+ <ignore>**/.gitignore</ignore>
+ <ignore>contrib/**</ignore>
+ <ignore>dist/**</ignore>
+ <ignore>docs/**</ignore>
+ <ignore>*.properties</ignore>
+ <ignore>*.tgz</ignore>
+ </d51pearpkg2>
+ <!-- time to fix the package.xml file since the task does not
+ allow everything we need:
+ - strip the base directory names like src, data and www
+ - remove that dumb baseinstalldir from files
+ - md5sums are generated automatically when packaging
+ -->
+ <!-- yes, we need to generate a 2nd file and move it back -->
+ <copy file="src/package.xml" tofile="src/package2.xml" overwrite="true">
+ <filterchain>
+ <replaceregexp>
+ <!-- remove md5sums -->
+ <regexp
+ pattern="md5sum=&quot;[a-z0-9]{32}&quot; "
+ replace=""
+ />
+ <!-- remove baseinstalldir for files -->
+ <regexp
+ pattern="&lt;file baseinstalldir=&quot;/&quot;"
+ replace="&lt;file"
+ />
+ <!-- install-as for different directories -->
+ <regexp
+ pattern="(&lt;file name=&quot;data/(.+?)&quot;)"
+ replace="\1 install-as=&quot;\2&quot;"
+ />
+ <regexp
+ pattern="(&lt;file name=&quot;doc/(.+?)&quot;)"
+ replace="\1 install-as=&quot;\2&quot;"
+ />
+ <regexp
+ pattern="(&lt;file name=&quot;tests/(.+?)&quot;)"
+ replace="\1 install-as=&quot;\2&quot;"
+ />
+ <regexp
+ pattern="(&lt;file name=&quot;www/(.+?)&quot;)"
+ replace="\1 install-as=&quot;phorkie/\2&quot;"
+ />
+ <regexp
+ pattern="(&lt;file name=&quot;src/(.+?)&quot;)"
+ replace="\1 install-as=&quot;\2&quot;"
+ />
+ </replaceregexp>
+ </filterchain>
+ </copy>
+ <move file="src/package2.xml" tofile="src/package.xml" overwrite="true" />
+
+ <!-- package up -->
+ <exec command="pear package" passthru="true" dir="src" />
+ <move file="src/${pkgfile}" todir="${phing.dir}/dist/pear/" />
+
+ <delete file="src/package.xml" failonerror="true" />
+ </target>
+
+
+
+ <target name="release" depends="check,pack,pack-pear,deploy-sf,gittag"
+ description="Release the version on sourceforge"
+ >
+ <!-- meta-target -->
+ </target>
+
+
+ <!--
+ https://sourceforge.net/apps/trac/sourceforge/wiki/Release%20files%20for%20download
+ -->
+ <target name="deploy-sf" depends="check,pack"
+ description="Upload release to sourceforge"
+ >
+ <delete dir="dist/deploy-sf" /><!-- make empty -->
+ <mkdir dir="dist/deploy-sf" />
+ <mkdir dir="dist/deploy-sf/geshi" />
+ <mkdir dir="dist/deploy-sf/geshi/GeSHi ${version}" />
+ <copy todir="dist/deploy-sf/geshi/GeSHi ${version}/">
+ <fileset dir="dist">
+ <include name="${zipfile}" />
+ <include name="${gzfile}" />
+ <include name="${bz2file}" />
+ </fileset>
+ </copy>
+ <!-- test
+ <exec command="rsync -av dist/deploy-sf/ /tmp/test/" escape="false" />
+ -->
+ <exec
+ command="rsync -av -e ssh dist/deploy-sf/ ${sfuser},${sfproject}@frs.sourceforge.net:/home/frs/project/${sffilepath}/${sfproject}/"
+ escape="false" checkreturn="false"
+ />
+
+ <!-- rsync always returns code 23 on sourceforge releases, so we
+ can't check return values -->
+ </target>
+
+
+ <target name="gittag"
+ description="create the git tag for the current version"
+ >
+ <exec
+ command="git tag v${version}'"
+ escape="false" checkreturn="true"
+ />
+ </target>
+
+
+ <target name="check"
+ description="Check variables"
+ >
+ <fail unless="version" message="Version not defined!" />
+ <fail unless="sfuser" message="Sourceforge username not defined!" />
+ <fail unless="sfproject" message="Sourceforge project name not defined!" />
+ <fail unless="sffilepath" message="Sourceforge project file path not defined!" />
+ </target>
+
+</project>
diff --git a/platform/www/vendor/geshi/geshi/src/geshi.php b/platform/www/vendor/geshi/geshi/src/geshi.php
new file mode 100644
index 0000000..8c3f0a3
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi.php
@@ -0,0 +1,4758 @@
+<?php
+/**
+ * GeSHi - Generic Syntax Highlighter
+ *
+ * The GeSHi class for Generic Syntax Highlighting. Please refer to the
+ * documentation at http://qbnz.com/highlighter/documentation.php for more
+ * information about how to use this class.
+ *
+ * For changes, release notes, TODOs etc, see the relevant files in the docs/
+ * directory.
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * @package geshi
+ * @subpackage core
+ * @author Nigel McNie <nigel@geshi.org>, Benny Baumann <BenBE@omorphia.de>
+ * @copyright (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2014 Benny Baumann
+ * @license http://gnu.org/copyleft/gpl.html GNU GPL
+ */
+
+//
+// GeSHi Constants
+// You should use these constant names in your programs instead of
+// their values - you never know when a value may change in a future
+// version
+//
+
+/** The version of this GeSHi file */
+define('GESHI_VERSION', '1.0.9.1');
+
+// Define the root directory for the GeSHi code tree
+if (!defined('GESHI_ROOT')) {
+ /** The root directory for GeSHi */
+ define('GESHI_ROOT', dirname(__FILE__) . DIRECTORY_SEPARATOR);
+}
+/** The language file directory for GeSHi
+ @access private */
+define('GESHI_LANG_ROOT', GESHI_ROOT . 'geshi' . DIRECTORY_SEPARATOR);
+
+// Define if GeSHi should be paranoid about security
+if (!defined('GESHI_SECURITY_PARANOID')) {
+ /** Tells GeSHi to be paranoid about security settings */
+ define('GESHI_SECURITY_PARANOID', false);
+}
+
+// Line numbers - use with enable_line_numbers()
+/** Use no line numbers when building the result */
+define('GESHI_NO_LINE_NUMBERS', 0);
+/** Use normal line numbers when building the result */
+define('GESHI_NORMAL_LINE_NUMBERS', 1);
+/** Use fancy line numbers when building the result */
+define('GESHI_FANCY_LINE_NUMBERS', 2);
+
+// Container HTML type
+/** Use nothing to surround the source */
+define('GESHI_HEADER_NONE', 0);
+/** Use a "div" to surround the source */
+define('GESHI_HEADER_DIV', 1);
+/** Use a "pre" to surround the source */
+define('GESHI_HEADER_PRE', 2);
+/** Use a pre to wrap lines when line numbers are enabled or to wrap the whole code. */
+define('GESHI_HEADER_PRE_VALID', 3);
+/**
+ * Use a "table" to surround the source:
+ *
+ * <table>
+ * <thead><tr><td colspan="2">$header</td></tr></thead>
+ * <tbody><tr><td><pre>$linenumbers</pre></td><td><pre>$code></pre></td></tr></tbody>
+ * <tfooter><tr><td colspan="2">$footer</td></tr></tfoot>
+ * </table>
+ *
+ * this is essentially only a workaround for Firefox, see sf#1651996 or take a look at
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=365805
+ * @note when linenumbers are disabled this is essentially the same as GESHI_HEADER_PRE
+ */
+define('GESHI_HEADER_PRE_TABLE', 4);
+
+// Capatalisation constants
+/** Lowercase keywords found */
+define('GESHI_CAPS_NO_CHANGE', 0);
+/** Uppercase keywords found */
+define('GESHI_CAPS_UPPER', 1);
+/** Leave keywords found as the case that they are */
+define('GESHI_CAPS_LOWER', 2);
+
+// Link style constants
+/** Links in the source in the :link state */
+define('GESHI_LINK', 0);
+/** Links in the source in the :hover state */
+define('GESHI_HOVER', 1);
+/** Links in the source in the :active state */
+define('GESHI_ACTIVE', 2);
+/** Links in the source in the :visited state */
+define('GESHI_VISITED', 3);
+
+// Important string starter/finisher
+// Note that if you change these, they should be as-is: i.e., don't
+// write them as if they had been run through htmlentities()
+/** The starter for important parts of the source */
+define('GESHI_START_IMPORTANT', '<BEGIN GeSHi>');
+/** The ender for important parts of the source */
+define('GESHI_END_IMPORTANT', '<END GeSHi>');
+
+/**#@+
+ * @access private
+ */
+// When strict mode applies for a language
+/** Strict mode never applies (this is the most common) */
+define('GESHI_NEVER', 0);
+/** Strict mode *might* apply, and can be enabled or
+ disabled by {@link GeSHi->enable_strict_mode()} */
+define('GESHI_MAYBE', 1);
+/** Strict mode always applies */
+define('GESHI_ALWAYS', 2);
+
+// Advanced regexp handling constants, used in language files
+/** The key of the regex array defining what to search for */
+define('GESHI_SEARCH', 0);
+/** The key of the regex array defining what bracket group in a
+ matched search to use as a replacement */
+define('GESHI_REPLACE', 1);
+/** The key of the regex array defining any modifiers to the regular expression */
+define('GESHI_MODIFIERS', 2);
+/** The key of the regex array defining what bracket group in a
+ matched search to put before the replacement */
+define('GESHI_BEFORE', 3);
+/** The key of the regex array defining what bracket group in a
+ matched search to put after the replacement */
+define('GESHI_AFTER', 4);
+/** The key of the regex array defining a custom keyword to use
+ for this regexp's html tag class */
+define('GESHI_CLASS', 5);
+
+/** Used in language files to mark comments */
+define('GESHI_COMMENTS', 0);
+
+/** some old PHP / PCRE subpatterns only support up to xxx subpatterns in
+ regular expressions. Set this to false if your PCRE lib is up to date
+ @see GeSHi->optimize_regexp_list()
+ **/
+define('GESHI_MAX_PCRE_SUBPATTERNS', 500);
+/** it's also important not to generate too long regular expressions
+ be generous here... but keep in mind, that when reaching this limit we
+ still have to close open patterns. 12k should do just fine on a 16k limit.
+ @see GeSHi->optimize_regexp_list()
+ **/
+define('GESHI_MAX_PCRE_LENGTH', 12288);
+
+//Number format specification
+/** Basic number format for integers */
+define('GESHI_NUMBER_INT_BASIC', 1); //Default integers \d+
+/** Enhanced number format for integers like seen in C */
+define('GESHI_NUMBER_INT_CSTYLE', 2); //Default C-Style \d+[lL]?
+/** Number format to highlight binary numbers with a suffix "b" */
+define('GESHI_NUMBER_BIN_SUFFIX', 16); //[01]+[bB]
+/** Number format to highlight binary numbers with a prefix % */
+define('GESHI_NUMBER_BIN_PREFIX_PERCENT', 32); //%[01]+
+/** Number format to highlight binary numbers with a prefix 0b (C) */
+define('GESHI_NUMBER_BIN_PREFIX_0B', 64); //0b[01]+
+/** Number format to highlight octal numbers with a leading zero */
+define('GESHI_NUMBER_OCT_PREFIX', 256); //0[0-7]+
+/** Number format to highlight octal numbers with a prefix 0o (logtalk) */
+define('GESHI_NUMBER_OCT_PREFIX_0O', 512); //0[0-7]+
+/** Number format to highlight octal numbers with a leading @ (Used in HiSofts Devpac series). */
+define('GESHI_NUMBER_OCT_PREFIX_AT', 1024); //@[0-7]+
+/** Number format to highlight octal numbers with a suffix of o */
+define('GESHI_NUMBER_OCT_SUFFIX', 2048); //[0-7]+[oO]
+/** Number format to highlight hex numbers with a prefix 0x */
+define('GESHI_NUMBER_HEX_PREFIX', 4096); //0x[0-9a-fA-F]+
+/** Number format to highlight hex numbers with a prefix $ */
+define('GESHI_NUMBER_HEX_PREFIX_DOLLAR', 8192); //$[0-9a-fA-F]+
+/** Number format to highlight hex numbers with a suffix of h */
+define('GESHI_NUMBER_HEX_SUFFIX', 16384); //[0-9][0-9a-fA-F]*h
+/** Number format to highlight floating-point numbers without support for scientific notation */
+define('GESHI_NUMBER_FLT_NONSCI', 65536); //\d+\.\d+
+/** Number format to highlight floating-point numbers without support for scientific notation */
+define('GESHI_NUMBER_FLT_NONSCI_F', 131072); //\d+(\.\d+)?f
+/** Number format to highlight floating-point numbers with support for scientific notation (E) and optional leading zero */
+define('GESHI_NUMBER_FLT_SCI_SHORT', 262144); //\.\d+e\d+
+/** Number format to highlight floating-point numbers with support for scientific notation (E) and required leading digit */
+define('GESHI_NUMBER_FLT_SCI_ZERO', 524288); //\d+(\.\d+)?e\d+
+//Custom formats are passed by RX array
+
+// Error detection - use these to analyse faults
+/** No sourcecode to highlight was specified
+ * @deprecated
+ */
+define('GESHI_ERROR_NO_INPUT', 1);
+/** The language specified does not exist */
+define('GESHI_ERROR_NO_SUCH_LANG', 2);
+/** GeSHi could not open a file for reading (generally a language file) */
+define('GESHI_ERROR_FILE_NOT_READABLE', 3);
+/** The header type passed to {@link GeSHi->set_header_type()} was invalid */
+define('GESHI_ERROR_INVALID_HEADER_TYPE', 4);
+/** The line number type passed to {@link GeSHi->enable_line_numbers()} was invalid */
+define('GESHI_ERROR_INVALID_LINE_NUMBER_TYPE', 5);
+/**#@-*/
+
+
+/**
+ * The GeSHi Class.
+ *
+ * Please refer to the documentation for GeSHi 1.0.X that is available
+ * at http://qbnz.com/highlighter/documentation.php for more information
+ * about how to use this class.
+ *
+ * @package geshi
+ * @author Nigel McNie <nigel@geshi.org>
+ * @author Benny Baumann <BenBE@omorphia.de>
+ * @copyright (C) 2004 - 2007 Nigel McNie, (C) 2007 - 2014 Benny Baumann
+ */
+class GeSHi {
+
+ /**
+ * The source code to highlight
+ * @var string
+ */
+ protected $source = '';
+
+ /**
+ * The language to use when highlighting
+ * @var string
+ */
+ protected $language = '';
+
+ /**
+ * The data for the language used
+ * @var array
+ */
+ protected $language_data = array();
+
+ /**
+ * The path to the language files
+ * @var string
+ */
+ protected $language_path = GESHI_LANG_ROOT;
+
+ /**
+ * The error message associated with an error
+ * @var string
+ * @todo check err reporting works
+ */
+ protected $error = false;
+
+ /**
+ * Possible error messages
+ * @var array
+ */
+ protected $error_messages = array(
+ GESHI_ERROR_NO_SUCH_LANG => 'GeSHi could not find the language {LANGUAGE} (using path {PATH})',
+ GESHI_ERROR_FILE_NOT_READABLE => 'The file specified for load_from_file was not readable',
+ GESHI_ERROR_INVALID_HEADER_TYPE => 'The header type specified is invalid',
+ GESHI_ERROR_INVALID_LINE_NUMBER_TYPE => 'The line number type specified is invalid'
+ );
+
+ /**
+ * Whether highlighting is strict or not
+ * @var boolean
+ */
+ protected $strict_mode = false;
+
+ /**
+ * Whether to use CSS classes in output
+ * @var boolean
+ */
+ protected $use_classes = false;
+
+ /**
+ * The type of header to use. Can be one of the following
+ * values:
+ *
+ * - GESHI_HEADER_PRE: Source is outputted in a "pre" HTML element.
+ * - GESHI_HEADER_DIV: Source is outputted in a "div" HTML element.
+ * - GESHI_HEADER_NONE: No header is outputted.
+ *
+ * @var int
+ */
+ protected $header_type = GESHI_HEADER_PRE;
+
+ /**
+ * Array of permissions for which lexics should be highlighted
+ * @var array
+ */
+ protected $lexic_permissions = array(
+ 'KEYWORDS' => array(),
+ 'COMMENTS' => array('MULTI' => true),
+ 'REGEXPS' => array(),
+ 'ESCAPE_CHAR' => true,
+ 'BRACKETS' => true,
+ 'SYMBOLS' => false,
+ 'STRINGS' => true,
+ 'NUMBERS' => true,
+ 'METHODS' => true,
+ 'SCRIPT' => true
+ );
+
+ /**
+ * The time it took to parse the code
+ * @var double
+ */
+ protected $time = 0;
+
+ /**
+ * The content of the header block
+ * @var string
+ */
+ protected $header_content = '';
+
+ /**
+ * The content of the footer block
+ * @var string
+ */
+ protected $footer_content = '';
+
+ /**
+ * The style of the header block
+ * @var string
+ */
+ protected $header_content_style = '';
+
+ /**
+ * The style of the footer block
+ * @var string
+ */
+ protected $footer_content_style = '';
+
+ /**
+ * Tells if a block around the highlighted source should be forced
+ * if not using line numbering
+ * @var boolean
+ */
+ protected $force_code_block = false;
+
+ /**
+ * The styles for hyperlinks in the code
+ * @var array
+ */
+ protected $link_styles = array();
+
+ /**
+ * Whether important blocks should be recognised or not
+ * @var boolean
+ * @deprecated
+ * @todo REMOVE THIS FUNCTIONALITY!
+ */
+ protected $enable_important_blocks = false;
+
+ /**
+ * Styles for important parts of the code
+ * @var string
+ * @deprecated
+ * @todo As above - rethink the whole idea of important blocks as it is buggy and
+ * will be hard to implement in 1.2
+ */
+ protected $important_styles = 'font-weight: bold; color: red;'; // Styles for important parts of the code
+
+ /**
+ * Whether CSS IDs should be added to the code
+ * @var boolean
+ */
+ protected $add_ids = false;
+
+ /**
+ * Lines that should be highlighted extra
+ * @var array
+ */
+ protected $highlight_extra_lines = array();
+
+ /**
+ * Styles of lines that should be highlighted extra
+ * @var array
+ */
+ protected $highlight_extra_lines_styles = array();
+
+ /**
+ * Styles of extra-highlighted lines
+ * @var string
+ */
+ protected $highlight_extra_lines_style = 'background-color: #ffc;';
+
+ /**
+ * The line ending
+ * If null, nl2br() will be used on the result string.
+ * Otherwise, all instances of \n will be replaced with $line_ending
+ * @var string
+ */
+ protected $line_ending = null;
+
+ /**
+ * Number at which line numbers should start at
+ * @var int
+ */
+ protected $line_numbers_start = 1;
+
+ /**
+ * The overall style for this code block
+ * @var string
+ */
+ protected $overall_style = 'font-family:monospace;';
+
+ /**
+ * The style for the actual code
+ * @var string
+ */
+ protected $code_style = 'font: normal normal 1em/1.2em monospace; margin:0; padding:0; background:none; vertical-align:top;';
+
+ /**
+ * The overall class for this code block
+ * @var string
+ */
+ protected $overall_class = '';
+
+ /**
+ * The overall ID for this code block
+ * @var string
+ */
+ protected $overall_id = '';
+
+ /**
+ * Line number styles
+ * @var string
+ */
+ protected $line_style1 = 'font-weight: normal; vertical-align:top;';
+
+ /**
+ * Line number styles for fancy lines
+ * @var string
+ */
+ protected $line_style2 = 'font-weight: bold; vertical-align:top;';
+
+ /**
+ * Style for line numbers when GESHI_HEADER_PRE_TABLE is chosen
+ * @var string
+ */
+ protected $table_linenumber_style = 'width:1px;text-align:right;margin:0;padding:0 2px;vertical-align:top;';
+
+ /**
+ * Flag for how line numbers are displayed
+ * @var boolean
+ */
+ protected $line_numbers = GESHI_NO_LINE_NUMBERS;
+
+ /**
+ * Flag to decide if multi line spans are allowed. Set it to false to make sure
+ * each tag is closed before and reopened after each linefeed.
+ * @var boolean
+ */
+ protected $allow_multiline_span = true;
+
+ /**
+ * The "nth" value for fancy line highlighting
+ * @var int
+ */
+ protected $line_nth_row = 0;
+
+ /**
+ * The size of tab stops
+ * @var int
+ */
+ protected $tab_width = 8;
+
+ /**
+ * Should we use language-defined tab stop widths?
+ * @var int
+ */
+ protected $use_language_tab_width = false;
+
+ /**
+ * Default target for keyword links
+ * @var string
+ */
+ protected $link_target = '';
+
+ /**
+ * The encoding to use for entity encoding
+ * NOTE: Used with Escape Char Sequences to fix UTF-8 handling (cf. SF#2037598)
+ * @var string
+ */
+ protected $encoding = 'utf-8';
+
+ /**
+ * Should keywords be linked?
+ * @var boolean
+ */
+ protected $keyword_links = true;
+
+ /**
+ * Currently loaded language file
+ * @var string
+ * @since 1.0.7.22
+ */
+ protected $loaded_language = '';
+
+ /**
+ * Wether the caches needed for parsing are built or not
+ *
+ * @var bool
+ * @since 1.0.8
+ */
+ protected $parse_cache_built = false;
+
+ /**
+ * Work around for Suhosin Patch with disabled /e modifier
+ *
+ * Note from suhosins author in config file:
+ * <blockquote>
+ * The /e modifier inside <code>preg_replace()</code> allows code execution.
+ * Often it is the cause for remote code execution exploits. It is wise to
+ * deactivate this feature and test where in the application it is used.
+ * The developer using the /e modifier should be made aware that he should
+ * use <code>preg_replace_callback()</code> instead
+ * </blockquote>
+ *
+ * @var array
+ * @since 1.0.8
+ */
+ protected $_kw_replace_group = 0;
+ protected $_rx_key = 0;
+
+ /**
+ * some "callback parameters" for handle_multiline_regexps
+ *
+ * @since 1.0.8
+ * @access private
+ * @var string
+ */
+ protected $_hmr_before = '';
+ protected $_hmr_replace = '';
+ protected $_hmr_after = '';
+ protected $_hmr_key = 0;
+
+ /**
+ * Creates a new GeSHi object, with source and language
+ *
+ * @param string $source The source code to highlight
+ * @param string $language The language to highlight the source with
+ * @param string $path The path to the language file directory. <b>This
+ * is deprecated!</b> I've backported the auto path
+ * detection from the 1.1.X dev branch, so now it
+ * should be automatically set correctly. If you have
+ * renamed the language directory however, you will
+ * still need to set the path using this parameter or
+ * {@link GeSHi->set_language_path()}
+ * @since 1.0.0
+ */
+ public function __construct($source = '', $language = '', $path = '') {
+ if ( is_string($source) && ($source !== '') ) {
+ $this->set_source($source);
+ }
+ if ( is_string($language) && ($language !== '') ) {
+ $this->set_language($language);
+ }
+ $this->set_language_path($path);
+ }
+
+ /**
+ * Returns the version of GeSHi
+ *
+ * @return string
+ * @since 1.0.8.11
+ */
+ public function get_version()
+ {
+ return GESHI_VERSION;
+ }
+
+ /**
+ * Returns an error message associated with the last GeSHi operation,
+ * or false if no error has occurred
+ *
+ * @return string|false An error message if there has been an error, else false
+ * @since 1.0.0
+ */
+ public function error() {
+ if ($this->error) {
+ //Put some template variables for debugging here ...
+ $debug_tpl_vars = array(
+ '{LANGUAGE}' => $this->language,
+ '{PATH}' => $this->language_path
+ );
+ $msg = str_replace(
+ array_keys($debug_tpl_vars),
+ array_values($debug_tpl_vars),
+ $this->error_messages[$this->error]);
+
+ return "<br /><strong>GeSHi Error:</strong> $msg (code {$this->error})<br />";
+ }
+ return false;
+ }
+
+ /**
+ * Gets a human-readable language name (thanks to Simon Patterson
+ * for the idea :))
+ *
+ * @return string The name for the current language
+ * @since 1.0.2
+ */
+ public function get_language_name() {
+ if (GESHI_ERROR_NO_SUCH_LANG == $this->error) {
+ return $this->language_data['LANG_NAME'] . ' (Unknown Language)';
+ }
+ return $this->language_data['LANG_NAME'];
+ }
+
+ /**
+ * Sets the source code for this object
+ *
+ * @param string $source The source code to highlight
+ * @since 1.0.0
+ */
+ public function set_source($source) {
+ $this->source = $source;
+ $this->highlight_extra_lines = array();
+ }
+
+ /**
+ * Clean up the language name to prevent malicious code injection
+ *
+ * @param string $language The name of the language to strip
+ * @since 1.0.9.1
+ */
+ public function strip_language_name($language) {
+ $language = preg_replace('#[^a-zA-Z0-9\-_]#', '', $language);
+ $language = strtolower($language);
+
+ return $language;
+ }
+
+ /**
+ * Sets the language for this object
+ *
+ * @note since 1.0.8 this function won't reset language-settings by default anymore!
+ * if you need this set $force_reset = true
+ *
+ * @param string $language The name of the language to use
+ * @param bool $force_reset
+ * @since 1.0.0
+ */
+ public function set_language($language, $force_reset = false) {
+ $this->error = false;
+ $this->strict_mode = GESHI_NEVER;
+
+ if ($force_reset) {
+ $this->loaded_language = false;
+ }
+
+ //Clean up the language name to prevent malicious code injection
+ $language = $this->strip_language_name($language);
+
+ //Retreive the full filename
+ $file_name = $this->language_path . $language . '.php';
+ if ($file_name == $this->loaded_language) {
+ // this language is already loaded!
+ return;
+ }
+
+ $this->language = $language;
+
+ //Check if we can read the desired file
+ if (!is_readable($file_name)) {
+ $this->error = GESHI_ERROR_NO_SUCH_LANG;
+ return;
+ }
+
+ // Load the language for parsing
+ $this->load_language($file_name);
+ }
+
+ /**
+ * Sets the path to the directory containing the language files. Note
+ * that this path is relative to the directory of the script that included
+ * geshi.php, NOT geshi.php itself.
+ *
+ * @param string $path The path to the language directory
+ * @since 1.0.0
+ * @deprecated The path to the language files should now be automatically
+ * detected, so this method should no longer be needed. The
+ * 1.1.X branch handles manual setting of the path differently
+ * so this method will disappear in 1.2.0.
+ */
+ public function set_language_path($path) {
+ if(strpos($path,':')) {
+ //Security Fix to prevent external directories using fopen wrappers.
+ if(DIRECTORY_SEPARATOR == "\\") {
+ if(!preg_match('#^[a-zA-Z]:#', $path) || false !== strpos($path, ':', 2)) {
+ return;
+ }
+ } else {
+ return;
+ }
+ }
+ if(preg_match('#[^/a-zA-Z0-9_\.\-\\\s:]#', $path)) {
+ //Security Fix to prevent external directories using fopen wrappers.
+ return;
+ }
+ if(GESHI_SECURITY_PARANOID && false !== strpos($path, '/.')) {
+ //Security Fix to prevent external directories using fopen wrappers.
+ return;
+ }
+ if(GESHI_SECURITY_PARANOID && false !== strpos($path, '..')) {
+ //Security Fix to prevent external directories using fopen wrappers.
+ return;
+ }
+ if ($path) {
+ $this->language_path = ('/' == $path[strlen($path) - 1]) ? $path : $path . '/';
+ $this->set_language($this->language); // otherwise set_language_path has no effect
+ }
+ }
+
+ /**
+ * Get supported langs or an associative array lang=>full_name.
+ * @param boolean $full_names
+ * @return array
+ */
+ public function get_supported_languages($full_names=false)
+ {
+ // return array
+ $back = array();
+
+ // we walk the lang root
+ $dir = dir($this->language_path);
+
+ // foreach entry
+ while (false !== ($entry = $dir->read()))
+ {
+ $full_path = $this->language_path.$entry;
+
+ // Skip all dirs
+ if (is_dir($full_path)) {
+ continue;
+ }
+
+ // we only want lang.php files
+ if (!preg_match('/^([^.]+)\.php$/', $entry, $matches)) {
+ continue;
+ }
+
+ // Raw lang name is here
+ $langname = $matches[1];
+
+ // We want the fullname too?
+ if ($full_names === true)
+ {
+ if (false !== ($fullname = $this->get_language_fullname($langname)))
+ {
+ $back[$langname] = $fullname; // we go associative
+ }
+ }
+ else
+ {
+ // just store raw langname
+ $back[] = $langname;
+ }
+ }
+
+ $dir->close();
+
+ return $back;
+ }
+
+ /**
+ * Get full_name for a lang or false.
+ * @param string $language short langname (html4strict for example)
+ * @return mixed
+ */
+ public function get_language_fullname($language)
+ {
+ //Clean up the language name to prevent malicious code injection
+ $language = preg_replace('#[^a-zA-Z0-9\-_]#', '', $language);
+
+ $language = strtolower($language);
+
+ // get fullpath-filename for a langname
+ $fullpath = $this->language_path.$language.'.php';
+
+ // we need to get contents :S
+ if (false === ($data = file_get_contents($fullpath))) {
+ $this->error = sprintf('Geshi::get_lang_fullname() Unknown Language: %s', $language);
+ return false;
+ }
+
+ // match the langname
+ if (!preg_match('/\'LANG_NAME\'\s*=>\s*\'((?:[^\']|\\\')+?)\'/', $data, $matches)) {
+ $this->error = sprintf('Geshi::get_lang_fullname(%s): Regex can not detect language', $language);
+ return false;
+ }
+
+ // return fullname for langname
+ return stripcslashes($matches[1]);
+ }
+
+ /**
+ * Sets the type of header to be used.
+ *
+ * If GESHI_HEADER_DIV is used, the code is surrounded in a "div".This
+ * means more source code but more control over tab width and line-wrapping.
+ * GESHI_HEADER_PRE means that a "pre" is used - less source, but less
+ * control. Default is GESHI_HEADER_PRE.
+ *
+ * From 1.0.7.2, you can use GESHI_HEADER_NONE to specify that no header code
+ * should be outputted.
+ *
+ * @param int $type The type of header to be used
+ * @since 1.0.0
+ */
+ public function set_header_type($type) {
+ //Check if we got a valid header type
+ if (!in_array($type, array(GESHI_HEADER_NONE, GESHI_HEADER_DIV,
+ GESHI_HEADER_PRE, GESHI_HEADER_PRE_VALID, GESHI_HEADER_PRE_TABLE))) {
+ $this->error = GESHI_ERROR_INVALID_HEADER_TYPE;
+ return;
+ }
+
+ //Set that new header type
+ $this->header_type = $type;
+ }
+
+ /**
+ * Sets the styles for the code that will be outputted
+ * when this object is parsed. The style should be a
+ * string of valid stylesheet declarations
+ *
+ * @param string $style The overall style for the outputted code block
+ * @param boolean $preserve_defaults Whether to merge the styles with the current styles or not
+ * @since 1.0.0
+ */
+ public function set_overall_style($style, $preserve_defaults = false) {
+ if (!$preserve_defaults) {
+ $this->overall_style = $style;
+ } else {
+ $this->overall_style .= $style;
+ }
+ }
+
+ /**
+ * Sets the overall classname for this block of code. This
+ * class can then be used in a stylesheet to style this object's
+ * output
+ *
+ * @param string $class The class name to use for this block of code
+ * @since 1.0.0
+ */
+ public function set_overall_class($class) {
+ $this->overall_class = $class;
+ }
+
+ /**
+ * Sets the overall id for this block of code. This id can then
+ * be used in a stylesheet to style this object's output
+ *
+ * @param string $id The ID to use for this block of code
+ * @since 1.0.0
+ */
+ public function set_overall_id($id) {
+ $this->overall_id = $id;
+ }
+
+ /**
+ * Sets whether CSS classes should be used to highlight the source. Default
+ * is off, calling this method with no arguments will turn it on
+ *
+ * @param boolean $flag Whether to turn classes on or not
+ * @since 1.0.0
+ */
+ public function enable_classes($flag = true) {
+ $this->use_classes = ($flag) ? true : false;
+ }
+
+ /**
+ * Sets the style for the actual code. This should be a string
+ * containing valid stylesheet declarations. If $preserve_defaults is
+ * true, then styles are merged with the default styles, with the
+ * user defined styles having priority
+ *
+ * Note: Use this method to override any style changes you made to
+ * the line numbers if you are using line numbers, else the line of
+ * code will have the same style as the line number! Consult the
+ * GeSHi documentation for more information about this.
+ *
+ * @param string $style The style to use for actual code
+ * @param boolean $preserve_defaults Whether to merge the current styles with the new styles
+ * @since 1.0.2
+ */
+ public function set_code_style($style, $preserve_defaults = false) {
+ if (!$preserve_defaults) {
+ $this->code_style = $style;
+ } else {
+ $this->code_style .= $style;
+ }
+ }
+
+ /**
+ * Sets the styles for the line numbers.
+ *
+ * @param string $style1 The style for the line numbers that are "normal"
+ * @param string|boolean $style2 If a string, this is the style of the line
+ * numbers that are "fancy", otherwise if boolean then this
+ * defines whether the normal styles should be merged with the
+ * new normal styles or not
+ * @param boolean $preserve_defaults If set, is the flag for whether to merge the "fancy"
+ * styles with the current styles or not
+ * @since 1.0.2
+ */
+ public function set_line_style($style1, $style2 = '', $preserve_defaults = false) {
+ //Check if we got 2 or three parameters
+ if (is_bool($style2)) {
+ $preserve_defaults = $style2;
+ $style2 = '';
+ }
+
+ //Actually set the new styles
+ if (!$preserve_defaults) {
+ $this->line_style1 = $style1;
+ $this->line_style2 = $style2;
+ } else {
+ $this->line_style1 .= $style1;
+ $this->line_style2 .= $style2;
+ }
+ }
+
+ /**
+ * Sets whether line numbers should be displayed.
+ *
+ * Valid values for the first parameter are:
+ *
+ * - GESHI_NO_LINE_NUMBERS: Line numbers will not be displayed
+ * - GESHI_NORMAL_LINE_NUMBERS: Line numbers will be displayed
+ * - GESHI_FANCY_LINE_NUMBERS: Fancy line numbers will be displayed
+ *
+ * For fancy line numbers, the second parameter is used to signal which lines
+ * are to be fancy. For example, if the value of this parameter is 5 then every
+ * 5th line will be fancy.
+ *
+ * @param int $flag How line numbers should be displayed
+ * @param int $nth_row Defines which lines are fancy
+ * @since 1.0.0
+ */
+ public function enable_line_numbers($flag, $nth_row = 5) {
+ if (GESHI_NO_LINE_NUMBERS != $flag && GESHI_NORMAL_LINE_NUMBERS != $flag
+ && GESHI_FANCY_LINE_NUMBERS != $flag) {
+ $this->error = GESHI_ERROR_INVALID_LINE_NUMBER_TYPE;
+ }
+ $this->line_numbers = $flag;
+ $this->line_nth_row = $nth_row;
+ }
+
+ /**
+ * Sets wether spans and other HTML markup generated by GeSHi can
+ * span over multiple lines or not. Defaults to true to reduce overhead.
+ * Set it to false if you want to manipulate the output or manually display
+ * the code in an ordered list.
+ *
+ * @param boolean $flag Wether multiline spans are allowed or not
+ * @since 1.0.7.22
+ */
+ public function enable_multiline_span($flag) {
+ $this->allow_multiline_span = (bool) $flag;
+ }
+
+ /**
+ * Get current setting for multiline spans, see GeSHi->enable_multiline_span().
+ *
+ * @see enable_multiline_span
+ * @return bool
+ */
+ public function get_multiline_span() {
+ return $this->allow_multiline_span;
+ }
+
+ /**
+ * Sets the style for a keyword group. If $preserve_defaults is
+ * true, then styles are merged with the default styles, with the
+ * user defined styles having priority
+ *
+ * @param int $key The key of the keyword group to change the styles of
+ * @param string $style The style to make the keywords
+ * @param boolean $preserve_defaults Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @since 1.0.0
+ */
+ public function set_keyword_group_style($key, $style, $preserve_defaults = false) {
+ //Set the style for this keyword group
+ if('*' == $key) {
+ foreach($this->language_data['STYLES']['KEYWORDS'] as $_key => $_value) {
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['KEYWORDS'][$_key] = $style;
+ } else {
+ $this->language_data['STYLES']['KEYWORDS'][$_key] .= $style;
+ }
+ }
+ } else {
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['KEYWORDS'][$key] = $style;
+ } else {
+ $this->language_data['STYLES']['KEYWORDS'][$key] .= $style;
+ }
+ }
+
+ //Update the lexic permissions
+ if (!isset($this->lexic_permissions['KEYWORDS'][$key])) {
+ $this->lexic_permissions['KEYWORDS'][$key] = true;
+ }
+ }
+
+ /**
+ * Turns highlighting on/off for a keyword group
+ *
+ * @param int $key The key of the keyword group to turn on or off
+ * @param boolean $flag Whether to turn highlighting for that group on or off
+ * @since 1.0.0
+ */
+ public function set_keyword_group_highlighting($key, $flag = true) {
+ $this->lexic_permissions['KEYWORDS'][$key] = ($flag) ? true : false;
+ }
+
+ /**
+ * Sets the styles for comment groups. If $preserve_defaults is
+ * true, then styles are merged with the default styles, with the
+ * user defined styles having priority
+ *
+ * @param int $key The key of the comment group to change the styles of
+ * @param string $style The style to make the comments
+ * @param boolean $preserve_defaults Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @since 1.0.0
+ */
+ public function set_comments_style($key, $style, $preserve_defaults = false) {
+ if('*' == $key) {
+ foreach($this->language_data['STYLES']['COMMENTS'] as $_key => $_value) {
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['COMMENTS'][$_key] = $style;
+ } else {
+ $this->language_data['STYLES']['COMMENTS'][$_key] .= $style;
+ }
+ }
+ } else {
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['COMMENTS'][$key] = $style;
+ } else {
+ $this->language_data['STYLES']['COMMENTS'][$key] .= $style;
+ }
+ }
+ }
+
+ /**
+ * Turns highlighting on/off for comment groups
+ *
+ * @param int $key The key of the comment group to turn on or off
+ * @param boolean $flag Whether to turn highlighting for that group on or off
+ * @since 1.0.0
+ */
+ public function set_comments_highlighting($key, $flag = true) {
+ $this->lexic_permissions['COMMENTS'][$key] = ($flag) ? true : false;
+ }
+
+ /**
+ * Sets the styles for escaped characters. If $preserve_defaults is
+ * true, then styles are merged with the default styles, with the
+ * user defined styles having priority
+ *
+ * @param string $style The style to make the escape characters
+ * @param boolean $preserve_defaults Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @param int $group Tells the group of symbols for which style should be set.
+ * @since 1.0.0
+ */
+ public function set_escape_characters_style($style, $preserve_defaults = false, $group = 0) {
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['ESCAPE_CHAR'][$group] = $style;
+ } else {
+ $this->language_data['STYLES']['ESCAPE_CHAR'][$group] .= $style;
+ }
+ }
+
+ /**
+ * Turns highlighting on/off for escaped characters
+ *
+ * @param boolean $flag Whether to turn highlighting for escape characters on or off
+ * @since 1.0.0
+ */
+ public function set_escape_characters_highlighting($flag = true) {
+ $this->lexic_permissions['ESCAPE_CHAR'] = ($flag) ? true : false;
+ }
+
+ /**
+ * Sets the styles for brackets. If $preserve_defaults is
+ * true, then styles are merged with the default styles, with the
+ * user defined styles having priority
+ *
+ * This method is DEPRECATED: use set_symbols_style instead.
+ * This method will be removed in 1.2.X
+ *
+ * @param string $style The style to make the brackets
+ * @param boolean $preserve_defaults Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @since 1.0.0
+ * @deprecated In favour of set_symbols_style
+ */
+ public function set_brackets_style($style, $preserve_defaults = false) {
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['BRACKETS'][0] = $style;
+ } else {
+ $this->language_data['STYLES']['BRACKETS'][0] .= $style;
+ }
+ }
+
+ /**
+ * Turns highlighting on/off for brackets
+ *
+ * This method is DEPRECATED: use set_symbols_highlighting instead.
+ * This method will be remove in 1.2.X
+ *
+ * @param boolean $flag Whether to turn highlighting for brackets on or off
+ * @since 1.0.0
+ * @deprecated In favour of set_symbols_highlighting
+ */
+ public function set_brackets_highlighting($flag) {
+ $this->lexic_permissions['BRACKETS'] = ($flag) ? true : false;
+ }
+
+ /**
+ * Sets the styles for symbols. If $preserve_defaults is
+ * true, then styles are merged with the default styles, with the
+ * user defined styles having priority
+ *
+ * @param string $style The style to make the symbols
+ * @param boolean $preserve_defaults Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @param int $group Tells the group of symbols for which style should be set.
+ * @since 1.0.1
+ */
+ public function set_symbols_style($style, $preserve_defaults = false, $group = 0) {
+ // Update the style of symbols
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['SYMBOLS'][$group] = $style;
+ } else {
+ $this->language_data['STYLES']['SYMBOLS'][$group] .= $style;
+ }
+
+ // For backward compatibility
+ if (0 == $group) {
+ $this->set_brackets_style ($style, $preserve_defaults);
+ }
+ }
+
+ /**
+ * Turns highlighting on/off for symbols
+ *
+ * @param boolean $flag Whether to turn highlighting for symbols on or off
+ * @since 1.0.0
+ */
+ public function set_symbols_highlighting($flag) {
+ // Update lexic permissions for this symbol group
+ $this->lexic_permissions['SYMBOLS'] = ($flag) ? true : false;
+
+ // For backward compatibility
+ $this->set_brackets_highlighting ($flag);
+ }
+
+ /**
+ * Sets the styles for strings. If $preserve_defaults is
+ * true, then styles are merged with the default styles, with the
+ * user defined styles having priority
+ *
+ * @param string $style The style to make the escape characters
+ * @param boolean $preserve_defaults Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @param int $group Tells the group of strings for which style should be set.
+ * @since 1.0.0
+ */
+ public function set_strings_style($style, $preserve_defaults = false, $group = 0) {
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['STRINGS'][$group] = $style;
+ } else {
+ $this->language_data['STYLES']['STRINGS'][$group] .= $style;
+ }
+ }
+
+ /**
+ * Turns highlighting on/off for strings
+ *
+ * @param boolean $flag Whether to turn highlighting for strings on or off
+ * @since 1.0.0
+ */
+ public function set_strings_highlighting($flag) {
+ $this->lexic_permissions['STRINGS'] = ($flag) ? true : false;
+ }
+
+ /**
+ * Sets the styles for strict code blocks. If $preserve_defaults is
+ * true, then styles are merged with the default styles, with the
+ * user defined styles having priority
+ *
+ * @param string $style The style to make the script blocks
+ * @param boolean $preserve_defaults Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @param int $group Tells the group of script blocks for which style should be set.
+ * @since 1.0.8.4
+ */
+ public function set_script_style($style, $preserve_defaults = false, $group = 0) {
+ // Update the style of symbols
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['SCRIPT'][$group] = $style;
+ } else {
+ $this->language_data['STYLES']['SCRIPT'][$group] .= $style;
+ }
+ }
+
+ /**
+ * Sets the styles for numbers. If $preserve_defaults is
+ * true, then styles are merged with the default styles, with the
+ * user defined styles having priority
+ *
+ * @param string $style The style to make the numbers
+ * @param boolean $preserve_defaults Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @param int $group Tells the group of numbers for which style should be set.
+ * @since 1.0.0
+ */
+ public function set_numbers_style($style, $preserve_defaults = false, $group = 0) {
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['NUMBERS'][$group] = $style;
+ } else {
+ $this->language_data['STYLES']['NUMBERS'][$group] .= $style;
+ }
+ }
+
+ /**
+ * Turns highlighting on/off for numbers
+ *
+ * @param boolean $flag Whether to turn highlighting for numbers on or off
+ * @since 1.0.0
+ */
+ public function set_numbers_highlighting($flag) {
+ $this->lexic_permissions['NUMBERS'] = ($flag) ? true : false;
+ }
+
+ /**
+ * Sets the styles for methods. $key is a number that references the
+ * appropriate "object splitter" - see the language file for the language
+ * you are highlighting to get this number. If $preserve_defaults is
+ * true, then styles are merged with the default styles, with the
+ * user defined styles having priority
+ *
+ * @param int $key The key of the object splitter to change the styles of
+ * @param string $style The style to make the methods
+ * @param boolean $preserve_defaults Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @since 1.0.0
+ */
+ public function set_methods_style($key, $style, $preserve_defaults = false) {
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['METHODS'][$key] = $style;
+ } else {
+ $this->language_data['STYLES']['METHODS'][$key] .= $style;
+ }
+ }
+
+ /**
+ * Turns highlighting on/off for methods
+ *
+ * @param boolean $flag Whether to turn highlighting for methods on or off
+ * @since 1.0.0
+ */
+ public function set_methods_highlighting($flag) {
+ $this->lexic_permissions['METHODS'] = ($flag) ? true : false;
+ }
+
+ /**
+ * Sets the styles for regexps. If $preserve_defaults is
+ * true, then styles are merged with the default styles, with the
+ * user defined styles having priority
+ *
+ * @param string $key The style to make the regular expression matches
+ * @param boolean $style Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @param bool $preserve_defaults Whether to merge the new styles with the old or just
+ * to overwrite them
+ * @since 1.0.0
+ */
+ public function set_regexps_style($key, $style, $preserve_defaults = false) {
+ if (!$preserve_defaults) {
+ $this->language_data['STYLES']['REGEXPS'][$key] = $style;
+ } else {
+ $this->language_data['STYLES']['REGEXPS'][$key] .= $style;
+ }
+ }
+
+ /**
+ * Turns highlighting on/off for regexps
+ *
+ * @param int $key The key of the regular expression group to turn on or off
+ * @param boolean $flag Whether to turn highlighting for the regular expression group on or off
+ * @since 1.0.0
+ */
+ public function set_regexps_highlighting($key, $flag) {
+ $this->lexic_permissions['REGEXPS'][$key] = ($flag) ? true : false;
+ }
+
+ /**
+ * Sets whether a set of keywords are checked for in a case sensitive manner
+ *
+ * @param int $key The key of the keyword group to change the case sensitivity of
+ * @param boolean $case Whether to check in a case sensitive manner or not
+ * @since 1.0.0
+ */
+ public function set_case_sensitivity($key, $case) {
+ $this->language_data['CASE_SENSITIVE'][$key] = ($case) ? true : false;
+ }
+
+ /**
+ * Sets the case that keywords should use when found. Use the constants:
+ *
+ * - GESHI_CAPS_NO_CHANGE: leave keywords as-is
+ * - GESHI_CAPS_UPPER: convert all keywords to uppercase where found
+ * - GESHI_CAPS_LOWER: convert all keywords to lowercase where found
+ *
+ * @param int $case A constant specifying what to do with matched keywords
+ * @since 1.0.1
+ */
+ public function set_case_keywords($case) {
+ if (in_array($case, array(
+ GESHI_CAPS_NO_CHANGE, GESHI_CAPS_UPPER, GESHI_CAPS_LOWER))) {
+ $this->language_data['CASE_KEYWORDS'] = $case;
+ }
+ }
+
+ /**
+ * Sets how many spaces a tab is substituted for
+ *
+ * Widths below zero are ignored
+ *
+ * @param int $width The tab width
+ * @since 1.0.0
+ */
+ public function set_tab_width($width) {
+ $this->tab_width = intval($width);
+
+ //Check if it fit's the constraints:
+ if ($this->tab_width < 1) {
+ //Return it to the default
+ $this->tab_width = 8;
+ }
+ }
+
+ /**
+ * Sets whether or not to use tab-stop width specifed by language
+ *
+ * @param boolean $use Whether to use language-specific tab-stop widths
+ * @since 1.0.7.20
+ */
+ public function set_use_language_tab_width($use) {
+ $this->use_language_tab_width = (bool) $use;
+ }
+
+ /**
+ * Returns the tab width to use, based on the current language and user
+ * preference
+ *
+ * @return int Tab width
+ * @since 1.0.7.20
+ */
+ public function get_real_tab_width() {
+ if (!$this->use_language_tab_width ||
+ !isset($this->language_data['TAB_WIDTH'])) {
+ return $this->tab_width;
+ } else {
+ return $this->language_data['TAB_WIDTH'];
+ }
+ }
+
+ /**
+ * Enables/disables strict highlighting. Default is off, calling this
+ * method without parameters will turn it on. See documentation
+ * for more details on strict mode and where to use it.
+ *
+ * @param boolean $mode Whether to enable strict mode or not
+ * @since 1.0.0
+ */
+ public function enable_strict_mode($mode = true) {
+ if (GESHI_MAYBE == $this->language_data['STRICT_MODE_APPLIES']) {
+ $this->strict_mode = ($mode) ? GESHI_ALWAYS : GESHI_NEVER;
+ }
+ }
+
+ /**
+ * Disables all highlighting
+ *
+ * @since 1.0.0
+ * @todo Rewrite with array traversal
+ * @deprecated In favour of enable_highlighting
+ */
+ public function disable_highlighting() {
+ $this->enable_highlighting(false);
+ }
+
+ /**
+ * Enables all highlighting
+ *
+ * The optional flag parameter was added in version 1.0.7.21 and can be used
+ * to enable (true) or disable (false) all highlighting.
+ *
+ * @since 1.0.0
+ * @param boolean $flag A flag specifying whether to enable or disable all highlighting
+ * @todo Rewrite with array traversal
+ */
+ public function enable_highlighting($flag = true) {
+ $flag = $flag ? true : false;
+ foreach ($this->lexic_permissions as $key => $value) {
+ if (is_array($value)) {
+ foreach ($value as $k => $v) {
+ $this->lexic_permissions[$key][$k] = $flag;
+ }
+ } else {
+ $this->lexic_permissions[$key] = $flag;
+ }
+ }
+
+ // Context blocks
+ $this->enable_important_blocks = $flag;
+ }
+
+ /**
+ * Given a file extension, this method returns either a valid geshi language
+ * name, or the empty string if it couldn't be found
+ *
+ * @param string $extension The extension to get a language name for
+ * @param array $lookup A lookup array to use instead of the default one
+ * @since 1.0.5
+ * @todo Re-think about how this method works (maybe make it private and/or make it
+ * a extension->lang lookup?)
+ * @return int|string
+ */
+ public static function get_language_name_from_extension( $extension, $lookup = array() ) {
+ $extension = strtolower($extension);
+
+ if ( !is_array($lookup) || empty($lookup)) {
+ $lookup = array(
+ '6502acme' => array( 'a', 's', 'asm', 'inc' ),
+ '6502tasm' => array( 'a', 's', 'asm', 'inc' ),
+ '6502kickass' => array( 'a', 's', 'asm', 'inc' ),
+ '68000devpac' => array( 'a', 's', 'asm', 'inc' ),
+ 'abap' => array('abap'),
+ 'actionscript' => array('as'),
+ 'ada' => array('a', 'ada', 'adb', 'ads'),
+ 'apache' => array('conf'),
+ 'asm' => array('ash', 'asm', 'inc'),
+ 'asp' => array('asp'),
+ 'bash' => array('sh'),
+ 'bf' => array('bf'),
+ 'c' => array('c', 'h'),
+ 'c_mac' => array('c', 'h'),
+ 'caddcl' => array(),
+ 'cadlisp' => array(),
+ 'cdfg' => array('cdfg'),
+ 'cobol' => array('cbl'),
+ 'cpp' => array('cpp', 'hpp', 'C', 'H', 'CPP', 'HPP'),
+ 'csharp' => array('cs'),
+ 'css' => array('css'),
+ 'd' => array('d'),
+ 'delphi' => array('dpk', 'dpr', 'pp', 'pas'),
+ 'diff' => array('diff', 'patch'),
+ 'dos' => array('bat', 'cmd'),
+ 'gdb' => array('kcrash', 'crash', 'bt'),
+ 'gettext' => array('po', 'pot'),
+ 'gml' => array('gml'),
+ 'gnuplot' => array('plt'),
+ 'groovy' => array('groovy'),
+ 'haskell' => array('hs'),
+ 'haxe' => array('hx'),
+ 'html4strict' => array('html', 'htm'),
+ 'ini' => array('ini', 'desktop', 'vbp'),
+ 'java' => array('java'),
+ 'javascript' => array('js'),
+ 'klonec' => array('kl1'),
+ 'klonecpp' => array('klx'),
+ 'latex' => array('tex'),
+ 'lisp' => array('lisp'),
+ 'lua' => array('lua'),
+ 'matlab' => array('m'),
+ 'mpasm' => array(),
+ 'mysql' => array('sql'),
+ 'nsis' => array(),
+ 'objc' => array(),
+ 'oobas' => array(),
+ 'oracle8' => array(),
+ 'oracle10' => array(),
+ 'pascal' => array('pas'),
+ 'perl' => array('pl', 'pm'),
+ 'php' => array('php', 'php5', 'phtml', 'phps'),
+ 'povray' => array('pov'),
+ 'providex' => array('pvc', 'pvx'),
+ 'prolog' => array('pl'),
+ 'python' => array('py'),
+ 'qbasic' => array('bi'),
+ 'reg' => array('reg'),
+ 'ruby' => array('rb'),
+ 'sas' => array('sas'),
+ 'scala' => array('scala'),
+ 'scheme' => array('scm'),
+ 'scilab' => array('sci'),
+ 'smalltalk' => array('st'),
+ 'smarty' => array(),
+ 'tcl' => array('tcl'),
+ 'text' => array('txt'),
+ 'vb' => array('bas', 'ctl', 'frm'),
+ 'vbnet' => array('vb', 'sln'),
+ 'visualfoxpro' => array(),
+ 'whitespace' => array('ws'),
+ 'xml' => array('xml', 'svg', 'xrc', 'vbproj', 'csproj', 'userprefs', 'resx', 'stetic', 'settings', 'manifest', 'myapp'),
+ 'z80' => array('z80', 'asm', 'inc')
+ );
+ }
+
+ foreach ($lookup as $lang => $extensions) {
+ if (in_array($extension, $extensions)) {
+ return $lang;
+ }
+ }
+
+ return 'text';
+ }
+
+ /**
+ * Given a file name, this method loads its contents in, and attempts
+ * to set the language automatically. An optional lookup table can be
+ * passed for looking up the language name. If not specified a default
+ * table is used
+ *
+ * The language table is in the form
+ * <pre>array(
+ * 'lang_name' => array('extension', 'extension', ...),
+ * 'lang_name' ...
+ * );</pre>
+ *
+ * @param string $file_name The filename to load the source from
+ * @param array $lookup A lookup array to use instead of the default one
+ * @todo Complete rethink of this and above method
+ * @since 1.0.5
+ */
+ public function load_from_file($file_name, $lookup = array()) {
+ if (is_readable($file_name)) {
+ $this->set_source(file_get_contents($file_name));
+ $this->set_language(self::get_language_name_from_extension(substr(strrchr($file_name, '.'), 1), $lookup));
+ } else {
+ $this->error = GESHI_ERROR_FILE_NOT_READABLE;
+ }
+ }
+
+ /**
+ * Adds a keyword to a keyword group for highlighting
+ *
+ * @param int $key The key of the keyword group to add the keyword to
+ * @param string $word The word to add to the keyword group
+ * @since 1.0.0
+ */
+ public function add_keyword($key, $word) {
+ if (!is_array($this->language_data['KEYWORDS'][$key])) {
+ $this->language_data['KEYWORDS'][$key] = array();
+ }
+ if (!in_array($word, $this->language_data['KEYWORDS'][$key])) {
+ $this->language_data['KEYWORDS'][$key][] = $word;
+
+ //NEW in 1.0.8 don't recompile the whole optimized regexp, simply append it
+ if ($this->parse_cache_built) {
+ $subkey = count($this->language_data['CACHED_KEYWORD_LISTS'][$key]) - 1;
+ $this->language_data['CACHED_KEYWORD_LISTS'][$key][$subkey] .= '|' . preg_quote($word, '/');
+ }
+ }
+ }
+
+ /**
+ * Removes a keyword from a keyword group
+ *
+ * @param int $key The key of the keyword group to remove the keyword from
+ * @param string $word The word to remove from the keyword group
+ * @param bool $recompile Wether to automatically recompile the optimized regexp list or not.
+ * Note: if you set this to false and @see GeSHi->parse_code() was already called once,
+ * for the current language, you have to manually call @see GeSHi->optimize_keyword_group()
+ * or the removed keyword will stay in cache and still be highlighted! On the other hand
+ * it might be too expensive to recompile the regexp list for every removal if you want to
+ * remove a lot of keywords.
+ * @since 1.0.0
+ */
+ public function remove_keyword($key, $word, $recompile = true) {
+ $key_to_remove = array_search($word, $this->language_data['KEYWORDS'][$key]);
+ if ($key_to_remove !== false) {
+ unset($this->language_data['KEYWORDS'][$key][$key_to_remove]);
+
+ //NEW in 1.0.8, optionally recompile keyword group
+ if ($recompile && $this->parse_cache_built) {
+ $this->optimize_keyword_group($key);
+ }
+ }
+ }
+
+ /**
+ * Creates a new keyword group
+ *
+ * @param int $key The key of the keyword group to create
+ * @param string $styles The styles for the keyword group
+ * @param boolean $case_sensitive Whether the keyword group is case sensitive ornot
+ * @param array $words The words to use for the keyword group
+ * @since 1.0.0
+ * @return bool
+ */
+ public function add_keyword_group($key, $styles, $case_sensitive = true, $words = array()) {
+ $words = (array) $words;
+ if (empty($words)) {
+ // empty word lists mess up highlighting
+ return false;
+ }
+
+ //Add the new keyword group internally
+ $this->language_data['KEYWORDS'][$key] = $words;
+ $this->lexic_permissions['KEYWORDS'][$key] = true;
+ $this->language_data['CASE_SENSITIVE'][$key] = $case_sensitive;
+ $this->language_data['STYLES']['KEYWORDS'][$key] = $styles;
+
+ //NEW in 1.0.8, cache keyword regexp
+ if ($this->parse_cache_built) {
+ $this->optimize_keyword_group($key);
+ }
+ return true;
+ }
+
+ /**
+ * Removes a keyword group
+ *
+ * @param int $key The key of the keyword group to remove
+ * @since 1.0.0
+ */
+ public function remove_keyword_group ($key) {
+ //Remove the keyword group internally
+ unset($this->language_data['KEYWORDS'][$key]);
+ unset($this->lexic_permissions['KEYWORDS'][$key]);
+ unset($this->language_data['CASE_SENSITIVE'][$key]);
+ unset($this->language_data['STYLES']['KEYWORDS'][$key]);
+
+ //NEW in 1.0.8
+ unset($this->language_data['CACHED_KEYWORD_LISTS'][$key]);
+ }
+
+ /**
+ * compile optimized regexp list for keyword group
+ *
+ * @param int $key The key of the keyword group to compile & optimize
+ * @since 1.0.8
+ */
+ public function optimize_keyword_group($key) {
+ $this->language_data['CACHED_KEYWORD_LISTS'][$key] =
+ $this->optimize_regexp_list($this->language_data['KEYWORDS'][$key]);
+ $space_as_whitespace = false;
+ if(isset($this->language_data['PARSER_CONTROL'])) {
+ if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS'])) {
+ if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS']['SPACE_AS_WHITESPACE'])) {
+ $space_as_whitespace = $this->language_data['PARSER_CONTROL']['KEYWORDS']['SPACE_AS_WHITESPACE'];
+ }
+ if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$key]['SPACE_AS_WHITESPACE'])) {
+ if(isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$key]['SPACE_AS_WHITESPACE'])) {
+ $space_as_whitespace = $this->language_data['PARSER_CONTROL']['KEYWORDS'][$key]['SPACE_AS_WHITESPACE'];
+ }
+ }
+ }
+ }
+ if($space_as_whitespace) {
+ foreach($this->language_data['CACHED_KEYWORD_LISTS'][$key] as $rxk => $rxv) {
+ $this->language_data['CACHED_KEYWORD_LISTS'][$key][$rxk] =
+ str_replace(" ", "\\s+", $rxv);
+ }
+ }
+ }
+
+ /**
+ * Sets the content of the header block
+ *
+ * @param string $content The content of the header block
+ * @since 1.0.2
+ */
+ public function set_header_content($content) {
+ $this->header_content = $content;
+ }
+
+ /**
+ * Sets the content of the footer block
+ *
+ * @param string $content The content of the footer block
+ * @since 1.0.2
+ */
+ public function set_footer_content($content) {
+ $this->footer_content = $content;
+ }
+
+ /**
+ * Sets the style for the header content
+ *
+ * @param string $style The style for the header content
+ * @since 1.0.2
+ */
+ public function set_header_content_style($style) {
+ $this->header_content_style = $style;
+ }
+
+ /**
+ * Sets the style for the footer content
+ *
+ * @param string $style The style for the footer content
+ * @since 1.0.2
+ */
+ public function set_footer_content_style($style) {
+ $this->footer_content_style = $style;
+ }
+
+ /**
+ * Sets whether to force a surrounding block around
+ * the highlighted code or not
+ *
+ * @param boolean $flag Tells whether to enable or disable this feature
+ * @since 1.0.7.20
+ */
+ public function enable_inner_code_block($flag) {
+ $this->force_code_block = (bool)$flag;
+ }
+
+ /**
+ * Sets the base URL to be used for keywords
+ *
+ * @param int $group The key of the keyword group to set the URL for
+ * @param string $url The URL to set for the group. If {FNAME} is in
+ * the url somewhere, it is replaced by the keyword
+ * that the URL is being made for
+ * @since 1.0.2
+ */
+ public function set_url_for_keyword_group($group, $url) {
+ $this->language_data['URLS'][$group] = $url;
+ }
+
+ /**
+ * Sets styles for links in code
+ *
+ * @param int $type A constant that specifies what state the style is being
+ * set for - e.g. :hover or :visited
+ * @param string $styles The styles to use for that state
+ * @since 1.0.2
+ */
+ public function set_link_styles($type, $styles) {
+ $this->link_styles[$type] = $styles;
+ }
+
+ /**
+ * Sets the target for links in code
+ *
+ * @param string $target The target for links in the code, e.g. _blank
+ * @since 1.0.3
+ */
+ public function set_link_target($target) {
+ if (!$target) {
+ $this->link_target = '';
+ } else {
+ $this->link_target = ' target="' . $target . '"';
+ }
+ }
+
+ /**
+ * Sets styles for important parts of the code
+ *
+ * @param string $styles The styles to use on important parts of the code
+ * @since 1.0.2
+ */
+ public function set_important_styles($styles) {
+ $this->important_styles = $styles;
+ }
+
+ /**
+ * Sets whether context-important blocks are highlighted
+ *
+ * @param boolean $flag Tells whether to enable or disable highlighting of important blocks
+ * @todo REMOVE THIS SHIZ FROM GESHI!
+ * @deprecated
+ * @since 1.0.2
+ */
+ public function enable_important_blocks($flag) {
+ $this->enable_important_blocks = ( $flag ) ? true : false;
+ }
+
+ /**
+ * Whether CSS IDs should be added to each line
+ *
+ * @param boolean $flag If true, IDs will be added to each line.
+ * @since 1.0.2
+ */
+ public function enable_ids($flag = true) {
+ $this->add_ids = ($flag) ? true : false;
+ }
+
+ /**
+ * Specifies which lines to highlight extra
+ *
+ * The extra style parameter was added in 1.0.7.21.
+ *
+ * @param mixed $lines An array of line numbers to highlight, or just a line
+ * number on its own.
+ * @param string $style A string specifying the style to use for this line.
+ * If null is specified, the default style is used.
+ * If false is specified, the line will be removed from
+ * special highlighting
+ * @since 1.0.2
+ * @todo Some data replication here that could be cut down on
+ */
+ public function highlight_lines_extra($lines, $style = null) {
+ if (is_array($lines)) {
+ //Split up the job using single lines at a time
+ foreach ($lines as $line) {
+ $this->highlight_lines_extra($line, $style);
+ }
+ } else {
+ //Mark the line as being highlighted specially
+ $lines = intval($lines);
+ $this->highlight_extra_lines[$lines] = $lines;
+
+ //Decide on which style to use
+ if ($style === null) { //Check if we should use default style
+ unset($this->highlight_extra_lines_styles[$lines]);
+ } elseif ($style === false) { //Check if to remove this line
+ unset($this->highlight_extra_lines[$lines]);
+ unset($this->highlight_extra_lines_styles[$lines]);
+ } else {
+ $this->highlight_extra_lines_styles[$lines] = $style;
+ }
+ }
+ }
+
+ /**
+ * Sets the style for extra-highlighted lines
+ *
+ * @param string $styles The style for extra-highlighted lines
+ * @since 1.0.2
+ */
+ public function set_highlight_lines_extra_style($styles) {
+ $this->highlight_extra_lines_style = $styles;
+ }
+
+ /**
+ * Sets the line-ending
+ *
+ * @param string $line_ending The new line-ending
+ * @since 1.0.2
+ */
+ public function set_line_ending($line_ending) {
+ $this->line_ending = (string)$line_ending;
+ }
+
+ /**
+ * Sets what number line numbers should start at. Should
+ * be a positive integer, and will be converted to one.
+ *
+ * <b>Warning:</b> Using this method will add the "start"
+ * attribute to the &lt;ol&gt; that is used for line numbering.
+ * This is <b>not</b> valid XHTML strict, so if that's what you
+ * care about then don't use this method. Firefox is getting
+ * support for the CSS method of doing this in 1.1 and Opera
+ * has support for the CSS method, but (of course) IE doesn't
+ * so it's not worth doing it the CSS way yet.
+ *
+ * @param int $number The number to start line numbers at
+ * @since 1.0.2
+ */
+ public function start_line_numbers_at($number) {
+ $this->line_numbers_start = abs(intval($number));
+ }
+
+ /**
+ * Sets the encoding used for htmlspecialchars(), for international
+ * support.
+ *
+ * NOTE: This is not needed for now because htmlspecialchars() is not
+ * being used (it has a security hole in PHP4 that has not been patched).
+ * Maybe in a future version it may make a return for speed reasons, but
+ * I doubt it.
+ *
+ * @param string $encoding The encoding to use for the source
+ * @since 1.0.3
+ */
+ public function set_encoding($encoding) {
+ if ($encoding) {
+ $this->encoding = strtolower($encoding);
+ }
+ }
+
+ /**
+ * Turns linking of keywords on or off.
+ *
+ * @param boolean $enable If true, links will be added to keywords
+ * @since 1.0.2
+ */
+ public function enable_keyword_links($enable = true) {
+ $this->keyword_links = (bool) $enable;
+ }
+
+ /**
+ * Setup caches needed for styling. This is automatically called in
+ * parse_code() and get_stylesheet() when appropriate. This function helps
+ * stylesheet generators as they rely on some style information being
+ * preprocessed
+ *
+ * @since 1.0.8
+ */
+ protected function build_style_cache() {
+ //Build the style cache needed to highlight numbers appropriate
+ if($this->lexic_permissions['NUMBERS']) {
+ //First check what way highlighting information for numbers are given
+ if(!isset($this->language_data['NUMBERS'])) {
+ $this->language_data['NUMBERS'] = 0;
+ }
+
+ if(is_array($this->language_data['NUMBERS'])) {
+ $this->language_data['NUMBERS_CACHE'] = $this->language_data['NUMBERS'];
+ } else {
+ $this->language_data['NUMBERS_CACHE'] = array();
+ if(!$this->language_data['NUMBERS']) {
+ $this->language_data['NUMBERS'] =
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_FLT_NONSCI;
+ }
+
+ for($i = 0, $j = $this->language_data['NUMBERS']; $j > 0; ++$i, $j>>=1) {
+ //Rearrange style indices if required ...
+ if(isset($this->language_data['STYLES']['NUMBERS'][1<<$i])) {
+ $this->language_data['STYLES']['NUMBERS'][$i] =
+ $this->language_data['STYLES']['NUMBERS'][1<<$i];
+ unset($this->language_data['STYLES']['NUMBERS'][1<<$i]);
+ }
+
+ //Check if this bit is set for highlighting
+ if($j&1) {
+ //So this bit is set ...
+ //Check if it belongs to group 0 or the actual stylegroup
+ if(isset($this->language_data['STYLES']['NUMBERS'][$i])) {
+ $this->language_data['NUMBERS_CACHE'][$i] = 1 << $i;
+ } else {
+ if(!isset($this->language_data['NUMBERS_CACHE'][0])) {
+ $this->language_data['NUMBERS_CACHE'][0] = 0;
+ }
+ $this->language_data['NUMBERS_CACHE'][0] |= 1 << $i;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Setup caches needed for parsing. This is automatically called in parse_code() when appropriate.
+ * This function makes stylesheet generators much faster as they do not need these caches.
+ *
+ * @since 1.0.8
+ */
+ protected function build_parse_cache() {
+ // check whether language_data is available
+ if (empty($this->language_data)) {
+ return false;
+ }
+
+ // cache symbol regexp
+ //As this is a costy operation, we avoid doing it for multiple groups ...
+ //Instead we perform it for all symbols at once.
+ //
+ //For this to work, we need to reorganize the data arrays.
+ if ($this->lexic_permissions['SYMBOLS'] && !empty($this->language_data['SYMBOLS'])) {
+ $this->language_data['MULTIPLE_SYMBOL_GROUPS'] = count($this->language_data['STYLES']['SYMBOLS']) > 1;
+
+ $this->language_data['SYMBOL_DATA'] = array();
+ $symbol_preg_multi = array(); // multi char symbols
+ $symbol_preg_single = array(); // single char symbols
+ foreach ($this->language_data['SYMBOLS'] as $key => $symbols) {
+ if (is_array($symbols)) {
+ foreach ($symbols as $sym) {
+ $sym = $this->hsc($sym);
+ if (!isset($this->language_data['SYMBOL_DATA'][$sym])) {
+ $this->language_data['SYMBOL_DATA'][$sym] = $key;
+ if (isset($sym[1])) { // multiple chars
+ $symbol_preg_multi[] = preg_quote($sym, '/');
+ } else { // single char
+ if ($sym == '-') {
+ // don't trigger range out of order error
+ $symbol_preg_single[] = '\-';
+ } else {
+ $symbol_preg_single[] = preg_quote($sym, '/');
+ }
+ }
+ }
+ }
+ } else {
+ $symbols = $this->hsc($symbols);
+ if (!isset($this->language_data['SYMBOL_DATA'][$symbols])) {
+ $this->language_data['SYMBOL_DATA'][$symbols] = 0;
+ if (isset($symbols[1])) { // multiple chars
+ $symbol_preg_multi[] = preg_quote($symbols, '/');
+ } elseif ($symbols == '-') {
+ // don't trigger range out of order error
+ $symbol_preg_single[] = '\-';
+ } else { // single char
+ $symbol_preg_single[] = preg_quote($symbols, '/');
+ }
+ }
+ }
+ }
+
+ //Now we have an array with each possible symbol as the key and the style as the actual data.
+ //This way we can set the correct style just the moment we highlight ...
+ //
+ //Now we need to rewrite our array to get a search string that
+ $symbol_preg = array();
+ if (!empty($symbol_preg_multi)) {
+ rsort($symbol_preg_multi);
+ $symbol_preg[] = implode('|', $symbol_preg_multi);
+ }
+ if (!empty($symbol_preg_single)) {
+ rsort($symbol_preg_single);
+ $symbol_preg[] = '[' . implode('', $symbol_preg_single) . ']';
+ }
+ $this->language_data['SYMBOL_SEARCH'] = implode("|", $symbol_preg);
+ }
+
+ // cache optimized regexp for keyword matching
+ // remove old cache
+ $this->language_data['CACHED_KEYWORD_LISTS'] = array();
+ foreach (array_keys($this->language_data['KEYWORDS']) as $key) {
+ if (!isset($this->lexic_permissions['KEYWORDS'][$key]) ||
+ $this->lexic_permissions['KEYWORDS'][$key]) {
+ $this->optimize_keyword_group($key);
+ }
+ }
+
+ // brackets
+ if ($this->lexic_permissions['BRACKETS']) {
+ $this->language_data['CACHE_BRACKET_MATCH'] = array('[', ']', '(', ')', '{', '}');
+ if (!$this->use_classes && isset($this->language_data['STYLES']['BRACKETS'][0])) {
+ $this->language_data['CACHE_BRACKET_REPLACE'] = array(
+ '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#91;|>',
+ '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#93;|>',
+ '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#40;|>',
+ '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#41;|>',
+ '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#123;|>',
+ '<| style="' . $this->language_data['STYLES']['BRACKETS'][0] . '">&#125;|>',
+ );
+ }
+ else {
+ $this->language_data['CACHE_BRACKET_REPLACE'] = array(
+ '<| class="br0">&#91;|>',
+ '<| class="br0">&#93;|>',
+ '<| class="br0">&#40;|>',
+ '<| class="br0">&#41;|>',
+ '<| class="br0">&#123;|>',
+ '<| class="br0">&#125;|>',
+ );
+ }
+ }
+
+ //Build the parse cache needed to highlight numbers appropriate
+ if($this->lexic_permissions['NUMBERS']) {
+ //Check if the style rearrangements have been processed ...
+ //This also does some preprocessing to check which style groups are useable ...
+ if(!isset($this->language_data['NUMBERS_CACHE'])) {
+ $this->build_style_cache();
+ }
+
+ //Number format specification
+ //All this formats are matched case-insensitively!
+ static $numbers_format = array(
+ GESHI_NUMBER_INT_BASIC =>
+ '(?:(?<![0-9a-z_\.%$@])|(?<=\.\.))(?<![\d\.]e[+\-])([1-9]\d*?|0)(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_INT_CSTYLE =>
+ '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])([1-9]\d*?|0)l(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_BIN_SUFFIX =>
+ '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])[01]+?[bB](?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_BIN_PREFIX_PERCENT =>
+ '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])%[01]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_BIN_PREFIX_0B =>
+ '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])0b[01]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_OCT_PREFIX =>
+ '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0[0-7]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_OCT_PREFIX_0O =>
+ '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])0o[0-7]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_OCT_PREFIX_AT =>
+ '(?<![0-9a-z_\.%])(?<![\d\.]e[+\-])\@[0-7]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_OCT_SUFFIX =>
+ '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])[0-7]+?o(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_HEX_PREFIX =>
+ '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0x[0-9a-fA-F]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_HEX_PREFIX_DOLLAR =>
+ '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\$[0-9a-fA-F]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_HEX_SUFFIX =>
+ '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\d[0-9a-fA-F]*?[hH](?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_FLT_NONSCI =>
+ '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\d+?\.\d+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_FLT_NONSCI_F =>
+ '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)f(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_FLT_SCI_SHORT =>
+ '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])\.\d+?(?:e[+\-]?\d+?)?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ GESHI_NUMBER_FLT_SCI_ZERO =>
+ '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])(?:\d+?(?:\.\d*?)?|\.\d+?)(?:e[+\-]?\d+?)?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)'
+ );
+
+ //At this step we have an associative array with flag groups for a
+ //specific style or an string denoting a regexp given its index.
+ $this->language_data['NUMBERS_RXCACHE'] = array();
+ foreach($this->language_data['NUMBERS_CACHE'] as $key => $rxdata) {
+ if(is_string($rxdata)) {
+ $regexp = $rxdata;
+ } else {
+ //This is a bitfield of number flags to highlight:
+ //Build an array, implode them together and make this the actual RX
+ $rxuse = array();
+ for($i = 1; $i <= $rxdata; $i<<=1) {
+ if($rxdata & $i) {
+ $rxuse[] = $numbers_format[$i];
+ }
+ }
+ $regexp = implode("|", $rxuse);
+ }
+
+ $this->language_data['NUMBERS_RXCACHE'][$key] =
+ "/(?<!<\|\/)(?<!<\|!REG3XP)(?<!<\|\/NUM!)(?<!\d\/>)($regexp)(?!(?:<DOT>|(?>[^\<]))+>)(?![^<]*>)(?!\|>)(?!\/>)/i";
+ }
+
+ if(!isset($this->language_data['PARSER_CONTROL']['NUMBERS']['PRECHECK_RX'])) {
+ $this->language_data['PARSER_CONTROL']['NUMBERS']['PRECHECK_RX'] = '#\d#';
+ }
+ }
+
+ $this->parse_cache_built = true;
+ }
+
+ /**
+ * Returns the code in $this->source, highlighted and surrounded by the
+ * nessecary HTML.
+ *
+ * This should only be called ONCE, cos it's SLOW! If you want to highlight
+ * the same source multiple times, you're better off doing a whole lot of
+ * str_replaces to replace the &lt;span&gt;s
+ *
+ * @since 1.0.0
+ */
+ public function parse_code() {
+ // Start the timer
+ $start_time = microtime();
+
+ // Replace all newlines to a common form.
+ $code = str_replace("\r\n", "\n", $this->source);
+ $code = str_replace("\r", "\n", $code);
+
+ // check whether language_data is available
+ if (empty($this->language_data)) {
+ $this->error = GESHI_ERROR_NO_SUCH_LANG;
+ }
+
+ // Firstly, if there is an error, we won't highlight
+ if ($this->error) {
+ //Escape the source for output
+ $result = $this->hsc($this->source);
+
+ //This fix is related to SF#1923020, but has to be applied regardless of
+ //actually highlighting symbols.
+ $result = str_replace(array('<SEMI>', '<PIPE>'), array(';', '|'), $result);
+
+ // Timing is irrelevant
+ $this->set_time($start_time, $start_time);
+ $this->finalise($result);
+ return $result;
+ }
+
+ // make sure the parse cache is up2date
+ if (!$this->parse_cache_built) {
+ $this->build_parse_cache();
+ }
+
+ // Initialise various stuff
+ $length = strlen($code);
+ $COMMENT_MATCHED = false;
+ $stuff_to_parse = '';
+ $endresult = '';
+
+ // "Important" selections are handled like multiline comments
+ // @todo GET RID OF THIS SHIZ
+ if ($this->enable_important_blocks) {
+ $this->language_data['COMMENT_MULTI'][GESHI_START_IMPORTANT] = GESHI_END_IMPORTANT;
+ }
+
+ if ($this->strict_mode) {
+ // Break the source into bits. Each bit will be a portion of the code
+ // within script delimiters - for example, HTML between < and >
+ $k = 0;
+ $parts = array();
+ $matches = array();
+ $next_match_pointer = null;
+ // we use a copy to unset delimiters on demand (when they are not found)
+ $delim_copy = $this->language_data['SCRIPT_DELIMITERS'];
+ $i = 0;
+ while ($i < $length) {
+ $next_match_pos = $length + 1; // never true
+ foreach ($delim_copy as $dk => $delimiters) {
+ if(is_array($delimiters)) {
+ foreach ($delimiters as $open => $close) {
+ // make sure the cache is setup properly
+ if (!isset($matches[$dk][$open])) {
+ $matches[$dk][$open] = array(
+ 'next_match' => -1,
+ 'dk' => $dk,
+
+ 'open' => $open, // needed for grouping of adjacent code blocks (see below)
+ 'open_strlen' => strlen($open),
+
+ 'close' => $close,
+ 'close_strlen' => strlen($close),
+ );
+ }
+ // Get the next little bit for this opening string
+ if ($matches[$dk][$open]['next_match'] < $i) {
+ // only find the next pos if it was not already cached
+ $open_pos = strpos($code, $open, $i);
+ if ($open_pos === false) {
+ // no match for this delimiter ever
+ unset($delim_copy[$dk][$open]);
+ continue;
+ }
+ $matches[$dk][$open]['next_match'] = $open_pos;
+ }
+ if ($matches[$dk][$open]['next_match'] < $next_match_pos) {
+ //So we got a new match, update the close_pos
+ $matches[$dk][$open]['close_pos'] =
+ strpos($code, $close, $matches[$dk][$open]['next_match']+1);
+
+ $next_match_pointer =& $matches[$dk][$open];
+ $next_match_pos = $matches[$dk][$open]['next_match'];
+ }
+ }
+ } else {
+ //So we should match an RegExp as Strict Block ...
+ /**
+ * The value in $delimiters is expected to be an RegExp
+ * containing exactly 2 matching groups:
+ * - Group 1 is the opener
+ * - Group 2 is the closer
+ */
+ if(preg_match($delimiters, $code, $matches_rx, PREG_OFFSET_CAPTURE, $i)) {
+ //We got a match ...
+ if(isset($matches_rx['start']) && isset($matches_rx['end']))
+ {
+ $matches[$dk] = array(
+ 'next_match' => $matches_rx['start'][1],
+ 'dk' => $dk,
+
+ 'close_strlen' => strlen($matches_rx['end'][0]),
+ 'close_pos' => $matches_rx['end'][1],
+ );
+ } else {
+ $matches[$dk] = array(
+ 'next_match' => $matches_rx[1][1],
+ 'dk' => $dk,
+
+ 'close_strlen' => strlen($matches_rx[2][0]),
+ 'close_pos' => $matches_rx[2][1],
+ );
+ }
+ } else {
+ // no match for this delimiter ever
+ unset($delim_copy[$dk]);
+ continue;
+ }
+
+ if ($matches[$dk]['next_match'] <= $next_match_pos) {
+ $next_match_pointer =& $matches[$dk];
+ $next_match_pos = $matches[$dk]['next_match'];
+ }
+ }
+ }
+
+ // non-highlightable text
+ $parts[$k] = array(
+ 1 => substr($code, $i, $next_match_pos - $i)
+ );
+ ++$k;
+
+ if ($next_match_pos > $length) {
+ // out of bounds means no next match was found
+ break;
+ }
+
+ // highlightable code
+ $parts[$k][0] = $next_match_pointer['dk'];
+
+ //Only combine for non-rx script blocks
+ if(is_array($delim_copy[$next_match_pointer['dk']])) {
+ // group adjacent script blocks, e.g. <foobar><asdf> should be one block, not three!
+ $i = $next_match_pos + $next_match_pointer['open_strlen'];
+ while (true) {
+ $close_pos = strpos($code, $next_match_pointer['close'], $i);
+ if ($close_pos == false) {
+ break;
+ }
+ $i = $close_pos + $next_match_pointer['close_strlen'];
+ if ($i == $length) {
+ break;
+ }
+ if ($code[$i] == $next_match_pointer['open'][0] && ($next_match_pointer['open_strlen'] == 1 ||
+ substr($code, $i, $next_match_pointer['open_strlen']) == $next_match_pointer['open'])) {
+ // merge adjacent but make sure we don't merge things like <tag><!-- comment -->
+ foreach ($matches as $submatches) {
+ foreach ($submatches as $match) {
+ if ($match['next_match'] == $i) {
+ // a different block already matches here!
+ break 3;
+ }
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ } else {
+ $close_pos = $next_match_pointer['close_pos'] + $next_match_pointer['close_strlen'];
+ $i = $close_pos;
+ }
+
+ if ($close_pos === false) {
+ // no closing delimiter found!
+ $parts[$k][1] = substr($code, $next_match_pos);
+ ++$k;
+ break;
+ } else {
+ $parts[$k][1] = substr($code, $next_match_pos, $i - $next_match_pos);
+ ++$k;
+ }
+ }
+ unset($delim_copy, $next_match_pointer, $next_match_pos, $matches);
+ $num_parts = $k;
+
+ if ($num_parts == 1 && $this->strict_mode == GESHI_MAYBE) {
+ // when we have only one part, we don't have anything to highlight at all.
+ // if we have a "maybe" strict language, this should be handled as highlightable code
+ $parts = array(
+ 0 => array(
+ 0 => '',
+ 1 => ''
+ ),
+ 1 => array(
+ 0 => null,
+ 1 => $parts[0][1]
+ )
+ );
+ $num_parts = 2;
+ }
+
+ } else {
+ // Not strict mode - simply dump the source into
+ // the array at index 1 (the first highlightable block)
+ $parts = array(
+ 0 => array(
+ 0 => '',
+ 1 => ''
+ ),
+ 1 => array(
+ 0 => null,
+ 1 => $code
+ )
+ );
+ $num_parts = 2;
+ }
+
+ //Unset variables we won't need any longer
+ unset($code);
+
+ //Preload some repeatedly used values regarding hardquotes ...
+ $hq = isset($this->language_data['HARDQUOTE']) ? $this->language_data['HARDQUOTE'][0] : false;
+ $hq_strlen = strlen($hq);
+
+ //Preload if line numbers are to be generated afterwards
+ //Added a check if line breaks should be forced even without line numbers, fixes SF#1727398
+ $check_linenumbers = $this->line_numbers != GESHI_NO_LINE_NUMBERS ||
+ !empty($this->highlight_extra_lines) || !$this->allow_multiline_span;
+
+ //preload the escape char for faster checking ...
+ $escaped_escape_char = $this->hsc($this->language_data['ESCAPE_CHAR']);
+
+ // this is used for single-line comments
+ $sc_disallowed_before = "";
+ $sc_disallowed_after = "";
+
+ if (isset($this->language_data['PARSER_CONTROL'])) {
+ if (isset($this->language_data['PARSER_CONTROL']['COMMENTS'])) {
+ if (isset($this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_BEFORE'])) {
+ $sc_disallowed_before = $this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_BEFORE'];
+ }
+ if (isset($this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_AFTER'])) {
+ $sc_disallowed_after = $this->language_data['PARSER_CONTROL']['COMMENTS']['DISALLOWED_AFTER'];
+ }
+ }
+ }
+
+ //Fix for SF#1932083: Multichar Quotemarks unsupported
+ $is_string_starter = array();
+ if ($this->lexic_permissions['STRINGS']) {
+ foreach ($this->language_data['QUOTEMARKS'] as $quotemark) {
+ if (!isset($is_string_starter[$quotemark[0]])) {
+ $is_string_starter[$quotemark[0]] = (string)$quotemark;
+ } elseif (is_string($is_string_starter[$quotemark[0]])) {
+ $is_string_starter[$quotemark[0]] = array(
+ $is_string_starter[$quotemark[0]],
+ $quotemark);
+ } else {
+ $is_string_starter[$quotemark[0]][] = $quotemark;
+ }
+ }
+ }
+
+ // Now we go through each part. We know that even-indexed parts are
+ // code that shouldn't be highlighted, and odd-indexed parts should
+ // be highlighted
+ for ($key = 0; $key < $num_parts; ++$key) {
+ $STRICTATTRS = '';
+
+ // If this block should be highlighted...
+ if (!($key & 1)) {
+ // Else not a block to highlight
+ $endresult .= $this->hsc($parts[$key][1]);
+ unset($parts[$key]);
+ continue;
+ }
+
+ $result = '';
+ $part = $parts[$key][1];
+
+ $highlight_part = true;
+ if ($this->strict_mode && !is_null($parts[$key][0])) {
+ // get the class key for this block of code
+ $script_key = $parts[$key][0];
+ $highlight_part = $this->language_data['HIGHLIGHT_STRICT_BLOCK'][$script_key];
+ if ($this->language_data['STYLES']['SCRIPT'][$script_key] != '' &&
+ $this->lexic_permissions['SCRIPT']) {
+ // Add a span element around the source to
+ // highlight the overall source block
+ if (!$this->use_classes &&
+ $this->language_data['STYLES']['SCRIPT'][$script_key] != '') {
+ $attributes = ' style="' . $this->language_data['STYLES']['SCRIPT'][$script_key] . '"';
+ } else {
+ $attributes = ' class="sc' . $script_key . '"';
+ }
+ $result .= "<span$attributes>";
+ $STRICTATTRS = $attributes;
+ }
+ }
+
+ if ($highlight_part) {
+ // Now, highlight the code in this block. This code
+ // is really the engine of GeSHi (along with the method
+ // parse_non_string_part).
+
+ // cache comment regexps incrementally
+ $next_comment_regexp_key = '';
+ $next_comment_regexp_pos = -1;
+ $next_comment_multi_pos = -1;
+ $next_comment_single_pos = -1;
+ $comment_regexp_cache_per_key = array();
+ $comment_multi_cache_per_key = array();
+ $comment_single_cache_per_key = array();
+ $next_open_comment_multi = '';
+ $next_comment_single_key = '';
+ $escape_regexp_cache_per_key = array();
+ $next_escape_regexp_key = '';
+ $next_escape_regexp_pos = -1;
+
+ $length = strlen($part);
+ for ($i = 0; $i < $length; ++$i) {
+ // Get the next char
+ $char = $part[$i];
+ $char_len = 1;
+
+ // update regexp comment cache if needed
+ if (isset($this->language_data['COMMENT_REGEXP']) && $next_comment_regexp_pos < $i) {
+ $next_comment_regexp_pos = $length;
+ foreach ($this->language_data['COMMENT_REGEXP'] as $comment_key => $regexp) {
+ $match_i = false;
+ if (isset($comment_regexp_cache_per_key[$comment_key]) &&
+ ($comment_regexp_cache_per_key[$comment_key]['pos'] >= $i ||
+ $comment_regexp_cache_per_key[$comment_key]['pos'] === false)) {
+ // we have already matched something
+ if ($comment_regexp_cache_per_key[$comment_key]['pos'] === false) {
+ // this comment is never matched
+ continue;
+ }
+ $match_i = $comment_regexp_cache_per_key[$comment_key]['pos'];
+ } elseif (preg_match($regexp, $part, $match, PREG_OFFSET_CAPTURE, $i)) {
+ $match_i = $match[0][1];
+
+ $comment_regexp_cache_per_key[$comment_key] = array(
+ 'key' => $comment_key,
+ 'length' => strlen($match[0][0]),
+ 'pos' => $match_i
+ );
+ } else {
+ $comment_regexp_cache_per_key[$comment_key]['pos'] = false;
+ continue;
+ }
+
+ if ($match_i !== false && $match_i < $next_comment_regexp_pos) {
+ $next_comment_regexp_pos = $match_i;
+ $next_comment_regexp_key = $comment_key;
+ if ($match_i === $i) {
+ break;
+ }
+ }
+ }
+ }
+
+ $string_started = false;
+
+ if (isset($is_string_starter[$char])) {
+ // Possibly the start of a new string ...
+
+ //Check which starter it was ...
+ //Fix for SF#1932083: Multichar Quotemarks unsupported
+ if (is_array($is_string_starter[$char])) {
+ $char_new = '';
+ foreach ($is_string_starter[$char] as $testchar) {
+ if ($testchar === substr($part, $i, strlen($testchar)) &&
+ strlen($testchar) > strlen($char_new)) {
+ $char_new = $testchar;
+ $string_started = true;
+ }
+ }
+ if ($string_started) {
+ $char = $char_new;
+ }
+ } else {
+ $testchar = $is_string_starter[$char];
+ if ($testchar === substr($part, $i, strlen($testchar))) {
+ $char = $testchar;
+ $string_started = true;
+ }
+ }
+ $char_len = strlen($char);
+ }
+
+ if ($string_started && ($i != $next_comment_regexp_pos)) {
+ // Hand out the correct style information for this string
+ $string_key = array_search($char, $this->language_data['QUOTEMARKS']);
+ if (!isset($this->language_data['STYLES']['STRINGS'][$string_key]) ||
+ !isset($this->language_data['STYLES']['ESCAPE_CHAR'][$string_key])) {
+ $string_key = 0;
+ }
+
+ // parse the stuff before this
+ $result .= $this->parse_non_string_part($stuff_to_parse);
+ $stuff_to_parse = '';
+
+ if (!$this->use_classes) {
+ $string_attributes = ' style="' . $this->language_data['STYLES']['STRINGS'][$string_key] . '"';
+ } else {
+ $string_attributes = ' class="st'.$string_key.'"';
+ }
+
+ // now handle the string
+ $string = "<span$string_attributes>" . GeSHi::hsc($char);
+ $start = $i + $char_len;
+ $string_open = true;
+
+ if(empty($this->language_data['ESCAPE_REGEXP'])) {
+ $next_escape_regexp_pos = $length;
+ }
+
+ do {
+ //Get the regular ending pos ...
+ $close_pos = strpos($part, $char, $start);
+ if(false === $close_pos) {
+ $close_pos = $length;
+ }
+
+ if($this->lexic_permissions['ESCAPE_CHAR']) {
+ // update escape regexp cache if needed
+ if (isset($this->language_data['ESCAPE_REGEXP']) && $next_escape_regexp_pos < $start) {
+ $next_escape_regexp_pos = $length;
+ foreach ($this->language_data['ESCAPE_REGEXP'] as $escape_key => $regexp) {
+ $match_i = false;
+ if (isset($escape_regexp_cache_per_key[$escape_key]) &&
+ ($escape_regexp_cache_per_key[$escape_key]['pos'] >= $start ||
+ $escape_regexp_cache_per_key[$escape_key]['pos'] === false)) {
+ // we have already matched something
+ if ($escape_regexp_cache_per_key[$escape_key]['pos'] === false) {
+ // this comment is never matched
+ continue;
+ }
+ $match_i = $escape_regexp_cache_per_key[$escape_key]['pos'];
+ } elseif (preg_match($regexp, $part, $match, PREG_OFFSET_CAPTURE, $start)) {
+ $match_i = $match[0][1];
+
+ $escape_regexp_cache_per_key[$escape_key] = array(
+ 'key' => $escape_key,
+ 'length' => strlen($match[0][0]),
+ 'pos' => $match_i
+ );
+ } else {
+ $escape_regexp_cache_per_key[$escape_key]['pos'] = false;
+ continue;
+ }
+
+ if ($match_i !== false && $match_i < $next_escape_regexp_pos) {
+ $next_escape_regexp_pos = $match_i;
+ $next_escape_regexp_key = $escape_key;
+ if ($match_i === $start) {
+ break;
+ }
+ }
+ }
+ }
+
+ //Find the next simple escape position
+ if('' != $this->language_data['ESCAPE_CHAR']) {
+ $simple_escape = strpos($part, $this->language_data['ESCAPE_CHAR'], $start);
+ if(false === $simple_escape) {
+ $simple_escape = $length;
+ }
+ } else {
+ $simple_escape = $length;
+ }
+ } else {
+ $next_escape_regexp_pos = $length;
+ $simple_escape = $length;
+ }
+
+ if($simple_escape < $next_escape_regexp_pos &&
+ $simple_escape < $length &&
+ $simple_escape < $close_pos) {
+ //The nexxt escape sequence is a simple one ...
+ $es_pos = $simple_escape;
+
+ //Add the stuff not in the string yet ...
+ $string .= $this->hsc(substr($part, $start, $es_pos - $start));
+
+ //Get the style for this escaped char ...
+ if (!$this->use_classes) {
+ $escape_char_attributes = ' style="' . $this->language_data['STYLES']['ESCAPE_CHAR'][0] . '"';
+ } else {
+ $escape_char_attributes = ' class="es0"';
+ }
+
+ //Add the style for the escape char ...
+ $string .= "<span$escape_char_attributes>" .
+ GeSHi::hsc($this->language_data['ESCAPE_CHAR']);
+
+ //Get the byte AFTER the ESCAPE_CHAR we just found
+ $es_char = $part[$es_pos + 1];
+ if ($es_char == "\n") {
+ // don't put a newline around newlines
+ $string .= "</span>\n";
+ $start = $es_pos + 2;
+ } elseif (ord($es_char) >= 128) {
+ //This is an non-ASCII char (UTF8 or single byte)
+ //This code tries to work around SF#2037598 ...
+ if(function_exists('mb_substr')) {
+ $es_char_m = mb_substr(substr($part, $es_pos+1, 16), 0, 1, $this->encoding);
+ $string .= $es_char_m . '</span>';
+ } elseif ('utf-8' == $this->encoding) {
+ if(preg_match("/[\xC2-\xDF][\x80-\xBF]".
+ "|\xE0[\xA0-\xBF][\x80-\xBF]".
+ "|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}".
+ "|\xED[\x80-\x9F][\x80-\xBF]".
+ "|\xF0[\x90-\xBF][\x80-\xBF]{2}".
+ "|[\xF1-\xF3][\x80-\xBF]{3}".
+ "|\xF4[\x80-\x8F][\x80-\xBF]{2}/s",
+ $part, $es_char_m, null, $es_pos + 1)) {
+ $es_char_m = $es_char_m[0];
+ } else {
+ $es_char_m = $es_char;
+ }
+ $string .= $this->hsc($es_char_m) . '</span>';
+ } else {
+ $es_char_m = $this->hsc($es_char);
+ }
+ $start = $es_pos + strlen($es_char_m) + 1;
+ } else {
+ $string .= $this->hsc($es_char) . '</span>';
+ $start = $es_pos + 2;
+ }
+ } elseif ($next_escape_regexp_pos < $length &&
+ $next_escape_regexp_pos < $close_pos) {
+ $es_pos = $next_escape_regexp_pos;
+ //Add the stuff not in the string yet ...
+ $string .= $this->hsc(substr($part, $start, $es_pos - $start));
+
+ //Get the key and length of this match ...
+ $escape = $escape_regexp_cache_per_key[$next_escape_regexp_key];
+ $escape_str = substr($part, $es_pos, $escape['length']);
+ $escape_key = $escape['key'];
+
+ //Get the style for this escaped char ...
+ if (!$this->use_classes) {
+ $escape_char_attributes = ' style="' . $this->language_data['STYLES']['ESCAPE_CHAR'][$escape_key] . '"';
+ } else {
+ $escape_char_attributes = ' class="es' . $escape_key . '"';
+ }
+
+ //Add the style for the escape char ...
+ $string .= "<span$escape_char_attributes>" .
+ $this->hsc($escape_str) . '</span>';
+
+ $start = $es_pos + $escape['length'];
+ } else {
+ //Copy the remainder of the string ...
+ $string .= $this->hsc(substr($part, $start, $close_pos - $start + $char_len)) . '</span>';
+ $start = $close_pos + $char_len;
+ $string_open = false;
+ }
+ } while($string_open);
+
+ if ($check_linenumbers) {
+ // Are line numbers used? If, we should end the string before
+ // the newline and begin it again (so when <li>s are put in the source
+ // remains XHTML compliant)
+ // note to self: This opens up possibility of config files specifying
+ // that languages can/cannot have multiline strings???
+ $string = str_replace("\n", "</span>\n<span$string_attributes>", $string);
+ }
+
+ $result .= $string;
+ $string = '';
+ $i = $start - 1;
+ continue;
+ } elseif ($this->lexic_permissions['STRINGS'] && $hq && $hq[0] == $char &&
+ substr($part, $i, $hq_strlen) == $hq && ($i != $next_comment_regexp_pos)) {
+ // The start of a hard quoted string
+ if (!$this->use_classes) {
+ $string_attributes = ' style="' . $this->language_data['STYLES']['STRINGS']['HARD'] . '"';
+ $escape_char_attributes = ' style="' . $this->language_data['STYLES']['ESCAPE_CHAR']['HARD'] . '"';
+ } else {
+ $string_attributes = ' class="st_h"';
+ $escape_char_attributes = ' class="es_h"';
+ }
+ // parse the stuff before this
+ $result .= $this->parse_non_string_part($stuff_to_parse);
+ $stuff_to_parse = '';
+
+ // now handle the string
+ $string = '';
+
+ // look for closing quote
+ $start = $i + $hq_strlen;
+ while ($close_pos = strpos($part, $this->language_data['HARDQUOTE'][1], $start)) {
+ $start = $close_pos + 1;
+ if ($this->lexic_permissions['ESCAPE_CHAR'] && $part[$close_pos - 1] == $this->language_data['HARDCHAR'] &&
+ (($i + $hq_strlen) != ($close_pos))) { //Support empty string for HQ escapes if Starter = Escape
+ // make sure this quote is not escaped
+ foreach ($this->language_data['HARDESCAPE'] as $hardescape) {
+ if (substr($part, $close_pos - 1, strlen($hardescape)) == $hardescape) {
+ // check wether this quote is escaped or if it is something like '\\'
+ $escape_char_pos = $close_pos - 1;
+ while ($escape_char_pos > 0
+ && $part[$escape_char_pos - 1] == $this->language_data['HARDCHAR']) {
+ --$escape_char_pos;
+ }
+ if (($close_pos - $escape_char_pos) & 1) {
+ // uneven number of escape chars => this quote is escaped
+ continue 2;
+ }
+ }
+ }
+ }
+
+ // found closing quote
+ break;
+ }
+
+ //Found the closing delimiter?
+ if (!$close_pos) {
+ // span till the end of this $part when no closing delimiter is found
+ $close_pos = $length;
+ }
+
+ //Get the actual string
+ $string = substr($part, $i, $close_pos - $i + 1);
+ $i = $close_pos;
+
+ // handle escape chars and encode html chars
+ // (special because when we have escape chars within our string they may not be escaped)
+ if ($this->lexic_permissions['ESCAPE_CHAR'] && $this->language_data['ESCAPE_CHAR']) {
+ $start = 0;
+ $new_string = '';
+ while ($es_pos = strpos($string, $this->language_data['ESCAPE_CHAR'], $start)) {
+ // hmtl escape stuff before
+ $new_string .= $this->hsc(substr($string, $start, $es_pos - $start));
+ // check if this is a hard escape
+ foreach ($this->language_data['HARDESCAPE'] as $hardescape) {
+ if (substr($string, $es_pos, strlen($hardescape)) == $hardescape) {
+ // indeed, this is a hardescape
+ $new_string .= "<span$escape_char_attributes>" .
+ $this->hsc($hardescape) . '</span>';
+ $start = $es_pos + strlen($hardescape);
+ continue 2;
+ }
+ }
+ // not a hard escape, but a normal escape
+ // they come in pairs of two
+ $c = 0;
+ while (isset($string[$es_pos + $c]) && isset($string[$es_pos + $c + 1])
+ && $string[$es_pos + $c] == $this->language_data['ESCAPE_CHAR']
+ && $string[$es_pos + $c + 1] == $this->language_data['ESCAPE_CHAR']) {
+ $c += 2;
+ }
+ if ($c) {
+ $new_string .= "<span$escape_char_attributes>" .
+ str_repeat($escaped_escape_char, $c) .
+ '</span>';
+ $start = $es_pos + $c;
+ } else {
+ // this is just a single lonely escape char...
+ $new_string .= $escaped_escape_char;
+ $start = $es_pos + 1;
+ }
+ }
+ $string = $new_string . $this->hsc(substr($string, $start));
+ } else {
+ $string = $this->hsc($string);
+ }
+
+ if ($check_linenumbers) {
+ // Are line numbers used? If, we should end the string before
+ // the newline and begin it again (so when <li>s are put in the source
+ // remains XHTML compliant)
+ // note to self: This opens up possibility of config files specifying
+ // that languages can/cannot have multiline strings???
+ $string = str_replace("\n", "</span>\n<span$string_attributes>", $string);
+ }
+
+ $result .= "<span$string_attributes>" . $string . '</span>';
+ $string = '';
+ continue;
+ } else {
+ //Have a look for regexp comments
+ if ($i == $next_comment_regexp_pos) {
+ $COMMENT_MATCHED = true;
+ $comment = $comment_regexp_cache_per_key[$next_comment_regexp_key];
+ $test_str = $this->hsc(substr($part, $i, $comment['length']));
+
+ //@todo If remove important do remove here
+ if ($this->lexic_permissions['COMMENTS']['MULTI']) {
+ if (!$this->use_classes) {
+ $attributes = ' style="' . $this->language_data['STYLES']['COMMENTS'][$comment['key']] . '"';
+ } else {
+ $attributes = ' class="co' . $comment['key'] . '"';
+ }
+
+ $test_str = "<span$attributes>" . $test_str . "</span>";
+
+ // Short-cut through all the multiline code
+ if ($check_linenumbers) {
+ // strreplace to put close span and open span around multiline newlines
+ $test_str = str_replace(
+ "\n", "</span>\n<span$attributes>",
+ str_replace("\n ", "\n&nbsp;", $test_str)
+ );
+ }
+ }
+
+ $i += $comment['length'] - 1;
+
+ // parse the rest
+ $result .= $this->parse_non_string_part($stuff_to_parse);
+ $stuff_to_parse = '';
+ }
+
+ // If we haven't matched a regexp comment, try multi-line comments
+ if (!$COMMENT_MATCHED) {
+ // Is this a multiline comment?
+ if (!empty($this->language_data['COMMENT_MULTI']) && $next_comment_multi_pos < $i) {
+ $next_comment_multi_pos = $length;
+ foreach ($this->language_data['COMMENT_MULTI'] as $open => $close) {
+ $match_i = false;
+ if (isset($comment_multi_cache_per_key[$open]) &&
+ ($comment_multi_cache_per_key[$open] >= $i ||
+ $comment_multi_cache_per_key[$open] === false)) {
+ // we have already matched something
+ if ($comment_multi_cache_per_key[$open] === false) {
+ // this comment is never matched
+ continue;
+ }
+ $match_i = $comment_multi_cache_per_key[$open];
+ } elseif (($match_i = stripos($part, $open, $i)) !== false) {
+ $comment_multi_cache_per_key[$open] = $match_i;
+ } else {
+ $comment_multi_cache_per_key[$open] = false;
+ continue;
+ }
+ if ($match_i !== false && $match_i < $next_comment_multi_pos) {
+ $next_comment_multi_pos = $match_i;
+ $next_open_comment_multi = $open;
+ if ($match_i === $i) {
+ break;
+ }
+ }
+ }
+ }
+ if ($i == $next_comment_multi_pos) {
+ $open = $next_open_comment_multi;
+ $close = $this->language_data['COMMENT_MULTI'][$open];
+ $open_strlen = strlen($open);
+ $close_strlen = strlen($close);
+ $COMMENT_MATCHED = true;
+ $test_str_match = $open;
+ //@todo If remove important do remove here
+ if ($this->lexic_permissions['COMMENTS']['MULTI'] ||
+ $open == GESHI_START_IMPORTANT) {
+ if ($open != GESHI_START_IMPORTANT) {
+ if (!$this->use_classes) {
+ $attributes = ' style="' . $this->language_data['STYLES']['COMMENTS']['MULTI'] . '"';
+ } else {
+ $attributes = ' class="coMULTI"';
+ }
+ $test_str = "<span$attributes>" . $this->hsc($open);
+ } else {
+ if (!$this->use_classes) {
+ $attributes = ' style="' . $this->important_styles . '"';
+ } else {
+ $attributes = ' class="imp"';
+ }
+
+ // We don't include the start of the comment if it's an
+ // "important" part
+ $test_str = "<span$attributes>";
+ }
+ } else {
+ $test_str = $this->hsc($open);
+ }
+
+ $close_pos = strpos( $part, $close, $i + $open_strlen );
+
+ if ($close_pos === false) {
+ $close_pos = $length;
+ }
+
+ // Short-cut through all the multiline code
+ $rest_of_comment = $this->hsc(substr($part, $i + $open_strlen, $close_pos - $i - $open_strlen + $close_strlen));
+ if (($this->lexic_permissions['COMMENTS']['MULTI'] ||
+ $test_str_match == GESHI_START_IMPORTANT) &&
+ $check_linenumbers) {
+
+ // strreplace to put close span and open span around multiline newlines
+ $test_str .= str_replace(
+ "\n", "</span>\n<span$attributes>",
+ str_replace("\n ", "\n&nbsp;", $rest_of_comment)
+ );
+ } else {
+ $test_str .= $rest_of_comment;
+ }
+
+ if ($this->lexic_permissions['COMMENTS']['MULTI'] ||
+ $test_str_match == GESHI_START_IMPORTANT) {
+ $test_str .= '</span>';
+ }
+
+ $i = $close_pos + $close_strlen - 1;
+
+ // parse the rest
+ $result .= $this->parse_non_string_part($stuff_to_parse);
+ $stuff_to_parse = '';
+ }
+ }
+
+ // If we haven't matched a multiline comment, try single-line comments
+ if (!$COMMENT_MATCHED) {
+ // cache potential single line comment occurances
+ if (!empty($this->language_data['COMMENT_SINGLE']) && $next_comment_single_pos < $i) {
+ $next_comment_single_pos = $length;
+ foreach ($this->language_data['COMMENT_SINGLE'] as $comment_key => $comment_mark) {
+ $match_i = false;
+ if (isset($comment_single_cache_per_key[$comment_key]) &&
+ ($comment_single_cache_per_key[$comment_key] >= $i ||
+ $comment_single_cache_per_key[$comment_key] === false)) {
+ // we have already matched something
+ if ($comment_single_cache_per_key[$comment_key] === false) {
+ // this comment is never matched
+ continue;
+ }
+ $match_i = $comment_single_cache_per_key[$comment_key];
+ } elseif (
+ // case sensitive comments
+ ($this->language_data['CASE_SENSITIVE'][GESHI_COMMENTS] &&
+ ($match_i = stripos($part, $comment_mark, $i)) !== false) ||
+ // non case sensitive
+ (!$this->language_data['CASE_SENSITIVE'][GESHI_COMMENTS] &&
+ (($match_i = strpos($part, $comment_mark, $i)) !== false))) {
+ $comment_single_cache_per_key[$comment_key] = $match_i;
+ } else {
+ $comment_single_cache_per_key[$comment_key] = false;
+ continue;
+ }
+ if ($match_i !== false && $match_i < $next_comment_single_pos) {
+ $next_comment_single_pos = $match_i;
+ $next_comment_single_key = $comment_key;
+ if ($match_i === $i) {
+ break;
+ }
+ }
+ }
+ }
+ if ($next_comment_single_pos == $i) {
+ $comment_key = $next_comment_single_key;
+ $comment_mark = $this->language_data['COMMENT_SINGLE'][$comment_key];
+ $com_len = strlen($comment_mark);
+
+ // This check will find special variables like $# in bash
+ // or compiler directives of Delphi beginning {$
+ if ((empty($sc_disallowed_before) || ($i == 0) ||
+ (false === strpos($sc_disallowed_before, $part[$i-1]))) &&
+ (empty($sc_disallowed_after) || ($length <= $i + $com_len) ||
+ (false === strpos($sc_disallowed_after, $part[$i + $com_len]))))
+ {
+ // this is a valid comment
+ $COMMENT_MATCHED = true;
+ if ($this->lexic_permissions['COMMENTS'][$comment_key]) {
+ if (!$this->use_classes) {
+ $attributes = ' style="' . $this->language_data['STYLES']['COMMENTS'][$comment_key] . '"';
+ } else {
+ $attributes = ' class="co' . $comment_key . '"';
+ }
+ $test_str = "<span$attributes>" . $this->hsc($this->change_case($comment_mark));
+ } else {
+ $test_str = $this->hsc($comment_mark);
+ }
+
+ //Check if this comment is the last in the source
+ $close_pos = strpos($part, "\n", $i);
+ $oops = false;
+ if ($close_pos === false) {
+ $close_pos = $length;
+ $oops = true;
+ }
+ $test_str .= $this->hsc(substr($part, $i + $com_len, $close_pos - $i - $com_len));
+ if ($this->lexic_permissions['COMMENTS'][$comment_key]) {
+ $test_str .= "</span>";
+ }
+
+ // Take into account that the comment might be the last in the source
+ if (!$oops) {
+ $test_str .= "\n";
+ }
+
+ $i = $close_pos;
+
+ // parse the rest
+ $result .= $this->parse_non_string_part($stuff_to_parse);
+ $stuff_to_parse = '';
+ }
+ }
+ }
+ }
+
+ // Where are we adding this char?
+ if (!$COMMENT_MATCHED) {
+ $stuff_to_parse .= $char;
+ } else {
+ $result .= $test_str;
+ unset($test_str);
+ $COMMENT_MATCHED = false;
+ }
+ }
+ // Parse the last bit
+ $result .= $this->parse_non_string_part($stuff_to_parse);
+ $stuff_to_parse = '';
+ } else {
+ $result .= $this->hsc($part);
+ }
+ // Close the <span> that surrounds the block
+ if ($STRICTATTRS != '') {
+ $result = str_replace("\n", "</span>\n<span$STRICTATTRS>", $result);
+ $result .= '</span>';
+ }
+
+ $endresult .= $result;
+ unset($part, $parts[$key], $result);
+ }
+
+ //This fix is related to SF#1923020, but has to be applied regardless of
+ //actually highlighting symbols.
+ /** NOTE: memorypeak #3 */
+ $endresult = str_replace(array('<SEMI>', '<PIPE>'), array(';', '|'), $endresult);
+
+// // Parse the last stuff (redundant?)
+// $result .= $this->parse_non_string_part($stuff_to_parse);
+
+ // Lop off the very first and last spaces
+// $result = substr($result, 1, -1);
+
+ // We're finished: stop timing
+ $this->set_time($start_time, microtime());
+
+ $this->finalise($endresult);
+ return $endresult;
+ }
+
+ /**
+ * Swaps out spaces and tabs for HTML indentation. Not needed if
+ * the code is in a pre block...
+ *
+ * @param string $result The source to indent (reference!)
+ * @since 1.0.0
+ */
+ protected function indent(&$result) {
+ /// Replace tabs with the correct number of spaces
+ if (false !== strpos($result, "\t")) {
+ $lines = explode("\n", $result);
+ $result = null;//Save memory while we process the lines individually
+ $tab_width = $this->get_real_tab_width();
+ $tab_string = '&nbsp;' . str_repeat(' ', $tab_width);
+
+ for ($key = 0, $n = count($lines); $key < $n; $key++) {
+ $line = $lines[$key];
+ if (false === strpos($line, "\t")) {
+ continue;
+ }
+
+ $pos = 0;
+ $length = strlen($line);
+ $lines[$key] = ''; // reduce memory
+
+ $IN_TAG = false;
+ for ($i = 0; $i < $length; ++$i) {
+ $char = $line[$i];
+ // Simple engine to work out whether we're in a tag.
+ // If we are we modify $pos. This is so we ignore HTML
+ // in the line and only workout the tab replacement
+ // via the actual content of the string
+ // This test could be improved to include strings in the
+ // html so that < or > would be allowed in user's styles
+ // (e.g. quotes: '<' '>'; or similar)
+ if ($IN_TAG) {
+ if ('>' == $char) {
+ $IN_TAG = false;
+ }
+ $lines[$key] .= $char;
+ } elseif ('<' == $char) {
+ $IN_TAG = true;
+ $lines[$key] .= '<';
+ } elseif ('&' == $char) {
+ $substr = substr($line, $i + 3, 5);
+ $posi = strpos($substr, ';');
+ if (false === $posi) {
+ ++$pos;
+ } else {
+ $pos -= $posi+2;
+ }
+ $lines[$key] .= $char;
+ } elseif ("\t" == $char) {
+ $str = '';
+ // OPTIMISE - move $strs out. Make an array:
+ // $tabs = array(
+ // 1 => '&nbsp;',
+ // 2 => '&nbsp; ',
+ // 3 => '&nbsp; &nbsp;' etc etc
+ // to use instead of building a string every time
+ $tab_end_width = $tab_width - ($pos % $tab_width); //Moved out of the look as it doesn't change within the loop
+ if (($pos & 1) || 1 == $tab_end_width) {
+ $str .= substr($tab_string, 6, $tab_end_width);
+ } else {
+ $str .= substr($tab_string, 0, $tab_end_width+5);
+ }
+ $lines[$key] .= $str;
+ $pos += $tab_end_width;
+
+ if (false === strpos($line, "\t", $i + 1)) {
+ $lines[$key] .= substr($line, $i + 1);
+ break;
+ }
+ } elseif (0 == $pos && ' ' == $char) {
+ $lines[$key] .= '&nbsp;';
+ ++$pos;
+ } else {
+ $lines[$key] .= $char;
+ ++$pos;
+ }
+ }
+ }
+ $result = implode("\n", $lines);
+ unset($lines);//We don't need the lines separated beyond this --- free them!
+ }
+ // Other whitespace
+ // BenBE: Fix to reduce the number of replacements to be done
+ $result = preg_replace('/^ /m', '&nbsp;', $result);
+ $result = str_replace(' ', ' &nbsp;', $result);
+
+ if ($this->line_numbers == GESHI_NO_LINE_NUMBERS && $this->header_type != GESHI_HEADER_PRE_TABLE) {
+ if ($this->line_ending === null) {
+ $result = nl2br($result);
+ } else {
+ $result = str_replace("\n", $this->line_ending, $result);
+ }
+ }
+ }
+
+ /**
+ * Changes the case of a keyword for those languages where a change is asked for
+ *
+ * @param string $instr The keyword to change the case of
+ * @return string The keyword with its case changed
+ * @since 1.0.0
+ */
+ protected function change_case($instr) {
+ switch ($this->language_data['CASE_KEYWORDS']) {
+ case GESHI_CAPS_UPPER:
+ return strtoupper($instr);
+ case GESHI_CAPS_LOWER:
+ return strtolower($instr);
+ default:
+ return $instr;
+ }
+ }
+
+ /**
+ * Handles replacements of keywords to include markup and links if requested
+ *
+ * @param string $match The keyword to add the Markup to
+ * @return string The HTML for the match found
+ * @since 1.0.8
+ *
+ * @todo Get rid of ender in keyword links
+ */
+ protected function handle_keyword_replace($match) {
+ $k = $this->_kw_replace_group;
+ $keyword = $match[0];
+ $keyword_match = $match[1];
+
+ $before = '';
+ $after = '';
+
+ if ($this->keyword_links) {
+ // Keyword links have been ebabled
+
+ if (isset($this->language_data['URLS'][$k]) &&
+ $this->language_data['URLS'][$k] != '') {
+ // There is a base group for this keyword
+
+ // Old system: strtolower
+ //$keyword = ( $this->language_data['CASE_SENSITIVE'][$group] ) ? $keyword : strtolower($keyword);
+ // New system: get keyword from language file to get correct case
+ if (!$this->language_data['CASE_SENSITIVE'][$k] &&
+ strpos($this->language_data['URLS'][$k], '{FNAME}') !== false) {
+ foreach ($this->language_data['KEYWORDS'][$k] as $word) {
+ if (strcasecmp($word, $keyword_match) == 0) {
+ break;
+ }
+ }
+ } else {
+ $word = $keyword_match;
+ }
+
+ $before = '<|UR1|"' .
+ str_replace(
+ array(
+ '{FNAME}',
+ '{FNAMEL}',
+ '{FNAMEU}',
+ '{FNAMEUF}',
+ '.'),
+ array(
+ str_replace('+', '%20', urlencode($this->hsc($word))),
+ str_replace('+', '%20', urlencode($this->hsc(strtolower($word)))),
+ str_replace('+', '%20', urlencode($this->hsc(strtoupper($word)))),
+ str_replace('+', '%20', urlencode($this->hsc(ucfirst($word)))),
+ '<DOT>'),
+ $this->language_data['URLS'][$k]
+ ) . '">';
+ $after = '</a>';
+ }
+ }
+
+ return $before . '<|/'. $k .'/>' . $this->change_case($keyword) . '|>' . $after;
+ }
+
+ /**
+ * handles regular expressions highlighting-definitions with callback functions
+ *
+ * @note this is a callback, don't use it directly
+ *
+ * @param array $matches the matches array
+ * @return string The highlighted string
+ * @since 1.0.8
+ */
+ protected function handle_regexps_callback($matches) {
+ // before: "' style=\"' . call_user_func(\"$func\", '\\1') . '\"\\1|>'",
+ return ' style="' . call_user_func($this->language_data['STYLES']['REGEXPS'][$this->_rx_key], $matches[1]) . '"'. $matches[1] . '|>';
+ }
+
+ /**
+ * handles newlines in REGEXPS matches. Set the _hmr_* vars before calling this
+ *
+ * @note this is a callback, don't use it directly
+ *
+ * @param array $matches the matches array
+ * @return string
+ * @since 1.0.8
+ */
+ protected function handle_multiline_regexps($matches) {
+ $before = $this->_hmr_before;
+ $after = $this->_hmr_after;
+ if ($this->_hmr_replace) {
+ $replace = $this->_hmr_replace;
+ $search = array();
+
+ foreach (array_keys($matches) as $k) {
+ $search[] = '\\' . $k;
+ }
+
+ $before = str_replace($search, $matches, $before);
+ $after = str_replace($search, $matches, $after);
+ $replace = str_replace($search, $matches, $replace);
+ } else {
+ $replace = $matches[0];
+ }
+ return $before
+ . '<|!REG3XP' . $this->_hmr_key .'!>'
+ . str_replace("\n", "|>\n<|!REG3XP" . $this->_hmr_key . '!>', $replace)
+ . '|>'
+ . $after;
+ }
+
+ /**
+ * Takes a string that has no strings or comments in it, and highlights
+ * stuff like keywords, numbers and methods.
+ *
+ * @param string $stuff_to_parse The string to parse for keyword, numbers etc.
+ * @since 1.0.0
+ * @todo BUGGY! Why? Why not build string and return?
+ * @return string
+ */
+ protected function parse_non_string_part($stuff_to_parse) {
+ $stuff_to_parse = ' ' . $this->hsc($stuff_to_parse);
+
+ // Highlight keywords
+ $disallowed_before = "(?<![a-zA-Z0-9\$_\|\#|^&";
+ $disallowed_after = "(?![a-zA-Z0-9_\|%\\-&;";
+ if ($this->lexic_permissions['STRINGS']) {
+ $quotemarks = preg_quote(implode($this->language_data['QUOTEMARKS']), '/');
+ $disallowed_before .= $quotemarks;
+ $disallowed_after .= $quotemarks;
+ }
+ $disallowed_before .= "])";
+ $disallowed_after .= "])";
+
+ $parser_control_pergroup = false;
+ if (isset($this->language_data['PARSER_CONTROL'])) {
+ if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS'])) {
+ $x = 0; // check wether per-keyword-group parser_control is enabled
+ if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'])) {
+ $disallowed_before = $this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_BEFORE'];
+ ++$x;
+ }
+ if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'])) {
+ $disallowed_after = $this->language_data['PARSER_CONTROL']['KEYWORDS']['DISALLOWED_AFTER'];
+ ++$x;
+ }
+ $parser_control_pergroup = (count($this->language_data['PARSER_CONTROL']['KEYWORDS']) - $x) > 0;
+ }
+ }
+
+ foreach (array_keys($this->language_data['KEYWORDS']) as $k) {
+ if (!isset($this->lexic_permissions['KEYWORDS'][$k]) ||
+ $this->lexic_permissions['KEYWORDS'][$k]) {
+
+ $case_sensitive = $this->language_data['CASE_SENSITIVE'][$k];
+ $modifiers = $case_sensitive ? '' : 'i';
+
+ // NEW in 1.0.8 - per-keyword-group parser control
+ $disallowed_before_local = $disallowed_before;
+ $disallowed_after_local = $disallowed_after;
+ if ($parser_control_pergroup && isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$k])) {
+ if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_BEFORE'])) {
+ $disallowed_before_local =
+ $this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_BEFORE'];
+ }
+
+ if (isset($this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_AFTER'])) {
+ $disallowed_after_local =
+ $this->language_data['PARSER_CONTROL']['KEYWORDS'][$k]['DISALLOWED_AFTER'];
+ }
+ }
+
+ $this->_kw_replace_group = $k;
+
+ //NEW in 1.0.8, the cached regexp list
+ // since we don't want PHP / PCRE to crash due to too large patterns we split them into smaller chunks
+ for ($set = 0, $set_length = count($this->language_data['CACHED_KEYWORD_LISTS'][$k]); $set < $set_length; ++$set) {
+ $keywordset =& $this->language_data['CACHED_KEYWORD_LISTS'][$k][$set];
+ // Might make a more unique string for putting the number in soon
+ // Basically, we don't put the styles in yet because then the styles themselves will
+ // get highlighted if the language has a CSS keyword in it (like CSS, for example ;))
+ $stuff_to_parse = preg_replace_callback(
+ "/$disallowed_before_local({$keywordset})(?!\<DOT\>(?:htm|php|aspx?))$disallowed_after_local/$modifiers",
+ array($this, 'handle_keyword_replace'),
+ $stuff_to_parse
+ );
+ }
+ }
+ }
+
+ // Regular expressions
+ foreach ($this->language_data['REGEXPS'] as $key => $regexp) {
+ if ($this->lexic_permissions['REGEXPS'][$key]) {
+ if (is_array($regexp)) {
+ if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ // produce valid HTML when we match multiple lines
+ $this->_hmr_replace = $regexp[GESHI_REPLACE];
+ $this->_hmr_before = $regexp[GESHI_BEFORE];
+ $this->_hmr_key = $key;
+ $this->_hmr_after = $regexp[GESHI_AFTER];
+ $stuff_to_parse = preg_replace_callback(
+ "/" . $regexp[GESHI_SEARCH] . "/{$regexp[GESHI_MODIFIERS]}",
+ array($this, 'handle_multiline_regexps'),
+ $stuff_to_parse);
+ $this->_hmr_replace = false;
+ $this->_hmr_before = '';
+ $this->_hmr_after = '';
+ } else {
+ $stuff_to_parse = preg_replace(
+ '/' . $regexp[GESHI_SEARCH] . '/' . $regexp[GESHI_MODIFIERS],
+ $regexp[GESHI_BEFORE] . '<|!REG3XP'. $key .'!>' . $regexp[GESHI_REPLACE] . '|>' . $regexp[GESHI_AFTER],
+ $stuff_to_parse);
+ }
+ } else {
+ if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ // produce valid HTML when we match multiple lines
+ $this->_hmr_key = $key;
+ $stuff_to_parse = preg_replace_callback( "/(" . $regexp . ")/",
+ array($this, 'handle_multiline_regexps'), $stuff_to_parse);
+ $this->_hmr_key = '';
+ } else {
+ $stuff_to_parse = preg_replace( "/(" . $regexp . ")/", "<|!REG3XP$key!>\\1|>", $stuff_to_parse);
+ }
+ }
+ }
+ }
+
+ // Highlight numbers. As of 1.0.8 we support different types of numbers
+ $numbers_found = false;
+
+ if ($this->lexic_permissions['NUMBERS'] && preg_match($this->language_data['PARSER_CONTROL']['NUMBERS']['PRECHECK_RX'], $stuff_to_parse )) {
+ $numbers_found = true;
+
+ //For each of the formats ...
+ foreach($this->language_data['NUMBERS_RXCACHE'] as $id => $regexp) {
+ //Check if it should be highlighted ...
+ $stuff_to_parse = preg_replace($regexp, "<|/NUM!$id/>\\1|>", $stuff_to_parse);
+ }
+ }
+
+ //
+ // Now that's all done, replace /[number]/ with the correct styles
+ //
+ foreach (array_keys($this->language_data['KEYWORDS']) as $k) {
+ if (!$this->use_classes) {
+ $attributes = ' style="' .
+ (isset($this->language_data['STYLES']['KEYWORDS'][$k]) ?
+ $this->language_data['STYLES']['KEYWORDS'][$k] : "") . '"';
+ } else {
+ $attributes = ' class="kw' . $k . '"';
+ }
+ $stuff_to_parse = str_replace("<|/$k/>", "<|$attributes>", $stuff_to_parse);
+ }
+
+ if ($numbers_found) {
+ // Put number styles in
+ foreach($this->language_data['NUMBERS_RXCACHE'] as $id => $regexp) {
+ //Commented out for now, as this needs some review ...
+ // if ($numbers_permissions & $id) {
+ //Get the appropriate style ...
+ //Checking for unset styles is done by the style cache builder ...
+ if (!$this->use_classes) {
+ $attributes = ' style="' . $this->language_data['STYLES']['NUMBERS'][$id] . '"';
+ } else {
+ $attributes = ' class="nu'.$id.'"';
+ }
+
+ //Set in the correct styles ...
+ $stuff_to_parse = str_replace("/NUM!$id/", $attributes, $stuff_to_parse);
+ // }
+ }
+ }
+
+ // Highlight methods and fields in objects
+ if ($this->lexic_permissions['METHODS'] && $this->language_data['OOLANG']) {
+ $oolang_spaces = "[\s]*";
+ $oolang_before = "";
+ $oolang_after = "[a-zA-Z][a-zA-Z0-9_]*";
+ if (isset($this->language_data['PARSER_CONTROL'])) {
+ if (isset($this->language_data['PARSER_CONTROL']['OOLANG'])) {
+ if (isset($this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_BEFORE'])) {
+ $oolang_before = $this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_BEFORE'];
+ }
+ if (isset($this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_AFTER'])) {
+ $oolang_after = $this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_AFTER'];
+ }
+ if (isset($this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_SPACES'])) {
+ $oolang_spaces = $this->language_data['PARSER_CONTROL']['OOLANG']['MATCH_SPACES'];
+ }
+ }
+ }
+
+ foreach ($this->language_data['OBJECT_SPLITTERS'] as $key => $splitter) {
+ if (false !== strpos($stuff_to_parse, $splitter)) {
+ if (!$this->use_classes) {
+ $attributes = ' style="' . $this->language_data['STYLES']['METHODS'][$key] . '"';
+ } else {
+ $attributes = ' class="me' . $key . '"';
+ }
+ $stuff_to_parse = preg_replace("/($oolang_before)(" . preg_quote($this->language_data['OBJECT_SPLITTERS'][$key], '/') . ")($oolang_spaces)($oolang_after)/", "\\1\\2\\3<|$attributes>\\4|>", $stuff_to_parse);
+ }
+ }
+ }
+
+ //
+ // Highlight brackets. Yes, I've tried adding a semi-colon to this list.
+ // You try it, and see what happens ;)
+ // TODO: Fix lexic permissions not converting entities if shouldn't
+ // be highlighting regardless
+ //
+ if ($this->lexic_permissions['BRACKETS']) {
+ $stuff_to_parse = str_replace( $this->language_data['CACHE_BRACKET_MATCH'],
+ $this->language_data['CACHE_BRACKET_REPLACE'], $stuff_to_parse );
+ }
+
+
+ //FIX for symbol highlighting ...
+ if ($this->lexic_permissions['SYMBOLS'] && !empty($this->language_data['SYMBOLS'])) {
+ //Get all matches and throw away those witin a block that is already highlighted... (i.e. matched by a regexp)
+ $n_symbols = preg_match_all("/<\|(?:<DOT>|[^>])+>(?:(?!\|>).*?)\|>|<\/a>|(?:" . $this->language_data['SYMBOL_SEARCH'] . ")+(?![^<]+?>)/", $stuff_to_parse, $pot_symbols, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
+ $global_offset = 0;
+ for ($s_id = 0; $s_id < $n_symbols; ++$s_id) {
+ $symbol_match = $pot_symbols[$s_id][0][0];
+ if (strpos($symbol_match, '<') !== false || strpos($symbol_match, '>') !== false) {
+ // already highlighted blocks _must_ include either < or >
+ // so if this conditional applies, we have to skip this match
+ // BenBE: UNLESS the block contains <SEMI> or <PIPE>
+ if(strpos($symbol_match, '<SEMI>') === false &&
+ strpos($symbol_match, '<PIPE>') === false) {
+ continue;
+ }
+ }
+
+ // if we reach this point, we have a valid match which needs to be highlighted
+
+ $symbol_length = strlen($symbol_match);
+ $symbol_offset = $pot_symbols[$s_id][0][1];
+ unset($pot_symbols[$s_id]);
+ $symbol_hl = "";
+
+ // if we have multiple styles, we have to handle them properly
+ if ($this->language_data['MULTIPLE_SYMBOL_GROUPS']) {
+ $old_sym = -1;
+ // Split the current stuff to replace into its atomic symbols ...
+ preg_match_all("/" . $this->language_data['SYMBOL_SEARCH'] . "/", $symbol_match, $sym_match_syms, PREG_PATTERN_ORDER);
+ foreach ($sym_match_syms[0] as $sym_ms) {
+ //Check if consequtive symbols belong to the same group to save output ...
+ if (isset($this->language_data['SYMBOL_DATA'][$sym_ms])
+ && ($this->language_data['SYMBOL_DATA'][$sym_ms] != $old_sym)) {
+ if (-1 != $old_sym) {
+ $symbol_hl .= "|>";
+ }
+ $old_sym = $this->language_data['SYMBOL_DATA'][$sym_ms];
+ if (!$this->use_classes) {
+ $symbol_hl .= '<| style="' . $this->language_data['STYLES']['SYMBOLS'][$old_sym] . '">';
+ } else {
+ $symbol_hl .= '<| class="sy' . $old_sym . '">';
+ }
+ }
+ $symbol_hl .= $sym_ms;
+ }
+ unset($sym_match_syms);
+
+ //Close remaining tags and insert the replacement at the right position ...
+ //Take caution if symbol_hl is empty to avoid doubled closing spans.
+ if (-1 != $old_sym) {
+ $symbol_hl .= "|>";
+ }
+ } else {
+ if (!$this->use_classes) {
+ $symbol_hl = '<| style="' . $this->language_data['STYLES']['SYMBOLS'][0] . '">';
+ } else {
+ $symbol_hl = '<| class="sy0">';
+ }
+ $symbol_hl .= $symbol_match . '|>';
+ }
+
+ $stuff_to_parse = substr_replace($stuff_to_parse, $symbol_hl, $symbol_offset + $global_offset, $symbol_length);
+
+ // since we replace old text with something of different size,
+ // we'll have to keep track of the differences
+ $global_offset += strlen($symbol_hl) - $symbol_length;
+ }
+ }
+ //FIX for symbol highlighting ...
+
+ // Add class/style for regexps
+ foreach (array_keys($this->language_data['REGEXPS']) as $key) {
+ if ($this->lexic_permissions['REGEXPS'][$key]) {
+ if (is_callable($this->language_data['STYLES']['REGEXPS'][$key])) {
+ $this->_rx_key = $key;
+ $stuff_to_parse = preg_replace_callback("/!REG3XP$key!(.*)\|>/U",
+ array($this, 'handle_regexps_callback'),
+ $stuff_to_parse);
+ } else {
+ if (!$this->use_classes) {
+ $attributes = ' style="' . $this->language_data['STYLES']['REGEXPS'][$key] . '"';
+ } else {
+ if (is_array($this->language_data['REGEXPS'][$key]) &&
+ array_key_exists(GESHI_CLASS, $this->language_data['REGEXPS'][$key])) {
+ $attributes = ' class="' .
+ $this->language_data['REGEXPS'][$key][GESHI_CLASS] . '"';
+ } else {
+ $attributes = ' class="re' . $key . '"';
+ }
+ }
+ $stuff_to_parse = str_replace("!REG3XP$key!", "$attributes", $stuff_to_parse);
+ }
+ }
+ }
+
+ // Replace <DOT> with . for urls
+ $stuff_to_parse = str_replace('<DOT>', '.', $stuff_to_parse);
+ // Replace <|UR1| with <a href= for urls also
+ if (isset($this->link_styles[GESHI_LINK])) {
+ if ($this->use_classes) {
+ $stuff_to_parse = str_replace('<|UR1|', '<a' . $this->link_target . ' href=', $stuff_to_parse);
+ } else {
+ $stuff_to_parse = str_replace('<|UR1|', '<a' . $this->link_target . ' style="' . $this->link_styles[GESHI_LINK] . '" href=', $stuff_to_parse);
+ }
+ } else {
+ $stuff_to_parse = str_replace('<|UR1|', '<a' . $this->link_target . ' href=', $stuff_to_parse);
+ }
+
+ //
+ // NOW we add the span thingy ;)
+ //
+
+ $stuff_to_parse = str_replace('<|', '<span', $stuff_to_parse);
+ $stuff_to_parse = str_replace ( '|>', '</span>', $stuff_to_parse );
+ return substr($stuff_to_parse, 1);
+ }
+
+ /**
+ * Sets the time taken to parse the code
+ *
+ * @param string $start_time The time when parsing started as returned by @see microtime()
+ * @param string $end_time The time when parsing ended as returned by @see microtime()
+ * @since 1.0.2
+ */
+ protected function set_time($start_time, $end_time) {
+ $start = explode(' ', $start_time);
+ $end = explode(' ', $end_time);
+ $this->time = $end[0] + $end[1] - $start[0] - $start[1];
+ }
+
+ /**
+ * Gets the time taken to parse the code
+ *
+ * @return double The time taken to parse the code
+ * @since 1.0.2
+ */
+ public function get_time() {
+ return $this->time;
+ }
+
+ /**
+ * Merges arrays recursively, overwriting values of the first array with values of later arrays
+ *
+ * @since 1.0.8
+ */
+ protected function merge_arrays() {
+ $arrays = func_get_args();
+ $narrays = count($arrays);
+
+ // check arguments
+ // comment out if more performance is necessary (in this case the foreach loop will trigger a warning if the argument is not an array)
+ for ($i = 0; $i < $narrays; $i ++) {
+ if (!is_array($arrays[$i])) {
+ // also array_merge_recursive returns nothing in this case
+ trigger_error('Argument #' . ($i+1) . ' is not an array - trying to merge array with scalar! Returning false!', E_USER_WARNING);
+ return false;
+ }
+ }
+
+ // the first array is in the output set in every case
+ $ret = $arrays[0];
+
+ // merege $ret with the remaining arrays
+ for ($i = 1; $i < $narrays; $i ++) {
+ foreach ($arrays[$i] as $key => $value) {
+ if (is_array($value) && isset($ret[$key])) {
+ // if $ret[$key] is not an array you try to merge an scalar value with an array - the result is not defined (incompatible arrays)
+ // in this case the call will trigger an E_USER_WARNING and the $ret[$key] will be false.
+ $ret[$key] = $this->merge_arrays($ret[$key], $value);
+ } else {
+ $ret[$key] = $value;
+ }
+ }
+ }
+
+ return $ret;
+ }
+
+ /**
+ * Gets language information and stores it for later use
+ *
+ * @param string $file_name The filename of the language file you want to load
+ * @since 1.0.0
+ * @todo Needs to load keys for lexic permissions for keywords, regexps etc
+ */
+ protected function load_language($file_name) {
+ if ($file_name == $this->loaded_language) {
+ // this file is already loaded!
+ return;
+ }
+
+ //Prepare some stuff before actually loading the language file
+ $this->loaded_language = $file_name;
+ $this->parse_cache_built = false;
+ $this->enable_highlighting();
+ $language_data = array();
+
+ //Load the language file
+ require $file_name;
+
+ // Perhaps some checking might be added here later to check that
+ // $language data is a valid thing but maybe not
+ $this->language_data = $language_data;
+
+ // Set strict mode if should be set
+ $this->strict_mode = $this->language_data['STRICT_MODE_APPLIES'];
+
+ // Set permissions for all lexics to true
+ // so they'll be highlighted by default
+ foreach (array_keys($this->language_data['KEYWORDS']) as $key) {
+ if (!empty($this->language_data['KEYWORDS'][$key])) {
+ $this->lexic_permissions['KEYWORDS'][$key] = true;
+ } else {
+ $this->lexic_permissions['KEYWORDS'][$key] = false;
+ }
+ }
+
+ foreach (array_keys($this->language_data['COMMENT_SINGLE']) as $key) {
+ $this->lexic_permissions['COMMENTS'][$key] = true;
+ }
+ foreach (array_keys($this->language_data['REGEXPS']) as $key) {
+ $this->lexic_permissions['REGEXPS'][$key] = true;
+ }
+
+ // for BenBE and future code reviews:
+ // we can use empty here since we only check for existance and emptiness of an array
+ // if it is not an array at all but rather false or null this will work as intended as well
+ // even if $this->language_data['PARSER_CONTROL'] is undefined this won't trigger a notice
+ if (!empty($this->language_data['PARSER_CONTROL']['ENABLE_FLAGS'])) {
+ foreach ($this->language_data['PARSER_CONTROL']['ENABLE_FLAGS'] as $flag => $value) {
+ // it's either true or false and maybe is true as well
+ $perm = $value !== GESHI_NEVER;
+ if ($flag == 'ALL') {
+ $this->enable_highlighting($perm);
+ continue;
+ }
+ if (!isset($this->lexic_permissions[$flag])) {
+ // unknown lexic permission
+ continue;
+ }
+ if (is_array($this->lexic_permissions[$flag])) {
+ foreach ($this->lexic_permissions[$flag] as $key => $val) {
+ $this->lexic_permissions[$flag][$key] = $perm;
+ }
+ } else {
+ $this->lexic_permissions[$flag] = $perm;
+ }
+ }
+ unset($this->language_data['PARSER_CONTROL']['ENABLE_FLAGS']);
+ }
+
+ //Fix: Problem where hardescapes weren't handled if no ESCAPE_CHAR was given
+ //You need to set one for HARDESCAPES only in this case.
+ if(!isset($this->language_data['HARDCHAR'])) {
+ $this->language_data['HARDCHAR'] = $this->language_data['ESCAPE_CHAR'];
+ }
+
+ //NEW in 1.0.8: Allow styles to be loaded from a separate file to override defaults
+ $style_filename = substr($file_name, 0, -4) . '.style.php';
+ if (is_readable($style_filename)) {
+ //Clear any style_data that could have been set before ...
+ if (isset($style_data)) {
+ unset($style_data);
+ }
+
+ //Read the Style Information from the style file
+ include $style_filename;
+
+ //Apply the new styles to our current language styles
+ if (isset($style_data) && is_array($style_data)) {
+ $this->language_data['STYLES'] =
+ $this->merge_arrays($this->language_data['STYLES'], $style_data);
+ }
+ }
+ }
+
+ /**
+ * Takes the parsed code and various options, and creates the HTML
+ * surrounding it to make it look nice.
+ *
+ * @param string $parsed_code The code already parsed (reference!)
+ * @since 1.0.0
+ */
+ protected function finalise(&$parsed_code) {
+ // Remove end parts of important declarations
+ // This is BUGGY!! My fault for bad code: fix coming in 1.2
+ // @todo Remove this crap
+ if ($this->enable_important_blocks &&
+ (strpos($parsed_code, $this->hsc(GESHI_START_IMPORTANT)) === false)) {
+ $parsed_code = str_replace($this->hsc(GESHI_END_IMPORTANT), '', $parsed_code);
+ }
+
+ // Add HTML whitespace stuff if we're using the <div> header
+ if ($this->header_type != GESHI_HEADER_PRE && $this->header_type != GESHI_HEADER_PRE_VALID) {
+ $this->indent($parsed_code);
+ }
+
+ // purge some unnecessary stuff
+ /** NOTE: memorypeak #1 */
+ $parsed_code = preg_replace('#<span[^>]+>(\s*)</span>#', '\\1', $parsed_code);
+
+ // If we are using IDs for line numbers, there needs to be an overall
+ // ID set to prevent collisions.
+ if ($this->add_ids && !$this->overall_id) {
+ $this->overall_id = 'geshi-' . substr(md5(microtime()), 0, 4);
+ }
+
+ // Get code into lines
+ /** NOTE: memorypeak #2 */
+ $code = explode("\n", $parsed_code);
+ $parsed_code = $this->header();
+
+ // If we're using line numbers, we insert <li>s and appropriate
+ // markup to style them (otherwise we don't need to do anything)
+ if ($this->line_numbers != GESHI_NO_LINE_NUMBERS && $this->header_type != GESHI_HEADER_PRE_TABLE) {
+ // If we're using the <pre> header, we shouldn't add newlines because
+ // the <pre> will line-break them (and the <li>s already do this for us)
+ $ls = ($this->header_type != GESHI_HEADER_PRE && $this->header_type != GESHI_HEADER_PRE_VALID) ? "\n" : '';
+
+ // Foreach line...
+ for ($i = 0, $n = count($code); $i < $n;) {
+ //Reset the attributes for a new line ...
+ $attrs = array();
+
+ // Make lines have at least one space in them if they're empty
+ // BenBE: Checking emptiness using trim instead of relying on blanks
+ if ('' == trim($code[$i])) {
+ $code[$i] = '&nbsp;';
+ }
+
+ // If this is a "special line"...
+ if ($this->line_numbers == GESHI_FANCY_LINE_NUMBERS &&
+ $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
+ // Set the attributes to style the line
+ if ($this->use_classes) {
+ //$attr = ' class="li2"';
+ $attrs['class'][] = 'li2';
+ $def_attr = ' class="de2"';
+ } else {
+ //$attr = ' style="' . $this->line_style2 . '"';
+ $attrs['style'][] = $this->line_style2;
+ // This style "covers up" the special styles set for special lines
+ // so that styles applied to special lines don't apply to the actual
+ // code on that line
+ $def_attr = ' style="' . $this->code_style . '"';
+ }
+ } else {
+ if ($this->use_classes) {
+ //$attr = ' class="li1"';
+ $attrs['class'][] = 'li1';
+ $def_attr = ' class="de1"';
+ } else {
+ //$attr = ' style="' . $this->line_style1 . '"';
+ $attrs['style'][] = $this->line_style1;
+ $def_attr = ' style="' . $this->code_style . '"';
+ }
+ }
+
+ //Check which type of tag to insert for this line
+ if ($this->header_type == GESHI_HEADER_PRE_VALID) {
+ $start = "<pre$def_attr>";
+ $end = '</pre>';
+ } else {
+ // Span or div?
+ $start = "<div$def_attr>";
+ $end = '</div>';
+ }
+
+ ++$i;
+
+ // Are we supposed to use ids? If so, add them
+ if ($this->add_ids) {
+ $attrs['id'][] = "$this->overall_id-$i";
+ }
+
+ //Is this some line with extra styles???
+ if (in_array($i, $this->highlight_extra_lines)) {
+ if ($this->use_classes) {
+ if (isset($this->highlight_extra_lines_styles[$i])) {
+ $attrs['class'][] = "lx$i";
+ } else {
+ $attrs['class'][] = "ln-xtra";
+ }
+ } else {
+ array_push($attrs['style'], $this->get_line_style($i));
+ }
+ }
+
+ // Add in the line surrounded by appropriate list HTML
+ $attr_string = '';
+ foreach ($attrs as $key => $attr) {
+ $attr_string .= ' ' . $key . '="' . implode(' ', $attr) . '"';
+ }
+
+ $parsed_code .= "<li$attr_string>$start{$code[$i-1]}$end</li>$ls";
+ unset($code[$i - 1]);
+ }
+ } else {
+ $n = count($code);
+ if ($this->use_classes) {
+ $attributes = ' class="de1"';
+ } else {
+ $attributes = ' style="'. $this->code_style .'"';
+ }
+ if ($this->header_type == GESHI_HEADER_PRE_VALID) {
+ $parsed_code .= '<pre'. $attributes .'>';
+ } elseif ($this->header_type == GESHI_HEADER_PRE_TABLE) {
+ if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ if ($this->use_classes) {
+ $attrs = ' class="ln"';
+ } else {
+ $attrs = ' style="'. $this->table_linenumber_style .'"';
+ }
+ $parsed_code .= '<td'.$attrs.'><pre'.$attributes.'>';
+ // get linenumbers
+ // we don't merge it with the for below, since it should be better for
+ // memory consumption this way
+ // @todo: but... actually it would still be somewhat nice to merge the two loops
+ // the mem peaks are at different positions
+ for ($i = 0; $i < $n; ++$i) {
+ $close = 0;
+ // fancy lines
+ if ($this->line_numbers == GESHI_FANCY_LINE_NUMBERS &&
+ $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
+ // Set the attributes to style the line
+ if ($this->use_classes) {
+ $parsed_code .= '<span class="xtra li2"><span class="de2">';
+ } else {
+ // This style "covers up" the special styles set for special lines
+ // so that styles applied to special lines don't apply to the actual
+ // code on that line
+ $parsed_code .= '<span style="display:block;' . $this->line_style2 . '">'
+ .'<span style="' . $this->code_style .'">';
+ }
+ $close += 2;
+ }
+ //Is this some line with extra styles???
+ if (in_array($i + 1, $this->highlight_extra_lines)) {
+ if ($this->use_classes) {
+ if (isset($this->highlight_extra_lines_styles[$i])) {
+ $parsed_code .= "<span class=\"xtra lx$i\">";
+ } else {
+ $parsed_code .= "<span class=\"xtra ln-xtra\">";
+ }
+ } else {
+ $parsed_code .= "<span style=\"display:block;" . $this->get_line_style($i) . "\">";
+ }
+ ++$close;
+ }
+ $parsed_code .= $this->line_numbers_start + $i;
+ if ($close) {
+ $parsed_code .= str_repeat('</span>', $close);
+ } elseif ($i != $n) {
+ $parsed_code .= "\n";
+ }
+ }
+ $parsed_code .= '</pre></td><td'.$attributes.'>';
+ }
+ $parsed_code .= '<pre'. $attributes .'>';
+ }
+ // No line numbers, but still need to handle highlighting lines extra.
+ // Have to use divs so the full width of the code is highlighted
+ $close = 0;
+ for ($i = 0; $i < $n; ++$i) {
+ // Make lines have at least one space in them if they're empty
+ // BenBE: Checking emptiness using trim instead of relying on blanks
+ if ('' == trim($code[$i])) {
+ $code[$i] = '&nbsp;';
+ }
+ // fancy lines
+ if ($this->line_numbers == GESHI_FANCY_LINE_NUMBERS &&
+ $i % $this->line_nth_row == ($this->line_nth_row - 1)) {
+ // Set the attributes to style the line
+ if ($this->use_classes) {
+ $parsed_code .= '<span class="xtra li2"><span class="de2">';
+ } else {
+ // This style "covers up" the special styles set for special lines
+ // so that styles applied to special lines don't apply to the actual
+ // code on that line
+ $parsed_code .= '<span style="display:block;' . $this->line_style2 . '">'
+ .'<span style="' . $this->code_style .'">';
+ }
+ $close += 2;
+ }
+ //Is this some line with extra styles???
+ if (in_array($i + 1, $this->highlight_extra_lines)) {
+ if ($this->use_classes) {
+ if (isset($this->highlight_extra_lines_styles[$i])) {
+ $parsed_code .= "<span class=\"xtra lx$i\">";
+ } else {
+ $parsed_code .= "<span class=\"xtra ln-xtra\">";
+ }
+ } else {
+ $parsed_code .= "<span style=\"display:block;" . $this->get_line_style($i) . "\">";
+ }
+ ++$close;
+ }
+
+ $parsed_code .= $code[$i];
+
+ if ($close) {
+ $parsed_code .= str_repeat('</span>', $close);
+ $close = 0;
+ }
+ if ($i + 1 < $n) {
+ $parsed_code .= "\n";
+ }
+ unset($code[$i]);
+ }
+
+ if ($this->header_type == GESHI_HEADER_PRE_VALID || $this->header_type == GESHI_HEADER_PRE_TABLE) {
+ $parsed_code .= '</pre>';
+ }
+ if ($this->header_type == GESHI_HEADER_PRE_TABLE && $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ $parsed_code .= '</td>';
+ }
+ }
+
+ $parsed_code .= $this->footer();
+ }
+
+ /**
+ * Creates the header for the code block (with correct attributes)
+ *
+ * @return string The header for the code block
+ * @since 1.0.0
+ */
+ protected function header() {
+ // Get attributes needed
+ /**
+ * @todo Document behaviour change - class is outputted regardless of whether
+ * we're using classes or not. Same with style
+ */
+ $attributes = ' class="' . $this->_genCSSName($this->language);
+ if ($this->overall_class != '') {
+ $attributes .= " ".$this->_genCSSName($this->overall_class);
+ }
+ $attributes .= '"';
+
+ if ($this->overall_id != '') {
+ $attributes .= " id=\"{$this->overall_id}\"";
+ }
+ if ($this->overall_style != '' && !$this->use_classes) {
+ $attributes .= ' style="' . $this->overall_style . '"';
+ }
+
+ $ol_attributes = '';
+
+ if ($this->line_numbers_start != 1) {
+ $ol_attributes .= ' start="' . $this->line_numbers_start . '"';
+ }
+
+ // Get the header HTML
+ $header = $this->header_content;
+ if ($header) {
+ if ($this->header_type == GESHI_HEADER_PRE || $this->header_type == GESHI_HEADER_PRE_VALID) {
+ $header = str_replace("\n", '', $header);
+ }
+ $header = $this->replace_keywords($header);
+
+ if ($this->use_classes) {
+ $attr = ' class="head"';
+ } else {
+ $attr = " style=\"{$this->header_content_style}\"";
+ }
+ if ($this->header_type == GESHI_HEADER_PRE_TABLE && $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ $header = "<thead><tr><td colspan=\"2\" $attr>$header</td></tr></thead>";
+ } else {
+ $header = "<div$attr>$header</div>";
+ }
+ }
+
+ if (GESHI_HEADER_NONE == $this->header_type) {
+ if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ return "$header<ol$attributes$ol_attributes>";
+ }
+ return $header . ($this->force_code_block ? '<div>' : '');
+ }
+
+ // Work out what to return and do it
+ if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ if ($this->header_type == GESHI_HEADER_PRE) {
+ return "<pre$attributes>$header<ol$ol_attributes>";
+ } elseif ($this->header_type == GESHI_HEADER_DIV ||
+ $this->header_type == GESHI_HEADER_PRE_VALID) {
+ return "<div$attributes>$header<ol$ol_attributes>";
+ } elseif ($this->header_type == GESHI_HEADER_PRE_TABLE) {
+ return "<table$attributes>$header<tbody><tr class=\"li1\">";
+ }
+ } else {
+ if ($this->header_type == GESHI_HEADER_PRE) {
+ return "<pre$attributes>$header" .
+ ($this->force_code_block ? '<div>' : '');
+ } else {
+ return "<div$attributes>$header" .
+ ($this->force_code_block ? '<div>' : '');
+ }
+ }
+ }
+
+ /**
+ * Returns the footer for the code block.
+ *
+ * @return string The footer for the code block
+ * @since 1.0.0
+ */
+ protected function footer() {
+ $footer = $this->footer_content;
+ if ($footer) {
+ if ($this->header_type == GESHI_HEADER_PRE) {
+ $footer = str_replace("\n", '', $footer);;
+ }
+ $footer = $this->replace_keywords($footer);
+
+ if ($this->use_classes) {
+ $attr = ' class="foot"';
+ } else {
+ $attr = " style=\"{$this->footer_content_style}\"";
+ }
+ if ($this->header_type == GESHI_HEADER_PRE_TABLE && $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ $footer = "<tfoot><tr><td colspan=\"2\">$footer</td></tr></tfoot>";
+ } else {
+ $footer = "<div$attr>$footer</div>";
+ }
+ }
+
+ if (GESHI_HEADER_NONE == $this->header_type) {
+ return ($this->line_numbers != GESHI_NO_LINE_NUMBERS) ? '</ol>' . $footer : $footer;
+ }
+
+ if ($this->header_type == GESHI_HEADER_DIV || $this->header_type == GESHI_HEADER_PRE_VALID) {
+ if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ return "</ol>$footer</div>";
+ }
+ return ($this->force_code_block ? '</div>' : '') .
+ "$footer</div>";
+ }
+ elseif ($this->header_type == GESHI_HEADER_PRE_TABLE) {
+ if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ return "</tr></tbody>$footer</table>";
+ }
+ return ($this->force_code_block ? '</div>' : '') .
+ "$footer</div>";
+ }
+ else {
+ if ($this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ return "</ol>$footer</pre>";
+ }
+ return ($this->force_code_block ? '</div>' : '') .
+ "$footer</pre>";
+ }
+ }
+
+ /**
+ * Replaces certain keywords in the header and footer with
+ * certain configuration values
+ *
+ * @param string $instr The header or footer content to do replacement on
+ * @return string The header or footer with replaced keywords
+ * @since 1.0.2
+ */
+ protected function replace_keywords($instr) {
+ $keywords = $replacements = array();
+
+ $keywords[] = '<TIME>';
+ $keywords[] = '{TIME}';
+ $replacements[] = $replacements[] = number_format($time = $this->get_time(), 3);
+
+ $keywords[] = '<LANGUAGE>';
+ $keywords[] = '{LANGUAGE}';
+ $replacements[] = $replacements[] = $this->language_data['LANG_NAME'];
+
+ $keywords[] = '<VERSION>';
+ $keywords[] = '{VERSION}';
+ $replacements[] = $replacements[] = GESHI_VERSION;
+
+ $keywords[] = '<SPEED>';
+ $keywords[] = '{SPEED}';
+ if ($time <= 0) {
+ $speed = 'N/A';
+ } else {
+ $speed = strlen($this->source) / $time;
+ if ($speed >= 1024) {
+ $speed = sprintf("%.2f KB/s", $speed / 1024.0);
+ } else {
+ $speed = sprintf("%.0f B/s", $speed);
+ }
+ }
+ $replacements[] = $replacements[] = $speed;
+
+ return str_replace($keywords, $replacements, $instr);
+ }
+
+ /**
+ * Secure replacement for PHP built-in function htmlspecialchars().
+ *
+ * See ticket #427 (http://wush.net/trac/wikka/ticket/427) for the rationale
+ * for this replacement function.
+ *
+ * The INTERFACE for this function is almost the same as that for
+ * htmlspecialchars(), with the same default for quote style; however, there
+ * is no 'charset' parameter. The reason for this is as follows:
+ *
+ * The PHP docs say:
+ * "The third argument charset defines character set used in conversion."
+ *
+ * I suspect PHP's htmlspecialchars() is working at the byte-value level and
+ * thus _needs_ to know (or asssume) a character set because the special
+ * characters to be replaced could exist at different code points in
+ * different character sets. (If indeed htmlspecialchars() works at
+ * byte-value level that goes some way towards explaining why the
+ * vulnerability would exist in this function, too, and not only in
+ * htmlentities() which certainly is working at byte-value level.)
+ *
+ * This replacement function however works at character level and should
+ * therefore be "immune" to character set differences - so no charset
+ * parameter is needed or provided. If a third parameter is passed, it will
+ * be silently ignored.
+ *
+ * In the OUTPUT there is a minor difference in that we use '&#39;' instead
+ * of PHP's '&#039;' for a single quote: this provides compatibility with
+ * get_html_translation_table(HTML_SPECIALCHARS, ENT_QUOTES)
+ * (see comment by mikiwoz at yahoo dot co dot uk on
+ * http://php.net/htmlspecialchars); it also matches the entity definition
+ * for XML 1.0
+ * (http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_Special_characters).
+ * Like PHP we use a numeric character reference instead of '&apos;' for the
+ * single quote. For the other special characters we use the named entity
+ * references, as PHP is doing.
+ *
+ * @author {@link http://wikkawiki.org/JavaWoman Marjolein Katsma}
+ *
+ * @license http://www.gnu.org/copyleft/lgpl.html
+ * GNU Lesser General Public License
+ * @copyright Copyright 2007, {@link http://wikkawiki.org/CreditsPage
+ * Wikka Development Team}
+ *
+ * @param string $string string to be converted
+ * @param integer $quote_style
+ * - ENT_COMPAT: escapes &, <, > and double quote (default)
+ * - ENT_NOQUOTES: escapes only &, < and >
+ * - ENT_QUOTES: escapes &, <, >, double and single quotes
+ * @return string converted string
+ * @since 1.0.7.18
+ */
+ protected function hsc($string, $quote_style = ENT_COMPAT) {
+ // init
+ static $aTransSpecchar = array(
+ '&' => '&amp;',
+ '"' => '&quot;',
+ '<' => '&lt;',
+ '>' => '&gt;',
+
+ //This fix is related to SF#1923020, but has to be applied
+ //regardless of actually highlighting symbols.
+
+ //Circumvent a bug with symbol highlighting
+ //This is required as ; would produce undesirable side-effects if it
+ //was not to be processed as an entity.
+ ';' => '<SEMI>', // Force ; to be processed as entity
+ '|' => '<PIPE>' // Force | to be processed as entity
+ ); // ENT_COMPAT set
+
+ switch ($quote_style) {
+ case ENT_NOQUOTES: // don't convert double quotes
+ unset($aTransSpecchar['"']);
+ break;
+ case ENT_QUOTES: // convert single quotes as well
+ $aTransSpecchar["'"] = '&#39;'; // (apos) htmlspecialchars() uses '&#039;'
+ break;
+ }
+
+ // return translated string
+ return strtr($string, $aTransSpecchar);
+ }
+
+ /**
+ * Generate a CSS class name from a given string.
+ * Prevents invalid CSS classes.
+ *
+ * @param string $name Proposed class name
+ *
+ * @return string Safe CSS class name
+ */
+ protected function _genCSSName($name) {
+ return (is_numeric($name[0]) ? '_' : '') . $name;
+ }
+
+ /**
+ * Returns a stylesheet for the highlighted code. If $economy mode
+ * is true, we only return the stylesheet declarations that matter for
+ * this code block instead of the whole thing
+ *
+ * @param boolean $economy_mode Whether to use economy mode or not
+ * @return string A stylesheet built on the data for the current language
+ * @since 1.0.0
+ */
+ public function get_stylesheet($economy_mode = true) {
+ // If there's an error, chances are that the language file
+ // won't have populated the language data file, so we can't
+ // risk getting a stylesheet...
+ if ($this->error) {
+ return '';
+ }
+
+ //Check if the style rearrangements have been processed ...
+ //This also does some preprocessing to check which style groups are useable ...
+ if(!isset($this->language_data['NUMBERS_CACHE'])) {
+ $this->build_style_cache();
+ }
+
+ // First, work out what the selector should be. If there's an ID,
+ // that should be used, the same for a class. Otherwise, a selector
+ // of '' means that these styles will be applied anywhere
+ if ($this->overall_id) {
+ $selector = '#' . $this->_genCSSName($this->overall_id);
+ } else {
+ $selector = '.' . $this->_genCSSName($this->language);
+ if ($this->overall_class) {
+ $selector .= '.' . $this->_genCSSName($this->overall_class);
+ }
+ }
+ $selector .= ' ';
+
+ // Header of the stylesheet
+ if (!$economy_mode) {
+ $stylesheet = "/**\n".
+ " * GeSHi Dynamically Generated Stylesheet\n".
+ " * --------------------------------------\n".
+ " * Dynamically generated stylesheet for {$this->language}\n".
+ " * CSS class: {$this->overall_class}, CSS id: {$this->overall_id}\n".
+ " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2014 Benny Baumann\n" .
+ " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
+ " * --------------------------------------\n".
+ " */\n";
+ } else {
+ $stylesheet = "/**\n".
+ " * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2014 Benny Baumann\n" .
+ " * (http://qbnz.com/highlighter/ and http://geshi.org/)\n".
+ " */\n";
+ }
+
+ // Set the <ol> to have no effect at all if there are line numbers
+ // (<ol>s have margins that should be destroyed so all layout is
+ // controlled by the set_overall_style method, which works on the
+ // <pre> or <div> container). Additionally, set default styles for lines
+ if (!$economy_mode || $this->line_numbers != GESHI_NO_LINE_NUMBERS) {
+ //$stylesheet .= "$selector, {$selector}ol, {$selector}ol li {margin: 0;}\n";
+ $stylesheet .= "$selector.de1, $selector.de2 {{$this->code_style}}\n";
+ }
+
+ // Add overall styles
+ // note: neglect economy_mode, empty styles are meaningless
+ if ($this->overall_style != '') {
+ $stylesheet .= "$selector {{$this->overall_style}}\n";
+ }
+
+ // Add styles for links
+ // note: economy mode does not make _any_ sense here
+ // either the style is empty and thus no selector is needed
+ // or the appropriate key is given.
+ foreach ($this->link_styles as $key => $style) {
+ if ($style != '') {
+ switch ($key) {
+ case GESHI_LINK:
+ $stylesheet .= "{$selector}a:link {{$style}}\n";
+ break;
+ case GESHI_HOVER:
+ $stylesheet .= "{$selector}a:hover {{$style}}\n";
+ break;
+ case GESHI_ACTIVE:
+ $stylesheet .= "{$selector}a:active {{$style}}\n";
+ break;
+ case GESHI_VISITED:
+ $stylesheet .= "{$selector}a:visited {{$style}}\n";
+ break;
+ }
+ }
+ }
+
+ // Header and footer
+ // note: neglect economy_mode, empty styles are meaningless
+ if ($this->header_content_style != '') {
+ $stylesheet .= "$selector.head {{$this->header_content_style}}\n";
+ }
+ if ($this->footer_content_style != '') {
+ $stylesheet .= "$selector.foot {{$this->footer_content_style}}\n";
+ }
+
+ // Styles for important stuff
+ // note: neglect economy_mode, empty styles are meaningless
+ if ($this->important_styles != '') {
+ $stylesheet .= "$selector.imp {{$this->important_styles}}\n";
+ }
+
+ // Simple line number styles
+ if ((!$economy_mode || $this->line_numbers != GESHI_NO_LINE_NUMBERS) && $this->line_style1 != '') {
+ $stylesheet .= "{$selector}li, {$selector}.li1 {{$this->line_style1}}\n";
+ }
+ if ((!$economy_mode || $this->line_numbers != GESHI_NO_LINE_NUMBERS) && $this->table_linenumber_style != '') {
+ $stylesheet .= "{$selector}.ln {{$this->table_linenumber_style}}\n";
+ }
+ // If there is a style set for fancy line numbers, echo it out
+ if ((!$economy_mode || $this->line_numbers == GESHI_FANCY_LINE_NUMBERS) && $this->line_style2 != '') {
+ $stylesheet .= "{$selector}.li2 {{$this->line_style2}}\n";
+ }
+
+ // note: empty styles are meaningless
+ foreach ($this->language_data['STYLES']['KEYWORDS'] as $group => $styles) {
+ if ($styles != '' && (!$economy_mode ||
+ (isset($this->lexic_permissions['KEYWORDS'][$group]) &&
+ $this->lexic_permissions['KEYWORDS'][$group]))) {
+ $stylesheet .= "$selector.kw$group {{$styles}}\n";
+ }
+ }
+ foreach ($this->language_data['STYLES']['COMMENTS'] as $group => $styles) {
+ if ($styles != '' && (!$economy_mode ||
+ (isset($this->lexic_permissions['COMMENTS'][$group]) &&
+ $this->lexic_permissions['COMMENTS'][$group]) ||
+ (!empty($this->language_data['COMMENT_REGEXP']) &&
+ !empty($this->language_data['COMMENT_REGEXP'][$group])))) {
+ $stylesheet .= "$selector.co$group {{$styles}}\n";
+ }
+ }
+ foreach ($this->language_data['STYLES']['ESCAPE_CHAR'] as $group => $styles) {
+ if ($styles != '' && (!$economy_mode || $this->lexic_permissions['ESCAPE_CHAR'])) {
+ // NEW: since 1.0.8 we have to handle hardescapes
+ if ($group === 'HARD') {
+ $group = '_h';
+ }
+ $stylesheet .= "$selector.es$group {{$styles}}\n";
+ }
+ }
+ foreach ($this->language_data['STYLES']['BRACKETS'] as $group => $styles) {
+ if ($styles != '' && (!$economy_mode || $this->lexic_permissions['BRACKETS'])) {
+ $stylesheet .= "$selector.br$group {{$styles}}\n";
+ }
+ }
+ foreach ($this->language_data['STYLES']['SYMBOLS'] as $group => $styles) {
+ if ($styles != '' && (!$economy_mode || $this->lexic_permissions['SYMBOLS'])) {
+ $stylesheet .= "$selector.sy$group {{$styles}}\n";
+ }
+ }
+ foreach ($this->language_data['STYLES']['STRINGS'] as $group => $styles) {
+ if ($styles != '' && (!$economy_mode || $this->lexic_permissions['STRINGS'])) {
+ // NEW: since 1.0.8 we have to handle hardquotes
+ if ($group === 'HARD') {
+ $group = '_h';
+ }
+ $stylesheet .= "$selector.st$group {{$styles}}\n";
+ }
+ }
+ foreach ($this->language_data['STYLES']['NUMBERS'] as $group => $styles) {
+ if ($styles != '' && (!$economy_mode || $this->lexic_permissions['NUMBERS'])) {
+ $stylesheet .= "$selector.nu$group {{$styles}}\n";
+ }
+ }
+ foreach ($this->language_data['STYLES']['METHODS'] as $group => $styles) {
+ if ($styles != '' && (!$economy_mode || $this->lexic_permissions['METHODS'])) {
+ $stylesheet .= "$selector.me$group {{$styles}}\n";
+ }
+ }
+ // note: neglect economy_mode, empty styles are meaningless
+ foreach ($this->language_data['STYLES']['SCRIPT'] as $group => $styles) {
+ if ($styles != '') {
+ $stylesheet .= "$selector.sc$group {{$styles}}\n";
+ }
+ }
+ foreach ($this->language_data['STYLES']['REGEXPS'] as $group => $styles) {
+ if ($styles != '' && (!$economy_mode ||
+ (isset($this->lexic_permissions['REGEXPS'][$group]) &&
+ $this->lexic_permissions['REGEXPS'][$group]))) {
+ if (is_array($this->language_data['REGEXPS'][$group]) &&
+ array_key_exists(GESHI_CLASS, $this->language_data['REGEXPS'][$group])) {
+ $stylesheet .= "$selector.";
+ $stylesheet .= $this->language_data['REGEXPS'][$group][GESHI_CLASS];
+ $stylesheet .= " {{$styles}}\n";
+ } else {
+ $stylesheet .= "$selector.re$group {{$styles}}\n";
+ }
+ }
+ }
+ // Styles for lines being highlighted extra
+ if (!$economy_mode || (count($this->highlight_extra_lines)!=count($this->highlight_extra_lines_styles))) {
+ $stylesheet .= "{$selector}.ln-xtra, {$selector}li.ln-xtra, {$selector}div.ln-xtra {{$this->highlight_extra_lines_style}}\n";
+ }
+ $stylesheet .= "{$selector}span.xtra { display:block; }\n";
+ foreach ($this->highlight_extra_lines_styles as $lineid => $linestyle) {
+ $stylesheet .= "{$selector}.lx$lineid, {$selector}li.lx$lineid, {$selector}div.lx$lineid {{$linestyle}}\n";
+ }
+
+ return $stylesheet;
+ }
+
+ /**
+ * Get's the style that is used for the specified line
+ *
+ * @param int $line The line number information is requested for
+ * @since 1.0.7.21
+ */
+ protected function get_line_style($line) {
+ $style = null;
+ if (isset($this->highlight_extra_lines_styles[$line])) {
+ $style = $this->highlight_extra_lines_styles[$line];
+ } else { // if no "extra" style assigned
+ $style = $this->highlight_extra_lines_style;
+ }
+
+ return $style;
+ }
+
+ /**
+ * this functions creates an optimized regular expression list
+ * of an array of strings.
+ *
+ * Example:
+ * <code>$list = array('faa', 'foo', 'foobar');
+ * => string 'f(aa|oo(bar)?)'</code>
+ *
+ * @param array $list array of (unquoted) strings
+ * @param string $regexp_delimiter your regular expression delimiter, @see preg_quote()
+ * @return string for regular expression
+ * @author Milian Wolff <mail@milianw.de>
+ * @since 1.0.8
+ */
+ protected function optimize_regexp_list($list, $regexp_delimiter = '/') {
+ $regex_chars = array('.', '\\', '+', '-', '*', '?', '[', '^', ']', '$',
+ '(', ')', '{', '}', '=', '!', '<', '>', '|', ':', $regexp_delimiter);
+ sort($list);
+ $regexp_list = array('');
+ $num_subpatterns = 0;
+ $list_key = 0;
+
+ // the tokens which we will use to generate the regexp list
+ $tokens = array();
+ $prev_keys = array();
+ // go through all entries of the list and generate the token list
+ $cur_len = 0;
+ for ($i = 0, $i_max = count($list); $i < $i_max; ++$i) {
+ if ($cur_len > GESHI_MAX_PCRE_LENGTH) {
+ // seems like the length of this pcre is growing exorbitantly
+ $regexp_list[++$list_key] = $this->_optimize_regexp_list_tokens_to_string($tokens);
+ $num_subpatterns = substr_count($regexp_list[$list_key], '(?:');
+ $tokens = array();
+ $cur_len = 0;
+ }
+ $level = 0;
+ $entry = preg_quote((string) $list[$i], $regexp_delimiter);
+ $pointer = &$tokens;
+ // properly assign the new entry to the correct position in the token array
+ // possibly generate smaller common denominator keys
+ while (true) {
+ // get the common denominator
+ if (isset($prev_keys[$level])) {
+ if ($prev_keys[$level] == $entry) {
+ // this is a duplicate entry, skip it
+ continue 2;
+ }
+ $char = 0;
+ while (isset($entry[$char]) && isset($prev_keys[$level][$char])
+ && $entry[$char] == $prev_keys[$level][$char]) {
+ ++$char;
+ }
+ if ($char > 0) {
+ // this entry has at least some chars in common with the current key
+ if ($char == strlen($prev_keys[$level])) {
+ // current key is totally matched, i.e. this entry has just some bits appended
+ $pointer = &$pointer[$prev_keys[$level]];
+ } else {
+ // only part of the keys match
+ $new_key_part1 = substr($prev_keys[$level], 0, $char);
+ $new_key_part2 = substr($prev_keys[$level], $char);
+
+ if (in_array($new_key_part1[0], $regex_chars)
+ || in_array($new_key_part2[0], $regex_chars)) {
+ // this is bad, a regex char as first character
+ $pointer[$entry] = array('' => true);
+ array_splice($prev_keys, $level, count($prev_keys), $entry);
+ $cur_len += strlen($entry);
+ continue;
+ } else {
+ // relocate previous tokens
+ $pointer[$new_key_part1] = array($new_key_part2 => $pointer[$prev_keys[$level]]);
+ unset($pointer[$prev_keys[$level]]);
+ $pointer = &$pointer[$new_key_part1];
+ // recreate key index
+ array_splice($prev_keys, $level, count($prev_keys), array($new_key_part1, $new_key_part2));
+ $cur_len += strlen($new_key_part2);
+ }
+ }
+ ++$level;
+ $entry = substr($entry, $char);
+ continue;
+ }
+ // else: fall trough, i.e. no common denominator was found
+ }
+ if ($level == 0 && !empty($tokens)) {
+ // we can dump current tokens into the string and throw them away afterwards
+ $new_entry = $this->_optimize_regexp_list_tokens_to_string($tokens);
+ $new_subpatterns = substr_count($new_entry, '(?:');
+ if (GESHI_MAX_PCRE_SUBPATTERNS && $num_subpatterns + $new_subpatterns > GESHI_MAX_PCRE_SUBPATTERNS) {
+ $regexp_list[++$list_key] = $new_entry;
+ $num_subpatterns = $new_subpatterns;
+ } else {
+ if (!empty($regexp_list[$list_key])) {
+ $new_entry = '|' . $new_entry;
+ }
+ $regexp_list[$list_key] .= $new_entry;
+ $num_subpatterns += $new_subpatterns;
+ }
+ $tokens = array();
+ $cur_len = 0;
+ }
+ // no further common denominator found
+ $pointer[$entry] = array('' => true);
+ array_splice($prev_keys, $level, count($prev_keys), $entry);
+
+ $cur_len += strlen($entry);
+ break;
+ }
+ unset($list[$i]);
+ }
+ // make sure the last tokens get converted as well
+ $new_entry = $this->_optimize_regexp_list_tokens_to_string($tokens);
+ if (GESHI_MAX_PCRE_SUBPATTERNS && $num_subpatterns + substr_count($new_entry, '(?:') > GESHI_MAX_PCRE_SUBPATTERNS) {
+ if ( !empty($regexp_list[$list_key]) ) {
+ ++$list_key;
+ }
+ $regexp_list[$list_key] = $new_entry;
+ } else {
+ if (!empty($regexp_list[$list_key])) {
+ $new_entry = '|' . $new_entry;
+ }
+ $regexp_list[$list_key] .= $new_entry;
+ }
+ return $regexp_list;
+ }
+
+ /**
+ * this function creates the appropriate regexp string of an token array
+ * you should not call this function directly, @see $this->optimize_regexp_list().
+ *
+ * @param array $tokens array of tokens
+ * @param bool $recursed to know wether we recursed or not
+ * @return string
+ * @author Milian Wolff <mail@milianw.de>
+ * @since 1.0.8
+ */
+ protected function _optimize_regexp_list_tokens_to_string(&$tokens, $recursed = false) {
+ $list = '';
+ foreach ($tokens as $token => $sub_tokens) {
+ $list .= $token;
+ $close_entry = isset($sub_tokens['']);
+ unset($sub_tokens['']);
+ if (!empty($sub_tokens)) {
+ $list .= '(?:' . $this->_optimize_regexp_list_tokens_to_string($sub_tokens, true) . ')';
+ if ($close_entry) {
+ // make sub_tokens optional
+ $list .= '?';
+ }
+ }
+ $list .= '|';
+ }
+ if (!$recursed) {
+ // do some optimizations
+ // common trailing strings
+ // BUGGY!
+ //$list = preg_replace_callback('#(?<=^|\:|\|)\w+?(\w+)(?:\|.+\1)+(?=\|)#', create_function(
+ // '$matches', 'return "(?:" . preg_replace("#" . preg_quote($matches[1], "#") . "(?=\||$)#", "", $matches[0]) . ")" . $matches[1];'), $list);
+ // (?:p)? => p?
+ $list = preg_replace('#\(\?\:(.)\)\?#', '\1?', $list);
+ // (?:a|b|c|d|...)? => [abcd...]?
+ // TODO: a|bb|c => [ac]|bb
+ static $callback_2;
+ if (!isset($callback_2)) {
+ $callback_2 = function($matches) {
+ return "[" . str_replace("|", "", $matches[1]) . "]";
+ };
+ }
+ $list = preg_replace_callback('#\(\?\:((?:.\|)+.)\)#', $callback_2, $list);
+ }
+ // return $list without trailing pipe
+ return substr($list, 0, -1);
+ }
+} // End Class GeSHi
+
+
+if (!function_exists('geshi_highlight')) {
+ /**
+ * Easy way to highlight stuff. Behaves just like highlight_string
+ *
+ * @param string $string The code to highlight
+ * @param string $language The language to highlight the code in
+ * @param string $path The path to the language files. You can leave this blank if you need
+ * as from version 1.0.7 the path should be automatically detected
+ * @param boolean $return Whether to return the result or to echo
+ * @return string The code highlighted (if $return is true)
+ * @since 1.0.2
+ */
+ function geshi_highlight($string, $language, $path = null, $return = false) {
+ $geshi = new GeSHi($string, $language, $path);
+ $geshi->set_header_type(GESHI_HEADER_NONE);
+
+ if ($return) {
+ return '<code>' . $geshi->parse_code() . '</code>';
+ }
+
+ echo '<code>' . $geshi->parse_code() . '</code>';
+
+ if ($geshi->error()) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/4cs.php b/platform/www/vendor/geshi/geshi/src/geshi/4cs.php
new file mode 100644
index 0000000..228d523
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/4cs.php
@@ -0,0 +1,137 @@
+<?php
+/*************************************************************************************
+ * 4cs.php
+ * ------
+ * Author: Jason Curl (jason.curl@continental-corporation.com)
+ * Copyright: (c) 2009 Jason Curl
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/09/05
+ *
+ * 4CS language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/09/05
+ * - First Release
+ *
+ * TODO (updated 2009/09/01)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'GADV 4CS',
+ 'COMMENT_SINGLE' => array(1 => "//"),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'All', 'AllMatches', 'And', 'And_Filters', 'As', 'Asc', 'BasedOn',
+ 'BestMatch', 'Block', 'Buffer', 'ByRef', 'ByVal', 'Call', 'Channel',
+ 'Chr', 'Clear', 'Close', 'Confirm', 'Const', 'Continue', 'Cos',
+ 'Critical', 'Declare', 'Default', 'DefaultChannel', 'DefaultDelayTime',
+ 'DefaultReceiveMode', 'DefaultResponseTime', '#Define', 'DelayTime',
+ 'Delete', 'Div', 'Else', '#Else', 'ElseIf', '#ElseIf', 'End', 'EndCritical',
+ 'EndInlineC', 'EndFunction', 'EndIf', '#EndIf', 'EndInputList',
+ 'EndLocalChannel', 'EndScenario', 'EndSub', 'EndWhile', 'Error',
+ 'ErrorLevelOff', 'ErrorLevelOn', 'ErrorLevelSet', 'ErrorLevelSetRaw',
+ 'Event', 'EventMode', 'EventOff', 'EventOn', 'EventSet', 'EventSetRaw',
+ 'Execute', 'Exit', 'Exp', 'FileClose', 'FilterClear', 'FileEOF', 'FileOpen',
+ 'FileRead', 'FileSize', 'FileWrite', 'FilterAdd', 'FilterMode',
+ 'FilterOff', 'FilterOn', 'For', 'Format', 'Function', 'GoOnline', 'GoTo',
+ 'Handle', 'Hide', 'If', '#If', '#IfDef', '#IfNDef', 'Ignore', '#Include',
+ 'InlineC', 'Input', 'InputItem', 'InputList', 'Kill', 'LBound', 'LocalChannel',
+ 'Local', 'Log', 'Log10', 'LogOff', 'LogOn', 'Loop', 'Message', 'Mod',
+ 'MonitorChannel', 'MostFormat', 'MostMessage', 'Named', 'Never', 'Next',
+ 'NoOrder', 'Not', 'Nothing', 'NoWait', 'Numeric', 'OnError', 'OnEvent',
+ 'Or', 'Or_Filters', 'Order', 'Pass', 'Pow', 'Prototype', 'Quit', 'Raise',
+ 'Random', 'Receive', 'ReceiveMode', 'ReceiveRaw', 'Redim', 'Remote', 'Repeat',
+ 'Repeated', 'ResponseTime', 'Resume', 'ResumeCritical', 'RT_Common',
+ 'RT_Dll_Call', 'RT_FILEIO', 'RT_General', 'RT_HardwareAccess',
+ 'RT_MessageVariableAccess', 'RT_Scenario', 'RT_VariableAccess', 'Runtime',
+ 'Scenario', 'ScenarioEnd', 'ScenarioStart', 'ScenarioStatus', 'ScenarioTerminate',
+ 'Send', 'SendRaw', 'Set', 'SetError', 'Sin', 'Single', 'Show', 'Start',
+ 'StartCritical', 'Starts', 'Static', 'Step', 'Stop', 'String', 'Sub',
+ 'System_Error', 'TerminateAllChilds', 'Terminates', 'Then', 'Throw', 'TimeOut',
+ 'To', 'TooLate', 'Trunc', 'UBound', 'Unexpected', 'Until', 'User_Error',
+ 'View', 'Wait', 'Warning', 'While', 'XOr'
+ ),
+ 2 => array(
+ 'alias', 'winapi', 'long', 'char', 'double', 'float', 'int', 'short', 'lib'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '=', ':=', '<', '>', '<>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000C0; font-weight: bold;',
+ 2 => 'color: #808080;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000080;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #800080;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #66cc66;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000080;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/6502acme.php b/platform/www/vendor/geshi/geshi/src/geshi/6502acme.php
new file mode 100644
index 0000000..5d40da9
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/6502acme.php
@@ -0,0 +1,228 @@
+<?php
+/*************************************************************************************
+ * 6502acme.php
+ * -------
+ * Author: Warren Willmey
+ * Copyright: (c) 2010 Warren Willmey.
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/05/26
+ *
+ * MOS 6502 (more specifically 6510) ACME Cross Assembler 0.93 by Marco Baye language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/07/22
+ * - First Release
+ *
+ * TODO (updated 2010/07/22)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'MOS 6502 (6510) ACME Cross Assembler format',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /* 6502/6510 Opcodes. */
+ 1 => array(
+ 'adc', 'and', 'asl', 'bcc', 'bcs', 'beq', 'bit', 'bmi',
+ 'bne', 'bpl', 'brk', 'bvc', 'bvs', 'clc', 'cld', 'cli',
+ 'clv', 'cmp', 'cpx', 'cpy', 'dec', 'dex', 'dey', 'eor',
+ 'inc', 'inx', 'iny', 'jmp', 'jsr', 'lda', 'ldx', 'ldy',
+ 'lsr', 'nop', 'ora', 'pha', 'php', 'pla', 'plp', 'rol',
+ 'ror', 'rti', 'rts', 'sbc', 'sec', 'sed', 'sei', 'sta',
+ 'stx', 'sty', 'tax', 'tay', 'tsx', 'txa', 'txs', 'tya',
+ ),
+ /* Index Registers, yes the 6502 has other registers by they are only
+ * accessable by specific opcodes. The 65816 also has access to the stack pointer S. */
+ 2 => array(
+ 'x', 'y', 's'
+ ),
+ /* Directives or "pseudo opcodes" as defined by ACME 0.93 file AllPOs.txt. */
+ 3 => array(
+ '!8', '!08', '!by', '!byte',
+ '!16', '!wo', '!word',
+ '!24', '!32',
+ '!fi', '!fill',
+ '!align',
+ '!ct', '!convtab',
+ '!tx', '!text',
+ '!pet',
+ '!raw',
+ '!scrxor',
+ '!to',
+ '!source',
+ '!bin', '!binary',
+ '!zn', '!zone',
+ '!sl',
+ '!svl',
+ '!sal',
+ '!if', '!ifdef',
+ '!for',
+ '!set',
+ '!do', 'while', 'until',
+ '!eof', '!endoffile',
+ '!warn', '!error', '!serious',
+ '!macro',
+// , '*=' // Not a valid keyword (uses both * and = signs) moved to symbols instead.
+ '!initmem',
+ '!pseudopc',
+ '!cpu',
+ '!al', '!as', '!rl', '!rs',
+ ),
+
+ /* 6502/6510 undocumented opcodes (often referred to as illegal instructions).
+ * These are present in the 6502/6510 but NOT in the newer CMOS revisions of the 65C02 or 65816.
+ * As they are undocumented instructions there are no "official" names for them, there are also
+ * several more that mainly perform various forms of crash and are not supported by ACME 0.93.
+ */
+ 4 => array(
+ 'anc', 'arr', 'asr', 'dcp', 'dop', 'isc', 'jam', 'lax',
+ 'rla', 'rra', 'sax', 'sbx', 'slo', 'sre', 'top',
+ ),
+ /* 65c02 instructions, MOS added a few (much needed) instructions in the CMOS version of the 6502, but stupidly removed the undocumented/illegal opcodes.
+ * ACME 0.93 does not support the rmb0-7 and smb0-7 instructions (they are currently rem'ed out). */
+ 5 => array(
+ 'bra', 'phx', 'phy', 'plx', 'ply', 'stz', 'trb', 'tsb'
+ ),
+ /* 65816 instructions. */
+ 6 => array(
+ 'brl', 'cop', 'jml', 'jsl', 'mvn', 'mvp', 'pea', 'pei',
+ 'per', 'phb', 'phd', 'phk', 'plb', 'pld', 'rep', 'rtl',
+ 'sep', 'tcd', 'tcs', 'tdc', 'tsc', 'txy', 'tyx', 'wdm',
+ 'xba', 'xce',
+ ),
+ /* Deprecated directives or "pseudo opcodes" as defined by ACME 0.93 file AllPOs.txt. */
+ 7 => array(
+ '!cbm',
+ '!sz', '!subzone',
+ '!realpc',
+ ),
+ /* Math functions, some are aliases for the symbols. */
+ 8 => array(
+ 'not', 'div', 'mod', 'xor', 'or', 'sin', 'cos', 'tan',
+ 'arcsin', 'arccos', 'arctan', 'int', 'float',
+
+ ),
+
+ ),
+ 'SYMBOLS' => array(
+// '[', ']', '(', ')', '{', '}', // These are already defined by GeSHi as BRACKETS.
+ '*=', '#', '!', '^', '-', '*', '/',
+ '%', '+', '-', '<<', '>>', '>>>',
+ '<', '>', '^', '<=', '<', '>=', '>', '!=',
+ '=', '&', '|', '<>',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ 8 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00f; font-weight:bold;',
+ 2 => 'color: #00f; font-weight:bold;',
+ 3 => 'color: #080; font-weight:bold;',
+ 4 => 'color: #f00; font-weight:bold;',
+ 5 => 'color: #80f; font-weight:bold;',
+ 6 => 'color: #f08; font-weight:bold;',
+ 7 => 'color: #a04; font-weight:bold; font-style: italic;',
+ 8 => 'color: #000;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #999; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #009; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'NUMBERS' => array(
+ GESHI_NUMBER_INT_BASIC => 'color: #f00;',
+ GESHI_NUMBER_HEX_PREFIX_DOLLAR => 'color: #f00;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #f00;',
+ GESHI_NUMBER_BIN_PREFIX_PERCENT => 'color: #f00;',
+ GESHI_NUMBER_FLT_NONSCI => 'color: #f00;',
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #f00;'
+ , 1 => 'color: #933;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_HEX_PREFIX_DOLLAR |
+ GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_BIN_PREFIX_PERCENT,
+ // AMCE Octal format not support and gets picked up as Decimal unfortunately.
+ 'REGEXPS' => array(
+ //ACME .# Binary number format. e.g. %..##..##..##
+ 0 => '\%[\.\#]{1,64}',
+ //ACME Local Labels
+ 1 => '\.[_a-zA-Z][_a-zA-Z0-9]*',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 8,
+ 'PARSER_CONTROL' => array(
+ 'NUMBERS' => array(
+ 'PRECHECK_RX' => '/[\da-fA-F\.\$\%]/'
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/6502kickass.php b/platform/www/vendor/geshi/geshi/src/geshi/6502kickass.php
new file mode 100644
index 0000000..1ddbc59
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/6502kickass.php
@@ -0,0 +1,239 @@
+<?php
+/*************************************************************************************
+ * 6502kickass.php
+ * -------
+ * Author: Warren Willmey
+ * Copyright: (c) 2010 Warren Willmey.
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/06/07
+ *
+ * MOS 6502 (6510) Kick Assembler 3.13 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/07/22
+ * - First Release
+ *
+ * TODO (updated 2010/07/22)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'MOS 6502 (6510) Kick Assembler format',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /* 6502/6510 Opcodes including undocumented opcodes as Kick Assembler 3.13 does not make a distinction - they are ALL valid. */
+ 1 => array(
+ 'adc', 'ahx', 'alr', 'anc', 'anc2', 'and', 'arr', 'asl',
+ 'axs', 'bcc', 'bcs', 'beq', 'bit', 'bmi', 'bne', 'bpl',
+ 'brk', 'bvc', 'bvs', 'clc', 'cld', 'cli', 'clv', 'cmp',
+ 'cpx', 'cpy', 'dcp', 'dec', 'dex', 'dey', 'eor', 'inc',
+ 'inx', 'iny', 'isc', 'jmp', 'jsr', 'las', 'lax', 'lda',
+ 'ldx', 'ldy', 'lsr', 'nop', 'ora', 'pha', 'php', 'pla',
+ 'plp', 'rla', 'rol', 'ror', 'rra', 'rti', 'rts', 'sax',
+ 'sbc', 'sbc2', 'sec', 'sed', 'sei', 'shx', 'shy', 'slo',
+ 'sre', 'sta', 'stx', 'sty', 'tas', 'tax', 'tay', 'tsx',
+ 'txa', 'txs', 'tya', 'xaa',
+ ),
+ /* DTV additional Opcodes. */
+ 2 => array(
+ 'bra', 'sac', 'sir'
+ ),
+ /* Index Registers, yes the 6502 has other registers by they are only
+ * accessable by specific opcodes. */
+ 3 => array(
+ 'x', 'y'
+ ),
+ /* Directives. */
+ 4 => array(
+ '.pc', '.pseudopc', 'virtual', '.align', '.byte', '.word', '.text', '.fill',
+ '.import source', '.import binary', '.import c64', '.import text', '.import', '.print', '.printnow',
+ '.error', '.var', '.eval', '.const', '.eval const', '.enum', '.label', '.define', '.struct',
+ 'if', '.for', '.macro', '.function', '.return', '.pseudocommand', '.namespace', '.filenamespace',
+ '.assert', '.asserterror',
+ ),
+ /* Kick Assembler 3.13 Functions/Operators. */
+ 5 => array(
+ 'size', 'charAt', 'substring', 'asNumber', 'asBoolean', 'toIntString', 'toBinaryString', 'toOctalString',
+ 'toHexString', 'lock', // String functions/operators.
+ 'get', 'set', 'add', 'remove', 'shuffle', // List functions.
+ 'put', 'keys', // Hashtable functions.
+ 'getType', 'getValue', 'CmdArgument', // Pseudo Commands functions.
+ 'asmCommandSize', // Opcode Constants functions.
+ 'LoadBinary', 'getSize',
+ 'LoadSid', 'getData',
+ 'LoadPicture', 'width', 'height', 'getPixel', 'getSinglecolorByte', 'getMulticolorByte',
+ 'createFile', 'writeln',
+ 'cmdLineVars',
+ 'getX', 'getY', 'getZ', // Vector functions.
+ 'RotationMatrix', 'ScaleMatrix', 'MoveMatrix', 'PerspectiveMatrix', // Matrix functions.
+
+ ),
+
+ /* Kick Assembler 3.13 Math Functions. */
+ 6 => array(
+ 'abs', 'acos', 'asin', 'atan', 'atan2', 'cbrt', 'ceil', 'cos', 'cosh',
+ 'exp', 'expm1', 'floor', 'hypot', 'IEEEremainder', 'log', 'log10',
+ 'log1p', 'max', 'min', 'pow', 'mod', 'random', 'round', 'signum',
+ 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'toDegrees', 'toRadians',
+ ),
+
+ /* Kick Assembler 3.13 Objects/Data Types. */
+ 7 => array(
+ 'List', // List() Object.
+ 'Hashtable', // Hashtable() Object.
+ 'Vector', // Vector() Object.
+ 'Matrix', // Matrix() Object.
+ ),
+
+ /* Kick Assembler 3.13 Constants. */
+ 8 => array(
+ 'PI', 'E', // Math Constants.
+ 'AT_ABSOLUTE' , 'AT_ABSOLUTEX' , 'AT_ABSOLUTEY' , 'AT_IMMEDIATE', // Pseudo Commands Constants.
+ 'AT_INDIRECT' , 'AT_IZEROPAGEX' , 'AT_IZEROPAGEY' , 'AT_NONE',
+ 'BLACK', 'WHITE', 'RED', 'CYAN', 'PURPLE', 'GREEN', 'BLUE', // Colour Constants.
+ 'YELLOW', 'ORANGE', 'BROWN', 'LIGHT_RED', 'DARK_GRAY', 'GRAY',
+ 'LIGHT_GREEN', 'LIGHT_BLUE', 'LIGHT_GRAY',
+ 'C64FILE', // Template Tag names.
+ 'BF_C64FILE', 'BF_BITMAP_SINGLECOLOR', 'BF_KOALA' , 'BF_FLI', // Binary format constant
+ ),
+
+ ),
+ 'SYMBOLS' => array(
+// '[', ']', '(', ')', '{', '}', // These are already defined by GeSHi as BRACKETS.
+ '-', '+', '-', '*', '/', '>', '<', '<<', '>>', '&', '|', '^', '=', '==',
+ '!=', '>=', '<=', '!', '&&', '||', '#',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00f; font-weight:bold;',
+ 2 => 'color: #00f; font-weight:bold;',
+ 3 => 'color: #00f; font-weight:bold;',
+ 4 => 'color: #080; font-weight:bold;',
+ 5 => 'color: #80f; font-weight:bold;',
+ 6 => 'color: #f08; font-weight:bold;',
+ 7 => 'color: #a04; font-weight:bold; font-style: italic;',
+ 8 => 'color: #f08; font-weight:bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #999; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #009; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'NUMBERS' => array(
+ GESHI_NUMBER_INT_BASIC => 'color: #f00;',
+ GESHI_NUMBER_HEX_PREFIX_DOLLAR => 'color: #f00;',
+ GESHI_NUMBER_BIN_PREFIX_PERCENT => 'color: #f00;',
+ GESHI_NUMBER_FLT_NONSCI => 'color: #f00;',
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #933;',
+ 1 => 'color: #933;',
+ 2 => 'color: #933;',
+ 3 => 'color: #00f; font-weight:bold;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_HEX_PREFIX_DOLLAR |
+ GESHI_NUMBER_BIN_PREFIX_PERCENT,
+ // AMCE Octal format not support and gets picked up as Decimal unfortunately.
+ 'REGEXPS' => array(
+ //Labels end with a collon.
+ 0 => '[!]{0,1}[_a-zA-Z][_a-zA-Z0-9]*\:',
+ //Multi Labels (local labels) references start with ! and end with + or - for forward/backward reference.
+ 1 => '![_a-zA-Z][_a-zA-Z0-9]*[+-]',
+ //Macros start with a colon :Macro.
+ 2 => ':[_a-zA-Z][_a-zA-Z0-9]*',
+ // Opcode Constants, such as LDA_IMM, STA_IZPY are basically all 6502 opcodes
+ // in UPPER case followed by _underscore_ and the ADDRESS MODE.
+ // As you might imagine that is rather a lot ( 78 supported Opcodes * 12 Addressing modes = 936 variations)
+ // So I thought it better and easier to maintain as a regular expression.
+ // NOTE: The order of the Address Modes must be maintained or it wont work properly (eg. place ZP first and find out!)
+ 3 => '[A-Z]{3}[2]?_(?:IMM|IND|IZPX|IZPY|ZPX|ZPY|ABSX|ABSY|REL|ABS|ZP)',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 8,
+ 'PARSER_CONTROL' => array(
+ 'NUMBERS' => array(
+ 'PRECHECK_RX' => '/[\da-fA-F\.\$\%]/'
+ ),
+ 'KEYWORDS' => array(
+ 5 => array (
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\;>|^&'\"])"
+ ),
+ 6 => array (
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\;>|^&'\"])"
+ ),
+ 8 => array (
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\;>|^&'\"])"
+ )
+ )
+ ),
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/6502tasm.php b/platform/www/vendor/geshi/geshi/src/geshi/6502tasm.php
new file mode 100644
index 0000000..539db01
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/6502tasm.php
@@ -0,0 +1,187 @@
+<?php
+/*************************************************************************************
+ * 6502tasm.php
+ * -------
+ * Author: Warren Willmey
+ * Copyright: (c) 2010 Warren Willmey.
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/06/02
+ *
+ * MOS 6502 (6510) TASM/64TASS (64TASS being the super set of TASM) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/07/22
+ * - First Release
+ *
+ * TODO (updated 2010/07/22)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'MOS 6502 (6510) TASM/64TASS 1.46 Assembler format',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /* 6502/6510 Opcodes. */
+ 1 => array(
+ 'adc', 'and', 'asl', 'bcc', 'bcs', 'beq', 'bit', 'bmi',
+ 'bne', 'bpl', 'brk', 'bvc', 'bvs', 'clc', 'cld', 'cli',
+ 'clv', 'cmp', 'cpx', 'cpy', 'dec', 'dex', 'dey', 'eor',
+ 'inc', 'inx', 'iny', 'jmp', 'jsr', 'lda', 'ldx', 'ldy',
+ 'lsr', 'nop', 'ora', 'pha', 'php', 'pla', 'plp', 'rol',
+ 'ror', 'rti', 'rts', 'sbc', 'sec', 'sed', 'sei', 'sta',
+ 'stx', 'sty', 'tax', 'tay', 'tsx', 'txa', 'txs', 'tya',
+ ),
+ /* Index Registers, yes the 6502 has other registers by they are only
+ * accessable by specific opcodes. The 65816 also has access to the stack pointer S. */
+ 2 => array(
+ 'x', 'y', 's'
+ ),
+ /* Directives. */
+ 3 => array(
+ '.al', '.align', '.as', '.assert', '.binary', '.byte', '.cerror', '.char',
+ '.comment', '.cpu', '.cwarn', '.databank', '.dpage', '.else', '.elsif',
+ '.enc', '.endc', '.endif', '.endm', '.endp', '.error', '.fi', '.fill',
+ '.for', '.here', '.if', '.ifeq', '.ifmi', '.ifne', '.ifpl',
+ '.include', '.int', '.logical', '.long', '.macro', '.next', '.null', '.offs',
+ '.page', '.pend', '.proc', '.rept', '.rta', '.shift', '.text', '.warn', '.word',
+ '.xl', '.xs',
+// , '*=' // Not a valid keyword (uses both * and = signs) moved to symbols instead.
+ ),
+
+ /* 6502/6510 undocumented opcodes (often referred to as illegal instructions).
+ * These are present in the 6502/6510 but NOT in the newer CMOS revisions of the 65C02 or 65816.
+ * As they are undocumented instructions there are no "official" names for them, these are the names
+ * used by 64TASS V1.46.
+ */
+ 4 => array(
+ 'ahx', 'alr', 'anc', 'ane', 'arr', 'asr', 'axs', 'dcm',
+ 'dcp', 'ins', 'isb', 'isc', 'jam', 'lae', 'las', 'lax',
+ 'lds', 'lxa', 'rla', 'rra', 'sax', 'sbx', 'sha', 'shs',
+ 'shx', 'shy', 'slo', 'sre', 'tas', 'xaa',
+ ),
+ /* 65c02 instructions, MOS added a few (much needed) instructions in the
+ * CMOS version of the 6502, but stupidly removed the undocumented/illegal opcodes. */
+ 5 => array(
+ 'bra', 'dea', 'gra', 'ina', 'phx', 'phy', 'plx', 'ply',
+ 'stz', 'trb', 'tsb',
+ ),
+ /* 65816 instructions. */
+ 6 => array(
+ 'brl', 'cop', 'jml', 'jsl', 'mvn', 'mvp', 'pea', 'pei',
+ 'per', 'phb', 'phd', 'phk', 'plb', 'pld', 'rep', 'rtl',
+ 'sep', 'stp', 'swa', 'tad', 'tcd', 'tcs', 'tda',
+ 'tdc', 'tsa', 'tsc', 'txy', 'tyx', 'wai', 'xba', 'xce',
+ ),
+ /* Deprecated directives (or yet to be implemented). */
+ 7 => array(
+ '.global', '.check'
+ ),
+ ),
+ 'SYMBOLS' => array(
+// '[', ']', '(', ')', '{', '}', // These are already defined by GeSHi as BRACKETS.
+ '*=', '#', '<', '>', '`', '=', '<', '>',
+ '!=', '>=', '<=', '+', '-', '*', '/', '//', '|',
+ '^', '&', '<<', '>>', '-', '~', '!',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00f; font-weight:bold;',
+ 2 => 'color: #00f; font-weight:bold;',
+ 3 => 'color: #080; font-weight:bold;',
+ 4 => 'color: #f00; font-weight:bold;',
+ 5 => 'color: #80f; font-weight:bold;',
+ 6 => 'color: #f08; font-weight:bold;',
+ 7 => 'color: #a04; font-weight:bold; font-style: italic;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #999; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #009; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'NUMBERS' => array(
+ GESHI_NUMBER_INT_BASIC => 'color: #f00;',
+ GESHI_NUMBER_HEX_PREFIX_DOLLAR => 'color: #f00;',
+ GESHI_NUMBER_BIN_PREFIX_PERCENT => 'color: #f00;',
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_HEX_PREFIX_DOLLAR |
+ GESHI_NUMBER_BIN_PREFIX_PERCENT,
+ // AMCE Octal format not support and gets picked up as Decimal unfortunately.
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 8,
+ 'PARSER_CONTROL' => array(
+ 'NUMBERS' => array(
+ 'PRECHECK_RX' => '/[\da-fA-F\.\$\%]/'
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/68000devpac.php b/platform/www/vendor/geshi/geshi/src/geshi/68000devpac.php
new file mode 100644
index 0000000..db5c85b
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/68000devpac.php
@@ -0,0 +1,166 @@
+<?php
+/*************************************************************************************
+ * 68000devpac.php
+ * -------
+ * Author: Warren Willmey
+ * Copyright: (c) 2010 Warren Willmey.
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/06/09
+ *
+ * Motorola 68000 - HiSoft Devpac ST 2 Assembler language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/07/22
+ * - First Release
+ *
+ * TODO (updated 2010/07/22)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Motorola 68000 - HiSoft Devpac ST 2 Assembler format',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /* Directives. */
+ 1 => array(
+ 'end', 'include', 'incbin', 'opt', 'even', 'cnop', 'dc.b', 'dc.w',
+ 'dc.l', 'ds.b', 'ds.w', 'ds.l', 'dcb.b', 'dcb.w', 'dcb.l',
+ 'fail', 'output', '__g2', 'rept', 'endr', 'list', 'nolist', 'plen',
+ 'llen', 'ttl', 'subttl', 'spc', 'page', 'listchar', 'format',
+ 'equ', 'equr', 'set', 'reg', 'rs.b', 'rs.w', 'rs.l', 'rsreset',
+ 'rsset', '__rs', 'ifeq', 'ifne', 'ifgt', 'ifge', 'iflt', 'ifle', 'endc',
+ 'ifd', 'ifnd', 'ifc', 'ifnc', 'elseif', 'iif', 'macro', 'endm', 'mexit',
+ 'narg', '\@', 'section', 'text', 'data', 'bss', 'xdef', 'xref', 'org',
+ 'offset', '__lk', 'comment',
+ ),
+ /* 68000 Opcodes. */
+ 2 => array(
+ 'abcd', 'add', 'adda', 'addi', 'addq', 'addx', 'and', 'andi',
+ 'asl', 'asr', 'bcc', 'bchg', 'bclr', 'bcs', 'beq', 'bge',
+ 'bgt', 'bhi', 'ble', 'bls', 'blt', 'bmi', 'bne', 'bpl',
+ 'bra', 'bset', 'bsr', 'btst', 'bvc', 'bvs', 'chk', 'clr',
+ 'cmp', 'cmpa', 'cmpi', 'cmpm', 'dbcc', 'dbcs', 'dbeq', 'dbf',
+ 'dbge', 'dbgt', 'dbhi', 'dble', 'dbls', 'dblt', 'dbmi', 'dbne',
+ 'dbpl', 'dbra', 'dbt', 'dbvc', 'dbvs', 'divs', 'divu', 'eor',
+ 'eori', 'exg', 'ext','illegal','jmp', 'jsr', 'lea', 'link',
+ 'lsl', 'lsr', 'move','movea','movem','movep','moveq', 'muls',
+ 'mulu', 'nbcd', 'neg', 'negx', 'nop', 'not', 'or', 'ori',
+ 'pea', 'reset', 'rol', 'ror', 'roxl', 'roxr', 'rte', 'rtr',
+ 'rts', 'sbcd', 'scc', 'scs', 'seq', 'sf', 'sge', 'sgt',
+ 'shi', 'sle', 'sls', 'slt', 'smi', 'sne', 'spl', 'st',
+ 'stop', 'sub', 'suba', 'subi', 'subq', 'subx', 'svc', 'svs',
+ 'swap', 'tas', 'trap','trapv', 'tst', 'unlk',
+ ),
+ /* oprand sizes. */
+ 3 => array(
+ 'b', 'w', 'l' , 's'
+ ),
+ /* 68000 Registers. */
+ 4 => array(
+ 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7',
+ 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'sp', 'usp', 'ssp',
+ 'pc', 'ccr', 'sr',
+ ),
+ ),
+ 'SYMBOLS' => array(
+// '[', ']', '(', ')', '{', '}', // These are already defined by GeSHi as BRACKETS.
+ '+', '-', '~', '<<', '>>', '&',
+ '!', '^', '*', '/', '=', '<', '>',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #f08; font-weight:bold;',
+ 2 => 'color: #00f; font-weight:bold;',
+ 3 => 'color: #00f; font-weight:bold;',
+ 4 => 'color: #080; font-weight:bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #999; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #009; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'NUMBERS' => array(
+ GESHI_NUMBER_INT_BASIC => 'color: #f00;',
+ GESHI_NUMBER_HEX_PREFIX_DOLLAR => 'color: #f00;',
+ GESHI_NUMBER_BIN_PREFIX_PERCENT => 'color: #f00;',
+ GESHI_NUMBER_OCT_PREFIX_AT => 'color: #f00;',
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #933;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_HEX_PREFIX_DOLLAR |
+ GESHI_NUMBER_OCT_PREFIX_AT |
+ GESHI_NUMBER_BIN_PREFIX_PERCENT,
+ 'REGEXPS' => array(
+ //Labels may end in a colon.
+ 0 => '(?<=\A\x20|\r|\n|^)[\._a-zA-Z][\._a-zA-Z0-9]*[\:]?[\s]'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 8,
+ 'PARSER_CONTROL' => array(
+ 'NUMBERS' => array(
+ 'PRECHECK_RX' => '/[\da-fA-F\.\$\%\@]/'
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/abap.php b/platform/www/vendor/geshi/geshi/src/geshi/abap.php
new file mode 100644
index 0000000..99536f0
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/abap.php
@@ -0,0 +1,1407 @@
+<?php
+/*************************************************************************************
+ * abap.php
+ * --------
+ * Author: Andres Picazo (andres@andrespicazo.com)
+ * Contributors:
+ * - Sandra Rossi (sandra.rossi@gmail.com)
+ * - Jacob Laursen (jlu@kmd.dk)
+ * Copyright: (c) 2007 Andres Picazo
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/04
+ *
+ * ABAP language file for GeSHi.
+ *
+ * Reference abap language documentation (abap 7.1) : http://help.sap.com/abapdocu/en/ABENABAP_INDEX.htm
+ *
+ * ABAP syntax is highly complex, several problems could not be addressed, see TODO below if you dare ;-)
+ * Be aware that in ABAP language, keywords may be composed of several tokens,
+ * separated by one or more spaces or carriage returns
+ * (for example CONCATENATE 'hello' 'world' INTO string SEPARATED BY ' ')
+ * it's why we must decode them with REGEXPS. As there are many keywords with several tokens,
+ * I had to create a separate section in the code to simplify the reading.
+ * Be aware that some words may be highlighted several times like for "ref to data", which is first
+ * highlighted for "ref to data", then secondly for "ref to". It is very important to
+ * position "ref to" after "ref to data" otherwise "data" wouldn't be highlighted because
+ * of the previous highlight.
+ * Control, declarative and other statements are assigned URLs to sap documentation website:
+ * http://help.sap.com/abapdocu/en/ABAP<statement_name>.htm
+ *
+ * CHANGES
+ * -------
+ * 2009/02/25 (1.0.8.3)
+ * - Some more rework of the language file
+ * 2009/01/04 (1.0.8.2)
+ * - Major Release, more than 1000 statements and keywords added = whole abap 7.1 (Sandra Rossi)
+ * 2007/06/27 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * ----
+ * - in DATA data TYPE type, 2nd "data" and 2nd "type" are highlighted with data
+ * style, but should be ignored. Same problem for all words!!! This is quite impossible to
+ * solve it as we should define syntaxes of all statements (huge effort!) and use a lex
+ * or something like that instead of regexp I guess.
+ * - Some words are considered as being statement names (report, tables, etc.) though they
+ * are used as keyword in some statements. For example: FORM xxxx TABLES itab. It was
+ * arbitrary decided to define them as statement instead of keyword, because it may be
+ * useful to have the URL to SAP help for some of them.
+ * - if a comment is between 2 words of a keyword (for example SEPARATED "comment \n BY),
+ * it is not considered as a keyword, but it should!
+ * - for statements like "READ DATASET", GeSHi does not allow to set URLs because these
+ * statements are determined by REGEXPS. For "READ DATASET", the URL should be
+ * ABAPREAD_DATASET.htm. If a technical solution is found, be careful : URLs
+ * are sometimes not valid because the URL does not exist. For example, for "AT NEW"
+ * statement, the URL should be ABAPAT_ITAB.htm (not ABAPAT_NEW.htm).
+ * There are many other exceptions.
+ * Note: for adding this functionality within your php program, you can execute this code:
+ * function add_urls_to_multi_tokens( $matches ) {
+ * $url = preg_replace( "/[ \n]+/" , "_" , $matches[3] );
+ * if( $url == $matches[3] ) return $matches[0] ;
+ * else return $matches[1]."<a href=\"http://help.sap.com/abapdocu/en/ABAP".strtoupper($url).".htm\">".$matches[3]."</a>".$matches[4];
+ * }
+ * $html = $geshi->parse_code();
+ * $html = preg_replace_callback( "£(zzz:(control|statement|data);\">)(.+?)(</span>)£s", "add_urls_to_multi_tokens", $html );
+ * echo $html;
+ * - Numbers followed by a dot terminating the statement are not properly recognized
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'ABAP',
+ 'COMMENT_SINGLE' => array(
+ 1 => '"'
+ ),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ // lines beginning with star at 1st position are comments
+ // (star anywhere else is not a comment, especially be careful with
+ // "assign dref->* to <fs>" statement)
+ 2 => '/^\*.*?$/m'
+ ),
+ 'CASE_KEYWORDS' => 0,
+ 'QUOTEMARKS' => array(
+ 1 => "'",
+ 2 => "`"
+ ),
+ 'ESCAPE_CHAR' => '',
+
+ 'KEYWORDS' => array(
+ //***********************************************
+ // Section 2 : process sequences of several tokens
+ //***********************************************
+
+ 7 => array(
+ 'at new',
+ 'at end of',
+ 'at first',
+ 'at last',
+ 'loop at',
+ 'loop at screen',
+ ),
+
+ 8 => array(
+ 'private section',
+ 'protected section',
+ 'public section',
+ 'at line-selection',
+ 'at selection-screen',
+ 'at user-command',
+ 'assign component',
+ 'assign table field',
+ 'call badi',
+ 'call customer-function',
+ 'call customer subscreen',
+ 'call dialog',
+ 'call function',
+ 'call method',
+ 'call screen',
+ 'call selection-screen',
+ 'call transaction',
+ 'call transformation',
+ 'close cursor',
+ 'close dataset',
+ 'commit work',
+ 'convert date',
+ 'convert text',
+ 'convert time stamp',
+ 'create data',
+ 'create object',
+ 'delete dataset',
+ 'delete from',
+ 'describe distance',
+ 'describe field',
+ 'describe list',
+ 'describe table',
+ 'exec sql',
+ 'exit from sql',
+ 'exit from step-loop',
+ 'export dynpro',
+ 'export nametab',
+ 'free memory',
+ 'generate subroutine-pool',
+ 'get badi',
+ 'get bit',
+ 'get cursor',
+ 'get dataset',
+ 'get locale',
+ 'get parameter',
+ 'get pf-status',
+ 'get property',
+ 'get reference',
+ 'get run time',
+ 'get time',
+ 'get time stamp',
+ 'import directory',
+ 'insert report',
+ 'insert text-pool',
+ 'leave list-processing',
+ 'leave program',
+ 'leave screen',
+ 'leave to list-processing',
+ 'leave to transaction',
+ 'modify line',
+ 'modify screen',
+ 'move percentage',
+ 'open cursor',
+ 'open dataset',
+ 'raise event',
+ 'raise exception',
+ 'read dataset',
+ 'read line',
+ 'read report',
+ 'read table',
+ 'read textpool',
+ 'receive results from function',
+ 'refresh control',
+ 'rollback work',
+ 'set bit',
+ 'set blank lines',
+ 'set country',
+ 'set cursor',
+ 'set dataset',
+ 'set extended check',
+ 'set handler',
+ 'set hold data',
+ 'set language',
+ 'set left scroll-boundary',
+ 'set locale',
+ 'set margin',
+ 'set parameter',
+ 'set pf-status',
+ 'set property',
+ 'set run time analyzer',
+ 'set run time clock',
+ 'set screen',
+ 'set titlebar',
+ 'set update task',
+ 'set user-command',
+ 'suppress dialog',
+ 'truncate dataset',
+ 'wait until',
+ 'wait up to',
+ ),
+
+ 9 => array(
+ 'accepting duplicate keys',
+ 'accepting padding',
+ 'accepting truncation',
+ 'according to',
+ 'actual length',
+ 'adjacent duplicates',
+ 'after input',
+ 'all blob columns',
+ 'all clob columns',
+ 'all fields',
+ 'all methods',
+ 'all other columns',
+ 'and mark',
+ 'and return to screen',
+ 'and return',
+ 'and skip first screen',
+ 'and wait',
+ 'any table',
+ 'appendage type',
+ 'archive mode',
+ 'archiving parameters',
+ 'area handle',
+ 'as checkbox',
+ 'as icon',
+ 'as line',
+ 'as listbox',
+ 'as person table',
+ 'as search patterns',
+ 'as separate unit',
+ 'as subscreen',
+ 'as symbol',
+ 'as text',
+ 'as window',
+ 'at cursor-selection',
+ 'at exit-command',
+ 'at next application statement',
+ 'at position',
+
+ 'backup into',
+ 'before output',
+ 'before unwind',
+ 'begin of block',
+ 'begin of common part',
+ 'begin of line',
+ 'begin of screen',
+ 'begin of tabbed block',
+ 'begin of version',
+ 'begin of',
+ 'big endian',
+ 'binary mode',
+ 'binary search',
+ 'by kernel module',
+ 'bypassing buffer',
+
+ 'client specified',
+ 'code page',
+ 'code page hint',
+ 'code page into',
+ 'color black',
+ 'color blue',
+ 'color green',
+ 'color pink',
+ 'color red',
+ 'color yellow',
+ 'compression off',
+ 'compression on',
+ 'connect to',
+ 'corresponding fields of table',
+ 'corresponding fields of',
+ 'cover page',
+ 'cover text',
+ 'create package',
+ 'create private',
+ 'create protected',
+ 'create public',
+ 'current position',
+
+ 'data buffer',
+ 'data values',
+ 'dataset expiration',
+ 'daylight saving time',
+ 'default key',
+ 'default program',
+ 'default screen',
+ 'defining database',
+ 'deleting leading',
+ 'deleting trailing',
+ 'directory entry',
+ 'display like',
+ 'display offset',
+ 'during line-selection',
+ 'dynamic selections',
+
+ 'edit mask',
+ 'end of block',
+ 'end of common part',
+ 'end of file',
+ 'end of line',
+ 'end of screen',
+ 'end of tabbed block',
+ 'end of version',
+ 'end of',
+ 'endian into',
+ 'ending at',
+ 'enhancement options into',
+ 'enhancement into',
+ 'environment time format',
+ 'execute procedure',
+ 'exporting list to memory',
+ 'extension type',
+
+ 'field format',
+ 'field selection',
+ 'field value into',
+ 'final methods',
+ 'first occurrence of',
+ 'fixed-point arithmetic',
+ 'for all entries',
+ 'for all instances',
+ 'for appending',
+ 'for columns',
+ 'for event of',
+ 'for field',
+ 'for high',
+ 'for input',
+ 'for lines',
+ 'for low',
+ 'for node',
+ 'for output',
+ 'for select',
+ 'for table',
+ 'for testing',
+ 'for update',
+ 'for user',
+ 'frame entry',
+ 'frame program from',
+ 'from code page',
+ 'from context',
+ 'from database',
+ 'from logfile id',
+ 'from number format',
+ 'from screen',
+ 'from table',
+ 'function key',
+
+ 'get connection',
+ 'global friends',
+ 'group by',
+
+ 'hashed table of',
+ 'hashed table',
+
+ 'if found',
+ 'ignoring case',
+ 'ignoring conversion errors',
+ 'ignoring structure boundaries',
+ 'implementations from',
+ 'in background',
+ 'in background task',
+ 'in background unit',
+ 'in binary mode',
+ 'in byte mode',
+ 'in char-to-hex mode',
+ 'in character mode',
+ 'in group',
+ 'in legacy binary mode',
+ 'in legacy text mode',
+ 'in program',
+ 'in remote task',
+ 'in text mode',
+ 'in table',
+ 'in update task',
+ 'include bound',
+ 'include into',
+ 'include program from',
+ 'include structure',
+ 'include type',
+ 'including gaps',
+ 'index table',
+ 'inheriting from',
+ 'init destination',
+ 'initial line of',
+ 'initial line',
+ 'initial size',
+ 'internal table',
+ 'into sortable code',
+
+ 'keep in spool',
+ 'keeping directory entry',
+ 'keeping logical unit of work',
+ 'keeping task',
+ 'keywords from',
+
+ 'left margin',
+ 'left outer',
+ 'levels into',
+ 'line format',
+ 'line into',
+ 'line of',
+ 'line page',
+ 'line value from',
+ 'line value into',
+ 'lines of',
+ 'list authority',
+ 'list dataset',
+ 'list name',
+ 'little endian',
+ 'lob handle for',
+ 'local friends',
+ 'locator for',
+ 'lower case',
+
+ 'main table field',
+ 'match count',
+ 'match length',
+ 'match line',
+ 'match offset',
+ 'matchcode object',
+ 'maximum length',
+ 'maximum width into',
+ 'memory id',
+ 'message into',
+ 'messages into',
+ 'modif id',
+
+ 'nesting level',
+ 'new list identification',
+ 'next cursor',
+ 'no database selection',
+ 'no dialog',
+ 'no end of line',
+ 'no fields',
+ 'no flush',
+ 'no intervals',
+ 'no intervals off',
+ 'no standard page heading',
+ 'no-extension off',
+ 'non-unique key',
+ 'non-unique sorted key',
+ 'not at end of mode',
+ 'number of lines',
+ 'number of pages',
+
+ 'object key',
+ 'obligatory off',
+ 'of current page',
+ 'of page',
+ 'of program',
+ 'offset into',
+ 'on block',
+ 'on commit',
+ 'on end of task',
+ 'on end of',
+ 'on exit-command',
+ 'on help-request for',
+ 'on radiobutton group',
+ 'on rollback',
+ 'on value-request for',
+ 'open for package',
+ 'option class-coding',
+ 'option class',
+ 'option coding',
+ 'option expand',
+ 'option syncpoints',
+ 'options from',
+ 'order by',
+ 'overflow into',
+
+ 'package section',
+ 'package size',
+ 'preferred parameter',
+ 'preserving identifier escaping',
+ 'primary key',
+ 'print off',
+ 'print on',
+ 'program from',
+ 'program type',
+
+ 'radiobutton groups',
+ 'radiobutton group',
+ 'range of',
+ 'reader for',
+ 'receive buffer',
+ 'reduced functionality',
+ 'ref to data',
+ 'ref to object',
+ 'ref to',
+
+ 'reference into',
+ 'renaming with suffix',
+ 'replacement character',
+ 'replacement count',
+ 'replacement length',
+ 'replacement line',
+ 'replacement offset',
+ 'respecting blanks',
+ 'respecting case',
+ 'result into',
+ 'risk level',
+
+ 'sap cover page',
+ 'search fkeq',
+ 'search fkge',
+ 'search gkeq',
+ 'search gkge',
+ 'section of',
+ 'send buffer',
+ 'separated by',
+ 'shared buffer',
+ 'shared memory',
+ 'shared memory enabled',
+ 'skipping byte-order mark',
+ 'sorted by',
+ 'sorted table of',
+ 'sorted table',
+ 'spool parameters',
+ 'standard table of',
+ 'standard table',
+ 'starting at',
+ 'starting new task',
+ 'statements into',
+ 'structure default',
+ 'structures into',
+
+ 'table field',
+ 'table of',
+ 'text mode',
+ 'time stamp',
+ 'time zone',
+ 'to code page',
+ 'to column',
+ 'to context',
+ 'to first page',
+ 'to last page',
+ 'to last line',
+ 'to line',
+ 'to lower case',
+ 'to number format',
+ 'to page',
+ 'to sap spool',
+ 'to upper case',
+ 'tokens into',
+ 'transporting no fields',
+ 'type tableview',
+ 'type tabstrip',
+
+ 'unicode enabling',
+ 'up to',
+ 'upper case',
+ 'using edit mask',
+ 'using key',
+ 'using no edit mask',
+ 'using screen',
+ 'using selection-screen',
+ 'using selection-set',
+ 'using selection-sets of program',
+
+ 'valid between',
+ 'valid from',
+ 'value check',
+ 'via job',
+ 'via selection-screen',
+ 'visible length',
+
+ 'whenever found',
+ 'with analysis',
+ 'with byte-order mark',
+ 'with comments',
+ 'with current switchstates',
+ 'with explicit enhancements',
+ 'with frame',
+ 'with free selections',
+ 'with further secondary keys',
+ 'with header line',
+ 'with hold',
+ 'with implicit enhancements',
+ 'with inactive enhancements',
+ 'with includes',
+ 'with key',
+ 'with linefeed',
+ 'with list tokenization',
+ 'with native linefeed',
+ 'with non-unique key',
+ 'with null',
+ 'with pragmas',
+ 'with precompiled headers',
+ 'with selection-table',
+ 'with smart linefeed',
+ 'with table key',
+ 'with test code',
+ 'with type-pools',
+ 'with unique key',
+ 'with unix linefeed',
+ 'with windows linefeed',
+ 'without further secondary keys',
+ 'without selection-screen',
+ 'without spool dynpro',
+ 'without trmac',
+ 'word into',
+ 'writer for'
+ ),
+
+ //**********************************************************
+ // Other abap statements
+ //**********************************************************
+ 3 => array(
+ 'add',
+ 'add-corresponding',
+ 'aliases',
+ 'append',
+ 'assign',
+ 'at',
+ 'authority-check',
+
+ 'break-point',
+
+ 'clear',
+ 'collect',
+ 'compute',
+ 'concatenate',
+ 'condense',
+ 'class',
+ 'class-events',
+ 'class-methods',
+ 'class-pool',
+
+ 'define',
+ 'delete',
+ 'demand',
+ 'detail',
+ 'divide',
+ 'divide-corresponding',
+
+ 'editor-call',
+ 'end-of-file',
+ 'end-enhancement-section',
+ 'end-of-definition',
+ 'end-of-page',
+ 'end-of-selection',
+ 'endclass',
+ 'endenhancement',
+ 'endexec',
+ 'endform',
+ 'endfunction',
+ 'endinterface',
+ 'endmethod',
+ 'endmodule',
+ 'endon',
+ 'endprovide',
+ 'endselect',
+ 'enhancement',
+ 'enhancement-point',
+ 'enhancement-section',
+ 'export',
+ 'extract',
+ 'events',
+
+ 'fetch',
+ 'field-groups',
+ 'find',
+ 'format',
+ 'form',
+ 'free',
+ 'function-pool',
+ 'function',
+
+ 'get',
+
+ 'hide',
+
+ 'import',
+ 'infotypes',
+ 'input',
+ 'insert',
+ 'include',
+ 'initialization',
+ 'interface',
+ 'interface-pool',
+ 'interfaces',
+
+ 'leave',
+ 'load-of-program',
+ 'log-point',
+
+ 'maximum',
+ 'message',
+ 'methods',
+ 'method',
+ 'minimum',
+ 'modify',
+ 'move',
+ 'move-corresponding',
+ 'multiply',
+ 'multiply-corresponding',
+
+ 'new-line',
+ 'new-page',
+ 'new-section',
+
+ 'overlay',
+
+ 'pack',
+ 'perform',
+ 'position',
+ 'print-control',
+ 'program',
+ 'provide',
+ 'put',
+
+ 'raise',
+ 'refresh',
+ 'reject',
+ 'replace',
+ 'report',
+ 'reserve',
+
+ 'scroll',
+ 'search',
+ 'select',
+ 'selection-screen',
+ 'shift',
+ 'skip',
+ 'sort',
+ 'split',
+ 'start-of-selection',
+ 'submit',
+ 'subtract',
+ 'subtract-corresponding',
+ 'sum',
+ 'summary',
+ 'summing',
+ 'supply',
+ 'syntax-check',
+
+ 'top-of-page',
+ 'transfer',
+ 'translate',
+ 'type-pool',
+
+ 'uline',
+ 'unpack',
+ 'update',
+
+ 'window',
+ 'write'
+
+ ),
+
+ //**********************************************************
+ // keywords
+ //**********************************************************
+
+ 4 => array(
+ 'abbreviated',
+ 'abstract',
+ 'accept',
+ 'acos',
+ 'activation',
+ 'alias',
+ 'align',
+ 'all',
+ 'allocate',
+ 'and',
+ 'assigned',
+ 'any',
+ 'appending',
+ 'area',
+ 'as',
+ 'ascending',
+ 'asin',
+ 'assigning',
+ 'atan',
+ 'attributes',
+ 'avg',
+
+ 'backward',
+ 'between',
+ 'bit-and',
+ 'bit-not',
+ 'bit-or',
+ 'bit-set',
+ 'bit-xor',
+ 'boolc',
+ 'boolx',
+ 'bound',
+ 'bt',
+ 'blocks',
+ 'bounds',
+ 'boxed',
+ 'by',
+ 'byte-ca',
+ 'byte-cn',
+ 'byte-co',
+ 'byte-cs',
+ 'byte-na',
+ 'byte-ns',
+
+ 'ca',
+ 'calling',
+ 'casting',
+ 'ceil',
+ 'center',
+ 'centered',
+ 'changing',
+ 'char_off',
+ 'charlen',
+ 'circular',
+ 'class_constructor',
+ 'client',
+ 'clike',
+ 'close',
+ 'cmax',
+ 'cmin',
+ 'cn',
+ 'cnt',
+ 'co',
+ 'col_background',
+ 'col_group',
+ 'col_heading',
+ 'col_key',
+ 'col_negative',
+ 'col_normal',
+ 'col_positive',
+ 'col_total',
+ 'color',
+ 'column',
+ 'comment',
+ 'comparing',
+ 'components',
+ 'condition',
+ 'context',
+ 'copies',
+ 'count',
+ 'country',
+ 'cpi',
+ 'creating',
+ 'critical',
+ 'concat_lines_of',
+ 'cos',
+ 'cosh',
+ 'count_any_not_of',
+ 'count_any_of',
+ 'cp',
+ 'cs',
+ 'csequence',
+ 'currency',
+ 'current',
+ 'cx_static_check',
+ 'cx_root',
+ 'cx_dynamic_check',
+
+ 'dangerous',
+ 'database',
+ 'datainfo',
+ 'date',
+ 'dbmaxlen',
+ 'dd/mm/yy',
+ 'dd/mm/yyyy',
+ 'ddmmyy',
+ 'deallocate',
+ 'decfloat',
+ 'decfloat16',
+ 'decfloat34',
+ 'decimals',
+ 'default',
+ 'deferred',
+ 'definition',
+ 'department',
+ 'descending',
+ 'destination',
+ 'disconnect',
+ 'display-mode',
+ 'distance',
+ 'distinct',
+ 'div',
+ 'dummy',
+
+ 'encoding',
+ 'end-lines',
+ 'engineering',
+ 'environment',
+ 'eq',
+ 'equiv',
+ 'error_message',
+ 'errormessage',
+ 'escape',
+ 'exact',
+ 'exception-table',
+ 'exceptions',
+ 'exclude',
+ 'excluding',
+ 'exists',
+ 'exp',
+ 'exponent',
+ 'exporting',
+ 'extended_monetary',
+
+ 'field',
+ 'filter-table',
+ 'filters',
+ 'filter',
+ 'final',
+ 'find_any_not_of',
+ 'find_any_of',
+ 'find_end',
+ 'floor',
+ 'first-line',
+ 'font',
+ 'forward',
+ 'for',
+ 'frac',
+ 'from_mixed',
+ 'friends',
+ 'from',
+
+ 'giving',
+ 'ge',
+ 'gt',
+
+ 'handle',
+ 'harmless',
+ 'having',
+ 'head-lines',
+ 'help-id',
+ 'help-request',
+ 'high',
+ 'hold',
+ 'hotspot',
+
+ 'id',
+ 'ids',
+ 'immediately',
+ 'implementation',
+ 'importing',
+ 'in',
+ 'initial',
+ 'incl',
+ 'including',
+ 'increment',
+ 'index',
+ 'index-line',
+ 'inner',
+ 'inout',
+ 'intensified',
+ 'into',
+ 'inverse',
+ 'is',
+ 'iso',
+
+ 'join',
+
+ 'key',
+ 'kind',
+
+ 'log10',
+ 'language',
+ 'late',
+ 'layout',
+ 'le',
+ 'lt',
+ 'left-justified',
+ 'leftplus',
+ 'leftspace',
+ 'left',
+ 'length',
+ 'level',
+ 'like',
+ 'line-count',
+ 'line-size',
+ 'lines',
+ 'line',
+ 'load',
+ 'long',
+ 'lower',
+ 'low',
+ 'lpi',
+
+ 'matches',
+ 'match',
+ 'mail',
+ 'major-id',
+ 'max',
+ 'medium',
+ 'memory',
+ 'message-id',
+ 'module',
+ 'minor-id',
+ 'min',
+ 'mm/dd/yyyy',
+ 'mm/dd/yy',
+ 'mmddyy',
+ 'mode',
+ 'modifier',
+ 'mod',
+ 'monetary',
+
+ 'name',
+ 'nb',
+ 'ne',
+ 'next',
+ 'no-display',
+ 'no-extension',
+ 'no-gap',
+ 'no-gaps',
+ 'no-grouping',
+ 'no-heading',
+ 'no-scrolling',
+ 'no-sign',
+ 'no-title',
+ 'no-topofpage',
+ 'no-zero',
+ 'nodes',
+ 'non-unicode',
+ 'no',
+ 'number',
+ 'nmax',
+ 'nmin',
+ 'not',
+ 'null',
+ 'numeric',
+ 'numofchar',
+
+ 'o',
+ 'objects',
+ 'obligatory',
+ 'occurs',
+ 'offset',
+ 'off',
+ 'of',
+ 'only',
+ 'open',
+ 'option',
+ 'optional',
+ 'options',
+ 'output-length',
+ 'output',
+ 'out',
+ 'on change of',
+ 'or',
+ 'others',
+
+ 'pad',
+ 'page',
+ 'pages',
+ 'parameter-table',
+ 'part',
+ 'performing',
+ 'pos_high',
+ 'pos_low',
+ 'priority',
+ 'public',
+ 'pushbutton',
+
+ 'queue-only',
+ 'quickinfo',
+
+ 'raising',
+ 'range',
+ 'read-only',
+ 'received',
+ 'receiver',
+ 'receiving',
+ 'redefinition',
+ 'reference',
+ 'regex',
+ 'replacing',
+ 'reset',
+ 'responsible',
+ 'result',
+ 'results',
+ 'resumable',
+ 'returncode',
+ 'returning',
+ 'right',
+ 'right-specified',
+ 'rightplus',
+ 'rightspace',
+ 'round',
+ 'rows',
+ 'repeat',
+ 'requested',
+ 'rescale',
+ 'reverse',
+
+ 'scale_preserving',
+ 'scale_preserving_scientific',
+ 'scientific',
+ 'scientific_with_leading_zero',
+ 'screen',
+ 'scrolling',
+ 'seconds',
+ 'segment',
+ 'shift_left',
+ 'shift_right',
+ 'sign',
+ 'simple',
+ 'sin',
+ 'sinh',
+ 'short',
+ 'shortdump-id',
+ 'sign_as_postfix',
+ 'single',
+ 'size',
+ 'some',
+ 'source',
+ 'space',
+ 'spots',
+ 'stable',
+ 'state',
+ 'static',
+ 'statusinfo',
+ 'sqrt',
+ 'string',
+ 'strlen',
+ 'structure',
+ 'style',
+ 'subkey',
+ 'submatches',
+ 'substring',
+ 'substring_after',
+ 'substring_before',
+ 'substring_from',
+ 'substring_to',
+ 'super',
+ 'supplied',
+ 'switch',
+
+ 'tan',
+ 'tanh',
+ 'table_line',
+ 'table',
+ 'tab',
+ 'then',
+ 'timestamp',
+ 'times',
+ 'time',
+ 'timezone',
+ 'title-lines',
+ 'title',
+ 'top-lines',
+ 'to',
+ 'to_lower',
+ 'to_mixed',
+ 'to_upper',
+ 'trace-file',
+ 'trace-table',
+ 'transporting',
+ 'trunc',
+ 'type',
+
+ 'under',
+ 'unique',
+ 'unit',
+ 'user-command',
+ 'using',
+ 'utf-8',
+
+ 'valid',
+ 'value',
+ 'value-request',
+ 'values',
+ 'vary',
+ 'varying',
+ 'version',
+
+ 'warning',
+ 'where',
+ 'width',
+ 'with',
+ 'word',
+ 'with-heading',
+ 'with-title',
+
+ 'xsequence',
+ 'xstring',
+ 'xstrlen',
+
+ 'yes',
+ 'yymmdd',
+
+ 'z',
+ 'zero'
+
+ ),
+
+ //**********************************************************
+ // screen statements
+ //**********************************************************
+
+ 5 => array(
+ 'call subscreen',
+ 'chain',
+ 'endchain',
+ 'on chain-input',
+ 'on chain-request',
+ 'on help-request',
+ 'on input',
+ 'on request',
+ 'on value-request',
+ 'process'
+ ),
+
+ //**********************************************************
+ // internal statements
+ //**********************************************************
+
+ 6 => array(
+ 'generate dynpro',
+ 'generate report',
+ 'import dynpro',
+ 'import nametab',
+ 'include methods',
+ 'load report',
+ 'scan abap-source',
+ 'scan and check abap-source',
+ 'syntax-check for dynpro',
+ 'syntax-check for program',
+ 'syntax-trace',
+ 'system-call',
+ 'system-exit',
+ 'verification-message'
+ ),
+
+ //**********************************************************
+ // Control statements
+ //**********************************************************
+
+ 1 => array(
+ 'assert',
+ 'case',
+ 'catch',
+ 'check',
+ 'cleanup',
+ 'continue',
+ 'do',
+ 'else',
+ 'elseif',
+ 'endat',
+ 'endcase',
+ 'endcatch',
+ 'endif',
+ 'enddo',
+ 'endloop',
+ 'endtry',
+ 'endwhile',
+ 'exit',
+ 'if',
+ 'loop',
+ 'resume',
+ 'retry',
+ 'return',
+ 'stop',
+ 'try',
+ 'when',
+ 'while'
+
+ ),
+
+ //**********************************************************
+ // variable declaration statements
+ //**********************************************************
+
+ 2 => array(
+ 'class-data',
+ 'controls',
+ 'constants',
+ 'data',
+ 'field-symbols',
+ 'fields',
+ 'local',
+ 'parameters',
+ 'ranges',
+ 'select-options',
+ 'statics',
+ 'tables',
+ 'type-pools',
+ 'types'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '->*', '->', '=>',
+ '(', ')', '{', '}', '[', ']', '+', '-', '*', '/', '!', '%', '^', '&', ':', ',', '.'
+ ),
+ 1 => array(
+ '>=', '<=', '<', '>', '='
+ ),
+ 2 => array(
+ '?='
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ 8 => false,
+ 9 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000066; font-weight: bold; zzz:control;', //control statements
+ 2 => 'color: #cc4050; font-weight: bold; zzz:data;', //data statements
+ 3 => 'color: #005066; font-weight: bold; zzz:statement;', //first token of other statements
+ 4 => 'color: #500066; font-weight: bold; zzz:keyword;', // next tokens of other statements ("keywords")
+ 5 => 'color: #005066; font-weight: bold; zzz:statement;',
+ 6 => 'color: #000066; font-weight: bold; zzz:control;',
+ 7 => 'color: #000066; font-weight: bold; zzz:control;',
+ 8 => 'color: #005066; font-weight: bold; zzz:statement;',
+ 9 => 'color: #500066; font-weight: bold; zzz:keyword;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #339933;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #808080;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #4da619;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #3399ff;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #808080;',
+ 1 => 'color: #800080;',
+ 2 => 'color: #0000ff;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://help.sap.com/abapdocu_740/en/ABAP{FNAMEU}.htm',
+ 2 => 'http://help.sap.com/abapdocu_740/en/ABAP{FNAMEU}.htm',
+ 3 => 'http://help.sap.com/abapdocu_740/en/ABAP{FNAMEU}.htm',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+ 9 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '-&gt;',
+ 2 => '=&gt;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 7 => array(
+ 'SPACE_AS_WHITESPACE' => true
+ ),
+ 8 => array(
+ 'SPACE_AS_WHITESPACE' => true
+ ),
+ 9 => array(
+ 'SPACE_AS_WHITESPACE' => true
+ )
+ )
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/actionscript.php b/platform/www/vendor/geshi/geshi/src/geshi/actionscript.php
new file mode 100644
index 0000000..d350a18
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/actionscript.php
@@ -0,0 +1,195 @@
+<?php
+/*************************************************************************************
+ * actionscript.php
+ * ----------------
+ * Author: Steffen Krause (Steffen.krause@muse.de)
+ * Copyright: (c) 2004 Steffen Krause, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/20
+ *
+ * Actionscript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ActionScript',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ '#include', 'for', 'foreach', 'each', 'if', 'elseif', 'else', 'while', 'do', 'dowhile',
+ 'endwhile', 'endif', 'switch', 'case', 'endswitch', 'return', 'break', 'continue', 'in'
+ ),
+ 2 => array(
+ 'null', 'false', 'true', 'var',
+ 'default', 'function', 'class',
+ 'new', '_global'
+ ),
+ 3 => array(
+ '#endinitclip', '#initclip', '__proto__', '_accProps', '_alpha', '_currentframe',
+ '_droptarget', '_focusrect', '_framesloaded', '_height', '_highquality', '_lockroot',
+ '_name', '_parent', '_quality', '_root', '_rotation', '_soundbuftime', '_target', '_totalframes',
+ '_url', '_visible', '_width', '_x', '_xmouse', '_xscale', '_y', '_ymouse', '_yscale', 'abs',
+ 'Accessibility', 'acos', 'activityLevel', 'add', 'addListener', 'addPage', 'addProperty',
+ 'addRequestHeader', 'align', 'allowDomain', 'allowInsecureDomain', 'and', 'appendChild',
+ 'apply', 'Arguments', 'Array', 'asfunction', 'asin', 'atan', 'atan2', 'attachAudio', 'attachMovie',
+ 'attachSound', 'attachVideo', 'attributes', 'autosize', 'avHardwareDisable', 'background',
+ 'backgroundColor', 'BACKSPACE', 'bandwidth', 'beginFill', 'beginGradientFill', 'blockIndent',
+ 'bold', 'Boolean', 'border', 'borderColor', 'bottomScroll', 'bufferLength', 'bufferTime',
+ 'builtInItems', 'bullet', 'Button', 'bytesLoaded', 'bytesTotal', 'call', 'callee', 'caller',
+ 'Camera', 'capabilities', 'CAPSLOCK', 'caption', 'catch', 'ceil', 'charAt', 'charCodeAt',
+ 'childNodes', 'chr', 'clear', 'clearInterval', 'cloneNode', 'close', 'Color', 'concat',
+ 'connect', 'condenseWhite', 'constructor', 'contentType', 'ContextMenu', 'ContextMenuItem',
+ 'CONTROL', 'copy', 'cos', 'createElement', 'createEmptyMovieClip', 'createTextField',
+ 'createTextNode', 'currentFps', 'curveTo', 'CustomActions', 'customItems', 'data', 'Date',
+ 'deblocking', 'delete', 'DELETEKEY', 'docTypeDecl', 'domain', 'DOWN',
+ 'duplicateMovieClip', 'duration', 'dynamic', 'E', 'embedFonts', 'enabled',
+ 'END', 'endFill', 'ENTER', 'eq', 'Error', 'ESCAPE(Konstante)', 'escape(Funktion)', 'eval',
+ 'exactSettings', 'exp', 'extends', 'finally', 'findText', 'firstChild', 'floor',
+ 'flush', 'focusEnabled', 'font', 'fps', 'fromCharCode', 'fscommand',
+ 'gain', 'ge', 'get', 'getAscii', 'getBeginIndex', 'getBounds', 'getBytesLoaded', 'getBytesTotal',
+ 'getCaretIndex', 'getCode', 'getCount', 'getDate', 'getDay', 'getDepth', 'getEndIndex', 'getFocus',
+ 'getFontList', 'getFullYear', 'getHours', 'getInstanceAtDepth', 'getLocal', 'getMilliseconds',
+ 'getMinutes', 'getMonth', 'getNewTextFormat', 'getNextHighestDepth', 'getPan', 'getProgress',
+ 'getProperty', 'getRGB', 'getSeconds', 'getSelected', 'getSelectedText', 'getSize', 'getStyle',
+ 'getStyleNames', 'getSWFVersion', 'getText', 'getTextExtent', 'getTextFormat', 'getTextSnapshot',
+ 'getTime', 'getTimer', 'getTimezoneOffset', 'getTransform', 'getURL', 'getUTCDate', 'getUTCDay',
+ 'getUTCFullYear', 'getUTCHours', 'getUTCMilliseconds', 'getUTCMinutes', 'getUTCMonth', 'getUTCSeconds',
+ 'getVersion', 'getVolume', 'getYear', 'globalToLocal', 'goto', 'gotoAndPlay', 'gotoAndStop',
+ 'hasAccessibility', 'hasAudio', 'hasAudioEncoder', 'hasChildNodes', 'hasEmbeddedVideo', 'hasMP3',
+ 'hasPrinting', 'hasScreenBroadcast', 'hasScreenPlayback', 'hasStreamingAudio', 'hasStreamingVideo',
+ 'hasVideoEncoder', 'height', 'hide', 'hideBuiltInItems', 'hitArea', 'hitTest', 'hitTestTextNearPos',
+ 'HOME', 'hscroll', 'html', 'htmlText', 'ID3', 'ifFrameLoaded', 'ignoreWhite', 'implements',
+ 'import', 'indent', 'index', 'indexOf', 'Infinity', '-Infinity', 'INSERT', 'insertBefore', 'install',
+ 'instanceof', 'int', 'interface', 'isActive', 'isDebugger', 'isDown', 'isFinite', 'isNaN', 'isToggled',
+ 'italic', 'join', 'Key', 'language', 'lastChild', 'lastIndexOf', 'le', 'leading', 'LEFT', 'leftMargin',
+ 'length', 'level', 'lineStyle', 'lineTo', 'list', 'LN10', 'LN2', 'load', 'loadClip', 'loaded', 'loadMovie',
+ 'loadMovieNum', 'loadSound', 'loadVariables', 'loadVariablesNum', 'LoadVars', 'LocalConnection',
+ 'localFileReadDisable', 'localToGlobal', 'log', 'LOG10E', 'LOG2E', 'manufacturer', 'Math', 'max',
+ 'MAX_VALUE', 'maxChars', 'maxhscroll', 'maxscroll', 'mbchr', 'mblength', 'mbord', 'mbsubstring', 'menu',
+ 'message', 'Microphone', 'min', 'MIN_VALUE', 'MMExecute', 'motionLevel', 'motionTimeOut', 'Mouse',
+ 'mouseWheelEnabled', 'moveTo', 'Movieclip', 'MovieClipLoader', 'multiline', 'muted', 'name', 'names', 'NaN',
+ 'ne', 'NEGATIVE_INFINITY', 'NetConnection', 'NetStream', 'newline', 'nextFrame',
+ 'nextScene', 'nextSibling', 'nodeName', 'nodeType', 'nodeValue', 'not', 'Number', 'Object',
+ 'on', 'onActivity', 'onChanged', 'onClipEvent', 'onClose', 'onConnect', 'onData', 'onDragOut',
+ 'onDragOver', 'onEnterFrame', 'onID3', 'onKeyDown', 'onKeyUp', 'onKillFocus', 'onLoad', 'onLoadComplete',
+ 'onLoadError', 'onLoadInit', 'onLoadProgress', 'onLoadStart', 'onMouseDown', 'onMouseMove', 'onMouseUp',
+ 'onMouseWheel', 'onPress', 'onRelease', 'onReleaseOutside', 'onResize', 'onRollOut', 'onRollOver',
+ 'onScroller', 'onSelect', 'onSetFocus', 'onSoundComplete', 'onStatus', 'onUnload', 'onUpdate', 'onXML',
+ 'or(logischesOR)', 'ord', 'os', 'parentNode', 'parseCSS', 'parseFloat', 'parseInt', 'parseXML', 'password',
+ 'pause', 'PGDN', 'PGUP', 'PI', 'pixelAspectRatio', 'play', 'playerType', 'pop', 'position',
+ 'POSITIVE_INFINITY', 'pow', 'prevFrame', 'previousSibling', 'prevScene', 'print', 'printAsBitmap',
+ 'printAsBitmapNum', 'PrintJob', 'printNum', 'private', 'prototype', 'public', 'push', 'quality',
+ 'random', 'rate', 'registerClass', 'removeListener', 'removeMovieClip', 'removeNode', 'removeTextField',
+ 'replaceSel', 'replaceText', 'resolutionX', 'resolutionY', 'restrict', 'reverse', 'RIGHT',
+ 'rightMargin', 'round', 'scaleMode', 'screenColor', 'screenDPI', 'screenResolutionX', 'screenResolutionY',
+ 'scroll', 'seek', 'selectable', 'Selection', 'send', 'sendAndLoad', 'separatorBefore', 'serverString',
+ 'set', 'setvariable', 'setBufferTime', 'setClipboard', 'setDate', 'setFocus', 'setFullYear', 'setGain',
+ 'setHours', 'setInterval', 'setMask', 'setMilliseconds', 'setMinutes', 'setMode', 'setMonth',
+ 'setMotionLevel', 'setNewTextFormat', 'setPan', 'setProperty', 'setQuality', 'setRate', 'setRGB',
+ 'setSeconds', 'setSelectColor', 'setSelected', 'setSelection', 'setSilenceLevel', 'setStyle',
+ 'setTextFormat', 'setTime', 'setTransform', 'setUseEchoSuppression', 'setUTCDate', 'setUTCFullYear',
+ 'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds', 'setVolume',
+ 'setYear', 'SharedObject', 'SHIFT(Konstante)', 'shift(Methode)', 'show', 'showMenu', 'showSettings',
+ 'silenceLevel', 'silenceTimeout', 'sin', 'size', 'slice', 'smoothing', 'sort', 'sortOn', 'Sound', 'SPACE',
+ 'splice', 'split', 'sqrt', 'SQRT1_2', 'SQRT2', 'Stage', 'start', 'startDrag', 'static', 'status', 'stop',
+ 'stopAllSounds', 'stopDrag', 'String', 'StyleSheet(Klasse)', 'styleSheet(Eigenschaft)', 'substr',
+ 'substring', 'super', 'swapDepths', 'System', 'TAB', 'tabChildren', 'tabEnabled', 'tabIndex',
+ 'tabStops', 'tan', 'target', 'targetPath', 'tellTarget', 'text', 'textColor', 'TextField', 'TextFormat',
+ 'textHeight', 'TextSnapshot', 'textWidth', 'this', 'throw', 'time', 'toggleHighQuality', 'toLowerCase',
+ 'toString', 'toUpperCase', 'trace', 'trackAsMenu', 'try', 'type', 'typeof', 'undefined',
+ 'underline', 'unescape', 'uninstall', 'unloadClip', 'unloadMovie', 'unLoadMovieNum', 'unshift', 'unwatch',
+ 'UP', 'updateAfterEvent', 'updateProperties', 'url', 'useCodePage', 'useEchoSuppression', 'useHandCursor',
+ 'UTC', 'valueOf', 'variable', 'version', 'Video', 'visible', 'void', 'watch', 'width',
+ 'with', 'wordwrap', 'XML', 'xmlDecl', 'XMLNode', 'XMLSocket'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '!', '@', '%', '&', '*', '|', '/', '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #0066CC;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/actionscript3.php b/platform/www/vendor/geshi/geshi/src/geshi/actionscript3.php
new file mode 100644
index 0000000..351b6b0
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/actionscript3.php
@@ -0,0 +1,471 @@
+<?php
+/*************************************************************************************
+ * actionscript3.php
+ * ----------------
+ * Author: Jordi Boggiano (j.boggiano@seld.be)
+ * Copyright: (c) 2007 Jordi Boggiano (http://www.seld.be/), Benny Baumann (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/11/26
+ *
+ * ActionScript3 language file for GeSHi.
+ *
+ * All keywords scraped from the Flex 2.0.1 Documentation
+ *
+ * The default style is based on FlexBuilder2 coloring, with the addition of class, package, method and
+ * constant names that are highlighted to help identifying problem when used on public pastebins.
+ *
+ * For styling, keywords data from 0 to 1 (accessible through .kw1, etc.) are described here :
+ *
+ * 1 : operators
+ * 2 : 'var' keyword
+ * 3 : 'function' keyword
+ * 4 : 'class' and 'package' keywords
+ * 5 : all flash.* class names plus Top Level classes, mx are excluded
+ * 6 : all flash.* package names, mx are excluded
+ * 7 : valid flash method names and properties (there is no type checks sadly, for example String().x will be highlighted as 'x' is valid, but obviously strings don't have a x property)
+ * 8 : valid flash constant names (again, no type check)
+ *
+ *
+ * CHANGES
+ * -------
+ * 2007/12/06 (1.0.7.22)
+ * - Added the 'this' keyword (oops)
+ *
+ * TODO (updated 2007/11/30)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ActionScript 3',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Regular expressions
+ 2 => "/(?<=[\\s^])(s|tr|y)\\/(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])+(?<!\s)\\/(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])*(?<!\s)\\/[msixpogcde]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])(m|q[qrwx]?)?\\/(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])+(?<!\s)\\/[msixpogc]*(?=[\\s$\\.\\,\\;\\)])/iU",
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'with', 'while', 'void', 'undefined', 'typeof', 'try', 'true',
+ 'throw', 'this', 'switch', 'super', 'set', 'return', 'public', 'protected',
+ 'private', 'null', 'new', 'is', 'internal', 'instanceof', 'in',
+ 'import', 'if', 'get', 'for', 'false', 'else', 'each', 'do',
+ 'delete', 'default', 'continue', 'catch', 'case', 'break', 'as',
+ 'extends', 'override'
+ ),
+ 2 => array(
+ 'var'
+ ),
+ 3 => array(
+ 'function'
+ ),
+ 4 => array(
+ 'class', 'package'
+ ),
+ 6 => array(
+ 'flash.xml', 'flash.utils', 'flash.ui', 'flash.text',
+ 'flash.system', 'flash.profiler', 'flash.printing', 'flash.net',
+ 'flash.media', 'flash.geom', 'flash.filters', 'flash.external',
+ 'flash.events', 'flash.errors', 'flash.display',
+ 'flash.accessibility'
+ ),
+ 7 => array(
+ 'zoom', 'year', 'y', 'xmlDecl', 'x', 'writeUnsignedInt',
+ 'writeUTFBytes', 'writeUTF', 'writeShort', 'writeObject',
+ 'writeMultiByte', 'writeInt', 'writeFloat', 'writeExternal',
+ 'writeDynamicProperty', 'writeDynamicProperties', 'writeDouble',
+ 'writeBytes', 'writeByte', 'writeBoolean', 'wordWrap',
+ 'willTrigger', 'width', 'volume', 'visible', 'videoWidth',
+ 'videoHeight', 'version', 'valueOf', 'value', 'usingTLS',
+ 'useRichTextClipboard', 'useHandCursor', 'useEchoSuppression',
+ 'useCodePage', 'url', 'uri', 'uploadCompleteData', 'upload',
+ 'updateProperties', 'updateAfterEvent', 'upState', 'unshift',
+ 'unlock', 'unload', 'union', 'unescapeMultiByte', 'unescape',
+ 'underline', 'uncompress', 'type', 'ty', 'tx', 'transparent',
+ 'translate', 'transformPoint', 'transform', 'trackAsMenu', 'track',
+ 'trace', 'totalMemory', 'totalFrames', 'topLeft', 'top',
+ 'togglePause', 'toXMLString', 'toUpperCase', 'toUTCString',
+ 'toTimeString', 'toString', 'toPrecision', 'toLowerCase',
+ 'toLocaleUpperCase', 'toLocaleTimeString', 'toLocaleString',
+ 'toLocaleLowerCase', 'toLocaleDateString', 'toFixed',
+ 'toExponential', 'toDateString', 'timezoneOffset', 'timerComplete',
+ 'timer', 'time', 'threshold', 'thickness', 'textWidth',
+ 'textSnapshot', 'textInput', 'textHeight', 'textColor', 'text',
+ 'test', 'target', 'tan', 'tabStops', 'tabIndexChange', 'tabIndex',
+ 'tabEnabledChange', 'tabEnabled', 'tabChildrenChange',
+ 'tabChildren', 'sync', 'swfVersion', 'swapChildrenAt',
+ 'swapChildren', 'subtract', 'substring', 'substr', 'styleSheet',
+ 'styleNames', 'strength', 'stopPropagation',
+ 'stopImmediatePropagation', 'stopDrag', 'stopAll', 'stop', 'status',
+ 'startDrag', 'start', 'stageY', 'stageX', 'stageWidth',
+ 'stageHeight', 'stageFocusRect', 'stage', 'sqrt', 'split', 'splice',
+ 'source', 'soundTransform', 'soundComplete', 'sortOn', 'sort',
+ 'songName', 'some', 'socketData', 'smoothing', 'slice', 'size',
+ 'sin', 'silent', 'silenceTimeout', 'silenceLevel', 'showSettings',
+ 'showRedrawRegions', 'showDefaultContextMenu', 'show', 'shortcut',
+ 'shiftKey', 'shift', 'sharpness', 'sharedEvents', 'shadowColor',
+ 'shadowAlpha', 'settings', 'setUseEchoSuppression', 'setUTCSeconds',
+ 'setUTCMonth', 'setUTCMinutes', 'setUTCMilliseconds', 'setUTCHours',
+ 'setUTCFullYear', 'setUTCDate', 'setTimeout', 'setTime',
+ 'setTextFormat', 'setStyle', 'setSilenceLevel', 'setSettings',
+ 'setSelection', 'setSelected', 'setSelectColor', 'setSeconds',
+ 'setQuality', 'setPropertyIsEnumerable', 'setProperty', 'setPixels',
+ 'setPixel32', 'setPixel', 'setNamespace', 'setName',
+ 'setMotionLevel', 'setMonth', 'setMode', 'setMinutes',
+ 'setMilliseconds', 'setLoopback', 'setLoopBack', 'setLocalName',
+ 'setKeyFrameInterval', 'setInterval', 'setHours', 'setFullYear',
+ 'setEmpty', 'setDirty', 'setDate', 'setCompositionString',
+ 'setClipboard', 'setChildren', 'setChildIndex',
+ 'setAdvancedAntiAliasingTable', 'serverString', 'separatorBefore',
+ 'sendToURL', 'send', 'selectionEndIndex', 'selectionBeginIndex',
+ 'selectable', 'select', 'seek', 'securityError', 'securityDomain',
+ 'secondsUTC', 'seconds', 'search', 'scrollV', 'scrollRect',
+ 'scrollH', 'scroll', 'screenResolutionY', 'screenResolutionX',
+ 'screenDPI', 'screenColor', 'scenes', 'scaleY', 'scaleX',
+ 'scaleMode', 'scale9Grid', 'scale', 'save', 'sandboxType',
+ 'sameDomain', 'running', 'round', 'rotation', 'rotate', 'root',
+ 'rollOver', 'rollOut', 'rightToRight', 'rightToLeft', 'rightPeak',
+ 'rightMargin', 'right', 'rewind', 'reverse', 'resume', 'restrict',
+ 'resize', 'reset', 'requestHeaders', 'replaceText',
+ 'replaceSelectedText', 'replace', 'repeatCount', 'render',
+ 'removedFromStage', 'removed', 'removeNode', 'removeNamespace',
+ 'removeEventListener', 'removeChildAt', 'removeChild',
+ 'relatedObject', 'registerFont', 'registerClassAlias', 'redOffset',
+ 'redMultiplier', 'rect', 'receiveVideo', 'receiveAudio',
+ 'readUnsignedShort', 'readUnsignedInt', 'readUnsignedByte',
+ 'readUTFBytes', 'readUTF', 'readShort', 'readObject',
+ 'readMultiByte', 'readInt', 'readFloat', 'readExternal',
+ 'readDouble', 'readBytes', 'readByte', 'readBoolean', 'ratios',
+ 'rate', 'random', 'quality', 'push', 'publish', 'proxyType',
+ 'prototype', 'propertyIsEnumerable', 'progress',
+ 'processingInstructions', 'printAsBitmap', 'print',
+ 'previousSibling', 'preventDefault', 'prevScene', 'prevFrame',
+ 'prettyPrinting', 'prettyIndent', 'preserveAlpha', 'prependChild',
+ 'prefix', 'pow', 'position', 'pop', 'polar', 'playerType', 'play',
+ 'pixelSnapping', 'pixelDissolve', 'pixelBounds', 'pixelAspectRatio',
+ 'perlinNoise', 'pause', 'parseXML', 'parseInt', 'parseFloat',
+ 'parseCSS', 'parse', 'parentNode', 'parentDomain',
+ 'parentAllowsChild', 'parent', 'parameters', 'paperWidth',
+ 'paperHeight', 'pan', 'paletteMap', 'pageWidth', 'pageHeight',
+ 'overState', 'outsideCutoff', 'os', 'orientation', 'open',
+ 'opaqueBackground', 'onPlayStatus', 'onMetaData', 'onCuePoint',
+ 'offsetPoint', 'offset', 'objectID', 'objectEncoding', 'numLock',
+ 'numLines', 'numFrames', 'numChildren', 'normalize', 'noise',
+ 'nodeValue', 'nodeType', 'nodeName', 'nodeKind', 'noAutoLabeling',
+ 'nextValue', 'nextSibling', 'nextScene', 'nextNameIndex',
+ 'nextName', 'nextFrame', 'netStatus', 'navigateToURL',
+ 'namespaceURI', 'namespaceDeclarations', 'namespace', 'names',
+ 'name', 'muted', 'multiline', 'moveTo', 'mouseY', 'mouseX',
+ 'mouseWheelEnabled', 'mouseWheel', 'mouseUp', 'mouseTarget',
+ 'mouseOver', 'mouseOut', 'mouseMove', 'mouseLeave',
+ 'mouseFocusChange', 'mouseEnabled', 'mouseDown', 'mouseChildren',
+ 'motionTimeout', 'motionLevel', 'monthUTC', 'month',
+ 'modificationDate', 'mode', 'minutesUTC', 'minutes', 'min',
+ 'millisecondsUTC', 'milliseconds', 'method', 'message', 'merge',
+ 'menuSelect', 'menuItemSelect', 'maxScrollV', 'maxScrollH',
+ 'maxLevel', 'maxChars', 'max', 'matrixY', 'matrixX', 'matrix',
+ 'match', 'mask', 'mapPoint', 'mapBitmap', 'map', 'manufacturer',
+ 'macType', 'loopback', 'loop', 'log', 'lock', 'localeCompare',
+ 'localY', 'localX', 'localToGlobal', 'localName',
+ 'localFileReadDisable', 'loaderURL', 'loaderInfo', 'loader',
+ 'loadPolicyFile', 'loadBytes', 'load', 'liveDelay', 'link',
+ 'lineTo', 'lineStyle', 'lineGradientStyle', 'level',
+ 'letterSpacing', 'length', 'leftToRight', 'leftToLeft', 'leftPeak',
+ 'leftMargin', 'left', 'leading', 'lastIndexOf', 'lastIndex',
+ 'lastChild', 'language', 'labels', 'knockout', 'keyUp',
+ 'keyLocation', 'keyFrameInterval', 'keyFocusChange', 'keyDown',
+ 'keyCode', 'kerning', 'join', 'italic', 'isXMLName',
+ 'isPrototypeOf', 'isNaN', 'isFocusInaccessible', 'isFinite',
+ 'isEmpty', 'isDefaultPrevented', 'isDebugger', 'isBuffering',
+ 'isAttribute', 'isAccessible', 'ioError', 'invert', 'invalidate',
+ 'intersects', 'intersection', 'interpolate', 'insideCutoff',
+ 'insertChildBefore', 'insertChildAfter', 'insertBefore', 'inner',
+ 'init', 'info', 'inflatePoint', 'inflate', 'indexOf', 'index',
+ 'indent', 'inScopeNamespaces', 'imeComposition', 'ime',
+ 'ignoreWhitespace', 'ignoreWhite', 'ignoreProcessingInstructions',
+ 'ignoreComments', 'ignoreCase', 'identity', 'idMap', 'id3',
+ 'httpStatus', 'htmlText', 'hoursUTC', 'hours', 'hitTestTextNearPos',
+ 'hitTestState', 'hitTestPoint', 'hitTestObject', 'hitTest',
+ 'hitArea', 'highlightColor', 'highlightAlpha', 'hideObject',
+ 'hideBuiltInItems', 'hide', 'height', 'hasVideoEncoder', 'hasTLS',
+ 'hasStreamingVideo', 'hasStreamingAudio', 'hasSimpleContent',
+ 'hasScreenPlayback', 'hasScreenBroadcast', 'hasProperty',
+ 'hasPrinting', 'hasOwnProperty', 'hasMP3', 'hasIME', 'hasGlyphs',
+ 'hasEventListener', 'hasEmbeddedVideo', 'hasDefinition',
+ 'hasComplexContent', 'hasChildNodes', 'hasAudioEncoder', 'hasAudio',
+ 'hasAccessibility', 'gridFitType', 'greenOffset', 'greenMultiplier',
+ 'graphics', 'gotoAndStop', 'gotoAndPlay', 'globalToLocal', 'global',
+ 'getUTCSeconds', 'getUTCMonth', 'getUTCMinutes',
+ 'getUTCMilliseconds', 'getUTCHours', 'getUTCFullYear', 'getUTCDay',
+ 'getUTCDate', 'getTimezoneOffset', 'getTimer', 'getTime',
+ 'getTextRunInfo', 'getTextFormat', 'getText', 'getStyle',
+ 'getStackTrace', 'getSelectedText', 'getSelected', 'getSeconds',
+ 'getRemote', 'getRect', 'getQualifiedSuperclassName',
+ 'getQualifiedClassName', 'getProperty', 'getPrefixForNamespace',
+ 'getPixels', 'getPixel32', 'getPixel', 'getParagraphLength',
+ 'getObjectsUnderPoint', 'getNamespaceForPrefix', 'getMonth',
+ 'getMinutes', 'getMilliseconds', 'getMicrophone', 'getLocal',
+ 'getLineText', 'getLineOffset', 'getLineMetrics', 'getLineLength',
+ 'getLineIndexOfChar', 'getLineIndexAtPoint', 'getImageReference',
+ 'getHours', 'getFullYear', 'getFirstCharInParagraph',
+ 'getDescendants', 'getDefinitionByName', 'getDefinition', 'getDay',
+ 'getDate', 'getColorBoundsRect', 'getClassByAlias', 'getChildIndex',
+ 'getChildByName', 'getChildAt', 'getCharIndexAtPoint',
+ 'getCharBoundaries', 'getCamera', 'getBounds', 'genre',
+ 'generateFilterRect', 'gain', 'fullYearUTC', 'fullYear',
+ 'fullScreen', 'fscommand', 'fromCharCode', 'framesLoaded',
+ 'frameRate', 'frame', 'fps', 'forwardAndBack', 'formatToString',
+ 'forceSimple', 'forEach', 'fontType', 'fontStyle', 'fontSize',
+ 'fontName', 'font', 'focusRect', 'focusOut', 'focusIn', 'focus',
+ 'flush', 'floor', 'floodFill', 'firstChild', 'findText', 'filters',
+ 'filter', 'fillRect', 'fileList', 'extension', 'extended', 'exp',
+ 'exec', 'exactSettings', 'every', 'eventPhase', 'escapeMultiByte',
+ 'escape', 'errorID', 'error', 'equals', 'enumerateFonts',
+ 'enterFrame', 'endian', 'endFill', 'encodeURIComponent',
+ 'encodeURI', 'enabled', 'embedFonts', 'elements',
+ 'dynamicPropertyWriter', 'dropTarget', 'drawRoundRect', 'drawRect',
+ 'drawEllipse', 'drawCircle', 'draw', 'download', 'downState',
+ 'doubleClickEnabled', 'doubleClick', 'dotall', 'domain',
+ 'docTypeDecl', 'doConversion', 'divisor', 'distance', 'dispose',
+ 'displayState', 'displayMode', 'displayAsPassword', 'dispatchEvent',
+ 'description', 'describeType', 'descent', 'descendants',
+ 'deltaTransformPoint', 'delta', 'deleteProperty', 'delay',
+ 'defaultTextFormat', 'defaultSettings', 'defaultObjectEncoding',
+ 'decodeURIComponent', 'decodeURI', 'decode', 'deblocking',
+ 'deactivate', 'dayUTC', 'day', 'dateUTC', 'date', 'dataFormat',
+ 'data', 'd', 'customItems', 'curveTo', 'currentTarget',
+ 'currentScene', 'currentLabels', 'currentLabel', 'currentFrame',
+ 'currentFPS', 'currentDomain', 'currentCount', 'ctrlKey', 'creator',
+ 'creationDate', 'createTextNode', 'createGradientBox',
+ 'createElement', 'createBox', 'cos', 'copyPixels', 'copyChannel',
+ 'copy', 'conversionMode', 'contextMenuOwner', 'contextMenu',
+ 'contentType', 'contentLoaderInfo', 'content', 'containsRect',
+ 'containsPoint', 'contains', 'constructor', 'connectedProxyType',
+ 'connected', 'connect', 'condenseWhite', 'concatenatedMatrix',
+ 'concatenatedColorTransform', 'concat', 'computeSpectrum',
+ 'compress', 'componentY', 'componentX', 'complete', 'compare',
+ 'comments', 'comment', 'colors', 'colorTransform', 'color', 'code',
+ 'close', 'cloneNode', 'clone', 'client', 'click', 'clearTimeout',
+ 'clearInterval', 'clear', 'clamp', 'children', 'childNodes',
+ 'childIndex', 'childAllowsParent', 'child', 'checkPolicyFile',
+ 'charCount', 'charCodeAt', 'charCode', 'charAt', 'changeList',
+ 'change', 'ceil', 'caretIndex', 'caption', 'capsLock', 'cancelable',
+ 'cancel', 'callee', 'callProperty', 'call', 'cacheAsBitmap', 'c',
+ 'bytesTotal', 'bytesLoaded', 'bytesAvailable', 'buttonMode',
+ 'buttonDown', 'bullet', 'builtInItems', 'bufferTime',
+ 'bufferLength', 'bubbles', 'browse', 'bottomScrollV', 'bottomRight',
+ 'bottom', 'borderColor', 'border', 'bold', 'blurY', 'blurX',
+ 'blueOffset', 'blueMultiplier', 'blockIndent', 'blendMode',
+ 'bitmapData', 'bias', 'beginGradientFill', 'beginFill',
+ 'beginBitmapFill', 'bandwidth', 'backgroundColor', 'background',
+ 'b', 'available', 'avHardwareDisable', 'autoSize', 'attributes',
+ 'attribute', 'attachNetStream', 'attachCamera', 'attachAudio',
+ 'atan2', 'atan', 'asyncError', 'asin', 'ascent', 'artist',
+ 'areSoundsInaccessible', 'areInaccessibleObjectsUnderPoint',
+ 'applyFilter', 'apply', 'applicationDomain', 'appendText',
+ 'appendChild', 'antiAliasType', 'angle', 'alwaysShowSelection',
+ 'altKey', 'alphas', 'alphaOffset', 'alphaMultiplier', 'alpha',
+ 'allowInsecureDomain', 'allowDomain', 'align', 'album',
+ 'addedToStage', 'added', 'addPage', 'addNamespace', 'addHeader',
+ 'addEventListener', 'addChildAt', 'addChild', 'addCallback', 'add',
+ 'activityLevel', 'activity', 'active', 'activating', 'activate',
+ 'actionScriptVersion', 'acos', 'accessibilityProperties', 'abs'
+ ),
+ 8 => array(
+ 'WRAP', 'VERTICAL', 'VARIABLES',
+ 'UTC', 'UPLOAD_COMPLETE_DATA', 'UP', 'UNLOAD', 'UNKNOWN',
+ 'UNIQUESORT', 'TOP_RIGHT', 'TOP_LEFT', 'TOP', 'TIMER_COMPLETE',
+ 'TIMER', 'TEXT_NODE', 'TEXT_INPUT', 'TEXT', 'TAB_INDEX_CHANGE',
+ 'TAB_ENABLED_CHANGE', 'TAB_CHILDREN_CHANGE', 'TAB', 'SYNC',
+ 'SUBTRACT', 'SUBPIXEL', 'STATUS', 'STANDARD', 'SQUARE', 'SQRT2',
+ 'SQRT1_2', 'SPACE', 'SOUND_COMPLETE', 'SOCKET_DATA', 'SHOW_ALL',
+ 'SHIFT', 'SETTINGS_MANAGER', 'SELECT', 'SECURITY_ERROR', 'SCROLL',
+ 'SCREEN', 'ROUND', 'ROLL_OVER', 'ROLL_OUT', 'RIGHT', 'RGB',
+ 'RETURNINDEXEDARRAY', 'RESIZE', 'REPEAT', 'RENDER',
+ 'REMOVED_FROM_STAGE', 'REMOVED', 'REMOTE', 'REGULAR', 'REFLECT',
+ 'RED', 'RADIAL', 'PROGRESS', 'PRIVACY', 'POST', 'POSITIVE_INFINITY',
+ 'PORTRAIT', 'PIXEL', 'PI', 'PENDING', 'PAGE_UP', 'PAGE_DOWN', 'PAD',
+ 'OVERLAY', 'OUTER', 'OPEN', 'NaN', 'NUM_PAD', 'NUMPAD_SUBTRACT',
+ 'NUMPAD_MULTIPLY', 'NUMPAD_ENTER', 'NUMPAD_DIVIDE',
+ 'NUMPAD_DECIMAL', 'NUMPAD_ADD', 'NUMPAD_9', 'NUMPAD_8', 'NUMPAD_7',
+ 'NUMPAD_6', 'NUMPAD_5', 'NUMPAD_4', 'NUMPAD_3', 'NUMPAD_2',
+ 'NUMPAD_1', 'NUMPAD_0', 'NUMERIC', 'NO_SCALE', 'NO_BORDER',
+ 'NORMAL', 'NONE', 'NEVER', 'NET_STATUS', 'NEGATIVE_INFINITY',
+ 'MULTIPLY', 'MOUSE_WHEEL', 'MOUSE_UP', 'MOUSE_OVER', 'MOUSE_OUT',
+ 'MOUSE_MOVE', 'MOUSE_LEAVE', 'MOUSE_FOCUS_CHANGE', 'MOUSE_DOWN',
+ 'MITER', 'MIN_VALUE', 'MICROPHONE', 'MENU_SELECT',
+ 'MENU_ITEM_SELECT', 'MEDIUM', 'MAX_VALUE', 'LOW', 'LOG2E', 'LOG10E',
+ 'LOCAL_WITH_NETWORK', 'LOCAL_WITH_FILE', 'LOCAL_TRUSTED',
+ 'LOCAL_STORAGE', 'LN2', 'LN10', 'LITTLE_ENDIAN', 'LINK',
+ 'LINEAR_RGB', 'LINEAR', 'LIGHT_COLOR', 'LIGHTEN', 'LEFT', 'LCD',
+ 'LAYER', 'LANDSCAPE', 'KOREAN', 'KEY_UP', 'KEY_FOCUS_CHANGE',
+ 'KEY_DOWN', 'JUSTIFY', 'JAPANESE_KATAKANA_HALF',
+ 'JAPANESE_KATAKANA_FULL', 'JAPANESE_HIRAGANA', 'Infinity', 'ITALIC',
+ 'IO_ERROR', 'INVERT', 'INSERT', 'INPUT', 'INNER', 'INIT',
+ 'IME_COMPOSITION', 'IGNORE', 'ID3', 'HTTP_STATUS', 'HORIZONTAL',
+ 'HOME', 'HIGH', 'HARDLIGHT', 'GREEN', 'GET', 'FULLSCREEN', 'FULL',
+ 'FOCUS_OUT', 'FOCUS_IN', 'FLUSHED', 'FLASH9', 'FLASH8', 'FLASH7',
+ 'FLASH6', 'FLASH5', 'FLASH4', 'FLASH3', 'FLASH2', 'FLASH1', 'F9',
+ 'F8', 'F7', 'F6', 'F5', 'F4', 'F3', 'F2', 'F15', 'F14', 'F13',
+ 'F12', 'F11', 'F10', 'F1', 'EXACT_FIT', 'ESCAPE', 'ERROR', 'ERASE',
+ 'ENTER_FRAME', 'ENTER', 'END', 'EMBEDDED', 'ELEMENT_NODE', 'E',
+ 'DYNAMIC', 'DOWN', 'DOUBLE_CLICK', 'DIFFERENCE', 'DEVICE',
+ 'DESCENDING', 'DELETE', 'DEFAULT', 'DEACTIVATE', 'DATA',
+ 'DARK_COLOR', 'DARKEN', 'CRT', 'CONTROL', 'CONNECT', 'COMPLETE',
+ 'COLOR', 'CLOSE', 'CLICK', 'CLAMP', 'CHINESE', 'CHANGE', 'CENTER',
+ 'CASEINSENSITIVE', 'CAPTURING_PHASE', 'CAPS_LOCK', 'CANCEL',
+ 'CAMERA', 'BUBBLING_PHASE', 'BOTTOM_RIGHT', 'BOTTOM_LEFT', 'BOTTOM',
+ 'BOLD_ITALIC', 'BOLD', 'BLUE', 'BINARY', 'BIG_ENDIAN', 'BEVEL',
+ 'BEST', 'BACKSPACE', 'AUTO', 'AT_TARGET', 'ASYNC_ERROR', 'AMF3',
+ 'AMF0', 'ALWAYS', 'ALPHANUMERIC_HALF', 'ALPHANUMERIC_FULL', 'ALPHA',
+ 'ADVANCED', 'ADDED_TO_STAGE', 'ADDED', 'ADD', 'ACTIVITY',
+ 'ACTIONSCRIPT3', 'ACTIONSCRIPT2'
+ ),
+ //FIX: Must be last in order to avoid conflicts with keywords present
+ //in other keyword groups, that might get highlighted as part of the URL.
+ //I know this is not a proper work-around, but should do just fine.
+ 5 => array(
+ 'uint', 'int', 'arguments', 'XMLSocket', 'XMLNodeType', 'XMLNode',
+ 'XMLList', 'XMLDocument', 'XML', 'Video', 'VerifyError',
+ 'URLVariables', 'URLStream', 'URLRequestMethod', 'URLRequestHeader',
+ 'URLRequest', 'URLLoaderDataFormat', 'URLLoader', 'URIError',
+ 'TypeError', 'Transform', 'TimerEvent', 'Timer', 'TextSnapshot',
+ 'TextRenderer', 'TextLineMetrics', 'TextFormatAlign', 'TextFormat',
+ 'TextFieldType', 'TextFieldAutoSize', 'TextField', 'TextEvent',
+ 'TextDisplayMode', 'TextColorType', 'System', 'SyntaxError',
+ 'SyncEvent', 'StyleSheet', 'String', 'StatusEvent', 'StaticText',
+ 'StageScaleMode', 'StageQuality', 'StageAlign', 'Stage',
+ 'StackOverflowError', 'Sprite', 'SpreadMethod', 'SoundTransform',
+ 'SoundMixer', 'SoundLoaderContext', 'SoundChannel', 'Sound',
+ 'Socket', 'SimpleButton', 'SharedObjectFlushStatus', 'SharedObject',
+ 'Shape', 'SecurityPanel', 'SecurityErrorEvent', 'SecurityError',
+ 'SecurityDomain', 'Security', 'ScriptTimeoutError', 'Scene',
+ 'SWFVersion', 'Responder', 'RegExp', 'ReferenceError', 'Rectangle',
+ 'RangeError', 'QName', 'Proxy', 'ProgressEvent',
+ 'PrintJobOrientation', 'PrintJobOptions', 'PrintJob', 'Point',
+ 'PixelSnapping', 'ObjectEncoding', 'Object', 'Number', 'NetStream',
+ 'NetStatusEvent', 'NetConnection', 'Namespace', 'MovieClip',
+ 'MouseEvent', 'Mouse', 'MorphShape', 'Microphone', 'MemoryError',
+ 'Matrix', 'Math', 'LocalConnection', 'LoaderInfo', 'LoaderContext',
+ 'Loader', 'LineScaleMode', 'KeyboardEvent', 'Keyboard',
+ 'KeyLocation', 'JointStyle', 'InvalidSWFError',
+ 'InterpolationMethod', 'InteractiveObject', 'IllegalOperationError',
+ 'IOErrorEvent', 'IOError', 'IMEEvent', 'IMEConversionMode', 'IME',
+ 'IExternalizable', 'IEventDispatcher', 'IDynamicPropertyWriter',
+ 'IDynamicPropertyOutput', 'IDataOutput', 'IDataInput', 'ID3Info',
+ 'IBitmapDrawable', 'HTTPStatusEvent', 'GridFitType', 'Graphics',
+ 'GradientType', 'GradientGlowFilter', 'GradientBevelFilter',
+ 'GlowFilter', 'Function', 'FrameLabel', 'FontType', 'FontStyle',
+ 'Font', 'FocusEvent', 'FileReferenceList', 'FileReference',
+ 'FileFilter', 'ExternalInterface', 'EventPhase', 'EventDispatcher',
+ 'Event', 'EvalError', 'ErrorEvent', 'Error', 'Endian', 'EOFError',
+ 'DropShadowFilter', 'DisplayObjectContainer', 'DisplayObject',
+ 'DisplacementMapFilterMode', 'DisplacementMapFilter', 'Dictionary',
+ 'DefinitionError', 'Date', 'DataEvent', 'ConvolutionFilter',
+ 'ContextMenuItem', 'ContextMenuEvent', 'ContextMenuBuiltInItems',
+ 'ContextMenu', 'ColorTransform', 'ColorMatrixFilter', 'Class',
+ 'CapsStyle', 'Capabilities', 'Camera', 'CSMSettings', 'ByteArray',
+ 'Boolean', 'BlurFilter', 'BlendMode', 'BitmapFilterType',
+ 'BitmapFilterQuality', 'BitmapFilter', 'BitmapDataChannel',
+ 'BitmapData', 'Bitmap', 'BevelFilter', 'AsyncErrorEvent', 'Array',
+ 'ArgumentError', 'ApplicationDomain', 'AntiAliasType',
+ 'ActivityEvent', 'ActionScriptVersion', 'AccessibilityProperties',
+ 'Accessibility', 'AVM1Movie'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '!', '%', '&', '*', '|', '/', '<', '>', '^', '-', '+', '~', '?', ':', ';', '.', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0033ff; font-weight: bold;',
+ 2 => 'color: #6699cc; font-weight: bold;',
+ 3 => 'color: #339966; font-weight: bold;',
+ 4 => 'color: #9900cc; font-weight: bold;',
+ 5 => 'color: #004993;',
+ 6 => 'color: #004993;',
+ 7 => 'color: #004993;',
+ 8 => 'color: #004993;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #009900; font-style: italic;',
+ 2 => 'color: #009966; font-style: italic;',
+ 'MULTI' => 'color: #3f5fbf;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #990000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000; font-weight:bold;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #000000;',
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => 'http://www.google.com/search?q={FNAMEL}%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:{FNAMEL}.html',
+ 6 => '',
+ 7 => '',
+ 8 => ''
+ ),
+ 'OOLANG' => false,//Save some time as OO identifiers aren't used
+ 'OBJECT_SPLITTERS' => array(
+ // commented out because it's not very relevant for AS, as all properties, methods and constants are dot-accessed.
+ // I believe it's preferable to have package highlighting for example, which is not possible with this enabled.
+ // 0 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/ada.php b/platform/www/vendor/geshi/geshi/src/geshi/ada.php
new file mode 100644
index 0000000..0eb0b7c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/ada.php
@@ -0,0 +1,130 @@
+<?php
+/*************************************************************************************
+ * ada.php
+ * -------
+ * Author: Tux (tux@inmail.cz)
+ * Copyright: (c) 2004 Tux (http://tux.a4.cz/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/07/29
+ *
+ * Ada language file for GeSHi.
+ * Words are from SciTe configuration file
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.2)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ * - Removed apostrophe as string delimiter
+ * - Added URL support
+ * 2004/08/05 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Ada',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'begin', 'declare', 'do', 'else', 'elsif', 'exception', 'for', 'if',
+ 'is', 'loop', 'while', 'then', 'end', 'select', 'case', 'until',
+ 'goto', 'return'
+ ),
+ 2 => array(
+ 'abs', 'and', 'at', 'mod', 'not', 'or', 'rem', 'xor'
+ ),
+ 3 => array(
+ 'abort', 'abstract', 'accept', 'access', 'aliased', 'all', 'array',
+ 'body', 'constant', 'delay', 'delta', 'digits', 'entry', 'exit',
+ 'function', 'generic', 'in', 'interface', 'limited', 'new', 'null',
+ 'of', 'others', 'out', 'overriding', 'package', 'pragma', 'private',
+ 'procedure', 'protected', 'raise', 'range', 'record', 'renames',
+ 'requeue', 'reverse', 'separate', 'subtype', 'synchronized',
+ 'tagged', 'task', 'terminate', 'type', 'use', 'when', 'with'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00007f;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #46aa03; font-weight:bold;',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/aimms.php b/platform/www/vendor/geshi/geshi/src/geshi/aimms.php
new file mode 100644
index 0000000..6c65391
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/aimms.php
@@ -0,0 +1,316 @@
+<?php
+/*************************************************************************************
+ * aimms.php
+ * --------
+ * Author: Guido Diepen (guido.diepen@aimms.com)
+ * Copyright: (c) 2011 Guido Diepen (http://www.aimms.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/05/05
+ *
+ * AIMMS language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * * Make sure the last few function I may have missed
+ * (like eval()) are included for highlighting
+ * * Split to several files - php4, php5 etc
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'AIMMS3',
+ 'COMMENT_SINGLE' => array(1 => '!'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array("'", "\\"),
+ 'HARDCHAR' => "\\",
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'if', 'then', 'else', 'endif', 'elseif', 'for', 'do', 'while' , 'endfor' , 'endwhile', 'break', 'switch', 'endswitch',
+ 'display', 'return', 'in', 'apply'
+
+ ),
+ 2 => array(
+ 'main model' , 'declaration section', 'procedure', 'endprocedure', 'endmodel', 'endsection' , 'set', 'parameter',
+ 'string parameter', 'element parameter', 'quantity'
+ ),
+ 3 => array(
+ 'identifier', 'index', 'index domain', 'body'
+ ),
+ 4 => array(
+ 'ActiveCard','Card','ConvertUnit','DistributionCumulative','DistributionDensity','DistributionDeviation',
+ 'DistributionInverseCumulative','DistributionInverseDensity','DistributionKurtosis','DistributionMean',
+ 'DistributionSkewness','DistributionVariance','Element','EvaluateUnit','First','FormatString','Last',
+ 'Ord','Unit','Val','Aggregate','AttributeToString','CaseCompareIdentifier','CaseCreateDifferenceFile',
+ 'CloseDataSource','CreateTimeTable','ConstraintVariables','ConvertReferenceDate','CloneElement',
+ 'FindNthString','FindReplaceNthString','FindReplaceStrings','FindString','StringOccurrences',
+ 'CurrentToMoment','CurrentToString','CurrentToTimeSlot','DaylightsavingEndDate','DaylightsavingStartDate',
+ 'DeclaredSubset','DomainIndex','IndexRange','IsRunningAsViewer','ListingFileCopy','ListingFileDelete',
+ 'DirectoryGetFiles','DirectoryGetSubdirectories','DirectSQL','Disaggregate','ElementCast','ElementRange',
+ 'EnvironmentGetString','EnvironmentSetString','errh::Adapt','errh::Attribute','errh::Category',
+ 'errh::Code','errh::Column','errh::CreationTime','errh::Filename','errh::InsideCategory',
+ 'errh::IsMarkedAsHandled','errh::Line','errh::MarkAsHandled','errh::Message','errh::Multiplicity',
+ 'errh::Node','errh::NumberOfLocations','errh::Severity','ExcelAddNewSheet','ExcelAssignParameter',
+ 'ExcelAssignSet','ExcelAssignTable','ExcelAssignValue','ExcelClearRange','ExcelCloseWorkbook',
+ 'ExcelColumnName','ExcelColumnNumber','ExcelCopyRange','ExcelCreateWorkbook','ExcelDeleteSheet',
+ 'ExcelPrint','ExcelRetrieveParameter','ExcelRetrieveSet','ExcelRetrieveTable','ExcelRetrieveValue',
+ 'ExcelRunMacro','ExcelSaveWorkbook','ExcelSetActiveSheet','ExcelSetUpdateLinksBehavior',
+ 'ExcelSetVisibility','FindUsedElements','GenerateCUT','GMP::Coefficient::Get',
+ 'GMP::Coefficient::GetQuadratic','GMP::Coefficient::Set','GMP::Coefficient::SetQuadratic',
+ 'GMP::Column::Add','GMP::Column::Delete','GMP::Column::Freeze','GMP::Column::GetLowerbound',
+ 'GMP::Column::GetScale','GMP::Column::GetStatus','GMP::Column::GetType','GMP::Column::GetUpperbound',
+ 'GMP::Column::SetAsObjective','GMP::Column::SetLowerbound','GMP::Column::SetType',
+ 'GMP::Column::SetUpperbound','GMP::Column::Unfreeze','GMP::Instance::AddIntegerEliminationRows',
+ 'GMP::Instance::CalculateSubGradient','GMP::Instance::Copy','GMP::Instance::CreateDual',
+ 'GMP::Instance::CreateMasterMip','GMP::Instance::CreatePresolved',
+ 'GMP::SolverSession::CreateProgressCategory','GMP::Instance::CreateProgressCategory',
+ 'GMP::Instance::CreateSolverSession','GMP::Stochastic::CreateBendersRootproblem',
+ 'GMP::Instance::Delete','GMP::Instance::DeleteIntegerEliminationRows',
+ 'GMP::Instance::DeleteSolverSession','GMP::Instance::FindApproximatelyFeasibleSolution',
+ 'GMP::Instance::FixColumns','GMP::Instance::Generate','GMP::Instance::GenerateRobustCounterpart',
+ 'GMP::Instance::GenerateStochasticProgram','GMP::SolverSession::GetCallbackInterruptStatus',
+ 'GMP::SolverSession::WaitForCompletion','GMP::SolverSession::WaitForSingleCompletion',
+ 'GMP::SolverSession::ExecutionStatus','GMP::Instance::GetDirection','GMP::Instance::GetLinearObjective',
+ 'GMP::Instance::GetMathematicalProgrammingType','GMP::Instance::GetMemoryUsed',
+ 'GMP::Instance::GetNumberOfColumns','GMP::Instance::GetNumberOfIndicatorRows',
+ 'GMP::Instance::GetNumberOfIntegerColumns','GMP::Instance::GetNumberOfNonlinearColumns',
+ 'GMP::Instance::GetNumberOfNonlinearNonzeros','GMP::Instance::GetNumberOfNonlinearRows',
+ 'GMP::Instance::GetNumberOfNonzeros','GMP::Instance::GetNumberOfRows',
+ 'GMP::Instance::GetNumberOfSOS1Rows','GMP::Instance::GetNumberOfSOS2Rows',
+ 'GMP::Instance::GetObjective','GMP::Instance::GetOptionValue','GMP::Instance::GetSolver',
+ 'GMP::Instance::GetSymbolicMathematicalProgram','GMP::Instance::MemoryStatistics',
+ 'GMP::Instance::Rename','GMP::Instance::SetCallbackAddCut','GMP::Instance::SetCallbackBranch',
+ 'GMP::Instance::SetCallbackHeuristic','GMP::Instance::SetCallbackIncumbent',
+ 'GMP::Instance::SetCallbackIterations','GMP::Instance::SetCallbackNewIncumbent',
+ 'GMP::Instance::SetCallbackStatusChange','GMP::Instance::SetCutoff','GMP::Instance::SetDirection',
+ 'GMP::Instance::SetMathematicalProgrammingType','GMP::Instance::SetSolver','GMP::Instance::Solve',
+ 'GMP::Stochastic::GetObjectiveBound','GMP::Stochastic::GetRelativeWeight',
+ 'GMP::Stochastic::GetRepresentativeScenario','GMP::Stochastic::UpdateBendersSubproblem',
+ 'GMP::Linearization::Add','GMP::Linearization::AddSingle','GMP::Linearization::Delete',
+ 'GMP::Linearization::GetDeviation','GMP::Linearization::GetDeviationBound',
+ 'GMP::Linearization::GetLagrangeMultiplier','GMP::Linearization::GetType',
+ 'GMP::Linearization::GetWeight','GMP::Linearization::RemoveDeviation',
+ 'GMP::Linearization::SetDeviationBound','GMP::Linearization::SetType',
+ 'GMP::Linearization::SetWeight','GMP::ProgressWindow::DeleteCategory',
+ 'GMP::ProgressWindow::DisplayLine','GMP::ProgressWindow::DisplayProgramStatus',
+ 'GMP::ProgressWindow::DisplaySolver','GMP::ProgressWindow::DisplaySolverStatus',
+ 'GMP::ProgressWindow::FreezeLine','GMP::ProgressWindow::UnfreezeLine',
+ 'GMP::QuadraticCoefficient::Get','GMP::QuadraticCoefficient::Set','GMP::Row::Activate',
+ 'GMP::Stochastic::AddBendersFeasibilityCut','GMP::Stochastic::AddBendersOptimalityCut',
+ 'GMP::Stochastic::BendersFindFeasibilityReference','GMP::Stochastic::MergeSolution',
+ 'GMP::Row::Add','GMP::Row::Deactivate','GMP::Row::Delete','GMP::Row::DeleteIndicatorCondition',
+ 'GMP::Row::Generate','GMP::Row::GetConvex','GMP::Row::GetIndicatorColumn',
+ 'GMP::Row::GetIndicatorCondition','GMP::Row::GetLeftHandSide','GMP::Row::GetRelaxationOnly',
+ 'GMP::Row::GetRightHandSide','GMP::Row::GetScale','GMP::Row::GetStatus','GMP::Row::GetType',
+ 'GMP::Row::SetConvex','GMP::Row::SetIndicatorCondition','GMP::Row::SetLeftHandSide',
+ 'GMP::Row::SetRelaxationOnly','GMP::Row::SetRightHandSide','GMP::Row::SetType',
+ 'GMP::Solution::Check','GMP::Solution::Copy','GMP::Solution::Count','GMP::Solution::Delete',
+ 'GMP::Solution::DeleteAll','GMP::Solution::GetColumnValue','GMP::Solution::GetCPUSecondsUsed',
+ 'GMP::Solution::GetDistance','GMP::Solution::GetFirstOrderDerivative',
+ 'GMP::Solution::GetIterationsUsed','GMP::Solution::GetNodesUsed','GMP::Solution::GetLinearObjective',
+ 'GMP::Solution::GetMemoryUsed','GMP::Solution::GetObjective','GMP::Solution::GetPenalizedObjective',
+ 'GMP::Solution::GetProgramStatus','GMP::Solution::GetRowValue','GMP::Solution::GetSolutionsSet',
+ 'GMP::Solution::GetSolverStatus','GMP::Solution::IsDualDegenerated','GMP::Solution::IsInteger',
+ 'GMP::Solution::IsPrimalDegenerated','GMP::Solution::SetMIPStartFlag','GMP::Solution::Move',
+ 'GMP::Solution::RandomlyGenerate','GMP::Solution::RetrieveFromModel',
+ 'GMP::Solution::RetrieveFromSolverSession','GMP::Solution::SendToModel',
+ 'GMP::Solution::SendToModelSelection','GMP::Solution::SendToSolverSession',
+ 'GMP::Solution::SetIterationCount','GMP::Solution::SetProgramStatus','GMP::Solution::SetSolverStatus',
+ 'GMP::Solution::UpdatePenaltyWeights','GMP::Solution::ConstructMean',
+ 'GMP::SolverSession::AsynchronousExecute','GMP::SolverSession::Execute',
+ 'GMP::SolverSession::Interrupt','GMP::SolverSession::AddLinearization',
+ 'GMP::SolverSession::GenerateBranchLowerBound','GMP::SolverSession::GenerateBranchUpperBound',
+ 'GMP::SolverSession::GenerateBranchRow','GMP::SolverSession::GenerateCut',
+ 'GMP::SolverSession::GenerateBinaryEliminationRow','GMP::SolverSession::GetCPUSecondsUsed',
+ 'GMP::SolverSession::GetHost','GMP::SolverSession::GetInstance',
+ 'GMP::SolverSession::GetIterationsUsed','GMP::SolverSession::GetNodesLeft',
+ 'GMP::SolverSession::GetNodesUsed','GMP::SolverSession::GetNodeNumber',
+ 'GMP::SolverSession::GetNodeObjective','GMP::SolverSession::GetNumberOfBranchNodes',
+ 'GMP::SolverSession::GetLinearObjective','GMP::SolverSession::GetMemoryUsed',
+ 'GMP::SolverSession::GetObjective','GMP::SolverSession::GetOptionValue',
+ 'GMP::SolverSession::GetProgramStatus','GMP::SolverSession::GetSolver',
+ 'GMP::SolverSession::GetSolverStatus','GMP::SolverSession::RejectIncumbent',
+ 'GMP::Event::Create','GMP::Event::Delete','GMP::Event::Reset','GMP::Event::Set',
+ 'GMP::SolverSession::SetObjective','GMP::SolverSession::SetOptionValue',
+ 'GMP::Instance::SetCPUSecondsLimit','GMP::Instance::SetIterationLimit',
+ 'GMP::Instance::SetMemoryLimit','GMP::Instance::SetOptionValue','GMP::Tuning::SolveSingleMPS',
+ 'GMP::Tuning::TuneMultipleMPS','GMP::Tuning::TuneSingleGMP',
+ 'GMP::Solver::GetAsynchronousSessionsLimit','GMP::Robust::EvaluateAdjustableVariables',
+ 'GenerateXML','GetDatasourceProperty','ReadGeneratedXML','ReadXML','ReferencedIdentifiers',
+ 'WriteXML','IdentifierAttributes','IdentifierDimension','IsRuntimeIdentifier','IdentifierMemory',
+ 'IdentifierMemoryStatistics','IdentifierText','IdentifierType','IdentifierUnit','ScalarValue',
+ 'SectionIdentifiers','SubRange','MemoryInUse','CommitTransaction','RollbackTransaction',
+ 'MemoryStatistics','me::AllowedAttribute','me::ChangeType','me::ChangeTypeAllowed','me::Children',
+ 'me::ChildTypeAllowed','me::Compile','me::Create','me::CreateLibrary','me::Delete','me::ExportNode',
+ 'me::GetAttribute','me::ImportLibrary','me::ImportNode','me::IsRunnable','me::Move','me::Parent',
+ 'me::Rename','me::SetAttribute','MomentToString','MomentToTimeSlot','OptionGetValue',
+ 'OptionGetKeywords','OptionGetString','OptionSetString','OptionSetValue','PeriodToString',
+ 'ProfilerContinue','ProfilerPause','ProfilerRestart','RestoreInactiveElements',
+ 'RetrieveCurrentVariableValues','SetAddRecursive','SetElementAdd','SetElementRename',
+ 'SQLColumnData','SQLCreateConnectionString','SQLDriverName','SQLNumberOfColumns',
+ 'SQLNumberOfDrivers','SQLNumberOfTables','SQLNumberOfViews','SQLTableName','SQLViewName',
+ 'StartTransaction','StringToElement','StringToMoment','StringToTimeSlot','TestDatabaseColumn',
+ 'TestDatabaseTable','TestDataSource','TestDate','TimeslotCharacteristic','TimeslotToMoment',
+ 'TimeslotToString','TimeZoneOffset','VariableConstraints','PageOpen','PageOpenSingle','PageClose',
+ 'PageGetActive','PageSetFocus','PageGetFocus','PageSetCursor','PageRefreshAll','PageGetChild',
+ 'PageGetParent','PageGetNext','PageGetPrevious','PageGetNextInTreeWalk','PageGetUsedIdentifiers',
+ 'PageGetTitle','PageGetAll','PageCopyTableToClipboard','PageCopyTableToExcel','PrintPage',
+ 'PrintPageCount','PrintStartReport','PrintEndReport','PivotTableReloadState','PivotTableSaveState',
+ 'PivotTableDeleteState','FileSelect','FileSelectNew','FileDelete','FileExists','FileCopy',
+ 'FileMove','FileView','FileEdit','FilePrint','FileTime','FileTouch','FileAppend','FileGetSize',
+ 'DirectorySelect','DirectoryCreate','DirectoryDelete','DirectoryExists','DirectoryCopy',
+ 'DirectoryMove','DirectoryGetCurrent','DialogProgress','DialogMessage','DialogError',
+ 'StatusMessage','DialogAsk','DialogGetString','DialogGetDate','DialogGetNumber','DialogGetElement',
+ 'DialogGetElementByText','DialogGetElementByData','DialogGetPassword','DialogGetColor','CaseNew',
+ 'CaseFind','CaseCreate','CaseLoadCurrent','CaseMerge','CaseLoadIntoCurrent','CaseSelect',
+ 'CaseSelectNew','CaseSetCurrent','CaseSave','CaseSaveAll','CaseSaveAs','CaseSelectMultiple',
+ 'CaseGetChangedStatus','CaseSetChangedStatus','CaseDelete','CaseGetType','CaseGetDatasetReference',
+ 'CaseWriteToSingleFile','CaseReadFromSingleFile','DatasetNew','DatasetFind','DatasetCreate',
+ 'DatasetLoadCurrent','DatasetMerge','DatasetLoadIntoCurrent','DatasetSelect','DatasetSelectNew',
+ 'DatasetSetCurrent','DatasetSave','DatasetSaveAll','DatasetSaveAs','DatasetGetChangedStatus',
+ 'DatasetSetChangedStatus','DatasetDelete','DatasetGetCategory','DataFileGetName',
+ 'DataFileGetAcronym','DataFileSetAcronym','DataFileGetComment','DataFileSetComment',
+ 'DataFileGetPath','DataFileGetTime','DataFileGetOwner','DataFileGetGroup','DataFileReadPermitted',
+ 'DataFileWritePermitted','DataFileExists','DataFileCopy','DataCategoryContents','CaseTypeContents',
+ 'CaseTypeCategories','Execute','OpenDocument','TestInternetConnection','GeoFindCoordinates',
+ 'ShowHelpTopic','Delay','ScheduleAt','ExitAimms','SessionArgument','SessionHasVisibleGUI',
+ 'ProjectDeveloperMode','DebuggerBreakpoint','ShowProgressWindow','ShowMessageWindow',
+ 'SolverGetControl','SolverReleaseControl','ProfilerStart','DataManagerImport','DataManagerExport',
+ 'DataManagerFileNew','DataManagerFileOpen','DataManagerFileGetCurrent','DataImport220',
+ 'SecurityGetUsers','SecurityGetGroups','UserColorAdd','UserColorDelete','UserColorGetRGB',
+ 'UserColorModify','LicenseNumber','LicenseType','LicenseStartDate','LicenseExpirationDate',
+ 'LicenseMaintenanceExpirationDate','VARLicenseExpirationDate','AimmsRevisionString',
+ 'VARLicenseCreate','HistogramCreate','HistogramDelete','HistogramSetDomain',
+ 'HistogramAddObservation','HistogramGetFrequencies','HistogramGetBounds',
+ 'HistogramGetObservationCount','HistogramGetAverage','HistogramGetDeviation',
+ 'HistogramGetSkewness','HistogramGetKurtosis','DateDifferenceDays','DateDifferenceYearFraction',
+ 'PriceFractional','PriceDecimal','RateEffective','RateNominal','DepreciationLinearLife',
+ 'DepreciationLinearRate','DepreciationNonLinearSumOfYear','DepreciationNonLinearLife',
+ 'DepreciationNonLinearFactor','DepreciationNonLinearRate','DepreciationSum',
+ 'InvestmentConstantPresentValue','InvestmentConstantFutureValue',
+ 'InvestmentConstantPeriodicPayment','InvestmentConstantInterestPayment',
+ 'InvestmentConstantPrincipalPayment','InvestmentConstantCumulativePrincipalPayment',
+ 'InvestmentConstantCumulativeInterestPayment','InvestmentConstantNumberPeriods',
+ 'InvestmentConstantRateAll','InvestmentConstantRate','InvestmentVariablePresentValue',
+ 'InvestmentVariablePresentValueInperiodic','InvestmentSingleFutureValue',
+ 'InvestmentVariableInternalRateReturnAll','InvestmentVariableInternalRateReturn',
+ 'InvestmentVariableInternalRateReturnInperiodicAll','InvestmentVariableInternalRateReturnInperiodic',
+ 'InvestmentVariableInternalRateReturnModified','SecurityDiscountedPrice',
+ 'SecurityDiscountedRedemption','SecurityDiscountedYield','SecurityDiscountedRate',
+ 'TreasuryBillPrice','TreasuryBillYield','TreasuryBillBondEquivalent','SecurityMaturityPrice',
+ 'SecurityMaturityCouponRate','SecurityMaturityYield','SecurityMaturityAccruedInterest',
+ 'SecurityCouponNumber','SecurityCouponPreviousDate','SecurityCouponNextDate','SecurityCouponDays',
+ 'SecurityCouponDaysPreSettlement','SecurityCouponDaysPostSettlement','SecurityPeriodicPrice',
+ 'SecurityPeriodicRedemption','SecurityPeriodicCouponRate','SecurityPeriodicYieldAll',
+ 'SecurityPeriodicYield','SecurityPeriodicAccruedInterest','SecurityPeriodicDuration',
+ 'SecurityPeriodicDurationModified','Abs','AtomicUnit','Ceil','Character','CharacterNumber','Cube',
+ 'Degrees','Div','Exp','FileRead','Floor','Log','Log10','Mapval','Max','Min','Mod','Power',
+ 'Radians','Round','Sign','Sqr','Sqrt','StringCapitalize','StringLength','StringToLower',
+ 'StringToUnit','StringToUpper','SubString','Trunc','Binomial','NegativeBinomial','Poisson',
+ 'Geometric','HyperGeometric','Uniform','Normal','LogNormal','Triangular','Exponential','Weibull',
+ 'Beta','Gamma','Logistic','Pareto','ExtremeValue','Precision','Factorial','Combination',
+ 'Permutation','Errorf','Cos','Sin','Tan','ArcCos','ArcSin','ArcTan','Cosh','Sinh','Tanh',
+ 'ArcCosh','ArcSinh','ArcTanh'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '(', ')', '[', ']', '{', '}',
+ '%', '&', '|', '/',
+ '<', '>', '>=' , '<=', ':=',
+ '=', '-', '+', '*',
+ '.', ','
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #404040;',
+ 4 => 'color: #990000; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #808080; font-style: italic ',
+ 'HARD' => 'color: #808080; font-style: italic'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000; font-style: italic;',
+ 'MULTI' => 'color: #008000; font-style: italic;'
+ ),
+
+ 'METHODS' => array(
+ 1 => 'color: #004000;',
+ 2 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;',
+ 1 => 'color: #000000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'ESCAPE_CHAR' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/algol68.php b/platform/www/vendor/geshi/geshi/src/geshi/algol68.php
new file mode 100644
index 0000000..956d35c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/algol68.php
@@ -0,0 +1,328 @@
+<?php
+/*************************************************************************************
+ * algol68.php
+ * --------
+ * Author: Neville Dempsey (NevilleD.sourceforge@sgr-a.net)
+ * Copyright: (c) 2010 Neville Dempsey (https://sourceforge.net/projects/algol68/files/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/04/24
+ *
+ * ALGOL 68 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/04/24 (1.0.8.8.0)
+ * - First Release - machine generated by http://rosettacode.org/geshi/
+ * 2010/05/24 (1.0.8.8.1)
+ * - #2324 - converted comment detection to RegEx
+ * 2010/06/16 (1.0.8.8.2)
+ * - separate symbols from keywords - quick fix
+ * 2010/06/16 (1.0.8.8.3)
+ * - reverse length order symbols
+ * - Add RegEx for BITS and REAL literals (INT to do)
+ * - recognise LONG and SHORT prefixes to literals
+ * 2010/07/23 (1.0.8.8.4)
+ * - fix errors detected by langcheck.php, eg rm tab, fix indenting, rm duplicate keywords, fix symbols as keywords etc
+ * - removed bulk of local variables from name space.
+ * - unfolded arrays
+ *
+ * TODO (updated yyyy/mm/dd)
+ * -------------------------
+ * - Use "Parser Control" to fix KEYWORD parsing, eg: (INT minus one= -1; print(ABSminus one))
+ * - Parse $FORMATS$ more fully - if possible.
+ * - Pull reserved words from the source of A68G and A68RS
+ * - Pull stdlib PROC/OP/MODE symbols from the soruce of A68G and A68RS
+ * - Pull PROC/OP/MODE extensions from the soruce of A68G and A68RS
+ * - Use RegEx to detect extended precision PROC names, eg 'long long sin' etc
+ * - Use RegEx to detect white space std PROC names, eg 'new line'
+ * - Use RegEx to detect white space ext PROC names, eg 'cgs speed of light'
+ * - Use RegEx to detect BOLD symbols, eg userdefined MODEs and OPs
+ * - Add REgEx for INT literals - Adding INT breaks formatting...
+ * - Adding PIPE as a key word breaks formatting of "|" symbols!!
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+if(!function_exists('geshi_langfile_algol68_vars')) {
+ function geshi_langfile_algol68_vars(){
+ $pre='(?<![0-9a-z_\.])';
+ $post='?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)';
+ $post=""; # assuming the RegEx is greedy #
+
+ $_="\s*";
+
+ $srad="Rr"; $rrad="[".$srad."]"; # either one digit, OR opt-space in digits #
+ $sbin="0-1"; $rbin="[".$sbin."]"; $_bin=$rbin."(?:[".$sbin."\s]*".$rbin."|)";
+ $snib="0-3"; $rnib="[".$snib."]"; $_nib=$rnib."(?:[".$snib."\s]*".$rnib."|)";
+ $soct="0-7"; $roct="[".$soct."]"; $_oct=$roct."(?:[".$soct."\s]*".$roct."|)";
+ $sdec="0-9"; $rdec="[".$sdec."]"; $_dec=$rdec."(?:[".$sdec."\s]*".$rdec."|)";
+ $shex="0-9A-Fa-f"; $rhex="[".$shex."]"; $_hex=$rhex."(?:[".$shex."\s]*".$rhex."|)";
+
+ # Define BITS: #
+ $prebits=$pre; $postbits=$post;
+ $bl="2".$_.$rrad.$_.$_bin;
+ $bl=$bl."|"."2".$_.$rrad.$_.$_bin;
+ $bl=$bl."|"."4".$_.$rrad.$_.$_nib;
+ $bl=$bl."|"."8".$_.$rrad.$_.$_oct;
+ $bl=$bl."|"."1".$_."0".$_.$rrad.$_.$_dec;
+ $bl=$bl."|"."1".$_."6".$_.$rrad.$_.$_hex;
+
+ # Define INT: #
+ $preint=$pre; $postint=$post;
+ # for some reason ".0 e - 2" is not recognised, but ".0 e + 2" IS!
+ # work around: remove spaces between sign and digits! Maybe because
+ # of the Unary '-' Operator
+ $sign_="(?:-|\-|[-]|[\-]|\+|)"; # attempts # // FIXME: This should be used or removed. Assignment beneath
+
+ $sign_="(?:-\s*|\+\s*|)"; # n.b. sign is followed by white space #
+
+ $_int=$sign_.$_dec;
+ $il= $_int; # +_9 #
+
+ //$GESHI_NUMBER_INT_BASIC='(?:(?<![0-9a-z_\.%])|(?<=\.\.))(?<![\d\.]e[+\-])([1-9]\d*?|0)(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)';
+
+ # Define REAL: #
+ $prereal=$pre; $postreal=$post;
+ $sexp="Ee\\\\"; $_exp="(?:â¨|[".$sexp."])".$_.$_int;
+ $_decimal="[.]".$_.$_dec;
+
+ # Add permitted permutations of various parts #
+ $rl= $_int.$_.$_decimal.$_.$_exp; # +_9_._9_e_+_9 #
+ $rl=$rl."|".$_int.$_."[.]".$_.$_exp; # +_9_.___e_+_9 #
+ $rl=$rl."|".$_int.$_.$_exp; # +_9_____e_+_9 #
+ $rl=$rl."|".$sign_.$_decimal.$_.$_exp; # +___._9_e_+_9 #
+
+ $rl=$rl."|".$_int.$_.$_decimal; # +_9_._9 #
+ $rl=$rl."|".$sign_.$_decimal; # +___._9 #
+
+ # The following line damaged formatting...
+ #$rl=$rl."|".$_int; # +_9 #
+
+ # Apparently Algol68 does not support '2.', c.f. Algol 68G
+ #$rl=$rl."|".$_int.$_."[.]"; # +_9_. #
+
+ # Literal prefixes are overridden by KEYWORDS :-(
+ $LONGS="(?:(?:(LONG\s+)*|(SHORT\s+))*|)";
+
+ return array(
+ "BITS" => $prebits.$LONGS."(?:".$bl.")".$postbits,
+ "INT" => $preint.$LONGS."(?:".$il.")".$postint,
+ "REAL" => $prereal.$LONGS."(?:".$rl.")".$postreal,
+
+ "BOLD" => 'color: #b1b100; font-weight: bold;',
+ "ITALIC" => 'color: #b1b100;', # procedures traditionally italic #
+ "NONSTD" => 'color: #FF0000; font-weight: bold;', # RED #
+ "COMMENT" => 'color: #666666; font-style: italic;'
+ );
+ }
+}
+$a68=geshi_langfile_algol68_vars();
+
+$language_data = array(
+ 'LANG_NAME' => 'ALGOL 68',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(
+ '¢' => '¢',
+ '£' => '£',
+ '#' => '#',
+ ),
+ 'COMMENT_REGEXP' => array(
+ 1 => '/\bCO((?:MMENT)?)\b.*?\bCO\\1\b/i',
+ 2 => '/\bPR((?:AGMAT)?)\b.*?\bPR\\1\b/i',
+ 3 => '/\bQUOTE\b.*?\bQUOTE\b/i'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '"',
+ 'NUMBERS' => GESHI_NUMBER_HEX_SUFFIX, # Warning: Feature!! #
+# GESHI_NUMBER_HEX_SUFFIX, # Attempt ignore default #
+ 'KEYWORDS' => array(
+# Extensions
+ 1 => array('KEEP', 'FINISH', 'USE', 'SYSPROCS', 'IOSTATE', 'USING', 'ENVIRON', 'PROGRAM', 'CONTEXT'),
+# 2 => array('CASE', 'IN', 'OUSE', 'IN', 'OUT', 'ESAC', '(', '|', '|:', ')', 'FOR', 'FROM', 'TO', 'BY', 'WHILE', 'DO', 'OD', 'IF', 'THEN', 'ELIF', 'THEN', 'ELSE', 'FI', 'PAR', 'BEGIN', 'EXIT', 'END', 'GO', 'GOTO', 'FORALL', 'UPTO', 'DOWNTO', 'FOREACH', 'ASSERT'), #
+ 2 => array('CASE', 'IN', 'OUSE', /* 'IN',*/ 'OUT', 'ESAC', 'PAR', 'BEGIN', 'EXIT', 'END', 'GO TO', 'GOTO', 'FOR', 'FROM', 'TO', 'BY', 'WHILE', 'DO', 'OD', 'IF', 'THEN', 'ELIF', /* 'THEN',*/ 'ELSE', 'FI' ),
+ 3 => array('BITS', 'BOOL', 'BYTES', 'CHAR', 'COMPL', 'INT', 'REAL', 'SEMA', 'STRING', 'VOID'),
+ 4 => array('MODE', 'OP', 'PRIO', 'PROC', 'FLEX', 'HEAP', 'LOC', 'REF', 'LONG', 'SHORT', 'EITHER'),
+# Extensions or deprecated keywords
+# 'PIPE': keyword somehow interferes with the internal operation of GeSHi
+ 5 => array('FORALL', 'UPTO', 'DOWNTO', 'FOREACH', 'ASSERT', 'CTB', 'CT', 'CTAB', 'COMPLEX', 'VECTOR', 'SOUND' /*, 'PIPE'*/),
+ 6 => array('CHANNEL', 'FILE', 'FORMAT', 'STRUCT', 'UNION', 'OF'),
+# '(', '|', '|:', ')', #
+# 7 => array('OF', 'AT', '@', 'IS', ':=:', 'ISNT', ':/=:', ':≠:', 'CTB', 'CT', '::', 'CTAB', '::=', 'TRUE', 'FALSE', 'EMPTY', 'NIL', '○', 'SKIP', '~'),
+ 7 => array('AT', 'IS', 'ISNT', 'TRUE', 'FALSE', 'EMPTY', 'NIL', 'SKIP'),
+ 8 => array('NOT', 'UP', 'DOWN', 'LWB', 'UPB', /* '-',*/ 'ABS', 'ARG', 'BIN', 'ENTIER', 'LENG', 'LEVEL', 'ODD', 'REPR', 'ROUND', 'SHORTEN', 'CONJ', 'SIGN'),
+# OPERATORS ordered roughtly by PRIORITY #
+# 9 => array('¬', '↑', '↓', '⌊', '⌈', '~', '⎩', '⎧'),
+# 10 => array('+*', 'I', '+×', '⊥', '!', 'â¨'),
+ 10 => array('I'),
+# 11 => array('SHL', 'SHR', '**', 'UP', 'DOWN', 'LWB', 'UPB', '↑', '↓', '⌊', '⌈', '⎩', '⎧'),
+ 11 => array('SHL', 'SHR', /*'UP', 'DOWN', 'LWB', 'UPB'*/),
+# 12 => array('*', '/', '%', 'OVER', '%*', 'MOD', 'ELEM', '×', '÷', '÷×', '÷*', '%×', '□', '÷:'),
+ 12 => array('OVER', 'MOD', 'ELEM'),
+# 13 => array('-', '+'),
+# 14 => array('<', 'LT', '<=', 'LE', '>=', 'GE', '>', 'GT', '≤', '≥'),
+ 14 => array('LT', 'LE', 'GE', 'GT'),
+# 15 => array('=', 'EQ', '/=', 'NE', '≠', '~='),
+ 15 => array('EQ', 'NE'),
+# 16 => array('&', 'AND', '∧', 'OR', '∨', '/\\', '\\/'),
+ 16 => array('AND', 'OR'),
+ 17 => array('MINUSAB', 'PLUSAB', 'TIMESAB', 'DIVAB', 'OVERAB', 'MODAB', 'PLUSTO'),
+# 18 => array('-:=', '+:=', '*:=', '/:=', '%:=', '%*:=', '+=:', '×:=', '÷:=', '÷×:=', '÷*:=', '%×:=', '÷::=', 'MINUS', 'PLUS', 'DIV', 'MOD', 'PRUS'),
+# Extensions or deprecated keywords
+ 18 => array('MINUS', 'PLUS', 'DIV', /* 'MOD',*/ 'PRUS', 'IS NOT'),
+# Extensions or deprecated keywords
+ 19 => array('THEF', 'ANDF', 'ORF', 'ANDTH', 'OREL', 'ANDTHEN', 'ORELSE'),
+# Built in procedures - from standard prelude #
+ 20 => array('int lengths', 'intlengths', 'int shorths', 'intshorths', 'max int', 'maxint', 'real lengths', 'reallengths', 'real shorths', 'realshorths', 'bits lengths', 'bitslengths', 'bits shorths', 'bitsshorths', 'bytes lengths', 'byteslengths', 'bytes shorths', 'bytesshorths', 'max abs char', 'maxabschar', 'int width', 'intwidth', 'long int width', 'longintwidth', 'long long int width', 'longlongintwidth', 'real width', 'realwidth', 'long real width', 'longrealwidth', 'long long real width', 'longlongrealwidth', 'exp width', 'expwidth', 'long exp width', 'longexpwidth', 'long long exp width', 'longlongexpwidth', 'bits width', 'bitswidth', 'long bits width', 'longbitswidth', 'long long bits width', 'longlongbitswidth', 'bytes width', 'byteswidth', 'long bytes width', 'longbyteswidth', 'max real', 'maxreal', 'small real', 'smallreal', 'long max int', 'longmaxint', 'long long max int', 'longlongmaxint', 'long max real', 'longmaxreal', 'long small real', 'longsmallreal', 'long long max real', 'longlongmaxreal', 'long long small real', 'longlongsmallreal', 'long max bits', 'longmaxbits', 'long long max bits', 'longlongmaxbits', 'null character', 'nullcharacter', 'blank', 'flip', 'flop', 'error char', 'errorchar', 'exp char', 'expchar', 'newline char', 'newlinechar', 'formfeed char', 'formfeedchar', 'tab char', 'tabchar'),
+ 21 => array('stand in channel', 'standinchannel', 'stand out channel', 'standoutchannel', 'stand back channel', 'standbackchannel', 'stand draw channel', 'standdrawchannel', 'stand error channel', 'standerrorchannel'),
+ 22 => array('put possible', 'putpossible', 'get possible', 'getpossible', 'bin possible', 'binpossible', 'set possible', 'setpossible', 'reset possible', 'resetpossible', 'reidf possible', 'reidfpossible', 'draw possible', 'drawpossible', 'compressible', 'on logical file end', 'onlogicalfileend', 'on physical file end', 'onphysicalfileend', 'on line end', 'onlineend', 'on page end', 'onpageend', 'on format end', 'onformatend', 'on value error', 'onvalueerror', 'on open error', 'onopenerror', 'on transput error', 'ontransputerror', 'on format error', 'onformaterror', 'open', 'establish', 'create', 'associate', 'close', 'lock', 'scratch', 'space', 'new line', 'newline', 'print', 'write f', 'writef', 'print f', 'printf', 'write bin', 'writebin', 'print bin', 'printbin', 'read f', 'readf', 'read bin', 'readbin', 'put f', 'putf', 'get f', 'getf', 'make term', 'maketerm', 'make device', 'makedevice', 'idf', 'term', 'read int', 'readint', 'read long int', 'readlongint', 'read long long int', 'readlonglongint', 'read real', 'readreal', 'read long real', 'readlongreal', 'read long long real', 'readlonglongreal', 'read complex', 'readcomplex', 'read long complex', 'readlongcomplex', 'read long long complex', 'readlonglongcomplex', 'read bool', 'readbool', 'read bits', 'readbits', 'read long bits', 'readlongbits', 'read long long bits', 'readlonglongbits', 'read char', 'readchar', 'read string', 'readstring', 'print int', 'printint', 'print long int', 'printlongint', 'print long long int', 'printlonglongint', 'print real', 'printreal', 'print long real', 'printlongreal', 'print long long real', 'printlonglongreal', 'print complex', 'printcomplex', 'print long complex', 'printlongcomplex', 'print long long complex', 'printlonglongcomplex', 'print bool', 'printbool', 'print bits', 'printbits', 'print long bits', 'printlongbits', 'print long long bits', 'printlonglongbits', 'print char', 'printchar', 'print string', 'printstring', 'whole', 'fixed', 'float'),
+ 23 => array('pi', 'long pi', 'longpi', 'long long pi', 'longlongpi'),
+ 24 => array('sqrt', 'curt', 'cbrt', 'exp', 'ln', 'log', 'sin', 'arc sin', 'arcsin', 'cos', 'arc cos', 'arccos', 'tan', 'arc tan', 'arctan', 'long sqrt', 'longsqrt', 'long curt', 'longcurt', 'long cbrt', 'longcbrt', 'long exp', 'longexp', 'long ln', 'longln', 'long log', 'longlog', 'long sin', 'longsin', 'long arc sin', 'longarcsin', 'long cos', 'longcos', 'long arc cos', 'longarccos', 'long tan', 'longtan', 'long arc tan', 'longarctan', 'long long sqrt', 'longlongsqrt', 'long long curt', 'longlongcurt', 'long long cbrt', 'longlongcbrt', 'long long exp', 'longlongexp', 'long long ln', 'longlongln', 'long long log', 'longlonglog', 'long long sin', 'longlongsin', 'long long arc sin', 'longlongarcsin', 'long long cos', 'longlongcos', 'long long arc cos', 'longlongarccos', 'long long tan', 'longlongtan', 'long long arc tan', 'longlongarctan'),
+ 25 => array('first random', 'firstrandom', 'next random', 'nextrandom', 'long next random', 'longnextrandom', 'long long next random', 'longlongnextrandom'),
+ 26 => array('real', 'bits pack', 'bitspack', 'long bits pack', 'longbitspack', 'long long bits pack', 'longlongbitspack', 'bytes pack', 'bytespack', 'long bytes pack', 'longbytespack', 'char in string', 'charinstring', 'last char in string', 'lastcharinstring', 'string in string', 'stringinstring'),
+ 27 => array('utc time', 'utctime', 'local time', 'localtime', 'argc', 'argv', 'get env', 'getenv', 'reset errno', 'reseterrno', 'errno', 'strerror'),
+ 28 => array('sinh', 'long sinh', 'longsinh', 'long long sinh', 'longlongsinh', 'arc sinh', 'arcsinh', 'long arc sinh', 'longarcsinh', 'long long arc sinh', 'longlongarcsinh', 'cosh', 'long cosh', 'longcosh', 'long long cosh', 'longlongcosh', 'arc cosh', 'arccosh', 'long arc cosh', 'longarccosh', 'long long arc cosh', 'longlongarccosh', 'tanh', 'long tanh', 'longtanh', 'long long tanh', 'longlongtanh', 'arc tanh', 'arctanh', 'long arc tanh', 'longarctanh', 'long long arc tanh', 'longlongarctanh', 'arc tan2', 'arctan2', 'long arc tan2', 'longarctan2', 'long long arc tan2', 'longlongarctan2'),
+ 29 => array('complex sqrt', 'complexsqrt', 'long complex sqrt', 'longcomplexsqrt', 'long long complex sqrt', 'longlongcomplexsqrt', 'complex exp', 'complexexp', 'long complex exp', 'longcomplexexp', 'long long complex exp', 'longlongcomplexexp', 'complex ln', 'complexln', 'long complex ln', 'longcomplexln', 'long long complex ln', 'longlongcomplexln', 'complex sin', 'complexsin', 'long complex sin', 'longcomplexsin', 'long long complex sin', 'longlongcomplexsin', 'complex arc sin', 'complexarcsin', 'long complex arc sin', 'longcomplexarcsin', 'long long complex arc sin', 'longlongcomplexarcsin', 'complex cos', 'complexcos', 'long complex cos', 'longcomplexcos', 'long long complex cos', 'longlongcomplexcos', 'complex arc cos', 'complexarccos', 'long complex arc cos', 'longcomplexarccos', 'long long complex arc cos', 'longlongcomplexarccos', 'complex tan', 'complextan', 'long complex tan', 'longcomplextan', 'long long complex tan', 'longlongcomplextan', 'complex arc tan', 'complexarctan', 'long complex arc tan', 'longcomplexarctan', 'long long complex arc tan', 'longlongcomplexarctan', 'complex sinh', 'complexsinh', 'complex arc sinh', 'complexarcsinh', 'complex cosh', 'complexcosh', 'complex arc cosh', 'complexarccosh', 'complex tanh', 'complextanh', 'complex arc tanh', 'complexarctanh')
+ ),
+ 'SYMBOLS' => array(
+ 1 => array( /* reverse length sorted... */ '÷×:=', '%×:=', ':≠:', '÷*:=', '÷::=', '%*:=', ':/=:', '×:=', '÷:=', '÷×', '%:=', '%×', '*:=', '+:=', '+=:', '+×', '-:=', '/:=', '::=', ':=:', '÷*', '÷:', '↑', '↓', '∧', '∨', '≠', '≤', '≥', '⊥', '⌈', '⌊', '⎧', '⎩', /* 'â¨', */ 'â–¡', 'â—‹', '%*', '**', '+*', '/=', '::', '/\\', '\\/', '<=', '>=', '|:', '~=', '¬', '×', '÷', '!', '%', '&', '(', ')', '*', '+', ',', '-', '/', ':', ';', '<', '=', '>', '?', '@', '[', ']', '^', '{', '|', '}', '~')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+# 9 => true,
+ 10 => true,
+ 11 => true,
+ 12 => true,
+# 13 => true,
+ 14 => true,
+ 15 => true,
+ 16 => true,
+ 17 => true,
+ 18 => true,
+ 19 => true,
+ 20 => true,
+ 21 => true,
+ 22 => true,
+ 23 => true,
+ 24 => true,
+ 25 => true,
+ 26 => true,
+ 27 => true,
+ 28 => true,
+ 29 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => $a68['NONSTD'], 2 => $a68['BOLD'], 3 => $a68['BOLD'], 4 => $a68['BOLD'],
+ 5 => $a68['NONSTD'], 6 => $a68['BOLD'], 7 => $a68['BOLD'], 8 => $a68['BOLD'],
+ /* 9 => $a68['BOLD'],*/ 10 => $a68['BOLD'], 11 => $a68['BOLD'], 12 => $a68['BOLD'],
+ /* 13 => $a68['BOLD'],*/ 14 => $a68['BOLD'], 15 => $a68['BOLD'], 16 => $a68['BOLD'], 17 => $a68['BOLD'],
+ 18 => $a68['NONSTD'], 19 => $a68['NONSTD'],
+ 20 => $a68['ITALIC'], 21 => $a68['ITALIC'], 22 => $a68['ITALIC'], 23 => $a68['ITALIC'],
+ 24 => $a68['ITALIC'], 25 => $a68['ITALIC'], 26 => $a68['ITALIC'], 27 => $a68['ITALIC'],
+ 28 => $a68['ITALIC'], 29 => $a68['ITALIC']
+ ),
+ 'COMMENTS' => array(
+ 1 => $a68['COMMENT'], 2 => $a68['COMMENT'], 3 => $a68['COMMENT'], /* 4 => $a68['COMMENT'],
+ 5 => $a68['COMMENT'],*/ 'MULTI' => $a68['COMMENT']
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;',
+ 1 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;',
+ 1 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #cc66cc;', # BITS #
+ 1 => 'color: #cc66cc;', # REAL #
+ /* 2 => 'color: #cc66cc;', # INT # */
+ ),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+# 9 => '',
+ 10 => '',
+ 11 => '',
+ 12 => '',
+# 13 => '',
+ 14 => '',
+ 15 => '',
+ 16 => '',
+ 17 => '',
+ 18 => '',
+ 19 => '',
+ 20 => '',
+ 21 => '',
+ 22 => '',
+ 23 => '',
+ 24 => '',
+ 25 => '',
+ 26 => '',
+ 27 => '',
+ 28 => '',
+ 29 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 0 => '→',
+ 1 => 'OF'
+ ),
+ 'REGEXPS' => array(
+ 0 => $a68['BITS'],
+ 1 => $a68['REAL']
+ # 2 => $a68['INT'], # Breaks formatting for some reason #
+ # 2 => $GESHI_NUMBER_INT_BASIC # Also breaks formatting #
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
+
+unset($a68);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/apache.php b/platform/www/vendor/geshi/geshi/src/geshi/apache.php
new file mode 100644
index 0000000..8db1b9a
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/apache.php
@@ -0,0 +1,481 @@
+<?php
+/*************************************************************************************
+ * apache.php
+ * ----------
+ * Author: Tux (tux@inmail.cz)
+ * Copyright: (c) 2004 Tux (http://tux.a4.cz/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/29/07
+ *
+ * Apache language file for GeSHi.
+ * Words are from SciTe configuration file
+ *
+ * CHANGES
+ * -------
+ * 2008/17/06 (1.0.8)
+ * - Added support for apache configuration sections (milian)
+ * - Added missing php keywords (milian)
+ * - Added some more keywords
+ * - Disabled highlighting of brackets by default
+ * 2004/11/27 (1.0.2)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ * - Added support for URLs
+ * 2004/08/05 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/07/29)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Apache configuration',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ /*keywords*/
+ 1 => array(
+ //core.c
+ 'AcceptFilter','AcceptPathInfo','AccessConfig','AccessFileName',
+ 'AddDefaultCharset','AddOutputFilterByType','AllowEncodedSlashes',
+ 'AllowOverride','AuthName','AuthType','ContentDigest',
+ 'CoreDumpDirectory','DefaultType','DocumentRoot','EnableMMAP',
+ 'EnableSendfile','ErrorDocument','ErrorLog','FileETag','ForceType',
+ 'HostnameLookups','Include','LimitInternalRecursion',
+ 'LimitRequestBody','LimitRequestFields','LimitRequestFieldsize',
+ 'LimitRequestLine','LimitXMLRequestBody','LogLevel','MaxMemFree',
+ 'MaxRequestsPerChild','NameVirtualHost','Options','PidFile','Port',
+ 'Protocol','Require','RLimitCPU','RLimitMEM','RLimitNPROC',
+ 'Satisfy','ScoreBoardFile','ServerAdmin','ServerAlias','ServerName',
+ 'ServerPath','ServerRoot','ServerSignature','ServerTokens',
+ 'SetHandler','SetInputFilter','SetOutputFilter','ThreadStackSize',
+ 'Timeout','TraceEnable','UseCanonicalName',
+ 'UseCanonicalPhysicalPort',
+
+ //http_core.c
+ 'KeepAlive','KeepAliveTimeout','MaxKeepAliveRequests',
+
+ //mod_actions.c
+ 'Action','Script',
+
+ //mod_alias.c
+ 'Alias','AliasMatch','Redirect','RedirectMatch','RedirectPermanent',
+ 'RedirectTemp','ScriptAlias','ScriptAliasMatch',
+
+ //mod_asis.c
+
+ //mod_auth_basic.c
+ 'AuthBasicAuthoritative','AuthBasicProvider',
+
+ //mod_auth_digest.c
+ 'AuthDigestAlgorithm','AuthDigestDomain','AuthDigestNcCheck',
+ 'AuthDigestNonceFormat','AuthDigestNonceLifetime',
+ 'AuthDigestProvider','AuthDigestQop','AuthDigestShmemSize',
+
+ //mod_authn_alias.c
+
+ //mod_authn_anon.c
+ 'Anonymous','Anonymous_LogEmail','Anonymous_MustGiveEmail',
+ 'Anonymous_NoUserId','Anonymous_VerifyEmail',
+
+ //mod_authn_dbd.c
+ 'AuthDBDUserPWQuery','AuthDBDUserRealmQuery',
+
+ //mod_authn_dbm.c
+ 'AuthDBMType','AuthDBMUserFile',
+
+ //mod_authn_default.c
+ 'AuthDefaultAuthoritative',
+
+ //mod_authn_file.c
+ 'AuthUserFile',
+
+ //mod_authnz_ldap.c
+ 'AuthLDAPBindDN','AuthLDAPBindPassword','AuthLDAPCharsetConfig',
+ 'AuthLDAPCompareDNOnServer','AuthLDAPDereferenceAliases',
+ 'AuthLDAPGroupAttribute','AuthLDAPGroupAttributeIsDN',
+ 'AuthLDAPRemoteUserAttribute','AuthLDAPRemoteUserIsDN',
+ 'AuthLDAPURL','AuthzLDAPAuthoritative',
+
+ //mod_authz_dbm.c
+ 'AuthDBMGroupFile','AuthzDBMAuthoritative','AuthzDBMType',
+
+ //mod_authz_default.c
+ 'AuthzDefaultAuthoritative',
+
+ //mod_authz_groupfile.c
+ 'AuthGroupFile','AuthzGroupFileAuthoritative',
+
+ //mod_authz_host.c
+ 'Allow','Deny','Order',
+
+ //mod_authz_owner.c
+ 'AuthzOwnerAuthoritative',
+
+ //mod_authz_svn.c
+ 'AuthzForceUsernameCase','AuthzSVNAccessFile','AuthzSVNAnonymous',
+ 'AuthzSVNAuthoritative','AuthzSVNNoAuthWhenAnonymousAllowed',
+
+ //mod_authz_user.c
+ 'AuthzUserAuthoritative',
+
+ //mod_autoindex.c
+ 'AddAlt','AddAltByEncoding','AddAltByType','AddDescription',
+ 'AddIcon','AddIconByEncoding','AddIconByType','DefaultIcon',
+ 'FancyIndexing','HeaderName','IndexHeadInsert','IndexIgnore',
+ 'IndexOptions','IndexOrderDefault','IndexStyleSheet','ReadmeName',
+
+ //mod_bt.c
+ 'Tracker','TrackerDetailURL','TrackerFlags','TrackerHashMaxAge',
+ 'TrackerHashMinAge','TrackerHashWatermark','TrackerHome',
+ 'TrackerReturnInterval','TrackerReturnMax',
+ 'TrackerReturnPeerFactor','TrackerReturnPeers','TrackerRootInclude',
+ 'TrackerStyleSheet',
+
+ //mod_bw.c
+ 'BandWidth','BandWidthError','BandWidthModule','BandWidthPacket',
+ 'ForceBandWidthModule','LargeFileLimit','MaxConnection',
+ 'MinBandWidth',
+
+ //mod_cache.c
+ 'CacheDefaultExpire','CacheDisable','CacheEnable',
+ 'CacheIgnoreCacheControl','CacheIgnoreHeaders',
+ 'CacheIgnoreNoLastMod','CacheIgnoreQueryString',
+ 'CacheLastModifiedFactor','CacheMaxExpire','CacheStoreNoStore',
+ 'CacheStorePrivate',
+
+ //mod_cern_meta.c
+ 'MetaDir','MetaFiles','MetaSuffix',
+
+ //mod_cgi.c
+ 'ScriptLog','ScriptLogBuffer','ScriptLogLength',
+
+ //mod_charset_lite.c
+ 'CharsetDefault','CharsetOptions','CharsetSourceEnc',
+
+ //mod_dav.c
+ 'DAV','DAVDepthInfinity','DAVMinTimeout',
+
+ //mod_dav_fs.c
+ 'DAVLockDB',
+
+ //mod_dav_lock.c
+ 'DAVGenericLockDB',
+
+ //mod_dav_svn.c
+ 'SVNActivitiesDB','SVNAllowBulkUpdates','SVNAutoversioning',
+ 'SVNIndexXSLT','SVNListParentPath','SVNMasterURI','SVNParentPath',
+ 'SVNPath','SVNPathAuthz','SVNReposName','SVNSpecialURI',
+
+ //mod_dbd.c
+ 'DBDExptime','DBDKeep','DBDMax','DBDMin','DBDParams','DBDPersist',
+ 'DBDPrepareSQL','DBDriver',
+
+ //mod_deflate.c
+ 'DeflateBufferSize','DeflateCompressionLevel','DeflateFilterNote',
+ 'DeflateMemLevel','DeflateWindowSize',
+
+ //mod_dir.c
+ 'DirectoryIndex','DirectorySlash',
+
+ //mod_disk_cache.c
+ 'CacheDirLength','CacheDirLevels','CacheMaxFileSize',
+ 'CacheMinFileSize','CacheRoot',
+
+ //mod_dumpio.c
+ 'DumpIOInput','DumpIOLogLevel','DumpIOOutput',
+
+ //mod_env.c
+ 'PassEnv','SetEnv','UnsetEnv',
+
+ //mod_expires.c
+ 'ExpiresActive','ExpiresByType','ExpiresDefault',
+
+ //mod_ext_filter.c
+ 'ExtFilterDefine','ExtFilterOptions',
+
+ //mod_file_cache.c
+ 'cachefile','mmapfile',
+
+ //mod_filter.c
+ 'FilterChain','FilterDeclare','FilterProtocol','FilterProvider',
+ 'FilterTrace',
+
+ //mod_gnutls.c
+ 'GnuTLSCache','GnuTLSCacheTimeout','GnuTLSCertificateFile',
+ 'GnuTLSKeyFile','GnuTLSPGPCertificateFile','GnuTLSPGPKeyFile',
+ 'GnuTLSClientVerify','GnuTLSClientCAFile','GnuTLSPGPKeyringFile',
+ 'GnuTLSEnable','GnuTLSDHFile','GnuTLSRSAFile','GnuTLSSRPPasswdFile',
+ 'GnuTLSSRPPasswdConfFile','GnuTLSPriorities',
+ 'GnuTLSExportCertificates',
+
+ //mod_headers.c
+ 'Header','RequestHeader',
+
+ //mod_imagemap.c
+ 'ImapBase','ImapDefault','ImapMenu',
+
+ //mod_include.c
+ 'SSIAccessEnable','SSIEndTag','SSIErrorMsg','SSIStartTag',
+ 'SSITimeFormat','SSIUndefinedEcho','XBitHack',
+
+ //mod_ident.c
+ 'IdentityCheck','IdentityCheckTimeout',
+
+ //mod_info.c
+ 'AddModuleInfo',
+
+ //mod_isapi.c
+ 'ISAPIAppendLogToErrors','ISAPIAppendLogToQuery','ISAPICacheFile',
+ 'ISAPIFakeAsync','ISAPILogNotSupported','ISAPIReadAheadBuffer',
+
+ //mod_log_config.c
+ 'BufferedLogs','CookieLog','CustomLog','LogFormat','TransferLog',
+
+ //mod_log_forensic.c
+ 'ForensicLog',
+
+ //mod_log_rotate.c
+ 'RotateInterval','RotateLogs','RotateLogsLocalTime',
+
+ //mod_logio.c
+
+ //mod_mem_cache.c
+ 'MCacheMaxObjectCount','MCacheMaxObjectSize',
+ 'MCacheMaxStreamingBuffer','MCacheMinObjectSize',
+ 'MCacheRemovalAlgorithm','MCacheSize',
+
+ //mod_mime.c
+ 'AddCharset','AddEncoding','AddHandler','AddInputFilter',
+ 'AddLanguage','AddOutputFilter','AddType','DefaultLanguage',
+ 'ModMimeUsePathInfo','MultiviewsMatch','RemoveCharset',
+ 'RemoveEncoding','RemoveHandler','RemoveInputFilter',
+ 'RemoveLanguage','RemoveOutputFilter','RemoveType','TypesConfig',
+
+ //mod_mime_magic.c
+ 'MimeMagicFile',
+
+ //mod_negotiation.c
+ 'CacheNegotiatedDocs','ForceLanguagePriority','LanguagePriority',
+
+ //mod_php5.c
+ 'php_admin_flag','php_admin_value','php_flag','php_value',
+ 'PHPINIDir',
+
+ //mod_proxy.c
+ 'AllowCONNECT','BalancerMember','NoProxy','ProxyBadHeader',
+ 'ProxyBlock','ProxyDomain','ProxyErrorOverride',
+ 'ProxyFtpDirCharset','ProxyIOBufferSize','ProxyMaxForwards',
+ 'ProxyPass','ProxyPassInterpolateEnv','ProxyPassMatch',
+ 'ProxyPassReverse','ProxyPassReverseCookieDomain',
+ 'ProxyPassReverseCookiePath','ProxyPreserveHost',
+ 'ProxyReceiveBufferSize','ProxyRemote','ProxyRemoteMatch',
+ 'ProxyRequests','ProxySet','ProxyStatus','ProxyTimeout','ProxyVia',
+
+ //mod_proxy_ajp.c
+
+ //mod_proxy_balancer.c
+
+ //mod_proxy_connect.c
+
+ //mod_proxy_ftp.c
+
+ //mod_proxy_http.c
+
+ //mod_rewrite.c
+ 'RewriteBase','RewriteCond','RewriteEngine','RewriteLock',
+ 'RewriteLog','RewriteLogLevel','RewriteMap','RewriteOptions',
+ 'RewriteRule',
+
+ //mod_setenvif.c
+ 'BrowserMatch','BrowserMatchNoCase','SetEnvIf','SetEnvIfNoCase',
+
+ //mod_so.c
+ 'LoadFile','LoadModule',
+
+ //mod_speling.c
+ 'CheckCaseOnly','CheckSpelling',
+
+ //mod_ssl.c
+ 'SSLCACertificateFile','SSLCACertificatePath','SSLCADNRequestFile',
+ 'SSLCADNRequestPath','SSLCARevocationFile','SSLCARevocationPath',
+ 'SSLCertificateChainFile','SSLCertificateFile',
+ 'SSLCertificateKeyFile','SSLCipherSuite','SSLCryptoDevice',
+ 'SSLEngine','SSLHonorCipherOrder','SSLMutex','SSLOptions',
+ 'SSLPassPhraseDialog','SSLProtocol','SSLProxyCACertificateFile',
+ 'SSLProxyCACertificatePath','SSLProxyCARevocationFile',
+ 'SSLProxyCARevocationPath','SSLProxyCipherSuite','SSLProxyEngine',
+ 'SSLProxyMachineCertificateFile','SSLProxyMachineCertificatePath',
+ 'SSLProxyProtocol','SSLProxyVerify','SSLProxyVerifyDepth',
+ 'SSLRandomSeed','SSLRenegBufferSize','SSLRequire','SSLRequireSSL',
+ 'SSLSessionCache','SSLSessionCacheTimeout','SSLUserName',
+ 'SSLVerifyClient','SSLVerifyDepth',
+
+ //mod_status.c
+ 'ExtendedStatus','SeeRequestTail',
+
+ //mod_substitute.c
+ 'Substitute',
+
+ //mod_suexec.c
+ 'SuexecUserGroup',
+
+ //mod_unique_id.c
+
+ //mod_upload_progress
+ 'ReportUploads', 'TrackUploads', 'UploadProgressSharedMemorySize',
+
+ //mod_userdir.c
+ 'UserDir',
+
+ //mod_usertrack.c
+ 'CookieDomain','CookieExpires','CookieName','CookieStyle',
+ 'CookieTracking',
+
+ //mod_version.c
+
+ //mod_vhost_alias.c
+ 'VirtualDocumentRoot','VirtualDocumentRootIP',
+ 'VirtualScriptAlias','VirtualScriptAliasIP',
+
+ //mod_view.c
+ 'ViewEnable',
+
+ //mod_win32.c
+ 'ScriptInterpreterSource',
+
+ //mpm_winnt.c
+ 'Listen','ListenBacklog','ReceiveBufferSize','SendBufferSize',
+ 'ThreadLimit','ThreadsPerChild','Win32DisableAcceptEx',
+
+ //mpm_common.c
+ 'AcceptMutex','AddModule','ClearModuleList','EnableExceptionHook',
+ 'Group','LockFile','MaxClients','MaxSpareServers','MaxSpareThreads',
+ 'MinSpareServers','MinSpareThreads','ServerLimit','StartServers',
+ 'StartThreads','User',
+
+ //util_ldap.c
+ 'LDAPCacheEntries','LDAPCacheTTL','LDAPConnectionTimeout',
+ 'LDAPOpCacheEntries','LDAPOpCacheTTL','LDAPSharedCacheFile',
+ 'LDAPSharedCacheSize','LDAPTrustedClientCert',
+ 'LDAPTrustedGlobalCert','LDAPTrustedMode','LDAPVerifyServerCert',
+
+ //Unknown Mods ...
+ 'AgentLog','BindAddress','bs2000account','CacheForceCompletion',
+ 'CacheGCInterval','CacheSize','NoCache','qsc','RefererIgnore',
+ 'RefererLog','Resourceconfig','ServerType','SingleListen'
+ ),
+ /*keywords 2*/
+ 2 => array(
+ 'all','on','off','standalone','inetd','indexes',
+ 'force-response-1.0','downgrade-1.0','nokeepalive',
+ 'includes','followsymlinks','none',
+ 'x-compress','x-gzip'
+ ),
+ /*keywords 3*/
+ 3 => array(
+ //core.c
+ 'Directory','DirectoryMatch','Files','FilesMatch','IfDefine',
+ 'IfModule','Limit','LimitExcept','Location','LocationMatch',
+ 'VirtualHost',
+
+ //mod_authn_alias.c
+ 'AuthnProviderAlias',
+
+ //mod_proxy.c
+ 'Proxy','ProxyMatch',
+
+ //mod_version.c
+ 'IfVersion'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '+', '-'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00007f;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #000000; font-weight:bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER,
+ 'SYMBOLS' => GESHI_NEVER
+ ),
+ 'KEYWORDS' => array(
+ 3 => array(
+ 'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+ 'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/applescript.php b/platform/www/vendor/geshi/geshi/src/geshi/applescript.php
new file mode 100644
index 0000000..c46912f
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/applescript.php
@@ -0,0 +1,155 @@
+<?php
+/*************************************************************************************
+ * applescript.php
+ * --------
+ * Author: Stephan Klimek (http://www.initware.org)
+ * Copyright: Stephan Klimek (http://www.initware.org)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/07/20
+ *
+ * AppleScript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ *
+ * TODO
+ * -------------------------
+ * URL settings to references
+ *
+ **************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'AppleScript',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array( '(*' => '*)'),
+ 'COMMENT_REGEXP' => array(
+ 2 => '/(?<=[a-z])\'/i',
+ 3 => '/(?<![a-z])\'.*?\'/i',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'application','close','count','delete','duplicate','exists','launch','make','move','open',
+ 'print','quit','reopen','run','save','saving', 'idle', 'path to', 'number', 'alias', 'list', 'text', 'string',
+ 'integer', 'it','me','version','pi','result','space','tab','anything','case','diacriticals','expansion',
+ 'hyphens','punctuation','bold','condensed','expanded','hidden','italic','outline','plain',
+ 'shadow','strikethrough','subscript','superscript','underline','ask','no','yes','false', 'id',
+ 'true','weekday','monday','mon','tuesday','tue','wednesday','wed','thursday','thu','friday',
+ 'fri','saturday','sat','sunday','sun','month','january','jan','february','feb','march',
+ 'mar','april','apr','may','june','jun','july','jul','august','aug','september', 'quote', 'do JavaScript',
+ 'sep','october','oct','november','nov','december','dec','minutes','hours', 'name', 'default answer',
+ 'days','weeks', 'folder', 'folders', 'file', 'files', 'window', 'eject', 'disk', 'reveal', 'sleep',
+ 'shut down', 'restart', 'display dialog', 'buttons', 'invisibles', 'item', 'items', 'delimiters', 'offset of',
+ 'AppleScript\'s', 'choose file', 'choose folder', 'choose from list', 'beep', 'contents', 'do shell script',
+ 'paragraph', 'paragraphs', 'missing value', 'quoted form', 'desktop', 'POSIX path', 'POSIX file',
+ 'activate', 'document', 'adding', 'receiving', 'content', 'new', 'properties', 'info for', 'bounds',
+ 'selection', 'extension', 'into', 'onto', 'by', 'between', 'against', 'set the clipboard to', 'the clipboard'
+ ),
+ 2 => array(
+ 'each','some','every','whose','where','index','first','second','third','fourth',
+ 'fifth','sixth','seventh','eighth','ninth','tenth','last','front','back','st','nd',
+ 'rd','th','middle','named','through','thru','before','after','beginning','the', 'as',
+ 'div','mod','and','not','or','contains','equal','equals','isnt', 'less', 'greater'
+ ),
+ 3 => array(
+ 'script','property','prop','end','to','set','global','local','on','of',
+ 'in','given','with','without','return','continue','tell','if','then','else','repeat',
+ 'times','while','until','from','exit','try','error','considering','ignoring','timeout',
+ 'transaction','my','get','put','is', 'copy'
+ )
+ ),
+ 'SYMBOLS' => array(
+ ')','+','-','^','*','/','&','<','>=','<','<=','=','�'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0066ff;',
+ 2 => 'color: #ff0033;',
+ 3 => 'color: #ff0033; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => '',
+ 3 => 'color: #ff0000;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000000; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #339933;',
+ 4 => 'color: #0066ff;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => ',+-=&lt;&gt;/?^&amp;*'
+ ),
+ 'REGEXPS' => array(
+ //Variables
+ 0 => '[\\$%@]+[a-zA-Z_][a-zA-Z0-9_]*',
+ //File descriptors
+ 4 => '&lt;[a-zA-Z_][a-zA-Z0-9_]*&gt;',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'SPACE_AS_WHITESPACE' => true
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/apt_sources.php b/platform/www/vendor/geshi/geshi/src/geshi/apt_sources.php
new file mode 100644
index 0000000..6e97909
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/apt_sources.php
@@ -0,0 +1,153 @@
+<?php
+/*************************************************************************************
+ * apt_sources.php
+ * ----------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff (http://milianw.de)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/06/17
+ *
+ * Apt sources.list language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/06/17 (1.0.8)
+ * - Initial import
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Apt sources',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ /*keywords*/
+ 1 => array(
+ 'deb-src', 'deb'
+ ),
+ 2 => array(
+ //Generic
+ 'stable', 'old-stable', 'testing', 'testing-proposed-updates',
+ 'unstable', 'unstable-proposed-updates', 'experimental',
+ 'non-US', 'security', 'volatile', 'volatile-sloppy',
+ 'apt-build',
+ 'stable/updates',
+ //Debian
+ 'buzz', 'rex', 'bo', 'hamm', 'slink', 'potato', 'woody', 'sarge',
+ 'etch', 'lenny', 'wheezy', 'jessie', 'sid',
+ //Ubuntu
+ 'warty', 'warty-updates', 'warty-security', 'warty-proposed', 'warty-backports',
+ 'hoary', 'hoary-updates', 'hoary-security', 'hoary-proposed', 'hoary-backports',
+ 'breezy', 'breezy-updates', 'breezy-security', 'breezy-proposed', 'breezy-backports',
+ 'dapper', 'dapper-updates', 'dapper-security', 'dapper-proposed', 'dapper-backports',
+ 'edgy', 'edgy-updates', 'edgy-security', 'edgy-proposed', 'edgy-backports',
+ 'feisty', 'feisty-updates', 'feisty-security', 'feisty-proposed', 'feisty-backports',
+ 'gutsy', 'gutsy-updates', 'gutsy-security', 'gutsy-proposed', 'gutsy-backports',
+ 'hardy', 'hardy-updates', 'hardy-security', 'hardy-proposed', 'hardy-backports',
+ 'intrepid', 'intrepid-updates', 'intrepid-security', 'intrepid-proposed', 'intrepid-backports',
+ 'jaunty', 'jaunty-updates', 'jaunty-security', 'jaunty-proposed', 'jaunty-backports',
+ 'karmic', 'karmic-updates', 'karmic-security', 'karmic-proposed', 'karmic-backports',
+ 'lucid', 'lucid-updates', 'lucid-security', 'lucid-proposed', 'lucid-backports',
+ 'maverick', 'maverick-updates', 'maverick-security', 'maverick-proposed', 'maverick-backports',
+ 'natty', 'natty-updates', 'natty-security', 'natty-proposed', 'natty-backports',
+ 'oneiric', 'oneiric-updates', 'oneiric-security', 'oneiric-proposed', 'oneiric-backports',
+ 'precise', 'precise-updates', 'precise-security', 'precise-proposed', 'precise-backports',
+ 'quantal', 'quantal-updates', 'quantal-security', 'quantal-proposed', 'quantal-backports',
+ 'raring', 'raring-updates', 'raring-security', 'raring-proposed', 'raring-backports',
+ 'saucy', 'saucy-updates', 'saucy-security', 'saucy-proposed', 'saucy-backports',
+ 'trusty', 'trusty-updates', 'trusty-security', 'trusty-proposed', 'trusty-backports'
+ ),
+ 3 => array(
+ 'main', 'restricted', 'preview', 'contrib', 'non-free',
+ 'commercial', 'universe', 'multiverse'
+ )
+ ),
+ 'REGEXPS' => array(
+ 0 => "(((http|ftp):\/\/|file:\/)[^\s]+)|(cdrom:\[[^\]]*\][^\s]*)",
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => true,
+ 3 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00007f;',
+ 2 => 'color: #b1b100;',
+ 3 => 'color: #b16000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ ),
+ 'STRINGS' => array(
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #009900;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'NUMBERS' => GESHI_NEVER,
+ 'METHODS' => GESHI_NEVER,
+ 'SCRIPT' => GESHI_NEVER,
+ 'SYMBOLS' => GESHI_NEVER,
+ 'ESCAPE_CHAR' => GESHI_NEVER,
+ 'BRACKETS' => GESHI_NEVER,
+ 'STRINGS' => GESHI_NEVER,
+ ),
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#;>|^\/])',
+ 'DISALLOWED_AFTER' => '(?![a-zA-Z0-9_\|%\\-&\.])'
+ )
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/arm.php b/platform/www/vendor/geshi/geshi/src/geshi/arm.php
new file mode 100644
index 0000000..8ac5264
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/arm.php
@@ -0,0 +1,3316 @@
+<?php
+/*************************************************************************************
+ * arm.php
+ * -------
+ * Author: Marat Dukhan (mdukhan3.at.gatech.dot.edu)
+ * Copyright: (c) Marat Dukhan (mdukhan3.at.gatech.dot.edu)
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/10/06
+ *
+ * ARM Assembler language file for GeSHi.
+ * Based on the following documents:
+ * - "ARM Architecture Reference Manual: ARMv7-A and ARMv7-R edition"
+ * - "Intel XScale Technology: Intel Wireless MMX2 Coprocessor",
+ * Revision 1.5, July 2006
+ *
+ * CHANGES
+ * -------
+ * 2011/10/06
+ * - First Release (supported UAL syntax for up to ARMv7 A/R, VFPv3, NEON, WMMX/WMMX2)
+ *
+ * TODO (updated 2011/10/06)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ARM ASSEMBLER',
+ 'COMMENT_SINGLE' => array(
+ 1 => ';'
+ ),
+ 'COMMENT_MULTI' => array(),
+ //Line address prefix suppression
+ 'COMMENT_REGEXP' => array(
+ 2 => "/^(?:[0-9a-f]{0,4}:)?[0-9a-f]{4}(?:[0-9a-f]{4})?/mi"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /* Unconditional Data Processing Instructions */
+ 1 => array(
+ /* Data Processing: Unconditional Addition & Subtraction */
+ 'adc.w','adcal.w',
+ 'adc','adcal',
+ 'add.w','addal.w',
+ 'add','addal',
+ 'addw','addwal',
+ 'rsb.w','rsbal.w',
+ 'rsb','rsbal',
+ 'rsc','rscal',
+ 'sbc.w','sbcal.w',
+ 'sbc','sbcal',
+ 'sub.w','subal.w',
+ 'sub','subal',
+ 'neg.w','negal.w',
+ 'neg','negal',
+ 'adr.w','adral.w',
+ 'adr','adral',
+ /* Data Processing: Unconditional Logical */
+ 'and.w','andal.w',
+ 'and','andal',
+ 'bic.w','bical.w',
+ 'bic','bical',
+ 'orr.w','orral.w',
+ 'orr','orral',
+ 'orn.w','ornal.w',
+ 'orn','ornal',
+ 'eor.w','eoral.w',
+ 'eor','eoral',
+ 'mov.w','moval.w',
+ 'mov','moval',
+ 'movw','movwal',
+ 'movt','movtal',
+ 'cpy','cpyal',
+ 'mvn.w','mvnal.w',
+ 'mvn','mvnal',
+ /* Data Processing: Unconditional Shifts and Rotates */
+ 'asr.w','asral.w',
+ 'asr','asral',
+ 'lsl.w','lslal.w',
+ 'lsl','lslal',
+ 'lsr.w','lsral.w',
+ 'lsr','lsral',
+ 'ror.w','roral.w',
+ 'ror','roral',
+ 'rrx','rrxal',
+ /* Data Processing: Unconditional Word Multiply and Multiply-Add */
+ 'mul','mulal',
+ 'mla','mlaal',
+ 'mls','mlsal',
+ 'smull','smullal',
+ 'muls','mulsal',
+ 'umull','umullal',
+ 'smlal','smlalal',
+ 'umlal','umlalal',
+ /* Data Processing: Unconditional Halfword Multiply and Multiply-Add (ARMv5TE) */
+ 'smulbb','smulbbal',
+ 'smulbt','smulbtal',
+ 'smultb','smultbal',
+ 'smultt','smulttal',
+ 'smulwb','smulwbal',
+ 'smulwt','smulwtal',
+ 'smlalbb','smlalbbal',
+ 'smlalbt','smlalbtal',
+ 'smlaltb','smlaltbal',
+ 'smlaltt','smlalttal',
+ 'smlabb','smlabbal',
+ 'smlabt','smlabtal',
+ 'smlatb','smlatbal',
+ 'smlatt','smlattal',
+ 'smlawb','smlawbal',
+ 'smlawt','smlawtal',
+ /* Data Processing: Unconditional Bit Operations */
+ 'ubfx','ubfxal',
+ 'sbfx','sbfxal',
+ 'bfc','bfcal',
+ 'bfi','bfial',
+ 'clz','clzal',
+ /* Data Processing: Unconditional Divide (ARMv7-R) */
+ 'sdiv','sdival',
+ 'udiv','udival'
+ ),
+ /* Conditional Data Processing Instructions */
+ 2 => array(
+ /* Data Processing: Conditional Addition & Subtraction */
+ 'adceq.w','adcne.w','adccs.w','adchs.w','adccc.w','adclo.w','adcmi.w','adcpl.w','adcvs.w','adcvc.w','adchi.w','adcls.w','adcge.w','adclt.w','adcgt.w','adcle.w',
+ 'adceq','adcne','adccs','adchs','adccc','adclo','adcmi','adcpl','adcvs','adcvc','adchi','adcls','adcge','adclt','adcgt','adcle',
+ 'addeq.w','addne.w','addcs.w','addhs.w','addcc.w','addlo.w','addmi.w','addpl.w','addvs.w','addvc.w','addhi.w','addls.w','addge.w','addlt.w','addgt.w','addle.w',
+ 'addeq','addne','addcs','addhs','addcc','addlo','addmi','addpl','addvs','addvc','addhi','addls','addge','addlt','addgt','addle',
+ 'addweq','addwne','addwcs','addwhs','addwcc','addwlo','addwmi','addwpl','addwvs','addwvc','addwhi','addwls','addwge','addwlt','addwgt','addwle',
+ 'rsbeq.w','rsbne.w','rsbcs.w','rsbhs.w','rsbcc.w','rsblo.w','rsbmi.w','rsbpl.w','rsbvs.w','rsbvc.w','rsbhi.w','rsbls.w','rsbge.w','rsblt.w','rsbgt.w','rsble.w',
+ 'rsbeq','rsbne','rsbcs','rsbhs','rsbcc','rsblo','rsbmi','rsbpl','rsbvs','rsbvc','rsbhi','rsbls','rsbge','rsblt','rsbgt','rsble',
+ 'rsceq','rscne','rsccs','rschs','rsccc','rsclo','rscmi','rscpl','rscvs','rscvc','rschi','rscls','rscge','rsclt','rscgt','rscle',
+ 'sbceq.w','sbcne.w','sbccs.w','sbchs.w','sbccc.w','sbclo.w','sbcmi.w','sbcpl.w','sbcvs.w','sbcvc.w','sbchi.w','sbcls.w','sbcge.w','sbclt.w','sbcgt.w','sbcle.w',
+ 'sbceq','sbcne','sbccs','sbchs','sbccc','sbclo','sbcmi','sbcpl','sbcvs','sbcvc','sbchi','sbcls','sbcge','sbclt','sbcgt','sbcle',
+ 'subeq.w','subne.w','subcs.w','subhs.w','subcc.w','sublo.w','submi.w','subpl.w','subvs.w','subvc.w','subhi.w','subls.w','subge.w','sublt.w','subgt.w','suble.w',
+ 'subeq','subne','subcs','subhs','subcc','sublo','submi','subpl','subvs','subvc','subhi','subls','subge','sublt','subgt','suble',
+ 'negeq.w','negne.w','negcs.w','neghs.w','negcc.w','neglo.w','negmi.w','negpl.w','negvs.w','negvc.w','neghi.w','negls.w','negge.w','neglt.w','neggt.w','negle.w',
+ 'negeq','negne','negcs','neghs','negcc','neglo','negmi','negpl','negvs','negvc','neghi','negls','negge','neglt','neggt','negle',
+ 'adreq.w','adrne.w','adrcs.w','adrhs.w','adrcc.w','adrlo.w','adrmi.w','adrpl.w','adrvs.w','adrvc.w','adrhi.w','adrls.w','adrge.w','adrlt.w','adrgt.w','adrle.w',
+ 'adreq','adrne','adrcs','adrhs','adrcc','adrlo','adrmi','adrpl','adrvs','adrvc','adrhi','adrls','adrge','adrlt','adrgt','adrle',
+ /* Data Processing: Conditional Logical */
+ 'andeq.w','andne.w','andcs.w','andhs.w','andcc.w','andlo.w','andmi.w','andpl.w','andvs.w','andvc.w','andhi.w','andls.w','andge.w','andlt.w','andgt.w','andle.w',
+ 'andeq','andne','andcs','andhs','andcc','andlo','andmi','andpl','andvs','andvc','andhi','andls','andge','andlt','andgt','andle',
+ 'biceq.w','bicne.w','biccs.w','bichs.w','biccc.w','biclo.w','bicmi.w','bicpl.w','bicvs.w','bicvc.w','bichi.w','bicls.w','bicge.w','biclt.w','bicgt.w','bicle.w',
+ 'biceq','bicne','biccs','bichs','biccc','biclo','bicmi','bicpl','bicvs','bicvc','bichi','bicls','bicge','biclt','bicgt','bicle',
+ 'orreq.w','orrne.w','orrcs.w','orrhs.w','orrcc.w','orrlo.w','orrmi.w','orrpl.w','orrvs.w','orrvc.w','orrhi.w','orrls.w','orrge.w','orrlt.w','orrgt.w','orrle.w',
+ 'orreq','orrne','orrcs','orrhs','orrcc','orrlo','orrmi','orrpl','orrvs','orrvc','orrhi','orrls','orrge','orrlt','orrgt','orrle',
+ 'orneq.w','ornne.w','orncs.w','ornhs.w','orncc.w','ornlo.w','ornmi.w','ornpl.w','ornvs.w','ornvc.w','ornhi.w','ornls.w','ornge.w','ornlt.w','orngt.w','ornle.w',
+ 'orneq','ornne','orncs','ornhs','orncc','ornlo','ornmi','ornpl','ornvs','ornvc','ornhi','ornls','ornge','ornlt','orngt','ornle',
+ 'eoreq.w','eorne.w','eorcs.w','eorhs.w','eorcc.w','eorlo.w','eormi.w','eorpl.w','eorvs.w','eorvc.w','eorhi.w','eorls.w','eorge.w','eorlt.w','eorgt.w','eorle.w',
+ 'eoreq','eorne','eorcs','eorhs','eorcc','eorlo','eormi','eorpl','eorvs','eorvc','eorhi','eorls','eorge','eorlt','eorgt','eorle',
+ 'moveq.w','movne.w','movcs.w','movhs.w','movcc.w','movlo.w','movmi.w','movpl.w','movvs.w','movvc.w','movhi.w','movls.w','movge.w','movlt.w','movgt.w','movle.w',
+ 'moveq','movne','movcs','movhs','movcc','movlo','movmi','movpl','movvs','movvc','movhi','movls','movge','movlt','movgt','movle',
+ 'movweq','movwne','movwcs','movwhs','movwcc','movwlo','movwmi','movwpl','movwvs','movwvc','movwhi','movwls','movwge','movwlt','movwgt','movwle',
+ 'movteq','movtne','movtcs','movths','movtcc','movtlo','movtmi','movtpl','movtvs','movtvc','movthi','movtls','movtge','movtlt','movtgt','movtle',
+ 'cpyeq','cpyne','cpycs','cpyhs','cpycc','cpylo','cpymi','cpypl','cpyvs','cpyvc','cpyhi','cpyls','cpyge','cpylt','cpygt','cpyle',
+ 'mvneq.w','mvnne.w','mvncs.w','mvnhs.w','mvncc.w','mvnlo.w','mvnmi.w','mvnpl.w','mvnvs.w','mvnvc.w','mvnhi.w','mvnls.w','mvnge.w','mvnlt.w','mvngt.w','mvnle.w',
+ 'mvneq','mvnne','mvncs','mvnhs','mvncc','mvnlo','mvnmi','mvnpl','mvnvs','mvnvc','mvnhi','mvnls','mvnge','mvnlt','mvngt','mvnle',
+ /* Data Processing: Conditional Shifts and Rotates */
+ 'asreq.w','asrne.w','asrcs.w','asrhs.w','asrcc.w','asrlo.w','asrmi.w','asrpl.w','asrvs.w','asrvc.w','asrhi.w','asrls.w','asrge.w','asrlt.w','asrgt.w','asrle.w',
+ 'asreq','asrne','asrcs','asrhs','asrcc','asrlo','asrmi','asrpl','asrvs','asrvc','asrhi','asrls','asrge','asrlt','asrgt','asrle',
+ 'lsleq.w','lslne.w','lslcs.w','lslhs.w','lslcc.w','lsllo.w','lslmi.w','lslpl.w','lslvs.w','lslvc.w','lslhi.w','lslls.w','lslge.w','lsllt.w','lslgt.w','lslle.w',
+ 'lsleq','lslne','lslcs','lslhs','lslcc','lsllo','lslmi','lslpl','lslvs','lslvc','lslhi','lslls','lslge','lsllt','lslgt','lslle',
+ 'lsreq.w','lsrne.w','lsrcs.w','lsrhs.w','lsrcc.w','lsrlo.w','lsrmi.w','lsrpl.w','lsrvs.w','lsrvc.w','lsrhi.w','lsrls.w','lsrge.w','lsrlt.w','lsrgt.w','lsrle.w',
+ 'lsreq','lsrne','lsrcs','lsrhs','lsrcc','lsrlo','lsrmi','lsrpl','lsrvs','lsrvc','lsrhi','lsrls','lsrge','lsrlt','lsrgt','lsrle',
+ 'roreq.w','rorne.w','rorcs.w','rorhs.w','rorcc.w','rorlo.w','rormi.w','rorpl.w','rorvs.w','rorvc.w','rorhi.w','rorls.w','rorge.w','rorlt.w','rorgt.w','rorle.w',
+ 'roreq','rorne','rorcs','rorhs','rorcc','rorlo','rormi','rorpl','rorvs','rorvc','rorhi','rorls','rorge','rorlt','rorgt','rorle',
+ 'rrxeq','rrxne','rrxcs','rrxhs','rrxcc','rrxlo','rrxmi','rrxpl','rrxvs','rrxvc','rrxhi','rrxls','rrxge','rrxlt','rrxgt','rrxle',
+ /* Data Processing: Conditional Word Multiply and Multiply-Add */
+ 'muleq','mulne','mulcs','mulhs','mulcc','mullo','mulmi','mulpl','mulvs','mulvc','mulhi','mulls','mulge','mullt','mulgt','mulle',
+ 'mlaeq','mlane','mlacs','mlahs','mlacc','mlalo','mlami','mlapl','mlavs','mlavc','mlahi','mlals','mlage','mlalt','mlagt','mlale',
+ 'mlseq','mlsne','mlscs','mlshs','mlscc','mlslo','mlsmi','mlspl','mlsvs','mlsvc','mlshi','mlsls','mlsge','mlslt','mlsgt','mlsle',
+ 'smulleq','smullne','smullcs','smullhs','smullcc','smulllo','smullmi','smullpl','smullvs','smullvc','smullhi','smullls','smullge','smulllt','smullgt','smullle',
+ 'mulseq','mulsne','mulscs','mulshs','mulscc','mulslo','mulsmi','mulspl','mulsvs','mulsvc','mulshi','mulsls','mulsge','mulslt','mulsgt','mulsle',
+ 'umulleq','umullne','umullcs','umullhs','umullcc','umulllo','umullmi','umullpl','umullvs','umullvc','umullhi','umullls','umullge','umulllt','umullgt','umullle',
+ 'smlaleq','smlalne','smlalcs','smlalhs','smlalcc','smlallo','smlalmi','smlalpl','smlalvs','smlalvc','smlalhi','smlalls','smlalge','smlallt','smlalgt','smlalle',
+ 'umlaleq','umlalne','umlalcs','umlalhs','umlalcc','umlallo','umlalmi','umlalpl','umlalvs','umlalvc','umlalhi','umlalls','umlalge','umlallt','umlalgt','umlalle',
+ /* Data Processing: Conditional Halfword Multiply and Multiply-Add (ARMv5TE) */
+ 'smulbbeq','smulbbne','smulbbcs','smulbbhs','smulbbcc','smulbblo','smulbbmi','smulbbpl','smulbbvs','smulbbvc','smulbbhi','smulbbls','smulbbge','smulbblt','smulbbgt','smulbble',
+ 'smulbteq','smulbtne','smulbtcs','smulbths','smulbtcc','smulbtlo','smulbtmi','smulbtpl','smulbtvs','smulbtvc','smulbthi','smulbtls','smulbtge','smulbtlt','smulbtgt','smulbtle',
+ 'smultbeq','smultbne','smultbcs','smultbhs','smultbcc','smultblo','smultbmi','smultbpl','smultbvs','smultbvc','smultbhi','smultbls','smultbge','smultblt','smultbgt','smultble',
+ 'smultteq','smulttne','smulttcs','smultths','smulttcc','smulttlo','smulttmi','smulttpl','smulttvs','smulttvc','smultthi','smulttls','smulttge','smulttlt','smulttgt','smulttle',
+ 'smulwbeq','smulwbne','smulwbcs','smulwbhs','smulwbcc','smulwblo','smulwbmi','smulwbpl','smulwbvs','smulwbvc','smulwbhi','smulwbls','smulwbge','smulwblt','smulwbgt','smulwble',
+ 'smulwteq','smulwtne','smulwtcs','smulwths','smulwtcc','smulwtlo','smulwtmi','smulwtpl','smulwtvs','smulwtvc','smulwthi','smulwtls','smulwtge','smulwtlt','smulwtgt','smulwtle',
+ 'smlalbbeq','smlalbbne','smlalbbcs','smlalbbhs','smlalbbcc','smlalbblo','smlalbbmi','smlalbbpl','smlalbbvs','smlalbbvc','smlalbbhi','smlalbbls','smlalbbge','smlalbblt','smlalbbgt','smlalbble',
+ 'smlalbteq','smlalbtne','smlalbtcs','smlalbths','smlalbtcc','smlalbtlo','smlalbtmi','smlalbtpl','smlalbtvs','smlalbtvc','smlalbthi','smlalbtls','smlalbtge','smlalbtlt','smlalbtgt','smlalbtle',
+ 'smlaltbeq','smlaltbne','smlaltbcs','smlaltbhs','smlaltbcc','smlaltblo','smlaltbmi','smlaltbpl','smlaltbvs','smlaltbvc','smlaltbhi','smlaltbls','smlaltbge','smlaltblt','smlaltbgt','smlaltble',
+ 'smlaltteq','smlalttne','smlalttcs','smlaltths','smlalttcc','smlalttlo','smlalttmi','smlalttpl','smlalttvs','smlalttvc','smlaltthi','smlalttls','smlalttge','smlalttlt','smlalttgt','smlalttle',
+ 'smlabbeq','smlabbne','smlabbcs','smlabbhs','smlabbcc','smlabblo','smlabbmi','smlabbpl','smlabbvs','smlabbvc','smlabbhi','smlabbls','smlabbge','smlabblt','smlabbgt','smlabble',
+ 'smlabteq','smlabtne','smlabtcs','smlabths','smlabtcc','smlabtlo','smlabtmi','smlabtpl','smlabtvs','smlabtvc','smlabthi','smlabtls','smlabtge','smlabtlt','smlabtgt','smlabtle',
+ 'smlatbeq','smlatbne','smlatbcs','smlatbhs','smlatbcc','smlatblo','smlatbmi','smlatbpl','smlatbvs','smlatbvc','smlatbhi','smlatbls','smlatbge','smlatblt','smlatbgt','smlatble',
+ 'smlatteq','smlattne','smlattcs','smlatths','smlattcc','smlattlo','smlattmi','smlattpl','smlattvs','smlattvc','smlatthi','smlattls','smlattge','smlattlt','smlattgt','smlattle',
+ 'smlawbeq','smlawbne','smlawbcs','smlawbhs','smlawbcc','smlawblo','smlawbmi','smlawbpl','smlawbvs','smlawbvc','smlawbhi','smlawbls','smlawbge','smlawblt','smlawbgt','smlawble',
+ 'smlawteq','smlawtne','smlawtcs','smlawths','smlawtcc','smlawtlo','smlawtmi','smlawtpl','smlawtvs','smlawtvc','smlawthi','smlawtls','smlawtge','smlawtlt','smlawtgt','smlawtle',
+ /* Data Processing: Conditional Bit Operations */
+ 'ubfxeq','ubfxne','ubfxcs','ubfxhs','ubfxcc','ubfxlo','ubfxmi','ubfxpl','ubfxvs','ubfxvc','ubfxhi','ubfxls','ubfxge','ubfxlt','ubfxgt','ubfxle',
+ 'sbfxeq','sbfxne','sbfxcs','sbfxhs','sbfxcc','sbfxlo','sbfxmi','sbfxpl','sbfxvs','sbfxvc','sbfxhi','sbfxls','sbfxge','sbfxlt','sbfxgt','sbfxle',
+ 'bfceq','bfcne','bfccs','bfchs','bfccc','bfclo','bfcmi','bfcpl','bfcvs','bfcvc','bfchi','bfcls','bfcge','bfclt','bfcgt','bfcle',
+ 'bfieq','bfine','bfics','bfihs','bficc','bfilo','bfimi','bfipl','bfivs','bfivc','bfihi','bfils','bfige','bfilt','bfigt','bfile',
+ 'clzeq','clzne','clzcs','clzhs','clzcc','clzlo','clzmi','clzpl','clzvs','clzvc','clzhi','clzls','clzge','clzlt','clzgt','clzle',
+ /* ARMv7-R: Conditional Divide */
+ 'sdiveq','sdivne','sdivcs','sdivhs','sdivcc','sdivlo','sdivmi','sdivpl','sdivvs','sdivvc','sdivhi','sdivls','sdivge','sdivlt','sdivgt','sdivle',
+ 'udiveq','udivne','udivcs','udivhs','udivcc','udivlo','udivmi','udivpl','udivvs','udivvc','udivhi','udivls','udivge','udivlt','udivgt','udivle'
+ ),
+ /* Unconditional Memory Access */
+ 3 => array(
+ /* Memory Access: Unconditional Memory Loads and Prefetches */
+ 'ldm.w','ldmal.w',
+ 'ldm','ldmal',
+ 'ldmda','ldmdaal',
+ 'ldmdb','ldmdbal',
+ 'ldmib','ldmibal',
+ 'ldmia','ldmiaal',
+ 'ldmea','ldmeaal',
+ 'ldmed','ldmedal',
+ 'ldmfa','ldmfaal',
+ 'ldmfd','ldmfdal',
+ 'ldrd','ldrdal',
+ 'ldr.w','ldral.w',
+ 'ldr','ldral',
+ 'ldrh.w','ldrhal.w',
+ 'ldrh','ldrhal',
+ 'ldrb.w','ldrbal.w',
+ 'ldrb','ldrbal',
+ 'ldrsh.w','ldrshal.w',
+ 'ldrsh','ldrshal',
+ 'ldrsb.w','ldrsbal.w',
+ 'ldrsb','ldrsbal',
+ 'ldrt','ldrtal',
+ 'ldrht','ldrhtal',
+ 'ldrbt','ldrbtal',
+ 'ldrsht','ldrshtal',
+ 'ldrsbt','ldrsbtal',
+ 'pop.w','popal.w',
+ 'pop','popal',
+ 'pld','pldal',
+ 'pldw','pldwal',
+ 'pli','plial',
+ /* Memory Access: Unconditional Memory Stores */
+ 'stm.w','stmal.w',
+ 'stm','stmal',
+ 'stmda','stmdaal',
+ 'stmdb','stmdbal',
+ 'stmib','stmibal',
+ 'stmia','stmiaal',
+ 'stmea','stmeaal',
+ 'stmed','stmedal',
+ 'stdfa','stdfaal',
+ 'stdfd','stdfdal',
+ 'strd','strdal',
+ 'str.w','stral.w',
+ 'str','stral',
+ 'strh.w','strhal.w',
+ 'strh','strhal',
+ 'strb.w','strbal.w',
+ 'strb','strbal',
+ 'strt','strtal',
+ 'strht','strhtal',
+ 'strbt','strbtal',
+ 'push.w','pushal.w',
+ 'push','pushal'
+ ),
+ /* Conditional Memory Access */
+ 4 => array(
+ /* Memory Access: Conditional Memory Loads and Prefetches */
+ 'ldmeq.w','ldmne.w','ldmcs.w','ldmhs.w','ldmcc.w','ldmlo.w','ldmmi.w','ldmpl.w','ldmvs.w','ldmvc.w','ldmhi.w','ldmls.w','ldmge.w','ldmlt.w','ldmgt.w','ldmle.w',
+ 'ldmeq','ldmne','ldmcs','ldmhs','ldmcc','ldmlo','ldmmi','ldmpl','ldmvs','ldmvc','ldmhi','ldmls','ldmge','ldmlt','ldmgt','ldmle',
+ 'ldmdaeq','ldmdane','ldmdacs','ldmdahs','ldmdacc','ldmdalo','ldmdami','ldmdapl','ldmdavs','ldmdavc','ldmdahi','ldmdals','ldmdage','ldmdalt','ldmdagt','ldmdale',
+ 'ldmdbeq','ldmdbne','ldmdbcs','ldmdbhs','ldmdbcc','ldmdblo','ldmdbmi','ldmdbpl','ldmdbvs','ldmdbvc','ldmdbhi','ldmdbls','ldmdbge','ldmdblt','ldmdbgt','ldmdble',
+ 'ldmibeq','ldmibne','ldmibcs','ldmibhs','ldmibcc','ldmiblo','ldmibmi','ldmibpl','ldmibvs','ldmibvc','ldmibhi','ldmibls','ldmibge','ldmiblt','ldmibgt','ldmible',
+ 'ldmiaeq','ldmiane','ldmiacs','ldmiahs','ldmiacc','ldmialo','ldmiami','ldmiapl','ldmiavs','ldmiavc','ldmiahi','ldmials','ldmiage','ldmialt','ldmiagt','ldmiale',
+ 'ldmeaeq','ldmeane','ldmeacs','ldmeahs','ldmeacc','ldmealo','ldmeami','ldmeapl','ldmeavs','ldmeavc','ldmeahi','ldmeals','ldmeage','ldmealt','ldmeagt','ldmeale',
+ 'ldmedeq','ldmedne','ldmedcs','ldmedhs','ldmedcc','ldmedlo','ldmedmi','ldmedpl','ldmedvs','ldmedvc','ldmedhi','ldmedls','ldmedge','ldmedlt','ldmedgt','ldmedle',
+ 'ldmfaeq','ldmfane','ldmfacs','ldmfahs','ldmfacc','ldmfalo','ldmfami','ldmfapl','ldmfavs','ldmfavc','ldmfahi','ldmfals','ldmfage','ldmfalt','ldmfagt','ldmfale',
+ 'ldmfdeq','ldmfdne','ldmfdcs','ldmfdhs','ldmfdcc','ldmfdlo','ldmfdmi','ldmfdpl','ldmfdvs','ldmfdvc','ldmfdhi','ldmfdls','ldmfdge','ldmfdlt','ldmfdgt','ldmfdle',
+ 'ldrdeq','ldrdne','ldrdcs','ldrdhs','ldrdcc','ldrdlo','ldrdmi','ldrdpl','ldrdvs','ldrdvc','ldrdhi','ldrdls','ldrdge','ldrdlt','ldrdgt','ldrdle',
+ 'ldreq.w','ldrne.w','ldrcs.w','ldrhs.w','ldrcc.w','ldrlo.w','ldrmi.w','ldrpl.w','ldrvs.w','ldrvc.w','ldrhi.w','ldrls.w','ldrge.w','ldrlt.w','ldrgt.w','ldrle.w',
+ 'ldreq','ldrne','ldrcs','ldrhs','ldrcc','ldrlo','ldrmi','ldrpl','ldrvs','ldrvc','ldrhi','ldrls','ldrge','ldrlt','ldrgt','ldrle',
+ 'ldrheq.w','ldrhne.w','ldrhcs.w','ldrhhs.w','ldrhcc.w','ldrhlo.w','ldrhmi.w','ldrhpl.w','ldrhvs.w','ldrhvc.w','ldrhhi.w','ldrhls.w','ldrhge.w','ldrhlt.w','ldrhgt.w','ldrhle.w',
+ 'ldrheq','ldrhne','ldrhcs','ldrhhs','ldrhcc','ldrhlo','ldrhmi','ldrhpl','ldrhvs','ldrhvc','ldrhhi','ldrhls','ldrhge','ldrhlt','ldrhgt','ldrhle',
+ 'ldrbeq.w','ldrbne.w','ldrbcs.w','ldrbhs.w','ldrbcc.w','ldrblo.w','ldrbmi.w','ldrbpl.w','ldrbvs.w','ldrbvc.w','ldrbhi.w','ldrbls.w','ldrbge.w','ldrblt.w','ldrbgt.w','ldrble.w',
+ 'ldrbeq','ldrbne','ldrbcs','ldrbhs','ldrbcc','ldrblo','ldrbmi','ldrbpl','ldrbvs','ldrbvc','ldrbhi','ldrbls','ldrbge','ldrblt','ldrbgt','ldrble',
+ 'ldrsheq.w','ldrshne.w','ldrshcs.w','ldrshhs.w','ldrshcc.w','ldrshlo.w','ldrshmi.w','ldrshpl.w','ldrshvs.w','ldrshvc.w','ldrshhi.w','ldrshls.w','ldrshge.w','ldrshlt.w','ldrshgt.w','ldrshle.w',
+ 'ldrsheq','ldrshne','ldrshcs','ldrshhs','ldrshcc','ldrshlo','ldrshmi','ldrshpl','ldrshvs','ldrshvc','ldrshhi','ldrshls','ldrshge','ldrshlt','ldrshgt','ldrshle',
+ 'ldrsbeq.w','ldrsbne.w','ldrsbcs.w','ldrsbhs.w','ldrsbcc.w','ldrsblo.w','ldrsbmi.w','ldrsbpl.w','ldrsbvs.w','ldrsbvc.w','ldrsbhi.w','ldrsbls.w','ldrsbge.w','ldrsblt.w','ldrsbgt.w','ldrsble.w',
+ 'ldrsbeq','ldrsbne','ldrsbcs','ldrsbhs','ldrsbcc','ldrsblo','ldrsbmi','ldrsbpl','ldrsbvs','ldrsbvc','ldrsbhi','ldrsbls','ldrsbge','ldrsblt','ldrsbgt','ldrsble',
+ 'ldrteq','ldrtne','ldrtcs','ldrths','ldrtcc','ldrtlo','ldrtmi','ldrtpl','ldrtvs','ldrtvc','ldrthi','ldrtls','ldrtge','ldrtlt','ldrtgt','ldrtle',
+ 'ldrhteq','ldrhtne','ldrhtcs','ldrhths','ldrhtcc','ldrhtlo','ldrhtmi','ldrhtpl','ldrhtvs','ldrhtvc','ldrhthi','ldrhtls','ldrhtge','ldrhtlt','ldrhtgt','ldrhtle',
+ 'ldrbteq','ldrbtne','ldrbtcs','ldrbths','ldrbtcc','ldrbtlo','ldrbtmi','ldrbtpl','ldrbtvs','ldrbtvc','ldrbthi','ldrbtls','ldrbtge','ldrbtlt','ldrbtgt','ldrbtle',
+ 'ldrshteq','ldrshtne','ldrshtcs','ldrshths','ldrshtcc','ldrshtlo','ldrshtmi','ldrshtpl','ldrshtvs','ldrshtvc','ldrshthi','ldrshtls','ldrshtge','ldrshtlt','ldrshtgt','ldrshtle',
+ 'ldrsbteq','ldrsbtne','ldrsbtcs','ldrsbths','ldrsbtcc','ldrsbtlo','ldrsbtmi','ldrsbtpl','ldrsbtvs','ldrsbtvc','ldrsbthi','ldrsbtls','ldrsbtge','ldrsbtlt','ldrsbtgt','ldrsbtle',
+ 'popeq.w','popne.w','popcs.w','pophs.w','popcc.w','poplo.w','popmi.w','poppl.w','popvs.w','popvc.w','pophi.w','popls.w','popge.w','poplt.w','popgt.w','pople.w',
+ 'popeq','popne','popcs','pophs','popcc','poplo','popmi','poppl','popvs','popvc','pophi','popls','popge','poplt','popgt','pople',
+ 'pldeq','pldne','pldcs','pldhs','pldcc','pldlo','pldmi','pldpl','pldvs','pldvc','pldhi','pldls','pldge','pldlt','pldgt','pldle',
+ 'pldweq','pldwne','pldwcs','pldwhs','pldwcc','pldwlo','pldwmi','pldwpl','pldwvs','pldwvc','pldwhi','pldwls','pldwge','pldwlt','pldwgt','pldwle',
+ 'plieq','pline','plics','plihs','plicc','plilo','plimi','plipl','plivs','plivc','plihi','plils','plige','plilt','pligt','plile',
+ /* Memory Access: Conditional Memory Stores */
+ 'stmeq.w','stmne.w','stmcs.w','stmhs.w','stmcc.w','stmlo.w','stmmi.w','stmpl.w','stmvs.w','stmvc.w','stmhi.w','stmls.w','stmge.w','stmlt.w','stmgt.w','stmle.w',
+ 'stmeq','stmne','stmcs','stmhs','stmcc','stmlo','stmmi','stmpl','stmvs','stmvc','stmhi','stmls','stmge','stmlt','stmgt','stmle',
+ 'stmdaeq','stmdane','stmdacs','stmdahs','stmdacc','stmdalo','stmdami','stmdapl','stmdavs','stmdavc','stmdahi','stmdals','stmdage','stmdalt','stmdagt','stmdale',
+ 'stmdbeq','stmdbne','stmdbcs','stmdbhs','stmdbcc','stmdblo','stmdbmi','stmdbpl','stmdbvs','stmdbvc','stmdbhi','stmdbls','stmdbge','stmdblt','stmdbgt','stmdble',
+ 'stmibeq','stmibne','stmibcs','stmibhs','stmibcc','stmiblo','stmibmi','stmibpl','stmibvs','stmibvc','stmibhi','stmibls','stmibge','stmiblt','stmibgt','stmible',
+ 'stmiaeq','stmiane','stmiacs','stmiahs','stmiacc','stmialo','stmiami','stmiapl','stmiavs','stmiavc','stmiahi','stmials','stmiage','stmialt','stmiagt','stmiale',
+ 'stmeaeq','stmeane','stmeacs','stmeahs','stmeacc','stmealo','stmeami','stmeapl','stmeavs','stmeavc','stmeahi','stmeals','stmeage','stmealt','stmeagt','stmeale',
+ 'stmedeq','stmedne','stmedcs','stmedhs','stmedcc','stmedlo','stmedmi','stmedpl','stmedvs','stmedvc','stmedhi','stmedls','stmedge','stmedlt','stmedgt','stmedle',
+ 'stdfaeq','stdfane','stdfacs','stdfahs','stdfacc','stdfalo','stdfami','stdfapl','stdfavs','stdfavc','stdfahi','stdfals','stdfage','stdfalt','stdfagt','stdfale',
+ 'stdfdeq','stdfdne','stdfdcs','stdfdhs','stdfdcc','stdfdlo','stdfdmi','stdfdpl','stdfdvs','stdfdvc','stdfdhi','stdfdls','stdfdge','stdfdlt','stdfdgt','stdfdle',
+ 'strdeq','strdne','strdcs','strdhs','strdcc','strdlo','strdmi','strdpl','strdvs','strdvc','strdhi','strdls','strdge','strdlt','strdgt','strdle',
+ 'streq.w','strne.w','strcs.w','strhs.w','strcc.w','strlo.w','strmi.w','strpl.w','strvs.w','strvc.w','strhi.w','strls.w','strge.w','strlt.w','strgt.w','strle.w',
+ 'streq','strne','strcs','strhs','strcc','strlo','strmi','strpl','strvs','strvc','strhi','strls','strge','strlt','strgt','strle',
+ 'strheq.w','strhne.w','strhcs.w','strhhs.w','strhcc.w','strhlo.w','strhmi.w','strhpl.w','strhvs.w','strhvc.w','strhhi.w','strhls.w','strhge.w','strhlt.w','strhgt.w','strhle.w',
+ 'strheq','strhne','strhcs','strhhs','strhcc','strhlo','strhmi','strhpl','strhvs','strhvc','strhhi','strhls','strhge','strhlt','strhgt','strhle',
+ 'strbeq.w','strbne.w','strbcs.w','strbhs.w','strbcc.w','strblo.w','strbmi.w','strbpl.w','strbvs.w','strbvc.w','strbhi.w','strbls.w','strbge.w','strblt.w','strbgt.w','strble.w',
+ 'strbeq','strbne','strbcs','strbhs','strbcc','strblo','strbmi','strbpl','strbvs','strbvc','strbhi','strbls','strbge','strblt','strbgt','strble',
+ 'strteq','strtne','strtcs','strths','strtcc','strtlo','strtmi','strtpl','strtvs','strtvc','strthi','strtls','strtge','strtlt','strtgt','strtle',
+ 'strhteq','strhtne','strhtcs','strhths','strhtcc','strhtlo','strhtmi','strhtpl','strhtvs','strhtvc','strhthi','strhtls','strhtge','strhtlt','strhtgt','strhtle',
+ 'strbteq','strbtne','strbtcs','strbths','strbtcc','strbtlo','strbtmi','strbtpl','strbtvs','strbtvc','strbthi','strbtls','strbtge','strbtlt','strbtgt','strbtle',
+ 'pusheq.w','pushne.w','pushcs.w','pushhs.w','pushcc.w','pushlo.w','pushmi.w','pushpl.w','pushvs.w','pushvc.w','pushhi.w','pushls.w','pushge.w','pushlt.w','pushgt.w','pushle.w',
+ 'pusheq','pushne','pushcs','pushhs','pushcc','pushlo','pushmi','pushpl','pushvs','pushvc','pushhi','pushls','pushge','pushlt','pushgt','pushle'
+ ),
+ /* Unconditional Flags-Affecting Instructions */
+ 5 => array(
+ /* Set Flags: Unconditional Addition and Subtraction */
+ 'adds.w','addsal.w',
+ 'adds','addsal',
+ 'subs.w','subsal.w',
+ 'subs','subsal',
+ 'rsbs.w','rsbsal.w',
+ 'rsbs','rsbsal',
+ 'negs.w','negsal.w',
+ 'negs','negsal',
+ 'adcs.w','adcsal.w',
+ 'adcs','adcsal',
+ 'sbcs.w','sbcsal.w',
+ 'sbcs','sbcsal',
+ 'rscs','rscsal',
+ 'cmp.w','cmpal.w',
+ 'cmp','cmpal',
+ 'cmn.w','cmnal.w',
+ 'cmn','cmnal',
+ /* Set Flags: Unconditional Logical */
+ 'ands.w','andsal.w',
+ 'ands','andsal',
+ 'bics.w','bicsal.w',
+ 'bics','bicsal',
+ 'orrs.w','orrsal.w',
+ 'orrs','orrsal',
+ 'orns.w','ornsal.w',
+ 'orns','ornsal',
+ 'eors.w','eorsal.w',
+ 'eors','eorsal',
+ 'mvns.w','mvnsal.w',
+ 'mvns','mvnsal',
+ 'movs.w','movsal.w',
+ 'movs','movsal',
+ 'teq','teqal',
+ 'tst.w','tstal.w',
+ 'tst','tstal',
+ 'mrs','mrsal',
+ 'msr','msral',
+ /* Set Flags: Unconditional Shifts and Rotates */
+ 'asrs.w','asrsal.w',
+ 'asrs','asrsal',
+ 'lsls.w','lslsal.w',
+ 'lsls','lslsal',
+ 'lsrs.w','lsrsal.w',
+ 'lsrs','lsrsal',
+ 'rors.w','rorsal.w',
+ 'rors','rorsal',
+ 'rrxs','rrxsal',
+ /* Set Flags: Unconditional Multiply and Multiply-Add */
+ 'mlas','mlasal',
+ 'smulls','smullsal',
+ 'umulls','umullsal',
+ 'smlals','smlalsal',
+ 'umlals','umlalsal'
+ ),
+ /* Conditional Flags-Affecting Instructions */
+ 6 => array(
+ /* Set Flags: Conditional Addition and Subtraction */
+ 'addseq.w','addsne.w','addscs.w','addshs.w','addscc.w','addslo.w','addsmi.w','addspl.w','addsvs.w','addsvc.w','addshi.w','addsls.w','addsge.w','addslt.w','addsgt.w','addsle.w',
+ 'addseq','addsne','addscs','addshs','addscc','addslo','addsmi','addspl','addsvs','addsvc','addshi','addsls','addsge','addslt','addsgt','addsle',
+ 'subseq.w','subsne.w','subscs.w','subshs.w','subscc.w','subslo.w','subsmi.w','subspl.w','subsvs.w','subsvc.w','subshi.w','subsls.w','subsge.w','subslt.w','subsgt.w','subsle.w',
+ 'subseq','subsne','subscs','subshs','subscc','subslo','subsmi','subspl','subsvs','subsvc','subshi','subsls','subsge','subslt','subsgt','subsle',
+ 'rsbseq.w','rsbsne.w','rsbscs.w','rsbshs.w','rsbscc.w','rsbslo.w','rsbsmi.w','rsbspl.w','rsbsvs.w','rsbsvc.w','rsbshi.w','rsbsls.w','rsbsge.w','rsbslt.w','rsbsgt.w','rsbsle.w',
+ 'rsbseq','rsbsne','rsbscs','rsbshs','rsbscc','rsbslo','rsbsmi','rsbspl','rsbsvs','rsbsvc','rsbshi','rsbsls','rsbsge','rsbslt','rsbsgt','rsbsle',
+ 'negseq.w','negsne.w','negscs.w','negshs.w','negscc.w','negslo.w','negsmi.w','negspl.w','negsvs.w','negsvc.w','negshi.w','negsls.w','negsge.w','negslt.w','negsgt.w','negsle.w',
+ 'negseq','negsne','negscs','negshs','negscc','negslo','negsmi','negspl','negsvs','negsvc','negshi','negsls','negsge','negslt','negsgt','negsle',
+ 'adcseq.w','adcsne.w','adcscs.w','adcshs.w','adcscc.w','adcslo.w','adcsmi.w','adcspl.w','adcsvs.w','adcsvc.w','adcshi.w','adcsls.w','adcsge.w','adcslt.w','adcsgt.w','adcsle.w',
+ 'adcseq','adcsne','adcscs','adcshs','adcscc','adcslo','adcsmi','adcspl','adcsvs','adcsvc','adcshi','adcsls','adcsge','adcslt','adcsgt','adcsle',
+ 'sbcseq.w','sbcsne.w','sbcscs.w','sbcshs.w','sbcscc.w','sbcslo.w','sbcsmi.w','sbcspl.w','sbcsvs.w','sbcsvc.w','sbcshi.w','sbcsls.w','sbcsge.w','sbcslt.w','sbcsgt.w','sbcsle.w',
+ 'sbcseq','sbcsne','sbcscs','sbcshs','sbcscc','sbcslo','sbcsmi','sbcspl','sbcsvs','sbcsvc','sbcshi','sbcsls','sbcsge','sbcslt','sbcsgt','sbcsle',
+ 'rscseq','rscsne','rscscs','rscshs','rscscc','rscslo','rscsmi','rscspl','rscsvs','rscsvc','rscshi','rscsls','rscsge','rscslt','rscsgt','rscsle',
+ 'cmpeq.w','cmpne.w','cmpcs.w','cmphs.w','cmpcc.w','cmplo.w','cmpmi.w','cmppl.w','cmpvs.w','cmpvc.w','cmphi.w','cmpls.w','cmpge.w','cmplt.w','cmpgt.w','cmple.w',
+ 'cmpeq','cmpne','cmpcs','cmphs','cmpcc','cmplo','cmpmi','cmppl','cmpvs','cmpvc','cmphi','cmpls','cmpge','cmplt','cmpgt','cmple',
+ 'cmneq.w','cmnne.w','cmncs.w','cmnhs.w','cmncc.w','cmnlo.w','cmnmi.w','cmnpl.w','cmnvs.w','cmnvc.w','cmnhi.w','cmnls.w','cmnge.w','cmnlt.w','cmngt.w','cmnle.w',
+ 'cmneq','cmnne','cmncs','cmnhs','cmncc','cmnlo','cmnmi','cmnpl','cmnvs','cmnvc','cmnhi','cmnls','cmnge','cmnlt','cmngt','cmnle',
+ /* Set Flags: Conditional Logical */
+ 'andseq.w','andsne.w','andscs.w','andshs.w','andscc.w','andslo.w','andsmi.w','andspl.w','andsvs.w','andsvc.w','andshi.w','andsls.w','andsge.w','andslt.w','andsgt.w','andsle.w',
+ 'andseq','andsne','andscs','andshs','andscc','andslo','andsmi','andspl','andsvs','andsvc','andshi','andsls','andsge','andslt','andsgt','andsle',
+ 'bicseq.w','bicsne.w','bicscs.w','bicshs.w','bicscc.w','bicslo.w','bicsmi.w','bicspl.w','bicsvs.w','bicsvc.w','bicshi.w','bicsls.w','bicsge.w','bicslt.w','bicsgt.w','bicsle.w',
+ 'bicseq','bicsne','bicscs','bicshs','bicscc','bicslo','bicsmi','bicspl','bicsvs','bicsvc','bicshi','bicsls','bicsge','bicslt','bicsgt','bicsle',
+ 'orrseq.w','orrsne.w','orrscs.w','orrshs.w','orrscc.w','orrslo.w','orrsmi.w','orrspl.w','orrsvs.w','orrsvc.w','orrshi.w','orrsls.w','orrsge.w','orrslt.w','orrsgt.w','orrsle.w',
+ 'orrseq','orrsne','orrscs','orrshs','orrscc','orrslo','orrsmi','orrspl','orrsvs','orrsvc','orrshi','orrsls','orrsge','orrslt','orrsgt','orrsle',
+ 'ornseq.w','ornsne.w','ornscs.w','ornshs.w','ornscc.w','ornslo.w','ornsmi.w','ornspl.w','ornsvs.w','ornsvc.w','ornshi.w','ornsls.w','ornsge.w','ornslt.w','ornsgt.w','ornsle.w',
+ 'ornseq','ornsne','ornscs','ornshs','ornscc','ornslo','ornsmi','ornspl','ornsvs','ornsvc','ornshi','ornsls','ornsge','ornslt','ornsgt','ornsle',
+ 'eorseq.w','eorsne.w','eorscs.w','eorshs.w','eorscc.w','eorslo.w','eorsmi.w','eorspl.w','eorsvs.w','eorsvc.w','eorshi.w','eorsls.w','eorsge.w','eorslt.w','eorsgt.w','eorsle.w',
+ 'eorseq','eorsne','eorscs','eorshs','eorscc','eorslo','eorsmi','eorspl','eorsvs','eorsvc','eorshi','eorsls','eorsge','eorslt','eorsgt','eorsle',
+ 'mvnseq.w','mvnsne.w','mvnscs.w','mvnshs.w','mvnscc.w','mvnslo.w','mvnsmi.w','mvnspl.w','mvnsvs.w','mvnsvc.w','mvnshi.w','mvnsls.w','mvnsge.w','mvnslt.w','mvnsgt.w','mvnsle.w',
+ 'mvnseq','mvnsne','mvnscs','mvnshs','mvnscc','mvnslo','mvnsmi','mvnspl','mvnsvs','mvnsvc','mvnshi','mvnsls','mvnsge','mvnslt','mvnsgt','mvnsle',
+ 'movseq.w','movsne.w','movscs.w','movshs.w','movscc.w','movslo.w','movsmi.w','movspl.w','movsvs.w','movsvc.w','movshi.w','movsls.w','movsge.w','movslt.w','movsgt.w','movsle.w',
+ 'movseq','movsne','movscs','movshs','movscc','movslo','movsmi','movspl','movsvs','movsvc','movshi','movsls','movsge','movslt','movsgt','movsle',
+ 'teqeq','teqne','teqcs','teqhs','teqcc','teqlo','teqmi','teqpl','teqvs','teqvc','teqhi','teqls','teqge','teqlt','teqgt','teqle',
+ 'tsteq.w','tstne.w','tstcs.w','tsths.w','tstcc.w','tstlo.w','tstmi.w','tstpl.w','tstvs.w','tstvc.w','tsthi.w','tstls.w','tstge.w','tstlt.w','tstgt.w','tstle.w',
+ 'tsteq','tstne','tstcs','tsths','tstcc','tstlo','tstmi','tstpl','tstvs','tstvc','tsthi','tstls','tstge','tstlt','tstgt','tstle',
+ 'mrseq','mrsne','mrscs','mrshs','mrscc','mrslo','mrsmi','mrspl','mrsvs','mrsvc','mrshi','mrsls','mrsge','mrslt','mrsgt','mrsle',
+ 'msreq','msrne','msrcs','msrhs','msrcc','msrlo','msrmi','msrpl','msrvs','msrvc','msrhi','msrls','msrge','msrlt','msrgt','msrle',
+ /* Set Flags: Conditional Shifts and Rotates */
+ 'asrseq.w','asrsne.w','asrscs.w','asrshs.w','asrscc.w','asrslo.w','asrsmi.w','asrspl.w','asrsvs.w','asrsvc.w','asrshi.w','asrsls.w','asrsge.w','asrslt.w','asrsgt.w','asrsle.w',
+ 'asrseq','asrsne','asrscs','asrshs','asrscc','asrslo','asrsmi','asrspl','asrsvs','asrsvc','asrshi','asrsls','asrsge','asrslt','asrsgt','asrsle',
+ 'lslseq.w','lslsne.w','lslscs.w','lslshs.w','lslscc.w','lslslo.w','lslsmi.w','lslspl.w','lslsvs.w','lslsvc.w','lslshi.w','lslsls.w','lslsge.w','lslslt.w','lslsgt.w','lslsle.w',
+ 'lslseq','lslsne','lslscs','lslshs','lslscc','lslslo','lslsmi','lslspl','lslsvs','lslsvc','lslshi','lslsls','lslsge','lslslt','lslsgt','lslsle',
+ 'lsrseq.w','lsrsne.w','lsrscs.w','lsrshs.w','lsrscc.w','lsrslo.w','lsrsmi.w','lsrspl.w','lsrsvs.w','lsrsvc.w','lsrshi.w','lsrsls.w','lsrsge.w','lsrslt.w','lsrsgt.w','lsrsle.w',
+ 'lsrseq','lsrsne','lsrscs','lsrshs','lsrscc','lsrslo','lsrsmi','lsrspl','lsrsvs','lsrsvc','lsrshi','lsrsls','lsrsge','lsrslt','lsrsgt','lsrsle',
+ 'rorseq.w','rorsne.w','rorscs.w','rorshs.w','rorscc.w','rorslo.w','rorsmi.w','rorspl.w','rorsvs.w','rorsvc.w','rorshi.w','rorsls.w','rorsge.w','rorslt.w','rorsgt.w','rorsle.w',
+ 'rorseq','rorsne','rorscs','rorshs','rorscc','rorslo','rorsmi','rorspl','rorsvs','rorsvc','rorshi','rorsls','rorsge','rorslt','rorsgt','rorsle',
+ 'rrxseq','rrxsne','rrxscs','rrxshs','rrxscc','rrxslo','rrxsmi','rrxspl','rrxsvs','rrxsvc','rrxshi','rrxsls','rrxsge','rrxslt','rrxsgt','rrxsle',
+ /* Set Flags: Conditional Multiply and Multiply-Add */
+ 'mlaseq','mlasne','mlascs','mlashs','mlascc','mlaslo','mlasmi','mlaspl','mlasvs','mlasvc','mlashi','mlasls','mlasge','mlaslt','mlasgt','mlasle',
+ 'smullseq','smullsne','smullscs','smullshs','smullscc','smullslo','smullsmi','smullspl','smullsvs','smullsvc','smullshi','smullsls','smullsge','smullslt','smullsgt','smullsle',
+ 'umullseq','umullsne','umullscs','umullshs','umullscc','umullslo','umullsmi','umullspl','umullsvs','umullsvc','umullshi','umullsls','umullsge','umullslt','umullsgt','umullsle',
+ 'smlalseq','smlalsne','smlalscs','smlalshs','smlalscc','smlalslo','smlalsmi','smlalspl','smlalsvs','smlalsvc','smlalshi','smlalsls','smlalsge','smlalslt','smlalsgt','smlalsle',
+ 'umlalseq','umlalsne','umlalscs','umlalshs','umlalscc','umlalslo','umlalsmi','umlalspl','umlalsvs','umlalsvc','umlalshi','umlalsls','umlalsge','umlalslt','umlalsgt','umlalsle'
+ ),
+ /* Unconditional Flow Control Instructions */
+ 7 => array(
+ /* Flow Control: Unconditional Branch and If-Then-Else */
+ 'b.w','bal.w',
+ 'b','bal',
+ 'bl','blal',
+ 'bx','bxal',
+ 'blx','blxal',
+ 'bxj','bxjal',
+ 'cbnz',
+ 'cbz',
+ 'tbb','tbbal',
+ 'tbh','tbhal',
+ 'it',
+ 'itt',
+ 'ite',
+ 'ittt',
+ 'itet',
+ 'itte',
+ 'itee',
+ 'itttt',
+ 'itett',
+ 'ittet',
+ 'iteet',
+ 'ittte',
+ 'itete',
+ 'ittee',
+ 'iteee'
+ ),
+ /* Conditional Flow Control Instructions */
+ 8 => array(
+ /* Flow Control: Conditional Branch and If-Then-Else */
+ 'beq.w','bne.w','bcs.w','bhs.w','bcc.w','blo.w','bmi.w','bpl.w','bvs.w','bvc.w','bhi.w','bls.w','bge.w','blt.w','bgt.w','ble.w',
+ 'beq','bne','bcs','bhs','bcc','blo','bmi','bpl','bvs','bvc','bhi','bls','bge','blt','bgt','ble',
+ 'bleq','blne','blcs','blhs','blcc','bllo','blmi','blpl','blvs','blvc','blhi','blls','blge','bllt','blgt','blle',
+ 'bxeq','bxne','bxcs','bxhs','bxcc','bxlo','bxmi','bxpl','bxvs','bxvc','bxhi','bxls','bxge','bxlt','bxgt','bxle',
+ 'blxeq','blxne','blxcs','blxhs','blxcc','blxlo','blxmi','blxpl','blxvs','blxvc','blxhi','blxls','blxge','blxlt','blxgt','blxle',
+ 'bxjeq','bxjne','bxjcs','bxjhs','bxjcc','bxjlo','bxjmi','bxjpl','bxjvs','bxjvc','bxjhi','bxjls','bxjge','bxjlt','bxjgt','bxjle',
+ 'tbbeq','tbbne','tbbcs','tbbhs','tbbcc','tbblo','tbbmi','tbbpl','tbbvs','tbbvc','tbbhi','tbbls','tbbge','tbblt','tbbgt','tbble',
+ 'tbheq','tbhne','tbhcs','tbhhs','tbhcc','tbhlo','tbhmi','tbhpl','tbhvs','tbhvc','tbhhi','tbhls','tbhge','tbhlt','tbhgt','tbhle'
+ ),
+ /* Unconditional Syncronization Instructions */
+ 9 => array(
+ /* Synchronization: Unconditional Loads, Stores and Barriers */
+ 'ldrexd','ldrexdal',
+ 'ldrex','ldrexal',
+ 'ldrexh','ldrexhal',
+ 'ldrexb','ldrexbal',
+ 'strexd','strexdal',
+ 'strex','strexal',
+ 'strexh','strexhal',
+ 'strexb','strexbal',
+ 'clrex','clrexal',
+ 'swp','swpal',
+ 'swpb','swpbal',
+ 'dbc','dbcal',
+ 'dsb','dsbal',
+ 'isb','isbal',
+ 'yield.w','yieldal.w',
+ 'yield','yieldal',
+ 'nop.w','nopal.w',
+ 'nop','nopal'
+ ),
+ /* Conditional Syncronization Instructions */
+ 10 => array(
+ /* Synchronization: Conditional Loads, Stores and Barriers */
+ 'ldrexdeq','ldrexdne','ldrexdcs','ldrexdhs','ldrexdcc','ldrexdlo','ldrexdmi','ldrexdpl','ldrexdvs','ldrexdvc','ldrexdhi','ldrexdls','ldrexdge','ldrexdlt','ldrexdgt','ldrexdle',
+ 'ldrexeq','ldrexne','ldrexcs','ldrexhs','ldrexcc','ldrexlo','ldrexmi','ldrexpl','ldrexvs','ldrexvc','ldrexhi','ldrexls','ldrexge','ldrexlt','ldrexgt','ldrexle',
+ 'ldrexheq','ldrexhne','ldrexhcs','ldrexhhs','ldrexhcc','ldrexhlo','ldrexhmi','ldrexhpl','ldrexhvs','ldrexhvc','ldrexhhi','ldrexhls','ldrexhge','ldrexhlt','ldrexhgt','ldrexhle',
+ 'ldrexbeq','ldrexbne','ldrexbcs','ldrexbhs','ldrexbcc','ldrexblo','ldrexbmi','ldrexbpl','ldrexbvs','ldrexbvc','ldrexbhi','ldrexbls','ldrexbge','ldrexblt','ldrexbgt','ldrexble',
+ 'strexdeq','strexdne','strexdcs','strexdhs','strexdcc','strexdlo','strexdmi','strexdpl','strexdvs','strexdvc','strexdhi','strexdls','strexdge','strexdlt','strexdgt','strexdle',
+ 'strexeq','strexne','strexcs','strexhs','strexcc','strexlo','strexmi','strexpl','strexvs','strexvc','strexhi','strexls','strexge','strexlt','strexgt','strexle',
+ 'strexheq','strexhne','strexhcs','strexhhs','strexhcc','strexhlo','strexhmi','strexhpl','strexhvs','strexhvc','strexhhi','strexhls','strexhge','strexhlt','strexhgt','strexhle',
+ 'strexbeq','strexbne','strexbcs','strexbhs','strexbcc','strexblo','strexbmi','strexbpl','strexbvs','strexbvc','strexbhi','strexbls','strexbge','strexblt','strexbgt','strexble',
+ 'clrexeq','clrexne','clrexcs','clrexhs','clrexcc','clrexlo','clrexmi','clrexpl','clrexvs','clrexvc','clrexhi','clrexls','clrexge','clrexlt','clrexgt','clrexle',
+ 'swpeq','swpne','swpcs','swphs','swpcc','swplo','swpmi','swppl','swpvs','swpvc','swphi','swpls','swpge','swplt','swpgt','swple',
+ 'swpbeq','swpbne','swpbcs','swpbhs','swpbcc','swpblo','swpbmi','swpbpl','swpbvs','swpbvc','swpbhi','swpbls','swpbge','swpblt','swpbgt','swpble',
+ 'dbceq','dbcne','dbccs','dbchs','dbccc','dbclo','dbcmi','dbcpl','dbcvs','dbcvc','dbchi','dbcls','dbcge','dbclt','dbcgt','dbcle',
+ 'dsbeq','dsbne','dsbcs','dsbhs','dsbcc','dsblo','dsbmi','dsbpl','dsbvs','dsbvc','dsbhi','dsbls','dsbge','dsblt','dsbgt','dsble',
+ 'isbeq','isbne','isbcs','isbhs','isbcc','isblo','isbmi','isbpl','isbvs','isbvc','isbhi','isbls','isbge','isblt','isbgt','isble',
+ 'yieldeq.w','yieldne.w','yieldcs.w','yieldhs.w','yieldcc.w','yieldlo.w','yieldmi.w','yieldpl.w','yieldvs.w','yieldvc.w','yieldhi.w','yieldls.w','yieldge.w','yieldlt.w','yieldgt.w','yieldle.w',
+ 'yieldeq','yieldne','yieldcs','yieldhs','yieldcc','yieldlo','yieldmi','yieldpl','yieldvs','yieldvc','yieldhi','yieldls','yieldge','yieldlt','yieldgt','yieldle',
+ 'nopeq.w','nopne.w','nopcs.w','nophs.w','nopcc.w','noplo.w','nopmi.w','noppl.w','nopvs.w','nopvc.w','nophi.w','nopls.w','nopge.w','noplt.w','nopgt.w','nople.w',
+ 'nopeq','nopne','nopcs','nophs','nopcc','noplo','nopmi','noppl','nopvs','nopvc','nophi','nopls','nopge','noplt','nopgt','nople'
+ ),
+ /* Unconditional ARMv6 SIMD */
+ 11 => array(
+ /* ARMv6 SIMD: Unconditional Addition, Subtraction & Saturation */
+ 'sadd16','sadd16al',
+ 'sadd8','sadd8al',
+ 'uadd16','uadd16al',
+ 'uadd8','uadd8al',
+ 'ssub16','ssub16al',
+ 'ssub8','ssub8al',
+ 'usub16','usub16al',
+ 'usub8','usub8al',
+ 'sasx','sasxal',
+ 'ssax','ssaxal',
+ 'uasx','uasxal',
+ 'usax','usaxal',
+ 'usad8','usad8al',
+ 'usada8','usada8al',
+ /* ARMv6 SIMD: Unconditional Halving Addition & Subtraction */
+ 'shadd16','shadd16al',
+ 'shadd8','shadd8al',
+ 'uhadd16','uhadd16al',
+ 'uhadd8','uhadd8al',
+ 'shsub16','shsub16al',
+ 'shsub8','shsub8al',
+ 'uhsub16','uhsub16al',
+ 'uhsub8','uhsub8al',
+ 'shasx','shasxal',
+ 'shsax','shsaxal',
+ 'uhasx','uhasxal',
+ 'uhsax','uhsaxal',
+ /* ARMv6 SIMD: Unconditional Saturating Operations */
+ 'qadd','qaddal',
+ 'qadd16','qadd16al',
+ 'qadd8','qadd8al',
+ 'uqadd16','uqadd16al',
+ 'uqadd8','uqadd8al',
+ 'qsub','qsubal',
+ 'qsub16','qsub16al',
+ 'qsub8','qsub8al',
+ 'uqsub16','uqsub16al',
+ 'uqsub8','uqsub8al',
+ 'qasx','qasxal',
+ 'qsax','qsaxal',
+ 'uqasx','uqasxal',
+ 'uqsax','uqsaxal',
+ 'qdadd','qdaddal',
+ 'qdsub','qdsubal',
+ 'ssat','ssatal',
+ 'ssat16','ssat16al',
+ 'usat','usatal',
+ 'usat16','usat16al',
+ /* ARMv6 SIMD: Unconditional Permutation and Combine Operations */
+ 'sxtah','sxtahal',
+ 'sxtab','sxtabal',
+ 'sxtab16','sxtab16al',
+ 'uxtah','uxtahal',
+ 'uxtab','uxtabal',
+ 'uxtab16','uxtab16al',
+ 'sxth.w','sxthal.w',
+ 'sxth','sxthal',
+ 'sxtb.w','sxtbal.w',
+ 'sxtb','sxtbal',
+ 'sxtb16','sxtb16al',
+ 'uxth.w','uxthal.w',
+ 'uxth','uxthal',
+ 'uxtb.w','uxtbal.w',
+ 'uxtb','uxtbal',
+ 'uxtb16','uxtb16al',
+ 'pkhbt','pkhbtal',
+ 'pkhtb','pkhtbal',
+ 'rbit','rbital',
+ 'rev.w','reval.w',
+ 'rev','reval',
+ 'rev16.w','rev16al.w',
+ 'rev16','rev16al',
+ 'revsh.w','revshal.w',
+ 'revsh','revshal',
+ 'sel','selal',
+ /* ARMv6 SIMD: Unconditional Multiply and Multiply-Add */
+ 'smlad','smladal',
+ 'smladx','smladxal',
+ 'smlsd','smlsdal',
+ 'smlsdx','smlsdxal',
+ 'smlald','smlaldal',
+ 'smlaldx','smlaldxal',
+ 'smlsld','smlsldal',
+ 'smlsldx','smlsldxal',
+ 'smmul','smmulal',
+ 'smmulr','smmulral',
+ 'smmla','smmlaal',
+ 'smmlar','smmlaral',
+ 'smmls','smmlsal',
+ 'smmlsr','smmlsral',
+ 'smuad','smuadal',
+ 'smuadx','smuadxal',
+ 'smusd','smusdal',
+ 'smusdx','smusdxal',
+ 'umaal','umaalal'
+ ),
+ /* Conditional ARMv6 SIMD */
+ 12 => array(
+ /* ARMv6 SIMD: Conditional Addition, Subtraction & Saturation */
+ 'sadd16eq','sadd16ne','sadd16cs','sadd16hs','sadd16cc','sadd16lo','sadd16mi','sadd16pl','sadd16vs','sadd16vc','sadd16hi','sadd16ls','sadd16ge','sadd16lt','sadd16gt','sadd16le',
+ 'sadd8eq','sadd8ne','sadd8cs','sadd8hs','sadd8cc','sadd8lo','sadd8mi','sadd8pl','sadd8vs','sadd8vc','sadd8hi','sadd8ls','sadd8ge','sadd8lt','sadd8gt','sadd8le',
+ 'uadd16eq','uadd16ne','uadd16cs','uadd16hs','uadd16cc','uadd16lo','uadd16mi','uadd16pl','uadd16vs','uadd16vc','uadd16hi','uadd16ls','uadd16ge','uadd16lt','uadd16gt','uadd16le',
+ 'uadd8eq','uadd8ne','uadd8cs','uadd8hs','uadd8cc','uadd8lo','uadd8mi','uadd8pl','uadd8vs','uadd8vc','uadd8hi','uadd8ls','uadd8ge','uadd8lt','uadd8gt','uadd8le',
+ 'ssub16eq','ssub16ne','ssub16cs','ssub16hs','ssub16cc','ssub16lo','ssub16mi','ssub16pl','ssub16vs','ssub16vc','ssub16hi','ssub16ls','ssub16ge','ssub16lt','ssub16gt','ssub16le',
+ 'ssub8eq','ssub8ne','ssub8cs','ssub8hs','ssub8cc','ssub8lo','ssub8mi','ssub8pl','ssub8vs','ssub8vc','ssub8hi','ssub8ls','ssub8ge','ssub8lt','ssub8gt','ssub8le',
+ 'usub16eq','usub16ne','usub16cs','usub16hs','usub16cc','usub16lo','usub16mi','usub16pl','usub16vs','usub16vc','usub16hi','usub16ls','usub16ge','usub16lt','usub16gt','usub16le',
+ 'usub8eq','usub8ne','usub8cs','usub8hs','usub8cc','usub8lo','usub8mi','usub8pl','usub8vs','usub8vc','usub8hi','usub8ls','usub8ge','usub8lt','usub8gt','usub8le',
+ 'sasxeq','sasxne','sasxcs','sasxhs','sasxcc','sasxlo','sasxmi','sasxpl','sasxvs','sasxvc','sasxhi','sasxls','sasxge','sasxlt','sasxgt','sasxle',
+ 'ssaxeq','ssaxne','ssaxcs','ssaxhs','ssaxcc','ssaxlo','ssaxmi','ssaxpl','ssaxvs','ssaxvc','ssaxhi','ssaxls','ssaxge','ssaxlt','ssaxgt','ssaxle',
+ 'uasxeq','uasxne','uasxcs','uasxhs','uasxcc','uasxlo','uasxmi','uasxpl','uasxvs','uasxvc','uasxhi','uasxls','uasxge','uasxlt','uasxgt','uasxle',
+ 'usaxeq','usaxne','usaxcs','usaxhs','usaxcc','usaxlo','usaxmi','usaxpl','usaxvs','usaxvc','usaxhi','usaxls','usaxge','usaxlt','usaxgt','usaxle',
+ 'usad8eq','usad8ne','usad8cs','usad8hs','usad8cc','usad8lo','usad8mi','usad8pl','usad8vs','usad8vc','usad8hi','usad8ls','usad8ge','usad8lt','usad8gt','usad8le',
+ 'usada8eq','usada8ne','usada8cs','usada8hs','usada8cc','usada8lo','usada8mi','usada8pl','usada8vs','usada8vc','usada8hi','usada8ls','usada8ge','usada8lt','usada8gt','usada8le',
+ /* ARMv6 SIMD: Conditional Halving Addition & Subtraction */
+ 'shadd16eq','shadd16ne','shadd16cs','shadd16hs','shadd16cc','shadd16lo','shadd16mi','shadd16pl','shadd16vs','shadd16vc','shadd16hi','shadd16ls','shadd16ge','shadd16lt','shadd16gt','shadd16le',
+ 'shadd8eq','shadd8ne','shadd8cs','shadd8hs','shadd8cc','shadd8lo','shadd8mi','shadd8pl','shadd8vs','shadd8vc','shadd8hi','shadd8ls','shadd8ge','shadd8lt','shadd8gt','shadd8le',
+ 'uhadd16eq','uhadd16ne','uhadd16cs','uhadd16hs','uhadd16cc','uhadd16lo','uhadd16mi','uhadd16pl','uhadd16vs','uhadd16vc','uhadd16hi','uhadd16ls','uhadd16ge','uhadd16lt','uhadd16gt','uhadd16le',
+ 'uhadd8eq','uhadd8ne','uhadd8cs','uhadd8hs','uhadd8cc','uhadd8lo','uhadd8mi','uhadd8pl','uhadd8vs','uhadd8vc','uhadd8hi','uhadd8ls','uhadd8ge','uhadd8lt','uhadd8gt','uhadd8le',
+ 'shsub16eq','shsub16ne','shsub16cs','shsub16hs','shsub16cc','shsub16lo','shsub16mi','shsub16pl','shsub16vs','shsub16vc','shsub16hi','shsub16ls','shsub16ge','shsub16lt','shsub16gt','shsub16le',
+ 'shsub8eq','shsub8ne','shsub8cs','shsub8hs','shsub8cc','shsub8lo','shsub8mi','shsub8pl','shsub8vs','shsub8vc','shsub8hi','shsub8ls','shsub8ge','shsub8lt','shsub8gt','shsub8le',
+ 'uhsub16eq','uhsub16ne','uhsub16cs','uhsub16hs','uhsub16cc','uhsub16lo','uhsub16mi','uhsub16pl','uhsub16vs','uhsub16vc','uhsub16hi','uhsub16ls','uhsub16ge','uhsub16lt','uhsub16gt','uhsub16le',
+ 'uhsub8eq','uhsub8ne','uhsub8cs','uhsub8hs','uhsub8cc','uhsub8lo','uhsub8mi','uhsub8pl','uhsub8vs','uhsub8vc','uhsub8hi','uhsub8ls','uhsub8ge','uhsub8lt','uhsub8gt','uhsub8le',
+ 'shasxeq','shasxne','shasxcs','shasxhs','shasxcc','shasxlo','shasxmi','shasxpl','shasxvs','shasxvc','shasxhi','shasxls','shasxge','shasxlt','shasxgt','shasxle',
+ 'shsaxeq','shsaxne','shsaxcs','shsaxhs','shsaxcc','shsaxlo','shsaxmi','shsaxpl','shsaxvs','shsaxvc','shsaxhi','shsaxls','shsaxge','shsaxlt','shsaxgt','shsaxle',
+ 'uhasxeq','uhasxne','uhasxcs','uhasxhs','uhasxcc','uhasxlo','uhasxmi','uhasxpl','uhasxvs','uhasxvc','uhasxhi','uhasxls','uhasxge','uhasxlt','uhasxgt','uhasxle',
+ 'uhsaxeq','uhsaxne','uhsaxcs','uhsaxhs','uhsaxcc','uhsaxlo','uhsaxmi','uhsaxpl','uhsaxvs','uhsaxvc','uhsaxhi','uhsaxls','uhsaxge','uhsaxlt','uhsaxgt','uhsaxle',
+ /* ARMv6 SIMD: Conditional Saturating Operations */
+ 'qaddeq','qaddne','qaddcs','qaddhs','qaddcc','qaddlo','qaddmi','qaddpl','qaddvs','qaddvc','qaddhi','qaddls','qaddge','qaddlt','qaddgt','qaddle',
+ 'qadd16eq','qadd16ne','qadd16cs','qadd16hs','qadd16cc','qadd16lo','qadd16mi','qadd16pl','qadd16vs','qadd16vc','qadd16hi','qadd16ls','qadd16ge','qadd16lt','qadd16gt','qadd16le',
+ 'qadd8eq','qadd8ne','qadd8cs','qadd8hs','qadd8cc','qadd8lo','qadd8mi','qadd8pl','qadd8vs','qadd8vc','qadd8hi','qadd8ls','qadd8ge','qadd8lt','qadd8gt','qadd8le',
+ 'uqadd16eq','uqadd16ne','uqadd16cs','uqadd16hs','uqadd16cc','uqadd16lo','uqadd16mi','uqadd16pl','uqadd16vs','uqadd16vc','uqadd16hi','uqadd16ls','uqadd16ge','uqadd16lt','uqadd16gt','uqadd16le',
+ 'uqadd8eq','uqadd8ne','uqadd8cs','uqadd8hs','uqadd8cc','uqadd8lo','uqadd8mi','uqadd8pl','uqadd8vs','uqadd8vc','uqadd8hi','uqadd8ls','uqadd8ge','uqadd8lt','uqadd8gt','uqadd8le',
+ 'qsubeq','qsubne','qsubcs','qsubhs','qsubcc','qsublo','qsubmi','qsubpl','qsubvs','qsubvc','qsubhi','qsubls','qsubge','qsublt','qsubgt','qsuble',
+ 'qsub16eq','qsub16ne','qsub16cs','qsub16hs','qsub16cc','qsub16lo','qsub16mi','qsub16pl','qsub16vs','qsub16vc','qsub16hi','qsub16ls','qsub16ge','qsub16lt','qsub16gt','qsub16le',
+ 'qsub8eq','qsub8ne','qsub8cs','qsub8hs','qsub8cc','qsub8lo','qsub8mi','qsub8pl','qsub8vs','qsub8vc','qsub8hi','qsub8ls','qsub8ge','qsub8lt','qsub8gt','qsub8le',
+ 'uqsub16eq','uqsub16ne','uqsub16cs','uqsub16hs','uqsub16cc','uqsub16lo','uqsub16mi','uqsub16pl','uqsub16vs','uqsub16vc','uqsub16hi','uqsub16ls','uqsub16ge','uqsub16lt','uqsub16gt','uqsub16le',
+ 'uqsub8eq','uqsub8ne','uqsub8cs','uqsub8hs','uqsub8cc','uqsub8lo','uqsub8mi','uqsub8pl','uqsub8vs','uqsub8vc','uqsub8hi','uqsub8ls','uqsub8ge','uqsub8lt','uqsub8gt','uqsub8le',
+ 'qasxeq','qasxne','qasxcs','qasxhs','qasxcc','qasxlo','qasxmi','qasxpl','qasxvs','qasxvc','qasxhi','qasxls','qasxge','qasxlt','qasxgt','qasxle',
+ 'qsaxeq','qsaxne','qsaxcs','qsaxhs','qsaxcc','qsaxlo','qsaxmi','qsaxpl','qsaxvs','qsaxvc','qsaxhi','qsaxls','qsaxge','qsaxlt','qsaxgt','qsaxle',
+ 'uqasxeq','uqasxne','uqasxcs','uqasxhs','uqasxcc','uqasxlo','uqasxmi','uqasxpl','uqasxvs','uqasxvc','uqasxhi','uqasxls','uqasxge','uqasxlt','uqasxgt','uqasxle',
+ 'uqsaxeq','uqsaxne','uqsaxcs','uqsaxhs','uqsaxcc','uqsaxlo','uqsaxmi','uqsaxpl','uqsaxvs','uqsaxvc','uqsaxhi','uqsaxls','uqsaxge','uqsaxlt','uqsaxgt','uqsaxle',
+ 'qdaddeq','qdaddne','qdaddcs','qdaddhs','qdaddcc','qdaddlo','qdaddmi','qdaddpl','qdaddvs','qdaddvc','qdaddhi','qdaddls','qdaddge','qdaddlt','qdaddgt','qdaddle',
+ 'qdsubeq','qdsubne','qdsubcs','qdsubhs','qdsubcc','qdsublo','qdsubmi','qdsubpl','qdsubvs','qdsubvc','qdsubhi','qdsubls','qdsubge','qdsublt','qdsubgt','qdsuble',
+ 'ssateq','ssatne','ssatcs','ssaths','ssatcc','ssatlo','ssatmi','ssatpl','ssatvs','ssatvc','ssathi','ssatls','ssatge','ssatlt','ssatgt','ssatle',
+ 'ssat16eq','ssat16ne','ssat16cs','ssat16hs','ssat16cc','ssat16lo','ssat16mi','ssat16pl','ssat16vs','ssat16vc','ssat16hi','ssat16ls','ssat16ge','ssat16lt','ssat16gt','ssat16le',
+ 'usateq','usatne','usatcs','usaths','usatcc','usatlo','usatmi','usatpl','usatvs','usatvc','usathi','usatls','usatge','usatlt','usatgt','usatle',
+ 'usat16eq','usat16ne','usat16cs','usat16hs','usat16cc','usat16lo','usat16mi','usat16pl','usat16vs','usat16vc','usat16hi','usat16ls','usat16ge','usat16lt','usat16gt','usat16le',
+ /* ARMv6 SIMD: Conditional Permutation and Combine Operations */
+ 'sxtaheq','sxtahne','sxtahcs','sxtahhs','sxtahcc','sxtahlo','sxtahmi','sxtahpl','sxtahvs','sxtahvc','sxtahhi','sxtahls','sxtahge','sxtahlt','sxtahgt','sxtahle',
+ 'sxtabeq','sxtabne','sxtabcs','sxtabhs','sxtabcc','sxtablo','sxtabmi','sxtabpl','sxtabvs','sxtabvc','sxtabhi','sxtabls','sxtabge','sxtablt','sxtabgt','sxtable',
+ 'sxtab16eq','sxtab16ne','sxtab16cs','sxtab16hs','sxtab16cc','sxtab16lo','sxtab16mi','sxtab16pl','sxtab16vs','sxtab16vc','sxtab16hi','sxtab16ls','sxtab16ge','sxtab16lt','sxtab16gt','sxtab16le',
+ 'uxtaheq','uxtahne','uxtahcs','uxtahhs','uxtahcc','uxtahlo','uxtahmi','uxtahpl','uxtahvs','uxtahvc','uxtahhi','uxtahls','uxtahge','uxtahlt','uxtahgt','uxtahle',
+ 'uxtabeq','uxtabne','uxtabcs','uxtabhs','uxtabcc','uxtablo','uxtabmi','uxtabpl','uxtabvs','uxtabvc','uxtabhi','uxtabls','uxtabge','uxtablt','uxtabgt','uxtable',
+ 'uxtab16eq','uxtab16ne','uxtab16cs','uxtab16hs','uxtab16cc','uxtab16lo','uxtab16mi','uxtab16pl','uxtab16vs','uxtab16vc','uxtab16hi','uxtab16ls','uxtab16ge','uxtab16lt','uxtab16gt','uxtab16le',
+ 'sxtheq.w','sxthne.w','sxthcs.w','sxthhs.w','sxthcc.w','sxthlo.w','sxthmi.w','sxthpl.w','sxthvs.w','sxthvc.w','sxthhi.w','sxthls.w','sxthge.w','sxthlt.w','sxthgt.w','sxthle.w',
+ 'sxtheq','sxthne','sxthcs','sxthhs','sxthcc','sxthlo','sxthmi','sxthpl','sxthvs','sxthvc','sxthhi','sxthls','sxthge','sxthlt','sxthgt','sxthle',
+ 'sxtbeq.w','sxtbne.w','sxtbcs.w','sxtbhs.w','sxtbcc.w','sxtblo.w','sxtbmi.w','sxtbpl.w','sxtbvs.w','sxtbvc.w','sxtbhi.w','sxtbls.w','sxtbge.w','sxtblt.w','sxtbgt.w','sxtble.w',
+ 'sxtbeq','sxtbne','sxtbcs','sxtbhs','sxtbcc','sxtblo','sxtbmi','sxtbpl','sxtbvs','sxtbvc','sxtbhi','sxtbls','sxtbge','sxtblt','sxtbgt','sxtble',
+ 'sxtb16eq','sxtb16ne','sxtb16cs','sxtb16hs','sxtb16cc','sxtb16lo','sxtb16mi','sxtb16pl','sxtb16vs','sxtb16vc','sxtb16hi','sxtb16ls','sxtb16ge','sxtb16lt','sxtb16gt','sxtb16le',
+ 'uxtheq.w','uxthne.w','uxthcs.w','uxthhs.w','uxthcc.w','uxthlo.w','uxthmi.w','uxthpl.w','uxthvs.w','uxthvc.w','uxthhi.w','uxthls.w','uxthge.w','uxthlt.w','uxthgt.w','uxthle.w',
+ 'uxtheq','uxthne','uxthcs','uxthhs','uxthcc','uxthlo','uxthmi','uxthpl','uxthvs','uxthvc','uxthhi','uxthls','uxthge','uxthlt','uxthgt','uxthle',
+ 'uxtbeq.w','uxtbne.w','uxtbcs.w','uxtbhs.w','uxtbcc.w','uxtblo.w','uxtbmi.w','uxtbpl.w','uxtbvs.w','uxtbvc.w','uxtbhi.w','uxtbls.w','uxtbge.w','uxtblt.w','uxtbgt.w','uxtble.w',
+ 'uxtbeq','uxtbne','uxtbcs','uxtbhs','uxtbcc','uxtblo','uxtbmi','uxtbpl','uxtbvs','uxtbvc','uxtbhi','uxtbls','uxtbge','uxtblt','uxtbgt','uxtble',
+ 'uxtb16eq','uxtb16ne','uxtb16cs','uxtb16hs','uxtb16cc','uxtb16lo','uxtb16mi','uxtb16pl','uxtb16vs','uxtb16vc','uxtb16hi','uxtb16ls','uxtb16ge','uxtb16lt','uxtb16gt','uxtb16le',
+ 'pkhbteq','pkhbtne','pkhbtcs','pkhbths','pkhbtcc','pkhbtlo','pkhbtmi','pkhbtpl','pkhbtvs','pkhbtvc','pkhbthi','pkhbtls','pkhbtge','pkhbtlt','pkhbtgt','pkhbtle',
+ 'pkhtbeq','pkhtbne','pkhtbcs','pkhtbhs','pkhtbcc','pkhtblo','pkhtbmi','pkhtbpl','pkhtbvs','pkhtbvc','pkhtbhi','pkhtbls','pkhtbge','pkhtblt','pkhtbgt','pkhtble',
+ 'rbiteq','rbitne','rbitcs','rbiths','rbitcc','rbitlo','rbitmi','rbitpl','rbitvs','rbitvc','rbithi','rbitls','rbitge','rbitlt','rbitgt','rbitle',
+ 'reveq.w','revne.w','revcs.w','revhs.w','revcc.w','revlo.w','revmi.w','revpl.w','revvs.w','revvc.w','revhi.w','revls.w','revge.w','revlt.w','revgt.w','revle.w',
+ 'reveq','revne','revcs','revhs','revcc','revlo','revmi','revpl','revvs','revvc','revhi','revls','revge','revlt','revgt','revle',
+ 'rev16eq.w','rev16ne.w','rev16cs.w','rev16hs.w','rev16cc.w','rev16lo.w','rev16mi.w','rev16pl.w','rev16vs.w','rev16vc.w','rev16hi.w','rev16ls.w','rev16ge.w','rev16lt.w','rev16gt.w','rev16le.w',
+ 'rev16eq','rev16ne','rev16cs','rev16hs','rev16cc','rev16lo','rev16mi','rev16pl','rev16vs','rev16vc','rev16hi','rev16ls','rev16ge','rev16lt','rev16gt','rev16le',
+ 'revsheq.w','revshne.w','revshcs.w','revshhs.w','revshcc.w','revshlo.w','revshmi.w','revshpl.w','revshvs.w','revshvc.w','revshhi.w','revshls.w','revshge.w','revshlt.w','revshgt.w','revshle.w',
+ 'revsheq','revshne','revshcs','revshhs','revshcc','revshlo','revshmi','revshpl','revshvs','revshvc','revshhi','revshls','revshge','revshlt','revshgt','revshle',
+ 'seleq','selne','selcs','selhs','selcc','sello','selmi','selpl','selvs','selvc','selhi','sells','selge','sellt','selgt','selle',
+ /* ARMv6 SIMD: Conditional Multiply and Multiply-Add */
+ 'smladeq','smladne','smladcs','smladhs','smladcc','smladlo','smladmi','smladpl','smladvs','smladvc','smladhi','smladls','smladge','smladlt','smladgt','smladle',
+ 'smladxeq','smladxne','smladxcs','smladxhs','smladxcc','smladxlo','smladxmi','smladxpl','smladxvs','smladxvc','smladxhi','smladxls','smladxge','smladxlt','smladxgt','smladxle',
+ 'smlsdeq','smlsdne','smlsdcs','smlsdhs','smlsdcc','smlsdlo','smlsdmi','smlsdpl','smlsdvs','smlsdvc','smlsdhi','smlsdls','smlsdge','smlsdlt','smlsdgt','smlsdle',
+ 'smlsdxeq','smlsdxne','smlsdxcs','smlsdxhs','smlsdxcc','smlsdxlo','smlsdxmi','smlsdxpl','smlsdxvs','smlsdxvc','smlsdxhi','smlsdxls','smlsdxge','smlsdxlt','smlsdxgt','smlsdxle',
+ 'smlaldeq','smlaldne','smlaldcs','smlaldhs','smlaldcc','smlaldlo','smlaldmi','smlaldpl','smlaldvs','smlaldvc','smlaldhi','smlaldls','smlaldge','smlaldlt','smlaldgt','smlaldle',
+ 'smlaldxeq','smlaldxne','smlaldxcs','smlaldxhs','smlaldxcc','smlaldxlo','smlaldxmi','smlaldxpl','smlaldxvs','smlaldxvc','smlaldxhi','smlaldxls','smlaldxge','smlaldxlt','smlaldxgt','smlaldxle',
+ 'smlsldeq','smlsldne','smlsldcs','smlsldhs','smlsldcc','smlsldlo','smlsldmi','smlsldpl','smlsldvs','smlsldvc','smlsldhi','smlsldls','smlsldge','smlsldlt','smlsldgt','smlsldle',
+ 'smlsldxeq','smlsldxne','smlsldxcs','smlsldxhs','smlsldxcc','smlsldxlo','smlsldxmi','smlsldxpl','smlsldxvs','smlsldxvc','smlsldxhi','smlsldxls','smlsldxge','smlsldxlt','smlsldxgt','smlsldxle',
+ 'smmuleq','smmulne','smmulcs','smmulhs','smmulcc','smmullo','smmulmi','smmulpl','smmulvs','smmulvc','smmulhi','smmulls','smmulge','smmullt','smmulgt','smmulle',
+ 'smmulreq','smmulrne','smmulrcs','smmulrhs','smmulrcc','smmulrlo','smmulrmi','smmulrpl','smmulrvs','smmulrvc','smmulrhi','smmulrls','smmulrge','smmulrlt','smmulrgt','smmulrle',
+ 'smmlaeq','smmlane','smmlacs','smmlahs','smmlacc','smmlalo','smmlami','smmlapl','smmlavs','smmlavc','smmlahi','smmlals','smmlage','smmlalt','smmlagt','smmlale',
+ 'smmlareq','smmlarne','smmlarcs','smmlarhs','smmlarcc','smmlarlo','smmlarmi','smmlarpl','smmlarvs','smmlarvc','smmlarhi','smmlarls','smmlarge','smmlarlt','smmlargt','smmlarle',
+ 'smmlseq','smmlsne','smmlscs','smmlshs','smmlscc','smmlslo','smmlsmi','smmlspl','smmlsvs','smmlsvc','smmlshi','smmlsls','smmlsge','smmlslt','smmlsgt','smmlsle',
+ 'smmlsreq','smmlsrne','smmlsrcs','smmlsrhs','smmlsrcc','smmlsrlo','smmlsrmi','smmlsrpl','smmlsrvs','smmlsrvc','smmlsrhi','smmlsrls','smmlsrge','smmlsrlt','smmlsrgt','smmlsrle',
+ 'smuadeq','smuadne','smuadcs','smuadhs','smuadcc','smuadlo','smuadmi','smuadpl','smuadvs','smuadvc','smuadhi','smuadls','smuadge','smuadlt','smuadgt','smuadle',
+ 'smuadxeq','smuadxne','smuadxcs','smuadxhs','smuadxcc','smuadxlo','smuadxmi','smuadxpl','smuadxvs','smuadxvc','smuadxhi','smuadxls','smuadxge','smuadxlt','smuadxgt','smuadxle',
+ 'smusdeq','smusdne','smusdcs','smusdhs','smusdcc','smusdlo','smusdmi','smusdpl','smusdvs','smusdvc','smusdhi','smusdls','smusdge','smusdlt','smusdgt','smusdle',
+ 'smusdxeq','smusdxne','smusdxcs','smusdxhs','smusdxcc','smusdxlo','smusdxmi','smusdxpl','smusdxvs','smusdxvc','smusdxhi','smusdxls','smusdxge','smusdxlt','smusdxgt','smusdxle',
+ 'umaaleq','umaalne','umaalcs','umaalhs','umaalcc','umaallo','umaalmi','umaalpl','umaalvs','umaalvc','umaalhi','umaalls','umaalge','umaallt','umaalgt','umaalle'
+ ),
+ /* Unconditional Coprocessor Instructions */
+ 13 => array(
+ /* Data Processing: Unconditional Coprocessor Instructions */
+ 'cdp','cdpal',
+ 'cdp2','cdp2al',
+ 'ldc','ldcal',
+ 'ldcl','ldclal',
+ 'ldc2','ldc2al',
+ 'ldc2l','ldc2lal',
+ 'stc','stcal',
+ 'stcl','stclal',
+ 'stc2','stc2al',
+ 'stc2l','stc2lal',
+ 'mcr','mcral',
+ 'mcr2','mcr2al',
+ 'mcrr','mcrral',
+ 'mcrr2','mcrr2al',
+ 'mrc','mrcal',
+ 'mrc2','mrc2al',
+ 'mrrc','mrrcal',
+ 'mrrc2','mrrc2al'
+ ),
+ /* Conditional Coprocessor Instructions */
+ 14 => array(
+ /* Data Processing: Conditional Coprocessor Instructions */
+ 'cdpeq','cdpne','cdpcs','cdphs','cdpcc','cdplo','cdpmi','cdppl','cdpvs','cdpvc','cdphi','cdpls','cdpge','cdplt','cdpgt','cdple',
+ 'cdp2eq','cdp2ne','cdp2cs','cdp2hs','cdp2cc','cdp2lo','cdp2mi','cdp2pl','cdp2vs','cdp2vc','cdp2hi','cdp2ls','cdp2ge','cdp2lt','cdp2gt','cdp2le',
+ 'ldceq','ldcne','ldccs','ldchs','ldccc','ldclo','ldcmi','ldcpl','ldcvs','ldcvc','ldchi','ldcls','ldcge','ldclt','ldcgt','ldcle',
+ 'ldcleq','ldclne','ldclcs','ldclhs','ldclcc','ldcllo','ldclmi','ldclpl','ldclvs','ldclvc','ldclhi','ldclls','ldclge','ldcllt','ldclgt','ldclle',
+ 'ldc2eq','ldc2ne','ldc2cs','ldc2hs','ldc2cc','ldc2lo','ldc2mi','ldc2pl','ldc2vs','ldc2vc','ldc2hi','ldc2ls','ldc2ge','ldc2lt','ldc2gt','ldc2le',
+ 'ldc2leq','ldc2lne','ldc2lcs','ldc2lhs','ldc2lcc','ldc2llo','ldc2lmi','ldc2lpl','ldc2lvs','ldc2lvc','ldc2lhi','ldc2lls','ldc2lge','ldc2llt','ldc2lgt','ldc2lle',
+ 'stceq','stcne','stccs','stchs','stccc','stclo','stcmi','stcpl','stcvs','stcvc','stchi','stcls','stcge','stclt','stcgt','stcle',
+ 'stcleq','stclne','stclcs','stclhs','stclcc','stcllo','stclmi','stclpl','stclvs','stclvc','stclhi','stclls','stclge','stcllt','stclgt','stclle',
+ 'stc2eq','stc2ne','stc2cs','stc2hs','stc2cc','stc2lo','stc2mi','stc2pl','stc2vs','stc2vc','stc2hi','stc2ls','stc2ge','stc2lt','stc2gt','stc2le',
+ 'stc2leq','stc2lne','stc2lcs','stc2lhs','stc2lcc','stc2llo','stc2lmi','stc2lpl','stc2lvs','stc2lvc','stc2lhi','stc2lls','stc2lge','stc2llt','stc2lgt','stc2lle',
+ 'mcreq','mcrne','mcrcs','mcrhs','mcrcc','mcrlo','mcrmi','mcrpl','mcrvs','mcrvc','mcrhi','mcrls','mcrge','mcrlt','mcrgt','mcrle',
+ 'mcr2eq','mcr2ne','mcr2cs','mcr2hs','mcr2cc','mcr2lo','mcr2mi','mcr2pl','mcr2vs','mcr2vc','mcr2hi','mcr2ls','mcr2ge','mcr2lt','mcr2gt','mcr2le',
+ 'mcrreq','mcrrne','mcrrcs','mcrrhs','mcrrcc','mcrrlo','mcrrmi','mcrrpl','mcrrvs','mcrrvc','mcrrhi','mcrrls','mcrrge','mcrrlt','mcrrgt','mcrrle',
+ 'mcrr2eq','mcrr2ne','mcrr2cs','mcrr2hs','mcrr2cc','mcrr2lo','mcrr2mi','mcrr2pl','mcrr2vs','mcrr2vc','mcrr2hi','mcrr2ls','mcrr2ge','mcrr2lt','mcrr2gt','mcrr2le',
+ 'mrceq','mrcne','mrccs','mrchs','mrccc','mrclo','mrcmi','mrcpl','mrcvs','mrcvc','mrchi','mrcls','mrcge','mrclt','mrcgt','mrcle',
+ 'mrc2eq','mrc2ne','mrc2cs','mrc2hs','mrc2cc','mrc2lo','mrc2mi','mrc2pl','mrc2vs','mrc2vc','mrc2hi','mrc2ls','mrc2ge','mrc2lt','mrc2gt','mrc2le',
+ 'mrrceq','mrrcne','mrrccs','mrrchs','mrrccc','mrrclo','mrrcmi','mrrcpl','mrrcvs','mrrcvc','mrrchi','mrrcls','mrrcge','mrrclt','mrrcgt','mrrcle',
+ 'mrrc2eq','mrrc2ne','mrrc2cs','mrrc2hs','mrrc2cc','mrrc2lo','mrrc2mi','mrrc2pl','mrrc2vs','mrrc2vc','mrrc2hi','mrrc2ls','mrrc2ge','mrrc2lt','mrrc2gt','mrrc2le'
+ ),
+ /* Unconditional System Instructions */
+ 15 => array(
+ /* System: Unconditional Debug and State-Change Instructions */
+ 'bkpt',
+ 'dbg','dbgal',
+ 'setend',
+ 'svc','svcal',
+ 'sev.w','seval.w',
+ 'sev','seval',
+ 'wfe.w','wfeal.w',
+ 'wfe','wfeal',
+ 'wfi.w','wfial.w',
+ 'wfi','wfial',
+ /* System: Unconditional ThumbEE Instructions */
+ 'enterx',
+ 'leavex',
+ 'chka.n','chkaal.n',
+ 'chka','chkaal',
+ 'hb.n','hbal.n',
+ 'hb','hbal',
+ 'hbl.n','hblal.n',
+ 'hbl','hblal',
+ 'hblp.n','hblpal.n',
+ 'hblp','hblpal',
+ 'hbp.n','hbpal.n',
+ 'hbp','hbpal',
+ /* System: Unconditional Privileged Instructions */
+ 'cpsie.n',
+ 'cpsie.w',
+ 'cpsie',
+ 'cpsid.n',
+ 'cpsid.w',
+ 'cpsid',
+ 'smc','smcal',
+ 'rfeda','rfedaal',
+ 'rfedb','rfedbal',
+ 'rfeia','rfeiaal',
+ 'rfeib','rfeibal',
+ 'srsda','srsdaal',
+ 'srsdb','srsdbal',
+ 'srsia','srsiaal',
+ 'srsib','srsibal'
+ ),
+ /* Conditional System Instructions */
+ 16 => array(
+ /* System: Conditional Debug and State-Change Instructions */
+ 'dbgeq','dbgne','dbgcs','dbghs','dbgcc','dbglo','dbgmi','dbgpl','dbgvs','dbgvc','dbghi','dbgls','dbgge','dbglt','dbggt','dbgle',
+ 'svceq','svcne','svccs','svchs','svccc','svclo','svcmi','svcpl','svcvs','svcvc','svchi','svcls','svcge','svclt','svcgt','svcle',
+ 'seveq.w','sevne.w','sevcs.w','sevhs.w','sevcc.w','sevlo.w','sevmi.w','sevpl.w','sevvs.w','sevvc.w','sevhi.w','sevls.w','sevge.w','sevlt.w','sevgt.w','sevle.w',
+ 'seveq','sevne','sevcs','sevhs','sevcc','sevlo','sevmi','sevpl','sevvs','sevvc','sevhi','sevls','sevge','sevlt','sevgt','sevle',
+ 'wfeeq.w','wfene.w','wfecs.w','wfehs.w','wfecc.w','wfelo.w','wfemi.w','wfepl.w','wfevs.w','wfevc.w','wfehi.w','wfels.w','wfege.w','wfelt.w','wfegt.w','wfele.w',
+ 'wfeeq','wfene','wfecs','wfehs','wfecc','wfelo','wfemi','wfepl','wfevs','wfevc','wfehi','wfels','wfege','wfelt','wfegt','wfele',
+ 'wfieq.w','wfine.w','wfics.w','wfihs.w','wficc.w','wfilo.w','wfimi.w','wfipl.w','wfivs.w','wfivc.w','wfihi.w','wfils.w','wfige.w','wfilt.w','wfigt.w','wfile.w',
+ 'wfieq','wfine','wfics','wfihs','wficc','wfilo','wfimi','wfipl','wfivs','wfivc','wfihi','wfils','wfige','wfilt','wfigt','wfile',
+ /* System: Conditional ThumbEE Instructions */
+ 'chkaeq.n','chkane.n','chkacs.n','chkahs.n','chkacc.n','chkalo.n','chkami.n','chkapl.n','chkavs.n','chkavc.n','chkahi.n','chkals.n','chkage.n','chkalt.n','chkagt.n','chkale.n',
+ 'chkaeq','chkane','chkacs','chkahs','chkacc','chkalo','chkami','chkapl','chkavs','chkavc','chkahi','chkals','chkage','chkalt','chkagt','chkale',
+ 'hbeq.n','hbne.n','hbcs.n','hbhs.n','hbcc.n','hblo.n','hbmi.n','hbpl.n','hbvs.n','hbvc.n','hbhi.n','hbls.n','hbge.n','hblt.n','hbgt.n','hble.n',
+ 'hbeq','hbne','hbcs','hbhs','hbcc','hblo','hbmi','hbpl','hbvs','hbvc','hbhi','hbls','hbge','hblt','hbgt','hble',
+ 'hbleq.n','hblne.n','hblcs.n','hblhs.n','hblcc.n','hbllo.n','hblmi.n','hblpl.n','hblvs.n','hblvc.n','hblhi.n','hblls.n','hblge.n','hbllt.n','hblgt.n','hblle.n',
+ 'hbleq','hblne','hblcs','hblhs','hblcc','hbllo','hblmi','hblpl','hblvs','hblvc','hblhi','hblls','hblge','hbllt','hblgt','hblle',
+ 'hblpeq.n','hblpne.n','hblpcs.n','hblphs.n','hblpcc.n','hblplo.n','hblpmi.n','hblppl.n','hblpvs.n','hblpvc.n','hblphi.n','hblpls.n','hblpge.n','hblplt.n','hblpgt.n','hblple.n',
+ 'hblpeq','hblpne','hblpcs','hblphs','hblpcc','hblplo','hblpmi','hblppl','hblpvs','hblpvc','hblphi','hblpls','hblpge','hblplt','hblpgt','hblple',
+ 'hbpeq.n','hbpne.n','hbpcs.n','hbphs.n','hbpcc.n','hbplo.n','hbpmi.n','hbppl.n','hbpvs.n','hbpvc.n','hbphi.n','hbpls.n','hbpge.n','hbplt.n','hbpgt.n','hbple.n',
+ 'hbpeq','hbpne','hbpcs','hbphs','hbpcc','hbplo','hbpmi','hbppl','hbpvs','hbpvc','hbphi','hbpls','hbpge','hbplt','hbpgt','hbple',
+ /* System: Conditional Privileged Instructions */
+ 'smceq','smcne','smccs','smchs','smccc','smclo','smcmi','smcpl','smcvs','smcvc','smchi','smcls','smcge','smclt','smcgt','smcle',
+ 'rfedaeq','rfedane','rfedacs','rfedahs','rfedacc','rfedalo','rfedami','rfedapl','rfedavs','rfedavc','rfedahi','rfedals','rfedage','rfedalt','rfedagt','rfedale',
+ 'rfedbeq','rfedbne','rfedbcs','rfedbhs','rfedbcc','rfedblo','rfedbmi','rfedbpl','rfedbvs','rfedbvc','rfedbhi','rfedbls','rfedbge','rfedblt','rfedbgt','rfedble',
+ 'rfeiaeq','rfeiane','rfeiacs','rfeiahs','rfeiacc','rfeialo','rfeiami','rfeiapl','rfeiavs','rfeiavc','rfeiahi','rfeials','rfeiage','rfeialt','rfeiagt','rfeiale',
+ 'rfeibeq','rfeibne','rfeibcs','rfeibhs','rfeibcc','rfeiblo','rfeibmi','rfeibpl','rfeibvs','rfeibvc','rfeibhi','rfeibls','rfeibge','rfeiblt','rfeibgt','rfeible',
+ 'srsdaeq','srsdane','srsdacs','srsdahs','srsdacc','srsdalo','srsdami','srsdapl','srsdavs','srsdavc','srsdahi','srsdals','srsdage','srsdalt','srsdagt','srsdale',
+ 'srsdbeq','srsdbne','srsdbcs','srsdbhs','srsdbcc','srsdblo','srsdbmi','srsdbpl','srsdbvs','srsdbvc','srsdbhi','srsdbls','srsdbge','srsdblt','srsdbgt','srsdble',
+ 'srsiaeq','srsiane','srsiacs','srsiahs','srsiacc','srsialo','srsiami','srsiapl','srsiavs','srsiavc','srsiahi','srsials','srsiage','srsialt','srsiagt','srsiale',
+ 'srsibeq','srsibne','srsibcs','srsibhs','srsibcc','srsiblo','srsibmi','srsibpl','srsibvs','srsibvc','srsibhi','srsibls','srsibge','srsiblt','srsibgt','srsible'
+ ),
+ /* Unconditional WMMX/WMMX2 instructions */
+ 17 => array(
+ /* Unconditional WMMX/WMMX2 SIMD Instructions */
+ 'tandcb','tandcbal',
+ 'tandch','tandchal',
+ 'tandcw','tandcwal',
+ 'tbcstb','tbcstbal',
+ 'tbcsth','tbcsthal',
+ 'tbcstw','tbcstwal',
+ 'textrcb','textrcbal',
+ 'textrch','textrchal',
+ 'textrcw','textrcwal',
+ 'textrmsb','textrmsbal',
+ 'textrmsh','textrmshal',
+ 'textrmsw','textrmswal',
+ 'textrmub','textrmubal',
+ 'textrmuh','textrmuhal',
+ 'textrmuw','textrmuwal',
+ 'tinsrb','tinsrbal',
+ 'tinsrh','tinsrhal',
+ 'tinsrw','tinsrwal',
+ 'tmcr','tmcral',
+ 'tmcrr','tmcrral',
+ 'tmia','tmiaal',
+ 'tmiaph','tmiaphal',
+ 'tmiabb','tmiabbal',
+ 'tmiabt','tmiabtal',
+ 'tmiatb','tmiatbal',
+ 'tmiatt','tmiattal',
+ 'tmovmskb','tmovmskbal',
+ 'tmovmskh','tmovmskhal',
+ 'tmovmskw','tmovmskwal',
+ 'tmrc','tmrcal',
+ 'tmrrc','tmrrcal',
+ 'torcb','torcbal',
+ 'torch','torchal',
+ 'torcw','torcwal',
+ 'torvscb','torvscbal',
+ 'torvsch','torvschal',
+ 'torvscw','torvscwal',
+ 'wabsb','wabsbal',
+ 'wabsh','wabshal',
+ 'wabsw','wabswal',
+ 'wabsdiffb','wabsdiffbal',
+ 'wabsdiffh','wabsdiffhal',
+ 'wabsdiffw','wabsdiffwal',
+ 'waccb','waccbal',
+ 'wacch','wacchal',
+ 'waccw','waccwal',
+ 'waddb','waddbal',
+ 'waddh','waddhal',
+ 'waddw','waddwal',
+ 'waddbc','waddbcal',
+ 'waddhc','waddhcal',
+ 'waddwc','waddwcal',
+ 'waddbss','waddbssal',
+ 'waddhss','waddhssal',
+ 'waddwss','waddwssal',
+ 'waddbus','waddbusal',
+ 'waddhus','waddhusal',
+ 'waddwus','waddwusal',
+ 'waddsubhx','waddsubhxal',
+ 'waligni','walignial',
+ 'walignr0','walignr0al',
+ 'walignr1','walignr1al',
+ 'walignr2','walignr2al',
+ 'walignr3','walignr3al',
+ 'wand','wandal',
+ 'wandn','wandnal',
+ 'wavg2b','wavg2bal',
+ 'wavg2h','wavg2hal',
+ 'wavg2br','wavg2bral',
+ 'wavg2hr','wavg2hral',
+ 'wavg4','wavg4al',
+ 'wavg4r','wavg4ral',
+ 'wcmpeqb','wcmpeqbal',
+ 'wcmpeqh','wcmpeqhal',
+ 'wcmpeqw','wcmpeqwal',
+ 'wcmpgtsb','wcmpgtsbal',
+ 'wcmpgtsh','wcmpgtshal',
+ 'wcmpgtsw','wcmpgtswal',
+ 'wcmpgtub','wcmpgtubal',
+ 'wcmpgtuh','wcmpgtuhal',
+ 'wcmpgtuw','wcmpgtuwal',
+ 'wldrb','wldrbal',
+ 'wldrh','wldrhal',
+ 'wldrw','wldrwal',
+ 'wldrd','wldrdal',
+ 'wmacs','wmacsal',
+ 'wmacu','wmacual',
+ 'wmacsz','wmacszal',
+ 'wmacuz','wmacuzal',
+ 'wmadds','wmaddsal',
+ 'wmaddu','wmaddual',
+ 'wmaddsx','wmaddsxal',
+ 'wmaddux','wmadduxal',
+ 'wmaddsn','wmaddsnal',
+ 'wmaddun','wmaddunal',
+ 'wmaxsb','wmaxsbal',
+ 'wmaxsh','wmaxshal',
+ 'wmaxsw','wmaxswal',
+ 'wmaxub','wmaxubal',
+ 'wmaxuh','wmaxuhal',
+ 'wmaxuw','wmaxuwal',
+ 'wmerge','wmergeal',
+ 'wmiabb','wmiabbal',
+ 'wmiabt','wmiabtal',
+ 'wmiatb','wmiatbal',
+ 'wmiatt','wmiattal',
+ 'wmiabbn','wmiabbnal',
+ 'wmiabtn','wmiabtnal',
+ 'wmiatbn','wmiatbnal',
+ 'wmiattn','wmiattnal',
+ 'wmiawbb','wmiawbbal',
+ 'wmiawbt','wmiawbtal',
+ 'wmiawtb','wmiawtbal',
+ 'wmiawtt','wmiawttal',
+ 'wmiawbbn','wmiawbbnal',
+ 'wmiawbtn','wmiawbtnal',
+ 'wmiawtbn','wmiawtbnal',
+ 'wmiawttn','wmiawttnal',
+ 'wminsb','wminsbal',
+ 'wminsh','wminshal',
+ 'wminsw','wminswal',
+ 'wminub','wminubal',
+ 'wminuh','wminuhal',
+ 'wminuw','wminuwal',
+ 'wmov','wmoval',
+ 'wmulsm','wmulsmal',
+ 'wmulsl','wmulslal',
+ 'wmulum','wmulumal',
+ 'wmulul','wmululal',
+ 'wmulsmr','wmulsmral',
+ 'wmulslr','wmulslral',
+ 'wmulumr','wmulumral',
+ 'wmululr','wmululral',
+ 'wmulwum','wmulwumal',
+ 'wmulwsm','wmulwsmal',
+ 'wmulwl','wmulwlal',
+ 'wmulwumr','wmulwumral',
+ 'wmulwsmr','wmulwsmral',
+ 'wor','woral',
+ 'wpackhss','wpackhssal',
+ 'wpackwss','wpackwssal',
+ 'wpackdss','wpackdssal',
+ 'wpackhus','wpackhusal',
+ 'wpackwus','wpackwusal',
+ 'wpackdus','wpackdusal',
+ 'wqmiabb','wqmiabbal',
+ 'wqmiabt','wqmiabtal',
+ 'wqmiatb','wqmiatbal',
+ 'wqmiatt','wqmiattal',
+ 'wqmiabbn','wqmiabbnal',
+ 'wqmiabtn','wqmiabtnal',
+ 'wqmiatbn','wqmiatbnal',
+ 'wqmiattn','wqmiattnal',
+ 'wqmulm','wqmulmal',
+ 'wqmulmr','wqmulmral',
+ 'wqmulwm','wqmulwmal',
+ 'wqmulwmr','wqmulwmral',
+ 'wrorh','wrorhal',
+ 'wrorw','wrorwal',
+ 'wrord','wrordal',
+ 'wrorhg','wrorhgal',
+ 'wrorwg','wrorwgal',
+ 'wrordg','wrordgal',
+ 'wsadb','wsadbal',
+ 'wsadh','wsadhal',
+ 'wsadbz','wsadbzal',
+ 'wsadhz','wsadhzal',
+ 'wshufh','wshufhal',
+ 'wsllh','wsllhal',
+ 'wsllw','wsllwal',
+ 'wslld','wslldal',
+ 'wsllhg','wsllhgal',
+ 'wsllwg','wsllwgal',
+ 'wslldg','wslldgal',
+ 'wsrah','wsrahal',
+ 'wsraw','wsrawal',
+ 'wsrad','wsradal',
+ 'wsrahg','wsrahgal',
+ 'wsrawg','wsrawgal',
+ 'wsradg','wsradgal',
+ 'wsrlh','wsrlhal',
+ 'wsrlw','wsrlwal',
+ 'wsrld','wsrldal',
+ 'wsrlhg','wsrlhgal',
+ 'wsrlwg','wsrlwgal',
+ 'wsrldg','wsrldgal',
+ 'wstrb','wstrbal',
+ 'wstrh','wstrhal',
+ 'wstrw','wstrwal',
+ 'wstrd','wstrdal',
+ 'wsubb','wsubbal',
+ 'wsubh','wsubhal',
+ 'wsubw','wsubwal',
+ 'wsubbss','wsubbssal',
+ 'wsubhss','wsubhssal',
+ 'wsubwss','wsubwssal',
+ 'wsubbus','wsubbusal',
+ 'wsubhus','wsubhusal',
+ 'wsubwus','wsubwusal',
+ 'wsubaddhx','wsubaddhxal',
+ 'wunpckehsb','wunpckehsbal',
+ 'wunpckehsh','wunpckehshal',
+ 'wunpckehsw','wunpckehswal',
+ 'wunpckehub','wunpckehubal',
+ 'wunpckehuh','wunpckehuhal',
+ 'wunpckehuw','wunpckehuwal',
+ 'wunpckihb','wunpckihbal',
+ 'wunpckihh','wunpckihhal',
+ 'wunpckihw','wunpckihwal',
+ 'wunpckelsb','wunpckelsbal',
+ 'wunpckelsh','wunpckelshal',
+ 'wunpckelsw','wunpckelswal',
+ 'wunpckelub','wunpckelubal',
+ 'wunpckeluh','wunpckeluhal',
+ 'wunpckeluw','wunpckeluwal',
+ 'wunpckilb','wunpckilbal',
+ 'wunpckilh','wunpckilhal',
+ 'wunpckilw','wunpckilwal',
+ 'wxor','wxoral',
+ 'wzero','wzeroal'
+ ),
+ /* Conditional WMMX/WMMX2 SIMD Instructions */
+ 18 => array(
+ /* Conditional WMMX/WMMX2 SIMD Instructions */
+ 'tandcbeq','tandcbne','tandcbcs','tandcbhs','tandcbcc','tandcblo','tandcbmi','tandcbpl','tandcbvs','tandcbvc','tandcbhi','tandcbls','tandcbge','tandcblt','tandcbgt','tandcble',
+ 'tandcheq','tandchne','tandchcs','tandchhs','tandchcc','tandchlo','tandchmi','tandchpl','tandchvs','tandchvc','tandchhi','tandchls','tandchge','tandchlt','tandchgt','tandchle',
+ 'tandcweq','tandcwne','tandcwcs','tandcwhs','tandcwcc','tandcwlo','tandcwmi','tandcwpl','tandcwvs','tandcwvc','tandcwhi','tandcwls','tandcwge','tandcwlt','tandcwgt','tandcwle',
+ 'tbcstbeq','tbcstbne','tbcstbcs','tbcstbhs','tbcstbcc','tbcstblo','tbcstbmi','tbcstbpl','tbcstbvs','tbcstbvc','tbcstbhi','tbcstbls','tbcstbge','tbcstblt','tbcstbgt','tbcstble',
+ 'tbcstheq','tbcsthne','tbcsthcs','tbcsthhs','tbcsthcc','tbcsthlo','tbcsthmi','tbcsthpl','tbcsthvs','tbcsthvc','tbcsthhi','tbcsthls','tbcsthge','tbcsthlt','tbcsthgt','tbcsthle',
+ 'tbcstweq','tbcstwne','tbcstwcs','tbcstwhs','tbcstwcc','tbcstwlo','tbcstwmi','tbcstwpl','tbcstwvs','tbcstwvc','tbcstwhi','tbcstwls','tbcstwge','tbcstwlt','tbcstwgt','tbcstwle',
+ 'textrcbeq','textrcbne','textrcbcs','textrcbhs','textrcbcc','textrcblo','textrcbmi','textrcbpl','textrcbvs','textrcbvc','textrcbhi','textrcbls','textrcbge','textrcblt','textrcbgt','textrcble',
+ 'textrcheq','textrchne','textrchcs','textrchhs','textrchcc','textrchlo','textrchmi','textrchpl','textrchvs','textrchvc','textrchhi','textrchls','textrchge','textrchlt','textrchgt','textrchle',
+ 'textrcweq','textrcwne','textrcwcs','textrcwhs','textrcwcc','textrcwlo','textrcwmi','textrcwpl','textrcwvs','textrcwvc','textrcwhi','textrcwls','textrcwge','textrcwlt','textrcwgt','textrcwle',
+ 'textrmsbeq','textrmsbne','textrmsbcs','textrmsbhs','textrmsbcc','textrmsblo','textrmsbmi','textrmsbpl','textrmsbvs','textrmsbvc','textrmsbhi','textrmsbls','textrmsbge','textrmsblt','textrmsbgt','textrmsble',
+ 'textrmsheq','textrmshne','textrmshcs','textrmshhs','textrmshcc','textrmshlo','textrmshmi','textrmshpl','textrmshvs','textrmshvc','textrmshhi','textrmshls','textrmshge','textrmshlt','textrmshgt','textrmshle',
+ 'textrmsweq','textrmswne','textrmswcs','textrmswhs','textrmswcc','textrmswlo','textrmswmi','textrmswpl','textrmswvs','textrmswvc','textrmswhi','textrmswls','textrmswge','textrmswlt','textrmswgt','textrmswle',
+ 'textrmubeq','textrmubne','textrmubcs','textrmubhs','textrmubcc','textrmublo','textrmubmi','textrmubpl','textrmubvs','textrmubvc','textrmubhi','textrmubls','textrmubge','textrmublt','textrmubgt','textrmuble',
+ 'textrmuheq','textrmuhne','textrmuhcs','textrmuhhs','textrmuhcc','textrmuhlo','textrmuhmi','textrmuhpl','textrmuhvs','textrmuhvc','textrmuhhi','textrmuhls','textrmuhge','textrmuhlt','textrmuhgt','textrmuhle',
+ 'textrmuweq','textrmuwne','textrmuwcs','textrmuwhs','textrmuwcc','textrmuwlo','textrmuwmi','textrmuwpl','textrmuwvs','textrmuwvc','textrmuwhi','textrmuwls','textrmuwge','textrmuwlt','textrmuwgt','textrmuwle',
+ 'tinsrbeq','tinsrbne','tinsrbcs','tinsrbhs','tinsrbcc','tinsrblo','tinsrbmi','tinsrbpl','tinsrbvs','tinsrbvc','tinsrbhi','tinsrbls','tinsrbge','tinsrblt','tinsrbgt','tinsrble',
+ 'tinsrheq','tinsrhne','tinsrhcs','tinsrhhs','tinsrhcc','tinsrhlo','tinsrhmi','tinsrhpl','tinsrhvs','tinsrhvc','tinsrhhi','tinsrhls','tinsrhge','tinsrhlt','tinsrhgt','tinsrhle',
+ 'tinsrweq','tinsrwne','tinsrwcs','tinsrwhs','tinsrwcc','tinsrwlo','tinsrwmi','tinsrwpl','tinsrwvs','tinsrwvc','tinsrwhi','tinsrwls','tinsrwge','tinsrwlt','tinsrwgt','tinsrwle',
+ 'tmcreq','tmcrne','tmcrcs','tmcrhs','tmcrcc','tmcrlo','tmcrmi','tmcrpl','tmcrvs','tmcrvc','tmcrhi','tmcrls','tmcrge','tmcrlt','tmcrgt','tmcrle',
+ 'tmcrreq','tmcrrne','tmcrrcs','tmcrrhs','tmcrrcc','tmcrrlo','tmcrrmi','tmcrrpl','tmcrrvs','tmcrrvc','tmcrrhi','tmcrrls','tmcrrge','tmcrrlt','tmcrrgt','tmcrrle',
+ 'tmiaeq','tmiane','tmiacs','tmiahs','tmiacc','tmialo','tmiami','tmiapl','tmiavs','tmiavc','tmiahi','tmials','tmiage','tmialt','tmiagt','tmiale',
+ 'tmiapheq','tmiaphne','tmiaphcs','tmiaphhs','tmiaphcc','tmiaphlo','tmiaphmi','tmiaphpl','tmiaphvs','tmiaphvc','tmiaphhi','tmiaphls','tmiaphge','tmiaphlt','tmiaphgt','tmiaphle',
+ 'tmiabbeq','tmiabbne','tmiabbcs','tmiabbhs','tmiabbcc','tmiabblo','tmiabbmi','tmiabbpl','tmiabbvs','tmiabbvc','tmiabbhi','tmiabbls','tmiabbge','tmiabblt','tmiabbgt','tmiabble',
+ 'tmiabteq','tmiabtne','tmiabtcs','tmiabths','tmiabtcc','tmiabtlo','tmiabtmi','tmiabtpl','tmiabtvs','tmiabtvc','tmiabthi','tmiabtls','tmiabtge','tmiabtlt','tmiabtgt','tmiabtle',
+ 'tmiatbeq','tmiatbne','tmiatbcs','tmiatbhs','tmiatbcc','tmiatblo','tmiatbmi','tmiatbpl','tmiatbvs','tmiatbvc','tmiatbhi','tmiatbls','tmiatbge','tmiatblt','tmiatbgt','tmiatble',
+ 'tmiatteq','tmiattne','tmiattcs','tmiatths','tmiattcc','tmiattlo','tmiattmi','tmiattpl','tmiattvs','tmiattvc','tmiatthi','tmiattls','tmiattge','tmiattlt','tmiattgt','tmiattle',
+ 'tmovmskbeq','tmovmskbne','tmovmskbcs','tmovmskbhs','tmovmskbcc','tmovmskblo','tmovmskbmi','tmovmskbpl','tmovmskbvs','tmovmskbvc','tmovmskbhi','tmovmskbls','tmovmskbge','tmovmskblt','tmovmskbgt','tmovmskble',
+ 'tmovmskheq','tmovmskhne','tmovmskhcs','tmovmskhhs','tmovmskhcc','tmovmskhlo','tmovmskhmi','tmovmskhpl','tmovmskhvs','tmovmskhvc','tmovmskhhi','tmovmskhls','tmovmskhge','tmovmskhlt','tmovmskhgt','tmovmskhle',
+ 'tmovmskweq','tmovmskwne','tmovmskwcs','tmovmskwhs','tmovmskwcc','tmovmskwlo','tmovmskwmi','tmovmskwpl','tmovmskwvs','tmovmskwvc','tmovmskwhi','tmovmskwls','tmovmskwge','tmovmskwlt','tmovmskwgt','tmovmskwle',
+ 'tmrceq','tmrcne','tmrccs','tmrchs','tmrccc','tmrclo','tmrcmi','tmrcpl','tmrcvs','tmrcvc','tmrchi','tmrcls','tmrcge','tmrclt','tmrcgt','tmrcle',
+ 'tmrrceq','tmrrcne','tmrrccs','tmrrchs','tmrrccc','tmrrclo','tmrrcmi','tmrrcpl','tmrrcvs','tmrrcvc','tmrrchi','tmrrcls','tmrrcge','tmrrclt','tmrrcgt','tmrrcle',
+ 'torcbeq','torcbne','torcbcs','torcbhs','torcbcc','torcblo','torcbmi','torcbpl','torcbvs','torcbvc','torcbhi','torcbls','torcbge','torcblt','torcbgt','torcble',
+ 'torcheq','torchne','torchcs','torchhs','torchcc','torchlo','torchmi','torchpl','torchvs','torchvc','torchhi','torchls','torchge','torchlt','torchgt','torchle',
+ 'torcweq','torcwne','torcwcs','torcwhs','torcwcc','torcwlo','torcwmi','torcwpl','torcwvs','torcwvc','torcwhi','torcwls','torcwge','torcwlt','torcwgt','torcwle',
+ 'torvscbeq','torvscbne','torvscbcs','torvscbhs','torvscbcc','torvscblo','torvscbmi','torvscbpl','torvscbvs','torvscbvc','torvscbhi','torvscbls','torvscbge','torvscblt','torvscbgt','torvscble',
+ 'torvscheq','torvschne','torvschcs','torvschhs','torvschcc','torvschlo','torvschmi','torvschpl','torvschvs','torvschvc','torvschhi','torvschls','torvschge','torvschlt','torvschgt','torvschle',
+ 'torvscweq','torvscwne','torvscwcs','torvscwhs','torvscwcc','torvscwlo','torvscwmi','torvscwpl','torvscwvs','torvscwvc','torvscwhi','torvscwls','torvscwge','torvscwlt','torvscwgt','torvscwle',
+ 'wabsbeq','wabsbne','wabsbcs','wabsbhs','wabsbcc','wabsblo','wabsbmi','wabsbpl','wabsbvs','wabsbvc','wabsbhi','wabsbls','wabsbge','wabsblt','wabsbgt','wabsble',
+ 'wabsheq','wabshne','wabshcs','wabshhs','wabshcc','wabshlo','wabshmi','wabshpl','wabshvs','wabshvc','wabshhi','wabshls','wabshge','wabshlt','wabshgt','wabshle',
+ 'wabsweq','wabswne','wabswcs','wabswhs','wabswcc','wabswlo','wabswmi','wabswpl','wabswvs','wabswvc','wabswhi','wabswls','wabswge','wabswlt','wabswgt','wabswle',
+ 'wabsdiffbeq','wabsdiffbne','wabsdiffbcs','wabsdiffbhs','wabsdiffbcc','wabsdiffblo','wabsdiffbmi','wabsdiffbpl','wabsdiffbvs','wabsdiffbvc','wabsdiffbhi','wabsdiffbls','wabsdiffbge','wabsdiffblt','wabsdiffbgt','wabsdiffble',
+ 'wabsdiffheq','wabsdiffhne','wabsdiffhcs','wabsdiffhhs','wabsdiffhcc','wabsdiffhlo','wabsdiffhmi','wabsdiffhpl','wabsdiffhvs','wabsdiffhvc','wabsdiffhhi','wabsdiffhls','wabsdiffhge','wabsdiffhlt','wabsdiffhgt','wabsdiffhle',
+ 'wabsdiffweq','wabsdiffwne','wabsdiffwcs','wabsdiffwhs','wabsdiffwcc','wabsdiffwlo','wabsdiffwmi','wabsdiffwpl','wabsdiffwvs','wabsdiffwvc','wabsdiffwhi','wabsdiffwls','wabsdiffwge','wabsdiffwlt','wabsdiffwgt','wabsdiffwle',
+ 'waccbeq','waccbne','waccbcs','waccbhs','waccbcc','waccblo','waccbmi','waccbpl','waccbvs','waccbvc','waccbhi','waccbls','waccbge','waccblt','waccbgt','waccble',
+ 'waccheq','wacchne','wacchcs','wacchhs','wacchcc','wacchlo','wacchmi','wacchpl','wacchvs','wacchvc','wacchhi','wacchls','wacchge','wacchlt','wacchgt','wacchle',
+ 'waccweq','waccwne','waccwcs','waccwhs','waccwcc','waccwlo','waccwmi','waccwpl','waccwvs','waccwvc','waccwhi','waccwls','waccwge','waccwlt','waccwgt','waccwle',
+ 'waddbeq','waddbne','waddbcs','waddbhs','waddbcc','waddblo','waddbmi','waddbpl','waddbvs','waddbvc','waddbhi','waddbls','waddbge','waddblt','waddbgt','waddble',
+ 'waddheq','waddhne','waddhcs','waddhhs','waddhcc','waddhlo','waddhmi','waddhpl','waddhvs','waddhvc','waddhhi','waddhls','waddhge','waddhlt','waddhgt','waddhle',
+ 'waddweq','waddwne','waddwcs','waddwhs','waddwcc','waddwlo','waddwmi','waddwpl','waddwvs','waddwvc','waddwhi','waddwls','waddwge','waddwlt','waddwgt','waddwle',
+ 'waddbceq','waddbcne','waddbccs','waddbchs','waddbccc','waddbclo','waddbcmi','waddbcpl','waddbcvs','waddbcvc','waddbchi','waddbcls','waddbcge','waddbclt','waddbcgt','waddbcle',
+ 'waddhceq','waddhcne','waddhccs','waddhchs','waddhccc','waddhclo','waddhcmi','waddhcpl','waddhcvs','waddhcvc','waddhchi','waddhcls','waddhcge','waddhclt','waddhcgt','waddhcle',
+ 'waddwceq','waddwcne','waddwccs','waddwchs','waddwccc','waddwclo','waddwcmi','waddwcpl','waddwcvs','waddwcvc','waddwchi','waddwcls','waddwcge','waddwclt','waddwcgt','waddwcle',
+ 'waddbsseq','waddbssne','waddbsscs','waddbsshs','waddbsscc','waddbsslo','waddbssmi','waddbsspl','waddbssvs','waddbssvc','waddbsshi','waddbssls','waddbssge','waddbsslt','waddbssgt','waddbssle',
+ 'waddhsseq','waddhssne','waddhsscs','waddhsshs','waddhsscc','waddhsslo','waddhssmi','waddhsspl','waddhssvs','waddhssvc','waddhsshi','waddhssls','waddhssge','waddhsslt','waddhssgt','waddhssle',
+ 'waddwsseq','waddwssne','waddwsscs','waddwsshs','waddwsscc','waddwsslo','waddwssmi','waddwsspl','waddwssvs','waddwssvc','waddwsshi','waddwssls','waddwssge','waddwsslt','waddwssgt','waddwssle',
+ 'waddbuseq','waddbusne','waddbuscs','waddbushs','waddbuscc','waddbuslo','waddbusmi','waddbuspl','waddbusvs','waddbusvc','waddbushi','waddbusls','waddbusge','waddbuslt','waddbusgt','waddbusle',
+ 'waddhuseq','waddhusne','waddhuscs','waddhushs','waddhuscc','waddhuslo','waddhusmi','waddhuspl','waddhusvs','waddhusvc','waddhushi','waddhusls','waddhusge','waddhuslt','waddhusgt','waddhusle',
+ 'waddwuseq','waddwusne','waddwuscs','waddwushs','waddwuscc','waddwuslo','waddwusmi','waddwuspl','waddwusvs','waddwusvc','waddwushi','waddwusls','waddwusge','waddwuslt','waddwusgt','waddwusle',
+ 'waddsubhxeq','waddsubhxne','waddsubhxcs','waddsubhxhs','waddsubhxcc','waddsubhxlo','waddsubhxmi','waddsubhxpl','waddsubhxvs','waddsubhxvc','waddsubhxhi','waddsubhxls','waddsubhxge','waddsubhxlt','waddsubhxgt','waddsubhxle',
+ 'walignieq','walignine','walignics','walignihs','walignicc','walignilo','walignimi','walignipl','walignivs','walignivc','walignihi','walignils','walignige','walignilt','walignigt','walignile',
+ 'walignr0eq','walignr0ne','walignr0cs','walignr0hs','walignr0cc','walignr0lo','walignr0mi','walignr0pl','walignr0vs','walignr0vc','walignr0hi','walignr0ls','walignr0ge','walignr0lt','walignr0gt','walignr0le',
+ 'walignr1eq','walignr1ne','walignr1cs','walignr1hs','walignr1cc','walignr1lo','walignr1mi','walignr1pl','walignr1vs','walignr1vc','walignr1hi','walignr1ls','walignr1ge','walignr1lt','walignr1gt','walignr1le',
+ 'walignr2eq','walignr2ne','walignr2cs','walignr2hs','walignr2cc','walignr2lo','walignr2mi','walignr2pl','walignr2vs','walignr2vc','walignr2hi','walignr2ls','walignr2ge','walignr2lt','walignr2gt','walignr2le',
+ 'walignr3eq','walignr3ne','walignr3cs','walignr3hs','walignr3cc','walignr3lo','walignr3mi','walignr3pl','walignr3vs','walignr3vc','walignr3hi','walignr3ls','walignr3ge','walignr3lt','walignr3gt','walignr3le',
+ 'wandeq','wandne','wandcs','wandhs','wandcc','wandlo','wandmi','wandpl','wandvs','wandvc','wandhi','wandls','wandge','wandlt','wandgt','wandle',
+ 'wandneq','wandnne','wandncs','wandnhs','wandncc','wandnlo','wandnmi','wandnpl','wandnvs','wandnvc','wandnhi','wandnls','wandnge','wandnlt','wandngt','wandnle',
+ 'wavg2beq','wavg2bne','wavg2bcs','wavg2bhs','wavg2bcc','wavg2blo','wavg2bmi','wavg2bpl','wavg2bvs','wavg2bvc','wavg2bhi','wavg2bls','wavg2bge','wavg2blt','wavg2bgt','wavg2ble',
+ 'wavg2heq','wavg2hne','wavg2hcs','wavg2hhs','wavg2hcc','wavg2hlo','wavg2hmi','wavg2hpl','wavg2hvs','wavg2hvc','wavg2hhi','wavg2hls','wavg2hge','wavg2hlt','wavg2hgt','wavg2hle',
+ 'wavg2breq','wavg2brne','wavg2brcs','wavg2brhs','wavg2brcc','wavg2brlo','wavg2brmi','wavg2brpl','wavg2brvs','wavg2brvc','wavg2brhi','wavg2brls','wavg2brge','wavg2brlt','wavg2brgt','wavg2brle',
+ 'wavg2hreq','wavg2hrne','wavg2hrcs','wavg2hrhs','wavg2hrcc','wavg2hrlo','wavg2hrmi','wavg2hrpl','wavg2hrvs','wavg2hrvc','wavg2hrhi','wavg2hrls','wavg2hrge','wavg2hrlt','wavg2hrgt','wavg2hrle',
+ 'wavg4eq','wavg4ne','wavg4cs','wavg4hs','wavg4cc','wavg4lo','wavg4mi','wavg4pl','wavg4vs','wavg4vc','wavg4hi','wavg4ls','wavg4ge','wavg4lt','wavg4gt','wavg4le',
+ 'wavg4req','wavg4rne','wavg4rcs','wavg4rhs','wavg4rcc','wavg4rlo','wavg4rmi','wavg4rpl','wavg4rvs','wavg4rvc','wavg4rhi','wavg4rls','wavg4rge','wavg4rlt','wavg4rgt','wavg4rle',
+ 'wcmpeqbeq','wcmpeqbne','wcmpeqbcs','wcmpeqbhs','wcmpeqbcc','wcmpeqblo','wcmpeqbmi','wcmpeqbpl','wcmpeqbvs','wcmpeqbvc','wcmpeqbhi','wcmpeqbls','wcmpeqbge','wcmpeqblt','wcmpeqbgt','wcmpeqble',
+ 'wcmpeqheq','wcmpeqhne','wcmpeqhcs','wcmpeqhhs','wcmpeqhcc','wcmpeqhlo','wcmpeqhmi','wcmpeqhpl','wcmpeqhvs','wcmpeqhvc','wcmpeqhhi','wcmpeqhls','wcmpeqhge','wcmpeqhlt','wcmpeqhgt','wcmpeqhle',
+ 'wcmpeqweq','wcmpeqwne','wcmpeqwcs','wcmpeqwhs','wcmpeqwcc','wcmpeqwlo','wcmpeqwmi','wcmpeqwpl','wcmpeqwvs','wcmpeqwvc','wcmpeqwhi','wcmpeqwls','wcmpeqwge','wcmpeqwlt','wcmpeqwgt','wcmpeqwle',
+ 'wcmpgtsbeq','wcmpgtsbne','wcmpgtsbcs','wcmpgtsbhs','wcmpgtsbcc','wcmpgtsblo','wcmpgtsbmi','wcmpgtsbpl','wcmpgtsbvs','wcmpgtsbvc','wcmpgtsbhi','wcmpgtsbls','wcmpgtsbge','wcmpgtsblt','wcmpgtsbgt','wcmpgtsble',
+ 'wcmpgtsheq','wcmpgtshne','wcmpgtshcs','wcmpgtshhs','wcmpgtshcc','wcmpgtshlo','wcmpgtshmi','wcmpgtshpl','wcmpgtshvs','wcmpgtshvc','wcmpgtshhi','wcmpgtshls','wcmpgtshge','wcmpgtshlt','wcmpgtshgt','wcmpgtshle',
+ 'wcmpgtsweq','wcmpgtswne','wcmpgtswcs','wcmpgtswhs','wcmpgtswcc','wcmpgtswlo','wcmpgtswmi','wcmpgtswpl','wcmpgtswvs','wcmpgtswvc','wcmpgtswhi','wcmpgtswls','wcmpgtswge','wcmpgtswlt','wcmpgtswgt','wcmpgtswle',
+ 'wcmpgtubeq','wcmpgtubne','wcmpgtubcs','wcmpgtubhs','wcmpgtubcc','wcmpgtublo','wcmpgtubmi','wcmpgtubpl','wcmpgtubvs','wcmpgtubvc','wcmpgtubhi','wcmpgtubls','wcmpgtubge','wcmpgtublt','wcmpgtubgt','wcmpgtuble',
+ 'wcmpgtuheq','wcmpgtuhne','wcmpgtuhcs','wcmpgtuhhs','wcmpgtuhcc','wcmpgtuhlo','wcmpgtuhmi','wcmpgtuhpl','wcmpgtuhvs','wcmpgtuhvc','wcmpgtuhhi','wcmpgtuhls','wcmpgtuhge','wcmpgtuhlt','wcmpgtuhgt','wcmpgtuhle',
+ 'wcmpgtuweq','wcmpgtuwne','wcmpgtuwcs','wcmpgtuwhs','wcmpgtuwcc','wcmpgtuwlo','wcmpgtuwmi','wcmpgtuwpl','wcmpgtuwvs','wcmpgtuwvc','wcmpgtuwhi','wcmpgtuwls','wcmpgtuwge','wcmpgtuwlt','wcmpgtuwgt','wcmpgtuwle',
+ 'wldrbeq','wldrbne','wldrbcs','wldrbhs','wldrbcc','wldrblo','wldrbmi','wldrbpl','wldrbvs','wldrbvc','wldrbhi','wldrbls','wldrbge','wldrblt','wldrbgt','wldrble',
+ 'wldrheq','wldrhne','wldrhcs','wldrhhs','wldrhcc','wldrhlo','wldrhmi','wldrhpl','wldrhvs','wldrhvc','wldrhhi','wldrhls','wldrhge','wldrhlt','wldrhgt','wldrhle',
+ 'wldrweq','wldrwne','wldrwcs','wldrwhs','wldrwcc','wldrwlo','wldrwmi','wldrwpl','wldrwvs','wldrwvc','wldrwhi','wldrwls','wldrwge','wldrwlt','wldrwgt','wldrwle',
+ 'wldrdeq','wldrdne','wldrdcs','wldrdhs','wldrdcc','wldrdlo','wldrdmi','wldrdpl','wldrdvs','wldrdvc','wldrdhi','wldrdls','wldrdge','wldrdlt','wldrdgt','wldrdle',
+ 'wmacseq','wmacsne','wmacscs','wmacshs','wmacscc','wmacslo','wmacsmi','wmacspl','wmacsvs','wmacsvc','wmacshi','wmacsls','wmacsge','wmacslt','wmacsgt','wmacsle',
+ 'wmacueq','wmacune','wmacucs','wmacuhs','wmacucc','wmaculo','wmacumi','wmacupl','wmacuvs','wmacuvc','wmacuhi','wmaculs','wmacuge','wmacult','wmacugt','wmacule',
+ 'wmacszeq','wmacszne','wmacszcs','wmacszhs','wmacszcc','wmacszlo','wmacszmi','wmacszpl','wmacszvs','wmacszvc','wmacszhi','wmacszls','wmacszge','wmacszlt','wmacszgt','wmacszle',
+ 'wmacuzeq','wmacuzne','wmacuzcs','wmacuzhs','wmacuzcc','wmacuzlo','wmacuzmi','wmacuzpl','wmacuzvs','wmacuzvc','wmacuzhi','wmacuzls','wmacuzge','wmacuzlt','wmacuzgt','wmacuzle',
+ 'wmaddseq','wmaddsne','wmaddscs','wmaddshs','wmaddscc','wmaddslo','wmaddsmi','wmaddspl','wmaddsvs','wmaddsvc','wmaddshi','wmaddsls','wmaddsge','wmaddslt','wmaddsgt','wmaddsle',
+ 'wmaddueq','wmaddune','wmadducs','wmadduhs','wmadducc','wmaddulo','wmaddumi','wmaddupl','wmadduvs','wmadduvc','wmadduhi','wmadduls','wmadduge','wmaddult','wmaddugt','wmaddule',
+ 'wmaddsxeq','wmaddsxne','wmaddsxcs','wmaddsxhs','wmaddsxcc','wmaddsxlo','wmaddsxmi','wmaddsxpl','wmaddsxvs','wmaddsxvc','wmaddsxhi','wmaddsxls','wmaddsxge','wmaddsxlt','wmaddsxgt','wmaddsxle',
+ 'wmadduxeq','wmadduxne','wmadduxcs','wmadduxhs','wmadduxcc','wmadduxlo','wmadduxmi','wmadduxpl','wmadduxvs','wmadduxvc','wmadduxhi','wmadduxls','wmadduxge','wmadduxlt','wmadduxgt','wmadduxle',
+ 'wmaddsneq','wmaddsnne','wmaddsncs','wmaddsnhs','wmaddsncc','wmaddsnlo','wmaddsnmi','wmaddsnpl','wmaddsnvs','wmaddsnvc','wmaddsnhi','wmaddsnls','wmaddsnge','wmaddsnlt','wmaddsngt','wmaddsnle',
+ 'wmadduneq','wmaddunne','wmadduncs','wmaddunhs','wmadduncc','wmaddunlo','wmaddunmi','wmaddunpl','wmaddunvs','wmaddunvc','wmaddunhi','wmaddunls','wmaddunge','wmaddunlt','wmaddungt','wmaddunle',
+ 'wmaxsbeq','wmaxsbne','wmaxsbcs','wmaxsbhs','wmaxsbcc','wmaxsblo','wmaxsbmi','wmaxsbpl','wmaxsbvs','wmaxsbvc','wmaxsbhi','wmaxsbls','wmaxsbge','wmaxsblt','wmaxsbgt','wmaxsble',
+ 'wmaxsheq','wmaxshne','wmaxshcs','wmaxshhs','wmaxshcc','wmaxshlo','wmaxshmi','wmaxshpl','wmaxshvs','wmaxshvc','wmaxshhi','wmaxshls','wmaxshge','wmaxshlt','wmaxshgt','wmaxshle',
+ 'wmaxsweq','wmaxswne','wmaxswcs','wmaxswhs','wmaxswcc','wmaxswlo','wmaxswmi','wmaxswpl','wmaxswvs','wmaxswvc','wmaxswhi','wmaxswls','wmaxswge','wmaxswlt','wmaxswgt','wmaxswle',
+ 'wmaxubeq','wmaxubne','wmaxubcs','wmaxubhs','wmaxubcc','wmaxublo','wmaxubmi','wmaxubpl','wmaxubvs','wmaxubvc','wmaxubhi','wmaxubls','wmaxubge','wmaxublt','wmaxubgt','wmaxuble',
+ 'wmaxuheq','wmaxuhne','wmaxuhcs','wmaxuhhs','wmaxuhcc','wmaxuhlo','wmaxuhmi','wmaxuhpl','wmaxuhvs','wmaxuhvc','wmaxuhhi','wmaxuhls','wmaxuhge','wmaxuhlt','wmaxuhgt','wmaxuhle',
+ 'wmaxuweq','wmaxuwne','wmaxuwcs','wmaxuwhs','wmaxuwcc','wmaxuwlo','wmaxuwmi','wmaxuwpl','wmaxuwvs','wmaxuwvc','wmaxuwhi','wmaxuwls','wmaxuwge','wmaxuwlt','wmaxuwgt','wmaxuwle',
+ 'wmergeeq','wmergene','wmergecs','wmergehs','wmergecc','wmergelo','wmergemi','wmergepl','wmergevs','wmergevc','wmergehi','wmergels','wmergege','wmergelt','wmergegt','wmergele',
+ 'wmiabbeq','wmiabbne','wmiabbcs','wmiabbhs','wmiabbcc','wmiabblo','wmiabbmi','wmiabbpl','wmiabbvs','wmiabbvc','wmiabbhi','wmiabbls','wmiabbge','wmiabblt','wmiabbgt','wmiabble',
+ 'wmiabteq','wmiabtne','wmiabtcs','wmiabths','wmiabtcc','wmiabtlo','wmiabtmi','wmiabtpl','wmiabtvs','wmiabtvc','wmiabthi','wmiabtls','wmiabtge','wmiabtlt','wmiabtgt','wmiabtle',
+ 'wmiatbeq','wmiatbne','wmiatbcs','wmiatbhs','wmiatbcc','wmiatblo','wmiatbmi','wmiatbpl','wmiatbvs','wmiatbvc','wmiatbhi','wmiatbls','wmiatbge','wmiatblt','wmiatbgt','wmiatble',
+ 'wmiatteq','wmiattne','wmiattcs','wmiatths','wmiattcc','wmiattlo','wmiattmi','wmiattpl','wmiattvs','wmiattvc','wmiatthi','wmiattls','wmiattge','wmiattlt','wmiattgt','wmiattle',
+ 'wmiabbneq','wmiabbnne','wmiabbncs','wmiabbnhs','wmiabbncc','wmiabbnlo','wmiabbnmi','wmiabbnpl','wmiabbnvs','wmiabbnvc','wmiabbnhi','wmiabbnls','wmiabbnge','wmiabbnlt','wmiabbngt','wmiabbnle',
+ 'wmiabtneq','wmiabtnne','wmiabtncs','wmiabtnhs','wmiabtncc','wmiabtnlo','wmiabtnmi','wmiabtnpl','wmiabtnvs','wmiabtnvc','wmiabtnhi','wmiabtnls','wmiabtnge','wmiabtnlt','wmiabtngt','wmiabtnle',
+ 'wmiatbneq','wmiatbnne','wmiatbncs','wmiatbnhs','wmiatbncc','wmiatbnlo','wmiatbnmi','wmiatbnpl','wmiatbnvs','wmiatbnvc','wmiatbnhi','wmiatbnls','wmiatbnge','wmiatbnlt','wmiatbngt','wmiatbnle',
+ 'wmiattneq','wmiattnne','wmiattncs','wmiattnhs','wmiattncc','wmiattnlo','wmiattnmi','wmiattnpl','wmiattnvs','wmiattnvc','wmiattnhi','wmiattnls','wmiattnge','wmiattnlt','wmiattngt','wmiattnle',
+ 'wmiawbbeq','wmiawbbne','wmiawbbcs','wmiawbbhs','wmiawbbcc','wmiawbblo','wmiawbbmi','wmiawbbpl','wmiawbbvs','wmiawbbvc','wmiawbbhi','wmiawbbls','wmiawbbge','wmiawbblt','wmiawbbgt','wmiawbble',
+ 'wmiawbteq','wmiawbtne','wmiawbtcs','wmiawbths','wmiawbtcc','wmiawbtlo','wmiawbtmi','wmiawbtpl','wmiawbtvs','wmiawbtvc','wmiawbthi','wmiawbtls','wmiawbtge','wmiawbtlt','wmiawbtgt','wmiawbtle',
+ 'wmiawtbeq','wmiawtbne','wmiawtbcs','wmiawtbhs','wmiawtbcc','wmiawtblo','wmiawtbmi','wmiawtbpl','wmiawtbvs','wmiawtbvc','wmiawtbhi','wmiawtbls','wmiawtbge','wmiawtblt','wmiawtbgt','wmiawtble',
+ 'wmiawtteq','wmiawttne','wmiawttcs','wmiawtths','wmiawttcc','wmiawttlo','wmiawttmi','wmiawttpl','wmiawttvs','wmiawttvc','wmiawtthi','wmiawttls','wmiawttge','wmiawttlt','wmiawttgt','wmiawttle',
+ 'wmiawbbneq','wmiawbbnne','wmiawbbncs','wmiawbbnhs','wmiawbbncc','wmiawbbnlo','wmiawbbnmi','wmiawbbnpl','wmiawbbnvs','wmiawbbnvc','wmiawbbnhi','wmiawbbnls','wmiawbbnge','wmiawbbnlt','wmiawbbngt','wmiawbbnle',
+ 'wmiawbtneq','wmiawbtnne','wmiawbtncs','wmiawbtnhs','wmiawbtncc','wmiawbtnlo','wmiawbtnmi','wmiawbtnpl','wmiawbtnvs','wmiawbtnvc','wmiawbtnhi','wmiawbtnls','wmiawbtnge','wmiawbtnlt','wmiawbtngt','wmiawbtnle',
+ 'wmiawtbneq','wmiawtbnne','wmiawtbncs','wmiawtbnhs','wmiawtbncc','wmiawtbnlo','wmiawtbnmi','wmiawtbnpl','wmiawtbnvs','wmiawtbnvc','wmiawtbnhi','wmiawtbnls','wmiawtbnge','wmiawtbnlt','wmiawtbngt','wmiawtbnle',
+ 'wmiawttneq','wmiawttnne','wmiawttncs','wmiawttnhs','wmiawttncc','wmiawttnlo','wmiawttnmi','wmiawttnpl','wmiawttnvs','wmiawttnvc','wmiawttnhi','wmiawttnls','wmiawttnge','wmiawttnlt','wmiawttngt','wmiawttnle',
+ 'wminsbeq','wminsbne','wminsbcs','wminsbhs','wminsbcc','wminsblo','wminsbmi','wminsbpl','wminsbvs','wminsbvc','wminsbhi','wminsbls','wminsbge','wminsblt','wminsbgt','wminsble',
+ 'wminsheq','wminshne','wminshcs','wminshhs','wminshcc','wminshlo','wminshmi','wminshpl','wminshvs','wminshvc','wminshhi','wminshls','wminshge','wminshlt','wminshgt','wminshle',
+ 'wminsweq','wminswne','wminswcs','wminswhs','wminswcc','wminswlo','wminswmi','wminswpl','wminswvs','wminswvc','wminswhi','wminswls','wminswge','wminswlt','wminswgt','wminswle',
+ 'wminubeq','wminubne','wminubcs','wminubhs','wminubcc','wminublo','wminubmi','wminubpl','wminubvs','wminubvc','wminubhi','wminubls','wminubge','wminublt','wminubgt','wminuble',
+ 'wminuheq','wminuhne','wminuhcs','wminuhhs','wminuhcc','wminuhlo','wminuhmi','wminuhpl','wminuhvs','wminuhvc','wminuhhi','wminuhls','wminuhge','wminuhlt','wminuhgt','wminuhle',
+ 'wminuweq','wminuwne','wminuwcs','wminuwhs','wminuwcc','wminuwlo','wminuwmi','wminuwpl','wminuwvs','wminuwvc','wminuwhi','wminuwls','wminuwge','wminuwlt','wminuwgt','wminuwle',
+ 'wmoveq','wmovne','wmovcs','wmovhs','wmovcc','wmovlo','wmovmi','wmovpl','wmovvs','wmovvc','wmovhi','wmovls','wmovge','wmovlt','wmovgt','wmovle',
+ 'wmulsmeq','wmulsmne','wmulsmcs','wmulsmhs','wmulsmcc','wmulsmlo','wmulsmmi','wmulsmpl','wmulsmvs','wmulsmvc','wmulsmhi','wmulsmls','wmulsmge','wmulsmlt','wmulsmgt','wmulsmle',
+ 'wmulsleq','wmulslne','wmulslcs','wmulslhs','wmulslcc','wmulsllo','wmulslmi','wmulslpl','wmulslvs','wmulslvc','wmulslhi','wmulslls','wmulslge','wmulsllt','wmulslgt','wmulslle',
+ 'wmulumeq','wmulumne','wmulumcs','wmulumhs','wmulumcc','wmulumlo','wmulummi','wmulumpl','wmulumvs','wmulumvc','wmulumhi','wmulumls','wmulumge','wmulumlt','wmulumgt','wmulumle',
+ 'wmululeq','wmululne','wmululcs','wmululhs','wmululcc','wmulullo','wmululmi','wmululpl','wmululvs','wmululvc','wmululhi','wmululls','wmululge','wmulullt','wmululgt','wmululle',
+ 'wmulsmreq','wmulsmrne','wmulsmrcs','wmulsmrhs','wmulsmrcc','wmulsmrlo','wmulsmrmi','wmulsmrpl','wmulsmrvs','wmulsmrvc','wmulsmrhi','wmulsmrls','wmulsmrge','wmulsmrlt','wmulsmrgt','wmulsmrle',
+ 'wmulslreq','wmulslrne','wmulslrcs','wmulslrhs','wmulslrcc','wmulslrlo','wmulslrmi','wmulslrpl','wmulslrvs','wmulslrvc','wmulslrhi','wmulslrls','wmulslrge','wmulslrlt','wmulslrgt','wmulslrle',
+ 'wmulumreq','wmulumrne','wmulumrcs','wmulumrhs','wmulumrcc','wmulumrlo','wmulumrmi','wmulumrpl','wmulumrvs','wmulumrvc','wmulumrhi','wmulumrls','wmulumrge','wmulumrlt','wmulumrgt','wmulumrle',
+ 'wmululreq','wmululrne','wmululrcs','wmululrhs','wmululrcc','wmululrlo','wmululrmi','wmululrpl','wmululrvs','wmululrvc','wmululrhi','wmululrls','wmululrge','wmululrlt','wmululrgt','wmululrle',
+ 'wmulwumeq','wmulwumne','wmulwumcs','wmulwumhs','wmulwumcc','wmulwumlo','wmulwummi','wmulwumpl','wmulwumvs','wmulwumvc','wmulwumhi','wmulwumls','wmulwumge','wmulwumlt','wmulwumgt','wmulwumle',
+ 'wmulwsmeq','wmulwsmne','wmulwsmcs','wmulwsmhs','wmulwsmcc','wmulwsmlo','wmulwsmmi','wmulwsmpl','wmulwsmvs','wmulwsmvc','wmulwsmhi','wmulwsmls','wmulwsmge','wmulwsmlt','wmulwsmgt','wmulwsmle',
+ 'wmulwleq','wmulwlne','wmulwlcs','wmulwlhs','wmulwlcc','wmulwllo','wmulwlmi','wmulwlpl','wmulwlvs','wmulwlvc','wmulwlhi','wmulwlls','wmulwlge','wmulwllt','wmulwlgt','wmulwlle',
+ 'wmulwumreq','wmulwumrne','wmulwumrcs','wmulwumrhs','wmulwumrcc','wmulwumrlo','wmulwumrmi','wmulwumrpl','wmulwumrvs','wmulwumrvc','wmulwumrhi','wmulwumrls','wmulwumrge','wmulwumrlt','wmulwumrgt','wmulwumrle',
+ 'wmulwsmreq','wmulwsmrne','wmulwsmrcs','wmulwsmrhs','wmulwsmrcc','wmulwsmrlo','wmulwsmrmi','wmulwsmrpl','wmulwsmrvs','wmulwsmrvc','wmulwsmrhi','wmulwsmrls','wmulwsmrge','wmulwsmrlt','wmulwsmrgt','wmulwsmrle',
+ 'woreq','worne','worcs','worhs','worcc','worlo','wormi','worpl','worvs','worvc','worhi','worls','worge','worlt','worgt','worle',
+ 'wpackhsseq','wpackhssne','wpackhsscs','wpackhsshs','wpackhsscc','wpackhsslo','wpackhssmi','wpackhsspl','wpackhssvs','wpackhssvc','wpackhsshi','wpackhssls','wpackhssge','wpackhsslt','wpackhssgt','wpackhssle',
+ 'wpackwsseq','wpackwssne','wpackwsscs','wpackwsshs','wpackwsscc','wpackwsslo','wpackwssmi','wpackwsspl','wpackwssvs','wpackwssvc','wpackwsshi','wpackwssls','wpackwssge','wpackwsslt','wpackwssgt','wpackwssle',
+ 'wpackdsseq','wpackdssne','wpackdsscs','wpackdsshs','wpackdsscc','wpackdsslo','wpackdssmi','wpackdsspl','wpackdssvs','wpackdssvc','wpackdsshi','wpackdssls','wpackdssge','wpackdsslt','wpackdssgt','wpackdssle',
+ 'wpackhuseq','wpackhusne','wpackhuscs','wpackhushs','wpackhuscc','wpackhuslo','wpackhusmi','wpackhuspl','wpackhusvs','wpackhusvc','wpackhushi','wpackhusls','wpackhusge','wpackhuslt','wpackhusgt','wpackhusle',
+ 'wpackwuseq','wpackwusne','wpackwuscs','wpackwushs','wpackwuscc','wpackwuslo','wpackwusmi','wpackwuspl','wpackwusvs','wpackwusvc','wpackwushi','wpackwusls','wpackwusge','wpackwuslt','wpackwusgt','wpackwusle',
+ 'wpackduseq','wpackdusne','wpackduscs','wpackdushs','wpackduscc','wpackduslo','wpackdusmi','wpackduspl','wpackdusvs','wpackdusvc','wpackdushi','wpackdusls','wpackdusge','wpackduslt','wpackdusgt','wpackdusle',
+ 'wqmiabbeq','wqmiabbne','wqmiabbcs','wqmiabbhs','wqmiabbcc','wqmiabblo','wqmiabbmi','wqmiabbpl','wqmiabbvs','wqmiabbvc','wqmiabbhi','wqmiabbls','wqmiabbge','wqmiabblt','wqmiabbgt','wqmiabble',
+ 'wqmiabteq','wqmiabtne','wqmiabtcs','wqmiabths','wqmiabtcc','wqmiabtlo','wqmiabtmi','wqmiabtpl','wqmiabtvs','wqmiabtvc','wqmiabthi','wqmiabtls','wqmiabtge','wqmiabtlt','wqmiabtgt','wqmiabtle',
+ 'wqmiatbeq','wqmiatbne','wqmiatbcs','wqmiatbhs','wqmiatbcc','wqmiatblo','wqmiatbmi','wqmiatbpl','wqmiatbvs','wqmiatbvc','wqmiatbhi','wqmiatbls','wqmiatbge','wqmiatblt','wqmiatbgt','wqmiatble',
+ 'wqmiatteq','wqmiattne','wqmiattcs','wqmiatths','wqmiattcc','wqmiattlo','wqmiattmi','wqmiattpl','wqmiattvs','wqmiattvc','wqmiatthi','wqmiattls','wqmiattge','wqmiattlt','wqmiattgt','wqmiattle',
+ 'wqmiabbneq','wqmiabbnne','wqmiabbncs','wqmiabbnhs','wqmiabbncc','wqmiabbnlo','wqmiabbnmi','wqmiabbnpl','wqmiabbnvs','wqmiabbnvc','wqmiabbnhi','wqmiabbnls','wqmiabbnge','wqmiabbnlt','wqmiabbngt','wqmiabbnle',
+ 'wqmiabtneq','wqmiabtnne','wqmiabtncs','wqmiabtnhs','wqmiabtncc','wqmiabtnlo','wqmiabtnmi','wqmiabtnpl','wqmiabtnvs','wqmiabtnvc','wqmiabtnhi','wqmiabtnls','wqmiabtnge','wqmiabtnlt','wqmiabtngt','wqmiabtnle',
+ 'wqmiatbneq','wqmiatbnne','wqmiatbncs','wqmiatbnhs','wqmiatbncc','wqmiatbnlo','wqmiatbnmi','wqmiatbnpl','wqmiatbnvs','wqmiatbnvc','wqmiatbnhi','wqmiatbnls','wqmiatbnge','wqmiatbnlt','wqmiatbngt','wqmiatbnle',
+ 'wqmiattneq','wqmiattnne','wqmiattncs','wqmiattnhs','wqmiattncc','wqmiattnlo','wqmiattnmi','wqmiattnpl','wqmiattnvs','wqmiattnvc','wqmiattnhi','wqmiattnls','wqmiattnge','wqmiattnlt','wqmiattngt','wqmiattnle',
+ 'wqmulmeq','wqmulmne','wqmulmcs','wqmulmhs','wqmulmcc','wqmulmlo','wqmulmmi','wqmulmpl','wqmulmvs','wqmulmvc','wqmulmhi','wqmulmls','wqmulmge','wqmulmlt','wqmulmgt','wqmulmle',
+ 'wqmulmreq','wqmulmrne','wqmulmrcs','wqmulmrhs','wqmulmrcc','wqmulmrlo','wqmulmrmi','wqmulmrpl','wqmulmrvs','wqmulmrvc','wqmulmrhi','wqmulmrls','wqmulmrge','wqmulmrlt','wqmulmrgt','wqmulmrle',
+ 'wqmulwmeq','wqmulwmne','wqmulwmcs','wqmulwmhs','wqmulwmcc','wqmulwmlo','wqmulwmmi','wqmulwmpl','wqmulwmvs','wqmulwmvc','wqmulwmhi','wqmulwmls','wqmulwmge','wqmulwmlt','wqmulwmgt','wqmulwmle',
+ 'wqmulwmreq','wqmulwmrne','wqmulwmrcs','wqmulwmrhs','wqmulwmrcc','wqmulwmrlo','wqmulwmrmi','wqmulwmrpl','wqmulwmrvs','wqmulwmrvc','wqmulwmrhi','wqmulwmrls','wqmulwmrge','wqmulwmrlt','wqmulwmrgt','wqmulwmrle',
+ 'wrorheq','wrorhne','wrorhcs','wrorhhs','wrorhcc','wrorhlo','wrorhmi','wrorhpl','wrorhvs','wrorhvc','wrorhhi','wrorhls','wrorhge','wrorhlt','wrorhgt','wrorhle',
+ 'wrorweq','wrorwne','wrorwcs','wrorwhs','wrorwcc','wrorwlo','wrorwmi','wrorwpl','wrorwvs','wrorwvc','wrorwhi','wrorwls','wrorwge','wrorwlt','wrorwgt','wrorwle',
+ 'wrordeq','wrordne','wrordcs','wrordhs','wrordcc','wrordlo','wrordmi','wrordpl','wrordvs','wrordvc','wrordhi','wrordls','wrordge','wrordlt','wrordgt','wrordle',
+ 'wrorhgeq','wrorhgne','wrorhgcs','wrorhghs','wrorhgcc','wrorhglo','wrorhgmi','wrorhgpl','wrorhgvs','wrorhgvc','wrorhghi','wrorhgls','wrorhgge','wrorhglt','wrorhggt','wrorhgle',
+ 'wrorwgeq','wrorwgne','wrorwgcs','wrorwghs','wrorwgcc','wrorwglo','wrorwgmi','wrorwgpl','wrorwgvs','wrorwgvc','wrorwghi','wrorwgls','wrorwgge','wrorwglt','wrorwggt','wrorwgle',
+ 'wrordgeq','wrordgne','wrordgcs','wrordghs','wrordgcc','wrordglo','wrordgmi','wrordgpl','wrordgvs','wrordgvc','wrordghi','wrordgls','wrordgge','wrordglt','wrordggt','wrordgle',
+ 'wsadbeq','wsadbne','wsadbcs','wsadbhs','wsadbcc','wsadblo','wsadbmi','wsadbpl','wsadbvs','wsadbvc','wsadbhi','wsadbls','wsadbge','wsadblt','wsadbgt','wsadble',
+ 'wsadheq','wsadhne','wsadhcs','wsadhhs','wsadhcc','wsadhlo','wsadhmi','wsadhpl','wsadhvs','wsadhvc','wsadhhi','wsadhls','wsadhge','wsadhlt','wsadhgt','wsadhle',
+ 'wsadbzeq','wsadbzne','wsadbzcs','wsadbzhs','wsadbzcc','wsadbzlo','wsadbzmi','wsadbzpl','wsadbzvs','wsadbzvc','wsadbzhi','wsadbzls','wsadbzge','wsadbzlt','wsadbzgt','wsadbzle',
+ 'wsadhzeq','wsadhzne','wsadhzcs','wsadhzhs','wsadhzcc','wsadhzlo','wsadhzmi','wsadhzpl','wsadhzvs','wsadhzvc','wsadhzhi','wsadhzls','wsadhzge','wsadhzlt','wsadhzgt','wsadhzle',
+ 'wshufheq','wshufhne','wshufhcs','wshufhhs','wshufhcc','wshufhlo','wshufhmi','wshufhpl','wshufhvs','wshufhvc','wshufhhi','wshufhls','wshufhge','wshufhlt','wshufhgt','wshufhle',
+ 'wsllheq','wsllhne','wsllhcs','wsllhhs','wsllhcc','wsllhlo','wsllhmi','wsllhpl','wsllhvs','wsllhvc','wsllhhi','wsllhls','wsllhge','wsllhlt','wsllhgt','wsllhle',
+ 'wsllweq','wsllwne','wsllwcs','wsllwhs','wsllwcc','wsllwlo','wsllwmi','wsllwpl','wsllwvs','wsllwvc','wsllwhi','wsllwls','wsllwge','wsllwlt','wsllwgt','wsllwle',
+ 'wslldeq','wslldne','wslldcs','wslldhs','wslldcc','wslldlo','wslldmi','wslldpl','wslldvs','wslldvc','wslldhi','wslldls','wslldge','wslldlt','wslldgt','wslldle',
+ 'wsllhgeq','wsllhgne','wsllhgcs','wsllhghs','wsllhgcc','wsllhglo','wsllhgmi','wsllhgpl','wsllhgvs','wsllhgvc','wsllhghi','wsllhgls','wsllhgge','wsllhglt','wsllhggt','wsllhgle',
+ 'wsllwgeq','wsllwgne','wsllwgcs','wsllwghs','wsllwgcc','wsllwglo','wsllwgmi','wsllwgpl','wsllwgvs','wsllwgvc','wsllwghi','wsllwgls','wsllwgge','wsllwglt','wsllwggt','wsllwgle',
+ 'wslldgeq','wslldgne','wslldgcs','wslldghs','wslldgcc','wslldglo','wslldgmi','wslldgpl','wslldgvs','wslldgvc','wslldghi','wslldgls','wslldgge','wslldglt','wslldggt','wslldgle',
+ 'wsraheq','wsrahne','wsrahcs','wsrahhs','wsrahcc','wsrahlo','wsrahmi','wsrahpl','wsrahvs','wsrahvc','wsrahhi','wsrahls','wsrahge','wsrahlt','wsrahgt','wsrahle',
+ 'wsraweq','wsrawne','wsrawcs','wsrawhs','wsrawcc','wsrawlo','wsrawmi','wsrawpl','wsrawvs','wsrawvc','wsrawhi','wsrawls','wsrawge','wsrawlt','wsrawgt','wsrawle',
+ 'wsradeq','wsradne','wsradcs','wsradhs','wsradcc','wsradlo','wsradmi','wsradpl','wsradvs','wsradvc','wsradhi','wsradls','wsradge','wsradlt','wsradgt','wsradle',
+ 'wsrahgeq','wsrahgne','wsrahgcs','wsrahghs','wsrahgcc','wsrahglo','wsrahgmi','wsrahgpl','wsrahgvs','wsrahgvc','wsrahghi','wsrahgls','wsrahgge','wsrahglt','wsrahggt','wsrahgle',
+ 'wsrawgeq','wsrawgne','wsrawgcs','wsrawghs','wsrawgcc','wsrawglo','wsrawgmi','wsrawgpl','wsrawgvs','wsrawgvc','wsrawghi','wsrawgls','wsrawgge','wsrawglt','wsrawggt','wsrawgle',
+ 'wsradgeq','wsradgne','wsradgcs','wsradghs','wsradgcc','wsradglo','wsradgmi','wsradgpl','wsradgvs','wsradgvc','wsradghi','wsradgls','wsradgge','wsradglt','wsradggt','wsradgle',
+ 'wsrlheq','wsrlhne','wsrlhcs','wsrlhhs','wsrlhcc','wsrlhlo','wsrlhmi','wsrlhpl','wsrlhvs','wsrlhvc','wsrlhhi','wsrlhls','wsrlhge','wsrlhlt','wsrlhgt','wsrlhle',
+ 'wsrlweq','wsrlwne','wsrlwcs','wsrlwhs','wsrlwcc','wsrlwlo','wsrlwmi','wsrlwpl','wsrlwvs','wsrlwvc','wsrlwhi','wsrlwls','wsrlwge','wsrlwlt','wsrlwgt','wsrlwle',
+ 'wsrldeq','wsrldne','wsrldcs','wsrldhs','wsrldcc','wsrldlo','wsrldmi','wsrldpl','wsrldvs','wsrldvc','wsrldhi','wsrldls','wsrldge','wsrldlt','wsrldgt','wsrldle',
+ 'wsrlhgeq','wsrlhgne','wsrlhgcs','wsrlhghs','wsrlhgcc','wsrlhglo','wsrlhgmi','wsrlhgpl','wsrlhgvs','wsrlhgvc','wsrlhghi','wsrlhgls','wsrlhgge','wsrlhglt','wsrlhggt','wsrlhgle',
+ 'wsrlwgeq','wsrlwgne','wsrlwgcs','wsrlwghs','wsrlwgcc','wsrlwglo','wsrlwgmi','wsrlwgpl','wsrlwgvs','wsrlwgvc','wsrlwghi','wsrlwgls','wsrlwgge','wsrlwglt','wsrlwggt','wsrlwgle',
+ 'wsrldgeq','wsrldgne','wsrldgcs','wsrldghs','wsrldgcc','wsrldglo','wsrldgmi','wsrldgpl','wsrldgvs','wsrldgvc','wsrldghi','wsrldgls','wsrldgge','wsrldglt','wsrldggt','wsrldgle',
+ 'wstrbeq','wstrbne','wstrbcs','wstrbhs','wstrbcc','wstrblo','wstrbmi','wstrbpl','wstrbvs','wstrbvc','wstrbhi','wstrbls','wstrbge','wstrblt','wstrbgt','wstrble',
+ 'wstrheq','wstrhne','wstrhcs','wstrhhs','wstrhcc','wstrhlo','wstrhmi','wstrhpl','wstrhvs','wstrhvc','wstrhhi','wstrhls','wstrhge','wstrhlt','wstrhgt','wstrhle',
+ 'wstrweq','wstrwne','wstrwcs','wstrwhs','wstrwcc','wstrwlo','wstrwmi','wstrwpl','wstrwvs','wstrwvc','wstrwhi','wstrwls','wstrwge','wstrwlt','wstrwgt','wstrwle',
+ 'wstrdeq','wstrdne','wstrdcs','wstrdhs','wstrdcc','wstrdlo','wstrdmi','wstrdpl','wstrdvs','wstrdvc','wstrdhi','wstrdls','wstrdge','wstrdlt','wstrdgt','wstrdle',
+ 'wsubbeq','wsubbne','wsubbcs','wsubbhs','wsubbcc','wsubblo','wsubbmi','wsubbpl','wsubbvs','wsubbvc','wsubbhi','wsubbls','wsubbge','wsubblt','wsubbgt','wsubble',
+ 'wsubheq','wsubhne','wsubhcs','wsubhhs','wsubhcc','wsubhlo','wsubhmi','wsubhpl','wsubhvs','wsubhvc','wsubhhi','wsubhls','wsubhge','wsubhlt','wsubhgt','wsubhle',
+ 'wsubweq','wsubwne','wsubwcs','wsubwhs','wsubwcc','wsubwlo','wsubwmi','wsubwpl','wsubwvs','wsubwvc','wsubwhi','wsubwls','wsubwge','wsubwlt','wsubwgt','wsubwle',
+ 'wsubbsseq','wsubbssne','wsubbsscs','wsubbsshs','wsubbsscc','wsubbsslo','wsubbssmi','wsubbsspl','wsubbssvs','wsubbssvc','wsubbsshi','wsubbssls','wsubbssge','wsubbsslt','wsubbssgt','wsubbssle',
+ 'wsubhsseq','wsubhssne','wsubhsscs','wsubhsshs','wsubhsscc','wsubhsslo','wsubhssmi','wsubhsspl','wsubhssvs','wsubhssvc','wsubhsshi','wsubhssls','wsubhssge','wsubhsslt','wsubhssgt','wsubhssle',
+ 'wsubwsseq','wsubwssne','wsubwsscs','wsubwsshs','wsubwsscc','wsubwsslo','wsubwssmi','wsubwsspl','wsubwssvs','wsubwssvc','wsubwsshi','wsubwssls','wsubwssge','wsubwsslt','wsubwssgt','wsubwssle',
+ 'wsubbuseq','wsubbusne','wsubbuscs','wsubbushs','wsubbuscc','wsubbuslo','wsubbusmi','wsubbuspl','wsubbusvs','wsubbusvc','wsubbushi','wsubbusls','wsubbusge','wsubbuslt','wsubbusgt','wsubbusle',
+ 'wsubhuseq','wsubhusne','wsubhuscs','wsubhushs','wsubhuscc','wsubhuslo','wsubhusmi','wsubhuspl','wsubhusvs','wsubhusvc','wsubhushi','wsubhusls','wsubhusge','wsubhuslt','wsubhusgt','wsubhusle',
+ 'wsubwuseq','wsubwusne','wsubwuscs','wsubwushs','wsubwuscc','wsubwuslo','wsubwusmi','wsubwuspl','wsubwusvs','wsubwusvc','wsubwushi','wsubwusls','wsubwusge','wsubwuslt','wsubwusgt','wsubwusle',
+ 'wsubaddhxeq','wsubaddhxne','wsubaddhxcs','wsubaddhxhs','wsubaddhxcc','wsubaddhxlo','wsubaddhxmi','wsubaddhxpl','wsubaddhxvs','wsubaddhxvc','wsubaddhxhi','wsubaddhxls','wsubaddhxge','wsubaddhxlt','wsubaddhxgt','wsubaddhxle',
+ 'wunpckehsbeq','wunpckehsbne','wunpckehsbcs','wunpckehsbhs','wunpckehsbcc','wunpckehsblo','wunpckehsbmi','wunpckehsbpl','wunpckehsbvs','wunpckehsbvc','wunpckehsbhi','wunpckehsbls','wunpckehsbge','wunpckehsblt','wunpckehsbgt','wunpckehsble',
+ 'wunpckehsheq','wunpckehshne','wunpckehshcs','wunpckehshhs','wunpckehshcc','wunpckehshlo','wunpckehshmi','wunpckehshpl','wunpckehshvs','wunpckehshvc','wunpckehshhi','wunpckehshls','wunpckehshge','wunpckehshlt','wunpckehshgt','wunpckehshle',
+ 'wunpckehsweq','wunpckehswne','wunpckehswcs','wunpckehswhs','wunpckehswcc','wunpckehswlo','wunpckehswmi','wunpckehswpl','wunpckehswvs','wunpckehswvc','wunpckehswhi','wunpckehswls','wunpckehswge','wunpckehswlt','wunpckehswgt','wunpckehswle',
+ 'wunpckehubeq','wunpckehubne','wunpckehubcs','wunpckehubhs','wunpckehubcc','wunpckehublo','wunpckehubmi','wunpckehubpl','wunpckehubvs','wunpckehubvc','wunpckehubhi','wunpckehubls','wunpckehubge','wunpckehublt','wunpckehubgt','wunpckehuble',
+ 'wunpckehuheq','wunpckehuhne','wunpckehuhcs','wunpckehuhhs','wunpckehuhcc','wunpckehuhlo','wunpckehuhmi','wunpckehuhpl','wunpckehuhvs','wunpckehuhvc','wunpckehuhhi','wunpckehuhls','wunpckehuhge','wunpckehuhlt','wunpckehuhgt','wunpckehuhle',
+ 'wunpckehuweq','wunpckehuwne','wunpckehuwcs','wunpckehuwhs','wunpckehuwcc','wunpckehuwlo','wunpckehuwmi','wunpckehuwpl','wunpckehuwvs','wunpckehuwvc','wunpckehuwhi','wunpckehuwls','wunpckehuwge','wunpckehuwlt','wunpckehuwgt','wunpckehuwle',
+ 'wunpckihbeq','wunpckihbne','wunpckihbcs','wunpckihbhs','wunpckihbcc','wunpckihblo','wunpckihbmi','wunpckihbpl','wunpckihbvs','wunpckihbvc','wunpckihbhi','wunpckihbls','wunpckihbge','wunpckihblt','wunpckihbgt','wunpckihble',
+ 'wunpckihheq','wunpckihhne','wunpckihhcs','wunpckihhhs','wunpckihhcc','wunpckihhlo','wunpckihhmi','wunpckihhpl','wunpckihhvs','wunpckihhvc','wunpckihhhi','wunpckihhls','wunpckihhge','wunpckihhlt','wunpckihhgt','wunpckihhle',
+ 'wunpckihweq','wunpckihwne','wunpckihwcs','wunpckihwhs','wunpckihwcc','wunpckihwlo','wunpckihwmi','wunpckihwpl','wunpckihwvs','wunpckihwvc','wunpckihwhi','wunpckihwls','wunpckihwge','wunpckihwlt','wunpckihwgt','wunpckihwle',
+ 'wunpckelsbeq','wunpckelsbne','wunpckelsbcs','wunpckelsbhs','wunpckelsbcc','wunpckelsblo','wunpckelsbmi','wunpckelsbpl','wunpckelsbvs','wunpckelsbvc','wunpckelsbhi','wunpckelsbls','wunpckelsbge','wunpckelsblt','wunpckelsbgt','wunpckelsble',
+ 'wunpckelsheq','wunpckelshne','wunpckelshcs','wunpckelshhs','wunpckelshcc','wunpckelshlo','wunpckelshmi','wunpckelshpl','wunpckelshvs','wunpckelshvc','wunpckelshhi','wunpckelshls','wunpckelshge','wunpckelshlt','wunpckelshgt','wunpckelshle',
+ 'wunpckelsweq','wunpckelswne','wunpckelswcs','wunpckelswhs','wunpckelswcc','wunpckelswlo','wunpckelswmi','wunpckelswpl','wunpckelswvs','wunpckelswvc','wunpckelswhi','wunpckelswls','wunpckelswge','wunpckelswlt','wunpckelswgt','wunpckelswle',
+ 'wunpckelubeq','wunpckelubne','wunpckelubcs','wunpckelubhs','wunpckelubcc','wunpckelublo','wunpckelubmi','wunpckelubpl','wunpckelubvs','wunpckelubvc','wunpckelubhi','wunpckelubls','wunpckelubge','wunpckelublt','wunpckelubgt','wunpckeluble',
+ 'wunpckeluheq','wunpckeluhne','wunpckeluhcs','wunpckeluhhs','wunpckeluhcc','wunpckeluhlo','wunpckeluhmi','wunpckeluhpl','wunpckeluhvs','wunpckeluhvc','wunpckeluhhi','wunpckeluhls','wunpckeluhge','wunpckeluhlt','wunpckeluhgt','wunpckeluhle',
+ 'wunpckeluweq','wunpckeluwne','wunpckeluwcs','wunpckeluwhs','wunpckeluwcc','wunpckeluwlo','wunpckeluwmi','wunpckeluwpl','wunpckeluwvs','wunpckeluwvc','wunpckeluwhi','wunpckeluwls','wunpckeluwge','wunpckeluwlt','wunpckeluwgt','wunpckeluwle',
+ 'wunpckilbeq','wunpckilbne','wunpckilbcs','wunpckilbhs','wunpckilbcc','wunpckilblo','wunpckilbmi','wunpckilbpl','wunpckilbvs','wunpckilbvc','wunpckilbhi','wunpckilbls','wunpckilbge','wunpckilblt','wunpckilbgt','wunpckilble',
+ 'wunpckilheq','wunpckilhne','wunpckilhcs','wunpckilhhs','wunpckilhcc','wunpckilhlo','wunpckilhmi','wunpckilhpl','wunpckilhvs','wunpckilhvc','wunpckilhhi','wunpckilhls','wunpckilhge','wunpckilhlt','wunpckilhgt','wunpckilhle',
+ 'wunpckilweq','wunpckilwne','wunpckilwcs','wunpckilwhs','wunpckilwcc','wunpckilwlo','wunpckilwmi','wunpckilwpl','wunpckilwvs','wunpckilwvc','wunpckilwhi','wunpckilwls','wunpckilwge','wunpckilwlt','wunpckilwgt','wunpckilwle',
+ 'wxoreq','wxorne','wxorcs','wxorhs','wxorcc','wxorlo','wxormi','wxorpl','wxorvs','wxorvc','wxorhi','wxorls','wxorge','wxorlt','wxorgt','wxorle',
+ 'wzeroeq','wzerone','wzerocs','wzerohs','wzerocc','wzerolo','wzeromi','wzeropl','wzerovs','wzerovc','wzerohi','wzerols','wzeroge','wzerolt','wzerogt','wzerole'
+ ),
+ /* Unconditional VFPv3 & NEON SIMD Memory Access Instructions */
+ 19 => array(
+ /* Unconditional VFPv3 & NEON SIMD Memory Access: Loads */
+ 'vld.8','vldal.8',
+ 'vld.16','vldal.16',
+ 'vld.32','vldal.32',
+ 'vld.64','vldal.64',
+
+ 'vld1.8','vld1al.8',
+ 'vld1.16','vld1al.16',
+ 'vld1.32','vld1al.32',
+
+ 'vld2.8','vld2al.8',
+ 'vld2.16','vld2al.16',
+ 'vld2.32','vld2al.32',
+
+ 'vld3.8','vld3al.8',
+ 'vld3.16','vld3al.16',
+ 'vld3.32','vld3al.32',
+
+ 'vld4.8','vld4al.8',
+ 'vld4.16','vld4al.16',
+ 'vld4.32','vld4al.32',
+
+ 'vldm','vldmal',
+ 'vldm.32','vldmal.32',
+ 'vldm.64','vldmal.64',
+
+ 'vldmia','vldmiaal',
+ 'vldmia.32','vldmiaal.32',
+ 'vldmia.64','vldmiaal.64',
+
+ 'vldmdb','vldmdbal',
+ 'vldmdb.32','vldmdbal.32',
+ 'vldmdb.64','vldmdbal.64',
+
+ 'vldr','vldral',
+ 'vldr.32','vldral.32',
+ 'vldr.64','vldral.64',
+
+ 'vpop','vpopal',
+ 'vpop.32','vpopal.32',
+ 'vpop.64','vpopal.64',
+
+ /* Unconditional VFPv3 & NEON SIMD Memory Access: Stores */
+ 'vst1.8','vst1al.8',
+ 'vst1.16','vst1al.16',
+ 'vst1.32','vst1al.32',
+ 'vst1.64','vst1al.64',
+
+ 'vst2.8','vst2al.8',
+ 'vst2.16','vst2al.16',
+ 'vst2.32','vst2al.32',
+
+ 'vst3.8','vst3al.8',
+ 'vst3.16','vst3al.16',
+ 'vst3.32','vst3al.32',
+
+ 'vst4.8','vst4al.8',
+ 'vst4.16','vst4al.16',
+ 'vst4.32','vst4al.32',
+
+ 'vstm','vstmal',
+ 'vstm.32','vstmal.32',
+ 'vstm.64','vstmal.64',
+
+ 'vstmia','vstmiaal',
+ 'vstmia.32','vstmiaal.32',
+ 'vstmia.64','vstmiaal.64',
+
+ 'vstmdb','vstmdbal',
+ 'vstmdb.32','vstmdbal.32',
+ 'vstmdb.64','vstmdbal.64',
+
+ 'vstr','vstral',
+ 'vstr.32','vstral.32',
+ 'vstr.64','vstral.64',
+
+ 'vpush','vpushal',
+ 'vpush.32','vpushal.32',
+ 'vpush.64','vpushal.64'
+ ),
+ /* Unconditional NEON SIMD Logical Instructions */
+ 20 => array(
+ 'vand','vandal',
+ 'vand.i8','vandal.i8',
+ 'vand.i16','vandal.i16',
+ 'vand.i32','vandal.i32',
+ 'vand.i64','vandal.i64',
+ 'vand.s8','vandal.s8',
+ 'vand.s16','vandal.s16',
+ 'vand.s32','vandal.s32',
+ 'vand.s64','vandal.s64',
+ 'vand.u8','vandal.u8',
+ 'vand.u16','vandal.u16',
+ 'vand.u32','vandal.u32',
+ 'vand.u64','vandal.u64',
+ 'vand.f32','vandal.f32',
+ 'vand.f64','vandal.f64',
+
+ 'vbic','vbical',
+ 'vbic.i8','vbical.i8',
+ 'vbic.i16','vbical.i16',
+ 'vbic.i32','vbical.i32',
+ 'vbic.i64','vbical.i64',
+ 'vbic.s8','vbical.s8',
+ 'vbic.s16','vbical.s16',
+ 'vbic.s32','vbical.s32',
+ 'vbic.s64','vbical.s64',
+ 'vbic.u8','vbical.u8',
+ 'vbic.u16','vbical.u16',
+ 'vbic.u32','vbical.u32',
+ 'vbic.u64','vbical.u64',
+ 'vbic.f32','vbical.f32',
+ 'vbic.f64','vbical.f64',
+
+ 'vbif','vbifal',
+ 'vbif.i8','vbifal.i8',
+ 'vbif.i16','vbifal.i16',
+ 'vbif.i32','vbifal.i32',
+ 'vbif.i64','vbifal.i64',
+ 'vbif.s8','vbifal.s8',
+ 'vbif.s16','vbifal.s16',
+ 'vbif.s32','vbifal.s32',
+ 'vbif.s64','vbifal.s64',
+ 'vbif.u8','vbifal.u8',
+ 'vbif.u16','vbifal.u16',
+ 'vbif.u32','vbifal.u32',
+ 'vbif.u64','vbifal.u64',
+ 'vbif.f32','vbifal.f32',
+ 'vbif.f64','vbifal.f64',
+
+ 'vbit','vbital',
+ 'vbit.i8','vbital.i8',
+ 'vbit.i16','vbital.i16',
+ 'vbit.i32','vbital.i32',
+ 'vbit.i64','vbital.i64',
+ 'vbit.s8','vbital.s8',
+ 'vbit.s16','vbital.s16',
+ 'vbit.s32','vbital.s32',
+ 'vbit.s64','vbital.s64',
+ 'vbit.u8','vbital.u8',
+ 'vbit.u16','vbital.u16',
+ 'vbit.u32','vbital.u32',
+ 'vbit.u64','vbital.u64',
+ 'vbit.f32','vbital.f32',
+ 'vbit.f64','vbital.f64',
+
+ 'vbsl','vbslal',
+ 'vbsl.i8','vbslal.i8',
+ 'vbsl.i16','vbslal.i16',
+ 'vbsl.i32','vbslal.i32',
+ 'vbsl.i64','vbslal.i64',
+ 'vbsl.s8','vbslal.s8',
+ 'vbsl.s16','vbslal.s16',
+ 'vbsl.s32','vbslal.s32',
+ 'vbsl.s64','vbslal.s64',
+ 'vbsl.u8','vbslal.u8',
+ 'vbsl.u16','vbslal.u16',
+ 'vbsl.u32','vbslal.u32',
+ 'vbsl.u64','vbslal.u64',
+ 'vbsl.f32','vbslal.f32',
+ 'vbsl.f64','vbslal.f64',
+
+ 'veor','veoral',
+ 'veor.i8','veoral.i8',
+ 'veor.i16','veoral.i16',
+ 'veor.i32','veoral.i32',
+ 'veor.i64','veoral.i64',
+ 'veor.s8','veoral.s8',
+ 'veor.s16','veoral.s16',
+ 'veor.s32','veoral.s32',
+ 'veor.s64','veoral.s64',
+ 'veor.u8','veoral.u8',
+ 'veor.u16','veoral.u16',
+ 'veor.u32','veoral.u32',
+ 'veor.u64','veoral.u64',
+ 'veor.f32','veoral.f32',
+ 'veor.f64','veoral.f64',
+
+ 'vmov','vmoval',
+ 'vmov.8','vmoval.8',
+ 'vmov.16','vmoval.16',
+ 'vmov.32','vmoval.32',
+ 'vmov.i8','vmoval.i8',
+ 'vmov.i16','vmoval.i16',
+ 'vmov.i32','vmoval.i32',
+ 'vmov.i64','vmoval.i64',
+ 'vmov.f32','vmoval.f32',
+ 'vmov.f64','vmoval.f64',
+
+ 'vmvn','vmvnal',
+ 'vmvn.s8','vmvnal.s8',
+ 'vmvn.s16','vmvnal.s16',
+ 'vmvn.s32','vmvnal.s32',
+ 'vmvn.s64','vmvnal.s64',
+ 'vmvn.u8','vmvnal.u8',
+ 'vmvn.u16','vmvnal.u16',
+ 'vmvn.u32','vmvnal.u32',
+ 'vmvn.u64','vmvnal.u64',
+ 'vmvn.i8','vmvnal.i8',
+ 'vmvn.i16','vmvnal.i16',
+ 'vmvn.i32','vmvnal.i32',
+ 'vmvn.i64','vmvnal.i64',
+ 'vmvn.f32','vmvnal.f32',
+ 'vmvn.f64','vmvnal.f64',
+
+ 'vorn','vornal',
+ 'vorn.s8','vornal.s8',
+ 'vorn.s16','vornal.s16',
+ 'vorn.s32','vornal.s32',
+ 'vorn.s64','vornal.s64',
+ 'vorn.u8','vornal.u8',
+ 'vorn.u16','vornal.u16',
+ 'vorn.u32','vornal.u32',
+ 'vorn.u64','vornal.u64',
+ 'vorn.i8','vornal.i8',
+ 'vorn.i16','vornal.i16',
+ 'vorn.i32','vornal.i32',
+ 'vorn.i64','vornal.i64',
+ 'vorn.f32','vornal.f32',
+ 'vorn.f64','vornal.f64',
+
+ 'vorr','vorral',
+ 'vorr.s8','vorral.s8',
+ 'vorr.s16','vorral.s16',
+ 'vorr.s32','vorral.s32',
+ 'vorr.s64','vorral.s64',
+ 'vorr.u8','vorral.u8',
+ 'vorr.u16','vorral.u16',
+ 'vorr.u32','vorral.u32',
+ 'vorr.u64','vorral.u64',
+ 'vorr.i8','vorral.i8',
+ 'vorr.i16','vorral.i16',
+ 'vorr.i32','vorral.i32',
+ 'vorr.i64','vorral.i64',
+ 'vorr.f32','vorral.f32',
+ 'vorr.f64','vorral.f64',
+
+ 'vswp','vswpal',
+ 'vswp.s8','vswpal.s8',
+ 'vswp.s16','vswpal.s16',
+ 'vswp.s32','vswpal.s32',
+ 'vswp.s64','vswpal.s64',
+ 'vswp.u8','vswpal.u8',
+ 'vswp.u16','vswpal.u16',
+ 'vswp.u32','vswpal.u32',
+ 'vswp.u64','vswpal.u64',
+ 'vswp.i8','vswpal.i8',
+ 'vswp.i16','vswpal.i16',
+ 'vswp.i32','vswpal.i32',
+ 'vswp.i64','vswpal.i64',
+ 'vswp.f32','vswpal.f32',
+ 'vswp.f64','vswpal.f64'
+ ),
+ /* Unconditional NEON SIMD ARM Registers Interop Instructions */
+ 21 => array(
+ 'vmrs','vmrsal',
+ 'vmsr','vmsral'
+ ),
+ /* Unconditional NEON SIMD Bit/Byte-Level Instructions */
+ 22 => array(
+ 'vcnt.8','vcntal.8',
+ 'vdup.8','vdupal.8',
+
+ 'vdup.16','vdupal.16',
+ 'vdup.32','vdupal.32',
+
+ 'vext.8','vextal.8',
+ 'vext.16','vextal.16',
+
+ 'vext.32','vextal.32',
+ 'vext.64','vextal.64',
+
+ 'vrev16.8','vrev16al.8',
+ 'vrev32.8','vrev32al.8',
+ 'vrev32.16','vrev32al.16',
+ 'vrev64.8','vrev64al.8',
+ 'vrev64.16','vrev64al.16',
+ 'vrev64.32','vrev64al.32',
+
+ 'vsli.8','vslial.8',
+ 'vsli.16','vslial.16',
+ 'vsli.32','vslial.32',
+ 'vsli.64','vslial.64',
+
+ 'vsri.8','vsrial.8',
+ 'vsri.16','vsrial.16',
+ 'vsri.32','vsrial.32',
+ 'vsri.64','vsrial.64',
+
+ 'vtbl.8','vtblal.8',
+
+ 'vtbx','vtbxal',
+
+ 'vtrn.8','vtrnal.8',
+ 'vtrn.16','vtrnal.16',
+ 'vtrn.32','vtrnal.32',
+
+ 'vtst.8','vtstal.8',
+ 'vtst.16','vtstal.16',
+ 'vtst.32','vtstal.32',
+
+ 'vuzp.8','vuzpal.8',
+ 'vuzp.16','vuzpal.16',
+ 'vuzp.32','vuzpal.32',
+
+ 'vzip.8','vzipal.8',
+ 'vzip.16','vzipal.16',
+ 'vzip.32','vzipal.32',
+
+ 'vmull.p8','vmullal.p8'
+ ),
+ /* Unconditional NEON SIMD Universal Integer Instructions */
+ 23 => array(
+ 'vadd.i8','vaddal.i8',
+ 'vadd.i16','vaddal.i16',
+ 'vadd.i32','vaddal.i32',
+ 'vadd.i64','vaddal.i64',
+
+ 'vsub.i8','vsubal.i8',
+ 'vsub.i16','vsubal.i16',
+ 'vsub.i32','vsubal.i32',
+ 'vsub.i64','vsubal.i64',
+
+ 'vaddhn.i16','vaddhnal.i16',
+ 'vaddhn.i32','vaddhnal.i32',
+ 'vaddhn.i64','vaddhnal.i64',
+
+ 'vsubhn.i16','vsubhnal.i16',
+ 'vsubhn.i32','vsubhnal.i32',
+ 'vsubhn.i64','vsubhnal.i64',
+
+ 'vraddhn.i16','vraddhnal.i16',
+ 'vraddhn.i32','vraddhnal.i32',
+ 'vraddhn.i64','vraddhnal.i64',
+
+ 'vrsubhn.i16','vrsubhnal.i16',
+ 'vrsubhn.i32','vrsubhnal.i32',
+ 'vrsubhn.i64','vrsubhnal.i64',
+
+ 'vpadd.i8','vpaddal.i8',
+ 'vpadd.i16','vpaddal.i16',
+ 'vpadd.i32','vpaddal.i32',
+
+ 'vceq.i8','vceqal.i8',
+ 'vceq.i16','vceqal.i16',
+ 'vceq.i32','vceqal.i32',
+
+ 'vclz.i8','vclzal.i8',
+ 'vclz.i16','vclzal.i16',
+ 'vclz.i32','vclzal.i32',
+
+ 'vmovn.i16','vmovnal.i16',
+ 'vmovn.i32','vmovnal.i32',
+ 'vmovn.i64','vmovnal.i64',
+
+ 'vmla.s8','vmlaal.s8',
+ 'vmla.s16','vmlaal.s16',
+ 'vmla.s32','vmlaal.s32',
+ 'vmla.u8','vmlaal.u8',
+ 'vmla.u16','vmlaal.u16',
+ 'vmla.u32','vmlaal.u32',
+ 'vmla.i8','vmlaal.i8',
+ 'vmla.i16','vmlaal.i16',
+ 'vmla.i32','vmlaal.i32',
+
+ 'vmls.s8','vmlsal.s8',
+ 'vmls.s16','vmlsal.s16',
+ 'vmls.s32','vmlsal.s32',
+ 'vmls.u8','vmlsal.u8',
+ 'vmls.u16','vmlsal.u16',
+ 'vmls.u32','vmlsal.u32',
+ 'vmls.i8','vmlsal.i8',
+ 'vmls.i16','vmlsal.i16',
+ 'vmls.i32','vmlsal.i32',
+
+ 'vmul.s8','vmulal.s8',
+ 'vmul.s16','vmulal.s16',
+ 'vmul.s32','vmulal.s32',
+ 'vmul.u8','vmulal.u8',
+ 'vmul.u16','vmulal.u16',
+ 'vmul.u32','vmulal.u32',
+ 'vmul.i8','vmulal.i8',
+ 'vmul.i16','vmulal.i16',
+ 'vmul.i32','vmulal.i32',
+ 'vmul.p8','vmulal.p8',
+
+ 'vrshrn.i16','vrshrnal.i16',
+ 'vrshrn.i32','vrshrnal.i32',
+ 'vrshrn.i64','vrshrnal.i64',
+
+ 'vshrn.i16','vshrnal.i16',
+ 'vshrn.i32','vshrnal.i32',
+ 'vshrn.i64','vshrnal.i64',
+
+ 'vshl.i8','vshlal.i8',
+ 'vshl.i16','vshlal.i16',
+ 'vshl.i32','vshlal.i32',
+ 'vshl.i64','vshlal.i64',
+
+ 'vshll.i8','vshllal.i8',
+ 'vshll.i16','vshllal.i16',
+ 'vshll.i32','vshllal.i32'
+ ),
+ /* Unconditional NEON SIMD Signed Integer Instructions */
+ 24 => array(
+ 'vaba.s8','vabaal.s8',
+ 'vaba.s16','vabaal.s16',
+ 'vaba.s32','vabaal.s32',
+
+ 'vabal.s8','vabalal.s8',
+ 'vabal.s16','vabalal.s16',
+ 'vabal.s32','vabalal.s32',
+
+ 'vabd.s8','vabdal.s8',
+ 'vabd.s16','vabdal.s16',
+ 'vabd.s32','vabdal.s32',
+
+ 'vabs.s8','vabsal.s8',
+ 'vabs.s16','vabsal.s16',
+ 'vabs.s32','vabsal.s32',
+
+ 'vaddl.s8','vaddlal.s8',
+ 'vaddl.s16','vaddlal.s16',
+ 'vaddl.s32','vaddlal.s32',
+
+ 'vcge.s8','vcgeal.s8',
+ 'vcge.s16','vcgeal.s16',
+ 'vcge.s32','vcgeal.s32',
+
+ 'vcle.s8','vcleal.s8',
+ 'vcle.s16','vcleal.s16',
+ 'vcle.s32','vcleal.s32',
+
+ 'vcgt.s8','vcgtal.s8',
+ 'vcgt.s16','vcgtal.s16',
+ 'vcgt.s32','vcgtal.s32',
+
+ 'vclt.s8','vcltal.s8',
+ 'vclt.s16','vcltal.s16',
+ 'vclt.s32','vcltal.s32',
+
+ 'vcls.s8','vclsal.s8',
+ 'vcls.s16','vclsal.s16',
+ 'vcls.s32','vclsal.s32',
+
+ 'vaddw.s8','vaddwal.s8',
+ 'vaddw.s16','vaddwal.s16',
+ 'vaddw.s32','vaddwal.s32',
+
+ 'vhadd.s8','vhaddal.s8',
+ 'vhadd.s16','vhaddal.s16',
+ 'vhadd.s32','vhaddal.s32',
+
+ 'vhsub.s8','vhsubal.s8',
+ 'vhsub.s16','vhsubal.s16',
+ 'vhsub.s32','vhsubal.s32',
+
+ 'vmax.s8','vmaxal.s8',
+ 'vmax.s16','vmaxal.s16',
+ 'vmax.s32','vmaxal.s32',
+
+ 'vmin.s8','vminal.s8',
+ 'vmin.s16','vminal.s16',
+ 'vmin.s32','vminal.s32',
+
+ 'vmlal.s8','vmlalal.s8',
+ 'vmlal.s16','vmlalal.s16',
+ 'vmlal.s32','vmlalal.s32',
+
+ 'vmlsl.s8','vmlslal.s8',
+ 'vmlsl.s16','vmlslal.s16',
+ 'vmlsl.s32','vmlslal.s32',
+
+ 'vneg.s8','vnegal.s8',
+ 'vneg.s16','vnegal.s16',
+ 'vneg.s32','vnegal.s32',
+
+ 'vpadal.s8','vpadalal.s8',
+ 'vpadal.s16','vpadalal.s16',
+ 'vpadal.s32','vpadalal.s32',
+
+ 'vmovl.s8','vmovlal.s8',
+ 'vmovl.s16','vmovlal.s16',
+ 'vmovl.s32','vmovlal.s32',
+
+ 'vmull.s8','vmullal.s8',
+ 'vmull.s16','vmullal.s16',
+ 'vmull.s32','vmullal.s32',
+
+ 'vpaddl.s8','vpaddlal.s8',
+ 'vpaddl.s16','vpaddlal.s16',
+ 'vpaddl.s32','vpaddlal.s32',
+
+ 'vpmax.s8','vpmaxal.s8',
+ 'vpmax.s16','vpmaxal.s16',
+ 'vpmax.s32','vpmaxal.s32',
+
+ 'vpmin.s8','vpminal.s8',
+ 'vpmin.s16','vpminal.s16',
+ 'vpmin.s32','vpminal.s32',
+
+ 'vqabs.s8','vqabsal.s8',
+ 'vqabs.s16','vqabsal.s16',
+ 'vqabs.s32','vqabsal.s32',
+
+ 'vqadd.s8','vqaddal.s8',
+ 'vqadd.s16','vqaddal.s16',
+ 'vqadd.s32','vqaddal.s32',
+ 'vqadd.s64','vqaddal.s64',
+
+ 'vqdmlal.s16','vqdmlalal.s16',
+ 'vqdmlal.s32','vqdmlalal.s32',
+
+ 'vqdmlsl.s16','vqdmlslal.s16',
+ 'vqdmlsl.s32','vqdmlslal.s32',
+
+ 'vqdmulh.s16','vqdmulhal.s16',
+ 'vqdmulh.s32','vqdmulhal.s32',
+
+ 'vqdmull.s16','vqdmullal.s16',
+ 'vqdmull.s32','vqdmullal.s32',
+
+ 'vqmovn.s16','vqmovnal.s16',
+ 'vqmovn.s32','vqmovnal.s32',
+ 'vqmovn.s64','vqmovnal.s64',
+
+ 'vqmovun.s16','vqmovunal.s16',
+ 'vqmovun.s32','vqmovunal.s32',
+ 'vqmovun.s64','vqmovunal.s64',
+
+ 'vqneg.s8','vqnegal.s8',
+ 'vqneg.s16','vqnegal.s16',
+ 'vqneg.s32','vqnegal.s32',
+
+ 'vqrdmulh.s16','vqrdmulhal.s16',
+ 'vqrdmulh.s32','vqrdmulhal.s32',
+
+ 'vqrshl.s8','vqrshlal.s8',
+ 'vqrshl.s16','vqrshlal.s16',
+ 'vqrshl.s32','vqrshlal.s32',
+ 'vqrshl.s64','vqrshlal.s64',
+
+ 'vqrshrn.s16','vqrshrnal.s16',
+ 'vqrshrn.s32','vqrshrnal.s32',
+ 'vqrshrn.s64','vqrshrnal.s64',
+
+ 'vqrshrun.s16','vqrshrunal.s16',
+ 'vqrshrun.s32','vqrshrunal.s32',
+ 'vqrshrun.s64','vqrshrunal.s64',
+
+ 'vqshl.s8','vqshlal.s8',
+ 'vqshl.s16','vqshlal.s16',
+ 'vqshl.s32','vqshlal.s32',
+ 'vqshl.s64','vqshlal.s64',
+
+ 'vqshlu.s8','vqshlual.s8',
+ 'vqshlu.s16','vqshlual.s16',
+ 'vqshlu.s32','vqshlual.s32',
+ 'vqshlu.s64','vqshlual.s64',
+
+ 'vqshrn.s16','vqshrnal.s16',
+ 'vqshrn.s32','vqshrnal.s32',
+ 'vqshrn.s64','vqshrnal.s64',
+
+ 'vqshrun.s16','vqshrunal.s16',
+ 'vqshrun.s32','vqshrunal.s32',
+ 'vqshrun.s64','vqshrunal.s64',
+
+ 'vqsub.s8','vqsubal.s8',
+ 'vqsub.s16','vqsubal.s16',
+ 'vqsub.s32','vqsubal.s32',
+ 'vqsub.s64','vqsubal.s64',
+
+ 'vrhadd.s8','vrhaddal.s8',
+ 'vrhadd.s16','vrhaddal.s16',
+ 'vrhadd.s32','vrhaddal.s32',
+
+ 'vrshl.s8','vrshlal.s8',
+ 'vrshl.s16','vrshlal.s16',
+ 'vrshl.s32','vrshlal.s32',
+ 'vrshl.s64','vrshlal.s64',
+
+ 'vrshr.s8','vrshral.s8',
+ 'vrshr.s16','vrshral.s16',
+ 'vrshr.s32','vrshral.s32',
+ 'vrshr.s64','vrshral.s64',
+
+ 'vrsra.s8','vrsraal.s8',
+ 'vrsra.s16','vrsraal.s16',
+ 'vrsra.s32','vrsraal.s32',
+ 'vrsra.s64','vrsraal.s64',
+
+ 'vshl.s8','vshlal.s8',
+ 'vshl.s16','vshlal.s16',
+ 'vshl.s32','vshlal.s32',
+ 'vshl.s64','vshlal.s64',
+
+ 'vshll.s8','vshllal.s8',
+ 'vshll.s16','vshllal.s16',
+ 'vshll.s32','vshllal.s32',
+
+ 'vshr.s8','vshral.s8',
+ 'vshr.s16','vshral.s16',
+ 'vshr.s32','vshral.s32',
+ 'vshr.s64','vshral.s64',
+
+ 'vsra.s8','vsraal.s8',
+ 'vsra.s16','vsraal.s16',
+ 'vsra.s32','vsraal.s32',
+ 'vsra.s64','vsraal.s64',
+
+ 'vsubl.s8','vsublal.s8',
+ 'vsubl.s16','vsublal.s16',
+ 'vsubl.s32','vsublal.s32',
+
+ 'vsubh.s8','vsubhal.s8',
+ 'vsubh.s16','vsubhal.s16',
+ 'vsubh.s32','vsubhal.s32'
+ ),
+ /* Unconditional NEON SIMD Unsigned Integer Instructions */
+ 25 => array(
+ 'vaba.u8','vabaal.u8',
+ 'vaba.u16','vabaal.u16',
+ 'vaba.u32','vabaal.u32',
+
+ 'vabal.u8','vabalal.u8',
+ 'vabal.u16','vabalal.u16',
+ 'vabal.u32','vabalal.u32',
+
+ 'vabd.u8','vabdal.u8',
+ 'vabd.u16','vabdal.u16',
+ 'vabd.u32','vabdal.u32',
+
+ 'vaddl.u8','vaddlal.u8',
+ 'vaddl.u16','vaddlal.u16',
+ 'vaddl.u32','vaddlal.u32',
+
+ 'vsubl.u8','vsublal.u8',
+ 'vsubl.u16','vsublal.u16',
+ 'vsubl.u32','vsublal.u32',
+
+ 'vaddw.u8','vaddwal.u8',
+ 'vaddw.u16','vaddwal.u16',
+ 'vaddw.u32','vaddwal.u32',
+
+ 'vsubh.u8','vsubhal.u8',
+ 'vsubh.u16','vsubhal.u16',
+ 'vsubh.u32','vsubhal.u32',
+
+ 'vhadd.u8','vhaddal.u8',
+ 'vhadd.u16','vhaddal.u16',
+ 'vhadd.u32','vhaddal.u32',
+
+ 'vhsub.u8','vhsubal.u8',
+ 'vhsub.u16','vhsubal.u16',
+ 'vhsub.u32','vhsubal.u32',
+
+ 'vpadal.u8','vpadalal.u8',
+ 'vpadal.u16','vpadalal.u16',
+ 'vpadal.u32','vpadalal.u32',
+
+ 'vpaddl.u8','vpaddlal.u8',
+ 'vpaddl.u16','vpaddlal.u16',
+ 'vpaddl.u32','vpaddlal.u32',
+
+ 'vcge.u8','vcgeal.u8',
+ 'vcge.u16','vcgeal.u16',
+ 'vcge.u32','vcgeal.u32',
+
+ 'vcle.u8','vcleal.u8',
+ 'vcle.u16','vcleal.u16',
+ 'vcle.u32','vcleal.u32',
+
+ 'vcgt.u8','vcgtal.u8',
+ 'vcgt.u16','vcgtal.u16',
+ 'vcgt.u32','vcgtal.u32',
+
+ 'vclt.u8','vcltal.u8',
+ 'vclt.u16','vcltal.u16',
+ 'vclt.u32','vcltal.u32',
+
+ 'vmax.u8','vmaxal.u8',
+ 'vmax.u16','vmaxal.u16',
+ 'vmax.u32','vmaxal.u32',
+
+ 'vmin.u8','vminal.u8',
+ 'vmin.u16','vminal.u16',
+ 'vmin.u32','vminal.u32',
+
+ 'vmlal.u8','vmlalal.u8',
+ 'vmlal.u16','vmlalal.u16',
+ 'vmlal.u32','vmlalal.u32',
+
+ 'vmlsl.u8','vmlslal.u8',
+ 'vmlsl.u16','vmlslal.u16',
+ 'vmlsl.u32','vmlslal.u32',
+
+ 'vmull.u8','vmullal.u8',
+ 'vmull.u16','vmullal.u16',
+ 'vmull.u32','vmullal.u32',
+
+ 'vmovl.u8','vmovlal.u8',
+ 'vmovl.u16','vmovlal.u16',
+ 'vmovl.u32','vmovlal.u32',
+
+ 'vshl.u8','vshlal.u8',
+ 'vshl.u16','vshlal.u16',
+ 'vshl.u32','vshlal.u32',
+ 'vshl.u64','vshlal.u64',
+
+ 'vshll.u8','vshllal.u8',
+ 'vshll.u16','vshllal.u16',
+ 'vshll.u32','vshllal.u32',
+
+ 'vshr.u8','vshral.u8',
+ 'vshr.u16','vshral.u16',
+ 'vshr.u32','vshral.u32',
+ 'vshr.u64','vshral.u64',
+
+ 'vsra.u8','vsraal.u8',
+ 'vsra.u16','vsraal.u16',
+ 'vsra.u32','vsraal.u32',
+ 'vsra.u64','vsraal.u64',
+
+ 'vpmax.u8','vpmaxal.u8',
+ 'vpmax.u16','vpmaxal.u16',
+ 'vpmax.u32','vpmaxal.u32',
+
+ 'vpmin.u8','vpminal.u8',
+ 'vpmin.u16','vpminal.u16',
+ 'vpmin.u32','vpminal.u32',
+
+ 'vqadd.u8','vqaddal.u8',
+ 'vqadd.u16','vqaddal.u16',
+ 'vqadd.u32','vqaddal.u32',
+ 'vqadd.u64','vqaddal.u64',
+
+ 'vqsub.u8','vqsubal.u8',
+ 'vqsub.u16','vqsubal.u16',
+ 'vqsub.u32','vqsubal.u32',
+ 'vqsub.u64','vqsubal.u64',
+
+ 'vqmovn.u16','vqmovnal.u16',
+ 'vqmovn.u32','vqmovnal.u32',
+ 'vqmovn.u64','vqmovnal.u64',
+
+ 'vqshl.u8','vqshlal.u8',
+ 'vqshl.u16','vqshlal.u16',
+ 'vqshl.u32','vqshlal.u32',
+ 'vqshl.u64','vqshlal.u64',
+
+ 'vqshrn.u16','vqshrnal.u16',
+ 'vqshrn.u32','vqshrnal.u32',
+ 'vqshrn.u64','vqshrnal.u64',
+
+ 'vqrshl.u8','vqrshlal.u8',
+ 'vqrshl.u16','vqrshlal.u16',
+ 'vqrshl.u32','vqrshlal.u32',
+ 'vqrshl.u64','vqrshlal.u64',
+
+ 'vqrshrn.u16','vqrshrnal.u16',
+ 'vqrshrn.u32','vqrshrnal.u32',
+ 'vqrshrn.u64','vqrshrnal.u64',
+
+ 'vrhadd.u8','vrhaddal.u8',
+ 'vrhadd.u16','vrhaddal.u16',
+ 'vrhadd.u32','vrhaddal.u32',
+
+ 'vrshl.u8','vrshlal.u8',
+ 'vrshl.u16','vrshlal.u16',
+ 'vrshl.u32','vrshlal.u32',
+ 'vrshl.u64','vrshlal.u64',
+
+ 'vrshr.u8','vrshral.u8',
+ 'vrshr.u16','vrshral.u16',
+ 'vrshr.u32','vrshral.u32',
+ 'vrshr.u64','vrshral.u64',
+
+ 'vrsra.u8','vrsraal.u8',
+ 'vrsra.u16','vrsraal.u16',
+ 'vrsra.u32','vrsraal.u32',
+ 'vrsra.u64','vrsraal.u64'
+ ),
+ /* Unconditional VFPv3 & NEON SIMD Floating-Point Instructions */
+ 26 => array(
+ 'vabd.f32','vabdal.f32',
+
+ 'vabs.f32','vabsal.f32',
+ 'vabs.f64','vabsal.f64',
+
+ 'vacge.f32','vacgeal.f32',
+ 'vacgt.f32','vacgtal.f32',
+ 'vacle.f32','vacleal.f32',
+ 'vaclt.f32','vacltal.f32',
+
+ 'vadd.f32','vaddal.f32',
+ 'vadd.f64','vaddal.f64',
+
+ 'vceq.f32','vceqal.f32',
+ 'vcge.f32','vcgeal.f32',
+ 'vcle.f32','vcleal.f32',
+ 'vcgt.f32','vcgtal.f32',
+ 'vclt.f32','vcltal.f32',
+
+ 'vcmp.f32','vcmpal.f32',
+ 'vcmp.f64','vcmpal.f64',
+
+ 'vcmpe.f32','vcmpeal.f32',
+ 'vcmpe.f64','vcmpeal.f64',
+
+ 'vcvt.s16.f32','vcvtal.s16.f32',
+ 'vcvt.s16.f64','vcvtal.s16.f64',
+ 'vcvt.s32.f32','vcvtal.s32.f32',
+ 'vcvt.s32.f64','vcvtal.s32.f64',
+ 'vcvt.u16.f32','vcvtal.u16.f32',
+ 'vcvt.u16.f64','vcvtal.u16.f64',
+ 'vcvt.u32.f32','vcvtal.u32.f32',
+ 'vcvt.u32.f64','vcvtal.u32.f64',
+ 'vcvt.f16.f32','vcvtal.f16.f32',
+ 'vcvt.f32.s32','vcvtal.f32.s32',
+ 'vcvt.f32.u32','vcvtal.f32.u32',
+ 'vcvt.f32.f16','vcvtal.f32.f16',
+ 'vcvt.f32.f64','vcvtal.f32.f64',
+ 'vcvt.f64.s32','vcvtal.f64.s32',
+ 'vcvt.f64.u32','vcvtal.f64.u32',
+ 'vcvt.f64.f32','vcvtal.f64.f32',
+
+ 'vcvtr.s32.f32','vcvtral.s32.f32',
+ 'vcvtr.s32.f64','vcvtral.s32.f64',
+ 'vcvtr.u32.f32','vcvtral.u32.f32',
+ 'vcvtr.u32.f64','vcvtral.u32.f64',
+
+ 'vcvtb.f16.f32','vcvtbal.f16.f32',
+ 'vcvtb.f32.f16','vcvtbal.f32.f16',
+
+ 'vcvtt.f16.f32','vcvttal.f16.f32',
+ 'vcvtt.f32.f16','vcvttal.f32.f16',
+
+ 'vdiv.f32','vdival.f32',
+ 'vdiv.f64','vdival.f64',
+
+ 'vmax.f32','vmaxal.f32',
+ 'vmin.f32','vminal.f32',
+
+ 'vmla.f32','vmlaal.f32',
+ 'vmla.f64','vmlaal.f64',
+
+ 'vmls.f32','vmlsal.f32',
+ 'vmls.f64','vmlsal.f64',
+
+ 'vmul.f32','vmulal.f32',
+ 'vmul.f64','vmulal.f64',
+
+ 'vneg.f32','vnegal.f32',
+ 'vneg.f64','vnegal.f64',
+
+ 'vnmla.f32','vnmlaal.f32',
+ 'vnmla.f64','vnmlaal.f64',
+
+ 'vnmls.f32','vnmlsal.f32',
+ 'vnmls.f64','vnmlsal.f64',
+
+ 'vnmul.f64','vnmulal.f64',
+ 'vnmul.f32','vnmulal.f32',
+
+ 'vpadd.f32','vpaddal.f32',
+
+ 'vpmax.f32','vpmaxal.f32',
+ 'vpmin.f32','vpminal.f32',
+
+ 'vrecpe.u32','vrecpeal.u32',
+ 'vrecpe.f32','vrecpeal.f32',
+ 'vrecps.f32','vrecpsal.f32',
+
+ 'vrsqrte.u32','vrsqrteal.u32',
+ 'vrsqrte.f32','vrsqrteal.f32',
+ 'vrsqrts.f32','vrsqrtsal.f32',
+
+ 'vsqrt.f32','vsqrtal.f32',
+ 'vsqrt.f64','vsqrtal.f64',
+
+ 'vsub.f32','vsubal.f32',
+ 'vsub.f64','vsubal.f64'
+ ),
+ /* Conditional VFPv3 & NEON SIMD Memory Access Instructions */
+ 27 => array(
+ /* Conditional VFPv3 & NEON SIMD Memory Access: Loads */
+ 'vldeq.8','vldne.8','vldcs.8','vldhs.8','vldcc.8','vldlo.8','vldmi.8','vldpl.8','vldvs.8','vldvc.8','vldhi.8','vldls.8','vldge.8','vldlt.8','vldgt.8','vldle.8',
+ 'vldeq.16','vldne.16','vldcs.16','vldhs.16','vldcc.16','vldlo.16','vldmi.16','vldpl.16','vldvs.16','vldvc.16','vldhi.16','vldls.16','vldge.16','vldlt.16','vldgt.16','vldle.16',
+ 'vldeq.32','vldne.32','vldcs.32','vldhs.32','vldcc.32','vldlo.32','vldmi.32','vldpl.32','vldvs.32','vldvc.32','vldhi.32','vldls.32','vldge.32','vldlt.32','vldgt.32','vldle.32',
+ 'vldeq.64','vldne.64','vldcs.64','vldhs.64','vldcc.64','vldlo.64','vldmi.64','vldpl.64','vldvs.64','vldvc.64','vldhi.64','vldls.64','vldge.64','vldlt.64','vldgt.64','vldle.64',
+
+ 'vld1eq.8','vld1ne.8','vld1cs.8','vld1hs.8','vld1cc.8','vld1lo.8','vld1mi.8','vld1pl.8','vld1vs.8','vld1vc.8','vld1hi.8','vld1ls.8','vld1ge.8','vld1lt.8','vld1gt.8','vld1le.8',
+ 'vld1eq.16','vld1ne.16','vld1cs.16','vld1hs.16','vld1cc.16','vld1lo.16','vld1mi.16','vld1pl.16','vld1vs.16','vld1vc.16','vld1hi.16','vld1ls.16','vld1ge.16','vld1lt.16','vld1gt.16','vld1le.16',
+ 'vld1eq.32','vld1ne.32','vld1cs.32','vld1hs.32','vld1cc.32','vld1lo.32','vld1mi.32','vld1pl.32','vld1vs.32','vld1vc.32','vld1hi.32','vld1ls.32','vld1ge.32','vld1lt.32','vld1gt.32','vld1le.32',
+
+ 'vld2eq.8','vld2ne.8','vld2cs.8','vld2hs.8','vld2cc.8','vld2lo.8','vld2mi.8','vld2pl.8','vld2vs.8','vld2vc.8','vld2hi.8','vld2ls.8','vld2ge.8','vld2lt.8','vld2gt.8','vld2le.8',
+ 'vld2eq.16','vld2ne.16','vld2cs.16','vld2hs.16','vld2cc.16','vld2lo.16','vld2mi.16','vld2pl.16','vld2vs.16','vld2vc.16','vld2hi.16','vld2ls.16','vld2ge.16','vld2lt.16','vld2gt.16','vld2le.16',
+ 'vld2eq.32','vld2ne.32','vld2cs.32','vld2hs.32','vld2cc.32','vld2lo.32','vld2mi.32','vld2pl.32','vld2vs.32','vld2vc.32','vld2hi.32','vld2ls.32','vld2ge.32','vld2lt.32','vld2gt.32','vld2le.32',
+
+ 'vld3eq.8','vld3ne.8','vld3cs.8','vld3hs.8','vld3cc.8','vld3lo.8','vld3mi.8','vld3pl.8','vld3vs.8','vld3vc.8','vld3hi.8','vld3ls.8','vld3ge.8','vld3lt.8','vld3gt.8','vld3le.8',
+ 'vld3eq.16','vld3ne.16','vld3cs.16','vld3hs.16','vld3cc.16','vld3lo.16','vld3mi.16','vld3pl.16','vld3vs.16','vld3vc.16','vld3hi.16','vld3ls.16','vld3ge.16','vld3lt.16','vld3gt.16','vld3le.16',
+ 'vld3eq.32','vld3ne.32','vld3cs.32','vld3hs.32','vld3cc.32','vld3lo.32','vld3mi.32','vld3pl.32','vld3vs.32','vld3vc.32','vld3hi.32','vld3ls.32','vld3ge.32','vld3lt.32','vld3gt.32','vld3le.32',
+
+ 'vld4eq.8','vld4ne.8','vld4cs.8','vld4hs.8','vld4cc.8','vld4lo.8','vld4mi.8','vld4pl.8','vld4vs.8','vld4vc.8','vld4hi.8','vld4ls.8','vld4ge.8','vld4lt.8','vld4gt.8','vld4le.8',
+ 'vld4eq.16','vld4ne.16','vld4cs.16','vld4hs.16','vld4cc.16','vld4lo.16','vld4mi.16','vld4pl.16','vld4vs.16','vld4vc.16','vld4hi.16','vld4ls.16','vld4ge.16','vld4lt.16','vld4gt.16','vld4le.16',
+ 'vld4eq.32','vld4ne.32','vld4cs.32','vld4hs.32','vld4cc.32','vld4lo.32','vld4mi.32','vld4pl.32','vld4vs.32','vld4vc.32','vld4hi.32','vld4ls.32','vld4ge.32','vld4lt.32','vld4gt.32','vld4le.32',
+
+ 'vldmeq','vldmne','vldmcs','vldmhs','vldmcc','vldmlo','vldmmi','vldmpl','vldmvs','vldmvc','vldmhi','vldmls','vldmge','vldmlt','vldmgt','vldmle',
+ 'vldmeq.32','vldmne.32','vldmcs.32','vldmhs.32','vldmcc.32','vldmlo.32','vldmmi.32','vldmpl.32','vldmvs.32','vldmvc.32','vldmhi.32','vldmls.32','vldmge.32','vldmlt.32','vldmgt.32','vldmle.32',
+ 'vldmeq.64','vldmne.64','vldmcs.64','vldmhs.64','vldmcc.64','vldmlo.64','vldmmi.64','vldmpl.64','vldmvs.64','vldmvc.64','vldmhi.64','vldmls.64','vldmge.64','vldmlt.64','vldmgt.64','vldmle.64',
+
+ 'vldmiaeq','vldmiane','vldmiacs','vldmiahs','vldmiacc','vldmialo','vldmiami','vldmiapl','vldmiavs','vldmiavc','vldmiahi','vldmials','vldmiage','vldmialt','vldmiagt','vldmiale',
+ 'vldmiaeq.32','vldmiane.32','vldmiacs.32','vldmiahs.32','vldmiacc.32','vldmialo.32','vldmiami.32','vldmiapl.32','vldmiavs.32','vldmiavc.32','vldmiahi.32','vldmials.32','vldmiage.32','vldmialt.32','vldmiagt.32','vldmiale.32',
+ 'vldmiaeq.64','vldmiane.64','vldmiacs.64','vldmiahs.64','vldmiacc.64','vldmialo.64','vldmiami.64','vldmiapl.64','vldmiavs.64','vldmiavc.64','vldmiahi.64','vldmials.64','vldmiage.64','vldmialt.64','vldmiagt.64','vldmiale.64',
+
+ 'vldmdbeq','vldmdbne','vldmdbcs','vldmdbhs','vldmdbcc','vldmdblo','vldmdbmi','vldmdbpl','vldmdbvs','vldmdbvc','vldmdbhi','vldmdbls','vldmdbge','vldmdblt','vldmdbgt','vldmdble',
+ 'vldmdbeq.32','vldmdbne.32','vldmdbcs.32','vldmdbhs.32','vldmdbcc.32','vldmdblo.32','vldmdbmi.32','vldmdbpl.32','vldmdbvs.32','vldmdbvc.32','vldmdbhi.32','vldmdbls.32','vldmdbge.32','vldmdblt.32','vldmdbgt.32','vldmdble.32',
+ 'vldmdbeq.64','vldmdbne.64','vldmdbcs.64','vldmdbhs.64','vldmdbcc.64','vldmdblo.64','vldmdbmi.64','vldmdbpl.64','vldmdbvs.64','vldmdbvc.64','vldmdbhi.64','vldmdbls.64','vldmdbge.64','vldmdblt.64','vldmdbgt.64','vldmdble.64',
+
+ 'vldreq','vldrne','vldrcs','vldrhs','vldrcc','vldrlo','vldrmi','vldrpl','vldrvs','vldrvc','vldrhi','vldrls','vldrge','vldrlt','vldrgt','vldrle',
+ 'vldreq.32','vldrne.32','vldrcs.32','vldrhs.32','vldrcc.32','vldrlo.32','vldrmi.32','vldrpl.32','vldrvs.32','vldrvc.32','vldrhi.32','vldrls.32','vldrge.32','vldrlt.32','vldrgt.32','vldrle.32',
+ 'vldreq.64','vldrne.64','vldrcs.64','vldrhs.64','vldrcc.64','vldrlo.64','vldrmi.64','vldrpl.64','vldrvs.64','vldrvc.64','vldrhi.64','vldrls.64','vldrge.64','vldrlt.64','vldrgt.64','vldrle.64',
+
+ 'vpopeq','vpopne','vpopcs','vpophs','vpopcc','vpoplo','vpopmi','vpoppl','vpopvs','vpopvc','vpophi','vpopls','vpopge','vpoplt','vpopgt','vpople',
+ 'vpopeq.32','vpopne.32','vpopcs.32','vpophs.32','vpopcc.32','vpoplo.32','vpopmi.32','vpoppl.32','vpopvs.32','vpopvc.32','vpophi.32','vpopls.32','vpopge.32','vpoplt.32','vpopgt.32','vpople.32',
+ 'vpopeq.64','vpopne.64','vpopcs.64','vpophs.64','vpopcc.64','vpoplo.64','vpopmi.64','vpoppl.64','vpopvs.64','vpopvc.64','vpophi.64','vpopls.64','vpopge.64','vpoplt.64','vpopgt.64','vpople.64',
+
+ /* Conditional VFPv3 & NEON SIMD Memory Access: Stores */
+ 'vst1eq.8','vst1ne.8','vst1cs.8','vst1hs.8','vst1cc.8','vst1lo.8','vst1mi.8','vst1pl.8','vst1vs.8','vst1vc.8','vst1hi.8','vst1ls.8','vst1ge.8','vst1lt.8','vst1gt.8','vst1le.8',
+ 'vst1eq.16','vst1ne.16','vst1cs.16','vst1hs.16','vst1cc.16','vst1lo.16','vst1mi.16','vst1pl.16','vst1vs.16','vst1vc.16','vst1hi.16','vst1ls.16','vst1ge.16','vst1lt.16','vst1gt.16','vst1le.16',
+ 'vst1eq.32','vst1ne.32','vst1cs.32','vst1hs.32','vst1cc.32','vst1lo.32','vst1mi.32','vst1pl.32','vst1vs.32','vst1vc.32','vst1hi.32','vst1ls.32','vst1ge.32','vst1lt.32','vst1gt.32','vst1le.32',
+ 'vst1eq.64','vst1ne.64','vst1cs.64','vst1hs.64','vst1cc.64','vst1lo.64','vst1mi.64','vst1pl.64','vst1vs.64','vst1vc.64','vst1hi.64','vst1ls.64','vst1ge.64','vst1lt.64','vst1gt.64','vst1le.64',
+
+ 'vst2eq.8','vst2ne.8','vst2cs.8','vst2hs.8','vst2cc.8','vst2lo.8','vst2mi.8','vst2pl.8','vst2vs.8','vst2vc.8','vst2hi.8','vst2ls.8','vst2ge.8','vst2lt.8','vst2gt.8','vst2le.8',
+ 'vst2eq.16','vst2ne.16','vst2cs.16','vst2hs.16','vst2cc.16','vst2lo.16','vst2mi.16','vst2pl.16','vst2vs.16','vst2vc.16','vst2hi.16','vst2ls.16','vst2ge.16','vst2lt.16','vst2gt.16','vst2le.16',
+ 'vst2eq.32','vst2ne.32','vst2cs.32','vst2hs.32','vst2cc.32','vst2lo.32','vst2mi.32','vst2pl.32','vst2vs.32','vst2vc.32','vst2hi.32','vst2ls.32','vst2ge.32','vst2lt.32','vst2gt.32','vst2le.32',
+
+ 'vst3eq.8','vst3ne.8','vst3cs.8','vst3hs.8','vst3cc.8','vst3lo.8','vst3mi.8','vst3pl.8','vst3vs.8','vst3vc.8','vst3hi.8','vst3ls.8','vst3ge.8','vst3lt.8','vst3gt.8','vst3le.8',
+ 'vst3eq.16','vst3ne.16','vst3cs.16','vst3hs.16','vst3cc.16','vst3lo.16','vst3mi.16','vst3pl.16','vst3vs.16','vst3vc.16','vst3hi.16','vst3ls.16','vst3ge.16','vst3lt.16','vst3gt.16','vst3le.16',
+ 'vst3eq.32','vst3ne.32','vst3cs.32','vst3hs.32','vst3cc.32','vst3lo.32','vst3mi.32','vst3pl.32','vst3vs.32','vst3vc.32','vst3hi.32','vst3ls.32','vst3ge.32','vst3lt.32','vst3gt.32','vst3le.32',
+
+ 'vst4eq.8','vst4ne.8','vst4cs.8','vst4hs.8','vst4cc.8','vst4lo.8','vst4mi.8','vst4pl.8','vst4vs.8','vst4vc.8','vst4hi.8','vst4ls.8','vst4ge.8','vst4lt.8','vst4gt.8','vst4le.8',
+ 'vst4eq.16','vst4ne.16','vst4cs.16','vst4hs.16','vst4cc.16','vst4lo.16','vst4mi.16','vst4pl.16','vst4vs.16','vst4vc.16','vst4hi.16','vst4ls.16','vst4ge.16','vst4lt.16','vst4gt.16','vst4le.16',
+ 'vst4eq.32','vst4ne.32','vst4cs.32','vst4hs.32','vst4cc.32','vst4lo.32','vst4mi.32','vst4pl.32','vst4vs.32','vst4vc.32','vst4hi.32','vst4ls.32','vst4ge.32','vst4lt.32','vst4gt.32','vst4le.32',
+
+ 'vstmeq','vstmne','vstmcs','vstmhs','vstmcc','vstmlo','vstmmi','vstmpl','vstmvs','vstmvc','vstmhi','vstmls','vstmge','vstmlt','vstmgt','vstmle',
+ 'vstmeq.32','vstmne.32','vstmcs.32','vstmhs.32','vstmcc.32','vstmlo.32','vstmmi.32','vstmpl.32','vstmvs.32','vstmvc.32','vstmhi.32','vstmls.32','vstmge.32','vstmlt.32','vstmgt.32','vstmle.32',
+ 'vstmeq.64','vstmne.64','vstmcs.64','vstmhs.64','vstmcc.64','vstmlo.64','vstmmi.64','vstmpl.64','vstmvs.64','vstmvc.64','vstmhi.64','vstmls.64','vstmge.64','vstmlt.64','vstmgt.64','vstmle.64',
+
+ 'vstmiaeq','vstmiane','vstmiacs','vstmiahs','vstmiacc','vstmialo','vstmiami','vstmiapl','vstmiavs','vstmiavc','vstmiahi','vstmials','vstmiage','vstmialt','vstmiagt','vstmiale',
+ 'vstmiaeq.32','vstmiane.32','vstmiacs.32','vstmiahs.32','vstmiacc.32','vstmialo.32','vstmiami.32','vstmiapl.32','vstmiavs.32','vstmiavc.32','vstmiahi.32','vstmials.32','vstmiage.32','vstmialt.32','vstmiagt.32','vstmiale.32',
+ 'vstmiaeq.64','vstmiane.64','vstmiacs.64','vstmiahs.64','vstmiacc.64','vstmialo.64','vstmiami.64','vstmiapl.64','vstmiavs.64','vstmiavc.64','vstmiahi.64','vstmials.64','vstmiage.64','vstmialt.64','vstmiagt.64','vstmiale.64',
+
+ 'vstmdbeq','vstmdbne','vstmdbcs','vstmdbhs','vstmdbcc','vstmdblo','vstmdbmi','vstmdbpl','vstmdbvs','vstmdbvc','vstmdbhi','vstmdbls','vstmdbge','vstmdblt','vstmdbgt','vstmdble',
+ 'vstmdbeq.32','vstmdbne.32','vstmdbcs.32','vstmdbhs.32','vstmdbcc.32','vstmdblo.32','vstmdbmi.32','vstmdbpl.32','vstmdbvs.32','vstmdbvc.32','vstmdbhi.32','vstmdbls.32','vstmdbge.32','vstmdblt.32','vstmdbgt.32','vstmdble.32',
+ 'vstmdbeq.64','vstmdbne.64','vstmdbcs.64','vstmdbhs.64','vstmdbcc.64','vstmdblo.64','vstmdbmi.64','vstmdbpl.64','vstmdbvs.64','vstmdbvc.64','vstmdbhi.64','vstmdbls.64','vstmdbge.64','vstmdblt.64','vstmdbgt.64','vstmdble.64',
+
+ 'vstreq','vstrne','vstrcs','vstrhs','vstrcc','vstrlo','vstrmi','vstrpl','vstrvs','vstrvc','vstrhi','vstrls','vstrge','vstrlt','vstrgt','vstrle',
+ 'vstreq.32','vstrne.32','vstrcs.32','vstrhs.32','vstrcc.32','vstrlo.32','vstrmi.32','vstrpl.32','vstrvs.32','vstrvc.32','vstrhi.32','vstrls.32','vstrge.32','vstrlt.32','vstrgt.32','vstrle.32',
+ 'vstreq.64','vstrne.64','vstrcs.64','vstrhs.64','vstrcc.64','vstrlo.64','vstrmi.64','vstrpl.64','vstrvs.64','vstrvc.64','vstrhi.64','vstrls.64','vstrge.64','vstrlt.64','vstrgt.64','vstrle.64',
+
+ 'vpusheq','vpushne','vpushcs','vpushhs','vpushcc','vpushlo','vpushmi','vpushpl','vpushvs','vpushvc','vpushhi','vpushls','vpushge','vpushlt','vpushgt','vpushle',
+ 'vpusheq.32','vpushne.32','vpushcs.32','vpushhs.32','vpushcc.32','vpushlo.32','vpushmi.32','vpushpl.32','vpushvs.32','vpushvc.32','vpushhi.32','vpushls.32','vpushge.32','vpushlt.32','vpushgt.32','vpushle.32',
+ 'vpusheq.64','vpushne.64','vpushcs.64','vpushhs.64','vpushcc.64','vpushlo.64','vpushmi.64','vpushpl.64','vpushvs.64','vpushvc.64','vpushhi.64','vpushls.64','vpushge.64','vpushlt.64','vpushgt.64','vpushle.64'
+ ),
+ /* Conditional NEON SIMD Logical Instructions */
+ 28 => array(
+ 'vandeq','vandne','vandcs','vandhs','vandcc','vandlo','vandmi','vandpl','vandvs','vandvc','vandhi','vandls','vandge','vandlt','vandgt','vandle',
+ 'vandeq.i8','vandne.i8','vandcs.i8','vandhs.i8','vandcc.i8','vandlo.i8','vandmi.i8','vandpl.i8','vandvs.i8','vandvc.i8','vandhi.i8','vandls.i8','vandge.i8','vandlt.i8','vandgt.i8','vandle.i8',
+ 'vandeq.i16','vandne.i16','vandcs.i16','vandhs.i16','vandcc.i16','vandlo.i16','vandmi.i16','vandpl.i16','vandvs.i16','vandvc.i16','vandhi.i16','vandls.i16','vandge.i16','vandlt.i16','vandgt.i16','vandle.i16',
+ 'vandeq.i32','vandne.i32','vandcs.i32','vandhs.i32','vandcc.i32','vandlo.i32','vandmi.i32','vandpl.i32','vandvs.i32','vandvc.i32','vandhi.i32','vandls.i32','vandge.i32','vandlt.i32','vandgt.i32','vandle.i32',
+ 'vandeq.i64','vandne.i64','vandcs.i64','vandhs.i64','vandcc.i64','vandlo.i64','vandmi.i64','vandpl.i64','vandvs.i64','vandvc.i64','vandhi.i64','vandls.i64','vandge.i64','vandlt.i64','vandgt.i64','vandle.i64',
+ 'vandeq.s8','vandne.s8','vandcs.s8','vandhs.s8','vandcc.s8','vandlo.s8','vandmi.s8','vandpl.s8','vandvs.s8','vandvc.s8','vandhi.s8','vandls.s8','vandge.s8','vandlt.s8','vandgt.s8','vandle.s8',
+ 'vandeq.s16','vandne.s16','vandcs.s16','vandhs.s16','vandcc.s16','vandlo.s16','vandmi.s16','vandpl.s16','vandvs.s16','vandvc.s16','vandhi.s16','vandls.s16','vandge.s16','vandlt.s16','vandgt.s16','vandle.s16',
+ 'vandeq.s32','vandne.s32','vandcs.s32','vandhs.s32','vandcc.s32','vandlo.s32','vandmi.s32','vandpl.s32','vandvs.s32','vandvc.s32','vandhi.s32','vandls.s32','vandge.s32','vandlt.s32','vandgt.s32','vandle.s32',
+ 'vandeq.s64','vandne.s64','vandcs.s64','vandhs.s64','vandcc.s64','vandlo.s64','vandmi.s64','vandpl.s64','vandvs.s64','vandvc.s64','vandhi.s64','vandls.s64','vandge.s64','vandlt.s64','vandgt.s64','vandle.s64',
+ 'vandeq.u8','vandne.u8','vandcs.u8','vandhs.u8','vandcc.u8','vandlo.u8','vandmi.u8','vandpl.u8','vandvs.u8','vandvc.u8','vandhi.u8','vandls.u8','vandge.u8','vandlt.u8','vandgt.u8','vandle.u8',
+ 'vandeq.u16','vandne.u16','vandcs.u16','vandhs.u16','vandcc.u16','vandlo.u16','vandmi.u16','vandpl.u16','vandvs.u16','vandvc.u16','vandhi.u16','vandls.u16','vandge.u16','vandlt.u16','vandgt.u16','vandle.u16',
+ 'vandeq.u32','vandne.u32','vandcs.u32','vandhs.u32','vandcc.u32','vandlo.u32','vandmi.u32','vandpl.u32','vandvs.u32','vandvc.u32','vandhi.u32','vandls.u32','vandge.u32','vandlt.u32','vandgt.u32','vandle.u32',
+ 'vandeq.u64','vandne.u64','vandcs.u64','vandhs.u64','vandcc.u64','vandlo.u64','vandmi.u64','vandpl.u64','vandvs.u64','vandvc.u64','vandhi.u64','vandls.u64','vandge.u64','vandlt.u64','vandgt.u64','vandle.u64',
+ 'vandeq.f32','vandne.f32','vandcs.f32','vandhs.f32','vandcc.f32','vandlo.f32','vandmi.f32','vandpl.f32','vandvs.f32','vandvc.f32','vandhi.f32','vandls.f32','vandge.f32','vandlt.f32','vandgt.f32','vandle.f32',
+ 'vandeq.f64','vandne.f64','vandcs.f64','vandhs.f64','vandcc.f64','vandlo.f64','vandmi.f64','vandpl.f64','vandvs.f64','vandvc.f64','vandhi.f64','vandls.f64','vandge.f64','vandlt.f64','vandgt.f64','vandle.f64',
+
+ 'vbiceq','vbicne','vbiccs','vbichs','vbiccc','vbiclo','vbicmi','vbicpl','vbicvs','vbicvc','vbichi','vbicls','vbicge','vbiclt','vbicgt','vbicle',
+ 'vbiceq.i8','vbicne.i8','vbiccs.i8','vbichs.i8','vbiccc.i8','vbiclo.i8','vbicmi.i8','vbicpl.i8','vbicvs.i8','vbicvc.i8','vbichi.i8','vbicls.i8','vbicge.i8','vbiclt.i8','vbicgt.i8','vbicle.i8',
+ 'vbiceq.i16','vbicne.i16','vbiccs.i16','vbichs.i16','vbiccc.i16','vbiclo.i16','vbicmi.i16','vbicpl.i16','vbicvs.i16','vbicvc.i16','vbichi.i16','vbicls.i16','vbicge.i16','vbiclt.i16','vbicgt.i16','vbicle.i16',
+ 'vbiceq.i32','vbicne.i32','vbiccs.i32','vbichs.i32','vbiccc.i32','vbiclo.i32','vbicmi.i32','vbicpl.i32','vbicvs.i32','vbicvc.i32','vbichi.i32','vbicls.i32','vbicge.i32','vbiclt.i32','vbicgt.i32','vbicle.i32',
+ 'vbiceq.i64','vbicne.i64','vbiccs.i64','vbichs.i64','vbiccc.i64','vbiclo.i64','vbicmi.i64','vbicpl.i64','vbicvs.i64','vbicvc.i64','vbichi.i64','vbicls.i64','vbicge.i64','vbiclt.i64','vbicgt.i64','vbicle.i64',
+ 'vbiceq.s8','vbicne.s8','vbiccs.s8','vbichs.s8','vbiccc.s8','vbiclo.s8','vbicmi.s8','vbicpl.s8','vbicvs.s8','vbicvc.s8','vbichi.s8','vbicls.s8','vbicge.s8','vbiclt.s8','vbicgt.s8','vbicle.s8',
+ 'vbiceq.s16','vbicne.s16','vbiccs.s16','vbichs.s16','vbiccc.s16','vbiclo.s16','vbicmi.s16','vbicpl.s16','vbicvs.s16','vbicvc.s16','vbichi.s16','vbicls.s16','vbicge.s16','vbiclt.s16','vbicgt.s16','vbicle.s16',
+ 'vbiceq.s32','vbicne.s32','vbiccs.s32','vbichs.s32','vbiccc.s32','vbiclo.s32','vbicmi.s32','vbicpl.s32','vbicvs.s32','vbicvc.s32','vbichi.s32','vbicls.s32','vbicge.s32','vbiclt.s32','vbicgt.s32','vbicle.s32',
+ 'vbiceq.s64','vbicne.s64','vbiccs.s64','vbichs.s64','vbiccc.s64','vbiclo.s64','vbicmi.s64','vbicpl.s64','vbicvs.s64','vbicvc.s64','vbichi.s64','vbicls.s64','vbicge.s64','vbiclt.s64','vbicgt.s64','vbicle.s64',
+ 'vbiceq.u8','vbicne.u8','vbiccs.u8','vbichs.u8','vbiccc.u8','vbiclo.u8','vbicmi.u8','vbicpl.u8','vbicvs.u8','vbicvc.u8','vbichi.u8','vbicls.u8','vbicge.u8','vbiclt.u8','vbicgt.u8','vbicle.u8',
+ 'vbiceq.u16','vbicne.u16','vbiccs.u16','vbichs.u16','vbiccc.u16','vbiclo.u16','vbicmi.u16','vbicpl.u16','vbicvs.u16','vbicvc.u16','vbichi.u16','vbicls.u16','vbicge.u16','vbiclt.u16','vbicgt.u16','vbicle.u16',
+ 'vbiceq.u32','vbicne.u32','vbiccs.u32','vbichs.u32','vbiccc.u32','vbiclo.u32','vbicmi.u32','vbicpl.u32','vbicvs.u32','vbicvc.u32','vbichi.u32','vbicls.u32','vbicge.u32','vbiclt.u32','vbicgt.u32','vbicle.u32',
+ 'vbiceq.u64','vbicne.u64','vbiccs.u64','vbichs.u64','vbiccc.u64','vbiclo.u64','vbicmi.u64','vbicpl.u64','vbicvs.u64','vbicvc.u64','vbichi.u64','vbicls.u64','vbicge.u64','vbiclt.u64','vbicgt.u64','vbicle.u64',
+ 'vbiceq.f32','vbicne.f32','vbiccs.f32','vbichs.f32','vbiccc.f32','vbiclo.f32','vbicmi.f32','vbicpl.f32','vbicvs.f32','vbicvc.f32','vbichi.f32','vbicls.f32','vbicge.f32','vbiclt.f32','vbicgt.f32','vbicle.f32',
+ 'vbiceq.f64','vbicne.f64','vbiccs.f64','vbichs.f64','vbiccc.f64','vbiclo.f64','vbicmi.f64','vbicpl.f64','vbicvs.f64','vbicvc.f64','vbichi.f64','vbicls.f64','vbicge.f64','vbiclt.f64','vbicgt.f64','vbicle.f64',
+
+ 'vbifeq','vbifne','vbifcs','vbifhs','vbifcc','vbiflo','vbifmi','vbifpl','vbifvs','vbifvc','vbifhi','vbifls','vbifge','vbiflt','vbifgt','vbifle',
+ 'vbifeq.i8','vbifne.i8','vbifcs.i8','vbifhs.i8','vbifcc.i8','vbiflo.i8','vbifmi.i8','vbifpl.i8','vbifvs.i8','vbifvc.i8','vbifhi.i8','vbifls.i8','vbifge.i8','vbiflt.i8','vbifgt.i8','vbifle.i8',
+ 'vbifeq.i16','vbifne.i16','vbifcs.i16','vbifhs.i16','vbifcc.i16','vbiflo.i16','vbifmi.i16','vbifpl.i16','vbifvs.i16','vbifvc.i16','vbifhi.i16','vbifls.i16','vbifge.i16','vbiflt.i16','vbifgt.i16','vbifle.i16',
+ 'vbifeq.i32','vbifne.i32','vbifcs.i32','vbifhs.i32','vbifcc.i32','vbiflo.i32','vbifmi.i32','vbifpl.i32','vbifvs.i32','vbifvc.i32','vbifhi.i32','vbifls.i32','vbifge.i32','vbiflt.i32','vbifgt.i32','vbifle.i32',
+ 'vbifeq.i64','vbifne.i64','vbifcs.i64','vbifhs.i64','vbifcc.i64','vbiflo.i64','vbifmi.i64','vbifpl.i64','vbifvs.i64','vbifvc.i64','vbifhi.i64','vbifls.i64','vbifge.i64','vbiflt.i64','vbifgt.i64','vbifle.i64',
+ 'vbifeq.s8','vbifne.s8','vbifcs.s8','vbifhs.s8','vbifcc.s8','vbiflo.s8','vbifmi.s8','vbifpl.s8','vbifvs.s8','vbifvc.s8','vbifhi.s8','vbifls.s8','vbifge.s8','vbiflt.s8','vbifgt.s8','vbifle.s8',
+ 'vbifeq.s16','vbifne.s16','vbifcs.s16','vbifhs.s16','vbifcc.s16','vbiflo.s16','vbifmi.s16','vbifpl.s16','vbifvs.s16','vbifvc.s16','vbifhi.s16','vbifls.s16','vbifge.s16','vbiflt.s16','vbifgt.s16','vbifle.s16',
+ 'vbifeq.s32','vbifne.s32','vbifcs.s32','vbifhs.s32','vbifcc.s32','vbiflo.s32','vbifmi.s32','vbifpl.s32','vbifvs.s32','vbifvc.s32','vbifhi.s32','vbifls.s32','vbifge.s32','vbiflt.s32','vbifgt.s32','vbifle.s32',
+ 'vbifeq.s64','vbifne.s64','vbifcs.s64','vbifhs.s64','vbifcc.s64','vbiflo.s64','vbifmi.s64','vbifpl.s64','vbifvs.s64','vbifvc.s64','vbifhi.s64','vbifls.s64','vbifge.s64','vbiflt.s64','vbifgt.s64','vbifle.s64',
+ 'vbifeq.u8','vbifne.u8','vbifcs.u8','vbifhs.u8','vbifcc.u8','vbiflo.u8','vbifmi.u8','vbifpl.u8','vbifvs.u8','vbifvc.u8','vbifhi.u8','vbifls.u8','vbifge.u8','vbiflt.u8','vbifgt.u8','vbifle.u8',
+ 'vbifeq.u16','vbifne.u16','vbifcs.u16','vbifhs.u16','vbifcc.u16','vbiflo.u16','vbifmi.u16','vbifpl.u16','vbifvs.u16','vbifvc.u16','vbifhi.u16','vbifls.u16','vbifge.u16','vbiflt.u16','vbifgt.u16','vbifle.u16',
+ 'vbifeq.u32','vbifne.u32','vbifcs.u32','vbifhs.u32','vbifcc.u32','vbiflo.u32','vbifmi.u32','vbifpl.u32','vbifvs.u32','vbifvc.u32','vbifhi.u32','vbifls.u32','vbifge.u32','vbiflt.u32','vbifgt.u32','vbifle.u32',
+ 'vbifeq.u64','vbifne.u64','vbifcs.u64','vbifhs.u64','vbifcc.u64','vbiflo.u64','vbifmi.u64','vbifpl.u64','vbifvs.u64','vbifvc.u64','vbifhi.u64','vbifls.u64','vbifge.u64','vbiflt.u64','vbifgt.u64','vbifle.u64',
+ 'vbifeq.f32','vbifne.f32','vbifcs.f32','vbifhs.f32','vbifcc.f32','vbiflo.f32','vbifmi.f32','vbifpl.f32','vbifvs.f32','vbifvc.f32','vbifhi.f32','vbifls.f32','vbifge.f32','vbiflt.f32','vbifgt.f32','vbifle.f32',
+ 'vbifeq.f64','vbifne.f64','vbifcs.f64','vbifhs.f64','vbifcc.f64','vbiflo.f64','vbifmi.f64','vbifpl.f64','vbifvs.f64','vbifvc.f64','vbifhi.f64','vbifls.f64','vbifge.f64','vbiflt.f64','vbifgt.f64','vbifle.f64',
+
+ 'vbiteq','vbitne','vbitcs','vbiths','vbitcc','vbitlo','vbitmi','vbitpl','vbitvs','vbitvc','vbithi','vbitls','vbitge','vbitlt','vbitgt','vbitle',
+ 'vbiteq.i8','vbitne.i8','vbitcs.i8','vbiths.i8','vbitcc.i8','vbitlo.i8','vbitmi.i8','vbitpl.i8','vbitvs.i8','vbitvc.i8','vbithi.i8','vbitls.i8','vbitge.i8','vbitlt.i8','vbitgt.i8','vbitle.i8',
+ 'vbiteq.i16','vbitne.i16','vbitcs.i16','vbiths.i16','vbitcc.i16','vbitlo.i16','vbitmi.i16','vbitpl.i16','vbitvs.i16','vbitvc.i16','vbithi.i16','vbitls.i16','vbitge.i16','vbitlt.i16','vbitgt.i16','vbitle.i16',
+ 'vbiteq.i32','vbitne.i32','vbitcs.i32','vbiths.i32','vbitcc.i32','vbitlo.i32','vbitmi.i32','vbitpl.i32','vbitvs.i32','vbitvc.i32','vbithi.i32','vbitls.i32','vbitge.i32','vbitlt.i32','vbitgt.i32','vbitle.i32',
+ 'vbiteq.i64','vbitne.i64','vbitcs.i64','vbiths.i64','vbitcc.i64','vbitlo.i64','vbitmi.i64','vbitpl.i64','vbitvs.i64','vbitvc.i64','vbithi.i64','vbitls.i64','vbitge.i64','vbitlt.i64','vbitgt.i64','vbitle.i64',
+ 'vbiteq.s8','vbitne.s8','vbitcs.s8','vbiths.s8','vbitcc.s8','vbitlo.s8','vbitmi.s8','vbitpl.s8','vbitvs.s8','vbitvc.s8','vbithi.s8','vbitls.s8','vbitge.s8','vbitlt.s8','vbitgt.s8','vbitle.s8',
+ 'vbiteq.s16','vbitne.s16','vbitcs.s16','vbiths.s16','vbitcc.s16','vbitlo.s16','vbitmi.s16','vbitpl.s16','vbitvs.s16','vbitvc.s16','vbithi.s16','vbitls.s16','vbitge.s16','vbitlt.s16','vbitgt.s16','vbitle.s16',
+ 'vbiteq.s32','vbitne.s32','vbitcs.s32','vbiths.s32','vbitcc.s32','vbitlo.s32','vbitmi.s32','vbitpl.s32','vbitvs.s32','vbitvc.s32','vbithi.s32','vbitls.s32','vbitge.s32','vbitlt.s32','vbitgt.s32','vbitle.s32',
+ 'vbiteq.s64','vbitne.s64','vbitcs.s64','vbiths.s64','vbitcc.s64','vbitlo.s64','vbitmi.s64','vbitpl.s64','vbitvs.s64','vbitvc.s64','vbithi.s64','vbitls.s64','vbitge.s64','vbitlt.s64','vbitgt.s64','vbitle.s64',
+ 'vbiteq.u8','vbitne.u8','vbitcs.u8','vbiths.u8','vbitcc.u8','vbitlo.u8','vbitmi.u8','vbitpl.u8','vbitvs.u8','vbitvc.u8','vbithi.u8','vbitls.u8','vbitge.u8','vbitlt.u8','vbitgt.u8','vbitle.u8',
+ 'vbiteq.u16','vbitne.u16','vbitcs.u16','vbiths.u16','vbitcc.u16','vbitlo.u16','vbitmi.u16','vbitpl.u16','vbitvs.u16','vbitvc.u16','vbithi.u16','vbitls.u16','vbitge.u16','vbitlt.u16','vbitgt.u16','vbitle.u16',
+ 'vbiteq.u32','vbitne.u32','vbitcs.u32','vbiths.u32','vbitcc.u32','vbitlo.u32','vbitmi.u32','vbitpl.u32','vbitvs.u32','vbitvc.u32','vbithi.u32','vbitls.u32','vbitge.u32','vbitlt.u32','vbitgt.u32','vbitle.u32',
+ 'vbiteq.u64','vbitne.u64','vbitcs.u64','vbiths.u64','vbitcc.u64','vbitlo.u64','vbitmi.u64','vbitpl.u64','vbitvs.u64','vbitvc.u64','vbithi.u64','vbitls.u64','vbitge.u64','vbitlt.u64','vbitgt.u64','vbitle.u64',
+ 'vbiteq.f32','vbitne.f32','vbitcs.f32','vbiths.f32','vbitcc.f32','vbitlo.f32','vbitmi.f32','vbitpl.f32','vbitvs.f32','vbitvc.f32','vbithi.f32','vbitls.f32','vbitge.f32','vbitlt.f32','vbitgt.f32','vbitle.f32',
+ 'vbiteq.f64','vbitne.f64','vbitcs.f64','vbiths.f64','vbitcc.f64','vbitlo.f64','vbitmi.f64','vbitpl.f64','vbitvs.f64','vbitvc.f64','vbithi.f64','vbitls.f64','vbitge.f64','vbitlt.f64','vbitgt.f64','vbitle.f64',
+
+ 'vbsleq','vbslne','vbslcs','vbslhs','vbslcc','vbsllo','vbslmi','vbslpl','vbslvs','vbslvc','vbslhi','vbslls','vbslge','vbsllt','vbslgt','vbslle',
+ 'vbsleq.i8','vbslne.i8','vbslcs.i8','vbslhs.i8','vbslcc.i8','vbsllo.i8','vbslmi.i8','vbslpl.i8','vbslvs.i8','vbslvc.i8','vbslhi.i8','vbslls.i8','vbslge.i8','vbsllt.i8','vbslgt.i8','vbslle.i8',
+ 'vbsleq.i16','vbslne.i16','vbslcs.i16','vbslhs.i16','vbslcc.i16','vbsllo.i16','vbslmi.i16','vbslpl.i16','vbslvs.i16','vbslvc.i16','vbslhi.i16','vbslls.i16','vbslge.i16','vbsllt.i16','vbslgt.i16','vbslle.i16',
+ 'vbsleq.i32','vbslne.i32','vbslcs.i32','vbslhs.i32','vbslcc.i32','vbsllo.i32','vbslmi.i32','vbslpl.i32','vbslvs.i32','vbslvc.i32','vbslhi.i32','vbslls.i32','vbslge.i32','vbsllt.i32','vbslgt.i32','vbslle.i32',
+ 'vbsleq.i64','vbslne.i64','vbslcs.i64','vbslhs.i64','vbslcc.i64','vbsllo.i64','vbslmi.i64','vbslpl.i64','vbslvs.i64','vbslvc.i64','vbslhi.i64','vbslls.i64','vbslge.i64','vbsllt.i64','vbslgt.i64','vbslle.i64',
+ 'vbsleq.s8','vbslne.s8','vbslcs.s8','vbslhs.s8','vbslcc.s8','vbsllo.s8','vbslmi.s8','vbslpl.s8','vbslvs.s8','vbslvc.s8','vbslhi.s8','vbslls.s8','vbslge.s8','vbsllt.s8','vbslgt.s8','vbslle.s8',
+ 'vbsleq.s16','vbslne.s16','vbslcs.s16','vbslhs.s16','vbslcc.s16','vbsllo.s16','vbslmi.s16','vbslpl.s16','vbslvs.s16','vbslvc.s16','vbslhi.s16','vbslls.s16','vbslge.s16','vbsllt.s16','vbslgt.s16','vbslle.s16',
+ 'vbsleq.s32','vbslne.s32','vbslcs.s32','vbslhs.s32','vbslcc.s32','vbsllo.s32','vbslmi.s32','vbslpl.s32','vbslvs.s32','vbslvc.s32','vbslhi.s32','vbslls.s32','vbslge.s32','vbsllt.s32','vbslgt.s32','vbslle.s32',
+ 'vbsleq.s64','vbslne.s64','vbslcs.s64','vbslhs.s64','vbslcc.s64','vbsllo.s64','vbslmi.s64','vbslpl.s64','vbslvs.s64','vbslvc.s64','vbslhi.s64','vbslls.s64','vbslge.s64','vbsllt.s64','vbslgt.s64','vbslle.s64',
+ 'vbsleq.u8','vbslne.u8','vbslcs.u8','vbslhs.u8','vbslcc.u8','vbsllo.u8','vbslmi.u8','vbslpl.u8','vbslvs.u8','vbslvc.u8','vbslhi.u8','vbslls.u8','vbslge.u8','vbsllt.u8','vbslgt.u8','vbslle.u8',
+ 'vbsleq.u16','vbslne.u16','vbslcs.u16','vbslhs.u16','vbslcc.u16','vbsllo.u16','vbslmi.u16','vbslpl.u16','vbslvs.u16','vbslvc.u16','vbslhi.u16','vbslls.u16','vbslge.u16','vbsllt.u16','vbslgt.u16','vbslle.u16',
+ 'vbsleq.u32','vbslne.u32','vbslcs.u32','vbslhs.u32','vbslcc.u32','vbsllo.u32','vbslmi.u32','vbslpl.u32','vbslvs.u32','vbslvc.u32','vbslhi.u32','vbslls.u32','vbslge.u32','vbsllt.u32','vbslgt.u32','vbslle.u32',
+ 'vbsleq.u64','vbslne.u64','vbslcs.u64','vbslhs.u64','vbslcc.u64','vbsllo.u64','vbslmi.u64','vbslpl.u64','vbslvs.u64','vbslvc.u64','vbslhi.u64','vbslls.u64','vbslge.u64','vbsllt.u64','vbslgt.u64','vbslle.u64',
+ 'vbsleq.f32','vbslne.f32','vbslcs.f32','vbslhs.f32','vbslcc.f32','vbsllo.f32','vbslmi.f32','vbslpl.f32','vbslvs.f32','vbslvc.f32','vbslhi.f32','vbslls.f32','vbslge.f32','vbsllt.f32','vbslgt.f32','vbslle.f32',
+ 'vbsleq.f64','vbslne.f64','vbslcs.f64','vbslhs.f64','vbslcc.f64','vbsllo.f64','vbslmi.f64','vbslpl.f64','vbslvs.f64','vbslvc.f64','vbslhi.f64','vbslls.f64','vbslge.f64','vbsllt.f64','vbslgt.f64','vbslle.f64',
+
+ 'veoreq','veorne','veorcs','veorhs','veorcc','veorlo','veormi','veorpl','veorvs','veorvc','veorhi','veorls','veorge','veorlt','veorgt','veorle',
+ 'veoreq.i8','veorne.i8','veorcs.i8','veorhs.i8','veorcc.i8','veorlo.i8','veormi.i8','veorpl.i8','veorvs.i8','veorvc.i8','veorhi.i8','veorls.i8','veorge.i8','veorlt.i8','veorgt.i8','veorle.i8',
+ 'veoreq.i16','veorne.i16','veorcs.i16','veorhs.i16','veorcc.i16','veorlo.i16','veormi.i16','veorpl.i16','veorvs.i16','veorvc.i16','veorhi.i16','veorls.i16','veorge.i16','veorlt.i16','veorgt.i16','veorle.i16',
+ 'veoreq.i32','veorne.i32','veorcs.i32','veorhs.i32','veorcc.i32','veorlo.i32','veormi.i32','veorpl.i32','veorvs.i32','veorvc.i32','veorhi.i32','veorls.i32','veorge.i32','veorlt.i32','veorgt.i32','veorle.i32',
+ 'veoreq.i64','veorne.i64','veorcs.i64','veorhs.i64','veorcc.i64','veorlo.i64','veormi.i64','veorpl.i64','veorvs.i64','veorvc.i64','veorhi.i64','veorls.i64','veorge.i64','veorlt.i64','veorgt.i64','veorle.i64',
+ 'veoreq.s8','veorne.s8','veorcs.s8','veorhs.s8','veorcc.s8','veorlo.s8','veormi.s8','veorpl.s8','veorvs.s8','veorvc.s8','veorhi.s8','veorls.s8','veorge.s8','veorlt.s8','veorgt.s8','veorle.s8',
+ 'veoreq.s16','veorne.s16','veorcs.s16','veorhs.s16','veorcc.s16','veorlo.s16','veormi.s16','veorpl.s16','veorvs.s16','veorvc.s16','veorhi.s16','veorls.s16','veorge.s16','veorlt.s16','veorgt.s16','veorle.s16',
+ 'veoreq.s32','veorne.s32','veorcs.s32','veorhs.s32','veorcc.s32','veorlo.s32','veormi.s32','veorpl.s32','veorvs.s32','veorvc.s32','veorhi.s32','veorls.s32','veorge.s32','veorlt.s32','veorgt.s32','veorle.s32',
+ 'veoreq.s64','veorne.s64','veorcs.s64','veorhs.s64','veorcc.s64','veorlo.s64','veormi.s64','veorpl.s64','veorvs.s64','veorvc.s64','veorhi.s64','veorls.s64','veorge.s64','veorlt.s64','veorgt.s64','veorle.s64',
+ 'veoreq.u8','veorne.u8','veorcs.u8','veorhs.u8','veorcc.u8','veorlo.u8','veormi.u8','veorpl.u8','veorvs.u8','veorvc.u8','veorhi.u8','veorls.u8','veorge.u8','veorlt.u8','veorgt.u8','veorle.u8',
+ 'veoreq.u16','veorne.u16','veorcs.u16','veorhs.u16','veorcc.u16','veorlo.u16','veormi.u16','veorpl.u16','veorvs.u16','veorvc.u16','veorhi.u16','veorls.u16','veorge.u16','veorlt.u16','veorgt.u16','veorle.u16',
+ 'veoreq.u32','veorne.u32','veorcs.u32','veorhs.u32','veorcc.u32','veorlo.u32','veormi.u32','veorpl.u32','veorvs.u32','veorvc.u32','veorhi.u32','veorls.u32','veorge.u32','veorlt.u32','veorgt.u32','veorle.u32',
+ 'veoreq.u64','veorne.u64','veorcs.u64','veorhs.u64','veorcc.u64','veorlo.u64','veormi.u64','veorpl.u64','veorvs.u64','veorvc.u64','veorhi.u64','veorls.u64','veorge.u64','veorlt.u64','veorgt.u64','veorle.u64',
+ 'veoreq.f32','veorne.f32','veorcs.f32','veorhs.f32','veorcc.f32','veorlo.f32','veormi.f32','veorpl.f32','veorvs.f32','veorvc.f32','veorhi.f32','veorls.f32','veorge.f32','veorlt.f32','veorgt.f32','veorle.f32',
+ 'veoreq.f64','veorne.f64','veorcs.f64','veorhs.f64','veorcc.f64','veorlo.f64','veormi.f64','veorpl.f64','veorvs.f64','veorvc.f64','veorhi.f64','veorls.f64','veorge.f64','veorlt.f64','veorgt.f64','veorle.f64',
+
+ 'vmoveq','vmovne','vmovcs','vmovhs','vmovcc','vmovlo','vmovmi','vmovpl','vmovvs','vmovvc','vmovhi','vmovls','vmovge','vmovlt','vmovgt','vmovle',
+ 'vmoveq.8','vmovne.8','vmovcs.8','vmovhs.8','vmovcc.8','vmovlo.8','vmovmi.8','vmovpl.8','vmovvs.8','vmovvc.8','vmovhi.8','vmovls.8','vmovge.8','vmovlt.8','vmovgt.8','vmovle.8',
+ 'vmoveq.16','vmovne.16','vmovcs.16','vmovhs.16','vmovcc.16','vmovlo.16','vmovmi.16','vmovpl.16','vmovvs.16','vmovvc.16','vmovhi.16','vmovls.16','vmovge.16','vmovlt.16','vmovgt.16','vmovle.16',
+ 'vmoveq.32','vmovne.32','vmovcs.32','vmovhs.32','vmovcc.32','vmovlo.32','vmovmi.32','vmovpl.32','vmovvs.32','vmovvc.32','vmovhi.32','vmovls.32','vmovge.32','vmovlt.32','vmovgt.32','vmovle.32',
+ 'vmoveq.i8','vmovne.i8','vmovcs.i8','vmovhs.i8','vmovcc.i8','vmovlo.i8','vmovmi.i8','vmovpl.i8','vmovvs.i8','vmovvc.i8','vmovhi.i8','vmovls.i8','vmovge.i8','vmovlt.i8','vmovgt.i8','vmovle.i8',
+ 'vmoveq.i16','vmovne.i16','vmovcs.i16','vmovhs.i16','vmovcc.i16','vmovlo.i16','vmovmi.i16','vmovpl.i16','vmovvs.i16','vmovvc.i16','vmovhi.i16','vmovls.i16','vmovge.i16','vmovlt.i16','vmovgt.i16','vmovle.i16',
+ 'vmoveq.i32','vmovne.i32','vmovcs.i32','vmovhs.i32','vmovcc.i32','vmovlo.i32','vmovmi.i32','vmovpl.i32','vmovvs.i32','vmovvc.i32','vmovhi.i32','vmovls.i32','vmovge.i32','vmovlt.i32','vmovgt.i32','vmovle.i32',
+ 'vmoveq.i64','vmovne.i64','vmovcs.i64','vmovhs.i64','vmovcc.i64','vmovlo.i64','vmovmi.i64','vmovpl.i64','vmovvs.i64','vmovvc.i64','vmovhi.i64','vmovls.i64','vmovge.i64','vmovlt.i64','vmovgt.i64','vmovle.i64',
+ 'vmoveq.f32','vmovne.f32','vmovcs.f32','vmovhs.f32','vmovcc.f32','vmovlo.f32','vmovmi.f32','vmovpl.f32','vmovvs.f32','vmovvc.f32','vmovhi.f32','vmovls.f32','vmovge.f32','vmovlt.f32','vmovgt.f32','vmovle.f32',
+ 'vmoveq.f64','vmovne.f64','vmovcs.f64','vmovhs.f64','vmovcc.f64','vmovlo.f64','vmovmi.f64','vmovpl.f64','vmovvs.f64','vmovvc.f64','vmovhi.f64','vmovls.f64','vmovge.f64','vmovlt.f64','vmovgt.f64','vmovle.f64',
+
+ 'vmvneq','vmvnne','vmvncs','vmvnhs','vmvncc','vmvnlo','vmvnmi','vmvnpl','vmvnvs','vmvnvc','vmvnhi','vmvnls','vmvnge','vmvnlt','vmvngt','vmvnle',
+ 'vmvneq.s8','vmvnne.s8','vmvncs.s8','vmvnhs.s8','vmvncc.s8','vmvnlo.s8','vmvnmi.s8','vmvnpl.s8','vmvnvs.s8','vmvnvc.s8','vmvnhi.s8','vmvnls.s8','vmvnge.s8','vmvnlt.s8','vmvngt.s8','vmvnle.s8',
+ 'vmvneq.s16','vmvnne.s16','vmvncs.s16','vmvnhs.s16','vmvncc.s16','vmvnlo.s16','vmvnmi.s16','vmvnpl.s16','vmvnvs.s16','vmvnvc.s16','vmvnhi.s16','vmvnls.s16','vmvnge.s16','vmvnlt.s16','vmvngt.s16','vmvnle.s16',
+ 'vmvneq.s32','vmvnne.s32','vmvncs.s32','vmvnhs.s32','vmvncc.s32','vmvnlo.s32','vmvnmi.s32','vmvnpl.s32','vmvnvs.s32','vmvnvc.s32','vmvnhi.s32','vmvnls.s32','vmvnge.s32','vmvnlt.s32','vmvngt.s32','vmvnle.s32',
+ 'vmvneq.s64','vmvnne.s64','vmvncs.s64','vmvnhs.s64','vmvncc.s64','vmvnlo.s64','vmvnmi.s64','vmvnpl.s64','vmvnvs.s64','vmvnvc.s64','vmvnhi.s64','vmvnls.s64','vmvnge.s64','vmvnlt.s64','vmvngt.s64','vmvnle.s64',
+ 'vmvneq.u8','vmvnne.u8','vmvncs.u8','vmvnhs.u8','vmvncc.u8','vmvnlo.u8','vmvnmi.u8','vmvnpl.u8','vmvnvs.u8','vmvnvc.u8','vmvnhi.u8','vmvnls.u8','vmvnge.u8','vmvnlt.u8','vmvngt.u8','vmvnle.u8',
+ 'vmvneq.u16','vmvnne.u16','vmvncs.u16','vmvnhs.u16','vmvncc.u16','vmvnlo.u16','vmvnmi.u16','vmvnpl.u16','vmvnvs.u16','vmvnvc.u16','vmvnhi.u16','vmvnls.u16','vmvnge.u16','vmvnlt.u16','vmvngt.u16','vmvnle.u16',
+ 'vmvneq.u32','vmvnne.u32','vmvncs.u32','vmvnhs.u32','vmvncc.u32','vmvnlo.u32','vmvnmi.u32','vmvnpl.u32','vmvnvs.u32','vmvnvc.u32','vmvnhi.u32','vmvnls.u32','vmvnge.u32','vmvnlt.u32','vmvngt.u32','vmvnle.u32',
+ 'vmvneq.u64','vmvnne.u64','vmvncs.u64','vmvnhs.u64','vmvncc.u64','vmvnlo.u64','vmvnmi.u64','vmvnpl.u64','vmvnvs.u64','vmvnvc.u64','vmvnhi.u64','vmvnls.u64','vmvnge.u64','vmvnlt.u64','vmvngt.u64','vmvnle.u64',
+ 'vmvneq.i8','vmvnne.i8','vmvncs.i8','vmvnhs.i8','vmvncc.i8','vmvnlo.i8','vmvnmi.i8','vmvnpl.i8','vmvnvs.i8','vmvnvc.i8','vmvnhi.i8','vmvnls.i8','vmvnge.i8','vmvnlt.i8','vmvngt.i8','vmvnle.i8',
+ 'vmvneq.i16','vmvnne.i16','vmvncs.i16','vmvnhs.i16','vmvncc.i16','vmvnlo.i16','vmvnmi.i16','vmvnpl.i16','vmvnvs.i16','vmvnvc.i16','vmvnhi.i16','vmvnls.i16','vmvnge.i16','vmvnlt.i16','vmvngt.i16','vmvnle.i16',
+ 'vmvneq.i32','vmvnne.i32','vmvncs.i32','vmvnhs.i32','vmvncc.i32','vmvnlo.i32','vmvnmi.i32','vmvnpl.i32','vmvnvs.i32','vmvnvc.i32','vmvnhi.i32','vmvnls.i32','vmvnge.i32','vmvnlt.i32','vmvngt.i32','vmvnle.i32',
+ 'vmvneq.i64','vmvnne.i64','vmvncs.i64','vmvnhs.i64','vmvncc.i64','vmvnlo.i64','vmvnmi.i64','vmvnpl.i64','vmvnvs.i64','vmvnvc.i64','vmvnhi.i64','vmvnls.i64','vmvnge.i64','vmvnlt.i64','vmvngt.i64','vmvnle.i64',
+ 'vmvneq.f32','vmvnne.f32','vmvncs.f32','vmvnhs.f32','vmvncc.f32','vmvnlo.f32','vmvnmi.f32','vmvnpl.f32','vmvnvs.f32','vmvnvc.f32','vmvnhi.f32','vmvnls.f32','vmvnge.f32','vmvnlt.f32','vmvngt.f32','vmvnle.f32',
+ 'vmvneq.f64','vmvnne.f64','vmvncs.f64','vmvnhs.f64','vmvncc.f64','vmvnlo.f64','vmvnmi.f64','vmvnpl.f64','vmvnvs.f64','vmvnvc.f64','vmvnhi.f64','vmvnls.f64','vmvnge.f64','vmvnlt.f64','vmvngt.f64','vmvnle.f64',
+
+ 'vorneq','vornne','vorncs','vornhs','vorncc','vornlo','vornmi','vornpl','vornvs','vornvc','vornhi','vornls','vornge','vornlt','vorngt','vornle',
+ 'vorneq.s8','vornne.s8','vorncs.s8','vornhs.s8','vorncc.s8','vornlo.s8','vornmi.s8','vornpl.s8','vornvs.s8','vornvc.s8','vornhi.s8','vornls.s8','vornge.s8','vornlt.s8','vorngt.s8','vornle.s8',
+ 'vorneq.s16','vornne.s16','vorncs.s16','vornhs.s16','vorncc.s16','vornlo.s16','vornmi.s16','vornpl.s16','vornvs.s16','vornvc.s16','vornhi.s16','vornls.s16','vornge.s16','vornlt.s16','vorngt.s16','vornle.s16',
+ 'vorneq.s32','vornne.s32','vorncs.s32','vornhs.s32','vorncc.s32','vornlo.s32','vornmi.s32','vornpl.s32','vornvs.s32','vornvc.s32','vornhi.s32','vornls.s32','vornge.s32','vornlt.s32','vorngt.s32','vornle.s32',
+ 'vorneq.s64','vornne.s64','vorncs.s64','vornhs.s64','vorncc.s64','vornlo.s64','vornmi.s64','vornpl.s64','vornvs.s64','vornvc.s64','vornhi.s64','vornls.s64','vornge.s64','vornlt.s64','vorngt.s64','vornle.s64',
+ 'vorneq.u8','vornne.u8','vorncs.u8','vornhs.u8','vorncc.u8','vornlo.u8','vornmi.u8','vornpl.u8','vornvs.u8','vornvc.u8','vornhi.u8','vornls.u8','vornge.u8','vornlt.u8','vorngt.u8','vornle.u8',
+ 'vorneq.u16','vornne.u16','vorncs.u16','vornhs.u16','vorncc.u16','vornlo.u16','vornmi.u16','vornpl.u16','vornvs.u16','vornvc.u16','vornhi.u16','vornls.u16','vornge.u16','vornlt.u16','vorngt.u16','vornle.u16',
+ 'vorneq.u32','vornne.u32','vorncs.u32','vornhs.u32','vorncc.u32','vornlo.u32','vornmi.u32','vornpl.u32','vornvs.u32','vornvc.u32','vornhi.u32','vornls.u32','vornge.u32','vornlt.u32','vorngt.u32','vornle.u32',
+ 'vorneq.u64','vornne.u64','vorncs.u64','vornhs.u64','vorncc.u64','vornlo.u64','vornmi.u64','vornpl.u64','vornvs.u64','vornvc.u64','vornhi.u64','vornls.u64','vornge.u64','vornlt.u64','vorngt.u64','vornle.u64',
+ 'vorneq.i8','vornne.i8','vorncs.i8','vornhs.i8','vorncc.i8','vornlo.i8','vornmi.i8','vornpl.i8','vornvs.i8','vornvc.i8','vornhi.i8','vornls.i8','vornge.i8','vornlt.i8','vorngt.i8','vornle.i8',
+ 'vorneq.i16','vornne.i16','vorncs.i16','vornhs.i16','vorncc.i16','vornlo.i16','vornmi.i16','vornpl.i16','vornvs.i16','vornvc.i16','vornhi.i16','vornls.i16','vornge.i16','vornlt.i16','vorngt.i16','vornle.i16',
+ 'vorneq.i32','vornne.i32','vorncs.i32','vornhs.i32','vorncc.i32','vornlo.i32','vornmi.i32','vornpl.i32','vornvs.i32','vornvc.i32','vornhi.i32','vornls.i32','vornge.i32','vornlt.i32','vorngt.i32','vornle.i32',
+ 'vorneq.i64','vornne.i64','vorncs.i64','vornhs.i64','vorncc.i64','vornlo.i64','vornmi.i64','vornpl.i64','vornvs.i64','vornvc.i64','vornhi.i64','vornls.i64','vornge.i64','vornlt.i64','vorngt.i64','vornle.i64',
+ 'vorneq.f32','vornne.f32','vorncs.f32','vornhs.f32','vorncc.f32','vornlo.f32','vornmi.f32','vornpl.f32','vornvs.f32','vornvc.f32','vornhi.f32','vornls.f32','vornge.f32','vornlt.f32','vorngt.f32','vornle.f32',
+ 'vorneq.f64','vornne.f64','vorncs.f64','vornhs.f64','vorncc.f64','vornlo.f64','vornmi.f64','vornpl.f64','vornvs.f64','vornvc.f64','vornhi.f64','vornls.f64','vornge.f64','vornlt.f64','vorngt.f64','vornle.f64',
+
+ 'vorreq','vorrne','vorrcs','vorrhs','vorrcc','vorrlo','vorrmi','vorrpl','vorrvs','vorrvc','vorrhi','vorrls','vorrge','vorrlt','vorrgt','vorrle',
+ 'vorreq.s8','vorrne.s8','vorrcs.s8','vorrhs.s8','vorrcc.s8','vorrlo.s8','vorrmi.s8','vorrpl.s8','vorrvs.s8','vorrvc.s8','vorrhi.s8','vorrls.s8','vorrge.s8','vorrlt.s8','vorrgt.s8','vorrle.s8',
+ 'vorreq.s16','vorrne.s16','vorrcs.s16','vorrhs.s16','vorrcc.s16','vorrlo.s16','vorrmi.s16','vorrpl.s16','vorrvs.s16','vorrvc.s16','vorrhi.s16','vorrls.s16','vorrge.s16','vorrlt.s16','vorrgt.s16','vorrle.s16',
+ 'vorreq.s32','vorrne.s32','vorrcs.s32','vorrhs.s32','vorrcc.s32','vorrlo.s32','vorrmi.s32','vorrpl.s32','vorrvs.s32','vorrvc.s32','vorrhi.s32','vorrls.s32','vorrge.s32','vorrlt.s32','vorrgt.s32','vorrle.s32',
+ 'vorreq.s64','vorrne.s64','vorrcs.s64','vorrhs.s64','vorrcc.s64','vorrlo.s64','vorrmi.s64','vorrpl.s64','vorrvs.s64','vorrvc.s64','vorrhi.s64','vorrls.s64','vorrge.s64','vorrlt.s64','vorrgt.s64','vorrle.s64',
+ 'vorreq.u8','vorrne.u8','vorrcs.u8','vorrhs.u8','vorrcc.u8','vorrlo.u8','vorrmi.u8','vorrpl.u8','vorrvs.u8','vorrvc.u8','vorrhi.u8','vorrls.u8','vorrge.u8','vorrlt.u8','vorrgt.u8','vorrle.u8',
+ 'vorreq.u16','vorrne.u16','vorrcs.u16','vorrhs.u16','vorrcc.u16','vorrlo.u16','vorrmi.u16','vorrpl.u16','vorrvs.u16','vorrvc.u16','vorrhi.u16','vorrls.u16','vorrge.u16','vorrlt.u16','vorrgt.u16','vorrle.u16',
+ 'vorreq.u32','vorrne.u32','vorrcs.u32','vorrhs.u32','vorrcc.u32','vorrlo.u32','vorrmi.u32','vorrpl.u32','vorrvs.u32','vorrvc.u32','vorrhi.u32','vorrls.u32','vorrge.u32','vorrlt.u32','vorrgt.u32','vorrle.u32',
+ 'vorreq.u64','vorrne.u64','vorrcs.u64','vorrhs.u64','vorrcc.u64','vorrlo.u64','vorrmi.u64','vorrpl.u64','vorrvs.u64','vorrvc.u64','vorrhi.u64','vorrls.u64','vorrge.u64','vorrlt.u64','vorrgt.u64','vorrle.u64',
+ 'vorreq.i8','vorrne.i8','vorrcs.i8','vorrhs.i8','vorrcc.i8','vorrlo.i8','vorrmi.i8','vorrpl.i8','vorrvs.i8','vorrvc.i8','vorrhi.i8','vorrls.i8','vorrge.i8','vorrlt.i8','vorrgt.i8','vorrle.i8',
+ 'vorreq.i16','vorrne.i16','vorrcs.i16','vorrhs.i16','vorrcc.i16','vorrlo.i16','vorrmi.i16','vorrpl.i16','vorrvs.i16','vorrvc.i16','vorrhi.i16','vorrls.i16','vorrge.i16','vorrlt.i16','vorrgt.i16','vorrle.i16',
+ 'vorreq.i32','vorrne.i32','vorrcs.i32','vorrhs.i32','vorrcc.i32','vorrlo.i32','vorrmi.i32','vorrpl.i32','vorrvs.i32','vorrvc.i32','vorrhi.i32','vorrls.i32','vorrge.i32','vorrlt.i32','vorrgt.i32','vorrle.i32',
+ 'vorreq.i64','vorrne.i64','vorrcs.i64','vorrhs.i64','vorrcc.i64','vorrlo.i64','vorrmi.i64','vorrpl.i64','vorrvs.i64','vorrvc.i64','vorrhi.i64','vorrls.i64','vorrge.i64','vorrlt.i64','vorrgt.i64','vorrle.i64',
+ 'vorreq.f32','vorrne.f32','vorrcs.f32','vorrhs.f32','vorrcc.f32','vorrlo.f32','vorrmi.f32','vorrpl.f32','vorrvs.f32','vorrvc.f32','vorrhi.f32','vorrls.f32','vorrge.f32','vorrlt.f32','vorrgt.f32','vorrle.f32',
+ 'vorreq.f64','vorrne.f64','vorrcs.f64','vorrhs.f64','vorrcc.f64','vorrlo.f64','vorrmi.f64','vorrpl.f64','vorrvs.f64','vorrvc.f64','vorrhi.f64','vorrls.f64','vorrge.f64','vorrlt.f64','vorrgt.f64','vorrle.f64',
+
+ 'vswpeq','vswpne','vswpcs','vswphs','vswpcc','vswplo','vswpmi','vswppl','vswpvs','vswpvc','vswphi','vswpls','vswpge','vswplt','vswpgt','vswple',
+ 'vswpeq.s8','vswpne.s8','vswpcs.s8','vswphs.s8','vswpcc.s8','vswplo.s8','vswpmi.s8','vswppl.s8','vswpvs.s8','vswpvc.s8','vswphi.s8','vswpls.s8','vswpge.s8','vswplt.s8','vswpgt.s8','vswple.s8',
+ 'vswpeq.s16','vswpne.s16','vswpcs.s16','vswphs.s16','vswpcc.s16','vswplo.s16','vswpmi.s16','vswppl.s16','vswpvs.s16','vswpvc.s16','vswphi.s16','vswpls.s16','vswpge.s16','vswplt.s16','vswpgt.s16','vswple.s16',
+ 'vswpeq.s32','vswpne.s32','vswpcs.s32','vswphs.s32','vswpcc.s32','vswplo.s32','vswpmi.s32','vswppl.s32','vswpvs.s32','vswpvc.s32','vswphi.s32','vswpls.s32','vswpge.s32','vswplt.s32','vswpgt.s32','vswple.s32',
+ 'vswpeq.s64','vswpne.s64','vswpcs.s64','vswphs.s64','vswpcc.s64','vswplo.s64','vswpmi.s64','vswppl.s64','vswpvs.s64','vswpvc.s64','vswphi.s64','vswpls.s64','vswpge.s64','vswplt.s64','vswpgt.s64','vswple.s64',
+ 'vswpeq.u8','vswpne.u8','vswpcs.u8','vswphs.u8','vswpcc.u8','vswplo.u8','vswpmi.u8','vswppl.u8','vswpvs.u8','vswpvc.u8','vswphi.u8','vswpls.u8','vswpge.u8','vswplt.u8','vswpgt.u8','vswple.u8',
+ 'vswpeq.u16','vswpne.u16','vswpcs.u16','vswphs.u16','vswpcc.u16','vswplo.u16','vswpmi.u16','vswppl.u16','vswpvs.u16','vswpvc.u16','vswphi.u16','vswpls.u16','vswpge.u16','vswplt.u16','vswpgt.u16','vswple.u16',
+ 'vswpeq.u32','vswpne.u32','vswpcs.u32','vswphs.u32','vswpcc.u32','vswplo.u32','vswpmi.u32','vswppl.u32','vswpvs.u32','vswpvc.u32','vswphi.u32','vswpls.u32','vswpge.u32','vswplt.u32','vswpgt.u32','vswple.u32',
+ 'vswpeq.u64','vswpne.u64','vswpcs.u64','vswphs.u64','vswpcc.u64','vswplo.u64','vswpmi.u64','vswppl.u64','vswpvs.u64','vswpvc.u64','vswphi.u64','vswpls.u64','vswpge.u64','vswplt.u64','vswpgt.u64','vswple.u64',
+ 'vswpeq.i8','vswpne.i8','vswpcs.i8','vswphs.i8','vswpcc.i8','vswplo.i8','vswpmi.i8','vswppl.i8','vswpvs.i8','vswpvc.i8','vswphi.i8','vswpls.i8','vswpge.i8','vswplt.i8','vswpgt.i8','vswple.i8',
+ 'vswpeq.i16','vswpne.i16','vswpcs.i16','vswphs.i16','vswpcc.i16','vswplo.i16','vswpmi.i16','vswppl.i16','vswpvs.i16','vswpvc.i16','vswphi.i16','vswpls.i16','vswpge.i16','vswplt.i16','vswpgt.i16','vswple.i16',
+ 'vswpeq.i32','vswpne.i32','vswpcs.i32','vswphs.i32','vswpcc.i32','vswplo.i32','vswpmi.i32','vswppl.i32','vswpvs.i32','vswpvc.i32','vswphi.i32','vswpls.i32','vswpge.i32','vswplt.i32','vswpgt.i32','vswple.i32',
+ 'vswpeq.i64','vswpne.i64','vswpcs.i64','vswphs.i64','vswpcc.i64','vswplo.i64','vswpmi.i64','vswppl.i64','vswpvs.i64','vswpvc.i64','vswphi.i64','vswpls.i64','vswpge.i64','vswplt.i64','vswpgt.i64','vswple.i64',
+ 'vswpeq.f32','vswpne.f32','vswpcs.f32','vswphs.f32','vswpcc.f32','vswplo.f32','vswpmi.f32','vswppl.f32','vswpvs.f32','vswpvc.f32','vswphi.f32','vswpls.f32','vswpge.f32','vswplt.f32','vswpgt.f32','vswple.f32',
+ 'vswpeq.f64','vswpne.f64','vswpcs.f64','vswphs.f64','vswpcc.f64','vswplo.f64','vswpmi.f64','vswppl.f64','vswpvs.f64','vswpvc.f64','vswphi.f64','vswpls.f64','vswpge.f64','vswplt.f64','vswpgt.f64','vswple.f64'
+ ),
+ /* Conditional NEON SIMD ARM Registers Interop Instructions */
+ 29 => array(
+ 'vmrseq','vmrsne','vmrscs','vmrshs','vmrscc','vmrslo','vmrsmi','vmrspl','vmrsvs','vmrsvc','vmrshi','vmrsls','vmrsge','vmrslt','vmrsgt','vmrsle',
+ 'vmsreq','vmsrne','vmsrcs','vmsrhs','vmsrcc','vmsrlo','vmsrmi','vmsrpl','vmsrvs','vmsrvc','vmsrhi','vmsrls','vmsrge','vmsrlt','vmsrgt','vmsrle'
+ ),
+ /* Conditional NEON SIMD Bit/Byte-Level Instructions */
+ 30 => array(
+ 'vcnteq.8','vcntne.8','vcntcs.8','vcnths.8','vcntcc.8','vcntlo.8','vcntmi.8','vcntpl.8','vcntvs.8','vcntvc.8','vcnthi.8','vcntls.8','vcntge.8','vcntlt.8','vcntgt.8','vcntle.8',
+ 'vdupeq.8','vdupne.8','vdupcs.8','vduphs.8','vdupcc.8','vduplo.8','vdupmi.8','vduppl.8','vdupvs.8','vdupvc.8','vduphi.8','vdupls.8','vdupge.8','vduplt.8','vdupgt.8','vduple.8',
+
+ 'vdupeq.16','vdupne.16','vdupcs.16','vduphs.16','vdupcc.16','vduplo.16','vdupmi.16','vduppl.16','vdupvs.16','vdupvc.16','vduphi.16','vdupls.16','vdupge.16','vduplt.16','vdupgt.16','vduple.16',
+ 'vdupeq.32','vdupne.32','vdupcs.32','vduphs.32','vdupcc.32','vduplo.32','vdupmi.32','vduppl.32','vdupvs.32','vdupvc.32','vduphi.32','vdupls.32','vdupge.32','vduplt.32','vdupgt.32','vduple.32',
+
+ 'vexteq.8','vextne.8','vextcs.8','vexths.8','vextcc.8','vextlo.8','vextmi.8','vextpl.8','vextvs.8','vextvc.8','vexthi.8','vextls.8','vextge.8','vextlt.8','vextgt.8','vextle.8',
+ 'vexteq.16','vextne.16','vextcs.16','vexths.16','vextcc.16','vextlo.16','vextmi.16','vextpl.16','vextvs.16','vextvc.16','vexthi.16','vextls.16','vextge.16','vextlt.16','vextgt.16','vextle.16',
+
+ 'vexteq.32','vextne.32','vextcs.32','vexths.32','vextcc.32','vextlo.32','vextmi.32','vextpl.32','vextvs.32','vextvc.32','vexthi.32','vextls.32','vextge.32','vextlt.32','vextgt.32','vextle.32',
+ 'vexteq.64','vextne.64','vextcs.64','vexths.64','vextcc.64','vextlo.64','vextmi.64','vextpl.64','vextvs.64','vextvc.64','vexthi.64','vextls.64','vextge.64','vextlt.64','vextgt.64','vextle.64',
+
+ 'vrev16eq.8','vrev16ne.8','vrev16cs.8','vrev16hs.8','vrev16cc.8','vrev16lo.8','vrev16mi.8','vrev16pl.8','vrev16vs.8','vrev16vc.8','vrev16hi.8','vrev16ls.8','vrev16ge.8','vrev16lt.8','vrev16gt.8','vrev16le.8',
+ 'vrev32eq.8','vrev32ne.8','vrev32cs.8','vrev32hs.8','vrev32cc.8','vrev32lo.8','vrev32mi.8','vrev32pl.8','vrev32vs.8','vrev32vc.8','vrev32hi.8','vrev32ls.8','vrev32ge.8','vrev32lt.8','vrev32gt.8','vrev32le.8',
+ 'vrev32eq.16','vrev32ne.16','vrev32cs.16','vrev32hs.16','vrev32cc.16','vrev32lo.16','vrev32mi.16','vrev32pl.16','vrev32vs.16','vrev32vc.16','vrev32hi.16','vrev32ls.16','vrev32ge.16','vrev32lt.16','vrev32gt.16','vrev32le.16',
+ 'vrev64eq.8','vrev64ne.8','vrev64cs.8','vrev64hs.8','vrev64cc.8','vrev64lo.8','vrev64mi.8','vrev64pl.8','vrev64vs.8','vrev64vc.8','vrev64hi.8','vrev64ls.8','vrev64ge.8','vrev64lt.8','vrev64gt.8','vrev64le.8',
+ 'vrev64eq.16','vrev64ne.16','vrev64cs.16','vrev64hs.16','vrev64cc.16','vrev64lo.16','vrev64mi.16','vrev64pl.16','vrev64vs.16','vrev64vc.16','vrev64hi.16','vrev64ls.16','vrev64ge.16','vrev64lt.16','vrev64gt.16','vrev64le.16',
+ 'vrev64eq.32','vrev64ne.32','vrev64cs.32','vrev64hs.32','vrev64cc.32','vrev64lo.32','vrev64mi.32','vrev64pl.32','vrev64vs.32','vrev64vc.32','vrev64hi.32','vrev64ls.32','vrev64ge.32','vrev64lt.32','vrev64gt.32','vrev64le.32',
+
+ 'vslieq.8','vsline.8','vslics.8','vslihs.8','vslicc.8','vslilo.8','vslimi.8','vslipl.8','vslivs.8','vslivc.8','vslihi.8','vslils.8','vslige.8','vslilt.8','vsligt.8','vslile.8',
+ 'vslieq.16','vsline.16','vslics.16','vslihs.16','vslicc.16','vslilo.16','vslimi.16','vslipl.16','vslivs.16','vslivc.16','vslihi.16','vslils.16','vslige.16','vslilt.16','vsligt.16','vslile.16',
+ 'vslieq.32','vsline.32','vslics.32','vslihs.32','vslicc.32','vslilo.32','vslimi.32','vslipl.32','vslivs.32','vslivc.32','vslihi.32','vslils.32','vslige.32','vslilt.32','vsligt.32','vslile.32',
+ 'vslieq.64','vsline.64','vslics.64','vslihs.64','vslicc.64','vslilo.64','vslimi.64','vslipl.64','vslivs.64','vslivc.64','vslihi.64','vslils.64','vslige.64','vslilt.64','vsligt.64','vslile.64',
+
+ 'vsrieq.8','vsrine.8','vsrics.8','vsrihs.8','vsricc.8','vsrilo.8','vsrimi.8','vsripl.8','vsrivs.8','vsrivc.8','vsrihi.8','vsrils.8','vsrige.8','vsrilt.8','vsrigt.8','vsrile.8',
+ 'vsrieq.16','vsrine.16','vsrics.16','vsrihs.16','vsricc.16','vsrilo.16','vsrimi.16','vsripl.16','vsrivs.16','vsrivc.16','vsrihi.16','vsrils.16','vsrige.16','vsrilt.16','vsrigt.16','vsrile.16',
+ 'vsrieq.32','vsrine.32','vsrics.32','vsrihs.32','vsricc.32','vsrilo.32','vsrimi.32','vsripl.32','vsrivs.32','vsrivc.32','vsrihi.32','vsrils.32','vsrige.32','vsrilt.32','vsrigt.32','vsrile.32',
+ 'vsrieq.64','vsrine.64','vsrics.64','vsrihs.64','vsricc.64','vsrilo.64','vsrimi.64','vsripl.64','vsrivs.64','vsrivc.64','vsrihi.64','vsrils.64','vsrige.64','vsrilt.64','vsrigt.64','vsrile.64',
+
+ 'vtbleq.8','vtblne.8','vtblcs.8','vtblhs.8','vtblcc.8','vtbllo.8','vtblmi.8','vtblpl.8','vtblvs.8','vtblvc.8','vtblhi.8','vtblls.8','vtblge.8','vtbllt.8','vtblgt.8','vtblle.8',
+
+ 'vtbxeq','vtbxne','vtbxcs','vtbxhs','vtbxcc','vtbxlo','vtbxmi','vtbxpl','vtbxvs','vtbxvc','vtbxhi','vtbxls','vtbxge','vtbxlt','vtbxgt','vtbxle',
+
+ 'vtrneq.8','vtrnne.8','vtrncs.8','vtrnhs.8','vtrncc.8','vtrnlo.8','vtrnmi.8','vtrnpl.8','vtrnvs.8','vtrnvc.8','vtrnhi.8','vtrnls.8','vtrnge.8','vtrnlt.8','vtrngt.8','vtrnle.8',
+ 'vtrneq.16','vtrnne.16','vtrncs.16','vtrnhs.16','vtrncc.16','vtrnlo.16','vtrnmi.16','vtrnpl.16','vtrnvs.16','vtrnvc.16','vtrnhi.16','vtrnls.16','vtrnge.16','vtrnlt.16','vtrngt.16','vtrnle.16',
+ 'vtrneq.32','vtrnne.32','vtrncs.32','vtrnhs.32','vtrncc.32','vtrnlo.32','vtrnmi.32','vtrnpl.32','vtrnvs.32','vtrnvc.32','vtrnhi.32','vtrnls.32','vtrnge.32','vtrnlt.32','vtrngt.32','vtrnle.32',
+
+ 'vtsteq.8','vtstne.8','vtstcs.8','vtsths.8','vtstcc.8','vtstlo.8','vtstmi.8','vtstpl.8','vtstvs.8','vtstvc.8','vtsthi.8','vtstls.8','vtstge.8','vtstlt.8','vtstgt.8','vtstle.8',
+ 'vtsteq.16','vtstne.16','vtstcs.16','vtsths.16','vtstcc.16','vtstlo.16','vtstmi.16','vtstpl.16','vtstvs.16','vtstvc.16','vtsthi.16','vtstls.16','vtstge.16','vtstlt.16','vtstgt.16','vtstle.16',
+ 'vtsteq.32','vtstne.32','vtstcs.32','vtsths.32','vtstcc.32','vtstlo.32','vtstmi.32','vtstpl.32','vtstvs.32','vtstvc.32','vtsthi.32','vtstls.32','vtstge.32','vtstlt.32','vtstgt.32','vtstle.32',
+
+ 'vuzpeq.8','vuzpne.8','vuzpcs.8','vuzphs.8','vuzpcc.8','vuzplo.8','vuzpmi.8','vuzppl.8','vuzpvs.8','vuzpvc.8','vuzphi.8','vuzpls.8','vuzpge.8','vuzplt.8','vuzpgt.8','vuzple.8',
+ 'vuzpeq.16','vuzpne.16','vuzpcs.16','vuzphs.16','vuzpcc.16','vuzplo.16','vuzpmi.16','vuzppl.16','vuzpvs.16','vuzpvc.16','vuzphi.16','vuzpls.16','vuzpge.16','vuzplt.16','vuzpgt.16','vuzple.16',
+ 'vuzpeq.32','vuzpne.32','vuzpcs.32','vuzphs.32','vuzpcc.32','vuzplo.32','vuzpmi.32','vuzppl.32','vuzpvs.32','vuzpvc.32','vuzphi.32','vuzpls.32','vuzpge.32','vuzplt.32','vuzpgt.32','vuzple.32',
+
+ 'vzipeq.8','vzipne.8','vzipcs.8','vziphs.8','vzipcc.8','vziplo.8','vzipmi.8','vzippl.8','vzipvs.8','vzipvc.8','vziphi.8','vzipls.8','vzipge.8','vziplt.8','vzipgt.8','vziple.8',
+ 'vzipeq.16','vzipne.16','vzipcs.16','vziphs.16','vzipcc.16','vziplo.16','vzipmi.16','vzippl.16','vzipvs.16','vzipvc.16','vziphi.16','vzipls.16','vzipge.16','vziplt.16','vzipgt.16','vziple.16',
+ 'vzipeq.32','vzipne.32','vzipcs.32','vziphs.32','vzipcc.32','vziplo.32','vzipmi.32','vzippl.32','vzipvs.32','vzipvc.32','vziphi.32','vzipls.32','vzipge.32','vziplt.32','vzipgt.32','vziple.32',
+
+ 'vmulleq.p8','vmullne.p8','vmullcs.p8','vmullhs.p8','vmullcc.p8','vmulllo.p8','vmullmi.p8','vmullpl.p8','vmullvs.p8','vmullvc.p8','vmullhi.p8','vmullls.p8','vmullge.p8','vmulllt.p8','vmullgt.p8','vmullle.p8'
+ ),
+ /* Conditional NEON SIMD Universal Integer Instructions */
+ 31 => array(
+ 'vaddeq.i8','vaddne.i8','vaddcs.i8','vaddhs.i8','vaddcc.i8','vaddlo.i8','vaddmi.i8','vaddpl.i8','vaddvs.i8','vaddvc.i8','vaddhi.i8','vaddls.i8','vaddge.i8','vaddlt.i8','vaddgt.i8','vaddle.i8',
+ 'vaddeq.i16','vaddne.i16','vaddcs.i16','vaddhs.i16','vaddcc.i16','vaddlo.i16','vaddmi.i16','vaddpl.i16','vaddvs.i16','vaddvc.i16','vaddhi.i16','vaddls.i16','vaddge.i16','vaddlt.i16','vaddgt.i16','vaddle.i16',
+ 'vaddeq.i32','vaddne.i32','vaddcs.i32','vaddhs.i32','vaddcc.i32','vaddlo.i32','vaddmi.i32','vaddpl.i32','vaddvs.i32','vaddvc.i32','vaddhi.i32','vaddls.i32','vaddge.i32','vaddlt.i32','vaddgt.i32','vaddle.i32',
+ 'vaddeq.i64','vaddne.i64','vaddcs.i64','vaddhs.i64','vaddcc.i64','vaddlo.i64','vaddmi.i64','vaddpl.i64','vaddvs.i64','vaddvc.i64','vaddhi.i64','vaddls.i64','vaddge.i64','vaddlt.i64','vaddgt.i64','vaddle.i64',
+
+ 'vsubeq.i8','vsubne.i8','vsubcs.i8','vsubhs.i8','vsubcc.i8','vsublo.i8','vsubmi.i8','vsubpl.i8','vsubvs.i8','vsubvc.i8','vsubhi.i8','vsubls.i8','vsubge.i8','vsublt.i8','vsubgt.i8','vsuble.i8',
+ 'vsubeq.i16','vsubne.i16','vsubcs.i16','vsubhs.i16','vsubcc.i16','vsublo.i16','vsubmi.i16','vsubpl.i16','vsubvs.i16','vsubvc.i16','vsubhi.i16','vsubls.i16','vsubge.i16','vsublt.i16','vsubgt.i16','vsuble.i16',
+ 'vsubeq.i32','vsubne.i32','vsubcs.i32','vsubhs.i32','vsubcc.i32','vsublo.i32','vsubmi.i32','vsubpl.i32','vsubvs.i32','vsubvc.i32','vsubhi.i32','vsubls.i32','vsubge.i32','vsublt.i32','vsubgt.i32','vsuble.i32',
+ 'vsubeq.i64','vsubne.i64','vsubcs.i64','vsubhs.i64','vsubcc.i64','vsublo.i64','vsubmi.i64','vsubpl.i64','vsubvs.i64','vsubvc.i64','vsubhi.i64','vsubls.i64','vsubge.i64','vsublt.i64','vsubgt.i64','vsuble.i64',
+
+ 'vaddhneq.i16','vaddhnne.i16','vaddhncs.i16','vaddhnhs.i16','vaddhncc.i16','vaddhnlo.i16','vaddhnmi.i16','vaddhnpl.i16','vaddhnvs.i16','vaddhnvc.i16','vaddhnhi.i16','vaddhnls.i16','vaddhnge.i16','vaddhnlt.i16','vaddhngt.i16','vaddhnle.i16',
+ 'vaddhneq.i32','vaddhnne.i32','vaddhncs.i32','vaddhnhs.i32','vaddhncc.i32','vaddhnlo.i32','vaddhnmi.i32','vaddhnpl.i32','vaddhnvs.i32','vaddhnvc.i32','vaddhnhi.i32','vaddhnls.i32','vaddhnge.i32','vaddhnlt.i32','vaddhngt.i32','vaddhnle.i32',
+ 'vaddhneq.i64','vaddhnne.i64','vaddhncs.i64','vaddhnhs.i64','vaddhncc.i64','vaddhnlo.i64','vaddhnmi.i64','vaddhnpl.i64','vaddhnvs.i64','vaddhnvc.i64','vaddhnhi.i64','vaddhnls.i64','vaddhnge.i64','vaddhnlt.i64','vaddhngt.i64','vaddhnle.i64',
+
+ 'vsubhneq.i16','vsubhnne.i16','vsubhncs.i16','vsubhnhs.i16','vsubhncc.i16','vsubhnlo.i16','vsubhnmi.i16','vsubhnpl.i16','vsubhnvs.i16','vsubhnvc.i16','vsubhnhi.i16','vsubhnls.i16','vsubhnge.i16','vsubhnlt.i16','vsubhngt.i16','vsubhnle.i16',
+ 'vsubhneq.i32','vsubhnne.i32','vsubhncs.i32','vsubhnhs.i32','vsubhncc.i32','vsubhnlo.i32','vsubhnmi.i32','vsubhnpl.i32','vsubhnvs.i32','vsubhnvc.i32','vsubhnhi.i32','vsubhnls.i32','vsubhnge.i32','vsubhnlt.i32','vsubhngt.i32','vsubhnle.i32',
+ 'vsubhneq.i64','vsubhnne.i64','vsubhncs.i64','vsubhnhs.i64','vsubhncc.i64','vsubhnlo.i64','vsubhnmi.i64','vsubhnpl.i64','vsubhnvs.i64','vsubhnvc.i64','vsubhnhi.i64','vsubhnls.i64','vsubhnge.i64','vsubhnlt.i64','vsubhngt.i64','vsubhnle.i64',
+
+ 'vraddhneq.i16','vraddhnne.i16','vraddhncs.i16','vraddhnhs.i16','vraddhncc.i16','vraddhnlo.i16','vraddhnmi.i16','vraddhnpl.i16','vraddhnvs.i16','vraddhnvc.i16','vraddhnhi.i16','vraddhnls.i16','vraddhnge.i16','vraddhnlt.i16','vraddhngt.i16','vraddhnle.i16',
+ 'vraddhneq.i32','vraddhnne.i32','vraddhncs.i32','vraddhnhs.i32','vraddhncc.i32','vraddhnlo.i32','vraddhnmi.i32','vraddhnpl.i32','vraddhnvs.i32','vraddhnvc.i32','vraddhnhi.i32','vraddhnls.i32','vraddhnge.i32','vraddhnlt.i32','vraddhngt.i32','vraddhnle.i32',
+ 'vraddhneq.i64','vraddhnne.i64','vraddhncs.i64','vraddhnhs.i64','vraddhncc.i64','vraddhnlo.i64','vraddhnmi.i64','vraddhnpl.i64','vraddhnvs.i64','vraddhnvc.i64','vraddhnhi.i64','vraddhnls.i64','vraddhnge.i64','vraddhnlt.i64','vraddhngt.i64','vraddhnle.i64',
+
+ 'vrsubhneq.i16','vrsubhnne.i16','vrsubhncs.i16','vrsubhnhs.i16','vrsubhncc.i16','vrsubhnlo.i16','vrsubhnmi.i16','vrsubhnpl.i16','vrsubhnvs.i16','vrsubhnvc.i16','vrsubhnhi.i16','vrsubhnls.i16','vrsubhnge.i16','vrsubhnlt.i16','vrsubhngt.i16','vrsubhnle.i16',
+ 'vrsubhneq.i32','vrsubhnne.i32','vrsubhncs.i32','vrsubhnhs.i32','vrsubhncc.i32','vrsubhnlo.i32','vrsubhnmi.i32','vrsubhnpl.i32','vrsubhnvs.i32','vrsubhnvc.i32','vrsubhnhi.i32','vrsubhnls.i32','vrsubhnge.i32','vrsubhnlt.i32','vrsubhngt.i32','vrsubhnle.i32',
+ 'vrsubhneq.i64','vrsubhnne.i64','vrsubhncs.i64','vrsubhnhs.i64','vrsubhncc.i64','vrsubhnlo.i64','vrsubhnmi.i64','vrsubhnpl.i64','vrsubhnvs.i64','vrsubhnvc.i64','vrsubhnhi.i64','vrsubhnls.i64','vrsubhnge.i64','vrsubhnlt.i64','vrsubhngt.i64','vrsubhnle.i64',
+
+ 'vpaddeq.i8','vpaddne.i8','vpaddcs.i8','vpaddhs.i8','vpaddcc.i8','vpaddlo.i8','vpaddmi.i8','vpaddpl.i8','vpaddvs.i8','vpaddvc.i8','vpaddhi.i8','vpaddls.i8','vpaddge.i8','vpaddlt.i8','vpaddgt.i8','vpaddle.i8',
+ 'vpaddeq.i16','vpaddne.i16','vpaddcs.i16','vpaddhs.i16','vpaddcc.i16','vpaddlo.i16','vpaddmi.i16','vpaddpl.i16','vpaddvs.i16','vpaddvc.i16','vpaddhi.i16','vpaddls.i16','vpaddge.i16','vpaddlt.i16','vpaddgt.i16','vpaddle.i16',
+ 'vpaddeq.i32','vpaddne.i32','vpaddcs.i32','vpaddhs.i32','vpaddcc.i32','vpaddlo.i32','vpaddmi.i32','vpaddpl.i32','vpaddvs.i32','vpaddvc.i32','vpaddhi.i32','vpaddls.i32','vpaddge.i32','vpaddlt.i32','vpaddgt.i32','vpaddle.i32',
+
+ 'vceqeq.i8','vceqne.i8','vceqcs.i8','vceqhs.i8','vceqcc.i8','vceqlo.i8','vceqmi.i8','vceqpl.i8','vceqvs.i8','vceqvc.i8','vceqhi.i8','vceqls.i8','vceqge.i8','vceqlt.i8','vceqgt.i8','vceqle.i8',
+ 'vceqeq.i16','vceqne.i16','vceqcs.i16','vceqhs.i16','vceqcc.i16','vceqlo.i16','vceqmi.i16','vceqpl.i16','vceqvs.i16','vceqvc.i16','vceqhi.i16','vceqls.i16','vceqge.i16','vceqlt.i16','vceqgt.i16','vceqle.i16',
+ 'vceqeq.i32','vceqne.i32','vceqcs.i32','vceqhs.i32','vceqcc.i32','vceqlo.i32','vceqmi.i32','vceqpl.i32','vceqvs.i32','vceqvc.i32','vceqhi.i32','vceqls.i32','vceqge.i32','vceqlt.i32','vceqgt.i32','vceqle.i32',
+
+ 'vclzeq.i8','vclzne.i8','vclzcs.i8','vclzhs.i8','vclzcc.i8','vclzlo.i8','vclzmi.i8','vclzpl.i8','vclzvs.i8','vclzvc.i8','vclzhi.i8','vclzls.i8','vclzge.i8','vclzlt.i8','vclzgt.i8','vclzle.i8',
+ 'vclzeq.i16','vclzne.i16','vclzcs.i16','vclzhs.i16','vclzcc.i16','vclzlo.i16','vclzmi.i16','vclzpl.i16','vclzvs.i16','vclzvc.i16','vclzhi.i16','vclzls.i16','vclzge.i16','vclzlt.i16','vclzgt.i16','vclzle.i16',
+ 'vclzeq.i32','vclzne.i32','vclzcs.i32','vclzhs.i32','vclzcc.i32','vclzlo.i32','vclzmi.i32','vclzpl.i32','vclzvs.i32','vclzvc.i32','vclzhi.i32','vclzls.i32','vclzge.i32','vclzlt.i32','vclzgt.i32','vclzle.i32',
+
+ 'vmovneq.i16','vmovnne.i16','vmovncs.i16','vmovnhs.i16','vmovncc.i16','vmovnlo.i16','vmovnmi.i16','vmovnpl.i16','vmovnvs.i16','vmovnvc.i16','vmovnhi.i16','vmovnls.i16','vmovnge.i16','vmovnlt.i16','vmovngt.i16','vmovnle.i16',
+ 'vmovneq.i32','vmovnne.i32','vmovncs.i32','vmovnhs.i32','vmovncc.i32','vmovnlo.i32','vmovnmi.i32','vmovnpl.i32','vmovnvs.i32','vmovnvc.i32','vmovnhi.i32','vmovnls.i32','vmovnge.i32','vmovnlt.i32','vmovngt.i32','vmovnle.i32',
+ 'vmovneq.i64','vmovnne.i64','vmovncs.i64','vmovnhs.i64','vmovncc.i64','vmovnlo.i64','vmovnmi.i64','vmovnpl.i64','vmovnvs.i64','vmovnvc.i64','vmovnhi.i64','vmovnls.i64','vmovnge.i64','vmovnlt.i64','vmovngt.i64','vmovnle.i64',
+
+ 'vmlaeq.s8','vmlane.s8','vmlacs.s8','vmlahs.s8','vmlacc.s8','vmlalo.s8','vmlami.s8','vmlapl.s8','vmlavs.s8','vmlavc.s8','vmlahi.s8','vmlals.s8','vmlage.s8','vmlalt.s8','vmlagt.s8','vmlale.s8',
+ 'vmlaeq.s16','vmlane.s16','vmlacs.s16','vmlahs.s16','vmlacc.s16','vmlalo.s16','vmlami.s16','vmlapl.s16','vmlavs.s16','vmlavc.s16','vmlahi.s16','vmlals.s16','vmlage.s16','vmlalt.s16','vmlagt.s16','vmlale.s16',
+ 'vmlaeq.s32','vmlane.s32','vmlacs.s32','vmlahs.s32','vmlacc.s32','vmlalo.s32','vmlami.s32','vmlapl.s32','vmlavs.s32','vmlavc.s32','vmlahi.s32','vmlals.s32','vmlage.s32','vmlalt.s32','vmlagt.s32','vmlale.s32',
+ 'vmlaeq.u8','vmlane.u8','vmlacs.u8','vmlahs.u8','vmlacc.u8','vmlalo.u8','vmlami.u8','vmlapl.u8','vmlavs.u8','vmlavc.u8','vmlahi.u8','vmlals.u8','vmlage.u8','vmlalt.u8','vmlagt.u8','vmlale.u8',
+ 'vmlaeq.u16','vmlane.u16','vmlacs.u16','vmlahs.u16','vmlacc.u16','vmlalo.u16','vmlami.u16','vmlapl.u16','vmlavs.u16','vmlavc.u16','vmlahi.u16','vmlals.u16','vmlage.u16','vmlalt.u16','vmlagt.u16','vmlale.u16',
+ 'vmlaeq.u32','vmlane.u32','vmlacs.u32','vmlahs.u32','vmlacc.u32','vmlalo.u32','vmlami.u32','vmlapl.u32','vmlavs.u32','vmlavc.u32','vmlahi.u32','vmlals.u32','vmlage.u32','vmlalt.u32','vmlagt.u32','vmlale.u32',
+ 'vmlaeq.i8','vmlane.i8','vmlacs.i8','vmlahs.i8','vmlacc.i8','vmlalo.i8','vmlami.i8','vmlapl.i8','vmlavs.i8','vmlavc.i8','vmlahi.i8','vmlals.i8','vmlage.i8','vmlalt.i8','vmlagt.i8','vmlale.i8',
+ 'vmlaeq.i16','vmlane.i16','vmlacs.i16','vmlahs.i16','vmlacc.i16','vmlalo.i16','vmlami.i16','vmlapl.i16','vmlavs.i16','vmlavc.i16','vmlahi.i16','vmlals.i16','vmlage.i16','vmlalt.i16','vmlagt.i16','vmlale.i16',
+ 'vmlaeq.i32','vmlane.i32','vmlacs.i32','vmlahs.i32','vmlacc.i32','vmlalo.i32','vmlami.i32','vmlapl.i32','vmlavs.i32','vmlavc.i32','vmlahi.i32','vmlals.i32','vmlage.i32','vmlalt.i32','vmlagt.i32','vmlale.i32',
+
+ 'vmlseq.s8','vmlsne.s8','vmlscs.s8','vmlshs.s8','vmlscc.s8','vmlslo.s8','vmlsmi.s8','vmlspl.s8','vmlsvs.s8','vmlsvc.s8','vmlshi.s8','vmlsls.s8','vmlsge.s8','vmlslt.s8','vmlsgt.s8','vmlsle.s8',
+ 'vmlseq.s16','vmlsne.s16','vmlscs.s16','vmlshs.s16','vmlscc.s16','vmlslo.s16','vmlsmi.s16','vmlspl.s16','vmlsvs.s16','vmlsvc.s16','vmlshi.s16','vmlsls.s16','vmlsge.s16','vmlslt.s16','vmlsgt.s16','vmlsle.s16',
+ 'vmlseq.s32','vmlsne.s32','vmlscs.s32','vmlshs.s32','vmlscc.s32','vmlslo.s32','vmlsmi.s32','vmlspl.s32','vmlsvs.s32','vmlsvc.s32','vmlshi.s32','vmlsls.s32','vmlsge.s32','vmlslt.s32','vmlsgt.s32','vmlsle.s32',
+ 'vmlseq.u8','vmlsne.u8','vmlscs.u8','vmlshs.u8','vmlscc.u8','vmlslo.u8','vmlsmi.u8','vmlspl.u8','vmlsvs.u8','vmlsvc.u8','vmlshi.u8','vmlsls.u8','vmlsge.u8','vmlslt.u8','vmlsgt.u8','vmlsle.u8',
+ 'vmlseq.u16','vmlsne.u16','vmlscs.u16','vmlshs.u16','vmlscc.u16','vmlslo.u16','vmlsmi.u16','vmlspl.u16','vmlsvs.u16','vmlsvc.u16','vmlshi.u16','vmlsls.u16','vmlsge.u16','vmlslt.u16','vmlsgt.u16','vmlsle.u16',
+ 'vmlseq.u32','vmlsne.u32','vmlscs.u32','vmlshs.u32','vmlscc.u32','vmlslo.u32','vmlsmi.u32','vmlspl.u32','vmlsvs.u32','vmlsvc.u32','vmlshi.u32','vmlsls.u32','vmlsge.u32','vmlslt.u32','vmlsgt.u32','vmlsle.u32',
+ 'vmlseq.i8','vmlsne.i8','vmlscs.i8','vmlshs.i8','vmlscc.i8','vmlslo.i8','vmlsmi.i8','vmlspl.i8','vmlsvs.i8','vmlsvc.i8','vmlshi.i8','vmlsls.i8','vmlsge.i8','vmlslt.i8','vmlsgt.i8','vmlsle.i8',
+ 'vmlseq.i16','vmlsne.i16','vmlscs.i16','vmlshs.i16','vmlscc.i16','vmlslo.i16','vmlsmi.i16','vmlspl.i16','vmlsvs.i16','vmlsvc.i16','vmlshi.i16','vmlsls.i16','vmlsge.i16','vmlslt.i16','vmlsgt.i16','vmlsle.i16',
+ 'vmlseq.i32','vmlsne.i32','vmlscs.i32','vmlshs.i32','vmlscc.i32','vmlslo.i32','vmlsmi.i32','vmlspl.i32','vmlsvs.i32','vmlsvc.i32','vmlshi.i32','vmlsls.i32','vmlsge.i32','vmlslt.i32','vmlsgt.i32','vmlsle.i32',
+
+ 'vmuleq.s8','vmulne.s8','vmulcs.s8','vmulhs.s8','vmulcc.s8','vmullo.s8','vmulmi.s8','vmulpl.s8','vmulvs.s8','vmulvc.s8','vmulhi.s8','vmulls.s8','vmulge.s8','vmullt.s8','vmulgt.s8','vmulle.s8',
+ 'vmuleq.s16','vmulne.s16','vmulcs.s16','vmulhs.s16','vmulcc.s16','vmullo.s16','vmulmi.s16','vmulpl.s16','vmulvs.s16','vmulvc.s16','vmulhi.s16','vmulls.s16','vmulge.s16','vmullt.s16','vmulgt.s16','vmulle.s16',
+ 'vmuleq.s32','vmulne.s32','vmulcs.s32','vmulhs.s32','vmulcc.s32','vmullo.s32','vmulmi.s32','vmulpl.s32','vmulvs.s32','vmulvc.s32','vmulhi.s32','vmulls.s32','vmulge.s32','vmullt.s32','vmulgt.s32','vmulle.s32',
+ 'vmuleq.u8','vmulne.u8','vmulcs.u8','vmulhs.u8','vmulcc.u8','vmullo.u8','vmulmi.u8','vmulpl.u8','vmulvs.u8','vmulvc.u8','vmulhi.u8','vmulls.u8','vmulge.u8','vmullt.u8','vmulgt.u8','vmulle.u8',
+ 'vmuleq.u16','vmulne.u16','vmulcs.u16','vmulhs.u16','vmulcc.u16','vmullo.u16','vmulmi.u16','vmulpl.u16','vmulvs.u16','vmulvc.u16','vmulhi.u16','vmulls.u16','vmulge.u16','vmullt.u16','vmulgt.u16','vmulle.u16',
+ 'vmuleq.u32','vmulne.u32','vmulcs.u32','vmulhs.u32','vmulcc.u32','vmullo.u32','vmulmi.u32','vmulpl.u32','vmulvs.u32','vmulvc.u32','vmulhi.u32','vmulls.u32','vmulge.u32','vmullt.u32','vmulgt.u32','vmulle.u32',
+ 'vmuleq.i8','vmulne.i8','vmulcs.i8','vmulhs.i8','vmulcc.i8','vmullo.i8','vmulmi.i8','vmulpl.i8','vmulvs.i8','vmulvc.i8','vmulhi.i8','vmulls.i8','vmulge.i8','vmullt.i8','vmulgt.i8','vmulle.i8',
+ 'vmuleq.i16','vmulne.i16','vmulcs.i16','vmulhs.i16','vmulcc.i16','vmullo.i16','vmulmi.i16','vmulpl.i16','vmulvs.i16','vmulvc.i16','vmulhi.i16','vmulls.i16','vmulge.i16','vmullt.i16','vmulgt.i16','vmulle.i16',
+ 'vmuleq.i32','vmulne.i32','vmulcs.i32','vmulhs.i32','vmulcc.i32','vmullo.i32','vmulmi.i32','vmulpl.i32','vmulvs.i32','vmulvc.i32','vmulhi.i32','vmulls.i32','vmulge.i32','vmullt.i32','vmulgt.i32','vmulle.i32',
+ 'vmuleq.p8','vmulne.p8','vmulcs.p8','vmulhs.p8','vmulcc.p8','vmullo.p8','vmulmi.p8','vmulpl.p8','vmulvs.p8','vmulvc.p8','vmulhi.p8','vmulls.p8','vmulge.p8','vmullt.p8','vmulgt.p8','vmulle.p8',
+
+ 'vrshrneq.i16','vrshrnne.i16','vrshrncs.i16','vrshrnhs.i16','vrshrncc.i16','vrshrnlo.i16','vrshrnmi.i16','vrshrnpl.i16','vrshrnvs.i16','vrshrnvc.i16','vrshrnhi.i16','vrshrnls.i16','vrshrnge.i16','vrshrnlt.i16','vrshrngt.i16','vrshrnle.i16',
+ 'vrshrneq.i32','vrshrnne.i32','vrshrncs.i32','vrshrnhs.i32','vrshrncc.i32','vrshrnlo.i32','vrshrnmi.i32','vrshrnpl.i32','vrshrnvs.i32','vrshrnvc.i32','vrshrnhi.i32','vrshrnls.i32','vrshrnge.i32','vrshrnlt.i32','vrshrngt.i32','vrshrnle.i32',
+ 'vrshrneq.i64','vrshrnne.i64','vrshrncs.i64','vrshrnhs.i64','vrshrncc.i64','vrshrnlo.i64','vrshrnmi.i64','vrshrnpl.i64','vrshrnvs.i64','vrshrnvc.i64','vrshrnhi.i64','vrshrnls.i64','vrshrnge.i64','vrshrnlt.i64','vrshrngt.i64','vrshrnle.i64',
+
+ 'vshrneq.i16','vshrnne.i16','vshrncs.i16','vshrnhs.i16','vshrncc.i16','vshrnlo.i16','vshrnmi.i16','vshrnpl.i16','vshrnvs.i16','vshrnvc.i16','vshrnhi.i16','vshrnls.i16','vshrnge.i16','vshrnlt.i16','vshrngt.i16','vshrnle.i16',
+ 'vshrneq.i32','vshrnne.i32','vshrncs.i32','vshrnhs.i32','vshrncc.i32','vshrnlo.i32','vshrnmi.i32','vshrnpl.i32','vshrnvs.i32','vshrnvc.i32','vshrnhi.i32','vshrnls.i32','vshrnge.i32','vshrnlt.i32','vshrngt.i32','vshrnle.i32',
+ 'vshrneq.i64','vshrnne.i64','vshrncs.i64','vshrnhs.i64','vshrncc.i64','vshrnlo.i64','vshrnmi.i64','vshrnpl.i64','vshrnvs.i64','vshrnvc.i64','vshrnhi.i64','vshrnls.i64','vshrnge.i64','vshrnlt.i64','vshrngt.i64','vshrnle.i64',
+
+ 'vshleq.i8','vshlne.i8','vshlcs.i8','vshlhs.i8','vshlcc.i8','vshllo.i8','vshlmi.i8','vshlpl.i8','vshlvs.i8','vshlvc.i8','vshlhi.i8','vshlls.i8','vshlge.i8','vshllt.i8','vshlgt.i8','vshlle.i8',
+ 'vshleq.i16','vshlne.i16','vshlcs.i16','vshlhs.i16','vshlcc.i16','vshllo.i16','vshlmi.i16','vshlpl.i16','vshlvs.i16','vshlvc.i16','vshlhi.i16','vshlls.i16','vshlge.i16','vshllt.i16','vshlgt.i16','vshlle.i16',
+ 'vshleq.i32','vshlne.i32','vshlcs.i32','vshlhs.i32','vshlcc.i32','vshllo.i32','vshlmi.i32','vshlpl.i32','vshlvs.i32','vshlvc.i32','vshlhi.i32','vshlls.i32','vshlge.i32','vshllt.i32','vshlgt.i32','vshlle.i32',
+ 'vshleq.i64','vshlne.i64','vshlcs.i64','vshlhs.i64','vshlcc.i64','vshllo.i64','vshlmi.i64','vshlpl.i64','vshlvs.i64','vshlvc.i64','vshlhi.i64','vshlls.i64','vshlge.i64','vshllt.i64','vshlgt.i64','vshlle.i64',
+
+ 'vshlleq.i8','vshllne.i8','vshllcs.i8','vshllhs.i8','vshllcc.i8','vshlllo.i8','vshllmi.i8','vshllpl.i8','vshllvs.i8','vshllvc.i8','vshllhi.i8','vshllls.i8','vshllge.i8','vshlllt.i8','vshllgt.i8','vshllle.i8',
+ 'vshlleq.i16','vshllne.i16','vshllcs.i16','vshllhs.i16','vshllcc.i16','vshlllo.i16','vshllmi.i16','vshllpl.i16','vshllvs.i16','vshllvc.i16','vshllhi.i16','vshllls.i16','vshllge.i16','vshlllt.i16','vshllgt.i16','vshllle.i16',
+ 'vshlleq.i32','vshllne.i32','vshllcs.i32','vshllhs.i32','vshllcc.i32','vshlllo.i32','vshllmi.i32','vshllpl.i32','vshllvs.i32','vshllvc.i32','vshllhi.i32','vshllls.i32','vshllge.i32','vshlllt.i32','vshllgt.i32','vshllle.i32'
+ ),
+ /* Conditional NEON SIMD Signed Integer Instructions */
+ 32 => array(
+ 'vabaeq.s8','vabane.s8','vabacs.s8','vabahs.s8','vabacc.s8','vabalo.s8','vabami.s8','vabapl.s8','vabavs.s8','vabavc.s8','vabahi.s8','vabals.s8','vabage.s8','vabalt.s8','vabagt.s8','vabale.s8',
+ 'vabaeq.s16','vabane.s16','vabacs.s16','vabahs.s16','vabacc.s16','vabalo.s16','vabami.s16','vabapl.s16','vabavs.s16','vabavc.s16','vabahi.s16','vabals.s16','vabage.s16','vabalt.s16','vabagt.s16','vabale.s16',
+ 'vabaeq.s32','vabane.s32','vabacs.s32','vabahs.s32','vabacc.s32','vabalo.s32','vabami.s32','vabapl.s32','vabavs.s32','vabavc.s32','vabahi.s32','vabals.s32','vabage.s32','vabalt.s32','vabagt.s32','vabale.s32',
+
+ 'vabaleq.s8','vabalne.s8','vabalcs.s8','vabalhs.s8','vabalcc.s8','vaballo.s8','vabalmi.s8','vabalpl.s8','vabalvs.s8','vabalvc.s8','vabalhi.s8','vaballs.s8','vabalge.s8','vaballt.s8','vabalgt.s8','vaballe.s8',
+ 'vabaleq.s16','vabalne.s16','vabalcs.s16','vabalhs.s16','vabalcc.s16','vaballo.s16','vabalmi.s16','vabalpl.s16','vabalvs.s16','vabalvc.s16','vabalhi.s16','vaballs.s16','vabalge.s16','vaballt.s16','vabalgt.s16','vaballe.s16',
+ 'vabaleq.s32','vabalne.s32','vabalcs.s32','vabalhs.s32','vabalcc.s32','vaballo.s32','vabalmi.s32','vabalpl.s32','vabalvs.s32','vabalvc.s32','vabalhi.s32','vaballs.s32','vabalge.s32','vaballt.s32','vabalgt.s32','vaballe.s32',
+
+ 'vabdeq.s8','vabdne.s8','vabdcs.s8','vabdhs.s8','vabdcc.s8','vabdlo.s8','vabdmi.s8','vabdpl.s8','vabdvs.s8','vabdvc.s8','vabdhi.s8','vabdls.s8','vabdge.s8','vabdlt.s8','vabdgt.s8','vabdle.s8',
+ 'vabdeq.s16','vabdne.s16','vabdcs.s16','vabdhs.s16','vabdcc.s16','vabdlo.s16','vabdmi.s16','vabdpl.s16','vabdvs.s16','vabdvc.s16','vabdhi.s16','vabdls.s16','vabdge.s16','vabdlt.s16','vabdgt.s16','vabdle.s16',
+ 'vabdeq.s32','vabdne.s32','vabdcs.s32','vabdhs.s32','vabdcc.s32','vabdlo.s32','vabdmi.s32','vabdpl.s32','vabdvs.s32','vabdvc.s32','vabdhi.s32','vabdls.s32','vabdge.s32','vabdlt.s32','vabdgt.s32','vabdle.s32',
+
+ 'vabseq.s8','vabsne.s8','vabscs.s8','vabshs.s8','vabscc.s8','vabslo.s8','vabsmi.s8','vabspl.s8','vabsvs.s8','vabsvc.s8','vabshi.s8','vabsls.s8','vabsge.s8','vabslt.s8','vabsgt.s8','vabsle.s8',
+ 'vabseq.s16','vabsne.s16','vabscs.s16','vabshs.s16','vabscc.s16','vabslo.s16','vabsmi.s16','vabspl.s16','vabsvs.s16','vabsvc.s16','vabshi.s16','vabsls.s16','vabsge.s16','vabslt.s16','vabsgt.s16','vabsle.s16',
+ 'vabseq.s32','vabsne.s32','vabscs.s32','vabshs.s32','vabscc.s32','vabslo.s32','vabsmi.s32','vabspl.s32','vabsvs.s32','vabsvc.s32','vabshi.s32','vabsls.s32','vabsge.s32','vabslt.s32','vabsgt.s32','vabsle.s32',
+
+ 'vaddleq.s8','vaddlne.s8','vaddlcs.s8','vaddlhs.s8','vaddlcc.s8','vaddllo.s8','vaddlmi.s8','vaddlpl.s8','vaddlvs.s8','vaddlvc.s8','vaddlhi.s8','vaddlls.s8','vaddlge.s8','vaddllt.s8','vaddlgt.s8','vaddlle.s8',
+ 'vaddleq.s16','vaddlne.s16','vaddlcs.s16','vaddlhs.s16','vaddlcc.s16','vaddllo.s16','vaddlmi.s16','vaddlpl.s16','vaddlvs.s16','vaddlvc.s16','vaddlhi.s16','vaddlls.s16','vaddlge.s16','vaddllt.s16','vaddlgt.s16','vaddlle.s16',
+ 'vaddleq.s32','vaddlne.s32','vaddlcs.s32','vaddlhs.s32','vaddlcc.s32','vaddllo.s32','vaddlmi.s32','vaddlpl.s32','vaddlvs.s32','vaddlvc.s32','vaddlhi.s32','vaddlls.s32','vaddlge.s32','vaddllt.s32','vaddlgt.s32','vaddlle.s32',
+
+ 'vcgeeq.s8','vcgene.s8','vcgecs.s8','vcgehs.s8','vcgecc.s8','vcgelo.s8','vcgemi.s8','vcgepl.s8','vcgevs.s8','vcgevc.s8','vcgehi.s8','vcgels.s8','vcgege.s8','vcgelt.s8','vcgegt.s8','vcgele.s8',
+ 'vcgeeq.s16','vcgene.s16','vcgecs.s16','vcgehs.s16','vcgecc.s16','vcgelo.s16','vcgemi.s16','vcgepl.s16','vcgevs.s16','vcgevc.s16','vcgehi.s16','vcgels.s16','vcgege.s16','vcgelt.s16','vcgegt.s16','vcgele.s16',
+ 'vcgeeq.s32','vcgene.s32','vcgecs.s32','vcgehs.s32','vcgecc.s32','vcgelo.s32','vcgemi.s32','vcgepl.s32','vcgevs.s32','vcgevc.s32','vcgehi.s32','vcgels.s32','vcgege.s32','vcgelt.s32','vcgegt.s32','vcgele.s32',
+
+ 'vcleeq.s8','vclene.s8','vclecs.s8','vclehs.s8','vclecc.s8','vclelo.s8','vclemi.s8','vclepl.s8','vclevs.s8','vclevc.s8','vclehi.s8','vclels.s8','vclege.s8','vclelt.s8','vclegt.s8','vclele.s8',
+ 'vcleeq.s16','vclene.s16','vclecs.s16','vclehs.s16','vclecc.s16','vclelo.s16','vclemi.s16','vclepl.s16','vclevs.s16','vclevc.s16','vclehi.s16','vclels.s16','vclege.s16','vclelt.s16','vclegt.s16','vclele.s16',
+ 'vcleeq.s32','vclene.s32','vclecs.s32','vclehs.s32','vclecc.s32','vclelo.s32','vclemi.s32','vclepl.s32','vclevs.s32','vclevc.s32','vclehi.s32','vclels.s32','vclege.s32','vclelt.s32','vclegt.s32','vclele.s32',
+
+ 'vcgteq.s8','vcgtne.s8','vcgtcs.s8','vcgths.s8','vcgtcc.s8','vcgtlo.s8','vcgtmi.s8','vcgtpl.s8','vcgtvs.s8','vcgtvc.s8','vcgthi.s8','vcgtls.s8','vcgtge.s8','vcgtlt.s8','vcgtgt.s8','vcgtle.s8',
+ 'vcgteq.s16','vcgtne.s16','vcgtcs.s16','vcgths.s16','vcgtcc.s16','vcgtlo.s16','vcgtmi.s16','vcgtpl.s16','vcgtvs.s16','vcgtvc.s16','vcgthi.s16','vcgtls.s16','vcgtge.s16','vcgtlt.s16','vcgtgt.s16','vcgtle.s16',
+ 'vcgteq.s32','vcgtne.s32','vcgtcs.s32','vcgths.s32','vcgtcc.s32','vcgtlo.s32','vcgtmi.s32','vcgtpl.s32','vcgtvs.s32','vcgtvc.s32','vcgthi.s32','vcgtls.s32','vcgtge.s32','vcgtlt.s32','vcgtgt.s32','vcgtle.s32',
+
+ 'vclteq.s8','vcltne.s8','vcltcs.s8','vclths.s8','vcltcc.s8','vcltlo.s8','vcltmi.s8','vcltpl.s8','vcltvs.s8','vcltvc.s8','vclthi.s8','vcltls.s8','vcltge.s8','vcltlt.s8','vcltgt.s8','vcltle.s8',
+ 'vclteq.s16','vcltne.s16','vcltcs.s16','vclths.s16','vcltcc.s16','vcltlo.s16','vcltmi.s16','vcltpl.s16','vcltvs.s16','vcltvc.s16','vclthi.s16','vcltls.s16','vcltge.s16','vcltlt.s16','vcltgt.s16','vcltle.s16',
+ 'vclteq.s32','vcltne.s32','vcltcs.s32','vclths.s32','vcltcc.s32','vcltlo.s32','vcltmi.s32','vcltpl.s32','vcltvs.s32','vcltvc.s32','vclthi.s32','vcltls.s32','vcltge.s32','vcltlt.s32','vcltgt.s32','vcltle.s32',
+
+ 'vclseq.s8','vclsne.s8','vclscs.s8','vclshs.s8','vclscc.s8','vclslo.s8','vclsmi.s8','vclspl.s8','vclsvs.s8','vclsvc.s8','vclshi.s8','vclsls.s8','vclsge.s8','vclslt.s8','vclsgt.s8','vclsle.s8',
+ 'vclseq.s16','vclsne.s16','vclscs.s16','vclshs.s16','vclscc.s16','vclslo.s16','vclsmi.s16','vclspl.s16','vclsvs.s16','vclsvc.s16','vclshi.s16','vclsls.s16','vclsge.s16','vclslt.s16','vclsgt.s16','vclsle.s16',
+ 'vclseq.s32','vclsne.s32','vclscs.s32','vclshs.s32','vclscc.s32','vclslo.s32','vclsmi.s32','vclspl.s32','vclsvs.s32','vclsvc.s32','vclshi.s32','vclsls.s32','vclsge.s32','vclslt.s32','vclsgt.s32','vclsle.s32',
+
+ 'vaddweq.s8','vaddwne.s8','vaddwcs.s8','vaddwhs.s8','vaddwcc.s8','vaddwlo.s8','vaddwmi.s8','vaddwpl.s8','vaddwvs.s8','vaddwvc.s8','vaddwhi.s8','vaddwls.s8','vaddwge.s8','vaddwlt.s8','vaddwgt.s8','vaddwle.s8',
+ 'vaddweq.s16','vaddwne.s16','vaddwcs.s16','vaddwhs.s16','vaddwcc.s16','vaddwlo.s16','vaddwmi.s16','vaddwpl.s16','vaddwvs.s16','vaddwvc.s16','vaddwhi.s16','vaddwls.s16','vaddwge.s16','vaddwlt.s16','vaddwgt.s16','vaddwle.s16',
+ 'vaddweq.s32','vaddwne.s32','vaddwcs.s32','vaddwhs.s32','vaddwcc.s32','vaddwlo.s32','vaddwmi.s32','vaddwpl.s32','vaddwvs.s32','vaddwvc.s32','vaddwhi.s32','vaddwls.s32','vaddwge.s32','vaddwlt.s32','vaddwgt.s32','vaddwle.s32',
+
+ 'vhaddeq.s8','vhaddne.s8','vhaddcs.s8','vhaddhs.s8','vhaddcc.s8','vhaddlo.s8','vhaddmi.s8','vhaddpl.s8','vhaddvs.s8','vhaddvc.s8','vhaddhi.s8','vhaddls.s8','vhaddge.s8','vhaddlt.s8','vhaddgt.s8','vhaddle.s8',
+ 'vhaddeq.s16','vhaddne.s16','vhaddcs.s16','vhaddhs.s16','vhaddcc.s16','vhaddlo.s16','vhaddmi.s16','vhaddpl.s16','vhaddvs.s16','vhaddvc.s16','vhaddhi.s16','vhaddls.s16','vhaddge.s16','vhaddlt.s16','vhaddgt.s16','vhaddle.s16',
+ 'vhaddeq.s32','vhaddne.s32','vhaddcs.s32','vhaddhs.s32','vhaddcc.s32','vhaddlo.s32','vhaddmi.s32','vhaddpl.s32','vhaddvs.s32','vhaddvc.s32','vhaddhi.s32','vhaddls.s32','vhaddge.s32','vhaddlt.s32','vhaddgt.s32','vhaddle.s32',
+
+ 'vhsubeq.s8','vhsubne.s8','vhsubcs.s8','vhsubhs.s8','vhsubcc.s8','vhsublo.s8','vhsubmi.s8','vhsubpl.s8','vhsubvs.s8','vhsubvc.s8','vhsubhi.s8','vhsubls.s8','vhsubge.s8','vhsublt.s8','vhsubgt.s8','vhsuble.s8',
+ 'vhsubeq.s16','vhsubne.s16','vhsubcs.s16','vhsubhs.s16','vhsubcc.s16','vhsublo.s16','vhsubmi.s16','vhsubpl.s16','vhsubvs.s16','vhsubvc.s16','vhsubhi.s16','vhsubls.s16','vhsubge.s16','vhsublt.s16','vhsubgt.s16','vhsuble.s16',
+ 'vhsubeq.s32','vhsubne.s32','vhsubcs.s32','vhsubhs.s32','vhsubcc.s32','vhsublo.s32','vhsubmi.s32','vhsubpl.s32','vhsubvs.s32','vhsubvc.s32','vhsubhi.s32','vhsubls.s32','vhsubge.s32','vhsublt.s32','vhsubgt.s32','vhsuble.s32',
+
+ 'vmaxeq.s8','vmaxne.s8','vmaxcs.s8','vmaxhs.s8','vmaxcc.s8','vmaxlo.s8','vmaxmi.s8','vmaxpl.s8','vmaxvs.s8','vmaxvc.s8','vmaxhi.s8','vmaxls.s8','vmaxge.s8','vmaxlt.s8','vmaxgt.s8','vmaxle.s8',
+ 'vmaxeq.s16','vmaxne.s16','vmaxcs.s16','vmaxhs.s16','vmaxcc.s16','vmaxlo.s16','vmaxmi.s16','vmaxpl.s16','vmaxvs.s16','vmaxvc.s16','vmaxhi.s16','vmaxls.s16','vmaxge.s16','vmaxlt.s16','vmaxgt.s16','vmaxle.s16',
+ 'vmaxeq.s32','vmaxne.s32','vmaxcs.s32','vmaxhs.s32','vmaxcc.s32','vmaxlo.s32','vmaxmi.s32','vmaxpl.s32','vmaxvs.s32','vmaxvc.s32','vmaxhi.s32','vmaxls.s32','vmaxge.s32','vmaxlt.s32','vmaxgt.s32','vmaxle.s32',
+
+ 'vmineq.s8','vminne.s8','vmincs.s8','vminhs.s8','vmincc.s8','vminlo.s8','vminmi.s8','vminpl.s8','vminvs.s8','vminvc.s8','vminhi.s8','vminls.s8','vminge.s8','vminlt.s8','vmingt.s8','vminle.s8',
+ 'vmineq.s16','vminne.s16','vmincs.s16','vminhs.s16','vmincc.s16','vminlo.s16','vminmi.s16','vminpl.s16','vminvs.s16','vminvc.s16','vminhi.s16','vminls.s16','vminge.s16','vminlt.s16','vmingt.s16','vminle.s16',
+ 'vmineq.s32','vminne.s32','vmincs.s32','vminhs.s32','vmincc.s32','vminlo.s32','vminmi.s32','vminpl.s32','vminvs.s32','vminvc.s32','vminhi.s32','vminls.s32','vminge.s32','vminlt.s32','vmingt.s32','vminle.s32',
+
+ 'vmlaleq.s8','vmlalne.s8','vmlalcs.s8','vmlalhs.s8','vmlalcc.s8','vmlallo.s8','vmlalmi.s8','vmlalpl.s8','vmlalvs.s8','vmlalvc.s8','vmlalhi.s8','vmlalls.s8','vmlalge.s8','vmlallt.s8','vmlalgt.s8','vmlalle.s8',
+ 'vmlaleq.s16','vmlalne.s16','vmlalcs.s16','vmlalhs.s16','vmlalcc.s16','vmlallo.s16','vmlalmi.s16','vmlalpl.s16','vmlalvs.s16','vmlalvc.s16','vmlalhi.s16','vmlalls.s16','vmlalge.s16','vmlallt.s16','vmlalgt.s16','vmlalle.s16',
+ 'vmlaleq.s32','vmlalne.s32','vmlalcs.s32','vmlalhs.s32','vmlalcc.s32','vmlallo.s32','vmlalmi.s32','vmlalpl.s32','vmlalvs.s32','vmlalvc.s32','vmlalhi.s32','vmlalls.s32','vmlalge.s32','vmlallt.s32','vmlalgt.s32','vmlalle.s32',
+
+ 'vmlsleq.s8','vmlslne.s8','vmlslcs.s8','vmlslhs.s8','vmlslcc.s8','vmlsllo.s8','vmlslmi.s8','vmlslpl.s8','vmlslvs.s8','vmlslvc.s8','vmlslhi.s8','vmlslls.s8','vmlslge.s8','vmlsllt.s8','vmlslgt.s8','vmlslle.s8',
+ 'vmlsleq.s16','vmlslne.s16','vmlslcs.s16','vmlslhs.s16','vmlslcc.s16','vmlsllo.s16','vmlslmi.s16','vmlslpl.s16','vmlslvs.s16','vmlslvc.s16','vmlslhi.s16','vmlslls.s16','vmlslge.s16','vmlsllt.s16','vmlslgt.s16','vmlslle.s16',
+ 'vmlsleq.s32','vmlslne.s32','vmlslcs.s32','vmlslhs.s32','vmlslcc.s32','vmlsllo.s32','vmlslmi.s32','vmlslpl.s32','vmlslvs.s32','vmlslvc.s32','vmlslhi.s32','vmlslls.s32','vmlslge.s32','vmlsllt.s32','vmlslgt.s32','vmlslle.s32',
+
+ 'vnegeq.s8','vnegne.s8','vnegcs.s8','vneghs.s8','vnegcc.s8','vneglo.s8','vnegmi.s8','vnegpl.s8','vnegvs.s8','vnegvc.s8','vneghi.s8','vnegls.s8','vnegge.s8','vneglt.s8','vneggt.s8','vnegle.s8',
+ 'vnegeq.s16','vnegne.s16','vnegcs.s16','vneghs.s16','vnegcc.s16','vneglo.s16','vnegmi.s16','vnegpl.s16','vnegvs.s16','vnegvc.s16','vneghi.s16','vnegls.s16','vnegge.s16','vneglt.s16','vneggt.s16','vnegle.s16',
+ 'vnegeq.s32','vnegne.s32','vnegcs.s32','vneghs.s32','vnegcc.s32','vneglo.s32','vnegmi.s32','vnegpl.s32','vnegvs.s32','vnegvc.s32','vneghi.s32','vnegls.s32','vnegge.s32','vneglt.s32','vneggt.s32','vnegle.s32',
+
+ 'vpadaleq.s8','vpadalne.s8','vpadalcs.s8','vpadalhs.s8','vpadalcc.s8','vpadallo.s8','vpadalmi.s8','vpadalpl.s8','vpadalvs.s8','vpadalvc.s8','vpadalhi.s8','vpadalls.s8','vpadalge.s8','vpadallt.s8','vpadalgt.s8','vpadalle.s8',
+ 'vpadaleq.s16','vpadalne.s16','vpadalcs.s16','vpadalhs.s16','vpadalcc.s16','vpadallo.s16','vpadalmi.s16','vpadalpl.s16','vpadalvs.s16','vpadalvc.s16','vpadalhi.s16','vpadalls.s16','vpadalge.s16','vpadallt.s16','vpadalgt.s16','vpadalle.s16',
+ 'vpadaleq.s32','vpadalne.s32','vpadalcs.s32','vpadalhs.s32','vpadalcc.s32','vpadallo.s32','vpadalmi.s32','vpadalpl.s32','vpadalvs.s32','vpadalvc.s32','vpadalhi.s32','vpadalls.s32','vpadalge.s32','vpadallt.s32','vpadalgt.s32','vpadalle.s32',
+
+ 'vmovleq.s8','vmovlne.s8','vmovlcs.s8','vmovlhs.s8','vmovlcc.s8','vmovllo.s8','vmovlmi.s8','vmovlpl.s8','vmovlvs.s8','vmovlvc.s8','vmovlhi.s8','vmovlls.s8','vmovlge.s8','vmovllt.s8','vmovlgt.s8','vmovlle.s8',
+ 'vmovleq.s16','vmovlne.s16','vmovlcs.s16','vmovlhs.s16','vmovlcc.s16','vmovllo.s16','vmovlmi.s16','vmovlpl.s16','vmovlvs.s16','vmovlvc.s16','vmovlhi.s16','vmovlls.s16','vmovlge.s16','vmovllt.s16','vmovlgt.s16','vmovlle.s16',
+ 'vmovleq.s32','vmovlne.s32','vmovlcs.s32','vmovlhs.s32','vmovlcc.s32','vmovllo.s32','vmovlmi.s32','vmovlpl.s32','vmovlvs.s32','vmovlvc.s32','vmovlhi.s32','vmovlls.s32','vmovlge.s32','vmovllt.s32','vmovlgt.s32','vmovlle.s32',
+
+ 'vmulleq.s8','vmullne.s8','vmullcs.s8','vmullhs.s8','vmullcc.s8','vmulllo.s8','vmullmi.s8','vmullpl.s8','vmullvs.s8','vmullvc.s8','vmullhi.s8','vmullls.s8','vmullge.s8','vmulllt.s8','vmullgt.s8','vmullle.s8',
+ 'vmulleq.s16','vmullne.s16','vmullcs.s16','vmullhs.s16','vmullcc.s16','vmulllo.s16','vmullmi.s16','vmullpl.s16','vmullvs.s16','vmullvc.s16','vmullhi.s16','vmullls.s16','vmullge.s16','vmulllt.s16','vmullgt.s16','vmullle.s16',
+ 'vmulleq.s32','vmullne.s32','vmullcs.s32','vmullhs.s32','vmullcc.s32','vmulllo.s32','vmullmi.s32','vmullpl.s32','vmullvs.s32','vmullvc.s32','vmullhi.s32','vmullls.s32','vmullge.s32','vmulllt.s32','vmullgt.s32','vmullle.s32',
+
+ 'vpaddleq.s8','vpaddlne.s8','vpaddlcs.s8','vpaddlhs.s8','vpaddlcc.s8','vpaddllo.s8','vpaddlmi.s8','vpaddlpl.s8','vpaddlvs.s8','vpaddlvc.s8','vpaddlhi.s8','vpaddlls.s8','vpaddlge.s8','vpaddllt.s8','vpaddlgt.s8','vpaddlle.s8',
+ 'vpaddleq.s16','vpaddlne.s16','vpaddlcs.s16','vpaddlhs.s16','vpaddlcc.s16','vpaddllo.s16','vpaddlmi.s16','vpaddlpl.s16','vpaddlvs.s16','vpaddlvc.s16','vpaddlhi.s16','vpaddlls.s16','vpaddlge.s16','vpaddllt.s16','vpaddlgt.s16','vpaddlle.s16',
+ 'vpaddleq.s32','vpaddlne.s32','vpaddlcs.s32','vpaddlhs.s32','vpaddlcc.s32','vpaddllo.s32','vpaddlmi.s32','vpaddlpl.s32','vpaddlvs.s32','vpaddlvc.s32','vpaddlhi.s32','vpaddlls.s32','vpaddlge.s32','vpaddllt.s32','vpaddlgt.s32','vpaddlle.s32',
+
+ 'vpmaxeq.s8','vpmaxne.s8','vpmaxcs.s8','vpmaxhs.s8','vpmaxcc.s8','vpmaxlo.s8','vpmaxmi.s8','vpmaxpl.s8','vpmaxvs.s8','vpmaxvc.s8','vpmaxhi.s8','vpmaxls.s8','vpmaxge.s8','vpmaxlt.s8','vpmaxgt.s8','vpmaxle.s8',
+ 'vpmaxeq.s16','vpmaxne.s16','vpmaxcs.s16','vpmaxhs.s16','vpmaxcc.s16','vpmaxlo.s16','vpmaxmi.s16','vpmaxpl.s16','vpmaxvs.s16','vpmaxvc.s16','vpmaxhi.s16','vpmaxls.s16','vpmaxge.s16','vpmaxlt.s16','vpmaxgt.s16','vpmaxle.s16',
+ 'vpmaxeq.s32','vpmaxne.s32','vpmaxcs.s32','vpmaxhs.s32','vpmaxcc.s32','vpmaxlo.s32','vpmaxmi.s32','vpmaxpl.s32','vpmaxvs.s32','vpmaxvc.s32','vpmaxhi.s32','vpmaxls.s32','vpmaxge.s32','vpmaxlt.s32','vpmaxgt.s32','vpmaxle.s32',
+
+ 'vpmineq.s8','vpminne.s8','vpmincs.s8','vpminhs.s8','vpmincc.s8','vpminlo.s8','vpminmi.s8','vpminpl.s8','vpminvs.s8','vpminvc.s8','vpminhi.s8','vpminls.s8','vpminge.s8','vpminlt.s8','vpmingt.s8','vpminle.s8',
+ 'vpmineq.s16','vpminne.s16','vpmincs.s16','vpminhs.s16','vpmincc.s16','vpminlo.s16','vpminmi.s16','vpminpl.s16','vpminvs.s16','vpminvc.s16','vpminhi.s16','vpminls.s16','vpminge.s16','vpminlt.s16','vpmingt.s16','vpminle.s16',
+ 'vpmineq.s32','vpminne.s32','vpmincs.s32','vpminhs.s32','vpmincc.s32','vpminlo.s32','vpminmi.s32','vpminpl.s32','vpminvs.s32','vpminvc.s32','vpminhi.s32','vpminls.s32','vpminge.s32','vpminlt.s32','vpmingt.s32','vpminle.s32',
+
+ 'vqabseq.s8','vqabsne.s8','vqabscs.s8','vqabshs.s8','vqabscc.s8','vqabslo.s8','vqabsmi.s8','vqabspl.s8','vqabsvs.s8','vqabsvc.s8','vqabshi.s8','vqabsls.s8','vqabsge.s8','vqabslt.s8','vqabsgt.s8','vqabsle.s8',
+ 'vqabseq.s16','vqabsne.s16','vqabscs.s16','vqabshs.s16','vqabscc.s16','vqabslo.s16','vqabsmi.s16','vqabspl.s16','vqabsvs.s16','vqabsvc.s16','vqabshi.s16','vqabsls.s16','vqabsge.s16','vqabslt.s16','vqabsgt.s16','vqabsle.s16',
+ 'vqabseq.s32','vqabsne.s32','vqabscs.s32','vqabshs.s32','vqabscc.s32','vqabslo.s32','vqabsmi.s32','vqabspl.s32','vqabsvs.s32','vqabsvc.s32','vqabshi.s32','vqabsls.s32','vqabsge.s32','vqabslt.s32','vqabsgt.s32','vqabsle.s32',
+
+ 'vqaddeq.s8','vqaddne.s8','vqaddcs.s8','vqaddhs.s8','vqaddcc.s8','vqaddlo.s8','vqaddmi.s8','vqaddpl.s8','vqaddvs.s8','vqaddvc.s8','vqaddhi.s8','vqaddls.s8','vqaddge.s8','vqaddlt.s8','vqaddgt.s8','vqaddle.s8',
+ 'vqaddeq.s16','vqaddne.s16','vqaddcs.s16','vqaddhs.s16','vqaddcc.s16','vqaddlo.s16','vqaddmi.s16','vqaddpl.s16','vqaddvs.s16','vqaddvc.s16','vqaddhi.s16','vqaddls.s16','vqaddge.s16','vqaddlt.s16','vqaddgt.s16','vqaddle.s16',
+ 'vqaddeq.s32','vqaddne.s32','vqaddcs.s32','vqaddhs.s32','vqaddcc.s32','vqaddlo.s32','vqaddmi.s32','vqaddpl.s32','vqaddvs.s32','vqaddvc.s32','vqaddhi.s32','vqaddls.s32','vqaddge.s32','vqaddlt.s32','vqaddgt.s32','vqaddle.s32',
+ 'vqaddeq.s64','vqaddne.s64','vqaddcs.s64','vqaddhs.s64','vqaddcc.s64','vqaddlo.s64','vqaddmi.s64','vqaddpl.s64','vqaddvs.s64','vqaddvc.s64','vqaddhi.s64','vqaddls.s64','vqaddge.s64','vqaddlt.s64','vqaddgt.s64','vqaddle.s64',
+
+ 'vqdmlaleq.s16','vqdmlalne.s16','vqdmlalcs.s16','vqdmlalhs.s16','vqdmlalcc.s16','vqdmlallo.s16','vqdmlalmi.s16','vqdmlalpl.s16','vqdmlalvs.s16','vqdmlalvc.s16','vqdmlalhi.s16','vqdmlalls.s16','vqdmlalge.s16','vqdmlallt.s16','vqdmlalgt.s16','vqdmlalle.s16',
+ 'vqdmlaleq.s32','vqdmlalne.s32','vqdmlalcs.s32','vqdmlalhs.s32','vqdmlalcc.s32','vqdmlallo.s32','vqdmlalmi.s32','vqdmlalpl.s32','vqdmlalvs.s32','vqdmlalvc.s32','vqdmlalhi.s32','vqdmlalls.s32','vqdmlalge.s32','vqdmlallt.s32','vqdmlalgt.s32','vqdmlalle.s32',
+
+ 'vqdmlsleq.s16','vqdmlslne.s16','vqdmlslcs.s16','vqdmlslhs.s16','vqdmlslcc.s16','vqdmlsllo.s16','vqdmlslmi.s16','vqdmlslpl.s16','vqdmlslvs.s16','vqdmlslvc.s16','vqdmlslhi.s16','vqdmlslls.s16','vqdmlslge.s16','vqdmlsllt.s16','vqdmlslgt.s16','vqdmlslle.s16',
+ 'vqdmlsleq.s32','vqdmlslne.s32','vqdmlslcs.s32','vqdmlslhs.s32','vqdmlslcc.s32','vqdmlsllo.s32','vqdmlslmi.s32','vqdmlslpl.s32','vqdmlslvs.s32','vqdmlslvc.s32','vqdmlslhi.s32','vqdmlslls.s32','vqdmlslge.s32','vqdmlsllt.s32','vqdmlslgt.s32','vqdmlslle.s32',
+
+ 'vqdmulheq.s16','vqdmulhne.s16','vqdmulhcs.s16','vqdmulhhs.s16','vqdmulhcc.s16','vqdmulhlo.s16','vqdmulhmi.s16','vqdmulhpl.s16','vqdmulhvs.s16','vqdmulhvc.s16','vqdmulhhi.s16','vqdmulhls.s16','vqdmulhge.s16','vqdmulhlt.s16','vqdmulhgt.s16','vqdmulhle.s16',
+ 'vqdmulheq.s32','vqdmulhne.s32','vqdmulhcs.s32','vqdmulhhs.s32','vqdmulhcc.s32','vqdmulhlo.s32','vqdmulhmi.s32','vqdmulhpl.s32','vqdmulhvs.s32','vqdmulhvc.s32','vqdmulhhi.s32','vqdmulhls.s32','vqdmulhge.s32','vqdmulhlt.s32','vqdmulhgt.s32','vqdmulhle.s32',
+
+ 'vqdmulleq.s16','vqdmullne.s16','vqdmullcs.s16','vqdmullhs.s16','vqdmullcc.s16','vqdmulllo.s16','vqdmullmi.s16','vqdmullpl.s16','vqdmullvs.s16','vqdmullvc.s16','vqdmullhi.s16','vqdmullls.s16','vqdmullge.s16','vqdmulllt.s16','vqdmullgt.s16','vqdmullle.s16',
+ 'vqdmulleq.s32','vqdmullne.s32','vqdmullcs.s32','vqdmullhs.s32','vqdmullcc.s32','vqdmulllo.s32','vqdmullmi.s32','vqdmullpl.s32','vqdmullvs.s32','vqdmullvc.s32','vqdmullhi.s32','vqdmullls.s32','vqdmullge.s32','vqdmulllt.s32','vqdmullgt.s32','vqdmullle.s32',
+
+ 'vqmovneq.s16','vqmovnne.s16','vqmovncs.s16','vqmovnhs.s16','vqmovncc.s16','vqmovnlo.s16','vqmovnmi.s16','vqmovnpl.s16','vqmovnvs.s16','vqmovnvc.s16','vqmovnhi.s16','vqmovnls.s16','vqmovnge.s16','vqmovnlt.s16','vqmovngt.s16','vqmovnle.s16',
+ 'vqmovneq.s32','vqmovnne.s32','vqmovncs.s32','vqmovnhs.s32','vqmovncc.s32','vqmovnlo.s32','vqmovnmi.s32','vqmovnpl.s32','vqmovnvs.s32','vqmovnvc.s32','vqmovnhi.s32','vqmovnls.s32','vqmovnge.s32','vqmovnlt.s32','vqmovngt.s32','vqmovnle.s32',
+ 'vqmovneq.s64','vqmovnne.s64','vqmovncs.s64','vqmovnhs.s64','vqmovncc.s64','vqmovnlo.s64','vqmovnmi.s64','vqmovnpl.s64','vqmovnvs.s64','vqmovnvc.s64','vqmovnhi.s64','vqmovnls.s64','vqmovnge.s64','vqmovnlt.s64','vqmovngt.s64','vqmovnle.s64',
+
+ 'vqmovuneq.s16','vqmovunne.s16','vqmovuncs.s16','vqmovunhs.s16','vqmovuncc.s16','vqmovunlo.s16','vqmovunmi.s16','vqmovunpl.s16','vqmovunvs.s16','vqmovunvc.s16','vqmovunhi.s16','vqmovunls.s16','vqmovunge.s16','vqmovunlt.s16','vqmovungt.s16','vqmovunle.s16',
+ 'vqmovuneq.s32','vqmovunne.s32','vqmovuncs.s32','vqmovunhs.s32','vqmovuncc.s32','vqmovunlo.s32','vqmovunmi.s32','vqmovunpl.s32','vqmovunvs.s32','vqmovunvc.s32','vqmovunhi.s32','vqmovunls.s32','vqmovunge.s32','vqmovunlt.s32','vqmovungt.s32','vqmovunle.s32',
+ 'vqmovuneq.s64','vqmovunne.s64','vqmovuncs.s64','vqmovunhs.s64','vqmovuncc.s64','vqmovunlo.s64','vqmovunmi.s64','vqmovunpl.s64','vqmovunvs.s64','vqmovunvc.s64','vqmovunhi.s64','vqmovunls.s64','vqmovunge.s64','vqmovunlt.s64','vqmovungt.s64','vqmovunle.s64',
+
+ 'vqnegeq.s8','vqnegne.s8','vqnegcs.s8','vqneghs.s8','vqnegcc.s8','vqneglo.s8','vqnegmi.s8','vqnegpl.s8','vqnegvs.s8','vqnegvc.s8','vqneghi.s8','vqnegls.s8','vqnegge.s8','vqneglt.s8','vqneggt.s8','vqnegle.s8',
+ 'vqnegeq.s16','vqnegne.s16','vqnegcs.s16','vqneghs.s16','vqnegcc.s16','vqneglo.s16','vqnegmi.s16','vqnegpl.s16','vqnegvs.s16','vqnegvc.s16','vqneghi.s16','vqnegls.s16','vqnegge.s16','vqneglt.s16','vqneggt.s16','vqnegle.s16',
+ 'vqnegeq.s32','vqnegne.s32','vqnegcs.s32','vqneghs.s32','vqnegcc.s32','vqneglo.s32','vqnegmi.s32','vqnegpl.s32','vqnegvs.s32','vqnegvc.s32','vqneghi.s32','vqnegls.s32','vqnegge.s32','vqneglt.s32','vqneggt.s32','vqnegle.s32',
+
+ 'vqrdmulheq.s16','vqrdmulhne.s16','vqrdmulhcs.s16','vqrdmulhhs.s16','vqrdmulhcc.s16','vqrdmulhlo.s16','vqrdmulhmi.s16','vqrdmulhpl.s16','vqrdmulhvs.s16','vqrdmulhvc.s16','vqrdmulhhi.s16','vqrdmulhls.s16','vqrdmulhge.s16','vqrdmulhlt.s16','vqrdmulhgt.s16','vqrdmulhle.s16',
+ 'vqrdmulheq.s32','vqrdmulhne.s32','vqrdmulhcs.s32','vqrdmulhhs.s32','vqrdmulhcc.s32','vqrdmulhlo.s32','vqrdmulhmi.s32','vqrdmulhpl.s32','vqrdmulhvs.s32','vqrdmulhvc.s32','vqrdmulhhi.s32','vqrdmulhls.s32','vqrdmulhge.s32','vqrdmulhlt.s32','vqrdmulhgt.s32','vqrdmulhle.s32',
+
+ 'vqrshleq.s8','vqrshlne.s8','vqrshlcs.s8','vqrshlhs.s8','vqrshlcc.s8','vqrshllo.s8','vqrshlmi.s8','vqrshlpl.s8','vqrshlvs.s8','vqrshlvc.s8','vqrshlhi.s8','vqrshlls.s8','vqrshlge.s8','vqrshllt.s8','vqrshlgt.s8','vqrshlle.s8',
+ 'vqrshleq.s16','vqrshlne.s16','vqrshlcs.s16','vqrshlhs.s16','vqrshlcc.s16','vqrshllo.s16','vqrshlmi.s16','vqrshlpl.s16','vqrshlvs.s16','vqrshlvc.s16','vqrshlhi.s16','vqrshlls.s16','vqrshlge.s16','vqrshllt.s16','vqrshlgt.s16','vqrshlle.s16',
+ 'vqrshleq.s32','vqrshlne.s32','vqrshlcs.s32','vqrshlhs.s32','vqrshlcc.s32','vqrshllo.s32','vqrshlmi.s32','vqrshlpl.s32','vqrshlvs.s32','vqrshlvc.s32','vqrshlhi.s32','vqrshlls.s32','vqrshlge.s32','vqrshllt.s32','vqrshlgt.s32','vqrshlle.s32',
+ 'vqrshleq.s64','vqrshlne.s64','vqrshlcs.s64','vqrshlhs.s64','vqrshlcc.s64','vqrshllo.s64','vqrshlmi.s64','vqrshlpl.s64','vqrshlvs.s64','vqrshlvc.s64','vqrshlhi.s64','vqrshlls.s64','vqrshlge.s64','vqrshllt.s64','vqrshlgt.s64','vqrshlle.s64',
+
+ 'vqrshrneq.s16','vqrshrnne.s16','vqrshrncs.s16','vqrshrnhs.s16','vqrshrncc.s16','vqrshrnlo.s16','vqrshrnmi.s16','vqrshrnpl.s16','vqrshrnvs.s16','vqrshrnvc.s16','vqrshrnhi.s16','vqrshrnls.s16','vqrshrnge.s16','vqrshrnlt.s16','vqrshrngt.s16','vqrshrnle.s16',
+ 'vqrshrneq.s32','vqrshrnne.s32','vqrshrncs.s32','vqrshrnhs.s32','vqrshrncc.s32','vqrshrnlo.s32','vqrshrnmi.s32','vqrshrnpl.s32','vqrshrnvs.s32','vqrshrnvc.s32','vqrshrnhi.s32','vqrshrnls.s32','vqrshrnge.s32','vqrshrnlt.s32','vqrshrngt.s32','vqrshrnle.s32',
+ 'vqrshrneq.s64','vqrshrnne.s64','vqrshrncs.s64','vqrshrnhs.s64','vqrshrncc.s64','vqrshrnlo.s64','vqrshrnmi.s64','vqrshrnpl.s64','vqrshrnvs.s64','vqrshrnvc.s64','vqrshrnhi.s64','vqrshrnls.s64','vqrshrnge.s64','vqrshrnlt.s64','vqrshrngt.s64','vqrshrnle.s64',
+
+ 'vqrshruneq.s16','vqrshrunne.s16','vqrshruncs.s16','vqrshrunhs.s16','vqrshruncc.s16','vqrshrunlo.s16','vqrshrunmi.s16','vqrshrunpl.s16','vqrshrunvs.s16','vqrshrunvc.s16','vqrshrunhi.s16','vqrshrunls.s16','vqrshrunge.s16','vqrshrunlt.s16','vqrshrungt.s16','vqrshrunle.s16',
+ 'vqrshruneq.s32','vqrshrunne.s32','vqrshruncs.s32','vqrshrunhs.s32','vqrshruncc.s32','vqrshrunlo.s32','vqrshrunmi.s32','vqrshrunpl.s32','vqrshrunvs.s32','vqrshrunvc.s32','vqrshrunhi.s32','vqrshrunls.s32','vqrshrunge.s32','vqrshrunlt.s32','vqrshrungt.s32','vqrshrunle.s32',
+ 'vqrshruneq.s64','vqrshrunne.s64','vqrshruncs.s64','vqrshrunhs.s64','vqrshruncc.s64','vqrshrunlo.s64','vqrshrunmi.s64','vqrshrunpl.s64','vqrshrunvs.s64','vqrshrunvc.s64','vqrshrunhi.s64','vqrshrunls.s64','vqrshrunge.s64','vqrshrunlt.s64','vqrshrungt.s64','vqrshrunle.s64',
+
+ 'vqshleq.s8','vqshlne.s8','vqshlcs.s8','vqshlhs.s8','vqshlcc.s8','vqshllo.s8','vqshlmi.s8','vqshlpl.s8','vqshlvs.s8','vqshlvc.s8','vqshlhi.s8','vqshlls.s8','vqshlge.s8','vqshllt.s8','vqshlgt.s8','vqshlle.s8',
+ 'vqshleq.s16','vqshlne.s16','vqshlcs.s16','vqshlhs.s16','vqshlcc.s16','vqshllo.s16','vqshlmi.s16','vqshlpl.s16','vqshlvs.s16','vqshlvc.s16','vqshlhi.s16','vqshlls.s16','vqshlge.s16','vqshllt.s16','vqshlgt.s16','vqshlle.s16',
+ 'vqshleq.s32','vqshlne.s32','vqshlcs.s32','vqshlhs.s32','vqshlcc.s32','vqshllo.s32','vqshlmi.s32','vqshlpl.s32','vqshlvs.s32','vqshlvc.s32','vqshlhi.s32','vqshlls.s32','vqshlge.s32','vqshllt.s32','vqshlgt.s32','vqshlle.s32',
+ 'vqshleq.s64','vqshlne.s64','vqshlcs.s64','vqshlhs.s64','vqshlcc.s64','vqshllo.s64','vqshlmi.s64','vqshlpl.s64','vqshlvs.s64','vqshlvc.s64','vqshlhi.s64','vqshlls.s64','vqshlge.s64','vqshllt.s64','vqshlgt.s64','vqshlle.s64',
+
+ 'vqshlueq.s8','vqshlune.s8','vqshlucs.s8','vqshluhs.s8','vqshlucc.s8','vqshlulo.s8','vqshlumi.s8','vqshlupl.s8','vqshluvs.s8','vqshluvc.s8','vqshluhi.s8','vqshluls.s8','vqshluge.s8','vqshlult.s8','vqshlugt.s8','vqshlule.s8',
+ 'vqshlueq.s16','vqshlune.s16','vqshlucs.s16','vqshluhs.s16','vqshlucc.s16','vqshlulo.s16','vqshlumi.s16','vqshlupl.s16','vqshluvs.s16','vqshluvc.s16','vqshluhi.s16','vqshluls.s16','vqshluge.s16','vqshlult.s16','vqshlugt.s16','vqshlule.s16',
+ 'vqshlueq.s32','vqshlune.s32','vqshlucs.s32','vqshluhs.s32','vqshlucc.s32','vqshlulo.s32','vqshlumi.s32','vqshlupl.s32','vqshluvs.s32','vqshluvc.s32','vqshluhi.s32','vqshluls.s32','vqshluge.s32','vqshlult.s32','vqshlugt.s32','vqshlule.s32',
+ 'vqshlueq.s64','vqshlune.s64','vqshlucs.s64','vqshluhs.s64','vqshlucc.s64','vqshlulo.s64','vqshlumi.s64','vqshlupl.s64','vqshluvs.s64','vqshluvc.s64','vqshluhi.s64','vqshluls.s64','vqshluge.s64','vqshlult.s64','vqshlugt.s64','vqshlule.s64',
+
+ 'vqshrneq.s16','vqshrnne.s16','vqshrncs.s16','vqshrnhs.s16','vqshrncc.s16','vqshrnlo.s16','vqshrnmi.s16','vqshrnpl.s16','vqshrnvs.s16','vqshrnvc.s16','vqshrnhi.s16','vqshrnls.s16','vqshrnge.s16','vqshrnlt.s16','vqshrngt.s16','vqshrnle.s16',
+ 'vqshrneq.s32','vqshrnne.s32','vqshrncs.s32','vqshrnhs.s32','vqshrncc.s32','vqshrnlo.s32','vqshrnmi.s32','vqshrnpl.s32','vqshrnvs.s32','vqshrnvc.s32','vqshrnhi.s32','vqshrnls.s32','vqshrnge.s32','vqshrnlt.s32','vqshrngt.s32','vqshrnle.s32',
+ 'vqshrneq.s64','vqshrnne.s64','vqshrncs.s64','vqshrnhs.s64','vqshrncc.s64','vqshrnlo.s64','vqshrnmi.s64','vqshrnpl.s64','vqshrnvs.s64','vqshrnvc.s64','vqshrnhi.s64','vqshrnls.s64','vqshrnge.s64','vqshrnlt.s64','vqshrngt.s64','vqshrnle.s64',
+
+ 'vqshruneq.s16','vqshrunne.s16','vqshruncs.s16','vqshrunhs.s16','vqshruncc.s16','vqshrunlo.s16','vqshrunmi.s16','vqshrunpl.s16','vqshrunvs.s16','vqshrunvc.s16','vqshrunhi.s16','vqshrunls.s16','vqshrunge.s16','vqshrunlt.s16','vqshrungt.s16','vqshrunle.s16',
+ 'vqshruneq.s32','vqshrunne.s32','vqshruncs.s32','vqshrunhs.s32','vqshruncc.s32','vqshrunlo.s32','vqshrunmi.s32','vqshrunpl.s32','vqshrunvs.s32','vqshrunvc.s32','vqshrunhi.s32','vqshrunls.s32','vqshrunge.s32','vqshrunlt.s32','vqshrungt.s32','vqshrunle.s32',
+ 'vqshruneq.s64','vqshrunne.s64','vqshruncs.s64','vqshrunhs.s64','vqshruncc.s64','vqshrunlo.s64','vqshrunmi.s64','vqshrunpl.s64','vqshrunvs.s64','vqshrunvc.s64','vqshrunhi.s64','vqshrunls.s64','vqshrunge.s64','vqshrunlt.s64','vqshrungt.s64','vqshrunle.s64',
+
+ 'vqsubeq.s8','vqsubne.s8','vqsubcs.s8','vqsubhs.s8','vqsubcc.s8','vqsublo.s8','vqsubmi.s8','vqsubpl.s8','vqsubvs.s8','vqsubvc.s8','vqsubhi.s8','vqsubls.s8','vqsubge.s8','vqsublt.s8','vqsubgt.s8','vqsuble.s8',
+ 'vqsubeq.s16','vqsubne.s16','vqsubcs.s16','vqsubhs.s16','vqsubcc.s16','vqsublo.s16','vqsubmi.s16','vqsubpl.s16','vqsubvs.s16','vqsubvc.s16','vqsubhi.s16','vqsubls.s16','vqsubge.s16','vqsublt.s16','vqsubgt.s16','vqsuble.s16',
+ 'vqsubeq.s32','vqsubne.s32','vqsubcs.s32','vqsubhs.s32','vqsubcc.s32','vqsublo.s32','vqsubmi.s32','vqsubpl.s32','vqsubvs.s32','vqsubvc.s32','vqsubhi.s32','vqsubls.s32','vqsubge.s32','vqsublt.s32','vqsubgt.s32','vqsuble.s32',
+ 'vqsubeq.s64','vqsubne.s64','vqsubcs.s64','vqsubhs.s64','vqsubcc.s64','vqsublo.s64','vqsubmi.s64','vqsubpl.s64','vqsubvs.s64','vqsubvc.s64','vqsubhi.s64','vqsubls.s64','vqsubge.s64','vqsublt.s64','vqsubgt.s64','vqsuble.s64',
+
+ 'vrhaddeq.s8','vrhaddne.s8','vrhaddcs.s8','vrhaddhs.s8','vrhaddcc.s8','vrhaddlo.s8','vrhaddmi.s8','vrhaddpl.s8','vrhaddvs.s8','vrhaddvc.s8','vrhaddhi.s8','vrhaddls.s8','vrhaddge.s8','vrhaddlt.s8','vrhaddgt.s8','vrhaddle.s8',
+ 'vrhaddeq.s16','vrhaddne.s16','vrhaddcs.s16','vrhaddhs.s16','vrhaddcc.s16','vrhaddlo.s16','vrhaddmi.s16','vrhaddpl.s16','vrhaddvs.s16','vrhaddvc.s16','vrhaddhi.s16','vrhaddls.s16','vrhaddge.s16','vrhaddlt.s16','vrhaddgt.s16','vrhaddle.s16',
+ 'vrhaddeq.s32','vrhaddne.s32','vrhaddcs.s32','vrhaddhs.s32','vrhaddcc.s32','vrhaddlo.s32','vrhaddmi.s32','vrhaddpl.s32','vrhaddvs.s32','vrhaddvc.s32','vrhaddhi.s32','vrhaddls.s32','vrhaddge.s32','vrhaddlt.s32','vrhaddgt.s32','vrhaddle.s32',
+
+ 'vrshleq.s8','vrshlne.s8','vrshlcs.s8','vrshlhs.s8','vrshlcc.s8','vrshllo.s8','vrshlmi.s8','vrshlpl.s8','vrshlvs.s8','vrshlvc.s8','vrshlhi.s8','vrshlls.s8','vrshlge.s8','vrshllt.s8','vrshlgt.s8','vrshlle.s8',
+ 'vrshleq.s16','vrshlne.s16','vrshlcs.s16','vrshlhs.s16','vrshlcc.s16','vrshllo.s16','vrshlmi.s16','vrshlpl.s16','vrshlvs.s16','vrshlvc.s16','vrshlhi.s16','vrshlls.s16','vrshlge.s16','vrshllt.s16','vrshlgt.s16','vrshlle.s16',
+ 'vrshleq.s32','vrshlne.s32','vrshlcs.s32','vrshlhs.s32','vrshlcc.s32','vrshllo.s32','vrshlmi.s32','vrshlpl.s32','vrshlvs.s32','vrshlvc.s32','vrshlhi.s32','vrshlls.s32','vrshlge.s32','vrshllt.s32','vrshlgt.s32','vrshlle.s32',
+ 'vrshleq.s64','vrshlne.s64','vrshlcs.s64','vrshlhs.s64','vrshlcc.s64','vrshllo.s64','vrshlmi.s64','vrshlpl.s64','vrshlvs.s64','vrshlvc.s64','vrshlhi.s64','vrshlls.s64','vrshlge.s64','vrshllt.s64','vrshlgt.s64','vrshlle.s64',
+
+ 'vrshreq.s8','vrshrne.s8','vrshrcs.s8','vrshrhs.s8','vrshrcc.s8','vrshrlo.s8','vrshrmi.s8','vrshrpl.s8','vrshrvs.s8','vrshrvc.s8','vrshrhi.s8','vrshrls.s8','vrshrge.s8','vrshrlt.s8','vrshrgt.s8','vrshrle.s8',
+ 'vrshreq.s16','vrshrne.s16','vrshrcs.s16','vrshrhs.s16','vrshrcc.s16','vrshrlo.s16','vrshrmi.s16','vrshrpl.s16','vrshrvs.s16','vrshrvc.s16','vrshrhi.s16','vrshrls.s16','vrshrge.s16','vrshrlt.s16','vrshrgt.s16','vrshrle.s16',
+ 'vrshreq.s32','vrshrne.s32','vrshrcs.s32','vrshrhs.s32','vrshrcc.s32','vrshrlo.s32','vrshrmi.s32','vrshrpl.s32','vrshrvs.s32','vrshrvc.s32','vrshrhi.s32','vrshrls.s32','vrshrge.s32','vrshrlt.s32','vrshrgt.s32','vrshrle.s32',
+ 'vrshreq.s64','vrshrne.s64','vrshrcs.s64','vrshrhs.s64','vrshrcc.s64','vrshrlo.s64','vrshrmi.s64','vrshrpl.s64','vrshrvs.s64','vrshrvc.s64','vrshrhi.s64','vrshrls.s64','vrshrge.s64','vrshrlt.s64','vrshrgt.s64','vrshrle.s64',
+
+ 'vrsraeq.s8','vrsrane.s8','vrsracs.s8','vrsrahs.s8','vrsracc.s8','vrsralo.s8','vrsrami.s8','vrsrapl.s8','vrsravs.s8','vrsravc.s8','vrsrahi.s8','vrsrals.s8','vrsrage.s8','vrsralt.s8','vrsragt.s8','vrsrale.s8',
+ 'vrsraeq.s16','vrsrane.s16','vrsracs.s16','vrsrahs.s16','vrsracc.s16','vrsralo.s16','vrsrami.s16','vrsrapl.s16','vrsravs.s16','vrsravc.s16','vrsrahi.s16','vrsrals.s16','vrsrage.s16','vrsralt.s16','vrsragt.s16','vrsrale.s16',
+ 'vrsraeq.s32','vrsrane.s32','vrsracs.s32','vrsrahs.s32','vrsracc.s32','vrsralo.s32','vrsrami.s32','vrsrapl.s32','vrsravs.s32','vrsravc.s32','vrsrahi.s32','vrsrals.s32','vrsrage.s32','vrsralt.s32','vrsragt.s32','vrsrale.s32',
+ 'vrsraeq.s64','vrsrane.s64','vrsracs.s64','vrsrahs.s64','vrsracc.s64','vrsralo.s64','vrsrami.s64','vrsrapl.s64','vrsravs.s64','vrsravc.s64','vrsrahi.s64','vrsrals.s64','vrsrage.s64','vrsralt.s64','vrsragt.s64','vrsrale.s64',
+
+ 'vshleq.s8','vshlne.s8','vshlcs.s8','vshlhs.s8','vshlcc.s8','vshllo.s8','vshlmi.s8','vshlpl.s8','vshlvs.s8','vshlvc.s8','vshlhi.s8','vshlls.s8','vshlge.s8','vshllt.s8','vshlgt.s8','vshlle.s8',
+ 'vshleq.s16','vshlne.s16','vshlcs.s16','vshlhs.s16','vshlcc.s16','vshllo.s16','vshlmi.s16','vshlpl.s16','vshlvs.s16','vshlvc.s16','vshlhi.s16','vshlls.s16','vshlge.s16','vshllt.s16','vshlgt.s16','vshlle.s16',
+ 'vshleq.s32','vshlne.s32','vshlcs.s32','vshlhs.s32','vshlcc.s32','vshllo.s32','vshlmi.s32','vshlpl.s32','vshlvs.s32','vshlvc.s32','vshlhi.s32','vshlls.s32','vshlge.s32','vshllt.s32','vshlgt.s32','vshlle.s32',
+ 'vshleq.s64','vshlne.s64','vshlcs.s64','vshlhs.s64','vshlcc.s64','vshllo.s64','vshlmi.s64','vshlpl.s64','vshlvs.s64','vshlvc.s64','vshlhi.s64','vshlls.s64','vshlge.s64','vshllt.s64','vshlgt.s64','vshlle.s64',
+
+ 'vshlleq.s8','vshllne.s8','vshllcs.s8','vshllhs.s8','vshllcc.s8','vshlllo.s8','vshllmi.s8','vshllpl.s8','vshllvs.s8','vshllvc.s8','vshllhi.s8','vshllls.s8','vshllge.s8','vshlllt.s8','vshllgt.s8','vshllle.s8',
+ 'vshlleq.s16','vshllne.s16','vshllcs.s16','vshllhs.s16','vshllcc.s16','vshlllo.s16','vshllmi.s16','vshllpl.s16','vshllvs.s16','vshllvc.s16','vshllhi.s16','vshllls.s16','vshllge.s16','vshlllt.s16','vshllgt.s16','vshllle.s16',
+ 'vshlleq.s32','vshllne.s32','vshllcs.s32','vshllhs.s32','vshllcc.s32','vshlllo.s32','vshllmi.s32','vshllpl.s32','vshllvs.s32','vshllvc.s32','vshllhi.s32','vshllls.s32','vshllge.s32','vshlllt.s32','vshllgt.s32','vshllle.s32',
+
+ 'vshreq.s8','vshrne.s8','vshrcs.s8','vshrhs.s8','vshrcc.s8','vshrlo.s8','vshrmi.s8','vshrpl.s8','vshrvs.s8','vshrvc.s8','vshrhi.s8','vshrls.s8','vshrge.s8','vshrlt.s8','vshrgt.s8','vshrle.s8',
+ 'vshreq.s16','vshrne.s16','vshrcs.s16','vshrhs.s16','vshrcc.s16','vshrlo.s16','vshrmi.s16','vshrpl.s16','vshrvs.s16','vshrvc.s16','vshrhi.s16','vshrls.s16','vshrge.s16','vshrlt.s16','vshrgt.s16','vshrle.s16',
+ 'vshreq.s32','vshrne.s32','vshrcs.s32','vshrhs.s32','vshrcc.s32','vshrlo.s32','vshrmi.s32','vshrpl.s32','vshrvs.s32','vshrvc.s32','vshrhi.s32','vshrls.s32','vshrge.s32','vshrlt.s32','vshrgt.s32','vshrle.s32',
+ 'vshreq.s64','vshrne.s64','vshrcs.s64','vshrhs.s64','vshrcc.s64','vshrlo.s64','vshrmi.s64','vshrpl.s64','vshrvs.s64','vshrvc.s64','vshrhi.s64','vshrls.s64','vshrge.s64','vshrlt.s64','vshrgt.s64','vshrle.s64',
+
+ 'vsraeq.s8','vsrane.s8','vsracs.s8','vsrahs.s8','vsracc.s8','vsralo.s8','vsrami.s8','vsrapl.s8','vsravs.s8','vsravc.s8','vsrahi.s8','vsrals.s8','vsrage.s8','vsralt.s8','vsragt.s8','vsrale.s8',
+ 'vsraeq.s16','vsrane.s16','vsracs.s16','vsrahs.s16','vsracc.s16','vsralo.s16','vsrami.s16','vsrapl.s16','vsravs.s16','vsravc.s16','vsrahi.s16','vsrals.s16','vsrage.s16','vsralt.s16','vsragt.s16','vsrale.s16',
+ 'vsraeq.s32','vsrane.s32','vsracs.s32','vsrahs.s32','vsracc.s32','vsralo.s32','vsrami.s32','vsrapl.s32','vsravs.s32','vsravc.s32','vsrahi.s32','vsrals.s32','vsrage.s32','vsralt.s32','vsragt.s32','vsrale.s32',
+ 'vsraeq.s64','vsrane.s64','vsracs.s64','vsrahs.s64','vsracc.s64','vsralo.s64','vsrami.s64','vsrapl.s64','vsravs.s64','vsravc.s64','vsrahi.s64','vsrals.s64','vsrage.s64','vsralt.s64','vsragt.s64','vsrale.s64',
+
+ 'vsubleq.s8','vsublne.s8','vsublcs.s8','vsublhs.s8','vsublcc.s8','vsubllo.s8','vsublmi.s8','vsublpl.s8','vsublvs.s8','vsublvc.s8','vsublhi.s8','vsublls.s8','vsublge.s8','vsubllt.s8','vsublgt.s8','vsublle.s8',
+ 'vsubleq.s16','vsublne.s16','vsublcs.s16','vsublhs.s16','vsublcc.s16','vsubllo.s16','vsublmi.s16','vsublpl.s16','vsublvs.s16','vsublvc.s16','vsublhi.s16','vsublls.s16','vsublge.s16','vsubllt.s16','vsublgt.s16','vsublle.s16',
+ 'vsubleq.s32','vsublne.s32','vsublcs.s32','vsublhs.s32','vsublcc.s32','vsubllo.s32','vsublmi.s32','vsublpl.s32','vsublvs.s32','vsublvc.s32','vsublhi.s32','vsublls.s32','vsublge.s32','vsubllt.s32','vsublgt.s32','vsublle.s32',
+
+ 'vsubheq.s8','vsubhne.s8','vsubhcs.s8','vsubhhs.s8','vsubhcc.s8','vsubhlo.s8','vsubhmi.s8','vsubhpl.s8','vsubhvs.s8','vsubhvc.s8','vsubhhi.s8','vsubhls.s8','vsubhge.s8','vsubhlt.s8','vsubhgt.s8','vsubhle.s8',
+ 'vsubheq.s16','vsubhne.s16','vsubhcs.s16','vsubhhs.s16','vsubhcc.s16','vsubhlo.s16','vsubhmi.s16','vsubhpl.s16','vsubhvs.s16','vsubhvc.s16','vsubhhi.s16','vsubhls.s16','vsubhge.s16','vsubhlt.s16','vsubhgt.s16','vsubhle.s16',
+ 'vsubheq.s32','vsubhne.s32','vsubhcs.s32','vsubhhs.s32','vsubhcc.s32','vsubhlo.s32','vsubhmi.s32','vsubhpl.s32','vsubhvs.s32','vsubhvc.s32','vsubhhi.s32','vsubhls.s32','vsubhge.s32','vsubhlt.s32','vsubhgt.s32','vsubhle.s32'
+ ),
+ /* Conditional NEON SIMD Unsigned Integer Instructions */
+ 33 => array(
+ 'vabaeq.u8','vabane.u8','vabacs.u8','vabahs.u8','vabacc.u8','vabalo.u8','vabami.u8','vabapl.u8','vabavs.u8','vabavc.u8','vabahi.u8','vabals.u8','vabage.u8','vabalt.u8','vabagt.u8','vabale.u8',
+ 'vabaeq.u16','vabane.u16','vabacs.u16','vabahs.u16','vabacc.u16','vabalo.u16','vabami.u16','vabapl.u16','vabavs.u16','vabavc.u16','vabahi.u16','vabals.u16','vabage.u16','vabalt.u16','vabagt.u16','vabale.u16',
+ 'vabaeq.u32','vabane.u32','vabacs.u32','vabahs.u32','vabacc.u32','vabalo.u32','vabami.u32','vabapl.u32','vabavs.u32','vabavc.u32','vabahi.u32','vabals.u32','vabage.u32','vabalt.u32','vabagt.u32','vabale.u32',
+
+ 'vabaleq.u8','vabalne.u8','vabalcs.u8','vabalhs.u8','vabalcc.u8','vaballo.u8','vabalmi.u8','vabalpl.u8','vabalvs.u8','vabalvc.u8','vabalhi.u8','vaballs.u8','vabalge.u8','vaballt.u8','vabalgt.u8','vaballe.u8',
+ 'vabaleq.u16','vabalne.u16','vabalcs.u16','vabalhs.u16','vabalcc.u16','vaballo.u16','vabalmi.u16','vabalpl.u16','vabalvs.u16','vabalvc.u16','vabalhi.u16','vaballs.u16','vabalge.u16','vaballt.u16','vabalgt.u16','vaballe.u16',
+ 'vabaleq.u32','vabalne.u32','vabalcs.u32','vabalhs.u32','vabalcc.u32','vaballo.u32','vabalmi.u32','vabalpl.u32','vabalvs.u32','vabalvc.u32','vabalhi.u32','vaballs.u32','vabalge.u32','vaballt.u32','vabalgt.u32','vaballe.u32',
+
+ 'vabdeq.u8','vabdne.u8','vabdcs.u8','vabdhs.u8','vabdcc.u8','vabdlo.u8','vabdmi.u8','vabdpl.u8','vabdvs.u8','vabdvc.u8','vabdhi.u8','vabdls.u8','vabdge.u8','vabdlt.u8','vabdgt.u8','vabdle.u8',
+ 'vabdeq.u16','vabdne.u16','vabdcs.u16','vabdhs.u16','vabdcc.u16','vabdlo.u16','vabdmi.u16','vabdpl.u16','vabdvs.u16','vabdvc.u16','vabdhi.u16','vabdls.u16','vabdge.u16','vabdlt.u16','vabdgt.u16','vabdle.u16',
+ 'vabdeq.u32','vabdne.u32','vabdcs.u32','vabdhs.u32','vabdcc.u32','vabdlo.u32','vabdmi.u32','vabdpl.u32','vabdvs.u32','vabdvc.u32','vabdhi.u32','vabdls.u32','vabdge.u32','vabdlt.u32','vabdgt.u32','vabdle.u32',
+
+ 'vaddleq.u8','vaddlne.u8','vaddlcs.u8','vaddlhs.u8','vaddlcc.u8','vaddllo.u8','vaddlmi.u8','vaddlpl.u8','vaddlvs.u8','vaddlvc.u8','vaddlhi.u8','vaddlls.u8','vaddlge.u8','vaddllt.u8','vaddlgt.u8','vaddlle.u8',
+ 'vaddleq.u16','vaddlne.u16','vaddlcs.u16','vaddlhs.u16','vaddlcc.u16','vaddllo.u16','vaddlmi.u16','vaddlpl.u16','vaddlvs.u16','vaddlvc.u16','vaddlhi.u16','vaddlls.u16','vaddlge.u16','vaddllt.u16','vaddlgt.u16','vaddlle.u16',
+ 'vaddleq.u32','vaddlne.u32','vaddlcs.u32','vaddlhs.u32','vaddlcc.u32','vaddllo.u32','vaddlmi.u32','vaddlpl.u32','vaddlvs.u32','vaddlvc.u32','vaddlhi.u32','vaddlls.u32','vaddlge.u32','vaddllt.u32','vaddlgt.u32','vaddlle.u32',
+
+ 'vsubleq.u8','vsublne.u8','vsublcs.u8','vsublhs.u8','vsublcc.u8','vsubllo.u8','vsublmi.u8','vsublpl.u8','vsublvs.u8','vsublvc.u8','vsublhi.u8','vsublls.u8','vsublge.u8','vsubllt.u8','vsublgt.u8','vsublle.u8',
+ 'vsubleq.u16','vsublne.u16','vsublcs.u16','vsublhs.u16','vsublcc.u16','vsubllo.u16','vsublmi.u16','vsublpl.u16','vsublvs.u16','vsublvc.u16','vsublhi.u16','vsublls.u16','vsublge.u16','vsubllt.u16','vsublgt.u16','vsublle.u16',
+ 'vsubleq.u32','vsublne.u32','vsublcs.u32','vsublhs.u32','vsublcc.u32','vsubllo.u32','vsublmi.u32','vsublpl.u32','vsublvs.u32','vsublvc.u32','vsublhi.u32','vsublls.u32','vsublge.u32','vsubllt.u32','vsublgt.u32','vsublle.u32',
+
+ 'vaddweq.u8','vaddwne.u8','vaddwcs.u8','vaddwhs.u8','vaddwcc.u8','vaddwlo.u8','vaddwmi.u8','vaddwpl.u8','vaddwvs.u8','vaddwvc.u8','vaddwhi.u8','vaddwls.u8','vaddwge.u8','vaddwlt.u8','vaddwgt.u8','vaddwle.u8',
+ 'vaddweq.u16','vaddwne.u16','vaddwcs.u16','vaddwhs.u16','vaddwcc.u16','vaddwlo.u16','vaddwmi.u16','vaddwpl.u16','vaddwvs.u16','vaddwvc.u16','vaddwhi.u16','vaddwls.u16','vaddwge.u16','vaddwlt.u16','vaddwgt.u16','vaddwle.u16',
+ 'vaddweq.u32','vaddwne.u32','vaddwcs.u32','vaddwhs.u32','vaddwcc.u32','vaddwlo.u32','vaddwmi.u32','vaddwpl.u32','vaddwvs.u32','vaddwvc.u32','vaddwhi.u32','vaddwls.u32','vaddwge.u32','vaddwlt.u32','vaddwgt.u32','vaddwle.u32',
+
+ 'vsubheq.u8','vsubhne.u8','vsubhcs.u8','vsubhhs.u8','vsubhcc.u8','vsubhlo.u8','vsubhmi.u8','vsubhpl.u8','vsubhvs.u8','vsubhvc.u8','vsubhhi.u8','vsubhls.u8','vsubhge.u8','vsubhlt.u8','vsubhgt.u8','vsubhle.u8',
+ 'vsubheq.u16','vsubhne.u16','vsubhcs.u16','vsubhhs.u16','vsubhcc.u16','vsubhlo.u16','vsubhmi.u16','vsubhpl.u16','vsubhvs.u16','vsubhvc.u16','vsubhhi.u16','vsubhls.u16','vsubhge.u16','vsubhlt.u16','vsubhgt.u16','vsubhle.u16',
+ 'vsubheq.u32','vsubhne.u32','vsubhcs.u32','vsubhhs.u32','vsubhcc.u32','vsubhlo.u32','vsubhmi.u32','vsubhpl.u32','vsubhvs.u32','vsubhvc.u32','vsubhhi.u32','vsubhls.u32','vsubhge.u32','vsubhlt.u32','vsubhgt.u32','vsubhle.u32',
+
+ 'vhaddeq.u8','vhaddne.u8','vhaddcs.u8','vhaddhs.u8','vhaddcc.u8','vhaddlo.u8','vhaddmi.u8','vhaddpl.u8','vhaddvs.u8','vhaddvc.u8','vhaddhi.u8','vhaddls.u8','vhaddge.u8','vhaddlt.u8','vhaddgt.u8','vhaddle.u8',
+ 'vhaddeq.u16','vhaddne.u16','vhaddcs.u16','vhaddhs.u16','vhaddcc.u16','vhaddlo.u16','vhaddmi.u16','vhaddpl.u16','vhaddvs.u16','vhaddvc.u16','vhaddhi.u16','vhaddls.u16','vhaddge.u16','vhaddlt.u16','vhaddgt.u16','vhaddle.u16',
+ 'vhaddeq.u32','vhaddne.u32','vhaddcs.u32','vhaddhs.u32','vhaddcc.u32','vhaddlo.u32','vhaddmi.u32','vhaddpl.u32','vhaddvs.u32','vhaddvc.u32','vhaddhi.u32','vhaddls.u32','vhaddge.u32','vhaddlt.u32','vhaddgt.u32','vhaddle.u32',
+
+ 'vhsubeq.u8','vhsubne.u8','vhsubcs.u8','vhsubhs.u8','vhsubcc.u8','vhsublo.u8','vhsubmi.u8','vhsubpl.u8','vhsubvs.u8','vhsubvc.u8','vhsubhi.u8','vhsubls.u8','vhsubge.u8','vhsublt.u8','vhsubgt.u8','vhsuble.u8',
+ 'vhsubeq.u16','vhsubne.u16','vhsubcs.u16','vhsubhs.u16','vhsubcc.u16','vhsublo.u16','vhsubmi.u16','vhsubpl.u16','vhsubvs.u16','vhsubvc.u16','vhsubhi.u16','vhsubls.u16','vhsubge.u16','vhsublt.u16','vhsubgt.u16','vhsuble.u16',
+ 'vhsubeq.u32','vhsubne.u32','vhsubcs.u32','vhsubhs.u32','vhsubcc.u32','vhsublo.u32','vhsubmi.u32','vhsubpl.u32','vhsubvs.u32','vhsubvc.u32','vhsubhi.u32','vhsubls.u32','vhsubge.u32','vhsublt.u32','vhsubgt.u32','vhsuble.u32',
+
+ 'vpadaleq.u8','vpadalne.u8','vpadalcs.u8','vpadalhs.u8','vpadalcc.u8','vpadallo.u8','vpadalmi.u8','vpadalpl.u8','vpadalvs.u8','vpadalvc.u8','vpadalhi.u8','vpadalls.u8','vpadalge.u8','vpadallt.u8','vpadalgt.u8','vpadalle.u8',
+ 'vpadaleq.u16','vpadalne.u16','vpadalcs.u16','vpadalhs.u16','vpadalcc.u16','vpadallo.u16','vpadalmi.u16','vpadalpl.u16','vpadalvs.u16','vpadalvc.u16','vpadalhi.u16','vpadalls.u16','vpadalge.u16','vpadallt.u16','vpadalgt.u16','vpadalle.u16',
+ 'vpadaleq.u32','vpadalne.u32','vpadalcs.u32','vpadalhs.u32','vpadalcc.u32','vpadallo.u32','vpadalmi.u32','vpadalpl.u32','vpadalvs.u32','vpadalvc.u32','vpadalhi.u32','vpadalls.u32','vpadalge.u32','vpadallt.u32','vpadalgt.u32','vpadalle.u32',
+
+ 'vpaddleq.u8','vpaddlne.u8','vpaddlcs.u8','vpaddlhs.u8','vpaddlcc.u8','vpaddllo.u8','vpaddlmi.u8','vpaddlpl.u8','vpaddlvs.u8','vpaddlvc.u8','vpaddlhi.u8','vpaddlls.u8','vpaddlge.u8','vpaddllt.u8','vpaddlgt.u8','vpaddlle.u8',
+ 'vpaddleq.u16','vpaddlne.u16','vpaddlcs.u16','vpaddlhs.u16','vpaddlcc.u16','vpaddllo.u16','vpaddlmi.u16','vpaddlpl.u16','vpaddlvs.u16','vpaddlvc.u16','vpaddlhi.u16','vpaddlls.u16','vpaddlge.u16','vpaddllt.u16','vpaddlgt.u16','vpaddlle.u16',
+ 'vpaddleq.u32','vpaddlne.u32','vpaddlcs.u32','vpaddlhs.u32','vpaddlcc.u32','vpaddllo.u32','vpaddlmi.u32','vpaddlpl.u32','vpaddlvs.u32','vpaddlvc.u32','vpaddlhi.u32','vpaddlls.u32','vpaddlge.u32','vpaddllt.u32','vpaddlgt.u32','vpaddlle.u32',
+
+ 'vcgeeq.u8','vcgene.u8','vcgecs.u8','vcgehs.u8','vcgecc.u8','vcgelo.u8','vcgemi.u8','vcgepl.u8','vcgevs.u8','vcgevc.u8','vcgehi.u8','vcgels.u8','vcgege.u8','vcgelt.u8','vcgegt.u8','vcgele.u8',
+ 'vcgeeq.u16','vcgene.u16','vcgecs.u16','vcgehs.u16','vcgecc.u16','vcgelo.u16','vcgemi.u16','vcgepl.u16','vcgevs.u16','vcgevc.u16','vcgehi.u16','vcgels.u16','vcgege.u16','vcgelt.u16','vcgegt.u16','vcgele.u16',
+ 'vcgeeq.u32','vcgene.u32','vcgecs.u32','vcgehs.u32','vcgecc.u32','vcgelo.u32','vcgemi.u32','vcgepl.u32','vcgevs.u32','vcgevc.u32','vcgehi.u32','vcgels.u32','vcgege.u32','vcgelt.u32','vcgegt.u32','vcgele.u32',
+
+ 'vcleeq.u8','vclene.u8','vclecs.u8','vclehs.u8','vclecc.u8','vclelo.u8','vclemi.u8','vclepl.u8','vclevs.u8','vclevc.u8','vclehi.u8','vclels.u8','vclege.u8','vclelt.u8','vclegt.u8','vclele.u8',
+ 'vcleeq.u16','vclene.u16','vclecs.u16','vclehs.u16','vclecc.u16','vclelo.u16','vclemi.u16','vclepl.u16','vclevs.u16','vclevc.u16','vclehi.u16','vclels.u16','vclege.u16','vclelt.u16','vclegt.u16','vclele.u16',
+ 'vcleeq.u32','vclene.u32','vclecs.u32','vclehs.u32','vclecc.u32','vclelo.u32','vclemi.u32','vclepl.u32','vclevs.u32','vclevc.u32','vclehi.u32','vclels.u32','vclege.u32','vclelt.u32','vclegt.u32','vclele.u32',
+
+ 'vcgteq.u8','vcgtne.u8','vcgtcs.u8','vcgths.u8','vcgtcc.u8','vcgtlo.u8','vcgtmi.u8','vcgtpl.u8','vcgtvs.u8','vcgtvc.u8','vcgthi.u8','vcgtls.u8','vcgtge.u8','vcgtlt.u8','vcgtgt.u8','vcgtle.u8',
+ 'vcgteq.u16','vcgtne.u16','vcgtcs.u16','vcgths.u16','vcgtcc.u16','vcgtlo.u16','vcgtmi.u16','vcgtpl.u16','vcgtvs.u16','vcgtvc.u16','vcgthi.u16','vcgtls.u16','vcgtge.u16','vcgtlt.u16','vcgtgt.u16','vcgtle.u16',
+ 'vcgteq.u32','vcgtne.u32','vcgtcs.u32','vcgths.u32','vcgtcc.u32','vcgtlo.u32','vcgtmi.u32','vcgtpl.u32','vcgtvs.u32','vcgtvc.u32','vcgthi.u32','vcgtls.u32','vcgtge.u32','vcgtlt.u32','vcgtgt.u32','vcgtle.u32',
+
+ 'vclteq.u8','vcltne.u8','vcltcs.u8','vclths.u8','vcltcc.u8','vcltlo.u8','vcltmi.u8','vcltpl.u8','vcltvs.u8','vcltvc.u8','vclthi.u8','vcltls.u8','vcltge.u8','vcltlt.u8','vcltgt.u8','vcltle.u8',
+ 'vclteq.u16','vcltne.u16','vcltcs.u16','vclths.u16','vcltcc.u16','vcltlo.u16','vcltmi.u16','vcltpl.u16','vcltvs.u16','vcltvc.u16','vclthi.u16','vcltls.u16','vcltge.u16','vcltlt.u16','vcltgt.u16','vcltle.u16',
+ 'vclteq.u32','vcltne.u32','vcltcs.u32','vclths.u32','vcltcc.u32','vcltlo.u32','vcltmi.u32','vcltpl.u32','vcltvs.u32','vcltvc.u32','vclthi.u32','vcltls.u32','vcltge.u32','vcltlt.u32','vcltgt.u32','vcltle.u32',
+
+ 'vmaxeq.u8','vmaxne.u8','vmaxcs.u8','vmaxhs.u8','vmaxcc.u8','vmaxlo.u8','vmaxmi.u8','vmaxpl.u8','vmaxvs.u8','vmaxvc.u8','vmaxhi.u8','vmaxls.u8','vmaxge.u8','vmaxlt.u8','vmaxgt.u8','vmaxle.u8',
+ 'vmaxeq.u16','vmaxne.u16','vmaxcs.u16','vmaxhs.u16','vmaxcc.u16','vmaxlo.u16','vmaxmi.u16','vmaxpl.u16','vmaxvs.u16','vmaxvc.u16','vmaxhi.u16','vmaxls.u16','vmaxge.u16','vmaxlt.u16','vmaxgt.u16','vmaxle.u16',
+ 'vmaxeq.u32','vmaxne.u32','vmaxcs.u32','vmaxhs.u32','vmaxcc.u32','vmaxlo.u32','vmaxmi.u32','vmaxpl.u32','vmaxvs.u32','vmaxvc.u32','vmaxhi.u32','vmaxls.u32','vmaxge.u32','vmaxlt.u32','vmaxgt.u32','vmaxle.u32',
+
+ 'vmineq.u8','vminne.u8','vmincs.u8','vminhs.u8','vmincc.u8','vminlo.u8','vminmi.u8','vminpl.u8','vminvs.u8','vminvc.u8','vminhi.u8','vminls.u8','vminge.u8','vminlt.u8','vmingt.u8','vminle.u8',
+ 'vmineq.u16','vminne.u16','vmincs.u16','vminhs.u16','vmincc.u16','vminlo.u16','vminmi.u16','vminpl.u16','vminvs.u16','vminvc.u16','vminhi.u16','vminls.u16','vminge.u16','vminlt.u16','vmingt.u16','vminle.u16',
+ 'vmineq.u32','vminne.u32','vmincs.u32','vminhs.u32','vmincc.u32','vminlo.u32','vminmi.u32','vminpl.u32','vminvs.u32','vminvc.u32','vminhi.u32','vminls.u32','vminge.u32','vminlt.u32','vmingt.u32','vminle.u32',
+
+ 'vmlaleq.u8','vmlalne.u8','vmlalcs.u8','vmlalhs.u8','vmlalcc.u8','vmlallo.u8','vmlalmi.u8','vmlalpl.u8','vmlalvs.u8','vmlalvc.u8','vmlalhi.u8','vmlalls.u8','vmlalge.u8','vmlallt.u8','vmlalgt.u8','vmlalle.u8',
+ 'vmlaleq.u16','vmlalne.u16','vmlalcs.u16','vmlalhs.u16','vmlalcc.u16','vmlallo.u16','vmlalmi.u16','vmlalpl.u16','vmlalvs.u16','vmlalvc.u16','vmlalhi.u16','vmlalls.u16','vmlalge.u16','vmlallt.u16','vmlalgt.u16','vmlalle.u16',
+ 'vmlaleq.u32','vmlalne.u32','vmlalcs.u32','vmlalhs.u32','vmlalcc.u32','vmlallo.u32','vmlalmi.u32','vmlalpl.u32','vmlalvs.u32','vmlalvc.u32','vmlalhi.u32','vmlalls.u32','vmlalge.u32','vmlallt.u32','vmlalgt.u32','vmlalle.u32',
+
+ 'vmlsleq.u8','vmlslne.u8','vmlslcs.u8','vmlslhs.u8','vmlslcc.u8','vmlsllo.u8','vmlslmi.u8','vmlslpl.u8','vmlslvs.u8','vmlslvc.u8','vmlslhi.u8','vmlslls.u8','vmlslge.u8','vmlsllt.u8','vmlslgt.u8','vmlslle.u8',
+ 'vmlsleq.u16','vmlslne.u16','vmlslcs.u16','vmlslhs.u16','vmlslcc.u16','vmlsllo.u16','vmlslmi.u16','vmlslpl.u16','vmlslvs.u16','vmlslvc.u16','vmlslhi.u16','vmlslls.u16','vmlslge.u16','vmlsllt.u16','vmlslgt.u16','vmlslle.u16',
+ 'vmlsleq.u32','vmlslne.u32','vmlslcs.u32','vmlslhs.u32','vmlslcc.u32','vmlsllo.u32','vmlslmi.u32','vmlslpl.u32','vmlslvs.u32','vmlslvc.u32','vmlslhi.u32','vmlslls.u32','vmlslge.u32','vmlsllt.u32','vmlslgt.u32','vmlslle.u32',
+
+ 'vmulleq.u8','vmullne.u8','vmullcs.u8','vmullhs.u8','vmullcc.u8','vmulllo.u8','vmullmi.u8','vmullpl.u8','vmullvs.u8','vmullvc.u8','vmullhi.u8','vmullls.u8','vmullge.u8','vmulllt.u8','vmullgt.u8','vmullle.u8',
+ 'vmulleq.u16','vmullne.u16','vmullcs.u16','vmullhs.u16','vmullcc.u16','vmulllo.u16','vmullmi.u16','vmullpl.u16','vmullvs.u16','vmullvc.u16','vmullhi.u16','vmullls.u16','vmullge.u16','vmulllt.u16','vmullgt.u16','vmullle.u16',
+ 'vmulleq.u32','vmullne.u32','vmullcs.u32','vmullhs.u32','vmullcc.u32','vmulllo.u32','vmullmi.u32','vmullpl.u32','vmullvs.u32','vmullvc.u32','vmullhi.u32','vmullls.u32','vmullge.u32','vmulllt.u32','vmullgt.u32','vmullle.u32',
+
+ 'vmovleq.u8','vmovlne.u8','vmovlcs.u8','vmovlhs.u8','vmovlcc.u8','vmovllo.u8','vmovlmi.u8','vmovlpl.u8','vmovlvs.u8','vmovlvc.u8','vmovlhi.u8','vmovlls.u8','vmovlge.u8','vmovllt.u8','vmovlgt.u8','vmovlle.u8',
+ 'vmovleq.u16','vmovlne.u16','vmovlcs.u16','vmovlhs.u16','vmovlcc.u16','vmovllo.u16','vmovlmi.u16','vmovlpl.u16','vmovlvs.u16','vmovlvc.u16','vmovlhi.u16','vmovlls.u16','vmovlge.u16','vmovllt.u16','vmovlgt.u16','vmovlle.u16',
+ 'vmovleq.u32','vmovlne.u32','vmovlcs.u32','vmovlhs.u32','vmovlcc.u32','vmovllo.u32','vmovlmi.u32','vmovlpl.u32','vmovlvs.u32','vmovlvc.u32','vmovlhi.u32','vmovlls.u32','vmovlge.u32','vmovllt.u32','vmovlgt.u32','vmovlle.u32',
+
+ 'vshleq.u8','vshlne.u8','vshlcs.u8','vshlhs.u8','vshlcc.u8','vshllo.u8','vshlmi.u8','vshlpl.u8','vshlvs.u8','vshlvc.u8','vshlhi.u8','vshlls.u8','vshlge.u8','vshllt.u8','vshlgt.u8','vshlle.u8',
+ 'vshleq.u16','vshlne.u16','vshlcs.u16','vshlhs.u16','vshlcc.u16','vshllo.u16','vshlmi.u16','vshlpl.u16','vshlvs.u16','vshlvc.u16','vshlhi.u16','vshlls.u16','vshlge.u16','vshllt.u16','vshlgt.u16','vshlle.u16',
+ 'vshleq.u32','vshlne.u32','vshlcs.u32','vshlhs.u32','vshlcc.u32','vshllo.u32','vshlmi.u32','vshlpl.u32','vshlvs.u32','vshlvc.u32','vshlhi.u32','vshlls.u32','vshlge.u32','vshllt.u32','vshlgt.u32','vshlle.u32',
+ 'vshleq.u64','vshlne.u64','vshlcs.u64','vshlhs.u64','vshlcc.u64','vshllo.u64','vshlmi.u64','vshlpl.u64','vshlvs.u64','vshlvc.u64','vshlhi.u64','vshlls.u64','vshlge.u64','vshllt.u64','vshlgt.u64','vshlle.u64',
+
+ 'vshlleq.u8','vshllne.u8','vshllcs.u8','vshllhs.u8','vshllcc.u8','vshlllo.u8','vshllmi.u8','vshllpl.u8','vshllvs.u8','vshllvc.u8','vshllhi.u8','vshllls.u8','vshllge.u8','vshlllt.u8','vshllgt.u8','vshllle.u8',
+ 'vshlleq.u16','vshllne.u16','vshllcs.u16','vshllhs.u16','vshllcc.u16','vshlllo.u16','vshllmi.u16','vshllpl.u16','vshllvs.u16','vshllvc.u16','vshllhi.u16','vshllls.u16','vshllge.u16','vshlllt.u16','vshllgt.u16','vshllle.u16',
+ 'vshlleq.u32','vshllne.u32','vshllcs.u32','vshllhs.u32','vshllcc.u32','vshlllo.u32','vshllmi.u32','vshllpl.u32','vshllvs.u32','vshllvc.u32','vshllhi.u32','vshllls.u32','vshllge.u32','vshlllt.u32','vshllgt.u32','vshllle.u32',
+
+ 'vshreq.u8','vshrne.u8','vshrcs.u8','vshrhs.u8','vshrcc.u8','vshrlo.u8','vshrmi.u8','vshrpl.u8','vshrvs.u8','vshrvc.u8','vshrhi.u8','vshrls.u8','vshrge.u8','vshrlt.u8','vshrgt.u8','vshrle.u8',
+ 'vshreq.u16','vshrne.u16','vshrcs.u16','vshrhs.u16','vshrcc.u16','vshrlo.u16','vshrmi.u16','vshrpl.u16','vshrvs.u16','vshrvc.u16','vshrhi.u16','vshrls.u16','vshrge.u16','vshrlt.u16','vshrgt.u16','vshrle.u16',
+ 'vshreq.u32','vshrne.u32','vshrcs.u32','vshrhs.u32','vshrcc.u32','vshrlo.u32','vshrmi.u32','vshrpl.u32','vshrvs.u32','vshrvc.u32','vshrhi.u32','vshrls.u32','vshrge.u32','vshrlt.u32','vshrgt.u32','vshrle.u32',
+ 'vshreq.u64','vshrne.u64','vshrcs.u64','vshrhs.u64','vshrcc.u64','vshrlo.u64','vshrmi.u64','vshrpl.u64','vshrvs.u64','vshrvc.u64','vshrhi.u64','vshrls.u64','vshrge.u64','vshrlt.u64','vshrgt.u64','vshrle.u64',
+
+ 'vsraeq.u8','vsrane.u8','vsracs.u8','vsrahs.u8','vsracc.u8','vsralo.u8','vsrami.u8','vsrapl.u8','vsravs.u8','vsravc.u8','vsrahi.u8','vsrals.u8','vsrage.u8','vsralt.u8','vsragt.u8','vsrale.u8',
+ 'vsraeq.u16','vsrane.u16','vsracs.u16','vsrahs.u16','vsracc.u16','vsralo.u16','vsrami.u16','vsrapl.u16','vsravs.u16','vsravc.u16','vsrahi.u16','vsrals.u16','vsrage.u16','vsralt.u16','vsragt.u16','vsrale.u16',
+ 'vsraeq.u32','vsrane.u32','vsracs.u32','vsrahs.u32','vsracc.u32','vsralo.u32','vsrami.u32','vsrapl.u32','vsravs.u32','vsravc.u32','vsrahi.u32','vsrals.u32','vsrage.u32','vsralt.u32','vsragt.u32','vsrale.u32',
+ 'vsraeq.u64','vsrane.u64','vsracs.u64','vsrahs.u64','vsracc.u64','vsralo.u64','vsrami.u64','vsrapl.u64','vsravs.u64','vsravc.u64','vsrahi.u64','vsrals.u64','vsrage.u64','vsralt.u64','vsragt.u64','vsrale.u64',
+
+ 'vpmaxeq.u8','vpmaxne.u8','vpmaxcs.u8','vpmaxhs.u8','vpmaxcc.u8','vpmaxlo.u8','vpmaxmi.u8','vpmaxpl.u8','vpmaxvs.u8','vpmaxvc.u8','vpmaxhi.u8','vpmaxls.u8','vpmaxge.u8','vpmaxlt.u8','vpmaxgt.u8','vpmaxle.u8',
+ 'vpmaxeq.u16','vpmaxne.u16','vpmaxcs.u16','vpmaxhs.u16','vpmaxcc.u16','vpmaxlo.u16','vpmaxmi.u16','vpmaxpl.u16','vpmaxvs.u16','vpmaxvc.u16','vpmaxhi.u16','vpmaxls.u16','vpmaxge.u16','vpmaxlt.u16','vpmaxgt.u16','vpmaxle.u16',
+ 'vpmaxeq.u32','vpmaxne.u32','vpmaxcs.u32','vpmaxhs.u32','vpmaxcc.u32','vpmaxlo.u32','vpmaxmi.u32','vpmaxpl.u32','vpmaxvs.u32','vpmaxvc.u32','vpmaxhi.u32','vpmaxls.u32','vpmaxge.u32','vpmaxlt.u32','vpmaxgt.u32','vpmaxle.u32',
+
+ 'vpmineq.u8','vpminne.u8','vpmincs.u8','vpminhs.u8','vpmincc.u8','vpminlo.u8','vpminmi.u8','vpminpl.u8','vpminvs.u8','vpminvc.u8','vpminhi.u8','vpminls.u8','vpminge.u8','vpminlt.u8','vpmingt.u8','vpminle.u8',
+ 'vpmineq.u16','vpminne.u16','vpmincs.u16','vpminhs.u16','vpmincc.u16','vpminlo.u16','vpminmi.u16','vpminpl.u16','vpminvs.u16','vpminvc.u16','vpminhi.u16','vpminls.u16','vpminge.u16','vpminlt.u16','vpmingt.u16','vpminle.u16',
+ 'vpmineq.u32','vpminne.u32','vpmincs.u32','vpminhs.u32','vpmincc.u32','vpminlo.u32','vpminmi.u32','vpminpl.u32','vpminvs.u32','vpminvc.u32','vpminhi.u32','vpminls.u32','vpminge.u32','vpminlt.u32','vpmingt.u32','vpminle.u32',
+
+ 'vqaddeq.u8','vqaddne.u8','vqaddcs.u8','vqaddhs.u8','vqaddcc.u8','vqaddlo.u8','vqaddmi.u8','vqaddpl.u8','vqaddvs.u8','vqaddvc.u8','vqaddhi.u8','vqaddls.u8','vqaddge.u8','vqaddlt.u8','vqaddgt.u8','vqaddle.u8',
+ 'vqaddeq.u16','vqaddne.u16','vqaddcs.u16','vqaddhs.u16','vqaddcc.u16','vqaddlo.u16','vqaddmi.u16','vqaddpl.u16','vqaddvs.u16','vqaddvc.u16','vqaddhi.u16','vqaddls.u16','vqaddge.u16','vqaddlt.u16','vqaddgt.u16','vqaddle.u16',
+ 'vqaddeq.u32','vqaddne.u32','vqaddcs.u32','vqaddhs.u32','vqaddcc.u32','vqaddlo.u32','vqaddmi.u32','vqaddpl.u32','vqaddvs.u32','vqaddvc.u32','vqaddhi.u32','vqaddls.u32','vqaddge.u32','vqaddlt.u32','vqaddgt.u32','vqaddle.u32',
+ 'vqaddeq.u64','vqaddne.u64','vqaddcs.u64','vqaddhs.u64','vqaddcc.u64','vqaddlo.u64','vqaddmi.u64','vqaddpl.u64','vqaddvs.u64','vqaddvc.u64','vqaddhi.u64','vqaddls.u64','vqaddge.u64','vqaddlt.u64','vqaddgt.u64','vqaddle.u64',
+
+ 'vqsubeq.u8','vqsubne.u8','vqsubcs.u8','vqsubhs.u8','vqsubcc.u8','vqsublo.u8','vqsubmi.u8','vqsubpl.u8','vqsubvs.u8','vqsubvc.u8','vqsubhi.u8','vqsubls.u8','vqsubge.u8','vqsublt.u8','vqsubgt.u8','vqsuble.u8',
+ 'vqsubeq.u16','vqsubne.u16','vqsubcs.u16','vqsubhs.u16','vqsubcc.u16','vqsublo.u16','vqsubmi.u16','vqsubpl.u16','vqsubvs.u16','vqsubvc.u16','vqsubhi.u16','vqsubls.u16','vqsubge.u16','vqsublt.u16','vqsubgt.u16','vqsuble.u16',
+ 'vqsubeq.u32','vqsubne.u32','vqsubcs.u32','vqsubhs.u32','vqsubcc.u32','vqsublo.u32','vqsubmi.u32','vqsubpl.u32','vqsubvs.u32','vqsubvc.u32','vqsubhi.u32','vqsubls.u32','vqsubge.u32','vqsublt.u32','vqsubgt.u32','vqsuble.u32',
+ 'vqsubeq.u64','vqsubne.u64','vqsubcs.u64','vqsubhs.u64','vqsubcc.u64','vqsublo.u64','vqsubmi.u64','vqsubpl.u64','vqsubvs.u64','vqsubvc.u64','vqsubhi.u64','vqsubls.u64','vqsubge.u64','vqsublt.u64','vqsubgt.u64','vqsuble.u64',
+
+ 'vqmovneq.u16','vqmovnne.u16','vqmovncs.u16','vqmovnhs.u16','vqmovncc.u16','vqmovnlo.u16','vqmovnmi.u16','vqmovnpl.u16','vqmovnvs.u16','vqmovnvc.u16','vqmovnhi.u16','vqmovnls.u16','vqmovnge.u16','vqmovnlt.u16','vqmovngt.u16','vqmovnle.u16',
+ 'vqmovneq.u32','vqmovnne.u32','vqmovncs.u32','vqmovnhs.u32','vqmovncc.u32','vqmovnlo.u32','vqmovnmi.u32','vqmovnpl.u32','vqmovnvs.u32','vqmovnvc.u32','vqmovnhi.u32','vqmovnls.u32','vqmovnge.u32','vqmovnlt.u32','vqmovngt.u32','vqmovnle.u32',
+ 'vqmovneq.u64','vqmovnne.u64','vqmovncs.u64','vqmovnhs.u64','vqmovncc.u64','vqmovnlo.u64','vqmovnmi.u64','vqmovnpl.u64','vqmovnvs.u64','vqmovnvc.u64','vqmovnhi.u64','vqmovnls.u64','vqmovnge.u64','vqmovnlt.u64','vqmovngt.u64','vqmovnle.u64',
+
+ 'vqshleq.u8','vqshlne.u8','vqshlcs.u8','vqshlhs.u8','vqshlcc.u8','vqshllo.u8','vqshlmi.u8','vqshlpl.u8','vqshlvs.u8','vqshlvc.u8','vqshlhi.u8','vqshlls.u8','vqshlge.u8','vqshllt.u8','vqshlgt.u8','vqshlle.u8',
+ 'vqshleq.u16','vqshlne.u16','vqshlcs.u16','vqshlhs.u16','vqshlcc.u16','vqshllo.u16','vqshlmi.u16','vqshlpl.u16','vqshlvs.u16','vqshlvc.u16','vqshlhi.u16','vqshlls.u16','vqshlge.u16','vqshllt.u16','vqshlgt.u16','vqshlle.u16',
+ 'vqshleq.u32','vqshlne.u32','vqshlcs.u32','vqshlhs.u32','vqshlcc.u32','vqshllo.u32','vqshlmi.u32','vqshlpl.u32','vqshlvs.u32','vqshlvc.u32','vqshlhi.u32','vqshlls.u32','vqshlge.u32','vqshllt.u32','vqshlgt.u32','vqshlle.u32',
+ 'vqshleq.u64','vqshlne.u64','vqshlcs.u64','vqshlhs.u64','vqshlcc.u64','vqshllo.u64','vqshlmi.u64','vqshlpl.u64','vqshlvs.u64','vqshlvc.u64','vqshlhi.u64','vqshlls.u64','vqshlge.u64','vqshllt.u64','vqshlgt.u64','vqshlle.u64',
+
+ 'vqshrneq.u16','vqshrnne.u16','vqshrncs.u16','vqshrnhs.u16','vqshrncc.u16','vqshrnlo.u16','vqshrnmi.u16','vqshrnpl.u16','vqshrnvs.u16','vqshrnvc.u16','vqshrnhi.u16','vqshrnls.u16','vqshrnge.u16','vqshrnlt.u16','vqshrngt.u16','vqshrnle.u16',
+ 'vqshrneq.u32','vqshrnne.u32','vqshrncs.u32','vqshrnhs.u32','vqshrncc.u32','vqshrnlo.u32','vqshrnmi.u32','vqshrnpl.u32','vqshrnvs.u32','vqshrnvc.u32','vqshrnhi.u32','vqshrnls.u32','vqshrnge.u32','vqshrnlt.u32','vqshrngt.u32','vqshrnle.u32',
+ 'vqshrneq.u64','vqshrnne.u64','vqshrncs.u64','vqshrnhs.u64','vqshrncc.u64','vqshrnlo.u64','vqshrnmi.u64','vqshrnpl.u64','vqshrnvs.u64','vqshrnvc.u64','vqshrnhi.u64','vqshrnls.u64','vqshrnge.u64','vqshrnlt.u64','vqshrngt.u64','vqshrnle.u64',
+
+ 'vqrshleq.u8','vqrshlne.u8','vqrshlcs.u8','vqrshlhs.u8','vqrshlcc.u8','vqrshllo.u8','vqrshlmi.u8','vqrshlpl.u8','vqrshlvs.u8','vqrshlvc.u8','vqrshlhi.u8','vqrshlls.u8','vqrshlge.u8','vqrshllt.u8','vqrshlgt.u8','vqrshlle.u8',
+ 'vqrshleq.u16','vqrshlne.u16','vqrshlcs.u16','vqrshlhs.u16','vqrshlcc.u16','vqrshllo.u16','vqrshlmi.u16','vqrshlpl.u16','vqrshlvs.u16','vqrshlvc.u16','vqrshlhi.u16','vqrshlls.u16','vqrshlge.u16','vqrshllt.u16','vqrshlgt.u16','vqrshlle.u16',
+ 'vqrshleq.u32','vqrshlne.u32','vqrshlcs.u32','vqrshlhs.u32','vqrshlcc.u32','vqrshllo.u32','vqrshlmi.u32','vqrshlpl.u32','vqrshlvs.u32','vqrshlvc.u32','vqrshlhi.u32','vqrshlls.u32','vqrshlge.u32','vqrshllt.u32','vqrshlgt.u32','vqrshlle.u32',
+ 'vqrshleq.u64','vqrshlne.u64','vqrshlcs.u64','vqrshlhs.u64','vqrshlcc.u64','vqrshllo.u64','vqrshlmi.u64','vqrshlpl.u64','vqrshlvs.u64','vqrshlvc.u64','vqrshlhi.u64','vqrshlls.u64','vqrshlge.u64','vqrshllt.u64','vqrshlgt.u64','vqrshlle.u64',
+
+ 'vqrshrneq.u16','vqrshrnne.u16','vqrshrncs.u16','vqrshrnhs.u16','vqrshrncc.u16','vqrshrnlo.u16','vqrshrnmi.u16','vqrshrnpl.u16','vqrshrnvs.u16','vqrshrnvc.u16','vqrshrnhi.u16','vqrshrnls.u16','vqrshrnge.u16','vqrshrnlt.u16','vqrshrngt.u16','vqrshrnle.u16',
+ 'vqrshrneq.u32','vqrshrnne.u32','vqrshrncs.u32','vqrshrnhs.u32','vqrshrncc.u32','vqrshrnlo.u32','vqrshrnmi.u32','vqrshrnpl.u32','vqrshrnvs.u32','vqrshrnvc.u32','vqrshrnhi.u32','vqrshrnls.u32','vqrshrnge.u32','vqrshrnlt.u32','vqrshrngt.u32','vqrshrnle.u32',
+ 'vqrshrneq.u64','vqrshrnne.u64','vqrshrncs.u64','vqrshrnhs.u64','vqrshrncc.u64','vqrshrnlo.u64','vqrshrnmi.u64','vqrshrnpl.u64','vqrshrnvs.u64','vqrshrnvc.u64','vqrshrnhi.u64','vqrshrnls.u64','vqrshrnge.u64','vqrshrnlt.u64','vqrshrngt.u64','vqrshrnle.u64',
+
+ 'vrhaddeq.u8','vrhaddne.u8','vrhaddcs.u8','vrhaddhs.u8','vrhaddcc.u8','vrhaddlo.u8','vrhaddmi.u8','vrhaddpl.u8','vrhaddvs.u8','vrhaddvc.u8','vrhaddhi.u8','vrhaddls.u8','vrhaddge.u8','vrhaddlt.u8','vrhaddgt.u8','vrhaddle.u8',
+ 'vrhaddeq.u16','vrhaddne.u16','vrhaddcs.u16','vrhaddhs.u16','vrhaddcc.u16','vrhaddlo.u16','vrhaddmi.u16','vrhaddpl.u16','vrhaddvs.u16','vrhaddvc.u16','vrhaddhi.u16','vrhaddls.u16','vrhaddge.u16','vrhaddlt.u16','vrhaddgt.u16','vrhaddle.u16',
+ 'vrhaddeq.u32','vrhaddne.u32','vrhaddcs.u32','vrhaddhs.u32','vrhaddcc.u32','vrhaddlo.u32','vrhaddmi.u32','vrhaddpl.u32','vrhaddvs.u32','vrhaddvc.u32','vrhaddhi.u32','vrhaddls.u32','vrhaddge.u32','vrhaddlt.u32','vrhaddgt.u32','vrhaddle.u32',
+
+ 'vrshleq.u8','vrshlne.u8','vrshlcs.u8','vrshlhs.u8','vrshlcc.u8','vrshllo.u8','vrshlmi.u8','vrshlpl.u8','vrshlvs.u8','vrshlvc.u8','vrshlhi.u8','vrshlls.u8','vrshlge.u8','vrshllt.u8','vrshlgt.u8','vrshlle.u8',
+ 'vrshleq.u16','vrshlne.u16','vrshlcs.u16','vrshlhs.u16','vrshlcc.u16','vrshllo.u16','vrshlmi.u16','vrshlpl.u16','vrshlvs.u16','vrshlvc.u16','vrshlhi.u16','vrshlls.u16','vrshlge.u16','vrshllt.u16','vrshlgt.u16','vrshlle.u16',
+ 'vrshleq.u32','vrshlne.u32','vrshlcs.u32','vrshlhs.u32','vrshlcc.u32','vrshllo.u32','vrshlmi.u32','vrshlpl.u32','vrshlvs.u32','vrshlvc.u32','vrshlhi.u32','vrshlls.u32','vrshlge.u32','vrshllt.u32','vrshlgt.u32','vrshlle.u32',
+ 'vrshleq.u64','vrshlne.u64','vrshlcs.u64','vrshlhs.u64','vrshlcc.u64','vrshllo.u64','vrshlmi.u64','vrshlpl.u64','vrshlvs.u64','vrshlvc.u64','vrshlhi.u64','vrshlls.u64','vrshlge.u64','vrshllt.u64','vrshlgt.u64','vrshlle.u64',
+
+ 'vrshreq.u8','vrshrne.u8','vrshrcs.u8','vrshrhs.u8','vrshrcc.u8','vrshrlo.u8','vrshrmi.u8','vrshrpl.u8','vrshrvs.u8','vrshrvc.u8','vrshrhi.u8','vrshrls.u8','vrshrge.u8','vrshrlt.u8','vrshrgt.u8','vrshrle.u8',
+ 'vrshreq.u16','vrshrne.u16','vrshrcs.u16','vrshrhs.u16','vrshrcc.u16','vrshrlo.u16','vrshrmi.u16','vrshrpl.u16','vrshrvs.u16','vrshrvc.u16','vrshrhi.u16','vrshrls.u16','vrshrge.u16','vrshrlt.u16','vrshrgt.u16','vrshrle.u16',
+ 'vrshreq.u32','vrshrne.u32','vrshrcs.u32','vrshrhs.u32','vrshrcc.u32','vrshrlo.u32','vrshrmi.u32','vrshrpl.u32','vrshrvs.u32','vrshrvc.u32','vrshrhi.u32','vrshrls.u32','vrshrge.u32','vrshrlt.u32','vrshrgt.u32','vrshrle.u32',
+ 'vrshreq.u64','vrshrne.u64','vrshrcs.u64','vrshrhs.u64','vrshrcc.u64','vrshrlo.u64','vrshrmi.u64','vrshrpl.u64','vrshrvs.u64','vrshrvc.u64','vrshrhi.u64','vrshrls.u64','vrshrge.u64','vrshrlt.u64','vrshrgt.u64','vrshrle.u64',
+
+ 'vrsraeq.u8','vrsrane.u8','vrsracs.u8','vrsrahs.u8','vrsracc.u8','vrsralo.u8','vrsrami.u8','vrsrapl.u8','vrsravs.u8','vrsravc.u8','vrsrahi.u8','vrsrals.u8','vrsrage.u8','vrsralt.u8','vrsragt.u8','vrsrale.u8',
+ 'vrsraeq.u16','vrsrane.u16','vrsracs.u16','vrsrahs.u16','vrsracc.u16','vrsralo.u16','vrsrami.u16','vrsrapl.u16','vrsravs.u16','vrsravc.u16','vrsrahi.u16','vrsrals.u16','vrsrage.u16','vrsralt.u16','vrsragt.u16','vrsrale.u16',
+ 'vrsraeq.u32','vrsrane.u32','vrsracs.u32','vrsrahs.u32','vrsracc.u32','vrsralo.u32','vrsrami.u32','vrsrapl.u32','vrsravs.u32','vrsravc.u32','vrsrahi.u32','vrsrals.u32','vrsrage.u32','vrsralt.u32','vrsragt.u32','vrsrale.u32',
+ 'vrsraeq.u64','vrsrane.u64','vrsracs.u64','vrsrahs.u64','vrsracc.u64','vrsralo.u64','vrsrami.u64','vrsrapl.u64','vrsravs.u64','vrsravc.u64','vrsrahi.u64','vrsrals.u64','vrsrage.u64','vrsralt.u64','vrsragt.u64','vrsrale.u64',
+ ),
+ /* Conditional VFPv3 & NEON SIMD Floating-Point Instructions */
+ 34 => array(
+ 'vabdeq.f32','vabdne.f32','vabdcs.f32','vabdhs.f32','vabdcc.f32','vabdlo.f32','vabdmi.f32','vabdpl.f32','vabdvs.f32','vabdvc.f32','vabdhi.f32','vabdls.f32','vabdge.f32','vabdlt.f32','vabdgt.f32','vabdle.f32',
+
+ 'vabseq.f32','vabsne.f32','vabscs.f32','vabshs.f32','vabscc.f32','vabslo.f32','vabsmi.f32','vabspl.f32','vabsvs.f32','vabsvc.f32','vabshi.f32','vabsls.f32','vabsge.f32','vabslt.f32','vabsgt.f32','vabsle.f32',
+ 'vabseq.f64','vabsne.f64','vabscs.f64','vabshs.f64','vabscc.f64','vabslo.f64','vabsmi.f64','vabspl.f64','vabsvs.f64','vabsvc.f64','vabshi.f64','vabsls.f64','vabsge.f64','vabslt.f64','vabsgt.f64','vabsle.f64',
+
+ 'vacgeeq.f32','vacgene.f32','vacgecs.f32','vacgehs.f32','vacgecc.f32','vacgelo.f32','vacgemi.f32','vacgepl.f32','vacgevs.f32','vacgevc.f32','vacgehi.f32','vacgels.f32','vacgege.f32','vacgelt.f32','vacgegt.f32','vacgele.f32',
+ 'vacgteq.f32','vacgtne.f32','vacgtcs.f32','vacgths.f32','vacgtcc.f32','vacgtlo.f32','vacgtmi.f32','vacgtpl.f32','vacgtvs.f32','vacgtvc.f32','vacgthi.f32','vacgtls.f32','vacgtge.f32','vacgtlt.f32','vacgtgt.f32','vacgtle.f32',
+ 'vacleeq.f32','vaclene.f32','vaclecs.f32','vaclehs.f32','vaclecc.f32','vaclelo.f32','vaclemi.f32','vaclepl.f32','vaclevs.f32','vaclevc.f32','vaclehi.f32','vaclels.f32','vaclege.f32','vaclelt.f32','vaclegt.f32','vaclele.f32',
+ 'vaclteq.f32','vacltne.f32','vacltcs.f32','vaclths.f32','vacltcc.f32','vacltlo.f32','vacltmi.f32','vacltpl.f32','vacltvs.f32','vacltvc.f32','vaclthi.f32','vacltls.f32','vacltge.f32','vacltlt.f32','vacltgt.f32','vacltle.f32',
+
+ 'vaddeq.f32','vaddne.f32','vaddcs.f32','vaddhs.f32','vaddcc.f32','vaddlo.f32','vaddmi.f32','vaddpl.f32','vaddvs.f32','vaddvc.f32','vaddhi.f32','vaddls.f32','vaddge.f32','vaddlt.f32','vaddgt.f32','vaddle.f32',
+ 'vaddeq.f64','vaddne.f64','vaddcs.f64','vaddhs.f64','vaddcc.f64','vaddlo.f64','vaddmi.f64','vaddpl.f64','vaddvs.f64','vaddvc.f64','vaddhi.f64','vaddls.f64','vaddge.f64','vaddlt.f64','vaddgt.f64','vaddle.f64',
+
+ 'vceqeq.f32','vceqne.f32','vceqcs.f32','vceqhs.f32','vceqcc.f32','vceqlo.f32','vceqmi.f32','vceqpl.f32','vceqvs.f32','vceqvc.f32','vceqhi.f32','vceqls.f32','vceqge.f32','vceqlt.f32','vceqgt.f32','vceqle.f32',
+ 'vcgeeq.f32','vcgene.f32','vcgecs.f32','vcgehs.f32','vcgecc.f32','vcgelo.f32','vcgemi.f32','vcgepl.f32','vcgevs.f32','vcgevc.f32','vcgehi.f32','vcgels.f32','vcgege.f32','vcgelt.f32','vcgegt.f32','vcgele.f32',
+ 'vcleeq.f32','vclene.f32','vclecs.f32','vclehs.f32','vclecc.f32','vclelo.f32','vclemi.f32','vclepl.f32','vclevs.f32','vclevc.f32','vclehi.f32','vclels.f32','vclege.f32','vclelt.f32','vclegt.f32','vclele.f32',
+ 'vcgteq.f32','vcgtne.f32','vcgtcs.f32','vcgths.f32','vcgtcc.f32','vcgtlo.f32','vcgtmi.f32','vcgtpl.f32','vcgtvs.f32','vcgtvc.f32','vcgthi.f32','vcgtls.f32','vcgtge.f32','vcgtlt.f32','vcgtgt.f32','vcgtle.f32',
+ 'vclteq.f32','vcltne.f32','vcltcs.f32','vclths.f32','vcltcc.f32','vcltlo.f32','vcltmi.f32','vcltpl.f32','vcltvs.f32','vcltvc.f32','vclthi.f32','vcltls.f32','vcltge.f32','vcltlt.f32','vcltgt.f32','vcltle.f32',
+
+ 'vcmpeq.f32','vcmpne.f32','vcmpcs.f32','vcmphs.f32','vcmpcc.f32','vcmplo.f32','vcmpmi.f32','vcmppl.f32','vcmpvs.f32','vcmpvc.f32','vcmphi.f32','vcmpls.f32','vcmpge.f32','vcmplt.f32','vcmpgt.f32','vcmple.f32',
+ 'vcmpeq.f64','vcmpne.f64','vcmpcs.f64','vcmphs.f64','vcmpcc.f64','vcmplo.f64','vcmpmi.f64','vcmppl.f64','vcmpvs.f64','vcmpvc.f64','vcmphi.f64','vcmpls.f64','vcmpge.f64','vcmplt.f64','vcmpgt.f64','vcmple.f64',
+
+ 'vcmpeeq.f32','vcmpene.f32','vcmpecs.f32','vcmpehs.f32','vcmpecc.f32','vcmpelo.f32','vcmpemi.f32','vcmpepl.f32','vcmpevs.f32','vcmpevc.f32','vcmpehi.f32','vcmpels.f32','vcmpege.f32','vcmpelt.f32','vcmpegt.f32','vcmpele.f32',
+ 'vcmpeeq.f64','vcmpene.f64','vcmpecs.f64','vcmpehs.f64','vcmpecc.f64','vcmpelo.f64','vcmpemi.f64','vcmpepl.f64','vcmpevs.f64','vcmpevc.f64','vcmpehi.f64','vcmpels.f64','vcmpege.f64','vcmpelt.f64','vcmpegt.f64','vcmpele.f64',
+
+ 'vcvteq.s16.f32','vcvtne.s16.f32','vcvtcs.s16.f32','vcvths.s16.f32','vcvtcc.s16.f32','vcvtlo.s16.f32','vcvtmi.s16.f32','vcvtpl.s16.f32','vcvtvs.s16.f32','vcvtvc.s16.f32','vcvthi.s16.f32','vcvtls.s16.f32','vcvtge.s16.f32','vcvtlt.s16.f32','vcvtgt.s16.f32','vcvtle.s16.f32',
+ 'vcvteq.s16.f64','vcvtne.s16.f64','vcvtcs.s16.f64','vcvths.s16.f64','vcvtcc.s16.f64','vcvtlo.s16.f64','vcvtmi.s16.f64','vcvtpl.s16.f64','vcvtvs.s16.f64','vcvtvc.s16.f64','vcvthi.s16.f64','vcvtls.s16.f64','vcvtge.s16.f64','vcvtlt.s16.f64','vcvtgt.s16.f64','vcvtle.s16.f64',
+ 'vcvteq.s32.f32','vcvtne.s32.f32','vcvtcs.s32.f32','vcvths.s32.f32','vcvtcc.s32.f32','vcvtlo.s32.f32','vcvtmi.s32.f32','vcvtpl.s32.f32','vcvtvs.s32.f32','vcvtvc.s32.f32','vcvthi.s32.f32','vcvtls.s32.f32','vcvtge.s32.f32','vcvtlt.s32.f32','vcvtgt.s32.f32','vcvtle.s32.f32',
+ 'vcvteq.s32.f64','vcvtne.s32.f64','vcvtcs.s32.f64','vcvths.s32.f64','vcvtcc.s32.f64','vcvtlo.s32.f64','vcvtmi.s32.f64','vcvtpl.s32.f64','vcvtvs.s32.f64','vcvtvc.s32.f64','vcvthi.s32.f64','vcvtls.s32.f64','vcvtge.s32.f64','vcvtlt.s32.f64','vcvtgt.s32.f64','vcvtle.s32.f64',
+ 'vcvteq.u16.f32','vcvtne.u16.f32','vcvtcs.u16.f32','vcvths.u16.f32','vcvtcc.u16.f32','vcvtlo.u16.f32','vcvtmi.u16.f32','vcvtpl.u16.f32','vcvtvs.u16.f32','vcvtvc.u16.f32','vcvthi.u16.f32','vcvtls.u16.f32','vcvtge.u16.f32','vcvtlt.u16.f32','vcvtgt.u16.f32','vcvtle.u16.f32',
+ 'vcvteq.u16.f64','vcvtne.u16.f64','vcvtcs.u16.f64','vcvths.u16.f64','vcvtcc.u16.f64','vcvtlo.u16.f64','vcvtmi.u16.f64','vcvtpl.u16.f64','vcvtvs.u16.f64','vcvtvc.u16.f64','vcvthi.u16.f64','vcvtls.u16.f64','vcvtge.u16.f64','vcvtlt.u16.f64','vcvtgt.u16.f64','vcvtle.u16.f64',
+ 'vcvteq.u32.f32','vcvtne.u32.f32','vcvtcs.u32.f32','vcvths.u32.f32','vcvtcc.u32.f32','vcvtlo.u32.f32','vcvtmi.u32.f32','vcvtpl.u32.f32','vcvtvs.u32.f32','vcvtvc.u32.f32','vcvthi.u32.f32','vcvtls.u32.f32','vcvtge.u32.f32','vcvtlt.u32.f32','vcvtgt.u32.f32','vcvtle.u32.f32',
+ 'vcvteq.u32.f64','vcvtne.u32.f64','vcvtcs.u32.f64','vcvths.u32.f64','vcvtcc.u32.f64','vcvtlo.u32.f64','vcvtmi.u32.f64','vcvtpl.u32.f64','vcvtvs.u32.f64','vcvtvc.u32.f64','vcvthi.u32.f64','vcvtls.u32.f64','vcvtge.u32.f64','vcvtlt.u32.f64','vcvtgt.u32.f64','vcvtle.u32.f64',
+ 'vcvteq.f16.f32','vcvtne.f16.f32','vcvtcs.f16.f32','vcvths.f16.f32','vcvtcc.f16.f32','vcvtlo.f16.f32','vcvtmi.f16.f32','vcvtpl.f16.f32','vcvtvs.f16.f32','vcvtvc.f16.f32','vcvthi.f16.f32','vcvtls.f16.f32','vcvtge.f16.f32','vcvtlt.f16.f32','vcvtgt.f16.f32','vcvtle.f16.f32',
+ 'vcvteq.f32.s32','vcvtne.f32.s32','vcvtcs.f32.s32','vcvths.f32.s32','vcvtcc.f32.s32','vcvtlo.f32.s32','vcvtmi.f32.s32','vcvtpl.f32.s32','vcvtvs.f32.s32','vcvtvc.f32.s32','vcvthi.f32.s32','vcvtls.f32.s32','vcvtge.f32.s32','vcvtlt.f32.s32','vcvtgt.f32.s32','vcvtle.f32.s32',
+ 'vcvteq.f32.u32','vcvtne.f32.u32','vcvtcs.f32.u32','vcvths.f32.u32','vcvtcc.f32.u32','vcvtlo.f32.u32','vcvtmi.f32.u32','vcvtpl.f32.u32','vcvtvs.f32.u32','vcvtvc.f32.u32','vcvthi.f32.u32','vcvtls.f32.u32','vcvtge.f32.u32','vcvtlt.f32.u32','vcvtgt.f32.u32','vcvtle.f32.u32',
+ 'vcvteq.f32.f16','vcvtne.f32.f16','vcvtcs.f32.f16','vcvths.f32.f16','vcvtcc.f32.f16','vcvtlo.f32.f16','vcvtmi.f32.f16','vcvtpl.f32.f16','vcvtvs.f32.f16','vcvtvc.f32.f16','vcvthi.f32.f16','vcvtls.f32.f16','vcvtge.f32.f16','vcvtlt.f32.f16','vcvtgt.f32.f16','vcvtle.f32.f16',
+ 'vcvteq.f32.f64','vcvtne.f32.f64','vcvtcs.f32.f64','vcvths.f32.f64','vcvtcc.f32.f64','vcvtlo.f32.f64','vcvtmi.f32.f64','vcvtpl.f32.f64','vcvtvs.f32.f64','vcvtvc.f32.f64','vcvthi.f32.f64','vcvtls.f32.f64','vcvtge.f32.f64','vcvtlt.f32.f64','vcvtgt.f32.f64','vcvtle.f32.f64',
+ 'vcvteq.f64.s32','vcvtne.f64.s32','vcvtcs.f64.s32','vcvths.f64.s32','vcvtcc.f64.s32','vcvtlo.f64.s32','vcvtmi.f64.s32','vcvtpl.f64.s32','vcvtvs.f64.s32','vcvtvc.f64.s32','vcvthi.f64.s32','vcvtls.f64.s32','vcvtge.f64.s32','vcvtlt.f64.s32','vcvtgt.f64.s32','vcvtle.f64.s32',
+ 'vcvteq.f64.u32','vcvtne.f64.u32','vcvtcs.f64.u32','vcvths.f64.u32','vcvtcc.f64.u32','vcvtlo.f64.u32','vcvtmi.f64.u32','vcvtpl.f64.u32','vcvtvs.f64.u32','vcvtvc.f64.u32','vcvthi.f64.u32','vcvtls.f64.u32','vcvtge.f64.u32','vcvtlt.f64.u32','vcvtgt.f64.u32','vcvtle.f64.u32',
+ 'vcvteq.f64.f32','vcvtne.f64.f32','vcvtcs.f64.f32','vcvths.f64.f32','vcvtcc.f64.f32','vcvtlo.f64.f32','vcvtmi.f64.f32','vcvtpl.f64.f32','vcvtvs.f64.f32','vcvtvc.f64.f32','vcvthi.f64.f32','vcvtls.f64.f32','vcvtge.f64.f32','vcvtlt.f64.f32','vcvtgt.f64.f32','vcvtle.f64.f32',
+
+ 'vcvtreq.s32.f32','vcvtrne.s32.f32','vcvtrcs.s32.f32','vcvtrhs.s32.f32','vcvtrcc.s32.f32','vcvtrlo.s32.f32','vcvtrmi.s32.f32','vcvtrpl.s32.f32','vcvtrvs.s32.f32','vcvtrvc.s32.f32','vcvtrhi.s32.f32','vcvtrls.s32.f32','vcvtrge.s32.f32','vcvtrlt.s32.f32','vcvtrgt.s32.f32','vcvtrle.s32.f32',
+ 'vcvtreq.s32.f64','vcvtrne.s32.f64','vcvtrcs.s32.f64','vcvtrhs.s32.f64','vcvtrcc.s32.f64','vcvtrlo.s32.f64','vcvtrmi.s32.f64','vcvtrpl.s32.f64','vcvtrvs.s32.f64','vcvtrvc.s32.f64','vcvtrhi.s32.f64','vcvtrls.s32.f64','vcvtrge.s32.f64','vcvtrlt.s32.f64','vcvtrgt.s32.f64','vcvtrle.s32.f64',
+ 'vcvtreq.u32.f32','vcvtrne.u32.f32','vcvtrcs.u32.f32','vcvtrhs.u32.f32','vcvtrcc.u32.f32','vcvtrlo.u32.f32','vcvtrmi.u32.f32','vcvtrpl.u32.f32','vcvtrvs.u32.f32','vcvtrvc.u32.f32','vcvtrhi.u32.f32','vcvtrls.u32.f32','vcvtrge.u32.f32','vcvtrlt.u32.f32','vcvtrgt.u32.f32','vcvtrle.u32.f32',
+ 'vcvtreq.u32.f64','vcvtrne.u32.f64','vcvtrcs.u32.f64','vcvtrhs.u32.f64','vcvtrcc.u32.f64','vcvtrlo.u32.f64','vcvtrmi.u32.f64','vcvtrpl.u32.f64','vcvtrvs.u32.f64','vcvtrvc.u32.f64','vcvtrhi.u32.f64','vcvtrls.u32.f64','vcvtrge.u32.f64','vcvtrlt.u32.f64','vcvtrgt.u32.f64','vcvtrle.u32.f64',
+
+ 'vcvtbeq.f16.f32','vcvtbne.f16.f32','vcvtbcs.f16.f32','vcvtbhs.f16.f32','vcvtbcc.f16.f32','vcvtblo.f16.f32','vcvtbmi.f16.f32','vcvtbpl.f16.f32','vcvtbvs.f16.f32','vcvtbvc.f16.f32','vcvtbhi.f16.f32','vcvtbls.f16.f32','vcvtbge.f16.f32','vcvtblt.f16.f32','vcvtbgt.f16.f32','vcvtble.f16.f32',
+ 'vcvtbeq.f32.f16','vcvtbne.f32.f16','vcvtbcs.f32.f16','vcvtbhs.f32.f16','vcvtbcc.f32.f16','vcvtblo.f32.f16','vcvtbmi.f32.f16','vcvtbpl.f32.f16','vcvtbvs.f32.f16','vcvtbvc.f32.f16','vcvtbhi.f32.f16','vcvtbls.f32.f16','vcvtbge.f32.f16','vcvtblt.f32.f16','vcvtbgt.f32.f16','vcvtble.f32.f16',
+
+ 'vcvtteq.f16.f32','vcvttne.f16.f32','vcvttcs.f16.f32','vcvtths.f16.f32','vcvttcc.f16.f32','vcvttlo.f16.f32','vcvttmi.f16.f32','vcvttpl.f16.f32','vcvttvs.f16.f32','vcvttvc.f16.f32','vcvtthi.f16.f32','vcvttls.f16.f32','vcvttge.f16.f32','vcvttlt.f16.f32','vcvttgt.f16.f32','vcvttle.f16.f32',
+ 'vcvtteq.f32.f16','vcvttne.f32.f16','vcvttcs.f32.f16','vcvtths.f32.f16','vcvttcc.f32.f16','vcvttlo.f32.f16','vcvttmi.f32.f16','vcvttpl.f32.f16','vcvttvs.f32.f16','vcvttvc.f32.f16','vcvtthi.f32.f16','vcvttls.f32.f16','vcvttge.f32.f16','vcvttlt.f32.f16','vcvttgt.f32.f16','vcvttle.f32.f16',
+
+ 'vdiveq.f32','vdivne.f32','vdivcs.f32','vdivhs.f32','vdivcc.f32','vdivlo.f32','vdivmi.f32','vdivpl.f32','vdivvs.f32','vdivvc.f32','vdivhi.f32','vdivls.f32','vdivge.f32','vdivlt.f32','vdivgt.f32','vdivle.f32',
+ 'vdiveq.f64','vdivne.f64','vdivcs.f64','vdivhs.f64','vdivcc.f64','vdivlo.f64','vdivmi.f64','vdivpl.f64','vdivvs.f64','vdivvc.f64','vdivhi.f64','vdivls.f64','vdivge.f64','vdivlt.f64','vdivgt.f64','vdivle.f64',
+
+ 'vmaxeq.f32','vmaxne.f32','vmaxcs.f32','vmaxhs.f32','vmaxcc.f32','vmaxlo.f32','vmaxmi.f32','vmaxpl.f32','vmaxvs.f32','vmaxvc.f32','vmaxhi.f32','vmaxls.f32','vmaxge.f32','vmaxlt.f32','vmaxgt.f32','vmaxle.f32',
+ 'vmineq.f32','vminne.f32','vmincs.f32','vminhs.f32','vmincc.f32','vminlo.f32','vminmi.f32','vminpl.f32','vminvs.f32','vminvc.f32','vminhi.f32','vminls.f32','vminge.f32','vminlt.f32','vmingt.f32','vminle.f32',
+
+ 'vmlaeq.f32','vmlane.f32','vmlacs.f32','vmlahs.f32','vmlacc.f32','vmlalo.f32','vmlami.f32','vmlapl.f32','vmlavs.f32','vmlavc.f32','vmlahi.f32','vmlals.f32','vmlage.f32','vmlalt.f32','vmlagt.f32','vmlale.f32',
+ 'vmlaeq.f64','vmlane.f64','vmlacs.f64','vmlahs.f64','vmlacc.f64','vmlalo.f64','vmlami.f64','vmlapl.f64','vmlavs.f64','vmlavc.f64','vmlahi.f64','vmlals.f64','vmlage.f64','vmlalt.f64','vmlagt.f64','vmlale.f64',
+
+ 'vmlseq.f32','vmlsne.f32','vmlscs.f32','vmlshs.f32','vmlscc.f32','vmlslo.f32','vmlsmi.f32','vmlspl.f32','vmlsvs.f32','vmlsvc.f32','vmlshi.f32','vmlsls.f32','vmlsge.f32','vmlslt.f32','vmlsgt.f32','vmlsle.f32',
+ 'vmlseq.f64','vmlsne.f64','vmlscs.f64','vmlshs.f64','vmlscc.f64','vmlslo.f64','vmlsmi.f64','vmlspl.f64','vmlsvs.f64','vmlsvc.f64','vmlshi.f64','vmlsls.f64','vmlsge.f64','vmlslt.f64','vmlsgt.f64','vmlsle.f64',
+
+ 'vmuleq.f32','vmulne.f32','vmulcs.f32','vmulhs.f32','vmulcc.f32','vmullo.f32','vmulmi.f32','vmulpl.f32','vmulvs.f32','vmulvc.f32','vmulhi.f32','vmulls.f32','vmulge.f32','vmullt.f32','vmulgt.f32','vmulle.f32',
+ 'vmuleq.f64','vmulne.f64','vmulcs.f64','vmulhs.f64','vmulcc.f64','vmullo.f64','vmulmi.f64','vmulpl.f64','vmulvs.f64','vmulvc.f64','vmulhi.f64','vmulls.f64','vmulge.f64','vmullt.f64','vmulgt.f64','vmulle.f64',
+
+ 'vnegeq.f32','vnegne.f32','vnegcs.f32','vneghs.f32','vnegcc.f32','vneglo.f32','vnegmi.f32','vnegpl.f32','vnegvs.f32','vnegvc.f32','vneghi.f32','vnegls.f32','vnegge.f32','vneglt.f32','vneggt.f32','vnegle.f32',
+ 'vnegeq.f64','vnegne.f64','vnegcs.f64','vneghs.f64','vnegcc.f64','vneglo.f64','vnegmi.f64','vnegpl.f64','vnegvs.f64','vnegvc.f64','vneghi.f64','vnegls.f64','vnegge.f64','vneglt.f64','vneggt.f64','vnegle.f64',
+
+ 'vnmlaeq.f32','vnmlane.f32','vnmlacs.f32','vnmlahs.f32','vnmlacc.f32','vnmlalo.f32','vnmlami.f32','vnmlapl.f32','vnmlavs.f32','vnmlavc.f32','vnmlahi.f32','vnmlals.f32','vnmlage.f32','vnmlalt.f32','vnmlagt.f32','vnmlale.f32',
+ 'vnmlaeq.f64','vnmlane.f64','vnmlacs.f64','vnmlahs.f64','vnmlacc.f64','vnmlalo.f64','vnmlami.f64','vnmlapl.f64','vnmlavs.f64','vnmlavc.f64','vnmlahi.f64','vnmlals.f64','vnmlage.f64','vnmlalt.f64','vnmlagt.f64','vnmlale.f64',
+
+ 'vnmlseq.f32','vnmlsne.f32','vnmlscs.f32','vnmlshs.f32','vnmlscc.f32','vnmlslo.f32','vnmlsmi.f32','vnmlspl.f32','vnmlsvs.f32','vnmlsvc.f32','vnmlshi.f32','vnmlsls.f32','vnmlsge.f32','vnmlslt.f32','vnmlsgt.f32','vnmlsle.f32',
+ 'vnmlseq.f64','vnmlsne.f64','vnmlscs.f64','vnmlshs.f64','vnmlscc.f64','vnmlslo.f64','vnmlsmi.f64','vnmlspl.f64','vnmlsvs.f64','vnmlsvc.f64','vnmlshi.f64','vnmlsls.f64','vnmlsge.f64','vnmlslt.f64','vnmlsgt.f64','vnmlsle.f64',
+
+ 'vnmuleq.f64','vnmulne.f64','vnmulcs.f64','vnmulhs.f64','vnmulcc.f64','vnmullo.f64','vnmulmi.f64','vnmulpl.f64','vnmulvs.f64','vnmulvc.f64','vnmulhi.f64','vnmulls.f64','vnmulge.f64','vnmullt.f64','vnmulgt.f64','vnmulle.f64',
+ 'vnmuleq.f32','vnmulne.f32','vnmulcs.f32','vnmulhs.f32','vnmulcc.f32','vnmullo.f32','vnmulmi.f32','vnmulpl.f32','vnmulvs.f32','vnmulvc.f32','vnmulhi.f32','vnmulls.f32','vnmulge.f32','vnmullt.f32','vnmulgt.f32','vnmulle.f32',
+
+ 'vpaddeq.f32','vpaddne.f32','vpaddcs.f32','vpaddhs.f32','vpaddcc.f32','vpaddlo.f32','vpaddmi.f32','vpaddpl.f32','vpaddvs.f32','vpaddvc.f32','vpaddhi.f32','vpaddls.f32','vpaddge.f32','vpaddlt.f32','vpaddgt.f32','vpaddle.f32',
+
+ 'vpmaxeq.f32','vpmaxne.f32','vpmaxcs.f32','vpmaxhs.f32','vpmaxcc.f32','vpmaxlo.f32','vpmaxmi.f32','vpmaxpl.f32','vpmaxvs.f32','vpmaxvc.f32','vpmaxhi.f32','vpmaxls.f32','vpmaxge.f32','vpmaxlt.f32','vpmaxgt.f32','vpmaxle.f32',
+ 'vpmineq.f32','vpminne.f32','vpmincs.f32','vpminhs.f32','vpmincc.f32','vpminlo.f32','vpminmi.f32','vpminpl.f32','vpminvs.f32','vpminvc.f32','vpminhi.f32','vpminls.f32','vpminge.f32','vpminlt.f32','vpmingt.f32','vpminle.f32',
+
+ 'vrecpeeq.u32','vrecpene.u32','vrecpecs.u32','vrecpehs.u32','vrecpecc.u32','vrecpelo.u32','vrecpemi.u32','vrecpepl.u32','vrecpevs.u32','vrecpevc.u32','vrecpehi.u32','vrecpels.u32','vrecpege.u32','vrecpelt.u32','vrecpegt.u32','vrecpele.u32',
+ 'vrecpeeq.f32','vrecpene.f32','vrecpecs.f32','vrecpehs.f32','vrecpecc.f32','vrecpelo.f32','vrecpemi.f32','vrecpepl.f32','vrecpevs.f32','vrecpevc.f32','vrecpehi.f32','vrecpels.f32','vrecpege.f32','vrecpelt.f32','vrecpegt.f32','vrecpele.f32',
+ 'vrecpseq.f32','vrecpsne.f32','vrecpscs.f32','vrecpshs.f32','vrecpscc.f32','vrecpslo.f32','vrecpsmi.f32','vrecpspl.f32','vrecpsvs.f32','vrecpsvc.f32','vrecpshi.f32','vrecpsls.f32','vrecpsge.f32','vrecpslt.f32','vrecpsgt.f32','vrecpsle.f32',
+
+ 'vrsqrteeq.u32','vrsqrtene.u32','vrsqrtecs.u32','vrsqrtehs.u32','vrsqrtecc.u32','vrsqrtelo.u32','vrsqrtemi.u32','vrsqrtepl.u32','vrsqrtevs.u32','vrsqrtevc.u32','vrsqrtehi.u32','vrsqrtels.u32','vrsqrtege.u32','vrsqrtelt.u32','vrsqrtegt.u32','vrsqrtele.u32',
+ 'vrsqrteeq.f32','vrsqrtene.f32','vrsqrtecs.f32','vrsqrtehs.f32','vrsqrtecc.f32','vrsqrtelo.f32','vrsqrtemi.f32','vrsqrtepl.f32','vrsqrtevs.f32','vrsqrtevc.f32','vrsqrtehi.f32','vrsqrtels.f32','vrsqrtege.f32','vrsqrtelt.f32','vrsqrtegt.f32','vrsqrtele.f32',
+ 'vrsqrtseq.f32','vrsqrtsne.f32','vrsqrtscs.f32','vrsqrtshs.f32','vrsqrtscc.f32','vrsqrtslo.f32','vrsqrtsmi.f32','vrsqrtspl.f32','vrsqrtsvs.f32','vrsqrtsvc.f32','vrsqrtshi.f32','vrsqrtsls.f32','vrsqrtsge.f32','vrsqrtslt.f32','vrsqrtsgt.f32','vrsqrtsle.f32',
+
+ 'vsqrteq.f32','vsqrtne.f32','vsqrtcs.f32','vsqrths.f32','vsqrtcc.f32','vsqrtlo.f32','vsqrtmi.f32','vsqrtpl.f32','vsqrtvs.f32','vsqrtvc.f32','vsqrthi.f32','vsqrtls.f32','vsqrtge.f32','vsqrtlt.f32','vsqrtgt.f32','vsqrtle.f32',
+ 'vsqrteq.f64','vsqrtne.f64','vsqrtcs.f64','vsqrths.f64','vsqrtcc.f64','vsqrtlo.f64','vsqrtmi.f64','vsqrtpl.f64','vsqrtvs.f64','vsqrtvc.f64','vsqrthi.f64','vsqrtls.f64','vsqrtge.f64','vsqrtlt.f64','vsqrtgt.f64','vsqrtle.f64',
+
+ 'vsubeq.f32','vsubne.f32','vsubcs.f32','vsubhs.f32','vsubcc.f32','vsublo.f32','vsubmi.f32','vsubpl.f32','vsubvs.f32','vsubvc.f32','vsubhi.f32','vsubls.f32','vsubge.f32','vsublt.f32','vsubgt.f32','vsuble.f32',
+ 'vsubeq.f64','vsubne.f64','vsubcs.f64','vsubhs.f64','vsubcc.f64','vsublo.f64','vsubmi.f64','vsubpl.f64','vsubvs.f64','vsubvc.f64','vsubhi.f64','vsubls.f64','vsubge.f64','vsublt.f64','vsubgt.f64','vsuble.f64'
+ ),
+ /* Registers */
+ 35 => array(
+ /* General-Purpose Registers */
+ 'r0','r1','r2','r3','r4','r5','r6','r7',
+ 'r8','r9','r10','r11','r12','r13','r14','r15',
+ /* Scratch Registers */
+ 'a1','a2','a3','a4',
+ /* Variable Registers */
+ 'v1','v2','v3','v4','v5','v6','v7','v8',
+ /* Other Synonims for General-Purpose Registers */
+ 'sb','sl','fp','ip','sp','lr','pc',
+ /* WMMX Data Registers */
+ 'wr0','wr1','wr2','wr3','wr4','wr5','wr6','wr7',
+ 'wr8','wr9','wr10','wr11','wr12','wr13','wr14','wr15',
+ /* WMMX Control Registers */
+ 'wcid','wcon','wcssf','wcasf',
+ /* WMMX-Mapped General-Purpose Registers */
+ 'wcgr0','wcgr1','wcgr2','wcgr3',
+ /* VFPv3 Registers */
+ 's0','s1','s2','s3','s4','s5','s6','s7',
+ 's8','s9','s10','s11','s12','s13','s14','s15',
+ 's16','s17','s18','s19','s20','s21','s22','s23',
+ 's24','s25','s26','s27','s28','s29','s30','s31',
+ /* VFPv3/NEON Registers */
+ 'd0','d1','d2','d3','d4','d5','d6','d7',
+ 'd8','d9','d10','d11','d12','d13','d14','d15',
+ 'd16','d17','d18','d19','d20','d21','d22','d23',
+ 'd24','d25','d26','d27','d28','d29','d30','d31',
+ /* NEON Registers */
+ 'q0','q1','q2','q3','q4','q5','q6','q7',
+ 'q8','q9','q10','q11','q12','q13','q14','q15'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '(', ')',
+ '+', '-', '*', '/', '%',
+ '.', ',', ';', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ 8 => false,
+ 9 => false,
+ 10 => false,
+ 11 => false,
+ 12 => false,
+ 13 => false,
+ 14 => false,
+ 15 => false,
+ 16 => false,
+ 17 => false,
+ 18 => false,
+ 19 => false,
+ 20 => false,
+ 21 => false,
+ 22 => false,
+ 23 => false,
+ 24 => false,
+ 25 => false,
+ 26 => false,
+ 27 => false,
+ 28 => false,
+ 29 => false,
+ 30 => false,
+ 31 => false,
+ 32 => false,
+ 33 => false,
+ 34 => false,
+ 35 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ /* Unconditional Data Processing Instructions */
+ 1 => 'color: #00007f; font-weight: normal; font-style: normal;',
+ /* Conditional Data Processing Instructions */
+ 2 => 'color: #00007f; font-weight: normal; font-style: italic;',
+ /* Unconditional Memory Access Instructions */
+ 3 => 'color: #00007f; font-weight: normal; font-style: normal;',
+ /* Conditional Memory Access Instructions */
+ 4 => 'color: #00007f; font-weight: normal; font-style: italic;',
+ /* Unconditional Flags Changing Instructions */
+ 5 => 'color: #00007f; font-weight: bold; font-style: normal;',
+ /* Conditional Flags Changing Instructions */
+ 6 => 'color: #00007f; font-weight: bold; font-style: italic;',
+ /* Unconditional Flow Control Instructions */
+ 7 => 'color: #0000ff; font-weight: normal; font-style: normal;',
+ /* Conditional Flow Control Instructions */
+ 8 => 'color: #0000ff; font-weight: normal; font-style: italic;',
+ /* Unconditional Syncronization Instructions */
+ 9 => 'color: #00007f; font-weight: normal; font-style: normal;',
+ /* Conditional Syncronization Instructions */
+ 10 => 'color: #00007f; font-weight: normal; font-style: italic;',
+ /* Unonditional ARMv6 SIMD */
+ 11 => 'color: #b00040; font-weight: normal; font-style: normal;',
+ /* Conditional ARMv6 SIMD */
+ 12 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Unconditional Coprocessor Instructions */
+ 13 => 'color: #00007f; font-weight: normal; font-style: normal;',
+ /* Conditional Coprocessor Instructions */
+ 14 => 'color: #00007f; font-weight: bold; font-style: italic;',
+ /* Unconditional System Instructions */
+ 15 => 'color: #00007f; font-weight: normal; font-style: normal;',
+ /* Conditional System Instructions */
+ 16 => 'color: #00007f; font-weight: bold; font-style: italic;',
+ /* Unconditional WMMX/WMMX2 SIMD Instructions */
+ 17 => 'color: #b00040; font-weight: normal; font-style: normal;',
+ /* Conditional WMMX/WMMX2 SIMD Instructions */
+ 18 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Unconditional VFPv3 & NEON SIMD Memory Access Instructions */
+ 19 => 'color: #b00040; font-weight: normal; font-style: normal;',
+ /* Unconditional NEON SIMD Logical Instructions */
+ 20 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Unconditional NEON SIMD ARM Registers Interop Instructions */
+ 21 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Unconditional NEON SIMD Bit/Byte-Level Instructions */
+ 22 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Unconditional NEON SIMD Universal Integer Instructions */
+ 23 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Unconditional NEON SIMD Signed Integer Instructions */
+ 24 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Unconditional NEON SIMD Unsigned Integer Instructions */
+ 25 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Unconditional VFPv3 & NEON SIMD Floating-Point Instructions */
+ 26 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Conditional VFPv3 & NEON SIMD Memory Access Instructions */
+ 27 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Conditional NEON SIMD Logical Instructions */
+ 28 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Conditional NEON SIMD ARM Registers Interop Instructions */
+ 29 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Conditional NEON SIMD Bit/Byte-Level Instructions */
+ 30 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Conditional NEON SIMD Universal Integer Instructions */
+ 31 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Conditional NEON SIMD Signed Integer Instructions */
+ 32 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Conditional NEON SIMD Unsigned Integer Instructions */
+ 33 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Conditional VFPv3 & NEON SIMD Floating-Point Instructions */
+ 34 => 'color: #b00040; font-weight: normal; font-style: italic;',
+ /* Registers */
+ 35 => 'color: #46aa03; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #adadad; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+ 9 => '',
+ 10 => '',
+ 11 => '',
+ 12 => '',
+ 13 => '',
+ 14 => '',
+ 15 => '',
+ 16 => '',
+ 17 => '',
+ 18 => '',
+ 19 => '',
+ 20 => '',
+ 21 => '',
+ 22 => '',
+ 23 => '',
+ 24 => '',
+ 25 => '',
+ 26 => '',
+ 27 => '',
+ 28 => '',
+ 29 => '',
+ 30 => '',
+ 31 => '',
+ 32 => '',
+ 33 => '',
+ 34 => '',
+ 35 => ''
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_BIN_PREFIX_PERCENT |
+ GESHI_NUMBER_BIN_SUFFIX |
+ GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_HEX_SUFFIX |
+ GESHI_NUMBER_OCT_SUFFIX |
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 8,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#>|^])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/asm.php b/platform/www/vendor/geshi/geshi/src/geshi/asm.php
new file mode 100644
index 0000000..44a70ca
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/asm.php
@@ -0,0 +1,601 @@
+<?php
+/*************************************************************************************
+ * asm.php
+ * -------
+ * Author: Tux (tux@inmail.cz)
+ * Copyright: (c) 2004 Tux (http://tux.a4.cz/),
+ * 2004-2009 Nigel McNie (http://qbnz.com/highlighter),
+ * 2009-2011 Benny Baumann (http://qbnz.com/highlighter),
+ * 2011 Dennis Yurichev (dennis@conus.info),
+ * 2011 Marat Dukhan (mdukhan3.at.gatech.dot.edu)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/07/27
+ *
+ * x86 Assembler language file for GeSHi.
+ * Based on the following documents:
+ * - "Intel64 and IA-32 Architectures Programmer's Reference Manual
+ * Volume 2 (2A & 2B): Instructions Set Reference, A-Z",
+ * Order Number 25383-039US, May 2011
+ * - "Intel Advanced Vector Extensions Programming Reference",
+ * Order Number 319433-011, June 2011
+ * - "AMD64 Architecture Programmer's Manual Volume 3:
+ * General-Purpose and System Instructions", Publication No. 24594,
+ * Revision 3.15, November 2009
+ * - "AMD64 Architecture Programmer's Manual Volume 4:
+ * 128-Bit and 256-Bit Media Instructions", Publication No. 26568,
+ * Revision 3.12, May 2011
+ * - "AMD64 Architecture Programmer's Manual Volume 5:
+ * 64-Bit Media and x87 Floating-Point Instructions",
+ * Publication No. 26569, Revision 3.11, December 2009
+ * - "AMD64 Technology Lightweight Profiling Specification",
+ * Publication No. 43724, Revision 3.08, August 2010
+ * - "Application Note 108: Cyrix Extended MMX Instruction Set"
+ * - "VIA Padlock Programming Guide", 3rd May 2005
+ * - http://en.wikipedia.org/wiki/X86_instruction_listings
+ * - NASM 2.10rc8 Online Documenation at
+ * http://www.nasm.us/xdoc/2.10rc8/html/nasmdoc0.html
+ * Color scheme is taken from SciTE. Previous versions of this file
+ * also used words from SciTE configuration file (based on NASM syntax)
+ *
+ * CHANGES
+ * -------
+ * 2011/10/07
+ * - Rearranged instructions and registers into groups
+ * - Updated to support the following extensions
+ * - CMOV, BMI1, BMI2, TBM, FSGSBASE
+ * - LZCNT, TZCNT, POPCNT, MOVBE, CRC32
+ * - MMX, MMX+, EMMX
+ * - 3dnow!, 3dnow!+, 3dnow! Geode, 3dnow! Prefetch
+ * - SSE, SSE2, SSE3, SSSE3, SSE4A, SSE4.1, SSE4.2
+ * - AVX, AVX2, XOP, FMA3, FMA4, CVT16
+ * - VMX, SVM
+ * - AES, PCLMULQDQ, Padlock, RDRAND
+ * - Updated NASM macros and directives
+ * 2010/07/01 (1.0.8.11)
+ * - Added MMX/SSE/new x86-64 registers, MMX/SSE (up to 4.2) instructions
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.2)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ * - Added support for URLs
+ * - Added binary and hexadecimal regexps
+ * 2004/08/05 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ASM',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ //Line address prefix suppression
+ 'COMMENT_REGEXP' => array(2 => "/^(?:[0-9a-f]{0,4}:)?[0-9a-f]{4}(?:[0-9a-f]{4})?/mi"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /* General-Purpose */
+ 1 => array(
+ /* BCD instructions */
+ 'aaa','aad','aam','aas','daa','das',
+ /* Control flow instructions */
+ 'ja','jae','jb','jbe','jc','je','jg','jge','jl','jle','jmp','jna',
+ 'jnae','jnb','jnbe','jnc','jne','jng','jnge','jnl','jnle','jno','jnp','jns','jnz',
+ 'jo','jp','jpe','jpo','js','jz','jcxz','jecxz','jrcxz','loop','loope','loopne',
+ 'call','ret','enter','leave','syscall','sysenter','int','into',
+ /* Predicate instructions */
+ 'seta','setae','setb','setbe','setc','sete','setg','setge','setl','setle','setna',
+ 'setnae','setnb','setnbe','setnc','setne','setng','setnge','setnl','setnle','setno',
+ 'setnp','setns','setnz','seto','setp','setpe','setpo','sets','setz','salc',
+ /* Conditional move instructions */
+ 'cmovo','cmovno','cmovb','cmovc','cmovnae','cmovae','cmovnb','cmovnc','cmove','cmovz',
+ 'cmovne','cmovnz','cmovbe','cmovna','cmova','cmovnbe','cmovs','cmovns','cmovp','cmovpe',
+ 'cmovnp','cmovpo','cmovl','cmovnge','cmovge','cmovnl','cmovle','cmovng','cmovg','cmovnle',
+ /* ALU instructions */
+ 'add','sub','adc','sbb','neg','cmp','inc','dec','and','or','xor','not','test',
+ 'shl','shr','sal','sar','shld','shrd','rol','ror','rcl','rcr',
+ 'cbw','cwd','cwde','cdq','cdqe','cqo','bsf','bsr','bt','btc','btr','bts',
+ 'idiv','imul','div','mul','bswap','nop',
+ /* Memory instructions */
+ 'lea','mov','movsx','movsxd','movzx','xlatb','bound','xchg','xadd','cmpxchg','cmpxchg8b','cmpxchg16b',
+ /* Stack instructions */
+ 'push','pop','pusha','popa','pushad','popad','pushf','popf','pushfd','popfd','pushfq','popfq',
+ /* EFLAGS manipulations instructions */
+ 'clc','cld','stc','std','cmc','lahf','sahf',
+ /* Prefix instructions */
+ 'lock','rep','repe','repz','repne','repnz',
+ /* String instructions */
+ 'cmps','cmpsb','cmpsw',/*'cmpsd',*/ 'cmpsq', /*CMPSD conflicts with the SSE2 instructions of the same name*/
+ 'movs','movsb','movsw',/*'movsd',*/ 'movsq', /*MOVSD conflicts with the SSE2 instructions of the same name*/
+ 'scas','scasb','scasw','scasd','scasq',
+ 'stos','stosb','stosw','stosd','stosq',
+ 'lods','lodsb','lodsw','lodsd','lodsq',
+ /* Information instructions */
+ 'cpuid','rdtsc','rdtscp','rdpmc','xgetbv',
+ 'sgdt','sidt','sldt','smsw','str','lar',
+ /* LWP instructions */
+ 'llwpcb','slwpcb','lwpval','lwpins',
+ /* Instructions from miscellaneous extensions */
+ 'crc32','popcnt','lzcnt','tzcnt','movbe','pclmulqdq','rdrand',
+ /* FSGSBASE instructions */
+ 'rdfsbase','rdgsbase','wrfsbase','wrgsbase',
+ /* BMI1 instructions */
+ 'andn','bextr','blsi','blsmk','blsr',
+ /* BMI2 instructions */
+ 'bzhi','mulx','pdep','pext','rorx','sarx','shlx','shrx',
+ /* TBM instructions */
+ 'blcfill','blci','blcic','blcmsk','blcs','blsfill','blsic','t1mskc','tzmsk',
+ /* Legacy instructions */
+ 'arpl','ud2','lds','les','lfs','lgs','lss','lsl','verr','verw',
+ /* Privileged instructions */
+ 'cli','sti','clts','hlt','rsm','in','insb','insw','insd',
+ 'out','outsb','outsw','outsd','clflush','invd','invlpg','invpcid','wbinvd',
+ 'iret','iretd','iretq','sysexit','sysret','lidt','lgdt','lldt','lmsw','ltr',
+ 'monitor','mwait','rdmsr','wrmsr','swapgs',
+ 'fxsave','fxsave64','fxrstor','fxrstor64',
+ 'xsave','xsaveopt','xrstor','xsetbv','getsec',
+ /* VMX instructions */
+ 'invept','invvpid','vmcall','vmclear','vmlaunch','vmresume',
+ 'vmptrld','vmptrst','vmread','vmwrite','vmxoff','vmxon',
+ /* SVM (AMD-V) instructions */
+ 'invlpga','skinit','clgi','stgi','vmload','vmsave','vmmcall','vmrun'
+ ),
+ /*FPU*/
+ 2 => array(
+ 'f2xm1','fabs','fadd','faddp','fbld','fbstp','fchs','fclex','fcom','fcomp','fcompp','fdecstp',
+ 'fdisi','fdiv','fdivp','fdivr','fdivrp','feni','ffree','fiadd','ficom','ficomp','fidiv',
+ 'fidivr','fild','fimul','fincstp','finit','fist','fistp','fisub','fisubr','fld','fld1',
+ 'fldcw','fldenv','fldenvw','fldl2e','fldl2t','fldlg2','fldln2','fldpi','fldz','fmul',
+ 'fmulp','fnclex','fndisi','fneni','fninit','fnop','fnsave','fnsavew','fnstcw','fnstenv',
+ 'fnstenvw','fnstsw','fpatan','fprem','fptan','frndint','frstor','frstorw','fsave',
+ 'fsavew','fscale','fsqrt','fst','fstcw','fstenv','fstenvw','fstp','fstsw','fsub','fsubp',
+ 'fsubr','fsubrp','ftst','fwait','fxam','fxch','fxtract','fyl2x','fyl2xp1',
+ 'fsetpm','fcos','fldenvd','fnsaved','fnstenvd','fprem1','frstord','fsaved','fsin','fsincos',
+ 'fstenvd','fucom','fucomp','fucompp','ffreep',
+ /* FCMOV instructions */
+ 'fcomi','fcomip','fucomi','fucomip',
+ 'fcmovb','fcmove','fcmovbe','fcmovu','fcmovnb','fcmovne','fcmovnbe','fcmovnu',
+ /* SSE3 instructions */
+ 'fisttp'
+ ),
+ /*SIMD*/
+ 3 => array(
+ /* MMX instructions */
+ 'movd','movq',
+ 'paddb','paddw','paddd','paddsb','paddsw','paddusb','paddusw',
+ 'psubb','psubw','psubd','psubsb','psubsw','psubusb','psubusw',
+ 'pand','pandn','por','pxor',
+ 'pcmpeqb','pcmpeqd','pcmpeqw','pcmpgtb','pcmpgtd','pcmpgtw',
+ 'pmaddwd','pmulhw','pmullw',
+ 'psllw','pslld','psllq','psrlw','psrld','psrlq','psraw','psrad',
+ 'packuswb','packsswb','packssdw',
+ 'punpcklbw','punpcklwd','punpckldq','punpckhbw','punpckhwd','punpckhdq',
+ 'emms',
+ /* MMX+ instructions */
+ 'pavgb','pavgw',
+ 'pextrw','pinsrw','pmovmskb',
+ 'pmaxsw','pmaxub','pminsw','pminub',
+ 'pmulhuw','psadbw','pshufw',
+ 'prefetchnta','prefetcht0','prefetcht1','prefetcht2',
+ 'maskmovq','movntq','sfence',
+ /* EMMX instructions (only available on Cyrix MediaGXm) */
+ 'paddsiw','psubsiw',
+ /*'pmulhrw',*/'pmachriw','pmulhriw', /* PMULHRW conflicts with the 3dnow! instruction of the same name */
+ 'pmagw','pdistib','paveb',
+ 'pmvzb','pmvnzb','pmvlzb','pmvgezb',
+ /* 3dnow! instructions! */
+ 'pfacc','pfadd','pfsub','pfsubr','pfmul',
+ 'pfcmpeq','pfcmpge','pfcmpgt',
+ 'pfmax','pfmin',
+ 'pfrcp','pfrcpit1','pfrcpit2','pfrsqit1','pfrsqrt',
+ 'pi2fd','pf2id',
+ 'pavgusb','pmulhrw',
+ 'femms',
+ /* 3dnow!+ instructions */
+ 'pfnacc','pfpnacc','pi2fw','pf2iw','pswapd',
+ /* 3dnow! Geode instructions */
+ 'pfrsqrtv','pfrcpv',
+ /* 3dnow! Prefetch instructions */
+ 'prefetch','prefetchw',
+ /* SSE instructions */
+ 'addss','addps','subss','subps',
+ 'mulss','mulps','divss','divps','sqrtss','sqrtps',
+ 'rcpss','rcpps','rsqrtss','rsqrtps',
+ 'maxss','maxps','minss','minps',
+ 'cmpss','comiss','ucomiss','cmpps',
+ 'cmpeqss','cmpltss','cmpless','cmpunordss','cmpneqss','cmpnltss','cmpnless','cmpordss',
+ 'cmpeqps','cmpltps','cmpleps','cmpunordps','cmpneqps','cmpnltps','cmpnleps','cmpordps',
+ 'andnps','andps','orps','xorps',
+ 'cvtsi2ss','cvtss2si','cvttss2si',
+ 'cvtpi2ps','cvtps2pi','cvttps2pi',
+ 'movss','movlps','movhps','movlhps','movhlps','movaps','movups','movntps','movmskps',
+ 'shufps','unpckhps','unpcklps',
+ 'ldmxcsr','stmxcsr',
+ /* SSE2 instructions */
+ 'addpd','addsd','subpd','subsd',
+ 'mulsd','mulpd','divsd','divpd','sqrtsd','sqrtpd',
+ 'maxsd','maxpd','minsd','minpd',
+ 'cmpsd','comisd','ucomisd','cmppd',
+ 'cmpeqsd','cmpltsd','cmplesd','cmpunordsd','cmpneqsd','cmpnltsd','cmpnlesd','cmpordsd',
+ 'cmpeqpd','cmpltpd','cmplepd','cmpunordpd','cmpneqpd','cmpnltpd','cmpnlepd','cmpordpd',
+ 'andnpd','andpd','orpd','xorpd',
+ 'cvtsd2ss','cvtpd2ps','cvtss2sd','cvtps2pd',
+ 'cvtdq2ps','cvtps2dq','cvttps2dq',
+ 'cvtdq2pd','cvtpd2dq','cvttpd2dq',
+ 'cvtsi2sd','cvtsd2si','cvttsd2si',
+ 'cvtpi2pd','cvtpd2pi','cvttpd2pi',
+ 'movsd','movlpd','movhpd','movapd','movupd','movntpd','movmskpd',
+ 'shufpd','unpckhpd','unpcklpd',
+ 'movnti','movdqa','movdqu','movntdq','maskmovdqu',
+ 'movdq2q','movq2dq',
+ 'paddq','psubq','pmuludq',
+ 'pslldq','psrldq',
+ 'punpcklqdq','punpckhqdq',
+ 'pshufhw','pshuflw','pshufd',
+ 'lfence','mfence',
+ /* SSE3 instructions */
+ 'addsubps','addsubpd',
+ 'haddps','haddpd','hsubps','hsubpd',
+ 'movsldup','movshdup','movddup',
+ 'lddqu',
+ /* SSSE3 instructions */
+ 'psignb','psignw','psignd',
+ 'pabsb','pabsw','pabsd',
+ 'palignr','pshufb',
+ 'pmulhrsw','pmaddubsw',
+ 'phaddw','phaddd','phaddsw',
+ 'phsubw','phsubd','phsubsw',
+ /* SSE4A instructions */
+ 'extrq','insertq','movntsd','movntss',
+ /* SSE4.1 instructions */
+ 'mpsadbw','phminposuw',
+ 'pmuldq','pmulld',
+ 'dpps','dppd',
+ 'blendps','blendpd','blendvps','blendvpd','pblendvb','pblendw',
+ 'pmaxsb','pmaxuw','pmaxsd','pmaxud','pminsb','pminuw','pminsd','pminud',
+ 'roundps','roundss','roundpd','roundsd',
+ 'insertps','pinsrb','pinsrd','pinsrq',
+ 'extractps','pextrb','pextrd','pextrq',
+ 'pmovsxbw','pmovsxbd','pmovsxbq','pmovsxwd','pmovsxwq','pmovsxdq',
+ 'pmovzxbw','pmovzxbd','pmovzxbq','pmovzxwd','pmovzxwq','pmovzxdq',
+ 'ptest',
+ 'pcmpeqq',
+ 'packusdw',
+ 'movntdqa',
+ /* SSE4.2 instructions */
+ 'pcmpgtq',
+ 'pcmpestri','pcmpestrm','pcmpistri','pcmpistrm',
+ /* AES instructions */
+ 'aesenc','aesenclast','aesdec','aesdeclast','aeskeygenassist','aesimc',
+ /* VIA Padlock instructions */
+ 'xcryptcbc','xcryptcfb','xcryptctr','xcryptecb','xcryptofb',
+ 'xsha1','xsha256','montmul','xstore',
+ /* AVX instructions */
+ 'vaddss','vaddps','vaddsd','vaddpd','vsubss','vsubps','vsubsd','vsubpd',
+ 'vaddsubps','vaddsubpd',
+ 'vhaddps','vhaddpd','vhsubps','vhsubpd',
+ 'vmulss','vmulps','vmulsd','vmulpd',
+ 'vmaxss','vmaxps','vmaxsd','vmaxpd','vminss','vminps','vminsd','vminpd',
+ 'vandps','vandpd','vandnps','vandnpd','vorps','vorpd','vxorps','vxorpd',
+ 'vblendps','vblendpd','vblendvps','vblendvpd',
+ 'vcmpss','vcomiss','vucomiss','vcmpsd','vcomisd','vucomisd','vcmpps','vcmppd',
+ 'vcmpeqss','vcmpltss','vcmpless','vcmpunordss','vcmpneqss','vcmpnltss','vcmpnless','vcmpordss',
+ 'vcmpeq_uqss','vcmpngess','vcmpngtss','vcmpfalsess','vcmpneq_oqss','vcmpgess','vcmpgtss','vcmptruess',
+ 'vcmpeq_osss','vcmplt_oqss','vcmple_oqss','vcmpunord_sss','vcmpneq_usss','vcmpnlt_uqss','vcmpnle_uqss','vcmpord_sss',
+ 'vcmpeq_usss','vcmpnge_uqss','vcmpngt_uqss','vcmpfalse_osss','vcmpneq_osss','vcmpge_oqss','vcmpgt_oqss','vcmptrue_usss',
+ 'vcmpeqps','vcmpltps','vcmpleps','vcmpunordps','vcmpneqps','vcmpnltps','vcmpnleps','vcmpordps',
+ 'vcmpeq_uqps','vcmpngeps','vcmpngtps','vcmpfalseps','vcmpneq_oqps','vcmpgeps','vcmpgtps','vcmptrueps',
+ 'vcmpeq_osps','vcmplt_oqps','vcmple_oqps','vcmpunord_sps','vcmpneq_usps','vcmpnlt_uqps','vcmpnle_uqps','vcmpord_sps',
+ 'vcmpeq_usps','vcmpnge_uqps','vcmpngt_uqps','vcmpfalse_osps','vcmpneq_osps','vcmpge_oqps','vcmpgt_oqps','vcmptrue_usps',
+ 'vcmpeqsd','vcmpltsd','vcmplesd','vcmpunordsd','vcmpneqsd','vcmpnltsd','vcmpnlesd','vcmpordsd',
+ 'vcmpeq_uqsd','vcmpngesd','vcmpngtsd','vcmpfalsesd','vcmpneq_oqsd','vcmpgesd','vcmpgtsd','vcmptruesd',
+ 'vcmpeq_ossd','vcmplt_oqsd','vcmple_oqsd','vcmpunord_ssd','vcmpneq_ussd','vcmpnlt_uqsd','vcmpnle_uqsd','vcmpord_ssd',
+ 'vcmpeq_ussd','vcmpnge_uqsd','vcmpngt_uqsd','vcmpfalse_ossd','vcmpneq_ossd','vcmpge_oqsd','vcmpgt_oqsd','vcmptrue_ussd',
+ 'vcmpeqpd','vcmpltpd','vcmplepd','vcmpunordpd','vcmpneqpd','vcmpnltpd','vcmpnlepd','vcmpordpd',
+ 'vcmpeq_uqpd','vcmpngepd','vcmpngtpd','vcmpfalsepd','vcmpneq_oqpd','vcmpgepd','vcmpgtpd','vcmptruepd',
+ 'vcmpeq_ospd','vcmplt_oqpd','vcmple_oqpd','vcmpunord_spd','vcmpneq_uspd','vcmpnlt_uqpd','vcmpnle_uqpd','vcmpord_spd',
+ 'vcmpeq_uspd','vcmpnge_uqpd','vcmpngt_uqpd','vcmpfalse_ospd','vcmpneq_ospd','vcmpge_oqpd','vcmpgt_oqpd','vcmptrue_uspd',
+ 'vcvtsd2ss','vcvtpd2ps','vcvtss2sd','vcvtps2pd',
+ 'vcvtsi2ss','vcvtss2si','vcvttss2si',
+ 'vcvtpi2ps','vcvtps2pi','vcvttps2pi',
+ 'vcvtdq2ps','vcvtps2dq','vcvttps2dq',
+ 'vcvtdq2pd','vcvtpd2dq','vcvttpd2dq',
+ 'vcvtsi2sd','vcvtsd2si','vcvttsd2si',
+ 'vcvtpi2pd','vcvtpd2pi','vcvttpd2pi',
+ 'vdivss','vdivps','vdivsd','vdivpd','vsqrtss','vsqrtps','vsqrtsd','vsqrtpd',
+ 'vdpps','vdppd',
+ 'vmaskmovps','vmaskmovpd',
+ 'vmovss','vmovsd','vmovaps','vmovapd','vmovups','vmovupd','vmovntps','vmovntpd',
+ 'vmovhlps','vmovlhps','vmovlps','vmovlpd','vmovhps','vmovhpd',
+ 'vmovsldup','vmovshdup','vmovddup',
+ 'vmovmskps','vmovmskpd',
+ 'vroundss','vroundps','vroundsd','vroundpd',
+ 'vrcpss','vrcpps','vrsqrtss','vrsqrtps',
+ 'vunpcklps','vunpckhps','vunpcklpd','vunpckhpd',
+ 'vbroadcastss','vbroadcastsd','vbroadcastf128',
+ 'vextractps','vinsertps','vextractf128','vinsertf128',
+ 'vshufps','vshufpd','vpermilps','vpermilpd','vperm2f128',
+ 'vtestps','vtestpd',
+ 'vpaddb','vpaddusb','vpaddsb','vpaddw','vpaddusw','vpaddsw','vpaddd','vpaddq',
+ 'vpsubb','vpsubusb','vpsubsb','vpsubw','vpsubusw','vpsubsw','vpsubd','vpsubq',
+ 'vphaddw','vphaddsw','vphaddd','vphsubw','vphsubsw','vphsubd',
+ 'vpsllw','vpslld','vpsllq','vpsrlw','vpsrld','vpsrlq','vpsraw','vpsrad',
+ 'vpand','vpandn','vpor','vpxor',
+ 'vpblendwb','vpblendw',
+ 'vpsignb','vpsignw','vpsignd',
+ 'vpavgb','vpavgw',
+ 'vpabsb','vpabsw','vpabsd',
+ 'vmovd','vmovq','vmovdqa','vmovdqu','vlddqu','vmovntdq','vmovntdqa','vmaskmovdqu',
+ 'vpmovsxbw','vpmovsxbd','vpmovsxbq','vpmovsxwd','vpmovsxwq','vpmovsxdq',
+ 'vpmovzxbw','vpmovzxbd','vpmovzxbq','vpmovzxwd','vpmovzxwq','vpmovzxdq',
+ 'vpackuswb','vpacksswb','vpackusdw','vpackssdw',
+ 'vpcmpeqb','vpcmpeqw','vpcmpeqd','vpcmpeqq','vpcmpgtb','vpcmpgtw','vpcmpgtd','vpcmpgtq',
+ 'vpmaddubsw','vpmaddwd',
+ 'vpmullw','vpmulhuw','vpmulhw','vpmulhrsw','vpmulld','vpmuludq','vpmuldq',
+ 'vpmaxub','vpmaxsb','vpmaxuw','vpmaxsw','vpmaxud','vpmaxsd',
+ 'vpminub','vpminsb','vpminuw','vpminsw','vpminud','vpminsd',
+ 'vpmovmskb','vptest',
+ 'vpunpcklbw','vpunpcklwd','vpunpckldq','vpunpcklqdq',
+ 'vpunpckhbw','vpunpckhwd','vpunpckhdq','vpunpckhqdq',
+ 'vpslldq','vpsrldq','vpalignr',
+ 'vpshufb','vpshuflw','vpshufhw','vpshufd',
+ 'vpextrb','vpextrw','vpextrd','vpextrq','vpinsrb','vpinsrw','vpinsrd','vpinsrq',
+ 'vpsadbw','vmpsadbw','vphminposuw',
+ 'vpcmpestri','vpcmpestrm','vpcmpistri','vpcmpistrm',
+ 'vpclmulqdq','vaesenc','vaesenclast','vaesdec','vaesdeclast','vaeskeygenassist','vaesimc',
+ 'vldmxcsr','vstmxcsr','vzeroall','vzeroupper',
+ /* AVX2 instructions */
+ 'vbroadcasti128','vpbroadcastb','vpbroadcastw','vpbroadcastd','vpbroadcastq',
+ 'vpblendd',
+ 'vpermd','vpermq','vperm2i128',
+ 'vextracti128','vinserti128',
+ 'vpmaskmovd','vpmaskmovq',
+ 'vpsllvd','vpsllvq','vpsravd','vpsrlvd',
+ 'vpgatherdd','vpgatherqd','vgatherdq','vgatherqq',
+ 'vpermps','vpermpd',
+ 'vgatherdpd','vgatherqpd','vgatherdps','vgatherqps',
+ /* XOP instructions */
+ 'vfrczss','vfrczps','vfrczsd','vfrczpd',
+ 'vpermil2ps','vperlil2pd',
+ 'vpcomub','vpcomb','vpcomuw','vpcomw','vpcomud','vpcomd','vpcomuq','vpcomq',
+ 'vphaddubw','vphaddbw','vphaddubd','vphaddbd','vphaddubq','vphaddbq',
+ 'vphadduwd','vphaddwd','vphadduwq','vphaddwq','vphaddudq','vphadddq',
+ 'vphsubbw','vphsubwd','vphsubdq',
+ 'vpmacsdd','vpmacssdd','vpmacsdql','vpmacssdql','vpmacsdqh','vpmacssdqh',
+ 'vpmacsww','vpmacssww','vpmacswd','vpmacsswd',
+ 'vpmadcswd','vpmadcsswd',
+ 'vpcmov','vpperm',
+ 'vprotb','vprotw','vprotd','vprotq',
+ 'vpshab','vpshaw','vpshad','vpshaq',
+ 'vpshlb','vpshlw','vpshld','vpshlq',
+ /* CVT16 instructions */
+ 'vcvtph2ps','vcvtps2ph',
+ /* FMA4 instructions */
+ 'vfmaddss','vfmaddps','vfmaddsd','vfmaddpd',
+ 'vfmsubss','vfmsubps','vfmsubsd','vfmsubpd',
+ 'vnfmaddss','vnfmaddps','vnfmaddsd','vnfmaddpd',
+ 'vnfmsubss','vnfmsubps','vnfmsubsd','vnfmsubpd',
+ 'vfmaddsubps','vfmaddsubpd','vfmsubaddps','vfmsubaddpd',
+ /* FMA3 instructions */
+ 'vfmadd132ss','vfmadd213ss','vfmadd231ss',
+ 'vfmadd132ps','vfmadd213ps','vfmadd231ps',
+ 'vfmadd132sd','vfmadd213sd','vfmadd231sd',
+ 'vfmadd132pd','vfmadd213pd','vfmadd231pd',
+ 'vfmaddsub132ps','vfmaddsub213ps','vfmaddsub231ps',
+ 'vfmaddsub132pd','vfmaddsub213pd','vfmaddsub231pd',
+ 'vfmsubadd132ps','vfmsubadd213ps','vfmsubadd231ps',
+ 'vfmsubadd132pd','vfmsubadd213pd','vfmsubadd231pd',
+ 'vfmsub132ss','vfmsub213ss','vfmsub231ss',
+ 'vfmsub132ps','vfmsub213ps','vfmsub231ps',
+ 'vfmsub132sd','vfmsub213sd','vfmsub231sd',
+ 'vfmsub132pd','vfmsub213pd','vfmsub231pd',
+ 'vfnmadd132ss','vfnmadd213ss','vfnmadd231ss',
+ 'vfnmadd132ps','vfnmadd213ps','vfnmadd231ps',
+ 'vfnmadd132sd','vfnmadd213sd','vfnmadd231sd',
+ 'vfnmadd132pd','vfnmadd213pd','vfnmadd231pd',
+ 'vfnmsub132ss','vfnmsub213ss','vfnmsub231ss',
+ 'vfnmsub132ps','vfnmsub213ps','vfnmsub231ps',
+ 'vfnmsub132sd','vfnmsub213sd','vfnmsub231sd',
+ 'vfnmsub132pd','vfnmsub213pd','vfnmsub231pd'
+ ),
+ /*registers*/
+ 4 => array(
+ /* General-Purpose Registers */
+ 'al','ah','bl','bh','cl','ch','dl','dh','sil','dil','bpl','spl',
+ 'r8b','r9b','r10b','r11b','r12b','r13b','r14b','r15b',
+ 'ax','bx','cx','dx','si','di','bp','sp',
+ 'r8w','r9w','r10w','r11w','r12w','r13w','r14w','r15w',
+ 'eax','ebx','ecx','edx','esi','edi','ebp','esp',
+ 'r8d','r9d','r10d','r11d','r12d','r13d','r14d','r15d',
+ 'rax','rcx','rdx','rbx','rsp','rbp','rsi','rdi',
+ 'r8','r9','r10','r11','r12','r13','r14','r15',
+ /* Debug Registers */
+ 'dr0','dr1','dr2','dr3','dr6','dr7',
+ /* Control Registers */
+ 'cr0','cr2','cr3','cr4','cr8',
+ /* Test Registers (Supported on Intel 486 only) */
+ 'tr3','tr4','tr5','tr6','tr7',
+ /* Segment Registers */
+ 'cs','ds','es','fs','gs','ss',
+ /* FPU Registers */
+ 'st','st0','st1','st2','st3','st4','st5','st6','st7',
+ /* MMX Registers */
+ 'mm0','mm1','mm2','mm3','mm4','mm5','mm6','mm7',
+ /* SSE Registers */
+ 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7',
+ 'xmm8','xmm9','xmm10','xmm11','xmm12','xmm13','xmm14','xmm15',
+ /* AVX Registers */
+ 'ymm0','ymm1','ymm2','ymm3','ymm4','ymm5','ymm6','ymm7',
+ 'ymm8','ymm9','ymm10','ymm11','ymm12','ymm13','ymm14','ymm15'
+ ),
+ /*Directive*/
+ 5 => array(
+ 'db','dw','dd','dq','dt','do','dy',
+ 'resb','resw','resd','resq','rest','reso','resy','incbin','equ','times','safeseh',
+ '__utf16__','__utf32__',
+ 'default','cpu','float','start','imagebase','osabi',
+ '..start','..imagebase','..gotpc','..gotoff','..gottpoff','..got','..plt','..sym','..tlsie',
+ 'section','segment','__sect__','group','absolute',
+ '.bss','.comment','.data','.lbss','.ldata','.lrodata','.rdata','.rodata','.tbss','.tdata','.text',
+ 'alloc','bss','code','exec','data','noalloc','nobits','noexec','nowrite','progbits','rdata','tls','write',
+ 'private','public','common','stack','overlay','class',
+ 'extern','global','import','export',
+ '%define','%idefine','%xdefine','%ixdefine','%assign','%undef',
+ '%defstr','%idefstr','%deftok','%ideftok',
+ '%strcat','%strlen','%substr',
+ '%macro','%imacro','%rmacro','%exitmacro','%endmacro','%unmacro',
+ '%if','%ifn','%elif','%elifn','%else','%endif',
+ '%ifdef','%ifndef','%elifdef','%elifndef',
+ '%ifmacro','%ifnmacro','%elifmacro','%elifnmacro',
+ '%ifctx','%ifnctx','%elifctx','%elifnctx',
+ '%ifidn','%ifnidn','%elifidn','%elifnidn',
+ '%ifidni','%ifnidni','%elifidni','%elifnidni',
+ '%ifid','%ifnid','%elifid','%elifnid',
+ '%ifnum','%ifnnum','%elifnum','%elifnnum',
+ '%ifstr','%ifnstr','%elifstr','%elifnstr',
+ '%iftoken','%ifntoken','%eliftoken','%elifntoken',
+ '%ifempty','%ifnempty','%elifempty','%elifnempty',
+ '%ifenv','%ifnenv','%elifenv','%elifnenv',
+ '%rep','%exitrep','%endrep',
+ '%while','%exitwhile','%endwhile',
+ '%include','%pathsearch','%depend','%use',
+ '%push','%pop','%repl','%arg','%local','%stacksize','flat','flat64','large','small',
+ '%error','%warning','%fatal',
+ '%00','.nolist','%rotate','%line','%!','%final','%clear',
+ 'struc','endstruc','istruc','at','iend',
+ 'align','alignb','sectalign',
+ 'bits','use16','use32','use64',
+ '__nasm_major__','__nasm_minor__','__nasm_subminor__','___nasm_patchlevel__',
+ '__nasm_version_id__','__nasm_ver__',
+ '__file__','__line__','__pass__','__bits__','__output_format__',
+ '__date__','__time__','__date_num__','__time_num__','__posix_time__',
+ '__utc_date__','__utc_time__','__utc_date_num__','__utc_time_num__',
+ '__float_daz__','__float_round__','__float__',
+ /* Keywords from standard packages */
+ '__use_altreg__',
+ '__use_smartalign__','smartalign','__alignmode__',
+ '__use_fp__','__infinity__','__nan__','__qnan__','__snan__',
+ '__float8__','__float16__','__float32__','__float64__','__float80m__','__float80e__','__float128l__','__float128h__'
+ ),
+ /*Operands*/
+ 6 => array(
+ 'a16','a32','a64','o16','o32','o64','strict',
+ 'byte','word','dword','qword','tword','oword','yword','nosplit',
+ '%0','%1','%2','%3','%4','%5','%6','%7','%8','%9',
+ 'abs','rel',
+ 'seg','wrt'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '[', ']', '(', ')',
+ '+', '-', '*', '/', '%',
+ '.', ',', ';', ':'
+ ),
+ 2 => array(
+ '$','$$','%+','%?','%??'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00007f; font-weight: bold;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #b00040;',
+ 4 => 'color: #46aa03; font-weight: bold;',
+ 5 => 'color: #0000ff; font-weight: bold;',
+ 6 => 'color: #0000ff; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #adadad; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #339933;',
+ 2 => 'color: #0000ff; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => ''
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_BIN_PREFIX_PERCENT |
+ GESHI_NUMBER_BIN_SUFFIX |
+ GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_HEX_SUFFIX |
+ GESHI_NUMBER_OCT_SUFFIX |
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 8,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#>|^])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/asp.php b/platform/www/vendor/geshi/geshi/src/geshi/asp.php
new file mode 100644
index 0000000..db9daae
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/asp.php
@@ -0,0 +1,162 @@
+<?php
+/*************************************************************************************
+ * asp.php
+ * --------
+ * Author: Amit Gupta (http://blog.igeek.info/)
+ * Copyright: (c) 2004 Amit Gupta (http://blog.igeek.info/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/13
+ *
+ * ASP language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/12/30 (1.0.3)
+ * - Strings only delimited by ", comments by '
+ * 2004/11/27 (1.0.2)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ * - Added support for URLs
+ * 2004/08/13 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Include all the functions, keywords etc that I have missed
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ASP',
+ 'COMMENT_SINGLE' => array(1 => "'", 2 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'include', 'file', 'Const', 'Dim', 'Option', 'Explicit', 'Implicit', 'Set', 'Select', 'ReDim', 'Preserve',
+ 'ByVal', 'ByRef', 'End', 'Private', 'Public', 'If', 'Then', 'Else', 'ElseIf', 'Case', 'With', 'NOT',
+ 'While', 'Wend', 'For', 'Loop', 'Do', 'Request', 'Response', 'Server', 'ADODB', 'Session', 'Application',
+ 'Each', 'In', 'Get', 'Next', 'INT', 'CINT', 'CBOOL', 'CDATE', 'CBYTE', 'CCUR', 'CDBL', 'CLNG', 'CSNG',
+ 'CSTR', 'Fix', 'Is', 'Sgn', 'String', 'Boolean', 'Currency', 'Me', 'Single', 'Long', 'Integer', 'Byte',
+ 'Variant', 'Double', 'To', 'Let', 'Xor', 'Resume', 'On', 'Error', 'Imp', 'GoTo', 'Call', 'Global'
+ ),
+ 2 => array(
+ 'Null', 'Nothing', 'And',
+ 'False',
+ 'True', 'var', 'Or', 'BOF', 'EOF', 'xor',
+ 'Function', 'Class', 'New', 'Sub'
+ ),
+ 3 => array(
+ 'CreateObject', 'Write', 'Redirect', 'Cookies', 'BinaryRead', 'ClientCertificate', 'Form', 'QueryString',
+ 'ServerVariables', 'TotalBytes', 'AddHeader', 'AppendToLog', 'BinaryWrite', 'Buffer', 'CacheControl',
+ 'Charset', 'Clear', 'ContentType', 'End()', 'Expires', 'ExpiresAbsolute', 'Flush()', 'IsClientConnected',
+ 'PICS', 'Status', 'Connection', 'Recordset', 'Execute', 'Abandon', 'Lock', 'UnLock', 'Command', 'Fields',
+ 'Properties', 'Property', 'Send', 'Replace', 'InStr', 'TRIM', 'NOW', 'Day', 'Month', 'Hour', 'Minute', 'Second',
+ 'Year', 'MonthName', 'LCase', 'UCase', 'Abs', 'Array', 'As', 'LEN', 'MoveFirst', 'MoveLast', 'MovePrevious',
+ 'MoveNext', 'LBound', 'UBound', 'Transfer', 'Open', 'Close', 'MapPath', 'FileExists', 'OpenTextFile', 'ReadAll'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '<%', '%>'
+ ),
+ 0 => array(
+ '(', ')', '[', ']', '!', '@', '%', '&', '*', '|', '/', '<', '>',
+ ';', ':', '?', '='),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #990099; font-weight: bold;',
+ 2 => 'color: #0000ff; font-weight: bold;',
+ 3 => 'color: #330066;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000;',
+ 2 => 'color: #ff6600;',
+ 'MULTI' => 'color: #008000;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #006600; font-weight:bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #cc0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #800000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #9900cc;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #006600; font-weight: bold;',
+ 1 => 'color: #000000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<%' => '%>'
+ ),
+ 1 => array(
+ '<script language="vbscript" runat="server">' => '</script>'
+ ),
+ 2 => array(
+ '<script language="javascript" runat="server">' => '</script>'
+ ),
+ 3 => "/(?P<start><%=?)(?:\"[^\"]*?\"|\/\*(?!\*\/).*?\*\/|.)*?(?P<end>%>|\Z)/sm"
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/asymptote.php b/platform/www/vendor/geshi/geshi/src/geshi/asymptote.php
new file mode 100644
index 0000000..a701ae9
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/asymptote.php
@@ -0,0 +1,1850 @@
+<?php
+/*************************************************************************************
+ * asymptote.php
+ * -------------
+ * Author: Manuel Yguel (manuel.yguel.robotics@gmail.com)
+ * Copyright: (c) 2012 Manuel Yguel (http://manuelyguel.eu)
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/05/24
+ *
+ * asymptote language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2012/05/24 (1.0.0.0)
+ * - First Release
+ *
+ * TODO (updated 2012/05/24)
+ * -------------------------
+ * * Split to several files - php4, php5 etc
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'asymptote',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Multiline-continued single-line comments
+ 1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Multiline-continued preprocessor define
+ 2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[\\\\abfnrtv\'\"?\n]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'and',
+ 'controls',
+ 'tension',
+ 'atleast',
+ 'curl',
+ 'if',
+ 'else',
+ 'while',
+ 'for',
+ 'do',
+ 'return',
+ 'break',
+ 'continue',
+ 'struct',
+ 'typedef',
+ 'new',
+ 'access',
+ 'import',
+ 'unravel',
+ 'from',
+ 'include',
+ 'quote',
+ 'static',
+ 'public',
+ 'private',
+ 'restricted',
+ 'this',
+ 'explicit',
+ 'true',
+ 'false',
+ 'null',
+ 'cycle',
+ 'newframe',
+ 'operator'
+ ),
+ 2 => array(
+ 'Braid',
+ 'FitResult',
+ 'Label',
+ 'Legend',
+ 'Segment',
+ 'Solution',
+ 'TreeNode',
+ 'abscissa',
+ 'arrowhead',
+ 'binarytree',
+ 'binarytreeNode',
+ 'block',
+ 'bool',
+ 'bool3',
+ 'bounds',
+ 'bqe',
+ 'circle',
+ 'conic',
+ 'coord',
+ 'coordsys',
+ 'cputime',
+ 'ellipse',
+ 'file',
+ 'filltype',
+ 'frame',
+ 'grid3',
+ 'guide',
+ 'horner',
+ 'hsv',
+ 'hyperbola',
+ 'indexedTransform',
+ 'int',
+ 'inversion',
+ 'key',
+ 'light',
+ 'line',
+ 'linefit',
+ 'marginT',
+ 'marker',
+ 'mass',
+ 'object',
+ 'pair',
+ 'parabola',
+ 'path',
+ 'path3',
+ 'pen',
+ 'picture',
+ 'point',
+ 'position',
+ 'projection',
+ 'real',
+ 'revolution',
+ 'scaleT',
+ 'scientific',
+ 'segment',
+ 'side',
+ 'slice',
+ 'solution',
+ 'splitface',
+ 'string',
+ 'surface',
+ 'tensionSpecifier',
+ 'ticklocate',
+ 'ticksgridT',
+ 'tickvalues',
+ 'transform',
+ 'transformation',
+ 'tree',
+ 'triangle',
+ 'trilinear',
+ 'triple',
+ 'vector',
+ 'vertex',
+ 'void'),
+
+ 3 => array(
+ 'AND',
+ 'Arc',
+ 'ArcArrow',
+ 'ArcArrows',
+ 'Arrow',
+ 'Arrows',
+ 'Automatic',
+ 'AvantGarde',
+ 'BBox',
+ 'BWRainbow',
+ 'BWRainbow2',
+ 'Bar',
+ 'Bars',
+ 'BeginArcArrow',
+ 'BeginArrow',
+ 'BeginBar',
+ 'BeginDotMargin',
+ 'BeginMargin',
+ 'BeginPenMargin',
+ 'Blank',
+ 'Bookman',
+ 'Bottom',
+ 'BottomTop',
+ 'Bounds',
+ 'Break',
+ 'Broken',
+ 'BrokenLog',
+ 'CLZ',
+ 'CTZ',
+ 'Ceil',
+ 'Circle',
+ 'CircleBarIntervalMarker',
+ 'Cos',
+ 'Courier',
+ 'CrossIntervalMarker',
+ 'DOSendl',
+ 'DOSnewl',
+ 'DefaultFormat',
+ 'DefaultLogFormat',
+ 'Degrees',
+ 'Dir',
+ 'DotMargin',
+ 'DotMargins',
+ 'Dotted',
+ 'Draw',
+ 'Drawline',
+ 'Embed',
+ 'EndArcArrow',
+ 'EndArrow',
+ 'EndBar',
+ 'EndDotMargin',
+ 'EndMargin',
+ 'EndPenMargin',
+ 'Fill',
+ 'FillDraw',
+ 'Floor',
+ 'Format',
+ 'Full',
+ 'Gaussian',
+ 'Gaussrand',
+ 'Gaussrandpair',
+ 'Gradient',
+ 'Grayscale',
+ 'Helvetica',
+ 'Hermite',
+ 'HookHead',
+ 'InOutTicks',
+ 'InTicks',
+ 'Jn',
+ 'Landscape',
+ 'Left',
+ 'LeftRight',
+ 'LeftTicks',
+ 'Linear',
+ 'Link',
+ 'Log',
+ 'LogFormat',
+ 'Margin',
+ 'Margins',
+ 'Mark',
+ 'MidArcArrow',
+ 'MidArrow',
+ 'NOT',
+ 'NewCenturySchoolBook',
+ 'NoBox',
+ 'NoMargin',
+ 'NoModifier',
+ 'NoTicks',
+ 'NoTicks3',
+ 'NoZero',
+ 'NoZeroFormat',
+ 'None',
+ 'OR',
+ 'OmitFormat',
+ 'OmitTick',
+ 'OmitTickInterval',
+ 'OmitTickIntervals',
+ 'OutTicks',
+ 'Ox',
+ 'Oy',
+ 'Palatino',
+ 'PaletteTicks',
+ 'Pen',
+ 'PenMargin',
+ 'PenMargins',
+ 'Pentype',
+ 'Portrait',
+ 'RadialShade',
+ 'RadialShadeDraw',
+ 'Rainbow',
+ 'Range',
+ 'Relative',
+ 'Right',
+ 'RightTicks',
+ 'Rotate',
+ 'Round',
+ 'SQR',
+ 'Scale',
+ 'ScaleX',
+ 'ScaleY',
+ 'ScaleZ',
+ 'Seascape',
+ 'Shift',
+ 'Sin',
+ 'Slant',
+ 'Spline',
+ 'StickIntervalMarker',
+ 'Straight',
+ 'Symbol',
+ 'Tan',
+ 'TeXify',
+ 'Ticks',
+ 'Ticks3',
+ 'TildeIntervalMarker',
+ 'TimesRoman',
+ 'Top',
+ 'TrueMargin',
+ 'UnFill',
+ 'UpsideDown',
+ 'Wheel',
+ 'X',
+ 'XEquals',
+ 'XOR',
+ 'XY',
+ 'XYEquals',
+ 'XYZero',
+ 'XYgrid',
+ 'XZEquals',
+ 'XZZero',
+ 'XZero',
+ 'XZgrid',
+ 'Y',
+ 'YEquals',
+ 'YXgrid',
+ 'YZ',
+ 'YZEquals',
+ 'YZZero',
+ 'YZero',
+ 'YZgrid',
+ 'Yn',
+ 'Z',
+ 'ZX',
+ 'ZXgrid',
+ 'ZYgrid',
+ 'ZapfChancery',
+ 'ZapfDingbats',
+ '_begingroup3',
+ '_cputime',
+ '_draw',
+ '_eval',
+ '_image',
+ '_labelpath',
+ '_projection',
+ '_strokepath',
+ '_texpath',
+ 'aCos',
+ 'aSin',
+ 'aTan',
+ 'abort',
+ 'abs',
+ 'accel',
+ 'acos',
+ 'acosh',
+ 'acot',
+ 'acsc',
+ 'activatequote',
+ 'add',
+ 'addArrow',
+ 'addMargins',
+ 'addSaveFunction',
+ 'addpenarc',
+ 'addpenline',
+ 'adjust',
+ 'alias',
+ 'align',
+ 'all',
+ 'altitude',
+ 'angabscissa',
+ 'angle',
+ 'angpoint',
+ 'animate',
+ 'annotate',
+ 'anticomplementary',
+ 'antipedal',
+ 'apply',
+ 'approximate',
+ 'arc',
+ 'arcarrowsize',
+ 'arccircle',
+ 'arcdir',
+ 'arcfromcenter',
+ 'arcfromfocus',
+ 'arclength',
+ 'arcnodesnumber',
+ 'arcpoint',
+ 'arcsubtended',
+ 'arcsubtendedcenter',
+ 'arctime',
+ 'arctopath',
+ 'array',
+ 'arrow',
+ 'arrow2',
+ 'arrowbase',
+ 'arrowbasepoints',
+ 'arrowsize',
+ 'asec',
+ 'asin',
+ 'asinh',
+ 'ask',
+ 'assert',
+ 'asy',
+ 'asycode',
+ 'asydir',
+ 'asyfigure',
+ 'asyfilecode',
+ 'asyinclude',
+ 'asywrite',
+ 'atan',
+ 'atan2',
+ 'atanh',
+ 'atbreakpoint',
+ 'atexit',
+ 'attach',
+ 'attract',
+ 'atupdate',
+ 'autoformat',
+ 'autoscale',
+ 'autoscale3',
+ 'axes',
+ 'axes3',
+ 'axialshade',
+ 'axis',
+ 'axiscoverage',
+ 'azimuth',
+ 'babel',
+ 'bangles',
+ 'bar',
+ 'barmarksize',
+ 'barsize',
+ 'baseline',
+ 'bbox',
+ 'beep',
+ 'begin',
+ 'beginclip',
+ 'begingroup',
+ 'beginpoint',
+ 'between',
+ 'bevel',
+ 'bezier',
+ 'bezierP',
+ 'bezierPP',
+ 'bezierPPP',
+ 'bezulate',
+ 'bibliography',
+ 'bibliographystyle',
+ 'binomial',
+ 'binput',
+ 'bins',
+ 'bisector',
+ 'bisectorpoint',
+ 'bispline',
+ 'blend',
+ 'blockconnector',
+ 'boutput',
+ 'box',
+ 'breakpoint',
+ 'breakpoints',
+ 'brick',
+ 'buildRestoreDefaults',
+ 'buildRestoreThunk',
+ 'buildcycle',
+ 'bulletcolor',
+ 'byte',
+ 'calculateScaling',
+ 'canonical',
+ 'canonicalcartesiansystem',
+ 'cartesiansystem',
+ 'case1',
+ 'case2',
+ 'case3',
+ 'case4',
+ 'cbrt',
+ 'cd',
+ 'ceil',
+ 'center',
+ 'centerToFocus',
+ 'centroid',
+ 'cevian',
+ 'change2',
+ 'changecoordsys',
+ 'checkSegment',
+ 'checkconditionlength',
+ 'checker',
+ 'checkincreasing',
+ 'checklengths',
+ 'checkposition',
+ 'checktriangle',
+ 'choose',
+ 'circlebarframe',
+ 'circlemarkradius',
+ 'circlenodesnumber',
+ 'circumcenter',
+ 'circumcircle',
+ 'clamped',
+ 'clear',
+ 'clip',
+ 'clipdraw',
+ 'close',
+ 'cmyk',
+ 'code',
+ 'colatitude',
+ 'collect',
+ 'collinear',
+ 'color',
+ 'colorless',
+ 'colors',
+ 'colorspace',
+ 'comma',
+ 'compassmark',
+ 'complement',
+ 'complementary',
+ 'concat',
+ 'concurrent',
+ 'cone',
+ 'conicnodesnumber',
+ 'conictype',
+ 'conj',
+ 'connect',
+ 'connected',
+ 'connectedindex',
+ 'containmentTree',
+ 'contains',
+ 'contour',
+ 'contour3',
+ 'contouredges',
+ 'controlSpecifier',
+ 'convert',
+ 'coordinates',
+ 'copy',
+ 'copyPairOrTriple',
+ 'cos',
+ 'cosh',
+ 'cot',
+ 'countIntersections',
+ 'crop',
+ 'cropcode',
+ 'cross',
+ 'crossframe',
+ 'crosshatch',
+ 'crossmarksize',
+ 'csc',
+ 'cubicroots',
+ 'curabscissa',
+ 'curlSpecifier',
+ 'curpoint',
+ 'currentarrow',
+ 'currentexitfunction',
+ 'currentmomarrow',
+ 'currentpolarconicroutine',
+ 'curve',
+ 'cut',
+ 'cutafter',
+ 'cutbefore',
+ 'cyclic',
+ 'cylinder',
+ 'deactivatequote',
+ 'debugger',
+ 'deconstruct',
+ 'defaultdir',
+ 'defined',
+ 'degenerate',
+ 'degrees',
+ 'delete',
+ 'deletepreamble',
+ 'determinant',
+ 'diagonal',
+ 'diamond',
+ 'diffdiv',
+ 'dir',
+ 'dirSpecifier',
+ 'dirtime',
+ 'display',
+ 'distance',
+ 'divisors',
+ 'do_overpaint',
+ 'dotsize',
+ 'downcase',
+ 'draw',
+ 'drawAll',
+ 'drawDoubleLine',
+ 'drawFermion',
+ 'drawGhost',
+ 'drawGluon',
+ 'drawMomArrow',
+ 'drawPRCcylinder',
+ 'drawPRCdisk',
+ 'drawPRCsphere',
+ 'drawPRCtube',
+ 'drawPhoton',
+ 'drawScalar',
+ 'drawVertex',
+ 'drawVertexBox',
+ 'drawVertexBoxO',
+ 'drawVertexBoxX',
+ 'drawVertexO',
+ 'drawVertexOX',
+ 'drawVertexTriangle',
+ 'drawVertexTriangleO',
+ 'drawVertexX',
+ 'drawarrow',
+ 'drawarrow2',
+ 'drawline',
+ 'drawpixel',
+ 'drawtick',
+ 'duplicate',
+ 'elle',
+ 'ellipsenodesnumber',
+ 'embed',
+ 'embed3',
+ 'empty',
+ 'enclose',
+ 'end',
+ 'endScript',
+ 'endclip',
+ 'endgroup',
+ 'endgroup3',
+ 'endl',
+ 'endpoint',
+ 'endpoints',
+ 'eof',
+ 'eol',
+ 'equation',
+ 'equations',
+ 'erase',
+ 'erasestep',
+ 'erf',
+ 'erfc',
+ 'error',
+ 'errorbar',
+ 'errorbars',
+ 'eval',
+ 'excenter',
+ 'excircle',
+ 'exit',
+ 'exitXasyMode',
+ 'exitfunction',
+ 'exp',
+ 'expfactors',
+ 'expi',
+ 'expm1',
+ 'exradius',
+ 'extend',
+ 'extension',
+ 'extouch',
+ 'fabs',
+ 'factorial',
+ 'fermat',
+ 'fft',
+ 'fhorner',
+ 'figure',
+ 'filecode',
+ 'fill',
+ 'filldraw',
+ 'filloutside',
+ 'fillrule',
+ 'find',
+ 'finite',
+ 'finiteDifferenceJacobian',
+ 'firstcut',
+ 'firstframe',
+ 'fit',
+ 'fit2',
+ 'fixedscaling',
+ 'floor',
+ 'flush',
+ 'fmdefaults',
+ 'fmod',
+ 'focusToCenter',
+ 'font',
+ 'fontcommand',
+ 'fontsize',
+ 'foot',
+ 'format',
+ 'frac',
+ 'frequency',
+ 'fromCenter',
+ 'fromFocus',
+ 'fspline',
+ 'functionshade',
+ 'gamma',
+ 'generate_random_backtrace',
+ 'generateticks',
+ 'gergonne',
+ 'getc',
+ 'getint',
+ 'getpair',
+ 'getreal',
+ 'getstring',
+ 'gettriple',
+ 'gluon',
+ 'gouraudshade',
+ 'graph',
+ 'graphic',
+ 'gray',
+ 'grestore',
+ 'grid',
+ 'gsave',
+ 'halfbox',
+ 'hatch',
+ 'hdiffdiv',
+ 'hermite',
+ 'hex',
+ 'histogram',
+ 'history',
+ 'hline',
+ 'hprojection',
+ 'hyperbolanodesnumber',
+ 'hyperlink',
+ 'hypot',
+ 'identity',
+ 'image',
+ 'incenter',
+ 'incentral',
+ 'incircle',
+ 'increasing',
+ 'incrementposition',
+ 'indexedfigure',
+ 'initXasyMode',
+ 'initdefaults',
+ 'input',
+ 'inradius',
+ 'insert',
+ 'inside',
+ 'integrate',
+ 'interactive',
+ 'interior',
+ 'interp',
+ 'interpolate',
+ 'intersect',
+ 'intersection',
+ 'intersectionpoint',
+ 'intersectionpoints',
+ 'intersections',
+ 'intouch',
+ 'inverse',
+ 'invisible',
+ 'is3D',
+ 'isCCW',
+ 'isDuplicate',
+ 'isogonal',
+ 'isogonalconjugate',
+ 'isotomic',
+ 'isotomicconjugate',
+ 'isparabola',
+ 'italic',
+ 'item',
+ 'jobname',
+ 'kurtosis',
+ 'kurtosisexcess',
+ 'label',
+ 'labelaxis',
+ 'labelmargin',
+ 'labelpath',
+ 'labels',
+ 'labeltick',
+ 'labelx',
+ 'labelx3',
+ 'labely',
+ 'labely3',
+ 'labelz',
+ 'labelz3',
+ 'lastcut',
+ 'latex',
+ 'latitude',
+ 'latticeshade',
+ 'layer',
+ 'layout',
+ 'ldexp',
+ 'leastsquares',
+ 'legend',
+ 'legenditem',
+ 'length',
+ 'lexorder',
+ 'lift',
+ 'limits',
+ 'linear',
+ 'linecap',
+ 'lineinversion',
+ 'linejoin',
+ 'linemargin',
+ 'lineskip',
+ 'linetype',
+ 'linewidth',
+ 'link',
+ 'list',
+ 'lm_enorm',
+ 'lm_evaluate_default',
+ 'lm_lmdif',
+ 'lm_lmpar',
+ 'lm_minimize',
+ 'lm_print_default',
+ 'lm_print_quiet',
+ 'lm_qrfac',
+ 'lm_qrsolv',
+ 'locale',
+ 'locate',
+ 'locatefile',
+ 'location',
+ 'log',
+ 'log10',
+ 'log1p',
+ 'logaxiscoverage',
+ 'longitude',
+ 'lookup',
+ 'makeNode',
+ 'makedraw',
+ 'makepen',
+ 'map',
+ 'margin',
+ 'markangle',
+ 'markarc',
+ 'markinterval',
+ 'marknodes',
+ 'markrightangle',
+ 'markuniform',
+ 'masscenter',
+ 'massformat',
+ 'math',
+ 'max',
+ 'max3',
+ 'maxAfterTransform',
+ 'maxbezier',
+ 'maxbound',
+ 'maxcoords',
+ 'maxlength',
+ 'maxratio',
+ 'maxtimes',
+ 'mean',
+ 'medial',
+ 'median',
+ 'midpoint',
+ 'min',
+ 'min3',
+ 'minAfterTransform',
+ 'minbezier',
+ 'minbound',
+ 'minipage',
+ 'minratio',
+ 'mintimes',
+ 'miterlimit',
+ 'mktemp',
+ 'momArrowPath',
+ 'momarrowsize',
+ 'monotonic',
+ 'multifigure',
+ 'nativeformat',
+ 'natural',
+ 'needshipout',
+ 'newl',
+ 'newpage',
+ 'newslide',
+ 'newton',
+ 'newtree',
+ 'nextframe',
+ 'nextnormal',
+ 'nextpage',
+ 'nib',
+ 'nodabscissa',
+ 'none',
+ 'norm',
+ 'normalvideo',
+ 'notaknot',
+ 'nowarn',
+ 'numberpage',
+ 'nurb',
+ 'offset',
+ 'onpath',
+ 'opacity',
+ 'opposite',
+ 'orientation',
+ 'origin',
+ 'orthic',
+ 'orthocentercenter',
+ 'outformat',
+ 'outline',
+ 'outname',
+ 'outprefix',
+ 'output',
+ 'overloadedMessage',
+ 'overwrite',
+ 'pack',
+ 'pad',
+ 'pairs',
+ 'palette',
+ 'parabolanodesnumber',
+ 'parallel',
+ 'parallelogram',
+ 'partialsum',
+ 'pattern',
+ 'pause',
+ 'pdf',
+ 'pedal',
+ 'periodic',
+ 'perp',
+ 'perpendicular',
+ 'perpendicularmark',
+ 'phantom',
+ 'phi1',
+ 'phi2',
+ 'phi3',
+ 'photon',
+ 'piecewisestraight',
+ 'polar',
+ 'polarconicroutine',
+ 'polargraph',
+ 'polygon',
+ 'postcontrol',
+ 'postscript',
+ 'pow10',
+ 'ppoint',
+ 'prc',
+ 'prc0',
+ 'precision',
+ 'precontrol',
+ 'prepend',
+ 'printBytecode',
+ 'print_random_addresses',
+ 'project',
+ 'purge',
+ 'pwhermite',
+ 'quadrant',
+ 'quadraticroots',
+ 'quantize',
+ 'quarticroots',
+ 'quotient',
+ 'radialshade',
+ 'radians',
+ 'radicalcenter',
+ 'radicalline',
+ 'radius',
+ 'rand',
+ 'randompath',
+ 'rd',
+ 'readline',
+ 'realmult',
+ 'realquarticroots',
+ 'rectangle',
+ 'rectangular',
+ 'rectify',
+ 'reflect',
+ 'relabscissa',
+ 'relative',
+ 'relativedistance',
+ 'reldir',
+ 'relpoint',
+ 'reltime',
+ 'remainder',
+ 'remark',
+ 'removeDuplicates',
+ 'rename',
+ 'replace',
+ 'report',
+ 'resetdefaultpen',
+ 'restore',
+ 'restoredefaults',
+ 'reverse',
+ 'reversevideo',
+ 'rf',
+ 'rfind',
+ 'rgb',
+ 'rgba',
+ 'rgbint',
+ 'rms',
+ 'rotate',
+ 'rotateO',
+ 'rotation',
+ 'round',
+ 'roundbox',
+ 'roundedpath',
+ 'roundrectangle',
+ 'same',
+ 'samecoordsys',
+ 'sameside',
+ 'sample',
+ 'save',
+ 'savedefaults',
+ 'saveline',
+ 'scale',
+ 'scale3',
+ 'scaleO',
+ 'scaleless',
+ 'search',
+ 'searchindex',
+ 'searchtree',
+ 'sec',
+ 'secondaryX',
+ 'secondaryY',
+ 'seconds',
+ 'section',
+ 'sector',
+ 'seek',
+ 'seekeof',
+ 'sequence',
+ 'setcontour',
+ 'setpens',
+ 'sgn',
+ 'sgnd',
+ 'sharpangle',
+ 'sharpdegrees',
+ 'shift',
+ 'shiftless',
+ 'shipout',
+ 'shipout3',
+ 'show',
+ 'simeq',
+ 'simpson',
+ 'sin',
+ 'sinh',
+ 'size',
+ 'size3',
+ 'skewness',
+ 'skip',
+ 'slant',
+ 'sleep',
+ 'slope',
+ 'slopefield',
+ 'solve',
+ 'solveBVP',
+ 'sort',
+ 'sourceline',
+ 'sphere',
+ 'split',
+ 'sqrt',
+ 'square',
+ 'srand',
+ 'standardizecoordsys',
+ 'startScript',
+ 'stdev',
+ 'step',
+ 'stickframe',
+ 'stickmarksize',
+ 'stickmarkspace',
+ 'stop',
+ 'straight',
+ 'straightness',
+ 'stripdirectory',
+ 'stripextension',
+ 'stripfile',
+ 'stripsuffix',
+ 'strokepath',
+ 'subdivide',
+ 'subitem',
+ 'subpath',
+ 'substr',
+ 'sum',
+ 'symmedial',
+ 'symmedian',
+ 'system',
+ 'tab',
+ 'tableau',
+ 'tan',
+ 'tangent',
+ 'tangential',
+ 'tangents',
+ 'tanh',
+ 'tell',
+ 'tensorshade',
+ 'tex',
+ 'texcolor',
+ 'texify',
+ 'texpath',
+ 'texpreamble',
+ 'texreset',
+ 'texshipout',
+ 'texsize',
+ 'textpath',
+ 'thick',
+ 'thin',
+ 'tick',
+ 'tickMax',
+ 'tickMax3',
+ 'tickMin',
+ 'tickMin3',
+ 'ticklabelshift',
+ 'tildeframe',
+ 'tildemarksize',
+ 'tile',
+ 'tiling',
+ 'time',
+ 'times',
+ 'title',
+ 'titlepage',
+ 'topbox',
+ 'transpose',
+ 'trembleFuzz',
+ 'triangleAbc',
+ 'triangleabc',
+ 'triangulate',
+ 'tricoef',
+ 'tridiagonal',
+ 'trim',
+ 'truepoint',
+ 'tube',
+ 'uncycle',
+ 'unfill',
+ 'uniform',
+ 'unique',
+ 'unit',
+ 'unitrand',
+ 'unitsize',
+ 'unityroot',
+ 'unstraighten',
+ 'upcase',
+ 'updatefunction',
+ 'uperiodic',
+ 'upscale',
+ 'uptodate',
+ 'usepackage',
+ 'usersetting',
+ 'usetypescript',
+ 'usleep',
+ 'value',
+ 'variance',
+ 'variancebiased',
+ 'vbox',
+ 'vectorfield',
+ 'verbatim',
+ 'view',
+ 'vperiodic',
+ 'vprojection',
+ 'warn',
+ 'warning',
+ 'windingnumber',
+ 'write',
+ 'xaxis',
+ 'xaxis3',
+ 'xaxis3At',
+ 'xaxisAt',
+ 'xequals',
+ 'xinput',
+ 'xlimits',
+ 'xoutput',
+ 'xpart',
+ 'xscale',
+ 'xscaleO',
+ 'xtick',
+ 'xtick3',
+ 'xtrans',
+ 'yaxis',
+ 'yaxis3',
+ 'yaxis3At',
+ 'yaxisAt',
+ 'yequals',
+ 'ylimits',
+ 'ypart',
+ 'yscale',
+ 'yscaleO',
+ 'ytick',
+ 'ytick3',
+ 'ytrans',
+ 'zaxis3',
+ 'zaxis3At',
+ 'zero',
+ 'zero3',
+ 'zlimits',
+ 'zpart',
+ 'ztick',
+ 'ztick3',
+ 'ztrans'
+ ),
+
+ 4 => array(
+ 'AliceBlue',
+ 'Align',
+ 'Allow',
+ 'AntiqueWhite',
+ 'Apricot',
+ 'Aqua',
+ 'Aquamarine',
+ 'Aspect',
+ 'Azure',
+ 'BeginPoint',
+ 'Beige',
+ 'Bisque',
+ 'Bittersweet',
+ 'Black',
+ 'BlanchedAlmond',
+ 'Blue',
+ 'BlueGreen',
+ 'BlueViolet',
+ 'Both',
+ 'BrickRed',
+ 'Brown',
+ 'BurlyWood',
+ 'BurntOrange',
+ 'CCW',
+ 'CW',
+ 'CadetBlue',
+ 'CarnationPink',
+ 'Center',
+ 'Centered',
+ 'Cerulean',
+ 'Chartreuse',
+ 'Chocolate',
+ 'Coeff',
+ 'Coral',
+ 'CornflowerBlue',
+ 'Cornsilk',
+ 'Crimson',
+ 'Crop',
+ 'Cyan',
+ 'Dandelion',
+ 'DarkBlue',
+ 'DarkCyan',
+ 'DarkGoldenrod',
+ 'DarkGray',
+ 'DarkGreen',
+ 'DarkKhaki',
+ 'DarkMagenta',
+ 'DarkOliveGreen',
+ 'DarkOrange',
+ 'DarkOrchid',
+ 'DarkRed',
+ 'DarkSalmon',
+ 'DarkSeaGreen',
+ 'DarkSlateBlue',
+ 'DarkSlateGray',
+ 'DarkTurquoise',
+ 'DarkViolet',
+ 'DeepPink',
+ 'DeepSkyBlue',
+ 'DefaultHead',
+ 'DimGray',
+ 'DodgerBlue',
+ 'Down',
+ 'E',
+ 'ENE',
+ 'EPS',
+ 'ESE',
+ 'E_Euler',
+ 'E_PC',
+ 'E_RK2',
+ 'E_RK3BS',
+ 'Emerald',
+ 'EndPoint',
+ 'Euler',
+ 'FireBrick',
+ 'FloralWhite',
+ 'ForestGreen',
+ 'Fuchsia',
+ 'Gainsboro',
+ 'GhostWhite',
+ 'Gold',
+ 'Goldenrod',
+ 'Gray',
+ 'Green',
+ 'GreenYellow',
+ 'Honeydew',
+ 'Horizontal',
+ 'HotPink',
+ 'I',
+ 'IgnoreAspect',
+ 'IndianRed',
+ 'Indigo',
+ 'Ivory',
+ 'JOIN_IN',
+ 'JOIN_OUT',
+ 'JungleGreen',
+ 'Khaki',
+ 'LM_DWARF',
+ 'LM_MACHEP',
+ 'LM_SQRT_DWARF',
+ 'LM_SQRT_GIANT',
+ 'LM_USERTOL',
+ 'Lavender',
+ 'LavenderBlush',
+ 'LawnGreen',
+ 'LeftJustified',
+ 'LeftSide',
+ 'LemonChiffon',
+ 'LightBlue',
+ 'LightCoral',
+ 'LightCyan',
+ 'LightGoldenrodYellow',
+ 'LightGreen',
+ 'LightGrey',
+ 'LightPink',
+ 'LightSalmon',
+ 'LightSeaGreen',
+ 'LightSkyBlue',
+ 'LightSlateGray',
+ 'LightSteelBlue',
+ 'LightYellow',
+ 'Lime',
+ 'LimeGreen',
+ 'Linen',
+ 'Logarithmic',
+ 'Magenta',
+ 'Mahogany',
+ 'MarkFill',
+ 'Maroon',
+ 'Max',
+ 'MediumAquamarine',
+ 'MediumBlue',
+ 'MediumOrchid',
+ 'MediumPurple',
+ 'MediumSeaGreen',
+ 'MediumSlateBlue',
+ 'MediumSpringGreen',
+ 'MediumTurquoise',
+ 'MediumVioletRed',
+ 'Melon',
+ 'MidPoint',
+ 'MidnightBlue',
+ 'Min',
+ 'MintCream',
+ 'MistyRose',
+ 'Moccasin',
+ 'Move',
+ 'MoveQuiet',
+ 'Mulberry',
+ 'N',
+ 'NE',
+ 'NNE',
+ 'NNW',
+ 'NW',
+ 'NavajoWhite',
+ 'Navy',
+ 'NavyBlue',
+ 'NoAlign',
+ 'NoCrop',
+ 'NoFill',
+ 'NoSide',
+ 'OldLace',
+ 'Olive',
+ 'OliveDrab',
+ 'OliveGreen',
+ 'Orange',
+ 'OrangeRed',
+ 'Orchid',
+ 'PC',
+ 'PaleGoldenrod',
+ 'PaleGreen',
+ 'PaleTurquoise',
+ 'PaleVioletRed',
+ 'PapayaWhip',
+ 'Peach',
+ 'PeachPuff',
+ 'Periwinkle',
+ 'Peru',
+ 'PineGreen',
+ 'Pink',
+ 'Plum',
+ 'PowderBlue',
+ 'ProcessBlue',
+ 'Purple',
+ 'RK2',
+ 'RK3',
+ 'RK3BS',
+ 'RK4',
+ 'RK5',
+ 'RK5DP',
+ 'RK5F',
+ 'RawSienna',
+ 'Red',
+ 'RedOrange',
+ 'RedViolet',
+ 'Rhodamine',
+ 'RightJustified',
+ 'RightSide',
+ 'RosyBrown',
+ 'RoyalBlue',
+ 'RoyalPurple',
+ 'RubineRed',
+ 'S',
+ 'SE',
+ 'SSE',
+ 'SSW',
+ 'SW',
+ 'SaddleBrown',
+ 'Salmon',
+ 'SandyBrown',
+ 'SeaGreen',
+ 'Seashell',
+ 'Sepia',
+ 'Sienna',
+ 'Silver',
+ 'SimpleHead',
+ 'SkyBlue',
+ 'SlateBlue',
+ 'SlateGray',
+ 'Snow',
+ 'SpringGreen',
+ 'SteelBlue',
+ 'Suppress',
+ 'SuppressQuiet',
+ 'TeXHead',
+ 'Teal',
+ 'TealBlue',
+ 'Thistle',
+ 'Ticksize',
+ 'Tomato',
+ 'Turquoise',
+ 'Up',
+ 'VERSION',
+ 'Value',
+ 'Vertical',
+ 'Violet',
+ 'VioletRed',
+ 'W',
+ 'WNW',
+ 'WSW',
+ 'Wheat',
+ 'White',
+ 'WhiteSmoke',
+ 'WildStrawberry',
+ 'XYAlign',
+ 'YAlign',
+ 'Yellow',
+ 'YellowGreen',
+ 'YellowOrange',
+ 'allowstepping',
+ 'angularsystem',
+ 'animationdelay',
+ 'appendsuffix',
+ 'arcarrowangle',
+ 'arcarrowfactor',
+ 'arrow2sizelimit',
+ 'arrowangle',
+ 'arrowbarb',
+ 'arrowdir',
+ 'arrowfactor',
+ 'arrowhookfactor',
+ 'arrowlength',
+ 'arrowsizelimit',
+ 'arrowtexfactor',
+ 'authorpen',
+ 'axislabelfactor',
+ 'background',
+ 'backgroundcolor',
+ 'backgroundpen',
+ 'barfactor',
+ 'barmarksizefactor',
+ 'basealign',
+ 'baselinetemplate',
+ 'beveljoin',
+ 'bigvertexpen',
+ 'bigvertexsize',
+ 'black',
+ 'blue',
+ 'bm',
+ 'bottom',
+ 'bp',
+ 'brown',
+ 'bullet',
+ 'byfoci',
+ 'byvertices',
+ 'camerafactor',
+ 'chartreuse',
+ 'circlemarkradiusfactor',
+ 'circlenodesnumberfactor',
+ 'circleprecision',
+ 'circlescale',
+ 'cm',
+ 'codefile',
+ 'codepen',
+ 'codeskip',
+ 'colorPen',
+ 'coloredNodes',
+ 'coloredSegments',
+ 'conditionlength',
+ 'conicnodesfactor',
+ 'count',
+ 'cputimeformat',
+ 'crossmarksizefactor',
+ 'currentcoordsys',
+ 'currentlight',
+ 'currentpatterns',
+ 'currentpen',
+ 'currentpicture',
+ 'currentposition',
+ 'currentprojection',
+ 'curvilinearsystem',
+ 'cuttings',
+ 'cyan',
+ 'darkblue',
+ 'darkbrown',
+ 'darkcyan',
+ 'darkgray',
+ 'darkgreen',
+ 'darkgrey',
+ 'darkmagenta',
+ 'darkolive',
+ 'darkred',
+ 'dashdotted',
+ 'dashed',
+ 'datepen',
+ 'dateskip',
+ 'debuggerlines',
+ 'debugging',
+ 'deepblue',
+ 'deepcyan',
+ 'deepgray',
+ 'deepgreen',
+ 'deepgrey',
+ 'deepmagenta',
+ 'deepred',
+ 'default',
+ 'defaultControl',
+ 'defaultS',
+ 'defaultbackpen',
+ 'defaultcoordsys',
+ 'defaultexcursion',
+ 'defaultfilename',
+ 'defaultformat',
+ 'defaultmassformat',
+ 'defaultpen',
+ 'diagnostics',
+ 'differentlengths',
+ 'dot',
+ 'dotfactor',
+ 'dotframe',
+ 'dotted',
+ 'doublelinepen',
+ 'doublelinespacing',
+ 'down',
+ 'duplicateFuzz',
+ 'edge',
+ 'ellipsenodesnumberfactor',
+ 'eps',
+ 'epsgeo',
+ 'epsilon',
+ 'evenodd',
+ 'expansionfactor',
+ 'extendcap',
+ 'exterior',
+ 'fermionpen',
+ 'figureborder',
+ 'figuremattpen',
+ 'file3',
+ 'firstnode',
+ 'firststep',
+ 'foregroundcolor',
+ 'fuchsia',
+ 'fuzz',
+ 'gapfactor',
+ 'ghostpen',
+ 'gluonamplitude',
+ 'gluonpen',
+ 'gluonratio',
+ 'green',
+ 'grey',
+ 'hatchepsilon',
+ 'havepagenumber',
+ 'heavyblue',
+ 'heavycyan',
+ 'heavygray',
+ 'heavygreen',
+ 'heavygrey',
+ 'heavymagenta',
+ 'heavyred',
+ 'hwratio',
+ 'hyperbolanodesnumberfactor',
+ 'identity4',
+ 'ignore',
+ 'inXasyMode',
+ 'inch',
+ 'inches',
+ 'includegraphicscommand',
+ 'inf',
+ 'infinity',
+ 'institutionpen',
+ 'intMax',
+ 'intMin',
+ 'invert',
+ 'itempen',
+ 'itemskip',
+ 'itemstep',
+ 'landscape',
+ 'lastnode',
+ 'left',
+ 'legendhskip',
+ 'legendlinelength',
+ 'legendmargin',
+ 'legendmarkersize',
+ 'legendmaxrelativewidth',
+ 'legendvskip',
+ 'lightblue',
+ 'lightcyan',
+ 'lightgray',
+ 'lightgreen',
+ 'lightgrey',
+ 'lightmagenta',
+ 'lightolive',
+ 'lightred',
+ 'lightyellow',
+ 'lm_infmsg',
+ 'lm_shortmsg',
+ 'longdashdotted',
+ 'longdashed',
+ 'magenta',
+ 'magneticRadius',
+ 'mantissaBits',
+ 'markangleradius',
+ 'markangleradiusfactor',
+ 'markanglespace',
+ 'markanglespacefactor',
+ 'mediumblue',
+ 'mediumcyan',
+ 'mediumgray',
+ 'mediumgreen',
+ 'mediumgrey',
+ 'mediummagenta',
+ 'mediumred',
+ 'mediumyellow',
+ 'middle',
+ 'minDistDefault',
+ 'minblockheight',
+ 'minblockwidth',
+ 'mincirclediameter',
+ 'minipagemargin',
+ 'minipagewidth',
+ 'minvertexangle',
+ 'miterjoin',
+ 'mm',
+ 'momarrowfactor',
+ 'momarrowlength',
+ 'momarrowmargin',
+ 'momarrowoffset',
+ 'momarrowpen',
+ 'monoPen',
+ 'morepoints',
+ 'nCircle',
+ 'newbulletcolor',
+ 'ngraph',
+ 'nil',
+ 'nmesh',
+ 'nobasealign',
+ 'nodeMarginDefault',
+ 'nodesystem',
+ 'nomarker',
+ 'nopoint',
+ 'noprimary',
+ 'nullpath',
+ 'nullpen',
+ 'numarray',
+ 'ocgindex',
+ 'oldbulletcolor',
+ 'olive',
+ 'orange',
+ 'overpaint',
+ 'page',
+ 'pageheight',
+ 'pagemargin',
+ 'pagenumberalign',
+ 'pagenumberpen',
+ 'pagenumberposition',
+ 'pagewidth',
+ 'paleblue',
+ 'palecyan',
+ 'palegray',
+ 'palegreen',
+ 'palegrey',
+
+ 'palemagenta',
+ 'palered',
+ 'paleyellow',
+ 'parabolanodesnumberfactor',
+ 'perpfactor',
+ 'phi',
+ 'photonamplitude',
+ 'photonpen',
+ 'photonratio',
+ 'pi',
+ 'pink',
+ 'plain',
+ 'plain_bounds',
+ 'plain_scaling',
+ 'plus',
+ 'preamblenodes',
+ 'pt',
+ 'purple',
+ 'r3',
+ 'r4a',
+ 'r4b',
+ 'randMax',
+ 'realDigits',
+ 'realEpsilon',
+ 'realMax',
+ 'realMin',
+ 'red',
+ 'relativesystem',
+ 'right',
+ 'roundcap',
+ 'roundjoin',
+ 'royalblue',
+ 'salmon',
+ 'saveFunctions',
+ 'scalarpen',
+ 'sequencereal',
+ 'settings',
+ 'shipped',
+ 'signedtrailingzero',
+ 'solid',
+ 'springgreen',
+ 'sqrtEpsilon',
+ 'squarecap',
+ 'squarepen',
+ 'startposition',
+ 'stdin',
+ 'stdout',
+ 'stepfactor',
+ 'stepfraction',
+ 'steppagenumberpen',
+ 'stepping',
+ 'stickmarksizefactor',
+ 'stickmarkspacefactor',
+ 'swap',
+ 'textpen',
+ 'ticksize',
+ 'tildemarksizefactor',
+ 'tinv',
+ 'titlealign',
+ 'titlepagepen',
+ 'titlepageposition',
+ 'titlepen',
+ 'titleskip',
+ 'top',
+ 'trailingzero',
+ 'treeLevelStep',
+ 'treeMinNodeWidth',
+ 'treeNodeStep',
+ 'trembleAngle',
+ 'trembleFrequency',
+ 'trembleRandom',
+ 'undefined',
+ 'unitcircle',
+ 'unitsquare',
+ 'up',
+ 'urlpen',
+ 'urlskip',
+ 'version',
+ 'vertexpen',
+ 'vertexsize',
+ 'viewportmargin',
+ 'viewportsize',
+ 'vline',
+ 'white',
+ 'wye',
+ 'xformStack',
+ 'yellow',
+ 'ylabelwidth',
+ 'zerotickfuzz',
+ 'zerowinding'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '(', ')', '{', '}', '[', ']'
+ ),
+ 1 => array('<', '>', '='),
+ 2 => array('+', '-', '*', '/', '%'),
+ 3 => array('!', '^', '&', '|'),
+ 4 => array('?', ':', ';'),
+ 5 => array('..')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #990000;',
+ 4 => 'color: #009900; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666;',
+ 2 => 'color: #339900;',
+ 'MULTI' => 'color: #ff0000; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #007788;',
+ 2 => 'color: #007788;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;',
+ 1 => 'color: #000080;',
+ 2 => 'color: #000040;',
+ 3 => 'color: #000040;',
+ 4 => 'color: #008080;',
+ 5 => 'color: #009080;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_\|%\\-])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/autoconf.php b/platform/www/vendor/geshi/geshi/src/geshi/autoconf.php
new file mode 100644
index 0000000..f7090fe
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/autoconf.php
@@ -0,0 +1,510 @@
+<?php
+/*************************************************************************************
+ * autoconf.php
+ * -----
+ * Author: Mihai Vasilian (grayasm@gmail.com)
+ * Copyright: (c) 2010 Mihai Vasilian
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/01/25
+ *
+ * autoconf language file for GeSHi.
+ *
+ ***********************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Autoconf',
+ 'COMMENT_SINGLE' => array(2 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ //Multiline-continued single-line comments
+ 1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Multiline-continued preprocessor define
+ 2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Single Line comment started by dnl
+ 3 => '/(?<!\$)\bdnl\b.*$/m',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'AC_ACT_IFELSE',
+ 'AC_AIX',
+ 'AC_ALLOCA',
+ 'AC_ARG_ARRAY',
+ 'AC_ARG_ENABLE',
+ 'AC_ARG_PROGRAM',
+ 'AC_ARG_VAR',
+ 'AC_ARG_WITH',
+ 'AC_AUTOCONF_VERSION',
+ 'AC_BEFORE',
+ 'AC_C_BACKSLASH_A',
+ 'AC_C_BIGENDIAN',
+ 'AC_C_CHAR_UNSIGNED',
+ 'AC_C_CONST',
+ 'AC_C_CROSS',
+ 'AC_C_FLEXIBLE_ARRAY_MEMBER',
+ 'AC_C_INLINE',
+ 'AC_C_LONG_DOUBLE',
+ 'AC_C_PROTOTYPES',
+ 'AC_C_RESTRICT',
+ 'AC_C_STRINGIZE',
+ 'AC_C_TYPEOF',
+ 'AC_C_VARARRAYS',
+ 'AC_C_VOLATILE',
+ 'AC_CACHE_CHECK',
+ 'AC_CACHE_LOAD',
+ 'AC_CACHE_SAVE',
+ 'AC_CACHE_VAL',
+ 'AC_CANONICAL_BUILD',
+ 'AC_CANONICAL_HOST',
+ 'AC_CANONICAL_SYSTEM',
+ 'AC_CANONICAL_TARGET',
+ 'AC_CHAR_UNSIGNED',
+ 'AC_CHECK_ALIGNOF',
+ 'AC_CHECK_DECL',
+ 'AC_CHECK_DECLS',
+ 'AC_CHECK_DECLS_ONCE',
+ 'AC_CHECK_FILE',
+ 'AC_CHECK_FILES',
+ 'AC_CHECK_FUNC',
+ 'AC_CHECK_FUNCS',
+ 'AC_CHECK_FUNCS_ONCE',
+ 'AC_CHECK_HEADER',
+ 'AC_CHECK_HEADERS',
+ 'AC_CHECK_HEADERS_ONCE',
+ 'AC_CHECK_LIB',
+ 'AC_CHECK_MEMBER',
+ 'AC_CHECK_MEMBERS',
+ 'AC_CHECK_PROG',
+ 'AC_CHECK_PROGS',
+ 'AC_CHECK_SIZEOF',
+ 'AC_CHECK_TARGET_TOOL',
+ 'AC_CHECK_TARGET_TOOLS',
+ 'AC_CHECK_TOOL',
+ 'AC_CHECK_TOOLS',
+ 'AC_CHECK_TYPE',
+ 'AC_CHECK_TYPES',
+ 'AC_CHECKING',
+ 'AC_COMPILE_CHECK',
+ 'AC_COMPILE_IFELSE',
+ 'AC_COMPUTE_INT',
+ 'AC_CONFIG_AUX_DIR',
+ 'AC_CONFIG_COMMANDS',
+ 'AC_CONFIG_COMMANDS_POST',
+ 'AC_CONFIG_COMMANDS_PRE',
+ 'AC_CONFIG_FILES',
+ 'AC_CONFIG_HEADERS',
+ 'AC_CONFIG_ITEMS',
+ 'AC_CONFIG_LIBOBJ_DIR',
+ 'AC_CONFIG_LINKS',
+ 'AC_CONFIG_MACRO_DIR',
+ 'AC_CONFIG_SRCDIR',
+ 'AC_CONFIG_SUBDIRS',
+ 'AC_CONFIG_TESTDIR',
+ 'AC_CONST',
+ 'AC_COPYRIGHT',
+ 'AC_CROSS_CHECK',
+ 'AC_CYGWIN',
+ 'AC_DATAROOTDIR_CHECKED',
+ 'AC_DECL_SYS_SIGLIST',
+ 'AC_DECL_YYTEXT',
+ 'AC_DEFINE',
+ 'AC_DEFINE_UNQUOTED',
+ 'AC_DEFUN',
+ 'AC_DEFUN_ONCE',
+ 'AC_DIAGNOSE',
+ 'AC_DIR_HEADER',
+ 'AC_DISABLE_OPTION_CHECKING',
+ 'AC_DYNIX_SEQ',
+ 'AC_EGREP_CPP',
+ 'AC_EGREP_HEADER',
+ 'AC_EMXOS2',
+ 'AC_ENABLE',
+ 'AC_ERLANG_CHECK_LIB',
+ 'AC_ERLANG_NEED_ERL',
+ 'AC_ERLANG_NEED_ERLC',
+ 'AC_ERLANG_PATH_ERL',
+ 'AC_ERLANG_PATH_ERLC',
+ 'AC_ERLANG_SUBST_ERTS_VER',
+ 'AC_ERLANG_SUBST_INSTALL_LIB_DIR',
+ 'AC_ERLANG_SUBST_INSTALL_LIB_SUBDIR',
+ 'AC_ERLANG_SUBST_LIB_DIR',
+ 'AC_ERLANG_SUBST_ROOT_DIR',
+ 'AC_ERROR',
+ 'AC_EXEEXT',
+ 'AC_F77_DUMMY_MAIN',
+ 'AC_F77_FUNC',
+ 'AC_F77_LIBRARY_LDFLAGS',
+ 'AC_F77_MAIN',
+ 'AC_F77_WRAPPERS',
+ 'AC_FATAL',
+ 'AC_FC_FREEFORM',
+ 'AC_FC_FUNC',
+ 'AC_FC_LIBRARY_LDFLAGS',
+ 'AC_FC_MAIN',
+ 'AC_FC_SRCEXT',
+ 'AC_FC_WRAPPERS',
+ 'AC_FIND_X',
+ 'AC_FIND_XTRA',
+ 'AC_FOREACH',
+ 'AC_FUNC_ALLOCA',
+ 'AC_FUNC_CHECK',
+ 'AC_FUNC_CHOWN',
+ 'AC_FUNC_CLOSEDIR_VOID',
+ 'AC_FUNC_ERROR_AT_LINE',
+ 'AC_FUNC_FNMATCH',
+ 'AC_FUNC_FNMATCH_GNU',
+ 'AC_FUNC_FORK',
+ 'AC_FUNC_FSEEKO',
+ 'AC_FUNC_GETGROUPS',
+ 'AC_FUNC_GETLOADAVG',
+ 'AC_FUNC_GETMNTENT',
+ 'AC_FUNC_GETPGRP',
+ 'AC_FUNC_LSTAT',
+ 'AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK',
+ 'AC_FUNC_MALLOC',
+ 'AC_FUNC_MBRTOWC',
+ 'AC_FUNC_MEMCMP',
+ 'AC_FUNC_MKTIME',
+ 'AC_FUNC_MMAP',
+ 'AC_FUNC_OBSTACK',
+ 'AC_FUNC_REALLOC',
+ 'AC_FUNC_SELECT_ARGTYPES',
+ 'AC_FUNC_SETPGRP',
+ 'AC_FUNC_SETVBUF_REVERSED',
+ 'AC_FUNC_STAT',
+ 'AC_FUNC_STRCOLL',
+ 'AC_FUNC_STRERROR_R',
+ 'AC_FUNC_STRFTIME',
+ 'AC_FUNC_STRNLEN',
+ 'AC_FUNC_STRTOD',
+ 'AC_FUNC_STRTOLD',
+ 'AC_FUNC_UTIME_NULL',
+ 'AC_FUNC_VPRINTF',
+ 'AC_FUNC_WAIT3',
+ 'AC_GCC_TRADITIONAL',
+ 'AC_GETGROUPS_T',
+ 'AC_GETLOADAVG',
+ 'AC_GNU_SOURCE',
+ 'AC_HAVE_FUNCS',
+ 'AC_HAVE_HEADERS',
+ 'AC_HAVE_LIBRARY',
+ 'AC_HAVE_POUNDBANG',
+ 'AC_HEADER_ASSERT',
+ 'AC_HEADER_CHECK',
+ 'AC_HEADER_DIRENT',
+ 'AC_HEADER_EGREP',
+ 'AC_HEADER_MAJOR',
+ 'AC_HEADER_RESOLV',
+ 'AC_HEADER_STAT',
+ 'AC_HEADER_STDBOOL',
+ 'AC_HEADER_STDC',
+ 'AC_HEADER_SYS_WAIT',
+ 'AC_HEADER_TIME',
+ 'AC_HEADER_TIOCGWINSZ',
+ 'AC_HELP_STRING',
+ 'AC_INCLUDES_DEFAULT',
+ 'AC_INIT',
+ 'AC_INLINE',
+ 'AC_INT_16_BITS',
+ 'AC_IRIX_SUN',
+ 'AC_ISC_POSIX',
+ 'AC_LANG_ASSERT',
+ 'AC_LANG_C',
+ 'AC_LANG_CALL',
+ 'AC_LANG_CONFTEST',
+ 'AC_LANG_CPLUSPLUS',
+ 'AC_LANG_FORTRAN77',
+ 'AC_LANG_FUNC_LINK_TRY',
+ 'AC_LANG_POP',
+ 'AC_LANG_PROGRAM',
+ 'AC_LANG_PUSH',
+ 'AC_LANG_RESTORE',
+ 'AC_LANG_SAVE',
+ 'AC_LANG_SOURCE',
+ 'AC_LANG_WERROR',
+ 'AC_LIBOBJ',
+ 'AC_LIBSOURCE',
+ 'AC_LIBSOURCES',
+ 'AC_LINK_FILES',
+ 'AC_LINK_IFELSE',
+ 'AC_LN_S',
+ 'AC_LONG_64_BITS',
+ 'AC_LONG_DOUBLE',
+ 'AC_LONG_FILE_NAMES',
+ 'AC_MAJOR_HEADER',
+ 'AC_MEMORY_H',
+ 'AC_MINGW32',
+ 'AC_MINIX',
+ 'AC_MINUS_C_MINUS_O',
+ 'AC_MMAP',
+ 'AC_MODE_T',
+ 'AC_MSG_CHECKING',
+ 'AC_MSG_ERROR',
+ 'AC_MSG_FAILURE',
+ 'AC_MSG_NOTICE',
+ 'AC_MSG_RESULT',
+ 'AC_MSG_WARN',
+ 'AC_OBJEXT',
+ 'AC_OBSOLETE',
+ 'AC_OFF_T',
+ 'AC_OPENMP',
+ 'AC_OUTPUT',
+ 'AC_OUTPUT_COMMANDS',
+ 'AC_PACKAGE_BUGREPORT',
+ 'AC_PACKAGE_NAME',
+ 'AC_PACKAGE_STRING',
+ 'AC_PACKAGE_TARNAME',
+ 'AC_PACKAGE_URL',
+ 'AC_PACKAGE_VERSION',
+ 'AC_PATH_PROG',
+ 'AC_PATH_PROGS',
+ 'AC_PATH_PROGS_FEATURE_CHECK',
+ 'AC_PATH_TARGET_TOOL',
+ 'AC_PATH_TOOL',
+ 'AC_PATH_X',
+ 'AC_PATH_XTRA',
+ 'AC_PID_T',
+ 'AC_PREFIX',
+ 'AC_PREFIX_DEFAULT',
+ 'AC_PREFIX_PROGRAM',
+ 'AC_PREPROC_IFELSE',
+ 'AC_PREREQ',
+ 'AC_PRESERVE_HELP_ORDER',
+ 'AC_PROG_AWK',
+ 'AC_PROG_CC',
+ 'AC_PROG_CC_C89',
+ 'AC_PROG_CC_C99',
+ 'AC_PROG_CC_C_O',
+ 'AC_PROG_CC_STDC',
+ 'AC_PROG_CPP',
+ 'AC_PROG_CPP_WERROR',
+ 'AC_PROG_CXX',
+ 'AC_PROG_CXX_C_O',
+ 'AC_PROG_CXXCPP',
+ 'AC_PROG_EGREP',
+ 'AC_PROG_F77',
+ 'AC_PROG_F77_C_O',
+ 'AC_PROG_FC',
+ 'AC_PROG_FC_C_O',
+ 'AC_PROG_FGREP',
+ 'AC_PROG_GCC_TRADITIONAL',
+ 'AC_PROG_GREP',
+ 'AC_PROG_INSTALL',
+ 'AC_PROG_LEX',
+ 'AC_PROG_LN_S',
+ 'AC_PROG_MAKE_SET',
+ 'AC_PROG_MKDIR_P',
+ 'AC_PROG_OBJC',
+ 'AC_PROG_OBJCPP',
+ 'AC_PROG_OBJCXX',
+ 'AC_PROG_OBJCXXCPP',
+ 'AC_PROG_RANLIB',
+ 'AC_PROG_SED',
+ 'AC_PROG_YACC',
+ 'AC_PROGRAM_CHECK',
+ 'AC_PROGRAM_EGREP',
+ 'AC_PROGRAM_PATH',
+ 'AC_PROGRAMS_CHECK',
+ 'AC_PROGRAMS_PATH',
+ 'AC_REMOTE_TAPE',
+ 'AC_REPLACE_FNMATCH',
+ 'AC_REPLACE_FUNCS',
+ 'AC_REQUIRE',
+ 'AC_REQUIRE_AUX_FILE',
+ 'AC_REQUIRE_CPP',
+ 'AC_RESTARTABLE_SYSCALLS',
+ 'AC_RETSIGTYPE',
+ 'AC_REVISION',
+ 'AC_RSH',
+ 'AC_RUN_IFELSE',
+ 'AC_SCO_INTL',
+ 'AC_SEARCH_LIBS',
+ 'AC_SET_MAKE',
+ 'AC_SETVBUF_REVERSED',
+ 'AC_SIZE_T',
+ 'AC_SIZEOF_TYPE',
+ 'AC_ST_BLKSIZE',
+ 'AC_ST_BLOCKS',
+ 'AC_ST_RDEV',
+ 'AC_STAT_MACROS_BROKEN',
+ 'AC_STDC_HEADERS',
+ 'AC_STRCOLL',
+ 'AC_STRUCT_DIRENT_D_INO',
+ 'AC_STRUCT_DIRENT_D_TYPE',
+ 'AC_STRUCT_ST_BLKSIZE',
+ 'AC_STRUCT_ST_BLOCKS',
+ 'AC_STRUCT_ST_RDEV',
+ 'AC_STRUCT_TIMEZONE',
+ 'AC_STRUCT_TM',
+ 'AC_SUBST',
+ 'AC_SUBST_FILE',
+ 'AC_SYS_INTERPRETER',
+ 'AC_SYS_LARGEFILE',
+ 'AC_SYS_LONG_FILE_NAMES',
+ 'AC_SYS_POSIX_TERMIOS',
+ 'AC_SYS_RESTARTABLE_SYSCALLS',
+ 'AC_SYS_SIGLIST_DECLARED',
+ 'AC_TEST_CPP',
+ 'AC_TEST_PROGRAM',
+ 'AC_TIME_WITH_SYS_TIME',
+ 'AC_TIMEZONE',
+ 'AC_TRY_ACT',
+ 'AC_TRY_COMPILE',
+ 'AC_TRY_CPP',
+ 'AC_TRY_LINK',
+ 'AC_TRY_LINK_FUNC',
+ 'AC_TRY_RUN',
+ 'AC_TYPE_GETGROUPS',
+ 'AC_TYPE_INT16_T',
+ 'AC_TYPE_INT32_T',
+ 'AC_TYPE_INT64_T',
+ 'AC_TYPE_INT8_T',
+ 'AC_TYPE_INTMAX_T',
+ 'AC_TYPE_INTPTR_T',
+ 'AC_TYPE_LONG_DOUBLE',
+ 'AC_TYPE_LONG_DOUBLE_WIDER',
+ 'AC_TYPE_LONG_LONG_INT',
+ 'AC_TYPE_MBSTATE_T',
+ 'AC_TYPE_MODE_T',
+ 'AC_TYPE_OFF_T',
+ 'AC_TYPE_PID_T',
+ 'AC_TYPE_SIGNAL',
+ 'AC_TYPE_SIZE_T',
+ 'AC_TYPE_SSIZE_T',
+ 'AC_TYPE_UID_T',
+ 'AC_TYPE_UINT16_T',
+ 'AC_TYPE_UINT32_T',
+ 'AC_TYPE_UINT64_T',
+ 'AC_TYPE_UINT8_T',
+ 'AC_TYPE_UINTMAX_T',
+ 'AC_TYPE_UINTPTR_T',
+ 'AC_TYPE_UNSIGNED_LONG_LONG_INT',
+ 'AC_UID_T',
+ 'AC_UNISTD_H',
+ 'AC_USE_SYSTEM_EXTENSIONS',
+ 'AC_USG',
+ 'AC_UTIME_NULL',
+ 'AC_VALIDATE_CACHED_SYSTEM_TUPLE',
+ 'AC_VERBOSE',
+ 'AC_VFORK',
+ 'AC_VPRINTF',
+ 'AC_WAIT3',
+ 'AC_WARN',
+ 'AC_WARNING',
+ 'AC_WITH',
+ 'AC_WORDS_BIGENDIAN',
+ 'AC_XENIX_DIR',
+ 'AC_YYTEXT_POINTER',
+ 'AH_BOTTOM',
+ 'AH_HEADER',
+ 'AH_TEMPLATE',
+ 'AH_TOP',
+ 'AH_VERBATIM',
+ 'AU_ALIAS',
+ 'AU_DEFUN'),
+ ),
+ 'SYMBOLS' => array('(', ')', '[', ']', '!', '@', '%', '&', '*', '|', '/', '<', '>', ';;', '`'),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00ffff;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666;',
+ 2 => 'color: #339900;',
+ 3 => 'color: #666666;',
+ 'MULTI' => 'color: #ff0000; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;',
+ 1 => 'color: #000099;',
+ 2 => 'color: #660099;',
+ 3 => 'color: #660099;',
+ 4 => 'color: #660099;',
+ 5 => 'color: #006699;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #996600;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;',
+ 1 => 'color: #000080;',
+ 2 => 'color: #000040;',
+ 3 => 'color: #000040;',
+ 4 => 'color: #008080;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'COMMENTS' => array(
+ 'DISALLOWED_BEFORE' => '$'
+ ),
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![\.\-a-zA-Z0-9_\$\#])",
+ 'DISALLOWED_AFTER' => "(?![\.\-a-zA-Z0-9_%\\/])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/autohotkey.php b/platform/www/vendor/geshi/geshi/src/geshi/autohotkey.php
new file mode 100644
index 0000000..03a03ab
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/autohotkey.php
@@ -0,0 +1,371 @@
+<?php
+/*************************************************************************************
+ * autohotkey.php
+ * --------
+ * Author: Naveen Garg (naveen.garg@gmail.com)
+ * Copyright: (c) 2009 Naveen Garg and GeSHi
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/06/11
+ *
+ * Autohotkey language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * Release 1.0.8.5 (2009/06/11)
+ * - First Release
+ *
+ * TODO
+ * ----
+ * Reference: http://www.autohotkey.com/docs/
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Autohotkey',
+ 'COMMENT_SINGLE' => array(
+ 1 => ';'
+ ),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'while','if','and','or','else','return'
+ ),
+ 2 => array(
+ // built in variables
+ 'A_AhkPath','A_AhkVersion','A_AppData','A_AppDataCommon',
+ 'A_AutoTrim','A_BatchLines','A_CaretX','A_CaretY',
+ 'A_ComputerName','A_ControlDelay','A_Cursor','A_DD',
+ 'A_DDD','A_DDDD','A_DefaultMouseSpeed','A_Desktop',
+ 'A_DesktopCommon','A_DetectHiddenText','A_DetectHiddenWindows','A_EndChar',
+ 'A_EventInfo','A_ExitReason','A_FormatFloat','A_FormatInteger',
+ 'A_Gui','A_GuiEvent','A_GuiControl','A_GuiControlEvent',
+ 'A_GuiHeight','A_GuiWidth','A_GuiX','A_GuiY',
+ 'A_Hour','A_IconFile','A_IconHidden','A_IconNumber',
+ 'A_IconTip','A_Index','A_IPAddress1','A_IPAddress2',
+ 'A_IPAddress3','A_IPAddress4','A_ISAdmin','A_IsCompiled',
+ 'A_IsCritical','A_IsPaused','A_IsSuspended','A_KeyDelay',
+ 'A_Language','A_LastError','A_LineFile','A_LineNumber',
+ 'A_LoopField','A_LoopFileAttrib','A_LoopFileDir','A_LoopFileExt',
+ 'A_LoopFileFullPath','A_LoopFileLongPath','A_LoopFileName','A_LoopFileShortName',
+ 'A_LoopFileShortPath','A_LoopFileSize','A_LoopFileSizeKB','A_LoopFileSizeMB',
+ 'A_LoopFileTimeAccessed','A_LoopFileTimeCreated','A_LoopFileTimeModified','A_LoopReadLine',
+ 'A_LoopRegKey','A_LoopRegName','A_LoopRegSubkey','A_LoopRegTimeModified',
+ 'A_LoopRegType','A_MDAY','A_Min','A_MM',
+ 'A_MMM','A_MMMM','A_Mon','A_MouseDelay',
+ 'A_MSec','A_MyDocuments','A_Now','A_NowUTC',
+ 'A_NumBatchLines','A_OSType','A_OSVersion','A_PriorHotkey',
+ 'A_ProgramFiles','A_Programs','A_ProgramsCommon','A_ScreenHeight',
+ 'A_ScreenWidth','A_ScriptDir','A_ScriptFullPath','A_ScriptName',
+ 'A_Sec','A_Space','A_StartMenu','A_StartMenuCommon',
+ 'A_Startup','A_StartupCommon','A_StringCaseSense','A_Tab',
+ 'A_Temp','A_ThisFunc','A_ThisHotkey','A_ThisLabel',
+ 'A_ThisMenu','A_ThisMenuItem','A_ThisMenuItemPos','A_TickCount',
+ 'A_TimeIdle','A_TimeIdlePhysical','A_TimeSincePriorHotkey','A_TimeSinceThisHotkey',
+ 'A_TitleMatchMode','A_TitleMatchModeSpeed','A_UserName','A_WDay',
+ 'A_WinDelay','A_WinDir','A_WorkingDir','A_YDay',
+ 'A_YEAR','A_YWeek','A_YYYY','Clipboard',
+ 'ClipboardAll','ComSpec','ErrorLevel','ProgramFiles',
+ ),
+ 3 => array(
+ 'AutoTrim',
+ 'BlockInput','Break','Click',
+ 'ClipWait','Continue','Control',
+ 'ControlClick','ControlFocus','ControlGet',
+ 'ControlGetFocus','ControlGetPos','ControlGetText',
+ 'ControlMove','ControlSend','ControlSendRaw',
+ 'ControlSetText','CoordMode','Critical',
+ 'DetectHiddenText','DetectHiddenWindows','DllCall','Drive',
+ 'DriveGet','DriveSpaceFree',
+ 'Else','EnvAdd','EnvDiv',
+ 'EnvGet','EnvMult','EnvSet',
+ 'EnvSub','EnvUpdate','Exit',
+ 'ExitApp','FileAppend','FileCopy',
+ 'FileCopyDir','FileCreateDir','FileCreateShortcut',
+ 'FileDelete','FileGetAttrib','FileGetShortcut',
+ 'FileGetSize','FileGetTime','FileGetVersion',
+ 'FileInstall','FileMove','FileMoveDir',
+ 'FileRead','FileReadLine','FileRecycle',
+ 'FileRecycleEmpty','FileRemoveDir','FileSelectFile',
+ 'FileSelectFolder','FileSetAttrib','FileSetTime',
+ 'FormatTime','Gosub',
+ 'Goto','GroupActivate','GroupAdd',
+ 'GroupClose','GroupDeactivate','Gui',
+ 'GuiControl','GuiControlGet','Hotkey',
+ 'IfExist','IfGreater','IfGreaterOrEqual',
+ 'IfInString','IfLess','IfLessOrEqual',
+ 'IfMsgBox','IfNotEqual','IfNotExist',
+ 'IfNotInString','IfWinActive','IfWinExist',
+ 'IfWinNotActive','IfWinNotExist','ImageSearch',
+ 'IniDelete','IniRead','IniWrite',
+ 'Input','InputBox','KeyHistory',
+ 'KeyWait','ListHotkeys','ListLines',
+ 'ListVars','Loop',
+ 'Menu','MouseClick','MouseClickDrag',
+ 'MouseGetPos','MouseMove','MsgBox',
+ 'OnMessage','OnExit','OutputDebug',
+ 'PixelGetColor','PixelSearch','PostMessage',
+ 'Process','Progress','Random',
+ 'RegExMatch','RegExReplace','RegisterCallback',
+ 'RegDelete','RegRead','RegWrite',
+ 'Reload','Repeat','Return',
+ 'Run','RunAs','RunWait',
+ 'Send','SendEvent','SendInput',
+ 'SendMessage','SendMode','SendPlay',
+ 'SendRaw','SetBatchLines','SetCapslockState',
+ 'SetControlDelay','SetDefaultMouseSpeed','SetEnv',
+ 'SetFormat','SetKeyDelay','SetMouseDelay',
+ 'SetNumlockState','SetScrollLockState','SetStoreCapslockMode',
+ 'SetTimer','SetTitleMatchMode','SetWinDelay',
+ 'SetWorkingDir','Shutdown','Sleep',
+ 'Sort','SoundBeep','SoundGet',
+ 'SoundGetWaveVolume','SoundPlay','SoundSet',
+ 'SoundSetWaveVolume','SplashImage','SplashTextOff',
+ 'SplashTextOn','SplitPath','StatusBarGetText',
+ 'StatusBarWait','StringCaseSense','StringGetPos',
+ 'StringLeft','StringLen','StringLower',
+ 'StringMid','StringReplace','StringRight',
+ 'StringSplit','StringTrimLeft','StringTrimRight',
+ 'StringUpper','Suspend','SysGet',
+ 'Thread','ToolTip','Transform',
+ 'TrayTip','URLDownloadToFile','While',
+ 'VarSetCapacity',
+ 'WinActivate','WinActivateBottom','WinClose',
+ 'WinGet','WinGetActiveStats','WinGetActiveTitle',
+ 'WinGetClass','WinGetPos','WinGetText',
+ 'WinGetTitle','WinHide','WinKill',
+ 'WinMaximize','WinMenuSelectItem','WinMinimize',
+ 'WinMinimizeAll','WinMinimizeAllUndo','WinMove',
+ 'WinRestore','WinSet','WinSetTitle',
+ 'WinShow','WinWait','WinWaitActive',
+ 'WinWaitClose','WinWaitNotActive'
+ ),
+ 4 => array(
+ 'Abs','ACos','Asc','ASin',
+ 'ATan','Ceil','Chr','Cos',
+ 'Exp','FileExist','Floor',
+ 'GetKeyState','IL_Add','IL_Create','IL_Destroy',
+ 'InStr','IsFunc','IsLabel','Ln',
+ 'Log','LV_Add','LV_Delete','LV_DeleteCol',
+ 'LV_GetCount','LV_GetNext','LV_GetText','LV_Insert',
+ 'LV_InsertCol','LV_Modify','LV_ModifyCol','LV_SetImageList',
+ 'Mod','NumGet','NumPut',
+ 'Round',
+ 'SB_SetIcon','SB_SetParts','SB_SetText','Sin',
+ 'Sqrt','StrLen','SubStr','Tan',
+ 'TV_Add','TV_Delete','TV_GetChild','TV_GetCount',
+ 'TV_GetNext','TV_Get','TV_GetParent','TV_GetPrev',
+ 'TV_GetSelection','TV_GetText','TV_Modify',
+ 'WinActive','WinExist'
+ ),
+ 5 => array(
+ // #Directives
+ 'AllowSameLineComments','ClipboardTimeout','CommentFlag',
+ 'ErrorStdOut','EscapeChar','HotkeyInterval',
+ 'HotkeyModifierTimeout','Hotstring','IfWinActive',
+ 'IfWinExist','IfWinNotActive','IfWinNotExist',
+ 'Include','IncludeAgain','InstallKeybdHook',
+ 'InstallMouseHook','KeyHistory','LTrim',
+ 'MaxHotkeysPerInterval','MaxMem','MaxThreads',
+ 'MaxThreadsBuffer','MaxThreadsPerHotkey','NoEnv',
+ 'NoTrayIcon','Persistent','SingleInstance',
+ 'UseHook','WinActivateForce'
+ ),
+ 6 => array(
+ 'Shift','LShift','RShift',
+ 'Alt','LAlt','RAlt',
+ 'LControl','RControl',
+ 'Ctrl','LCtrl','RCtrl',
+ 'LWin','RWin','AppsKey',
+ 'AltDown','AltUp','ShiftDown',
+ 'ShiftUp','CtrlDown','CtrlUp',
+ 'LWinDown','LWinUp','RWinDown',
+ 'RWinUp','LButton','RButton',
+ 'MButton','WheelUp','WheelDown',
+ 'WheelLeft','WheelRight','XButton1',
+ 'XButton2','Joy1','Joy2',
+ 'Joy3','Joy4','Joy5',
+ 'Joy6','Joy7','Joy8',
+ 'Joy9','Joy10','Joy11',
+ 'Joy12','Joy13','Joy14',
+ 'Joy15','Joy16','Joy17',
+ 'Joy18','Joy19','Joy20',
+ 'Joy21','Joy22','Joy23',
+ 'Joy24','Joy25','Joy26',
+ 'Joy27','Joy28','Joy29',
+ 'Joy30','Joy31','Joy32',
+ 'JoyX','JoyY','JoyZ',
+ 'JoyR','JoyU','JoyV',
+ 'JoyPOV','JoyName','JoyButtons',
+ 'JoyAxes','JoyInfo','Space',
+ 'Tab','Enter',
+ 'Escape','Esc','BackSpace',
+ 'BS','Delete','Del',
+ 'Insert','Ins','PGUP',
+ 'PGDN','Home','End',
+ 'Up','Down','Left',
+ 'Right','PrintScreen','CtrlBreak',
+ 'Pause','ScrollLock','CapsLock',
+ 'NumLock','Numpad0','Numpad1',
+ 'Numpad2','Numpad3','Numpad4',
+ 'Numpad5','Numpad6','Numpad7',
+ 'Numpad8','Numpad9','NumpadMult',
+ 'NumpadAdd','NumpadSub','NumpadDiv',
+ 'NumpadDot','NumpadDel','NumpadIns',
+ 'NumpadClear','NumpadUp','NumpadDown',
+ 'NumpadLeft','NumpadRight','NumpadHome',
+ 'NumpadEnd','NumpadPgup','NumpadPgdn',
+ 'NumpadEnter','F1','F2',
+ 'F3','F4','F5',
+ 'F6','F7','F8',
+ 'F9','F10','F11',
+ 'F12','F13','F14',
+ 'F15','F16','F17',
+ 'F18','F19','F20',
+ 'F21','F22','F23',
+ 'F24','Browser_Back','Browser_Forward',
+ 'Browser_Refresh','Browser_Stop','Browser_Search',
+ 'Browser_Favorites','Browser_Home','Volume_Mute',
+ 'Volume_Down','Volume_Up','Media_Next',
+ 'Media_Prev','Media_Stop','Media_Play_Pause',
+ 'Launch_Mail','Launch_Media','Launch_App1',
+ 'Launch_App2'
+ ),
+ 7 => array(
+ // Gui commands
+ 'Add',
+ 'Show', 'Submit', 'Cancel', 'Destroy',
+ 'Font', 'Color', 'Margin', 'Flash', 'Default',
+ 'GuiEscape','GuiClose','GuiSize','GuiContextMenu','GuiDropFilesTabStop',
+ ),
+ 8 => array(
+ // Gui Controls
+ 'Button',
+ 'Checkbox','Radio','DropDownList','DDL',
+ 'ComboBox','ListBox','ListView',
+ 'Text', 'Edit', 'UpDown', 'Picture',
+ 'TreeView','DateTime', 'MonthCal',
+ 'Slider'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(',')','[',']',
+ '+','-','*','/','&','^',
+ '=','+=','-=','*=','/=','&=',
+ '==','<','<=','>','>=',':=',
+ ',','.'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ 8 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #AAAAFF; font-weight: bold;', // reserved #blue
+ 2 => 'color: #88FF88;', // BIV yellow
+ 3 => 'color: #FF00FF; font-style: italic;', // commands purple
+ 4 => 'color: #888844; font-weight: bold;', // functions #0080FF
+ 5 => 'color: #000000; font-style: italic;', // directives #black
+ 6 => 'color: #FF0000; font-style: italic;', // hotkeys #red
+ 7 => 'color: #000000; font-style: italic;', // gui commands #black
+ 8 => 'color: #000000; font-style: italic;' // gui controls
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'font-style: italic; color: #669900;',
+ 1 => 'font-style: italic; color: #009933;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #00FF00; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'font-weight: bold; color: #008080;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0000FF; font-style: italic; font-weight: italic;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000; font-weight: italic;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'font-weight: italic; color: #A00A0;',
+ 1 => 'color: #CC0000; font-style: italic;',
+ 2 => 'color: #DD0000; font-style: italic;',
+ 3 => 'color: #88FF88;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '_'
+ ),
+ 'REGEXPS' => array(
+ //Variables
+ 0 => '%[a-zA-Z_][a-zA-Z0-9_]*%',
+ //hotstrings
+ 1 => '::[\w\d]+::',
+ //labels
+ 2 => '\w[\w\d]+:\s',
+ //Built-in Variables
+ 3 => '\bA_\w+\b(?![^<]*>)'
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => 'http://www.autohotkey.com/docs/Variables.htm#{FNAME}',
+ 3 => 'http://www.autohotkey.com/docs/commands/{FNAME}.htm',
+ 4 => 'http://www.autohotkey.com/docs/Functions.htm#BuiltIn',
+ 5 => 'http://www.autohotkey.com/docs/commands/_{FNAME}.htm',
+ 6 => '',
+ 7 => 'http://www.autohotkey.com/docs/commands/Gui.htm#{FNAME}',
+ 8 => 'http://www.autohotkey.com/docs/commands/GuiControls.htm#{FNAME}'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 5 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\w)\#'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/autoit.php b/platform/www/vendor/geshi/geshi/src/geshi/autoit.php
new file mode 100644
index 0000000..2286aae
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/autoit.php
@@ -0,0 +1,1888 @@
+<?php
+/*************************************************************************************
+ * autoit.php
+ * --------
+ * Author: big_daddy, guinness & Tlem
+ * Copyright: (c) 2006-2015
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/01/26
+ *
+ * AutoIt: v3.3.14.2
+ * Updated: 2015/09/18
+ *
+ * AutoIt language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * Release 1.0.8.11 (2014/01/03) by guinness
+ * - Added: Split directives so as to point to their specific URL.
+ * - Fixed: #EndRegion not highlighting correctly.
+ * - Fixed: AutoItWrapper directives and settings were incorrectly highlighting.
+ * - Fixed: Highlighting of hex values and complex math values.
+ * - Fixed: Include file name to the correct colour scheme.
+ * - Fixed: Incorrectly highlighting the _ (underscore).
+ * - Fixed: Upper case #include being incorrectly highlighted.
+ * - Fixed: Variables and macros were being incorrectly highlighted.
+ * - Fixed: Generation based on AutoIt_php.ini file to commit only on specific GeSHi change.
+ * Release 1.0.8.1 (2008/09/15) by Tlem
+ * - Added: http://www.autoitscript.com/autoit3/docs/functions/{FNAME}.htm
+ * - Fixed: The link on functions will now correctly re-direct to
+ * Release 1.0.7.20 (2006/01/26)
+ * - Initial Release
+ *
+ * TODO:
+ * ----------
+ * - None
+ *
+ * Reference: http://www.autoitscript.com/autoit3/docs/
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'AutoIt',
+ 'COMMENT_SINGLE' => array(
+ 1 => ';',
+ 2 => ';~'
+ ),
+ 'COMMENT_MULTI' => array(
+ '#comments-start' => '#comments-end',
+ '#cs' => '#ce'),
+ 'COMMENT_REGEXP' => array(
+ 0 => '/(?<=(i|I)nclude)\s*<.*?>/'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'And', 'ByRef', 'Case', 'Const', 'ContinueCase', 'ContinueLoop',
+ 'Default', 'Dim', 'Do', 'Else', 'ElseIf', 'EndFunc', 'EndIf', 'EndSelect',
+ 'EndSwitch', 'EndWith', 'Enum', 'Exit', 'ExitLoop', 'False', 'For', 'Func',
+ 'Global', 'If', 'In', 'Local', 'Next', 'Not', 'Null', 'Or', 'ReDim',
+ 'Return', 'Select', 'Static', 'Step', 'Switch', 'Then', 'To', 'True',
+ 'Until', 'Volatile', 'WEnd', 'While', 'With'
+ ),
+ 2 => array(
+ '@AppDataCommonDir', '@AppDataDir', '@AutoItExe', '@AutoItPID',
+ '@AutoItVersion', '@AutoItX64', '@COM_EventObj', '@CommonFilesDir',
+ '@Compiled', '@ComputerName', '@ComSpec', '@CPUArch', '@CR', '@CRLF',
+ '@DesktopCommonDir', '@DesktopDepth', '@DesktopDir', '@DesktopHeight',
+ '@DesktopRefresh', '@DesktopWidth', '@DocumentsCommonDir', '@error',
+ '@exitCode', '@exitMethod', '@extended', '@FavoritesCommonDir',
+ '@FavoritesDir', '@GUI_CtrlHandle', '@GUI_CtrlId', '@GUI_DragFile',
+ '@GUI_DragId', '@GUI_DropId', '@GUI_WinHandle', '@HomeDrive',
+ '@HomePath', '@HomeShare', '@HotKeyPressed', '@HOUR', '@IPAddress1',
+ '@IPAddress2', '@IPAddress3', '@IPAddress4', '@KBLayout', '@LF',
+ '@LocalAppDataDir', '@LogonDNSDomain', '@LogonDomain', '@LogonServer',
+ '@MDAY', '@MIN', '@MON', '@MSEC', '@MUILang', '@MyDocumentsDir',
+ '@NumParams', '@OSArch', '@OSBuild', '@OSLang', '@OSServicePack',
+ '@OSType', '@OSVersion', '@ProgramFilesDir', '@ProgramsCommonDir',
+ '@ProgramsDir', '@ScriptDir', '@ScriptFullPath', '@ScriptLineNumber',
+ '@ScriptName', '@SEC', '@StartMenuCommonDir', '@StartMenuDir',
+ '@StartupCommonDir', '@StartupDir', '@SW_DISABLE', '@SW_ENABLE',
+ '@SW_HIDE', '@SW_LOCK', '@SW_MAXIMIZE', '@SW_MINIMIZE', '@SW_RESTORE',
+ '@SW_SHOW', '@SW_SHOWDEFAULT', '@SW_SHOWMAXIMIZED',
+ '@SW_SHOWMINIMIZED', '@SW_SHOWMINNOACTIVE', '@SW_SHOWNA',
+ '@SW_SHOWNOACTIVATE', '@SW_SHOWNORMAL', '@SW_UNLOCK', '@SystemDir',
+ '@TAB', '@TempDir', '@TRAY_ID', '@TrayIconFlashing', '@TrayIconVisible',
+ '@UserName', '@UserProfileDir', '@WDAY', '@WindowsDir', '@WorkingDir',
+ '@YDAY', '@YEAR'
+ ),
+ 3 => array(
+ 'Abs', 'ACos', 'AdlibRegister', 'AdlibUnRegister', 'Asc', 'AscW', 'ASin',
+ 'Assign', 'ATan', 'AutoItSetOption', 'AutoItWinGetTitle',
+ 'AutoItWinSetTitle', 'Beep', 'Binary', 'BinaryLen', 'BinaryMid',
+ 'BinaryToString', 'BitAND', 'BitNOT', 'BitOR', 'BitRotate', 'BitShift',
+ 'BitXOR', 'BlockInput', 'Break', 'Call', 'CDTray', 'Ceiling', 'Chr',
+ 'ChrW', 'ClipGet', 'ClipPut', 'ConsoleRead', 'ConsoleWrite',
+ 'ConsoleWriteError', 'ControlClick', 'ControlCommand',
+ 'ControlDisable', 'ControlEnable', 'ControlFocus', 'ControlGetFocus',
+ 'ControlGetHandle', 'ControlGetPos', 'ControlGetText', 'ControlHide',
+ 'ControlListView', 'ControlMove', 'ControlSend', 'ControlSetText',
+ 'ControlShow', 'ControlTreeView', 'Cos', 'Dec', 'DirCopy', 'DirCreate',
+ 'DirGetSize', 'DirMove', 'DirRemove', 'DllCall', 'DllCallAddress',
+ 'DllCallbackFree', 'DllCallbackGetPtr', 'DllCallbackRegister',
+ 'DllClose', 'DllOpen', 'DllStructCreate', 'DllStructGetData',
+ 'DllStructGetPtr', 'DllStructGetSize', 'DllStructSetData',
+ 'DriveGetDrive', 'DriveGetFileSystem', 'DriveGetLabel',
+ 'DriveGetSerial', 'DriveGetType', 'DriveMapAdd', 'DriveMapDel',
+ 'DriveMapGet', 'DriveSetLabel', 'DriveSpaceFree', 'DriveSpaceTotal',
+ 'DriveStatus', 'EnvGet', 'EnvSet', 'EnvUpdate', 'Eval', 'Execute', 'Exp',
+ 'FileChangeDir', 'FileClose', 'FileCopy', 'FileCreateNTFSLink',
+ 'FileCreateShortcut', 'FileDelete', 'FileExists', 'FileFindFirstFile',
+ 'FileFindNextFile', 'FileFlush', 'FileGetAttrib', 'FileGetEncoding',
+ 'FileGetLongName', 'FileGetPos', 'FileGetShortcut', 'FileGetShortName',
+ 'FileGetSize', 'FileGetTime', 'FileGetVersion', 'FileInstall',
+ 'FileMove', 'FileOpen', 'FileOpenDialog', 'FileRead', 'FileReadLine',
+ 'FileReadToArray', 'FileRecycle', 'FileRecycleEmpty', 'FileSaveDialog',
+ 'FileSelectFolder', 'FileSetAttrib', 'FileSetEnd', 'FileSetPos',
+ 'FileSetTime', 'FileWrite', 'FileWriteLine', 'Floor', 'FtpSetProxy',
+ 'FuncName', 'GUICreate', 'GUICtrlCreateAvi', 'GUICtrlCreateButton',
+ 'GUICtrlCreateCheckbox', 'GUICtrlCreateCombo',
+ 'GUICtrlCreateContextMenu', 'GUICtrlCreateDate', 'GUICtrlCreateDummy',
+ 'GUICtrlCreateEdit', 'GUICtrlCreateGraphic', 'GUICtrlCreateGroup',
+ 'GUICtrlCreateIcon', 'GUICtrlCreateInput', 'GUICtrlCreateLabel',
+ 'GUICtrlCreateList', 'GUICtrlCreateListView',
+ 'GUICtrlCreateListViewItem', 'GUICtrlCreateMenu',
+ 'GUICtrlCreateMenuItem', 'GUICtrlCreateMonthCal', 'GUICtrlCreateObj',
+ 'GUICtrlCreatePic', 'GUICtrlCreateProgress', 'GUICtrlCreateRadio',
+ 'GUICtrlCreateSlider', 'GUICtrlCreateTab', 'GUICtrlCreateTabItem',
+ 'GUICtrlCreateTreeView', 'GUICtrlCreateTreeViewItem',
+ 'GUICtrlCreateUpdown', 'GUICtrlDelete', 'GUICtrlGetHandle',
+ 'GUICtrlGetState', 'GUICtrlRead', 'GUICtrlRecvMsg',
+ 'GUICtrlRegisterListViewSort', 'GUICtrlSendMsg', 'GUICtrlSendToDummy',
+ 'GUICtrlSetBkColor', 'GUICtrlSetColor', 'GUICtrlSetCursor',
+ 'GUICtrlSetData', 'GUICtrlSetDefBkColor', 'GUICtrlSetDefColor',
+ 'GUICtrlSetFont', 'GUICtrlSetGraphic', 'GUICtrlSetImage',
+ 'GUICtrlSetLimit', 'GUICtrlSetOnEvent', 'GUICtrlSetPos',
+ 'GUICtrlSetResizing', 'GUICtrlSetState', 'GUICtrlSetStyle',
+ 'GUICtrlSetTip', 'GUIDelete', 'GUIGetCursorInfo', 'GUIGetMsg',
+ 'GUIGetStyle', 'GUIRegisterMsg', 'GUISetAccelerators', 'GUISetBkColor',
+ 'GUISetCoord', 'GUISetCursor', 'GUISetFont', 'GUISetHelp', 'GUISetIcon',
+ 'GUISetOnEvent', 'GUISetState', 'GUISetStyle', 'GUIStartGroup',
+ 'GUISwitch', 'Hex', 'HotKeySet', 'HttpSetProxy', 'HttpSetUserAgent',
+ 'HWnd', 'InetClose', 'InetGet', 'InetGetInfo', 'InetGetSize', 'InetRead',
+ 'IniDelete', 'IniRead', 'IniReadSection', 'IniReadSectionNames',
+ 'IniRenameSection', 'IniWrite', 'IniWriteSection', 'InputBox', 'Int',
+ 'IsAdmin', 'IsArray', 'IsBinary', 'IsBool', 'IsDeclared', 'IsDllStruct',
+ 'IsFloat', 'IsFunc', 'IsHWnd', 'IsInt', 'IsKeyword', 'IsNumber', 'IsObj',
+ 'IsPtr', 'IsString', 'Log', 'MemGetStats', 'Mod', 'MouseClick',
+ 'MouseClickDrag', 'MouseDown', 'MouseGetCursor', 'MouseGetPos',
+ 'MouseMove', 'MouseUp', 'MouseWheel', 'MsgBox', 'Number', 'ObjCreate',
+ 'ObjCreateInterface', 'ObjEvent', 'ObjGet', 'ObjName',
+ 'OnAutoItExitRegister', 'OnAutoItExitUnRegister', 'Opt', 'Ping',
+ 'PixelChecksum', 'PixelGetColor', 'PixelSearch', 'ProcessClose',
+ 'ProcessExists', 'ProcessGetStats', 'ProcessList',
+ 'ProcessSetPriority', 'ProcessWait', 'ProcessWaitClose', 'ProgressOff',
+ 'ProgressOn', 'ProgressSet', 'Ptr', 'Random', 'RegDelete', 'RegEnumKey',
+ 'RegEnumVal', 'RegRead', 'RegWrite', 'Round', 'Run', 'RunAs', 'RunAsWait',
+ 'RunWait', 'Send', 'SendKeepActive', 'SetError', 'SetExtended',
+ 'ShellExecute', 'ShellExecuteWait', 'Shutdown', 'Sin', 'Sleep',
+ 'SoundPlay', 'SoundSetWaveVolume', 'SplashImageOn', 'SplashOff',
+ 'SplashTextOn', 'Sqrt', 'SRandom', 'StatusbarGetText', 'StderrRead',
+ 'StdinWrite', 'StdioClose', 'StdoutRead', 'String', 'StringAddCR',
+ 'StringCompare', 'StringFormat', 'StringFromASCIIArray', 'StringInStr',
+ 'StringIsAlNum', 'StringIsAlpha', 'StringIsASCII', 'StringIsDigit',
+ 'StringIsFloat', 'StringIsInt', 'StringIsLower', 'StringIsSpace',
+ 'StringIsUpper', 'StringIsXDigit', 'StringLeft', 'StringLen',
+ 'StringLower', 'StringMid', 'StringRegExp', 'StringRegExpReplace',
+ 'StringReplace', 'StringReverse', 'StringRight', 'StringSplit',
+ 'StringStripCR', 'StringStripWS', 'StringToASCIIArray',
+ 'StringToBinary', 'StringTrimLeft', 'StringTrimRight', 'StringUpper',
+ 'Tan', 'TCPAccept', 'TCPCloseSocket', 'TCPConnect', 'TCPListen',
+ 'TCPNameToIP', 'TCPRecv', 'TCPSend', 'TCPShutdown', 'TCPStartup',
+ 'TimerDiff', 'TimerInit', 'ToolTip', 'TrayCreateItem', 'TrayCreateMenu',
+ 'TrayGetMsg', 'TrayItemDelete', 'TrayItemGetHandle',
+ 'TrayItemGetState', 'TrayItemGetText', 'TrayItemSetOnEvent',
+ 'TrayItemSetState', 'TrayItemSetText', 'TraySetClick', 'TraySetIcon',
+ 'TraySetOnEvent', 'TraySetPauseIcon', 'TraySetState', 'TraySetToolTip',
+ 'TrayTip', 'UBound', 'UDPBind', 'UDPCloseSocket', 'UDPOpen', 'UDPRecv',
+ 'UDPSend', 'UDPShutdown', 'UDPStartup', 'VarGetType', 'WinActivate',
+ 'WinActive', 'WinClose', 'WinExists', 'WinFlash', 'WinGetCaretPos',
+ 'WinGetClassList', 'WinGetClientSize', 'WinGetHandle', 'WinGetPos',
+ 'WinGetProcess', 'WinGetState', 'WinGetText', 'WinGetTitle', 'WinKill',
+ 'WinList', 'WinMenuSelectItem', 'WinMinimizeAll', 'WinMinimizeAllUndo',
+ 'WinMove', 'WinSetOnTop', 'WinSetState', 'WinSetTitle', 'WinSetTrans',
+ 'WinWait', 'WinWaitActive', 'WinWaitClose', 'WinWaitNotActive'
+ ),
+ 4 => array(
+ 'Array1DToHistogram', 'ArrayAdd', 'ArrayBinarySearch',
+ 'ArrayColDelete', 'ArrayColInsert', 'ArrayCombinations',
+ 'ArrayConcatenate', 'ArrayDelete', 'ArrayDisplay', 'ArrayExtract',
+ 'ArrayFindAll', 'ArrayInsert', 'ArrayMax', 'ArrayMaxIndex', 'ArrayMin',
+ 'ArrayMinIndex', 'ArrayPermute', 'ArrayPop', 'ArrayPush',
+ 'ArrayReverse', 'ArraySearch', 'ArrayShuffle', 'ArraySort', 'ArraySwap',
+ 'ArrayToClip', 'ArrayToString', 'ArrayTranspose', 'ArrayTrim',
+ 'ArrayUnique', 'Assert', 'ChooseColor', 'ChooseFont',
+ 'ClipBoard_ChangeChain', 'ClipBoard_Close', 'ClipBoard_CountFormats',
+ 'ClipBoard_Empty', 'ClipBoard_EnumFormats', 'ClipBoard_FormatStr',
+ 'ClipBoard_GetData', 'ClipBoard_GetDataEx', 'ClipBoard_GetFormatName',
+ 'ClipBoard_GetOpenWindow', 'ClipBoard_GetOwner',
+ 'ClipBoard_GetPriorityFormat', 'ClipBoard_GetSequenceNumber',
+ 'ClipBoard_GetViewer', 'ClipBoard_IsFormatAvailable',
+ 'ClipBoard_Open', 'ClipBoard_RegisterFormat', 'ClipBoard_SetData',
+ 'ClipBoard_SetDataEx', 'ClipBoard_SetViewer', 'ClipPutFile',
+ 'ColorConvertHSLtoRGB', 'ColorConvertRGBtoHSL', 'ColorGetBlue',
+ 'ColorGetCOLORREF', 'ColorGetGreen', 'ColorGetRed', 'ColorGetRGB',
+ 'ColorSetCOLORREF', 'ColorSetRGB', 'Crypt_DecryptData',
+ 'Crypt_DecryptFile', 'Crypt_DeriveKey', 'Crypt_DestroyKey',
+ 'Crypt_EncryptData', 'Crypt_EncryptFile', 'Crypt_GenRandom',
+ 'Crypt_HashData', 'Crypt_HashFile', 'Crypt_Shutdown', 'Crypt_Startup',
+ 'DateAdd', 'DateDayOfWeek', 'DateDaysInMonth', 'DateDiff',
+ 'DateIsLeapYear', 'DateIsValid', 'DateTimeFormat', 'DateTimeSplit',
+ 'DateToDayOfWeek', 'DateToDayOfWeekISO', 'DateToDayValue',
+ 'DateToMonth', 'Date_Time_CompareFileTime',
+ 'Date_Time_DOSDateTimeToArray', 'Date_Time_DOSDateTimeToFileTime',
+ 'Date_Time_DOSDateTimeToStr', 'Date_Time_DOSDateToArray',
+ 'Date_Time_DOSDateToStr', 'Date_Time_DOSTimeToArray',
+ 'Date_Time_DOSTimeToStr', 'Date_Time_EncodeFileTime',
+ 'Date_Time_EncodeSystemTime', 'Date_Time_FileTimeToArray',
+ 'Date_Time_FileTimeToDOSDateTime',
+ 'Date_Time_FileTimeToLocalFileTime', 'Date_Time_FileTimeToStr',
+ 'Date_Time_FileTimeToSystemTime', 'Date_Time_GetFileTime',
+ 'Date_Time_GetLocalTime', 'Date_Time_GetSystemTime',
+ 'Date_Time_GetSystemTimeAdjustment',
+ 'Date_Time_GetSystemTimeAsFileTime', 'Date_Time_GetSystemTimes',
+ 'Date_Time_GetTickCount', 'Date_Time_GetTimeZoneInformation',
+ 'Date_Time_LocalFileTimeToFileTime', 'Date_Time_SetFileTime',
+ 'Date_Time_SetLocalTime', 'Date_Time_SetSystemTime',
+ 'Date_Time_SetSystemTimeAdjustment',
+ 'Date_Time_SetTimeZoneInformation', 'Date_Time_SystemTimeToArray',
+ 'Date_Time_SystemTimeToDateStr', 'Date_Time_SystemTimeToDateTimeStr',
+ 'Date_Time_SystemTimeToFileTime', 'Date_Time_SystemTimeToTimeStr',
+ 'Date_Time_SystemTimeToTzSpecificLocalTime',
+ 'Date_Time_TzSpecificLocalTimeToSystemTime', 'DayValueToDate',
+ 'DebugBugReportEnv', 'DebugCOMError', 'DebugOut', 'DebugReport',
+ 'DebugReportEx', 'DebugReportVar', 'DebugSetup', 'Degree',
+ 'EventLog__Backup', 'EventLog__Clear', 'EventLog__Close',
+ 'EventLog__Count', 'EventLog__DeregisterSource', 'EventLog__Full',
+ 'EventLog__Notify', 'EventLog__Oldest', 'EventLog__Open',
+ 'EventLog__OpenBackup', 'EventLog__Read', 'EventLog__RegisterSource',
+ 'EventLog__Report', 'Excel_BookAttach', 'Excel_BookClose',
+ 'Excel_BookList', 'Excel_BookNew', 'Excel_BookOpen',
+ 'Excel_BookOpenText', 'Excel_BookSave', 'Excel_BookSaveAs',
+ 'Excel_Close', 'Excel_ColumnToLetter', 'Excel_ColumnToNumber',
+ 'Excel_ConvertFormula', 'Excel_Export', 'Excel_FilterGet',
+ 'Excel_FilterSet', 'Excel_Open', 'Excel_PictureAdd', 'Excel_Print',
+ 'Excel_RangeCopyPaste', 'Excel_RangeDelete', 'Excel_RangeFind',
+ 'Excel_RangeInsert', 'Excel_RangeLinkAddRemove', 'Excel_RangeRead',
+ 'Excel_RangeReplace', 'Excel_RangeSort', 'Excel_RangeValidate',
+ 'Excel_RangeWrite', 'Excel_SheetAdd', 'Excel_SheetCopyMove',
+ 'Excel_SheetDelete', 'Excel_SheetList', 'FileCountLines', 'FileCreate',
+ 'FileListToArray', 'FileListToArrayRec', 'FilePrint',
+ 'FileReadToArray', 'FileWriteFromArray', 'FileWriteLog',
+ 'FileWriteToLine', 'FTP_Close', 'FTP_Command', 'FTP_Connect',
+ 'FTP_DecodeInternetStatus', 'FTP_DirCreate', 'FTP_DirDelete',
+ 'FTP_DirGetCurrent', 'FTP_DirPutContents', 'FTP_DirSetCurrent',
+ 'FTP_FileClose', 'FTP_FileDelete', 'FTP_FileGet', 'FTP_FileGetSize',
+ 'FTP_FileOpen', 'FTP_FilePut', 'FTP_FileRead', 'FTP_FileRename',
+ 'FTP_FileTimeLoHiToStr', 'FTP_FindFileClose', 'FTP_FindFileFirst',
+ 'FTP_FindFileNext', 'FTP_GetLastResponseInfo', 'FTP_ListToArray',
+ 'FTP_ListToArray2D', 'FTP_ListToArrayEx', 'FTP_Open',
+ 'FTP_ProgressDownload', 'FTP_ProgressUpload', 'FTP_SetStatusCallback',
+ 'GDIPlus_ArrowCapCreate', 'GDIPlus_ArrowCapDispose',
+ 'GDIPlus_ArrowCapGetFillState', 'GDIPlus_ArrowCapGetHeight',
+ 'GDIPlus_ArrowCapGetMiddleInset', 'GDIPlus_ArrowCapGetWidth',
+ 'GDIPlus_ArrowCapSetFillState', 'GDIPlus_ArrowCapSetHeight',
+ 'GDIPlus_ArrowCapSetMiddleInset', 'GDIPlus_ArrowCapSetWidth',
+ 'GDIPlus_BitmapApplyEffect', 'GDIPlus_BitmapApplyEffectEx',
+ 'GDIPlus_BitmapCloneArea', 'GDIPlus_BitmapConvertFormat',
+ 'GDIPlus_BitmapCreateApplyEffect',
+ 'GDIPlus_BitmapCreateApplyEffectEx',
+ 'GDIPlus_BitmapCreateDIBFromBitmap', 'GDIPlus_BitmapCreateFromFile',
+ 'GDIPlus_BitmapCreateFromGraphics',
+ 'GDIPlus_BitmapCreateFromHBITMAP', 'GDIPlus_BitmapCreateFromHICON',
+ 'GDIPlus_BitmapCreateFromHICON32', 'GDIPlus_BitmapCreateFromMemory',
+ 'GDIPlus_BitmapCreateFromResource', 'GDIPlus_BitmapCreateFromScan0',
+ 'GDIPlus_BitmapCreateFromStream',
+ 'GDIPlus_BitmapCreateHBITMAPFromBitmap', 'GDIPlus_BitmapDispose',
+ 'GDIPlus_BitmapGetHistogram', 'GDIPlus_BitmapGetHistogramEx',
+ 'GDIPlus_BitmapGetHistogramSize', 'GDIPlus_BitmapGetPixel',
+ 'GDIPlus_BitmapLockBits', 'GDIPlus_BitmapSetPixel',
+ 'GDIPlus_BitmapUnlockBits', 'GDIPlus_BrushClone',
+ 'GDIPlus_BrushCreateSolid', 'GDIPlus_BrushDispose',
+ 'GDIPlus_BrushGetSolidColor', 'GDIPlus_BrushGetType',
+ 'GDIPlus_BrushSetSolidColor', 'GDIPlus_ColorMatrixCreate',
+ 'GDIPlus_ColorMatrixCreateGrayScale',
+ 'GDIPlus_ColorMatrixCreateNegative',
+ 'GDIPlus_ColorMatrixCreateSaturation',
+ 'GDIPlus_ColorMatrixCreateScale',
+ 'GDIPlus_ColorMatrixCreateTranslate', 'GDIPlus_CustomLineCapClone',
+ 'GDIPlus_CustomLineCapCreate', 'GDIPlus_CustomLineCapDispose',
+ 'GDIPlus_CustomLineCapGetStrokeCaps',
+ 'GDIPlus_CustomLineCapSetStrokeCaps', 'GDIPlus_Decoders',
+ 'GDIPlus_DecodersGetCount', 'GDIPlus_DecodersGetSize',
+ 'GDIPlus_DrawImageFX', 'GDIPlus_DrawImageFXEx',
+ 'GDIPlus_DrawImagePoints', 'GDIPlus_EffectCreate',
+ 'GDIPlus_EffectCreateBlur', 'GDIPlus_EffectCreateBrightnessContrast',
+ 'GDIPlus_EffectCreateColorBalance', 'GDIPlus_EffectCreateColorCurve',
+ 'GDIPlus_EffectCreateColorLUT', 'GDIPlus_EffectCreateColorMatrix',
+ 'GDIPlus_EffectCreateHueSaturationLightness',
+ 'GDIPlus_EffectCreateLevels', 'GDIPlus_EffectCreateRedEyeCorrection',
+ 'GDIPlus_EffectCreateSharpen', 'GDIPlus_EffectCreateTint',
+ 'GDIPlus_EffectDispose', 'GDIPlus_EffectGetParameters',
+ 'GDIPlus_EffectSetParameters', 'GDIPlus_Encoders',
+ 'GDIPlus_EncodersGetCLSID', 'GDIPlus_EncodersGetCount',
+ 'GDIPlus_EncodersGetParamList', 'GDIPlus_EncodersGetParamListSize',
+ 'GDIPlus_EncodersGetSize', 'GDIPlus_FontCreate',
+ 'GDIPlus_FontDispose', 'GDIPlus_FontFamilyCreate',
+ 'GDIPlus_FontFamilyCreateFromCollection',
+ 'GDIPlus_FontFamilyDispose', 'GDIPlus_FontFamilyGetCellAscent',
+ 'GDIPlus_FontFamilyGetCellDescent', 'GDIPlus_FontFamilyGetEmHeight',
+ 'GDIPlus_FontFamilyGetLineSpacing', 'GDIPlus_FontGetHeight',
+ 'GDIPlus_FontPrivateAddFont', 'GDIPlus_FontPrivateAddMemoryFont',
+ 'GDIPlus_FontPrivateCollectionDispose',
+ 'GDIPlus_FontPrivateCreateCollection', 'GDIPlus_GraphicsClear',
+ 'GDIPlus_GraphicsCreateFromHDC', 'GDIPlus_GraphicsCreateFromHWND',
+ 'GDIPlus_GraphicsDispose', 'GDIPlus_GraphicsDrawArc',
+ 'GDIPlus_GraphicsDrawBezier', 'GDIPlus_GraphicsDrawClosedCurve',
+ 'GDIPlus_GraphicsDrawClosedCurve2', 'GDIPlus_GraphicsDrawCurve',
+ 'GDIPlus_GraphicsDrawCurve2', 'GDIPlus_GraphicsDrawEllipse',
+ 'GDIPlus_GraphicsDrawImage', 'GDIPlus_GraphicsDrawImagePointsRect',
+ 'GDIPlus_GraphicsDrawImageRect', 'GDIPlus_GraphicsDrawImageRectRect',
+ 'GDIPlus_GraphicsDrawLine', 'GDIPlus_GraphicsDrawPath',
+ 'GDIPlus_GraphicsDrawPie', 'GDIPlus_GraphicsDrawPolygon',
+ 'GDIPlus_GraphicsDrawRect', 'GDIPlus_GraphicsDrawString',
+ 'GDIPlus_GraphicsDrawStringEx', 'GDIPlus_GraphicsFillClosedCurve',
+ 'GDIPlus_GraphicsFillClosedCurve2', 'GDIPlus_GraphicsFillEllipse',
+ 'GDIPlus_GraphicsFillPath', 'GDIPlus_GraphicsFillPie',
+ 'GDIPlus_GraphicsFillPolygon', 'GDIPlus_GraphicsFillRect',
+ 'GDIPlus_GraphicsFillRegion', 'GDIPlus_GraphicsGetCompositingMode',
+ 'GDIPlus_GraphicsGetCompositingQuality', 'GDIPlus_GraphicsGetDC',
+ 'GDIPlus_GraphicsGetInterpolationMode',
+ 'GDIPlus_GraphicsGetSmoothingMode', 'GDIPlus_GraphicsGetTransform',
+ 'GDIPlus_GraphicsMeasureCharacterRanges',
+ 'GDIPlus_GraphicsMeasureString', 'GDIPlus_GraphicsReleaseDC',
+ 'GDIPlus_GraphicsResetClip', 'GDIPlus_GraphicsResetTransform',
+ 'GDIPlus_GraphicsRestore', 'GDIPlus_GraphicsRotateTransform',
+ 'GDIPlus_GraphicsSave', 'GDIPlus_GraphicsScaleTransform',
+ 'GDIPlus_GraphicsSetClipPath', 'GDIPlus_GraphicsSetClipRect',
+ 'GDIPlus_GraphicsSetClipRegion',
+ 'GDIPlus_GraphicsSetCompositingMode',
+ 'GDIPlus_GraphicsSetCompositingQuality',
+ 'GDIPlus_GraphicsSetInterpolationMode',
+ 'GDIPlus_GraphicsSetPixelOffsetMode',
+ 'GDIPlus_GraphicsSetSmoothingMode',
+ 'GDIPlus_GraphicsSetTextRenderingHint',
+ 'GDIPlus_GraphicsSetTransform', 'GDIPlus_GraphicsTransformPoints',
+ 'GDIPlus_GraphicsTranslateTransform', 'GDIPlus_HatchBrushCreate',
+ 'GDIPlus_HICONCreateFromBitmap', 'GDIPlus_ImageAttributesCreate',
+ 'GDIPlus_ImageAttributesDispose',
+ 'GDIPlus_ImageAttributesSetColorKeys',
+ 'GDIPlus_ImageAttributesSetColorMatrix', 'GDIPlus_ImageDispose',
+ 'GDIPlus_ImageGetDimension', 'GDIPlus_ImageGetFlags',
+ 'GDIPlus_ImageGetGraphicsContext', 'GDIPlus_ImageGetHeight',
+ 'GDIPlus_ImageGetHorizontalResolution',
+ 'GDIPlus_ImageGetPixelFormat', 'GDIPlus_ImageGetRawFormat',
+ 'GDIPlus_ImageGetThumbnail', 'GDIPlus_ImageGetType',
+ 'GDIPlus_ImageGetVerticalResolution', 'GDIPlus_ImageGetWidth',
+ 'GDIPlus_ImageLoadFromFile', 'GDIPlus_ImageLoadFromStream',
+ 'GDIPlus_ImageResize', 'GDIPlus_ImageRotateFlip',
+ 'GDIPlus_ImageSaveToFile', 'GDIPlus_ImageSaveToFileEx',
+ 'GDIPlus_ImageSaveToStream', 'GDIPlus_ImageScale',
+ 'GDIPlus_LineBrushCreate', 'GDIPlus_LineBrushCreateFromRect',
+ 'GDIPlus_LineBrushCreateFromRectWithAngle',
+ 'GDIPlus_LineBrushGetColors', 'GDIPlus_LineBrushGetRect',
+ 'GDIPlus_LineBrushMultiplyTransform',
+ 'GDIPlus_LineBrushResetTransform', 'GDIPlus_LineBrushSetBlend',
+ 'GDIPlus_LineBrushSetColors', 'GDIPlus_LineBrushSetGammaCorrection',
+ 'GDIPlus_LineBrushSetLinearBlend', 'GDIPlus_LineBrushSetPresetBlend',
+ 'GDIPlus_LineBrushSetSigmaBlend', 'GDIPlus_LineBrushSetTransform',
+ 'GDIPlus_MatrixClone', 'GDIPlus_MatrixCreate',
+ 'GDIPlus_MatrixDispose', 'GDIPlus_MatrixGetElements',
+ 'GDIPlus_MatrixInvert', 'GDIPlus_MatrixMultiply',
+ 'GDIPlus_MatrixRotate', 'GDIPlus_MatrixScale',
+ 'GDIPlus_MatrixSetElements', 'GDIPlus_MatrixShear',
+ 'GDIPlus_MatrixTransformPoints', 'GDIPlus_MatrixTranslate',
+ 'GDIPlus_PaletteInitialize', 'GDIPlus_ParamAdd', 'GDIPlus_ParamInit',
+ 'GDIPlus_ParamSize', 'GDIPlus_PathAddArc', 'GDIPlus_PathAddBezier',
+ 'GDIPlus_PathAddClosedCurve', 'GDIPlus_PathAddClosedCurve2',
+ 'GDIPlus_PathAddCurve', 'GDIPlus_PathAddCurve2',
+ 'GDIPlus_PathAddCurve3', 'GDIPlus_PathAddEllipse',
+ 'GDIPlus_PathAddLine', 'GDIPlus_PathAddLine2', 'GDIPlus_PathAddPath',
+ 'GDIPlus_PathAddPie', 'GDIPlus_PathAddPolygon',
+ 'GDIPlus_PathAddRectangle', 'GDIPlus_PathAddString',
+ 'GDIPlus_PathBrushCreate', 'GDIPlus_PathBrushCreateFromPath',
+ 'GDIPlus_PathBrushGetCenterPoint', 'GDIPlus_PathBrushGetFocusScales',
+ 'GDIPlus_PathBrushGetPointCount', 'GDIPlus_PathBrushGetRect',
+ 'GDIPlus_PathBrushGetWrapMode', 'GDIPlus_PathBrushMultiplyTransform',
+ 'GDIPlus_PathBrushResetTransform', 'GDIPlus_PathBrushSetBlend',
+ 'GDIPlus_PathBrushSetCenterColor', 'GDIPlus_PathBrushSetCenterPoint',
+ 'GDIPlus_PathBrushSetFocusScales',
+ 'GDIPlus_PathBrushSetGammaCorrection',
+ 'GDIPlus_PathBrushSetLinearBlend', 'GDIPlus_PathBrushSetPresetBlend',
+ 'GDIPlus_PathBrushSetSigmaBlend',
+ 'GDIPlus_PathBrushSetSurroundColor',
+ 'GDIPlus_PathBrushSetSurroundColorsWithCount',
+ 'GDIPlus_PathBrushSetTransform', 'GDIPlus_PathBrushSetWrapMode',
+ 'GDIPlus_PathClone', 'GDIPlus_PathCloseFigure', 'GDIPlus_PathCreate',
+ 'GDIPlus_PathCreate2', 'GDIPlus_PathDispose', 'GDIPlus_PathFlatten',
+ 'GDIPlus_PathGetData', 'GDIPlus_PathGetFillMode',
+ 'GDIPlus_PathGetLastPoint', 'GDIPlus_PathGetPointCount',
+ 'GDIPlus_PathGetPoints', 'GDIPlus_PathGetWorldBounds',
+ 'GDIPlus_PathIsOutlineVisiblePoint', 'GDIPlus_PathIsVisiblePoint',
+ 'GDIPlus_PathIterCreate', 'GDIPlus_PathIterDispose',
+ 'GDIPlus_PathIterGetSubpathCount', 'GDIPlus_PathIterNextMarkerPath',
+ 'GDIPlus_PathIterNextSubpathPath', 'GDIPlus_PathIterRewind',
+ 'GDIPlus_PathReset', 'GDIPlus_PathReverse', 'GDIPlus_PathSetFillMode',
+ 'GDIPlus_PathSetMarker', 'GDIPlus_PathStartFigure',
+ 'GDIPlus_PathTransform', 'GDIPlus_PathWarp', 'GDIPlus_PathWiden',
+ 'GDIPlus_PathWindingModeOutline', 'GDIPlus_PenCreate',
+ 'GDIPlus_PenCreate2', 'GDIPlus_PenDispose', 'GDIPlus_PenGetAlignment',
+ 'GDIPlus_PenGetColor', 'GDIPlus_PenGetCustomEndCap',
+ 'GDIPlus_PenGetDashCap', 'GDIPlus_PenGetDashStyle',
+ 'GDIPlus_PenGetEndCap', 'GDIPlus_PenGetMiterLimit',
+ 'GDIPlus_PenGetWidth', 'GDIPlus_PenSetAlignment',
+ 'GDIPlus_PenSetColor', 'GDIPlus_PenSetCustomEndCap',
+ 'GDIPlus_PenSetDashCap', 'GDIPlus_PenSetDashStyle',
+ 'GDIPlus_PenSetEndCap', 'GDIPlus_PenSetLineCap',
+ 'GDIPlus_PenSetLineJoin', 'GDIPlus_PenSetMiterLimit',
+ 'GDIPlus_PenSetStartCap', 'GDIPlus_PenSetWidth',
+ 'GDIPlus_RectFCreate', 'GDIPlus_RegionClone',
+ 'GDIPlus_RegionCombinePath', 'GDIPlus_RegionCombineRect',
+ 'GDIPlus_RegionCombineRegion', 'GDIPlus_RegionCreate',
+ 'GDIPlus_RegionCreateFromPath', 'GDIPlus_RegionCreateFromRect',
+ 'GDIPlus_RegionDispose', 'GDIPlus_RegionGetBounds',
+ 'GDIPlus_RegionGetHRgn', 'GDIPlus_RegionTransform',
+ 'GDIPlus_RegionTranslate', 'GDIPlus_Shutdown', 'GDIPlus_Startup',
+ 'GDIPlus_StringFormatCreate', 'GDIPlus_StringFormatDispose',
+ 'GDIPlus_StringFormatGetMeasurableCharacterRangeCount',
+ 'GDIPlus_StringFormatSetAlign', 'GDIPlus_StringFormatSetLineAlign',
+ 'GDIPlus_StringFormatSetMeasurableCharacterRanges',
+ 'GDIPlus_TextureCreate', 'GDIPlus_TextureCreate2',
+ 'GDIPlus_TextureCreateIA', 'GetIP', 'GUICtrlAVI_Close',
+ 'GUICtrlAVI_Create', 'GUICtrlAVI_Destroy', 'GUICtrlAVI_IsPlaying',
+ 'GUICtrlAVI_Open', 'GUICtrlAVI_OpenEx', 'GUICtrlAVI_Play',
+ 'GUICtrlAVI_Seek', 'GUICtrlAVI_Show', 'GUICtrlAVI_Stop',
+ 'GUICtrlButton_Click', 'GUICtrlButton_Create',
+ 'GUICtrlButton_Destroy', 'GUICtrlButton_Enable',
+ 'GUICtrlButton_GetCheck', 'GUICtrlButton_GetFocus',
+ 'GUICtrlButton_GetIdealSize', 'GUICtrlButton_GetImage',
+ 'GUICtrlButton_GetImageList', 'GUICtrlButton_GetNote',
+ 'GUICtrlButton_GetNoteLength', 'GUICtrlButton_GetSplitInfo',
+ 'GUICtrlButton_GetState', 'GUICtrlButton_GetText',
+ 'GUICtrlButton_GetTextMargin', 'GUICtrlButton_SetCheck',
+ 'GUICtrlButton_SetDontClick', 'GUICtrlButton_SetFocus',
+ 'GUICtrlButton_SetImage', 'GUICtrlButton_SetImageList',
+ 'GUICtrlButton_SetNote', 'GUICtrlButton_SetShield',
+ 'GUICtrlButton_SetSize', 'GUICtrlButton_SetSplitInfo',
+ 'GUICtrlButton_SetState', 'GUICtrlButton_SetStyle',
+ 'GUICtrlButton_SetText', 'GUICtrlButton_SetTextMargin',
+ 'GUICtrlButton_Show', 'GUICtrlComboBoxEx_AddDir',
+ 'GUICtrlComboBoxEx_AddString', 'GUICtrlComboBoxEx_BeginUpdate',
+ 'GUICtrlComboBoxEx_Create', 'GUICtrlComboBoxEx_CreateSolidBitMap',
+ 'GUICtrlComboBoxEx_DeleteString', 'GUICtrlComboBoxEx_Destroy',
+ 'GUICtrlComboBoxEx_EndUpdate', 'GUICtrlComboBoxEx_FindStringExact',
+ 'GUICtrlComboBoxEx_GetComboBoxInfo',
+ 'GUICtrlComboBoxEx_GetComboControl', 'GUICtrlComboBoxEx_GetCount',
+ 'GUICtrlComboBoxEx_GetCurSel',
+ 'GUICtrlComboBoxEx_GetDroppedControlRect',
+ 'GUICtrlComboBoxEx_GetDroppedControlRectEx',
+ 'GUICtrlComboBoxEx_GetDroppedState',
+ 'GUICtrlComboBoxEx_GetDroppedWidth',
+ 'GUICtrlComboBoxEx_GetEditControl', 'GUICtrlComboBoxEx_GetEditSel',
+ 'GUICtrlComboBoxEx_GetEditText',
+ 'GUICtrlComboBoxEx_GetExtendedStyle',
+ 'GUICtrlComboBoxEx_GetExtendedUI', 'GUICtrlComboBoxEx_GetImageList',
+ 'GUICtrlComboBoxEx_GetItem', 'GUICtrlComboBoxEx_GetItemEx',
+ 'GUICtrlComboBoxEx_GetItemHeight', 'GUICtrlComboBoxEx_GetItemImage',
+ 'GUICtrlComboBoxEx_GetItemIndent',
+ 'GUICtrlComboBoxEx_GetItemOverlayImage',
+ 'GUICtrlComboBoxEx_GetItemParam',
+ 'GUICtrlComboBoxEx_GetItemSelectedImage',
+ 'GUICtrlComboBoxEx_GetItemText', 'GUICtrlComboBoxEx_GetItemTextLen',
+ 'GUICtrlComboBoxEx_GetList', 'GUICtrlComboBoxEx_GetListArray',
+ 'GUICtrlComboBoxEx_GetLocale', 'GUICtrlComboBoxEx_GetLocaleCountry',
+ 'GUICtrlComboBoxEx_GetLocaleLang',
+ 'GUICtrlComboBoxEx_GetLocalePrimLang',
+ 'GUICtrlComboBoxEx_GetLocaleSubLang',
+ 'GUICtrlComboBoxEx_GetMinVisible', 'GUICtrlComboBoxEx_GetTopIndex',
+ 'GUICtrlComboBoxEx_GetUnicode', 'GUICtrlComboBoxEx_InitStorage',
+ 'GUICtrlComboBoxEx_InsertString', 'GUICtrlComboBoxEx_LimitText',
+ 'GUICtrlComboBoxEx_ReplaceEditSel', 'GUICtrlComboBoxEx_ResetContent',
+ 'GUICtrlComboBoxEx_SetCurSel', 'GUICtrlComboBoxEx_SetDroppedWidth',
+ 'GUICtrlComboBoxEx_SetEditSel', 'GUICtrlComboBoxEx_SetEditText',
+ 'GUICtrlComboBoxEx_SetExtendedStyle',
+ 'GUICtrlComboBoxEx_SetExtendedUI', 'GUICtrlComboBoxEx_SetImageList',
+ 'GUICtrlComboBoxEx_SetItem', 'GUICtrlComboBoxEx_SetItemEx',
+ 'GUICtrlComboBoxEx_SetItemHeight', 'GUICtrlComboBoxEx_SetItemImage',
+ 'GUICtrlComboBoxEx_SetItemIndent',
+ 'GUICtrlComboBoxEx_SetItemOverlayImage',
+ 'GUICtrlComboBoxEx_SetItemParam',
+ 'GUICtrlComboBoxEx_SetItemSelectedImage',
+ 'GUICtrlComboBoxEx_SetMinVisible', 'GUICtrlComboBoxEx_SetTopIndex',
+ 'GUICtrlComboBoxEx_SetUnicode', 'GUICtrlComboBoxEx_ShowDropDown',
+ 'GUICtrlComboBox_AddDir', 'GUICtrlComboBox_AddString',
+ 'GUICtrlComboBox_AutoComplete', 'GUICtrlComboBox_BeginUpdate',
+ 'GUICtrlComboBox_Create', 'GUICtrlComboBox_DeleteString',
+ 'GUICtrlComboBox_Destroy', 'GUICtrlComboBox_EndUpdate',
+ 'GUICtrlComboBox_FindString', 'GUICtrlComboBox_FindStringExact',
+ 'GUICtrlComboBox_GetComboBoxInfo', 'GUICtrlComboBox_GetCount',
+ 'GUICtrlComboBox_GetCueBanner', 'GUICtrlComboBox_GetCurSel',
+ 'GUICtrlComboBox_GetDroppedControlRect',
+ 'GUICtrlComboBox_GetDroppedControlRectEx',
+ 'GUICtrlComboBox_GetDroppedState', 'GUICtrlComboBox_GetDroppedWidth',
+ 'GUICtrlComboBox_GetEditSel', 'GUICtrlComboBox_GetEditText',
+ 'GUICtrlComboBox_GetExtendedUI',
+ 'GUICtrlComboBox_GetHorizontalExtent',
+ 'GUICtrlComboBox_GetItemHeight', 'GUICtrlComboBox_GetLBText',
+ 'GUICtrlComboBox_GetLBTextLen', 'GUICtrlComboBox_GetList',
+ 'GUICtrlComboBox_GetListArray', 'GUICtrlComboBox_GetLocale',
+ 'GUICtrlComboBox_GetLocaleCountry', 'GUICtrlComboBox_GetLocaleLang',
+ 'GUICtrlComboBox_GetLocalePrimLang',
+ 'GUICtrlComboBox_GetLocaleSubLang', 'GUICtrlComboBox_GetMinVisible',
+ 'GUICtrlComboBox_GetTopIndex', 'GUICtrlComboBox_InitStorage',
+ 'GUICtrlComboBox_InsertString', 'GUICtrlComboBox_LimitText',
+ 'GUICtrlComboBox_ReplaceEditSel', 'GUICtrlComboBox_ResetContent',
+ 'GUICtrlComboBox_SelectString', 'GUICtrlComboBox_SetCueBanner',
+ 'GUICtrlComboBox_SetCurSel', 'GUICtrlComboBox_SetDroppedWidth',
+ 'GUICtrlComboBox_SetEditSel', 'GUICtrlComboBox_SetEditText',
+ 'GUICtrlComboBox_SetExtendedUI',
+ 'GUICtrlComboBox_SetHorizontalExtent',
+ 'GUICtrlComboBox_SetItemHeight', 'GUICtrlComboBox_SetMinVisible',
+ 'GUICtrlComboBox_SetTopIndex', 'GUICtrlComboBox_ShowDropDown',
+ 'GUICtrlDTP_Create', 'GUICtrlDTP_Destroy', 'GUICtrlDTP_GetMCColor',
+ 'GUICtrlDTP_GetMCFont', 'GUICtrlDTP_GetMonthCal',
+ 'GUICtrlDTP_GetRange', 'GUICtrlDTP_GetRangeEx',
+ 'GUICtrlDTP_GetSystemTime', 'GUICtrlDTP_GetSystemTimeEx',
+ 'GUICtrlDTP_SetFormat', 'GUICtrlDTP_SetMCColor',
+ 'GUICtrlDTP_SetMCFont', 'GUICtrlDTP_SetRange',
+ 'GUICtrlDTP_SetRangeEx', 'GUICtrlDTP_SetSystemTime',
+ 'GUICtrlDTP_SetSystemTimeEx', 'GUICtrlEdit_AppendText',
+ 'GUICtrlEdit_BeginUpdate', 'GUICtrlEdit_CanUndo',
+ 'GUICtrlEdit_CharFromPos', 'GUICtrlEdit_Create',
+ 'GUICtrlEdit_Destroy', 'GUICtrlEdit_EmptyUndoBuffer',
+ 'GUICtrlEdit_EndUpdate', 'GUICtrlEdit_Find', 'GUICtrlEdit_FmtLines',
+ 'GUICtrlEdit_GetCueBanner', 'GUICtrlEdit_GetFirstVisibleLine',
+ 'GUICtrlEdit_GetLimitText', 'GUICtrlEdit_GetLine',
+ 'GUICtrlEdit_GetLineCount', 'GUICtrlEdit_GetMargins',
+ 'GUICtrlEdit_GetModify', 'GUICtrlEdit_GetPasswordChar',
+ 'GUICtrlEdit_GetRECT', 'GUICtrlEdit_GetRECTEx', 'GUICtrlEdit_GetSel',
+ 'GUICtrlEdit_GetText', 'GUICtrlEdit_GetTextLen',
+ 'GUICtrlEdit_HideBalloonTip', 'GUICtrlEdit_InsertText',
+ 'GUICtrlEdit_LineFromChar', 'GUICtrlEdit_LineIndex',
+ 'GUICtrlEdit_LineLength', 'GUICtrlEdit_LineScroll',
+ 'GUICtrlEdit_PosFromChar', 'GUICtrlEdit_ReplaceSel',
+ 'GUICtrlEdit_Scroll', 'GUICtrlEdit_SetCueBanner',
+ 'GUICtrlEdit_SetLimitText', 'GUICtrlEdit_SetMargins',
+ 'GUICtrlEdit_SetModify', 'GUICtrlEdit_SetPasswordChar',
+ 'GUICtrlEdit_SetReadOnly', 'GUICtrlEdit_SetRECT',
+ 'GUICtrlEdit_SetRECTEx', 'GUICtrlEdit_SetRECTNP',
+ 'GUICtrlEdit_SetRectNPEx', 'GUICtrlEdit_SetSel',
+ 'GUICtrlEdit_SetTabStops', 'GUICtrlEdit_SetText',
+ 'GUICtrlEdit_ShowBalloonTip', 'GUICtrlEdit_Undo',
+ 'GUICtrlHeader_AddItem', 'GUICtrlHeader_ClearFilter',
+ 'GUICtrlHeader_ClearFilterAll', 'GUICtrlHeader_Create',
+ 'GUICtrlHeader_CreateDragImage', 'GUICtrlHeader_DeleteItem',
+ 'GUICtrlHeader_Destroy', 'GUICtrlHeader_EditFilter',
+ 'GUICtrlHeader_GetBitmapMargin', 'GUICtrlHeader_GetImageList',
+ 'GUICtrlHeader_GetItem', 'GUICtrlHeader_GetItemAlign',
+ 'GUICtrlHeader_GetItemBitmap', 'GUICtrlHeader_GetItemCount',
+ 'GUICtrlHeader_GetItemDisplay', 'GUICtrlHeader_GetItemFlags',
+ 'GUICtrlHeader_GetItemFormat', 'GUICtrlHeader_GetItemImage',
+ 'GUICtrlHeader_GetItemOrder', 'GUICtrlHeader_GetItemParam',
+ 'GUICtrlHeader_GetItemRect', 'GUICtrlHeader_GetItemRectEx',
+ 'GUICtrlHeader_GetItemText', 'GUICtrlHeader_GetItemWidth',
+ 'GUICtrlHeader_GetOrderArray', 'GUICtrlHeader_GetUnicodeFormat',
+ 'GUICtrlHeader_HitTest', 'GUICtrlHeader_InsertItem',
+ 'GUICtrlHeader_Layout', 'GUICtrlHeader_OrderToIndex',
+ 'GUICtrlHeader_SetBitmapMargin',
+ 'GUICtrlHeader_SetFilterChangeTimeout',
+ 'GUICtrlHeader_SetHotDivider', 'GUICtrlHeader_SetImageList',
+ 'GUICtrlHeader_SetItem', 'GUICtrlHeader_SetItemAlign',
+ 'GUICtrlHeader_SetItemBitmap', 'GUICtrlHeader_SetItemDisplay',
+ 'GUICtrlHeader_SetItemFlags', 'GUICtrlHeader_SetItemFormat',
+ 'GUICtrlHeader_SetItemImage', 'GUICtrlHeader_SetItemOrder',
+ 'GUICtrlHeader_SetItemParam', 'GUICtrlHeader_SetItemText',
+ 'GUICtrlHeader_SetItemWidth', 'GUICtrlHeader_SetOrderArray',
+ 'GUICtrlHeader_SetUnicodeFormat', 'GUICtrlIpAddress_ClearAddress',
+ 'GUICtrlIpAddress_Create', 'GUICtrlIpAddress_Destroy',
+ 'GUICtrlIpAddress_Get', 'GUICtrlIpAddress_GetArray',
+ 'GUICtrlIpAddress_GetEx', 'GUICtrlIpAddress_IsBlank',
+ 'GUICtrlIpAddress_Set', 'GUICtrlIpAddress_SetArray',
+ 'GUICtrlIpAddress_SetEx', 'GUICtrlIpAddress_SetFocus',
+ 'GUICtrlIpAddress_SetFont', 'GUICtrlIpAddress_SetRange',
+ 'GUICtrlIpAddress_ShowHide', 'GUICtrlListBox_AddFile',
+ 'GUICtrlListBox_AddString', 'GUICtrlListBox_BeginUpdate',
+ 'GUICtrlListBox_ClickItem', 'GUICtrlListBox_Create',
+ 'GUICtrlListBox_DeleteString', 'GUICtrlListBox_Destroy',
+ 'GUICtrlListBox_Dir', 'GUICtrlListBox_EndUpdate',
+ 'GUICtrlListBox_FindInText', 'GUICtrlListBox_FindString',
+ 'GUICtrlListBox_GetAnchorIndex', 'GUICtrlListBox_GetCaretIndex',
+ 'GUICtrlListBox_GetCount', 'GUICtrlListBox_GetCurSel',
+ 'GUICtrlListBox_GetHorizontalExtent', 'GUICtrlListBox_GetItemData',
+ 'GUICtrlListBox_GetItemHeight', 'GUICtrlListBox_GetItemRect',
+ 'GUICtrlListBox_GetItemRectEx', 'GUICtrlListBox_GetListBoxInfo',
+ 'GUICtrlListBox_GetLocale', 'GUICtrlListBox_GetLocaleCountry',
+ 'GUICtrlListBox_GetLocaleLang', 'GUICtrlListBox_GetLocalePrimLang',
+ 'GUICtrlListBox_GetLocaleSubLang', 'GUICtrlListBox_GetSel',
+ 'GUICtrlListBox_GetSelCount', 'GUICtrlListBox_GetSelItems',
+ 'GUICtrlListBox_GetSelItemsText', 'GUICtrlListBox_GetText',
+ 'GUICtrlListBox_GetTextLen', 'GUICtrlListBox_GetTopIndex',
+ 'GUICtrlListBox_InitStorage', 'GUICtrlListBox_InsertString',
+ 'GUICtrlListBox_ItemFromPoint', 'GUICtrlListBox_ReplaceString',
+ 'GUICtrlListBox_ResetContent', 'GUICtrlListBox_SelectString',
+ 'GUICtrlListBox_SelItemRange', 'GUICtrlListBox_SelItemRangeEx',
+ 'GUICtrlListBox_SetAnchorIndex', 'GUICtrlListBox_SetCaretIndex',
+ 'GUICtrlListBox_SetColumnWidth', 'GUICtrlListBox_SetCurSel',
+ 'GUICtrlListBox_SetHorizontalExtent', 'GUICtrlListBox_SetItemData',
+ 'GUICtrlListBox_SetItemHeight', 'GUICtrlListBox_SetLocale',
+ 'GUICtrlListBox_SetSel', 'GUICtrlListBox_SetTabStops',
+ 'GUICtrlListBox_SetTopIndex', 'GUICtrlListBox_Sort',
+ 'GUICtrlListBox_SwapString', 'GUICtrlListBox_UpdateHScroll',
+ 'GUICtrlListView_AddArray', 'GUICtrlListView_AddColumn',
+ 'GUICtrlListView_AddItem', 'GUICtrlListView_AddSubItem',
+ 'GUICtrlListView_ApproximateViewHeight',
+ 'GUICtrlListView_ApproximateViewRect',
+ 'GUICtrlListView_ApproximateViewWidth', 'GUICtrlListView_Arrange',
+ 'GUICtrlListView_BeginUpdate', 'GUICtrlListView_CancelEditLabel',
+ 'GUICtrlListView_ClickItem', 'GUICtrlListView_CopyItems',
+ 'GUICtrlListView_Create', 'GUICtrlListView_CreateDragImage',
+ 'GUICtrlListView_CreateSolidBitMap',
+ 'GUICtrlListView_DeleteAllItems', 'GUICtrlListView_DeleteColumn',
+ 'GUICtrlListView_DeleteItem', 'GUICtrlListView_DeleteItemsSelected',
+ 'GUICtrlListView_Destroy', 'GUICtrlListView_DrawDragImage',
+ 'GUICtrlListView_EditLabel', 'GUICtrlListView_EnableGroupView',
+ 'GUICtrlListView_EndUpdate', 'GUICtrlListView_EnsureVisible',
+ 'GUICtrlListView_FindInText', 'GUICtrlListView_FindItem',
+ 'GUICtrlListView_FindNearest', 'GUICtrlListView_FindParam',
+ 'GUICtrlListView_FindText', 'GUICtrlListView_GetBkColor',
+ 'GUICtrlListView_GetBkImage', 'GUICtrlListView_GetCallbackMask',
+ 'GUICtrlListView_GetColumn', 'GUICtrlListView_GetColumnCount',
+ 'GUICtrlListView_GetColumnOrder',
+ 'GUICtrlListView_GetColumnOrderArray',
+ 'GUICtrlListView_GetColumnWidth', 'GUICtrlListView_GetCounterPage',
+ 'GUICtrlListView_GetEditControl',
+ 'GUICtrlListView_GetExtendedListViewStyle',
+ 'GUICtrlListView_GetFocusedGroup', 'GUICtrlListView_GetGroupCount',
+ 'GUICtrlListView_GetGroupInfo',
+ 'GUICtrlListView_GetGroupInfoByIndex',
+ 'GUICtrlListView_GetGroupRect',
+ 'GUICtrlListView_GetGroupViewEnabled', 'GUICtrlListView_GetHeader',
+ 'GUICtrlListView_GetHotCursor', 'GUICtrlListView_GetHotItem',
+ 'GUICtrlListView_GetHoverTime', 'GUICtrlListView_GetImageList',
+ 'GUICtrlListView_GetISearchString', 'GUICtrlListView_GetItem',
+ 'GUICtrlListView_GetItemChecked', 'GUICtrlListView_GetItemCount',
+ 'GUICtrlListView_GetItemCut', 'GUICtrlListView_GetItemDropHilited',
+ 'GUICtrlListView_GetItemEx', 'GUICtrlListView_GetItemFocused',
+ 'GUICtrlListView_GetItemGroupID', 'GUICtrlListView_GetItemImage',
+ 'GUICtrlListView_GetItemIndent', 'GUICtrlListView_GetItemParam',
+ 'GUICtrlListView_GetItemPosition',
+ 'GUICtrlListView_GetItemPositionX',
+ 'GUICtrlListView_GetItemPositionY', 'GUICtrlListView_GetItemRect',
+ 'GUICtrlListView_GetItemRectEx', 'GUICtrlListView_GetItemSelected',
+ 'GUICtrlListView_GetItemSpacing', 'GUICtrlListView_GetItemSpacingX',
+ 'GUICtrlListView_GetItemSpacingY', 'GUICtrlListView_GetItemState',
+ 'GUICtrlListView_GetItemStateImage', 'GUICtrlListView_GetItemText',
+ 'GUICtrlListView_GetItemTextArray',
+ 'GUICtrlListView_GetItemTextString', 'GUICtrlListView_GetNextItem',
+ 'GUICtrlListView_GetNumberOfWorkAreas', 'GUICtrlListView_GetOrigin',
+ 'GUICtrlListView_GetOriginX', 'GUICtrlListView_GetOriginY',
+ 'GUICtrlListView_GetOutlineColor',
+ 'GUICtrlListView_GetSelectedColumn',
+ 'GUICtrlListView_GetSelectedCount',
+ 'GUICtrlListView_GetSelectedIndices',
+ 'GUICtrlListView_GetSelectionMark', 'GUICtrlListView_GetStringWidth',
+ 'GUICtrlListView_GetSubItemRect', 'GUICtrlListView_GetTextBkColor',
+ 'GUICtrlListView_GetTextColor', 'GUICtrlListView_GetToolTips',
+ 'GUICtrlListView_GetTopIndex', 'GUICtrlListView_GetUnicodeFormat',
+ 'GUICtrlListView_GetView', 'GUICtrlListView_GetViewDetails',
+ 'GUICtrlListView_GetViewLarge', 'GUICtrlListView_GetViewList',
+ 'GUICtrlListView_GetViewRect', 'GUICtrlListView_GetViewSmall',
+ 'GUICtrlListView_GetViewTile', 'GUICtrlListView_HideColumn',
+ 'GUICtrlListView_HitTest', 'GUICtrlListView_InsertColumn',
+ 'GUICtrlListView_InsertGroup', 'GUICtrlListView_InsertItem',
+ 'GUICtrlListView_JustifyColumn', 'GUICtrlListView_MapIDToIndex',
+ 'GUICtrlListView_MapIndexToID', 'GUICtrlListView_RedrawItems',
+ 'GUICtrlListView_RegisterSortCallBack',
+ 'GUICtrlListView_RemoveAllGroups', 'GUICtrlListView_RemoveGroup',
+ 'GUICtrlListView_Scroll', 'GUICtrlListView_SetBkColor',
+ 'GUICtrlListView_SetBkImage', 'GUICtrlListView_SetCallBackMask',
+ 'GUICtrlListView_SetColumn', 'GUICtrlListView_SetColumnOrder',
+ 'GUICtrlListView_SetColumnOrderArray',
+ 'GUICtrlListView_SetColumnWidth',
+ 'GUICtrlListView_SetExtendedListViewStyle',
+ 'GUICtrlListView_SetGroupInfo', 'GUICtrlListView_SetHotItem',
+ 'GUICtrlListView_SetHoverTime', 'GUICtrlListView_SetIconSpacing',
+ 'GUICtrlListView_SetImageList', 'GUICtrlListView_SetItem',
+ 'GUICtrlListView_SetItemChecked', 'GUICtrlListView_SetItemCount',
+ 'GUICtrlListView_SetItemCut', 'GUICtrlListView_SetItemDropHilited',
+ 'GUICtrlListView_SetItemEx', 'GUICtrlListView_SetItemFocused',
+ 'GUICtrlListView_SetItemGroupID', 'GUICtrlListView_SetItemImage',
+ 'GUICtrlListView_SetItemIndent', 'GUICtrlListView_SetItemParam',
+ 'GUICtrlListView_SetItemPosition',
+ 'GUICtrlListView_SetItemPosition32',
+ 'GUICtrlListView_SetItemSelected', 'GUICtrlListView_SetItemState',
+ 'GUICtrlListView_SetItemStateImage', 'GUICtrlListView_SetItemText',
+ 'GUICtrlListView_SetOutlineColor',
+ 'GUICtrlListView_SetSelectedColumn',
+ 'GUICtrlListView_SetSelectionMark', 'GUICtrlListView_SetTextBkColor',
+ 'GUICtrlListView_SetTextColor', 'GUICtrlListView_SetToolTips',
+ 'GUICtrlListView_SetUnicodeFormat', 'GUICtrlListView_SetView',
+ 'GUICtrlListView_SetWorkAreas', 'GUICtrlListView_SimpleSort',
+ 'GUICtrlListView_SortItems', 'GUICtrlListView_SubItemHitTest',
+ 'GUICtrlListView_UnRegisterSortCallBack', 'GUICtrlMenu_AddMenuItem',
+ 'GUICtrlMenu_AppendMenu', 'GUICtrlMenu_CalculatePopupWindowPosition',
+ 'GUICtrlMenu_CheckMenuItem', 'GUICtrlMenu_CheckRadioItem',
+ 'GUICtrlMenu_CreateMenu', 'GUICtrlMenu_CreatePopup',
+ 'GUICtrlMenu_DeleteMenu', 'GUICtrlMenu_DestroyMenu',
+ 'GUICtrlMenu_DrawMenuBar', 'GUICtrlMenu_EnableMenuItem',
+ 'GUICtrlMenu_FindItem', 'GUICtrlMenu_FindParent',
+ 'GUICtrlMenu_GetItemBmp', 'GUICtrlMenu_GetItemBmpChecked',
+ 'GUICtrlMenu_GetItemBmpUnchecked', 'GUICtrlMenu_GetItemChecked',
+ 'GUICtrlMenu_GetItemCount', 'GUICtrlMenu_GetItemData',
+ 'GUICtrlMenu_GetItemDefault', 'GUICtrlMenu_GetItemDisabled',
+ 'GUICtrlMenu_GetItemEnabled', 'GUICtrlMenu_GetItemGrayed',
+ 'GUICtrlMenu_GetItemHighlighted', 'GUICtrlMenu_GetItemID',
+ 'GUICtrlMenu_GetItemInfo', 'GUICtrlMenu_GetItemRect',
+ 'GUICtrlMenu_GetItemRectEx', 'GUICtrlMenu_GetItemState',
+ 'GUICtrlMenu_GetItemStateEx', 'GUICtrlMenu_GetItemSubMenu',
+ 'GUICtrlMenu_GetItemText', 'GUICtrlMenu_GetItemType',
+ 'GUICtrlMenu_GetMenu', 'GUICtrlMenu_GetMenuBackground',
+ 'GUICtrlMenu_GetMenuBarInfo', 'GUICtrlMenu_GetMenuContextHelpID',
+ 'GUICtrlMenu_GetMenuData', 'GUICtrlMenu_GetMenuDefaultItem',
+ 'GUICtrlMenu_GetMenuHeight', 'GUICtrlMenu_GetMenuInfo',
+ 'GUICtrlMenu_GetMenuStyle', 'GUICtrlMenu_GetSystemMenu',
+ 'GUICtrlMenu_InsertMenuItem', 'GUICtrlMenu_InsertMenuItemEx',
+ 'GUICtrlMenu_IsMenu', 'GUICtrlMenu_LoadMenu',
+ 'GUICtrlMenu_MapAccelerator', 'GUICtrlMenu_MenuItemFromPoint',
+ 'GUICtrlMenu_RemoveMenu', 'GUICtrlMenu_SetItemBitmaps',
+ 'GUICtrlMenu_SetItemBmp', 'GUICtrlMenu_SetItemBmpChecked',
+ 'GUICtrlMenu_SetItemBmpUnchecked', 'GUICtrlMenu_SetItemChecked',
+ 'GUICtrlMenu_SetItemData', 'GUICtrlMenu_SetItemDefault',
+ 'GUICtrlMenu_SetItemDisabled', 'GUICtrlMenu_SetItemEnabled',
+ 'GUICtrlMenu_SetItemGrayed', 'GUICtrlMenu_SetItemHighlighted',
+ 'GUICtrlMenu_SetItemID', 'GUICtrlMenu_SetItemInfo',
+ 'GUICtrlMenu_SetItemState', 'GUICtrlMenu_SetItemSubMenu',
+ 'GUICtrlMenu_SetItemText', 'GUICtrlMenu_SetItemType',
+ 'GUICtrlMenu_SetMenu', 'GUICtrlMenu_SetMenuBackground',
+ 'GUICtrlMenu_SetMenuContextHelpID', 'GUICtrlMenu_SetMenuData',
+ 'GUICtrlMenu_SetMenuDefaultItem', 'GUICtrlMenu_SetMenuHeight',
+ 'GUICtrlMenu_SetMenuInfo', 'GUICtrlMenu_SetMenuStyle',
+ 'GUICtrlMenu_TrackPopupMenu', 'GUICtrlMonthCal_Create',
+ 'GUICtrlMonthCal_Destroy', 'GUICtrlMonthCal_GetCalendarBorder',
+ 'GUICtrlMonthCal_GetCalendarCount', 'GUICtrlMonthCal_GetColor',
+ 'GUICtrlMonthCal_GetColorArray', 'GUICtrlMonthCal_GetCurSel',
+ 'GUICtrlMonthCal_GetCurSelStr', 'GUICtrlMonthCal_GetFirstDOW',
+ 'GUICtrlMonthCal_GetFirstDOWStr', 'GUICtrlMonthCal_GetMaxSelCount',
+ 'GUICtrlMonthCal_GetMaxTodayWidth',
+ 'GUICtrlMonthCal_GetMinReqHeight', 'GUICtrlMonthCal_GetMinReqRect',
+ 'GUICtrlMonthCal_GetMinReqRectArray',
+ 'GUICtrlMonthCal_GetMinReqWidth', 'GUICtrlMonthCal_GetMonthDelta',
+ 'GUICtrlMonthCal_GetMonthRange', 'GUICtrlMonthCal_GetMonthRangeMax',
+ 'GUICtrlMonthCal_GetMonthRangeMaxStr',
+ 'GUICtrlMonthCal_GetMonthRangeMin',
+ 'GUICtrlMonthCal_GetMonthRangeMinStr',
+ 'GUICtrlMonthCal_GetMonthRangeSpan', 'GUICtrlMonthCal_GetRange',
+ 'GUICtrlMonthCal_GetRangeMax', 'GUICtrlMonthCal_GetRangeMaxStr',
+ 'GUICtrlMonthCal_GetRangeMin', 'GUICtrlMonthCal_GetRangeMinStr',
+ 'GUICtrlMonthCal_GetSelRange', 'GUICtrlMonthCal_GetSelRangeMax',
+ 'GUICtrlMonthCal_GetSelRangeMaxStr',
+ 'GUICtrlMonthCal_GetSelRangeMin',
+ 'GUICtrlMonthCal_GetSelRangeMinStr', 'GUICtrlMonthCal_GetToday',
+ 'GUICtrlMonthCal_GetTodayStr', 'GUICtrlMonthCal_GetUnicodeFormat',
+ 'GUICtrlMonthCal_HitTest', 'GUICtrlMonthCal_SetCalendarBorder',
+ 'GUICtrlMonthCal_SetColor', 'GUICtrlMonthCal_SetCurSel',
+ 'GUICtrlMonthCal_SetDayState', 'GUICtrlMonthCal_SetFirstDOW',
+ 'GUICtrlMonthCal_SetMaxSelCount', 'GUICtrlMonthCal_SetMonthDelta',
+ 'GUICtrlMonthCal_SetRange', 'GUICtrlMonthCal_SetSelRange',
+ 'GUICtrlMonthCal_SetToday', 'GUICtrlMonthCal_SetUnicodeFormat',
+ 'GUICtrlRebar_AddBand', 'GUICtrlRebar_AddToolBarBand',
+ 'GUICtrlRebar_BeginDrag', 'GUICtrlRebar_Create',
+ 'GUICtrlRebar_DeleteBand', 'GUICtrlRebar_Destroy',
+ 'GUICtrlRebar_DragMove', 'GUICtrlRebar_EndDrag',
+ 'GUICtrlRebar_GetBandBackColor', 'GUICtrlRebar_GetBandBorders',
+ 'GUICtrlRebar_GetBandBordersEx', 'GUICtrlRebar_GetBandChildHandle',
+ 'GUICtrlRebar_GetBandChildSize', 'GUICtrlRebar_GetBandCount',
+ 'GUICtrlRebar_GetBandForeColor', 'GUICtrlRebar_GetBandHeaderSize',
+ 'GUICtrlRebar_GetBandID', 'GUICtrlRebar_GetBandIdealSize',
+ 'GUICtrlRebar_GetBandLength', 'GUICtrlRebar_GetBandLParam',
+ 'GUICtrlRebar_GetBandMargins', 'GUICtrlRebar_GetBandMarginsEx',
+ 'GUICtrlRebar_GetBandRect', 'GUICtrlRebar_GetBandRectEx',
+ 'GUICtrlRebar_GetBandStyle', 'GUICtrlRebar_GetBandStyleBreak',
+ 'GUICtrlRebar_GetBandStyleChildEdge',
+ 'GUICtrlRebar_GetBandStyleFixedBMP',
+ 'GUICtrlRebar_GetBandStyleFixedSize',
+ 'GUICtrlRebar_GetBandStyleGripperAlways',
+ 'GUICtrlRebar_GetBandStyleHidden',
+ 'GUICtrlRebar_GetBandStyleHideTitle',
+ 'GUICtrlRebar_GetBandStyleNoGripper',
+ 'GUICtrlRebar_GetBandStyleTopAlign',
+ 'GUICtrlRebar_GetBandStyleUseChevron',
+ 'GUICtrlRebar_GetBandStyleVariableHeight',
+ 'GUICtrlRebar_GetBandText', 'GUICtrlRebar_GetBarHeight',
+ 'GUICtrlRebar_GetBarInfo', 'GUICtrlRebar_GetBKColor',
+ 'GUICtrlRebar_GetColorScheme', 'GUICtrlRebar_GetRowCount',
+ 'GUICtrlRebar_GetRowHeight', 'GUICtrlRebar_GetTextColor',
+ 'GUICtrlRebar_GetToolTips', 'GUICtrlRebar_GetUnicodeFormat',
+ 'GUICtrlRebar_HitTest', 'GUICtrlRebar_IDToIndex',
+ 'GUICtrlRebar_MaximizeBand', 'GUICtrlRebar_MinimizeBand',
+ 'GUICtrlRebar_MoveBand', 'GUICtrlRebar_SetBandBackColor',
+ 'GUICtrlRebar_SetBandForeColor', 'GUICtrlRebar_SetBandHeaderSize',
+ 'GUICtrlRebar_SetBandID', 'GUICtrlRebar_SetBandIdealSize',
+ 'GUICtrlRebar_SetBandLength', 'GUICtrlRebar_SetBandLParam',
+ 'GUICtrlRebar_SetBandStyle', 'GUICtrlRebar_SetBandStyleBreak',
+ 'GUICtrlRebar_SetBandStyleChildEdge',
+ 'GUICtrlRebar_SetBandStyleFixedBMP',
+ 'GUICtrlRebar_SetBandStyleFixedSize',
+ 'GUICtrlRebar_SetBandStyleGripperAlways',
+ 'GUICtrlRebar_SetBandStyleHidden',
+ 'GUICtrlRebar_SetBandStyleHideTitle',
+ 'GUICtrlRebar_SetBandStyleNoGripper',
+ 'GUICtrlRebar_SetBandStyleTopAlign',
+ 'GUICtrlRebar_SetBandStyleUseChevron',
+ 'GUICtrlRebar_SetBandStyleVariableHeight',
+ 'GUICtrlRebar_SetBandText', 'GUICtrlRebar_SetBarInfo',
+ 'GUICtrlRebar_SetBKColor', 'GUICtrlRebar_SetColorScheme',
+ 'GUICtrlRebar_SetTextColor', 'GUICtrlRebar_SetToolTips',
+ 'GUICtrlRebar_SetUnicodeFormat', 'GUICtrlRebar_ShowBand',
+ 'GUICtrlRichEdit_AppendText', 'GUICtrlRichEdit_AutoDetectURL',
+ 'GUICtrlRichEdit_CanPaste', 'GUICtrlRichEdit_CanPasteSpecial',
+ 'GUICtrlRichEdit_CanRedo', 'GUICtrlRichEdit_CanUndo',
+ 'GUICtrlRichEdit_ChangeFontSize', 'GUICtrlRichEdit_Copy',
+ 'GUICtrlRichEdit_Create', 'GUICtrlRichEdit_Cut',
+ 'GUICtrlRichEdit_Deselect', 'GUICtrlRichEdit_Destroy',
+ 'GUICtrlRichEdit_EmptyUndoBuffer', 'GUICtrlRichEdit_FindText',
+ 'GUICtrlRichEdit_FindTextInRange', 'GUICtrlRichEdit_GetBkColor',
+ 'GUICtrlRichEdit_GetCharAttributes',
+ 'GUICtrlRichEdit_GetCharBkColor', 'GUICtrlRichEdit_GetCharColor',
+ 'GUICtrlRichEdit_GetCharPosFromXY',
+ 'GUICtrlRichEdit_GetCharPosOfNextWord',
+ 'GUICtrlRichEdit_GetCharPosOfPreviousWord',
+ 'GUICtrlRichEdit_GetCharWordBreakInfo',
+ 'GUICtrlRichEdit_GetFirstCharPosOnLine', 'GUICtrlRichEdit_GetFont',
+ 'GUICtrlRichEdit_GetLineCount', 'GUICtrlRichEdit_GetLineLength',
+ 'GUICtrlRichEdit_GetLineNumberFromCharPos',
+ 'GUICtrlRichEdit_GetNextRedo', 'GUICtrlRichEdit_GetNextUndo',
+ 'GUICtrlRichEdit_GetNumberOfFirstVisibleLine',
+ 'GUICtrlRichEdit_GetParaAlignment',
+ 'GUICtrlRichEdit_GetParaAttributes', 'GUICtrlRichEdit_GetParaBorder',
+ 'GUICtrlRichEdit_GetParaIndents', 'GUICtrlRichEdit_GetParaNumbering',
+ 'GUICtrlRichEdit_GetParaShading', 'GUICtrlRichEdit_GetParaSpacing',
+ 'GUICtrlRichEdit_GetParaTabStops', 'GUICtrlRichEdit_GetPasswordChar',
+ 'GUICtrlRichEdit_GetRECT', 'GUICtrlRichEdit_GetScrollPos',
+ 'GUICtrlRichEdit_GetSel', 'GUICtrlRichEdit_GetSelAA',
+ 'GUICtrlRichEdit_GetSelText', 'GUICtrlRichEdit_GetSpaceUnit',
+ 'GUICtrlRichEdit_GetText', 'GUICtrlRichEdit_GetTextInLine',
+ 'GUICtrlRichEdit_GetTextInRange', 'GUICtrlRichEdit_GetTextLength',
+ 'GUICtrlRichEdit_GetVersion', 'GUICtrlRichEdit_GetXYFromCharPos',
+ 'GUICtrlRichEdit_GetZoom', 'GUICtrlRichEdit_GotoCharPos',
+ 'GUICtrlRichEdit_HideSelection', 'GUICtrlRichEdit_InsertText',
+ 'GUICtrlRichEdit_IsModified', 'GUICtrlRichEdit_IsTextSelected',
+ 'GUICtrlRichEdit_Paste', 'GUICtrlRichEdit_PasteSpecial',
+ 'GUICtrlRichEdit_PauseRedraw', 'GUICtrlRichEdit_Redo',
+ 'GUICtrlRichEdit_ReplaceText', 'GUICtrlRichEdit_ResumeRedraw',
+ 'GUICtrlRichEdit_ScrollLineOrPage', 'GUICtrlRichEdit_ScrollLines',
+ 'GUICtrlRichEdit_ScrollToCaret', 'GUICtrlRichEdit_SetBkColor',
+ 'GUICtrlRichEdit_SetCharAttributes',
+ 'GUICtrlRichEdit_SetCharBkColor', 'GUICtrlRichEdit_SetCharColor',
+ 'GUICtrlRichEdit_SetEventMask', 'GUICtrlRichEdit_SetFont',
+ 'GUICtrlRichEdit_SetLimitOnText', 'GUICtrlRichEdit_SetModified',
+ 'GUICtrlRichEdit_SetParaAlignment',
+ 'GUICtrlRichEdit_SetParaAttributes', 'GUICtrlRichEdit_SetParaBorder',
+ 'GUICtrlRichEdit_SetParaIndents', 'GUICtrlRichEdit_SetParaNumbering',
+ 'GUICtrlRichEdit_SetParaShading', 'GUICtrlRichEdit_SetParaSpacing',
+ 'GUICtrlRichEdit_SetParaTabStops', 'GUICtrlRichEdit_SetPasswordChar',
+ 'GUICtrlRichEdit_SetReadOnly', 'GUICtrlRichEdit_SetRECT',
+ 'GUICtrlRichEdit_SetScrollPos', 'GUICtrlRichEdit_SetSel',
+ 'GUICtrlRichEdit_SetSpaceUnit', 'GUICtrlRichEdit_SetTabStops',
+ 'GUICtrlRichEdit_SetText', 'GUICtrlRichEdit_SetUndoLimit',
+ 'GUICtrlRichEdit_SetZoom', 'GUICtrlRichEdit_StreamFromFile',
+ 'GUICtrlRichEdit_StreamFromVar', 'GUICtrlRichEdit_StreamToFile',
+ 'GUICtrlRichEdit_StreamToVar', 'GUICtrlRichEdit_Undo',
+ 'GUICtrlSlider_ClearSel', 'GUICtrlSlider_ClearTics',
+ 'GUICtrlSlider_Create', 'GUICtrlSlider_Destroy',
+ 'GUICtrlSlider_GetBuddy', 'GUICtrlSlider_GetChannelRect',
+ 'GUICtrlSlider_GetChannelRectEx', 'GUICtrlSlider_GetLineSize',
+ 'GUICtrlSlider_GetLogicalTics', 'GUICtrlSlider_GetNumTics',
+ 'GUICtrlSlider_GetPageSize', 'GUICtrlSlider_GetPos',
+ 'GUICtrlSlider_GetRange', 'GUICtrlSlider_GetRangeMax',
+ 'GUICtrlSlider_GetRangeMin', 'GUICtrlSlider_GetSel',
+ 'GUICtrlSlider_GetSelEnd', 'GUICtrlSlider_GetSelStart',
+ 'GUICtrlSlider_GetThumbLength', 'GUICtrlSlider_GetThumbRect',
+ 'GUICtrlSlider_GetThumbRectEx', 'GUICtrlSlider_GetTic',
+ 'GUICtrlSlider_GetTicPos', 'GUICtrlSlider_GetToolTips',
+ 'GUICtrlSlider_GetUnicodeFormat', 'GUICtrlSlider_SetBuddy',
+ 'GUICtrlSlider_SetLineSize', 'GUICtrlSlider_SetPageSize',
+ 'GUICtrlSlider_SetPos', 'GUICtrlSlider_SetRange',
+ 'GUICtrlSlider_SetRangeMax', 'GUICtrlSlider_SetRangeMin',
+ 'GUICtrlSlider_SetSel', 'GUICtrlSlider_SetSelEnd',
+ 'GUICtrlSlider_SetSelStart', 'GUICtrlSlider_SetThumbLength',
+ 'GUICtrlSlider_SetTic', 'GUICtrlSlider_SetTicFreq',
+ 'GUICtrlSlider_SetTipSide', 'GUICtrlSlider_SetToolTips',
+ 'GUICtrlSlider_SetUnicodeFormat', 'GUICtrlStatusBar_Create',
+ 'GUICtrlStatusBar_Destroy', 'GUICtrlStatusBar_EmbedControl',
+ 'GUICtrlStatusBar_GetBorders', 'GUICtrlStatusBar_GetBordersHorz',
+ 'GUICtrlStatusBar_GetBordersRect', 'GUICtrlStatusBar_GetBordersVert',
+ 'GUICtrlStatusBar_GetCount', 'GUICtrlStatusBar_GetHeight',
+ 'GUICtrlStatusBar_GetIcon', 'GUICtrlStatusBar_GetParts',
+ 'GUICtrlStatusBar_GetRect', 'GUICtrlStatusBar_GetRectEx',
+ 'GUICtrlStatusBar_GetText', 'GUICtrlStatusBar_GetTextFlags',
+ 'GUICtrlStatusBar_GetTextLength', 'GUICtrlStatusBar_GetTextLengthEx',
+ 'GUICtrlStatusBar_GetTipText', 'GUICtrlStatusBar_GetUnicodeFormat',
+ 'GUICtrlStatusBar_GetWidth', 'GUICtrlStatusBar_IsSimple',
+ 'GUICtrlStatusBar_Resize', 'GUICtrlStatusBar_SetBkColor',
+ 'GUICtrlStatusBar_SetIcon', 'GUICtrlStatusBar_SetMinHeight',
+ 'GUICtrlStatusBar_SetParts', 'GUICtrlStatusBar_SetSimple',
+ 'GUICtrlStatusBar_SetText', 'GUICtrlStatusBar_SetTipText',
+ 'GUICtrlStatusBar_SetUnicodeFormat', 'GUICtrlStatusBar_ShowHide',
+ 'GUICtrlTab_ActivateTab', 'GUICtrlTab_ClickTab', 'GUICtrlTab_Create',
+ 'GUICtrlTab_DeleteAllItems', 'GUICtrlTab_DeleteItem',
+ 'GUICtrlTab_DeselectAll', 'GUICtrlTab_Destroy', 'GUICtrlTab_FindTab',
+ 'GUICtrlTab_GetCurFocus', 'GUICtrlTab_GetCurSel',
+ 'GUICtrlTab_GetDisplayRect', 'GUICtrlTab_GetDisplayRectEx',
+ 'GUICtrlTab_GetExtendedStyle', 'GUICtrlTab_GetImageList',
+ 'GUICtrlTab_GetItem', 'GUICtrlTab_GetItemCount',
+ 'GUICtrlTab_GetItemImage', 'GUICtrlTab_GetItemParam',
+ 'GUICtrlTab_GetItemRect', 'GUICtrlTab_GetItemRectEx',
+ 'GUICtrlTab_GetItemState', 'GUICtrlTab_GetItemText',
+ 'GUICtrlTab_GetRowCount', 'GUICtrlTab_GetToolTips',
+ 'GUICtrlTab_GetUnicodeFormat', 'GUICtrlTab_HighlightItem',
+ 'GUICtrlTab_HitTest', 'GUICtrlTab_InsertItem',
+ 'GUICtrlTab_RemoveImage', 'GUICtrlTab_SetCurFocus',
+ 'GUICtrlTab_SetCurSel', 'GUICtrlTab_SetExtendedStyle',
+ 'GUICtrlTab_SetImageList', 'GUICtrlTab_SetItem',
+ 'GUICtrlTab_SetItemImage', 'GUICtrlTab_SetItemParam',
+ 'GUICtrlTab_SetItemSize', 'GUICtrlTab_SetItemState',
+ 'GUICtrlTab_SetItemText', 'GUICtrlTab_SetMinTabWidth',
+ 'GUICtrlTab_SetPadding', 'GUICtrlTab_SetToolTips',
+ 'GUICtrlTab_SetUnicodeFormat', 'GUICtrlToolbar_AddBitmap',
+ 'GUICtrlToolbar_AddButton', 'GUICtrlToolbar_AddButtonSep',
+ 'GUICtrlToolbar_AddString', 'GUICtrlToolbar_ButtonCount',
+ 'GUICtrlToolbar_CheckButton', 'GUICtrlToolbar_ClickAccel',
+ 'GUICtrlToolbar_ClickButton', 'GUICtrlToolbar_ClickIndex',
+ 'GUICtrlToolbar_CommandToIndex', 'GUICtrlToolbar_Create',
+ 'GUICtrlToolbar_Customize', 'GUICtrlToolbar_DeleteButton',
+ 'GUICtrlToolbar_Destroy', 'GUICtrlToolbar_EnableButton',
+ 'GUICtrlToolbar_FindToolbar', 'GUICtrlToolbar_GetAnchorHighlight',
+ 'GUICtrlToolbar_GetBitmapFlags', 'GUICtrlToolbar_GetButtonBitmap',
+ 'GUICtrlToolbar_GetButtonInfo', 'GUICtrlToolbar_GetButtonInfoEx',
+ 'GUICtrlToolbar_GetButtonParam', 'GUICtrlToolbar_GetButtonRect',
+ 'GUICtrlToolbar_GetButtonRectEx', 'GUICtrlToolbar_GetButtonSize',
+ 'GUICtrlToolbar_GetButtonState', 'GUICtrlToolbar_GetButtonStyle',
+ 'GUICtrlToolbar_GetButtonText', 'GUICtrlToolbar_GetColorScheme',
+ 'GUICtrlToolbar_GetDisabledImageList',
+ 'GUICtrlToolbar_GetExtendedStyle', 'GUICtrlToolbar_GetHotImageList',
+ 'GUICtrlToolbar_GetHotItem', 'GUICtrlToolbar_GetImageList',
+ 'GUICtrlToolbar_GetInsertMark', 'GUICtrlToolbar_GetInsertMarkColor',
+ 'GUICtrlToolbar_GetMaxSize', 'GUICtrlToolbar_GetMetrics',
+ 'GUICtrlToolbar_GetPadding', 'GUICtrlToolbar_GetRows',
+ 'GUICtrlToolbar_GetString', 'GUICtrlToolbar_GetStyle',
+ 'GUICtrlToolbar_GetStyleAltDrag',
+ 'GUICtrlToolbar_GetStyleCustomErase', 'GUICtrlToolbar_GetStyleFlat',
+ 'GUICtrlToolbar_GetStyleList', 'GUICtrlToolbar_GetStyleRegisterDrop',
+ 'GUICtrlToolbar_GetStyleToolTips',
+ 'GUICtrlToolbar_GetStyleTransparent',
+ 'GUICtrlToolbar_GetStyleWrapable', 'GUICtrlToolbar_GetTextRows',
+ 'GUICtrlToolbar_GetToolTips', 'GUICtrlToolbar_GetUnicodeFormat',
+ 'GUICtrlToolbar_HideButton', 'GUICtrlToolbar_HighlightButton',
+ 'GUICtrlToolbar_HitTest', 'GUICtrlToolbar_IndexToCommand',
+ 'GUICtrlToolbar_InsertButton', 'GUICtrlToolbar_InsertMarkHitTest',
+ 'GUICtrlToolbar_IsButtonChecked', 'GUICtrlToolbar_IsButtonEnabled',
+ 'GUICtrlToolbar_IsButtonHidden',
+ 'GUICtrlToolbar_IsButtonHighlighted',
+ 'GUICtrlToolbar_IsButtonIndeterminate',
+ 'GUICtrlToolbar_IsButtonPressed', 'GUICtrlToolbar_LoadBitmap',
+ 'GUICtrlToolbar_LoadImages', 'GUICtrlToolbar_MapAccelerator',
+ 'GUICtrlToolbar_MoveButton', 'GUICtrlToolbar_PressButton',
+ 'GUICtrlToolbar_SetAnchorHighlight', 'GUICtrlToolbar_SetBitmapSize',
+ 'GUICtrlToolbar_SetButtonBitMap', 'GUICtrlToolbar_SetButtonInfo',
+ 'GUICtrlToolbar_SetButtonInfoEx', 'GUICtrlToolbar_SetButtonParam',
+ 'GUICtrlToolbar_SetButtonSize', 'GUICtrlToolbar_SetButtonState',
+ 'GUICtrlToolbar_SetButtonStyle', 'GUICtrlToolbar_SetButtonText',
+ 'GUICtrlToolbar_SetButtonWidth', 'GUICtrlToolbar_SetCmdID',
+ 'GUICtrlToolbar_SetColorScheme',
+ 'GUICtrlToolbar_SetDisabledImageList',
+ 'GUICtrlToolbar_SetDrawTextFlags', 'GUICtrlToolbar_SetExtendedStyle',
+ 'GUICtrlToolbar_SetHotImageList', 'GUICtrlToolbar_SetHotItem',
+ 'GUICtrlToolbar_SetImageList', 'GUICtrlToolbar_SetIndent',
+ 'GUICtrlToolbar_SetIndeterminate', 'GUICtrlToolbar_SetInsertMark',
+ 'GUICtrlToolbar_SetInsertMarkColor', 'GUICtrlToolbar_SetMaxTextRows',
+ 'GUICtrlToolbar_SetMetrics', 'GUICtrlToolbar_SetPadding',
+ 'GUICtrlToolbar_SetParent', 'GUICtrlToolbar_SetRows',
+ 'GUICtrlToolbar_SetStyle', 'GUICtrlToolbar_SetStyleAltDrag',
+ 'GUICtrlToolbar_SetStyleCustomErase', 'GUICtrlToolbar_SetStyleFlat',
+ 'GUICtrlToolbar_SetStyleList', 'GUICtrlToolbar_SetStyleRegisterDrop',
+ 'GUICtrlToolbar_SetStyleToolTips',
+ 'GUICtrlToolbar_SetStyleTransparent',
+ 'GUICtrlToolbar_SetStyleWrapable', 'GUICtrlToolbar_SetToolTips',
+ 'GUICtrlToolbar_SetUnicodeFormat', 'GUICtrlToolbar_SetWindowTheme',
+ 'GUICtrlTreeView_Add', 'GUICtrlTreeView_AddChild',
+ 'GUICtrlTreeView_AddChildFirst', 'GUICtrlTreeView_AddFirst',
+ 'GUICtrlTreeView_BeginUpdate', 'GUICtrlTreeView_ClickItem',
+ 'GUICtrlTreeView_Create', 'GUICtrlTreeView_CreateDragImage',
+ 'GUICtrlTreeView_CreateSolidBitMap', 'GUICtrlTreeView_Delete',
+ 'GUICtrlTreeView_DeleteAll', 'GUICtrlTreeView_DeleteChildren',
+ 'GUICtrlTreeView_Destroy', 'GUICtrlTreeView_DisplayRect',
+ 'GUICtrlTreeView_DisplayRectEx', 'GUICtrlTreeView_EditText',
+ 'GUICtrlTreeView_EndEdit', 'GUICtrlTreeView_EndUpdate',
+ 'GUICtrlTreeView_EnsureVisible', 'GUICtrlTreeView_Expand',
+ 'GUICtrlTreeView_ExpandedOnce', 'GUICtrlTreeView_FindItem',
+ 'GUICtrlTreeView_FindItemEx', 'GUICtrlTreeView_GetBkColor',
+ 'GUICtrlTreeView_GetBold', 'GUICtrlTreeView_GetChecked',
+ 'GUICtrlTreeView_GetChildCount', 'GUICtrlTreeView_GetChildren',
+ 'GUICtrlTreeView_GetCount', 'GUICtrlTreeView_GetCut',
+ 'GUICtrlTreeView_GetDropTarget', 'GUICtrlTreeView_GetEditControl',
+ 'GUICtrlTreeView_GetExpanded', 'GUICtrlTreeView_GetFirstChild',
+ 'GUICtrlTreeView_GetFirstItem', 'GUICtrlTreeView_GetFirstVisible',
+ 'GUICtrlTreeView_GetFocused', 'GUICtrlTreeView_GetHeight',
+ 'GUICtrlTreeView_GetImageIndex',
+ 'GUICtrlTreeView_GetImageListIconHandle',
+ 'GUICtrlTreeView_GetIndent', 'GUICtrlTreeView_GetInsertMarkColor',
+ 'GUICtrlTreeView_GetISearchString', 'GUICtrlTreeView_GetItemByIndex',
+ 'GUICtrlTreeView_GetItemHandle', 'GUICtrlTreeView_GetItemParam',
+ 'GUICtrlTreeView_GetLastChild', 'GUICtrlTreeView_GetLineColor',
+ 'GUICtrlTreeView_GetNext', 'GUICtrlTreeView_GetNextChild',
+ 'GUICtrlTreeView_GetNextSibling', 'GUICtrlTreeView_GetNextVisible',
+ 'GUICtrlTreeView_GetNormalImageList',
+ 'GUICtrlTreeView_GetParentHandle', 'GUICtrlTreeView_GetParentParam',
+ 'GUICtrlTreeView_GetPrev', 'GUICtrlTreeView_GetPrevChild',
+ 'GUICtrlTreeView_GetPrevSibling', 'GUICtrlTreeView_GetPrevVisible',
+ 'GUICtrlTreeView_GetScrollTime', 'GUICtrlTreeView_GetSelected',
+ 'GUICtrlTreeView_GetSelectedImageIndex',
+ 'GUICtrlTreeView_GetSelection', 'GUICtrlTreeView_GetSiblingCount',
+ 'GUICtrlTreeView_GetState', 'GUICtrlTreeView_GetStateImageIndex',
+ 'GUICtrlTreeView_GetStateImageList', 'GUICtrlTreeView_GetText',
+ 'GUICtrlTreeView_GetTextColor', 'GUICtrlTreeView_GetToolTips',
+ 'GUICtrlTreeView_GetTree', 'GUICtrlTreeView_GetUnicodeFormat',
+ 'GUICtrlTreeView_GetVisible', 'GUICtrlTreeView_GetVisibleCount',
+ 'GUICtrlTreeView_HitTest', 'GUICtrlTreeView_HitTestEx',
+ 'GUICtrlTreeView_HitTestItem', 'GUICtrlTreeView_Index',
+ 'GUICtrlTreeView_InsertItem', 'GUICtrlTreeView_IsFirstItem',
+ 'GUICtrlTreeView_IsParent', 'GUICtrlTreeView_Level',
+ 'GUICtrlTreeView_SelectItem', 'GUICtrlTreeView_SelectItemByIndex',
+ 'GUICtrlTreeView_SetBkColor', 'GUICtrlTreeView_SetBold',
+ 'GUICtrlTreeView_SetChecked', 'GUICtrlTreeView_SetCheckedByIndex',
+ 'GUICtrlTreeView_SetChildren', 'GUICtrlTreeView_SetCut',
+ 'GUICtrlTreeView_SetDropTarget', 'GUICtrlTreeView_SetFocused',
+ 'GUICtrlTreeView_SetHeight', 'GUICtrlTreeView_SetIcon',
+ 'GUICtrlTreeView_SetImageIndex', 'GUICtrlTreeView_SetIndent',
+ 'GUICtrlTreeView_SetInsertMark',
+ 'GUICtrlTreeView_SetInsertMarkColor',
+ 'GUICtrlTreeView_SetItemHeight', 'GUICtrlTreeView_SetItemParam',
+ 'GUICtrlTreeView_SetLineColor', 'GUICtrlTreeView_SetNormalImageList',
+ 'GUICtrlTreeView_SetScrollTime', 'GUICtrlTreeView_SetSelected',
+ 'GUICtrlTreeView_SetSelectedImageIndex', 'GUICtrlTreeView_SetState',
+ 'GUICtrlTreeView_SetStateImageIndex',
+ 'GUICtrlTreeView_SetStateImageList', 'GUICtrlTreeView_SetText',
+ 'GUICtrlTreeView_SetTextColor', 'GUICtrlTreeView_SetToolTips',
+ 'GUICtrlTreeView_SetUnicodeFormat', 'GUICtrlTreeView_Sort',
+ 'GUIImageList_Add', 'GUIImageList_AddBitmap', 'GUIImageList_AddIcon',
+ 'GUIImageList_AddMasked', 'GUIImageList_BeginDrag',
+ 'GUIImageList_Copy', 'GUIImageList_Create', 'GUIImageList_Destroy',
+ 'GUIImageList_DestroyIcon', 'GUIImageList_DragEnter',
+ 'GUIImageList_DragLeave', 'GUIImageList_DragMove',
+ 'GUIImageList_Draw', 'GUIImageList_DrawEx', 'GUIImageList_Duplicate',
+ 'GUIImageList_EndDrag', 'GUIImageList_GetBkColor',
+ 'GUIImageList_GetIcon', 'GUIImageList_GetIconHeight',
+ 'GUIImageList_GetIconSize', 'GUIImageList_GetIconSizeEx',
+ 'GUIImageList_GetIconWidth', 'GUIImageList_GetImageCount',
+ 'GUIImageList_GetImageInfoEx', 'GUIImageList_Remove',
+ 'GUIImageList_ReplaceIcon', 'GUIImageList_SetBkColor',
+ 'GUIImageList_SetIconSize', 'GUIImageList_SetImageCount',
+ 'GUIImageList_Swap', 'GUIScrollBars_EnableScrollBar',
+ 'GUIScrollBars_GetScrollBarInfoEx', 'GUIScrollBars_GetScrollBarRect',
+ 'GUIScrollBars_GetScrollBarRGState',
+ 'GUIScrollBars_GetScrollBarXYLineButton',
+ 'GUIScrollBars_GetScrollBarXYThumbBottom',
+ 'GUIScrollBars_GetScrollBarXYThumbTop',
+ 'GUIScrollBars_GetScrollInfo', 'GUIScrollBars_GetScrollInfoEx',
+ 'GUIScrollBars_GetScrollInfoMax', 'GUIScrollBars_GetScrollInfoMin',
+ 'GUIScrollBars_GetScrollInfoPage', 'GUIScrollBars_GetScrollInfoPos',
+ 'GUIScrollBars_GetScrollInfoTrackPos', 'GUIScrollBars_GetScrollPos',
+ 'GUIScrollBars_GetScrollRange', 'GUIScrollBars_Init',
+ 'GUIScrollBars_ScrollWindow', 'GUIScrollBars_SetScrollInfo',
+ 'GUIScrollBars_SetScrollInfoMax', 'GUIScrollBars_SetScrollInfoMin',
+ 'GUIScrollBars_SetScrollInfoPage', 'GUIScrollBars_SetScrollInfoPos',
+ 'GUIScrollBars_SetScrollRange', 'GUIScrollBars_ShowScrollBar',
+ 'GUIToolTip_Activate', 'GUIToolTip_AddTool', 'GUIToolTip_AdjustRect',
+ 'GUIToolTip_BitsToTTF', 'GUIToolTip_Create', 'GUIToolTip_Deactivate',
+ 'GUIToolTip_DelTool', 'GUIToolTip_Destroy', 'GUIToolTip_EnumTools',
+ 'GUIToolTip_GetBubbleHeight', 'GUIToolTip_GetBubbleSize',
+ 'GUIToolTip_GetBubbleWidth', 'GUIToolTip_GetCurrentTool',
+ 'GUIToolTip_GetDelayTime', 'GUIToolTip_GetMargin',
+ 'GUIToolTip_GetMarginEx', 'GUIToolTip_GetMaxTipWidth',
+ 'GUIToolTip_GetText', 'GUIToolTip_GetTipBkColor',
+ 'GUIToolTip_GetTipTextColor', 'GUIToolTip_GetTitleBitMap',
+ 'GUIToolTip_GetTitleText', 'GUIToolTip_GetToolCount',
+ 'GUIToolTip_GetToolInfo', 'GUIToolTip_HitTest',
+ 'GUIToolTip_NewToolRect', 'GUIToolTip_Pop', 'GUIToolTip_PopUp',
+ 'GUIToolTip_SetDelayTime', 'GUIToolTip_SetMargin',
+ 'GUIToolTip_SetMaxTipWidth', 'GUIToolTip_SetTipBkColor',
+ 'GUIToolTip_SetTipTextColor', 'GUIToolTip_SetTitle',
+ 'GUIToolTip_SetToolInfo', 'GUIToolTip_SetWindowTheme',
+ 'GUIToolTip_ToolExists', 'GUIToolTip_ToolToArray',
+ 'GUIToolTip_TrackActivate', 'GUIToolTip_TrackPosition',
+ 'GUIToolTip_Update', 'GUIToolTip_UpdateTipText', 'HexToString',
+ 'IEAction', 'IEAttach', 'IEBodyReadHTML', 'IEBodyReadText',
+ 'IEBodyWriteHTML', 'IECreate', 'IECreateEmbedded', 'IEDocGetObj',
+ 'IEDocInsertHTML', 'IEDocInsertText', 'IEDocReadHTML',
+ 'IEDocWriteHTML', 'IEErrorNotify', 'IEFormElementCheckBoxSelect',
+ 'IEFormElementGetCollection', 'IEFormElementGetObjByName',
+ 'IEFormElementGetValue', 'IEFormElementOptionSelect',
+ 'IEFormElementRadioSelect', 'IEFormElementSetValue',
+ 'IEFormGetCollection', 'IEFormGetObjByName', 'IEFormImageClick',
+ 'IEFormReset', 'IEFormSubmit', 'IEFrameGetCollection',
+ 'IEFrameGetObjByName', 'IEGetObjById', 'IEGetObjByName',
+ 'IEHeadInsertEventScript', 'IEImgClick', 'IEImgGetCollection',
+ 'IEIsFrameSet', 'IELinkClickByIndex', 'IELinkClickByText',
+ 'IELinkGetCollection', 'IELoadWait', 'IELoadWaitTimeout', 'IENavigate',
+ 'IEPropertyGet', 'IEPropertySet', 'IEQuit', 'IETableGetCollection',
+ 'IETableWriteToArray', 'IETagNameAllGetCollection',
+ 'IETagNameGetCollection', 'IE_Example', 'IE_Introduction',
+ 'IE_VersionInfo', 'INetExplorerCapable', 'INetGetSource', 'INetMail',
+ 'INetSmtpMail', 'IsPressed', 'MathCheckDiv', 'Max', 'MemGlobalAlloc',
+ 'MemGlobalFree', 'MemGlobalLock', 'MemGlobalSize', 'MemGlobalUnlock',
+ 'MemMoveMemory', 'MemVirtualAlloc', 'MemVirtualAllocEx',
+ 'MemVirtualFree', 'MemVirtualFreeEx', 'Min', 'MouseTrap',
+ 'NamedPipes_CallNamedPipe', 'NamedPipes_ConnectNamedPipe',
+ 'NamedPipes_CreateNamedPipe', 'NamedPipes_CreatePipe',
+ 'NamedPipes_DisconnectNamedPipe',
+ 'NamedPipes_GetNamedPipeHandleState', 'NamedPipes_GetNamedPipeInfo',
+ 'NamedPipes_PeekNamedPipe', 'NamedPipes_SetNamedPipeHandleState',
+ 'NamedPipes_TransactNamedPipe', 'NamedPipes_WaitNamedPipe',
+ 'Net_Share_ConnectionEnum', 'Net_Share_FileClose',
+ 'Net_Share_FileEnum', 'Net_Share_FileGetInfo', 'Net_Share_PermStr',
+ 'Net_Share_ResourceStr', 'Net_Share_SessionDel',
+ 'Net_Share_SessionEnum', 'Net_Share_SessionGetInfo',
+ 'Net_Share_ShareAdd', 'Net_Share_ShareCheck', 'Net_Share_ShareDel',
+ 'Net_Share_ShareEnum', 'Net_Share_ShareGetInfo',
+ 'Net_Share_ShareSetInfo', 'Net_Share_StatisticsGetSvr',
+ 'Net_Share_StatisticsGetWrk', 'Now', 'NowCalc', 'NowCalcDate',
+ 'NowDate', 'NowTime', 'PathFull', 'PathGetRelative', 'PathMake',
+ 'PathSplit', 'ProcessGetName', 'ProcessGetPriority', 'Radian',
+ 'ReplaceStringInFile', 'RunDos', 'ScreenCapture_Capture',
+ 'ScreenCapture_CaptureWnd', 'ScreenCapture_SaveImage',
+ 'ScreenCapture_SetBMPFormat', 'ScreenCapture_SetJPGQuality',
+ 'ScreenCapture_SetTIFColorDepth', 'ScreenCapture_SetTIFCompression',
+ 'Security__AdjustTokenPrivileges',
+ 'Security__CreateProcessWithToken', 'Security__DuplicateTokenEx',
+ 'Security__GetAccountSid', 'Security__GetLengthSid',
+ 'Security__GetTokenInformation', 'Security__ImpersonateSelf',
+ 'Security__IsValidSid', 'Security__LookupAccountName',
+ 'Security__LookupAccountSid', 'Security__LookupPrivilegeValue',
+ 'Security__OpenProcessToken', 'Security__OpenThreadToken',
+ 'Security__OpenThreadTokenEx', 'Security__SetPrivilege',
+ 'Security__SetTokenInformation', 'Security__SidToStringSid',
+ 'Security__SidTypeStr', 'Security__StringSidToSid', 'SendMessage',
+ 'SendMessageA', 'SetDate', 'SetTime', 'Singleton', 'SoundClose',
+ 'SoundLength', 'SoundOpen', 'SoundPause', 'SoundPlay', 'SoundPos',
+ 'SoundResume', 'SoundSeek', 'SoundStatus', 'SoundStop',
+ 'SQLite_Changes', 'SQLite_Close', 'SQLite_Display2DResult',
+ 'SQLite_Encode', 'SQLite_ErrCode', 'SQLite_ErrMsg', 'SQLite_Escape',
+ 'SQLite_Exec', 'SQLite_FastEncode', 'SQLite_FastEscape',
+ 'SQLite_FetchData', 'SQLite_FetchNames', 'SQLite_GetTable',
+ 'SQLite_GetTable2d', 'SQLite_LastInsertRowID', 'SQLite_LibVersion',
+ 'SQLite_Open', 'SQLite_Query', 'SQLite_QueryFinalize',
+ 'SQLite_QueryReset', 'SQLite_QuerySingleRow', 'SQLite_SafeMode',
+ 'SQLite_SetTimeout', 'SQLite_Shutdown', 'SQLite_SQLiteExe',
+ 'SQLite_Startup', 'SQLite_TotalChanges', 'StringBetween',
+ 'StringExplode', 'StringInsert', 'StringProper', 'StringRepeat',
+ 'StringTitleCase', 'StringToHex', 'TCPIpToName', 'TempFile',
+ 'TicksToTime', 'Timer_Diff', 'Timer_GetIdleTime', 'Timer_GetTimerID',
+ 'Timer_Init', 'Timer_KillAllTimers', 'Timer_KillTimer',
+ 'Timer_SetTimer', 'TimeToTicks', 'VersionCompare', 'viClose',
+ 'viExecCommand', 'viFindGpib', 'viGpibBusReset', 'viGTL',
+ 'viInteractiveControl', 'viOpen', 'viSetAttribute', 'viSetTimeout',
+ 'WeekNumberISO', 'WinAPI_AbortPath', 'WinAPI_ActivateKeyboardLayout',
+ 'WinAPI_AddClipboardFormatListener', 'WinAPI_AddFontMemResourceEx',
+ 'WinAPI_AddFontResourceEx', 'WinAPI_AddIconOverlay',
+ 'WinAPI_AddIconTransparency', 'WinAPI_AddMRUString',
+ 'WinAPI_AdjustBitmap', 'WinAPI_AdjustTokenPrivileges',
+ 'WinAPI_AdjustWindowRectEx', 'WinAPI_AlphaBlend', 'WinAPI_AngleArc',
+ 'WinAPI_AnimateWindow', 'WinAPI_Arc', 'WinAPI_ArcTo',
+ 'WinAPI_ArrayToStruct', 'WinAPI_AssignProcessToJobObject',
+ 'WinAPI_AssocGetPerceivedType', 'WinAPI_AssocQueryString',
+ 'WinAPI_AttachConsole', 'WinAPI_AttachThreadInput',
+ 'WinAPI_BackupRead', 'WinAPI_BackupReadAbort', 'WinAPI_BackupSeek',
+ 'WinAPI_BackupWrite', 'WinAPI_BackupWriteAbort', 'WinAPI_Beep',
+ 'WinAPI_BeginBufferedPaint', 'WinAPI_BeginDeferWindowPos',
+ 'WinAPI_BeginPaint', 'WinAPI_BeginPath', 'WinAPI_BeginUpdateResource',
+ 'WinAPI_BitBlt', 'WinAPI_BringWindowToTop',
+ 'WinAPI_BroadcastSystemMessage', 'WinAPI_BrowseForFolderDlg',
+ 'WinAPI_BufferedPaintClear', 'WinAPI_BufferedPaintInit',
+ 'WinAPI_BufferedPaintSetAlpha', 'WinAPI_BufferedPaintUnInit',
+ 'WinAPI_CallNextHookEx', 'WinAPI_CallWindowProc',
+ 'WinAPI_CallWindowProcW', 'WinAPI_CascadeWindows',
+ 'WinAPI_ChangeWindowMessageFilterEx', 'WinAPI_CharToOem',
+ 'WinAPI_ChildWindowFromPointEx', 'WinAPI_ClientToScreen',
+ 'WinAPI_ClipCursor', 'WinAPI_CloseDesktop', 'WinAPI_CloseEnhMetaFile',
+ 'WinAPI_CloseFigure', 'WinAPI_CloseHandle', 'WinAPI_CloseThemeData',
+ 'WinAPI_CloseWindow', 'WinAPI_CloseWindowStation',
+ 'WinAPI_CLSIDFromProgID', 'WinAPI_CoInitialize',
+ 'WinAPI_ColorAdjustLuma', 'WinAPI_ColorHLSToRGB',
+ 'WinAPI_ColorRGBToHLS', 'WinAPI_CombineRgn',
+ 'WinAPI_CombineTransform', 'WinAPI_CommandLineToArgv',
+ 'WinAPI_CommDlgExtendedError', 'WinAPI_CommDlgExtendedErrorEx',
+ 'WinAPI_CompareString', 'WinAPI_CompressBitmapBits',
+ 'WinAPI_CompressBuffer', 'WinAPI_ComputeCrc32',
+ 'WinAPI_ConfirmCredentials', 'WinAPI_CopyBitmap', 'WinAPI_CopyCursor',
+ 'WinAPI_CopyEnhMetaFile', 'WinAPI_CopyFileEx', 'WinAPI_CopyIcon',
+ 'WinAPI_CopyImage', 'WinAPI_CopyRect', 'WinAPI_CopyStruct',
+ 'WinAPI_CoTaskMemAlloc', 'WinAPI_CoTaskMemFree',
+ 'WinAPI_CoTaskMemRealloc', 'WinAPI_CoUninitialize',
+ 'WinAPI_Create32BitHBITMAP', 'WinAPI_Create32BitHICON',
+ 'WinAPI_CreateANDBitmap', 'WinAPI_CreateBitmap',
+ 'WinAPI_CreateBitmapIndirect', 'WinAPI_CreateBrushIndirect',
+ 'WinAPI_CreateBuffer', 'WinAPI_CreateBufferFromStruct',
+ 'WinAPI_CreateCaret', 'WinAPI_CreateColorAdjustment',
+ 'WinAPI_CreateCompatibleBitmap', 'WinAPI_CreateCompatibleBitmapEx',
+ 'WinAPI_CreateCompatibleDC', 'WinAPI_CreateDesktop',
+ 'WinAPI_CreateDIB', 'WinAPI_CreateDIBColorTable',
+ 'WinAPI_CreateDIBitmap', 'WinAPI_CreateDIBSection',
+ 'WinAPI_CreateDirectory', 'WinAPI_CreateDirectoryEx',
+ 'WinAPI_CreateEllipticRgn', 'WinAPI_CreateEmptyIcon',
+ 'WinAPI_CreateEnhMetaFile', 'WinAPI_CreateEvent', 'WinAPI_CreateFile',
+ 'WinAPI_CreateFileEx', 'WinAPI_CreateFileMapping',
+ 'WinAPI_CreateFont', 'WinAPI_CreateFontEx',
+ 'WinAPI_CreateFontIndirect', 'WinAPI_CreateGUID',
+ 'WinAPI_CreateHardLink', 'WinAPI_CreateIcon',
+ 'WinAPI_CreateIconFromResourceEx', 'WinAPI_CreateIconIndirect',
+ 'WinAPI_CreateJobObject', 'WinAPI_CreateMargins',
+ 'WinAPI_CreateMRUList', 'WinAPI_CreateMutex', 'WinAPI_CreateNullRgn',
+ 'WinAPI_CreateNumberFormatInfo', 'WinAPI_CreateObjectID',
+ 'WinAPI_CreatePen', 'WinAPI_CreatePoint', 'WinAPI_CreatePolygonRgn',
+ 'WinAPI_CreateProcess', 'WinAPI_CreateProcessWithToken',
+ 'WinAPI_CreateRect', 'WinAPI_CreateRectEx', 'WinAPI_CreateRectRgn',
+ 'WinAPI_CreateRectRgnIndirect', 'WinAPI_CreateRoundRectRgn',
+ 'WinAPI_CreateSemaphore', 'WinAPI_CreateSize',
+ 'WinAPI_CreateSolidBitmap', 'WinAPI_CreateSolidBrush',
+ 'WinAPI_CreateStreamOnHGlobal', 'WinAPI_CreateString',
+ 'WinAPI_CreateSymbolicLink', 'WinAPI_CreateTransform',
+ 'WinAPI_CreateWindowEx', 'WinAPI_CreateWindowStation',
+ 'WinAPI_DecompressBuffer', 'WinAPI_DecryptFile',
+ 'WinAPI_DeferWindowPos', 'WinAPI_DefineDosDevice',
+ 'WinAPI_DefRawInputProc', 'WinAPI_DefSubclassProc',
+ 'WinAPI_DefWindowProc', 'WinAPI_DefWindowProcW', 'WinAPI_DeleteDC',
+ 'WinAPI_DeleteEnhMetaFile', 'WinAPI_DeleteFile',
+ 'WinAPI_DeleteObject', 'WinAPI_DeleteObjectID',
+ 'WinAPI_DeleteVolumeMountPoint', 'WinAPI_DeregisterShellHookWindow',
+ 'WinAPI_DestroyCaret', 'WinAPI_DestroyCursor', 'WinAPI_DestroyIcon',
+ 'WinAPI_DestroyWindow', 'WinAPI_DeviceIoControl',
+ 'WinAPI_DisplayStruct', 'WinAPI_DllGetVersion', 'WinAPI_DllInstall',
+ 'WinAPI_DllUninstall', 'WinAPI_DPtoLP', 'WinAPI_DragAcceptFiles',
+ 'WinAPI_DragFinish', 'WinAPI_DragQueryFileEx',
+ 'WinAPI_DragQueryPoint', 'WinAPI_DrawAnimatedRects',
+ 'WinAPI_DrawBitmap', 'WinAPI_DrawEdge', 'WinAPI_DrawFocusRect',
+ 'WinAPI_DrawFrameControl', 'WinAPI_DrawIcon', 'WinAPI_DrawIconEx',
+ 'WinAPI_DrawLine', 'WinAPI_DrawShadowText', 'WinAPI_DrawText',
+ 'WinAPI_DrawThemeBackground', 'WinAPI_DrawThemeEdge',
+ 'WinAPI_DrawThemeIcon', 'WinAPI_DrawThemeParentBackground',
+ 'WinAPI_DrawThemeText', 'WinAPI_DrawThemeTextEx',
+ 'WinAPI_DuplicateEncryptionInfoFile', 'WinAPI_DuplicateHandle',
+ 'WinAPI_DuplicateTokenEx', 'WinAPI_DwmDefWindowProc',
+ 'WinAPI_DwmEnableBlurBehindWindow', 'WinAPI_DwmEnableComposition',
+ 'WinAPI_DwmExtendFrameIntoClientArea',
+ 'WinAPI_DwmGetColorizationColor',
+ 'WinAPI_DwmGetColorizationParameters',
+ 'WinAPI_DwmGetWindowAttribute', 'WinAPI_DwmInvalidateIconicBitmaps',
+ 'WinAPI_DwmIsCompositionEnabled',
+ 'WinAPI_DwmQueryThumbnailSourceSize', 'WinAPI_DwmRegisterThumbnail',
+ 'WinAPI_DwmSetColorizationParameters',
+ 'WinAPI_DwmSetIconicLivePreviewBitmap',
+ 'WinAPI_DwmSetIconicThumbnail', 'WinAPI_DwmSetWindowAttribute',
+ 'WinAPI_DwmUnregisterThumbnail',
+ 'WinAPI_DwmUpdateThumbnailProperties', 'WinAPI_DWordToFloat',
+ 'WinAPI_DWordToInt', 'WinAPI_EjectMedia', 'WinAPI_Ellipse',
+ 'WinAPI_EmptyWorkingSet', 'WinAPI_EnableWindow', 'WinAPI_EncryptFile',
+ 'WinAPI_EncryptionDisable', 'WinAPI_EndBufferedPaint',
+ 'WinAPI_EndDeferWindowPos', 'WinAPI_EndPaint', 'WinAPI_EndPath',
+ 'WinAPI_EndUpdateResource', 'WinAPI_EnumChildProcess',
+ 'WinAPI_EnumChildWindows', 'WinAPI_EnumDesktops',
+ 'WinAPI_EnumDesktopWindows', 'WinAPI_EnumDeviceDrivers',
+ 'WinAPI_EnumDisplayDevices', 'WinAPI_EnumDisplayMonitors',
+ 'WinAPI_EnumDisplaySettings', 'WinAPI_EnumDllProc',
+ 'WinAPI_EnumFiles', 'WinAPI_EnumFileStreams',
+ 'WinAPI_EnumFontFamilies', 'WinAPI_EnumHardLinks',
+ 'WinAPI_EnumMRUList', 'WinAPI_EnumPageFiles',
+ 'WinAPI_EnumProcessHandles', 'WinAPI_EnumProcessModules',
+ 'WinAPI_EnumProcessThreads', 'WinAPI_EnumProcessWindows',
+ 'WinAPI_EnumRawInputDevices', 'WinAPI_EnumResourceLanguages',
+ 'WinAPI_EnumResourceNames', 'WinAPI_EnumResourceTypes',
+ 'WinAPI_EnumSystemGeoID', 'WinAPI_EnumSystemLocales',
+ 'WinAPI_EnumUILanguages', 'WinAPI_EnumWindows',
+ 'WinAPI_EnumWindowsPopup', 'WinAPI_EnumWindowStations',
+ 'WinAPI_EnumWindowsTop', 'WinAPI_EqualMemory', 'WinAPI_EqualRect',
+ 'WinAPI_EqualRgn', 'WinAPI_ExcludeClipRect',
+ 'WinAPI_ExpandEnvironmentStrings', 'WinAPI_ExtCreatePen',
+ 'WinAPI_ExtCreateRegion', 'WinAPI_ExtFloodFill', 'WinAPI_ExtractIcon',
+ 'WinAPI_ExtractIconEx', 'WinAPI_ExtSelectClipRgn',
+ 'WinAPI_FatalAppExit', 'WinAPI_FatalExit',
+ 'WinAPI_FileEncryptionStatus', 'WinAPI_FileExists',
+ 'WinAPI_FileIconInit', 'WinAPI_FileInUse', 'WinAPI_FillMemory',
+ 'WinAPI_FillPath', 'WinAPI_FillRect', 'WinAPI_FillRgn',
+ 'WinAPI_FindClose', 'WinAPI_FindCloseChangeNotification',
+ 'WinAPI_FindExecutable', 'WinAPI_FindFirstChangeNotification',
+ 'WinAPI_FindFirstFile', 'WinAPI_FindFirstFileName',
+ 'WinAPI_FindFirstStream', 'WinAPI_FindNextChangeNotification',
+ 'WinAPI_FindNextFile', 'WinAPI_FindNextFileName',
+ 'WinAPI_FindNextStream', 'WinAPI_FindResource',
+ 'WinAPI_FindResourceEx', 'WinAPI_FindTextDlg', 'WinAPI_FindWindow',
+ 'WinAPI_FlashWindow', 'WinAPI_FlashWindowEx', 'WinAPI_FlattenPath',
+ 'WinAPI_FloatToDWord', 'WinAPI_FloatToInt', 'WinAPI_FlushFileBuffers',
+ 'WinAPI_FlushFRBuffer', 'WinAPI_FlushViewOfFile',
+ 'WinAPI_FormatDriveDlg', 'WinAPI_FormatMessage', 'WinAPI_FrameRect',
+ 'WinAPI_FrameRgn', 'WinAPI_FreeLibrary', 'WinAPI_FreeMemory',
+ 'WinAPI_FreeMRUList', 'WinAPI_FreeResource', 'WinAPI_GdiComment',
+ 'WinAPI_GetActiveWindow', 'WinAPI_GetAllUsersProfileDirectory',
+ 'WinAPI_GetAncestor', 'WinAPI_GetApplicationRestartSettings',
+ 'WinAPI_GetArcDirection', 'WinAPI_GetAsyncKeyState',
+ 'WinAPI_GetBinaryType', 'WinAPI_GetBitmapBits',
+ 'WinAPI_GetBitmapDimension', 'WinAPI_GetBitmapDimensionEx',
+ 'WinAPI_GetBkColor', 'WinAPI_GetBkMode', 'WinAPI_GetBoundsRect',
+ 'WinAPI_GetBrushOrg', 'WinAPI_GetBufferedPaintBits',
+ 'WinAPI_GetBufferedPaintDC', 'WinAPI_GetBufferedPaintTargetDC',
+ 'WinAPI_GetBufferedPaintTargetRect', 'WinAPI_GetBValue',
+ 'WinAPI_GetCaretBlinkTime', 'WinAPI_GetCaretPos', 'WinAPI_GetCDType',
+ 'WinAPI_GetClassInfoEx', 'WinAPI_GetClassLongEx',
+ 'WinAPI_GetClassName', 'WinAPI_GetClientHeight',
+ 'WinAPI_GetClientRect', 'WinAPI_GetClientWidth',
+ 'WinAPI_GetClipboardSequenceNumber', 'WinAPI_GetClipBox',
+ 'WinAPI_GetClipCursor', 'WinAPI_GetClipRgn',
+ 'WinAPI_GetColorAdjustment', 'WinAPI_GetCompressedFileSize',
+ 'WinAPI_GetCompression', 'WinAPI_GetConnectedDlg',
+ 'WinAPI_GetCurrentDirectory', 'WinAPI_GetCurrentHwProfile',
+ 'WinAPI_GetCurrentObject', 'WinAPI_GetCurrentPosition',
+ 'WinAPI_GetCurrentProcess',
+ 'WinAPI_GetCurrentProcessExplicitAppUserModelID',
+ 'WinAPI_GetCurrentProcessID', 'WinAPI_GetCurrentThemeName',
+ 'WinAPI_GetCurrentThread', 'WinAPI_GetCurrentThreadId',
+ 'WinAPI_GetCursor', 'WinAPI_GetCursorInfo', 'WinAPI_GetDateFormat',
+ 'WinAPI_GetDC', 'WinAPI_GetDCEx', 'WinAPI_GetDefaultPrinter',
+ 'WinAPI_GetDefaultUserProfileDirectory', 'WinAPI_GetDesktopWindow',
+ 'WinAPI_GetDeviceCaps', 'WinAPI_GetDeviceDriverBaseName',
+ 'WinAPI_GetDeviceDriverFileName', 'WinAPI_GetDeviceGammaRamp',
+ 'WinAPI_GetDIBColorTable', 'WinAPI_GetDIBits',
+ 'WinAPI_GetDiskFreeSpaceEx', 'WinAPI_GetDlgCtrlID',
+ 'WinAPI_GetDlgItem', 'WinAPI_GetDllDirectory',
+ 'WinAPI_GetDriveBusType', 'WinAPI_GetDriveGeometryEx',
+ 'WinAPI_GetDriveNumber', 'WinAPI_GetDriveType',
+ 'WinAPI_GetDurationFormat', 'WinAPI_GetEffectiveClientRect',
+ 'WinAPI_GetEnhMetaFile', 'WinAPI_GetEnhMetaFileBits',
+ 'WinAPI_GetEnhMetaFileDescription', 'WinAPI_GetEnhMetaFileDimension',
+ 'WinAPI_GetEnhMetaFileHeader', 'WinAPI_GetErrorMessage',
+ 'WinAPI_GetErrorMode', 'WinAPI_GetExitCodeProcess',
+ 'WinAPI_GetExtended', 'WinAPI_GetFileAttributes', 'WinAPI_GetFileID',
+ 'WinAPI_GetFileInformationByHandle',
+ 'WinAPI_GetFileInformationByHandleEx', 'WinAPI_GetFilePointerEx',
+ 'WinAPI_GetFileSizeEx', 'WinAPI_GetFileSizeOnDisk',
+ 'WinAPI_GetFileTitle', 'WinAPI_GetFileType',
+ 'WinAPI_GetFileVersionInfo', 'WinAPI_GetFinalPathNameByHandle',
+ 'WinAPI_GetFinalPathNameByHandleEx', 'WinAPI_GetFocus',
+ 'WinAPI_GetFontMemoryResourceInfo', 'WinAPI_GetFontName',
+ 'WinAPI_GetFontResourceInfo', 'WinAPI_GetForegroundWindow',
+ 'WinAPI_GetFRBuffer', 'WinAPI_GetFullPathName', 'WinAPI_GetGeoInfo',
+ 'WinAPI_GetGlyphOutline', 'WinAPI_GetGraphicsMode',
+ 'WinAPI_GetGuiResources', 'WinAPI_GetGUIThreadInfo',
+ 'WinAPI_GetGValue', 'WinAPI_GetHandleInformation',
+ 'WinAPI_GetHGlobalFromStream', 'WinAPI_GetIconDimension',
+ 'WinAPI_GetIconInfo', 'WinAPI_GetIconInfoEx', 'WinAPI_GetIdleTime',
+ 'WinAPI_GetKeyboardLayout', 'WinAPI_GetKeyboardLayoutList',
+ 'WinAPI_GetKeyboardState', 'WinAPI_GetKeyboardType',
+ 'WinAPI_GetKeyNameText', 'WinAPI_GetKeyState',
+ 'WinAPI_GetLastActivePopup', 'WinAPI_GetLastError',
+ 'WinAPI_GetLastErrorMessage', 'WinAPI_GetLayeredWindowAttributes',
+ 'WinAPI_GetLocaleInfo', 'WinAPI_GetLogicalDrives',
+ 'WinAPI_GetMapMode', 'WinAPI_GetMemorySize',
+ 'WinAPI_GetMessageExtraInfo', 'WinAPI_GetModuleFileNameEx',
+ 'WinAPI_GetModuleHandle', 'WinAPI_GetModuleHandleEx',
+ 'WinAPI_GetModuleInformation', 'WinAPI_GetMonitorInfo',
+ 'WinAPI_GetMousePos', 'WinAPI_GetMousePosX', 'WinAPI_GetMousePosY',
+ 'WinAPI_GetMUILanguage', 'WinAPI_GetNumberFormat', 'WinAPI_GetObject',
+ 'WinAPI_GetObjectID', 'WinAPI_GetObjectInfoByHandle',
+ 'WinAPI_GetObjectNameByHandle', 'WinAPI_GetObjectType',
+ 'WinAPI_GetOpenFileName', 'WinAPI_GetOutlineTextMetrics',
+ 'WinAPI_GetOverlappedResult', 'WinAPI_GetParent',
+ 'WinAPI_GetParentProcess', 'WinAPI_GetPerformanceInfo',
+ 'WinAPI_GetPEType', 'WinAPI_GetPhysicallyInstalledSystemMemory',
+ 'WinAPI_GetPixel', 'WinAPI_GetPolyFillMode', 'WinAPI_GetPosFromRect',
+ 'WinAPI_GetPriorityClass', 'WinAPI_GetProcAddress',
+ 'WinAPI_GetProcessAffinityMask', 'WinAPI_GetProcessCommandLine',
+ 'WinAPI_GetProcessFileName', 'WinAPI_GetProcessHandleCount',
+ 'WinAPI_GetProcessID', 'WinAPI_GetProcessIoCounters',
+ 'WinAPI_GetProcessMemoryInfo', 'WinAPI_GetProcessName',
+ 'WinAPI_GetProcessShutdownParameters', 'WinAPI_GetProcessTimes',
+ 'WinAPI_GetProcessUser', 'WinAPI_GetProcessWindowStation',
+ 'WinAPI_GetProcessWorkingDirectory', 'WinAPI_GetProfilesDirectory',
+ 'WinAPI_GetPwrCapabilities', 'WinAPI_GetRawInputBuffer',
+ 'WinAPI_GetRawInputBufferLength', 'WinAPI_GetRawInputData',
+ 'WinAPI_GetRawInputDeviceInfo', 'WinAPI_GetRegionData',
+ 'WinAPI_GetRegisteredRawInputDevices',
+ 'WinAPI_GetRegKeyNameByHandle', 'WinAPI_GetRgnBox', 'WinAPI_GetROP2',
+ 'WinAPI_GetRValue', 'WinAPI_GetSaveFileName', 'WinAPI_GetShellWindow',
+ 'WinAPI_GetStartupInfo', 'WinAPI_GetStdHandle',
+ 'WinAPI_GetStockObject', 'WinAPI_GetStretchBltMode',
+ 'WinAPI_GetString', 'WinAPI_GetSysColor', 'WinAPI_GetSysColorBrush',
+ 'WinAPI_GetSystemDefaultLangID', 'WinAPI_GetSystemDefaultLCID',
+ 'WinAPI_GetSystemDefaultUILanguage', 'WinAPI_GetSystemDEPPolicy',
+ 'WinAPI_GetSystemInfo', 'WinAPI_GetSystemMetrics',
+ 'WinAPI_GetSystemPowerStatus', 'WinAPI_GetSystemTimes',
+ 'WinAPI_GetSystemWow64Directory', 'WinAPI_GetTabbedTextExtent',
+ 'WinAPI_GetTempFileName', 'WinAPI_GetTextAlign',
+ 'WinAPI_GetTextCharacterExtra', 'WinAPI_GetTextColor',
+ 'WinAPI_GetTextExtentPoint32', 'WinAPI_GetTextFace',
+ 'WinAPI_GetTextMetrics', 'WinAPI_GetThemeAppProperties',
+ 'WinAPI_GetThemeBackgroundContentRect',
+ 'WinAPI_GetThemeBackgroundExtent', 'WinAPI_GetThemeBackgroundRegion',
+ 'WinAPI_GetThemeBitmap', 'WinAPI_GetThemeBool',
+ 'WinAPI_GetThemeColor', 'WinAPI_GetThemeDocumentationProperty',
+ 'WinAPI_GetThemeEnumValue', 'WinAPI_GetThemeFilename',
+ 'WinAPI_GetThemeFont', 'WinAPI_GetThemeInt', 'WinAPI_GetThemeMargins',
+ 'WinAPI_GetThemeMetric', 'WinAPI_GetThemePartSize',
+ 'WinAPI_GetThemePosition', 'WinAPI_GetThemePropertyOrigin',
+ 'WinAPI_GetThemeRect', 'WinAPI_GetThemeString',
+ 'WinAPI_GetThemeSysBool', 'WinAPI_GetThemeSysColor',
+ 'WinAPI_GetThemeSysColorBrush', 'WinAPI_GetThemeSysFont',
+ 'WinAPI_GetThemeSysInt', 'WinAPI_GetThemeSysSize',
+ 'WinAPI_GetThemeSysString', 'WinAPI_GetThemeTextExtent',
+ 'WinAPI_GetThemeTextMetrics', 'WinAPI_GetThemeTransitionDuration',
+ 'WinAPI_GetThreadDesktop', 'WinAPI_GetThreadErrorMode',
+ 'WinAPI_GetThreadLocale', 'WinAPI_GetThreadUILanguage',
+ 'WinAPI_GetTickCount', 'WinAPI_GetTickCount64',
+ 'WinAPI_GetTimeFormat', 'WinAPI_GetTopWindow',
+ 'WinAPI_GetUDFColorMode', 'WinAPI_GetUpdateRect',
+ 'WinAPI_GetUpdateRgn', 'WinAPI_GetUserDefaultLangID',
+ 'WinAPI_GetUserDefaultLCID', 'WinAPI_GetUserDefaultUILanguage',
+ 'WinAPI_GetUserGeoID', 'WinAPI_GetUserObjectInformation',
+ 'WinAPI_GetVersion', 'WinAPI_GetVersionEx',
+ 'WinAPI_GetVolumeInformation', 'WinAPI_GetVolumeInformationByHandle',
+ 'WinAPI_GetVolumeNameForVolumeMountPoint', 'WinAPI_GetWindow',
+ 'WinAPI_GetWindowDC', 'WinAPI_GetWindowDisplayAffinity',
+ 'WinAPI_GetWindowExt', 'WinAPI_GetWindowFileName',
+ 'WinAPI_GetWindowHeight', 'WinAPI_GetWindowInfo',
+ 'WinAPI_GetWindowLong', 'WinAPI_GetWindowOrg',
+ 'WinAPI_GetWindowPlacement', 'WinAPI_GetWindowRect',
+ 'WinAPI_GetWindowRgn', 'WinAPI_GetWindowRgnBox',
+ 'WinAPI_GetWindowSubclass', 'WinAPI_GetWindowText',
+ 'WinAPI_GetWindowTheme', 'WinAPI_GetWindowThreadProcessId',
+ 'WinAPI_GetWindowWidth', 'WinAPI_GetWorkArea',
+ 'WinAPI_GetWorldTransform', 'WinAPI_GetXYFromPoint',
+ 'WinAPI_GlobalMemoryStatus', 'WinAPI_GradientFill',
+ 'WinAPI_GUIDFromString', 'WinAPI_GUIDFromStringEx', 'WinAPI_HashData',
+ 'WinAPI_HashString', 'WinAPI_HiByte', 'WinAPI_HideCaret',
+ 'WinAPI_HiDWord', 'WinAPI_HiWord', 'WinAPI_InflateRect',
+ 'WinAPI_InitMUILanguage', 'WinAPI_InProcess',
+ 'WinAPI_IntersectClipRect', 'WinAPI_IntersectRect',
+ 'WinAPI_IntToDWord', 'WinAPI_IntToFloat', 'WinAPI_InvalidateRect',
+ 'WinAPI_InvalidateRgn', 'WinAPI_InvertANDBitmap',
+ 'WinAPI_InvertColor', 'WinAPI_InvertRect', 'WinAPI_InvertRgn',
+ 'WinAPI_IOCTL', 'WinAPI_IsAlphaBitmap', 'WinAPI_IsBadCodePtr',
+ 'WinAPI_IsBadReadPtr', 'WinAPI_IsBadStringPtr',
+ 'WinAPI_IsBadWritePtr', 'WinAPI_IsChild', 'WinAPI_IsClassName',
+ 'WinAPI_IsDoorOpen', 'WinAPI_IsElevated', 'WinAPI_IsHungAppWindow',
+ 'WinAPI_IsIconic', 'WinAPI_IsInternetConnected',
+ 'WinAPI_IsLoadKBLayout', 'WinAPI_IsMemory',
+ 'WinAPI_IsNameInExpression', 'WinAPI_IsNetworkAlive',
+ 'WinAPI_IsPathShared', 'WinAPI_IsProcessInJob',
+ 'WinAPI_IsProcessorFeaturePresent', 'WinAPI_IsRectEmpty',
+ 'WinAPI_IsThemeActive',
+ 'WinAPI_IsThemeBackgroundPartiallyTransparent',
+ 'WinAPI_IsThemePartDefined', 'WinAPI_IsValidLocale',
+ 'WinAPI_IsWindow', 'WinAPI_IsWindowEnabled', 'WinAPI_IsWindowUnicode',
+ 'WinAPI_IsWindowVisible', 'WinAPI_IsWow64Process',
+ 'WinAPI_IsWritable', 'WinAPI_IsZoomed', 'WinAPI_Keybd_Event',
+ 'WinAPI_KillTimer', 'WinAPI_LineDDA', 'WinAPI_LineTo',
+ 'WinAPI_LoadBitmap', 'WinAPI_LoadCursor', 'WinAPI_LoadCursorFromFile',
+ 'WinAPI_LoadIcon', 'WinAPI_LoadIconMetric',
+ 'WinAPI_LoadIconWithScaleDown', 'WinAPI_LoadImage',
+ 'WinAPI_LoadIndirectString', 'WinAPI_LoadKeyboardLayout',
+ 'WinAPI_LoadLibrary', 'WinAPI_LoadLibraryEx', 'WinAPI_LoadMedia',
+ 'WinAPI_LoadResource', 'WinAPI_LoadShell32Icon', 'WinAPI_LoadString',
+ 'WinAPI_LoadStringEx', 'WinAPI_LoByte', 'WinAPI_LocalFree',
+ 'WinAPI_LockDevice', 'WinAPI_LockFile', 'WinAPI_LockResource',
+ 'WinAPI_LockWindowUpdate', 'WinAPI_LockWorkStation', 'WinAPI_LoDWord',
+ 'WinAPI_LongMid', 'WinAPI_LookupIconIdFromDirectoryEx',
+ 'WinAPI_LoWord', 'WinAPI_LPtoDP', 'WinAPI_MAKELANGID',
+ 'WinAPI_MAKELCID', 'WinAPI_MakeLong', 'WinAPI_MakeQWord',
+ 'WinAPI_MakeWord', 'WinAPI_MapViewOfFile', 'WinAPI_MapVirtualKey',
+ 'WinAPI_MaskBlt', 'WinAPI_MessageBeep', 'WinAPI_MessageBoxCheck',
+ 'WinAPI_MessageBoxIndirect', 'WinAPI_MirrorIcon',
+ 'WinAPI_ModifyWorldTransform', 'WinAPI_MonitorFromPoint',
+ 'WinAPI_MonitorFromRect', 'WinAPI_MonitorFromWindow',
+ 'WinAPI_Mouse_Event', 'WinAPI_MoveFileEx', 'WinAPI_MoveMemory',
+ 'WinAPI_MoveTo', 'WinAPI_MoveToEx', 'WinAPI_MoveWindow',
+ 'WinAPI_MsgBox', 'WinAPI_MulDiv', 'WinAPI_MultiByteToWideChar',
+ 'WinAPI_MultiByteToWideCharEx', 'WinAPI_NtStatusToDosError',
+ 'WinAPI_OemToChar', 'WinAPI_OffsetClipRgn', 'WinAPI_OffsetPoints',
+ 'WinAPI_OffsetRect', 'WinAPI_OffsetRgn', 'WinAPI_OffsetWindowOrg',
+ 'WinAPI_OpenDesktop', 'WinAPI_OpenFileById', 'WinAPI_OpenFileDlg',
+ 'WinAPI_OpenFileMapping', 'WinAPI_OpenIcon',
+ 'WinAPI_OpenInputDesktop', 'WinAPI_OpenJobObject', 'WinAPI_OpenMutex',
+ 'WinAPI_OpenProcess', 'WinAPI_OpenProcessToken',
+ 'WinAPI_OpenSemaphore', 'WinAPI_OpenThemeData',
+ 'WinAPI_OpenWindowStation', 'WinAPI_PageSetupDlg',
+ 'WinAPI_PaintDesktop', 'WinAPI_PaintRgn', 'WinAPI_ParseURL',
+ 'WinAPI_ParseUserName', 'WinAPI_PatBlt', 'WinAPI_PathAddBackslash',
+ 'WinAPI_PathAddExtension', 'WinAPI_PathAppend',
+ 'WinAPI_PathBuildRoot', 'WinAPI_PathCanonicalize',
+ 'WinAPI_PathCommonPrefix', 'WinAPI_PathCompactPath',
+ 'WinAPI_PathCompactPathEx', 'WinAPI_PathCreateFromUrl',
+ 'WinAPI_PathFindExtension', 'WinAPI_PathFindFileName',
+ 'WinAPI_PathFindNextComponent', 'WinAPI_PathFindOnPath',
+ 'WinAPI_PathGetArgs', 'WinAPI_PathGetCharType',
+ 'WinAPI_PathGetDriveNumber', 'WinAPI_PathIsContentType',
+ 'WinAPI_PathIsDirectory', 'WinAPI_PathIsDirectoryEmpty',
+ 'WinAPI_PathIsExe', 'WinAPI_PathIsFileSpec',
+ 'WinAPI_PathIsLFNFileSpec', 'WinAPI_PathIsRelative',
+ 'WinAPI_PathIsRoot', 'WinAPI_PathIsSameRoot',
+ 'WinAPI_PathIsSystemFolder', 'WinAPI_PathIsUNC',
+ 'WinAPI_PathIsUNCServer', 'WinAPI_PathIsUNCServerShare',
+ 'WinAPI_PathMakeSystemFolder', 'WinAPI_PathMatchSpec',
+ 'WinAPI_PathParseIconLocation', 'WinAPI_PathRelativePathTo',
+ 'WinAPI_PathRemoveArgs', 'WinAPI_PathRemoveBackslash',
+ 'WinAPI_PathRemoveExtension', 'WinAPI_PathRemoveFileSpec',
+ 'WinAPI_PathRenameExtension', 'WinAPI_PathSearchAndQualify',
+ 'WinAPI_PathSkipRoot', 'WinAPI_PathStripPath',
+ 'WinAPI_PathStripToRoot', 'WinAPI_PathToRegion',
+ 'WinAPI_PathUndecorate', 'WinAPI_PathUnExpandEnvStrings',
+ 'WinAPI_PathUnmakeSystemFolder', 'WinAPI_PathUnquoteSpaces',
+ 'WinAPI_PathYetAnotherMakeUniqueName', 'WinAPI_PickIconDlg',
+ 'WinAPI_PlayEnhMetaFile', 'WinAPI_PlaySound', 'WinAPI_PlgBlt',
+ 'WinAPI_PointFromRect', 'WinAPI_PolyBezier', 'WinAPI_PolyBezierTo',
+ 'WinAPI_PolyDraw', 'WinAPI_Polygon', 'WinAPI_PostMessage',
+ 'WinAPI_PrimaryLangId', 'WinAPI_PrintDlg', 'WinAPI_PrintDlgEx',
+ 'WinAPI_PrintWindow', 'WinAPI_ProgIDFromCLSID', 'WinAPI_PtInRect',
+ 'WinAPI_PtInRectEx', 'WinAPI_PtInRegion', 'WinAPI_PtVisible',
+ 'WinAPI_QueryDosDevice', 'WinAPI_QueryInformationJobObject',
+ 'WinAPI_QueryPerformanceCounter', 'WinAPI_QueryPerformanceFrequency',
+ 'WinAPI_RadialGradientFill', 'WinAPI_ReadDirectoryChanges',
+ 'WinAPI_ReadFile', 'WinAPI_ReadProcessMemory', 'WinAPI_Rectangle',
+ 'WinAPI_RectInRegion', 'WinAPI_RectIsEmpty', 'WinAPI_RectVisible',
+ 'WinAPI_RedrawWindow', 'WinAPI_RegCloseKey',
+ 'WinAPI_RegConnectRegistry', 'WinAPI_RegCopyTree',
+ 'WinAPI_RegCopyTreeEx', 'WinAPI_RegCreateKey',
+ 'WinAPI_RegDeleteEmptyKey', 'WinAPI_RegDeleteKey',
+ 'WinAPI_RegDeleteKeyValue', 'WinAPI_RegDeleteTree',
+ 'WinAPI_RegDeleteTreeEx', 'WinAPI_RegDeleteValue',
+ 'WinAPI_RegDisableReflectionKey', 'WinAPI_RegDuplicateHKey',
+ 'WinAPI_RegEnableReflectionKey', 'WinAPI_RegEnumKey',
+ 'WinAPI_RegEnumValue', 'WinAPI_RegFlushKey',
+ 'WinAPI_RegisterApplicationRestart', 'WinAPI_RegisterClass',
+ 'WinAPI_RegisterClassEx', 'WinAPI_RegisterHotKey',
+ 'WinAPI_RegisterPowerSettingNotification',
+ 'WinAPI_RegisterRawInputDevices', 'WinAPI_RegisterShellHookWindow',
+ 'WinAPI_RegisterWindowMessage', 'WinAPI_RegLoadMUIString',
+ 'WinAPI_RegNotifyChangeKeyValue', 'WinAPI_RegOpenKey',
+ 'WinAPI_RegQueryInfoKey', 'WinAPI_RegQueryLastWriteTime',
+ 'WinAPI_RegQueryMultipleValues', 'WinAPI_RegQueryReflectionKey',
+ 'WinAPI_RegQueryValue', 'WinAPI_RegRestoreKey', 'WinAPI_RegSaveKey',
+ 'WinAPI_RegSetValue', 'WinAPI_ReleaseCapture', 'WinAPI_ReleaseDC',
+ 'WinAPI_ReleaseMutex', 'WinAPI_ReleaseSemaphore',
+ 'WinAPI_ReleaseStream', 'WinAPI_RemoveClipboardFormatListener',
+ 'WinAPI_RemoveDirectory', 'WinAPI_RemoveFontMemResourceEx',
+ 'WinAPI_RemoveFontResourceEx', 'WinAPI_RemoveWindowSubclass',
+ 'WinAPI_ReOpenFile', 'WinAPI_ReplaceFile', 'WinAPI_ReplaceTextDlg',
+ 'WinAPI_ResetEvent', 'WinAPI_RestartDlg', 'WinAPI_RestoreDC',
+ 'WinAPI_RGB', 'WinAPI_RotatePoints', 'WinAPI_RoundRect',
+ 'WinAPI_SaveDC', 'WinAPI_SaveFileDlg', 'WinAPI_SaveHBITMAPToFile',
+ 'WinAPI_SaveHICONToFile', 'WinAPI_ScaleWindowExt',
+ 'WinAPI_ScreenToClient', 'WinAPI_SearchPath', 'WinAPI_SelectClipPath',
+ 'WinAPI_SelectClipRgn', 'WinAPI_SelectObject',
+ 'WinAPI_SendMessageTimeout', 'WinAPI_SetActiveWindow',
+ 'WinAPI_SetArcDirection', 'WinAPI_SetBitmapBits',
+ 'WinAPI_SetBitmapDimensionEx', 'WinAPI_SetBkColor',
+ 'WinAPI_SetBkMode', 'WinAPI_SetBoundsRect', 'WinAPI_SetBrushOrg',
+ 'WinAPI_SetCapture', 'WinAPI_SetCaretBlinkTime', 'WinAPI_SetCaretPos',
+ 'WinAPI_SetClassLongEx', 'WinAPI_SetColorAdjustment',
+ 'WinAPI_SetCompression', 'WinAPI_SetCurrentDirectory',
+ 'WinAPI_SetCurrentProcessExplicitAppUserModelID', 'WinAPI_SetCursor',
+ 'WinAPI_SetDCBrushColor', 'WinAPI_SetDCPenColor',
+ 'WinAPI_SetDefaultPrinter', 'WinAPI_SetDeviceGammaRamp',
+ 'WinAPI_SetDIBColorTable', 'WinAPI_SetDIBits',
+ 'WinAPI_SetDIBitsToDevice', 'WinAPI_SetDllDirectory',
+ 'WinAPI_SetEndOfFile', 'WinAPI_SetEnhMetaFileBits',
+ 'WinAPI_SetErrorMode', 'WinAPI_SetEvent', 'WinAPI_SetFileAttributes',
+ 'WinAPI_SetFileInformationByHandleEx', 'WinAPI_SetFilePointer',
+ 'WinAPI_SetFilePointerEx', 'WinAPI_SetFileShortName',
+ 'WinAPI_SetFileValidData', 'WinAPI_SetFocus', 'WinAPI_SetFont',
+ 'WinAPI_SetForegroundWindow', 'WinAPI_SetFRBuffer',
+ 'WinAPI_SetGraphicsMode', 'WinAPI_SetHandleInformation',
+ 'WinAPI_SetInformationJobObject', 'WinAPI_SetKeyboardLayout',
+ 'WinAPI_SetKeyboardState', 'WinAPI_SetLastError',
+ 'WinAPI_SetLayeredWindowAttributes', 'WinAPI_SetLocaleInfo',
+ 'WinAPI_SetMapMode', 'WinAPI_SetMessageExtraInfo', 'WinAPI_SetParent',
+ 'WinAPI_SetPixel', 'WinAPI_SetPolyFillMode',
+ 'WinAPI_SetPriorityClass', 'WinAPI_SetProcessAffinityMask',
+ 'WinAPI_SetProcessShutdownParameters',
+ 'WinAPI_SetProcessWindowStation', 'WinAPI_SetRectRgn',
+ 'WinAPI_SetROP2', 'WinAPI_SetSearchPathMode',
+ 'WinAPI_SetStretchBltMode', 'WinAPI_SetSysColors',
+ 'WinAPI_SetSystemCursor', 'WinAPI_SetTextAlign',
+ 'WinAPI_SetTextCharacterExtra', 'WinAPI_SetTextColor',
+ 'WinAPI_SetTextJustification', 'WinAPI_SetThemeAppProperties',
+ 'WinAPI_SetThreadDesktop', 'WinAPI_SetThreadErrorMode',
+ 'WinAPI_SetThreadExecutionState', 'WinAPI_SetThreadLocale',
+ 'WinAPI_SetThreadUILanguage', 'WinAPI_SetTimer',
+ 'WinAPI_SetUDFColorMode', 'WinAPI_SetUserGeoID',
+ 'WinAPI_SetUserObjectInformation', 'WinAPI_SetVolumeMountPoint',
+ 'WinAPI_SetWindowDisplayAffinity', 'WinAPI_SetWindowExt',
+ 'WinAPI_SetWindowLong', 'WinAPI_SetWindowOrg',
+ 'WinAPI_SetWindowPlacement', 'WinAPI_SetWindowPos',
+ 'WinAPI_SetWindowRgn', 'WinAPI_SetWindowsHookEx',
+ 'WinAPI_SetWindowSubclass', 'WinAPI_SetWindowText',
+ 'WinAPI_SetWindowTheme', 'WinAPI_SetWinEventHook',
+ 'WinAPI_SetWorldTransform', 'WinAPI_SfcIsFileProtected',
+ 'WinAPI_SfcIsKeyProtected', 'WinAPI_ShellAboutDlg',
+ 'WinAPI_ShellAddToRecentDocs', 'WinAPI_ShellChangeNotify',
+ 'WinAPI_ShellChangeNotifyDeregister',
+ 'WinAPI_ShellChangeNotifyRegister', 'WinAPI_ShellCreateDirectory',
+ 'WinAPI_ShellEmptyRecycleBin', 'WinAPI_ShellExecute',
+ 'WinAPI_ShellExecuteEx', 'WinAPI_ShellExtractAssociatedIcon',
+ 'WinAPI_ShellExtractIcon', 'WinAPI_ShellFileOperation',
+ 'WinAPI_ShellFlushSFCache', 'WinAPI_ShellGetFileInfo',
+ 'WinAPI_ShellGetIconOverlayIndex', 'WinAPI_ShellGetImageList',
+ 'WinAPI_ShellGetKnownFolderIDList', 'WinAPI_ShellGetKnownFolderPath',
+ 'WinAPI_ShellGetLocalizedName', 'WinAPI_ShellGetPathFromIDList',
+ 'WinAPI_ShellGetSetFolderCustomSettings', 'WinAPI_ShellGetSettings',
+ 'WinAPI_ShellGetSpecialFolderLocation',
+ 'WinAPI_ShellGetSpecialFolderPath', 'WinAPI_ShellGetStockIconInfo',
+ 'WinAPI_ShellILCreateFromPath', 'WinAPI_ShellNotifyIcon',
+ 'WinAPI_ShellNotifyIconGetRect', 'WinAPI_ShellObjectProperties',
+ 'WinAPI_ShellOpenFolderAndSelectItems', 'WinAPI_ShellOpenWithDlg',
+ 'WinAPI_ShellQueryRecycleBin',
+ 'WinAPI_ShellQueryUserNotificationState',
+ 'WinAPI_ShellRemoveLocalizedName', 'WinAPI_ShellRestricted',
+ 'WinAPI_ShellSetKnownFolderPath', 'WinAPI_ShellSetLocalizedName',
+ 'WinAPI_ShellSetSettings', 'WinAPI_ShellStartNetConnectionDlg',
+ 'WinAPI_ShellUpdateImage', 'WinAPI_ShellUserAuthenticationDlg',
+ 'WinAPI_ShellUserAuthenticationDlgEx', 'WinAPI_ShortToWord',
+ 'WinAPI_ShowCaret', 'WinAPI_ShowCursor', 'WinAPI_ShowError',
+ 'WinAPI_ShowLastError', 'WinAPI_ShowMsg', 'WinAPI_ShowOwnedPopups',
+ 'WinAPI_ShowWindow', 'WinAPI_ShutdownBlockReasonCreate',
+ 'WinAPI_ShutdownBlockReasonDestroy',
+ 'WinAPI_ShutdownBlockReasonQuery', 'WinAPI_SizeOfResource',
+ 'WinAPI_StretchBlt', 'WinAPI_StretchDIBits',
+ 'WinAPI_StrFormatByteSize', 'WinAPI_StrFormatByteSizeEx',
+ 'WinAPI_StrFormatKBSize', 'WinAPI_StrFromTimeInterval',
+ 'WinAPI_StringFromGUID', 'WinAPI_StringLenA', 'WinAPI_StringLenW',
+ 'WinAPI_StrLen', 'WinAPI_StrokeAndFillPath', 'WinAPI_StrokePath',
+ 'WinAPI_StructToArray', 'WinAPI_SubLangId', 'WinAPI_SubtractRect',
+ 'WinAPI_SwapDWord', 'WinAPI_SwapQWord', 'WinAPI_SwapWord',
+ 'WinAPI_SwitchColor', 'WinAPI_SwitchDesktop',
+ 'WinAPI_SwitchToThisWindow', 'WinAPI_SystemParametersInfo',
+ 'WinAPI_TabbedTextOut', 'WinAPI_TerminateJobObject',
+ 'WinAPI_TerminateProcess', 'WinAPI_TextOut', 'WinAPI_TileWindows',
+ 'WinAPI_TrackMouseEvent', 'WinAPI_TransparentBlt',
+ 'WinAPI_TwipsPerPixelX', 'WinAPI_TwipsPerPixelY',
+ 'WinAPI_UnhookWindowsHookEx', 'WinAPI_UnhookWinEvent',
+ 'WinAPI_UnionRect', 'WinAPI_UnionStruct', 'WinAPI_UniqueHardwareID',
+ 'WinAPI_UnloadKeyboardLayout', 'WinAPI_UnlockFile',
+ 'WinAPI_UnmapViewOfFile', 'WinAPI_UnregisterApplicationRestart',
+ 'WinAPI_UnregisterClass', 'WinAPI_UnregisterHotKey',
+ 'WinAPI_UnregisterPowerSettingNotification',
+ 'WinAPI_UpdateLayeredWindow', 'WinAPI_UpdateLayeredWindowEx',
+ 'WinAPI_UpdateLayeredWindowIndirect', 'WinAPI_UpdateResource',
+ 'WinAPI_UpdateWindow', 'WinAPI_UrlApplyScheme',
+ 'WinAPI_UrlCanonicalize', 'WinAPI_UrlCombine', 'WinAPI_UrlCompare',
+ 'WinAPI_UrlCreateFromPath', 'WinAPI_UrlFixup', 'WinAPI_UrlGetPart',
+ 'WinAPI_UrlHash', 'WinAPI_UrlIs', 'WinAPI_UserHandleGrantAccess',
+ 'WinAPI_ValidateRect', 'WinAPI_ValidateRgn', 'WinAPI_VerQueryRoot',
+ 'WinAPI_VerQueryValue', 'WinAPI_VerQueryValueEx',
+ 'WinAPI_WaitForInputIdle', 'WinAPI_WaitForMultipleObjects',
+ 'WinAPI_WaitForSingleObject', 'WinAPI_WideCharToMultiByte',
+ 'WinAPI_WidenPath', 'WinAPI_WindowFromDC', 'WinAPI_WindowFromPoint',
+ 'WinAPI_WordToShort', 'WinAPI_Wow64EnableWow64FsRedirection',
+ 'WinAPI_WriteConsole', 'WinAPI_WriteFile',
+ 'WinAPI_WriteProcessMemory', 'WinAPI_ZeroMemory',
+ 'WinNet_AddConnection', 'WinNet_AddConnection2',
+ 'WinNet_AddConnection3', 'WinNet_CancelConnection',
+ 'WinNet_CancelConnection2', 'WinNet_CloseEnum',
+ 'WinNet_ConnectionDialog', 'WinNet_ConnectionDialog1',
+ 'WinNet_DisconnectDialog', 'WinNet_DisconnectDialog1',
+ 'WinNet_EnumResource', 'WinNet_GetConnection',
+ 'WinNet_GetConnectionPerformance', 'WinNet_GetLastError',
+ 'WinNet_GetNetworkInformation', 'WinNet_GetProviderName',
+ 'WinNet_GetResourceInformation', 'WinNet_GetResourceParent',
+ 'WinNet_GetUniversalName', 'WinNet_GetUser', 'WinNet_OpenEnum',
+ 'WinNet_RestoreConnection', 'WinNet_UseConnection', 'Word_Create',
+ 'Word_DocAdd', 'Word_DocAttach', 'Word_DocClose', 'Word_DocExport',
+ 'Word_DocFind', 'Word_DocFindReplace', 'Word_DocGet',
+ 'Word_DocLinkAdd', 'Word_DocLinkGet', 'Word_DocOpen',
+ 'Word_DocPictureAdd', 'Word_DocPrint', 'Word_DocRangeSet',
+ 'Word_DocSave', 'Word_DocSaveAs', 'Word_DocTableRead',
+ 'Word_DocTableWrite', 'Word_Quit'
+ ),
+ 5 => array(
+ 'ce', 'comments-end', 'comments-start', 'cs'
+ ),
+ 6 => array(
+ 'Au3Stripper_Ignore_Funcs', 'Au3Stripper_Ignore_Variables',
+ 'Au3Stripper_Off', 'Au3Stripper_On', 'Au3Stripper_Parameters',
+ 'AutoIt3Wrapper_Add_Constants', 'AutoIt3Wrapper_Au3Check_Parameters',
+ 'AutoIt3Wrapper_Au3Check_Stop_OnWarning', 'AutoIt3Wrapper_Aut2Exe',
+ 'AutoIt3Wrapper_AutoIt3', 'AutoIt3Wrapper_AutoIt3Dir',
+ 'AutoIt3Wrapper_Change2CUI', 'AutoIt3Wrapper_Compile_Both',
+ 'AutoIt3Wrapper_Compression', 'AutoIt3Wrapper_EndIf',
+ 'AutoIt3Wrapper_Icon', 'AutoIt3Wrapper_If_Compile',
+ 'AutoIt3Wrapper_If_Run', 'AutoIt3Wrapper_Jump_To_First_Error',
+ 'AutoIt3Wrapper_OutFile', 'AutoIt3Wrapper_OutFile_Type',
+ 'AutoIt3Wrapper_OutFile_X64', 'AutoIt3Wrapper_PlugIn_Funcs',
+ 'AutoIt3Wrapper_Res_Comment', 'Autoit3Wrapper_Res_Compatibility',
+ 'AutoIt3Wrapper_Res_Description', 'AutoIt3Wrapper_Res_Field',
+ 'AutoIt3Wrapper_Res_File_Add', 'AutoIt3Wrapper_Res_FileVersion',
+ 'AutoIt3Wrapper_Res_FileVersion_AutoIncrement',
+ 'AutoIt3Wrapper_Res_Icon_Add', 'AutoIt3Wrapper_Res_Language',
+ 'AutoIt3Wrapper_Res_LegalCopyright',
+ 'AutoIt3Wrapper_Res_ProductVersion',
+ 'AutoIt3Wrapper_Res_requestedExecutionLevel',
+ 'AutoIt3Wrapper_Res_SaveSource', 'AutoIt3Wrapper_Run_After',
+ 'AutoIt3Wrapper_Run_Au3Check', 'AutoIt3Wrapper_Run_Au3Stripper',
+ 'AutoIt3Wrapper_Run_Before', 'AutoIt3Wrapper_Run_Debug_Mode',
+ 'AutoIt3Wrapper_Run_SciTE_Minimized',
+ 'AutoIt3Wrapper_Run_SciTE_OutputPane_Minimized',
+ 'AutoIt3Wrapper_Run_Tidy', 'AutoIt3Wrapper_ShowProgress',
+ 'AutoIt3Wrapper_Testing', 'AutoIt3Wrapper_Tidy_Stop_OnError',
+ 'AutoIt3Wrapper_UPX_Parameters', 'AutoIt3Wrapper_UseUPX',
+ 'AutoIt3Wrapper_UseX64', 'AutoIt3Wrapper_Version',
+ 'AutoIt3Wrapper_Versioning', 'AutoIt3Wrapper_Versioning_Parameters',
+ 'Tidy_Off', 'Tidy_On', 'Tidy_Parameters', 'EndRegion', 'Region'
+ ),
+ 7 => array(
+ 'APPSKEY', 'BACKSPACE', 'BROWSER_BACK', 'BROWSER_FAVORITES',
+ 'BROWSER_FORWARD', 'BROWSER_HOME', 'BROWSER_REFRESH', 'BROWSER_SEARCH',
+ 'BROWSER_STOP', 'BS', 'CAPSLOCK', 'DEL', 'DELETE', 'DOWN', 'END', 'ENTER',
+ 'ESC', 'ESCAPE', 'F1', 'F10', 'F11', 'F12', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7',
+ 'F8', 'F9', 'HOME', 'INS', 'INSERT', 'LAUNCH_APP1', 'LAUNCH_APP2',
+ 'LAUNCH_MAIL', 'LAUNCH_MEDIA', 'LEFT', 'MEDIA_NEXT', 'MEDIA_PLAY_PAUSE',
+ 'MEDIA_PREV', 'MEDIA_STOP', 'NUMLOCK', 'NUMPAD0', 'NUMPAD1', 'NUMPAD2',
+ 'NUMPAD3', 'NUMPAD4', 'NUMPAD5', 'NUMPAD6', 'NUMPAD7', 'NUMPAD8',
+ 'NUMPAD9', 'NUMPADADD', 'NUMPADDIV', 'NUMPADDOT', 'NUMPADENTER',
+ 'NUMPADMULT', 'NUMPADSUB', 'PAUSE', 'PGDN', 'PGUP', 'PRINTSCREEN',
+ 'RIGHT', 'SCROLLLOCK', 'SLEEP', 'SPACE', 'TAB', 'UP', 'VOLUME_DOWN',
+ 'VOLUME_MUTE', 'VOLUME_UP'
+ ),
+ 8 => array(
+ 'include', 'include-once', 'NoTrayIcon', 'OnAutoItStartRegister',
+ 'RequireAdmin'
+ ),
+ 9 => array(
+ 'pragma'
+ ),
+ 10 => array(
+ 'forcedef', 'forceref', 'ignorefunc'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '[', ']',
+ '+', '-', '*', '/', '&', '^', ':', '?',
+ '=', '==', '+=', '-=', '*=', '/=', '&=',
+ '<', '<=', '>', '>=',
+ ',', '.'
+ ),
+ 1 => array('_' // Undersore for continuation of strings.
+ ),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ 8 => false,
+ 9 => false,
+ 10 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF;', // Keywords
+ 2 => 'color: #808000;', // Macros
+ 3 => 'color: #000090;', // Native Functions
+ 4 => 'color: #0080FF;', // UDF Functions
+ 5 => 'color: #808000;', // Comments
+ 6 => 'color: #DC143C;', // Directives
+ 7 => 'color: #5A5A5A;', // Keylist
+ 8 => 'color: #808000;', // PreProcessor
+ 9 => 'color: #DC143C;', // Pragma
+ 10 => 'color: #DC143C;' // Au3Check
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #FF0000; font-style: italic',
+ 1 => 'color: #008000; font-style: italic;',
+ 2 => 'color: #008000; font-style: italic;',
+ 'MULTI' => 'color: #008000; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #FF8000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000FF;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #FF0000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #FF8000;',
+ 1 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #5A5A5A;', // Variables
+ 1 => 'color: #5A5A5A;' // Keylist
+ ),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => 'https://www.autoitscript.com/autoit3/docs/keywords.htm', // Keywords
+ 2 => 'https://www.autoitscript.com/autoit3/docs/macros.htm#{FNAME}', // Macros
+ 3 => 'https://www.autoitscript.com/autoit3/docs/functions/{FNAME}.htm', // Native Functions
+ 4 => 'https://www.autoitscript.com/autoit3/docs/libfunctions/_{FNAME}.htm', // UDF Functions
+ 5 => 'https://www.autoitscript.com/autoit3/docs/keywords/comments-start.htm', // Comments
+ 6 => 'https://www.autoitscript.com/autoit3/scite/docs/AutoIt3Wrapper.html', // Directives
+ 7 => 'https://www.autoitscript.com/autoit3/docs/appendix/SendKeys.htm#KeysList', // Keylist
+ 8 => 'https://www.autoitscript.com/autoit3/docs/keywords/{FNAME}.htm', // PreProcessor
+ 9 => 'https://www.autoitscript.com/autoit3/docs/keywords/{FNAME}.htm', // Pragma
+ 10 => 'https://www.autoitscript.com/autoit3/docs/intro/au3check.htm' // Au3Check
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ 0 => '\$[a-zA-Z0-9_]*', // Variables
+ 1 => '\\{[a-zA-Z0-9_]+\\}' // Keylist
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 4 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\w)\_'
+ ),
+ 5 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\w)\#'
+ ),
+ 6 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\w)\#',
+ 'DISALLOWED_AFTER' => '(?<!=)[^\r\n]*'
+ ),
+ 8 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\w)\#',
+ 'DISALLOWED_AFTER' => '(?<!=)[^\r\n]*'
+ ),
+ 9 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\w)\#',
+ 'DISALLOWED_AFTER' => '(?<!=)[^\r\n]*'
+ ),
+ 10 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\w)\#',
+ 'DISALLOWED_AFTER' => '(?<!=)[^\r\n]*'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/avisynth.php b/platform/www/vendor/geshi/geshi/src/geshi/avisynth.php
new file mode 100644
index 0000000..ea9fc9a
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/avisynth.php
@@ -0,0 +1,193 @@
+<?php
+/*************************************************************************************
+ * avisynth.php
+ * --------
+ * Author: Ryan Jones (sciguyryan@gmail.com)
+ * Copyright: (c) 2008 Ryan Jones
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/10/08
+ *
+ * AviSynth language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/08 (1.0.8.1)
+ * - First Release
+ *
+ * TODO (updated 2008/10/08)
+ * -------------------------
+ * * There are also some special words that can't currently be specified directly in GeSHi as they may
+ * also be used as variables which would really mess things up.
+ * * Also there is an issue with the escape character as this language uses a muti-character escape system. Escape char should be """ but has been left
+ * as empty due to this restiction.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'AviSynth',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/', '[*' => '*]'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ // Reserved words.
+ 1 => array(
+ 'try', 'cache', 'function', 'global', 'return'
+ ),
+ // Constants / special variables.
+ 2 => array(
+ 'true', 'yes', 'false', 'no', '__END__'
+ ),
+ // Internal Filters.
+ 3 => array(
+ 'AviSource', 'AviFileSource', 'AddBorders', 'AlignedSplice', 'AssumeFPS', 'AssumeScaledFPS',
+ 'AssumeFrameBased', 'AssumeFieldBased', 'AssumeBFF', 'AssumeTFF', 'Amplify', 'AmplifydB',
+ 'AssumeSampleRate', 'AudioDub', 'AudioDubEx', 'Animate', 'ApplyRange',
+ 'BicubicResize', 'BilinearResize', 'BlackmanResize', 'Blur', 'Bob', 'BlankClip', 'Blackness',
+ 'ColorYUV', 'ConvertBackToYUY2', 'ConvertToRGB', 'ConvertToRGB24', 'ConvertToRGB32',
+ 'ConvertToYUY2', 'ConvertToY8', 'ConvertToYV411', 'ConvertToYV12', 'ConvertToYV16', 'ConvertToYV24',
+ 'ColorKeyMask', 'Crop', 'CropBottom', 'ChangeFPS', 'ConvertFPS', 'ComplementParity', 'ConvertAudioTo8bit',
+ 'ConvertAudioTo16bit', 'ConvertAudioTo24bit', 'ConvertAudioTo32bit', 'ConvertAudioToFloat', 'ConvertToMono',
+ 'ConditionalFilter', 'ConditionalReader', 'ColorBars', 'Compare',
+ 'DirectShowSource', 'DeleteFrame', 'Dissolve', 'DuplicateFrame', 'DoubleWeave', 'DelayAudio',
+ 'EnsureVBRMP3Sync',
+ 'FixLuminance', 'FlipHorizontal', 'FlipVertical', 'FixBrokenChromaUpsampling', 'FadeIn0', 'FadeIn',
+ 'FadeIn2', 'FadeOut0', 'FadeOut', 'FadeOut2', 'FadeIO0', 'FadeIO', 'FadeIO2', 'FreezeFrame', 'FrameEvaluate',
+ 'GreyScale', 'GaussResize', 'GeneralConvolution', 'GetChannel', 'GetLeftChannel', 'GetRightChannel',
+ 'HorizontalReduceBy2', 'Histogram',
+ 'ImageReader', 'ImageSource', 'ImageWriter', 'Invert', 'Interleave', 'Info',
+ 'KillAudio', 'KillVideo',
+ 'Levels', 'Limiter', 'Layer', 'Letterbox', 'LanczosResize', 'Lanczos4Resize', 'Loop',
+ 'MergeARGB', 'MergeRGB', 'MergeChroma', 'MergeLuma', 'Merge', 'Mask', 'MaskHS', 'MergeChannels', 'MixAudio',
+ 'MonoToStereo', 'MessageClip',
+ 'Normalize',
+ 'OpenDMLSource', 'Overlay',
+ 'PointResize', 'PeculiarBlend', 'Pulldown',
+ 'RGBAdjust', 'ResetMask', 'Reverse', 'ResampleAudio', 'ReduceBy2',
+ 'SegmentedAviSource', 'SegmentedDirectShowSource', 'SoundOut', 'ShowAlpha', 'ShowRed', 'ShowGreen',
+ 'ShowBlue', 'SwapUV', 'Subtract', 'SincResize', 'Spline16Resize', 'Spline36Resize', 'Spline64Resize',
+ 'SelectEven', 'SelectOdd', 'SelectEvery', 'SelectRangeEvery', 'Sharpen', 'SpatialSoften', 'SeparateFields',
+ 'ShowFiveVersions', 'ShowFrameNumber', 'ShowSMPTE', 'ShowTime', 'StackHorizontal', 'StackVertical', 'Subtitle',
+ 'SwapFields', 'SuperEQ', 'SSRC', 'ScriptClip',
+ 'Tweak', 'TurnLeft', 'TurnRight', 'Turn180', 'TemporalSoften', 'TimeStretch', 'TCPServer', 'TCPSource', 'Trim',
+ 'Tone',
+ 'UToY', 'UToY8', 'UnalignedSplice',
+ 'VToY', 'VToY8', 'VerticalReduceBy2', 'Version',
+ 'WavSource', 'Weave', 'WriteFile', 'WriteFileIf', 'WriteFileStart', 'WriteFileEnd',
+ 'YToUV'
+ ),
+ // Internal functions.
+ 4 => array(
+ 'Abs', 'Apply', 'Assert', 'AverageLuma', 'AverageChromaU', 'AverageChromaV',
+ 'Ceil', 'Cos', 'Chr', 'ChromaUDifference', 'ChromaVDifference',
+ 'Defined', 'Default',
+ 'Exp', 'Exist', 'Eval',
+ 'Floor', 'Frac', 'Float', 'Findstr', 'GetMTMode',
+ 'HexValue',
+ 'Int', 'IsBool', 'IsClip', 'IsFloat', 'IsInt', 'IsString', 'Import',
+ 'LoadPlugin', 'Log', 'LCase', 'LeftStr', 'LumaDifference', 'LoadVirtualDubPlugin', 'LoadVFAPIPlugin',
+ 'LoadCPlugin', 'Load_Stdcall_Plugin',
+ 'Max', 'MulDiv', 'MidStr',
+ 'NOP',
+ 'OPT_AllowFloatAudio', 'OPT_UseWaveExtensible',
+ 'Pi', 'Pow',
+ 'Round', 'Rand', 'RevStr', 'RightStr', 'RGBDifference', 'RGBDifferenceFromPrevious', 'RGBDifferenceToNext',
+ 'Sin', 'Sqrt', 'Sign', 'Spline', 'StrLen', 'String', 'Select', 'SetMemoryMax', 'SetWorkingDir', 'SetMTMode',
+ 'SetPlanarLegacyAlignment',
+ 'Time',
+ 'UCase', 'UDifferenceFromPrevious', 'UDifferenceToNext', 'UPlaneMax', 'UPlaneMin', 'UPlaneMedian',
+ 'UPlaneMinMaxDifference',
+ 'Value', 'VersionNumber', 'VersionString', 'VDifferenceFromPrevious', 'VDifferenceToNext', 'VPlaneMax',
+ 'VPlaneMin', 'VPlaneMedian', 'VPlaneMinMaxDifference',
+ 'YDifferenceFromPrevious', 'YDifferenceToNext', 'YPlaneMax', 'YPlaneMin', 'YPlaneMedian',
+ 'YPlaneMinMaxDifference'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '+', '++', '-', '--', '/', '*', '%',
+ '=', '==', '<', '<=', '>', '>=', '<>', '!=',
+ '!', '?', ':',
+ '|', '||', '&&',
+ '\\',
+ '(', ')', '{', '}',
+ '.', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color:#9966CC; font-weight:bold;',
+ 2 => 'color:#0000FF; font-weight:bold;',
+ 3 => 'color:#CC3300; font-weight:bold;',
+ 4 => 'color:#660000; font-weight:bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color:#008000; font-style:italic;',
+ 'MULTI' => 'color:#000080; font-style:italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color:#000099;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color:#006600; font-weight:bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color:#996600;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color:#006666;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color:#9900CC;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color:#006600; font-weight:bold;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://avisynth.org/mediawiki/{FNAME}',
+ 4 => ''
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/awk.php b/platform/www/vendor/geshi/geshi/src/geshi/awk.php
new file mode 100644
index 0000000..f116b81
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/awk.php
@@ -0,0 +1,156 @@
+<?php
+/************************************************
+ * awk.php
+ * -------
+ * Author: George Pollard (porges@porg.es)
+ * Copyright: (c) 2009 George Pollard
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/01/28
+ *
+ * Awk language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/01/28 (1.0.8.5)
+ * - First Release
+ *
+ * TODO (updated 2009/01/28)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'awk',
+ 'COMMENT_SINGLE' => array(
+ 1 => '#'
+ ),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array (
+ 1 => array(
+ 'for', 'in', 'if', 'else', 'while', 'do', 'continue', 'break'
+ ),
+ 2 => array(
+ 'BEGIN', 'END'
+ ),
+ 3 => array(
+ 'ARGC', 'ARGV', 'CONVFMT', 'ENVIRON',
+ 'FILENAME', 'FNR', 'FS', 'NF', 'NR', 'OFMT',
+ 'OFS','ORS','RLENGTH','RS','RSTART','SUBSEP'
+ ),
+ 4 => array(
+ 'gsub','index','length','match','split',
+ 'sprintf','sub','substr','tolower','toupper',
+ 'atan2','cos','exp','int','log','rand',
+ 'sin','sqrt','srand'
+ ),
+ 5 => array(
+ 'print','printf','getline','close','fflush','system'
+ ),
+ 6 => array(
+ 'function', 'return'
+ )
+ ),
+ 'SYMBOLS' => array (
+ 0 => array(
+ '(',')','[',']','{','}'
+ ),
+ 1 => array(
+ '!','||','&&'
+ ),
+ 2 => array(
+ '<','>','<=','>=','==','!='
+ ),
+ 3 => array(
+ '+','-','*','/','%','^','++','--'
+ ),
+ 4 => array(
+ '~','!~'
+ ),
+ 5 => array(
+ '?',':'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #C20CB9; font-weight: bold;',
+ 3 => 'color: #4107D5; font-weight: bold;',
+ 4 => 'color: #07D589; font-weight: bold;',
+ 5 => 'color: #0BD507; font-weight: bold;',
+ 6 => 'color: #078CD5; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color:#808080;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color:black;',
+ 1 => 'color:black;',
+ 2 => 'color:black;',
+ 3 => 'color:black;',
+ 4 => 'color:#C4C364;',
+ 5 => 'color:black;font-weight:bold;'),
+ 'SCRIPT' => array(),
+ 'REGEXPS' => array(
+ 0 => 'color:#000088;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #7a0874; font-weight: bold;'
+ ),
+ 'METHODS' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array (),
+ 'REGEXPS' => array(
+ 0 => "\\$[a-zA-Z0-9_]+"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array (),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/bascomavr.php b/platform/www/vendor/geshi/geshi/src/geshi/bascomavr.php
new file mode 100644
index 0000000..90d8506
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/bascomavr.php
@@ -0,0 +1,183 @@
+<?php
+/*************************************************************************************
+ * bascomavr.php
+ * ---------------------------------
+ * Author: aquaticus.info
+ * Copyright: (c) 2008 aquaticus.info
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/01/09
+ *
+ * BASCOM AVR language file for GeSHi.
+ *
+ * You can find the BASCOM AVR Website at (www.mcselec.com/bascom-avr.htm)
+ *
+ * CHANGES
+ * -------
+ * 2008/01/09 (1.0.8.10)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'BASCOM AVR',
+ 'COMMENT_SINGLE' => array(1 => "'"),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ // Navy Blue Bold Keywords
+ '1WRESET' , '1WREAD' , '1WWRITE' , '1WSEARCHFIRST' , '1WSEARCHNEXT' ,'1WVERIFY' , '1WIRECOUNT',
+ 'CONFIG' , 'ACI' , 'ADC' , 'BCCARD' , 'CLOCK' , 'COM1' ,
+ 'COM2' , 'PS2EMU' , 'ATEMU' , 'I2CSLAVE' ,
+ 'INPUT', 'OUTPUT', 'GRAPHLCD' , 'KEYBOARD' , 'TIMER0' , 'TIMER1' ,
+ 'LCDBUS' , 'LCDMODE' , '1WIRE' , 'LCD' , 'SERIALOUT' ,
+ 'SERIALIN' , 'SPI' , 'LCDPIN' , 'SDA' , 'SCL' ,
+ 'WATCHDOG' , 'PORT' , 'COUNTER0', 'COUNTER1' , 'TCPIP' , 'TWISLAVE' ,
+ 'X10' , 'XRAM' , 'USB',
+ 'BCD' , 'GRAY2BIN' , 'BIN2GRAY' , 'BIN' , 'MAKEBCD' , 'MAKEDEC' , 'MAKEINT' , 'FORMAT' , 'FUSING' , 'BINVAL' ,
+ 'CRC8' , 'CRC16' , 'CRC16UNI' , 'CRC32' , 'HIGH' , 'HIGHW' , 'LOW',
+ 'DATE' , 'TIME' , 'DATE$' , 'TIME$' , 'DAYOFWEEK' , 'DAYOFYEAR' , 'SECOFDAY' , 'SECELAPSED' , 'SYSDAY' , 'SYSSEC' , 'SYSSECELAPSED',
+ 'WAIT' , 'WAITMS' , 'WAITUS' , 'DELAY',
+ 'BSAVE' , 'BLOAD' , 'GET' , 'VER' , 'DISKFREE' , 'DIR' , 'DriveReset' , 'DriveInit' , 'LINE' , 'INITFILESYSTEM' ,
+ 'EOF' , 'WRITE' , 'FLUSH' , 'FREEFILE' , 'FILEATTR' , 'FILEDATE' , 'FILETIME' , 'FILEDATETIME' , 'FILELEN' , 'SEEK' ,
+ 'KILL' , 'DriveGetIdentity' , 'DriveWriteSector' , 'DriveReadSector' , 'LOC' , 'LOF' , 'PUT' , 'OPEN' , 'CLOSE',
+ 'GLCDCMD' , 'GLCDDATA' , 'SETFONT' , 'PSET' , 'SHOWPIC' , 'SHOWPICE' , 'CIRCLE' , 'BOX',
+ 'I2CINIT' , 'I2CRECEIVE' , 'I2CSEND' , 'I2CSTART','I2CSTOP','I2CRBYTE','I2CWBYTE',
+ 'ALIAS' , 'BITWAIT' , 'TOGGLE' , 'RESET' , 'SET' , 'SHIFTIN' , 'SHIFTOUT' , 'DEBOUNCE' , 'PULSEIN' , 'PULSEOUT',
+ 'IDLE' , 'POWERDOWN' , 'POWERSAVE' , 'ON', 'INTERRUPT' , 'ENABLE' , 'DISABLE' , 'START' , 'VERSION' , 'CLOCKDIVISION' , 'CRYSTAL' , 'STOP',
+ 'ADR' , 'ADR2' , 'WRITEEEPROM' , 'CPEEK' , 'CPEEKH' , 'PEEK' , 'POKE' , 'OUT' , 'READEEPROM' , 'DATA' , 'INP' , 'READ' , 'RESTORE' , 'LOOKDOWN' , 'LOOKUP' , 'LOOKUPSTR' , 'LOAD' , 'LOADADR' , 'LOADLABEL' , 'LOADWORDADR' , 'MEMCOPY',
+ 'RC5SEND' , 'RC6SEND' , 'GETRC5' , 'SONYSEND',
+ 'BAUD' , 'BAUD1', 'BUFSPACE' , 'CLEAR', 'ECHO' , 'WAITKEY' , 'ISCHARWAITING' , 'INKEY' , 'INPUTBIN' , 'INPUTHEX' , 'PRINT', 'PRINT1','PRINT0', 'PRINTBIN' , 'SERIN' , 'SEROUT' , 'SPC' , 'MAKEMODBUS',
+ 'SPIIN' , 'SPIINIT' , 'SPIMOVE' , 'SPIOUT', 'SINGLE',
+ 'ASC' , 'UCASE' , 'LCASE' , 'TRIM' , 'SPLIT' , 'LTRIM' , 'INSTR' , 'SPACE' , 'RTRIM' , 'LEFT' , 'LEN' , 'MID' , 'RIGHT' , 'VAL' , 'STR' , 'CHR' , 'CHECKSUM' , 'HEX' , 'HEXVAL',
+ 'BASE64DEC' , 'BASE64ENC' , 'IP2STR' , 'UDPREAD' , 'UDPWRITE' , 'UDPWRITESTR' , 'TCPWRITE' , 'TCPWRITESTR' , 'TCPREAD' , 'GETDSTIP' , 'GETDSTPORT' , 'SOCKETSTAT' , 'SOCKETCONNECT' , 'SOCKETLISTEN' , 'GETSOCKET' , 'CLOSESOCKET' ,
+ 'SETTCP' , 'GETTCPREGS' , 'SETTCPREGS' , 'SETIPPROTOCOL' , 'TCPCHECKSUM',
+ 'HOME' , 'CURSOR' , 'UPPERLINE' , 'THIRDLINE' , 'INITLCD' , 'LOWERLINE' , 'LCDAT' , 'FOURTHLINE' , 'DISPLAY' , 'LCDCONTRAST' , 'LOCATE' , 'SHIFTCURSOR' , 'DEFLCDCHAR' , 'SHIFTLCD' , 'CLS',
+ 'ACOS' , 'ASIN' , 'ATN' , 'ATN2' , 'EXP' , 'RAD2DEG' , 'FRAC' , 'TAN' , 'TANH' , 'COS' , 'COSH' , 'LOG' , 'LOG10' , 'ROUND' , 'ABS' , 'INT' , 'MAX' , 'MIN' , 'SQR' , 'SGN' , 'POWER' , 'SIN' , 'SINH' , 'FIX' , 'INCR' , 'DECR' , 'DEG2RAD',
+ 'DBG' , 'DEBUG', 'DTMFOUT' , 'ENCODER' , 'GETADC' , 'GETKBD' , 'GETATKBD' , 'GETRC' , 'VALUE' , 'POPALL' , 'PS2MOUSEXY' , 'PUSHALL' ,
+ 'RETURN' , 'RND' , 'ROTATE' , 'SENDSCAN' , 'SENDSCANKBD' , 'SHIFT' , 'SOUND' , 'STCHECK' , 'SWAP' , 'VARPTR' , 'X10DETECT' , 'X10SEND' , 'READMAGCARD' , 'REM' , 'BITS' , 'BYVAL' , 'CALL' , 'READHITAG',
+ 'Buffered', 'Size', 'Dummy', 'Parity', 'None', 'Stopbits', 'Databits', 'Clockpol', 'Synchrone', 'Prescaler', 'Reference', 'int0', 'int1', 'Interrupts',
+ 'Auto', 'avcc', 'ack', 'nack', 'Pin', 'Db4', 'Db3', 'Db2', 'Db1', 'Db7', 'Db6', 'Db5', 'Db0', 'e', 'rs', 'twi',
+ ),
+ 2 => array(
+ // Red Lowercase Keywords
+ '$ASM' , '$BAUD' , '$BAUD1' , '$BGF' , '$BOOT' , '$CRYSTAL' , '$DATA' , '$DBG' , '$DEFAULT' , '$EEPLEAVE' , '$EEPROM' ,
+ '$EEPROMHEX' , '$EXTERNAL' , '$HWSTACK' , '$INC' , '$INCLUDE' , '$INITMICRO' , '$LCD' , '$LCDRS' , '$LCDPUTCTRL' ,
+ '$LCDPUTDATA' , '$LCDVFO' , '$LIB' , '$LOADER' , '$LOADERSIZE' , '$MAP' , '$NOCOMPILE' , '$NOINIT' , '$NORAMCLEAR' ,
+ '$PROG' , '$PROGRAMMER' , '$REGFILE' , '$RESOURCE' , '$ROMSTART', '$SERIALINPUT', '$SERIALINPUT1' , '$SERIALINPUT2LCD' ,
+ '$SERIALOUTPUT' , '$SERIALOUTPUT1' , '$SIM' , '$SWSTACK' , '$TIMEOUT' , '$TINY' , '$WAITSTATE' , '$XRAMSIZE' , '$XRAMSTART', '$XA',
+ '#IF' , '#ELSE' , '#ENDIF', '$framesize'
+ ),
+ 3 => array(
+ // Blue Lowercase Keywords
+ 'IF', 'THEN', 'ELSE', 'END', 'WHILE', 'WEND', 'DO', 'LOOP', 'SELECT', 'CASE', 'FOR', 'NEXT',
+ 'GOSUB' , 'GOTO' , 'LOCAL' , 'SUB' , 'DEFBIT', 'DEFBYTE', 'DEFINT', 'DEFWORD', 'DEFLNG', 'DEFSNG', 'DEFDBL',
+ 'CONST', 'DECLARE', 'FUNCTION', 'DIM', 'EXIT', 'LONG', 'INTEGER', 'BYTE', 'AS', 'STRING', 'WORD'
+ ),
+ 4 => array(
+ //light blue
+ 'PINA.0', 'PINA.1', 'PINA.2', 'PINA.3', 'PINA.4', 'PINA.5', 'PINA.6', 'PINA.7',
+ 'PINB.0', 'PINB.1', 'PINB.2', 'PINB.3', 'PINB.4', 'PINB.5', 'PINB.6', 'PINB.7',
+ 'PINC.0', 'PINC.1', 'PINC.2', 'PINC.3', 'PINC.4', 'PINC.5', 'PINC.6', 'PINC.7',
+ 'PIND.0', 'PIND.1', 'PIND.2', 'PIND.3', 'PIND.4', 'PIND.5', 'PIND.6', 'PIND.7',
+ 'PINE.0', 'PINE.1', 'PINE.2', 'PINE.3', 'PINE.4', 'PINE.5', 'PINE.6', 'PINE.7',
+ 'PINF.0', 'PINF.1', 'PINF.2', 'PINF.3', 'PINF.4', 'PINF.5', 'PINF.6', 'PINF.7',
+
+ 'PORTA.0', 'PORTA.1', 'PORTA.2', 'PORTA.3', 'PORTA.4', 'PORTA.5', 'PORTA.6', 'PORTA.7',
+ 'PORTB.0', 'PORTB.1', 'PORTB.2', 'PORTB.3', 'PORTB.4', 'PORTB.5', 'PORTB.6', 'PORTB.7',
+ 'PORTC.0', 'PORTC.1', 'PORTC.2', 'PORTC.3', 'PORTC.4', 'PORTC.5', 'PORTC.6', 'PORTC.7',
+ 'PORTD.0', 'PORTD.1', 'PORTD.2', 'PORTD.3', 'PORTD.4', 'PORTD.5', 'PORTD.6', 'PORTD.7',
+ 'PORTE.0', 'PORTE.1', 'PORTE.2', 'PORTE.3', 'PORTE.4', 'PORTE.5', 'PORTE.6', 'PORTE.7',
+ 'PORTF.0', 'PORTF.1', 'PORTF.2', 'PORTF.3', 'PORTF.4', 'PORTF.5', 'PORTF.6', 'PORTF.7',
+
+ 'DDRA.0', 'DDRA.1', 'DDRA.2', 'DDRA.3', 'DDRA.4', 'DDRA.5', 'DDRA.6', 'DDRA.7',
+ 'DDRB.0', 'DDRB.1', 'DDRB.2', 'DDRB.3', 'DDRB.4', 'DDRB.5', 'DDRB.6', 'DDRB.7',
+ 'DDRC.0', 'DDRC.1', 'DDRC.2', 'DDRC.3', 'DDRC.4', 'DDRC.5', 'DDRC.6', 'DDRC.7',
+ 'DDRD.0', 'DDRD.1', 'DDRD.2', 'DDRD.3', 'DDRD.4', 'DDRD.5', 'DDRD.6', 'DDRD.7',
+ 'DDRE.0', 'DDRE.1', 'DDRE.2', 'DDRE.3', 'DDRE.4', 'DDRE.5', 'DDRE.6', 'DDRE.7',
+ 'DDRF.0', 'DDRF.1', 'DDRF.2', 'DDRF.3', 'DDRF.4', 'DDRF.5', 'DDRF.6', 'DDRF.7',
+
+ 'DDRA','DDRB','DDRC','DDRD','DDRE','DDRF',
+ 'PORTA','PORTB','PORTC','PORTD','PORTE','PORTF',
+ 'PINA','PINB','PINC','PIND','PINE','PINF',
+ )
+ ),
+ 'SYMBOLS' => array(
+ '=', '<', '>', '>=', '<=', '+', '-', '*', '/', '%', '(', ')', '{', '}', '[', ']', ';', ':', '$', '&H'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000080; font-weight: bold;',
+ 2 => 'color: #FF0000;',
+ 3 => 'color: #0000FF;',
+ 4 => 'color: #0080FF;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #657CC4; font-style: italic;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000080;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000080; font-weight: bold;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #0000FF;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/bash.php b/platform/www/vendor/geshi/geshi/src/geshi/bash.php
new file mode 100644
index 0000000..939b23a
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/bash.php
@@ -0,0 +1,475 @@
+<?php
+/*************************************************************************************
+ * bash.php
+ * --------
+ * Author: Andreas Gohr (andi@splitbrain.org)
+ * Copyright: (c) 2004 Andreas Gohr, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/20
+ *
+ * BASH language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/06/21 (1.0.8)
+ * - Added loads of keywords and commands of GNU/Linux
+ * - Added support for parameters starting with a dash
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2007/09/05 (1.0.7.21)
+ * - PARSER_CONTROL patch using SF #1788408 (BenBE)
+ * 2007/06/11 (1.0.7.20)
+ * - Added a lot of keywords (BenBE / Jan G)
+ * 2004/11/27 (1.0.2)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ * - Added support for URLs
+ * 2004/08/20 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Get symbols working
+ * * Highlight builtin vars
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Bash',
+ // Bash DOES have single line comments with # markers. But bash also has
+ // the $# variable, so comments need special handling (see sf.net
+ // 1564839)
+ 'COMMENT_SINGLE' => array('#'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ //Variables
+ 1 => "/\\$\\{[^\\n\\}]*?\\}/i",
+ //BASH-style Heredoc
+ 2 => '/<<-?\s*?(\'?)([a-zA-Z0-9]+)\1\\n.*\\n\\2(?![a-zA-Z0-9])/siU',
+ //Escaped String Starters
+ 3 => "/\\\\['\"]/siU",
+ // Single-Line Shell usage: Hide the prompt at the beginning
+ /* 4 => "/\A(?!#!)\s*(?>[\w:@\\/\\-\\._~]*[$#]\s?)?(?=[^\n]+\n?\Z)|^(?!#!)(\w+@)?[\w\\-\\.]+(:~?)[\w\\/\\-\\._]*?[$#]\s?/ms" */
+ 4 => "/\A(?!#!)(?:(?>[\w:@\\/\\-\\._~]*)[$#]\s?)(?=(?>[^\n]+)\n?\Z)|^(?!#!)(?:\w+@)?(?>[\w\\-\\.]+)(?>:~?[\w\\/\\-\\._]*?)?[$#]\s?/sm"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array("\'"),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[nfrtv\\$\\\"\n]#i",
+ // $var
+ 2 => "#\\$[a-z_][a-z0-9_]*#i",
+ // ${...}
+ 3 => "/\\$\\{[^\\n\\}]*?\\}/i",
+ // $(...)
+ 4 => "/\\$\\([^\\n\\)]*?\\)/i",
+ // `...`
+ 5 => "/`[^`]*`/"
+ ),
+ 'KEYWORDS' => array(
+ // Control flow keywords and super-important builtins
+ 1 => array(
+ 'case', 'do', 'done', 'elif', 'else', 'esac', 'fi', 'for', 'function',
+ 'if', 'in', 'select', 'set', 'then', 'time', 'until', 'while'
+ ),
+ // Common Unix commands
+ 2 => array(
+ 'aclocal', 'aconnect', 'apachectl', 'apache2ctl', 'aplay', 'apm',
+ 'apmsleep', 'apropos', 'apt-cache', 'apt-cdrom', 'apt-config',
+ 'apt-file', 'apt-ftparchive', 'apt-get', 'apt-key', 'apt-listbugs',
+ 'apt-listchanges', 'apt-mark', 'apt-mirror', 'apt-sortpkgs',
+ 'apt-src', 'apticron', 'aptitude', 'aptsh', 'apxs', 'apxs2', 'ar',
+ 'arch', 'arecord', 'as', 'as86', 'ash', 'autoconf', 'autoheader',
+ 'automake', 'awk',
+
+ 'apachectl start', 'apachectl stop', 'apachectl restart',
+ 'apachectl graceful', 'apachectl graceful-stop',
+ 'apachectl configtest', 'apachectl status', 'apachectl fullstatus',
+ 'apachectl help', 'apache2ctl start', 'apache2ctl stop',
+ 'apache2ctl restart', 'apache2ctl graceful',
+ 'apache2ctl graceful-stop', 'apache2ctl configtest',
+ 'apache2ctl status', 'apache2ctl fullstatus', 'apache2ctl help',
+
+ 'apt-cache add', 'apt-cache depends', 'apt-cache dotty',
+ 'apt-cache dump', 'apt-cache dumpavail', 'apt-cache gencaches',
+ 'apt-cache pkgnames', 'apt-cache policy', 'apt-cache rdepends',
+ 'apt-cache search', 'apt-cache show', 'apt-cache showauto',
+ 'apt-cache showpkg', 'apt-cache showsrc', 'apt-cache stats',
+ 'apt-cache unmet', 'apt-cache xvcg', 'apt-cdrom add',
+ 'apt-cdrom ident', 'apt-config dump', 'apt-config shell',
+ 'apt-file find', 'apt-file list', 'apt-file purge',
+ 'apt-file search', 'apt-file shot', 'apt-file update',
+ 'apt-get autoclean', 'apt-get autoremove', 'apt-get build-dep',
+ 'apt-get check', 'apt-get clean', 'apt-get dist-upgrade',
+ 'apt-get dselect-upgrade', 'apt-get install', 'apt-get markauto',
+ 'apt-get purge', 'apt-get remove', 'apt-get source',
+ 'apt-get unmarkauto', 'apt-get update', 'apt-get upgrade',
+ 'apt-key add', 'apt-key adv', 'apt-key del', 'apt-key export',
+ 'apt-key exportall', 'apt-key finger', 'apt-key list',
+ 'apt-key net-update', 'apt-key update', 'apt-listbugs apt',
+ 'apt-listbugs list', 'apt-listbugs rss', 'apt-src build',
+ 'apt-src clean', 'apt-src import', 'apt-src install',
+ 'apt-src list', 'apt-src location', 'apt-src name',
+ 'apt-src remove', 'apt-src update', 'apt-src upgrade',
+ 'apt-src version',
+
+ 'aptitude autoclean', 'aptitude build-dep', 'aptitude changelog',
+ 'aptitude clean', 'aptitude download', 'aptitude forbid-version',
+ 'aptitude forget-new', 'aptitude full-upgrade', 'aptitude hold',
+ 'aptitude install', 'aptitude markauto', 'aptitude purge',
+ 'aptitude reinstall', 'aptitude remove', 'aptitude safe-upgrade',
+ 'aptitude search', 'aptitude show', 'aptitude unhold',
+ 'aptitude unmarkauto', 'aptitude update', 'aptitude versions',
+ 'aptitude why', 'aptitude why-not',
+
+ 'basename', 'bash', 'batctl', 'bc', 'bison', 'bunzip2', 'bzcat',
+ 'bzcmp', 'bzdiff', 'bzegrep', 'bzfgrep', 'bzgrep',
+ 'bzip2', 'bzip2recover', 'bzless', 'bzmore',
+
+ 'c++', 'cal', 'cat', 'chattr', 'cc', 'cdda2wav', 'cdparanoia',
+ 'cdrdao', 'cd-read', 'cdrecord', 'chfn', 'chgrp', 'chmod',
+ 'chown', 'chroot', 'chsh', 'chvt', 'clear', 'cmp', 'comm', 'co',
+ 'col', 'cp', 'cpio', 'cpp', 'csh', 'cut', 'cvs', 'cvs-pserver',
+
+ 'cvs add', 'cvs admin', 'cvs annotate', 'cvs checkout',
+ 'cvs commit', 'cvs diff', 'cvs edit', 'cvs editors', 'cvs export',
+ 'cvs history', 'cvs import', 'cvs init', 'cvs log', 'cvs login',
+ 'cvs logout', 'cvs ls', 'cvs pserver', 'cvs rannotate',
+ 'cvs rdiff', 'cvs release', 'cvs remove', 'cvs rlog', 'cvs rls',
+ 'cvs rtag', 'cvs server', 'cvs status', 'cvs tag', 'cvs unedit',
+ 'cvs update', 'cvs version', 'cvs watch', 'cvs watchers',
+
+ 'dash', 'date', 'dc', 'dch', 'dcop', 'dd', 'ddate', 'ddd',
+ 'deallocvt', 'debconf', 'defoma', 'depmod', 'df', 'dh',
+ 'dialog', 'diff', 'diff3', 'dig', 'dir', 'dircolors', 'directomatic',
+ 'dirname', 'dmesg', 'dnsdomainname', 'domainname', 'dpkg',
+ 'dselect', 'du', 'dumpkeys',
+
+ 'ed', 'egrep', 'env', 'expr',
+
+ 'false', 'fbset', 'fdisk', 'ffmpeg', 'fgconsole','fgrep', 'file',
+ 'find', 'flex', 'flex++', 'fmt', 'free', 'ftp', 'funzip', 'fuser',
+
+ 'g++', 'gawk', 'gc','gcc', 'gdb', 'gdisk', 'getent', 'getkeycodes',
+ 'getopt', 'gettext', 'gettextize', 'gimp', 'gimp-remote',
+ 'gimptool', 'gmake', 'gocr', 'grep', 'groups', 'gs', 'gunzip',
+ 'gzexe', 'gzip',
+
+ 'git', 'git add', 'git add--interactive', 'git am', 'git annotate',
+ 'git apply', 'git archive', 'git bisect', 'git bisect--helper',
+ 'git blame', 'git branch', 'git bundle', 'git cat-file',
+ 'git check-attr', 'git checkout', 'git checkout-index',
+ 'git check-ref-format', 'git cherry', 'git cherry-pick',
+ 'git clean', 'git clone', 'git commit', 'git commit-tree',
+ 'git config', 'git count-objects', 'git daemon', 'git describe',
+ 'git diff', 'git diff-files', 'git diff-index', 'git difftool',
+ 'git difftool--helper', 'git diff-tree', 'git fast-export',
+ 'git fast-import', 'git fetch', 'git fetch-pack',
+ 'git filter-branch', 'git fmt-merge-msg', 'git for-each-ref',
+ 'git format-patch', 'git fsck', 'git fsck-objects', 'git gc', 'git gui',
+ 'git get-tar-commit-id', 'git grep', 'git hash-object', 'git help',
+ 'git http-backend', 'git http-fetch', 'git http-push',
+ 'git imap-send', 'git index-pack', 'git init', 'git init-db',
+ 'git instaweb', 'git log', 'git lost-found', 'git ls-files',
+ 'git ls-remote', 'git ls-tree', 'git mailinfo', 'git mailsplit',
+ 'git merge', 'git merge-base', 'git merge-file', 'git merge-index',
+ 'git merge-octopus', 'git merge-one-file', 'git merge-ours',
+ 'git merge-recursive', 'git merge-resolve', 'git merge-subtree',
+ 'git mergetool', 'git merge-tree', 'git mktag', 'git mktree',
+ 'git mv', 'git name-rev', 'git notes', 'git pack-objects',
+ 'git pack-redundant', 'git pack-refs', 'git patch-id',
+ 'git peek-remote', 'git prune', 'git prune-packed', 'git pull',
+ 'git push', 'git quiltimport', 'git read-tree', 'git rebase',
+ 'git rebase--interactive', 'git receive-pack', 'git reflog',
+ 'git relink', 'git remote', 'git remote-ftp', 'git remote-ftps',
+ 'git remote-http', 'git remote-https', 'git remote-testgit',
+ 'git repack', 'git replace', 'git repo-config', 'git request-pull',
+ 'git rerere', 'git reset', 'git revert', 'git rev-list',
+ 'git rev-parse', 'git rm', 'git send-pack', 'git shell',
+ 'git shortlog', 'git show', 'git show-branch', 'git show-index',
+ 'git show-ref', 'git stage', 'git stash', 'git status',
+ 'git stripspace', 'git submodule', 'git symbolic-ref', 'git tag',
+ 'git tar-tree', 'git unpack-file', 'git unpack-objects',
+ 'git update-index', 'git update-ref', 'git update-server-info',
+ 'git upload-archive', 'git upload-pack', 'git var',
+ 'git verify-pack', 'git verify-tag', 'git web--browse',
+ 'git whatchanged', 'git write-tree',
+
+ 'gitaction', 'git-add', 'git-add--interactive', 'git-am',
+ 'git-annotate', 'git-apply', 'git-archive', 'git-bisect',
+ 'git-bisect--helper', 'git-blame', 'git-branch', 'git-bundle',
+ 'git-cat-file', 'git-check-attr', 'git-checkout',
+ 'git-checkout-index', 'git-check-ref-format', 'git-cherry',
+ 'git-cherry-pick', 'git-clean', 'git-clone', 'git-commit',
+ 'git-commit-tree', 'git-config', 'git-count-objects', 'git-daemon',
+ 'git-describe', 'git-diff', 'git-diff-files', 'git-diff-index',
+ 'git-difftool', 'git-difftool--helper', 'git-diff-tree',
+ 'gitdpkgname', 'git-fast-export', 'git-fast-import', 'git-fetch',
+ 'git-fetch-pack', 'git-fetch--tool', 'git-filter-branch', 'gitfm',
+ 'git-fmt-merge-msg', 'git-for-each-ref', 'git-format-patch',
+ 'git-fsck', 'git-fsck-objects', 'git-gc', 'git-get-tar-commit-id',
+ 'git-grep', 'git-hash-object', 'git-help', 'git-http-fetch',
+ 'git-http-push', 'git-imap-send', 'git-index-pack', 'git-init',
+ 'git-init-db', 'git-instaweb', 'gitkeys', 'git-log',
+ 'git-lost-found', 'git-ls-files', 'git-ls-remote', 'git-ls-tree',
+ 'git-mailinfo', 'git-mailsplit', 'git-merge', 'git-merge-base',
+ 'git-merge-file', 'git-merge-index', 'git-merge-octopus',
+ 'git-merge-one-file', 'git-merge-ours', 'git-merge-recursive',
+ 'git-merge-resolve', 'git-merge-subtree', 'git-mergetool',
+ 'git-mergetool--lib', 'git-merge-tree', 'gitmkdirs', 'git-mktag',
+ 'git-mktree', 'gitmount', 'git-mv', 'git-name-rev',
+ 'git-pack-objects', 'git-pack-redundant', 'git-pack-refs',
+ 'git-parse-remote', 'git-patch-id', 'git-peek-remote', 'git-prune',
+ 'git-prune-packed', 'gitps', 'git-pull', 'git-push',
+ 'git-quiltimport', 'git-read-tree', 'git-rebase',
+ 'git-rebase--interactive', 'git-receive-pack', 'git-reflog',
+ 'gitregrep', 'git-relink', 'git-remote', 'git-repack',
+ 'git-repo-config', 'git-request-pull', 'git-rerere', 'git-reset',
+ 'git-revert', 'git-rev-list', 'git-rev-parse', 'gitrfgrep',
+ 'gitrgrep', 'git-rm', 'git-send-pack', 'git-shell', 'git-shortlog',
+ 'git-show', 'git-show-branch', 'git-show-index', 'git-show-ref',
+ 'git-sh-setup', 'git-stage', 'git-stash', 'git-status',
+ 'git-stripspace', 'git-submodule', 'git-svn', 'git-symbolic-ref',
+ 'git-tag', 'git-tar-tree', 'gitunpack', 'git-unpack-file',
+ 'git-unpack-objects', 'git-update-index', 'git-update-ref',
+ 'git-update-server-info', 'git-upload-archive', 'git-upload-pack',
+ 'git-var', 'git-verify-pack', 'git-verify-tag', 'gitview',
+ 'git-web--browse', 'git-whatchanged', 'gitwhich', 'gitwipe',
+ 'git-write-tree', 'gitxgrep',
+
+ 'head', 'hexdump', 'hostname', 'htop',
+
+ 'id', 'ifconfig', 'ifdown', 'ifup', 'igawk', 'install',
+
+ 'ip', 'ip addr', 'ip addrlabel', 'ip link', 'ip maddr', 'ip mroute',
+ 'ip neigh', 'ip route', 'ip rule', 'ip tunnel', 'ip xfrm',
+
+ 'jar', 'java', 'javac', 'join',
+
+ 'kbd_mode','kbdrate', 'kdialog', 'kfile', 'killall',
+
+ 'lame', 'last', 'lastb', 'ld', 'ld86', 'ldd', 'less', 'lex', 'link',
+ 'ln', 'loadkeys', 'loadunimap', 'locate', 'lockfile', 'login',
+ 'logname', 'lp', 'lpr', 'ls', 'lsattr', 'lsmod', 'lsmod.old',
+ 'lspci', 'ltrace', 'lynx',
+
+ 'm4', 'make', 'man', 'mapscrn', 'mesg', 'mkdir', 'mkfifo',
+ 'mknod', 'mktemp', 'more', 'mount', 'mplayer', 'msgfmt', 'mv',
+
+ 'namei', 'nano', 'nasm', 'nawk', 'netstat', 'nice',
+ 'nisdomainname', 'nl', 'nm', 'nm86', 'nmap', 'nohup', 'nop',
+
+ 'od', 'openvt',
+
+ 'passwd', 'patch', 'pbzip2', 'pcregrep', 'pcretest', 'perl',
+ 'perror', 'pgawk', 'pidof', 'pigz', 'ping', 'pr', 'procmail',
+ 'prune', 'ps', 'pstree', 'ps2ascii', 'ps2epsi', 'ps2frag',
+ 'ps2pdf', 'ps2ps', 'psbook', 'psmerge', 'psnup', 'psresize',
+ 'psselect', 'pstops',
+
+ 'rbash', 'rcs', 'rcs2log', 'readlink', 'red', 'resizecons',
+ 'rev', 'rm', 'rmdir', 'rsh', 'run-parts',
+
+ 'sash', 'scp', 'screen', 'sed', 'seq', 'sendmail', 'setfont',
+ 'setkeycodes', 'setleds', 'setmetamode', 'setserial', 'setterm',
+ 'sh', 'showkey', 'shred', 'size', 'size86', 'skill', 'sleep',
+ 'slogin', 'snice', 'sort', 'sox', 'split', 'ssed', 'ssh', 'ssh-add',
+ 'ssh-agent', 'ssh-keygen', 'ssh-keyscan', 'sshfs', 'stat', 'strace',
+ 'strings', 'strip', 'stty', 'su', 'sudo', 'suidperl', 'sum', 'svn',
+ 'svnadmin', 'svndumpfilter', 'svnlook', 'svnmerge', 'svnmucc',
+ 'svnserve', 'svnshell', 'svnsync', 'svnversion', 'svnwrap', 'sync',
+
+ 'svn add', 'svn ann', 'svn annotate', 'svn blame', 'svn cat',
+ 'svn changelist', 'svn checkout', 'svn ci', 'svn cl', 'svn cleanup',
+ 'svn co', 'svn commit', 'svn copy', 'svn cp', 'svn del',
+ 'svn delete', 'svn di', 'svn diff', 'svn export', 'svn help',
+ 'svn import', 'svn info', 'svn list', 'svn lock', 'svn log',
+ 'svn ls', 'svn merge', 'svn mergeinfo', 'svn mkdir', 'svn move',
+ 'svn mv', 'svn patch', 'svn pd', 'svn pdel', 'svn pe', 'svn pedit',
+ 'svn pg', 'svn pget', 'svn pl', 'svn plist', 'svn praise',
+ 'svn propdel', 'svn propedit', 'svn propget', 'svn proplist',
+ 'svn propset', 'svn ps', 'svn pset', 'svn relocate', 'svn remove',
+ 'svn rename', 'svn resolve', 'svn resolved', 'svn revert', 'svn rm',
+ 'svn st', 'svn stat', 'svn status', 'svn sw', 'svn switch',
+ 'svn unlock', 'svn up', 'svn update', 'svn upgrade',
+
+ 'svnadmin crashtest', 'svnadmin create', 'svnadmin deltify',
+ 'svnadmin dump', 'svnadmin help', 'svnadmin hotcopy',
+ 'svnadmin list-dblogs', 'svnadmin list-unused-dblogs',
+ 'svnadmin load', 'svnadmin lslocks', 'svnadmin lstxns',
+ 'svnadmin pack', 'svnadmin recover', 'svnadmin rmlocks',
+ 'svnadmin rmtxns', 'svnadmin setlog', 'svnadmin setrevprop',
+ 'svnadmin setuuid', 'svnadmin upgrade', 'svnadmin verify',
+
+ 'svndumpfilter exclude', 'svndumpfilter help',
+ 'svndumpfilter include',
+
+ 'svnlook author', 'svnlook cat', 'svnlook changed', 'svnlook date',
+ 'svnlook diff', 'svnlook dirs-changed', 'svnlook filesize',
+ 'svnlook help', 'svnlook history', 'svnlook info', 'svnlook lock',
+ 'svnlook log', 'svnlook pg', 'svnlook pget', 'svnlook pl',
+ 'svnlook plist', 'svnlook propget', 'svnlook proplist',
+ 'svnlook tree', 'svnlook uuid', 'svnlook youngest',
+
+ 'svnrdump dump', 'svnrdump help', 'svnrdump load',
+
+ 'svnsync copy-revprops', 'svnsync help', 'svnsync info',
+ 'svnsync init', 'svnsync initialize', 'svnsync sync',
+ 'svnsync synchronize',
+
+ 'tac', 'tail', 'tar', 'tee', 'tempfile', 'touch', 'tr', 'tree',
+ 'true',
+
+ 'umount', 'uname', 'unicode_start', 'unicode_stop', 'uniq',
+ 'unlink', 'unzip', 'updatedb', 'updmap', 'uptime', 'users',
+ 'utmpdump', 'uuidgen',
+
+ 'valgrind', 'vdir', 'vi', 'vim', 'vmstat',
+
+ 'w', 'wall', 'watch', 'wc', 'wget', 'whatis', 'whereis',
+ 'which', 'whiptail', 'who', 'whoami', 'whois', 'wine', 'wineboot',
+ 'winebuild', 'winecfg', 'wineconsole', 'winedbg', 'winedump',
+ 'winefile', 'wodim', 'write',
+
+ 'xargs', 'xhost', 'xmodmap', 'xset',
+
+ 'yacc', 'yes', 'ypdomainname', 'yum',
+
+ 'yum check-update', 'yum clean', 'yum deplist', 'yum erase',
+ 'yum groupinfo', 'yum groupinstall', 'yum grouplist',
+ 'yum groupremove', 'yum groupupdate', 'yum info', 'yum install',
+ 'yum list', 'yum localinstall', 'yum localupdate', 'yum makecache',
+ 'yum provides', 'yum remove', 'yum resolvedep', 'yum search',
+ 'yum shell', 'yum update', 'yum upgrade', 'yum whatprovides',
+
+ 'zcat', 'zcmp', 'zdiff', 'zdump', 'zegrep', 'zfgrep', 'zforce',
+ 'zgrep', 'zip', 'zipgrep', 'zipinfo', 'zless', 'zmore', 'znew',
+ 'zsh', 'zsoelim'
+ ),
+ // Builtin commands
+ 3 => array(
+ 'alias', 'bg', 'bind', 'break', 'builtin', 'caller', 'cd', 'command',
+ 'compgen', 'complete', 'compopt', 'continue', 'coproc', 'declare', 'dirs', 'disown',
+ 'echo', 'enable', 'eval', 'exec', 'exit', 'export', 'fc',
+ 'fg', 'getopts', 'hash', 'help', 'history', 'jobs', 'kill', 'let',
+ 'local', 'logout', 'mapfile', 'popd', 'printf', 'pushd', 'pwd', 'read',
+ 'readarray', 'readonly', 'return', 'shift', 'shopt', 'source',
+ 'suspend', 'test', 'times', 'trap', 'type', 'typeset', 'ulimit',
+ 'umask', 'unalias', 'unset', 'wait'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '!', '@', '%', '&', '*', '|', '/', '<', '>', ';;', '`'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #c20cb9; font-weight: bold;',
+ 3 => 'color: #7a0874; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #666666; font-style: italic;',
+ 1 => 'color: #800000;',
+ 2 => 'color: #cc0000; font-style: italic;',
+ 3 => 'color: #000000; font-weight: bold;',
+ 4 => 'color: #666666;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #007800;',
+ 3 => 'color: #007800;',
+ 4 => 'color: #007800;',
+ 5 => 'color: #780078;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #7a0874; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ 'HARD' => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #007800;',
+ 1 => 'color: #007800;',
+ 2 => 'color: #007800;',
+ 4 => 'color: #007800;',
+ 5 => 'color: #660033;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Variables (will be handled by comment_regexps)
+ 0 => "\\$\\{[a-zA-Z_][a-zA-Z0-9_]*?\\}",
+ //Variables without braces
+ 1 => "\\$[a-zA-Z_][a-zA-Z0-9_]*",
+ //Variable assignment
+ 2 => "(?<![\.a-zA-Z_\-])([a-zA-Z_][a-zA-Z0-9_]*?)(?==)",
+ //Shorthand shell variables
+ 4 => "\\$[*#\$\\-\\?!\d]",
+ //Parameters of commands
+ 5 => "(?<=\s)--?[0-9a-zA-Z\-]+(?=[\s=]|<(?:SEMI|PIPE)>|$)"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'COMMENTS' => array(
+ 'DISALLOWED_BEFORE' => '$'
+ ),
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![\.\-a-zA-Z0-9_\$\#:])",
+ 'DISALLOWED_AFTER' => "(?![\.\-a-zA-Z0-9_%=\\/:])",
+ 2 => array(
+ 'SPACE_AS_WHITESPACE' => false
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/basic4gl.php b/platform/www/vendor/geshi/geshi/src/geshi/basic4gl.php
new file mode 100644
index 0000000..ab4b6ef
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/basic4gl.php
@@ -0,0 +1,339 @@
+<?php
+/*************************************************************************************
+ * basic4gl.php
+ * ---------------------------------
+ * Author: Matthew Webb (bmatthew1@blueyonder.co.uk)
+ * Copyright: (c) 2004 Matthew Webb (http://matthew-4gl.wikispaces.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/09/15
+ *
+ * Basic4GL language file for GeSHi.
+ *
+ * You can find the Basic4GL Website at (http://www.basic4gl.net/)
+ *
+ * CHANGES
+ * -------
+ * 2007/09/17 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2007/09/17)
+ * -------------------------
+ * Make sure all the OpenGL and Basic4GL commands have been added and are complete.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Basic4GL',
+ 'COMMENT_SINGLE' => array(1 => "'"),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+
+ // Navy Blue Bold Keywords
+
+ 'true','rnd_max','m_pi','m_e','false','VK_ZOOM','VK_UP','VK_TAB','VK_SUBTRACT','VK_SPACE','VK_SNAPSHOT',
+ 'VK_SHIFT','VK_SEPARATOR','VK_SELECT','VK_SCROLL','VK_RWIN','VK_RSHIFT','VK_RMENU','VK_RIGHT','VK_RETURN',
+ 'VK_RCONTROL','VK_RBUTTON','VK_PROCESSKEY','VK_PRIOR','VK_PRINT','VK_PLAY','VK_PAUSE','VK_NUMPAD9','VK_NUMPAD8',
+ 'VK_NUMPAD7','VK_NUMPAD6','VK_NUMPAD5','VK_NUMPAD4','VK_NUMPAD3','VK_NUMPAD2','VK_NUMPAD1','VK_NUMPAD0',
+ 'VK_NUMLOCK','VK_NONCONVERT','VK_NEXT','VK_MULTIPLY','VK_MODECHANGE','VK_MENU','VK_MBUTTON','VK_LWIN',
+ 'VK_LSHIFT','VK_LMENU','VK_LEFT','VK_LCONTROL','VK_LBUTTON','VK_KANJI','VK_KANA','VK_JUNJA','VK_INSERT',
+ 'VK_HOME','VK_HELP','VK_HANJA','VK_HANGUL','VK_HANGEUL','VK_FINAL','VK_F9','VK_F8','VK_F7','VK_F6','VK_F5',
+ 'VK_F4','VK_F3','VK_F24','VK_F23','VK_F22','VK_F21','VK_F20','VK_F2','VK_F19','VK_F18','VK_F17','VK_F16',
+ 'VK_F15','VK_F14','VK_F13','VK_F12','VK_F11','VK_F10','VK_F1','VK_EXSEL','VK_EXECUTE','VK_ESCAPE','VK_EREOF',
+ 'VK_END','VK_DOWN','VK_DIVIDE','VK_DELETE','VK_DECIMAL','VK_CRSEL','VK_CONVERT','VK_CONTROL','VK_CLEAR',
+ 'VK_CAPITAL','VK_CANCEL','VK_BACK','VK_ATTN','VK_APPS','VK_ADD','VK_ACCEPT','TEXT_SIMPLE','TEXT_OVERLAID',
+ 'TEXT_BUFFERED','SPR_TILEMAP','SPR_SPRITE','SPR_INVALID','MOUSE_RBUTTON','MOUSE_MBUTTON','MOUSE_LBUTTON',
+ 'GL_ZOOM_Y','GL_ZOOM_X','GL_ZERO','GL_XOR','GL_WIN_swap_hint','GL_WIN_draw_range_elements','GL_VIEWPORT_BIT',
+ 'GL_VIEWPORT','GL_VERTEX_ARRAY_TYPE_EXT','GL_VERTEX_ARRAY_TYPE','GL_VERTEX_ARRAY_STRIDE_EXT','GL_VERTEX_ARRAY_STRIDE',
+ 'GL_VERTEX_ARRAY_SIZE_EXT','GL_VERTEX_ARRAY_SIZE','GL_VERTEX_ARRAY_POINTER_EXT','GL_VERTEX_ARRAY_POINTER',
+ 'GL_VERTEX_ARRAY_EXT','GL_VERTEX_ARRAY_COUNT_EXT','GL_VERTEX_ARRAY','GL_VERSION_1_1','GL_VERSION','GL_VENDOR',
+ 'GL_V3F','GL_V2F','GL_UNSIGNED_SHORT','GL_UNSIGNED_INT','GL_UNSIGNED_BYTE','GL_UNPACK_SWAP_BYTES','GL_UNPACK_SKIP_ROWS',
+ 'GL_UNPACK_SKIP_PIXELS','GL_UNPACK_ROW_LENGTH','GL_UNPACK_LSB_FIRST','GL_UNPACK_ALIGNMENT','GL_TRUE','GL_TRIANGLE_STRIP',
+ 'GL_TRIANGLE_FAN','GL_TRIANGLES','GL_TRANSFORM_BIT','GL_TEXTURE_WRAP_T','GL_TEXTURE_WRAP_S','GL_TEXTURE_WIDTH',
+ 'GL_TEXTURE_STACK_DEPTH','GL_TEXTURE_RESIDENT','GL_TEXTURE_RED_SIZE','GL_TEXTURE_PRIORITY','GL_TEXTURE_MIN_FILTER',
+ 'GL_TEXTURE_MATRIX','GL_TEXTURE_MAG_FILTER','GL_TEXTURE_LUMINANCE_SIZE','GL_TEXTURE_INTERNAL_FORMAT','GL_TEXTURE_INTENSITY_SIZE',
+ 'GL_TEXTURE_HEIGHT','GL_TEXTURE_GREEN_SIZE','GL_TEXTURE_GEN_T','GL_TEXTURE_GEN_S','GL_TEXTURE_GEN_R','GL_TEXTURE_GEN_Q',
+ 'GL_TEXTURE_GEN_MODE','GL_TEXTURE_ENV_MODE','GL_TEXTURE_ENV_COLOR','GL_TEXTURE_ENV','GL_TEXTURE_COORD_ARRAY_TYPE_EXT',
+ 'GL_TEXTURE_COORD_ARRAY_TYPE','GL_TEXTURE_COORD_ARRAY_STRIDE_EXT','GL_TEXTURE_COORD_ARRAY_STRIDE','GL_TEXTURE_COORD_ARRAY_SIZE_EXT',
+ 'GL_TEXTURE_COORD_ARRAY_SIZE','GL_TEXTURE_COORD_ARRAY_POINTER_EXT','GL_TEXTURE_COORD_ARRAY_POINTER','GL_TEXTURE_COORD_ARRAY_EXT',
+ 'GL_TEXTURE_COORD_ARRAY_COUNT_EXT','GL_TEXTURE_COORD_ARRAY','GL_TEXTURE_COMPONENTS','GL_TEXTURE_BORDER_COLOR','GL_TEXTURE_BORDER',
+ 'GL_TEXTURE_BLUE_SIZE','GL_TEXTURE_BIT','GL_TEXTURE_BINDING_2D','GL_TEXTURE_BINDING_1D','GL_TEXTURE_ALPHA_SIZE',
+ 'GL_TEXTURE_2D','GL_TEXTURE_1D','GL_TEXTURE9_ARB','GL_TEXTURE9','GL_TEXTURE8_ARB','GL_TEXTURE8','GL_TEXTURE7_ARB',
+ 'GL_TEXTURE7','GL_TEXTURE6_ARB','GL_TEXTURE6','GL_TEXTURE5_ARB','GL_TEXTURE5','GL_TEXTURE4_ARB','GL_TEXTURE4',
+ 'GL_TEXTURE3_ARB','GL_TEXTURE31_ARB','GL_TEXTURE31','GL_TEXTURE30_ARB','GL_TEXTURE30','GL_TEXTURE3','GL_TEXTURE2_ARB',
+ 'GL_TEXTURE29_ARB','GL_TEXTURE29','GL_TEXTURE28_ARB','GL_TEXTURE28','GL_TEXTURE27_ARB','GL_TEXTURE27','GL_TEXTURE26_ARB',
+ 'GL_TEXTURE26','GL_TEXTURE25_ARB','GL_TEXTURE25','GL_TEXTURE24_ARB','GL_TEXTURE24','GL_TEXTURE23_ARB','GL_TEXTURE23',
+ 'GL_TEXTURE22_ARB','GL_TEXTURE22','GL_TEXTURE21_ARB','GL_TEXTURE21','GL_TEXTURE20_ARB','GL_TEXTURE20','GL_TEXTURE2',
+ 'GL_TEXTURE1_ARB','GL_TEXTURE19_ARB','GL_TEXTURE19','GL_TEXTURE18_ARB','GL_TEXTURE18','GL_TEXTURE17_ARB',
+ 'GL_TEXTURE17','GL_TEXTURE16_ARB','GL_TEXTURE16','GL_TEXTURE15_ARB','GL_TEXTURE15','GL_TEXTURE14_ARB','GL_TEXTURE14',
+ 'GL_TEXTURE13_ARB','GL_TEXTURE13','GL_TEXTURE12_ARB','GL_TEXTURE12','GL_TEXTURE11_ARB','GL_TEXTURE11','GL_TEXTURE10_ARB',
+ 'GL_TEXTURE10','GL_TEXTURE1','GL_TEXTURE0_ARB','GL_TEXTURE0','GL_TEXTURE','GL_T4F_V4F','GL_T4F_C4F_N3F_V4F','GL_T2F_V3F',
+ 'GL_T2F_N3F_V3F','GL_T2F_C4UB_V3F','GL_T2F_C4F_N3F_V3F','GL_T2F_C3F_V3F','GL_T','GL_SUBPIXEL_BITS','GL_STEREO',
+ 'GL_STENCIL_WRITEMASK','GL_STENCIL_VALUE_MASK','GL_STENCIL_TEST','GL_STENCIL_REF','GL_STENCIL_PASS_DEPTH_PASS',
+ 'GL_STENCIL_PASS_DEPTH_FAIL','GL_STENCIL_INDEX','GL_STENCIL_FUNC','GL_STENCIL_FAIL','GL_STENCIL_CLEAR_VALUE',
+ 'GL_STENCIL_BUFFER_BIT','GL_STENCIL_BITS','GL_STENCIL','GL_STACK_UNDERFLOW','GL_STACK_OVERFLOW','GL_SRC_COLOR',
+ 'GL_SRC_ALPHA_SATURATE','GL_SRC_ALPHA','GL_SPOT_EXPONENT','GL_SPOT_DIRECTION','GL_SPOT_CUTOFF','GL_SPHERE_MAP',
+ 'GL_SPECULAR','GL_SOURCE2_RGB_EXT','GL_SOURCE2_RGB','GL_SOURCE2_ALPHA_EXT','GL_SOURCE2_ALPHA','GL_SOURCE1_RGB_EXT',
+ 'GL_SOURCE1_RGB','GL_SOURCE1_ALPHA_EXT','GL_SOURCE1_ALPHA','GL_SOURCE0_RGB_EXT','GL_SOURCE0_RGB','GL_SOURCE0_ALPHA_EXT',
+ 'GL_SOURCE0_ALPHA','GL_SMOOTH','GL_SHORT','GL_SHININESS','GL_SHADE_MODEL','GL_SET','GL_SELECTION_BUFFER_SIZE',
+ 'GL_SELECTION_BUFFER_POINTER','GL_SELECT','GL_SCISSOR_TEST','GL_SCISSOR_BOX','GL_SCISSOR_BIT','GL_S','GL_RIGHT',
+ 'GL_RGB_SCALE_EXT','GL_RGB_SCALE','GL_RGBA_MODE','GL_RGBA8','GL_RGBA4','GL_RGBA2','GL_RGBA16','GL_RGBA12','GL_RGBA',
+ 'GL_RGB8','GL_RGB5_A1','GL_RGB5','GL_RGB4','GL_RGB16','GL_RGB12','GL_RGB10_A2','GL_RGB10','GL_RGB','GL_RETURN',
+ 'GL_REPLACE','GL_REPEAT','GL_RENDER_MODE','GL_RENDERER','GL_RENDER','GL_RED_SCALE','GL_RED_BITS','GL_RED_BIAS',
+ 'GL_RED','GL_READ_BUFFER','GL_R3_G3_B2','GL_R','GL_QUAD_STRIP','GL_QUADS','GL_QUADRATIC_ATTENUATION','GL_Q',
+ 'GL_PROXY_TEXTURE_2D','GL_PROXY_TEXTURE_1D','GL_PROJECTION_STACK_DEPTH','GL_PROJECTION_MATRIX','GL_PROJECTION',
+ 'GL_PRIMARY_COLOR_EXT','GL_PRIMARY_COLOR','GL_PREVIOUS_EXT','GL_PREVIOUS','GL_POSITION','GL_POLYGON_TOKEN',
+ 'GL_POLYGON_STIPPLE_BIT','GL_POLYGON_STIPPLE','GL_POLYGON_SMOOTH_HINT','GL_POLYGON_SMOOTH','GL_POLYGON_OFFSET_UNITS',
+ 'GL_POLYGON_OFFSET_POINT','GL_POLYGON_OFFSET_LINE','GL_POLYGON_OFFSET_FILL','GL_POLYGON_OFFSET_FACTOR','GL_POLYGON_MODE',
+ 'GL_POLYGON_BIT','GL_POLYGON','GL_POINT_TOKEN','GL_POINT_SMOOTH_HINT','GL_POINT_SMOOTH','GL_POINT_SIZE_RANGE',
+ 'GL_POINT_SIZE_GRANULARITY','GL_POINT_SIZE','GL_POINT_BIT','GL_POINTS','GL_POINT','GL_PIXEL_MODE_BIT',
+ 'GL_PIXEL_MAP_S_TO_S_SIZE','GL_PIXEL_MAP_S_TO_S','GL_PIXEL_MAP_R_TO_R_SIZE','GL_PIXEL_MAP_R_TO_R','GL_PIXEL_MAP_I_TO_R_SIZE',
+ 'GL_PIXEL_MAP_I_TO_R','GL_PIXEL_MAP_I_TO_I_SIZE','GL_PIXEL_MAP_I_TO_I','GL_PIXEL_MAP_I_TO_G_SIZE','GL_PIXEL_MAP_I_TO_G',
+ 'GL_PIXEL_MAP_I_TO_B_SIZE','GL_PIXEL_MAP_I_TO_B','GL_PIXEL_MAP_I_TO_A_SIZE','GL_PIXEL_MAP_I_TO_A','GL_PIXEL_MAP_G_TO_G_SIZE',
+ 'GL_PIXEL_MAP_G_TO_G','GL_PIXEL_MAP_B_TO_B_SIZE','GL_PIXEL_MAP_B_TO_B','GL_PIXEL_MAP_A_TO_A_SIZE','GL_PIXEL_MAP_A_TO_A',
+ 'GL_PHONG_WIN','GL_PHONG_HINT_WIN','GL_PERSPECTIVE_CORRECTION_HINT','GL_PASS_THROUGH_TOKEN','GL_PACK_SWAP_BYTES',
+ 'GL_PACK_SKIP_ROWS','GL_PACK_SKIP_PIXELS','GL_PACK_ROW_LENGTH','GL_PACK_LSB_FIRST','GL_PACK_ALIGNMENT','GL_OUT_OF_MEMORY',
+ 'GL_OR_REVERSE','GL_OR_INVERTED','GL_ORDER','GL_OR','GL_OPERAND2_RGB_EXT','GL_OPERAND2_RGB','GL_OPERAND2_ALPHA_EXT',
+ 'GL_OPERAND2_ALPHA','GL_OPERAND1_RGB_EXT','GL_OPERAND1_RGB','GL_OPERAND1_ALPHA_EXT','GL_OPERAND1_ALPHA','GL_OPERAND0_RGB_EXT',
+ 'GL_OPERAND0_RGB','GL_OPERAND0_ALPHA_EXT','GL_OPERAND0_ALPHA','GL_ONE_MINUS_SRC_COLOR','GL_ONE_MINUS_SRC_ALPHA',
+ 'GL_ONE_MINUS_DST_COLOR','GL_ONE_MINUS_DST_ALPHA','GL_ONE','GL_OBJECT_PLANE','GL_OBJECT_LINEAR','GL_NO_ERROR',
+ 'GL_NOTEQUAL','GL_NORMAL_ARRAY_TYPE_EXT','GL_NORMAL_ARRAY_TYPE','GL_NORMAL_ARRAY_STRIDE_EXT','GL_NORMAL_ARRAY_STRIDE',
+ 'GL_NORMAL_ARRAY_POINTER_EXT','GL_NORMAL_ARRAY_POINTER','GL_NORMAL_ARRAY_EXT','GL_NORMAL_ARRAY_COUNT_EXT',
+ 'GL_NORMAL_ARRAY','GL_NORMALIZE','GL_NOR','GL_NOOP','GL_NONE','GL_NICEST','GL_NEVER','GL_NEAREST_MIPMAP_NEAREST','GL_NEAREST_MIPMAP_LINEAR',
+ 'GL_NEAREST','GL_NAND','GL_NAME_STACK_DEPTH','GL_N3F_V3F','GL_MULT','GL_MODULATE','GL_MODELVIEW_STACK_DEPTH','GL_MODELVIEW_MATRIX',
+ 'GL_MODELVIEW','GL_MAX_VIEWPORT_DIMS','GL_MAX_TEXTURE_UNITS_ARB','GL_MAX_TEXTURE_UNITS','GL_MAX_TEXTURE_STACK_DEPTH',
+ 'GL_MAX_TEXTURE_SIZE','GL_MAX_PROJECTION_STACK_DEPTH','GL_MAX_PIXEL_MAP_TABLE','GL_MAX_NAME_STACK_DEPTH','GL_MAX_MODELVIEW_STACK_DEPTH',
+ 'GL_MAX_LIST_NESTING','GL_MAX_LIGHTS','GL_MAX_EVAL_ORDER','GL_MAX_ELEMENTS_VERTICES_WIN','GL_MAX_ELEMENTS_INDICES_WIN',
+ 'GL_MAX_CLIP_PLANES','GL_MAX_CLIENT_ATTRIB_STACK_DEPTH','GL_MAX_ATTRIB_STACK_DEPTH','GL_MATRIX_MODE','GL_MAP_STENCIL',
+ 'GL_MAP_COLOR','GL_MAP2_VERTEX_4','GL_MAP2_VERTEX_3','GL_MAP2_TEXTURE_COORD_4','GL_MAP2_TEXTURE_COORD_3','GL_MAP2_TEXTURE_COORD_2',
+ 'GL_MAP2_TEXTURE_COORD_1','GL_MAP2_NORMAL','GL_MAP2_INDEX','GL_MAP2_GRID_SEGMENTS','GL_MAP2_GRID_DOMAIN','GL_MAP2_COLOR_4',
+ 'GL_MAP1_VERTEX_4','GL_MAP1_VERTEX_3','GL_MAP1_TEXTURE_COORD_4','GL_MAP1_TEXTURE_COORD_3','GL_MAP1_TEXTURE_COORD_2',
+ 'GL_MAP1_TEXTURE_COORD_1','GL_MAP1_NORMAL','GL_MAP1_INDEX','GL_MAP1_GRID_SEGMENTS','GL_MAP1_GRID_DOMAIN',
+ 'GL_MAP1_COLOR_4','GL_LUMINANCE_ALPHA','GL_LUMINANCE8_ALPHA8','GL_LUMINANCE8','GL_LUMINANCE6_ALPHA2','GL_LUMINANCE4_ALPHA4',
+ 'GL_LUMINANCE4','GL_LUMINANCE16_ALPHA16','GL_LUMINANCE16','GL_LUMINANCE12_ALPHA4','GL_LUMINANCE12_ALPHA12','GL_LUMINANCE12',
+ 'GL_LUMINANCE','GL_LOGIC_OP_MODE','GL_LOGIC_OP','GL_LOAD','GL_LIST_MODE','GL_LIST_INDEX','GL_LIST_BIT',
+ 'GL_LIST_BASE','GL_LINE_WIDTH_RANGE','GL_LINE_WIDTH_GRANULARITY','GL_LINE_WIDTH','GL_LINE_TOKEN','GL_LINE_STRIP','GL_LINE_STIPPLE_REPEAT',
+ 'GL_LINE_STIPPLE_PATTERN','GL_LINE_STIPPLE','GL_LINE_SMOOTH_HINT','GL_LINE_SMOOTH','GL_LINE_RESET_TOKEN','GL_LINE_LOOP',
+ 'GL_LINE_BIT','GL_LINES','GL_LINEAR_MIPMAP_NEAREST','GL_LINEAR_MIPMAP_LINEAR','GL_LINEAR_ATTENUATION','GL_LINEAR',
+ 'GL_LINE','GL_LIGHT_MODEL_TWO_SIDE','GL_LIGHT_MODEL_LOCAL_VIEWER','GL_LIGHT_MODEL_AMBIENT','GL_LIGHTING_BIT',
+ 'GL_LIGHTING','GL_LIGHT7','GL_LIGHT6','GL_LIGHT5','GL_LIGHT4','GL_LIGHT3','GL_LIGHT2','GL_LIGHT1','GL_LIGHT0',
+ 'GL_LESS','GL_LEQUAL','GL_LEFT','GL_KEEP','GL_INVERT','GL_INVALID_VALUE','GL_INVALID_OPERATION','GL_INVALID_ENUM','GL_INTERPOLATE_EXT',
+ 'GL_INTERPOLATE','GL_INTENSITY8','GL_INTENSITY4','GL_INTENSITY16','GL_INTENSITY12','GL_INTENSITY','GL_INT',
+ 'GL_INDEX_WRITEMASK','GL_INDEX_SHIFT','GL_INDEX_OFFSET','GL_INDEX_MODE','GL_INDEX_LOGIC_OP','GL_INDEX_CLEAR_VALUE','GL_INDEX_BITS',
+ 'GL_INDEX_ARRAY_TYPE_EXT','GL_INDEX_ARRAY_TYPE','GL_INDEX_ARRAY_STRIDE_EXT','GL_INDEX_ARRAY_STRIDE','GL_INDEX_ARRAY_POINTER_EXT',
+ 'GL_INDEX_ARRAY_POINTER','GL_INDEX_ARRAY_EXT','GL_INDEX_ARRAY_COUNT_EXT','GL_INDEX_ARRAY','GL_INCR','GL_HINT_BIT',
+ 'GL_GREEN_SCALE','GL_GREEN_BITS','GL_GREEN_BIAS','GL_GREEN','GL_GREATER','GL_GEQUAL','GL_FRONT_RIGHT','GL_FRONT_LEFT',
+ 'GL_FRONT_FACE','GL_FRONT_AND_BACK','GL_FRONT','GL_FOG_START','GL_FOG_SPECULAR_TEXTURE_WIN','GL_FOG_MODE','GL_FOG_INDEX',
+ 'GL_FOG_HINT','GL_FOG_END','GL_FOG_DENSITY','GL_FOG_COLOR','GL_FOG_BIT','GL_FOG','GL_FLOAT','GL_FLAT','GL_FILL',
+ 'GL_FEEDBACK_BUFFER_TYPE','GL_FEEDBACK_BUFFER_SIZE','GL_FEEDBACK_BUFFER_POINTER','GL_FEEDBACK','GL_FASTEST','GL_FALSE',
+ 'GL_EYE_PLANE','GL_EYE_LINEAR','GL_EXT_vertex_array','GL_EXT_paletted_texture','GL_EXT_bgra','GL_EXTENSIONS','GL_EXP2',
+ 'GL_EXP','GL_EVAL_BIT','GL_EQUIV','GL_EQUAL','GL_ENABLE_BIT','GL_EMISSION','GL_EDGE_FLAG_ARRAY_STRIDE_EXT','GL_EDGE_FLAG_ARRAY_STRIDE',
+ 'GL_EDGE_FLAG_ARRAY_POINTER_EXT','GL_EDGE_FLAG_ARRAY_POINTER','GL_EDGE_FLAG_ARRAY_EXT','GL_EDGE_FLAG_ARRAY_COUNT_EXT','GL_EDGE_FLAG_ARRAY',
+ 'GL_EDGE_FLAG','GL_DST_COLOR','GL_DST_ALPHA','GL_DRAW_PIXEL_TOKEN','GL_DRAW_BUFFER','GL_DOUBLE_EXT','GL_DOUBLEBUFFER',
+ 'GL_DOUBLE','GL_DONT_CARE','GL_DOMAIN','GL_DITHER','GL_DIFFUSE','GL_DEPTH_WRITEMASK','GL_DEPTH_TEST','GL_DEPTH_SCALE',
+ 'GL_DEPTH_RANGE','GL_DEPTH_FUNC','GL_DEPTH_COMPONENT','GL_DEPTH_CLEAR_VALUE','GL_DEPTH_BUFFER_BIT','GL_DEPTH_BITS',
+ 'GL_DEPTH_BIAS','GL_DEPTH','GL_DECR','GL_DECAL','GL_CW','GL_CURRENT_TEXTURE_COORDS','GL_CURRENT_RASTER_TEXTURE_COORDS','GL_CURRENT_RASTER_POSITION_VALID',
+ 'GL_CURRENT_RASTER_POSITION','GL_CURRENT_RASTER_INDEX','GL_CURRENT_RASTER_DISTANCE','GL_CURRENT_RASTER_COLOR','GL_CURRENT_NORMAL',
+ 'GL_CURRENT_INDEX','GL_CURRENT_COLOR','GL_CURRENT_BIT','GL_CULL_FACE_MODE','GL_CULL_FACE','GL_COPY_PIXEL_TOKEN',
+ 'GL_COPY_INVERTED','GL_COPY','GL_CONSTANT_EXT','GL_CONSTANT_ATTENUATION','GL_CONSTANT','GL_COMPILE_AND_EXECUTE','GL_COMPILE','GL_COMBINE_RGB_EXT',
+ 'GL_COMBINE_RGB','GL_COMBINE_EXT','GL_COMBINE_ALPHA_EXT','GL_COMBINE_ALPHA','GL_COMBINE','GL_COLOR_WRITEMASK',
+ 'GL_COLOR_TABLE_WIDTH_EXT','GL_COLOR_TABLE_RED_SIZE_EXT','GL_COLOR_TABLE_LUMINANCE_SIZE_EXT','GL_COLOR_TABLE_INTENSITY_SIZE_EXT',
+ 'GL_COLOR_TABLE_GREEN_SIZE_EXT','GL_COLOR_TABLE_FORMAT_EXT','GL_COLOR_TABLE_BLUE_SIZE_EXT','GL_COLOR_TABLE_ALPHA_SIZE_EXT',
+ 'GL_COLOR_MATERIAL_PARAMETER','GL_COLOR_MATERIAL_FACE','GL_COLOR_MATERIAL','GL_COLOR_LOGIC_OP','GL_COLOR_INDEXES',
+ 'GL_COLOR_INDEX8_EXT','GL_COLOR_INDEX4_EXT','GL_COLOR_INDEX2_EXT','GL_COLOR_INDEX1_EXT','GL_COLOR_INDEX16_EXT',
+ 'GL_COLOR_INDEX12_EXT','GL_COLOR_INDEX','GL_COLOR_CLEAR_VALUE','GL_COLOR_BUFFER_BIT','GL_COLOR_ARRAY_TYPE_EXT',
+ 'GL_COLOR_ARRAY_TYPE','GL_COLOR_ARRAY_STRIDE_EXT','GL_COLOR_ARRAY_STRIDE','GL_COLOR_ARRAY_SIZE_EXT','GL_COLOR_ARRAY_SIZE',
+ 'GL_COLOR_ARRAY_POINTER_EXT','GL_COLOR_ARRAY_POINTER','GL_COLOR_ARRAY_EXT','GL_COLOR_ARRAY_COUNT_EXT','GL_COLOR_ARRAY',
+ 'GL_COLOR','GL_COEFF','GL_CLIP_PLANE5','GL_CLIP_PLANE4','GL_CLIP_PLANE3','GL_CLIP_PLANE2','GL_CLIP_PLANE1','GL_CLIP_PLANE0',
+ 'GL_CLIENT_VERTEX_ARRAY_BIT','GL_CLIENT_PIXEL_STORE_BIT','GL_CLIENT_ATTRIB_STACK_DEPTH','GL_CLIENT_ALL_ATTRIB_BITS',
+ 'GL_CLIENT_ACTIVE_TEXTURE_ARB','GL_CLIENT_ACTIVE_TEXTURE','GL_CLEAR','GL_CLAMP','GL_CCW','GL_C4UB_V3F','GL_C4UB_V2F',
+ 'GL_C4F_N3F_V3F','GL_C3F_V3F','GL_BYTE','GL_BLUE_SCALE','GL_BLUE_BITS','GL_BLUE_BIAS','GL_BLUE','GL_BLEND_SRC','GL_BLEND_DST',
+ 'GL_BLEND','GL_BITMAP_TOKEN','GL_BITMAP','GL_BGR_EXT','GL_BGRA_EXT','GL_BACK_RIGHT','GL_BACK_LEFT','GL_BACK',
+ 'GL_AUX_BUFFERS','GL_AUX3','GL_AUX2','GL_AUX1','GL_AUX0','GL_AUTO_NORMAL','GL_ATTRIB_STACK_DEPTH','GL_AND_REVERSE',
+ 'GL_AND_INVERTED','GL_AND','GL_AMBIENT_AND_DIFFUSE','GL_AMBIENT','GL_ALWAYS','GL_ALPHA_TEST_REF','GL_ALPHA_TEST_FUNC',
+ 'GL_ALPHA_TEST','GL_ALPHA_SCALE','GL_ALPHA_BITS','GL_ALPHA_BIAS','GL_ALPHA8','GL_ALPHA4','GL_ALPHA16','GL_ALPHA12',
+ 'GL_ALPHA','GL_ALL_ATTRIB_BITS','GL_ADD_SIGNED_EXT','GL_ADD_SIGNED','GL_ADD','GL_ACTIVE_TEXTURE_ARB','GL_ACTIVE_TEXTURE',
+ 'GL_ACCUM_RED_BITS','GL_ACCUM_GREEN_BITS','GL_ACCUM_CLEAR_VALUE','GL_ACCUM_BUFFER_BIT','GL_ACCUM_BLUE_BITS','GL_ACCUM_ALPHA_BITS',
+ 'GL_ACCUM','GL_4_BYTES','GL_4D_COLOR_TEXTURE','GL_3_BYTES','GL_3D_COLOR_TEXTURE','GL_3D_COLOR','GL_3D','GL_2_BYTES',
+ 'GL_2D','GLU_V_STEP','GLU_VERTEX','GLU_VERSION_1_2','GLU_VERSION_1_1','GLU_VERSION','GLU_U_STEP','GLU_UNKNOWN','GLU_TRUE',
+ 'GLU_TESS_WINDING_RULE','GLU_TESS_WINDING_POSITIVE','GLU_TESS_WINDING_ODD','GLU_TESS_WINDING_NONZERO','GLU_TESS_WINDING_NEGATIVE',
+ 'GLU_TESS_WINDING_ABS_GEQ_TWO','GLU_TESS_VERTEX_DATA','GLU_TESS_VERTEX','GLU_TESS_TOLERANCE','GLU_TESS_NEED_COMBINE_CALLBACK','GLU_TESS_MISSING_END_POLYGON',
+ 'GLU_TESS_MISSING_END_CONTOUR','GLU_TESS_MISSING_BEGIN_POLYGON','GLU_TESS_MISSING_BEGIN_CONTOUR','GLU_TESS_ERROR_DATA',
+ 'GLU_TESS_ERROR8','GLU_TESS_ERROR7','GLU_TESS_ERROR6','GLU_TESS_ERROR5','GLU_TESS_ERROR4','GLU_TESS_ERROR3','GLU_TESS_ERROR2',
+ 'GLU_TESS_ERROR1','GLU_TESS_ERROR','GLU_TESS_END_DATA','GLU_TESS_END','GLU_TESS_EDGE_FLAG_DATA','GLU_TESS_EDGE_FLAG',
+ 'GLU_TESS_COORD_TOO_LARGE','GLU_TESS_COMBINE_DATA','GLU_TESS_COMBINE','GLU_TESS_BOUNDARY_ONLY','GLU_TESS_BEGIN_DATA',
+ 'GLU_TESS_BEGIN','GLU_SMOOTH','GLU_SILHOUETTE','GLU_SAMPLING_TOLERANCE','GLU_SAMPLING_METHOD','GLU_POINT','GLU_PATH_LENGTH',
+ 'GLU_PARAMETRIC_TOLERANCE','GLU_PARAMETRIC_ERROR','GLU_OUT_OF_MEMORY','GLU_OUTSIDE','GLU_OUTLINE_POLYGON','GLU_OUTLINE_PATCH',
+ 'GLU_NURBS_ERROR9','GLU_NURBS_ERROR8','GLU_NURBS_ERROR7','GLU_NURBS_ERROR6','GLU_NURBS_ERROR5','GLU_NURBS_ERROR4',
+ 'GLU_NURBS_ERROR37','GLU_NURBS_ERROR36','GLU_NURBS_ERROR35','GLU_NURBS_ERROR34','GLU_NURBS_ERROR33','GLU_NURBS_ERROR32',
+ 'GLU_NURBS_ERROR31','GLU_NURBS_ERROR30','GLU_NURBS_ERROR3','GLU_NURBS_ERROR29','GLU_NURBS_ERROR28','GLU_NURBS_ERROR27','GLU_NURBS_ERROR26',
+ 'GLU_NURBS_ERROR25','GLU_NURBS_ERROR24','GLU_NURBS_ERROR23','GLU_NURBS_ERROR22','GLU_NURBS_ERROR21','GLU_NURBS_ERROR20',
+ 'GLU_NURBS_ERROR2','GLU_NURBS_ERROR19','GLU_NURBS_ERROR18','GLU_NURBS_ERROR17','GLU_NURBS_ERROR16','GLU_NURBS_ERROR15','GLU_NURBS_ERROR14',
+ 'GLU_NURBS_ERROR13','GLU_NURBS_ERROR12','GLU_NURBS_ERROR11','GLU_NURBS_ERROR10','GLU_NURBS_ERROR1','GLU_NONE',
+ 'GLU_MAP1_TRIM_3','GLU_MAP1_TRIM_2','GLU_LINE','GLU_INVALID_VALUE','GLU_INVALID_ENUM','GLU_INTERIOR','GLU_INSIDE','GLU_INCOMPATIBLE_GL_VERSION',
+ 'GLU_FLAT','GLU_FILL','GLU_FALSE','GLU_EXTERIOR','GLU_EXTENSIONS','GLU_ERROR','GLU_END','GLU_EDGE_FLAG','GLU_DOMAIN_DISTANCE',
+ 'GLU_DISPLAY_MODE','GLU_CW','GLU_CULLING','GLU_CCW','GLU_BEGIN','GLU_AUTO_LOAD_MATRIX','CHANNEL_UNORDERED','CHANNEL_ORDERED',
+ 'CHANNEL_MAX'
+ ),
+ 2 => array(
+
+ // Red Lowercase Keywords
+
+ 'WriteWord','WriteString','WriteReal','WriteLine','WriteInt','WriteFloat','WriteDouble','WriteChar','WriteByte',
+ 'windowwidth','windowheight','waittimer','Vec4','Vec3','Vec2','val','UpdateJoystick','ucase$','Transpose','tickcount',
+ 'textscroll','textrows','textmode','textcols','tanh','tand','tan','synctimercatchup','synctimer','swapbuffers',
+ 'str$','stopsoundvoice','stopsounds','stopmusic','sqrt','sqr','sprzorder','spryvel','sprytiles','sprysize','spryrepeat',
+ 'spryflip','sprycentre','spry','sprxvel','sprxtiles','sprxsize','sprxrepeat','sprxflip','sprxcentre','sprx',
+ 'sprvisible','sprvel','sprtype','sprtop','sprspin','sprsolid','sprsetzorder','sprsetyvel','sprsetysize','sprsetyrepeat',
+ 'sprsetyflip','sprsetycentre','sprsety','sprsetxvel','sprsetxsize','sprsetxrepeat','sprsetxflip','sprsetxcentre',
+ 'sprsetx','sprsetvisible','sprsetvel','sprsettiles','sprsettextures','sprsettexture','sprsetspin','sprsetsolid',
+ 'sprsetsize','sprsetscale','sprsetpos','sprsetparallax','sprsetframe','sprsetcolor','sprsetanimspeed','sprsetanimloop',
+ 'sprsetangle','sprsetalpha','sprscale','sprright','sprpos','sprparallax','sprleft','spriteareawidth','spriteareaheight',
+ 'sprframe','sprcolor','sprcameraz','sprcameray','sprcamerax','sprcamerasetz','sprcamerasety','sprcamerasetx',
+ 'sprcamerasetpos','sprcamerasetfov','sprcamerasetangle','sprcamerapos','sprcamerafov','sprcameraangle',
+ 'sprbottom','spranimspeed','spranimloop','spranimdone','sprangle','spralpha','spraddtextures','spraddtexture',
+ 'sounderror','sleep','sind','sin','showcursor','sgn','settextscroll','setmusicvolume','SendMessage','Seek',
+ 'scankeydown','RTInvert','rnd','right$','resizetext','resizespritearea','RejectConnection','ReceiveMessage','ReadWord',
+ 'ReadText','ReadReal','ReadLine','ReadInt','ReadFloat','ReadDouble','ReadChar','ReadByte','randomize','printr',
+ 'print','pow','playsound','playmusic','performancecounter','Orthonormalize','OpenFileWrite','OpenFileRead','Normalize',
+ 'newtilemap','newsprite','NewServer','NewConnection','musicplaying','mouse_yd','mouse_y','mouse_xd','mouse_x',
+ 'mouse_wheel','mouse_button','mid$','MessageSmoothed','MessageReliable','MessagePending','MessageChannel','maxtextureunits',
+ 'MatrixZero','MatrixTranslate','MatrixScale','MatrixRotateZ','MatrixRotateY','MatrixRotateX','MatrixRotate','MatrixIdentity',
+ 'MatrixCrossProduct','MatrixBasis','log','locate','loadtexture','loadsound','loadmipmaptexture','loadmipmapimagestrip',
+ 'loadimagestrip','loadimage','Length','len','left$','lcase$','keydown','Joy_Y','Joy_X','Joy_Up','Joy_Right','Joy_Left',
+ 'Joy_Keys','Joy_Down','Joy_Button','Joy_3','Joy_2','Joy_1','Joy_0','int','inscankey','input$','inkey$','inittimer',
+ 'imagewidth','imagestripframes','imageheight','imageformat','imagedatatype','hidecursor','glViewport','glVertex4sv',
+ 'glVertex4s','glVertex4iv','glVertex4i','glVertex4fv','glVertex4f','glVertex4dv','glVertex4d','glVertex3sv','glVertex3s',
+ 'glVertex3iv','glVertex3i','glVertex3fv','glVertex3f','glVertex3dv','glVertex3d','glVertex2sv','glVertex2s','glVertex2iv',
+ 'glVertex2i','glVertex2fv','glVertex2f','glVertex2dv','glVertex2d','gluPerspective','gluOrtho2D','gluLookAt',
+ 'glubuild2dmipmaps','glTranslatef','glTranslated','gltexsubimage2d','glTexParameteriv','glTexParameteri',
+ 'glTexParameterfv','glTexParameterf','glteximage2d','glTexGeniv','glTexGeni','glTexGenfv','glTexGenf','glTexGendv',
+ 'glTexGend','glTexEnviv','glTexEnvi','glTexEnvfv','glTexEnvf','glTexCoord4sv','glTexCoord4s','glTexCoord4iv','glTexCoord4i',
+ 'glTexCoord4fv','glTexCoord4f','glTexCoord4dv','glTexCoord4d','glTexCoord3sv','glTexCoord3s','glTexCoord3iv','glTexCoord3i',
+ 'glTexCoord3fv','glTexCoord3f','glTexCoord3dv','glTexCoord3d','glTexCoord2sv','glTexCoord2s','glTexCoord2iv','glTexCoord2i',
+ 'glTexCoord2fv','glTexCoord2f','glTexCoord2dv','glTexCoord2d','glTexCoord1sv','glTexCoord1s','glTexCoord1iv','glTexCoord1i','glTexCoord1fv',
+ 'glTexCoord1f','glTexCoord1dv','glTexCoord1d','glStencilOp','glStencilMask','glStencilFunc','glShadeModel','glSelectBuffer',
+ 'glScissor','glScalef','glScaled','glRotatef','glRotated','glRenderMode','glRectsv','glRects','glRectiv','glRecti',
+ 'glRectfv','glRectf','glRectdv','glRectd','glReadBuffer','glRasterPos4sv','glRasterPos4s','glRasterPos4iv',
+ 'glRasterPos4i','glRasterPos4fv','glRasterPos4f','glRasterPos4dv','glRasterPos4d','glRasterPos3sv','glRasterPos3s',
+ 'glRasterPos3iv','glRasterPos3i','glRasterPos3fv','glRasterPos3f','glRasterPos3dv','glRasterPos3d','glRasterPos2sv',
+ 'glRasterPos2s','glRasterPos2iv','glRasterPos2i','glRasterPos2fv','glRasterPos2f','glRasterPos2dv','glRasterPos2d',
+ 'glPushName','glPushMatrix','glPushClientAttrib','glPushAttrib','glPrioritizeTextures','glPopName','glPopMatrix',
+ 'glPopClientAttrib','glPopAttrib','glpolygonstipple','glPolygonOffset','glPolygonMode','glPointSize','glPixelZoom',
+ 'glPixelTransferi','glPixelTransferf','glPixelStorei','glPixelStoref','glPassThrough','glOrtho','glNormal3sv','glNormal3s',
+ 'glNormal3iv','glNormal3i','glNormal3fv','glNormal3f','glNormal3dv','glNormal3d','glNormal3bv','glNormal3b','glNewList',
+ 'glMultMatrixf','glMultMatrixd','glmultitexcoord2f','glmultitexcoord2d','glMatrixMode','glMaterialiv','glMateriali',
+ 'glMaterialfv','glMaterialf','glMapGrid2f','glMapGrid2d','glMapGrid1f','glMapGrid1d','glLogicOp','glLoadName','glLoadMatrixf',
+ 'glLoadMatrixd','glLoadIdentity','glListBase','glLineWidth','glLineStipple','glLightModeliv','glLightModeli','glLightModelfv',
+ 'glLightModelf','glLightiv','glLighti','glLightfv','glLightf','glIsTexture','glIsList','glIsEnabled','glInitNames',
+ 'glIndexubv','glIndexub','glIndexsv','glIndexs','glIndexMask','glIndexiv','glIndexi','glIndexfv','glIndexf','glIndexdv',
+ 'glIndexd','glHint','glGetTexParameteriv','glGetTexParameterfv','glGetTexLevelParameteriv','glGetTexLevelParameterfv',
+ 'glGetTexGeniv','glGetTexGenfv','glGetTexGendv','glGetTexEnviv','glGetTexEnvfv','glgetstring','glgetpolygonstipple','glGetPixelMapuiv',
+ 'glGetMaterialiv','glGetMaterialfv','glGetLightiv','glGetLightfv','glGetIntegerv','glGetFloatv',
+ 'glGetError','glGetDoublev','glGetClipPlane','glGetBooleanv','glgentextures','glgentexture',
+ 'glgenlists','glFrustum','glFrontFace','glFogiv','glFogi','glFogfv','glFogf','glFlush','glFinish','glFeedbackBuffer',
+ 'glEvalPoint2','glEvalPoint1','glEvalMesh2','glEvalMesh1','glEvalCoord2fv','glEvalCoord2f','glEvalCoord2dv','glEvalCoord2d',
+ 'glEvalCoord1fv','glEvalCoord1f','glEvalCoord1dv','glEvalCoord1d','glEndList','glEnd','glEnableClientState','glEnable',
+ 'glEdgeFlagv','glEdgeFlag','glDrawBuffer','glDrawArrays','glDisableClientState','glDisable','glDepthRange','glDepthMask',
+ 'glDepthFunc','gldeletetextures','gldeletetexture','gldeletelists','glCullFace','glCopyTexSubImage2D','glCopyTexSubImage1D',
+ 'glCopyTexImage2D','glCopyTexImage1D','glColorMaterial','glColorMask','glColor4usv','glColor4us','glColor4uiv','glColor4ui',
+ 'glColor4ubv','glColor4ub','glColor4sv','glColor4s','glColor4iv','glColor4i','glColor4fv','glColor4f','glColor4dv',
+ 'glColor4d','glColor4bv','glColor4b','glColor3usv','glColor3us','glColor3uiv','glColor3ui','glColor3ubv','glColor3ub',
+ 'glColor3sv','glColor3s','glColor3iv','glColor3i','glColor3fv','glColor3f','glColor3dv','glColor3d','glColor3bv',
+ 'glColor3b','glClipPlane','glClearStencil','glClearIndex','glClearDepth','glClearColor','glClearAccum','glClear',
+ 'glcalllists','glCallList','glBlendFunc','glBindTexture','glBegin','glArrayElement','glAreTexturesResident',
+ 'glAlphaFunc','glactivetexture','glAccum','font','FindNextFile','FindFirstFile','FindClose','FileError',
+ 'extensionsupported','exp','execute','EndOfFile','drawtext','divbyzero','Determinant','deletesprite','deletesound',
+ 'DeleteServer','deleteimage','DeleteConnection','defaultfont','CrossProduct','cosd','cos','copysprite','ConnectionPending',
+ 'ConnectionHandShaking','ConnectionConnected','ConnectionAddress','compilererrorline','compilererrorcol','compilererror',
+ 'compilefile','compile','color','cls','CloseFile','clearregion','clearline','clearkeys','chr$','charat$','bindsprite',
+ 'beep','atnd','atn2d','atn2','atn','atand','asc','argcount','arg','animatesprites','AcceptConnection','abs'
+ ),
+ 3 => array(
+
+ // Blue Lowercase Keywords
+
+ 'xor','while','wend','until','type','traditional_print','traditional','to','then','struc','string','step','single',
+ 'run','return','reset','read','or','null','not','next','lor','loop','language','land','integer','input','if',
+ 'goto','gosub','for','endstruc','endif','end','elseif','else','double','do','dim','data','const','basic4gl','as',
+ 'and','alloc'
+ )
+
+ ),
+ 'SYMBOLS' => array(
+ '=', '<', '>', '>=', '<=', '+', '-', '*', '/', '%', '(', ')', '{', '}', '[', ']', '&', ';', ':', '$'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000080; font-weight: bold;',
+ 2 => 'color: #FF0000;',
+ 3 => 'color: #0000FF;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #657CC4; font-style: italic;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000080;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000080; font-weight: bold;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #0000FF;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/batch.php b/platform/www/vendor/geshi/geshi/src/geshi/batch.php
new file mode 100644
index 0000000..4f048b6
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/batch.php
@@ -0,0 +1,228 @@
+<?php
+/*************************************************************************************
+ * batch.php
+ * ------------
+ * Author: FraidZZ ( fraidzz [@] bk.ru )
+ * Copyright: (c) 2015 FraidZZ ( http://vk.com/fraidzz , http://www.cyberforum.ru/members/340557.html )
+ * Release Version: 1.0.9.1
+ * Date Started: 2015/03/28
+ *
+ * Windows batch file language file for GeSHi.
+ *
+ *************************************************************************************
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Windows Batch file',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 100 => '/(?:^|[&|])\\s*(?:rem|::)[^\\n]*/msi',
+ 101 => '/[\\/-]\\S*/si',
+ 102 => '/^\s*:[^:]\\S*/msi',
+ 103 => '/(?:([%!])[^"\'~ ][^"\' ]*\\1|%%?(?:~[dpnxsatz]*)?[^"\'])/si'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ 100 => '/(?:([%!])\\S+\\1|%%(?:~[dpnxsatz]*)?[^"\'])/si'
+ ),
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'echo',
+ 'set',
+ 'for',
+ 'if',
+ 'exit',
+ 'else',
+ 'do',
+ 'not',
+ 'defined',
+ 'exist'
+ ),
+ 2 => array(
+ "ASSOC",
+ "ATTRIB",
+ "BREAK",
+ "BCDEDIT",
+ "CACLS",
+ "CD",
+ "CHCP",
+ "CHDIR",
+ "CHKDSK",
+ "CHKNTFS",
+ "CLS",
+ "CMD",
+ "COLOR",
+ "COMP",
+ "COMPACT",
+ "CONVERT",
+ "COPY",
+ "DATE",
+ "DEL",
+ "DIR",
+ "DISKCOMP",
+ "DISKCOPY",
+ "DISKPART",
+ "DOSKEY",
+ "DRIVERQUERY",
+ "ECHO",
+ "ENDLOCAL",
+ "ERASE",
+ "EXIT",
+ "FC",
+ "FIND",
+ "FINDSTR",
+ "FOR",
+ "FORMAT",
+ "FSUTIL",
+ "FTYPE",
+ "GPRESULT",
+ "GRAFTABL",
+ "HELP",
+ "ICACLS",
+ "IF",
+ "LABEL",
+ "MD",
+ "MKDIR",
+ "MKLINK",
+ "MODE",
+ "MORE",
+ "MOVE",
+ "OPENFILES",
+ "PATH",
+ "PAUSE",
+ "POPD",
+ "PRINT",
+ "PROMPT",
+ "PUSHD",
+ "RD",
+ "RECOVER",
+ "REN",
+ "RENAME",
+ "REPLACE",
+ "RMDIR",
+ "ROBOCOPY",
+ "SET",
+ "SETLOCAL",
+ "SC",
+ "SCHTASKS",
+ "SHIFT",
+ "SHUTDOWN",
+ "SORT",
+ "START",
+ "SUBST",
+ "SYSTEMINFO",
+ "TASKLIST",
+ "TASKKILL",
+ "TIME",
+ "TITLE",
+ "TREE",
+ "TYPE",
+ "VER",
+ "VERIFY",
+ "VOL",
+ "XCOPY",
+ "WMIC",
+ "CSCRIPT"
+ ),
+ 3 => array(
+ "enabledelayedexpansion",
+ "enableextensions"
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(',
+ ')',
+ '+',
+ '-',
+ '~',
+ '^',
+ '@',
+ '&',
+ '*',
+ '|',
+ '/',
+ '<',
+ '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #800080; font-weight: bold;',
+ 2 => 'color: #0080FF; font-weight: bold;',
+ 3 => 'color: #0000FF; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 101 => 'color: #44aa44; font-weight: bold;',
+ 100 => 'color: #888888;',
+ 102 => 'color: #990000; font-weight: bold;',
+ 103 => 'color: #000099; font-weight: bold;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 100 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #44aa44; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #990000; font-weight: bold',
+ 1 => 'color: #800080; font-weight: bold;'
+ ),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ 0 => array(
+ GESHI_SEARCH => "((?:goto|call)\\s*)(\\S+)",
+ GESHI_REPLACE => "\\2",
+ GESHI_BEFORE => "\\1",
+ GESHI_MODIFIERS => "si",
+ GESHI_AFTER => ""
+ ),
+ 1 => "goto|call"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/bf.php b/platform/www/vendor/geshi/geshi/src/geshi/bf.php
new file mode 100644
index 0000000..4206d2f
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/bf.php
@@ -0,0 +1,113 @@
+<?php
+/*************************************************************************************
+ * bf.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/10/31
+ *
+ * Brainfuck language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/31 (1.0.8.1)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+$language_data = array (
+ 'LANG_NAME' => 'Brainfuck',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(1 => '/[^\n+\-<>\[\]\.\,Y]+/s'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('+', '-'),
+ 1 => array('[', ']'),
+ 2 => array('<', '>'),
+ 3 => array('.', ','),
+ 4 => array('Y') //Brainfork Extension ;-)
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #660000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #006600;',
+ 1 => 'color: #660000;',
+ 2 => 'color: #000066;',
+ 3 => 'color: #666600;',
+ 4 => 'color: #660066;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'STRINGS' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER,
+ 'BRACKETS' => GESHI_NEVER
+ ),
+ 'KEYWORDS' => array(
+ 'DISALLOW_BEFORE' => '',
+ 'DISALLOW_AFTER' => ''
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/biblatex.php b/platform/www/vendor/geshi/geshi/src/geshi/biblatex.php
new file mode 100644
index 0000000..873c4ad
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/biblatex.php
@@ -0,0 +1,200 @@
+<?php
+/********************************************************************************
+ * bibtex.php
+ * -----
+ * Author: Maïeul Rouquette from
+ * Quinn Taylor (quinntaylor@mac.com)
+ * Copyright: (c) 2009 Quinn Taylor (quinntaylor@mac.com), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/04/29
+ *
+ * BibLaTeX language file for GeSHi.
+ *
+ * CHANGES
+ * 2015/12/29 (1.0.8.13) Biblatex parser
+ * CHANGES
+ * -------
+ * 2009/04/29 (1.0.8.4)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ * - Add regex for matching and replacing URLs with corresponding hyperlinks
+ * - Add regex for matching more LaTeX commands that may be embedded in BibTeX
+ * (Someone who understands regex better than I should borrow from latex.php)
+ ********************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+*******************************************************************************/
+
+// http://en.wikipedia.org/wiki/BibTeX
+// http://www.fb10.uni-bremen.de/anglistik/langpro/bibliographies/jacobsen-bibtex.html
+
+$language_data = array (
+ 'LANG_NAME' => 'BibTeX',
+ 'OOLANG' => false,
+ 'COMMENT_SINGLE' => array(
+ 1 => '%%'
+ ),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 0 => array(
+ '@comment','@preamble','@string'
+ ),
+ // Standard entry types
+ 1 => array(
+ '@article','@book','@booklet','@conference','@inbook',
+ '@incollection','@inproceedings','@manual','@mastersthesis',
+ '@misc','@phdthesis','@proceedings','@techreport','@unpublished'
+ ),
+ // Custom entry types
+ 2 => array(
+ '@collection','@patent','@webpage'
+ ),
+ // Standard entry field names
+ 3 => array(
+ 'address','annote','author','booktitle','chapter','crossref',
+ 'edition','editor','howpublished','institution','journal','key',
+ 'month','note','number','organization','pages','publisher','school',
+ 'series','title','type','volume','year',
+ ),
+ // Custom entry field names
+ 4 => array(
+ 'abstract','affiliation','chaptername','cited-by','cites',
+ 'contents','copyright','date-added','date-modified','doi','eprint',
+ 'isbn','issn','keywords','language','lccn','lib-congress',
+ 'location','price','rating','read','size','source','url',
+ )
+ ),
+ 'URLS' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'SYMBOLS' => array(
+ '{', '}', '#', '=', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ GESHI_COMMENTS => false,
+ ),
+ // Define the colors for the groups listed above
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #C02020;', // Standard entry types
+ 2 => 'color: #C02020;', // Custom entry types
+ 3 => 'color: #C08020;', // Standard entry field names
+ 4 => 'color: #C08020;' // Custom entry field names
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #2C922C; font-style: italic;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #2020C0;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #E02020;'
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #2020C0;', // {...}
+ 2 => 'color: #C08020;', // BibDesk fields
+ 3 => 'color: #800000;', // LaTeX commands
+ 4 => 'color: #C08020;', // Custom entry field (biblatex)
+ 5 => 'color: #C02020;', // Custom entry types (biblatex)
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000000; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #E02020;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'REGEXPS' => array(
+ // {parameters}
+ 1 => array(
+ GESHI_SEARCH => "(?<=\\{)(?:\\{(?R)\\}|[^\\{\\}])*(?=\\})",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => 's',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 2 => array(
+ GESHI_SEARCH => "\bBdsk-(File|Url)-\d+",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => 'Us',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 3 => array(
+ GESHI_SEARCH => "\\\\[A-Za-z0-9]*+",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => 'Us',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 4 => array(
+ GESHI_SEARCH => "([A-z]+)\s+=",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => 'Us',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 5 => array(
+ GESHI_SEARCH => "@([A-z])+",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'NUMBERS' => GESHI_NEVER
+ ),
+ 'KEYWORDS' => array(
+ 3 => array(
+ 'DISALLOWED_AFTER' => '(?=\s*=)'
+ ),
+ 4 => array(
+ 'DISALLOWED_AFTER' => '(?=\s*=)'
+ ),
+ )
+ )
+ );
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/bibtex.php b/platform/www/vendor/geshi/geshi/src/geshi/bibtex.php
new file mode 100644
index 0000000..684f938
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/bibtex.php
@@ -0,0 +1,181 @@
+<?php
+/********************************************************************************
+ * bibtex.php
+ * -----
+ * Author: Quinn Taylor (quinntaylor@mac.com)
+ * Copyright: (c) 2009 Quinn Taylor (quinntaylor@mac.com), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/04/29
+ *
+ * BibTeX language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/04/29 (1.0.8.4)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ * - Add regex for matching and replacing URLs with corresponding hyperlinks
+ * - Add regex for matching more LaTeX commands that may be embedded in BibTeX
+ * (Someone who understands regex better than I should borrow from latex.php)
+ ********************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+*******************************************************************************/
+
+// http://en.wikipedia.org/wiki/BibTeX
+// http://www.fb10.uni-bremen.de/anglistik/langpro/bibliographies/jacobsen-bibtex.html
+
+$language_data = array (
+ 'LANG_NAME' => 'BibTeX',
+ 'OOLANG' => false,
+ 'COMMENT_SINGLE' => array(
+ 1 => '%%'
+ ),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 0 => array(
+ '@comment','@preamble','@string'
+ ),
+ // Standard entry types
+ 1 => array(
+ '@article','@book','@booklet','@conference','@inbook',
+ '@incollection','@inproceedings','@manual','@mastersthesis',
+ '@misc','@phdthesis','@proceedings','@techreport','@unpublished'
+ ),
+ // Custom entry types
+ 2 => array(
+ '@collection','@patent','@webpage'
+ ),
+ // Standard entry field names
+ 3 => array(
+ 'address','annote','author','booktitle','chapter','crossref',
+ 'edition','editor','howpublished','institution','journal','key',
+ 'month','note','number','organization','pages','publisher','school',
+ 'series','title','type','volume','year'
+ ),
+ // Custom entry field names
+ 4 => array(
+ 'abstract','affiliation','chaptername','cited-by','cites',
+ 'contents','copyright','date-added','date-modified','doi','eprint',
+ 'isbn','issn','keywords','language','lccn','lib-congress',
+ 'location','price','rating','read','size','source','url'
+ )
+ ),
+ 'URLS' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'SYMBOLS' => array(
+ '{', '}', '#', '=', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ GESHI_COMMENTS => false,
+ ),
+ // Define the colors for the groups listed above
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #C02020;', // Standard entry types
+ 2 => 'color: #C02020;', // Custom entry types
+ 3 => 'color: #C08020;', // Standard entry field names
+ 4 => 'color: #C08020;' // Custom entry field names
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #2C922C; font-style: italic;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #2020C0;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #E02020;'
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #2020C0;', // {...}
+ 2 => 'color: #C08020;', // BibDesk fields
+ 3 => 'color: #800000;' // LaTeX commands
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000000; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #E02020;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'REGEXPS' => array(
+ // {parameters}
+ 1 => array(
+ GESHI_SEARCH => "(?<=\\{)(?:\\{(?R)\\}|[^\\{\\}])*(?=\\})",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => 's',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 2 => array(
+ GESHI_SEARCH => "\bBdsk-(File|Url)-\d+",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => 'Us',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 3 => array(
+ GESHI_SEARCH => "\\\\[A-Za-z0-9]*+",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => 'Us',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'NUMBERS' => GESHI_NEVER
+ ),
+ 'KEYWORDS' => array(
+ 3 => array(
+ 'DISALLOWED_AFTER' => '(?=\s*=)'
+ ),
+ 4 => array(
+ 'DISALLOWED_AFTER' => '(?=\s*=)'
+ ),
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/blitzbasic.php b/platform/www/vendor/geshi/geshi/src/geshi/blitzbasic.php
new file mode 100644
index 0000000..092aaa7
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/blitzbasic.php
@@ -0,0 +1,183 @@
+<?php
+/*************************************************************************************
+ * blitzbasic.php
+ * --------------
+ * Author: P�draig O`Connel (info@moonsword.info)
+ * Copyright: (c) 2005 P�draig O`Connel (http://moonsword.info)
+ * Release Version: 1.0.9.1
+ * Date Started: 16.10.2005
+ *
+ * BlitzBasic language file for GeSHi.
+ *
+ * It is a simple Basic dialect. Released for Games and Network Connections.
+ * In this Language File are all functions included (2D BB and 3D BB)
+ *
+ *
+ * CHANGES
+ * -------
+ * 2005/12/28 (1.0.1)
+ * - Remove unnecessary style index for regexps
+ * 2005/10/22 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2005/10/22)
+ * -------------------------
+ * * Sort out the Basic commands for splitting up.
+ * * To set up the right colors.
+ * (the colors are ok, but not the correct ones)
+ * * Split to BlitzBasic 2D and BlitzBasic 3D.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'BlitzBasic',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'If','EndIf','ElseIf','Else','While','Wend','Return','Next','Include','End Type','End Select','End If','End Function','End','Select',
+ 'Type','Forever','For','Or','And','AppTitle','Case','Goto','Gosub','Step','Stop','Int','Last','False','Then','To','True','Until','Float',
+ 'String','Before','Not'
+ ),
+ 2 => array(
+ // All Functions - 2D BB and 3D BB
+ 'Xor','WriteString','WriteShort','WritePixelFast','WritePixel','WriteLine','WriteInt','WriteFloat','WriteFile','WriteBytes',
+ 'WriteByte','Write','WaitTimer','WaitMouse','WaitKey','WaitJoy','VWait','Viewport',
+ 'Upper','UpdateGamma','UnlockBuffer','UDPTimeouts','UDPStreamPort','UDPStreamIP','UDPMsgPort','UDPMsgIP',
+ 'Trim','TotalVidMem','TileImage','TileBlock','TFormImage','TFormFilter','Text',
+ 'TCPTimeouts','TCPStreamPort','TCPStreamIP','Tan','SystemProperty','StringWidth','StringHeight','Str','StopNetGame',
+ 'StopChannel','StartNetGame','Sqr','SoundVolume','SoundPitch','SoundPan','Sin','Shr',
+ 'ShowPointer','Shl','Sgn','SetGfxDriver','SetGamma','SetFont','SetEnv','SetBuffer','SendUDPMsg','SendNetMsg',
+ 'SeekFile','SeedRnd','ScanLine','ScaleImage','SaveImage','SaveBuffer','Sar','RuntimeError','RSet',
+ 'RotateImage','RndSeed','Rnd','Right','ResumeChannel','Restore','ResizeImage','ResizeBank','Replace',
+ 'Repeat','RecvUDPMsg','RecvNetMsg','RectsOverlap','Rect','ReadString','ReadShort','ReadPixelFast','ReadPixel','ReadLine',
+ 'ReadInt','ReadFloat','ReadFile','ReadDir','ReadBytes','ReadByte','ReadAvail','Read','Rand','Print',
+ 'PokeShort','PokeInt','PokeFloat','PokeByte','Plot','PlaySound','PlayMusic','PlayCDTrack','Pi','PeekShort',
+ 'PeekInt','PeekFloat','PeekByte','PauseChannel','Oval','Origin','OpenTCPStream','OpenMovie','OpenFile',
+ 'Null','NextFile','New','NetPlayerName','NetPlayerLocal','NetMsgType','NetMsgTo','NetMsgFrom',
+ 'NetMsgData','MovieWidth','MoviePlaying','MovieHeight','MoveMouse','MouseZSpeed','MouseZ','MouseYSpeed','MouseY','MouseXSpeed',
+ 'MouseX','MouseHit','MouseDown','Mod','Millisecs','MidHandle','Mid','MaskImage','LSet','Lower',
+ 'LoopSound','Log10','Log','LockBuffer','Locate','Local','LoadSound','LoadImage','LoadFont','LoadBuffer',
+ 'LoadAnimImage','Line','Len','Left','KeyHit','KeyDown','JoyZDir','JoyZ','JoyYDir',
+ 'JoyYaw','JoyY','JoyXDir','JoyX','JoyVDir','JoyV','JoyUDir','JoyU','JoyType','JoyRoll',
+ 'JoyPitch','JoyHit','JoyHat','JoyDown','JoinNetGame','Instr','Insert','Input',
+ 'ImageYHandle','ImageXHandle','ImageWidth','ImagesOverlap','ImagesCollide','ImageRectOverlap','ImageRectCollide','ImageHeight','ImageBuffer',
+ 'HostNetGame','HostIP','HidePointer','Hex','HandleImage','GraphicsWidth','GraphicsHeight','GraphicsDepth','GraphicsBuffer','Graphics',
+ 'GrabImage','Global','GFXModeWidth','GFXModeHeight','GfxModeExists','GFXModeDepth','GfxDriverName','GetMouse',
+ 'GetKey','GetJoy','GetEnv','GetColor','GammaRed','GammaGreen','GammaBlue','Function','FrontBuffer','FreeTimer',
+ 'FreeSound','FreeImage','FreeFont','FreeBank','FontWidth','FontHeight','FlushMouse','FlushKeys',
+ 'FlushJoy','Floor','Flip','First','FileType','FileSize','FilePos','Field',
+ 'Exp','Exit','ExecFile','Eof','EndGraphics','Each','DrawMovie','DrawImageRect','DrawImage','DrawBlockRect','DrawBlock',
+ 'DottedIP','Dim','DeleteNetPlayer','DeleteFile','DeleteDir','Delete','Delay','Default','DebugLog','Data',
+ 'CurrentTime','CurrentDir','CurrentDate','CreateUDPStream','CreateTimer','CreateTCPServer','CreateNetPlayer','CreateImage','CreateDir','CreateBank',
+ 'CountHostIPs','CountGFXModes','CountGfxDrivers','Cos','CopyStream','CopyRect','CopyPixelFast','CopyPixel','CopyImage','CopyFile',
+ 'CopyBank','Const','CommandLine','ColorRed','ColorGreen','ColorBlue','Color','ClsColor','Cls','CloseUDPStream',
+ 'CloseTCPStream','CloseTCPServer','CloseMovie','CloseFile','CloseDir','Chr','ChannelVolume','ChannelPlaying','ChannelPitch','ChannelPan',
+ 'ChangeDir','Ceil','CallDLL','Bin','BankSize','BackBuffer','AvailVidMem','AutoMidHandle',
+ 'ATan2','ATan','ASin','Asc','After','ACos','AcceptTCPStream','Abs',
+ // 3D Commands
+ 'Wireframe','Windowed3D','WBuffer','VertexZ','VertexY',
+ 'VertexX','VertexW','VertexV','VertexU','VertexTexCoords','VertexRed','VertexNZ','VertexNY','VertexNX','VertexNormal',
+ 'VertexGreen','VertexCoords','VertexColor','VertexBlue','VertexAlpha','VectorYaw','VectorPitch','UpdateWorld','UpdateNormals','TurnEntity',
+ 'TrisRendered','TriangleVertex','TranslateEntity','TFormVector','TFormPoint','TFormNormal','TFormedZ','TFormedY','TFormedX','TextureWidth',
+ 'TextureName','TextureHeight','TextureFilter','TextureCoords','TextureBuffer','TextureBlend','TerrainZ','TerrainY','TerrainX','TerrainSize',
+ 'TerrainShading','TerrainHeight','TerrainDetail','SpriteViewMode','ShowEntity','SetCubeFace','SetAnimTime','SetAnimKey','ScaleTexture','ScaleSprite',
+ 'ScaleMesh','ScaleEntity','RotateTexture','RotateSprite','RotateMesh','RotateEntity','ResetEntity','RenderWorld','ProjectedZ','ProjectedY',
+ 'ProjectedX','PositionTexture','PositionMesh','PositionEntity','PointEntity','PickedZ','PickedY','PickedX','PickedTriangle','PickedTime',
+ 'PickedSurface','PickedNZ','PickedNY','PickedNX','PickedEntity','PaintSurface','PaintMesh','PaintEntity','NameEntity','MoveEntity',
+ 'ModifyTerrain','MeshWidth','MeshHeight','MeshesIntersect','MeshDepth','MD2AnimTime','MD2AnimLength','MD2Animating','LoadTexture','LoadTerrain',
+ 'LoadSprite','LoadMesh','LoadMD2','LoaderMatrix','LoadBSP','LoadBrush','LoadAnimTexture','LoadAnimSeq','LoadAnimMesh','Load3DSound',
+ 'LinePick','LightRange','LightMesh','LightConeAngles','LightColor','HWMultiTex','HideEntity','HandleSprite','Graphics3D','GfxMode3DExists',
+ 'GfxMode3D','GfxDriverCaps3D','GfxDriver3D','GetSurfaceBrush','GetSurface','GetParent','GetMatElement','GetEntityType','GetEntityBrush','GetChild',
+ 'GetBrushTexture','FreeTexture','FreeEntity','FreeBrush','FlipMesh','FitMesh','FindSurface','FindChild','ExtractAnimSeq','EntityZ',
+ 'EntityYaw','EntityY','EntityX','EntityVisible','EntityType','EntityTexture','EntityShininess','EntityRoll','EntityRadius','EntityPitch',
+ 'EntityPickMode','EntityPick','EntityParent','EntityOrder','EntityName','EntityInView','EntityFX','EntityDistance','EntityColor','EntityCollided',
+ 'EntityBox','EntityBlend','EntityAutoFade','EntityAlpha','EmitSound','Dither','DeltaYaw','DeltaPitch','CreateTexture','CreateTerrain',
+ 'CreateSurface','CreateSprite','CreateSphere','CreatePlane','CreatePivot','CreateMirror','CreateMesh','CreateListener','CreateLight','CreateCylinder',
+ 'CreateCube','CreateCone','CreateCamera','CreateBrush','CountVertices','CountTriangles','CountSurfaces','CountGfxModes3D','CountCollisions','CountChildren',
+ 'CopyMesh','CopyEntity','CollisionZ','CollisionY','CollisionX','CollisionTriangle','CollisionTime','CollisionSurface','Collisions','CollisionNZ',
+ 'CollisionNY','CollisionNX','CollisionEntity','ClearWorld','ClearTextureFilters','ClearSurface','ClearCollisions','CaptureWorld','CameraZoom','CameraViewport',
+ 'CameraRange','CameraProjMode','CameraProject','CameraPick','CameraFogRange','CameraFogMode','CameraFogColor','CameraClsMode','CameraClsColor','BSPLighting',
+ 'BSPAmbientLight','BrushTexture','BrushShininess','BrushFX','BrushColor','BrushBlend','BrushAlpha','AntiAlias','AnimTime','AnimSeq',
+ 'AnimLength','Animating','AnimateMD2','Animate','AmbientLight','AlignToVector','AddVertex','AddTriangle','AddMesh','AddAnimSeq',
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(',')'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000066; font-weight: bold;',
+ 2 => 'color: #0000ff;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #D9D100; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #CC0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '\\'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => false,
+ 1 => false
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/bnf.php b/platform/www/vendor/geshi/geshi/src/geshi/bnf.php
new file mode 100644
index 0000000..1d7b053
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/bnf.php
@@ -0,0 +1,117 @@
+<?php
+/*************************************************************************************
+ * bnf.php
+ * --------
+ * Author: Rowan Rodrik van der Molen (rowan@bigsmoke.us)
+ * Copyright: (c) 2006 Rowan Rodrik van der Molen (http://www.bigsmoke.us/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/09/28
+ *
+ * BNF (Backus-Naur form) language file for GeSHi.
+ *
+ * See http://en.wikipedia.org/wiki/Backus-Naur_form for more info on BNF.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * - Removed superflicious regexps
+ * 2006/09/18 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2006/09/18)
+ * -------------------------
+ * * Nothing I can think of
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'bnf',
+ 'COMMENT_SINGLE' => array(';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'"),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')'),
+ 1 => array('<', '>'),
+ 2 => array('[', ']'),
+ 3 => array('{', '}'),
+ 4 => array('=', '*', '/', '|', ':'),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(),
+ 'COMMENTS' => array(
+ 0 => 'color: #666666; font-style: italic;', // Single Line comments
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => ''
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #a00;',
+ 1 => 'color: #a00;'
+ ),
+ 'NUMBERS' => array(
+ 0 => ''
+ ),
+ 'METHODS' => array(
+ 0 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066; font-weight: bold;', // Round brackets
+ 1 => 'color: #000066; font-weight: bold;', // Angel Brackets
+ 2 => 'color: #000066; font-weight: bold;', // Square Brackets
+ 3 => 'color: #000066; font-weight: bold;', // BRaces
+ 4 => 'color: #006600; font-weight: bold;', // Other operator symbols
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #007;',
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ //terminal symbols
+ 0 => array(
+ GESHI_SEARCH => '(&lt;)([^&]+?)(&gt;)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/boo.php b/platform/www/vendor/geshi/geshi/src/geshi/boo.php
new file mode 100644
index 0000000..0a35d5d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/boo.php
@@ -0,0 +1,215 @@
+<?php
+/*************************************************************************************
+ * boo.php
+ * --------
+ * Author: Marcus Griep (neoeinstein+GeSHi@gmail.com)
+ * Copyright: (c) 2007 Marcus Griep (http://www.xpdm.us)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/09/10
+ *
+ * Boo language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/09/10 (1.0.8)
+ * - First Release
+ *
+ * TODO (updated 2007/09/10)
+ * -------------------------
+ * Regular Expression Literal matching
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Boo',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'''", "'", '"""', '"'),
+ 'HARDQUOTE' => array('"""', '"""'),
+ 'HARDESCAPE' => array('\"""'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(//Namespace
+ 'namespace', 'import', 'from'
+ ),
+ 2 => array(//Jump
+ 'yield', 'return', 'goto', 'continue', 'break'
+ ),
+ 3 => array(//Conditional
+ 'while', 'unless', 'then', 'in', 'if', 'for', 'else', 'elif'
+ ),
+ 4 => array(//Property
+ 'set', 'get'
+ ),
+ 5 => array(//Exception
+ 'try', 'raise', 'failure', 'except', 'ensure'
+ ),
+ 6 => array(//Visibility
+ 'public', 'private', 'protected', 'internal'
+ ),
+ 7 => array(//Define
+ 'struct', 'ref', 'of', 'interface', 'event', 'enum', 'do', 'destructor', 'def', 'constructor', 'class'
+ ),
+ 8 => array(//Cast
+ 'typeof', 'cast', 'as'
+ ),
+ 9 => array(//BiMacro
+ 'yieldAll', 'using', 'unchecked', 'rawArayIndexing', 'print', 'normalArrayIndexing', 'lock',
+ 'debug', 'checked', 'assert'
+ ),
+ 10 => array(//BiAttr
+ 'required', 'property', 'meta', 'getter', 'default'
+ ),
+ 11 => array(//BiFunc
+ 'zip', 'shellp', 'shellm', 'shell', 'reversed', 'range', 'prompt',
+ 'matrix', 'map', 'len', 'join', 'iterator', 'gets', 'enumerate', 'cat', 'array'
+ ),
+ 12 => array(//HiFunc
+ '__switch__', '__initobj__', '__eval__', '__addressof__', 'quack'
+ ),
+ 13 => array(//Primitive
+ 'void', 'ushort', 'ulong', 'uint', 'true', 'timespan', 'string', 'single',
+ 'short', 'sbyte', 'regex', 'object', 'null', 'long', 'int', 'false', 'duck',
+ 'double', 'decimal', 'date', 'char', 'callable', 'byte', 'bool'
+ ),
+ 14 => array(//Operator
+ 'not', 'or', 'and', 'is', 'isa',
+ ),
+ 15 => array(//Modifier
+ 'virtual', 'transient', 'static', 'partial', 'override', 'final', 'abstract'
+ ),
+ 16 => array(//Access
+ 'super', 'self'
+ ),
+ 17 => array(//Pass
+ 'pass'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '[|', '|]', '${', '(', ')', '[', ']', '{', '}', '!', '@', '%', '&', '*', '|', '/', '<', '>', '+', '-', ';'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true,
+ 10 => true,
+ 11 => true,
+ 12 => true,
+ 13 => true,
+ 14 => true,
+ 15 => true,
+ 16 => true,
+ 17 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color:green;font-weight:bold;',
+ 2 => 'color:navy;',
+ 3 => 'color:blue;font-weight:bold;',
+ 4 => 'color:#8B4513;',
+ 5 => 'color:teal;font-weight:bold;',
+ 6 => 'color:blue;font-weight:bold;',
+ 7 => 'color:blue;font-weight:bold;',
+ 8 => 'color:blue;font-weight:bold;',
+ 9 => 'color:maroon;',
+ 10 => 'color:maroon;',
+ 11 => 'color:purple;',
+ 12 => 'color:#4B0082;',
+ 13 => 'color:purple;font-weight:bold;',
+ 14 => 'color:#008B8B;font-weight:bold;',
+ 15 => 'color:brown;',
+ 16 => 'color:black;font-weight:bold;',
+ 17 => 'color:gray;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #999999; font-style: italic;',
+ 2 => 'color: #999999; font-style: italic;',
+ 'MULTI' => 'color: #008000; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #0000FF; font-weight: bold;',
+ 'HARD' => 'color: #0000FF; font-weight: bold;',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #006400;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #008000;',
+ 'HARD' => 'color: #008000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #00008B;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: 000000;',
+ 1 => 'color: 000000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #006400;'
+ ),
+ 'REGEXPS' => array(
+ #0 => 'color: #0066ff;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+ 9 => '',
+ 10 => '',
+ 11 => '',
+ 12 => '',
+ 13 => '',
+ 14 => '',
+ 15 => '',
+ 16 => '',
+ 17 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 0 => '.',
+ 1 => '::'
+ ),
+ 'REGEXPS' => array(
+ #0 => '%(@)?\/(?:(?(1)[^\/\\\\\r\n]+|[^\/\\\\\r\n \t]+)|\\\\[\/\\\\\w+()|.*?$^[\]{}\d])+\/%'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/c.php b/platform/www/vendor/geshi/geshi/src/geshi/c.php
new file mode 100644
index 0000000..1d217ea
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/c.php
@@ -0,0 +1,279 @@
+<?php
+/*************************************************************************************
+ * c.php
+ * -----
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Contributors:
+ * - Jack Lloyd (lloyd@randombit.net)
+ * - Michael Mol (mikemol@gmail.com)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/04
+ *
+ * C language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/01/22 (1.0.8.3)
+ * - Made keywords case-sensitive.
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/XX/XX (1.0.4)
+ * - Added a couple of new keywords (Jack Lloyd)
+ * 2004/11/27 (1.0.3)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ * - Added support for URLs
+ * 2004/08/05 (1.0.1)
+ * - Added support for symbols
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2009/02/08)
+ * -------------------------
+ * - Get a list of inbuilt functions to add (and explore C more
+ * to complete this rather bare language file
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'C',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Multiline-continued single-line comments
+ 1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Multiline-continued preprocessor define
+ 2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[\\\\abfnrtv\'\"?\n]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'if', 'return', 'while', 'case', 'continue', 'default',
+ 'do', 'else', 'for', 'switch', 'goto'
+ ),
+ 2 => array(
+ 'null', 'false', 'break', 'true', 'function', 'enum', 'extern', 'inline'
+ ),
+ 3 => array(
+ // assert.h
+ 'assert',
+
+ //complex.h
+ 'cabs', 'cacos', 'cacosh', 'carg', 'casin', 'casinh', 'catan',
+ 'catanh', 'ccos', 'ccosh', 'cexp', 'cimag', 'cis', 'clog', 'conj',
+ 'cpow', 'cproj', 'creal', 'csin', 'csinh', 'csqrt', 'ctan', 'ctanh',
+
+ //ctype.h
+ 'digittoint', 'isalnum', 'isalpha', 'isascii', 'isblank', 'iscntrl',
+ 'isdigit', 'isgraph', 'islower', 'isprint', 'ispunct', 'isspace',
+ 'isupper', 'isxdigit', 'toascii', 'tolower', 'toupper',
+
+ //inttypes.h
+ 'imaxabs', 'imaxdiv', 'strtoimax', 'strtoumax', 'wcstoimax',
+ 'wcstoumax',
+
+ //locale.h
+ 'localeconv', 'setlocale',
+
+ //math.h
+ 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'exp',
+ 'fabs', 'floor', 'frexp', 'ldexp', 'log', 'log10', 'modf', 'pow',
+ 'sin', 'sinh', 'sqrt', 'tan', 'tanh',
+
+ //setjmp.h
+ 'longjmp', 'setjmp',
+
+ //signal.h
+ 'raise',
+
+ //stdarg.h
+ 'va_arg', 'va_copy', 'va_end', 'va_start',
+
+ //stddef.h
+ 'offsetof',
+
+ //stdio.h
+ 'clearerr', 'fclose', 'fdopen', 'feof', 'ferror', 'fflush', 'fgetc',
+ 'fgetpos', 'fgets', 'fopen', 'fprintf', 'fputc', 'fputchar',
+ 'fputs', 'fread', 'freopen', 'fscanf', 'fseek', 'fsetpos', 'ftell',
+ 'fwrite', 'getc', 'getch', 'getchar', 'gets', 'perror', 'printf',
+ 'putc', 'putchar', 'puts', 'remove', 'rename', 'rewind', 'scanf',
+ 'setbuf', 'setvbuf', 'snprintf', 'sprintf', 'sscanf', 'tmpfile',
+ 'tmpnam', 'ungetc', 'vfprintf', 'vfscanf', 'vprintf', 'vscanf',
+ 'vsprintf', 'vsscanf',
+
+ //stdlib.h
+ 'abort', 'abs', 'atexit', 'atof', 'atoi', 'atol', 'bsearch',
+ 'calloc', 'div', 'exit', 'free', 'getenv', 'itoa', 'labs', 'ldiv',
+ 'ltoa', 'malloc', 'qsort', 'rand', 'realloc', 'srand', 'strtod',
+ 'strtol', 'strtoul', 'system',
+
+ //string.h
+ 'memchr', 'memcmp', 'memcpy', 'memmove', 'memset', 'strcat',
+ 'strchr', 'strcmp', 'strcoll', 'strcpy', 'strcspn', 'strerror',
+ 'strlen', 'strncat', 'strncmp', 'strncpy', 'strpbrk', 'strrchr',
+ 'strspn', 'strstr', 'strtok', 'strxfrm',
+
+ //time.h
+ 'asctime', 'clock', 'ctime', 'difftime', 'gmtime', 'localtime',
+ 'mktime', 'strftime', 'time',
+
+ //wchar.h
+ 'btowc', 'fgetwc', 'fgetws', 'fputwc', 'fputws', 'fwide',
+ 'fwprintf', 'fwscanf', 'getwc', 'getwchar', 'mbrlen', 'mbrtowc',
+ 'mbsinit', 'mbsrtowcs', 'putwc', 'putwchar', 'swprintf', 'swscanf',
+ 'ungetwc', 'vfwprintf', 'vswprintf', 'vwprintf', 'wcrtomb',
+ 'wcscat', 'wcschr', 'wcscmp', 'wcscoll', 'wcscpy', 'wcscspn',
+ 'wcsftime', 'wcslen', 'wcsncat', 'wcsncmp', 'wcsncpy', 'wcspbrk',
+ 'wcsrchr', 'wcsrtombs', 'wcsspn', 'wcsstr', 'wcstod', 'wcstok',
+ 'wcstol', 'wcstoul', 'wcsxfrm', 'wctob', 'wmemchr', 'wmemcmp',
+ 'wmemcpy', 'wmemmove', 'wmemset', 'wprintf', 'wscanf',
+
+ //wctype.h
+ 'iswalnum', 'iswalpha', 'iswcntrl', 'iswctype', 'iswdigit',
+ 'iswgraph', 'iswlower', 'iswprint', 'iswpunct', 'iswspace',
+ 'iswupper', 'iswxdigit', 'towctrans', 'towlower', 'towupper',
+ 'wctrans', 'wctype'
+ ),
+ 4 => array(
+ 'auto', 'char', 'const', 'double', 'float', 'int', 'long',
+ 'register', 'short', 'signed', 'sizeof', 'static', 'struct',
+ 'typedef', 'union', 'unsigned', 'void', 'volatile', 'wchar_t',
+
+ 'int8', 'int16', 'int32', 'int64',
+ 'uint8', 'uint16', 'uint32', 'uint64',
+
+ 'int_fast8_t', 'int_fast16_t', 'int_fast32_t', 'int_fast64_t',
+ 'uint_fast8_t', 'uint_fast16_t', 'uint_fast32_t', 'uint_fast64_t',
+
+ 'int_least8_t', 'int_least16_t', 'int_least32_t', 'int_least64_t',
+ 'uint_least8_t', 'uint_least16_t', 'uint_least32_t', 'uint_least64_t',
+
+ 'int8_t', 'int16_t', 'int32_t', 'int64_t',
+ 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t',
+
+ 'intmax_t', 'uintmax_t', 'intptr_t', 'uintptr_t',
+ 'size_t', 'off_t'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']',
+ '+', '-', '*', '/', '%',
+ '=', '<', '>',
+ '!', '^', '&', '|',
+ '?', ':',
+ ';', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #993333;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #339933;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAMEL}.html',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/c_loadrunner.php b/platform/www/vendor/geshi/geshi/src/geshi/c_loadrunner.php
new file mode 100644
index 0000000..2d5cc73
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/c_loadrunner.php
@@ -0,0 +1,321 @@
+<?php
+/*************************************************************************************
+ * c_loadrunner.php
+ * ---------------------------------
+ * Author: Stuart Moncrieff (stuart at myloadtest dot com)
+ * Copyright: (c) 2010 Stuart Moncrieff (http://www.myloadtest.com/loadrunner-syntax-highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010-07-25
+ *
+ * C (for LoadRunner) language file for GeSHi.
+ *
+ * Based on LoadRunner 9.52.
+ *
+ * CHANGES
+ * -------
+ * 2010-08-01 (1.0.8.9)
+ * - Added highlighting support for LoadRunner {parameters}.
+ * 2010-07-25 (1.0.8.8)
+ * - First Release. Syntax highlighting support for lr_, web_, and sapgui_ functions only.
+ *
+ * TODO (updated 2010-07-25)
+ * -------------------------
+ * - Add support for other vuser types: MMS, FTP, etc.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * ************************************************************************************/
+
+$language_data = array (
+ // The First Indices
+ 'LANG_NAME' => 'C (LoadRunner)',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ // Escape characters within strings (like \\) are not highlighted differently in LoadRunner, so
+ // I am using GeSHi escape characters (or regular expressions) to highlight LoadRunner {parameters}.
+ // LoadRunner {parameters} must begin with a letter and contain only alphanumeric characters and '_'
+ 'ESCAPE_REGEXP' => array(
+ 0 => "#\{[a-zA-Z]{1}[a-zA-Z_]{0,}\}#",
+ ),
+
+ // Keywords
+ 'KEYWORDS' => array(
+ // Keywords from http://en.wikipedia.org/wiki/C_syntax
+ 1 => array(
+ 'auto', 'break', 'case', 'char', 'const', 'continue', 'default',
+ 'do', 'double', 'else', 'enum', 'extern', 'float', 'for', 'goto',
+ 'if', 'inline', 'int', 'long', 'register', 'restrict', 'return',
+ 'short', 'signed', 'sizeof', 'static', 'struct', 'switch',
+ 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while',
+ '_Bool', '_Complex', '_Imaginary'
+ ),
+ // C preprocessor directives from http://en.wikipedia.org/wiki/C_preprocessor
+ 2 => array(
+ '#define', '#if', '#ifdef', '#ifndef', '#include', '#else', '#elif', '#endif', '#pragma', '#undef'
+ ),
+ // Functions from lrun.h
+ 3 => array(
+ 'lr_start_transaction', 'lr_start_sub_transaction', 'lr_start_transaction_instance', 'lr_end_transaction',
+ 'lr_end_sub_transaction', 'lr_end_transaction_instance', 'lr_stop_transaction', 'lr_stop_transaction_instance',
+ 'lr_resume_transaction', 'lr_resume_transaction_instance', 'lr_wasted_time', 'lr_set_transaction', 'lr_user_data_point',
+ 'lr_user_data_point_instance', 'lr_user_data_point_ex', 'lr_user_data_point_instance_ex', 'lr_get_transaction_duration',
+ 'lr_get_trans_instance_duration', 'lr_get_transaction_think_time', 'lr_get_trans_instance_think_time',
+ 'lr_get_transaction_wasted_time', 'lr_get_trans_instance_wasted_time', 'lr_get_transaction_status',
+ 'lr_get_trans_instance_status', 'lr_set_transaction_status', 'lr_set_transaction_status_by_name',
+ 'lr_set_transaction_instance_status', 'lr_start_timer', 'lr_end_timer', 'lr_rendezvous', 'lr_rendezvous_ex',
+ 'lr_get_vuser_ip', 'lr_whoami', 'lr_get_host_name', 'lr_get_master_host_name', 'lr_get_attrib_long',
+ 'lr_get_attrib_string', 'lr_get_attrib_double', 'lr_paramarr_idx', 'lr_paramarr_random', 'lr_paramarr_len',
+ 'lr_param_unique', 'lr_param_sprintf', 'lr_load_dll', 'lr_continue_on_error', 'lr_decrypt', 'lr_abort', 'lr_exit',
+ 'lr_peek_events', 'lr_think_time', 'lr_debug_message', 'lr_log_message', 'lr_message', 'lr_error_message',
+ 'lr_output_message', 'lr_vuser_status_message', 'lr_fail_trans_with_error', 'lr_next_row', 'lr_advance_param',
+ 'lr_eval_string', 'lr_eval_string_ext', 'lr_eval_string_ext_free', 'lr_param_increment', 'lr_save_var',
+ 'lr_save_string', 'lr_save_int', 'lr_save_datetime', 'lr_save_searched_string', 'lr_set_debug_message',
+ 'lr_get_debug_message', 'lr_enable_ip_spoofing', 'lr_disable_ip_spoofing', 'lr_convert_string_encoding'
+ ),
+ // Constants from lrun.h
+ 4 => array(
+ 'DP_FLAGS_NO_LOG', 'DP_FLAGS_STANDARD_LOG', 'DP_FLAGS_EXTENDED_LOG', 'merc_timer_handle_t', 'LR_EXIT_VUSER',
+ 'LR_EXIT_ACTION_AND_CONTINUE', 'LR_EXIT_ITERATION_AND_CONTINUE', 'LR_EXIT_VUSER_AFTER_ITERATION',
+ 'LR_EXIT_VUSER_AFTER_ACTION', 'LR_EXIT_MAIN_ITERATION_AND_CONTINUE', 'LR_MSG_CLASS_DISABLE_LOG',
+ 'LR_MSG_CLASS_STANDARD_LOG', 'LR_MSG_CLASS_RETURNED_DATA', 'LR_MSG_CLASS_PARAMETERS', 'LR_MSG_CLASS_ADVANCED_TRACE',
+ 'LR_MSG_CLASS_EXTENDED_LOG', 'LR_MSG_CLASS_SENT_DATA', 'LR_MSG_CLASS_JIT_LOG_ON_ERROR', 'LR_SWITCH_OFF', 'LR_SWITCH_ON',
+ 'LR_SWITCH_DEFAULT', 'ONE_DAY', 'ONE_HOUR', 'ONE_MIN', 'DATE_NOW', 'TIME_NOW', 'LR_MSG_CLASS_BRIEF_LOG',
+ 'LR_MSG_CLASS_RESULT_DATA', 'LR_MSG_CLASS_FULL_TRACE', 'LR_MSG_CLASS_AUTO_LOG', 'LR_MSG_OFF', 'LR_MSG_ON',
+ 'LR_MSG_DEFAULT'
+ ),
+ // Functions from web_api.h
+ 5 => array(
+ 'web_reg_add_cookie', 'web_report_data_point', 'web_text_link', 'web_element', 'web_image_link', 'web_static_image',
+ 'web_image_submit', 'web_button', 'web_edit_field', 'web_radio_group', 'web_check_box', 'web_list', 'web_text_area',
+ 'web_map_area', 'web_eval_java_script', 'web_reg_dialog', 'web_reg_cross_step_download', 'web_browser',
+ 'web_set_rts_key', 'web_save_param_length', 'web_save_timestamp_param', 'web_load_cache', 'web_dump_cache',
+ 'web_add_cookie_ex'
+ ),
+ // Constants from web_api.h
+ 6 => array(
+ 'DESCRIPTION', 'ACTION', 'VERIFICATION', 'LR_NOT_FOUND', 'HTTP_INFO_TOTAL_REQUEST_STAT',
+ 'HTTP_INFO_TOTAL_RESPONSE_STAT', 'LRW_OPT_STOP_VUSER_ON_ERROR', 'LRW_OPT_DISPLAY_IMAGE_BODY'
+ ),
+ // Functions from as_web.h
+ 7 => array(
+ 'web_add_filter', 'web_add_auto_filter', 'web_add_auto_header', 'web_add_header', 'web_add_cookie',
+ 'web_cleanup_auto_headers', 'web_cleanup_cookies', 'web_concurrent_end', 'web_concurrent_start', 'web_create_html_param',
+ 'web_create_html_param_ex', 'web_custom_request', 'web_disable_keep_alive', 'web_enable_keep_alive', 'web_find',
+ 'web_get_int_property', 'web_image', 'web_image_check', 'web_link', 'web_global_verification', 'web_reg_find',
+ 'web_reg_save_param', 'web_convert_param', 'web_remove_auto_filter', 'web_remove_auto_header', 'web_revert_auto_header',
+ 'web_remove_cookie', 'web_save_header', 'web_set_certificate', 'web_set_certificate_ex', 'web_set_connections_limit',
+ 'web_set_max_html_param_len', 'web_set_max_retries', 'web_set_proxy', 'web_set_proxy_bypass', 'web_set_secure_proxy',
+ 'web_set_sockets_option', 'web_set_option', 'web_set_timeout', 'web_set_user', 'web_sjis_to_euc_param',
+ 'web_submit_data', 'web_submit_form', 'web_url', 'web_set_proxy_bypass_local', 'web_cache_cleanup',
+ 'web_create_html_query', 'web_create_radio_button_param', 'web_switch_net_layer'
+ ),
+ // Constants from as_web.h
+ 8 => array(
+ 'ENDFORM', 'LAST', 'ENDITEM', 'EXTRARES', 'ITEMDATA', 'STARTHIDDENS', 'ENDHIDDENS', 'CONNECT', 'RECEIVE', 'RESOLVE',
+ 'STEP', 'REQUEST', 'RESPONSE', 'STARTQUERY', 'ENDQUERY', 'INPROPS', 'OUTPROPS', 'ENDPROPS', 'RAW_BODY_START',
+ 'RAW_BODY_END', 'HTTP_INFO_RETURN_CODE', 'HTTP_INFO_DOWNLOAD_SIZE', 'HTTP_INFO_DOWNLOAD_TIME',
+ 'LRW_NET_SOCKET_OPT_LOAD_VERIFY_FILE', 'LRW_NET_SOCKET_OPT_DEFAULT_VERIFY_PATH', 'LRW_NET_SOCKET_OPT_SSL_VERSION',
+ 'LRW_NET_SOCKET_OPT_SSL_CIPHER_LIST', 'LRW_NET_SOCKET_OPT_SO_REUSE_ADDRESS', 'LRW_NET_SOCKET_OPT_USER_IP_ADDRESS',
+ 'LRW_NET_SOCKET_OPT_IP_ADDRESS_BY_INDEX', 'LRW_NET_SOCKET_OPT_HELP', 'LRW_NET_SOCKET_OPT_PRINT_USER_IP_ADDRESS_LIST',
+ 'LRW_OPT_HTML_CHAR_REF_BACKWARD_COMPATIBILITY', 'LRW_OPT_VALUE_YES', 'LRW_OPT_VALUE_NO'
+ ),
+ // Functions from as_sapgui.h
+ 9 => array(
+ 'sapgui_open_connection', 'sapgui_open_connection_ex', 'sapgui_logon', 'sapgui_create_session',
+ 'sapgui_create_new_session', 'sapgui_call_method', 'sapgui_call_method_ex', 'sapgui_set_property',
+ 'sapgui_get_property', 'sapgui_set_collection_property', 'sapgui_active_object_from_parent_method',
+ 'sapgui_active_object_from_parent_property', 'sapgui_call_method_of_active_object',
+ 'sapgui_call_method_of_active_object_ex', 'sapgui_set_property_of_active_object', 'sapgui_get_property_of_active_object',
+ 'sapgui_select_active_connection', 'sapgui_select_active_session', 'sapgui_select_active_window ',
+ 'sapgui_status_bar_get_text', 'sapgui_status_bar_get_param', 'sapgui_status_bar_get_type', 'sapgui_get_status_bar_text',
+ 'sapgui_get_active_window_title', 'sapgui_is_object_available', 'sapgui_is_tab_selected', 'sapgui_is_object_changeable',
+ 'sapgui_set_ok_code', 'sapgui_send_vkey', 'sapgui_resize_window', 'sapgui_window_resize', 'sapgui_window_maximize',
+ 'sapgui_window_close', 'sapgui_window_restore', 'sapgui_window_scroll_to_row', 'sapgui_press_button',
+ 'sapgui_select_radio_button', 'sapgui_set_password', 'sapgui_set_text', 'sapgui_select_menu', 'sapgui_select_tab',
+ 'sapgui_set_checkbox', 'sapgui_set_focus', 'sapgui_select_combobox_entry', 'sapgui_get_ok_code',
+ 'sapgui_is_radio_button_selected', 'sapgui_get_text', 'sapgui_is_checkbox_selected', 'sapgui_table_set_focus',
+ 'sapgui_table_press_button', 'sapgui_table_select_radio_button', 'sapgui_table_set_password', 'sapgui_table_set_text',
+ 'sapgui_table_set_checkbox', 'sapgui_table_select_combobox_entry', 'sapgui_table_set_row_selected',
+ 'sapgui_table_set_column_selected', 'sapgui_table_set_column_width', 'sapgui_table_reorder', 'sapgui_table_fill_data',
+ 'sapgui_table_get_text', 'sapgui_table_is_radio_button_selected', 'sapgui_table_is_checkbox_selected',
+ 'sapgui_table_is_row_selected', 'sapgui_table_is_column_selected', 'sapgui_table_get_column_width',
+ 'sapgui_grid_clear_selection', 'sapgui_grid_select_all', 'sapgui_grid_selection_changed',
+ 'sapgui_grid_press_column_header', 'sapgui_grid_select_cell', 'sapgui_grid_select_rows', 'sapgui_grid_select_column',
+ 'sapgui_grid_deselect_column', 'sapgui_grid_select_columns', 'sapgui_grid_select_cells', 'sapgui_grid_select_cell_row',
+ 'sapgui_grid_select_cell_column', 'sapgui_grid_set_column_order', 'sapgui_grid_set_column_width',
+ 'sapgui_grid_scroll_to_row', 'sapgui_grid_double_click', 'sapgui_grid_click', 'sapgui_grid_press_button',
+ 'sapgui_grid_press_total_row', 'sapgui_grid_set_cell_data', 'sapgui_grid_set_checkbox',
+ 'sapgui_grid_double_click_current_cell', 'sapgui_grid_click_current_cell', 'sapgui_grid_press_button_current_cell',
+ 'sapgui_grid_press_total_row_current_cell', 'sapgui_grid_press_F1', 'sapgui_grid_press_F4', 'sapgui_grid_press_ENTER',
+ 'sapgui_grid_press_toolbar_button', 'sapgui_grid_press_toolbar_context_button', 'sapgui_grid_open_context_menu',
+ 'sapgui_grid_select_context_menu', 'sapgui_grid_select_toolbar_menu', 'sapgui_grid_fill_data',
+ 'sapgui_grid_get_current_cell_row', 'sapgui_grid_get_current_cell_column', 'sapgui_grid_get_rows_count',
+ 'sapgui_grid_get_columns_count', 'sapgui_grid_get_cell_data', 'sapgui_grid_is_checkbox_selected',
+ 'sapgui_tree_scroll_to_node', 'sapgui_tree_set_hierarchy_header_width', 'sapgui_tree_set_selected_node',
+ 'sapgui_tree_double_click_node', 'sapgui_tree_press_key', 'sapgui_tree_press_button', 'sapgui_tree_set_checkbox',
+ 'sapgui_tree_double_click_item', 'sapgui_tree_click_link', 'sapgui_tree_open_default_context_menu',
+ 'sapgui_tree_open_node_context_menu', 'sapgui_tree_open_header_context_menu', 'sapgui_tree_open_item_context_menu',
+ 'sapgui_tree_select_context_menu', 'sapgui_tree_select_item', 'sapgui_tree_select_node', 'sapgui_tree_unselect_node',
+ 'sapgui_tree_unselect_all', 'sapgui_tree_select_column', 'sapgui_tree_unselect_column', 'sapgui_tree_set_column_order',
+ 'sapgui_tree_collapse_node', 'sapgui_tree_expand_node', 'sapgui_tree_scroll_to_item', 'sapgui_tree_set_column_width',
+ 'sapgui_tree_press_header', 'sapgui_tree_is_checkbox_selected', 'sapgui_tree_get_node_text', 'sapgui_tree_get_item_text',
+ 'sapgui_calendar_scroll_to_date', 'sapgui_calendar_focus_date', 'sapgui_calendar_select_interval',
+ 'sapgui_apogrid_select_all', 'sapgui_apogrid_clear_selection', 'sapgui_apogrid_select_cell',
+ 'sapgui_apogrid_deselect_cell', 'sapgui_apogrid_select_row', 'sapgui_apogrid_deselect_row',
+ 'sapgui_apogrid_select_column', 'sapgui_apogrid_deselect_column', 'sapgui_apogrid_scroll_to_row',
+ 'sapgui_apogrid_scroll_to_column', 'sapgui_apogrid_double_click', 'sapgui_apogrid_set_cell_data',
+ 'sapgui_apogrid_get_cell_data', 'sapgui_apogrid_is_cell_changeable', 'sapgui_apogrid_get_cell_format',
+ 'sapgui_apogrid_get_cell_tooltip', 'sapgui_apogrid_press_ENTER', 'sapgui_apogrid_open_cell_context_menu',
+ 'sapgui_apogrid_select_context_menu_item', 'sapgui_text_edit_scroll_to_line', 'sapgui_text_edit_set_selection_indexes',
+ 'sapgui_text_edit_set_unprotected_text_part', 'sapgui_text_edit_get_first_visible_line',
+ 'sapgui_text_edit_get_selection_index_start', 'sapgui_text_edit_get_selection_index_end',
+ 'sapgui_text_edit_get_number_of_unprotected_text_parts', 'sapgui_text_edit_double_click',
+ 'sapgui_text_edit_single_file_dropped', 'sapgui_text_edit_multiple_files_dropped', 'sapgui_text_edit_press_F1',
+ 'sapgui_text_edit_press_F4', 'sapgui_text_edit_open_context_menu', 'sapgui_text_edit_select_context_menu',
+ 'sapgui_text_edit_modified_status_changed', 'sapgui_htmlviewer_send_event', 'sapgui_htmlviewer_dom_get_property',
+ 'sapgui_toolbar_press_button', 'sapgui_toolbar_press_context_button', 'sapgui_toolbar_select_menu_item',
+ 'sapgui_toolbar_select_menu_item_by_text', 'sapgui_toolbar_select_context_menu_item',
+ 'sapgui_toolbar_select_context_menu_item_by_text'
+ ),
+ // Constants from as_sapgui.h
+ 10 => array(
+ 'BEGIN_OPTIONAL', 'END_OPTIONAL', 'al-keys', 'ENTER', 'HELP', 'F2', 'BACK', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9',
+ 'F10', 'F11', 'ESC', 'SHIFT_F1', 'SHIFT_F2', 'SHIFT_F3', 'SHIFT_F4', 'SHIFT_F5', 'SHIFT_F6', 'SHIFT_F7', 'SHIFT_F8',
+ 'SHIFT_F9', 'SHIFT_F10', 'SHIFT_F11', 'SHIFT_F12', 'CTRL_F1', 'CTRL_F2', 'CTRL_F3', 'CTRL_F4', 'CTRL_F5', 'CTRL_F6',
+ 'CTRL_F7', 'CTRL_F8', 'CTRL_F9', 'CTRL_F10', 'CTRL_F11', 'CTRL_F12', 'CTRL_SHIFT_F1', 'CTRL_SHIFT_F2', 'CTRL_SHIFT_F3',
+ 'CTRL_SHIFT_F4', 'CTRL_SHIFT_F5', 'CTRL_SHIFT_F6', 'CTRL_SHIFT_F7', 'CTRL_SHIFT_F8', 'CTRL_SHIFT_F9', 'CTRL_SHIFT_F10',
+ 'CTRL_SHIFT_F11', 'CTRL_SHIFT_F12', 'CANCEL', 'CTRL_F', 'CTRL_PAGE_UP', 'PAGE_UP', 'PAGE_DOWN', 'CTRL_PAGE_DOWN',
+ 'CTRL_G', 'CTRL_P'
+ ),
+ ),
+
+ // Symbols and Case Sensitivity
+ // Symbols from: http://en.wikipedia.org/wiki/C_syntax
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']',
+ '+', '-', '*', '/', '%',
+ '=', '<', '>', '!', '^', '&', '|', '?', ':', ';', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true, // Standard C reserved keywords
+ 2 => true, // C preprocessor directives
+ 3 => true, // Functions from lrun.h
+ 4 => true, // Constants from lrun.h
+ 5 => true, // Functions from web_api.h
+ 6 => true, // Constants from web_api.h
+ 7 => true, // Functions from as_web.h
+ 8 => true, // Constants from as_web.h
+ 9 => true, // Functions from as_sapgui.h
+ 10 => true, // Constants from as_sapgui.h
+ ),
+
+ // Styles
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ // Functions are brown, constants and reserved words are blue
+ 1 => 'color: #0000ff;', // Standard C reserved keywords
+ 2 => 'color: #0000ff;', // C preprocessor directives
+ 3 => 'color: #8a0000;', // Functions from lrun.h
+ 4 => 'color: #0000ff;', // Constants from lrun.h
+ 5 => 'color: #8a0000;', // Functions from web_api.h
+ 6 => 'color: #0000ff;', // Constants from web_api.h
+ 7 => 'color: #8a0000;', // Functions from as_web.h
+ 8 => 'color: #0000ff;', // Constants from as_web.h
+ 9 => 'color: #8a0000;', // Functions from as_sapgui.h
+ 10 => 'color: #0000ff;', // Constants from as_sapgui.h
+ ),
+ 'COMMENTS' => array(
+ // Comments are grey
+ 1 => 'color: #9b9b9b;',
+ 'MULTI' => 'color: #9b9b9b;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ // GeSHi cannot define a separate style for ESCAPE_REGEXP. The style for ESCAPE_CHAR also applies to ESCAPE_REGEXP.
+ // This is used for LoadRunner {parameters}
+ // {parameters} are pink
+ 0 => 'color: #c000c0;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ // Strings are green
+ 0 => 'color: #008080;'
+ ),
+ 'NUMBERS' => array(
+ // Numbers are green
+ 0 => 'color: #008080;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #008080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #008080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #008080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#008080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#008080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#008080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#008080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #000000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+
+ // URLs for Functions
+ 'URLS' => array(
+ 1 => '', // Standard C reserved keywords
+ 2 => '', // C preprocessor directives
+ 3 => '', // Functions from lrun.h
+ 4 => '', // Constants from lrun.h
+ 5 => '', // Functions from web_api.h
+ 6 => '', // Constants from web_api.h
+ 7 => '', // Functions from as_web.h
+ 8 => '', // Constants from as_web.h
+ 9 => '', // Functions from as_sapgui.h
+ 10 => '', // Constants from as_sapgui.h
+ ),
+
+ // Object Orientation
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+
+ // Regular Expressions
+ // Note that REGEXPS are not applied within strings.
+ 'REGEXPS' => array(
+ ),
+
+ // Contextual Highlighting and Strict Mode
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+
+ // Tabs
+ // Note that if you are using <pre> tags for your code, then the browser chooses how many spaces your tabs will translate to.
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/c_mac.php b/platform/www/vendor/geshi/geshi/src/geshi/c_mac.php
new file mode 100644
index 0000000..5a364d9
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/c_mac.php
@@ -0,0 +1,225 @@
+<?php
+/*************************************************************************************
+ * c_mac.php
+ * ---------
+ * Author: M. Uli Kusterer (witness.of.teachtext@gmx.net)
+ * Copyright: (c) 2004 M. Uli Kusterer, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/04
+ *
+ * C for Macs language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/11/27
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'C (Mac)',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Multiline-continued single-line comments
+ 1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Multiline-continued preprocessor define
+ 2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[\\\\abfnrtv\'\"?\n]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'if', 'return', 'while', 'case', 'continue', 'default',
+ 'do', 'else', 'for', 'switch', 'goto'
+ ),
+ 2 => array(
+ 'NULL', 'false', 'break', 'true', 'enum', 'errno', 'EDOM',
+ 'ERANGE', 'FLT_RADIX', 'FLT_ROUNDS', 'FLT_DIG', 'DBL_DIG', 'LDBL_DIG',
+ 'FLT_EPSILON', 'DBL_EPSILON', 'LDBL_EPSILON', 'FLT_MANT_DIG', 'DBL_MANT_DIG',
+ 'LDBL_MANT_DIG', 'FLT_MAX', 'DBL_MAX', 'LDBL_MAX', 'FLT_MAX_EXP', 'DBL_MAX_EXP',
+ 'LDBL_MAX_EXP', 'FLT_MIN', 'DBL_MIN', 'LDBL_MIN', 'FLT_MIN_EXP', 'DBL_MIN_EXP',
+ 'LDBL_MIN_EXP', 'CHAR_BIT', 'CHAR_MAX', 'CHAR_MIN', 'SCHAR_MAX', 'SCHAR_MIN',
+ 'UCHAR_MAX', 'SHRT_MAX', 'SHRT_MIN', 'USHRT_MAX', 'INT_MAX', 'INT_MIN',
+ 'UINT_MAX', 'LONG_MAX', 'LONG_MIN', 'ULONG_MAX', 'HUGE_VAL', 'SIGABRT',
+ 'SIGFPE', 'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_ERR',
+ 'SIG_IGN', 'BUFSIZ', 'EOF', 'FILENAME_MAX', 'FOPEN_MAX', 'L_tmpnam',
+ 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX', 'stdin', 'stdout', 'stderr',
+ 'EXIT_FAILURE', 'EXIT_SUCCESS', 'RAND_MAX', 'CLOCKS_PER_SEC',
+ // Mac-specific constants:
+ 'kCFAllocatorDefault'
+ ),
+ 3 => array(
+ 'printf', 'fprintf', 'snprintf', 'sprintf', 'assert',
+ 'isalnum', 'isalpha', 'isdigit', 'iscntrl', 'isgraph', 'islower', 'isprint',
+ 'ispunct', 'isspace', 'isupper', 'isxdigit', 'tolower', 'toupper',
+ 'exp', 'log', 'log10', 'pow', 'sqrt', 'ceil', 'floor', 'fabs', 'ldexp',
+ 'frexp', 'modf', 'fmod', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2',
+ 'sinh', 'cosh', 'tanh', 'setjmp', 'longjmp',
+ 'va_start', 'va_arg', 'va_end', 'offsetof', 'sizeof', 'fopen', 'freopen',
+ 'fflush', 'fclose', 'remove', 'rename', 'tmpfile', 'tmpname', 'setvbuf',
+ 'setbuf', 'vfprintf', 'vprintf', 'vsprintf', 'fscanf', 'scanf', 'sscanf',
+ 'fgetc', 'fgets', 'fputc', 'fputs', 'getc', 'getchar', 'gets', 'putc',
+ 'putchar', 'puts', 'ungetc', 'fread', 'fwrite', 'fseek', 'ftell', 'rewind',
+ 'fgetpos', 'fsetpos', 'clearerr', 'feof', 'ferror', 'perror', 'abs', 'labs',
+ 'div', 'ldiv', 'atof', 'atoi', 'atol', 'strtod', 'strtol', 'strtoul', 'calloc',
+ 'malloc', 'realloc', 'free', 'abort', 'exit', 'atexit', 'system', 'getenv',
+ 'bsearch', 'qsort', 'rand', 'srand', 'strcpy', 'strncpy', 'strcat', 'strncat',
+ 'strcmp', 'strncmp', 'strcoll', 'strchr', 'strrchr', 'strspn', 'strcspn',
+ 'strpbrk', 'strstr', 'strlen', 'strerror', 'strtok', 'strxfrm', 'memcpy',
+ 'memmove', 'memcmp', 'memchr', 'memset', 'clock', 'time', 'difftime', 'mktime',
+ 'asctime', 'ctime', 'gmtime', 'localtime', 'strftime'
+ ),
+ 4 => array(
+ 'auto', 'char', 'const', 'double', 'float', 'int', 'long',
+ 'register', 'short', 'signed', 'static', 'struct',
+ 'typedef', 'union', 'unsigned', 'void', 'volatile', 'extern', 'jmp_buf',
+ 'signal', 'raise', 'va_list', 'ptrdiff_t', 'size_t', 'FILE', 'fpos_t',
+ 'div_t', 'ldiv_t', 'clock_t', 'time_t', 'tm', 'wchar_t',
+
+ 'int8', 'int16', 'int32', 'int64',
+ 'uint8', 'uint16', 'uint32', 'uint64',
+
+ 'int_fast8_t', 'int_fast16_t', 'int_fast32_t', 'int_fast64_t',
+ 'uint_fast8_t', 'uint_fast16_t', 'uint_fast32_t', 'uint_fast64_t',
+
+ 'int_least8_t', 'int_least16_t', 'int_least32_t', 'int_least64_t',
+ 'uint_least8_t', 'uint_least16_t', 'uint_least32_t', 'uint_least64_t',
+
+ 'int8_t', 'int16_t', 'int32_t', 'int64_t',
+ 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t',
+
+ 'intmax_t', 'uintmax_t', 'intptr_t', 'uintptr_t',
+
+ // Mac-specific types:
+ 'CFArrayRef', 'CFDictionaryRef', 'CFMutableDictionaryRef', 'CFBundleRef', 'CFSetRef', 'CFStringRef',
+ 'CFURLRef', 'CFLocaleRef', 'CFDateFormatterRef', 'CFNumberFormatterRef', 'CFPropertyListRef',
+ 'CFTreeRef', 'CFWriteStreamRef', 'CFCharacterSetRef', 'CFMutableStringRef', 'CFNotificationRef',
+ 'CFReadStreamRef', 'CFNull', 'CFAllocatorRef', 'CFBagRef', 'CFBinaryHeapRef',
+ 'CFBitVectorRef', 'CFBooleanRef', 'CFDataRef', 'CFDateRef', 'CFMachPortRef', 'CFMessagePortRef',
+ 'CFMutableArrayRef', 'CFMutableBagRef', 'CFMutableBitVectorRef', 'CFMutableCharacterSetRef',
+ 'CFMutableDataRef', 'CFMutableSetRef', 'CFNumberRef', 'CFPlugInRef', 'CFPlugInInstanceRef',
+ 'CFRunLoopRef', 'CFRunLoopObserverRef', 'CFRunLoopSourceRef', 'CFRunLoopTimerRef', 'CFSocketRef',
+ 'CFTimeZoneRef', 'CFTypeRef', 'CFUserNotificationRef', 'CFUUIDRef', 'CFXMLNodeRef', 'CFXMLParserRef',
+ 'CFXMLTreeRef'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #0000dd;',
+ 4 => 'color: #0000ff;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #ff0000;',
+ 2 => 'color: #339900;',
+ 'MULTI' => 'color: #ff0000; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #666666;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #00eeff;',
+ 2 => 'color: #00eeff;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAMEL}.html',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/c_winapi.php b/platform/www/vendor/geshi/geshi/src/geshi/c_winapi.php
new file mode 100644
index 0000000..52ea491
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/c_winapi.php
@@ -0,0 +1,870 @@
+<?php
+/*************************************************************************************
+ * c_winapi.php
+ * -----
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Contributors:
+ * - Jack Lloyd (lloyd@randombit.net)
+ * - Michael Mol (mikemol@gmail.com)
+ * Copyright: (c) 2012 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/08/12
+ *
+ * C (WinAPI) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/01/22 (1.0.8.3)
+ * - Made keywords case-sensitive.
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/XX/XX (1.0.4)
+ * - Added a couple of new keywords (Jack Lloyd)
+ * 2004/11/27 (1.0.3)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ * - Added support for URLs
+ * 2004/08/05 (1.0.1)
+ * - Added support for symbols
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2009/02/08)
+ * -------------------------
+ * - Get a list of inbuilt functions to add (and explore C more
+ * to complete this rather bare language file
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'C (WinAPI)',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Multiline-continued single-line comments
+ 1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Multiline-continued preprocessor define
+ 2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[\\\\abfnrtv\'\"?\n]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'if', 'return', 'while', 'case', 'continue', 'default',
+ 'do', 'else', 'for', 'switch', 'goto'
+ ),
+ 2 => array(
+ 'null', 'false', 'break', 'true', 'function', 'enum', 'extern', 'inline'
+ ),
+ 3 => array(
+ // assert.h
+ 'assert',
+
+ //complex.h
+ 'cabs', 'cacos', 'cacosh', 'carg', 'casin', 'casinh', 'catan',
+ 'catanh', 'ccos', 'ccosh', 'cexp', 'cimag', 'cis', 'clog', 'conj',
+ 'cpow', 'cproj', 'creal', 'csin', 'csinh', 'csqrt', 'ctan', 'ctanh',
+
+ //ctype.h
+ 'digittoint', 'isalnum', 'isalpha', 'isascii', 'isblank', 'iscntrl',
+ 'isdigit', 'isgraph', 'islower', 'isprint', 'ispunct', 'isspace',
+ 'isupper', 'isxdigit', 'toascii', 'tolower', 'toupper',
+
+ //inttypes.h
+ 'imaxabs', 'imaxdiv', 'strtoimax', 'strtoumax', 'wcstoimax',
+ 'wcstoumax',
+
+ //locale.h
+ 'localeconv', 'setlocale',
+
+ //math.h
+ 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'exp',
+ 'fabs', 'floor', 'frexp', 'ldexp', 'log', 'log10', 'modf', 'pow',
+ 'sin', 'sinh', 'sqrt', 'tan', 'tanh',
+
+ //setjmp.h
+ 'longjmp', 'setjmp',
+
+ //signal.h
+ 'raise',
+
+ //stdarg.h
+ 'va_arg', 'va_copy', 'va_end', 'va_start',
+
+ //stddef.h
+ 'offsetof',
+
+ //stdio.h
+ 'clearerr', 'fclose', 'fdopen', 'feof', 'ferror', 'fflush', 'fgetc',
+ 'fgetpos', 'fgets', 'fopen', 'fprintf', 'fputc', 'fputchar',
+ 'fputs', 'fread', 'freopen', 'fscanf', 'fseek', 'fsetpos', 'ftell',
+ 'fwrite', 'getc', 'getch', 'getchar', 'gets', 'perror', 'printf',
+ 'putc', 'putchar', 'puts', 'remove', 'rename', 'rewind', 'scanf',
+ 'setbuf', 'setvbuf', 'snprintf', 'sprintf', 'sscanf', 'tmpfile',
+ 'tmpnam', 'ungetc', 'vfprintf', 'vfscanf', 'vprintf', 'vscanf',
+ 'vsprintf', 'vsscanf',
+
+ //stdlib.h
+ 'abort', 'abs', 'atexit', 'atof', 'atoi', 'atol', 'bsearch',
+ 'calloc', 'div', 'exit', 'free', 'getenv', 'itoa', 'labs', 'ldiv',
+ 'ltoa', 'malloc', 'qsort', 'rand', 'realloc', 'srand', 'strtod',
+ 'strtol', 'strtoul', 'system',
+
+ //string.h
+ 'memchr', 'memcmp', 'memcpy', 'memmove', 'memset', 'strcat',
+ 'strchr', 'strcmp', 'strcoll', 'strcpy', 'strcspn', 'strerror',
+ 'strlen', 'strncat', 'strncmp', 'strncpy', 'strpbrk', 'strrchr',
+ 'strspn', 'strstr', 'strtok', 'strxfrm',
+
+ //time.h
+ 'asctime', 'clock', 'ctime', 'difftime', 'gmtime', 'localtime',
+ 'mktime', 'strftime', 'time',
+
+ //wchar.h
+ 'btowc', 'fgetwc', 'fgetws', 'fputwc', 'fputws', 'fwide',
+ 'fwprintf', 'fwscanf', 'getwc', 'getwchar', 'mbrlen', 'mbrtowc',
+ 'mbsinit', 'mbsrtowcs', 'putwc', 'putwchar', 'swprintf', 'swscanf',
+ 'ungetwc', 'vfwprintf', 'vswprintf', 'vwprintf', 'wcrtomb',
+ 'wcscat', 'wcschr', 'wcscmp', 'wcscoll', 'wcscpy', 'wcscspn',
+ 'wcsftime', 'wcslen', 'wcsncat', 'wcsncmp', 'wcsncpy', 'wcspbrk',
+ 'wcsrchr', 'wcsrtombs', 'wcsspn', 'wcsstr', 'wcstod', 'wcstok',
+ 'wcstol', 'wcstoul', 'wcsxfrm', 'wctob', 'wmemchr', 'wmemcmp',
+ 'wmemcpy', 'wmemmove', 'wmemset', 'wprintf', 'wscanf',
+
+ //wctype.h
+ 'iswalnum', 'iswalpha', 'iswcntrl', 'iswctype', 'iswdigit',
+ 'iswgraph', 'iswlower', 'iswprint', 'iswpunct', 'iswspace',
+ 'iswupper', 'iswxdigit', 'towctrans', 'towlower', 'towupper',
+ 'wctrans', 'wctype'
+ ),
+ 4 => array(
+ 'auto', 'char', 'const', 'double', 'float', 'int', 'long',
+ 'register', 'short', 'signed', 'sizeof', 'static', 'struct',
+ 'typedef', 'union', 'unsigned', 'void', 'volatile', 'wchar_t',
+
+ 'int8', 'int16', 'int32', 'int64',
+ 'uint8', 'uint16', 'uint32', 'uint64',
+
+ 'int_fast8_t', 'int_fast16_t', 'int_fast32_t', 'int_fast64_t',
+ 'uint_fast8_t', 'uint_fast16_t', 'uint_fast32_t', 'uint_fast64_t',
+
+ 'int_least8_t', 'int_least16_t', 'int_least32_t', 'int_least64_t',
+ 'uint_least8_t', 'uint_least16_t', 'uint_least32_t', 'uint_least64_t',
+
+ 'int8_t', 'int16_t', 'int32_t', 'int64_t',
+ 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t',
+
+ 'intmax_t', 'uintmax_t', 'intptr_t', 'uintptr_t',
+ 'size_t', 'off_t'
+ ),
+ // Public API
+ 5 => array(
+ 'AssignProcessToJobObject', 'CommandLineToArgvW', 'ConvertThreadToFiber',
+ 'CreateFiber', 'CreateJobObjectA', 'CreateJobObjectW', 'CreateProcessA',
+ 'CreateProcessAsUserA', 'CreateProcessAsUserW', 'CreateProcessW',
+ 'CreateRemoteThread', 'CreateThread', 'DeleteFiber', 'ExitProcess',
+ 'ExitThread', 'FreeEnvironmentStringsA', 'FreeEnvironmentStringsW',
+ 'GetCommandLineA', 'GetCommandLineW', 'GetCurrentProcess',
+ 'GetCurrentProcessId', 'GetCurrentThread', 'GetCurrentThreadId',
+ 'GetEnvironmentStringsA', 'GetEnvironmentStringsW',
+ 'GetEnvironmentVariableA', 'GetEnvironmentVariableW', 'GetExitCodeProcess',
+ 'GetExitCodeThread', 'GetGuiResources', 'GetPriorityClass',
+ 'GetProcessAffinityMask', 'GetProcessPriorityBoost',
+ 'GetProcessShutdownParameters', 'GetProcessTimes', 'GetProcessVersion',
+ 'GetProcessWorkingSetSize', 'GetStartupInfoA', 'GetStartupInfoW',
+ 'GetThreadPriority', 'GetThreadPriorityBoost', 'GetThreadTimes',
+ 'OpenJobObjectA', 'OpenJobObjectW', 'OpenProcess',
+ 'QueryInformationJobObject', 'ResumeThread', 'SetEnvironmentVariableA',
+ 'SetEnvironmentVariableW', 'SetInformationJobObject', 'SetPriorityClass',
+ 'SetProcessAffinityMask', 'SetProcessPriorityBoost',
+ 'SetProcessShutdownParameters', 'SetProcessWorkingSetSize',
+ 'SetThreadAffinityMask', 'SetThreadIdealProcessor', 'SetThreadPriority',
+ 'SetThreadPriorityBoost', 'Sleep', 'SleepEx', 'SuspendThread',
+ 'SwitchToFiber', 'SwitchToThread', 'TerminateJobObject', 'TerminateProcess',
+ 'TerminateThread', 'WaitForInputIdle', 'WinExec',
+
+ '_hread', '_hwrite', '_lclose', '_lcreat', '_llseek', '_lopen', '_lread',
+ '_lwrite', 'AreFileApisANSI', 'CancelIo', 'CopyFileA', 'CopyFileW',
+ 'CreateDirectoryA', 'CreateDirectoryExA', 'CreateDirectoryExW',
+ 'CreateDirectoryW', 'CreateFileA', 'CreateFileW', 'DeleteFileA',
+ 'DeleteFileW', 'FindClose', 'FindCloseChangeNotification',
+ 'FindFirstChangeNotificationA', 'FindFirstChangeNotificationW',
+ 'FindFirstFileA', 'FindFirstFileW', 'FindNextFileA', 'FindNextFileW',
+ 'FlushFileBuffers', 'GetCurrentDirectoryA', 'GetCurrentDirectoryW',
+ 'GetDiskFreeSpaceA', 'GetDiskFreeSpaceExA', 'GetDiskFreeSpaceExW',
+ 'GetDiskFreeSpaceW', 'GetDriveTypeA', 'GetDriveTypeW', 'GetFileAttributesA',
+ 'GetFileAttributesExA', 'GetFileAttributesExW', 'GetFileAttributesW',
+ 'GetFileInformationByHandle', 'GetFileSize', 'GetFileType',
+ 'GetFullPathNameA', 'GetFullPathNameW', 'GetLogicalDrives',
+ 'GetLogicalDriveStringsA', 'GetLogicalDriveStringsW', 'GetLongPathNameA',
+ 'GetLongPathNameW', 'GetShortPathNameA', 'GetShortPathNameW',
+ 'GetTempFileNameA', 'GetTempFileNameW', 'GetTempPathA', 'GetTempPathW',
+ 'LockFile', 'MoveFileA', 'MoveFileW', 'MulDiv', 'OpenFile',
+ 'QueryDosDeviceA', 'QueryDosDeviceW', 'ReadFile', 'ReadFileEx',
+ 'RemoveDirectoryA', 'RemoveDirectoryW', 'SearchPathA', 'SearchPathW',
+ 'SetCurrentDirectoryA', 'SetCurrentDirectoryW', 'SetEndOfFile',
+ 'SetFileApisToANSI', 'SetFileApisToOEM', 'SetFileAttributesA',
+ 'SetFileAttributesW', 'SetFilePointer', 'SetHandleCount',
+ 'SetVolumeLabelA', 'SetVolumeLabelW', 'UnlockFile', 'WriteFile',
+ 'WriteFileEx',
+
+ 'DeviceIoControl',
+
+ 'GetModuleFileNameA', 'GetModuleFileNameW', 'GetProcAddress',
+ 'LoadLibraryA', 'LoadLibraryExA', 'LoadLibraryExW', 'LoadLibraryW',
+ 'LoadModule',
+
+ 'GetPrivateProfileIntA', 'GetPrivateProfileIntW',
+ 'GetPrivateProfileSectionA', 'GetPrivateProfileSectionNamesA',
+ 'GetPrivateProfileSectionNamesW', 'GetPrivateProfileSectionW',
+ 'GetPrivateProfileStringA', 'GetPrivateProfileStringW',
+ 'GetPrivateProfileStructA', 'GetPrivateProfileStructW',
+ 'GetProfileIntA', 'GetProfileIntW', 'GetProfileSectionA',
+ 'GetProfileSectionW', 'GetProfileStringA', 'GetProfileStringW',
+ 'RegCloseKey', 'RegConnectRegistryA', 'RegConnectRegistryW',
+ 'RegCreateKeyA', 'RegCreateKeyExA', 'RegCreateKeyExW',
+ 'RegCreateKeyW', 'RegDeleteKeyA', 'RegDeleteKeyW', 'RegDeleteValueA',
+ 'RegDeleteValueW', 'RegEnumKeyA', 'RegEnumKeyExA', 'RegEnumKeyExW',
+ 'RegEnumKeyW', 'RegEnumValueA', 'RegEnumValueW', 'RegFlushKey',
+ 'RegGetKeySecurity', 'RegLoadKeyA', 'RegLoadKeyW',
+ 'RegNotifyChangeKeyValue', 'RegOpenKeyA', 'RegOpenKeyExA', 'RegOpenKeyExW',
+ 'RegOpenKeyW', 'RegOverridePredefKey', 'RegQueryInfoKeyA',
+ 'RegQueryInfoKeyW', 'RegQueryMultipleValuesA', 'RegQueryMultipleValuesW',
+ 'RegQueryValueA', 'RegQueryValueExA', 'RegQueryValueExW', 'RegQueryValueW',
+ 'RegReplaceKeyA', 'RegReplaceKeyW', 'RegRestoreKeyA', 'RegRestoreKeyW',
+ 'RegSaveKeyA', 'RegSaveKeyW', 'RegSetKeySecurity', 'RegSetValueA',
+ 'RegSetValueExA', 'RegSetValueExW', 'RegSetValueW', 'RegUnLoadKeyA',
+ 'RegUnLoadKeyW', 'WritePrivateProfileSectionA', 'WritePrivateProfileSectionW',
+ 'WritePrivateProfileStringA', 'WritePrivateProfileStringW',
+ 'WritePrivateProfileStructA', 'WritePrivateProfileStructW',
+ 'WriteProfileSectionA', 'WriteProfileSectionW', 'WriteProfileStringA',
+ 'WriteProfileStringW',
+
+ 'AccessCheck', 'AccessCheckAndAuditAlarmA', 'AccessCheckAndAuditAlarmW',
+ 'AccessCheckByType', 'AccessCheckByTypeAndAuditAlarmA',
+ 'AccessCheckByTypeAndAuditAlarmW', 'AccessCheckByTypeResultList',
+ 'AccessCheckByTypeResultListAndAuditAlarmA', 'AccessCheckByTypeResultListAndAuditAlarmW',
+ 'AddAccessAllowedAce', 'AddAccessAllowedAceEx', 'AddAccessAllowedObjectAce',
+ 'AddAccessDeniedAce', 'AddAccessDeniedAceEx', 'AddAccessDeniedObjectAce',
+ 'AddAce', 'AddAuditAccessAce', 'AddAuditAccessAceEx', 'AddAuditAccessObjectAce',
+ 'AdjustTokenGroups', 'AdjustTokenPrivileges', 'AllocateAndInitializeSid',
+ 'AllocateLocallyUniqueId', 'AreAllAccessesGranted', 'AreAnyAccessesGranted',
+ 'BuildExplicitAccessWithNameA', 'BuildExplicitAccessWithNameW',
+ 'BuildImpersonateExplicitAccessWithNameA', 'BuildImpersonateExplicitAccessWithNameW',
+ 'BuildImpersonateTrusteeA', 'BuildImpersonateTrusteeW', 'BuildSecurityDescriptorA',
+ 'BuildSecurityDescriptorW', 'BuildTrusteeWithNameA', 'BuildTrusteeWithNameW',
+ 'BuildTrusteeWithSidA', 'BuildTrusteeWithSidW',
+ 'ConvertToAutoInheritPrivateObjectSecurity', 'CopySid', 'CreatePrivateObjectSecurity',
+ 'CreatePrivateObjectSecurityEx', 'CreateRestrictedToken', 'DeleteAce',
+ 'DestroyPrivateObjectSecurity', 'DuplicateToken', 'DuplicateTokenEx',
+ 'EqualPrefixSid', 'EqualSid', 'FindFirstFreeAce', 'FreeSid', 'GetAce',
+ 'GetAclInformation', 'GetAuditedPermissionsFromAclA', 'GetAuditedPermissionsFromAclW',
+ 'GetEffectiveRightsFromAclA', 'GetEffectiveRightsFromAclW',
+ 'GetExplicitEntriesFromAclA', 'GetExplicitEntriesFromAclW', 'GetFileSecurityA',
+ 'GetFileSecurityW', 'GetKernelObjectSecurity', 'GetLengthSid', 'GetMultipleTrusteeA',
+ 'GetMultipleTrusteeOperationA', 'GetMultipleTrusteeOperationW', 'GetMultipleTrusteeW',
+ 'GetNamedSecurityInfoA', 'GetNamedSecurityInfoW', 'GetPrivateObjectSecurity',
+ 'GetSecurityDescriptorControl', 'GetSecurityDescriptorDacl',
+ 'GetSecurityDescriptorGroup', 'GetSecurityDescriptorLength',
+ 'GetSecurityDescriptorOwner', 'GetSecurityDescriptorSacl', 'GetSecurityInfo',
+ 'GetSidIdentifierAuthority', 'GetSidLengthRequired', 'GetSidSubAuthority',
+ 'GetSidSubAuthorityCount', 'GetTokenInformation', 'GetTrusteeFormA',
+ 'GetTrusteeFormW', 'GetTrusteeNameA', 'GetTrusteeNameW', 'GetTrusteeTypeA',
+ 'GetTrusteeTypeW', 'GetUserObjectSecurity', 'ImpersonateLoggedOnUser',
+ 'ImpersonateNamedPipeClient', 'ImpersonateSelf', 'InitializeAcl',
+ 'InitializeSecurityDescriptor', 'InitializeSid', 'IsTokenRestricted', 'IsValidAcl',
+ 'IsValidSecurityDescriptor', 'IsValidSid', 'LogonUserA', 'LogonUserW',
+ 'LookupAccountNameA', 'LookupAccountNameW', 'LookupAccountSidA', 'LookupAccountSidW',
+ 'LookupPrivilegeDisplayNameA', 'LookupPrivilegeDisplayNameW', 'LookupPrivilegeNameA',
+ 'LookupPrivilegeNameW', 'LookupPrivilegeValueA', 'LookupPrivilegeValueW',
+ 'LookupSecurityDescriptorPartsA', 'LookupSecurityDescriptorPartsW', 'MakeAbsoluteSD',
+ 'MakeSelfRelativeSD', 'MapGenericMask', 'ObjectCloseAuditAlarmA',
+ 'ObjectCloseAuditAlarmW', 'ObjectDeleteAuditAlarmA', 'ObjectDeleteAuditAlarmW',
+ 'ObjectOpenAuditAlarmA', 'ObjectOpenAuditAlarmW', 'ObjectPrivilegeAuditAlarmA',
+ 'ObjectPrivilegeAuditAlarmW', 'OpenProcessToken', 'OpenThreadToken', 'PrivilegeCheck',
+ 'PrivilegedServiceAuditAlarmA', 'PrivilegedServiceAuditAlarmW', 'RevertToSelf',
+ 'SetAclInformation', 'SetEntriesInAclA', 'SetEntriesInAclW', 'SetFileSecurityA',
+ 'SetFileSecurityW', 'SetKernelObjectSecurity', 'SetNamedSecurityInfoA',
+ 'SetNamedSecurityInfoW', 'SetPrivateObjectSecurity', 'SetPrivateObjectSecurityEx',
+ 'SetSecurityDescriptorControl', 'SetSecurityDescriptorDacl',
+ 'SetSecurityDescriptorGroup', 'SetSecurityDescriptorOwner',
+ 'SetSecurityDescriptorSacl', 'SetSecurityInfo', 'SetThreadToken',
+ 'SetTokenInformation', 'SetUserObjectSecurity', 'ChangeServiceConfig2A',
+ 'ChangeServiceConfig2W', 'ChangeServiceConfigA', 'ChangeServiceConfigW',
+ 'CloseServiceHandle', 'ControlService', 'CreateServiceA', 'CreateServiceW',
+ 'DeleteService', 'EnumDependentServicesA', 'EnumDependentServicesW',
+ 'EnumServicesStatusA', 'EnumServicesStatusW', 'GetServiceDisplayNameA',
+ 'GetServiceDisplayNameW', 'GetServiceKeyNameA', 'GetServiceKeyNameW',
+ 'LockServiceDatabase', 'NotifyBootConfigStatus', 'OpenSCManagerA', 'OpenSCManagerW',
+ 'OpenServiceA', 'OpenServiceW', 'QueryServiceConfig2A', 'QueryServiceConfig2W',
+ 'QueryServiceConfigA', 'QueryServiceConfigW', 'QueryServiceLockStatusA',
+ 'QueryServiceLockStatusW', 'QueryServiceObjectSecurity', 'QueryServiceStatus',
+ 'RegisterServiceCtrlHandlerA', 'RegisterServiceCtrlHandlerW',
+ 'SetServiceObjectSecurity', 'SetServiceStatus', 'StartServiceA',
+ 'StartServiceCtrlDispatcherA', 'StartServiceCtrlDispatcherW', 'StartServiceW',
+ 'UnlockServiceDatabase',
+
+ 'MultinetGetConnectionPerformanceA', 'MultinetGetConnectionPerformanceW',
+ 'NetAlertRaise', 'NetAlertRaiseEx', 'NetApiBufferAllocate', 'NetApiBufferFree',
+ 'NetApiBufferReallocate', 'NetApiBufferSize', 'NetConnectionEnum', 'NetFileClose',
+ 'NetFileGetInfo', 'NetGetAnyDCName', 'NetGetDCName', 'NetGetDisplayInformationIndex',
+ 'NetGroupAdd', 'NetGroupAddUser', 'NetGroupDel', 'NetGroupDelUser', 'NetGroupEnum',
+ 'NetGroupGetInfo', 'NetGroupGetUsers', 'NetGroupSetInfo', 'NetGroupSetUsers',
+ 'NetLocalGroupAdd', 'NetLocalGroupAddMember', 'NetLocalGroupAddMembers',
+ 'NetLocalGroupDel', 'NetLocalGroupDelMember', 'NetLocalGroupDelMembers',
+ 'NetLocalGroupEnum', 'NetLocalGroupGetInfo', 'NetLocalGroupGetMembers',
+ 'NetLocalGroupSetInfo', 'NetLocalGroupSetMembers', 'NetMessageBufferSend',
+ 'NetMessageNameAdd', 'NetMessageNameDel', 'NetMessageNameEnum',
+ 'NetMessageNameGetInfo', 'NetQueryDisplayInformation', 'NetRemoteComputerSupports',
+ 'NetRemoteTOd', 'NetReplExportDirAdd', 'NetReplExportDirDel', 'NetReplExportDirEnum',
+ 'NetReplExportDirGetInfo', 'NetReplExportDirLock', 'NetReplExportDirSetInfo',
+ 'NetReplExportDirUnlock', 'NetReplGetInfo', 'NetReplImportDirAdd',
+ 'NetReplImportDirDel', 'NetReplImportDirEnum', 'NetReplImportDirGetInfo',
+ 'NetReplImportDirLock', 'NetReplImportDirUnlock', 'NetReplSetInfo',
+ 'NetScheduleJobAdd', 'NetScheduleJobDel', 'NetScheduleJobEnum',
+ 'NetScheduleJobGetInfo', 'NetServerComputerNameAdd', 'NetServerComputerNameDel',
+ 'NetServerDiskEnum', 'NetServerEnum', 'NetServerEnumEx', 'NetServerGetInfo',
+ 'NetServerSetInfo', 'NetServerTransportAdd', 'NetServerTransportAddEx',
+ 'NetServerTransportDel', 'NetServerTransportEnum', 'NetSessionDel', 'NetSessionEnum',
+ 'NetSessionGetInfo', 'NetShareAdd', 'NetShareCheck', 'NetShareDel', 'NetShareEnum',
+ 'NetShareGetInfo', 'NetShareSetInfo', 'NetStatisticsGet', 'NetUseAdd', 'NetUseDel',
+ 'NetUseEnum', 'NetUseGetInfo', 'NetUserAdd', 'NetUserChangePassword', 'NetUserDel',
+ 'NetUserEnum', 'NetUserGetGroups', 'NetUserGetInfo', 'NetUserGetLocalGroups',
+ 'NetUserModalsGet', 'NetUserModalsSet', 'NetUserSetGroups', 'NetUserSetInfo',
+ 'NetWkstaGetInfo', 'NetWkstaSetInfo', 'NetWkstaTransportAdd', 'NetWkstaTransportDel',
+ 'NetWkstaTransportEnum', 'NetWkstaUserEnum', 'NetWkstaUserGetInfo',
+ 'NetWkstaUserSetInfo', 'WNetAddConnection2A', 'WNetAddConnection2W',
+ 'WNetAddConnection3A', 'WNetAddConnection3W', 'WNetAddConnectionA',
+ 'WNetAddConnectionW', 'WNetCancelConnection2A', 'WNetCancelConnection2W',
+ 'WNetCancelConnectionA', 'WNetCancelConnectionW', 'WNetCloseEnum',
+ 'WNetConnectionDialog', 'WNetConnectionDialog1A', 'WNetConnectionDialog1W',
+ 'WNetDisconnectDialog', 'WNetDisconnectDialog1A', 'WNetDisconnectDialog1W',
+ 'WNetEnumResourceA', 'WNetEnumResourceW', 'WNetGetConnectionA', 'WNetGetConnectionW',
+ 'WNetGetLastErrorA', 'WNetGetLastErrorW', 'WNetGetNetworkInformationA',
+ 'WNetGetNetworkInformationW', 'WNetGetProviderNameA', 'WNetGetProviderNameW',
+ 'WNetGetResourceInformationA', 'WNetGetResourceInformationW',
+ 'WNetGetResourceParentA', 'WNetGetResourceParentW', 'WNetGetUniversalNameA',
+ 'WNetGetUniversalNameW', 'WNetGetUserA', 'WNetGetUserW', 'WNetOpenEnumA',
+ 'WNetOpenEnumW', 'WNetUseConnectionA', 'WnetUseConnectionW',
+
+ 'accept', 'bind', 'closesocket', 'connect', 'gethostbyaddr', 'gethostbyname',
+ 'gethostname', 'getpeername', 'getprotobyname', 'getprotobynumber', 'getservbyname',
+ 'getservbyport', 'getsockname', 'getsockopt', 'htonl', 'htons', 'inet_addr',
+ 'inet_ntoa', 'ioctlsocket', 'listen', 'ntohl', 'ntohs', 'recv', 'recvfrom', 'select',
+ 'send', 'sendto', 'setsockopt', 'shutdown', 'socket', 'WSAAccept',
+ 'WSAAddressToStringA', 'WSAAddressToStringW', 'WSAAsyncGetHostByAddr',
+ 'WSAAsyncGetHostByName', 'WSAAsyncGetProtoByName', 'WSAAsyncGetProtoByNumber',
+ 'WSAAsyncGetServByName', 'WSAAsyncGetServByPort', 'WSAAsyncSelect',
+ 'WSACancelAsyncRequest', 'WSACancelBlockingCall', 'WSACleanup', 'WSACloseEvent',
+ 'WSAConnect', 'WSACreateEvent', 'WSADuplicateSocketA', 'WSADuplicateSocketW',
+ 'WSAEnumNameSpaceProvidersA', 'WSAEnumNameSpaceProvidersW', 'WSAEnumNetworkEvents',
+ 'WSAEnumProtocolsA', 'WSAEnumProtocolsW', 'WSAEventSelect', 'WSAGetLastError',
+ 'WSAGetOverlappedResult', 'WSAGetQOSByName', 'WSAGetServiceClassInfoA',
+ 'WSAGetServiceClassInfoW', 'WSAGetServiceClassNameByClassIdA',
+ 'WSAGetServiceClassNameByClassIdW', 'WSAHtonl', 'WSAHtons', 'WSAInstallServiceClassA',
+ 'WSAInstallServiceClassW', 'WSAIoctl', 'WSAIsBlocking', 'WSAJoinLeaf',
+ 'WSALookupServiceBeginA', 'WSALookupServiceBeginW', 'WSALookupServiceEnd',
+ 'WSALookupServiceNextA', 'WSALookupServiceNextW', 'WSANtohl', 'WSANtohs',
+ 'WSAProviderConfigChange', 'WSARecv', 'WSARecvDisconnect', 'WSARecvFrom',
+ 'WSARemoveServiceClass', 'WSAResetEvent', 'WSASend', 'WSASendDisconnect', 'WSASendTo',
+ 'WSASetBlockingHook', 'WSASetEvent', 'WSASetLastError', 'WSASetServiceA',
+ 'WSASetServiceW', 'WSASocketA', 'WSASocketW', 'WSAStartup', 'WSAStringToAddressA',
+ 'WSAStringToAddressW', 'WSAUnhookBlockingHook', 'WSAWaitForMultipleEvents',
+ 'WSCDeinstallProvider', 'WSCEnableNSProvider', 'WSCEnumProtocols',
+ 'WSCGetProviderPath', 'WSCInstallNameSpace', 'WSCInstallProvider',
+ 'WSCUnInstallNameSpace',
+
+ 'ContinueDebugEvent', 'DebugActiveProcess', 'DebugBreak', 'FatalExit',
+ 'FlushInstructionCache', 'GetThreadContext', 'GetThreadSelectorEntry',
+ 'IsDebuggerPresent', 'OutputDebugStringA', 'OutputDebugStringW', 'ReadProcessMemory',
+ 'SetDebugErrorLevel', 'SetThreadContext', 'WaitForDebugEvent', 'WriteProcessMemory',
+
+ 'CloseHandle', 'DuplicateHandle', 'GetHandleInformation', 'SetHandleInformation',
+
+ 'AdjustWindowRect', 'AdjustWindowRectEx', 'AllowSetForegroundWindow',
+ 'AnimateWindow', 'AnyPopup', 'ArrangeIconicWindows', 'BeginDeferWindowPos',
+ 'BringWindowToTop', 'CascadeWindows', 'ChildWindowFromPoint',
+ 'ChildWindowFromPointEx', 'CloseWindow', 'CreateWindowExA', 'CreateWindowExW',
+ 'DeferWindowPos', 'DestroyWindow', 'EndDeferWindowPos', 'EnumChildWindows',
+ 'EnumThreadWindows', 'EnumWindows', 'FindWindowA', 'FindWindowExA', 'FindWindowExW',
+ 'FindWindowW', 'GetAltTabInfoA', 'GetAltTabInfoW', 'GetAncestor', 'GetClientRect',
+ 'GetDesktopWindow', 'GetForegroundWindow', 'GetGUIThreadInfo', 'GetLastActivePopup',
+ 'GetLayout', 'GetParent', 'GetProcessDefaultLayout', 'GetTitleBarInf', 'GetTopWindow',
+ 'GetWindow', 'GetWindowInfo', 'GetWindowModuleFileNameA', 'GetWindowModuleFileNameW',
+ 'GetWindowPlacement', 'GetWindowRect', 'GetWindowTextA', 'GetWindowTextLengthA',
+ 'GetWindowTextLengthW', 'GetWindowTextW', 'GetWindowThreadProcessId', 'IsChild',
+ 'IsIconic', 'IsWindow', 'IsWindowUnicode', 'IsWindowVisible', 'IsZoomed',
+ 'LockSetForegroundWindow', 'MoveWindow', 'OpenIcon', 'RealChildWindowFromPoint',
+ 'RealGetWindowClassA', 'RealGetWindowClassW', 'SetForegroundWindow',
+ 'SetLayeredWindowAttributes', 'SetLayout', 'SetParent', 'SetProcessDefaultLayout',
+ 'SetWindowPlacement', 'SetWindowPos', 'SetWindowTextA', 'SetWindowTextW',
+ 'ShowOwnedPopups', 'ShowWindow', 'ShowWindowAsync', 'TileWindows',
+ 'UpdateLayeredWindow', 'WindowFromPoint',
+
+ 'CreateDialogIndirectParamA', 'CreateDialogIndirectParamW', 'CreateDialogParamA',
+ 'CreateDialogParamW', 'DefDlgProcA', 'DefDlgProcW', 'DialogBoxIndirectParamA',
+ 'DialogBoxIndirectParamW', 'DialogBoxParamA', 'DialogBoxParamW', 'EndDialog',
+ 'GetDialogBaseUnits', 'GetDlgCtrlID', 'GetDlgItem', 'GetDlgItemInt',
+ 'GetDlgItemTextA', 'GetDlgItemTextW', 'GetNextDlgGroupItem', 'GetNextDlgTabItem',
+ 'IsDialogMessageA', 'IsDialogMessageW', 'MapDialogRect', 'MessageBoxA',
+ 'MessageBoxExA', 'MessageBoxExW', 'MessageBoxIndirectA', 'MessageBoxIndirectW',
+ 'MessageBoxW', 'SendDlgItemMessageA', 'SendDlgItemMessageW', 'SetDlgItemInt',
+ 'SetDlgItemTextA', 'SetDlgItemTextW',
+
+ 'GetWriteWatch', 'GlobalMemoryStatus', 'GlobalMemoryStatusEx', 'IsBadCodePtr',
+ 'IsBadReadPtr', 'IsBadStringPtrA', 'IsBadStringPtrW', 'IsBadWritePtr',
+ 'ResetWriteWatch', 'AllocateUserPhysicalPages', 'FreeUserPhysicalPages',
+ 'MapUserPhysicalPages', 'MapUserPhysicalPagesScatter', 'GlobalAlloc', 'GlobalFlags',
+ 'GlobalFree', 'GlobalHandle', 'GlobalLock', 'GlobalReAlloc', 'GlobalSize',
+ 'GlobalUnlock', 'LocalAlloc', 'LocalFlags', 'LocalFree', 'LocalHandle', 'LocalLock',
+ 'LocalReAlloc', 'LocalSize', 'LocalUnlock', 'GetProcessHeap', 'GetProcessHeaps',
+ 'HeapAlloc', 'HeapCompact', 'HeapCreate', 'HeapDestroy', 'HeapFree', 'HeapLock',
+ 'HeapReAlloc', 'HeapSize', 'HeapUnlock', 'HeapValidate', 'HeapWalk', 'VirtualAlloc',
+ 'VirtualAllocEx', 'VirtualFree', 'VirtualFreeEx', 'VirtualLock', 'VirtualProtect',
+ 'VirtualProtectEx', 'VirtualQuery', 'VirtualQueryEx', 'VirtualUnlock',
+ 'GetFreeSpace', 'GlobalCompact', 'GlobalFix', 'GlobalUnfix', 'GlobalUnWire',
+ 'GlobalWire', 'IsBadHugeReadPtr', 'IsBadHugeWritePtr', 'LocalCompact', 'LocalShrink',
+
+ 'GetClassInfoA', 'GetClassInfoW', 'GetClassInfoExA', 'GetClassInfoExW',
+ 'GetClassLongA', 'GetClassLongW', 'GetClassLongPtrA', 'GetClassLongPtrW',
+ 'RegisterClassA', 'RegisterClassW', 'RegisterClassExA', 'RegisterClassExW',
+ 'SetClassLongA', 'SetClassLongW', 'SetClassLongPtrA', 'SetClassLongPtrW',
+ 'SetWindowLongA', 'SetWindowLongW', 'SetWindowLongPtrA', 'SetWindowLongPtrW',
+ 'UnregisterClassA', 'UnregisterClassW', 'GetClassWord', 'GetWindowWord',
+ 'SetClassWord', 'SetWindowWord'
+ ),
+ // Native API
+ 6 => array(
+ 'CsrAllocateCaptureBuffer', 'CsrAllocateCapturePointer', 'CsrAllocateMessagePointer',
+ 'CsrCaptureMessageBuffer', 'CsrCaptureMessageString', 'CsrCaptureTimeout',
+ 'CsrClientCallServer', 'CsrClientConnectToServer', 'CsrFreeCaptureBuffer',
+ 'CsrIdentifyAlertableThread', 'CsrNewThread', 'CsrProbeForRead', 'CsrProbeForWrite',
+ 'CsrSetPriorityClass',
+
+ 'LdrAccessResource', 'LdrDisableThreadCalloutsForDll', 'LdrEnumResources',
+ 'LdrFindEntryForAddress', 'LdrFindResource_U', 'LdrFindResourceDirectory_U',
+ 'LdrGetDllHandle', 'LdrGetProcedureAddress', 'LdrInitializeThunk', 'LdrLoadDll',
+ 'LdrProcessRelocationBlock', 'LdrQueryImageFileExecutionOptions',
+ 'LdrQueryProcessModuleInformation', 'LdrShutdownProcess', 'LdrShutdownThread',
+ 'LdrUnloadDll', 'LdrVerifyImageMatchesChecksum',
+
+ 'NtAcceptConnectPort', 'ZwAcceptConnectPort', 'NtCompleteConnectPort',
+ 'ZwCompleteConnectPort', 'NtConnectPort', 'ZwConnectPort', 'NtCreatePort',
+ 'ZwCreatePort', 'NtImpersonateClientOfPort', 'ZwImpersonateClientOfPort',
+ 'NtListenPort', 'ZwListenPort', 'NtQueryInformationPort', 'ZwQueryInformationPort',
+ 'NtReadRequestData', 'ZwReadRequestData', 'NtReplyPort', 'ZwReplyPort',
+ 'NtReplyWaitReceivePort', 'ZwReplyWaitReceivePort', 'NtReplyWaitReplyPort',
+ 'ZwReplyWaitReplyPort', 'NtRequestPort', 'ZwRequestPort', 'NtRequestWaitReplyPort',
+ 'ZwRequestWaitReplyPort', 'NtSecureConnectPort', 'ZwSecureConnectPort',
+ 'NtWriteRequestData', 'ZwWriteRequestData',
+
+ 'NtAccessCheck', 'ZwAccessCheck', 'NtAccessCheckAndAuditAlarm',
+ 'ZwAccessCheckAndAuditAlarm', 'NtAccessCheckByType', 'ZwAccessCheckByType',
+ 'NtAccessCheckByTypeAndAuditAlarm', 'ZwAccessCheckByTypeAndAuditAlarm',
+ 'NtAccessCheckByTypeResultList', 'ZwAccessCheckByTypeResultList',
+ 'NtAdjustGroupsToken', 'ZwAdjustGroupsToken', 'NtAdjustPrivilegesToken',
+ 'ZwAdjustPrivilegesToken', 'NtCloseObjectAuditAlarm', 'ZwCloseObjectAuditAlarm',
+ 'NtCreateToken', 'ZwCreateToken', 'NtDeleteObjectAuditAlarm',
+ 'ZwDeleteObjectAuditAlarm', 'NtDuplicateToken', 'ZwDuplicateToken',
+ 'NtFilterToken', 'ZwFilterToken', 'NtImpersonateThread', 'ZwImpersonateThread',
+ 'NtOpenObjectAuditAlarm', 'ZwOpenObjectAuditAlarm', 'NtOpenProcessToken',
+ 'ZwOpenProcessToken', 'NtOpenThreadToken', 'ZwOpenThreadToken', 'NtPrivilegeCheck',
+ 'ZwPrivilegeCheck', 'NtPrivilegedServiceAuditAlarm', 'ZwPrivilegedServiceAuditAlarm',
+ 'NtPrivilegeObjectAuditAlarm', 'ZwPrivilegeObjectAuditAlarm',
+ 'NtQueryInformationToken', 'ZwQueryInformationToken', 'NtQuerySecurityObject',
+ 'ZwQuerySecurityObject', 'NtSetInformationToken', 'ZwSetInformationToken',
+ 'NtSetSecurityObject', 'ZwSetSecurityObject',
+
+ 'NtAddAtom', 'ZwAddAtom', 'NtDeleteAtom', 'ZwDeleteAtom', 'NtFindAtom', 'ZwFindAtom',
+ 'NtQueryInformationAtom', 'ZwQueryInformationAtom',
+
+ 'NtAlertResumeThread', 'ZwAlertResumeThread', 'NtAlertThread', 'ZwAlertThread',
+ 'NtCreateProcess', 'ZwCreateProcess', 'NtCreateThread', 'ZwCreateThread',
+ 'NtCurrentTeb', 'NtDelayExecution', 'ZwDelayExecution', 'NtGetContextThread',
+ 'ZwGetContextThread', 'NtOpenProcess', 'ZwOpenProcess', 'NtOpenThread',
+ 'ZwOpenThread', 'NtQueryInformationProcess', 'ZwQueryInformationProcess',
+ 'NtQueryInformationThread', 'ZwQueryInformationThread', 'NtQueueApcThread',
+ 'ZwQueueApcThread', 'NtResumeThread', 'ZwResumeThread', 'NtSetContextThread',
+ 'ZwSetContextThread', 'NtSetHighWaitLowThread', 'ZwSetHighWaitLowThread',
+ 'NtSetInformationProcess', 'ZwSetInformationProcess', 'NtSetInformationThread',
+ 'ZwSetInformationThread', 'NtSetLowWaitHighThread', 'ZwSetLowWaitHighThread',
+ 'NtSuspendThread', 'ZwSuspendThread', 'NtTerminateProcess', 'ZwTerminateProcess',
+ 'NtTerminateThread', 'ZwTerminateThread', 'NtTestAlert', 'ZwTestAlert',
+ 'NtYieldExecution', 'ZwYieldExecution',
+
+ 'NtAllocateVirtualMemory', 'ZwAllocateVirtualMemory', 'NtAllocateVirtualMemory64',
+ 'ZwAllocateVirtualMemory64', 'NtAreMappedFilesTheSame', 'ZwAreMappedFilesTheSame',
+ 'NtCreateSection', 'ZwCreateSection', 'NtExtendSection', 'ZwExtendSection',
+ 'NtFlushVirtualMemory', 'ZwFlushVirtualMemory', 'NtFreeVirtualMemory',
+ 'ZwFreeVirtualMemory', 'NtFreeVirtualMemory64', 'ZwFreeVirtualMemory64',
+ 'NtLockVirtualMemory', 'ZwLockVirtualMemory', 'NtMapViewOfSection',
+ 'ZwMapViewOfSection', 'NtMapViewOfVlmSection', 'ZwMapViewOfVlmSection',
+ 'NtOpenSection', 'ZwOpenSection', 'NtProtectVirtualMemory', 'ZwProtectVirtualMemory',
+ 'NtProtectVirtualMemory64', 'ZwProtectVirtualMemory64', 'NtQueryVirtualMemory',
+ 'ZwQueryVirtualMemory', 'NtQueryVirtualMemory64', 'ZwQueryVirtualMemory64',
+ 'NtReadVirtualMemory', 'ZwReadVirtualMemory', 'NtReadVirtualMemory64',
+ 'ZwReadVirtualMemory64', 'NtUnlockVirtualMemory', 'ZwUnlockVirtualMemory',
+ 'NtUnmapViewOfSection', 'ZwUnmapViewOfSection', 'NtUnmapViewOfVlmSection',
+ 'ZwUnmapViewOfVlmSection', 'NtWriteVirtualMemory', 'ZwWriteVirtualMemory',
+ 'NtWriteVirtualMemory64', 'ZwWriteVirtualMemory64',
+
+ 'NtAssignProcessToJobObject', 'ZwAssignProcessToJobObject', 'NtCreateJobObject',
+ 'ZwCreateJobObject', 'NtOpenJobObject', 'ZwOpenJobObject',
+ 'NtQueryInformationJobObject', 'ZwQueryInformationJobObject',
+ 'NtSetInformationJobObject', 'ZwSetInformationJobObject', 'NtTerminateJobObject',
+ 'ZwTerminateJobObject',
+
+ 'NtCancelIoFile', 'ZwCancelIoFile', 'NtCreateFile', 'ZwCreateFile',
+ 'NtCreateIoCompletion', 'ZwCreateIoCompletion', 'NtDeleteFile', 'ZwDeleteFile',
+ 'NtDeviceIoControlFile', 'ZwDeviceIoControlFile', 'NtFlushBuffersFile',
+ 'ZwFlushBuffersFile', 'NtFsControlFile', 'ZwFsControlFile', 'NtLockFile', 'ZwLockFile',
+ 'NtNotifyChangeDirectoryFile', 'ZwNotifyChangeDirectoryFile', 'NtOpenFile',
+ 'ZwOpenFile', 'NtOpenIoCompletion', 'ZwOpenIoCompletion', 'NtQueryAttributesFile',
+ 'ZwQueryAttributesFile', 'NtQueryDirectoryFile', 'ZwQueryDirectoryFile',
+ 'NtQueryEaFile', 'ZwQueryEaFile', 'NtQueryIoCompletion', 'ZwQueryIoCompletion',
+ 'NtQueryQuotaInformationFile', 'ZwQueryQuotaInformationFile',
+ 'NtQueryVolumeInformationFile', 'ZwQueryVolumeInformationFile', 'NtReadFile',
+ 'ZwReadFile', 'NtReadFile64', 'ZwReadFile64', 'NtReadFileScatter', 'ZwReadFileScatter',
+ 'NtRemoveIoCompletion', 'ZwRemoveIoCompletion', 'NtSetEaFile', 'ZwSetEaFile',
+ 'NtSetInformationFile', 'ZwSetInformationFile', 'NtSetIoCompletion',
+ 'ZwSetIoCompletion', 'NtSetQuotaInformationFile', 'ZwSetQuotaInformationFile',
+ 'NtSetVolumeInformationFile', 'ZwSetVolumeInformationFile', 'NtUnlockFile',
+ 'ZwUnlockFile', 'NtWriteFile', 'ZwWriteFile', 'NtWriteFile64','ZwWriteFile64',
+ 'NtWriteFileGather', 'ZwWriteFileGather', 'NtQueryFullAttributesFile',
+ 'ZwQueryFullAttributesFile', 'NtQueryInformationFile', 'ZwQueryInformationFile',
+
+ 'RtlAbortRXact', 'RtlAbsoluteToSelfRelativeSD', 'RtlAcquirePebLock',
+ 'RtlAcquireResourceExclusive', 'RtlAcquireResourceShared', 'RtlAddAccessAllowedAce',
+ 'RtlAddAccessDeniedAce', 'RtlAddAce', 'RtlAddActionToRXact', 'RtlAddAtomToAtomTable',
+ 'RtlAddAttributeActionToRXact', 'RtlAddAuditAccessAce', 'RtlAddCompoundAce',
+ 'RtlAdjustPrivilege', 'RtlAllocateAndInitializeSid', 'RtlAllocateHandle',
+ 'RtlAllocateHeap', 'RtlAnsiCharToUnicodeChar', 'RtlAnsiStringToUnicodeSize',
+ 'RtlAnsiStringToUnicodeString', 'RtlAppendAsciizToString', 'RtlAppendStringToString',
+ 'RtlAppendUnicodeStringToString', 'RtlAppendUnicodeToString', 'RtlApplyRXact',
+ 'RtlApplyRXactNoFlush', 'RtlAreAllAccessesGranted', 'RtlAreAnyAccessesGranted',
+ 'RtlAreBitsClear', 'RtlAreBitsSet', 'RtlAssert', 'RtlCaptureStackBackTrace',
+ 'RtlCharToInteger', 'RtlCheckRegistryKey', 'RtlClearAllBits', 'RtlClearBits',
+ 'RtlClosePropertySet', 'RtlCompactHeap', 'RtlCompareMemory', 'RtlCompareMemoryUlong',
+ 'RtlCompareString', 'RtlCompareUnicodeString', 'RtlCompareVariants',
+ 'RtlCompressBuffer', 'RtlConsoleMultiByteToUnicodeN', 'RtlConvertExclusiveToShared',
+ 'RtlConvertLongToLargeInteger', 'RtlConvertPropertyToVariant',
+ 'RtlConvertSharedToExclusive', 'RtlConvertSidToUnicodeString',
+ 'RtlConvertUiListToApiList', 'RtlConvertUlongToLargeInteger',
+ 'RtlConvertVariantToProperty', 'RtlCopyLuid', 'RtlCopyLuidAndAttributesArray',
+ 'RtlCopySecurityDescriptor', 'RtlCopySid', 'RtlCopySidAndAttributesArray',
+ 'RtlCopyString', 'RtlCopyUnicodeString', 'RtlCreateAcl', 'RtlCreateAndSetSD',
+ 'RtlCreateAtomTable', 'RtlCreateEnvironment', 'RtlCreateHeap',
+ 'RtlCreateProcessParameters', 'RtlCreatePropertySet', 'RtlCreateQueryDebugBuffer',
+ 'RtlCreateRegistryKey', 'RtlCreateSecurityDescriptor', 'RtlCreateTagHeap',
+ 'RtlCreateUnicodeString', 'RtlCreateUnicodeStringFromAsciiz', 'RtlCreateUserProcess',
+ 'RtlCreateUserSecurityObject', 'RtlCreateUserThread', 'RtlCustomCPToUnicodeN',
+ 'RtlCutoverTimeToSystemTime', 'RtlDecompressBuffer', 'RtlDecompressFragment',
+ 'RtlDelete', 'RtlDeleteAce', 'RtlDeleteAtomFromAtomTable', 'RtlDeleteCriticalSection',
+ 'RtlDeleteElementGenericTable', 'RtlDeleteNoSplay', 'RtlDeleteRegistryValue',
+ 'RtlDeleteResource', 'RtlDeleteSecurityObject', 'RtlDeNormalizeProcessParams',
+ 'RtlDestroyAtomTable', 'RtlDestroyEnvironment', 'RtlDestroyHandleTable',
+ 'RtlDestroyHeap', 'RtlDestroyProcessParameters', 'RtlDestroyQueryDebugBuffer',
+ 'RtlDetermineDosPathNameType_U', 'RtlDoesFileExists_U', 'RtlDosPathNameToNtPathName_U',
+ 'RtlDosSearchPath_U', 'RtlDowncaseUnicodeString', 'RtlDumpResource',
+ 'RtlEmptyAtomTable', 'RtlEnlargedIntegerMultiply', 'RtlEnlargedUnsignedDivide',
+ 'RtlEnlargedUnsignedMultiply', 'RtlEnterCriticalSection', 'RtlEnumerateGenericTable',
+ 'RtlEnumerateGenericTableWithoutSplaying', 'RtlEnumerateProperties',
+ 'RtlEnumProcessHeaps', 'RtlEqualComputerName', 'RtlEqualDomainName', 'RtlEqualLuid',
+ 'RtlEqualPrefixSid', 'RtlEqualSid', 'RtlEqualString', 'RtlEqualUnicodeString',
+ 'RtlEraseUnicodeString', 'RtlExpandEnvironmentStrings_U', 'RtlExtendedIntegerMultiply',
+ 'RtlExtendedLargeIntegerDivide', 'RtlExtendedMagicDivide', 'RtlExtendHeap',
+ 'RtlFillMemory', 'RtlFillMemoryUlong', 'RtlFindClearBits', 'RtlFindClearBitsAndSet',
+ 'RtlFindLongestRunClear', 'RtlFindLongestRunSet', 'RtlFindMessage', 'RtlFindSetBits',
+ 'RtlFindSetBitsAndClear', 'RtlFirstFreeAce', 'RtlFlushPropertySet',
+ 'RtlFormatCurrentUserKeyPath', 'RtlFormatMessage', 'RtlFreeAnsiString',
+ 'RtlFreeHandle', 'RtlFreeHeap', 'RtlFreeOemString', 'RtlFreeSid',
+ 'RtlFreeUnicodeString', 'RtlFreeUserThreadStack', 'RtlGenerate8dot3Name', 'RtlGetAce',
+ 'RtlGetCallersAddress', 'RtlGetCompressionWorkSpaceSize',
+ 'RtlGetControlSecurityDescriptor', 'RtlGetCurrentDirectory_U',
+ 'RtlGetDaclSecurityDescriptor', 'RtlGetElementGenericTable', 'RtlGetFullPathName_U',
+ 'RtlGetGroupSecurityDescriptor', 'RtlGetLongestNtPathLength', 'RtlGetNtGlobalFlags',
+ 'RtlGetNtProductType', 'RtlGetOwnerSecurityDescriptor', 'RtlGetProcessHeaps',
+ 'RtlGetSaclSecurityDescriptor', 'RtlGetUserInfoHeap', 'RtlGuidToPropertySetName',
+ 'RtlIdentifierAuthoritySid', 'RtlImageDirectoryEntryToData', 'RtlImageNtHeader',
+ 'RtlImageRvaToSection', 'RtlImageRvaToVa', 'RtlImpersonateSelf', 'RtlInitAnsiString',
+ 'RtlInitCodePageTable', 'RtlInitializeAtomPackage', 'RtlInitializeBitMap',
+ 'RtlInitializeContext', 'RtlInitializeCriticalSection',
+ 'RtlInitializeCriticalSectionAndSpinCount', 'RtlInitializeGenericTable',
+ 'RtlInitializeHandleTable', 'RtlInitializeResource', 'RtlInitializeRXact',
+ 'RtlInitializeSid', 'RtlInitNlsTables', 'RtlInitString', 'RtlInitUnicodeString',
+ 'RtlInsertElementGenericTable', 'RtlIntegerToChar', 'RtlIntegerToUnicodeString',
+ 'RtlIsDosDeviceName_U', 'RtlIsGenericTableEmpty', 'RtlIsNameLegalDOS8Dot3',
+ 'RtlIsTextUnicode', 'RtlIsValidHandle', 'RtlIsValidIndexHandle', 'RtlLargeIntegerAdd',
+ 'RtlLargeIntegerArithmeticShift', 'RtlLargeIntegerDivide', 'RtlLargeIntegerNegate',
+ 'RtlLargeIntegerShiftLeft', 'RtlLargeIntegerShiftRight', 'RtlLargeIntegerSubtract',
+ 'RtlLargeIntegerToChar', 'RtlLeaveCriticalSection', 'RtlLengthRequiredSid',
+ 'RtlLengthSecurityDescriptor', 'RtlLengthSid', 'RtlLocalTimeToSystemTime',
+ 'RtlLockHeap', 'RtlLookupAtomInAtomTable', 'RtlLookupElementGenericTable',
+ 'RtlMakeSelfRelativeSD', 'RtlMapGenericMask', 'RtlMoveMemory',
+ 'RtlMultiByteToUnicodeN', 'RtlMultiByteToUnicodeSize', 'RtlNewInstanceSecurityObject',
+ 'RtlNewSecurityGrantedAccess', 'RtlNewSecurityObject', 'RtlNormalizeProcessParams',
+ 'RtlNtStatusToDosError', 'RtlNumberGenericTableElements', 'RtlNumberOfClearBits',
+ 'RtlNumberOfSetBits', 'RtlOemStringToUnicodeSize', 'RtlOemStringToUnicodeString',
+ 'RtlOemToUnicodeN', 'RtlOnMappedStreamEvent', 'RtlOpenCurrentUser',
+ 'RtlPcToFileHeader', 'RtlPinAtomInAtomTable', 'RtlpNtCreateKey',
+ 'RtlpNtEnumerateSubKey', 'RtlpNtMakeTemporaryKey', 'RtlpNtOpenKey',
+ 'RtlpNtQueryValueKey', 'RtlpNtSetValueKey', 'RtlPrefixString',
+ 'RtlPrefixUnicodeString', 'RtlPropertySetNameToGuid', 'RtlProtectHeap',
+ 'RtlpUnWaitCriticalSection', 'RtlpWaitForCriticalSection', 'RtlQueryAtomInAtomTable',
+ 'RtlQueryEnvironmentVariable_U', 'RtlQueryInformationAcl',
+ 'RtlQueryProcessBackTraceInformation', 'RtlQueryProcessDebugInformation',
+ 'RtlQueryProcessHeapInformation', 'RtlQueryProcessLockInformation',
+ 'RtlQueryProperties', 'RtlQueryPropertyNames', 'RtlQueryPropertySet',
+ 'RtlQueryRegistryValues', 'RtlQuerySecurityObject', 'RtlQueryTagHeap',
+ 'RtlQueryTimeZoneInformation', 'RtlRaiseException', 'RtlRaiseStatus', 'RtlRandom',
+ 'RtlReAllocateHeap', 'RtlRealPredecessor', 'RtlRealSuccessor', 'RtlReleasePebLock',
+ 'RtlReleaseResource', 'RtlRemoteCall', 'RtlResetRtlTranslations',
+ 'RtlRunDecodeUnicodeString', 'RtlRunEncodeUnicodeString', 'RtlSecondsSince1970ToTime',
+ 'RtlSecondsSince1980ToTime', 'RtlSelfRelativeToAbsoluteSD', 'RtlSetAllBits',
+ 'RtlSetAttributesSecurityDescriptor', 'RtlSetBits', 'RtlSetCriticalSectionSpinCount',
+ 'RtlSetCurrentDirectory_U', 'RtlSetCurrentEnvironment', 'RtlSetDaclSecurityDescriptor',
+ 'RtlSetEnvironmentVariable', 'RtlSetGroupSecurityDescriptor', 'RtlSetInformationAcl',
+ 'RtlSetOwnerSecurityDescriptor', 'RtlSetProperties', 'RtlSetPropertyNames',
+ 'RtlSetPropertySetClassId', 'RtlSetSaclSecurityDescriptor', 'RtlSetSecurityObject',
+ 'RtlSetTimeZoneInformation', 'RtlSetUnicodeCallouts', 'RtlSetUserFlagsHeap',
+ 'RtlSetUserValueHeap', 'RtlSizeHeap', 'RtlSplay', 'RtlStartRXact',
+ 'RtlSubAuthorityCountSid', 'RtlSubAuthoritySid', 'RtlSubtreePredecessor',
+ 'RtlSubtreeSuccessor', 'RtlSystemTimeToLocalTime', 'RtlTimeFieldsToTime',
+ 'RtlTimeToElapsedTimeFields', 'RtlTimeToSecondsSince1970', 'RtlTimeToSecondsSince1980',
+ 'RtlTimeToTimeFields', 'RtlTryEnterCriticalSection', 'RtlUnicodeStringToAnsiSize',
+ 'RtlUnicodeStringToAnsiString', 'RtlUnicodeStringToCountedOemString',
+ 'RtlUnicodeStringToInteger', 'RtlUnicodeStringToOemSize',
+ 'RtlUnicodeStringToOemString', 'RtlUnicodeToCustomCPN', 'RtlUnicodeToMultiByteN',
+ 'RtlUnicodeToMultiByteSize', 'RtlUnicodeToOemN', 'RtlUniform', 'RtlUnlockHeap',
+ 'RtlUnwind', 'RtlUpcaseUnicodeChar', 'RtlUpcaseUnicodeString',
+ 'RtlUpcaseUnicodeStringToAnsiString', 'RtlUpcaseUnicodeStringToCountedOemString',
+ 'RtlUpcaseUnicodeStringToOemString', 'RtlUpcaseUnicodeToCustomCPN',
+ 'RtlUpcaseUnicodeToMultiByteN', 'RtlUpcaseUnicodeToOemN', 'RtlUpperChar',
+ 'RtlUpperString', 'RtlUsageHeap', 'RtlValidAcl', 'RtlValidateHeap',
+ 'RtlValidateProcessHeaps', 'RtlValidSecurityDescriptor', 'RtlValidSid', 'RtlWalkHeap',
+ 'RtlWriteRegistryValue', 'RtlxAnsiStringToUnicodeSize', 'RtlxOemStringToUnicodeSize',
+ 'RtlxUnicodeStringToAnsiSize', 'RtlxUnicodeStringToOemSize', 'RtlZeroHeap',
+ 'RtlZeroMemory',
+
+ 'NtCancelTimer', 'ZwCancelTimer', 'NtCreateTimer', 'ZwCreateTimer', 'NtGetTickCount',
+ 'ZwGetTickCount', 'NtOpenTimer', 'ZwOpenTimer', 'NtQueryPerformanceCounter',
+ 'ZwQueryPerformanceCounter', 'NtQuerySystemTime', 'ZwQuerySystemTime', 'NtQueryTimer',
+ 'ZwQueryTimer', 'NtQueryTimerResolution', 'ZwQueryTimerResolution', 'NtSetSystemTime',
+ 'ZwSetSystemTime', 'NtSetTimer', 'ZwSetTimer', 'NtSetTimerResolution',
+ 'ZwSetTimerResolution',
+
+ 'NtClearEvent', 'ZwClearEvent', 'NtCreateEvent', 'ZwCreateEvent', 'NtCreateEventPair',
+ 'ZwCreateEventPair', 'NtCreateMutant', 'ZwCreateMutant', 'NtCreateSemaphore',
+ 'ZwCreateSemaphore', 'NtOpenEvent', 'ZwOpenEvent', 'NtOpenEventPair',
+ 'ZwOpenEventPair', 'NtOpenMutant', 'ZwOpenMutant', 'NtOpenSemaphore',
+ 'ZwOpenSemaphore', 'NtPulseEvent', 'ZwPulseEvent', 'NtQueryEvent', 'ZwQueryEvent',
+ 'NtQueryMutant', 'ZwQueryMutant', 'NtQuerySemaphore', 'ZwQuerySemaphore',
+ 'NtReleaseMutant', 'ZwReleaseMutant', 'NtReleaseProcessMutant',
+ 'ZwReleaseProcessMutant', 'NtReleaseSemaphore', 'ZwReleaseSemaphore',
+ 'NtReleaseThreadMutant', 'ZwReleaseThreadMutant', 'NtResetEvent', 'ZwResetEvent',
+ 'NtSetEvent', 'ZwSetEvent', 'NtSetHighEventPair', 'ZwSetHighEventPair',
+ 'NtSetHighWaitLowEventPair', 'ZwSetHighWaitLowEventPair', 'NtSetLowEventPair',
+ 'ZwSetLowEventPair', 'NtSetLowWaitHighEventPair', 'ZwSetLowWaitHighEventPair',
+ 'NtSignalAndWaitForSingleObject', 'ZwSignalAndWaitForSingleObject',
+ 'NtWaitForMultipleObjects', 'ZwWaitForMultipleObjects', 'NtWaitForSingleObject',
+ 'ZwWaitForSingleObject', 'NtWaitHighEventPair', 'ZwWaitHighEventPair',
+ 'NtWaitLowEventPair', 'ZwWaitLowEventPair',
+
+ 'NtClose', 'ZwClose', 'NtCreateDirectoryObject', 'ZwCreateDirectoryObject',
+ 'NtCreateSymbolicLinkObject', 'ZwCreateSymbolicLinkObject',
+ 'NtDuplicateObject', 'ZwDuplicateObject', 'NtMakeTemporaryObject',
+ 'ZwMakeTemporaryObject', 'NtOpenDirectoryObject', 'ZwOpenDirectoryObject',
+ 'NtOpenSymbolicLinkObject', 'ZwOpenSymbolicLinkObject', 'NtQueryDirectoryObject',
+ 'ZwQueryDirectoryObject', 'NtQueryObject', 'ZwQueryObject',
+ 'NtQuerySymbolicLinkObject', 'ZwQuerySymbolicLinkObject', 'NtSetInformationObject',
+ 'ZwSetInformationObject',
+
+ 'NtContinue', 'ZwContinue', 'NtRaiseException', 'ZwRaiseException',
+ 'NtRaiseHardError', 'ZwRaiseHardError', 'NtSetDefaultHardErrorPort',
+ 'ZwSetDefaultHardErrorPort',
+
+ 'NtCreateChannel', 'ZwCreateChannel', 'NtListenChannel', 'ZwListenChannel',
+ 'NtOpenChannel', 'ZwOpenChannel', 'NtReplyWaitSendChannel', 'ZwReplyWaitSendChannel',
+ 'NtSendWaitReplyChannel', 'ZwSendWaitReplyChannel', 'NtSetContextChannel',
+ 'ZwSetContextChannel',
+
+ 'NtCreateKey', 'ZwCreateKey', 'NtDeleteKey', 'ZwDeleteKey', 'NtDeleteValueKey',
+ 'ZwDeleteValueKey', 'NtEnumerateKey', 'ZwEnumerateKey', 'NtEnumerateValueKey',
+ 'ZwEnumerateValueKey', 'NtFlushKey', 'ZwFlushKey', 'NtInitializeRegistry',
+ 'ZwInitializeRegistry', 'NtLoadKey', 'ZwLoadKey', 'NtLoadKey2', 'ZwLoadKey2',
+ 'NtNotifyChangeKey', 'ZwNotifyChangeKey', 'NtOpenKey', 'ZwOpenKey', 'NtQueryKey',
+ 'ZwQueryKey', 'NtQueryMultipleValueKey', 'ZwQueryMultipleValueKey',
+ 'NtQueryMultiplValueKey', 'ZwQueryMultiplValueKey', 'NtQueryValueKey',
+ 'ZwQueryValueKey', 'NtReplaceKey', 'ZwReplaceKey', 'NtRestoreKey', 'ZwRestoreKey',
+ 'NtSaveKey', 'ZwSaveKey', 'NtSetInformationKey', 'ZwSetInformationKey',
+ 'NtSetValueKey', 'ZwSetValueKey', 'NtUnloadKey', 'ZwUnloadKey',
+
+ 'NtCreateMailslotFile', 'ZwCreateMailslotFile', 'NtCreateNamedPipeFile',
+ 'ZwCreateNamedPipeFile', 'NtCreatePagingFile', 'ZwCreatePagingFile',
+
+ 'NtCreateProfile', 'ZwCreateProfile', 'NtQueryIntervalProfile',
+ 'ZwQueryIntervalProfile', 'NtRegisterThreadTerminatePort',
+ 'ZwRegisterThreadTerminatePort', 'NtSetIntervalProfile', 'ZwSetIntervalProfile',
+ 'NtStartProfile', 'ZwStartProfile', 'NtStopProfile', 'ZwStopProfile',
+ 'NtSystemDebugControl', 'ZwSystemDebugControl',
+
+ 'NtEnumerateBus', 'ZwEnumerateBus', 'NtFlushInstructionCache',
+ 'ZwFlushInstructionCache', 'NtFlushWriteBuffer', 'ZwFlushWriteBuffer',
+ 'NtSetLdtEntries', 'ZwSetLdtEntries',
+
+ 'NtGetPlugPlayEvent', 'ZwGetPlugPlayEvent', 'NtPlugPlayControl', 'ZwPlugPlayControl',
+
+ 'NtInitiatePowerAction', 'ZwInitiatePowerAction', 'NtPowerInformation',
+ 'ZwPowerInformation', 'NtRequestWakeupLatency', 'ZwRequestWakeupLatency',
+ 'NtSetSystemPowerState', 'ZwSetSystemPowerState', 'NtSetThreadExecutionState',
+ 'ZwSetThreadExecutionState',
+
+ 'NtLoadDriver', 'ZwLoadDriver', 'NtRegisterNewDevice', 'ZwRegisterNewDevice',
+ 'NtUnloadDriver', 'ZwUnloadDriver',
+
+ 'NtQueryDefaultLocale', 'ZwQueryDefaultLocale', 'NtQueryDefaultUILanguage',
+ 'ZwQueryDefaultUILanguage', 'NtQuerySystemEnvironmentValue',
+ 'ZwQuerySystemEnvironmentValue', 'NtSetDefaultLocale', 'ZwSetDefaultLocale',
+ 'NtSetDefaultUILanguage', 'ZwSetDefaultUILanguage', 'NtSetSystemEnvironmentValue',
+ 'ZwSetSystemEnvironmentValue',
+
+ 'DbgBreakPoint', 'DbgPrint', 'DbgPrompt', 'DbgSsHandleKmApiMsg', 'DbgSsInitialize',
+ 'DbgUiConnectToDbg', 'DbgUiContinue', 'DbgUiWaitStateChange', 'DbgUserBreakPoint',
+ 'KiRaiseUserExceptionDispatcher', 'KiUserApcDispatcher', 'KiUserCallbackDispatcher',
+ 'KiUserExceptionDispatcher', 'NlsAnsiCodePage', 'NlsMbCodePageTag',
+ 'NlsMbOemCodePageTag', 'NtAllocateLocallyUniqueId', 'ZwAllocateLocallyUniqueId',
+ 'NtAllocateUuids', 'ZwAllocateUuids', 'NtCallbackReturn', 'ZwCallbackReturn',
+ 'NtDisplayString', 'ZwDisplayString', 'NtQueryOleDirectoryFile',
+ 'ZwQueryOleDirectoryFile', 'NtQuerySection', 'ZwQuerySection',
+ 'NtQuerySystemInformation', 'ZwQuerySystemInformation', 'NtSetSystemInformation',
+ 'ZwSetSystemInformation', 'NtShutdownSystem', 'ZwShutdownSystem', 'NtVdmControl',
+ 'ZwVdmControl', 'NtW32Call', 'ZwW32Call', 'PfxFindPrefix', 'PfxInitialize',
+ 'PfxInsertPrefix', 'PfxRemovePrefix', 'PropertyLengthAsVariant', 'RestoreEm87Context',
+ 'SaveEm87Context'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']',
+ '+', '-', '*', '/', '%',
+ '=', '<', '>',
+ '!', '^', '&', '|',
+ '?', ':',
+ ';', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #993333;',
+ 5 => 'color: #4000dd;',
+ 6 => 'color: #4000dd;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #339933;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAMEL}.html',
+ 4 => '',
+ 5 => 'http://www.google.com/search?q={FNAMEL}+msdn.microsoft.com',
+ 6 => 'http://www.google.com/search?q={FNAMEL}+msdn.microsoft.com'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/caddcl.php b/platform/www/vendor/geshi/geshi/src/geshi/caddcl.php
new file mode 100644
index 0000000..72d1cd9
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/caddcl.php
@@ -0,0 +1,124 @@
+<?php
+/*************************************************************************************
+ * caddcl.php
+ * ----------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/30
+ *
+ * CAD DCL (Dialog Control Language) language file for GeSHi.
+ *
+ * DCL for AutoCAD 12 or later and IntelliCAD all versions.
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/1!/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'CAD DCL',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'boxed_column','boxed_radio_column','boxed_radio_row','boxed_row',
+ 'column','concatenation','button','dialog','edit_box','image','image_button',
+ 'errtile','list_box','ok_cancel','ok_cancel_help','ok_cancel_help_errtile',
+ 'ok_cancel_help_info','ok_only','paragraph','popup_list','radio_button',
+ 'radio_column','radio_row','row','slider','spacer','spacer_0','spacer_1','text',
+ 'text_part','toggle',
+ 'action','alignment','allow_accept','aspect_ratio','big_increment',
+ 'children_alignment','children_fixed_height',
+ 'children_fixed_width','color',
+ 'edit_limit','edit_width','fixed_height','fixed_width',
+ 'height','initial_focus','is_cancel','is_default',
+ 'is_enabled','is_tab_stop','is-bold','key','label','layout','list',
+ 'max_value','min_value','mnemonic','multiple_select','password_char',
+ 'small_increment','tabs','tab_truncate','value','width',
+ 'false','true','left','right','centered','top','bottom',
+ 'dialog_line','dialog_foreground','dialog_background',
+ 'graphics_background','black','red','yellow','green','cyan',
+ 'blue','magenta','whitegraphics_foreground',
+ 'horizontal','vertical'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/cadlisp.php b/platform/www/vendor/geshi/geshi/src/geshi/cadlisp.php
new file mode 100644
index 0000000..1123af1
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/cadlisp.php
@@ -0,0 +1,184 @@
+<?php
+/*************************************************************************************
+ * cadlisp.php
+ * -----------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/blog)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/30
+ *
+ * AutoCAD/IntelliCAD Lisp language file for GeSHi.
+ *
+ * For AutoCAD V.12..2005 and IntelliCAD all versions.
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'CAD Lisp',
+ 'COMMENT_SINGLE' => array(1 => ";"),
+ 'COMMENT_MULTI' => array(";|" => "|;"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'abs','acad_colordlg','acad_helpdlg','acad_strlsort','action_tile',
+ 'add_list','alert','alloc','and','angle','angtof','angtos','append','apply',
+ 'arx','arxload','arxunload','ascii','assoc','atan','atof','atoi','atom',
+ 'atoms-family','autoarxload','autoload','Boole','boundp','caddr',
+ 'cadr','car','cdr','chr','client_data_tile','close','command','cond',
+ 'cons','cos','cvunit','defun','defun-q','defun-q-list-ref',
+ 'defun-q-list-set','dictadd','dictnext','dictremove','dictrename',
+ 'dictsearch','dimx_tile','dimy_tile','distance','distof','done_dialog',
+ 'end_image','end_list','entdel','entget','entlast','entmake',
+ 'entmakex','entmod','entnext','entsel','entupd','eq','equal','eval','exit',
+ 'exp','expand','expt','fill_image','findfile','fix','float','foreach','function',
+ 'gc','gcd','get_attr','get_tile','getangle','getcfg','getcname','getcorner',
+ 'getdist','getenv','getfiled','getint','getkword','getorient','getpoint',
+ 'getreal','getstring','getvar','graphscr','grclear','grdraw','grread','grtext',
+ 'grvecs','handent','help','if','initdia','initget','inters','itoa','lambda','last',
+ 'layoutlist','length','list','listp','load','load_dialog','log','logand','logior',
+ 'lsh','mapcar','max','mem','member','menucmd','menugroup','min','minusp','mode_tile',
+ 'namedobjdict','nentsel','nentselp','new_dialog','nil','not','nth','null',
+ 'numberp','open','or','osnap','polar','prin1','princ','print','progn','prompt',
+ 'quit','quote','read','read-char','read-line','redraw','regapp','rem','repeat',
+ 'reverse','rtos','set','set_tile','setcfg','setenv','setfunhelp','setq','setvar',
+ 'setview','sin','slide_image','snvalid','sqrt','ssadd','ssdel','ssget','ssgetfirst',
+ 'sslength','ssmemb','ssname','ssnamex','sssetfirst','start_dialog','start_image',
+ 'start_list','startapp','strcase','strcat','strlen','subst','substr','t','tablet',
+ 'tblnext','tblobjname','tblsearch','term_dialog','terpri','textbox','textpage',
+ 'textscr','trace','trans','type','unload_dialog','untrace','vector_image','ver',
+ 'vports','wcmatch','while','write-char','write-line','xdroom','xdsize','zerop',
+ 'vl-acad-defun','vl-acad-undefun','vl-arx-import','vlax-3D-point',
+ 'vlax-add-cmd','vlax-create-object','vlax-curve-getArea',
+ 'vlax-curve-getClosestPointTo','vlax-curve-getClosestPointToProjection',
+ 'vlax-curve-getDistAtParam','vlax-curve-getDistAtPoint',
+ 'vlax-curve-getEndParam','vlax-curve-getEndPoint',
+ 'vlax-curve-getFirstDeriv','vlax-curve-getParamAtDist',
+ 'vlax-curve-getParamAtPoint','vlax-curve-getPointAtDist',
+ 'vlax-curve-getPointAtParam','vlax-curve-getSecondDeriv',
+ 'vlax-curve-getStartParam','vlax-curve-getStartPoint',
+ 'vlax-curve-isClosed','vlax-curve-isPeriodic','vlax-curve-isPlanar',
+ 'vlax-dump-object','vlax-erased-p','vlax-for','vlax-get-acad-object',
+ 'vlax-get-object','vlax-get-or-create-object','vlax-get-property',
+ 'vlax-import-type-library','vlax-invoke-method','vlax-ldata-delete',
+ 'vlax-ldata-get','vlax-ldata-list','vlax-ldata-put','vlax-ldata-test',
+ 'vlax-make-safearray','vlax-make-variant','vlax-map-collection',
+ 'vlax-method-applicable-p','vlax-object-released-p','vlax-product-key',
+ 'vlax-property-available-p','vlax-put-property','vlax-read-enabled-p',
+ 'vlax-release-object','vlax-remove-cmd','vlax-safearray-fill',
+ 'vlax-safearray-get-dim','vlax-safearray-get-element',
+ 'vlax-safearray-get-l-bound','vlax-safearray-get-u-bound',
+ 'vlax-safearray-put-element','vlax-safearray-type','vlax-tmatrix',
+ 'vlax-typeinfo-available-p','vlax-variant-change-type',
+ 'vlax-variant-type','vlax-variant-value','vlax-write-enabled-p',
+ 'vl-bb-ref','vl-bb-set','vl-catch-all-apply','vl-catch-all-error-message',
+ 'vl-catch-all-error-p','vl-cmdf','vl-consp','vl-directory-files','vl-doc-export',
+ 'vl-doc-import','vl-doc-ref','vl-doc-set','vl-every','vl-exit-with-error',
+ 'vl-exit-with-value','vl-file-copy','vl-file-delete','vl-file-directory-p',
+ 'vl-filename-base','vl-filename-directory','vl-filename-extension',
+ 'vl-filename-mktemp','vl-file-rename','vl-file-size','vl-file-systime',
+ 'vl-get-resource','vlisp-compile','vl-list-exported-functions',
+ 'vl-list-length','vl-list-loaded-vlx','vl-load-all','vl-load-com',
+ 'vl-load-reactors','vl-member-if','vl-member-if-not','vl-position',
+ 'vl-prin1-to-string','vl-princ-to-string','vl-propagate','vlr-acdb-reactor',
+ 'vlr-add','vlr-added-p','vlr-beep-reaction','vlr-command-reactor',
+ 'vlr-current-reaction-name','vlr-data','vlr-data-set',
+ 'vlr-deepclone-reactor','vlr-docmanager-reactor','vlr-dwg-reactor',
+ 'vlr-dxf-reactor','vlr-editor-reactor','vl-registry-delete',
+ 'vl-registry-descendents','vl-registry-read','vl-registry-write',
+ 'vl-remove','vl-remove-if','vl-remove-if-not','vlr-insert-reactor',
+ 'vlr-linker-reactor','vlr-lisp-reactor','vlr-miscellaneous-reactor',
+ 'vlr-mouse-reactor','vlr-notification','vlr-object-reactor',
+ 'vlr-owner-add','vlr-owner-remove','vlr-owners','vlr-pers','vlr-pers-list',
+ 'vlr-pers-p','vlr-pers-release','vlr-reaction-names','vlr-reactions',
+ 'vlr-reaction-set','vlr-reactors','vlr-remove','vlr-remove-all',
+ 'vlr-set-notification','vlr-sysvar-reactor','vlr-toolbar-reactor',
+ 'vlr-trace-reaction','vlr-type','vlr-types','vlr-undo-reactor',
+ 'vlr-wblock-reactor','vlr-window-reactor','vlr-xref-reactor',
+ 'vl-some','vl-sort','vl-sort-i','vl-string-elt','vl-string-left-trim',
+ 'vl-string-mismatch','vl-string-position','vl-string-right-trim',
+ 'vl-string-search','vl-string-subst','vl-string-translate','vl-string-trim',
+ 'vl-symbol-name','vl-symbolp','vl-symbol-value','vl-unload-vlx','vl-vbaload',
+ 'vl-vbarun','vl-vlx-loaded-p'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '!', '%', '^', '&', '/','+','-','*','=','<','>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/ceylon.php b/platform/www/vendor/geshi/geshi/src/geshi/ceylon.php
new file mode 100644
index 0000000..52b74c1
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/ceylon.php
@@ -0,0 +1,171 @@
+<?php
+/*************************************************************************************
+ * ceylon.php
+ * ----------
+ * Author: Lucas Werkmeister (mail@lucaswerkmeister.de)
+ * Copyright: (c) 2015 Lucas Werkmeister (http://lucaswerkmeister.de)
+ * Release Version: 1.0.9.1
+ * Date Started: 2015-01-08
+ *
+ * Ceylon language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ *
+ * TODO (updated 2015-06-19)
+ * ------------------
+ * * Regexes match and break help URLs, so those are commented out for now
+ * * Ceylon supports nested block comments
+ * * The Ceylon compiler correctly parses
+ * "\{FICTITIOUS CHARACTER WITH " IN NAME}"
+ * as a single string literal.
+ * (However, that's not really important
+ * since Unicode character names never contain quotes.)
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Ceylon',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#!'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ /*
+ * 1. regular line comments (see COMMENT_SINGLE)
+ * 2. shebang line comments (see COMMENT_SINGLE)
+ * 3. strings (including string templates)
+ */
+ 3 => '/(?:"|``).*?(?:``|")/'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'"),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ /*
+ * 1. lexer keywords (class, else, etc.)
+ * 2. language modifiers (shared, formal, etc.)
+ * 3. language doc modifiers (doc, see, etc.)
+ */
+ 1 => array(
+ 'assembly', 'module', 'package', 'import',
+ 'alias', 'class', 'interface', 'object', 'given',
+ 'value', 'assign', 'void', 'function',
+ 'new', 'of', 'extends', 'satisfies', 'abstracts',
+ 'in', 'out',
+ 'return', 'break', 'continue', 'throw', 'assert',
+ 'dynamic',
+ 'if', 'else', 'switch', 'case',
+ 'for', 'while', 'try', 'catch', 'finally',
+ 'then', 'let',
+ 'this', 'outer', 'super',
+ 'is', 'exists', 'nonempty'
+ ),
+ 2 => array(
+ 'shared', 'abstract', 'formal', 'default', 'actual',
+ 'variable', 'late', 'native', 'deprecated',
+ 'final', 'sealed', 'annotation', 'small'
+ ),
+ 3 => array(
+ 'doc', 'by', 'license', 'see', 'throws', 'tagged'
+ )
+ ),
+ 'SYMBOLS' => array(
+ ',', ';', '...', '{', '}', '[', ']', '`', '?.', '*.',
+ '?', '-&gt;', '=&gt;',
+ '**', '++', '--', '..', ':', '&&', '||',
+ '+=', '-=', '*=', '/=', '%=', '|=', '&=', '~=', '||=', '&&=',
+ '+', '-', '*', '/', '%', '^',
+ '~', '&', '|', '===', '==', '=', '!=', '!',
+ '&lt;=&gt;', '&lt;=', '&gt;=',
+ '&lt;', '&gt;',
+ '.'
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'font-weight:bold;color:#4C4C4C;',
+ 2 => 'color:#39C',
+ 3 => 'color:#39C'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color:darkgray;',
+ 2 => 'color:darkgray;',
+ 3 => 'color:blue',
+ 'MULTI' => 'color:darkgray;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color:blue;'
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color:#639;',
+ 2 => 'color:#039;',
+ 3 => 'color:#906;'
+ ),
+ 'ESCAPE_CHAR' => array(),
+ 'BRACKETS' => array(),
+ 'NUMBERS' => array(),
+ 'METHODS' => array(),
+ 'SYMBOLS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'REGEXPS' => array(
+ /*
+ * 1. qualified lidentifiers
+ * 2. lidentifiers
+ * 3. uidentifiers
+ *
+ * All of these contain various lookahead and -behind to ensure
+ * that we don't match various stuff that GeSHi escapes
+ * (for instance, we see semicolons as <SEMI>).
+ */
+ 1 => array(
+ GESHI_SEARCH => '\\b((\?|\*)?\.[[:space:]]*)([[:lower:]][[:alnum:]]*|\\\\i[[:alnum:]]*)\\b',
+ GESHI_REPLACE => '\\3',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 2 => array(
+ GESHI_SEARCH => '(?<![|<>&![:alnum:]])([[:lower:]][[:alnum:]]*|\\\\i[[:alnum:]]*)(?![>[:alnum:]])',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 3 => array(
+ GESHI_SEARCH => '(?<![|<>&![:alnum:]])([[:upper:]][[:alnum:]]*|\\\\I[[:alnum:]]*)(?![>[:alnum:]])',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '', 3 => '' // the real URLs are commented out because syntax highlighting breaks them
+// 2 => 'https://modules.ceylon-lang.org/repo/1/ceylon/language/1.1.0/module-doc/api/index.html#{FNAME}',
+// 3 => 'https://modules.ceylon-lang.org/repo/1/ceylon/language/1.1.0/module-doc/api/index.html#{FNAME}',
+ ),
+ 'CASE_SENSITIVE' => array(1 => true, 2 => true, 3 => true),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/cfdg.php b/platform/www/vendor/geshi/geshi/src/geshi/cfdg.php
new file mode 100644
index 0000000..2cf72f4
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/cfdg.php
@@ -0,0 +1,122 @@
+<?php
+/*************************************************************************************
+ * cfdg.php
+ * --------
+ * Author: John Horigan <john@glyphic.com>
+ * Copyright: (c) 2006 John Horigan http://www.ozonehouse.com/john/
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/03/11
+ *
+ * CFDG language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2006/03/11 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2006/03/11)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'CFDG',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'include', 'startshape', 'rule', 'background'
+ ),
+ 2 => array(
+ 'SQUARE', 'CIRCLE', 'TRIANGLE',
+ ),
+ 3 => array(
+ 'b','brightness','h','hue','sat','saturation',
+ 'a','alpha','x','y','z','s','size',
+ 'r','rotate','f','flip','skew','xml_set_object'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '{', '}', '*', '|'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #717100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #006666;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/cfm.php b/platform/www/vendor/geshi/geshi/src/geshi/cfm.php
new file mode 100644
index 0000000..516c666
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/cfm.php
@@ -0,0 +1,297 @@
+<?php
+/*************************************************************************************
+ * cfm.php
+ * -------
+ * Author: Diego
+ * Copyright: (c) 2006 Diego
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/02/25
+ *
+ * ColdFusion language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2006/02/25 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2006/02/25)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ColdFusion',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ /* CFM Tags */
+ 1 => array(
+ 'cfabort', 'cfapplet', 'cfapplication', 'cfargument', 'cfassociate',
+ 'cfbreak', 'cfcache', 'cfcase', 'cfcatch', 'cfchart', 'cfchartdata',
+ 'cfchartseries', 'cfcol', 'cfcollection', 'cfcomponent',
+ 'cfcontent', 'cfcookie', 'cfdefaultcase', 'cfdirectory',
+ 'cfdocument', 'cfdocumentitem', 'cfdocumentsection', 'cfdump',
+ 'cfelse', 'cfelseif', 'cferror', 'cfexecute', 'cfexit', 'cffile',
+ 'cfflush', 'cfform', 'cfformgroup', 'cfformitem', 'cfftp',
+ 'cffunction', 'cfgrid', 'cfgridcolumn', 'cfgridrow', 'cfgridupdate',
+ 'cfheader', 'cfhtmlhead', 'cfhttp', 'cfhttpparam', 'cfif',
+ 'cfimport', 'cfinclude', 'cfindex', 'cfinput', 'cfinsert',
+ 'cfinvoke', 'cfinvokeargument', 'cfldap', 'cflocation', 'cflock',
+ 'cflog', 'cflogin', 'cfloginuser', 'cflogout', 'cfloop', 'cfmail',
+ 'cfmailparam', 'cfmailpart', 'cfmodule', 'cfNTauthenticate',
+ 'cfobject', 'cfobjectcache', 'cfoutput', 'cfparam', 'cfpop',
+ 'cfprocessingdirective', 'cfprocparam',
+ 'cfprocresult', 'cfproperty', 'cfquery', 'cfqueryparam',
+ 'cfregistry', 'cfreport', 'cfreportparam', 'cfrethrow', 'cfreturn',
+ 'cfsavecontent', 'cfschedule', 'cfscript', 'cfsearch', 'cfselect',
+ 'cfset', 'cfsetting', 'cfsilent', 'cfstoredproc',
+ 'cfswitch', 'cftable', 'cftextarea', 'cfthrow', 'cftimer',
+ 'cftrace', 'cftransaction', 'cftree', 'cftreeitem', 'cftry',
+ 'cfupdate', 'cfwddx'
+ ),
+ /* HTML Tags */
+ 2 => array(
+ 'a', 'abbr', 'acronym', 'address', 'applet',
+
+ 'base', 'basefont', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'b',
+
+ 'caption', 'center', 'cite', 'code', 'colgroup', 'col',
+
+ 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt',
+
+ 'em',
+
+ 'fieldset', 'font', 'form', 'frame', 'frameset',
+
+ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html',
+
+ 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'i',
+
+ 'kbd',
+
+ 'label', 'legend', 'link', 'li',
+
+ 'map', 'meta',
+
+ 'noframes', 'noscript',
+
+ 'object', 'ol', 'optgroup', 'option',
+
+ 'param', 'pre', 'p',
+
+ 'q',
+
+ 'samp', 'script', 'select', 'small', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 's',
+
+ 'table', 'tbody', 'td', 'textarea', 'text', 'tfoot', 'thead', 'th', 'title', 'tr', 'tt',
+
+ 'ul', 'u',
+
+ 'var',
+ ),
+ /* HTML attributes */
+ 3 => array(
+ 'abbr', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alink', 'alt', 'archive', 'axis',
+ 'background', 'bgcolor', 'border',
+ 'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols', 'colspan', 'compact', 'content', 'coords',
+ 'data', 'datetime', 'declare', 'defer', 'dir', 'disabled',
+ 'enctype',
+ 'face', 'for', 'frame', 'frameborder',
+ 'headers', 'height', 'href', 'hreflang', 'hspace', 'http-equiv',
+ 'id', 'ismap',
+ 'label', 'lang', 'language', 'link', 'longdesc',
+ 'marginheight', 'marginwidth', 'maxlength', 'media', 'method', 'multiple',
+ 'name', 'nohref', 'noresize', 'noshade', 'nowrap',
+ 'object', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onreset', 'onselect', 'onsubmit', 'onunload',
+ 'profile', 'prompt',
+ 'readonly', 'rel', 'rev', 'rowspan', 'rows', 'rules',
+ 'scheme', 'scope', 'scrolling', 'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary',
+ 'tabindex', 'target', 'text', 'title', 'type',
+ 'usemap',
+ 'valign', 'value', 'valuetype', 'version', 'vlink', 'vspace',
+ 'width'
+ ),
+ /* CFM Script delimeters */
+ 4 => array(
+ 'var', 'function', 'while', 'if','else'
+ ),
+ /* CFM Functions */
+ 5 => array(
+ 'Abs', 'GetFunctionList', 'LSTimeFormat','ACos','GetGatewayHelper','LTrim','AddSOAPRequestHeader','GetHttpRequestData',
+ 'Max','AddSOAPResponseHeader','GetHttpTimeString','Mid','ArrayAppend','GetLocale','Min','ArrayAvg','GetLocaleDisplayName',
+ 'Minute','ArrayClear','GetMetaData','Month','ArrayDeleteAt','GetMetricData','MonthAsString','ArrayInsertAt','GetPageContext',
+ 'Now','ArrayIsEmpty','GetProfileSections','NumberFormat','ArrayLen','GetProfileString','ParagraphFormat','ArrayMax',
+ 'GetLocalHostIP','ParseDateTime','ArrayMin','GetSOAPRequest','Pi','ArrayNew','GetSOAPRequestHeader','PreserveSingleQuotes',
+ 'ArrayPrepend','GetSOAPResponse','Quarter','ArrayResize','GetSOAPResponseHeader','QueryAddColumn','ArraySet',
+ 'GetTempDirectory','QueryAddRow','ArraySort','QueryNew','ArraySum','GetTempFile','QuerySetCell',
+ 'ArraySwap','GetTickCount','QuotedValueList','ArrayToList','GetTimeZoneInfo','Rand','Asc','GetToken','Randomize',
+ 'ASin','Hash','RandRange','Atn','Hour','REFind','BinaryDecode','HTMLCodeFormat','REFindNoCase','BinaryEncode',
+ 'HTMLEditFormat','ReleaseComObject','BitAnd','IIf','RemoveChars','BitMaskClear','IncrementValue','RepeatString',
+ 'BitMaskRead','InputBaseN','Replace','BitMaskSet','Insert','ReplaceList','BitNot','Int','ReplaceNoCase','BitOr',
+ 'IsArray','REReplace','BitSHLN','IsBinary','REReplaceNoCase','BitSHRN','IsBoolean','Reverse','BitXor','IsCustomFunction',
+ 'Right','Ceiling','IsDate','RJustify','CharsetDecode','IsDebugMode','Round','CharsetEncode','IsDefined','RTrim',
+ 'Chr','IsLeapYear','Second','CJustify','IsLocalHost','SendGatewayMessage','Compare','IsNumeric','SetEncoding',
+ 'CompareNoCase','IsNumericDate','SetLocale','Cos','IsObject','SetProfileString','CreateDate','IsQuery','SetVariable',
+ 'CreateDateTime','IsSimpleValue','Sgn','CreateObject','IsSOAPRequest','Sin','CreateODBCDate','IsStruct','SpanExcluding',
+ 'CreateODBCDateTime','IsUserInRole','SpanIncluding','CreateODBCTime','IsValid','Sqr','CreateTime','IsWDDX','StripCR',
+ 'CreateTimeSpan','IsXML','StructAppend','CreateUUID','IsXmlAttribute','StructClear','DateAdd','IsXmlDoc','StructCopy',
+ 'DateCompare','IsXmlElem','StructCount','DateConvert','IsXmlNode','StructDelete','DateDiff','IsXmlRoot','StructFind',
+ 'DateFormat','JavaCast','StructFindKey','DatePart','JSStringFormat','StructFindValue','Day','LCase','StructGet',
+ 'DayOfWeek','Left','StructInsert','DayOfWeekAsString','Len','StructIsEmpty','DayOfYear','ListAppend','StructKeyArray',
+ 'DaysInMonth','ListChangeDelims','StructKeyExists','DaysInYear','ListContains','StructKeyList','DE','ListContainsNoCase',
+ 'StructNew','DecimalFormat','ListDeleteAt','StructSort','DecrementValue','ListFind','StructUpdate','Decrypt','ListFindNoCase',
+ 'Tan','DecryptBinary','ListFirst','TimeFormat','DeleteClientVariable','ListGetAt','ToBase64','DirectoryExists',
+ 'ListInsertAt','ToBinary','DollarFormat','ListLast','ToScript','Duplicate','ListLen','ToString','Encrypt','ListPrepend',
+ 'Trim','EncryptBinary','ListQualify','UCase','Evaluate','ListRest','URLDecode','Exp','ListSetAt','URLEncodedFormat',
+ 'ExpandPath','ListSort','URLSessionFormat','FileExists','ListToArray','Val','Find','ListValueCount','ValueList',
+ 'FindNoCase','ListValueCountNoCase','Week','FindOneOf','LJustify','Wrap','FirstDayOfMonth','Log','WriteOutput',
+ 'Fix','Log10','XmlChildPos','FormatBaseN','LSCurrencyFormat','XmlElemNew','GetAuthUser','LSDateFormat','XmlFormat',
+ 'GetBaseTagData','LSEuroCurrencyFormat','XmlGetNodeType','GetBaseTagList','LSIsCurrency','XmlNew','GetBaseTemplatePath',
+ 'LSIsDate','XmlParse','GetClientVariablesList','LSIsNumeric','XmlSearch','GetCurrentTemplatePath','LSNumberFormat',
+ 'XmlTransform','GetDirectoryFromPath','LSParseCurrency','XmlValidate','GetEncoding','LSParseDateTime','Year',
+ 'GetException','LSParseEuroCurrency','YesNoFormat','GetFileFromPath','LSParseNumber'
+ ),
+ /* CFM Attributes */
+ 6 => array(
+ 'dbtype','connectstring','datasource','username','password','query','delimeter','description','required','hint','default','access','from','to','list','index'
+ ),
+ 7 => array(
+ 'EQ', 'GT', 'LT', 'GTE', 'LTE', 'IS', 'LIKE', 'NEQ'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '/', '=', '{', '}', '(', ')', '[', ']', '<', '>', '&'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #990000; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #0000FF;',
+ 4 => 'color: #000000; font-weight: bold;',
+ 5 => 'color: #0000FF;',
+ 6 => 'color: #0000FF;',
+ 7 => 'color: #0000FF;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #0000FF;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #0000FF;'
+ ),
+ 'SCRIPT' => array(
+ 0 => 'color: #808080; font-style: italic;',
+ 1 => 'color: #00bbdd;',
+ 2 => 'color: #0000FF;',
+ 3 => 'color: #000099;',
+ 4 => 'color: #333333;',
+ 5 => 'color: #333333;'
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => 'http://december.com/html/4/element/{FNAMEL}.html',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<!--' => '-->'
+ ),
+ 1 => array(
+ '<!DOCTYPE' => '>'
+ ),
+ 2 => "/(?!<#)(?:(?:##)*)(#)[a-zA-Z0-9_\.\(\)]+(#)/",
+ 3 => array(
+ '<cfscript>' => '</cfscript>'
+ ),
+ 4 => array(
+ '<' => '>'
+ ),
+ 5 => '/((?!<!)<)(?:"[^"]*"|\'[^\']*\'|(?R)|[^">])+?(>)/si'
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => false,
+ 1 => false,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+ 'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+ ),
+ 2 => array(
+ 'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+ 'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+ ),
+ 3 => array(
+ 'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#>|^])', // allow ; before keywords
+ 'DISALLOWED_AFTER' => '(?![a-zA-Z0-9_\|%\\-])', // allow & after keywords
+ ),
+ 7 => array(
+ 'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#>&|^])', // allow ; before keywords
+ 'DISALLOWED_AFTER' => '(?![a-zA-Z0-9_\|%\\-])', // allow & after keywords
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/chaiscript.php b/platform/www/vendor/geshi/geshi/src/geshi/chaiscript.php
new file mode 100644
index 0000000..e816782
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/chaiscript.php
@@ -0,0 +1,138 @@
+<?php
+/*************************************************************************************
+ * chaiscript.php
+ * --------------
+ * Author: Jason Turner & Jonathan Turner
+ * Copyright: (c) 2010 Jason Turner (lefticus@gmail.com),
+ * (c) 2009 Jonathan Turner,
+ * (c) 2004 Ben Keen (ben.keen@gmail.com), Benny Baumann (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/07/03
+ *
+ * ChaiScript language file for GeSHi.
+ *
+ * Based on JavaScript by Ben Keen (ben.keen@gmail.com)
+ *
+ * CHANGES
+ * -------
+ * 2010/03/30 (1.0.8.8)
+ * - Updated to include more language features
+ * - Removed left over pieces from JavaScript
+ * 2009/07/03 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ChaiScript',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ //Regular Expressions
+ 'COMMENT_REGEXP' => array(2 => "/(?<=[\\s^])s\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[gimsu]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])m?\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[gimsu]*(?=[\\s$\\.\\,\\;\\)])/iU"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'break', 'else', 'elseif', 'eval', 'for', 'if', 'return', 'while', 'try', 'catch', 'finally',
+ ),
+ 2 => array(
+ 'def', 'false', 'fun', 'true', 'var', 'attr',
+ ),
+ 3 => array(
+ // built in functions
+ 'throw',
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}',
+ '+', '-', '*', '/', '%',
+ '!', '@', '&', '|', '^',
+ '<', '>', '=',
+ ',', ';', '?', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000066; font-weight: bold;',
+ 2 => 'color: #003366; font-weight: bold;',
+ 3 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #006600; font-style: italic;',
+ 2 => 'color: #009966; font-style: italic;',
+ 'MULTI' => 'color: #006600; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #3366CC;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #CC0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #660066;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ ),
+ 1 => array(
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/chapel.php b/platform/www/vendor/geshi/geshi/src/geshi/chapel.php
new file mode 100644
index 0000000..4f31f88
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/chapel.php
@@ -0,0 +1,169 @@
+<?php
+/*************************************************************************************
+ * chapel.php
+ * -----
+ * Author: Richard Molitor (richard.molitor@student.kit.edu)
+ * Copyright: (c) 2013 Richard Molitor
+ * Release Version: 1.0.9.1
+ * Date Started: 2013/06/22
+ *
+ * Chapel language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2013/06/22 (1.0.8.13)
+ * - First Release
+ *
+ * TODO (updated 2013/06/22)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Chapel',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI | GESHI_NUMBER_FLT_NONSCI_F |
+ GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ // statements
+ 1 => array(
+ 'atomic', 'begin', 'break', 'class', 'cobegin', 'coforall',
+ 'continue', 'do', 'else', 'export', 'extern', 'for', 'forall', 'if',
+ 'iter', 'inline', 'label', 'let', 'local', 'module',
+ 'otherwise', 'proc', 'record', 'return', 'select', 'serial',
+ 'then', 'use', 'var', 'when', 'where', 'while', 'yield'
+ ),
+ // literals
+ 2 => array(
+ 'nil', 'true', 'false'
+ ),
+ // built-in functions
+ 3 => array(
+ 'by', 'delete', 'dmapped', 'domain', 'enum', 'index', 'min',
+ 'minloc', 'max', 'maxloc', 'new', 'range', 'reduce', 'scan',
+ 'sparse', 'subdomain', 'sync', 'union', 'zip'
+ ),
+ // built-in types
+ 4 => array(
+ 'config', 'const', 'in', 'inout', 'opaque', 'on', 'out', 'param',
+ 'ref', 'single', 'type'
+ ),
+ // library types
+ 5 => array(
+ 'void', 'bool', 'int', 'uint', 'real', 'imag', 'complex', 'string',
+ 'locale'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']',
+ '+', '-', '*', '/', '%',
+ '=', '<', '>',
+ '!', '^', '&', '|',
+ '?', ':',
+ ';', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #993333;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ //2 => 'color: #339933;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/cil.php b/platform/www/vendor/geshi/geshi/src/geshi/cil.php
new file mode 100644
index 0000000..152fcc2
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/cil.php
@@ -0,0 +1,194 @@
+<?php
+/*************************************************************************************
+ * cil.php
+ * --------
+ * Author: Marcus Griep (neoeinstein+GeSHi@gmail.com)
+ * Copyright: (c) 2007 Marcus Griep (http://www.xpdm.us)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/10/24
+ *
+ * CIL (Common Intermediate Language) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/10/24 (1.0.8)
+ * - First Release
+ *
+ * TODO (updated 2007/10/24)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'CIL',
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'COMMENT_SINGLE' => array('//'),
+ 'COMMENT_MULTI' => array(),
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(//Dotted
+ '.zeroinit', '.vtfixup', '.vtentry', '.vtable', '.ver', '.try', '.subsystem', '.size', '.set', '.removeon',
+ '.publickeytoken', '.publickey', '.property', '.permissionset', '.permission', '.pdirect', '.param', '.pack',
+ '.override', '.other', '.namespace', '.mresource', '.module', '.method', '.maxstack', '.manifestres', '.locals',
+ '.localized', '.locale', '.line', '.language', '.import', '.imagebase', '.hash', '.get', '.fire', '.file', '.field',
+ '.export', '.event', '.entrypoint', '.emitbyte', '.data', '.custom', '.culture', '.ctor', '.corflags', '.class',
+ '.cctor', '.assembly', '.addon'
+ ),
+ 2 => array(//Attributes
+ 'wrapper', 'with', 'winapi', 'virtual', 'vector', 'vararg', 'value', 'userdefined', 'unused', 'unmanagedexp',
+ 'unmanaged', 'unicode', 'to', 'tls', 'thiscall', 'synchronized', 'struct', 'strict', 'storage', 'stdcall',
+ 'static', 'specialname', 'special', 'serializable', 'sequential', 'sealed', 'runtime', 'rtspecialname', 'request',
+ 'reqsecobj', 'reqrefuse', 'reqopt', 'reqmin', 'record', 'public', 'privatescope', 'private', 'preservesig',
+ 'prejitgrant', 'prejitdeny', 'platformapi', 'pinvokeimpl', 'pinned', 'permitonly', 'out', 'optil', 'opt',
+ 'notserialized', 'notremotable', 'not_in_gc_heap', 'noprocess', 'noncaslinkdemand', 'noncasinheritance',
+ 'noncasdemand', 'nometadata', 'nomangle', 'nomachine', 'noinlining', 'noappdomain', 'newslot', 'nested', 'native',
+ 'modreq', 'modopt', 'marshal', 'managed', 'literal', 'linkcheck', 'lcid', 'lasterr', 'internalcall', 'interface',
+ 'instance', 'initonly', 'init', 'inheritcheck', 'in', 'import', 'implicitres', 'implicitcom', 'implements',
+ 'illegal', 'il', 'hidebysig', 'handler', 'fromunmanaged', 'forwardref', 'fixed', 'finally', 'final', 'filter',
+ 'filetime', 'field', 'fault', 'fastcall', 'famorassem', 'family', 'famandassem', 'extern', 'extends', 'explicit',
+ 'error', 'enum', 'endmac', 'deny', 'demand', 'default', 'custom', 'compilercontrolled', 'clsid', 'class', 'cil',
+ 'cf', 'cdecl', 'catch', 'beforefieldinit', 'autochar', 'auto', 'at', 'assert', 'assembly', 'as', 'any', 'ansi',
+ 'alignment', 'algorithm', 'abstract'
+ ),
+ 3 => array(//Types
+ 'wchar', 'void', 'variant', 'unsigned', 'valuetype', 'typedref', 'tbstr', 'sysstring', 'syschar', 'string',
+ 'streamed_object', 'stream', 'stored_object', 'safearray', 'objectref', 'object', 'nullref', 'method', 'lpwstr',
+ 'lpvoid', 'lptstr', 'lpstruct', 'lpstr', 'iunknown', 'int64', 'int32', 'int16', 'int8', 'int', 'idispatch',
+ 'hresult', 'float64', 'float32', 'float', 'decimal', 'date', 'currency', 'char', 'carray', 'byvalstr',
+ 'bytearray', 'boxed', 'bool', 'blob_object', 'blob', 'array'
+ ),
+ 4 => array(//Prefix
+ 'volatile', 'unaligned', 'tail', 'readonly', 'no', 'constrained'
+ ),
+ 5 => array(//Suffix
+ 'un', 'u8', 'u4', 'u2', 'u1', 'u', 's', 'ref', 'r8', 'r4', 'm1', 'i8', 'i4', 'i2', 'i1', 'i'#, '.8', '.7', '.6', '.5', '.4', '.3', '.2', '.1', '.0'
+ ),
+ 6 => array(//Base
+ 'xor', 'switch', 'sub', 'stloc',
+ 'stind', 'starg',
+ 'shr', 'shl', 'ret', 'rem', 'pop', 'or', 'not', 'nop', 'neg', 'mul',
+ 'localloc', 'leave', 'ldnull', 'ldloca',
+ 'ldloc', 'ldind', 'ldftn', 'ldc', 'ldarga',
+ 'ldarg', 'jmp', 'initblk', 'endfinally', 'endfilter',
+ 'endfault', 'dup', 'div', 'cpblk', 'conv', 'clt', 'ckfinite', 'cgt', 'ceq', 'calli',
+ 'call', 'brzero', 'brtrue', 'brnull', 'brinst',
+ 'brfalse', 'break', 'br', 'bne', 'blt', 'ble', 'bgt', 'bge', 'beq', 'arglist',
+ 'and', 'add'
+ ),
+ 7 => array(//Object
+ 'unbox.any', 'unbox', 'throw', 'stsfld', 'stobj', 'stfld', 'stelem', 'sizeof', 'rethrow', 'refanyval', 'refanytype', 'newobj',
+ 'newarr', 'mkrefany', 'ldvirtftn', 'ldtoken', 'ldstr', 'ldsflda', 'ldsfld', 'ldobj', 'ldlen', 'ldflda', 'ldfld',
+ 'ldelema', 'ldelem', 'isinst', 'initobj', 'cpobj', 'castclass',
+ 'callvirt', 'callmostderived', 'box'
+ ),
+ 8 => array(//Other
+ 'prefixref', 'prefix7', 'prefix6', 'prefix5', 'prefix4', 'prefix3', 'prefix2', 'prefix1', 'prefix0'
+ ),
+ 9 => array(//Literal
+ 'true', 'null', 'false'
+ ),
+ 10 => array(//Comment-like
+ '#line', '^THE_END^'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '!', '!!'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true,
+ 10 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color:maroon;font-weight:bold;',
+ 2 => 'color:blue;font-weight:bold;',
+ 3 => 'color:purple;font-weight:bold;',
+ 4 => 'color:teal;',
+ 5 => 'color:blue;',
+ 6 => 'color:blue;',
+ 7 => 'color:blue;',
+ 8 => 'color:blue;',
+ 9 => 'color:00008B',
+ 10 => 'color:gray'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color:gray;font-style:italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #008000; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #006400;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #00008B;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #000033;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #006400;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color:blue;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+ 9 => '',
+ 10 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '::'
+ ),
+ 'REGEXPS' => array(
+ 0 => '(?<=ldc\\.i4\\.)[0-8]|(?<=(?:ldarg|ldloc|stloc)\\.)[0-3]' # Pickup the opcodes that end with integers
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/clojure.php b/platform/www/vendor/geshi/geshi/src/geshi/clojure.php
new file mode 100644
index 0000000..55cbc42
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/clojure.php
@@ -0,0 +1,132 @@
+<?php
+/*************************************************************************************
+ * clojure.php
+ * --------
+ * Author: Jess Johnson (jess@grok-code.com)
+ * Copyright: (c) 2009 Jess Johnson (http://grok-code.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/09/20
+ *
+ * Clojure language file for GeSHi.
+ *
+ * This file borrows significantly from the lisp language file for GeSHi
+ *
+ * CHANGES
+ * -------
+ * 2009/09/20 (1.0.8.6)
+ * - First Release
+ *
+ * TODO (updated 2009/09/20)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Clojure',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(';|' => '|;'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'defn', 'defn-', 'defmulti', 'defmethod', 'defmacro', 'deftest',
+ 'defstruct', 'def', 'defonce', 'let', 'letfn', 'do', 'cond', 'condp',
+ 'for', 'loop', 'recur', 'when', 'when-not', 'when-let', 'when-first',
+ 'if', 'if-let', 'if-not', 'doto', 'and', 'or','not','aget','aset',
+ 'dosync', 'doseq', 'dotimes', 'dorun', 'doall',
+ 'load', 'import', 'unimport', 'ns', 'in-ns', 'refer', 'print',
+ 'try', 'catch', 'finally', 'throw', 'fn', 'update-in',
+ 'with-open', 'with-local-vars', 'binding',
+ 'gen-class', 'gen-and-load-class', 'gen-and-save-class',
+ 'implement', 'proxy', 'lazy-cons', 'with-meta',
+ 'struct', 'struct-map', 'delay', 'locking', 'sync', 'time', 'apply',
+ 'remove', 'merge', 'interleave', 'interpose', 'distinct',
+ 'cons', 'concat', 'lazy-cat', 'cycle', 'rest', 'frest', 'drop',
+ 'drop-while', 'nthrest', 'take', 'take-while', 'take-nth', 'butlast',
+ 'reverse', 'sort', 'sort-by', 'split-at', 'partition', 'split-with',
+ 'first', 'ffirst', 'rfirst', 'zipmap', 'into', 'set', 'vec',
+ 'to-array-2d', 'not-empty', 'seq?', 'not-every?', 'every?', 'not-any?',
+ 'map', 'mapcat', 'vector?', 'list?', 'hash-map', 'reduce', 'filter',
+ 'vals', 'keys', 'rseq', 'subseq', 'rsubseq', 'count', 'empty?',
+ 'fnseq', 'repeatedly', 'iterate', 'drop-last',
+ 'repeat', 'replicate', 'range', 'into-array',
+ 'line-seq', 'resultset-seq', 're-seq', 're-find', 'tree-seq', 'file-seq',
+ 'iterator-seq', 'enumeration-seq', 'declare', 'xml-seq',
+ 'symbol?', 'string?', 'vector', 'conj', 'str',
+ 'pos?', 'neg?', 'zero?', 'nil?', 'inc', 'dec', 'format',
+ 'alter', 'commute', 'ref-set', 'floor', 'assoc', 'send', 'send-off'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '!', '%', '^', '&', '/','+','-','*','=','<','>',';','|', '.', '..', '->',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #555;',
+ 1 => 'color: #555;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ '::', ':'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/cmake.php b/platform/www/vendor/geshi/geshi/src/geshi/cmake.php
new file mode 100644
index 0000000..13e67ff
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/cmake.php
@@ -0,0 +1,179 @@
+<?php
+/*************************************************************************************
+ * cmake.php
+ * -------
+ * Author: Daniel Nelson (danieln@eng.utah.edu)
+ * Copyright: (c) 2009 Daniel Nelson
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/04/06
+ *
+ * CMake language file for GeSHi.
+ *
+ * Keyword list generated using CMake 2.6.3.
+ *
+ * CHANGES
+ * -------
+ * <date-of-release> (<GeSHi release>)
+ * - First Release
+ *
+ * TODO (updated <date-of-release>)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'CMake',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'ESCAPE_REGEXP' => array(
+ // Quoted variables ${...}
+ 1 => "/\\$(ENV)?\\{[^\\n\\}]*?\\}/i",
+ // Quoted registry keys [...]
+ 2 => "/\\[HKEY[^\n\\]]*?]/i"
+ ),
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'add_custom_command', 'add_custom_target', 'add_definitions',
+ 'add_dependencies', 'add_executable', 'add_library',
+ 'add_subdirectory', 'add_test', 'aux_source_directory', 'break',
+ 'build_command', 'cmake_minimum_required', 'cmake_policy',
+ 'configure_file', 'create_test_sourcelist', 'define_property',
+ 'else', 'elseif', 'enable_language', 'enable_testing',
+ 'endforeach', 'endfunction', 'endif', 'endmacro',
+ 'endwhile', 'execute_process', 'export', 'file', 'find_file',
+ 'find_library', 'find_package', 'find_path', 'find_program',
+ 'fltk_wrap_ui', 'foreach', 'function', 'get_cmake_property',
+ 'get_directory_property', 'get_filename_component', 'get_property',
+ 'get_source_file_property', 'get_target_property',
+ 'get_test_property', 'if', 'include', 'include_directories',
+ 'include_external_msproject', 'include_regular_expression',
+ 'install', 'link_directories', 'list', 'load_cache',
+ 'load_command', 'macro', 'mark_as_advanced', 'math', 'message',
+ 'option', 'output_required_files', 'project', 'qt_wrap_cpp',
+ 'qt_wrap_ui', 'remove_definitions', 'return', 'separate_arguments',
+ 'set', 'set_directory_properties', 'set_property',
+ 'set_source_files_properties', 'set_target_properties',
+ 'set_tests_properties', 'site_name', 'source_group', 'string',
+ 'target_link_libraries', 'try_compile', 'try_run', 'unset',
+ 'variable_watch', 'while'
+ ),
+ 2 => array(
+ // Deprecated commands
+ 'build_name', 'exec_program', 'export_library_dependencies',
+ 'install_files', 'install_programs', 'install_targets',
+ 'link_libraries', 'make_directory', 'remove', 'subdir_depends',
+ 'subdirs', 'use_mangled_mesa', 'utility_source',
+ 'variable_requires', 'write_file'
+ ),
+ 3 => array(
+ // Special command arguments, this list is not comprehesive.
+ 'AND', 'APPEND', 'ASCII', 'BOOL', 'CACHE', 'COMMAND', 'COMMENT',
+ 'COMPARE', 'CONFIGURE', 'DEFINED', 'DEPENDS', 'DIRECTORY',
+ 'EQUAL', 'EXCLUDE_FROM_ALL', 'EXISTS', 'FALSE', 'FATAL_ERROR',
+ 'FILEPATH', 'FIND', 'FORCE', 'GET', 'GLOBAL', 'GREATER',
+ 'IMPLICIT_DEPENDS', 'INSERT', 'INTERNAL', 'IS_ABSOLUTE',
+ 'IS_DIRECTORY', 'IS_NEWER_THAN', 'LENGTH', 'LESS',
+ 'MAIN_DEPENDENCY', 'MATCH', 'MATCHALL', 'MATCHES', 'MODULE', 'NOT',
+ 'NOTFOUND', 'OFF', 'ON', 'OR', 'OUTPUT', 'PARENT_SCOPE', 'PATH',
+ 'POLICY', 'POST_BUILD', 'PRE_BUILD', 'PRE_LINK', 'PROPERTY',
+ 'RANDOM', 'REGEX', 'REMOVE_AT', 'REMOVE_DUPLICATES', 'REMOVE_ITEM',
+ 'REPLACE', 'REVERSE', 'SEND_ERROR', 'SHARED', 'SORT', 'SOURCE',
+ 'STATIC', 'STATUS', 'STREQUAL', 'STRGREATER', 'STRING', 'STRIP',
+ 'STRLESS', 'SUBSTRING', 'TARGET', 'TEST', 'TOLOWER', 'TOUPPER',
+ 'TRUE', 'VERBATIM', 'VERSION', 'VERSION_EQUAL', 'VERSION_GREATOR',
+ 'VERSION_LESS', 'WORKING_DIRECTORY',
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => true
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')')
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #1f3f81; font-style: bold;',
+ 2 => 'color: #1f3f81;',
+ 3 => 'color: #077807; font-sytle: italic;'
+ ),
+ 'BRACKETS' => array(),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #b08000;',
+ 2 => 'color: #0000cd;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #912f11;',
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #197d8b;'
+ ),
+ 'NUMBERS' => array(),
+ 'METHODS' => array(),
+ 'REGEXPS' => array(
+ 0 => 'color: #b08000;',
+ 1 => 'color: #0000cd;'
+ ),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.cmake.org/cmake/help/cmake2.6docs.html#command:{FNAMEL}',
+ 2 => 'http://www.cmake.org/cmake/help/cmake2.6docs.html#command:{FNAMEL}',
+ 3 => '',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ // Unquoted variables
+ 0 => "\\$(ENV)?\\{[^\\n}]*?\\}",
+ // Unquoted registry keys
+ 1 => "\\[HKEY[^\n\\]]*?]"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ // These keywords cannot come after a open paren
+ 1 => array(
+ 'DISALLOWED_AFTER' => '(?= *\()'
+ ),
+ 2 => array(
+ 'DISALLOWED_AFTER' => '(?= *\()'
+ )
+ ),
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER,
+ 'METHODS' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/cobol.php b/platform/www/vendor/geshi/geshi/src/geshi/cobol.php
new file mode 100644
index 0000000..ac466f2
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/cobol.php
@@ -0,0 +1,457 @@
+<?php
+/*************************************************************************************
+ * cobol.php
+ * ----------
+ * Author: BenBE (BenBE@omorphia.org)
+ * Copyright: (c) 2007-2008 BenBE (http://www.omorphia.de/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/07/02
+ *
+ * COBOL language file for GeSHi.
+ *
+ * Most of the compiler directives, reserved words and intrinsic functions are
+ * from the 2009 COBOL Draft Standard, Micro Focus, and GNU Cobol. The lists of
+ * these were found in the draft standard (Sections 8.9, 8.10, 8.11 and 8.12),
+ * Micro Focus' COBOL Language Reference and the GNU Cobol FAQ.
+ *
+ * CHANGES
+ * -------
+ * 2013/11/17 (1.0.8.13)
+ * - Changed compiler directives to be handled like comments.
+ * - Fixed bug where keywords in identifiers were highlighted.
+ * 2013/08/19 (1.0.8.13)
+ * - Added more intrinsic functions, reserved words, and compiler directives
+ * from the (upcoming) standard.
+ * 2013/07/07 (1.0.8.13)
+ * - Added more reserved words, compiler directives and intrinsic functions.
+ * - Added modern comment syntax and corrected the other one.
+ * - Set OOLANG to true and added an object splitter.
+ * - Added extra symbols.
+ * - Fixed bug where scope terminators were only the statement in
+ * end-statement was highlighted.
+ *
+ * TODO (updated 2013/11/17)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'COBOL',
+ 'COMMENT_SINGLE' => array(
+ 1 => '*>', // COBOL 2002 inline comment
+ 2 => '>>' // COBOL compiler directive indicator
+ ),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 1 => '/^......(\*.*?$)/m', // Fixed-form comment
+ 2 => '/\$SET.*/i' // MF compiler directive indicator
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'"),
+ 'ESCAPE_CHAR' => '',
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_SCI_SHORT |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ // Statements containing spaces. These are separate to other statements
+ // so that they are highlighted correctly.
+ 1 => array(
+ 'DELETE FILE', 'GO TO', 'NEXT SENTENCE', 'XML GENERATE',
+ 'XML PARSE'
+ ),
+
+ 2 => array( // Other Reserved Words
+ '3-D', 'ABSENT', 'ABSTRACT', 'ACCESS', 'ACQUIRE',
+ 'ACTION', 'ACTIVE-CLASS', 'ACTIVE-X', 'ACTUAL', 'ADDRESS',
+ 'ADDRESS-ARRAY', 'ADDRESS-OFFSET', 'ADJUSTABLE-COLUMNS',
+ 'ADVANCING', 'AFP-5A', 'AFTER', 'ALIGNED', 'ALIGNMENT', 'ALL',
+ 'ALLOW', 'ALLOWING', 'ALPHABET', 'ALPHABETIC',
+ 'ALPHABETIC-LOWER', 'ALPHABETIC-UPPER', 'ALPHANUMERIC',
+ 'ALPHANUMERIC-EDITED', 'ALSO', 'ALTERNATE', 'AND', 'ANY',
+ 'ANYCASE',
+ 'APPLY', 'ARE', 'AREA', 'AREAS', 'ARGUMENT-NUMBER',
+ 'ARGUMENT-VALUE',
+ 'ARITHMETIC', 'AS', 'ASCENDING',
+ 'ASSEMBLY-ATTRIBUTES', 'ASSIGN', 'AT', 'ATTRIBUTE', 'AUTHOR',
+ 'AUTO', 'AUTO-DECIMAL', 'AUTO-HYPHEN-SKIP', 'AUTO-MINIMIZE',
+ 'AUTO-RESIZE', 'AUTO-SKIP', 'AUTO-SPIN', 'AUTOMATIC',
+ 'AUTOTERMINATE', 'AWAY-FROM-ZERO',
+ 'AX-EVENT-LIST', 'B-AND', 'B-EXOR', 'B-LEFT',
+ 'B-NOT', 'B-OR', 'B-RIGHT', 'B-XOR', 'BACKGROUND-COLOR',
+ 'BACKGROUND-COLOUR', 'BACKGROUND-HIGH', 'BACKGROUND-LOW',
+ 'BACKGROUND-STANDARD', 'BACKWARD', 'BAR', 'BASED', 'BASIS', 'BEEP',
+ 'BEFORE', 'BEGINNING', 'BELL', 'BINARY', 'BINARY-CHAR',
+ 'BINARY-DOUBLE', 'BINARY-LONG', 'BINARY-SHORT', 'BIND', 'BIT',
+ 'BITMAP', 'BITMAP-END', 'BITMAP-HANDLE', 'BITMAP-NUMBER',
+ 'BITMAP-RAW-HEIGHT', 'BITMAP-RAW-WIDTH', 'BITMAP-SCALE',
+ 'BITMAP-START', 'BITMAP-TIMER', 'BITMAP-TRAILING', 'BITMAP-WIDTH',
+ 'BLANK', 'BLINK', 'BLINKING', 'BLOB', 'BLOB-FILE', 'BLOB-LOCATOR',
+ 'BLOCK', 'BOLD', 'BOOLEAN', 'BOTTOM', 'BOX', 'BOXED', 'BROWSING',
+ 'BUSY', 'BUTTONS', 'BY', 'C01', 'C02', 'C03', 'C04',
+ 'C05',
+ 'C06', 'C07', 'C08', 'C09', 'C10', 'C11', 'C12', 'CALENDAR-FONT',
+ 'CALLED', 'CANCEL-BUTTON', 'CAPACITY', 'CATCH', 'CBL',
+ 'CBL-CTR', 'CCOL', 'CD', 'CELL', 'CELL-COLOR', 'CELL-DATA',
+ 'CELL-FONT', 'CELL-PROTECTION', 'CELLS', 'CENTER', 'CENTERED',
+ 'CENTERED-HEADINGS', 'CENTURY-DATE', 'CENTURY-DAY', 'CF', 'CH',
+ 'CHAINING', 'CHANGED', 'CHAR-VARYING',
+ 'CHARACTER',
+ 'CHARACTERS', 'CHART', 'CHECK-BOX', 'CHECKING', 'CLASS',
+ 'CLASS-ATTRIBUTES', 'CLASS-CONTROL', 'CLASS-ID', 'CLASS-OBJECT',
+ 'CLASSIFICATION',
+ 'CLEAR-SELECTION', 'CLINE', 'CLINES', 'CLOB', 'CLOB-FILE',
+ 'CLOB-LOCATOR', 'CLOCK-UNITS', 'COBOL', 'CODE', 'CODE-SET',
+ 'COERCION', 'COL', 'COLLATING', 'COLORS', 'COLOUR',
+ 'COLOURS', 'COLS', 'COLUMN', 'COLUMN-COLOR', 'COLUMN-DIVIDERS',
+ 'COLUMN-FONT', 'COLUMN-HEADINGS', 'COLUMN-PROTECTION', 'COLUMNS',
+ 'COM-REG', 'COMBO-BOX', 'COMMA', 'COMMITMENT', 'COMMON',
+ 'COMMUNICATION', 'COMP', 'COMP-0', 'COMP-1', 'COMP-2', 'COMP-3',
+ 'COMP-4', 'COMP-5', 'COMP-6', 'COMP-X', 'COMPRESSION',
+ 'COMPUTATIONAL', 'COMPUTATIONAL-0', 'COMPUTATIONAL-1',
+ 'COMPUTATIONAL-2', 'COMPUTATIONAL-3', 'COMPUTATIONAL-4',
+ 'COMPUTATIONAL-5', 'COMPUTATIONAL-6', 'COMPUTATIONAL-X',
+ 'CONDITION-VALUE', 'CONFIGURATION', 'CONSOLE', 'CONSTANT',
+ 'CONSTRAIN', 'CONSTRAINTS', 'CONTAINS', 'CONTENT',
+ 'CONTROL', 'CONTROL-AREA', 'CONTROLS', 'CONTROLS-UNCROPPED',
+ 'CONVERSION', 'CONVERT', 'CONVERTING', 'COPY-SELECTION',
+ 'CORE-INDEX', 'CORR', 'CORRESPONDING', 'COUNT',
+ 'CREATING', 'CRT', 'CRT-UNDER', 'CSIZE', 'CSP', 'CURRENCY',
+ 'CURSOR', 'CURSOR-COL', 'CURSOR-COLOR',
+ 'CURSOR-FRAME-WIDTH', 'CURSOR-ROW', 'CURSOR-X', 'CURSOR-Y',
+ 'CUSTOM-ATTRIBUTE', 'CUSTOM-PRINT-TEMPLATE', 'CYCLE', 'CYL-INDEX',
+ 'CYL-OVERFLOW', 'DASHED', 'DATA', 'DATA-COLUMNS',
+ 'DATA-POINTER', 'DATA-TYPES', 'DATABASE-KEY', 'DATABASE-KEY-LONG',
+ 'DATE', 'DATE-COMPILED', 'DATE-ENTRY', 'DATE-RECORD',
+ 'DATE-WRITTEN', 'DAY', 'DAY-OF-WEEK', 'DBCLOB', 'DBCLOB-FILE',
+ 'DBCLOB-LOCATOR', 'DBCS', 'DE', 'DEBUG', 'DEBUG-CONTENTS',
+ 'DEBUG-ITEM', 'DEBUG-LINE', 'DEBUG-NAME', 'DEBUG-SUB-1',
+ 'DEBUG-SUB-2', 'DEBUG-SUB-3', 'DEBUGGING', 'DECIMAL',
+ 'DECIMAL-POINT', 'DECLARATIVES', 'DEFAULT',
+ 'DEFAULT-BUTTON', 'DEFAULT-FONT', 'DEFINITION',
+ 'DELEGATE-ID', 'DELIMITED', 'DELIMITER', 'DEPENDING',
+ 'DESCENDING', 'DESTINATION', 'DESTROY', 'DETAIL', 'DICTIONARY',
+ 'DISABLE', 'DISC', 'DISJOINING', 'DISK', 'DISP',
+ 'DISPLAY-1', 'DISPLAY-COLUMNS', 'DISPLAY-FORMAT', 'DISPLAY-ST',
+ 'DIVIDER-COLOR', 'DIVIDERS', 'DIVISION', 'DOT-DASH',
+ 'DOTTED', 'DOWN', 'DRAG-COLOR', 'DRAW', 'DROP', 'DROP-DOWN',
+ 'DROP-LIST', 'DUPLICATES', 'DYNAMIC', 'EBCDIC', 'EC', 'ECHO', 'EGCS',
+ 'EGI', 'EJECT', 'ELEMENTARY', 'ELSE', 'EMI', 'EMPTY-CHECK',
+ 'ENABLE', 'ENABLED', 'END', 'END-ACCEPT', 'END-ADD', 'END-CALL',
+ 'END-CHAIN', 'END-COLOR', 'END-COMPUTE', 'END-DELEGATE',
+ 'END-DELETE', 'END-DISPLAY', 'END-DIVIDE', 'END-EVALUATE',
+ 'END-IF', 'END-INVOKE', 'END-MODIFY', 'END-MOVE', 'END-MULTIPLY',
+ 'END-OF-PAGE', 'END-PERFORM', 'END-READ', 'END-RECEIVE',
+ 'END-RETURN', 'END-REWRITE', 'END-SEARCH', 'END-START',
+ 'END-STRING', 'END-SUBTRACT', 'END-SYNC', 'END-TRY',
+ 'END-UNSTRING', 'END-WAIT', 'END-WRITE', 'END-XML', 'ENDING',
+ 'ENGRAVED', 'ENSURE-VISIBLE', 'ENTRY-CONVENTION',
+ 'ENTRY-FIELD',
+ 'ENTRY-REASON', 'ENUM', 'ENUM-ID', 'ENVIRONMENT',
+ 'ENVIRONMENT-NAME', 'ENVIRONMENT-VALUE', 'EOL', 'EOP',
+ 'EOS', 'EQUAL', 'EQUALS', 'ERASE', 'ERROR', 'ESCAPE',
+ 'ESCAPE-BUTTON', 'ESI', 'EVENT', 'EVENT-LIST',
+ 'EVENT-POINTER', 'EVERY', 'EXCEEDS', 'EXCEPTION',
+ 'EXCEPTION-OBJECT', 'EXCEPTION-VALUE', 'EXCESS-3',
+ 'EXCLUDE-EVENT-LIST', 'EXCLUSIVE',
+ 'EXPAND', 'EXPANDS', 'EXTEND', 'EXTENDED',
+ 'EXTENDED-SEARCH', 'EXTENSION', 'EXTERNAL', 'EXTERNAL-FORM',
+ 'EXTERNALLY-DESCRIBED-KEY', 'FACTORY', 'FALSE', 'FD',
+ 'FH--FCD', 'FH--KEYDEF', 'FILE', 'FILE-CONTROL', 'FILE-ID',
+ 'FILE-LIMIT', 'FILE-LIMITS', 'FILE-NAME', 'FILE-POS', 'FILL-COLOR',
+ 'FILL-COLOR2', 'FILL-PERCENT', 'FILLER', 'FINAL', 'FINALLY',
+ 'FINISH-REASON', 'FIRST', 'FIXED', 'FIXED-FONT', 'FIXED-WIDTH',
+ 'FLAT', 'FLAT-BUTTONS', 'FLOAT-BINARY-7', 'FLOAT-BINARY-16',
+ 'FLOAT-BINARY-34', 'FLOAT-DECIMAL-16', 'FLOAT-DECIMAL-34',
+ 'FLOAT-EXTENDED', 'FLOAT-LONG',
+ 'FLOAT-SHORT', 'FLOATING', 'FONT', 'FOOTING', 'FOR',
+ 'FOREGROUND-COLOR', 'FOREGROUND-COLOUR', 'FOREVER', 'FORMAT',
+ 'FRAME', 'FRAMED', 'FROM', 'FULL', 'FULL-HEIGHT',
+ 'FUNCTION', 'FUNCTION-ID', 'FUNCTION-POINTER', 'GENERATE',
+ 'GET', 'GETTER', 'GIVING', 'GLOBAL', 'GO-BACK', 'GO-FORWARD',
+ 'GO-HOME', 'GO-SEARCH', 'GRAPHICAL', 'GREATER', 'GRID',
+ 'GRIP', 'GROUP', 'GROUP-USAGE', 'GROUP-VALUE', 'HANDLE',
+ 'HAS-CHILDREN', 'HEADING', 'HEADING-COLOR', 'HEADING-DIVIDER-COLOR',
+ 'HEADING-FONT', 'HEAVY', 'HEIGHT', 'HEIGHT-IN-CELLS', 'HELP-ID',
+ 'HIDDEN-DATA', 'HIGH', 'HIGH-COLOR', 'HIGH-VALUE', 'HIGH-VALUES',
+ 'HIGHLIGHT', 'HORIZONTAL', 'HOT-TRACK', 'HSCROLL', 'HSCROLL-POS',
+ 'I-O', 'I-O-CONTROL', 'ICON', 'ID', 'IDENTIFICATION',
+ 'IDENTIFIED', 'IFINITY', 'IGNORE', 'IGNORING', 'IMPLEMENTS', 'IN',
+ 'INDEPENDENT', 'INDEX', 'INDEXED', 'INDEXER', 'INDEXER-ID', 'INDIC',
+ 'INDICATE', 'INDICATOR', 'INDICATORS', 'INDIRECT',
+ 'INHERITING', 'INHERITS',
+ 'INITIAL', 'INITIALIZED', 'INPUT',
+ 'INPUT-OUTPUT', 'INQUIRE', 'INSERT', 'INSERT-ROWS',
+ 'INSERTION-INDEX', 'INSTALLATION', 'INSTANCE',
+ 'INTERFACE', 'INTERFACE-ID', 'INTERMEDIATE',
+ 'INTERNAL', 'INTO', 'INTRINSIC',
+ 'INVALID', 'INVOKED', 'IS', 'ITEM', 'ITEM-BOLD',
+ 'ITEM-ID', 'ITEM-TEXT', 'ITEM-TO-ADD', 'ITEM-TO-DELETE',
+ 'ITEM-TO-EMPTY', 'ITEM-VALUE', 'ITERATOR', 'ITERATOR-ID', 'J',
+ 'JOINED', 'JOINING', 'JUST', 'JUSTIFIED', 'KANJI',
+ 'KEPT', 'KEY', 'KEY-YY', 'KEYBOARD', 'LABEL', 'LABEL-OFFSET',
+ 'LARGE-FONT', 'LAST', 'LAST-ROW', 'LAYOUT-DATA', 'LAYOUT-MANAGER',
+ 'LC_ALL', 'LC_COLLATE', 'LC_CTYPE', 'LC_CURRENCY', 'LC_MESSAGES',
+ 'LC_MONETARY', 'LC_NUMERIC', 'LC_TIME', 'LEADING', 'LEADING-SHIFT',
+ 'LEAVE', 'LEFT', 'LEFT-JUSTIFY', 'LEFT-TEXT', 'LEFTLINE',
+ 'LENGTH-CHECK', 'LESS', 'LIMIT', 'LIMITS', 'LIN', 'LINAGE',
+ 'LINAGE-COUNTER', 'LINE', 'LINE-COUNTER', 'LINES', 'LINES-AT-ROOT',
+ 'LINK', 'LINKAGE', 'LIST', 'LIST-BOX', 'LM-RESIZE', 'LOCAL-STORAGE',
+ 'LOCALE', 'LOCK', 'LOCKING', 'LONG-DATE', 'LONG-VARBINARY',
+ 'LONG-VARCHAR', 'LOW', 'LOW-COLOR', 'LOW-VALUE', 'LOW-VALUES',
+ 'LOWER', 'LOWERED', 'LOWLIGHT', 'MANUAL', 'MASS-UPDATE',
+ 'MASTER-INDEX', 'MAX-HEIGHT', 'MAX-LINES', 'MAX-PROGRESS',
+ 'MAX-SIZE', 'MAX-TEXT', 'MAX-VAL', 'MAX-WIDTH', 'MDI-CHILD',
+ 'MDI-FRAME', 'MEDIUM-FONT', 'MEMORY', 'MENU', 'MESSAGE',
+ 'MESSAGES', 'METACLASS', 'METHOD', 'METHOD-ID', 'MIN-HEIGHT',
+ 'MIN-LINES', 'MIN-SIZE', 'MIN-VAL', 'MIN-WIDTH', 'MODAL', 'MODE',
+ 'MODELESS', 'MODIFIED', 'MODULES', 'MONITOR-POINTER',
+ 'MORE-LABELS', 'MULTILINE',
+ 'MUTEX-POINTER', 'NAME', 'NAMED', 'NATIONAL',
+ 'NATIONAL-EDITED', 'NATIVE', 'NAVIGATE-URL', 'NCHAR',
+ 'NEAREST-AWAY-FROM-ZERO', 'NEAREST-EVEN', 'NEAREST-TOWARD-ZERO',
+ 'NEGATIVE', 'NEGATIVE-INFINITY',
+ 'NESTED', 'NET-EVENT-LIST', 'NEW', 'NEWABLE', 'NEXT ', 'NEXT-ITEM',
+ 'NO', 'NO-AUTO-DEFAULT', 'NO-AUTOSEL', 'NO-BOX', 'NO-CELL-DRAG',
+ 'NO-CLOSE', 'NO-DIVIDERS', 'NO-ECHO', 'NO-F4', 'NO-FOCUS',
+ 'NO-GROUP-TAB', 'NO-KEY-LETTER', 'NO-SEARCH', 'NO-TAB', 'NO-UPDOWN',
+ 'NOMINAL', 'NONE', 'NORMAL', 'NOT', 'NOT-A-NUMBER', 'NOTIFY',
+ 'NOTIFY-CHANGE', 'NOTIFY-DBLCLICK', 'NOTIFY-SELCHANGE',
+ 'NSTD-REELS', 'NULL', 'NULLS', 'NUM-COL-HEADINGS',
+ 'NUM-ROW-HEADINGS', 'NUM-ROWS', 'NUMBER', 'NUMBERS', 'NUMERIC',
+ 'NUMERIC-EDITED', 'NUMERIC-FILL', 'O-FILL', 'OBJECT',
+ 'OBJECT-COMPUTER', 'OBJECT-ID', 'OBJECT-REFERENCE',
+ 'OBJECT-STORAGE', 'OCCURS', 'OF', 'OFF', 'OK-BUTTON', 'OMITTED',
+ 'ONLY', 'OOSTACKPTR', 'OPERATOR', 'OPERATOR-ID',
+ 'OPTIONAL', 'OPTIONS', 'OR', 'ORDER', 'ORGANIZATION', 'OTHER',
+ 'OTHERWISE', 'OUTPUT', 'OVERFLOW', 'OVERLAP-LEFT', 'OVERLAP-TOP',
+ 'OVERLAPPED', 'OVERLINE', 'OVERRIDE', 'PACKED-DECIMAL',
+ 'PADDING', 'PAGE', 'PAGE-COUNTER', 'PAGE-SETUP', 'PAGE-SIZE',
+ 'PAGED', 'PANEL-INDEX', 'PANEL-STYLE', 'PANEL-TEXT', 'PANEL-WIDTHS',
+ 'PARAGRAPH', 'PARAMS', 'PARENT', 'PARSE', 'PARTIAL', 'PASSWORD',
+ 'PERMANENT', 'PF', 'PH', 'PIC', 'PICTURE', 'PIXEL',
+ 'PIXELS', 'PLACEMENT', 'PLUS', 'POINTER', 'POP-UP', 'POSITION',
+ 'POSITION-SHIFT', 'POSITIONING', 'POSITIVE', 'POSITIVE-INFINITY',
+ 'PREFIXED', 'PREFIXING', 'PRESENT',
+ 'PREVIOUS', 'PRINT', 'PRINT-CONTROL', 'PRINT-NO-PROMPT',
+ 'PRINT-PREVIEW', 'PRINT-SWITCH', 'PRINTER', 'PRINTER-1', 'PRINTING',
+ 'PRIOR', 'PRIORITY', 'PRIVATE', 'PROCEDURE', 'PROCEDURE-POINTER',
+ 'PROCEDURES', 'PROCEED', 'PROCESS', 'PROCESSING', 'PROGRAM',
+ 'PROGRAM-ID', 'PROGRAM-POINTER', 'PROGRESS', 'PROHIBITED',
+ 'PROMPT', 'PROPERTIES',
+ 'PROPERTY', 'PROPERTY-ID', 'PROPERTY-VALUE', 'PROTECTED',
+ 'PROTOTYPE', 'PUBLIC', 'PURGE', 'PUSH-BUTTON', 'QUERY-INDEX',
+ 'QUEUE', 'QUOTE', 'QUOTES', 'RADIO-BUTTON', 'RAISED',
+ 'RAISING', 'RD', 'READ-ONLY', 'READING',
+ 'READY', 'RECORD', 'RECORD-DATA', 'RECORD-OVERFLOW',
+ 'RECORD-TO-ADD', 'RECORD-TO-DELETE', 'RECORDING', 'RECORDS',
+ 'RECURSIVE', 'REDEFINE', 'REDEFINES', 'REDEFINITION', 'REEL',
+ 'REFERENCE', 'REFERENCES', 'REFRESH', 'REGION-COLOR', 'RELATION',
+ 'RELATIVE', 'RELOAD', 'REMAINDER', 'REMARKS', 'REMOVAL',
+ 'RENAMES', 'REORG-CRITERIA', 'REPEATED', 'REPLACE', 'REPLACING',
+ 'REPORT', 'REPORTING', 'REPORTS', 'REPOSITORY', 'REQUIRED',
+ 'REPRESENTS-NOT-A-NUMBER',
+ 'REREAD', 'RERUN', 'RESERVE', 'RESET-GRID', 'RESET-LIST',
+ 'RESET-TABS', 'RESIZABLE', 'RESTRICTED', 'RESULT-SET-LOCATOR',
+ 'RETRY', 'RETURN-CODE', 'RETURNING',
+ 'REVERSE-VIDEO', 'REVERSED', 'REWIND', 'RF', 'RH',
+ 'RIGHT', 'RIGHT-ALIGN', 'RIGHT-JUSTIFY', 'RIMMED',
+ 'ROLLING', 'ROUNDED', 'ROUNDING', 'ROW-COLOR', 'ROW-COLOR-PATTERN',
+ 'ROW-DIVIDERS', 'ROW-FONT', 'ROW-HEADINGS', 'ROW-PROTECTION',
+ 'ROWID', 'RUN', 'S01', 'S02', 'S03', 'S04', 'S05', 'SAME',
+ 'SAVE-AS', 'SAVE-AS-NO-PROMPT', 'SCREEN', 'SCROLL', 'SCROLL-BAR',
+ 'SD', 'SEARCH-OPTIONS', 'SEARCH-TEXT', 'SECONDS',
+ 'SECTION', 'SECURE', 'SECURITY', 'SEEK', 'SEGMENT', 'SEGMENT-LIMIT',
+ 'SELECT-ALL', 'SELECTION-INDEX', 'SELECTION-TEXT',
+ 'SELECTIVE', 'SELF', 'SELF-ACT', 'SELFCLASS', 'SEMAPHORE-POINTER',
+ 'SEND', 'SENTENCE', 'SEPARATE', 'SEPARATION', 'SEQUENCE',
+ 'SEQUENTIAL', 'SETTER', 'SHADING', 'SHADOW',
+ 'SHARING', 'SHIFT-IN', 'SHIFT-OUT', 'SHORT-DATE', 'SHOW-LINES',
+ 'SHOW-NONE', 'SHOW-SEL-ALWAYS', 'SIGNED', 'SIGNED-INT',
+ 'SIGNED-LONG', 'SIGNED-SHORT', 'SIZE', 'SKIP1',
+ 'SKIP2', 'SKIP3', 'SMALL-FONT', 'SORT-CONTROL',
+ 'SORT-CORE-SIZE', 'SORT-FILE-SIZE', 'SORT-MERGE', 'SORT-MESSAGE',
+ 'SORT-MODE-SIZE', 'SORT-OPTION', 'SORT-ORDER', 'SORT-RETURN',
+ 'SORT-TAPE', 'SORT-TAPES', 'SOURCE', 'SOURCE-COMPUTER', 'SOURCES',
+ 'SPACE', 'SPACE-FILL', 'SPACES', 'SPECIAL-NAMES', 'SPINNER', 'SQL',
+ 'SQUARE', 'STANDARD', 'STANDARD-1', 'STANDARD-2', 'STANDARD-3',
+ 'STANDARD-BINARY', 'STANDARD-DECIMAL',
+ 'START-X', 'START-Y', 'STARTING', 'STATEMENT', 'STATIC',
+ 'STATIC-LIST',
+ 'STATUS', 'STATUS-BAR', 'STATUS-TEXT', 'STEP',
+ 'STOP-BROWSER', 'STRONG', 'STYLE', 'SUB-QUEUE-1',
+ 'SUB-QUEUE-2', 'SUB-QUEUE-3', 'SUBFILE', 'SUBWINDOW',
+ 'SUFFIXING', 'SUPER', 'SYMBOL', 'SYMBOLIC',
+ 'SYNCHRONIZED', 'SYSIN', 'SYSIPT', 'SYSLST', 'SYSOUT',
+ 'SYSPCH', 'SYSPUNCH', 'SYSTEM', 'SYSTEM-DEFAULT', 'SYSTEM-INFO',
+ 'TAB', 'TAB-CONTROL', 'TAB-TO-ADD', 'TAB-TO-DELETE', 'TABLE',
+ 'TALLY', 'TALLYING', 'TAPE', 'TAPES', 'TEMPORARY', 'TERMINAL',
+ 'TERMINAL-INFO', 'TERMINATION-VALUE', 'TEST', 'TEXT',
+ 'THAN', 'THEN', 'THREAD', 'THREAD-LOCAL', 'THREAD-LOCAL-STORAGE',
+ 'THREAD-POINTER', 'THROUGH', 'THRU', 'THUMB-POSITION',
+ 'TILED-HEADINGS', 'TIME', 'TIME-OF-DAY', 'TIME-OUT', 'TIME-RECORD',
+ 'TIMEOUT', 'TIMES', 'TIMESTAMP', 'TIMESTAMP-OFFSET',
+ 'TIMESTAMP-OFFSET-RECORD', 'TIMESTAMP-RECORD', 'TITLE', 'TITLE-BAR',
+ 'TITLE-POSITION', 'TO', 'TOOL-BAR', 'TOP', 'TOTALED', 'TOTALING',
+ 'TOWARD-GREATER', 'TOWARD-LESSER',
+ 'TRACE', 'TRACK-AREA', 'TRACK-LIMIT', 'TRACK-THUMB', 'TRACKS',
+ 'TRADITIONAL-FONT', 'TRAILING', 'TRAILING-SHIFT', 'TRAILING-SIGN',
+ 'TRANSACTION', 'TRANSPARENT', 'TRANSPARENT-COLOR',
+ 'TREE-VIEW', 'TRUE', 'TRUNCATION', 'TYPE', 'TYPEDEF', 'UCS-4',
+ 'UNDERLINE', 'UNDERLINED', 'UNEQUAL', 'UNFRAMED', 'UNIT', 'UNITS',
+ 'UNIVERSAL', 'UNSIGNED', 'UNSIGNED-INT', 'UNSIGNED-LONG',
+ 'UNSIGNED-SHORT',
+ 'UNSORTED', 'UP', 'UPDATE', 'UNTIL', 'UPON', 'UPPER',
+ 'UPSI-0', 'UPSI-1', 'UPSI-2', 'UPSI-3', 'UPSI-4', 'UPSI-5',
+ 'UPSI-6', 'UPSI-7', 'USAGE', 'USE-ALT', 'USE-RETURN',
+ 'USE-TAB', 'USER', 'USER-COLORS', 'USER-DEFAULT', 'USER-GRAY',
+ 'USER-WHITE', 'USING', 'UTF-16', 'UTF-8', 'VALID',
+ 'VAL-STATUS', 'VALIDATE-STATUS',
+ 'VALUE', 'VALUE-FORMAT', 'VALUES', 'VALUETYPE', 'VALUETYPE-ID',
+ 'VARBINARY', 'VARIABLE', 'VARIANT', 'VARYING', 'VERTICAL',
+ 'VERY-HEAVY', 'VIRTUAL-WIDTH', 'VISIBLE', 'VPADDING', 'VSCROLL',
+ 'VSCROLL-BAR', 'VSCROLL-POS', 'VTOP', 'WEB-BROWSER', 'WHEN',
+ 'WHERE', 'WIDTH', 'WIDTH-IN-CELLS', 'WINDOW',
+ 'WITH', 'WORDS', 'WORKING-STORAGE', 'WRAP', 'WRITE-ONLY',
+ 'WRITE-VERIFY', 'WRITING', ' XML', 'XML ', 'XML-CODE', 'XML-EVENT',
+ 'XML-NTEXT', 'XML-TEXT', 'YIELDING', 'YYYYDDD', 'YYYYMMDD', 'ZERO',
+ 'ZERO-FILL', 'ZEROES', 'ZEROS'
+ ),
+ 3 => array( // Statement Keywords containing no spaces.
+ 'ACCEPT', 'ADD', 'ALTER', 'ALLOCATE', 'ATTACH', 'CALL', 'CANCEL',
+ 'CHAIN', 'CREATE',
+ 'CLOSE', 'COLOR', 'COMPUTE', 'COMMIT', 'CONTINUE',
+ 'COPY', 'DECLARE', 'DELEGATE', 'DELETE', 'DETACH', 'DISPLAY',
+ 'DIVIDE',
+ 'ENTER', 'ENTRY', 'EVALUATE', 'EXAMINE',
+ 'EXEC', 'EXECUTE', 'EXHIBIT', 'EXIT', 'FREE', 'GOBACK',
+ 'IF', 'INITIALIZE', 'INITIATE', 'INSPECT', 'INVOKE', 'MERGE',
+ 'MODIFY', 'MOVE', 'MULTIPLY', 'NOTE', 'ON', 'OPEN',
+ 'PERFORM', 'RAISE', 'READ', 'RECEIVE', 'RELEASE', 'RETURN',
+ 'RESET', 'RESUME',
+ 'REWRITE', 'ROLLBACK', 'SEARCH', 'SELECT', 'SERVICE', 'SET', 'SORT',
+ 'START', 'STOP', 'STRING', 'SUBTRACT', 'SYNC',
+ 'SUPPRESS', 'TERMINATE',
+ 'TRANSFORM', 'TRY', 'UNLOCKFILE', 'UNLOCK', 'UNSTRING', 'USE',
+ 'VALIDATE', 'WAIT', 'WRITE'
+ ),
+ 4 => array( // Intrinsic functions
+ 'ABS', 'ACOS', 'ANNUITY', 'ASIN', 'ATAN', 'BOOLEAN-OF-INTEGER',
+ 'BYTE-LENGTH', 'CHAR', 'CHAR-NATIONAL',
+ 'COS', 'COMBINED-DATETIME', 'CONCATENATE', 'CURRENT-DATE',
+ 'DATE-OF-INTEGER', 'DATE-TO-YYYYMMDD', 'DAY-TO-YYYYDDD',
+ 'DAY-OF-INTEGER', 'DISPLAY-OF', 'E', 'EXCEPTION-FILE',
+ 'EXCEPTION-FILE-N', 'EXCEPTION-LOCATION',
+ 'EXCEPTION-LOCATION-N', 'EXCEPTION-STATEMENT', 'EXCEPTION-STATUS',
+ 'EXP', 'EXP10', 'FACTORIAL', 'FORMATTED-CURRENT-DATE',
+ 'FORMATTED-DATE', 'FORMATTED-DATETIME', 'FORMATTED-TIME',
+ 'FRACTION-PART', 'HIGHEST-ALGEBRAIC', 'INTEGER',
+ 'INTEGER-OF-BOOLEAN', 'INTEGER-OF-DATE', 'INTEGER-OF-DAY',
+ 'INTEGER-OF-FORMATTED-DATE', 'INTEGER-PART', 'LENGTH',
+ 'LOCALE-COMPARE',
+ 'LOCALE-DATE', 'LOCALE-TIME', 'LOCALE-TIME-FROM-SECONDS',
+ 'LOCALE-TIME-FROM-SECS', 'LOG',
+ 'LOG10', 'LOWER-CASE', 'LOWEST-ALGEBRAIC',
+ 'MAX', 'MEAN', 'MEDIAN', 'MIDRANGE',
+ 'MIN', 'MOD', 'NATIONAL-OF', 'NUMVAL', 'NUMVAL-C', 'NUMVAL-F',
+ 'ORD', 'ORD-MAX', 'ORD-MIN',
+ 'PI', 'PRESENT-VALUE', 'RANDOM', 'RANGE', 'REM', 'REVERSE',
+ 'SECONDS-FROM-FORMATTED-TIME', 'SIGN', 'SIN', 'SQRT',
+ 'SECONDS-PAST-MIDNIGHT', 'STANDARD-DEVIATION', 'STANDARD-COMPARE',
+ 'STORED-CHAR-LENGTH',
+ 'SUBSTITUTE', 'SUBSTITUE-CASE', 'SUM', 'TAN', 'TEST-DATE-YYYYMMDD',
+ 'TEST-DAY-YYYYDDD', 'TEST-FORMATTED-TIME', 'TEST-NUMVAL',
+ 'TEST-NUMVAL-C', 'TEST-NUMVAL-F',
+ 'TRIM', 'UPPER-CASE', 'VARIANCE', 'YEAR-TO-YYYY', 'WHEN-COMPILED'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ // Arithmetic and comparison operators must be surrounded by spaces.
+ ' + ', ' - ', ' * ', ' / ', ' ** ', ' ^ ',
+ '.', ',',
+ ' = ', ' < ', ' > ', ' >= ', ' <= ', ' <> ',
+ '(', ')', '[', ']'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #008000; font-weight: bold;',
+ 3 => 'color: #000000; font-weight: bold;',
+ 4 => 'color: #9d7700;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #a0a0a0; font-style: italic;',
+ 2 => 'color: #000080; font-weight: bold;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #993399;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #800080;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9-\$_\|\#|^&])',
+ ),
+ ),
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/coffeescript.php b/platform/www/vendor/geshi/geshi/src/geshi/coffeescript.php
new file mode 100644
index 0000000..4b5feb2
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/coffeescript.php
@@ -0,0 +1,144 @@
+<?php
+/*************************************************************************************
+ * coffeescript.php
+ * ----------
+ * Author: Trevor Burnham (trevorburnham@gmail.com)
+ * Copyright: (c) 2010 Trevor Burnham (http://iterative.ly)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/06/08
+ *
+ * CoffeeScript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/06/08 (1.0.8.9)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'CoffeeScript',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array('###' => '###'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ //Longest quotemarks ALWAYS first
+ 'QUOTEMARKS' => array('"""', "'''", '"', "'"),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+
+ /*
+ ** Set 1: control keywords
+ */
+ 1 => array(
+ 'break', 'by', 'catch', 'continue', 'else', 'finally', 'for', 'in', 'of', 'if',
+ 'return', 'switch', 'then', 'throw', 'try', 'unless', 'when', 'while', 'until'
+ ),
+
+ /*
+ ** Set 2: logic keywords
+ */
+ 2 => array(
+ 'and', 'or', 'is', 'isnt', 'not'
+ ),
+
+ /*
+ ** Set 3: other keywords
+ */
+ 3 => array(
+ 'instanceof', 'new', 'delete', 'typeof',
+ 'class', 'super', 'this', 'extends'
+ ),
+
+ /*
+ ** Set 4: constants
+ */
+ 4 => array(
+ 'true', 'false', 'on', 'off', 'yes', 'no',
+ 'Infinity', 'NaN', 'undefined', 'null'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '*', '&', '|', '%', '!', ',', ';', '<', '>', '?', '`',
+ '+', '-', '*', '/', '->', '=>', '<<', '>>', '@', ':', '^'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #ff7700;font-weight:bold;',
+ 2 => 'color: #008000;',
+ 3 => 'color: #dc143c;',
+ 4 => 'color: #0000cd;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: black;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #483d8b;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff4500;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: black;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<script type="text/coffeescript">' => '</script>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/cpp-qt.php b/platform/www/vendor/geshi/geshi/src/geshi/cpp-qt.php
new file mode 100644
index 0000000..3d9e55d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/cpp-qt.php
@@ -0,0 +1,622 @@
+<?php
+/*************************************************************************************
+ * cpp.php
+ * -------
+ * Author: Iulian M
+ * Copyright: (c) 2006 Iulian M
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/09/27
+ *
+ * C++ (with Qt extensions) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/06/28 (1.0.8.4)
+ * - Updated list of Keywords from Qt 4.5
+ *
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'C++ (Qt)',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Multiline-continued single-line comments
+ 1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Multiline-continued preprocessor define
+ 2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //C++ 11 string literal extensions
+ 3 => '/(?:L|u8?|U)(?=")/',
+ //C++ 11 string literal extensions (raw)
+ 4 => '/R"([^()\s\\\\]*)\((?:(?!\)\\1").)*\)\\1"/ms'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[abfnrtv\\\'\"?\n]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'case', 'continue', 'default', 'do', 'else', 'for', 'goto', 'if', 'return',
+ 'switch', 'while', 'delete', 'new', 'this'
+ ),
+ 2 => array(
+ 'NULL', 'false', 'break', 'true', 'enum', 'errno', 'EDOM',
+ 'ERANGE', 'FLT_RADIX', 'FLT_ROUNDS', 'FLT_DIG', 'DBL_DIG', 'LDBL_DIG',
+ 'FLT_EPSILON', 'DBL_EPSILON', 'LDBL_EPSILON', 'FLT_MANT_DIG', 'DBL_MANT_DIG',
+ 'LDBL_MANT_DIG', 'FLT_MAX', 'DBL_MAX', 'LDBL_MAX', 'FLT_MAX_EXP', 'DBL_MAX_EXP',
+ 'LDBL_MAX_EXP', 'FLT_MIN', 'DBL_MIN', 'LDBL_MIN', 'FLT_MIN_EXP', 'DBL_MIN_EXP',
+ 'LDBL_MIN_EXP', 'CHAR_BIT', 'CHAR_MAX', 'CHAR_MIN', 'SCHAR_MAX', 'SCHAR_MIN',
+ 'UCHAR_MAX', 'SHRT_MAX', 'SHRT_MIN', 'USHRT_MAX', 'INT_MAX', 'INT_MIN',
+ 'UINT_MAX', 'LONG_MAX', 'LONG_MIN', 'ULONG_MAX', 'HUGE_VAL', 'SIGABRT',
+ 'SIGFPE', 'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_ERR',
+ 'SIG_IGN', 'BUFSIZ', 'EOF', 'FILENAME_MAX', 'FOPEN_MAX', 'L_tmpnam',
+ 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX', 'stdin', 'stdout', 'stderr',
+ 'EXIT_FAILURE', 'EXIT_SUCCESS', 'RAND_MAX', 'CLOCKS_PER_SEC',
+ 'virtual', 'public', 'private', 'protected', 'template', 'using', 'namespace',
+ 'try', 'catch', 'inline', 'dynamic_cast', 'const_cast', 'reinterpret_cast',
+ 'static_cast', 'explicit', 'friend', 'typename', 'typeid', 'class' ,
+ 'foreach','connect', 'Q_OBJECT' , 'slots' , 'signals', 'Q_SIGNALS', 'Q_SLOTS',
+ 'Q_FOREACH', 'QCOMPARE', 'QVERIFY', 'qDebug', 'kDebug', 'QBENCHMARK',
+ 'SIGNAL', 'SLOT', 'emit'
+ ),
+ 3 => array(
+ 'cin', 'cerr', 'clog', 'cout',
+ 'printf', 'fprintf', 'snprintf', 'sprintf', 'assert',
+ 'isalnum', 'isalpha', 'isdigit', 'iscntrl', 'isgraph', 'islower', 'isprint',
+ 'ispunct', 'isspace', 'isupper', 'isxdigit', 'tolower', 'toupper',
+ 'exp', 'log', 'log10', 'pow', 'sqrt', 'ceil', 'floor', 'fabs', 'ldexp',
+ 'frexp', 'modf', 'fmod', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2',
+ 'sinh', 'cosh', 'tanh', 'setjmp', 'longjmp',
+ 'va_start', 'va_arg', 'va_end', 'offsetof', 'sizeof', 'fopen', 'freopen',
+ 'fflush', 'fclose', 'remove', 'rename', 'tmpfile', 'tmpname', 'setvbuf',
+ 'setbuf', 'vfprintf', 'vprintf', 'vsprintf', 'fscanf', 'scanf', 'sscanf',
+ 'fgetc', 'fgets', 'fputc', 'fputs', 'getc', 'getchar', 'gets', 'putc',
+ 'putchar', 'puts', 'ungetc', 'fread', 'fwrite', 'fseek', 'ftell', 'rewind',
+ 'fgetpos', 'fsetpos', 'clearerr', 'feof', 'ferror', 'perror', 'abs', 'labs',
+ 'div', 'ldiv', 'atof', 'atoi', 'atol', 'strtod', 'strtol', 'strtoul', 'calloc',
+ 'malloc', 'realloc', 'free', 'abort', 'exit', 'atexit', 'system', 'getenv',
+ 'bsearch', 'qsort', 'rand', 'srand', 'strcpy', 'strncpy', 'strcat', 'strncat',
+ 'strcmp', 'strncmp', 'strcoll', 'strchr', 'strrchr', 'strspn', 'strcspn',
+ 'strpbrk', 'strstr', 'strlen', 'strerror', 'strtok', 'strxfrm', 'memcpy',
+ 'memmove', 'memcmp', 'memchr', 'memset', 'clock', 'time', 'difftime', 'mktime',
+ 'asctime', 'ctime', 'gmtime', 'localtime', 'strftime'
+ ),
+ 4 => array(
+ 'auto', 'bool', 'char', 'const', 'double', 'float', 'int', 'long', 'longint',
+ 'register', 'short', 'shortint', 'signed', 'static', 'struct',
+ 'typedef', 'union', 'unsigned', 'void', 'volatile', 'extern', 'jmp_buf',
+ 'signal', 'raise', 'va_list', 'ptrdiff_t', 'size_t', 'FILE', 'fpos_t',
+ 'div_t', 'ldiv_t', 'clock_t', 'time_t', 'tm', 'wchar_t',
+
+ 'int8', 'int16', 'int32', 'int64',
+ 'uint8', 'uint16', 'uint32', 'uint64',
+
+ 'int_fast8_t', 'int_fast16_t', 'int_fast32_t', 'int_fast64_t',
+ 'uint_fast8_t', 'uint_fast16_t', 'uint_fast32_t', 'uint_fast64_t',
+
+ 'int_least8_t', 'int_least16_t', 'int_least32_t', 'int_least64_t',
+ 'uint_least8_t', 'uint_least16_t', 'uint_least32_t', 'uint_least64_t',
+
+ 'int8_t', 'int16_t', 'int32_t', 'int64_t',
+ 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t',
+
+ 'intmax_t', 'uintmax_t', 'intptr_t', 'uintptr_t'
+ ),
+ 5 => array(
+ 'Q_INT8', 'Q_INT16', 'Q_INT32', 'Q_INT64', 'Q_LLONG', 'Q_LONG',
+ 'Q_UINT8', 'Q_UINT16', 'Q_UINT32', 'Q_UINT64', 'Q_ULLONG', 'Q_ULONG',
+
+ 'QAbstractAnimation', 'QAbstractButton', 'QAbstractEventDispatcher',
+ 'QAbstractExtensionFactory', 'QAbstractExtensionManager',
+ 'QAbstractFormBuilder', 'QAbstractGraphicsShapeItem',
+ 'QAbstractItemDelegate', 'QAbstractItemModel', 'QAbstractItemView',
+ 'QAbstractListModel', 'QAbstractMessageHandler',
+ 'QAbstractNativeEventFilter', 'QAbstractNetworkCache',
+ 'QAbstractOpenGLFunctions', 'QAbstractPlanarVideoBuffer',
+ 'QAbstractPrintDialog', 'QAbstractProxyModel', 'QAbstractScrollArea',
+ 'QAbstractSlider', 'QAbstractSocket', 'QAbstractSpinBox',
+ 'QAbstractState', 'QAbstractTableModel',
+ 'QAbstractTextDocumentLayout', 'QAbstractTransition',
+ 'QAbstractUriResolver', 'QAbstractVideoBuffer',
+ 'QAbstractVideoSurface', 'QAbstractXmlNodeModel',
+ 'QAbstractXmlReceiver', 'QAccelerometer', 'QAccelerometerFilter',
+ 'QAccelerometerReading', 'QAccessible', 'QAccessibleActionInterface',
+ 'QAccessibleEditableTextInterface', 'QAccessibleEvent',
+ 'QAccessibleInterface', 'QAccessibleObject', 'QAccessiblePlugin',
+ 'QAccessibleStateChangeEvent', 'QAccessibleTableCellInterface',
+ 'QAccessibleTableInterface', 'QAccessibleTableModelChangeEvent',
+ 'QAccessibleTextCursorEvent', 'QAccessibleTextInsertEvent',
+ 'QAccessibleTextInterface', 'QAccessibleTextRemoveEvent',
+ 'QAccessibleTextSelectionEvent', 'QAccessibleTextUpdateEvent',
+ 'QAccessibleValueChangeEvent', 'QAccessibleValueInterface',
+ 'QAccessibleWidget', 'QAction', 'QActionEvent', 'QActionGroup',
+ 'QAltimeter', 'QAltimeterFilter', 'QAltimeterReading',
+ 'QAmbientLightFilter','QAmbientLightReading', 'QAmbientLightSensor',
+ 'QAmbientTemperatureFilter', 'QAmbientTemperatureReading',
+ 'QAmbientTemperatureSensor', 'QAndroidActivityResultReceiver',
+ 'QAndroidJniEnvironment', 'QAndroidJniObject', 'QAnimationGroup',
+ 'QApplication', 'QAssociativeIterable', 'QAtomicInt',
+ 'QAtomicInteger', 'QAtomicPointer', 'QAudioBuffer', 'QAudioDecoder',
+ 'QAudioDecoderControl', 'QAudioDeviceInfo', 'QAudioEncoderSettings',
+ 'QAudioEncoderSettingsControl', 'QAudioFormat', 'QAudioInput',
+ 'QAudioInputSelectorControl', 'QAudioOutput',
+ 'QAudioOutputSelectorControl', 'QAudioProbe', 'QAudioRecorder',
+ 'QAuthenticator', 'QAxAggregated', 'QAxBase', 'QAxBindable',
+ 'QAxFactory', 'QAxObject', 'QAxScript', 'QAxScriptEngine',
+ 'QAxScriptManager', 'QAxSelect', 'QAxWidget', 'QBackingStore',
+ 'QBasicTimer', 'QBitArray', 'QBitmap', 'QBluetoothAddress',
+ 'QBluetoothDeviceDiscoveryAgent', 'QBluetoothDeviceInfo',
+ 'QBluetoothHostInfo', 'QBluetoothLocalDevice', 'QBluetoothServer',
+ 'QBluetoothServiceDiscoveryAgent', 'QBluetoothServiceInfo',
+ 'QBluetoothSocket', 'QBluetoothTransferManager',
+ 'QBluetoothTransferReply', 'QBluetoothTransferRequest',
+ 'QBluetoothUuid', 'QBoxLayout', 'QBrush', 'QBuffer', 'QButtonGroup',
+ 'QByteArray', 'QByteArrayList', 'QByteArrayMatcher', 'QCache',
+ 'QCalendarWidget', 'QCamera', 'QCameraCaptureBufferFormatControl',
+ 'QCameraCaptureDestinationControl', 'QCameraControl',
+ 'QCameraExposure', 'QCameraExposureControl', 'QCameraFeedbackControl',
+ 'QCameraFlashControl', 'QCameraFocus', 'QCameraFocusControl',
+ 'QCameraFocusZone', 'QCameraImageCapture',
+ 'QCameraImageCaptureControl', 'QCameraImageProcessing',
+ 'QCameraImageProcessingControl', 'QCameraInfo', 'QCameraInfoControl',
+ 'QCameraLocksControl', 'QCameraViewfinder',
+ 'QCameraViewfinderSettingsControl', 'QCameraZoomControl', 'QChar',
+ 'QCheckBox', 'QChildEvent', 'QClipboard', 'QCloseEvent',
+ 'QCocoaNativeContext', 'QCollator', 'QCollatorSortKey', 'QColor',
+ 'QColorDialog', 'QColormap', 'QColumnView', 'QComboBox',
+ 'QCommandLineOption', 'QCommandLineParser', 'QCommandLinkButton',
+ 'QCommonStyle', 'QCompass', 'QCompassFilter', 'QCompassReading',
+ 'QCompleter', 'QConicalGradient', 'QContextMenuEvent',
+ 'QContiguousCache', 'QCoreApplication', 'QCryptographicHash',
+ 'QCursor', 'QDBusAbstractAdaptor', 'QDBusAbstractInterface',
+ 'QDBusArgument', 'QDBusConnection', 'QDBusConnectionInterface',
+ 'QDBusContext', 'QDBusError', 'QDBusInterface', 'QDBusMessage',
+ 'QDBusObjectPath', 'QDBusPendingCall', 'QDBusPendingCallWatcher',
+ 'QDBusPendingReply', 'QDBusReply', 'QDBusServer',
+ 'QDBusServiceWatcher', 'QDBusSignature', 'QDBusUnixFileDescriptor',
+ 'QDBusVariant', 'QDBusVirtualObject', 'QDataStream',
+ 'QDataWidgetMapper', 'QDate', 'QDateEdit', 'QDateTime',
+ 'QDateTimeEdit', 'QDebug', 'QDebugStateSaver',
+ 'QDesignerActionEditorInterface', 'QDesignerContainerExtension',
+ 'QDesignerCustomWidgetCollectionInterface',
+ 'QDesignerCustomWidgetInterface',
+ 'QDesignerDynamicPropertySheetExtension',
+ 'QDesignerFormEditorInterface', 'QDesignerFormWindowCursorInterface',
+ 'QDesignerFormWindowInterface', 'QDesignerFormWindowManagerInterface',
+ 'QDesignerMemberSheetExtension', 'QDesignerObjectInspectorInterface',
+ 'QDesignerPropertyEditorInterface', 'QDesignerPropertySheetExtension',
+ 'QDesignerTaskMenuExtension', 'QDesignerWidgetBoxInterface',
+ 'QDesktopServices', 'QDesktopWidget', 'QDial', 'QDialog',
+ 'QDialogButtonBox', 'QDir', 'QDirIterator', 'QDirModel',
+ 'QDistanceFilter', 'QDistanceReading', 'QDistanceSensor',
+ 'QDnsDomainNameRecord', 'QDnsHostAddressRecord', 'QDnsLookup',
+ 'QDnsMailExchangeRecord', 'QDnsServiceRecord', 'QDnsTextRecord',
+ 'QDockWidget', 'QDomAttr', 'QDomCDATASection', 'QDomCharacterData',
+ 'QDomComment', 'QDomDocument', 'QDomDocumentFragment',
+ 'QDomDocumentType', 'QDomElement', 'QDomEntity', 'QDomEntityReference',
+ 'QDomImplementation', 'QDomNamedNodeMap', 'QDomNode', 'QDomNodeList',
+ 'QDomNotation', 'QDomProcessingInstruction', 'QDomText',
+ 'QDoubleSpinBox', 'QDoubleValidator', 'QDrag', 'QDragEnterEvent',
+ 'QDragLeaveEvent', 'QDragMoveEvent', 'QDropEvent',
+ 'QDynamicPropertyChangeEvent', 'EnginioClient',
+ 'EnginioClientConnection', 'EnginioIdentity', 'EnginioModel',
+ 'EnginioOAuth2Authentication', 'EnginioReply', 'QEGLNativeContext',
+ 'QEasingCurve', 'QEglFSFunctions', 'QElapsedTimer',
+ 'QEnableSharedFromThis', 'QEnterEvent', 'QErrorMessage', 'QEvent',
+ 'QEventLoop', 'QEventLoopLocker', 'QEventTransition', 'QException',
+ 'QExplicitlySharedDataPointer', 'QExposeEvent', 'QExtensionFactory',
+ 'QExtensionManager', 'QFile', 'QFileDevice', 'QFileDialog',
+ 'QFileIconProvider', 'QFileInfo', 'QFileOpenEvent', 'QFileSelector',
+ 'QFileSystemModel', 'QFileSystemWatcher', 'QFinalState', 'QFlag',
+ 'QFlags', 'QFocusEvent', 'QFocusFrame', 'QFont', 'QFontComboBox',
+ 'QFontDatabase', 'QFontDialog', 'QFontInfo', 'QFontMetrics',
+ 'QFontMetricsF', 'QFormBuilder', 'QFormLayout', 'QFrame', 'QFuture',
+ 'QFutureIterator', 'QFutureSynchronizer', 'QFutureWatcher',
+ 'QGLBuffer', 'QGLColormap', 'QGLContext', 'QGLFormat',
+ 'QGLFramebufferObject', 'QGLFramebufferObjectFormat', 'QGLFunctions',
+ 'QGLPixelBuffer', 'QGLShader', 'QGLShaderProgram', 'QGLWidget',
+ 'QGLXNativeContext', 'QGenericArgument', 'QGenericMatrix',
+ 'QGenericPlugin', 'QGenericPluginFactory', 'QGenericReturnArgument',
+ 'QGeoAddress', 'QGeoAreaMonitorInfo', 'QGeoAreaMonitorSource',
+ 'QGeoCircle', 'QGeoCodeReply', 'QGeoCodingManager',
+ 'QGeoCodingManagerEngine', 'QGeoCoordinate', 'QGeoLocation',
+ 'QGeoManeuver', 'QGeoPositionInfo', 'QGeoPositionInfoSource',
+ 'QGeoPositionInfoSourceFactory', 'QGeoRectangle', 'QGeoRoute',
+ 'QGeoRouteReply', 'QGeoRouteRequest', 'QGeoRouteSegment',
+ 'QGeoRoutingManager', 'QGeoRoutingManagerEngine',
+ 'QGeoSatelliteInfo', 'QGeoSatelliteInfoSource',
+ 'QGeoServiceProvider', 'QGeoServiceProviderFactory', 'QGeoShape',
+ 'QGesture', 'QGestureEvent', 'QGestureRecognizer', 'QGlobalStatic',
+ 'QGlyphRun', 'QGradient', 'QGraphicsAnchor', 'QGraphicsAnchorLayout',
+ 'QGraphicsBlurEffect', 'QGraphicsColorizeEffect',
+ 'QGraphicsDropShadowEffect', 'QGraphicsEffect',
+ 'QGraphicsEllipseItem', 'QGraphicsGridLayout', 'QGraphicsItem',
+ 'QGraphicsItemAnimation', 'QGraphicsItemGroup', 'QGraphicsLayout',
+ 'QGraphicsLayoutItem', 'QGraphicsLineItem', 'QGraphicsLinearLayout',
+ 'QGraphicsObject', 'QGraphicsOpacityEffect', 'QGraphicsPathItem',
+ 'QGraphicsPixmapItem', 'QGraphicsPolygonItem',
+ 'QGraphicsProxyWidget', 'QGraphicsRectItem', 'QGraphicsRotation',
+ 'QGraphicsScale', 'QGraphicsScene', 'QGraphicsSceneContextMenuEvent',
+ 'QGraphicsSceneDragDropEvent', 'QGraphicsSceneEvent',
+ 'QGraphicsSceneHelpEvent', 'QGraphicsSceneHoverEvent',
+ 'QGraphicsSceneMouseEvent', 'QGraphicsSceneMoveEvent',
+ 'QGraphicsSceneResizeEvent', 'QGraphicsSceneWheelEvent',
+ 'QGraphicsSimpleTextItem', 'QGraphicsSvgItem', 'QGraphicsTextItem',
+ 'QGraphicsTransform', 'QGraphicsVideoItem', 'QGraphicsView',
+ 'QGraphicsWebView', 'QGraphicsWidget', 'QGridLayout', 'QGroupBox',
+ 'QGuiApplication', 'QGyroscope', 'QGyroscopeFilter',
+ 'QGyroscopeReading', 'QHBoxLayout', 'QHash', 'QHashIterator',
+ 'QHeaderView', 'QHelpContentItem', 'QHelpContentModel',
+ 'QHelpContentWidget', 'QHelpEngine', 'QHelpEngineCore', 'QHelpEvent',
+ 'QHelpIndexModel', 'QHelpIndexWidget', 'QHelpSearchEngine',
+ 'QHelpSearchQuery', 'QHelpSearchQueryWidget',
+ 'QHelpSearchResultWidget', 'QHideEvent', 'QHistoryState',
+ 'QHolsterFilter', 'QHolsterReading', 'QHolsterSensor',
+ 'QHostAddress', 'QHostInfo', 'QHoverEvent', 'QHttpMultiPart',
+ 'QHttpPart', 'QIODevice', 'QIRProximityFilter', 'QIRProximityReading',
+ 'QIRProximitySensor', 'QIcon', 'QIconDragEvent', 'QIconEngine',
+ 'QIconEnginePlugin', 'QIdentityProxyModel', 'QImage',
+ 'QImageEncoderControl', 'QImageEncoderSettings', 'QImageIOHandler',
+ 'QImageIOPlugin', 'QImageReader', 'QImageWriter', 'QInputDialog',
+ 'QInputEvent', 'QInputMethod', 'QInputMethodEvent',
+ 'QInputMethodQueryEvent', 'QIntValidator', 'QItemDelegate',
+ 'QItemEditorCreator', 'QItemEditorCreatorBase', 'QItemEditorFactory',
+ 'QItemSelection', 'QItemSelectionModel', 'QItemSelectionRange',
+ 'QJSEngine', 'QJSValue', 'QJSValueIterator', 'QJsonArray',
+ 'QJsonDocument', 'QJsonObject', 'QJsonParseError', 'QJsonValue',
+ 'QKeyEvent', 'QKeyEventTransition', 'QKeySequence', 'QKeySequenceEdit',
+ 'QLCDNumber', 'QLabel', 'QLatin1Char', 'QLatin1String', 'QLayout',
+ 'QLayoutItem', 'QLibrary', 'QLibraryInfo', 'QLightFilter',
+ 'QLightReading', 'QLightSensor', 'QLine', 'QLineEdit', 'QLineF',
+ 'QLinearGradient', 'QLinkedList', 'QLinkedListIterator', 'QList',
+ 'QListIterator', 'QListView', 'QListWidget', 'QListWidgetItem',
+ 'QLocalServer', 'QLocalSocket', 'QLocale', 'QLockFile',
+ 'QLoggingCategory', 'QLowEnergyCharacteristic',
+ 'QLowEnergyController', 'QLowEnergyDescriptor', 'QLowEnergyService',
+ 'QMacCocoaViewContainer', 'QMacNativeWidget', 'QMacPasteboardMime',
+ 'QMacToolBar', 'QMacToolBarItem', 'QMagnetometer',
+ 'QMagnetometerFilter', 'QMagnetometerReading', 'QMainWindow', 'QMap',
+ 'QMapIterator', 'QMargins', 'QMarginsF', 'QMaskGenerator', 'QMatrix',
+ 'QMatrix4x4', 'QMdiArea', 'QMdiSubWindow', 'QMediaAudioProbeControl',
+ 'QMediaAvailabilityControl', 'QMediaBindableInterface',
+ 'QMediaContainerControl', 'QMediaContent', 'QMediaControl',
+ 'QMediaGaplessPlaybackControl', 'QMediaNetworkAccessControl',
+ 'QMediaObject', 'QMediaPlayer', 'QMediaPlayerControl',
+ 'QMediaPlaylist', 'QMediaRecorder', 'QMediaRecorderControl',
+ 'QMediaResource', 'QMediaService', 'QMediaServiceCameraInfoInterface',
+ 'QMediaServiceFeaturesInterface', 'QMediaServiceProviderPlugin',
+ 'QMediaServiceSupportedDevicesInterface',
+ 'QMediaServiceSupportedFormatsInterface', 'QMediaStreamsControl',
+ 'QMediaTimeInterval', 'QMediaTimeRange', 'QMediaVideoProbeControl',
+ 'QMenu', 'QMenuBar', 'QMessageAuthenticationCode', 'QMessageBox',
+ 'QMessageLogContext', 'QMessageLogger', 'QMetaClassInfo',
+ 'QMetaDataReaderControl', 'QMetaDataWriterControl', 'QMetaEnum',
+ 'QMetaMethod', 'QMetaObject', 'QMetaProperty', 'QMetaType',
+ 'QMimeData', 'QMimeDatabase', 'QMimeType', 'QModelIndex',
+ 'QMouseEvent', 'QMouseEventTransition', 'QMoveEvent', 'QMovie',
+ 'QMultiHash', 'QMultiMap', 'QMutableHashIterator',
+ 'QMutableLinkedListIterator', 'QMutableListIterator',
+ 'QMutableMapIterator', 'QMutableSetIterator',
+ 'QMutableVectorIterator', 'QMutex', 'QMutexLocker',
+ 'QNativeGestureEvent', 'QNdefFilter', 'QNdefMessage',
+ 'QNdefNfcSmartPosterRecord', 'QNdefNfcTextRecord',
+ 'QNdefNfcUriRecord', 'QNdefRecord', 'QNearFieldManager',
+ 'QNearFieldShareManager', 'QNearFieldShareTarget', 'QNearFieldTarget',
+ 'QNetworkAccessManager', 'QNetworkAddressEntry',
+ 'QNetworkCacheMetaData', 'QNetworkConfiguration',
+ 'QNetworkConfigurationManager', 'QNetworkCookie', 'QNetworkCookieJar',
+ 'QNetworkDiskCache', 'QNetworkInterface', 'QNetworkProxy',
+ 'QNetworkProxyFactory', 'QNetworkProxyQuery', 'QNetworkReply',
+ 'QNetworkRequest', 'QNetworkSession', 'QNmeaPositionInfoSource',
+ 'QObject', 'QObjectCleanupHandler', 'QOffscreenSurface',
+ 'QOpenGLBuffer', 'QOpenGLContext', 'QOpenGLContextGroup',
+ 'QOpenGLDebugLogger', 'QOpenGLDebugMessage',
+ 'QOpenGLFramebufferObject', 'QOpenGLFramebufferObjectFormat',
+ 'QOpenGLFunctions', 'QOpenGLFunctions_1_0', 'QOpenGLFunctions_1_1',
+ 'QOpenGLFunctions_1_2', 'QOpenGLFunctions_1_3', 'QOpenGLFunctions_1_4',
+ 'QOpenGLFunctions_1_5', 'QOpenGLFunctions_2_0', 'QOpenGLFunctions_2_1',
+ 'QOpenGLFunctions_3_0', 'QOpenGLFunctions_3_1',
+ 'QOpenGLFunctions_3_2_Compatibility', 'QOpenGLFunctions_3_2_Core',
+ 'QOpenGLFunctions_3_3_Compatibility', 'QOpenGLFunctions_3_3_Core',
+ 'QOpenGLFunctions_4_0_Compatibility', 'QOpenGLFunctions_4_0_Core',
+ 'QOpenGLFunctions_4_1_Compatibility', 'QOpenGLFunctions_4_1_Core',
+ 'QOpenGLFunctions_4_2_Compatibility', 'QOpenGLFunctions_4_2_Core',
+ 'QOpenGLFunctions_4_3_Compatibility', 'QOpenGLFunctions_4_3_Core',
+ 'QOpenGLFunctions_ES2', 'QOpenGLPaintDevice',
+ 'QOpenGLPixelTransferOptions', 'QOpenGLShader',
+ 'QOpenGLShaderProgram', 'QOpenGLTexture', 'QOpenGLTimeMonitor',
+ 'QOpenGLTimerQuery', 'QOpenGLVersionProfile',
+ 'QOpenGLVertexArrayObject', 'QOpenGLWidget', 'QOpenGLWindow',
+ 'QOrientationFilter', 'QOrientationReading', 'QOrientationSensor',
+ 'QPageLayout', 'QPageSetupDialog', 'QPageSize', 'QPagedPaintDevice',
+ 'QPaintDevice', 'QPaintDeviceWindow', 'QPaintEngine',
+ 'QPaintEngineState', 'QPaintEvent', 'QPainter', 'QPainterPath',
+ 'QPainterPathStroker', 'QPair', 'QPalette', 'QPanGesture',
+ 'QParallelAnimationGroup', 'QPauseAnimation', 'QPdfWriter', 'QPen',
+ 'QPersistentModelIndex', 'QPicture', 'QPictureFormatPlugin',
+ 'QPictureIO', 'QPinchGesture', 'QPixelFormat', 'QPixmap',
+ 'QPixmapCache', 'QPlace', 'QPlaceAttribute', 'QPlaceCategory',
+ 'QPlaceContactDetail', 'QPlaceContent', 'QPlaceContentReply',
+ 'QPlaceContentRequest', 'QPlaceDetailsReply', 'QPlaceEditorial',
+ 'QPlaceIcon', 'QPlaceIdReply', 'QPlaceImage', 'QPlaceManager',
+ 'QPlaceManagerEngine', 'QPlaceMatchReply', 'QPlaceMatchRequest',
+ 'QPlaceProposedSearchResult', 'QPlaceRatings', 'QPlaceReply',
+ 'QPlaceResult', 'QPlaceReview', 'QPlaceSearchReply',
+ 'QPlaceSearchRequest', 'QPlaceSearchResult',
+ 'QPlaceSearchSuggestionReply', 'QPlaceSupplier', 'QPlaceUser',
+ 'QPlainTextDocumentLayout', 'QPlainTextEdit',
+ 'QPlatformSystemTrayIcon', 'QPluginLoader', 'QPoint', 'QPointF',
+ 'QPointer', 'QPolygon', 'QPolygonF', 'QPressureFilter',
+ 'QPressureReading', 'QPressureSensor', 'QPrintDialog', 'QPrintEngine',
+ 'QPrintPreviewDialog', 'QPrintPreviewWidget', 'QPrinter',
+ 'QPrinterInfo', 'QProcess', 'QProcessEnvironment', 'QProgressBar',
+ 'QProgressDialog', 'QPropertyAnimation', 'QProximityFilter',
+ 'QProximityReading', 'QProximitySensor', 'QProxyStyle',
+ 'QPushButton', 'QQmlAbstractProfilerAdapter',
+ 'QQmlAbstractUrlInterceptor', 'QQmlApplicationEngine',
+ 'QQmlComponent', 'QQmlContext', 'QQmlEngine', 'QQmlError',
+ 'QQmlExpression', 'QQmlExtensionPlugin', 'QQmlFileSelector',
+ 'QQmlImageProviderBase', 'QQmlIncubationController', 'QQmlIncubator',
+ 'QQmlListProperty', 'QQmlListReference', 'QQmlNdefRecord',
+ 'QQmlNetworkAccessManagerFactory', 'QQmlParserStatus', 'QQmlProperty',
+ 'QQmlPropertyMap', 'QQmlPropertyValueSource', 'QQmlScriptString',
+ 'QQuaternion', 'QQueue', 'QQuickFramebufferObject', 'QQuickImageProvider',
+ 'QQuickItem', 'QQuickItemGrabResult', 'QQuickPaintedItem',
+ 'QQuickRenderControl', 'QQuickTextDocument', 'QQuickTextureFactory',
+ 'QQuickView', 'QQuickWidget', 'QQuickWindow', 'QTouchEventSequence',
+ 'Qoutputrange', 'QRadialGradient', 'QRadioButton', 'QRadioData',
+ 'QRadioDataControl', 'QRadioTuner', 'QRadioTunerControl',
+ 'QRasterPaintEngine', 'QRasterWindow', 'QRawFont', 'QReadLocker',
+ 'QReadWriteLock', 'QRect', 'QRectF', 'QRegExp', 'QRegExpValidator',
+ 'QRegion', 'QRegularExpression', 'QRegularExpressionMatch',
+ 'QRegularExpressionMatchIterator', 'QRegularExpressionValidator',
+ 'QResizeEvent', 'QResource', 'QRotationFilter', 'QRotationReading',
+ 'QRotationSensor', 'QRubberBand', 'QRunnable', 'QSGAbstractRenderer',
+ 'QSGBasicGeometryNode', 'QSGClipNode', 'QSGDynamicTexture',
+ 'QSGEngine', 'QSGFlatColorMaterial', 'QSGGeometry', 'QSGGeometryNode',
+ 'QSGMaterial', 'QSGMaterialShader', 'QSGMaterialType', 'QSGNode',
+ 'QSGOpacityNode', 'QSGOpaqueTextureMaterial', 'QSGSimpleMaterial',
+ 'QSGSimpleMaterialShader', 'QSGSimpleRectNode',
+ 'QSGSimpleTextureNode', 'QSGTexture', 'QSGTextureMaterial',
+ 'QSGTextureProvider', 'QSGTransformNode', 'QSGVertexColorMaterial',
+ 'QSaveFile', 'QScopedArrayPointer', 'QScopedPointer',
+ 'QScopedValueRollback', 'QScreen', 'QScriptClass',
+ 'QScriptClassPropertyIterator', 'QScriptContext',
+ 'QScriptContextInfo', 'QScriptEngine', 'QScriptEngineAgent',
+ 'QScriptEngineDebugger', 'QScriptExtensionPlugin', 'QScriptProgram',
+ 'QScriptString', 'QScriptSyntaxCheckResult', 'QScriptValue',
+ 'QScriptValueIterator', 'QScriptable', 'QScrollArea', 'QScrollBar',
+ 'QScrollEvent', 'QScrollPrepareEvent', 'QScroller',
+ 'QScrollerProperties', 'QSemaphore', 'QSensor', 'QSensorBackend',
+ 'QSensorBackendFactory', 'QSensorChangesInterface', 'QSensorFilter',
+ 'QSensorGesture', 'QSensorGestureManager',
+ 'QSensorGesturePluginInterface', 'QSensorGestureRecognizer',
+ 'QSensorManager', 'QSensorPluginInterface', 'QSensorReading',
+ 'QSequentialAnimationGroup', 'QSequentialIterable', 'QSerialPort',
+ 'QSerialPortInfo', 'QSessionManager', 'QSet', 'QSetIterator',
+ 'QSettings', 'QSharedData', 'QSharedDataPointer', 'QSharedMemory',
+ 'QSharedPointer', 'QShortcut', 'QShortcutEvent', 'QShowEvent',
+ 'QSignalBlocker', 'QSignalMapper', 'QSignalSpy', 'QSignalTransition',
+ 'QSimpleXmlNodeModel', 'QSize', 'QSizeF', 'QSizeGrip', 'QSizePolicy',
+ 'QSlider', 'QSocketNotifier', 'QSortFilterProxyModel', 'QSound',
+ 'QSoundEffect', 'QSourceLocation', 'QSpacerItem', 'QSpinBox',
+ 'QSplashScreen', 'QSplitter', 'QSplitterHandle', 'QSqlDatabase',
+ 'QSqlDriver', 'QSqlDriverCreator', 'QSqlDriverCreatorBase',
+ 'QSqlDriverPlugin', 'QSqlError', 'QSqlField', 'QSqlIndex',
+ 'QSqlQuery', 'QSqlQueryModel', 'QSqlRecord', 'QSqlRelation',
+ 'QSqlRelationalDelegate', 'QSqlRelationalTableModel', 'QSqlResult',
+ 'QSqlTableModel', 'QSslCertificate', 'QSslCertificateExtension',
+ 'QSslCipher', 'QSslConfiguration', 'QSslError', 'QSslKey',
+ 'QSslSocket', 'QStack', 'QStackedLayout', 'QStackedWidget',
+ 'QStandardItem', 'QStandardItemEditorCreator', 'QStandardItemModel',
+ 'QStandardPaths', 'QState', 'QStateMachine', 'QStaticPlugin',
+ 'QStaticText', 'QStatusBar', 'QStatusTipEvent', 'QStorageInfo',
+ 'QString', 'QStringList', 'QStringListModel', 'QStringMatcher',
+ 'QStringRef', 'QStyle', 'QStyleFactory', 'QStyleHintReturn',
+ 'QStyleHintReturnMask', 'QStyleHintReturnVariant', 'QStyleHints',
+ 'QStyleOption', 'QStyleOptionButton', 'QStyleOptionComboBox',
+ 'QStyleOptionComplex', 'QStyleOptionDockWidget',
+ 'QStyleOptionFocusRect', 'QStyleOptionFrame',
+ 'QStyleOptionGraphicsItem', 'QStyleOptionGroupBox',
+ 'QStyleOptionHeader', 'QStyleOptionMenuItem',
+ 'QStyleOptionProgressBar', 'QStyleOptionRubberBand',
+ 'QStyleOptionSizeGrip', 'QStyleOptionSlider',
+ 'QStyleOptionSpinBox', 'QStyleOptionTab',
+ 'QStyleOptionTabBarBase', 'QStyleOptionTabWidgetFrame',
+ 'QStyleOptionTitleBar', 'QStyleOptionToolBar',
+ 'QStyleOptionToolBox', 'QStyleOptionToolButton',
+ 'QStyleOptionViewItem', 'QStylePainter', 'QStylePlugin',
+ 'QStyledItemDelegate', 'QSupportedWritingSystems', 'QSurface',
+ 'QSurfaceFormat', 'QSvgGenerator', 'QSvgRenderer', 'QSvgWidget',
+ 'QSwipeGesture', 'QSyntaxHighlighter', 'QSysInfo', 'QSystemSemaphore',
+ 'QSystemTrayIcon', 'QTabBar', 'QTabWidget', 'QTableView',
+ 'QTableWidget', 'QTableWidgetItem', 'QTableWidgetSelectionRange',
+ 'QTabletEvent', 'QTapAndHoldGesture', 'QTapFilter', 'QTapGesture',
+ 'QTapReading', 'QTapSensor', 'QTcpServer', 'QTcpSocket',
+ 'QTemporaryDir', 'QTemporaryFile', 'QTestEventList', 'QTextBlock',
+ 'QTextBlockFormat', 'QTextBlockGroup', 'QTextBlockUserData',
+ 'QTextBoundaryFinder', 'QTextBrowser', 'QTextCharFormat',
+ 'QTextCodec', 'QTextCursor', 'QTextDecoder', 'QTextDocument',
+ 'QTextDocumentFragment', 'QTextDocumentWriter', 'QTextEdit',
+ 'QTextEncoder', 'QTextFormat', 'QTextFragment', 'QTextFrame',
+ 'QTextFrameFormat', 'QTextImageFormat', 'QTextInlineObject',
+ 'QTextItem', 'QTextLayout', 'QTextLength', 'QTextLine', 'QTextList',
+ 'QTextListFormat', 'QTextObject', 'QTextObjectInterface',
+ 'QTextOption', 'QTextStream', 'QTextTable', 'QTextTableCell',
+ 'QTextTableCellFormat', 'QTextTableFormat', 'QThread', 'QThreadPool',
+ 'QThreadStorage', 'QTileRules', 'QTiltFilter', 'QTiltReading',
+ 'QTiltSensor', 'QTime', 'QTimeEdit', 'QTimeLine', 'QTimeZone',
+ 'QTimer', 'QTimerEvent', 'QToolBar', 'QToolBox', 'QToolButton',
+ 'QToolTip', 'QTouchDevice', 'QTouchEvent', 'QTransform',
+ 'QTranslator', 'QTreeView', 'QTreeWidget', 'QTreeWidgetItem',
+ 'QTreeWidgetItemIterator', 'QUdpSocket', 'QUiLoader', 'QUndoCommand',
+ 'QUndoGroup', 'QUndoStack', 'QUndoView', 'QUnhandledException',
+ 'QUrl', 'QUrlQuery', 'QUuid', 'QVBoxLayout', 'QValidator',
+ 'QVarLengthArray', 'QVariant', 'QVariantAnimation', 'QVector',
+ 'QVector2D', 'QVector3D', 'QVector4D', 'QVectorIterator',
+ 'QVideoDeviceSelectorControl', 'QVideoEncoderSettings',
+ 'QVideoEncoderSettingsControl', 'QVideoFrame', 'QVideoProbe',
+ 'QVideoRendererControl', 'QVideoSurfaceFormat', 'QVideoWidget',
+ 'QVideoWidgetControl', 'QVideoWindowControl', 'QWGLNativeContext',
+ 'QWaitCondition', 'QWeakPointer', 'QWebChannel',
+ 'QWebChannelAbstractTransport', 'QWebDatabase', 'QWebElement',
+ 'QWebElementCollection', 'QWebEngineHistory', 'QWebEngineHistoryItem',
+ 'QWebEnginePage', 'QWebEngineSettings', 'QWebEngineView', 'QWebFrame',
+ 'QWebHistory', 'QWebHistoryInterface', 'QWebHistoryItem',
+ 'QWebHitTestResult', 'QWebInspector', 'QWebPage', 'QWebPluginFactory',
+ 'QWebSecurityOrigin', 'QWebSettings', 'QWebSocket',
+ 'QWebSocketCorsAuthenticator', 'QWebSocketServer', 'QWebView',
+ 'QWhatsThis', 'QWhatsThisClickedEvent', 'QWheelEvent', 'QWidget',
+ 'QWidgetAction', 'QWidgetItem', 'QWinEventNotifier', 'QWinJumpList',
+ 'QWinJumpListCategory', 'QWinJumpListItem', 'QWinMime',
+ 'QWinTaskbarButton', 'QWinTaskbarProgress', 'QWinThumbnailToolBar',
+ 'QWinThumbnailToolButton', 'QWindow', 'QWindowStateChangeEvent',
+ 'QWizard', 'QWizardPage', 'QWriteLocker', 'QX11Info',
+ 'QXcbWindowFunctions', 'QXmlAttributes', 'QXmlContentHandler',
+ 'QXmlDTDHandler', 'QXmlDeclHandler', 'QXmlDefaultHandler',
+ 'QXmlEntityResolver','QXmlErrorHandler', 'QXmlFormatter',
+ 'QXmlInputSource', 'QXmlItem', 'QXmlLexicalHandler', 'QXmlLocator',
+ 'QXmlName', 'QXmlNamePool', 'QXmlNamespaceSupport',
+ 'QXmlNodeModelIndex', 'QXmlParseException', 'QXmlQuery',
+ 'QXmlReader', 'QXmlResultItems', 'QXmlSchema', 'QXmlSchemaValidator',
+ 'QXmlSerializer', 'QXmlSimpleReader', 'QXmlStreamAttribute',
+ 'QXmlStreamAttributes', 'QXmlStreamEntityDeclaration',
+ 'QXmlStreamEntityResolver', 'QXmlStreamNamespaceDeclaration',
+ 'QXmlStreamNotationDeclaration', 'QXmlStreamReader',
+ 'QXmlStreamWriter'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':', ',', ';', '|', '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight:bold;',
+ 2 => 'color: #0057AE;',
+ 3 => 'color: #2B74C7;',
+ 4 => 'color: #0057AE;',
+ 5 => 'color: #22aadd;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #888888;',
+ 2 => 'color: #006E28;',
+ 3 => 'color: #BF0303;',
+ 4 => 'color: #BF0303;',
+ 'MULTI' => 'color: #888888; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #006E28;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #BF0303;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #B08000;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #2B74C7;',
+ 2 => 'color: #2B74C7;',
+ 3 => 'color: #2B74C7;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #006E28;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => 'http://qt-project.org/doc/latest/{FNAMEL}.html'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::',
+ 3 => '-&gt;',
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#>|^])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%\\-])"
+ ),
+ 'OOLANG' => array(
+ 'MATCH_AFTER' => '~?[a-zA-Z][a-zA-Z0-9_]*',
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/cpp-winapi.php b/platform/www/vendor/geshi/geshi/src/geshi/cpp-winapi.php
new file mode 100644
index 0000000..662e4c4
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/cpp-winapi.php
@@ -0,0 +1,836 @@
+<?php
+/*************************************************************************************
+ * cpp-winapi.php
+ * -------
+ * Author: Dennis Bayer (Dennis.Bayer@mnifh-giessen.de)
+ * Contributors:
+ * - M. Uli Kusterer (witness.of.teachtext@gmx.net)
+ * - Jack Lloyd (lloyd@randombit.net)
+ * - Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2004 Dennis Bayer, Nigel McNie, 2012 Benny Baumann (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/09/27
+ *
+ * C++ language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/XX/XX (1.0.2)
+ * - Added several new keywords (Jack Lloyd)
+ * 2004/11/27 (1.0.1)
+ * - Added StdCLib function and constant names, changed color scheme to
+ * a cleaner one. (M. Uli Kusterer)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'C++ (WinAPI)',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Multiline-continued single-line comments
+ 1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Multiline-continued preprocessor define
+ 2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //C++ 11 string literal extensions
+ 3 => '/(?:L|u8?|U)(?=")/',
+ //C++ 11 string literal extensions (raw)
+ 4 => '/R"([^()\s\\\\]*)\((?:(?!\)\\1").)*\)\\1"/ms'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[abfnrtv\\\'\"?\n]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'break', 'case', 'continue', 'default', 'do', 'else', 'for', 'goto', 'if', 'return',
+ 'switch', 'throw', 'while'
+ ),
+ 2 => array(
+ 'NULL', 'false', 'true', 'enum', 'errno', 'EDOM',
+ 'ERANGE', 'FLT_RADIX', 'FLT_ROUNDS', 'FLT_DIG', 'DBL_DIG', 'LDBL_DIG',
+ 'FLT_EPSILON', 'DBL_EPSILON', 'LDBL_EPSILON', 'FLT_MANT_DIG', 'DBL_MANT_DIG',
+ 'LDBL_MANT_DIG', 'FLT_MAX', 'DBL_MAX', 'LDBL_MAX', 'FLT_MAX_EXP', 'DBL_MAX_EXP',
+ 'LDBL_MAX_EXP', 'FLT_MIN', 'DBL_MIN', 'LDBL_MIN', 'FLT_MIN_EXP', 'DBL_MIN_EXP',
+ 'LDBL_MIN_EXP', 'CHAR_BIT', 'CHAR_MAX', 'CHAR_MIN', 'SCHAR_MAX', 'SCHAR_MIN',
+ 'UCHAR_MAX', 'SHRT_MAX', 'SHRT_MIN', 'USHRT_MAX', 'INT_MAX', 'INT_MIN',
+ 'UINT_MAX', 'LONG_MAX', 'LONG_MIN', 'ULONG_MAX', 'HUGE_VAL', 'SIGABRT',
+ 'SIGFPE', 'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_ERR',
+ 'SIG_IGN', 'BUFSIZ', 'EOF', 'FILENAME_MAX', 'FOPEN_MAX', 'L_tmpnam',
+ 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX', 'stdin', 'stdout', 'stderr',
+ 'EXIT_FAILURE', 'EXIT_SUCCESS', 'RAND_MAX', 'CLOCKS_PER_SEC',
+ 'virtual', 'public', 'private', 'protected', 'template', 'using', 'namespace',
+ 'try', 'catch', 'inline', 'dynamic_cast', 'const_cast', 'reinterpret_cast',
+ 'static_cast', 'explicit', 'friend', 'typename', 'typeid', 'class'
+ ),
+ 3 => array(
+ 'cin', 'cerr', 'clog', 'cout', 'delete', 'new', 'this',
+ 'printf', 'fprintf', 'snprintf', 'sprintf', 'assert',
+ 'isalnum', 'isalpha', 'isdigit', 'iscntrl', 'isgraph', 'islower', 'isprint',
+ 'ispunct', 'isspace', 'isupper', 'isxdigit', 'tolower', 'toupper',
+ 'exp', 'log', 'log10', 'pow', 'sqrt', 'ceil', 'floor', 'fabs', 'ldexp',
+ 'frexp', 'modf', 'fmod', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2',
+ 'sinh', 'cosh', 'tanh', 'setjmp', 'longjmp',
+ 'va_start', 'va_arg', 'va_end', 'offsetof', 'sizeof', 'fopen', 'freopen',
+ 'fflush', 'fclose', 'remove', 'rename', 'tmpfile', 'tmpname', 'setvbuf',
+ 'setbuf', 'vfprintf', 'vprintf', 'vsprintf', 'fscanf', 'scanf', 'sscanf',
+ 'fgetc', 'fgets', 'fputc', 'fputs', 'getc', 'getchar', 'gets', 'putc',
+ 'putchar', 'puts', 'ungetc', 'fread', 'fwrite', 'fseek', 'ftell', 'rewind',
+ 'fgetpos', 'fsetpos', 'clearerr', 'feof', 'ferror', 'perror', 'abs', 'labs',
+ 'div', 'ldiv', 'atof', 'atoi', 'atol', 'strtod', 'strtol', 'strtoul', 'calloc',
+ 'malloc', 'realloc', 'free', 'abort', 'exit', 'atexit', 'system', 'getenv',
+ 'bsearch', 'qsort', 'rand', 'srand', 'strcpy', 'strncpy', 'strcat', 'strncat',
+ 'strcmp', 'strncmp', 'strcoll', 'strchr', 'strrchr', 'strspn', 'strcspn',
+ 'strpbrk', 'strstr', 'strlen', 'strerror', 'strtok', 'strxfrm', 'memcpy',
+ 'memmove', 'memcmp', 'memchr', 'memset', 'clock', 'time', 'difftime', 'mktime',
+ 'asctime', 'ctime', 'gmtime', 'localtime', 'strftime'
+ ),
+ 4 => array(
+ 'auto', 'bool', 'char', 'const', 'double', 'float', 'int', 'long', 'longint',
+ 'register', 'short', 'shortint', 'signed', 'static', 'struct',
+ 'typedef', 'union', 'unsigned', 'void', 'volatile', 'extern', 'jmp_buf',
+ 'signal', 'raise', 'va_list', 'ptrdiff_t', 'size_t', 'FILE', 'fpos_t',
+ 'div_t', 'ldiv_t', 'clock_t', 'time_t', 'tm', 'wchar_t',
+
+ 'int8', 'int16', 'int32', 'int64',
+ 'uint8', 'uint16', 'uint32', 'uint64',
+
+ 'int_fast8_t', 'int_fast16_t', 'int_fast32_t', 'int_fast64_t',
+ 'uint_fast8_t', 'uint_fast16_t', 'uint_fast32_t', 'uint_fast64_t',
+
+ 'int_least8_t', 'int_least16_t', 'int_least32_t', 'int_least64_t',
+ 'uint_least8_t', 'uint_least16_t', 'uint_least32_t', 'uint_least64_t',
+
+ 'int8_t', 'int16_t', 'int32_t', 'int64_t',
+ 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t',
+
+ 'intmax_t', 'uintmax_t', 'intptr_t', 'uintptr_t'
+ ),
+ // Public API
+ 5 => array(
+ 'AssignProcessToJobObject', 'CommandLineToArgvW', 'ConvertThreadToFiber',
+ 'CreateFiber', 'CreateJobObjectA', 'CreateJobObjectW', 'CreateProcessA',
+ 'CreateProcessAsUserA', 'CreateProcessAsUserW', 'CreateProcessW',
+ 'CreateRemoteThread', 'CreateThread', 'DeleteFiber', 'ExitProcess',
+ 'ExitThread', 'FreeEnvironmentStringsA', 'FreeEnvironmentStringsW',
+ 'GetCommandLineA', 'GetCommandLineW', 'GetCurrentProcess',
+ 'GetCurrentProcessId', 'GetCurrentThread', 'GetCurrentThreadId',
+ 'GetEnvironmentStringsA', 'GetEnvironmentStringsW',
+ 'GetEnvironmentVariableA', 'GetEnvironmentVariableW', 'GetExitCodeProcess',
+ 'GetExitCodeThread', 'GetGuiResources', 'GetPriorityClass',
+ 'GetProcessAffinityMask', 'GetProcessPriorityBoost',
+ 'GetProcessShutdownParameters', 'GetProcessTimes', 'GetProcessVersion',
+ 'GetProcessWorkingSetSize', 'GetStartupInfoA', 'GetStartupInfoW',
+ 'GetThreadPriority', 'GetThreadPriorityBoost', 'GetThreadTimes',
+ 'OpenJobObjectA', 'OpenJobObjectW', 'OpenProcess',
+ 'QueryInformationJobObject', 'ResumeThread', 'SetEnvironmentVariableA',
+ 'SetEnvironmentVariableW', 'SetInformationJobObject', 'SetPriorityClass',
+ 'SetProcessAffinityMask', 'SetProcessPriorityBoost',
+ 'SetProcessShutdownParameters', 'SetProcessWorkingSetSize',
+ 'SetThreadAffinityMask', 'SetThreadIdealProcessor', 'SetThreadPriority',
+ 'SetThreadPriorityBoost', 'Sleep', 'SleepEx', 'SuspendThread',
+ 'SwitchToFiber', 'SwitchToThread', 'TerminateJobObject', 'TerminateProcess',
+ 'TerminateThread', 'WaitForInputIdle', 'WinExec',
+
+ '_hread', '_hwrite', '_lclose', '_lcreat', '_llseek', '_lopen', '_lread',
+ '_lwrite', 'AreFileApisANSI', 'CancelIo', 'CopyFileA', 'CopyFileW',
+ 'CreateDirectoryA', 'CreateDirectoryExA', 'CreateDirectoryExW',
+ 'CreateDirectoryW', 'CreateFileA', 'CreateFileW', 'DeleteFileA',
+ 'DeleteFileW', 'FindClose', 'FindCloseChangeNotification',
+ 'FindFirstChangeNotificationA', 'FindFirstChangeNotificationW',
+ 'FindFirstFileA', 'FindFirstFileW', 'FindNextFileA', 'FindNextFileW',
+ 'FlushFileBuffers', 'GetCurrentDirectoryA', 'GetCurrentDirectoryW',
+ 'GetDiskFreeSpaceA', 'GetDiskFreeSpaceExA', 'GetDiskFreeSpaceExW',
+ 'GetDiskFreeSpaceW', 'GetDriveTypeA', 'GetDriveTypeW', 'GetFileAttributesA',
+ 'GetFileAttributesExA', 'GetFileAttributesExW', 'GetFileAttributesW',
+ 'GetFileInformationByHandle', 'GetFileSize', 'GetFileType',
+ 'GetFullPathNameA', 'GetFullPathNameW', 'GetLogicalDrives',
+ 'GetLogicalDriveStringsA', 'GetLogicalDriveStringsW', 'GetLongPathNameA',
+ 'GetLongPathNameW', 'GetShortPathNameA', 'GetShortPathNameW',
+ 'GetTempFileNameA', 'GetTempFileNameW', 'GetTempPathA', 'GetTempPathW',
+ 'LockFile', 'MoveFileA', 'MoveFileW', 'MulDiv', 'OpenFile',
+ 'QueryDosDeviceA', 'QueryDosDeviceW', 'ReadFile', 'ReadFileEx',
+ 'RemoveDirectoryA', 'RemoveDirectoryW', 'SearchPathA', 'SearchPathW',
+ 'SetCurrentDirectoryA', 'SetCurrentDirectoryW', 'SetEndOfFile',
+ 'SetFileApisToANSI', 'SetFileApisToOEM', 'SetFileAttributesA',
+ 'SetFileAttributesW', 'SetFilePointer', 'SetHandleCount',
+ 'SetVolumeLabelA', 'SetVolumeLabelW', 'UnlockFile', 'WriteFile',
+ 'WriteFileEx',
+
+ 'DeviceIoControl',
+
+ 'GetModuleFileNameA', 'GetModuleFileNameW', 'GetProcAddress',
+ 'LoadLibraryA', 'LoadLibraryExA', 'LoadLibraryExW', 'LoadLibraryW',
+ 'LoadModule',
+
+ 'GetPrivateProfileIntA', 'GetPrivateProfileIntW',
+ 'GetPrivateProfileSectionA', 'GetPrivateProfileSectionNamesA',
+ 'GetPrivateProfileSectionNamesW', 'GetPrivateProfileSectionW',
+ 'GetPrivateProfileStringA', 'GetPrivateProfileStringW',
+ 'GetPrivateProfileStructA', 'GetPrivateProfileStructW',
+ 'GetProfileIntA', 'GetProfileIntW', 'GetProfileSectionA',
+ 'GetProfileSectionW', 'GetProfileStringA', 'GetProfileStringW',
+ 'RegCloseKey', 'RegConnectRegistryA', 'RegConnectRegistryW',
+ 'RegCreateKeyA', 'RegCreateKeyExA', 'RegCreateKeyExW',
+ 'RegCreateKeyW', 'RegDeleteKeyA', 'RegDeleteKeyW', 'RegDeleteValueA',
+ 'RegDeleteValueW', 'RegEnumKeyA', 'RegEnumKeyExA', 'RegEnumKeyExW',
+ 'RegEnumKeyW', 'RegEnumValueA', 'RegEnumValueW', 'RegFlushKey',
+ 'RegGetKeySecurity', 'RegLoadKeyA', 'RegLoadKeyW',
+ 'RegNotifyChangeKeyValue', 'RegOpenKeyA', 'RegOpenKeyExA', 'RegOpenKeyExW',
+ 'RegOpenKeyW', 'RegOverridePredefKey', 'RegQueryInfoKeyA',
+ 'RegQueryInfoKeyW', 'RegQueryMultipleValuesA', 'RegQueryMultipleValuesW',
+ 'RegQueryValueA', 'RegQueryValueExA', 'RegQueryValueExW', 'RegQueryValueW',
+ 'RegReplaceKeyA', 'RegReplaceKeyW', 'RegRestoreKeyA', 'RegRestoreKeyW',
+ 'RegSaveKeyA', 'RegSaveKeyW', 'RegSetKeySecurity', 'RegSetValueA',
+ 'RegSetValueExA', 'RegSetValueExW', 'RegSetValueW', 'RegUnLoadKeyA',
+ 'RegUnLoadKeyW', 'WritePrivateProfileSectionA', 'WritePrivateProfileSectionW',
+ 'WritePrivateProfileStringA', 'WritePrivateProfileStringW',
+ 'WritePrivateProfileStructA', 'WritePrivateProfileStructW',
+ 'WriteProfileSectionA', 'WriteProfileSectionW', 'WriteProfileStringA',
+ 'WriteProfileStringW',
+
+ 'AccessCheck', 'AccessCheckAndAuditAlarmA', 'AccessCheckAndAuditAlarmW',
+ 'AccessCheckByType', 'AccessCheckByTypeAndAuditAlarmA',
+ 'AccessCheckByTypeAndAuditAlarmW', 'AccessCheckByTypeResultList',
+ 'AccessCheckByTypeResultListAndAuditAlarmA', 'AccessCheckByTypeResultListAndAuditAlarmW',
+ 'AddAccessAllowedAce', 'AddAccessAllowedAceEx', 'AddAccessAllowedObjectAce',
+ 'AddAccessDeniedAce', 'AddAccessDeniedAceEx', 'AddAccessDeniedObjectAce',
+ 'AddAce', 'AddAuditAccessAce', 'AddAuditAccessAceEx', 'AddAuditAccessObjectAce',
+ 'AdjustTokenGroups', 'AdjustTokenPrivileges', 'AllocateAndInitializeSid',
+ 'AllocateLocallyUniqueId', 'AreAllAccessesGranted', 'AreAnyAccessesGranted',
+ 'BuildExplicitAccessWithNameA', 'BuildExplicitAccessWithNameW',
+ 'BuildImpersonateExplicitAccessWithNameA', 'BuildImpersonateExplicitAccessWithNameW',
+ 'BuildImpersonateTrusteeA', 'BuildImpersonateTrusteeW', 'BuildSecurityDescriptorA',
+ 'BuildSecurityDescriptorW', 'BuildTrusteeWithNameA', 'BuildTrusteeWithNameW',
+ 'BuildTrusteeWithSidA', 'BuildTrusteeWithSidW',
+ 'ConvertToAutoInheritPrivateObjectSecurity', 'CopySid', 'CreatePrivateObjectSecurity',
+ 'CreatePrivateObjectSecurityEx', 'CreateRestrictedToken', 'DeleteAce',
+ 'DestroyPrivateObjectSecurity', 'DuplicateToken', 'DuplicateTokenEx',
+ 'EqualPrefixSid', 'EqualSid', 'FindFirstFreeAce', 'FreeSid', 'GetAce',
+ 'GetAclInformation', 'GetAuditedPermissionsFromAclA', 'GetAuditedPermissionsFromAclW',
+ 'GetEffectiveRightsFromAclA', 'GetEffectiveRightsFromAclW',
+ 'GetExplicitEntriesFromAclA', 'GetExplicitEntriesFromAclW', 'GetFileSecurityA',
+ 'GetFileSecurityW', 'GetKernelObjectSecurity', 'GetLengthSid', 'GetMultipleTrusteeA',
+ 'GetMultipleTrusteeOperationA', 'GetMultipleTrusteeOperationW', 'GetMultipleTrusteeW',
+ 'GetNamedSecurityInfoA', 'GetNamedSecurityInfoW', 'GetPrivateObjectSecurity',
+ 'GetSecurityDescriptorControl', 'GetSecurityDescriptorDacl',
+ 'GetSecurityDescriptorGroup', 'GetSecurityDescriptorLength',
+ 'GetSecurityDescriptorOwner', 'GetSecurityDescriptorSacl', 'GetSecurityInfo',
+ 'GetSidIdentifierAuthority', 'GetSidLengthRequired', 'GetSidSubAuthority',
+ 'GetSidSubAuthorityCount', 'GetTokenInformation', 'GetTrusteeFormA',
+ 'GetTrusteeFormW', 'GetTrusteeNameA', 'GetTrusteeNameW', 'GetTrusteeTypeA',
+ 'GetTrusteeTypeW', 'GetUserObjectSecurity', 'ImpersonateLoggedOnUser',
+ 'ImpersonateNamedPipeClient', 'ImpersonateSelf', 'InitializeAcl',
+ 'InitializeSecurityDescriptor', 'InitializeSid', 'IsTokenRestricted', 'IsValidAcl',
+ 'IsValidSecurityDescriptor', 'IsValidSid', 'LogonUserA', 'LogonUserW',
+ 'LookupAccountNameA', 'LookupAccountNameW', 'LookupAccountSidA', 'LookupAccountSidW',
+ 'LookupPrivilegeDisplayNameA', 'LookupPrivilegeDisplayNameW', 'LookupPrivilegeNameA',
+ 'LookupPrivilegeNameW', 'LookupPrivilegeValueA', 'LookupPrivilegeValueW',
+ 'LookupSecurityDescriptorPartsA', 'LookupSecurityDescriptorPartsW', 'MakeAbsoluteSD',
+ 'MakeSelfRelativeSD', 'MapGenericMask', 'ObjectCloseAuditAlarmA',
+ 'ObjectCloseAuditAlarmW', 'ObjectDeleteAuditAlarmA', 'ObjectDeleteAuditAlarmW',
+ 'ObjectOpenAuditAlarmA', 'ObjectOpenAuditAlarmW', 'ObjectPrivilegeAuditAlarmA',
+ 'ObjectPrivilegeAuditAlarmW', 'OpenProcessToken', 'OpenThreadToken', 'PrivilegeCheck',
+ 'PrivilegedServiceAuditAlarmA', 'PrivilegedServiceAuditAlarmW', 'RevertToSelf',
+ 'SetAclInformation', 'SetEntriesInAclA', 'SetEntriesInAclW', 'SetFileSecurityA',
+ 'SetFileSecurityW', 'SetKernelObjectSecurity', 'SetNamedSecurityInfoA',
+ 'SetNamedSecurityInfoW', 'SetPrivateObjectSecurity', 'SetPrivateObjectSecurityEx',
+ 'SetSecurityDescriptorControl', 'SetSecurityDescriptorDacl',
+ 'SetSecurityDescriptorGroup', 'SetSecurityDescriptorOwner',
+ 'SetSecurityDescriptorSacl', 'SetSecurityInfo', 'SetThreadToken',
+ 'SetTokenInformation', 'SetUserObjectSecurity', 'ChangeServiceConfig2A',
+ 'ChangeServiceConfig2W', 'ChangeServiceConfigA', 'ChangeServiceConfigW',
+ 'CloseServiceHandle', 'ControlService', 'CreateServiceA', 'CreateServiceW',
+ 'DeleteService', 'EnumDependentServicesA', 'EnumDependentServicesW',
+ 'EnumServicesStatusA', 'EnumServicesStatusW', 'GetServiceDisplayNameA',
+ 'GetServiceDisplayNameW', 'GetServiceKeyNameA', 'GetServiceKeyNameW',
+ 'LockServiceDatabase', 'NotifyBootConfigStatus', 'OpenSCManagerA', 'OpenSCManagerW',
+ 'OpenServiceA', 'OpenServiceW', 'QueryServiceConfig2A', 'QueryServiceConfig2W',
+ 'QueryServiceConfigA', 'QueryServiceConfigW', 'QueryServiceLockStatusA',
+ 'QueryServiceLockStatusW', 'QueryServiceObjectSecurity', 'QueryServiceStatus',
+ 'RegisterServiceCtrlHandlerA', 'RegisterServiceCtrlHandlerW',
+ 'SetServiceObjectSecurity', 'SetServiceStatus', 'StartServiceA',
+ 'StartServiceCtrlDispatcherA', 'StartServiceCtrlDispatcherW', 'StartServiceW',
+ 'UnlockServiceDatabase',
+
+ 'MultinetGetConnectionPerformanceA', 'MultinetGetConnectionPerformanceW',
+ 'NetAlertRaise', 'NetAlertRaiseEx', 'NetApiBufferAllocate', 'NetApiBufferFree',
+ 'NetApiBufferReallocate', 'NetApiBufferSize', 'NetConnectionEnum', 'NetFileClose',
+ 'NetFileGetInfo', 'NetGetAnyDCName', 'NetGetDCName', 'NetGetDisplayInformationIndex',
+ 'NetGroupAdd', 'NetGroupAddUser', 'NetGroupDel', 'NetGroupDelUser', 'NetGroupEnum',
+ 'NetGroupGetInfo', 'NetGroupGetUsers', 'NetGroupSetInfo', 'NetGroupSetUsers',
+ 'NetLocalGroupAdd', 'NetLocalGroupAddMember', 'NetLocalGroupAddMembers',
+ 'NetLocalGroupDel', 'NetLocalGroupDelMember', 'NetLocalGroupDelMembers',
+ 'NetLocalGroupEnum', 'NetLocalGroupGetInfo', 'NetLocalGroupGetMembers',
+ 'NetLocalGroupSetInfo', 'NetLocalGroupSetMembers', 'NetMessageBufferSend',
+ 'NetMessageNameAdd', 'NetMessageNameDel', 'NetMessageNameEnum',
+ 'NetMessageNameGetInfo', 'NetQueryDisplayInformation', 'NetRemoteComputerSupports',
+ 'NetRemoteTOd', 'NetReplExportDirAdd', 'NetReplExportDirDel', 'NetReplExportDirEnum',
+ 'NetReplExportDirGetInfo', 'NetReplExportDirLock', 'NetReplExportDirSetInfo',
+ 'NetReplExportDirUnlock', 'NetReplGetInfo', 'NetReplImportDirAdd',
+ 'NetReplImportDirDel', 'NetReplImportDirEnum', 'NetReplImportDirGetInfo',
+ 'NetReplImportDirLock', 'NetReplImportDirUnlock', 'NetReplSetInfo',
+ 'NetScheduleJobAdd', 'NetScheduleJobDel', 'NetScheduleJobEnum',
+ 'NetScheduleJobGetInfo', 'NetServerComputerNameAdd', 'NetServerComputerNameDel',
+ 'NetServerDiskEnum', 'NetServerEnum', 'NetServerEnumEx', 'NetServerGetInfo',
+ 'NetServerSetInfo', 'NetServerTransportAdd', 'NetServerTransportAddEx',
+ 'NetServerTransportDel', 'NetServerTransportEnum', 'NetSessionDel', 'NetSessionEnum',
+ 'NetSessionGetInfo', 'NetShareAdd', 'NetShareCheck', 'NetShareDel', 'NetShareEnum',
+ 'NetShareGetInfo', 'NetShareSetInfo', 'NetStatisticsGet', 'NetUseAdd', 'NetUseDel',
+ 'NetUseEnum', 'NetUseGetInfo', 'NetUserAdd', 'NetUserChangePassword', 'NetUserDel',
+ 'NetUserEnum', 'NetUserGetGroups', 'NetUserGetInfo', 'NetUserGetLocalGroups',
+ 'NetUserModalsGet', 'NetUserModalsSet', 'NetUserSetGroups', 'NetUserSetInfo',
+ 'NetWkstaGetInfo', 'NetWkstaSetInfo', 'NetWkstaTransportAdd', 'NetWkstaTransportDel',
+ 'NetWkstaTransportEnum', 'NetWkstaUserEnum', 'NetWkstaUserGetInfo',
+ 'NetWkstaUserSetInfo', 'WNetAddConnection2A', 'WNetAddConnection2W',
+ 'WNetAddConnection3A', 'WNetAddConnection3W', 'WNetAddConnectionA',
+ 'WNetAddConnectionW', 'WNetCancelConnection2A', 'WNetCancelConnection2W',
+ 'WNetCancelConnectionA', 'WNetCancelConnectionW', 'WNetCloseEnum',
+ 'WNetConnectionDialog', 'WNetConnectionDialog1A', 'WNetConnectionDialog1W',
+ 'WNetDisconnectDialog', 'WNetDisconnectDialog1A', 'WNetDisconnectDialog1W',
+ 'WNetEnumResourceA', 'WNetEnumResourceW', 'WNetGetConnectionA', 'WNetGetConnectionW',
+ 'WNetGetLastErrorA', 'WNetGetLastErrorW', 'WNetGetNetworkInformationA',
+ 'WNetGetNetworkInformationW', 'WNetGetProviderNameA', 'WNetGetProviderNameW',
+ 'WNetGetResourceInformationA', 'WNetGetResourceInformationW',
+ 'WNetGetResourceParentA', 'WNetGetResourceParentW', 'WNetGetUniversalNameA',
+ 'WNetGetUniversalNameW', 'WNetGetUserA', 'WNetGetUserW', 'WNetOpenEnumA',
+ 'WNetOpenEnumW', 'WNetUseConnectionA', 'WnetUseConnectionW',
+
+ 'accept', 'bind', 'closesocket', 'connect', 'gethostbyaddr', 'gethostbyname',
+ 'gethostname', 'getpeername', 'getprotobyname', 'getprotobynumber', 'getservbyname',
+ 'getservbyport', 'getsockname', 'getsockopt', 'htonl', 'htons', 'inet_addr',
+ 'inet_ntoa', 'ioctlsocket', 'listen', 'ntohl', 'ntohs', 'recv', 'recvfrom', 'select',
+ 'send', 'sendto', 'setsockopt', 'shutdown', 'socket', 'WSAAccept',
+ 'WSAAddressToStringA', 'WSAAddressToStringW', 'WSAAsyncGetHostByAddr',
+ 'WSAAsyncGetHostByName', 'WSAAsyncGetProtoByName', 'WSAAsyncGetProtoByNumber',
+ 'WSAAsyncGetServByName', 'WSAAsyncGetServByPort', 'WSAAsyncSelect',
+ 'WSACancelAsyncRequest', 'WSACancelBlockingCall', 'WSACleanup', 'WSACloseEvent',
+ 'WSAConnect', 'WSACreateEvent', 'WSADuplicateSocketA', 'WSADuplicateSocketW',
+ 'WSAEnumNameSpaceProvidersA', 'WSAEnumNameSpaceProvidersW', 'WSAEnumNetworkEvents',
+ 'WSAEnumProtocolsA', 'WSAEnumProtocolsW', 'WSAEventSelect', 'WSAGetLastError',
+ 'WSAGetOverlappedResult', 'WSAGetQOSByName', 'WSAGetServiceClassInfoA',
+ 'WSAGetServiceClassInfoW', 'WSAGetServiceClassNameByClassIdA',
+ 'WSAGetServiceClassNameByClassIdW', 'WSAHtonl', 'WSAHtons', 'WSAInstallServiceClassA',
+ 'WSAInstallServiceClassW', 'WSAIoctl', 'WSAIsBlocking', 'WSAJoinLeaf',
+ 'WSALookupServiceBeginA', 'WSALookupServiceBeginW', 'WSALookupServiceEnd',
+ 'WSALookupServiceNextA', 'WSALookupServiceNextW', 'WSANtohl', 'WSANtohs',
+ 'WSAProviderConfigChange', 'WSARecv', 'WSARecvDisconnect', 'WSARecvFrom',
+ 'WSARemoveServiceClass', 'WSAResetEvent', 'WSASend', 'WSASendDisconnect', 'WSASendTo',
+ 'WSASetBlockingHook', 'WSASetEvent', 'WSASetLastError', 'WSASetServiceA',
+ 'WSASetServiceW', 'WSASocketA', 'WSASocketW', 'WSAStartup', 'WSAStringToAddressA',
+ 'WSAStringToAddressW', 'WSAUnhookBlockingHook', 'WSAWaitForMultipleEvents',
+ 'WSCDeinstallProvider', 'WSCEnableNSProvider', 'WSCEnumProtocols',
+ 'WSCGetProviderPath', 'WSCInstallNameSpace', 'WSCInstallProvider',
+ 'WSCUnInstallNameSpace',
+
+ 'ContinueDebugEvent', 'DebugActiveProcess', 'DebugBreak', 'FatalExit',
+ 'FlushInstructionCache', 'GetThreadContext', 'GetThreadSelectorEntry',
+ 'IsDebuggerPresent', 'OutputDebugStringA', 'OutputDebugStringW', 'ReadProcessMemory',
+ 'SetDebugErrorLevel', 'SetThreadContext', 'WaitForDebugEvent', 'WriteProcessMemory',
+
+ 'CloseHandle', 'DuplicateHandle', 'GetHandleInformation', 'SetHandleInformation',
+
+ 'AdjustWindowRect', 'AdjustWindowRectEx', 'AllowSetForegroundWindow',
+ 'AnimateWindow', 'AnyPopup', 'ArrangeIconicWindows', 'BeginDeferWindowPos',
+ 'BringWindowToTop', 'CascadeWindows', 'ChildWindowFromPoint',
+ 'ChildWindowFromPointEx', 'CloseWindow', 'CreateWindowExA', 'CreateWindowExW',
+ 'DeferWindowPos', 'DestroyWindow', 'EndDeferWindowPos', 'EnumChildWindows',
+ 'EnumThreadWindows', 'EnumWindows', 'FindWindowA', 'FindWindowExA', 'FindWindowExW',
+ 'FindWindowW', 'GetAltTabInfoA', 'GetAltTabInfoW', 'GetAncestor', 'GetClientRect',
+ 'GetDesktopWindow', 'GetForegroundWindow', 'GetGUIThreadInfo', 'GetLastActivePopup',
+ 'GetLayout', 'GetParent', 'GetProcessDefaultLayout', 'GetTitleBarInf', 'GetTopWindow',
+ 'GetWindow', 'GetWindowInfo', 'GetWindowModuleFileNameA', 'GetWindowModuleFileNameW',
+ 'GetWindowPlacement', 'GetWindowRect', 'GetWindowTextA', 'GetWindowTextLengthA',
+ 'GetWindowTextLengthW', 'GetWindowTextW', 'GetWindowThreadProcessId', 'IsChild',
+ 'IsIconic', 'IsWindow', 'IsWindowUnicode', 'IsWindowVisible', 'IsZoomed',
+ 'LockSetForegroundWindow', 'MoveWindow', 'OpenIcon', 'RealChildWindowFromPoint',
+ 'RealGetWindowClassA', 'RealGetWindowClassW', 'SetForegroundWindow',
+ 'SetLayeredWindowAttributes', 'SetLayout', 'SetParent', 'SetProcessDefaultLayout',
+ 'SetWindowPlacement', 'SetWindowPos', 'SetWindowTextA', 'SetWindowTextW',
+ 'ShowOwnedPopups', 'ShowWindow', 'ShowWindowAsync', 'TileWindows',
+ 'UpdateLayeredWindow', 'WindowFromPoint',
+
+ 'CreateDialogIndirectParamA', 'CreateDialogIndirectParamW', 'CreateDialogParamA',
+ 'CreateDialogParamW', 'DefDlgProcA', 'DefDlgProcW', 'DialogBoxIndirectParamA',
+ 'DialogBoxIndirectParamW', 'DialogBoxParamA', 'DialogBoxParamW', 'EndDialog',
+ 'GetDialogBaseUnits', 'GetDlgCtrlID', 'GetDlgItem', 'GetDlgItemInt',
+ 'GetDlgItemTextA', 'GetDlgItemTextW', 'GetNextDlgGroupItem', 'GetNextDlgTabItem',
+ 'IsDialogMessageA', 'IsDialogMessageW', 'MapDialogRect', 'MessageBoxA',
+ 'MessageBoxExA', 'MessageBoxExW', 'MessageBoxIndirectA', 'MessageBoxIndirectW',
+ 'MessageBoxW', 'SendDlgItemMessageA', 'SendDlgItemMessageW', 'SetDlgItemInt',
+ 'SetDlgItemTextA', 'SetDlgItemTextW',
+
+ 'GetWriteWatch', 'GlobalMemoryStatus', 'GlobalMemoryStatusEx', 'IsBadCodePtr',
+ 'IsBadReadPtr', 'IsBadStringPtrA', 'IsBadStringPtrW', 'IsBadWritePtr',
+ 'ResetWriteWatch', 'AllocateUserPhysicalPages', 'FreeUserPhysicalPages',
+ 'MapUserPhysicalPages', 'MapUserPhysicalPagesScatter', 'GlobalAlloc', 'GlobalFlags',
+ 'GlobalFree', 'GlobalHandle', 'GlobalLock', 'GlobalReAlloc', 'GlobalSize',
+ 'GlobalUnlock', 'LocalAlloc', 'LocalFlags', 'LocalFree', 'LocalHandle', 'LocalLock',
+ 'LocalReAlloc', 'LocalSize', 'LocalUnlock', 'GetProcessHeap', 'GetProcessHeaps',
+ 'HeapAlloc', 'HeapCompact', 'HeapCreate', 'HeapDestroy', 'HeapFree', 'HeapLock',
+ 'HeapReAlloc', 'HeapSize', 'HeapUnlock', 'HeapValidate', 'HeapWalk', 'VirtualAlloc',
+ 'VirtualAllocEx', 'VirtualFree', 'VirtualFreeEx', 'VirtualLock', 'VirtualProtect',
+ 'VirtualProtectEx', 'VirtualQuery', 'VirtualQueryEx', 'VirtualUnlock',
+ 'GetFreeSpace', 'GlobalCompact', 'GlobalFix', 'GlobalUnfix', 'GlobalUnWire',
+ 'GlobalWire', 'IsBadHugeReadPtr', 'IsBadHugeWritePtr', 'LocalCompact', 'LocalShrink',
+
+ 'GetClassInfoA', 'GetClassInfoW', 'GetClassInfoExA', 'GetClassInfoExW',
+ 'GetClassLongA', 'GetClassLongW', 'GetClassLongPtrA', 'GetClassLongPtrW',
+ 'RegisterClassA', 'RegisterClassW', 'RegisterClassExA', 'RegisterClassExW',
+ 'SetClassLongA', 'SetClassLongW', 'SetClassLongPtrA', 'SetClassLongPtrW',
+ 'SetWindowLongA', 'SetWindowLongW', 'SetWindowLongPtrA', 'SetWindowLongPtrW',
+ 'UnregisterClassA', 'UnregisterClassW', 'GetClassWord', 'GetWindowWord',
+ 'SetClassWord', 'SetWindowWord'
+ ),
+ // Native API
+ 6 => array(
+ 'CsrAllocateCaptureBuffer', 'CsrAllocateCapturePointer', 'CsrAllocateMessagePointer',
+ 'CsrCaptureMessageBuffer', 'CsrCaptureMessageString', 'CsrCaptureTimeout',
+ 'CsrClientCallServer', 'CsrClientConnectToServer', 'CsrFreeCaptureBuffer',
+ 'CsrIdentifyAlertableThread', 'CsrNewThread', 'CsrProbeForRead', 'CsrProbeForWrite',
+ 'CsrSetPriorityClass',
+
+ 'LdrAccessResource', 'LdrDisableThreadCalloutsForDll', 'LdrEnumResources',
+ 'LdrFindEntryForAddress', 'LdrFindResource_U', 'LdrFindResourceDirectory_U',
+ 'LdrGetDllHandle', 'LdrGetProcedureAddress', 'LdrInitializeThunk', 'LdrLoadDll',
+ 'LdrProcessRelocationBlock', 'LdrQueryImageFileExecutionOptions',
+ 'LdrQueryProcessModuleInformation', 'LdrShutdownProcess', 'LdrShutdownThread',
+ 'LdrUnloadDll', 'LdrVerifyImageMatchesChecksum',
+
+ 'NtAcceptConnectPort', 'ZwAcceptConnectPort', 'NtCompleteConnectPort',
+ 'ZwCompleteConnectPort', 'NtConnectPort', 'ZwConnectPort', 'NtCreatePort',
+ 'ZwCreatePort', 'NtImpersonateClientOfPort', 'ZwImpersonateClientOfPort',
+ 'NtListenPort', 'ZwListenPort', 'NtQueryInformationPort', 'ZwQueryInformationPort',
+ 'NtReadRequestData', 'ZwReadRequestData', 'NtReplyPort', 'ZwReplyPort',
+ 'NtReplyWaitReceivePort', 'ZwReplyWaitReceivePort', 'NtReplyWaitReplyPort',
+ 'ZwReplyWaitReplyPort', 'NtRequestPort', 'ZwRequestPort', 'NtRequestWaitReplyPort',
+ 'ZwRequestWaitReplyPort', 'NtSecureConnectPort', 'ZwSecureConnectPort',
+ 'NtWriteRequestData', 'ZwWriteRequestData',
+
+ 'NtAccessCheck', 'ZwAccessCheck', 'NtAccessCheckAndAuditAlarm',
+ 'ZwAccessCheckAndAuditAlarm', 'NtAccessCheckByType', 'ZwAccessCheckByType',
+ 'NtAccessCheckByTypeAndAuditAlarm', 'ZwAccessCheckByTypeAndAuditAlarm',
+ 'NtAccessCheckByTypeResultList', 'ZwAccessCheckByTypeResultList',
+ 'NtAdjustGroupsToken', 'ZwAdjustGroupsToken', 'NtAdjustPrivilegesToken',
+ 'ZwAdjustPrivilegesToken', 'NtCloseObjectAuditAlarm', 'ZwCloseObjectAuditAlarm',
+ 'NtCreateToken', 'ZwCreateToken', 'NtDeleteObjectAuditAlarm',
+ 'ZwDeleteObjectAuditAlarm', 'NtDuplicateToken', 'ZwDuplicateToken',
+ 'NtFilterToken', 'ZwFilterToken', 'NtImpersonateThread', 'ZwImpersonateThread',
+ 'NtOpenObjectAuditAlarm', 'ZwOpenObjectAuditAlarm', 'NtOpenProcessToken',
+ 'ZwOpenProcessToken', 'NtOpenThreadToken', 'ZwOpenThreadToken', 'NtPrivilegeCheck',
+ 'ZwPrivilegeCheck', 'NtPrivilegedServiceAuditAlarm', 'ZwPrivilegedServiceAuditAlarm',
+ 'NtPrivilegeObjectAuditAlarm', 'ZwPrivilegeObjectAuditAlarm',
+ 'NtQueryInformationToken', 'ZwQueryInformationToken', 'NtQuerySecurityObject',
+ 'ZwQuerySecurityObject', 'NtSetInformationToken', 'ZwSetInformationToken',
+ 'NtSetSecurityObject', 'ZwSetSecurityObject',
+
+ 'NtAddAtom', 'ZwAddAtom', 'NtDeleteAtom', 'ZwDeleteAtom', 'NtFindAtom', 'ZwFindAtom',
+ 'NtQueryInformationAtom', 'ZwQueryInformationAtom',
+
+ 'NtAlertResumeThread', 'ZwAlertResumeThread', 'NtAlertThread', 'ZwAlertThread',
+ 'NtCreateProcess', 'ZwCreateProcess', 'NtCreateThread', 'ZwCreateThread',
+ 'NtCurrentTeb', 'NtDelayExecution', 'ZwDelayExecution', 'NtGetContextThread',
+ 'ZwGetContextThread', 'NtOpenProcess', 'ZwOpenProcess', 'NtOpenThread',
+ 'ZwOpenThread', 'NtQueryInformationProcess', 'ZwQueryInformationProcess',
+ 'NtQueryInformationThread', 'ZwQueryInformationThread', 'NtQueueApcThread',
+ 'ZwQueueApcThread', 'NtResumeThread', 'ZwResumeThread', 'NtSetContextThread',
+ 'ZwSetContextThread', 'NtSetHighWaitLowThread', 'ZwSetHighWaitLowThread',
+ 'NtSetInformationProcess', 'ZwSetInformationProcess', 'NtSetInformationThread',
+ 'ZwSetInformationThread', 'NtSetLowWaitHighThread', 'ZwSetLowWaitHighThread',
+ 'NtSuspendThread', 'ZwSuspendThread', 'NtTerminateProcess', 'ZwTerminateProcess',
+ 'NtTerminateThread', 'ZwTerminateThread', 'NtTestAlert', 'ZwTestAlert',
+ 'NtYieldExecution', 'ZwYieldExecution',
+
+ 'NtAllocateVirtualMemory', 'ZwAllocateVirtualMemory', 'NtAllocateVirtualMemory64',
+ 'ZwAllocateVirtualMemory64', 'NtAreMappedFilesTheSame', 'ZwAreMappedFilesTheSame',
+ 'NtCreateSection', 'ZwCreateSection', 'NtExtendSection', 'ZwExtendSection',
+ 'NtFlushVirtualMemory', 'ZwFlushVirtualMemory', 'NtFreeVirtualMemory',
+ 'ZwFreeVirtualMemory', 'NtFreeVirtualMemory64', 'ZwFreeVirtualMemory64',
+ 'NtLockVirtualMemory', 'ZwLockVirtualMemory', 'NtMapViewOfSection',
+ 'ZwMapViewOfSection', 'NtMapViewOfVlmSection', 'ZwMapViewOfVlmSection',
+ 'NtOpenSection', 'ZwOpenSection', 'NtProtectVirtualMemory', 'ZwProtectVirtualMemory',
+ 'NtProtectVirtualMemory64', 'ZwProtectVirtualMemory64', 'NtQueryVirtualMemory',
+ 'ZwQueryVirtualMemory', 'NtQueryVirtualMemory64', 'ZwQueryVirtualMemory64',
+ 'NtReadVirtualMemory', 'ZwReadVirtualMemory', 'NtReadVirtualMemory64',
+ 'ZwReadVirtualMemory64', 'NtUnlockVirtualMemory', 'ZwUnlockVirtualMemory',
+ 'NtUnmapViewOfSection', 'ZwUnmapViewOfSection', 'NtUnmapViewOfVlmSection',
+ 'ZwUnmapViewOfVlmSection', 'NtWriteVirtualMemory', 'ZwWriteVirtualMemory',
+ 'NtWriteVirtualMemory64', 'ZwWriteVirtualMemory64',
+
+ 'NtAssignProcessToJobObject', 'ZwAssignProcessToJobObject', 'NtCreateJobObject',
+ 'ZwCreateJobObject', 'NtOpenJobObject', 'ZwOpenJobObject',
+ 'NtQueryInformationJobObject', 'ZwQueryInformationJobObject',
+ 'NtSetInformationJobObject', 'ZwSetInformationJobObject', 'NtTerminateJobObject',
+ 'ZwTerminateJobObject',
+
+ 'NtCancelIoFile', 'ZwCancelIoFile', 'NtCreateFile', 'ZwCreateFile',
+ 'NtCreateIoCompletion', 'ZwCreateIoCompletion', 'NtDeleteFile', 'ZwDeleteFile',
+ 'NtDeviceIoControlFile', 'ZwDeviceIoControlFile', 'NtFlushBuffersFile',
+ 'ZwFlushBuffersFile', 'NtFsControlFile', 'ZwFsControlFile', 'NtLockFile', 'ZwLockFile',
+ 'NtNotifyChangeDirectoryFile', 'ZwNotifyChangeDirectoryFile', 'NtOpenFile',
+ 'ZwOpenFile', 'NtOpenIoCompletion', 'ZwOpenIoCompletion', 'NtQueryAttributesFile',
+ 'ZwQueryAttributesFile', 'NtQueryDirectoryFile', 'ZwQueryDirectoryFile',
+ 'NtQueryEaFile', 'ZwQueryEaFile', 'NtQueryIoCompletion', 'ZwQueryIoCompletion',
+ 'NtQueryQuotaInformationFile', 'ZwQueryQuotaInformationFile',
+ 'NtQueryVolumeInformationFile', 'ZwQueryVolumeInformationFile', 'NtReadFile',
+ 'ZwReadFile', 'NtReadFile64', 'ZwReadFile64', 'NtReadFileScatter', 'ZwReadFileScatter',
+ 'NtRemoveIoCompletion', 'ZwRemoveIoCompletion', 'NtSetEaFile', 'ZwSetEaFile',
+ 'NtSetInformationFile', 'ZwSetInformationFile', 'NtSetIoCompletion',
+ 'ZwSetIoCompletion', 'NtSetQuotaInformationFile', 'ZwSetQuotaInformationFile',
+ 'NtSetVolumeInformationFile', 'ZwSetVolumeInformationFile', 'NtUnlockFile',
+ 'ZwUnlockFile', 'NtWriteFile', 'ZwWriteFile', 'NtWriteFile64','ZwWriteFile64',
+ 'NtWriteFileGather', 'ZwWriteFileGather', 'NtQueryFullAttributesFile',
+ 'ZwQueryFullAttributesFile', 'NtQueryInformationFile', 'ZwQueryInformationFile',
+
+ 'RtlAbortRXact', 'RtlAbsoluteToSelfRelativeSD', 'RtlAcquirePebLock',
+ 'RtlAcquireResourceExclusive', 'RtlAcquireResourceShared', 'RtlAddAccessAllowedAce',
+ 'RtlAddAccessDeniedAce', 'RtlAddAce', 'RtlAddActionToRXact', 'RtlAddAtomToAtomTable',
+ 'RtlAddAttributeActionToRXact', 'RtlAddAuditAccessAce', 'RtlAddCompoundAce',
+ 'RtlAdjustPrivilege', 'RtlAllocateAndInitializeSid', 'RtlAllocateHandle',
+ 'RtlAllocateHeap', 'RtlAnsiCharToUnicodeChar', 'RtlAnsiStringToUnicodeSize',
+ 'RtlAnsiStringToUnicodeString', 'RtlAppendAsciizToString', 'RtlAppendStringToString',
+ 'RtlAppendUnicodeStringToString', 'RtlAppendUnicodeToString', 'RtlApplyRXact',
+ 'RtlApplyRXactNoFlush', 'RtlAreAllAccessesGranted', 'RtlAreAnyAccessesGranted',
+ 'RtlAreBitsClear', 'RtlAreBitsSet', 'RtlAssert', 'RtlCaptureStackBackTrace',
+ 'RtlCharToInteger', 'RtlCheckRegistryKey', 'RtlClearAllBits', 'RtlClearBits',
+ 'RtlClosePropertySet', 'RtlCompactHeap', 'RtlCompareMemory', 'RtlCompareMemoryUlong',
+ 'RtlCompareString', 'RtlCompareUnicodeString', 'RtlCompareVariants',
+ 'RtlCompressBuffer', 'RtlConsoleMultiByteToUnicodeN', 'RtlConvertExclusiveToShared',
+ 'RtlConvertLongToLargeInteger', 'RtlConvertPropertyToVariant',
+ 'RtlConvertSharedToExclusive', 'RtlConvertSidToUnicodeString',
+ 'RtlConvertUiListToApiList', 'RtlConvertUlongToLargeInteger',
+ 'RtlConvertVariantToProperty', 'RtlCopyLuid', 'RtlCopyLuidAndAttributesArray',
+ 'RtlCopySecurityDescriptor', 'RtlCopySid', 'RtlCopySidAndAttributesArray',
+ 'RtlCopyString', 'RtlCopyUnicodeString', 'RtlCreateAcl', 'RtlCreateAndSetSD',
+ 'RtlCreateAtomTable', 'RtlCreateEnvironment', 'RtlCreateHeap',
+ 'RtlCreateProcessParameters', 'RtlCreatePropertySet', 'RtlCreateQueryDebugBuffer',
+ 'RtlCreateRegistryKey', 'RtlCreateSecurityDescriptor', 'RtlCreateTagHeap',
+ 'RtlCreateUnicodeString', 'RtlCreateUnicodeStringFromAsciiz', 'RtlCreateUserProcess',
+ 'RtlCreateUserSecurityObject', 'RtlCreateUserThread', 'RtlCustomCPToUnicodeN',
+ 'RtlCutoverTimeToSystemTime', 'RtlDecompressBuffer', 'RtlDecompressFragment',
+ 'RtlDelete', 'RtlDeleteAce', 'RtlDeleteAtomFromAtomTable', 'RtlDeleteCriticalSection',
+ 'RtlDeleteElementGenericTable', 'RtlDeleteNoSplay', 'RtlDeleteRegistryValue',
+ 'RtlDeleteResource', 'RtlDeleteSecurityObject', 'RtlDeNormalizeProcessParams',
+ 'RtlDestroyAtomTable', 'RtlDestroyEnvironment', 'RtlDestroyHandleTable',
+ 'RtlDestroyHeap', 'RtlDestroyProcessParameters', 'RtlDestroyQueryDebugBuffer',
+ 'RtlDetermineDosPathNameType_U', 'RtlDoesFileExists_U', 'RtlDosPathNameToNtPathName_U',
+ 'RtlDosSearchPath_U', 'RtlDowncaseUnicodeString', 'RtlDumpResource',
+ 'RtlEmptyAtomTable', 'RtlEnlargedIntegerMultiply', 'RtlEnlargedUnsignedDivide',
+ 'RtlEnlargedUnsignedMultiply', 'RtlEnterCriticalSection', 'RtlEnumerateGenericTable',
+ 'RtlEnumerateGenericTableWithoutSplaying', 'RtlEnumerateProperties',
+ 'RtlEnumProcessHeaps', 'RtlEqualComputerName', 'RtlEqualDomainName', 'RtlEqualLuid',
+ 'RtlEqualPrefixSid', 'RtlEqualSid', 'RtlEqualString', 'RtlEqualUnicodeString',
+ 'RtlEraseUnicodeString', 'RtlExpandEnvironmentStrings_U', 'RtlExtendedIntegerMultiply',
+ 'RtlExtendedLargeIntegerDivide', 'RtlExtendedMagicDivide', 'RtlExtendHeap',
+ 'RtlFillMemory', 'RtlFillMemoryUlong', 'RtlFindClearBits', 'RtlFindClearBitsAndSet',
+ 'RtlFindLongestRunClear', 'RtlFindLongestRunSet', 'RtlFindMessage', 'RtlFindSetBits',
+ 'RtlFindSetBitsAndClear', 'RtlFirstFreeAce', 'RtlFlushPropertySet',
+ 'RtlFormatCurrentUserKeyPath', 'RtlFormatMessage', 'RtlFreeAnsiString',
+ 'RtlFreeHandle', 'RtlFreeHeap', 'RtlFreeOemString', 'RtlFreeSid',
+ 'RtlFreeUnicodeString', 'RtlFreeUserThreadStack', 'RtlGenerate8dot3Name', 'RtlGetAce',
+ 'RtlGetCallersAddress', 'RtlGetCompressionWorkSpaceSize',
+ 'RtlGetControlSecurityDescriptor', 'RtlGetCurrentDirectory_U',
+ 'RtlGetDaclSecurityDescriptor', 'RtlGetElementGenericTable', 'RtlGetFullPathName_U',
+ 'RtlGetGroupSecurityDescriptor', 'RtlGetLongestNtPathLength', 'RtlGetNtGlobalFlags',
+ 'RtlGetNtProductType', 'RtlGetOwnerSecurityDescriptor', 'RtlGetProcessHeaps',
+ 'RtlGetSaclSecurityDescriptor', 'RtlGetUserInfoHeap', 'RtlGuidToPropertySetName',
+ 'RtlIdentifierAuthoritySid', 'RtlImageDirectoryEntryToData', 'RtlImageNtHeader',
+ 'RtlImageRvaToSection', 'RtlImageRvaToVa', 'RtlImpersonateSelf', 'RtlInitAnsiString',
+ 'RtlInitCodePageTable', 'RtlInitializeAtomPackage', 'RtlInitializeBitMap',
+ 'RtlInitializeContext', 'RtlInitializeCriticalSection',
+ 'RtlInitializeCriticalSectionAndSpinCount', 'RtlInitializeGenericTable',
+ 'RtlInitializeHandleTable', 'RtlInitializeResource', 'RtlInitializeRXact',
+ 'RtlInitializeSid', 'RtlInitNlsTables', 'RtlInitString', 'RtlInitUnicodeString',
+ 'RtlInsertElementGenericTable', 'RtlIntegerToChar', 'RtlIntegerToUnicodeString',
+ 'RtlIsDosDeviceName_U', 'RtlIsGenericTableEmpty', 'RtlIsNameLegalDOS8Dot3',
+ 'RtlIsTextUnicode', 'RtlIsValidHandle', 'RtlIsValidIndexHandle', 'RtlLargeIntegerAdd',
+ 'RtlLargeIntegerArithmeticShift', 'RtlLargeIntegerDivide', 'RtlLargeIntegerNegate',
+ 'RtlLargeIntegerShiftLeft', 'RtlLargeIntegerShiftRight', 'RtlLargeIntegerSubtract',
+ 'RtlLargeIntegerToChar', 'RtlLeaveCriticalSection', 'RtlLengthRequiredSid',
+ 'RtlLengthSecurityDescriptor', 'RtlLengthSid', 'RtlLocalTimeToSystemTime',
+ 'RtlLockHeap', 'RtlLookupAtomInAtomTable', 'RtlLookupElementGenericTable',
+ 'RtlMakeSelfRelativeSD', 'RtlMapGenericMask', 'RtlMoveMemory',
+ 'RtlMultiByteToUnicodeN', 'RtlMultiByteToUnicodeSize', 'RtlNewInstanceSecurityObject',
+ 'RtlNewSecurityGrantedAccess', 'RtlNewSecurityObject', 'RtlNormalizeProcessParams',
+ 'RtlNtStatusToDosError', 'RtlNumberGenericTableElements', 'RtlNumberOfClearBits',
+ 'RtlNumberOfSetBits', 'RtlOemStringToUnicodeSize', 'RtlOemStringToUnicodeString',
+ 'RtlOemToUnicodeN', 'RtlOnMappedStreamEvent', 'RtlOpenCurrentUser',
+ 'RtlPcToFileHeader', 'RtlPinAtomInAtomTable', 'RtlpNtCreateKey',
+ 'RtlpNtEnumerateSubKey', 'RtlpNtMakeTemporaryKey', 'RtlpNtOpenKey',
+ 'RtlpNtQueryValueKey', 'RtlpNtSetValueKey', 'RtlPrefixString',
+ 'RtlPrefixUnicodeString', 'RtlPropertySetNameToGuid', 'RtlProtectHeap',
+ 'RtlpUnWaitCriticalSection', 'RtlpWaitForCriticalSection', 'RtlQueryAtomInAtomTable',
+ 'RtlQueryEnvironmentVariable_U', 'RtlQueryInformationAcl',
+ 'RtlQueryProcessBackTraceInformation', 'RtlQueryProcessDebugInformation',
+ 'RtlQueryProcessHeapInformation', 'RtlQueryProcessLockInformation',
+ 'RtlQueryProperties', 'RtlQueryPropertyNames', 'RtlQueryPropertySet',
+ 'RtlQueryRegistryValues', 'RtlQuerySecurityObject', 'RtlQueryTagHeap',
+ 'RtlQueryTimeZoneInformation', 'RtlRaiseException', 'RtlRaiseStatus', 'RtlRandom',
+ 'RtlReAllocateHeap', 'RtlRealPredecessor', 'RtlRealSuccessor', 'RtlReleasePebLock',
+ 'RtlReleaseResource', 'RtlRemoteCall', 'RtlResetRtlTranslations',
+ 'RtlRunDecodeUnicodeString', 'RtlRunEncodeUnicodeString', 'RtlSecondsSince1970ToTime',
+ 'RtlSecondsSince1980ToTime', 'RtlSelfRelativeToAbsoluteSD', 'RtlSetAllBits',
+ 'RtlSetAttributesSecurityDescriptor', 'RtlSetBits', 'RtlSetCriticalSectionSpinCount',
+ 'RtlSetCurrentDirectory_U', 'RtlSetCurrentEnvironment', 'RtlSetDaclSecurityDescriptor',
+ 'RtlSetEnvironmentVariable', 'RtlSetGroupSecurityDescriptor', 'RtlSetInformationAcl',
+ 'RtlSetOwnerSecurityDescriptor', 'RtlSetProperties', 'RtlSetPropertyNames',
+ 'RtlSetPropertySetClassId', 'RtlSetSaclSecurityDescriptor', 'RtlSetSecurityObject',
+ 'RtlSetTimeZoneInformation', 'RtlSetUnicodeCallouts', 'RtlSetUserFlagsHeap',
+ 'RtlSetUserValueHeap', 'RtlSizeHeap', 'RtlSplay', 'RtlStartRXact',
+ 'RtlSubAuthorityCountSid', 'RtlSubAuthoritySid', 'RtlSubtreePredecessor',
+ 'RtlSubtreeSuccessor', 'RtlSystemTimeToLocalTime', 'RtlTimeFieldsToTime',
+ 'RtlTimeToElapsedTimeFields', 'RtlTimeToSecondsSince1970', 'RtlTimeToSecondsSince1980',
+ 'RtlTimeToTimeFields', 'RtlTryEnterCriticalSection', 'RtlUnicodeStringToAnsiSize',
+ 'RtlUnicodeStringToAnsiString', 'RtlUnicodeStringToCountedOemString',
+ 'RtlUnicodeStringToInteger', 'RtlUnicodeStringToOemSize',
+ 'RtlUnicodeStringToOemString', 'RtlUnicodeToCustomCPN', 'RtlUnicodeToMultiByteN',
+ 'RtlUnicodeToMultiByteSize', 'RtlUnicodeToOemN', 'RtlUniform', 'RtlUnlockHeap',
+ 'RtlUnwind', 'RtlUpcaseUnicodeChar', 'RtlUpcaseUnicodeString',
+ 'RtlUpcaseUnicodeStringToAnsiString', 'RtlUpcaseUnicodeStringToCountedOemString',
+ 'RtlUpcaseUnicodeStringToOemString', 'RtlUpcaseUnicodeToCustomCPN',
+ 'RtlUpcaseUnicodeToMultiByteN', 'RtlUpcaseUnicodeToOemN', 'RtlUpperChar',
+ 'RtlUpperString', 'RtlUsageHeap', 'RtlValidAcl', 'RtlValidateHeap',
+ 'RtlValidateProcessHeaps', 'RtlValidSecurityDescriptor', 'RtlValidSid', 'RtlWalkHeap',
+ 'RtlWriteRegistryValue', 'RtlxAnsiStringToUnicodeSize', 'RtlxOemStringToUnicodeSize',
+ 'RtlxUnicodeStringToAnsiSize', 'RtlxUnicodeStringToOemSize', 'RtlZeroHeap',
+ 'RtlZeroMemory',
+
+ 'NtCancelTimer', 'ZwCancelTimer', 'NtCreateTimer', 'ZwCreateTimer', 'NtGetTickCount',
+ 'ZwGetTickCount', 'NtOpenTimer', 'ZwOpenTimer', 'NtQueryPerformanceCounter',
+ 'ZwQueryPerformanceCounter', 'NtQuerySystemTime', 'ZwQuerySystemTime', 'NtQueryTimer',
+ 'ZwQueryTimer', 'NtQueryTimerResolution', 'ZwQueryTimerResolution', 'NtSetSystemTime',
+ 'ZwSetSystemTime', 'NtSetTimer', 'ZwSetTimer', 'NtSetTimerResolution',
+ 'ZwSetTimerResolution',
+
+ 'NtClearEvent', 'ZwClearEvent', 'NtCreateEvent', 'ZwCreateEvent', 'NtCreateEventPair',
+ 'ZwCreateEventPair', 'NtCreateMutant', 'ZwCreateMutant', 'NtCreateSemaphore',
+ 'ZwCreateSemaphore', 'NtOpenEvent', 'ZwOpenEvent', 'NtOpenEventPair',
+ 'ZwOpenEventPair', 'NtOpenMutant', 'ZwOpenMutant', 'NtOpenSemaphore',
+ 'ZwOpenSemaphore', 'NtPulseEvent', 'ZwPulseEvent', 'NtQueryEvent', 'ZwQueryEvent',
+ 'NtQueryMutant', 'ZwQueryMutant', 'NtQuerySemaphore', 'ZwQuerySemaphore',
+ 'NtReleaseMutant', 'ZwReleaseMutant', 'NtReleaseProcessMutant',
+ 'ZwReleaseProcessMutant', 'NtReleaseSemaphore', 'ZwReleaseSemaphore',
+ 'NtReleaseThreadMutant', 'ZwReleaseThreadMutant', 'NtResetEvent', 'ZwResetEvent',
+ 'NtSetEvent', 'ZwSetEvent', 'NtSetHighEventPair', 'ZwSetHighEventPair',
+ 'NtSetHighWaitLowEventPair', 'ZwSetHighWaitLowEventPair', 'NtSetLowEventPair',
+ 'ZwSetLowEventPair', 'NtSetLowWaitHighEventPair', 'ZwSetLowWaitHighEventPair',
+ 'NtSignalAndWaitForSingleObject', 'ZwSignalAndWaitForSingleObject',
+ 'NtWaitForMultipleObjects', 'ZwWaitForMultipleObjects', 'NtWaitForSingleObject',
+ 'ZwWaitForSingleObject', 'NtWaitHighEventPair', 'ZwWaitHighEventPair',
+ 'NtWaitLowEventPair', 'ZwWaitLowEventPair',
+
+ 'NtClose', 'ZwClose', 'NtCreateDirectoryObject', 'ZwCreateDirectoryObject',
+ 'NtCreateSymbolicLinkObject', 'ZwCreateSymbolicLinkObject',
+ 'NtDuplicateObject', 'ZwDuplicateObject', 'NtMakeTemporaryObject',
+ 'ZwMakeTemporaryObject', 'NtOpenDirectoryObject', 'ZwOpenDirectoryObject',
+ 'NtOpenSymbolicLinkObject', 'ZwOpenSymbolicLinkObject', 'NtQueryDirectoryObject',
+ 'ZwQueryDirectoryObject', 'NtQueryObject', 'ZwQueryObject',
+ 'NtQuerySymbolicLinkObject', 'ZwQuerySymbolicLinkObject', 'NtSetInformationObject',
+ 'ZwSetInformationObject',
+
+ 'NtContinue', 'ZwContinue', 'NtRaiseException', 'ZwRaiseException',
+ 'NtRaiseHardError', 'ZwRaiseHardError', 'NtSetDefaultHardErrorPort',
+ 'ZwSetDefaultHardErrorPort',
+
+ 'NtCreateChannel', 'ZwCreateChannel', 'NtListenChannel', 'ZwListenChannel',
+ 'NtOpenChannel', 'ZwOpenChannel', 'NtReplyWaitSendChannel', 'ZwReplyWaitSendChannel',
+ 'NtSendWaitReplyChannel', 'ZwSendWaitReplyChannel', 'NtSetContextChannel',
+ 'ZwSetContextChannel',
+
+ 'NtCreateKey', 'ZwCreateKey', 'NtDeleteKey', 'ZwDeleteKey', 'NtDeleteValueKey',
+ 'ZwDeleteValueKey', 'NtEnumerateKey', 'ZwEnumerateKey', 'NtEnumerateValueKey',
+ 'ZwEnumerateValueKey', 'NtFlushKey', 'ZwFlushKey', 'NtInitializeRegistry',
+ 'ZwInitializeRegistry', 'NtLoadKey', 'ZwLoadKey', 'NtLoadKey2', 'ZwLoadKey2',
+ 'NtNotifyChangeKey', 'ZwNotifyChangeKey', 'NtOpenKey', 'ZwOpenKey', 'NtQueryKey',
+ 'ZwQueryKey', 'NtQueryMultipleValueKey', 'ZwQueryMultipleValueKey',
+ 'NtQueryMultiplValueKey', 'ZwQueryMultiplValueKey', 'NtQueryValueKey',
+ 'ZwQueryValueKey', 'NtReplaceKey', 'ZwReplaceKey', 'NtRestoreKey', 'ZwRestoreKey',
+ 'NtSaveKey', 'ZwSaveKey', 'NtSetInformationKey', 'ZwSetInformationKey',
+ 'NtSetValueKey', 'ZwSetValueKey', 'NtUnloadKey', 'ZwUnloadKey',
+
+ 'NtCreateMailslotFile', 'ZwCreateMailslotFile', 'NtCreateNamedPipeFile',
+ 'ZwCreateNamedPipeFile', 'NtCreatePagingFile', 'ZwCreatePagingFile',
+
+ 'NtCreateProfile', 'ZwCreateProfile', 'NtQueryIntervalProfile',
+ 'ZwQueryIntervalProfile', 'NtRegisterThreadTerminatePort',
+ 'ZwRegisterThreadTerminatePort', 'NtSetIntervalProfile', 'ZwSetIntervalProfile',
+ 'NtStartProfile', 'ZwStartProfile', 'NtStopProfile', 'ZwStopProfile',
+ 'NtSystemDebugControl', 'ZwSystemDebugControl',
+
+ 'NtEnumerateBus', 'ZwEnumerateBus', 'NtFlushInstructionCache',
+ 'ZwFlushInstructionCache', 'NtFlushWriteBuffer', 'ZwFlushWriteBuffer',
+ 'NtSetLdtEntries', 'ZwSetLdtEntries',
+
+ 'NtGetPlugPlayEvent', 'ZwGetPlugPlayEvent', 'NtPlugPlayControl', 'ZwPlugPlayControl',
+
+ 'NtInitiatePowerAction', 'ZwInitiatePowerAction', 'NtPowerInformation',
+ 'ZwPowerInformation', 'NtRequestWakeupLatency', 'ZwRequestWakeupLatency',
+ 'NtSetSystemPowerState', 'ZwSetSystemPowerState', 'NtSetThreadExecutionState',
+ 'ZwSetThreadExecutionState',
+
+ 'NtLoadDriver', 'ZwLoadDriver', 'NtRegisterNewDevice', 'ZwRegisterNewDevice',
+ 'NtUnloadDriver', 'ZwUnloadDriver',
+
+ 'NtQueryDefaultLocale', 'ZwQueryDefaultLocale', 'NtQueryDefaultUILanguage',
+ 'ZwQueryDefaultUILanguage', 'NtQuerySystemEnvironmentValue',
+ 'ZwQuerySystemEnvironmentValue', 'NtSetDefaultLocale', 'ZwSetDefaultLocale',
+ 'NtSetDefaultUILanguage', 'ZwSetDefaultUILanguage', 'NtSetSystemEnvironmentValue',
+ 'ZwSetSystemEnvironmentValue',
+
+ 'DbgBreakPoint', 'DbgPrint', 'DbgPrompt', 'DbgSsHandleKmApiMsg', 'DbgSsInitialize',
+ 'DbgUiConnectToDbg', 'DbgUiContinue', 'DbgUiWaitStateChange', 'DbgUserBreakPoint',
+ 'KiRaiseUserExceptionDispatcher', 'KiUserApcDispatcher', 'KiUserCallbackDispatcher',
+ 'KiUserExceptionDispatcher', 'NlsAnsiCodePage', 'NlsMbCodePageTag',
+ 'NlsMbOemCodePageTag', 'NtAllocateLocallyUniqueId', 'ZwAllocateLocallyUniqueId',
+ 'NtAllocateUuids', 'ZwAllocateUuids', 'NtCallbackReturn', 'ZwCallbackReturn',
+ 'NtDisplayString', 'ZwDisplayString', 'NtQueryOleDirectoryFile',
+ 'ZwQueryOleDirectoryFile', 'NtQuerySection', 'ZwQuerySection',
+ 'NtQuerySystemInformation', 'ZwQuerySystemInformation', 'NtSetSystemInformation',
+ 'ZwSetSystemInformation', 'NtShutdownSystem', 'ZwShutdownSystem', 'NtVdmControl',
+ 'ZwVdmControl', 'NtW32Call', 'ZwW32Call', 'PfxFindPrefix', 'PfxInitialize',
+ 'PfxInsertPrefix', 'PfxRemovePrefix', 'PropertyLengthAsVariant', 'RestoreEm87Context',
+ 'SaveEm87Context'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '{', '}', '[', ']'),
+ 1 => array('<', '>','='),
+ 2 => array('+', '-', '*', '/', '%'),
+ 3 => array('!', '^', '&', '|'),
+ 4 => array('?', ':', ';')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #0000dd;',
+ 4 => 'color: #0000ff;',
+ 5 => 'color: #4000dd;',
+ 6 => 'color: #4000dd;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666;',
+ 2 => 'color: #339900;',
+ 3 => 'color: #FF0000;',
+ 4 => 'color: #FF0000;',
+ 'MULTI' => 'color: #ff0000; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #007788;',
+ 2 => 'color: #007788;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;',
+ 1 => 'color: #000080;',
+ 2 => 'color: #000040;',
+ 3 => 'color: #000040;',
+ 4 => 'color: #008080;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => 'http://www.google.com/search?q={FNAMEL}+msdn.microsoft.com',
+ 6 => 'http://www.google.com/search?q={FNAMEL}+msdn.microsoft.com'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_\|%\\-])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/cpp.php b/platform/www/vendor/geshi/geshi/src/geshi/cpp.php
new file mode 100644
index 0000000..348c7cf
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/cpp.php
@@ -0,0 +1,250 @@
+<?php
+/*************************************************************************************
+ * cpp.php
+ * -------
+ * Author: Dennis Bayer (Dennis.Bayer@mnifh-giessen.de)
+ * Contributors:
+ * - M. Uli Kusterer (witness.of.teachtext@gmx.net)
+ * - Jack Lloyd (lloyd@randombit.net)
+ * Copyright: (c) 2004 Dennis Bayer, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/09/27
+ *
+ * C++ language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2013/11/06
+ * - Added nullptr from c++11 & others
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/XX/XX (1.0.2)
+ * - Added several new keywords (Jack Lloyd)
+ * 2004/11/27 (1.0.1)
+ * - Added StdCLib function and constant names, changed color scheme to
+ * a cleaner one. (M. Uli Kusterer)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'C++',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Multiline-continued single-line comments
+ 1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Multiline-continued preprocessor define
+ 2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //C++ 11 string literal extensions
+ 3 => '/(?:L|u8?|U)(?=")/',
+ //C++ 11 string literal extensions (raw)
+ 4 => '/R"([^()\s\\\\]*)\((?:(?!\)\\1").)*\)\\1"/ms'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[abfnrtv\\\'\"?\n]#",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'break', 'case', 'continue', 'default', 'do', 'else', 'for', 'goto', 'if', 'return',
+ 'switch', 'throw', 'while'
+ ),
+ 2 => array(
+ 'NULL', 'false', 'true', 'enum', 'errno', 'EDOM',
+ 'ERANGE', 'FLT_RADIX', 'FLT_ROUNDS', 'FLT_DIG', 'DBL_DIG', 'LDBL_DIG',
+ 'FLT_EPSILON', 'DBL_EPSILON', 'LDBL_EPSILON', 'FLT_MANT_DIG', 'DBL_MANT_DIG',
+ 'LDBL_MANT_DIG', 'FLT_MAX', 'DBL_MAX', 'LDBL_MAX', 'FLT_MAX_EXP', 'DBL_MAX_EXP',
+ 'LDBL_MAX_EXP', 'FLT_MIN', 'DBL_MIN', 'LDBL_MIN', 'FLT_MIN_EXP', 'DBL_MIN_EXP',
+ 'LDBL_MIN_EXP', 'CHAR_BIT', 'CHAR_MAX', 'CHAR_MIN', 'SCHAR_MAX', 'SCHAR_MIN',
+ 'UCHAR_MAX', 'SHRT_MAX', 'SHRT_MIN', 'USHRT_MAX', 'INT_MAX', 'INT_MIN',
+ 'UINT_MAX', 'LONG_MAX', 'LONG_MIN', 'ULONG_MAX', 'HUGE_VAL', 'SIGABRT',
+ 'SIGFPE', 'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_ERR',
+ 'SIG_IGN', 'BUFSIZ', 'EOF', 'FILENAME_MAX', 'FOPEN_MAX', 'L_tmpnam',
+ 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX', 'stdin', 'stdout', 'stderr',
+ 'EXIT_FAILURE', 'EXIT_SUCCESS', 'RAND_MAX', 'CLOCKS_PER_SEC',
+ 'virtual', 'public', 'private', 'protected', 'template', 'using', 'namespace',
+ 'try', 'catch', 'inline', 'dynamic_cast', 'const_cast', 'reinterpret_cast',
+ 'static_cast', 'explicit', 'friend', 'typename', 'typeid', 'class', 'nullptr',
+ 'decltype', 'override', 'final', 'noexcept', 'alignas', 'alignof', 'noreturn',
+ 'constexpr', 'and', 'and_eq', 'asm', 'bitand', 'bitor', 'thread_local',
+ 'static_assert', 'compl', 'or', 'or_eq', 'xor', 'xor_eq', 'not', 'not_eq'
+ ),
+ 3 => array(
+ 'cin', 'cerr', 'clog', 'cout', 'delete', 'new', 'this', 'export',
+ 'printf', 'fprintf', 'snprintf', 'sprintf', 'assert',
+ 'isalnum', 'isalpha', 'isdigit', 'iscntrl', 'isgraph', 'islower', 'isprint',
+ 'ispunct', 'isspace', 'isupper', 'isxdigit', 'tolower', 'toupper',
+ 'exp', 'log', 'log10', 'pow', 'sqrt', 'ceil', 'floor', 'fabs', 'ldexp',
+ 'frexp', 'modf', 'fmod', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2',
+ 'sinh', 'cosh', 'tanh', 'setjmp', 'longjmp',
+ 'va_start', 'va_arg', 'va_end', 'offsetof', 'sizeof', 'fopen', 'freopen',
+ 'fflush', 'fclose', 'remove', 'rename', 'tmpfile', 'tmpname', 'setvbuf',
+ 'setbuf', 'vfprintf', 'vprintf', 'vsprintf', 'fscanf', 'scanf', 'sscanf',
+ 'fgetc', 'fgets', 'fputc', 'fputs', 'getc', 'getchar', 'gets', 'putc',
+ 'putchar', 'puts', 'ungetc', 'fread', 'fwrite', 'fseek', 'ftell', 'rewind',
+ 'fgetpos', 'fsetpos', 'clearerr', 'feof', 'ferror', 'perror', 'abs', 'labs',
+ 'div', 'ldiv', 'atof', 'atoi', 'atol', 'strtod', 'strtol', 'strtoul', 'calloc',
+ 'malloc', 'realloc', 'free', 'abort', 'exit', 'atexit', 'system', 'getenv',
+ 'bsearch', 'qsort', 'rand', 'srand', 'strcpy', 'strncpy', 'strcat', 'strncat',
+ 'strcmp', 'strncmp', 'strcoll', 'strchr', 'strrchr', 'strspn', 'strcspn',
+ 'strpbrk', 'strstr', 'strlen', 'strerror', 'strtok', 'strxfrm', 'memcpy',
+ 'memmove', 'memcmp', 'memchr', 'memset', 'clock', 'time', 'difftime', 'mktime',
+ 'asctime', 'ctime', 'gmtime', 'localtime', 'strftime'
+ ),
+ 4 => array(
+ 'auto', 'bool', 'char', 'char16_t', 'char32_t', 'const', 'double', 'float',
+ 'int', 'long', 'longint','register', 'short', 'shortint', 'signed',
+ 'static', 'struct', 'typedef', 'union', 'unsigned', 'void', 'volatile',
+ 'extern', 'jmp_buf','signal', 'raise', 'va_list', 'ptrdiff_t', 'size_t',
+ 'FILE', 'fpos_t', 'div_t', 'ldiv_t', 'clock_t', 'time_t', 'tm', 'wchar_t',
+ 'mutable',
+
+ 'int8', 'int16', 'int32', 'int64',
+ 'uint8', 'uint16', 'uint32', 'uint64',
+
+ 'int_fast8_t', 'int_fast16_t', 'int_fast32_t', 'int_fast64_t',
+ 'uint_fast8_t', 'uint_fast16_t', 'uint_fast32_t', 'uint_fast64_t',
+
+ 'int_least8_t', 'int_least16_t', 'int_least32_t', 'int_least64_t',
+ 'uint_least8_t', 'uint_least16_t', 'uint_least32_t', 'uint_least64_t',
+
+ 'int8_t', 'int16_t', 'int32_t', 'int64_t',
+ 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t',
+
+ 'intmax_t', 'uintmax_t', 'intptr_t', 'uintptr_t'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '{', '}', '[', ']'),
+ 1 => array('<', '>','='),
+ 2 => array('+', '-', '*', '/', '%'),
+ 3 => array('!', '^', '&', '|'),
+ 4 => array('?', ':', ';')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #0000dd;',
+ 4 => 'color: #0000ff;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666;',
+ 2 => 'color: #339900;',
+ 3 => 'color: #FF0000;',
+ 4 => 'color: #FF0000;',
+ 'MULTI' => 'color: #ff0000; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #007788;',
+ 2 => 'color: #007788;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;',
+ 1 => 'color: #000080;',
+ 2 => 'color: #000040;',
+ 3 => 'color: #000040;',
+ 4 => 'color: #008080;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_\|%\\-])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/csharp.php b/platform/www/vendor/geshi/geshi/src/geshi/csharp.php
new file mode 100644
index 0000000..da72167
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/csharp.php
@@ -0,0 +1,257 @@
+<?php
+/*************************************************************************************
+ * csharp.php
+ * ----------
+ * Author: Alan Juden (alan@judenware.org)
+ * Revised by: Michael Mol (mikemol@gmail.com)
+ * Copyright: (c) 2004 Alan Juden, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/04
+ *
+ * C# language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2015/04/14
+ * - Added C# 5.0 and 6.0 missing keywords and #pragma directive
+ * 2012/06/18 (1.0.8.11)
+ * - Added missing keywords (Christian Stelzmann)
+ * 2009/04/03 (1.0.8.6)
+ * - Added missing keywords identified by Rosetta Code users.
+ * 2008/05/25 (1.0.7.22)
+ * - Added highlighting of using and namespace directives as non-OOP
+ * 2005/01/05 (1.0.1)
+ * - Used hardquote support for @"..." strings (Cliff Stanford)
+ * 2004/11/27 (1.0.0)
+ * - Initial release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'C#',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Using and Namespace directives (basic support)
+ //Please note that the alias syntax for using is not supported
+ 3 => '/(?:(?<=using[\\n\\s])|(?<=namespace[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*[a-zA-Z0-9_]+[\n\s]*(?=[;=])/i'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'HARDQUOTE' => array('@"', '"'),
+ 'HARDESCAPE' => array('"'),
+ 'HARDCHAR' => '"',
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'abstract', 'add', 'as', 'async', 'await', 'base',
+ 'break', 'by', 'case', 'catch', 'const', 'continue',
+ 'default', 'do', 'else', 'event', 'explicit', 'extern', 'false',
+ 'finally', 'fixed', 'for', 'foreach', 'from', 'get', 'goto', 'group', 'if',
+ 'implicit', 'in', 'into', 'internal', 'join', 'lock', 'namespace', 'null',
+ 'operator', 'out', 'override', 'params', 'partial', 'private',
+ 'protected', 'public', 'readonly', 'remove', 'ref', 'return', 'sealed',
+ 'select', 'set', 'stackalloc', 'static', 'switch', 'this', 'throw', 'true',
+ 'try', 'unsafe', 'using', 'var', 'value', 'virtual', 'volatile', 'where',
+ 'while', 'yield'
+ ),
+ 2 => array(
+ '#elif', '#endif', '#endregion', '#else', '#error', '#define', '#if',
+ '#line', '#pragma', '#region', '#undef', '#warning'
+ ),
+ 3 => array(
+ 'checked', 'is', 'new', 'nameof', 'sizeof', 'typeof', 'unchecked'
+ ),
+ 4 => array(
+ 'bool', 'byte', 'char', 'class', 'decimal', 'delegate', 'double',
+ 'dynamic', 'enum', 'float', 'int', 'interface', 'long', 'object', 'sbyte',
+ 'short', 'string', 'struct', 'uint', 'ulong', 'ushort', 'void'
+ ),
+ 5 => array(
+ 'Microsoft.Win32',
+ 'System',
+ 'System.CodeDOM',
+ 'System.CodeDOM.Compiler',
+ 'System.Collections',
+ 'System.Collections.Bases',
+ 'System.ComponentModel',
+ 'System.ComponentModel.Design',
+ 'System.ComponentModel.Design.CodeModel',
+ 'System.Configuration',
+ 'System.Configuration.Assemblies',
+ 'System.Configuration.Core',
+ 'System.Configuration.Install',
+ 'System.Configuration.Interceptors',
+ 'System.Configuration.Schema',
+ 'System.Configuration.Web',
+ 'System.Core',
+ 'System.Data',
+ 'System.Data.ADO',
+ 'System.Data.Design',
+ 'System.Data.Internal',
+ 'System.Data.SQL',
+ 'System.Data.SQLTypes',
+ 'System.Data.XML',
+ 'System.Data.XML.DOM',
+ 'System.Data.XML.XPath',
+ 'System.Data.XML.XSLT',
+ 'System.Diagnostics',
+ 'System.Diagnostics.SymbolStore',
+ 'System.DirectoryServices',
+ 'System.Drawing',
+ 'System.Drawing.Design',
+ 'System.Drawing.Drawing2D',
+ 'System.Drawing.Imaging',
+ 'System.Drawing.Printing',
+ 'System.Drawing.Text',
+ 'System.Globalization',
+ 'System.IO',
+ 'System.IO.IsolatedStorage',
+ 'System.Messaging',
+ 'System.Net',
+ 'System.Net.Sockets',
+ 'System.NewXml',
+ 'System.NewXml.XPath',
+ 'System.NewXml.Xsl',
+ 'System.Reflection',
+ 'System.Reflection.Emit',
+ 'System.Resources',
+ 'System.Runtime.InteropServices',
+ 'System.Runtime.InteropServices.Expando',
+ 'System.Runtime.Remoting',
+ 'System.Runtime.Serialization',
+ 'System.Runtime.Serialization.Formatters',
+ 'System.Runtime.Serialization.Formatters.Binary',
+ 'System.Security',
+ 'System.Security.Cryptography',
+ 'System.Security.Cryptography.X509Certificates',
+ 'System.Security.Permissions',
+ 'System.Security.Policy',
+ 'System.Security.Principal',
+ 'System.ServiceProcess',
+ 'System.Text',
+ 'System.Text.RegularExpressions',
+ 'System.Threading',
+ 'System.Timers',
+ 'System.Web',
+ 'System.Web.Caching',
+ 'System.Web.Configuration',
+ 'System.Web.Security',
+ 'System.Web.Services',
+ 'System.Web.Services.Description',
+ 'System.Web.Services.Discovery',
+ 'System.Web.Services.Protocols',
+ 'System.Web.UI',
+ 'System.Web.UI.Design',
+ 'System.Web.UI.Design.WebControls',
+ 'System.Web.UI.Design.WebControls.ListControls',
+ 'System.Web.UI.HtmlControls',
+ 'System.Web.UI.WebControls',
+ 'System.WinForms',
+ 'System.WinForms.ComponentModel',
+ 'System.WinForms.Design',
+ 'System.Xml',
+ 'System.Xml.Serialization',
+ 'System.Xml.Serialization.Code',
+ 'System.Xml.Serialization.Schema'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '+', '-', '*', '?', '=', '/', '%', '&', '>', '<', '^', '!', ':', ';',
+ '(', ')', '{', '}', '[', ']', '|', '.'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0600FF; font-weight: bold;',
+ 2 => 'color: #FF8000; font-weight: bold;',
+ 3 => 'color: #008000;',
+ 4 => 'color: #6666cc; font-weight: bold;',
+ 5 => 'color: #000000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008080; font-style: italic;',
+ 2 => 'color: #008080;',
+ 3 => 'color: #008080;',
+ 'MULTI' => 'color: #008080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #008080; font-weight: bold;',
+ 'HARD' => 'color: #008080; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #666666;',
+ 'HARD' => 'color: #666666;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0000FF;',
+ 2 => 'color: #0000FF;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.google.com/search?q={FNAMEL}+msdn.microsoft.com',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#>|^])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_%\\-])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/css.php b/platform/www/vendor/geshi/geshi/src/geshi/css.php
new file mode 100644
index 0000000..15450ed
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/css.php
@@ -0,0 +1,944 @@
+<?php
+/*************************************************************************************
+ * css.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org), Zéfling (zefling@ikilote.net)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/18
+ *
+ * CSS language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2014/07/14 (1.0.8.13)
+ * - update for current CSS3 (properties, value, expression, unites & color)
+ * - remove pseudo class regex
+ * - add rules regex
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.3)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ * - Changed regexps to catch "-" symbols
+ * - Added support for URLs
+ * 2004/08/05 (1.0.1)
+ * - Added support for symbols
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Improve or drop regexps for class/id highlighting
+ * * Re-look at keywords - possibly to make several CSS language
+ * files, all with different versions of CSS in them
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'CSS',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ 2 => "/(?<=\\()\\s*(?:(?:[a-z0-9]+?:\\/\\/)?[a-z0-9_\\-\\.\\/:]+?)?[a-z]+?\\.[a-z]+?(\\?[^\)]+?)?\\s*?(?=\\))/i"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'"),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ //1 => "#\\\\[nfrtv\$\"\n\\\\]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\[\da-fA-F]{1,6}\s?#i",
+ //Unicode Char Specs
+ //3 => "#\\\\u[\da-fA-F]{1,8}#i",
+ ),
+ 'KEYWORDS' => array(
+ // properties
+ 1 => array(
+ 'align-content',
+ 'align-items',
+ 'align-self',
+ 'all',
+ 'animation',
+ 'animation-delay',
+ 'animation-direction',
+ 'animation-duration',
+ 'animation-fill-mode',
+ 'animation-iteration-count',
+ 'animation-name',
+ 'animation-play-state',
+ 'animation-timing-function',
+ 'backface-visibility',
+ 'background',
+ 'background-attachment',
+ 'background-blend-mode',
+ 'background-clip',
+ 'background-color',
+ 'background-image',
+ 'background-origin',
+ 'background-position',
+ 'background-repeat',
+ 'background-size',
+ 'border',
+ 'border-bottom',
+ 'border-bottom-color',
+ 'border-bottom-left-radius',
+ 'border-bottom-right-radius',
+ 'border-bottom-style',
+ 'border-bottom-width',
+ 'border-collapse',
+ 'border-color',
+ 'border-image',
+ 'border-image-outset',
+ 'border-image-repeat',
+ 'border-image-slice',
+ 'border-image-source',
+ 'border-image-width',
+ 'border-left',
+ 'border-left-color',
+ 'border-left-style',
+ 'border-left-width',
+ 'border-radius',
+ 'border-right',
+ 'border-right-color',
+ 'border-right-style',
+ 'border-right-width',
+ 'border-spacing',
+ 'border-style',
+ 'border-top',
+ 'border-top-color',
+ 'border-top-left-radius',
+ 'border-top-right-radius',
+ 'border-top-style',
+ 'border-top-width',
+ 'border-width',
+ 'bottom',
+ 'box-decoration-break',
+ 'box-shadow',
+ 'box-sizing',
+ 'break-after',
+ 'break-before',
+ 'break-inside',
+ 'caption-side',
+ 'clear',
+ 'clip',
+ 'clip-path',
+ 'color',
+ 'columns',
+ 'column-count',
+ 'column-fill',
+ 'column-gap',
+ 'column-rule',
+ 'column-rule-color',
+ 'column-rule-style',
+ 'column-rule-width',
+ 'column-span',
+ 'column-width',
+ 'content',
+ 'counter-increment',
+ 'counter-reset',
+ 'cursor',
+ 'direction',
+ 'display',
+ 'empty-cells',
+ 'fill',
+ 'fill-rule',
+ 'fill-opacity',
+ 'filter',
+ 'flex',
+ 'flex-basis',
+ 'flex-direction',
+ 'flex-flow',
+ 'flex-grow',
+ 'flex-shrink',
+ 'flex-wrap',
+ 'float',
+ 'font',
+ 'font-family',
+ 'font-feature-settings',
+ 'font-kerning',
+ 'font-language-override',
+ 'font-size',
+ 'font-size-adjust',
+ 'font-stretch',
+ 'font-style',
+ 'font-synthesis',
+ 'font-variant',
+ 'font-variant-alternates',
+ 'font-variant-caps',
+ 'font-variant-east-asian',
+ 'font-variant-ligatures',
+ 'font-variant-numeric',
+ 'font-variant-position',
+ 'font-weight',
+ 'grid',
+ 'grid-area',
+ 'grid-auto-columns',
+ 'grid-auto-flow',
+ 'grid-auto-position',
+ 'grid-auto-rows',
+ 'grid-column',
+ 'grid-column-start',
+ 'grid-column-end',
+ 'grid-row',
+ 'grid-row-start',
+ 'grid-row-end',
+ 'grid-template',
+ 'grid-template-areas',
+ 'grid-template-rows',
+ 'grid-template-columns',
+ 'height',
+ 'hyphens',
+ 'icon',
+ 'image-rendering',
+ 'image-resolution',
+ 'image-orientation',
+ 'ime-mode',
+ 'justify-content',
+ 'left',
+ 'letter-spacing',
+ 'line-break',
+ 'line-height',
+ 'list-style',
+ 'list-style-image',
+ 'list-style-position',
+ 'list-style-type',
+ 'margin',
+ 'margin-bottom',
+ 'margin-left',
+ 'margin-right',
+ 'margin-top',
+ 'marks',
+ 'mask',
+ 'mask-type',
+ 'max-height',
+ 'max-width',
+ 'min-height',
+ 'min-width',
+ 'mix-blend-mode',
+ 'nav-down',
+ 'nav-index',
+ 'nav-left',
+ 'nav-right',
+ 'nav-up',
+ 'object-fit',
+ 'object-position',
+ 'opacity',
+ 'order',
+ 'orphans',
+ 'outline',
+ 'outline-color',
+ 'outline-offset',
+ 'outline-style',
+ 'outline-width',
+ 'overflow',
+ 'overflow-wrap',
+ 'overflow-x',
+ 'overflow-y',
+ 'overflow-clip-box',
+ 'padding',
+ 'padding-bottom',
+ 'padding-left',
+ 'padding-right',
+ 'padding-top',
+ 'page-break-after',
+ 'page-break-before',
+ 'page-break-inside',
+ 'perspective',
+ 'perspective-origin',
+ 'pointer-events',
+ 'position',
+ 'quotes',
+ 'resize',
+ 'right',
+ 'shape-image-threshold',
+ 'shape-margin',
+ 'shape-outside',
+ 'stroke',
+ 'stroke-width',
+ 'stroke-linecap',
+ 'stroke-linejoin',
+ 'stroke-miterlimit',
+ 'stroke-dasharray',
+ 'stroke-dashoffset',
+ 'table-layout',
+ 'tab-size',
+ 'text-align',
+ 'text-align-last',
+ 'text-combine-horizontal',
+ 'text-decoration',
+ 'text-decoration-color',
+ 'text-decoration-line',
+ 'text-decoration-style',
+ 'text-indent',
+ 'text-orientation',
+ 'text-overflow',
+ 'text-rendering',
+ 'text-shadow',
+ 'text-transform',
+ 'text-underline-position',
+ 'top',
+ 'touch-action',
+ 'transform',
+ 'transform-origin',
+ 'transform-style',
+ 'transition',
+ 'transition-delay',
+ 'transition-duration',
+ 'transition-property',
+ 'transition-timing-function',
+ 'unicode-bidi',
+ 'unicode-range',
+ 'vertical-align',
+ 'visibility',
+ 'white-space',
+ 'widows',
+ 'width',
+ 'will-change',
+ 'word-break',
+ 'word-spacing',
+ 'word-wrap',
+ 'writing-mode',
+ 'z-index'
+ ),
+ // value
+ 2 => array(
+ 'absolute',
+ 'activeborder',
+ 'activecaption',
+ 'after-white-space',
+ 'ahead',
+ 'alternate',
+ 'always',
+ 'appworkspace',
+ 'armenian',
+ 'auto',
+ 'avoid',
+ 'background',
+ 'backwards',
+ 'baseline',
+ 'below',
+ 'bevel',
+ 'bidi-override',
+ 'blink',
+ 'block',
+ 'block clear',
+ 'block width',
+ 'block-axis',
+ 'bold',
+ 'bolder',
+ 'border',
+ 'border-box',
+ 'both',
+ 'bottom',
+ 'break-word',
+ 'butt',
+ 'button',
+ 'button-bevel',
+ 'buttonface',
+ 'buttonhighlight',
+ 'buttonshadow',
+ 'buttontext',
+ 'capitalize',
+ 'caption',
+ 'captiontext',
+ 'caret',
+ 'center',
+ 'checkbox',
+ 'circle',
+ 'cjk-ideographic',
+ 'clip',
+ 'close-quote',
+ 'collapse',
+ 'compact',
+ 'condensed',
+ 'content',
+ 'content-box',
+ 'continuous',
+ 'crop',
+ 'cross',
+ 'crosshair',
+ 'currentColor',
+ 'cursive',
+ 'dashed',
+ 'decimal',
+ 'decimal-leading-zero',
+ 'default',
+ 'disc',
+ 'discard',
+ 'dot-dash',
+ 'dot-dot-dash',
+ 'dotted',
+ 'double',
+ 'down',
+ 'e-resize',
+ 'element',
+ 'ellipsis',
+ 'embed',
+ 'end',
+ 'evenodd',
+ 'expanded',
+ 'extra-condensed',
+ 'extra-expanded',
+ 'fantasy',
+ 'fast',
+ 'fixed',
+ 'forwards',
+ 'georgian',
+ 'graytext',
+ 'groove',
+ 'hand',
+ 'hebrew',
+ 'help',
+ 'hidden',
+ 'hide',
+ 'higher',
+ 'highlight',
+ 'highlighttext',
+ 'hiragana',
+ 'hiragana-iroha',
+ 'horizontal',
+ 'icon',
+ 'ignore',
+ 'inactiveborder',
+ 'inactivecaption',
+ 'inactivecaptiontext',
+ 'infinite',
+ 'infobackground',
+ 'infotext',
+ 'inherit',
+ 'initial',
+ 'inline',
+ 'inline-axis',
+ 'inline-block',
+ 'inline-table',
+ 'inset',
+ 'inside',
+ 'intrinsic',
+ 'invert',
+ 'italic',
+ 'justify',
+ 'katakana',
+ 'katakana-iroha',
+ 'landscape',
+ 'large',
+ 'larger',
+ 'left',
+ 'level',
+ 'lighter',
+ 'line-through',
+ 'list-item',
+ 'listbox',
+ 'listitem',
+ 'logical',
+ 'loud',
+ 'lower',
+ 'lower-alpha',
+ 'lower-greek',
+ 'lower-latin',
+ 'lower-roman',
+ 'lowercase',
+ 'ltr',
+ 'marker',
+ 'match',
+ 'medium',
+ 'menu',
+ 'menulist',
+ 'menulist-button',
+ 'menulist-text',
+ 'menulist-textfield',
+ 'menutext',
+ 'message-box',
+ 'middle',
+ 'min-intrinsic',
+ 'miter',
+ 'mix',
+ 'monospace',
+ 'move',
+ 'multiple',
+ 'n-resize',
+ 'narrower',
+ 'ne-resize',
+ 'no-close',
+ 'no-close-quote',
+ 'no-open-quote',
+ 'no-repeat',
+ 'none',
+ 'nonzero',
+ 'normal',
+ 'nowrap',
+ 'nw-resize',
+ 'oblique',
+ 'once',
+ 'open-quote',
+ 'outset',
+ 'outside',
+ 'overline',
+ 'padding',
+ 'pointer',
+ 'portrait',
+ 'pre',
+ 'pre-line',
+ 'pre-wrap',
+ 'push-button',
+ 'radio',
+ 'read-only',
+ 'read-write',
+ 'read-write-plaintext-only',
+ 'relative',
+ 'repeat',
+ 'repeat-x',
+ 'repeat-y',
+ 'reverse',
+ 'ridge',
+ 'right',
+ 'round',
+ 'rtl',
+ 'run-in',
+ 's-resize',
+ 'sans-serif',
+ 'scroll',
+ 'scrollbar',
+ 'scrollbarbutton-down',
+ 'scrollbarbutton-left',
+ 'scrollbarbutton-right',
+ 'scrollbarbutton-up',
+ 'scrollbargripper-horizontal',
+ 'scrollbargripper-vertical',
+ 'scrollbarthumb-horizontal',
+ 'scrollbarthumb-vertical',
+ 'scrollbartrack-horizontal',
+ 'scrollbartrack-vertical',
+ 'se-resize',
+ 'searchfield',
+ 'searchfield-close',
+ 'searchfield-results',
+ 'semi-condensed',
+ 'semi-expanded',
+ 'separate',
+ 'serif',
+ 'show',
+ 'single',
+ 'skip-white-space',
+ 'slide',
+ 'slider-horizontal',
+ 'slider-vertical',
+ 'sliderthumb-horizontal',
+ 'sliderthumb-vertical',
+ 'slow',
+ 'small',
+ 'small-caps',
+ 'small-caption',
+ 'smaller',
+ 'solid',
+ 'space',
+ 'square',
+ 'square-button',
+ 'start',
+ 'static',
+ 'status-bar',
+ 'stretch',
+ 'sub',
+ 'super',
+ 'sw-resize',
+ 'table',
+ 'table-caption',
+ 'table-cell',
+ 'table-column',
+ 'table-column-group',
+ 'table-footer-group',
+ 'table-header-group',
+ 'table-row',
+ 'table-row-group',
+ 'text',
+ 'text-bottom',
+ 'text-top',
+ 'textfield',
+ 'thick',
+ 'thin',
+ 'threeddarkshadow',
+ 'threedface',
+ 'threedhighlight',
+ 'threedlightshadow',
+ 'threedshadow',
+ 'top',
+ 'ultra-condensed',
+ 'ultra-expanded',
+ 'underline',
+ 'unfurl',
+ 'up',
+ 'upper-alpha',
+ 'upper-latin',
+ 'upper-roman',
+ 'uppercase',
+ 'vertical',
+ 'visible',
+ 'visual',
+ 'w-resize',
+ 'wait',
+ 'wave',
+ 'wider',
+ 'window',
+ 'windowframe',
+ 'windowtext',
+ 'x-large',
+ 'x-small',
+ 'xx-large',
+ 'xx-small'
+ ),
+ // function xxx()
+ 3 => array(
+ 'attr',
+ 'calc',
+ 'contrast',
+ 'cross-fade',
+ 'cubic-bezier',
+ 'cycle',
+ 'device-cmyk',
+ 'drop-shadow',
+ 'ellipse',
+ 'hsl',
+ 'hsla',
+ 'hwb',
+ 'image',
+ 'matrix',
+ 'matrix3d',
+ 'minmax',
+ 'grayscale',
+ 'perspective',
+ 'polygon',
+ 'radial-gradient',
+ 'translate',
+ 'translatex',
+ 'translatey',
+ 'translatez',
+ 'translate3d',
+ 'skew',
+ 'skewx',
+ 'skewy',
+ 'saturate',
+ 'sepia',
+ 'scale',
+ 'scalex',
+ 'scaley',
+ 'scalez',
+ 'scale3d',
+ 'steps',
+ 'rect',
+ 'repeating-linear-gradient',
+ 'repeating-radial-gradient',
+ 'rgb',
+ 'rgba',
+ 'rotate',
+ 'rotatex',
+ 'rotatey',
+ 'rotatez',
+ 'rotate3d',
+ 'url',
+ 'var'
+ ),
+ // colors
+ 4 => array(
+ 'aliceblue',
+ 'antiquewhite',
+ 'aqua',
+ 'aquamarine',
+ 'azure',
+ 'beige',
+ 'bisque',
+ 'black',
+ 'blanchedalmond',
+ 'blue',
+ 'blueviolet',
+ 'brown',
+ 'burlywood',
+ 'cadetblue',
+ 'chartreuse',
+ 'chocolate',
+ 'coral',
+ 'cornflowerblue',
+ 'cornsilk',
+ 'crimson',
+ 'cyan',
+ 'darkblue',
+ 'darkcyan',
+ 'darkgoldenrod',
+ 'darkgray',
+ 'darkgreen',
+ 'darkgrey',
+ 'darkkhaki',
+ 'darkmagenta',
+ 'darkolivegreen',
+ 'darkorange',
+ 'darkorchid',
+ 'darkred',
+ 'darksalmon',
+ 'darkseagreen',
+ 'darkslateblue',
+ 'darkslategray',
+ 'darkslategrey',
+ 'darkturquoise',
+ 'darkviolet',
+ 'deeppink',
+ 'deepskyblue',
+ 'dimgray',
+ 'dimgrey',
+ 'dodgerblue',
+ 'firebrick',
+ 'floralwhite',
+ 'forestgreen',
+ 'fuchsia',
+ 'gainsboro',
+ 'ghostwhite',
+ 'gold',
+ 'goldenrod',
+ 'gray',
+ 'green',
+ 'greenyellow',
+ 'grey',
+ 'honeydew',
+ 'hotpink',
+ 'indianred',
+ 'indigo',
+ 'ivory',
+ 'khaki',
+ 'lavender',
+ 'lavenderblush',
+ 'lawngreen',
+ 'lemonchiffon',
+ 'lightblue',
+ 'lightcoral',
+ 'lightcyan',
+ 'lightgoldenrodyellow',
+ 'lightgray',
+ 'lightgreen',
+ 'lightgrey',
+ 'lightpink',
+ 'lightsalmon',
+ 'lightseagreen',
+ 'lightskyblue',
+ 'lightslategray',
+ 'lightslategrey',
+ 'lightsteelblue',
+ 'lightyellow',
+ 'lime',
+ 'limegreen',
+ 'linen',
+ 'magenta',
+ 'maroon',
+ 'mediumaquamarine',
+ 'mediumblue',
+ 'mediumorchid',
+ 'mediumpurple',
+ 'mediumseagreen',
+ 'mediumslateblue',
+ 'mediumspringgreen',
+ 'mediumturquoise',
+ 'mediumvioletred',
+ 'midnightblue',
+ 'mintcream',
+ 'mistyrose',
+ 'moccasin',
+ 'navajowhite',
+ 'navy',
+ 'oldlace',
+ 'olive',
+ 'olivedrab',
+ 'orange',
+ 'orangered',
+ 'orchid',
+ 'palegoldenrod',
+ 'palegreen',
+ 'paleturquoise',
+ 'palevioletred',
+ 'papayawhip',
+ 'peachpuff',
+ 'peru',
+ 'pink',
+ 'plum',
+ 'powderblue',
+ 'purple',
+ 'rebeccapurple',
+ 'red',
+ 'rosybrown',
+ 'royalblue',
+ 'saddlebrown',
+ 'salmon',
+ 'sandybrown',
+ 'seagreen',
+ 'seashell',
+ 'sienna',
+ 'silver',
+ 'skyblue',
+ 'slateblue',
+ 'slategray',
+ 'slategrey',
+ 'snow',
+ 'springgreen',
+ 'steelblue',
+ 'tan',
+ 'teal',
+ 'thistle',
+ 'transparent',
+ 'tomato',
+ 'turquoise',
+ 'violet',
+ 'wheat',
+ 'white',
+ 'whitesmoke',
+ 'yellow',
+ 'yellowgreen'
+ ),
+ // pseudo class
+ 5 => array(
+ 'active',
+ 'after',
+ 'before',
+ 'checked',
+ 'choices',
+ 'dir',
+ 'disabled',
+ 'empty',
+ 'enabled',
+ 'first',
+ 'first-child',
+ 'first-letter',
+ 'first-line',
+ 'first-of-type',
+ 'focus',
+ 'fullscreen',
+ 'hover',
+ 'indeterminate',
+ 'in-range',
+ 'invalid',
+ 'lang',
+ 'last-child',
+ 'last-of-type',
+ 'link',
+ 'not',
+ 'nth-child',
+ 'nth-last-child',
+ 'nth-last-of-type',
+ 'nth-of-type',
+ 'only-child',
+ 'only-of-type',
+ 'optional',
+ 'out-of-range',
+ 'repeat-index',
+ 'repeat-item',
+ 'required',
+ 'root',
+ 'scope',
+ 'selection',
+ 'target',
+ 'valid',
+ 'value',
+ 'visited'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', ':', ';',
+ '>', '+', '*', ',', '^', '='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #993333;',
+ 3 => 'color: #9932cc;',
+ 4 => 'color: #dc143c;',
+ 5 => 'color: #F5758F;',
+ ),
+ 'COMMENTS' => array(
+ 2 => 'color: #ff0000; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ //1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #000099; font-weight: bold;'
+ //3 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #00AA00;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(),
+ 'SYMBOLS' => array(
+ 0 => 'color: #00AA00;'
+ ),
+ 'SCRIPT' => array(),
+ 'REGEXPS' => array(
+ 0 => 'color: #cc00cc;',
+ 1 => 'color: #6666ff;',
+ 2 => 'color: #3F84D9; font-weight: bold;',
+ 3 => 'color: #933;',
+ 4 => 'color: #444;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ //DOM Node ID
+ 0 => '\#[a-zA-Z0-9\-_]+(?:\\\\:[a-zA-Z0-9\-_]+)*',
+ //CSS classname
+ 1 => '\.(?!\d)[a-zA-Z0-9\-_]+(?:\\\\:[a-zA-Z0-9\-_]+)*\b(?=[\{\.#\s,:].|<\|)',
+ //CSS rules
+ 2 => '\@(?!\d)[a-zA-Z0-9\-_]+(?:\\\\:[a-zA-Z0-9\-_]+)*\b(?=[\{\.#\s,:].|<\|)',
+ //Measurements
+ 3 => '[+\-]?(\d+|(\d*\.\d+))(em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx|%)',
+ //var
+ 4 => '(--[a-zA-Z0-9\-]*)'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_AFTER' => '(?![\-a-zA-Z0-9_\|%\\-&\.])',
+ 'DISALLOWED_BEFORE' => '(?<![\-a-zA-Z0-9_\|%\\~&\.])',
+ 1 => array(
+ 'DISALLOWED_AFTER' => '(?![\-a-zA-Z0-9_\|%\\-&\.])(?=\s*:)'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/cuesheet.php b/platform/www/vendor/geshi/geshi/src/geshi/cuesheet.php
new file mode 100644
index 0000000..c9724f5
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/cuesheet.php
@@ -0,0 +1,136 @@
+<?php
+/*************************************************************************************
+ * cuesheet.php
+ * ----------
+ * Author: Benny Baumann (benbe@geshi.org)
+ * Copyright: (c) 2009 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/12/21
+ *
+ * Cuesheet language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/12/21 (1.0.8.6)
+ * - First Release
+ *
+ * TODO (updated 2009/12/21)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Cuesheet',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ //Single-Line Comments using REM command
+ 1 => "/(?<=\bREM\b).*?$/im",
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'CATALOG','CDTEXTFILE','FILE','FLAGS','INDEX','ISRC','PERFORMER',
+ 'POSTGAP','PREGAP','REM','SONGWRITER','TITLE','TRACK'
+ ),
+ 2 => array(
+ 'AIFF', 'BINARY', 'MOTOROLA', 'MP3', 'WAVE'
+ ),
+ 3 => array(
+ '4CH', 'DCP', 'PRE', 'SCMS'
+ ),
+ 4 => array(
+ 'AUDIO', 'CDG', 'MODE1/2048', 'MODE1/2336', 'MODE2/2336',
+ 'MODE2/2352', 'CDI/2336', 'CDI/2352'
+ )
+ ),
+ 'SYMBOLS' => array(
+ ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000066; font-weight: bold;',
+ 3 => 'color: #000066; font-weight: bold;',
+ 4 => 'color: #000066; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080;',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #006600;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #000099;',
+ 2 => 'color: #009900;',
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://digitalx.org/cuesheetsyntax.php#{FNAMEL}',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 2 => '\b[A-Za-z0-9]{5}\d{7}\b',
+ 1 => '(?<=[\s:]|^)\d+(?=[\s:]|$)',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 2,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => '(?<![\w\.])',
+ 'DISALLOWED_AFTER' => '(?![\w\.])',
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/d.php b/platform/www/vendor/geshi/geshi/src/geshi/d.php
new file mode 100644
index 0000000..2f0e352
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/d.php
@@ -0,0 +1,250 @@
+<?php
+/*************************************************************************************
+ * d.php
+ * -----
+ * Author: Thomas Kuehne (thomas@kuehne.cn)
+ * Contributors:
+ * - Jimmy Cao
+ * Copyright: (c) 2005 Thomas Kuehne (http://thomas.kuehne.cn/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/04/22
+ *
+ * D language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2011/06/28 (0.0.3) (Jimmy Cao)
+ * - added D2 features
+ * 2005/04/22 (0.0.2)
+ * - added _d_* and sizeof/ptrdiff_t
+ * 2005/04/20 (0.0.1)
+ * - First release
+ *
+ * TODO (updated 2005/04/22)
+ * -------------------------
+ * * nested comments
+ * * correct handling of r"" and ``
+ * * correct handling of ... and ..
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'D',
+ 'COMMENT_SINGLE' => array(2 => '///', 1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/', '/+' => '+/'),
+ 'COMMENT_REGEXP' => array(
+ // doxygen comments
+ 3 => '#/\*\*(?![\*\/]).*\*/#sU',
+ // raw strings
+ 4 => '#r"[^"]*"#s',
+ // Script Style interpreter comment
+ 5 => "/\A#!(?=\\/).*?$/m"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'"),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[abfnrtv\\'\"?\n\\\\]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#",
+ //Named entity escapes
+ /*6 => "#\\\\&(?:quot|amp|lt|gt|OElig|oelig|Scaron|scaron|Yuml|circ|tilde|".
+ "ensp|emsp|thinsp|zwnj|zwj|lrm|rlm|ndash|mdash|lsquo|rsquo|sbquo|".
+ "ldquo|rdquo|bdquo|dagger|Dagger|permil|lsaquo|rsaquo|euro|nbsp|".
+ "iexcl|cent|pound|curren|yen|brvbar|sect|uml|copy|ordf|laquo|not|".
+ "shy|reg|macr|deg|plusmn|sup2|sup3|acute|micro|para|middot|cedil|".
+ "sup1|ordm|raquo|frac14|frac12|frac34|iquest|Agrave|Aacute|Acirc|".
+ "Atilde|Auml|Aring|AElig|Ccedil|Egrave|Eacute|Ecirc|Euml|Igrave|".
+ "Iacute|Icirc|Iuml|ETH|Ntilde|Ograve|Oacute|Ocirc|Otilde|Ouml|".
+ "times|Oslash|Ugrave|Uacute|Ucirc|Uuml|Yacute|THORN|szlig|agrave|".
+ "aacute|acirc|atilde|auml|aring|aelig|ccedil|egrave|eacute|ecirc|".
+ "euml|igrave|iacute|icirc|iuml|eth|ntilde|ograve|oacute|ocirc|".
+ "otilde|ouml|divide|oslash|ugrave|uacute|ucirc|uuml|yacute|thorn|".
+ "yuml|fnof|Alpha|Beta|Gamma|Delta|Epsilon|Zeta|Eta|Theta|Iota|".
+ "Kappa|Lambda|Mu|Nu|Xi|Omicron|Pi|Rho|Sigma|Tau|Upsilon|Phi|Chi|".
+ "Psi|Omega|alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|".
+ "kappa|lambda|mu|nu|xi|omicron|pi|rho|sigmaf|sigma|tau|upsilon|".
+ "phi|chi|psi|omega|thetasym|upsih|piv|bull|hellip|prime|Prime|".
+ "oline|frasl|weierp|image|real|trade|alefsym|larr|uarr|rarr|darr|".
+ "harr|crarr|lArr|uArr|rArr|dArr|hArr|forall|part|exist|empty|".
+ "nabla|isin|notin|ni|prod|sum|minus|lowast|radic|prop|infin|ang|".
+ "and|or|cap|cup|int|there4|sim|cong|asymp|ne|equiv|le|ge|sub|sup|".
+ "nsub|sube|supe|oplus|otimes|perp|sdot|lceil|rceil|lfloor|rfloor|".
+ "lang|rang|loz|spades|clubs|hearts|diams);#",*/
+ // optimized:
+ 6 => "#\\\\&(?:A(?:Elig|acute|circ|grave|lpha|ring|tilde|uml)|Beta|".
+ "C(?:cedil|hi)|D(?:agger|elta)|E(?:TH|acute|circ|grave|psilon|ta|uml)|".
+ "Gamma|I(?:acute|circ|grave|ota|uml)|Kappa|Lambda|Mu|N(?:tilde|u)|".
+ "O(?:Elig|acute|circ|grave|m(?:ega|icron)|slash|tilde|uml)|".
+ "P(?:hi|i|rime|si)|Rho|S(?:caron|igma)|T(?:HORN|au|heta)|".
+ "U(?:acute|circ|grave|psilon|uml)|Xi|Y(?:acute|uml)|Zeta|".
+ "a(?:acute|c(?:irc|ute)|elig|grave|l(?:efsym|pha)|mp|n[dg]|ring|".
+ "symp|tilde|uml)|b(?:dquo|eta|rvbar|ull)|c(?:ap|cedil|e(?:dil|nt)|".
+ "hi|irc|lubs|o(?:ng|py)|rarr|u(?:p|rren))|d(?:Arr|a(?:gger|rr)|".
+ "e(?:g|lta)|i(?:ams|vide))|e(?:acute|circ|grave|m(?:pty|sp)|nsp|".
+ "psilon|quiv|t[ah]|u(?:ml|ro)|xist)|f(?:nof|orall|ra(?:c(?:1[24]|34)|sl))|".
+ "g(?:amma|e|t)|h(?:Arr|arr|e(?:arts|llip))|i(?:acute|circ|excl|grave|mage|".
+ "n(?:fin|t)|ota|quest|sin|uml)|kappa|l(?:Arr|a(?:mbda|ng|quo|rr)|ceil|".
+ "dquo|e|floor|o(?:wast|z)|rm|s(?:aquo|quo)|t)|m(?:acr|dash|".
+ "i(?:cro|ddot|nus)|u)|n(?:abla|bsp|dash|e|i|ot(?:in)?|sub|tilde|u)|".
+ "o(?:acute|circ|elig|grave|line|m(?:ega|icron)|plus|r(?:d[fm])?|".
+ "slash|ti(?:lde|mes)|uml)|p(?:ar[at]|er(?:mil|p)|hi|iv?|lusmn|ound|".
+ "r(?:ime|o[dp])|si)|quot|r(?:Arr|a(?:dic|ng|quo|rr)|ceil|dquo|e(?:al|g)|".
+ "floor|ho|lm|s(?:aquo|quo))|s(?:bquo|caron|dot|ect|hy|i(?:gmaf?|m)|".
+ "pades|u(?:be?|m|p[123e]?)|zlig)|t(?:au|h(?:e(?:re4|ta(?:sym)?)|insp|".
+ "orn)|i(?:lde|mes)|rade)|u(?:Arr|a(?:cute|rr)|circ|grave|ml|".
+ "psi(?:h|lon)|uml)|weierp|xi|y(?:acute|en|uml)|z(?:eta|w(?:j|nj)));#",
+ ),
+ 'HARDQUOTE' => array('`', '`'),
+ 'HARDESCAPE' => array(),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'break', 'case', 'continue', 'do', 'else',
+ 'for', 'foreach', 'goto', 'if', 'return',
+ 'switch', 'while', 'foreach_reverse'
+ ),
+ 2 => array(
+ 'alias', 'asm', 'assert', 'body', 'cast',
+ 'catch', 'default', 'delegate', 'delete',
+ 'extern', 'false', 'finally', 'function',
+ 'import', 'in', 'inout',
+ 'invariant', 'is', 'lazy', 'mixin', 'module', 'new',
+ 'null', 'out', 'pragma', 'ref', 'super', 'this',
+ 'throw', 'true', 'try', 'typeid',
+ 'typeof', 'union', 'with', 'scope'
+ ),
+ 3 => array(
+ 'ClassInfo', 'Error', 'Exception',
+ 'Interface', 'Object', 'IMonitor',
+ 'OffsetTypeInfo', 'Throwable',
+ 'TypeInfo_Class', 'TypeInfo', '__traits',
+ '__EOF__', '__FILE__', '__LINE__',
+ ),
+ 4 => array(
+ 'abstract', 'align', 'auto', 'bit', 'bool',
+ 'byte', 'cdouble', 'cfloat', 'char',
+ 'class', 'const', 'creal', 'dchar', 'dstring', 'debug',
+ 'deprecated', 'double', 'enum', 'export',
+ 'final', 'float', 'idouble', 'ifloat', 'immutable', 'int',
+ 'interface', 'ireal', 'long', 'nothrow', 'override',
+ 'package', 'private', 'protected', 'ptrdiff_t',
+ 'public', 'real', 'short', 'shared', 'size_t',
+ 'static', 'string', 'struct', 'synchronized',
+ 'template', 'ubyte', 'ucent', 'uint',
+ 'ulong', 'unittest', 'ushort', 'version',
+ 'void', 'volatile', 'wchar', 'wstring',
+ '__gshared', '@disable', '@property', 'pure', 'safe'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '?', '!', ';', ':', ',', '...', '..',
+ '+', '-', '*', '/', '%', '&', '|', '^', '<', '>', '=', '~',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #aaaadd; font-weight: bold;',
+ 4 => 'color: #993333;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #009933; font-style: italic;',
+ 3 => 'color: #009933; font-style: italic;',
+ 4 => 'color: #ff0000;',
+ 5 => 'color: #0040ff;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 6 => 'color: #666699; font-weight: bold; font-style: italic;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ 'HARD' => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/dart.php b/platform/www/vendor/geshi/geshi/src/geshi/dart.php
new file mode 100644
index 0000000..4d1d824
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/dart.php
@@ -0,0 +1,159 @@
+<?php
+/*************************************************************************************
+ * dart.php
+ * --------
+ * Author: Edward Hart (edward.dan.hart@gmail.com)
+ * Copyright: (c) 2013 Edward Hart
+ * Release Version: 1.0.9.1
+ * Date Started: 2013/10/25
+ *
+ * Dart language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2013/10/25
+ * - First Release
+ *
+ * TODO (updated 2013/10/25)
+ * -------------------------
+ * - Highlight standard library types.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Dart',
+
+ 'COMMENT_SINGLE' => array('//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(),
+
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[\\\\nrfbtv\'\"?\n]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ 4 => "#\\\\u\\{[\da-fA-F]*\\}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE |
+ GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'abstract', 'as', 'assert', 'break', 'case', 'catch', 'class',
+ 'const', 'continue', 'default', 'do', 'dynamic', 'else', 'export',
+ 'extends', 'external', 'factory', 'false', 'final', 'finally',
+ 'for', 'get', 'if', 'implements', 'import', 'in', 'is', 'library',
+ 'new', 'null', 'operator', 'part', 'return', 'set', 'static',
+ 'super', 'switch', 'this', 'throw', 'true', 'try', 'typedef', 'var',
+ 'while', 'with'
+ ),
+ 2 => array(
+ 'double', 'bool', 'int', 'num', 'void'
+ ),
+ ),
+
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '{', '}', '[', ']'),
+ 1 => array('+', '-', '*', '/', '%', '~'),
+ 2 => array('&', '|', '^'),
+ 3 => array('=', '!', '<', '>'),
+ 4 => array('?', ':'),
+ 5 => array('..'),
+ 6 => array(';', ',')
+ ),
+
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ ),
+
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'font-weight: bold;',
+ 2 => 'color: #445588; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #999988; font-style: italic;',
+ 'MULTI' => 'color: #999988; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => ''
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #d14;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #009999;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'BRACKETS' => array(''),
+ 'METHODS' => array(
+ 1 => 'color: #006633;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'font-weight: bold;',
+ 1 => 'font-weight: bold;',
+ 2 => 'font-weight: bold;',
+ 3 => 'font-weight: bold;',
+ 4 => 'font-weight: bold;',
+ 5 => 'font-weight: bold;',
+ 6 => 'font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/dcl.php b/platform/www/vendor/geshi/geshi/src/geshi/dcl.php
new file mode 100644
index 0000000..6607744
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/dcl.php
@@ -0,0 +1,190 @@
+<?php
+/*************************************************************************************
+ * dcl.php
+ * --------
+ * Author: Petr Hendl (petr@hendl.cz)
+ * Copyright: (c) 2011 Petr Hendl http://hendl.cz/geshi/
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/02/17
+ *
+ * DCL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2011-02-17 (1.0.8.11)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'DCL',
+ 'COMMENT_SINGLE' => array('$!', '!'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 2 => '/(?<=\$)\s*sql\s+.*?(?:quit|exit);?\s*?$/sim' // do not highlight inline sql
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'HARDESCAPE' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ 1 => "/''[a-zA-Z\\-_]+'/"
+ ),
+ 'KEYWORDS' => array(
+ 1 => array( // commands
+ 'ACCOUNTING', 'ALLOCATE', 'ANALYZE', 'APPEND', 'ASSIGN', 'ATTACH', 'BACKUP',
+ 'CALL', 'CANCEL', 'CHECKSUM', 'CLOSE', 'CONNECT', 'CONTINUE', 'CONVERT',
+ 'COPY', 'CREATE', 'DEALLOCATE', 'DEASSIGN', 'DEBUG', 'DECK',
+ 'DECRYPT', 'DEFINE', 'DELETE', 'DEPOSIT', 'DIFFERENCES', 'DIRECTORY',
+ 'DISABLE', 'AUTOSTART', 'DISCONNECT', 'DISMOUNT', 'DUMP', 'EDIT', 'ENABLE',
+ 'ENCRYPT', 'ENDSUBROUTINE', 'EOD', 'EOJ', 'EXAMINE', 'EXCHANGE',
+ 'EXIT', 'FONT', 'GOSUB', 'GOTO', 'HELP', 'IF', 'THEN', 'ELSE', 'ENDIF', 'INITIALIZE', 'INQUIRE',
+ 'INSTALL', 'JAVA', 'JOB', 'LIBRARY', 'LICENSE', 'LINK', 'LOGIN', 'LOGOUT',
+ 'MACRO', 'MAIL', 'MERGE', 'MESSAGE', 'MONITOR', 'MOUNT', 'NCS', 'ON', 'OPEN',
+ 'PASSWORD', 'PATCH', 'PHONE', 'PIPE', 'PPPD', 'PRINT', 'PRODUCT', 'PURGE',
+ 'READ', 'RECALL', 'RENAME', 'REPLY', 'REQUEST', 'RETURN', 'RMU', 'RUN', 'RUNOFF',
+ 'SEARCH', 'SET', 'SET AUDIT', 'SET BOOTBLOCK', 'SET BROADCAST',
+ 'SET CACHE', 'SET CARD_READER', 'SET CLUSTER', 'SET COMMAND', 'SET CONTROL',
+ 'SET CPU', 'SET DAY', 'SET DEFAULT', 'SET DEVICE', 'SET DIRECTORY',
+ 'SET DISPLAY', 'SET ENTRY', 'SET FILE', 'SET HOST', 'SET IMAGE', 'SET KEY',
+ 'SET LOGINS', 'SET MAGTAPE', 'SET MESSAGE', 'SET NETWORK', 'SET ON', 'SET OUTPUT_RATE',
+ 'SET PASSWORD', 'SET PREFERRED_PATH', 'SET PREFIX', 'SET PRINTER', 'SET PROCESS',
+ 'SET PROMPT', 'SET PROTECTION', 'SET QUEUE', 'SET RESTART_VALUE',
+ 'SET RIGHTS_LIST', 'SET RMS_DEFAULT', 'SET ROOT', 'SET SECURITY',
+ 'SET SERVER ACME_SERVER', 'SET SERVER REGISTRY_SERVER', 'SET SERVER SECURITY_SERVER',
+ 'SET SHADOW', 'SET SYMBOL', 'SET TERMINAL', 'SET TIME', 'SET VERIFY',
+ 'SET VOLUME', 'SET WORKING_SET', 'SHOW', 'SHOW AUDIT',
+ 'SHOW BROADCAST', 'SHOW CLUSTER', 'SHOW CPU', 'SHOW DEFAULT', 'SHOW DEVICES',
+ 'SHOW DISPLAY', 'SHOW ENTRY', 'SHOW ERROR', 'SHOW FASTPATH', 'SHOW IMAGE',
+ 'SHOW INTRUSION', 'SHOW KEY', 'SHOW LICENSE', 'SHOW LOGICAL', 'SHOW MEMORY',
+ 'SHOW NETWORK', 'SHOW PRINTER', 'SHOW PROCESS', 'SHOW PROTECTION', 'SHOW QUEUE',
+ 'SHOW QUOTA', 'SHOW RMS_DEFAULT', 'SHOW ROOT', 'SHOW SECURITY',
+ 'SHOW SERVER ACME_SERVER', 'SHOW SERVER REGISTRY_SERVER', 'SHOW SHADOW',
+ 'SHOW STATUS', 'SHOW SYMBOL', 'SHOW SYSTEM', 'SHOW TERMINAL', 'SHOW TIME',
+ 'SHOW TRANSLATION', 'SHOW USERS', 'SHOW WORKING_SET', 'SHOW ZONE', 'SORT',
+ 'SPAWN', 'START', 'STOP', 'SUBMIT', 'SUBROUTINE', 'SYNCHRONIZE', 'TYPE',
+ 'UNLOCK', 'VIEW', 'WAIT', 'WRITE', 'XAUTH'
+ ),
+ 2 => array( // lexical functions
+ 'F$CONTEXT', 'F$CSID', 'F$CUNITS', 'F$CVSI', 'F$CVTIME', 'F$CVUI',
+ 'F$DELTA_TIME', 'F$DEVICE', 'F$DIRECTORY', 'F$EDIT', 'F$ELEMENT',
+ 'F$ENVIRONMENT', 'F$EXTRACT', 'F$FAO', 'F$FID_TO_NAME', 'F$FILE_ATTRIBUTES',
+ 'F$GETDVI', 'F$GETENV', 'F$GETJPI', 'F$GETQUI', 'F$GETSYI', 'F$IDENTIFIER',
+ 'F$INTEGER', 'F$LENGTH', 'F$LICENSE', 'F$LOCATE', 'F$MATCH_WILD', 'F$MESSAGE',
+ 'F$MODE', 'F$MULTIPATH', 'F$PARSE', 'F$PID', 'F$PRIVILEGE', 'F$PROCESS',
+ 'F$SEARCH', 'F$SETPRV', 'F$STRING', 'F$TIME', 'F$TRNLNM', 'F$TYPE', 'F$UNIQUE',
+ 'F$USER', 'F$VERIFY'
+ ),
+ 3 => array( // special variables etc
+ 'sql$database', 'P1', 'P2', 'P3', 'P4', 'P5', 'P6', 'P7', 'P8', 'P9',
+ '$status', '$severity', 'sys$login', 'sys$system',
+ 'sys$input', 'sys$output', 'sys$pipe'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '@', '&', '|', '<', '>', '-',
+ '.eqs.', '.eq.', '.lt.', '.lts.', '.gt.', '.gts.', '.ne.', '.nes.',
+ '.le.', '.ge.', '.ges.', '.les.',
+ '.EQS.', '.EQ.', '.LT.', '.LTS.', '.GT.', '.GTS.', '.NE.', '.NES.',
+ '.LE.', '.GE.', '.GES.', '.LES.',
+ '.and.', '.or.', '.not.',
+ '.AND.', '.OR.', '.NOT.',
+ '==', ':==', '=', ':='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #0066FF;',
+ 3 => 'color: #993300;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #666666; font-style: italic;',
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #9999FF; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #006666;',
+ 1 => 'color: #0099FF;',
+ 2 => 'color: red;',
+ 3 => 'color: #007800;',
+ 4 => 'color: #007800;',
+ 5 => 'color: #780078;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #7a0874; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0099FF;', // variables
+ 1 => 'color: #0000FF;', // qualifiers
+ 2 => 'color: #FF6600; font-weight: bold;' // labels
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ // variables
+ 0 => "'[a-zA-Z_\\-$]+'",
+ // qualifiers and parameters
+ 1 => "(?:\/[a-zA-Z_\/]+)[\s=]",
+ // labels
+ 2 => '(?<=\$)\s*[a-zA-Z\-_]+:'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'COMMENTS' => array(
+ ),
+ 'KEYWORDS' => array(
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/dcpu16.php b/platform/www/vendor/geshi/geshi/src/geshi/dcpu16.php
new file mode 100644
index 0000000..b5dbb2f
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/dcpu16.php
@@ -0,0 +1,129 @@
+<?php
+/*************************************************************************************
+ * dcpu16.php
+ * -------
+ * Author: Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2007-2014 Benny Baumann (http://geshi.org/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/04/12
+ *
+ * DCPU/16 Assembly language file for GeSHi.
+ * Syntax definition based on http://0x10c.com/doc/dcpu-16.txt
+ *
+ * CHANGES
+ * -------
+ * 2012/04/12 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2012/04/12)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'DCPU-16 Assembly',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'NUMBERS' => GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_HEX_PREFIX,
+ 'KEYWORDS' => array(
+ /*CPU*/
+ 1 => array(
+ 'set','add','sub','mul','div','mod','shl','shr','and','bor','xor',
+ 'ife','ifn','ifg','ifb',
+ 'jsr'
+ ),
+ /*registers*/
+ 2 => array(
+ 'a','b','c','x','y','z','i','j',
+ 'pc','sp','o',
+ 'pop','peek','push' //Special cases with DCPU-16
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '+', '-', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000088; font-weight:bold;',
+ 2 => 'color: #0000ff;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000088;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #880000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'REGEXPS' => array(
+ 2 => 'color: #993333;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://0x10c.com/doc/dcpu-16.txt',
+ 2 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Hex numbers
+ //0 => '0[0-9a-fA-F]{1,32}[hH]',
+ //Binary numbers
+ //1 => '\%[01]{1,64}|[01]{1,64}[bB]?(?![^<]*>)',
+ //Labels
+ 2 => '^:[_a-zA-Z][_a-zA-Z0-9]?(?=\s|$)'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#\/])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_\|%\\-])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/dcs.php b/platform/www/vendor/geshi/geshi/src/geshi/dcs.php
new file mode 100644
index 0000000..72b0c37
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/dcs.php
@@ -0,0 +1,180 @@
+<?php
+/*************************************************************************************
+ * dcs.php
+ * ---------------------------------
+ * Author: Stelio Passaris (GeSHi@stelio.net)
+ * Copyright: (c) 2009 Stelio Passaris (http://stelio.net/stiki/GeSHi)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/01/20
+ *
+ * DCS language file for GeSHi.
+ *
+ * DCS (Data Conversion System) is part of Sungard iWorks' Prophet suite and is used
+ * to convert external data files into a format that Prophet and Glean can read.
+ * See http://www.prophet-web.com/Products/DCS for product information.
+ * This language file is current for DCS version 7.3.2.
+ *
+ * Note that the DCS IDE does not handle escape characters correctly. The IDE thinks
+ * that a backslash '\' is an escape character, but in practice the backslash does
+ * not escape the string delimiter character '"' when the program runs. A '\\' is
+ * escaped to '\' when the program runs, but '\"' is treated as '\' at the end of a
+ * string. Therefore in this language file, we do not recognise the backslash as an
+ * escape character. For the purposes of GeSHi, there is no character escaping.
+ *
+ * CHANGES
+ * -------
+ * 2009/02/21 (1.0.8.3)
+ * - First Release
+ *
+ * TODO (updated 2009/02/21)
+ * -------------------------
+ * * Add handling for embedded C code. Note that the DCS IDE does not highlight C code
+ * correctly, but that doesn't mean that we can't! This will be included for a
+ * stable release of GeSHi of version 1.1.x (or later) that allows for highlighting
+ * embedded code using that code's appropriate language file.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'DCS',
+ 'COMMENT_SINGLE' => array(
+ 1 => ';'
+ ),
+ 'COMMENT_MULTI' => array(
+ ),
+ 'COMMENT_REGEXP' => array(
+ // Highlight embedded C code in a separate color:
+ 2 => '/\bINSERT_C_CODE\b.*?\bEND_C_CODE\b/ims'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array(
+ '"'
+ ),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => '',
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'abs', 'ascii_value', 'bit_value', 'blank_date', 'calc_unit_values', 'cm',
+ 'complete_months', 'complete_years', 'correct', 'create_input_file', 'cy',
+ 'date_convert', 'day', 'del_output_separator',
+ 'delete_existing_output_files', 'div', 'ex', 'exact_years', 'exp',
+ 'extract_date', 'failed_validation', 'file_number', 'first_record',
+ 'fract', 'fund_fac_a', 'fund_fac_b', 'fund_fac_c', 'fund_fac_d',
+ 'fund_fac_e', 'fund_fac_f', 'fund_fac_g', 'fund_fac_h', 'fund_fac_i',
+ 'fund_fac_j', 'fund_fac_k', 'fund_fac_l', 'fund_fac_m', 'fund_fac_n',
+ 'fund_fac_o', 'fund_fac_p', 'fund_fac_q', 'fund_fac_r', 'fund_fac_s',
+ 'fund_fac_t', 'fund_fac_u', 'fund_fac_v', 'fund_fac_w', 'fund_fac_x',
+ 'fund_fac_y', 'fund_fac_z', 'group', 'group_record',
+ 'input_file_date_time', 'input_file_extension', 'input_file_location',
+ 'input_file_name', 'int', 'invalid', 'last_record', 'leap_year', 'len',
+ 'ln', 'log', 'main_format_name', 'max', 'max_num_subrecords', 'message',
+ 'min', 'mod', 'month', 'months_add', 'months_sub', 'nearest_months',
+ 'nearest_years', 'next_record', 'nm', 'no_of_current_records',
+ 'no_of_records', 'numval', 'ny', 'output', 'output_array_as_constants',
+ 'output_file_path', 'output_record', 'pmdf_output', 'previous', 'rand',
+ 're_start', 'read_generic_table', 'read_generic_table_text',
+ 'read_input_footer', 'read_input_footer_text', 'read_input_header',
+ 'read_input_header_text', 'record_count', 'record_suppressed', 'round',
+ 'round_down', 'round_near', 'round_up', 'run_dcs_program', 'run_parameter',
+ 'run_parameter_text', 'set_main_record', 'set_num_subrecords',
+ 'sort_array', 'sort_current_records', 'sort_input', 'strval', 'substr',
+ 'summarise', 'summarise_record', 'summarise_units',
+ 'summarise_units_record', 'suppress_record', 'table_correct',
+ 'table_validate', 'terminate', 'time', 'today', 'trim', 'ubound', 'year',
+ 'years_add', 'years_sub'
+ ),
+ 2 => array(
+ 'and', 'as', 'begin', 'boolean', 'byref', 'byval', 'call', 'case', 'date',
+ 'default', 'do', 'else', 'elseif', 'end_c_code', 'endfor', 'endfunction',
+ 'endif', 'endproc', 'endswitch', 'endwhile', 'eq',
+ 'explicit_declarations', 'false', 'for', 'from', 'function', 'ge', 'gt',
+ 'if', 'insert_c_code', 'integer', 'le', 'loop', 'lt', 'ne', 'not',
+ 'number', 'or', 'private', 'proc', 'public', 'quitloop', 'return',
+ 'short', 'step', 'switch', 'text', 'then', 'to', 'true', 'while'
+ ),
+ 3 => array(
+ // These keywords are not highlighted by the DCS IDE but we may as well
+ // keep track of them anyway:
+ 'mp_file', 'odbc_file'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']',
+ '=', '<', '>',
+ '+', '-', '*', '/', '^',
+ ':', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: red;',
+ 2 => 'color: blue;',
+ 3 => 'color: black;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: black; background-color: silver;',
+ // Colors for highlighting embedded C code:
+ 2 => 'color: maroon; background-color: pink;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: black;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: green;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: green;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: black;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ ),
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/delphi.php b/platform/www/vendor/geshi/geshi/src/geshi/delphi.php
new file mode 100644
index 0000000..3533f62
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/delphi.php
@@ -0,0 +1,299 @@
+<?php
+/*************************************************************************************
+ * delphi.php
+ * ----------
+ * Author: J�rja Norbert (jnorbi@vipmail.hu), Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2004 J�rja Norbert, Benny Baumann (BenBE@omorphia.de), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/07/26
+ *
+ * Delphi (Object Pascal) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2012/06/27 (1.0.8.11)
+ * - Added some keywords
+ * - fixed hex numbers and hex char literals (including WideChar)
+ * - Added support for FPC-Style generics
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2005/11/19 (1.0.3)
+ * - Updated the very incomplete keyword and type lists
+ * 2005/09/03 (1.0.2)
+ * - Added support for hex numbers and string entities
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Delphi',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('(*' => '*)', '{' => '}'),
+ //Compiler directives
+ 'COMMENT_REGEXP' => array(2 => '/\\{\\$.*?}|\\(\\*\\$.*?\\*\\)/U'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'"),
+ 'ESCAPE_CHAR' => '',
+
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'Abstract', 'And', 'Array', 'As', 'Asm', 'At', 'Begin', 'Case',
+ 'Class', 'Const', 'Constructor', 'Contains', 'Default', 'delayed', 'Destructor',
+ 'DispInterface', 'Div', 'Do', 'DownTo', 'Else', 'End', 'Except',
+ 'Export', 'Exports', 'External', 'File', 'Finalization', 'Finally', 'For',
+ 'Function', 'Generic', 'Goto', 'If', 'Implementation', 'In', 'Inherited',
+ 'Initialization', 'Inline', 'Interface', 'Is', 'Label', 'Library', 'Message',
+ 'Mod', 'Nil', 'Not', 'Object', 'Of', 'On', 'Or', 'Overload', 'Override',
+ 'Package', 'Packed', 'Private', 'Procedure', 'Program', 'Property',
+ 'Protected', 'Public', 'Published', 'Read', 'Raise', 'Record', 'Register',
+ 'Repeat', 'Requires', 'Resourcestring', 'Set', 'Shl', 'Shr', 'Specialize', 'Stored',
+ 'Then', 'ThreadVar', 'To', 'Try', 'Type', 'Unit', 'Until', 'Uses', 'Var',
+ 'Virtual', 'While', 'With', 'Write', 'Xor', 'assembler', 'far',
+ 'near', 'pascal', 'cdecl', 'safecall', 'stdcall', 'varargs'
+ ),
+ 2 => array(
+ 'false', 'self', 'true',
+ ),
+ 3 => array(
+ 'Abs', 'AcquireExceptionObject', 'Addr', 'AnsiToUtf8', 'Append', 'ArcTan',
+ 'Assert', 'AssignFile', 'Assigned', 'BeginThread', 'BlockRead',
+ 'BlockWrite', 'Break', 'ChDir', 'Chr', 'Close', 'CloseFile',
+ 'CompToCurrency', 'CompToDouble', 'Concat', 'Continue', 'Copy', 'Cos',
+ 'Dec', 'Delete', 'Dispose', 'DoubleToComp', 'EndThread', 'EnumModules',
+ 'EnumResourceModules', 'Eof', 'Eoln', 'Erase', 'ExceptAddr',
+ 'ExceptObject', 'Exclude', 'Exit', 'Exp', 'FilePos', 'FileSize',
+ 'FillChar', 'Finalize', 'FindClassHInstance', 'FindHInstance',
+ 'FindResourceHInstance', 'Flush', 'Frac', 'FreeMem', 'Get8087CW',
+ 'GetDir', 'GetLastError', 'GetMem', 'GetMemoryManager',
+ 'GetModuleFileName', 'GetVariantManager', 'Halt', 'Hi', 'High',
+ 'IOResult', 'Inc', 'Include', 'Initialize', 'Insert', 'Int',
+ 'IsMemoryManagerSet', 'IsVariantManagerSet', 'Length', 'Ln', 'Lo', 'Low',
+ 'MkDir', 'Move', 'New', 'Odd', 'OleStrToStrVar', 'OleStrToString', 'Ord',
+ 'PUCS4Chars', 'ParamCount', 'ParamStr', 'Pi', 'Pos', 'Pred', 'Ptr',
+ 'Random', 'Randomize', 'Read', 'ReadLn', 'ReallocMem',
+ 'ReleaseExceptionObject', 'Rename', 'Reset', 'Rewrite', 'RmDir', 'Round',
+ 'RunError', 'Seek', 'SeekEof', 'SeekEoln', 'Set8087CW', 'SetLength',
+ 'SetLineBreakStyle', 'SetMemoryManager', 'SetString', 'SetTextBuf',
+ 'SetVariantManager', 'Sin', 'SizeOf', 'Slice', 'Sqr', 'Sqrt', 'Str',
+ 'StringOfChar', 'StringToOleStr', 'StringToWideChar', 'Succ', 'Swap',
+ 'Trunc', 'Truncate', 'TypeInfo', 'UCS4StringToWideString', 'UTF8Decode',
+ 'UTF8Encode', 'UnicodeToUtf8', 'UniqueString', 'UpCase', 'Utf8ToAnsi',
+ 'Utf8ToUnicode', 'Val', 'VarArrayRedim', 'VarClear',
+ 'WideCharLenToStrVar', 'WideCharLenToString', 'WideCharToStrVar',
+ 'WideCharToString', 'WideStringToUCS4String', 'Write', 'WriteLn',
+
+ 'Abort', 'AddExitProc', 'AddTerminateProc', 'AdjustLineBreaks', 'AllocMem',
+ 'AnsiCompareFileName', 'AnsiCompareStr', 'AnsiCompareText',
+ 'AnsiDequotedStr', 'AnsiExtractQuotedStr', 'AnsiLastChar',
+ 'AnsiLowerCase', 'AnsiLowerCaseFileName', 'AnsiPos', 'AnsiQuotedStr',
+ 'AnsiSameStr', 'AnsiSameText', 'AnsiStrComp', 'AnsiStrIComp',
+ 'AnsiStrLComp', 'AnsiStrLIComp', 'AnsiStrLastChar', 'AnsiStrLower',
+ 'AnsiStrPos', 'AnsiStrRScan', 'AnsiStrScan', 'AnsiStrUpper',
+ 'AnsiUpperCase', 'AnsiUpperCaseFileName', 'AppendStr', 'AssignStr',
+ 'Beep', 'BoolToStr', 'ByteToCharIndex', 'ByteToCharLen', 'ByteType',
+ 'CallTerminateProcs', 'ChangeFileExt', 'CharLength', 'CharToByteIndex',
+ 'CharToByteLen', 'CompareMem', 'CompareStr', 'CompareText', 'CreateDir',
+ 'CreateGUID', 'CurrToStr', 'CurrToStrF', 'CurrentYear', 'Date',
+ 'DateTimeToFileDate', 'DateTimeToStr', 'DateTimeToString',
+ 'DateTimeToSystemTime', 'DateTimeToTimeStamp', 'DateToStr', 'DayOfWeek',
+ 'DecodeDate', 'DecodeDateFully', 'DecodeTime', 'DeleteFile',
+ 'DirectoryExists', 'DiskFree', 'DiskSize', 'DisposeStr', 'EncodeDate',
+ 'EncodeTime', 'ExceptionErrorMessage', 'ExcludeTrailingBackslash',
+ 'ExcludeTrailingPathDelimiter', 'ExpandFileName', 'ExpandFileNameCase',
+ 'ExpandUNCFileName', 'ExtractFileDir', 'ExtractFileDrive',
+ 'ExtractFileExt', 'ExtractFileName', 'ExtractFilePath',
+ 'ExtractRelativePath', 'ExtractShortPathName', 'FileAge', 'FileClose',
+ 'FileCreate', 'FileDateToDateTime', 'FileExists', 'FileGetAttr',
+ 'FileGetDate', 'FileIsReadOnly', 'FileOpen', 'FileRead', 'FileSearch',
+ 'FileSeek', 'FileSetAttr', 'FileSetDate', 'FileSetReadOnly', 'FileWrite',
+ 'FinalizePackage', 'FindClose', 'FindCmdLineSwitch', 'FindFirst',
+ 'FindNext', 'FloatToCurr', 'FloatToDateTime', 'FloatToDecimal',
+ 'FloatToStr', 'FloatToStrF', 'FloatToText', 'FloatToTextFmt',
+ 'FmtLoadStr', 'FmtStr', 'ForceDirectories', 'Format', 'FormatBuf',
+ 'FormatCurr', 'FormatDateTime', 'FormatFloat', 'FreeAndNil',
+ 'GUIDToString', 'GetCurrentDir', 'GetEnvironmentVariable',
+ 'GetFileVersion', 'GetFormatSettings', 'GetLocaleFormatSettings',
+ 'GetModuleName', 'GetPackageDescription', 'GetPackageInfo', 'GetTime',
+ 'IncAMonth', 'IncMonth', 'IncludeTrailingBackslash',
+ 'IncludeTrailingPathDelimiter', 'InitializePackage', 'IntToHex',
+ 'IntToStr', 'InterlockedDecrement', 'InterlockedExchange',
+ 'InterlockedExchangeAdd', 'InterlockedIncrement', 'IsDelimiter',
+ 'IsEqualGUID', 'IsLeapYear', 'IsPathDelimiter', 'IsValidIdent',
+ 'Languages', 'LastDelimiter', 'LoadPackage', 'LoadStr', 'LowerCase',
+ 'MSecsToTimeStamp', 'NewStr', 'NextCharIndex', 'Now', 'OutOfMemoryError',
+ 'QuotedStr', 'RaiseLastOSError', 'RaiseLastWin32Error', 'RemoveDir',
+ 'RenameFile', 'ReplaceDate', 'ReplaceTime', 'SafeLoadLibrary',
+ 'SameFileName', 'SameText', 'SetCurrentDir', 'ShowException', 'Sleep',
+ 'StrAlloc', 'StrBufSize', 'StrByteType', 'StrCat', 'StrCharLength',
+ 'StrComp', 'StrCopy', 'StrDispose', 'StrECopy', 'StrEnd', 'StrFmt',
+ 'StrIComp', 'StrLCat', 'StrLComp', 'StrLCopy', 'StrLFmt', 'StrLIComp',
+ 'StrLen', 'StrLower', 'StrMove', 'StrNew', 'StrNextChar', 'StrPCopy',
+ 'StrPLCopy', 'StrPas', 'StrPos', 'StrRScan', 'StrScan', 'StrToBool',
+ 'StrToBoolDef', 'StrToCurr', 'StrToCurrDef', 'StrToDate', 'StrToDateDef',
+ 'StrToDateTime', 'StrToDateTimeDef', 'StrToFloat', 'StrToFloatDef',
+ 'StrToInt', 'StrToInt64', 'StrToInt64Def', 'StrToIntDef', 'StrToTime',
+ 'StrToTimeDef', 'StrUpper', 'StringReplace', 'StringToGUID', 'Supports',
+ 'SysErrorMessage', 'SystemTimeToDateTime', 'TextToFloat', 'Time',
+ 'TimeStampToDateTime', 'TimeStampToMSecs', 'TimeToStr', 'Trim',
+ 'TrimLeft', 'TrimRight', 'TryEncodeDate', 'TryEncodeTime',
+ 'TryFloatToCurr', 'TryFloatToDateTime', 'TryStrToBool', 'TryStrToCurr',
+ 'TryStrToDate', 'TryStrToDateTime', 'TryStrToFloat', 'TryStrToInt',
+ 'TryStrToInt64', 'TryStrToTime', 'UnloadPackage', 'UpperCase',
+ 'WideCompareStr', 'WideCompareText', 'WideFmtStr', 'WideFormat',
+ 'WideFormatBuf', 'WideLowerCase', 'WideSameStr', 'WideSameText',
+ 'WideUpperCase', 'Win32Check', 'WrapText',
+
+ 'ActivateClassGroup', 'AllocateHwnd', 'BinToHex', 'CheckSynchronize',
+ 'CollectionsEqual', 'CountGenerations', 'DeallocateHwnd', 'EqualRect',
+ 'ExtractStrings', 'FindClass', 'FindGlobalComponent', 'GetClass',
+ 'GroupDescendantsWith', 'HexToBin', 'IdentToInt',
+ 'InitInheritedComponent', 'IntToIdent', 'InvalidPoint',
+ 'IsUniqueGlobalComponentName', 'LineStart', 'ObjectBinaryToText',
+ 'ObjectResourceToText', 'ObjectTextToBinary', 'ObjectTextToResource',
+ 'PointsEqual', 'ReadComponentRes', 'ReadComponentResEx',
+ 'ReadComponentResFile', 'Rect', 'RegisterClass', 'RegisterClassAlias',
+ 'RegisterClasses', 'RegisterComponents', 'RegisterIntegerConsts',
+ 'RegisterNoIcon', 'RegisterNonActiveX', 'SmallPoint', 'StartClassGroup',
+ 'TestStreamFormat', 'UnregisterClass', 'UnregisterClasses',
+ 'UnregisterIntegerConsts', 'UnregisterModuleClasses',
+ 'WriteComponentResFile',
+
+ 'ArcCos', 'ArcCosh', 'ArcCot', 'ArcCotH', 'ArcCsc', 'ArcCscH', 'ArcSec',
+ 'ArcSecH', 'ArcSin', 'ArcSinh', 'ArcTan2', 'ArcTanh', 'Ceil',
+ 'CompareValue', 'Cosecant', 'Cosh', 'Cot', 'CotH', 'Cotan', 'Csc', 'CscH',
+ 'CycleToDeg', 'CycleToGrad', 'CycleToRad', 'DegToCycle', 'DegToGrad',
+ 'DegToRad', 'DivMod', 'DoubleDecliningBalance', 'EnsureRange', 'Floor',
+ 'Frexp', 'FutureValue', 'GetExceptionMask', 'GetPrecisionMode',
+ 'GetRoundMode', 'GradToCycle', 'GradToDeg', 'GradToRad', 'Hypot',
+ 'InRange', 'IntPower', 'InterestPayment', 'InterestRate',
+ 'InternalRateOfReturn', 'IsInfinite', 'IsNan', 'IsZero', 'Ldexp', 'LnXP1',
+ 'Log10', 'Log2', 'LogN', 'Max', 'MaxIntValue', 'MaxValue', 'Mean',
+ 'MeanAndStdDev', 'Min', 'MinIntValue', 'MinValue', 'MomentSkewKurtosis',
+ 'NetPresentValue', 'Norm', 'NumberOfPeriods', 'Payment', 'PeriodPayment',
+ 'Poly', 'PopnStdDev', 'PopnVariance', 'Power', 'PresentValue',
+ 'RadToCycle', 'RadToDeg', 'RadToGrad', 'RandG', 'RandomRange', 'RoundTo',
+ 'SLNDepreciation', 'SYDDepreciation', 'SameValue', 'Sec', 'SecH',
+ 'Secant', 'SetExceptionMask', 'SetPrecisionMode', 'SetRoundMode', 'Sign',
+ 'SimpleRoundTo', 'SinCos', 'Sinh', 'StdDev', 'Sum', 'SumInt',
+ 'SumOfSquares', 'SumsAndSquares', 'Tan', 'Tanh', 'TotalVariance',
+ 'Variance'
+ ),
+ 4 => array(
+ 'AnsiChar', 'AnsiString', 'Bool', 'Boolean', 'Byte', 'ByteBool', 'Cardinal', 'Char',
+ 'Comp', 'Currency', 'DWORD', 'Double', 'Extended', 'Int64', 'Integer', 'IUnknown',
+ 'LongBool', 'LongInt', 'LongWord', 'PAnsiChar', 'PAnsiString', 'PBool', 'PBoolean', 'PByte',
+ 'PByteArray', 'PCardinal', 'PChar', 'PComp', 'PCurrency', 'PDWORD', 'PDate', 'PDateTime',
+ 'PDouble', 'PExtended', 'PInt64', 'PInteger', 'PLongInt', 'PLongWord', 'Pointer', 'PPointer',
+ 'PShortInt', 'PShortString', 'PSingle', 'PSmallInt', 'PString', 'PHandle', 'PVariant', 'PWord',
+ 'PWordArray', 'PWordBool', 'PWideChar', 'PWideString', 'Real', 'Real48', 'ShortInt', 'ShortString',
+ 'Single', 'SmallInt', 'String', 'TClass', 'TDate', 'TDateTime', 'TextFile', 'THandle',
+ 'TObject', 'TTime', 'Variant', 'WideChar', 'WideString', 'Word', 'WordBool'
+ ),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '[', ']'),
+ 1 => array('.', ',', ':', ';'),
+ 2 => array('@', '^'),
+ 3 => array('=', '+', '-', '*', '/')
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #000066; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #008000; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #ff0000; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000cc;',
+ 1 => 'color: #ff0000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066;',
+ 1 => 'color: #000066;',
+ 2 => 'color: #000066;',
+ 3 => 'color: #000066;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ //Hex numbers
+ 0 => '(?<!\#)\$[0-9a-fA-F]+(?!\w)',
+ //Characters
+ 1 => '\#(?:\$[0-9a-fA-F]{1,4}|\d{1,5})'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 2,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 3 => array(
+ 'DISALLOWED_AFTER' => '(?=\s*[(;])'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/diff.php b/platform/www/vendor/geshi/geshi/src/geshi/diff.php
new file mode 100644
index 0000000..b630be2
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/diff.php
@@ -0,0 +1,194 @@
+<?php
+/*************************************************************************************
+ * diff.php
+ * --------
+ * Author: Conny Brunnkvist (conny@fuchsia.se), W. Tasin (tasin@fhm.edu)
+ * Copyright: (c) 2004 Fuchsia Open Source Solutions (http://www.fuchsia.se/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/12/29
+ *
+ * Diff-output language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2006/02/27
+ * - changing language file to use matching of start (^) and end ($) (wt)
+ * 2004/12/29 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2006/02/27)
+ * -------------------------
+ *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+
+$language_data = array (
+ 'LANG_NAME' => 'Diff',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => ' ',
+ 'KEYWORDS' => array(
+ 1 => array(
+ '\ No newline at end of file'
+ ),
+// 2 => array(
+// '***************' /* This only seems to works in some cases? */
+// ),
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'CASE_SENSITIVE' => array(
+ 1 => false,
+// 2 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #aaaaaa; font-style: italic;',
+// 2 => 'color: #dd6611;',
+ ),
+ 'COMMENTS' => array(
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => ''
+ ),
+ 'STRINGS' => array(
+ 0 => ''
+ ),
+ 'NUMBERS' => array(
+ 0 => ''
+ ),
+ 'METHODS' => array(
+ 0 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => ''
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #440088;',
+ 1 => 'color: #991111;',
+ 2 => 'color: #00b000;',
+ 3 => 'color: #888822;',
+ 4 => 'color: #888822;',
+ 5 => 'color: #0011dd;',
+ 6 => 'color: #440088;',
+ 7 => 'color: #991111;',
+ 8 => 'color: #00b000;',
+ 9 => 'color: #888822;',
+ ),
+ ),
+ 'URLS' => array(
+ 1 => '',
+// 2 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ 0 => "[0-9,]+[acd][0-9,]+",
+ //Removed lines
+ 1 => array(
+ GESHI_SEARCH => '(^|(?<=\A\s))\\&lt;.*$',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ //Inserted lines
+ 2 => array(
+ GESHI_SEARCH => '(^|(?<=\A\s))\\&gt;.*$',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ //Location line
+ 3 => array(
+ GESHI_SEARCH => '(^|(?<=\A\s))-{3}\\s.*$',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ //Inserted line
+ 4 => array(
+ GESHI_SEARCH => '(^|(?<=\A\s))(\\+){3}\\s.*$',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ //Modified line
+ 5 => array(
+ GESHI_SEARCH => '(^|(?<=\A\s))\\!.*$',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ //File specification
+ 6 => array(
+ GESHI_SEARCH => '(^|(?<=\A\s))[\\@]{2}.*$',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ //Removed line
+ 7 => array(
+ GESHI_SEARCH => '(^|(?<=\A\s))\\-.*$',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ //Inserted line
+ 8 => array(
+ GESHI_SEARCH => '(^|(?<=\A\s))\\+.*$',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ //File specification
+ 9 => array(
+ GESHI_SEARCH => '(^|(?<=\A\s))(\\*){3}\\s.*$',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/div.php b/platform/www/vendor/geshi/geshi/src/geshi/div.php
new file mode 100644
index 0000000..6740724
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/div.php
@@ -0,0 +1,124 @@
+<?php
+/*************************************************************************************
+ * div.php
+ * ---------------------------------
+ * Author: Gabriel Lorenzo (ermakina@gmail.com)
+ * Copyright: (c) 2005 Gabriel Lorenzo (http://ermakina.gazpachito.net)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/06/19
+ *
+ * DIV language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/06/22 (1.0.0)
+ * - First Release, includes "2nd gen" ELSEIF statement
+ *
+ * TODO (updated 2005/06/22)
+ * -------------------------
+ * - I'm pretty satisfied with this, so nothing for now... :P
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'DIV',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'while','until','to','switch','step','return','repeat','loop','if','from','frame','for','end','elseif',
+ 'else','default','debug','continue','clone','case','break','begin'
+ ),
+ 2 => array(
+ 'xor','whoami','type','sizeof','pointer','or','offset','not','neg','mod','id','dup','and','_ne','_lt',
+ '_le','_gt','_ge','_eq'
+ ),
+ 3 => array(
+ 'setup_program','program','process','private','local','import','global','function','const',
+ 'compiler_options'
+ ),
+ 4 => array(
+ 'word','struct','string','int','byte'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(',')','[',']','=','+','-','*','/','!','%','^','&',':',';',',','<','>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0040b1;',
+ 2 => 'color: #000000;',
+ 3 => 'color: #000066; font-weight: bold;',
+ 4 => 'color: #993333;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #44aa44;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #202020;',
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #44aa44;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/dos.php b/platform/www/vendor/geshi/geshi/src/geshi/dos.php
new file mode 100644
index 0000000..1a4ebb7
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/dos.php
@@ -0,0 +1,225 @@
+<?php
+/*************************************************************************************
+ * dos.php
+ * -------
+ * Author: Alessandro Staltari (staltari@geocities.com)
+ * Copyright: (c) 2005 Alessandro Staltari (http://www.geocities.com/SiliconValley/Vista/8155/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/07/05
+ *
+ * DOS language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2005/07/05 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2005/07/05)
+ * -------------------------
+ *
+ * - Highlight pipes and redirection (do we really need this?)
+ * - Add missing keywords.
+ * - Find a good hyperlink for keywords.
+ * - Improve styles.
+ *
+ * KNOWN ISSUES (updated 2005/07/07)
+ * ---------------------------------
+ *
+ * - Doesn't even try to handle spaces in variables name or labels (I can't
+ * find a reliable way to establish if a sting is a name or not, in some
+ * cases it depends on the contex or enviroment status).
+ * - Doesn't handle %%[letter] pseudo variable used inside FOR constructs
+ * (it should be done only into its scope: how to handle variable it?).
+ * - Doesn't handle %~[something] pseudo arguments.
+ * - If the same keyword is placed at the end of the line and the
+ * beginning of the next, the second occourrence is not highlighted
+ * (this should be a GeSHi bug, not related to the language definition).
+ * - I can't avoid to have keyword highlighted even when they are not used
+ * as keywords but, for example, as arguments to the echo command.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'DOS',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ //DOS comment lines
+ 'COMMENT_REGEXP' => array(
+ 1 => "/^\s*@?REM\b.*$/mi",
+ 2 => "/^\s*::.*$/m",
+ 3 => "/\^./"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /* Flow control keywords */
+ 1 => array(
+ 'if', 'else', 'goto', 'shift',
+ 'for', 'in', 'do',
+ 'call', 'exit'
+ ),
+ /* IF statement keywords */
+ 2 => array(
+ 'not', 'exist', 'errorlevel',
+ 'defined',
+ 'equ', 'neq', 'lss', 'leq', 'gtr', 'geq'
+ ),
+ /* Internal commands */
+ 3 => array(
+ 'cd', 'md', 'rd', 'chdir', 'mkdir', 'rmdir', 'dir',
+ 'del', 'copy', 'move', 'ren', 'rename',
+ 'echo',
+ 'setlocal', 'endlocal', 'set',
+ 'pause',
+ 'pushd', 'popd', 'title', 'verify'
+ ),
+ /* Special files */
+ 4 => array(
+ 'prn', 'nul', 'lpt3', 'lpt2', 'lpt1', 'con',
+ 'com4', 'com3', 'com2', 'com1', 'aux'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '@', '%', '!', '|', '<', '>', '&'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00b100; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #b1b100; font-weight: bold;',
+ 4 => 'color: #0000ff; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #b100b1; font-style: italic;',
+ 3 => 'color: #33cc33;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #ff0000; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #33cc33;',
+ 1 => 'color: #33cc33;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #b100b1; font-weight: bold;',
+ 1 => 'color: #448844;',
+ 2 => 'color: #448888;',
+ 3 => 'color: #448888;'
+ )
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.ss64.com/nt/{FNAMEL}.html',
+ 2 => 'http://www.ss64.com/nt/{FNAMEL}.html',
+ 3 => 'http://www.ss64.com/nt/{FNAMEL}.html',
+ 4 => 'http://www.ss64.com/nt/{FNAMEL}.html'
+ ),
+ 'REGEXPS' => array(
+ /* Label */
+ 0 => array(
+/* GESHI_SEARCH => '((?si:[@\s]+GOTO\s+|\s+:)[\s]*)((?<!\n)[^\s\n]*)',*/
+ GESHI_SEARCH => '((?si:[@\s]+GOTO\s+|\s+:)[\s]*)((?<!\n)[^\s\n]*)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'si',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ /* Variable assignement */
+ 1 => array(
+/* GESHI_SEARCH => '(SET[\s]+(?si:\/A[\s]+|\/P[\s]+|))([^=\s\n]+)([\s]*=)',*/
+ GESHI_SEARCH => '(SET\s+(?si:\\/A\s+|\\/P\s+)?)([^=\n]+)(\s*=)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'si',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ /* Arguments or variable evaluation */
+ 2 => array(
+/* GESHI_SEARCH => '(%)([\d*]|[^%\s]*(?=%))((?<!%\d)%|)',*/
+ GESHI_SEARCH => '(!(?:!(?=[a-z0-9]))?)([\d*]|(?:~[adfnpstxz]*(?:$\w+:)?)?[a-z0-9](?!\w)|[^!>\n]*(?=!))((?<!%\d)%|)(?!!>)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'si',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ /* Arguments or variable evaluation */
+ 3 => array(
+/* GESHI_SEARCH => '(%)([\d*]|[^%\s]*(?=%))((?<!%\d)%|)',*/
+ GESHI_SEARCH => '(%(?:%(?=[a-z0-9]))?)([\d*]|(?:~[adfnpstxz]*(?:$\w+:)?)?[a-z0-9](?!\w)|[^%\n]*(?=%))((?<!%\d)%|)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'si',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER
+ ),
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'DISALLOWED_BEFORE' => '(?<![\w\-])'
+ ),
+ 2 => array(
+ 'DISALLOWED_BEFORE' => '(?<![\w\-])'
+ ),
+ 3 => array(
+ 'DISALLOWED_BEFORE' => '(?<![\w\-])'
+ ),
+ 4 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\w)'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/dot.php b/platform/www/vendor/geshi/geshi/src/geshi/dot.php
new file mode 100644
index 0000000..a4e8267
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/dot.php
@@ -0,0 +1,162 @@
+<?php
+/*************************************************************************************
+ * dot.php
+ * ---------------------------------
+ * Author: Adrien Friggeri (adrien@friggeri.net)
+ * Copyright: (c) 2007 Adrien Friggeri (http://www.friggeri.net)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/05/30
+ *
+ * dot language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2007/05/30 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2007/05/30)
+ * -------------------------
+ * Everything
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'dot',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'URL', 'arrowhead', 'arrowsize', 'arrowtail', 'bb', 'bgcolor', 'bottomlabel',
+ 'center', 'clusterrank', 'color', 'comment', 'constraint', 'decorate',
+ 'dir', 'distortion', 'fillcolor', 'fixedsize', 'fontcolor',
+ 'fontname', 'fontsize', 'group', 'headclip', 'headlabel', 'headport',
+ 'height', 'id', 'label', 'labelangle', 'labeldistance', 'labelfontcolor',
+ 'labelfontname', 'labelfontsize', 'layer', 'layers', 'margin', 'mclimit',
+ 'minlen', 'nodesep', 'nslimit', 'ordering', 'orientation', 'page',
+ 'pagedir', 'peripheries', 'port_label_distance', 'quantum', 'rank', 'rankdir',
+ 'ranksep', 'ratio', 'regular', 'rotate', 'samehead', 'sametail', 'searchsize',
+ 'shape', 'shapefile', 'showboxes', 'sides', 'size', 'skew', 'style',
+ 'tailclip', 'taillabel', 'tailport', 'toplabel', 'weight', 'width'
+ ),
+ 2 => array(
+ 'node', 'graph', 'digraph', 'strict', 'edge', 'subgraph'
+ ),
+ 3 => array(
+ 'Mcircle', 'Mdiamond', 'Mrecord', 'Msquare', 'auto', 'back', 'bold',
+ 'both', 'box', 'circle', 'compress', 'dashed', 'diamond', 'dot',
+ 'dotted', 'doublecircle', 'doubleoctagon', 'egg', 'ellipse', 'epsf',
+ 'false', 'fill', 'filled', 'forward', 'global', 'hexagon', 'house',
+ 'inv', 'invdot', 'invhouse', 'invis', 'invodot', 'invtrapezium',
+ 'invtriangle', 'local', 'max', 'min', 'none', 'normal', 'octagon',
+ 'odot', 'out', 'parallelogram', 'plaintext', 'polygon', 'record',
+ 'same', 'solid', 'trapezium', 'triangle', 'tripleoctagon', 'true'
+ ),
+ 4 => array(
+ 'aliceblue', 'antiquewhite', 'aquamarine', 'azure', 'beige', 'bisque', 'black',
+ 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue',
+ 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson',
+ 'cyan', 'darkgoldenrod', 'darkgreen', 'darkkhaki', 'darkolivegreen',
+ 'darkorange', 'darkorchid', 'darksalmon', 'darkseagreen', 'darkslateblue',
+ 'darkslategray', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue',
+ 'dimgray', 'dodgerblue', 'firebrick', 'forestgreen', 'gainsboro', 'ghostwhite',
+ 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'honeydew', 'hotpink',
+ 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush',
+ 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcyan', 'lightgoldenrod',
+ 'lightgoldenrodyellow', 'lightgray', 'lightpink', 'lightsalmon',
+ 'lightseagreen', 'lightskyblue', 'lightslateblue', 'lightslategray',
+ 'lightyellow', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine',
+ 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen',
+ 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred',
+ 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy',
+ 'navyblue', 'oldlace', 'olivedrab', 'oralwhite', 'orange', 'orangered',
+ 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred',
+ 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple',
+ 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'salmon2', 'sandybrown',
+ 'seagreen', 'seashell', 'sienna', 'skyblue', 'slateblue', 'slategray', 'snow',
+ 'springgreen', 'steelblue', 'tan', 'thistle', 'tomato', 'turquoise', 'violet',
+ 'violetred', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '{', '}', '-', '+', '*', '/', '<', '>', '!', '~', '%', '&', '|', '='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000066;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #993333;',
+ 4 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #339933;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #af624d; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/e.php b/platform/www/vendor/geshi/geshi/src/geshi/e.php
new file mode 100644
index 0000000..6a04779
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/e.php
@@ -0,0 +1,206 @@
+<?php
+/*************************************************************************************
+ * e.php
+ * --------
+ * Author: Kevin Reid (kpreid@switchb.org)
+ * Copyright: (c) 2010 Kevin Reid (http://switchb.org/kpreid/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/04/16
+ *
+ * E language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010-04-21 (1.0.8.8)
+ * - Fixing langcheck-reported bugs.
+ * 2010-04-14 (0.1)
+ * - First Release
+ *
+ * TODO (updated 2010-04-21)
+ * -------------------------
+ * - Do something useful with the keyword groups. Since RC uses CSS classes named
+ * by the group numbers, either
+ * - change the numbering to match conventional uses by other languages,
+ * - or find or create some way to produce usefully named classes.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'E',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array('/**' => '*/'), // Note: This is method doc, not a general comment syntax.
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+
+ // FIXME: The escaping inside ` is actually doubling of any interior `, $, or @ -- backslash is NOT special
+ 'QUOTEMARKS' => array('\'', '"', '`'),
+ 'ESCAPE_CHAR' => '\\',
+
+ 'KEYWORDS' => array(
+ // builtin control structures
+ 1 => array(
+ 'accum', 'break', 'try', 'continue', 'if', 'while', 'for', 'switch'
+ ),
+
+ // control structures subsidiary keywords
+ 2 => array(
+ 'catch', 'else', 'finally', 'in', 'exit'
+ ),
+
+ // named operators
+ 3 => array(
+ 'fn', 'via'
+ ),
+
+ // variable/function/object definers
+ 4 => array(
+ 'def', 'bind', 'var'
+ ),
+
+ // object definition subsidiary keywords
+ 5 => array(
+ 'extends', 'as', 'implements', 'guards', 'match', 'to', 'method'
+ ),
+
+ // builtin nouns in safeEnv
+ 6 => array(
+ 'null', 'false', 'true', 'throw', '__loop', '__makeList',
+ '__makeMap', '__makeProtocolDesc', '__makeMessageDesc',
+ '__makeParamDesc', 'any', 'void', 'boolean', '__makeOrderedSpace',
+ 'ValueGuard', '__MatchContext', 'require', '__makeVerbFacet', 'NaN',
+ 'Infinity', '__identityFunc', '__makeInt', '__makeFinalSlot',
+ '__makeVarSlot', '__makeGuardedSlot', '__makeGuard', '__makeTwine',
+ '__makeSourceSpan', '__auditedBy', 'Guard', 'near', 'pbc',
+ 'PassByCopy', 'DeepPassByCopy', 'Data', 'Persistent', 'DeepFrozen',
+ 'int', 'float64', 'char', 'String', 'Twine', 'TextWriter', 'List',
+ 'Map', 'nullOk', 'Tuple', '__Portrayal', 'notNull', 'vow', 'rcvr',
+ 'SturdyRef', 'simple__quasiParser', 'twine__quasiParser',
+ 'rx__quasiParser', 'e__quasiParser', 'epatt__quasiParser',
+ 'sml__quasiParser', 'term__quasiParser', 'traceln', '__equalizer',
+ '__comparer', 'Ref', 'E', 'promiseAllFulfilled', 'EIO', 'help',
+ 'safeScope', '__eval', 'resource__uriGetter', 'type__uriGetter',
+ 'import__uriGetter', 'elib__uriGetter', 'elang__uriGetter',
+ 'opaque__uriGetter'
+ ),
+
+ // builtin nouns in privilegedEnv
+ 7 => array(
+ 'file__uriGetter', 'fileURL__uriGetter', 'jar__uriGetter',
+ 'http__uriGetter', 'ftp__uriGetter', 'gopher__uriGetter',
+ 'news__uriGetter', 'cap__uriGetter', 'makeCommand', 'stdout',
+ 'stderr', 'stdin', 'print', 'println', 'interp', 'entropy', 'timer',
+ 'introducer', 'identityMgr', 'makeSturdyRef', 'timeMachine',
+ 'unsafe__uriGetter', 'currentVat', 'rune', 'awt__uriGetter',
+ 'swing__uriGetter', 'JPanel__quasiParser', 'swt__uriGetter',
+ 'currentDisplay', 'swtGrid__quasiParser', 'swtGrid`',
+ 'privilegedScope'
+ ),
+
+ // reserved keywords
+ 8 => array(
+ 'abstract', 'an', 'assert', 'attribute', 'be', 'begin', 'behalf',
+ 'belief', 'believe', 'believes', 'case', 'class', 'const',
+ 'constructor', 'declare', 'default', 'define', 'defmacro',
+ 'delicate', 'deprecated', 'dispatch', 'do', 'encapsulate',
+ 'encapsulated', 'encapsulates', 'end', 'ensure', 'enum', 'eventual',
+ 'eventually', 'export', 'facet', 'forall', 'function', 'given',
+ 'hidden', 'hides', 'inline', 'is', 'know', 'knows', 'lambda', 'let',
+ 'methods', 'module', 'namespace', 'native', 'obeys', 'octet',
+ 'oneway', 'operator', 'package', 'private', 'protected', 'public',
+ 'raises', 'reliance', 'reliant', 'relies', 'rely', 'reveal', 'sake',
+ 'signed', 'static', 'struct', 'suchthat', 'supports', 'suspect',
+ 'suspects', 'synchronized', 'this', 'transient', 'truncatable',
+ 'typedef', 'unsigned', 'unum', 'uses', 'using', 'utf8', 'utf16',
+ 'virtual', 'volatile', 'wstring'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '(', ')', '{', '}', '[', ']', '+', '-', '*', '/', '%', '=', '<', '>', '!', '^', '&', '|', '?', ':', ';', ','
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #b1b100;',
+ 3 => 'color: #b1b100;',
+ 4 => 'color: #b1b100;',
+ 5 => 'color: #b1b100;',
+ 6 => 'color: #b1b100;',
+ 7 => 'color: #b1b100;',
+ 8 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => 'http://wiki.erights.org/wiki/{FNAME}',
+ 2 => 'http://wiki.erights.org/wiki/{FNAME}',
+ 3 => 'http://wiki.erights.org/wiki/{FNAME}',
+ 4 => 'http://wiki.erights.org/wiki/{FNAME}',
+ 5 => 'http://wiki.erights.org/wiki/{FNAME}',
+ 6 => 'http://wiki.erights.org/wiki/{FNAME}',
+ 7 => 'http://wiki.erights.org/wiki/{FNAME}',
+ 8 => 'http://wiki.erights.org/wiki/{FNAME}'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '<-',
+ 3 => '::'
+ ),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/ecmascript.php b/platform/www/vendor/geshi/geshi/src/geshi/ecmascript.php
new file mode 100644
index 0000000..05069ff
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/ecmascript.php
@@ -0,0 +1,208 @@
+<?php
+/*************************************************************************************
+ * ecmascript.php
+ * --------------
+ * Author: Michel Mariani (http://www.tonton-pixel.com/site/)
+ * Copyright: (c) 2010 Michel Mariani (http://www.tonton-pixel.com/site/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/01/08
+ *
+ * ECMAScript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/01/08 (1.0.8.6)
+ * - First Release
+ * - Adapted from javascript.php to support plain ECMAScript/JavaScript (no HTML, no DOM)
+ * - Fixed regular expression for 'COMMENT_REGEXP' to exclude 'COMMENT_MULTI' syntax
+ * - Added '~' and removed '@' from 'SYMBOLS'
+ * - Cleaned up and expanded the list of 'KEYWORDS'
+ * - Added support for 'ESCAPE_REGEXP' and 'NUMBERS' (from c.php)
+ * - Selected colors to match my web site color chart
+ * - Added full number highlighting in all C language style formats
+ * - Added highlighting of escape sequences in strings, in all C language style formats including Unicode (\uXXXX).
+ *
+ * TODO (updated 2010/01/08)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ECMAScript',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ // Regular Expression Literals
+ 'COMMENT_REGEXP' => array(2 => "/(?<=[\\s^])s\\/(?:\\\\.|(?!\n)[^\\*\\/\\\\])+\\/(?:\\\\.|(?!\n)[^\\*\\/\\\\])+\\/[gimsu]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])m?\\/(?:\\\\.|(?!\n)[^\\*\\/\\\\])+\\/[gimsu]*(?=[\\s$\\.\\,\\;\\)])/iU"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[\\\\abfnrtv\'\"?\n]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array( // Reserved literals
+ 'false', 'true',
+ 'null'
+ ),
+ 2 => array( // Main keywords
+ 'break', 'case', 'catch', 'continue', 'default', 'delete', 'do', 'else',
+ 'finally', 'for', 'function', 'if', 'in', 'instanceof', 'new', 'return',
+ 'switch', 'this', 'throw', 'try', 'typeof', 'var', 'void', 'while',
+ 'with'
+ ),
+ 3 => array( // Extra keywords or keywords reserved for future use
+ 'abstract', 'as', 'boolean', 'byte', 'char', 'class', 'const', 'debugger',
+ 'double', 'enum', 'export', 'extends', 'final', 'float', 'goto', 'implements',
+ 'import', 'int', 'interface', 'is', 'long', 'native', 'namespace', 'package',
+ 'private', 'protected', 'public', 'short', 'static', 'super', 'synchronized', 'throws',
+ 'transient', 'use', 'volatile'
+ ),
+ 4 => array( // Operators
+ 'get', 'set'
+ ),
+ 5 => array( // Built-in object classes
+ 'Array', 'Boolean', 'Date', 'EvalError', 'Error', 'Function', 'Math', 'Number',
+ 'Object', 'RangeError', 'ReferenceError', 'RegExp', 'String', 'SyntaxError', 'TypeError', 'URIError'
+ ),
+ 6 => array( // Global properties
+ 'Infinity', 'NaN', 'undefined'
+ ),
+ 7 => array( // Global methods
+ 'decodeURI', 'decodeURIComponent', 'encodeURI', 'encodeURIComponent',
+ 'eval', 'isFinite', 'isNaN', 'parseFloat', 'parseInt',
+ // The escape and unescape functions do not work properly for non-ASCII characters and have been deprecated.
+ // In JavaScript 1.5 and later, use encodeURI, decodeURI, encodeURIComponent, and decodeURIComponent.
+ 'escape', 'unescape'
+ ),
+ 8 => array( // Function's arguments
+ 'arguments'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}',
+ '+', '-', '*', '/', '%',
+ '!', '.', '&', '|', '^',
+ '<', '>', '=', '~',
+ ',', ';', '?', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #009999;',
+ 2 => 'color: #1500C8;',
+ 3 => 'color: #1500C8;',
+ 4 => 'color: #1500C8;',
+ 5 => 'color: #1500C8;',
+ 6 => 'color: #1500C8;',
+ 7 => 'color: #1500C8;',
+ 8 => 'color: #1500C8;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #CC0000;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #3366CC;',
+ 1 => 'color: #3366CC;',
+ 2 => 'color: #3366CC;',
+ 3 => 'color: #3366CC;',
+ 4 => 'color: #3366CC;',
+ 5 => 'color: #3366CC;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #008800;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #9900FF;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF00FF;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #FF00FF;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #FF00FF;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #FF00FF;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color: #FF00FF;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color: #FF00FF;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color: #FF00FF;',
+ GESHI_NUMBER_FLT_NONSCI => 'color: #FF00FF;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #660066;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/eiffel.php b/platform/www/vendor/geshi/geshi/src/geshi/eiffel.php
new file mode 100644
index 0000000..50cdf6f
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/eiffel.php
@@ -0,0 +1,393 @@
+<?php
+/*************************************************************************************
+ * eiffel.php
+ * ----------
+ * Author: Zoran Simic (zsimic@axarosenberg.com)
+ * Copyright: (c) 2005 Zoran Simic
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/06/30
+ *
+ * Eiffel language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/06/30 (1.0.7)
+ * - Initial release
+ *
+ * TODO (updated 2005/06/30)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Eiffel',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '%',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'separate',
+ 'invariant',
+ 'inherit',
+ 'indexing',
+ 'feature',
+ 'expanded',
+ 'deferred',
+ 'class'
+ ),
+ 2 => array(
+ 'xor',
+ 'when',
+ 'variant',
+ 'until',
+ 'unique',
+ 'undefine',
+ 'then',
+ 'strip',
+ 'select',
+ 'retry',
+ 'rescue',
+ 'require',
+ 'rename',
+ 'reference',
+ 'redefine',
+ 'prefix',
+ 'or',
+ 'once',
+ 'old',
+ 'obsolete',
+ 'not',
+ 'loop',
+ 'local',
+ 'like',
+ 'is',
+ 'inspect',
+ 'infix',
+ 'include',
+ 'implies',
+ 'if',
+ 'frozen',
+ 'from',
+ 'external',
+ 'export',
+ 'ensure',
+ 'end',
+ 'elseif',
+ 'else',
+ 'do',
+ 'creation',
+ 'create',
+ 'check',
+ 'as',
+ 'and',
+ 'alias',
+ 'agent'
+ ),
+ 3 => array(
+ 'Void',
+ 'True',
+ 'Result',
+ 'Precursor',
+ 'False',
+ 'Current'
+ ),
+ 4 => array(
+ 'UNIX_SIGNALS',
+ 'UNIX_FILE_INFO',
+ 'UNBOUNDED',
+ 'TWO_WAY_TREE_CURSOR',
+ 'TWO_WAY_TREE',
+ 'TWO_WAY_SORTED_SET',
+ 'TWO_WAY_LIST',
+ 'TWO_WAY_CURSOR_TREE',
+ 'TWO_WAY_CIRCULAR',
+ 'TWO_WAY_CHAIN_ITERATOR',
+ 'TUPLE',
+ 'TREE',
+ 'TRAVERSABLE',
+ 'TO_SPECIAL',
+ 'THREAD_CONTROL',
+ 'THREAD_ATTRIBUTES',
+ 'THREAD',
+ 'TABLE',
+ 'SUBSET',
+ 'STRING_HANDLER',
+ 'STRING',
+ 'STREAM',
+ 'STORABLE',
+ 'STD_FILES',
+ 'STACK',
+ 'SPECIAL',
+ 'SORTED_TWO_WAY_LIST',
+ 'SORTED_STRUCT',
+ 'SORTED_LIST',
+ 'SINGLE_MATH',
+ 'SET',
+ 'SEQUENCE',
+ 'SEQ_STRING',
+ 'SEMAPHORE',
+ 'ROUTINE',
+ 'RESIZABLE',
+ 'RECURSIVE_TREE_CURSOR',
+ 'RECURSIVE_CURSOR_TREE',
+ 'REAL_REF',
+ 'REAL',
+ 'RAW_FILE',
+ 'RANDOM',
+ 'QUEUE',
+ 'PROXY',
+ 'PROFILING_SETTING',
+ 'PROCEDURE',
+ 'PRIORITY_QUEUE',
+ 'PRIMES',
+ 'PRECOMP',
+ 'POINTER_REF',
+ 'POINTER',
+ 'PLATFORM',
+ 'PLAIN_TEXT_FILE',
+ 'PATH_NAME',
+ 'PART_SORTED_TWO_WAY_LIST',
+ 'PART_SORTED_SET',
+ 'PART_SORTED_LIST',
+ 'PART_COMPARABLE',
+ 'OPERATING_ENVIRONMENT',
+ 'ONCE_CONTROL',
+ 'OBJECT_OWNER',
+ 'OBJECT_CONTROL',
+ 'NUMERIC',
+ 'NONE',
+ 'MUTEX',
+ 'MULTI_ARRAY_LIST',
+ 'MULTAR_LIST_CURSOR',
+ 'MEMORY',
+ 'MEM_INFO',
+ 'MEM_CONST',
+ 'MATH_CONST',
+ 'LIST',
+ 'LINKED_TREE_CURSOR',
+ 'LINKED_TREE',
+ 'LINKED_STACK',
+ 'LINKED_SET',
+ 'LINKED_QUEUE',
+ 'LINKED_PRIORITY_QUEUE',
+ 'LINKED_LIST_CURSOR',
+ 'LINKED_LIST',
+ 'LINKED_CURSOR_TREE',
+ 'LINKED_CIRCULAR',
+ 'LINKABLE',
+ 'LINEAR_ITERATOR',
+ 'LINEAR',
+ 'ITERATOR',
+ 'IO_MEDIUM',
+ 'INTERNAL',
+ 'INTEGER_REF',
+ 'INTEGER_INTERVAL',
+ 'INTEGER',
+ 'INFINITE',
+ 'INDEXABLE',
+ 'IDENTIFIED_CONTROLLER',
+ 'IDENTIFIED',
+ 'HIERARCHICAL',
+ 'HEAP_PRIORITY_QUEUE',
+ 'HASHABLE',
+ 'HASH_TABLE_CURSOR',
+ 'HASH_TABLE',
+ 'GENERAL',
+ 'GC_INFO',
+ 'FUNCTION',
+ 'FORMAT_INTEGER',
+ 'FORMAT_DOUBLE',
+ 'FIXED_TREE',
+ 'FIXED_LIST',
+ 'FIXED',
+ 'FINITE',
+ 'FILE_NAME',
+ 'FILE',
+ 'FIBONACCI',
+ 'EXECUTION_ENVIRONMENT',
+ 'EXCEPTIONS',
+ 'EXCEP_CONST',
+ 'DYNAMIC_TREE',
+ 'DYNAMIC_LIST',
+ 'DYNAMIC_CIRCULAR',
+ 'DYNAMIC_CHAIN',
+ 'DOUBLE_REF',
+ 'DOUBLE_MATH',
+ 'DOUBLE',
+ 'DISPENSER',
+ 'DIRECTORY_NAME',
+ 'DIRECTORY',
+ 'DECLARATOR',
+ 'DEBUG_OUTPUT',
+ 'CURSOR_TREE_ITERATOR',
+ 'CURSOR_TREE',
+ 'CURSOR_STRUCTURE',
+ 'CURSOR',
+ 'COUNTABLE_SEQUENCE',
+ 'COUNTABLE',
+ 'CONTAINER',
+ 'CONSOLE',
+ 'CONDITION_VARIABLE',
+ 'COMPARABLE_STRUCT',
+ 'COMPARABLE_SET',
+ 'COMPARABLE',
+ 'COMPACT_TREE_CURSOR',
+ 'COMPACT_CURSOR_TREE',
+ 'COLLECTION',
+ 'CIRCULAR_CURSOR',
+ 'CIRCULAR',
+ 'CHARACTER_REF',
+ 'CHARACTER',
+ 'CHAIN',
+ 'CELL',
+ 'BOX',
+ 'BOUNDED_STACK',
+ 'BOUNDED_QUEUE',
+ 'BOUNDED',
+ 'BOOLEAN_REF',
+ 'BOOLEAN',
+ 'BOOL_STRING',
+ 'BIT_REF',
+ 'BINARY_TREE',
+ 'BINARY_SEARCH_TREE_SET',
+ 'BINARY_SEARCH_TREE',
+ 'BILINEAR',
+ 'BI_LINKABLE',
+ 'BASIC_ROUTINES',
+ 'BAG',
+ 'ASCII',
+ 'ARRAYED_TREE',
+ 'ARRAYED_STACK',
+ 'ARRAYED_QUEUE',
+ 'ARRAYED_LIST_CURSOR',
+ 'ARRAYED_LIST',
+ 'ARRAYED_CIRCULAR',
+ 'ARRAY2',
+ 'ARRAY',
+ 'ARGUMENTS',
+ 'ANY',
+ 'ACTIVE'
+ ),
+ 5 => array(
+ 'yes',
+ 'visible',
+ 'trace',
+ 'system',
+ 'root',
+ 'profile',
+ 'override_cluster',
+ 'object',
+ 'no',
+ 'multithreaded',
+ 'msil_generation_type',
+ 'line_generation',
+ 'library',
+ 'inlining_size',
+ 'inlining',
+ 'include_path',
+ 'il_verifiable',
+ 'exclude',
+ 'exception_trace',
+ 'dynamic_runtime',
+ 'dotnet_naming_convention',
+ 'disabled_debug',
+ 'default',
+ 'debug',
+ 'dead_code_removal',
+ 'console_application',
+ 'cluster',
+ 'cls_compliant',
+ 'check_vape',
+ 'assertion',
+ 'array_optimization',
+ 'all',
+ 'address_expression'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '+', '-', '*', '?', '=', '/', '%', '&', '>', '<', '^', '!', '|', ':',
+ '(', ')', '{', '}', '[', ']', '#'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => true,
+ 5 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0600FF; font-weight: bold;',
+ 2 => 'color: #0600FF; font-weight: bold;',
+ 3 => 'color: #800080;',
+ 4 => 'color: #800000',
+ 5 => 'color: #603000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000; font-style: italic;',
+ 'MULTI' => ''
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #005070; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0080A0;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #000060;',
+ 2 => 'color: #000050;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #600000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => 'http://www.google.com/search?q=site%3Ahttp%3A%2F%2Fdocs.eiffel.com%2Feiffelstudio%2Flibraries+{FNAMEL}&amp;btnI=I%27m+Feeling+Lucky',
+ 5 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/email.php b/platform/www/vendor/geshi/geshi/src/geshi/email.php
new file mode 100644
index 0000000..c9bdf26
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/email.php
@@ -0,0 +1,264 @@
+<?php
+/*************************************************************************************
+ * email.php
+ * ---------------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/10/19
+ *
+ * Email (mbox \ eml \ RFC format) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/19 (1.0.8.1)
+ * - First Release
+ *
+ * TODO (updated 2008/10/19)
+ * -------------------------
+ * * Better checks when a header field should be expected
+ * * Fix the bound checks for kw groups 2 and 3, as well as rx group 1
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'eMail (mbox)',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'HTTP', 'SMTP', 'ASMTP', 'ESMTP'
+ ),
+ 2 => array(
+ 'Original-Recipient','Accept-Language','Alternate-Recipient',
+ 'Archived-At','Authentication-Results','Auto-Submitted',
+ 'Autoforwarded','Autosubmitted','Base','Comments',
+ 'Content-Alternative','Content-Base','Content-Description',
+ 'Content-Disposition','Content-Duration','Content-features',
+ 'Content-ID','Content-Identifier','Content-Language',
+ 'Content-Location','Content-MD5','Content-Return',
+ 'Content-Transfer-Encoding','Content-Type','Conversion',
+ 'Conversion-With-Loss','Deferred-Delivery','Delivery-Date',
+ 'Discarded-X400-IPMS-Extensions','Discarded-X400-MTS-Extensions',
+ 'Disclose-Recipients','Disposition-Notification-Options',
+ 'Disposition-Notification-To','DKIM-Signature',
+ 'DL-Expansion-History','Downgraded-Bcc','Downgraded-Cc',
+ 'Downgraded-Disposition-Notification-To',
+ 'Downgraded-Final-Recipient','Downgraded-From',
+ 'Downgraded-In-Reply-To','Downgraded-Mail-From',
+ 'Downgraded-Message-Id','Downgraded-Original-Recipient',
+ 'Downgraded-Rcpt-To','Downgraded-References',
+ 'Downgraded-Reply-To','Downgraded-Resent-Bcc',
+ 'Downgraded-Resent-Cc','Downgraded-Resent-From',
+ 'Downgraded-Resent-Reply-To','Downgraded-Resent-Sender',
+ 'Downgraded-Resent-To','Downgraded-Return-Path',
+ 'Downgraded-Sender','Downgraded-To','Encoding','Encrypted','Expires',
+ 'Expiry-Date','Generate-Delivery-Report','Importance','In-Reply-To',
+ 'Incomplete-Copy','Keywords','Language','Latest-Delivery-Time',
+ 'List-Archive','List-Help','List-ID','List-Owner','List-Post',
+ 'List-Subscribe','List-Unsubscribe','List-Unsubscribe-Post',
+ 'Message-Context','Message-ID','Message-Type','MIME-Version',
+ 'MMHS-Acp127-Message-Identifier','MMHS-Codress-Message-Indicator',
+ 'MMHS-Copy-Precedence','MMHS-Exempted-Address',
+ 'MMHS-Extended-Authorisation-Info','MMHS-Handling-Instructions',
+ 'MMHS-Message-Instructions','MMHS-Message-Type',
+ 'MMHS-Originator-PLAD','MMHS-Originator-Reference',
+ 'MMHS-Other-Recipients-Indicator-CC',
+ 'MMHS-Other-Recipients-Indicator-To','MMHS-Primary-Precedence',
+ 'MMHS-Subject-Indicator-Codes','MT-Priority','Obsoletes',
+ 'Organization','Original-Encoded-Information-Types','Original-From',
+ 'Original-Message-ID','Original-Subject','Originator-Return-Address',
+ 'PICS-Label','Prevent-NonDelivery-Report','Priority','Received',
+ 'Received-SPF','References','Reply-By','Reply-To',
+ 'Require-Recipient-Valid-Since','Resent-Bcc','Resent-Cc',
+ 'Resent-Date','Resent-From','Resent-Message-ID','Resent-Reply-To',
+ 'Resent-Sender','Resent-To','Return-Path','Sensitivity',
+ 'Solicitation','Supersedes','VBR-Info','X400-Content-Identifier',
+ 'X400-Content-Return','X400-Content-Type','X400-MTS-Identifier',
+ 'X400-Originator','X400-Received','X400-Recipients','X400-Trace'
+ ),
+ 3 => array(
+ 'Bcc','CC','Date','From','Sender','Subject','To'
+ ),
+ 4 => array(
+ 'by', 'for', 'from', 'id', 'with'
+ )
+ ),
+ 'SYMBOLS' => array(
+ ':', ';', '<', '>', '[', ']'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => false,
+ 3 => false,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #800000; font-weight: bold;',
+ 4 => 'font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ 0 => 'color: #000040;',
+ 1 => 'color: #002040;',
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #0000FF;',
+ 3 => 'color: #008000;',
+ 4 => 'color: #0000FF; font-weight: bold;',
+ 5 => 'font-weight: bold;',
+ 6 => 'color: #400080;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ // Non-Standard-Header
+ 1 => array(
+ GESHI_SEARCH => "(?<=\A\x20|\n)x-[a-z0-9\-]*(?=\s*:|\s*<)",
+ GESHI_REPLACE => "\\0",
+ GESHI_MODIFIERS => "smi",
+ GESHI_BEFORE => "",
+ GESHI_AFTER => ""
+ ),
+ //Email-Adresses or Mail-IDs
+ 2 => array(
+ GESHI_SEARCH => "\b(?<!\\/)(?P<q>\"?)[\w\.\-]+\k<q>@(?!-)[\w\-]+(?<!-)(?:(?:\.(?!-)[\w\-]+(?<!-))*)?",
+ GESHI_REPLACE => "\\0",
+ GESHI_MODIFIERS => "mi",
+ GESHI_BEFORE => "",
+ GESHI_AFTER => ""
+ ),
+ //Date values in RFC format
+ 3 => array(
+ GESHI_SEARCH => "\b(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s+\d\d?\s+" .
+ "(?:Jan|Feb|Mar|apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+" .
+ "\d{4}\s+\d\d?:\d\d:\d\d\s+[+\-]\d{4}(?:\s+\(\w+\))?",
+ GESHI_REPLACE => "\\0",
+ GESHI_MODIFIERS => "mi",
+ GESHI_BEFORE => "",
+ GESHI_AFTER => ""
+ ),
+ //IP addresses
+ 4 => array(
+ GESHI_SEARCH => "(?<=\s)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?=\s)|".
+ "(?<=\[)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?=\])|".
+ "(?<==)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?=<)|".
+
+ "(?<=\s)(?:[a-f\d]{1,4}\:)+(?:[a-f\d]{0,4})?(?:\:[a-f\d]{1,4})+(?=\s)|".
+ "(?<=\[)(?:[a-f\d]{1,4}\:)+(?:[a-f\d]{0,4})?(?:\:[a-f\d]{1,4})+(?=\])|".
+ "(?<==)(?:[a-f\d]{1,4}\:)+(?:[a-f\d]{0,4})?(?:\:[a-f\d]{1,4})+(?=<)|".
+
+ "(?<=\s)\:(?:\:[a-f\d]{1,4})+(?=\s)|".
+ "(?<=\[)\:(?:\:[a-f\d]{1,4})+(?=\])|".
+ "(?<==)\:(?:\:[a-f\d]{1,4})+(?=<)|".
+
+ "(?<=\s)(?:[a-f\d]{1,4}\:)+\:(?=\s)|".
+ "(?<=\[)(?:[a-f\d]{1,4}\:)+\:(?=\])|".
+ "(?<==)(?:[a-f\d]{1,4}\:)+\:(?=<)",
+ GESHI_REPLACE => "\\0",
+ GESHI_MODIFIERS => "i",
+ GESHI_BEFORE => "",
+ GESHI_AFTER => ""
+ ),
+ //Field-Assignments
+ 5 => array(
+ GESHI_SEARCH => "(?<=\s)[A-Z0-9\-\.]+(?==(?:$|\s$|[^\s=]))",
+ GESHI_REPLACE => "\\0",
+ GESHI_MODIFIERS => "mi",
+ GESHI_BEFORE => "",
+ GESHI_AFTER => ""
+ ),
+ //MIME type
+ 6 => array(
+ GESHI_SEARCH => "(?<=\s)(?:audio|application|image|multipart|text|".
+ "video|x-[a-z0-9\-]+)\/[a-z0-9][a-z0-9\-]*(?=\s|<|$)",
+ GESHI_REPLACE => "\\0",
+ GESHI_MODIFIERS => "m",
+ GESHI_BEFORE => "",
+ GESHI_AFTER => ""
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => "/(?P<start>^)[A-Za-z][a-zA-Z0-9\-]*\s*:\s*(?:.|(?=\n\s)\n)*(?P<end>$)/m",
+ 1 => "/(?P<start>^)--[a-zA-Z0-9_=\-]+[a-zA-Z0-9_](?:--)?(?P<end>$)/m"
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => false
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 2 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\A\x20|\n)',
+ 'DISALLOWED_AFTER' => '(?=\s*:)',
+ ),
+ 3 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\A\x20|\n)',
+ 'DISALLOWED_AFTER' => '(?=\s*:)',
+ ),
+ 4 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\s)',
+ 'DISALLOWED_AFTER' => '(?=\s|\b)',
+ )
+ ),
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER,
+ 'COMMENTS' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/epc.php b/platform/www/vendor/geshi/geshi/src/geshi/epc.php
new file mode 100644
index 0000000..7882d00
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/epc.php
@@ -0,0 +1,152 @@
+<?php
+/*************************************************************************************
+ * epc.php
+ * --------
+ * Author: Thorsten Muehlfelder (muehlfelder@enertex.de)
+ * Copyright: (c) 2010 Enertex Bayern GmbH
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/08/26
+ *
+ * Enerscript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/08/26 (1.0.8.10)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'EPC',
+ 'COMMENT_SINGLE' => array('//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //[Sections]
+ //1 => "/^\\[.*\\]/"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(
+ 0 => '"',
+ 1 => '$'
+ ),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'if', 'then', 'else', 'endif',
+ 'and', 'or', 'xor', 'hysteresis'
+ ),
+ 2 => array(
+ 'read', 'write', 'event',
+ 'gettime', 'settime', 'getdate', 'setdate', 'gettimedate', 'settimedate',
+ 'hour', 'minute', 'second', 'changehour', 'changeminute', 'changesecond',
+ 'date', 'month', 'day', 'dayofweek', 'sun', 'azimuth', 'elevation',
+ 'sunrisehour', 'sunriseminute', 'sunsethour', 'sunsetminute',
+ 'wtime', 'htime', 'mtime', 'stime',
+ 'cwtime', 'chtime', 'cmtime', 'cstime',
+ 'delay', 'after', 'cycle',
+ 'readflash', 'writeflash',
+ 'abs', 'acos', 'asin', 'atan', 'cos', 'ceil', 'average', 'exp', 'floor',
+ 'log', 'max', 'min', 'mod', 'pow', 'sqrt', 'sin', 'tan', 'change', 'convert',
+ 'eval', 'systemstart', 'random', 'comobject', 'sleep', 'scene', 'storescene', 'callscene',
+ 'find', 'stringcast', 'stringset', 'stringformat', 'split', 'size',
+ 'readrs232'. 'sendrs232', 'address', 'readknx',
+ 'readudp', 'sendudp', 'connecttcp', 'closetcp', 'readtcp', 'sendtcp',
+ 'resolve', 'sendmail',
+ 'button', 'webbutton', 'chart', 'webchart', 'webdisplay', 'getslider', 'pshifter', 'mpshifter',
+ 'getpslider', 'mbutton', 'mbbutton', 'mchart', 'mpchart', 'mpbutton', 'pdisplay', 'pchart',
+ 'pbutton', 'setslider', 'setpslider', 'slider', 'pslider', 'page', 'line', 'header',
+ 'footer', 'none', 'plink', 'link', 'frame', 'dframe'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '%', 'b01',
+ ),
+ 1 => array(
+ '+', '-', '==', '>=', '=<',
+ ),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #e63ec3;',
+ 2 => 'color: #e63ec3;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #0000ff;'
+ //1 => 'color: #ffa500;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 1 => 'color: #000099;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #8a0808;',
+ 1 => 'color: #6e6e6e;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0b610b;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #0b610b;',
+ 1 => 'color: #e63ec3;'
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #0b610b;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ // Numbers, e.g. 255u08
+ 1 => "[0-9]*[subf][0136][12468]"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'COMMENTS' => array(
+ 'DISALLOWED_BEFORE' => '$'
+ ),
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![\.\-a-zA-Z0-9_\$\#])",
+ 'DISALLOWED_AFTER' => "(?![\.\-a-zA-Z0-9_%=\\/])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/erlang.php b/platform/www/vendor/geshi/geshi/src/geshi/erlang.php
new file mode 100644
index 0000000..8053d87
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/erlang.php
@@ -0,0 +1,439 @@
+<?php
+/*************************************************************************************
+ * erlang.php
+ * --------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Contributions:
+ * - Uwe Dauernheim (uwe@dauernheim.net)
+ * - Dan Forest-Barbier (dan@twisted.in)
+ * Copyright: (c) 2008 Uwe Dauernheim (http://www.kreisquadratur.de/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008-09-27
+ *
+ * Erlang language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/05/02 (1.0.8.3)
+ * - Now using 'PARSER_CONTROL' instead of huge rexgexps, better and cleaner
+ *
+ * 2009/04/26 (1.0.8.3)
+ * - Only link to existing docs / Fixes
+ *
+ * 2008-09-28 (1.0.0.1)
+ * [!] Bug fixed with keyword module.
+ * [+] Added more function names
+ *
+ * 2008-09-27 (1.0.0)
+ * [ ] First Release
+ *
+ * TODO (updated 2008-09-27)
+ * -------------------------
+ * [!] Stop ';' from being transformed to '<SEMI>'
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Erlang',
+ 'COMMENT_SINGLE' => array(1 => '%'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array("'", "\\"),
+ 'HARDCHAR' => "\\",
+ 'ESCAPE_CHAR' => '\\',
+ 'NUMBERS' => GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ //Control flow keywrods
+ 1 => array(
+ 'after', 'andalso', 'begin', 'case', 'catch', 'end', 'fun', 'if',
+ 'of', 'orelse', 'receive', 'try', 'when', 'query'
+ ),
+ //Binary operators
+ 2 => array(
+ 'and', 'band', 'bnot', 'bor', 'bsl', 'bsr', 'bxor', 'div', 'not',
+ 'or', 'rem', 'xor'
+ ),
+ 3 => array(
+ 'abs', 'alive', 'apply', 'atom_to_list', 'binary_to_list',
+ 'binary_to_term', 'concat_binary', 'date', 'disconnect_node',
+ 'element', 'erase', 'exit', 'float', 'float_to_list', 'get',
+ 'get_keys', 'group_leader', 'halt', 'hd', 'integer_to_list',
+ 'is_alive', 'length', 'link', 'list_to_atom', 'list_to_binary',
+ 'list_to_float', 'list_to_integer', 'list_to_pid', 'list_to_tuple',
+ 'load_module', 'make_ref', 'monitor_node', 'node', 'nodes', 'now',
+ 'open_port', 'pid_to_list', 'process_flag', 'process_info',
+ 'process', 'put', 'register', 'registered', 'round', 'self',
+ 'setelement', 'size', 'spawn', 'spawn_link', 'split_binary',
+ 'statistics', 'term_to_binary', 'throw', 'time', 'tl', 'trunc',
+ 'tuple_to_list', 'unlink', 'unregister', 'whereis'
+ ),
+ // Built-In Functions
+ 4 => array(
+ 'atom', 'binary', 'constant', 'function', 'integer', 'is_atom',
+ 'is_binary', 'is_constant', 'is_function', 'is_integer', 'is_list',
+ 'is_number', 'is_pid', 'is_reference', 'is_record', 'list',
+ 'number', 'pid', 'ports', 'port_close', 'port_info', 'reference'
+ ),
+ // Erlang/OTP internal modules (scary one)
+ 5 => array(
+ 'alarm_handler', 'any', 'app', 'application', 'appmon', 'appup',
+ 'array', 'asn1ct', 'asn1rt', 'auth', 'base64', 'beam_lib', 'c',
+ 'calendar', 'code', 'common_test_app', 'compile', 'config',
+ 'corba', 'corba_object', 'cosEventApp', 'CosEventChannelAdmin',
+ 'CosEventChannelAdmin_ConsumerAdmin',
+ 'CosEventChannelAdmin_EventChannel',
+ 'CosEventChannelAdmin_ProxyPullConsumer',
+ 'CosEventChannelAdmin_ProxyPullSupplier',
+ 'CosEventChannelAdmin_ProxyPushConsumer',
+ 'CosEventChannelAdmin_ProxyPushSupplier',
+ 'CosEventChannelAdmin_SupplierAdmin', 'CosEventDomainAdmin',
+ 'CosEventDomainAdmin_EventDomain',
+ 'CosEventDomainAdmin_EventDomainFactory',
+ 'cosEventDomainApp', 'CosFileTransfer_Directory',
+ 'CosFileTransfer_File', 'CosFileTransfer_FileIterator',
+ 'CosFileTransfer_FileTransferSession',
+ 'CosFileTransfer_VirtualFileSystem',
+ 'cosFileTransferApp', 'CosNaming', 'CosNaming_BindingIterator',
+ 'CosNaming_NamingContext', 'CosNaming_NamingContextExt',
+ 'CosNotification', 'CosNotification_AdminPropertiesAdmin',
+ 'CosNotification_QoSAdmin', 'cosNotificationApp',
+ 'CosNotifyChannelAdmin_ConsumerAdmin',
+ 'CosNotifyChannelAdmin_EventChannel',
+ 'CosNotifyChannelAdmin_EventChannelFactory',
+ 'CosNotifyChannelAdmin_ProxyConsumer',
+ 'CosNotifyChannelAdmin_ProxyPullConsumer',
+ 'CosNotifyChannelAdmin_ProxyPullSupplier',
+ 'CosNotifyChannelAdmin_ProxyPushConsumer',
+ 'CosNotifyChannelAdmin_ProxyPushSupplier',
+ 'CosNotifyChannelAdmin_ProxySupplier',
+ 'CosNotifyChannelAdmin_SequenceProxyPullConsumer',
+ 'CosNotifyChannelAdmin_SequenceProxyPullSupplier',
+ 'CosNotifyChannelAdmin_SequenceProxyPushConsumer',
+ 'CosNotifyChannelAdmin_SequenceProxyPushSupplier',
+ 'CosNotifyChannelAdmin_StructuredProxyPullConsumer',
+ 'CosNotifyChannelAdmin_StructuredProxyPullSupplier',
+ 'CosNotifyChannelAdmin_StructuredProxyPushConsumer',
+ 'CosNotifyChannelAdmin_StructuredProxyPushSupplier',
+ 'CosNotifyChannelAdmin_SupplierAdmin',
+ 'CosNotifyComm_NotifyPublish', 'CosNotifyComm_NotifySubscribe',
+ 'CosNotifyFilter_Filter', 'CosNotifyFilter_FilterAdmin',
+ 'CosNotifyFilter_FilterFactory', 'CosNotifyFilter_MappingFilter',
+ 'cosProperty', 'CosPropertyService_PropertiesIterator',
+ 'CosPropertyService_PropertyNamesIterator',
+ 'CosPropertyService_PropertySet',
+ 'CosPropertyService_PropertySetDef',
+ 'CosPropertyService_PropertySetDefFactory',
+ 'CosPropertyService_PropertySetFactory', 'cosTime',
+ 'CosTime_TimeService', 'CosTime_TIO', 'CosTime_UTO',
+ 'CosTimerEvent_TimerEventHandler',
+ 'CosTimerEvent_TimerEventService', 'cosTransactions',
+ 'CosTransactions_Control', 'CosTransactions_Coordinator',
+ 'CosTransactions_RecoveryCoordinator', 'CosTransactions_Resource',
+ 'CosTransactions_SubtransactionAwareResource',
+ 'CosTransactions_Terminator', 'CosTransactions_TransactionFactory',
+ 'cover', 'cprof', 'cpu_sup', 'crashdump', 'crypto', 'crypto_app',
+ 'ct', 'ct_cover', 'ct_ftp', 'ct_master', 'ct_rpc', 'ct_snmp',
+ 'ct_ssh', 'ct_telnet', 'dbg', 'debugger', 'dets', 'dialyzer',
+ 'dict', 'digraph', 'digraph_utils', 'disk_log', 'disksup',
+ 'docb_gen', 'docb_transform', 'docb_xml_check', 'docbuilder_app',
+ 'driver_entry', 'edoc', 'edoc_doclet', 'edoc_extract',
+ 'edoc_layout', 'edoc_lib', 'edoc_run', 'egd', 'ei', 'ei_connect',
+ 'epmd', 'epp', 'epp_dodger', 'eprof', 'erl', 'erl_boot_server',
+ 'erl_call', 'erl_comment_scan', 'erl_connect', 'erl_ddll',
+ 'erl_driver', 'erl_error', 'erl_eterm', 'erl_eval',
+ 'erl_expand_records', 'erl_format', 'erl_global', 'erl_id_trans',
+ 'erl_internal', 'erl_lint', 'erl_malloc', 'erl_marshal',
+ 'erl_parse', 'erl_pp', 'erl_prettypr', 'erl_prim_loader',
+ 'erl_prim_loader_stub', 'erl_recomment', 'erl_scan',
+ 'erl_set_memory_block', 'erl_syntax', 'erl_syntax_lib', 'erl_tar',
+ 'erl_tidy', 'erlang', 'erlang_mode', 'erlang_stub', 'erlc',
+ 'erlsrv', 'error_handler', 'error_logger', 'erts_alloc',
+ 'erts_alloc_config', 'escript', 'et', 'et_collector',
+ 'et_selector', 'et_viewer', 'etop', 'ets', 'eunit', 'file',
+ 'file_sorter', 'filelib', 'filename', 'fixed', 'fprof', 'ftp',
+ 'gb_sets', 'gb_trees', 'gen_event', 'gen_fsm', 'gen_sctp',
+ 'gen_server', 'gen_tcp', 'gen_udp', 'gl', 'global', 'global_group',
+ 'glu', 'gs', 'heart', 'http', 'httpd', 'httpd_conf',
+ 'httpd_socket', 'httpd_util', 'i', 'ic', 'ic_c_protocol',
+ 'ic_clib', 'igor', 'inet', 'inets', 'init', 'init_stub',
+ 'instrument', 'int', 'interceptors', 'inviso', 'inviso_as_lib',
+ 'inviso_lfm', 'inviso_lfm_tpfreader', 'inviso_rt',
+ 'inviso_rt_meta', 'io', 'io_lib', 'kernel_app', 'lib', 'lists',
+ 'lname', 'lname_component', 'log_mf_h', 'make', 'math', 'megaco',
+ 'megaco_codec_meas', 'megaco_codec_transform',
+ 'megaco_edist_compress', 'megaco_encoder', 'megaco_flex_scanner',
+ 'megaco_tcp', 'megaco_transport', 'megaco_udp', 'megaco_user',
+ 'memsup', 'mnesia', 'mnesia_frag_hash', 'mnesia_registry',
+ 'mod_alias', 'mod_auth', 'mod_esi', 'mod_security',
+ 'Module_Interface', 'ms_transform', 'net_adm', 'net_kernel',
+ 'new_ssl', 'nteventlog', 'observer_app', 'odbc', 'orber',
+ 'orber_acl', 'orber_diagnostics', 'orber_ifr', 'orber_tc',
+ 'orddict', 'ordsets', 'os', 'os_mon', 'os_mon_mib', 'os_sup',
+ 'otp_mib', 'overload', 'packages', 'percept', 'percept_profile',
+ 'pg', 'pg2', 'pman', 'pool', 'prettypr', 'proc_lib', 'proplists',
+ 'public_key', 'qlc', 'queue', 'random', 'rb', 're', 'regexp',
+ 'registry', 'rel', 'release_handler', 'reltool', 'relup', 'rpc',
+ 'run_erl', 'run_test', 'runtime_tools_app', 'sasl_app', 'script',
+ 'seq_trace', 'sets', 'shell', 'shell_default', 'slave', 'snmp',
+ 'snmp_app', 'snmp_community_mib', 'snmp_framework_mib',
+ 'snmp_generic', 'snmp_index', 'snmp_notification_mib', 'snmp_pdus',
+ 'snmp_standard_mib', 'snmp_target_mib', 'snmp_user_based_sm_mib',
+ 'snmp_view_based_acm_mib', 'snmpa', 'snmpa_conf', 'snmpa_error',
+ 'snmpa_error_io', 'snmpa_error_logger', 'snmpa_error_report',
+ 'snmpa_local_db', 'snmpa_mpd', 'snmpa_network_interface',
+ 'snmpa_network_interface_filter',
+ 'snmpa_notification_delivery_info_receiver',
+ 'snmpa_notification_filter', 'snmpa_supervisor', 'snmpc', 'snmpm',
+ 'snmpm_conf', 'snmpm_mpd', 'snmpm_network_interface', 'snmpm_user',
+ 'sofs', 'ssh', 'ssh_channel', 'ssh_connection', 'ssh_sftp',
+ 'ssh_sftpd', 'ssl', 'ssl_app', 'ssl_pkix', 'start', 'start_erl',
+ 'start_webtool', 'stdlib_app', 'string', 'supervisor',
+ 'supervisor_bridge', 'sys', 'systools', 'tags', 'test_server',
+ 'test_server_app', 'test_server_ctrl', 'tftp', 'timer', 'toolbar',
+ 'ttb', 'tv', 'unicode', 'unix_telnet', 'user', 'webtool', 'werl',
+ 'win32reg', 'wrap_log_reader', 'wx', 'wx_misc', 'wx_object',
+ 'wxAcceleratorEntry', 'wxAcceleratorTable', 'wxArtProvider',
+ 'wxAuiDockArt', 'wxAuiManager', 'wxAuiNotebook', 'wxAuiPaneInfo',
+ 'wxAuiTabArt', 'wxBitmap', 'wxBitmapButton', 'wxBitmapDataObject',
+ 'wxBoxSizer', 'wxBrush', 'wxBufferedDC', 'wxBufferedPaintDC',
+ 'wxButton', 'wxCalendarCtrl', 'wxCalendarDateAttr',
+ 'wxCalendarEvent', 'wxCaret', 'wxCheckBox', 'wxCheckListBox',
+ 'wxChildFocusEvent', 'wxChoice', 'wxClientDC', 'wxClipboard',
+ 'wxCloseEvent', 'wxColourData', 'wxColourDialog',
+ 'wxColourPickerCtrl', 'wxColourPickerEvent', 'wxComboBox',
+ 'wxCommandEvent', 'wxContextMenuEvent', 'wxControl',
+ 'wxControlWithItems', 'wxCursor', 'wxDataObject', 'wxDateEvent',
+ 'wxDatePickerCtrl', 'wxDC', 'wxDialog', 'wxDirDialog',
+ 'wxDirPickerCtrl', 'wxDisplayChangedEvent', 'wxEraseEvent',
+ 'wxEvent', 'wxEvtHandler', 'wxFileDataObject', 'wxFileDialog',
+ 'wxFileDirPickerEvent', 'wxFilePickerCtrl', 'wxFindReplaceData',
+ 'wxFindReplaceDialog', 'wxFlexGridSizer', 'wxFocusEvent', 'wxFont',
+ 'wxFontData', 'wxFontDialog', 'wxFontPickerCtrl',
+ 'wxFontPickerEvent', 'wxFrame', 'wxGauge', 'wxGBSizerItem',
+ 'wxGenericDirCtrl', 'wxGLCanvas', 'wxGraphicsBrush',
+ 'wxGraphicsContext', 'wxGraphicsFont', 'wxGraphicsMatrix',
+ 'wxGraphicsObject', 'wxGraphicsPath', 'wxGraphicsPen',
+ 'wxGraphicsRenderer', 'wxGrid', 'wxGridBagSizer', 'wxGridCellAttr',
+ 'wxGridCellEditor', 'wxGridCellRenderer', 'wxGridEvent',
+ 'wxGridSizer', 'wxHelpEvent', 'wxHtmlEasyPrinting', 'wxIcon',
+ 'wxIconBundle', 'wxIconizeEvent', 'wxIdleEvent', 'wxImage',
+ 'wxImageList', 'wxJoystickEvent', 'wxKeyEvent',
+ 'wxLayoutAlgorithm', 'wxListBox', 'wxListCtrl', 'wxListEvent',
+ 'wxListItem', 'wxListView', 'wxMask', 'wxMaximizeEvent',
+ 'wxMDIChildFrame', 'wxMDIClientWindow', 'wxMDIParentFrame',
+ 'wxMemoryDC', 'wxMenu', 'wxMenuBar', 'wxMenuEvent', 'wxMenuItem',
+ 'wxMessageDialog', 'wxMiniFrame', 'wxMirrorDC',
+ 'wxMouseCaptureChangedEvent', 'wxMouseEvent', 'wxMoveEvent',
+ 'wxMultiChoiceDialog', 'wxNavigationKeyEvent', 'wxNcPaintEvent',
+ 'wxNotebook', 'wxNotebookEvent', 'wxNotifyEvent',
+ 'wxPageSetupDialog', 'wxPageSetupDialogData', 'wxPaintDC',
+ 'wxPaintEvent', 'wxPalette', 'wxPaletteChangedEvent', 'wxPanel',
+ 'wxPasswordEntryDialog', 'wxPen', 'wxPickerBase', 'wxPostScriptDC',
+ 'wxPreviewCanvas', 'wxPreviewControlBar', 'wxPreviewFrame',
+ 'wxPrintData', 'wxPrintDialog', 'wxPrintDialogData', 'wxPrinter',
+ 'wxPrintout', 'wxPrintPreview', 'wxProgressDialog',
+ 'wxQueryNewPaletteEvent', 'wxRadioBox', 'wxRadioButton',
+ 'wxRegion', 'wxSashEvent', 'wxSashLayoutWindow', 'wxSashWindow',
+ 'wxScreenDC', 'wxScrollBar', 'wxScrolledWindow', 'wxScrollEvent',
+ 'wxScrollWinEvent', 'wxSetCursorEvent', 'wxShowEvent',
+ 'wxSingleChoiceDialog', 'wxSizeEvent', 'wxSizer', 'wxSizerFlags',
+ 'wxSizerItem', 'wxSlider', 'wxSpinButton', 'wxSpinCtrl',
+ 'wxSpinEvent', 'wxSplashScreen', 'wxSplitterEvent',
+ 'wxSplitterWindow', 'wxStaticBitmap', 'wxStaticBox',
+ 'wxStaticBoxSizer', 'wxStaticLine', 'wxStaticText', 'wxStatusBar',
+ 'wxStdDialogButtonSizer', 'wxStyledTextCtrl', 'wxStyledTextEvent',
+ 'wxSysColourChangedEvent', 'wxTextAttr', 'wxTextCtrl',
+ 'wxTextDataObject', 'wxTextEntryDialog', 'wxToggleButton',
+ 'wxToolBar', 'wxToolTip', 'wxTopLevelWindow', 'wxTreeCtrl',
+ 'wxTreeEvent', 'wxUpdateUIEvent', 'wxWindow', 'wxWindowCreateEvent',
+ 'wxWindowDC', 'wxWindowDestroyEvent', 'wxXmlResource', 'xmerl',
+ 'xmerl_eventp', 'xmerl_scan', 'xmerl_xpath', 'xmerl_xs',
+ 'xmerl_xsd', 'xref', 'yecc', 'zip', 'zlib', 'zlib_stub'
+ ),
+ // Binary modifiers
+ 6 => array(
+ 'big', 'binary', 'float', 'integer', 'little', 'signed', 'unit', 'unsigned'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '[', ']', '{', '}'),
+ 1 => array('->', ',', ';', '.'),
+ 2 => array('<<', '>>'),
+ 3 => array('=', '||', '-', '+', '*', '/', '++', '--', '!', '<', '>', '>=',
+ '=<', '==', '/=', '=:=', '=/=')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #186895;',
+ 2 => 'color: #014ea4;',
+ 3 => 'color: #fa6fff;',
+ 4 => 'color: #fa6fff;',
+ 5 => 'color: #ff4e18;',
+ 6 => 'color: #9d4f37;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #109ab8;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff7800;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff9600;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #004866;',
+ 1 => 'color: #6bb810;',
+ 2 => 'color: #ee3800;',
+ 3 => 'color: #014ea4;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #6941fd;',
+ 1 => 'color: #d400ed;',
+ 2 => 'color: #5400b3;',
+ 3 => 'color: #ff3c00;',
+ 4 => 'color: #6941fd;',
+ 5 => 'color: #45b3e6;',
+ 6 => 'color: #ff9600;',
+ 7 => 'color: #d400ed;',
+ 8 => 'color: #ff9600;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => 'http://erlang.org/doc/man/{FNAME}.html',
+ 6 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '-&gt;',
+ 2 => ':'
+ ),
+ 'REGEXPS' => array(
+ //�Macro definitions
+ 0 => array(
+ GESHI_SEARCH => '(-define\s*\()([a-zA-Z0-9_]+)(\(|,)',
+ GESHI_REPLACE => '\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\1',
+ GESHI_AFTER => '\3'
+ ),
+ // Record definitions
+ 1 => array(
+ GESHI_SEARCH => '(-record\s*\()([a-zA-Z0-9_]+)(,)',
+ GESHI_REPLACE => '\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\1',
+ GESHI_AFTER => '\3'
+ ),
+ // Precompiler directives
+ 2 => array(
+ GESHI_SEARCH => '(-)([a-z][a-zA-Z0-9_]*)(\()',
+ GESHI_REPLACE => '\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\1',
+ GESHI_AFTER => '\3'
+ ),
+ // Functions
+ 3 => array(
+ GESHI_SEARCH => '([a-z]\w*|\'\w*\')(\s*\()',
+ GESHI_REPLACE => '\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '\2'
+ ),
+ // Macros
+ 4 => array(
+ GESHI_SEARCH => '(\?)([a-zA-Z0-9_]+)',
+ GESHI_REPLACE => '\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\1',
+ GESHI_AFTER => ''
+ ),
+ // Variables - With hack to avoid interfering wish GeSHi internals
+ 5 => array(
+ GESHI_SEARCH => '([([{,<+*-\/=\s!]|&lt;)(?!(?:PIPE|SEMI|DOT|NUM|REG3XP\d*)\W)([A-Z_]\w*)(?!\w)',
+ GESHI_REPLACE => '\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\1',
+ GESHI_AFTER => ''
+ ),
+ // ASCII�codes
+ 6 => '(\$[a-zA-Z0-9_])',
+ // Records
+ 7 => array(
+ GESHI_SEARCH => '(#)([a-z][a-zA-Z0-9_]*)(\.|\{)',
+ GESHI_REPLACE => '\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\1',
+ GESHI_AFTER => '\3'
+ ),
+ // Numbers with a different radix
+ 8 => '(?<=>)(#[a-zA-Z0-9]*)'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 3 => array(
+ 'DISALLOWED_BEFORE' => '(?<![\w])',
+ 'DISALLOWED_AFTER' => ''//'(?=\s*\()'
+ ),
+ 5 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\'|)',
+ 'DISALLOWED_AFTER' => '(?=(\'|):)'
+ ),
+ 6 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\/|-)',
+ 'DISALLOWED_AFTER' => ''
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/euphoria.php b/platform/www/vendor/geshi/geshi/src/geshi/euphoria.php
new file mode 100644
index 0000000..35c99ec
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/euphoria.php
@@ -0,0 +1,138 @@
+<?php
+/*************************************************************************************
+ * euphoria.php
+ * ---------------------------------
+ * Author: Nicholas Koceja (nerketur@hotmail.com)
+ * Copyright: (c) 2010 Nicholas Koceja
+ * Release Version: 1.0.9.1
+ * Date Started: 11/24/2010
+ *
+ * Euphoria language file for GeSHi.
+ *
+ * Author's note: The colors are based off of the Euphoria Editor (ed.ex) colors.
+ * Also, I added comments in places so I could remember a few things about Euphoria.
+ *
+ *
+ * CHANGES
+ * -------
+ * <date-of-release> (1.0.8.9)
+ * - First Release
+ *
+ * TODO (updated <date-of-release>)
+ * -------------------------
+ * seperate the funtions from the procedures, and have a slight color change for each.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Euphoria',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array(), //Euphoria doesn't support multi-line comments
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array( // keywords
+ 'and', 'by', 'constant', 'do', 'else', 'elsif', 'end', 'exit',
+ 'for', 'function', 'global', 'if', 'include', 'not', 'or',
+ 'procedure', 'return', 'then', 'to', 'type', 'while', 'with',
+ 'without', 'xor'
+ ),
+ 2 => array( // built-ins
+ 'abort', 'and_bits', 'append', 'arctan', 'atom', 'c_func', 'call',
+ 'c_proc', 'call_func', 'call_proc', 'clear_screen', 'close', 'compare',
+ 'command_line', 'cos', 'date', 'equal', 'find', 'find_from', 'floor',
+ 'getc', 'getenv', 'gets', 'get_key', 'get_pixel', 'integer', 'length',
+ 'log', 'machine_func', 'machine_proc', 'match', 'match_from',
+ 'mem_copy', 'mem_set', 'not_bits', 'object', 'open', 'or_bits', 'peek',
+ 'peek4s', 'peek4u', 'pixel', 'platform', 'poke', 'poke4', 'position',
+ 'power', 'prepend', 'print', 'printf', 'profile', 'puts', 'rand',
+ 'remainder', 'repeat', 'routine_id', 'sequence', 'sin', 'sprintf',
+ 'sqrt', 'system', 'system_exec', 'tan', 'task_clock_stop',
+ 'task_clock_start', 'task_create', 'task_list', 'task_schedule',
+ 'task_self', 'task_status', 'task_suspend', 'task_yield', 'time',
+ 'trace', 'xor_bits'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '(', ')', '{', '}', '[', ']'
+ ),
+ 1 => array(
+ '+', '-', '*', '/', '=', '&', '^'
+ ),
+ 2 => array(
+ '&', '?', ','
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff; font-weight: bold;', // keywords
+ 2 => 'color: #cc33ff; font-weight: bold;', // builtins
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #ff0000; font-style: italic;',
+ 'MULTI' => '' // doesn't exist
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #009900; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #999900; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #00cc00;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc33cc; font-style: italic'
+ ),
+ 'METHODS' => array( // Doesn't exist in Euphoria. Everything is a function =)
+ 0 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #999900;', // brackets
+ 1 => 'color: #333333;', // operators
+ 2 => 'color: #333333; font-style: bold' // print+concat
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array( // Never included in scripts.
+ )
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/ezt.php b/platform/www/vendor/geshi/geshi/src/geshi/ezt.php
new file mode 100644
index 0000000..a02ebc4
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/ezt.php
@@ -0,0 +1,134 @@
+<?php
+/*************************************************************************************
+ * ezt.php
+ * -----------
+ * Author: Ramesh Vishveshwar (ramesh.vishveshwar@gmail.com)
+ * Copyright: (c) 2012 Ramesh Vishveshwar (http://thecodeisclear.in)
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/09/01
+ *
+ * Easytrieve language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2012/09/22 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'EZT',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'COMMENT_REGEXP' => array(
+ // First character of the line is an asterisk. Rest of the line is spaces/null
+ 0 => '/\*(\s|\D)?(\n)/',
+ // Asterisk followed by any character & then a non numeric character.
+ // This is to prevent expressions such as 25 * 4 from being marked as a comment
+ // Note: 25*4 - 100 will mark *4 - 100 as a comment. Pls. space out expressions
+ // In any case, 25*4 will result in an Easytrieve error
+ 1 => '/\*.([^0-9\n])+.*(\n)/'
+ ),
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'CONTROL','DEFINE','DISPLAY','DO','ELSE','END-DO','END-IF',
+ 'END-PROC','FILE','GET','GOTO','HEADING','IF','JOB','LINE',
+ 'PARM','PERFORM','POINT','PRINT','PROC','PUT','READ','RECORD',
+ 'REPORT','RETRIEVE','SEARCH','SELECT','SEQUENCE','SORT','STOP',
+ 'TITLE','WRITE'
+ ),
+ // Procedure Keywords (Names of specific procedures)
+ 2 => array (
+ 'AFTER-BREAK','AFTER-LINE','BEFORE-BREAK','BEFORE-LINE',
+ 'ENDPAGE','REPORT-INPUT','TERMINATION',
+ ),
+ // Macro names, Parameters
+ 3 => array (
+ 'COMPILE','CONCAT','DESC','GETDATE','MASK','PUNCH',
+ 'VALUE','SYNTAX','NEWPAGE','SKIP','COL','TALLY',
+ 'WITH'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(',')','=','&',',','*','>','<','%'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false
+ //4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #FF0000;',
+ 2 => 'color: #21A502;',
+ 3 => 'color: #FF00FF;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #0000FF; font-style: italic;',
+ 1 => 'color: #0000FF; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #FF7400;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #66CC66;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #736205;'
+ ),
+ 'METHODS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #FF7400;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #E01B6A;'
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ // We are trying to highlight Macro names here which preceded by %
+ 0 => '(%)([a-zA-Z0-9])+(\s|\n)'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/f1.php b/platform/www/vendor/geshi/geshi/src/geshi/f1.php
new file mode 100644
index 0000000..c6f93cc
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/f1.php
@@ -0,0 +1,149 @@
+<?php
+/*************************************************************************************
+ * f1.php
+ * -------
+ * Author: Juro Bystricky (juro@f1compiler.com)
+ * Copyright: K2 Software Corp.
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/07/06
+ *
+ * Formula One language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/07/06 (1.0.8.9)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ * - Add more RTL functions with URLs
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Formula One',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('{' => '}'),
+ 'COMMENT_REGEXP' => array(
+ //Nested Comments
+ 2 => "/(\{(?:\{.*\}|[^\{])*\})/m"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'",'"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[\\\\nrt\'\"?\n]#i",
+ //Hexadecimal Char Specs (Utf16 codes, Unicode versions only)
+ 2 => "#\\\\u[\da-fA-F]{4}#",
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE |
+ GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX_0O |
+ GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'pred','proc','subr','else','elsif','iff','if','then','false','true',
+ 'case','of','use','local','mod','end','list','file','all','one','max','min','rel',
+ 'external','Nil','_stdcall','_cdecl','_addressof','_pred','_file','_line'
+ ),
+ 2 => array(
+ 'Ascii','Bin','I','L','P','R','S','U'
+ ),
+ 3 => array(
+ 'Append','in','Dupl','Len','Print','_AllDifferent','_AllAscending',
+ '_AllDescending','_Ascending','_Descending'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '[', ']'),
+ 1 => array('<', '>','='),
+ 2 => array('+', '-', '*', '/'),
+ 3 => array('&', '|'),
+ 4 => array(':', ';')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #000080;',
+ 3 => 'color: #000080;',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000; font-style: italic;',
+ 2 => 'color: #008000; font-style: italic;',
+ 'MULTI' => 'color: #008000; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #009999; font-weight: bold;',
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #800000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;',
+ 1 => 'color: #000000;',
+ 2 => 'color: #000000;',
+ 3 => 'color: #000000;',
+ 4 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.f1compiler.com/f1helponline/f1_runtime_library.html#{FNAME}'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/falcon.php b/platform/www/vendor/geshi/geshi/src/geshi/falcon.php
new file mode 100644
index 0000000..6160cba
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/falcon.php
@@ -0,0 +1,217 @@
+<?php
+/*************************************************************************************
+ * falcon.php
+ * ---------------------------------
+ * Author: billykater (billykater+geshi@gmail.com)
+ * Copyright: (c) 2010 billykater (http://falconpl.org/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/06/07
+ *
+ * Falcon language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * <2010/8/1> (1.0.8.10)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Falcon',
+ 'COMMENT_SINGLE' => array( 1 => '//' ),
+ 'COMMENT_MULTI' => array( '/*' => '*/' ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array( "'", '"' ),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'break','case','catch','class','const','continue','def','default',
+ 'dropping','elif','else','end','enum','for','forfirst','forlast',
+ 'formiddle','from','function','global','if','init','innerfunc',
+ 'launch','loop','object','raise','return','select','state','static',
+ 'switch','try','while'
+ ),
+ 2 => array(
+ 'false','nil','true',
+ ),
+ 3 => array(
+ 'and','as','eq','fself','in','not','notin','or','provides','self','to'
+ ),
+ 4 => array(
+ 'directive','export','import','load','macro'
+ ),
+ 5 => array(
+ 'ArrayType','BooleanType','ClassMethodType','ClassType','DictionaryType',
+ 'FunctionType','MemBufType','MethodType','NilType','NumericType','ObjectType',
+ 'RangeType','StringType','LBindType'
+ ),
+ 6 => array(
+ "CurrentTime","IOStream","InputStream","MemBufFromPtr","OutputStream",
+ "PageDict","ParseRFC2822","abs","acos","all",
+ "allp","any","anyp","argd","argv",
+ "arrayAdd","arrayBuffer","arrayCompact","arrayDel","arrayDelAll",
+ "arrayFill","arrayFind","arrayHead","arrayIns","arrayMerge",
+ "arrayNM","arrayRemove","arrayResize","arrayScan","arraySort",
+ "arrayTail","asin","assert","atan","atan2",
+ "attributes","baseClass","beginCritical","bless","brigade",
+ "broadcast","cascade","ceil","choice","chr",
+ "className","clone","combinations","compare","consume",
+ "cos","deg2rad","deoob","derivedFrom","describe",
+ "deserialize","dictBack","dictBest","dictClear","dictFill",
+ "dictFind","dictFront","dictGet","dictKeys","dictMerge",
+ "dictRemove","dictSet","dictValues","dirChange","dirCurrent",
+ "dirMake","dirMakeLink","dirReadLink","dirRemove","dolist",
+ "endCritical","epoch","eval","exit","exp",
+ "factorial","fileChgroup","fileChmod","fileChown","fileCopy",
+ "fileExt","fileMove","fileName","fileNameMerge","filePath",
+ "fileRemove","fileType","fileUnit","filter","fint",
+ "firstOf","floop","floor","fract","getAssert",
+ "getEnviron","getProperty","getSlot","getSystemEncoding","getenv",
+ "iff","include","input","inspect","int",
+ "isBound","isCallable","isoob","lbind","len",
+ "let","lit","log","map","max",
+ "metaclass","min","numeric","oob","ord",
+ "paramCount","paramIsRef","paramSet","parameter","passvp",
+ "permutations","pow","print","printl","properties",
+ "rad2deg","random","randomChoice","randomDice","randomGrab",
+ "randomPick","randomSeed","randomWalk","readURI","reduce",
+ "retract","round","seconds","serialize","set",
+ "setProperty","setenv","sin","sleep","stdErr",
+ "stdErrRaw","stdIn","stdInRaw","stdOut","stdOutRaw",
+ "strBack","strBackFind","strBackTrim","strBuffer","strCmpIgnoreCase",
+ "strEndsWith","strEscape","strEsq","strFill","strFind",
+ "strFromMemBuf","strFront","strFrontTrim","strLower","strMerge",
+ "strReplace","strReplicate","strSplit","strSplitTrimmed","strStartsWith",
+ "strToMemBuf","strTrim","strUnescape","strUnesq","strUpper",
+ "strWildcardMatch","subscribe","systemErrorDescription","tan","times",
+ "toString","transcodeFrom","transcodeTo","typeOf","unsetenv",
+ "unsubscribe","valof","vmFalconPath","vmIsMain","vmModuleName",
+ "vmModuleVersionInfo","vmSearchPath","vmSystemType","vmVersionInfo","vmVersionName",
+ "writeURI","xmap","yield","yieldOut"
+ ),
+ 7 => array(
+ "AccessError","Array","BOM","Base64","Class",
+ "ClassMethod","CloneError","CmdlineParser","CodeError","Continuation",
+ "Dictionary","Directory","Error","FileStat","Format",
+ "Function","GarbagePointer","GenericError","Integer","InterruptedError",
+ "IoError","Iterator","LateBinding","List","MathError",
+ "MemoryBuffer","MessageError","Method","Numeric","Object",
+ "ParamError","ParseError","Path","Range","Semaphore",
+ "Sequence","Set","Stream","String","StringStream",
+ "SyntaxError","Table","TableError","TimeStamp","TimeZone",
+ "Tokenizer","TypeError","URI","VMSlot"
+ ),
+ 8 => array(
+ "args","scriptName","scriptPath"
+ ),
+ 9 => array(
+ "GC"
+ ),
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => 'http://falconpl.org/project_docs/core/functions.html#typeOf',
+ 6 => 'http://falconpl.org/project_docs/core/functions.html#{FNAME}',
+ 7 => 'http://falconpl.org/project_docs/core/class_{FNAME}.html',
+ 8 => 'http://falconpl.org/project_docs/core/globals.html#{FNAME}',
+ 9 => 'http://falconpl.org/project_docs/core/object_{FNAME}.html)'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true
+ ),
+ 'SYMBOLS' => array(
+ '(',')','$','%','&','/','{','[',']','=','}','?','+','-','#','*','@',
+ '<','>','|',',',':',';','\\','^'
+ ),
+ 'REGEXPS' => array(
+ 0 => array(
+ GESHI_SEARCH => '(\[)([a-zA-Z_]|\c{C})(?:[a-zA-Z0-9_]|\p{C})*(\])',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3',
+
+ ),
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array( '<?' => '?>' )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000080;font-weight:bold;',
+ 2 => 'color: #800000;font-weight:bold;',
+ 3 => 'color: #800000;font-weight:bold;',
+ 4 => 'color: #000080;font-weight:bold;',
+ 5 => 'color: #000000;font-weight:bold;',
+ 6 => 'font-weight:bold;',
+ 7 => 'font-weight:bold;',
+ 8 => 'font-weight:bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #29B900;',
+ 'MULTI' => 'color: #008080'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #800000'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #800000'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #000000'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #8B0513'
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #FF00FF'
+ )
+ ),
+
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ '.'
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/fo.php b/platform/www/vendor/geshi/geshi/src/geshi/fo.php
new file mode 100644
index 0000000..c9dca6c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/fo.php
@@ -0,0 +1,326 @@
+<?php
+/*************************************************************************************
+ * fo.php
+ * --------
+ * Author: Tan-Vinh Nguyen (tvnguyen@web.de)
+ * Copyright: (c) 2009 Tan-Vinh Nguyen
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/03/23
+ *
+ * fo language file for GeSHi.
+ *
+ * FO stands for "Flexible Oberflaechen" (Flexible Surfaces) and
+ * is part of the abas-ERP.
+ *
+ * CHANGES
+ * -------
+ * 2009/03/23 (1.0.0)
+ * - First Release
+ * Basic commands in German and English
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'FO (abas-ERP)',
+ 'COMMENT_SINGLE' => array(1 => '..'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ //Control Flow
+ 1 => array(
+ /* see http://www.abas.de/sub_de/kunden/help/hd/html/9.html */
+
+ /* fo keywords, part 1: control flow */
+ '.weiter', '.continue'
+
+ /* this language works with goto's only*/
+ ),
+
+ //FO Keywords
+ 2 => array(
+ /* fo keywords, part 2 */
+ '.fo', '.formel', '.formula',
+ '.zuweisen', '.assign',
+ '.fehler', '.error',
+ '.ende', '.end'
+ ),
+
+ //Java Keywords
+ 3 => array(
+ /* Java keywords, part 3: primitive data types */
+ '.art', '.type',
+ 'integer', 'real', 'bool', 'text', 'datum', 'woche', 'termin', 'zeit',
+ 'mehr', 'MEHR'
+ ),
+
+ //Reserved words in fo literals
+ 4 => array(
+ /* other reserved words in fo literals */
+ /* should be styled to look similar to numbers and Strings */
+ 'false', 'null', 'true',
+ 'OBJEKT',
+ 'VORGANG', 'PROCESS',
+ 'OFFEN', 'OPEN',
+ 'ABORT',
+ 'AN', 'ADDEDTO',
+ 'AUF', 'NEW',
+ 'BILDSCHIRM', 'TERMINAL',
+ 'PC',
+ 'MASKE', 'SCREEN',
+ 'ZEILE', 'LINE'
+ ),
+
+ // interpreter settings
+ 5 => array (
+ '..!INTERPRETER', 'DEBUG'
+ ),
+
+ // database commands
+ 6 => array (
+ '.hole', '.hol', '.select',
+ '.lade', '.load',
+ '.aktion', '.action',
+ '.belegen', '.occupy',
+ '.bringe', '.rewrite',
+ '.dazu', '.add',
+ '.löschen', '.delete',
+ '.mache', '.make',
+ '.merke', '.reserve',
+ '.setze', '.set',
+ 'SPERREN', 'LOCK',
+ 'TEIL', 'PART',
+ 'KEINESPERRE',
+ 'AMASKE', 'ASCREEN',
+ 'BETRIEB', 'WORK-ORDER',
+ 'NUMERISCH', 'NUMERICAL',
+ 'VORSCHLAG', 'SUGGESTION',
+ 'OBLIGO', 'OUTSTANDING',
+ 'LISTE', 'LIST',
+ 'DRUCK', 'PRINT',
+ 'ÃœBERNAHME', 'TAGEOVER',
+ 'ABLAGE', 'FILINGSYSTEM',
+ 'BDE', 'PDC',
+ 'BINDUNG', 'ALLOCATION',
+ 'BUCHUNG', 'ENTRY',
+ 'COLLI', 'SERIAL',
+ 'DATEI', 'FILE',
+ 'VERKAUF', 'SALES',
+ 'EINKAUF', 'PURCHASING',
+ 'EXEMPLAR', 'EXAMPLE',
+ 'FERTIGUNG', 'PRODUCTION',
+ 'FIFO',
+ 'GRUPPE', 'GROUP',
+ 'JAHR', 'YEAR',
+ 'JOURNAL',
+ 'KOPF', 'HEADER',
+ 'KOSTEN',
+ 'LIFO',
+ 'LMENGE', 'SQUANTITY',
+ 'LOHNFERTIGUNG', 'SUBCONTRACTING',
+ 'LPLATZ', 'LOCATION',
+ 'MBELEGUNG', 'MACHLOADING',
+ 'MONAT', 'MONTH', 'MZ',
+ 'NACHRICHT', 'MESSAGE',
+ 'PLAN', 'TARGET',
+ 'REGIONEN', 'REGIONS',
+ 'SERVICEANFRAGE', 'SERVICEREQUEST',
+ 'VERWENDUNG', 'APPLICATION',
+ 'WEITER', 'CONTINUE',
+ 'ABBRUCH', 'CANCEL',
+ 'ABLAGEKENNZEICHEN', 'FILLINGCODE',
+ 'ALLEIN', 'SINGLEUSER',
+ 'AUFZAEHLTYP', 'ENUMERATION-TYPE',
+ 'AUSGABE', 'OUTPUT',
+ 'DEZPUNKT', 'DECPOINT'
+ ),
+
+ // output settings
+ 7 => array (
+ '.absatz', '.para',
+ '.blocksatz', '.justified',
+ '.flattersatz', '.unjustified',
+ '.format',
+ '.box',
+ '.drucken', '.print',
+ '.gedruckt', '.printed',
+ '.länge', '.length',
+ '.links', '.left',
+ '.rechts', '.right',
+ '.oben', '.up',
+ '.unten', '.down',
+ '.seite', '.page',
+ '.tabellensatz', '.tablerecord',
+ '.trenner', '.separator',
+ 'ARCHIV'
+ ),
+
+ // text commands
+ 8 => array (
+ '.text',
+ '.atext',
+ '.println',
+ '.uebersetzen', '.translate'
+ ),
+
+ // I/O commands
+ 9 => array (
+ '.aus', '.ausgabe', '.output',
+ '.ein', '.eingabe', '.input',
+ '.datei', '.file',
+ '.lesen', '.read',
+ '.sortiere', '.sort',
+ '-ÖFFNEN', '-OPEN',
+ '-TEST',
+ '-LESEN', '-READ',
+ 'VON', 'FROM'
+ ),
+
+ //system
+ 10 => array (
+ '.browser',
+ '.kommando', '.command',
+ '.system', '.dde',
+ '.editiere', '.edit',
+ '.hilfe', '.help',
+ '.kopieren', '.copy',
+ '.pc.clip',
+ '.pc.copy',
+ '.pc.dll',
+ '.pc.exec',
+ '.pc.open',
+ 'DIAGNOSE', 'ERRORREPORT',
+ 'DOPPELPUNKT', 'COLON',
+ 'ERSETZUNG', 'REPLACEMENT',
+ 'WARTEN', 'PARALLEL'
+ ),
+
+ //fibu/accounting specific commands
+ 11 => array (
+ '.budget',
+ '.chart',
+ 'VKZ',
+ 'KONTO', 'ACCOUNT',
+ 'AUSZUG', 'STATEMENT',
+ 'WAEHRUNG', 'CURRENCY',
+ 'WAEHRUNGSKURS', 'EXCHANGERATE',
+ 'AUSWAEHR', 'FORCURR',
+ 'BUCHUNGSKREIS', 'SET OF BOOKS'
+ ),
+
+ // efop - extended flexible surface
+ 12 => array (
+ '.cursor',
+ '.farbe', '.colour',
+ '.fenster', '.window',
+ '.hinweis', '.note',
+ '.menue', '.menu',
+ '.schutz', '.protection',
+ '.zeigen', '.view',
+ '.zeile', '.line',
+ 'VORDERGRUND', 'FOREGROUND',
+ 'HINTERGRUND', 'BACKGROUND',
+ 'SOFORT', 'IMMEDIATELY',
+ 'AKTUALISIEREN', 'UPDATE',
+ 'FENSTERSCHLIESSEN', 'CLOSEWINDOWS'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '[', ']', '{', '}', '*', '&', '%', ';', '<', '>'),
+ 1 => array('?', '!')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ /* all fo keywords are case sensitive, don't have to but I like this type of coding */
+ 1 => true, 2 => true, 3 => true, 4 => true,
+ 5 => true, 6 => true, 7 => true, 8 => true, 9 => true,
+ 10 => true, 11 => true, 12 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #006600; font-weight: bold;',
+ 4 => 'color: #006600; font-weight: bold;',
+ 5 => 'color: #003399; font-weight: bold;',
+ 6 => 'color: #003399; font-weight: bold;',
+ 7 => 'color: #003399; font-weight: bold;',
+ 8 => 'color: #003399; font-weight: bold;',
+ 9 => 'color: #003399; font-weight: bold;',
+ 10 => 'color: #003399; font-weight: bold;',
+ 11 => 'color: #003399; font-weight: bold;',
+ 12 => 'color: #003399; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ //2 => 'color: #006699;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006633;',
+ 2 => 'color: #006633;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;',
+ 1 => 'color: #000000; font-weight: bold;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+ 9 => '',
+ 10 => '',
+ 11 => '',
+ 12 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/fortran.php b/platform/www/vendor/geshi/geshi/src/geshi/fortran.php
new file mode 100644
index 0000000..6e41e9d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/fortran.php
@@ -0,0 +1,158 @@
+<?php
+/*************************************************************************************
+ * fortran.php
+ * -----------
+ * Author: Cedric Arrabie (cedric.arrabie@univ-pau.fr)
+ * Copyright: (C) 2006 Cetric Arrabie
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/04/22
+ *
+ * Fortran language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2006/04/20 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ * - Get a list of inbuilt functions to add (and explore fortran more
+ * to complete this rather bare language file)
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME'=>'Fortran',
+ 'COMMENT_SINGLE'=> array(1 =>'!',2=>'Cf2py'),
+ 'COMMENT_MULTI'=> array(),
+ //Fortran Comments
+ 'COMMENT_REGEXP' => array(1 => '/^C.*?$/mi'),
+ 'CASE_KEYWORDS'=> GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS'=> array("'",'"'),
+ 'ESCAPE_CHAR'=>'\\',
+ 'KEYWORDS'=> array(
+ 1 => array(
+ 'allocate','block','call','case','contains','continue','cycle','deallocate',
+ 'default','do','else','elseif','elsewhere','end','enddo','endif','endwhere',
+ 'entry','exit','function','go','goto','if','interface','module','nullify','only',
+ 'operator','procedure','program','recursive','return','select','stop',
+ 'subroutine','then','to','where','while',
+ 'access','action','advance','blank','blocksize','carriagecontrol',
+ 'delim','direct','eor','err','exist','file','flen','fmt','form','formatted',
+ 'iostat','name','named','nextrec','nml','number','opened','pad','position',
+ 'readwrite','recl','sequential','status','unformatted','unit'
+ ),
+ 2 => array(
+ '.AND.','.EQ.','.EQV.','.GE.','.GT.','.LE.','.LT.','.NE.','.NEQV.','.NOT.',
+ '.OR.','.TRUE.','.FALSE.'
+ ),
+ 3 => array(
+ 'allocatable','character','common','complex','data','dimension','double',
+ 'equivalence','external','implicit','in','inout','integer','intent','intrinsic',
+ 'kind','logical','namelist','none','optional','out','parameter','pointer',
+ 'private','public','real','result','save','sequence','target','type','use'
+ ),
+ 4 => array(
+ 'abs','achar','acos','adjustl','adjustr','aimag','aint','all','allocated',
+ 'anint','any','asin','atan','atan2','bit_size','break','btest','carg',
+ 'ceiling','char','cmplx','conjg','cos','cosh','cpu_time','count','cshift',
+ 'date_and_time','dble','digits','dim','dot_product','dprod dvchk',
+ 'eoshift','epsilon','error','exp','exponent','floor','flush','fraction',
+ 'getcl','huge','iachar','iand','ibclr','ibits','ibset','ichar','ieor','index',
+ 'int','intrup','invalop','ior','iostat_msg','ishft','ishftc','lbound',
+ 'len','len_trim','lge','lgt','lle','llt','log','log10','matmul','max','maxexponent',
+ 'maxloc','maxval','merge','min','minexponent','minloc','minval','mod','modulo',
+ 'mvbits','nbreak','ndperr','ndpexc','nearest','nint','not','offset','ovefl',
+ 'pack','precfill','precision','present','product','prompt','radix',
+ 'random_number','random_seed','range','repeat','reshape','rrspacing',
+ 'scale','scan','segment','selected_int_kind','selected_real_kind',
+ 'set_exponent','shape','sign','sin','sinh','size','spacing','spread','sqrt',
+ 'sum system','system_clock','tan','tanh','timer','tiny','transfer','transpose',
+ 'trim','ubound','undfl','unpack','val','verify'
+ ),
+ ),
+ 'SYMBOLS'=> array(
+ '(',')','{','}','[',']','=','+','-','*','/','!','%','^','&',':'
+ ),
+ 'CASE_SENSITIVE'=> array(
+ GESHI_COMMENTS => true,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES'=> array(
+ 'KEYWORDS'=> array(
+ 1 =>'color: #b1b100;',
+ 2 =>'color: #000000; font-weight: bold;',
+ 3 =>'color: #000066;',
+ 4 =>'color: #993333;'
+ ),
+ 'COMMENTS'=> array(
+ 1 =>'color: #666666; font-style: italic;',
+ 2 =>'color: #339933;',
+ 'MULTI'=>'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR'=> array(
+ 0 =>'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS'=> array(
+ 0 =>'color: #009900;'
+ ),
+ 'STRINGS'=> array(
+ 0 =>'color: #ff0000;'
+ ),
+ 'NUMBERS'=> array(
+ 0 =>'color: #cc66cc;'
+ ),
+ 'METHODS'=> array(
+ 1 =>'color: #202020;',
+ 2 =>'color: #202020;'
+ ),
+ 'SYMBOLS'=> array(
+ 0 =>'color: #339933;'
+ ),
+ 'REGEXPS'=> array(
+ ),
+ 'SCRIPT'=> array(
+ )
+ ),
+ 'URLS'=> array(
+ 1 =>'',
+ 2 =>'',
+ 3 =>'',
+ 4 =>''
+ ),
+ 'OOLANG'=> true,
+ 'OBJECT_SPLITTERS'=> array(
+ 1 =>'.',
+ 2 =>'::'
+ ),
+ 'REGEXPS'=> array(
+ ),
+ 'STRICT_MODE_APPLIES'=> GESHI_NEVER,
+ 'SCRIPT_DELIMITERS'=> array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK'=> array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/freebasic.php b/platform/www/vendor/geshi/geshi/src/geshi/freebasic.php
new file mode 100644
index 0000000..952d8f1
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/freebasic.php
@@ -0,0 +1,139 @@
+<?php
+/*************************************************************************************
+ * freebasic.php
+ * -------------
+ * Author: Roberto Rossi
+ * Copyright: (c) 2005 Roberto Rossi (http://rsoftware.altervista.org)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/08/19
+ *
+ * FreeBasic (http://www.freebasic.net/) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/08/19 (1.0.0)
+ * - First Release
+ *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'FreeBasic',
+ 'COMMENT_SINGLE' => array(1 => "'", 2 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ "append", "as", "asc", "asin", "asm", "atan2", "atn", "beep", "bin", "binary", "bit",
+ "bitreset", "bitset", "bload", "bsave", "byref", "byte", "byval", "call",
+ "callocate", "case", "cbyte", "cdbl", "cdecl", "chain", "chdir", "chr", "cint",
+ "circle", "clear", "clng", "clngint", "close", "cls", "color", "command",
+ "common", "cons", "const", "continue", "cos", "cshort", "csign", "csng",
+ "csrlin", "cubyte", "cuint", "culngint", "cunsg", "curdir", "cushort", "custom",
+ "cvd", "cvi", "cvl", "cvlongint", "cvs", "cvshort", "data", "date",
+ "deallocate", "declare", "defbyte", "defdbl", "defined", "defint", "deflng",
+ "deflngint", "defshort", "defsng", "defstr", "defubyte", "defuint",
+ "defulngint", "defushort", "dim", "dir", "do", "double", "draw", "dylibload",
+ "dylibsymbol", "else", "elseif", "end", "enum", "environ", 'environ$', "eof",
+ "eqv", "erase", "err", "error", "exec", "exepath", "exit", "exp", "export",
+ "extern", "field", "fix", "flip", "for", "fre", "freefile", "function", "get",
+ "getjoystick", "getkey", "getmouse", "gosub", "goto", "hex", "hibyte", "hiword",
+ "if", "iif", "imagecreate", "imagedestroy", "imp", "inkey", "inp", "input",
+ "instr", "int", "integer", "is", "kill", "lbound", "lcase", "left", "len",
+ "let", "lib", "line", "lobyte", "loc", "local", "locate", "lock", "lof", "log",
+ "long", "longint", "loop", "loword", "lset", "ltrim", "mid", "mkd", "mkdir",
+ "mki", "mkl", "mklongint", "mks", "mkshort", "mod", "multikey", "mutexcreate",
+ "mutexdestroy", "mutexlock", "mutexunlock", "name", "next", "not", "oct", "on",
+ "once", "open", "option", "or", "out", "output", "overload", "paint", "palette",
+ "pascal", "pcopy", "peek", "peeki", "peeks", "pipe", "pmap", "point", "pointer",
+ "poke", "pokei", "pokes", "pos", "preserve", "preset", "print", "private",
+ "procptr", "pset", "ptr", "public", "put", "random", "randomize", "read",
+ "reallocate", "redim", "rem", "reset", "restore", "resume",
+ "return", "rgb", "rgba", "right", "rmdir", "rnd", "rset", "rtrim", "run",
+ "sadd", "screen", "screencopy", "screeninfo", "screenlock", "screenptr",
+ "screenres", "screenset", "screensync", "screenunlock", "seek", "statement",
+ "selectcase", "setdate", "setenviron", "setmouse",
+ "settime", "sgn", "shared", "shell", "shl", "short", "shr", "sin", "single",
+ "sizeof", "sleep", "space", "spc", "sqr", "static", "stdcall", "step", "stop",
+ "str", "string", "strptr", "sub", "swap", "system", "tab", "tan",
+ "then", "threadcreate", "threadwait", "time", "timer", "to", "trans",
+ "trim", "type", "ubound", "ubyte", "ucase", "uinteger", "ulongint", "union",
+ "unlock", "unsigned", "until", "ushort", "using", "va_arg", "va_first",
+ "va_next", "val", "val64", "valint", "varptr", "view", "viewprint", "wait",
+ "wend", "while", "width", "window", "windowtitle", "with", "write", "xor",
+ "zstring", "explicit", "escape", "true", "false"
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080;',
+ 2 => 'color: #339933;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/freeswitch.php b/platform/www/vendor/geshi/geshi/src/geshi/freeswitch.php
new file mode 100644
index 0000000..a4729a4
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/freeswitch.php
@@ -0,0 +1,166 @@
+<?php
+/*************************************************************************************
+ * freeswitch.php
+ * --------
+ * Author: James Rose (james.gs@stubbornroses.com)
+ * Copyright: (c) 2006 Christian Lescuyer http://xtian.goelette.info
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/11/18
+ *
+ * FreeSWITCH language file for GeSHi.
+ *
+ * This file is based on robots.php
+ *
+ * 2011/11/18 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'FreeSWITCH',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(1 => "/^Comment:.*?$/m"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+// 1 => array(
+// 'Disallow', 'Request-rate', 'Robot-version',
+// 'Sitemap', 'User-agent', 'Visit-time'
+// )
+ ),
+ 'SYMBOLS' => array(
+// ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false
+ ),
+
+//order is important. regexes will overwrite most things....
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+// 1 => 'color: #FF0000; font-weight: bold;',//red
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+// 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+// 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+// 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+// 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: firebrick; font-weight: bold;',
+ 1 => 'color: cornflowerblue; font-weight: bold;',
+ 2 => 'color: goldenrod; font-weight: bold;',
+ 3 => 'color: green; font-weight: bold;',
+ 4 => 'color: dimgrey; font-style: italic;',
+ 5 => 'color: green; font-weight: bold;',
+ 6 => 'color: firebrick; font-weight: bold;',
+ 7 => 'color: indigo; font-weight: italic;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+// 1 => 'http://www.robotstxt.org/wc/norobots.html'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => array(
+ GESHI_SEARCH => '(^.*ERROR.*)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'im',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 1 => array(
+ GESHI_SEARCH => '(^.*NOTICE.*)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'im',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 2 => array(
+ GESHI_SEARCH => '(^.*DEBUG.*)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 3 => array(
+ GESHI_SEARCH => '(^.*INFO.*|.*info\(.*|^Channel.*|^Caller.*|^variable.*)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 4 => array(
+ GESHI_SEARCH => '(^Dialplan.*)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'im',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 5 => array(
+ GESHI_SEARCH => '(Regex\ \(PASS\))',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 6 => array(
+ GESHI_SEARCH => '(Regex\ \(FAIL\))',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 7 => array(
+ GESHI_SEARCH => '(\d{7,15})',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ )
+ ),
+
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/fsharp.php b/platform/www/vendor/geshi/geshi/src/geshi/fsharp.php
new file mode 100644
index 0000000..c88c4c2
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/fsharp.php
@@ -0,0 +1,211 @@
+<?php
+/*************************************************************************************
+ * fsharp.php
+ * ----------
+ * Author: julien ortin (jo_spam-divers@yahoo.fr)
+ * Copyright: (c) 2009 julien ortin
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/09/20
+ *
+ * F# language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/09/22 (1.0.1)
+ * - added rules for single char handling (generics ['a] vs char ['x'])
+ * - added symbols and keywords
+ * 2009/09/20 (1.0.0)
+ * - Initial release
+ *
+ * TODO
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'F#',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(3 => '/\(\*(?!\)).*?\*\)/s'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'HARDQUOTE' => array('@"', '"'),
+ 'HARDESCAPE' => array('"'),
+ 'HARDCHAR' => '"',
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ /* main F# keywords */
+ /* section 3.4 */
+ 1 => array(
+ 'abstract', 'and', 'as', 'assert', 'base', 'begin', 'class', 'default', 'delegate', 'do', 'done',
+ 'downcast', 'downto', 'elif', 'else', 'end', 'exception', 'extern', 'false', 'finally', 'for',
+ 'fun', 'function', 'if', 'in', 'inherit', 'inline', 'interface', 'internal', 'lazy', 'let',
+ 'match', 'member', 'module', 'mutable', 'namespace', 'new', 'not', 'null', 'of', 'open', 'or',
+ 'override', 'private', 'public', 'rec', 'return', 'sig', 'static', 'struct', 'then', 'to',
+ 'true', 'try', 'type', 'upcast', 'use', 'val', 'void', 'when', 'while', 'with', 'yield',
+ 'asr', 'land', 'lor', 'lsl', 'lsr', 'lxor', 'mod',
+ /* identifiers are reserved for future use by F# */
+ 'atomic', 'break', 'checked', 'component', 'const', 'constraint', 'constructor',
+ 'continue', 'eager', 'fixed', 'fori', 'functor', 'global', 'include', 'method', 'mixin',
+ 'object', 'parallel', 'params', 'process', 'protected', 'pure', 'sealed', 'tailcall',
+ 'trait', 'virtual', 'volatile',
+ /* take monads into account */
+ 'let!', 'yield!'
+ ),
+ /* define names of main libraries in F# Core, so we can link to it
+ * http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/namespaces.html
+ */
+ 2 => array(
+ 'Array', 'Array2D', 'Array3D', 'Array4D', 'ComparisonIdentity', 'HashIdentity', 'List',
+ 'Map', 'Seq', 'SequenceExpressionHelpers', 'Set', 'CommonExtensions', 'Event',
+ 'ExtraTopLevelOperators', 'LanguagePrimitives', 'NumericLiterals', 'Operators',
+ 'OptimizedClosures', 'Option', 'String', 'NativePtr', 'Printf'
+ ),
+ /* 17.2 & 17.3 */
+ 3 => array(
+ 'abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'exp',
+ 'floor', 'log', 'log10', 'pown', 'round', 'sign', 'sin', 'sinh', 'sqrt',
+ 'tan', 'tanh',
+ 'ignore',
+ 'fst', 'snd',
+ 'stdin', 'stdout', 'stderr',
+ 'KeyValue',
+ 'max', 'min'
+ ),
+ /* Pervasives Types & Overloaded Conversion Functions */
+ 4 => array(
+ 'bool', 'byref', 'byte', 'char', 'decimal', 'double', 'exn', 'float', 'float32',
+ 'FuncConvert', 'ilsigptr', 'int', 'int16', 'int32', 'int64', 'int8',
+ 'nativeint', 'nativeptr', 'obj', 'option', 'ref', 'sbyte', 'single', 'string', 'uint16',
+ 'uint32', 'uint64', 'uint8', 'unativeint', 'unit',
+ 'enum',
+ 'async', 'seq', 'dict'
+ ),
+ /* 17.2 Exceptions */
+ 5 => array (
+ 'failwith', 'invalidArg', 'raise', 'rethrow'
+ ),
+ /* 3.3 Conditional compilation & 13.3 Compiler Directives + light / light off */
+ 6 => array(
+ '(*IF-FSHARP', 'ENDIF-FSHARP*)', '(*F#', 'F#*)', '(*IF-OCAML', 'ENDIF-OCAML*)',
+ '#light',
+ '#if', '#else', '#endif', '#indent', '#nowarn', '#r', '#reference',
+ '#I', '#Include', '#load', '#time', '#help', '#q', '#quit',
+ ),
+ /* 3.11 Pre-processor Declarations / Identifier Replacements */
+ 7 => array(
+ '__SOURCE_DIRECTORY__', '__SOURCE_FILE__', '__LINE__'
+ ),
+ /* 17.2 Object Transformation Operators */
+ 8 => array(
+ 'box', 'hash', 'sizeof', 'typeof', 'typedefof', 'unbox'
+ )
+ ),
+ /* 17.2 basic operators + the yield and yield! arrows */
+ 'SYMBOLS' => array(
+ 1 => array('+', '-', '/', '*', '**', '%', '~-'),
+ 2 => array('<', '<=', '>', '<=', '=', '<>'),
+ 3 => array('<<<', '>>>', '^^^', '&&&', '|||', '~~~'),
+ 4 => array('|>', '>>', '<|', '<<'),
+ 5 => array('!', '->', '->>'),
+ 6 => array('[',']','(',')','{','}', '[|', '|]', '(|', '|)'),
+ 7 => array(':=', ';', ';;')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true, /* keywords */
+ 2 => true, /* modules */
+ 3 => true, /* pervasives functions */
+ 4 => true, /* types and overloaded conversion operators */
+ 5 => true, /* exceptions */
+ 6 => true, /* conditional compilation & compiler Directives */
+ 7 => true, /* pre-processor declarations / identifier replacements */
+ 8 => true /* object transformation operators */
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 2 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 3 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 4 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 5 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 6 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 7 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 8 => 'color: #06c; font-weight: bold;' /* nice blue */
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #5d478b; font-style: italic;', /* light purple */
+ 1 => 'color: #5d478b; font-style: italic;',
+ 2 => 'color: #5d478b; font-style: italic;', /* light purple */
+ 3 => 'color: #5d478b; font-style: italic;' /* light purple */
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #6c6;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #3cb371;' /* nice green */
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #c6c;' /* pink */
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #060;' /* dark green */
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #a52a2a;' /* maroon */
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ /* some of keywords are Pervasives functions (land, lxor, asr, ...) */
+ 1 => '',
+ 2 => 'http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/namespaces.html',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#>|^])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%\\-])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/gambas.php b/platform/www/vendor/geshi/geshi/src/geshi/gambas.php
new file mode 100644
index 0000000..9993a6c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/gambas.php
@@ -0,0 +1,212 @@
+<?php
+/*************************************************************************************
+ * gambas.php
+ * ---------
+ * Author: Jesus Guardon (jguardon@telefonica.net)
+ * Copyright: (c) 2009 Jesus Guardon (http://gambas-es.org),
+ * Benny Baumann (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/20
+ *
+ * GAMBAS language file for GeSHi.
+ * GAMBAS Official Site: http://gambas.sourceforge.net
+ *
+ * CHANGES
+ * -------
+ * 2009/09/26 (1.0.1)
+ * - Splitted dollar-ended keywords in another group to match with or without '$'
+ * - Modified URL for object/components keywords search through Google "I'm feeling lucky"
+ * 2009/09/23 (1.0.0)
+ * - Initial release
+ *
+ * TODO (updated 2009/09/26)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'GAMBAS',
+ 'COMMENT_SINGLE' => array(1 => "'"),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ //keywords
+ 1 => array(
+ 'APPEND', 'AS', 'BREAK', 'BYREF', 'CASE', 'CATCH', 'CLASS', 'CLOSE', 'CONST', 'CONTINUE', 'COPY',
+ 'CREATE', 'DEBUG', 'DEC', 'DEFAULT', 'DIM', 'DO', 'EACH', 'ELSE', 'END', 'ENDIF', 'ERROR', 'EVENT', 'EXEC',
+ 'EXPORT', 'EXTERN', 'FALSE', 'FINALLY', 'FLUSH', 'FOR', 'FUNCTION', 'GOTO', 'IF', 'IN', 'INC', 'INHERITS',
+ 'INPUT', 'FROM', 'IS', 'KILL', 'LAST', 'LIBRARY', 'LIKE', 'LINE INPUT', 'LINK', 'LOCK', 'LOOP', 'ME',
+ 'MKDIR', 'MOVE', 'NEW', 'NEXT', 'NULL', 'OPEN', 'OPTIONAL', 'OUTPUT', 'PIPE', 'PRINT', 'PRIVATE',
+ 'PROCEDURE', 'PROPERTY', 'PUBLIC', 'QUIT', 'RAISE', 'RANDOMIZE', 'READ', 'REPEAT', 'RETURN', 'RMDIR',
+ 'SEEK', 'SELECT', 'SHELL', 'SLEEP', 'STATIC', 'STEP', 'STOP', 'SUB', 'SUPER', 'SWAP', 'THEN', 'TO',
+ 'TRUE', 'TRY', 'UNLOCK', 'UNTIL', 'WAIT', 'WATCH', 'WEND', 'WHILE', 'WITH', 'WRITE'
+ ),
+ //functions
+ 2 => array(
+ 'Abs', 'Access', 'Acos', 'Acosh', 'Alloc', 'Ang', 'Asc', 'ASin', 'ASinh', 'Asl', 'Asr', 'Assign', 'Atan',
+ 'ATan2', 'ATanh',
+ 'BChg', 'BClr', 'Bin', 'BSet', 'BTst',
+ 'CBool', 'Cbr', 'CByte', 'CDate', 'CFloat', 'Choose', 'Chr', 'CInt', 'CLong', 'Comp', 'Conv', 'Cos',
+ 'Cosh', 'CShort', 'CSng', 'CStr',
+ 'DateAdd', 'DateDiff', 'Day', 'DConv', 'Deg', 'DFree', 'Dir',
+ 'Eof', 'Eval', 'Exist', 'Exp', 'Exp10', 'Exp2', 'Expm',
+ 'Fix', 'Format', 'Frac', 'Free',
+ 'Hex', 'Hour', 'Hyp',
+ 'Iif', 'InStr', 'Int', 'IsAscii', 'IsBlank', 'IsBoolean', 'IsByte', 'IsDate', 'IsDigit', 'IsDir',
+ 'IsFloat', 'IsHexa', 'IsInteger', 'IsLCase', 'IsLetter', 'IsLong', 'IsNull', 'IsNumber', 'IsObject',
+ 'IsPunct', 'IsShort', 'IsSingle', 'IsSpace', 'IsString', 'IsUCase', 'IsVariant',
+ 'LCase', 'Left', 'Len', 'Lof', 'Log', 'Log10', 'Log2', 'Logp', 'Lsl', 'Lsr', 'LTrim',
+ 'Mag', 'Max', 'Mid', 'Min', 'Minute', 'Month', 'Now', 'Quote',
+ 'Rad', 'RDir', 'Realloc', 'Replace', 'Right', 'RInStr', 'Rnd', 'Rol', 'Ror', 'Round', 'RTrim',
+ 'Scan', 'SConv', 'Second', 'Seek', 'Sgn', 'Shl', 'Shr', 'Sin', 'Sinh', 'Space', 'Split', 'Sqr',
+ 'Stat', 'Str', 'StrPtr', 'Subst',
+ 'Tan', 'Tanh', 'Temp$', 'Time', 'Timer', 'Tr', 'Trim', 'TypeOf',
+ 'UCase', 'Unquote', 'Val', 'VarPtr', 'Week', 'WeekDay', 'Year'
+ ),
+ //string functions
+ 3 => array(
+ 'Bin$', 'Chr$', 'Conv$', 'DConv$', 'Format$', 'Hex$', 'LCase$', 'Left$', 'LTrim$', 'Mid$', 'Quote$',
+ 'Replace$', 'Right$', 'SConv$', 'Space$', 'Str$', 'String$', 'Subst$', 'Tr$', 'Trim$', 'UCase$',
+ 'Unquote$'
+ ),
+ //datatypes
+ 4 => array(
+ 'Boolean', 'Byte', 'Short', 'Integer', 'Long', 'Single', 'Float', 'Date', 'String', 'Variant', 'Object',
+ 'Pointer', 'File'
+ ),
+ //operators
+ 5 => array(
+ 'AND', 'DIV', 'MOD', 'NOT', 'OR', 'XOR'
+ ),
+ //objects/classes
+ 6 => array(
+ 'Application', 'Array', 'Byte[]', 'Collection', 'Component', 'Enum', 'Observer', 'Param', 'Process',
+ 'Stream', 'System', 'User', 'Chart', 'Compress', 'Crypt', 'Blob', 'Connection', 'DB', 'Database',
+ 'DatabaseUser', 'Field', 'Index', 'Result', 'ResultField', 'Table', 'DataBrowser', 'DataCombo',
+ 'DataControl', 'DataSource', 'DataView', 'Desktop', 'DesktopFile', 'Balloon', 'ColorButton',
+ 'ColorChooser', 'DateChooser', 'DirChooser', 'DirView', 'Expander', 'FileChooser', 'FileView',
+ 'FontChooser', 'InputBox', 'ListContainer', 'SidePanel', 'Stock', 'TableView', 'ToolPanel', 'ValueBox',
+ 'Wizard', 'Dialog', 'ToolBar', 'WorkSpace', 'DnsClient', 'SerialPort', 'ServerSocket', 'Socket',
+ 'UdpSocket', 'FtpClient', 'HttpClient', 'SmtpClient', 'Regexp', 'Action', 'Button', 'CheckBox',
+ 'ColumnView', 'ComboBox', 'Draw', 'Container', 'Control', 'Cursor', 'DrawingArea', 'Embedder',
+ 'Font', 'Form', 'Frame', 'GridView', 'HBox', 'HPanel', 'HSplit', 'IconView', 'Image', 'Key', 'Label',
+ 'Line', 'ListBox', 'ListView', 'Menu', 'Message', 'Mouse', 'MovieBox', 'Panel', 'Picture', 'PictureBox',
+ 'ProgressBar', 'RadioButton', 'ScrollBar', 'ScrollView', 'Separator', 'Slider', 'SpinBox', 'TabStrip',
+ 'TextArea', 'TextBox', 'TextLabel', 'ToggleButton', 'TrayIcon', 'TreeView', 'VBox', 'VPanel', 'VSplit',
+ 'Watcher', 'Window', 'Dial', 'Editor', 'LCDNumber', 'Printer', 'TextEdit', 'WebBrowser', 'GLarea',
+ 'Report', 'ReportCloner', 'ReportContainer', 'ReportControl', 'ReportDrawing', 'ReportField', 'ReportHBox',
+ 'ReportImage', 'ReportLabel', 'ReportSection', 'ReportSpecialField', 'ReportTextLabel', 'ReportVBox',
+ 'CDRom', 'Channel', 'Music', 'Sound', 'Settings', 'VideoDevice', 'Vb', 'CGI', 'HTML', 'Request', 'Response',
+ 'Session', 'XmlDocument', 'XmlNode', 'XmlReader', 'XmlReaderNodeType', 'XmlWriter', 'RpcArray', 'RpcClient',
+ 'RpcFunction', 'RpcServer', 'RpcStruct', 'RpcType', 'XmlRpc', 'Xslt'
+ ),
+ //constants
+ 7 => array(
+ 'Pi'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '&', '&=', '&/', '*', '*=', '+', '+=', '-', '-=', '//', '/', '/=', '=', '==', '\\', '\\=',
+ '^', '^=', '[', ']', '{', '}', '<', '>', '<>', '<=', '>='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0600FF; font-weight: bold;', // Keywords
+ 2 => 'color: #8B1433;', // Functions
+ 3 => 'color: #8B1433;', // String Functions
+ 4 => 'color: #0600FF;', // Data Types
+ 5 => 'color: #1E90FF;', // Operators
+ 6 => 'color: #0600FF;', // Objects/Components
+ 7 => 'color: #0600FF;' // Constants
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #1A5B1A; font-style: italic;',
+ 'MULTI' => 'color: #1A5B1A; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #008080;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #612188;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7E4B05;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF0000;',
+ GESHI_NUMBER_INT_BASIC => 'color: #FF0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0000FF;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #6132B2;'
+ ),
+ 'REGEXPS' => array(
+ //3 => 'color: #8B1433;' //fakes '$' colour matched by REGEXP
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://gambasdoc.org/help/lang/{FNAMEL}',
+ 2 => 'http://gambasdoc.org/help/lang/{FNAMEL}',
+ 3 => 'http://www.google.com/search?hl=en&amp;q={FNAMEL}+site:http://gambasdoc.org/help/lang/&amp;btnI=I%27m%20Feeling%20Lucky',
+ 4 => 'http://gambasdoc.org/help/lang/type/{FNAMEL}',
+ 5 => 'http://gambasdoc.org/help/lang/{FNAMEL}',
+ 6 => 'http://www.google.com/search?hl=en&amp;q={FNAMEL}+site:http://gambasdoc.org/&amp;btnI=I%27m%20Feeling%20Lucky',
+ 7 => 'http://gambasdoc.org/help/lang/{FNAMEL}'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 =>'.'
+ ),
+ 'REGEXPS' => array(
+ //3 => "\\$(?!\\w)" //matches '$' at the end of Keyword
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 2 => array(
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_\|%\\-&;\$])"
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/gdb.php b/platform/www/vendor/geshi/geshi/src/geshi/gdb.php
new file mode 100644
index 0000000..250e277
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/gdb.php
@@ -0,0 +1,194 @@
+<?php
+/*************************************************************************************
+ * gdb.php
+ * --------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2009 Milian Wolff
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/06/24
+ *
+ * GDB language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/06/24 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2009/06/24)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'GDB',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 0 => array(
+ 'Application',
+ 'signal',
+ ),
+ 1 => array(
+ 'Segmentation fault',
+ '[KCrash Handler]',
+ ),
+ ),
+ 'NUMBERS' => false,
+ 'SYMBOLS' => array(
+ ),
+ 'CASE_SENSITIVE' => array(
+ 0 => true,
+ 1 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 0 => 'font-weight:bold;',
+ 1 => 'font-weight:bold; color: #ff0000;'
+ ),
+ 'COMMENTS' => array(
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'font-weight:bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #933;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #000066; font-weight:bold;',
+ 1 => 'color: #006600;',
+ 2 => 'color: #B07E00;',
+ 3 => 'color: #0057AE; text-style:italic;',
+ 4 => 'color: #0057AE; text-style:italic;',
+ 5 => 'color: #442886;',
+ 6 => 'color: #442886; font-weight:bold;',
+ 7 => 'color: #FF0000; font-weight:bold;',
+ 8 => 'color: #006E26;',
+ 9 => 'color: #555;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 0 => '',
+ 1 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //[Current Thread...], [KCrash Handler] etc.
+ 0 => array(
+ GESHI_SEARCH => '^\[.+\]',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ //stack number
+ 1 => array(
+ GESHI_SEARCH => '^#\d+',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ //Thread X (Thread...)
+ 2 => array(
+ GESHI_SEARCH => '^Thread \d.+$',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ //Files with linenumbers
+ 3 => array(
+ GESHI_SEARCH => '(at\s+)(.+)(:\d+\s*)$',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ //Libs without linenumbers
+ 4 => array(
+ GESHI_SEARCH => '(from\s+)(.+)(\s*)$',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ //Line numbers
+ 5 => array(
+ GESHI_SEARCH => '(:)(\d+)(\s*)$',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ //Location
+ 6 => array(
+ GESHI_SEARCH => '(\s+)(in\s+)?([^ 0-9][^ ]*)([ \n]+\()',
+ GESHI_REPLACE => '\\3',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1\\2',
+ GESHI_AFTER => '\\4'
+ ),
+ // interesting parts: abort, qFatal, assertions, null ptrs, ...
+ 7 => array(
+ GESHI_SEARCH => '\b((?:\*__GI_)?(?:__assert_fail|abort)|qFatal|0x0)\b([^\.]|$)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '\\2'
+ ),
+ // Namespace / Classes
+ 8 => array(
+ GESHI_SEARCH => '\b(\w+)(::)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'U',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '\\2'
+ ),
+ // make ptr adresses and <value optimized out> uninteresting
+ 9 => '\b(?:0x[a-f0-9]{2,}|value\s+optimized\s+out)\b'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'NUMBERS' => false
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/genero.php b/platform/www/vendor/geshi/geshi/src/geshi/genero.php
new file mode 100644
index 0000000..afdf9d9
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/genero.php
@@ -0,0 +1,461 @@
+<?php
+/*************************************************************************************
+ * genero.php
+ * ----------
+ * Author: Lars Gersmann (lars.gersmann@gmail.com)
+ * Copyright: (c) 2007 Lars Gersmann, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/07/01
+ *
+ * Genero (FOURJ's Genero 4GL) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2007/07/01 (1.0.0)
+ * - Initial release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'genero',
+ 'COMMENT_SINGLE' => array(1 => '--', 2 => '#'),
+ 'COMMENT_MULTI' => array('{' => '}'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ "ABSOLUTE",
+ "ACCEPT",
+ "ACTION",
+ "ADD",
+ "AFTER",
+ "ALL",
+ "ALTER",
+ "AND",
+ "ANY",
+ "APPEND",
+ "APPLICATION",
+ "AS",
+ "AT",
+ "ATTRIBUTE",
+ "ATTRIBUTES",
+ "AUDIT",
+ "AVG",
+ "BEFORE",
+ "BEGIN",
+ "BETWEEN",
+ "BORDER",
+ "BOTTOM",
+ "BREAKPOINT",
+ "BUFFER",
+ "BUFFERED",
+ "BY",
+ "CALL",
+ "CANCEL",
+ "CASE",
+ "CENTURY",
+ "CHANGE",
+ "CHECK",
+ "CLEAR",
+ "CLIPPED",
+ "CLOSE",
+ "CLUSTER",
+ "COLUMN",
+ "COLUMNS",
+ "COMMAND",
+ "COMMENT",
+ "COMMIT",
+ "COMMITTED",
+ "CONCURRENT ",
+ "CONNECT",
+ "CONNECTION",
+ "CONSTANT",
+ "CONSTRAINED",
+ "CONSTRAINT",
+ "CONSTRUCT",
+ "CONTINUE",
+ "CONTROL",
+ "COUNT",
+ "CREATE",
+ "CROSS",
+ "CURRENT",
+ "DATABASE",
+ "DBA",
+ "DEC",
+ "DECLARE",
+ "DEFAULT",
+ "DEFAULTS",
+ "DEFER",
+ "DEFINE",
+ "DELETE",
+ "DELIMITER",
+ "DESCRIBE",
+ "DESTINATION",
+ "DIM",
+ "DIALOG",
+ "DIMENSION",
+ "DIRTY",
+ "DISCONNECT",
+ "DISPLAY",
+ "DISTINCT",
+ "DORMANT",
+ "DOWN",
+ "DROP",
+ "DYNAMIC",
+ "ELSE",
+ "END",
+ "ERROR",
+ "ESCAPE",
+ "EVERY",
+ "EXCLUSIVE",
+ "EXECUTE",
+ "EXISTS",
+ "EXIT",
+ "EXPLAIN",
+ "EXTEND",
+ "EXTENT",
+ "EXTERNAL",
+ "FETCH",
+ "FGL_DRAWBOX",
+ "FIELD",
+ "FIELD_TOUCHED",
+ "FILE",
+ "FILL",
+ "FINISH",
+ "FIRST",
+ "FLOAT",
+ "FLUSH",
+ "FOR",
+ "FOREACH",
+ "FORM",
+ "FORMAT",
+ "FOUND",
+ "FRACTION",
+ "FREE",
+ "FROM",
+ "FULL",
+ "FUNCTION",
+ "GET_FLDBUF",
+ "GLOBALS",
+ "GO",
+ "GOTO",
+ "GRANT",
+ "GROUP",
+ "HAVING",
+ "HEADER",
+ "HELP",
+ "HIDE",
+ "HOLD",
+ "HOUR",
+ "IDLE",
+ "IF",
+ "IMAGE",
+ "IMMEDIATE",
+ "IN",
+ "INDEX",
+ "INFIELD",
+ "INITIALIZE",
+ "INNER",
+ "INPUT",
+ "INSERT",
+ "INTERRUPT",
+ "INTERVAL",
+ "INTO",
+ "INVISIBLE",
+ "IS",
+ "ISOLATION",
+ "JOIN",
+ "KEEP",
+ "KEY",
+ "LABEL",
+ "LAST",
+ "LEFT",
+ "LENGTH",
+ "LET",
+ "LIKE",
+ "LINE",
+ "LINENO",
+ "LINES",
+ "LOAD",
+ "LOCATE",
+ "LOCK",
+ "LOG",
+ "LSTR",
+ "MAIN",
+ "MARGIN",
+ "MATCHES",
+ "MAX",
+ "MAXCOUNT",
+ "MDY",
+ "MEMORY",
+ "MENU",
+ "MESSAGE",
+ "MIN",
+ "MINUTE",
+ "MOD",
+ "MODE",
+ "MODIFY",
+ "MONEY",
+ "NAME",
+ "NEED",
+ "NEXT",
+ "NO",
+ "NORMAL",
+ "NOT",
+ "NOTFOUND",
+ "NULL",
+ "NUMERIC",
+ "OF",
+ "ON",
+ "OPEN",
+ "OPTION",
+ "OPTIONS",
+ "OR",
+ "ORDER",
+ "OTHERWISE",
+ "OUTER",
+ "OUTPUT",
+ "PAGE",
+ "PAGENO",
+ "PAUSE",
+ "PERCENT",
+ "PICTURE",
+ "PIPE",
+ "PRECISION",
+ "PREPARE",
+ "PREVIOUS",
+ "PRINT",
+ "PRINTER",
+ "PRINTX",
+ "PRIOR",
+ "PRIVILEGES",
+ "PROCEDURE",
+ "PROGRAM",
+ "PROMPT",
+ "PUBLIC",
+ "PUT",
+ "QUIT",
+ "READ",
+ "REAL",
+ "RECORD",
+ "RECOVER",
+ "RED ",
+ "RELATIVE",
+ "RENAME",
+ "REOPTIMIZATION",
+ "REPEATABLE",
+ "REPORT",
+ "RESOURCE",
+ "RETURN",
+ "RETURNING",
+ "REVERSE",
+ "REVOKE",
+ "RIGHT",
+ "ROLLBACK",
+ "ROLLFORWARD",
+ "ROW",
+ "ROWS",
+ "RUN",
+ "SCHEMA",
+ "SCREEN",
+ "SCROLL",
+ "SECOND",
+ "SELECT",
+ "SERIAL",
+ "SET",
+ "SFMT",
+ "SHARE",
+ "SHIFT",
+ "SHOW",
+ "SIGNAL ",
+ "SIZE",
+ "SKIP",
+ "SLEEP",
+ "SOME",
+ "SPACE",
+ "SPACES",
+ "SQL",
+ "SQLERRMESSAGE",
+ "SQLERROR",
+ "SQLSTATE",
+ "STABILITY",
+ "START",
+ "STATISTICS",
+ "STEP",
+ "STOP",
+ "STYLE",
+ "SUM",
+ "SYNONYM",
+ "TABLE",
+ "TEMP",
+ "TERMINATE",
+ "TEXT",
+ "THEN",
+ "THROUGH",
+ "THRU",
+ "TO",
+ "TODAY",
+ "TOP",
+ "TRAILER",
+ "TRANSACTION ",
+ "UNBUFFERED",
+ "UNCONSTRAINED",
+ "UNDERLINE",
+ "UNION",
+ "UNIQUE",
+ "UNITS",
+ "UNLOAD",
+ "UNLOCK",
+ "UP",
+ "UPDATE",
+ "USE",
+ "USER",
+ "USING",
+ "VALIDATE",
+ "VALUE",
+ "VALUES",
+ "VARCHAR",
+ "VIEW",
+ "WAIT",
+ "WAITING",
+ "WARNING",
+ "WHEN",
+ "WHENEVER",
+ "WHERE",
+ "WHILE",
+ "WINDOW",
+ "WITH",
+ "WITHOUT",
+ "WORDWRAP",
+ "WORK",
+ "WRAP"
+ ),
+ 2 => array(
+ '&amp;IFDEF', '&amp;ENDIF'
+ ),
+ 3 => array(
+ "ARRAY",
+ "BYTE",
+ "CHAR",
+ "CHARACTER",
+ "CURSOR",
+ "DATE",
+ "DATETIME",
+ "DECIMAL",
+ "DOUBLE",
+ "FALSE",
+ "INT",
+ "INTEGER",
+ "SMALLFLOAT",
+ "SMALLINT",
+ "STRING",
+ "TIME",
+ "TRUE"
+ ),
+ 4 => array(
+ "BLACK",
+ "BLINK",
+ "BLUE",
+ "BOLD",
+ "ANSI",
+ "ASC",
+ "ASCENDING",
+ "ASCII",
+ "CYAN",
+ "DESC",
+ "DESCENDING",
+ "GREEN",
+ "MAGENTA",
+ "OFF",
+ "WHITE",
+ "YELLOW",
+ "YEAR",
+ "DAY",
+ "MONTH",
+ "WEEKDAY"
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '+', '-', '*', '?', '=', '/', '%', '>', '<', '^', '!', '|', ':',
+ '(', ')', '[', ']'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0600FF;',
+ 2 => 'color: #0000FF; font-weight: bold;',
+ 3 => 'color: #008000;',
+ 4 => 'color: #FF0000;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008080; font-style: italic;',
+ 2 => 'color: #008080;',
+ 'MULTI' => 'color: #008080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #008080; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #808080;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0000FF;',
+ 2 => 'color: #0000FF;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/genie.php b/platform/www/vendor/geshi/geshi/src/geshi/genie.php
new file mode 100644
index 0000000..05b3565
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/genie.php
@@ -0,0 +1,155 @@
+<?php
+/*************************************************************************************
+ * genie.php
+ * ----------
+ * Author: Nicolas Joseph (nicolas.joseph@valaide.org)
+ * Copyright: (c) 2009 Nicolas Joseph
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/04/29
+ *
+ * Genie language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Genie',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Using and Namespace directives (basic support)
+ //Please note that the alias syntax for using is not supported
+ 3 => '/(?:(?<=using[\\n\\s])|(?<=namespace[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*[a-zA-Z0-9_]+[\n\s]*(?=[;=])/i'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'HARDQUOTE' => array('@"', '"'),
+ 'HARDESCAPE' => array('""'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'and', 'as', 'abstract', 'break', 'case', 'cast', 'catch', 'const',
+ 'construct', 'continue', 'default', 'def', 'delete', 'div',
+ 'dynamic', 'do', 'downto', 'else', 'ensures', 'except', 'extern',
+ 'false', 'final', 'finally', 'for', 'foreach', 'get', 'if', 'in',
+ 'init', 'inline', 'internal', 'implements', 'lock', 'not', 'null',
+ 'of', 'or', 'otherwise', 'out', 'override', 'pass', 'raise',
+ 'raises', 'readonly', 'ref', 'requires', 'self', 'set', 'static',
+ 'super', 'switch', 'to', 'true', 'try', 'unless', 'uses', 'var', 'virtual',
+ 'volatile', 'void', 'when', 'while'
+ ),
+// 2 => array(
+// ),
+ 3 => array(
+ 'is', 'isa', 'new', 'owned', 'sizeof', 'typeof', 'unchecked',
+ 'unowned', 'weak'
+ ),
+ 4 => array(
+ 'bool', 'byte', 'class', 'char', 'date', 'datetime', 'decimal', 'delegate',
+ 'double', 'enum', 'event', 'exception', 'float', 'int', 'interface',
+ 'long', 'object', 'prop', 'sbyte', 'short', 'single', 'string',
+ 'struct', 'ulong', 'ushort'
+ ),
+// 5 => array(
+// ),
+ ),
+ 'SYMBOLS' => array(
+ '+', '-', '*', '?', '=', '/', '%', '&', '>', '<', '^', '!', ':', ';',
+ '(', ')', '{', '}', '[', ']', '|'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+// 2 => false,
+ 3 => false,
+ 4 => false,
+// 5 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0600FF;',
+// 2 => 'color: #FF8000; font-weight: bold;',
+ 3 => 'color: #008000;',
+ 4 => 'color: #FF0000;',
+// 5 => 'color: #000000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008080; font-style: italic;',
+// 2 => 'color: #008080;',
+ 3 => 'color: #008080;',
+ 'MULTI' => 'color: #008080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #008080; font-weight: bold;',
+ 'HARD' => 'color: #008080; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #666666;',
+ 'HARD' => 'color: #666666;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0000FF;',
+ 2 => 'color: #0000FF;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+// 2 => '',
+ 3 => '',
+ 4 => '',
+// 5 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#>|^])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%\\-])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/gettext.php b/platform/www/vendor/geshi/geshi/src/geshi/gettext.php
new file mode 100644
index 0000000..4161cb8
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/gettext.php
@@ -0,0 +1,95 @@
+<?php
+/*************************************************************************************
+ * gettext.php
+ * --------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/05/25
+ *
+ * GNU Gettext .po/.pot language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/08/02 (1.0.8)
+ * - New comments: flags and previous-fields
+ * - New keywords: msgctxt, msgid_plural
+ * - Msgstr array indices
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'GNU Gettext',
+ 'COMMENT_SINGLE' => array('#:', '#.', '#,', '#|', '#'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array('msgctxt', 'msgid_plural', 'msgid', 'msgstr'),
+ ),
+ 'SYMBOLS' => array(),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #000099;',
+ 1 => 'color: #000099;',
+ 2 => 'color: #000099;',
+ 3 => 'color: #006666;',
+ 4 => 'color: #666666; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'REGEXPS' => array(),
+ 'SYMBOLS' => array(),
+ 'NUMBERS' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'METHODS' => array(),
+ 'SCRIPT' => array(),
+ 'BRACKETS' => array(
+ 0 => 'color: #000099;'
+ ),
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/glsl.php b/platform/www/vendor/geshi/geshi/src/geshi/glsl.php
new file mode 100644
index 0000000..eab78e9
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/glsl.php
@@ -0,0 +1,203 @@
+<?php
+/*************************************************************************************
+ * glsl.php
+ * -----
+ * Author: Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2008 Benny Baumann (BenBE@omorphia.de)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/03/20
+ *
+ * glSlang language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/03/20 (1.0.7.21)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'glSlang',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Multiline-continued single-line comments
+ 1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Multiline-continued preprocessor define
+ 2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'if', 'else', 'for', 'while', 'do', 'break', 'continue', 'asm',
+ 'switch', 'case', 'default', 'return', 'discard',
+ 'namespace', 'using', 'sizeof', 'cast'
+ ),
+ 2 => array(
+ 'const', 'uniform', 'attribute', 'centroid', 'varying', 'invariant',
+ 'in', 'out', 'inout', 'input', 'output', 'typedef', 'volatile',
+ 'public', 'static', 'extern', 'external', 'packed',
+ 'inline', 'noinline', 'noperspective', 'flat'
+ ),
+ 3 => array(
+ 'void', 'bool', 'int', 'long', 'short', 'float', 'half', 'fixed',
+ 'unsigned', 'lowp', 'mediump', 'highp', 'precision',
+ 'vec2', 'vec3', 'vec4', 'bvec2', 'bvec3', 'bvec4',
+ 'dvec2', 'dvec3', 'dvec4', 'fvec2', 'fvec3', 'fvec4',
+ 'hvec2', 'hvec3', 'hvec4', 'ivec2', 'ivec3', 'ivec4',
+ 'mat2', 'mat3', 'mat4', 'mat2x2', 'mat3x2', 'mat4x2',
+ 'mat2x3', 'mat3x3', 'mat4x3', 'mat2x4', 'mat3x4', 'mat4x4',
+ 'sampler1D', 'sampler2D', 'sampler3D', 'samplerCube',
+ 'sampler1DShadow', 'sampler2DShadow',
+ 'struct', 'class', 'union', 'enum', 'interface', 'template'
+ ),
+ 4 => array(
+ 'this', 'false', 'true'
+ ),
+ 5 => array(
+ 'radians', 'degrees', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan',
+ 'pow', 'exp2', 'log2', 'sqrt', 'inversesqrt', 'abs', 'sign', 'ceil',
+ 'floor', 'fract', 'mod', 'min', 'max', 'clamp', 'mix', 'step',
+ 'smoothstep', 'length', 'distance', 'dot', 'cross', 'normalize',
+ 'ftransform', 'faceforward', 'reflect', 'matrixCompMult', 'equal',
+ 'lessThan', 'lessThanEqual', 'greaterThan', 'greaterThanEqual',
+ 'notEqual', 'any', 'all', 'not', 'texture1D', 'texture1DProj',
+ 'texture1DLod', 'texture1DProjLod', 'texture2D', 'texture2DProj',
+ 'texture2DLod', 'texture2DProjLod', 'texture3D', 'texture3DProj',
+ 'texture3DLod', 'texture3DProjLod', 'textureCube', 'textureCubeLod',
+ 'shadow1D', 'shadow1DProj', 'shadow1DLod', 'shadow1DProjLod',
+ 'shadow2D', 'shadow2DProj', 'shadow2DLod', 'shadow2DProjLod',
+ 'noise1', 'noise2', 'noise3', 'noise4'
+ ),
+ 6 => array(
+ 'gl_Position', 'gl_PointSize', 'gl_ClipVertex', 'gl_FragColor',
+ 'gl_FragData', 'gl_FragDepth', 'gl_FragCoord', 'gl_FrontFacing',
+ 'gl_Color', 'gl_SecondaryColor', 'gl_Normal', 'gl_Vertex',
+ 'gl_MultiTexCoord0', 'gl_MultiTexCoord1', 'gl_MultiTexCoord2',
+ 'gl_MultiTexCoord3', 'gl_MultiTexCoord4', 'gl_MultiTexCoord5',
+ 'gl_MultiTexCoord6', 'gl_MultiTexCoord7', 'gl_FogCoord',
+ 'gl_MaxLights', 'gl_MaxClipPlanes', 'gl_MaxTextureUnits',
+ 'gl_MaxTextureCoords', 'gl_MaxVertexAttribs', 'gl_MaxVaryingFloats',
+ 'gl_MaxVertexUniformComponents', 'gl_MaxVertexTextureImageUnits',
+ 'gl_MaxCombinedTextureImageUnits', 'gl_MaxTextureImageUnits',
+ 'gl_MaxFragmentUniformComponents', 'gl_MaxDrawBuffers', 'gl_Point',
+ 'gl_ModelViewMatrix', 'gl_ProjectionMatrix', 'gl_FrontMaterial',
+ 'gl_ModelViewProjectionMatrix', 'gl_TextureMatrix', 'gl_ClipPlane',
+ 'gl_NormalMatrix', 'gl_ModelViewMatrixInverse', 'gl_BackMaterial',
+ 'gl_ProjectionMatrixInverse', 'gl_ModelViewProjectionMatrixInverse',
+ 'gl_TextureMatrixInverse', 'gl_ModelViewMatrixTranspose', 'gl_Fog',
+ 'gl_ProjectionMatrixTranspose', 'gl_NormalScale', 'gl_DepthRange',
+ 'gl_odelViewProjectionMatrixTranspose', 'gl_TextureMatrixTranspose',
+ 'gl_ModelViewMatrixInverseTranspose', 'gl_LightSource',
+ 'gl_ProjectionMatrixInverseTranspose', 'gl_LightModel',
+ 'gl_ModelViewProjectionMatrixInverseTranspose', 'gl_TexCoord',
+ 'gl_TextureMatrixInverseTranspose', 'gl_TextureEnvColor',
+ 'gl_FrontLightModelProduct', 'gl_BackLightModelProduct',
+ 'gl_FrontLightProduct', 'gl_BackLightProduct', 'gl_ObjectPlaneS',
+ 'gl_ObjectPlaneT', 'gl_ObjectPlaneR', 'gl_ObjectPlaneQ',
+ 'gl_EyePlaneS', 'gl_EyePlaneT', 'gl_EyePlaneR', 'gl_EyePlaneQ',
+ 'gl_FrontColor', 'gl_BackColor', 'gl_FrontSecondaryColor',
+ 'gl_BackSecondaryColor', 'gl_FogFragCoord', 'gl_PointCoord'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^',
+ '&', '?', ':', '.', '|', ';', ',', '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #333399; font-weight: bold;',
+ 3 => 'color: #000066; font-weight: bold;',
+ 4 => 'color: #333399; font-weight: bold;',
+ 5 => 'color: #993333; font-weight: bold;',
+ 6 => 'color: #551111;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #009900;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'OOLANG' => array(
+ 'MATCH_BEFORE' => '',
+ 'MATCH_AFTER' => '[a-zA-Z_][a-zA-Z0-9_]*',
+ 'MATCH_SPACES' => '[\s]*'
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/gml.php b/platform/www/vendor/geshi/geshi/src/geshi/gml.php
new file mode 100644
index 0000000..30b900e
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/gml.php
@@ -0,0 +1,367 @@
+<?php
+/*************************************************************************************
+ * gml.php
+ * -------
+ * Author: José Jorge Enríquez <jenriquez@users.sourceforge.net>, Timon Knigge <timonknigge@live.nl>
+ * Copyright: (c) 2005 José Jorge Enríquez Rodríguez (http://www.zonamakers.com), (c) 2013 Timon Knigge (http://www.bluemoonproductions.nl)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/06/21
+ *
+ * GML language file for GeSHi.
+ *
+ * GML (Game Maker Language) is a script language that is built-in into Game Maker,
+ * a game creation program, more info about Game Maker can be found at
+ * http://www.gamemaker.nl/
+ * All GML keywords were extracted from the Game Maker HTML Help file using a PHP
+ * script (one section at a time). I love PHP for saving me that bunch of work :P!.
+ * I think all GML functions have been indexed here, but I'm not sure about it, so
+ * please let me know of any issue you may find.
+ *
+ * CHANGES
+ * -------
+ * 2005/11/11
+ * - Changed 'CASE_KEYWORDS' fom 'GESHI_CAPS_LOWER' to 'GESHI_CAPS_NO_CHANGE',
+ * so that MCI_command appears correctly (the only GML function using capitals).
+ * - Changed 'CASE_SENSITIVE' options, 'GESHI_COMMENTS' from true to false and all
+ * of the others from false to true.
+ * - Deleted repeated entries.
+ * - div and mod are language keywords, moved (from symbols) to the appropiate section (1).
+ * - Moved self, other, all, noone and global identifiers to language keywords section 1.
+ * - Edited this file lines to a maximum width of 100 characters (as stated in
+ * the GeSHi docs). Well, not strictly to 100 but around it.
+ * - Corrected some minor issues (the vk_f1...vk_f12 keys and similar).
+ * - Deleted the KEYWORDS=>5 and KEYWORDS=>6 sections (actually, they were empty).
+ * I was planning of using those for the GML functions available only in the
+ * registered version of the program, but not anymore.
+ *
+ * 2005/06/26 (1.0.3)
+ * - First Release.
+ *
+ * TODO (updated 2005/11/11)
+ * -------------------------
+ * - Test it for a while and make the appropiate corrections.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'GML',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'"),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ // Variables
+ 1 => array(
+ 'argument','argument0','argument1','argument10','argument11','argument12','argument13','argument14','argument15','argument2','argument3','argument4','argument5','argument6','argument7',
+ 'argument8','argument9','argument_count','argument_relative','async_load','background_alpha','background_blend','background_color','background_foreground','background_height','background_hspeed',
+ 'background_htiled','background_index','background_showcolor','background_visible','background_vspeed','background_vtiled','background_width','background_x','background_xscale','background_y',
+ 'background_yscale','browser_height','browser_width','caption_health','caption_lives','caption_score','current_day','current_hour','current_minute','current_month','current_second','current_time',
+ 'current_weekday','current_year','cursor_sprite','debug_mode','delta_time','display_aa','error_last','error_occurred','event_action','event_number','event_object','event_type','fps','fps_real',
+ 'game_id','gamemaker_pro','gamemaker_registered','gamemaker_version','health','instance_count','instance_id','keyboard_key','keyboard_lastchar','keyboard_lastkey','keyboard_string','lives',
+ 'mouse_button','mouse_lastbutton','mouse_x','mouse_y','os_browser','os_device','os_type','os_version','program_directory','room','room_caption','room_first','room_height','room_last',
+ 'room_persistent','room_speed','room_width','score','secure_mode','show_health','show_lives','show_score','temp_directory','transition_color','transition_kind','transition_steps','view_angle',
+ 'view_current','view_enabled','view_hborder','view_hport','view_hspeed','view_hview','view_object','view_surface_id','view_vborder','view_visible','view_vspeed','view_wport','view_wview','view_xport',
+ 'view_xview','view_yport','view_yview','webgl_enabled','working_directory','alarm','bbox_bottom','bbox_left','bbox_right','bbox_top','depth','direction','friction','gravity','gravity_direction',
+ 'hspeed','id','image_alpha','image_angle','image_blend','image_index','image_number','image_single','image_speed','image_xscale','image_yscale','mask_index','object_index','path_endaction','path_index',
+ 'path_orientation','path_position','path_positionprevious','path_scale','path_speed','persistent','phy_active','phy_angular_damping','phy_angular_velocity','phy_bullet','phy_col_normal_x',
+ 'phy_col_normal_y','phy_collision_points','phy_collision_x','phy_collision_y','phy_com_x','phy_com_y','phy_dynamic','phy_fixed_rotation','phy_inertia','phy_kinematic','phy_linear_damping',
+ 'phy_linear_velocity_x','phy_linear_velocity_y','phy_mass','phy_position_x','phy_position_xprevious','phy_position_y','phy_position_yprevious','phy_rotation','phy_sleeping','phy_speed','phy_speed_x',
+ 'phy_speed_y','solid','speed','sprite_height','sprite_index','sprite_width','sprite_xoffset','sprite_yoffset','timeline_index','timeline_loop','timeline_position','timeline_running','timeline_speed',
+ 'visible','vspeed','x','xprevious','xstart','y','yprevious','ystart'
+ ),
+
+ // Functions
+ 2 => array(
+ 'YoYo_AchievementsAvailable','YoYo_AddVirtualKey','YoYo_CheckSecurity','YoYo_DeleteVirtualKey','YoYo_DisableAds','YoYo_EnableAds','YoYo_EnableAlphaBlend','YoYo_GetCPUDetails','YoYo_GetConfig',
+ 'YoYo_GetDevice','YoYo_GetDomain','YoYo_GetPictureSprite','YoYo_GetPlatform','YoYo_GetSessionKey','YoYo_GetTiltX','YoYo_GetTiltY','YoYo_GetTiltZ','YoYo_GetTimer','YoYo_HideVirtualKey','YoYo_IsKeypadOpen',
+ 'YoYo_LeaveRating','YoYo_LoginAchievements','YoYo_LogoutAchievements','YoYo_MouseCheckButton','YoYo_MouseCheckButtonPressed','YoYo_MouseCheckButtonReleased','YoYo_MouseX','YoYo_MouseXRaw','YoYo_MouseY',
+ 'YoYo_MouseYRaw','YoYo_OSPauseEvent','YoYo_OpenURL','YoYo_OpenURL_ext','YoYo_OpenURL_full','YoYo_PostAchievement','YoYo_PostScore','YoYo_SelectPicture','YoYo_ShowVirtualKey','abs','achievement_available',
+ 'achievement_event','achievement_get_challenges','achievement_get_info','achievement_get_pic','achievement_increment','achievement_load_friends','achievement_load_leaderboard','achievement_load_progress',
+ 'achievement_login','achievement_login_status','achievement_logout','achievement_post','achievement_post_score','achievement_reset','achievement_send_challenge','achievement_show',
+ 'achievement_show_achievements','achievement_show_challenge_notifications','achievement_show_leaderboards','action_another_room','action_bounce','action_change_object','action_color','action_create_object',
+ 'action_create_object_motion','action_create_object_random','action_current_room','action_draw_arrow','action_draw_background','action_draw_ellipse','action_draw_ellipse_gradient','action_draw_gradient_hor',
+ 'action_draw_gradient_vert','action_draw_health','action_draw_life','action_draw_life_images','action_draw_line','action_draw_rectangle','action_draw_score','action_draw_sprite','action_draw_text',
+ 'action_draw_text_transformed','action_draw_variable','action_effect','action_end_game','action_end_sound','action_execute_script','action_font','action_fullscreen','action_highscore_clear','action_if',
+ 'action_if_aligned','action_if_collision','action_if_dice','action_if_empty','action_if_health','action_if_life','action_if_mouse','action_if_next_room','action_if_number','action_if_object',
+ 'action_if_previous_room','action_if_question','action_if_score','action_if_sound','action_if_variable','action_inherited','action_kill_object','action_kill_position','action_linear_step','action_load_game',
+ 'action_message','action_move','action_move_contact','action_move_point','action_move_random','action_move_start','action_move_to','action_next_room','action_partemit_burst','action_partemit_create',
+ 'action_partemit_destroy','action_partemit_stream','action_partsyst_clear','action_partsyst_create','action_partsyst_destroy','action_parttype_color','action_parttype_create','action_parttype_gravity',
+ 'action_parttype_life','action_parttype_secondary','action_parttype_speed','action_path','action_path_end','action_path_position','action_path_speed','action_potential_step','action_previous_room',
+ 'action_replace_background','action_replace_sound','action_replace_sprite','action_restart_game','action_reverse_xdir','action_reverse_ydir','action_save_game','action_set_alarm','action_set_cursor',
+ 'action_set_friction','action_set_gravity','action_set_health','action_set_hspeed','action_set_life','action_set_motion','action_set_score','action_set_timeline_position','action_set_timeline_speed',
+ 'action_set_vspeed','action_snap','action_snapshot','action_sound','action_sprite_color','action_sprite_set','action_sprite_transform','action_timeline_pause','action_timeline_set','action_timeline_start',
+ 'action_timeline_stop','action_webpage','action_wrap','ads_disable','ads_enable','ads_engagement_active','ads_engagement_available','ads_engagement_launch','ads_event','ads_event_preload',
+ 'ads_get_display_height','ads_get_display_width','ads_interstitial_available','ads_interstitial_display','ads_move','ads_set_reward_callback','ads_setup','analytics_event','analytics_event_ext','ansi_char',
+ 'arccos','arcsin','arctan','arctan2','array_height_2d','array_length_1d','array_length_2d','asset_get_index','asset_get_type','audio_channel_num','audio_emitter_create','audio_emitter_exists',
+ 'audio_emitter_falloff','audio_emitter_free','audio_emitter_gain','audio_emitter_pitch','audio_emitter_position','audio_emitter_velocity','audio_exists','audio_falloff_set_model','audio_get_type',
+ 'audio_is_paused','audio_is_playing','audio_listener_orientation','audio_listener_position','audio_listener_velocity','audio_master_gain','audio_music_gain','audio_music_is_playing','audio_pause_all',
+ 'audio_pause_music','audio_pause_sound','audio_play_music','audio_play_sound','audio_play_sound_at','audio_play_sound_on','audio_resume_all','audio_resume_music','audio_resume_sound','audio_sound_gain',
+ 'audio_sound_length','audio_sound_pitch','audio_stop_all','audio_stop_music','audio_stop_sound','audio_system','background_add','background_assign','background_create_color','background_create_from_surface',
+ 'background_create_gradient','background_delete','background_duplicate','background_exists','background_get_height','background_get_name','background_get_texture','background_get_uvs','background_get_width',
+ 'background_replace','background_save','background_set_alpha_from_background','base64_decode','base64_encode','buffer_base64_decode','buffer_base64_decode_ext','buffer_base64_encode','buffer_copy',
+ 'buffer_create','buffer_delete','buffer_fill','buffer_get_size','buffer_get_surface','buffer_load','buffer_load_ext','buffer_md5','buffer_peek','buffer_poke','buffer_read','buffer_resize','buffer_save',
+ 'buffer_save_ext','buffer_seek','buffer_set_surface','buffer_sha1','buffer_sizeof','buffer_tell','buffer_write','ceil','choose','chr','clamp','clickable_add','clickable_add_ext','clickable_change',
+ 'clickable_change_ext','clickable_delete','clickable_exists','clipboard_get_text','clipboard_has_text','clipboard_set_text','cloud_file_save','cloud_string_save','cloud_synchronise','code_is_compiled',
+ 'collision_circle','collision_ellipse','collision_line','collision_point','collision_rectangle','color_get_blue','color_get_green','color_get_hue','color_get_red','color_get_saturation','color_get_value',
+ 'cos','d3d_draw_block','d3d_draw_cone','d3d_draw_cylinder','d3d_draw_ellipsoid','d3d_draw_floor','d3d_draw_wall','d3d_end','d3d_light_define_ambient','d3d_light_define_direction','d3d_light_define_point',
+ 'd3d_light_enable','d3d_model_block','d3d_model_clear','d3d_model_cone','d3d_model_create','d3d_model_cylinder','d3d_model_destroy','d3d_model_draw','d3d_model_ellipsoid','d3d_model_floor','d3d_model_load',
+ 'd3d_model_primitive_begin','d3d_model_primitive_end','d3d_model_save','d3d_model_vertex','d3d_model_vertex_color','d3d_model_vertex_normal','d3d_model_vertex_normal_color','d3d_model_vertex_normal_texture',
+ 'd3d_model_vertex_normal_texture_color','d3d_model_vertex_texture','d3d_model_vertex_texture_color','d3d_model_wall','d3d_primitive_begin','d3d_primitive_begin_texture','d3d_primitive_end','d3d_set_culling',
+ 'd3d_set_depth','d3d_set_fog','d3d_set_hidden','d3d_set_lighting','d3d_set_perspective','d3d_set_projection','d3d_set_projection_ext','d3d_set_projection_ortho','d3d_set_projection_perspective',
+ 'd3d_set_shading','d3d_set_zwriteenable','d3d_start','d3d_transform_add_rotation_axis','d3d_transform_add_rotation_x','d3d_transform_add_rotation_y','d3d_transform_add_rotation_z','d3d_transform_add_scaling',
+ 'd3d_transform_add_translation','d3d_transform_set_identity','d3d_transform_set_rotation_axis','d3d_transform_set_rotation_x','d3d_transform_set_rotation_y','d3d_transform_set_rotation_z',
+ 'd3d_transform_set_scaling','d3d_transform_set_translation','d3d_transform_stack_clear','d3d_transform_stack_discard','d3d_transform_stack_empty','d3d_transform_stack_pop','d3d_transform_stack_push',
+ 'd3d_transform_stack_top','d3d_transform_vertex','d3d_vertex','d3d_vertex_color','d3d_vertex_normal','d3d_vertex_normal_color','d3d_vertex_normal_texture','d3d_vertex_normal_texture_color','d3d_vertex_texture',
+ 'd3d_vertex_texture_color','date_compare_date','date_compare_datetime','date_compare_time','date_create_datetime','date_current_datetime','date_date_of','date_date_string','date_datetime_string','date_day_span',
+ 'date_days_in_month','date_days_in_year','date_get_day','date_get_day_of_year','date_get_hour','date_get_hour_of_year','date_get_minute','date_get_minute_of_year','date_get_month','date_get_second',
+ 'date_get_second_of_year','date_get_week','date_get_weekday','date_get_year','date_hour_span','date_inc_day','date_inc_hour','date_inc_minute','date_inc_month','date_inc_second','date_inc_week','date_inc_year',
+ 'date_is_today','date_leap_year','date_minute_span','date_month_span','date_second_span','date_time_of','date_time_string','date_valid_datetime','date_week_span','date_year_span','degtorad','device_get_tilt_x',
+ 'device_get_tilt_y','device_get_tilt_z','device_ios_get_image','device_ios_get_imagename','device_is_keypad_open','device_mouse_check_button','device_mouse_check_button_pressed',
+ 'device_mouse_check_button_released','device_mouse_dbclick_enable','device_mouse_raw_x','device_mouse_raw_y','device_mouse_x','device_mouse_y','directory_create','directory_exists','display_get_dpi_x',
+ 'display_get_dpi_y','display_get_gui_height','display_get_gui_width','display_get_height','display_get_orientation','display_get_width','display_mouse_get_x','display_mouse_get_y','display_mouse_set',
+ 'display_reset','display_set_gui_size','distance_to_object','distance_to_point','dot_product','dot_product_3d','dot_product_3d_normalised','dot_product_normalised','draw_arrow','draw_background',
+ 'draw_background_ext','draw_background_general','draw_background_part','draw_background_part_ext','draw_background_stretched','draw_background_stretched_ext','draw_background_tiled','draw_background_tiled_ext',
+ 'draw_button','draw_circle','draw_circle_color','draw_clear','draw_clear_alpha','draw_ellipse','draw_ellipse_color','draw_enable_alphablend','draw_enable_drawevent','draw_get_alpha','draw_get_alpha_test',
+ 'draw_get_alpha_test_ref_value','draw_get_color','draw_getpixel','draw_getpixel_ext','draw_healthbar','draw_highscore','draw_line','draw_line_color','draw_line_width','draw_line_width_color','draw_path',
+ 'draw_point','draw_point_color','draw_primitive_begin','draw_primitive_begin_texture','draw_primitive_end','draw_rectangle','draw_rectangle_color','draw_roundrect','draw_roundrect_color','draw_self',
+ 'draw_set_alpha','draw_set_alpha_test','draw_set_alpha_test_ref_value','draw_set_blend_mode','draw_set_blend_mode_ext','draw_set_circle_precision','draw_set_color','draw_set_color_write_enable',
+ 'draw_set_font','draw_set_halign','draw_set_valign','draw_sprite','draw_sprite_ext','draw_sprite_general','draw_sprite_part','draw_sprite_part_ext','draw_sprite_pos','draw_sprite_stretched',
+ 'draw_sprite_stretched_ext','draw_sprite_tiled','draw_sprite_tiled_ext','draw_surface','draw_surface_ext','draw_surface_general','draw_surface_part','draw_surface_part_ext','draw_surface_stretched',
+ 'draw_surface_stretched_ext','draw_surface_tiled','draw_surface_tiled_ext','draw_text','draw_text_color','draw_text_ext','draw_text_ext_color','draw_text_ext_transformed','draw_text_ext_transformed_color',
+ 'draw_text_transformed','draw_text_transformed_color','draw_texture_flush','draw_triangle','draw_triangle_color','draw_vertex','draw_vertex_color','draw_vertex_texture','draw_vertex_texture_color',
+ 'ds_exists','ds_grid_add','ds_grid_add_disk','ds_grid_add_grid_region','ds_grid_add_region','ds_grid_clear','ds_grid_copy','ds_grid_create','ds_grid_destroy','ds_grid_get','ds_grid_get_disk_max',
+ 'ds_grid_get_disk_mean','ds_grid_get_disk_min','ds_grid_get_disk_sum','ds_grid_get_max','ds_grid_get_mean','ds_grid_get_min','ds_grid_get_sum','ds_grid_height','ds_grid_multiply','ds_grid_multiply_disk',
+ 'ds_grid_multiply_grid_region','ds_grid_multiply_region','ds_grid_read','ds_grid_resize','ds_grid_set','ds_grid_set_disk','ds_grid_set_grid_region','ds_grid_set_region','ds_grid_shuffle','ds_grid_sort',
+ 'ds_grid_value_disk_exists','ds_grid_value_disk_x','ds_grid_value_disk_y','ds_grid_value_exists','ds_grid_value_x','ds_grid_value_y','ds_grid_width','ds_grid_write','ds_list_add','ds_list_clear',
+ 'ds_list_copy','ds_list_create','ds_list_delete','ds_list_destroy','ds_list_empty','ds_list_find_index','ds_list_find_value','ds_list_insert','ds_list_mark_as_list','ds_list_mark_as_map','ds_list_read',
+ 'ds_list_replace','ds_list_shuffle','ds_list_size','ds_list_sort','ds_list_write','ds_map_add','ds_map_add_list','ds_map_add_map','ds_map_clear','ds_map_copy','ds_map_create','ds_map_delete',
+ 'ds_map_destroy','ds_map_empty','ds_map_exists','ds_map_find_first','ds_map_find_last','ds_map_find_next','ds_map_find_previous','ds_map_find_value','ds_map_read','ds_map_replace','ds_map_replace_list',
+ 'ds_map_replace_map','ds_map_size','ds_map_write','ds_priority_add','ds_priority_change_priority','ds_priority_clear','ds_priority_copy','ds_priority_create','ds_priority_delete_max','ds_priority_delete_min',
+ 'ds_priority_delete_value','ds_priority_destroy','ds_priority_empty','ds_priority_find_max','ds_priority_find_min','ds_priority_find_priority','ds_priority_read','ds_priority_size','ds_priority_write',
+ 'ds_queue_clear','ds_queue_copy','ds_queue_create','ds_queue_dequeue','ds_queue_destroy','ds_queue_empty','ds_queue_enqueue','ds_queue_head','ds_queue_read','ds_queue_size','ds_queue_tail','ds_queue_write',
+ 'ds_set_precision','ds_stack_clear','ds_stack_copy','ds_stack_create','ds_stack_destroy','ds_stack_empty','ds_stack_pop','ds_stack_push','ds_stack_read','ds_stack_size','ds_stack_top','ds_stack_write',
+ 'effect_clear','effect_create_above','effect_create_below','environment_get_variable','event_inherited','event_perform','event_perform_object','event_user','exp','external_call','external_define','external_free',
+ 'facebook_accesstoken','facebook_dialog','facebook_graph_request','facebook_init','facebook_launch_offerwall','facebook_login','facebook_logout','facebook_post_message','facebook_send_invite','facebook_status',
+ 'facebook_user_id','file_attributes','file_bin_close','file_bin_open','file_bin_position','file_bin_read_byte','file_bin_rewrite','file_bin_seek','file_bin_size','file_bin_write_byte','file_copy','file_delete',
+ 'file_exists','file_find_close','file_find_first','file_find_next','file_rename','file_text_close','file_text_eof','file_text_eoln','file_text_open_append','file_text_open_from_string','file_text_open_read',
+ 'file_text_open_write','file_text_read_real','file_text_read_string','file_text_readln','file_text_write_real','file_text_write_string','file_text_writeln','filename_change_ext','filename_dir','filename_drive',
+ 'filename_ext','filename_name','filename_path','floor','font_add','font_add_sprite','font_add_sprite_ext','font_delete','font_exists','font_get_bold','font_get_first','font_get_fontname','font_get_italic',
+ 'font_get_last','font_get_name','font_get_size','font_get_texture','font_get_uvs','font_replace','font_replace_sprite','font_replace_sprite_ext','font_set_cache_size','frac','game_end','game_load',
+ 'game_load_buffer','game_restart','game_save','game_save_buffer','gamepad_axis_count','gamepad_axis_value','gamepad_button_check','gamepad_button_check_pressed','gamepad_button_check_released',
+ 'gamepad_button_count','gamepad_button_value','gamepad_get_axis_deadzone','gamepad_get_button_threshold','gamepad_get_description','gamepad_get_device_count','gamepad_is_connected','gamepad_is_supported',
+ 'gamepad_set_axis_deadzone','gamepad_set_button_threshold','gamepad_set_vibration','get_integer','get_integer_async','get_login_async','get_open_filename','get_open_filename_ext','get_save_filename',
+ 'get_save_filename_ext','get_string','get_string_async','get_timer','highscore_add','highscore_clear','highscore_name','highscore_value','http_get','http_get_file','http_post_string','iap_acquire',
+ 'iap_activate','iap_consume','iap_event_queue','iap_files_purchased','iap_is_downloaded','iap_is_purchased','iap_product_details','iap_product_files','iap_product_status','iap_restore_all','iap_status',
+ 'iap_store_status','immersion_play_effect','immersion_stop','ini_close','ini_key_delete','ini_key_exists','ini_open','ini_open_from_string','ini_read_real','ini_read_string','ini_section_delete',
+ 'ini_section_exists','ini_write_real','ini_write_string','instance_activate_all','instance_activate_object','instance_activate_region','instance_change','instance_copy','instance_create',
+ 'instance_deactivate_all','instance_deactivate_object','instance_deactivate_region','instance_destroy','instance_exists','instance_find','instance_furthest','instance_nearest','instance_number',
+ 'instance_place','instance_position','io_clear','irandom','irandom_range','is_array','is_real','is_string','joystick_axes','joystick_buttons','joystick_check_button','joystick_direction','joystick_exists',
+ 'joystick_has_pov','joystick_name','joystick_pov','joystick_rpos','joystick_upos','joystick_vpos','joystick_xpos','joystick_ypos','joystick_zpos','json_decode','json_encode','keyboard_check',
+ 'keyboard_check_direct','keyboard_check_pressed','keyboard_check_released','keyboard_clear','keyboard_get_map','keyboard_get_numlock','keyboard_key_press','keyboard_key_release','keyboard_set_map',
+ 'keyboard_set_numlock','keyboard_unset_map','lengthdir_x','lengthdir_y','lerp','ln','log10','log2','logn','make_color_hsv','make_color_rgb','math_set_epsilon','matrix_build','matrix_get','matrix_multiply',
+ 'matrix_set','max','md5_file','md5_string_unicode','md5_string_utf8','mean','median','merge_color','message_caption','min','motion_add','motion_set','mouse_check_button','mouse_check_button_pressed',
+ 'mouse_check_button_released','mouse_clear','mouse_wheel_down','mouse_wheel_up','move_bounce','move_bounce_all','move_bounce_solid','move_contact','move_contact_all','move_contact_solid','move_outside_all',
+ 'move_outside_solid','move_random','move_snap','move_towards_point','move_wrap','mp_grid_add_cell','mp_grid_add_instances','mp_grid_add_rectangle','mp_grid_clear_all','mp_grid_clear_cell',
+ 'mp_grid_clear_rectangle','mp_grid_create','mp_grid_destroy','mp_grid_draw','mp_grid_path','mp_linear_path','mp_linear_path_object','mp_linear_step','mp_linear_step_object','mp_potential_path',
+ 'mp_potential_path_object','mp_potential_settings','mp_potential_step','mp_potential_step_object','network_connect','network_connect_raw','network_create_server','network_create_socket','network_destroy',
+ 'network_resolve','network_send_broadcast','network_send_packet','network_send_raw','network_send_udp','network_set_timeout','object_exists','object_get_depth','object_get_mask',
+ 'object_get_name','object_get_parent','object_get_persistent','object_get_physics','object_get_solid','object_get_sprite','object_get_visible','object_is_ancestor','object_set_depth','object_set_mask',
+ 'object_set_persistent','object_set_solid','object_set_sprite','object_set_visible','ord','os_get_config','os_get_info','os_get_language','os_is_network_connected','os_is_paused','os_lock_orientation',
+ 'os_powersave_enable','parameter_count','parameter_string','part_emitter_burst','part_emitter_clear','part_emitter_create','part_emitter_destroy','part_emitter_destroy_all','part_emitter_exists',
+ 'part_emitter_region','part_emitter_stream','part_particles_clear','part_particles_count','part_particles_create','part_particles_create_color','part_system_automatic_draw','part_system_automatic_update',
+ 'part_system_clear','part_system_create','part_system_depth','part_system_destroy','part_system_draw_order','part_system_drawit','part_system_exists','part_system_position','part_system_update',
+ 'part_type_alpha','part_type_alpha1','part_type_alpha2','part_type_alpha3','part_type_blend','part_type_clear','part_type_color','part_type_color1','part_type_color2','part_type_color3','part_type_color_hsv',
+ 'part_type_color_mix','part_type_color_rgb','part_type_create','part_type_death','part_type_destroy','part_type_direction','part_type_exists','part_type_gravity','part_type_life','part_type_orientation',
+ 'part_type_scale','part_type_shape','part_type_size','part_type_speed','part_type_sprite','part_type_step','path_add','path_add_point','path_append','path_assign','path_change_point','path_clear_points',
+ 'path_delete','path_delete_point','path_duplicate','path_end','path_exists','path_flip','path_get_closed','path_get_kind','path_get_length','path_get_name','path_get_number','path_get_point_speed',
+ 'path_get_point_x','path_get_point_y','path_get_precision','path_get_speed','path_get_x','path_get_y','path_insert_point','path_mirror','path_rescale','path_reverse','path_rotate','path_set_closed',
+ 'path_set_kind','path_set_precision','path_shift','path_start','physics_apply_force','physics_apply_impulse','physics_apply_local_force','physics_apply_local_impulse','physics_apply_torque',
+ 'physics_draw_debug','physics_fixture_add_point','physics_fixture_bind','physics_fixture_bind_ext','physics_fixture_create','physics_fixture_delete','physics_fixture_set_angular_damping',
+ 'physics_fixture_set_awake','physics_fixture_set_box_shape','physics_fixture_set_circle_shape','physics_fixture_set_collision_group','physics_fixture_set_density','physics_fixture_set_edge_shape',
+ 'physics_fixture_set_friction','physics_fixture_set_kinematic','physics_fixture_set_linear_damping','physics_fixture_set_polygon_shape','physics_fixture_set_restitution','physics_fixture_set_sensor',
+ 'physics_get_density','physics_get_friction','physics_get_restitution','physics_joint_delete','physics_joint_distance_create','physics_joint_enable_motor','physics_joint_gear_create','physics_joint_get_value',
+ 'physics_joint_prismatic_create','physics_joint_pulley_create','physics_joint_revolute_create','physics_joint_set_value','physics_mass_properties','physics_pause_enable','physics_remove_fixture','physics_set_density',
+ 'physics_set_friction','physics_set_restitution','physics_test_overlap','physics_world_create','physics_world_draw_debug','physics_world_gravity','physics_world_update_iterations','physics_world_update_speed',
+ 'place_empty','place_free','place_meeting','place_snapped','playhaven_add_notification_badge','playhaven_hide_notification_badge','playhaven_position_notification_badge','playhaven_update_notification_badge',
+ 'pocketchange_display_reward','pocketchange_display_shop','point_direction','point_distance','point_distance_3d','position_change','position_destroy','position_empty','position_meeting','power','radtodeg','random',
+ 'random_get_seed','random_range','random_set_seed','randomize','real','room_add','room_assign','room_duplicate','room_exists','room_get_name','room_goto','room_goto_next','room_goto_previous','room_instance_add',
+ 'room_instance_clear','room_next','room_previous','room_restart','room_set_background','room_set_background_color','room_set_height','room_set_persistent','room_set_view','room_set_view_enabled','room_set_width',
+ 'room_tile_add','room_tile_add_ext','room_tile_clear','round','screen_save','screen_save_part','script_execute','script_exists','script_get_name','sha1_file','sha1_string_unicode','sha1_string_utf8','shader_enable_corner_id',
+ 'shader_get_sampler_index','shader_get_uniform','shader_is_compiled','shader_reset','shader_set','shader_set_uniform_f','shader_set_uniform_f_array','shader_set_uniform_i','shader_set_uniform_i_array',
+ 'shader_set_uniform_matrix','shader_set_uniform_matrix_array','shaders_are_supported','shop_leave_rating','show_debug_message','show_debug_overlay','show_error','show_message','show_message_async',
+ 'show_question','show_question_async','sign','sin','sound_add','sound_delete','sound_exists','sound_fade','sound_get_name','sound_global_volume','sound_isplaying','sound_loop','sound_play','sound_replace',
+ 'sound_stop','sound_stop_all','sound_volume','sprite_add','sprite_add_from_surface','sprite_assign','sprite_collision_mask','sprite_create_from_surface','sprite_delete','sprite_duplicate','sprite_exists',
+ 'sprite_get_bbox_bottom','sprite_get_bbox_left','sprite_get_bbox_right','sprite_get_bbox_top','sprite_get_height','sprite_get_name','sprite_get_number','sprite_get_texture','sprite_get_tpe','sprite_get_uvs',
+ 'sprite_get_width','sprite_get_xoffset','sprite_get_yoffset','sprite_merge','sprite_replace','sprite_save','sprite_save_strip','sprite_set_alpha_from_sprite','sprite_set_cache_size','sprite_set_cache_size_ext',
+ 'sprite_set_offset','sqr','sqrt','steam_activate_overlay','steam_clear_achievement','steam_create_leaderboard','steam_download_friends_scores','steam_download_scores','steam_download_scores_around_user',
+ 'steam_file_delete','steam_file_exists','steam_file_persisted','steam_file_read','steam_file_share','steam_file_size','steam_file_write','steam_file_write_file','steam_get_achievement','steam_get_persona_name',
+ 'steam_get_quota_free','steam_get_quota_total','steam_get_stat_avg_rate','steam_get_stat_float','steam_get_stat_int','steam_get_user_steam_id','steam_initialised','steam_is_cloud_enabled_for_account',
+ 'steam_is_cloud_enabled_for_app','steam_is_overlay_activated','steam_is_overlay_enabled','steam_is_screenshot_requested','steam_is_user_logged_on','steam_publish_workshop_file','steam_reset_all_stats',
+ 'steam_reset_all_stats_achievements','steam_send_screenshot','steam_set_achievement','steam_set_stat_avg_rate','steam_set_stat_float','steam_set_stat_int','steam_stats_ready','steam_upload_score',
+ 'steam_user_installed_dlc','steam_user_owns_dlc','string','string_byte_at','string_byte_length','string_char_at','string_copy','string_count','string_delete','string_digits','string_format','string_height',
+ 'string_height_ext','string_insert','string_length','string_letters','string_lettersdigits','string_lower','string_pos','string_repeat','string_replace','string_replace_all','string_set_byte_at','string_upper',
+ 'string_width','string_width_ext','surface_copy','surface_copy_part','surface_create','surface_create_ext','surface_exists','surface_free','surface_get_height','surface_get_texture','surface_get_width',
+ 'surface_getpixel','surface_getpixel_ext','surface_reset_target','surface_save','surface_save_part','surface_set_target','surface_set_target_ext','tan','texture_exists','texture_get_height','texture_get_texel_height',
+ 'texture_get_texel_width','texture_get_width','texture_set_blending','texture_set_interpolation','texture_set_interpolation_ext','texture_set_repeat','texture_set_repeat_ext','texture_set_stage','tile_add',
+ 'tile_delete','tile_delete_at','tile_exists','tile_find','tile_get_alpha','tile_get_background','tile_get_blend','tile_get_depth','tile_get_height','tile_get_left','tile_get_top','tile_get_visible','tile_get_width',
+ 'tile_get_x','tile_get_xscale','tile_get_y','tile_get_yscale','tile_layer_delete','tile_layer_delete_at','tile_layer_depth','tile_layer_find','tile_layer_hide','tile_layer_shift','tile_layer_show','tile_set_alpha',
+ 'tile_set_background','tile_set_blend','tile_set_depth','tile_set_position','tile_set_region','tile_set_scale','tile_set_visible','timeline_add','timeline_clear','timeline_delete','timeline_exists','timeline_get_name',
+ 'timeline_moment_clear','url_get_domain','url_open','url_open_ext','url_open_full','vertex_argb','vertex_begin','vertex_colour','vertex_create_buffer','vertex_create_buffer_ext','vertex_delete_buffer','vertex_end',
+ 'vertex_float1','vertex_float2','vertex_float3','vertex_float4','vertex_format_add_colour','vertex_format_add_custom','vertex_format_add_normal','vertex_format_add_position','vertex_format_add_position_3d',
+ 'vertex_format_add_textcoord','vertex_format_begin','vertex_format_end','vertex_freeze','vertex_normal','vertex_position','vertex_position_3d','vertex_submit','vertex_texcoord','vertex_ubyte4','virtual_key_add',
+ 'virtual_key_delete','virtual_key_hide','virtual_key_show','win8_appbar_add_element','win8_appbar_enable','win8_appbar_remove_element','win8_device_touchscreen_available','win8_license_initialize_sandbox',
+ 'win8_license_trial_version','win8_livetile_badge_clear','win8_livetile_badge_notification','win8_livetile_notification_begin','win8_livetile_notification_end','win8_livetile_notification_expiry',
+ 'win8_livetile_notification_image_add','win8_livetile_notification_secondary_begin','win8_livetile_notification_tag','win8_livetile_notification_text_add','win8_livetile_queue_enable','win8_livetile_tile_clear',
+ 'win8_livetile_tile_notification','win8_search_add_suggestions','win8_search_disable','win8_search_enable','win8_secondarytile_badge_notification','win8_secondarytile_delete','win8_secondarytile_pin',
+ 'win8_settingscharm_add_entry','win8_settingscharm_add_html_entry','win8_settingscharm_add_xaml_entry','win8_settingscharm_get_xaml_property','win8_settingscharm_remove_entry','win8_settingscharm_set_xaml_property',
+ 'win8_share_file','win8_share_image','win8_share_screenshot','win8_share_text','win8_share_url','window_center','window_get_caption','window_get_color','window_get_cursor','window_get_fullscreen','window_get_height',
+ 'window_get_width','window_get_x','window_get_y','window_handle','window_has_focus','window_mouse_get_x','window_mouse_get_y','window_mouse_set','window_set_caption','window_set_color','window_set_cursor',
+ 'window_set_fullscreen','window_set_position','window_set_rectangle','window_set_size','window_view_mouse_get_x','window_view_mouse_get_y','window_views_mouse_get_x','window_views_mouse_get_y',
+ 'winphone_license_trial_version','winphone_tile_back_content','winphone_tile_back_content_wide','winphone_tile_back_image','winphone_tile_back_image_wide','winphone_tile_back_title','winphone_tile_background_color',
+ 'winphone_tile_count','winphone_tile_cycle_images','winphone_tile_front_image','winphone_tile_front_image_small','winphone_tile_front_image_wide','winphone_tile_icon_image','winphone_tile_small_background_image',
+ 'winphone_tile_small_icon_image','winphone_tile_title','winphone_tile_wide_content','zip_unzip'
+ ),
+
+ // Constants
+ 3 => array(
+ 'ANSI_CHARSET','ARABIC_CHARSET','BALTIC_CHARSET','CHINESEBIG5_CHARSET','DEFAULT_CHARSET','EASTEUROPE_CHARSET','GB2312_CHARSET','GREEK_CHARSET','HANGEUL_CHARSET','HEBREW_CHARSET','JOHAB_CHARSET',
+ 'MAC_CHARSET','OEM_CHARSET','RUSSIAN_CHARSET','SHIFTJIS_CHARSET','SYMBOL_CHARSET','THAI_CHARSET','TURKISH_CHARSET','VIETNAMESE_CHARSET','achievement_achievement_info','achievement_challenge_completed',
+ 'achievement_challenge_completed_by_remote','achievement_challenge_launched','achievement_challenge_list_received','achievement_challenge_received','achievement_filter_all_players',
+ 'achievement_filter_friends_only','achievement_friends_info','achievement_leaderboard_info','achievement_our_info','achievement_pic_loaded','achievement_player_info','achievement_purchase_info',
+ 'achievement_show_achievement','achievement_show_bank','achievement_show_friend_picker','achievement_show_leaderboard','achievement_show_profile','achievement_show_purchase_prompt','achievement_show_ui',
+ 'achievement_type_achievement_challenge','achievement_type_score_challenge','all','asset_background','asset_font','asset_object','asset_path','asset_room','asset_script','asset_sound','asset_sprite',
+ 'asset_timeline','asset_unknown','audio_falloff_exponent_distance','audio_falloff_exponent_distance_clamped','audio_falloff_inverse_distance','audio_falloff_inverse_distance_clamped',
+ 'audio_falloff_linear_distance','audio_falloff_linear_distance_clamped','audio_falloff_none','audio_new_system','audio_old_system','bm_add','bm_dest_alpha','bm_dest_color','bm_inv_dest_alpha',
+ 'bm_inv_dest_color','bm_inv_src_alpha','bm_inv_src_color','bm_max','bm_normal','bm_one','bm_src_alpha','bm_src_alpha_sat','bm_src_color','bm_subtract','bm_zero','browser_chrome',
+ 'browser_firefox','browser_ie','browser_ie_mobile','browser_not_a_browser','browser_opera','browser_safari','browser_safari_mobile','browser_tizen','browser_unknown','browser_windows_store','buffer_bool',
+ 'buffer_f16','buffer_f32','buffer_f64','buffer_fast','buffer_fixed','buffer_generalerror','buffer_grow','buffer_invalidtype','buffer_outofbounds','buffer_outofspace','buffer_s16','buffer_s32','buffer_s8',
+ 'buffer_seek_end','buffer_seek_relative','buffer_seek_start','buffer_string','buffer_u16','buffer_u32','buffer_u8','buffer_vbuffer','buffer_wrap','button_type','c_aqua','c_black','c_blue','c_dkgray',
+ 'c_fuchsia','c_gray','c_green','c_lime','c_ltgray','c_maroon','c_navy','c_olive','c_orange','c_purple','c_red','c_silver','c_teal','c_white','c_yellow','cr_appstart','cr_arrow','cr_beam','cr_cross',
+ 'cr_default','cr_drag','cr_handpoint','cr_help','cr_hourglass','cr_hsplit','cr_multidrag','cr_no','cr_nodrop','cr_none','cr_size_all','cr_size_nesw','cr_size_ns','cr_size_nwse','cr_size_we','cr_sqlwait',
+ 'cr_uparrow','cr_vsplit','device_emulator','device_ios_ipad','device_ios_ipad_retina','device_ios_iphone','device_ios_iphone5','device_ios_iphone_retina','device_ios_unknown','device_tablet','display_landscape',
+ 'display_landscape_flipped','display_portrait','display_portrait_flipped','dll_cdecl','dll_stdcall','ds_type_grid','ds_type_list','ds_type_map','ds_type_priority','ds_type_queue','ds_type_stack','e','ef_cloud',
+ 'ef_ellipse','ef_explosion','ef_firework','ef_flare','ef_rain','ef_ring','ef_smoke','ef_smokeup','ef_snow','ef_spark','ef_star','ev_alarm','ev_animation_end','ev_boundary','ev_close_button','ev_collision',
+ 'ev_create','ev_destroy','ev_draw','ev_end_of_path','ev_game_end','ev_game_start','ev_global_left_button','ev_global_left_press','ev_global_left_release','ev_global_middle_button','ev_global_middle_press',
+ 'ev_global_middle_release','ev_global_press','ev_global_release','ev_global_right_button','ev_global_right_press','ev_global_right_release','ev_gui','ev_joystick1_button1','ev_joystick1_button2',
+ 'ev_joystick1_button3','ev_joystick1_button4','ev_joystick1_button5','ev_joystick1_button6','ev_joystick1_button7','ev_joystick1_button8','ev_joystick1_down','ev_joystick1_left','ev_joystick1_right',
+ 'ev_joystick1_up','ev_joystick2_button1','ev_joystick2_button2','ev_joystick2_button3','ev_joystick2_button4','ev_joystick2_button5','ev_joystick2_button6','ev_joystick2_button7','ev_joystick2_button8',
+ 'ev_joystick2_down','ev_joystick2_left','ev_joystick2_right','ev_joystick2_up','ev_keyboard','ev_keypress','ev_keyrelease','ev_left_button','ev_left_press','ev_left_release','ev_middle_button',
+ 'ev_middle_press','ev_middle_release','ev_mouse','ev_mouse_enter','ev_mouse_leave','ev_mouse_wheel_down','ev_mouse_wheel_up','ev_no_button','ev_no_more_health','ev_no_more_lives','ev_other','ev_outside',
+ 'ev_right_button','ev_right_press','ev_right_release','ev_room_end','ev_room_start','ev_step','ev_step_begin','ev_step_end','ev_step_normal','ev_trigger','ev_user0','ev_user1','ev_user10','ev_user11',
+ 'ev_user12','ev_user13','ev_user14','ev_user15','ev_user2','ev_user3','ev_user4','ev_user5','ev_user6','ev_user7','ev_user8','ev_user9','fa_archive','fa_bottom','fa_center','fa_directory','fa_hidden',
+ 'fa_left','fa_middle','fa_readonly','fa_right','fa_sysfile','fa_top','fa_volumeid','false','gp_axislh','gp_axislv','gp_axisrh','gp_axisrv','gp_face1','gp_face2','gp_face3','gp_face4','gp_padd',
+ 'gp_padl','gp_padr','gp_padu','gp_select','gp_shoulderl','gp_shoulderlb','gp_shoulderr','gp_shoulderrb','gp_start','gp_stickl','gp_stickr','input_type','lb_disp_none','lb_disp_numeric','lb_disp_time_ms',
+ 'lb_disp_time_sec','lb_sort_ascending','lb_sort_descending','lb_sort_none','leaderboard_type_number','leaderboard_type_time_mins_secs','matrix_projection','matrix_view','matrix_world','mb_any',
+ 'mb_left','mb_middle','mb_none','mb_right','network_socket_bluetooth','network_socket_tcp','network_socket_udp','network_type_connect','network_type_data','network_type_disconnect',
+ 'of_challenge_lose','of_challenge_tie','of_challenge_win','os_android','os_ios','os_linux','os_macosx','os_psp','os_symbian','os_tizen','os_unknown','os_win32','os_win8native','os_windows','os_winphone',
+ 'ov_achievements','ov_community','ov_friends','ov_gamegroup','ov_players','ov_settings','phy_debug_render_aabb','phy_debug_render_collision_pairs','phy_debug_render_coms',
+ 'phy_debug_render_core_shapes','phy_debug_render_joints','phy_debug_render_obb','phy_debug_render_shapes','phy_joint_anchor_1_x','phy_joint_anchor_1_y','phy_joint_anchor_2_x','phy_joint_anchor_2_y',
+ 'phy_joint_angle','phy_joint_angle_limits','phy_joint_damping_ratio','phy_joint_frequency','phy_joint_length_1','phy_joint_length_2','phy_joint_lower_angle_limit','phy_joint_max_motor_force',
+ 'phy_joint_max_motor_torque','phy_joint_motor_force','phy_joint_motor_speed','phy_joint_motor_torque','phy_joint_reaction_force_x','phy_joint_reaction_force_y','phy_joint_reaction_torque','phy_joint_speed',
+ 'phy_joint_translation','phy_joint_upper_angle_limit','pi','pr_linelist','pr_linestrip','pr_pointlist','pr_trianglefan','pr_trianglelist','pr_trianglestrip','ps_change_all','ps_change_motion',
+ 'ps_change_shape','ps_deflect_horizontal','ps_deflect_vertical','ps_distr_gaussian','ps_distr_invgaussian','ps_distr_linear','ps_force_constant','ps_force_linear','ps_force_quadratic','ps_shape_diamond',
+ 'ps_shape_ellipse','ps_shape_line','ps_shape_rectangle','pt_shape_circle','pt_shape_cloud','pt_shape_disk','pt_shape_explosion','pt_shape_flare','pt_shape_line','pt_shape_pixel','pt_shape_ring',
+ 'pt_shape_smoke','pt_shape_snow','pt_shape_spark','pt_shape_sphere','pt_shape_square','pt_shape_star','se_chorus','se_compressor','se_echo','se_equalizer','se_flanger','se_gargle','se_none','se_reverb',
+ 'text_type','true','ty_real','ty_string','vertex_type_colour','vertex_type_float1','vertex_type_float2','vertex_type_float3','vertex_type_float4','vertex_type_ubyte4','vertex_usage_binormal',
+ 'vertex_usage_blendindices','vertex_usage_blendweight','vertex_usage_colour','vertex_usage_depth','vertex_usage_fog','vertex_usage_normal','vertex_usage_position','vertex_usage_psize','vertex_usage_sample',
+ 'vertex_usage_tagnet','vertex_usage_textcoord','vk_add','vk_alt','vk_anykey','vk_backspace','vk_control','vk_decimal','vk_delete','vk_divide','vk_down','vk_end','vk_enter','vk_escape','vk_f1','vk_f10',
+ 'vk_f11','vk_f12','vk_f2','vk_f3','vk_f4','vk_f5','vk_f6','vk_f7','vk_f8','vk_f9','vk_home','vk_insert','vk_lalt','vk_lcontrol','vk_left','vk_lshift','vk_multiply','vk_nokey','vk_numpad0','vk_numpad1',
+ 'vk_numpad2','vk_numpad3','vk_numpad4','vk_numpad5','vk_numpad6','vk_numpad7','vk_numpad8','vk_numpad9','vk_pagedown','vk_pageup','vk_pause','vk_printscreen','vk_ralt','vk_rcontrol','vk_return','vk_right',
+ 'vk_rshift','vk_shift','vk_space','vk_subtract','vk_tab','vk_up'
+ ),
+
+ // Keywords
+ 4 => array(
+ 'if','while','do','until','exit','break','continue','for','switch','case','default',
+ 'else','then','begin','end','repeat','var','globalvar','with','div','mod',
+ 'self','noone','other','global','local','return',
+ 'and','or','xor','not'
+ )
+ ),
+
+ 'SYMBOLS' => array(
+ // Angled brackets
+ 0 => array('{','}'),
+ // Other brackets
+ 1 => array('(',')','[',']'),
+ // Operators (NOTE: Operators and/or/not/xor are included in the keywords section. These are non-alphanumeric operators
+ 2 => array('&&', '||', '^^', '&', '|', '^',
+ '<', '<=', '==', '!=', '>', '>=', '=',
+ '<<', '>>',
+ '+=', '-=', '*=', '/=',
+ '+', '-', '*', '/',
+ '!', '~', ',', ';'
+ )),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #800000;',
+ 2 => 'color: #800000;',
+ 3 => 'color: #800000;',
+ 4 => 'color: #000080; font-weight: bold;'),
+ 'COMMENTS' => array(
+ 1 => 'font-style: italic; color: #008000;',
+ 'MULTI' => 'font-style: italic; color: #008000;'),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''),
+ 'BRACKETS' => array(
+ 0 => 'color: #000080;'),
+ 'STRINGS' => array(
+ 0 => 'color: #0000FF;',
+ 1 => 'color: #0000FF;'),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000FF;'),
+ 'METHODS' => array(
+ 0 => 'color: #800000;'),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000080; font-weight: bold;',
+ 1 => 'color: #000000;',
+ 2 => 'color: #000000;'),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/gnuplot.php b/platform/www/vendor/geshi/geshi/src/geshi/gnuplot.php
new file mode 100644
index 0000000..3af5f93
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/gnuplot.php
@@ -0,0 +1,294 @@
+<?php
+/*************************************************************************************
+ * gnuplot.php
+ * ----------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff (http://milianw.de)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/07/07
+ *
+ * Gnuplot script language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/07 (1.0.8)
+ * - Initial import
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Gnuplot',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('`', '"', "'"),
+ 'ESCAPE_CHAR' => '\\',
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_SCI_SHORT |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ // copy output of help command, indent properly and use this replace regexp:
+ // ([a-z0-9_\-]+)(( )+|$) => '\1',\3
+
+ // commands as found in `help commands`
+ 1 => array(
+ 'bind', 'call', 'cd', 'clear',
+ 'exit', 'fit', 'help', 'history',
+ 'if', 'load', 'lower', 'pause',
+ 'plot', 'print', 'pwd', 'quit',
+ 'raise', 'replot', 'reread', 'reset',
+ 'save', 'set', 'shell', 'show',
+ 'splot', 'system', 'test', 'unset',
+ 'update'
+ ),
+ 2 => array(
+ // set commands as returned by `help set`
+ 'angles', 'arrow', 'autoscale', 'bars',
+ 'bmargin', 'border', 'boxwidth', 'cbdata',
+ 'cbdtics', 'cblabel', 'cbmtics', 'cbrange',
+ 'cbtics', 'clabel', 'clip', 'cntrparam',
+ 'colorbox', 'contour', 'datafile', 'date_specifiers',
+ 'decimalsign', 'dgrid3d', 'dummy', 'encoding',
+ 'fontpath', 'format', 'grid',
+ 'hidden3d', 'historysize', 'isosamples', 'key',
+ 'label', 'lmargin', 'loadpath', 'locale',
+ 'log', 'logscale', 'macros', 'mapping',
+ 'margin', 'missing', 'mouse', 'multiplot',
+ 'mx2tics', 'mxtics', 'my2tics', 'mytics',
+ 'mztics', 'object', 'offsets', 'origin',
+ 'output', 'palette', 'parametric', 'pm3d',
+ 'pointsize', 'polar', 'rmargin',
+ 'rrange', 'samples', 'size', 'style',
+ 'surface', 'table', 'term', 'terminal',
+ 'termoption', 'tics', 'ticscale', 'ticslevel',
+ 'time_specifiers', 'timefmt', 'timestamp', 'title',
+ 'trange', 'urange', 'view',
+ 'vrange', 'x2data', 'x2dtics', 'x2label',
+ 'x2mtics', 'x2range', 'x2tics', 'x2zeroaxis',
+ 'xdata', 'xdtics', 'xlabel', 'xmtics',
+ 'xrange', 'xtics', 'xyplane', 'xzeroaxis',
+ 'y2data', 'y2dtics', 'y2label', 'y2mtics',
+ 'y2range', 'y2tics', 'y2zeroaxis', 'ydata',
+ 'ydtics', 'ylabel', 'ymtics', 'yrange',
+ 'ytics', 'yzeroaxis', 'zdata', 'zdtics',
+ 'zero', 'zeroaxis', 'zlabel', 'zmtics',
+ 'zrange', 'ztics', 'zzeroaxis',
+ // same but with leading no
+ 'noangles', 'noarrow', 'noautoscale', 'nobars',
+ 'nobmargin', 'noborder', 'noboxwidth', 'nocbdata',
+ 'nocbdtics', 'nocblabel', 'nocbmtics', 'nocbrange',
+ 'nocbtics', 'noclabel', 'noclip', 'nocntrparam',
+ 'nocolorbox', 'nocontour', 'nodatafile', 'nodate_specifiers',
+ 'nodecimalsign', 'nodgrid3d', 'nodummy', 'noencoding',
+ 'nofit', 'nofontpath', 'noformat', 'nogrid',
+ 'nohidden3d', 'nohistorysize', 'noisosamples', 'nokey',
+ 'nolabel', 'nolmargin', 'noloadpath', 'nolocale',
+ 'nolog', 'nologscale', 'nomacros', 'nomapping',
+ 'nomargin', 'nomissing', 'nomouse', 'nomultiplot',
+ 'nomx2tics', 'nomxtics', 'nomy2tics', 'nomytics',
+ 'nomztics', 'noobject', 'nooffsets', 'noorigin',
+ 'nooutput', 'nopalette', 'noparametric', 'nopm3d',
+ 'nopointsize', 'nopolar', 'noprint', 'normargin',
+ 'norrange', 'nosamples', 'nosize', 'nostyle',
+ 'nosurface', 'notable', 'noterm', 'noterminal',
+ 'notermoption', 'notics', 'noticscale', 'noticslevel',
+ 'notime_specifiers', 'notimefmt', 'notimestamp', 'notitle',
+ 'notmargin', 'notrange', 'nourange', 'noview',
+ 'novrange', 'nox2data', 'nox2dtics', 'nox2label',
+ 'nox2mtics', 'nox2range', 'nox2tics', 'nox2zeroaxis',
+ 'noxdata', 'noxdtics', 'noxlabel', 'noxmtics',
+ 'noxrange', 'noxtics', 'noxyplane', 'noxzeroaxis',
+ 'noy2data', 'noy2dtics', 'noy2label', 'noy2mtics',
+ 'noy2range', 'noy2tics', 'noy2zeroaxis', 'noydata',
+ 'noydtics', 'noylabel', 'noymtics', 'noyrange',
+ 'noytics', 'noyzeroaxis', 'nozdata', 'nozdtics',
+ 'nozero', 'nozeroaxis', 'nozlabel', 'nozmtics',
+ 'nozrange', 'noztics', 'nozzeroaxis',
+ ),
+ 3 => array(
+ // predefined variables
+ 'pi', 'NaN', 'GNUTERM',
+ 'GPVAL_X_MIN', 'GPVAL_X_MAX', 'GPVAL_Y_MIN', 'GPVAL_Y_MAX',
+ 'GPVAL_TERM', 'GPVAL_TERMOPTIONS', 'GPVAL_OUTPUT',
+ 'GPVAL_VERSION', 'GPVAL_PATcHLEVEL', 'GPVAL_COMPILE_OPTIONS',
+ 'MOUSE_KEY', 'MOUSE_X', 'MOUSE_X2', 'MOUSE_Y', 'MOUSE_Y2',
+ 'MOUSE_BUTTON', 'MOUSE_SHIFT', 'MOUSE_ALT', 'MOUSE_CTRL'
+ ),
+ 4 => array(
+ // predefined functions `help functions`
+ 'abs', 'acos', 'acosh', 'arg',
+ 'asin', 'asinh', 'atan', 'atan2',
+ 'atanh', 'besj0', 'besj1', 'besy0',
+ 'besy1', 'ceil', 'column', 'cos',
+ 'cosh', 'defined', 'erf', 'erfc',
+ 'exists', 'exp', 'floor', 'gamma',
+ 'gprintf', 'ibeta', 'igamma', 'imag',
+ 'int', 'inverf', 'invnorm', 'lambertw',
+ 'lgamma', 'log10', 'norm',
+ 'rand', 'random', 'real', 'sgn',
+ 'sin', 'sinh', 'sprintf', 'sqrt',
+ 'stringcolumn', 'strlen', 'strstrt', 'substr',
+ 'tan', 'tanh', 'timecolumn',
+ 'tm_hour', 'tm_mday', 'tm_min', 'tm_mon',
+ 'tm_sec', 'tm_wday', 'tm_yday', 'tm_year',
+ 'valid', 'word', 'words',
+ ),
+ 5 => array(
+ // mixed arguments
+ // there is no sane way to get these ones easily...
+ 'autofreq', 'x', 'y', 'z',
+ 'lt', 'linetype', 'lw', 'linewidth', 'ls', 'linestyle',
+ 'out', 'rotate by', 'screen',
+ 'enhanced', 'via',
+ // `help set key`
+ 'on', 'off', 'default', 'inside', 'outside', 'tmargin',
+ 'at', 'left', 'right', 'center', 'top', 'bottom', 'vertical', 'horizontal', 'Left', 'Right',
+ 'noreverse', 'reverse', 'noinvert', 'invert', 'samplen', 'spacing', 'width', 'height',
+ 'noautotitle', 'autotitle', 'noenhanced', 'nobox', 'box',
+
+ // help set terminal postscript
+ 'landscape', 'portrait', 'eps', 'defaultplex', 'simplex', 'duplex',
+ 'fontfile', 'add', 'delete', 'nofontfiles', 'level1', 'leveldefault',
+ 'color', 'colour', 'monochrome', 'solid', 'dashed', 'dashlength', 'dl',
+ 'rounded', 'butt', 'palfuncparam', 'blacktext', 'colortext', 'colourtext',
+ 'font',
+
+ // help set terminal png
+ 'notransparent', 'transparent', 'nointerlace', 'interlace',
+ 'notruecolor', 'truecolor', 'tiny', 'small', 'medium', 'large', 'giant',
+ 'nocrop', 'crop',
+
+ // `help plot`
+ 'acsplines', 'bezier', 'binary', 'csplines',
+ 'every',
+ 'example', 'frequency', 'index', 'matrix',
+ 'ranges', 'sbezier', 'smooth',
+ 'special-filenames', 'thru',
+ 'unique', 'using', 'with',
+
+ // `help plotting styles`
+ 'boxerrorbars', 'boxes', 'boxxyerrorbars', 'candlesticks',
+ 'dots', 'errorbars', 'errorlines', 'filledcurves',
+ 'financebars', 'fsteps', 'histeps', 'histograms',
+ 'image', 'impulses', 'labels', 'lines',
+ 'linespoints', 'points', 'rgbimage', 'steps',
+ 'vectors', 'xerrorbars', 'xerrorlines', 'xyerrorbars',
+ 'xyerrorlines', 'yerrorbars', 'yerrorlines',
+
+
+ // terminals `help terminals`
+ 'aed512', 'aed767', 'aifm', 'bitgraph',
+ 'cgm', 'corel', 'dumb', 'dxf',
+ 'eepic', 'emf', 'emtex', 'epslatex',
+ 'epson-180dpi', 'epson-60dpi', 'epson-lx800', 'fig',
+ 'gif', 'gpic', 'hp2623a', 'hp2648',
+ 'hp500c', 'hpdj', 'hpgl', 'hpljii',
+ 'hppj', 'imagen', 'jpeg', 'kc-tek40xx',
+ 'km-tek40xx', 'latex', 'mf', 'mif',
+ 'mp', 'nec-cp6', 'okidata', 'pbm',
+ 'pcl5', 'png', 'pop', 'postscript',
+ 'pslatex', 'pstex', 'pstricks', 'push',
+ 'qms', 'regis', 'selanar', 'starc',
+ 'svg', 'tandy-60dpi', 'tek40xx', 'tek410x',
+ 'texdraw', 'tgif', 'tkcanvas', 'tpic',
+ 'vttek', 'x11', 'xlib',
+ )
+ ),
+ 'REGEXPS' => array(
+ //Variable assignment
+ 0 => "(?<![?;>\w])([a-zA-Z_][a-zA-Z0-9_]*)\s*=",
+ //Numbers with unit
+ 1 => "(?<=^|\s)([0-9]*\.?[0-9]+\s*cm)"
+ ),
+ 'SYMBOLS' => array(
+ '-', '+', '~', '!', '$',
+ '*', '/', '%', '=', '<', '>', '&',
+ '^', '|', '.', 'eq', 'ne', '?:', ':', '`', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #990000;',
+ 3 => 'color: #550000;',
+ 4 => 'color: #7a0874;',
+ 5 => 'color: #448888;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight:bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000099; font-weight:bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;',
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #007800;',
+ 1 => 'color: #cc66cc;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => 'http://www.google.com/search?q=%22set+{FNAME}%22+site%3Ahttp%3A%2F%2Fwww.gnuplot.info%2Fdocs%2F&amp;btnI=lucky',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 4 => array(
+ 'DISALLOWED_AFTER' => "(?![\.\-a-zA-Z0-9_%])"
+ )
+ )
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/go.php b/platform/www/vendor/geshi/geshi/src/geshi/go.php
new file mode 100644
index 0000000..83d3cab
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/go.php
@@ -0,0 +1,373 @@
+<?php
+/*************************************************************************************
+ * go.php
+ * --------
+ * Author: Markus Jarderot (mizardx at gmail dot com)
+ * Copyright: (c) 2010 Markus Jarderot
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/05/20
+ *
+ * Go language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/05/20 (1.0.8.9)
+ * - First Release
+ *
+ * TODO (updated 2010/05/20)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Go',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ # Raw strings (escapes and linebreaks ignored)
+ 2 => "#`[^`]*`#"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'"),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ 1 => "#\\\\[abfnrtv\\\\\'\"]#",
+ 2 => "#\\\\[0-7]{3}#",
+ 3 => "#\\\\x[0-9a-fA-F]{2}#",
+ 4 => "#\\\\u[0-9a-fA-F]{4}#",
+ 5 => "#\\\\U[0-9a-fA-F]{8}#"
+ ),
+ 'NUMBERS' => array(
+ # integer literals (possibly imaginary)
+ 0 => '\b([1-9][0-9]*i?|0[0-7]*|0[xX][0-9a-f]+|0[0-9]*i)\b',
+ # real floating point literals
+ 1 => '\b((?:\d+\.\d*(?:[Ee][+-]?\d+\b)?|\.\d+(?:[Ee][+-]?\d+)?|\d+[Ee][+-]?\d+)?)\b',
+ # imaginary floating point literals
+ 2 => '\b((?:\d+\.\d*(?:[Ee][+-]?\d+)?|\.\d+(?:[Ee][+-]?\d+)?|\d+[Ee][+-]?\d+)?i)\b'
+ ),
+ 'KEYWORDS' => array(
+ # statements
+ 1 => array(
+ 'break', 'case', 'const', 'continue', 'default', 'defer', 'else',
+ 'fallthrough', 'for', 'go', 'goto', 'if', 'import', 'package',
+ 'range', 'return', 'select', 'switch', 'type', 'var'
+ ),
+ # literals
+ 2 => array(
+ 'nil', 'true', 'false'
+ ),
+ # built-in functions
+ 3 => array(
+ 'close', 'closed', 'len', 'cap', 'new', 'make', 'copy', 'cmplx',
+ 'real', 'imag', 'panic', 'recover', 'print', 'println'
+ ),
+ # built-in types
+ 4 => array(
+ 'chan', 'func', 'interface', 'map', 'struct', 'bool', 'uint8',
+ 'uint16', 'uint32', 'uint64', 'int8', 'int16', 'int32', 'int64',
+ 'float32', 'float64', 'complex64', 'complex128', 'byte', 'uint',
+ 'int', 'float', 'complex', 'uintptr', 'string'
+ ),
+ # library types
+ 5 => array(
+ 'aes.Cipher', 'aes.KeySizeError', 'ascii85.CorruptInputError', 'asn1.BitString',
+ 'asn1.RawValue', 'asn1.StructuralError', 'asn1.SyntaxError', 'ast.ChanDir',
+ 'ast.Comment', 'ast.CommentGroup', 'ast.Decl', 'ast.Expr', 'ast.Field',
+ 'ast.FieldList', 'ast.File', 'ast.Filter', 'ast.MergeMode', 'ast.Node',
+ 'ast.ObjKind', 'ast.Object', 'ast.Package', 'ast.Scope', 'ast.Stmt',
+ 'ast.Visitor', 'av.Color', 'av.Image', 'av.Window', 'base64.CorruptInputError',
+ 'base64.Encoding', 'big.Int', 'big.Word', 'bignum.Integer', 'bignum.Rational',
+ 'binary.ByteOrder', 'block.Cipher', 'block.EAXTagError', 'blowfish.Cipher',
+ 'blowfish.KeySizeError', 'bufio.BufSizeError', 'bufio.Error', 'bufio.ReadWriter',
+ 'bufio.Reader', 'bufio.Writer', 'bytes.Buffer', 'datafmt.Environment',
+ 'datafmt.Format', 'datafmt.Formatter', 'datafmt.FormatterMap', 'datafmt.State',
+ 'doc.Filter', 'doc.FuncDoc', 'doc.PackageDoc', 'doc.TypeDoc', 'doc.ValueDoc',
+ 'draw.Color', 'draw.Context', 'draw.Image', 'draw.Mouse', 'draw.Op',
+ 'draw.Point', 'draw.Rectangle', 'dwarf.AddrType', 'dwarf.ArrayType',
+ 'dwarf.Attr', 'dwarf.BasicType', 'dwarf.BoolType', 'dwarf.CharType',
+ 'dwarf.CommonType', 'dwarf.ComplexType', 'dwarf.Data', 'dwarf.DecodeError',
+ 'dwarf.DotDotDotType', 'dwarf.Entry', 'dwarf.EnumType', 'dwarf.EnumValue',
+ 'dwarf.Field', 'dwarf.FloatType', 'dwarf.FuncType', 'dwarf.IntType',
+ 'dwarf.Offset', 'dwarf.PtrType', 'dwarf.QualType', 'dwarf.Reader',
+ 'dwarf.StructField', 'dwarf.StructType', 'dwarf.Tag', 'dwarf.Type',
+ 'dwarf.TypedefType', 'dwarf.UcharType', 'dwarf.UintType', 'dwarf.VoidType',
+ 'elf.Class', 'elf.Data', 'elf.Dyn32', 'elf.Dyn64', 'elf.DynFlag', 'elf.DynTag',
+ 'elf.File', 'elf.FileHeader', 'elf.FormatError', 'elf.Header32', 'elf.Header64',
+ 'elf.Machine', 'elf.NType', 'elf.OSABI', 'elf.Prog', 'elf.Prog32', 'elf.Prog64',
+ 'elf.ProgFlag', 'elf.ProgHeader', 'elf.ProgType', 'elf.R_386', 'elf.R_ALPHA',
+ 'elf.R_ARM', 'elf.R_PPC', 'elf.R_SPARC', 'elf.R_X86_64', 'elf.Rel32',
+ 'elf.Rel64', 'elf.Rela32', 'elf.Rela64', 'elf.Section', 'elf.Section32',
+ 'elf.Section64', 'elf.SectionFlag', 'elf.SectionHeader', 'elf.SectionIndex',
+ 'elf.SectionType', 'elf.Sym32', 'elf.Sym64', 'elf.SymBind', 'elf.SymType',
+ 'elf.SymVis', 'elf.Symbol', 'elf.Type', 'elf.Version', 'eval.ArrayType',
+ 'eval.ArrayValue', 'eval.BoolValue', 'eval.BoundedType', 'eval.ChanType',
+ 'eval.Code', 'eval.Constant', 'eval.Def', 'eval.DivByZeroError',
+ 'eval.FloatValue', 'eval.Frame', 'eval.Func', 'eval.FuncDecl', 'eval.FuncType',
+ 'eval.FuncValue', 'eval.IMethod', 'eval.IdealFloatValue', 'eval.IdealIntValue',
+ 'eval.IndexError', 'eval.IntValue', 'eval.Interface', 'eval.InterfaceType',
+ 'eval.InterfaceValue', 'eval.KeyError', 'eval.Map', 'eval.MapType',
+ 'eval.MapValue', 'eval.Method', 'eval.MultiType', 'eval.NamedType',
+ 'eval.NegativeCapacityError', 'eval.NegativeLengthError', 'eval.NilPointerError',
+ 'eval.PtrType', 'eval.PtrValue', 'eval.RedefinitionError', 'eval.Scope',
+ 'eval.Slice', 'eval.SliceError', 'eval.SliceType', 'eval.SliceValue',
+ 'eval.StringValue', 'eval.StructField', 'eval.StructType', 'eval.StructValue',
+ 'eval.Thread', 'eval.Type', 'eval.UintValue', 'eval.Value', 'eval.Variable',
+ 'eval.World', 'exec.Cmd', 'expvar.Int', 'expvar.IntFunc', 'expvar.KeyValue',
+ 'expvar.Map', 'expvar.String', 'expvar.StringFunc', 'expvar.Var', 'flag.Flag',
+ 'flag.Value', 'flate.CorruptInputError', 'flate.InternalError',
+ 'flate.ReadError', 'flate.Reader', 'flate.WriteError', 'flate.WrongValueError',
+ 'fmt.Formatter', 'fmt.GoStringer', 'fmt.State', 'fmt.Stringer',
+ 'git85.CorruptInputError', 'gob.Decoder', 'gob.Encoder', 'gosym.DecodingError',
+ 'gosym.Func', 'gosym.LineTable', 'gosym.Obj', 'gosym.Sym', 'gosym.Table',
+ 'gosym.UnknownFileError', 'gosym.UnknownLineError', 'gzip.Deflater',
+ 'gzip.Header', 'gzip.Inflater', 'hash.Hash', 'hash.Hash32', 'hash.Hash64',
+ 'heap.Interface', 'hex.InvalidHexCharError', 'hex.OddLengthInputError',
+ 'http.ClientConn', 'http.Conn', 'http.Handler', 'http.HandlerFunc',
+ 'http.ProtocolError', 'http.Request', 'http.Response', 'http.ServeMux',
+ 'http.ServerConn', 'http.URL', 'http.URLError', 'http.URLEscapeError',
+ 'image.Alpha', 'image.AlphaColor', 'image.Color', 'image.ColorImage',
+ 'image.ColorModel', 'image.ColorModelFunc', 'image.Image', 'image.NRGBA',
+ 'image.NRGBA64', 'image.NRGBA64Color', 'image.NRGBAColor', 'image.Paletted',
+ 'image.RGBA', 'image.RGBA64', 'image.RGBA64Color', 'image.RGBAColor',
+ 'io.Closer', 'io.Error', 'io.PipeReader', 'io.PipeWriter', 'io.ReadByter',
+ 'io.ReadCloser', 'io.ReadSeeker', 'io.ReadWriteCloser', 'io.ReadWriteSeeker',
+ 'io.ReadWriter', 'io.Reader', 'io.ReaderAt', 'io.ReaderFrom', 'io.SectionReader',
+ 'io.Seeker', 'io.WriteCloser', 'io.WriteSeeker', 'io.Writer', 'io.WriterAt',
+ 'io.WriterTo', 'iterable.Func', 'iterable.Group', 'iterable.Grouper',
+ 'iterable.Injector', 'iterable.Iterable', 'jpeg.FormatError', 'jpeg.Reader',
+ 'jpeg.UnsupportedError', 'json.Decoder', 'json.Encoder',
+ 'json.InvalidUnmarshalError', 'json.Marshaler', 'json.MarshalerError',
+ 'json.SyntaxError', 'json.UnmarshalTypeError', 'json.Unmarshaler',
+ 'json.UnsupportedTypeError', 'list.Element', 'list.List', 'log.Logger',
+ 'macho.Cpu', 'macho.File', 'macho.FileHeader', 'macho.FormatError', 'macho.Load',
+ 'macho.LoadCmd', 'macho.Regs386', 'macho.RegsAMD64', 'macho.Section',
+ 'macho.Section32', 'macho.Section64', 'macho.SectionHeader', 'macho.Segment',
+ 'macho.Segment32', 'macho.Segment64', 'macho.SegmentHeader', 'macho.Thread',
+ 'macho.Type', 'net.Addr', 'net.AddrError', 'net.Conn', 'net.DNSConfigError',
+ 'net.DNSError', 'net.Error', 'net.InvalidAddrError', 'net.InvalidConnError',
+ 'net.Listener', 'net.OpError', 'net.PacketConn', 'net.TCPAddr', 'net.TCPConn',
+ 'net.TCPListener', 'net.UDPAddr', 'net.UDPConn', 'net.UnixAddr', 'net.UnixConn',
+ 'net.UnixListener', 'net.UnknownNetworkError', 'net.UnknownSocketError',
+ 'netchan.Dir', 'netchan.Exporter', 'netchan.Importer', 'nntp.Article',
+ 'nntp.Conn', 'nntp.Error', 'nntp.Group', 'nntp.ProtocolError', 'ogle.Arch',
+ 'ogle.ArchAlignedMultiple', 'ogle.ArchLSB', 'ogle.Breakpoint', 'ogle.Event',
+ 'ogle.EventAction', 'ogle.EventHandler', 'ogle.EventHook', 'ogle.FormatError',
+ 'ogle.Frame', 'ogle.Goroutine', 'ogle.GoroutineCreate', 'ogle.GoroutineExit',
+ 'ogle.NoCurrentGoroutine', 'ogle.NotOnStack', 'ogle.Process',
+ 'ogle.ProcessNotStopped', 'ogle.ReadOnlyError', 'ogle.RemoteMismatchError',
+ 'ogle.UnknownArchitecture', 'ogle.UnknownGoroutine', 'ogle.UsageError',
+ 'os.Errno', 'os.Error', 'os.ErrorString', 'os.File', 'os.FileInfo',
+ 'os.LinkError', 'os.PathError', 'os.SyscallError', 'os.Waitmsg', 'patch.Diff',
+ 'patch.File', 'patch.GitBinaryLiteral', 'patch.Op', 'patch.Set',
+ 'patch.SyntaxError', 'patch.TextChunk', 'patch.Verb', 'path.Visitor',
+ 'pdp1.HaltError', 'pdp1.LoopError', 'pdp1.Trapper', 'pdp1.UnknownInstrError',
+ 'pdp1.Word', 'pem.Block', 'png.FormatError', 'png.IDATDecodingError',
+ 'png.UnsupportedError', 'printer.Config', 'printer.HTMLTag', 'printer.Styler',
+ 'proc.Breakpoint', 'proc.Cause', 'proc.Process', 'proc.ProcessExited',
+ 'proc.Regs', 'proc.Signal', 'proc.Stopped', 'proc.Thread', 'proc.ThreadCreate',
+ 'proc.ThreadExit', 'proc.Word', 'quick.CheckEqualError', 'quick.CheckError',
+ 'quick.Config', 'quick.Generator', 'quick.SetupError', 'rand.Rand',
+ 'rand.Source', 'rand.Zipf', 'rc4.Cipher', 'rc4.KeySizeError',
+ 'reflect.ArrayOrSliceType', 'reflect.ArrayOrSliceValue', 'reflect.ArrayType',
+ 'reflect.ArrayValue', 'reflect.BoolType', 'reflect.BoolValue', 'reflect.ChanDir',
+ 'reflect.ChanType', 'reflect.ChanValue', 'reflect.Complex128Type',
+ 'reflect.Complex128Value', 'reflect.Complex64Type', 'reflect.Complex64Value',
+ 'reflect.ComplexType', 'reflect.ComplexValue', 'reflect.Float32Type',
+ 'reflect.Float32Value', 'reflect.Float64Type', 'reflect.Float64Value',
+ 'reflect.FloatType', 'reflect.FloatValue', 'reflect.FuncType',
+ 'reflect.FuncValue', 'reflect.Int16Type', 'reflect.Int16Value',
+ 'reflect.Int32Type', 'reflect.Int32Value', 'reflect.Int64Type',
+ 'reflect.Int64Value', 'reflect.Int8Type', 'reflect.Int8Value', 'reflect.IntType',
+ 'reflect.IntValue', 'reflect.InterfaceType', 'reflect.InterfaceValue',
+ 'reflect.MapType', 'reflect.MapValue', 'reflect.Method', 'reflect.PtrType',
+ 'reflect.PtrValue', 'reflect.SliceHeader', 'reflect.SliceType',
+ 'reflect.SliceValue', 'reflect.StringHeader', 'reflect.StringType',
+ 'reflect.StringValue', 'reflect.StructField', 'reflect.StructType',
+ 'reflect.StructValue', 'reflect.Type', 'reflect.Uint16Type',
+ 'reflect.Uint16Value', 'reflect.Uint32Type', 'reflect.Uint32Value',
+ 'reflect.Uint64Type', 'reflect.Uint64Value', 'reflect.Uint8Type',
+ 'reflect.Uint8Value', 'reflect.UintType', 'reflect.UintValue',
+ 'reflect.UintptrType', 'reflect.UintptrValue', 'reflect.UnsafePointerType',
+ 'reflect.UnsafePointerValue', 'reflect.Value', 'regexp.Error', 'regexp.Regexp',
+ 'ring.Ring', 'rpc.Call', 'rpc.Client', 'rpc.ClientCodec', 'rpc.InvalidRequest',
+ 'rpc.Request', 'rpc.Response', 'rpc.ServerCodec', 'rsa.DecryptionError',
+ 'rsa.MessageTooLongError', 'rsa.PKCS1v15Hash', 'rsa.PrivateKey', 'rsa.PublicKey',
+ 'rsa.VerificationError', 'runtime.ArrayType', 'runtime.BoolType',
+ 'runtime.ChanDir', 'runtime.ChanType', 'runtime.Complex128Type',
+ 'runtime.Complex64Type', 'runtime.ComplexType', 'runtime.Error',
+ 'runtime.Float32Type', 'runtime.Float64Type', 'runtime.FloatType',
+ 'runtime.Func', 'runtime.FuncType', 'runtime.Int16Type', 'runtime.Int32Type',
+ 'runtime.Int64Type', 'runtime.Int8Type', 'runtime.IntType',
+ 'runtime.InterfaceType', 'runtime.Itable', 'runtime.MapType',
+ 'runtime.MemProfileRecord', 'runtime.MemStatsType', 'runtime.PtrType',
+ 'runtime.SliceType', 'runtime.StringType', 'runtime.StructType', 'runtime.Type',
+ 'runtime.TypeAssertionError', 'runtime.Uint16Type', 'runtime.Uint32Type',
+ 'runtime.Uint64Type', 'runtime.Uint8Type', 'runtime.UintType',
+ 'runtime.UintptrType', 'runtime.UnsafePointerType', 'scanner.Error',
+ 'scanner.ErrorHandler', 'scanner.ErrorVector', 'scanner.Position',
+ 'scanner.Scanner', 'script.Close', 'script.Closed', 'script.Event',
+ 'script.ReceivedUnexpected', 'script.Recv', 'script.RecvMatch', 'script.Send',
+ 'script.SetupError', 'signal.Signal', 'signal.UnixSignal', 'sort.Interface',
+ 'srpc.Client', 'srpc.Errno', 'srpc.Handler', 'srpc.RPC', 'strconv.NumError',
+ 'strings.Reader', 'sync.Mutex', 'sync.RWMutex',
+ 'syscall.ByHandleFileInformation', 'syscall.Cmsghdr', 'syscall.Dirent',
+ 'syscall.EpollEvent', 'syscall.Fbootstraptransfer_t', 'syscall.FdSet',
+ 'syscall.Filetime', 'syscall.Flock_t', 'syscall.Fstore_t', 'syscall.Iovec',
+ 'syscall.Kevent_t', 'syscall.Linger', 'syscall.Log2phys_t', 'syscall.Msghdr',
+ 'syscall.Overlapped', 'syscall.PtraceRegs', 'syscall.Radvisory_t',
+ 'syscall.RawSockaddr', 'syscall.RawSockaddrAny', 'syscall.RawSockaddrInet4',
+ 'syscall.RawSockaddrInet6', 'syscall.RawSockaddrUnix', 'syscall.Rlimit',
+ 'syscall.Rusage', 'syscall.Sockaddr', 'syscall.SockaddrInet4',
+ 'syscall.SockaddrInet6', 'syscall.SockaddrUnix', 'syscall.Stat_t',
+ 'syscall.Statfs_t', 'syscall.Sysinfo_t', 'syscall.Time_t', 'syscall.Timespec',
+ 'syscall.Timeval', 'syscall.Timex', 'syscall.Tms', 'syscall.Ustat_t',
+ 'syscall.Utimbuf', 'syscall.Utsname', 'syscall.WaitStatus',
+ 'syscall.Win32finddata', 'syslog.Priority', 'syslog.Writer', 'tabwriter.Writer',
+ 'tar.Header', 'tar.Reader', 'tar.Writer', 'template.Error',
+ 'template.FormatterMap', 'template.Template', 'testing.Benchmark',
+ 'testing.Regexp', 'testing.Test', 'time.ParseError', 'time.Ticker', 'time.Time',
+ 'tls.CASet', 'tls.Certificate', 'tls.Config', 'tls.Conn', 'tls.ConnectionState',
+ 'tls.Listener', 'token.Position', 'token.Token', 'unicode.CaseRange',
+ 'unicode.Range', 'unsafe.ArbitraryType', 'vector.LessInterface',
+ 'websocket.Conn', 'websocket.Draft75Handler', 'websocket.Handler',
+ 'websocket.ProtocolError', 'websocket.WebSocketAddr', 'x509.Certificate',
+ 'x509.ConstraintViolationError', 'x509.KeyUsage', 'x509.Name',
+ 'x509.PublicKeyAlgorithm', 'x509.SignatureAlgorithm',
+ 'x509.UnhandledCriticalExtension', 'x509.UnsupportedAlgorithmError', 'xml.Attr',
+ 'xml.EndElement', 'xml.Name', 'xml.Parser', 'xml.ProcInst', 'xml.StartElement',
+ 'xml.SyntaxError', 'xml.Token', 'xml.UnmarshalError', 'xtea.Cipher',
+ 'xtea.KeySizeError'
+ )
+ ),
+ 'SYMBOLS' => array(
+ # delimiters
+ 1 => array(
+ '(', ')', '{', '}', '[', ']', ',', ':', ';'
+ ),
+ # assignments
+ 2 => array(
+ '<<=', '!=', '%=', '&=', '&^=', '*=', '+=', '-=', '/=', ':=', '>>=',
+ '^=', '|=', '=', '++', '--'
+ ),
+ # operators
+ 3 => array(
+ '<=', '<', '==', '>', '>=', '&&', '!', '||', '&', '&^', '|', '^',
+ '>>', '<<', '*', '%', '+', '-', '.', '/', '<-'),
+ # vararg
+ 4 => array(
+ '...'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ # statements
+ 1 => 'color: #b1b100; font-weight: bold;',
+ # literals
+ 2 => 'color: #000000; font-weight: bold;',
+ # built-in functions
+ 3 => 'color: #000066;',
+ # built-in types
+ 4 => 'color: #993333;',
+ # library types
+ 5 => 'color: #003399;'
+ ),
+ 'COMMENTS' => array(
+ # single-line comments
+ 1 => 'color: #666666; font-style: italic;',
+ # raw strings
+ 2 => 'color: #0000ff;',
+ # multi-line comments
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ # simple escape
+ 1 => 'color: #000099; font-weight: bold;',
+ # octal escape
+ 2 => 'color: #000099;',
+ # hex escape
+ 3 => 'color: #000099;',
+ # unicode escape
+ 4 => 'color: #000099;',
+ # long unicode escape
+ 5 => 'color: #000099;'
+ ),
+ 'BRACKETS' => array(
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;',
+ 0 => 'color: #cc66cc;' // FIXME: Duplicate array key
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ # delimiters
+ 1 => 'color: #339933;',
+ # assignments
+ 2 => 'color: #339933;',
+ # operators
+ 3 => 'color: #339933;',
+ # vararg (highlighted as a keyword)
+ 4 => 'color: #000000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ # If CSS classes are enabled, these would be highlighted as numbers (nu0)
+ # integer literals (possibly imaginary)
+ //0 => 'color: #cc66cc;',
+ # real floating point literals
+ //1 => 'color: #cc66cc;',
+ # imaginary floating point literals
+ //2 => 'color: #cc66cc;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => 'http://golang.org/search?q={FNAME}'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(1 => '.'),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER, # handled by symbols
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/groovy.php b/platform/www/vendor/geshi/geshi/src/geshi/groovy.php
new file mode 100644
index 0000000..f8a228e
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/groovy.php
@@ -0,0 +1,1009 @@
+<?php
+/*************************************************************************************
+ * groovy.php
+ * ----------
+ * Author: Ivan F. Villanueva B. (geshi_groovy@artificialidea.com)
+ * Copyright: (c) 2006 Ivan F. Villanueva B.(http://www.artificialidea.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/04/29
+ *
+ * Groovy language file for GeSHi.
+ *
+ * Keywords from http: http://docs.codehaus.org/download/attachments/2715/groovy-reference-card.pdf?version=1
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2006/04/29 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2006/04/29)
+ * -------------------------
+ * Testing
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Groovy',
+ 'COMMENT_SINGLE' => array(1 => '//', 3 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Import and Package directives (Basic Support only)
+ 2 => '/(?:(?<=import[\\n\\s])|(?<=package[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*([a-zA-Z0-9_]+|\*)(?=[\n\s;])/i',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'''", '"""', "'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'case', 'do', 'else', 'for', 'foreach', 'if', 'in', 'switch',
+ 'while',
+ ),
+ 2 => array(
+ 'abstract', 'as', 'assert', 'break', 'catch', 'class', 'const',
+ 'continue', 'def', 'default', 'enum', 'extends',
+ 'false', 'final', 'finally', 'goto', 'implements', 'import',
+ 'instanceof', 'interface', 'native', 'new', 'null',
+ 'package', 'private', 'property', 'protected',
+ 'public', 'return', 'static', 'strictfp', 'super',
+ 'synchronized', 'this', 'throw', 'throws',
+ 'transient', 'true', 'try', 'volatile'
+ ),
+ 3 => array(
+ 'AbstractAction', 'AbstractBorder', 'AbstractButton',
+ 'AbstractCellEditor', 'AbstractCollection',
+ 'AbstractColorChooserPanel', 'AbstractDocument',
+ 'AbstractDocument.AttributeContext',
+ 'AbstractDocument.Content',
+ 'AbstractDocument.ElementEdit',
+ 'AbstractLayoutCache',
+ 'AbstractLayoutCache.NodeDimensions', 'AbstractList',
+ 'AbstractListModel', 'AbstractMap',
+ 'AbstractMethodError', 'AbstractSequentialList',
+ 'AbstractSet', 'AbstractTableModel',
+ 'AbstractUndoableEdit', 'AbstractWriter',
+ 'AccessControlContext', 'AccessControlException',
+ 'AccessController', 'AccessException', 'Accessible',
+ 'AccessibleAction', 'AccessibleBundle',
+ 'AccessibleComponent', 'AccessibleContext',
+ 'AccessibleHyperlink', 'AccessibleHypertext',
+ 'AccessibleIcon', 'AccessibleObject',
+ 'AccessibleRelation', 'AccessibleRelationSet',
+ 'AccessibleResourceBundle', 'AccessibleRole',
+ 'AccessibleSelection', 'AccessibleState',
+ 'AccessibleStateSet', 'AccessibleTable',
+ 'AccessibleTableModelChange', 'AccessibleText',
+ 'AccessibleValue', 'Acl', 'AclEntry',
+ 'AclNotFoundException', 'Action', 'ActionEvent',
+ 'ActionListener', 'ActionMap', 'ActionMapUIResource',
+ 'Activatable', 'ActivateFailedException',
+ 'ActivationDesc', 'ActivationException',
+ 'ActivationGroup', 'ActivationGroupDesc',
+ 'ActivationGroupDesc.CommandEnvironment',
+ 'ActivationGroupID', 'ActivationID',
+ 'ActivationInstantiator', 'ActivationMonitor',
+ 'ActivationSystem', 'Activator', 'ActiveEvent',
+ 'Adjustable', 'AdjustmentEvent',
+ 'AdjustmentListener', 'Adler32', 'AffineTransform',
+ 'AffineTransformOp', 'AlgorithmParameterGenerator',
+ 'AlgorithmParameterGeneratorSpi',
+ 'AlgorithmParameters', 'AlgorithmParameterSpec',
+ 'AlgorithmParametersSpi', 'AllPermission',
+ 'AlphaComposite', 'AlreadyBound',
+ 'AlreadyBoundException', 'AlreadyBoundHelper',
+ 'AlreadyBoundHolder', 'AncestorEvent',
+ 'AncestorListener', 'Annotation', 'Any', 'AnyHolder',
+ 'AnySeqHelper', 'AnySeqHolder', 'Applet',
+ 'AppletContext', 'AppletInitializer', 'AppletStub',
+ 'ApplicationException', 'Arc2D', 'Arc2D.Double',
+ 'Arc2D.Float', 'Area', 'AreaAveragingScaleFilter',
+ 'ARG_IN', 'ARG_INOUT', 'ARG_OUT',
+ 'ArithmeticException', 'Array',
+ 'ArrayIndexOutOfBoundsException', 'ArrayList',
+ 'Arrays', 'ArrayStoreException', 'AsyncBoxView',
+ 'Attribute', 'AttributedCharacterIterator',
+ 'AttributedCharacterIterator.Attribute',
+ 'AttributedString', 'AttributeInUseException',
+ 'AttributeList', 'AttributeModificationException',
+ 'Attributes', 'Attributes.Name', 'AttributeSet',
+ 'AttributeSet.CharacterAttribute',
+ 'AttributeSet.ColorAttribute',
+ 'AttributeSet.FontAttribute',
+ 'AttributeSet.ParagraphAttribute', 'AudioClip',
+ 'AudioFileFormat', 'AudioFileFormat.Type',
+ 'AudioFileReader', 'AudioFileWriter', 'AudioFormat',
+ 'AudioFormat.Encoding', 'AudioInputStream',
+ 'AudioPermission', 'AudioSystem',
+ 'AuthenticationException',
+ 'AuthenticationNotSupportedException',
+ 'Authenticator', 'Autoscroll', 'AWTError',
+ 'AWTEvent', 'AWTEventListener',
+ 'AWTEventMulticaster', 'AWTException',
+ 'AWTPermission', 'BadKind', 'BadLocationException',
+ 'BAD_CONTEXT', 'BAD_INV_ORDER', 'BAD_OPERATION',
+ 'BAD_PARAM', 'BAD_POLICY', 'BAD_POLICY_TYPE',
+ 'BAD_POLICY_VALUE', 'BAD_TYPECODE', 'BandCombineOp',
+ 'BandedSampleModel', 'BasicArrowButton',
+ 'BasicAttribute', 'BasicAttributes', 'BasicBorders',
+ 'BasicBorders.ButtonBorder',
+ 'BasicBorders.FieldBorder',
+ 'BasicBorders.MarginBorder',
+ 'BasicBorders.MenuBarBorder',
+ 'BasicBorders.RadioButtonBorder',
+ 'BasicBorders.SplitPaneBorder',
+ 'BasicBorders.ToggleButtonBorder',
+ 'BasicButtonListener', 'BasicButtonUI',
+ 'BasicCheckBoxMenuItemUI', 'BasicCheckBoxUI',
+ 'BasicColorChooserUI', 'BasicComboBoxEditor',
+ 'BasicComboBoxEditor.UIResource',
+ 'BasicComboBoxRenderer',
+ 'BasicComboBoxRenderer.UIResource',
+ 'BasicComboBoxUI', 'BasicComboPopup',
+ 'BasicDesktopIconUI', 'BasicDesktopPaneUI',
+ 'BasicDirectoryModel', 'BasicEditorPaneUI',
+ 'BasicFileChooserUI', 'BasicGraphicsUtils',
+ 'BasicHTML', 'BasicIconFactory',
+ 'BasicInternalFrameTitlePane',
+ 'BasicInternalFrameUI', 'BasicLabelUI',
+ 'BasicListUI', 'BasicLookAndFeel', 'BasicMenuBarUI',
+ 'BasicMenuItemUI', 'BasicMenuUI',
+ 'BasicOptionPaneUI',
+ 'BasicOptionPaneUI.ButtonAreaLayout', 'BasicPanelUI',
+ 'BasicPasswordFieldUI', 'BasicPermission',
+ 'BasicPopupMenuSeparatorUI', 'BasicPopupMenuUI',
+ 'BasicProgressBarUI', 'BasicRadioButtonMenuItemUI',
+ 'BasicRadioButtonUI', 'BasicRootPaneUI',
+ 'BasicScrollBarUI', 'BasicScrollPaneUI',
+ 'BasicSeparatorUI', 'BasicSliderUI',
+ 'BasicSplitPaneDivider', 'BasicSplitPaneUI',
+ 'BasicStroke', 'BasicTabbedPaneUI',
+ 'BasicTableHeaderUI', 'BasicTableUI',
+ 'BasicTextAreaUI', 'BasicTextFieldUI',
+ 'BasicTextPaneUI', 'BasicTextUI',
+ 'BasicTextUI.BasicCaret',
+ 'BasicTextUI.BasicHighlighter',
+ 'BasicToggleButtonUI', 'BasicToolBarSeparatorUI',
+ 'BasicToolBarUI', 'BasicToolTipUI', 'BasicTreeUI',
+ 'BasicViewportUI', 'BatchUpdateException',
+ 'BeanContext', 'BeanContextChild',
+ 'BeanContextChildComponentProxy',
+ 'BeanContextChildSupport',
+ 'BeanContextContainerProxy', 'BeanContextEvent',
+ 'BeanContextMembershipEvent',
+ 'BeanContextMembershipListener', 'BeanContextProxy',
+ 'BeanContextServiceAvailableEvent',
+ 'BeanContextServiceProvider',
+ 'BeanContextServiceProviderBeanInfo',
+ 'BeanContextServiceRevokedEvent',
+ 'BeanContextServiceRevokedListener',
+ 'BeanContextServices', 'BeanContextServicesListener',
+ 'BeanContextServicesSupport',
+ 'BeanContextServicesSupport.BCSSServiceProvider',
+ 'BeanContextSupport',
+ 'BeanContextSupport.BCSIterator', 'BeanDescriptor',
+ 'BeanInfo', 'Beans', 'BevelBorder', 'BigDecimal',
+ 'BigInteger', 'BinaryRefAddr', 'BindException',
+ 'Binding', 'BindingHelper', 'BindingHolder',
+ 'BindingIterator', 'BindingIteratorHelper',
+ 'BindingIteratorHolder', 'BindingIteratorOperations',
+ 'BindingListHelper', 'BindingListHolder',
+ 'BindingType', 'BindingTypeHelper',
+ 'BindingTypeHolder', 'BitSet', 'Blob', 'BlockView',
+ 'Book', 'Boolean', 'BooleanControl',
+ 'BooleanControl.Type', 'BooleanHolder',
+ 'BooleanSeqHelper', 'BooleanSeqHolder', 'Border',
+ 'BorderFactory', 'BorderLayout', 'BorderUIResource',
+ 'BorderUIResource.BevelBorderUIResource',
+ 'BorderUIResource.CompoundBorderUIResource',
+ 'BorderUIResource.EmptyBorderUIResource',
+ 'BorderUIResource.EtchedBorderUIResource',
+ 'BorderUIResource.LineBorderUIResource',
+ 'BorderUIResource.MatteBorderUIResource',
+ 'BorderUIResource.TitledBorderUIResource',
+ 'BoundedRangeModel', 'Bounds', 'Box', 'Box.Filler',
+ 'BoxedValueHelper', 'BoxLayout', 'BoxView',
+ 'BreakIterator', 'BufferedImage',
+ 'BufferedImageFilter', 'BufferedImageOp',
+ 'BufferedInputStream', 'BufferedOutputStream',
+ 'BufferedReader', 'BufferedWriter', 'Button',
+ 'ButtonGroup', 'ButtonModel', 'ButtonUI', 'Byte',
+ 'ByteArrayInputStream', 'ByteArrayOutputStream',
+ 'ByteHolder', 'ByteLookupTable', 'Calendar',
+ 'CallableStatement', 'CannotProceed',
+ 'CannotProceedException', 'CannotProceedHelper',
+ 'CannotProceedHolder', 'CannotRedoException',
+ 'CannotUndoException', 'Canvas', 'CardLayout',
+ 'Caret', 'CaretEvent', 'CaretListener', 'CellEditor',
+ 'CellEditorListener', 'CellRendererPane',
+ 'Certificate', 'Certificate.CertificateRep',
+ 'CertificateEncodingException',
+ 'CertificateException',
+ 'CertificateExpiredException', 'CertificateFactory',
+ 'CertificateFactorySpi',
+ 'CertificateNotYetValidException',
+ 'CertificateParsingException',
+ 'ChangedCharSetException', 'ChangeEvent',
+ 'ChangeListener', 'Character', 'Character.Subset',
+ 'Character.UnicodeBlock', 'CharacterIterator',
+ 'CharArrayReader', 'CharArrayWriter',
+ 'CharConversionException', 'CharHolder',
+ 'CharSeqHelper', 'CharSeqHolder', 'Checkbox',
+ 'CheckboxGroup', 'CheckboxMenuItem',
+ 'CheckedInputStream', 'CheckedOutputStream',
+ 'Checksum', 'Choice', 'ChoiceFormat', 'Class',
+ 'ClassCastException', 'ClassCircularityError',
+ 'ClassDesc', 'ClassFormatError', 'ClassLoader',
+ 'ClassNotFoundException', 'Clip', 'Clipboard',
+ 'ClipboardOwner', 'Clob', 'Cloneable',
+ 'CloneNotSupportedException', 'CMMException',
+ 'CodeSource', 'CollationElementIterator',
+ 'CollationKey', 'Collator', 'Collection',
+ 'Collections', 'Color',
+ 'ColorChooserComponentFactory', 'ColorChooserUI',
+ 'ColorConvertOp', 'ColorModel',
+ 'ColorSelectionModel', 'ColorSpace',
+ 'ColorUIResource', 'ComboBoxEditor', 'ComboBoxModel',
+ 'ComboBoxUI', 'ComboPopup', 'CommunicationException',
+ 'COMM_FAILURE', 'Comparable', 'Comparator',
+ 'Compiler', 'CompletionStatus',
+ 'CompletionStatusHelper', 'Component',
+ 'ComponentAdapter', 'ComponentColorModel',
+ 'ComponentEvent', 'ComponentInputMap',
+ 'ComponentInputMapUIResource', 'ComponentListener',
+ 'ComponentOrientation', 'ComponentSampleModel',
+ 'ComponentUI', 'ComponentView', 'Composite',
+ 'CompositeContext', 'CompositeName', 'CompositeView',
+ 'CompoundBorder', 'CompoundControl',
+ 'CompoundControl.Type', 'CompoundEdit',
+ 'CompoundName', 'ConcurrentModificationException',
+ 'ConfigurationException', 'ConnectException',
+ 'ConnectIOException', 'Connection', 'Constructor',
+ 'Container', 'ContainerAdapter', 'ContainerEvent',
+ 'ContainerListener', 'ContentHandler',
+ 'ContentHandlerFactory', 'ContentModel', 'Context',
+ 'ContextList', 'ContextNotEmptyException',
+ 'ContextualRenderedImageFactory', 'Control',
+ 'Control.Type', 'ControlFactory',
+ 'ControllerEventListener', 'ConvolveOp', 'CRC32',
+ 'CRL', 'CRLException', 'CropImageFilter', 'CSS',
+ 'CSS.Attribute', 'CTX_RESTRICT_SCOPE',
+ 'CubicCurve2D', 'CubicCurve2D.Double',
+ 'CubicCurve2D.Float', 'Current', 'CurrentHelper',
+ 'CurrentHolder', 'CurrentOperations', 'Cursor',
+ 'Customizer', 'CustomMarshal', 'CustomValue',
+ 'DatabaseMetaData', 'DataBuffer', 'DataBufferByte',
+ 'DataBufferInt', 'DataBufferShort',
+ 'DataBufferUShort', 'DataFlavor',
+ 'DataFormatException', 'DatagramPacket',
+ 'DatagramSocket', 'DatagramSocketImpl',
+ 'DatagramSocketImplFactory', 'DataInput',
+ 'DataInputStream', 'DataLine', 'DataLine.Info',
+ 'DataOutput', 'DataOutputStream', 'DataTruncation',
+ 'DATA_CONVERSION', 'Date', 'DateFormat',
+ 'DateFormatSymbols', 'DebugGraphics',
+ 'DecimalFormat', 'DecimalFormatSymbols',
+ 'DefaultBoundedRangeModel', 'DefaultButtonModel',
+ 'DefaultCaret', 'DefaultCellEditor',
+ 'DefaultColorSelectionModel', 'DefaultComboBoxModel',
+ 'DefaultDesktopManager', 'DefaultEditorKit',
+ 'DefaultEditorKit.BeepAction',
+ 'DefaultEditorKit.CopyAction',
+ 'DefaultEditorKit.CutAction',
+ 'DefaultEditorKit.DefaultKeyTypedAction',
+ 'DefaultEditorKit.InsertBreakAction',
+ 'DefaultEditorKit.InsertContentAction',
+ 'DefaultEditorKit.InsertTabAction',
+ 'DefaultEditorKit.PasteAction,',
+ 'DefaultFocusManager', 'DefaultHighlighter',
+ 'DefaultHighlighter.DefaultHighlightPainter',
+ 'DefaultListCellRenderer',
+ 'DefaultListCellRenderer.UIResource',
+ 'DefaultListModel', 'DefaultListSelectionModel',
+ 'DefaultMenuLayout', 'DefaultMetalTheme',
+ 'DefaultMutableTreeNode',
+ 'DefaultSingleSelectionModel',
+ 'DefaultStyledDocument',
+ 'DefaultStyledDocument.AttributeUndoableEdit',
+ 'DefaultStyledDocument.ElementSpec',
+ 'DefaultTableCellRenderer',
+ 'DefaultTableCellRenderer.UIResource',
+ 'DefaultTableColumnModel', 'DefaultTableModel',
+ 'DefaultTextUI', 'DefaultTreeCellEditor',
+ 'DefaultTreeCellRenderer', 'DefaultTreeModel',
+ 'DefaultTreeSelectionModel', 'DefinitionKind',
+ 'DefinitionKindHelper', 'Deflater',
+ 'DeflaterOutputStream', 'Delegate', 'DesignMode',
+ 'DesktopIconUI', 'DesktopManager', 'DesktopPaneUI',
+ 'DGC', 'Dialog', 'Dictionary', 'DigestException',
+ 'DigestInputStream', 'DigestOutputStream',
+ 'Dimension', 'Dimension2D', 'DimensionUIResource',
+ 'DirContext', 'DirectColorModel', 'DirectoryManager',
+ 'DirObjectFactory', 'DirStateFactory',
+ 'DirStateFactory.Result', 'DnDConstants', 'Document',
+ 'DocumentEvent', 'DocumentEvent.ElementChange',
+ 'DocumentEvent.EventType', 'DocumentListener',
+ 'DocumentParser', 'DomainCombiner', 'DomainManager',
+ 'DomainManagerOperations', 'Double', 'DoubleHolder',
+ 'DoubleSeqHelper', 'DoubleSeqHolder',
+ 'DragGestureEvent', 'DragGestureListener',
+ 'DragGestureRecognizer', 'DragSource',
+ 'DragSourceContext', 'DragSourceDragEvent',
+ 'DragSourceDropEvent', 'DragSourceEvent',
+ 'DragSourceListener', 'Driver', 'DriverManager',
+ 'DriverPropertyInfo', 'DropTarget',
+ 'DropTarget.DropTargetAutoScroller',
+ 'DropTargetContext', 'DropTargetDragEvent',
+ 'DropTargetDropEvent', 'DropTargetEvent',
+ 'DropTargetListener', 'DSAKey',
+ 'DSAKeyPairGenerator', 'DSAParameterSpec',
+ 'DSAParams', 'DSAPrivateKey', 'DSAPrivateKeySpec',
+ 'DSAPublicKey', 'DSAPublicKeySpec', 'DTD',
+ 'DTDConstants', 'DynamicImplementation', 'DynAny',
+ 'DynArray', 'DynEnum', 'DynFixed', 'DynSequence',
+ 'DynStruct', 'DynUnion', 'DynValue', 'EditorKit',
+ 'Element', 'ElementIterator', 'Ellipse2D',
+ 'Ellipse2D.Double', 'Ellipse2D.Float', 'EmptyBorder',
+ 'EmptyStackException', 'EncodedKeySpec', 'Entity',
+ 'EnumControl', 'EnumControl.Type', 'Enumeration',
+ 'Environment', 'EOFException', 'Error',
+ 'EtchedBorder', 'Event', 'EventContext',
+ 'EventDirContext', 'EventListener',
+ 'EventListenerList', 'EventObject', 'EventQueue',
+ 'EventSetDescriptor', 'Exception',
+ 'ExceptionInInitializerError', 'ExceptionList',
+ 'ExpandVetoException', 'ExportException',
+ 'ExtendedRequest', 'ExtendedResponse',
+ 'Externalizable', 'FeatureDescriptor', 'Field',
+ 'FieldNameHelper', 'FieldPosition', 'FieldView',
+ 'File', 'FileChooserUI', 'FileDescriptor',
+ 'FileDialog', 'FileFilter', 'FileInputStream',
+ 'FilenameFilter', 'FileNameMap',
+ 'FileNotFoundException', 'FileOutputStream',
+ 'FilePermission', 'FileReader', 'FileSystemView',
+ 'FileView', 'FileWriter', 'FilteredImageSource',
+ 'FilterInputStream', 'FilterOutputStream',
+ 'FilterReader', 'FilterWriter',
+ 'FixedHeightLayoutCache', 'FixedHolder',
+ 'FlatteningPathIterator', 'FlavorMap', 'Float',
+ 'FloatControl', 'FloatControl.Type', 'FloatHolder',
+ 'FloatSeqHelper', 'FloatSeqHolder', 'FlowLayout',
+ 'FlowView', 'FlowView.FlowStrategy', 'FocusAdapter',
+ 'FocusEvent', 'FocusListener', 'FocusManager',
+ 'Font', 'FontFormatException', 'FontMetrics',
+ 'FontRenderContext', 'FontUIResource', 'Format',
+ 'FormatConversionProvider', 'FormView', 'Frame',
+ 'FREE_MEM', 'GapContent', 'GeneralPath',
+ 'GeneralSecurityException', 'GlyphJustificationInfo',
+ 'GlyphMetrics', 'GlyphVector', 'GlyphView',
+ 'GlyphView.GlyphPainter', 'GradientPaint',
+ 'GraphicAttribute', 'Graphics', 'Graphics2D',
+ 'GraphicsConfigTemplate', 'GraphicsConfiguration',
+ 'GraphicsDevice', 'GraphicsEnvironment',
+ 'GrayFilter', 'GregorianCalendar',
+ 'GridBagConstraints', 'GridBagLayout', 'GridLayout',
+ 'Group', 'Guard', 'GuardedObject', 'GZIPInputStream',
+ 'GZIPOutputStream', 'HasControls', 'HashMap',
+ 'HashSet', 'Hashtable', 'HierarchyBoundsAdapter',
+ 'HierarchyBoundsListener', 'HierarchyEvent',
+ 'HierarchyListener', 'Highlighter',
+ 'Highlighter.Highlight',
+ 'Highlighter.HighlightPainter', 'HTML',
+ 'HTML.Attribute', 'HTML.Tag', 'HTML.UnknownTag',
+ 'HTMLDocument', 'HTMLDocument.Iterator',
+ 'HTMLEditorKit', 'HTMLEditorKit.HTMLFactory',
+ 'HTMLEditorKit.HTMLTextAction',
+ 'HTMLEditorKit.InsertHTMLTextAction',
+ 'HTMLEditorKit.LinkController',
+ 'HTMLEditorKit.Parser',
+ 'HTMLEditorKit.ParserCallback',
+ 'HTMLFrameHyperlinkEvent', 'HTMLWriter',
+ 'HttpURLConnection', 'HyperlinkEvent',
+ 'HyperlinkEvent.EventType', 'HyperlinkListener',
+ 'ICC_ColorSpace', 'ICC_Profile', 'ICC_ProfileGray',
+ 'ICC_ProfileRGB', 'Icon', 'IconUIResource',
+ 'IconView', 'IdentifierHelper', 'Identity',
+ 'IdentityScope', 'IDLEntity', 'IDLType',
+ 'IDLTypeHelper', 'IDLTypeOperations',
+ 'IllegalAccessError', 'IllegalAccessException',
+ 'IllegalArgumentException',
+ 'IllegalComponentStateException',
+ 'IllegalMonitorStateException',
+ 'IllegalPathStateException', 'IllegalStateException',
+ 'IllegalThreadStateException', 'Image',
+ 'ImageConsumer', 'ImageFilter',
+ 'ImageGraphicAttribute', 'ImageIcon',
+ 'ImageObserver', 'ImageProducer',
+ 'ImagingOpException', 'IMP_LIMIT',
+ 'IncompatibleClassChangeError',
+ 'InconsistentTypeCode', 'IndexColorModel',
+ 'IndexedPropertyDescriptor',
+ 'IndexOutOfBoundsException', 'IndirectionException',
+ 'InetAddress', 'Inflater', 'InflaterInputStream',
+ 'InheritableThreadLocal', 'InitialContext',
+ 'InitialContextFactory',
+ 'InitialContextFactoryBuilder', 'InitialDirContext',
+ 'INITIALIZE', 'Initializer', 'InitialLdapContext',
+ 'InlineView', 'InputContext', 'InputEvent',
+ 'InputMap', 'InputMapUIResource', 'InputMethod',
+ 'InputMethodContext', 'InputMethodDescriptor',
+ 'InputMethodEvent', 'InputMethodHighlight',
+ 'InputMethodListener', 'InputMethodRequests',
+ 'InputStream', 'InputStreamReader', 'InputSubset',
+ 'InputVerifier', 'Insets', 'InsetsUIResource',
+ 'InstantiationError', 'InstantiationException',
+ 'Instrument', 'InsufficientResourcesException',
+ 'Integer', 'INTERNAL', 'InternalError',
+ 'InternalFrameAdapter', 'InternalFrameEvent',
+ 'InternalFrameListener', 'InternalFrameUI',
+ 'InterruptedException', 'InterruptedIOException',
+ 'InterruptedNamingException', 'INTF_REPOS',
+ 'IntHolder', 'IntrospectionException',
+ 'Introspector', 'Invalid',
+ 'InvalidAlgorithmParameterException',
+ 'InvalidAttributeIdentifierException',
+ 'InvalidAttributesException',
+ 'InvalidAttributeValueException',
+ 'InvalidClassException',
+ 'InvalidDnDOperationException',
+ 'InvalidKeyException', 'InvalidKeySpecException',
+ 'InvalidMidiDataException', 'InvalidName',
+ 'InvalidNameException', 'InvalidNameHelper',
+ 'InvalidNameHolder', 'InvalidObjectException',
+ 'InvalidParameterException',
+ 'InvalidParameterSpecException',
+ 'InvalidSearchControlsException',
+ 'InvalidSearchFilterException', 'InvalidSeq',
+ 'InvalidTransactionException', 'InvalidValue',
+ 'INVALID_TRANSACTION', 'InvocationEvent',
+ 'InvocationHandler', 'InvocationTargetException',
+ 'InvokeHandler', 'INV_FLAG', 'INV_IDENT',
+ 'INV_OBJREF', 'INV_POLICY', 'IOException',
+ 'IRObject', 'IRObjectOperations', 'IstringHelper',
+ 'ItemEvent', 'ItemListener', 'ItemSelectable',
+ 'Iterator', 'JApplet', 'JarEntry', 'JarException',
+ 'JarFile', 'JarInputStream', 'JarOutputStream',
+ 'JarURLConnection', 'JButton', 'JCheckBox',
+ 'JCheckBoxMenuItem', 'JColorChooser', 'JComboBox',
+ 'JComboBox.KeySelectionManager', 'JComponent',
+ 'JDesktopPane', 'JDialog', 'JEditorPane',
+ 'JFileChooser', 'JFrame', 'JInternalFrame',
+ 'JInternalFrame.JDesktopIcon', 'JLabel',
+ 'JLayeredPane', 'JList', 'JMenu', 'JMenuBar',
+ 'JMenuItem', 'JobAttributes',
+ 'JobAttributes.DefaultSelectionType',
+ 'JobAttributes.DestinationType',
+ 'JobAttributes.DialogType',
+ 'JobAttributes.MultipleDocumentHandlingType',
+ 'JobAttributes.SidesType', 'JOptionPane', 'JPanel',
+ 'JPasswordField', 'JPopupMenu',
+ 'JPopupMenu.Separator', 'JProgressBar',
+ 'JRadioButton', 'JRadioButtonMenuItem', 'JRootPane',
+ 'JScrollBar', 'JScrollPane', 'JSeparator', 'JSlider',
+ 'JSplitPane', 'JTabbedPane', 'JTable',
+ 'JTableHeader', 'JTextArea', 'JTextComponent',
+ 'JTextComponent.KeyBinding', 'JTextField',
+ 'JTextPane', 'JToggleButton',
+ 'JToggleButton.ToggleButtonModel', 'JToolBar',
+ 'JToolBar.Separator', 'JToolTip', 'JTree',
+ 'JTree.DynamicUtilTreeNode',
+ 'JTree.EmptySelectionModel', 'JViewport', 'JWindow',
+ 'Kernel', 'Key', 'KeyAdapter', 'KeyEvent',
+ 'KeyException', 'KeyFactory', 'KeyFactorySpi',
+ 'KeyListener', 'KeyManagementException', 'Keymap',
+ 'KeyPair', 'KeyPairGenerator', 'KeyPairGeneratorSpi',
+ 'KeySpec', 'KeyStore', 'KeyStoreException',
+ 'KeyStoreSpi', 'KeyStroke', 'Label', 'LabelUI',
+ 'LabelView', 'LastOwnerException',
+ 'LayeredHighlighter',
+ 'LayeredHighlighter.LayerPainter', 'LayoutManager',
+ 'LayoutManager2', 'LayoutQueue', 'LdapContext',
+ 'LdapReferralException', 'Lease',
+ 'LimitExceededException', 'Line', 'Line.Info',
+ 'Line2D', 'Line2D.Double', 'Line2D.Float',
+ 'LineBorder', 'LineBreakMeasurer', 'LineEvent',
+ 'LineEvent.Type', 'LineListener', 'LineMetrics',
+ 'LineNumberInputStream', 'LineNumberReader',
+ 'LineUnavailableException', 'LinkageError',
+ 'LinkedList', 'LinkException', 'LinkLoopException',
+ 'LinkRef', 'List', 'ListCellRenderer',
+ 'ListDataEvent', 'ListDataListener', 'ListIterator',
+ 'ListModel', 'ListResourceBundle',
+ 'ListSelectionEvent', 'ListSelectionListener',
+ 'ListSelectionModel', 'ListUI', 'ListView',
+ 'LoaderHandler', 'Locale', 'LocateRegistry',
+ 'LogStream', 'Long', 'LongHolder',
+ 'LongLongSeqHelper', 'LongLongSeqHolder',
+ 'LongSeqHelper', 'LongSeqHolder', 'LookAndFeel',
+ 'LookupOp', 'LookupTable', 'MalformedLinkException',
+ 'MalformedURLException', 'Manifest', 'Map',
+ 'Map.Entry', 'MARSHAL', 'MarshalException',
+ 'MarshalledObject', 'Math', 'MatteBorder',
+ 'MediaTracker', 'Member', 'MemoryImageSource',
+ 'Menu', 'MenuBar', 'MenuBarUI', 'MenuComponent',
+ 'MenuContainer', 'MenuDragMouseEvent',
+ 'MenuDragMouseListener', 'MenuElement', 'MenuEvent',
+ 'MenuItem', 'MenuItemUI', 'MenuKeyEvent',
+ 'MenuKeyListener', 'MenuListener',
+ 'MenuSelectionManager', 'MenuShortcut',
+ 'MessageDigest', 'MessageDigestSpi', 'MessageFormat',
+ 'MetaEventListener', 'MetalBorders',
+ 'MetalBorders.ButtonBorder',
+ 'MetalBorders.Flush3DBorder',
+ 'MetalBorders.InternalFrameBorder',
+ 'MetalBorders.MenuBarBorder',
+ 'MetalBorders.MenuItemBorder',
+ 'MetalBorders.OptionDialogBorder',
+ 'MetalBorders.PaletteBorder',
+ 'MetalBorders.PopupMenuBorder',
+ 'MetalBorders.RolloverButtonBorder',
+ 'MetalBorders.ScrollPaneBorder',
+ 'MetalBorders.TableHeaderBorder',
+ 'MetalBorders.TextFieldBorder',
+ 'MetalBorders.ToggleButtonBorder',
+ 'MetalBorders.ToolBarBorder', 'MetalButtonUI',
+ 'MetalCheckBoxIcon', 'MetalCheckBoxUI',
+ 'MetalComboBoxButton', 'MetalComboBoxEditor',
+ 'MetalComboBoxEditor.UIResource',
+ 'MetalComboBoxIcon', 'MetalComboBoxUI',
+ 'MetalDesktopIconUI', 'MetalFileChooserUI',
+ 'MetalIconFactory', 'MetalIconFactory.FileIcon16',
+ 'MetalIconFactory.FolderIcon16',
+ 'MetalIconFactory.PaletteCloseIcon',
+ 'MetalIconFactory.TreeControlIcon',
+ 'MetalIconFactory.TreeFolderIcon',
+ 'MetalIconFactory.TreeLeafIcon',
+ 'MetalInternalFrameTitlePane',
+ 'MetalInternalFrameUI', 'MetalLabelUI',
+ 'MetalLookAndFeel', 'MetalPopupMenuSeparatorUI',
+ 'MetalProgressBarUI', 'MetalRadioButtonUI',
+ 'MetalScrollBarUI', 'MetalScrollButton',
+ 'MetalScrollPaneUI', 'MetalSeparatorUI',
+ 'MetalSliderUI', 'MetalSplitPaneUI',
+ 'MetalTabbedPaneUI', 'MetalTextFieldUI',
+ 'MetalTheme', 'MetalToggleButtonUI',
+ 'MetalToolBarUI', 'MetalToolTipUI', 'MetalTreeUI',
+ 'MetaMessage', 'Method', 'MethodDescriptor',
+ 'MidiChannel', 'MidiDevice', 'MidiDevice.Info',
+ 'MidiDeviceProvider', 'MidiEvent', 'MidiFileFormat',
+ 'MidiFileReader', 'MidiFileWriter', 'MidiMessage',
+ 'MidiSystem', 'MidiUnavailableException',
+ 'MimeTypeParseException', 'MinimalHTMLWriter',
+ 'MissingResourceException', 'Mixer', 'Mixer.Info',
+ 'MixerProvider', 'ModificationItem', 'Modifier',
+ 'MouseAdapter', 'MouseDragGestureRecognizer',
+ 'MouseEvent', 'MouseInputAdapter',
+ 'MouseInputListener', 'MouseListener',
+ 'MouseMotionAdapter', 'MouseMotionListener',
+ 'MultiButtonUI', 'MulticastSocket',
+ 'MultiColorChooserUI', 'MultiComboBoxUI',
+ 'MultiDesktopIconUI', 'MultiDesktopPaneUI',
+ 'MultiFileChooserUI', 'MultiInternalFrameUI',
+ 'MultiLabelUI', 'MultiListUI', 'MultiLookAndFeel',
+ 'MultiMenuBarUI', 'MultiMenuItemUI',
+ 'MultiOptionPaneUI', 'MultiPanelUI',
+ 'MultiPixelPackedSampleModel', 'MultipleMaster',
+ 'MultiPopupMenuUI', 'MultiProgressBarUI',
+ 'MultiScrollBarUI', 'MultiScrollPaneUI',
+ 'MultiSeparatorUI', 'MultiSliderUI',
+ 'MultiSplitPaneUI', 'MultiTabbedPaneUI',
+ 'MultiTableHeaderUI', 'MultiTableUI', 'MultiTextUI',
+ 'MultiToolBarUI', 'MultiToolTipUI', 'MultiTreeUI',
+ 'MultiViewportUI', 'MutableAttributeSet',
+ 'MutableComboBoxModel', 'MutableTreeNode', 'Name',
+ 'NameAlreadyBoundException', 'NameClassPair',
+ 'NameComponent', 'NameComponentHelper',
+ 'NameComponentHolder', 'NamedValue', 'NameHelper',
+ 'NameHolder', 'NameNotFoundException', 'NameParser',
+ 'NamespaceChangeListener', 'NameValuePair',
+ 'NameValuePairHelper', 'Naming', 'NamingContext',
+ 'NamingContextHelper', 'NamingContextHolder',
+ 'NamingContextOperations', 'NamingEnumeration',
+ 'NamingEvent', 'NamingException',
+ 'NamingExceptionEvent', 'NamingListener',
+ 'NamingManager', 'NamingSecurityException',
+ 'NegativeArraySizeException', 'NetPermission',
+ 'NoClassDefFoundError', 'NoInitialContextException',
+ 'NoninvertibleTransformException',
+ 'NoPermissionException', 'NoRouteToHostException',
+ 'NoSuchAlgorithmException',
+ 'NoSuchAttributeException', 'NoSuchElementException',
+ 'NoSuchFieldError', 'NoSuchFieldException',
+ 'NoSuchMethodError', 'NoSuchMethodException',
+ 'NoSuchObjectException', 'NoSuchProviderException',
+ 'NotActiveException', 'NotBoundException',
+ 'NotContextException', 'NotEmpty', 'NotEmptyHelper',
+ 'NotEmptyHolder', 'NotFound', 'NotFoundHelper',
+ 'NotFoundHolder', 'NotFoundReason',
+ 'NotFoundReasonHelper', 'NotFoundReasonHolder',
+ 'NotOwnerException', 'NotSerializableException',
+ 'NO_IMPLEMENT', 'NO_MEMORY', 'NO_PERMISSION',
+ 'NO_RESOURCES', 'NO_RESPONSE',
+ 'NullPointerException', 'Number', 'NumberFormat',
+ 'NumberFormatException', 'NVList', 'Object',
+ 'ObjectChangeListener', 'ObjectFactory',
+ 'ObjectFactoryBuilder', 'ObjectHelper',
+ 'ObjectHolder', 'ObjectImpl', 'ObjectInput',
+ 'ObjectInputStream', 'ObjectInputStream.GetField',
+ 'ObjectInputValidation', 'ObjectOutput',
+ 'ObjectOutputStream', 'ObjectOutputStream.PutField',
+ 'ObjectStreamClass', 'ObjectStreamConstants',
+ 'ObjectStreamException', 'ObjectStreamField',
+ 'ObjectView', 'OBJECT_NOT_EXIST', 'ObjID',
+ 'OBJ_ADAPTER', 'Observable', 'Observer',
+ 'OctetSeqHelper', 'OctetSeqHolder', 'OMGVMCID',
+ 'OpenType', 'Operation',
+ 'OperationNotSupportedException', 'Option',
+ 'OptionalDataException', 'OptionPaneUI', 'ORB',
+ 'OutOfMemoryError', 'OutputStream',
+ 'OutputStreamWriter', 'OverlayLayout', 'Owner',
+ 'Package', 'PackedColorModel', 'Pageable',
+ 'PageAttributes', 'PageAttributes.ColorType',
+ 'PageAttributes.MediaType',
+ 'PageAttributes.OrientationRequestedType',
+ 'PageAttributes.OriginType',
+ 'PageAttributes.PrintQualityType', 'PageFormat',
+ 'Paint', 'PaintContext', 'PaintEvent', 'Panel',
+ 'PanelUI', 'Paper', 'ParagraphView',
+ 'ParameterBlock', 'ParameterDescriptor',
+ 'ParseException', 'ParsePosition', 'Parser',
+ 'ParserDelegator', 'PartialResultException',
+ 'PasswordAuthentication', 'PasswordView', 'Patch',
+ 'PathIterator', 'Permission', 'PermissionCollection',
+ 'Permissions', 'PERSIST_STORE', 'PhantomReference',
+ 'PipedInputStream', 'PipedOutputStream',
+ 'PipedReader', 'PipedWriter', 'PixelGrabber',
+ 'PixelInterleavedSampleModel', 'PKCS8EncodedKeySpec',
+ 'PlainDocument', 'PlainView', 'Point', 'Point2D',
+ 'Point2D.Double', 'Point2D.Float', 'Policy',
+ 'PolicyError', 'PolicyHelper', 'PolicyHolder',
+ 'PolicyListHelper', 'PolicyListHolder',
+ 'PolicyOperations', 'PolicyTypeHelper', 'Polygon',
+ 'PopupMenu', 'PopupMenuEvent', 'PopupMenuListener',
+ 'PopupMenuUI', 'Port', 'Port.Info',
+ 'PortableRemoteObject',
+ 'PortableRemoteObjectDelegate', 'Position',
+ 'Position.Bias', 'PreparedStatement', 'Principal',
+ 'PrincipalHolder', 'Printable',
+ 'PrinterAbortException', 'PrinterException',
+ 'PrinterGraphics', 'PrinterIOException',
+ 'PrinterJob', 'PrintGraphics', 'PrintJob',
+ 'PrintStream', 'PrintWriter', 'PrivateKey',
+ 'PRIVATE_MEMBER', 'PrivilegedAction',
+ 'PrivilegedActionException',
+ 'PrivilegedExceptionAction', 'Process',
+ 'ProfileDataException', 'ProgressBarUI',
+ 'ProgressMonitor', 'ProgressMonitorInputStream',
+ 'Properties', 'PropertyChangeEvent',
+ 'PropertyChangeListener', 'PropertyChangeSupport',
+ 'PropertyDescriptor', 'PropertyEditor',
+ 'PropertyEditorManager', 'PropertyEditorSupport',
+ 'PropertyPermission', 'PropertyResourceBundle',
+ 'PropertyVetoException', 'ProtectionDomain',
+ 'ProtocolException', 'Provider', 'ProviderException',
+ 'Proxy', 'PublicKey', 'PUBLIC_MEMBER',
+ 'PushbackInputStream', 'PushbackReader',
+ 'QuadCurve2D', 'QuadCurve2D.Double',
+ 'QuadCurve2D.Float', 'Random', 'RandomAccessFile',
+ 'Raster', 'RasterFormatException', 'RasterOp',
+ 'Reader', 'Receiver', 'Rectangle', 'Rectangle2D',
+ 'Rectangle2D.Double', 'Rectangle2D.Float',
+ 'RectangularShape', 'Ref', 'RefAddr', 'Reference',
+ 'Referenceable', 'ReferenceQueue',
+ 'ReferralException', 'ReflectPermission', 'Registry',
+ 'RegistryHandler', 'RemarshalException', 'Remote',
+ 'RemoteCall', 'RemoteException', 'RemoteObject',
+ 'RemoteRef', 'RemoteServer', 'RemoteStub',
+ 'RenderableImage', 'RenderableImageOp',
+ 'RenderableImageProducer', 'RenderContext',
+ 'RenderedImage', 'RenderedImageFactory', 'Renderer',
+ 'RenderingHints', 'RenderingHints.Key',
+ 'RepaintManager', 'ReplicateScaleFilter',
+ 'Repository', 'RepositoryIdHelper', 'Request',
+ 'RescaleOp', 'Resolver', 'ResolveResult',
+ 'ResourceBundle', 'ResponseHandler', 'ResultSet',
+ 'ResultSetMetaData', 'ReverbType', 'RGBImageFilter',
+ 'RMIClassLoader', 'RMIClientSocketFactory',
+ 'RMIFailureHandler', 'RMISecurityException',
+ 'RMISecurityManager', 'RMIServerSocketFactory',
+ 'RMISocketFactory', 'Robot', 'RootPaneContainer',
+ 'RootPaneUI', 'RoundRectangle2D',
+ 'RoundRectangle2D.Double', 'RoundRectangle2D.Float',
+ 'RowMapper', 'RSAKey', 'RSAKeyGenParameterSpec',
+ 'RSAPrivateCrtKey', 'RSAPrivateCrtKeySpec',
+ 'RSAPrivateKey', 'RSAPrivateKeySpec', 'RSAPublicKey',
+ 'RSAPublicKeySpec', 'RTFEditorKit',
+ 'RuleBasedCollator', 'Runnable', 'Runtime',
+ 'RunTime', 'RuntimeException', 'RunTimeOperations',
+ 'RuntimePermission', 'SampleModel',
+ 'SchemaViolationException', 'Scrollable',
+ 'Scrollbar', 'ScrollBarUI', 'ScrollPane',
+ 'ScrollPaneConstants', 'ScrollPaneLayout',
+ 'ScrollPaneLayout.UIResource', 'ScrollPaneUI',
+ 'SearchControls', 'SearchResult',
+ 'SecureClassLoader', 'SecureRandom',
+ 'SecureRandomSpi', 'Security', 'SecurityException',
+ 'SecurityManager', 'SecurityPermission', 'Segment',
+ 'SeparatorUI', 'Sequence', 'SequenceInputStream',
+ 'Sequencer', 'Sequencer.SyncMode', 'Serializable',
+ 'SerializablePermission', 'ServantObject',
+ 'ServerCloneException', 'ServerError',
+ 'ServerException', 'ServerNotActiveException',
+ 'ServerRef', 'ServerRequest',
+ 'ServerRuntimeException', 'ServerSocket',
+ 'ServiceDetail', 'ServiceDetailHelper',
+ 'ServiceInformation', 'ServiceInformationHelper',
+ 'ServiceInformationHolder',
+ 'ServiceUnavailableException', 'Set',
+ 'SetOverrideType', 'SetOverrideTypeHelper', 'Shape',
+ 'ShapeGraphicAttribute', 'Short', 'ShortHolder',
+ 'ShortLookupTable', 'ShortMessage', 'ShortSeqHelper',
+ 'ShortSeqHolder', 'Signature', 'SignatureException',
+ 'SignatureSpi', 'SignedObject', 'Signer',
+ 'SimpleAttributeSet', 'SimpleBeanInfo',
+ 'SimpleDateFormat', 'SimpleTimeZone',
+ 'SinglePixelPackedSampleModel',
+ 'SingleSelectionModel', 'SizeLimitExceededException',
+ 'SizeRequirements', 'SizeSequence', 'Skeleton',
+ 'SkeletonMismatchException',
+ 'SkeletonNotFoundException', 'SliderUI', 'Socket',
+ 'SocketException', 'SocketImpl', 'SocketImplFactory',
+ 'SocketOptions', 'SocketPermission',
+ 'SocketSecurityException', 'SoftBevelBorder',
+ 'SoftReference', 'SortedMap', 'SortedSet',
+ 'Soundbank', 'SoundbankReader', 'SoundbankResource',
+ 'SourceDataLine', 'SplitPaneUI', 'SQLData',
+ 'SQLException', 'SQLInput', 'SQLOutput',
+ 'SQLPermission', 'SQLWarning', 'Stack',
+ 'StackOverflowError', 'StateEdit', 'StateEditable',
+ 'StateFactory', 'Statement', 'Streamable',
+ 'StreamableValue', 'StreamCorruptedException',
+ 'StreamTokenizer', 'StrictMath', 'String',
+ 'StringBuffer', 'StringBufferInputStream',
+ 'StringCharacterIterator', 'StringContent',
+ 'StringHolder', 'StringIndexOutOfBoundsException',
+ 'StringReader', 'StringRefAddr', 'StringSelection',
+ 'StringTokenizer', 'StringValueHelper',
+ 'StringWriter', 'Stroke', 'Struct', 'StructMember',
+ 'StructMemberHelper', 'Stub', 'StubDelegate',
+ 'StubNotFoundException', 'Style', 'StyleConstants',
+ 'StyleConstants.CharacterConstants',
+ 'StyleConstants.ColorConstants',
+ 'StyleConstants.FontConstants',
+ 'StyleConstants.ParagraphConstants', 'StyleContext',
+ 'StyledDocument', 'StyledEditorKit',
+ 'StyledEditorKit.AlignmentAction',
+ 'StyledEditorKit.BoldAction',
+ 'StyledEditorKit.FontFamilyAction',
+ 'StyledEditorKit.FontSizeAction',
+ 'StyledEditorKit.ForegroundAction',
+ 'StyledEditorKit.ItalicAction',
+ 'StyledEditorKit.StyledTextAction',
+ 'StyledEditorKit.UnderlineAction', 'StyleSheet',
+ 'StyleSheet.BoxPainter', 'StyleSheet.ListPainter',
+ 'SwingConstants', 'SwingPropertyChangeSupport',
+ 'SwingUtilities', 'SyncFailedException',
+ 'Synthesizer', 'SysexMessage', 'System',
+ 'SystemColor', 'SystemException', 'SystemFlavorMap',
+ 'TabableView', 'TabbedPaneUI', 'TabExpander',
+ 'TableCellEditor', 'TableCellRenderer',
+ 'TableColumn', 'TableColumnModel',
+ 'TableColumnModelEvent', 'TableColumnModelListener',
+ 'TableHeaderUI', 'TableModel', 'TableModelEvent',
+ 'TableModelListener', 'TableUI', 'TableView',
+ 'TabSet', 'TabStop', 'TagElement', 'TargetDataLine',
+ 'TCKind', 'TextAction', 'TextArea', 'TextAttribute',
+ 'TextComponent', 'TextEvent', 'TextField',
+ 'TextHitInfo', 'TextLayout',
+ 'TextLayout.CaretPolicy', 'TextListener',
+ 'TextMeasurer', 'TextUI', 'TexturePaint', 'Thread',
+ 'ThreadDeath', 'ThreadGroup', 'ThreadLocal',
+ 'Throwable', 'Tie', 'TileObserver', 'Time',
+ 'TimeLimitExceededException', 'Timer', 'TimerTask',
+ 'Timestamp', 'TimeZone', 'TitledBorder', 'ToolBarUI',
+ 'Toolkit', 'ToolTipManager', 'ToolTipUI',
+ 'TooManyListenersException', 'Track',
+ 'TransactionRequiredException',
+ 'TransactionRolledbackException',
+ 'TRANSACTION_REQUIRED', 'TRANSACTION_ROLLEDBACK',
+ 'Transferable', 'TransformAttribute', 'TRANSIENT',
+ 'Transmitter', 'Transparency', 'TreeCellEditor',
+ 'TreeCellRenderer', 'TreeExpansionEvent',
+ 'TreeExpansionListener', 'TreeMap', 'TreeModel',
+ 'TreeModelEvent', 'TreeModelListener', 'TreeNode',
+ 'TreePath', 'TreeSelectionEvent',
+ 'TreeSelectionListener', 'TreeSelectionModel',
+ 'TreeSet', 'TreeUI', 'TreeWillExpandListener',
+ 'TypeCode', 'TypeCodeHolder', 'TypeMismatch',
+ 'Types', 'UID', 'UIDefaults',
+ 'UIDefaults.ActiveValue', 'UIDefaults.LazyInputMap',
+ 'UIDefaults.LazyValue', 'UIDefaults.ProxyLazyValue',
+ 'UIManager', 'UIManager.LookAndFeelInfo',
+ 'UIResource', 'ULongLongSeqHelper',
+ 'ULongLongSeqHolder', 'ULongSeqHelper',
+ 'ULongSeqHolder', 'UndeclaredThrowableException',
+ 'UndoableEdit', 'UndoableEditEvent',
+ 'UndoableEditListener', 'UndoableEditSupport',
+ 'UndoManager', 'UnexpectedException',
+ 'UnicastRemoteObject', 'UnionMember',
+ 'UnionMemberHelper', 'UNKNOWN', 'UnknownError',
+ 'UnknownException', 'UnknownGroupException',
+ 'UnknownHostException', 'UnknownObjectException',
+ 'UnknownServiceException', 'UnknownUserException',
+ 'UnmarshalException', 'UnrecoverableKeyException',
+ 'Unreferenced', 'UnresolvedPermission',
+ 'UnsatisfiedLinkError', 'UnsolicitedNotification',
+ 'UnsolicitedNotificationEvent',
+ 'UnsolicitedNotificationListener',
+ 'UnsupportedAudioFileException',
+ 'UnsupportedClassVersionError',
+ 'UnsupportedEncodingException',
+ 'UnsupportedFlavorException',
+ 'UnsupportedLookAndFeelException',
+ 'UnsupportedOperationException',
+ 'UNSUPPORTED_POLICY', 'UNSUPPORTED_POLICY_VALUE',
+ 'URL', 'URLClassLoader', 'URLConnection',
+ 'URLDecoder', 'URLEncoder', 'URLStreamHandler',
+ 'URLStreamHandlerFactory', 'UserException',
+ 'UShortSeqHelper', 'UShortSeqHolder',
+ 'UTFDataFormatException', 'Util', 'UtilDelegate',
+ 'Utilities', 'ValueBase', 'ValueBaseHelper',
+ 'ValueBaseHolder', 'ValueFactory', 'ValueHandler',
+ 'ValueMember', 'ValueMemberHelper',
+ 'VariableHeightLayoutCache', 'Vector', 'VerifyError',
+ 'VersionSpecHelper', 'VetoableChangeListener',
+ 'VetoableChangeSupport', 'View', 'ViewFactory',
+ 'ViewportLayout', 'ViewportUI',
+ 'VirtualMachineError', 'Visibility',
+ 'VisibilityHelper', 'VMID', 'VM_ABSTRACT',
+ 'VM_CUSTOM', 'VM_NONE', 'VM_TRUNCATABLE',
+ 'VoiceStatus', 'Void', 'WCharSeqHelper',
+ 'WCharSeqHolder', 'WeakHashMap', 'WeakReference',
+ 'Window', 'WindowAdapter', 'WindowConstants',
+ 'WindowEvent', 'WindowListener', 'WrappedPlainView',
+ 'WritableRaster', 'WritableRenderedImage',
+ 'WriteAbortedException', 'Writer',
+ 'WrongTransaction', 'WStringValueHelper',
+ 'X509Certificate', 'X509CRL', 'X509CRLEntry',
+ 'X509EncodedKeySpec', 'X509Extension', 'ZipEntry',
+ 'ZipException', 'ZipFile', 'ZipInputStream',
+ 'ZipOutputStream', 'ZoneView',
+ '_BindingIteratorImplBase', '_BindingIteratorStub',
+ '_IDLTypeStub', '_NamingContextImplBase',
+ '_NamingContextStub', '_PolicyStub', '_Remote_Stub'
+ ),
+ 4 => array(
+ 'boolean', 'byte', 'char', 'double', 'float', 'int', 'long',
+ 'short', 'void'
+ ),
+ 5 => array(
+ 'allProperties', 'asImmutable', 'asSynchronized', 'collect',
+ 'count', 'each', 'eachProperty', 'eachPropertyName',
+ 'eachWithIndex', 'find', 'findAll', 'findIndexOf',
+ 'flatten', 'get', 'grep', 'inject', 'intersect',
+ 'join', 'max', 'min', 'pop', 'reverse',
+ 'reverseEach', 'size', 'sort', 'subMap', 'toList'
+ ),
+ 6 => array(
+ 'center', 'contains', 'eachMatch', 'padLeft', 'padRight',
+ 'toCharacter', 'tokenize', 'toLong', 'toURL'
+ ),
+ 7 => array(
+ 'append', 'eachByte', 'eachFile', 'eachFileRecurse', 'eachLine',
+ 'eachLines', 'encodeBase64', 'filterLine', 'getText',
+ 'splitEachLine', 'transformChar', 'transformLine',
+ 'withOutputStream', 'withPrintWriter', 'withReader',
+ 'withStream', 'withStreams', 'withWriter',
+ 'withWriterAppend', 'write', 'writeLine'
+ ),
+ 8 => array(
+ 'dump', 'getLastMatcher', 'inspect', 'invokeMethod', 'print',
+ 'println', 'start', 'startDaemon', 'step', 'times',
+ 'upto', 'use'
+ ),
+ 9 => array(
+ 'call', 'close', 'eachRow', 'execute', 'executeUpdate', 'Sql'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '*', '&', '%', '!', ';', '<', '>', '?', '|', '=',
+ '=>', '||', '-', '+', '<<', '<<<', '&&'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => false,
+ 2 => false,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #aaaadd; font-weight: bold;',
+ 4 => 'color: #993333;',
+ 5 => 'color: #663399;',
+ 6 => 'color: #CC0099;',
+ 7 => 'color: #FFCC33;',
+ 8 => 'color: #993399;',
+ 9 => 'color: #993399; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1=> 'color: #808080; font-style: italic;',
+ 2=> 'color: #a1a100;',
+ 3=> 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000ff;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.google.de/search?q=site%3Agroovy.codehaus.org/%20{FNAMEL}',
+ 2 => 'http://www.google.de/search?q=site%3Agroovy.codehaus.org/%20{FNAMEL}',
+ 3 => 'http://www.google.de/search?as_q={FNAME}&amp;num=100&amp;hl=en&amp;as_occt=url&amp;as_sitesearch=java.sun.com%2Fj2se%2F1%2E5%2E0%2Fdocs%2Fapi%2F',
+ 4 => 'http://www.google.de/search?q=site%3Agroovy.codehaus.org/%20{FNAME}',
+ 5 => 'http://www.google.de/search?q=site%3Agroovy.codehaus.org/%20{FNAME}',
+ 6 => 'http://www.google.de/search?q=site%3Agroovy.codehaus.org/%20{FNAME}',
+ 7 => 'http://www.google.de/search?q=site%3Agroovy.codehaus.org/%20{FNAME}',
+ 8 => 'http://www.google.de/search?q=site%3Agroovy.codehaus.org/%20{FNAME}',
+ 9 => 'http://www.google.de/search?q=site%3Agroovy.codehaus.org/%20{FNAME}'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ //Variables
+ 0 => '\\$\\{[a-zA-Z_][a-zA-Z0-9_]*\\}'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/gwbasic.php b/platform/www/vendor/geshi/geshi/src/geshi/gwbasic.php
new file mode 100644
index 0000000..0fd7a29
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/gwbasic.php
@@ -0,0 +1,151 @@
+<?php
+/*************************************************************************************
+ * gwbasic.php
+ * ----------
+ * Author: José Gabriel Moya Yangüela (josemoya@gmail.com)
+ * Copyright: (c) 2010 José Gabriel Moya Yangüela (http://doc.apagada.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/01/30
+ *
+ * GwBasic language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * REM was not classified as comment.
+ * APPEND and RANDOM missing.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'GwBasic',
+ 'COMMENT_SINGLE' => array(1 => "'", 2=> "REM"),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /* Statements */
+ 1 => array('END','FOR','NEXT','DATA','INPUT','DIM','READ','LET',
+ 'GOTO','RUN','IF','RESTORE','GOSUB','RETURN','REM',
+ 'STOP','PRINT','CLEAR','LIST','NEW','ON','WAIT','DEF',
+ 'POKE','CONT','OUT','LPRINT','LLIST','WIDTH','ELSE',
+ 'TRON','TROFF','SWAP','ERASE','EDIT','ERROR','RESUME',
+ 'DELETE','AUTO','RENUM','DEFSTR','DEFINT','DEFSNG',
+ 'DEFDBL','LINE','WHILE','WEND','CALL','WRITE','OPTION',
+ 'RANDOMIZE','OPEN','CLOSE','LOAD','MERGE','SAVE',
+ 'COLOR','CLS','MOTOR','BSAVE','BLOAD','SOUND','BEEP',
+ 'PSET','PRESET','SCREEN','KEY','LOCATE','TO','THEN',
+ 'STEP','USR','FN','SPC','NOT','ERL','ERR','STRING',
+ 'USING','INSTR','VARPTR','CSRLIN','POINT','OFF',
+ 'FILES','FIELD','SYSTEM','NAME','LSET','RSET','KILL',
+ 'PUT','GET','RESET','COMMON','CHAIN','PAINT','COM',
+ 'CIRCLE','DRAW','PLAY','TIMER','IOCTL','CHDIR','MKDIR',
+ 'RMDIR','SHELL','VIEW','WINDOW','PMAP','PALETTE','LCOPY',
+ 'CALLS','PCOPY','LOCK','UNLOCK','RANDOM','APPEND',
+ ),
+ 2 => array(
+ /* Functions */
+ 'CVI','CVS','CVD','MKI','MKS','MKD','ENVIRON',
+ 'LEFT','RIGHT','MID','SGN','INT','ABS',
+ 'SQR','SIN','LOG','EXP','COS','TAN','ATN',
+ 'FRE','INP','POS','LEN','STR','VAL','ASC',
+ 'CHR','PEEK','SPACE','OCT','HEX','LPOS',
+ 'CINT','CSNG','CDBL','FIX','PEN','STICK',
+ 'STRIG','EOF','LOC','LOF'
+ ),
+ 3 => array(
+ /* alpha Operators */
+ 'AND','OR','XOR','EQV','IMP','MOD'
+ ),
+ 4 => array(
+ /* parameterless functions */
+ 'INKEY','DATE','TIME','ERDEV','RND'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '>','=','<','+','-','*','/','^','\\'
+ ),
+ 1 => array(
+ '?'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00a1a1;font-weight: bold',
+ 2 => 'color: #000066;font-weight: bold',
+ 3 => 'color: #00a166;font-weight: bold',
+ 4 => 'color: #0066a1;font-weight: bold'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080;',
+ 2 => 'color: #808080;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ /* Same as KEYWORDS[3] (and, or, not...) */
+ 0 => 'color: #00a166;font-weight: bold',
+ 1 => 'color: #00a1a1;font-weight: bold',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #708090'
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 1 => '^[0-9]+ '
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/haskell.php b/platform/www/vendor/geshi/geshi/src/geshi/haskell.php
new file mode 100644
index 0000000..1a22447
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/haskell.php
@@ -0,0 +1,195 @@
+<?php
+/*************************************************************************************
+ * haskell.php
+ * ----------
+ * Author: Daniel Mlot (duplode_1 at yahoo dot com dot br)
+ * Based on haskell.php by Jason Dagit (dagit@codersbase.com), which was
+ * based on ocaml.php by Flaie (fireflaie@gmail.com).
+ * Copyright: (c) 2005 Flaie, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2014/05/12
+ *
+ * Haskell language file for GeSHi.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Haskell',
+ 'COMMENT_SINGLE' => array( 1 => '--'),
+ 'COMMENT_MULTI' => array('{-' => '-}'),
+ 'COMMENT_REGEXP' => array(
+ 2 => "/-->/",
+ 3 => "/{-(?:(?R)|.)-}/s", //Nested Comments
+ ),
+ 'CASE_KEYWORDS' => 0,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ /* main haskell keywords */
+ 1 => array(
+ 'as',
+ 'case', 'of', 'class', 'data', 'default',
+ 'deriving', 'do', 'forall', 'hiding', 'if', 'then',
+ 'else', 'import', 'infix', 'infixl', 'infixr',
+ 'instance', 'let', 'in', 'module', 'newtype',
+ 'qualified', 'type', 'where'
+ ),
+ /* define names of main libraries, so we can link to it */
+ 2 => array(
+ 'Foreign', 'Numeric', 'Prelude'
+ ),
+ /* just link to Prelude functions, cause it's the default opened library when starting Haskell */
+ 3 => array(
+ 'not', 'otherwise', 'maybe',
+ 'either', 'fst', 'snd', 'curry', 'uncurry',
+ 'compare',
+ 'max', 'min', 'succ', 'pred', 'toEnum', 'fromEnum',
+ 'enumFrom', 'enumFromThen', 'enumFromTo',
+ 'enumFromThenTo', 'minBound', 'maxBound',
+ 'negate', 'abs', 'signum',
+ 'fromInteger', 'toRational', 'quot', 'rem',
+ 'div', 'mod', 'quotRem', 'divMod', 'toInteger',
+ 'recip', 'fromRational', 'pi', 'exp',
+ 'log', 'sqrt', 'logBase', 'sin', 'cos',
+ 'tan', 'asin', 'acos', 'atan', 'sinh', 'cosh',
+ 'tanh', 'asinh', 'acosh', 'atanh',
+ 'properFraction', 'truncate', 'round', 'ceiling',
+ 'floor', 'floatRadix', 'floatDigits', 'floatRange',
+ 'decodeFloat', 'encodeFloat', 'exponent',
+ 'significand', 'scaleFloat', 'isNaN', 'isInfinite',
+ 'isDenomalized', 'isNegativeZero', 'isIEEE',
+ 'atan2', 'subtract', 'even', 'odd', 'gcd',
+ 'lcm', 'fromIntegral', 'realToFrac',
+ 'return', 'fail', 'fmap',
+ 'mapM', 'mapM_', 'sequence', 'sequence_',
+ 'id', 'const','flip',
+ 'until', 'asTypeOf', 'error', 'undefined',
+ 'seq','map','filter', 'head',
+ 'last', 'tail', 'init', 'null', 'length',
+ 'reverse', 'foldl', 'foldl1', 'foldr',
+ 'foldr1', 'and', 'or', 'any', 'all', 'sum',
+ 'product', 'concat', 'concatMap', 'maximum',
+ 'minimum', 'scanl', 'scanl1', 'scanr', 'scanr1',
+ 'iterate', 'repeat', 'cycle', 'take', 'drop',
+ 'splitAt', 'takeWhile', 'dropWhile', 'span',
+ 'break', 'elem', 'notElem', 'lookup', 'zip',
+ 'zip3', 'zipWith', 'zipWith3', 'unzip', 'unzip3',
+ 'lines', 'words', 'unlines',
+ 'unwords', 'showPrec', 'show', 'showList',
+ 'shows', 'showChar', 'showString', 'showParen',
+ 'readsPrec', 'readList', 'reads', 'readParen',
+ 'read', 'lex', 'putChar', 'putStr', 'putStrLn',
+ 'print', 'getChar', 'getLine', 'getContents',
+ 'interact', 'readFile', 'writeFile', 'appendFile',
+ 'readIO', 'readLn', 'ioError', 'userError', 'catch'
+ ),
+ /* Prelude types */
+ 4 => array (
+ 'Bool', 'Maybe', 'Either', 'Ordering',
+ 'Char', 'String',
+ 'Int', 'Integer', 'Float', 'Double', 'Rational', 'Word',
+ 'ShowS', 'ReadS',
+ 'IO', 'IOError', 'IOException'
+ ),
+ /* Prelude classes */
+ 5 => array (
+ 'Ord', 'Eq', 'Enum', 'Bounded',
+ 'Num', 'Real', 'Integral', 'Fractional',
+ 'Floating', 'RealFrac', 'RealFloat',
+ 'Semigroup', 'Monoid',
+ 'Monad', 'Applicative', 'Functor',
+ 'Foldable', 'Traversable',
+ 'Show', 'Read'
+ )
+ ),
+ /* Most symbol combinations can be valid Haskell operators */
+ 'SYMBOLS' => array(
+ '!', '@', '#', '$', '%', '&', '*', '-', '+', '=',
+ '^', '~', '|', '\\', '>', '<', ':', '?', '/'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true, /* Haskell is a case sensitive language */
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 2 => 'color: #06c; font-weight: bold;', /* blue as well */
+ 3 => 'font-weight: bold;', /* make the preduled functions bold */
+ 4 => 'color: #cccc00; font-weight: bold;', /* give types a different bg */
+ 5 => 'color: maroon; font-weight: bold;' /* similarly for classes */
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #5d478b; font-style: italic;',
+ 2 => 'color: #339933; font-weight: bold;',
+ 3 => 'color: #5d478b; font-style: italic;', /* light purple */
+ 'MULTI' => 'color: #5d478b; font-style: italic;' /* light purple */
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'background-color: #3cb371; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: green;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #3cb371;' /* nice green */
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: red;' /* pink */
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #060;' /* dark green */
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933; font-weight: bold;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ /* some of keywords are Prelude functions */
+ 1 => '',
+ /* link to the wanted library */
+ 2 => 'http://hackage.haskell.org/package/base/docs/{FNAME}.html',
+ /* link to Prelude functions */
+ 3 => 'http://hackage.haskell.org/package/base/docs/Prelude.html#v:{FNAME}',
+ /* link to Prelude types */
+ 4 => 'http://hackage.haskell.org/package/base/docs/Prelude.html#t:{FNAME}',
+ /* link to Prelude exceptions */
+ 5 => 'http://hackage.haskell.org/package/base/docs/Prelude.html#t:{FNAME}'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/haxe.php b/platform/www/vendor/geshi/geshi/src/geshi/haxe.php
new file mode 100644
index 0000000..f63674d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/haxe.php
@@ -0,0 +1,158 @@
+<?php
+/*************************************************************************************
+ * haxe.php
+ * --------
+ * Author: Andy Li (andy@onthewings.net)
+ * John Liao (colorhook@gmail.com)
+ * Copyright: (c) 2012 onthewings (http://www.onthewings.net/)
+ * 2010 colorhook (http://colorhook.com/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/10/05
+ *
+ * Haxe language file for GeSHi.
+ * Haxe version: 2.10
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Haxe',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Import and Package directives (Basic Support only)
+ 2 => '/(?:(?<=import[\\n\\s])|(?<=using[\\n\\s])|(?<=package[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*([a-zA-Z0-9_]+|\*)(?=[\n\s;])/i',
+ // Haxe comments
+ 3 => '#/\*\*(?![\*\/]).*\*/#sU',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ //http://haxe.org/ref/keywords
+ 'break', 'callback', 'case', 'cast', 'catch', 'class', 'continue', 'default', 'do', 'dynamic',
+ 'else', 'enum', 'extends', 'extern', /*'false',*/ 'for', 'function', 'here', 'if',
+ 'implements', 'import', 'in', 'inline', 'interface', 'never', 'new', /*'null',*/ 'override',
+ 'package', 'private', 'public', 'return', 'static', 'super', 'switch', 'this', 'throw',
+ 'trace', /*'true',*/ 'try', 'typedef', 'untyped', 'using', 'var', 'while',
+ 'macro', '$type',
+ ),
+ 2 => array(
+ //primitive values
+ 'null', 'false', 'true',
+ ),
+ 3 => array(
+ //global types
+ 'Array', 'ArrayAccess', /*'Bool',*/ 'Class', 'Date', 'DateTools', 'Dynamic',
+ 'EReg', 'Enum', 'EnumValue', /*'Float',*/ 'Hash', /*'Int',*/ 'IntHash', 'IntIter',
+ 'Iterable', 'Iterator', 'Lambda', 'List', 'Math', 'Null', 'Reflect', 'Std',
+ /*'String',*/ 'StringBuf', 'StringTools', 'Sys', 'Type', /*'UInt',*/ 'ValueType',
+ /*'Void',*/ 'Xml', 'XmlType',
+ ),
+ 4 => array(
+ //primitive types
+ 'Void', 'Bool', 'Int', 'Float', 'UInt', 'String',
+ ),
+ 5 => array(
+ //compiler switches
+ "#if", "#elseif", "#else", "#end", "#error",
+ ),
+ ),
+ 'SYMBOLS' => array(
+ //http://haxe.org/manual/operators
+ '++', '--',
+ '%',
+ '*', '/',
+ '+', '-',
+ '<<', '>>', '>>>',
+ '|', '&', '^',
+ '==', '!=', '>', '>=', '<', '<=',
+ '...',
+ '&&',
+ '||',
+ '?', ':',
+ '=', '+=', '-=', '/=', '*=', '<<=', '>>=', '>>>=', '|=', '&=', '^=',
+ '(', ')', '[', ']', '{', '}', ';',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #6699cc; font-weight: bold;',
+ 2 => 'color: #000066; font-weight: bold;',
+ 3 => 'color: #03F; ',
+ 4 => 'color: #000033; font-weight: bold;',
+ 5 => 'color: #330000; font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #006699;',
+ 3 => 'color: #008000; font-style: italic; font-weight: bold;',
+ 'MULTI' => 'color: #666666; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;',
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #FF0000;',
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006633;',
+ 2 => 'color: #006633;',
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;',
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/hicest.php b/platform/www/vendor/geshi/geshi/src/geshi/hicest.php
new file mode 100644
index 0000000..f92f6d6
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/hicest.php
@@ -0,0 +1,106 @@
+<?php
+/*************************************************************************************
+ * hicest.php
+ * --------
+ * Author: Georg Petrich (spt@hicest.com)
+ * Copyright: (c) 2010 Georg Petrich (http://www.HicEst.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/03/15
+ *
+ * HicEst language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * yyyy/mm/dd (v.v.v.v)
+ * - First Release
+ *
+ * TODO (updated yyyy/mm/dd)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'HicEst',
+ 'COMMENT_SINGLE' => array(1 => '!'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', '\''),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ '$cmd_line', 'abs', 'acos', 'alarm', 'alias', 'allocate', 'appendix', 'asin', 'atan', 'axis', 'beep',
+ 'call', 'ceiling', 'char', 'character', 'com', 'continue', 'cos', 'cosh', 'data', 'diffeq', 'dimension', 'dlg', 'dll',
+ 'do', 'edit', 'else', 'elseif', 'end', 'enddo', 'endif', 'exp', 'floor', 'function', 'fuz', 'goto', 'iand', 'ichar',
+ 'ieor', 'if', 'index', 'init', 'int', 'intpol', 'ior', 'key', 'len', 'len_trim', 'line', 'lock', 'log', 'max', 'maxloc',
+ 'min', 'minloc', 'mod', 'nint', 'not', 'open', 'pop', 'ran', 'read', 'real', 'return', 'rgb', 'roots', 'sign', 'sin',
+ 'sinh', 'solve', 'sort', 'subroutine', 'sum', 'system', 'tan', 'tanh', 'then', 'time', 'use', 'window', 'write', 'xeq'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '(', ')', '+', '-', '*', '/', '=', '<', '>', '!', '^', ':', ','
+ ),
+ 2 => array(
+ '$', '$$'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #ff0000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #339933;',
+ 2 => 'color: #ff0000;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(1 => ''),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/hq9plus.php b/platform/www/vendor/geshi/geshi/src/geshi/hq9plus.php
new file mode 100644
index 0000000..29878ed
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/hq9plus.php
@@ -0,0 +1,102 @@
+<?php
+/*************************************************************************************
+ * hq9plus.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/10/31
+ *
+ * HQ9+ language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/31 (1.0.8.1)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+$language_data = array (
+ 'LANG_NAME' => 'HQ9+',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 'H', 'Q', '9', '+', 'h', 'q'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ ),
+ 'COMMENTS' => array(
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #a16000;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'KEYWORDS' => GESHI_NEVER,
+ 'COMMENTS' => GESHI_NEVER,
+ 'STRINGS' => GESHI_NEVER,
+ 'REGEXPS' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/html4strict.php b/platform/www/vendor/geshi/geshi/src/geshi/html4strict.php
new file mode 100644
index 0000000..56c40a1
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/html4strict.php
@@ -0,0 +1,188 @@
+<?php
+/*************************************************************************************
+ * html4strict.php
+ * ---------------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/07/10
+ *
+ * HTML 4.01 strict language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/12/28 (1.0.4)
+ * - Removed escape character for strings
+ * 2004/11/27 (1.0.3)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ * - Added support for URLs
+ * 2004/08/05 (1.0.1)
+ * - Added INS and DEL
+ * - Removed the background colour from tags' styles
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Check that only HTML4 strict attributes are highlighted
+ * * Eliminate empty tags that aren't allowed in HTML4 strict
+ * * Split to several files - html4trans, xhtml1 etc
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'HTML',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 2 => array(
+ 'a', 'abbr', 'acronym', 'address', 'applet', 'area',
+ 'base', 'basefont', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'b',
+ 'caption', 'center', 'cite', 'code', 'colgroup', 'col',
+ 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt',
+ 'em',
+ 'fieldset', 'font', 'form', 'frame', 'frameset',
+ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html',
+ 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'i',
+ 'kbd',
+ 'label', 'legend', 'link', 'li',
+ 'map', 'meta',
+ 'noframes', 'noscript',
+ 'object', 'ol', 'optgroup', 'option',
+ 'param', 'pre', 'p',
+ 'q',
+ 'samp', 'script', 'select', 'small', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 's',
+ 'table', 'tbody', 'td', 'textarea', 'text', 'tfoot', 'thead', 'th', 'title', 'tr', 'tt',
+ 'ul', 'u',
+ 'var',
+ ),
+ 3 => array(
+ 'abbr', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alink', 'alt', 'archive', 'axis',
+ 'background', 'bgcolor', 'border',
+ 'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols', 'colspan', 'compact', 'content', 'coords',
+ 'data', 'datetime', 'declare', 'defer', 'dir', 'disabled',
+ 'enctype',
+ 'face', 'for', 'frame', 'frameborder',
+ 'headers', 'height', 'href', 'hreflang', 'hspace', 'http-equiv',
+ 'id', 'ismap',
+ 'label', 'lang', 'language', 'link', 'longdesc',
+ 'marginheight', 'marginwidth', 'maxlength', 'media', 'method', 'multiple',
+ 'name', 'nohref', 'noresize', 'noshade', 'nowrap',
+ 'object', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onreset', 'onselect', 'onsubmit', 'onunload',
+ 'profile', 'prompt',
+ 'readonly', 'rel', 'rev', 'rowspan', 'rows', 'rules',
+ 'scheme', 'scope', 'scrolling', 'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary',
+ 'tabindex', 'target', 'text', 'title', 'type',
+ 'usemap',
+ 'valign', 'value', 'valuetype', 'version', 'vlink', 'vspace',
+ 'width'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '/', '='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ -2 => 'color: #404040;', // CDATA
+ -1 => 'color: #808080; font-style: italic;', // comments
+ 0 => 'color: #00bbdd;',
+ 1 => 'color: #ddbb00;',
+ 2 => 'color: #009900;'
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 2 => 'http://december.com/html/4/element/{FNAMEL}.html',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+ 'SCRIPT_DELIMITERS' => array(
+ -2 => array(
+ '<![CDATA[' => ']]>'
+ ),
+ -1 => array(
+ '<!--' => '-->'
+ ),
+ 0 => array(
+ '<!DOCTYPE' => '>'
+ ),
+ 1 => array(
+ '&' => ';'
+ ),
+ 2 => array(
+ '<' => '>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ -2 => false,
+ -1 => false,
+ 0 => false,
+ 1 => false,
+ 2 => true
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 2 => array(
+ 'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+ 'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/html5.php b/platform/www/vendor/geshi/geshi/src/geshi/html5.php
new file mode 100644
index 0000000..f6316f7
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/html5.php
@@ -0,0 +1,210 @@
+<?php
+/*************************************************************************************
+ * html5.php
+ * ---------------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/07/10
+ *
+ * HTML 5 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/12/28 (1.0.4)
+ * - Removed escape character for strings
+ * 2004/11/27 (1.0.3)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ * - Added support for URLs
+ * 2004/08/05 (1.0.1)
+ * - Added INS and DEL
+ * - Removed the background colour from tags' styles
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Check that only HTML4 strict attributes are highlighted
+ * * Eliminate empty tags that aren't allowed in HTML4 strict
+ * * Split to several files - html4trans, xhtml1 etc
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'HTML5',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 2 => array(
+ 'a', 'abbr', 'address', 'article', 'area', 'aside', 'audio',
+
+ 'base', 'bdo', 'blockquote', 'body', 'br', 'button', 'b',
+
+ 'caption', 'cite', 'code', 'colgroup', 'col', 'canvas', 'command', 'datalist', 'details',
+
+ 'dd', 'del', 'dfn', 'div', 'dl', 'dt',
+
+ 'em', 'embed',
+
+ 'fieldset', 'form', 'figcaption', 'figure', 'footer',
+
+ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html', 'header', 'hgroup',
+
+ 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'i',
+
+ 'kbd', 'keygen',
+
+ 'label', 'legend', 'link', 'li',
+
+ 'map', 'meta', 'mark', 'meter',
+
+ 'noscript', 'nav',
+
+ 'object', 'ol', 'optgroup', 'option', 'output',
+
+ 'param', 'pre', 'p', 'progress',
+
+ 'q',
+
+ 'rp', 'rt', 'ruby',
+
+ 'samp', 'script', 'select', 'small', 'span', 'strong', 'style', 'sub', 'sup', 's', 'section', 'source', 'summary',
+
+ 'table', 'tbody', 'td', 'textarea', 'text', 'tfoot', 'thead', 'th', 'title', 'tr', 'time',
+
+ 'ul',
+
+ 'var', 'video',
+
+ 'wbr',
+ ),
+ 3 => array(
+ 'abbr', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alink', 'alt', 'archive', 'axis', 'autocomplete', 'autofocus',
+ 'background', 'bgcolor', 'border',
+ 'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols', 'colspan', 'compact', 'content', 'coords', 'contenteditable', 'contextmenu',
+ 'data', 'datetime', 'declare', 'defer', 'dir', 'disabled', 'draggable', 'dropzone',
+ 'enctype',
+ 'face', 'for', 'frame', 'frameborder', 'form', 'formaction', 'formenctype', 'formmethod', 'formnovalidate', 'formtarget',
+ 'headers', 'height', 'href', 'hreflang', 'hspace', 'http-equiv', 'hidden',
+ 'id', 'ismap',
+ 'label', 'lang', 'language', 'link', 'longdesc',
+ 'marginheight', 'marginwidth', 'maxlength', 'media', 'method', 'multiple', 'min', 'max',
+ 'name', 'nohref', 'noresize', 'noshade', 'nowrap', 'novalidate',
+ 'object', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onselect', 'onsubmit', 'onunload', 'onafterprint', 'onbeforeprint', 'onbeforeonload', 'onerror', 'onhaschange', 'onmessage', 'onoffline', 'ononline', 'onpagehide', 'onpageshow', 'onpopstate', 'onredo', 'onresize', 'onstorage', 'onundo', 'oncontextmenu', 'onformchange', 'onforminput', 'oninput', 'oninvalid', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onmousewheel', 'onscroll', 'oncanplay', 'oncanplaythrough', 'ondurationchange', 'onemptied', 'onended', 'onloadeddata', 'onloadedmetadata', 'onloadstart', 'onpause', 'onplay', 'onplaying', 'onprogress', 'onratechange', 'onreadystatechange', 'onseeked', 'onseeking', 'onstalled', 'onsuspend', 'ontimeupdate', 'onvolumechange', 'onwaiting',
+ 'profile', 'prompt', 'pattern', 'placeholder',
+ 'readonly', 'rel', 'rev', 'rowspan', 'rows', 'rules', 'required',
+ 'scheme', 'scope', 'scrolling', 'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary', 'spellcheck', 'step',
+ 'tabindex', 'target', 'text', 'title', 'type',
+ 'usemap',
+ 'valign', 'value', 'valuetype', 'version', 'vlink', 'vspace',
+ 'width'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '/', '='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ -2 => 'color: #404040;', // CDATA
+ -1 => 'color: #808080; font-style: italic;', // comments
+ 0 => 'color: #00bbdd;',
+ 1 => 'color: #ddbb00;',
+ 2 => 'color: #009900;'
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 2 => 'http://december.com/html/4/element/{FNAMEL}.html',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+ 'SCRIPT_DELIMITERS' => array(
+ -2 => array(
+ '<![CDATA[' => ']]>'
+ ),
+ -1 => array(
+ '<!--' => '-->'
+ ),
+ 0 => array(
+ '<!DOCTYPE' => '>'
+ ),
+ 1 => array(
+ '&' => ';'
+ ),
+ 2 => array(
+ '<' => '>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ -2 => false,
+ -1 => false,
+ 0 => false,
+ 1 => false,
+ 2 => true
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 2 => array(
+ 'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+ 'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/icon.php b/platform/www/vendor/geshi/geshi/src/geshi/icon.php
new file mode 100644
index 0000000..feb3d84
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/icon.php
@@ -0,0 +1,210 @@
+<?php
+/*************************************************************************************
+ * icon.php
+ * --------
+ * Author: Matt Oates (mattoates@gmail.com)
+ * Copyright: (c) 2010 Matt Oates (http://mattoates.co.uk)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/04/24
+ *
+ * Icon language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/04/24 (0.0.0.2)
+ * - Validated with Geshi langcheck.php FAILED due to preprocessor keywords looking like symbols
+ * - Hard wrapped to improve readability
+ * 2010/04/20 (0.0.0.1)
+ * - First Release
+ *
+ * TODO (updated 2010/04/20)
+ * -------------------------
+ * - Do the &amp; need replacing with &?
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Icon',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', '\''),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'break', 'case', 'continue', 'create', 'default', 'do', 'else',
+ 'end', 'every', 'fail', 'for', 'if', 'import', 'initial',
+ 'initially', 'invocable', 'link', 'next', 'not', 'of', 'package',
+ 'procedure', 'record', 'repeat', 'return', 'switch', 'suspend',
+ 'then', 'to', 'until', 'while'
+ ),
+ 2 => array(
+ 'global', 'local', 'static'
+ ),
+ 3 => array(
+ 'allocated', 'ascii', 'clock', 'collections',
+ 'column', 'cset', 'current', 'date', 'dateline', 'digits',
+ 'dump', 'e', 'error', 'errornumber', 'errortext',
+ 'errorvalue', 'errout', 'eventcode', 'eventsource', 'eventvalue',
+ 'fail', 'features', 'file', 'host', 'input', 'lcase',
+ 'letters', 'level', 'line', 'main', 'now', 'null',
+ 'output', 'phi', 'pi', 'pos', 'progname', 'random',
+ 'regions', 'source', 'storage', 'subject', 'syserr', 'time',
+ 'trace', 'ucase', 'version', 'col', 'control', 'interval',
+ 'ldrag', 'lpress', 'lrelease', 'mdrag', 'meta', 'mpress',
+ 'mrelease', 'rdrag', 'resize', 'row', 'rpress', 'rrelease',
+ 'shift', 'window', 'x', 'y'
+ ),
+ 4 => array(
+ 'abs', 'acos', 'any', 'args', 'asin', 'atan', 'bal', 'center', 'char',
+ 'chmod', 'close', 'cofail', 'collect', 'copy', 'cos', 'cset', 'ctime', 'delay', 'delete',
+ 'detab', 'display', 'dtor', 'entab', 'errorclear', 'event', 'eventmask', 'EvGet', 'exit',
+ 'exp', 'fetch', 'fieldnames', 'find', 'flock', 'flush', 'function', 'get', 'getch',
+ 'getche', 'getenv', 'gettimeofday', 'globalnames', 'gtime', 'iand', 'icom', 'image',
+ 'insert', 'integer', 'ior', 'ishift', 'ixor', 'key', 'left', 'list', 'load', 'loadfunc',
+ 'localnames', 'log', 'many', 'map', 'match', 'member', 'mkdir', 'move', 'name', 'numeric',
+ 'open', 'opmask', 'ord', 'paramnames', 'parent', 'pipe', 'pop', 'pos', 'proc', 'pull',
+ 'push', 'put', 'read', 'reads', 'real', 'receive', 'remove', 'rename', 'repl', 'reverse',
+ 'right', 'rmdir', 'rtod', 'runerr', 'seek', 'select', 'send', 'seq', 'serial', 'set',
+ 'setenv', 'sort', 'sortf', 'sql', 'sqrt', 'stat', 'stop', 'string', 'system', 'tab',
+ 'table', 'tan', 'trap', 'trim', 'truncate', 'type', 'upto', 'utime', 'variable', 'where',
+ 'write', 'writes'
+ ),
+ 5 => array(
+ 'Active', 'Alert', 'Bg', 'Clip', 'Clone', 'Color', 'ColorValue',
+ 'CopyArea', 'Couple', 'DrawArc', 'DrawCircle', 'DrawCurve', 'DrawCylinder', 'DrawDisk',
+ 'DrawImage', 'DrawLine', 'DrawPoint', 'DrawPolygon', 'DrawRectangle', 'DrawSegment',
+ 'DrawSphere', 'DrawString', 'DrawTorus', 'EraseArea', 'Event', 'Fg', 'FillArc',
+ 'FillCircle', 'FillPolygon', 'FillRectangle', 'Font', 'FreeColor', 'GotoRC', 'GotoXY',
+ 'IdentifyMatrix', 'Lower', 'MatrixMode', 'NewColor', 'PaletteChars', 'PaletteColor',
+ 'PaletteKey', 'Pattern', 'Pending', 'Pixel', 'PopMatrix', 'PushMatrix', 'PushRotate',
+ 'PushScale', 'PushTranslate', 'QueryPointer', 'Raise', 'ReadImage', 'Refresh', 'Rotate',
+ 'Scale', 'Texcoord', 'TextWidth', 'Texture', 'Translate', 'Uncouple', 'WAttrib',
+ 'WDefault', 'WFlush', 'WindowContents', 'WriteImage', 'WSync'
+ ),
+ 6 => array(
+ 'define', 'include', 'ifdef', 'ifndef', 'else', 'endif', 'error',
+ 'line', 'undef'
+ ),
+ 7 => array(
+ '_V9', '_AMIGA', '_ACORN', '_CMS', '_MACINTOSH', '_MSDOS_386',
+ '_MS_WINDOWS_NT', '_MSDOS', '_MVS', '_OS2', '_POR', 'T', '_UNIX', '_POSIX', '_DBM',
+ '_VMS', '_ASCII', '_EBCDIC', '_CO_EXPRESSIONS', '_CONSOLE_WINDOW', '_DYNAMIC_LOADING',
+ '_EVENT_MONITOR', '_EXTERNAL_FUNCTIONS', '_KEYBOARD_FUNCTIONS', '_LARGE_INTEGERS',
+ '_MULTITASKING', '_PIPES', '_RECORD_IO', '_SYSTEM_FUNCTION', '_MESSAGING', '_GRAPHICS',
+ '_X_WINDOW_SYSTEM', '_MS_WINDOWS', '_WIN32', '_PRESENTATION_MGR', '_ARM_FUNCTIONS',
+ '_DOS_FUNCTIONS'
+ ),
+ 8 => array(
+ 'line'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '(', ')', '{', '}', '[', ']', '+', '-', '*', '/', '\\', '%', '=', '<', '>', '!', '^',
+ '&', '|', '?', ':', ';', ',', '.', '~', '@'
+ ),
+ 2 => array(
+ '$(', '$)', '$<', '$>', '$'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #b1b100;',
+ 3 => 'color: #b1b100;',
+ 4 => 'color: #b1b100;',
+ 5 => 'color: #b1b100;',
+ 6 => 'color: #b1b100;',
+ 7 => 'color: #b1b100;',
+ 8 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #339933;',
+ 2 => 'color: #b1b100;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(1 => '.'),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 3 => array(
+ 'DISALLOWED_BEFORE' => '(?<=&amp;)'
+ ),
+ 4 => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9_\"\'])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_\"\'])"
+ ),
+ 6 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\$)'
+ ),
+ 8 => array(
+ 'DISALLOWED_BEFORE' => '(?<=#)'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/idl.php b/platform/www/vendor/geshi/geshi/src/geshi/idl.php
new file mode 100644
index 0000000..e7596ce
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/idl.php
@@ -0,0 +1,121 @@
+<?php
+/*************************************************************************************
+ * idl.php
+ * -------
+ * Author: Cedric Bosdonnat (cedricbosdo@openoffice.org)
+ * Copyright: (c) 2006 Cedric Bosdonnat
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/08/20
+ *
+ * Unoidl language file for GeSHi.
+ *
+ * 2006/08/20 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+
+$language_data = array (
+ 'LANG_NAME' => 'Uno Idl',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'published', 'get', 'set', 'service', 'singleton', 'type', 'module', 'interface', 'struct',
+ 'const', 'constants', 'exception', 'enum', 'raises', 'typedef'
+ ),
+ 2 => array(
+ 'bound', 'maybeambiguous', 'maybedefault', 'maybevoid', 'oneway', 'optional',
+ 'readonly', 'in', 'out', 'inout', 'attribute', 'transient', 'removable'
+ ),
+ 3 => array(
+ 'True', 'False', 'TRUE', 'FALSE'
+ ),
+ 4 => array(
+ 'string', 'long', 'byte', 'hyper', 'boolean', 'any', 'char', 'double',
+ 'void', 'sequence', 'unsigned'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':', ';', '...'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #990078; font-weight: bold',
+ 2 => 'color: #36dd1c;',
+ 3 => 'color: #990078; font-weight: bold',
+ 4 => 'color: #0000ec;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #3f7f5f;',
+ 2 => 'color: #808080;',
+ 'MULTI' => 'color: #4080ff; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #666666; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #808080;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/ini.php b/platform/www/vendor/geshi/geshi/src/geshi/ini.php
new file mode 100644
index 0000000..bf25d4b
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/ini.php
@@ -0,0 +1,127 @@
+<?php
+/*************************************************************************************
+ * ini.php
+ * --------
+ * Author: deguix (cevo_deguix@yahoo.com.br)
+ * Copyright: (c) 2005 deguix
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/03/27
+ *
+ * INI language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2005/12/28 (1.0.1)
+ * - Removed unnecessary keyword style index
+ * - Added support for " strings
+ * 2005/04/05 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2005/03/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'INI',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(0 => '/^\s*;.*?$/m'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'"),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => ''
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #933;'
+ ),
+ 'NUMBERS' => array(
+ 0 => ''
+ ),
+ 'METHODS' => array(
+ 0 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066; font-weight:bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #000066; font-weight:bold;',
+ 1 => 'color: #000099;',
+ 2 => 'color: #660066;'
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Section names
+ 0 => '\[.+\]',
+ //Entry names
+ 1 => array(
+ GESHI_SEARCH => '^(\s*)([a-zA-Z0-9_\-]+)(\s*=)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ //Entry values
+ 2 => array(
+ // Evil hackery to get around GeSHi bug: <>" and ; are added so <span>s can be matched
+ // Explicit match on variable names because if a comment is before the first < of the span
+ // gets chewed up...
+ GESHI_SEARCH => '([<>";a-zA-Z0-9_]+\s*)=(.*)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1=',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/inno.php b/platform/www/vendor/geshi/geshi/src/geshi/inno.php
new file mode 100644
index 0000000..32202af
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/inno.php
@@ -0,0 +1,210 @@
+<?php
+/*************************************************************************************
+ * Inno.php
+ * ----------
+ * Author: Thomas Klingler (hotline@theratech.de) based on delphi.php from J�rja Norbert (jnorbi@vipmail.hu)
+ * Copyright: (c) 2004 J�rja Norbert, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/07/29
+ *
+ * Inno Script language inkl. Delphi (Object Pascal) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/09/03
+ * - First Release
+ *
+ * TODO (updated 2005/07/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Inno',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('(*' => '*)'),
+ 'CASE_KEYWORDS' => 0,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'Setup','Types','Components','Tasks','Dirs','Files','Icons','INI',
+ 'InstallDelete','Languages','Messages','CustomMessage',
+ 'LangOptions','Registry','RUN','UninstallDelete','UninstallRun',
+ 'app','win','sys','syswow64','src','sd','pf','pf32','pf64','cf',
+ 'cf32','cf64','tmp','fonts','dao','group','localappdata','sendto',
+ 'userappdata','commonappdata','userdesktop','commondesktop',
+ 'userdocs','commondocs','userfavorites','commonfavorites',
+ 'userprograms','commonprograms','userstartmenu','commonstartmenu',
+ 'userstartup','commonstartup','usertemplates','commontemplates'
+ ),
+ 2 => array(
+ 'nil', 'false', 'true', 'var', 'type', 'const','And', 'Array', 'As', 'Begin', 'Case', 'Class', 'Constructor', 'Destructor', 'Div', 'Do', 'DownTo', 'Else',
+ 'End', 'Except', 'File', 'Finally', 'For', 'Function', 'Goto', 'If', 'Implementation', 'In', 'Inherited', 'Interface',
+ 'Is', 'Mod', 'Not', 'Object', 'Of', 'On', 'Or', 'Packed', 'Procedure', 'Property', 'Raise', 'Record',
+ 'Repeat', 'Set', 'Shl', 'Shr', 'Then', 'ThreadVar', 'To', 'Try', 'Unit', 'Until', 'Uses', 'While', 'With', 'Xor',
+
+ 'HKCC','HKCR','HKCU','HKLM','HKU','alwaysoverwrite','alwaysskipifsameorolder','append',
+ 'binary','classic','closeonexit','comparetimestamp','confirmoverwrite',
+ 'createkeyifdoesntexist','createonlyiffileexists','createvalueifdoesntexist',
+ 'deleteafterinstall','deletekey','deletevalue','dirifempty','dontcloseonexit',
+ 'dontcopy','dontcreatekey','disablenouninstallwarning','dword','exclusive','expandsz',
+ 'external','files','filesandordirs','fixed','fontisnttruetype','ignoreversion','iscustom','isreadme',
+ 'modern','multisz','new','noerror','none','normal','nowait','onlyifdestfileexists',
+ 'onlyifdoesntexist','onlyifnewer','overwrite','overwritereadonly','postinstall',
+ 'preservestringtype','promptifolder','regserver','regtypelib','restart','restartreplace',
+ 'runhidden','runmaximized','runminimized','sharedfile','shellexec','showcheckbox',
+ 'skipifnotsilent','skipifsilent','silent','skipifdoesntexist',
+ 'skipifsourcedoesntexist','sortfilesbyextension','unchecked','uninsalwaysuninstall',
+ 'uninsclearvalue','uninsdeleteentry','uninsdeletekey','uninsdeletekeyifempty',
+ 'uninsdeletesection','uninsdeletesectionifempty','uninsdeletevalue',
+ 'uninsneveruninstall','useapppaths','verysilent','waituntilidle'
+ ),
+ 3 => array(
+ 'Abs', 'Addr', 'AnsiCompareStr', 'AnsiCompareText', 'AnsiContainsStr', 'AnsiEndsStr', 'AnsiIndexStr', 'AnsiLeftStr',
+ 'AnsiLowerCase', 'AnsiMatchStr', 'AnsiMidStr', 'AnsiPos', 'AnsiReplaceStr', 'AnsiReverseString', 'AnsiRightStr',
+ 'AnsiStartsStr', 'AnsiUpperCase', 'ArcCos', 'ArcSin', 'ArcTan', 'Assigned', 'BeginThread', 'Bounds', 'CelsiusToFahrenheit',
+ 'ChangeFileExt', 'Chr', 'CompareStr', 'CompareText', 'Concat', 'Convert', 'Copy', 'Cos', 'CreateDir', 'CurrToStr',
+ 'CurrToStrF', 'Date', 'DateTimeToFileDate', 'DateTimeToStr', 'DateToStr', 'DayOfTheMonth', 'DayOfTheWeek', 'DayOfTheYear',
+ 'DayOfWeek', 'DaysBetween', 'DaysInAMonth', 'DaysInAYear', 'DaySpan', 'DegToRad', 'DeleteFile', 'DiskFree', 'DiskSize',
+ 'DupeString', 'EncodeDate', 'EncodeDateTime', 'EncodeTime', 'EndOfADay', 'EndOfAMonth', 'Eof', 'Eoln', 'Exp', 'ExtractFileDir',
+ 'ExtractFileDrive', 'ExtractFileExt', 'ExtractFileName', 'ExtractFilePath', 'FahrenheitToCelsius', 'FileAge',
+ 'FileDateToDateTime', 'FileExists', 'FilePos', 'FileSearch', 'FileSetDate', 'FileSize', 'FindClose', 'FindCmdLineSwitch',
+ 'FindFirst', 'FindNext', 'FloatToStr', 'FloatToStrF', 'Format', 'FormatCurr', 'FormatDateTime', 'FormatFloat', 'Frac',
+ 'GetCurrentDir', 'GetLastError', 'GetMem', 'High', 'IncDay', 'IncMinute', 'IncMonth', 'IncYear', 'InputBox',
+ 'InputQuery', 'Int', 'IntToHex', 'IntToStr', 'IOResult', 'IsInfinite', 'IsLeapYear', 'IsMultiThread', 'IsNaN',
+ 'LastDelimiter', 'Length', 'Ln', 'Lo', 'Log10', 'Low', 'LowerCase', 'Max', 'Mean', 'MessageDlg', 'MessageDlgPos',
+ 'MonthOfTheYear', 'Now', 'Odd', 'Ord', 'ParamCount', 'ParamStr', 'Pi', 'Point', 'PointsEqual', 'Pos', 'Pred',
+ 'Printer', 'PromptForFileName', 'PtInRect', 'RadToDeg', 'Random', 'RandomRange', 'RecodeDate', 'RecodeTime', 'Rect',
+ 'RemoveDir', 'RenameFile', 'Round', 'SeekEof', 'SeekEoln', 'SelectDirectory', 'SetCurrentDir', 'Sin', 'SizeOf',
+ 'Slice', 'Sqr', 'Sqrt', 'StringOfChar', 'StringReplace', 'StringToWideChar', 'StrToCurr', 'StrToDate', 'StrToDateTime',
+ 'StrToFloat', 'StrToInt', 'StrToInt64', 'StrToInt64Def', 'StrToIntDef', 'StrToTime', 'StuffString', 'Succ', 'Sum', 'Tan',
+ 'Time', 'TimeToStr', 'Tomorrow', 'Trunc', 'UpCase', 'UpperCase', 'VarType', 'WideCharToString', 'WrapText', 'Yesterday',
+ 'Append', 'AppendStr', 'Assign', 'AssignFile', 'AssignPrn', 'Beep', 'BlockRead', 'BlockWrite', 'Break',
+ 'ChDir', 'Close', 'CloseFile', 'Continue', 'DateTimeToString', 'Dec', 'DecodeDate', 'DecodeDateTime',
+ 'DecodeTime', 'Delete', 'Dispose', 'EndThread', 'Erase', 'Exclude', 'Exit', 'FillChar', 'Flush', 'FreeAndNil',
+ 'FreeMem', 'GetDir', 'GetLocaleFormatSettings', 'Halt', 'Inc', 'Include', 'Insert', 'MkDir', 'Move', 'New',
+ 'ProcessPath', 'Randomize', 'Read', 'ReadLn', 'ReallocMem', 'Rename', 'ReplaceDate', 'ReplaceTime',
+ 'Reset', 'ReWrite', 'RmDir', 'RunError', 'Seek', 'SetLength', 'SetString', 'ShowMessage', 'ShowMessageFmt',
+ 'ShowMessagePos', 'Str', 'Truncate', 'Val', 'Write', 'WriteLn',
+
+ 'AdminPrivilegesRequired','AfterInstall','AllowCancelDuringInstall','AllowNoIcons','AllowRootDirectory','AllowUNCPath','AlwaysRestart','AlwaysShowComponentsList','AlwaysShowDirOnReadyPage','AlwaysShowGroupOnReadyPage ','AlwaysUsePersonalGroup','AppComments','AppContact','AppCopyright','AppendDefaultDirName',
+ 'AppendDefaultGroupName','AppId','AppModifyPath','AppMutex','AppName','AppPublisher',
+ 'AppPublisherURL','AppReadmeFile','AppSupportURL','AppUpdatesURL','AppVerName','AppVersion',
+ 'Attribs','BackColor','BackColor2','BackColorDirection','BackSolid','BeforeInstall',
+ 'ChangesAssociations','ChangesEnvironment','Check','CodeFile','Comment','Compression','CopyMode',
+ 'CreateAppDir','CreateUninstallRegKey','DefaultDirName','DefaultGroupName',
+ 'DefaultUserInfoName','DefaultUserInfoOrg','DefaultUserInfoSerial',
+ 'Description','DestDir','DestName','DirExistsWarning',
+ 'DisableDirPage','DisableFinishedPage',
+ 'DisableProgramGroupPage','DisableReadyMemo','DisableReadyPage',
+ 'DisableStartupPrompt','DiskClusterSize','DiskSliceSize','DiskSpaceMBLabel',
+ 'DiskSpanning','DontMergeDuplicateFiles','EnableDirDoesntExistWarning','Encryption',
+ 'Excludes','ExtraDiskSpaceRequired','Filename','Flags','FlatComponentsList','FontInstall',
+ 'GroupDescription','HotKey','IconFilename','IconIndex','InfoAfterFile','InfoBeforeFile',
+ 'InternalCompressLevel','Key','LanguageDetectionMethod',
+ 'LicenseFile','MergeDuplicateFiles','MessagesFile','MinVersion','Name',
+ 'OnlyBelowVersion','OutputBaseFilename','OutputManifestFile','OutputDir',
+ 'Parameters','Password','Permissions','PrivilegesRequired','ReserveBytes',
+ 'RestartIfNeededByRun','Root','RunOnceId','Section','SetupIconFile',
+ 'ShowComponentSizes','ShowLanguageDialog','ShowTasksTreeLines','SlicesPerDisk',
+ 'SolidCompression','Source','SourceDir','StatusMsg','Subkey',
+ 'TimeStampRounding','TimeStampsInUTC','TouchDate','TouchTime','Type',
+ 'UninstallDisplayIcon','UninstallDisplayName','UninstallFilesDir','UninstallIconFile',
+ 'UninstallLogMode','UninstallRestartComputer','UninstallStyle','Uninstallable',
+ 'UpdateUninstallLogAppName','UsePreviousAppDir','UsePreviousGroup',
+ 'UsePreviousTasks','UsePreviousSetupType','UsePreviousUserInfo',
+ 'UserInfoPage','UseSetupLdr','ValueData','ValueName','ValueType',
+ 'VersionInfoVersion','VersionInfoCompany','VersionInfoDescription','VersionInfoTextVersion',
+ 'WindowResizable','WindowShowCaption','WindowStartMaximized',
+ 'WindowVisible','WizardImageBackColor','WizardImageFile','WizardImageStretch','WizardSmallImageBackColor','WizardSmallImageFile','WizardStyle','WorkingDir'
+ ),
+ 4 => array(
+ 'AnsiChar', 'AnsiString', 'Boolean', 'Byte', 'Cardinal', 'Char', 'Comp', 'Currency', 'Double', 'Extended',
+ 'Int64', 'Integer', 'LongInt', 'LongWord', 'PAnsiChar', 'PAnsiString', 'PChar', 'PCurrency', 'PDateTime',
+ 'PExtended', 'PInt64', 'Pointer', 'PShortString', 'PString', 'PVariant', 'PWideChar', 'PWideString',
+ 'Real', 'Real48', 'ShortInt', 'ShortString', 'Single', 'SmallInt', 'String', 'TBits', 'TConvType', 'TDateTime',
+ 'Text', 'TextFile', 'TFloatFormat', 'TFormatSettings', 'TList', 'TObject', 'TOpenDialog', 'TPoint',
+ 'TPrintDialog', 'TRect', 'TReplaceFlags', 'TSaveDialog', 'TSearchRec', 'TStringList', 'TSysCharSet',
+ 'TThreadFunc', 'Variant', 'WideChar', 'WideString', 'Word'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '@', '%', '&', '*', '|', '/', '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',/*bold Black*/
+ 2 => 'color: #000000;font-style: italic;',/*Black*/
+ 3 => 'color: #0000FF;',/*blue*/
+ 4 => 'color: #CC0000;'/*red*/
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #33FF00; font-style: italic;',
+ 'MULTI' => 'color: #33FF00; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000; font-weight: bold;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/intercal.php b/platform/www/vendor/geshi/geshi/src/geshi/intercal.php
new file mode 100644
index 0000000..5702d91
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/intercal.php
@@ -0,0 +1,120 @@
+<?php
+/*************************************************************************************
+ * intercal.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/10/31
+ *
+ * INTERCAL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/31 (1.0.8.1)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+$language_data = array (
+ 'LANG_NAME' => 'INTERCAL',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ //Politeness
+ 1 => array(
+ 'DO', 'DOES', 'DONT', 'DON\'T', 'NOT', 'PLEASE', 'PLEASENT', 'PLEASEN\'T', 'MAYBE'
+ ),
+ //Statements
+ 2 => array(
+ 'STASH', 'RETRIEVE', 'NEXT', 'RESUME', 'FORGET', 'ABSTAIN', 'ABSTAINING',
+ 'COME', 'FROM', 'CALCULATING', 'REINSTATE', 'IGNORE', 'REMEMBER',
+ 'WRITE', 'IN', 'READ', 'OUT', 'GIVE', 'UP'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '.', ',', ':', ';', '#',
+ '~', '$', '&', '?',
+ '\'', '"', '<-'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000080; font-weight: bold;',
+ 2 => 'color: #000080; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #808080; font-style: italic;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 1 => '^\(\d+\)'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'COMMENTS' => GESHI_NEVER,
+ 'STRINGS' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/io.php b/platform/www/vendor/geshi/geshi/src/geshi/io.php
new file mode 100644
index 0000000..ce1c0e9
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/io.php
@@ -0,0 +1,136 @@
+<?php
+/*************************************************************************************
+ * io.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2006 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/09/23
+ *
+ * Io language file for GeSHi. Thanks to Johnathan Wright for the suggestion and help
+ * with this language :)
+ *
+ * CHANGES
+ * -------
+ * 2006/09/23(1.0.0)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Io',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'and', 'break', 'else', 'elseif', 'exit', 'for', 'foreach', 'if', 'ifFalse', 'ifNil',
+ 'ifTrue', 'or', 'pass', 'raise', 'return', 'then', 'try', 'wait', 'while', 'yield'
+ ),
+ 2 => array(
+ 'activate', 'activeCoroCount', 'asString', 'block', 'catch', 'clone', 'collectGarbage',
+ 'compileString', 'continue', 'do', 'doFile', 'doMessage', 'doString', 'forward',
+ 'getSlot', 'getenv', 'hasSlot', 'isActive', 'isNil', 'isResumable', 'list', 'message',
+ 'method', 'parent', 'pause', 'perform', 'performWithArgList', 'print', 'proto',
+ 'raiseResumable', 'removeSlot', 'resend', 'resume', 'schedulerSleepSeconds', 'self',
+ 'sender', 'setSchedulerSleepSeconds', 'setSlot', 'shallowCopy', 'slotNames', 'super',
+ 'system', 'thisBlock', 'thisContext', 'thisMessage', 'type', 'uniqueId', 'updateSlot',
+ 'write'
+ ),
+ 3 => array(
+ 'Array', 'AudioDevice', 'AudioMixer', 'Block', 'Box', 'Buffer', 'CFunction', 'CGI',
+ 'Color', 'Curses', 'DBM', 'DNSResolver', 'DOConnection', 'DOProxy', 'DOServer',
+ 'Date', 'Directory', 'Duration', 'DynLib', 'Error', 'Exception', 'FFT', 'File',
+ 'Fnmatch', 'Font', 'Future', 'GL', 'GLE', 'GLScissor', 'GLU', 'GLUCylinder',
+ 'GLUQuadric', 'GLUSphere', 'GLUT', 'Host', 'Image', 'Importer', 'LinkList', 'List',
+ 'Lobby', 'Locals', 'MD5', 'MP3Decoder', 'MP3Encoder', 'Map', 'Message', 'Movie',
+ 'NULL', 'Nil', 'Nop', 'Notifiction', 'Number', 'Object', 'OpenGL', 'Point', 'Protos',
+ 'Regex', 'SGMLTag', 'SQLite', 'Server', 'ShowMessage', 'SleepyCat', 'SleepyCatCursor',
+ 'Socket', 'SocketManager', 'Sound', 'Soup', 'Store', 'String', 'Tree', 'UDPSender',
+ 'UDPReceiver', 'URL', 'User', 'Warning', 'WeakLink'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '!', '@', '%', '&', '*', '|', '/', '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/ispfpanel.php b/platform/www/vendor/geshi/geshi/src/geshi/ispfpanel.php
new file mode 100644
index 0000000..37e04b6
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/ispfpanel.php
@@ -0,0 +1,165 @@
+<?php
+/*************************************************************************************
+ * ispfpanel.php
+ * -------------
+ * Author: Ramesh Vishveshwar (ramesh.vishveshwar@gmail.com)
+ * Copyright: (c) 2012 Ramesh Vishveshwar (http://thecodeisclear.in)
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/09/18
+ *
+ * ISPF Panel Definition (MVS) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2011/09/22 (1.0.0)
+ * - First Release
+ *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ISPF Panel',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ // Panel Definition Statements
+ 1 => array(
+ ')CCSID',')PANEL',')ATTR',')ABC',')ABCINIT',')ABCPROC',')BODY',')MODEL',
+ ')AREA',')INIT',')REINIT',')PROC',')FIELD',')HELP',')LIST',')PNTS',')END'
+ ),
+ // File-Tailoring Skeletons
+ 2 => array (
+ ')DEFAULT',')BLANK', ')CM', ')DO', ')DOT', ')ELSE', ')ENDSEL',
+ ')ENDDO', ')ENDDOT', ')IF', ')IM', ')ITERATE', ')LEAVE', ')NOP', ')SEL',
+ ')SET', ')TB', ')TBA'
+ ),
+ // Control Variables
+ 3 => array (
+ '.ALARM','.ATTR','.ATTRCHAR','.AUTOSEL','.CSRPOS','.CSRROW','.CURSOR','.HELP',
+ '.HHELP','.KANA','.MSG','.NRET','.PFKEY','.RESP','.TRAIL','.ZVARS'
+ ),
+ // Keywords
+ 4 => array (
+ 'WINDOW','ALARM','ATTN','BARRIER','HILITE','CAPS',
+ 'CKBOX','CLEAR','CMD','COLOR','COMBO','CSRGRP','CUADYN',
+ 'SKIP','INTENS','AREA','EXTEND',
+ 'DESC','ASIS','VGET','VPUT','JUST','BATSCRD','BATSCRW',
+ 'BDBCS','BDISPMAX','BIT','BKGRND','BREDIMAX','PAD','PADC',
+ 'PAS','CHINESES','CHINESET','DANISH','DATAMOD','DDLIST',
+ 'DEPTH','DUMP','ENGLISH','ERROR','EXIT','EXPAND','FIELD',
+ 'FORMAT','FRENCH','GE','GERMAN','IMAGE','IND','TYPE',
+ 'ITALIAN','JAPANESE','KOREAN','LCOL','LEN','LIND','LISTBOX',
+ 'MODE','NEST','NOJUMP','NOKANA','NUMERIC','OUTLINE','PARM',
+ 'PGM','PORTUGESE','RADIO','RCOL','REP','RIND','ROWS',
+ 'SCALE','SCROLL','SFIHDR','SGERMAN','SIND','SPANISH',
+ 'UPPERENG','WIDTH'
+ ),
+ // Parameters
+ 5 => array (
+ 'ADDPOP','ALPHA','ALPHAB','DYNAMIC','SCRL',
+ 'CCSID','COMMAND','DSNAME','DSNAMEF','DSNAMEFM',
+ 'DSNAMEPQ','DSNAMEQ','EBCDIC','ENBLDUMP','ENUM',// 'EXTEND',
+ 'FI','FILEID','FRAME','GUI','GUISCRD','GUISCRW','HEX',
+ 'HIGH','IDATE','IN','INCLUDE','INPUT','ITIME','JDATE',
+ 'JSTD','KEYLIST','LANG','LEFT','LIST','LISTV','LISTVX',
+ 'LISTX','LMSG','LOGO','LOW','MIX','NAME','NAMEF','NB',
+ 'NEWAPPL','NEWPOOL','NOCHECK','NOLOGO','NON','NONBLANK',
+ 'NULLS','NUM','OFF','ON','OPT','OUT','OUTPUT','PANEL',
+ /* 'PGM',*/'PICT','PICTN','POSITION','TBDISPL','PROFILE',
+ 'QUERY','RANGE','REVERSE','RIGHT','SHARED','SMSG',
+ 'STDDATE','STDTIME','TERMSTAT','TERMTRAC','TEST',
+ 'TESTX','TEXT','TRACE','TRACEX','USCORE','USER',
+ 'USERMOD','WSCMD','WSCMDV'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(',')','=','&',',','*','#','+','&','%','_','-','@','!'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false
+ ),
+ 'STYLES' => array(
+ 'BKGROUND' => 'background-color: #000000; color: #00FFFF;',
+ 'KEYWORDS' => array(
+ 1 => 'color: #FF0000;',
+ 2 => 'color: #21A502;',
+ 3 => 'color: #FF00FF;',
+ 4 => 'color: #876C00;',
+ 5 => 'color: #00FF00;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #002EB8; font-style: italic;',
+ //1 => 'color: #002EB8; font-style: italic;',
+ //2 => 'color: #002EB8; font-style: italic;',
+ 'MULTI' => 'color: #002EB8; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #FF7400;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #700000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF6633;'
+ ),
+ 'METHODS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #FF7400;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #6B1F6B;'
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ // Variables Defined in the Panel
+ 0 => '&amp;[a-zA-Z]{1,8}[0-9]{0,}',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/j.php b/platform/www/vendor/geshi/geshi/src/geshi/j.php
new file mode 100644
index 0000000..c39e54f
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/j.php
@@ -0,0 +1,188 @@
+<?php
+/*************************************************************************************
+ * j.php
+ * --------
+ * Author: Ric Sherlock (tikkanz@gmail.com)
+ * Copyright: (c) 2009 Ric Sherlock
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/11/10
+ *
+ * J language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/07/18 (1.0.8.10)
+ * - Infinity and negative infinity recognized as numbers
+ * 2010/03/01 (1.0.8.8)
+ * - Add support for label_xyz. and goto_xyz.
+ * - Fix highlighting of for_i.
+ * - Use alternative method for highlighting for_xyz. construct
+ * 2010/02/14 (1.0.8.7)
+ * - Add support for primitives
+ * 2010/01/12 (1.0.2)
+ * - Use HARDQUOTE for strings
+ * - Highlight open quotes/incomplete strings
+ * - Highlight multi-line comments that use Note
+ * - Refinements for NUMBERS and Argument keywords
+ * - Highlight infinity and neg. infinity using REGEXPS
+ * - Highlight "for_myvar." style Control keyword using REGEXPS
+ * 2009/12/14 (1.0.1)
+ * - Regex for NUMBERS, SYMBOLS for () and turn off BRACKETS
+ * 2009/11/12 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2010/01/27)
+ * -------------------------
+ * * combine keyword categories by using conditional regex statement in PARSER CONTROL?
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'J',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 1 => '/(?<!\w)NB\..*?$/m', //singleline comments NB.
+ 2 => '/(?<=\bNote\b).*?$\s+\)(?:(?!\n)\s)*$/sm', //multiline comments in Note
+ 3 => "/'[^']*?$/m" //incomplete strings/open quotes
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array("'"),
+ 'HARDCHAR' => "'",
+ 'NUMBERS' => array(
+ 0 => '\b(?:_?\d+(?:\.\d+)?(?:x|[bejprx]_?[\da-z]+(?:\.[\da-z]+)?)?|__?)(?![\w\.\:])',
+ ),
+ 'KEYWORDS' => array(
+ //Control words
+ 1 => array(
+ 'assert.', 'break.', 'case.', 'catch.', 'catcht.', 'continue.', 'do.',
+ 'else.', 'elseif.', 'end.', 'fcase.', 'for.', 'goto.', 'if.', 'label.',
+ 'return.', 'select.', 'throw.', 'trap.', 'try.', 'while.', 'whilst.'
+ ),
+ //Arguments
+ 2 => array(
+ 'm', 'n', 'u', 'v', 'x', 'y'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ //Punctuation
+ 0 => array(
+ '(', ')'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ //6 => true,
+ //7 => true,
+ //8 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff; font-weight: bold;',
+ 2 => 'color: #0000cc; font-weight: bold;',
+ //6 => 'color: #000000; font-weight: bold;',
+ //7 => 'color: #000000; font-weight: bold;',
+ //8 => 'color: #000000; font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #666666; font-style: italic; font-weight: bold;',
+ 3 => 'color: #ff00ff; ', //open quote
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 'HARD' => 'font-weight: bold;',
+ 0 => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 'HARD' => 'color: #ff0000;',
+ 0 => 'color: #ff0000;',
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #009999; font-weight: bold;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #009900; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000ff; font-weight: bold;', //for_xyz. - same as kw1
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '', //'http://www.jsoftware.com/help/dictionary/ctrl.htm',
+ 2 => '',
+ //6 => '', //'http://www.jsoftware.com/jwiki/Vocabulary',
+ //7 => '', //'http://www.jsoftware.com/jwiki/Vocabulary',
+ //8 => '', //'http://www.jsoftware.com/jwiki/Vocabulary',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => '\b(for|goto|label)_[a-zA-Z]\w*\.', //for_xyz. - should be kw1
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER,
+ ),
+ 'NUMBERS' => array(
+ 'PRECHECK_RX' => '#[\d_]#', // underscore is valid number
+ ),
+ 'KEYWORDS' => array(
+ //Control words
+ 2 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\w)',
+ 'DISALLOWED_AFTER' => '(?![\w\.\:])',
+ ),
+ //Primtives starting with a symbol (except . or :)
+ 6 => array(
+ 'DISALLOWED_BEFORE' => '(?!K)', // effect should be to allow anything
+ 'DISALLOWED_AFTER' => '(?=.*)',
+ ),
+ //Primtives starting with a letter
+ 7 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\w)',
+ 'DISALLOWED_AFTER' => '(?=.*)',
+ ),
+ //Primtives starting with symbol . or :
+ 8 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\s)',
+ 'DISALLOWED_AFTER' => '(?=.*)',
+ ),
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/java.php b/platform/www/vendor/geshi/geshi/src/geshi/java.php
new file mode 100644
index 0000000..71c2d71
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/java.php
@@ -0,0 +1,980 @@
+<?php
+/*************************************************************************************
+ * java.php
+ * --------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/07/10
+ *
+ * Java language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/25 (1.0.7.22)
+ * - Added highlighting of import and package directives as non-OOP
+ * 2005/12/28 (1.0.4)
+ * - Added instanceof keyword
+ * 2004/11/27 (1.0.3)
+ * - Added support for multiple object splitters
+ * 2004/08/05 (1.0.2)
+ * - Added URL support
+ * - Added keyword "this", as bugs in GeSHi class ironed out
+ * 2004/08/05 (1.0.1)
+ * - Added support for symbols
+ * - Added extra missed keywords
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Compact the class names like the first few have been
+ * and eliminate repeats
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Java',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Import and Package directives (Basic Support only)
+ 2 => '/(?:(?<=import[\\n\\s])|(?<=package[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*([a-zA-Z0-9_]+|\*)(?=[\n\s;])/i',
+ // javadoc comments
+ 3 => '#/\*\*(?![\*\/]).*\*/#sU'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'for', 'foreach', 'if', 'else', 'while', 'do',
+ 'switch', 'case', 'return', 'public',
+ 'private', 'protected', 'extends', 'break', 'class',
+ 'new', 'try', 'catch', 'throws', 'finally', 'implements',
+ 'interface', 'throw', 'final', 'native', 'synchronized', 'this',
+ 'abstract', 'transient', 'instanceof', 'assert', 'continue',
+ 'default', 'enum', 'package', 'static', 'strictfp', 'super',
+ 'volatile', 'const', 'goto', 'import'
+ ),
+ 2 => array(
+ 'null', 'false', 'true'
+ ),
+ 3 => array(
+ 'AbstractAction', 'AbstractBorder', 'AbstractButton',
+ 'AbstractCellEditor', 'AbstractCollection',
+ 'AbstractColorChooserPanel', 'AbstractDocument',
+ 'AbstractDocument.AttributeContext',
+ 'AbstractDocument.Content',
+ 'AbstractDocument.ElementEdit',
+ 'AbstractLayoutCache',
+ 'AbstractLayoutCache.NodeDimensions', 'AbstractList',
+ 'AbstractListModel', 'AbstractMap',
+ 'AbstractMethodError', 'AbstractSequentialList',
+ 'AbstractSet', 'AbstractTableModel',
+ 'AbstractUndoableEdit', 'AbstractWriter',
+ 'AccessControlContext', 'AccessControlException',
+ 'AccessController', 'AccessException', 'Accessible',
+ 'AccessibleAction', 'AccessibleBundle',
+ 'AccessibleComponent', 'AccessibleContext',
+ 'AccessibleHyperlink', 'AccessibleHypertext',
+ 'AccessibleIcon', 'AccessibleObject',
+ 'AccessibleRelation', 'AccessibleRelationSet',
+ 'AccessibleResourceBundle', 'AccessibleRole',
+ 'AccessibleSelection', 'AccessibleState',
+ 'AccessibleStateSet', 'AccessibleTable',
+ 'AccessibleTableModelChange', 'AccessibleText',
+ 'AccessibleValue', 'Acl', 'AclEntry',
+ 'AclNotFoundException', 'Action', 'ActionEvent',
+ 'ActionListener', 'ActionMap', 'ActionMapUIResource',
+ 'Activatable', 'ActivateFailedException',
+ 'ActivationDesc', 'ActivationException',
+ 'ActivationGroup', 'ActivationGroupDesc',
+ 'ActivationGroupDesc.CommandEnvironment',
+ 'ActivationGroupID', 'ActivationID',
+ 'ActivationInstantiator', 'ActivationMonitor',
+ 'ActivationSystem', 'Activator', 'ActiveEvent',
+ 'Adjustable', 'AdjustmentEvent',
+ 'AdjustmentListener', 'Adler32', 'AffineTransform',
+ 'AffineTransformOp', 'AlgorithmParameterGenerator',
+ 'AlgorithmParameterGeneratorSpi',
+ 'AlgorithmParameters', 'AlgorithmParameterSpec',
+ 'AlgorithmParametersSpi', 'AllPermission',
+ 'AlphaComposite', 'AlreadyBound',
+ 'AlreadyBoundException', 'AlreadyBoundHelper',
+ 'AlreadyBoundHolder', 'AncestorEvent',
+ 'AncestorListener', 'Annotation', 'Any', 'AnyHolder',
+ 'AnySeqHelper', 'AnySeqHolder', 'Applet',
+ 'AppletContext', 'AppletInitializer', 'AppletStub',
+ 'ApplicationException', 'Arc2D', 'Arc2D.Double',
+ 'Arc2D.Float', 'Area', 'AreaAveragingScaleFilter',
+ 'ARG_IN', 'ARG_INOUT', 'ARG_OUT',
+ 'ArithmeticException', 'Array',
+ 'ArrayIndexOutOfBoundsException', 'ArrayList',
+ 'Arrays', 'ArrayStoreException', 'AsyncBoxView',
+ 'Attribute', 'AttributedCharacterIterator',
+ 'AttributedCharacterIterator.Attribute',
+ 'AttributedString', 'AttributeInUseException',
+ 'AttributeList', 'AttributeModificationException',
+ 'Attributes', 'Attributes.Name', 'AttributeSet',
+ 'AttributeSet.CharacterAttribute',
+ 'AttributeSet.ColorAttribute',
+ 'AttributeSet.FontAttribute',
+ 'AttributeSet.ParagraphAttribute', 'AudioClip',
+ 'AudioFileFormat', 'AudioFileFormat.Type',
+ 'AudioFileReader', 'AudioFileWriter', 'AudioFormat',
+ 'AudioFormat.Encoding', 'AudioInputStream',
+ 'AudioPermission', 'AudioSystem',
+ 'AuthenticationException',
+ 'AuthenticationNotSupportedException',
+ 'Authenticator', 'Autoscroll', 'AWTError',
+ 'AWTEvent', 'AWTEventListener',
+ 'AWTEventMulticaster', 'AWTException',
+ 'AWTPermission', 'BadKind', 'BadLocationException',
+ 'BAD_CONTEXT', 'BAD_INV_ORDER', 'BAD_OPERATION',
+ 'BAD_PARAM', 'BAD_POLICY', 'BAD_POLICY_TYPE',
+ 'BAD_POLICY_VALUE', 'BAD_TYPECODE', 'BandCombineOp',
+ 'BandedSampleModel', 'BasicArrowButton',
+ 'BasicAttribute', 'BasicAttributes', 'BasicBorders',
+ 'BasicBorders.ButtonBorder',
+ 'BasicBorders.FieldBorder',
+ 'BasicBorders.MarginBorder',
+ 'BasicBorders.MenuBarBorder',
+ 'BasicBorders.RadioButtonBorder',
+ 'BasicBorders.SplitPaneBorder',
+ 'BasicBorders.ToggleButtonBorder',
+ 'BasicButtonListener', 'BasicButtonUI',
+ 'BasicCheckBoxMenuItemUI', 'BasicCheckBoxUI',
+ 'BasicColorChooserUI', 'BasicComboBoxEditor',
+ 'BasicComboBoxEditor.UIResource',
+ 'BasicComboBoxRenderer',
+ 'BasicComboBoxRenderer.UIResource',
+ 'BasicComboBoxUI', 'BasicComboPopup',
+ 'BasicDesktopIconUI', 'BasicDesktopPaneUI',
+ 'BasicDirectoryModel', 'BasicEditorPaneUI',
+ 'BasicFileChooserUI', 'BasicGraphicsUtils',
+ 'BasicHTML', 'BasicIconFactory',
+ 'BasicInternalFrameTitlePane',
+ 'BasicInternalFrameUI', 'BasicLabelUI',
+ 'BasicListUI', 'BasicLookAndFeel', 'BasicMenuBarUI',
+ 'BasicMenuItemUI', 'BasicMenuUI',
+ 'BasicOptionPaneUI',
+ 'BasicOptionPaneUI.ButtonAreaLayout', 'BasicPanelUI',
+ 'BasicPasswordFieldUI', 'BasicPermission',
+ 'BasicPopupMenuSeparatorUI', 'BasicPopupMenuUI',
+ 'BasicProgressBarUI', 'BasicRadioButtonMenuItemUI',
+ 'BasicRadioButtonUI', 'BasicRootPaneUI',
+ 'BasicScrollBarUI', 'BasicScrollPaneUI',
+ 'BasicSeparatorUI', 'BasicSliderUI',
+ 'BasicSplitPaneDivider', 'BasicSplitPaneUI',
+ 'BasicStroke', 'BasicTabbedPaneUI',
+ 'BasicTableHeaderUI', 'BasicTableUI',
+ 'BasicTextAreaUI', 'BasicTextFieldUI',
+ 'BasicTextPaneUI', 'BasicTextUI',
+ 'BasicTextUI.BasicCaret',
+ 'BasicTextUI.BasicHighlighter',
+ 'BasicToggleButtonUI', 'BasicToolBarSeparatorUI',
+ 'BasicToolBarUI', 'BasicToolTipUI', 'BasicTreeUI',
+ 'BasicViewportUI', 'BatchUpdateException',
+ 'BeanContext', 'BeanContextChild',
+ 'BeanContextChildComponentProxy',
+ 'BeanContextChildSupport',
+ 'BeanContextContainerProxy', 'BeanContextEvent',
+ 'BeanContextMembershipEvent',
+ 'BeanContextMembershipListener', 'BeanContextProxy',
+ 'BeanContextServiceAvailableEvent',
+ 'BeanContextServiceProvider',
+ 'BeanContextServiceProviderBeanInfo',
+ 'BeanContextServiceRevokedEvent',
+ 'BeanContextServiceRevokedListener',
+ 'BeanContextServices', 'BeanContextServicesListener',
+ 'BeanContextServicesSupport',
+ 'BeanContextServicesSupport.BCSSServiceProvider',
+ 'BeanContextSupport',
+ 'BeanContextSupport.BCSIterator', 'BeanDescriptor',
+ 'BeanInfo', 'Beans', 'BevelBorder', 'BigDecimal',
+ 'BigInteger', 'BinaryRefAddr', 'BindException',
+ 'Binding', 'BindingHelper', 'BindingHolder',
+ 'BindingIterator', 'BindingIteratorHelper',
+ 'BindingIteratorHolder', 'BindingIteratorOperations',
+ 'BindingListHelper', 'BindingListHolder',
+ 'BindingType', 'BindingTypeHelper',
+ 'BindingTypeHolder', 'BitSet', 'Blob', 'BlockView',
+ 'Book', 'Boolean', 'BooleanControl',
+ 'BooleanControl.Type', 'BooleanHolder',
+ 'BooleanSeqHelper', 'BooleanSeqHolder', 'Border',
+ 'BorderFactory', 'BorderLayout', 'BorderUIResource',
+ 'BorderUIResource.BevelBorderUIResource',
+ 'BorderUIResource.CompoundBorderUIResource',
+ 'BorderUIResource.EmptyBorderUIResource',
+ 'BorderUIResource.EtchedBorderUIResource',
+ 'BorderUIResource.LineBorderUIResource',
+ 'BorderUIResource.MatteBorderUIResource',
+ 'BorderUIResource.TitledBorderUIResource',
+ 'BoundedRangeModel', 'Bounds', 'Box', 'Box.Filler',
+ 'BoxedValueHelper', 'BoxLayout', 'BoxView',
+ 'BreakIterator', 'BufferedImage',
+ 'BufferedImageFilter', 'BufferedImageOp',
+ 'BufferedInputStream', 'BufferedOutputStream',
+ 'BufferedReader', 'BufferedWriter', 'Button',
+ 'ButtonGroup', 'ButtonModel', 'ButtonUI', 'Byte',
+ 'ByteArrayInputStream', 'ByteArrayOutputStream',
+ 'ByteHolder', 'ByteLookupTable', 'Calendar',
+ 'CallableStatement', 'CannotProceed',
+ 'CannotProceedException', 'CannotProceedHelper',
+ 'CannotProceedHolder', 'CannotRedoException',
+ 'CannotUndoException', 'Canvas', 'CardLayout',
+ 'Caret', 'CaretEvent', 'CaretListener', 'CellEditor',
+ 'CellEditorListener', 'CellRendererPane',
+ 'Certificate', 'Certificate.CertificateRep',
+ 'CertificateEncodingException',
+ 'CertificateException',
+ 'CertificateExpiredException', 'CertificateFactory',
+ 'CertificateFactorySpi',
+ 'CertificateNotYetValidException',
+ 'CertificateParsingException',
+ 'ChangedCharSetException', 'ChangeEvent',
+ 'ChangeListener', 'Character', 'Character.Subset',
+ 'Character.UnicodeBlock', 'CharacterIterator',
+ 'CharArrayReader', 'CharArrayWriter',
+ 'CharConversionException', 'CharHolder',
+ 'CharSeqHelper', 'CharSeqHolder', 'Checkbox',
+ 'CheckboxGroup', 'CheckboxMenuItem',
+ 'CheckedInputStream', 'CheckedOutputStream',
+ 'Checksum', 'Choice', 'ChoiceFormat', 'Class',
+ 'ClassCastException', 'ClassCircularityError',
+ 'ClassDesc', 'ClassFormatError', 'ClassLoader',
+ 'ClassNotFoundException', 'Clip', 'Clipboard',
+ 'ClipboardOwner', 'Clob', 'Cloneable',
+ 'CloneNotSupportedException', 'CMMException',
+ 'CodeSource', 'CollationElementIterator',
+ 'CollationKey', 'Collator', 'Collection',
+ 'Collections', 'Color',
+ 'ColorChooserComponentFactory', 'ColorChooserUI',
+ 'ColorConvertOp', 'ColorModel',
+ 'ColorSelectionModel', 'ColorSpace',
+ 'ColorUIResource', 'ComboBoxEditor', 'ComboBoxModel',
+ 'ComboBoxUI', 'ComboPopup', 'CommunicationException',
+ 'COMM_FAILURE', 'Comparable', 'Comparator',
+ 'Compiler', 'CompletionStatus',
+ 'CompletionStatusHelper', 'Component',
+ 'ComponentAdapter', 'ComponentColorModel',
+ 'ComponentEvent', 'ComponentInputMap',
+ 'ComponentInputMapUIResource', 'ComponentListener',
+ 'ComponentOrientation', 'ComponentSampleModel',
+ 'ComponentUI', 'ComponentView', 'Composite',
+ 'CompositeContext', 'CompositeName', 'CompositeView',
+ 'CompoundBorder', 'CompoundControl',
+ 'CompoundControl.Type', 'CompoundEdit',
+ 'CompoundName', 'ConcurrentModificationException',
+ 'ConfigurationException', 'ConnectException',
+ 'ConnectIOException', 'Connection', 'Constructor', 'Container',
+ 'ContainerAdapter', 'ContainerEvent',
+ 'ContainerListener', 'ContentHandler',
+ 'ContentHandlerFactory', 'ContentModel', 'Context',
+ 'ContextList', 'ContextNotEmptyException',
+ 'ContextualRenderedImageFactory', 'Control',
+ 'Control.Type', 'ControlFactory',
+ 'ControllerEventListener', 'ConvolveOp', 'CRC32',
+ 'CRL', 'CRLException', 'CropImageFilter', 'CSS',
+ 'CSS.Attribute', 'CTX_RESTRICT_SCOPE',
+ 'CubicCurve2D', 'CubicCurve2D.Double',
+ 'CubicCurve2D.Float', 'Current', 'CurrentHelper',
+ 'CurrentHolder', 'CurrentOperations', 'Cursor',
+ 'Customizer', 'CustomMarshal', 'CustomValue',
+ 'DatabaseMetaData', 'DataBuffer', 'DataBufferByte',
+ 'DataBufferInt', 'DataBufferShort',
+ 'DataBufferUShort', 'DataFlavor',
+ 'DataFormatException', 'DatagramPacket',
+ 'DatagramSocket', 'DatagramSocketImpl',
+ 'DatagramSocketImplFactory', 'DataInput',
+ 'DataInputStream', 'DataLine', 'DataLine.Info',
+ 'DataOutput', 'DataOutputStream',
+ 'DataTruncation', 'DATA_CONVERSION', 'Date',
+ 'DateFormat', 'DateFormatSymbols', 'DebugGraphics',
+ 'DecimalFormat', 'DecimalFormatSymbols',
+ 'DefaultBoundedRangeModel', 'DefaultButtonModel',
+ 'DefaultCaret', 'DefaultCellEditor',
+ 'DefaultColorSelectionModel', 'DefaultComboBoxModel',
+ 'DefaultDesktopManager', 'DefaultEditorKit',
+ 'DefaultEditorKit.BeepAction',
+ 'DefaultEditorKit.CopyAction',
+ 'DefaultEditorKit.CutAction',
+ 'DefaultEditorKit.DefaultKeyTypedAction',
+ 'DefaultEditorKit.InsertBreakAction',
+ 'DefaultEditorKit.InsertContentAction',
+ 'DefaultEditorKit.InsertTabAction',
+ 'DefaultEditorKit.PasteAction,',
+ 'DefaultFocusManager', 'DefaultHighlighter',
+ 'DefaultHighlighter.DefaultHighlightPainter',
+ 'DefaultListCellRenderer',
+ 'DefaultListCellRenderer.UIResource',
+ 'DefaultListModel', 'DefaultListSelectionModel',
+ 'DefaultMenuLayout', 'DefaultMetalTheme',
+ 'DefaultMutableTreeNode',
+ 'DefaultSingleSelectionModel',
+ 'DefaultStyledDocument',
+ 'DefaultStyledDocument.AttributeUndoableEdit',
+ 'DefaultStyledDocument.ElementSpec',
+ 'DefaultTableCellRenderer',
+ 'DefaultTableCellRenderer.UIResource',
+ 'DefaultTableColumnModel', 'DefaultTableModel',
+ 'DefaultTextUI', 'DefaultTreeCellEditor',
+ 'DefaultTreeCellRenderer', 'DefaultTreeModel',
+ 'DefaultTreeSelectionModel', 'DefinitionKind',
+ 'DefinitionKindHelper', 'Deflater',
+ 'DeflaterOutputStream', 'Delegate', 'DesignMode',
+ 'DesktopIconUI', 'DesktopManager', 'DesktopPaneUI',
+ 'DGC', 'Dialog', 'Dictionary', 'DigestException',
+ 'DigestInputStream', 'DigestOutputStream',
+ 'Dimension', 'Dimension2D', 'DimensionUIResource',
+ 'DirContext', 'DirectColorModel', 'DirectoryManager',
+ 'DirObjectFactory', 'DirStateFactory',
+ 'DirStateFactory.Result', 'DnDConstants', 'Document',
+ 'DocumentEvent', 'DocumentEvent.ElementChange',
+ 'DocumentEvent.EventType', 'DocumentListener',
+ 'DocumentParser', 'DomainCombiner', 'DomainManager',
+ 'DomainManagerOperations', 'Double', 'DoubleHolder',
+ 'DoubleSeqHelper', 'DoubleSeqHolder',
+ 'DragGestureEvent', 'DragGestureListener',
+ 'DragGestureRecognizer', 'DragSource',
+ 'DragSourceContext', 'DragSourceDragEvent',
+ 'DragSourceDropEvent', 'DragSourceEvent',
+ 'DragSourceListener', 'Driver', 'DriverManager',
+ 'DriverPropertyInfo', 'DropTarget',
+ 'DropTarget.DropTargetAutoScroller',
+ 'DropTargetContext', 'DropTargetDragEvent',
+ 'DropTargetDropEvent', 'DropTargetEvent',
+ 'DropTargetListener', 'DSAKey',
+ 'DSAKeyPairGenerator', 'DSAParameterSpec',
+ 'DSAParams', 'DSAPrivateKey', 'DSAPrivateKeySpec',
+ 'DSAPublicKey', 'DSAPublicKeySpec', 'DTD',
+ 'DTDConstants', 'DynamicImplementation', 'DynAny',
+ 'DynArray', 'DynEnum', 'DynFixed', 'DynSequence',
+ 'DynStruct', 'DynUnion', 'DynValue', 'EditorKit',
+ 'Element', 'ElementIterator', 'Ellipse2D',
+ 'Ellipse2D.Double', 'Ellipse2D.Float', 'EmptyBorder',
+ 'EmptyStackException', 'EncodedKeySpec', 'Entity',
+ 'EnumControl', 'EnumControl.Type', 'Enumeration',
+ 'Environment', 'EOFException', 'Error',
+ 'EtchedBorder', 'Event', 'EventContext',
+ 'EventDirContext', 'EventListener',
+ 'EventListenerList', 'EventObject', 'EventQueue',
+ 'EventSetDescriptor', 'Exception',
+ 'ExceptionInInitializerError', 'ExceptionList',
+ 'ExpandVetoException', 'ExportException',
+ 'ExtendedRequest', 'ExtendedResponse',
+ 'Externalizable', 'FeatureDescriptor', 'Field',
+ 'FieldNameHelper', 'FieldPosition', 'FieldView',
+ 'File', 'FileChooserUI', 'FileDescriptor',
+ 'FileDialog', 'FileFilter',
+ 'FileInputStream', 'FilenameFilter', 'FileNameMap',
+ 'FileNotFoundException', 'FileOutputStream',
+ 'FilePermission', 'FileReader', 'FileSystemView',
+ 'FileView', 'FileWriter', 'FilteredImageSource',
+ 'FilterInputStream', 'FilterOutputStream',
+ 'FilterReader', 'FilterWriter',
+ 'FixedHeightLayoutCache', 'FixedHolder',
+ 'FlatteningPathIterator', 'FlavorMap', 'Float',
+ 'FloatControl', 'FloatControl.Type', 'FloatHolder',
+ 'FloatSeqHelper', 'FloatSeqHolder', 'FlowLayout',
+ 'FlowView', 'FlowView.FlowStrategy', 'FocusAdapter',
+ 'FocusEvent', 'FocusListener', 'FocusManager',
+ 'Font', 'FontFormatException', 'FontMetrics',
+ 'FontRenderContext', 'FontUIResource', 'Format',
+ 'FormatConversionProvider', 'FormView', 'Frame',
+ 'FREE_MEM', 'GapContent', 'GeneralPath',
+ 'GeneralSecurityException', 'GlyphJustificationInfo',
+ 'GlyphMetrics', 'GlyphVector', 'GlyphView',
+ 'GlyphView.GlyphPainter', 'GradientPaint',
+ 'GraphicAttribute', 'Graphics', 'Graphics2D',
+ 'GraphicsConfigTemplate', 'GraphicsConfiguration',
+ 'GraphicsDevice', 'GraphicsEnvironment',
+ 'GrayFilter', 'GregorianCalendar',
+ 'GridBagConstraints', 'GridBagLayout', 'GridLayout',
+ 'Group', 'Guard', 'GuardedObject', 'GZIPInputStream',
+ 'GZIPOutputStream', 'HasControls', 'HashMap',
+ 'HashSet', 'Hashtable', 'HierarchyBoundsAdapter',
+ 'HierarchyBoundsListener', 'HierarchyEvent',
+ 'HierarchyListener', 'Highlighter',
+ 'Highlighter.Highlight',
+ 'Highlighter.HighlightPainter', 'HTML',
+ 'HTML.Attribute', 'HTML.Tag', 'HTML.UnknownTag',
+ 'HTMLDocument', 'HTMLDocument.Iterator',
+ 'HTMLEditorKit', 'HTMLEditorKit.HTMLFactory',
+ 'HTMLEditorKit.HTMLTextAction',
+ 'HTMLEditorKit.InsertHTMLTextAction',
+ 'HTMLEditorKit.LinkController',
+ 'HTMLEditorKit.Parser',
+ 'HTMLEditorKit.ParserCallback',
+ 'HTMLFrameHyperlinkEvent', 'HTMLWriter',
+ 'HttpURLConnection', 'HyperlinkEvent',
+ 'HyperlinkEvent.EventType', 'HyperlinkListener',
+ 'ICC_ColorSpace', 'ICC_Profile', 'ICC_ProfileGray',
+ 'ICC_ProfileRGB', 'Icon', 'IconUIResource',
+ 'IconView', 'IdentifierHelper', 'Identity',
+ 'IdentityScope', 'IDLEntity', 'IDLType',
+ 'IDLTypeHelper', 'IDLTypeOperations',
+ 'IllegalAccessError', 'IllegalAccessException',
+ 'IllegalArgumentException',
+ 'IllegalComponentStateException',
+ 'IllegalMonitorStateException',
+ 'IllegalPathStateException', 'IllegalStateException',
+ 'IllegalThreadStateException', 'Image',
+ 'ImageConsumer', 'ImageFilter',
+ 'ImageGraphicAttribute', 'ImageIcon',
+ 'ImageObserver', 'ImageProducer',
+ 'ImagingOpException', 'IMP_LIMIT',
+ 'IncompatibleClassChangeError',
+ 'InconsistentTypeCode', 'IndexColorModel',
+ 'IndexedPropertyDescriptor',
+ 'IndexOutOfBoundsException', 'IndirectionException',
+ 'InetAddress', 'Inflater', 'InflaterInputStream',
+ 'InheritableThreadLocal', 'InitialContext',
+ 'InitialContextFactory',
+ 'InitialContextFactoryBuilder', 'InitialDirContext',
+ 'INITIALIZE', 'Initializer', 'InitialLdapContext',
+ 'InlineView', 'InputContext', 'InputEvent',
+ 'InputMap', 'InputMapUIResource', 'InputMethod',
+ 'InputMethodContext', 'InputMethodDescriptor',
+ 'InputMethodEvent', 'InputMethodHighlight',
+ 'InputMethodListener', 'InputMethodRequests',
+ 'InputStream',
+ 'InputStreamReader', 'InputSubset', 'InputVerifier',
+ 'Insets', 'InsetsUIResource', 'InstantiationError',
+ 'InstantiationException', 'Instrument',
+ 'InsufficientResourcesException', 'Integer',
+ 'INTERNAL', 'InternalError', 'InternalFrameAdapter',
+ 'InternalFrameEvent', 'InternalFrameListener',
+ 'InternalFrameUI', 'InterruptedException',
+ 'InterruptedIOException',
+ 'InterruptedNamingException', 'INTF_REPOS',
+ 'IntHolder', 'IntrospectionException',
+ 'Introspector', 'Invalid',
+ 'InvalidAlgorithmParameterException',
+ 'InvalidAttributeIdentifierException',
+ 'InvalidAttributesException',
+ 'InvalidAttributeValueException',
+ 'InvalidClassException',
+ 'InvalidDnDOperationException',
+ 'InvalidKeyException', 'InvalidKeySpecException',
+ 'InvalidMidiDataException', 'InvalidName',
+ 'InvalidNameException',
+ 'InvalidNameHelper', 'InvalidNameHolder',
+ 'InvalidObjectException',
+ 'InvalidParameterException',
+ 'InvalidParameterSpecException',
+ 'InvalidSearchControlsException',
+ 'InvalidSearchFilterException', 'InvalidSeq',
+ 'InvalidTransactionException', 'InvalidValue',
+ 'INVALID_TRANSACTION', 'InvocationEvent',
+ 'InvocationHandler', 'InvocationTargetException',
+ 'InvokeHandler', 'INV_FLAG', 'INV_IDENT',
+ 'INV_OBJREF', 'INV_POLICY', 'IOException',
+ 'IRObject', 'IRObjectOperations', 'IstringHelper',
+ 'ItemEvent', 'ItemListener', 'ItemSelectable',
+ 'Iterator', 'JApplet', 'JarEntry', 'JarException',
+ 'JarFile', 'JarInputStream', 'JarOutputStream',
+ 'JarURLConnection', 'JButton', 'JCheckBox',
+ 'JCheckBoxMenuItem', 'JColorChooser', 'JComboBox',
+ 'JComboBox.KeySelectionManager', 'JComponent',
+ 'JDesktopPane', 'JDialog', 'JEditorPane',
+ 'JFileChooser', 'JFrame', 'JInternalFrame',
+ 'JInternalFrame.JDesktopIcon', 'JLabel',
+ 'JLayeredPane', 'JList', 'JMenu', 'JMenuBar',
+ 'JMenuItem', 'JobAttributes',
+ 'JobAttributes.DefaultSelectionType',
+ 'JobAttributes.DestinationType',
+ 'JobAttributes.DialogType',
+ 'JobAttributes.MultipleDocumentHandlingType',
+ 'JobAttributes.SidesType', 'JOptionPane', 'JPanel',
+ 'JPasswordField', 'JPopupMenu',
+ 'JPopupMenu.Separator', 'JProgressBar',
+ 'JRadioButton', 'JRadioButtonMenuItem', 'JRootPane',
+ 'JScrollBar', 'JScrollPane', 'JSeparator', 'JSlider',
+ 'JSplitPane', 'JTabbedPane', 'JTable',
+ 'JTableHeader', 'JTextArea', 'JTextComponent',
+ 'JTextComponent.KeyBinding', 'JTextField',
+ 'JTextPane', 'JToggleButton',
+ 'JToggleButton.ToggleButtonModel', 'JToolBar',
+ 'JToolBar.Separator', 'JToolTip', 'JTree',
+ 'JTree.DynamicUtilTreeNode',
+ 'JTree.EmptySelectionModel', 'JViewport', 'JWindow',
+ 'Kernel', 'Key', 'KeyAdapter', 'KeyEvent',
+ 'KeyException', 'KeyFactory', 'KeyFactorySpi',
+ 'KeyListener', 'KeyManagementException', 'Keymap',
+ 'KeyPair', 'KeyPairGenerator', 'KeyPairGeneratorSpi',
+ 'KeySpec', 'KeyStore', 'KeyStoreException',
+ 'KeyStoreSpi', 'KeyStroke', 'Label', 'LabelUI',
+ 'LabelView', 'LastOwnerException',
+ 'LayeredHighlighter',
+ 'LayeredHighlighter.LayerPainter', 'LayoutManager',
+ 'LayoutManager2', 'LayoutQueue', 'LdapContext',
+ 'LdapReferralException', 'Lease',
+ 'LimitExceededException', 'Line', 'Line.Info',
+ 'Line2D', 'Line2D.Double', 'Line2D.Float',
+ 'LineBorder', 'LineBreakMeasurer', 'LineEvent',
+ 'LineEvent.Type', 'LineListener', 'LineMetrics',
+ 'LineNumberInputStream', 'LineNumberReader',
+ 'LineUnavailableException', 'LinkageError',
+ 'LinkedList', 'LinkException', 'LinkLoopException',
+ 'LinkRef', 'List', 'ListCellRenderer',
+ 'ListDataEvent', 'ListDataListener', 'ListIterator',
+ 'ListModel', 'ListResourceBundle',
+ 'ListSelectionEvent', 'ListSelectionListener',
+ 'ListSelectionModel', 'ListUI', 'ListView',
+ 'LoaderHandler', 'Locale', 'LocateRegistry',
+ 'LogStream', 'Long', 'LongHolder',
+ 'LongLongSeqHelper', 'LongLongSeqHolder',
+ 'LongSeqHelper', 'LongSeqHolder', 'LookAndFeel',
+ 'LookupOp', 'LookupTable', 'MalformedLinkException',
+ 'MalformedURLException', 'Manifest', 'Map',
+ 'Map.Entry', 'MARSHAL', 'MarshalException',
+ 'MarshalledObject', 'Math', 'MatteBorder',
+ 'MediaTracker', 'Member', 'MemoryImageSource',
+ 'Menu', 'MenuBar', 'MenuBarUI', 'MenuComponent',
+ 'MenuContainer', 'MenuDragMouseEvent',
+ 'MenuDragMouseListener', 'MenuElement', 'MenuEvent',
+ 'MenuItem', 'MenuItemUI', 'MenuKeyEvent',
+ 'MenuKeyListener', 'MenuListener',
+ 'MenuSelectionManager', 'MenuShortcut',
+ 'MessageDigest', 'MessageDigestSpi', 'MessageFormat',
+ 'MetaEventListener', 'MetalBorders',
+ 'MetalBorders.ButtonBorder',
+ 'MetalBorders.Flush3DBorder',
+ 'MetalBorders.InternalFrameBorder',
+ 'MetalBorders.MenuBarBorder',
+ 'MetalBorders.MenuItemBorder',
+ 'MetalBorders.OptionDialogBorder',
+ 'MetalBorders.PaletteBorder',
+ 'MetalBorders.PopupMenuBorder',
+ 'MetalBorders.RolloverButtonBorder',
+ 'MetalBorders.ScrollPaneBorder',
+ 'MetalBorders.TableHeaderBorder',
+ 'MetalBorders.TextFieldBorder',
+ 'MetalBorders.ToggleButtonBorder',
+ 'MetalBorders.ToolBarBorder', 'MetalButtonUI',
+ 'MetalCheckBoxIcon', 'MetalCheckBoxUI',
+ 'MetalComboBoxButton', 'MetalComboBoxEditor',
+ 'MetalComboBoxEditor.UIResource',
+ 'MetalComboBoxIcon', 'MetalComboBoxUI',
+ 'MetalDesktopIconUI', 'MetalFileChooserUI',
+ 'MetalIconFactory', 'MetalIconFactory.FileIcon16',
+ 'MetalIconFactory.FolderIcon16',
+ 'MetalIconFactory.PaletteCloseIcon',
+ 'MetalIconFactory.TreeControlIcon',
+ 'MetalIconFactory.TreeFolderIcon',
+ 'MetalIconFactory.TreeLeafIcon',
+ 'MetalInternalFrameTitlePane',
+ 'MetalInternalFrameUI', 'MetalLabelUI',
+ 'MetalLookAndFeel', 'MetalPopupMenuSeparatorUI',
+ 'MetalProgressBarUI', 'MetalRadioButtonUI',
+ 'MetalScrollBarUI', 'MetalScrollButton',
+ 'MetalScrollPaneUI', 'MetalSeparatorUI',
+ 'MetalSliderUI', 'MetalSplitPaneUI',
+ 'MetalTabbedPaneUI', 'MetalTextFieldUI',
+ 'MetalTheme', 'MetalToggleButtonUI',
+ 'MetalToolBarUI', 'MetalToolTipUI', 'MetalTreeUI',
+ 'MetaMessage', 'Method', 'MethodDescriptor',
+ 'MidiChannel', 'MidiDevice', 'MidiDevice.Info',
+ 'MidiDeviceProvider', 'MidiEvent', 'MidiFileFormat',
+ 'MidiFileReader', 'MidiFileWriter', 'MidiMessage',
+ 'MidiSystem', 'MidiUnavailableException',
+ 'MimeTypeParseException', 'MinimalHTMLWriter',
+ 'MissingResourceException', 'Mixer', 'Mixer.Info',
+ 'MixerProvider', 'ModificationItem', 'Modifier',
+ 'MouseAdapter', 'MouseDragGestureRecognizer',
+ 'MouseEvent', 'MouseInputAdapter',
+ 'MouseInputListener', 'MouseListener',
+ 'MouseMotionAdapter', 'MouseMotionListener',
+ 'MultiButtonUI', 'MulticastSocket',
+ 'MultiColorChooserUI', 'MultiComboBoxUI',
+ 'MultiDesktopIconUI', 'MultiDesktopPaneUI',
+ 'MultiFileChooserUI', 'MultiInternalFrameUI',
+ 'MultiLabelUI', 'MultiListUI', 'MultiLookAndFeel',
+ 'MultiMenuBarUI', 'MultiMenuItemUI',
+ 'MultiOptionPaneUI', 'MultiPanelUI',
+ 'MultiPixelPackedSampleModel', 'MultipleMaster',
+ 'MultiPopupMenuUI', 'MultiProgressBarUI',
+ 'MultiScrollBarUI', 'MultiScrollPaneUI',
+ 'MultiSeparatorUI', 'MultiSliderUI',
+ 'MultiSplitPaneUI', 'MultiTabbedPaneUI',
+ 'MultiTableHeaderUI', 'MultiTableUI', 'MultiTextUI',
+ 'MultiToolBarUI', 'MultiToolTipUI', 'MultiTreeUI',
+ 'MultiViewportUI', 'MutableAttributeSet',
+ 'MutableComboBoxModel', 'MutableTreeNode', 'Name',
+ 'NameAlreadyBoundException', 'NameClassPair',
+ 'NameComponent', 'NameComponentHelper',
+ 'NameComponentHolder', 'NamedValue', 'NameHelper',
+ 'NameHolder', 'NameNotFoundException', 'NameParser',
+ 'NamespaceChangeListener', 'NameValuePair',
+ 'NameValuePairHelper', 'Naming', 'NamingContext',
+ 'NamingContextHelper', 'NamingContextHolder',
+ 'NamingContextOperations', 'NamingEnumeration',
+ 'NamingEvent', 'NamingException',
+ 'NamingExceptionEvent', 'NamingListener',
+ 'NamingManager', 'NamingSecurityException',
+ 'NegativeArraySizeException', 'NetPermission',
+ 'NoClassDefFoundError', 'NoInitialContextException',
+ 'NoninvertibleTransformException',
+ 'NoPermissionException', 'NoRouteToHostException',
+ 'NoSuchAlgorithmException',
+ 'NoSuchAttributeException', 'NoSuchElementException',
+ 'NoSuchFieldError', 'NoSuchFieldException',
+ 'NoSuchMethodError', 'NoSuchMethodException',
+ 'NoSuchObjectException', 'NoSuchProviderException',
+ 'NotActiveException', 'NotBoundException',
+ 'NotContextException', 'NotEmpty', 'NotEmptyHelper',
+ 'NotEmptyHolder', 'NotFound', 'NotFoundHelper',
+ 'NotFoundHolder', 'NotFoundReason',
+ 'NotFoundReasonHelper', 'NotFoundReasonHolder',
+ 'NotOwnerException', 'NotSerializableException',
+ 'NO_IMPLEMENT', 'NO_MEMORY', 'NO_PERMISSION',
+ 'NO_RESOURCES', 'NO_RESPONSE',
+ 'NullPointerException', 'Number', 'NumberFormat',
+ 'NumberFormatException', 'NVList', 'Object',
+ 'ObjectChangeListener', 'ObjectFactory',
+ 'ObjectFactoryBuilder', 'ObjectHelper',
+ 'ObjectHolder', 'ObjectImpl',
+ 'ObjectInput', 'ObjectInputStream',
+ 'ObjectInputStream.GetField',
+ 'ObjectInputValidation', 'ObjectOutput',
+ 'ObjectOutputStream', 'ObjectOutputStream.PutField',
+ 'ObjectStreamClass', 'ObjectStreamConstants',
+ 'ObjectStreamException', 'ObjectStreamField',
+ 'ObjectView', 'OBJECT_NOT_EXIST', 'ObjID',
+ 'OBJ_ADAPTER', 'Observable', 'Observer',
+ 'OctetSeqHelper', 'OctetSeqHolder', 'OMGVMCID',
+ 'OpenType', 'Operation',
+ 'OperationNotSupportedException', 'Option',
+ 'OptionalDataException', 'OptionPaneUI', 'ORB',
+ 'OutOfMemoryError', 'OutputStream',
+ 'OutputStreamWriter', 'OverlayLayout', 'Owner',
+ 'Package', 'PackedColorModel', 'Pageable',
+ 'PageAttributes', 'PageAttributes.ColorType',
+ 'PageAttributes.MediaType',
+ 'PageAttributes.OrientationRequestedType',
+ 'PageAttributes.OriginType',
+ 'PageAttributes.PrintQualityType', 'PageFormat',
+ 'Paint', 'PaintContext', 'PaintEvent', 'Panel',
+ 'PanelUI', 'Paper', 'ParagraphView',
+ 'ParameterBlock', 'ParameterDescriptor',
+ 'ParseException', 'ParsePosition', 'Parser',
+ 'ParserDelegator', 'PartialResultException',
+ 'PasswordAuthentication', 'PasswordView', 'Patch',
+ 'PathIterator', 'Permission',
+ 'PermissionCollection', 'Permissions',
+ 'PERSIST_STORE', 'PhantomReference',
+ 'PipedInputStream', 'PipedOutputStream',
+ 'PipedReader', 'PipedWriter', 'PixelGrabber',
+ 'PixelInterleavedSampleModel', 'PKCS8EncodedKeySpec',
+ 'PlainDocument', 'PlainView', 'Point', 'Point2D',
+ 'Point2D.Double', 'Point2D.Float', 'Policy',
+ 'PolicyError', 'PolicyHelper',
+ 'PolicyHolder', 'PolicyListHelper',
+ 'PolicyListHolder', 'PolicyOperations',
+ 'PolicyTypeHelper', 'Polygon', 'PopupMenu',
+ 'PopupMenuEvent', 'PopupMenuListener', 'PopupMenuUI',
+ 'Port', 'Port.Info', 'PortableRemoteObject',
+ 'PortableRemoteObjectDelegate', 'Position',
+ 'Position.Bias', 'PreparedStatement', 'Principal',
+ 'PrincipalHolder', 'Printable',
+ 'PrinterAbortException', 'PrinterException',
+ 'PrinterGraphics', 'PrinterIOException',
+ 'PrinterJob', 'PrintGraphics', 'PrintJob',
+ 'PrintStream', 'PrintWriter', 'PrivateKey',
+ 'PRIVATE_MEMBER', 'PrivilegedAction',
+ 'PrivilegedActionException',
+ 'PrivilegedExceptionAction', 'Process',
+ 'ProfileDataException', 'ProgressBarUI',
+ 'ProgressMonitor', 'ProgressMonitorInputStream',
+ 'Properties', 'PropertyChangeEvent',
+ 'PropertyChangeListener', 'PropertyChangeSupport',
+ 'PropertyDescriptor', 'PropertyEditor',
+ 'PropertyEditorManager', 'PropertyEditorSupport',
+ 'PropertyPermission', 'PropertyResourceBundle',
+ 'PropertyVetoException', 'ProtectionDomain',
+ 'ProtocolException', 'Provider', 'ProviderException',
+ 'Proxy', 'PublicKey', 'PUBLIC_MEMBER',
+ 'PushbackInputStream', 'PushbackReader',
+ 'QuadCurve2D', 'QuadCurve2D.Double',
+ 'QuadCurve2D.Float', 'Random', 'RandomAccessFile',
+ 'Raster', 'RasterFormatException', 'RasterOp',
+ 'Reader', 'Receiver', 'Rectangle', 'Rectangle2D',
+ 'Rectangle2D.Double', 'Rectangle2D.Float',
+ 'RectangularShape', 'Ref', 'RefAddr', 'Reference',
+ 'Referenceable', 'ReferenceQueue',
+ 'ReferralException', 'ReflectPermission', 'Registry',
+ 'RegistryHandler', 'RemarshalException', 'Remote',
+ 'RemoteCall', 'RemoteException', 'RemoteObject',
+ 'RemoteRef', 'RemoteServer', 'RemoteStub',
+ 'RenderableImage', 'RenderableImageOp',
+ 'RenderableImageProducer', 'RenderContext',
+ 'RenderedImage', 'RenderedImageFactory', 'Renderer',
+ 'RenderingHints', 'RenderingHints.Key',
+ 'RepaintManager', 'ReplicateScaleFilter',
+ 'Repository', 'RepositoryIdHelper', 'Request',
+ 'RescaleOp', 'Resolver', 'ResolveResult',
+ 'ResourceBundle', 'ResponseHandler', 'ResultSet',
+ 'ResultSetMetaData', 'ReverbType', 'RGBImageFilter',
+ 'RMIClassLoader', 'RMIClientSocketFactory',
+ 'RMIFailureHandler', 'RMISecurityException',
+ 'RMISecurityManager', 'RMIServerSocketFactory',
+ 'RMISocketFactory', 'Robot', 'RootPaneContainer',
+ 'RootPaneUI', 'RoundRectangle2D',
+ 'RoundRectangle2D.Double', 'RoundRectangle2D.Float',
+ 'RowMapper', 'RSAKey', 'RSAKeyGenParameterSpec',
+ 'RSAPrivateCrtKey', 'RSAPrivateCrtKeySpec',
+ 'RSAPrivateKey', 'RSAPrivateKeySpec', 'RSAPublicKey',
+ 'RSAPublicKeySpec', 'RTFEditorKit',
+ 'RuleBasedCollator', 'Runnable', 'RunTime',
+ 'Runtime', 'RuntimeException', 'RunTimeOperations',
+ 'RuntimePermission', 'SampleModel',
+ 'SchemaViolationException', 'Scrollable',
+ 'Scrollbar', 'ScrollBarUI', 'ScrollPane',
+ 'ScrollPaneConstants', 'ScrollPaneLayout',
+ 'ScrollPaneLayout.UIResource', 'ScrollPaneUI',
+ 'SearchControls', 'SearchResult',
+ 'SecureClassLoader', 'SecureRandom',
+ 'SecureRandomSpi', 'Security', 'SecurityException',
+ 'SecurityManager', 'SecurityPermission', 'Segment',
+ 'SeparatorUI', 'Sequence', 'SequenceInputStream',
+ 'Sequencer', 'Sequencer.SyncMode', 'Serializable',
+ 'SerializablePermission', 'ServantObject',
+ 'ServerCloneException', 'ServerError',
+ 'ServerException', 'ServerNotActiveException',
+ 'ServerRef', 'ServerRequest',
+ 'ServerRuntimeException', 'ServerSocket',
+ 'ServiceDetail', 'ServiceDetailHelper',
+ 'ServiceInformation', 'ServiceInformationHelper',
+ 'ServiceInformationHolder',
+ 'ServiceUnavailableException', 'Set',
+ 'SetOverrideType', 'SetOverrideTypeHelper', 'Shape',
+ 'ShapeGraphicAttribute', 'Short', 'ShortHolder',
+ 'ShortLookupTable', 'ShortMessage', 'ShortSeqHelper',
+ 'ShortSeqHolder', 'Signature', 'SignatureException',
+ 'SignatureSpi', 'SignedObject', 'Signer',
+ 'SimpleAttributeSet', 'SimpleBeanInfo',
+ 'SimpleDateFormat', 'SimpleTimeZone',
+ 'SinglePixelPackedSampleModel',
+ 'SingleSelectionModel', 'SizeLimitExceededException',
+ 'SizeRequirements', 'SizeSequence', 'Skeleton',
+ 'SkeletonMismatchException',
+ 'SkeletonNotFoundException', 'SliderUI', 'Socket',
+ 'SocketException', 'SocketImpl', 'SocketImplFactory',
+ 'SocketOptions', 'SocketPermission',
+ 'SocketSecurityException', 'SoftBevelBorder',
+ 'SoftReference', 'SortedMap', 'SortedSet',
+ 'Soundbank', 'SoundbankReader', 'SoundbankResource',
+ 'SourceDataLine', 'SplitPaneUI', 'SQLData',
+ 'SQLException', 'SQLInput', 'SQLOutput',
+ 'SQLPermission', 'SQLWarning', 'Stack',
+ 'StackOverflowError', 'StateEdit', 'StateEditable',
+ 'StateFactory', 'Statement', 'Streamable',
+ 'StreamableValue', 'StreamCorruptedException',
+ 'StreamTokenizer', 'StrictMath', 'String',
+ 'StringBuffer', 'StringBufferInputStream',
+ 'StringCharacterIterator', 'StringContent',
+ 'StringHolder', 'StringIndexOutOfBoundsException',
+ 'StringReader', 'StringRefAddr', 'StringSelection',
+ 'StringTokenizer', 'StringValueHelper',
+ 'StringWriter', 'Stroke', 'Struct', 'StructMember',
+ 'StructMemberHelper', 'Stub', 'StubDelegate',
+ 'StubNotFoundException', 'Style', 'StyleConstants',
+ 'StyleConstants.CharacterConstants',
+ 'StyleConstants.ColorConstants',
+ 'StyleConstants.FontConstants',
+ 'StyleConstants.ParagraphConstants', 'StyleContext',
+ 'StyledDocument', 'StyledEditorKit',
+ 'StyledEditorKit.AlignmentAction',
+ 'StyledEditorKit.BoldAction',
+ 'StyledEditorKit.FontFamilyAction',
+ 'StyledEditorKit.FontSizeAction',
+ 'StyledEditorKit.ForegroundAction',
+ 'StyledEditorKit.ItalicAction',
+ 'StyledEditorKit.StyledTextAction',
+ 'StyledEditorKit.UnderlineAction', 'StyleSheet',
+ 'StyleSheet.BoxPainter', 'StyleSheet.ListPainter',
+ 'SwingConstants', 'SwingPropertyChangeSupport',
+ 'SwingUtilities', 'SyncFailedException',
+ 'Synthesizer', 'SysexMessage', 'System',
+ 'SystemColor', 'SystemException', 'SystemFlavorMap',
+ 'TabableView', 'TabbedPaneUI', 'TabExpander',
+ 'TableCellEditor', 'TableCellRenderer',
+ 'TableColumn', 'TableColumnModel',
+ 'TableColumnModelEvent', 'TableColumnModelListener',
+ 'TableHeaderUI', 'TableModel', 'TableModelEvent',
+ 'TableModelListener', 'TableUI', 'TableView',
+ 'TabSet', 'TabStop', 'TagElement', 'TargetDataLine',
+ 'TCKind', 'TextAction', 'TextArea', 'TextAttribute',
+ 'TextComponent', 'TextEvent', 'TextField',
+ 'TextHitInfo', 'TextLayout',
+ 'TextLayout.CaretPolicy', 'TextListener',
+ 'TextMeasurer', 'TextUI', 'TexturePaint', 'Thread',
+ 'ThreadDeath', 'ThreadGroup', 'ThreadLocal',
+ 'Throwable', 'Tie', 'TileObserver', 'Time',
+ 'TimeLimitExceededException', 'Timer',
+ 'TimerTask', 'Timestamp', 'TimeZone', 'TitledBorder',
+ 'ToolBarUI', 'Toolkit', 'ToolTipManager',
+ 'ToolTipUI', 'TooManyListenersException', 'Track',
+ 'TransactionRequiredException',
+ 'TransactionRolledbackException',
+ 'TRANSACTION_REQUIRED', 'TRANSACTION_ROLLEDBACK',
+ 'Transferable', 'TransformAttribute', 'TRANSIENT',
+ 'Transmitter', 'Transparency', 'TreeCellEditor',
+ 'TreeCellRenderer', 'TreeExpansionEvent',
+ 'TreeExpansionListener', 'TreeMap', 'TreeModel',
+ 'TreeModelEvent', 'TreeModelListener', 'TreeNode',
+ 'TreePath', 'TreeSelectionEvent',
+ 'TreeSelectionListener', 'TreeSelectionModel',
+ 'TreeSet', 'TreeUI', 'TreeWillExpandListener',
+ 'TypeCode', 'TypeCodeHolder', 'TypeMismatch',
+ 'Types', 'UID', 'UIDefaults',
+ 'UIDefaults.ActiveValue', 'UIDefaults.LazyInputMap',
+ 'UIDefaults.LazyValue', 'UIDefaults.ProxyLazyValue',
+ 'UIManager', 'UIManager.LookAndFeelInfo',
+ 'UIResource', 'ULongLongSeqHelper',
+ 'ULongLongSeqHolder', 'ULongSeqHelper',
+ 'ULongSeqHolder', 'UndeclaredThrowableException',
+ 'UndoableEdit', 'UndoableEditEvent',
+ 'UndoableEditListener', 'UndoableEditSupport',
+ 'UndoManager', 'UnexpectedException',
+ 'UnicastRemoteObject', 'UnionMember',
+ 'UnionMemberHelper', 'UNKNOWN', 'UnknownError',
+ 'UnknownException', 'UnknownGroupException',
+ 'UnknownHostException',
+ 'UnknownObjectException', 'UnknownServiceException',
+ 'UnknownUserException', 'UnmarshalException',
+ 'UnrecoverableKeyException', 'Unreferenced',
+ 'UnresolvedPermission', 'UnsatisfiedLinkError',
+ 'UnsolicitedNotification',
+ 'UnsolicitedNotificationEvent',
+ 'UnsolicitedNotificationListener',
+ 'UnsupportedAudioFileException',
+ 'UnsupportedClassVersionError',
+ 'UnsupportedEncodingException',
+ 'UnsupportedFlavorException',
+ 'UnsupportedLookAndFeelException',
+ 'UnsupportedOperationException',
+ 'UNSUPPORTED_POLICY', 'UNSUPPORTED_POLICY_VALUE',
+ 'URL', 'URLClassLoader', 'URLConnection',
+ 'URLDecoder', 'URLEncoder', 'URLStreamHandler',
+ 'URLStreamHandlerFactory', 'UserException',
+ 'UShortSeqHelper', 'UShortSeqHolder',
+ 'UTFDataFormatException', 'Util', 'UtilDelegate',
+ 'Utilities', 'ValueBase', 'ValueBaseHelper',
+ 'ValueBaseHolder', 'ValueFactory', 'ValueHandler',
+ 'ValueMember', 'ValueMemberHelper',
+ 'VariableHeightLayoutCache', 'Vector', 'VerifyError',
+ 'VersionSpecHelper', 'VetoableChangeListener',
+ 'VetoableChangeSupport', 'View', 'ViewFactory',
+ 'ViewportLayout', 'ViewportUI',
+ 'VirtualMachineError', 'Visibility',
+ 'VisibilityHelper', 'VMID', 'VM_ABSTRACT',
+ 'VM_CUSTOM', 'VM_NONE', 'VM_TRUNCATABLE',
+ 'VoiceStatus', 'Void', 'WCharSeqHelper',
+ 'WCharSeqHolder', 'WeakHashMap', 'WeakReference',
+ 'Window', 'WindowAdapter', 'WindowConstants',
+ 'WindowEvent', 'WindowListener', 'WrappedPlainView',
+ 'WritableRaster', 'WritableRenderedImage',
+ 'WriteAbortedException', 'Writer',
+ 'WrongTransaction', 'WStringValueHelper',
+ 'X509Certificate', 'X509CRL', 'X509CRLEntry',
+ 'X509EncodedKeySpec', 'X509Extension', 'ZipEntry',
+ 'ZipException', 'ZipFile', 'ZipInputStream',
+ 'ZipOutputStream', 'ZoneView',
+ '_BindingIteratorImplBase', '_BindingIteratorStub',
+ '_IDLTypeStub', '_NamingContextImplBase',
+ '_NamingContextStub', '_PolicyStub', '_Remote_Stub'
+ ),
+ 4 => array(
+ 'void', 'double', 'int', 'boolean', 'byte', 'short', 'long', 'char', 'float'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}',
+ '+', '-', '*', '/', '%',
+ '!', '&', '|', '^',
+ '<', '>', '=',
+ '?', ':', ';',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => true,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000066; font-weight: bold;',
+ 3 => 'color: #003399;',
+ 4 => 'color: #000066; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #006699;',
+ 3 => 'color: #008000; font-style: italic; font-weight: bold;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006633;',
+ 2 => 'color: #006633;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+{FNAMEL}',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/java5.php b/platform/www/vendor/geshi/geshi/src/geshi/java5.php
new file mode 100644
index 0000000..fbd0e30
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/java5.php
@@ -0,0 +1,1035 @@
+<?php
+/*************************************************************************************
+ * java.php
+ * --------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/07/10
+ *
+ * Java language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/25 (1.0.7.22)
+ * - Added highlighting of import and package directives as non-OOP
+ * 2005/12/28 (1.0.4)
+ * - Added instanceof keyword
+ * 2004/11/27 (1.0.3)
+ * - Added support for multiple object splitters
+ * 2004/08/05 (1.0.2)
+ * - Added URL support
+ * - Added keyword "this", as bugs in GeSHi class ironed out
+ * 2004/08/05 (1.0.1)
+ * - Added support for symbols
+ * - Added extra missed keywords
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ * *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Java(TM) 2 Platform Standard Edition 5.0',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Import and Package directives (Basic Support only)
+ 2 => '/(?:(?<=import[\\n\\s](?!static))|(?<=import[\\n\\s]static[\\n\\s])|(?<=package[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*([a-zA-Z0-9_]+|\*)(?=[\n\s;])/i',
+ // javadoc comments
+ 3 => '#/\*\*(?![\*\/]).*\*/#sU'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ /* see the authoritative list of all 50 Java keywords at */
+ /* http://java.sun.com/docs/books/jls/third_edition/html/lexical.html#229308 */
+
+ /* java keywords, part 1: control flow */
+ 'case', 'default', 'do', 'else', 'for',
+ 'goto', 'if', 'switch', 'while'
+
+ /* IMO 'break', 'continue', 'return' and 'throw' */
+ /* should also be added to this group, as they */
+ /* also manage the control flow, */
+ /* arguably 'try'/'catch'/'finally' as well */
+ ),
+ 2 => array(
+ /* java keywords, part 2 */
+
+ 'break', 'continue', 'return', 'throw',
+ 'try', 'catch', 'finally',
+
+ 'abstract', 'assert', 'class', 'const', 'enum', 'extends',
+ 'final', 'implements', 'import', 'instanceof', 'interface',
+ 'native', 'new', 'package', 'private', 'protected',
+ 'public', 'static', 'strictfp', 'super', 'synchronized',
+ 'this', 'throws', 'transient', 'volatile'
+ ),
+ 3 => array(
+ /* Java keywords, part 3: primitive data types and 'void' */
+ 'boolean', 'byte', 'char', 'double',
+ 'float', 'int', 'long', 'short', 'void'
+ ),
+ 4 => array(
+ /* other reserved words in Java: literals */
+ /* should be styled to look similar to numbers and Strings */
+ 'false', 'null', 'true'
+ ),
+ 5 => array (
+ 'Applet', 'AppletContext', 'AppletStub', 'AudioClip'
+ ),
+ 6 => array (
+ 'AWTError', 'AWTEvent', 'AWTEventMulticaster', 'AWTException', 'AWTKeyStroke', 'AWTPermission', 'ActiveEvent', 'Adjustable', 'AlphaComposite', 'BasicStroke', 'BorderLayout', 'BufferCapabilities', 'BufferCapabilities.FlipContents', 'Button', 'Canvas', 'CardLayout', 'Checkbox', 'CheckboxGroup', 'CheckboxMenuItem', 'Choice', 'Color', 'Component', 'ComponentOrientation', 'Composite', 'CompositeContext', 'Container', 'ContainerOrderFocusTraversalPolicy', 'Cursor', 'DefaultFocusTraversalPolicy', 'DefaultKeyboardFocusManager', 'Dialog', 'Dimension', 'DisplayMode', 'EventQueue', 'FileDialog', 'FlowLayout', 'FocusTraversalPolicy', 'Font', 'FontFormatException', 'FontMetrics', 'Frame', 'GradientPaint', 'Graphics', 'Graphics2D', 'GraphicsConfigTemplate', 'GraphicsConfiguration', 'GraphicsDevice', 'GraphicsEnvironment', 'GridBagConstraints', 'GridBagLayout', 'GridLayout', 'HeadlessException', 'IllegalComponentStateException', 'Image', 'ImageCapabilities', 'Insets', 'ItemSelectable', 'JobAttributes',
+ 'JobAttributes.DefaultSelectionType', 'JobAttributes.DestinationType', 'JobAttributes.DialogType', 'JobAttributes.MultipleDocumentHandlingType', 'JobAttributes.SidesType', 'KeyEventDispatcher', 'KeyEventPostProcessor', 'KeyboardFocusManager', 'Label', 'LayoutManager', 'LayoutManager2', 'MediaTracker', 'Menu', 'MenuBar', 'MenuComponent', 'MenuContainer', 'MenuItem', 'MenuShortcut', 'MouseInfo', 'PageAttributes', 'PageAttributes.ColorType', 'PageAttributes.MediaType', 'PageAttributes.OrientationRequestedType', 'PageAttributes.OriginType', 'PageAttributes.PrintQualityType', 'Paint', 'PaintContext', 'Panel', 'Point', 'PointerInfo', 'Polygon', 'PopupMenu', 'PrintGraphics', 'PrintJob', 'Rectangle', 'RenderingHints', 'RenderingHints.Key', 'Robot', 'ScrollPane', 'ScrollPaneAdjustable', 'Scrollbar', 'Shape', 'Stroke', 'SystemColor', 'TextArea', 'TextComponent', 'TextField', 'TexturePaint', 'Toolkit', 'Transparency', 'Window'
+ ),
+ 7 => array (
+ 'CMMException', 'ColorSpace', 'ICC_ColorSpace', 'ICC_Profile', 'ICC_ProfileGray', 'ICC_ProfileRGB', 'ProfileDataException'
+ ),
+ 8 => array (
+ 'Clipboard', 'ClipboardOwner', 'DataFlavor', 'FlavorEvent', 'FlavorListener', 'FlavorMap', 'FlavorTable', 'MimeTypeParseException', 'StringSelection', 'SystemFlavorMap', 'Transferable', 'UnsupportedFlavorException'
+ ),
+ 9 => array (
+ 'Autoscroll', 'DnDConstants', 'DragGestureEvent', 'DragGestureListener', 'DragGestureRecognizer', 'DragSource', 'DragSourceAdapter', 'DragSourceContext', 'DragSourceDragEvent', 'DragSourceDropEvent', 'DragSourceEvent', 'DragSourceListener', 'DragSourceMotionListener', 'DropTarget', 'DropTarget.DropTargetAutoScroller', 'DropTargetAdapter', 'DropTargetContext', 'DropTargetDragEvent', 'DropTargetDropEvent', 'DropTargetEvent', 'DropTargetListener', 'InvalidDnDOperationException', 'MouseDragGestureRecognizer'
+ ),
+ 10 => array (
+ 'AWTEventListener', 'AWTEventListenerProxy', 'ActionEvent', 'ActionListener', 'AdjustmentEvent', 'AdjustmentListener', 'ComponentAdapter', 'ComponentEvent', 'ComponentListener', 'ContainerAdapter', 'ContainerEvent', 'ContainerListener', 'FocusAdapter', 'FocusEvent', 'FocusListener', 'HierarchyBoundsAdapter', 'HierarchyBoundsListener', 'HierarchyEvent', 'HierarchyListener', 'InputEvent', 'InputMethodEvent', 'InputMethodListener', 'InvocationEvent', 'ItemEvent', 'ItemListener', 'KeyAdapter', 'KeyEvent', 'KeyListener', 'MouseAdapter', 'MouseListener', 'MouseMotionAdapter', 'MouseMotionListener', 'MouseWheelEvent', 'MouseWheelListener', 'PaintEvent', 'TextEvent', 'TextListener', 'WindowAdapter', 'WindowEvent', 'WindowFocusListener', 'WindowListener', 'WindowStateListener'
+ ),
+ 11 => array (
+ 'FontRenderContext', 'GlyphJustificationInfo', 'GlyphMetrics', 'GlyphVector', 'GraphicAttribute', 'ImageGraphicAttribute', 'LineBreakMeasurer', 'LineMetrics', 'MultipleMaster', 'NumericShaper', 'ShapeGraphicAttribute', 'TextAttribute', 'TextHitInfo', 'TextLayout', 'TextLayout.CaretPolicy', 'TextMeasurer', 'TransformAttribute'
+ ),
+ 12 => array (
+ 'AffineTransform', 'Arc2D', 'Arc2D.Double', 'Arc2D.Float', 'Area', 'CubicCurve2D', 'CubicCurve2D.Double', 'CubicCurve2D.Float', 'Dimension2D', 'Ellipse2D', 'Ellipse2D.Double', 'Ellipse2D.Float', 'FlatteningPathIterator', 'GeneralPath', 'IllegalPathStateException', 'Line2D', 'Line2D.Double', 'Line2D.Float', 'NoninvertibleTransformException', 'PathIterator', 'Point2D', 'Point2D.Double', 'Point2D.Float', 'QuadCurve2D', 'QuadCurve2D.Double', 'QuadCurve2D.Float', 'Rectangle2D', 'Rectangle2D.Double', 'Rectangle2D.Float', 'RectangularShape', 'RoundRectangle2D', 'RoundRectangle2D.Double', 'RoundRectangle2D.Float'
+ ),
+ 13 => array (
+ 'InputContext', 'InputMethodHighlight', 'InputMethodRequests', 'InputSubset'
+ ),
+ 14 => array (
+ 'InputMethod', 'InputMethodContext', 'InputMethodDescriptor'
+ ),
+ 15 => array (
+ 'AffineTransformOp', 'AreaAveragingScaleFilter', 'BandCombineOp', 'BandedSampleModel', 'BufferStrategy', 'BufferedImage', 'BufferedImageFilter', 'BufferedImageOp', 'ByteLookupTable', 'ColorConvertOp', 'ColorModel', 'ComponentColorModel', 'ComponentSampleModel', 'ConvolveOp', 'CropImageFilter', 'DataBuffer', 'DataBufferByte', 'DataBufferDouble', 'DataBufferFloat', 'DataBufferInt', 'DataBufferShort', 'DataBufferUShort', 'DirectColorModel', 'FilteredImageSource', 'ImageConsumer', 'ImageFilter', 'ImageObserver', 'ImageProducer', 'ImagingOpException', 'IndexColorModel', 'Kernel', 'LookupOp', 'LookupTable', 'MemoryImageSource', 'MultiPixelPackedSampleModel', 'PackedColorModel', 'PixelGrabber', 'PixelInterleavedSampleModel', 'RGBImageFilter', 'Raster', 'RasterFormatException', 'RasterOp', 'RenderedImage', 'ReplicateScaleFilter', 'RescaleOp', 'SampleModel', 'ShortLookupTable', 'SinglePixelPackedSampleModel', 'TileObserver', 'VolatileImage', 'WritableRaster', 'WritableRenderedImage'
+ ),
+ 16 => array (
+ 'ContextualRenderedImageFactory', 'ParameterBlock', 'RenderContext', 'RenderableImage', 'RenderableImageOp', 'RenderableImageProducer', 'RenderedImageFactory'
+ ),
+ 17 => array (
+ 'Book', 'PageFormat', 'Pageable', 'Paper', 'Printable', 'PrinterAbortException', 'PrinterException', 'PrinterGraphics', 'PrinterIOException', 'PrinterJob'
+ ),
+ 18 => array (
+ 'AppletInitializer', 'BeanDescriptor', 'BeanInfo', 'Beans', 'Customizer', 'DefaultPersistenceDelegate', 'DesignMode', 'Encoder', 'EventHandler', 'EventSetDescriptor', 'ExceptionListener', 'Expression', 'FeatureDescriptor', 'IndexedPropertyChangeEvent', 'IndexedPropertyDescriptor', 'Introspector', 'MethodDescriptor', 'ParameterDescriptor', 'PersistenceDelegate', 'PropertyChangeEvent', 'PropertyChangeListener', 'PropertyChangeListenerProxy', 'PropertyChangeSupport', 'PropertyDescriptor', 'PropertyEditor', 'PropertyEditorManager', 'PropertyEditorSupport', 'PropertyVetoException', 'SimpleBeanInfo', 'VetoableChangeListener', 'VetoableChangeListenerProxy', 'VetoableChangeSupport', 'Visibility', 'XMLDecoder', 'XMLEncoder'
+ ),
+ 19 => array (
+ 'BeanContext', 'BeanContextChild', 'BeanContextChildComponentProxy', 'BeanContextChildSupport', 'BeanContextContainerProxy', 'BeanContextEvent', 'BeanContextMembershipEvent', 'BeanContextMembershipListener', 'BeanContextProxy', 'BeanContextServiceAvailableEvent', 'BeanContextServiceProvider', 'BeanContextServiceProviderBeanInfo', 'BeanContextServiceRevokedEvent', 'BeanContextServiceRevokedListener', 'BeanContextServices', 'BeanContextServicesListener', 'BeanContextServicesSupport', 'BeanContextServicesSupport.BCSSServiceProvider', 'BeanContextSupport', 'BeanContextSupport.BCSIterator'
+ ),
+ 20 => array (
+ 'BufferedInputStream', 'BufferedOutputStream', 'BufferedReader', 'BufferedWriter', 'ByteArrayInputStream', 'ByteArrayOutputStream', 'CharArrayReader', 'CharArrayWriter', 'CharConversionException', 'Closeable', 'DataInput', 'DataOutput', 'EOFException', 'Externalizable', 'File', 'FileDescriptor', 'FileInputStream', 'FileNotFoundException', 'FileOutputStream', 'FilePermission', 'FileReader', 'FileWriter', 'FilenameFilter', 'FilterInputStream', 'FilterOutputStream', 'FilterReader', 'FilterWriter', 'Flushable', 'IOException', 'InputStreamReader', 'InterruptedIOException', 'InvalidClassException', 'InvalidObjectException', 'LineNumberInputStream', 'LineNumberReader', 'NotActiveException', 'NotSerializableException', 'ObjectInput', 'ObjectInputStream', 'ObjectInputStream.GetField', 'ObjectInputValidation', 'ObjectOutput', 'ObjectOutputStream', 'ObjectOutputStream.PutField', 'ObjectStreamClass', 'ObjectStreamConstants', 'ObjectStreamException', 'ObjectStreamField', 'OptionalDataException', 'OutputStreamWriter',
+ 'PipedInputStream', 'PipedOutputStream', 'PipedReader', 'PipedWriter', 'PrintStream', 'PrintWriter', 'PushbackInputStream', 'PushbackReader', 'RandomAccessFile', 'Reader', 'SequenceInputStream', 'Serializable', 'SerializablePermission', 'StreamCorruptedException', 'StreamTokenizer', 'StringBufferInputStream', 'StringReader', 'StringWriter', 'SyncFailedException', 'UTFDataFormatException', 'UnsupportedEncodingException', 'WriteAbortedException', 'Writer'
+ ),
+ 21 => array (
+ 'AbstractMethodError', 'Appendable', 'ArithmeticException', 'ArrayIndexOutOfBoundsException', 'ArrayStoreException', 'AssertionError', 'Boolean', 'Byte', 'CharSequence', 'Character', 'Character.Subset', 'Character.UnicodeBlock', 'Class', 'ClassCastException', 'ClassCircularityError', 'ClassFormatError', 'ClassLoader', 'ClassNotFoundException', 'CloneNotSupportedException', 'Cloneable', 'Comparable', 'Compiler', 'Deprecated', 'Double', 'Enum', 'EnumConstantNotPresentException', 'Error', 'Exception', 'ExceptionInInitializerError', 'Float', 'IllegalAccessError', 'IllegalAccessException', 'IllegalArgumentException', 'IllegalMonitorStateException', 'IllegalStateException', 'IllegalThreadStateException', 'IncompatibleClassChangeError', 'IndexOutOfBoundsException', 'InheritableThreadLocal', 'InstantiationError', 'InstantiationException', 'Integer', 'InternalError', 'InterruptedException', 'Iterable', 'LinkageError', 'Long', 'Math', 'NegativeArraySizeException', 'NoClassDefFoundError', 'NoSuchFieldError',
+ 'NoSuchFieldException', 'NoSuchMethodError', 'NoSuchMethodException', 'NullPointerException', 'Number', 'NumberFormatException', 'OutOfMemoryError', 'Override', 'Package', 'Process', 'ProcessBuilder', 'Readable', 'Runnable', 'Runtime', 'RuntimeException', 'RuntimePermission', 'SecurityException', 'SecurityManager', 'Short', 'StackOverflowError', 'StackTraceElement', 'StrictMath', 'String', 'StringBuffer', 'StringBuilder', 'StringIndexOutOfBoundsException', 'SuppressWarnings', 'System', 'Thread', 'Thread.State', 'Thread.UncaughtExceptionHandler', 'ThreadDeath', 'ThreadGroup', 'ThreadLocal', 'Throwable', 'TypeNotPresentException', 'UnknownError', 'UnsatisfiedLinkError', 'UnsupportedClassVersionError', 'UnsupportedOperationException', 'VerifyError', 'VirtualMachineError', 'Void'
+ ),
+ 22 => array (
+ 'AnnotationFormatError', 'AnnotationTypeMismatchException', 'Documented', 'ElementType', 'IncompleteAnnotationException', 'Inherited', 'Retention', 'RetentionPolicy', 'Target'
+ ),
+ 23 => array (
+ 'ClassDefinition', 'ClassFileTransformer', 'IllegalClassFormatException', 'Instrumentation', 'UnmodifiableClassException'
+ ),
+ 24 => array (
+ 'ClassLoadingMXBean', 'CompilationMXBean', 'GarbageCollectorMXBean', 'ManagementFactory', 'ManagementPermission', 'MemoryMXBean', 'MemoryManagerMXBean', 'MemoryNotificationInfo', 'MemoryPoolMXBean', 'MemoryType', 'MemoryUsage', 'OperatingSystemMXBean', 'RuntimeMXBean', 'ThreadInfo', 'ThreadMXBean'
+ ),
+ 25 => array (
+ 'PhantomReference', 'ReferenceQueue', 'SoftReference', 'WeakReference'
+ ),
+ 26 => array (
+ 'AccessibleObject', 'AnnotatedElement', 'Constructor', 'Field', 'GenericArrayType', 'GenericDeclaration', 'GenericSignatureFormatError', 'InvocationHandler', 'InvocationTargetException', 'MalformedParameterizedTypeException', 'Member', 'Method', 'Modifier', 'ParameterizedType', 'ReflectPermission', 'Type', 'TypeVariable', 'UndeclaredThrowableException', 'WildcardType'
+ ),
+ 27 => array (
+ 'BigDecimal', 'BigInteger', 'MathContext', 'RoundingMode'
+ ),
+ 28 => array (
+ 'Authenticator', 'Authenticator.RequestorType', 'BindException', 'CacheRequest', 'CacheResponse', 'ContentHandlerFactory', 'CookieHandler', 'DatagramPacket', 'DatagramSocket', 'DatagramSocketImpl', 'DatagramSocketImplFactory', 'FileNameMap', 'HttpRetryException', 'HttpURLConnection', 'Inet4Address', 'Inet6Address', 'InetAddress', 'InetSocketAddress', 'JarURLConnection', 'MalformedURLException', 'MulticastSocket', 'NetPermission', 'NetworkInterface', 'NoRouteToHostException', 'PasswordAuthentication', 'PortUnreachableException', 'ProtocolException', 'Proxy.Type', 'ProxySelector', 'ResponseCache', 'SecureCacheResponse', 'ServerSocket', 'Socket', 'SocketAddress', 'SocketException', 'SocketImpl', 'SocketImplFactory', 'SocketOptions', 'SocketPermission', 'SocketTimeoutException', 'URI', 'URISyntaxException', 'URL', 'URLClassLoader', 'URLConnection', 'URLDecoder', 'URLEncoder', 'URLStreamHandler', 'URLStreamHandlerFactory', 'UnknownServiceException'
+ ),
+ 29 => array (
+ 'Buffer', 'BufferOverflowException', 'BufferUnderflowException', 'ByteBuffer', 'ByteOrder', 'CharBuffer', 'DoubleBuffer', 'FloatBuffer', 'IntBuffer', 'InvalidMarkException', 'LongBuffer', 'MappedByteBuffer', 'ReadOnlyBufferException', 'ShortBuffer'
+ ),
+ 30 => array (
+ 'AlreadyConnectedException', 'AsynchronousCloseException', 'ByteChannel', 'CancelledKeyException', 'Channel', 'Channels', 'ClosedByInterruptException', 'ClosedChannelException', 'ClosedSelectorException', 'ConnectionPendingException', 'DatagramChannel', 'FileChannel', 'FileChannel.MapMode', 'FileLock', 'FileLockInterruptionException', 'GatheringByteChannel', 'IllegalBlockingModeException', 'IllegalSelectorException', 'InterruptibleChannel', 'NoConnectionPendingException', 'NonReadableChannelException', 'NonWritableChannelException', 'NotYetBoundException', 'NotYetConnectedException', 'OverlappingFileLockException', 'Pipe', 'Pipe.SinkChannel', 'Pipe.SourceChannel', 'ReadableByteChannel', 'ScatteringByteChannel', 'SelectableChannel', 'SelectionKey', 'Selector', 'ServerSocketChannel', 'SocketChannel', 'UnresolvedAddressException', 'UnsupportedAddressTypeException', 'WritableByteChannel'
+ ),
+ 31 => array (
+ 'AbstractInterruptibleChannel', 'AbstractSelectableChannel', 'AbstractSelectionKey', 'AbstractSelector', 'SelectorProvider'
+ ),
+ 32 => array (
+ 'CharacterCodingException', 'Charset', 'CharsetDecoder', 'CharsetEncoder', 'CoderMalfunctionError', 'CoderResult', 'CodingErrorAction', 'IllegalCharsetNameException', 'MalformedInputException', 'UnmappableCharacterException', 'UnsupportedCharsetException'
+ ),
+ 33 => array (
+ 'CharsetProvider'
+ ),
+ 34 => array (
+ 'AccessException', 'AlreadyBoundException', 'ConnectIOException', 'MarshalException', 'MarshalledObject', 'Naming', 'NoSuchObjectException', 'NotBoundException', 'RMISecurityException', 'RMISecurityManager', 'Remote', 'RemoteException', 'ServerError', 'ServerException', 'ServerRuntimeException', 'StubNotFoundException', 'UnexpectedException', 'UnmarshalException'
+ ),
+ 35 => array (
+ 'Activatable', 'ActivateFailedException', 'ActivationDesc', 'ActivationException', 'ActivationGroup', 'ActivationGroupDesc', 'ActivationGroupDesc.CommandEnvironment', 'ActivationGroupID', 'ActivationGroup_Stub', 'ActivationID', 'ActivationInstantiator', 'ActivationMonitor', 'ActivationSystem', 'Activator', 'UnknownGroupException', 'UnknownObjectException'
+ ),
+ 36 => array (
+ 'DGC', 'Lease', 'VMID'
+ ),
+ 37 => array (
+ 'LocateRegistry', 'Registry', 'RegistryHandler'
+ ),
+ 38 => array (
+ 'ExportException', 'LoaderHandler', 'LogStream', 'ObjID', 'Operation', 'RMIClassLoader', 'RMIClassLoaderSpi', 'RMIClientSocketFactory', 'RMIFailureHandler', 'RMIServerSocketFactory', 'RMISocketFactory', 'RemoteCall', 'RemoteObject', 'RemoteObjectInvocationHandler', 'RemoteRef', 'RemoteServer', 'RemoteStub', 'ServerCloneException', 'ServerNotActiveException', 'ServerRef', 'Skeleton', 'SkeletonMismatchException', 'SkeletonNotFoundException', 'SocketSecurityException', 'UID', 'UnicastRemoteObject', 'Unreferenced'
+ ),
+ 39 => array (
+ 'AccessControlContext', 'AccessControlException', 'AccessController', 'AlgorithmParameterGenerator', 'AlgorithmParameterGeneratorSpi', 'AlgorithmParameters', 'AlgorithmParametersSpi', 'AllPermission', 'AuthProvider', 'BasicPermission', 'CodeSigner', 'CodeSource', 'DigestException', 'DigestInputStream', 'DigestOutputStream', 'DomainCombiner', 'GeneralSecurityException', 'Guard', 'GuardedObject', 'Identity', 'IdentityScope', 'InvalidAlgorithmParameterException', 'InvalidParameterException', 'Key', 'KeyException', 'KeyFactory', 'KeyFactorySpi', 'KeyManagementException', 'KeyPair', 'KeyPairGenerator', 'KeyPairGeneratorSpi', 'KeyRep', 'KeyRep.Type', 'KeyStore', 'KeyStore.Builder', 'KeyStore.CallbackHandlerProtection', 'KeyStore.Entry', 'KeyStore.LoadStoreParameter', 'KeyStore.PasswordProtection', 'KeyStore.PrivateKeyEntry', 'KeyStore.ProtectionParameter', 'KeyStore.SecretKeyEntry', 'KeyStore.TrustedCertificateEntry', 'KeyStoreException', 'KeyStoreSpi', 'MessageDigest', 'MessageDigestSpi',
+ 'NoSuchAlgorithmException', 'NoSuchProviderException', 'PermissionCollection', 'Permissions', 'PrivateKey', 'PrivilegedAction', 'PrivilegedActionException', 'PrivilegedExceptionAction', 'ProtectionDomain', 'Provider', 'Provider.Service', 'ProviderException', 'PublicKey', 'SecureClassLoader', 'SecureRandom', 'SecureRandomSpi', 'Security', 'SecurityPermission', 'Signature', 'SignatureException', 'SignatureSpi', 'SignedObject', 'Signer', 'UnrecoverableEntryException', 'UnrecoverableKeyException', 'UnresolvedPermission'
+ ),
+ 40 => array (
+ 'Acl', 'AclEntry', 'AclNotFoundException', 'Group', 'LastOwnerException', 'NotOwnerException', 'Owner'
+ ),
+ 41 => array (
+ 'CRL', 'CRLException', 'CRLSelector', 'CertPath', 'CertPath.CertPathRep', 'CertPathBuilder', 'CertPathBuilderException', 'CertPathBuilderResult', 'CertPathBuilderSpi', 'CertPathParameters', 'CertPathValidator', 'CertPathValidatorException', 'CertPathValidatorResult', 'CertPathValidatorSpi', 'CertSelector', 'CertStore', 'CertStoreException', 'CertStoreParameters', 'CertStoreSpi', 'Certificate.CertificateRep', 'CertificateFactory', 'CertificateFactorySpi', 'CollectionCertStoreParameters', 'LDAPCertStoreParameters', 'PKIXBuilderParameters', 'PKIXCertPathBuilderResult', 'PKIXCertPathChecker', 'PKIXCertPathValidatorResult', 'PKIXParameters', 'PolicyNode', 'PolicyQualifierInfo', 'TrustAnchor', 'X509CRL', 'X509CRLEntry', 'X509CRLSelector', 'X509CertSelector', 'X509Extension'
+ ),
+ 42 => array (
+ 'DSAKey', 'DSAKeyPairGenerator', 'DSAParams', 'DSAPrivateKey', 'DSAPublicKey', 'ECKey', 'ECPrivateKey', 'ECPublicKey', 'RSAKey', 'RSAMultiPrimePrivateCrtKey', 'RSAPrivateCrtKey', 'RSAPrivateKey', 'RSAPublicKey'
+ ),
+ 43 => array (
+ 'AlgorithmParameterSpec', 'DSAParameterSpec', 'DSAPrivateKeySpec', 'DSAPublicKeySpec', 'ECField', 'ECFieldF2m', 'ECFieldFp', 'ECGenParameterSpec', 'ECParameterSpec', 'ECPoint', 'ECPrivateKeySpec', 'ECPublicKeySpec', 'EllipticCurve', 'EncodedKeySpec', 'InvalidKeySpecException', 'InvalidParameterSpecException', 'KeySpec', 'MGF1ParameterSpec', 'PKCS8EncodedKeySpec', 'PSSParameterSpec', 'RSAKeyGenParameterSpec', 'RSAMultiPrimePrivateCrtKeySpec', 'RSAOtherPrimeInfo', 'RSAPrivateCrtKeySpec', 'RSAPrivateKeySpec', 'RSAPublicKeySpec', 'X509EncodedKeySpec'
+ ),
+ 44 => array (
+ 'BatchUpdateException', 'Blob', 'CallableStatement', 'Clob', 'Connection', 'DataTruncation', 'DatabaseMetaData', 'Driver', 'DriverManager', 'DriverPropertyInfo', 'ParameterMetaData', 'PreparedStatement', 'Ref', 'ResultSet', 'ResultSetMetaData', 'SQLData', 'SQLException', 'SQLInput', 'SQLOutput', 'SQLPermission', 'SQLWarning', 'Savepoint', 'Struct', 'Time', 'Types'
+ ),
+ 45 => array (
+ 'AttributedCharacterIterator', 'AttributedCharacterIterator.Attribute', 'AttributedString', 'Bidi', 'BreakIterator', 'CharacterIterator', 'ChoiceFormat', 'CollationElementIterator', 'CollationKey', 'Collator', 'DateFormat', 'DateFormat.Field', 'DateFormatSymbols', 'DecimalFormat', 'DecimalFormatSymbols', 'FieldPosition', 'Format', 'Format.Field', 'MessageFormat', 'MessageFormat.Field', 'NumberFormat', 'NumberFormat.Field', 'ParseException', 'ParsePosition', 'RuleBasedCollator', 'SimpleDateFormat', 'StringCharacterIterator'
+ ),
+ 46 => array (
+ 'AbstractCollection', 'AbstractList', 'AbstractMap', 'AbstractQueue', 'AbstractSequentialList', 'AbstractSet', 'ArrayList', 'Arrays', 'BitSet', 'Calendar', 'Collection', 'Collections', 'Comparator', 'ConcurrentModificationException', 'Currency', 'Dictionary', 'DuplicateFormatFlagsException', 'EmptyStackException', 'EnumMap', 'EnumSet', 'Enumeration', 'EventListenerProxy', 'EventObject', 'FormatFlagsConversionMismatchException', 'Formattable', 'FormattableFlags', 'Formatter.BigDecimalLayoutForm', 'FormatterClosedException', 'GregorianCalendar', 'HashMap', 'HashSet', 'Hashtable', 'IdentityHashMap', 'IllegalFormatCodePointException', 'IllegalFormatConversionException', 'IllegalFormatException', 'IllegalFormatFlagsException', 'IllegalFormatPrecisionException', 'IllegalFormatWidthException', 'InputMismatchException', 'InvalidPropertiesFormatException', 'Iterator', 'LinkedHashMap', 'LinkedHashSet', 'LinkedList', 'ListIterator', 'ListResourceBundle', 'Locale', 'Map', 'Map.Entry', 'MissingFormatArgumentException',
+ 'MissingFormatWidthException', 'MissingResourceException', 'NoSuchElementException', 'Observable', 'Observer', 'PriorityQueue', 'Properties', 'PropertyPermission', 'PropertyResourceBundle', 'Queue', 'Random', 'RandomAccess', 'ResourceBundle', 'Scanner', 'Set', 'SimpleTimeZone', 'SortedMap', 'SortedSet', 'Stack', 'StringTokenizer', 'TimeZone', 'TimerTask', 'TooManyListenersException', 'TreeMap', 'TreeSet', 'UUID', 'UnknownFormatConversionException', 'UnknownFormatFlagsException', 'Vector', 'WeakHashMap'
+ ),
+ 47 => array (
+ 'AbstractExecutorService', 'ArrayBlockingQueue', 'BlockingQueue', 'BrokenBarrierException', 'Callable', 'CancellationException', 'CompletionService', 'ConcurrentHashMap', 'ConcurrentLinkedQueue', 'ConcurrentMap', 'CopyOnWriteArrayList', 'CopyOnWriteArraySet', 'CountDownLatch', 'CyclicBarrier', 'DelayQueue', 'Delayed', 'Exchanger', 'ExecutionException', 'Executor', 'ExecutorCompletionService', 'ExecutorService', 'Executors', 'Future', 'FutureTask', 'LinkedBlockingQueue', 'PriorityBlockingQueue', 'RejectedExecutionException', 'RejectedExecutionHandler', 'ScheduledExecutorService', 'ScheduledFuture', 'ScheduledThreadPoolExecutor', 'Semaphore', 'SynchronousQueue', 'ThreadFactory', 'ThreadPoolExecutor', 'ThreadPoolExecutor.AbortPolicy', 'ThreadPoolExecutor.CallerRunsPolicy', 'ThreadPoolExecutor.DiscardOldestPolicy', 'ThreadPoolExecutor.DiscardPolicy', 'TimeUnit', 'TimeoutException'
+ ),
+ 48 => array (
+ 'AtomicBoolean', 'AtomicInteger', 'AtomicIntegerArray', 'AtomicIntegerFieldUpdater', 'AtomicLong', 'AtomicLongArray', 'AtomicLongFieldUpdater', 'AtomicMarkableReference', 'AtomicReference', 'AtomicReferenceArray', 'AtomicReferenceFieldUpdater', 'AtomicStampedReference'
+ ),
+ 49 => array (
+ 'AbstractQueuedSynchronizer', 'Condition', 'Lock', 'LockSupport', 'ReadWriteLock', 'ReentrantLock', 'ReentrantReadWriteLock', 'ReentrantReadWriteLock.ReadLock', 'ReentrantReadWriteLock.WriteLock'
+ ),
+ 50 => array (
+ 'Attributes.Name', 'JarEntry', 'JarException', 'JarFile', 'JarInputStream', 'JarOutputStream', 'Manifest', 'Pack200', 'Pack200.Packer', 'Pack200.Unpacker'
+ ),
+ 51 => array (
+ 'ConsoleHandler', 'ErrorManager', 'FileHandler', 'Filter', 'Handler', 'Level', 'LogManager', 'LogRecord', 'Logger', 'LoggingMXBean', 'LoggingPermission', 'MemoryHandler', 'SimpleFormatter', 'SocketHandler', 'StreamHandler', 'XMLFormatter'
+ ),
+ 52 => array (
+ 'AbstractPreferences', 'BackingStoreException', 'InvalidPreferencesFormatException', 'NodeChangeEvent', 'NodeChangeListener', 'PreferenceChangeEvent', 'PreferenceChangeListener', 'Preferences', 'PreferencesFactory'
+ ),
+ 53 => array (
+ 'MatchResult', 'Matcher', 'Pattern', 'PatternSyntaxException'
+ ),
+ 54 => array (
+ 'Adler32', 'CRC32', 'CheckedInputStream', 'CheckedOutputStream', 'Checksum', 'DataFormatException', 'Deflater', 'DeflaterOutputStream', 'GZIPInputStream', 'GZIPOutputStream', 'Inflater', 'InflaterInputStream', 'ZipEntry', 'ZipException', 'ZipFile', 'ZipInputStream', 'ZipOutputStream'
+ ),
+ 55 => array (
+ 'Accessible', 'AccessibleAction', 'AccessibleAttributeSequence', 'AccessibleBundle', 'AccessibleComponent', 'AccessibleContext', 'AccessibleEditableText', 'AccessibleExtendedComponent', 'AccessibleExtendedTable', 'AccessibleExtendedText', 'AccessibleHyperlink', 'AccessibleHypertext', 'AccessibleIcon', 'AccessibleKeyBinding', 'AccessibleRelation', 'AccessibleRelationSet', 'AccessibleResourceBundle', 'AccessibleRole', 'AccessibleSelection', 'AccessibleState', 'AccessibleStateSet', 'AccessibleStreamable', 'AccessibleTable', 'AccessibleTableModelChange', 'AccessibleText', 'AccessibleTextSequence', 'AccessibleValue'
+ ),
+ 56 => array (
+ 'ActivityCompletedException', 'ActivityRequiredException', 'InvalidActivityException'
+ ),
+ 57 => array (
+ 'BadPaddingException', 'Cipher', 'CipherInputStream', 'CipherOutputStream', 'CipherSpi', 'EncryptedPrivateKeyInfo', 'ExemptionMechanism', 'ExemptionMechanismException', 'ExemptionMechanismSpi', 'IllegalBlockSizeException', 'KeyAgreement', 'KeyAgreementSpi', 'KeyGenerator', 'KeyGeneratorSpi', 'Mac', 'MacSpi', 'NoSuchPaddingException', 'NullCipher', 'SealedObject', 'SecretKey', 'SecretKeyFactory', 'SecretKeyFactorySpi', 'ShortBufferException'
+ ),
+ 58 => array (
+ 'DHKey', 'DHPrivateKey', 'DHPublicKey', 'PBEKey'
+ ),
+ 59 => array (
+ 'DESKeySpec', 'DESedeKeySpec', 'DHGenParameterSpec', 'DHParameterSpec', 'DHPrivateKeySpec', 'DHPublicKeySpec', 'IvParameterSpec', 'OAEPParameterSpec', 'PBEKeySpec', 'PBEParameterSpec', 'PSource', 'PSource.PSpecified', 'RC2ParameterSpec', 'RC5ParameterSpec', 'SecretKeySpec'
+ ),
+ 60 => array (
+ 'IIOException', 'IIOImage', 'IIOParam', 'IIOParamController', 'ImageIO', 'ImageReadParam', 'ImageReader', 'ImageTranscoder', 'ImageTypeSpecifier', 'ImageWriteParam', 'ImageWriter'
+ ),
+ 61 => array (
+ 'IIOReadProgressListener', 'IIOReadUpdateListener', 'IIOReadWarningListener', 'IIOWriteProgressListener', 'IIOWriteWarningListener'
+ ),
+ 62 => array (
+ 'IIOInvalidTreeException', 'IIOMetadata', 'IIOMetadataController', 'IIOMetadataFormat', 'IIOMetadataFormatImpl', 'IIOMetadataNode'
+ ),
+ 63 => array (
+ 'BMPImageWriteParam'
+ ),
+ 64 => array (
+ 'JPEGHuffmanTable', 'JPEGImageReadParam', 'JPEGImageWriteParam', 'JPEGQTable'
+ ),
+ 65 => array (
+ 'IIORegistry', 'IIOServiceProvider', 'ImageInputStreamSpi', 'ImageOutputStreamSpi', 'ImageReaderSpi', 'ImageReaderWriterSpi', 'ImageTranscoderSpi', 'ImageWriterSpi', 'RegisterableService', 'ServiceRegistry', 'ServiceRegistry.Filter'
+ ),
+ 66 => array (
+ 'FileCacheImageInputStream', 'FileCacheImageOutputStream', 'FileImageInputStream', 'FileImageOutputStream', 'IIOByteBuffer', 'ImageInputStream', 'ImageInputStreamImpl', 'ImageOutputStream', 'ImageOutputStreamImpl', 'MemoryCacheImageInputStream', 'MemoryCacheImageOutputStream'
+ ),
+ 67 => array (
+ 'AttributeChangeNotification', 'AttributeChangeNotificationFilter', 'AttributeNotFoundException', 'AttributeValueExp', 'BadAttributeValueExpException', 'BadBinaryOpValueExpException', 'BadStringOperationException', 'Descriptor', 'DescriptorAccess', 'DynamicMBean', 'InstanceAlreadyExistsException', 'InstanceNotFoundException', 'InvalidApplicationException', 'JMException', 'JMRuntimeException', 'ListenerNotFoundException', 'MBeanAttributeInfo', 'MBeanConstructorInfo', 'MBeanException', 'MBeanFeatureInfo', 'MBeanInfo', 'MBeanNotificationInfo', 'MBeanOperationInfo', 'MBeanParameterInfo', 'MBeanPermission', 'MBeanRegistration', 'MBeanRegistrationException', 'MBeanServer', 'MBeanServerBuilder', 'MBeanServerConnection', 'MBeanServerDelegate', 'MBeanServerDelegateMBean', 'MBeanServerFactory', 'MBeanServerInvocationHandler', 'MBeanServerNotification', 'MBeanServerPermission', 'MBeanTrustPermission', 'MalformedObjectNameException', 'NotCompliantMBeanException', 'Notification', 'NotificationBroadcaster',
+ 'NotificationBroadcasterSupport', 'NotificationEmitter', 'NotificationFilter', 'NotificationFilterSupport', 'NotificationListener', 'ObjectInstance', 'ObjectName', 'OperationsException', 'PersistentMBean', 'Query', 'QueryEval', 'QueryExp', 'ReflectionException', 'RuntimeErrorException', 'RuntimeMBeanException', 'RuntimeOperationsException', 'ServiceNotFoundException', 'StandardMBean', 'StringValueExp', 'ValueExp'
+ ),
+ 68 => array (
+ 'ClassLoaderRepository', 'MLet', 'MLetMBean', 'PrivateClassLoader', 'PrivateMLet'
+ ),
+ 69 => array (
+ 'DescriptorSupport', 'InvalidTargetObjectTypeException', 'ModelMBean', 'ModelMBeanAttributeInfo', 'ModelMBeanConstructorInfo', 'ModelMBeanInfo', 'ModelMBeanInfoSupport', 'ModelMBeanNotificationBroadcaster', 'ModelMBeanNotificationInfo', 'ModelMBeanOperationInfo', 'RequiredModelMBean', 'XMLParseException'
+ ),
+ 70 => array (
+ 'CounterMonitor', 'CounterMonitorMBean', 'GaugeMonitor', 'GaugeMonitorMBean', 'Monitor', 'MonitorMBean', 'MonitorNotification', 'MonitorSettingException', 'StringMonitor', 'StringMonitorMBean'
+ ),
+ 71 => array (
+ 'ArrayType', 'CompositeData', 'CompositeDataSupport', 'CompositeType', 'InvalidOpenTypeException', 'KeyAlreadyExistsException', 'OpenDataException', 'OpenMBeanAttributeInfo', 'OpenMBeanAttributeInfoSupport', 'OpenMBeanConstructorInfo', 'OpenMBeanConstructorInfoSupport', 'OpenMBeanInfo', 'OpenMBeanInfoSupport', 'OpenMBeanOperationInfo', 'OpenMBeanOperationInfoSupport', 'OpenMBeanParameterInfo', 'OpenMBeanParameterInfoSupport', 'SimpleType', 'TabularData', 'TabularDataSupport', 'TabularType'
+ ),
+ 72 => array (
+ 'InvalidRelationIdException', 'InvalidRelationServiceException', 'InvalidRelationTypeException', 'InvalidRoleInfoException', 'InvalidRoleValueException', 'MBeanServerNotificationFilter', 'Relation', 'RelationException', 'RelationNotFoundException', 'RelationNotification', 'RelationService', 'RelationServiceMBean', 'RelationServiceNotRegisteredException', 'RelationSupport', 'RelationSupportMBean', 'RelationType', 'RelationTypeNotFoundException', 'RelationTypeSupport', 'Role', 'RoleInfo', 'RoleInfoNotFoundException', 'RoleList', 'RoleNotFoundException', 'RoleResult', 'RoleStatus', 'RoleUnresolved', 'RoleUnresolvedList'
+ ),
+ 73 => array (
+ 'JMXAuthenticator', 'JMXConnectionNotification', 'JMXConnector', 'JMXConnectorFactory', 'JMXConnectorProvider', 'JMXConnectorServer', 'JMXConnectorServerFactory', 'JMXConnectorServerMBean', 'JMXConnectorServerProvider', 'JMXPrincipal', 'JMXProviderException', 'JMXServerErrorException', 'JMXServiceURL', 'MBeanServerForwarder', 'NotificationResult', 'SubjectDelegationPermission', 'TargetedNotification'
+ ),
+ 74 => array (
+ 'RMIConnection', 'RMIConnectionImpl', 'RMIConnectionImpl_Stub', 'RMIConnector', 'RMIConnectorServer', 'RMIIIOPServerImpl', 'RMIJRMPServerImpl', 'RMIServer', 'RMIServerImpl', 'RMIServerImpl_Stub'
+ ),
+ 75 => array (
+ 'TimerAlarmClockNotification', 'TimerMBean', 'TimerNotification'
+ ),
+ 76 => array (
+ 'AuthenticationNotSupportedException', 'BinaryRefAddr', 'CannotProceedException', 'CommunicationException', 'CompositeName', 'CompoundName', 'ConfigurationException', 'ContextNotEmptyException', 'InitialContext', 'InsufficientResourcesException', 'InterruptedNamingException', 'InvalidNameException', 'LimitExceededException', 'LinkException', 'LinkLoopException', 'LinkRef', 'MalformedLinkException', 'Name', 'NameAlreadyBoundException', 'NameClassPair', 'NameNotFoundException', 'NameParser', 'NamingEnumeration', 'NamingException', 'NamingSecurityException', 'NoInitialContextException', 'NoPermissionException', 'NotContextException', 'OperationNotSupportedException', 'PartialResultException', 'RefAddr', 'Referenceable', 'ReferralException', 'ServiceUnavailableException', 'SizeLimitExceededException', 'StringRefAddr', 'TimeLimitExceededException'
+ ),
+ 77 => array (
+ 'AttributeInUseException', 'AttributeModificationException', 'BasicAttribute', 'BasicAttributes', 'DirContext', 'InitialDirContext', 'InvalidAttributeIdentifierException', 'InvalidAttributesException', 'InvalidSearchControlsException', 'InvalidSearchFilterException', 'ModificationItem', 'NoSuchAttributeException', 'SchemaViolationException', 'SearchControls', 'SearchResult'
+ ),
+ 78 => array (
+ 'EventContext', 'EventDirContext', 'NamespaceChangeListener', 'NamingEvent', 'NamingExceptionEvent', 'NamingListener', 'ObjectChangeListener'
+ ),
+ 79 => array (
+ 'BasicControl', 'ControlFactory', 'ExtendedRequest', 'ExtendedResponse', 'HasControls', 'InitialLdapContext', 'LdapContext', 'LdapName', 'LdapReferralException', 'ManageReferralControl', 'PagedResultsControl', 'PagedResultsResponseControl', 'Rdn', 'SortControl', 'SortKey', 'SortResponseControl', 'StartTlsRequest', 'StartTlsResponse', 'UnsolicitedNotification', 'UnsolicitedNotificationEvent', 'UnsolicitedNotificationListener'
+ ),
+ 80 => array (
+ 'DirObjectFactory', 'DirStateFactory', 'DirStateFactory.Result', 'DirectoryManager', 'InitialContextFactory', 'InitialContextFactoryBuilder', 'NamingManager', 'ObjectFactory', 'ObjectFactoryBuilder', 'ResolveResult', 'Resolver', 'StateFactory'
+ ),
+ 81 => array (
+ 'ServerSocketFactory', 'SocketFactory'
+ ),
+ 82 => array (
+ 'CertPathTrustManagerParameters', 'HandshakeCompletedEvent', 'HandshakeCompletedListener', 'HostnameVerifier', 'HttpsURLConnection', 'KeyManager', 'KeyManagerFactory', 'KeyManagerFactorySpi', 'KeyStoreBuilderParameters', 'ManagerFactoryParameters', 'SSLContext', 'SSLContextSpi', 'SSLEngine', 'SSLEngineResult', 'SSLEngineResult.HandshakeStatus', 'SSLEngineResult.Status', 'SSLException', 'SSLHandshakeException', 'SSLKeyException', 'SSLPeerUnverifiedException', 'SSLPermission', 'SSLProtocolException', 'SSLServerSocket', 'SSLServerSocketFactory', 'SSLSession', 'SSLSessionBindingEvent', 'SSLSessionBindingListener', 'SSLSessionContext', 'SSLSocket', 'SSLSocketFactory', 'TrustManager', 'TrustManagerFactory', 'TrustManagerFactorySpi', 'X509ExtendedKeyManager', 'X509KeyManager', 'X509TrustManager'
+ ),
+ 83 => array (
+ 'AttributeException', 'CancelablePrintJob', 'Doc', 'DocFlavor', 'DocFlavor.BYTE_ARRAY', 'DocFlavor.CHAR_ARRAY', 'DocFlavor.INPUT_STREAM', 'DocFlavor.READER', 'DocFlavor.SERVICE_FORMATTED', 'DocFlavor.STRING', 'DocFlavor.URL', 'DocPrintJob', 'FlavorException', 'MultiDoc', 'MultiDocPrintJob', 'MultiDocPrintService', 'PrintException', 'PrintService', 'PrintServiceLookup', 'ServiceUI', 'ServiceUIFactory', 'SimpleDoc', 'StreamPrintService', 'StreamPrintServiceFactory', 'URIException'
+ ),
+ 84 => array (
+ 'AttributeSetUtilities', 'DateTimeSyntax', 'DocAttribute', 'DocAttributeSet', 'EnumSyntax', 'HashAttributeSet', 'HashDocAttributeSet', 'HashPrintJobAttributeSet', 'HashPrintRequestAttributeSet', 'HashPrintServiceAttributeSet', 'IntegerSyntax', 'PrintJobAttribute', 'PrintJobAttributeSet', 'PrintRequestAttribute', 'PrintRequestAttributeSet', 'PrintServiceAttribute', 'PrintServiceAttributeSet', 'ResolutionSyntax', 'SetOfIntegerSyntax', 'Size2DSyntax', 'SupportedValuesAttribute', 'TextSyntax', 'URISyntax', 'UnmodifiableSetException'
+ ),
+ 85 => array (
+ 'Chromaticity', 'ColorSupported', 'Compression', 'Copies', 'CopiesSupported', 'DateTimeAtCompleted', 'DateTimeAtCreation', 'DateTimeAtProcessing', 'Destination', 'DocumentName', 'Fidelity', 'Finishings', 'JobHoldUntil', 'JobImpressions', 'JobImpressionsCompleted', 'JobImpressionsSupported', 'JobKOctets', 'JobKOctetsProcessed', 'JobKOctetsSupported', 'JobMediaSheets', 'JobMediaSheetsCompleted', 'JobMediaSheetsSupported', 'JobMessageFromOperator', 'JobName', 'JobOriginatingUserName', 'JobPriority', 'JobPrioritySupported', 'JobSheets', 'JobState', 'JobStateReason', 'JobStateReasons', 'Media', 'MediaName', 'MediaPrintableArea', 'MediaSize', 'MediaSize.Engineering', 'MediaSize.ISO', 'MediaSize.JIS', 'MediaSize.NA', 'MediaSize.Other', 'MediaSizeName', 'MediaTray', 'MultipleDocumentHandling', 'NumberOfDocuments', 'NumberOfInterveningJobs', 'NumberUp', 'NumberUpSupported', 'OrientationRequested', 'OutputDeviceAssigned', 'PDLOverrideSupported', 'PageRanges', 'PagesPerMinute', 'PagesPerMinuteColor',
+ 'PresentationDirection', 'PrintQuality', 'PrinterInfo', 'PrinterIsAcceptingJobs', 'PrinterLocation', 'PrinterMakeAndModel', 'PrinterMessageFromOperator', 'PrinterMoreInfo', 'PrinterMoreInfoManufacturer', 'PrinterName', 'PrinterResolution', 'PrinterState', 'PrinterStateReason', 'PrinterStateReasons', 'PrinterURI', 'QueuedJobCount', 'ReferenceUriSchemesSupported', 'RequestingUserName', 'Severity', 'SheetCollate', 'Sides'
+ ),
+ 86 => array (
+ 'PrintEvent', 'PrintJobAdapter', 'PrintJobAttributeEvent', 'PrintJobAttributeListener', 'PrintJobEvent', 'PrintJobListener', 'PrintServiceAttributeEvent', 'PrintServiceAttributeListener'
+ ),
+ 87 => array (
+ 'PortableRemoteObject'
+ ),
+ 88 => array (
+ 'ClassDesc', 'PortableRemoteObjectDelegate', 'Stub', 'StubDelegate', 'Tie', 'Util', 'UtilDelegate', 'ValueHandler', 'ValueHandlerMultiFormat'
+ ),
+ 89 => array (
+ 'SslRMIClientSocketFactory', 'SslRMIServerSocketFactory'
+ ),
+ 90 => array (
+ 'AuthPermission', 'DestroyFailedException', 'Destroyable', 'PrivateCredentialPermission', 'RefreshFailedException', 'Refreshable', 'Subject', 'SubjectDomainCombiner'
+ ),
+ 91 => array (
+ 'Callback', 'CallbackHandler', 'ChoiceCallback', 'ConfirmationCallback', 'LanguageCallback', 'NameCallback', 'PasswordCallback', 'TextInputCallback', 'TextOutputCallback', 'UnsupportedCallbackException'
+ ),
+ 92 => array (
+ 'DelegationPermission', 'KerberosKey', 'KerberosPrincipal', 'KerberosTicket', 'ServicePermission'
+ ),
+ 93 => array (
+ 'AccountException', 'AccountExpiredException', 'AccountLockedException', 'AccountNotFoundException', 'AppConfigurationEntry', 'AppConfigurationEntry.LoginModuleControlFlag', 'Configuration', 'CredentialException', 'CredentialExpiredException', 'CredentialNotFoundException', 'FailedLoginException', 'LoginContext', 'LoginException'
+ ),
+ 94 => array (
+ 'LoginModule'
+ ),
+ 95 => array (
+ 'X500Principal', 'X500PrivateCredential'
+ ),
+ 96 => array (
+ 'AuthorizeCallback', 'RealmCallback', 'RealmChoiceCallback', 'Sasl', 'SaslClient', 'SaslClientFactory', 'SaslException', 'SaslServer', 'SaslServerFactory'
+ ),
+ 97 => array (
+ 'ControllerEventListener', 'Instrument', 'InvalidMidiDataException', 'MetaEventListener', 'MetaMessage', 'MidiChannel', 'MidiDevice', 'MidiDevice.Info', 'MidiEvent', 'MidiFileFormat', 'MidiMessage', 'MidiSystem', 'MidiUnavailableException', 'Patch', 'Receiver', 'Sequence', 'Sequencer', 'Sequencer.SyncMode', 'ShortMessage', 'Soundbank', 'SoundbankResource', 'Synthesizer', 'SysexMessage', 'Track', 'Transmitter', 'VoiceStatus'
+ ),
+ 98 => array (
+ 'MidiDeviceProvider', 'MidiFileReader', 'MidiFileWriter', 'SoundbankReader'
+ ),
+ 99 => array (
+ 'AudioFileFormat', 'AudioFileFormat.Type', 'AudioFormat', 'AudioFormat.Encoding', 'AudioInputStream', 'AudioPermission', 'AudioSystem', 'BooleanControl', 'BooleanControl.Type', 'Clip', 'CompoundControl', 'CompoundControl.Type', 'Control.Type', 'DataLine', 'DataLine.Info', 'EnumControl', 'EnumControl.Type', 'FloatControl', 'FloatControl.Type', 'Line', 'Line.Info', 'LineEvent', 'LineEvent.Type', 'LineListener', 'LineUnavailableException', 'Mixer', 'Mixer.Info', 'Port', 'Port.Info', 'ReverbType', 'SourceDataLine', 'TargetDataLine', 'UnsupportedAudioFileException'
+ ),
+ 100 => array (
+ 'AudioFileReader', 'AudioFileWriter', 'FormatConversionProvider', 'MixerProvider'
+ ),
+ 101 => array (
+ 'ConnectionEvent', 'ConnectionEventListener', 'ConnectionPoolDataSource', 'DataSource', 'PooledConnection', 'RowSet', 'RowSetEvent', 'RowSetInternal', 'RowSetListener', 'RowSetMetaData', 'RowSetReader', 'RowSetWriter', 'XAConnection', 'XADataSource'
+ ),
+ 102 => array (
+ 'BaseRowSet', 'CachedRowSet', 'FilteredRowSet', 'JdbcRowSet', 'JoinRowSet', 'Joinable', 'Predicate', 'RowSetMetaDataImpl', 'RowSetWarning', 'WebRowSet'
+ ),
+ 103 => array (
+ 'SQLInputImpl', 'SQLOutputImpl', 'SerialArray', 'SerialBlob', 'SerialClob', 'SerialDatalink', 'SerialException', 'SerialJavaObject', 'SerialRef', 'SerialStruct'
+ ),
+ 104 => array (
+ 'SyncFactory', 'SyncFactoryException', 'SyncProvider', 'SyncProviderException', 'SyncResolver', 'TransactionalWriter', 'XmlReader', 'XmlWriter'
+ ),
+ 105 => array (
+ 'AbstractAction', 'AbstractButton', 'AbstractCellEditor', 'AbstractListModel', 'AbstractSpinnerModel', 'Action', 'ActionMap', 'BorderFactory', 'BoundedRangeModel', 'Box', 'Box.Filler', 'BoxLayout', 'ButtonGroup', 'ButtonModel', 'CellEditor', 'CellRendererPane', 'ComboBoxEditor', 'ComboBoxModel', 'ComponentInputMap', 'DebugGraphics', 'DefaultBoundedRangeModel', 'DefaultButtonModel', 'DefaultCellEditor', 'DefaultComboBoxModel', 'DefaultDesktopManager', 'DefaultFocusManager', 'DefaultListCellRenderer', 'DefaultListCellRenderer.UIResource', 'DefaultListModel', 'DefaultListSelectionModel', 'DefaultSingleSelectionModel', 'DesktopManager', 'FocusManager', 'GrayFilter', 'Icon', 'ImageIcon', 'InputMap', 'InputVerifier', 'InternalFrameFocusTraversalPolicy', 'JApplet', 'JButton', 'JCheckBox', 'JCheckBoxMenuItem', 'JColorChooser', 'JComboBox', 'JComboBox.KeySelectionManager', 'JComponent', 'JDesktopPane', 'JDialog', 'JEditorPane', 'JFileChooser', 'JFormattedTextField', 'JFormattedTextField.AbstractFormatter',
+ 'JFormattedTextField.AbstractFormatterFactory', 'JFrame', 'JInternalFrame', 'JInternalFrame.JDesktopIcon', 'JLabel', 'JLayeredPane', 'JList', 'JMenu', 'JMenuBar', 'JMenuItem', 'JOptionPane', 'JPanel', 'JPasswordField', 'JPopupMenu', 'JPopupMenu.Separator', 'JProgressBar', 'JRadioButton', 'JRadioButtonMenuItem', 'JRootPane', 'JScrollBar', 'JScrollPane', 'JSeparator', 'JSlider', 'JSpinner', 'JSpinner.DateEditor', 'JSpinner.DefaultEditor', 'JSpinner.ListEditor', 'JSpinner.NumberEditor', 'JSplitPane', 'JTabbedPane', 'JTable', 'JTable.PrintMode', 'JTextArea', 'JTextField', 'JTextPane', 'JToggleButton', 'JToggleButton.ToggleButtonModel', 'JToolBar', 'JToolBar.Separator', 'JToolTip', 'JTree', 'JTree.DynamicUtilTreeNode', 'JTree.EmptySelectionModel', 'JViewport', 'JWindow', 'KeyStroke', 'LayoutFocusTraversalPolicy', 'ListCellRenderer', 'ListModel', 'ListSelectionModel', 'LookAndFeel', 'MenuElement', 'MenuSelectionManager', 'MutableComboBoxModel', 'OverlayLayout', 'Popup', 'PopupFactory', 'ProgressMonitor',
+ 'ProgressMonitorInputStream', 'Renderer', 'RepaintManager', 'RootPaneContainer', 'ScrollPaneConstants', 'ScrollPaneLayout', 'ScrollPaneLayout.UIResource', 'Scrollable', 'SingleSelectionModel', 'SizeRequirements', 'SizeSequence', 'SortingFocusTraversalPolicy', 'SpinnerDateModel', 'SpinnerListModel', 'SpinnerModel', 'SpinnerNumberModel', 'Spring', 'SpringLayout', 'SpringLayout.Constraints', 'SwingConstants', 'SwingUtilities', 'ToolTipManager', 'TransferHandler', 'UIDefaults', 'UIDefaults.ActiveValue', 'UIDefaults.LazyInputMap', 'UIDefaults.LazyValue', 'UIDefaults.ProxyLazyValue', 'UIManager', 'UIManager.LookAndFeelInfo', 'UnsupportedLookAndFeelException', 'ViewportLayout', 'WindowConstants'
+ ),
+ 106 => array (
+ 'AbstractBorder', 'BevelBorder', 'Border', 'CompoundBorder', 'EmptyBorder', 'EtchedBorder', 'LineBorder', 'MatteBorder', 'SoftBevelBorder', 'TitledBorder'
+ ),
+ 107 => array (
+ 'AbstractColorChooserPanel', 'ColorChooserComponentFactory', 'ColorSelectionModel', 'DefaultColorSelectionModel'
+ ),
+ 108 => array (
+ 'AncestorEvent', 'AncestorListener', 'CaretEvent', 'CaretListener', 'CellEditorListener', 'ChangeEvent', 'ChangeListener', 'DocumentEvent.ElementChange', 'DocumentEvent.EventType', 'DocumentListener', 'EventListenerList', 'HyperlinkEvent', 'HyperlinkEvent.EventType', 'HyperlinkListener', 'InternalFrameAdapter', 'InternalFrameEvent', 'InternalFrameListener', 'ListDataEvent', 'ListDataListener', 'ListSelectionEvent', 'ListSelectionListener', 'MenuDragMouseEvent', 'MenuDragMouseListener', 'MenuEvent', 'MenuKeyEvent', 'MenuKeyListener', 'MenuListener', 'MouseInputAdapter', 'MouseInputListener', 'PopupMenuEvent', 'PopupMenuListener', 'SwingPropertyChangeSupport', 'TableColumnModelEvent', 'TableColumnModelListener', 'TableModelEvent', 'TableModelListener', 'TreeExpansionEvent', 'TreeExpansionListener', 'TreeModelEvent', 'TreeModelListener', 'TreeSelectionEvent', 'TreeSelectionListener', 'TreeWillExpandListener', 'UndoableEditEvent', 'UndoableEditListener'
+ ),
+ 109 => array (
+ 'FileSystemView', 'FileView'
+ ),
+ 110 => array (
+ 'ActionMapUIResource', 'BorderUIResource', 'BorderUIResource.BevelBorderUIResource', 'BorderUIResource.CompoundBorderUIResource', 'BorderUIResource.EmptyBorderUIResource', 'BorderUIResource.EtchedBorderUIResource', 'BorderUIResource.LineBorderUIResource', 'BorderUIResource.MatteBorderUIResource', 'BorderUIResource.TitledBorderUIResource', 'ButtonUI', 'ColorChooserUI', 'ColorUIResource', 'ComboBoxUI', 'ComponentInputMapUIResource', 'ComponentUI', 'DesktopIconUI', 'DesktopPaneUI', 'DimensionUIResource', 'FileChooserUI', 'FontUIResource', 'IconUIResource', 'InputMapUIResource', 'InsetsUIResource', 'InternalFrameUI', 'LabelUI', 'ListUI', 'MenuBarUI', 'MenuItemUI', 'OptionPaneUI', 'PanelUI', 'PopupMenuUI', 'ProgressBarUI', 'RootPaneUI', 'ScrollBarUI', 'ScrollPaneUI', 'SeparatorUI', 'SliderUI', 'SpinnerUI', 'SplitPaneUI', 'TabbedPaneUI', 'TableHeaderUI', 'TableUI', 'TextUI', 'ToolBarUI', 'ToolTipUI', 'TreeUI', 'UIResource', 'ViewportUI'
+ ),
+ 111 => array (
+ 'BasicArrowButton', 'BasicBorders', 'BasicBorders.ButtonBorder', 'BasicBorders.FieldBorder', 'BasicBorders.MarginBorder', 'BasicBorders.MenuBarBorder', 'BasicBorders.RadioButtonBorder', 'BasicBorders.RolloverButtonBorder', 'BasicBorders.SplitPaneBorder', 'BasicBorders.ToggleButtonBorder', 'BasicButtonListener', 'BasicButtonUI', 'BasicCheckBoxMenuItemUI', 'BasicCheckBoxUI', 'BasicColorChooserUI', 'BasicComboBoxEditor', 'BasicComboBoxEditor.UIResource', 'BasicComboBoxRenderer', 'BasicComboBoxRenderer.UIResource', 'BasicComboBoxUI', 'BasicComboPopup', 'BasicDesktopIconUI', 'BasicDesktopPaneUI', 'BasicDirectoryModel', 'BasicEditorPaneUI', 'BasicFileChooserUI', 'BasicFormattedTextFieldUI', 'BasicGraphicsUtils', 'BasicHTML', 'BasicIconFactory', 'BasicInternalFrameTitlePane', 'BasicInternalFrameUI', 'BasicLabelUI', 'BasicListUI', 'BasicLookAndFeel', 'BasicMenuBarUI', 'BasicMenuItemUI', 'BasicMenuUI', 'BasicOptionPaneUI', 'BasicOptionPaneUI.ButtonAreaLayout', 'BasicPanelUI', 'BasicPasswordFieldUI',
+ 'BasicPopupMenuSeparatorUI', 'BasicPopupMenuUI', 'BasicProgressBarUI', 'BasicRadioButtonMenuItemUI', 'BasicRadioButtonUI', 'BasicRootPaneUI', 'BasicScrollBarUI', 'BasicScrollPaneUI', 'BasicSeparatorUI', 'BasicSliderUI', 'BasicSpinnerUI', 'BasicSplitPaneDivider', 'BasicSplitPaneUI', 'BasicTabbedPaneUI', 'BasicTableHeaderUI', 'BasicTableUI', 'BasicTextAreaUI', 'BasicTextFieldUI', 'BasicTextPaneUI', 'BasicTextUI', 'BasicTextUI.BasicCaret', 'BasicTextUI.BasicHighlighter', 'BasicToggleButtonUI', 'BasicToolBarSeparatorUI', 'BasicToolBarUI', 'BasicToolTipUI', 'BasicTreeUI', 'BasicViewportUI', 'ComboPopup', 'DefaultMenuLayout'
+ ),
+ 112 => array (
+ 'DefaultMetalTheme', 'MetalBorders', 'MetalBorders.ButtonBorder', 'MetalBorders.Flush3DBorder', 'MetalBorders.InternalFrameBorder', 'MetalBorders.MenuBarBorder', 'MetalBorders.MenuItemBorder', 'MetalBorders.OptionDialogBorder', 'MetalBorders.PaletteBorder', 'MetalBorders.PopupMenuBorder', 'MetalBorders.RolloverButtonBorder', 'MetalBorders.ScrollPaneBorder', 'MetalBorders.TableHeaderBorder', 'MetalBorders.TextFieldBorder', 'MetalBorders.ToggleButtonBorder', 'MetalBorders.ToolBarBorder', 'MetalButtonUI', 'MetalCheckBoxIcon', 'MetalCheckBoxUI', 'MetalComboBoxButton', 'MetalComboBoxEditor', 'MetalComboBoxEditor.UIResource', 'MetalComboBoxIcon', 'MetalComboBoxUI', 'MetalDesktopIconUI', 'MetalFileChooserUI', 'MetalIconFactory', 'MetalIconFactory.FileIcon16', 'MetalIconFactory.FolderIcon16', 'MetalIconFactory.PaletteCloseIcon', 'MetalIconFactory.TreeControlIcon', 'MetalIconFactory.TreeFolderIcon', 'MetalIconFactory.TreeLeafIcon', 'MetalInternalFrameTitlePane', 'MetalInternalFrameUI', 'MetalLabelUI',
+ 'MetalLookAndFeel', 'MetalMenuBarUI', 'MetalPopupMenuSeparatorUI', 'MetalProgressBarUI', 'MetalRadioButtonUI', 'MetalRootPaneUI', 'MetalScrollBarUI', 'MetalScrollButton', 'MetalScrollPaneUI', 'MetalSeparatorUI', 'MetalSliderUI', 'MetalSplitPaneUI', 'MetalTabbedPaneUI', 'MetalTextFieldUI', 'MetalTheme', 'MetalToggleButtonUI', 'MetalToolBarUI', 'MetalToolTipUI', 'MetalTreeUI', 'OceanTheme'
+ ),
+ 113 => array (
+ 'MultiButtonUI', 'MultiColorChooserUI', 'MultiComboBoxUI', 'MultiDesktopIconUI', 'MultiDesktopPaneUI', 'MultiFileChooserUI', 'MultiInternalFrameUI', 'MultiLabelUI', 'MultiListUI', 'MultiLookAndFeel', 'MultiMenuBarUI', 'MultiMenuItemUI', 'MultiOptionPaneUI', 'MultiPanelUI', 'MultiPopupMenuUI', 'MultiProgressBarUI', 'MultiRootPaneUI', 'MultiScrollBarUI', 'MultiScrollPaneUI', 'MultiSeparatorUI', 'MultiSliderUI', 'MultiSpinnerUI', 'MultiSplitPaneUI', 'MultiTabbedPaneUI', 'MultiTableHeaderUI', 'MultiTableUI', 'MultiTextUI', 'MultiToolBarUI', 'MultiToolTipUI', 'MultiTreeUI', 'MultiViewportUI'
+ ),
+ 114 => array (
+ 'ColorType', 'Region', 'SynthConstants', 'SynthContext', 'SynthGraphicsUtils', 'SynthLookAndFeel', 'SynthPainter', 'SynthStyle', 'SynthStyleFactory'
+ ),
+ 115 => array (
+ 'AbstractTableModel', 'DefaultTableCellRenderer', 'DefaultTableCellRenderer.UIResource', 'DefaultTableColumnModel', 'DefaultTableModel', 'JTableHeader', 'TableCellEditor', 'TableCellRenderer', 'TableColumn', 'TableColumnModel', 'TableModel'
+ ),
+ 116 => array (
+ 'AbstractDocument', 'AbstractDocument.AttributeContext', 'AbstractDocument.Content', 'AbstractDocument.ElementEdit', 'AbstractWriter', 'AsyncBoxView', 'AttributeSet.CharacterAttribute', 'AttributeSet.ColorAttribute', 'AttributeSet.FontAttribute', 'AttributeSet.ParagraphAttribute', 'BadLocationException', 'BoxView', 'Caret', 'ChangedCharSetException', 'ComponentView', 'CompositeView', 'DateFormatter', 'DefaultCaret', 'DefaultEditorKit', 'DefaultEditorKit.BeepAction', 'DefaultEditorKit.CopyAction', 'DefaultEditorKit.CutAction', 'DefaultEditorKit.DefaultKeyTypedAction', 'DefaultEditorKit.InsertBreakAction', 'DefaultEditorKit.InsertContentAction', 'DefaultEditorKit.InsertTabAction', 'DefaultEditorKit.PasteAction', 'DefaultFormatter', 'DefaultFormatterFactory', 'DefaultHighlighter', 'DefaultHighlighter.DefaultHighlightPainter', 'DefaultStyledDocument', 'DefaultStyledDocument.AttributeUndoableEdit', 'DefaultStyledDocument.ElementSpec', 'DefaultTextUI', 'DocumentFilter', 'DocumentFilter.FilterBypass',
+ 'EditorKit', 'ElementIterator', 'FieldView', 'FlowView', 'FlowView.FlowStrategy', 'GapContent', 'GlyphView', 'GlyphView.GlyphPainter', 'Highlighter', 'Highlighter.Highlight', 'Highlighter.HighlightPainter', 'IconView', 'InternationalFormatter', 'JTextComponent', 'JTextComponent.KeyBinding', 'Keymap', 'LabelView', 'LayeredHighlighter', 'LayeredHighlighter.LayerPainter', 'LayoutQueue', 'MaskFormatter', 'MutableAttributeSet', 'NavigationFilter', 'NavigationFilter.FilterBypass', 'NumberFormatter', 'PasswordView', 'PlainDocument', 'PlainView', 'Position', 'Position.Bias', 'Segment', 'SimpleAttributeSet', 'StringContent', 'Style', 'StyleConstants', 'StyleConstants.CharacterConstants', 'StyleConstants.ColorConstants', 'StyleConstants.FontConstants', 'StyleConstants.ParagraphConstants', 'StyleContext', 'StyledDocument', 'StyledEditorKit', 'StyledEditorKit.AlignmentAction', 'StyledEditorKit.BoldAction', 'StyledEditorKit.FontFamilyAction', 'StyledEditorKit.FontSizeAction', 'StyledEditorKit.ForegroundAction',
+ 'StyledEditorKit.ItalicAction', 'StyledEditorKit.StyledTextAction', 'StyledEditorKit.UnderlineAction', 'TabExpander', 'TabSet', 'TabStop', 'TabableView', 'TableView', 'TextAction', 'Utilities', 'View', 'ViewFactory', 'WrappedPlainView', 'ZoneView'
+ ),
+ 117 => array (
+ 'BlockView', 'CSS', 'CSS.Attribute', 'FormSubmitEvent', 'FormSubmitEvent.MethodType', 'FormView', 'HTML', 'HTML.Attribute', 'HTML.Tag', 'HTML.UnknownTag', 'HTMLDocument', 'HTMLDocument.Iterator', 'HTMLEditorKit', 'HTMLEditorKit.HTMLFactory', 'HTMLEditorKit.HTMLTextAction', 'HTMLEditorKit.InsertHTMLTextAction', 'HTMLEditorKit.LinkController', 'HTMLEditorKit.Parser', 'HTMLEditorKit.ParserCallback', 'HTMLFrameHyperlinkEvent', 'HTMLWriter', 'ImageView', 'InlineView', 'ListView', 'MinimalHTMLWriter', 'ObjectView', 'Option', 'StyleSheet', 'StyleSheet.BoxPainter', 'StyleSheet.ListPainter'
+ ),
+ 118 => array (
+ 'ContentModel', 'DTD', 'DTDConstants', 'DocumentParser', 'ParserDelegator', 'TagElement'
+ ),
+ 119 => array (
+ 'RTFEditorKit'
+ ),
+ 120 => array (
+ 'AbstractLayoutCache', 'AbstractLayoutCache.NodeDimensions', 'DefaultMutableTreeNode', 'DefaultTreeCellEditor', 'DefaultTreeCellRenderer', 'DefaultTreeModel', 'DefaultTreeSelectionModel', 'ExpandVetoException', 'FixedHeightLayoutCache', 'MutableTreeNode', 'RowMapper', 'TreeCellEditor', 'TreeCellRenderer', 'TreeModel', 'TreeNode', 'TreePath', 'TreeSelectionModel', 'VariableHeightLayoutCache'
+ ),
+ 121 => array (
+ 'AbstractUndoableEdit', 'CannotRedoException', 'CannotUndoException', 'CompoundEdit', 'StateEdit', 'StateEditable', 'UndoManager', 'UndoableEdit', 'UndoableEditSupport'
+ ),
+ 122 => array (
+ 'InvalidTransactionException', 'TransactionRequiredException', 'TransactionRolledbackException'
+ ),
+ 123 => array (
+ 'XAException', 'XAResource', 'Xid'
+ ),
+ 124 => array (
+ 'XMLConstants'
+ ),
+ 125 => array (
+ 'DatatypeConfigurationException', 'DatatypeConstants', 'DatatypeConstants.Field', 'DatatypeFactory', 'Duration', 'XMLGregorianCalendar'
+ ),
+ 126 => array (
+ 'NamespaceContext', 'QName'
+ ),
+ 127 => array (
+ 'DocumentBuilder', 'DocumentBuilderFactory', 'FactoryConfigurationError', 'ParserConfigurationException', 'SAXParser', 'SAXParserFactory'
+ ),
+ 128 => array (
+ 'ErrorListener', 'OutputKeys', 'Result', 'Source', 'SourceLocator', 'Templates', 'Transformer', 'TransformerConfigurationException', 'TransformerException', 'TransformerFactory', 'TransformerFactoryConfigurationError', 'URIResolver'
+ ),
+ 129 => array (
+ 'DOMResult', 'DOMSource'
+ ),
+ 130 => array (
+ 'SAXResult', 'SAXSource', 'SAXTransformerFactory', 'TemplatesHandler', 'TransformerHandler'
+ ),
+ 131 => array (
+ 'StreamResult', 'StreamSource'
+ ),
+ 132 => array (
+ 'Schema', 'SchemaFactory', 'SchemaFactoryLoader', 'TypeInfoProvider', 'Validator', 'ValidatorHandler'
+ ),
+ 133 => array (
+ 'XPath', 'XPathConstants', 'XPathException', 'XPathExpression', 'XPathExpressionException', 'XPathFactory', 'XPathFactoryConfigurationException', 'XPathFunction', 'XPathFunctionException', 'XPathFunctionResolver', 'XPathVariableResolver'
+ ),
+ 134 => array (
+ 'ChannelBinding', 'GSSContext', 'GSSCredential', 'GSSException', 'GSSManager', 'GSSName', 'MessageProp', 'Oid'
+ ),
+ 135 => array (
+ 'ACTIVITY_COMPLETED', 'ACTIVITY_REQUIRED', 'ARG_IN', 'ARG_INOUT', 'ARG_OUT', 'Any', 'AnyHolder', 'AnySeqHolder', 'BAD_CONTEXT', 'BAD_INV_ORDER', 'BAD_OPERATION', 'BAD_PARAM', 'BAD_POLICY', 'BAD_POLICY_TYPE', 'BAD_POLICY_VALUE', 'BAD_QOS', 'BAD_TYPECODE', 'BooleanHolder', 'BooleanSeqHelper', 'BooleanSeqHolder', 'ByteHolder', 'CODESET_INCOMPATIBLE', 'COMM_FAILURE', 'CTX_RESTRICT_SCOPE', 'CharHolder', 'CharSeqHelper', 'CharSeqHolder', 'CompletionStatus', 'CompletionStatusHelper', 'ContextList', 'CurrentHolder', 'CustomMarshal', 'DATA_CONVERSION', 'DefinitionKind', 'DefinitionKindHelper', 'DomainManager', 'DomainManagerOperations', 'DoubleHolder', 'DoubleSeqHelper', 'DoubleSeqHolder', 'Environment', 'ExceptionList', 'FREE_MEM', 'FixedHolder', 'FloatHolder', 'FloatSeqHelper', 'FloatSeqHolder', 'IDLType', 'IDLTypeHelper', 'IDLTypeOperations', 'IMP_LIMIT', 'INITIALIZE', 'INTERNAL', 'INTF_REPOS', 'INVALID_ACTIVITY', 'INVALID_TRANSACTION', 'INV_FLAG', 'INV_IDENT', 'INV_OBJREF', 'INV_POLICY', 'IRObject',
+ 'IRObjectOperations', 'IdentifierHelper', 'IntHolder', 'LocalObject', 'LongHolder', 'LongLongSeqHelper', 'LongLongSeqHolder', 'LongSeqHelper', 'LongSeqHolder', 'MARSHAL', 'NO_IMPLEMENT', 'NO_MEMORY', 'NO_PERMISSION', 'NO_RESOURCES', 'NO_RESPONSE', 'NVList', 'NamedValue', 'OBJECT_NOT_EXIST', 'OBJ_ADAPTER', 'OMGVMCID', 'ObjectHelper', 'ObjectHolder', 'OctetSeqHelper', 'OctetSeqHolder', 'PERSIST_STORE', 'PRIVATE_MEMBER', 'PUBLIC_MEMBER', 'ParameterMode', 'ParameterModeHelper', 'ParameterModeHolder', 'PolicyError', 'PolicyErrorCodeHelper', 'PolicyErrorHelper', 'PolicyErrorHolder', 'PolicyHelper', 'PolicyHolder', 'PolicyListHelper', 'PolicyListHolder', 'PolicyOperations', 'PolicyTypeHelper', 'PrincipalHolder', 'REBIND', 'RepositoryIdHelper', 'Request', 'ServerRequest', 'ServiceDetail', 'ServiceDetailHelper', 'ServiceInformation', 'ServiceInformationHelper', 'ServiceInformationHolder', 'SetOverrideType', 'SetOverrideTypeHelper', 'ShortHolder', 'ShortSeqHelper', 'ShortSeqHolder', 'StringHolder',
+ 'StringSeqHelper', 'StringSeqHolder', 'StringValueHelper', 'StructMember', 'StructMemberHelper', 'SystemException', 'TCKind', 'TIMEOUT', 'TRANSACTION_MODE', 'TRANSACTION_REQUIRED', 'TRANSACTION_ROLLEDBACK', 'TRANSACTION_UNAVAILABLE', 'TRANSIENT', 'TypeCode', 'TypeCodeHolder', 'ULongLongSeqHelper', 'ULongLongSeqHolder', 'ULongSeqHelper', 'ULongSeqHolder', 'UNSUPPORTED_POLICY', 'UNSUPPORTED_POLICY_VALUE', 'UShortSeqHelper', 'UShortSeqHolder', 'UnionMember', 'UnionMemberHelper', 'UnknownUserException', 'UnknownUserExceptionHelper', 'UnknownUserExceptionHolder', 'UserException', 'VM_ABSTRACT', 'VM_CUSTOM', 'VM_NONE', 'VM_TRUNCATABLE', 'ValueBaseHelper', 'ValueBaseHolder', 'ValueMember', 'ValueMemberHelper', 'VersionSpecHelper', 'VisibilityHelper', 'WCharSeqHelper', 'WCharSeqHolder', 'WStringSeqHelper', 'WStringSeqHolder', 'WStringValueHelper', 'WrongTransaction', 'WrongTransactionHelper', 'WrongTransactionHolder', '_IDLTypeStub', '_PolicyStub'
+ ),
+ 136 => array (
+ 'Invalid', 'InvalidSeq'
+ ),
+ 137 => array (
+ 'BadKind'
+ ),
+ 138 => array (
+ 'ApplicationException', 'BoxedValueHelper', 'CustomValue', 'IDLEntity', 'IndirectionException', 'InvokeHandler', 'RemarshalException', 'ResponseHandler', 'ServantObject', 'Streamable', 'StreamableValue', 'UnknownException', 'ValueBase', 'ValueFactory', 'ValueInputStream', 'ValueOutputStream'
+ ),
+ 139 => array (
+ 'BindingHelper', 'BindingHolder', 'BindingIterator', 'BindingIteratorHelper', 'BindingIteratorHolder', 'BindingIteratorOperations', 'BindingIteratorPOA', 'BindingListHelper', 'BindingListHolder', 'BindingType', 'BindingTypeHelper', 'BindingTypeHolder', 'IstringHelper', 'NameComponent', 'NameComponentHelper', 'NameComponentHolder', 'NameHelper', 'NameHolder', 'NamingContext', 'NamingContextExt', 'NamingContextExtHelper', 'NamingContextExtHolder', 'NamingContextExtOperations', 'NamingContextExtPOA', 'NamingContextHelper', 'NamingContextHolder', 'NamingContextOperations', 'NamingContextPOA', '_BindingIteratorImplBase', '_BindingIteratorStub', '_NamingContextExtStub', '_NamingContextImplBase', '_NamingContextStub'
+ ),
+ 140 => array (
+ 'AddressHelper', 'InvalidAddress', 'InvalidAddressHelper', 'InvalidAddressHolder', 'StringNameHelper', 'URLStringHelper'
+ ),
+ 141 => array (
+ 'AlreadyBound', 'AlreadyBoundHelper', 'AlreadyBoundHolder', 'CannotProceed', 'CannotProceedHelper', 'CannotProceedHolder', 'InvalidNameHolder', 'NotEmpty', 'NotEmptyHelper', 'NotEmptyHolder', 'NotFound', 'NotFoundHelper', 'NotFoundHolder', 'NotFoundReason', 'NotFoundReasonHelper', 'NotFoundReasonHolder'
+ ),
+ 142 => array (
+ 'Parameter'
+ ),
+ 143 => array (
+ 'DynAnyFactory', 'DynAnyFactoryHelper', 'DynAnyFactoryOperations', 'DynAnyHelper', 'DynAnyOperations', 'DynAnySeqHelper', 'DynArrayHelper', 'DynArrayOperations', 'DynEnumHelper', 'DynEnumOperations', 'DynFixedHelper', 'DynFixedOperations', 'DynSequenceHelper', 'DynSequenceOperations', 'DynStructHelper', 'DynStructOperations', 'DynUnionHelper', 'DynUnionOperations', 'DynValueBox', 'DynValueBoxOperations', 'DynValueCommon', 'DynValueCommonOperations', 'DynValueHelper', 'DynValueOperations', 'NameDynAnyPair', 'NameDynAnyPairHelper', 'NameDynAnyPairSeqHelper', 'NameValuePairSeqHelper', '_DynAnyFactoryStub', '_DynAnyStub', '_DynArrayStub', '_DynEnumStub', '_DynFixedStub', '_DynSequenceStub', '_DynStructStub', '_DynUnionStub', '_DynValueStub'
+ ),
+ 144 => array (
+ 'InconsistentTypeCodeHelper'
+ ),
+ 145 => array (
+ 'InvalidValueHelper'
+ ),
+ 146 => array (
+ 'CodeSets', 'Codec', 'CodecFactory', 'CodecFactoryHelper', 'CodecFactoryOperations', 'CodecOperations', 'ComponentIdHelper', 'ENCODING_CDR_ENCAPS', 'Encoding', 'ExceptionDetailMessage', 'IOR', 'IORHelper', 'IORHolder', 'MultipleComponentProfileHelper', 'MultipleComponentProfileHolder', 'ProfileIdHelper', 'RMICustomMaxStreamFormat', 'ServiceContext', 'ServiceContextHelper', 'ServiceContextHolder', 'ServiceContextListHelper', 'ServiceContextListHolder', 'ServiceIdHelper', 'TAG_ALTERNATE_IIOP_ADDRESS', 'TAG_CODE_SETS', 'TAG_INTERNET_IOP', 'TAG_JAVA_CODEBASE', 'TAG_MULTIPLE_COMPONENTS', 'TAG_ORB_TYPE', 'TAG_POLICIES', 'TAG_RMI_CUSTOM_MAX_STREAM_FORMAT', 'TaggedComponent', 'TaggedComponentHelper', 'TaggedComponentHolder', 'TaggedProfile', 'TaggedProfileHelper', 'TaggedProfileHolder', 'TransactionService'
+ ),
+ 147 => array (
+ 'UnknownEncoding', 'UnknownEncodingHelper'
+ ),
+ 148 => array (
+ 'FormatMismatch', 'FormatMismatchHelper', 'InvalidTypeForEncoding', 'InvalidTypeForEncodingHelper'
+ ),
+ 149 => array (
+ 'SYNC_WITH_TRANSPORT', 'SyncScopeHelper'
+ ),
+ 150 => array (
+ 'ACTIVE', 'AdapterManagerIdHelper', 'AdapterNameHelper', 'AdapterStateHelper', 'ClientRequestInfo', 'ClientRequestInfoOperations', 'ClientRequestInterceptor', 'ClientRequestInterceptorOperations', 'DISCARDING', 'HOLDING', 'INACTIVE', 'IORInfo', 'IORInfoOperations', 'IORInterceptor', 'IORInterceptorOperations', 'IORInterceptor_3_0', 'IORInterceptor_3_0Helper', 'IORInterceptor_3_0Holder', 'IORInterceptor_3_0Operations', 'Interceptor', 'InterceptorOperations', 'InvalidSlot', 'InvalidSlotHelper', 'LOCATION_FORWARD', 'NON_EXISTENT', 'ORBIdHelper', 'ORBInitInfo', 'ORBInitInfoOperations', 'ORBInitializer', 'ORBInitializerOperations', 'ObjectReferenceFactory', 'ObjectReferenceFactoryHelper', 'ObjectReferenceFactoryHolder', 'ObjectReferenceTemplate', 'ObjectReferenceTemplateHelper', 'ObjectReferenceTemplateHolder', 'ObjectReferenceTemplateSeqHelper', 'ObjectReferenceTemplateSeqHolder', 'PolicyFactory', 'PolicyFactoryOperations', 'RequestInfo', 'RequestInfoOperations', 'SUCCESSFUL', 'SYSTEM_EXCEPTION',
+ 'ServerIdHelper', 'ServerRequestInfo', 'ServerRequestInfoOperations', 'ServerRequestInterceptor', 'ServerRequestInterceptorOperations', 'TRANSPORT_RETRY', 'USER_EXCEPTION'
+ ),
+ 151 => array (
+ 'DuplicateName', 'DuplicateNameHelper'
+ ),
+ 152 => array (
+ 'AdapterActivator', 'AdapterActivatorOperations', 'ID_ASSIGNMENT_POLICY_ID', 'ID_UNIQUENESS_POLICY_ID', 'IMPLICIT_ACTIVATION_POLICY_ID', 'IdAssignmentPolicy', 'IdAssignmentPolicyOperations', 'IdAssignmentPolicyValue', 'IdUniquenessPolicy', 'IdUniquenessPolicyOperations', 'IdUniquenessPolicyValue', 'ImplicitActivationPolicy', 'ImplicitActivationPolicyOperations', 'ImplicitActivationPolicyValue', 'LIFESPAN_POLICY_ID', 'LifespanPolicy', 'LifespanPolicyOperations', 'LifespanPolicyValue', 'POA', 'POAHelper', 'POAManager', 'POAManagerOperations', 'POAOperations', 'REQUEST_PROCESSING_POLICY_ID', 'RequestProcessingPolicy', 'RequestProcessingPolicyOperations', 'RequestProcessingPolicyValue', 'SERVANT_RETENTION_POLICY_ID', 'Servant', 'ServantActivator', 'ServantActivatorHelper', 'ServantActivatorOperations', 'ServantActivatorPOA', 'ServantLocator', 'ServantLocatorHelper', 'ServantLocatorOperations', 'ServantLocatorPOA', 'ServantManager', 'ServantManagerOperations', 'ServantRetentionPolicy',
+ 'ServantRetentionPolicyOperations', 'ServantRetentionPolicyValue', 'THREAD_POLICY_ID', 'ThreadPolicy', 'ThreadPolicyOperations', 'ThreadPolicyValue', '_ServantActivatorStub', '_ServantLocatorStub'
+ ),
+ 153 => array (
+ 'NoContext', 'NoContextHelper'
+ ),
+ 154 => array (
+ 'AdapterInactive', 'AdapterInactiveHelper', 'State'
+ ),
+ 155 => array (
+ 'AdapterAlreadyExists', 'AdapterAlreadyExistsHelper', 'AdapterNonExistent', 'AdapterNonExistentHelper', 'InvalidPolicy', 'InvalidPolicyHelper', 'NoServant', 'NoServantHelper', 'ObjectAlreadyActive', 'ObjectAlreadyActiveHelper', 'ObjectNotActive', 'ObjectNotActiveHelper', 'ServantAlreadyActive', 'ServantAlreadyActiveHelper', 'ServantNotActive', 'ServantNotActiveHelper', 'WrongAdapter', 'WrongAdapterHelper', 'WrongPolicy', 'WrongPolicyHelper'
+ ),
+ 156 => array (
+ 'CookieHolder'
+ ),
+ 157 => array (
+ 'RunTime', 'RunTimeOperations'
+ ),
+ 158 => array (
+ '_Remote_Stub'
+ ),
+ 159 => array (
+ 'Attr', 'CDATASection', 'CharacterData', 'Comment', 'DOMConfiguration', 'DOMError', 'DOMErrorHandler', 'DOMException', 'DOMImplementation', 'DOMImplementationList', 'DOMImplementationSource', 'DOMStringList', 'DocumentFragment', 'DocumentType', 'EntityReference', 'NameList', 'NamedNodeMap', 'Node', 'NodeList', 'Notation', 'ProcessingInstruction', 'Text', 'TypeInfo', 'UserDataHandler'
+ ),
+ 160 => array (
+ 'DOMImplementationRegistry'
+ ),
+ 161 => array (
+ 'EventException', 'EventTarget', 'MutationEvent', 'UIEvent'
+ ),
+ 162 => array (
+ 'DOMImplementationLS', 'LSException', 'LSInput', 'LSLoadEvent', 'LSOutput', 'LSParser', 'LSParserFilter', 'LSProgressEvent', 'LSResourceResolver', 'LSSerializer', 'LSSerializerFilter'
+ ),
+ 163 => array (
+ 'DTDHandler', 'DocumentHandler', 'EntityResolver', 'ErrorHandler', 'HandlerBase', 'InputSource', 'Locator', 'SAXException', 'SAXNotRecognizedException', 'SAXNotSupportedException', 'SAXParseException', 'XMLFilter', 'XMLReader'
+ ),
+ 164 => array (
+ 'Attributes2', 'Attributes2Impl', 'DeclHandler', 'DefaultHandler2', 'EntityResolver2', 'LexicalHandler', 'Locator2', 'Locator2Impl'
+ ),
+ 165 => array (
+ 'AttributeListImpl', 'AttributesImpl', 'DefaultHandler', 'LocatorImpl', 'NamespaceSupport', 'ParserAdapter', 'ParserFactory', 'XMLFilterImpl', 'XMLReaderAdapter', 'XMLReaderFactory'
+ ),
+ /* ambiguous class names (appear in more than one package) */
+ 166 => array (
+ 'Annotation', 'AnySeqHelper', 'Array', 'Attribute', 'AttributeList', 'AttributeSet', 'Attributes', 'AuthenticationException', 'Binding', 'Bounds', 'Certificate', 'CertificateEncodingException', 'CertificateException', 'CertificateExpiredException', 'CertificateNotYetValidException', 'CertificateParsingException', 'ConnectException', 'ContentHandler', 'Context', 'Control', 'Current', 'CurrentHelper', 'CurrentOperations', 'DOMLocator', 'DataInputStream', 'DataOutputStream', 'Date', 'DefaultLoaderRepository', 'Delegate', 'Document', 'DocumentEvent', 'DynAny', 'DynArray', 'DynEnum', 'DynFixed', 'DynSequence', 'DynStruct', 'DynUnion', 'DynValue', 'DynamicImplementation', 'Element', 'Entity', 'Event', 'EventListener', 'FieldNameHelper', 'FileFilter', 'Formatter', 'ForwardRequest', 'ForwardRequestHelper', 'InconsistentTypeCode', 'InputStream', 'IntrospectionException', 'InvalidAttributeValueException', 'InvalidKeyException', 'InvalidName', 'InvalidNameHelper', 'InvalidValue', 'List', 'MouseEvent',
+ 'NameValuePair', 'NameValuePairHelper', 'ORB', 'Object', 'ObjectIdHelper', 'ObjectImpl', 'OpenType', 'OutputStream', 'ParagraphView', 'Parser', 'Permission', 'Policy', 'Principal', 'Proxy', 'Reference', 'Statement', 'Timer', 'Timestamp', 'TypeMismatch', 'TypeMismatchHelper', 'UNKNOWN', 'UnknownHostException', 'X509Certificate'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '*', '&', '%', '!', ';', '<', '>', '?'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ /* all Java keywords are case sensitive */
+ 1 => true, 2 => true, 3 => true, 4 => true,
+ 5 => true, 6 => true, 7 => true, 8 => true, 9 => true,
+ 10 => true, 11 => true, 12 => true, 13 => true, 14 => true,
+ 15 => true, 16 => true, 17 => true, 18 => true, 19 => true,
+ 20 => true, 21 => true, 22 => true, 23 => true, 24 => true,
+ 25 => true, 26 => true, 27 => true, 28 => true, 29 => true,
+ 30 => true, 31 => true, 32 => true, 33 => true, 34 => true,
+ 35 => true, 36 => true, 37 => true, 38 => true, 39 => true,
+ 40 => true, 41 => true, 42 => true, 43 => true, 44 => true,
+ 45 => true, 46 => true, 47 => true, 48 => true, 49 => true,
+ 50 => true, 51 => true, 52 => true, 53 => true, 54 => true,
+ 55 => true, 56 => true, 57 => true, 58 => true, 59 => true,
+ 60 => true, 61 => true, 62 => true, 63 => true, 64 => true,
+ 65 => true, 66 => true, 67 => true, 68 => true, 69 => true,
+ 70 => true, 71 => true, 72 => true, 73 => true, 74 => true,
+ 75 => true, 76 => true, 77 => true, 78 => true, 79 => true,
+ 80 => true, 81 => true, 82 => true, 83 => true, 84 => true,
+ 85 => true, 86 => true, 87 => true, 88 => true, 89 => true,
+ 90 => true, 91 => true, 92 => true, 93 => true, 94 => true,
+ 95 => true, 96 => true, 97 => true, 98 => true, 99 => true,
+ 100 => true, 101 => true, 102 => true, 103 => true, 104 => true,
+ 105 => true, 106 => true, 107 => true, 108 => true, 109 => true,
+ 110 => true, 111 => true, 112 => true, 113 => true, 114 => true,
+ 115 => true, 116 => true, 117 => true, 118 => true, 119 => true,
+ 120 => true, 121 => true, 122 => true, 123 => true, 124 => true,
+ 125 => true, 126 => true, 127 => true, 128 => true, 129 => true,
+ 130 => true, 131 => true, 132 => true, 133 => true, 134 => true,
+ 135 => true, 136 => true, 137 => true, 138 => true, 139 => true,
+ 140 => true, 141 => true, 142 => true, 143 => true, 144 => true,
+ 145 => true, 146 => true, 147 => true, 148 => true, 149 => true,
+ 150 => true, 151 => true, 152 => true, 153 => true, 154 => true,
+ 155 => true, 156 => true, 157 => true, 158 => true, 159 => true,
+ 160 => true, 161 => true, 162 => true, 163 => true, 164 => true,
+ 165 => true, 166 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #006600; font-weight: bold;',
+ 4 => 'color: #006600; font-weight: bold;',
+ 5 => 'color: #003399; font-weight: bold;',
+ 6 => 'color: #003399; font-weight: bold;',
+ 7 => 'color: #003399; font-weight: bold;',
+ 8 => 'color: #003399; font-weight: bold;',
+ 9 => 'color: #003399; font-weight: bold;',
+ 10 => 'color: #003399; font-weight: bold;',
+ 11 => 'color: #003399; font-weight: bold;',
+ 12 => 'color: #003399; font-weight: bold;',
+ 13 => 'color: #003399; font-weight: bold;',
+ 14 => 'color: #003399; font-weight: bold;',
+ 15 => 'color: #003399; font-weight: bold;',
+ 16 => 'color: #003399; font-weight: bold;',
+ 17 => 'color: #003399; font-weight: bold;',
+ 18 => 'color: #003399; font-weight: bold;',
+ 19 => 'color: #003399; font-weight: bold;',
+ 20 => 'color: #003399; font-weight: bold;',
+ 21 => 'color: #003399; font-weight: bold;',
+ 22 => 'color: #003399; font-weight: bold;',
+ 23 => 'color: #003399; font-weight: bold;',
+ 24 => 'color: #003399; font-weight: bold;',
+ 25 => 'color: #003399; font-weight: bold;',
+ 26 => 'color: #003399; font-weight: bold;',
+ 27 => 'color: #003399; font-weight: bold;',
+ 28 => 'color: #003399; font-weight: bold;',
+ 29 => 'color: #003399; font-weight: bold;',
+ 30 => 'color: #003399; font-weight: bold;',
+ 31 => 'color: #003399; font-weight: bold;',
+ 32 => 'color: #003399; font-weight: bold;',
+ 33 => 'color: #003399; font-weight: bold;',
+ 34 => 'color: #003399; font-weight: bold;',
+ 35 => 'color: #003399; font-weight: bold;',
+ 36 => 'color: #003399; font-weight: bold;',
+ 37 => 'color: #003399; font-weight: bold;',
+ 38 => 'color: #003399; font-weight: bold;',
+ 39 => 'color: #003399; font-weight: bold;',
+ 40 => 'color: #003399; font-weight: bold;',
+ 41 => 'color: #003399; font-weight: bold;',
+ 42 => 'color: #003399; font-weight: bold;',
+ 43 => 'color: #003399; font-weight: bold;',
+ 44 => 'color: #003399; font-weight: bold;',
+ 45 => 'color: #003399; font-weight: bold;',
+ 46 => 'color: #003399; font-weight: bold;',
+ 47 => 'color: #003399; font-weight: bold;',
+ 48 => 'color: #003399; font-weight: bold;',
+ 49 => 'color: #003399; font-weight: bold;',
+ 50 => 'color: #003399; font-weight: bold;',
+ 51 => 'color: #003399; font-weight: bold;',
+ 52 => 'color: #003399; font-weight: bold;',
+ 53 => 'color: #003399; font-weight: bold;',
+ 54 => 'color: #003399; font-weight: bold;',
+ 55 => 'color: #003399; font-weight: bold;',
+ 56 => 'color: #003399; font-weight: bold;',
+ 57 => 'color: #003399; font-weight: bold;',
+ 58 => 'color: #003399; font-weight: bold;',
+ 59 => 'color: #003399; font-weight: bold;',
+ 60 => 'color: #003399; font-weight: bold;',
+ 61 => 'color: #003399; font-weight: bold;',
+ 62 => 'color: #003399; font-weight: bold;',
+ 63 => 'color: #003399; font-weight: bold;',
+ 64 => 'color: #003399; font-weight: bold;',
+ 65 => 'color: #003399; font-weight: bold;',
+ 66 => 'color: #003399; font-weight: bold;',
+ 67 => 'color: #003399; font-weight: bold;',
+ 68 => 'color: #003399; font-weight: bold;',
+ 69 => 'color: #003399; font-weight: bold;',
+ 70 => 'color: #003399; font-weight: bold;',
+ 71 => 'color: #003399; font-weight: bold;',
+ 72 => 'color: #003399; font-weight: bold;',
+ 73 => 'color: #003399; font-weight: bold;',
+ 74 => 'color: #003399; font-weight: bold;',
+ 75 => 'color: #003399; font-weight: bold;',
+ 76 => 'color: #003399; font-weight: bold;',
+ 77 => 'color: #003399; font-weight: bold;',
+ 78 => 'color: #003399; font-weight: bold;',
+ 79 => 'color: #003399; font-weight: bold;',
+ 80 => 'color: #003399; font-weight: bold;',
+ 81 => 'color: #003399; font-weight: bold;',
+ 82 => 'color: #003399; font-weight: bold;',
+ 83 => 'color: #003399; font-weight: bold;',
+ 84 => 'color: #003399; font-weight: bold;',
+ 85 => 'color: #003399; font-weight: bold;',
+ 86 => 'color: #003399; font-weight: bold;',
+ 87 => 'color: #003399; font-weight: bold;',
+ 88 => 'color: #003399; font-weight: bold;',
+ 89 => 'color: #003399; font-weight: bold;',
+ 90 => 'color: #003399; font-weight: bold;',
+ 91 => 'color: #003399; font-weight: bold;',
+ 92 => 'color: #003399; font-weight: bold;',
+ 93 => 'color: #003399; font-weight: bold;',
+ 94 => 'color: #003399; font-weight: bold;',
+ 95 => 'color: #003399; font-weight: bold;',
+ 96 => 'color: #003399; font-weight: bold;',
+ 97 => 'color: #003399; font-weight: bold;',
+ 98 => 'color: #003399; font-weight: bold;',
+ 99 => 'color: #003399; font-weight: bold;',
+ 100 => 'color: #003399; font-weight: bold;',
+ 101 => 'color: #003399; font-weight: bold;',
+ 102 => 'color: #003399; font-weight: bold;',
+ 103 => 'color: #003399; font-weight: bold;',
+ 104 => 'color: #003399; font-weight: bold;',
+ 105 => 'color: #003399; font-weight: bold;',
+ 106 => 'color: #003399; font-weight: bold;',
+ 107 => 'color: #003399; font-weight: bold;',
+ 108 => 'color: #003399; font-weight: bold;',
+ 109 => 'color: #003399; font-weight: bold;',
+ 110 => 'color: #003399; font-weight: bold;',
+ 111 => 'color: #003399; font-weight: bold;',
+ 112 => 'color: #003399; font-weight: bold;',
+ 113 => 'color: #003399; font-weight: bold;',
+ 114 => 'color: #003399; font-weight: bold;',
+ 115 => 'color: #003399; font-weight: bold;',
+ 116 => 'color: #003399; font-weight: bold;',
+ 117 => 'color: #003399; font-weight: bold;',
+ 118 => 'color: #003399; font-weight: bold;',
+ 119 => 'color: #003399; font-weight: bold;',
+ 120 => 'color: #003399; font-weight: bold;',
+ 121 => 'color: #003399; font-weight: bold;',
+ 122 => 'color: #003399; font-weight: bold;',
+ 123 => 'color: #003399; font-weight: bold;',
+ 124 => 'color: #003399; font-weight: bold;',
+ 125 => 'color: #003399; font-weight: bold;',
+ 126 => 'color: #003399; font-weight: bold;',
+ 127 => 'color: #003399; font-weight: bold;',
+ 128 => 'color: #003399; font-weight: bold;',
+ 129 => 'color: #003399; font-weight: bold;',
+ 130 => 'color: #003399; font-weight: bold;',
+ 131 => 'color: #003399; font-weight: bold;',
+ 132 => 'color: #003399; font-weight: bold;',
+ 133 => 'color: #003399; font-weight: bold;',
+ 134 => 'color: #003399; font-weight: bold;',
+ 135 => 'color: #003399; font-weight: bold;',
+ 136 => 'color: #003399; font-weight: bold;',
+ 137 => 'color: #003399; font-weight: bold;',
+ 138 => 'color: #003399; font-weight: bold;',
+ 139 => 'color: #003399; font-weight: bold;',
+ 140 => 'color: #003399; font-weight: bold;',
+ 141 => 'color: #003399; font-weight: bold;',
+ 142 => 'color: #003399; font-weight: bold;',
+ 143 => 'color: #003399; font-weight: bold;',
+ 144 => 'color: #003399; font-weight: bold;',
+ 145 => 'color: #003399; font-weight: bold;',
+ 146 => 'color: #003399; font-weight: bold;',
+ 147 => 'color: #003399; font-weight: bold;',
+ 148 => 'color: #003399; font-weight: bold;',
+ 149 => 'color: #003399; font-weight: bold;',
+ 150 => 'color: #003399; font-weight: bold;',
+ 151 => 'color: #003399; font-weight: bold;',
+ 152 => 'color: #003399; font-weight: bold;',
+ 153 => 'color: #003399; font-weight: bold;',
+ 154 => 'color: #003399; font-weight: bold;',
+ 155 => 'color: #003399; font-weight: bold;',
+ 156 => 'color: #003399; font-weight: bold;',
+ 157 => 'color: #003399; font-weight: bold;',
+ 158 => 'color: #003399; font-weight: bold;',
+ 159 => 'color: #003399; font-weight: bold;',
+ 160 => 'color: #003399; font-weight: bold;',
+ 161 => 'color: #003399; font-weight: bold;',
+ 162 => 'color: #003399; font-weight: bold;',
+ 163 => 'color: #003399; font-weight: bold;',
+ 164 => 'color: #003399; font-weight: bold;',
+ 165 => 'color: #003399; font-weight: bold;',
+ 166 => 'color: #003399; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #006699;',
+ 3 => 'color: #008000; font-style: italic; font-weight: bold;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006633;',
+ 2 => 'color: #006633;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => 'http://docs.oracle.com/javase/7/docs/api/java/applet/{FNAME}.html',
+ 6 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/{FNAME}.html',
+ 7 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/color/{FNAME}.html',
+ 8 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/datatransfer/{FNAME}.html',
+ 9 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/dnd/{FNAME}.html',
+ 10 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/event/{FNAME}.html',
+ 11 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/font/{FNAME}.html',
+ 12 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/geom/{FNAME}.html',
+ 13 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/im/{FNAME}.html',
+ 14 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/im/spi/{FNAME}.html',
+ 15 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/image/{FNAME}.html',
+ 16 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/image/renderable/{FNAME}.html',
+ 17 => 'http://docs.oracle.com/javase/7/docs/api/java/awt/print/{FNAME}.html',
+ 18 => 'http://docs.oracle.com/javase/7/docs/api/java/beans/{FNAME}.html',
+ 19 => 'http://docs.oracle.com/javase/7/docs/api/java/beans/beancontext/{FNAME}.html',
+ 20 => 'http://docs.oracle.com/javase/7/docs/api/java/io/{FNAME}.html',
+ 21 => 'http://docs.oracle.com/javase/7/docs/api/java/lang/{FNAME}.html',
+ 22 => 'http://docs.oracle.com/javase/7/docs/api/java/lang/annotation/{FNAME}.html',
+ 23 => 'http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/{FNAME}.html',
+ 24 => 'http://docs.oracle.com/javase/7/docs/api/java/lang/management/{FNAME}.html',
+ 25 => 'http://docs.oracle.com/javase/7/docs/api/java/lang/ref/{FNAME}.html',
+ 26 => 'http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/{FNAME}.html',
+ 27 => 'http://docs.oracle.com/javase/7/docs/api/java/math/{FNAME}.html',
+ 28 => 'http://docs.oracle.com/javase/7/docs/api/java/net/{FNAME}.html',
+ 29 => 'http://docs.oracle.com/javase/7/docs/api/java/nio/{FNAME}.html',
+ 30 => 'http://docs.oracle.com/javase/7/docs/api/java/nio/channels/{FNAME}.html',
+ 31 => 'http://docs.oracle.com/javase/7/docs/api/java/nio/channels/spi/{FNAME}.html',
+ 32 => 'http://docs.oracle.com/javase/7/docs/api/java/nio/charset/{FNAME}.html',
+ 33 => 'http://docs.oracle.com/javase/7/docs/api/java/nio/charset/spi/{FNAME}.html',
+ 34 => 'http://docs.oracle.com/javase/7/docs/api/java/rmi/{FNAME}.html',
+ 35 => 'http://docs.oracle.com/javase/7/docs/api/java/rmi/activation/{FNAME}.html',
+ 36 => 'http://docs.oracle.com/javase/7/docs/api/java/rmi/dgc/{FNAME}.html',
+ 37 => 'http://docs.oracle.com/javase/7/docs/api/java/rmi/registry/{FNAME}.html',
+ 38 => 'http://docs.oracle.com/javase/7/docs/api/java/rmi/server/{FNAME}.html',
+ 39 => 'http://docs.oracle.com/javase/7/docs/api/java/security/{FNAME}.html',
+ 40 => 'http://docs.oracle.com/javase/7/docs/api/java/security/acl/{FNAME}.html',
+ 41 => 'http://docs.oracle.com/javase/7/docs/api/java/security/cert/{FNAME}.html',
+ 42 => 'http://docs.oracle.com/javase/7/docs/api/java/security/interfaces/{FNAME}.html',
+ 43 => 'http://docs.oracle.com/javase/7/docs/api/java/security/spec/{FNAME}.html',
+ 44 => 'http://docs.oracle.com/javase/7/docs/api/java/sql/{FNAME}.html',
+ 45 => 'http://docs.oracle.com/javase/7/docs/api/java/text/{FNAME}.html',
+ 46 => 'http://docs.oracle.com/javase/7/docs/api/java/util/{FNAME}.html',
+ 47 => 'http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/{FNAME}.html',
+ 48 => 'http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/{FNAME}.html',
+ 49 => 'http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/{FNAME}.html',
+ 50 => 'http://docs.oracle.com/javase/7/docs/api/java/util/jar/{FNAME}.html',
+ 51 => 'http://docs.oracle.com/javase/7/docs/api/java/util/logging/{FNAME}.html',
+ 52 => 'http://docs.oracle.com/javase/7/docs/api/java/util/prefs/{FNAME}.html',
+ 53 => 'http://docs.oracle.com/javase/7/docs/api/java/util/regex/{FNAME}.html',
+ 54 => 'http://docs.oracle.com/javase/7/docs/api/java/util/zip/{FNAME}.html',
+ 55 => 'http://docs.oracle.com/javase/7/docs/api/javax/accessibility/{FNAME}.html',
+ 56 => 'http://docs.oracle.com/javase/7/docs/api/javax/activity/{FNAME}.html',
+ 57 => 'http://docs.oracle.com/javase/7/docs/api/javax/crypto/{FNAME}.html',
+ 58 => 'http://docs.oracle.com/javase/7/docs/api/javax/crypto/interfaces/{FNAME}.html',
+ 59 => 'http://docs.oracle.com/javase/7/docs/api/javax/crypto/spec/{FNAME}.html',
+ 60 => 'http://docs.oracle.com/javase/7/docs/api/javax/imageio/{FNAME}.html',
+ 61 => 'http://docs.oracle.com/javase/7/docs/api/javax/imageio/event/{FNAME}.html',
+ 62 => 'http://docs.oracle.com/javase/7/docs/api/javax/imageio/metadata/{FNAME}.html',
+ 63 => 'http://docs.oracle.com/javase/7/docs/api/javax/imageio/plugins/bmp/{FNAME}.html',
+ 64 => 'http://docs.oracle.com/javase/7/docs/api/javax/imageio/plugins/jpeg/{FNAME}.html',
+ 65 => 'http://docs.oracle.com/javase/7/docs/api/javax/imageio/spi/{FNAME}.html',
+ 66 => 'http://docs.oracle.com/javase/7/docs/api/javax/imageio/stream/{FNAME}.html',
+ 67 => 'http://docs.oracle.com/javase/7/docs/api/javax/management/{FNAME}.html',
+ 68 => 'http://docs.oracle.com/javase/7/docs/api/javax/management/loading/{FNAME}.html',
+ 69 => 'http://docs.oracle.com/javase/7/docs/api/javax/management/modelmbean/{FNAME}.html',
+ 70 => 'http://docs.oracle.com/javase/7/docs/api/javax/management/monitor/{FNAME}.html',
+ 71 => 'http://docs.oracle.com/javase/7/docs/api/javax/management/openmbean/{FNAME}.html',
+ 72 => 'http://docs.oracle.com/javase/7/docs/api/javax/management/relation/{FNAME}.html',
+ 73 => 'http://docs.oracle.com/javase/7/docs/api/javax/management/remote/{FNAME}.html',
+ 74 => 'http://docs.oracle.com/javase/7/docs/api/javax/management/remote/rmi/{FNAME}.html',
+ 75 => 'http://docs.oracle.com/javase/7/docs/api/javax/management/timer/{FNAME}.html',
+ 76 => 'http://docs.oracle.com/javase/7/docs/api/javax/naming/{FNAME}.html',
+ 77 => 'http://docs.oracle.com/javase/7/docs/api/javax/naming/directory/{FNAME}.html',
+ 78 => 'http://docs.oracle.com/javase/7/docs/api/javax/naming/event/{FNAME}.html',
+ 79 => 'http://docs.oracle.com/javase/7/docs/api/javax/naming/ldap/{FNAME}.html',
+ 80 => 'http://docs.oracle.com/javase/7/docs/api/javax/naming/spi/{FNAME}.html',
+ 81 => 'http://docs.oracle.com/javase/7/docs/api/javax/net/{FNAME}.html',
+ 82 => 'http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/{FNAME}.html',
+ 83 => 'http://docs.oracle.com/javase/7/docs/api/javax/print/{FNAME}.html',
+ 84 => 'http://docs.oracle.com/javase/7/docs/api/javax/print/attribute/{FNAME}.html',
+ 85 => 'http://docs.oracle.com/javase/7/docs/api/javax/print/attribute/standard/{FNAME}.html',
+ 86 => 'http://docs.oracle.com/javase/7/docs/api/javax/print/event/{FNAME}.html',
+ 87 => 'http://docs.oracle.com/javase/7/docs/api/javax/rmi/{FNAME}.html',
+ 88 => 'http://docs.oracle.com/javase/7/docs/api/javax/rmi/CORBA/{FNAME}.html',
+ 89 => 'http://docs.oracle.com/javase/7/docs/api/javax/rmi/ssl/{FNAME}.html',
+ 90 => 'http://docs.oracle.com/javase/7/docs/api/javax/security/auth/{FNAME}.html',
+ 91 => 'http://docs.oracle.com/javase/7/docs/api/javax/security/auth/callback/{FNAME}.html',
+ 92 => 'http://docs.oracle.com/javase/7/docs/api/javax/security/auth/kerberos/{FNAME}.html',
+ 93 => 'http://docs.oracle.com/javase/7/docs/api/javax/security/auth/login/{FNAME}.html',
+ 94 => 'http://docs.oracle.com/javase/7/docs/api/javax/security/auth/spi/{FNAME}.html',
+ 95 => 'http://docs.oracle.com/javase/7/docs/api/javax/security/auth/x500/{FNAME}.html',
+ 96 => 'http://docs.oracle.com/javase/7/docs/api/javax/security/sasl/{FNAME}.html',
+ 97 => 'http://docs.oracle.com/javase/7/docs/api/javax/sound/midi/{FNAME}.html',
+ 98 => 'http://docs.oracle.com/javase/7/docs/api/javax/sound/midi/spi/{FNAME}.html',
+ 99 => 'http://docs.oracle.com/javase/7/docs/api/javax/sound/sampled/{FNAME}.html',
+ 100 => 'http://docs.oracle.com/javase/7/docs/api/javax/sound/sampled/spi/{FNAME}.html',
+ 101 => 'http://docs.oracle.com/javase/7/docs/api/javax/sql/{FNAME}.html',
+ 102 => 'http://docs.oracle.com/javase/7/docs/api/javax/sql/rowset/{FNAME}.html',
+ 103 => 'http://docs.oracle.com/javase/7/docs/api/javax/sql/rowset/serial/{FNAME}.html',
+ 104 => 'http://docs.oracle.com/javase/7/docs/api/javax/sql/rowset/spi/{FNAME}.html',
+ 105 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/{FNAME}.html',
+ 106 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/border/{FNAME}.html',
+ 107 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/colorchooser/{FNAME}.html',
+ 108 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/event/{FNAME}.html',
+ 109 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/filechooser/{FNAME}.html',
+ 110 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/plaf/{FNAME}.html',
+ 111 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/plaf/basic/{FNAME}.html',
+ 112 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/plaf/metal/{FNAME}.html',
+ 113 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/plaf/multi/{FNAME}.html',
+ 114 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/plaf/synth/{FNAME}.html',
+ 115 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/table/{FNAME}.html',
+ 116 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/text/{FNAME}.html',
+ 117 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/text/html/{FNAME}.html',
+ 118 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/text/html/parser/{FNAME}.html',
+ 119 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/text/rtf/{FNAME}.html',
+ 120 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/tree/{FNAME}.html',
+ 121 => 'http://docs.oracle.com/javase/7/docs/api/javax/swing/undo/{FNAME}.html',
+ 122 => 'http://docs.oracle.com/javase/7/docs/api/javax/transaction/{FNAME}.html',
+ 123 => 'http://docs.oracle.com/javase/7/docs/api/javax/transaction/xa/{FNAME}.html',
+ 124 => 'http://docs.oracle.com/javase/7/docs/api/javax/xml/{FNAME}.html',
+ 125 => 'http://docs.oracle.com/javase/7/docs/api/javax/xml/datatype/{FNAME}.html',
+ 126 => 'http://docs.oracle.com/javase/7/docs/api/javax/xml/namespace/{FNAME}.html',
+ 127 => 'http://docs.oracle.com/javase/7/docs/api/javax/xml/parsers/{FNAME}.html',
+ 128 => 'http://docs.oracle.com/javase/7/docs/api/javax/xml/transform/{FNAME}.html',
+ 129 => 'http://docs.oracle.com/javase/7/docs/api/javax/xml/transform/dom/{FNAME}.html',
+ 130 => 'http://docs.oracle.com/javase/7/docs/api/javax/xml/transform/sax/{FNAME}.html',
+ 131 => 'http://docs.oracle.com/javase/7/docs/api/javax/xml/transform/stream/{FNAME}.html',
+ 132 => 'http://docs.oracle.com/javase/7/docs/api/javax/xml/validation/{FNAME}.html',
+ 133 => 'http://docs.oracle.com/javase/7/docs/api/javax/xml/xpath/{FNAME}.html',
+ 134 => 'http://docs.oracle.com/javase/7/docs/api/org/ietf/jgss/{FNAME}.html',
+ 135 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/CORBA/{FNAME}.html',
+ 136 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/CORBA/DynAnyPackage/{FNAME}.html',
+ 137 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/CORBA/TypeCodePackage/{FNAME}.html',
+ 138 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/CORBA/portable/{FNAME}.html',
+ 139 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/CosNaming/{FNAME}.html',
+ 140 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/CosNaming/NamingContextExtPackage/{FNAME}.html',
+ 141 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/CosNaming/NamingContextPackage/{FNAME}.html',
+ 142 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/Dynamic/{FNAME}.html',
+ 143 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/DynamicAny/{FNAME}.html',
+ 144 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/DynamicAny/DynAnyFactoryPackage/{FNAME}.html',
+ 145 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/DynamicAny/DynAnyPackage/{FNAME}.html',
+ 146 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/IOP/{FNAME}.html',
+ 147 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/IOP/CodecFactoryPackage/{FNAME}.html',
+ 148 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/IOP/CodecPackage/{FNAME}.html',
+ 149 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/Messaging/{FNAME}.html',
+ 150 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/PortableInterceptor/{FNAME}.html',
+ 151 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/PortableInterceptor/ORBInitInfoPackage/{FNAME}.html',
+ 152 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/PortableServer/{FNAME}.html',
+ 153 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/PortableServer/CurrentPackage/{FNAME}.html',
+ 154 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/PortableServer/POAManagerPackage/{FNAME}.html',
+ 155 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/PortableServer/POAPackage/{FNAME}.html',
+ 156 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/PortableServer/ServantLocatorPackage/{FNAME}.html',
+ 157 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/SendingContext/{FNAME}.html',
+ 158 => 'http://docs.oracle.com/javase/7/docs/api/org/omg/stub/java/rmi/{FNAME}.html',
+ 159 => 'http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/{FNAME}.html',
+ 160 => 'http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/bootstrap/{FNAME}.html',
+ 161 => 'http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/events/{FNAME}.html',
+ 162 => 'http://docs.oracle.com/javase/7/docs/api/org/w3c/dom/ls/{FNAME}.html',
+ 163 => 'http://docs.oracle.com/javase/7/docs/api/org/xml/sax/{FNAME}.html',
+ 164 => 'http://docs.oracle.com/javase/7/docs/api/org/xml/sax/ext/{FNAME}.html',
+ 165 => 'http://docs.oracle.com/javase/7/docs/api/org/xml/sax/helpers/{FNAME}.html',
+ /* ambiguous class names (appear in more than one package) */
+ 166 => 'http://www.google.com/search?sitesearch=docs.oracle.com&amp;q=allinurl%3Ajavase+docs+api+{FNAME}'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ /* Java does not use '::' */
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#>|^&"\'])',
+ 'DISALLOWED_AFTER' => '(?![a-zA-Z0-9_\|%\\-;"\'])'
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/javascript.php b/platform/www/vendor/geshi/geshi/src/geshi/javascript.php
new file mode 100644
index 0000000..70fca9c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/javascript.php
@@ -0,0 +1,172 @@
+<?php
+/*************************************************************************************
+ * javascript.php
+ * --------------
+ * Author: Ben Keen (ben.keen@gmail.com)
+ * Copyright: (c) 2004 Ben Keen (ben.keen@gmail.com), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/20
+ *
+ * JavaScript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2012/06/27 (1.0.8.11)
+ * - Reordered Keyword Groups to reflect syntactical meaning of keywords
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Javascript',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Regular Expressions
+ 2 => "/(?<=[\\s^])(s|tr|y)\\/(?!\*)(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])+(?<!\s)\\/(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])*(?<!\s)\\/[msixpogcde]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])(m|q[qrwx]?)?\\/(?!\*)(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])+(?<!\s)\\/[msixpogc]*(?=[\\s$\\.\\,\\;\\)])/iU"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ //reserved/keywords; also some non-reserved keywords
+ 'break','case','catch','const','continue',
+ 'default','delete','do',
+ 'else',
+ 'finally','for','function',
+ 'get','goto',
+ 'if','in','instanceof',
+ 'new',
+ 'prototype',
+ 'return',
+ 'set','static','switch',
+ 'this','throw','try','typeof',
+ 'var','void'
+ ),
+ 2 => array(
+ //reserved/non-keywords; metaconstants
+ 'false','null','true','undefined','NaN','Infinity'
+ ),
+ 3 => array(
+ //magic properties/functions
+ '__proto__','__defineGetter__','__defineSetter__','hasOwnProperty','hasProperty'
+ ),
+ 4 => array(
+ //type constructors
+ 'Object', 'Function', 'Date', 'Math', 'String', 'Number', 'Boolean', 'Array'
+ ),
+ 5 => array(
+ //reserved, but invalid in language
+ 'abstract','boolean','byte','char','class','debugger','double','enum','export','extends',
+ 'final','float','implements','import','int','interface','long','native',
+ 'short','super','synchronized','throws','transient','volatile'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}',
+ '+', '-', '*', '/', '%',
+ '!', '@', '&', '|', '^',
+ '<', '>', '=',
+ ',', ';', '?', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000066; font-weight: bold;',
+ 2 => 'color: #003366; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 5 => 'color: #FF0000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #006600; font-style: italic;',
+ 2 => 'color: #009966; font-style: italic;',
+ 'MULTI' => 'color: #006600; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #3366CC;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #CC0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #660066;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<script type="text/javascript">' => '</script>'
+ ),
+ 1 => array(
+ '<script language="javascript">' => '</script>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/jcl.php b/platform/www/vendor/geshi/geshi/src/geshi/jcl.php
new file mode 100644
index 0000000..9bc0c6c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/jcl.php
@@ -0,0 +1,155 @@
+<?php
+/*************************************************************************************
+ * jcl.php
+ * -----------
+ * Author: Ramesh Vishveshwar (ramesh.vishveshwar@gmail.com)
+ * Copyright: (c) 2012 Ramesh Vishveshwar (http://thecodeisclear.in)
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/09/16
+ *
+ * JCL (MVS), DFSORT, IDCAMS language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2011/09/16 (1.0.0)
+ * - Internal Release (for own blog/testing)
+ * 2012/09/22 (1.0.1)
+ * - Released with support for DFSORT, ICETOOL, IDCAMS
+ * - Added support for Symbolic variables in JCL
+ * - Added support for TWS OPC variables
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'JCL',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ // Comments identified using REGEX
+ // Comments start with //* but should not be followed by % (TWS) or + (some JES3 stmts)
+ 3 => "\/\/\*[^%](.*?)(\n)"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'COMMAND', 'CNTL', 'DD', 'ENDCNTL', 'EXEC', 'IF', 'THEN', 'ELSE',
+ 'ENDIF', 'JCLLIB', 'JOB', 'OUTPUT', 'PEND',
+ 'PROC', 'SET', 'XMIT'
+ ),
+ 2 => array (
+ 'PGM','CLASS','NOTIFY','MSGCLASS','DSN','KEYLEN','LABEL','LIKE',
+ 'RECFM','LRECL','DCB','DSORG','BLKSIZE','SPACE','STORCLAS',
+ 'DUMMY','DYNAM','AVGREC','BURST','DISP','UNIT','VOLUME',
+ 'MSGLEVEL','REGION'
+ ),
+ // Keywords set 3: DFSORT, ICETOOL
+ 3 => array (
+ 'ALTSEQ','DEBUG','END','INCLUDE','INREC','MERGE','MODS','OMIT',
+ 'OPTION','OUTFIL','OUTREC','RECORD','SORT','SUM',
+ 'COPY','COUNT','DEFAULTS','DISPLAY','MODE','OCCUR','RANGE',
+ 'SELECT','STATS','UNIQUE','VERIFY'
+ ),
+ // Keywords set 4: IDCAMS
+ 4 => array (
+ 'ALTER','BLDINDEX','CNVTCAT','DEFINE','ALIAS','ALTERNATEINDEX',
+ 'CLUSTER','GENERATIONDATAGROUP','GDG','NONVSAM','PAGESPACE','PATH',
+ /* 'SPACE',*/'USERCATALOG','DELETE','EXAMINE','EXPORT','DISCONNECT',
+ 'EXPORTRA','IMPORT','CONNECT','IMPORTRA','LISTCAT','LISTCRA',
+ 'PRINT','REPRO','RESETCAT'//,'VERIFY'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(',')','=',',','>','<'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #FF0000;',
+ 2 => 'color: #21A502;',
+ 3 => 'color: #FF00FF;',
+ 4 => 'color: #876C00;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #0000FF;',
+ //1 => 'color: #0000FF;',
+ //2 => 'color: #0000FF;',
+ 3 => 'color: #0000FF;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #FF7400;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #66CC66;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #336633;'
+ ),
+ 'METHODS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #FF7400;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #6B1F6B;',
+ 1 => 'color: #6B1F6B;',
+ 2 => 'color: #6B1F6B;'
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ // JCL book at IBM Bookshelf is http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/handheld/Connected/BOOKS/IEA2B680/CONTENTS?SHELF=&DT=20080604022956#3.1
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ // The following regular expressions solves three purposes
+ // - Identify Temp Variables in JCL (e.g. &&TEMP)
+ // - Symbolic variables in JCL (e.g. &SYSUID)
+ // - TWS OPC Variables (e.g. %OPC)
+ // Thanks to Simon for pointing me to this
+ 0 => '&amp;&amp;[a-zA-Z]{1,8}[0-9]{0,}',
+ 1 => '&amp;[a-zA-Z]{1,8}[0-9]{0,}',
+ 2 => '&amp;|\?|%[a-zA-Z]{1,8}[0-9]{0,}'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/jquery.php b/platform/www/vendor/geshi/geshi/src/geshi/jquery.php
new file mode 100644
index 0000000..f8b9c11
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/jquery.php
@@ -0,0 +1,236 @@
+<?php
+/*************************************************************************************
+ * jquery.php
+ * --------------
+ * Author: Rob Loach (http://www.robloach.net)
+ * Copyright: (c) 2009 Rob Loach (http://www.robloach.net)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/07/20
+ *
+ * jQuery 1.3 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/07/20 (1.0.8.5)
+ * - First Release
+ *
+ * TODO (updated 2009/07/20)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'jQuery',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ //Regular Expressions
+ 'COMMENT_REGEXP' => array(2 => "/(?<=[\\s^])s\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[gimsu]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])m?\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[gimsu]*(?=[\\s$\\.\\,\\;\\)])/iU"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'as', 'break', 'case', 'catch', 'continue', 'decodeURI', 'delete', 'do',
+ 'else', 'encodeURI', 'eval', 'finally', 'for', 'if', 'in', 'is', 'item',
+ 'instanceof', 'return', 'switch', 'this', 'throw', 'try', 'typeof', 'void',
+ 'while', 'write', 'with'
+ ),
+ 2 => array(
+ 'class', 'const', 'default', 'debugger', 'export', 'extends', 'false',
+ 'function', 'import', 'namespace', 'new', 'null', 'package', 'private',
+ 'protected', 'public', 'super', 'true', 'use', 'var'
+ ),
+ 3 => array(
+ // common functions for Window object
+ 'alert', 'back', 'close', 'confirm', 'forward', 'home',
+ 'name', 'navigate', 'onblur', 'onerror', 'onfocus', 'onload', 'onmove',
+ 'onresize', 'onunload', 'open', 'print', 'prompt', 'status',
+ //'blur', 'focus', 'scroll', // Duplicate with kw9
+ //'stop', //Duplicate with kw10
+ ),
+ 4 => array(
+ // jQuery Core Functions
+ 'jQuery', 'each', 'size', 'length', 'selector', 'context', 'eq',
+ 'index', 'data', 'removeData', 'queue', 'dequeue', 'noConflict'
+ //'get', //Duplicate with kw11
+ ),
+ 5 => array(
+ // jQuery Attribute Functions
+ 'attr', 'removeAttr', 'addClass', 'hasClass', 'removeClass', 'toggleClass',
+ 'html', 'text', 'val',
+ ),
+ 6 => array(
+ // jQuery Traversing Functions
+ 'filter', 'not', 'slice', 'add', 'children', 'closest',
+ 'contents', 'find', 'next', 'nextAll', 'parent', 'parents',
+ 'prev', 'prevAll', 'siblings', 'andSelf', 'end',
+ //'is', //Dup with kw1
+ //'offsetParent', //Duplicate with kw8
+ //'map', //Duplicate with kw12
+ ),
+ 7 => array(
+ // jQuery Manipulation Functions
+ 'append', 'appendTo', 'prepend', 'prependTo', 'after', 'before', 'insertAfter',
+ 'insertBefore', 'wrap', 'wrapAll', 'wrapInner', 'replaceWith', 'replaceAll',
+ 'empty', 'remove', 'clone',
+ ),
+ 8 => array(
+ // jQuery CSS Functions
+ 'css', 'offset', 'offsetParent', 'position', 'scrollTop', 'scrollLeft',
+ 'height', 'width', 'innerHeight', 'innerWidth', 'outerHeight', 'outerWidth',
+ ),
+ 9 => array(
+ // jQuery Events Functions
+ 'ready', 'bind', 'one', 'trigger', 'triggerHandler', 'unbind', 'live',
+ 'die', 'hover', 'blur', 'change', 'click', 'dblclick', 'error',
+ 'focus', 'keydown', 'keypress', 'keyup', 'mousedown', 'mouseenter',
+ 'mouseleave', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'resize',
+ 'scroll', 'select', 'submit', 'unload',
+ //'toggle', //Duplicate with kw10
+ //'load', //Duplicate with kw11
+ ),
+ 10 => array(
+ // jQuery Effects Functions
+ 'show', 'hide', 'toggle', 'slideDown', 'slideUp', 'slideToggle', 'fadeIn',
+ 'fadeOut', 'fadeTo', 'animate', 'stop',
+ ),
+ 11 => array(
+ // jQuery Ajax Functions
+ 'ajax', 'load', 'get', 'getJSON', 'getScript', 'post', 'ajaxComplete',
+ 'ajaxError', 'ajaxSend', 'ajaxStart', 'ajaxStop', 'ajaxSuccess', 'ajaxSetup',
+ 'serialize', 'serializeArray',
+ ),
+ 12 => array(
+ // jQuery Utility Functions
+ 'support', 'browser', 'version', 'boxModal', 'extend', 'grep', 'makeArray',
+ 'map', 'inArray', 'merge', 'unique', 'isArray', 'isFunction', 'trim',
+ 'param',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '(', ')', '[', ']', '{', '}',
+ '+', '-', '*', '/', '%',
+ '!', '@', '&', '|', '^',
+ '<', '>', '=',
+ ',', ';', '?', ':'
+ ),
+ 1 => array(
+ '$'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ 8 => false,
+ 9 => false,
+ 10 => false,
+ 11 => false,
+ 12 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000066; font-weight: bold;',
+ 2 => 'color: #003366; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #000066;',
+ 5 => 'color: #000066;',
+ 6 => 'color: #000066;',
+ 7 => 'color: #000066;',
+ 8 => 'color: #000066;',
+ 9 => 'color: #000066;',
+ 10 => 'color: #000066;',
+ 11 => 'color: #000066;',
+ 12 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #006600; font-style: italic;',
+ 2 => 'color: #009966; font-style: italic;',
+ 'MULTI' => 'color: #006600; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #3366CC;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #CC0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #660066;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;',
+ 1 => 'color: #000066;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => 'http://docs.jquery.com/Core/{FNAME}',
+ 5 => 'http://docs.jquery.com/Attributes/{FNAME}',
+ 6 => 'http://docs.jquery.com/Traversing/{FNAME}',
+ 7 => 'http://docs.jquery.com/Manipulation/{FNAME}',
+ 8 => 'http://docs.jquery.com/CSS/{FNAME}',
+ 9 => 'http://docs.jquery.com/Events/{FNAME}',
+ 10 => 'http://docs.jquery.com/Effects/{FNAME}',
+ 11 => 'http://docs.jquery.com/Ajax/{FNAME}',
+ 12 => 'http://docs.jquery.com/Utilities/{FNAME}'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<script type="text/javascript">' => '</script>'
+ ),
+ 1 => array(
+ '<script language="javascript">' => '</script>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/julia.php b/platform/www/vendor/geshi/geshi/src/geshi/julia.php
new file mode 100644
index 0000000..70848e6
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/julia.php
@@ -0,0 +1,171 @@
+<?php
+/*************************************************************************************
+ * julia.php
+ * -----------
+ * Author: John Lynch (john.lynch@iname.com)
+ * Contributors:
+ * - Magnus Lie Hetland
+ * - Curtis Vogt
+ * Copyright: (c) 2013 John Lynch
+ * Release Version: 1.0.9.1
+ * Date Started: 2013/11/06
+ *
+ * Julia language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ *
+ * 2015/11/04
+ * - First Release submitted
+ *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Julia',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ //Longest quotemarks ALWAYS first
+ 'QUOTEMARKS' => array('"""', '"', "'"),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+
+ /*
+ ** reserved words
+ */
+ 1 => array(
+ 'function', 'global', 'for', 'end', 'while', 'if', 'else', 'elseif', 'break',
+ 'switch', 'case', 'otherwise', 'try', 'catch', 'const', 'immutable',
+ 'import', 'importall', 'export', 'type', 'typealias', 'return', 'true',
+ 'false', 'macro', 'quote', 'in', 'abstract', 'module', 'using', 'continue',
+ 'ifelse', 'do', 'eval', 'let', 'finally', 'throw'
+ ),
+
+ /*
+ ** builtins
+ */
+ 2 => array(
+ 'Array', 'String', 'Bool', 'Number', 'Int', 'Integer', 'Real', 'Complex',
+ 'FloatingPoint', 'Float64', 'Float32', 'Int8', 'Int16', 'Int32', 'Int64',
+ 'Rational', 'AbstractArray', 'Unsigned', 'Signed', 'Uint', 'Uint8', 'Uint16',
+ 'Uint32', 'Uint64', 'Vector', 'AbstractVector', 'Matrix', 'AbstractMatrix',
+ 'Type', 'IO', 'Any', 'ASCIIString', 'Union', 'Dict', 'Function', 'SubArray',
+ 'Range', 'Range1', 'Symbol', 'Expr',
+
+ 'cell', 'collect', 'filter', 'merge', 'divrem', 'hex', 'dec', 'oct', 'base',
+ 'int', 'round', 'cmp', 'float', 'linspace', 'fill', 'start', 'done', 'tuple',
+ 'minimum', 'maximum', 'count', 'index', 'append', 'push', 'pop', 'shift',
+ 'unshift', 'insert', 'splice', 'reverse', 'sort', 'zip', 'length', 'delete',
+ 'copy', 'haskey', 'keys', 'values', 'get', 'getkey', 'Set', 'isa', 'issubset',
+ 'intersect', 'setdiff', 'symdiff', 'complement', 'print', 'printf', 'println',
+ 'sprintf', 'utf8', 'char', 'search', 'rsearch',
+ 'replace', 'lowercase', 'uppercase', 'ucfirst', 'lcfirst', 'union',
+ 'split', 'rsplit', 'chop', 'chomp', 'lpad', 'rpad', 'lstrip', 'rstrip',
+ 'strip', 'isalnum', 'isalpha', 'isascii', 'isblank', 'iscntrl', 'isdigit',
+ 'isgraph', 'islower', 'isprint', 'ispunct', 'isspace', 'isupper', 'isxdigit',
+ 'match', 'captures', 'offset', 'offsets', 'matchall', 'eachmatch', 'hcat',
+ 'vcat', 'hvcat', 'reshape', 'deepcopy', 'similar', 'reinterpret', 'map',
+ 'reduce', 'mapreduce', 'DataArray', 'DataFrame', 'removeNA', 'replaceNA',
+ 'colnames', 'head', 'tail', 'describe', 'join', 'groupby', 'by', 'stack',
+ 'readtable', 'readcsv', 'readdlm', 'writetable', 'writecsv', 'writedlm',
+ 'require', 'reload', 'include', 'evalfile', 'cd', 'open', 'write', 'close',
+ 'position', 'seek', 'seekstart', 'skip', 'isopen', 'eof',
+ 'isreadonly', 'ltoh', 'htol', 'serialize', 'deserialize', 'download',
+ 'isequal', 'getindex', 'setindex', 'eachline', 'beginswith', 'endswith',
+ 'parsefloat', 'parseint', 'seekend', 'findnz', 'DivideError', 'addprocs',
+ 'scale', 'issubnormal', 'readdir', 'mapslices'
+ ),
+
+ /*
+ ** system interaction
+ */
+ 3 => array(
+ 'run', 'spawn', 'success', 'process_running', 'process_exited', 'kill',
+ 'readsfrom', 'writesto', 'readsandwrite', 'detach', 'setenv', 'ENV', 'getpid',
+ 'clipboard', 'strftime', 'time', 'gethostname', 'getipaddr', 'pwd',
+ 'mkdir', 'mkpath', 'rmdir', 'ignorestatus'
+ ),
+
+ /*
+ ** prompt
+ */
+ 4 => array(
+ 'julia>'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '*', '&', '|', '%', '!', ';', '<', '>', '?', '`'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #4266d5;font-weight:bold;', // Reserved
+ 2 => 'color: #0000A8;font-weight:bold;', // Built-ins
+ 3 => 'color: #0000A8;font-weight:bold;', // System Interaction
+ 4 => 'color: #3b972e;font-weight:bold;' // Prompt
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #888888;',
+ 'MULTI' => 'color: #888888;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #3b972e;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #c93d39;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: black;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: black;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #6bab5b;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/kixtart.php b/platform/www/vendor/geshi/geshi/src/geshi/kixtart.php
new file mode 100644
index 0000000..0d67f64
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/kixtart.php
@@ -0,0 +1,327 @@
+<?php
+/*************************************************************************************
+ * kixtart.php
+ * --------
+ * Author: Riley McArdle (riley@glyff.net)
+ * Copyright: (c) 2007 Riley McArdle (http://www.glyff.net/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/08/31
+ *
+ * PHP language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2007/08/31 (1.0.7.22)
+ * - First Release
+ *
+ * TODO (updated 2007/08/31)
+ * -------------------------
+ * *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'KiXtart',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'While', 'Loop',
+ 'Use',
+ 'Small',
+ 'Sleep',
+ 'Shell',
+ 'SetTime',
+ 'SetM',
+ 'SetL',
+ 'Set',
+ 'Select', 'Case',
+ 'Run',
+ 'Return',
+ 'Redim',
+ 'RD',
+ 'Quit',
+ 'Play',
+ 'Move',
+ 'MD',
+ 'Include',
+ 'If', 'Else', 'Endif',
+ 'GoTo',
+ 'GoSub',
+ 'Go',
+ 'Global',
+ 'GetS',
+ 'Get',
+ 'Function', 'Endfunction',
+ 'For', 'Next',
+ 'Each',
+ 'FlushKb',
+ 'Exit',
+ 'Do', 'Until',
+ 'Display',
+ 'Dim',
+ 'Del',
+ 'Debug',
+ 'Copy',
+ 'Cookie1',
+ 'Color',
+ 'CLS',
+ 'CD',
+ 'Call',
+ 'Break',
+ 'Big',
+ 'Beep',
+ ),
+ 2 => array(
+ '@Address',
+ '@Build',
+ '@Color',
+ '@Comment',
+ '@CPU',
+ '@CRLF',
+ '@CSD',
+ '@CurDir',
+ '@Date',
+ '@Day',
+ '@Domain',
+ '@DOS',
+ '@Error',
+ '@FullName',
+ '@HomeDir',
+ '@HomeDrive',
+ '@HomeShr',
+ '@HostName',
+ '@InWin',
+ '@IPaddressX',
+ '@KiX',
+ '@LanRoot',
+ '@LDomain',
+ '@LDrive',
+ '@LM',
+ '@LogonMode',
+ '@LongHomeDir',
+ '@LServer',
+ '@MaxPWAge',
+ '@MDayNo',
+ '@MHz',
+ '@MonthNo',
+ '@Month',
+ '@MSecs',
+ '@OnWoW64',
+ '@PID',
+ '@PrimaryGroup',
+ '@Priv',
+ '@ProductSuite',
+ '@ProductType',
+ '@PWAge',
+ '@RAS',
+ '@Result',
+ '@RServer',
+ '@ScriptDir',
+ '@ScriptExe',
+ '@ScriptName',
+ '@SError',
+ '@SID',
+ '@Site',
+ '@StartDir',
+ '@SysLang',
+ '@Ticks',
+ '@Time',
+ '@TsSession',
+ '@UserID',
+ '@UserLang',
+ '@WDayNo',
+ '@Wksta',
+ '@WUserID',
+ '@YDayNo',
+ '@Year',
+ ),
+ 3 => array(
+ 'WriteValue',
+ 'WriteProfileString',
+ 'WriteLine',
+ 'VarTypeName',
+ 'VarType',
+ 'Val',
+ 'UnloadHive',
+ 'UCase',
+ 'Ubound',
+ 'Trim',
+ 'Substr',
+ 'SRnd',
+ 'Split',
+ 'SidToName',
+ 'ShutDown',
+ 'ShowProgramGroup',
+ 'SetWallpaper',
+ 'SetTitle',
+ 'SetSystemState',
+ 'SetOption',
+ 'SetFocus',
+ 'SetFileAttr',
+ 'SetDefaultPrinter',
+ 'SetConsole',
+ 'SetAscii',
+ 'SendMessage',
+ 'SendKeys',
+ 'SaveKey',
+ 'RTrim',
+ 'Round',
+ 'Rnd',
+ 'Right',
+ 'RedirectOutput',
+ 'ReadValue',
+ 'ReadType',
+ 'ReadProfileString',
+ 'ReadLine',
+ 'Open',
+ 'MessageBox',
+ 'MemorySize',
+ 'LTrim',
+ 'Logoff',
+ 'LogEvent',
+ 'LoadKey',
+ 'LoadHive',
+ 'Len',
+ 'Left',
+ 'LCase',
+ 'KeyExist',
+ 'KbHit',
+ 'Join',
+ 'IsDeclared',
+ 'Int',
+ 'InStrRev',
+ 'InStr',
+ 'InGroup',
+ 'IIF',
+ 'GetObject',
+ 'GetFileVersion',
+ 'GetFileTime',
+ 'GetFileSize',
+ 'GetFileAttr',
+ 'GetDiskSpace',
+ 'FreeFileHandle',
+ 'FormatNumber',
+ 'Fix',
+ 'ExpandEnvironmentVars',
+ 'Exist',
+ 'Execute',
+ 'EnumValue',
+ 'EnumLocalGroup',
+ 'EnumKey',
+ 'EnumIpInfo',
+ 'EnumGroup',
+ 'Dir',
+ 'DelValue',
+ 'DelTree',
+ 'DelProgramItem',
+ 'DelProgramGroup',
+ 'DelPrinterConnection',
+ 'DelKey',
+ 'DecToHex',
+ 'CStr',
+ 'CreateObject',
+ 'CompareFileTimes',
+ 'Close',
+ 'ClearEventLog',
+ 'CInt',
+ 'Chr',
+ 'CDbl',
+ 'Box',
+ 'BackupEventLog',
+ 'At',
+ 'AScan',
+ 'Asc',
+ 'AddProgramItem',
+ 'AddProgramGroup',
+ 'AddPrinterConnection',
+ 'AddKey',
+ 'Abs'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '?', ':', '+', '-', '*', '/', '&', '|', '^', '~', '<', '>', '='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.kixtart.org/manual/Commands/{FNAMEL}.htm',
+ 2 => '',
+ 3 => 'http://www.kixtart.org/manual/Functions/{FNAMEL}.htm'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/klonec.php b/platform/www/vendor/geshi/geshi/src/geshi/klonec.php
new file mode 100644
index 0000000..faecffe
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/klonec.php
@@ -0,0 +1,280 @@
+<?php
+/*************************************************************************************
+ * klonec.php
+ * --------
+ * Author: AUGER Mickael
+ * Copyright: Synchronic
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/04/16
+ *
+ * KLone with C language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/04/16 (1.0.8)
+ * - First Release
+ *
+ * TODO (updated 2008/04/16)
+ * -------------------------
+ * A tester et a completer si besoin
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'KLone C',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),//#pour precede les include de C
+ 'COMMENT_MULTI' => array('/*' => '*/', '<!--' => '-->' ),//comentaires C et KLone suivi de ceux pour HTML
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(//mots-cles C
+ 'if', 'return', 'while', 'case', 'class', 'continue', 'default',
+ 'do', 'else', 'for', 'switch', 'goto',
+ 'null', 'break', 'true', 'enum', 'extern', 'inline', 'false'
+ ),
+ 2 => array(//mots-cles KLone
+ 'out', 'request', 'response',
+ ),
+ 3 => array(//fonctions C usuelles
+ 'printf', 'malloc', 'fopen', 'fclose', 'free', 'fputs', 'fgets', 'feof', 'fwrite',
+ 'perror', 'ferror', 'qsort', 'stats', 'sscanf', 'scanf',
+ 'strdup', 'strcpy', 'strcmp', 'strncpy', 'strcasecmp', 'cat', 'strcat', 'strstr',
+ 'strlen', 'strtof', 'strtod', 'strtok', 'towlower', 'towupper',
+ 'cd', 'system', 'exit', 'exec', 'fork', 'vfork', 'kill', 'signal', 'syslog',
+ 'usleep', 'utime', 'wait', 'waitpid', 'waitid',
+ 'ceil', 'eval', 'round', 'floor',
+ 'atoi', 'atol', 'abs', 'cos', 'sin', 'tan', 'acos', 'asin', 'atan', 'exp',
+ 'time', 'ctime', 'localtime', 'asctime', 'gmtime', 'difftime', 'date'
+ ),
+ 4 => array(//fonctions KLone usuelles
+ 'request_get_cookies', 'request_get_cookie', 'request_get_args', 'request_get_arg',
+ 'request_io', 'request_get_uri', 'request_get_filename', 'request_get_query_string', 'request_get_path_info',
+ 'request_get_if_modified_since', 'request_get_http', 'request_get_client_request',
+ 'request_get_content_length', 'request_get_uploads', 'request_get_uploaded_file',
+ 'request_get_method', 'request_get_protocol', 'request_get_resolved_filename',
+ 'request_get_resolved_path_info', 'request_get_addr', 'request_get_peer_addr',
+ 'request_get_header', 'request_get_field', 'request_get_field_value',
+ 'response_set_content_encoding', 'response_disable_caching', 'response_enable_caching',
+ 'response_set_cookie', 'response_set_method', 'response_get_method',
+ 'response_print_header', 'response_set_field', 'response_del_field',
+ 'response_set_content_type', 'response_set_date', 'response_set_last_modified',
+ 'response_set_content_length', 'response_get_status', 'response_get_header',
+ 'response_io', 'response_redirect', 'response_set_status',
+ 'session_get_vars', 'session_get', 'session_set', 'session_age', 'session_clean', 'session_del',
+ 'io_type', 'io_pipe', 'io_dup', 'io_copy', 'io_seek', 'io_tell', 'io_close',
+ 'io_free', 'io_read', 'io_printf', 'io_flush', 'io_write', 'io_putc', 'io_getc',
+ 'io_get_until', 'io_gets', 'io_codec_add_head', 'io_codec_add_tail',
+ 'io_codecs_remove', 'io_name_set', 'io_name_get'
+ ),
+ 5 => array(//types C
+ 'auto', 'char', 'const', 'double', 'float', 'int', 'long',
+ 'register', 'short', 'signed', 'sizeof', 'static', 'string', 'struct',
+ 'typedef', 'union', 'unsigned', 'void', 'volatile',
+ 'wchar_t', 'time_t', 'FILE'
+ ),
+ 6 => array(//mots-cles HTML
+ 'a', 'abbr', 'acronym', 'address', 'applet',
+
+ 'base', 'basefont', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'b',
+
+ 'caption', 'center', 'cite', 'code', 'colgroup', 'col',
+
+ 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt',
+
+ 'em',
+
+ 'fieldset', 'font', 'form', 'frame', 'frameset',
+
+ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html',
+
+ 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'i',
+
+ 'kbd',
+
+ 'label', 'legend', 'link', 'li',
+
+ 'map', 'meta',
+
+ 'noframes', 'noscript',
+
+ 'object', 'ol', 'optgroup', 'option',
+
+ 'param', 'pre', 'p',
+
+ 'q',
+
+ 'samp', 'script', 'select', 'small', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 's',
+
+ 'table', 'tbody', 'td', 'textarea', 'text', 'tfoot', 'thead', 'th', 'title', 'tr', 'tt',
+
+ 'ul', 'u',
+
+ 'var',
+ ),
+ 7 => array(//autres mots-cles HTML
+ 'abbr', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alink', 'alt', 'archive', 'axis',
+ 'background', 'bgcolor', 'border',
+ 'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols', 'colspan', 'compact', 'content', 'coords',
+ 'data', 'datetime', 'declare', 'defer', 'dir', 'disabled',
+ 'enctype',
+ 'face', 'for', 'frame', 'frameborder',
+ 'headers', 'height', 'href', 'hreflang', 'hspace', 'http-equiv',
+ 'id', 'ismap',
+ 'label', 'lang', 'language', 'link', 'longdesc',
+ 'marginheight', 'marginwidth', 'maxlength', 'media', 'method', 'multiple',
+ 'name', 'nohref', 'noresize', 'noshade', 'nowrap',
+ 'object', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onreset', 'onselect', 'onsubmit', 'onunload',
+ 'profile', 'prompt',
+ 'readonly', 'rel', 'rev', 'rowspan', 'rows', 'rules',
+ 'scheme', 'scope', 'scrolling', 'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary',
+ 'tabindex', 'target', 'text', 'title', 'type',
+ 'usemap',
+ 'valign', 'value', 'valuetype', 'version', 'vlink', 'vspace',
+ 'width'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '<%=', '<%!', '<%', '%>'
+ ),
+ 0 => array(
+ '(', ')', '[', ']', '{', '}',
+ '!', '%', '&', '|', '/',
+ '<', '>',
+ '=', '-', '+', '*',
+ '.', ':', ',', ';', '^'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100; font-weight: bold;',//pour les mots-cles C
+ 2 => 'color: #000000; font-weight: bold;',//pour les mots-cles KLone
+ 3 => 'color: #6600FF;',//pour les fonctions C
+ 4 => 'color: #6600FF;',//pour les fonctions Klone
+ 5 => 'color: #0099FF; font-weight: bold;',//pour les types C
+ 6 => 'color: #990099; font-weight: bold;',//pour les mots-cles HTML
+ 7 => 'color: #000066;'//pour les autres mots-cles HTML
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',//commentaire sur une ligne C et KLone
+ 2 => 'color: #339933;',//pour les #... en C
+ 'MULTI' => 'color: #808080; font-style: italic;'//commentaire sur plusieurs lignes C et KLone
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;',
+ 1 => 'color: #000000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array(
+ 0 => 'background-color:#ffccff; font-weight: bold; color:#000000;',
+ 1 => '',
+ 2 => '',
+ 3 => 'color: #00bbdd; font-weight: bold;',
+ 4 => 'color: #ddbb00;',
+ 5 => 'color: #009900;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAMEL}.html',
+ 4 => 'http://www.koanlogic.com/klone/api/html/globals.html',
+ 5 => '',
+ 6 => 'http://december.com/html/4/element/{FNAMEL}.html',
+ 7 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+ 'SCRIPT_DELIMITERS' => array(
+ //delimiteurs pour KLone
+ 0 => array(
+ '<%=' => '%>'
+ ),
+ 1 => array(
+ '<%!' => '%>'
+ ),
+ 2 => array(
+ '<%' => '%>'
+ ),
+ //delimiteur pour HTML
+ 3 => array(
+ '<!DOCTYPE' => '>'
+ ),
+ 4 => array(
+ '&' => ';'
+ ),
+ 5 => array(
+ '<' => '>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => false,
+ 1 => true,
+ 2 => true,
+ 3 => false,
+ 4 => false,
+ 5 => true
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 6 => array(
+ 'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+ 'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+ ),
+ 7 => array(
+ 'DISALLOWED_AFTER' => '(?=\s*=)',
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/klonecpp.php b/platform/www/vendor/geshi/geshi/src/geshi/klonecpp.php
new file mode 100644
index 0000000..7f5949d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/klonecpp.php
@@ -0,0 +1,308 @@
+<?php
+/*************************************************************************************
+ * klonecpp.php
+ * --------
+ * Author: AUGER Mickael
+ * Copyright: Synchronic
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/04/16
+ *
+ * KLone with C++ language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/04/16 (1.0.8)
+ * - First Release
+ *
+ * TODO (updated 2008/04/16)
+ * -------------------------
+ * A tester et a completer si besoin
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'KLone C++',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),//#pour precede les include de C
+ 'COMMENT_MULTI' => array('/*' => '*/', '<!--' => '-->' ),//comentaires C et KLone suivi de ceux pour HTML
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(//mots-cles C++
+ 'if', 'return', 'while', 'case', 'continue', 'default',
+ 'do', 'else', 'for', 'switch', 'goto',
+ 'break', 'true', 'enum', 'extern', 'inline', 'false',
+ 'errno', 'stdin', 'stdout', 'stderr',
+ 'virtual', 'public', 'private', 'protected', 'template', 'using', 'namespace',
+ 'try', 'catch', 'dynamic_cast', 'const_cast', 'reinterpret_cast',
+ 'static_cast', 'explicit', 'friend', 'typename', 'typeid', 'class',
+ 'EDOM', 'ERANGE', 'FLT_RADIX', 'FLT_ROUNDS', 'FLT_DIG', 'DBL_DIG', 'LDBL_DIG',
+ 'FLT_EPSILON', 'DBL_EPSILON', 'LDBL_EPSILON', 'FLT_MANT_DIG', 'DBL_MANT_DIG',
+ 'LDBL_MANT_DIG', 'FLT_MAX', 'DBL_MAX', 'LDBL_MAX', 'FLT_MAX_EXP', 'DBL_MAX_EXP',
+ 'LDBL_MAX_EXP', 'FLT_MIN', 'DBL_MIN', 'LDBL_MIN', 'FLT_MIN_EXP', 'DBL_MIN_EXP',
+ 'LDBL_MIN_EXP', 'CHAR_BIT', 'CHAR_MAX', 'CHAR_MIN', 'SCHAR_MAX', 'SCHAR_MIN',
+ 'UCHAR_MAX', 'SHRT_MAX', 'SHRT_MIN', 'USHRT_MAX', 'INT_MAX', 'INT_MIN',
+ 'UINT_MAX', 'LONG_MAX', 'LONG_MIN', 'ULONG_MAX', 'HUGE_VAL', 'SIGABRT',
+ 'SIGFPE', 'SIGILL', 'SIGINT', 'SIGSEGV', 'SIGTERM', 'SIG_DFL', 'SIG_ERR',
+ 'SIG_IGN', 'BUFSIZ', 'EOF', 'FILENAME_MAX', 'FOPEN_MAX', 'L_tmpnam', 'NULL',
+ 'SEEK_CUR', 'SEEK_END', 'SEEK_SET', 'TMP_MAX',
+ 'EXIT_FAILURE', 'EXIT_SUCCESS', 'RAND_MAX', 'CLOCKS_PER_SEC'
+ ),
+ 2 => array(//mots-cles KLone
+ 'out', 'request', 'response',
+ ),
+ 3 => array(//fonctions C++ usuelles
+ 'cin', 'cerr', 'clog', 'cout', 'delete', 'new', 'this',
+ 'printf', 'fprintf', 'snprintf', 'sprintf', 'assert',
+ 'isalnum', 'isalpha', 'isdigit', 'iscntrl', 'isgraph', 'islower', 'isprint',
+ 'ispunct', 'isspace', 'isupper', 'isxdigit', 'tolower', 'toupper',
+ 'exp', 'log', 'log10', 'pow', 'sqrt', 'ceil', 'floor', 'fabs', 'ldexp',
+ 'frexp', 'modf', 'fmod', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'atan2',
+ 'sinh', 'cosh', 'tanh', 'setjmp', 'longjmp',
+ 'va_start', 'va_arg', 'va_end', 'offsetof', 'sizeof', 'fopen', 'freopen',
+ 'fflush', 'fclose', 'remove', 'rename', 'tmpfile', 'tmpname', 'setvbuf',
+ 'setbuf', 'vfprintf', 'vprintf', 'vsprintf', 'fscanf', 'scanf', 'sscanf',
+ 'fgetc', 'fgets', 'fputc', 'fputs', 'getc', 'getchar', 'gets', 'putc',
+ 'putchar', 'puts', 'ungetc', 'fread', 'fwrite', 'fseek', 'ftell', 'rewind',
+ 'fgetpos', 'fsetpos', 'clearerr', 'feof', 'ferror', 'perror', 'abs', 'labs',
+ 'div', 'ldiv', 'atof', 'atoi', 'atol', 'strtod', 'strtol', 'strtoul', 'calloc',
+ 'malloc', 'realloc', 'free', 'abort', 'exit', 'atexit', 'system', 'getenv',
+ 'bsearch', 'qsort', 'rand', 'srand', 'strcpy', 'strncpy', 'strcat', 'strncat',
+ 'strcmp', 'strncmp', 'strcoll', 'strchr', 'strrchr', 'strspn', 'strcspn',
+ 'strpbrk', 'strstr', 'strlen', 'strerror', 'strtok', 'strxfrm', 'memcpy',
+ 'memmove', 'memcmp', 'memchr', 'memset', 'clock', 'time', 'difftime', 'mktime',
+ 'asctime', 'ctime', 'gmtime', 'localtime', 'strftime'
+ ),
+ 4 => array(//fonctions KLone usuelles
+ 'request_get_cookies', 'request_get_cookie', 'request_get_args', 'request_get_arg',
+ 'request_io', 'request_get_uri', 'request_get_filename', 'request_get_query_string', 'request_get_path_info',
+ 'request_get_if_modified_since', 'request_get_http', 'request_get_client_request',
+ 'request_get_content_length', 'request_get_uploads', 'request_get_uploaded_file',
+ 'request_get_method', 'request_get_protocol', 'request_get_resolved_filename',
+ 'request_get_resolved_path_info', 'request_get_addr', 'request_get_peer_addr',
+ 'request_get_header', 'request_get_field', 'request_get_field_value',
+ 'response_set_content_encoding', 'response_disable_caching', 'response_enable_caching',
+ 'response_set_cookie', 'response_set_method', 'response_get_method',
+ 'response_print_header', 'response_set_field', 'response_del_field',
+ 'response_set_content_type', 'response_set_date', 'response_set_last_modified',
+ 'response_set_content_length', 'response_get_status', 'response_get_header',
+ 'response_io', 'response_redirect', 'response_set_status',
+ 'session_get_vars', 'session_get', 'session_set', 'session_age', 'session_clean', 'session_del',
+ 'io_type', 'io_pipe', 'io_dup', 'io_copy', 'io_seek', 'io_tell', 'io_close',
+ 'io_free', 'io_read', 'io_printf', 'io_flush', 'io_write', 'io_putc', 'io_getc',
+ 'io_get_until', 'io_gets', 'io_codec_add_head', 'io_codec_add_tail',
+ 'io_codecs_remove', 'io_name_set', 'io_name_get'
+ ),
+ 5 => array(//types C++
+ 'auto', 'bool', 'char', 'const', 'double', 'float', 'int', 'long', 'longint',
+ 'register', 'short', 'shortint', 'signed', 'static', 'struct',
+ 'typedef', 'union', 'unsigned', 'void', 'volatile', 'jmp_buf',
+ 'signal', 'raise', 'va_list', 'ptrdiff_t', 'size_t', 'FILE', 'fpos_t',
+ 'div_t', 'ldiv_t', 'clock_t', 'time_t', 'tm',
+ 'string', 'wchar_t'
+ ),
+ 6 => array(//mots-cles HTML
+ 'a', 'abbr', 'acronym', 'address', 'applet',
+
+ 'base', 'basefont', 'bdo', 'big', 'blockquote', 'body', 'br', 'button', 'b',
+
+ 'caption', 'center', 'cite', 'code', 'colgroup', 'col',
+
+ 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt',
+
+ 'em',
+
+ 'fieldset', 'font', 'form', 'frame', 'frameset',
+
+ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'hr', 'html',
+
+ 'iframe', 'ilayer', 'img', 'input', 'ins', 'isindex', 'i',
+
+ 'kbd',
+
+ 'label', 'legend', 'link', 'li',
+
+ 'map', 'meta',
+
+ 'noframes', 'noscript',
+
+ 'object', 'ol', 'optgroup', 'option',
+
+ 'param', 'pre', 'p',
+
+ 'q',
+
+ 'samp', 'script', 'select', 'small', 'span', 'strike', 'strong', 'style', 'sub', 'sup', 's',
+
+ 'table', 'tbody', 'td', 'textarea', 'text', 'tfoot', 'thead', 'th', 'title', 'tr', 'tt',
+
+ 'ul', 'u',
+
+ 'var',
+ ),
+ 7 => array(//autres mots-cles HTML
+ 'abbr', 'accept-charset', 'accept', 'accesskey', 'action', 'align', 'alink', 'alt', 'archive', 'axis',
+ 'background', 'bgcolor', 'border',
+ 'cellpadding', 'cellspacing', 'char', 'charoff', 'charset', 'checked', 'cite', 'class', 'classid', 'clear', 'code', 'codebase', 'codetype', 'color', 'cols', 'colspan', 'compact', 'content', 'coords',
+ 'data', 'datetime', 'declare', 'defer', 'dir', 'disabled',
+ 'enctype',
+ 'face', 'for', 'frame', 'frameborder',
+ 'headers', 'height', 'href', 'hreflang', 'hspace', 'http-equiv',
+ 'id', 'ismap',
+ 'label', 'lang', 'language', 'link', 'longdesc',
+ 'marginheight', 'marginwidth', 'maxlength', 'media', 'method', 'multiple',
+ 'name', 'nohref', 'noresize', 'noshade', 'nowrap',
+ 'object', 'onblur', 'onchange', 'onclick', 'ondblclick', 'onfocus', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onmousedown', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onreset', 'onselect', 'onsubmit', 'onunload',
+ 'profile', 'prompt',
+ 'readonly', 'rel', 'rev', 'rowspan', 'rows', 'rules',
+ 'scheme', 'scope', 'scrolling', 'selected', 'shape', 'size', 'span', 'src', 'standby', 'start', 'style', 'summary',
+ 'tabindex', 'target', 'text', 'title', 'type',
+ 'usemap',
+ 'valign', 'value', 'valuetype', 'version', 'vlink', 'vspace',
+ 'width'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '<%=', '<%!', '<%', '%>'
+ ),
+ 0 => array(
+ '(', ')', '[', ']', '{', '}',
+ '!', '%', '&', '|', '/',
+ '<', '>',
+ '=', '-', '+', '*',
+ '.', ':', ',', ';', '^'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100; font-weight: bold;',//pour les mots-cles C++
+ 2 => 'color: #000000; font-weight: bold;',//pour les mots-cles KLone
+ 3 => 'color: #6600FF;',//pour les fonctions C++
+ 4 => 'color: #6600FF;',//pour les fonctions Klone
+ 5 => 'color: #0099FF; font-weight: bold;',//pour les types C++
+ 6 => 'color: #990099; font-weight: bold;',//pour les mots-cles HTML
+ 7 => 'color: #000066;'//pour les autres mots-cles HTML
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',//commentaire sur une ligne C++ et KLone
+ 2 => 'color: #339933;',//pour les #... en C++
+ 'MULTI' => 'color: #808080; font-style: italic;'//commentaire sur plusieurs lignes C++ et KLone
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;',
+ 1 => 'color: #000000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array(
+ 0 => 'background-color:#ffccff; font-weight: bold; color:#000000;',
+ 1 => '',
+ 2 => '',
+ 3 => 'color: #00bbdd; font-weight: bold;',
+ 4 => 'color: #ddbb00;',
+ 5 => 'color: #009900;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAMEL}.html',
+ 4 => 'http://www.koanlogic.com/klone/api/html/globals.html',
+ 5 => '',
+ 6 => 'http://december.com/html/4/element/{FNAMEL}.html',
+ 7 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+ 'SCRIPT_DELIMITERS' => array(
+ //delimiteurs pour KLone
+ 0 => array(
+ '<%=' => '%>'
+ ),
+ 1 => array(
+ '<%!' => '%>'
+ ),
+ 2 => array(
+ '<%' => '%>'
+ ),
+ //delimiteur pour HTML
+ 3 => array(
+ '<!DOCTYPE' => '>'
+ ),
+ 4 => array(
+ '&' => ';'
+ ),
+ 5 => array(
+ '<' => '>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => false,
+ 1 => true,
+ 2 => true,
+ 3 => false,
+ 4 => false,
+ 5 => true
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 6 => array(
+ 'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+ 'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+ ),
+ 7 => array(
+ 'DISALLOWED_AFTER' => '(?=\s*=)',
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/kotlin.php b/platform/www/vendor/geshi/geshi/src/geshi/kotlin.php
new file mode 100644
index 0000000..d83e76c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/kotlin.php
@@ -0,0 +1,959 @@
+<?php
+/*************************************************************************************
+ * kotlin.php
+ * --------
+ * Author: Ole Sandum (oksandum@gmail.com)
+ * Copyright: (c) 2017 Ole Sandum
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/07/10
+ *
+ * Kotlin language file for GeSHi.
+ *
+ * 2017/01/28
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Kotlin',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Import and Package directives (Basic Support only)
+ 2 => '/(?:(?<=import[\\n\\s])|(?<=package[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*([a-zA-Z0-9_]+|\*)(?=[\n\s;])/i',
+ // javadoc comments
+ 3 => '#/\*\*(?![\*\/]).*\*/#sU'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'fun', 'var', 'val', 'typeof', 'typealias', 'suspend',
+ 'for', 'if', 'else', 'while', 'do',
+ 'when', 'return', 'public', 'get', 'set',
+ 'private', 'protected', 'internal', 'break', 'class', 'object',
+ 'companion', 'data', 'sealed', 'open', 'operator',
+ 'try', 'catch', 'finally', 'inner', 'constructor', 'init',
+ 'interface', 'throw', 'final', 'external', 'this',
+ 'abstract', 'is', '!is', 'as', 'as?', 'continue',
+ 'default', 'enum', 'package', 'super', 'where',
+ 'const', 'import', 'in', '!in', 'out', 'override',
+ 'reified', 'inline', 'noinline', 'crossinline'
+ ),
+ 2 => array(
+ 'null', 'false', 'true'
+ ),
+ 3 => array(
+ 'AbstractAction', 'AbstractBorder', 'AbstractButton',
+ 'AbstractCellEditor', 'AbstractCollection',
+ 'AbstractColorChooserPanel', 'AbstractDocument',
+ 'AbstractDocument.AttributeContext',
+ 'AbstractDocument.Content',
+ 'AbstractDocument.ElementEdit',
+ 'AbstractLayoutCache',
+ 'AbstractLayoutCache.NodeDimensions', 'AbstractList',
+ 'AbstractListModel', 'AbstractMap',
+ 'AbstractMethodError', 'AbstractSequentialList',
+ 'AbstractSet', 'AbstractTableModel',
+ 'AbstractUndoableEdit', 'AbstractWriter',
+ 'AccessControlContext', 'AccessControlException',
+ 'AccessController', 'AccessException', 'Accessible',
+ 'AccessibleAction', 'AccessibleBundle',
+ 'AccessibleComponent', 'AccessibleContext',
+ 'AccessibleHyperlink', 'AccessibleHypertext',
+ 'AccessibleIcon', 'AccessibleObject',
+ 'AccessibleRelation', 'AccessibleRelationSet',
+ 'AccessibleResourceBundle', 'AccessibleRole',
+ 'AccessibleSelection', 'AccessibleState',
+ 'AccessibleStateSet', 'AccessibleTable',
+ 'AccessibleTableModelChange', 'AccessibleText',
+ 'AccessibleValue', 'Acl', 'AclEntry',
+ 'AclNotFoundException', 'Action', 'ActionEvent',
+ 'ActionListener', 'ActionMap', 'ActionMapUIResource',
+ 'Activatable', 'ActivateFailedException',
+ 'ActivationDesc', 'ActivationException',
+ 'ActivationGroup', 'ActivationGroupDesc',
+ 'ActivationGroupDesc.CommandEnvironment',
+ 'ActivationGroupID', 'ActivationID',
+ 'ActivationInstantiator', 'ActivationMonitor',
+ 'ActivationSystem', 'Activator', 'ActiveEvent',
+ 'Adjustable', 'AdjustmentEvent',
+ 'AdjustmentListener', 'Adler32', 'AffineTransform',
+ 'AffineTransformOp', 'AlgorithmParameterGenerator',
+ 'AlgorithmParameterGeneratorSpi',
+ 'AlgorithmParameters', 'AlgorithmParameterSpec',
+ 'AlgorithmParametersSpi', 'AllPermission',
+ 'AlphaComposite', 'AlreadyBound',
+ 'AlreadyBoundException', 'AlreadyBoundHelper',
+ 'AlreadyBoundHolder', 'AncestorEvent',
+ 'AncestorListener', 'Annotation', 'AnyHolder',
+ 'AnySeqHelper', 'AnySeqHolder', 'Applet',
+ 'AppletContext', 'AppletInitializer', 'AppletStub',
+ 'ApplicationException', 'Arc2D', 'Arc2D.Double',
+ 'Arc2D.Float', 'Area', 'AreaAveragingScaleFilter',
+ 'ARG_IN', 'ARG_INOUT', 'ARG_OUT',
+ 'ArithmeticException', 'Array',
+ 'ArrayIndexOutOfBoundsException', 'ArrayList',
+ 'Arrays', 'ArrayStoreException', 'AsyncBoxView',
+ 'Attribute', 'AttributedCharacterIterator',
+ 'AttributedCharacterIterator.Attribute',
+ 'AttributedString', 'AttributeInUseException',
+ 'AttributeList', 'AttributeModificationException',
+ 'Attributes', 'Attributes.Name', 'AttributeSet',
+ 'AttributeSet.CharacterAttribute',
+ 'AttributeSet.ColorAttribute',
+ 'AttributeSet.FontAttribute',
+ 'AttributeSet.ParagraphAttribute', 'AudioClip',
+ 'AudioFileFormat', 'AudioFileFormat.Type',
+ 'AudioFileReader', 'AudioFileWriter', 'AudioFormat',
+ 'AudioFormat.Encoding', 'AudioInputStream',
+ 'AudioPermission', 'AudioSystem',
+ 'AuthenticationException',
+ 'AuthenticationNotSupportedException',
+ 'Authenticator', 'Autoscroll', 'AWTError',
+ 'AWTEvent', 'AWTEventListener',
+ 'AWTEventMulticaster', 'AWTException',
+ 'AWTPermission', 'BadKind', 'BadLocationException',
+ 'BAD_CONTEXT', 'BAD_INV_ORDER', 'BAD_OPERATION',
+ 'BAD_PARAM', 'BAD_POLICY', 'BAD_POLICY_TYPE',
+ 'BAD_POLICY_VALUE', 'BAD_TYPECODE', 'BandCombineOp',
+ 'BandedSampleModel', 'BasicArrowButton',
+ 'BasicAttribute', 'BasicAttributes', 'BasicBorders',
+ 'BasicBorders.ButtonBorder',
+ 'BasicBorders.FieldBorder',
+ 'BasicBorders.MarginBorder',
+ 'BasicBorders.MenuBarBorder',
+ 'BasicBorders.RadioButtonBorder',
+ 'BasicBorders.SplitPaneBorder',
+ 'BasicBorders.ToggleButtonBorder',
+ 'BasicButtonListener', 'BasicButtonUI',
+ 'BasicCheckBoxMenuItemUI', 'BasicCheckBoxUI',
+ 'BasicColorChooserUI', 'BasicComboBoxEditor',
+ 'BasicComboBoxEditor.UIResource',
+ 'BasicComboBoxRenderer',
+ 'BasicComboBoxRenderer.UIResource',
+ 'BasicComboBoxUI', 'BasicComboPopup',
+ 'BasicDesktopIconUI', 'BasicDesktopPaneUI',
+ 'BasicDirectoryModel', 'BasicEditorPaneUI',
+ 'BasicFileChooserUI', 'BasicGraphicsUtils',
+ 'BasicHTML', 'BasicIconFactory',
+ 'BasicInternalFrameTitlePane',
+ 'BasicInternalFrameUI', 'BasicLabelUI',
+ 'BasicListUI', 'BasicLookAndFeel', 'BasicMenuBarUI',
+ 'BasicMenuItemUI', 'BasicMenuUI',
+ 'BasicOptionPaneUI',
+ 'BasicOptionPaneUI.ButtonAreaLayout', 'BasicPanelUI',
+ 'BasicPasswordFieldUI', 'BasicPermission',
+ 'BasicPopupMenuSeparatorUI', 'BasicPopupMenuUI',
+ 'BasicProgressBarUI', 'BasicRadioButtonMenuItemUI',
+ 'BasicRadioButtonUI', 'BasicRootPaneUI',
+ 'BasicScrollBarUI', 'BasicScrollPaneUI',
+ 'BasicSeparatorUI', 'BasicSliderUI',
+ 'BasicSplitPaneDivider', 'BasicSplitPaneUI',
+ 'BasicStroke', 'BasicTabbedPaneUI',
+ 'BasicTableHeaderUI', 'BasicTableUI',
+ 'BasicTextAreaUI', 'BasicTextFieldUI',
+ 'BasicTextPaneUI', 'BasicTextUI',
+ 'BasicTextUI.BasicCaret',
+ 'BasicTextUI.BasicHighlighter',
+ 'BasicToggleButtonUI', 'BasicToolBarSeparatorUI',
+ 'BasicToolBarUI', 'BasicToolTipUI', 'BasicTreeUI',
+ 'BasicViewportUI', 'BatchUpdateException',
+ 'BeanContext', 'BeanContextChild',
+ 'BeanContextChildComponentProxy',
+ 'BeanContextChildSupport',
+ 'BeanContextContainerProxy', 'BeanContextEvent',
+ 'BeanContextMembershipEvent',
+ 'BeanContextMembershipListener', 'BeanContextProxy',
+ 'BeanContextServiceAvailableEvent',
+ 'BeanContextServiceProvider',
+ 'BeanContextServiceProviderBeanInfo',
+ 'BeanContextServiceRevokedEvent',
+ 'BeanContextServiceRevokedListener',
+ 'BeanContextServices', 'BeanContextServicesListener',
+ 'BeanContextServicesSupport',
+ 'BeanContextServicesSupport.BCSSServiceProvider',
+ 'BeanContextSupport',
+ 'BeanContextSupport.BCSIterator', 'BeanDescriptor',
+ 'BeanInfo', 'Beans', 'BevelBorder', 'BigDecimal',
+ 'BigInteger', 'BinaryRefAddr', 'BindException',
+ 'Binding', 'BindingHelper', 'BindingHolder',
+ 'BindingIterator', 'BindingIteratorHelper',
+ 'BindingIteratorHolder', 'BindingIteratorOperations',
+ 'BindingListHelper', 'BindingListHolder',
+ 'BindingType', 'BindingTypeHelper',
+ 'BindingTypeHolder', 'BitSet', 'Blob', 'BlockView',
+ 'Book', 'BooleanControl',
+ 'BooleanControl.Type', 'BooleanHolder',
+ 'BooleanSeqHelper', 'BooleanSeqHolder', 'Border',
+ 'BorderFactory', 'BorderLayout', 'BorderUIResource',
+ 'BorderUIResource.BevelBorderUIResource',
+ 'BorderUIResource.CompoundBorderUIResource',
+ 'BorderUIResource.EmptyBorderUIResource',
+ 'BorderUIResource.EtchedBorderUIResource',
+ 'BorderUIResource.LineBorderUIResource',
+ 'BorderUIResource.MatteBorderUIResource',
+ 'BorderUIResource.TitledBorderUIResource',
+ 'BoundedRangeModel', 'Bounds', 'Box', 'Box.Filler',
+ 'BoxedValueHelper', 'BoxLayout', 'BoxView',
+ 'BreakIterator', 'BufferedImage',
+ 'BufferedImageFilter', 'BufferedImageOp',
+ 'BufferedInputStream', 'BufferedOutputStream',
+ 'BufferedReader', 'BufferedWriter', 'Button',
+ 'ButtonGroup', 'ButtonModel', 'ButtonUI',
+ 'ByteArrayInputStream', 'ByteArrayOutputStream',
+ 'ByteHolder', 'ByteLookupTable', 'Calendar',
+ 'CallableStatement', 'CannotProceed',
+ 'CannotProceedException', 'CannotProceedHelper',
+ 'CannotProceedHolder', 'CannotRedoException',
+ 'CannotUndoException', 'Canvas', 'CardLayout',
+ 'Caret', 'CaretEvent', 'CaretListener', 'CellEditor',
+ 'CellEditorListener', 'CellRendererPane',
+ 'Certificate', 'Certificate.CertificateRep',
+ 'CertificateEncodingException',
+ 'CertificateException',
+ 'CertificateExpiredException', 'CertificateFactory',
+ 'CertificateFactorySpi',
+ 'CertificateNotYetValidException',
+ 'CertificateParsingException',
+ 'ChangedCharSetException', 'ChangeEvent',
+ 'ChangeListener', 'Character', 'Character.Subset',
+ 'Character.UnicodeBlock', 'CharacterIterator',
+ 'CharArrayReader', 'CharArrayWriter',
+ 'CharConversionException', 'CharHolder',
+ 'CharSeqHelper', 'CharSeqHolder', 'Checkbox',
+ 'CheckboxGroup', 'CheckboxMenuItem',
+ 'CheckedInputStream', 'CheckedOutputStream',
+ 'Checksum', 'Choice', 'ChoiceFormat', 'Class',
+ 'ClassCastException', 'ClassCircularityError',
+ 'ClassDesc', 'ClassFormatError', 'ClassLoader',
+ 'ClassNotFoundException', 'Clip', 'Clipboard',
+ 'ClipboardOwner', 'Clob', 'Cloneable',
+ 'CloneNotSupportedException', 'CMMException',
+ 'CodeSource', 'CollationElementIterator',
+ 'CollationKey', 'Collator', 'Collection',
+ 'Collections', 'Color',
+ 'ColorChooserComponentFactory', 'ColorChooserUI',
+ 'ColorConvertOp', 'ColorModel',
+ 'ColorSelectionModel', 'ColorSpace',
+ 'ColorUIResource', 'ComboBoxEditor', 'ComboBoxModel',
+ 'ComboBoxUI', 'ComboPopup', 'CommunicationException',
+ 'COMM_FAILURE', 'Comparable', 'Comparator',
+ 'Compiler', 'CompletionStatus',
+ 'CompletionStatusHelper', 'Component',
+ 'ComponentAdapter', 'ComponentColorModel',
+ 'ComponentEvent', 'ComponentInputMap',
+ 'ComponentInputMapUIResource', 'ComponentListener',
+ 'ComponentOrientation', 'ComponentSampleModel',
+ 'ComponentUI', 'ComponentView', 'Composite',
+ 'CompositeContext', 'CompositeName', 'CompositeView',
+ 'CompoundBorder', 'CompoundControl',
+ 'CompoundControl.Type', 'CompoundEdit',
+ 'CompoundName', 'ConcurrentModificationException',
+ 'ConfigurationException', 'ConnectException',
+ 'ConnectIOException', 'Connection', 'Constructor', 'Container',
+ 'ContainerAdapter', 'ContainerEvent',
+ 'ContainerListener', 'ContentHandler',
+ 'ContentHandlerFactory', 'ContentModel', 'Context',
+ 'ContextList', 'ContextNotEmptyException',
+ 'ContextualRenderedImageFactory', 'Control',
+ 'Control.Type', 'ControlFactory',
+ 'ControllerEventListener', 'ConvolveOp', 'CRC32',
+ 'CRL', 'CRLException', 'CropImageFilter', 'CSS',
+ 'CSS.Attribute', 'CTX_RESTRICT_SCOPE',
+ 'CubicCurve2D', 'CubicCurve2D.Double',
+ 'CubicCurve2D.Float', 'Current', 'CurrentHelper',
+ 'CurrentHolder', 'CurrentOperations', 'Cursor',
+ 'Customizer', 'CustomMarshal', 'CustomValue',
+ 'DatabaseMetaData', 'DataBuffer', 'DataBufferByte',
+ 'DataBufferInt', 'DataBufferShort',
+ 'DataBufferUShort', 'DataFlavor',
+ 'DataFormatException', 'DatagramPacket',
+ 'DatagramSocket', 'DatagramSocketImpl',
+ 'DatagramSocketImplFactory', 'DataInput',
+ 'DataInputStream', 'DataLine', 'DataLine.Info',
+ 'DataOutput', 'DataOutputStream',
+ 'DataTruncation', 'DATA_CONVERSION', 'Date',
+ 'DateFormat', 'DateFormatSymbols', 'DebugGraphics',
+ 'DecimalFormat', 'DecimalFormatSymbols',
+ 'DefaultBoundedRangeModel', 'DefaultButtonModel',
+ 'DefaultCaret', 'DefaultCellEditor',
+ 'DefaultColorSelectionModel', 'DefaultComboBoxModel',
+ 'DefaultDesktopManager', 'DefaultEditorKit',
+ 'DefaultEditorKit.BeepAction',
+ 'DefaultEditorKit.CopyAction',
+ 'DefaultEditorKit.CutAction',
+ 'DefaultEditorKit.DefaultKeyTypedAction',
+ 'DefaultEditorKit.InsertBreakAction',
+ 'DefaultEditorKit.InsertContentAction',
+ 'DefaultEditorKit.InsertTabAction',
+ 'DefaultEditorKit.PasteAction,',
+ 'DefaultFocusManager', 'DefaultHighlighter',
+ 'DefaultHighlighter.DefaultHighlightPainter',
+ 'DefaultListCellRenderer',
+ 'DefaultListCellRenderer.UIResource',
+ 'DefaultListModel', 'DefaultListSelectionModel',
+ 'DefaultMenuLayout', 'DefaultMetalTheme',
+ 'DefaultMutableTreeNode',
+ 'DefaultSingleSelectionModel',
+ 'DefaultStyledDocument',
+ 'DefaultStyledDocument.AttributeUndoableEdit',
+ 'DefaultStyledDocument.ElementSpec',
+ 'DefaultTableCellRenderer',
+ 'DefaultTableCellRenderer.UIResource',
+ 'DefaultTableColumnModel', 'DefaultTableModel',
+ 'DefaultTextUI', 'DefaultTreeCellEditor',
+ 'DefaultTreeCellRenderer', 'DefaultTreeModel',
+ 'DefaultTreeSelectionModel', 'DefinitionKind',
+ 'DefinitionKindHelper', 'Deflater',
+ 'DeflaterOutputStream', 'Delegate', 'DesignMode',
+ 'DesktopIconUI', 'DesktopManager', 'DesktopPaneUI',
+ 'DGC', 'Dialog', 'Dictionary', 'DigestException',
+ 'DigestInputStream', 'DigestOutputStream',
+ 'Dimension', 'Dimension2D', 'DimensionUIResource',
+ 'DirContext', 'DirectColorModel', 'DirectoryManager',
+ 'DirObjectFactory', 'DirStateFactory',
+ 'DirStateFactory.Result', 'DnDConstants', 'Document',
+ 'DocumentEvent', 'DocumentEvent.ElementChange',
+ 'DocumentEvent.EventType', 'DocumentListener',
+ 'DocumentParser', 'DomainCombiner', 'DomainManager',
+ 'DomainManagerOperations', 'DoubleHolder',
+ 'DoubleSeqHelper', 'DoubleSeqHolder',
+ 'DragGestureEvent', 'DragGestureListener',
+ 'DragGestureRecognizer', 'DragSource',
+ 'DragSourceContext', 'DragSourceDragEvent',
+ 'DragSourceDropEvent', 'DragSourceEvent',
+ 'DragSourceListener', 'Driver', 'DriverManager',
+ 'DriverPropertyInfo', 'DropTarget',
+ 'DropTarget.DropTargetAutoScroller',
+ 'DropTargetContext', 'DropTargetDragEvent',
+ 'DropTargetDropEvent', 'DropTargetEvent',
+ 'DropTargetListener', 'DSAKey',
+ 'DSAKeyPairGenerator', 'DSAParameterSpec',
+ 'DSAParams', 'DSAPrivateKey', 'DSAPrivateKeySpec',
+ 'DSAPublicKey', 'DSAPublicKeySpec', 'DTD',
+ 'DTDConstants', 'DynamicImplementation', 'DynAny',
+ 'DynArray', 'DynEnum', 'DynFixed', 'DynSequence',
+ 'DynStruct', 'DynUnion', 'DynValue', 'EditorKit',
+ 'Element', 'ElementIterator', 'Ellipse2D',
+ 'Ellipse2D.Double', 'Ellipse2D.Float', 'EmptyBorder',
+ 'EmptyStackException', 'EncodedKeySpec', 'Entity',
+ 'EnumControl', 'EnumControl.Type', 'Enumeration',
+ 'Environment', 'EOFException', 'Error',
+ 'EtchedBorder', 'Event', 'EventContext',
+ 'EventDirContext', 'EventListener',
+ 'EventListenerList', 'EventObject', 'EventQueue',
+ 'EventSetDescriptor', 'Exception',
+ 'ExceptionInInitializerError', 'ExceptionList',
+ 'ExpandVetoException', 'ExportException',
+ 'ExtendedRequest', 'ExtendedResponse',
+ 'Externalizable', 'FeatureDescriptor', 'Field',
+ 'FieldNameHelper', 'FieldPosition', 'FieldView',
+ 'File', 'FileChooserUI', 'FileDescriptor',
+ 'FileDialog', 'FileFilter',
+ 'FileInputStream', 'FilenameFilter', 'FileNameMap',
+ 'FileNotFoundException', 'FileOutputStream',
+ 'FilePermission', 'FileReader', 'FileSystemView',
+ 'FileView', 'FileWriter', 'FilteredImageSource',
+ 'FilterInputStream', 'FilterOutputStream',
+ 'FilterReader', 'FilterWriter',
+ 'FixedHeightLayoutCache', 'FixedHolder',
+ 'FlatteningPathIterator', 'FlavorMap',
+ 'FloatControl', 'FloatControl.Type', 'FloatHolder',
+ 'FloatSeqHelper', 'FloatSeqHolder', 'FlowLayout',
+ 'FlowView', 'FlowView.FlowStrategy', 'FocusAdapter',
+ 'FocusEvent', 'FocusListener', 'FocusManager',
+ 'Font', 'FontFormatException', 'FontMetrics',
+ 'FontRenderContext', 'FontUIResource', 'Format',
+ 'FormatConversionProvider', 'FormView', 'Frame',
+ 'FREE_MEM', 'GapContent', 'GeneralPath',
+ 'GeneralSecurityException', 'GlyphJustificationInfo',
+ 'GlyphMetrics', 'GlyphVector', 'GlyphView',
+ 'GlyphView.GlyphPainter', 'GradientPaint',
+ 'GraphicAttribute', 'Graphics', 'Graphics2D',
+ 'GraphicsConfigTemplate', 'GraphicsConfiguration',
+ 'GraphicsDevice', 'GraphicsEnvironment',
+ 'GrayFilter', 'GregorianCalendar',
+ 'GridBagConstraints', 'GridBagLayout', 'GridLayout',
+ 'Group', 'Guard', 'GuardedObject', 'GZIPInputStream',
+ 'GZIPOutputStream', 'HasControls', 'HashMap',
+ 'HashSet', 'Hashtable', 'HierarchyBoundsAdapter',
+ 'HierarchyBoundsListener', 'HierarchyEvent',
+ 'HierarchyListener', 'Highlighter',
+ 'Highlighter.Highlight',
+ 'Highlighter.HighlightPainter', 'HTML',
+ 'HTML.Attribute', 'HTML.Tag', 'HTML.UnknownTag',
+ 'HTMLDocument', 'HTMLDocument.Iterator',
+ 'HTMLEditorKit', 'HTMLEditorKit.HTMLFactory',
+ 'HTMLEditorKit.HTMLTextAction',
+ 'HTMLEditorKit.InsertHTMLTextAction',
+ 'HTMLEditorKit.LinkController',
+ 'HTMLEditorKit.Parser',
+ 'HTMLEditorKit.ParserCallback',
+ 'HTMLFrameHyperlinkEvent', 'HTMLWriter',
+ 'HttpURLConnection', 'HyperlinkEvent',
+ 'HyperlinkEvent.EventType', 'HyperlinkListener',
+ 'ICC_ColorSpace', 'ICC_Profile', 'ICC_ProfileGray',
+ 'ICC_ProfileRGB', 'Icon', 'IconUIResource',
+ 'IconView', 'IdentifierHelper', 'Identity',
+ 'IdentityScope', 'IDLEntity', 'IDLType',
+ 'IDLTypeHelper', 'IDLTypeOperations',
+ 'IllegalAccessError', 'IllegalAccessException',
+ 'IllegalArgumentException',
+ 'IllegalComponentStateException',
+ 'IllegalMonitorStateException',
+ 'IllegalPathStateException', 'IllegalStateException',
+ 'IllegalThreadStateException', 'Image',
+ 'ImageConsumer', 'ImageFilter',
+ 'ImageGraphicAttribute', 'ImageIcon',
+ 'ImageObserver', 'ImageProducer',
+ 'ImagingOpException', 'IMP_LIMIT',
+ 'IncompatibleClassChangeError',
+ 'InconsistentTypeCode', 'IndexColorModel',
+ 'IndexedPropertyDescriptor',
+ 'IndexOutOfBoundsException', 'IndirectionException',
+ 'InetAddress', 'Inflater', 'InflaterInputStream',
+ 'InheritableThreadLocal', 'InitialContext',
+ 'InitialContextFactory',
+ 'InitialContextFactoryBuilder', 'InitialDirContext',
+ 'INITIALIZE', 'Initializer', 'InitialLdapContext',
+ 'InlineView', 'InputContext', 'InputEvent',
+ 'InputMap', 'InputMapUIResource', 'InputMethod',
+ 'InputMethodContext', 'InputMethodDescriptor',
+ 'InputMethodEvent', 'InputMethodHighlight',
+ 'InputMethodListener', 'InputMethodRequests',
+ 'InputStream',
+ 'InputStreamReader', 'InputSubset', 'InputVerifier',
+ 'Insets', 'InsetsUIResource', 'InstantiationError',
+ 'InstantiationException', 'Instrument',
+ 'InsufficientResourcesException', 'Integer',
+ 'INTERNAL', 'InternalError', 'InternalFrameAdapter',
+ 'InternalFrameEvent', 'InternalFrameListener',
+ 'InternalFrameUI', 'InterruptedException',
+ 'InterruptedIOException',
+ 'InterruptedNamingException', 'INTF_REPOS',
+ 'IntHolder', 'IntrospectionException',
+ 'Introspector', 'Invalid',
+ 'InvalidAlgorithmParameterException',
+ 'InvalidAttributeIdentifierException',
+ 'InvalidAttributesException',
+ 'InvalidAttributeValueException',
+ 'InvalidClassException',
+ 'InvalidDnDOperationException',
+ 'InvalidKeyException', 'InvalidKeySpecException',
+ 'InvalidMidiDataException', 'InvalidName',
+ 'InvalidNameException',
+ 'InvalidNameHelper', 'InvalidNameHolder',
+ 'InvalidObjectException',
+ 'InvalidParameterException',
+ 'InvalidParameterSpecException',
+ 'InvalidSearchControlsException',
+ 'InvalidSearchFilterException', 'InvalidSeq',
+ 'InvalidTransactionException', 'InvalidValue',
+ 'INVALID_TRANSACTION', 'InvocationEvent',
+ 'InvocationHandler', 'InvocationTargetException',
+ 'InvokeHandler', 'INV_FLAG', 'INV_IDENT',
+ 'INV_OBJREF', 'INV_POLICY', 'IOException',
+ 'IRObject', 'IRObjectOperations', 'IstringHelper',
+ 'ItemEvent', 'ItemListener', 'ItemSelectable',
+ 'Iterator', 'JApplet', 'JarEntry', 'JarException',
+ 'JarFile', 'JarInputStream', 'JarOutputStream',
+ 'JarURLConnection', 'JButton', 'JCheckBox',
+ 'JCheckBoxMenuItem', 'JColorChooser', 'JComboBox',
+ 'JComboBox.KeySelectionManager', 'JComponent',
+ 'JDesktopPane', 'JDialog', 'JEditorPane',
+ 'JFileChooser', 'JFrame', 'JInternalFrame',
+ 'JInternalFrame.JDesktopIcon', 'JLabel',
+ 'JLayeredPane', 'JList', 'JMenu', 'JMenuBar',
+ 'JMenuItem', 'JobAttributes',
+ 'JobAttributes.DefaultSelectionType',
+ 'JobAttributes.DestinationType',
+ 'JobAttributes.DialogType',
+ 'JobAttributes.MultipleDocumentHandlingType',
+ 'JobAttributes.SidesType', 'JOptionPane', 'JPanel',
+ 'JPasswordField', 'JPopupMenu',
+ 'JPopupMenu.Separator', 'JProgressBar',
+ 'JRadioButton', 'JRadioButtonMenuItem', 'JRootPane',
+ 'JScrollBar', 'JScrollPane', 'JSeparator', 'JSlider',
+ 'JSplitPane', 'JTabbedPane', 'JTable',
+ 'JTableHeader', 'JTextArea', 'JTextComponent',
+ 'JTextComponent.KeyBinding', 'JTextField',
+ 'JTextPane', 'JToggleButton',
+ 'JToggleButton.ToggleButtonModel', 'JToolBar',
+ 'JToolBar.Separator', 'JToolTip', 'JTree',
+ 'JTree.DynamicUtilTreeNode',
+ 'JTree.EmptySelectionModel', 'JViewport', 'JWindow',
+ 'Kernel', 'Key', 'KeyAdapter', 'KeyEvent',
+ 'KeyException', 'KeyFactory', 'KeyFactorySpi',
+ 'KeyListener', 'KeyManagementException', 'Keymap',
+ 'KeyPair', 'KeyPairGenerator', 'KeyPairGeneratorSpi',
+ 'KeySpec', 'KeyStore', 'KeyStoreException',
+ 'KeyStoreSpi', 'KeyStroke', 'Label', 'LabelUI',
+ 'LabelView', 'LastOwnerException',
+ 'LayeredHighlighter',
+ 'LayeredHighlighter.LayerPainter', 'LayoutManager',
+ 'LayoutManager2', 'LayoutQueue', 'LdapContext',
+ 'LdapReferralException', 'Lease',
+ 'LimitExceededException', 'Line', 'Line.Info',
+ 'Line2D', 'Line2D.Double', 'Line2D.Float',
+ 'LineBorder', 'LineBreakMeasurer', 'LineEvent',
+ 'LineEvent.Type', 'LineListener', 'LineMetrics',
+ 'LineNumberInputStream', 'LineNumberReader',
+ 'LineUnavailableException', 'LinkageError',
+ 'LinkedList', 'LinkException', 'LinkLoopException',
+ 'LinkRef', 'List', 'ListCellRenderer',
+ 'ListDataEvent', 'ListDataListener', 'ListIterator',
+ 'ListModel', 'ListResourceBundle',
+ 'ListSelectionEvent', 'ListSelectionListener',
+ 'ListSelectionModel', 'ListUI', 'ListView',
+ 'LoaderHandler', 'Locale', 'LocateRegistry',
+ 'LogStream', 'LongHolder',
+ 'LongLongSeqHelper', 'LongLongSeqHolder',
+ 'LongSeqHelper', 'LongSeqHolder', 'LookAndFeel',
+ 'LookupOp', 'LookupTable', 'MalformedLinkException',
+ 'MalformedURLException', 'Manifest', 'Map',
+ 'Map.Entry', 'MARSHAL', 'MarshalException',
+ 'MarshalledObject', 'Math', 'MatteBorder',
+ 'MediaTracker', 'Member', 'MemoryImageSource',
+ 'Menu', 'MenuBar', 'MenuBarUI', 'MenuComponent',
+ 'MenuContainer', 'MenuDragMouseEvent',
+ 'MenuDragMouseListener', 'MenuElement', 'MenuEvent',
+ 'MenuItem', 'MenuItemUI', 'MenuKeyEvent',
+ 'MenuKeyListener', 'MenuListener',
+ 'MenuSelectionManager', 'MenuShortcut',
+ 'MessageDigest', 'MessageDigestSpi', 'MessageFormat',
+ 'MetaEventListener', 'MetalBorders',
+ 'MetalBorders.ButtonBorder',
+ 'MetalBorders.Flush3DBorder',
+ 'MetalBorders.InternalFrameBorder',
+ 'MetalBorders.MenuBarBorder',
+ 'MetalBorders.MenuItemBorder',
+ 'MetalBorders.OptionDialogBorder',
+ 'MetalBorders.PaletteBorder',
+ 'MetalBorders.PopupMenuBorder',
+ 'MetalBorders.RolloverButtonBorder',
+ 'MetalBorders.ScrollPaneBorder',
+ 'MetalBorders.TableHeaderBorder',
+ 'MetalBorders.TextFieldBorder',
+ 'MetalBorders.ToggleButtonBorder',
+ 'MetalBorders.ToolBarBorder', 'MetalButtonUI',
+ 'MetalCheckBoxIcon', 'MetalCheckBoxUI',
+ 'MetalComboBoxButton', 'MetalComboBoxEditor',
+ 'MetalComboBoxEditor.UIResource',
+ 'MetalComboBoxIcon', 'MetalComboBoxUI',
+ 'MetalDesktopIconUI', 'MetalFileChooserUI',
+ 'MetalIconFactory', 'MetalIconFactory.FileIcon16',
+ 'MetalIconFactory.FolderIcon16',
+ 'MetalIconFactory.PaletteCloseIcon',
+ 'MetalIconFactory.TreeControlIcon',
+ 'MetalIconFactory.TreeFolderIcon',
+ 'MetalIconFactory.TreeLeafIcon',
+ 'MetalInternalFrameTitlePane',
+ 'MetalInternalFrameUI', 'MetalLabelUI',
+ 'MetalLookAndFeel', 'MetalPopupMenuSeparatorUI',
+ 'MetalProgressBarUI', 'MetalRadioButtonUI',
+ 'MetalScrollBarUI', 'MetalScrollButton',
+ 'MetalScrollPaneUI', 'MetalSeparatorUI',
+ 'MetalSliderUI', 'MetalSplitPaneUI',
+ 'MetalTabbedPaneUI', 'MetalTextFieldUI',
+ 'MetalTheme', 'MetalToggleButtonUI',
+ 'MetalToolBarUI', 'MetalToolTipUI', 'MetalTreeUI',
+ 'MetaMessage', 'Method', 'MethodDescriptor',
+ 'MidiChannel', 'MidiDevice', 'MidiDevice.Info',
+ 'MidiDeviceProvider', 'MidiEvent', 'MidiFileFormat',
+ 'MidiFileReader', 'MidiFileWriter', 'MidiMessage',
+ 'MidiSystem', 'MidiUnavailableException',
+ 'MimeTypeParseException', 'MinimalHTMLWriter',
+ 'MissingResourceException', 'Mixer', 'Mixer.Info',
+ 'MixerProvider', 'ModificationItem', 'Modifier',
+ 'MouseAdapter', 'MouseDragGestureRecognizer',
+ 'MouseEvent', 'MouseInputAdapter',
+ 'MouseInputListener', 'MouseListener',
+ 'MouseMotionAdapter', 'MouseMotionListener',
+ 'MultiButtonUI', 'MulticastSocket',
+ 'MultiColorChooserUI', 'MultiComboBoxUI',
+ 'MultiDesktopIconUI', 'MultiDesktopPaneUI',
+ 'MultiFileChooserUI', 'MultiInternalFrameUI',
+ 'MultiLabelUI', 'MultiListUI', 'MultiLookAndFeel',
+ 'MultiMenuBarUI', 'MultiMenuItemUI',
+ 'MultiOptionPaneUI', 'MultiPanelUI',
+ 'MultiPixelPackedSampleModel', 'MultipleMaster',
+ 'MultiPopupMenuUI', 'MultiProgressBarUI',
+ 'MultiScrollBarUI', 'MultiScrollPaneUI',
+ 'MultiSeparatorUI', 'MultiSliderUI',
+ 'MultiSplitPaneUI', 'MultiTabbedPaneUI',
+ 'MultiTableHeaderUI', 'MultiTableUI', 'MultiTextUI',
+ 'MultiToolBarUI', 'MultiToolTipUI', 'MultiTreeUI',
+ 'MultiViewportUI', 'MutableAttributeSet',
+ 'MutableComboBoxModel', 'MutableTreeNode', 'Name',
+ 'NameAlreadyBoundException', 'NameClassPair',
+ 'NameComponent', 'NameComponentHelper',
+ 'NameComponentHolder', 'NamedValue', 'NameHelper',
+ 'NameHolder', 'NameNotFoundException', 'NameParser',
+ 'NamespaceChangeListener', 'NameValuePair',
+ 'NameValuePairHelper', 'Naming', 'NamingContext',
+ 'NamingContextHelper', 'NamingContextHolder',
+ 'NamingContextOperations', 'NamingEnumeration',
+ 'NamingEvent', 'NamingException',
+ 'NamingExceptionEvent', 'NamingListener',
+ 'NamingManager', 'NamingSecurityException',
+ 'NegativeArraySizeException', 'NetPermission',
+ 'NoClassDefFoundError', 'NoInitialContextException',
+ 'NoninvertibleTransformException',
+ 'NoPermissionException', 'NoRouteToHostException',
+ 'NoSuchAlgorithmException',
+ 'NoSuchAttributeException', 'NoSuchElementException',
+ 'NoSuchFieldError', 'NoSuchFieldException',
+ 'NoSuchMethodError', 'NoSuchMethodException',
+ 'NoSuchObjectException', 'NoSuchProviderException',
+ 'NotActiveException', 'NotBoundException',
+ 'NotContextException', 'NotEmpty', 'NotEmptyHelper',
+ 'NotEmptyHolder', 'NotFound', 'NotFoundHelper',
+ 'NotFoundHolder', 'NotFoundReason',
+ 'NotFoundReasonHelper', 'NotFoundReasonHolder',
+ 'NotOwnerException', 'NotSerializableException',
+ 'NO_IMPLEMENT', 'NO_MEMORY', 'NO_PERMISSION',
+ 'NO_RESOURCES', 'NO_RESPONSE',
+ 'NullPointerException', 'Number', 'NumberFormat',
+ 'NumberFormatException', 'NVList', 'Object',
+ 'ObjectChangeListener', 'ObjectFactory',
+ 'ObjectFactoryBuilder', 'ObjectHelper',
+ 'ObjectHolder', 'ObjectImpl',
+ 'ObjectInput', 'ObjectInputStream',
+ 'ObjectInputStream.GetField',
+ 'ObjectInputValidation', 'ObjectOutput',
+ 'ObjectOutputStream', 'ObjectOutputStream.PutField',
+ 'ObjectStreamClass', 'ObjectStreamConstants',
+ 'ObjectStreamException', 'ObjectStreamField',
+ 'ObjectView', 'OBJECT_NOT_EXIST', 'ObjID',
+ 'OBJ_ADAPTER', 'Observable', 'Observer',
+ 'OctetSeqHelper', 'OctetSeqHolder', 'OMGVMCID',
+ 'OpenType', 'Operation',
+ 'OperationNotSupportedException', 'Option',
+ 'OptionalDataException', 'OptionPaneUI', 'ORB',
+ 'OutOfMemoryError', 'OutputStream',
+ 'OutputStreamWriter', 'OverlayLayout', 'Owner',
+ 'Package', 'PackedColorModel', 'Pageable',
+ 'PageAttributes', 'PageAttributes.ColorType',
+ 'PageAttributes.MediaType',
+ 'PageAttributes.OrientationRequestedType',
+ 'PageAttributes.OriginType',
+ 'PageAttributes.PrintQualityType', 'PageFormat',
+ 'Paint', 'PaintContext', 'PaintEvent', 'Panel',
+ 'PanelUI', 'Paper', 'ParagraphView',
+ 'ParameterBlock', 'ParameterDescriptor',
+ 'ParseException', 'ParsePosition', 'Parser',
+ 'ParserDelegator', 'PartialResultException',
+ 'PasswordAuthentication', 'PasswordView', 'Patch',
+ 'PathIterator', 'Permission',
+ 'PermissionCollection', 'Permissions',
+ 'PERSIST_STORE', 'PhantomReference',
+ 'PipedInputStream', 'PipedOutputStream',
+ 'PipedReader', 'PipedWriter', 'PixelGrabber',
+ 'PixelInterleavedSampleModel', 'PKCS8EncodedKeySpec',
+ 'PlainDocument', 'PlainView', 'Point', 'Point2D',
+ 'Point2D.Double', 'Point2D.Float', 'Policy',
+ 'PolicyError', 'PolicyHelper',
+ 'PolicyHolder', 'PolicyListHelper',
+ 'PolicyListHolder', 'PolicyOperations',
+ 'PolicyTypeHelper', 'Polygon', 'PopupMenu',
+ 'PopupMenuEvent', 'PopupMenuListener', 'PopupMenuUI',
+ 'Port', 'Port.Info', 'PortableRemoteObject',
+ 'PortableRemoteObjectDelegate', 'Position',
+ 'Position.Bias', 'PreparedStatement', 'Principal',
+ 'PrincipalHolder', 'Printable',
+ 'PrinterAbortException', 'PrinterException',
+ 'PrinterGraphics', 'PrinterIOException',
+ 'PrinterJob', 'PrintGraphics', 'PrintJob',
+ 'PrintStream', 'PrintWriter', 'PrivateKey',
+ 'PRIVATE_MEMBER', 'PrivilegedAction',
+ 'PrivilegedActionException',
+ 'PrivilegedExceptionAction', 'Process',
+ 'ProfileDataException', 'ProgressBarUI',
+ 'ProgressMonitor', 'ProgressMonitorInputStream',
+ 'Properties', 'PropertyChangeEvent',
+ 'PropertyChangeListener', 'PropertyChangeSupport',
+ 'PropertyDescriptor', 'PropertyEditor',
+ 'PropertyEditorManager', 'PropertyEditorSupport',
+ 'PropertyPermission', 'PropertyResourceBundle',
+ 'PropertyVetoException', 'ProtectionDomain',
+ 'ProtocolException', 'Provider', 'ProviderException',
+ 'Proxy', 'PublicKey', 'PUBLIC_MEMBER',
+ 'PushbackInputStream', 'PushbackReader',
+ 'QuadCurve2D', 'QuadCurve2D.Double',
+ 'QuadCurve2D.Float', 'Random', 'RandomAccessFile',
+ 'Raster', 'RasterFormatException', 'RasterOp',
+ 'Reader', 'Receiver', 'Rectangle', 'Rectangle2D',
+ 'Rectangle2D.Double', 'Rectangle2D.Float',
+ 'RectangularShape', 'Ref', 'RefAddr', 'Reference',
+ 'Referenceable', 'ReferenceQueue',
+ 'ReferralException', 'ReflectPermission', 'Registry',
+ 'RegistryHandler', 'RemarshalException', 'Remote',
+ 'RemoteCall', 'RemoteException', 'RemoteObject',
+ 'RemoteRef', 'RemoteServer', 'RemoteStub',
+ 'RenderableImage', 'RenderableImageOp',
+ 'RenderableImageProducer', 'RenderContext',
+ 'RenderedImage', 'RenderedImageFactory', 'Renderer',
+ 'RenderingHints', 'RenderingHints.Key',
+ 'RepaintManager', 'ReplicateScaleFilter',
+ 'Repository', 'RepositoryIdHelper', 'Request',
+ 'RescaleOp', 'Resolver', 'ResolveResult',
+ 'ResourceBundle', 'ResponseHandler', 'ResultSet',
+ 'ResultSetMetaData', 'ReverbType', 'RGBImageFilter',
+ 'RMIClassLoader', 'RMIClientSocketFactory',
+ 'RMIFailureHandler', 'RMISecurityException',
+ 'RMISecurityManager', 'RMIServerSocketFactory',
+ 'RMISocketFactory', 'Robot', 'RootPaneContainer',
+ 'RootPaneUI', 'RoundRectangle2D',
+ 'RoundRectangle2D.Double', 'RoundRectangle2D.Float',
+ 'RowMapper', 'RSAKey', 'RSAKeyGenParameterSpec',
+ 'RSAPrivateCrtKey', 'RSAPrivateCrtKeySpec',
+ 'RSAPrivateKey', 'RSAPrivateKeySpec', 'RSAPublicKey',
+ 'RSAPublicKeySpec', 'RTFEditorKit',
+ 'RuleBasedCollator', 'Runnable', 'RunTime',
+ 'Runtime', 'RuntimeException', 'RunTimeOperations',
+ 'RuntimePermission', 'SampleModel',
+ 'SchemaViolationException', 'Scrollable',
+ 'Scrollbar', 'ScrollBarUI', 'ScrollPane',
+ 'ScrollPaneConstants', 'ScrollPaneLayout',
+ 'ScrollPaneLayout.UIResource', 'ScrollPaneUI',
+ 'SearchControls', 'SearchResult',
+ 'SecureClassLoader', 'SecureRandom',
+ 'SecureRandomSpi', 'Security', 'SecurityException',
+ 'SecurityManager', 'SecurityPermission', 'Segment',
+ 'SeparatorUI', 'Sequence', 'SequenceInputStream',
+ 'Sequencer', 'Sequencer.SyncMode', 'Serializable',
+ 'SerializablePermission', 'ServantObject',
+ 'ServerCloneException', 'ServerError',
+ 'ServerException', 'ServerNotActiveException',
+ 'ServerRef', 'ServerRequest',
+ 'ServerRuntimeException', 'ServerSocket',
+ 'ServiceDetail', 'ServiceDetailHelper',
+ 'ServiceInformation', 'ServiceInformationHelper',
+ 'ServiceInformationHolder',
+ 'ServiceUnavailableException', 'Set',
+ 'SetOverrideType', 'SetOverrideTypeHelper', 'Shape',
+ 'ShapeGraphicAttribute', 'ShortHolder',
+ 'ShortLookupTable', 'ShortMessage', 'ShortSeqHelper',
+ 'ShortSeqHolder', 'Signature', 'SignatureException',
+ 'SignatureSpi', 'SignedObject', 'Signer',
+ 'SimpleAttributeSet', 'SimpleBeanInfo',
+ 'SimpleDateFormat', 'SimpleTimeZone',
+ 'SinglePixelPackedSampleModel',
+ 'SingleSelectionModel', 'SizeLimitExceededException',
+ 'SizeRequirements', 'SizeSequence', 'Skeleton',
+ 'SkeletonMismatchException',
+ 'SkeletonNotFoundException', 'SliderUI', 'Socket',
+ 'SocketException', 'SocketImpl', 'SocketImplFactory',
+ 'SocketOptions', 'SocketPermission',
+ 'SocketSecurityException', 'SoftBevelBorder',
+ 'SoftReference', 'SortedMap', 'SortedSet',
+ 'Soundbank', 'SoundbankReader', 'SoundbankResource',
+ 'SourceDataLine', 'SplitPaneUI', 'SQLData',
+ 'SQLException', 'SQLInput', 'SQLOutput',
+ 'SQLPermission', 'SQLWarning', 'Stack',
+ 'StackOverflowError', 'StateEdit', 'StateEditable',
+ 'StateFactory', 'Statement', 'Streamable',
+ 'StreamableValue', 'StreamCorruptedException',
+ 'StreamTokenizer', 'StrictMath', 'String',
+ 'StringBuffer', 'StringBufferInputStream',
+ 'StringCharacterIterator', 'StringContent',
+ 'StringHolder', 'StringIndexOutOfBoundsException',
+ 'StringReader', 'StringRefAddr', 'StringSelection',
+ 'StringTokenizer', 'StringValueHelper',
+ 'StringWriter', 'Stroke', 'Struct', 'StructMember',
+ 'StructMemberHelper', 'Stub', 'StubDelegate',
+ 'StubNotFoundException', 'Style', 'StyleConstants',
+ 'StyleConstants.CharacterConstants',
+ 'StyleConstants.ColorConstants',
+ 'StyleConstants.FontConstants',
+ 'StyleConstants.ParagraphConstants', 'StyleContext',
+ 'StyledDocument', 'StyledEditorKit',
+ 'StyledEditorKit.AlignmentAction',
+ 'StyledEditorKit.BoldAction',
+ 'StyledEditorKit.FontFamilyAction',
+ 'StyledEditorKit.FontSizeAction',
+ 'StyledEditorKit.ForegroundAction',
+ 'StyledEditorKit.ItalicAction',
+ 'StyledEditorKit.StyledTextAction',
+ 'StyledEditorKit.UnderlineAction', 'StyleSheet',
+ 'StyleSheet.BoxPainter', 'StyleSheet.ListPainter',
+ 'SwingConstants', 'SwingPropertyChangeSupport',
+ 'SwingUtilities', 'SyncFailedException',
+ 'Synthesizer', 'SysexMessage', 'System',
+ 'SystemColor', 'SystemException', 'SystemFlavorMap',
+ 'TabableView', 'TabbedPaneUI', 'TabExpander',
+ 'TableCellEditor', 'TableCellRenderer',
+ 'TableColumn', 'TableColumnModel',
+ 'TableColumnModelEvent', 'TableColumnModelListener',
+ 'TableHeaderUI', 'TableModel', 'TableModelEvent',
+ 'TableModelListener', 'TableUI', 'TableView',
+ 'TabSet', 'TabStop', 'TagElement', 'TargetDataLine',
+ 'TCKind', 'TextAction', 'TextArea', 'TextAttribute',
+ 'TextComponent', 'TextEvent', 'TextField',
+ 'TextHitInfo', 'TextLayout',
+ 'TextLayout.CaretPolicy', 'TextListener',
+ 'TextMeasurer', 'TextUI', 'TexturePaint', 'Thread',
+ 'ThreadDeath', 'ThreadGroup', 'ThreadLocal',
+ 'Throwable', 'Tie', 'TileObserver', 'Time',
+ 'TimeLimitExceededException', 'Timer',
+ 'TimerTask', 'Timestamp', 'TimeZone', 'TitledBorder',
+ 'ToolBarUI', 'Toolkit', 'ToolTipManager',
+ 'ToolTipUI', 'TooManyListenersException', 'Track',
+ 'TransactionRequiredException',
+ 'TransactionRolledbackException',
+ 'TRANSACTION_REQUIRED', 'TRANSACTION_ROLLEDBACK',
+ 'Transferable', 'TransformAttribute', 'TRANSIENT',
+ 'Transmitter', 'Transparency', 'TreeCellEditor',
+ 'TreeCellRenderer', 'TreeExpansionEvent',
+ 'TreeExpansionListener', 'TreeMap', 'TreeModel',
+ 'TreeModelEvent', 'TreeModelListener', 'TreeNode',
+ 'TreePath', 'TreeSelectionEvent',
+ 'TreeSelectionListener', 'TreeSelectionModel',
+ 'TreeSet', 'TreeUI', 'TreeWillExpandListener',
+ 'TypeCode', 'TypeCodeHolder', 'TypeMismatch',
+ 'Types', 'UID', 'UIDefaults',
+ 'UIDefaults.ActiveValue', 'UIDefaults.LazyInputMap',
+ 'UIDefaults.LazyValue', 'UIDefaults.ProxyLazyValue',
+ 'UIManager', 'UIManager.LookAndFeelInfo',
+ 'UIResource', 'ULongLongSeqHelper',
+ 'ULongLongSeqHolder', 'ULongSeqHelper',
+ 'ULongSeqHolder', 'UndeclaredThrowableException',
+ 'UndoableEdit', 'UndoableEditEvent',
+ 'UndoableEditListener', 'UndoableEditSupport',
+ 'UndoManager', 'UnexpectedException',
+ 'UnicastRemoteObject', 'UnionMember',
+ 'UnionMemberHelper', 'UNKNOWN', 'UnknownError',
+ 'UnknownException', 'UnknownGroupException',
+ 'UnknownHostException',
+ 'UnknownObjectException', 'UnknownServiceException',
+ 'UnknownUserException', 'UnmarshalException',
+ 'UnrecoverableKeyException', 'Unreferenced',
+ 'UnresolvedPermission', 'UnsatisfiedLinkError',
+ 'UnsolicitedNotification',
+ 'UnsolicitedNotificationEvent',
+ 'UnsolicitedNotificationListener',
+ 'UnsupportedAudioFileException',
+ 'UnsupportedClassVersionError',
+ 'UnsupportedEncodingException',
+ 'UnsupportedFlavorException',
+ 'UnsupportedLookAndFeelException',
+ 'UnsupportedOperationException',
+ 'UNSUPPORTED_POLICY', 'UNSUPPORTED_POLICY_VALUE',
+ 'URL', 'URLClassLoader', 'URLConnection',
+ 'URLDecoder', 'URLEncoder', 'URLStreamHandler',
+ 'URLStreamHandlerFactory', 'UserException',
+ 'UShortSeqHelper', 'UShortSeqHolder',
+ 'UTFDataFormatException', 'Util', 'UtilDelegate',
+ 'Utilities', 'ValueBase', 'ValueBaseHelper',
+ 'ValueBaseHolder', 'ValueFactory', 'ValueHandler',
+ 'ValueMember', 'ValueMemberHelper',
+ 'VariableHeightLayoutCache', 'Vector', 'VerifyError',
+ 'VersionSpecHelper', 'VetoableChangeListener',
+ 'VetoableChangeSupport', 'View', 'ViewFactory',
+ 'ViewportLayout', 'ViewportUI',
+ 'VirtualMachineError', 'Visibility',
+ 'VisibilityHelper', 'VMID', 'VM_ABSTRACT',
+ 'VM_CUSTOM', 'VM_NONE', 'VM_TRUNCATABLE',
+ 'VoiceStatus', 'Void', 'WCharSeqHelper',
+ 'WCharSeqHolder', 'WeakHashMap', 'WeakReference',
+ 'Window', 'WindowAdapter', 'WindowConstants',
+ 'WindowEvent', 'WindowListener', 'WrappedPlainView',
+ 'WritableRaster', 'WritableRenderedImage',
+ 'WriteAbortedException', 'Writer',
+ 'WrongTransaction', 'WStringValueHelper',
+ 'X509Certificate', 'X509CRL', 'X509CRLEntry',
+ 'X509EncodedKeySpec', 'X509Extension', 'ZipEntry',
+ 'ZipException', 'ZipFile', 'ZipInputStream',
+ 'ZipOutputStream', 'ZoneView',
+ '_BindingIteratorImplBase', '_BindingIteratorStub',
+ '_IDLTypeStub', '_NamingContextImplBase',
+ '_NamingContextStub', '_PolicyStub', '_Remote_Stub'
+ ),
+ 4 => array(
+ 'Double', 'Int', 'Boolean', 'Byte', 'Short', 'Long', 'Char', 'Float', 'Unit', 'Nothing', 'Any'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}',
+ '+', '-', '*', '/', '%',
+ '!', '&', '|', '^',
+ '<', '>', '=',
+ '?', ':', ';',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000066; font-weight: bold;',
+ 3 => 'color: #003399;',
+ 4 => 'color: #000066; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #006699;',
+ 3 => 'color: #008000; font-style: italic; font-weight: bold;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006633;',
+ 2 => 'color: #006633;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'SCRIPT' => array(),
+ 'REGEXPS' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.google.com/search?hl=en&amp;q=allinurl%3Adocs.oracle.com+javase+docs+api+{FNAMEL}',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/latex.php b/platform/www/vendor/geshi/geshi/src/geshi/latex.php
new file mode 100644
index 0000000..79f1f9d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/latex.php
@@ -0,0 +1,221 @@
+<?php
+/*************************************************************************************
+ * latex.php
+ * -----
+ * Author: efi, Matthias Pospiech (matthias@pospiech.eu)
+ * Copyright: (c) 2006 efi, Matthias Pospiech (matthias@pospiech.eu), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/09/23
+ *
+ * LaTeX language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/08/18 (1.0.8.1)
+ * - Changes in color and some additional command recognition
+ * - No special Color for Brackets, it is only distracting
+ * if color should be reintroduced it should be less bright
+ * - Math color changed from green to violett, since green is now used for comments
+ * - Comments are now colored and the only green. The reason for coloring the comments
+ * is that often important information is in the comments und was merely unvisible before.
+ * - New Color for [Options]
+ * - color for labels not specialised anymore. It makes sence in large documents but less in
+ * small web examples.
+ * - \@keyword introduced
+ * - Fixed \& escaped ampersand
+ * 2006/09/23 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ * *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'LaTeX',
+ 'COMMENT_SINGLE' => array(
+ 1 => '%'
+ ),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'addlinespace','and','address','appendix','author','backmatter',
+ 'bfseries','bibitem','bigskip','blindtext','caption','captionabove',
+ 'captionbelow','cdot','centering','chapter','cite','color',
+ 'colorbox','date','dedication','def','definecolor','documentclass',
+ 'edef','else','email','emph','eqref','extratitle','fbox','fi',
+ 'flushleft','flushright','footnote','frac','frontmatter',
+ 'graphicspath','hfil','hfill','hfilll','hline','hspace','huge','ifx','include',
+ 'includegraphics','infty','input','int','item','itemsep',
+ 'KOMAoption','KOMAoptions','label','LaTeX','left','let','limits',
+ 'listfiles','listoffigures','listoftables','lowertitleback',
+ 'mainmatter','makeatletter','makeatother','makebox','makeindex',
+ 'maketitle','mbox','mediumskip','newcommand','newenvironment',
+ 'newpage','nocite','nonumber','pagestyle','par','paragraph',
+ 'parbox','parident','parskip','partial','publishers','raggedleft',
+ 'raggedright','raisebox','ref','renewcommand','renewenvironment',
+ 'right','rule','section','setlength','sffamily','subject',
+ 'subparagraph','subsection','subsubsection','subtitle','sum',
+ 'table','tableofcontents','textbf','textcolor','textit',
+ 'textnormal','textsuperscript','texttt','textwidth','thanks','title',
+ 'titlehead','today','ttfamily','uppertitleback','urlstyle',
+ 'usepackage','vfil','vfill','vfilll','vspace'
+ )
+ ),
+ 'SYMBOLS' => array(
+ "&", "\\", "{", "}", "[", "]"
+ ),
+ 'CASE_SENSITIVE' => array(
+ 1 => true,
+ GESHI_COMMENTS => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #800000;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #2C922C; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000000; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #E02020; '
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #8020E0; font-weight: normal;', // Math inner
+ 2 => 'color: #C08020; font-weight: normal;', // [Option]
+ 3 => 'color: #8020E0; font-weight: normal;', // Maths
+ 4 => 'color: #800000; font-weight: normal;', // Structure: Labels
+ 5 => 'color: #00008B; font-weight: bold;', // Structure (\section{->x<-})
+ 6 => 'color: #800000; font-weight: normal;', // Structure (\section)
+ 7 => 'color: #0000D0; font-weight: normal;', // Environment \end or \begin{->x<-} (brighter blue)
+ 8 => 'color: #C00000; font-weight: normal;', // Structure \end or \begin
+ 9 => 'color: #2020C0; font-weight: normal;', // {...}
+ 10 => 'color: #800000; font-weight: normal;', // \%, \& etc.
+ 11 => 'color: #E00000; font-weight: normal;', // \@keyword
+ 12 => 'color: #800000; font-weight: normal;', // \keyword
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.golatex.de/wiki/%5C{FNAME}',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ // Math inner
+ 1 => array(
+ GESHI_SEARCH => "(\\\\begin\\{(equation|displaymath|eqnarray|subeqnarray|math|multline|gather|align|alignat|flalign)\\})(.*)(\\\\end\\{\\2\\})",
+ GESHI_REPLACE => '\3',
+ GESHI_MODIFIERS => 'Us',
+ GESHI_BEFORE => '\1',
+ GESHI_AFTER => '\4'
+ ),
+ // [options]
+ 2 => array(
+ GESHI_SEARCH => "(?<=\[).*(?=\])",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => 'Us',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ // Math mode with $ ... $
+ 3 => array(
+ GESHI_SEARCH => "\\$.+\\$",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => 'Us',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ // Structure: Label
+ 4 => "\\\\(?:label|pageref|ref|cite)(?=[^a-zA-Z])",
+ // Structure: sections
+ 5 => array(
+ GESHI_SEARCH => "(\\\\(?:part|chapter|(?:sub){0,2}section|(?:sub)?paragraph|addpart|addchap|addsec)\*?\\{)(.*)(?=\\})",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'U',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ // Structure: sections
+ 6 => "\\\\(?:part|chapter|(?:sub){0,2}section|(?:sub)?paragraph|addpart|addchap|addsec)\*?(?=[^a-zA-Z])",
+ // environment \begin{} and \end{} (i.e. the things inside the {})
+ 7 => array(
+ GESHI_SEARCH => "(\\\\(?:begin|end)\\{)(.*)(?=\\})",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'U',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ // Structure \begin and \end
+ 8 => "\\\\(?:end|begin)(?=[^a-zA-Z])",
+ // {parameters}
+ 9 => array(
+ GESHI_SEARCH => "(?<=\\{)(?!<\|!REG3XP5!>).*?(?=\\})",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => 'Us',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ // \%, \& usw.
+ 10 => "\\\\(?:[_$%]|&amp;)",
+ // \@keywords
+ 11 => "(?<!<\|!REG3XP[8]!>)\\\\@[a-zA-Z]+\*?",
+ // \keywords
+ 12 => "(?<!<\|!REG3XP[468]!>)\\\\[a-zA-Z]+\*?",
+
+// ---------------------------------------------
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'COMMENTS' => array(
+ 'DISALLOWED_BEFORE' => '\\'
+ ),
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<=\\\\)",
+ 'DISALLOWED_AFTER' => "(?![A-Za-z0-9])"
+ ),
+ 'ENABLE_FLAGS' => array(
+ 'NUMBERS' => GESHI_NEVER,
+ 'BRACKETS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/lb.php b/platform/www/vendor/geshi/geshi/src/geshi/lb.php
new file mode 100644
index 0000000..b1193c0
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/lb.php
@@ -0,0 +1,160 @@
+<?php
+/*************************************************************************************
+ * lb.php
+ * --------
+ * Author: Chris Iverson (cj.no.one@gmail.com)
+ * Copyright: (c) 2010 Chris Iverson
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/07/18
+ *
+ * Liberty BASIC language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/07/22
+ * - First Release
+ *
+ * 2010/08/23
+ * - Added missing default variables
+ *
+ * TODO (updated 2010/07/20)
+ * -------------------------
+ * Prevent highlighting numbers in handle names(constants beginning with #)
+ * Allow number highlighting after a single period(e.g. .9 = 0.9, should be
+ * highlighted
+ * Prevent highlighting keywords within branch labels(within brackets)
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Liberty BASIC',
+ 'COMMENT_SINGLE' => array(1 => '\''),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'and', 'append', 'as', 'beep', 'bmpbutton', 'bmpsave', 'boolean',
+ 'button', 'byref', 'call', 'callback', 'calldll', 'callfn', 'case',
+ 'checkbox', 'close', 'cls', 'colordialog', 'combobox', 'confirm',
+ 'cursor', 'data', 'dialog', 'dim', 'dll', 'do', 'double', 'dump',
+ 'dword', 'else', 'end', 'error', 'exit', 'field', 'filedialog',
+ 'files', 'fontdialog', 'for', 'function', 'get', 'gettrim',
+ 'global', 'gosub', 'goto', 'graphicbox', 'graphics', 'groupbox',
+ 'if', 'input', 'kill', 'let', 'line', 'listbox', 'loadbmp',
+ 'locate', 'long', 'loop', 'lprint', 'mainwin', 'maphandle', 'menu',
+ 'mod', 'name', 'next', 'nomainwin', 'none', 'notice', 'on',
+ 'oncomerror', 'or', 'open', 'out', 'output', 'password', 'playmidi',
+ 'playwave', 'popupmenu', 'print', 'printerdialog', 'prompt', 'ptr',
+ 'put', 'radiobutton', 'random', 'randomize', 'read', 'readjoystick',
+ 'redim', 'rem', 'restore', 'resume', 'return', 'run', 'scan',
+ 'seek', 'select', 'short', 'sort', 'statictext', 'stop', 'stopmidi',
+ 'struct', 'stylebits', 'sub', 'text', 'textbox', 'texteditor',
+ 'then', 'timer', 'titlebar', 'to', 'trace', 'ulong', 'unloadbmp',
+ 'until', 'ushort', 'void', 'wait', 'window', 'wend', 'while',
+ 'word', 'xor'
+ ),
+ 2 => array(
+ 'abs', 'acs', 'asc', 'asn', 'atn', 'chr$', 'cos', 'date$',
+ 'dechex$', 'eof', 'eval', 'eval$', 'exp', 'hbmp', 'hexdec', 'hwnd',
+ 'inp', 'input$', 'inputto$', 'instr', 'int', 'left$', 'len', 'lof',
+ 'log', 'lower$', 'max', 'midipos', 'mid$', 'min', 'mkdir', 'not',
+ 'right$', 'rmdir', 'rnd', 'sin', 'space$', 'sqr', 'str$', 'tab',
+ 'tan', 'time$', 'trim$', 'txcount', 'upper$', 'using', 'val',
+ 'winstring', 'word$'
+ ),
+ 3 => array(
+ 'BackgroundColor$', 'Com', 'ComboboxColor$', 'ComError', 'ComErrorNumber',
+ 'CommandLine$', 'ComPortNumber', 'DefaultDir$',
+ 'DisplayHeight', 'DisplayWidth', 'Drives$', 'Err', 'Err$',
+ 'ForegroundColor$', 'Inkey$', 'Joy1x', 'Joy1y', 'Joy1z',
+ 'Joy1button1', 'Joy1button2', 'Joy2x', 'Joy2y', 'Joy2z',
+ 'Joy2button1', 'Joy2button2', 'ListboxColor$', 'MouseX', 'MouseY', 'Platform$',
+ 'PrintCollate', 'PrintCopies', 'PrinterFont$', 'PrinterName$', 'StartupDir$',
+ 'TextboxColor$', 'TexteditorColor$', 'Version$', 'WindowHeight',
+ 'WindowWidth', 'UpperLeftX', 'UpperLeftY'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '(', ')', '[', ']', '+', '-', '*', '/', '%', '=', '<', '>', ':', ',', '#'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF;',
+ 2 => 'color: #AD0080;',
+ 3 => 'color: #008080;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF0000;',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 2 => array(
+ //In LB, the second keyword list is a list of built-in functions,
+ //and their names should not be highlighted unless being used
+ //as a function name.
+ 'DISALLOWED_AFTER' => '(?=\s*\()'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/ldif.php b/platform/www/vendor/geshi/geshi/src/geshi/ldif.php
new file mode 100644
index 0000000..b77b8ee
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/ldif.php
@@ -0,0 +1,114 @@
+<?php
+/*************************************************************************************
+ * ldif.php
+ * --------
+ * Author: Bruno Harbulot (Bruno.Harbulot@manchester.ac.uk)
+ * Copyright: (c) 2005 deguix, (c) 2010 Bruno Harbulot
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/03/01
+ *
+ * LDIF language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/03/01 (1.0.8.11)
+ * - First Release
+ * - Derived from ini.php (INI language), (c) 2005 deguix
+ *
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'LDIF',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => ''
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #933;'
+ ),
+ 'NUMBERS' => array(
+ 0 => ''
+ ),
+ 'METHODS' => array(
+ 0 => ''
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #000066; font-weight: bold;',
+ 1 => 'color: #FF0000;'
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => array(
+ GESHI_SEARCH => '([a-zA-Z0-9_]+):(.+)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ':\\2'
+ ),
+ 1 => array(
+ // Evil hackery to get around GeSHi bug: <>" and ; are added so <span>s can be matched
+ // Explicit match on variable names because if a comment is before the first < of the span
+ // gets chewed up...
+ GESHI_SEARCH => '([<>";a-zA-Z0-9_]+):(.+)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1:',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/lisp.php b/platform/www/vendor/geshi/geshi/src/geshi/lisp.php
new file mode 100644
index 0000000..5029ca2
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/lisp.php
@@ -0,0 +1,147 @@
+<?php
+/*************************************************************************************
+ * lisp.php
+ * --------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/30
+ *
+ * Generic Lisp language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2013/11/13 (1.0.8.13)
+ * - Fixed bug where a keyword was highlighted in identifiers (Edward Hart)
+ * 2005/12/9 (1.0.2)
+ * - Added support for :keywords and ::access (Denis Mashkevich)
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/08/30 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Lisp',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(';|' => '|;'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'not','defun','princ','when',
+ 'eval','apply','funcall','quote','identity','function',
+ 'complement','backquote','lambda','set','setq','setf',
+ 'defmacro','gensym','make','symbol','intern',
+ 'name','value','plist','get',
+ 'getf','putprop','remprop','hash','array','aref',
+ 'car','cdr','caar','cadr','cdar','cddr','caaar','caadr','cadar',
+ 'caddr','cdaar','cdadr','cddar','cdddr','caaaar','caaadr',
+ 'caadar','caaddr','cadaar','cadadr','caddar','cadddr',
+ 'cdaaar','cdaadr','cdadar','cdaddr','cddaar','cddadr',
+ 'cdddar','cddddr','cons','list','append','reverse','last','nth',
+ 'nthcdr','member','assoc','subst','sublis','nsubst',
+ 'nsublis','remove','length',
+ 'mapc','mapcar','mapl','maplist','mapcan','mapcon','rplaca',
+ 'rplacd','nconc','delete','atom','symbolp','numberp',
+ 'boundp','null','listp','consp','minusp','zerop','plusp',
+ 'evenp','oddp','eq','eql','equal','cond','case','and','or',
+ 'let','l','if','prog','prog1','prog2','progn','go','return',
+ 'do','dolist','dotimes','catch','throw','error','cerror','break',
+ 'continue','errset','baktrace','evalhook','truncate','float',
+ 'rem','min','max','abs','sin','cos','tan','expt','exp','sqrt',
+ 'random','logand','logior','logxor','lognot','bignums','logeqv',
+ 'lognand','lognor','logorc2','logtest','logbitp','logcount',
+ 'integer','nil','parse-integer','make-list','print','write'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']',
+ '!', '%', '^', '&',
+ ' + ',' - ',' * ',' / ',
+ '=','<','>',
+ '.',':',',',';',
+ '|'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #555;',
+ 1 => 'color: #555;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ '::', ':'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9-\$_\|\#|^&])',
+ ),
+ 'OOLANG' => array(
+ 'MATCH_AFTER' => '[a-zA-Z][a-zA-Z0-9_\-]*'
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/llvm.php b/platform/www/vendor/geshi/geshi/src/geshi/llvm.php
new file mode 100644
index 0000000..0c19c7d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/llvm.php
@@ -0,0 +1,389 @@
+<?php
+/*************************************************************************************
+ * llvm.php
+ * --------
+ * Author: Benny Baumann (BenBE@geshi.org), Azriel Fasten (azriel.fasten@gmail.com)
+ * Copyright: (c) 2010 Benny Baumann (http://qbnz.com/highlighter/), Azriel Fasten (azriel.fasten@gmail.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/10/14
+ *
+ * LLVM language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/10/14 (1.0.8.10)
+ * - First Release
+ *
+ * TODO (updated 2010/10/14)
+ * -------------------------
+ * * Check if all links aren't broken
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'LLVM Intermediate Representation',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'HARDQUOTE' => array("\"", "\""),
+ 'HARDESCAPE' => array("\"", "\\"),
+ 'HARDCHAR' => "\\",
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ // 1 => "#\\\\[nfrtv\$\"\n\\\\]#i",
+ //Hexadecimal Char Specs
+ // 2 => "#\\\\x[\da-fA-F]{1,2}#i",
+ //Octal Char Specs
+ // 3 => "#\\\\[0-7]{1,3}#",
+ //String Parsing of Variable Names
+ // 4 => "#\\$[a-z0-9_]+(?:\\[[a-z0-9_]+\\]|->[a-z0-9_]+)?|(?:\\{\\$|\\$\\{)[a-z0-9_]+(?:\\[('?)[a-z0-9_]*\\1\\]|->[a-z0-9_]+)*\\}#i",
+ //Experimental extension supporting cascaded {${$var}} syntax
+ // 5 => "#\$[a-z0-9_]+(?:\[[a-z0-9_]+\]|->[a-z0-9_]+)?|(?:\{\$|\$\{)[a-z0-9_]+(?:\[('?)[a-z0-9_]*\\1\]|->[a-z0-9_]+)*\}|\{\$(?R)\}#i",
+ //Format String support in ""-Strings
+ // 6 => "#%(?:%|(?:\d+\\\\\\\$)?\\+?(?:\x20|0|'.)?-?(?:\d+|\\*)?(?:\.\d+)?[bcdefFosuxX])#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 0 => array(
+ 'to', 'nuw', 'nsw', 'inbounds', 'entry', 'return'
+ ),
+ //Terminator Instructions
+ 1 => array(
+ 'ret', 'br', 'switch', 'indirectbr', 'invoke', 'resume', 'catchswitch', 'catchret', 'cleanupret', 'unreachable'
+ ),
+ //Binary Operations
+ 2 => array(
+ 'add', 'fadd', 'sub', 'fsub', 'mul', 'fmul', 'udiv', 'sdiv', 'fdiv', 'urem', 'srem', 'frem'
+ ),
+ //Bitwise Binary Operations
+ 3 => array(
+ 'shl', 'lshr', 'ashr', 'and', 'or', 'xor'
+ ),
+ //Vector Operations
+ 4 => array(
+ 'extractelement', 'insertelement', 'shufflevector'
+ ),
+ //Aggregate Operations
+ 5 => array(
+ 'extractvalue', 'insertvalue'
+ ),
+ //Memory Access and Addressing Operations
+ 6 => array(
+ 'alloca', 'load', 'store', 'fence', 'cmpxchg', 'atomicrmw', 'getelementptr'
+ ),
+ //Conversion Operations
+ 7 => array(
+ 'trunc', 'zext', 'sext', 'fptrunc', 'fpext', 'fptoui', 'fptosi', 'uitofp', 'sitofp',
+ 'ptrtoint', 'inttoptr', 'bitcast', 'addrspacecast'
+ ),
+ //Other Operations
+ 8 => array(
+ 'icmp', 'fcmp', 'phi', 'select', 'call', 'va_arg', 'landingpad', 'catchpad', 'cleanuppad'
+ ),
+ //Linkage Types
+ 9 => array(
+ 'private', 'internal', 'available_externally', 'linkonce', 'weak', 'common', 'appending',
+ 'extern_weak', 'linkonce_odr', 'weak_odr', 'external'
+ ),
+ //Calling Conventions
+ 10 => array(
+ 'ccc', 'fastcc', 'coldcc', 'cc 10', 'cc 11', 'webkit_jscc', 'anyregcc', 'preserve_mostcc',
+ 'preserve_allcc', 'cxx_fast_tlscc', 'swiftcc', 'cc'
+ ),
+ //Structure Types
+ 11 => array(
+ 'type'
+ ),
+ //Parameter Attributes
+ 12 => array(
+ 'zeroext', 'signext', 'inreg', 'byval', 'inalloca', 'sret', 'align', 'noalias', 'nocapture', 'nest',
+ 'returned', 'nonnull', 'dereferenceable', 'dereferenceable_or_null', 'swiftself', 'swifterror'
+ ),
+ //Function Attributes
+ 13 => array(
+ 'alignstack', 'allocsize', 'alwaysinline', 'builtin', 'cold', 'convergent', 'inaccessiblememonly',
+ 'inaccessiblemem_or_argmemonly', 'inlinehint', 'jumptable', 'minsize', 'naked', 'nobuiltin', 'noduplicate',
+ 'noimplicitfloat', 'noinline', 'nonlazybind', 'noredzone', 'noreturn', 'norecurse', 'nounwind',
+ 'optnone', 'optsize', 'patchable-function', 'readnone', 'readonly', 'writeonly', 'argmemonly',
+ 'returns_twice', 'safestack', 'sanitize_address', 'sanitize_memory', 'sanitize_thread', 'ssp',
+ 'sspreq', 'sspstrong', 'thunk', 'uwtable'
+ ),
+ //Module-Level Inline Assembly
+ 14 => array(
+ 'module asm'
+ ),
+ //Data Layout
+ 15 => array(
+ 'target datalayout'
+ ),
+ //Type System
+ 16 => array(
+ 'x86_mmx',
+ 'void',
+ 'label',
+ 'metadata',
+ 'opaque'
+ ),
+ //Floating Point Types
+ 17 => array(
+ 'half', 'float', 'double', 'fp128', 'x86_fp80', 'ppc_fp128',
+ ),
+ //Simple Constants
+ 18 => array(
+ 'false', 'true', 'null'
+ ),
+ //Global Variable
+ 19 => array(
+ 'global', 'addrspace', 'constant', 'section'
+ ),
+ //Functions
+ 20 => array(
+ 'declare', 'define'
+ ),
+ //Complex Constants
+ 21 => array(
+ 'zeroinitializer'
+ ),
+ //Undefined Values
+ 22 => array(
+ 'undef'
+ ),
+ //Addresses of Basic Blocks
+ 23 => array(
+ 'blockaddress'
+ ),
+ //Visibility Styles
+ 24 => array(
+ 'default', 'hidden', 'protected'
+ ),
+ //Volatile Memory Accesses
+ 25 => array(
+ 'volatile'
+ ),
+ 26 => array(
+ 'tail'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '(', ')', '[', ']', '{', '}',
+ '!', '@', '%', '&', '|', '/',
+ '<', '>',
+ '=', '-', '+', '*',
+ '.', ':', ',', ';'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true,
+ 10 => true,
+ 11 => true,
+ 12 => true,
+ 13 => true,
+ 14 => true,
+ 15 => true,
+ 16 => true,
+ 17 => true,
+ 18 => true,
+ 19 => true,
+ 20 => true,
+ 21 => true,
+ 22 => true,
+ 23 => true,
+ 24 => true,
+ 25 => true,
+ 26 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 0 => 'color: #209090;',
+ 1 => 'color: #0000F0;',
+ 2 => 'color: #00F000; font-weight: bold;',
+ 3 => 'color: #F00000;',
+ 4 => 'color: #00F0F0; font-weight: bold;',
+ 5 => 'color: #F000F0; font-weight: bold;',
+ 6 => 'color: #403020; font-weight: bold;',
+ 7 => 'color: #909090; font-weight: bold;',
+ 8 => 'color: #009090; font-weight: bold;',
+ 9 => 'color: #900090; font-weight: bold;',
+ 10 => 'color: #909000; font-weight: bold;',
+ 11 => 'color: #000090; font-weight: bold;',
+ 12 => 'color: #900000; font-weight: bold;',
+ 13 => 'color: #009000; font-weight: bold;',
+ 14 => 'color: #F0F090; font-weight: bold;',
+ 15 => 'color: #F090F0; font-weight: bold;',
+ 16 => 'color: #90F0F0; font-weight: bold;',
+ 17 => 'color: #9090F0; font-weight: bold;',
+ 18 => 'color: #90F090; font-weight: bold;',
+ 19 => 'color: #F09090; font-weight: bold;',
+ 20 => 'color: #4040F0; font-weight: bold;',
+ 21 => 'color: #40F040; font-weight: bold;',
+ 22 => 'color: #F04040; font-weight: bold;',
+ 23 => 'color: #F0F040; font-weight: bold;',
+ 24 => 'color: #F040F0; font-weight: bold;',
+ 25 => 'color: #40F0F0; font-weight: bold;',
+ 26 => 'color: #904040; font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #006699; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold; font-style: italic;',
+ 6 => 'color: #009933; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;',
+ 'HARD' => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #004000;',
+ 2 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;',
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #007088;',
+ 1 => 'color: #007088;',
+ // 2 => 'color: #000088;',
+ 3 => 'color: #700088;',
+ 4 => 'color: #010088;',
+ // 5 => 'color: #610088;',
+ // 6 => 'color: #616088;',
+ // 7 => 'color: #616988;',
+ // 8 => 'color: #616908;',
+ 9 => 'color: #6109F8;',
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ )
+ ),
+ 'URLS' => array(
+ 0 => '',
+ 1 => 'http://llvm.org/docs/LangRef.html#{FNAME}-instruction',
+ 2 => 'http://llvm.org/docs/LangRef.html#{FNAME}-instruction',
+ 3 => 'http://llvm.org/docs/LangRef.html#{FNAME}-instruction',
+ 4 => 'http://llvm.org/docs/LangRef.html#{FNAME}-instruction',
+ 5 => 'http://llvm.org/docs/LangRef.html#{FNAME}-instruction',
+ 6 => 'http://llvm.org/docs/LangRef.html#{FNAME}-instruction',
+ 7 => 'http://llvm.org/docs/LangRef.html#{FNAME}-instruction',
+ 8 => 'http://llvm.org/docs/LangRef.html#{FNAME}-instruction',
+ 9 => 'http://llvm.org/docs/LangRef.html#linkage-types',
+ 10 => 'http://llvm.org/docs/LangRef.html#calling-conventions',
+ 11 => 'http://llvm.org/docs/LangRef.html#opaque-structure-types',
+ 12 => 'http://llvm.org/docs/LangRef.html#parameter-attributes',
+ 13 => 'http://llvm.org/docs/LangRef.html#function-attributes',
+ 14 => 'http://llvm.org/docs/LangRef.html#module-level-inline-assembly',
+ 15 => 'http://llvm.org/docs/LangRef.html#data-layout',
+ 16 => 'http://llvm.org/docs/LangRef.html#type-system',
+ 17 => 'http://llvm.org/docs/LangRef.html#floating-point-types',
+ 18 => 'http://llvm.org/docs/LangRef.html#simple-constants',
+ 19 => 'http://llvm.org/docs/LangRef.html#global-variables',
+ 20 => 'http://llvm.org/docs/LangRef.html#functions',
+ 21 => 'http://llvm.org/docs/LangRef.html#complex-constants',
+ 22 => 'http://llvm.org/docs/LangRef.html#undefined-values',
+ 23 => 'http://llvm.org/docs/LangRef.html#addresses-of-basic-blocks',
+ 24 => 'http://llvm.org/docs/LangRef.html#visibility-styles',
+ 25 => 'http://llvm.org/docs/LangRef.html#volatile-memory-accesses',
+ 26 => 'http://llvm.org/docs/LangRef.html#call-instruction',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Variables
+ 0 => '%[-a-zA-Z$\._][-a-zA-Z$\._0-9]*',
+ //Labels
+ // 1 => '[-a-zA-Z$\._0-9]+:',
+ 1 => '(?<!\w)[\-\w\$\.]+:(?![^">]*<)',
+ //Strings
+ // 2 => '"[^"]+"',
+ //Unnamed variable slots
+ 3 => '%[-]?[0-9]+',
+ //Integer Types
+ 4 => array(
+ GESHI_SEARCH => '(?<!\w)i\d+(?!\w)',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '<a href="http://llvm.org/docs/LangRef.html#t_integer">',
+ GESHI_AFTER => '</a>'
+ ),
+ //Comments
+ // 5 => ';.*',
+ //Integer literals
+ // 6 => '\\b[-]?[0-9]+\\b',
+ //Floating point constants
+ // 7 => '\\b[-+]?[0-9]+\.[0-9]*\([eE][-+]?[0-9]+\)?\\b',
+ //Hex constants
+ // 8 => '\\b0x[0-9A-Fa-f]+\\b',
+ //Global variables
+ 9 => array(
+ GESHI_SEARCH => '@[-a-zA-Z$\._][-a-zA-Z$\._0-9]*',
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '<a href="http://llvm.org/docs/LangRef.html#globalvars">',
+ GESHI_AFTER => '</a>'
+ ),
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'SCRIPT_DELIMITERS' => array(),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/locobasic.php b/platform/www/vendor/geshi/geshi/src/geshi/locobasic.php
new file mode 100644
index 0000000..709de5d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/locobasic.php
@@ -0,0 +1,128 @@
+<?php
+/*************************************************************************************
+ * locobasic.php
+ * -------------
+ * Author: Nacho Cabanes
+ * Copyright: (c) 2009 Nacho Cabanes (http://www.nachocabanes.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/03/22
+ *
+ * Locomotive Basic (Amstrad CPC series) language file for GeSHi.
+ *
+ * More details at http://en.wikipedia.org/wiki/Locomotive_BASIC
+ *
+ * CHANGES
+ * -------
+ * 2009/03/22 (1.0.8.3)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Locomotive Basic',
+ 'COMMENT_SINGLE' => array(1 => "'", 2 => 'REM'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ "AFTER", "AND", "AUTO", "BORDER", "BREAK", "CALL", "CAT", "CHAIN",
+ "CLEAR", "CLG", "CLS", "CLOSEIN", "CLOSEOUT", "CONT", "CURSOR",
+ "DATA", "DEF", "DEFINT", "DEFREAL", "DEFSTR", "DEG", "DELETE",
+ "DERR", "DI", "DIM", "DRAW", "DRAWR", "EDIT", "EI", "ELSE", "END",
+ "ENV", "ENT", "EOF", "ERASE", "ERL", "ERR", "ERROR", "EVERY",
+ "FILL", "FN", "FOR", "FRAME", "GOSUB", "GOTO", "GRAPHICS", "HIMEM",
+ "IF", "INK", "INPUT", "KEY", "LET", "LINE", "LIST", "LOAD",
+ "LOCATE", "MASK", "MEMORY", "MERGE", "MODE", "MOVE", "MOVER", "NEW",
+ "NEXT", "NOT", "ON", "OPENIN", "OPENOUT", "OR", "ORIGIN", "PAPER",
+ "PEEK", "PEN", "PLOT", "PLOTR", "POKE", "PRINT", "RAD", "RANDOMIZE",
+ "READ", "RELEASE", "REMAIN", "RENUM", "RESTORE", "RESUME", "RETURN",
+ "RUN", "SAVE", "SPEED", "SOUND", "SPC", "SQ", "STEP", "STOP", "SWAP",
+ "SYMBOL", "TAB", "TAG", "TAGOFF", "TEST", "TESTR", "TIME", "TO",
+ "THEN", "TRON", "TROFF", "USING", "WAIT", "WEND", "WHILE", "WIDTH",
+ "WINDOW", "WRITE", "XOR", "ZONE"
+ ),
+ 2 => array(
+ "ABS", "ASC", "ATN", "BIN", "CHR", "CINT", "COPYCHR", "COS",
+ "CREAL", "DEC", "FIX", "FRE", "EXP", "HEX", "INKEY", "INP", "INSTR",
+ "INT", "JOY", "LEFT", "LEN", "LOG", "LOG10", "LOWER", "MAX", "MID",
+ "MIN", "MOD", "OUT", "PI", "POS", "RIGHT", "RND", "ROUND", "SGN",
+ "SIN", "SPACE", "SQR", "STR", "STRING", "TAN", "UNT", "UPPER",
+ "VAL", "VPOS", "XPOS", "YPOS"
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000088; font-weight: bold;',
+ 2 => 'color: #AA00AA; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080;',
+ 2 => 'color: #808080;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #008800;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0044ff;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/logtalk.php b/platform/www/vendor/geshi/geshi/src/geshi/logtalk.php
new file mode 100644
index 0000000..a4af76c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/logtalk.php
@@ -0,0 +1,343 @@
+<?php
+/*************************************************************************************
+ * logtalk.php
+ * -----------
+ *
+ * Author: Paulo Moura (pmoura@logtalk.org)
+ * Copyright: (c) 2009-2011 Paulo Moura (http://logtalk.org/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/10/24
+ *
+ * Logtalk language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2011/01/18 (1.1.4)
+ * - Added syntax coloring of ignore/1
+ * 2010/11/28 (1.1.3)
+ * - Added syntax coloring of conforms_to_protocol/2-3
+ * 2010/09/14 (1.1.2)
+ * - Added syntax coloring of coinductive/1
+ * 2010/06/23 (1.1.1)
+ * - Added syntax coloring of e/0 and pi/0
+ * - Added syntax coloring of ground/1, numbervars/3, keysort/2, and sort/2
+ * 2010/05/15 (1.1.0)
+ * - Added syntax coloring of callable/1 and compare/3
+ * 2009/10/28 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Logtalk',
+ 'COMMENT_SINGLE' => array(1 => '%'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(2 => "/0'./sim"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'"),
+ 'HARDQUOTE' => array('"', '"'),
+ 'HARDESCAPE' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[\\\\abfnrtv\'\"?\n]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]+\\\\#",
+ //Octal Char Specs
+ 3 => "#\\\\[0-7]+\\\\#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX_0O |
+ GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ // Directives (with arguments)
+ 1 => array(
+ // file directives
+ 'encoding', 'ensure_loaded',
+ // flag directives
+ 'set_logtalk_flag', 'set_prolog_flag',
+ // entity opening directives
+ 'category', 'object', 'protocol',
+ // predicate scope directives
+ 'private', 'protected', 'public',
+ // conditional compilation directives
+ 'elif', 'if',
+ // entity directives
+ 'calls', 'initialization', 'op', 'uses',
+ // predicate directives
+ 'alias', 'coinductive', 'discontiguous', 'dynamic', 'mode', 'info', 'meta_predicate', 'multifile', 'synchronized',
+ // module directives
+ 'export', 'module', 'reexport', 'use_module'
+ ),
+ // Directives (no arguments)
+ 2 => array(
+ // entity directives
+ 'dynamic',
+ // multi-threading directives
+ 'synchronized', 'threaded',
+ // entity closing directives
+ 'end_category', 'end_object', 'end_protocol',
+ // conditional compilation directives
+ 'else', 'endif'
+ ),
+ // Entity relations
+ 3 => array(
+ 'complements', 'extends', 'imports', 'implements','instantiates', 'specializes'
+ ),
+ // Built-in predicates (with arguments)
+ 4 => array(
+ // event handlers
+ 'after', 'before',
+ // execution-context methods
+ 'parameter', 'self', 'sender', 'this',
+ // predicate reflection
+ 'current_predicate', 'predicate_property',
+ // DCGs and term expansion
+ 'expand_goal', 'expand_term', 'goal_expansion', 'phrase', 'term_expansion',
+ // entity
+ 'abolish_category', 'abolish_object', 'abolish_protocol',
+ 'create_category', 'create_object', 'create_protocol',
+ 'current_category', 'current_object', 'current_protocol',
+ 'category_property', 'object_property', 'protocol_property',
+ // entity relations
+ 'complements_object', 'conforms_to_protocol',
+ 'extends_category', 'extends_object', 'extends_protocol',
+ 'implements_protocol', 'imports_category',
+ 'instantiates_class', 'specializes_class',
+ // events
+ 'abolish_events', 'current_event', 'define_events',
+ // flags
+ 'current_logtalk_flag', 'set_logtalk_flag',
+ 'current_prolog_flag', 'set_prolog_flag',
+ // compiling, loading, and library path
+ 'logtalk_compile', 'logtalk_library_path', 'logtalk_load',
+ // database
+ 'abolish', 'asserta', 'assertz', 'clause', 'retract', 'retractall',
+ // control
+ 'call', 'catch', 'ignore', 'once', 'throw',
+ // all solutions predicates
+ 'bagof', 'findall', 'forall', 'setof',
+ // multi-threading meta-predicates
+ 'threaded',
+ 'threaded_call', 'threaded_once', 'threaded_ignore', 'threaded_exit', 'threaded_peek',
+ 'threaded_wait', 'threaded_notify',
+ // term unification
+ 'unify_with_occurs_check',
+ // atomic term processing
+ 'atom_chars', 'atom_codes', 'atom_concat', 'atom_length',
+ 'number_chars', 'number_codes',
+ 'char_code',
+ // term creation and decomposition
+ 'arg', 'copy_term', 'functor', 'numbervars',
+ // term testing
+ 'atom', 'atomic', 'callable', 'compound', 'float', 'ground', 'integer', 'nonvar', 'number', 'sub_atom', 'var',
+ // term comparison
+ 'compare',
+ // stream selection and control
+ 'current_input', 'current_output', 'set_input', 'set_output',
+ 'open', 'close', 'flush_output', 'stream_property',
+ 'at_end_of_stream', 'set_stream_position',
+ // character and byte input/output predicates
+ 'get_byte', 'get_char', 'get_code',
+ 'peek_byte', 'peek_char', 'peek_code',
+ 'put_byte', 'put_char', 'put_code',
+ 'nl',
+ // term input/output predicates
+ 'current_op', 'op',
+ 'write', 'writeq', 'write_canonical', 'write_term',
+ 'read', 'read_term',
+ 'char_conversion', 'current_char_conversion',
+ // hooks
+ 'halt',
+ // sorting
+ 'keysort', 'sort'
+ ),
+ // Built-in predicates (no arguments)
+ 5 => array(
+ // control
+ 'fail', 'repeat', 'true',
+ // character and byte input/output predicates
+ 'nl',
+ // implementation defined hooks functions
+ 'halt',
+ // arithemtic evaluation
+ 'is',
+ // stream selection and control
+ 'at_end_of_stream', 'flush_output'
+ ),
+ // Evaluable functors (with arguments)
+ 6 => array(
+ 'float_integer_part', 'float_fractional_part',
+ 'rem', 'mod', 'abs', 'sign', 'floor', 'truncate', 'round', 'ceiling',
+ 'cos', 'atan', 'exp', 'log', 'sin', 'sqrt'
+ ),
+ // Evaluable functors (no arguments)
+ 7 => array(
+ 'e', 'pi', 'mod', 'rem'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ // external call
+ '{', '}'
+ ),
+ 1 => array(
+ // arithemtic comparison
+ '=:=', '=\=', '<', '=<', '>=', '>',
+ // term comparison
+ '<<', '>>', '/\\', '\\/', '\\',
+ // bitwise functors
+ '==', '\==', '@<', '@=<', '@>=', '@>',
+ // evaluable functors
+ '+', '-', '*', '/', '**',
+ // logic and control
+ '!', '\\+', ';',
+ // message sending operators
+ '::', '^^', ':',
+ // grammar rule and conditional functors
+ '-->', '->',
+ // mode operators
+ '@', '?',
+ // term to list predicate
+ '=..',
+ // unification
+ '=', '\\='
+ ),
+ 2 => array(
+ // clause and directive functors
+ ':-'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #2e4dc9;',
+ 2 => 'color: #2e4dc9;',
+ 3 => 'color: #2e4dc9;',
+ 4 => 'color: #9d4f37;',
+ 5 => 'color: #9d4f37;',
+ 6 => 'color: #9d4f37;',
+ 7 => 'color: #9d4f37;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #430000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #60a0b0; font-style: italic;',
+ 2 => 'color: #430000;',
+ 'MULTI' => 'color: #60a0b0; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #9f0000; font-weight: bold;',
+ 1 => 'color: #9f0000; font-weight: bold;',
+ 2 => 'color: #9f0000; font-weight: bold;',
+ 3 => 'color: #9f0000; font-weight: bold;',
+ 'HARD' => '',
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #666666;font-weight: bold;',
+ 1 => 'color: #666666;font-weight: bold;',
+ 2 => 'color: #000000;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #9f0000;',
+ 'HARD' => 'color: #9f0000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #848484;'
+ ),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '::'
+ ),
+ 'REGEXPS' => array(
+ // variables
+ 0 => '\b(?!(?:PIPE|SEMI|REG3XP\d*)[^a-zA-Z0-9_])[A-Z_][a-zA-Z0-9_]*(?![a-zA-Z0-9_])'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER
+ ),
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'DISALLOWED_BEFORE' => '(?<=:-\s)',
+ 'DISALLOWED_AFTER' => '(?=\()'
+ ),
+ 2 => array(
+ 'DISALLOWED_BEFORE' => '(?<=:-\s)',
+ 'DISALLOWED_AFTER' => '(?=\.)'
+ ),
+ 3 => array(
+ 'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#>|^&\'"])',
+ 'DISALLOWED_AFTER' => '(?=\()'
+ ),
+ 4 => array(
+ 'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#>|^&\'"])',
+ 'DISALLOWED_AFTER' => '(?=\()'
+ ),
+ 5 => array(
+ 'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#>|^&\'"])',
+ 'DISALLOWED_AFTER' => '(?![a-zA-Z0-9_\|%\\-&\'"])'
+ ),
+ 6 => array(
+ 'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#;>|^&\'"])',
+ 'DISALLOWED_AFTER' => '(?=\()'
+ ),
+ 7 => array(
+ 'DISALLOWED_BEFORE' => '(?<![a-zA-Z0-9\$_\|\#;>|^&\'"])',
+ 'DISALLOWED_AFTER' => '(?![a-zA-Z0-9_\|%\\-&\'"])'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/lolcode.php b/platform/www/vendor/geshi/geshi/src/geshi/lolcode.php
new file mode 100644
index 0000000..f473c0d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/lolcode.php
@@ -0,0 +1,159 @@
+<?php
+/*************************************************************************************
+ * lolcode.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/10/31
+ *
+ * LOLcode language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2014/2/25
+ * - Fixed to not throw missing index exception.
+ *
+ * 2008/10/31 (1.0.8.1)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'LOLcode',
+ 'COMMENT_SINGLE' => array('BTW'),
+ 'COMMENT_MULTI' => array('BTW','WTB'),
+ 'COMMENT_REGEXP' => array(
+ 1 => "/\bBTW\b.*$/im",
+ 2 => "/(^|\b)(?:OBTW\b.+?\bTLDR|LOL\b.+?\/LOL)(\b|$)/si"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ 1 => '/:[)>o":]/',
+ 2 => '/:\([\da-f]+\)/i',
+ 3 => '/:\{\w+\}/i',
+ 4 => '/:\[\w+\]/i',
+ ),
+ 'KEYWORDS' => array(
+ //Statements
+ 1 => array(
+ 'VISIBLE', 'HAI', 'KTHX', 'KTHXBYE', 'SMOOSH', 'GIMMEH', 'PLZ',
+ 'ON', 'INVISIBLE', 'R', 'ITZ', 'GTFO', 'COMPLAIN', 'GIMME',
+
+ 'OPEN', 'FILE', 'I HAS A', 'AWSUM THX', 'O NOES', 'CAN', 'HAS', 'HAZ',
+ 'HOW DOES I', 'IF U SAY SO', 'FOUND YR', 'BORROW', 'OWN', 'ALONG',
+ 'WITH', 'WIT', 'LOOK', 'AT', 'AWSUM', 'THX'
+ ),
+ //Conditionals
+ 2 => array(
+ 'IZ', 'YARLY', 'NOWAI', 'WTF?', 'MEBBE', 'OMG', 'OMGWTF',
+ 'ORLY?', 'OF', 'NOPE', 'SO', 'IM', 'MAI',
+
+ 'O RLY?', 'SUM', 'BOTH SAEM', 'DIFFRINT', 'BOTH', 'EITHER', 'WON',
+ 'DIFF', 'PRODUKT', 'QUOSHUNT', 'MOD', 'MKAY', 'OK', 'THING',
+ 'BIGNESS'
+ ),
+ //Repetition
+ 3 => array(
+ 'IN', 'OUTTA', 'LOOP', 'WHILE'
+ ),
+ //Operators \Math
+ 4 => array(
+ 'AN', 'AND', 'NOT', 'UP', 'YR', 'UPPIN', 'NERF', 'NERFIN', 'NERFZ',
+ 'SMASHING', 'UR', 'KINDA', 'LIKE', 'SAEM', 'BIG', 'SMALL',
+ 'BIGGR', 'SMALLR', 'BIGGER', 'SMALLER', 'GOOD', 'CUTE', 'THAN'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '.', ',', '?',
+ '!!'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #008000;',
+ 2 => 'color: #000080;',
+ 3 => 'color: #000080;',
+ 4 => 'color: #800000;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #666666; style: italic;',
+ 1 => 'color: #666666; style: italic;',
+ 2 => 'color: #666666; style: italic;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #00F;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #0F0;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #00F;'
+ ),
+ 'SCRIPT' => array(
+ 0 => 'color: #00F;'
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'SPACE_AS_WHITESPACE' => true
+ )
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/lotusformulas.php b/platform/www/vendor/geshi/geshi/src/geshi/lotusformulas.php
new file mode 100644
index 0000000..57d34f3
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/lotusformulas.php
@@ -0,0 +1,316 @@
+<?php
+/*************************************************************************************
+ * lotusformulas.php
+ * ------------------------
+ * Author: Richard Civil (info@richardcivil.net)
+ * Copyright: (c) 2008 Richard Civil (info@richardcivil.net), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/04/12
+ *
+ * @Formula/@Command language file for GeSHi.
+ *
+ * @Formula/@Command source: IBM Lotus Notes/Domino 8 Designer Help
+ *
+ * CHANGES
+ * -------
+ * 2008/04/12 (1.0.7.22)
+ * - First Release
+ *
+ * TODO (updated 2008/04/12)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Lotus Notes @Formulas',
+ 'COMMENT_SINGLE' => array(1 => "'"),
+ 'COMMENT_MULTI' => array('REM' => ';'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array (
+ '[ZoomPreview]', '[WorkspaceStackReplicaIcons]',
+ '[WorkspaceProperties]', '[WindowWorkspace]',
+ '[WindowTile]', '[WindowRestore]', '[WindowNext]',
+ '[WindowMinimizeAll]', '[WindowMinimize]', '[WindowMaximizeAll]',
+ '[WindowMaximize]', '[WindowCascade]', '[ViewSwitchForm]',
+ '[ViewShowUnread]', '[ViewShowServerNames]', '[ViewShowSearchBar]',
+ '[ViewShowRuler]', '[ViewShowPageBreaks]', '[ViewShowOnlyUnread]',
+ '[ViewShowOnlySelected]', '[ViewShowOnlySearchResults]',
+ '[ViewShowOnlyCategories]', '[ViewShowObject]',
+ '[ViewShowFieldHelp]', '[ViewRenamePerson]', '[ViewRefreshUnread]',
+ '[ViewRefreshFields]', '[ViewNavigatorsNone]',
+ '[ViewNavigatorsFolders]', '[ViewMoveName]', '[ViewHorizScrollbar]',
+ '[ViewExpandWithChildren]', '[ViewExpandAll]', '[ViewExpand]',
+ '[ViewCollapseAll]', '[ViewCollapse]', '[ViewChange]',
+ '[ViewCertify]', '[ViewBesideFolders]', '[ViewBelowFolders]',
+ '[ViewArrangeIcons]', '[V3EditPrevField]', '[V3EditNextField]',
+ '[UserIDSwitch]', '[UserIDSetPassword]', '[UserIDMergeCopy]',
+ '[UserIDInfo]', '[UserIDEncryptionKeys]', '[UserIDCreateSafeCopy]',
+ '[UserIDClearPassword]', '[UserIDCertificates]',
+ '[ToolsUserLogoff]', '[ToolsSpellCheck]', '[ToolsSmartIcons]',
+ '[ToolsSetupUserSetup]', '[ToolsSetupPorts]', '[ToolsSetupMail]',
+ '[ToolsSetupLocation]', '[ToolsScanUnreadSelected]',
+ '[ToolsScanUnreadPreferred]', '[ToolsScanUnreadChoose]',
+ '[ToolsRunMacro]', '[ToolsRunBackgroundMacros]', '[ToolsReplicate]',
+ '[ToolsRefreshSelectedDocs]', '[ToolsRefreshAllDocs]',
+ '[ToolsMarkSelectedUnread]', '[ToolsMarkSelectedRead]',
+ '[ToolsMarkAllUnread]', '[ToolsMarkAllRead]', '[ToolsHangUp]',
+ '[ToolsCategorize]', '[ToolsCall]', '[TextUnderline]',
+ '[TextSpacingSingle]', '[TextSpacingOneAndaHalf]',
+ '[TextSpacingDouble]', '[TextSetFontSize]', '[TextSetFontFace]',
+ '[TextSetFontColor]', '[TextReduceFont]', '[TextPermanentPen]',
+ '[TextParagraphStyles]', '[TextParagraph]', '[TextOutdent]',
+ '[TextNumbers]', '[TextNormal]', '[TextItalic]', '[TextFont]',
+ '[TextEnlargeFont]', '[TextCycleSpacing]', '[TextBullet]',
+ '[TextBold]', '[TextAlignRight]', '[TextAlignNone]',
+ '[TextAlignLeft]', '[TextAlignFull]', '[TextAlignCenter]',
+ '[SwitchView]', '[SwitchForm]', '[StyleCycleKey]',
+ '[SmartIconsNextSet]', '[SmartIconsFloating]', '[ShowProperties]',
+ '[ShowHidePreviewPane]', '[ShowHideParentPreview]',
+ '[ShowHideLinkPreview]', '[ShowHideIMContactList]',
+ '[SetCurrentLocation]', '[SendInstantMessage]',
+ '[SectionRemoveHeader]', '[SectionProperties]',
+ '[SectionExpandAll]', '[SectionExpand]', '[SectionDefineEditors]',
+ '[SectionCollapseAll]', '[SectionCollapse]', '[RunScheduledAgents]',
+ '[RunAgent]', '[ReplicatorStop]', '[ReplicatorStart]',
+ '[ReplicatorSendReceiveMail]', '[ReplicatorSendMail]',
+ '[ReplicatorReplicateWithServer]', '[ReplicatorReplicateSelected]',
+ '[ReplicatorReplicateNext]', '[ReplicatorReplicateHigh]',
+ '[Replicator]', '[RenameDatabase]', '[RemoveFromFolder]',
+ '[RemoteDebugLotusScript]', '[ReloadWindow]', '[RefreshWindow]',
+ '[RefreshParentNote]', '[RefreshHideFormulas]', '[RefreshFrame]',
+ '[PublishDatabase]', '[PictureProperties]', '[PasteBitmapAsObject]',
+ '[PasteBitmapAsBackground]', '[OpenView]', '[OpenPage]',
+ '[OpenNavigator]', '[OpenInNewWindow]', '[OpenHelpDocument]',
+ '[OpenFrameset]', '[OpenDocument]', '[OpenCalendar]',
+ '[ObjectProperties]', '[ObjectOpen]', '[ObjectDisplayAs]',
+ '[NavPrevUnread]', '[NavPrevSelected]', '[NavPrevMain]',
+ '[NavPrev]', '[NavNextUnread]', '[NavNextSelected]',
+ '[NavNextMain]', '[NavNext]', '[NavigatorTest]',
+ '[NavigatorProperties]', '[NavigateToBacklink]',
+ '[NavigatePrevUnread]', '[NavigatePrevSelected]',
+ '[NavigatePrevMain]', '[NavigatePrevHighlight]', '[NavigatePrev]',
+ '[NavigateNextUnread]', '[NavigateNextSelected]',
+ '[NavigateNextMain]', '[NavigateNextHighlight]', '[NavigateNext]',
+ '[MoveToTrash]', '[MailSendPublicKey]', '[MailSendEncryptionKey]',
+ '[MailSendCertificateRequest]', '[MailSend]', '[MailScanUnread]',
+ '[MailRequestNewPublicKey]', '[MailRequestNewName]',
+ '[MailRequestCrossCert]', '[MailOpen]', '[MailForwardAsAttachment]',
+ '[MailForward]', '[MailComposeMemo]', '[MailAddress]',
+ '[LayoutProperties]', '[LayoutElementSendToBack]',
+ '[LayoutElementProperties]', '[LayoutElementBringToFront]',
+ '[LayoutAddText]', '[LayoutAddGraphic]', '[InsertSubform]',
+ '[HotspotProperties]', '[HotspotClear]', '[HelpUsingDatabase]',
+ '[HelpAboutNotes]', '[HelpAboutDatabase]', '[GoUpLevel]',
+ '[FormTestDocument]', '[FormActions]', '[FolderRename]',
+ '[FolderProperties]', '[FolderMove]', '[FolderExpandWithChildren]',
+ '[FolderExpandAll]', '[FolderExpand]', '[FolderDocuments]',
+ '[FolderCustomize]', '[FolderCollapse]', '[Folder]',
+ '[FindFreeTimeDialog]', '[FileSaveNewVersion]', '[FileSave]',
+ '[FilePrintSetup]', '[FilePrint]', '[FilePageSetup]',
+ '[FileOpenDBRepID]', '[FileOpenDatabase]', '[FileNewReplica]',
+ '[FileNewDatabase]', '[FileImport]', '[FileFullTextUpdate]',
+ '[FileFullTextInfo]', '[FileFullTextDelete]',
+ '[FileFullTextCreate]', '[FileExport]', '[FileExit]',
+ '[FileDatabaseUseServer]', '[FileDatabaseRemove]',
+ '[FileDatabaseInfo]', '[FileDatabaseDelete]', '[FileDatabaseCopy]',
+ '[FileDatabaseCompact]', '[FileDatabaseACL]', '[FileCloseWindow]',
+ '[ExitNotes]', '[Execute]', '[ExchangeUnreadMarks]', '[EmptyTrash]',
+ '[EditUp]', '[EditUntruncate]', '[EditUndo]', '[EditTop]',
+ '[EditTableInsertRowColumn]', '[EditTableFormat]',
+ '[EditTableDeleteRowColumn]', '[EditShowHideHiddenChars]',
+ '[EditSelectByDate]', '[EditSelectAll]', '[EditRight]',
+ '[EditRestoreDocument]', '[EditResizePicture]',
+ '[EditQuoteSelection]', '[EditProfileDocument]', '[EditProfile]',
+ '[EditPrevField]', '[EditPhoneNumbers]', '[EditPasteSpecial]',
+ '[EditPaste]', '[EditOpenLink]', '[EditNextField]',
+ '[EditMakeDocLink]', '[EditLocations]', '[EditLinks]', '[EditLeft]',
+ '[EditInsertText]', '[EditInsertTable]', '[EditInsertPopup]',
+ '[EditInsertPageBreak]', '[EditInsertObject]',
+ '[EditInsertFileAttachment]', '[EditInsertButton]',
+ '[EditIndentFirstLine]', '[EditIndent]', '[EditHorizScrollbar]',
+ '[EditHeaderFooter]', '[EditGotoField]', '[EditFindNext]',
+ '[EditFindInPreview]', '[EditFind]', '[EditEncryptionKeys]',
+ '[EditDown]', '[EditDocument]', '[EditDetach]', '[EditDeselectAll]',
+ '[EditCut]', '[EditCopy]', '[EditClear]', '[EditButton]',
+ '[EditBottom]', '[DiscoverFolders]', '[Directories]',
+ '[DialingRules]', '[DesignViewSelectFormula]', '[DesignViews]',
+ '[DesignViewNewColumn]', '[DesignViewFormFormula]',
+ '[DesignViewEditActions]', '[DesignViewColumnDef]',
+ '[DesignViewAttributes]', '[DesignViewAppendColumn]',
+ '[DesignSynopsis]', '[DesignSharedFields]', '[DesignReplace]',
+ '[DesignRefresh]', '[DesignMacros]', '[DesignIcon]',
+ '[DesignHelpUsingDocument]', '[DesignHelpAboutDocument]',
+ '[DesignFormWindowTitle]', '[DesignFormUseField]',
+ '[DesignFormShareField]', '[DesignForms]', '[DesignFormNewField]',
+ '[DesignFormFieldDef]', '[DesignFormAttributes]',
+ '[DesignDocumentInfo]', '[DebugLotusScript]',
+ '[DatabaseReplSettings]', '[DatabaseDelete]', '[CreateView]',
+ '[CreateTextbox]', '[CreateSubForm]', '[CreateSection]',
+ '[CreateRectangularHotspot]', '[CreateRectangle]',
+ '[CreatePolyline]', '[CreatePolygon]', '[CreateNavigator]',
+ '[CreateLayoutRegion]', '[CreateForm]', '[CreateFolder]',
+ '[CreateEllipse]', '[CreateControlledAccessSection]',
+ '[CreateAgent]', '[CreateAction]', '[CopySelectedAsTable]',
+ '[ComposeWithReference]', '[Compose]', '[CloseWindow]', '[Clear]',
+ '[ChooseFolders]', '[CalendarGoTo]', '[CalendarFormat]',
+ '[AttachmentView]', '[AttachmentProperties]', '[AttachmentLaunch]',
+ '[AttachmentDetachAll]', '[AgentTestRun]', '[AgentSetServerName]',
+ '[AgentRun]', '[AgentLog]', '[AgentEnableDisable]', '[AgentEdit]',
+ '[AdminTraceConnection]', '[AdminStatisticsConfig]',
+ '[AdminSendMailTrace]', '[AdminRemoteConsole]',
+ '[AdminRegisterUser]', '[AdminRegisterServer]',
+ '[AdminRegisterFromFile]', '[AdminOutgoingMail]',
+ '[AdminOpenUsersView]', '[AdminOpenStatistics]',
+ '[AdminOpenServersView]', '[AdminOpenServerLog]',
+ '[AdminOpenGroupsView]', '[AdminOpenCertLog]', '[AdminOpenCatalog]',
+ '[AdminOpenAddressBook]', '[AdminNewOrgUnit]',
+ '[AdminNewOrganization]', '[Administration]',
+ '[AdminIDFileSetPassword]', '[AdminIDFileExamine]',
+ '[AdminIDFileClearPassword]', '[AdminDatabaseQuotas]',
+ '[AdminDatabaseAnalysis]', '[AdminCrossCertifyKey]',
+ '[AdminCrossCertifyIDFile]', '[AdminCreateGroup]', '[AdminCertify]',
+ '[AddToIMContactList]', '[AddDatabaseRepID]', '[AddDatabase]',
+ '[AddBookmark]'
+ ),
+ 2 => array(
+ 'SELECT', 'FIELD', 'ENVIRONMENT', 'DEFAULT', '@Zone ', '@Yesterday',
+ '@Yes', '@Year', '@Word', '@Wide', '@While', '@Weekday',
+ '@WebDbName', '@ViewTitle', '@ViewShowThisUnread', '@Version',
+ '@VerifyPassword', '@ValidateInternetAddress', '@V4UserAccess',
+ '@V3UserName', '@V2If', '@UserRoles', '@UserPrivileges',
+ '@UserNamesList', '@UserNameLanguage', '@UserName', '@UserAccess',
+ '@UrlQueryString', '@URLOpen', '@URLHistory', '@URLGetHeader',
+ '@URLEncode', '@URLDecode', '@UpperCase', '@UpdateFormulaContext',
+ '@Unique', '@UndeleteDocument', '@Unavailable', '@True', '@Trim',
+ '@Transform', '@ToTime', '@ToNumber', '@Tomorrow', '@Today',
+ '@TimeZoneToText', '@TimeToTextInZone', '@TimeMerge', '@Time',
+ '@ThisValue', '@ThisName', '@TextToTime', '@TextToNumber', '@Text',
+ '@TemplateVersion', '@Tan', '@Sum', '@Success', '@Subset',
+ '@StatusBar', '@Sqrt', '@Soundex', '@Sort', '@Sin', '@Sign',
+ '@SetViewInfo', '@SetTargetFrame', '@SetProfileField',
+ '@SetHTTPHeader', '@SetField', '@SetEnvironment', '@SetDocField',
+ '@Set', '@ServerName', '@ServerAccess', '@Select', '@Second',
+ '@Round', '@RightBack', '@Right', '@Return', '@Responses',
+ '@ReplicaID', '@ReplaceSubstring', '@Replace', '@Repeat',
+ '@RegQueryValue', '@RefreshECL', '@Random', '@ProperCase',
+ '@Prompt', '@Power', '@PostedCommand', '@PolicyIsFieldLocked',
+ '@Platform', '@PickList', '@Pi', '@PasswordQuality', '@Password',
+ '@OrgDir', '@OptimizeMailAddress', '@OpenInNewWindow', '@Now',
+ '@Nothing', '@NoteID', '@No', '@NewLine', '@Narrow', '@NameLookup',
+ '@Name', '@Month', '@Modulo', '@Modified', '@Minute', '@Min',
+ '@MiddleBack', '@Middle', '@Member', '@Max', '@Matches',
+ '@MailSignPreference', '@MailSend', '@MailSavePreference',
+ '@MailEncryptSentPreference', '@MailEncryptSavedPreference',
+ '@MailDbName', '@LowerCase', '@Log', '@Locale', '@Ln', '@Like',
+ '@Length', '@LeftBack', '@Left', '@LDAPServer', '@LaunchApp',
+ '@LanguagePreference', '@Keywords', '@IsVirtualizedDirectory',
+ '@IsValid', '@IsUsingJavaElement', '@IsUnavailable', '@IsTime',
+ '@IsText', '@IsResponseDoc', '@IsNumber', '@IsNull', '@IsNotMember',
+ '@IsNewDoc', '@IsModalHelp', '@IsMember', '@IsExpandable',
+ '@IsError', '@IsEmbeddedInsideWCT', '@IsDocTruncated',
+ '@IsDocBeingSaved', '@IsDocBeingRecalculated', '@IsDocBeingMailed',
+ '@IsDocBeingLoaded', '@IsDocBeingEdited', '@IsDB2', '@IsCategory',
+ '@IsAvailable', '@IsAppInstalled', '@IsAgentEnabled', '@Integer',
+ '@InheritedDocumentUniqueID', '@Implode', '@IfError', '@If',
+ '@Hour', '@HashPassword', '@HardDeleteDocument', '@GetViewInfo',
+ '@GetProfileField', '@GetPortsList', '@GetIMContactListGroupNames',
+ '@GetHTTPHeader', '@GetFocusTable', '@GetField', '@GetDocField',
+ '@GetCurrentTimeZone', '@GetAddressBooks', '@FormLanguage', '@For',
+ '@FontList', '@FloatEq', '@FileDir', '@False', '@Failure',
+ '@Explode', '@Exp', '@Eval', '@Error', '@Environment', '@Ends',
+ '@EnableAlarms', '@Elements', '@EditUserECL', '@EditECL',
+ '@DoWhile', '@Domain', '@DocumentUniqueID', '@DocSiblings',
+ '@DocParentNumber', '@DocOmmittedLength', '@DocNumber', '@DocMark',
+ '@DocLock', '@DocLevel', '@DocLength', '@DocFields',
+ '@DocDescendants', '@DocChildren', '@Do', '@DialogBox',
+ '@DeleteField', '@DeleteDocument', '@DDETerminate', '@DDEPoke',
+ '@DDEInitiate', '@DDEExecute', '@DbTitle', '@DbName', '@DbManager',
+ '@DbLookup', '@DbExists', '@DbCommand', '@DbColumn', '@DB2Schema',
+ '@Day', '@Date', '@Created', '@Count', '@Cos', '@Contains',
+ '@ConfigFile', '@Compare', '@Command', '@ClientType',
+ '@CheckFormulaSyntax', '@CheckAlarms', '@Char', '@Certificate',
+ '@BusinessDays', '@BrowserInfo', '@Begins', '@Author',
+ '@Attachments', '@AttachmentNames', '@AttachmentModifiedTimes',
+ '@AttachmentLengths', '@ATan2', '@ATan', '@ASin', '@Ascii',
+ '@AllDescendants', '@AllChildren', '@All', '@AdminECLIsLocked',
+ '@Adjust', '@AddToFolder', '@ACos', '@Accessed', '@AbstractSimple',
+ '@Abstract', '@Abs'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #800000;',
+ 2 => 'color: #0000FF;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #FF00FF;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF00FF;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0000AA;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 2
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/lotusscript.php b/platform/www/vendor/geshi/geshi/src/geshi/lotusscript.php
new file mode 100644
index 0000000..8e41f36
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/lotusscript.php
@@ -0,0 +1,189 @@
+<?php
+/**
+ * lotusscript.php
+ * ------------------------
+ * Author: Richard Civil (info@richardcivil.net)
+ * Copyright: (c) 2008 Richard Civil (info@richardcivil.net), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/04/12
+ *
+ * LotusScript language file for GeSHi.
+ *
+ * LotusScript source: IBM Lotus Notes/Domino 8 Designer Help
+ *
+ * CHANGES
+ * -------
+ * 2008/04/12 (1.0.7.22)
+ * - First Release
+ *
+ * TODO (2008/04/12)
+ * -----------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'LotusScript',
+ 'COMMENT_SINGLE' => array(1 => "'"),
+ 'COMMENT_MULTI' => array('%REM' => '%END REM'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"' , "|"),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array (
+ 'Yield', 'Year', 'Xor', 'Write', 'With', 'Width', 'While', 'Wend',
+ 'Weekday', 'VarType', 'Variant', 'Val', 'UString', 'UString$',
+ 'UseLSX', 'Use', 'Until', 'Unlock', 'Unicode', 'Uni', 'UChr',
+ 'UChr$', 'UCase', 'UCase$', 'UBound', 'TypeName', 'Type', 'TRUE',
+ 'Trim', 'Trim$', 'Today', 'To', 'TimeValue', 'TimeSerial', 'Timer',
+ 'TimeNumber', 'Time', 'Time$', 'Then', 'Text', 'Tan', 'Tab', 'Sub',
+ 'StrToken', 'StrToken$', 'StrRightBack', 'StrRightBack$',
+ 'StrRight', 'StrRight$', 'StrLeftBack', 'StrLeftBack$', 'StrLeft',
+ 'StrLeft$', 'String', 'String$', 'StrConv', 'StrCompare', 'StrComp',
+ 'Str', 'Str$', 'Stop', 'Step', 'Static', 'Sqr', 'Split', 'Spc',
+ 'Space', 'Space$', 'Sleep', 'Single', 'Sin', 'Shell', 'Shared',
+ 'Sgn', 'SetFileAttr', 'SetAttr', 'Set', 'SendKeys', 'Select',
+ 'Seek', 'Second', 'RTrim', 'RTrim$', 'RSet', 'Round', 'Rnd',
+ 'RmDir', 'RightC', 'RightC$', 'RightBP', 'RightBP$', 'RightB',
+ 'RightB$', 'Right', 'Right$', 'Return', 'Resume', 'Reset',
+ 'Replace', 'Remove', 'Rem', 'ReDim', 'Read', 'Randomize',
+ 'Random', 'Put', 'Public', 'Property', 'Private', 'Print',
+ 'Preserve', 'Pitch', 'PI', 'Output', 'Or', 'Option', 'Open', 'On',
+ 'Oct', 'Oct$', 'NULL', 'Now', 'NOTHING', 'Not', 'NoPitch', 'NoCase',
+ 'Next', 'New', 'Name', 'MsgBox', 'Month', 'Mod', 'MkDir', 'Minute',
+ 'MidC', 'MidC$', 'MidBP', 'MidBP$', 'MidB', 'MidB$', 'Mid', 'Mid$',
+ 'MessageBox', 'Me', 'LTrim', 'LTrim$', 'LSServer', 'LSI_Info',
+ 'LSet', 'Loop', 'Long', 'Log', 'LOF', 'Lock', 'LOC', 'LMBCS',
+ 'ListTag', 'List', 'Line', 'Like', 'Lib', 'Let', 'LenC', 'LenBP',
+ 'LenB', 'Len', 'LeftC', 'LeftC$', 'LeftBP', 'LeftBP$', 'LeftB',
+ 'LeftB$', 'Left', 'Left$', 'LCase', 'LCase$', 'LBound', 'Kill',
+ 'Join', 'IsUnknown', 'IsScalar', 'IsObject', 'IsNumeric', 'IsNull',
+ 'IsList', 'IsEmpty', 'IsElement', 'IsDate', 'IsArray', 'IsA', 'Is',
+ 'Integer', 'Int', 'InStrC', 'InStrBP', 'InStrB', 'InStr', 'InputBP',
+ 'InputBP$', 'InputBox', 'InputBox$', 'InputB', 'InputB$', 'Input',
+ 'Input$', 'In', 'IMSetMode', 'Implode', 'Implode$', 'Imp',
+ 'IMEStatus', 'If', 'Hour', 'Hex', 'Hex$', 'Goto', 'GoSub',
+ 'GetThreadInfo', 'GetFileAttr', 'GetAttr', 'Get', 'Function',
+ 'FullTrim', 'From', 'FreeFile', 'Fraction', 'Format', 'Format$',
+ 'ForAll', 'For', 'Fix', 'FileLen', 'FileDateTime', 'FileCopy',
+ 'FileAttr', 'FALSE', 'Explicit', 'Exp', 'Exit', 'Execute', 'Event',
+ 'Evaluate', 'Error', 'Error$', 'Err', 'Erl', 'Erase', 'Eqv', 'EOF',
+ 'Environ', 'Environ$', 'End', 'ElseIf', 'Else', 'Double', 'DoEvents',
+ 'Do', 'Dir', 'Dir$', 'Dim', 'DestroyLock', 'Delete', 'DefVar',
+ 'DefStr', 'DefSng', 'DefLng', 'DefInt', 'DefDbl', 'DefCur',
+ 'DefByte', 'DefBool', 'Declare', 'Day', 'DateValue', 'DateSerial',
+ 'DateNumber', 'Date', 'Date$', 'DataType', 'CVDate', 'CVar',
+ 'Currency', 'CurDrive', 'CurDrive$', 'CurDir', 'CurDir$', 'CStr',
+ 'CSng', 'CreateLock', 'Cos', 'Const', 'Compare', 'Command',
+ 'Command$', 'CodeUnlock', 'CodeLockCheck', 'CodeLock', 'Close',
+ 'CLng', 'Class', 'CInt', 'Chr', 'Chr$', 'ChDrive', 'ChDir', 'CDbl',
+ 'CDat', 'CCur', 'CByte', 'CBool', 'Case', 'Call', 'ByVal', 'Byte',
+ 'Boolean', 'Bind', 'Binary', 'Bin', 'Bin$', 'Beep', 'Base', 'Atn2',
+ 'Atn', 'ASin', 'Asc', 'As', 'ArrayUnique', 'ArrayReplace',
+ 'ArrayGetIndex', 'ArrayAppend', 'Append', 'AppActivate', 'Any',
+ 'And', 'Alias', 'ActivateApp', 'ACos', 'Access', 'Abs', '%Include',
+ '%If', '%END', '%ElseIf', '%Else'
+ ),
+ 2 => array (
+ 'NotesXSLTransformer', 'NotesXMLProcessor', 'NotesViewNavigator',
+ 'NotesViewEntryCollection', 'NotesViewEntry', 'NotesViewColumn',
+ 'NotesView', 'NotesUIWorkspace', 'NotesUIView', 'NotesUIScheduler',
+ 'NotesUIDocument', 'NotesUIDatabase', 'NotesTimer', 'NotesStream',
+ 'NotesSession', 'NotesSAXParser', 'NotesSAXException',
+ 'NotesSAXAttributeList', 'NotesRichTextTable', 'NotesRichTextTab',
+ 'NotesRichTextStyle', 'NotesRichTextSection', 'NotesRichTextRange',
+ 'NotesRichTextParagraphStyle', 'NotesRichTextNavigator',
+ 'NotesRichTextItem', 'NotesRichTextDocLink',
+ 'NotesReplicationEntry', 'NotesReplication', 'NotesRegistration',
+ 'NotesOutlineEntry', 'NotesOutline', 'NotesNoteCollection',
+ 'NotesNewsLetter', 'NotesName', 'NotesMIMEHeader',
+ 'NotesMIMEEntity', 'NotesLog', 'NotesItem', 'NotesInternational',
+ 'NotesForm', 'NotesEmbeddedObject', 'NotesDXLImporter',
+ 'NotesDXLExporter', 'NotesDOMXMLDeclNode', 'NotesDOMTextNode',
+ 'NotesDOMProcessingInstructionNode', 'NotesDOMParser',
+ 'NotesDOMNotationNode', 'NotesDOMNodeList', 'NotesDOMNode',
+ 'NotesDOMNamedNodeMap', 'NotesDOMEntityReferenceNode',
+ 'NotesDOMEntityNode', 'NotesDOMElementNode',
+ 'NotesDOMDocumentTypeNode', 'NotesDOMDocumentNode',
+ 'NotesDOMDocumentFragmentNode', 'NotesDOMCommentNode',
+ 'NotesDOMCharacterDataNote', 'NotesDOMCDATASectionNode',
+ 'NotesDOMAttributeNode', 'NotesDocumentCollection', 'NotesDocument',
+ 'NotesDbDirectory', 'NotesDateTime', 'NotesDateRange',
+ 'NotesDatabase', 'NotesColorObject', 'NotesAgent',
+ 'NotesAdministrationProcess', 'NotesACLEntry', 'NotesACL',
+ 'Navigator', 'Field', 'Button'
+ )
+ ) ,
+ 'SYMBOLS' => array(
+ '(', ')'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF;',
+ 2 => 'color: #0000EE;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF00FF;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0000AA;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #006600;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 2
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/lscript.php b/platform/www/vendor/geshi/geshi/src/geshi/lscript.php
new file mode 100644
index 0000000..a73e786
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/lscript.php
@@ -0,0 +1,385 @@
+<?php
+/*************************************************************************************
+ * lscript.php
+ * ---------
+ * Author: Arendedwinter (admin@arendedwinter.com)
+ * Copyright: (c) 2008 Beau McGuigan (http://www.arendedwinter.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 15/11/2008
+ *
+ * Lightwave Script language file for GeSHi.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'LScript',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ //Yes, I'm aware these are out of order,
+ //I had to rearrange and couldn't be bothered changing the numbers...
+ 7 => array(
+ '@data', '@define', '@else', '@end', '@fpdepth', '@if', '@include',
+ '@insert', '@library', '@localipc', '@name', '@save', '@script',
+ '@sequence', '@version', '@warnings'
+ ),
+ 1 => array(
+ 'break', 'case', 'continue', 'else', 'end', 'false', 'for',
+ 'foreach', 'if', 'return', 'switch', 'true', 'while',
+ ),
+ 3 => array(
+ 'active', 'alertlevel', 'alpha', 'alphaprefix', 'animfilename', 'autokeycreate',
+ 'backdroptype', 'blue', 'boxthreshold', 'button',
+ 'channelsvisible', 'childrenvisible', 'compfg', 'compbg', 'compfgalpha',
+ 'coneangles', 'cosine', 'count', 'ctl', 'curFilename', 'curFrame',
+ 'currenttime', 'curTime', 'curType',
+ 'depth', 'diffshade', 'diffuse', 'dimensions', 'displayopts', 'dynamicupdate',
+ 'end', 'eta',
+ 'filename', 'flags', 'fogtype', 'fps', 'frame', 'frameend', 'frameheight',
+ 'framestart', 'framestep', 'framewidth',
+ 'generalopts', 'genus', 'geometry', 'gNorm', 'goal', 'green',
+ 'h', 'hasAlpha', 'height',
+ 'id', 'innerlimit', 'isColor',
+ 'keyCount', 'keys',
+ 'limiteregion', 'locked', 'luminous',
+ 'maxsamplesperpixel', 'minsamplesperpixel', 'mirror', 'motionx', 'motiony',
+ 'name', 'newFilename', 'newFrame', 'newTime', 'newType', 'null', 'numthreads',
+ 'objID', 'oPos', 'outerlimit', 'oXfrm',
+ 'parent', 'pixel', 'pixelaspect', 'point', 'points', 'pointcount', 'polNum',
+ 'polycount', 'polygon', 'polygons', 'postBehavior', 'preBehavior', 'previewend',
+ 'previewstart', 'previewstep',
+ 'range', 'rawblue', 'rawgreen', 'rawred', 'rayLength', 'raySource', 'red',
+ 'reflectblue', 'reflectgreen', 'reflectred', 'recursiondepth', 'renderend',
+ 'renderopts', 'renderstart', 'renderstep', 'rendertype', 'restlength',
+ 'rgbprefix', 'roughness',
+ 'selected', 'setColor', 'setPattern', 'shading', 'shadow', 'shadows',
+ 'shadowtype', 'size', 'source', 'special', 'specshade', 'specular',
+ 'spotsize', 'start', 'sx', 'sy', 'sz',
+ 'target', 'totallayers', 'totalpoints', 'totalpolygons', 'trans', 'transparency',
+ 'type',
+ 'value', 'view', 'visible', 'visibility',
+ 'w', 'width', 'wNorm', 'wPos', 'wXfrm',
+ 'x', 'xoffset',
+ 'y', 'yoffset',
+ 'z'
+ ),
+ 4 => array(
+ 'addLayer', 'addParticle', 'alphaspot', 'ambient', 'asAsc', 'asBin',
+ 'asInt', 'asNum', 'asStr', 'asVec', 'attach', 'axislocks',
+ 'backdropColor', 'backdropRay', 'backdropSqueeze', 'bone', 'blurLength',
+ 'close', 'color', 'contains', 'copy', 'createKey',
+ 'deleteKey', 'detach', 'drawCircle', 'drawLine', 'drawPoint', 'drawText',
+ 'drawTriangle',
+ 'edit', 'eof', 'event',
+ 'firstChannel', 'firstLayer', 'firstSelect', 'focalLength', 'fogColor',
+ 'fogMaxAmount', 'fogMaxDist', 'fogMinAmount', 'fogMinDist',
+ 'fovAngles', 'fStop', 'firstChild', 'focalDistance',
+ 'get', 'getChannelGroup', 'getEnvelope', 'getForward', 'getKeyBias',
+ 'getKeyContinuity', 'getKeyCurve', 'getKeyHermite', 'getKeyTension',
+ 'getKeyTime', 'getKeyValue', 'getParticle', 'getPivot', 'getPosition',
+ 'getRight', 'getRotation', 'getSelect', 'getScaling', 'getTag', 'getTexture',
+ 'getUp', 'getValue', 'getWorldPosition', 'getWorldForward', 'getWorldRight',
+ 'getWorldRotation', 'getWorldUp', 'globalBlur', 'globalMask', 'globalResolution',
+ 'hasCCEnd', 'hasCCStart',
+ 'illuminate', 'indexOf', 'isAscii', 'isAlnum', 'isAlpha', 'isBone',
+ 'isCamera', 'isChannel', 'isChannelGroup', 'isCntrl', 'isCurve', 'isDigit',
+ 'isEnvelope', 'isImage', 'isInt', 'isLight', 'isLower', 'isMapped', 'isMesh',
+ 'isNil', 'isNum', 'IsOpen', 'isOriginal', 'isPrint', 'isPunct', 'isScene',
+ 'isSpace', 'isStr', 'isUpper', 'isValid', 'isVMap', 'isVec', 'isXDigit',
+ 'keyExists',
+ 'layer', 'layerName', 'layerVisible', 'limits', 'line', 'linecount', 'load', 'luma',
+ 'next', 'nextLayer', 'nextSelect', 'nextChannel', 'nextChild', 'nl',
+ 'offset', 'open',
+ 'pack', 'param', 'parse', 'paste', 'persist', 'polygonCount', 'position',
+ 'rayCast', 'rayTrace', 'read', 'readByte', 'readInt', 'readNumber',
+ 'readDouble', 'readShort', 'readString', 'readVector', 'reduce',
+ 'remParticle', 'renderCamera', 'reopen', 'replace', 'reset', 'restParam',
+ 'rewind', 'rgb', 'rgbambient', 'rgbcolor', 'rgbspot',
+ 'save', 'schemaPosition', 'select', 'set', 'setChannelGroup', 'setKeyBias',
+ 'setKeyContinuity', 'setKeyCurve',
+ 'setKeyHermite', 'setKeyTension', 'setKeyValue', 'setParticle', 'setPoints',
+ 'setTag', 'setValue', 'server', 'serverFlags', 'sortA', 'sortD', 'surface',
+ 'trunc',
+ 'write', 'writeln', 'writeByte', 'writeData', 'writeNumber', 'writeDouble',
+ 'writeShort', 'writeString', 'writeVector',
+ 'vertex', 'vertexCount',
+ 'zoomFactor'
+ ),
+ 2 => array(
+ 'abs', 'acos', 'angle', 'append', 'ascii', 'asin', 'atan',
+ 'binary',
+ 'ceil', 'center', 'chdir', 'clearimage', 'cloned', 'comringattach',
+ 'comringdecode', 'comringdetach', 'comringencode', 'comringmsg', 'cos',
+ 'cosh', 'cot', 'cross2d', 'cross3d', 'csc', 'ctlstring', 'ctlinteger',
+ 'ctlnumber', 'ctlvector', 'ctldistance', 'ctlchoice', 'ctltext',
+ 'ctlcolor', 'ctlsurface', 'ctlfont', 'ctlpopup', 'ctledit', 'ctlpercent',
+ 'ctlangle', 'ctlrgb', 'ctlhsv', 'ctlcheckbox', 'ctlstate', 'ctlfilename',
+ 'ctlbutton', 'ctllistbox', 'ctlslider', 'ctlminislider', 'ctlsep', 'ctlimage',
+ 'ctltab', 'ctlallitems', 'ctlmeshitems', 'ctlcameraitems', 'ctllightitems',
+ 'ctlboneitems', 'ctlimageitems', 'ctlchannel', 'ctlviewport', 'Control_Management',
+ 'ctlpage', 'ctlgroup', 'ctlposition', 'ctlactive', 'ctlvisible', 'ctlalign',
+ 'ctlrefresh', 'ctlmenu', 'ctlinfo',
+ 'date', 'debug', 'deg', 'dot2d', 'dot3d', 'drawborder', 'drawbox', 'drawcircle',
+ 'drawelipse', 'drawerase', 'drawfillcircle', 'drawfillelipse', 'drawline',
+ 'drawpixel', 'drawtext', 'drawtextwidth', 'drawtextheight', 'dump',
+ 'error', 'exp', 'expose', 'extent',
+ 'fac', 'filecrc', 'filedelete', 'fileexists', 'filefind', 'filerename',
+ 'filestat', 'floor', 'format', 'frac', 'fullpath',
+ 'gamma', 'getdir', 'getenv', 'getfile', 'getfirstitem', 'getsep', 'getvalue',
+ 'globalrecall', 'globalstore',
+ 'hash', 'hex', 'hostBuild', 'hostVersion', 'hypot',
+ 'info', 'integer',
+ 'library', 'licenseId', 'lscriptVersion', 'load', 'loadimage', 'log', 'log10',
+ 'matchdirs', 'matchfiles', 'max', 'min', 'mkdir', 'mod', 'monend', 'moninit', 'monstep',
+ 'nil', 'normalize', 'number',
+ 'octal', 'overlayglyph',
+ 'parse', 'platform', 'pow',
+ 'rad', 'random', 'randu', 'range', 'read', 'readdouble', 'readInt', 'readNumber',
+ 'readShort', 'recall', 'regexp', 'reqabort', 'reqbegin', 'reqend', 'reqisopen',
+ 'reqkeyboard', 'reqopen', 'reqposition', 'reqpost', 'reqredraw',
+ 'reqsize', 'reqresize', 'requpdate', 'rmdir', 'round', 'runningUnder',
+ 'save', 'sec', 'select', 'selector', 'setdesc', 'setvalue', 'sin', 'sinh', 'size',
+ 'sizeof', 'sleep', 'spawn', 'split', 'sqrt', 'step', 'store', 'string', 'strleft',
+ 'strlower', 'strright', 'strsub', 'strupper',
+ 'tan', 'tanh', 'targetobject', 'terminate', 'text', 'time',
+ 'wait', 'warn', 'when', 'write', 'writeDouble', 'writeInt', 'writeNumber', 'writeShort',
+ 'var', 'vector', 'visitnodes', 'vmag',
+ ),
+ 5 => array(
+ 'addcurve', 'addpoint', 'addpolygon', 'addquad', 'addtriangle', 'alignpols',
+ 'autoflex', 'axisdrill',
+ 'bend', 'bevel', 'boolean', 'boundingbox',
+ 'changepart', 'changesurface', 'close', 'closeall', 'cmdseq', 'copy', 'copysurface',
+ 'createsurface', 'cut',
+ 'deformregion', 'delete',
+ 'editbegin', 'editend', 'exit', 'extrude',
+ 'fixedflex', 'flip', 'fontclear', 'fontcount', 'fontindex', 'fontload',
+ 'fontname', 'fracsubdivide', 'freezecurves',
+ 'getdefaultsurface',
+ 'jitter',
+ 'lathe', 'layerName', 'layerVisible', 'lyrbg', 'lyrdata', 'lyrempty', 'lyremptybg',
+ 'lyremptyfg', 'lyrfg', 'lyrsetbg', 'lyrsetfg', 'lyrswap',
+ 'magnet', 'make4patch', 'makeball', 'makebox', 'makecone', 'makedisc',
+ 'maketesball', 'maketext', 'mergepoints', 'mergepols', 'meshedit', 'mirror',
+ 'morphpols', 'move',
+ 'new', 'nextsurface',
+ 'paste', 'pathclone', 'pathextrude', 'pixel', 'pointcount', 'pointinfo',
+ 'pointmove', 'pole', 'polycount', 'polyinfo', 'polynormal', 'polypointcount',
+ 'polypoints', 'polysurface',
+ 'quantize',
+ 'railclone', 'railextrude', 'redo', 'removepols', 'rempoint', 'rempoly',
+ 'renamesurface', 'revert', 'rotate',
+ 'scale', 'selhide', 'selinvert', 'selmode', 'selpoint', 'selpolygon', 'selunhide',
+ 'selectvmap', 'setlayername', 'setobject', 'setpivot', 'setsurface', 'shapebevel',
+ 'shear', 'skinpols', 'smooth', 'smoothcurves', 'smoothscale', 'smoothshift',
+ 'soliddrill', 'splitpols', 'subdivide', 'swaphidden',
+ 'taper', 'triple', 'toggleCCend', 'toggleCCstart', 'togglepatches', 'twist',
+ 'undo', 'undogroupend', 'undogroupbegin', 'unifypols', 'unweld',
+ 'vortex',
+ 'weldaverage', 'weldpoints'
+ ),
+ 6 => array(
+ 'About', 'AboutOpenGL', 'AdaptiveSampling', 'AdaptiveThreshold',
+ 'AddAreaLight', 'AddBone', 'AddButton', 'AddCamera', 'AddChildBone',
+ 'AddDistantLight', 'AddEnvelope', 'AddLinearLight', 'AddNull',
+ 'AddPartigon', 'AddPlugins', 'AddPointLight', 'AddPosition',
+ 'AddRotation', 'AddScale', 'AddSpotlight', 'AddToSelection',
+ 'AdjustRegionTool', 'AffectCaustics', 'AffectDiffuse', 'AffectOpenGL',
+ 'AffectSpecular', 'AlertLevel', 'AmbientColor', 'AmbientIntensity',
+ 'Antialiasing', 'ApertureHeight', 'ApplyServer', 'AreaLight',
+ 'AutoConfirm', 'AutoFrameAdvance', 'AutoKey',
+ 'BackdropColor', 'BackView', 'BController', 'BLimits', 'BLurLength', 'BoneActive',
+ 'BoneFalloffType', 'BoneJointComp', 'BoneJointCompAmounts', 'BoneJointCompParent',
+ 'BoneLimitedRange', 'BoneMaxRange', 'BoneMinRange', 'BoneMuscleFlex',
+ 'BoneMuscleFlexAmounts', 'BoneMuscleFlexParent', 'BoneNormalization',
+ 'BoneRestLength', 'BoneRestPosition', 'BoneRestRotation', 'BoneSource',
+ 'BoneStrength', 'BoneStrengthMultiply', 'BoneWeightMapName', 'BoneWeightMapOnly',
+ 'BoneWeightShade', 'BoneXRay', 'BottomView', 'BoundingBoxThreshold',
+ 'BStiffness',
+ 'CacheCaustics', 'CacheRadiosity', 'CacheShadowMap',
+ 'CameraMask', 'CameraView', 'CameraZoomTool', 'CastShadow', 'CausticIntensity',
+ 'CenterItem', 'CenterMouse', 'ChangeTool', 'ClearAllBones', 'ClearAllCameras',
+ 'ClearAllLights', 'ClearAllObjects', 'ClearAudio', 'ClearScene', 'ClearSelected',
+ 'Clone', 'CommandHistory', 'CommandInput', 'Compositing', 'ConeAngleTool',
+ 'ContentDirectory', 'CreateKey',
+ 'DecreaseGrid', 'DeleteKey', 'DepthBufferAA', 'DepthOfField', 'DisplayOptions',
+ 'DistantLight', 'DrawAntialiasing', 'DrawBones', 'DrawChildBones', 'DynamicUpdate',
+ 'EditBones', 'EditCameras', 'EditKeys', 'EditLights',
+ 'EditMenus', 'EditObjects', 'EditPlugins', 'EditServer', 'EnableCaustics',
+ 'EnableDeformations', 'EnableIK', 'EnableLensFlares', 'EnableRadiosity', 'EnableServer',
+ 'EnableShadowMaps', 'EnableVIPER', 'EnableVolumetricLights', 'EnableXH',
+ 'EnableYP', 'EnableZB', 'EnahancedAA', 'ExcludeLight', 'ExcludeObject',
+ 'EyeSeparation',
+ 'FasterBones', 'FirstFrame', 'FirstItem', 'FitAll', 'FitSelected',
+ 'FlareIntensity', 'FlareOptions', 'FocalDistance', 'FogColor', 'FogMaxAmount',
+ 'FogMaxDistance', 'FogMinAmount', 'FogMinDistance', 'FogType', 'FractionalFrames',
+ 'FrameSize', 'FramesPerSecond', 'FrameStep', 'FreePreview', 'FrontView', 'FullTimeIK',
+ 'GeneralOptions', 'Generics', 'GlobalApertureHeight', 'GlobalBlurLength',
+ 'GlobalFrameSize', 'GlobalIllumination', 'GlobalMaskPosition', 'GlobalMotionBlur',
+ 'GlobalParticleBlur', 'GlobalPixelAspect', 'GlobalResolutionMulitplier', 'GoalItem',
+ 'GoalStrength', 'GoToFrame', 'GradientBackdrop', 'GraphEditor', 'GridSize', 'GroundColor',
+ 'HController', 'HideToolbar', 'HideWindows', 'HLimits', 'HStiffness',
+ 'ImageEditor', 'ImageProcessing', 'IncludeLight', 'IncludeObject', 'IncreaseGrid',
+ 'IndirectBounces', 'Item_SetWindowPos', 'ItemActive', 'ItemColor', 'ItemLock',
+ 'ItemProperties', 'ItemVisibilty',
+ 'KeepGoalWithinReach',
+ 'LastFrame', 'LastItem', 'LastPluginInterface', 'Layout_SetWindowPos',
+ 'Layout_SetWindowSize', 'LeftView', 'LensFlare', 'LensFStop', 'LightColor',
+ 'LightConeAngle', 'LightEdgeAngle', 'LightFalloffType', 'LightIntensity',
+ 'LightIntensityTool', 'LightQuality', 'LightRange', 'LightView', 'LimitB',
+ 'LimitDynamicRange', 'LimitedRegion', 'LimitH', 'LimitP', 'LinearLight',
+ 'LoadAudio', 'LoadFromScene', 'LoadMotion', 'LoadObject', 'LoadObjectLayer',
+ 'LoadPreview', 'LoadScene', 'LocalCoordinateSystem',
+ 'MakePreview', 'MaskColor', 'MaskPosition', 'MasterPlugins', 'MatchGoalOrientation',
+ 'MatteColor', 'MatteObject', 'MetaballResolution', 'Model', 'MorphAmount',
+ 'MorphAmountTool', 'MorphMTSE', 'MorphSurfaces', 'MorphTarget', 'MotionBlur',
+ 'MotionBlurDOFPreview', 'MotionOptions', 'MovePathTool', 'MovePivotTool', 'MoveTool',
+ 'NadirColor', 'NetRender', 'NextFrame', 'NextItem', 'NextKey', 'NextSibling',
+ 'NextViewLayout', 'NoiseReduction', 'Numeric',
+ 'ObjectDissolve',
+ 'ParentCoordinateSystem', 'ParentInPlace', 'ParentItem',
+ 'ParticleBlur', 'PathAlignLookAhead', 'PathAlignMaxLookSteps', 'PathAlignReliableDist',
+ 'Pause', 'PController', 'PerspectiveView',
+ 'PivotPosition', 'PivotRotation', 'PixelAspect', 'PlayAudio', 'PlayBackward',
+ 'PlayForward', 'PlayPreview', 'PLimits', 'PointLight', 'PolygonEdgeColor',
+ 'PolygonEdgeFlags', 'PolygonEdgeThickness', 'PolygonEdgeZScale', 'PolygonSize',
+ 'Position', 'Presets', 'PreviewFirstFrame', 'PreviewFrameStep', 'PreviewLastFrame',
+ 'PreviewOptions', 'PreviousFrame', 'PreviousItem', 'PreviousKey', 'PreviousSibling',
+ 'PreviousViewLayout', 'PStiffness',
+ 'Quit',
+ 'RadiosityIntensity', 'RadiosityTolerance', 'RadiosityType', 'RayRecursionLimit',
+ 'RayTraceReflection', 'RayTraceShadows',
+ 'RayTraceTransparency', 'ReceiveShadow', 'RecentContentDirs', 'RecentScenes',
+ 'ReconstructionFilter', 'RecordMaxAngles', 'RecordMinAngles', 'RecordPivotRotation',
+ 'RecordRestPosition', 'Redraw', 'RedrawNow', 'Refresh', 'RefreshNow', 'RegionPosition',
+ 'RemoveEnvelope', 'RemoveFromSelection', 'RemoveServer', 'Rename', 'RenderFrame',
+ 'RenderOptions', 'RenderScene', 'RenderSelected', 'RenderThreads',
+ 'ReplaceObjectLayer', 'ReplaceWithNull', 'ReplaceWithObject', 'Reset',
+ 'ResolutionMultiplier', 'RestLengthTool', 'RightView', 'RotatePivotTool',
+ 'RotateTool', 'Rotation',
+ 'SaveAllObjects', 'SaveCommandList', 'SaveCommandMessages',
+ 'SaveEndomorph', 'SaveLight', 'SaveLWSC1', 'SaveMotion', 'SaveObject', 'SaveObjectCopy',
+ 'SavePreview', 'SaveScene', 'SaveSceneAs', 'SaveSceneCopy', 'SaveTransformed',
+ 'SaveViewLayout', 'Scale', 'Scene_SetWindowPos', 'Scene_SetWindowSize',
+ 'SceneEditor', 'SchematicPosition', 'SchematicView', 'SelectAllBones',
+ 'SelectAllCameras', 'SelectAllLights', 'SelectAllObjects', 'SelectByName',
+ 'SelectChild', 'SelectItem', 'SelectParent', 'SelfShadow', 'ShadowColor',
+ 'ShadowExclusion', 'ShadowMapAngle', 'ShadowMapFitCone', 'ShadowMapFuzziness',
+ 'ShadowMapSize', 'ShadowType', 'ShowCages', 'ShowFieldChart', 'ShowHandles',
+ 'ShowIKChains', 'ShowMotionPaths', 'ShowSafeAreas', 'ShowTargetLines',
+ 'ShrinkEdgesWithDistance', 'SingleView', 'SizeTool', 'SkelegonsToBones', 'SkyColor',
+ 'Spotlight', 'SquashTool', 'Statistics', 'StatusMsg', 'Stereoscopic', 'StretchTool',
+ 'SubdivisionOrder', 'SubPatchLevel', 'SurfaceEditor', 'Synchronize',
+ 'TargetItem', 'TopView',
+ 'UnaffectedByFog', 'UnaffectedByIK', 'Undo', 'UnseenByAlphaChannel', 'UnseenByCamera',
+ 'UnseenByRays', 'UseGlobalResolution', 'UseGlobalBlur', 'UseGlobalMask',
+ 'UseMorphedPositions',
+ 'ViewLayout', 'VIPER', 'VolumetricLighting',
+ 'VolumetricLightingOptions', 'VolumetricRadiosity', 'Volumetrics',
+ 'WorldCoordinateSystem',
+ 'XYView', 'XZView',
+ 'ZenithColor', 'ZoomFactor', 'ZoomIn', 'ZoomInX2', 'ZoomOut', 'ZoomOutX2', 'ZYView',
+ 'Camera', 'Channel', 'ChannelGroup', 'Envelope', 'File', 'Glyph', 'Icon', 'Image',
+ 'Light', 'Mesh', 'Scene', 'Surface', 'VMap'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '=', '<', '>', '+', '-', '*', '/', '!', '%', '&', '@'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #FF6820; font-weight: bold;', //LS_COMMANDS
+ 3 => 'color: #007F7F; font-weight: bold;', //LS_MEMBERS
+ 4 => 'color: #800080; font-weight: bold;', //LS_METHODS
+ 5 => 'color: #51BD95; font-weight: bold;', //LS_MODELER
+ 6 => 'color: #416F85; font-weight: bold;', //LS_GENERAL
+ 7 => 'color: #C92929; font-weight: bold;' //LS_COMMANDS (cont)
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #7F7F7F;',
+ 'MULTI' => 'color: #7F7F7F;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #0040A0;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #00C800;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #6953AC;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #0040A0;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'ESCAPE_CHAR' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 3 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\.)'
+ ),
+ 4 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\.)'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/lsl2.php b/platform/www/vendor/geshi/geshi/src/geshi/lsl2.php
new file mode 100644
index 0000000..94f4754
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/lsl2.php
@@ -0,0 +1,1276 @@
+<?php
+/*************************************************************************************
+ * lsl2.php
+ * --------
+ * Author: William Fry (william.fry@nyu.edu)
+ * Copyright: (c) 2009 William Fry
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/02/04
+ *
+ * Linden Scripting Language (LSL2) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009-02-05 (1.0.0)
+ * - First Release
+ * 2013-01-01
+ * - Modified by Sei Lisa for compatibility with the geshi.py output module
+ * which is part of the LSL2 Derived Files Generator, available at:
+ * http://code.google.com/p/lsl-keywords
+ * 2013-07-11
+ * - Modified by Sei Lisa to fix symbols and to add multiline comment support
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+// Generated by LSL2 Derived Files Generator. Database version: 0.0.20140116001; output module version: 0.0.20130817000
+
+$language_data = array(
+ 'LANG_NAME' => 'LSL2',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array( // flow control
+ 'do',
+ 'else',
+ 'for',
+ 'if',
+ 'jump',
+ 'return',
+ 'state',
+ 'while',
+ ),
+ 2 => array( // manifest constants
+ 'ACTIVE',
+ 'AGENT',
+ 'AGENT_ALWAYS_RUN',
+ 'AGENT_ATTACHMENTS',
+ 'AGENT_AUTOPILOT',
+ 'AGENT_AWAY',
+ 'AGENT_BUSY',
+ 'AGENT_BY_LEGACY_NAME',
+ 'AGENT_BY_USERNAME',
+ 'AGENT_CROUCHING',
+ 'AGENT_FLYING',
+ 'AGENT_IN_AIR',
+ 'AGENT_LIST_PARCEL',
+ 'AGENT_LIST_PARCEL_OWNER',
+ 'AGENT_LIST_REGION',
+ 'AGENT_MOUSELOOK',
+ 'AGENT_ON_OBJECT',
+ 'AGENT_SCRIPTED',
+ 'AGENT_SITTING',
+ 'AGENT_TYPING',
+ 'AGENT_WALKING',
+ 'ALL_SIDES',
+ 'ANIM_ON',
+ 'ATTACH_AVATAR_CENTER',
+ 'ATTACH_BACK',
+ 'ATTACH_BELLY',
+ 'ATTACH_CHEST',
+ 'ATTACH_CHIN',
+ 'ATTACH_HEAD',
+ 'ATTACH_HUD_BOTTOM',
+ 'ATTACH_HUD_BOTTOM_LEFT',
+ 'ATTACH_HUD_BOTTOM_RIGHT',
+ 'ATTACH_HUD_CENTER_1',
+ 'ATTACH_HUD_CENTER_2',
+ 'ATTACH_HUD_TOP_CENTER',
+ 'ATTACH_HUD_TOP_LEFT',
+ 'ATTACH_HUD_TOP_RIGHT',
+ 'ATTACH_LEAR',
+ 'ATTACH_LEFT_PEC',
+ 'ATTACH_LEYE',
+ 'ATTACH_LFOOT',
+ 'ATTACH_LHAND',
+ 'ATTACH_LHIP',
+ 'ATTACH_LLARM',
+ 'ATTACH_LLLEG',
+ 'ATTACH_LSHOULDER',
+ 'ATTACH_LUARM',
+ 'ATTACH_LULEG',
+ 'ATTACH_MOUTH',
+ 'ATTACH_NECK',
+ 'ATTACH_NOSE',
+ 'ATTACH_PELVIS',
+ 'ATTACH_REAR',
+ 'ATTACH_REYE',
+ 'ATTACH_RFOOT',
+ 'ATTACH_RHAND',
+ 'ATTACH_RHIP',
+ 'ATTACH_RIGHT_PEC',
+ 'ATTACH_RLARM',
+ 'ATTACH_RLLEG',
+ 'ATTACH_RSHOULDER',
+ 'ATTACH_RUARM',
+ 'ATTACH_RULEG',
+ 'AVOID_CHARACTERS',
+ 'AVOID_DYNAMIC_OBSTACLES',
+ 'AVOID_NONE',
+ 'CAMERA_ACTIVE',
+ 'CAMERA_BEHINDNESS_ANGLE',
+ 'CAMERA_BEHINDNESS_LAG',
+ 'CAMERA_DISTANCE',
+ 'CAMERA_FOCUS',
+ 'CAMERA_FOCUS_LAG',
+ 'CAMERA_FOCUS_LOCKED',
+ 'CAMERA_FOCUS_OFFSET',
+ 'CAMERA_FOCUS_THRESHOLD',
+ 'CAMERA_PITCH',
+ 'CAMERA_POSITION',
+ 'CAMERA_POSITION_LAG',
+ 'CAMERA_POSITION_LOCKED',
+ 'CAMERA_POSITION_THRESHOLD',
+ 'CHANGED_ALLOWED_DROP',
+ 'CHANGED_COLOR',
+ 'CHANGED_INVENTORY',
+ 'CHANGED_LINK',
+ 'CHANGED_MEDIA',
+ 'CHANGED_OWNER',
+ 'CHANGED_REGION',
+ 'CHANGED_REGION_START',
+ 'CHANGED_SCALE',
+ 'CHANGED_SHAPE',
+ 'CHANGED_TELEPORT',
+ 'CHANGED_TEXTURE',
+ 'CHARACTER_ACCOUNT_FOR_SKIPPED_FRAMES',
+ 'CHARACTER_AVOIDANCE_MODE',
+ 'CHARACTER_CMD_JUMP',
+ 'CHARACTER_CMD_SMOOTH_STOP',
+ 'CHARACTER_CMD_STOP',
+ 'CHARACTER_DESIRED_SPEED',
+ 'CHARACTER_DESIRED_TURN_SPEED',
+ 'CHARACTER_LENGTH',
+ 'CHARACTER_MAX_ACCEL',
+ 'CHARACTER_MAX_DECEL',
+ 'CHARACTER_MAX_SPEED',
+ 'CHARACTER_MAX_TURN_RADIUS',
+ 'CHARACTER_ORIENTATION',
+ 'CHARACTER_RADIUS',
+ 'CHARACTER_STAY_WITHIN_PARCEL',
+ 'CHARACTER_TYPE',
+ 'CHARACTER_TYPE_A',
+ 'CHARACTER_TYPE_B',
+ 'CHARACTER_TYPE_C',
+ 'CHARACTER_TYPE_D',
+ 'CHARACTER_TYPE_NONE',
+ 'CLICK_ACTION_BUY',
+ 'CLICK_ACTION_NONE',
+ 'CLICK_ACTION_OPEN',
+ 'CLICK_ACTION_OPEN_MEDIA',
+ 'CLICK_ACTION_PAY',
+ 'CLICK_ACTION_PLAY',
+ 'CLICK_ACTION_SIT',
+ 'CLICK_ACTION_TOUCH',
+ 'CONTENT_TYPE_ATOM',
+ 'CONTENT_TYPE_FORM',
+ 'CONTENT_TYPE_HTML',
+ 'CONTENT_TYPE_JSON',
+ 'CONTENT_TYPE_LLSD',
+ 'CONTENT_TYPE_RSS',
+ 'CONTENT_TYPE_TEXT',
+ 'CONTENT_TYPE_XHTML',
+ 'CONTENT_TYPE_XML',
+ 'CONTROL_BACK',
+ 'CONTROL_DOWN',
+ 'CONTROL_FWD',
+ 'CONTROL_LBUTTON',
+ 'CONTROL_LEFT',
+ 'CONTROL_ML_LBUTTON',
+ 'CONTROL_RIGHT',
+ 'CONTROL_ROT_LEFT',
+ 'CONTROL_ROT_RIGHT',
+ 'CONTROL_UP',
+ 'DATA_BORN',
+ 'DATA_NAME',
+ 'DATA_ONLINE',
+ 'DATA_PAYINFO',
+ 'DATA_SIM_POS',
+ 'DATA_SIM_RATING',
+ 'DATA_SIM_STATUS',
+ 'DEBUG_CHANNEL',
+ 'DEG_TO_RAD',
+ 'DENSITY',
+ 'EOF',
+ 'ERR_GENERIC',
+ 'ERR_MALFORMED_PARAMS',
+ 'ERR_PARCEL_PERMISSIONS',
+ 'ERR_RUNTIME_PERMISSIONS',
+ 'ERR_THROTTLED',
+ 'ESTATE_ACCESS_ALLOWED_AGENT_ADD',
+ 'ESTATE_ACCESS_ALLOWED_AGENT_REMOVE',
+ 'ESTATE_ACCESS_ALLOWED_GROUP_ADD',
+ 'ESTATE_ACCESS_ALLOWED_GROUP_REMOVE',
+ 'ESTATE_ACCESS_BANNED_AGENT_ADD',
+ 'ESTATE_ACCESS_BANNED_AGENT_REMOVE',
+ 'FALSE',
+ 'FORCE_DIRECT_PATH',
+ 'FRICTION',
+ 'GCNP_RADIUS',
+ 'GCNP_STATIC',
+ 'GRAVITY_MULTIPLIER',
+ 'HORIZONTAL',
+ 'HTTP_BODY_MAXLENGTH',
+ 'HTTP_BODY_TRUNCATED',
+ 'HTTP_CUSTOM_HEADER',
+ 'HTTP_METHOD',
+ 'HTTP_MIMETYPE',
+ 'HTTP_PRAGMA_NO_CACHE',
+ 'HTTP_VERBOSE_THROTTLE',
+ 'HTTP_VERIFY_CERT',
+ 'INVENTORY_ALL',
+ 'INVENTORY_ANIMATION',
+ 'INVENTORY_BODYPART',
+ 'INVENTORY_CLOTHING',
+ 'INVENTORY_GESTURE',
+ 'INVENTORY_LANDMARK',
+ 'INVENTORY_NONE',
+ 'INVENTORY_NOTECARD',
+ 'INVENTORY_OBJECT',
+ 'INVENTORY_SCRIPT',
+ 'INVENTORY_SOUND',
+ 'INVENTORY_TEXTURE',
+ 'JSON_APPEND',
+ 'JSON_ARRAY',
+ 'JSON_DELETE',
+ 'JSON_FALSE',
+ 'JSON_INVALID',
+ 'JSON_NULL',
+ 'JSON_NUMBER',
+ 'JSON_OBJECT',
+ 'JSON_STRING',
+ 'JSON_TRUE',
+ 'KFM_CMD_PAUSE',
+ 'KFM_CMD_PLAY',
+ 'KFM_CMD_SET_MODE',
+ 'KFM_CMD_STOP',
+ 'KFM_COMMAND',
+ 'KFM_DATA',
+ 'KFM_FORWARD',
+ 'KFM_LOOP',
+ 'KFM_MODE',
+ 'KFM_PING_PONG',
+ 'KFM_REVERSE',
+ 'KFM_ROTATION',
+ 'KFM_TRANSLATION',
+ 'LAND_LARGE_BRUSH',
+ 'LAND_LEVEL',
+ 'LAND_LOWER',
+ 'LAND_MEDIUM_BRUSH',
+ 'LAND_NOISE',
+ 'LAND_RAISE',
+ 'LAND_REVERT',
+ 'LAND_SMALL_BRUSH',
+ 'LAND_SMOOTH',
+ 'LINK_ALL_CHILDREN',
+ 'LINK_ALL_OTHERS',
+ 'LINK_ROOT',
+ 'LINK_SET',
+ 'LINK_THIS',
+ 'LIST_STAT_GEOMETRIC_MEAN',
+ 'LIST_STAT_MAX',
+ 'LIST_STAT_MEAN',
+ 'LIST_STAT_MEDIAN',
+ 'LIST_STAT_MIN',
+ 'LIST_STAT_NUM_COUNT',
+ 'LIST_STAT_RANGE',
+ 'LIST_STAT_STD_DEV',
+ 'LIST_STAT_SUM',
+ 'LIST_STAT_SUM_SQUARES',
+ 'LOOP',
+ 'MASK_BASE',
+ 'MASK_EVERYONE',
+ 'MASK_GROUP',
+ 'MASK_NEXT',
+ 'MASK_OWNER',
+ 'NULL_KEY',
+ 'OBJECT_ATTACHED_POINT',
+ 'OBJECT_CHARACTER_TIME',
+ 'OBJECT_CREATOR',
+ 'OBJECT_DESC',
+ 'OBJECT_GROUP',
+ 'OBJECT_NAME',
+ 'OBJECT_OWNER',
+ 'OBJECT_PATHFINDING_TYPE',
+ 'OBJECT_PHANTOM',
+ 'OBJECT_PHYSICS',
+ 'OBJECT_PHYSICS_COST',
+ 'OBJECT_POS',
+ 'OBJECT_PRIM_EQUIVALENCE',
+ 'OBJECT_RENDER_WEIGHT',
+ 'OBJECT_RETURN_PARCEL',
+ 'OBJECT_RETURN_PARCEL_OWNER',
+ 'OBJECT_RETURN_REGION',
+ 'OBJECT_ROOT',
+ 'OBJECT_ROT',
+ 'OBJECT_RUNNING_SCRIPT_COUNT',
+ 'OBJECT_SCRIPT_MEMORY',
+ 'OBJECT_SCRIPT_TIME',
+ 'OBJECT_SERVER_COST',
+ 'OBJECT_STREAMING_COST',
+ 'OBJECT_TEMP_ON_REZ',
+ 'OBJECT_TOTAL_SCRIPT_COUNT',
+ 'OBJECT_UNKNOWN_DETAIL',
+ 'OBJECT_VELOCITY',
+ 'OPT_AVATAR',
+ 'OPT_CHARACTER',
+ 'OPT_EXCLUSION_VOLUME',
+ 'OPT_LEGACY_LINKSET',
+ 'OPT_MATERIAL_VOLUME',
+ 'OPT_OTHER',
+ 'OPT_STATIC_OBSTACLE',
+ 'OPT_WALKABLE',
+ 'PARCEL_COUNT_GROUP',
+ 'PARCEL_COUNT_OTHER',
+ 'PARCEL_COUNT_OWNER',
+ 'PARCEL_COUNT_SELECTED',
+ 'PARCEL_COUNT_TEMP',
+ 'PARCEL_COUNT_TOTAL',
+ 'PARCEL_DETAILS_AREA',
+ 'PARCEL_DETAILS_DESC',
+ 'PARCEL_DETAILS_GROUP',
+ 'PARCEL_DETAILS_ID',
+ 'PARCEL_DETAILS_NAME',
+ 'PARCEL_DETAILS_OWNER',
+ 'PARCEL_DETAILS_SEE_AVATARS',
+ 'PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY',
+ 'PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS',
+ 'PARCEL_FLAG_ALLOW_CREATE_OBJECTS',
+ 'PARCEL_FLAG_ALLOW_DAMAGE',
+ 'PARCEL_FLAG_ALLOW_FLY',
+ 'PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY',
+ 'PARCEL_FLAG_ALLOW_GROUP_SCRIPTS',
+ 'PARCEL_FLAG_ALLOW_LANDMARK',
+ 'PARCEL_FLAG_ALLOW_SCRIPTS',
+ 'PARCEL_FLAG_ALLOW_TERRAFORM',
+ 'PARCEL_FLAG_LOCAL_SOUND_ONLY',
+ 'PARCEL_FLAG_RESTRICT_PUSHOBJECT',
+ 'PARCEL_FLAG_USE_ACCESS_GROUP',
+ 'PARCEL_FLAG_USE_ACCESS_LIST',
+ 'PARCEL_FLAG_USE_BAN_LIST',
+ 'PARCEL_FLAG_USE_LAND_PASS_LIST',
+ 'PARCEL_MEDIA_COMMAND_AGENT',
+ 'PARCEL_MEDIA_COMMAND_AUTO_ALIGN',
+ 'PARCEL_MEDIA_COMMAND_DESC',
+ 'PARCEL_MEDIA_COMMAND_LOOP',
+ 'PARCEL_MEDIA_COMMAND_LOOP_SET',
+ 'PARCEL_MEDIA_COMMAND_PAUSE',
+ 'PARCEL_MEDIA_COMMAND_PLAY',
+ 'PARCEL_MEDIA_COMMAND_SIZE',
+ 'PARCEL_MEDIA_COMMAND_STOP',
+ 'PARCEL_MEDIA_COMMAND_TEXTURE',
+ 'PARCEL_MEDIA_COMMAND_TIME',
+ 'PARCEL_MEDIA_COMMAND_TYPE',
+ 'PARCEL_MEDIA_COMMAND_UNLOAD',
+ 'PARCEL_MEDIA_COMMAND_URL',
+ 'PASSIVE',
+ 'PATROL_PAUSE_AT_WAYPOINTS',
+ 'PAYMENT_INFO_ON_FILE',
+ 'PAYMENT_INFO_USED',
+ 'PAY_DEFAULT',
+ 'PAY_HIDE',
+ 'PERMISSION_ATTACH',
+ 'PERMISSION_CHANGE_LINKS',
+ 'PERMISSION_CONTROL_CAMERA',
+ 'PERMISSION_DEBIT',
+ 'PERMISSION_OVERRIDE_ANIMATIONS',
+ 'PERMISSION_RETURN_OBJECTS',
+ 'PERMISSION_SILENT_ESTATE_MANAGEMENT',
+ 'PERMISSION_TAKE_CONTROLS',
+ 'PERMISSION_TELEPORT',
+ 'PERMISSION_TRACK_CAMERA',
+ 'PERMISSION_TRIGGER_ANIMATION',
+ 'PERM_ALL',
+ 'PERM_COPY',
+ 'PERM_MODIFY',
+ 'PERM_MOVE',
+ 'PERM_TRANSFER',
+ 'PI',
+ 'PING_PONG',
+ 'PI_BY_TWO',
+ 'PRIM_BUMP_BARK',
+ 'PRIM_BUMP_BLOBS',
+ 'PRIM_BUMP_BRICKS',
+ 'PRIM_BUMP_BRIGHT',
+ 'PRIM_BUMP_CHECKER',
+ 'PRIM_BUMP_CONCRETE',
+ 'PRIM_BUMP_DARK',
+ 'PRIM_BUMP_DISKS',
+ 'PRIM_BUMP_GRAVEL',
+ 'PRIM_BUMP_LARGETILE',
+ 'PRIM_BUMP_NONE',
+ 'PRIM_BUMP_SHINY',
+ 'PRIM_BUMP_SIDING',
+ 'PRIM_BUMP_STONE',
+ 'PRIM_BUMP_STUCCO',
+ 'PRIM_BUMP_SUCTION',
+ 'PRIM_BUMP_TILE',
+ 'PRIM_BUMP_WEAVE',
+ 'PRIM_BUMP_WOOD',
+ 'PRIM_COLOR',
+ 'PRIM_DESC',
+ 'PRIM_FLEXIBLE',
+ 'PRIM_FULLBRIGHT',
+ 'PRIM_GLOW',
+ 'PRIM_HOLE_CIRCLE',
+ 'PRIM_HOLE_DEFAULT',
+ 'PRIM_HOLE_SQUARE',
+ 'PRIM_HOLE_TRIANGLE',
+ 'PRIM_LINK_TARGET',
+ 'PRIM_MATERIAL',
+ 'PRIM_MATERIAL_FLESH',
+ 'PRIM_MATERIAL_GLASS',
+ 'PRIM_MATERIAL_METAL',
+ 'PRIM_MATERIAL_PLASTIC',
+ 'PRIM_MATERIAL_RUBBER',
+ 'PRIM_MATERIAL_STONE',
+ 'PRIM_MATERIAL_WOOD',
+ 'PRIM_MEDIA_ALT_IMAGE_ENABLE',
+ 'PRIM_MEDIA_AUTO_LOOP',
+ 'PRIM_MEDIA_AUTO_PLAY',
+ 'PRIM_MEDIA_AUTO_SCALE',
+ 'PRIM_MEDIA_AUTO_ZOOM',
+ 'PRIM_MEDIA_CONTROLS',
+ 'PRIM_MEDIA_CONTROLS_MINI',
+ 'PRIM_MEDIA_CONTROLS_STANDARD',
+ 'PRIM_MEDIA_CURRENT_URL',
+ 'PRIM_MEDIA_FIRST_CLICK_INTERACT',
+ 'PRIM_MEDIA_HEIGHT_PIXELS',
+ 'PRIM_MEDIA_HOME_URL',
+ 'PRIM_MEDIA_MAX_HEIGHT_PIXELS',
+ 'PRIM_MEDIA_MAX_URL_LENGTH',
+ 'PRIM_MEDIA_MAX_WHITELIST_COUNT',
+ 'PRIM_MEDIA_MAX_WHITELIST_SIZE',
+ 'PRIM_MEDIA_MAX_WIDTH_PIXELS',
+ 'PRIM_MEDIA_PARAM_MAX',
+ 'PRIM_MEDIA_PERMS_CONTROL',
+ 'PRIM_MEDIA_PERMS_INTERACT',
+ 'PRIM_MEDIA_PERM_ANYONE',
+ 'PRIM_MEDIA_PERM_GROUP',
+ 'PRIM_MEDIA_PERM_NONE',
+ 'PRIM_MEDIA_PERM_OWNER',
+ 'PRIM_MEDIA_WHITELIST',
+ 'PRIM_MEDIA_WHITELIST_ENABLE',
+ 'PRIM_MEDIA_WIDTH_PIXELS',
+ 'PRIM_NAME',
+ 'PRIM_OMEGA',
+ 'PRIM_PHANTOM',
+ 'PRIM_PHYSICS',
+ 'PRIM_PHYSICS_SHAPE_CONVEX',
+ 'PRIM_PHYSICS_SHAPE_NONE',
+ 'PRIM_PHYSICS_SHAPE_PRIM',
+ 'PRIM_PHYSICS_SHAPE_TYPE',
+ 'PRIM_POINT_LIGHT',
+ 'PRIM_POSITION',
+ 'PRIM_POS_LOCAL',
+ 'PRIM_ROTATION',
+ 'PRIM_ROT_LOCAL',
+ 'PRIM_SCULPT_FLAG_INVERT',
+ 'PRIM_SCULPT_FLAG_MIRROR',
+ 'PRIM_SCULPT_TYPE_CYLINDER',
+ 'PRIM_SCULPT_TYPE_MASK',
+ 'PRIM_SCULPT_TYPE_PLANE',
+ 'PRIM_SCULPT_TYPE_SPHERE',
+ 'PRIM_SCULPT_TYPE_TORUS',
+ 'PRIM_SHINY_HIGH',
+ 'PRIM_SHINY_LOW',
+ 'PRIM_SHINY_MEDIUM',
+ 'PRIM_SHINY_NONE',
+ 'PRIM_SIZE',
+ 'PRIM_SLICE',
+ 'PRIM_TEMP_ON_REZ',
+ 'PRIM_TEXGEN',
+ 'PRIM_TEXGEN_DEFAULT',
+ 'PRIM_TEXGEN_PLANAR',
+ 'PRIM_TEXT',
+ 'PRIM_TEXTURE',
+ 'PRIM_TYPE',
+ 'PRIM_TYPE_BOX',
+ 'PRIM_TYPE_CYLINDER',
+ 'PRIM_TYPE_PRISM',
+ 'PRIM_TYPE_RING',
+ 'PRIM_TYPE_SCULPT',
+ 'PRIM_TYPE_SPHERE',
+ 'PRIM_TYPE_TORUS',
+ 'PRIM_TYPE_TUBE',
+ 'PROFILE_NONE',
+ 'PROFILE_SCRIPT_MEMORY',
+ 'PSYS_PART_BF_DEST_COLOR',
+ 'PSYS_PART_BF_ONE',
+ 'PSYS_PART_BF_ONE_MINUS_DEST_COLOR',
+ 'PSYS_PART_BF_ONE_MINUS_SOURCE_ALPHA',
+ 'PSYS_PART_BF_ONE_MINUS_SOURCE_COLOR',
+ 'PSYS_PART_BF_SOURCE_ALPHA',
+ 'PSYS_PART_BF_SOURCE_COLOR',
+ 'PSYS_PART_BF_ZERO',
+ 'PSYS_PART_BLEND_FUNC_DEST',
+ 'PSYS_PART_BLEND_FUNC_SOURCE',
+ 'PSYS_PART_BOUNCE_MASK',
+ 'PSYS_PART_EMISSIVE_MASK',
+ 'PSYS_PART_END_ALPHA',
+ 'PSYS_PART_END_COLOR',
+ 'PSYS_PART_END_GLOW',
+ 'PSYS_PART_END_SCALE',
+ 'PSYS_PART_FLAGS',
+ 'PSYS_PART_FOLLOW_SRC_MASK',
+ 'PSYS_PART_FOLLOW_VELOCITY_MASK',
+ 'PSYS_PART_INTERP_COLOR_MASK',
+ 'PSYS_PART_INTERP_SCALE_MASK',
+ 'PSYS_PART_MAX_AGE',
+ 'PSYS_PART_RIBBON_MASK',
+ 'PSYS_PART_START_ALPHA',
+ 'PSYS_PART_START_COLOR',
+ 'PSYS_PART_START_GLOW',
+ 'PSYS_PART_START_SCALE',
+ 'PSYS_PART_TARGET_LINEAR_MASK',
+ 'PSYS_PART_TARGET_POS_MASK',
+ 'PSYS_PART_WIND_MASK',
+ 'PSYS_SRC_ACCEL',
+ 'PSYS_SRC_ANGLE_BEGIN',
+ 'PSYS_SRC_ANGLE_END',
+ 'PSYS_SRC_BURST_PART_COUNT',
+ 'PSYS_SRC_BURST_RADIUS',
+ 'PSYS_SRC_BURST_RATE',
+ 'PSYS_SRC_BURST_SPEED_MAX',
+ 'PSYS_SRC_BURST_SPEED_MIN',
+ 'PSYS_SRC_MAX_AGE',
+ 'PSYS_SRC_OMEGA',
+ 'PSYS_SRC_PATTERN',
+ 'PSYS_SRC_PATTERN_ANGLE',
+ 'PSYS_SRC_PATTERN_ANGLE_CONE',
+ 'PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY',
+ 'PSYS_SRC_PATTERN_DROP',
+ 'PSYS_SRC_PATTERN_EXPLODE',
+ 'PSYS_SRC_TARGET_KEY',
+ 'PSYS_SRC_TEXTURE',
+ 'PUBLIC_CHANNEL',
+ 'PURSUIT_FUZZ_FACTOR',
+ 'PURSUIT_GOAL_TOLERANCE',
+ 'PURSUIT_INTERCEPT',
+ 'PURSUIT_OFFSET',
+ 'PU_EVADE_HIDDEN',
+ 'PU_EVADE_SPOTTED',
+ 'PU_FAILURE_DYNAMIC_PATHFINDING_DISABLED',
+ 'PU_FAILURE_INVALID_GOAL',
+ 'PU_FAILURE_INVALID_START',
+ 'PU_FAILURE_NO_NAVMESH',
+ 'PU_FAILURE_NO_VALID_DESTINATION',
+ 'PU_FAILURE_OTHER',
+ 'PU_FAILURE_PARCEL_UNREACHABLE',
+ 'PU_FAILURE_TARGET_GONE',
+ 'PU_FAILURE_UNREACHABLE',
+ 'PU_GOAL_REACHED',
+ 'PU_SLOWDOWN_DISTANCE_REACHED',
+ 'RAD_TO_DEG',
+ 'RCERR_CAST_TIME_EXCEEDED',
+ 'RCERR_SIM_PERF_LOW',
+ 'RCERR_UNKNOWN',
+ 'RC_DATA_FLAGS',
+ 'RC_DETECT_PHANTOM',
+ 'RC_GET_LINK_NUM',
+ 'RC_GET_NORMAL',
+ 'RC_GET_ROOT_KEY',
+ 'RC_MAX_HITS',
+ 'RC_REJECT_AGENTS',
+ 'RC_REJECT_LAND',
+ 'RC_REJECT_NONPHYSICAL',
+ 'RC_REJECT_PHYSICAL',
+ 'RC_REJECT_TYPES',
+ 'REGION_FLAG_ALLOW_DAMAGE',
+ 'REGION_FLAG_ALLOW_DIRECT_TELEPORT',
+ 'REGION_FLAG_BLOCK_FLY',
+ 'REGION_FLAG_BLOCK_TERRAFORM',
+ 'REGION_FLAG_DISABLE_COLLISIONS',
+ 'REGION_FLAG_DISABLE_PHYSICS',
+ 'REGION_FLAG_FIXED_SUN',
+ 'REGION_FLAG_RESTRICT_PUSHOBJECT',
+ 'REGION_FLAG_SANDBOX',
+ 'REMOTE_DATA_CHANNEL',
+ 'REMOTE_DATA_REPLY',
+ 'REMOTE_DATA_REQUEST',
+ 'REQUIRE_LINE_OF_SIGHT',
+ 'RESTITUTION',
+ 'REVERSE',
+ 'ROTATE',
+ 'SCALE',
+ 'SCRIPTED',
+ 'SIM_STAT_PCT_CHARS_STEPPED',
+ 'SMOOTH',
+ 'SQRT2',
+ 'STATUS_BLOCK_GRAB',
+ 'STATUS_BLOCK_GRAB_OBJECT',
+ 'STATUS_BOUNDS_ERROR',
+ 'STATUS_CAST_SHADOWS',
+ 'STATUS_DIE_AT_EDGE',
+ 'STATUS_INTERNAL_ERROR',
+ 'STATUS_MALFORMED_PARAMS',
+ 'STATUS_NOT_FOUND',
+ 'STATUS_NOT_SUPPORTED',
+ 'STATUS_OK',
+ 'STATUS_PHANTOM',
+ 'STATUS_PHYSICS',
+ 'STATUS_RETURN_AT_EDGE',
+ 'STATUS_ROTATE_X',
+ 'STATUS_ROTATE_Y',
+ 'STATUS_ROTATE_Z',
+ 'STATUS_SANDBOX',
+ 'STATUS_TYPE_MISMATCH',
+ 'STATUS_WHITELIST_FAILED',
+ 'STRING_TRIM',
+ 'STRING_TRIM_HEAD',
+ 'STRING_TRIM_TAIL',
+ 'TEXTURE_BLANK',
+ 'TEXTURE_DEFAULT',
+ 'TEXTURE_MEDIA',
+ 'TEXTURE_PLYWOOD',
+ 'TEXTURE_TRANSPARENT',
+ 'TOUCH_INVALID_FACE',
+ 'TOUCH_INVALID_TEXCOORD',
+ 'TOUCH_INVALID_VECTOR',
+ 'TRAVERSAL_TYPE',
+ 'TRAVERSAL_TYPE_FAST',
+ 'TRAVERSAL_TYPE_NONE',
+ 'TRAVERSAL_TYPE_SLOW',
+ 'TRUE',
+ 'TWO_PI',
+ 'TYPE_FLOAT',
+ 'TYPE_INTEGER',
+ 'TYPE_INVALID',
+ 'TYPE_KEY',
+ 'TYPE_ROTATION',
+ 'TYPE_STRING',
+ 'TYPE_VECTOR',
+ 'URL_REQUEST_DENIED',
+ 'URL_REQUEST_GRANTED',
+ 'VEHICLE_ANGULAR_DEFLECTION_EFFICIENCY',
+ 'VEHICLE_ANGULAR_DEFLECTION_TIMESCALE',
+ 'VEHICLE_ANGULAR_FRICTION_TIMESCALE',
+ 'VEHICLE_ANGULAR_MOTOR_DECAY_TIMESCALE',
+ 'VEHICLE_ANGULAR_MOTOR_DIRECTION',
+ 'VEHICLE_ANGULAR_MOTOR_TIMESCALE',
+ 'VEHICLE_BANKING_EFFICIENCY',
+ 'VEHICLE_BANKING_MIX',
+ 'VEHICLE_BANKING_TIMESCALE',
+ 'VEHICLE_BUOYANCY',
+ 'VEHICLE_FLAG_CAMERA_DECOUPLED',
+ 'VEHICLE_FLAG_HOVER_GLOBAL_HEIGHT',
+ 'VEHICLE_FLAG_HOVER_TERRAIN_ONLY',
+ 'VEHICLE_FLAG_HOVER_UP_ONLY',
+ 'VEHICLE_FLAG_HOVER_WATER_ONLY',
+ 'VEHICLE_FLAG_LIMIT_MOTOR_UP',
+ 'VEHICLE_FLAG_LIMIT_ROLL_ONLY',
+ 'VEHICLE_FLAG_MOUSELOOK_BANK',
+ 'VEHICLE_FLAG_MOUSELOOK_STEER',
+ 'VEHICLE_FLAG_NO_DEFLECTION_UP',
+ 'VEHICLE_HOVER_EFFICIENCY',
+ 'VEHICLE_HOVER_HEIGHT',
+ 'VEHICLE_HOVER_TIMESCALE',
+ 'VEHICLE_LINEAR_DEFLECTION_EFFICIENCY',
+ 'VEHICLE_LINEAR_DEFLECTION_TIMESCALE',
+ 'VEHICLE_LINEAR_FRICTION_TIMESCALE',
+ 'VEHICLE_LINEAR_MOTOR_DECAY_TIMESCALE',
+ 'VEHICLE_LINEAR_MOTOR_DIRECTION',
+ 'VEHICLE_LINEAR_MOTOR_OFFSET',
+ 'VEHICLE_LINEAR_MOTOR_TIMESCALE',
+ 'VEHICLE_REFERENCE_FRAME',
+ 'VEHICLE_TYPE_AIRPLANE',
+ 'VEHICLE_TYPE_BALLOON',
+ 'VEHICLE_TYPE_BOAT',
+ 'VEHICLE_TYPE_CAR',
+ 'VEHICLE_TYPE_NONE',
+ 'VEHICLE_TYPE_SLED',
+ 'VEHICLE_VERTICAL_ATTRACTION_EFFICIENCY',
+ 'VEHICLE_VERTICAL_ATTRACTION_TIMESCALE',
+ 'VERTICAL',
+ 'WANDER_PAUSE_AT_WAYPOINTS',
+ 'ZERO_ROTATION',
+ 'ZERO_VECTOR',
+ ),
+ 3 => array( // handlers
+ 'at_rot_target',
+ 'at_target',
+ 'attach',
+ 'changed',
+ 'collision',
+ 'collision_end',
+ 'collision_start',
+ 'control',
+ 'dataserver',
+ 'email',
+ 'http_request',
+ 'http_response',
+ 'land_collision',
+ 'land_collision_end',
+ 'land_collision_start',
+ 'link_message',
+ 'listen',
+ 'money',
+ 'moving_end',
+ 'moving_start',
+ 'no_sensor',
+ 'not_at_rot_target',
+ 'not_at_target',
+ 'object_rez',
+ 'on_rez',
+ 'path_update',
+ 'remote_data',
+ 'run_time_permissions',
+ 'sensor',
+ 'state_entry',
+ 'state_exit',
+ 'timer',
+ 'touch',
+ 'touch_end',
+ 'touch_start',
+ 'transaction_result',
+ ),
+ 4 => array( // data types
+ 'float',
+ 'integer',
+ 'key',
+ 'list',
+ 'quaternion',
+ 'rotation',
+ 'string',
+ 'vector',
+ ),
+ 5 => array( // library
+ 'default',
+ 'llAbs',
+ 'llAcos',
+ 'llAddToLandBanList',
+ 'llAddToLandPassList',
+ 'llAdjustSoundVolume',
+ 'llAllowInventoryDrop',
+ 'llAngleBetween',
+ 'llApplyImpulse',
+ 'llApplyRotationalImpulse',
+ 'llAsin',
+ 'llAtan2',
+ 'llAttachToAvatar',
+ 'llAttachToAvatarTemp',
+ 'llAvatarOnLinkSitTarget',
+ 'llAvatarOnSitTarget',
+ 'llAxes2Rot',
+ 'llAxisAngle2Rot',
+ 'llBase64ToInteger',
+ 'llBase64ToString',
+ 'llBreakAllLinks',
+ 'llBreakLink',
+ 'llCastRay',
+ 'llCeil',
+ 'llClearCameraParams',
+ 'llClearLinkMedia',
+ 'llClearPrimMedia',
+ 'llCloseRemoteDataChannel',
+ 'llCollisionFilter',
+ 'llCollisionSound',
+ 'llCos',
+ 'llCreateCharacter',
+ 'llCreateLink',
+ 'llCSV2List',
+ 'llDeleteCharacter',
+ 'llDeleteSubList',
+ 'llDeleteSubString',
+ 'llDetachFromAvatar',
+ 'llDetectedGrab',
+ 'llDetectedGroup',
+ 'llDetectedKey',
+ 'llDetectedLinkNumber',
+ 'llDetectedName',
+ 'llDetectedOwner',
+ 'llDetectedPos',
+ 'llDetectedRot',
+ 'llDetectedTouchBinormal',
+ 'llDetectedTouchFace',
+ 'llDetectedTouchNormal',
+ 'llDetectedTouchPos',
+ 'llDetectedTouchST',
+ 'llDetectedTouchUV',
+ 'llDetectedType',
+ 'llDetectedVel',
+ 'llDialog',
+ 'llDie',
+ 'llDumpList2String',
+ 'llEdgeOfWorld',
+ 'llEjectFromLand',
+ 'llEmail',
+ 'llEscapeURL',
+ 'llEuler2Rot',
+ 'llEvade',
+ 'llExecCharacterCmd',
+ 'llFabs',
+ 'llFleeFrom',
+ 'llFloor',
+ 'llForceMouselook',
+ 'llFrand',
+ 'llGenerateKey',
+ 'llGetAccel',
+ 'llGetAgentInfo',
+ 'llGetAgentLanguage',
+ 'llGetAgentList',
+ 'llGetAgentSize',
+ 'llGetAlpha',
+ 'llGetAndResetTime',
+ 'llGetAnimation',
+ 'llGetAnimationList',
+ 'llGetAnimationOverride',
+ 'llGetAttached',
+ 'llGetBoundingBox',
+ 'llGetCameraPos',
+ 'llGetCameraRot',
+ 'llGetCenterOfMass',
+ 'llGetClosestNavPoint',
+ 'llGetColor',
+ 'llGetCreator',
+ 'llGetDate',
+ 'llGetDisplayName',
+ 'llGetEnergy',
+ 'llGetEnv',
+ 'llGetForce',
+ 'llGetFreeMemory',
+ 'llGetFreeURLs',
+ 'llGetGeometricCenter',
+ 'llGetGMTclock',
+ 'llGetHTTPHeader',
+ 'llGetInventoryCreator',
+ 'llGetInventoryKey',
+ 'llGetInventoryName',
+ 'llGetInventoryNumber',
+ 'llGetInventoryPermMask',
+ 'llGetInventoryType',
+ 'llGetKey',
+ 'llGetLandOwnerAt',
+ 'llGetLinkKey',
+ 'llGetLinkMedia',
+ 'llGetLinkName',
+ 'llGetLinkNumber',
+ 'llGetLinkNumberOfSides',
+ 'llGetLinkPrimitiveParams',
+ 'llGetListEntryType',
+ 'llGetListLength',
+ 'llGetLocalPos',
+ 'llGetLocalRot',
+ 'llGetMass',
+ 'llGetMassMKS',
+ 'llGetMaxScaleFactor',
+ 'llGetMemoryLimit',
+ 'llGetMinScaleFactor',
+ 'llGetNextEmail',
+ 'llGetNotecardLine',
+ 'llGetNumberOfNotecardLines',
+ 'llGetNumberOfPrims',
+ 'llGetNumberOfSides',
+ 'llGetObjectDesc',
+ 'llGetObjectDetails',
+ 'llGetObjectMass',
+ 'llGetObjectName',
+ 'llGetObjectPermMask',
+ 'llGetObjectPrimCount',
+ 'llGetOmega',
+ 'llGetOwner',
+ 'llGetOwnerKey',
+ 'llGetParcelDetails',
+ 'llGetParcelFlags',
+ 'llGetParcelMaxPrims',
+ 'llGetParcelMusicURL',
+ 'llGetParcelPrimCount',
+ 'llGetParcelPrimOwners',
+ 'llGetPermissions',
+ 'llGetPermissionsKey',
+ 'llGetPhysicsMaterial',
+ 'llGetPos',
+ 'llGetPrimitiveParams',
+ 'llGetPrimMediaParams',
+ 'llGetRegionAgentCount',
+ 'llGetRegionCorner',
+ 'llGetRegionFlags',
+ 'llGetRegionFPS',
+ 'llGetRegionName',
+ 'llGetRegionTimeDilation',
+ 'llGetRootPosition',
+ 'llGetRootRotation',
+ 'llGetRot',
+ 'llGetScale',
+ 'llGetScriptName',
+ 'llGetScriptState',
+ 'llGetSimStats',
+ 'llGetSimulatorHostname',
+ 'llGetSPMaxMemory',
+ 'llGetStartParameter',
+ 'llGetStaticPath',
+ 'llGetStatus',
+ 'llGetSubString',
+ 'llGetSunDirection',
+ 'llGetTexture',
+ 'llGetTextureOffset',
+ 'llGetTextureRot',
+ 'llGetTextureScale',
+ 'llGetTime',
+ 'llGetTimeOfDay',
+ 'llGetTimestamp',
+ 'llGetTorque',
+ 'llGetUnixTime',
+ 'llGetUsedMemory',
+ 'llGetUsername',
+ 'llGetVel',
+ 'llGetWallclock',
+ 'llGiveInventory',
+ 'llGiveInventoryList',
+ 'llGiveMoney',
+ 'llGround',
+ 'llGroundContour',
+ 'llGroundNormal',
+ 'llGroundRepel',
+ 'llGroundSlope',
+ 'llHTTPRequest',
+ 'llHTTPResponse',
+ 'llInsertString',
+ 'llInstantMessage',
+ 'llIntegerToBase64',
+ 'llJson2List',
+ 'llJsonGetValue',
+ 'llJsonSetValue',
+ 'llJsonValueType',
+ 'llKey2Name',
+ 'llLinkParticleSystem',
+ 'llLinkSitTarget',
+ 'llList2CSV',
+ 'llList2Float',
+ 'llList2Integer',
+ 'llList2Json',
+ 'llList2Key',
+ 'llList2List',
+ 'llList2ListStrided',
+ 'llList2Rot',
+ 'llList2String',
+ 'llList2Vector',
+ 'llListen',
+ 'llListenControl',
+ 'llListenRemove',
+ 'llListFindList',
+ 'llListInsertList',
+ 'llListRandomize',
+ 'llListReplaceList',
+ 'llListSort',
+ 'llListStatistics',
+ 'llLoadURL',
+ 'llLog',
+ 'llLog10',
+ 'llLookAt',
+ 'llLoopSound',
+ 'llLoopSoundMaster',
+ 'llLoopSoundSlave',
+ 'llManageEstateAccess',
+ 'llMapDestination',
+ 'llMD5String',
+ 'llMessageLinked',
+ 'llMinEventDelay',
+ 'llModifyLand',
+ 'llModPow',
+ 'llMoveToTarget',
+ 'llNavigateTo',
+ 'llOffsetTexture',
+ 'llOpenRemoteDataChannel',
+ 'llOverMyLand',
+ 'llOwnerSay',
+ 'llParcelMediaCommandList',
+ 'llParcelMediaQuery',
+ 'llParseString2List',
+ 'llParseStringKeepNulls',
+ 'llParticleSystem',
+ 'llPassCollisions',
+ 'llPassTouches',
+ 'llPatrolPoints',
+ 'llPlaySound',
+ 'llPlaySoundSlave',
+ 'llPow',
+ 'llPreloadSound',
+ 'llPursue',
+ 'llPushObject',
+ 'llRegionSay',
+ 'llRegionSayTo',
+ 'llReleaseControls',
+ 'llReleaseURL',
+ 'llRemoteDataReply',
+ 'llRemoteLoadScriptPin',
+ 'llRemoveFromLandBanList',
+ 'llRemoveFromLandPassList',
+ 'llRemoveInventory',
+ 'llRemoveVehicleFlags',
+ 'llRequestAgentData',
+ 'llRequestDisplayName',
+ 'llRequestInventoryData',
+ 'llRequestPermissions',
+ 'llRequestSecureURL',
+ 'llRequestSimulatorData',
+ 'llRequestURL',
+ 'llRequestUsername',
+ 'llResetAnimationOverride',
+ 'llResetLandBanList',
+ 'llResetLandPassList',
+ 'llResetOtherScript',
+ 'llResetScript',
+ 'llResetTime',
+ 'llReturnObjectsByID',
+ 'llReturnObjectsByOwner',
+ 'llRezAtRoot',
+ 'llRezObject',
+ 'llRot2Angle',
+ 'llRot2Axis',
+ 'llRot2Euler',
+ 'llRot2Fwd',
+ 'llRot2Left',
+ 'llRot2Up',
+ 'llRotateTexture',
+ 'llRotBetween',
+ 'llRotLookAt',
+ 'llRotTarget',
+ 'llRotTargetRemove',
+ 'llRound',
+ 'llSameGroup',
+ 'llSay',
+ 'llScaleByFactor',
+ 'llScaleTexture',
+ 'llScriptDanger',
+ 'llScriptProfiler',
+ 'llSendRemoteData',
+ 'llSensor',
+ 'llSensorRemove',
+ 'llSensorRepeat',
+ 'llSetAlpha',
+ 'llSetAngularVelocity',
+ 'llSetAnimationOverride',
+ 'llSetBuoyancy',
+ 'llSetCameraAtOffset',
+ 'llSetCameraEyeOffset',
+ 'llSetCameraParams',
+ 'llSetClickAction',
+ 'llSetColor',
+ 'llSetContentType',
+ 'llSetDamage',
+ 'llSetForce',
+ 'llSetForceAndTorque',
+ 'llSetHoverHeight',
+ 'llSetKeyframedMotion',
+ 'llSetLinkAlpha',
+ 'llSetLinkCamera',
+ 'llSetLinkColor',
+ 'llSetLinkMedia',
+ 'llSetLinkPrimitiveParams',
+ 'llSetLinkPrimitiveParamsFast',
+ 'llSetLinkTexture',
+ 'llSetLinkTextureAnim',
+ 'llSetLocalRot',
+ 'llSetMemoryLimit',
+ 'llSetObjectDesc',
+ 'llSetObjectName',
+ 'llSetParcelMusicURL',
+ 'llSetPayPrice',
+ 'llSetPhysicsMaterial',
+ 'llSetPos',
+ 'llSetPrimitiveParams',
+ 'llSetPrimMediaParams',
+ 'llSetRegionPos',
+ 'llSetRemoteScriptAccessPin',
+ 'llSetRot',
+ 'llSetScale',
+ 'llSetScriptState',
+ 'llSetSitText',
+ 'llSetSoundQueueing',
+ 'llSetSoundRadius',
+ 'llSetStatus',
+ 'llSetText',
+ 'llSetTexture',
+ 'llSetTextureAnim',
+ 'llSetTimerEvent',
+ 'llSetTorque',
+ 'llSetTouchText',
+ 'llSetVehicleFlags',
+ 'llSetVehicleFloatParam',
+ 'llSetVehicleRotationParam',
+ 'llSetVehicleType',
+ 'llSetVehicleVectorParam',
+ 'llSetVelocity',
+ 'llSHA1String',
+ 'llShout',
+ 'llSin',
+ 'llSitTarget',
+ 'llSleep',
+ 'llSqrt',
+ 'llStartAnimation',
+ 'llStopAnimation',
+ 'llStopHover',
+ 'llStopLookAt',
+ 'llStopMoveToTarget',
+ 'llStopSound',
+ 'llStringLength',
+ 'llStringToBase64',
+ 'llStringTrim',
+ 'llSubStringIndex',
+ 'llTakeControls',
+ 'llTan',
+ 'llTarget',
+ 'llTargetOmega',
+ 'llTargetRemove',
+ 'llTeleportAgent',
+ 'llTeleportAgentGlobalCoords',
+ 'llTeleportAgentHome',
+ 'llTextBox',
+ 'llToLower',
+ 'llToUpper',
+ 'llTransferLindenDollars',
+ 'llTriggerSound',
+ 'llTriggerSoundLimited',
+ 'llUnescapeURL',
+ 'llUnSit',
+ 'llUpdateCharacter',
+ 'llVecDist',
+ 'llVecMag',
+ 'llVecNorm',
+ 'llVolumeDetect',
+ 'llWanderWithin',
+ 'llWater',
+ 'llWhisper',
+ 'llWind',
+ 'llXorBase64',
+ 'print',
+ ),
+ 6 => array( // deprecated
+ 'ATTACH_LPEC',
+ 'ATTACH_RPEC',
+ 'DATA_RATING',
+ 'PERMISSION_CHANGE_JOINTS',
+ 'PERMISSION_CHANGE_PERMISSIONS',
+ 'PERMISSION_RELEASE_OWNERSHIP',
+ 'PERMISSION_REMAP_CONTROLS',
+ 'PRIM_CAST_SHADOWS',
+ 'PRIM_MATERIAL_LIGHT',
+ 'PSYS_SRC_INNERANGLE',
+ 'PSYS_SRC_OBJ_REL_MASK',
+ 'PSYS_SRC_OUTERANGLE',
+ 'VEHICLE_FLAG_NO_FLY_UP',
+ 'llCloud',
+ 'llMakeExplosion',
+ 'llMakeFire',
+ 'llMakeFountain',
+ 'llMakeSmoke',
+ 'llRemoteDataSetRegion',
+ 'llSound',
+ 'llSoundPreload',
+ 'llXorBase64Strings',
+ 'llXorBase64StringsCorrect',
+ ),
+ 7 => array( // unimplemented
+ 'event',
+ 'llCollisionSprite',
+ 'llPointAt',
+ 'llRefreshPrimURL',
+ 'llReleaseCamera',
+ 'llRemoteLoadScript',
+ 'llSetPrimURL',
+ 'llStopPointAt',
+ 'llTakeCamera',
+ ),
+ 8 => array( // God mode
+ 'llGodLikeRezObject',
+ 'llSetInventoryPermMask',
+ 'llSetObjectPermMask',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '{', '}', '(', ')', '[', ']',
+ '=', '+', '-', '*', '/',
+ '+=', '-=', '*=', '/=', '%=', '++', '--',
+ '!', '%', '&', '|', '&&', '||',
+ '==', '!=', '<', '>', '<=', '>=',
+ '~', '<<', '>>', '^', ':',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #000080;',
+ 3 => 'color: #008080;',
+ 4 => 'color: #228b22;',
+ 5 => 'color: #b22222;',
+ 6 => 'color: #8b0000; background-color: #ffff00;',
+ 7 => 'color: #8b0000; background-color: #fa8072;',
+ 8 => 'color: #000000; background-color: #ba55d3;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #ff7f50; font-style: italic;',
+ 'MULTI' => 'color: #ff7f50; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #006400;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://wiki.secondlife.com/wiki/{FNAME}',
+ 4 => 'http://wiki.secondlife.com/wiki/{FNAME}',
+ 5 => 'http://wiki.secondlife.com/wiki/{FNAME}',
+ 6 => 'http://wiki.secondlife.com/wiki/{FNAME}',
+ 7 => 'http://wiki.secondlife.com/wiki/{FNAME}',
+ 8 => 'http://wiki.secondlife.com/wiki/{FNAME}',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/lua.php b/platform/www/vendor/geshi/geshi/src/geshi/lua.php
new file mode 100644
index 0000000..2b8ebc4
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/lua.php
@@ -0,0 +1,175 @@
+<?php
+/*************************************************************************************
+ * lua.php
+ * -------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/07/10
+ *
+ * LUA language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/08/26 (1.0.2)
+ * - Added support for objects and methods
+ * - Removed unusable keywords
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Lua',
+ 'COMMENT_SINGLE' => array(1 => "--"),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(1 => '/--\[(=*)\[.*?\]\1\]/s'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[\\\\abfnrtv\'\"]#i",
+ //Octal Char Specs
+ 2 => "#\\\\\\d{1,3}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_FLT_NONSCI | GESHI_NUMBER_FLT_NONSCI_F |
+ GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'break','do','else','elseif','end','for','function','if',
+ 'local','repeat','return','then','until','while'
+ ),
+ 2 => array(
+ 'and','in','not','or'
+ ),
+ 3 => array(
+ '_VERSION','assert','collectgarbage','dofile','error','gcinfo','loadfile','loadstring',
+ 'print','tonumber','tostring','type','unpack',
+ '_ALERT','_ERRORMESSAGE','_INPUT','_PROMPT','_OUTPUT',
+ '_STDERR','_STDIN','_STDOUT','call','dostring','foreach','foreachi','getn','globals','newtype',
+ 'rawget','rawset','require','sort','tinsert','tremove',
+ 'abs','acos','asin','atan','atan2','ceil','cos','deg','exp',
+ 'floor','format','frexp','gsub','ldexp','log','log10','max','min','mod','rad','random','randomseed',
+ 'sin','sqrt','strbyte','strchar','strfind','strlen','strlower','strrep','strsub','strupper','tan',
+ 'openfile','closefile','readfrom','writeto','appendto',
+ 'remove','rename','flush','seek','tmpfile','tmpname','read','write',
+ 'clock','date','difftime','execute','exit','getenv','setlocale','time',
+ '_G','getfenv','getmetatable','ipairs','loadlib','next','pairs','pcall',
+ 'rawegal','setfenv','setmetatable','xpcall',
+ 'string.byte','string.char','string.dump','string.find','string.len',
+ 'string.lower','string.rep','string.sub','string.upper','string.format','string.gfind','string.gsub',
+ 'table.concat','table.foreach','table.foreachi','table.getn','table.sort','table.insert','table.remove','table.setn',
+ 'math.abs','math.acos','math.asin','math.atan','math.atan2','math.ceil','math.cos','math.deg','math.exp',
+ 'math.floor','math.frexp','math.ldexp','math.log','math.log10','math.max','math.min','math.mod',
+ 'math.pi','math.rad','math.random','math.randomseed','math.sin','math.sqrt','math.tan',
+ 'coroutine.create','coroutine.resume','coroutine.status',
+ 'coroutine.wrap','coroutine.yield',
+ 'io.close','io.flush','io.input','io.lines','io.open','io.output','io.read','io.tmpfile','io.type','io.write',
+ 'io.stdin','io.stdout','io.stderr',
+ 'os.clock','os.date','os.difftime','os.execute','os.exit','os.getenv','os.remove','os.rename',
+ 'os.setlocale','os.time','os.tmpname',
+ 'string','table','math','coroutine','io','os','debug'
+ ),
+ 4 => array(
+ 'nil', 'false', 'true'
+ ),
+ 5 => array(
+ 'Nil', 'Boolean', 'Number', 'String', 'Userdata', 'Thread', 'Table'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '+', '-', '*', '/', '%', '^', '#',
+ '==', '~=', '<=', '>=', '<', '>', '=',
+ '(', ')', '{', '}', '[', ']',
+ ';', ':', ',', '.', '..', '...'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #aa9900; font-weight: bold;',
+ 2 => 'color: #aa9900; font-weight: bold;',
+ 3 => 'color: #0000aa;',
+ 4 => 'color: #aa9900;',
+ 5 => 'color: #aa9900;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ //2 => 'color: #ff0000;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff6666;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #aa9900;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/m68k.php b/platform/www/vendor/geshi/geshi/src/geshi/m68k.php
new file mode 100644
index 0000000..2d995c5
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/m68k.php
@@ -0,0 +1,141 @@
+<?php
+/*************************************************************************************
+ * m68k.php
+ * --------
+ * Author: Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2007 Benny Baumann (http://www.omorphia.de/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/02/06
+ *
+ * Motorola 68000 Assembler language file for GeSHi.
+ *
+ * Syntax definition as commonly used by the motorola documentation for the
+ * MC68HC908GP32 Microcontroller (and maybe others).
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2007/06/02 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2007/06/02)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Motorola 68000 Assembler',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /*CPU*/
+ 1 => array(
+ 'adc','add','ais','aix','and','asl','asr','bcc','bclr','bcs','beq',
+ 'bge','bgt','bhcc','bhcs','bhi','bhs','bih','bil','bit','ble','blo',
+ 'bls','blt','bmc','bmi','bms','bne','bpl','bra','brclr','brn',
+ 'brset','bset','bsr','cbeq','clc','cli','clr','cmp','com','cphx',
+ 'cpx','daa','dbnz','dec','div','eor','inc','jmp','jsr','lda','ldhx',
+ 'ldx','lsl','lsr','mov','mul','neg','nop','nsa','ora','psha','pshh',
+ 'pshx','pula','pulh','pulx','rol','ror','rsp','rti','rts','sbc',
+ 'sec','sei','sta','sthx','stop','stx','sub','swi','tap','tax','tpa',
+ 'tst','tsx','txa','txs','wait'
+ ),
+ /*registers*/
+ 2 => array(
+ 'a','h','x',
+ 'hx','sp'
+ ),
+ /*Directive*/
+ 3 => array(
+ '#define','#endif','#else','#ifdef','#ifndef','#include','#undef',
+ '.db','.dd','.df','.dq','.dt','.dw','.end','.org','equ'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff; font-weight:bold;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #46aa03; font-weight:bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #dd22dd;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #22bbff;',
+ 1 => 'color: #22bbff;',
+ 2 => 'color: #993333;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Hex numbers
+ 0 => '#?0[0-9a-fA-F]{1,32}[hH]',
+ //Binary numbers
+ 1 => '\%[01]{1,64}[bB]',
+ //Labels
+ 2 => '^[_a-zA-Z][_a-zA-Z0-9]*?\:'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 8
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/magiksf.php b/platform/www/vendor/geshi/geshi/src/geshi/magiksf.php
new file mode 100644
index 0000000..44f069d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/magiksf.php
@@ -0,0 +1,191 @@
+<?php
+/*************************************************************************************
+ * magiksf.php
+ * --------
+ * Author: Sjoerd van Leent (svanleent@gmail.com)
+ * Copyright: (c) 2010 Sjoerd van Leent
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/02/15
+ *
+ * MagikSF language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/02/22 (1.0.0.2)
+ * - Symbols also accept the ! and ? characters properly
+ * - Labels (identifiers starting with !) are also coloured
+ * 2010/02/17 (1.0.0.1)
+ * - Parsing out symbols better
+ * - Add package identifiers
+ * 2010/02/15 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'ESCAPE_CHAR' => null,
+ 'LANG_NAME' => 'MagikSF',
+ 'COMMENT_SINGLE' => array(1 => '##', 2 => '#%', 3 => '#'),
+ 'COMMENT_MULTI' => array("_pragma(" => ")"),
+ //Multiline-continued single-line comments
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '', // FIXME: Duplicate array key. null or ''?
+ 'KEYWORDS' => array(
+ 1 => array(
+ '_block', '_endblock', '_proc', '_endproc', '_loop', '_endloop',
+ '_method', '_endmethod',
+ '_protect', '_endprotect', '_protection', '_locking',
+ '_continue',
+ ),
+ 2 => array(
+ '_self', '_thisthread', '_pragma', '_private', '_abstract',
+ '_local', '_global', '_dynamic', '_package', '_constant',
+ '_import', '_iter', '_lock', '_optional', '_recursive', '_super'
+ ),
+ 3 => array(
+ '_if', '_endif', '_then', '_else', '_elif', '_orif', '_andif', '_for', '_over',
+ '_try', '_endtry', '_when', '_throw', '_catch', '_endcatch', '_handling',
+ '_finally', '_loopbody', '_return', '_leave', '_with'
+ ),
+ 4 => array(
+ '_false', '_true', '_maybe', '_unset', '_no_way'
+ ),
+ 5 => array(
+ '_mod', '_div', '_or', '_and', '_cf', '_is', '_isnt', '_not', '_gather', '_scatter',
+ '_allresults', '_clone', '_xor'
+ ),
+ 6 => array(
+ 'def_slotted_exemplar', 'write_string', 'write', 'condition',
+ 'record_transaction', 'gis_program_manager', 'perform', 'define_shared_constant',
+ 'property_list', 'rope', 'def_property', 'def_mixin'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']',
+ '+', '-', '*', '/', '**',
+ '=', '<', '>', '<<', '>>',
+ ',', '$',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #ff3f3f;',
+ 3 => 'color: #3f7f3f; font-weight: bold;',
+ 4 => 'color: #cc66cc;',
+ 5 => 'color: #ff3fff; font-weight: bold;',
+ 6 => 'font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #339933; font-weight: bold;',
+ 2 => 'color: #993333;',
+ 3 => 'color: #339933;',
+ 'MULTI' => 'color: #7f7f7f; font-style: italic',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #ff3f3f;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #ff3f3f;'
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #3f3fff;',
+ 2 => 'color: #3f3fff;',
+ 3 => 'color: #cc66cc;',
+ 4 => 'color: #7f3f7f; font-style: italic;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ 1 => array(
+ GESHI_SEARCH => '\b[a-zA-Z0-9_]+:', // package identifiers
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 2 => array(
+ GESHI_SEARCH => ':(?:[a-zA-Z0-9!?_]+|(?:[<pipe>].*?[<pipe>]))*', //symbols
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 3 => array(
+ GESHI_SEARCH => '%space|%tab|%newline|%.', //characters
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 4 => array(
+ GESHI_SEARCH => '@(?:[a-zA-Z0-9!?_]+|(?:[<pipe>].*?[<pipe>]))*', //symbols
+ GESHI_REPLACE => '\\0',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/make.php b/platform/www/vendor/geshi/geshi/src/geshi/make.php
new file mode 100644
index 0000000..6ea601f
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/make.php
@@ -0,0 +1,149 @@
+<?php
+/*************************************************************************************
+ * make.php
+ * --------
+ * Author: Neil Bird <phoenix@fnxweb.com>
+ * Copyright: (c) 2008 Neil Bird
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/08/26
+ *
+ * make language file for GeSHi.
+ *
+ * (GNU make specific)
+ *
+ * CHANGES
+ * -------
+ * 2008/09/05 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'GNU make',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_REGEXP' => array(
+ //Escaped String Starters
+ 2 => "/\\\\['\"]/siU"
+ ),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ // core
+ 'ifeq', 'else', 'endif', 'ifneq', 'ifdef', 'ifndef',
+ 'include', 'vpath', 'export', 'unexport', 'override',
+ 'info', 'warning', 'error'
+ ),
+ 2 => array(
+ // macros, literals
+ '.SUFFIXES', '.PHONY', '.DEFAULT', '.PRECIOUS', '.IGNORE', '.SILENT', '.EXPORT_ALL_VARIABLES', '.KEEP_STATE',
+ '.LIBPATTERNS', '.NOTPARALLEL', '.DELETE_ON_ERROR', '.INTERMEDIATE', '.POSIX', '.SECONDARY'
+ ),
+ /*
+ 3 => array(
+ // funcs - see regex
+ //'subst', 'addprefix', 'addsuffix', 'basename', 'call', 'dir', 'error', 'eval', 'filter-out', 'filter',
+ //'findstring', 'firstword', 'foreach', 'if', 'join', 'notdir', 'origin', 'patsubst', 'shell', 'sort', 'strip',
+ //'suffix', 'warning', 'wildcard', 'word', 'wordlist', 'words'
+ )*/
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}',
+ '!', '@', '%', '&', '|', '/',
+ '<', '>',
+ '=', '-', '+', '*',
+ '.', ':', ',', ';',
+ '$'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ //3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #666622; font-weight: bold;',
+ 2 => 'color: #990000;',
+ //3 => 'color: #000000; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #339900; font-style: italic;',
+ 2 => 'color: #000099; font-weight: bold;',
+ 'MULTI' => ''
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array( # keep same as symbols so as to make ${} and $() equiv.
+ 0 => 'color: #004400;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #CC2200;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #CC2200;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #004400;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #000088; font-weight: bold;',
+ 1 => 'color: #0000CC; font-weight: bold;',
+ 2 => 'color: #000088;'
+ ),
+ 'SCRIPT' => array(),
+ 'METHODS' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ //3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ //Simple variables
+ 0 => "\\$(?:[^{(&]|&(?:amp|lt|gt);)",
+ //Complex variables/functions [built-ins]
+ 1 => array(
+ GESHI_SEARCH => '(\\$[({])(subst|addprefix|addsuffix|basename|call|dir|error|eval|filter-out|filter,|findstring|firstword|foreach|if|join|notdir|origin|patsubst|shell|sort|strip,|suffix|warning|wildcard|word|wordlist|words)([ })])',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ //Complex variables/functions [others]
+ 2 => array(
+ GESHI_SEARCH => '(\\$[({])([A-Za-z_][A-Za-z_0-9]*)([ })])',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 8
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/mapbasic.php b/platform/www/vendor/geshi/geshi/src/geshi/mapbasic.php
new file mode 100644
index 0000000..383bb51
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/mapbasic.php
@@ -0,0 +1,906 @@
+<?php
+/*************************************************************************************
+ * mapbasic.php
+ * ------
+ * Author: Tomasz Berus (t.berus@gisodkuchni.pl)
+ * Copyright: (c) 2009 Tomasz Berus (http://sourceforge.net/projects/mbsyntax/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/11/25
+ *
+ * MapBasic language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/09/17 (1.0.1)
+ * - Replaced all tabs with spaces
+ * - Fixed 'URLS' array
+ * 2008/11/25 (1.0.0)
+ * - First Release (MapBasic v9.5)
+ *
+ * TODO (updated 2008/11/25)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'MapBasic',
+ 'COMMENT_SINGLE' => array(1 => "'"),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+/*
+ 1 - Statements + Clauses + Data Types + Logical Operators, Geographical Operators + SQL
+ 2 - Special Procedures
+ 3 - Functions
+ 4 - Constants
+ 5 - Extended keywords (case sensitive)
+*/
+ 1 => array(
+ 'Add', 'Alias', 'All', 'Alter', 'And', 'Any', 'Application', 'Arc',
+ 'Area', 'As', 'AutoLabel', 'Bar', 'Beep', 'Begin', 'Bind',
+ 'Browse', 'Brush', 'BrushPicker', 'Button', 'ButtonPad',
+ 'ButtonPads', 'BY', 'Call', 'CancelButton', 'Cartographic', 'Case',
+ 'CharSet', 'Check', 'CheckBox', 'Clean', 'Close', 'Collection',
+ 'Column', 'Combine', 'Command', 'Commit', 'Connection',
+ 'ConnectionNumber', 'Contains', 'Continue', 'Control', 'CoordSys',
+ 'Create', 'Cutter', 'Date', 'Datum', 'DDEExecute', 'DDEPoke',
+ 'DDETerminate', 'DDETerminateAll', 'Declare', 'Default', 'Define',
+ 'Delete', 'Dialog', 'Digitizer', 'Dim', 'Disaggregate',
+ 'Disconnect', 'Distance', 'Do', 'Document', 'DocumentWindow',
+ 'Drag', 'Drop', 'EditText', 'Ellipse', 'Enclose', 'End', 'Entire',
+ 'Entirely', 'Erase', 'Error', 'Event', 'Exit', 'Export',
+ 'Farthest', 'Fetch', 'File', 'Find', 'Float', 'FME', 'Font',
+ 'FontPicker', 'For', 'Format', 'Frame', 'From', 'Function',
+ 'Geocode', 'Get', 'Global', 'Goto', 'Graph', 'Grid', 'GROUP',
+ 'GroupBox', 'Handler', 'If', 'Import', 'In', 'Include', 'Index',
+ 'Info', 'Input', 'Insert', 'Integer', 'Intersect', 'Intersects',
+ 'INTO', 'Isogram', 'Item', 'Kill', 'Layout', 'Legend', 'Line',
+ 'Link', 'ListBox', 'Logical', 'Loop', 'Map', 'Map3D', 'MapInfo',
+ 'MapInfoDialog', 'Menu', 'Merge', 'Metadata', 'Method', 'Mod',
+ 'Move', 'MultiListBox', 'MultiPoint', 'MWS', 'Nearest', 'Next',
+ 'NOSELECT', 'Not', 'Note', 'Object', 'Objects', 'Offset',
+ 'OKButton', 'OnError', 'Open', 'Or', 'ORDER', 'Overlay', 'Pack',
+ 'Paper', 'Part', 'Partly', 'Pen', 'PenPicker', 'Pline', 'Point',
+ 'PopupMenu', 'Preserve', 'Print', 'PrintWin', 'PrismMap',
+ 'Processing', 'Program', 'ProgressBar', 'ProgressBars', 'Put',
+ 'RadioGroup', 'Randomize', 'Ranges', 'Rect', 'ReDim',
+ 'Redistricter', 'Refresh', 'Region', 'Register', 'Relief',
+ 'Reload', 'Remove', 'Rename', 'Report', 'Reproject', 'Resolution',
+ 'Resume', 'Rollback', 'RoundRect', 'RowID', 'Run', 'Save', 'Seek',
+ 'Select', 'Selection', 'Server', 'Set', 'Shade', 'SmallInt',
+ 'Snap', 'Split', 'StaticText', 'StatusBar', 'Stop', 'String',
+ 'Style', 'Styles', 'Sub', 'Symbol', 'SymbolPicker', 'Symbols',
+ 'Table', 'Target', 'Terminate', 'Text', 'Then', 'Threshold',
+ 'Timeout', 'To', 'Transaction', 'Transform', 'Type', 'UnDim',
+ 'Units', 'Unlink', 'Update', 'Using', 'VALUES', 'Version',
+ 'Versioning', 'Wend', 'WFS', 'WHERE', 'While', 'Window', 'Within',
+ 'Workspace', 'Write'
+ ),
+ 2 => array(
+ 'EndHandler', 'ForegroundTaskSwitchHandler', 'Main',
+ 'RemoteMapGenHandler', 'RemoteMsgHandler', 'SelChangedHandler',
+ 'ToolHandler', 'WinChangedHandler', 'WinClosedHandler',
+ 'WinFocusChangedHandler'
+ ),
+ 3 => array(
+ 'Abs', 'Acos', 'ApplicationDirectory$', 'AreaOverlap', 'Asc',
+ 'Asin', 'Ask', 'Atn', 'Avg', 'Buffer', 'ButtonPadInfo',
+ 'CartesianArea', 'CartesianBuffer', 'CartesianConnectObjects',
+ 'CartesianDistance', 'CartesianObjectDistance',
+ 'CartesianObjectLen', 'CartesianOffset', 'CartesianOffsetXY',
+ 'CartesianPerimeter', 'Centroid', 'CentroidX', 'CentroidY',
+ 'ChooseProjection$', 'Chr$', 'ColumnInfo', 'CommandInfo',
+ 'ConnectObjects', 'ControlPointInfo', 'ConvertToPline',
+ 'ConvertToRegion', 'ConvexHull', 'CoordSysName$', 'Cos', 'Count',
+ 'CreateCircle', 'CreateLine', 'CreatePoint', 'CreateText',
+ 'CurDate', 'CurrentBorderPen', 'CurrentBrush', 'CurrentFont',
+ 'CurrentLinePen', 'CurrentPen', 'CurrentSymbol', 'DateWindow',
+ 'Day', 'DDEInitiate', 'DDERequest$', 'DeformatNumber$', 'EOF',
+ 'EOT', 'EPSGToCoordSysString$', 'Err', 'Error$', 'Exp',
+ 'ExtractNodes', 'FileAttr', 'FileExists', 'FileOpenDlg',
+ 'FileSaveAsDlg', 'Fix', 'Format$', 'FormatDate$', 'FormatNumber$',
+ 'FrontWindow', 'GeocodeInfo', 'GetFolderPath$', 'GetGridCellValue',
+ 'GetMetadata$', 'GetSeamlessSheet', 'GridTableInfo',
+ 'HomeDirectory$', 'InStr', 'Int', 'IntersectNodes',
+ 'IsGridCellNull', 'IsogramInfo', 'IsPenWidthPixels',
+ 'LabelFindByID', 'LabelFindFirst', 'LabelFindNext', 'LabelInfo',
+ 'LayerInfo', 'LCase$', 'Left$', 'LegendFrameInfo', 'LegendInfo',
+ 'LegendStyleInfo', 'Len', 'Like', 'LocateFile$', 'LOF', 'Log',
+ 'LTrim$', 'MakeBrush', 'MakeCustomSymbol', 'MakeFont',
+ 'MakeFontSymbol', 'MakePen', 'MakeSymbol', 'Map3DInfo',
+ 'MapperInfo', 'Max', 'Maximum', 'MBR', 'MenuItemInfoByHandler',
+ 'MenuItemInfoByID', 'MGRSToPoint', 'MICloseContent',
+ 'MICloseFtpConnection', 'MICloseFtpFileFind',
+ 'MICloseHttpConnection', 'MICloseHttpFile', 'MICloseSession',
+ 'MICreateSession', 'MICreateSessionFull', 'Mid$', 'MidByte$',
+ 'MIErrorDlg', 'MIFindFtpFile', 'MIFindNextFtpFile', 'MIGetContent',
+ 'MIGetContentBuffer', 'MIGetContentLen', 'MIGetContentString',
+ 'MIGetContentToFile', 'MIGetContentType',
+ 'MIGetCurrentFtpDirectory', 'MIGetErrorCode', 'MIGetErrorMessage',
+ 'MIGetFileURL', 'MIGetFtpConnection', 'MIGetFtpFile',
+ 'MIGetFtpFileFind', 'MIGetFtpFileName', 'MIGetHttpConnection',
+ 'MIIsFtpDirectory', 'MIIsFtpDots', 'Min', 'Minimum',
+ 'MIOpenRequest', 'MIOpenRequestFull', 'MIParseURL', 'MIPutFtpFile',
+ 'MIQueryInfo', 'MIQueryInfoStatusCode', 'MISaveContent',
+ 'MISendRequest', 'MISendSimpleRequest', 'MISetCurrentFtpDirectory',
+ 'MISetSessionTimeout', 'MIXmlAttributeListDestroy',
+ 'MIXmlDocumentCreate', 'MIXmlDocumentDestroy',
+ 'MIXmlDocumentGetNamespaces', 'MIXmlDocumentGetRootNode',
+ 'MIXmlDocumentLoad', 'MIXmlDocumentLoadXML',
+ 'MIXmlDocumentLoadXMLString', 'MIXmlDocumentSetProperty',
+ 'MIXmlGetAttributeList', 'MIXmlGetChildList',
+ 'MIXmlGetNextAttribute', 'MIXmlGetNextNode', 'MIXmlNodeDestroy',
+ 'MIXmlNodeGetAttributeValue', 'MIXmlNodeGetFirstChild',
+ 'MIXmlNodeGetName', 'MIXmlNodeGetParent', 'MIXmlNodeGetText',
+ 'MIXmlNodeGetValue', 'MIXmlNodeListDestroy', 'MIXmlSCDestroy',
+ 'MIXmlSCGetLength', 'MIXmlSCGetNamespace', 'MIXmlSelectNodes',
+ 'MIXmlSelectSingleNode', 'Month', 'NumAllWindows', 'NumberToDate',
+ 'NumCols', 'NumTables', 'NumWindows', 'ObjectDistance',
+ 'ObjectGeography', 'ObjectInfo', 'ObjectLen', 'ObjectNodeHasM',
+ 'ObjectNodeHasZ', 'ObjectNodeM', 'ObjectNodeX', 'ObjectNodeY',
+ 'ObjectNodeZ', 'OffsetXY', 'Overlap', 'OverlayNodes',
+ 'PathToDirectory$', 'PathToFileName$', 'PathToTableName$',
+ 'PenWidthToPoints', 'Perimeter', 'PointsToPenWidth',
+ 'PointToMGRS$', 'PrismMapInfo', 'ProgramDirectory$', 'Proper$',
+ 'ProportionOverlap', 'RasterTableInfo', 'ReadControlValue',
+ 'RegionInfo', 'RemoteQueryHandler', 'RGB', 'Right$', 'Rnd',
+ 'Rotate', 'RotateAtPoint', 'Round', 'RTrim$', 'SearchInfo',
+ 'SearchPoint', 'SearchRect', 'SelectionInfo', 'Server_ColumnInfo',
+ 'Server_Connect', 'Server_ConnectInfo', 'Server_DriverInfo',
+ 'Server_EOT', 'Server_Execute', 'Server_GetODBCHConn',
+ 'Server_GetODBCHStmt', 'Server_NumCols', 'Server_NumDrivers',
+ 'SessionInfo', 'Sgn', 'Sin', 'Space$', 'SphericalArea',
+ 'SphericalConnectObjects', 'SphericalDistance',
+ 'SphericalObjectDistance', 'SphericalObjectLen', 'SphericalOffset',
+ 'SphericalOffsetXY', 'SphericalPerimeter', 'Sqr', 'Str$',
+ 'String$', 'StringCompare', 'StringCompareIntl', 'StringToDate',
+ 'StyleAttr', 'Sum', 'SystemInfo', 'TableInfo', 'Tan',
+ 'TempFileName$', 'TextSize', 'Time', 'Timer', 'TriggerControl',
+ 'TrueFileName$', 'UBound', 'UCase$', 'UnitAbbr$', 'UnitName$',
+ 'Val', 'Weekday', 'WindowID', 'WindowInfo', 'WtAvg', 'Year'
+ ),
+ 4 => array(
+ 'BLACK', 'BLUE', 'BRUSH_BACKCOLOR', 'BRUSH_FORECOLOR',
+ 'BRUSH_PATTERN', 'BTNPAD_INFO_FLOATING', 'BTNPAD_INFO_NBTNS',
+ 'BTNPAD_INFO_WIDTH', 'BTNPAD_INFO_WINID', 'BTNPAD_INFO_X',
+ 'BTNPAD_INFO_Y', 'CLS', 'CMD_INFO_CTRL', 'CMD_INFO_CUSTOM_OBJ',
+ 'CMD_INFO_DLG_DBL', 'CMD_INFO_DLG_OK', 'CMD_INFO_EDIT_ASK',
+ 'CMD_INFO_EDIT_DISCARD', 'CMD_INFO_EDIT_SAVE',
+ 'CMD_INFO_EDIT_STATUS', 'CMD_INFO_EDIT_TABLE', 'CMD_INFO_FIND_RC',
+ 'CMD_INFO_FIND_ROWID', 'CMD_INFO_HL_FILE_NAME',
+ 'CMD_INFO_HL_LAYER_ID', 'CMD_INFO_HL_ROWID',
+ 'CMD_INFO_HL_TABLE_NAME', 'CMD_INFO_HL_WINDOW_ID',
+ 'CMD_INFO_INTERRUPT', 'CMD_INFO_MENUITEM', 'CMD_INFO_MSG',
+ 'CMD_INFO_ROWID', 'CMD_INFO_SELTYPE', 'CMD_INFO_SHIFT',
+ 'CMD_INFO_STATUS', 'CMD_INFO_TASK_SWITCH', 'CMD_INFO_TOOLBTN',
+ 'CMD_INFO_WIN', 'CMD_INFO_X', 'CMD_INFO_X2', 'CMD_INFO_XCMD',
+ 'CMD_INFO_Y', 'CMD_INFO_Y2', 'COL_INFO_DECPLACES',
+ 'COL_INFO_EDITABLE', 'COL_INFO_INDEXED', 'COL_INFO_NAME',
+ 'COL_INFO_NUM', 'COL_INFO_TYPE', 'COL_INFO_WIDTH', 'COL_TYPE_CHAR',
+ 'COL_TYPE_DATE', 'COL_TYPE_DATETIME', 'COL_TYPE_DECIMAL',
+ 'COL_TYPE_FLOAT', 'COL_TYPE_GRAPHIC', 'COL_TYPE_INTEGER',
+ 'COL_TYPE_LOGICAL', 'COL_TYPE_SMALLINT', 'COL_TYPE_TIME', 'CYAN',
+ 'DATE_WIN_CURPROG', 'DATE_WIN_SESSION', 'DEG_2_RAD',
+ 'DICTIONARY_ADDRESS_ONLY', 'DICTIONARY_ALL',
+ 'DICTIONARY_PREFER_ADDRESS', 'DICTIONARY_PREFER_USER',
+ 'DICTIONARY_USER_ONLY', 'DM_CUSTOM_CIRCLE', 'DM_CUSTOM_ELLIPSE',
+ 'DM_CUSTOM_LINE', 'DM_CUSTOM_POINT', 'DM_CUSTOM_POLYGON',
+ 'DM_CUSTOM_POLYLINE', 'DM_CUSTOM_RECT', 'DMPAPER_10X11',
+ 'DMPAPER_10X14', 'DMPAPER_11X17', 'DMPAPER_12X11', 'DMPAPER_15X11',
+ 'DMPAPER_9X11', 'DMPAPER_A_PLUS', 'DMPAPER_A2', 'DMPAPER_A3',
+ 'DMPAPER_A3_EXTRA', 'DMPAPER_A3_EXTRA_TRANSVERSE',
+ 'DMPAPER_A3_ROTATED', 'DMPAPER_A3_TRANSVERSE', 'DMPAPER_A4',
+ 'DMPAPER_A4_EXTRA', 'DMPAPER_A4_PLUS', 'DMPAPER_A4_ROTATED',
+ 'DMPAPER_A4_TRANSVERSE', 'DMPAPER_A4SMALL', 'DMPAPER_A5',
+ 'DMPAPER_A5_EXTRA', 'DMPAPER_A5_ROTATED', 'DMPAPER_A5_TRANSVERSE',
+ 'DMPAPER_A6', 'DMPAPER_A6_ROTATED', 'DMPAPER_B_PLUS', 'DMPAPER_B4',
+ 'DMPAPER_B4_JIS_ROTATED', 'DMPAPER_B5', 'DMPAPER_B5_EXTRA',
+ 'DMPAPER_B5_JIS_ROTATED', 'DMPAPER_B5_TRANSVERSE',
+ 'DMPAPER_B6_JIS', 'DMPAPER_B6_JIS_ROTATED', 'DMPAPER_CSHEET',
+ 'DMPAPER_DBL_JAPANESE_POSTCARD',
+ 'DMPAPER_DBL_JAPANESE_POSTCARD_ROTATED', 'DMPAPER_DSHEET',
+ 'DMPAPER_ENV_10', 'DMPAPER_ENV_11', 'DMPAPER_ENV_12',
+ 'DMPAPER_ENV_14', 'DMPAPER_ENV_9', 'DMPAPER_ENV_B4',
+ 'DMPAPER_ENV_B5', 'DMPAPER_ENV_B6', 'DMPAPER_ENV_C3',
+ 'DMPAPER_ENV_C4', 'DMPAPER_ENV_C5', 'DMPAPER_ENV_C6',
+ 'DMPAPER_ENV_C65', 'DMPAPER_ENV_DL', 'DMPAPER_ENV_INVITE',
+ 'DMPAPER_ENV_ITALY', 'DMPAPER_ENV_MONARCH', 'DMPAPER_ENV_PERSONAL',
+ 'DMPAPER_ESHEET', 'DMPAPER_EXECUTIVE',
+ 'DMPAPER_FANFOLD_LGL_GERMAN', 'DMPAPER_FANFOLD_STD_GERMAN',
+ 'DMPAPER_FANFOLD_US', 'DMPAPER_FIRST', 'DMPAPER_FOLIO',
+ 'DMPAPER_ISO_B4', 'DMPAPER_JAPANESE_POSTCARD',
+ 'DMPAPER_JAPANESE_POSTCARD_ROTATED', 'DMPAPER_JENV_CHOU3',
+ 'DMPAPER_JENV_CHOU3_ROTATED', 'DMPAPER_JENV_CHOU4',
+ 'DMPAPER_JENV_CHOU4_ROTATED', 'DMPAPER_JENV_KAKU2',
+ 'DMPAPER_JENV_KAKU2_ROTATED', 'DMPAPER_JENV_KAKU3',
+ 'DMPAPER_JENV_KAKU3_ROTATED', 'DMPAPER_JENV_YOU4',
+ 'DMPAPER_JENV_YOU4_ROTATED', 'DMPAPER_LEDGER', 'DMPAPER_LEGAL',
+ 'DMPAPER_LEGAL_EXTRA', 'DMPAPER_LETTER', 'DMPAPER_LETTER_EXTRA',
+ 'DMPAPER_LETTER_EXTRA_TRANSVERSE', 'DMPAPER_LETTER_PLUS',
+ 'DMPAPER_LETTER_ROTATED', 'DMPAPER_LETTER_TRANSVERSE',
+ 'DMPAPER_LETTERSMALL', 'DMPAPER_NOTE', 'DMPAPER_P16K',
+ 'DMPAPER_P16K_ROTATED', 'DMPAPER_P32K', 'DMPAPER_P32K_ROTATED',
+ 'DMPAPER_P32KBIG', 'DMPAPER_P32KBIG_ROTATED', 'DMPAPER_PENV_1',
+ 'DMPAPER_PENV_1_ROTATED', 'DMPAPER_PENV_10',
+ 'DMPAPER_PENV_10_ROTATED', 'DMPAPER_PENV_2',
+ 'DMPAPER_PENV_2_ROTATED', 'DMPAPER_PENV_3',
+ 'DMPAPER_PENV_3_ROTATED', 'DMPAPER_PENV_4',
+ 'DMPAPER_PENV_4_ROTATED', 'DMPAPER_PENV_5',
+ 'DMPAPER_PENV_5_ROTATED', 'DMPAPER_PENV_6',
+ 'DMPAPER_PENV_6_ROTATED', 'DMPAPER_PENV_7',
+ 'DMPAPER_PENV_7_ROTATED', 'DMPAPER_PENV_8',
+ 'DMPAPER_PENV_8_ROTATED', 'DMPAPER_PENV_9',
+ 'DMPAPER_PENV_9_ROTATED', 'DMPAPER_QUARTO', 'DMPAPER_RESERVED_48',
+ 'DMPAPER_RESERVED_49', 'DMPAPER_STATEMENT', 'DMPAPER_TABLOID',
+ 'DMPAPER_TABLOID_EXTRA', 'DMPAPER_USER', 'ERR_BAD_WINDOW',
+ 'ERR_BAD_WINDOW_NUM', 'ERR_CANT_ACCESS_FILE',
+ 'ERR_CANT_INITIATE_LINK', 'ERR_CMD_NOT_SUPPORTED',
+ 'ERR_FCN_ARG_RANGE', 'ERR_FCN_INVALID_FMT',
+ 'ERR_FCN_OBJ_FETCH_FAILED', 'ERR_FILEMGR_NOTOPEN',
+ 'ERR_FP_MATH_LIB_DOMAIN', 'ERR_FP_MATH_LIB_RANGE',
+ 'ERR_INVALID_CHANNEL', 'ERR_INVALID_READ_CONTROL',
+ 'ERR_INVALID_TRIG_CONTROL', 'ERR_NO_FIELD',
+ 'ERR_NO_RESPONSE_FROM_APP', 'ERR_NULL_SELECTION',
+ 'ERR_PROCESS_FAILED_IN_APP', 'ERR_TABLE_NOT_FOUND',
+ 'ERR_WANT_MAPPER_WIN', 'FALSE', 'FILE_ATTR_FILESIZE',
+ 'FILE_ATTR_MODE', 'FILTER_ALL_DIRECTIONS_1',
+ 'FILTER_ALL_DIRECTIONS_2', 'FILTER_DIAGONALLY',
+ 'FILTER_HORIZONTALLY', 'FILTER_VERTICALLY',
+ 'FILTER_VERTICALLY_AND_HORIZONTALLY', 'FOLDER_APPDATA',
+ 'FOLDER_COMMON_APPDATA', 'FOLDER_COMMON_DOCS',
+ 'FOLDER_LOCAL_APPDATA', 'FOLDER_MI_APPDATA',
+ 'FOLDER_MI_COMMON_APPDATA', 'FOLDER_MI_LOCAL_APPDATA',
+ 'FOLDER_MI_PREFERENCE', 'FOLDER_MYDOCS', 'FOLDER_MYPICS',
+ 'FONT_BACKCOLOR', 'FONT_FORECOLOR', 'FONT_NAME', 'FONT_POINTSIZE',
+ 'FONT_STYLE', 'FRAME_INFO_BORDER_PEN', 'FRAME_INFO_COLUMN',
+ 'FRAME_INFO_HEIGHT', 'FRAME_INFO_LABEL', 'FRAME_INFO_MAP_LAYER_ID',
+ 'FRAME_INFO_NUM_STYLES', 'FRAME_INFO_POS_X', 'FRAME_INFO_POS_Y',
+ 'FRAME_INFO_REFRESHABLE', 'FRAME_INFO_SUBTITLE',
+ 'FRAME_INFO_SUBTITLE_FONT', 'FRAME_INFO_TITLE',
+ 'FRAME_INFO_TITLE_FONT', 'FRAME_INFO_TYPE', 'FRAME_INFO_VISIBLE',
+ 'FRAME_INFO_WIDTH', 'FRAME_TYPE_STYLE', 'FRAME_TYPE_THEME',
+ 'GEO_CONTROL_POINT_X', 'GEO_CONTROL_POINT_Y', 'GEOCODE_BATCH_SIZE',
+ 'GEOCODE_COUNT_GEOCODED', 'GEOCODE_COUNT_NOTGEOCODED',
+ 'GEOCODE_COUNTRY_SUBDIVISION', 'GEOCODE_COUNTRY_SUBDIVISION2',
+ 'GEOCODE_DICTIONARY', 'GEOCODE_FALLBACK_GEOGRAPHIC',
+ 'GEOCODE_FALLBACK_POSTAL', 'GEOCODE_MAX_BATCH_SIZE',
+ 'GEOCODE_MIXED_CASE', 'GEOCODE_MUNICIPALITY',
+ 'GEOCODE_MUNICIPALITY2', 'GEOCODE_OFFSET_CENTER',
+ 'GEOCODE_OFFSET_CENTER_UNITS', 'GEOCODE_OFFSET_END',
+ 'GEOCODE_OFFSET_END_UNITS', 'GEOCODE_PASSTHROUGH',
+ 'GEOCODE_POSTAL_CODE', 'GEOCODE_RESULT_MARK_MULTIPLE',
+ 'GEOCODE_STREET_NAME', 'GEOCODE_STREET_NUMBER',
+ 'GEOCODE_UNABLE_TO_CONVERT_DATA', 'GREEN',
+ 'GRID_TAB_INFO_HAS_HILLSHADE', 'GRID_TAB_INFO_MAX_VALUE',
+ 'GRID_TAB_INFO_MIN_VALUE', 'HOTLINK_INFO_ENABLED',
+ 'HOTLINK_INFO_EXPR', 'HOTLINK_INFO_MODE', 'HOTLINK_INFO_RELATIVE',
+ 'HOTLINK_MODE_BOTH', 'HOTLINK_MODE_LABEL', 'HOTLINK_MODE_OBJ',
+ 'IMAGE_CLASS_BILEVEL', 'IMAGE_CLASS_GREYSCALE',
+ 'IMAGE_CLASS_PALETTE', 'IMAGE_CLASS_RGB', 'IMAGE_TYPE_GRID',
+ 'IMAGE_TYPE_RASTER', 'INCL_ALL', 'INCL_COMMON', 'INCL_CROSSINGS',
+ 'ISOGRAM_AMBIENT_SPEED_DIST_UNIT',
+ 'ISOGRAM_AMBIENT_SPEED_TIME_UNIT', 'ISOGRAM_BANDING',
+ 'ISOGRAM_BATCH_SIZE', 'ISOGRAM_DEFAULT_AMBIENT_SPEED',
+ 'ISOGRAM_MAJOR_POLYGON_ONLY', 'ISOGRAM_MAJOR_ROADS_ONLY',
+ 'ISOGRAM_MAX_BANDS', 'ISOGRAM_MAX_BATCH_SIZE',
+ 'ISOGRAM_MAX_DISTANCE', 'ISOGRAM_MAX_DISTANCE_UNITS',
+ 'ISOGRAM_MAX_OFFROAD_DIST', 'ISOGRAM_MAX_OFFROAD_DIST_UNITS',
+ 'ISOGRAM_MAX_TIME', 'ISOGRAM_MAX_TIME_UNITS',
+ 'ISOGRAM_POINTS_ONLY', 'ISOGRAM_PROPAGATION_FACTOR',
+ 'ISOGRAM_RECORDS_INSERTED', 'ISOGRAM_RECORDS_NOTINSERTED',
+ 'ISOGRAM_RETURN_HOLES', 'ISOGRAM_SIMPLIFICATION_FACTOR',
+ 'LABEL_INFO_ANCHORX', 'LABEL_INFO_ANCHORY', 'LABEL_INFO_DRAWN',
+ 'LABEL_INFO_EDIT', 'LABEL_INFO_EDIT_ANCHOR',
+ 'LABEL_INFO_EDIT_ANGLE', 'LABEL_INFO_EDIT_FONT',
+ 'LABEL_INFO_EDIT_OFFSET', 'LABEL_INFO_EDIT_PEN',
+ 'LABEL_INFO_EDIT_POSITION', 'LABEL_INFO_EDIT_TEXT',
+ 'LABEL_INFO_EDIT_TEXTARROW', 'LABEL_INFO_EDIT_TEXTLINE',
+ 'LABEL_INFO_EDIT_VISIBILITY', 'LABEL_INFO_OBJECT',
+ 'LABEL_INFO_OFFSET', 'LABEL_INFO_ORIENTATION',
+ 'LABEL_INFO_POSITION', 'LABEL_INFO_ROWID', 'LABEL_INFO_SELECT',
+ 'LABEL_INFO_TABLE', 'LAYER_INFO_ARROWS', 'LAYER_INFO_CENTROIDS',
+ 'LAYER_INFO_COSMETIC', 'LAYER_INFO_DISPLAY',
+ 'LAYER_INFO_DISPLAY_GLOBAL', 'LAYER_INFO_DISPLAY_GRAPHIC',
+ 'LAYER_INFO_DISPLAY_OFF', 'LAYER_INFO_DISPLAY_VALUE',
+ 'LAYER_INFO_EDITABLE', 'LAYER_INFO_HOTLINK_COUNT',
+ 'LAYER_INFO_HOTLINK_EXPR', 'LAYER_INFO_HOTLINK_MODE',
+ 'LAYER_INFO_HOTLINK_RELATIVE', 'LAYER_INFO_LABEL_ALPHA',
+ 'LAYER_INFO_LABEL_ORIENT_CURVED',
+ 'LAYER_INFO_LABEL_ORIENT_HORIZONTAL',
+ 'LAYER_INFO_LABEL_ORIENT_PARALLEL', 'LAYER_INFO_LAYER_ALPHA',
+ 'LAYER_INFO_LAYER_TRANSLUCENCY', 'LAYER_INFO_LBL_AUTODISPLAY',
+ 'LAYER_INFO_LBL_CURFONT', 'LAYER_INFO_LBL_DUPLICATES',
+ 'LAYER_INFO_LBL_EXPR', 'LAYER_INFO_LBL_FONT', 'LAYER_INFO_LBL_LT',
+ 'LAYER_INFO_LBL_LT_ARROW', 'LAYER_INFO_LBL_LT_NONE',
+ 'LAYER_INFO_LBL_LT_SIMPLE', 'LAYER_INFO_LBL_MAX',
+ 'LAYER_INFO_LBL_OFFSET', 'LAYER_INFO_LBL_ORIENTATION',
+ 'LAYER_INFO_LBL_OVERLAP', 'LAYER_INFO_LBL_PARALLEL',
+ 'LAYER_INFO_LBL_PARTIALSEGS', 'LAYER_INFO_LBL_POS',
+ 'LAYER_INFO_LBL_POS_BC', 'LAYER_INFO_LBL_POS_BL',
+ 'LAYER_INFO_LBL_POS_BR', 'LAYER_INFO_LBL_POS_CC',
+ 'LAYER_INFO_LBL_POS_CL', 'LAYER_INFO_LBL_POS_CR',
+ 'LAYER_INFO_LBL_POS_TC', 'LAYER_INFO_LBL_POS_TL',
+ 'LAYER_INFO_LBL_POS_TR', 'LAYER_INFO_LBL_VIS_OFF',
+ 'LAYER_INFO_LBL_VIS_ON', 'LAYER_INFO_LBL_VIS_ZOOM',
+ 'LAYER_INFO_LBL_VISIBILITY', 'LAYER_INFO_LBL_ZOOM_MAX',
+ 'LAYER_INFO_LBL_ZOOM_MIN', 'LAYER_INFO_NAME', 'LAYER_INFO_NODES',
+ 'LAYER_INFO_OVR_BRUSH', 'LAYER_INFO_OVR_FONT',
+ 'LAYER_INFO_OVR_LINE', 'LAYER_INFO_OVR_PEN',
+ 'LAYER_INFO_OVR_SYMBOL', 'LAYER_INFO_PATH',
+ 'LAYER_INFO_SELECTABLE', 'LAYER_INFO_TYPE',
+ 'LAYER_INFO_TYPE_COSMETIC', 'LAYER_INFO_TYPE_GRID',
+ 'LAYER_INFO_TYPE_IMAGE', 'LAYER_INFO_TYPE_NORMAL',
+ 'LAYER_INFO_TYPE_THEMATIC', 'LAYER_INFO_TYPE_WMS',
+ 'LAYER_INFO_ZOOM_LAYERED', 'LAYER_INFO_ZOOM_MAX',
+ 'LAYER_INFO_ZOOM_MIN', 'LEGEND_INFO_MAP_ID',
+ 'LEGEND_INFO_NUM_FRAMES', 'LEGEND_INFO_ORIENTATION',
+ 'LEGEND_INFO_STYLE_SAMPLE_SIZE', 'LEGEND_STYLE_INFO_FONT',
+ 'LEGEND_STYLE_INFO_OBJ', 'LEGEND_STYLE_INFO_TEXT',
+ 'LOCATE_ABB_FILE', 'LOCATE_CLR_FILE', 'LOCATE_CUSTSYMB_DIR',
+ 'LOCATE_DEF_WOR', 'LOCATE_FNT_FILE', 'LOCATE_GEOCODE_SERVERLIST',
+ 'LOCATE_GRAPH_DIR', 'LOCATE_LAYOUT_TEMPLATE_DIR',
+ 'LOCATE_MNU_FILE', 'LOCATE_PEN_FILE', 'LOCATE_PREF_FILE',
+ 'LOCATE_PRJ_FILE', 'LOCATE_ROUTING_SERVERLIST',
+ 'LOCATE_THMTMPLT_DIR', 'LOCATE_WFS_SERVERLIST',
+ 'LOCATE_WMS_SERVERLIST', 'M_3DMAP_CLONE_VIEW',
+ 'M_3DMAP_PREVIOUS_VIEW', 'M_3DMAP_PROPERTIES',
+ 'M_3DMAP_REFRESH_GRID_TEXTURE', 'M_3DMAP_VIEW_ENTIRE_GRID',
+ 'M_3DMAP_VIEWPOINT_CONTROL', 'M_3DMAP_WIREFRAME',
+ 'M_ANALYZE_CALC_STATISTICS', 'M_ANALYZE_CUSTOMIZE_LEGEND',
+ 'M_ANALYZE_FIND', 'M_ANALYZE_FIND_SELECTION',
+ 'M_ANALYZE_INVERTSELECT', 'M_ANALYZE_SELECT',
+ 'M_ANALYZE_SELECTALL', 'M_ANALYZE_SHADE', 'M_ANALYZE_SQLQUERY',
+ 'M_ANALYZE_UNSELECT', 'M_BROWSE_EDIT', 'M_BROWSE_GRID',
+ 'M_BROWSE_NEW_RECORD', 'M_BROWSE_OPTIONS', 'M_BROWSE_PICK_FIELDS',
+ 'M_DBMS_OPEN_ODBC', 'M_EDIT_CLEAR', 'M_EDIT_CLEAROBJ',
+ 'M_EDIT_COPY', 'M_EDIT_CUT', 'M_EDIT_GETINFO', 'M_EDIT_NEW_ROW',
+ 'M_EDIT_PASTE', 'M_EDIT_PREFERENCES', 'M_EDIT_PREFERENCES_COUNTRY',
+ 'M_EDIT_PREFERENCES_FILE', 'M_EDIT_PREFERENCES_IMAGE_PROC',
+ 'M_EDIT_PREFERENCES_LAYOUT', 'M_EDIT_PREFERENCES_LEGEND',
+ 'M_EDIT_PREFERENCES_MAP', 'M_EDIT_PREFERENCES_OUTPUT',
+ 'M_EDIT_PREFERENCES_PATH', 'M_EDIT_PREFERENCES_PRINTER',
+ 'M_EDIT_PREFERENCES_STYLES', 'M_EDIT_PREFERENCES_SYSTEM',
+ 'M_EDIT_PREFERENCES_WEBSERVICES', 'M_EDIT_RESHAPE', 'M_EDIT_UNDO',
+ 'M_FILE_ABOUT', 'M_FILE_ADD_WORKSPACE', 'M_FILE_CLOSE',
+ 'M_FILE_CLOSE_ALL', 'M_FILE_CLOSE_ODBC', 'M_FILE_EXIT',
+ 'M_FILE_HELP', 'M_FILE_NEW', 'M_FILE_OPEN', 'M_FILE_OPEN_ODBC',
+ 'M_FILE_OPEN_ODBC_CONN', 'M_FILE_OPEN_UNIVERSAL_DATA',
+ 'M_FILE_OPEN_WFS', 'M_FILE_OPEN_WMS', 'M_FILE_PAGE_SETUP',
+ 'M_FILE_PRINT', 'M_FILE_PRINT_SETUP', 'M_FILE_REVERT',
+ 'M_FILE_RUN', 'M_FILE_SAVE', 'M_FILE_SAVE_COPY_AS',
+ 'M_FILE_SAVE_QUERY', 'M_FILE_SAVE_WINDOW_AS',
+ 'M_FILE_SAVE_WORKSPACE', 'M_FORMAT_CUSTOM_COLORS',
+ 'M_FORMAT_PICK_FILL', 'M_FORMAT_PICK_FONT', 'M_FORMAT_PICK_LINE',
+ 'M_FORMAT_PICK_SYMBOL', 'M_GRAPH_3D_VIEWING_ANGLE',
+ 'M_GRAPH_FORMATING', 'M_GRAPH_GENERAL_OPTIONS',
+ 'M_GRAPH_GRID_SCALES', 'M_GRAPH_LABEL_AXIS',
+ 'M_GRAPH_SAVE_AS_TEMPLATE', 'M_GRAPH_SERIES',
+ 'M_GRAPH_SERIES_OPTIONS', 'M_GRAPH_TITLES', 'M_GRAPH_TYPE',
+ 'M_GRAPH_VALUE_AXIS', 'M_HELP_ABOUT', 'M_HELP_CHECK_FOR_UPDATE',
+ 'M_HELP_CONNECT_MIFORUM', 'M_HELP_CONTENTS',
+ 'M_HELP_CONTEXTSENSITIVE', 'M_HELP_HELPMODE',
+ 'M_HELP_MAPINFO_3DGRAPH_HELP', 'M_HELP_MAPINFO_CONNECT_SERVICES',
+ 'M_HELP_MAPINFO_WWW', 'M_HELP_MAPINFO_WWW_STORE',
+ 'M_HELP_MAPINFO_WWW_TUTORIAL', 'M_HELP_SEARCH',
+ 'M_HELP_TECHSUPPORT', 'M_HELP_USE_HELP', 'M_LAYOUT_ACTUAL',
+ 'M_LAYOUT_ALIGN', 'M_LAYOUT_AUTOSCROLL_ONOFF',
+ 'M_LAYOUT_BRING2FRONT', 'M_LAYOUT_CHANGE_VIEW',
+ 'M_LAYOUT_DISPLAYOPTIONS', 'M_LAYOUT_DROPSHADOWS',
+ 'M_LAYOUT_ENTIRE', 'M_LAYOUT_LAYOUT_SIZE', 'M_LAYOUT_PREVIOUS',
+ 'M_LAYOUT_SEND2BACK', 'M_LEGEND_ADD_FRAMES', 'M_LEGEND_DELETE',
+ 'M_LEGEND_PROPERTIES', 'M_LEGEND_REFRESH', 'M_MAP_AUTOLABEL',
+ 'M_MAP_AUTOSCROLL_ONOFF', 'M_MAP_CHANGE_VIEW',
+ 'M_MAP_CLEAR_COSMETIC', 'M_MAP_CLEAR_CUSTOM_LABELS',
+ 'M_MAP_CLIP_REGION_ONOFF', 'M_MAP_CLONE_MAPPER',
+ 'M_MAP_CREATE_3DMAP', 'M_MAP_CREATE_LEGEND',
+ 'M_MAP_CREATE_PRISMMAP', 'M_MAP_ENTIRE_LAYER',
+ 'M_MAP_LAYER_CONTROL', 'M_MAP_MODIFY_THEMATIC', 'M_MAP_OPTIONS',
+ 'M_MAP_PREVIOUS', 'M_MAP_PROJECTION', 'M_MAP_SAVE_COSMETIC',
+ 'M_MAP_SET_CLIP_REGION', 'M_MAP_SETUNITS', 'M_MAP_SETUPDIGITIZER',
+ 'M_MAP_THEMATIC', 'M_MAPBASIC_CLEAR', 'M_MAPBASIC_SAVECONTENTS',
+ 'M_OBJECTS_BREAKPOLY', 'M_OBJECTS_BUFFER',
+ 'M_OBJECTS_CHECK_REGIONS', 'M_OBJECTS_CLEAN',
+ 'M_OBJECTS_CLEAR_TARGET', 'M_OBJECTS_COMBINE',
+ 'M_OBJECTS_CONVEX_HULL', 'M_OBJECTS_CVT_PGON',
+ 'M_OBJECTS_CVT_PLINE', 'M_OBJECTS_DISAGG',
+ 'M_OBJECTS_DRIVE_REGION', 'M_OBJECTS_ENCLOSE', 'M_OBJECTS_ERASE',
+ 'M_OBJECTS_ERASE_OUT', 'M_OBJECTS_MERGE', 'M_OBJECTS_OFFSET',
+ 'M_OBJECTS_OVERLAY', 'M_OBJECTS_POLYLINE_SPLIT',
+ 'M_OBJECTS_POLYLINE_SPLIT_AT_NODE', 'M_OBJECTS_RESHAPE',
+ 'M_OBJECTS_ROTATE', 'M_OBJECTS_SET_TARGET', 'M_OBJECTS_SMOOTH',
+ 'M_OBJECTS_SNAP', 'M_OBJECTS_SPLIT', 'M_OBJECTS_UNSMOOTH',
+ 'M_OBJECTS_VORONOI', 'M_ORACLE_CREATE_WORKSPACE',
+ 'M_ORACLE_DELETE_WORKSPACE', 'M_ORACLE_MERGE_PARENT',
+ 'M_ORACLE_REFRESH_FROM_PARENT', 'M_ORACLE_VERSION_ENABLE_OFF',
+ 'M_ORACLE_VERSION_ENABLE_ON', 'M_QUERY_CALC_STATISTICS',
+ 'M_QUERY_FIND', 'M_QUERY_FIND_ADDRESS', 'M_QUERY_FIND_SELECTION',
+ 'M_QUERY_FIND_SELECTION_CURRENT_MAP', 'M_QUERY_INVERTSELECT',
+ 'M_QUERY_SELECT', 'M_QUERY_SELECTALL', 'M_QUERY_SQLQUERY',
+ 'M_QUERY_UNSELECT', 'M_REDISTRICT_ADD', 'M_REDISTRICT_ASSIGN',
+ 'M_REDISTRICT_DELETE', 'M_REDISTRICT_OPTIONS',
+ 'M_REDISTRICT_TARGET', 'M_SENDMAIL_CURRENTWINDOW',
+ 'M_SENDMAIL_WORKSPACE', 'M_TABLE_APPEND', 'M_TABLE_BUFFER',
+ 'M_TABLE_CHANGESYMBOL', 'M_TABLE_CREATE_POINTS', 'M_TABLE_DELETE',
+ 'M_TABLE_DRIVE_REGION', 'M_TABLE_EXPORT', 'M_TABLE_GEOCODE',
+ 'M_TABLE_IMPORT', 'M_TABLE_MAKEMAPPABLE',
+ 'M_TABLE_MERGE_USING_COLUMN', 'M_TABLE_MODIFY_STRUCTURE',
+ 'M_TABLE_PACK', 'M_TABLE_RASTER_REG', 'M_TABLE_RASTER_STYLE',
+ 'M_TABLE_REFRESH', 'M_TABLE_RENAME',
+ 'M_TABLE_UNIVERSAL_DATA_REFRESH', 'M_TABLE_UNLINK',
+ 'M_TABLE_UPDATE_COLUMN', 'M_TABLE_VORONOI', 'M_TABLE_WEB_GEOCODE',
+ 'M_TABLE_WFS_PROPS', 'M_TABLE_WFS_REFRESH', 'M_TABLE_WMS_PROPS',
+ 'M_TOOLS_ADD_NODE', 'M_TOOLS_ARC', 'M_TOOLS_CRYSTAL_REPORTS_NEW',
+ 'M_TOOLS_CRYSTAL_REPORTS_OPEN', 'M_TOOLS_DRAGWINDOW',
+ 'M_TOOLS_ELLIPSE', 'M_TOOLS_EXPAND', 'M_TOOLS_FRAME',
+ 'M_TOOLS_HOTLINK', 'M_TOOLS_LABELER', 'M_TOOLS_LINE',
+ 'M_TOOLS_MAPBASIC', 'M_TOOLS_PNT_QUERY', 'M_TOOLS_POINT',
+ 'M_TOOLS_POLYGON', 'M_TOOLS_POLYLINE', 'M_TOOLS_RASTER_REG',
+ 'M_TOOLS_RECENTER', 'M_TOOLS_RECTANGLE', 'M_TOOLS_ROUNDEDRECT',
+ 'M_TOOLS_RULER', 'M_TOOLS_RUN', 'M_TOOLS_SEARCH_BOUNDARY',
+ 'M_TOOLS_SEARCH_POLYGON', 'M_TOOLS_SEARCH_RADIUS',
+ 'M_TOOLS_SEARCH_RECT', 'M_TOOLS_SELECTOR', 'M_TOOLS_SHRINK',
+ 'M_TOOLS_TEXT', 'M_TOOLS_TOOL_MANAGER', 'M_WINDOW_ARRANGEICONS',
+ 'M_WINDOW_BROWSE', 'M_WINDOW_BUTTONPAD', 'M_WINDOW_CASCADE',
+ 'M_WINDOW_EXPORT_WINDOW', 'M_WINDOW_FIRST', 'M_WINDOW_GRAPH',
+ 'M_WINDOW_LAYOUT', 'M_WINDOW_LEGEND', 'M_WINDOW_MAP',
+ 'M_WINDOW_MAPBASIC', 'M_WINDOW_MORE', 'M_WINDOW_REDISTRICT',
+ 'M_WINDOW_REDRAW', 'M_WINDOW_STATISTICS', 'M_WINDOW_STATUSBAR',
+ 'M_WINDOW_TILE', 'M_WINDOW_TOOL_PALETTE', 'MAGENTA',
+ 'MAP3D_INFO_BACKGROUND', 'MAP3D_INFO_CAMERA_CLIP_FAR',
+ 'MAP3D_INFO_CAMERA_CLIP_NEAR', 'MAP3D_INFO_CAMERA_FOCAL_X',
+ 'MAP3D_INFO_CAMERA_FOCAL_Y', 'MAP3D_INFO_CAMERA_FOCAL_Z',
+ 'MAP3D_INFO_CAMERA_VPN_1', 'MAP3D_INFO_CAMERA_VPN_2',
+ 'MAP3D_INFO_CAMERA_VPN_3', 'MAP3D_INFO_CAMERA_VU_1',
+ 'MAP3D_INFO_CAMERA_VU_2', 'MAP3D_INFO_CAMERA_VU_3',
+ 'MAP3D_INFO_CAMERA_X', 'MAP3D_INFO_CAMERA_Y',
+ 'MAP3D_INFO_CAMERA_Z', 'MAP3D_INFO_LIGHT_COLOR',
+ 'MAP3D_INFO_LIGHT_X', 'MAP3D_INFO_LIGHT_Y', 'MAP3D_INFO_LIGHT_Z',
+ 'MAP3D_INFO_RESOLUTION_X', 'MAP3D_INFO_RESOLUTION_Y',
+ 'MAP3D_INFO_SCALE', 'MAP3D_INFO_UNITS', 'MAPPER_INFO_AREAUNITS',
+ 'MAPPER_INFO_CENTERX', 'MAPPER_INFO_CENTERY',
+ 'MAPPER_INFO_CLIP_DISPLAY_ALL', 'MAPPER_INFO_CLIP_DISPLAY_POLYOBJ',
+ 'MAPPER_INFO_CLIP_OVERLAY', 'MAPPER_INFO_CLIP_REGION',
+ 'MAPPER_INFO_CLIP_TYPE', 'MAPPER_INFO_COORDSYS_CLAUSE',
+ 'MAPPER_INFO_COORDSYS_CLAUSE_WITH_BOUNDS',
+ 'MAPPER_INFO_COORDSYS_NAME', 'MAPPER_INFO_DISPLAY',
+ 'MAPPER_INFO_DISPLAY_DECIMAL', 'MAPPER_INFO_DISPLAY_DEGMINSEC',
+ 'MAPPER_INFO_DISPLAY_DMS', 'MAPPER_INFO_DISPLAY_MGRS',
+ 'MAPPER_INFO_DISPLAY_POSITION', 'MAPPER_INFO_DISPLAY_SCALE',
+ 'MAPPER_INFO_DISPLAY_ZOOM', 'MAPPER_INFO_DIST_CALC_TYPE',
+ 'MAPPER_INFO_DIST_CARTESIAN', 'MAPPER_INFO_DIST_SPHERICAL',
+ 'MAPPER_INFO_DISTUNITS', 'MAPPER_INFO_EDIT_LAYER',
+ 'MAPPER_INFO_LAYERS', 'MAPPER_INFO_MAXX', 'MAPPER_INFO_MAXY',
+ 'MAPPER_INFO_MERGE_MAP', 'MAPPER_INFO_MINX', 'MAPPER_INFO_MINY',
+ 'MAPPER_INFO_MOVE_DUPLICATE_NODES', 'MAPPER_INFO_NUM_THEMATIC',
+ 'MAPPER_INFO_REPROJECTION', 'MAPPER_INFO_RESAMPLING',
+ 'MAPPER_INFO_SCALE', 'MAPPER_INFO_SCROLLBARS',
+ 'MAPPER_INFO_XYUNITS', 'MAPPER_INFO_ZOOM', 'MAX_STRING_LENGTH',
+ 'MENUITEM_INFO_ACCELERATOR', 'MENUITEM_INFO_CHECKABLE',
+ 'MENUITEM_INFO_CHECKED', 'MENUITEM_INFO_ENABLED',
+ 'MENUITEM_INFO_HANDLER', 'MENUITEM_INFO_HELPMSG',
+ 'MENUITEM_INFO_ID', 'MENUITEM_INFO_SHOWHIDEABLE',
+ 'MENUITEM_INFO_TEXT', 'MI_CURSOR_ARROW', 'MI_CURSOR_CHANGE_WIDTH',
+ 'MI_CURSOR_CROSSHAIR', 'MI_CURSOR_DRAG_OBJ',
+ 'MI_CURSOR_FINGER_LEFT', 'MI_CURSOR_FINGER_UP',
+ 'MI_CURSOR_GRABBER', 'MI_CURSOR_IBEAM', 'MI_CURSOR_IBEAM_CROSS',
+ 'MI_CURSOR_ZOOM_IN', 'MI_CURSOR_ZOOM_OUT', 'MI_ICON_ADD_NODE',
+ 'MI_ICON_ARC', 'MI_ICON_ARROW', 'MI_ICON_ARROW_1',
+ 'MI_ICON_ARROW_10', 'MI_ICON_ARROW_11', 'MI_ICON_ARROW_12',
+ 'MI_ICON_ARROW_13', 'MI_ICON_ARROW_14', 'MI_ICON_ARROW_15',
+ 'MI_ICON_ARROW_16', 'MI_ICON_ARROW_17', 'MI_ICON_ARROW_18',
+ 'MI_ICON_ARROW_19', 'MI_ICON_ARROW_2', 'MI_ICON_ARROW_20',
+ 'MI_ICON_ARROW_21', 'MI_ICON_ARROW_3', 'MI_ICON_ARROW_4',
+ 'MI_ICON_ARROW_5', 'MI_ICON_ARROW_6', 'MI_ICON_ARROW_7',
+ 'MI_ICON_ARROW_8', 'MI_ICON_ARROW_9', 'MI_ICON_CLIP_MODE',
+ 'MI_ICON_CLIP_REGION', 'MI_ICON_CLOSE_ALL',
+ 'MI_ICON_COMMUNICATION_1', 'MI_ICON_COMMUNICATION_10',
+ 'MI_ICON_COMMUNICATION_11', 'MI_ICON_COMMUNICATION_12',
+ 'MI_ICON_COMMUNICATION_2', 'MI_ICON_COMMUNICATION_3',
+ 'MI_ICON_COMMUNICATION_4', 'MI_ICON_COMMUNICATION_5',
+ 'MI_ICON_COMMUNICATION_6', 'MI_ICON_COMMUNICATION_7',
+ 'MI_ICON_COMMUNICATION_8', 'MI_ICON_COMMUNICATION_9',
+ 'MI_ICON_COMPASS_CIRCLE_TA', 'MI_ICON_COMPASS_CONTRACT',
+ 'MI_ICON_COMPASS_EXPAND', 'MI_ICON_COMPASS_POLY_TA',
+ 'MI_ICON_COMPASS_TAG', 'MI_ICON_COMPASS_UNTAG', 'MI_ICON_COPY',
+ 'MI_ICON_CROSSHAIR', 'MI_ICON_CUT', 'MI_ICON_DISTRICT_MANY',
+ 'MI_ICON_DISTRICT_SAME', 'MI_ICON_DRAG_HANDLE', 'MI_ICON_ELLIPSE',
+ 'MI_ICON_EMERGENCY_1', 'MI_ICON_EMERGENCY_10',
+ 'MI_ICON_EMERGENCY_11', 'MI_ICON_EMERGENCY_12',
+ 'MI_ICON_EMERGENCY_13', 'MI_ICON_EMERGENCY_14',
+ 'MI_ICON_EMERGENCY_15', 'MI_ICON_EMERGENCY_16',
+ 'MI_ICON_EMERGENCY_17', 'MI_ICON_EMERGENCY_18',
+ 'MI_ICON_EMERGENCY_2', 'MI_ICON_EMERGENCY_3',
+ 'MI_ICON_EMERGENCY_4', 'MI_ICON_EMERGENCY_5',
+ 'MI_ICON_EMERGENCY_6', 'MI_ICON_EMERGENCY_7',
+ 'MI_ICON_EMERGENCY_8', 'MI_ICON_EMERGENCY_9', 'MI_ICON_GRABBER',
+ 'MI_ICON_GRAPH_SELECT', 'MI_ICON_HELP', 'MI_ICON_HOT_LINK',
+ 'MI_ICON_INFO', 'MI_ICON_INVERTSELECT', 'MI_ICON_LABEL',
+ 'MI_ICON_LAYERS', 'MI_ICON_LEGEND', 'MI_ICON_LETTERS_A',
+ 'MI_ICON_LETTERS_B', 'MI_ICON_LETTERS_C', 'MI_ICON_LETTERS_D',
+ 'MI_ICON_LETTERS_E', 'MI_ICON_LETTERS_F', 'MI_ICON_LETTERS_G',
+ 'MI_ICON_LETTERS_H', 'MI_ICON_LETTERS_I', 'MI_ICON_LETTERS_J',
+ 'MI_ICON_LETTERS_K', 'MI_ICON_LETTERS_L', 'MI_ICON_LETTERS_M',
+ 'MI_ICON_LETTERS_N', 'MI_ICON_LETTERS_O', 'MI_ICON_LETTERS_P',
+ 'MI_ICON_LETTERS_Q', 'MI_ICON_LETTERS_R', 'MI_ICON_LETTERS_S',
+ 'MI_ICON_LETTERS_T', 'MI_ICON_LETTERS_U', 'MI_ICON_LETTERS_V',
+ 'MI_ICON_LETTERS_W', 'MI_ICON_LETTERS_X', 'MI_ICON_LETTERS_Y',
+ 'MI_ICON_LETTERS_Z', 'MI_ICON_LINE', 'MI_ICON_LINE_STYLE',
+ 'MI_ICON_MAPSYMB_1', 'MI_ICON_MAPSYMB_10', 'MI_ICON_MAPSYMB_11',
+ 'MI_ICON_MAPSYMB_12', 'MI_ICON_MAPSYMB_13', 'MI_ICON_MAPSYMB_14',
+ 'MI_ICON_MAPSYMB_15', 'MI_ICON_MAPSYMB_16', 'MI_ICON_MAPSYMB_17',
+ 'MI_ICON_MAPSYMB_18', 'MI_ICON_MAPSYMB_19', 'MI_ICON_MAPSYMB_2',
+ 'MI_ICON_MAPSYMB_20', 'MI_ICON_MAPSYMB_21', 'MI_ICON_MAPSYMB_22',
+ 'MI_ICON_MAPSYMB_23', 'MI_ICON_MAPSYMB_24', 'MI_ICON_MAPSYMB_25',
+ 'MI_ICON_MAPSYMB_26', 'MI_ICON_MAPSYMB_3', 'MI_ICON_MAPSYMB_4',
+ 'MI_ICON_MAPSYMB_5', 'MI_ICON_MAPSYMB_6', 'MI_ICON_MAPSYMB_7',
+ 'MI_ICON_MAPSYMB_8', 'MI_ICON_MAPSYMB_9', 'MI_ICON_MARITIME_1',
+ 'MI_ICON_MARITIME_10', 'MI_ICON_MARITIME_2', 'MI_ICON_MARITIME_3',
+ 'MI_ICON_MARITIME_4', 'MI_ICON_MARITIME_5', 'MI_ICON_MARITIME_6',
+ 'MI_ICON_MARITIME_7', 'MI_ICON_MARITIME_8', 'MI_ICON_MARITIME_9',
+ 'MI_ICON_MB_1', 'MI_ICON_MB_10', 'MI_ICON_MB_11', 'MI_ICON_MB_12',
+ 'MI_ICON_MB_13', 'MI_ICON_MB_14', 'MI_ICON_MB_2', 'MI_ICON_MB_3',
+ 'MI_ICON_MB_4', 'MI_ICON_MB_5', 'MI_ICON_MB_6', 'MI_ICON_MB_7',
+ 'MI_ICON_MB_8', 'MI_ICON_MB_9', 'MI_ICON_MISC_1',
+ 'MI_ICON_MISC_10', 'MI_ICON_MISC_11', 'MI_ICON_MISC_12',
+ 'MI_ICON_MISC_13', 'MI_ICON_MISC_14', 'MI_ICON_MISC_15',
+ 'MI_ICON_MISC_16', 'MI_ICON_MISC_17', 'MI_ICON_MISC_18',
+ 'MI_ICON_MISC_19', 'MI_ICON_MISC_2', 'MI_ICON_MISC_20',
+ 'MI_ICON_MISC_21', 'MI_ICON_MISC_22', 'MI_ICON_MISC_23',
+ 'MI_ICON_MISC_24', 'MI_ICON_MISC_25', 'MI_ICON_MISC_26',
+ 'MI_ICON_MISC_27', 'MI_ICON_MISC_28', 'MI_ICON_MISC_29',
+ 'MI_ICON_MISC_3', 'MI_ICON_MISC_30', 'MI_ICON_MISC_31',
+ 'MI_ICON_MISC_4', 'MI_ICON_MISC_5', 'MI_ICON_MISC_6',
+ 'MI_ICON_MISC_7', 'MI_ICON_MISC_8', 'MI_ICON_MISC_9',
+ 'MI_ICON_NEW_DOC', 'MI_ICON_NUMBERS_1', 'MI_ICON_NUMBERS_10',
+ 'MI_ICON_NUMBERS_11', 'MI_ICON_NUMBERS_12', 'MI_ICON_NUMBERS_13',
+ 'MI_ICON_NUMBERS_14', 'MI_ICON_NUMBERS_15', 'MI_ICON_NUMBERS_16',
+ 'MI_ICON_NUMBERS_17', 'MI_ICON_NUMBERS_18', 'MI_ICON_NUMBERS_19',
+ 'MI_ICON_NUMBERS_2', 'MI_ICON_NUMBERS_20', 'MI_ICON_NUMBERS_21',
+ 'MI_ICON_NUMBERS_22', 'MI_ICON_NUMBERS_23', 'MI_ICON_NUMBERS_24',
+ 'MI_ICON_NUMBERS_25', 'MI_ICON_NUMBERS_26', 'MI_ICON_NUMBERS_27',
+ 'MI_ICON_NUMBERS_28', 'MI_ICON_NUMBERS_29', 'MI_ICON_NUMBERS_3',
+ 'MI_ICON_NUMBERS_30', 'MI_ICON_NUMBERS_31', 'MI_ICON_NUMBERS_32',
+ 'MI_ICON_NUMBERS_4', 'MI_ICON_NUMBERS_5', 'MI_ICON_NUMBERS_6',
+ 'MI_ICON_NUMBERS_7', 'MI_ICON_NUMBERS_8', 'MI_ICON_NUMBERS_9',
+ 'MI_ICON_ODBC_DISCONNECT', 'MI_ICON_ODBC_MAPPABLE',
+ 'MI_ICON_ODBC_OPEN', 'MI_ICON_ODBC_REFRESH', 'MI_ICON_ODBC_SYMBOL',
+ 'MI_ICON_ODBC_UNLINK', 'MI_ICON_OPEN_FILE', 'MI_ICON_OPEN_WOR',
+ 'MI_ICON_OPENWFS', 'MI_ICON_OPENWMS', 'MI_ICON_PASTE',
+ 'MI_ICON_POLYGON', 'MI_ICON_POLYLINE', 'MI_ICON_PRINT',
+ 'MI_ICON_REALESTATE_1', 'MI_ICON_REALESTATE_10',
+ 'MI_ICON_REALESTATE_11', 'MI_ICON_REALESTATE_12',
+ 'MI_ICON_REALESTATE_13', 'MI_ICON_REALESTATE_14',
+ 'MI_ICON_REALESTATE_15', 'MI_ICON_REALESTATE_16',
+ 'MI_ICON_REALESTATE_17', 'MI_ICON_REALESTATE_18',
+ 'MI_ICON_REALESTATE_19', 'MI_ICON_REALESTATE_2',
+ 'MI_ICON_REALESTATE_20', 'MI_ICON_REALESTATE_21',
+ 'MI_ICON_REALESTATE_22', 'MI_ICON_REALESTATE_23',
+ 'MI_ICON_REALESTATE_3', 'MI_ICON_REALESTATE_4',
+ 'MI_ICON_REALESTATE_5', 'MI_ICON_REALESTATE_6',
+ 'MI_ICON_REALESTATE_7', 'MI_ICON_REALESTATE_8',
+ 'MI_ICON_REALESTATE_9', 'MI_ICON_RECT', 'MI_ICON_REGION_STYLE',
+ 'MI_ICON_RESHAPE', 'MI_ICON_ROUND_RECT', 'MI_ICON_RULER',
+ 'MI_ICON_RUN', 'MI_ICON_SAVE_FILE', 'MI_ICON_SAVE_WIN',
+ 'MI_ICON_SAVE_WOR', 'MI_ICON_SEARCH_BDY', 'MI_ICON_SEARCH_POLYGON',
+ 'MI_ICON_SEARCH_RADIUS', 'MI_ICON_SEARCH_RECT', 'MI_ICON_SIGNS_1',
+ 'MI_ICON_SIGNS_10', 'MI_ICON_SIGNS_11', 'MI_ICON_SIGNS_12',
+ 'MI_ICON_SIGNS_13', 'MI_ICON_SIGNS_14', 'MI_ICON_SIGNS_15',
+ 'MI_ICON_SIGNS_16', 'MI_ICON_SIGNS_17', 'MI_ICON_SIGNS_18',
+ 'MI_ICON_SIGNS_19', 'MI_ICON_SIGNS_2', 'MI_ICON_SIGNS_3',
+ 'MI_ICON_SIGNS_4', 'MI_ICON_SIGNS_5', 'MI_ICON_SIGNS_6',
+ 'MI_ICON_SIGNS_7', 'MI_ICON_SIGNS_8', 'MI_ICON_SIGNS_9',
+ 'MI_ICON_STATISTICS', 'MI_ICON_SYMBOL', 'MI_ICON_SYMBOL_STYLE',
+ 'MI_ICON_TEXT', 'MI_ICON_TEXT_STYLE', 'MI_ICON_TRANSPORT_1',
+ 'MI_ICON_TRANSPORT_10', 'MI_ICON_TRANSPORT_11',
+ 'MI_ICON_TRANSPORT_12', 'MI_ICON_TRANSPORT_13',
+ 'MI_ICON_TRANSPORT_14', 'MI_ICON_TRANSPORT_15',
+ 'MI_ICON_TRANSPORT_16', 'MI_ICON_TRANSPORT_17',
+ 'MI_ICON_TRANSPORT_18', 'MI_ICON_TRANSPORT_19',
+ 'MI_ICON_TRANSPORT_2', 'MI_ICON_TRANSPORT_20',
+ 'MI_ICON_TRANSPORT_21', 'MI_ICON_TRANSPORT_22',
+ 'MI_ICON_TRANSPORT_23', 'MI_ICON_TRANSPORT_24',
+ 'MI_ICON_TRANSPORT_25', 'MI_ICON_TRANSPORT_26',
+ 'MI_ICON_TRANSPORT_27', 'MI_ICON_TRANSPORT_3',
+ 'MI_ICON_TRANSPORT_4', 'MI_ICON_TRANSPORT_5',
+ 'MI_ICON_TRANSPORT_6', 'MI_ICON_TRANSPORT_7',
+ 'MI_ICON_TRANSPORT_8', 'MI_ICON_TRANSPORT_9', 'MI_ICON_UNDO',
+ 'MI_ICON_UNSELECT_ALL', 'MI_ICON_WINDOW_FRAME', 'MI_ICON_WRENCH',
+ 'MI_ICON_ZOOM_IN', 'MI_ICON_ZOOM_OUT', 'MI_ICON_ZOOM_QUESTION',
+ 'MI_ICONS_MAPS_1', 'MI_ICONS_MAPS_10', 'MI_ICONS_MAPS_11',
+ 'MI_ICONS_MAPS_12', 'MI_ICONS_MAPS_13', 'MI_ICONS_MAPS_14',
+ 'MI_ICONS_MAPS_15', 'MI_ICONS_MAPS_2', 'MI_ICONS_MAPS_3',
+ 'MI_ICONS_MAPS_4', 'MI_ICONS_MAPS_5', 'MI_ICONS_MAPS_6',
+ 'MI_ICONS_MAPS_7', 'MI_ICONS_MAPS_8', 'MI_ICONS_MAPS_9',
+ 'MIPLATFORM_HP', 'MIPLATFORM_MAC68K', 'MIPLATFORM_POWERMAC',
+ 'MIPLATFORM_SPECIAL', 'MIPLATFORM_SUN', 'MIPLATFORM_WIN16',
+ 'MIPLATFORM_WIN32', 'MODE_APPEND', 'MODE_BINARY', 'MODE_INPUT',
+ 'MODE_OUTPUT', 'MODE_RANDOM', 'OBJ_ARC', 'OBJ_ELLIPSE',
+ 'OBJ_FRAME', 'OBJ_GEO_ARCBEGANGLE', 'OBJ_GEO_ARCENDANGLE',
+ 'OBJ_GEO_CENTROID', 'OBJ_GEO_LINEBEGX', 'OBJ_GEO_LINEBEGY',
+ 'OBJ_GEO_LINEENDX', 'OBJ_GEO_LINEENDY', 'OBJ_GEO_MAXX',
+ 'OBJ_GEO_MAXY', 'OBJ_GEO_MINX', 'OBJ_GEO_MINY', 'OBJ_GEO_POINTM',
+ 'OBJ_GEO_POINTX', 'OBJ_GEO_POINTY', 'OBJ_GEO_POINTZ',
+ 'OBJ_GEO_ROUNDRADIUS', 'OBJ_GEO_TEXTANGLE', 'OBJ_GEO_TEXTLINEX',
+ 'OBJ_GEO_TEXTLINEY', 'OBJ_INFO_BRUSH', 'OBJ_INFO_FILLFRAME',
+ 'OBJ_INFO_FRAMETITLE', 'OBJ_INFO_FRAMEWIN', 'OBJ_INFO_HAS_M',
+ 'OBJ_INFO_HAS_Z', 'OBJ_INFO_MPOINT', 'OBJ_INFO_NONEMPTY',
+ 'OBJ_INFO_NPNTS', 'OBJ_INFO_NPOLYGONS', 'OBJ_INFO_PEN',
+ 'OBJ_INFO_PLINE', 'OBJ_INFO_REGION', 'OBJ_INFO_SMOOTH',
+ 'OBJ_INFO_SYMBOL', 'OBJ_INFO_TEXTARROW', 'OBJ_INFO_TEXTFONT',
+ 'OBJ_INFO_TEXTJUSTIFY', 'OBJ_INFO_TEXTSPACING',
+ 'OBJ_INFO_TEXTSTRING', 'OBJ_INFO_TYPE', 'OBJ_INFO_Z_UNIT',
+ 'OBJ_INFO_Z_UNIT_SET', 'OBJ_LINE', 'OBJ_PLINE', 'OBJ_POINT',
+ 'OBJ_RECT', 'OBJ_REGION', 'OBJ_ROUNDRECT', 'OBJ_TEXT',
+ 'OBJ_TYPE_ARC', 'OBJ_TYPE_COLLECTION', 'OBJ_TYPE_ELLIPSE',
+ 'OBJ_TYPE_FRAME', 'OBJ_TYPE_LINE', 'OBJ_TYPE_MPOINT',
+ 'OBJ_TYPE_PLINE', 'OBJ_TYPE_POINT', 'OBJ_TYPE_RECT',
+ 'OBJ_TYPE_REGION', 'OBJ_TYPE_ROUNDRECT', 'OBJ_TYPE_TEXT',
+ 'ORIENTATION_CUSTOM', 'ORIENTATION_LANDSCAPE',
+ 'ORIENTATION_PORTRAIT', 'PEN_COLOR', 'PEN_INDEX',
+ 'PEN_INTERLEAVED', 'PEN_PATTERN', 'PEN_WIDTH', 'PLATFORM_MAC',
+ 'PLATFORM_MOTIF', 'PLATFORM_SPECIAL', 'PLATFORM_WIN',
+ 'PLATFORM_X11', 'PLATFORM_XOL', 'PRISMMAP_INFO_BACKGROUND',
+ 'PRISMMAP_INFO_CAMERA_CLIP_FAR', 'PRISMMAP_INFO_CAMERA_CLIP_NEAR',
+ 'PRISMMAP_INFO_CAMERA_FOCAL_X', 'PRISMMAP_INFO_CAMERA_FOCAL_Y',
+ 'PRISMMAP_INFO_CAMERA_FOCAL_Z', 'PRISMMAP_INFO_CAMERA_VPN_1',
+ 'PRISMMAP_INFO_CAMERA_VPN_2', 'PRISMMAP_INFO_CAMERA_VPN_3',
+ 'PRISMMAP_INFO_CAMERA_VU_1', 'PRISMMAP_INFO_CAMERA_VU_2',
+ 'PRISMMAP_INFO_CAMERA_VU_3', 'PRISMMAP_INFO_CAMERA_X',
+ 'PRISMMAP_INFO_CAMERA_Y', 'PRISMMAP_INFO_CAMERA_Z',
+ 'PRISMMAP_INFO_INFOTIP_EXPR', 'PRISMMAP_INFO_LIGHT_COLOR',
+ 'PRISMMAP_INFO_LIGHT_X', 'PRISMMAP_INFO_LIGHT_Y',
+ 'PRISMMAP_INFO_LIGHT_Z', 'PRISMMAP_INFO_SCALE', 'RAD_2_DEG',
+ 'RASTER_CONTROL_POINT_X', 'RASTER_CONTROL_POINT_Y',
+ 'RASTER_TAB_INFO_ALPHA', 'RASTER_TAB_INFO_BITS_PER_PIXEL',
+ 'RASTER_TAB_INFO_BRIGHTNESS', 'RASTER_TAB_INFO_CONTRAST',
+ 'RASTER_TAB_INFO_DISPLAY_TRANSPARENT', 'RASTER_TAB_INFO_GREYSCALE',
+ 'RASTER_TAB_INFO_HEIGHT', 'RASTER_TAB_INFO_IMAGE_CLASS',
+ 'RASTER_TAB_INFO_IMAGE_NAME', 'RASTER_TAB_INFO_IMAGE_TYPE',
+ 'RASTER_TAB_INFO_NUM_CONTROL_POINTS',
+ 'RASTER_TAB_INFO_TRANSPARENT_COLOR', 'RASTER_TAB_INFO_WIDTH',
+ 'RED', 'REGION_INFO_IS_CLOCKWISE', 'SEARCH_INFO_ROW',
+ 'SEARCH_INFO_TABLE', 'SECONDS_PER_DAY', 'SEL_INFO_NROWS',
+ 'SEL_INFO_SELNAME', 'SEL_INFO_TABLENAME',
+ 'SESSION_INFO_AREA_UNITS', 'SESSION_INFO_COORDSYS_CLAUSE',
+ 'SESSION_INFO_DISTANCE_UNITS', 'SESSION_INFO_PAPER_UNITS',
+ 'SRV_COL_INFO_ALIAS', 'SRV_COL_INFO_NAME',
+ 'SRV_COL_INFO_PRECISION', 'SRV_COL_INFO_SCALE',
+ 'SRV_COL_INFO_STATUS', 'SRV_COL_INFO_TYPE', 'SRV_COL_INFO_VALUE',
+ 'SRV_COL_INFO_WIDTH', 'SRV_COL_TYPE_BIN_STRING',
+ 'SRV_COL_TYPE_CHAR', 'SRV_COL_TYPE_DATE', 'SRV_COL_TYPE_DECIMAL',
+ 'SRV_COL_TYPE_FIXED_LEN_STRING', 'SRV_COL_TYPE_FLOAT',
+ 'SRV_COL_TYPE_INTEGER', 'SRV_COL_TYPE_LOGICAL',
+ 'SRV_COL_TYPE_NONE', 'SRV_COL_TYPE_SMALLINT',
+ 'SRV_CONNECT_INFO_DB_NAME', 'SRV_CONNECT_INFO_DRIVER_NAME',
+ 'SRV_CONNECT_INFO_DS_NAME', 'SRV_CONNECT_INFO_QUOTE_CHAR',
+ 'SRV_CONNECT_INFO_SQL_USER_ID', 'SRV_DRV_DATA_SOURCE',
+ 'SRV_DRV_INFO_NAME', 'SRV_DRV_INFO_NAME_LIST', 'SRV_ERROR',
+ 'SRV_FETCH_FIRST', 'SRV_FETCH_LAST', 'SRV_FETCH_NEXT',
+ 'SRV_FETCH_PREV', 'SRV_INVALID_HANDLE', 'SRV_NEED_DATA',
+ 'SRV_NO_MORE_DATA', 'SRV_NULL_DATA', 'SRV_SUCCESS',
+ 'SRV_SUCCESS_WITH_INFO', 'SRV_TRUNCATED_DATA',
+ 'SRV_WM_HIST_NO_OVERWRITE', 'SRV_WM_HIST_NONE',
+ 'SRV_WM_HIST_OVERWRITE', 'STR_EQ', 'STR_GT', 'STR_LT',
+ 'STYLE_SAMPLE_SIZE_LARGE', 'STYLE_SAMPLE_SIZE_SMALL',
+ 'SWITCHING_INTO_MAPINFO', 'SWITCHING_OUT_OF_MAPINFO',
+ 'SYMBOL_ANGLE', 'SYMBOL_CODE', 'SYMBOL_COLOR',
+ 'SYMBOL_CUSTOM_NAME', 'SYMBOL_CUSTOM_STYLE', 'SYMBOL_FONT_NAME',
+ 'SYMBOL_FONT_STYLE', 'SYMBOL_KIND', 'SYMBOL_KIND_CUSTOM',
+ 'SYMBOL_KIND_FONT', 'SYMBOL_KIND_VECTOR', 'SYMBOL_POINTSIZE',
+ 'SYS_INFO_APPIDISPATCH', 'SYS_INFO_APPLICATIONWND',
+ 'SYS_INFO_APPVERSION', 'SYS_INFO_CHARSET',
+ 'SYS_INFO_COPYPROTECTED', 'SYS_INFO_DATE_FORMAT',
+ 'SYS_INFO_DDESTATUS', 'SYS_INFO_DIG_INSTALLED',
+ 'SYS_INFO_DIG_MODE', 'SYS_INFO_MAPINFOWND',
+ 'SYS_INFO_MDICLIENTWND', 'SYS_INFO_MIBUILD_NUMBER',
+ 'SYS_INFO_MIPLATFORM', 'SYS_INFO_MIVERSION',
+ 'SYS_INFO_NUMBER_FORMAT', 'SYS_INFO_PLATFORM',
+ 'SYS_INFO_PRODUCTLEVEL', 'SYS_INFO_RUNTIME',
+ 'TAB_GEO_CONTROL_POINT_X', 'TAB_GEO_CONTROL_POINT_Y',
+ 'TAB_INFO_BROWSER_LIST', 'TAB_INFO_COORDSYS_CLAUSE',
+ 'TAB_INFO_COORDSYS_CLAUSE_WITHOUT_BOUNDS',
+ 'TAB_INFO_COORDSYS_MAXX', 'TAB_INFO_COORDSYS_MAXY',
+ 'TAB_INFO_COORDSYS_MINX', 'TAB_INFO_COORDSYS_MINY',
+ 'TAB_INFO_COORDSYS_NAME', 'TAB_INFO_EDITED', 'TAB_INFO_FASTEDIT',
+ 'TAB_INFO_MAPPABLE', 'TAB_INFO_MAPPABLE_TABLE', 'TAB_INFO_MAXX',
+ 'TAB_INFO_MAXY', 'TAB_INFO_MINX', 'TAB_INFO_MINY', 'TAB_INFO_NAME',
+ 'TAB_INFO_NCOLS', 'TAB_INFO_NREFS', 'TAB_INFO_NROWS',
+ 'TAB_INFO_NUM', 'TAB_INFO_READONLY', 'TAB_INFO_SEAMLESS',
+ 'TAB_INFO_SUPPORT_MZ', 'TAB_INFO_TABFILE', 'TAB_INFO_TEMP',
+ 'TAB_INFO_THEME_METADATA', 'TAB_INFO_TYPE', 'TAB_INFO_UNDO',
+ 'TAB_INFO_USERBROWSE', 'TAB_INFO_USERCLOSE',
+ 'TAB_INFO_USERDISPLAYMAP', 'TAB_INFO_USEREDITABLE',
+ 'TAB_INFO_USERMAP', 'TAB_INFO_USERREMOVEMAP', 'TAB_INFO_Z_UNIT',
+ 'TAB_INFO_Z_UNIT_SET', 'TAB_TYPE_BASE', 'TAB_TYPE_FME',
+ 'TAB_TYPE_IMAGE', 'TAB_TYPE_LINKED', 'TAB_TYPE_RESULT',
+ 'TAB_TYPE_VIEW', 'TAB_TYPE_WFS', 'TAB_TYPE_WMS', 'TRUE', 'WHITE',
+ 'WIN_3DMAP', 'WIN_BROWSER', 'WIN_BUTTONPAD', 'WIN_CART_LEGEND',
+ 'WIN_GRAPH', 'WIN_HELP', 'WIN_INFO', 'WIN_INFO_AUTOSCROLL',
+ 'WIN_INFO_CLONEWINDOW', 'WIN_INFO_ENHANCED_RENDERING',
+ 'WIN_INFO_EXPORT_ANTIALIASING', 'WIN_INFO_EXPORT_BORDER',
+ 'WIN_INFO_EXPORT_DITHER', 'WIN_INFO_EXPORT_FILTER',
+ 'WIN_INFO_EXPORT_MASKSIZE', 'WIN_INFO_EXPORT_THRESHOLD',
+ 'WIN_INFO_EXPORT_TRANSPRASTER', 'WIN_INFO_EXPORT_TRANSPVECTOR',
+ 'WIN_INFO_EXPORT_TRUECOLOR', 'WIN_INFO_HEIGHT',
+ 'WIN_INFO_LEGENDS_MAP', 'WIN_INFO_NAME', 'WIN_INFO_OPEN',
+ 'WIN_INFO_PRINTER_BORDER', 'WIN_INFO_PRINTER_BOTTOMMARGIN',
+ 'WIN_INFO_PRINTER_COPIES', 'WIN_INFO_PRINTER_DITHER',
+ 'WIN_INFO_PRINTER_LEFTMARGIN', 'WIN_INFO_PRINTER_METHOD',
+ 'WIN_INFO_PRINTER_NAME', 'WIN_INFO_PRINTER_ORIENT',
+ 'WIN_INFO_PRINTER_PAPERSIZE', 'WIN_INFO_PRINTER_RIGHTMARGIN',
+ 'WIN_INFO_PRINTER_SCALE_PATTERNS', 'WIN_INFO_PRINTER_TOPMARGIN',
+ 'WIN_INFO_PRINTER_TRANSPRASTER', 'WIN_INFO_PRINTER_TRANSPVECTOR',
+ 'WIN_INFO_PRINTER_TRUECOLOR', 'WIN_INFO_SMARTPAN',
+ 'WIN_INFO_SMOOTH_IMAGE', 'WIN_INFO_SMOOTH_TEXT',
+ 'WIN_INFO_SMOOTH_VECTOR', 'WIN_INFO_SNAPMODE',
+ 'WIN_INFO_SNAPTHRESHOLD', 'WIN_INFO_STATE',
+ 'WIN_INFO_SYSMENUCLOSE', 'WIN_INFO_TABLE', 'WIN_INFO_TOPMOST',
+ 'WIN_INFO_TYPE', 'WIN_INFO_WIDTH', 'WIN_INFO_WINDOWID',
+ 'WIN_INFO_WND', 'WIN_INFO_WORKSPACE', 'WIN_INFO_X', 'WIN_INFO_Y',
+ 'WIN_LAYOUT', 'WIN_LEGEND', 'WIN_MAPBASIC', 'WIN_MAPINFO',
+ 'WIN_MAPPER', 'WIN_MESSAGE', 'WIN_PENPICKER',
+ 'WIN_PRINTER_LANDSCAPE', 'WIN_PRINTER_PORTRAIT', 'WIN_RULER',
+ 'WIN_STATE_MAXIMIZED', 'WIN_STATE_MINIMIZED', 'WIN_STATE_NORMAL',
+ 'WIN_STATISTICS', 'WIN_STYLE_CHILD', 'WIN_STYLE_POPUP',
+ 'WIN_STYLE_POPUP_FULLCAPTION', 'WIN_STYLE_STANDARD',
+ 'WIN_SYMBOLPICKER', 'WIN_TOOLBAR', 'WIN_TOOLPICKER', 'YELLOW'
+ ),
+ 5 => array(
+ 'Abbrs', 'Above', 'Access', 'Active', 'Address', 'Advanced',
+ 'Affine', 'Align', 'Alpha', 'alpha_value', 'Always', 'Angle',
+ 'Animate', 'Antialiasing', 'Append', 'Apply', 'ApplyUpdates',
+ 'Arrow', 'Ascending', 'ASCII', 'At', 'AttributeData', 'Auto',
+ 'Autoflip', 'Autokey', 'Automatic', 'Autoscroll', 'Axis',
+ 'Background', 'Banding', 'Batch', 'Behind', 'Below', 'Bend',
+ 'Binary', 'Blocks', 'Border', 'BorderPen', 'Bottom', 'Bounds',
+ 'ByteOrder', 'ByVal', 'Calling', 'Camera', 'Candidates',
+ 'Cartesian', 'Cell', 'Center', 'Change', 'Char', 'Circle',
+ 'Clipping', 'CloseMatchesOnly', 'ClosestAddr', 'Color', 'Columns',
+ 'Contents', 'ControlPoints', 'Copies', 'Copyright', 'Counter',
+ 'Country', 'CountrySecondarySubdivision', 'CountrySubdivision',
+ 'Cross', 'CubicConvolution', 'Cull', 'Cursor', 'Custom', 'Data',
+ 'DBF', 'DDE', 'Decimal', 'DecimalPlaces', 'DefaultAmbientSpeed',
+ 'DefaultPropagationFactor', 'DeformatNumber', 'Delimiter',
+ 'Density', 'DenyWrite', 'Descending', 'Destroy', 'Device',
+ 'Dictionary', 'DInfo', 'Disable', 'DiscardUpdates', 'Display',
+ 'Dither', 'DrawMode', 'DropKey', 'Droplines', 'Duplicates',
+ 'Dynamic', 'Earth', 'East', 'EditLayerPopup', 'Elevation', 'Else',
+ 'ElseIf', 'Emf', 'Enable', 'Envinsa', 'ErrorDiffusion', 'Extents',
+ 'Fallback', 'FastEdit', 'FillFrame', 'Filter', 'First', 'Fit',
+ 'Fixed', 'FocalPoint', 'Footnote', 'Force', 'FromMapCatalog',
+ 'Front', 'Gap', 'Geographic', 'Geography', 'Graduated', 'Graphic',
+ 'Gutter', 'Half', 'Halftone', 'Handles', 'Height', 'Help',
+ 'HelpMsg', 'Hide', 'Hierarchical', 'HIGHLOW', 'History', 'Icon',
+ 'ID', 'Ignore', 'Image', 'Inflect', 'Inset', 'Inside',
+ 'Interactive', 'Internal', 'Interpolate', 'IntersectingStreet',
+ 'Justify', 'Key', 'Label', 'Labels', 'Landscape', 'Large', 'Last',
+ 'Layer', 'Left', 'Lib', 'Light', 'LinePen', 'Lines', 'Linestyle',
+ 'Longitude', 'LOWHIGH', 'Major', 'MajorPolygonOnly',
+ 'MajorRoadsOnly', 'MapBounds', 'MapMarker', 'MapString', 'Margins',
+ 'MarkMultiple', 'MaskSize', 'Match', 'MaxOffRoadDistance',
+ 'Message', 'MICODE', 'Minor', 'MixedCase', 'Mode', 'ModifierKeys',
+ 'Modify', 'Multiple', 'MultiPolygonRgns', 'Municipality',
+ 'MunicipalitySubdivision', 'Name', 'NATIVE', 'NearestNeighbor',
+ 'NoCollision', 'Node', 'Nodes', 'NoIndex', 'None', 'Nonearth',
+ 'NoRefresh', 'Normalized', 'North', 'Number', 'ObjectType', 'ODBC',
+ 'Off', 'OK', 'OLE', 'On', 'Options', 'Orientation', 'OtherBdy',
+ 'Output', 'Outside', 'Overlapped', 'Overwrite', 'Pagebreaks',
+ 'Pan', 'Papersize', 'Parent', 'PassThrough', 'Password',
+ 'Patterns', 'Per', 'Percent', 'Percentage', 'Permanent',
+ 'PersistentCache', 'Pie', 'Pitch', 'Placename', 'PointsOnly',
+ 'PolyObj', 'Portrait', 'Position', 'PostalCode', 'Prefer',
+ 'Preferences', 'Prev', 'Printer', 'Projection', 'PushButton',
+ 'Quantile', 'Query', 'Random', 'Range', 'Raster', 'Read',
+ 'ReadOnly', 'Rec', 'Redraw', 'Refine', 'Regionstyle', 'RemoveData',
+ 'Replace', 'Reprojection', 'Resampling', 'Restore', 'ResultCode',
+ 'ReturnHoles', 'Right', 'Roll', 'ROP', 'Rotated', 'Row', 'Ruler',
+ 'Scale', 'ScrollBars', 'Seamless', 'SecondaryPostalCode',
+ 'SelfInt', 'Separator', 'Series', 'Service', 'SetKey',
+ 'SetTraverse', 'Shades', 'Show', 'Simple', 'SimplificationFactor',
+ 'Size', 'Small', 'Smart', 'Smooth', 'South', 'Spacing',
+ 'SPATIALWARE', 'Spherical', 'Square', 'Stacked', 'Step', 'Store',
+ 'Street', 'StreetName', 'StreetNumber', 'StyleType', 'Subtitle',
+ 'SysMenuClose', 'Thin', 'Tick', 'Title', 'TitleAxisY',
+ 'TitleGroup', 'Titles', 'TitleSeries', 'ToggleButton', 'Tolerance',
+ 'ToolbarPosition', 'ToolButton', 'Toolkit', 'Top', 'Translucency',
+ 'translucency_percent', 'Transparency', 'Transparent', 'Traverse',
+ 'TrueColor', 'Uncheck', 'Undo', 'Union', 'Unit', 'Until', 'URL',
+ 'Use', 'User', 'UserBrowse', 'UserClose', 'UserDisplayMap',
+ 'UserEdit', 'UserMap', 'UserRemoveMap', 'Value', 'Variable',
+ 'Vary', 'Vector', 'Versioned', 'View', 'ViewDisplayPopup',
+ 'VisibleOnly', 'VMDefault', 'VMGrid', 'VMRaster', 'Voronoi',
+ 'Warnings', 'Wedge', 'West', 'Width', 'With', 'XY', 'XYINDEX',
+ 'Yaw', 'Zoom'
+ )
+ ),
+ 'SYMBOLS' => array(
+ //Numeric/String Operators + Comparison Operators
+ '(', ')', '[', ']', '+', '-', '*', '/', '\\', '^', '&',
+ '=', '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;', //Statements + Clauses + Data Types + Logical Operators, Geographical Operators + SQL
+ 2 => 'color: #2391af;', //Special Procedures
+ 3 => 'color: #2391af;', //Functions
+ 4 => 'color: #c635cb;', //Constants
+ 5 => 'color: #0000ff;' //Extended keywords (case sensitive)
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000;',
+ 'MULTI' => 'color: #008000;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #a31515;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #12198b;', //Table Attributes
+ 1 => 'color: #2391af;' //Data Types
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Table Attribute
+ 0 => "[\\.]{1}[a-zA-Z0-9_]+",
+ //Data Type
+ 1 => "(?xi) \\s+ as \\s+ (Alias|Brush|Date|Float|Font|Integer|Logical|Object|Pen|SmallInt|String|Symbol)"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/mathematica.php b/platform/www/vendor/geshi/geshi/src/geshi/mathematica.php
new file mode 100644
index 0000000..238ccde
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/mathematica.php
@@ -0,0 +1,5035 @@
+<?php
+/*************************************************************************************
+ * mathematica.php
+ * --------
+ * Author: Connor Glosser (glosser1@gmail.com)
+ * Copyright: (c) 2014 Connor Glosser (http://www.msu.edu/~glosser1)
+ * Release Version: 1.0.9.1
+ * Date Started: 2014/08/11
+ *
+ * Mathematica language file for GeSHi.
+ *
+ * COMMENTS
+ * --------
+ * Mathematica itself uses a lot of hyper-contextual syntax highlighting
+ * that doesn't work well outside of their proprietary Notebook interface.
+ * Consequently, external syntax highlighting tends to get noisy quickly.
+ * Here, I've tried to create a triadic color scheme to distinguish keywords,
+ * infix functions, and $-designated variables.
+ *
+ * CHANGES
+ * -------
+ * 2016/10/27 (1.0.8.13)
+ * - Update function list to Ver. 11
+ * - Add delimiters for associative arrays
+ * 2014/10/13 (1.0.8.11)
+ * - Removed style variables for compatability
+ * 2014/08/11 (1.0.8.11)
+ * - First Release
+ * - Symbols taken from http://reference.wolfram.com/language/guide/AlphabeticalListing.html
+ * (Mathematica Version 10)
+ *
+ * TODO (updated 2014/08/12)
+ * -------------------------
+ * - evaluate colored array syntax
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+//"Base" styles
+//string = 'color: #666666; font-style: italic;';
+//comment = 'color: #999999; font-style: italic;';
+
+//Purple-green colors
+//primary = 'color: #500D75; font-weight: bold;'; //keywords
+//secondary = 'color: #70A30A; font-weight: bold;'; //infix functions
+//tertiary = 'color: #8C0953; font-weight: bold;'; //$variables
+//quaternary = 'color: #AFAF0B; font-weight: bold;'; //potentially array syntax in the future
+
+//Orange-blue colors (similar to python coloring)
+//primary = 'color: #FF7700; font-weight: bold;'; //keywords
+//secondary = 'color: #133CAC; font-weight: bold;'; //infix functions
+//tertiary = 'color: #028E9B; font-weight: bold;'; //$variables
+//quaternary = 'color: #FFAD00; font-weight: bold;'; //potentially array syntax in the future
+
+$language_data = array(
+ 'LANG_NAME' => 'Mathematica',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(
+ '(*' => '*)',
+ ),
+ 'COMMENT_REGEXP' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(
+ 1 => '"',
+ ),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(),
+ 'HARDQUOTE' => array(),
+ 'HARDESCAPE' => array(),
+ 'HARDCHAR' => '',
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'AASTriangle',
+ 'APIFunction',
+ 'ARCHProcess',
+ 'ARIMAProcess',
+ 'ARMAProcess',
+ 'ARProcess',
+ 'ASATriangle',
+ 'AbelianGroup',
+ 'Abort',
+ 'AbortKernels',
+ 'AbortProtect',
+ 'AbortScheduledTask',
+ 'Above',
+ 'Abs',
+ 'AbsArg',
+ 'AbsoluteCorrelation',
+ 'AbsoluteCorrelationFunction',
+ 'AbsoluteCurrentValue',
+ 'AbsoluteDashing',
+ 'AbsoluteFileName',
+ 'AbsoluteOptions',
+ 'AbsolutePointSize',
+ 'AbsoluteThickness',
+ 'AbsoluteTime',
+ 'AbsoluteTiming',
+ 'AccountingForm',
+ 'Accumulate',
+ 'Accuracy',
+ 'AccuracyGoal',
+ 'ActionMenu',
+ 'Activate',
+ 'ActiveStyle',
+ 'AcyclicGraphQ',
+ 'AddTo',
+ 'AddUsers',
+ 'AdjacencyGraph',
+ 'AdjacencyList',
+ 'AdjacencyMatrix',
+ 'AdjustTimeSeriesForecast',
+ 'AdjustmentBox',
+ 'AdjustmentBoxOptions',
+ 'AdministrativeDivisionData',
+ 'AffineHalfSpace',
+ 'AffineSpace',
+ 'AffineStateSpaceModel',
+ 'AffineTransform',
+ 'After',
+ 'AirPressureData',
+ 'AirTemperatureData',
+ 'AircraftData',
+ 'AirportData',
+ 'AiryAi',
+ 'AiryAiPrime',
+ 'AiryAiZero',
+ 'AiryBi',
+ 'AiryBiPrime',
+ 'AiryBiZero',
+ 'AlgebraicIntegerQ',
+ 'AlgebraicNumber',
+ 'AlgebraicNumberDenominator',
+ 'AlgebraicNumberNorm',
+ 'AlgebraicNumberPolynomial',
+ 'AlgebraicNumberTrace',
+ 'AlgebraicUnitQ',
+ 'Algebraics',
+ 'Alignment',
+ 'AlignmentPoint',
+ 'All',
+ 'AllTrue',
+ 'AllowGroupClose',
+ 'AllowInlineCells',
+ 'AllowLooseGrammar',
+ 'AllowReverseGroupClose',
+ 'AllowedDimensions',
+ 'AlphaChannel',
+ 'Alphabet',
+ 'AlphabeticOrder',
+ 'AlphabeticSort',
+ 'AlternateImage',
+ 'AlternatingFactorial',
+ 'AlternatingGroup',
+ 'AlternativeHypothesis',
+ 'Alternatives',
+ 'AltitudeMethod',
+ 'AmbiguityFunction',
+ 'AmbiguityList',
+ 'AnatomyData',
+ 'AnatomyForm',
+ 'AnatomyPlot3D',
+ 'AnchoredSearch',
+ 'And',
+ 'AndersonDarlingTest',
+ 'AngerJ',
+ 'AngleBracket',
+ 'AnglePath',
+ 'AngleVector',
+ 'AngularGauge',
+ 'Animate',
+ 'AnimationDirection',
+ 'AnimationRate',
+ 'AnimationRepetitions',
+ 'AnimationRunTime',
+ 'AnimationRunning',
+ 'AnimationTimeIndex',
+ 'Animator',
+ 'Annotation',
+ 'Annuity',
+ 'AnnuityDue',
+ 'Annulus',
+ 'Anonymous',
+ 'Antialiasing',
+ 'AntihermitianMatrixQ',
+ 'Antisymmetric',
+ 'AntisymmetricMatrixQ',
+ 'AnyOrder',
+ 'AnySubset',
+ 'AnyTrue',
+ 'Apart',
+ 'ApartSquareFree',
+ 'Appearance',
+ 'AppearanceElements',
+ 'AppearanceRules',
+ 'AppellF1',
+ 'Append',
+ 'AppendTo',
+ 'Apply',
+ 'ArcCos',
+ 'ArcCosh',
+ 'ArcCot',
+ 'ArcCoth',
+ 'ArcCsc',
+ 'ArcCsch',
+ 'ArcCurvature',
+ 'ArcLength',
+ 'ArcSec',
+ 'ArcSech',
+ 'ArcSin',
+ 'ArcSinDistribution',
+ 'ArcSinh',
+ 'ArcTan',
+ 'ArcTanh',
+ 'Area',
+ 'Arg',
+ 'ArgMax',
+ 'ArgMin',
+ 'ArithmeticGeometricMean',
+ 'Array',
+ 'ArrayComponents',
+ 'ArrayDepth',
+ 'ArrayFilter',
+ 'ArrayFlatten',
+ 'ArrayMesh',
+ 'ArrayPad',
+ 'ArrayPlot',
+ 'ArrayQ',
+ 'ArrayResample',
+ 'ArrayReshape',
+ 'ArrayRules',
+ 'Arrays',
+ 'Arrow',
+ 'Arrowheads',
+ 'Ask',
+ 'AskAppend',
+ 'AskConfirm',
+ 'AskDisplay',
+ 'AskFunction',
+ 'AskTemplateDisplay',
+ 'AskedQ',
+ 'AskedValue',
+ 'AspectRatio',
+ 'Assert',
+ 'AssociateTo',
+ 'Association',
+ 'AssociationFormat',
+ 'AssociationMap',
+ 'AssociationQ',
+ 'AssociationThread',
+ 'AssumeDeterministic',
+ 'Assuming',
+ 'Assumptions',
+ 'AsymptoticOutputTracker',
+ 'Asynchronous',
+ 'AsynchronousTaskObject',
+ 'AsynchronousTasks',
+ 'AtomQ',
+ 'Attributes',
+ 'Audio',
+ 'AudioAmplify',
+ 'AudioBlockMap',
+ 'AudioChannelCombine',
+ 'AudioChannelMix',
+ 'AudioChannelSeparate',
+ 'AudioChannels',
+ 'AudioData',
+ 'AudioDelay',
+ 'AudioDelete',
+ 'AudioDevice',
+ 'AudioFade',
+ 'AudioFrequencyShift',
+ 'AudioGenerator',
+ 'AudioIntervals',
+ 'AudioJoin',
+ 'AudioLabel',
+ 'AudioLength',
+ 'AudioLocalMeasurements',
+ 'AudioMeasurements',
+ 'AudioNormalize',
+ 'AudioOverlay',
+ 'AudioPad',
+ 'AudioPan',
+ 'AudioPartition',
+ 'AudioPitchShift',
+ 'AudioPlot',
+ 'AudioQ',
+ 'AudioResample',
+ 'AudioReverb',
+ 'AudioSampleRate',
+ 'AudioSplit',
+ 'AudioTimeStretch',
+ 'AudioTrim',
+ 'AudioType',
+ 'AugmentedSymmetricPolynomial',
+ 'Authentication',
+ 'AutoAction',
+ 'AutoDelete',
+ 'AutoIndent',
+ 'AutoItalicWords',
+ 'AutoMultiplicationSymbol',
+ 'AutoRefreshed',
+ 'AutoRemove',
+ 'AutoScroll',
+ 'AutoSpacing',
+ 'AutoSubmitting',
+ 'Autocomplete',
+ 'AutocompletionFunction',
+ 'AutocorrelationTest',
+ 'Automatic',
+ 'AutorunSequencing',
+ 'Axes',
+ 'AxesEdge',
+ 'AxesLabel',
+ 'AxesOrigin',
+ 'AxesStyle',
+ 'Axis',
+ 'BSplineBasis',
+ 'BSplineCurve',
+ 'BSplineFunction',
+ 'BSplineSurface',
+ 'BabyMonsterGroupB',
+ 'Back',
+ 'Background',
+ 'Backslash',
+ 'Backward',
+ 'Ball',
+ 'Band',
+ 'BandpassFilter',
+ 'BandstopFilter',
+ 'BarChart',
+ 'BarChart3D',
+ 'BarLegend',
+ 'BarOrigin',
+ 'BarSpacing',
+ 'BarabasiAlbertGraphDistribution',
+ 'BarcodeImage',
+ 'BarcodeRecognize',
+ 'BaringhausHenzeTest',
+ 'BarlowProschanImportance',
+ 'BarnesG',
+ 'BartlettHannWindow',
+ 'BartlettWindow',
+ 'BaseForm',
+ 'BaseStyle',
+ 'Baseline',
+ 'BaselinePosition',
+ 'BatchNormalizationLayer',
+ 'BatchSize',
+ 'BatesDistribution',
+ 'BattleLemarieWavelet',
+ 'BayesianMaximization',
+ 'BayesianMaximizationObject',
+ 'BayesianMinimization',
+ 'BayesianMinimizationObject',
+ 'Because',
+ 'BeckmannDistribution',
+ 'Beep',
+ 'Before',
+ 'Begin',
+ 'BeginDialogPacket',
+ 'BeginPackage',
+ 'BellB',
+ 'BellY',
+ 'Below',
+ 'BenfordDistribution',
+ 'BeniniDistribution',
+ 'BenktanderGibratDistribution',
+ 'BenktanderWeibullDistribution',
+ 'BernoulliB',
+ 'BernoulliDistribution',
+ 'BernoulliGraphDistribution',
+ 'BernoulliProcess',
+ 'BernsteinBasis',
+ 'BesselFilterModel',
+ 'BesselI',
+ 'BesselJ',
+ 'BesselJZero',
+ 'BesselK',
+ 'BesselY',
+ 'BesselYZero',
+ 'Beta',
+ 'BetaBinomialDistribution',
+ 'BetaDistribution',
+ 'BetaNegativeBinomialDistribution',
+ 'BetaPrimeDistribution',
+ 'BetaRegularized',
+ 'Between',
+ 'BetweennessCentrality',
+ 'BezierCurve',
+ 'BezierFunction',
+ 'BilateralFilter',
+ 'BinCounts',
+ 'BinLists',
+ 'Binarize',
+ 'BinaryDistance',
+ 'BinaryFormat',
+ 'BinaryImageQ',
+ 'BinaryRead',
+ 'BinaryReadList',
+ 'BinaryWrite',
+ 'Binomial',
+ 'BinomialDistribution',
+ 'BinomialProcess',
+ 'BinormalDistribution',
+ 'BiorthogonalSplineWavelet',
+ 'BipartiteGraphQ',
+ 'BiquadraticFilterModel',
+ 'BirnbaumImportance',
+ 'BirnbaumSaundersDistribution',
+ 'BitAnd',
+ 'BitClear',
+ 'BitGet',
+ 'BitLength',
+ 'BitNot',
+ 'BitOr',
+ 'BitSet',
+ 'BitShiftLeft',
+ 'BitShiftRight',
+ 'BitXor',
+ 'Black',
+ 'BlackmanHarrisWindow',
+ 'BlackmanNuttallWindow',
+ 'BlackmanWindow',
+ 'Blank',
+ 'BlankNullSequence',
+ 'BlankSequence',
+ 'Blend',
+ 'Block',
+ 'BlockMap',
+ 'BlockRandom',
+ 'BlomqvistBeta',
+ 'BlomqvistBetaTest',
+ 'Blue',
+ 'Blur',
+ 'BodePlot',
+ 'BohmanWindow',
+ 'Bold',
+ 'Bookmarks',
+ 'Boole',
+ 'BooleanConsecutiveFunction',
+ 'BooleanConvert',
+ 'BooleanCountingFunction',
+ 'BooleanFunction',
+ 'BooleanGraph',
+ 'BooleanMaxterms',
+ 'BooleanMinimize',
+ 'BooleanMinterms',
+ 'BooleanQ',
+ 'BooleanRegion',
+ 'BooleanStrings',
+ 'BooleanTable',
+ 'BooleanVariables',
+ 'Booleans',
+ 'BorderDimensions',
+ 'BorelTannerDistribution',
+ 'Bottom',
+ 'BottomHatTransform',
+ 'BoundaryDiscretizeGraphics',
+ 'BoundaryDiscretizeRegion',
+ 'BoundaryMesh',
+ 'BoundaryMeshRegion',
+ 'BoundaryMeshRegionQ',
+ 'BoundaryStyle',
+ 'BoundedRegionQ',
+ 'BoundingRegion',
+ 'BoxData',
+ 'BoxMatrix',
+ 'BoxObject',
+ 'BoxRatios',
+ 'BoxStyle',
+ 'BoxWhiskerChart',
+ 'Boxed',
+ 'BracketingBar',
+ 'BrayCurtisDistance',
+ 'BreadthFirstScan',
+ 'Break',
+ 'BridgeData',
+ 'BroadcastStationData',
+ 'Brown',
+ 'BrownForsytheTest',
+ 'BrownianBridgeProcess',
+ 'BubbleChart',
+ 'BubbleChart3D',
+ 'BubbleScale',
+ 'BubbleSizes',
+ 'BuildingData',
+ 'BulletGauge',
+ 'BusinessDayQ',
+ 'ButterflyGraph',
+ 'ButterworthFilterModel',
+ 'Button',
+ 'ButtonBar',
+ 'ButtonBox',
+ 'ButtonBoxOptions',
+ 'ButtonData',
+ 'ButtonFunction',
+ 'ButtonMinHeight',
+ 'ButtonNotebook',
+ 'ButtonSource',
+ 'Byte',
+ 'ByteArray',
+ 'ByteArrayQ',
+ 'ByteCount',
+ 'ByteOrdering',
+
+ 'C',
+ 'CDF',
+ 'CDFDeploy',
+ 'CDFInformation',
+ 'CDFWavelet',
+ 'CForm',
+ 'CMYKColor',
+ 'CachePersistence',
+ 'CalendarConvert',
+ 'CalendarData',
+ 'CalendarType',
+ 'CallPacket',
+ 'Callout',
+ 'CalloutMarker',
+ 'CalloutStyle',
+ 'CanberraDistance',
+ 'Cancel',
+ 'CancelButton',
+ 'CandlestickChart',
+ 'CanonicalGraph',
+ 'CanonicalName',
+ 'CanonicalWarpingCorrespondence',
+ 'CanonicalWarpingDistance',
+ 'CantorStaircase',
+ 'Cap',
+ 'CapForm',
+ 'CapitalDifferentialD',
+ 'Capitalize',
+ 'CapsuleShape',
+ 'CarlemanLinearize',
+ 'CarmichaelLambda',
+ 'CaseOrdering',
+ 'CaseSensitive',
+ 'Cases',
+ 'Cashflow',
+ 'Casoratian',
+ 'Catalan',
+ 'CatalanNumber',
+ 'Catch',
+ 'Catenate',
+ 'CatenateLayer',
+ 'CauchyDistribution',
+ 'CauchyWindow',
+ 'CayleyGraph',
+ 'Ceiling',
+ 'CelestialSystem',
+ 'Cell',
+ 'CellAutoOverwrite',
+ 'CellBaseline',
+ 'CellBracketOptions',
+ 'CellChangeTimes',
+ 'CellContext',
+ 'CellDingbat',
+ 'CellDynamicExpression',
+ 'CellEditDuplicate',
+ 'CellEpilog',
+ 'CellEvaluationDuplicate',
+ 'CellEvaluationFunction',
+ 'CellEventActions',
+ 'CellFrame',
+ 'CellFrameColor',
+ 'CellFrameLabelMargins',
+ 'CellFrameLabels',
+ 'CellFrameMargins',
+ 'CellGroup',
+ 'CellGroupData',
+ 'CellGrouping',
+ 'CellID',
+ 'CellLabel',
+ 'CellLabelAutoDelete',
+ 'CellMargins',
+ 'CellObject',
+ 'CellOpen',
+ 'CellPrint',
+ 'CellProlog',
+ 'CellStyle',
+ 'CellTags',
+ 'Cells',
+ 'CellularAutomaton',
+ 'CensoredDistribution',
+ 'Censoring',
+ 'Center',
+ 'CenterArray',
+ 'CenterDot',
+ 'CentralMoment',
+ 'CentralMomentGeneratingFunction',
+ 'ChampernowneNumber',
+ 'ChanVeseBinarize',
+ 'ChannelBase',
+ 'ChannelDatabin',
+ 'ChannelListen',
+ 'ChannelListener',
+ 'ChannelListeners',
+ 'ChannelObject',
+ 'ChannelPreSendFunction',
+ 'ChannelSend',
+ 'ChannelSubscribers',
+ 'Character',
+ 'CharacterCounts',
+ 'CharacterEncoding',
+ 'CharacterName',
+ 'CharacterRange',
+ 'CharacteristicFunction',
+ 'CharacteristicPolynomial',
+ 'Characters',
+ 'ChartBaseStyle',
+ 'ChartElementFunction',
+ 'ChartElements',
+ 'ChartLabels',
+ 'ChartLayout',
+ 'ChartLegends',
+ 'ChartStyle',
+ 'Chebyshev1FilterModel',
+ 'Chebyshev2FilterModel',
+ 'ChebyshevT',
+ 'ChebyshevU',
+ 'Check',
+ 'CheckAbort',
+ 'Checkbox',
+ 'CheckboxBar',
+ 'ChemicalData',
+ 'ChessboardDistance',
+ 'ChiDistribution',
+ 'ChiSquareDistribution',
+ 'ChineseRemainder',
+ 'ChoiceButtons',
+ 'ChoiceDialog',
+ 'CholeskyDecomposition',
+ 'Chop',
+ 'ChromaticPolynomial',
+ 'ChromaticityPlot',
+ 'ChromaticityPlot3D',
+ 'Circle',
+ 'CircleDot',
+ 'CircleMinus',
+ 'CirclePlus',
+ 'CirclePoints',
+ 'CircleTimes',
+ 'CirculantGraph',
+ 'CircularOrthogonalMatrixDistribution',
+ 'CircularQuaternionMatrixDistribution',
+ 'CircularRealMatrixDistribution',
+ 'CircularSymplecticMatrixDistribution',
+ 'CircularUnitaryMatrixDistribution',
+ 'Circumsphere',
+ 'CityData',
+ 'ClassPriors',
+ 'ClassifierFunction',
+ 'ClassifierInformation',
+ 'ClassifierMeasurements',
+ 'ClassifierMeasurementsObject',
+ 'Classify',
+ 'Clear',
+ 'ClearAll',
+ 'ClearAttributes',
+ 'ClearCookies',
+ 'ClearPermissions',
+ 'ClearSystemCache',
+ 'ClebschGordan',
+ 'ClickPane',
+ 'Clip',
+ 'ClipPlanes',
+ 'ClipPlanesStyle',
+ 'ClipRange',
+ 'ClippingStyle',
+ 'Clock',
+ 'ClockGauge',
+ 'Close',
+ 'CloseKernels',
+ 'ClosenessCentrality',
+ 'Closing',
+ 'CloudAccountData',
+ 'CloudBase',
+ 'CloudConnect',
+ 'CloudDeploy',
+ 'CloudDirectory',
+ 'CloudDisconnect',
+ 'CloudEvaluate',
+ 'CloudExport',
+ 'CloudExpression',
+ 'CloudExpressions',
+ 'CloudFunction',
+ 'CloudGet',
+ 'CloudImport',
+ 'CloudLoggingData',
+ 'CloudObject',
+ 'CloudObjects',
+ 'CloudPublish',
+ 'CloudPut',
+ 'CloudSave',
+ 'CloudShare',
+ 'CloudSubmit',
+ 'CloudSymbol',
+ 'ClusterClassify',
+ 'ClusterDissimilarityFunction',
+ 'ClusteringComponents',
+ 'ClusteringTree',
+ 'CodeAssistOptions',
+ 'Coefficient',
+ 'CoefficientArrays',
+ 'CoefficientList',
+ 'CoefficientRules',
+ 'CoifletWavelet',
+ 'Collect',
+ 'Colon',
+ 'ColorBalance',
+ 'ColorCombine',
+ 'ColorConvert',
+ 'ColorCoverage',
+ 'ColorData',
+ 'ColorDataFunction',
+ 'ColorDistance',
+ 'ColorFunction',
+ 'ColorFunctionScaling',
+ 'ColorNegate',
+ 'ColorProfileData',
+ 'ColorQ',
+ 'ColorQuantize',
+ 'ColorReplace',
+ 'ColorRules',
+ 'ColorSeparate',
+ 'ColorSetter',
+ 'ColorSlider',
+ 'ColorSpace',
+ 'ColorToneMapping',
+ 'Colorize',
+ 'Column',
+ 'ColumnAlignments',
+ 'ColumnLines',
+ 'ColumnSpacings',
+ 'ColumnWidths',
+ 'ColumnsEqual',
+ 'CombinerFunction',
+ 'CometData',
+ 'CommonName',
+ 'CommonUnits',
+ 'Commonest',
+ 'CommonestFilter',
+ 'CommunityBoundaryStyle',
+ 'CommunityGraphPlot',
+ 'CommunityLabels',
+ 'CommunityRegionStyle',
+ 'CompanyData',
+ 'CompatibleUnitQ',
+ 'CompilationOptions',
+ 'CompilationTarget',
+ 'Compile',
+ 'Compiled',
+ 'CompiledFunction',
+ 'Complement',
+ 'CompleteGraph',
+ 'CompleteGraphQ',
+ 'CompleteKaryTree',
+ 'Complex',
+ 'ComplexExpand',
+ 'ComplexInfinity',
+ 'Complexes',
+ 'ComplexityFunction',
+ 'ComponentMeasurements',
+ 'ComposeList',
+ 'ComposeSeries',
+ 'CompositeQ',
+ 'Composition',
+ 'CompoundElement',
+ 'CompoundExpression',
+ 'CompoundPoissonDistribution',
+ 'CompoundPoissonProcess',
+ 'CompoundRenewalProcess',
+ 'Compress',
+ 'Condition',
+ 'ConditionalExpression',
+ 'Conditioned',
+ 'Cone',
+ 'ConfidenceLevel',
+ 'ConfidenceRange',
+ 'ConfidenceTransform',
+ 'ConformAudio',
+ 'ConformImages',
+ 'Congruent',
+ 'ConicHullRegion',
+ 'Conjugate',
+ 'ConjugateTranspose',
+ 'Conjunction',
+ 'ConnectLibraryCallbackFunction',
+ 'ConnectedComponents',
+ 'ConnectedGraphComponents',
+ 'ConnectedGraphQ',
+ 'ConnectedMeshComponents',
+ 'ConnesWindow',
+ 'ConoverTest',
+ 'Constant',
+ 'ConstantArray',
+ 'ConstantImage',
+ 'ConstantRegionQ',
+ 'Constants',
+ 'ConstellationData',
+ 'Containing',
+ 'ContainsAll',
+ 'ContainsAny',
+ 'ContainsExactly',
+ 'ContainsNone',
+ 'ContainsOnly',
+ 'ContentFieldOptions',
+ 'ContentLocationFunction',
+ 'ContentObject',
+ 'ContentPadding',
+ 'ContentSelectable',
+ 'ContentSize',
+ 'Context',
+ 'ContextToFileName',
+ 'Contexts',
+ 'Continue',
+ 'ContinuedFraction',
+ 'ContinuedFractionK',
+ 'ContinuousAction',
+ 'ContinuousMarkovProcess',
+ 'ContinuousTask',
+ 'ContinuousTimeModelQ',
+ 'ContinuousWaveletData',
+ 'ContinuousWaveletTransform',
+ 'ContourDetect',
+ 'ContourLabels',
+ 'ContourPlot',
+ 'ContourPlot3D',
+ 'ContourShading',
+ 'ContourStyle',
+ 'Contours',
+ 'ContraharmonicMean',
+ 'Control',
+ 'ControlActive',
+ 'ControlPlacement',
+ 'ControlType',
+ 'ControllabilityGramian',
+ 'ControllabilityMatrix',
+ 'ControllableDecomposition',
+ 'ControllableModelQ',
+ 'ControllerInformation',
+ 'ControllerLinking',
+ 'ControllerManipulate',
+ 'ControllerMethod',
+ 'ControllerPath',
+ 'ControllerState',
+ 'ControlsRendering',
+ 'Convergents',
+ 'ConversionRules',
+ 'ConvexHullMesh',
+ 'ConvolutionLayer',
+ 'Convolve',
+ 'ConwayGroupCo1',
+ 'ConwayGroupCo2',
+ 'ConwayGroupCo3',
+ 'CookieFunction',
+ 'CoordinateBoundingBox',
+ 'CoordinateBoundingBoxArray',
+ 'CoordinateBounds',
+ 'CoordinateBoundsArray',
+ 'CoordinateChartData',
+ 'CoordinateTransform',
+ 'CoordinateTransformData',
+ 'CoordinatesToolOptions',
+ 'CoprimeQ',
+ 'Coproduct',
+ 'CopulaDistribution',
+ 'CopyDatabin',
+ 'CopyDirectory',
+ 'CopyFile',
+ 'CopyToClipboard',
+ 'Copyable',
+ 'CornerFilter',
+ 'CornerNeighbors',
+ 'Correlation',
+ 'CorrelationDistance',
+ 'CorrelationFunction',
+ 'CorrelationTest',
+ 'Cos',
+ 'CosIntegral',
+ 'Cosh',
+ 'CoshIntegral',
+ 'CosineDistance',
+ 'CosineWindow',
+ 'Cot',
+ 'Coth',
+ 'Count',
+ 'CountDistinct',
+ 'CountDistinctBy',
+ 'CountRoots',
+ 'CountryData',
+ 'Counts',
+ 'CountsBy',
+ 'Covariance',
+ 'CovarianceEstimatorFunction',
+ 'CovarianceFunction',
+ 'CoxIngersollRossProcess',
+ 'CoxModel',
+ 'CoxModelFit',
+ 'CoxianDistribution',
+ 'CramerVonMisesTest',
+ 'CreateArchive',
+ 'CreateCellID',
+ 'CreateChannel',
+ 'CreateCloudExpression',
+ 'CreateDatabin',
+ 'CreateDialog',
+ 'CreateDirectory',
+ 'CreateDocument',
+ 'CreateFile',
+ 'CreateIntermediateDirectories',
+ 'CreateManagedLibraryExpression',
+ 'CreateNotebook',
+ 'CreatePalette',
+ 'CreatePermissionsGroup',
+ 'CreateScheduledTask',
+ 'CreateSearchIndex',
+ 'CreateUUID',
+ 'CreateWindow',
+ 'CriterionFunction',
+ 'CriticalSection',
+ 'CriticalityFailureImportance',
+ 'CriticalitySuccessImportance',
+ 'Cross',
+ 'CrossEntropyLossLayer',
+ 'CrossMatrix',
+ 'CrossingDetect',
+ 'Csc',
+ 'Csch',
+ 'CubeRoot',
+ 'Cubics',
+ 'Cuboid',
+ 'Cumulant',
+ 'CumulantGeneratingFunction',
+ 'Cup',
+ 'CupCap',
+ 'Curl',
+ 'CurrencyConvert',
+ 'CurrentImage',
+ 'CurrentValue',
+ 'CurvatureFlowFilter',
+ 'CurveClosed',
+ 'Cyan',
+ 'CycleGraph',
+ 'CycleIndexPolynomial',
+ 'Cycles',
+ 'CyclicGroup',
+ 'Cyclotomic',
+ 'Cylinder',
+ 'CylindricalDecomposition',
+
+ 'D',
+ 'DEigensystem',
+ 'DEigenvalues',
+ 'DGaussianWavelet',
+ 'DMSList',
+ 'DMSString',
+ 'DSolve',
+ 'DSolveValue',
+ 'DagumDistribution',
+ 'DamData',
+ 'DamerauLevenshteinDistance',
+ 'Darker',
+ 'Dashed',
+ 'Dashing',
+ 'DataDistribution',
+ 'DataRange',
+ 'DataReversed',
+ 'Databin',
+ 'DatabinAdd',
+ 'DatabinRemove',
+ 'DatabinUpload',
+ 'Databins',
+ 'Dataset',
+ 'DateBounds',
+ 'DateDifference',
+ 'DateFormat',
+ 'DateFunction',
+ 'DateHistogram',
+ 'DateList',
+ 'DateListLogPlot',
+ 'DateListPlot',
+ 'DateListStepPlot',
+ 'DateObject',
+ 'DateObjectQ',
+ 'DatePattern',
+ 'DatePlus',
+ 'DateRange',
+ 'DateReduction',
+ 'DateString',
+ 'DateTicksFormat',
+ 'DateValue',
+ 'Dated',
+ 'DatedUnit',
+ 'DaubechiesWavelet',
+ 'DavisDistribution',
+ 'DawsonF',
+ 'DayCount',
+ 'DayCountConvention',
+ 'DayHemisphere',
+ 'DayMatchQ',
+ 'DayName',
+ 'DayNightTerminator',
+ 'DayPlus',
+ 'DayRange',
+ 'DayRound',
+ 'DaylightQ',
+ 'DeBruijnGraph',
+ 'Decapitalize',
+ 'DeclarePackage',
+ 'Decompose',
+ 'DeconvolutionLayer',
+ 'Decrement',
+ 'Decrypt',
+ 'DedekindEta',
+ 'DeepSpaceProbeData',
+ 'Default',
+ 'DefaultAxesStyle',
+ 'DefaultBaseStyle',
+ 'DefaultBoxStyle',
+ 'DefaultButton',
+ 'DefaultDuplicateCellStyle',
+ 'DefaultDuration',
+ 'DefaultElement',
+ 'DefaultFaceGridsStyle',
+ 'DefaultFieldHintStyle',
+ 'DefaultFrameStyle',
+ 'DefaultFrameTicksStyle',
+ 'DefaultGridLinesStyle',
+ 'DefaultLabelStyle',
+ 'DefaultMenuStyle',
+ 'DefaultNaturalLanguage',
+ 'DefaultNewCellStyle',
+ 'DefaultOptions',
+ 'DefaultTicksStyle',
+ 'DefaultTooltipStyle',
+ 'Defer',
+ 'DefineInputStreamMethod',
+ 'DefineOutputStreamMethod',
+ 'Definition',
+ 'Degree',
+ 'DegreeCentrality',
+ 'DegreeGraphDistribution',
+ 'Deinitialization',
+ 'Del',
+ 'DelaunayMesh',
+ 'Delayed',
+ 'Deletable',
+ 'Delete',
+ 'DeleteBorderComponents',
+ 'DeleteCases',
+ 'DeleteChannel',
+ 'DeleteCloudExpression',
+ 'DeleteContents',
+ 'DeleteDirectory',
+ 'DeleteDuplicates',
+ 'DeleteDuplicatesBy',
+ 'DeleteFile',
+ 'DeleteMissing',
+ 'DeletePermissionsKey',
+ 'DeleteSearchIndex',
+ 'DeleteSmallComponents',
+ 'DeleteStopwords',
+ 'DelimitedSequence',
+ 'Delimiter',
+ 'DelimiterFlashTime',
+ 'Delimiters',
+ 'DeliveryFunction',
+ 'Dendrogram',
+ 'Denominator',
+ 'DensityHistogram',
+ 'DensityPlot',
+ 'DensityPlot3D',
+ 'DependentVariables',
+ 'Deploy',
+ 'Deployed',
+ 'Depth',
+ 'DepthFirstScan',
+ 'Derivative',
+ 'DerivativeFilter',
+ 'DescriptorStateSpace',
+ 'DesignMatrix',
+ 'Det',
+ 'DeviceClose',
+ 'DeviceConfigure',
+ 'DeviceExecute',
+ 'DeviceExecuteAsynchronous',
+ 'DeviceObject',
+ 'DeviceOpen',
+ 'DeviceRead',
+ 'DeviceReadBuffer',
+ 'DeviceReadLatest',
+ 'DeviceReadList',
+ 'DeviceReadTimeSeries',
+ 'DeviceStreams',
+ 'DeviceWrite',
+ 'DeviceWriteBuffer',
+ 'Devices',
+ 'Diagonal',
+ 'DiagonalMatrix',
+ 'DiagonalizableMatrixQ',
+ 'Dialog',
+ 'DialogInput',
+ 'DialogNotebook',
+ 'DialogProlog',
+ 'DialogReturn',
+ 'DialogSymbols',
+ 'Diamond',
+ 'DiamondMatrix',
+ 'DiceDissimilarity',
+ 'DictionaryLookup',
+ 'DictionaryWordQ',
+ 'DifferenceDelta',
+ 'DifferenceQuotient',
+ 'DifferenceRoot',
+ 'DifferenceRootReduce',
+ 'Differences',
+ 'DifferentialD',
+ 'DifferentialRoot',
+ 'DifferentialRootReduce',
+ 'DifferentiatorFilter',
+ 'DigitBlock',
+ 'DigitCharacter',
+ 'DigitCount',
+ 'DigitQ',
+ 'DihedralGroup',
+ 'Dilation',
+ 'DimensionReduce',
+ 'DimensionReducerFunction',
+ 'DimensionReduction',
+ 'DimensionalCombinations',
+ 'DimensionalMeshComponents',
+ 'Dimensions',
+ 'DiracComb',
+ 'DiracDelta',
+ 'DirectedEdge',
+ 'DirectedEdges',
+ 'DirectedGraph',
+ 'DirectedGraphQ',
+ 'DirectedInfinity',
+ 'Direction',
+ 'Directive',
+ 'Directory',
+ 'DirectoryName',
+ 'DirectoryQ',
+ 'DirectoryStack',
+ 'DirichletBeta',
+ 'DirichletCharacter',
+ 'DirichletCondition',
+ 'DirichletConvolve',
+ 'DirichletDistribution',
+ 'DirichletEta',
+ 'DirichletL',
+ 'DirichletLambda',
+ 'DirichletTransform',
+ 'DirichletWindow',
+ 'DisableFormatting',
+ 'DiscreteChirpZTransform',
+ 'DiscreteConvolve',
+ 'DiscreteDelta',
+ 'DiscreteHadamardTransform',
+ 'DiscreteIndicator',
+ 'DiscreteLQEstimatorGains',
+ 'DiscreteLQRegulatorGains',
+ 'DiscreteLyapunovSolve',
+ 'DiscreteMarkovProcess',
+ 'DiscretePlot',
+ 'DiscretePlot3D',
+ 'DiscreteRatio',
+ 'DiscreteRiccatiSolve',
+ 'DiscreteShift',
+ 'DiscreteTimeModelQ',
+ 'DiscreteUniformDistribution',
+ 'DiscreteVariables',
+ 'DiscreteWaveletData',
+ 'DiscreteWaveletPacketTransform',
+ 'DiscreteWaveletTransform',
+ 'DiscretizeGraphics',
+ 'DiscretizeRegion',
+ 'Discriminant',
+ 'DisjointQ',
+ 'Disjunction',
+ 'Disk',
+ 'DiskMatrix',
+ 'DiskSegment',
+ 'Dispatch',
+ 'DispersionEstimatorFunction',
+ 'DisplayAllSteps',
+ 'DisplayEndPacket',
+ 'DisplayForm',
+ 'DisplayFunction',
+ 'DisplayPacket',
+ 'DistanceFunction',
+ 'DistanceMatrix',
+ 'DistanceTransform',
+ 'Distribute',
+ 'DistributeDefinitions',
+ 'Distributed',
+ 'DistributedContexts',
+ 'DistributionChart',
+ 'DistributionFitTest',
+ 'DistributionParameterAssumptions',
+ 'DistributionParameterQ',
+ 'Dithering',
+ 'Div',
+ 'Divide',
+ 'DivideBy',
+ 'Dividers',
+ 'Divisible',
+ 'DivisorSigma',
+ 'DivisorSum',
+ 'Divisors',
+ 'Do',
+ 'DockedCells',
+ 'DocumentGenerator',
+ 'DocumentGeneratorInformation',
+ 'DocumentGenerators',
+ 'DocumentNotebook',
+ 'DominantColors',
+ 'Dot',
+ 'DotDashed',
+ 'DotEqual',
+ 'DotPlusLayer',
+ 'Dotted',
+ 'DoubleBracketingBar',
+ 'DoubleDownArrow',
+ 'DoubleLeftArrow',
+ 'DoubleLeftRightArrow',
+ 'DoubleLeftTee',
+ 'DoubleLongLeftArrow',
+ 'DoubleLongLeftRightArrow',
+ 'DoubleLongRightArrow',
+ 'DoubleRightArrow',
+ 'DoubleRightTee',
+ 'DoubleUpArrow',
+ 'DoubleUpDownArrow',
+ 'DoubleVerticalBar',
+ 'DownArrow',
+ 'DownArrowBar',
+ 'DownArrowUpArrow',
+ 'DownLeftRightVector',
+ 'DownLeftTeeVector',
+ 'DownLeftVector',
+ 'DownLeftVectorBar',
+ 'DownRightTeeVector',
+ 'DownRightVector',
+ 'DownRightVectorBar',
+ 'DownTee',
+ 'DownTeeArrow',
+ 'DownValues',
+ 'Downsample',
+ 'Drop',
+ 'DropoutLayer',
+ 'Dt',
+ 'DualSystemsModel',
+ 'DumpSave',
+ 'DuplicateFreeQ',
+ 'Duration',
+ 'Dynamic',
+ 'DynamicEvaluationTimeout',
+ 'DynamicGeoGraphics',
+ 'DynamicImage',
+ 'DynamicModule',
+ 'DynamicModuleValues',
+ 'DynamicSetting',
+ 'DynamicWrapper',
+
+ 'E',
+ 'EarthImpactData',
+ 'EarthquakeData',
+ 'EccentricityCentrality',
+ 'Echo',
+ 'EchoFunction',
+ 'EclipseType',
+ 'EdgeAdd',
+ 'EdgeBetweennessCentrality',
+ 'EdgeCapacity',
+ 'EdgeConnectivity',
+ 'EdgeContract',
+ 'EdgeCost',
+ 'EdgeCount',
+ 'EdgeCoverQ',
+ 'EdgeCycleMatrix',
+ 'EdgeDelete',
+ 'EdgeDetect',
+ 'EdgeForm',
+ 'EdgeIndex',
+ 'EdgeLabelStyle',
+ 'EdgeLabeling',
+ 'EdgeLabels',
+ 'EdgeList',
+ 'EdgeQ',
+ 'EdgeRenderingFunction',
+ 'EdgeRules',
+ 'EdgeShapeFunction',
+ 'EdgeStyle',
+ 'EdgeWeight',
+ 'EditDistance',
+ 'Editable',
+ 'EffectiveInterest',
+ 'Eigensystem',
+ 'Eigenvalues',
+ 'EigenvectorCentrality',
+ 'Eigenvectors',
+ 'Element',
+ 'ElementData',
+ 'ElementwiseLayer',
+ 'ElidedForms',
+ 'Eliminate',
+ 'Ellipsoid',
+ 'EllipticE',
+ 'EllipticExp',
+ 'EllipticExpPrime',
+ 'EllipticF',
+ 'EllipticFilterModel',
+ 'EllipticK',
+ 'EllipticLog',
+ 'EllipticNomeQ',
+ 'EllipticPi',
+ 'EllipticTheta',
+ 'EllipticThetaPrime',
+ 'EmbedCode',
+ 'EmbeddedHTML',
+ 'EmbeddedService',
+ 'EmbeddingLayer',
+ 'EmitSound',
+ 'EmpiricalDistribution',
+ 'EmptyGraphQ',
+ 'EmptyRegion',
+ 'Enabled',
+ 'Encode',
+ 'Encrypt',
+ 'EncryptedObject',
+ 'End',
+ 'EndDialogPacket',
+ 'EndOfBuffer',
+ 'EndOfFile',
+ 'EndOfLine',
+ 'EndOfString',
+ 'EndPackage',
+ 'EngineeringForm',
+ 'EnterExpressionPacket',
+ 'EnterTextPacket',
+ 'Entity',
+ 'EntityClass',
+ 'EntityClassList',
+ 'EntityCopies',
+ 'EntityGroup',
+ 'EntityInstance',
+ 'EntityList',
+ 'EntityProperties',
+ 'EntityProperty',
+ 'EntityPropertyClass',
+ 'EntityStore',
+ 'EntityTypeName',
+ 'EntityValue',
+ 'Entropy',
+ 'EntropyFilter',
+ 'Environment',
+ 'Epilog',
+ 'EpilogFunction',
+ 'Equal',
+ 'EqualTilde',
+ 'EqualTo',
+ 'Equilibrium',
+ 'EquirippleFilterKernel',
+ 'Equivalent',
+ 'Erf',
+ 'Erfc',
+ 'Erfi',
+ 'ErlangB',
+ 'ErlangC',
+ 'ErlangDistribution',
+ 'Erosion',
+ 'ErrorBox',
+ 'EscapeRadius',
+ 'EstimatedBackground',
+ 'EstimatedDistribution',
+ 'EstimatedProcess',
+ 'EstimatorGains',
+ 'EstimatorRegulator',
+ 'EuclideanDistance',
+ 'EulerAngles',
+ 'EulerE',
+ 'EulerGamma',
+ 'EulerMatrix',
+ 'EulerPhi',
+ 'EulerianGraphQ',
+ 'Evaluatable',
+ 'Evaluate',
+ 'EvaluatePacket',
+ 'EvaluateScheduledTask',
+ 'EvaluationBox',
+ 'EvaluationCell',
+ 'EvaluationData',
+ 'EvaluationElements',
+ 'EvaluationMonitor',
+ 'EvaluationNotebook',
+ 'EvaluationObject',
+ 'Evaluator',
+ 'EvenQ',
+ 'EventData',
+ 'EventHandler',
+ 'EventLabels',
+ 'EventSeries',
+ 'ExactBlackmanWindow',
+ 'ExactNumberQ',
+ 'ExampleData',
+ 'Except',
+ 'ExcludePods',
+ 'ExcludedForms',
+ 'ExcludedLines',
+ 'ExcludedPhysicalQuantities',
+ 'Exclusions',
+ 'ExclusionsStyle',
+ 'Exists',
+ 'Exit',
+ 'ExoplanetData',
+ 'Exp',
+ 'ExpGammaDistribution',
+ 'ExpIntegralE',
+ 'ExpIntegralEi',
+ 'ExpToTrig',
+ 'Expand',
+ 'ExpandAll',
+ 'ExpandDenominator',
+ 'ExpandFileName',
+ 'ExpandNumerator',
+ 'Expectation',
+ 'Exponent',
+ 'ExponentFunction',
+ 'ExponentStep',
+ 'ExponentialDistribution',
+ 'ExponentialFamily',
+ 'ExponentialGeneratingFunction',
+ 'ExponentialMovingAverage',
+ 'ExponentialPowerDistribution',
+ 'Export',
+ 'ExportForm',
+ 'ExportString',
+ 'Expression',
+ 'ExpressionCell',
+ 'ExtendedGCD',
+ 'Extension',
+ 'ExtentElementFunction',
+ 'ExtentMarkers',
+ 'ExtentSize',
+ 'ExternalBundle',
+ 'ExternalOptions',
+ 'ExternalTypeSignature',
+ 'Extract',
+ 'ExtractArchive',
+ 'ExtremeValueDistribution',
+
+ 'FARIMAProcess',
+ 'FRatioDistribution',
+ 'FaceForm',
+ 'FaceGrids',
+ 'FaceGridsStyle',
+ 'Factor',
+ 'FactorInteger',
+ 'FactorList',
+ 'FactorSquareFree',
+ 'FactorSquareFreeList',
+ 'FactorTerms',
+ 'FactorTermsList',
+ 'Factorial',
+ 'Factorial2',
+ 'FactorialMoment',
+ 'FactorialMomentGeneratingFunction',
+ 'FactorialPower',
+ 'Failure',
+ 'FailureAction',
+ 'FailureDistribution',
+ 'FailureQ',
+ 'False',
+ 'FareySequence',
+ 'FeatureDistance',
+ 'FeatureExtract',
+ 'FeatureExtraction',
+ 'FeatureExtractor',
+ 'FeatureExtractorFunction',
+ 'FeatureNames',
+ 'FeatureTypes',
+ 'FeedbackLinearize',
+ 'FeedbackSector',
+ 'FeedbackSectorStyle',
+ 'FeedbackType',
+ 'FetalGrowthData',
+ 'Fibonacci',
+ 'Fibonorial',
+ 'FieldHint',
+ 'FieldHintStyle',
+ 'FieldMasked',
+ 'FieldSize',
+ 'File',
+ 'FileBaseName',
+ 'FileByteCount',
+ 'FileDate',
+ 'FileExistsQ',
+ 'FileExtension',
+ 'FileFormat',
+ 'FileHash',
+ 'FileNameDepth',
+ 'FileNameDrop',
+ 'FileNameForms',
+ 'FileNameJoin',
+ 'FileNameSetter',
+ 'FileNameSplit',
+ 'FileNameTake',
+ 'FileNames',
+ 'FilePrint',
+ 'FileSystemMap',
+ 'FileSystemScan',
+ 'FileTemplate',
+ 'FileTemplateApply',
+ 'FileType',
+ 'FilledCurve',
+ 'Filling',
+ 'FillingStyle',
+ 'FillingTransform',
+ 'FilterRules',
+ 'FinancialBond',
+ 'FinancialData',
+ 'FinancialDerivative',
+ 'FinancialIndicator',
+ 'Find',
+ 'FindArgMax',
+ 'FindArgMin',
+ 'FindChannels',
+ 'FindClique',
+ 'FindClusters',
+ 'FindCookies',
+ 'FindCurvePath',
+ 'FindCycle',
+ 'FindDevices',
+ 'FindDistribution',
+ 'FindDistributionParameters',
+ 'FindDivisions',
+ 'FindEdgeCover',
+ 'FindEdgeCut',
+ 'FindEdgeIndependentPaths',
+ 'FindEulerianCycle',
+ 'FindFaces',
+ 'FindFile',
+ 'FindFit',
+ 'FindFormula',
+ 'FindFundamentalCycles',
+ 'FindGeneratingFunction',
+ 'FindGeoLocation',
+ 'FindGeometricTransform',
+ 'FindGraphCommunities',
+ 'FindGraphIsomorphism',
+ 'FindGraphPartition',
+ 'FindHamiltonianCycle',
+ 'FindHamiltonianPath',
+ 'FindHiddenMarkovStates',
+ 'FindIndependentEdgeSet',
+ 'FindIndependentVertexSet',
+ 'FindInstance',
+ 'FindIntegerNullVector',
+ 'FindKClan',
+ 'FindKClique',
+ 'FindKClub',
+ 'FindKPlex',
+ 'FindLibrary',
+ 'FindLinearRecurrence',
+ 'FindList',
+ 'FindMaxValue',
+ 'FindMaximum',
+ 'FindMaximumFlow',
+ 'FindMeshDefects',
+ 'FindMinValue',
+ 'FindMinimum',
+ 'FindMinimumCostFlow',
+ 'FindMinimumCut',
+ 'FindPath',
+ 'FindPeaks',
+ 'FindPermutation',
+ 'FindPostmanTour',
+ 'FindProcessParameters',
+ 'FindRoot',
+ 'FindSequenceFunction',
+ 'FindSettings',
+ 'FindShortestPath',
+ 'FindShortestTour',
+ 'FindSpanningTree',
+ 'FindThreshold',
+ 'FindTransientRepeat',
+ 'FindVertexCover',
+ 'FindVertexCut',
+ 'FindVertexIndependentPaths',
+ 'FinishDynamic',
+ 'FiniteAbelianGroupCount',
+ 'FiniteGroupCount',
+ 'FiniteGroupData',
+ 'First',
+ 'FirstCase',
+ 'FirstPassageTimeDistribution',
+ 'FirstPosition',
+ 'FischerGroupFi22',
+ 'FischerGroupFi23',
+ 'FischerGroupFi24Prime',
+ 'FisherHypergeometricDistribution',
+ 'FisherRatioTest',
+ 'FisherZDistribution',
+ 'Fit',
+ 'FittedModel',
+ 'FixedOrder',
+ 'FixedPoint',
+ 'FixedPointList',
+ 'Flat',
+ 'FlatTopWindow',
+ 'Flatten',
+ 'FlattenAt',
+ 'FlattenLayer',
+ 'FlipView',
+ 'Floor',
+ 'FlowPolynomial',
+ 'Fold',
+ 'FoldList',
+ 'FoldPair',
+ 'FoldPairList',
+ 'FollowRedirects',
+ 'FontColor',
+ 'FontFamily',
+ 'FontSize',
+ 'FontSlant',
+ 'FontSubstitutions',
+ 'FontTracking',
+ 'FontVariations',
+ 'FontWeight',
+ 'For',
+ 'ForAll',
+ 'FormBox',
+ 'FormBoxOptions',
+ 'FormControl',
+ 'FormFunction',
+ 'FormLayoutFunction',
+ 'FormObject',
+ 'FormPage',
+ 'Format',
+ 'FormatType',
+ 'FormulaData',
+ 'FormulaLookup',
+ 'FortranForm',
+ 'Forward',
+ 'ForwardBackward',
+ 'Fourier',
+ 'FourierCoefficient',
+ 'FourierCosCoefficient',
+ 'FourierCosSeries',
+ 'FourierCosTransform',
+ 'FourierDCT',
+ 'FourierDCTFilter',
+ 'FourierDCTMatrix',
+ 'FourierDST',
+ 'FourierDSTMatrix',
+ 'FourierMatrix',
+ 'FourierParameters',
+ 'FourierSequenceTransform',
+ 'FourierSeries',
+ 'FourierSinCoefficient',
+ 'FourierSinSeries',
+ 'FourierSinTransform',
+ 'FourierTransform',
+ 'FourierTrigSeries',
+ 'FractionBox',
+ 'FractionBoxOptions',
+ 'FractionalBrownianMotionProcess',
+ 'FractionalGaussianNoiseProcess',
+ 'FractionalPart',
+ 'Frame',
+ 'FrameBox',
+ 'FrameBoxOptions',
+ 'FrameLabel',
+ 'FrameMargins',
+ 'FrameStyle',
+ 'FrameTicks',
+ 'FrameTicksStyle',
+ 'Framed',
+ 'FrechetDistribution',
+ 'FreeQ',
+ 'FrenetSerretSystem',
+ 'FrequencySamplingFilterKernel',
+ 'FresnelC',
+ 'FresnelF',
+ 'FresnelG',
+ 'FresnelS',
+ 'Friday',
+ 'FrobeniusNumber',
+ 'FrobeniusSolve',
+ 'FromCharacterCode',
+ 'FromCoefficientRules',
+ 'FromContinuedFraction',
+ 'FromDMS',
+ 'FromDigits',
+ 'FromEntity',
+ 'FromJulianDate',
+ 'FromLetterNumber',
+ 'FromPolarCoordinates',
+ 'FromRomanNumeral',
+ 'FromSphericalCoordinates',
+ 'FromUnixTime',
+ 'Front',
+ 'FrontEndDynamicExpression',
+ 'FrontEndEventActions',
+ 'FrontEndExecute',
+ 'FrontEndToken',
+ 'FrontEndTokenExecute',
+ 'Full',
+ 'FullDefinition',
+ 'FullForm',
+ 'FullGraphics',
+ 'FullInformationOutputRegulator',
+ 'FullRegion',
+ 'FullSimplify',
+ 'Function',
+ 'FunctionDomain',
+ 'FunctionExpand',
+ 'FunctionInterpolation',
+ 'FunctionPeriod',
+ 'FunctionRange',
+ 'FunctionSpace',
+ 'FussellVeselyImportance',
+
+ 'GARCHProcess',
+ 'GCD',
+ 'GaborFilter',
+ 'GaborMatrix',
+ 'GaborWavelet',
+ 'GainMargins',
+ 'GainPhaseMargins',
+ 'GalaxyData',
+ 'GalleryView',
+ 'Gamma',
+ 'GammaDistribution',
+ 'GammaRegularized',
+ 'GapPenalty',
+ 'Gather',
+ 'GatherBy',
+ 'GaugeFaceElementFunction',
+ 'GaugeFaceStyle',
+ 'GaugeFrameElementFunction',
+ 'GaugeFrameSize',
+ 'GaugeFrameStyle',
+ 'GaugeLabels',
+ 'GaugeMarkers',
+ 'GaugeStyle',
+ 'GaussianFilter',
+ 'GaussianIntegers',
+ 'GaussianMatrix',
+ 'GaussianOrthogonalMatrixDistribution',
+ 'GaussianSymplecticMatrixDistribution',
+ 'GaussianUnitaryMatrixDistribution',
+ 'GaussianWindow',
+ 'GegenbauerC',
+ 'General',
+ 'GeneralizedLinearModelFit',
+ 'GenerateAsymmetricKeyPair',
+ 'GenerateConditions',
+ 'GenerateDocument',
+ 'GenerateHTTPResponse',
+ 'GenerateSymmetricKey',
+ 'GeneratedCell',
+ 'GeneratedDocumentBinding',
+ 'GeneratedParameters',
+ 'GeneratingFunction',
+ 'GeneratorDescription',
+ 'GeneratorHistoryLength',
+ 'GeneratorOutputType',
+ 'GenericCylindricalDecomposition',
+ 'GenomeData',
+ 'GenomeLookup',
+ 'GeoArea',
+ 'GeoBackground',
+ 'GeoBoundingBox',
+ 'GeoBounds',
+ 'GeoBoundsRegion',
+ 'GeoCenter',
+ 'GeoCircle',
+ 'GeoDestination',
+ 'GeoDirection',
+ 'GeoDisk',
+ 'GeoDisplacement',
+ 'GeoDistance',
+ 'GeoDistanceList',
+ 'GeoElevationData',
+ 'GeoEntities',
+ 'GeoGraphics',
+ 'GeoGridLines',
+ 'GeoGridLinesStyle',
+ 'GeoGridPosition',
+ 'GeoGroup',
+ 'GeoHemisphere',
+ 'GeoHemisphereBoundary',
+ 'GeoHistogram',
+ 'GeoIdentify',
+ 'GeoLabels',
+ 'GeoLength',
+ 'GeoListPlot',
+ 'GeoLocation',
+ 'GeoMarker',
+ 'GeoModel',
+ 'GeoNearest',
+ 'GeoPath',
+ 'GeoPosition',
+ 'GeoPositionENU',
+ 'GeoPositionXYZ',
+ 'GeoProjection',
+ 'GeoProjectionData',
+ 'GeoRange',
+ 'GeoRangePadding',
+ 'GeoRegionValuePlot',
+ 'GeoScaleBar',
+ 'GeoServer',
+ 'GeoStyling',
+ 'GeoStylingImageFunction',
+ 'GeoVariant',
+ 'GeoVisibleRegion',
+ 'GeoVisibleRegionBoundary',
+ 'GeoWithinQ',
+ 'GeoZoomLevel',
+ 'GeodesicClosing',
+ 'GeodesicDilation',
+ 'GeodesicErosion',
+ 'GeodesicOpening',
+ 'GeodesyData',
+ 'GeogravityModelData',
+ 'GeologicalPeriodData',
+ 'GeomagneticModelData',
+ 'GeometricBrownianMotionProcess',
+ 'GeometricDistribution',
+ 'GeometricMean',
+ 'GeometricMeanFilter',
+ 'GeometricTransformation',
+ 'GestureHandler',
+ 'Get',
+ 'GetEnvironment',
+ 'Glaisher',
+ 'GlobalClusteringCoefficient',
+ 'Glow',
+ 'GoldenAngle',
+ 'GoldenRatio',
+ 'GompertzMakehamDistribution',
+ 'GoodmanKruskalGamma',
+ 'GoodmanKruskalGammaTest',
+ 'Goto',
+ 'Grad',
+ 'Gradient',
+ 'GradientFilter',
+ 'GradientOrientationFilter',
+ 'GrammarApply',
+ 'GrammarRules',
+ 'GrammarToken',
+ 'Graph',
+ 'Graph3D',
+ 'GraphAssortativity',
+ 'GraphAutomorphismGroup',
+ 'GraphCenter',
+ 'GraphComplement',
+ 'GraphData',
+ 'GraphDensity',
+ 'GraphDiameter',
+ 'GraphDifference',
+ 'GraphDisjointUnion',
+ 'GraphDistance',
+ 'GraphDistanceMatrix',
+ 'GraphEmbedding',
+ 'GraphHighlight',
+ 'GraphHighlightStyle',
+ 'GraphHub',
+ 'GraphIntersection',
+ 'GraphLayout',
+ 'GraphLinkEfficiency',
+ 'GraphPeriphery',
+ 'GraphPlot',
+ 'GraphPlot3D',
+ 'GraphPower',
+ 'GraphPropertyDistribution',
+ 'GraphQ',
+ 'GraphRadius',
+ 'GraphReciprocity',
+ 'GraphStyle',
+ 'GraphUnion',
+ 'Graphics',
+ 'Graphics3D',
+ 'GraphicsColumn',
+ 'GraphicsComplex',
+ 'GraphicsGrid',
+ 'GraphicsGroup',
+ 'GraphicsRow',
+ 'Gray',
+ 'GrayLevel',
+ 'Greater',
+ 'GreaterEqual',
+ 'GreaterEqualLess',
+ 'GreaterEqualThan',
+ 'GreaterFullEqual',
+ 'GreaterGreater',
+ 'GreaterLess',
+ 'GreaterSlantEqual',
+ 'GreaterThan',
+ 'GreaterTilde',
+ 'Green',
+ 'GreenFunction',
+ 'Grid',
+ 'GridBox',
+ 'GridDefaultElement',
+ 'GridGraph',
+ 'GridLines',
+ 'GridLinesStyle',
+ 'GroebnerBasis',
+ 'GroupActionBase',
+ 'GroupBy',
+ 'GroupCentralizer',
+ 'GroupElementFromWord',
+ 'GroupElementPosition',
+ 'GroupElementQ',
+ 'GroupElementToWord',
+ 'GroupElements',
+ 'GroupGenerators',
+ 'GroupMultiplicationTable',
+ 'GroupOrbits',
+ 'GroupOrder',
+ 'GroupPageBreakWithin',
+ 'GroupSetwiseStabilizer',
+ 'GroupStabilizer',
+ 'GroupStabilizerChain',
+ 'Groupings',
+ 'GrowCutComponents',
+ 'Gudermannian',
+ 'GuidedFilter',
+ 'GumbelDistribution',
+
+ 'HITSCentrality',
+ 'HTTPErrorResponse',
+ 'HTTPRedirect',
+ 'HTTPRequest',
+ 'HTTPRequestData',
+ 'HTTPResponse',
+ 'HaarWavelet',
+ 'HadamardMatrix',
+ 'HalfLine',
+ 'HalfNormalDistribution',
+ 'HalfPlane',
+ 'HalfSpace',
+ 'HamiltonianGraphQ',
+ 'HammingDistance',
+ 'HammingWindow',
+ 'HandlerFunctions',
+ 'HandlerFunctionsKeys',
+ 'HankelH1',
+ 'HankelH2',
+ 'HankelMatrix',
+ 'HannPoissonWindow',
+ 'HannWindow',
+ 'HaradaNortonGroupHN',
+ 'HararyGraph',
+ 'HarmonicMean',
+ 'HarmonicMeanFilter',
+ 'HarmonicNumber',
+ 'Hash',
+ 'Haversine',
+ 'HazardFunction',
+ 'Head',
+ 'HeaderLines',
+ 'Heads',
+ 'HeavisideLambda',
+ 'HeavisidePi',
+ 'HeavisideTheta',
+ 'HeldGroupHe',
+ 'Here',
+ 'HermiteDecomposition',
+ 'HermiteH',
+ 'HermitianMatrixQ',
+ 'HessenbergDecomposition',
+ 'HexadecimalCharacter',
+ 'Hexahedron',
+ 'HiddenMarkovProcess',
+ 'HighlightGraph',
+ 'HighlightImage',
+ 'HighlightMesh',
+ 'Highlighted',
+ 'HighpassFilter',
+ 'HigmanSimsGroupHS',
+ 'HilbertFilter',
+ 'HilbertMatrix',
+ 'Histogram',
+ 'Histogram3D',
+ 'HistogramDistribution',
+ 'HistogramList',
+ 'HistogramTransform',
+ 'HistogramTransformInterpolation',
+ 'HistoricalPeriodData',
+ 'HitMissTransform',
+ 'HodgeDual',
+ 'HoeffdingD',
+ 'HoeffdingDTest',
+ 'Hold',
+ 'HoldAll',
+ 'HoldAllComplete',
+ 'HoldComplete',
+ 'HoldFirst',
+ 'HoldForm',
+ 'HoldPattern',
+ 'HoldRest',
+ 'HolidayCalendar',
+ 'HorizontalGauge',
+ 'HornerForm',
+ 'HostLookup',
+ 'HotellingTSquareDistribution',
+ 'HoytDistribution',
+ 'Hue',
+ 'HumanGrowthData',
+ 'HumpDownHump',
+ 'HumpEqual',
+ 'HurwitzLerchPhi',
+ 'HurwitzZeta',
+ 'HyperbolicDistribution',
+ 'HypercubeGraph',
+ 'HyperexponentialDistribution',
+ 'Hyperfactorial',
+ 'Hypergeometric0F1',
+ 'Hypergeometric0F1Regularized',
+ 'Hypergeometric1F1',
+ 'Hypergeometric1F1Regularized',
+ 'Hypergeometric2F1',
+ 'Hypergeometric2F1Regularized',
+ 'HypergeometricDistribution',
+ 'HypergeometricPFQ',
+ 'HypergeometricPFQRegularized',
+ 'HypergeometricU',
+ 'Hyperlink',
+ 'Hyperplane',
+ 'Hyphenation',
+ 'HypoexponentialDistribution',
+ 'HypothesisTestData',
+
+ 'I',
+ 'IPAddress',
+ 'IconData',
+ 'IconRules',
+ 'Identity',
+ 'IdentityMatrix',
+ 'If',
+ 'IgnoreCase',
+ 'IgnoreDiacritics',
+ 'IgnorePunctuation',
+ 'IgnoringInactive',
+ 'Im',
+ 'Image',
+ 'Image3D',
+ 'Image3DSlices',
+ 'ImageAccumulate',
+ 'ImageAdd',
+ 'ImageAdjust',
+ 'ImageAlign',
+ 'ImageApply',
+ 'ImageApplyIndexed',
+ 'ImageAspectRatio',
+ 'ImageAssemble',
+ 'ImageCapture',
+ 'ImageChannels',
+ 'ImageClip',
+ 'ImageCollage',
+ 'ImageColorSpace',
+ 'ImageCompose',
+ 'ImageConvolve',
+ 'ImageCooccurrence',
+ 'ImageCorners',
+ 'ImageCorrelate',
+ 'ImageCorrespondingPoints',
+ 'ImageCrop',
+ 'ImageData',
+ 'ImageDeconvolve',
+ 'ImageDemosaic',
+ 'ImageDifference',
+ 'ImageDimensions',
+ 'ImageDisplacements',
+ 'ImageDistance',
+ 'ImageEffect',
+ 'ImageExposureCombine',
+ 'ImageFeatureTrack',
+ 'ImageFileApply',
+ 'ImageFileFilter',
+ 'ImageFileScan',
+ 'ImageFilter',
+ 'ImageFocusCombine',
+ 'ImageForestingComponents',
+ 'ImageFormattingWidth',
+ 'ImageForwardTransformation',
+ 'ImageHistogram',
+ 'ImageIdentify',
+ 'ImageInstanceQ',
+ 'ImageKeypoints',
+ 'ImageLevels',
+ 'ImageLines',
+ 'ImageMargins',
+ 'ImageMarker',
+ 'ImageMeasurements',
+ 'ImageMesh',
+ 'ImageMultiply',
+ 'ImagePad',
+ 'ImagePadding',
+ 'ImagePartition',
+ 'ImagePeriodogram',
+ 'ImagePerspectiveTransformation',
+ 'ImageQ',
+ 'ImageReflect',
+ 'ImageResize',
+ 'ImageResolution',
+ 'ImageRotate',
+ 'ImageSaliencyFilter',
+ 'ImageScaled',
+ 'ImageScan',
+ 'ImageSize',
+ 'ImageSizeAction',
+ 'ImageSizeMultipliers',
+ 'ImageSubtract',
+ 'ImageTake',
+ 'ImageTransformation',
+ 'ImageTrim',
+ 'ImageType',
+ 'ImageValue',
+ 'ImageValuePositions',
+ 'ImagingDevice',
+ 'ImplicitRegion',
+ 'Implies',
+ 'Import',
+ 'ImportOptions',
+ 'ImportString',
+ 'ImprovementImportance',
+ 'In',
+ 'InString',
+ 'Inactivate',
+ 'Inactive',
+ 'IncidenceGraph',
+ 'IncidenceList',
+ 'IncidenceMatrix',
+ 'IncludeConstantBasis',
+ 'IncludeGeneratorTasks',
+ 'IncludeInflections',
+ 'IncludeMetaInformation',
+ 'IncludePods',
+ 'IncludeQuantities',
+ 'IncludeWindowTimes',
+ 'Increment',
+ 'IndefiniteMatrixQ',
+ 'IndependenceTest',
+ 'IndependentEdgeSetQ',
+ 'IndependentUnit',
+ 'IndependentVertexSetQ',
+ 'Indeterminate',
+ 'IndeterminateThreshold',
+ 'IndexGraph',
+ 'Indexed',
+ 'InexactNumberQ',
+ 'InfiniteLine',
+ 'InfinitePlane',
+ 'Infinity',
+ 'Infix',
+ 'InflationAdjust',
+ 'InflationMethod',
+ 'Information',
+ 'InheritScope',
+ 'Inherited',
+ 'InhomogeneousPoissonProcess',
+ 'InitialEvaluationHistory',
+ 'Initialization',
+ 'InitializationCell',
+ 'Inner',
+ 'Inpaint',
+ 'Input',
+ 'InputAliases',
+ 'InputAssumptions',
+ 'InputAutoReplacements',
+ 'InputField',
+ 'InputForm',
+ 'InputNamePacket',
+ 'InputNotebook',
+ 'InputPacket',
+ 'InputStream',
+ 'InputString',
+ 'InputStringPacket',
+ 'Insert',
+ 'InsertLinebreaks',
+ 'InsertResults',
+ 'InsertionFunction',
+ 'Inset',
+ 'Insphere',
+ 'Install',
+ 'InstallService',
+ 'Integer',
+ 'IntegerDigits',
+ 'IntegerExponent',
+ 'IntegerLength',
+ 'IntegerName',
+ 'IntegerPart',
+ 'IntegerPartitions',
+ 'IntegerQ',
+ 'IntegerReverse',
+ 'IntegerString',
+ 'Integers',
+ 'Integrate',
+ 'Interactive',
+ 'InteractiveTradingChart',
+ 'Interleaving',
+ 'InternallyBalancedDecomposition',
+ 'InterpolatingFunction',
+ 'InterpolatingPolynomial',
+ 'Interpolation',
+ 'InterpolationOrder',
+ 'InterpolationPoints',
+ 'Interpretation',
+ 'InterpretationBox',
+ 'InterpretationBoxOptions',
+ 'Interpreter',
+ 'InterquartileRange',
+ 'Interrupt',
+ 'IntersectingQ',
+ 'Intersection',
+ 'Interval',
+ 'IntervalIntersection',
+ 'IntervalMemberQ',
+ 'IntervalSlider',
+ 'IntervalUnion',
+ 'Inverse',
+ 'InverseBetaRegularized',
+ 'InverseCDF',
+ 'InverseChiSquareDistribution',
+ 'InverseContinuousWaveletTransform',
+ 'InverseDistanceTransform',
+ 'InverseEllipticNomeQ',
+ 'InverseErf',
+ 'InverseErfc',
+ 'InverseFourier',
+ 'InverseFourierCosTransform',
+ 'InverseFourierSequenceTransform',
+ 'InverseFourierSinTransform',
+ 'InverseFourierTransform',
+ 'InverseFunction',
+ 'InverseFunctions',
+ 'InverseGammaDistribution',
+ 'InverseGammaRegularized',
+ 'InverseGaussianDistribution',
+ 'InverseGudermannian',
+ 'InverseHaversine',
+ 'InverseJacobiCD',
+ 'InverseJacobiCN',
+ 'InverseJacobiCS',
+ 'InverseJacobiDC',
+ 'InverseJacobiDN',
+ 'InverseJacobiDS',
+ 'InverseJacobiNC',
+ 'InverseJacobiND',
+ 'InverseJacobiNS',
+ 'InverseJacobiSC',
+ 'InverseJacobiSD',
+ 'InverseJacobiSN',
+ 'InverseLaplaceTransform',
+ 'InverseMellinTransform',
+ 'InversePermutation',
+ 'InverseRadon',
+ 'InverseSeries',
+ 'InverseSurvivalFunction',
+ 'InverseTransformedRegion',
+ 'InverseWaveletTransform',
+ 'InverseWeierstrassP',
+ 'InverseWishartMatrixDistribution',
+ 'InverseZTransform',
+ 'Invisible',
+ 'IrreduciblePolynomialQ',
+ 'IslandData',
+ 'IsolatingInterval',
+ 'IsomorphicGraphQ',
+ 'IsotopeData',
+ 'Italic',
+ 'Item',
+ 'ItemAspectRatio',
+ 'ItemSize',
+ 'ItemStyle',
+ 'ItoProcess',
+
+ 'JaccardDissimilarity',
+ 'JacobiAmplitude',
+ 'JacobiCD',
+ 'JacobiCN',
+ 'JacobiCS',
+ 'JacobiDC',
+ 'JacobiDN',
+ 'JacobiDS',
+ 'JacobiNC',
+ 'JacobiND',
+ 'JacobiNS',
+ 'JacobiP',
+ 'JacobiSC',
+ 'JacobiSD',
+ 'JacobiSN',
+ 'JacobiSymbol',
+ 'JacobiZeta',
+ 'JankoGroupJ1',
+ 'JankoGroupJ2',
+ 'JankoGroupJ3',
+ 'JankoGroupJ4',
+ 'JarqueBeraALMTest',
+ 'JohnsonDistribution',
+ 'Join',
+ 'JoinAcross',
+ 'JoinForm',
+ 'Joined',
+ 'JoinedCurve',
+ 'JordanDecomposition',
+ 'JordanModelDecomposition',
+ 'JuliaSetBoettcher',
+ 'JuliaSetIterationCount',
+ 'JuliaSetPlot',
+ 'JuliaSetPoints',
+ 'JulianDate',
+
+ 'KCoreComponents',
+ 'KDistribution',
+ 'KEdgeConnectedComponents',
+ 'KEdgeConnectedGraphQ',
+ 'KVertexConnectedComponents',
+ 'KVertexConnectedGraphQ',
+ 'KagiChart',
+ 'KaiserBesselWindow',
+ 'KaiserWindow',
+ 'KalmanEstimator',
+ 'KalmanFilter',
+ 'KarhunenLoeveDecomposition',
+ 'KaryTree',
+ 'KatzCentrality',
+ 'KelvinBei',
+ 'KelvinBer',
+ 'KelvinKei',
+ 'KelvinKer',
+ 'KendallTau',
+ 'KendallTauTest',
+ 'KernelMixtureDistribution',
+ 'KernelObject',
+ 'Kernels',
+ 'Key',
+ 'KeyCollisionFunction',
+ 'KeyComplement',
+ 'KeyDrop',
+ 'KeyDropFrom',
+ 'KeyExistsQ',
+ 'KeyFreeQ',
+ 'KeyIntersection',
+ 'KeyMap',
+ 'KeyMemberQ',
+ 'KeySelect',
+ 'KeySort',
+ 'KeySortBy',
+ 'KeyTake',
+ 'KeyUnion',
+ 'KeyValueMap',
+ 'KeyValuePattern',
+ 'KeypointStrength',
+ 'Keys',
+ 'Khinchin',
+ 'KillProcess',
+ 'KirchhoffGraph',
+ 'KirchhoffMatrix',
+ 'KleinInvariantJ',
+ 'KnapsackSolve',
+ 'KnightTourGraph',
+ 'KnotData',
+ 'KnownUnitQ',
+ 'KolmogorovSmirnovTest',
+ 'KroneckerDelta',
+ 'KroneckerModelDecomposition',
+ 'KroneckerProduct',
+ 'KroneckerSymbol',
+ 'KuiperTest',
+ 'KumaraswamyDistribution',
+ 'Kurtosis',
+ 'KuwaharaFilter',
+
+ 'LABColor',
+ 'LCHColor',
+ 'LCM',
+ 'LQEstimatorGains',
+ 'LQGRegulator',
+ 'LQOutputRegulatorGains',
+ 'LQRegulatorGains',
+ 'LUDecomposition',
+ 'LUVColor',
+ 'Label',
+ 'LabelStyle',
+ 'Labeled',
+ 'LabelingFunction',
+ 'LaguerreL',
+ 'LakeData',
+ 'LambdaComponents',
+ 'LaminaData',
+ 'LanczosWindow',
+ 'LandauDistribution',
+ 'Language',
+ 'LanguageCategory',
+ 'LanguageData',
+ 'LanguageIdentify',
+ 'LaplaceDistribution',
+ 'LaplaceTransform',
+ 'Laplacian',
+ 'LaplacianFilter',
+ 'LaplacianGaussianFilter',
+ 'Large',
+ 'Larger',
+ 'Last',
+ 'Latitude',
+ 'LatitudeLongitude',
+ 'LatticeData',
+ 'LatticeReduce',
+ 'LaunchKernels',
+ 'LayerSizeFunction',
+ 'LayeredGraphPlot',
+ 'LeaderSize',
+ 'LeafCount',
+ 'LeapYearQ',
+ 'LeastSquares',
+ 'LeastSquaresFilterKernel',
+ 'Left',
+ 'LeftArrow',
+ 'LeftArrowBar',
+ 'LeftArrowRightArrow',
+ 'LeftDownTeeVector',
+ 'LeftDownVector',
+ 'LeftDownVectorBar',
+ 'LeftRightArrow',
+ 'LeftRightVector',
+ 'LeftTee',
+ 'LeftTeeArrow',
+ 'LeftTeeVector',
+ 'LeftTriangle',
+ 'LeftTriangleBar',
+ 'LeftTriangleEqual',
+ 'LeftUpDownVector',
+ 'LeftUpTeeVector',
+ 'LeftUpVector',
+ 'LeftUpVectorBar',
+ 'LeftVector',
+ 'LeftVectorBar',
+ 'LegendAppearance',
+ 'LegendFunction',
+ 'LegendLabel',
+ 'LegendLayout',
+ 'LegendMargins',
+ 'LegendMarkerSize',
+ 'LegendMarkers',
+ 'Legended',
+ 'LegendreP',
+ 'LegendreQ',
+ 'Length',
+ 'LengthWhile',
+ 'LerchPhi',
+ 'Less',
+ 'LessEqual',
+ 'LessEqualGreater',
+ 'LessEqualThan',
+ 'LessFullEqual',
+ 'LessGreater',
+ 'LessLess',
+ 'LessSlantEqual',
+ 'LessThan',
+ 'LessTilde',
+ 'LetterCharacter',
+ 'LetterCounts',
+ 'LetterNumber',
+ 'LetterQ',
+ 'Level',
+ 'LeveneTest',
+ 'LeviCivitaTensor',
+ 'LevyDistribution',
+ 'LibraryDataType',
+ 'LibraryFunction',
+ 'LibraryFunctionError',
+ 'LibraryFunctionInformation',
+ 'LibraryFunctionLoad',
+ 'LibraryFunctionUnload',
+ 'LibraryLoad',
+ 'LibraryUnload',
+ 'LiftingFilterData',
+ 'LiftingWaveletTransform',
+ 'LightBlue',
+ 'LightBrown',
+ 'LightCyan',
+ 'LightGray',
+ 'LightGreen',
+ 'LightMagenta',
+ 'LightOrange',
+ 'LightPink',
+ 'LightPurple',
+ 'LightRed',
+ 'LightYellow',
+ 'Lighter',
+ 'Lighting',
+ 'LightingAngle',
+ 'Likelihood',
+ 'Limit',
+ 'LimitsPositioning',
+ 'LindleyDistribution',
+ 'Line',
+ 'LineBreakChart',
+ 'LineGraph',
+ 'LineIndent',
+ 'LineIndentMaxFraction',
+ 'LineIntegralConvolutionPlot',
+ 'LineIntegralConvolutionScale',
+ 'LineLegend',
+ 'LineSpacing',
+ 'LinearFractionalTransform',
+ 'LinearGradientImage',
+ 'LinearModelFit',
+ 'LinearOffsetFunction',
+ 'LinearProgramming',
+ 'LinearRecurrence',
+ 'LinearSolve',
+ 'LinearSolveFunction',
+ 'LinearizingTransformationData',
+ 'LinkActivate',
+ 'LinkClose',
+ 'LinkConnect',
+ 'LinkCreate',
+ 'LinkFunction',
+ 'LinkInterrupt',
+ 'LinkLaunch',
+ 'LinkObject',
+ 'LinkPatterns',
+ 'LinkProtocol',
+ 'LinkRankCentrality',
+ 'LinkRead',
+ 'LinkReadyQ',
+ 'LinkWrite',
+ 'Links',
+ 'LiouvilleLambda',
+ 'List',
+ 'ListAnimate',
+ 'ListContourPlot',
+ 'ListContourPlot3D',
+ 'ListConvolve',
+ 'ListCorrelate',
+ 'ListCurvePathPlot',
+ 'ListDeconvolve',
+ 'ListDensityPlot',
+ 'ListDensityPlot3D',
+ 'ListFormat',
+ 'ListFourierSequenceTransform',
+ 'ListInterpolation',
+ 'ListLineIntegralConvolutionPlot',
+ 'ListLinePlot',
+ 'ListLogLinearPlot',
+ 'ListLogLogPlot',
+ 'ListLogPlot',
+ 'ListPicker',
+ 'ListPickerBox',
+ 'ListPickerBoxOptions',
+ 'ListPlay',
+ 'ListPlot',
+ 'ListPlot3D',
+ 'ListPointPlot3D',
+ 'ListPolarPlot',
+ 'ListQ',
+ 'ListSliceContourPlot3D',
+ 'ListSliceDensityPlot3D',
+ 'ListSliceVectorPlot3D',
+ 'ListStepPlot',
+ 'ListStreamDensityPlot',
+ 'ListStreamPlot',
+ 'ListSurfacePlot3D',
+ 'ListVectorDensityPlot',
+ 'ListVectorPlot',
+ 'ListVectorPlot3D',
+ 'ListZTransform',
+ 'Listable',
+ 'LocalAdaptiveBinarize',
+ 'LocalCache',
+ 'LocalClusteringCoefficient',
+ 'LocalObject',
+ 'LocalObjects',
+ 'LocalSymbol',
+ 'LocalTime',
+ 'LocalTimeZone',
+ 'LocalizeVariables',
+ 'LocationEquivalenceTest',
+ 'LocationTest',
+ 'Locator',
+ 'LocatorAutoCreate',
+ 'LocatorPane',
+ 'LocatorRegion',
+ 'Locked',
+ 'Log',
+ 'Log10',
+ 'Log2',
+ 'LogBarnesG',
+ 'LogGamma',
+ 'LogGammaDistribution',
+ 'LogIntegral',
+ 'LogLikelihood',
+ 'LogLinearPlot',
+ 'LogLogPlot',
+ 'LogLogisticDistribution',
+ 'LogMultinormalDistribution',
+ 'LogNormalDistribution',
+ 'LogPlot',
+ 'LogRankTest',
+ 'LogSeriesDistribution',
+ 'LogicalExpand',
+ 'LogisticDistribution',
+ 'LogisticSigmoid',
+ 'LogitModelFit',
+ 'LongLeftArrow',
+ 'LongLeftRightArrow',
+ 'LongRightArrow',
+ 'Longest',
+ 'LongestCommonSequence',
+ 'LongestCommonSequencePositions',
+ 'LongestCommonSubsequence',
+ 'LongestCommonSubsequencePositions',
+ 'LongestOrderedSequence',
+ 'Longitude',
+ 'Lookup',
+ 'LoopFreeGraphQ',
+ 'LowerCaseQ',
+ 'LowerLeftArrow',
+ 'LowerRightArrow',
+ 'LowerTriangularize',
+ 'LowpassFilter',
+ 'LucasL',
+ 'LuccioSamiComponents',
+ 'LunarEclipse',
+ 'LyapunovSolve',
+ 'LyonsGroupLy',
+
+ 'MAProcess',
+ 'MachineNumberQ',
+ 'MachinePrecision',
+ 'Magenta',
+ 'Magnification',
+ 'Magnify',
+ 'MailReceiverFunction',
+ 'MailResponseFunction',
+ 'Majority',
+ 'MakeBoxes',
+ 'MakeExpression',
+ 'ManagedLibraryExpressionID',
+ 'ManagedLibraryExpressionQ',
+ 'MandelbrotSetBoettcher',
+ 'MandelbrotSetDistance',
+ 'MandelbrotSetIterationCount',
+ 'MandelbrotSetMemberQ',
+ 'MandelbrotSetPlot',
+ 'MangoldtLambda',
+ 'ManhattanDistance',
+ 'Manipulate',
+ 'Manipulator',
+ 'MannWhitneyTest',
+ 'MannedSpaceMissionData',
+ 'MantissaExponent',
+ 'Manual',
+ 'Map',
+ 'MapAll',
+ 'MapAt',
+ 'MapIndexed',
+ 'MapThread',
+ 'MarchenkoPasturDistribution',
+ 'MarcumQ',
+ 'MardiaCombinedTest',
+ 'MardiaKurtosisTest',
+ 'MardiaSkewnessTest',
+ 'MarginalDistribution',
+ 'MarkovProcessProperties',
+ 'Masking',
+ 'MatchLocalNames',
+ 'MatchQ',
+ 'MatchingDissimilarity',
+ 'MathMLForm',
+ 'MathematicalFunctionData',
+ 'MathieuC',
+ 'MathieuCPrime',
+ 'MathieuCharacteristicA',
+ 'MathieuCharacteristicB',
+ 'MathieuCharacteristicExponent',
+ 'MathieuGroupM11',
+ 'MathieuGroupM12',
+ 'MathieuGroupM22',
+ 'MathieuGroupM23',
+ 'MathieuGroupM24',
+ 'MathieuS',
+ 'MathieuSPrime',
+ 'Matrices',
+ 'MatrixExp',
+ 'MatrixForm',
+ 'MatrixFunction',
+ 'MatrixLog',
+ 'MatrixNormalDistribution',
+ 'MatrixPlot',
+ 'MatrixPower',
+ 'MatrixPropertyDistribution',
+ 'MatrixQ',
+ 'MatrixRank',
+ 'MatrixTDistribution',
+ 'Max',
+ 'MaxCellMeasure',
+ 'MaxDetect',
+ 'MaxExtraBandwidths',
+ 'MaxExtraConditions',
+ 'MaxFeatureDisplacement',
+ 'MaxFeatures',
+ 'MaxFilter',
+ 'MaxItems',
+ 'MaxIterations',
+ 'MaxMemoryUsed',
+ 'MaxMixtureKernels',
+ 'MaxPlotPoints',
+ 'MaxRecursion',
+ 'MaxStableDistribution',
+ 'MaxStepFraction',
+ 'MaxStepSize',
+ 'MaxSteps',
+ 'MaxTrainingRounds',
+ 'MaxValue',
+ 'MaxWordGap',
+ 'MaximalBy',
+ 'Maximize',
+ 'MaxwellDistribution',
+ 'McLaughlinGroupMcL',
+ 'Mean',
+ 'MeanAbsoluteLossLayer',
+ 'MeanClusteringCoefficient',
+ 'MeanDegreeConnectivity',
+ 'MeanDeviation',
+ 'MeanFilter',
+ 'MeanGraphDistance',
+ 'MeanNeighborDegree',
+ 'MeanShift',
+ 'MeanShiftFilter',
+ 'MeanSquaredLossLayer',
+ 'Median',
+ 'MedianDeviation',
+ 'MedianFilter',
+ 'MedicalTestData',
+ 'Medium',
+ 'MeijerG',
+ 'MeijerGReduce',
+ 'MeixnerDistribution',
+ 'MellinConvolve',
+ 'MellinTransform',
+ 'MemberQ',
+ 'MemoryConstrained',
+ 'MemoryConstraint',
+ 'MemoryInUse',
+ 'MenuCommandKey',
+ 'MenuPacket',
+ 'MenuSortingValue',
+ 'MenuStyle',
+ 'MenuView',
+ 'Merge',
+ 'MersennePrimeExponent',
+ 'MersennePrimeExponentQ',
+ 'Mesh',
+ 'MeshCellCentroid',
+ 'MeshCellCount',
+ 'MeshCellHighlight',
+ 'MeshCellIndex',
+ 'MeshCellLabel',
+ 'MeshCellMarker',
+ 'MeshCellMeasure',
+ 'MeshCellQuality',
+ 'MeshCellShapeFunction',
+ 'MeshCellStyle',
+ 'MeshCells',
+ 'MeshCoordinates',
+ 'MeshFunctions',
+ 'MeshPrimitives',
+ 'MeshQualityGoal',
+ 'MeshRefinementFunction',
+ 'MeshRegion',
+ 'MeshRegionQ',
+ 'MeshShading',
+ 'MeshStyle',
+ 'Message',
+ 'MessageDialog',
+ 'MessageList',
+ 'MessageName',
+ 'MessagePacket',
+ 'Messages',
+ 'MetaInformation',
+ 'MeteorShowerData',
+ 'Method',
+ 'MexicanHatWavelet',
+ 'MeyerWavelet',
+ 'Min',
+ 'MinColorDistance',
+ 'MinDetect',
+ 'MinFilter',
+ 'MinIntervalSize',
+ 'MinMax',
+ 'MinStableDistribution',
+ 'MinValue',
+ 'MineralData',
+ 'MinimalBy',
+ 'MinimalPolynomial',
+ 'MinimalStateSpaceModel',
+ 'Minimize',
+ 'MinimumTimeIncrement',
+ 'MinkowskiQuestionMark',
+ 'MinorPlanetData',
+ 'Minors',
+ 'Minus',
+ 'MinusPlus',
+ 'Missing',
+ 'MissingBehavior',
+ 'MissingDataMethod',
+ 'MissingDataRules',
+ 'MissingQ',
+ 'MissingString',
+ 'MissingStyle',
+ 'MittagLefflerE',
+ 'MixedGraphQ',
+ 'MixedMagnitude',
+ 'MixedRadix',
+ 'MixedRadixQuantity',
+ 'MixedUnit',
+ 'MixtureDistribution',
+ 'Mod',
+ 'Modal',
+ 'ModularLambda',
+ 'Module',
+ 'Modulus',
+ 'MoebiusMu',
+ 'Moment',
+ 'MomentConvert',
+ 'MomentEvaluate',
+ 'MomentGeneratingFunction',
+ 'MomentOfInertia',
+ 'Monday',
+ 'Monitor',
+ 'MonomialList',
+ 'MonsterGroupM',
+ 'MoonPhase',
+ 'MoonPosition',
+ 'MorletWavelet',
+ 'MorphologicalBinarize',
+ 'MorphologicalBranchPoints',
+ 'MorphologicalComponents',
+ 'MorphologicalEulerNumber',
+ 'MorphologicalGraph',
+ 'MorphologicalPerimeter',
+ 'MorphologicalTransform',
+ 'MortalityData',
+ 'Most',
+ 'MountainData',
+ 'MouseAnnotation',
+ 'MouseAppearance',
+ 'MousePosition',
+ 'Mouseover',
+ 'MovieData',
+ 'MovingAverage',
+ 'MovingMap',
+ 'MovingMedian',
+ 'MoyalDistribution',
+ 'Multicolumn',
+ 'MultiedgeStyle',
+ 'MultigraphQ',
+ 'Multinomial',
+ 'MultinomialDistribution',
+ 'MultinormalDistribution',
+ 'MultiplicativeOrder',
+ 'Multiselection',
+ 'MultivariateHypergeometricDistribution',
+ 'MultivariatePoissonDistribution',
+ 'MultivariateTDistribution',
+
+ 'N',
+ 'NArgMax',
+ 'NArgMin',
+ 'NCache',
+ 'NDEigensystem',
+ 'NDEigenvalues',
+ 'NDSolve',
+ 'NDSolveValue',
+ 'NExpectation',
+ 'NHoldAll',
+ 'NHoldFirst',
+ 'NHoldRest',
+ 'NIntegrate',
+ 'NMaxValue',
+ 'NMaximize',
+ 'NMinValue',
+ 'NMinimize',
+ 'NProbability',
+ 'NProduct',
+ 'NRoots',
+ 'NSolve',
+ 'NSum',
+ 'NakagamiDistribution',
+ 'NameQ',
+ 'Names',
+ 'Nand',
+ 'Nearest',
+ 'NearestFunction',
+ 'NearestNeighborGraph',
+ 'NebulaData',
+ 'NeedlemanWunschSimilarity',
+ 'Needs',
+ 'Negative',
+ 'NegativeBinomialDistribution',
+ 'NegativeDefiniteMatrixQ',
+ 'NegativeMultinomialDistribution',
+ 'NegativeSemidefiniteMatrixQ',
+ 'NeighborhoodData',
+ 'NeighborhoodGraph',
+ 'Nest',
+ 'NestGraph',
+ 'NestList',
+ 'NestWhile',
+ 'NestWhileList',
+ 'NestedGreaterGreater',
+ 'NestedLessLess',
+ 'NetChain',
+ 'NetDecoder',
+ 'NetEncoder',
+ 'NetExtract',
+ 'NetGraph',
+ 'NetInitialize',
+ 'NetPort',
+ 'NetTrain',
+ 'NeumannValue',
+ 'NevilleThetaC',
+ 'NevilleThetaD',
+ 'NevilleThetaN',
+ 'NevilleThetaS',
+ 'NextCell',
+ 'NextPrime',
+ 'NextScheduledTaskTime',
+ 'NicholsGridLines',
+ 'NicholsPlot',
+ 'NightHemisphere',
+ 'NoWhitespace',
+ 'NominalVariables',
+ 'NonCommutativeMultiply',
+ 'NonConstants',
+ 'NonNegative',
+ 'NonPositive',
+ 'NoncentralBetaDistribution',
+ 'NoncentralChiSquareDistribution',
+ 'NoncentralFRatioDistribution',
+ 'NoncentralStudentTDistribution',
+ 'None',
+ 'NoneTrue',
+ 'NonlinearModelFit',
+ 'NonlinearStateSpaceModel',
+ 'NonlocalMeansFilter',
+ 'Nor',
+ 'NorlundB',
+ 'Norm',
+ 'NormFunction',
+ 'Normal',
+ 'NormalDistribution',
+ 'NormalMatrixQ',
+ 'Normalize',
+ 'Normalized',
+ 'NormalizedSquaredEuclideanDistance',
+ 'NormalsFunction',
+ 'Not',
+ 'NotCongruent',
+ 'NotCupCap',
+ 'NotDoubleVerticalBar',
+ 'NotElement',
+ 'NotEqualTilde',
+ 'NotExists',
+ 'NotGreater',
+ 'NotGreaterEqual',
+ 'NotGreaterFullEqual',
+ 'NotGreaterGreater',
+ 'NotGreaterLess',
+ 'NotGreaterSlantEqual',
+ 'NotGreaterTilde',
+ 'NotHumpDownHump',
+ 'NotHumpEqual',
+ 'NotLeftTriangle',
+ 'NotLeftTriangleBar',
+ 'NotLeftTriangleEqual',
+ 'NotLess',
+ 'NotLessEqual',
+ 'NotLessFullEqual',
+ 'NotLessGreater',
+ 'NotLessLess',
+ 'NotLessSlantEqual',
+ 'NotLessTilde',
+ 'NotNestedGreaterGreater',
+ 'NotNestedLessLess',
+ 'NotPrecedes',
+ 'NotPrecedesEqual',
+ 'NotPrecedesSlantEqual',
+ 'NotPrecedesTilde',
+ 'NotReverseElement',
+ 'NotRightTriangle',
+ 'NotRightTriangleBar',
+ 'NotRightTriangleEqual',
+ 'NotSquareSubset',
+ 'NotSquareSubsetEqual',
+ 'NotSquareSuperset',
+ 'NotSquareSupersetEqual',
+ 'NotSubset',
+ 'NotSubsetEqual',
+ 'NotSucceeds',
+ 'NotSucceedsEqual',
+ 'NotSucceedsSlantEqual',
+ 'NotSucceedsTilde',
+ 'NotSuperset',
+ 'NotSupersetEqual',
+ 'NotTilde',
+ 'NotTildeEqual',
+ 'NotTildeFullEqual',
+ 'NotTildeTilde',
+ 'NotVerticalBar',
+ 'Notebook',
+ 'NotebookApply',
+ 'NotebookAutoSave',
+ 'NotebookClose',
+ 'NotebookDelete',
+ 'NotebookDirectory',
+ 'NotebookDynamicExpression',
+ 'NotebookEvaluate',
+ 'NotebookEventActions',
+ 'NotebookFileName',
+ 'NotebookFind',
+ 'NotebookGet',
+ 'NotebookImport',
+ 'NotebookInformation',
+ 'NotebookLocate',
+ 'NotebookObject',
+ 'NotebookOpen',
+ 'NotebookPrint',
+ 'NotebookPut',
+ 'NotebookRead',
+ 'NotebookSave',
+ 'NotebookSelection',
+ 'NotebookTemplate',
+ 'NotebookWrite',
+ 'Notebooks',
+ 'Nothing',
+ 'NotificationFunction',
+ 'Now',
+ 'NuclearExplosionData',
+ 'NuclearReactorData',
+ 'Null',
+ 'NullRecords',
+ 'NullSpace',
+ 'NullWords',
+ 'Number',
+ 'NumberCompose',
+ 'NumberDecompose',
+ 'NumberExpand',
+ 'NumberFieldClassNumber',
+ 'NumberFieldDiscriminant',
+ 'NumberFieldFundamentalUnits',
+ 'NumberFieldIntegralBasis',
+ 'NumberFieldNormRepresentatives',
+ 'NumberFieldRegulator',
+ 'NumberFieldRootsOfUnity',
+ 'NumberFieldSignature',
+ 'NumberForm',
+ 'NumberFormat',
+ 'NumberLinePlot',
+ 'NumberMarks',
+ 'NumberMultiplier',
+ 'NumberPadding',
+ 'NumberPoint',
+ 'NumberQ',
+ 'NumberSeparator',
+ 'NumberSigns',
+ 'NumberString',
+ 'Numerator',
+ 'NumericFunction',
+ 'NumericQ',
+ 'NuttallWindow',
+ 'NyquistGridLines',
+ 'NyquistPlot',
+
+ 'O',
+ 'ONanGroupON',
+ 'ObservabilityGramian',
+ 'ObservabilityMatrix',
+ 'ObservableDecomposition',
+ 'ObservableModelQ',
+ 'OceanData',
+ 'OddQ',
+ 'Off',
+ 'Offset',
+ 'On',
+ 'Once',
+ 'OneIdentity',
+ 'Opacity',
+ 'OpacityFunction',
+ 'OpacityFunctionScaling',
+ 'OpenAppend',
+ 'OpenRead',
+ 'OpenWrite',
+ 'Opener',
+ 'OpenerView',
+ 'Opening',
+ 'Operate',
+ 'OperatingSystem',
+ 'OptimumFlowData',
+ 'OptionValue',
+ 'Optional',
+ 'OptionalElement',
+ 'Options',
+ 'OptionsPattern',
+ 'Or',
+ 'Orange',
+ 'Order',
+ 'OrderDistribution',
+ 'OrderedQ',
+ 'Ordering',
+ 'Orderless',
+ 'OrderlessPatternSequence',
+ 'OrnsteinUhlenbeckProcess',
+ 'OrthogonalMatrixQ',
+ 'Orthogonalize',
+ 'Out',
+ 'Outer',
+ 'OutputControllabilityMatrix',
+ 'OutputControllableModelQ',
+ 'OutputForm',
+ 'OutputNamePacket',
+ 'OutputResponse',
+ 'OutputSizeLimit',
+ 'OutputStream',
+ 'OverBar',
+ 'OverDot',
+ 'OverHat',
+ 'OverTilde',
+ 'OverVector',
+ 'Overflow',
+ 'Overlaps',
+ 'Overlay',
+ 'Overscript',
+ 'OverscriptBox',
+ 'OverscriptBoxOptions',
+ 'OverwriteTarget',
+ 'OwenT',
+ 'OwnValues',
+
+ 'PDF',
+ 'PERTDistribution',
+ 'PIDData',
+ 'PIDDerivativeFilter',
+ 'PIDFeedforward',
+ 'PIDTune',
+ 'PackingMethod',
+ 'PadLeft',
+ 'PadRight',
+ 'PaddedForm',
+ 'Padding',
+ 'PaddingSize',
+ 'PadeApproximant',
+ 'PageBreakAbove',
+ 'PageBreakBelow',
+ 'PageBreakWithin',
+ 'PageFooters',
+ 'PageHeaders',
+ 'PageRankCentrality',
+ 'PageTheme',
+ 'PageWidth',
+ 'Pagination',
+ 'PairedBarChart',
+ 'PairedHistogram',
+ 'PairedSmoothHistogram',
+ 'PairedTTest',
+ 'PairedZTest',
+ 'PaletteNotebook',
+ 'PalindromeQ',
+ 'Pane',
+ 'PaneSelector',
+ 'Panel',
+ 'Paneled',
+ 'ParabolicCylinderD',
+ 'ParagraphIndent',
+ 'ParagraphSpacing',
+ 'ParallelArray',
+ 'ParallelCombine',
+ 'ParallelDo',
+ 'ParallelEvaluate',
+ 'ParallelMap',
+ 'ParallelNeeds',
+ 'ParallelProduct',
+ 'ParallelSubmit',
+ 'ParallelSum',
+ 'ParallelTable',
+ 'ParallelTry',
+ 'Parallelepiped',
+ 'Parallelization',
+ 'Parallelize',
+ 'Parallelogram',
+ 'ParameterEstimator',
+ 'ParameterMixtureDistribution',
+ 'ParametricFunction',
+ 'ParametricNDSolve',
+ 'ParametricNDSolveValue',
+ 'ParametricPlot',
+ 'ParametricPlot3D',
+ 'ParametricRegion',
+ 'ParentBox',
+ 'ParentCell',
+ 'ParentDirectory',
+ 'ParentNotebook',
+ 'ParetoDistribution',
+ 'ParkData',
+ 'Part',
+ 'PartBehavior',
+ 'PartOfSpeech',
+ 'PartProtection',
+ 'PartialCorrelationFunction',
+ 'ParticleAcceleratorData',
+ 'ParticleData',
+ 'Partition',
+ 'PartitionGranularity',
+ 'PartitionsP',
+ 'PartitionsQ',
+ 'ParzenWindow',
+ 'PascalDistribution',
+ 'PassEventsDown',
+ 'PassEventsUp',
+ 'Paste',
+ 'PasteButton',
+ 'Path',
+ 'PathGraph',
+ 'PathGraphQ',
+ 'Pattern',
+ 'PatternSequence',
+ 'PatternTest',
+ 'PaulWavelet',
+ 'PauliMatrix',
+ 'Pause',
+ 'PeakDetect',
+ 'PearsonChiSquareTest',
+ 'PearsonCorrelationTest',
+ 'PearsonDistribution',
+ 'PerfectNumber',
+ 'PerfectNumberQ',
+ 'PerformanceGoal',
+ 'PeriodicBoundaryCondition',
+ 'Periodogram',
+ 'PeriodogramArray',
+ 'Permanent',
+ 'Permissions',
+ 'PermissionsGroup',
+ 'PermissionsGroups',
+ 'PermissionsKey',
+ 'PermissionsKeys',
+ 'PermutationCycles',
+ 'PermutationCyclesQ',
+ 'PermutationGroup',
+ 'PermutationLength',
+ 'PermutationList',
+ 'PermutationListQ',
+ 'PermutationMax',
+ 'PermutationMin',
+ 'PermutationOrder',
+ 'PermutationPower',
+ 'PermutationProduct',
+ 'PermutationReplace',
+ 'PermutationSupport',
+ 'Permutations',
+ 'Permute',
+ 'PeronaMalikFilter',
+ 'PersonData',
+ 'PetersenGraph',
+ 'PhaseMargins',
+ 'PhaseRange',
+ 'PhysicalSystemData',
+ 'Pi',
+ 'Pick',
+ 'PieChart',
+ 'PieChart3D',
+ 'Piecewise',
+ 'PiecewiseExpand',
+ 'PillaiTrace',
+ 'PillaiTraceTest',
+ 'PingTime',
+ 'Pink',
+ 'PixelConstrained',
+ 'PixelValue',
+ 'PixelValuePositions',
+ 'Placed',
+ 'Placeholder',
+ 'PlaceholderReplace',
+ 'Plain',
+ 'PlanarGraph',
+ 'PlanarGraphQ',
+ 'PlanckRadiationLaw',
+ 'PlaneCurveData',
+ 'PlanetData',
+ 'PlanetaryMoonData',
+ 'PlantData',
+ 'Play',
+ 'PlayRange',
+ 'Plot',
+ 'Plot3D',
+ 'PlotLabel',
+ 'PlotLabels',
+ 'PlotLayout',
+ 'PlotLegends',
+ 'PlotMarkers',
+ 'PlotPoints',
+ 'PlotRange',
+ 'PlotRangeClipping',
+ 'PlotRangePadding',
+ 'PlotRegion',
+ 'PlotStyle',
+ 'PlotTheme',
+ 'Pluralize',
+ 'Plus',
+ 'PlusMinus',
+ 'Pochhammer',
+ 'PodStates',
+ 'PodWidth',
+ 'Point',
+ 'PointFigureChart',
+ 'PointLegend',
+ 'PointSize',
+ 'PoissonConsulDistribution',
+ 'PoissonDistribution',
+ 'PoissonProcess',
+ 'PoissonWindow',
+ 'PolarAxes',
+ 'PolarAxesOrigin',
+ 'PolarGridLines',
+ 'PolarPlot',
+ 'PolarTicks',
+ 'PoleZeroMarkers',
+ 'PolyGamma',
+ 'PolyLog',
+ 'PolyaAeppliDistribution',
+ 'Polygon',
+ 'PolygonalNumber',
+ 'PolyhedronData',
+ 'PolynomialExtendedGCD',
+ 'PolynomialGCD',
+ 'PolynomialLCM',
+ 'PolynomialMod',
+ 'PolynomialQ',
+ 'PolynomialQuotient',
+ 'PolynomialQuotientRemainder',
+ 'PolynomialReduce',
+ 'PolynomialRemainder',
+ 'PoolingLayer',
+ 'PopupMenu',
+ 'PopupView',
+ 'PopupWindow',
+ 'Position',
+ 'PositionIndex',
+ 'Positive',
+ 'PositiveDefiniteMatrixQ',
+ 'PositiveSemidefiniteMatrixQ',
+ 'PossibleZeroQ',
+ 'Postfix',
+ 'Power',
+ 'PowerDistribution',
+ 'PowerExpand',
+ 'PowerMod',
+ 'PowerModList',
+ 'PowerRange',
+ 'PowerSpectralDensity',
+ 'PowerSymmetricPolynomial',
+ 'PowersRepresentations',
+ 'PreDecrement',
+ 'PreIncrement',
+ 'PrecedenceForm',
+ 'Precedes',
+ 'PrecedesEqual',
+ 'PrecedesSlantEqual',
+ 'PrecedesTilde',
+ 'Precision',
+ 'PrecisionGoal',
+ 'Predict',
+ 'PredictorFunction',
+ 'PredictorInformation',
+ 'PredictorMeasurements',
+ 'PredictorMeasurementsObject',
+ 'PreemptProtect',
+ 'Prefix',
+ 'Prepend',
+ 'PrependTo',
+ 'PreserveImageOptions',
+ 'PreviousCell',
+ 'PriceGraphDistribution',
+ 'Prime',
+ 'PrimeNu',
+ 'PrimeOmega',
+ 'PrimePi',
+ 'PrimePowerQ',
+ 'PrimeQ',
+ 'PrimeZetaP',
+ 'Primes',
+ 'PrimitiveRoot',
+ 'PrimitiveRootList',
+ 'PrincipalComponents',
+ 'PrincipalValue',
+ 'Print',
+ 'PrintTemporary',
+ 'PrintableASCIIQ',
+ 'PrintingStyleEnvironment',
+ 'Printout3D',
+ 'Printout3DPreviewer',
+ 'Prism',
+ 'PrivateCellOptions',
+ 'PrivateFontOptions',
+ 'PrivateKey',
+ 'PrivateNotebookOptions',
+ 'Probability',
+ 'ProbabilityDistribution',
+ 'ProbabilityPlot',
+ 'ProbabilityScalePlot',
+ 'ProbitModelFit',
+ 'ProcessConnection',
+ 'ProcessDirectory',
+ 'ProcessEnvironment',
+ 'ProcessEstimator',
+ 'ProcessInformation',
+ 'ProcessObject',
+ 'ProcessParameterAssumptions',
+ 'ProcessParameterQ',
+ 'ProcessStatus',
+ 'Processes',
+ 'Product',
+ 'ProductDistribution',
+ 'ProductLog',
+ 'ProgressIndicator',
+ 'Projection',
+ 'Prolog',
+ 'Properties',
+ 'Property',
+ 'PropertyList',
+ 'PropertyValue',
+ 'Proportion',
+ 'Proportional',
+ 'Protect',
+ 'Protected',
+ 'ProteinData',
+ 'Pruning',
+ 'PseudoInverse',
+ 'PublicKey',
+ 'PulsarData',
+ 'PunctuationCharacter',
+ 'Purple',
+ 'Put',
+ 'PutAppend',
+ 'Pyramid',
+
+ 'QBinomial',
+ 'QFactorial',
+ 'QGamma',
+ 'QHypergeometricPFQ',
+ 'QPochhammer',
+ 'QPolyGamma',
+ 'QRDecomposition',
+ 'QuadraticIrrationalQ',
+ 'Quantile',
+ 'QuantilePlot',
+ 'Quantity',
+ 'QuantityArray',
+ 'QuantityDistribution',
+ 'QuantityForm',
+ 'QuantityMagnitude',
+ 'QuantityQ',
+ 'QuantityUnit',
+ 'QuantityVariable',
+ 'QuantityVariableCanonicalUnit',
+ 'QuantityVariableDimensions',
+ 'QuantityVariableIdentifier',
+ 'QuantityVariablePhysicalQuantity',
+ 'Quartics',
+ 'QuartileDeviation',
+ 'QuartileSkewness',
+ 'Quartiles',
+ 'Query',
+ 'QueueProperties',
+ 'QueueingNetworkProcess',
+ 'QueueingProcess',
+ 'Quiet',
+ 'Quit',
+ 'Quotient',
+ 'QuotientRemainder',
+
+ 'RGBColor',
+ 'RSolve',
+ 'RSolveValue',
+ 'RadialGradientImage',
+ 'RadialityCentrality',
+ 'RadicalBox',
+ 'RadicalBoxOptions',
+ 'RadioButton',
+ 'RadioButtonBar',
+ 'Radon',
+ 'RamanujanTau',
+ 'RamanujanTauL',
+ 'RamanujanTauTheta',
+ 'RamanujanTauZ',
+ 'Ramp',
+ 'RandomChoice',
+ 'RandomColor',
+ 'RandomComplex',
+ 'RandomEntity',
+ 'RandomFunction',
+ 'RandomGraph',
+ 'RandomImage',
+ 'RandomInteger',
+ 'RandomPermutation',
+ 'RandomPoint',
+ 'RandomPrime',
+ 'RandomReal',
+ 'RandomSample',
+ 'RandomVariate',
+ 'RandomWalkProcess',
+ 'RandomWord',
+ 'Range',
+ 'RangeFilter',
+ 'RankedMax',
+ 'RankedMin',
+ 'Raster',
+ 'Raster3D',
+ 'RasterSize',
+ 'Rasterize',
+ 'Rational',
+ 'Rationalize',
+ 'Rationals',
+ 'Ratios',
+ 'RawBoxes',
+ 'RawData',
+ 'RayleighDistribution',
+ 'Re',
+ 'ReIm',
+ 'Read',
+ 'ReadLine',
+ 'ReadList',
+ 'ReadProtected',
+ 'ReadString',
+ 'Real',
+ 'RealBlockDiagonalForm',
+ 'RealDigits',
+ 'RealExponent',
+ 'Reals',
+ 'Reap',
+ 'RecognitionPrior',
+ 'RecognitionThreshold',
+ 'Record',
+ 'RecordLists',
+ 'RecordSeparators',
+ 'Rectangle',
+ 'RectangleChart',
+ 'RectangleChart3D',
+ 'RecurrenceFilter',
+ 'RecurrenceTable',
+ 'Red',
+ 'Reduce',
+ 'ReferenceLineStyle',
+ 'Refine',
+ 'ReflectionMatrix',
+ 'ReflectionTransform',
+ 'Refresh',
+ 'RefreshRate',
+ 'RegionBinarize',
+ 'RegionBoundary',
+ 'RegionBounds',
+ 'RegionCentroid',
+ 'RegionDifference',
+ 'RegionDimension',
+ 'RegionDistance',
+ 'RegionDistanceFunction',
+ 'RegionEmbeddingDimension',
+ 'RegionFunction',
+ 'RegionIntersection',
+ 'RegionMeasure',
+ 'RegionMember',
+ 'RegionMemberFunction',
+ 'RegionMoment',
+ 'RegionNearest',
+ 'RegionNearestFunction',
+ 'RegionPlot',
+ 'RegionPlot3D',
+ 'RegionProduct',
+ 'RegionQ',
+ 'RegionResize',
+ 'RegionSize',
+ 'RegionSymmetricDifference',
+ 'RegionUnion',
+ 'RegularExpression',
+ 'RegularPolygon',
+ 'Regularization',
+ 'RegularlySampledQ',
+ 'RelationGraph',
+ 'ReleaseHold',
+ 'ReliabilityDistribution',
+ 'ReliefImage',
+ 'ReliefPlot',
+ 'Remove',
+ 'RemoveAlphaChannel',
+ 'RemoveAsynchronousTask',
+ 'RemoveBackground',
+ 'RemoveChannelListener',
+ 'RemoveDiacritics',
+ 'RemoveInputStreamMethod',
+ 'RemoveOutputStreamMethod',
+ 'RemoveProperty',
+ 'RemoveScheduledTask',
+ 'RemoveUsers',
+ 'RenameDirectory',
+ 'RenameFile',
+ 'RenewalProcess',
+ 'RenkoChart',
+ 'RepairMesh',
+ 'Repeated',
+ 'RepeatedNull',
+ 'RepeatedTiming',
+ 'RepeatingElement',
+ 'Replace',
+ 'ReplaceAll',
+ 'ReplaceImageValue',
+ 'ReplaceList',
+ 'ReplacePart',
+ 'ReplacePixelValue',
+ 'ReplaceRepeated',
+ 'RequiredPhysicalQuantities',
+ 'Resampling',
+ 'ResamplingAlgorithmData',
+ 'ResamplingMethod',
+ 'Rescale',
+ 'RescalingTransform',
+ 'ResetDirectory',
+ 'ResetScheduledTask',
+ 'ReshapeLayer',
+ 'Residue',
+ 'Resolve',
+ 'ResourceData',
+ 'ResourceObject',
+ 'ResourceRemove',
+ 'ResourceSearch',
+ 'ResponseForm',
+ 'Rest',
+ 'RestartInterval',
+ 'Restricted',
+ 'Resultant',
+ 'Return',
+ 'ReturnExpressionPacket',
+ 'ReturnPacket',
+ 'ReturnReceiptFunction',
+ 'ReturnTextPacket',
+ 'Reverse',
+ 'ReverseBiorthogonalSplineWavelet',
+ 'ReverseElement',
+ 'ReverseEquilibrium',
+ 'ReverseGraph',
+ 'ReverseUpEquilibrium',
+ 'RevolutionAxis',
+ 'RevolutionPlot3D',
+ 'RiccatiSolve',
+ 'RiceDistribution',
+ 'RidgeFilter',
+ 'RiemannR',
+ 'RiemannSiegelTheta',
+ 'RiemannSiegelZ',
+ 'RiemannXi',
+ 'Riffle',
+ 'Right',
+ 'RightArrow',
+ 'RightArrowBar',
+ 'RightArrowLeftArrow',
+ 'RightComposition',
+ 'RightCosetRepresentative',
+ 'RightDownTeeVector',
+ 'RightDownVector',
+ 'RightDownVectorBar',
+ 'RightTee',
+ 'RightTeeArrow',
+ 'RightTeeVector',
+ 'RightTriangle',
+ 'RightTriangleBar',
+ 'RightTriangleEqual',
+ 'RightUpDownVector',
+ 'RightUpTeeVector',
+ 'RightUpVector',
+ 'RightUpVectorBar',
+ 'RightVector',
+ 'RightVectorBar',
+ 'RiskAchievementImportance',
+ 'RiskReductionImportance',
+ 'RogersTanimotoDissimilarity',
+ 'RollPitchYawAngles',
+ 'RollPitchYawMatrix',
+ 'RomanNumeral',
+ 'Root',
+ 'RootApproximant',
+ 'RootIntervals',
+ 'RootLocusPlot',
+ 'RootMeanSquare',
+ 'RootOfUnityQ',
+ 'RootReduce',
+ 'RootSum',
+ 'Roots',
+ 'Rotate',
+ 'RotateLabel',
+ 'RotateLeft',
+ 'RotateRight',
+ 'RotationAction',
+ 'RotationMatrix',
+ 'RotationTransform',
+ 'Round',
+ 'RoundingRadius',
+ 'Row',
+ 'RowAlignments',
+ 'RowBox',
+ 'RowLines',
+ 'RowMinHeight',
+ 'RowReduce',
+ 'RowSpacings',
+ 'RowsEqual',
+ 'RudinShapiro',
+ 'RudvalisGroupRu',
+ 'Rule',
+ 'RuleDelayed',
+ 'RulePlot',
+ 'Run',
+ 'RunProcess',
+ 'RunScheduledTask',
+ 'RunThrough',
+ 'RuntimeAttributes',
+ 'RuntimeOptions',
+ 'RussellRaoDissimilarity',
+
+ 'SARIMAProcess',
+ 'SARMAProcess',
+ 'SASTriangle',
+ 'SSSTriangle',
+ 'SameQ',
+ 'SameTest',
+ 'SampleDepth',
+ 'SampleRate',
+ 'SampledSoundFunction',
+ 'SampledSoundList',
+ 'SamplingPeriod',
+ 'SatelliteData',
+ 'SatisfiabilityCount',
+ 'SatisfiabilityInstances',
+ 'SatisfiableQ',
+ 'Saturday',
+ 'Save',
+ 'SaveDefinitions',
+ 'SavitzkyGolayMatrix',
+ 'SawtoothWave',
+ 'Scale',
+ 'ScaleDivisions',
+ 'ScaleOrigin',
+ 'ScalePadding',
+ 'ScaleRangeStyle',
+ 'ScaleRanges',
+ 'Scaled',
+ 'ScalingFunctions',
+ 'ScalingMatrix',
+ 'ScalingTransform',
+ 'Scan',
+ 'ScheduledTask',
+ 'ScheduledTaskActiveQ',
+ 'ScheduledTaskInformation',
+ 'ScheduledTaskObject',
+ 'ScheduledTasks',
+ 'SchurDecomposition',
+ 'ScientificForm',
+ 'ScorerGi',
+ 'ScorerGiPrime',
+ 'ScorerHi',
+ 'ScorerHiPrime',
+ 'ScreenStyleEnvironment',
+ 'ScriptBaselineShifts',
+ 'ScriptMinSize',
+ 'ScriptSizeMultipliers',
+ 'ScrollPosition',
+ 'Scrollbars',
+ 'ScrollingOptions',
+ 'SearchAdjustment',
+ 'SearchIndexObject',
+ 'SearchIndices',
+ 'SearchQueryString',
+ 'SearchResultObject',
+ 'Sec',
+ 'Sech',
+ 'SechDistribution',
+ 'SectorChart',
+ 'SectorChart3D',
+ 'SectorOrigin',
+ 'SectorSpacing',
+ 'SeedRandom',
+ 'Select',
+ 'SelectComponents',
+ 'SelectFirst',
+ 'Selectable',
+ 'SelectedCells',
+ 'SelectedNotebook',
+ 'SelectionCreateCell',
+ 'SelectionEvaluate',
+ 'SelectionEvaluateCreateCell',
+ 'SelectionMove',
+ 'SelfLoopStyle',
+ 'SemanticImport',
+ 'SemanticImportString',
+ 'SemanticInterpretation',
+ 'SemialgebraicComponentInstances',
+ 'SendMail',
+ 'SendMessage',
+ 'Sequence',
+ 'SequenceAlignment',
+ 'SequenceCases',
+ 'SequenceCount',
+ 'SequenceFold',
+ 'SequenceFoldList',
+ 'SequenceHold',
+ 'SequencePosition',
+ 'Series',
+ 'SeriesCoefficient',
+ 'SeriesData',
+ 'ServiceConnect',
+ 'ServiceDisconnect',
+ 'ServiceExecute',
+ 'ServiceObject',
+ 'SessionTime',
+ 'Set',
+ 'SetAccuracy',
+ 'SetAlphaChannel',
+ 'SetAttributes',
+ 'SetCloudDirectory',
+ 'SetCookies',
+ 'SetDelayed',
+ 'SetDirectory',
+ 'SetEnvironment',
+ 'SetFileDate',
+ 'SetOptions',
+ 'SetPermissions',
+ 'SetPrecision',
+ 'SetProperty',
+ 'SetSelectedNotebook',
+ 'SetSharedFunction',
+ 'SetSharedVariable',
+ 'SetStreamPosition',
+ 'SetSystemOptions',
+ 'SetUsers',
+ 'Setter',
+ 'SetterBar',
+ 'Setting',
+ 'Shallow',
+ 'ShannonWavelet',
+ 'ShapiroWilkTest',
+ 'Share',
+ 'Sharpen',
+ 'ShearingMatrix',
+ 'ShearingTransform',
+ 'ShellRegion',
+ 'ShenCastanMatrix',
+ 'ShiftRegisterSequence',
+ 'ShiftedGompertzDistribution',
+ 'Short',
+ 'ShortDownArrow',
+ 'ShortLeftArrow',
+ 'ShortRightArrow',
+ 'ShortUpArrow',
+ 'Shortest',
+ 'ShortestPathFunction',
+ 'Show',
+ 'ShowAutoSpellCheck',
+ 'ShowAutoStyles',
+ 'ShowCellBracket',
+ 'ShowCellLabel',
+ 'ShowCellTags',
+ 'ShowCursorTracker',
+ 'ShowGroupOpener',
+ 'ShowPageBreaks',
+ 'ShowSelection',
+ 'ShowSpecialCharacters',
+ 'ShowStringCharacters',
+ 'ShrinkingDelay',
+ 'SiderealTime',
+ 'SiegelTheta',
+ 'SiegelTukeyTest',
+ 'Sign',
+ 'SignPadding',
+ 'SignTest',
+ 'Signature',
+ 'SignedRankTest',
+ 'SignedRegionDistance',
+ 'SignificanceLevel',
+ 'SimilarityRules',
+ 'SimpleGraph',
+ 'SimpleGraphQ',
+ 'Simplex',
+ 'Simplify',
+ 'Sin',
+ 'SinIntegral',
+ 'Sinc',
+ 'SinghMaddalaDistribution',
+ 'SingleLetterItalics',
+ 'SingularValueDecomposition',
+ 'SingularValueList',
+ 'SingularValuePlot',
+ 'Sinh',
+ 'SinhIntegral',
+ 'SixJSymbol',
+ 'Skeleton',
+ 'SkeletonTransform',
+ 'SkellamDistribution',
+ 'SkewNormalDistribution',
+ 'Skewness',
+ 'SkinStyle',
+ 'Skip',
+ 'SliceContourPlot3D',
+ 'SliceDensityPlot3D',
+ 'SliceDistribution',
+ 'SliceVectorPlot3D',
+ 'SlideView',
+ 'Slider',
+ 'Slider2D',
+ 'Slot',
+ 'SlotSequence',
+ 'Small',
+ 'SmallCircle',
+ 'Smaller',
+ 'SmithDecomposition',
+ 'SmithDelayCompensator',
+ 'SmithWatermanSimilarity',
+ 'SmoothDensityHistogram',
+ 'SmoothHistogram',
+ 'SmoothHistogram3D',
+ 'SmoothKernelDistribution',
+ 'Snippet',
+ 'SocialMediaData',
+ 'SocketConnect',
+ 'SocketObject',
+ 'SoftmaxLayer',
+ 'SokalSneathDissimilarity',
+ 'SolarEclipse',
+ 'SolarSystemFeatureData',
+ 'SolidData',
+ 'SolidRegionQ',
+ 'Solve',
+ 'SolveAlways',
+ 'Sort',
+ 'SortBy',
+ 'Sound',
+ 'SoundNote',
+ 'SoundVolume',
+ 'SourceLink',
+ 'Sow',
+ 'SpaceCurveData',
+ 'Spacer',
+ 'Spacings',
+ 'Span',
+ 'SpanFromAbove',
+ 'SpanFromBoth',
+ 'SpanFromLeft',
+ 'SparseArray',
+ 'SpatialGraphDistribution',
+ 'Speak',
+ 'SpearmanRankTest',
+ 'SpearmanRho',
+ 'SpeciesData',
+ 'SpecificityGoal',
+ 'Spectrogram',
+ 'SpectrogramArray',
+ 'Specularity',
+ 'SpellingCorrection',
+ 'SpellingCorrectionList',
+ 'SpellingOptions',
+ 'Sphere',
+ 'SphericalBesselJ',
+ 'SphericalBesselY',
+ 'SphericalHankelH1',
+ 'SphericalHankelH2',
+ 'SphericalHarmonicY',
+ 'SphericalPlot3D',
+ 'SphericalRegion',
+ 'SphericalShell',
+ 'SpheroidalEigenvalue',
+ 'SpheroidalJoiningFactor',
+ 'SpheroidalPS',
+ 'SpheroidalPSPrime',
+ 'SpheroidalQS',
+ 'SpheroidalQSPrime',
+ 'SpheroidalRadialFactor',
+ 'SpheroidalS1',
+ 'SpheroidalS1Prime',
+ 'SpheroidalS2',
+ 'SpheroidalS2Prime',
+ 'SplicedDistribution',
+ 'SplineClosed',
+ 'SplineDegree',
+ 'SplineKnots',
+ 'SplineWeights',
+ 'Split',
+ 'SplitBy',
+ 'SpokenString',
+ 'Sqrt',
+ 'SqrtBox',
+ 'SqrtBoxOptions',
+ 'Square',
+ 'SquareFreeQ',
+ 'SquareIntersection',
+ 'SquareMatrixQ',
+ 'SquareSubset',
+ 'SquareSubsetEqual',
+ 'SquareSuperset',
+ 'SquareSupersetEqual',
+ 'SquareUnion',
+ 'SquareWave',
+ 'SquaredEuclideanDistance',
+ 'SquaresR',
+ 'StabilityMargins',
+ 'StabilityMarginsStyle',
+ 'StableDistribution',
+ 'Stack',
+ 'StackBegin',
+ 'StackComplete',
+ 'StackInhibit',
+ 'StadiumShape',
+ 'StandardAtmosphereData',
+ 'StandardDeviation',
+ 'StandardDeviationFilter',
+ 'StandardForm',
+ 'StandardOceanData',
+ 'Standardize',
+ 'Standardized',
+ 'StandbyDistribution',
+ 'Star',
+ 'StarClusterData',
+ 'StarData',
+ 'StarGraph',
+ 'StartAsynchronousTask',
+ 'StartOfLine',
+ 'StartOfString',
+ 'StartProcess',
+ 'StartScheduledTask',
+ 'StartingStepSize',
+ 'StateFeedbackGains',
+ 'StateOutputEstimator',
+ 'StateResponse',
+ 'StateSpaceModel',
+ 'StateSpaceRealization',
+ 'StateSpaceTransform',
+ 'StateTransformationLinearize',
+ 'StationaryDistribution',
+ 'StationaryWaveletPacketTransform',
+ 'StationaryWaveletTransform',
+ 'StatusArea',
+ 'StatusCentrality',
+ 'StepMonitor',
+ 'StieltjesGamma',
+ 'StirlingS1',
+ 'StirlingS2',
+ 'StopAsynchronousTask',
+ 'StopScheduledTask',
+ 'StoppingPowerData',
+ 'StrataVariables',
+ 'StratonovichProcess',
+ 'StreamColorFunction',
+ 'StreamColorFunctionScaling',
+ 'StreamDensityPlot',
+ 'StreamPlot',
+ 'StreamPoints',
+ 'StreamPosition',
+ 'StreamScale',
+ 'StreamStyle',
+ 'Streams',
+ 'String',
+ 'StringCases',
+ 'StringContainsQ',
+ 'StringCount',
+ 'StringDelete',
+ 'StringDrop',
+ 'StringEndsQ',
+ 'StringExpression',
+ 'StringExtract',
+ 'StringForm',
+ 'StringFormat',
+ 'StringFreeQ',
+ 'StringInsert',
+ 'StringJoin',
+ 'StringLength',
+ 'StringMatchQ',
+ 'StringPadLeft',
+ 'StringPadRight',
+ 'StringPart',
+ 'StringPartition',
+ 'StringPosition',
+ 'StringQ',
+ 'StringRepeat',
+ 'StringReplace',
+ 'StringReplaceList',
+ 'StringReplacePart',
+ 'StringReverse',
+ 'StringRiffle',
+ 'StringRotateLeft',
+ 'StringRotateRight',
+ 'StringSkeleton',
+ 'StringSplit',
+ 'StringStartsQ',
+ 'StringTake',
+ 'StringTemplate',
+ 'StringToStream',
+ 'StringTrim',
+ 'StripBoxes',
+ 'StripOnInput',
+ 'StripWrapperBoxes',
+ 'StructuralImportance',
+ 'StructuredArray',
+ 'StructuredSelection',
+ 'StruveH',
+ 'StruveL',
+ 'Stub',
+ 'StudentTDistribution',
+ 'Style',
+ 'StyleBox',
+ 'StyleData',
+ 'StyleDefinitions',
+ 'SubMinus',
+ 'SubPlus',
+ 'SubStar',
+ 'Subdivide',
+ 'Subfactorial',
+ 'Subgraph',
+ 'SubresultantPolynomialRemainders',
+ 'SubresultantPolynomials',
+ 'Subresultants',
+ 'Subscript',
+ 'SubscriptBox',
+ 'SubscriptBoxOptions',
+ 'Subsequences',
+ 'Subset',
+ 'SubsetEqual',
+ 'SubsetQ',
+ 'Subsets',
+ 'SubstitutionSystem',
+ 'Subsuperscript',
+ 'SubsuperscriptBox',
+ 'SubsuperscriptBoxOptions',
+ 'Subtract',
+ 'SubtractFrom',
+ 'Succeeds',
+ 'SucceedsEqual',
+ 'SucceedsSlantEqual',
+ 'SucceedsTilde',
+ 'SuchThat',
+ 'Sum',
+ 'SumConvergence',
+ 'SummationLayer',
+ 'SunPosition',
+ 'Sunday',
+ 'Sunrise',
+ 'Sunset',
+ 'SuperDagger',
+ 'SuperMinus',
+ 'SuperPlus',
+ 'SuperStar',
+ 'SupernovaData',
+ 'Superscript',
+ 'SuperscriptBox',
+ 'SuperscriptBoxOptions',
+ 'Superset',
+ 'SupersetEqual',
+ 'Surd',
+ 'SurfaceData',
+ 'SurvivalDistribution',
+ 'SurvivalFunction',
+ 'SurvivalModel',
+ 'SurvivalModelFit',
+ 'SuzukiDistribution',
+ 'SuzukiGroupSuz',
+ 'SwatchLegend',
+ 'Switch',
+ 'Symbol',
+ 'SymbolName',
+ 'SymletWavelet',
+ 'Symmetric',
+ 'SymmetricGroup',
+ 'SymmetricKey',
+ 'SymmetricMatrixQ',
+ 'SymmetricPolynomial',
+ 'SymmetricReduction',
+ 'Symmetrize',
+ 'SymmetrizedArray',
+ 'SymmetrizedArrayRules',
+ 'SymmetrizedDependentComponents',
+ 'SymmetrizedIndependentComponents',
+ 'SymmetrizedReplacePart',
+ 'SynchronousInitialization',
+ 'SynchronousUpdating',
+ 'SyntaxForm',
+ 'SyntaxInformation',
+ 'SyntaxLength',
+ 'SyntaxPacket',
+ 'SyntaxQ',
+ 'SystemDialogInput',
+ 'SystemInformation',
+ 'SystemOpen',
+ 'SystemOptions',
+ 'SystemsModelDelay',
+ 'SystemsModelDelayApproximate',
+ 'SystemsModelDelete',
+ 'SystemsModelDimensions',
+ 'SystemsModelExtract',
+ 'SystemsModelFeedbackConnect',
+ 'SystemsModelLabels',
+ 'SystemsModelLinearity',
+ 'SystemsModelMerge',
+ 'SystemsModelOrder',
+ 'SystemsModelParallelConnect',
+ 'SystemsModelSeriesConnect',
+ 'SystemsModelStateFeedbackConnect',
+ 'SystemsModelVectorRelativeOrders',
+
+ 'TTest',
+ 'TabView',
+ 'Table',
+ 'TableAlignments',
+ 'TableDepth',
+ 'TableDirections',
+ 'TableForm',
+ 'TableHeadings',
+ 'TableSpacing',
+ 'TagBox',
+ 'TagBoxOptions',
+ 'TagSet',
+ 'TagSetDelayed',
+ 'TagUnset',
+ 'TaggingRules',
+ 'Take',
+ 'TakeDrop',
+ 'TakeLargest',
+ 'TakeLargestBy',
+ 'TakeSmallest',
+ 'TakeSmallestBy',
+ 'TakeWhile',
+ 'Tally',
+ 'Tan',
+ 'Tanh',
+ 'TargetDevice',
+ 'TargetFunctions',
+ 'TargetUnits',
+ 'TautologyQ',
+ 'TeXForm',
+ 'TelegraphProcess',
+ 'TemplateApply',
+ 'TemplateBox',
+ 'TemplateBoxOptions',
+ 'TemplateExpression',
+ 'TemplateIf',
+ 'TemplateObject',
+ 'TemplateSequence',
+ 'TemplateSlot',
+ 'TemplateWith',
+ 'TemporalData',
+ 'TemporalRegularity',
+ 'Temporary',
+ 'TensorContract',
+ 'TensorDimensions',
+ 'TensorExpand',
+ 'TensorProduct',
+ 'TensorRank',
+ 'TensorReduce',
+ 'TensorSymmetry',
+ 'TensorTranspose',
+ 'TensorWedge',
+ 'TestID',
+ 'TestReport',
+ 'TestReportObject',
+ 'TestResultObject',
+ 'Tetrahedron',
+ 'Text',
+ 'TextAlignment',
+ 'TextCases',
+ 'TextCell',
+ 'TextClipboardType',
+ 'TextData',
+ 'TextElement',
+ 'TextGrid',
+ 'TextJustification',
+ 'TextPacket',
+ 'TextPosition',
+ 'TextRecognize',
+ 'TextSearch',
+ 'TextSearchReport',
+ 'TextSentences',
+ 'TextString',
+ 'TextStructure',
+ 'TextWords',
+ 'Texture',
+ 'TextureCoordinateFunction',
+ 'TextureCoordinateScaling',
+ 'Therefore',
+ 'ThermodynamicData',
+ 'ThermometerGauge',
+ 'Thick',
+ 'Thickness',
+ 'Thin',
+ 'Thinning',
+ 'ThompsonGroupTh',
+ 'Thread',
+ 'ThreeJSymbol',
+ 'Threshold',
+ 'Through',
+ 'Throw',
+ 'ThueMorse',
+ 'Thumbnail',
+ 'Thursday',
+ 'Ticks',
+ 'TicksStyle',
+ 'Tilde',
+ 'TildeEqual',
+ 'TildeFullEqual',
+ 'TildeTilde',
+ 'TimeConstrained',
+ 'TimeConstraint',
+ 'TimeDirection',
+ 'TimeFormat',
+ 'TimeObject',
+ 'TimeObjectQ',
+ 'TimeSeries',
+ 'TimeSeriesAggregate',
+ 'TimeSeriesForecast',
+ 'TimeSeriesInsert',
+ 'TimeSeriesInvertibility',
+ 'TimeSeriesMap',
+ 'TimeSeriesMapThread',
+ 'TimeSeriesModel',
+ 'TimeSeriesModelFit',
+ 'TimeSeriesResample',
+ 'TimeSeriesRescale',
+ 'TimeSeriesShift',
+ 'TimeSeriesThread',
+ 'TimeSeriesWindow',
+ 'TimeUsed',
+ 'TimeValue',
+ 'TimeZone',
+ 'TimeZoneConvert',
+ 'TimeZoneOffset',
+ 'TimelinePlot',
+ 'Times',
+ 'TimesBy',
+ 'Timing',
+ 'Tiny',
+ 'TitsGroupT',
+ 'ToBoxes',
+ 'ToCharacterCode',
+ 'ToContinuousTimeModel',
+ 'ToDiscreteTimeModel',
+ 'ToEntity',
+ 'ToExpression',
+ 'ToInvertibleTimeSeries',
+ 'ToLowerCase',
+ 'ToNumberField',
+ 'ToPolarCoordinates',
+ 'ToRadicals',
+ 'ToRules',
+ 'ToSphericalCoordinates',
+ 'ToString',
+ 'ToUpperCase',
+ 'Today',
+ 'ToeplitzMatrix',
+ 'Together',
+ 'Toggler',
+ 'TogglerBar',
+ 'TokenWords',
+ 'Tolerance',
+ 'Tomorrow',
+ 'Tooltip',
+ 'TooltipDelay',
+ 'TooltipStyle',
+ 'Top',
+ 'TopHatTransform',
+ 'TopologicalSort',
+ 'Total',
+ 'TotalLayer',
+ 'TotalVariationFilter',
+ 'TotalWidth',
+ 'TouchPosition',
+ 'TouchscreenAutoZoom',
+ 'TouchscreenControlPlacement',
+ 'Tr',
+ 'Trace',
+ 'TraceAbove',
+ 'TraceBackward',
+ 'TraceDepth',
+ 'TraceDialog',
+ 'TraceForward',
+ 'TraceOff',
+ 'TraceOn',
+ 'TraceOriginal',
+ 'TracePrint',
+ 'TraceScan',
+ 'TrackedSymbols',
+ 'TrackingFunction',
+ 'TracyWidomDistribution',
+ 'TradingChart',
+ 'TraditionalForm',
+ 'TransferFunctionCancel',
+ 'TransferFunctionExpand',
+ 'TransferFunctionFactor',
+ 'TransferFunctionModel',
+ 'TransferFunctionPoles',
+ 'TransferFunctionTransform',
+ 'TransferFunctionZeros',
+ 'TransformationClass',
+ 'TransformationFunction',
+ 'TransformationFunctions',
+ 'TransformationMatrix',
+ 'TransformedDistribution',
+ 'TransformedField',
+ 'TransformedProcess',
+ 'TransformedRegion',
+ 'TransitionDirection',
+ 'TransitionDuration',
+ 'TransitionEffect',
+ 'TransitiveClosureGraph',
+ 'TransitiveReductionGraph',
+ 'Translate',
+ 'TranslationOptions',
+ 'TranslationTransform',
+ 'Transliterate',
+ 'Transparent',
+ 'Transpose',
+ 'TravelDirections',
+ 'TravelDirectionsData',
+ 'TravelDistance',
+ 'TravelDistanceList',
+ 'TravelMethod',
+ 'TravelTime',
+ 'TreeForm',
+ 'TreeGraph',
+ 'TreeGraphQ',
+ 'TreePlot',
+ 'TrendStyle',
+ 'Triangle',
+ 'TriangleWave',
+ 'TriangularDistribution',
+ 'TriangulateMesh',
+ 'Trig',
+ 'TrigExpand',
+ 'TrigFactor',
+ 'TrigFactorList',
+ 'TrigReduce',
+ 'TrigToExp',
+ 'Trigger',
+ 'TrimmedMean',
+ 'TropicalStormData',
+ 'True',
+ 'TrueQ',
+ 'TruncatedDistribution',
+ 'TsallisQExponentialDistribution',
+ 'TsallisQGaussianDistribution',
+ 'Tube',
+ 'Tuesday',
+ 'TukeyLambdaDistribution',
+ 'TukeyWindow',
+ 'TunnelData',
+ 'Tuples',
+ 'TuranGraph',
+ 'TuringMachine',
+ 'TuttePolynomial',
+
+ 'URL',
+ 'URLBuild',
+ 'URLDecode',
+ 'URLDispatcher',
+ 'URLDownload',
+ 'URLEncode',
+ 'URLExecute',
+ 'URLExpand',
+ 'URLParse',
+ 'URLQueryDecode',
+ 'URLQueryEncode',
+ 'URLRead',
+ 'URLSaveAsynchronous',
+ 'URLShorten',
+ 'URLSubmit',
+ 'UnateQ',
+ 'Uncompress',
+ 'Undefined',
+ 'UnderBar',
+ 'Underflow',
+ 'Underlined',
+ 'Underoverscript',
+ 'UnderoverscriptBox',
+ 'UnderoverscriptBoxOptions',
+ 'Underscript',
+ 'UnderscriptBox',
+ 'UnderscriptBoxOptions',
+ 'UnderseaFeatureData',
+ 'UndirectedEdge',
+ 'UndirectedGraph',
+ 'UndirectedGraphQ',
+ 'UndoOptions',
+ 'UndoTrackedVariables',
+ 'Unequal',
+ 'UnequalTo',
+ 'Unevaluated',
+ 'UniformDistribution',
+ 'UniformGraphDistribution',
+ 'UniformSumDistribution',
+ 'Uninstall',
+ 'Union',
+ 'UnionPlus',
+ 'Unique',
+ 'UnitBox',
+ 'UnitConvert',
+ 'UnitDimensions',
+ 'UnitRootTest',
+ 'UnitSimplify',
+ 'UnitStep',
+ 'UnitSystem',
+ 'UnitTriangle',
+ 'UnitVector',
+ 'UnitaryMatrixQ',
+ 'Unitize',
+ 'UnityDimensions',
+ 'UniverseModelData',
+ 'UniversityData',
+ 'UnixTime',
+ 'Unprotect',
+ 'UnsameQ',
+ 'UnsavedVariables',
+ 'Unset',
+ 'UnsetShared',
+ 'UpArrow',
+ 'UpArrowBar',
+ 'UpArrowDownArrow',
+ 'UpDownArrow',
+ 'UpEquilibrium',
+ 'UpSet',
+ 'UpSetDelayed',
+ 'UpTee',
+ 'UpTeeArrow',
+ 'UpTo',
+ 'UpValues',
+ 'Update',
+ 'UpdateInterval',
+ 'UpdateSearchIndex',
+ 'UpperCaseQ',
+ 'UpperLeftArrow',
+ 'UpperRightArrow',
+ 'UpperTriangularize',
+ 'Upsample',
+ 'UsingFrontEnd',
+ 'UtilityFunction',
+
+ 'ValidationLength',
+ 'ValidationSet',
+ 'ValueDimensions',
+ 'ValueQ',
+ 'Values',
+ 'Variables',
+ 'Variance',
+ 'VarianceEquivalenceTest',
+ 'VarianceEstimatorFunction',
+ 'VarianceGammaDistribution',
+ 'VarianceTest',
+ 'VectorAngle',
+ 'VectorColorFunction',
+ 'VectorColorFunctionScaling',
+ 'VectorDensityPlot',
+ 'VectorPlot',
+ 'VectorPlot3D',
+ 'VectorPoints',
+ 'VectorQ',
+ 'VectorScale',
+ 'VectorStyle',
+ 'Vectors',
+ 'Vee',
+ 'Verbatim',
+ 'VerificationTest',
+ 'VerifyConvergence',
+ 'VerifySecurityCertificates',
+ 'VerifySolutions',
+ 'VerifyTestAssumptions',
+ 'VertexAdd',
+ 'VertexCapacity',
+ 'VertexColors',
+ 'VertexComponent',
+ 'VertexConnectivity',
+ 'VertexContract',
+ 'VertexCoordinateRules',
+ 'VertexCoordinates',
+ 'VertexCorrelationSimilarity',
+ 'VertexCosineSimilarity',
+ 'VertexCount',
+ 'VertexCoverQ',
+ 'VertexDataCoordinates',
+ 'VertexDegree',
+ 'VertexDelete',
+ 'VertexDiceSimilarity',
+ 'VertexEccentricity',
+ 'VertexInComponent',
+ 'VertexInDegree',
+ 'VertexIndex',
+ 'VertexJaccardSimilarity',
+ 'VertexLabelStyle',
+ 'VertexLabeling',
+ 'VertexLabels',
+ 'VertexList',
+ 'VertexNormals',
+ 'VertexOutComponent',
+ 'VertexOutDegree',
+ 'VertexQ',
+ 'VertexRenderingFunction',
+ 'VertexReplace',
+ 'VertexShape',
+ 'VertexShapeFunction',
+ 'VertexSize',
+ 'VertexStyle',
+ 'VertexTextureCoordinates',
+ 'VertexWeight',
+ 'VerticalBar',
+ 'VerticalGauge',
+ 'VerticalSeparator',
+ 'VerticalSlider',
+ 'VerticalTilde',
+ 'ViewAngle',
+ 'ViewCenter',
+ 'ViewMatrix',
+ 'ViewPoint',
+ 'ViewRange',
+ 'ViewVector',
+ 'ViewVertical',
+ 'Visible',
+ 'VoigtDistribution',
+ 'VolcanoData',
+ 'Volume',
+ 'VonMisesDistribution',
+ 'VoronoiMesh',
+
+ 'WaitAll',
+ 'WaitAsynchronousTask',
+ 'WaitNext',
+ 'WakebyDistribution',
+ 'WalleniusHypergeometricDistribution',
+ 'WaringYuleDistribution',
+ 'WarpingCorrespondence',
+ 'WarpingDistance',
+ 'WatershedComponents',
+ 'WatsonUSquareTest',
+ 'WattsStrogatzGraphDistribution',
+ 'WaveletBestBasis',
+ 'WaveletFilterCoefficients',
+ 'WaveletImagePlot',
+ 'WaveletListPlot',
+ 'WaveletMapIndexed',
+ 'WaveletMatrixPlot',
+ 'WaveletPhi',
+ 'WaveletPsi',
+ 'WaveletScale',
+ 'WaveletScalogram',
+ 'WaveletThreshold',
+ 'WeakStationarity',
+ 'WeaklyConnectedComponents',
+ 'WeaklyConnectedGraphComponents',
+ 'WeaklyConnectedGraphQ',
+ 'WeatherData',
+ 'WeatherForecastData',
+ 'WeberE',
+ 'Wedge',
+ 'Wednesday',
+ 'WeibullDistribution',
+ 'WeierstrassHalfPeriods',
+ 'WeierstrassInvariants',
+ 'WeierstrassP',
+ 'WeierstrassPPrime',
+ 'WeierstrassSigma',
+ 'WeierstrassZeta',
+ 'WeightedAdjacencyGraph',
+ 'WeightedAdjacencyMatrix',
+ 'WeightedData',
+ 'WeightedGraphQ',
+ 'Weights',
+ 'WelchWindow',
+ 'WheelGraph',
+ 'WhenEvent',
+ 'Which',
+ 'While',
+ 'White',
+ 'WhiteNoiseProcess',
+ 'WhitePoint',
+ 'Whitespace',
+ 'WhitespaceCharacter',
+ 'WhittakerM',
+ 'WhittakerW',
+ 'WienerFilter',
+ 'WienerProcess',
+ 'WignerD',
+ 'WignerSemicircleDistribution',
+ 'WikipediaData',
+ 'WikipediaSearch',
+ 'WilksW',
+ 'WilksWTest',
+ 'WindDirectionData',
+ 'WindSpeedData',
+ 'WindVectorData',
+ 'WindowClickSelect',
+ 'WindowElements',
+ 'WindowFloating',
+ 'WindowFrame',
+ 'WindowMargins',
+ 'WindowMovable',
+ 'WindowOpacity',
+ 'WindowSize',
+ 'WindowStatusArea',
+ 'WindowTitle',
+ 'WindowToolbars',
+ 'WishartMatrixDistribution',
+ 'With',
+ 'WolframAlpha',
+ 'WolframLanguageData',
+ 'Word',
+ 'WordBoundary',
+ 'WordCharacter',
+ 'WordCloud',
+ 'WordCount',
+ 'WordCounts',
+ 'WordData',
+ 'WordDefinition',
+ 'WordFrequency',
+ 'WordFrequencyData',
+ 'WordList',
+ 'WordOrientation',
+ 'WordSearch',
+ 'WordSeparators',
+ 'WordSpacings',
+ 'WordStem',
+ 'WordTranslation',
+ 'WorkingPrecision',
+ 'WrapAround',
+ 'Write',
+ 'WriteLine',
+ 'WriteString',
+ 'Wronskian',
+
+ 'XMLElement',
+ 'XMLObject',
+ 'XMLTemplate',
+ 'XYZColor',
+ 'Xnor',
+ 'Xor',
+
+ 'Yellow',
+ 'Yesterday',
+ 'YuleDissimilarity',
+
+ 'ZIPCodeData',
+ 'ZTest',
+ 'ZTransform',
+ 'ZernikeR',
+ 'ZeroSymmetric',
+ 'ZeroTest',
+ 'Zeta',
+ 'ZoomCenter',
+ 'ZetaZero',
+ 'ZipfDistribution',
+ 'ZoomFactor'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ 1 => true
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '@', '//', '/@', '@@', '@@@', '#', '&', //functions
+ '=', ':=', '+=', '-=', '*=', '/=', //assignments
+ '^', '+' ,'-', '/', '*', '>', '<', '%', //math
+ '||', '&&', //logic
+ '/.', '/;', '->', ':>' //rules
+ ),
+ 2 => array( // Wolfram
+ '$Aborted',
+ '$AllowExternalChannelFunctions',
+ '$AssertFunction',
+ '$Assumptions',
+ '$AsynchronousTask',
+ '$AudioOutputDevices',
+
+ '$BaseDirectory',
+ '$BatchInput',
+ '$BatchOutput',
+ '$ByteOrdering',
+
+ '$CacheBaseDirectory',
+ '$Canceled',
+ '$ChannelBase',
+ '$CharacterEncoding',
+ '$CharacterEncodings',
+ '$CloudBase',
+ '$CloudConnected',
+ '$CloudCreditsAvailable',
+ '$CloudEvaluation',
+ '$CloudExpressionBase',
+ '$CloudRootDirectory',
+ '$CloudSymbolBase',
+ '$CommandLine',
+ '$CompilationTarget',
+ '$ConfiguredKernels',
+ '$Context',
+ '$ContextPath',
+ '$ControlActiveSetting',
+ '$CookieStore',
+ '$Cookies',
+ '$CreationDate',
+ '$CurrentLink',
+
+ '$DateStringFormat',
+ '$DefaultAudioOutputDevice',
+ '$DefaultImagingDevice',
+ '$DefaultLocalBase',
+ '$Display',
+ '$DisplayFunction',
+ '$DistributedContexts',
+ '$DynamicEvaluation',
+
+ '$Echo',
+ '$EmbedCodeEnvironments',
+ '$EmbeddableServices',
+ '$EntityStores',
+ '$Epilog',
+ '$EvaluationCloudObject',
+ '$EvaluationEnvironment',
+ '$ExportFormats',
+
+ '$Failed',
+ '$FontFamilies',
+ '$FrontEnd',
+ '$FrontEndSession',
+
+ '$GeoLocation',
+ '$GeoLocationCity',
+ '$GeoLocationCountry',
+ '$GeoLocationSource',
+
+ '$HistoryLength',
+ '$HomeDirectory',
+
+ '$IgnoreEOF',
+ '$ImageFormattingWidth',
+ '$ImagingDevice',
+ '$ImagingDevices',
+ '$ImportFormats',
+ '$InitialDirectory',
+ '$Input',
+ '$InputFileName',
+ '$InputStreamMethods',
+ '$Inspector',
+ '$InstallationDirectory',
+ '$InterpreterTypes',
+ '$IterationLimit',
+
+ '$KernelCount',
+ '$KernelID',
+
+ '$Language',
+ '$LibraryPath',
+ '$LicenseExpirationDate',
+ '$LicenseID',
+ '$LicenseServer',
+ '$Line',
+ '$Linked',
+ '$LocalBase',
+ '$LocalSymbolBase',
+
+ '$MachineAddresses',
+ '$MachineDomains',
+ '$MachineEpsilon',
+ '$MachineID',
+ '$MachineName',
+ '$MachinePrecision',
+ '$MachineType',
+ '$MaxExtraPrecision',
+ '$MaxMachineNumber',
+ '$MaxNumber',
+ '$MaxPiecewiseCases',
+ '$MaxPrecision',
+ '$MaxRootDegree',
+ '$MessageGroups',
+ '$MessageList',
+ '$MessagePrePrint',
+ '$Messages',
+ '$MinMachineNumber',
+ '$MinNumber',
+ '$MinPrecision',
+ '$ModuleNumber',
+
+ '$NewMessage',
+ '$NewSymbol',
+ '$Notebooks',
+ '$NumberMarks',
+
+ '$OperatingSystem',
+ '$Output',
+ '$OutputSizeLimit',
+ '$OutputStreamMethods',
+
+ '$Packages',
+ '$ParentLink',
+ '$ParentProcessID',
+ '$Path',
+ '$PathnameSeparator',
+ '$PerformanceGoal',
+ '$Permissions',
+ '$PlotTheme',
+ '$Post',
+ '$Pre',
+ '$PrePrint',
+ '$PreRead',
+ '$Printout3DPreviewer',
+ '$ProcessID',
+ '$ProcessorCount',
+ '$ProcessorType',
+
+ '$RecursionLimit',
+ '$ReleaseNumber',
+ '$RequesterAddress',
+ '$RequesterWolframID',
+ '$RequesterWolframUUID',
+ '$RootDirectory',
+
+ '$ScheduledTask',
+ '$ScriptCommandLine',
+ '$ScriptInputString',
+ '$Services',
+ '$SessionID',
+ '$SharedFunctions',
+ '$SharedVariables',
+ '$SoundDisplayFunction',
+ '$SourceLink',
+ '$SynchronousEvaluation',
+ '$SyntaxHandler',
+ '$System',
+ '$SystemCharacterEncoding',
+ '$SystemID',
+ '$SystemShell',
+ '$SystemTimeZone',
+ '$SystemWordLength',
+
+ '$TemplatePath',
+ '$TemporaryDirectory',
+ '$TimeUnit',
+ '$TimeZone',
+ '$TimeZoneEntity',
+ '$TimedOut',
+
+ '$UnitSystem',
+ '$Urgent',
+ '$UserAgentString',
+ '$UserBaseDirectory',
+ '$UserDocumentsDirectory',
+ '$UserName',
+
+ '$Version',
+ '$VersionNumber',
+
+ '$WolframID',
+ '$WolframUUID',
+ ),
+ 3 => array( // array stuff
+ '{', '}', '[[', ']]', '<|', '|>'
+ ),
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #FF7700; font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #999999; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 1 => '',
+ ),
+ 'BRACKETS' => array(),
+ 'STRINGS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(),
+ 'SYMBOLS' => array(
+ 1 => 'color: #133CAC; font-weight: bold;',
+ 2 => 'color: #028E9B; font-weight: bold;',
+ 3 => 'color: #FFAD00; font-weight: bold;',
+ ),
+ //'BRACKETS' => array(
+ //0 => 'color: #8C0953; font-weight: bold;', // array
+ //),
+ 'REGEXPS' => array(
+ 0 => 'color: #133CAC; font-weight: bold;',
+ ),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => 'http://reference.wolfram.com/language/ref/{FNAME}.html'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ 0 => '#[1-9][0-9]*'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/matlab.php b/platform/www/vendor/geshi/geshi/src/geshi/matlab.php
new file mode 100644
index 0000000..84c0209
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/matlab.php
@@ -0,0 +1,226 @@
+<?php
+/*************************************************************************************
+ * matlab.php
+ * -----------
+ * Author: Florian Knorn (floz@gmx.de)
+ * Copyright: (c) 2004 Florian Knorn (http://www.florian-knorn.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/02/09
+ *
+ * Matlab M-file language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2006-03-25 (1.0.7.22)
+ * - support for the transpose operator
+ * - many keywords added
+ * - links to the matlab documentation at mathworks
+ * by: Olivier Verdier (olivier.verdier@free.fr)
+ * 2005/05/07 (1.0.0)
+ * - First Release
+ *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Matlab M',
+ 'COMMENT_SINGLE' => array(1 => '%'),
+ 'COMMENT_MULTI' => array(),
+ //Matlab Strings
+ 'COMMENT_REGEXP' => array(
+ 2 => "/(?<![\\w\\)\\]\\}\\.])('[^\\n']*?')/"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'break', 'case', 'catch', 'classdef', 'continue', 'elseif', 'else', 'end', 'for',
+ 'function', 'global', 'if', 'otherwise', 'persistent', 'return',
+ 'switch', 'try', 'while'
+ ),
+ 2 => array(
+ 'all','any','exist','is','logical','mislocked',
+
+ 'abs','acos','acosh','acot','acoth','acsc','acsch','airy','angle',
+ 'ans','area','arrayfun','asec','asech','asin','asinh','atan','atan2','atanh',
+ 'auread','autumn','auwrite','axes','axis','balance','bar','bar3',
+ 'bar3h','barh','besselh','besseli','besselj','besselk','Bessely',
+ 'beta','betainc','betaln','bicg','bicgstab','bin2dec','bitand',
+ 'bitcmp','bitget','bitmax','bitor','bitset','bitshift','bitxor',
+ 'blkdiag','bone','bounds','box','brighten','builtin','bwcontr','calendar',
+ 'camdolly','camlight','camlookat','camorbit','campan','campos',
+ 'camproj','camroll','camtarget','camup','camva','camzoom','capture',
+ 'cart2pol','cart2sph','cat','caxis','cdf2rdf','ceil','cell',
+ 'cell2struct','celldisp','cellfun','cellplot','cellstr','cgs',
+ 'char','chol','cholinc','cholupdate','cla','clabel','class','clc',
+ 'clf','clg','clock','close','colmmd','colorbar','colorcube',
+ 'colordef','colormap','colperm','comet','comet3','compan','compass',
+ 'complex','computer','cond','condeig','condest','coneplot','conj',
+ 'contour','contourc','contourf','contourslice','contrast','conv',
+ 'conv2','convhull','cool','copper','copyobj','corrcoef','cos',
+ 'cosh','cot','coth','cov','cplxpair','cputime','cross','csc','csch',
+ 'cumprod','cumsum','cumtrapz','cylinder','daspect','dataset','datastore','date','datenum',
+ 'datestr','datetick','datetime','datevec','dbclear','dbcont','dbdown',
+ 'dblquad','dbmex','dbquit','dbstack','dbstatus','dbstep','dbstop',
+ 'dbtype','dbup','deblank','dec2bin','dec2hex','deconv','del2',
+ 'delaunay','det','diag','dialog','diff','diffuse','discretize','dlmread',
+ 'dlmwrite','dmperm','double','dragrect','drawnow','dsearch','duration','eig',
+ 'eigs','ellipj','ellipke','eomday','eps','erf','erfc','erfcx',
+ 'erfiny','error','errorbar','errordlg','etime','eval','evalc',
+ 'evalin','exp','expint','expm','eye','ezcontour','ezcontourf',
+ 'ezmesh','ezmeshc','ezplot','ezplot3','ezpolar','ezsurf','ezsurfc',
+ 'factor','factorial','fclose','feather','feof','ferror','feval',
+ 'fft','fft2','fftshift','fgetl','fgets','fieldnames','figure',
+ 'fill','fill3','filter','filter2','find','findfigs','findobj',
+ 'findstr','fix','flag','flipdim','fliplr','flipud','floor','flops',
+ 'fmin','fmins','fopen','fplot','fprintf','fread','frewind','fscanf',
+ 'fseek','ftell','full','funm','fwrite','fzero','gallery','gamma',
+ 'gammainc','gammaln','gca','gcbo','gcd','gcf','gco','get',
+ 'getfield','ginput','gmres','gradient','gray','graymon','grid',
+ 'griddata','gsvd','gtext','hadamard','hankel','hdf','head','helpdlg',
+ 'hess','hex2dec','hex2num','hidden','hilb','hist','hold','hot',
+ 'hsv','hsv2rgb','i','ifft','ifft2','ifftn','ifftshift','imag',
+ 'image','imfinfo','imread','imwrite','ind2sub','Inf','inferiorto',
+ 'inline','inpolygon','input','inputdlg','inputname','int16',
+ 'int2str','int32','int8','int64','interp1','interp2','interp3','interpft',
+ 'interpn','intersect','inv','invhilb','ipermute','isa','iscell',
+ 'iscellstr','isfile','isfolder','ishandle','isinf',
+ 'ismember','isnan','isocaps','isonormals','isosurface','issorted','j','jet','keyboard',
+ 'lcm','legend','legendre','light','lighting','lightingangle',
+ 'lin2mu','line','lines','linspace','listdlg','loadobj','log',
+ 'log10','log2','loglog','logm','logspace','lower','lscov','lu',
+ 'luinc','magic','mat2str','material','max','mean','median','menu',
+ 'menuedit','mesh','meshc','meshgrid','min','missing','mod','msgbox','mu2lin',
+ 'NaN','nargchk','nargin','nargout','nchoosek','ndgrid','ndims',
+ 'newplot','nextpow2','nnls','nnz','nonzeros','norm','normest','now',
+ 'null','num2cell','num2str','nzmax','ode113,','ode15s,','ode23s,',
+ 'ode23t,','ode23tb','ode45,','odefile','odeget','odeset','ones',
+ 'orient','orth','pagedlg','pareto','pascal','patch','pause',
+ 'pbaspect','pcg','pcolor','peaks','perms','permute','pi','pie',
+ 'pie3','pinv','plot','plot3','plotmatrix','plotyy','pol2cart',
+ 'polar','poly','polyarea','polyder','polyeig','polyfit','polyval',
+ 'polyvalm','pow2','primes','print','printdlg','printopt','prism',
+ 'prod','propedit','qmr','qr','qrdelete','qrinsert','qrupdate',
+ 'quad','questdlg','quiver','quiver3','qz','rand','randn','randperm',
+ 'rank','rat','rats','rbbox','rcond','readtable','real','realmax','realmin',
+ 'rectangle','reducepatch','reducevolume','refresh','rem','repmat',
+ 'reset','reshape','residue','rgb2hsv','rgbplot','ribbon','rmfield',
+ 'roots','rose','rot90','rotate','rotate3d','round','rref',
+ 'rrefmovie','rsf2csf','saveobj','scatter','scatter3','schur',
+ 'script','sec','sech','selectmoveresize','semilogx','semilogy',
+ 'set','setdiff','setfield','setxor','shading','shg','shiftdim',
+ 'shrinkfaces','sign','sin','single','sinh','slice','smooth3','sort',
+ 'sortrows','sound','soundsc','spalloc','sparse','spconvert',
+ 'spdiags','specular','speye','spfun','sph2cart','sphere','spinmap',
+ 'spline','spones','spparms','sprand','sprandn','sprandsym','spring',
+ 'sprintf','sqrt','sqrtm','squeeze','sscanf','stairs','std','stem',
+ 'stem3','str2double','str2num','strcat','strcmp','strcmpi',
+ 'stream2','stream3','streamline','string','strings','strjust','strmatch',
+ 'strncmp','strrep','strtok','struct','structfun','struct2cell','strvcat',
+ 'sub2ind','subplot','subspace','subvolume','sum','summer',
+ 'superiorto','surf','surf2patch','surface','surfc','surfl',
+ 'surfnorm','svd','svds','symmmd','symrcm','symvar','tail','tall','tan','tanh',
+ 'texlabel','text Create','textread','textwrap','tic','timeseries','timer','timetable','title','toc',
+ 'toeplitz','trace','trapz','tril','trimesh','trisurf','triu',
+ 'tsearch','uicontext Create','uicontextmenu','uicontrol',
+ 'uigetfile','uimenu','uint32','uint8','uint64','uiputfile','uiresume',
+ 'uisetcolor','uisetfont','uiwait Used','union','unique','unwrap',
+ 'upper','var','varargin','varargout','vectorize','view','viewmtx',
+ 'voronoi','waitbar','waitforbuttonpress','warndlg','warning',
+ 'waterfall','wavread','wavwrite','weekday','whitebg','wilkinson',
+ 'winter','wk1read','wk1write','writetable','xlabel','xlim','ylabel','ylim',
+ 'zeros','zlabel','zlim','zoom',
+ //'[Keywords 6]',
+ 'addpath','cd','clear','copyfile','delete','diary','dir','disp',
+ 'doc','docopt','echo','edit','fileparts','format','fullfile','help',
+ 'helpdesk','helpwin','home','inmem','lasterr','lastwarn','length',
+ 'load','lookfor','ls','matlabrc','matlabroot','mkdir','mlock',
+ 'more','munlock','numel','open','openvar','pack','partialpath','path',
+ 'pathtool','profile','profreport','pwd','quit','rmpath','save',
+ 'saveas','size','tempdir','tempname','type','ver','version','web',
+ 'what','whatsnew','which','who','whos','workspace'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '...'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ //3 => false,
+ //4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF;',
+ 2 => 'color: #0000FF;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #228B22;',
+ 2 => 'color:#A020F0;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'STRINGS' => array(
+ //0 => 'color: #A020F0;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #33f;'
+ ),
+ 'METHODS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #33f;'
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => 'https://www.mathworks.com/help/matlab/ref/{FNAMEL}.html'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ //Complex numbers
+ 0 => '(?<![\\w\\/])[+-]?[\\d]*([\\d]\\.|\\.[\\d])?[\\d]*[ij](?![\\w]|\<DOT>html)'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/mercury.php b/platform/www/vendor/geshi/geshi/src/geshi/mercury.php
new file mode 100644
index 0000000..df8c9bb
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/mercury.php
@@ -0,0 +1,130 @@
+<?php
+/*************************************************************************************
+ * mercury.php
+ * --------
+ * Author: Sebastian Godelet (sebastian.godelet+github@gmail.com)
+ * Copyright: (c) 2014
+ * Release Version: 1.0.9.1
+ * Date Started: 2014/10/30
+ *
+ * Mercury language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2014/10/30 (1.0.8.13)
+ * - First Release
+ *
+ * TODO (updated 2014/10/30)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Mercury',
+ 'COMMENT_SINGLE' => array(1 => '%'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array('"', "\'"),
+ 'HARDCHAR' => '"',
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '\\',
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'end_module', 'finalise', 'finalize', 'func', 'implementation',
+ 'include_module', 'initalisation', 'initialization',
+ 'instance', 'interface',
+ 'import_module', 'module', 'pragma', 'pred',
+ 'type', 'typeclass', 'use_module'
+ ),
+ 2 => array(
+ 'atomic', 'foreign_code', 'foreign_export', 'foreign_type', 'memo'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '[', ']', '{', '}',),
+ 1 => array('?-', ':-', '=:='),
+ 2 => array('\-', '\+', '\*', '\/', '/\\'),
+ 3 => array('-', '+', '*', '/'),
+ 4 => array('.', ':', ',', ';'),
+ 5 => array('!', '@', '&', '|', '!.', '!:'),
+ 6 => array('<', '>', '=')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #990000;',
+ 2 => 'color: #99aa77;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;',
+ 'HARD' => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #800080;'
+ ),
+ 'METHODS' => array(),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;',
+ 1 => 'color: #339933;',
+ 2 => 'color: #339933;',
+ 3 => 'color: #339933;',
+ 4 => 'color: #339933;',
+ 5 => 'color: #339933;',
+ 6 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #008080;'
+ ),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.mercurylang.org',
+ 2 => 'http://www.mercurylang.org'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ //Variables
+ 0 => "(?<![a-zA-Z0-9_])(?!(?:PIPE|SEMI|DOT)[^a-zA-Z0-9_])[A-Z_][a-zA-Z0-9_]*(?![a-zA-Z0-9_])(?!\x7C)"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/metapost.php b/platform/www/vendor/geshi/geshi/src/geshi/metapost.php
new file mode 100644
index 0000000..83882d8
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/metapost.php
@@ -0,0 +1,399 @@
+<?php
+/*************************************************************************************
+ * metapost.php
+ * -----------
+ * Author: Maxime Chupin (notezik@gmail.com)
+ * Copyright: (c) 2011 Maxime Chupin
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/08/02
+ *
+ * Metapost language file for GeSHi.
+ *
+ * https://en.wikipedia.org/wiki/MetaPost
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'MetaPost',
+ 'COMMENT_SINGLE' => array(1 => '%'),
+ 'COMMENT_MULTI' => array(
+ 'verbatim'=>'etex', //TeX and LaTeX preambule
+ 'btex' => 'etex' //TeX invocation
+ ),
+ 'COMMENT_REGEXP' => array(
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array( //type
+ 'boolean',
+ 'color', 'cmykcolor',
+ 'expr',
+ 'numeric',
+ 'pair', 'path', 'pen', 'picture',
+ 'string', 'suffix',
+ 'text', 'transform',
+ ),
+ 2 => array( //file construction
+ 'beginfig', 'begingroup',
+ 'def',
+ 'end', 'enddef', 'endfig', 'endgroup',
+ 'hide',
+ 'image', 'input',
+ 'let',
+ 'makepen', 'makepath',
+ 'newinternal',
+ 'primary', 'primarydef',
+ 'save', 'secondarydef', 'shipout', 'special',
+ 'tertiarydef',
+ 'vardef'
+ ),
+ 3 => array( //programmation structure
+ 'else', 'elseif', 'endfor', 'exitif', 'exitunless',
+ 'fi', 'for', 'forever', 'forsuffix',
+ 'if',
+ 'step',
+ 'until', 'upto',
+ ),
+ 4 => array( //operations return pair
+ 'bot',
+ 'dir', 'direction of',
+ 'intersectionpoint', 'intiersectiontimes',
+ 'lft', 'llcorner', 'lrcorner',
+ 'penoffset of', 'point of', 'postcontrol of', 'precontrol of',
+ 'rt',
+ 'top',
+ 'ulcorner', 'unitvector', 'urcorner',
+ 'z',
+ ),
+ 5 => array( //operations return path or picture or pen
+ 'bbox',
+ 'center', 'cutafter', 'cutbefore',
+ 'dashpart', 'dashpattern',
+ 'glyph of',
+ 'infont',
+ 'pathpart', 'penpart',
+ 'reverse',
+ 'subpath of',
+ ),
+ 6 => array( //operations return string (or complementary)
+ 'closefrom',
+ 'fontpart',
+ 'readfrom',
+ 'str', 'substring of',
+ 'textpart'
+ ),
+ 7 => array( // operations return numeric
+ 'abs', 'angle', 'arclength', 'arctime of', 'ASCII',
+ 'blackpart', 'bluepart',
+ 'ceiling', 'char', 'colormodel', 'cosd', 'cyanpart',
+ 'decimal', 'decr', 'directionpoint of', 'directiontime of',
+ 'div', 'dotprod',
+ 'floor', 'fontsize',
+ 'greenpart', 'greypart',
+ 'hex',
+ 'incr',
+ 'length',
+ 'magentapart', 'max', 'mexp', 'min', 'mlog', 'mod',
+ 'normaldeviate',
+ 'oct',
+ 'redpart', 'round',
+ 'sind', 'sqrt',
+ 'uniformdeviate',
+ 'xpart', 'xxpart', 'xypart',
+ 'yellowpart', 'ypart', 'yxpart', 'yypart',
+ ),
+ 8 => array( // operations return boolean
+ 'and',
+ 'bounded',
+ 'clipped',
+ 'filled',
+ 'known',
+ 'not',
+ 'odd',
+ 'or',
+ 'rgbcolor',
+ 'stroked',
+ 'textual',
+ 'unknown'
+ ),
+ 9 => array( //operations return color
+ 'colorpart'
+ ),
+ 10 => array( //operations return transform
+ 'inverse'
+ ),
+ 11 => array( //constructors
+ 'also',
+ 'buildcycle',
+ 'contour', 'controls', 'cycle',
+ 'doublepath',
+ 'setbounds',
+ 'to',
+ 'whatever'
+ ),
+ 12 => array( //labels
+ 'label',
+ 'label.bot',
+ 'label.top',
+ 'label.llft',
+ 'label.lft',
+ 'label.ulft',
+ 'label.lrt',
+ 'label.rt',
+ 'label.urt',
+
+ 'labels',
+ 'labels.bot',
+ 'labels.top',
+ 'labels.llft',
+ 'labels.lft',
+ 'labels.ulft',
+ 'labels.lrt',
+ 'labels.rt',
+ 'labels.urt',
+
+ 'thelabel',
+ 'thelabel.bot',
+ 'thelabel.top',
+ 'thelabel.llft',
+ 'thelabel.lft',
+ 'thelabel.ulft',
+ 'thelabel.lrt',
+ 'thelabel.rt',
+ 'thelabel.urt',
+
+ 'dotlabel',
+ 'dotlabel.bot',
+ 'dotlabel.top',
+ 'dotlabel.llft',
+ 'dotlabel.lft',
+ 'dotlabel.ulft',
+ 'dotlabel.lrt',
+ 'dotlabel.rt',
+ 'dotlabel.urt',
+ ),
+ 13 => array( //general transformations
+ 'about',
+ 'reflected', 'reflectedaround',
+ 'rotated', 'rotatedabout', 'rotatedaround',
+ 'scaled', 'slanted', 'shifted',
+ 'transformed',
+ 'xscaled',
+ 'yscaled',
+ 'zscaled',
+ ),
+ 14 => array( //draw instructions
+ 'addto',
+ 'clip', 'cutdraw',
+ 'draw', 'drawarrow', 'drawdblarrow', 'drawdot',
+ 'fill', 'filldraw',
+ 'undraw', 'unfill', 'unfilldraw'
+ ),
+ 15 => array( //style of drawing
+ 'curl',
+ 'dashed', 'drawoptions',
+ 'pickup',
+ 'tension',
+ 'withcmykcolor', 'withcolor',
+ 'withgreyscale', 'withpen', 'withpostscript', 'withprescript',
+ 'withrgbcolor',
+ ),
+ 16 => array( //read write show
+ 'errhelp', 'errmessage',
+ 'fontmapfile', 'fontmapline',
+ 'interim',
+ 'loggingall',
+ 'message',
+ 'scantokens', 'show', 'showdependencies', 'showtoken', 'showvariable',
+ 'tracingall', 'tracingnone',
+ 'write to',
+ ),
+ 17 => array( //Internal variables with numeric values
+ 'ahangle', 'ahlength',
+ 'bboxmargin',
+ 'charcode',
+ 'day', 'defaultcolormodel', 'defaultpen', 'defaultscale',
+ 'dotlabeldiam',
+ 'hour',
+ 'labeloffset',
+ 'linecap', 'linejoin',
+ 'minute', 'miterlimit', 'month', 'mpprocset',
+ 'pausing', 'prologues',
+ 'restoreclipcolor',
+ 'showstopping',
+ 'time',
+ 'tracingcapsules', 'tracingchoices', 'tracingcommands',
+ 'tracingequations', 'tracinglostchars', 'tracingmacros',
+ 'tracingonline', 'tracingoutput', 'tracingrestores',
+ 'tracingspecs', 'tracingstats', 'tracingtitles',
+ 'troffmode', 'truecorners',
+ 'warningcheck',
+ 'year',
+ ),
+ 18 => array( //Internal string variables
+ 'filenametemplate',
+ 'jobname',
+ 'outputformat', 'outputtemplate',
+ ),
+ 19 => array( //other predefined variables
+ 'background',
+ 'currentpen', 'currentpicture', 'cuttings',
+ 'defaultfont',
+ 'extra_beginfig', 'extra_endfig',
+ ),
+ 20 => array( //predefined constants
+ 'beveled', 'black', 'blue', 'bp', 'butt',
+ 'cc', 'cm',
+ 'dd', 'ditto', 'down',
+ 'epsilon', 'evenly', 'EOF',
+ 'false', 'fullcircle',
+ 'green',
+ 'halfcircle',
+ 'identity',
+ 'left',
+ 'mitered', 'mm', 'mpversion',
+ 'nullpen', 'nullpicture',
+ 'origin',
+ 'pc', 'pencircle', 'pensquare', 'pt',
+ 'quartercircle',
+ 'red', 'right', 'rounded',
+ 'squared',
+ 'true',
+ 'unitsquare', 'up',
+ 'white', 'withdots',
+ )
+ ),
+ 'SYMBOLS' => array(
+ '&', ':=', '=', '+', '-',
+ '*', '**', '/', '++', '+-+',
+ '<', '>', '>=', '<=', '<>',
+ '#@', '@', '@#'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true,
+ 10 => true,
+ 11 => true,
+ 12 => true,
+ 13 => true,
+ 14 => true,
+ 15 => true,
+ 16 => true,
+ 17 => true,
+ 18 => true,
+ 19 => true,
+ 20 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #472;', //type
+ 2 => 'color: #35A;font-weight: bold;', //file construction
+ 3 => 'color: #A53;', //structure
+ 4 => 'color: #35A;', //operations return pair
+ 5 => 'color: #35A;', //operations return path or picture or pen
+ 6 => 'color: #35A;', //operations return string
+ 7 => 'color: #35A;', //operations return numeric
+ 8 => 'color: #35A;', //operations return boolean
+ 9 => 'color: #35A;', //operations return color
+ 10 => 'color: #35A;', //operations return transform
+ 11 => 'color: #35A;', //constructors
+ 12 => 'color: #35A;', //labels
+ 13 => 'color: #3B5;', //general transformations
+ 14 => 'color: #35A;', //draw instructions
+ 15 => 'color: #472;', //style of drawing
+ 16 => 'color: #000;', //read write show
+ 17 => 'color: #000;', //Internal variables with numeric values
+ 18 => 'color: #000;', //Internal string variables
+ 19 => 'color: #000;', //other predefined variables
+ 20 => 'color: #000;' //predefined constants
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #777;',
+ 'MULTI' => 'color: #880;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #820;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #880;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000;'
+ ),
+ 'METHODS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+ 9 => '',
+ 10 => '',
+ 11 => '',
+ 12 => '',
+ 13 => '',
+ 14 => '',
+ 15 => '',
+ 16 => '',
+ 17 => '',
+ 18 => '',
+ 19 => '',
+ 20 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/mirc.php b/platform/www/vendor/geshi/geshi/src/geshi/mirc.php
new file mode 100644
index 0000000..a58b45f
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/mirc.php
@@ -0,0 +1,169 @@
+<?php
+/*************************************************************************************
+ * mirc.php
+ * -----
+ * Author: Alberto 'Birckin' de Areba (Birckin@hotmail.com)
+ * Copyright: (c) 2006 Alberto de Areba
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/05/29
+ *
+ * mIRC Scripting language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2006/05/29 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'mIRC Scripting',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'alias', 'menu', 'dialog',
+ ),
+ 2 => array(
+ 'if', 'elseif', 'else', 'while', 'return', 'goto', 'var'
+ ),
+ 3 => array(
+ 'action','ajinvite','amsg','ame','anick','aop','auser',
+ 'avoice','auto','autojoin','away','background','ban','beep',
+ 'channel','clear','clearall','clipboard','close','closemsg','color',
+ 'copy','creq','ctcp','ctcpreply','ctcps','dcc','dde','ddeserver',
+ 'debug','describe','disable','disconnect','dlevel','dll','dns',
+ 'dqwindow','ebeeps','echo','editbox','emailaddr','enable','events',
+ 'exit','filter','findtext','finger','flash','flood','flush',
+ 'flushini','font','fsend','fserve','fullname','ghide','gload',
+ 'gmove','gopts','gplay','gpoint','gqreq','groups','gshow','gsize',
+ 'gstop','gtalk','gunload','guser','help','hop','ignore','invite',
+ 'join','kick','linesep','links','list','load','loadbuf','localinfo',
+ 'log','me','mdi','mkdir','mnick','mode','msg','names','nick','noop',
+ 'notice','notify','omsg','onotice','part','partall','pdcc',
+ 'perform','ping','play','pop','protect','pvoice','qmsg','qme',
+ 'query','queryrn','quit','raw','remini','remote','remove','rename',
+ 'enwin','resetidle','rlevel','rmdir','run','ruser','save','savebuf',
+ 'saveini','say','server','showmirc','sline','sound','speak','splay',
+ 'sreq','strip','time',
+ //'timer[N/name]', //Handled as a regular expression below ...
+ 'timers','timestamp','titlebar','tnick','tokenize','topic','ulist',
+ 'unload','updatenl','url','uwho','window','winhelp','write',
+ 'writeini','who','whois','whowas'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '/'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #994444;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #990000; font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #FF0000;',
+ ),
+ 'STRINGS' => array(
+ ),
+ 'NUMBERS' => array(
+ 0 => '',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #FF0000;',
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #000099;',
+ 1 => 'color: #990000;',
+ 2 => 'color: #000099;',
+ 3 => 'color: #888800;',
+ 4 => 'color: #888800;',
+ 5 => 'color: #000099;',
+ 6 => 'color: #990000; font-weight: bold;',
+ 7 => 'color: #990000; font-weight: bold;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://en.wikichip.org/wiki/mirc/commands/{FNAMEL}'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array('.'),
+ 'REGEXPS' => array(
+ //Variable names
+ 0 => '\$[a-zA-Z0-9]+',
+ //Variable names
+ 1 => '(%|&amp;)[\w\x80-\xFE]+',
+ //Client to Client Protocol handling
+ 2 => '(on|ctcp) (!|@|&amp;)?(\d|\*):[a-zA-Z]+:',
+ /*4 => array(
+ GESHI_SEARCH => '((on|ctcp) (!|@|&)?(\d|\*):(Action|Active|Agent|AppActive|Ban|Chat|Close|Connect|Ctcp|CtcpReply|DccServer|DeHelp|DeOp|DeVoice|Dialog|Dns|Error|Exit|FileRcvd|FileSent|GetFail|Help|Hotlink|Input|Invite|Join|KeyDown|KeyUp|Kick|Load|Logon|MidiEnd|Mode|Mp3End|Nick|NoSound|Notice|Notify|Op|Open|Part|Ping|Pong|PlayEnd|Quit|Raw|RawMode|SendFail|Serv|ServerMode|ServerOp|Signal|Snotice|Start|Text|Topic|UnBan|Unload|Unotify|User|Mode|Voice|Wallops|WaveEnd):)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),*/
+ //Channel names
+ 3 => '(#|@)[a-zA-Z0-9]+',
+ 4 => '-[a-z\d]+',
+ //Raw protocol handling
+ 5 => 'raw (\d|\*):',
+ //Timer handling
+ 6 => '(?<!>|:|\/)\/timer(?!s\b)[0-9a-zA-Z_]+',
+ // /...
+ 7 => '(?<!>|:|\/|\w)\/[a-zA-Z][a-zA-Z0-9]*(?!>)'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'NUMBERS' => GESHI_NEVER
+ ),
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => '(?<![\w\$\|\#;<^&])'
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/mk-61.php b/platform/www/vendor/geshi/geshi/src/geshi/mk-61.php
new file mode 100644
index 0000000..669799c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/mk-61.php
@@ -0,0 +1,106 @@
+<?php
+/*********************************************************************
+ * МК-61/52 language file for GeSHi.
+ *
+ * Author: Russkiy
+ * Copyright: (c) 2014 Russkiy
+ * Release Version: 1.0.9.1
+ * Date Started: 2014-03-11
+ *
+ *********************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ********************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'МК-61/52',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(),
+ 'SYMBOLS' => array(),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(),
+ 'COMMENTS' => array(),
+ 'ESCAPE_CHAR' => array(),
+ 'BRACKETS' => array(),
+ 'STRINGS' => array(),
+ 'NUMBERS' => array(),
+ 'METHODS' => array(),
+ 'SYMBOLS' => array(),
+ 'SCRIPT' => array(),
+ 'REGEXPS' => array(
+ 1 => 'color:#000000;',
+ 2 => 'color:#A0A000;',
+ 3 => 'color:#00A000;',
+ 4 => 'color:#A00000;',
+ 5 => 'color:#0000A0;',
+ 6 => 'text-decoration: underline; color: #A000A0;',
+ 7 => 'font-size: 75%; color: #A0A0A0;'
+ )
+ ),
+ 'URLS' => array(),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ 1 => array(
+ GESHI_SEARCH => '(\s|\t|^|\G|\.)((F|K|К)?(пи|π|СЧ|KСЧ|КСЧ|,|\.|\/\-\/|\+\/\-|ВП))(\s|\t|$)',
+ GESHI_REPLACE => '\\4',
+ GESHI_MODIFIERS => '', GESHI_BEFORE => '\\1<span style="font-weight:lighter;font-size:90%;color:#404040;">\\3</span>', GESHI_AFTER => '\\5'
+ ),
+ 2 => array(
+ GESHI_SEARCH => '(\s|\t|^|\G|\.)((F|K|К)?(ÐОП|&lt;\-&gt;|XY|↔|X↔Y|\^|Ð’\^|↑|В↑|Ð’x|Ð’x|Сx|\-&gt;|↻|→))(\s|\t|$)',
+ GESHI_REPLACE => '\\4',
+ GESHI_MODIFIERS => '', GESHI_BEFORE => '\\1<span style="font-weight:lighter;font-size:90%;color:#404040;">\\3</span>', GESHI_AFTER => '\\5'
+ ),
+ 3 => array(
+ GESHI_SEARCH => '(\s|\t|^|\G|\.)((K|К)?(П|XП|ИП|ПX|Пx)(\d|[A-E]|[a-e]|(Ð|Ð’|С|Д|Е)))(\s|\t|$)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '', GESHI_BEFORE => '\\1', GESHI_AFTER => '\\7'
+ ),
+ 4 => array(
+ GESHI_SEARCH => '(\s|\t|^|\G|\.)((F|K|К)?(10\^x|10x|e\^x|ex|lg|ln|ЧМ|arcsin|<PIPE>x<PIPE>|arccos|ЗÐ|arctg|ГМ|sin|\[x\]|cos|\{x\}|\(x\)|tg|max|\+|\-|\*|x|Ñ…|×|â‹…|\/|\:|÷|МГ|КвКор|квкор|корень|√|x\^2|x2|x²|1\/x|x\^y|xy|МЧ|\x2F\x5C|â‹€|\x5C\x2F|â‹|\(\+\)|⊕|ИÐÐ’))(\s|\t|$)',
+ GESHI_REPLACE => '\\4',
+ GESHI_MODIFIERS => '', GESHI_BEFORE => '\\1<span style="font-weight:lighter;font-size:90%;color:#404040;">\\3</span>', GESHI_AFTER => '\\5'
+ ),
+ 5 => array(
+ GESHI_SEARCH => '(\s|\t|^|\G|\.)((F?)((K|К)?(В\/О|В\/0|С\/П|x&gt;\=0|x≥0|x≥0|x⩾0|x\#0|x\!\=0|x&lt;&gt;0|x≠0|БП|ПП|L2|L3|x&lt;0|x\=0|L0|L1)))(\s|\t|$)',
+ GESHI_REPLACE => '\\4',
+ GESHI_MODIFIERS => '', GESHI_BEFORE => '\\1<span style="font-weight:lighter;font-size:90%;color:#404040;">\\3</span>', GESHI_AFTER => '\\7'
+ ),
+ 6 => array(
+ GESHI_SEARCH => '(\s|\t|^|\G|\.)(\d{2})(\s|\t|$)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '', GESHI_BEFORE => '\\1', GESHI_AFTER => '\\3'
+ ),
+ 7 => array(
+ GESHI_SEARCH => '(\s|\t|^|\G|\.)([\d\-A]\d\.)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '', GESHI_BEFORE => '\\1', GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'PARSER_CONTROL' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/mmix.php b/platform/www/vendor/geshi/geshi/src/geshi/mmix.php
new file mode 100644
index 0000000..21fc061
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/mmix.php
@@ -0,0 +1,191 @@
+<?php
+/*************************************************************************************
+ * mmix.php
+ * -------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2009 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/10/16
+ *
+ * MMIX Assembler language file for GeSHi.
+ *
+ * This is an implementation of the MMIX language as designed by Donald E. Knuth
+ *
+ * CHANGES
+ * -------
+ * 2004/08/05 (1.0.8.6)
+ * - First Release
+ *
+ * TODO (updated 2009/10/16)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'MMIX',
+ 'COMMENT_SINGLE' => array(1 => ';', 2 => '%'),
+ 'COMMENT_MULTI' => array(),
+ //Line address prefix suppression
+ 'COMMENT_REGEXP' => array(
+ 3 => "/^\s*(?!\s)[^\w].*$/m",
+ 4 => "/^\s*[0-9a-f]{12,16}+(?:\s+[0-9a-f]+(?:\.{3}[0-9a-f]{2,})?)?:/mi"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'NUMBERS' => array(
+ 1 => '(?<![\d\$#\w])[\da-fA-F]+(?!\w)',
+ 2 => '#[\da-fA-F]+',
+ 3 => '\$\d+'
+ ),
+ 'KEYWORDS' => array(
+ /*CPU*/
+ 1 => array(
+ '16ADDU','2ADDU','4ADDU','8ADDU','ADD','ADDU','AND','ANDN','ANDNH',
+ 'ANDNL','ANDNMH','ANDNML','BDIF','BEV','BN','BNN','BNP','BNZ','BOD',
+ 'BP','BZ','CMP','CMPU','CSEV','CSN','CSNN','CSNP','CSNZ','CSOD',
+ 'CSP','CSWAP','CSZ','DIV','DIVU','FADD','FCMP','FCMPE','FDIV',
+ 'FEQL','FEQLE','FINT','FIX','FIXU','FLOT','FLOTU','FMUL','FREM',
+ 'FSQRT','FSUB','FUN','FUNE','GET','GETA','GO','INCH','INCL','INCMH',
+ 'INCML','JMP','LDA','LDB','LDBU','LDHT','LDO','LDOU','LDSF','LDT',
+ 'LDTU','LDUNC','LDVTS','LDW','LDWU','MOR','MUL','MULU','MUX','MXOR',
+ 'NAND','NEG','NEGU','NOR','NXOR','ODIF','OR','ORH','ORL','ORMH',
+ 'ORML','ORN','PBEV','PBN','PBNN','PBNP','PBNZ','PBOD','PBP','PBZ',
+ 'POP','PREGO','PRELD','PREST','PUSHGO','PUSHJ','PUT','RESUME','SADD',
+ 'SAVE','SETH','SETL','SETMH','SETML','SFLOT','SFLOTU','SL','SLU',
+ 'SR','SRU','STB','STBU','STCO','STHT','STO','STOU','STSF','STT',
+ 'STTU','STUNC','STW','STWU','SUB','SUBU','SWYM','SYNC','SYNCD',
+ 'SYNCID','TDIF','TRAP','TRIP','UNSAVE','WDIF','XOR','ZSEV','ZSN',
+ 'ZSNN','ZSNP','ZSNZ','ZSOD','ZSP','ZSZ'
+ ),
+ 2 => array(
+ 'BSPEC','BYTE','ESPEC','GREG','IS','LOC','LOCAL','OCTA',
+ 'PREFIX','SET','TETRA','WYDE'
+ ),
+ /*registers*/
+ 3 => array(
+ 'rA','rB','rC','rD','rE','rF','rG','rH','rI','rJ','rK','rL','rM',
+ 'rN','rO','rP','rQ','rR','rS','rT','rU','rV','rW','rX','rY','rZ',
+ 'rBB','rTT','rWW','rXX','rYY','rZZ'
+ ),
+// /*Directive*/
+// 4 => array(
+// ),
+// /*Operands*/
+// 5 => array(
+// )
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '(', ')',
+ '+', '-', '*', '/', '%',
+ '.', ',', ';', ':',
+ '<<','>>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => false,
+ 3 => true,
+// 4 => false,
+// 5 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00007f; font-weight: bold;',
+ 2 => 'color: #0000ff; font-weight: bold;',
+ 3 => 'color: #00007f;',
+// 4 => 'color: #000000; font-weight: bold;',
+// 5 => 'color: #000000; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #666666; font-style: italic;',
+ 3 => 'color: #666666; font-style: italic;',
+ 4 => 'color: #adadad; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000ff;',
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #00007f;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+// 0 => 'color: #0000ff;',
+// 1 => 'color: #0000ff;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+// 4 => '',
+// 5 => ''
+ ),
+/*
+ 'NUMBERS' =>
+ GESHI_NUMBER_BIN_PREFIX_PERCENT |
+ GESHI_NUMBER_BIN_SUFFIX |
+ GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_HEX_SUFFIX |
+ GESHI_NUMBER_OCT_SUFFIX |
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+*/
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Hex numbers
+// 0 => /* */ "(?<=([\\s\\(\\)\\[\\],;.:+\\-\\/*]))(?:[0-9][0-9a-fA-F]{0,31}[hH]|0x[0-9a-fA-F]{1,32})(?=([\\s\\(\\)\\[\\],;.:+\\-\\/*]))",
+ //Binary numbers
+// 1 => "(?<=([\\s\\(\\)\\[\\],;.:+\\-\\/*]))[01]{1,64}[bB](?=([\\s\\(\\)\\[\\],;.:+\\-\\/*]))"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 8,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#>|^])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/modula2.php b/platform/www/vendor/geshi/geshi/src/geshi/modula2.php
new file mode 100644
index 0000000..850b9e6
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/modula2.php
@@ -0,0 +1,134 @@
+<?php
+/****************************************************************************
+ * modula2.php
+ * -----------
+ * Author: Benjamin Kowarsch (benjamin@modula2.net)
+ * Copyright: (c) 2009 Benjamin Kowarsch (benjamin@modula2.net)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/11/05
+ *
+ * Modula-2 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/05/22 (1.0.8.8)
+ * - First Release
+ *
+ * TODO (updated 2010/05/22)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Modula-2',
+ 'COMMENT_MULTI' => array('(*' => '*)'),
+ 'COMMENT_SINGLE' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array("''"),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array( /* reserved words */
+ 'AND', 'ARRAY', 'BEGIN', 'BY', 'CASE', 'CONST', 'DEFINITION',
+ 'DIV', 'DO', 'ELSE', 'ELSIF', 'END', 'EXIT', 'EXPORT', 'FOR',
+ 'FROM', 'IF', 'IMPLEMENTATION', 'IMPORT', 'IN', 'LOOP', 'MOD',
+ 'MODULE', 'NOT', 'OF', 'OR', 'POINTER', 'PROCEDURE', 'QUALIFIED',
+ 'RECORD', 'REPEAT', 'RETURN', 'SET', 'THEN', 'TO', 'TYPE',
+ 'UNTIL', 'VAR', 'WHILE', 'WITH'
+ ),
+ 2 => array( /* pervasive constants */
+ 'NIL', 'FALSE', 'TRUE',
+ ),
+ 3 => array( /* pervasive types */
+ 'BITSET', 'CAP', 'CHR', 'DEC', 'DISPOSE', 'EXCL', 'FLOAT',
+ 'HALT', 'HIGH', 'INC', 'INCL', 'MAX', 'MIN', 'NEW', 'ODD', 'ORD',
+ 'SIZE', 'TRUNC', 'VAL'
+ ),
+ 4 => array( /* pervasive functions and macros */
+ 'ABS', 'BOOLEAN', 'CARDINAL', 'CHAR', 'INTEGER',
+ 'LONGCARD', 'LONGINT', 'LONGREAL', 'PROC', 'REAL'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ ',', ':', '=', '+', '-', '*', '/', '#', '~'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #000066; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ 'HARD' => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0066ee;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => ''
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/modula3.php b/platform/www/vendor/geshi/geshi/src/geshi/modula3.php
new file mode 100644
index 0000000..1ba83f6
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/modula3.php
@@ -0,0 +1,133 @@
+<?php
+/*************************************************************************************
+ * modula3.php
+ * ----------
+ * Author: mbishop (mbishop@esoteriq.org)
+ * Copyright: (c) 2009 mbishop (mbishop@esoteriq.org)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/01/21
+ *
+ * Modula-3 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ *
+ * TODO
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Modula-3',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('(*' => '*)'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array("''"),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'AND', 'ANY', 'ARRAY', 'AS', 'BEGIN', 'BITS', 'BRANDED', 'BY', 'CASE',
+ 'CONST', 'DIV', 'DO', 'ELSE', 'ELSIF', 'END', 'EVAL', 'EXCEPT', 'EXCEPTION',
+ 'EXIT', 'EXPORTS', 'FINALLY', 'FOR', 'FROM', 'GENERIC', 'IF', 'IMPORT', 'IN',
+ 'INTERFACE', 'LOCK', 'LOOP', 'METHODS', 'MOD', 'MODULE', 'NOT', 'OBJECT', 'OF',
+ 'OR', 'OVERRIDES', 'PROCEDURE', 'RAISE', 'RAISES', 'READONLY', 'RECORD', 'REF',
+ 'REPEAT', 'RETURN', 'REVEAL', 'ROOT', 'SET', 'THEN', 'TO', 'TRY', 'TYPE', 'TYPECASE',
+ 'UNSAFE', 'UNTIL', 'UNTRACED', 'VALUE', 'VAR', 'WHILE', 'WITH'
+ ),
+ 2 => array(
+ 'NIL', 'NULL', 'FALSE', 'TRUE',
+ ),
+ 3 => array(
+ 'ABS','ADR','ADRSIZE','BITSIZE','BYTESIZE','CEILING','DEC','DISPOSE',
+ 'EXTENDED','FIRST','FLOAT','FLOOR','INC','ISTYPE','LAST','LOOPHOLE','MAX','MIN',
+ 'NARROW','NEW','NUMBER','ORD','ROUND','SUBARRAY','TRUNC','TYPECODE', 'VAL'
+ ),
+ 4 => array(
+ 'ADDRESS', 'BOOLEAN', 'CARDINAL', 'CHAR', 'INTEGER',
+ 'LONGREAL', 'MUTEX', 'REAL', 'REFANY', 'TEXT'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ ',', ':', '=', '+', '-', '*', '/', '#'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #000066; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ 'HARD' => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0066ee;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/mpasm.php b/platform/www/vendor/geshi/geshi/src/geshi/mpasm.php
new file mode 100644
index 0000000..42c85a1
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/mpasm.php
@@ -0,0 +1,162 @@
+<?php
+/*************************************************************************************
+ * mpasm.php
+ * ---------
+ * Author: Bakalex (bakalex@gmail.com)
+ * Copyright: (c) 2004 Bakalex, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/12/6
+ *
+ * Microchip Assembler language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2005/01/29 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2005/12/6)
+ * -------------------------
+ *
+ * For the moment, i've only added PIC16C6X registers. We need more (PIC16F/C7x/8x,
+ * PIC10, PIC18 and dsPIC registers).
+ * Must take a look to dsPIC instructions.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Microchip Assembler',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /*Directive Language*/
+ 4 => array(
+ 'CONSTANT', '#DEFINE', 'END', 'EQU', 'ERROR', 'ERROR-LEVEL', '#INCLUDE', 'LIST',
+ 'MESSG', 'NOLIST', 'ORG', 'PAGE', 'PROCESSOR', 'RADIX', 'SET', 'SPACE', 'SUBTITLE',
+ 'TITLE', '#UNDEFINE', 'VARIABLE', 'ELSE', 'ENDIF', 'ENDW', 'IF', 'IFDEF', 'IFNDEF',
+ 'WHILE', '__BADRAM', 'CBLOCK', '__CONFIG', 'DA', 'DATA', 'DB', 'DE', 'DT', 'DW',
+ 'ENDC', 'FILL', '__IDLOCS', '__MAXRAM', 'RES', 'ENDM', 'EXITM', 'EXPAND', 'LOCAL',
+ 'MACRO', 'NOEXPAND', 'BANKISEL', 'BANKSEL', 'CODE', 'EXTERN', 'GLOBAL', 'IDATA',
+ 'PAGESEL', 'UDATA', 'UDATA_ACS', 'UDATA_OVR', 'UDATA_SHR'
+ ),
+ /* 12&14-bit Specific Instruction Set*/
+ 1 => array(
+ 'andlw', 'call', 'clrwdt', 'goto', 'iorlw', 'movlw', 'option', 'retlw', 'sleep',
+ 'tris', 'xorlw', 'addwf', 'andwf', 'clrf', 'clrw', 'comf', 'decf', 'decfsz', 'incf',
+ 'incfsz', 'iorwf', 'movf', 'nop', 'rlf', 'rrf', 'subwf', 'swapf', 'xorwf',
+ 'bcf', 'bsf', 'btfsc', 'btfss',
+ 'addlw', 'retfie', 'return', 'sublw', 'addcf', 'adddcf', 'b', 'bc', 'bdc',
+ 'bnc', 'bndc', 'bnz', 'bz', 'clrc', 'clrdc', 'clrz', 'lcall', 'lgoto', 'movfw',
+ 'negf', 'setc', 'setdc', 'setz', 'skpc', 'skpdc', 'skpnc', 'skpndc', 'skpnz', 'skpz',
+ 'subcf', 'subdcf', 'tstf'
+ ),
+ /* 16-bit Specific Instructiob Set */
+ 2 => array (
+ 'movfp', 'movlb', 'movlp', 'movpf', 'movwf', 'tablrd', 'tablwt', 'tlrd', 'tlwt',
+ 'addwfc', 'daw', 'mullw', 'negw', 'rlcf', 'rlncf', 'rrcf', 'rrncf', 'setf', 'subwfb',
+ 'btg', 'cpfseq', 'cpfsgt', 'cpfslt', 'dcfsnz', 'infsnz', 'tstfsz', 'lfsr', 'bnn',
+ 'bnov', 'bra', 'pop', 'push', 'rcall', 'reset'
+ ),
+ /* Registers */
+ 3 => array(
+ 'INDF', 'TMR0', 'PCL', 'STATUS', 'FSR', 'PORTA', 'PORTB', 'PORTC', 'PORTD', 'PORTE',
+ 'PCLATH', 'INTCON', 'PIR1', 'PIR2', 'TMR1L', 'TMR1H', 'T1CON', 'TMR2', 'T2CON', 'TMR2L',
+ 'TMR2H', 'TMR0H', 'TMR0L', 'SSPBUF', 'SSPCON', 'CCPR1L', 'CCPR1H', 'CCP1CON', 'RCSTA',
+ 'TXREG', 'RCREG', 'CCPR2L', 'CCPR2H', 'CCP2CON', 'OPTION', 'TRISA', 'TRISB', 'TRISC',
+ 'TRISD', 'TRISE', 'PIE2', 'PIE1', 'PR2', 'SSPADD', 'SSPSTAT', 'TXSTA', 'SPBRG'
+ ),
+ /*Operands*/
+ 5 => array(
+ 'high','low'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '(', ')'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00007f;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #007f00;',
+ 4 => 'color: #46aa03; font-weight:bold;',
+ 5 => 'color: #7f0000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #ff0000;',
+ 1 => 'color: #ff0000;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Hex numbers
+ 0 => '[0-9a-fA-F]{1,32}[hH]',
+ //Binary numbers
+ 1 => '[01]{1,64}[bB]'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/mxml.php b/platform/www/vendor/geshi/geshi/src/geshi/mxml.php
new file mode 100644
index 0000000..afc0769
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/mxml.php
@@ -0,0 +1,143 @@
+<?php
+/*************************************************************************************
+ * mxml.php
+ * -------
+ * Author: David Spurr
+ * Copyright: (c) 2007 David Spurr (http://www.defusion.org.uk/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/10/04
+ *
+ * MXML language file for GeSHi. Based on the XML file by Nigel McNie
+ *
+ * CHANGES
+ * -------
+ * 2007/10/04 (1.0.7.22)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'MXML',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('<!--' => '-->'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ 0 => 'color: #00bbdd;',
+ 1 => 'color: #ddbb00;',
+ 2 => 'color: #339933;',
+ 3 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'font-weight: bold; color: black;',
+ 1 => 'color: #7400FF;',
+ 2 => 'color: #7400FF;'
+ )
+ ),
+ 'URLS' => array(
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ // xml declaration
+ 0 => array(
+ GESHI_SEARCH => '(&lt;[\/?|(\?xml)]?[a-z0-9_\-:]*(\?&gt;))',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ // opening tags
+ 1 => array(
+ GESHI_SEARCH => '(&lt;\/?[a-z]+:[a-z]+)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ // closing tags
+ 2 => array(
+ GESHI_SEARCH => '(\/?&gt;)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<!DOCTYPE' => '>'
+ ),
+ 1 => array(
+ '&' => ';'
+ ),
+ 2 => array(
+ //'<![CDATA[' => ']]>'
+ '<mx:Script>' => '</mx:Script>'
+ ),
+ 3 => array(
+ '<' => '>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => false,
+ 1 => false,
+ 2 => false,
+ 3 => true
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/mysql.php b/platform/www/vendor/geshi/geshi/src/geshi/mysql.php
new file mode 100644
index 0000000..afe8684
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/mysql.php
@@ -0,0 +1,472 @@
+<?php
+/*************************************************************************************
+ * mysql.php
+ * ---------
+ * Author: Marjolein Katsma (marjolein.is.back@gmail.com)
+ * Copyright: (c) 2008 Marjolein Katsma (http://blog.marjoleinkatsma.com/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008-12-12
+ *
+ * MySQL language file for GeSHi.
+ *
+ * Based on original MySQL language file by Carl Fürstenberg (2004); brought
+ * up-to-date for current MySQL versions, and with more classes for different
+ * types of keywords; several minor errors were corrected as well.
+ *
+ * Some "classes" have two groups here: this is to allow for the fact that some
+ * keywords in MySQL have a double function: many of those are either a function
+ * (must be immediately followed by an opening bracket) or some other keyword:
+ * so they can be distinguished by the presence (or not) of that opening bracket.
+ * (An immediately following opening bracket is a default rule for functions in
+ * MySQL, though this may be overridden; because it's only a default, we use a
+ * regex lookahead only where necessary to distinguish homonyms, not generally
+ * to match any function.)
+ * Other keywords with double usage cannot be distinguished and are classified
+ * in the "Mix" category.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'MySQL',
+ //'COMMENT_SINGLE' => array(1 =>'--', 2 => '#'), // '--' MUST be folowed by whitespace,not necessarily a space
+ 'COMMENT_SINGLE' => array(
+ 1 =>'-- ',
+ 2 => '#'
+ ),
+ 'COMMENT_REGEXP' => array(
+ 1 => "/(?:--\s).*?$/", // double dash followed by any whitespace
+ ),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE, // @@@ would be nice if this could be defined per group!
+ 'QUOTEMARKS' => array("'", '"', '`'),
+ 'ESCAPE_CHAR' => '\\', // by default only, can be specified
+ 'ESCAPE_REGEXP' => array(
+ 1 => "/[_%]/", // search wildcards
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_OCT_PREFIX |
+ GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_SCI_SHORT |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ // Mix: statement keywords and keywords that don't fit in any other
+ // category, or have multiple usage/meanings
+ 'ACTION','ADD','AFTER','ALGORITHM','ALL','ALTER','ANALYZE','ANY',
+ 'ASC','AS','BDB','BEGIN','BERKELEYDB','BINARY','BTREE','CALL',
+ 'CASCADED','CASCADE','CHAIN','CHANGE','CHECK','COLUMNS','COLUMN',
+ 'COMMENT','COMMIT','COMMITTED','CONSTRAINT','CONTAINS SQL',
+ 'CONSISTENT','CONVERT','CREATE','CROSS','DATA','DATABASES',
+ 'DECLARE','DEFINER','DELAYED','DELETE','DESCRIBE','DESC',
+ 'DETERMINISTIC','DISABLE','DISCARD','DISTINCTROW','DISTINCT','DO',
+ 'DROP','DUMPFILE','DUPLICATE KEY','ENABLE','ENCLOSED BY','ENGINE',
+ 'ERRORS','ESCAPED BY','EXISTS','EXPLAIN','EXTENDED','FIELDS',
+ 'FIRST','FOR EACH ROW','FORCE','FOREIGN KEY','FROM','FULL',
+ 'FUNCTION','GLOBAL','GRANT','GROUP BY','HANDLER','HASH','HAVING',
+ 'HELP','HIGH_PRIORITY','IF NOT EXISTS','IGNORE','IMPORT','INDEX',
+ 'INFILE','INNER','INNODB','INOUT','INTO','INVOKER',
+ 'ISOLATION LEVEL','JOIN','KEYS','KEY','KILL','LANGUAGE SQL','LAST',
+ 'LIMIT','LINES','LOAD','LOCAL','LOCK','LOW_PRIORITY',
+ 'MASTER_SERVER_ID','MATCH','MERGE','MIDDLEINT','MODIFIES SQL DATA',
+ 'MODIFY','MRG_MYISAM','NATURAL','NEXT','NO SQL','NO','ON',
+ 'OPTIMIZE','OPTIONALLY','OPTION','ORDER BY','OUTER','OUTFILE','OUT',
+ 'PARTIAL','PARTITION','PREV','PRIMARY KEY','PRIVILEGES','PROCEDURE',
+ 'PURGE','QUICK','READS SQL DATA','READ','REFERENCES','RELEASE',
+ 'RENAME','REORGANIZE','REPEATABLE','REQUIRE','RESTRICT','RETURNS',
+ 'REVOKE','ROLLBACK','ROUTINE','RTREE','SAVEPOINT','SELECT',
+ 'SERIALIZABLE','SESSION','SET','SHARE MODE','SHOW','SIMPLE',
+ 'SNAPSHOT','SOME','SONAME','SQL SECURITY','SQL_BIG_RESULT',
+ 'SQL_BUFFER_RESULT','SQL_CACHE','SQL_CALC_FOUND_ROWS',
+ 'SQL_NO_CACHE','SQL_SMALL_RESULT','SSL','START','STARTING BY',
+ 'STATUS','STRAIGHT_JOIN','STRIPED','TABLESPACE','TABLES','TABLE',
+ 'TEMPORARY','TEMPTABLE','TERMINATED BY','TO','TRANSACTIONS',
+ 'TRANSACTION','TRIGGER','TYPES','TYPE','UNCOMMITTED','UNDEFINED',
+ 'UNION','UNLOCK_TABLES','UPDATE','USAGE','USE','USER_RESOURCES',
+ 'USING','VALUES','VALUE','VIEW','WARNINGS','WHERE','WITH ROLLUP',
+ 'WITH','WORK','WRITE',
+ ),
+ 2 => array( //No ( must follow
+ // Mix: statement keywords distinguished from functions by the same name
+ "CURRENT_USER", "DATABASE", "IN", "INSERT", "DEFAULT", "REPLACE", "SCHEMA", "TRUNCATE"
+ ),
+ 3 => array(
+ // Values (Constants)
+ 'FALSE','NULL','TRUE',
+ ),
+ 4 => array(
+ // Column Data Types
+ 'BIGINT','BIT','BLOB','BOOLEAN','BOOL','CHARACTER VARYING',
+ 'CHAR VARYING','DATETIME','DECIMAL','DEC','DOUBLE PRECISION',
+ 'DOUBLE','ENUM','FIXED','FLOAT','GEOMETRYCOLLECTION','GEOMETRY',
+ 'INTEGER','INT','LINESTRING','LONGBLOB','LONGTEXT','MEDIUMBLOB',
+ 'MEDIUMINT','MEDIUMTEXT','MULTIPOINT','MULTILINESTRING',
+ 'MULTIPOLYGON','NATIONAL CHARACTER','NATIONAL CHARACTER VARYING',
+ 'NATIONAL CHAR VARYING','NATIONAL VARCHAR','NCHAR VARCHAR','NCHAR',
+ 'NUMERIC','POINT','POLYGON','REAL','SERIAL',
+ 'SMALLINT','TEXT','TIMESTAMP','TINYBLOB','TINYINT',
+ 'TINYTEXT','VARBINARY','VARCHARACTER','VARCHAR',
+ ),
+ 5 => array( //No ( must follow
+ // Column data types distinguished from functions by the same name
+ "CHAR", "DATE", "TIME"
+ ),
+ 6 => array(
+ // Table, Column & Index Attributes
+ 'AUTO_INCREMENT','AVG_ROW_LENGTH','BOTH','CHECKSUM','CONNECTION',
+ 'DATA DIRECTORY','DEFAULT NULL','DELAY_KEY_WRITE','FULLTEXT',
+ 'INDEX DIRECTORY','INSERT_METHOD','LEADING','MAX_ROWS','MIN_ROWS',
+ 'NOT NULL','PACK_KEYS','ROW_FORMAT','SERIAL DEFAULT VALUE','SIGNED',
+ 'SPATIAL','TRAILING','UNIQUE','UNSIGNED','ZEROFILL'
+ ),
+ 7 => array( //No ( must follow
+ // Column attribute distinguished from function by the same name
+ "CHARSET"
+ ),
+ 8 => array(
+ // Date and Time Unit Specifiers
+ 'DAY_HOUR','DAY_MICROSECOND','DAY_MINUTE','DAY_SECOND',
+ 'HOUR_MICROSECOND','HOUR_MINUTE','HOUR_SECOND',
+ 'MINUTE_MICROSECOND','MINUTE_SECOND',
+ 'SECOND_MICROSECOND','YEAR_MONTH'
+ ),
+ 9 => array( //No ( must follow
+ // Date-time unit specifiers distinguished from functions by the same name
+ "DAY", "HOUR", "MICROSECOND", "MINUTE", "MONTH", "QUARTER", "SECOND", "WEEK", "YEAR"
+ ),
+ 10 => array(
+ // Operators (see also Symbols)
+ 'AND','BETWEEN','CHARACTER SET','COLLATE','DIV','IS NOT NULL',
+ 'IS NOT','IS NULL','IS','LIKE','NOT','OFFSET','OR','REGEXP','RLIKE',
+ 'SOUNDS LIKE','XOR'
+ ),
+ 11 => array( //No ( must follow
+ // Operator distinghuished from function by the same name
+ "INTERVAL"
+ ),
+ 12 => array(
+ // Control Flow (functions)
+ 'CASE','ELSE','END','IFNULL','IF','NULLIF','THEN','WHEN',
+ ),
+ 13 => array(
+ // String Functions
+ 'ASCII','BIN','BIT_LENGTH','CHAR_LENGTH','CHARACTER_LENGTH',
+ 'CONCAT_WS','CONCAT','ELT','EXPORT_SET','FIELD',
+ 'FIND_IN_SET','FORMAT','HEX','INSTR','LCASE','LEFT','LENGTH',
+ 'LOAD_FILE','LOCATE','LOWER','LPAD','LTRIM','MAKE_SET','MID',
+ 'OCTET_LENGTH','ORD','POSITION','QUOTE','REPEAT','REVERSE',
+ 'RIGHT','RPAD','RTRIM','SOUNDEX','SPACE','STRCMP','SUBSTRING_INDEX',
+ 'SUBSTRING','TRIM','UCASE','UNHEX','UPPER',
+ ),
+ 14 => array( //A ( must follow
+ // String functions distinguished from other keywords by the same name
+ "INSERT", "REPLACE", "CHAR"
+ ),
+ 15 => array(
+ // Numeric Functions
+ 'ABS','ACOS','ASIN','ATAN2','ATAN','CEILING','CEIL',
+ 'CONV','COS','COT','CRC32','DEGREES','EXP','FLOOR','LN','LOG10',
+ 'LOG2','LOG','MOD','OCT','PI','POWER','POW','RADIANS','RAND',
+ 'ROUND','SIGN','SIN','SQRT','TAN',
+ ),
+ 16 => array( //A ( must follow
+ // Numeric function distinguished from other keyword by the same name
+ "TRUNCATE"
+ ),
+ 17 => array(
+ // Date and Time Functions
+ 'ADDDATE','ADDTIME','CONVERT_TZ','CURDATE','CURRENT_DATE',
+ 'CURRENT_TIME','CURRENT_TIMESTAMP','CURTIME','DATE_ADD',
+ 'DATE_FORMAT','DATE_SUB','DATEDIFF','DAYNAME','DAYOFMONTH',
+ 'DAYOFWEEK','DAYOFYEAR','EXTRACT','FROM_DAYS','FROM_UNIXTIME',
+ 'GET_FORMAT','LAST_DAY','LOCALTIME','LOCALTIMESTAMP','MAKEDATE',
+ 'MAKETIME','MONTHNAME','NOW','PERIOD_ADD',
+ 'PERIOD_DIFF','SEC_TO_TIME','STR_TO_DATE','SUBDATE','SUBTIME',
+ 'SYSDATE','TIME_FORMAT','TIME_TO_SEC',
+ 'TIMESTAMPADD','TIMESTAMPDIFF','TO_DAYS',
+ 'UNIX_TIMESTAMP','UTC_DATE','UTC_TIME','UTC_TIMESTAMP','WEEKDAY',
+ 'WEEKOFYEAR','YEARWEEK',
+ ),
+ 18 => array( //A ( must follow
+ // Date-time functions distinguished from other keywords by the same name
+ "DATE", "DAY", "HOUR", "MICROSECOND", "MINUTE", "MONTH", "QUARTER",
+ "SECOND", "TIME", "WEEK", "YEAR"
+ ),
+ 19 => array(
+ // Comparison Functions
+ 'COALESCE','GREATEST','ISNULL','LEAST',
+ ),
+ 20 => array( //A ( must follow
+ // Comparison functions distinguished from other keywords by the same name
+ "IN", "INTERVAL"
+ ),
+ 21 => array(
+ // Encryption and Compression Functions
+ 'AES_DECRYPT','AES_ENCRYPT','COMPRESS','DECODE','DES_DECRYPT',
+ 'DES_ENCRYPT','ENCODE','ENCRYPT','MD5','OLD_PASSWORD','PASSWORD',
+ 'SHA1','SHA','UNCOMPRESS','UNCOMPRESSED_LENGTH',
+ ),
+ 22 => array(
+ // GROUP BY (aggregate) Functions
+ 'AVG','BIT_AND','BIT_OR','BIT_XOR','COUNT','GROUP_CONCAT',
+ 'MAX','MIN','STDDEV_POP','STDDEV_SAMP','STDDEV','STD','SUM',
+ 'VAR_POP','VAR_SAMP','VARIANCE',
+ ),
+ 23 => array(
+ // Information Functions
+ 'BENCHMARK','COERCIBILITY','COLLATION','CONNECTION_ID',
+ 'FOUND_ROWS','LAST_INSERT_ID','ROW_COUNT',
+ 'SESSION_USER','SYSTEM_USER','USER','VERSION',
+ ),
+ 24 => array( //A ( must follow
+ // Information functions distinguished from other keywords by the same name
+ "CURRENT_USER", "DATABASE", "SCHEMA", "CHARSET"
+ ),
+ 25 => array(
+ // Miscellaneous Functions
+ 'ExtractValue','BIT_COUNT','GET_LOCK','INET_ATON','INET_NTOA',
+ 'IS_FREE_LOCK','IS_USED_LOCK','MASTER_POS_WAIT','NAME_CONST',
+ 'RELEASE_LOCK','SLEEP','UpdateXML','UUID',
+ ),
+ 26 => array( //A ( must follow
+ // Miscellaneous function distinguished from other keyword by the same name
+ "DEFAULT"
+ ),
+ 27 => array(
+ // Geometry Functions
+ 'Area','AsBinary','AsText','AsWKB','AsWKT','Boundary','Buffer',
+ 'Centroid','Contains','ConvexHull','Crosses',
+ 'Difference','Dimension','Disjoint','Distance',
+ 'EndPoint','Envelope','Equals','ExteriorRing',
+ 'GLength','GeomCollFromText','GeomCollFromWKB','GeomFromText',
+ 'GeomFromWKB','GeometryCollectionFromText',
+ 'GeometryCollectionFromWKB','GeometryFromText','GeometryFromWKB',
+ 'GeometryN','GeometryType',
+ 'InteriorRingN','Intersection','Intersects','IsClosed','IsEmpty',
+ 'IsRing','IsSimple',
+ 'LineFromText','LineFromWKB','LineStringFromText',
+ 'LineStringFromWKB',
+ 'MBRContains','MBRDisjoint','MBREqual','MBRIntersects',
+ 'MBROverlaps','MBRTouches','MBRWithin','MLineFromText',
+ 'MLineFromWKB','MPointFromText','MPointFromWKB','MPolyFromText',
+ 'MPolyFromWKB','MultiLineStringFromText','MultiLineStringFromWKB',
+ 'MultiPointFromText','MultiPointFromWKB','MultiPolygonFromText',
+ 'MultiPolygonFromWKB',
+ 'NumGeometries','NumInteriorRings','NumPoints',
+ 'Overlaps',
+ 'PointFromText','PointFromWKB','PointN','PointOnSurface',
+ 'PolyFromText','PolyFromWKB','PolygonFromText','PolygonFromWKB',
+ 'Related','SRID','StartPoint','SymDifference',
+ 'Touches',
+ 'Union',
+ 'Within',
+ 'X',
+ 'Y',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ /* Operators */
+ '=', ':=', // assignment operators
+ '||', '&&', '!', // locical operators
+ '=', '<=>', '>=', '>', '<=', '<', '<>', '!=', // comparison operators
+ '|', '&', '^', '~', '<<', '>>', // bitwise operators
+ '-', '+', '*', '/', '%', // numerical operators
+ ),
+ 2 => array(
+ /* Other syntactical symbols */
+ '(', ')',
+ ',', ';',
+ ),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ 8 => false,
+ 9 => false,
+ 10 => false,
+ 11 => false,
+ 12 => false,
+ 13 => false,
+ 14 => false,
+ 15 => false,
+ 16 => false,
+ 17 => false,
+ 18 => false,
+ 19 => false,
+ 20 => false,
+ 21 => false,
+ 22 => false,
+ 23 => false,
+ 24 => false,
+ 25 => false,
+ 26 => false,
+ 27 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #990099; font-weight: bold;', // mix
+ 2 => 'color: #990099; font-weight: bold;', // mix
+ 3 => 'color: #9900FF; font-weight: bold;', // constants
+ 4 => 'color: #999900; font-weight: bold;', // column data types
+ 5 => 'color: #999900; font-weight: bold;', // column data types
+ 6 => 'color: #FF9900; font-weight: bold;', // attributes
+ 7 => 'color: #FF9900; font-weight: bold;', // attributes
+ 8 => 'color: #9900FF; font-weight: bold;', // date-time units
+ 9 => 'color: #9900FF; font-weight: bold;', // date-time units
+
+ 10 => 'color: #CC0099; font-weight: bold;', // operators
+ 11 => 'color: #CC0099; font-weight: bold;', // operators
+
+ 12 => 'color: #009900;', // control flow (functions)
+ 13 => 'color: #000099;', // string functions
+ 14 => 'color: #000099;', // string functions
+ 15 => 'color: #000099;', // numeric functions
+ 16 => 'color: #000099;', // numeric functions
+ 17 => 'color: #000099;', // date-time functions
+ 18 => 'color: #000099;', // date-time functions
+ 19 => 'color: #000099;', // comparison functions
+ 20 => 'color: #000099;', // comparison functions
+ 21 => 'color: #000099;', // encryption functions
+ 22 => 'color: #000099;', // aggregate functions
+ 23 => 'color: #000099;', // information functions
+ 24 => 'color: #000099;', // information functions
+ 25 => 'color: #000099;', // miscellaneous functions
+ 26 => 'color: #000099;', // miscellaneous functions
+ 27 => 'color: #00CC00;', // geometry functions
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #808000; font-style: italic;',
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #004000; font-weight: bold;',
+ 1 => 'color: #008080; font-weight: bold;' // search wildcards
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #FF00FF;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #008080;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #CC0099;', // operators
+ 2 => 'color: #000033;', // syntax
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'https://www.oracle.com/search/results?cat=mysql&amp;Ntk=SI-ALL5&amp;Ntt={FNAME}',
+ 2 => 'https://www.oracle.com/search/results?cat=mysql&amp;Ntk=SI-ALL5&amp;Ntt={FNAME}',
+ 3 => 'https://www.oracle.com/search/results?cat=mysql&amp;Ntk=SI-ALL5&amp;Ntt={FNAME}',
+ 4 => 'https://www.oracle.com/search/results?cat=mysql&amp;Ntk=SI-ALL5&amp;Ntt={FNAME}',
+ 5 => 'https://www.oracle.com/search/results?cat=mysql&amp;Ntk=SI-ALL5&amp;Ntt={FNAME}',
+ 6 => 'https://www.oracle.com/search/results?cat=mysql&amp;Ntk=SI-ALL5&amp;Ntt={FNAME}',
+ 7 => 'https://www.oracle.com/search/results?cat=mysql&amp;Ntk=SI-ALL5&amp;Ntt={FNAME}',
+ 8 => 'https://www.oracle.com/search/results?cat=mysql&amp;Ntk=SI-ALL5&amp;Ntt={FNAME}',
+ 9 => 'https://www.oracle.com/search/results?cat=mysql&amp;Ntk=SI-ALL5&amp;Ntt={FNAME}',
+
+ 10 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/non-typed-operators.html',
+ 11 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/non-typed-operators.html',
+
+ 12 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/control-flow-functions.html',
+ 13 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/string-functions.html',
+ 14 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/string-functions.html',
+ 15 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/numeric-functions.html',
+ 16 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/numeric-functions.html',
+ 17 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/date-and-time-functions.html',
+ 18 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/date-and-time-functions.html',
+ 19 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/comparison-operators.html',
+ 20 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/comparison-operators.html',
+ 21 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/encryption-functions.html',
+ 22 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/group-by-functions-and-modifiers.html',
+ 23 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/information-functions.html',
+ 24 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/information-functions.html',
+ 25 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/func-op-summary-ref.html',
+ 26 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/func-op-summary-ref.html',
+ 27 => 'http://dev.mysql.com/doc/refman/%35%2E%31/en/analysing-spatial-information.html',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 2 => array(
+ 'DISALLOWED_AFTER' => '(?![\(\w])'
+ ),
+ 5 => array(
+ 'DISALLOWED_AFTER' => '(?![\(\w])'
+ ),
+ 7 => array(
+ 'DISALLOWED_AFTER' => '(?![\(\w])'
+ ),
+ 9 => array(
+ 'DISALLOWED_AFTER' => '(?![\(\w])'
+ ),
+ 11 => array(
+ 'DISALLOWED_AFTER' => '(?![\(\w])'
+ ),
+
+ 14 => array(
+ 'DISALLOWED_AFTER' => '(?=\()'
+ ),
+ 16 => array(
+ 'DISALLOWED_AFTER' => '(?=\()'
+ ),
+ 18 => array(
+ 'DISALLOWED_AFTER' => '(?=\()'
+ ),
+ 20 => array(
+ 'DISALLOWED_AFTER' => '(?=\()'
+ ),
+ 24 => array(
+ 'DISALLOWED_AFTER' => '(?=\()'
+ ),
+ 26 => array(
+ 'DISALLOWED_AFTER' => '(?=\()'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/nagios.php b/platform/www/vendor/geshi/geshi/src/geshi/nagios.php
new file mode 100644
index 0000000..2358598
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/nagios.php
@@ -0,0 +1,223 @@
+<?php
+/*************************************************************************************
+ * nagios.php
+ * --------
+ * Author: Albéric de Pertat <alberic@depertat.net>
+ * Copyright: (c) 2012 Albéric de Pertat (https://github.com/adepertat/geshi-nagios)
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/01/19
+ *
+ * Nagios language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2012/01/19 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2012/01/19)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Nagios',
+ 'COMMENT_SINGLE' => array(1 => ';', 2 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'HARDQUOTE' => array("'", "'"),
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\'',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'define'
+ ),
+ 2 => array(
+ 'command', 'contact', 'contactgroup', 'host', 'hostdependency',
+ 'hostescalation', 'hostextinfo', 'hostgroup', 'service',
+ 'servicedependency', 'serviceescalation',
+ 'serviceextinfo', 'servicegroup', 'timeperiod'
+ ),
+ 3 => array(
+ 'active_checks_enabled', 'passive_checks_enabled', 'alias',
+ 'display_name', 'host_name', 'address', 'hostgroups', 'parents',
+ 'hostgroup_members', 'members', 'service_description',
+ 'servicegroups', 'is_volatile', 'servicegroup_name',
+ 'servicegroup_members', 'contact_name', 'contactgroups', 'email',
+ 'pager', 'can_submit_commands', 'contactgroup_name',
+ 'contactgroup_members', 'host_notifications_enabled',
+ 'service_notifications_enabled', 'host_notification_period',
+ 'service_notification_period', 'host_notification_options',
+ 'service_notification_options', 'host_notification_commands',
+ 'service_notification_commands', 'check_command',
+ 'check_freshness', 'check_interval', 'check_period', 'contacts',
+ 'contact_groups', 'event_handler', 'event_handler_enabled',
+ 'flap_detection_enabled', 'flap_detection_options',
+ 'freshness_threshold', 'initial_state', 'low_flap_threshold',
+ 'high_flap_threshold', 'max_check_attempts',
+ 'notification_interval', 'first_notification_delay',
+ 'notification_period', 'notification_options',
+ 'notifications_enabled', 'stalking_options', 'notes', 'notes_url',
+ 'action_url', 'icon_image', 'icon_image_alt', 'vrml_image',
+ 'statusmap_image', '2d_coords', '3d_coords', 'obsess_over_host',
+ 'obsess_over_hostver_service', 'process_perf_data',
+ 'retain_status_information', 'retain_nonstatus_information',
+ 'retry_interval', 'register', 'use', 'name', 'timeperiod_name',
+ 'exclude', 'command_name', 'command_line', 'dependent_host_name',
+ 'dependent_hostgroup_name', 'dependent_service_description',
+ 'inherits_parent', 'execution_failure_criteria',
+ 'notification_failure_criteria', 'dependency_period',
+ 'first_notification', 'last_notification', 'escalation_period',
+ 'escalation_options'
+ ),
+ 4 => array(
+ 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday',
+ 'sunday', 'january', 'february', 'march', 'april', 'may', 'june',
+ 'july', 'august', 'september', 'october', 'november', 'december',
+ 'day'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '{', '}', ',', '+'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'font-weight:bold;color:#FFDCA8;',
+ 2 => 'font-weight:bold;color #FFA858;',
+ 3 => 'font-weight:bold;color:#00C0C0;',
+ 4 => 'font-weight:bold;color:#C0C0FF;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'font-weight:bold;color:#000000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => ''
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #AAAAAA; font-style: italic;',
+ 1 => 'color: #AAAAAA; font-style: italic;',
+ 2 => 'color: #AAAAAA; font-style: italic;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #660066;',
+ 'HARD' => 'color: #660066;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'font-weight:bold;color:#808080;',
+ 1 => 'font-weight:bold;color:#000080;',
+ 2 => 'font-weight:bold;color:red;',
+ 3 => 'font-weight:bold;color:#808000;',
+ 4 => 'font-weight:bold;color:blue;',
+ 5 => 'font-weight:bold;color:#C0FFC0;',
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ )
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '\\'
+ ),
+ 'REGEXPS' => array(
+ // Custom macros
+ 0 => array(
+ GESHI_SEARCH => '(\$[a-zA-Z_]+\$)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '',
+ ),
+ // Custom macro definitions
+ 1 => array(
+ GESHI_SEARCH => '(\A|\s)(_[a-zA-Z_]+)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '',
+ ),
+ // $USERxx$
+ 2 => array(
+ GESHI_SEARCH => '(\$USER[0-9]+\$)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '',
+ ),
+ // $ARGxx$
+ 3 => array(
+ GESHI_SEARCH => '(\$ARG[1-9]\$)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '',
+ ),
+ // register 0
+ 4 => array(
+ GESHI_SEARCH => '(\bregister[\\x20\\t]+[01])',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '',
+ ),
+ // use
+ 5 => array(
+ GESHI_SEARCH => '(use[\\x20\\t]+[^\\x20\\t]+)([\\x20\\t]*[$;#])',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '',
+ ),
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => false
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'NUMBERS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/netrexx.php b/platform/www/vendor/geshi/geshi/src/geshi/netrexx.php
new file mode 100644
index 0000000..a6d444b
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/netrexx.php
@@ -0,0 +1,161 @@
+<?php
+/*************************************************************************************
+ * netrexx.php
+ * ---------------------------------
+ * Author: Jon Wolfers (sahananda@windhorse.biz)
+ * Contributors:
+ * - Walter Pachl (pachl@chello.at)
+ * Copyright: (c) 2008 Jon Wolfers, (c) 2012 Walter Pachl
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/01/07
+ *
+ * NetRexx language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2012/07/29 (1.0.0)
+ * - tried to get it syntactically right
+ *
+ * TODO (updated 2012/07/29)
+ * -------------------------
+ * - Get it working on rosettacode.org
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'NetRexx',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'class', 'do', 'exit', 'if', 'import', 'iterate', 'leave',
+ 'loop', 'nop', 'numeric', 'package', 'parse', 'properties',
+ 'return', 'say', 'select', 'signal', 'trace'
+ ),
+ 2 => array(
+ 'abstract', 'adapter', 'all', 'ask', 'binary', 'case',
+ 'constant', 'dependent', 'deprecated', 'extends', 'final',
+ 'implements', 'inheritable', 'interface', 'label', 'methods',
+ 'native', 'off', 'private', 'protect', 'public', 'results',
+ 'returns', 'shared', 'signals', 'source', 'static',
+ 'transient', 'unused', 'uses', 'version', 'volatile'
+ ),
+ 3 => array(
+ 'catch', 'else', 'end', 'finally', 'otherwise', 'then', 'when'
+ ),
+ 4 => array(
+ 'rc', 'result', 'self', 'sigl', 'super'
+ ),
+ 5 => array(
+ 'placeholderforoorexxdirectives'
+ ),
+ 6 => array(
+ 'abbrev', 'abs', 'b2x', 'c2d', 'c2x', 'center', 'centre',
+ 'changestr', 'compare', 'copies', 'copyindexed', 'countstr',
+ 'd2c', 'd2x', 'datatype', 'delstr', 'delword', 'exists',
+ 'formword', 'hashcode', 'insert', 'lastpos', 'left', 'lower',
+ 'max', 'min', 'noteq', 'noteqs', 'opadd', 'opand', 'opcc',
+ 'opccblank', 'opdiv', 'opdivi', 'opeq', 'opeqs', 'opgt',
+ 'opgteq', 'opgteqs', 'opgts', 'oplt', 'oplteq', 'oplteqs',
+ 'oplts', 'opminus', 'opmult', 'opnot', 'opor', 'opplus',
+ 'oppow', 'oprem', 'opsub', 'opxor', 'overlay', 'pos position',
+ 'reverse', 'right', 'sequence', 'setdigits', 'setform',
+ 'sign', 'space', 'strip', 'substr', 'subword', 'toboolean',
+ 'tobyte', 'tochar', 'todouble', 'tofloat', 'toint', 'tolong',
+ 'toshort', 'tostring', 'translate', 'trunc', 'upper',
+ 'verify', 'word', 'wordindex', 'wordlength', 'wordpos',
+ 'words', 'x2b', 'x2c', 'x2d'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '<', '>', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':',
+ '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #ff0000; font-weight: bold;',
+ 3 => 'color: #00ff00; font-weight: bold;',
+ 4 => 'color: #0000ff; font-weight: bold;',
+ 5 => 'color: #880088; font-weight: bold;',
+ 6 => 'color: #888800; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666;',
+ 'MULTI' => 'color: #808080;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/newlisp.php b/platform/www/vendor/geshi/geshi/src/geshi/newlisp.php
new file mode 100644
index 0000000..2daa72b
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/newlisp.php
@@ -0,0 +1,189 @@
+<?php
+/*************************************************************************************
+ * newlisp.php
+ * ----------
+ * Author: cormullion (cormullion@mac.com) Sept 2009
+ * Copyright: (c) 2009 Cormullion (http://unbalanced-parentheses.nfshost.com/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/09/30
+ *
+ * newLISP language file for GeSHi.
+ *
+ * based on work by Lutz Mueller and Jeff Ober
+ *
+ * CHANGES
+ * -------
+ * 2009/09/30 (1.0.8.6)
+ * - First Release
+ *
+ * TODO (updated 2009/09/30)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'newlisp',
+ 'COMMENT_SINGLE' => array(1 => ';', 2 => '#'),
+ 'COMMENT_MULTI' => array('[text]' => '[/text]', '{' => '}'), // also used for strings
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'NUMBERS' => GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'TAB_WIDTH' => 2,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'NaN?','abort','abs','acos','acosh','add','address','amb','and',
+ 'append','append-file','apply','args','array','array-list','array?',
+ 'asin','asinh','assoc','atan','atan2','atanh','atom?','base64-dec',
+ 'base64-enc','bayes-query','bayes-train','begin','beta','betai',
+ 'bind','binomial','bits','callback','case','catch','ceil',
+ 'change-dir','char','chop','clean','close','command-event','cond',
+ 'cons','constant','context','context?','copy','copy-file','cos',
+ 'cosh','count','cpymem','crc32','crit-chi2','crit-z','current-line',
+ 'curry','date','date-value','debug','dec','def-new','default',
+ 'define','define-macro','delete','delete-file','delete-url',
+ 'destroy','det','device','difference','directory','directory?',
+ 'div','do-until','do-while','doargs','dolist','dostring','dotimes',
+ 'dotree','dump','dup','empty?','encrypt','ends-with','env','erf',
+ 'error-event','estack','eval','eval-string','exec','exists','exit',
+ 'exp','expand','explode','factor','fft','file-info','file?',
+ 'filter','find','find-all','first','flat','float','float?','floor',
+ 'flt','for','for-all','fork','format','fv','gammai','gammaln','gcd',
+ 'get-char','get-float','get-int','get-long','get-string','get-url',
+ 'global','global?','if','if-not','ifft','import','inc','index',
+ 'inf?','int','integer','integer?','intersect','invert','irr','join',
+ 'lambda','lambda?','last','last-error','legal?','length','let',
+ 'letex','letn','list','list?','load','local','log','lookup',
+ 'lower-case','macro?','main-args','make-dir','map','mat','match',
+ 'max','member','min','mod','mul','multiply','name','net-accept',
+ 'net-close','net-connect','net-error','net-eval','net-interface',
+ 'net-listen','net-local','net-lookup','net-peek','net-peer',
+ 'net-ping','net-receive','net-receive-from','net-receive-udp',
+ 'net-select','net-send','net-send-to','net-send-udp','net-service',
+ 'net-sessions','new','nil','nil?','normal','not','now','nper','npv',
+ 'nth','null?','number?','open','or','pack','parse','parse-date',
+ 'peek','pipe','pmt','pop','pop-assoc','post-url','pow',
+ 'pretty-print','primitive?','print','println','prob-chi2','prob-z',
+ 'process','prompt-event','protected?','push','put-url','pv','quote',
+ 'quote?','rand','random','randomize','read-buffer','read-char',
+ 'read-expr','read-file','read-key','read-line','read-utf8',
+ 'real-path','receive','ref','ref-all','regex','regex-comp',
+ 'remove-dir','rename-file','replace','reset','rest','reverse',
+ 'rotate','round','save','search','seed','seek','select','semaphore',
+ 'send','sequence','series','set','set-locale','set-ref',
+ 'set-ref-all','setf','setq','sgn','share','signal','silent','sin',
+ 'sinh','sleep','slice','sort','source','spawn','sqrt','starts-with',
+ 'string','string?','sub','swap','sym','symbol?','symbols','sync',
+ 'sys-error','sys-info','tan','tanh','throw','throw-error','time',
+ 'time-of-day','timer','title-case','trace','trace-highlight',
+ 'transpose','trim','true','true?','unicode','unify','unique',
+ 'unless','unpack','until','upper-case','utf8','utf8len','uuid',
+ 'wait-pid','when','while','write-buffer','write-char','write-file',
+ 'write-line','xfer-event','xml-error','xml-parse','xml-type-tags',
+ 'zero?'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '(', ')','\''
+ ),
+ 1 => array(
+ '!','!=','$','%','&','*','+','-','/',':',
+ '<','<<','<=','=','>','>=','>>','^','|'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000AA;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #00aa00; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #777700;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #AA0000;',
+ 1 => 'color: #0000AA;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #00aa00;',
+ 1 => 'color: #00aa00;',
+ 2 => 'color: #00aa00;',
+ 3 => 'color: #00aa00;',
+ 4 => 'color: #00aa00;',
+ 5 => 'color: #AA0000;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.newlisp.org/downloads/newlisp_manual.html#{FNAME}'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(':'),
+ 'REGEXPS' => array(
+ // tags in newlispdoc
+ 0 => "\s+@\S*?\s+",
+ // dollar sign symbols
+ 1 => "[\\$]\w*",
+ // curly-braced string literals
+ 2 => "{[^{}]*?}",
+ // [text] multi-line strings
+ 3 => "(?s)\[text\].*\[\/text\](?-s)",
+ // [code] multi-line blocks
+ 4 => "(?s)\[code\].*\[\/code\](?-s)",
+ // variable references
+ 5 => "'[\w\-]+"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'OOLANG' => array(
+ 'MATCH_AFTER' => '[a-zA-Z][a-zA-Z0-9_\-]*'
+ ),
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => '(?<=[^\w\-])',
+ )
+ ),
+
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/nginx.php b/platform/www/vendor/geshi/geshi/src/geshi/nginx.php
new file mode 100644
index 0000000..ab2a9fb
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/nginx.php
@@ -0,0 +1,873 @@
+<?php
+/*************************************************************************************
+ * nginx.php
+ * ------
+ * Author: Cliff Wells (cliff@nginx.org)
+ * Copyright: (c) Cliff Wells (http://wiki.nginx.org/CliffWells)
+ * Contributors:
+ * - Deoren Moor (http://www.whyaskwhy.org/blog/)
+ * - Thomas Joiner
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/08/24
+ *
+ * nginx language file for GeSHi.
+ *
+ * Original release found at http://forum.nginx.org/read.php?2,123194,123210
+ *
+ * CHANGES
+ * -------
+ * 2012/08/29
+ * - Clean up the duplicate keywords
+ *
+ * 2012/08/26
+ * - Synchronized with directives listed on wiki/doc pages
+ * - Misc formatting tweaks and language fixes to pass langcheck
+ *
+ * 2010/08/24
+ * - First Release
+ *
+ * TODO (updated 2012/08/26)
+ * -------------------------
+ * - Verify PARSER_CONTROL items are correct
+ * - Verify REGEXPS
+ * - Verify ['STYLES']['REGEXPS'] entries
+ *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'nginx',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array( // core module
+ // http://wiki.nginx.org/CoreModule
+ // http://nginx.org/en/docs/ngx_core_module.html
+ 'daemon',
+ 'debug_points',
+ 'env',
+ 'error_log',
+ 'events',
+ 'include',
+ 'lock_file',
+ 'master_process',
+ 'pcre_jit',
+ 'pid',
+ 'ssl_engine',
+ 'timer_resolution',
+ 'user',
+ 'worker_cpu_affinity',
+ 'worker_priority',
+ 'worker_processes',
+ 'worker_rlimit_core',
+ 'worker_rlimit_nofile',
+ 'worker_rlimit_sigpending',
+ 'working_directory',
+ // see EventsModule due to organization of wiki
+ //'accept_mutex',
+ //'accept_mutex_delay',
+ //'debug_connection',
+ //'multi_accept',
+ //'use',
+ //'worker_connections',
+ ),
+ 2 => array( // events module
+ // http://wiki.nginx.org/EventsModule
+ // http://nginx.org/en/docs/ngx_core_module.html
+ 'accept_mutex',
+ 'accept_mutex_delay',
+ 'debug_connection',
+ 'devpoll_changes',
+ 'devpoll_events',
+ 'kqueue_changes',
+ 'kqueue_events',
+ 'epoll_events',
+ 'multi_accept',
+ 'rtsig_signo',
+ 'rtsig_overflow_events',
+ 'rtsig_overflow_test',
+ 'rtsig_overflow_threshold',
+ 'use',
+ 'worker_connections',
+ ),
+ 3 => array( // http module
+ // http://wiki.nginx.org/HttpCoreModule
+ // http://nginx.org/en/docs/http/ngx_http_core_module.html
+ 'aio',
+ 'alias',
+ 'chunked_transfer_encoding',
+ 'client_body_buffer_size',
+ 'client_body_in_file_only',
+ 'client_body_in_single_buffer',
+ 'client_body_temp_path',
+ 'client_body_timeout',
+ 'client_header_buffer_size',
+ 'client_header_timeout',
+ 'client_max_body_size',
+ 'connection_pool_size',
+ 'default_type',
+ 'directio',
+ 'directio_alignment',
+ 'disable_symlinks',
+ 'error_page',
+ 'etag',
+ 'http',
+ 'if_modified_since',
+ 'ignore_invalid_headers',
+ 'internal',
+ 'keepalive_disable',
+ 'keepalive_requests',
+ 'keepalive_timeout',
+ 'large_client_header_buffers',
+ 'limit_except',
+ 'limit_rate',
+ 'limit_rate_after',
+ 'lingering_close',
+ 'lingering_time',
+ 'lingering_timeout',
+ 'listen',
+ 'location',
+ 'log_not_found',
+ 'log_subrequest',
+ 'max_ranges',
+ 'merge_slashes',
+ 'msie_padding',
+ 'msie_refresh',
+ 'open_file_cache',
+ 'open_file_cache_errors',
+ 'open_file_cache_min_uses',
+ 'open_file_cache_valid',
+ 'optimize_server_names',
+ 'port_in_redirect',
+ 'postpone_output',
+ 'read_ahead',
+ 'recursive_error_pages',
+ 'request_pool_size',
+ 'reset_timedout_connection',
+ 'resolver',
+ 'resolver_timeout',
+ 'root',
+ 'satisfy',
+ 'satisfy_any',
+ 'send_lowat',
+ 'send_timeout',
+ 'sendfile',
+ 'sendfile_max_chunk',
+ 'server',
+ 'server_name',
+ 'server_name_in_redirect',
+ 'server_names_hash_bucket_size',
+ 'server_names_hash_max_size',
+ 'server_tokens',
+ 'tcp_nodelay',
+ 'tcp_nopush',
+ 'try_files',
+ 'types',
+ 'types_hash_bucket_size',
+ 'types_hash_max_size',
+ 'underscores_in_headers',
+ 'variables_hash_bucket_size',
+ 'variables_hash_max_size',
+ ),
+ 4 => array( // upstream module
+ // http://wiki.nginx.org/HttpUpstreamModule
+ // http://nginx.org/en/docs/http/ngx_http_upstream_module.html
+ 'ip_hash',
+ 'keepalive',
+ 'least_conn',
+ // Use the documentation from the core module since every conf will have at least one of those.
+ //'server',
+ 'upstream',
+ ),
+ 5 => array( // access module
+ // http://wiki.nginx.org/HttpAccessModule
+ // http://nginx.org/en/docs/http/ngx_http_access_module.html
+ 'deny',
+ 'allow',
+ ),
+ 6 => array( // auth basic module
+ // http://wiki.nginx.org/HttpAuthBasicModule
+ // http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html
+ 'auth_basic',
+ 'auth_basic_user_file'
+ ),
+ 7 => array( // auto index module
+ // http://wiki.nginx.org/HttpAutoindexModule
+ // http://nginx.org/en/docs/http/ngx_http_autoindex_module.html
+ 'autoindex',
+ 'autoindex_exact_size',
+ 'autoindex_localtime',
+ ),
+ 8 => array( // browser module
+ // http://wiki.nginx.org/HttpBrowserModule
+ // http://nginx.org/en/docs/http/ngx_http_browser_module.html
+ 'ancient_browser',
+ 'ancient_browser_value',
+ 'modern_browser',
+ 'modern_browser_value',
+ ),
+ 9 => array( // charset module
+ // http://wiki.nginx.org/HttpCharsetModule
+ // http://nginx.org/en/docs/http/ngx_http_charset_module.html
+ 'charset',
+ 'charset_map',
+ 'charset_types',
+ 'override_charset',
+ 'source_charset',
+ ),
+ 10 => array( // empty gif module
+ // http://wiki.nginx.org/HttpEmptyGifModule
+ // http://nginx.org/en/docs/http/ngx_http_empty_gif_module.html
+ 'empty_gif',
+ ),
+ 11 => array( // fastcgi module
+ // http://wiki.nginx.org/HttpFastcgiModule
+ // http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html
+ 'fastcgi_bind',
+ 'fastcgi_buffer_size',
+ 'fastcgi_buffers',
+ 'fastcgi_busy_buffers_size',
+ 'fastcgi_cache',
+ 'fastcgi_cache_bypass',
+ 'fastcgi_cache_key',
+ 'fastcgi_cache_lock',
+ 'fastcgi_cache_lock_timeout',
+ 'fastcgi_cache_methods',
+ 'fastcgi_cache_min_uses',
+ 'fastcgi_cache_path',
+ 'fastcgi_cache_use_stale',
+ 'fastcgi_cache_valid',
+ 'fastcgi_connect_timeout',
+ 'fastcgi_hide_header',
+ 'fastcgi_ignore_client_abort',
+ 'fastcgi_ignore_headers',
+ 'fastcgi_index',
+ 'fastcgi_intercept_errors',
+ 'fastcgi_keep_conn',
+ 'fastcgi_max_temp_file_size',
+ 'fastcgi_next_upstream',
+ 'fastcgi_no_cache',
+ 'fastcgi_param',
+ 'fastcgi_pass',
+ 'fastcgi_pass_header',
+ 'fastcgi_pass_request_body',
+ 'fastcgi_pass_request_headers',
+ 'fastcgi_read_timeout',
+ 'fastcgi_redirect_errors',
+ 'fastcgi_send_timeout',
+ 'fastcgi_split_path_info',
+ 'fastcgi_store',
+ 'fastcgi_store_access',
+ 'fastcgi_temp_file_write_size',
+ 'fastcgi_temp_path',
+ ),
+ 12 => array( // geo module
+ // http://wiki.nginx.org/HttpGeoModule
+ // http://nginx.org/en/docs/http/ngx_http_geo_module.html
+ 'geo'
+ ),
+ 13 => array( // gzip module
+ // http://wiki.nginx.org/HttpGzipModule
+ // http://nginx.org/en/docs/http/ngx_http_gzip_module.html
+ 'gzip',
+ 'gzip_buffers',
+ 'gzip_comp_level',
+ 'gzip_disable',
+ 'gzip_min_length',
+ 'gzip_http_version',
+ 'gzip_proxied',
+ 'gzip_types',
+ 'gzip_vary',
+ ),
+ 14 => array( // headers module
+ // http://wiki.nginx.org/HttpHeadersModule
+ // http://nginx.org/en/docs/http/ngx_http_headers_module.html
+ 'add_header',
+ 'expires',
+ ),
+ 15 => array( // index module
+ // http://wiki.nginx.org/HttpIndexModule
+ // http://nginx.org/en/docs/http/ngx_http_index_module.html
+ 'index',
+ ),
+ 16 => array( // limit requests module
+ // http://wiki.nginx.org/HttpLimitReqModule
+ // http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
+ 'limit_req',
+ 'limit_req_log_level',
+ 'limit_req_zone',
+ ),
+ 17 => array( // referer module
+ // http://wiki.nginx.org/HttpRefererModule
+ // http://nginx.org/en/docs/http/ngx_http_referer_module.html
+ 'referer_hash_bucket_size',
+ 'referer_hash_max_size',
+ 'valid_referers',
+ ),
+ 18 => array( // limit zone module
+ // deprecated in 1.1.8
+ // http://wiki.nginx.org/HttpLimitZoneModule
+ 'limit_zone',
+ // Covered by documentation for ngx_http_limit_conn_module
+ //'limit_conn',
+ ),
+ 19 => array( // limit connection module
+ // http://wiki.nginx.org/HttpLimitConnModule
+ // http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
+ 'limit_conn',
+ 'limit_conn_zone',
+ 'limit_conn_log_level',
+ ),
+ 20 => array( // log module
+ // http://wiki.nginx.org/HttpLogModule
+ // http://nginx.org/en/docs/http/ngx_http_log_module.html
+ 'access_log',
+ 'log_format',
+ // Appears to be deprecated
+ 'log_format_combined',
+ 'open_log_file_cache',
+ ),
+ 21 => array( // map module
+ // http://wiki.nginx.org/HttpMapModule
+ // http://nginx.org/en/docs/http/ngx_http_map_module.html
+ 'map',
+ 'map_hash_max_size',
+ 'map_hash_bucket_size',
+ ),
+ 22 => array( // memcached module
+ // http://wiki.nginx.org/HttpMemcachedModule
+ // http://nginx.org/en/docs/http/ngx_http_memcached_module.html
+ 'memcached_buffer_size',
+ 'memcached_connect_timeout',
+ 'memcached_next_upstream',
+ 'memcached_pass',
+ 'memcached_read_timeout',
+ 'memcached_send_timeout',
+ ),
+ 23 => array( // proxy module
+ // http://wiki.nginx.org/HttpProxyModule
+ // http://nginx.org/en/docs/http/ngx_http_proxy_module.html
+ 'proxy_bind',
+ 'proxy_buffer_size',
+ 'proxy_buffering',
+ 'proxy_buffers',
+ 'proxy_busy_buffers_size',
+ 'proxy_cache',
+ 'proxy_cache_bypass',
+ 'proxy_cache_key',
+ 'proxy_cache_lock',
+ 'proxy_cache_lock_timeout',
+ 'proxy_cache_methods',
+ 'proxy_cache_min_uses',
+ 'proxy_cache_path',
+ 'proxy_cache_use_stale',
+ 'proxy_cache_valid',
+ 'proxy_connect_timeout',
+ 'proxy_cookie_domain',
+ 'proxy_cookie_path',
+ 'proxy_headers_hash_bucket_size',
+ 'proxy_headers_hash_max_size',
+ 'proxy_hide_header',
+ 'proxy_http_version',
+ 'proxy_ignore_client_abort',
+ 'proxy_ignore_headers',
+ 'proxy_intercept_errors',
+ 'proxy_max_temp_file_size',
+ 'proxy_method',
+ 'proxy_next_upstream',
+ 'proxy_no_cache',
+ 'proxy_pass',
+ 'proxy_pass_header',
+ 'proxy_pass_request_body',
+ 'proxy_pass_request_headers',
+ 'proxy_redirect',
+ 'proxy_read_timeout',
+ 'proxy_redirect_errors',
+ 'proxy_send_lowat',
+ 'proxy_send_timeout',
+ 'proxy_set_body',
+ 'proxy_set_header',
+ 'proxy_ssl_session_reuse',
+ 'proxy_store',
+ 'proxy_store_access',
+ 'proxy_temp_file_write_size',
+ 'proxy_temp_path',
+ 'proxy_upstream_fail_timeout',
+ 'proxy_upstream_max_fails',
+ ),
+ 24 => array( // rewrite module
+ // http://wiki.nginx.org/HttpRewriteModule
+ // http://nginx.org/en/docs/http/ngx_http_rewrite_module.html
+ 'break',
+ 'if',
+ 'return',
+ 'rewrite',
+ 'rewrite_log',
+ 'set',
+ 'uninitialized_variable_warn',
+ ),
+ 25 => array( // ssi module
+ // http://wiki.nginx.org/HttpSsiModule
+ // http://nginx.org/en/docs/http/ngx_http_ssi_module.html
+ 'ssi',
+ 'ssi_silent_errors',
+ 'ssi_types',
+ 'ssi_value_length',
+ ),
+ 26 => array( // user id module
+ // http://wiki.nginx.org/HttpUseridModule
+ // http://nginx.org/en/docs/http/ngx_http_userid_module.html
+ 'userid',
+ 'userid_domain',
+ 'userid_expires',
+ 'userid_name',
+ 'userid_p3p',
+ 'userid_path',
+ 'userid_service',
+ ),
+ 27 => array( // addition module
+ // http://wiki.nginx.org/HttpAdditionModule
+ // http://nginx.org/en/docs/http/ngx_http_addition_module.html
+ 'add_before_body',
+ 'add_after_body',
+ 'addition_types',
+ ),
+ 28 => array( // embedded Perl module
+ // http://wiki.nginx.org/HttpPerlModule
+ // http://nginx.org/en/docs/http/ngx_http_perl_module.html
+ 'perl',
+ 'perl_modules',
+ 'perl_require',
+ 'perl_set',
+ ),
+ 29 => array( // flash video files module
+ // http://wiki.nginx.org/HttpFlvModule
+ // http://nginx.org/en/docs/http/ngx_http_flv_module.html
+ 'flv',
+ ),
+ 30 => array( // gzip precompression module
+ // http://wiki.nginx.org/HttpGzipStaticModule
+ // http://nginx.org/en/docs/http/ngx_http_gzip_static_module.html
+ 'gzip_static',
+ // Removed to remove duplication with ngx_http_gzip_module
+ //'gzip_http_version',
+ //'gzip_proxied',
+ //'gzip_disable',
+ //'gzip_vary',
+ ),
+ 31 => array( // random index module
+ // http://wiki.nginx.org/HttpRandomIndexModule
+ // http://nginx.org/en/docs/http/ngx_http_random_index_module.html
+ 'random_index',
+ ),
+ 32 => array( // real ip module
+ // http://wiki.nginx.org/HttpRealipModule
+ // http://nginx.org/en/docs/http/ngx_http_realip_module.html
+ 'set_real_ip_from',
+ 'real_ip_header',
+ 'real_ip_recursive',
+ ),
+ 33 => array( // https module
+ // http://wiki.nginx.org/HttpSslModule
+ // http://nginx.org/en/docs/http/ngx_http_ssl_module.html
+ 'ssl',
+ 'ssl_certificate',
+ 'ssl_certificate_key',
+ 'ssl_ciphers',
+ 'ssl_client_certificate',
+ 'ssl_crl',
+ 'ssl_dhparam',
+ // Use the documentation for the core module since it links to the
+ // original properly
+ //'ssl_engine',
+ 'ssl_prefer_server_ciphers',
+ 'ssl_protocols',
+ 'ssl_session_cache',
+ 'ssl_session_timeout',
+ 'ssl_verify_client',
+ 'ssl_verify_depth',
+ ),
+ 34 => array( // status module
+ // http://wiki.nginx.org/HttpStubStatusModule
+ 'stub_status',
+ ),
+ 35 => array( // substitution module
+ // http://wiki.nginx.org/HttpSubModule
+ // http://nginx.org/en/docs/http/ngx_http_sub_module.html
+ 'sub_filter',
+ 'sub_filter_once',
+ 'sub_filter_types',
+ ),
+ 36 => array( // NginxHttpDavModule
+ // http://wiki.nginx.org/HttpDavModule
+ // http://nginx.org/en/docs/http/ngx_http_dav_module.html
+ 'dav_access',
+ 'dav_methods',
+ 'create_full_put_path',
+ 'min_delete_depth',
+ ),
+ 37 => array( // Google performance tools module
+ // http://wiki.nginx.org/GooglePerftoolsModule
+ 'google_perftools_profiles',
+ ),
+ 38 => array( // xslt module
+ // http://wiki.nginx.org/HttpXsltModule
+ // http://nginx.org/en/docs/http/ngx_http_xslt_module.html
+ 'xslt_entities',
+ 'xslt_param',
+ 'xslt_string_param',
+ 'xslt_stylesheet',
+ 'xslt_types',
+ ),
+ 39 => array( // uWSGI module
+ // http://wiki.nginx.org/HttpUwsgiModule
+ 'uwsgi_bind',
+ 'uwsgi_buffer_size',
+ 'uwsgi_buffering',
+ 'uwsgi_buffers',
+ 'uwsgi_busy_buffers_size',
+ 'uwsgi_cache',
+ 'uwsgi_cache_bypass',
+ 'uwsgi_cache_key',
+ 'uwsgi_cache_lock',
+ 'uwsgi_cache_lock_timeout',
+ 'uwsgi_cache_methods',
+ 'uwsgi_cache_min_uses',
+ 'uwsgi_cache_path',
+ 'uwsgi_cache_use_stale',
+ 'uwsgi_cache_valid',
+ 'uwsgi_connect_timeout',
+ 'uwsgi_hide_header',
+ 'uwsgi_ignore_client_abort',
+ 'uwsgi_ignore_headers',
+ 'uwsgi_intercept_errors',
+ 'uwsgi_max_temp_file_size',
+ 'uwsgi_modifier',
+ 'uwsgi_next_upstream',
+ 'uwsgi_no_cache',
+ 'uwsgi_param',
+ 'uwsgi_pass',
+ 'uwsgi_pass_header',
+ 'uwsgi_pass_request_body',
+ 'uwsgi_pass_request_headers',
+ 'uwsgi_read_timeout',
+ 'uwsgi_send_timeout',
+ 'uwsgi_store',
+ 'uwsgi_store_access',
+ 'uwsgi_string',
+ 'uwsgi_temp_file_write_size',
+ 'uwsgi_temp_path',
+ ),
+ 40 => array( // SCGI module
+ // http://wiki.nginx.org/HttpScgiModule
+ // Note: These directives were pulled from nginx 1.2.3
+ // ngx_http_scgi_module.c source file.
+ 'scgi_bind',
+ 'scgi_buffering',
+ 'scgi_buffers',
+ 'scgi_buffer_size',
+ 'scgi_busy_buffers_size',
+ 'scgi_cache',
+ 'scgi_cache_bypass',
+ 'scgi_cache_key',
+ 'scgi_cache_lock',
+ 'scgi_cache_lock_timeout',
+ 'scgi_cache_methods',
+ 'scgi_cache_min_uses',
+ 'scgi_cache_path',
+ 'scgi_cache_use_stale',
+ 'scgi_cache_valid',
+ 'scgi_connect_timeout',
+ 'scgi_hide_header',
+ 'scgi_ignore_client_abort',
+ 'scgi_ignore_headers',
+ 'scgi_intercept_errors',
+ 'scgi_max_temp_file_size',
+ 'scgi_next_upstream',
+ 'scgi_no_cache',
+ 'scgi_param',
+ 'scgi_pass',
+ 'scgi_pass_header',
+ 'scgi_pass_request_body',
+ 'scgi_pass_request_headers',
+ 'scgi_read_timeout',
+ 'scgi_send_timeout',
+ 'scgi_store',
+ 'scgi_store_access',
+ 'scgi_temp_file_write_size',
+ 'scgi_temp_path',
+ ),
+ 41 => array( // split clients module
+ // http://wiki.nginx.org/HttpSplitClientsModule
+ // http://nginx.org/en/docs/http/ngx_http_split_clients_module.html
+ 'split_clients',
+ ),
+ 42 => array( // X-Accel module
+ // http://wiki.nginx.org/X-accel
+ 'X-Accel-Redirect',
+ 'X-Accel-Buffering',
+ 'X-Accel-Charset',
+ 'X-Accel-Expires',
+ 'X-Accel-Limit-Rate',
+ ),
+ 43 => array( // degradation module
+ // http://wiki.nginx.org/HttpDegradationModule
+ 'degradation',
+ 'degrade',
+ ),
+ 44 => array( // GeoIP module
+ // http://wiki.nginx.org/HttpGeoipModule
+ // http://nginx.org/en/docs/http/ngx_http_geoip_module.html
+ 'geoip_country',
+ 'geoip_city',
+ 'geoip_proxy',
+ 'geoip_proxy_recursive',
+ ),
+ 45 => array( // Image filter module
+ // http://wiki.nginx.org/HttpImageFilterModule
+ // http://nginx.org/en/docs/http/ngx_http_image_filter_module.html
+ 'image_filter',
+ 'image_filter_buffer',
+ 'image_filter_jpeg_quality',
+ 'image_filter_sharpen',
+ 'image_filter_transparency',
+ ),
+ 46 => array( // MP4 module
+ // http://wiki.nginx.org/HttpMp4Module
+ // http://nginx.org/en/docs/http/ngx_http_mp4_module.html
+ 'mp4',
+ 'mp4_buffer_size',
+ 'mp4_max_buffer_size',
+ ),
+ 47 => array( // Secure Link module
+ // http://wiki.nginx.org/HttpSecureLinkModule
+ // http://nginx.org/en/docs/http/ngx_http_secure_link_module.html
+ 'secure_link',
+ 'secure_link_md',
+ 'secure_link_secret',
+ ),
+ 48 => array( // Mail Core module
+ // http://wiki.nginx.org/MailCoreModule
+ 'auth',
+ 'imap_capabilities',
+ 'imap_client_buffer',
+ 'pop_auth',
+ 'pop_capabilities',
+ 'protocol',
+ 'smtp_auth',
+ 'smtp_capabilities',
+ 'so_keepalive',
+ 'timeout',
+ // Removed to prioritize documentation for core module
+ //'listen',
+ //'server',
+ //'server_name',
+ ),
+ 49 => array( // Mail Auth module
+ // http://wiki.nginx.org/MailAuthModule
+ 'auth_http',
+ 'auth_http_header',
+ 'auth_http_timeout',
+ ),
+ 50 => array( // Mail Proxy module
+ // http://wiki.nginx.org/MailProxyModule
+ 'proxy',
+ 'proxy_buffer',
+ 'proxy_pass_error_message',
+ 'proxy_timeout',
+ 'xclient',
+ ),
+ 51 => array( // Mail SSL module
+ // http://wiki.nginx.org/MailSslModule
+ // Removed to prioritize documentation for http
+ //'ssl',
+ //'ssl_certificate',
+ //'ssl_certificate_key',
+ //'ssl_ciphers',
+ //'ssl_prefer_server_ciphers',
+ //'ssl_protocols',
+ //'ssl_session_cache',
+ //'ssl_session_timeout',
+ 'starttls',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '=', '~', ';'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true,
+ 10 => true,
+ 11 => true,
+ 12 => true,
+ 13 => true,
+ 14 => true,
+ 15 => true,
+ 16 => true,
+ 17 => true,
+ 18 => true,
+ 19 => true,
+ 20 => true,
+ 21 => true,
+ 22 => true,
+ 23 => true,
+ 24 => true,
+ 25 => true,
+ 26 => true,
+ 27 => true,
+ 28 => true,
+ 29 => true,
+ 30 => true,
+ 31 => true,
+ 32 => true,
+ 33 => true,
+ 34 => true,
+ 35 => true,
+ 36 => true,
+ 37 => true,
+ 38 => true,
+ 39 => true,
+ 40 => true,
+ 41 => true,
+ 42 => true,
+ 43 => true,
+ 44 => true,
+ 45 => true,
+ 46 => true,
+ 47 => true,
+ 48 => true,
+ 49 => true,
+ 50 => true,
+ 51 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #993333;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #000066;',
+ 4 => 'color: #000000; font-weight: bold;',
+ ),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => 'http://wiki.nginx.org/CoreModule#{FNAME}',
+ 2 => 'http://wiki.nginx.org/NginxHttpEventsModule#{FNAME}',
+ 3 => 'http://wiki.nginx.org/NginxHttpCoreModule#{FNAME}',
+ 4 => 'http://wiki.nginx.org/NginxHttpUpstreamModule#{FNAME}',
+ 5 => 'http://wiki.nginx.org/NginxHttpAccessModule#{FNAME}',
+ 6 => 'http://wiki.nginx.org/NginxHttpAuthBasicModule#{FNAME}',
+ 7 => 'http://wiki.nginx.org/NginxHttpAutoIndexModule#{FNAME}',
+ 8 => 'http://wiki.nginx.org/NginxHttpBrowserModule#{FNAME}',
+ 9 => 'http://wiki.nginx.org/NginxHttpCharsetModule#{FNAME}',
+ 10 => 'http://wiki.nginx.org/NginxHttpEmptyGifModule#{FNAME}',
+ 11 => 'http://wiki.nginx.org/NginxHttpFcgiModule#{FNAME}',
+ 12 => 'http://wiki.nginx.org/NginxHttpGeoModule#{FNAME}',
+ 13 => 'http://wiki.nginx.org/NginxHttpGzipModule#{FNAME}',
+ 14 => 'http://wiki.nginx.org/NginxHttpHeadersModule#{FNAME}',
+ 15 => 'http://wiki.nginx.org/NginxHttpIndexModule#{FNAME}',
+ 16 => 'http://wiki.nginx.org/HttpLimitReqModule#{FNAME}',
+ 17 => 'http://wiki.nginx.org/NginxHttpRefererModule#{FNAME}',
+ 18 => 'http://wiki.nginx.org/NginxHttpLimitZoneModule#{FNAME}',
+ 19 => 'http://wiki.nginx.org/HttpLimitConnModule#{FNAME}',
+ 20 => 'http://wiki.nginx.org/NginxHttpLogModule#{FNAME}',
+ 21 => 'http://wiki.nginx.org/NginxHttpMapModule#{FNAME}',
+ 22 => 'http://wiki.nginx.org/NginxHttpMemcachedModule#{FNAME}',
+ 23 => 'http://wiki.nginx.org/NginxHttpProxyModule#{FNAME}',
+ 24 => 'http://wiki.nginx.org/NginxHttpRewriteModule#{FNAME}',
+ 25 => 'http://wiki.nginx.org/NginxHttpSsiModule#{FNAME}',
+ 26 => 'http://wiki.nginx.org/NginxHttpUserIdModule#{FNAME}',
+ 27 => 'http://wiki.nginx.org/NginxHttpAdditionModule#{FNAME}',
+ 28 => 'http://wiki.nginx.org/NginxHttpEmbeddedPerlModule#{FNAME}',
+ 29 => 'http://wiki.nginx.org/NginxHttpFlvStreamModule#{FNAME}',
+ 30 => 'http://wiki.nginx.org/NginxHttpGzipStaticModule#{FNAME}',
+ 31 => 'http://wiki.nginx.org/NginxHttpRandomIndexModule#{FNAME}',
+ 32 => 'http://wiki.nginx.org/NginxHttpRealIpModule#{FNAME}',
+ 33 => 'http://wiki.nginx.org/NginxHttpSslModule#{FNAME}',
+ 34 => 'http://wiki.nginx.org/NginxHttpStubStatusModule#{FNAME}',
+ 35 => 'http://wiki.nginx.org/NginxHttpSubModule#{FNAME}',
+ 36 => 'http://wiki.nginx.org/NginxHttpDavModule#{FNAME}',
+ 37 => 'http://wiki.nginx.org/NginxHttpGooglePerfToolsModule#{FNAME}',
+ 38 => 'http://wiki.nginx.org/NginxHttpXsltModule#{FNAME}',
+ 39 => 'http://wiki.nginx.org/NginxHttpUwsgiModule#{FNAME}',
+ 40 => 'http://wiki.nginx.org/HttpScgiModule',
+ 41 => 'http://wiki.nginx.org/HttpSplitClientsModule#{FNAME}',
+ 42 => 'http://wiki.nginx.org/X-accel#{FNAME}',
+ 43 => 'http://wiki.nginx.org/HttpDegradationModule#{FNAME}',
+ 44 => 'http://wiki.nginx.org/HttpGeoipModule#{FNAME}',
+ 45 => 'http://wiki.nginx.org/HttpImageFilterModule#{FNAME}',
+ 46 => 'http://wiki.nginx.org/HttpMp4Module#{FNAME}',
+ 47 => 'http://wiki.nginx.org/HttpSecureLinkModule#{FNAME}',
+ 48 => 'http://wiki.nginx.org/MailCoreModule#{FNAME}',
+ 49 => 'http://wiki.nginx.org/MailAuthModule#{FNAME}',
+ 50 => 'http://wiki.nginx.org/MailProxyModule#{FNAME}',
+ 51 => 'http://wiki.nginx.org/MailSslModule#{FNAME}',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ 0 => '[\\$%@]+[a-zA-Z_][a-zA-Z0-9_]*',
+ 4 => '&lt;[a-zA-Z_][a-zA-Z0-9_]*&gt;',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'NUMBERS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/nimrod.php b/platform/www/vendor/geshi/geshi/src/geshi/nimrod.php
new file mode 100644
index 0000000..1be7970
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/nimrod.php
@@ -0,0 +1,201 @@
+<?php
+/*************************************************************************************
+ * nimrod.php
+ * ----------
+ * Author: Dennis Felsing (dennis@felsin9.de)
+ * Copyright: (c) 2014 Dennis Felsing
+ * Release Version: 1.0.9.1
+ * Date Started: 2014/07/15
+ *
+ * Nimrod language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2014/07/15 (1.0.8.13)
+ * - First Release
+ *
+ * TODO (updated 2014/07/15)
+ * -------------------------
+ * - Int literals like 50'u8
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Nimrod',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ //Longest quotemarks ALWAYS first
+ 'QUOTEMARKS' => array('"""', '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX_0O | GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_FLT_NONSCI | GESHI_NUMBER_FLT_NONSCI_F |
+ GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+
+ /*
+ ** Set 1: reserved words
+ ** http://nimrod-lang.org/manual.html#identifiers-keywords
+ */
+ 1 => array(
+ 'addr', 'and', 'as', 'asm', 'atomic',
+ 'bind', 'block', 'break',
+ 'case', 'cast', 'const', 'continue', 'converter',
+ 'discard', 'distinct', 'div', 'do',
+ 'elif', 'else', 'end', 'enum', 'except', 'export',
+ 'finally', 'for', 'from',
+ 'generic',
+ 'if', 'import', 'in', 'include', 'interface', 'is', 'isnot', 'iterator',
+ 'lambda', 'let',
+ 'macro', 'method', 'mixin', 'mod',
+ 'nil', 'not', 'notin',
+ 'object', 'of', 'or', 'out',
+ 'proc',
+ 'raise', 'ref', 'return',
+ 'shl', 'shr', 'static',
+ 'template', 'try', 'tuple', 'type',
+ 'using',
+ 'var',
+ 'when', 'while', 'with', 'without',
+ 'xor',
+ 'yield'
+ ),
+
+ 2 => array(
+ 'true', 'false'
+ ),
+
+ 3 => array(
+ /* system module */
+ 'abs', 'accumulateResult', 'add', 'addAndFetch', 'addQuitProc',
+ 'alloc', 'alloc0', 'allocCStringArray', 'allocShared',
+ 'allocShared0', 'assert', 'astToStr', 'atomicDec', 'atomicInc',
+ 'card', 'chr', 'clamp', 'close', 'cmp', 'compileOption',
+ 'compiles', 'contains', 'copy', 'copyMem', 'countdown', 'countup',
+ 'create', 'createShared', 'createSharedU', 'createU',
+ 'cstringArrayToSeq', 'currentSourcePath', 'dealloc',
+ 'deallocCStringArray', 'deallocShared', 'debugEcho', 'dec',
+ 'defined', 'definedInScope', 'del', 'delete', 'doAssert', 'each',
+ 'echo', 'endOfFile', 'equalMem', 'excl', 'failedAssertImpl',
+ 'fieldPairs', 'fields', 'fileHandle', 'find', 'finished',
+ 'flushFile', 'free', 'freeShared', 'GC_addCycleRoot', 'GC_disable',
+ 'GC_disableMarkAndSweep', 'GC_enable', 'GC_enableMarkAndSweep',
+ 'GC_fullCollect', 'GC_getStatistics', 'gcInvariant', 'GC_ref',
+ 'GC_setStrategy', 'GC_unref', 'getCurrentException',
+ 'getCurrentExceptionMsg', 'getFilePos', 'getFileSize',
+ 'getFreeMem', 'getOccupiedMem', 'getRefcount', 'getStackTrace',
+ 'getTotalMem', 'getTypeInfo', 'gorge', 'high', 'inc', 'incl',
+ 'insert', 'instantiationInfo', 'internalNew', 'isNil', 'isOnStack',
+ 'isStatic', 'items', 'len', 'likely', 'lines', 'locals', 'low',
+ 'map', 'max', 'min', 'moveMem', 'new', 'newException', 'newSeq',
+ 'newString', 'newStringOfCap', 'newWideCString', 'nimDestroyRange',
+ 'onFailedAssert', 'onRaise', 'open', 'ord', 'pairs', 'pop', 'pred',
+ 'quit', 'raiseAssert', 'rand', 'rawEnv', 'rawProc', 'readAll',
+ 'readBuffer', 'readBytes', 'readChar', 'readChars', 'readFile',
+ 'readLine', 'realloc', 'reallocShared', 'reopen', 'repr', 'reset',
+ 'resize', 'safeAdd', 'setControlCHook', 'setFilePos', 'setLen',
+ 'shallow', 'shallowCopy', 'sizeof', 'slurp', 'staticExec',
+ 'staticRead', 'stdmsg', 'substr', 'succ', 'swap', 'toBiggestFloat',
+ 'toBiggestInt', 'toFloat', 'toInt', 'toU16', 'toU32', 'toU8',
+ 'unlikely', 'unsafeNew', 'write', 'writeBuffer', 'writeBytes',
+ 'writeChars', 'writeFile', 'writeln', 'writeStackTrace', 'ze',
+ 'ze64', 'zeroMem'
+ ),
+
+ 4 => array(
+ 'auto', 'pointer', 'ptr', 'void', 'any', 'expr', 'stmt', 'typedesc',
+ 'int', 'int8', 'int16', 'int32', 'int64', 'float', 'float32', 'float64',
+ 'uint', 'uint8', 'uint16', 'uint32', 'uint64',
+ 'bool', 'char', 'range', 'array', 'seq', 'set', 'string', 'TSlice',
+ 'cstring', 'cint', 'clong', 'culong', 'cchar', 'cschar', 'cshort',
+ 'csize', 'clonglong', 'cfloat', 'cdouble', 'clongdouble', 'cuchar',
+ 'cushort', 'cuint', 'culonglong', 'cstringArray'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '*', '/', '%', '\\',
+ '+', '-', '~', '|',
+ '&',
+ '..',
+ '=', '<', '>', '!',
+ '@', '?'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #ff7700;font-weight:bold;', // Reserved
+ 2 => 'color: #008000;', // Built-ins + self
+ 3 => 'color: #dc143c;', // Standard lib
+ 4 => 'color: #0000cd;' // Special methods
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: black;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #483d8b;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff4500;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: black;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/nsis.php b/platform/www/vendor/geshi/geshi/src/geshi/nsis.php
new file mode 100644
index 0000000..3fb54a0
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/nsis.php
@@ -0,0 +1,351 @@
+<?php
+/*************************************************************************************
+ * nsis.php
+ * --------
+ * Author: deguix (cevo_deguix@yahoo.com.br), Tux (http://tux.a4.cz/), Jan T. Sott (http://github.com/idleberg)
+ * Copyright: (c) 2005 deguix, 2004 Tux (http://tux.a4.cz/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/12/03
+ *
+ * Nullsoft Scriptable Install System language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2014/04/23 (2.0.3)
+ * - Updated to NSIS 3.0a2
+ * - Removed deprecated commands
+ * 2005/12/03 (2.0.2)
+ * - Updated to NSIS 2.11.
+ * 2005/06/17 (2.0.1)
+ * - Updated to NSIS 2.07b0.
+ * 2005/04/05 (2.0.0)
+ * - Updated to NSIS 2.06.
+ * 2004/11/27 (1.0.2)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ * - Added support for URLs
+ * 2004/08/05 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'NSIS',
+ 'COMMENT_SINGLE' => array(1 => ';', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'",'"','`'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ '!addincludedir', '!addplugindir', '!appendfile', '!cd', '!define', '!delfile', '!echo', '!error',
+ '!execute', '!finalize', '!getdllversion', '!include', '!insertmacro', '!macro', '!macroend', '!makensis', '!packhdr',
+ '!searchparse', '!searchreplace', '!system', '!tempfile', '!undef', '!verbose', '!warning'
+ ),
+ 2 => array(
+ 'AddBrandingImage', 'AllowRootDirInstall', 'AutoCloseWindow', 'BGFont',
+ 'BGGradient', 'BrandingText', 'Caption', 'ChangeUI', 'CheckBitmap', 'CompletedText', 'ComponentText',
+ 'CRCCheck', 'DetailsButtonText', 'DirText', 'DirVar', 'DirVerify', 'FileErrorText',
+ 'Function', 'FunctionEnd', 'Icon', 'InstallButtonText', 'InstallColors', 'InstallDir',
+ 'InstallDirRegKey', 'InstProgressFlags', 'InstType', 'LangString', 'LicenseBkColor',
+ 'LicenseData', 'LicenseForceSelection', 'LicenseLangString', 'LicenseText', 'LoadLanguageFile', 'ManifestDPIAware', 'ManifestSupportedOS',
+ 'MiscButtonText', 'Name', 'OutFile', 'Page', 'PageEx', 'PageExEnd', 'RequestExecutionLevel', 'Section',
+ 'SectionEnd', 'SectionGroup', 'SectionGroupEnd', 'SetCompressor', 'SetFont', 'ShowInstDetails',
+ 'ShowUninstDetails', 'SilentInstall', 'SilentUnInstall', 'SpaceTexts', 'SubCaption', 'SubSection',
+ 'SubSectionEnd', 'Unicode', 'UninstallButtonText', 'UninstallCaption', 'UninstallIcon', 'UninstallSubCaption',
+ 'UninstallText', 'UninstPage', 'Var', 'VIAddVersionKey', 'VIFileVersion', 'VIProductVersion', 'WindowIcon', 'XPStyle'
+ ),
+ 3 => array(
+ 'AddSize', 'AllowSkipFiles', 'FileBufSize', 'GetInstDirError', 'PageCallbacks',
+ 'SectionIn', 'SetCompress', 'SetCompressorDictSize',
+ 'SetDatablockOptimize', 'SetDateSave', 'SetOverwrite', 'SetPluginUnload'
+ ),
+ 4 => array(
+ 'Abort', 'BringToFront', 'Call', 'CallInstDLL', 'ClearErrors', 'CopyFiles','CreateDirectory',
+ 'CreateFont', 'CreateShortCut', 'Delete', 'DeleteINISec', 'DeleteINIStr', 'DeleteRegKey',
+ 'DeleteRegValue', 'DetailPrint', 'EnableWindow', 'EnumRegKey', 'EnumRegValue', 'Exch', 'Exec',
+ 'ExecShell', 'ExecWait', 'ExpandEnvStrings', 'File', 'FileClose', 'FileOpen', 'FileRead',
+ 'FileReadByte', 'FileReadUTF16LE', 'FileReadWord', 'FileSeek', 'FileWrite', 'FileWriteByte', 'FileWriteUTF16LE', 'FileWriteWord', 'FindClose', 'FindFirst', 'FindNext',
+ 'FindWindow', 'FlushINI', 'GetCurInstType', 'GetCurrentAddress', 'GetDlgItem', 'GetDLLVersion',
+ 'GetDLLVersionLocal', 'GetErrorLevel', 'GetFileTime', 'GetFileTimeLocal', 'GetFullPathName',
+ 'GetFunctionAddress', 'GetLabelAddress', 'GetTempFileName', 'Goto', 'HideWindow',
+ 'IfAbort', 'IfErrors', 'IfFileExists', 'IfRebootFlag', 'IfSilent', 'InitPluginsDir', 'InstTypeGetText',
+ 'InstTypeSetText', 'IntCmp', 'IntCmpU', 'IntFmt', 'IntOp', 'IsWindow', 'LockWindow', 'LogSet', 'LogText',
+ 'MessageBox', 'Nop', 'Pop', 'Push', 'Quit', 'ReadEnvStr', 'ReadINIStr', 'ReadRegDWORD', 'ReadRegStr',
+ 'Reboot', 'RegDLL', 'Rename', 'ReserveFile', 'Return', 'RMDir', 'SearchPath', 'SectionGetFlags',
+ 'SectionGetInstTypes', 'SectionGetSize', 'SectionGetText', 'SectionSetFlags', 'SectionSetInstTypes',
+ 'SectionSetSize', 'SectionSetText', 'SendMessage', 'SetAutoClose', 'SetBrandingImage', 'SetCtlColors',
+ 'SetCurInstType', 'SetDetailsPrint', 'SetDetailsView', 'SetErrorLevel', 'SetErrors', 'SetFileAttributes',
+ 'SetOutPath', 'SetRebootFlag', 'SetRegView', 'SetShellVarContext', 'SetSilent', 'ShowWindow', 'Sleep', 'StrCmp', 'StrCmpS',
+ 'StrCpy', 'StrLen', 'UnRegDLL', 'WriteINIStr', 'WriteRegBin', 'WriteRegDWORD', 'WriteRegExpandStr',
+ 'WriteRegStr', 'WriteUninstaller'
+ ),
+ 5 => array(
+ 'all', 'alwaysoff', 'ARCHIVE', 'auto', 'both', 'bzip2', 'checkbox', 'components', 'current',
+ 'custom', 'directory', 'false', 'FILE_ATTRIBUTE_ARCHIVE', 'FILE_ATTRIBUTE_HIDDEN', 'FILE_ATTRIBUTE_NORMAL',
+ 'FILE_ATTRIBUTE_OFFLINE', 'FILE_ATTRIBUTE_READONLY', 'FILE_ATTRIBUTE_SYSTEM,TEMPORARY',
+ 'FILE_ATTRIBUTE_TEMPORARY', 'force', 'HIDDEN', 'hide', 'HKCC', 'HKCR', 'HKCU', 'HKDD', 'HKEY_CLASSES_ROOT',
+ 'HKEY_CURRENT_CONFIG', 'HKEY_CURRENT_USER', 'HKEY_DYN_DATA', 'HKEY_LOCAL_MACHINE', 'HKEY_PERFORMANCE_DATA',
+ 'HKEY_USERS', 'HKLM', 'HKPD', 'HKU', 'IDABORT', 'IDCANCEL', 'IDIGNORE', 'IDNO', 'IDOK', 'IDRETRY', 'IDYES',
+ 'ifdiff', 'ifnewer', 'instfiles', 'lastused', 'leave', 'license', 'listonly', 'lzma', 'manual',
+ 'MB_ABORTRETRYIGNORE', 'MB_DEFBUTTON1', 'MB_DEFBUTTON2', 'MB_DEFBUTTON3', 'MB_DEFBUTTON4',
+ 'MB_ICONEXCLAMATION', 'MB_ICONINFORMATION', 'MB_ICONQUESTION', 'MB_ICONSTOP', 'MB_OK', 'MB_OKCANCEL',
+ 'MB_RETRYCANCEL', 'MB_RIGHT', 'MB_SETFOREGROUND', 'MB_TOPMOST', 'MB_YESNO', 'MB_YESNOCANCEL', 'nevershow',
+ 'none', 'normal', 'off', 'OFFLINE', 'on', 'radiobuttons', 'READONLY', 'RO', 'SHCTX', 'SHELL_CONTEXT', 'show',
+ 'silent', 'silentlog', 'SW_HIDE', 'SW_SHOWMAXIMIZED', 'SW_SHOWMINIMIZED', 'SW_SHOWNORMAL', 'SYSTEM',
+ 'textonly', 'true', 'try', 'uninstConfirm', 'zlib'
+ ),
+ 6 => array(
+ '/a', '/components', '/COMPONENTSONLYONCUSTOM', '/CUSTOMSTRING', '/e', '/FILESONLY', '/FINAL', '/gray', '/GLOBAL',
+ '/ifempty', '/IMGID', '/ITALIC', '/lang', '/NOCUSTOM', '/nonfatal', '/NOUNLOAD', '/oname', '/r', '/REBOOTOK',
+ '/RESIZETOFIT', '/SOLID', '/SD', '/SHORT', '/silent', '/STRIKE', '/TIMEOUT', '/TRIMCENTER', '/TRIMLEFT',
+ '/TRIMRIGHT', '/UNDERLINE', '/windows', '/x'
+ ),
+ 7 => array(
+ '.onGUIEnd', '.onGUIInit', '.onInit', '.onInstFailed', '.onInstSuccess', '.onMouseOverSection',
+ '.onRebootFailed', '.onSelChange', '.onUserAbort', '.onVerifyInstDir', 'un.onGUIEnd', 'un.onGUIInit',
+ 'un.onInit', 'un.onRebootFailed', 'un.onUninstFailed', 'un.onUninstSuccess', 'un.onUserAbort'
+ ),
+ 8 => array(
+ 'MUI.nsh', '"${NSISDIR}\Contrib\Modern UI\System.nsh"', 'MUI_SYSVERSION', 'MUI_ICON', 'MUI_UNICON',
+ 'MUI_HEADERIMAGE', 'MUI_HEADERIMAGE_BITMAP', 'MUI_HEADERIMAGE_BITMAP_NOSTRETCH', 'MUI_HEADERIMAGE_BITMAP_RTL',
+ 'MUI_HEADERIMAGE_BITMAP_RTL_NOSTRETCH', 'MUI_HEADERIMAGE_UNBITMAP', 'MUI_HEADERIMAGE_UNBITMAP_NOSTRETCH',
+ 'MUI_HEADERIMAGE_UNBITMAP_RTL', 'MUI_HEADERIMAGE_UNBITMAP_RTL_NOSTRETCH', 'MUI_HEADERIMAGE_RIGHT', 'MUI_BGCOLOR',
+ 'MUI_UI', 'MUI_UI_HEADERIMAGE', 'MUI_UI_HEADERIMAGE_RIGHT', 'MUI_UI_COMPONENTSPAGE_SMALLDESC',
+ 'MUI_UI_COMPONENTSPAGE_NODESC', 'MUI_WELCOMEFINISHPAGE_BITMAP', 'MUI_WELCOMEFINISHPAGE_BITMAP_NOSTRETCH',
+ 'MUI_WELCOMEFINISHPAGE_INI', 'MUI_UNWELCOMEFINISHPAGE_BITMAP', 'MUI_UNWELCOMEFINISHPAGE_BITMAP_NOSTRETCH',
+ 'MUI_UNWELCOMEFINISHPAGE_INI', 'MUI_LICENSEPAGE_BGCOLOR', 'MUI_COMPONENTSPAGE_CHECKBITMAP',
+ 'MUI_COMPONENTSPAGE_SMALLDESC', 'MUI_COMPONENTSPAGE_NODESC', 'MUI_INSTFILESPAGE_COLORS',
+ 'MUI_INSTFILESPAGE_PROGRESSBAR', 'MUI_FINISHPAGE_NOAUTOCLOSE', 'MUI_UNFINISHPAGE_NOAUTOCLOSE',
+ 'MUI_ABORTWARNING', 'MUI_ABORTWARNING_TEXT', 'MUI_UNABORTWARNING', 'MUI_UNABORTWARNING_TEXT',
+ 'MUI_PAGE_WELCOME', 'MUI_PAGE_LICENSE', 'MUI_PAGE_COMPONENTS', 'MUI_PAGE_DIRECTORY',
+ 'MUI_PAGE_STARTMENU', 'MUI_PAGE_INSTFILES', 'MUI_PAGE_FINISH', 'MUI_UNPAGE_WELCOME',
+ 'MUI_UNPAGE_CONFIRM', 'MUI_UNPAGE_LICENSE', 'MUI_UNPAGE_COMPONENTS', 'MUI_UNPAGE_DIRECTORY',
+ 'MUI_UNPAGE_INSTFILES', 'MUI_UNPAGE_FINISH', 'MUI_PAGE_HEADER_TEXT', 'MUI_PAGE_HEADER_SUBTEXT',
+ 'MUI_WELCOMEPAGE_TITLE', 'MUI_WELCOMEPAGE_TITLE_3LINES', 'MUI_WELCOMEPAGE_TEXT',
+ 'MUI_LICENSEPAGE_TEXT_TOP', 'MUI_LICENSEPAGE_TEXT_BOTTOM', 'MUI_LICENSEPAGE_BUTTON',
+ 'MUI_LICENSEPAGE_CHECKBOX', 'MUI_LICENSEPAGE_CHECKBOX_TEXT', 'MUI_LICENSEPAGE_RADIOBUTTONS',
+ 'MUI_LICENSEPAGE_RADIOBUTTONS_TEXT_ACCEPT', 'MUI_LICENSEPAGE_RADIOBUTTONS_TEXT_DECLINE',
+ 'MUI_COMPONENTSPAGE_TEXT_TOP', 'MUI_COMPONENTSPAGE_TEXT_COMPLIST', 'MUI_COMPONENTSPAGE_TEXT_INSTTYPE',
+ 'MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_TITLE', 'MUI_COMPONENTSPAGE_TEXT_DESCRIPTION_INFO',
+ 'MUI_DIRECTORYPAGE_TEXT_TOP', 'MUI_DIRECTORYPAGE_TEXT_DESTINATION', 'MUI_DIRECTORYPAGE_VARIABLE',
+ 'MUI_DIRECTORYPAGE_VERIFYONLEAVE', 'MUI_STARTMENU_WRITE_BEGIN', 'MUI_STARTMENU_WRITE_END',
+ 'MUI_STARTMENUPAGE_TEXT_TOP', 'MUI_STARTMENUPAGE_TEXT_CHECKBOX', 'MUI_STARTMENUPAGE_DEFAULTFOLDER',
+ 'MUI_STARTMENUPAGE_NODISABLE', 'MUI_STARTMENUPAGE_REGISTRY_ROOT', 'MUI_STARTMENUPAGE_REGISTRY_KEY',
+ 'MUI_STARTMENUPAGE_REGISTRY_VALUENAME', 'MUI_INSTFILESPAGE_FINISHHEADER_TEXT',
+ 'MUI_INSTFILESPAGE_FINISHHEADER_SUBTEXT', 'MUI_INSTFILESPAGE_ABORTHEADER_TEXT',
+ 'MUI_INSTFILESPAGE_ABORTHEADER_SUBTEXT', 'MUI_FINISHPAGE_TITLE', 'MUI_FINISHPAGE_TITLE_3LINES',
+ 'MUI_FINISHPAGE_TEXT', 'MUI_FINISHPAGE_TEXT_LARGE', 'MUI_FINISHPAGE_BUTTON',
+ 'MUI_FINISHPAGE_TEXT_REBOOT', 'MUI_FINISHPAGE_TEXT_REBOOTNOW', 'MUI_FINISHPAGE_TEXT_REBOOTLATER',
+ 'MUI_FINISHPAGE_RUN', 'MUI_FINISHPAGE_RUN_TEXT', 'MUI_FINISHPAGE_RUN_PARAMETERS',
+ 'MUI_FINISHPAGE_RUN_NOTCHECKED', 'MUI_FINISHPAGE_RUN_FUNCTION', 'MUI_FINISHPAGE_SHOWREADME',
+ 'MUI_FINISHPAGE_SHOWREADME_TEXT', 'MUI_FINISHPAGE_SHOWREADME_NOTCHECKED',
+ 'MUI_FINISHPAGE_SHOWREADME_FUNCTION', 'MUI_FINISHPAGE_LINK', 'MUI_FINISHPAGE_LINK_LOCATION',
+ 'MUI_FINISHPAGE_LINK_COLOR', 'MUI_FINISHPAGE_NOREBOOTSUPPORT', 'MUI_UNCONFIRMPAGE_TEXT_TOP',
+ 'MUI_UNCONFIRMPAGE_TEXT_LOCATION', 'MUI_LANGUAGE', 'MUI_LANGDLL_DISPLAY',
+ 'MUI_LANGDLL_REGISTRY_ROOT', 'MUI_LANGDLL_REGISTRY_KEY', 'MUI_LANGDLL_REGISTRY_VALUENAME',
+ 'MUI_LANGDLL_WINDOWTITLE', 'MUI_LANGDLL_INFO', 'MUI_LANGDLL_ALWAYSSHOW',
+ 'MUI_RESERVEFILE_INSTALLOPTIONS', 'MUI_RESERVEFILE_LANGDLL', 'MUI_FUNCTION_DESCRIPTION_BEGIN',
+ 'MUI_DESCRIPTION_TEXT', 'MUI_FUNCTION_DESCRIPTION_END', 'MUI_INSTALLOPTIONS_EXTRACT',
+ 'MUI_INSTALLOPTIONS_EXTRACT_AS', 'MUI_HEADER_TEXT', 'MUI_INSTALLOPTIONS_DISPLAY',
+ 'MUI_INSTALLOPTIONS_INITDIALOG', 'MUI_INSTALLOPTIONS_SHOW',
+ 'MUI_INSTALLOPTIONS_DISPLAY_RETURN', 'MUI_INSTALLOPTIONS_SHOW_RETURN',
+ 'MUI_INSTALLOPTIONS_READ', 'MUI_INSTALLOPTIONS_WRITE',
+ 'MUI_CUSTOMFUNCTION_GUIINIT', 'MUI_CUSTOMFUNCTION_UNGUIINIT',
+ 'MUI_CUSTOMFUNCTION_ABORT', 'MUI_CUSTOMFUNCTION_UNABORT',
+ 'MUI_PAGE_CUSTOMFUNCTION_PRE', 'MUI_PAGE_CUSTOMFUNCTION_SHOW', 'MUI_PAGE_CUSTOMFUNCTION_LEAVE',
+ 'MUI_WELCOMEFINISHPAGE_CUSTOMFUNCTION_INIT'
+ ),
+ 9 => array(
+ 'LogicLib.nsh', '${LOGICLIB}', 'LOGICLIB_STRCMP', 'LOGICLIB_INT64CMP', 'LOGICLIB_SECTIONCMP', '${If}', '${Unless}',
+ '${ElseIf}', '${ElseUnless}', '${Else}', '${EndIf}', '${EndUnless}', '${AndIf}', '${AndUnless}',
+ '${OrIf}', '${OrUnless}', '${IfThen}', '${IfCmd}', '${Select}', '${Case2}', '${Case3}',
+ '${Case4}', '${Case5}', '${CaseElse}', '${Default}', '${EndSelect}', '${Switch}',
+ '${Case}', '${EndSwitch}', '${Do}', '${DoWhile}', '${UntilWhile}', '${Continue}', '${Break}',
+ '${Loop}', '${LoopWhile}', '${LoopUntil}', '${While}', '${ExitWhile}', '${EndWhile}', '${For}',
+ '${ForEach}', '${ExitFor}', '${Next}', '${Abort}', '${Errors}', '${RebootFlag}', '${Silent}',
+ '${FileExists}', '${Cmd}', '${SectionIsSelected}', '${SectionIsSectionGroup}',
+ '${SectionIsSectionGroupEnd}', '${SectionIsBold}', '${SectionIsReadOnly}',
+ '${SectionIsExpanded}', '${SectionIsPartiallySelected}'
+ ),
+ 10 => array(
+ 'StrFunc.nsh', '${STRFUNC}', '${StrCase}', '${StrClb}', '${StrIOToNSIS}', '${StrLoc}', '${StrNSISToIO}', '${StrRep}',
+ '${StrSort}', '${StrStr}', '${StrStrAdv}', '${StrTok}', '${StrTrimNewLines}'
+ ),
+ 11 => array(
+ 'UpgradeDLL.nsh', 'UPGRADEDLL_INCLUDED', 'UpgradeDLL'
+ ),
+ 12 => array(
+ 'Sections.nsh', 'SECTIONS_INCLUDED', '${SF_SELECTED}', '${SF_SECGRP}', '${SF_SUBSEC}', '${SF_SECGRPEND}',
+ '${SF_SUBSECEND}', '${SF_BOLD}', '${SF_RO}', '${SF_EXPAND}', '${SF_PSELECTED}', '${SF_TOGGLED}',
+ '${SF_NAMECHG}', '${SECTION_OFF}', 'SelectSection', 'UnselectSection', 'ReverseSection',
+ 'StartRadioButtons', 'RadioButton', 'EndRadioButtons', '${INSTTYPE_0}', '${INSTTYPE_1}', '${INSTTYPE_2}',
+ '${INSTTYPE_3}', '${INSTTYPE_4}', '${INSTTYPE_5}', '${INSTTYPE_6}', '${INSTTYPE_7}', '${INSTTYPE_8}',
+ '${INSTTYPE_9}', '${INSTTYPE_10}', '${INSTTYPE_11}', '${INSTTYPE_12}', '${INSTTYPE_13}', '${INSTTYPE_14}',
+ '${INSTTYPE_15}', '${INSTTYPE_16}', '${INSTTYPE_17}', '${INSTTYPE_18}', '${INSTTYPE_19}', '${INSTTYPE_20}',
+ '${INSTTYPE_21}', '${INSTTYPE_22}', '${INSTTYPE_23}', '${INSTTYPE_24}', '${INSTTYPE_25}', '${INSTTYPE_26}',
+ '${INSTTYPE_27}', '${INSTTYPE_28}', '${INSTTYPE_29}', '${INSTTYPE_30}', '${INSTTYPE_31}', '${INSTTYPE_32}',
+ 'SetSectionInInstType', 'ClearSectionInInstType', 'SetSectionFlag', 'ClearSectionFlag', 'SectionFlagIsSet'
+ ),
+ 13 => array(
+ 'Colors.nsh', 'WHITE', 'BLACK', 'YELLOW', 'RED', 'GREEN', 'BLUE', 'MAGENTA', 'CYAN', 'rgb2hex'
+ ),
+ 14 => array(
+ 'FileFunc.nsh', '${Locate}', '${GetSize}', '${DriveSpace}', '${GetDrives}', '${GetTime}', '${GetFileAttributes}', '${GetFileVersion}', '${GetExeName}', '${GetExePath}', '${GetParameters}', '${GetOptions}', '${GetRoot}', '${GetParent}', '${GetFileName}', '${GetBaseName}', '${GetFileExt}', '${BannerTrimPath}', '${DirState}', '${RefreshShellIcons}'
+ ),
+ 15 => array(
+ 'TextFunc.nsh', '${LineFind}', '${LineRead}', '${FileReadFromEnd}', '${LineSum}', '${FileJoin}', '${TextCompare}', '${ConfigRead}', '${ConfigWrite}', '${FileRecode}', '${TrimNewLines}'
+ ),
+ 16 => array(
+ 'WordFunc.nsh', '${WordFind}', '${WordFind2X}', '${WordFind3X}', '${WordReplace}', '${WordAdd}', '${WordInsert}', '${StrFilter}', '${VersionCompare}', '${VersionConvert}'
+ )
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ 8 => false,
+ 9 => false,
+ 10 => false,
+ 11 => false,
+ 12 => false,
+ 13 => false,
+ 14 => false,
+ 15 => false,
+ 16 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000066; font-weight:bold;',
+ 2 => 'color: #000066;',
+ 3 => 'color: #003366;',
+ 4 => 'color: #000099;',
+ 5 => 'color: #ff6600;',
+ 6 => 'color: #ff6600;',
+ 7 => 'color: #006600;',
+ 8 => 'color: #006600;',
+ 9 => 'color: #006600;',
+ 10 => 'color: #006600;',
+ 11 => 'color: #006600;',
+ 12 => 'color: #006600;',
+ 13 => 'color: #006600;',
+ 14 => 'color: #006600;',
+ 15 => 'color: #006600;',
+ 16 => 'color: #006600;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #660066; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => ''
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #660066;'
+ ),
+ 'NUMBERS' => array(
+ 0 => ''
+ ),
+ 'METHODS' => array(
+ 0 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => ''
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #660000;',
+ 1 => 'color: #660000;',
+ 2 => 'color: #660000;',
+ 3 => 'color: #660000;',
+ 4 => 'color: #660000;',
+ 5 => 'color: #660000;',
+ 6 => 'color: #660000;',
+ 7 => 'color: #000099;',
+ 8 => 'color: #003399;'
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+ 9 => '',
+ 10 => '',
+ 11 => '',
+ 12 => '',
+ 13 => '',
+ 14 => '',
+ 15 => '',
+ 16 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => '\$\$',
+ 1 => '\$\\r',
+ 2 => '\$\\n',
+ 3 => '\$\\t',
+ 4 => '\$[a-zA-Z0-9_]+',
+ 5 => '\$\{.{1,256}\}',
+ 6 => '\$\\\(.{1,256}\\\)',
+ 7 => array(
+ GESHI_SEARCH => '([^:\/\\\*\?\"\<\>(?:<PIPE>)\s]*?)(::)([^:\/\\\*\?\"\<\>(?:<PIPE>)\s]*?)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '\\2\\3'
+ ),
+ 8 => array(
+ GESHI_SEARCH => '([^:\/\\\*\?\"\<\>(?:<PIPE>)\s]*?)(::)([^:\/\\\*\?\"\<\>(?:<PIPE>)]*?\s)',
+ GESHI_REPLACE => '\\3',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1\\2',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/oberon2.php b/platform/www/vendor/geshi/geshi/src/geshi/oberon2.php
new file mode 100644
index 0000000..38a1915
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/oberon2.php
@@ -0,0 +1,133 @@
+<?php
+/*************************************************************************************
+ * oberon2.php
+ * ----------
+ * Author: mbishop (mbishop@esoteriq.org)
+ * Copyright: (c) 2009 mbishop (mbishop@esoteriq.org)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/02/10
+ *
+ * Oberon-2 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ *
+ * TODO
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Oberon-2',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('(*' => '*)'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array("''"),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'ARRAY', 'BEGIN', 'BY', 'CASE',
+ 'CONST', 'DIV', 'DO', 'ELSE', 'ELSIF', 'END',
+ 'EXIT', 'FOR', 'IF', 'IMPORT', 'IN', 'IS',
+ 'LOOP', 'MOD', 'MODULE', 'OF',
+ 'OR', 'POINTER', 'PROCEDURE', 'RECORD',
+ 'REPEAT', 'RETURN', 'THEN', 'TO',
+ 'TYPE', 'UNTIL', 'VAR', 'WHILE', 'WITH'
+ ),
+ 2 => array(
+ 'NIL', 'FALSE', 'TRUE',
+ ),
+ 3 => array(
+ 'ABS', 'ASH', 'ASSERT', 'CAP', 'CHR', 'COPY', 'DEC',
+ 'ENTIER', 'EXCL', 'HALT', 'INC', 'INCL', 'LEN',
+ 'LONG', 'MAX', 'MIN', 'NEW', 'ODD', 'ORD', 'SHORT', 'SIZE'
+ ),
+ 4 => array(
+ 'BOOLEAN', 'CHAR', 'SHORTINT', 'LONGINT',
+ 'INTEGER', 'LONGREAL', 'REAL', 'SET', 'PTR'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ ',', ':', '=', '+', '-', '*', '/', '#', '~'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #000066; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ 'HARD' => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0066ee;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/objc.php b/platform/www/vendor/geshi/geshi/src/geshi/objc.php
new file mode 100644
index 0000000..0f6ee1d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/objc.php
@@ -0,0 +1,356 @@
+<?php
+/*************************************************************************************
+ * objc.php
+ * --------
+ * Author: M. Uli Kusterer (witness.of.teachtext@gmx.net)
+ * Contributors: Quinn Taylor (quinntaylor@mac.com)
+ * Copyright: (c) 2008 Quinn Taylor, 2004 M. Uli Kusterer, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/04
+ *
+ * Objective-C language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/11 (1.0.8)
+ * - Added support for @ before strings being highlighted
+ * 2008/06/10 (1.0.7.22)
+ * - Added keywords for Objective-C 2.0 (Leopard+).
+ * - Changed colors to match Xcode 3 highlighting more closely.
+ * - Updated API for AppKit and Foundation; added CoreData classes.
+ * - Updated URLs for AppKit and Foundation; split classes and protocols.
+ * - Sorted all keyword group in reverse-alpha order for correct matching.
+ * - Changed all keyword groups to be case-sensitive.
+ * 2004/11/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Objective-C',
+ 'COMMENT_SINGLE' => array(
+ //Compiler directives
+ 1 => '#',
+ //Single line C-Comments
+ 2 => '//'
+ ),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Multiline Continuation for single-line comment
+ 2 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Pseudo-Highlighting of the @-sign before strings
+ 3 => "/@(?=\")/"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'"),
+ 'ESCAPE_CHAR' => '\\',
+
+ 'KEYWORDS' => array(
+ // Objective-C keywords
+ 1 => array(
+ 'while', 'switch', 'return', 'in', 'if', 'goto', 'foreach', 'for',
+ 'else', 'do', 'default', 'continue', 'case', '@try', '@throw',
+ '@synthesize', '@synchronized', '@selector', '@public', '@protocol',
+ '@protected', '@property', '@private', '@interface',
+ '@implementation', '@finally', '@end', '@encode', '@defs', '@class',
+ '@catch'
+ ),
+ // Macros and constants
+ 2 => array(
+ 'YES', 'USHRT_MAX', 'ULONG_MAX', 'UINT_MAX', 'UCHAR_MAX', 'true',
+ 'TMP_MAX', 'stdout', 'stdin', 'stderr', 'SIGTERM', 'SIGSEGV',
+ 'SIGINT', 'SIGILL', 'SIG_IGN', 'SIGFPE', 'SIG_ERR', 'SIG_DFL',
+ 'SIGABRT', 'SHRT_MIN', 'SHRT_MAX', 'SEEK_SET', 'SEEK_END',
+ 'SEEK_CUR', 'SCHAR_MIN', 'SCHAR_MAX', 'RAND_MAX', 'NULL',
+ 'NO', 'nil', 'Nil', 'L_tmpnam', 'LONG_MIN', 'LONG_MAX',
+ 'LDBL_MIN_EXP', 'LDBL_MIN', 'LDBL_MAX_EXP', 'LDBL_MAX',
+ 'LDBL_MANT_DIG', 'LDBL_EPSILON', 'LDBL_DIG', 'INT_MIN', 'INT_MAX',
+ 'HUGE_VAL', 'FOPEN_MAX', 'FLT_ROUNDS', 'FLT_RADIX', 'FLT_MIN_EXP',
+ 'FLT_MIN', 'FLT_MAX_EXP', 'FLT_MAX', 'FLT_MANT_DIG', 'FLT_EPSILON',
+ 'FLT_DIG', 'FILENAME_MAX', 'false', 'EXIT_SUCCESS', 'EXIT_FAILURE',
+ 'errno', 'ERANGE', 'EOF', 'enum', 'EDOM', 'DBL_MIN_EXP', 'DBL_MIN',
+ 'DBL_MAX_EXP', 'DBL_MAX', 'DBL_MANT_DIG', 'DBL_EPSILON', 'DBL_DIG',
+ 'CLOCKS_PER_SEC', 'CHAR_MIN', 'CHAR_MAX', 'CHAR_BIT', 'BUFSIZ',
+ 'break'
+ ),
+ // C standard library functions
+ 3 => array(
+ 'vsprintf', 'vprintf', 'vfprintf', 'va_start', 'va_end', 'va_arg',
+ 'ungetc', 'toupper', 'tolower', 'tmpname', 'tmpfile', 'time',
+ 'tanh', 'tan', 'system', 'strxfrm', 'strtoul', 'strtol', 'strtok',
+ 'strtod', 'strstr', 'strspn', 'strrchr', 'strpbrk', 'strncpy',
+ 'strncmp', 'strncat', 'strlen', 'strftime', 'strerror', 'strcspn',
+ 'strcpy', 'strcoll', 'strcmp', 'strchr', 'strcat', 'sscanf',
+ 'srand', 'sqrt', 'sprintf', 'snprintf', 'sizeof', 'sinh', 'sin',
+ 'setvbuf', 'setjmp', 'setbuf', 'scanf', 'rewind', 'rename',
+ 'remove', 'realloc', 'rand', 'qsort', 'puts', 'putchar', 'putc',
+ 'printf', 'pow', 'perror', 'offsetof', 'modf', 'mktime', 'memset',
+ 'memmove', 'memcpy', 'memcmp', 'memchr', 'malloc', 'longjmp',
+ 'log10', 'log', 'localtime', 'ldiv', 'ldexp', 'labs', 'isxdigit',
+ 'isupper', 'isspace', 'ispunct', 'isprint', 'islower',
+ 'isgraph', 'isdigit', 'iscntrl', 'isalpha', 'isalnum', 'gmtime',
+ 'gets', 'getenv', 'getchar', 'getc', 'fwrite', 'ftell', 'fsetpos',
+ 'fseek', 'fscanf', 'frexp', 'freopen', 'free', 'fread', 'fputs',
+ 'fputc', 'fprintf', 'fopen', 'fmod', 'floor', 'fgets', 'fgetpos',
+ 'fgetc', 'fflush', 'ferror', 'feof', 'fclose', 'fabs', 'exp',
+ 'exit', 'div', 'difftime', 'ctime', 'cosh', 'cos', 'clock',
+ 'clearerr', 'ceil', 'calloc', 'bsearch', 'atol', 'atoi', 'atof',
+ 'atexit', 'atan2', 'atan', 'assert', 'asin', 'asctime', 'acos',
+ 'abs', 'abort'
+ ),
+ // Data types (C, Objective-C, Cocoa)
+ 4 => array(
+ 'volatile', 'void', 'va_list', 'unsigned', 'union', 'typedef', 'tm',
+ 'time_t', 'struct', 'string', 'static', 'size_t',
+ 'signed', 'signal', 'short', 'SEL', 'register', 'raise',
+ 'ptrdiff_t', 'NSZone', 'NSRect', 'NSRange', 'NSPoint', 'long',
+ 'ldiv_t', 'jmp_buf', 'int', 'IMP', 'id', 'fpos_t', 'float', 'FILE',
+ 'extern', 'double', 'div_t', 'const', 'clock_t', 'Class', 'char',
+ 'BOOL', 'auto'
+ ),
+ // Foundation classes
+ 5 => array(
+ 'NSXMLParser', 'NSXMLNode', 'NSXMLElement', 'NSXMLDTDNode',
+ 'NSXMLDTD', 'NSXMLDocument', 'NSWhoseSpecifier',
+ 'NSValueTransformer', 'NSValue', 'NSUserDefaults', 'NSURLResponse',
+ 'NSURLRequest', 'NSURLProtocol', 'NSURLProtectionSpace',
+ 'NSURLHandle', 'NSURLDownload', 'NSURLCredentialStorage',
+ 'NSURLCredential', 'NSURLConnection', 'NSURLCache',
+ 'NSURLAuthenticationChallenge', 'NSURL', 'NSUniqueIDSpecifier',
+ 'NSUndoManager', 'NSUnarchiver', 'NSTimeZone', 'NSTimer',
+ 'NSThread', 'NSTask', 'NSString', 'NSStream', 'NSSpellServer',
+ 'NSSpecifierTest', 'NSSortDescriptor', 'NSSocketPortNameServer',
+ 'NSSocketPort', 'NSSetCommand', 'NSSet', 'NSSerializer',
+ 'NSScriptWhoseTest', 'NSScriptSuiteRegistry',
+ 'NSScriptObjectSpecifier', 'NSScriptExecutionContext',
+ 'NSScriptCommandDescription', 'NSScriptCommand',
+ 'NSScriptCoercionHandler', 'NSScriptClassDescription', 'NSScanner',
+ 'NSRunLoop', 'NSRelativeSpecifier', 'NSRecursiveLock',
+ 'NSRangeSpecifier', 'NSRandomSpecifier', 'NSQuitCommand', 'NSProxy',
+ 'NSProtocolChecker', 'NSPropertySpecifier',
+ 'NSPropertyListSerialization', 'NSProcessInfo', 'NSPredicate',
+ 'NSPositionalSpecifier', 'NSPortNameServer', 'NSPortMessage',
+ 'NSPortCoder', 'NSPort', 'NSPointerFunctions', 'NSPointerArray',
+ 'NSPipe', 'NSOutputStream', 'NSOperationQueue', 'NSOperation',
+ 'NSObject', 'NSNumberFormatter', 'NSNumber', 'NSNull',
+ 'NSNotificationQueue', 'NSNotificationCenter', 'NSNotification',
+ 'NSNetServiceBrowser', 'NSNetService', 'NSNameSpecifier',
+ 'NSMutableURLRequest', 'NSMutableString', 'NSMutableSet',
+ 'NSMutableIndexSet', 'NSMutableDictionary', 'NSMutableData',
+ 'NSMutableCharacterSet', 'NSMutableAttributedString',
+ 'NSMutableArray', 'NSMoveCommand', 'NSMiddleSpecifier',
+ 'NSMethodSignature', 'NSMetadataQueryResultGroup',
+ 'NSMetadataQueryAttributeValueTuple', 'NSMetadataQuery',
+ 'NSMetadataItem', 'NSMessagePortNameServer', 'NSMessagePort',
+ 'NSMapTable', 'NSMachPort', 'NSMachBootstrapServer',
+ 'NSLogicalTest', 'NSLock', 'NSLocale', 'NSKeyedUnarchiver',
+ 'NSKeyedArchiver', 'NSInvocationOperation', 'NSInvocation',
+ 'NSInputStream', 'NSIndexSpecifier', 'NSIndexSet', 'NSIndexPath',
+ 'NSHTTPURLResponse', 'NSHTTPCookieStorage', 'NSHTTPCookie',
+ 'NSHost', 'NSHashTable', 'NSGetCommand', 'NSGarbageCollector',
+ 'NSFormatter', 'NSFileManager', 'NSFileHandle', 'NSExpression',
+ 'NSExistsCommand', 'NSException', 'NSError', 'NSEnumerator',
+ 'NSDistributedNotificationCenter', 'NSDistributedLock',
+ 'NSDistantObjectRequest', 'NSDistantObject',
+ 'NSDirectoryEnumerator', 'NSDictionary', 'NSDeserializer',
+ 'NSDeleteCommand', 'NSDecimalNumberHandler', 'NSDecimalNumber',
+ 'NSDateFormatter', 'NSDateComponents', 'NSDate', 'NSData',
+ 'NSCreateCommand', 'NSCountedSet', 'NSCountCommand', 'NSConnection',
+ 'NSConditionLock', 'NSCondition', 'NSCompoundPredicate',
+ 'NSComparisonPredicate', 'NSCoder', 'NSCloseCommand',
+ 'NSCloneCommand', 'NSClassDescription', 'NSCharacterSet',
+ 'NSCalendarDate', 'NSCalendar', 'NSCachedURLResponse', 'NSBundle',
+ 'NSAutoreleasePool', 'NSAttributedString', 'NSAssertionHandler',
+ 'NSArray', 'NSArchiver', 'NSAppleScript', 'NSAppleEventManager',
+ 'NSAppleEventDescriptor', 'NSAffineTransform'
+ ),
+ // Foundation protocols
+ 6 => array(
+ 'NSURLProtocolClient', 'NSURLHandleClient', 'NSURLClient',
+ 'NSURLAuthenticationChallengeSender', 'NSScriptObjectSpecifiers',
+ 'NSScriptKeyValueCoding', 'NSScriptingComparisonMethods',
+ 'NSObjCTypeSerializationCallBack', 'NSMutableCopying',
+ 'NSLocking', 'NSKeyValueObserving', 'NSKeyValueCoding',
+ 'NSFastEnumeration', 'NSErrorRecoveryAttempting',
+ 'NSDecimalNumberBehaviors', 'NSCopying', 'NSComparisonMethods',
+ 'NSCoding'
+ ),
+ // AppKit classes
+ 7 => array(
+ 'NSWorkspace', 'NSWindowController', 'NSWindow', 'NSViewController',
+ 'NSViewAnimation', 'NSView', 'NSUserDefaultsController',
+ 'NSTypesetter', 'NSTreeNode', 'NSTreeController', 'NSTrackingArea',
+ 'NSToolbarItemGroup', 'NSToolbarItem', 'NSToolbar',
+ 'NSTokenFieldCell', 'NSTokenField', 'NSTextView',
+ 'NSTextTableBlock', 'NSTextTable', 'NSTextTab', 'NSTextStorage',
+ 'NSTextList', 'NSTextFieldCell', 'NSTextField', 'NSTextContainer',
+ 'NSTextBlock', 'NSTextAttachmentCell', 'NSTextAttachment', 'NSText',
+ 'NSTabViewItem', 'NSTabView', 'NSTableView', 'NSTableHeaderView',
+ 'NSTableHeaderCell', 'NSTableColumn', 'NSStepperCell', 'NSStepper',
+ 'NSStatusItem', 'NSStatusBar', 'NSSplitView', 'NSSpellChecker',
+ 'NSSpeechSynthesizer', 'NSSpeechRecognizer', 'NSSound',
+ 'NSSliderCell', 'NSSlider', 'NSSimpleHorizontalTypesetter',
+ 'NSShadow', 'NSSegmentedControl', 'NSSegmentedCell',
+ 'NSSecureTextFieldCell', 'NSSecureTextField', 'NSSearchFieldCell',
+ 'NSSearchField', 'NSScrollView', 'NSScroller', 'NSScreen',
+ 'NSSavePanel', 'NSRulerView', 'NSRulerMarker', 'NSRuleEditor',
+ 'NSResponder', 'NSQuickDrawView', 'NSProgressIndicator',
+ 'NSPrintPanel', 'NSPrintOperation', 'NSPrintInfo', 'NSPrinter',
+ 'NSPredicateEditorRowTemplate', 'NSPredicateEditor',
+ 'NSPopUpButtonCell', 'NSPopUpButton', 'NSPICTImageRep',
+ 'NSPersistentDocument', 'NSPDFImageRep', 'NSPathControl',
+ 'NSPathComponentCell', 'NSPathCell', 'NSPasteboard',
+ 'NSParagraphStyle', 'NSPanel', 'NSPageLayout', 'NSOutlineView',
+ 'NSOpenPanel', 'NSOpenGLView', 'NSOpenGLPixelFormat',
+ 'NSOpenGLPixelBuffer', 'NSOpenGLContext', 'NSObjectController',
+ 'NSNibOutletConnector', 'NSNibControlConnector', 'NSNibConnector',
+ 'NSNib', 'NSMutableParagraphStyle', 'NSMovieView', 'NSMovie',
+ 'NSMenuView', 'NSMenuItemCell', 'NSMenuItem', 'NSMenu', 'NSMatrix',
+ 'NSLevelIndicatorCell', 'NSLevelIndicator', 'NSLayoutManager',
+ 'NSInputServer', 'NSInputManager', 'NSImageView', 'NSImageRep',
+ 'NSImageCell', 'NSImage', 'NSHelpManager', 'NSGraphicsContext',
+ 'NSGradient', 'NSGlyphInfo', 'NSGlyphGenerator', 'NSFormCell',
+ 'NSForm', 'NSFontPanel', 'NSFontManager', 'NSFontDescriptor',
+ 'NSFont', 'NSFileWrapper', 'NSEvent', 'NSEPSImageRep', 'NSDrawer',
+ 'NSDocumentController', 'NSDocument', 'NSDockTile',
+ 'NSDictionaryController', 'NSDatePickerCell', 'NSDatePicker',
+ 'NSCustomImageRep', 'NSCursor', 'NSController', 'NSControl',
+ 'NSComboBoxCell', 'NSComboBox', 'NSColorWell', 'NSColorSpace',
+ 'NSColorPicker', 'NSColorPanel', 'NSColorList', 'NSColor',
+ 'NSCollectionViewItem', 'NSCollectionView', 'NSClipView',
+ 'NSCIImageRep', 'NSCell', 'NSCachedImageRep', 'NSButtonCell',
+ 'NSButton', 'NSBrowserCell', 'NSBrowser', 'NSBox',
+ 'NSBitmapImageRep', 'NSBezierPath', 'NSATSTypesetter',
+ 'NSArrayController', 'NSApplication', 'NSAnimationContext',
+ 'NSAnimation', 'NSAlert', 'NSActionCell'
+ ),
+ // AppKit protocols
+ 8 => array(
+ 'NSWindowScripting', 'NSValidatedUserInterfaceItem',
+ 'NSUserInterfaceValidations', 'NSToolTipOwner',
+ 'NSToolbarItemValidation', 'NSTextInput',
+ 'NSTableDataSource', 'NSServicesRequests',
+ 'NSPrintPanelAccessorizing', 'NSPlaceholders',
+ 'NSPathControlDelegate', 'NSPathCellDelegate',
+ 'NSOutlineViewDataSource', 'NSNibAwaking', 'NSMenuValidation',
+ 'NSKeyValueBindingCreation', 'NSInputServiceProvider',
+ 'NSInputServerMouseTracker', 'NSIgnoreMisspelledWords',
+ 'NSGlyphStorage', 'NSFontPanelValidation', 'NSEditorRegistration',
+ 'NSEditor', 'NSDraggingSource', 'NSDraggingInfo',
+ 'NSDraggingDestination', 'NSDictionaryControllerKeyValuePair',
+ 'NSComboBoxDataSource', 'NSComboBoxCellDataSource',
+ 'NSColorPickingDefault', 'NSColorPickingCustom', 'NSChangeSpelling',
+ 'NSAnimatablePropertyContainer', 'NSAccessibility'
+ ),
+ // CoreData classes
+ 9 => array(
+ 'NSRelationshipDescription', 'NSPropertyMapping',
+ 'NSPropertyDescription', 'NSPersistentStoreCoordinator',
+ 'NSPersistentStore', 'NSMigrationManager', 'NSMappingModel',
+ 'NSManagedObjectModel', 'NSManagedObjectID',
+ 'NSManagedObjectContext', 'NSManagedObject',
+ 'NSFetchRequestExpression', 'NSFetchRequest',
+ 'NSFetchedPropertyDescription', 'NSEntityMigrationPolicy',
+ 'NSEntityMapping', 'NSEntityDescription', 'NSAttributeDescription',
+ 'NSAtomicStoreCacheNode', 'NSAtomicStore'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true
+ ),
+ // Define the colors for the groups listed above
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #a61390;', // Objective-C keywords
+ 2 => 'color: #a61390;', // Macros and constants
+ 3 => 'color: #a61390;', // C standard library functions
+ 4 => 'color: #a61390;', // data types
+ 5 => 'color: #400080;', // Foundation classes
+ 6 => 'color: #2a6f76;', // Foundation protocols
+ 7 => 'color: #400080;', // AppKit classes
+ 8 => 'color: #2a6f76;', // AppKit protocols
+ 9 => 'color: #400080;' // CoreData classes
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #6e371a;', // Preprocessor directives
+ 2 => 'color: #11740a; font-style: italic;', // Normal C single-line comments
+ 3 => 'color: #bf1d1a;', // Q-sign in front of Strings
+ 'MULTI' => 'color: #11740a; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #2400d9;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #002200;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #bf1d1a;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #2400d9;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #002200;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAME}.html',
+ 4 => '',
+ 5 => 'http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/{FNAME}_Class/',
+ 6 => 'http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Protocols/{FNAME}_Protocol/',
+ 7 => 'http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Classes/{FNAME}_Class/',
+ 8 => 'http://developer.apple.com/documentation/Cocoa/Reference/ApplicationKit/Protocols/{FNAME}_Protocol/',
+ 9 => 'http://developer.apple.com/documentation/Cocoa/Reference/CoreDataFramework/Classes/{FNAME}_Class/'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/objeck.php b/platform/www/vendor/geshi/geshi/src/geshi/objeck.php
new file mode 100644
index 0000000..465db89
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/objeck.php
@@ -0,0 +1,114 @@
+<?php
+/*************************************************************************************
+ * objeck.php
+ * --------
+ * Author: Randy Hollines (objeck@gmail.com)
+ * Copyright: (c) 2010 Randy Hollines (http://code.google.com/p/objeck-lang/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/07/01
+ *
+ * Objeck Programming Language language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/07/26 (1.0.8.10)
+ * - Added new and missing keywords and symbols: 'String', 'each', '+=', '-=', '*=' and '/='.
+ * 2010/07/01 (1.0.8.9)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Objeck Programming Language',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array('#~' => '~#'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'virtual', 'if', 'else', 'do', 'while', 'use', 'bundle', 'native',
+ 'static', 'public', 'private', 'class', 'function', 'method',
+ 'select', 'other', 'enum', 'for', 'each', 'label', 'return', 'from'
+ ),
+ 2 => array(
+ 'Byte', 'Int', 'Nil', 'Float', 'Char', 'Bool', 'String'
+ ),
+ 3 => array(
+ 'true', 'false'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '(', ')', '{', '}', '[', ']', '+', '-', '*', '/', '%', '=', '<', '>', '&', '|', ':', ';', ',', '+=', '-=', '*=', '/=',
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #b1b100;',
+ 3 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '-&gt;'
+ ),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/ocaml-brief.php b/platform/www/vendor/geshi/geshi/src/geshi/ocaml-brief.php
new file mode 100644
index 0000000..1d7563e
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/ocaml-brief.php
@@ -0,0 +1,110 @@
+<?php
+/*************************************************************************************
+ * ocaml.php
+ * ----------
+ * Author: Flaie (fireflaie@gmail.com)
+ * Copyright: (c) 2005 Flaie, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/08/27
+ *
+ * OCaml (Objective Caml) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/08/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2005/08/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'OCaml (brief)',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('(*' => '*)'),
+ 'CASE_KEYWORDS' => 0,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => "",
+ 'KEYWORDS' => array(
+ /* main OCaml keywords */
+ 1 => array(
+ 'and', 'as', 'asr', 'begin', 'class', 'closed', 'constraint', 'do', 'done', 'downto', 'else',
+ 'end', 'exception', 'external', 'failwith', 'false', 'flush', 'for', 'fun', 'function', 'functor',
+ 'if', 'in', 'include', 'inherit', 'incr', 'land', 'let', 'load', 'los', 'lsl', 'lsr', 'lxor',
+ 'match', 'method', 'mod', 'module', 'mutable', 'new', 'not', 'of', 'open', 'option', 'or', 'parser',
+ 'private', 'ref', 'rec', 'raise', 'regexp', 'sig', 'struct', 'stdout', 'stdin', 'stderr', 'then',
+ 'to', 'true', 'try', 'type', 'val', 'virtual', 'when', 'while', 'with'
+ )
+ ),
+ /* highlighting symbols is really important in OCaml */
+ 'SYMBOLS' => array(
+ ';', '!', ':', '.', '=', '%', '^', '*', '-', '/', '+',
+ '>', '<', '(', ')', '[', ']', '&', '|', '#', "'"
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #06c; font-weight: bold;' /* nice blue */
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #5d478b; font-style: italic;' /* light purple */
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #6c6;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #3cb371;' /* nice green */
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #c6c;' /* pink */
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #060;' /* dark green */
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #a52a2a;' /* maroon */
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/ocaml.php b/platform/www/vendor/geshi/geshi/src/geshi/ocaml.php
new file mode 100644
index 0000000..e9e57ef
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/ocaml.php
@@ -0,0 +1,185 @@
+<?php
+/*************************************************************************************
+ * ocaml.php
+ * ----------
+ * Author: Flaie (fireflaie@gmail.com)
+ * Copyright: (c) 2005 Flaie, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/08/27
+ *
+ * OCaml (Objective Caml) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/03/29 (1.0.7.22)
+ * - Fixed warnings resulting from missing style information
+ * 2005/08/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2005/08/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'OCaml',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('(*' => '*)'),
+ 'COMMENT_REGEXP' => array(1 => '/\(\*(?:(?R)|.)+?\*\)/s'),
+ 'CASE_KEYWORDS' => 0,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => "",
+ 'KEYWORDS' => array(
+ /* main OCaml keywords */
+ 1 => array(
+ 'and', 'as', 'asr', 'begin', 'class', 'closed', 'constraint', 'do', 'done', 'downto', 'else',
+ 'end', 'exception', 'external', 'failwith', 'false', 'for', 'fun', 'function', 'functor',
+ 'if', 'in', 'include', 'inherit', 'incr', 'land', 'let', 'load', 'los', 'lsl', 'lsr', 'lxor',
+ 'match', 'method', 'mod', 'module', 'mutable', 'new', 'not', 'of', 'open', 'option', 'or', 'parser',
+ 'private', 'ref', 'rec', 'raise', 'regexp', 'sig', 'struct', 'stdout', 'stdin', 'stderr', 'then',
+ 'to', 'true', 'try', 'type', 'val', 'virtual', 'when', 'while', 'with'
+ ),
+ /* define names of main librarys, so we can link to it */
+ 2 => array(
+ 'Arg', 'Arith_status', 'Array', //'Array1', 'Array2', 'Array3',
+ 'ArrayLabels', 'Big_int', 'Bigarray', 'Buffer', 'Callback',
+ 'CamlinternalLazy', 'CamlinternalMod', 'CamlinternalOO', 'Char',
+ 'Complex', 'Condition', 'Dbm', 'Digest', 'Dynlink', 'Event',
+ 'Filename', 'Format', 'Gc', 'Genlex', 'Graphics', 'GraphicsX11',
+ 'Hashtbl', 'Int32', 'Int64', 'Lazy', 'Lexing', 'List', 'ListLabels',
+ 'Map', 'Marshal', 'MoreLabels', 'Mutex', 'Nativeint', 'Num', 'Obj',
+ 'Oo', 'Parsing', 'Pervasives', 'Printexc', 'Printf', 'Queue',
+ 'Random', 'Scanf', 'Set', 'Sort', 'Stack', 'StdLabels', 'Str',
+ 'Stream', 'String', 'StringLabels', 'Sys', 'Thread', 'ThreadUnix',
+ 'Tk', 'Unix', 'UnixLabels', 'Weak'
+ ),
+ /* just link to the Pervasives functions library, cause it's the default opened library when starting OCaml */
+ 3 => array(
+ 'abs', 'abs_float', 'acos', 'asin', 'at_exit', 'atan', 'atan2',
+ 'bool_of_string', 'ceil', 'char_of_int', 'classify_float',
+ 'close_in', 'close_in_noerr', 'close_out', 'close_out_noerr',
+ 'compare', 'cos', 'cosh', 'decr', 'epsilon_float', 'exit', 'exp',
+ 'float', 'float_of_int', 'float_of_string', 'floor', 'flush',
+ 'flush_all', 'format_of_string', 'frexp', 'fst', 'ignore',
+ 'in_channel_length', 'infinity', 'input', 'input_binary_int',
+ 'input_byte', 'input_char', 'input_line', 'input_value',
+ 'int_of_char', 'int_of_float', 'int_of_string', 'invalid_arg',
+ 'ldexp', 'log', 'log10', 'max', 'max_float', 'max_int', 'min',
+ 'min_float', 'min_int', 'mod_float', 'modf', 'nan', 'open_in',
+ 'open_in_bin', 'open_in_gen', 'open_out', 'open_out_bin',
+ 'open_out_gen', 'out_channel_length', 'output', 'output_binary_int',
+ 'output_byte', 'output_char', 'output_string', 'output_value',
+ 'pos_in', 'pos_out', 'pred', 'prerr_char', 'prerr_endline',
+ 'prerr_float', 'prerr_int', 'prerr_newline', 'prerr_string',
+ 'print_char', 'print_endline', 'print_float', 'print_int',
+ 'print_newline', 'print_string', 'read_float', 'read_int',
+ 'read_line', 'really_input', 'seek_in', 'seek_out',
+ 'set_binary_mode_in', 'set_binary_mode_out', 'sin', 'sinh', 'snd',
+ 'sqrt', 'string_of_bool', 'string_of_float', 'string_of_format',
+ 'string_of_int', 'succ', 'tan', 'tanh', 'truncate'
+ ),
+ /* here Pervasives Types */
+ 4 => array (
+ 'array','bool','char','exn','file_descr','format','fpclass',
+ 'in_channel','int','int32','int64','list','nativeint','open_flag',
+ 'out_channel','string','Sys_error','unit'
+ ),
+ /* finally Pervasives Exceptions */
+ 5 => array (
+ 'Exit', 'Invalid_Argument', 'Failure', 'Division_by_zero'
+ )
+ ),
+ /* highlighting symbols is really important in OCaml */
+ 'SYMBOLS' => array(
+ '+.', '-.', '*.', '/.', '[<', '>]',
+ ';', '!', ':', '.', '=', '%', '^', '*', '-', '/', '+',
+ '>', '<', '(', ')', '[', ']', '&', '|', '#', "'",
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => true, /* functions name are case sensitive */
+ 3 => true, /* types name too */
+ 4 => true, /* pervasives types */
+ 5 => true /* pervasives exceptions */
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 2 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 3 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 4 => 'color: #06c; font-weight: bold;', /* nice blue */
+ 5 => 'color: #06c; font-weight: bold;' /* nice blue */
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #5d478b; font-style: italic;', /* light purple */
+ 1 => 'color: #5d478b; font-style: italic;' /* light purple */
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #a52a2a;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #3cb371;' /* nice green */
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #c6c;' /* pink */
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #060;' /* dark green */
+ ),
+ 'REGEXPS' => array(
+ 1 => 'font-weight:bold; color:#339933;',
+ 2 => 'font-weight:bold; color:#993399;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #a52a2a;' /* maroon */
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ /* some of keywords are Pervasives functions (land, lxor, asr, ...) */
+ 1 => '',
+ /* link to the wanted library */
+ 2 => 'http://caml.inria.fr/pub/docs/manual-ocaml/libref/{FNAME}.html',
+ /* link to Pervasives functions */
+ 3 => 'http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#VAL{FNAME}',
+ /* link to Pervasives type */
+ 4 => 'http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#TYPE{FNAME}',
+ /* link to Pervasives exceptions */
+ 5 => 'http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#EXCEPTION{FNAME}'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ 1 => '~\w+',
+ 2 => '`(?=(?-i:[a-z]))\w*',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/octave.php b/platform/www/vendor/geshi/geshi/src/geshi/octave.php
new file mode 100644
index 0000000..999ab26
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/octave.php
@@ -0,0 +1,513 @@
+<?php
+/*************************************************************************************
+ * octave.php
+ * -----------
+ * Author: Carnë Draug (carandraug+dev@gmail.com)
+ * Juan Pablo Carbajal (carbajal@ifi.uzh.ch)
+ * Copyright: (c) 2012 Carnë Draug
+ * (c) 2012 Juan Pablo Carbajal
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/05/22
+ *
+ * GNU/Octave M-file language file for GeSHi.
+ *
+ * This file was heavily based on octave.lang from gtksourceview. If bugs are
+ * found and/or fixed on this file, please send them to the gtksourceview
+ * project or e-mail them to this file authors. Thanks in advance
+ *
+ * CHANGES
+ * -------
+ * 2012/05/22 (1.0.8.11)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'GNU/Octave',
+ 'COMMENT_SINGLE' => array(1 => '#', 2 => '%'),
+ // we can't use COMMENT_MULTI since start and end of block comments need to
+ // be alone on the line (optionally, with whitespace). See COMMENT_REGEXP
+ 'COMMENT_MULTI' => array(),
+ // we can't use QUOTEMARKS, not even HARDQUOTE, see COMMENT_REGEXP
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'COMMENT_REGEXP' => array(
+ // Single quote strings: we can't use QUOTEMARKS here since new
+ // lines will break the string. Plus, single quote strings do not even
+ // allow for continuation markers, only double quote strings allow it.
+ // Also, to do not misdetect the transpose operator ' as the start of a
+ // string we assert to not follow a variable name (letters, digits and
+ // underscores) or a closing bracket (round, square or curly) or a dot
+ // (to form the array transpose operator ".'" ).
+ 3 => "/(?<![0-9a-zA-Z_\)\]}\.])'.*?'/",
+ // Double quote strings: we also can't use QUOTEMARKS here (see single
+ // line quotes). However, with double quote strings both \ and ... can
+ // be used to make multiline strings. Continuation markers can be
+ // followed by whitespace
+ 4 => '/"(.|(\.\.\.|\\\)(\s)*?\n)*?(?<!\\\)"/',
+ // Block comments: the ms modifiers treat strings as multiple lines (to
+ // be able to use ^ and $ instead of newline and thus support block
+ // comments on the first and last line of source) and make . also match
+ // a newline
+ 5 => "/^\s*?[%#]{\s*?$.*?^\s*?[%#]}\s*?$/ms",
+ // Packaging system: comes here so that pkg can also be used in the
+ // function form. The list of pkg commands is optional to the match so
+ // that at least pkg is highlighted if new commands are implemented
+ 6 => "/\bpkg(?!\s*\()\s+((un)?install|update|(un)?load|list|(global|local)_list|describe|prefix|(re)?build)?\b/",
+ // Function handles
+ 7 => "/@([a-z_][a-z1-9_]*)?/i",
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_OCT_PREFIX |
+ GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'KEYWORDS' => array(
+ // Reserved words
+ 1 => array(
+ 'break', 'case', 'catch', 'continue', 'do', 'else', 'elseif', 'end',
+ 'end_try_catch', 'end_unwind_protect', 'endfor', 'endfunction',
+ 'endif', 'endparfor', 'endswitch', 'endwhile', 'for', 'function',
+ 'if', 'otherwise', 'parfor', 'return',
+ 'switch', 'try', 'until', 'unwind_protect',
+ 'unwind_protect_cleanup', 'varargin', 'varargout', 'while'
+ ),
+ // Storage type
+ 2 => array(
+ 'global', 'persistent', 'static'
+ ),
+ // Internal variable
+ 3 => array(
+ 'ans'
+ ),
+ // Data types
+ 4 => array(
+ 'cell', 'char', 'double', 'uint8', 'uint16', 'uint32', 'uint64',
+ 'int8','int16', 'int32', 'int64', 'logical', 'single', 'struct'
+ ),
+ // Built in
+ 5 => array(
+ 'P_tmpdir', 'abs', 'acos', 'acosh',
+ 'add_input_event_hook', 'addlistener', 'addpath', 'addproperty',
+ 'all', 'allow_noninteger_range_as_index', 'and', 'angle', 'any',
+ 'arg', 'argnames', 'argv', 'asin', 'asinh', 'assignin', 'atan',
+ 'atan2', 'atanh', 'atexit', 'autoload', 'available_graphics_toolkits',
+ 'beep_on_error', 'bitand', 'bitmax', 'bitor', 'bitshift', 'bitxor',
+ 'builtin', 'canonicalize_file_name', 'cat', 'cbrt', 'cd', 'ceil',
+ 'cell2struct', 'cellstr', 'chdir', 'class', 'clc',
+ 'clear', 'columns', 'command_line_path', 'completion_append_char',
+ 'completion_matches', 'complex', 'confirm_recursive_rmdir', 'conj',
+ 'cos', 'cosh', 'cputime', 'crash_dumps_octave_core', 'ctranspose',
+ 'cumprod', 'cumsum', 'dbclear', 'dbcont', 'dbdown', 'dbnext',
+ 'dbquit', 'dbstack', 'dbstatus', 'dbstep', 'dbstop', 'dbtype', 'dbup',
+ 'dbwhere', 'debug_on_error', 'debug_on_interrupt', 'debug_on_warning',
+ 'default_save_options', 'dellistener', 'diag', 'diary', 'diff',
+ 'disp', 'do_braindead_shortcircuit_evaluation', 'do_string_escapes',
+ 'doc_cache_file', 'drawnow', 'dup2', 'echo',
+ 'echo_executing_commands', 'edit_history','eq', 'erf', 'erfc',
+ 'erfcx', 'erfinv', 'errno', 'errno_list', 'error', 'eval', 'evalin',
+ 'exec', 'exist', 'exit', 'exp', 'expm1', 'eye', 'fclear',
+ 'fclose', 'fcntl', 'fdisp', 'feof', 'ferror', 'feval', 'fflush',
+ 'fgetl', 'fgets', 'fieldnames', 'file_in_loadpath', 'file_in_path',
+ 'filemarker', 'filesep', 'find_dir_in_path', 'finite', 'fix',
+ 'fixed_point_format', 'floor', 'fmod', 'fnmatch', 'fopen', 'fork',
+ 'format', 'formula', 'fprintf', 'fputs', 'fread', 'freport',
+ 'frewind', 'fscanf', 'fseek', 'fskipl', 'ftell', 'full', 'func2str',
+ 'functions', 'fwrite', 'gamma', 'gammaln', 'ge', 'genpath', 'get',
+ 'get_help_text', 'get_help_text_from_file', 'getegid', 'getenv',
+ 'geteuid', 'getgid', 'gethostname', 'getpgrp', 'getpid', 'getppid',
+ 'getuid', 'glob', 'gt', 'history', 'history_control', 'history_file',
+ 'history_size', 'history_timestamp_format_string', 'home', 'horzcat',
+ 'hypot', 'ifelse', 'ignore_function_time_stamp', 'imag',
+ 'inferiorto', 'info_file', 'info_program', 'inline', 'input',
+ 'intmax', 'intmin', 'ipermute',
+ 'is_absolute_filename', 'is_dq_string', 'is_function_handle',
+ 'is_rooted_relative_filename', 'is_sq_string', 'isalnum', 'isalpha',
+ 'isargout', 'isascii', 'isbool', 'iscell', 'iscellstr', 'ischar',
+ 'iscntrl', 'iscomplex', 'isdebugmode', 'isdigit', 'isempty',
+ 'isfield', 'isfinite', 'isfloat', 'isglobal', 'isgraph', 'ishandle',
+ 'isieee', 'isindex', 'isinf', 'isinteger', 'iskeyword', 'islogical',
+ 'islower', 'ismatrix', 'ismethod', 'isna', 'isnan', 'isnull',
+ 'isnumeric', 'isobject', 'isprint', 'ispunct', 'isreal', 'issorted',
+ 'isspace', 'issparse', 'isstruct', 'isupper', 'isvarname', 'isxdigit',
+ 'kbhit', 'keyboard', 'kill', 'lasterr', 'lasterror', 'lastwarn',
+ 'ldivide', 'le', 'length', 'lgamma', 'link', 'linspace',
+ 'list_in_columns', 'load', 'loaded_graphics_toolkits', 'log', 'log10',
+ 'log1p', 'log2', 'lower', 'lstat', 'lt',
+ 'make_absolute_filename', 'makeinfo_program', 'max_recursion_depth',
+ 'merge', 'methods', 'mfilename', 'minus', 'mislocked',
+ 'missing_function_hook', 'mkdir', 'mkfifo', 'mkstemp', 'mldivide',
+ 'mlock', 'mod', 'more', 'mpower', 'mrdivide', 'mtimes', 'munlock',
+ 'nargin', 'nargout', 'native_float_format', 'ndims', 'ne',
+ 'nfields', 'nnz', 'norm', 'not', 'nth_element', 'numel', 'nzmax',
+ 'octave_config_info', 'octave_core_file_limit',
+ 'octave_core_file_name', 'octave_core_file_options',
+ 'octave_tmp_file_name', 'onCleanup', 'ones',
+ 'optimize_subsasgn_calls', 'or', 'output_max_field_width',
+ 'output_precision', 'page_output_immediately', 'page_screen_output',
+ 'path', 'pathsep', 'pause', 'pclose', 'permute', 'pipe', 'plus',
+ 'popen', 'popen2', 'power', 'print_empty_dimensions',
+ 'print_struct_array_contents', 'printf', 'prod',
+ 'program_invocation_name', 'program_name', 'putenv', 'puts', 'pwd',
+ 'quit', 'rats', 'rdivide', 're_read_readline_init_file',
+ 'read_readline_init_file', 'readdir', 'readlink', 'real', 'realmax',
+ 'realmin', 'register_graphics_toolkit', 'rehash', 'rem',
+ 'remove_input_event_hook', 'rename', 'repelems', 'reset', 'reshape',
+ 'resize', 'restoredefaultpath', 'rethrow', 'rmdir', 'rmfield',
+ 'rmpath', 'round', 'roundb', 'rows', 'run_history', 'save',
+ 'save_header_format_string', 'save_precision', 'saving_history',
+ 'scanf', 'set', 'setenv', 'sighup_dumps_octave_core', 'sign',
+ 'sigterm_dumps_octave_core', 'silent_functions', 'sin',
+ 'sinh', 'size', 'size_equal', 'sizemax', 'sizeof', 'sleep', 'sort',
+ 'source', 'spalloc', 'sparse', 'sparse_auto_mutate',
+ 'split_long_rows', 'sprintf', 'sqrt', 'squeeze', 'sscanf', 'stat',
+ 'stderr', 'stdin', 'stdout', 'str2func', 'strcmp', 'strcmpi',
+ 'string_fill_char', 'strncmp', 'strncmpi', 'struct2cell',
+ 'struct_levels_to_print', 'strvcat', 'subsasgn', 'subsref', 'sum',
+ 'sumsq', 'superiorto', 'suppress_verbose_help_message', 'symlink',
+ 'system', 'tan', 'tanh', 'terminal_size', 'tic', 'tilde_expand',
+ 'times', 'tmpfile', 'tmpnam', 'toascii', 'toc', 'tolower', 'toupper',
+ 'transpose', 'typeinfo',
+ 'umask', 'uminus', 'uname', 'undo_string_escapes', 'unlink',
+ 'uplus', 'upper', 'usage', 'usleep', 'vec', 'vectorize', 'vertcat',
+ 'waitfor', 'waitpid', 'warning', 'warranty', 'who', 'whos',
+ 'whos_line_format', 'yes_or_no', 'zeros'
+ ),
+ // Octave functions
+ 6 => array(
+ 'accumarray', 'accumdim', 'acosd', 'acot', 'acotd', 'acoth', 'acsc',
+ 'acscd', 'acsch', 'addpref', 'addtodate', 'allchild', 'amd',
+ 'ancestor', 'anova', 'arch_fit', 'arch_rnd', 'arch_test',
+ 'area', 'arma_rnd', 'asctime', 'asec', 'asecd', 'asech', 'asind',
+ 'assert', 'atand', 'autoreg_matrix', 'autumn',
+ 'axes', 'axis', 'balance', 'bar', 'barh', 'bartlett', 'bartlett_test',
+ 'base2dec', 'beep', 'bessel', 'besselj', 'beta', 'betacdf',
+ 'betainc', 'betainv', 'betaln', 'betapdf', 'betarnd', 'bicg',
+ 'bicgstab', 'bicubic', 'bin2dec', 'bincoeff', 'binocdf', 'binoinv',
+ 'binopdf', 'binornd', 'bitcmp', 'bitget', 'bitset', 'blackman',
+ 'blanks', 'blkdiag', 'bone', 'box', 'brighten', 'bsxfun',
+ 'bug_report', 'bunzip2', 'bzip2', 'calendar', 'cart2pol', 'cart2sph',
+ 'cast', 'cauchy_cdf', 'cauchy_inv', 'cauchy_pdf', 'cauchy_rnd',
+ 'caxis', 'ccolamd', 'cell2mat', 'celldisp', 'cellfun',
+ 'center', 'cgs', 'chi2cdf', 'chi2inv', 'chi2pdf', 'chi2rnd',
+ 'chisquare_test_homogeneity', 'chisquare_test_independence', 'chol',
+ 'chop', 'circshift', 'cla', 'clabel', 'clf', 'clock',
+ 'cloglog', 'close', 'closereq', 'colamd', 'colloc', 'colon',
+ 'colorbar', 'colormap', 'colperm', 'colstyle', 'comet', 'comet3',
+ 'comma', 'common_size', 'commutation_matrix', 'compan',
+ 'compare_versions', 'compass', 'computer', 'cond', 'condest',
+ 'contour', 'contour3', 'contourc', 'contourf', 'contrast', 'conv',
+ 'conv2', 'convhull', 'convhulln', 'cool', 'copper', 'copyfile',
+ 'cor_test', 'corr', 'cosd', 'cot', 'cotd', 'coth', 'cov',
+ 'cplxpair', 'cross', 'csc', 'cscd', 'csch', 'cstrcat',
+ 'csvread', 'csvwrite', 'ctime', 'cumtrapz', 'curl', 'cylinder',
+ 'daspect', 'daspk', 'dasrt', 'dassl', 'date', 'datenum', 'datestr',
+ 'datetick', 'datevec', 'dblquad', 'deal', 'deblank', 'debug',
+ 'dec2base', 'dec2bin', 'dec2hex', 'deconv', 'del2', 'delaunay',
+ 'delaunay3', 'delaunayn', 'delete', 'demo', 'det', 'detrend',
+ 'diffpara', 'diffuse', 'dir', 'discrete_cdf', 'discrete_inv',
+ 'discrete_pdf', 'discrete_rnd', 'display', 'divergence',
+ 'dlmread', 'dlmwrite', 'dmperm', 'doc', 'dos', 'dot', 'dsearch',
+ 'dsearchn', 'dump_prefs', 'duplication_matrix', 'durbinlevinson',
+ 'edit', 'eig', 'eigs', 'ellipsoid', 'empirical_cdf', 'empirical_inv',
+ 'empirical_pdf', 'empirical_rnd', 'eomday', 'errorbar',
+ 'etime', 'etreeplot', 'example', 'expcdf', 'expinv', 'expm', 'exppdf',
+ 'exprnd', 'ezcontour', 'ezcontourf', 'ezmesh', 'ezmeshc', 'ezplot',
+ 'ezplot3', 'ezpolar', 'ezsurf', 'ezsurfc', 'f_test_regression',
+ 'fact', 'factor', 'factorial', 'fail', 'fcdf', 'feather', 'fft',
+ 'fft2', 'fftconv', 'fftfilt', 'fftn', 'fftshift', 'fftw', 'figure',
+ 'fileattrib', 'fileparts', 'fileread', 'fill', 'filter', 'filter2',
+ 'find', 'findall', 'findobj', 'findstr', 'finv', 'flag', 'flipdim',
+ 'fliplr', 'flipud', 'fminbnd', 'fminunc', 'fpdf', 'fplot',
+ 'fractdiff', 'freqz', 'freqz_plot', 'frnd', 'fsolve',
+ 'fullfile', 'fzero', 'gamcdf', 'gaminv', 'gammainc',
+ 'gampdf', 'gamrnd', 'gca', 'gcbf', 'gcbo', 'gcd', 'gcf',
+ 'gen_doc_cache', 'genvarname', 'geocdf', 'geoinv', 'geopdf', 'geornd',
+ 'get_first_help_sentence', 'getappdata', 'getfield', 'getgrent',
+ 'getpref', 'getpwent', 'getrusage', 'ginput', 'givens', 'glpk',
+ 'gls', 'gmap40', 'gmres', 'gnuplot_binary', 'gplot',
+ 'gradient', 'graphics_toolkit', 'gray', 'gray2ind', 'grid',
+ 'griddata', 'griddata3', 'griddatan', 'gtext', 'guidata',
+ 'guihandles', 'gunzip', 'gzip', 'hadamard', 'hamming', 'hankel',
+ 'hanning', 'help', 'hess', 'hex2dec', 'hex2num', 'hggroup', 'hidden',
+ 'hilb', 'hist', 'histc', 'hold', 'hot', 'hotelling_test',
+ 'hotelling_test_2', 'housh', 'hsv', 'hsv2rgb', 'hurst', 'hygecdf',
+ 'hygeinv', 'hygepdf', 'hygernd', 'idivide', 'ifftshift', 'image',
+ 'imagesc', 'imfinfo', 'imread', 'imshow', 'imwrite', 'ind2gray',
+ 'ind2rgb', 'index', 'info', 'inpolygon', 'inputname', 'int2str',
+ 'interp1', 'interp1q', 'interp2', 'interp3', 'interpft', 'interpn',
+ 'intersect', 'inv', 'invhilb', 'iqr',
+ 'is_leap_year', 'is_valid_file_id',
+ 'isa', 'isappdata', 'iscolumn', 'isdefinite', 'isdeployed', 'isdir',
+ 'isequal', 'isequalwithequalnans', 'isfigure', 'ishermitian',
+ 'ishghandle', 'ishold', 'isletter', 'ismac', 'ismember', 'isocolors',
+ 'isonormals', 'isosurface', 'ispc', 'ispref', 'isprime', 'isprop',
+ 'isrow', 'isscalar', 'issquare', 'isstrprop', 'issymmetric',
+ 'isunix', 'isvector', 'jet', 'kendall', 'kolmogorov_smirnov_cdf',
+ 'kolmogorov_smirnov_test', 'kolmogorov_smirnov_test_2', 'kron',
+ 'kruskal_wallis_test', 'krylov', 'kurtosis', 'laplace_cdf',
+ 'laplace_inv', 'laplace_pdf', 'laplace_rnd', 'lcm', 'legend',
+ 'legendre', 'license', 'lin2mu', 'line', 'linkprop', 'list_primes',
+ 'loadaudio', 'loadobj', 'logistic_cdf', 'logistic_inv',
+ 'logistic_pdf', 'logistic_regression', 'logistic_rnd', 'logit',
+ 'loglog', 'loglogerr', 'logm', 'logncdf', 'logninv', 'lognpdf',
+ 'lognrnd', 'logspace', 'lookfor', 'lookup', 'ls', 'ls_command',
+ 'lsode', 'lsqnonneg', 'lu', 'luinc', 'magic', 'mahalanobis', 'manova',
+ 'mat2str', 'matlabroot', 'matrix_type', 'max', 'mcnemar_test',
+ 'md5sum', 'mean', 'meansq', 'median', 'menu', 'mesh', 'meshc',
+ 'meshgrid', 'meshz', 'mex', 'mexext', 'mgorth', 'mkoctfile', 'mkpp',
+ 'mode', 'moment', 'movefile', 'mpoles', 'mu2lin', 'namelengthmax',
+ 'nargchk', 'narginchk', 'nargoutchk', 'nbincdf', 'nbininv', 'nbinpdf',
+ 'nbinrnd', 'nchoosek', 'ndgrid', 'newplot', 'news', 'nextpow2',
+ 'nonzeros', 'normcdf', 'normest', 'norminv', 'normpdf', 'normrnd',
+ 'now', 'nproc', 'nthargout', 'nthroot', 'ntsc2rgb', 'null', 'num2str',
+ 'ocean', 'ols', 'onenormest', 'optimget', 'optimset', 'orderfields',
+ 'orient', 'orth', 'pack', 'paren', 'pareto', 'parseparams', 'pascal',
+ 'patch', 'pathdef', 'pbaspect', 'pcg', 'pchip', 'pcolor', 'pcr',
+ 'peaks', 'periodogram', 'perl', 'perms', 'pie', 'pie3',
+ 'pink', 'pinv', 'pkg', 'planerot', 'playaudio', 'plot', 'plot3',
+ 'plotmatrix', 'plotyy', 'poisscdf', 'poissinv', 'poisspdf',
+ 'poissrnd', 'pol2cart', 'polar', 'poly', 'polyaffine', 'polyarea',
+ 'polyder', 'polyfit', 'polygcd', 'polyint', 'polyout',
+ 'polyreduce', 'polyval', 'polyvalm', 'postpad', 'pow2', 'powerset',
+ 'ppder', 'ppint', 'ppjumps', 'ppplot', 'ppval', 'pqpnonneg',
+ 'prctile', 'prepad', 'primes', 'print', 'printAllBuiltins',
+ 'print_usage', 'prism', 'probit', 'profexplore', 'profile',
+ 'profshow', 'prop_test_2', 'python', 'qp', 'qqplot', 'qr', 'quad',
+ 'quadcc', 'quadgk', 'quadl', 'quadv', 'quantile', 'quiver', 'quiver3',
+ 'qz', 'qzhess', 'rainbow', 'rand', 'randi', 'range', 'rank', 'ranks',
+ 'rat', 'rcond', 'reallog', 'realpow', 'realsqrt', 'record',
+ 'rectangle', 'rectint', 'recycle', 'refresh', 'refreshdata', 'regexp',
+ 'regexptranslate', 'repmat', 'residue', 'rgb2hsv',
+ 'rgb2ind', 'rgb2ntsc', 'ribbon', 'rindex', 'rmappdata', 'rmpref',
+ 'roots', 'rose', 'rosser', 'rot90', 'rotdim', 'rref', 'run',
+ 'run_count', 'run_test', 'rundemos', 'runlength', 'runtests',
+ 'saveas', 'saveaudio', 'saveobj', 'savepath', 'scatter',
+ 'scatter3', 'schur', 'sec', 'secd', 'sech', 'semicolon', 'semilogx',
+ 'semilogxerr', 'semilogy', 'semilogyerr', 'setappdata', 'setaudio',
+ 'setdiff', 'setfield', 'setpref', 'setxor', 'shading',
+ 'shg', 'shift', 'shiftdim', 'sign_test', 'sinc', 'sind',
+ 'sinetone', 'sinewave', 'skewness', 'slice', 'sombrero', 'sortrows',
+ 'spaugment', 'spconvert', 'spdiags', 'spearman', 'spectral_adf',
+ 'spectral_xdf', 'specular', 'speed', 'spencer', 'speye', 'spfun',
+ 'sph2cart', 'sphere', 'spinmap', 'spline', 'spones', 'spparms',
+ 'sprand', 'sprandn', 'sprandsym', 'spring', 'spstats', 'spy', 'sqp',
+ 'sqrtm', 'stairs', 'statistics', 'std', 'stdnormal_cdf',
+ 'stdnormal_inv', 'stdnormal_pdf', 'stdnormal_rnd', 'stem', 'stem3',
+ 'stft', 'str2double', 'str2num', 'strcat', 'strchr',
+ 'strfind', 'strjust', 'strmatch', 'strread', 'strsplit', 'strtok',
+ 'strtrim', 'strtrunc', 'structfun', 'sub2ind',
+ 'subplot', 'subsindex', 'subspace', 'substr', 'substruct', 'summer',
+ 'surf', 'surface', 'surfc', 'surfl', 'surfnorm', 'svd', 'svds',
+ 'swapbytes', 'syl', 'symbfact', 'symrcm',
+ 'symvar', 'synthesis', 't_test', 't_test_2', 't_test_regression',
+ 'table', 'tand', 'tar', 'tcdf', 'tempdir', 'tempname', 'test', 'text',
+ 'textread', 'textscan', 'time', 'tinv', 'title', 'toeplitz', 'tpdf',
+ 'trace', 'trapz', 'treelayout', 'treeplot', 'tril', 'trimesh',
+ 'triplequad', 'triplot', 'trisurf', 'trnd', 'tsearch', 'tsearchn',
+ 'type', 'typecast', 'u_test', 'uicontextmenu', 'uicontrol',
+ 'uigetdir', 'uigetfile', 'uimenu', 'uipanel', 'uipushtool',
+ 'uiputfile', 'uiresume', 'uitoggletool', 'uitoolbar', 'uiwait',
+ 'unidcdf', 'unidinv', 'unidpdf', 'unidrnd', 'unifcdf', 'unifinv',
+ 'unifpdf', 'unifrnd', 'unimplemented', 'union', 'unique', 'unix',
+ 'unmkpp', 'unpack', 'untabify', 'untar', 'unwrap', 'unzip',
+ 'urlwrite', 'usejava', 'validatestring', 'vander', 'var',
+ 'var_test', 'vech', 'ver', 'version', 'view', 'voronoi', 'voronoin',
+ 'waitbar', 'waitforbuttonpress', 'warning_ids', 'wavread', 'wavwrite',
+ 'wblcdf', 'wblinv', 'wblpdf', 'wblrnd', 'weekday',
+ 'welch_test', 'what', 'which',
+ 'white', 'whitebg', 'wienrnd', 'wilcoxon_test', 'wilkinson', 'winter',
+ 'xlabel', 'xlim', 'xor', 'ylabel', 'ylim', 'yulewalker', 'z_test',
+ 'z_test_2', 'zip', 'zlabel', 'zlim', 'zscore', 'airy', 'arrayfun',
+ 'besselh', 'besseli', 'besselk', 'bessely', 'bitpack', 'bitunpack',
+ 'blkmm', 'cellindexmat', 'cellslices', 'chol2inv', 'choldelete',
+ 'cholinsert', 'cholinv', 'cholshift', 'cholupdate', 'convn',
+ 'csymamd', 'cummax', 'cummin', 'daspk_options', 'dasrt_options',
+ 'dassl_options', 'endgrent', 'endpwent', 'etree', 'getgrgid',
+ 'getgrnam', 'getpwnam', 'getpwuid', 'gmtime', 'gui_mode', 'ifft',
+ 'ifft2', 'ifftn', 'ind2sub', 'inverse', 'localtime', 'lsode_options',
+ 'luupdate', 'mat2cell', 'min', 'mktime', 'mouse_wheel_zoom',
+ 'num2cell', 'num2hex', 'qrdelete', 'qrinsert', 'qrshift', 'qrupdate',
+ 'quad_options', 'rande', 'randg', 'randn', 'randp', 'randperm',
+ 'regexpi', 'regexprep', 'rsf2csf', 'setgrent', 'setpwent', 'sprank',
+ 'strftime', 'strptime', 'strrep', 'svd_driver', 'symamd', 'triu',
+ 'urlread'
+ ),
+ // Private builtin
+ 7 => array(
+ '__accumarray_max__', '__accumarray_min__', '__accumarray_sum__',
+ '__accumdim_sum__', '__builtins__', '__calc_dimensions__',
+ '__current_scope__', '__display_tokens__', '__dump_symtab_info__',
+ '__end__', '__get__', '__go_axes__', '__go_axes_init__',
+ '__go_delete__', '__go_execute_callback__', '__go_figure__',
+ '__go_figure_handles__', '__go_handles__', '__go_hggroup__',
+ '__go_image__', '__go_line__', '__go_patch__', '__go_surface__',
+ '__go_text__', '__go_uicontextmenu__', '__go_uicontrol__',
+ '__go_uimenu__', '__go_uipanel__', '__go_uipushtool__',
+ '__go_uitoggletool__', '__go_uitoolbar__', '__gud_mode__',
+ '__image_pixel_size__', '__is_handle_visible__', '__isa_parent__',
+ '__keywords__', '__lexer_debug_flag__', '__list_functions__',
+ '__operators__', '__parent_classes__', '__parser_debug_flag__',
+ '__pathorig__', '__profiler_data__', '__profiler_enable__',
+ '__profiler_reset__', '__request_drawnow__', '__sort_rows_idx__',
+ '__token_count__', '__varval__', '__version_info__', '__which__'
+ ),
+ // Private Octave functions
+ 8 => array(
+ '__all_opts__', '__contourc__', '__delaunayn__', '__dispatch__',
+ '__dsearchn__', '__finish__', '__fltk_uigetfile__',
+ '__glpk__', '__gnuplot_drawnow__', '__init_fltk__',
+ '__init_gnuplot__', '__lin_interpn__', '__magick_read__',
+ '__makeinfo__', '__pchip_deriv__', '__plt_get_axis_arg__', '__qp__',
+ '__voronoi__', '__fltk_maxtime__', '__fltk_redraw__', '__ftp__',
+ '__ftp_ascii__', '__ftp_binary__', '__ftp_close__', '__ftp_cwd__',
+ '__ftp_delete__', '__ftp_dir__', '__ftp_mget__', '__ftp_mkdir__',
+ '__ftp_mode__', '__ftp_mput__', '__ftp_pwd__', '__ftp_rename__',
+ '__ftp_rmdir__', '__magick_finfo__', '__magick_format_list__',
+ '__magick_write__'
+ ),
+ // Builtin Global Variables
+ 9 => array(
+ 'EDITOR', 'EXEC_PATH', 'F_DUPFD', 'F_GETFD', 'F_GETFL', 'F_SETFD',
+ 'F_SETFL', 'IMAGE_PATH', 'OCTAVE_HOME',
+ 'OCTAVE_VERSION', 'O_APPEND', 'O_ASYNC', 'O_CREAT', 'O_EXCL',
+ 'O_NONBLOCK', 'O_RDONLY', 'O_RDWR', 'O_SYNC', 'O_TRUNC', 'O_WRONLY',
+ 'PAGER', 'PAGER_FLAGS', 'PS1', 'PS2', 'PS4', 'SEEK_CUR', 'SEEK_END',
+ 'SEEK_SET', 'SIG', 'S_ISBLK', 'S_ISCHR', 'S_ISDIR', 'S_ISFIFO',
+ 'S_ISLNK', 'S_ISREG', 'S_ISSOCK', 'WCONTINUE', 'WCOREDUMP',
+ 'WEXITSTATUS', 'WIFCONTINUED', 'WIFEXITED', 'WIFSIGNALED',
+ 'WIFSTOPPED', 'WNOHANG', 'WSTOPSIG', 'WTERMSIG', 'WUNTRACED'
+ ),
+ // Constant functions
+ 10 => array (
+ 'e', 'eps', 'inf', 'Inf', 'nan', 'NaN', 'NA', 'pi', 'i', 'I', 'j',
+ 'J', 'true', 'false'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ // Comparison & logical
+ 0 => array(
+ '!', '!=', '&', '&&','|', '||', '~', '~=',
+ '<', '<=', '==', '>', '>='
+ ),
+ // Aritmethical
+ 1 => array(
+ '*', '**', '+', '++', '-', '--', '/', "\\","'"
+ ),
+ // Elementwise arithmetical
+ 2 => array(
+ '.*', '.**','./', '.^', '^',".\\",".'"
+ ),
+ // Arithmetical & assignation
+ 3 => array(
+ '*=','+=','-=','/=','\=','**=','^=',
+ '.*=','.+=','.-=','./=','.\=','.**=','.^=','='
+ ),
+ // Indexer
+ 4 => array(
+ ':'
+ ),
+ // Delimiters
+ 5 => array(
+ ',', '...', ';'
+ ),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true,
+ 10 => true,
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => 'http://octave.sourceforge.net/octave/function/{FNAME}.html',
+ 5 => 'http://octave.sourceforge.net/octave/function/{FNAME}.html',
+ 6 => 'http://octave.sourceforge.net/octave/function/{FNAME}.html',
+ 7 => '',
+ 8 => '',
+ 9 => 'http://octave.sourceforge.net/octave/function/{FNAME}.html',
+ 10 => 'http://octave.sourceforge.net/octave/function/{FNAME}.html',
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ ),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'STYLES' => array(
+ 'COMMENTS' => array(
+ 1 => 'color: #0000FF; font-style: italic;', // comments with #
+ 2 => 'color: #0000FF; font-style: italic;', // comments with %
+ 3 => 'color: #FF00FF; font-style: italic;', // single quote strings
+ 4 => 'color: #FF00FF; font-style: italic;', // double quote strings
+ 5 => 'color: #0000FF; font-style: italic;', // block comments
+ 6 => 'color: #996600; font-weight:bold;', // packaging system
+ 7 => 'color: #006600; font-weight:bold;', // function handles
+ 'MULTI' => 'color: #0000FF; font-style: italic;',
+ ),
+ 'KEYWORDS' => array(
+ 1 => 'color: #990000; font-weight:bold;', // Reserved words
+ 2 => 'color: #2E8B57;', // Storage type
+ 3 => 'color: #0000FF; font-weight:bold;', // Internal variable
+ 4 => 'color: #2E8B57; font-weight:bold;', // Data types
+ 5 => 'color: #008A8C; font-weight:bold;', // Built-in
+ 6 => 'color: #008A8C;', // Octave functions
+ 9 => 'color: #000000; font-weight:bold;', // Builtin Global Variables
+ 10 => 'color: #008A8C; font-weight:bold;', // Constant functions
+ ),
+ 'ESCAPE_CHAR' => array(),
+ 'BRACKETS' => array(
+ 0 => 'color: #080;',
+ ),
+ 'STRINGS' => array(
+ // strings were specified on the COMMENT_REGEXP section
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ ),
+ 'METHODS' => array(),
+ 'SYMBOLS' => array(
+ 0 => 'color: #FF9696; font-weight:bold;', // Comparison & logical
+ 1 => 'color: #CC0000; font-weight:bold;', // Aritmethical
+ 2 => 'color: #993333; font-weight:bold;', // Elementwise arithmetical
+ 3 => 'color: #FF0000; font-weight:bold;', // Arithmetical & assignation
+ 4 => 'color: #33F;', // Indexer
+ 5 => 'color: #33F;', // Delimiters
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array(),
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/oobas.php b/platform/www/vendor/geshi/geshi/src/geshi/oobas.php
new file mode 100644
index 0000000..b022ebf
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/oobas.php
@@ -0,0 +1,133 @@
+<?php
+/*************************************************************************************
+ * oobas.php
+ * ---------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/30
+ *
+ * OpenOffice.org Basic language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'OpenOffice.org Basic',
+ 'COMMENT_SINGLE' => array(1 => "'"),
+ 'COMMENT_MULTI' => array(),
+ //Single-Line comments using REM keyword
+ 'COMMENT_REGEXP' => array(2 => '/\bREM.*?$/i'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'dim','private','public','global','as','if','redim','true','set','byval',
+ 'false','bool','double','integer','long','object','single','variant',
+ 'msgbox','print','inputbox','green','blue','red','qbcolor',
+ 'rgb','open','close','reset','freefile','get','input','line',
+ 'put','write','loc','seek','eof','lof','chdir','chdrive',
+ 'curdir','dir','fileattr','filecopy','filedatetime','fileexists',
+ 'filelen','getattr','kill','mkdir','name','rmdir','setattr',
+ 'dateserial','datevalue','day','month','weekday','year','cdatetoiso',
+ 'cdatefromiso','hour','minute','second','timeserial','timevalue',
+ 'date','now','time','timer','erl','err','error','on','goto','resume',
+ 'and','eqv','imp','not','or','xor','mod','atn','cos','sin','tan','log',
+ 'exp','rnd','randomize','sqr','fix','int','abs','sgn','hex','oct',
+ 'it','then','else','select','case','iif','do','loop','for','next','to',
+ 'while','wend','gosub','return','call','choose','declare',
+ 'end','exit','freelibrary','function','rem','stop','sub','switch','with',
+ 'cbool','cdate','cdbl','cint','clng','const','csng','cstr','defbool',
+ 'defdate','defdbl','defint','deflng','asc','chr','str','val','cbyte',
+ 'space','string','format','lcase','left','lset','ltrim','mid','right',
+ 'rset','rtrim','trim','ucase','split','join','converttourl','convertfromurl',
+ 'instr','len','strcomp','beep','shell','wait','getsystemticks','environ',
+ 'getsolarversion','getguitype','twipsperpixelx','twipsperpixely',
+ 'createunostruct','createunoservice','getprocessservicemanager',
+ 'createunodialog','createunolistener','createunovalue','thiscomponent',
+ 'globalscope'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080;',
+ 2 => 'color: #808080;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/oorexx.php b/platform/www/vendor/geshi/geshi/src/geshi/oorexx.php
new file mode 100644
index 0000000..db629b5
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/oorexx.php
@@ -0,0 +1,169 @@
+<?php
+/*************************************************************************************
+ * oorexx.php
+ * ---------------------------------
+ * Author: Jon Wolfers (sahananda@windhorse.biz)
+ * Contributors:
+ * - Walter Pachl (pachl@chello.at)
+ * Copyright: (c) 2008 Jon Wolfers, (c) 2012 Walter Pachl
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/01/07
+ *
+ * ooRexx language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2012/07/29 (1.0.0)
+ * - tried to get it syntactically right
+ *
+ * TODO (updated 2012/07/29)
+ * -------------------------
+ * - Get it working on rosettacode.org
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ooRexx',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'address', 'arg', 'attribute', 'call', 'constant', 'do',
+ 'drop', 'exit', 'if',
+ 'interpret', 'iterate', 'leave', 'loop', 'nop', 'numeric',
+ 'parse', 'procedure', 'pull', 'push', 'queue',
+ 'raise', 'reply', 'return', 'say', 'select', 'signal',
+ 'use'
+ ),
+ 2 => array(
+ 'abstract', 'any', 'arguments', 'array', 'by',
+ 'continue', 'digits', 'engineering', 'error',
+ 'expose', 'external', 'failure', 'for', 'forever',
+ 'forward', 'get', 'guard', 'guarded', 'halt',
+ 'inherit', 'library', 'lostdigits', 'message',
+ 'metaclass', 'mixinclass', 'name', 'nomethod', 'nostring',
+ 'notready', 'novalue', 'off', 'on', 'options', 'over',
+ 'private', 'protected', 'public', 'scientific', 'set',
+ 'source', 'subclass', 'syntax', 'to', 'unguarded',
+ 'unprotected', 'until', 'user',
+ 'version', 'while', 'with'
+ ),
+ 3 => array(
+ 'else', 'end', 'otherwise', 'then', 'when'
+ ),
+ 4 => array(
+ 'rc', 'result', 'self', 'sigl', 'super'
+ ),
+ 5 => array(
+ '::attribute', '::class', '::constant', '::method',
+ '::optins', '::requires', '::routine'
+ ),
+ 6 => array(
+ 'abbrev', 'abs', 'beep', 'bitand', 'bitor',
+ 'bitxor', 'b2x', 'center', 'centre', 'changestr', 'charin',
+ 'charout', 'chars', 'compare', 'condition', 'copies',
+ 'countstr', 'c2d', 'c2x', 'datatype', 'date', 'delstr',
+ 'delword', 'directory', 'd2c', 'd2x', 'endlocal',
+ 'errortext', 'filespec', 'form', 'format', 'fuzz', 'insert',
+ 'lastpos', 'left', 'length', 'linein', 'lineout', 'lines',
+ 'lower', 'max', 'min', 'overlay', 'pos', 'qualify', 'queued',
+ 'random', 'reverse', 'right', 'rxfuncadd', 'rxfuncdrop',
+ 'rxfuncquery', 'rxqueue', 'setlocal', 'sign', 'sourceline',
+ 'space', 'stream', 'strip', 'substr', 'subword', 'symbol',
+ 'time', 'trace', 'translate', 'trunc', 'upper', 'userid',
+ 'value', 'var', 'verify', 'word', 'wordindex', 'wordlength',
+ 'wordpos', 'words', 'xrange', 'x2b', 'x2c', 'x2d'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '<', '>', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':',
+ '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #ff0000; font-weight: bold;',
+ 3 => 'color: #00ff00; font-weight: bold;',
+ 4 => 'color: #0000ff; font-weight: bold;',
+ 5 => 'color: #880088; font-weight: bold;',
+ 6 => 'color: #888800; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666;',
+ 'MULTI' => 'color: #808080;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/oracle11.php b/platform/www/vendor/geshi/geshi/src/geshi/oracle11.php
new file mode 100644
index 0000000..0e2cf4a
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/oracle11.php
@@ -0,0 +1,612 @@
+<?php
+/*************************************************************************************
+ * oracle11.php
+ * -----------
+ * Author: Guy Wicks (Guy.Wicks@rbs.co.uk)
+ * Contributions:
+ * - Updated for 11i by Simon Redhead
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/04
+ *
+ * Oracle 11i language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/04/08 (1.0.8)
+ * - SR changes to oracle8.php to support Oracle 11i reserved words.
+ * 2005/01/29 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Oracle 11 SQL',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array("'", '"', '`'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+//Put your package names here - e.g. select distinct ''''|| lower(name) || ''',' from user_source;
+// 6 => array(
+// ),
+
+//Put your table names here - e.g. select distinct ''''|| lower(table_name) || ''',' from user_tables;
+// 5 => array(
+// ),
+
+//Put your view names here - e.g. select distinct ''''|| lower(view_name) || ''',' from user_views;
+// 4 => array(
+// ),
+
+//Put your table field names here - e.g. select distinct ''''|| lower(column_name) || ''',' from user_tab_columns;
+// 3 => array(
+// ),
+
+ //Put ORACLE reserved keywords here (11i). I like mine uppercase.
+ 1 => array(
+ 'ABS',
+ 'ACCESS',
+ 'ACOS',
+ 'ADD',
+ 'ADD_MONTHS',
+ 'ALL',
+ 'ALTER',
+ 'ANALYZE',
+ 'AND',
+ 'ANY',
+ 'APPENDCHILDXML',
+ 'ARRAY',
+ 'AS',
+ 'ASC',
+ 'ASCII',
+ 'ASCIISTR',
+ 'ASIN',
+ 'ASSOCIATE',
+ 'AT',
+ 'ATAN',
+ 'ATAN2',
+ 'AUDIT',
+ 'AUTHID',
+ 'AVG',
+ 'BEGIN',
+ 'BETWEEN',
+ 'BFILENAME',
+ 'BIN_TO_NUM',
+ 'BINARY_INTEGER',
+ 'BITAND',
+ 'BODY',
+ 'BOOLEAN',
+ 'BULK',
+ 'BY',
+ 'CALL',
+ 'CARDINALITY',
+ 'CASCADE',
+ 'CASE',
+ 'CAST',
+ 'CEIL',
+ 'CHAR',
+ 'CHAR_BASE',
+ 'CHARTOROWID',
+ 'CHECK',
+ 'CHR',
+ 'CLOSE',
+ 'CLUSTER',
+ 'CLUSTER_ID',
+ 'CLUSTER_PROBABILITY',
+ 'CLUSTER_SET',
+ 'COALESCE',
+ 'COLLECT',
+ 'COLUMN',
+ 'COMMENT',
+ 'COMMIT',
+ 'COMPOSE',
+ 'COMPRESS',
+ 'CONCAT',
+ 'CONNECT',
+ 'CONSTANT',
+ 'CONSTRAINT',
+ 'CONSTRAINTS',
+ 'CONTEXT',
+ 'CONTROLFILE',
+ 'CONVERT',
+ 'CORR',
+ 'CORR_K',
+ 'CORR_S',
+ 'COS',
+ 'COSH',
+ 'COST',
+ 'COUNT',
+ 'COVAR_POP',
+ 'COVAR_SAMP',
+ 'CREATE',
+ 'CUBE_TABLE',
+ 'CUME_DIST',
+ 'CURRENT',
+ 'CURRENT_DATE',
+ 'CURRENT_TIMESTAMP',
+ 'CURRVAL',
+ 'CURSOR',
+ 'CV',
+ 'DATABASE',
+ 'DATAOBJ_TO_PARTITION',
+ 'DATE',
+ 'DAY',
+ 'DBTIMEZONE',
+ 'DECIMAL',
+ 'DECLARE',
+ 'DECODE',
+ 'DECOMPOSE',
+ 'DEFAULT',
+ 'DELETE',
+ 'DELETEXML',
+ 'DENSE_RANK',
+ 'DEPTH',
+ 'DEREF',
+ 'DESC',
+ 'DIMENSION',
+ 'DIRECTORY',
+ 'DISASSOCIATE',
+ 'DISTINCT',
+ 'DO',
+ 'DROP',
+ 'DUMP',
+ 'ELSE',
+ 'ELSIF',
+ 'EMPTY_BLOB',
+ 'EMPTY_CLOB',
+ 'END',
+ 'EXCEPTION',
+ 'EXCLUSIVE',
+ 'EXEC',
+ 'EXECUTE',
+ 'EXISTS',
+ 'EXISTSNODE',
+ 'EXIT',
+ 'EXP',
+ 'EXPLAIN',
+ 'EXTENDS',
+ 'EXTRACT',
+ 'EXTRACTVALUE',
+ 'FALSE',
+ 'FEATURE_ID',
+ 'FEATURE_SET',
+ 'FEATURE_VALUE',
+ 'FETCH',
+ 'FILE',
+ 'FIRST',
+ 'FIRST_VALUE',
+ 'FLOAT',
+ 'FLOOR',
+ 'FOR',
+ 'FORALL',
+ 'FROM',
+ 'FROM_TZ',
+ 'FUNCTION',
+ 'GOTO',
+ 'GRANT',
+ 'GREATEST',
+ 'GROUP',
+ 'GROUP_ID',
+ 'GROUPING',
+ 'GROUPING_ID',
+ 'HAVING',
+ 'HEAP',
+ 'HEXTORAW',
+ 'HOUR',
+ 'IDENTIFIED',
+ 'IF',
+ 'IMMEDIATE',
+ 'IN',
+ 'INCREMENT',
+ 'INDEX',
+ 'INDEXTYPE',
+ 'INDICATOR',
+ 'INITCAP',
+ 'INITIAL',
+ 'INSERT',
+ 'INSERTCHILDXML',
+ 'INSERTXMLBEFORE',
+ 'INSTR',
+ 'INSTRB',
+ 'INTEGER',
+ 'INTERFACE',
+ 'INTERSECT',
+ 'INTERVAL',
+ 'INTO',
+ 'IS',
+ 'ISOLATION',
+ 'ITERATION_NUMBER',
+ 'JAVA',
+ 'KEY',
+ 'LAG',
+ 'LAST',
+ 'LAST_DAY',
+ 'LAST_VALUE',
+ 'LEAD',
+ 'LEAST',
+ 'LENGTH',
+ 'LENGTHB',
+ 'LEVEL',
+ 'LIBRARY',
+ 'LIKE',
+ 'LIMITED',
+ 'LINK',
+ 'LN',
+ 'LNNVL',
+ 'LOCALTIMESTAMP',
+ 'LOCK',
+ 'LOG',
+ 'LONG',
+ 'LOOP',
+ 'LOWER',
+ 'LPAD',
+ 'LTRIM',
+ 'MAKE_REF',
+ 'MATERIALIZED',
+ 'MAX',
+ 'MAXEXTENTS',
+ 'MEDIAN',
+ 'MIN',
+ 'MINUS',
+ 'MINUTE',
+ 'MLSLABEL',
+ 'MOD',
+ 'MODE',
+ 'MODIFY',
+ 'MONTH',
+ 'MONTHS_BETWEEN',
+ 'NANVL',
+ 'NATURAL',
+ 'NATURALN',
+ 'NCHR',
+ 'NEW',
+ 'NEW_TIME',
+ 'NEXT_DAY',
+ 'NEXTVAL',
+ 'NLS_CHARSET_DECL_LEN',
+ 'NLS_CHARSET_ID',
+ 'NLS_CHARSET_NAME',
+ 'NLS_INITCAP',
+ 'NLS_LOWER',
+ 'NLS_UPPER',
+ 'NLSSORT',
+ 'NOAUDIT',
+ 'NOCOMPRESS',
+ 'NOCOPY',
+ 'NOT',
+ 'NOWAIT',
+ 'NTILE',
+ 'NULL',
+ 'NULLIF',
+ 'NUMBER',
+ 'NUMBER_BASE',
+ 'NUMTODSINTERVAL',
+ 'NUMTOYMINTERVAL',
+ 'NVL',
+ 'NVL2',
+ 'OCIROWID',
+ 'OF',
+ 'OFFLINE',
+ 'ON',
+ 'ONLINE',
+ 'OPAQUE',
+ 'OPEN',
+ 'OPERATOR',
+ 'OPTION',
+ 'OR',
+ 'ORA_HASH',
+ 'ORDER',
+ 'ORGANIZATION',
+ 'OTHERS',
+ 'OUT',
+ 'OUTLINE',
+ 'PACKAGE',
+ 'PARTITION',
+ 'PATH',
+ 'PCTFREE',
+ 'PERCENT_RANK',
+ 'PERCENTILE_CONT',
+ 'PERCENTILE_DISC',
+ 'PLAN',
+ 'PLS_INTEGER',
+ 'POSITIVE',
+ 'POSITIVEN',
+ 'POWER',
+ 'POWERMULTISET',
+ 'POWERMULTISET_BY_CARDINALITY',
+ 'PRAGMA',
+ 'PREDICTION',
+ 'PREDICTION_BOUNDS',
+ 'PREDICTION_COST',
+ 'PREDICTION_DETAILS',
+ 'PREDICTION_PROBABILITY',
+ 'PREDICTION_SET',
+ 'PRESENTNNV',
+ 'PRESENTV',
+ 'PREVIOUS',
+ 'PRIMARY',
+ 'PRIOR',
+ 'PRIVATE',
+ 'PRIVILEGES',
+ 'PROCEDURE',
+ 'PROFILE',
+ 'PUBLIC',
+ 'RAISE',
+ 'RANGE',
+ 'RANK',
+ 'RATIO_TO_REPORT',
+ 'RAW',
+ 'RAWTOHEX',
+ 'RAWTONHEX',
+ 'REAL',
+ 'RECORD',
+ 'REF',
+ 'REFTOHEX',
+ 'REGEXP_COUNT',
+ 'REGEXP_INSTR',
+ 'REGEXP_REPLACE',
+ 'REGEXP_SUBSTR',
+ 'REGR_AVGX',
+ 'REGR_AVGY',
+ 'REGR_COUNT',
+ 'REGR_INTERCEPT',
+ 'REGR_R2',
+ 'REGR_SLOPE',
+ 'REGR_SXX',
+ 'REGR_SXY',
+ 'REGR_SYY',
+ 'RELEASE',
+ 'REMAINDER',
+ 'RENAME',
+ 'REPLACE',
+ 'RESOURCE',
+ 'RETURN',
+ 'RETURNING',
+ 'REVERSE',
+ 'REVOKE',
+ 'ROLE',
+ 'ROLLBACK',
+ 'ROUND',
+ 'ROW',
+ 'ROW_NUMBER',
+ 'ROWID',
+ 'ROWIDTOCHAR',
+ 'ROWIDTONCHAR',
+ 'ROWNUM',
+ 'ROWS',
+ 'ROWTYPE',
+ 'RPAD',
+ 'RTRIM',
+ 'SAVEPOINT',
+ 'SCHEMA',
+ 'SCN_TO_TIMESTAMP',
+ 'SECOND',
+ 'SEGMENT',
+ 'SELECT',
+ 'SEPERATE',
+ 'SEQUENCE',
+ 'SESSION',
+ 'SESSIONTIMEZONE',
+ 'SET',
+ 'SHARE',
+ 'SIGN',
+ 'SIN',
+ 'SINH',
+ 'SIZE',
+ 'SMALLINT',
+ 'SOUNDEX',
+ 'SPACE',
+ 'SQL',
+ 'SQLCODE',
+ 'SQLERRM',
+ 'SQRT',
+ 'START',
+ 'STATISTICS',
+ 'STATS_BINOMIAL_TEST',
+ 'STATS_CROSSTAB',
+ 'STATS_F_TEST',
+ 'STATS_KS_TEST',
+ 'STATS_MODE',
+ 'STATS_MW_TEST',
+ 'STATS_ONE_WAY_ANOVA',
+ 'STATS_T_TEST_INDEP',
+ 'STATS_T_TEST_INDEPU',
+ 'STATS_T_TEST_ONE',
+ 'STATS_T_TEST_PAIRED',
+ 'STATS_WSR_TEST',
+ 'STDDEV',
+ 'STDDEV_POP',
+ 'STDDEV_SAMP',
+ 'STOP',
+ 'SUBSTR',
+ 'SUBSTRB',
+ 'SUBTYPE',
+ 'SUCCESSFUL',
+ 'SUM',
+ 'SYNONYM',
+ 'SYS_CONNECT_BY_PATH',
+ 'SYS_CONTEXT',
+ 'SYS_DBURIGEN',
+ 'SYS_EXTRACT_UTC',
+ 'SYS_GUID',
+ 'SYS_TYPEID',
+ 'SYS_XMLAGG',
+ 'SYS_XMLGEN',
+ 'SYSDATE',
+ 'SYSTEM',
+ 'SYSTIMESTAMP',
+ 'TABLE',
+ 'TABLESPACE',
+ 'TAN',
+ 'TANH',
+ 'TEMPORARY',
+ 'THEN',
+ 'TIME',
+ 'TIMESTAMP',
+ 'TIMESTAMP_TO_SCN',
+ 'TIMEZONE_ABBR',
+ 'TIMEZONE_HOUR',
+ 'TIMEZONE_MINUTE',
+ 'TIMEZONE_REGION',
+ 'TIMING',
+ 'TO',
+ 'TO_BINARY_DOUBLE',
+ 'TO_BINARY_FLOAT',
+ 'TO_CHAR',
+ 'TO_CLOB',
+ 'TO_DATE',
+ 'TO_DSINTERVAL',
+ 'TO_LOB',
+ 'TO_MULTI_BYTE',
+ 'TO_NCHAR',
+ 'TO_NCLOB',
+ 'TO_NUMBER',
+ 'TO_SINGLE_BYTE',
+ 'TO_TIMESTAMP',
+ 'TO_TIMESTAMP_TZ',
+ 'TO_YMINTERVAL',
+ 'TRANSACTION',
+ 'TRANSLATE',
+ 'TREAT',
+ 'TRIGGER',
+ 'TRIM',
+ 'TRUE',
+ 'TRUNC',
+ 'TRUNCATE',
+ 'TYPE',
+ 'TZ_OFFSET',
+ 'UI',
+ 'UID',
+ 'UNION',
+ 'UNIQUE',
+ 'UNISTR',
+ 'UPDATE',
+ 'UPDATEXML',
+ 'UPPER',
+ 'USE',
+ 'USER',
+ 'USERENV',
+ 'USING',
+ 'VALIDATE',
+ 'VALUE',
+ 'VALUES',
+ 'VAR_POP',
+ 'VAR_SAMP',
+ 'VARCHAR',
+ 'VARCHAR2',
+ 'VARIANCE',
+ 'VIEW',
+ 'VSIZE',
+ 'WHEN',
+ 'WHENEVER',
+ 'WHERE',
+ 'WHILE',
+ 'WIDTH_BUCKET',
+ 'WITH',
+ 'WORK',
+ 'WRITE',
+ 'XMLAGG',
+ 'XMLCAST',
+ 'XMLCDATA',
+ 'XMLCOLATTVAL',
+ 'XMLCOMMENT',
+ 'XMLCONCAT',
+ 'XMLDIFF',
+ 'XMLELEMENT',
+ 'XMLEXISTS',
+ 'XMLFOREST',
+ 'XMLPARSE',
+ 'XMLPATCH',
+ 'XMLPI',
+ 'XMLQUERY',
+ 'XMLROOT',
+ 'XMLSEQUENCE',
+ 'XMLSERIALIZE',
+ 'XMLTABLE',
+ 'XMLTRANSFORM',
+ 'YEAR',
+ 'ZONE'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '=', '<', '>', '|', '+', '-', '*', '/', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+// 3 => false,
+// 4 => false,
+// 5 => false,
+// 6 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #993333; font-weight: bold; text-transform: uppercase;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #ff0000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+// 3 => '',
+// 4 => '',
+// 5 => '',
+// 6 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/oracle8.php b/platform/www/vendor/geshi/geshi/src/geshi/oracle8.php
new file mode 100644
index 0000000..f723e65
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/oracle8.php
@@ -0,0 +1,494 @@
+<?php
+/*************************************************************************************
+ * oracle8.php
+ * -----------
+ * Author: Guy Wicks (Guy.Wicks@rbs.co.uk)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/04
+ *
+ * Oracle 8 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/01/29 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Oracle 8 SQL',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array("'", '"', '`'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+//Put your package names here - e.g. select distinct ''''|| lower(name) || ''',' from user_source;
+// 6 => array(
+// ),
+
+//Put your table names here - e.g. select distinct ''''|| lower(table_name) || ''',' from user_tables;
+// 5 => array(
+// ),
+
+//Put your view names here - e.g. select distinct ''''|| lower(view_name) || ''',' from user_views;
+// 4 => array(
+// ),
+
+//Put your table field names here - e.g. select distinct ''''|| lower(column_name) || ''',' from user_tab_columns;
+// 3 => array(
+// ),
+
+//Put ORACLE reserved keywords here (8.1.7). I like mine uppercase.
+ 1 => array(
+ 'ABS',
+ 'ACCESS',
+ 'ACOS',
+ 'ADD',
+ 'ADD_MONTHS',
+ 'ALL',
+ 'ALTER',
+ 'ANALYZE',
+ 'AND',
+ 'ANY',
+ 'ARRAY',
+ 'AS',
+ 'ASC',
+ 'ASCII',
+ 'ASIN',
+ 'ASSOCIATE',
+ 'AT',
+ 'ATAN',
+ 'ATAN2',
+ 'AUDIT',
+ 'AUTHID',
+ 'AVG',
+ 'BEGIN',
+ 'BETWEEN',
+ 'BFILENAME',
+ 'BINARY_INTEGER',
+ 'BITAND',
+ 'BODY',
+ 'BOOLEAN',
+ 'BULK',
+ 'BY',
+ 'CALL',
+ 'CASCADE',
+ 'CASE',
+ 'CEIL',
+ 'CHAR',
+ 'CHAR_BASE',
+ 'CHARTOROWID',
+ 'CHECK',
+ 'CHR',
+ 'CLOSE',
+ 'CLUSTER',
+ 'COALESCE',
+ 'COLLECT',
+ 'COLUMN',
+ 'COMMENT',
+ 'COMMIT',
+ 'COMPRESS',
+ 'CONCAT',
+ 'CONNECT',
+ 'CONSTANT',
+ 'CONSTRAINT',
+ 'CONSTRAINTS',
+ 'CONTEXT',
+ 'CONTROLFILE',
+ 'CONVERT',
+ 'CORR',
+ 'COS',
+ 'COSH',
+ 'COST',
+ 'COUNT',
+ 'COVAR_POP',
+ 'COVAR_SAMP',
+ 'CREATE',
+ 'CUME_DIST',
+ 'CURRENT',
+ 'CURRVAL',
+ 'CURSOR',
+ 'DATABASE',
+ 'DATE',
+ 'DAY',
+ 'DECIMAL',
+ 'DECLARE',
+ 'DECODE',
+ 'DEFAULT',
+ 'DELETE',
+ 'DENSE_RANK',
+ 'DEREF',
+ 'DESC',
+ 'DIMENSION',
+ 'DIRECTORY',
+ 'DISASSOCIATE',
+ 'DISTINCT',
+ 'DO',
+ 'DROP',
+ 'DUMP',
+ 'ELSE',
+ 'ELSIF',
+ 'EMPTY_BLOB',
+ 'EMPTY_CLOB',
+ 'END',
+ 'EXCEPTION',
+ 'EXCLUSIVE',
+ 'EXEC',
+ 'EXECUTE',
+ 'EXISTS',
+ 'EXIT',
+ 'EXP',
+ 'EXPLAIN',
+ 'EXTENDS',
+ 'EXTRACT',
+ 'FALSE',
+ 'FETCH',
+ 'FILE',
+ 'FIRST_VALUE',
+ 'FLOAT',
+ 'FLOOR',
+ 'FOR',
+ 'FORALL',
+ 'FROM',
+ 'FUNCTION',
+ 'GOTO',
+ 'GRANT',
+ 'GREATEST',
+ 'GROUP',
+ 'GROUPING',
+ 'HAVING',
+ 'HEAP',
+ 'HEXTORAW',
+ 'HOUR',
+ 'IDENTIFIED',
+ 'IF',
+ 'IMMEDIATE',
+ 'IN',
+ 'INCREMENT',
+ 'INDEX',
+ 'INDEXTYPE',
+ 'INDICATOR',
+ 'INITCAP',
+ 'INITIAL',
+ 'INSERT',
+ 'INSTR',
+ 'INSTRB',
+ 'INTEGER',
+ 'INTERFACE',
+ 'INTERSECT',
+ 'INTERVAL',
+ 'INTO',
+ 'IS',
+ 'ISOLATION',
+ 'JAVA',
+ 'KEY',
+ 'LAG',
+ 'LAST_DAY',
+ 'LAST_VALUE',
+ 'LEAD',
+ 'LEAST',
+ 'LENGTH',
+ 'LENGTHB',
+ 'LEVEL',
+ 'LIBRARY',
+ 'LIKE',
+ 'LIMITED',
+ 'LINK',
+ 'LN',
+ 'LOCK',
+ 'LOG',
+ 'LONG',
+ 'LOOP',
+ 'LOWER',
+ 'LPAD',
+ 'LTRIM',
+ 'MAKE_REF',
+ 'MATERIALIZED',
+ 'MAX',
+ 'MAXEXTENTS',
+ 'MIN',
+ 'MINUS',
+ 'MINUTE',
+ 'MLSLABEL',
+ 'MOD',
+ 'MODE',
+ 'MODIFY',
+ 'MONTH',
+ 'MONTHS_BETWEEN',
+ 'NATURAL',
+ 'NATURALN',
+ 'NEW',
+ 'NEW_TIME',
+ 'NEXT_DAY',
+ 'NEXTVAL',
+ 'NLS_CHARSET_DECL_LEN',
+ 'NLS_CHARSET_ID',
+ 'NLS_CHARSET_NAME',
+ 'NLS_INITCAP',
+ 'NLS_LOWER',
+ 'NLS_UPPER',
+ 'NLSSORT',
+ 'NOAUDIT',
+ 'NOCOMPRESS',
+ 'NOCOPY',
+ 'NOT',
+ 'NOWAIT',
+ 'NTILE',
+ 'NULL',
+ 'NULLIF',
+ 'NUMBER',
+ 'NUMBER_BASE',
+ 'NUMTODSINTERVAL',
+ 'NUMTOYMINTERVAL',
+ 'NVL',
+ 'NVL2',
+ 'OCIROWID',
+ 'OF',
+ 'OFFLINE',
+ 'ON',
+ 'ONLINE',
+ 'OPAQUE',
+ 'OPEN',
+ 'OPERATOR',
+ 'OPTION',
+ 'OR',
+ 'ORDER',
+ 'ORGANIZATION',
+ 'OTHERS',
+ 'OUT',
+ 'OUTLINE',
+ 'PACKAGE',
+ 'PARTITION',
+ 'PCTFREE',
+ 'PERCENT_RANK',
+ 'PLAN',
+ 'PLS_INTEGER',
+ 'POSITIVE',
+ 'POSITIVEN',
+ 'POWER',
+ 'PRAGMA',
+ 'PRIMARY',
+ 'PRIOR',
+ 'PRIVATE',
+ 'PRIVILEGES',
+ 'PROCEDURE',
+ 'PROFILE',
+ 'PUBLIC',
+ 'RAISE',
+ 'RANGE',
+ 'RANK',
+ 'RATIO_TO_REPORT',
+ 'RAW',
+ 'RAWTOHEX',
+ 'REAL',
+ 'RECORD',
+ 'REF',
+ 'REFTOHEX',
+ 'REGR_AVGX',
+ 'REGR_AVGY',
+ 'REGR_COUNT',
+ 'REGR_INTERCEPT',
+ 'REGR_R2',
+ 'REGR_SLOPE',
+ 'REGR_SXX',
+ 'REGR_SXY',
+ 'REGR_SYY',
+ 'RELEASE',
+ 'RENAME',
+ 'REPLACE',
+ 'RESOURCE',
+ 'RETURN',
+ 'RETURNING',
+ 'REVERSE',
+ 'REVOKE',
+ 'ROLE',
+ 'ROLLBACK',
+ 'ROUND',
+ 'ROW',
+ 'ROW_NUMBER',
+ 'ROWID',
+ 'ROWIDTOCHAR',
+ 'ROWNUM',
+ 'ROWS',
+ 'ROWTYPE',
+ 'RPAD',
+ 'RTRIM',
+ 'SAVEPOINT',
+ 'SCHEMA',
+ 'SECOND',
+ 'SEGMENT',
+ 'SELECT',
+ 'SEPERATE',
+ 'SEQUENCE',
+ 'SESSION',
+ 'SET',
+ 'SHARE',
+ 'SIGN',
+ 'SIN',
+ 'SINH',
+ 'SIZE',
+ 'SMALLINT',
+ 'SOUNDEX',
+ 'SPACE',
+ 'SQL',
+ 'SQLCODE',
+ 'SQLERRM',
+ 'SQRT',
+ 'START',
+ 'STATISTICS',
+ 'STDDEV',
+ 'STDDEV_POP',
+ 'STDDEV_SAMP',
+ 'STOP',
+ 'SUBSTR',
+ 'SUBSTRB',
+ 'SUBTYPE',
+ 'SUCCESSFUL',
+ 'SUM',
+ 'SYNONYM',
+ 'SYS_CONTEXT',
+ 'SYS_GUID',
+ 'SYSDATE',
+ 'SYSTEM',
+ 'TABLE',
+ 'TABLESPACE',
+ 'TAN',
+ 'TANH',
+ 'TEMPORARY',
+ 'THEN',
+ 'TIME',
+ 'TIMESTAMP',
+ 'TIMEZONE_ABBR',
+ 'TIMEZONE_HOUR',
+ 'TIMEZONE_MINUTE',
+ 'TIMEZONE_REGION',
+ 'TIMING',
+ 'TO',
+ 'TO_CHAR',
+ 'TO_DATE',
+ 'TO_LOB',
+ 'TO_MULTI_BYTE',
+ 'TO_NUMBER',
+ 'TO_SINGLE_BYTE',
+ 'TRANSACTION',
+ 'TRANSLATE',
+ 'TRIGGER',
+ 'TRIM',
+ 'TRUE',
+ 'TRUNC',
+ 'TRUNCATE',
+ 'TYPE',
+ 'UI',
+ 'UID',
+ 'UNION',
+ 'UNIQUE',
+ 'UPDATE',
+ 'UPPER',
+ 'USE',
+ 'USER',
+ 'USERENV',
+ 'USING',
+ 'VALIDATE',
+ 'VALUE',
+ 'VALUES',
+ 'VAR_POP',
+ 'VAR_SAMP',
+ 'VARCHAR',
+ 'VARCHAR2',
+ 'VARIANCE',
+ 'VIEW',
+ 'VSIZE',
+ 'WHEN',
+ 'WHENEVER',
+ 'WHERE',
+ 'WHILE',
+ 'WITH',
+ 'WORK',
+ 'WRITE',
+ 'YEAR',
+ 'ZONE'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '=', '<', '>', '|', '+', '-', '*', '/', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+// 3 => false,
+// 4 => false,
+// 5 => false,
+// 6 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #993333; font-weight: bold; text-transform: uppercase;'
+//Add the styles for groups 3-6 here when used
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #ff0000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+// 3 => '',
+// 4 => '',
+// 5 => '',
+// 6 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/oxygene.php b/platform/www/vendor/geshi/geshi/src/geshi/oxygene.php
new file mode 100644
index 0000000..ac7e88c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/oxygene.php
@@ -0,0 +1,155 @@
+<?php
+/*************************************************************************************
+ * oxygene.php
+ * ----------
+ * Author: Carlo Kok (ck@remobjects.com), J�rja Norbert (jnorbi@vipmail.hu), Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2004 J�rja Norbert, Benny Baumann (BenBE@omorphia.de), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/01/11
+ *
+ * Delphi Prism (Oxygene) language file for GeSHi.
+ * Based on the original Delphi language file.
+ *
+ * CHANGES
+ * -------
+ * 2014/01/09 (1.0.8.13)
+ * - New keywords & updated languge name
+ * 2012/06/28 (1.0.8.11)
+ * - Added "write" keyword for properties
+ * 2010/01/11 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Oxygene',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('(*' => '*)', '{' => '}'),
+ //Compiler directives
+ 'COMMENT_REGEXP' => array(2 => '/{\\$.*?}|\\(\\*\\$.*?\\*\\)/U'),
+ 'CASE_KEYWORDS' => 0,
+ 'QUOTEMARKS' => array("'"),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'and', 'begin', 'case', 'const', 'div', 'do', 'downto', 'else',
+ 'end', 'for', 'function', 'if', 'in', 'mod', 'not', 'of', 'or',
+ 'procedure', 'repeat', 'record', 'set', 'shl', 'shr', 'then', 'to',
+ 'type', 'until', 'uses', 'var','while', 'with', 'xor', 'exit', 'break',
+ 'class', 'constructor', 'inherited', 'private', 'public', 'protected',
+ 'property', 'As', 'Is', 'Unit', 'Continue', 'Try', 'Except', 'Forward',
+ 'Interface','Implementation', 'nil', 'out', 'loop', 'namespace', 'true',
+ 'false', 'new', 'ensure', 'require', 'on', 'event', 'delegate', 'method',
+ 'raise', 'assembly', 'module', 'using','locking', 'old', 'invariants', 'operator',
+ 'self', 'async', 'finalizer', 'where', 'yield', 'nullable', 'Future',
+ 'From', 'Finally', 'dynamic', 'mapped'
+ ),
+ 2 => array(
+ 'override', 'virtual', 'External', 'read', 'add', 'remove','final', 'abstract',
+ 'empty', 'global', 'locked', 'sealed', 'reintroduce', 'implements', 'each',
+ 'default', 'partial', 'finalize', 'enum', 'flags', 'result', 'readonly', 'unsafe',
+ 'pinned', 'matching', 'static', 'has', 'step', 'iterator', 'inline', 'nested',
+ 'Implies', 'Select', 'Order', 'By', 'Desc', 'Asc', 'Group', 'Join', 'Take',
+ 'Skip', 'Concat', 'Union', 'Reverse', 'Distinct', 'Into', 'Equals', 'params',
+ 'sequence', 'index', 'notify', 'Parallel', 'create', 'array', 'Queryable', 'Aspect',
+ 'volatile', 'write', 'autoreleasepool', 'await', 'block', 'deprecated', 'extension',
+ 'optional', 'raises', 'selector', 'strong', 'weak', 'tuple', 'unretained'
+ ),
+ 3 => array(
+ 'chr', 'ord', 'inc', 'dec', 'assert', 'iff', 'assigned','futureAssigned', 'length', 'low', 'high', 'typeOf', 'sizeOf', 'disposeAndNil', 'Coalesce', 'unquote'
+ ),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+// 4 => false,
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '[', ']'),
+ 1 => array('.', ',', ':', ';'),
+ 2 => array('@', '^'),
+ 3 => array('=', '+', '-', '*', '/')
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+// 4 => 'color: #000066; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #008000; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #ff0000; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #9ac;',
+ 1 => 'color: #ff0000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066;',
+ 1 => 'color: #000066;',
+ 2 => 'color: #000066;',
+ 3 => 'color: #000066;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+// 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ //Hex numbers
+ 0 => '\$[0-9a-fA-F]+',
+ //Characters
+ 1 => '\#\$?[0-9]{1,3}'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 2
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/oz.php b/platform/www/vendor/geshi/geshi/src/geshi/oz.php
new file mode 100644
index 0000000..943eb8d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/oz.php
@@ -0,0 +1,142 @@
+<?php
+/*************************************************************************************
+ * oz.php
+ * --------
+ * Author: Wolfgang Meyer (Wolfgang.Meyer@gmx.net)
+ * Copyright: (c) 2010 Wolfgang Meyer
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/01/03
+ *
+ * Oz language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'OZ',
+ 'COMMENT_SINGLE' => array(1 => '%'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"','\''),
+ 'ESCAPE_CHAR' => '\\',
+ 'NUMBERS' => array(),
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'declare','local','in','end','proc','fun','functor','require','prepare',
+ 'import','export','define','at','case','then','else','of','elseof',
+ 'elsecase','if','elseif','class','from','prop','attr','feat','meth',
+ 'self','true','false','unit','div','mod','andthen','orelse','cond','or',
+ 'dis','choice','not','thread','try','catch','finally','raise','lock',
+ 'skip','fail','for','do'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true
+ ),
+ 'SYMBOLS' => array(
+ '@', '!', '|', '<-', ':=', '<', '>', '=<', '>=', '<=', '#', '~', '.',
+ '*', '-', '+', '/', '<:', '>:', '=:', '=<:', '>=:', '\\=', '\\=:', ',',
+ '!!', '...', '==', '::', ':::'
+ ),
+ 'STYLES' => array(
+ 'REGEXPS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #00a030;',
+ 3 => 'color: #bc8f8f;',
+ 4 => 'color: #0000ff;',
+ 5 => 'color: #a020f0;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #bc8f8f;'
+ ),
+ 'KEYWORDS' => array(
+ 1 => 'color: #a020f0;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #B22222;',
+ 'MULTI' => 'color: #B22222;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #bc8f8f;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #a020f0;'
+ ),
+ 'BRACKETS' => array(),
+ 'NUMBERS' => array(),
+ 'METHODS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'REGEXPS' => array(
+ // function and procedure definition
+ 1 => array(
+ GESHI_SEARCH => "(proc|fun)([^{}\n\)]*)(\\{)([\$A-Z\300-\326\330-\336][A-Z\300-\326\330-\336a-z\337-\366\370-\3770-9_.]*)",
+ GESHI_REPLACE => '\4',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\1\2\3',
+ GESHI_AFTER => ''
+ ),
+ // class definition
+ 2 => array(
+ GESHI_SEARCH => "(class)([^A-Z\$]*)([\$A-Z\300-\326\330-\336][A-Z\300-\326\330-\336a-z\337-\366\370-\3770-9_.]*)",
+ GESHI_REPLACE => '\3\4',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\1\2',
+ GESHI_AFTER => ''
+ ),
+ // single character
+ 3 => array(
+ GESHI_SEARCH => "&amp;.",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ // method definition
+ 4 => array(
+ GESHI_SEARCH => "(meth)([^a-zA-Z]+)([a-zA-Z\300-\326\330-\336][A-Z\300-\326\330-\336a-z\337-\366\370-\3770-9]*)",
+ GESHI_REPLACE => '\3',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\1\2',
+ GESHI_AFTER => ''
+ ),
+ // highlight "[]"
+ // ([] is actually a keyword, but that causes problems in validation; putting it into symbols doesn't work.)
+ 5 => array(
+ GESHI_SEARCH => "\[\]",
+ GESHI_REPLACE => '\0',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/parasail.php b/platform/www/vendor/geshi/geshi/src/geshi/parasail.php
new file mode 100644
index 0000000..7a136b9
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/parasail.php
@@ -0,0 +1,128 @@
+<?php
+/*************************************************************************************
+ * parasail.php
+ * -------
+ * Author: T. Taft (taft@adacore.com)
+ * Copyright: (c) 2012 AdaCore (http://adacore.com/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/08/02
+ *
+ * ParaSail language file for GeSHi.
+ *
+ * Words are from SciTe configuration file
+ *
+ * CHANGES
+ * -------
+ * 2012/08/02 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2012/08/02)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ParaSail',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('{' => '}'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'all', 'block', 'case', 'continue', 'each',
+ 'else', 'elsif', 'exit', 'for',
+ 'forward', 'if', 'loop', 'return', 'reverse', 'some',
+ 'then', 'until', 'while', 'with'
+ ),
+ 2 => array(
+ 'abs', 'and','in', 'mod', 'not', 'null', 'or', 'rem', 'xor'
+ ),
+ 3 => array(
+ 'abstract', 'class',
+ 'concurrent', 'const',
+ 'end', 'extends', 'exports',
+ 'func', 'global', 'implements', 'import',
+ 'interface', 'is', 'lambda', 'locked',
+ 'new', 'of', 'op', 'optional',
+ 'private', 'queued', 'ref',
+ 'separate', 'type', 'var',
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00007f;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #46aa03; font-weight:bold;',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/parigp.php b/platform/www/vendor/geshi/geshi/src/geshi/parigp.php
new file mode 100644
index 0000000..fe99c10
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/parigp.php
@@ -0,0 +1,293 @@
+<?php
+/*************************************************************************************
+ * parigp.php
+ * --------
+ * Author: Charles R Greathouse IV (charles@crg4.com)
+ * Copyright: 2011-2013 Charles R Greathouse IV (http://math.crg4.com/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/05/11
+ *
+ * PARI/GP language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2011/07/09 (1.0.8.11)
+ * - First Release
+ * 2013/02/05 (1.0.8.13)
+ * - Added 2.6.0 commands, default, member functions, and error-handling
+ *
+ * TODO (updated 2011/07/09)
+ * -------------------------
+ *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'PARI/GP',
+ 'COMMENT_SINGLE' => array(1 => '\\\\'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'NUMBERS' => array(
+ # Integers
+ 1 => GESHI_NUMBER_INT_BASIC,
+ # Reals
+ 2 => GESHI_NUMBER_FLT_SCI_ZERO
+ ),
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'abs','acos','acosh','addhelp','addprimes','agm','alarm','algdep',
+ 'alias','allocatemem','apply','arg','asin','asinh','atan','atanh',
+ 'bernfrac','bernpol','bernreal','bernvec','besselh1','besselh2',
+ 'besseli','besselj','besseljh','besselk','besseln','bestappr',
+ 'bestapprPade','bezout','bezoutres','bigomega','binary','binomial',
+ 'bitand','bitneg','bitnegimply','bitor','bittest','bitxor',
+ 'bnfcertify','bnfcompress','bnfdecodemodule','bnfinit',
+ 'bnfisintnorm','bnfisnorm','bnfisprincipal','bnfissunit',
+ 'bnfisunit','bnfnarrow','bnfsignunit','bnfsunit','bnrclassno',
+ 'bnrclassnolist','bnrconductor','bnrconductorofchar','bnrdisc',
+ 'bnrdisclist','bnrinit','bnrisconductor','bnrisprincipal','bnrL1',
+ 'bnrrootnumber','bnrstark','break','breakpoint','Catalan','ceil',
+ 'centerlift','charpoly','chinese','cmp','Col','component','concat',
+ 'conj','conjvec','content','contfrac','contfracpnqn','core',
+ 'coredisc','cos','cosh','cotan','dbg_down','dbg_err','dbg_up',
+ 'dbg_x','default','denominator','deriv','derivnum','diffop',
+ 'digits','dilog','dirdiv','direuler','dirmul','dirzetak','divisors',
+ 'divrem','eint1','elladd','ellak','ellan','ellanalyticrank','ellap',
+ 'ellbil','ellcard','ellchangecurve','ellchangepoint',
+ 'ellconvertname','elldivpol','elleisnum','elleta','ellffinit',
+ 'ellfromj','ellgenerators','ellglobalred','ellgroup','ellheegner',
+ 'ellheight','ellheightmatrix','ellidentify','ellinit',
+ 'ellisoncurve','ellj','ellL1','elllocalred','elllog','elllseries',
+ 'ellminimalmodel','ellmodulareqn','ellmul','ellneg','ellorder',
+ 'ellordinate','ellpointtoz','ellrootno','ellsearch','ellsigma',
+ 'ellsub','elltaniyama','elltatepairing','elltors','ellweilpairing',
+ 'ellwp','ellzeta','ellztopoint','erfc','errname','error','eta','Euler',
+ 'eulerphi','eval','exp','extern','externstr','factor','factorback',
+ 'factorcantor','factorff','factorial','factorint','factormod',
+ 'factornf','factorpadic','ffgen','ffinit','fflog','ffnbirred',
+ 'fforder','ffprimroot','fibonacci','floor','for','forcomposite','fordiv','forell',
+ 'forprime','forqfvec','forstep','forsubgroup','forvec','frac','galoisexport',
+ 'galoisfixedfield','galoisgetpol','galoisidentify','galoisinit',
+ 'galoisisabelian','galoisisnormal','galoispermtopol',
+ 'galoissubcyclo','galoissubfields','galoissubgroups','gamma',
+ 'gammah','gcd','getenv','getheap','getrand','getstack','gettime',
+ 'global','hammingweight','hilbert','hyperu','I','idealadd',
+ 'idealaddtoone','idealappr','idealchinese','idealcoprime',
+ 'idealdiv','idealfactor','idealfactorback','idealfrobenius',
+ 'idealhnf','idealintersect','idealinv','ideallist','ideallistarch',
+ 'ideallog','idealmin','idealmul','idealnorm','idealnumden',
+ 'idealpow','idealprimedec','idealramgroups','idealred','idealstar',
+ 'idealtwoelt','idealval','if','iferr','iferrname','imag','incgam','incgamc','input',
+ 'install','intcirc','intformal','intfouriercos','intfourierexp',
+ 'intfouriersin','intfuncinit','intlaplaceinv','intmellininv',
+ 'intmellininvshort','intnum','intnuminit','intnuminitgen',
+ 'intnumromb','intnumstep','isfundamental','ispolygonal','ispower','ispowerful',
+ 'isprime','isprimepower','ispseudoprime','issquare','issquarefree','istotient',
+ 'kill','kronecker','lcm','length','lex','lift','lindep','List',
+ 'listcreate','listinsert','listkill','listpop','listput','listsort',
+ 'lngamma','local','log','Mat','matadjoint','matalgtobasis',
+ 'matbasistoalg','matcompanion','matconcat','matcontent','matdet','matdetint',
+ 'matdiagonal','mateigen','matfrobenius','mathess','mathilbert',
+ 'mathnf','mathnfmod','mathnfmodid','matid','matimage',
+ 'matimagecompl','matindexrank','matintersect','matinverseimage',
+ 'matisdiagonal','matker','matkerint','matmuldiagonal',
+ 'matmultodiagonal','matpascal','matrank','matrix','matrixqz',
+ 'matsize','matsnf','matsolve','matsolvemod','matsupplement',
+ 'mattranspose','max','min','minpoly','Mod','modreverse','moebius',
+ 'my','newtonpoly','next','nextprime','nfalgtobasis','nfbasis',
+ 'nfbasistoalg','nfdetint','nfdisc','nfeltadd','nfeltdiv',
+ 'nfeltdiveuc','nfeltdivmodpr','nfeltdivrem','nfeltmod','nfeltmul',
+ 'nfeltmulmodpr','nfeltnorm','nfeltpow','nfeltpowmodpr',
+ 'nfeltreduce','nfeltreducemodpr','nfelttrace','nfeltval','nffactor',
+ 'nffactorback','nffactormod','nfgaloisapply','nfgaloisconj',
+ 'nfhilbert','nfhnf','nfhnfmod','nfinit','nfisideal','nfisincl',
+ 'nfisisom','nfkermodpr','nfmodprinit','nfnewprec','nfroots',
+ 'nfrootsof1','nfsnf','nfsolvemodpr','nfsubfields','norm','norml2',
+ 'numbpart','numdiv','numerator','numtoperm','O','omega','padicappr',
+ 'padicfields','padicprec','partitions','permtonum','Pi','plot',
+ 'plotbox','plotclip','plotcolor','plotcopy','plotcursor','plotdraw',
+ 'ploth','plothraw','plothsizes','plotinit','plotkill','plotlines',
+ 'plotlinetype','plotmove','plotpoints','plotpointsize',
+ 'plotpointtype','plotrbox','plotrecth','plotrecthraw','plotrline',
+ 'plotrmove','plotrpoint','plotscale','plotstring','Pol',
+ 'polchebyshev','polcoeff','polcompositum','polcyclo','polcyclofactors','poldegree',
+ 'poldisc','poldiscreduced','polgalois','polgraeffe','polhensellift',
+ 'polhermite','polinterpolate','poliscyclo','poliscycloprod',
+ 'polisirreducible','pollead','pollegendre','polrecip','polred',
+ 'polredabs','polredbest','polredord','polresultant','Polrev','polroots',
+ 'polrootsff','polrootsmod','polrootspadic','polsturm','polsubcyclo',
+ 'polsylvestermatrix','polsym','poltchebi','poltschirnhaus',
+ 'polylog','polzagier','precision','precprime','prime','primepi',
+ 'primes','print','print1','printf','printsep','printtex','prod','prodeuler',
+ 'prodinf','psdraw','psi','psploth','psplothraw','Qfb','qfbclassno',
+ 'qfbcompraw','qfbhclassno','qfbnucomp','qfbnupow','qfbpowraw',
+ 'qfbprimeform','qfbred','qfbsolve','qfgaussred','qfjacobi','qflll',
+ 'qflllgram','qfminim','qfperfection','qfrep','qfsign',
+ 'quadclassunit','quaddisc','quadgen','quadhilbert','quadpoly',
+ 'quadray','quadregulator','quadunit','quit','random','randomprime','read',
+ 'readvec','real','removeprimes','return','rnfalgtobasis','rnfbasis',
+ 'rnfbasistoalg','rnfcharpoly','rnfconductor','rnfdedekind','rnfdet',
+ 'rnfdisc','rnfeltabstorel','rnfeltdown','rnfeltreltoabs','rnfeltup',
+ 'rnfequation','rnfhnfbasis','rnfidealabstorel','rnfidealdown',
+ 'rnfidealhnf','rnfidealmul','rnfidealnormabs','rnfidealnormrel',
+ 'rnfidealreltoabs','rnfidealtwoelt','rnfidealup','rnfinit',
+ 'rnfisabelian','rnfisfree','rnfisnorm','rnfisnorminit','rnfkummer',
+ 'rnflllgram','rnfnormgroup','rnfpolred','rnfpolredabs',
+ 'rnfpseudobasis','rnfsteinitz','round','select','Ser','serconvol',
+ 'serlaplace','serreverse','Set','setbinop','setintersect',
+ 'setisset','setminus','setrand','setsearch','setunion','shift',
+ 'shiftmul','sigma','sign','simplify','sin','sinh','sizebyte',
+ 'sizedigit','solve','sqr','sqrt','sqrtint','sqrtn','sqrtnint','stirling','Str',
+ 'Strchr','Strexpand','Strprintf','Strtex','subgrouplist','subst',
+ 'substpol','substvec','sum','sumalt','sumdedekind','sumdiv','sumdivmult','sumdigits',
+ 'sumformal','suminf','sumnum','sumnumalt','sumnuminit','sumpos','system','tan',
+ 'tanh','taylor','teichmuller','theta','thetanullk','thue',
+ 'thueinit','trace','trap','truncate','type','until','valuation',
+ 'variable','Vec','vecextract','vecmax','vecmin','Vecrev',
+ 'vecsearch','Vecsmall','vecsort','vector','vectorsmall','vectorv',
+ 'version','warning','weber','whatnow','while','write','write1',
+ 'writebin','writetex','zeta','zetak','zetakinit','zncoppersmith',
+ 'znlog','znorder','znprimroot','znstar'
+ ),
+
+ 2 => array(
+ 'void','bool','negbool','small','int',/*'real',*/'mp','var','lg','pol',
+ 'vecsmall','vec','list','str','genstr','gen','typ'
+ ),
+
+ 3 => array(
+ 'TeXstyle','breakloop','colors','compatible','datadir','debug',
+ 'debugfiles','debugmem','echo','factor_add_primes','factor_proven',
+ 'format','graphcolormap','graphcolors','help','histfile','histsize',
+ 'lines','linewrap',/*'log',*/'logfile','new_galois_format','output',
+ 'parisize','path','prettyprinter','primelimit','prompt_cont',
+ 'prompt','psfile','readline','realprecision','recover','secure',
+ 'seriesprecision',/*'simplify',*/'sopath','strictmatch','timer'
+ ),
+
+ 4 => array(
+ '"e_ARCH"','"e_BUG"','"e_FILE"','"e_IMPL"','"e_PACKAGE"','"e_DIM"',
+ '"e_FLAG"','"e_NOTFUNC"','"e_OP"','"e_TYPE"','"e_TYPE2"',
+ '"e_PRIORITY"','"e_VAR"','"e_DOMAIN"','"e_MAXPRIME"','"e_MEM"',
+ '"e_OVERFLOW"','"e_PREC"','"e_STACK"','"e_ALARM"','"e_USER"',
+ '"e_CONSTPOL"','"e_COPRIME"','"e_INV"','"e_IRREDPOL"','"e_MISC"',
+ '"e_MODULUS"','"e_NEGVAL"','"e_PRIME"','"e_ROOTS0"','"e_SQRTN"'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '(',')','{','}','[',']','+','-','*','/','%','=','<','>','!','^','&','|','?',';',':',',','\\','\''
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #e07022;',
+ 3 => 'color: #00d2d2;',
+ 4 => 'color: #00d2d2;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000;',
+ 'MULTI' => 'color: #008000;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #111111; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #002222;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #800080;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #666666;',
+ 1 => 'color: #666666;',
+ 2 => 'color: #666666;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #e07022', # Should be the same as keyword group 2
+ 1 => 'color: #555555',
+ 2 => 'color: #0000ff' # Should be the same as keyword group 1
+ ),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ 0 => array( # types marked on variables
+ GESHI_SEARCH => '(?<!\\\\ )"(t_(?:INT|REAL|INTMOD|FRAC|FFELT|COMPLEX|PADIC|QUAD|POLMOD|POL|SER|RFRAC|QFR|QFI|VEC|COL|MAT|LIST|STR|VECSMALL|CLOSURE|ERROR))"',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '"',
+ GESHI_AFTER => '"'
+ ),
+ 1 => array( # literal variables
+ GESHI_SEARCH => '(?<!\\\\)(\'[a-zA-Z][a-zA-Z0-9_]*)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 2 => array( # member functions
+ GESHI_SEARCH => '(?<=[.])(a[1-6]|b[2-8]|c[4-6]|area|bid|bnf|clgp|cyc|diff|disc|[efjp]|fu|gen|index|mod|nf|no|omega|pol|reg|roots|sign|r[12]|t2|tate|tu|zk|zkst)\b',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ 2 => array(
+ '[a-zA-Z][a-zA-Z0-9_]*:' => ''
+ ),
+ 3 => array(
+ 'default(' => ''
+ ),
+ 4 => array(
+ 'iferrname(' => ''
+ ),
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/pascal.php b/platform/www/vendor/geshi/geshi/src/geshi/pascal.php
new file mode 100644
index 0000000..ee89223
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/pascal.php
@@ -0,0 +1,163 @@
+<?php
+/*************************************************************************************
+ * pascal.php
+ * ----------
+ * Author: Tux (tux@inamil.cz)
+ * Copyright: (c) 2004 Tux (http://tux.a4.cz/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/07/26
+ *
+ * Pascal language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.2)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.1)
+ * - Added support for URLs
+ * 2004/08/05 (1.0.0)
+ * - Added support for symbols
+ * 2004/07/27 (0.9.1)
+ * - Pascal is OO language. Some new words.
+ * 2004/07/26 (0.9.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Pascal',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('(*' => '*)', '{' => '}'),
+ //Compiler directives
+ 'COMMENT_REGEXP' => array(2 => '/\\{\\$.*?}|\\(\\*\\$.*?\\*\\)/U'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'"),
+ 'ESCAPE_CHAR' => '',
+
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'absolute','asm','assembler','begin','break','case','catch','cdecl',
+ 'const','constructor','default','destructor','div','do','downto',
+ 'else','end','except','export','exports','external','far',
+ 'finalization','finally','for','forward','function','goto','if',
+ 'implementation','in','index','inherited','initialization','inline',
+ 'interface','interrupt','label','library','mod','name','not','of',
+ 'or','overload','override','private','procedure','program',
+ 'property','protected','public','published','raise','repeat',
+ 'resourcestring','shl','shr','stdcall','stored','switch','then',
+ 'to','try','type','unit','until','uses','var','while','with','xor'
+ ),
+ 2 => array(
+ 'nil', 'false', 'true',
+ ),
+ 3 => array(
+ 'abs','and','arc','arctan','blockread','blockwrite','chr','dispose',
+ 'cos','eof','eoln','exp','get','ln','new','odd','ord','ordinal',
+ 'pred','read','readln','sin','sqrt','succ','write','writeln'
+ ),
+ 4 => array(
+ 'ansistring','array','boolean','byte','bytebool','char','file',
+ 'integer','longbool','longint','object','packed','pointer','real',
+ 'record','set','shortint','smallint','string','union','word'
+ ),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '[', ']'),
+ 1 => array('.', ',', ':', ';'),
+ 2 => array('@', '^'),
+ 3 => array('=', '+', '-', '*', '/')
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #000066; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #008000; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #ff0000; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ //'HARD' => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000cc;',
+ 1 => 'color: #ff0000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066;',
+ 1 => 'color: #000066;',
+ 2 => 'color: #000066;',
+ 3 => 'color: #000066;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ //Hex numbers
+ 0 => '\$[0-9a-fA-F]+',
+ //Characters
+ 1 => '\#(?:\$[0-9a-fA-F]{1,2}|\d{1,3})'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/pcre.php b/platform/www/vendor/geshi/geshi/src/geshi/pcre.php
new file mode 100644
index 0000000..fd48c39
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/pcre.php
@@ -0,0 +1,186 @@
+<?php
+/*************************************************************************************
+ * pcre.php
+ * --------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2010 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/05/22
+ *
+ * PCRE language file for GeSHi.
+ *
+ * NOTE: This language file handles plain PCRE expressions without delimiters.
+ * If you want to highlight PCRE with delimiters you should use the
+ * Perl language file instead.
+ *
+ * CHANGES
+ * -------
+ * 2010/05/22 (1.0.8.8)
+ * - First Release
+ *
+ * TODO (updated 2010/05/22)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'PCRE',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(
+ ),
+ 'COMMENT_REGEXP' => array(
+ // Non-matching groups
+ 1 => "/(?<=\()\?(?::|(?=\())/",
+
+ // Modifier groups
+ 2 => "/(?<=\()\?[cdegimopsuxUX\-]+(?::|(?=\)))/",
+
+ // Look-Aheads
+ 3 => "/(?<=\()\?[!=]/",
+
+ // Look-Behinds
+ 4 => "/(?<=\()\?<[!=]/",
+
+ // Forward Matching
+ 5 => "/(?<=\()\?>/",
+
+ // Recursive Matching
+ 6 => "/(?<=\()\?R(?=\))/",
+
+ // Named Subpattern
+ 7 => "/(?<=\()\?(?:P?<\w+>|\d+(?=\))|P[=>]\w+(?=\)))/",
+
+ // Back Reference
+ 8 => "/\\\\(?:[1-9]\d?|g\d+|g\{(?:-?\d+|\w+)\}|k<\w+>|k'\w+'|k\{\w+\})/",
+
+ // Byte sequence: Octal
+ 9 => "/\\\\[0-7]{2,3}/",
+
+ // Byte sequence: Hex
+ 10 => "/\\\\x[0-9a-fA-F]{2}/",
+
+ // Byte sequence: Hex
+ 11 => "/\\\\u[0-9a-fA-F]{4}/",
+
+ // Byte sequence: Hex
+ 12 => "/\\\\U[0-9a-fA-F]{8}/",
+
+ // Byte sequence: Unicode
+ 13 => "/\\\\[pP]\{[^}\n]+\}/",
+
+ // One-Char Escapes
+ 14 => "/\\\\[abdefnrstvwzABCDGSWXZ\\\\\\.\[\]\(\)\{\}\^\\\$\?\+\*]/",
+
+ // Byte sequence: Control-X sequence
+ 15 => "/\\\\c./",
+
+ // Quantifier
+ 16 => "/\{(?:\d+,?|\d*,\d+)\}/",
+
+ // Comment Subpattern
+ 17 => "/(?<=\()\?#[^\)]*/",
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('.'),
+ 1 => array('(', ')'),
+ 2 => array('[', ']', '|'),
+ 3 => array('^', '$'),
+ 4 => array('?', '+', '*'),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #993333; font-weight: bold;',
+ 2 => 'color: #cc3300; font-weight: bold;',
+ 3 => 'color: #cc0066; font-weight: bold;',
+ 4 => 'color: #cc0066; font-weight: bold;',
+ 5 => 'color: #cc6600; font-weight: bold;',
+ 6 => 'color: #cc00cc; font-weight: bold;',
+ 7 => 'color: #cc9900; font-weight: bold; font-style: italic;',
+ 8 => 'color: #cc9900; font-style: italic;',
+ 9 => 'color: #669933; font-style: italic;',
+ 10 => 'color: #339933; font-style: italic;',
+ 11 => 'color: #339966; font-style: italic;',
+ 12 => 'color: #339999; font-style: italic;',
+ 13 => 'color: #663399; font-style: italic;',
+ 14 => 'color: #999933; font-style: italic;',
+ 15 => 'color: #993399; font-style: italic;',
+ 16 => 'color: #333399; font-style: italic;',
+ 17 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #333399; font-weight: bold;',
+ 1 => 'color: #993333; font-weight: bold;',
+ 2 => 'color: #339933; font-weight: bold;',
+ 3 => 'color: #333399; font-weight: bold;',
+ 4 => 'color: #333399; font-style: italic;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/per.php b/platform/www/vendor/geshi/geshi/src/geshi/per.php
new file mode 100644
index 0000000..0962235
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/per.php
@@ -0,0 +1,300 @@
+<?php
+/*************************************************************************************
+ * per.php
+ * --------
+ * Author: Lars Gersmann (lars.gersmann@gmail.com)
+ * Copyright: (c) 2007 Lars Gersmann
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/06/03
+ *
+ * Per (forms) (FOURJ's Genero 4GL) language file for GeSHi.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'per',
+ 'COMMENT_SINGLE' => array(1 => '--', 2 => '#'),
+ 'COMMENT_MULTI' => array('{' => '}'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ "ACCELERATOR",
+ "ACCELERATOR2",
+ "ACTION",
+ "ALT",
+ "AND",
+ "AUTO",
+ "AUTONEXT",
+ "AUTOSCALE",
+ "BETWEEN",
+ "BOTH",
+ "BUTTON",
+ "BUTTONEDIT",
+ "BUTTONTEXTHIDDEN",
+ "BY",
+ "BYTE",
+ "CANVAS",
+ "CENTER",
+ "CHECKBOX",
+ "CLASS",
+ "COLOR",
+ "COLUMNS",
+ "COMBOBOX",
+ "COMMAND",
+ "COMMENT",
+ "COMMENTS",
+ "COMPACT",
+ "COMPRESS",
+ "CONFIG",
+ "CONTROL",
+ "CURRENT",
+ "DATABASE",
+ "DATEEDIT",
+ "DEC",
+ "DEFAULT",
+ "DEFAULTS",
+ "DELIMITERS",
+ "DISPLAY",
+ "DISPLAYONLY",
+ "DOWNSHIFT",
+ "DYNAMIC",
+ "EDIT",
+ "FIXED",
+ "FOLDER",
+ "FONTPITCH",
+ "FORMAT",
+ "FORMONLY",
+ "GRID",
+ "GRIDCHILDRENINPARENT",
+ "GROUP",
+ "HBOX",
+ "HEIGHT",
+ "HIDDEN",
+ "HORIZONTAL",
+ "INCLUDE",
+ "INITIAL",
+ "INITIALIZER",
+ "INPUT",
+ "INSTRUCTIONS",
+ "INTERVAL",
+ "INVISIBLE",
+ "IS",
+ "ITEM",
+ "ITEMS",
+ "JUSTIFY",
+ "KEY",
+ "KEYS",
+ "LABEL",
+ "LEFT",
+ "LIKE",
+ "LINES",
+ "MATCHES",
+ "NAME",
+ "NOENTRY",
+ "NONCOMPRESS",
+ "NORMAL",
+ "NOT",
+ "NOUPDATE",
+ "OPTIONS",
+ "OR",
+ "ORIENTATION",
+ "PACKED",
+ "PAGE",
+ "PICTURE",
+ "PIXELHEIGHT",
+ "PIXELS",
+ "PIXELWIDTH",
+ "POINTS",
+ "PROGRAM",
+ "PROGRESSBAR",
+ "QUERYCLEAR",
+ "QUERYEDITABLE",
+ "RADIOGROUP",
+ "RECORD",
+ "REQUIRED",
+ "REVERSE",
+ "RIGHT",
+ "SAMPLE",
+ "SCREEN",
+ "SCROLL",
+ "SCROLLBARS",
+ "SCROLLGRID",
+ "SECOND",
+ "SEPARATOR",
+ "SHIFT",
+ "SIZE",
+ "SIZEPOLICY",
+ "SMALLFLOAT",
+ "SMALLINT",
+ "SPACING",
+ "STRETCH",
+ "STYLE",
+ "TABINDEX",
+ "TABLE",
+ "TAG",
+ "TEXT",
+ "TEXTEDIT",
+ "THROUGH",
+ "THRU",
+ "TITLE",
+ "TO",
+ "TOOLBAR",
+ "TOPMENU",
+ "TYPE",
+ "UNHIDABLE",
+ "UNHIDABLECOLUMNS",
+ "UNMOVABLE",
+ "UNMOVABLECOLUMNS",
+ "UNSIZABLE",
+ "UNSIZABLECOLUMNS",
+ "UNSORTABLE",
+ "UNSORTABLECOLUMNS",
+ "UPSHIFT",
+ "USER",
+ "VALIDATE",
+ "VALUECHECKED",
+ "VALUEMAX",
+ "VALUEMIN",
+ "VALUEUNCHECKED",
+ "VARCHAR",
+ "VARIABLE",
+ "VBOX",
+ "VERIFY",
+ "VERSION",
+ "VERTICAL",
+ "TIMESTAMP",
+ "WANTCOLUMNSANCHORED", /* to be removed! */
+ "WANTFIXEDPAGESIZE",
+ "WANTNORETURNS",
+ "WANTTABS",
+ "WHERE",
+ "WIDGET",
+ "WIDTH",
+ "WINDOWSTYLE",
+ "WITHOUT",
+ "WORDWRAP",
+ "X",
+ "Y",
+ "ZEROFILL",
+ "SCHEMA",
+ "ATTRIBUTES",
+ "TABLES",
+ "LAYOUT",
+ "END"
+ ),
+ 2 => array(
+ "YEAR",
+ "BLACK",
+ "BLINK",
+ "BLUE",
+ "YELLOW",
+ "WHITE",
+ "UNDERLINE",
+ "CENTURY",
+ "FRACTION",
+ "CHAR",
+ "CHARACTER",
+ "CHARACTERS",
+ "CYAN",
+ "DATE",
+ "DATETIME",
+ "DAY",
+ "DECIMAL",
+ "FALSE",
+ "FLOAT",
+ "GREEN",
+ "HOUR",
+ "INT",
+ "INTEGER",
+ "MAGENTA",
+ "MINUTE",
+ "MONEY",
+ "NONE",
+ "NULL",
+ "REAL",
+ "RED",
+ "TRUE",
+ "TODAY",
+ "MONTH",
+ "IMAGE"
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '+', '-', '*', '?', '=', '/', '%', '>', '<', '^', '!', '|', ':',
+ '(', ')', '[', ']'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0600FF;',
+ 2 => 'color: #0000FF; font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008080; font-style: italic;',
+ 2 => 'color: #008080;',
+ 'MULTI' => 'color: green'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #008080; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #808080;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0000FF;',
+ 2 => 'color: #0000FF;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/perl.php b/platform/www/vendor/geshi/geshi/src/geshi/perl.php
new file mode 100644
index 0000000..e60c4c4
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/perl.php
@@ -0,0 +1,211 @@
+<?php
+/*************************************************************************************
+ * perl.php
+ * --------
+ * Author: Andreas Gohr (andi@splitbrain.org), Ben Keen (ben.keen@gmail.com)
+ * Copyright: (c) 2004 Andreas Gohr, Ben Keen (http://www.benjaminkeen.org/), Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/20
+ *
+ * Perl language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/06/22 (1.0.8)
+ * - Added support for system calls in backticks (Corley Kinnane)
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * - Added comment_regexp for predefined variables
+ * 2008/02/15 (1.003)
+ * - Fixed SF#1891630 with placebo patch
+ * 2006/01/05 (1.0.2)
+ * - Used hardescape feature for ' strings (Cliff Stanford)
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/08/20 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * LABEL:
+ * * string comparison operators
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Perl',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(
+ '=back' => '=cut',
+ '=head' => '=cut',
+ '=item' => '=cut',
+ '=over' => '=cut',
+ '=begin' => '=cut',
+ '=end' => '=cut',
+ '=for' => '=cut',
+ '=encoding' => '=cut',
+ '=pod' => '=cut'
+ ),
+ 'COMMENT_REGEXP' => array(
+ //Regular expressions
+ 2 => "/(?<=[\\s^])(s|tr|y)\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/(?:\\\\.|(?!\n)[^\\/\\\\])*\\/[msixpogcde]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])(m|q[qrwx]?)?\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[msixpogc]*(?=[\\s$\\.\\,\\;\\)])/iU",
+ //Regular expression match variables
+ 3 => '/\$\d+/',
+ //Heredoc
+ 4 => '/<<\s*?([\'"]?)([a-zA-Z0-9]+)\1;[^\n]*?\\n.*\\n\\2(?![a-zA-Z0-9])/siU',
+ //Predefined variables
+ 5 => '/\$(\^[a-zA-Z]?|[\*\$`\'&_\.,+\-~:;\\\\\/"\|%=\?!@#<>\(\)\[\]])(?!\w)|@[_+\-]|%[!]|\$(?=\{)/',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"','`'),
+ 'HARDQUOTE' => array("'", "'"), // An optional 2-element array defining the beginning and end of a hard-quoted string
+ 'HARDESCAPE' => array('\\\'',),
+ // Things that must still be escaped inside a hard-quoted string
+ // If HARDQUOTE is defined, HARDESCAPE must be defined
+ // This will not work unless the first character of each element is either in the
+ // QUOTEMARKS array or is the ESCAPE_CHAR
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'case', 'do', 'else', 'elsif', 'for', 'if', 'then', 'until', 'while', 'foreach', 'my',
+ 'xor', 'or', 'and', 'unless', 'next', 'last', 'redo', 'not', 'our',
+ 'reset', 'continue', 'cmp', 'ne', 'eq', 'lt', 'gt', 'le', 'ge',
+ ),
+ 2 => array(
+ 'use', 'sub', 'new', '__END__', '__DATA__', '__DIE__', '__WARN__', 'BEGIN',
+ 'STDIN', 'STDOUT', 'STDERR', 'ARGV', 'ARGVOUT'
+ ),
+ 3 => array(
+ 'abs', 'accept', 'alarm', 'atan2', 'bind', 'binmode', 'bless',
+ 'caller', 'chdir', 'chmod', 'chomp', 'chop', 'chown', 'chr',
+ 'chroot', 'close', 'closedir', 'connect', 'cos',
+ 'crypt', 'dbmclose', 'dbmopen', 'defined', 'delete', 'die',
+ 'dump', 'each', 'endgrent', 'endhostent', 'endnetent', 'endprotoent',
+ 'endpwent', 'endservent', 'eof', 'eval', 'exec', 'exists', 'exit',
+ 'exp', 'fcntl', 'fileno', 'flock', 'fork', 'format', 'formline',
+ 'getc', 'getgrent', 'getgrgid', 'getgrnam', 'gethostbyaddr',
+ 'gethostbyname', 'gethostent', 'getlogin', 'getnetbyaddr', 'getnetbyname',
+ 'getnetent', 'getpeername', 'getpgrp', 'getppid', 'getpriority',
+ 'getprotobyname', 'getprotobynumber', 'getprotoent', 'getpwent',
+ 'getpwnam', 'getpwuid', 'getservbyname', 'getservbyport', 'getservent',
+ 'getsockname', 'getsockopt', 'glob', 'gmtime', 'goto', 'grep',
+ 'hex', 'import', 'index', 'int', 'ioctl', 'join', 'keys', 'kill',
+ 'lc', 'lcfirst', 'length', 'link', 'listen', 'local',
+ 'localtime', 'log', 'lstat', 'm', 'map', 'mkdir', 'msgctl', 'msgget',
+ 'msgrcv', 'msgsnd', 'no', 'oct', 'open', 'opendir',
+ 'ord', 'pack', 'package', 'pipe', 'pop', 'pos', 'print',
+ 'printf', 'prototype', 'push', 'qq', 'qr', 'quotemeta', 'qw',
+ 'qx', 'q', 'rand', 'read', 'readdir', 'readline', 'readlink', 'readpipe',
+ 'recv', 'ref', 'rename', 'require', 'return',
+ 'reverse', 'rewinddir', 'rindex', 'rmdir', 's', 'scalar', 'seek',
+ 'seekdir', 'select', 'semctl', 'semget', 'semop', 'send', 'setgrent',
+ 'sethostent', 'setnetent', 'setpgrp', 'setpriority', 'setprotoent',
+ 'setpwent', 'setservent', 'setsockopt', 'shift', 'shmctl', 'shmget',
+ 'shmread', 'shmwrite', 'shutdown', 'sin', 'sleep', 'socket', 'socketpair',
+ 'sort', 'splice', 'split', 'sprintf', 'sqrt', 'srand', 'stat',
+ 'study', 'substr', 'symlink', 'syscall', 'sysopen', 'sysread',
+ 'sysseek', 'system', 'syswrite', 'tell', 'telldir', 'tie', 'tied',
+ 'time', 'times', 'tr', 'truncate', 'uc', 'ucfirst', 'umask', 'undef',
+ 'unlink', 'unpack', 'unshift', 'untie', 'utime', 'values',
+ 'vec', 'wait', 'waitpid', 'wantarray', 'warn', 'write', 'y'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '<', '>', '=',
+ '!', '@', '~', '&', '|', '^',
+ '+','-', '*', '/', '%',
+ ',', ';', '?', '.', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #009966; font-style: italic;',
+ 3 => 'color: #0000ff;',
+ 4 => 'color: #cc0000; font-style: italic;',
+ 5 => 'color: #0000ff;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ 'HARD' => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000ff;',
+ 4 => 'color: #009999;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://perldoc.perl.org/functions/{FNAMEL}.html'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '-&gt;',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ //Variable
+ 0 => '(?:\$[\$#]?|\\\\(?:[@%*]?|\\\\*\$|&amp;)|%[$]?|@[$]?|\*[$]?|&amp;[$]?)[a-zA-Z_][a-zA-Z0-9_]*',
+ //File Descriptor
+ 4 => '&lt;[a-zA-Z_][a-zA-Z0-9_]*&gt;',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'COMMENTS' => array(
+ 'DISALLOWED_BEFORE' => '$'
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/perl6.php b/platform/www/vendor/geshi/geshi/src/geshi/perl6.php
new file mode 100644
index 0000000..ce2fafb
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/perl6.php
@@ -0,0 +1,195 @@
+<?php
+/*************************************************************************************
+ * perl6.php
+ * ---------
+ * Author: Kodi Arfer (kodiarfer {at} warpmail {period} net); forked from perl.php 1.0.8 by Andreas Gohr (andi@splitbrain.org), Ben Keen (ben.keen@gmail.com)
+ * Copyright: (c) 2009 Kodi Arfer, (c) 2004 Andreas Gohr, Ben Keen (http://www.benjaminkeen.org/), Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/11/07
+ *
+ * Perl 6 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/12/25 (1.0.8.6)
+ * - First Release
+ *
+ * TODO (updated 2009/11/07)
+ * -------------------------
+ * * It's all pretty rough. Perl 6 is complicated; this'll never be more
+ * than reasonably accurate unless it's carefully written to match
+ * STD.pm.
+ * * It's largely incomplete. Lots of keywords are no doubt missing.
+ * * Recognize comments like #`( Hello! ).
+ * * Recognize qw-ing angle brackets.
+ * * ! should probably be in OBJECT_SPLITTERS too, but putting it there
+ * gives bizarre results. What to do?.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Perl 6',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array('=begin' => '=end'),
+ 'COMMENT_REGEXP' => array(
+ //Regular expressions
+ 2 => "/(?<=[\\s^])(s|tr|y)\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/(?:\\\\.|(?!\n)[^\\/\\\\])*\\/[msixpogcde]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])(m|q[qrwx]?)?\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[msixpogc]*(?=[\\s$\\.\\,\\;\\)])/iU",
+ //Regular expression match variables
+ 3 => '/\$\d+/',
+ //Heredoc
+ 4 => '/<<\s*?([\'"]?)([a-zA-Z0-9]+)\1;[^\n]*?\\n.*\\n\\2(?![a-zA-Z0-9])/siU',
+ //Beastly hack to finish highlighting each POD block
+ 5 => '((?<==end) .+)'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'HARDQUOTE' => array("'", "'"), // An optional 2-element array defining the beginning and end of a hard-quoted string
+ 'HARDESCAPE' => array('\\\''),
+ // Things that must still be escaped inside a hard-quoted string
+ // If HARDQUOTE is defined, HARDESCAPE must be defined
+ // This will not work unless the first character of each element is either in the
+ // QUOTEMARKS array or is the ESCAPE_CHAR
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'do', 'else', 'elsif', 'for', 'if', 'then', 'until',
+ 'while', 'loop', 'repeat', 'my', 'xor', 'or', 'and',
+ 'unless', 'next', 'last', 'redo', 'not', 'our', 'let',
+ 'temp', 'state', 'enum', 'constant', 'continue', 'cmp',
+ 'ne', 'eq', 'lt', 'gt', 'le', 'ge', 'leg', 'div', 'X',
+ 'Z', 'x', 'xx', 'given', 'when', 'default', 'has',
+ 'returns', 'of', 'is', 'does', 'where', 'subset', 'but',
+ 'True', 'False', 'return', 'die', 'fail'
+ ),
+ 2 => array(
+ 'use', 'sub', 'multi', 'method', 'submethod', 'proto',
+ 'class', 'role', 'grammar', 'regex', 'token', 'rule',
+ 'new', 'BEGIN', 'END', 'CHECK', 'INIT', 'START', 'FIRST',
+ 'ENTER', 'LEAVE', 'KEEP', 'UNDO', 'NEXT', 'LAST', 'PRE',
+ 'POST', 'CATCH', 'CONTROL', 'BUILD'
+ ),
+ 3 => array(
+ 'all', 'any', 'cat', 'classify', 'defined', 'grep', 'first',
+ 'keys', 'kv', 'join', 'map', 'max', 'min', 'none', 'one', 'pairs',
+ 'print', 'printf', 'roundrobin', 'pick', 'reduce', 'reverse', 'say',
+ 'shape', 'sort', 'srand', 'undefine', 'uri', 'values', 'warn', 'zip',
+
+ # Container
+ 'rotate', 'comb', 'end', 'elems', 'delete',
+ 'exists', 'pop', 'push', 'shift', 'splice',
+ 'unshift', 'invert', 'decode',
+
+ # Numeric
+ 'succ', 'pred', 'abs', 'exp', 'log',
+ 'log10', 'rand', 'roots', 'cis', 'unpolar', 'i', 'floor',
+ 'ceiling', 'round', 'truncate', 'sign', 'sqrt',
+ 'polar', 're', 'im', 'I', 'atan2', 'nude',
+ 'denominator', 'numerator',
+
+ # Str
+ 'p5chop', 'chop', 'p5chomp', 'chomp', 'lc', 'lcfirst',
+ 'uc', 'ucfirst', 'normalize', 'samecase', 'sameaccent',
+ 'capitalize', 'length', 'chars', 'graphs', 'codes',
+ 'bytes', 'encode', 'index', 'pack', 'quotemeta', 'rindex',
+ 'split', 'words', 'flip', 'sprintf', 'fmt',
+ 'substr', 'trim', 'unpack', 'match', 'subst', 'trans'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '<', '>', '=',
+ '!', '@', '~', '&', '|', '^',
+ '+','-', '*', '/', '%',
+ ',', ';', '?', '.', ':',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #009966; font-style: italic;',
+ 3 => 'color: #0000ff;',
+ 4 => 'color: #cc0000; font-style: italic;',
+ 5 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ 'HARD' => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000ff;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ //Variable
+ 0 => '(?:[$@%]|&amp;)(?:(?:[\^:*?!~]|&lt;)?[a-zA-Z_][a-zA-Z0-9_]*|(?=\.))'
+ # We treat the . twigil specially so the name can be highlighted as an
+ # object field (via OBJECT_SPLITTERS).
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'COMMENTS' => array(
+ 'DISALLOWED_BEFORE' => '$'
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/pf.php b/platform/www/vendor/geshi/geshi/src/geshi/pf.php
new file mode 100644
index 0000000..440ecb3
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/pf.php
@@ -0,0 +1,176 @@
+<?php
+/*************************************************************************************
+ * pf.php
+ * --------
+ * Author: David Berard (david@nfrance.com)
+ * Copyright: (c) 2010 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/10/16
+ * Based on bash.php
+ *
+ * OpenBSD PACKET FILTER language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/10/16 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ * * Support ALTQ
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'OpenBSD Packet Filter',
+ 'COMMENT_SINGLE' => array('#'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 1 => "/\\$\\{[^\\n\\}]*?\\}/i",
+ 2 => '/<<-?\s*?(\'?)([a-zA-Z0-9]+)\1\\n.*\\n\\2(?![a-zA-Z0-9])/siU',
+ 3 => "/\\\\['\"]/siU"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array("\'"),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ 1 => "#\\\\[nfrtv\\$\\\"\n]#i",
+ 2 => "#\\$[a-z_][a-z0-9_]*#i",
+ 3 => "/\\$\\{[^\\n\\}]*?\\}/i",
+ 4 => "/\\$\\([^\\n\\)]*?\\)/i",
+ 5 => "/`[^`]*`/"
+ ),
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'pass'
+ ),
+ 2 => array(
+ 'block'
+ ),
+ 3 => array(
+ 'quick','keep','state','antispoof','table','persist','file','scrub',
+ 'set','skip','flags','on'
+ ),
+ 4 => array(
+ 'in','out','proto'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '!', '@', '%', '&', '*', '|', '/', '<', '>', ';;', '`','='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #009900; font-weight: bold;',
+ 2 => 'color: #990000; font-weight: bold;',
+ 3 => 'color: #7a0874;',
+ 4 => 'color: #336699;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #666666; font-style: italic;',
+ 1 => 'color: #800000;',
+ 2 => 'color: #cc0000; font-style: italic;',
+ 3 => 'color: #000000; font-weight: bold;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #007800;',
+ 3 => 'color: #007800;',
+ 4 => 'color: #007800;',
+ 5 => 'color: #780078;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #7a0874; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #CC0000;',
+ 'HARD' => 'color: #CC0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff00cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #007800;',
+ 1 => 'color: #007800;',
+ 2 => 'color: #007800;',
+ 4 => 'color: #007800;',
+ 5 => 'color: #660033;',
+ 6 => 'color: #000099; font-weight: bold;',
+ 7 => 'color: #0000ff;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Variables (will be handled by comment_regexps)
+ 0 => "\\$\\{[a-zA-Z_][a-zA-Z0-9_]*?\\}",
+ //Variables without braces
+ 1 => "\\$[a-zA-Z_][a-zA-Z0-9_]*",
+ //Variable assignment
+ 2 => "(?<![\.a-zA-Z_\-])([a-zA-Z_][a-zA-Z0-9_]*?)(?==)",
+ //Shorthand shell variables
+ 4 => "\\$[*#\$\\-\\?!]",
+ //Parameters of commands
+ 5 => "(?<=\s)--?[0-9a-zA-Z\-]+(?=[\s=]|$)",
+ //IPs
+ 6 => "([0-9]{1,3}\.){3}[0-9]{1,3}",
+ //Tables
+ 7 => "(&lt;(.*)&gt;)"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'COMMENTS' => array(
+ 'DISALLOWED_BEFORE' => '$'
+ ),
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![\.\-a-zA-Z0-9_\$\#])",
+ 'DISALLOWED_AFTER' => "(?![\.\-a-zA-Z0-9_%\\/])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/phix.php b/platform/www/vendor/geshi/geshi/src/geshi/phix.php
new file mode 100644
index 0000000..66096a2
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/phix.php
@@ -0,0 +1,439 @@
+<?php
+/*************************************************************************************
+ * phix.php
+ * ---------------------------------
+ * Author: Pete Lomax
+ * Copyright: (c) 2010 Nicholas Koceja
+ * Release Version: 1.0.9.1
+ * Date Started: 16/08/2015
+ *
+ * Phix language file for GeSHi.
+ *
+ * Author's note: The colors are based on those of Edita.
+ *
+ * CHANGES
+ * -------
+ * <date-of-release> (1.0.8.9)
+ * - First Release
+ *
+ * TODO (updated <date-of-release>)
+ * -------------------------
+ * seperate the funtions from the procedures, and have a slight color change for each.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Phix',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(2 => '/\/\*(?:(?R)|.)+?\*\//s'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"', '"""', '`'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array( // keywords
+ 'and', 'as',
+ 'break', 'by',
+ 'case', 'constant',
+ 'default', 'do',
+ 'else', 'elsif', 'end', 'enum', 'exit',
+ 'for', 'forward', 'function',
+ 'global',
+ 'if', 'include',
+ 'not',
+ 'or',
+ 'procedure',
+ 'return',
+ 'switch',
+ 'then', 'to', 'type',
+ 'while', 'with', 'without',
+ 'xor'
+ ),
+ 2 => array( // directives
+ 'console',
+ 'debug',
+ 'fallthru',
+ 'fallthrough', 'format',
+ 'gui',
+ 'ilASM',
+ 'jump_table',
+ 'profile', 'profile_time',
+ 'trace', 'type_check',
+ 'warning'
+ ),
+ 3 => array( // built-ins
+ 'abort',
+ 'abs',
+ 'adjust_timedate',
+ 'allocate',
+ 'allocate_string',
+ 'allocate_struct',
+ 'allow_break',
+ 'and_bits',
+ 'append',
+ 'arccos',
+ 'arcsin',
+ 'arctan',
+ 'atom',
+ 'atom_to_float32',
+ 'atom_to_float64',
+ 'atom_to_float80',
+
+ 'bits_to_int',
+ 'bk_color',
+ 'bytes_to_int',
+
+ 'call',
+ 'call_back',
+ 'call_func',
+ 'call_proc',
+ 'canonical_path',
+ 'ceil',
+ 'change_timezone',
+ 'chdir',
+ 'check_break',
+ 'clear_screen',
+ 'close',
+ 'columnize',
+ 'compare',
+ 'command_line',
+ 'cos',
+ 'crash_file',
+ 'crash_message',
+ 'crash_routine',
+ 'create_thread',
+ 'current_dir',
+ 'cursor',
+ 'custom_sort',
+ 'c_func',
+ 'c_proc',
+
+ 'date',
+ 'day_of_week',
+ 'day_of_year',
+ 'db_close',
+ 'db_compress',
+ 'db_create',
+ 'db_create_table',
+ 'db_delete_record',
+ 'db_delete_table',
+ 'db_dump',
+ 'db_fatal_id',
+ 'db_find_key',
+ 'db_insert',
+ 'db_open',
+ 'db_record_data',
+ 'db_record_key',
+ 'db_replace_data',
+ 'db_select',
+ 'db_select_table',
+ 'db_table_list',
+ 'db_table_size',
+ 'define_c_func',
+ 'define_c_proc',
+ 'define_c_var',
+ 'define_cfunc',
+ 'define_cproc',
+ 'define_struct',
+ 'delete',
+ 'delete_cs',
+ 'delete_routine',
+ 'dir',
+ 'display_text_image',
+
+ 'enter_cs',
+ 'equal',
+ 'exit_thread',
+
+ 'factorial',
+ 'factors',
+ 'find',
+ 'flatten',
+ 'float32_to_atom',
+ 'float64_to_atom',
+ 'float80_to_atom',
+ 'floor',
+ 'flush',
+ 'format_timedate',
+ 'free',
+ 'free_console',
+
+ 'gcd',
+ 'get',
+ 'getc',
+ 'getenv',
+ 'gets',
+ 'get_bytes',
+ 'get_field_details',
+ 'get_key',
+ 'get_position',
+ 'get_proper_path',
+ 'get_screen_char',
+ 'get_struct_field',
+ 'get_struct_size',
+ 'get_text',
+ 'get_thread_exitcode',
+
+ 'iif',
+ 'iff',
+ 'include_paths',
+ 'init_cs',
+ 'instance',
+ 'integer',
+ 'int_to_bits',
+ 'int_to_bytes',
+ 'is_leap_year',
+
+ 'join',
+
+ 'leave_cs',
+ 'length',
+ 'lock_file',
+ 'log',
+ 'lower',
+
+ 'machine_bits',
+ 'machine_func',
+ 'machine_proc',
+ 'match',
+ 'max',
+ 'mem_copy',
+ 'mem_set',
+ 'message_box',
+ 'min',
+ 'mod',
+
+ 'not_bits',
+
+ 'object',
+ 'open',
+ 'open_dll',
+ 'or_bits',
+
+ 'parse_date_string',
+ 'peek',
+ 'peek1s',
+ 'peek1u',
+ 'peek2s',
+ 'peek2u',
+ 'peek4s',
+ 'peek4u',
+ 'peek8s',
+ 'peek8u',
+ 'peekNS',
+ 'peek_string',
+ 'permute',
+ 'platform',
+ 'poke',
+ 'poke1',
+ 'poke2',
+ 'poke4',
+ 'poke8',
+ 'pokeN',
+ 'position',
+ 'power',
+ 'prepend',
+ 'prime_factors',
+ 'print',
+ 'printf',
+ 'prompt_number',
+ 'prompt_string',
+ 'puts',
+ 'put_screen_char',
+
+ 'rand',
+ 'read_bitmap',
+ 'remainder',
+ 'repeat',
+ 'resume_thread',
+ 'reverse',
+ 'rfind',
+ 'round',
+ 'routine_id',
+
+ 'save_bitmap',
+ 'save_text_image',
+ 'scanf',
+ 'scroll',
+ 'seek',
+ 'sequence',
+ 'set_rand',
+ 'set_struct_field',
+ 'set_system_doevents',
+ 'set_timedate_formats',
+ 'set_timezone',
+ 'set_unicode',
+ 'sign',
+ 'sin',
+ 'sleep',
+ 'sort',
+ 'sprint',
+ 'sprintf',
+ 'sqrt',
+ 'sq_abs',
+ 'sq_add',
+ 'sq_and',
+ 'sq_and_bits',
+ 'sq_arccos',
+ 'sq_arcsin',
+ 'sq_arctan',
+ 'sq_atom',
+ 'sq_ceil',
+ 'sq_cos',
+ 'sq_div',
+ 'sq_eq',
+ 'sq_floor',
+ 'sq_floor_div',
+ 'sq_ge',
+ 'sq_gt',
+ 'sq_int',
+ 'sq_le',
+ 'sq_log',
+ 'sq_lower',
+ 'sq_lt',
+ 'sq_mod',
+ 'sq_mul',
+ 'sq_ne',
+ 'sq_not',
+ 'sq_not_bits',
+ 'sq_or',
+ 'sq_or_bits',
+ 'sq_power',
+ 'sq_rand',
+ 'sq_round',
+ 'sq_rmdr',
+ 'sq_seq',
+ 'sq_sign',
+ 'sq_sin',
+ 'sq_sqrt',
+ 'sq_str',
+ 'sq_sub',
+ 'sq_tan',
+ 'sq_trunc',
+ 'sq_uminus',
+ 'sq_upper',
+ 'sq_xor',
+ 'sq_xor_bits',
+ 'string',
+ 'substitute',
+ 'sum',
+ 'suspend_thread',
+ 'system',
+ 'system_exec',
+ 'system_open',
+ 'system_wait',
+
+ 'tagset',
+ 'tan',
+ 'task_clock_stop',
+ 'task_clock_start',
+ 'task_create',
+ 'task_list',
+ 'task_schedule',
+ 'task_self',
+ 'task_status',
+ 'task_suspend',
+ 'task_yield',
+ 'text_color',
+ 'text_rows',
+ 'time',
+ 'timedate',
+ 'timedelta',
+ 'trunc',
+ 'try_cs',
+
+ 'unlock_file',
+ 'upper',
+
+ 'value',
+ 'video_config',
+
+ 'wait_key',
+ 'wait_thread',
+ 'walk_dir',
+ 'where',
+ 'wildcard_file',
+ 'wildcard_match',
+ 'wrap',
+
+ 'xor_bits'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '(', ')', '{', '}', '[', ']'
+ ),
+ 1 => array(
+ '+', '-', '*', '/', '=', '&', '^', '?', ',', ':'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #008080;', // keywords
+ 2 => 'color: #008080;', // directives
+ 3 => 'color: #004080;' // builtins
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #000080; font-style: italic;',
+ 2 => 'color: #000080; font-style: italic;',
+ 'MULTI' => 'color: #000080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #009900; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #0000FF;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'METHODS' => array( // Do not exist in Phix)
+ 0 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #0000FF;', // brackets
+ 1 => 'color: #0000FF;' // operators
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array( // Never included in scripts.
+ )
+ ),
+ 'REGEXPS' => array(),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/php-brief.php b/platform/www/vendor/geshi/geshi/src/geshi/php-brief.php
new file mode 100644
index 0000000..f7fb415
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/php-brief.php
@@ -0,0 +1,220 @@
+<?php
+/*************************************************************************************
+ * php-brief.php
+ * -------------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/02
+ *
+ * PHP (brief version) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.3)
+ * - Added support for multiple object splitters
+ * - Fixed &new problem
+ * 2004/10/27 (1.0.2)
+ * - Added support for URLs
+ * 2004/08/05 (1.0.1)
+ * - Added support for symbols
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * * Remove more functions that are hardly used
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'PHP (brief)',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ //Heredoc and Nowdoc syntax
+ 'COMMENT_REGEXP' => array(3 => '/<<<\s*?(\'?)([a-zA-Z0-9]+)\1[^\n]*?\\n.*\\n\\2(?![a-zA-Z0-9])/siU'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array("\'"),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'include', 'require', 'include_once', 'require_once',
+ 'for', 'as', 'foreach', 'if', 'elseif', 'else', 'while', 'do', 'endwhile', 'endif', 'switch', 'case', 'endswitch',
+ 'return', 'break'
+ ),
+ 2 => array(
+ 'null', '__LINE__', '__FILE__',
+ 'false', '&lt;?php',
+ 'true', 'var', 'default',
+ 'function', 'class', 'new', '&amp;new', 'public', 'private', 'interface', 'extends',
+ 'const', 'self'
+ ),
+ 3 => array(
+ 'func_num_args', 'func_get_arg', 'func_get_args', 'strlen', 'strcmp', 'strncmp', 'strcasecmp', 'strncasecmp', 'each', 'error_reporting', 'define', 'defined',
+ 'trigger_error', 'user_error', 'set_error_handler', 'restore_error_handler', 'get_declared_classes', 'get_loaded_extensions',
+ 'extension_loaded', 'get_extension_funcs', 'debug_backtrace',
+ 'constant', 'bin2hex', 'sleep', 'usleep', 'time', 'mktime', 'gmmktime', 'strftime', 'gmstrftime', 'strtotime', 'date', 'gmdate', 'getdate', 'localtime', 'checkdate', 'flush', 'wordwrap', 'htmlspecialchars', 'htmlentities', 'html_entity_decode', 'md5', 'md5_file', 'crc32', 'getimagesize', 'image_type_to_mime_type', 'phpinfo', 'phpversion', 'phpcredits', 'strnatcmp', 'strnatcasecmp', 'substr_count', 'strspn', 'strcspn', 'strtok', 'strtoupper', 'strtolower', 'strpos', 'strrpos', 'strrev', 'hebrev', 'hebrevc', 'nl2br', 'basename', 'dirname', 'pathinfo', 'stripslashes', 'stripcslashes', 'strstr', 'stristr', 'strrchr', 'str_shuffle', 'str_word_count', 'strcoll', 'substr', 'substr_replace', 'quotemeta', 'ucfirst', 'ucwords', 'strtr', 'addslashes', 'addcslashes', 'rtrim', 'str_replace', 'str_repeat', 'count_chars', 'chunk_split', 'trim', 'ltrim', 'strip_tags', 'similar_text', 'explode', 'implode', 'setlocale', 'localeconv',
+ 'parse_str', 'str_pad', 'chop', 'strchr', 'sprintf', 'printf', 'vprintf', 'vsprintf', 'sscanf', 'fscanf', 'parse_url', 'urlencode', 'urldecode', 'rawurlencode', 'rawurldecode', 'readlink', 'linkinfo', 'link', 'unlink', 'exec', 'system', 'escapeshellcmd', 'escapeshellarg', 'passthru', 'shell_exec', 'proc_open', 'proc_close', 'rand', 'srand', 'getrandmax', 'mt_rand', 'mt_srand', 'mt_getrandmax', 'base64_decode', 'base64_encode', 'abs', 'ceil', 'floor', 'round', 'is_finite', 'is_nan', 'is_infinite', 'bindec', 'hexdec', 'octdec', 'decbin', 'decoct', 'dechex', 'base_convert', 'number_format', 'fmod', 'ip2long', 'long2ip', 'getenv', 'putenv', 'getopt', 'microtime', 'gettimeofday', 'getrusage', 'uniqid', 'quoted_printable_decode', 'set_time_limit', 'get_cfg_var', 'magic_quotes_runtime', 'set_magic_quotes_runtime', 'get_magic_quotes_gpc', 'get_magic_quotes_runtime',
+ 'import_request_variables', 'error_log', 'serialize', 'unserialize', 'memory_get_usage', 'var_dump', 'var_export', 'debug_zval_dump', 'print_r','highlight_file', 'show_source', 'highlight_string', 'ini_get', 'ini_get_all', 'ini_set', 'ini_alter', 'ini_restore', 'get_include_path', 'set_include_path', 'restore_include_path', 'setcookie', 'header', 'headers_sent', 'connection_aborted', 'connection_status', 'ignore_user_abort', 'parse_ini_file', 'is_uploaded_file', 'move_uploaded_file', 'intval', 'floatval', 'doubleval', 'strval', 'gettype', 'settype', 'is_null', 'is_resource', 'is_bool', 'is_long', 'is_float', 'is_int', 'is_integer', 'is_double', 'is_real', 'is_numeric', 'is_string', 'is_array', 'is_object', 'is_scalar',
+ 'ereg', 'ereg_replace', 'eregi', 'eregi_replace', 'split', 'spliti', 'join', 'sql_regcase', 'dl', 'pclose', 'popen', 'readfile', 'rewind', 'rmdir', 'umask', 'fclose', 'feof', 'fgetc', 'fgets', 'fgetss', 'fread', 'fopen', 'fpassthru', 'ftruncate', 'fstat', 'fseek', 'ftell', 'fflush', 'fwrite', 'fputs', 'mkdir', 'rename', 'copy', 'tempnam', 'tmpfile', 'file', 'file_get_contents', 'stream_select', 'stream_context_create', 'stream_context_set_params', 'stream_context_set_option', 'stream_context_get_options', 'stream_filter_prepend', 'stream_filter_append', 'fgetcsv', 'flock', 'get_meta_tags', 'stream_set_write_buffer', 'set_file_buffer', 'set_socket_blocking', 'stream_set_blocking', 'socket_set_blocking', 'stream_get_meta_data', 'stream_register_wrapper', 'stream_wrapper_register', 'stream_set_timeout', 'socket_set_timeout', 'socket_get_status', 'realpath', 'fnmatch', 'fsockopen', 'pfsockopen', 'pack', 'unpack', 'get_browser', 'crypt', 'opendir', 'closedir', 'chdir', 'getcwd', 'rewinddir', 'readdir', 'dir', 'glob', 'fileatime', 'filectime', 'filegroup', 'fileinode', 'filemtime', 'fileowner', 'fileperms', 'filesize', 'filetype', 'file_exists', 'is_writable', 'is_writeable', 'is_readable', 'is_executable', 'is_file', 'is_dir', 'is_link', 'stat', 'lstat', 'chown',
+ 'touch', 'clearstatcache', 'mail', 'ob_start', 'ob_flush', 'ob_clean', 'ob_end_flush', 'ob_end_clean', 'ob_get_flush', 'ob_get_clean', 'ob_get_length', 'ob_get_level', 'ob_get_status', 'ob_get_contents', 'ob_implicit_flush', 'ob_list_handlers', 'ksort', 'krsort', 'natsort', 'natcasesort', 'asort', 'arsort', 'sort', 'rsort', 'usort', 'uasort', 'uksort', 'shuffle', 'array_walk', 'count', 'end', 'prev', 'next', 'reset', 'current', 'key', 'min', 'max', 'in_array', 'array_search', 'extract', 'compact', 'array_fill', 'range', 'array_multisort', 'array_push', 'array_pop', 'array_shift', 'array_unshift', 'array_splice', 'array_slice', 'array_merge', 'array_merge_recursive', 'array_keys', 'array_values', 'array_count_values', 'array_reverse', 'array_reduce', 'array_pad', 'array_flip', 'array_change_key_case', 'array_rand', 'array_unique', 'array_intersect', 'array_intersect_assoc', 'array_diff', 'array_diff_assoc', 'array_sum', 'array_filter', 'array_map', 'array_chunk', 'array_key_exists', 'pos', 'sizeof', 'key_exists', 'assert', 'assert_options', 'version_compare', 'ftok', 'str_rot13', 'aggregate',
+ 'session_name', 'session_module_name', 'session_save_path', 'session_id', 'session_regenerate_id', 'session_decode', 'session_register', 'session_unregister', 'session_is_registered', 'session_encode',
+ 'session_start', 'session_destroy', 'session_unset', 'session_set_save_handler', 'session_cache_limiter', 'session_cache_expire', 'session_set_cookie_params', 'session_get_cookie_params', 'session_write_close', 'preg_match', 'preg_match_all', 'preg_replace', 'preg_replace_callback', 'preg_split', 'preg_quote', 'preg_grep', 'overload', 'ctype_alnum', 'ctype_alpha', 'ctype_cntrl', 'ctype_digit', 'ctype_lower', 'ctype_graph', 'ctype_print', 'ctype_punct', 'ctype_space', 'ctype_upper', 'ctype_xdigit', 'virtual', 'apache_request_headers', 'apache_note', 'apache_lookup_uri', 'apache_child_terminate', 'apache_setenv', 'apache_response_headers', 'apache_get_version', 'getallheaders', 'mysql_connect', 'mysql_pconnect', 'mysql_close', 'mysql_select_db', 'mysql_create_db', 'mysql_drop_db', 'mysql_query', 'mysql_unbuffered_query', 'mysql_db_query', 'mysql_list_dbs', 'mysql_list_tables', 'mysql_list_fields', 'mysql_list_processes', 'mysql_error', 'mysql_errno', 'mysql_affected_rows', 'mysql_insert_id', 'mysql_result', 'mysql_num_rows', 'mysql_num_fields', 'mysql_fetch_row', 'mysql_fetch_array', 'mysql_fetch_assoc', 'mysql_fetch_object', 'mysql_data_seek', 'mysql_fetch_lengths', 'mysql_fetch_field', 'mysql_field_seek', 'mysql_free_result', 'mysql_field_name', 'mysql_field_table', 'mysql_field_len', 'mysql_field_type', 'mysql_field_flags', 'mysql_escape_string', 'mysql_real_escape_string', 'mysql_stat',
+ 'mysql_thread_id', 'mysql_client_encoding', 'mysql_get_client_info', 'mysql_get_host_info', 'mysql_get_proto_info', 'mysql_get_server_info', 'mysql_info', 'mysql', 'mysql_fieldname', 'mysql_fieldtable', 'mysql_fieldlen', 'mysql_fieldtype', 'mysql_fieldflags', 'mysql_selectdb', 'mysql_createdb', 'mysql_dropdb', 'mysql_freeresult', 'mysql_numfields', 'mysql_numrows', 'mysql_listdbs', 'mysql_listtables', 'mysql_listfields', 'mysql_db_name', 'mysql_dbname', 'mysql_tablename', 'mysql_table_name', 'pg_connect', 'pg_pconnect', 'pg_close', 'pg_connection_status', 'pg_connection_busy', 'pg_connection_reset', 'pg_host', 'pg_dbname', 'pg_port', 'pg_tty', 'pg_options', 'pg_ping', 'pg_query', 'pg_send_query', 'pg_cancel_query', 'pg_fetch_result', 'pg_fetch_row', 'pg_fetch_assoc', 'pg_fetch_array', 'pg_fetch_object', 'pg_fetch_all', 'pg_affected_rows', 'pg_get_result', 'pg_result_seek', 'pg_result_status', 'pg_free_result', 'pg_last_oid', 'pg_num_rows', 'pg_num_fields', 'pg_field_name', 'pg_field_num', 'pg_field_size', 'pg_field_type', 'pg_field_prtlen', 'pg_field_is_null', 'pg_get_notify', 'pg_get_pid', 'pg_result_error', 'pg_last_error', 'pg_last_notice', 'pg_put_line', 'pg_end_copy', 'pg_copy_to', 'pg_copy_from',
+ 'pg_trace', 'pg_untrace', 'pg_lo_create', 'pg_lo_unlink', 'pg_lo_open', 'pg_lo_close', 'pg_lo_read', 'pg_lo_write', 'pg_lo_read_all', 'pg_lo_import', 'pg_lo_export', 'pg_lo_seek', 'pg_lo_tell', 'pg_escape_string', 'pg_escape_bytea', 'pg_unescape_bytea', 'pg_client_encoding', 'pg_set_client_encoding', 'pg_meta_data', 'pg_convert', 'pg_insert', 'pg_update', 'pg_delete', 'pg_select', 'pg_exec', 'pg_getlastoid', 'pg_cmdtuples', 'pg_errormessage', 'pg_numrows', 'pg_numfields', 'pg_fieldname', 'pg_fieldsize', 'pg_fieldtype', 'pg_fieldnum', 'pg_fieldprtlen', 'pg_fieldisnull', 'pg_freeresult', 'pg_result', 'pg_loreadall', 'pg_locreate', 'pg_lounlink', 'pg_loopen', 'pg_loclose', 'pg_loread', 'pg_lowrite', 'pg_loimport', 'pg_loexport',
+ 'echo', 'print', 'global', 'static', 'exit', 'array', 'empty', 'eval', 'isset', 'unset', 'die'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '<%', '<%=', '%>', '<?', '<?=', '?>'
+ ),
+ 0 => array(
+ '(', ')', '[', ']', '{', '}',
+ '!', '@', '%', '&', '|', '/',
+ '<', '>',
+ '=', '-', '+', '*',
+ '.', ':', ',', ';'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #990000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #666666; font-style: italic;',
+ 3 => 'color: #0000cc; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;',
+ 'HARD' => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #004000;',
+ 2 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;',
+ 1 => 'color: #000000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.php.net/{FNAMEL}'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '-&gt;',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ //Variables
+ 0 => "[\\$]+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<?php' => '?>'
+ ),
+ 1 => array(
+ '<?' => '?>'
+ ),
+ 2 => array(
+ '<%' => '%>'
+ ),
+ 3 => array(
+ '<script language="php">' => '</script>'
+ ),
+ 4 => "/(?P<start><\\?(?>php\b)?)(?:".
+ "(?>[^\"'?\\/<]+)|".
+ "\\?(?!>)|".
+ "(?>'(?>[^'\\\\]|\\\\'|\\\\\\\|\\\\)*')|".
+ "(?>\"(?>[^\"\\\\]|\\\\\"|\\\\\\\\|\\\\)*\")|".
+ "(?>\\/\\*(?>[^\\*]|(?!\\*\\/)\\*)*\\*\\/)|".
+ "\\/\\/(?>.*?$)|".
+ "\\/(?=[^*\\/])|".
+ "<(?!<<)|".
+ "<<<(?P<phpdoc>\w+)\s.*?\s\k<phpdoc>".
+ ")*(?P<end>\\?>|\Z)/sm",
+ 5 => "/(?P<start><%)(?:".
+ "(?>[^\"'%\\/<]+)|".
+ "%(?!>)|".
+ "(?>'(?>[^'\\\\]|\\\\'|\\\\\\\|\\\\)*')|".
+ "(?>\"(?>[^\\\"\\\\]|\\\\\"|\\\\\\\\|\\\\)*\")|".
+ "(?>\\/\\*(?>[^\\*]|(?!\\*\\/)\\*)*\\*\\/)|".
+ "\\/\\/(?>.*?$)|".
+ "\\/(?=[^*\\/])|".
+ "<(?!<<)|".
+ "<<<(?P<phpdoc>\w+)\s.*?\s\k<phpdoc>".
+ ")*(?P<end>%>)/sm"
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/php.php b/platform/www/vendor/geshi/geshi/src/geshi/php.php
new file mode 100644
index 0000000..dc9561a
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/php.php
@@ -0,0 +1,1115 @@
+<?php
+/*************************************************************************************
+ * php.php
+ * --------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/20
+ *
+ * PHP language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/11/25 (1.0.3)
+ * - Added support for multiple object splitters
+ * - Fixed &new problem
+ * 2004/10/27 (1.0.2)
+ * - Added URL support
+ * - Added extra constants
+ * 2004/08/05 (1.0.1)
+ * - Added support for symbols
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * * Make sure the last few function I may have missed
+ * (like eval()) are included for highlighting
+ * * Split to several files - php4, php5 etc
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'PHP',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Heredoc and Nowdoc syntax
+ 3 => '/<<<\s*?(\'?)([a-zA-Z0-9]+?)\1[^\n]*?\\n.*\\n\\2(?![a-zA-Z0-9])/siU',
+ // phpdoc comments
+ 4 => '#/\*\*(?![\*\/]).*\*/#sU',
+ // Advanced # handling
+ 2 => "/#.*?(?:(?=\?\>)|^)/smi"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[nfrtv\$\"\n\\\\]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{1,2}#i",
+ //Octal Char Specs
+ 3 => "#\\\\[0-7]{1,3}#",
+ //String Parsing of Variable Names
+ 4 => "#\\$[a-z0-9_]+(?:\\[[a-z0-9_]+\\]|->[a-z0-9_]+)?|(?:\\{\\$|\\$\\{)[a-z0-9_]+(?:\\[('?)[a-z0-9_]*\\1\\]|->[a-z0-9_]+)*\\}#i",
+ //Experimental extension supporting cascaded {${$var}} syntax
+ 5 => "#\$[a-z0-9_]+(?:\[[a-z0-9_]+\]|->[a-z0-9_]+)?|(?:\{\$|\$\{)[a-z0-9_]+(?:\[('?)[a-z0-9_]*\\1\]|->[a-z0-9_]+)*\}|\{\$(?R)\}#i",
+ //Format String support in ""-Strings
+ 6 => "#%(?:%|(?:\d+\\\\\\\$)?\\+?(?:\x20|0|'.)?-?(?:\d+|\\*)?(?:\.\d+)?[bcdefFosuxX])#"
+ ),
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array("'", "\\"),
+ 'HARDCHAR' => "\\",
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'as','break','case','continue','default','do','else','elseif',
+ 'endfor','endforeach','endif','endswitch','endwhile','for',
+ 'foreach','if','include','include_once','require','require_once',
+ 'return','switch','throw','while', 'yield',
+
+ 'echo','print'
+ ),
+ 2 => array(
+ '&amp;new','&lt;/script&gt;','&lt;?php','&lt;script language',
+ 'abstract','class','const','declare','extends','function','global',
+ 'implements', 'interface','namespace','new','private','protected',
+ 'public','self','trait','use','var'
+ ),
+ 3 => array(
+ 'abs','acos','acosh','addcslashes','addslashes','aggregate',
+ 'aggregate_methods','aggregate_methods_by_list',
+ 'aggregate_methods_by_regexp','aggregate_properties',
+ 'aggregate_properties_by_list','aggregate_properties_by_regexp',
+ 'aggregation_info','apache_child_terminate','apache_get_modules',
+ 'apache_get_version','apache_getenv','apache_lookup_uri',
+ 'apache_note','apache_request_headers','apache_response_headers',
+ 'apache_setenv','array','array_change_key_case','array_chunk',
+ 'array_combine','array_count_values','array_diff',
+ 'array_diff_assoc','array_diff_key','array_diff_uassoc',
+ 'array_diff_ukey','array_fill','array_fill_keys','array_filter',
+ 'array_flip','array_intersect','array_intersect_assoc',
+ 'array_intersect_key','array_intersect_uassoc',
+ 'array_intersect_ukey','array_key_exists','array_keys','array_map',
+ 'array_merge','array_merge_recursive','array_multisort','array_pad',
+ 'array_pop','array_product','array_push','array_rand',
+ 'array_reduce','array_reverse','array_search','array_shift',
+ 'array_slice','array_splice','array_sum','array_udiff',
+ 'array_udiff_assoc','array_udiff_uassoc','array_uintersect',
+ 'array_uintersect_assoc','array_uintersect_uassoc','array_unique',
+ 'array_unshift','array_values','array_walk','array_walk_recursive',
+ 'arsort','asin','asinh','asort','assert','assert_options','atan',
+ 'atan2','atanh','base_convert','base64_decode','base64_encode',
+ 'basename','bcadd','bccomp','bcdiv','bcmod','bcmul',
+ 'bcompiler_load','bcompiler_load_exe','bcompiler_parse_class',
+ 'bcompiler_read','bcompiler_write_class','bcompiler_write_constant',
+ 'bcompiler_write_exe_footer','bcompiler_write_file',
+ 'bcompiler_write_footer','bcompiler_write_function',
+ 'bcompiler_write_functions_from_file','bcompiler_write_header',
+ 'bcompiler_write_included_filename','bcpow','bcpowmod','bcscale',
+ 'bcsqrt','bcsub','bin2hex','bindec','bindtextdomain',
+ 'bind_textdomain_codeset','bitset_empty','bitset_equal',
+ 'bitset_excl','bitset_fill','bitset_from_array','bitset_from_hash',
+ 'bitset_from_string','bitset_in','bitset_incl',
+ 'bitset_intersection','bitset_invert','bitset_is_empty',
+ 'bitset_subset','bitset_to_array','bitset_to_hash',
+ 'bitset_to_string','bitset_union','blenc_encrypt','bzclose',
+ 'bzcompress','bzdecompress','bzerrno','bzerror','bzerrstr',
+ 'bzflush','bzopen','bzread','bzwrite','cal_days_in_month',
+ 'cal_from_jd','cal_info','cal_to_jd','call_user_func',
+ 'call_user_func_array','call_user_method','call_user_method_array',
+ 'ceil','chdir','checkdate','checkdnsrr','chgrp','chmod','chop',
+ 'chown','chr','chunk_split','class_exists','class_implements',
+ 'class_parents','classkit_aggregate_methods',
+ 'classkit_doc_comments','classkit_import','classkit_method_add',
+ 'classkit_method_copy','classkit_method_redefine',
+ 'classkit_method_remove','classkit_method_rename','clearstatcache',
+ 'closedir','closelog','com_create_guid','com_event_sink',
+ 'com_get_active_object','com_load_typelib','com_message_pump',
+ 'com_print_typeinfo','compact','confirm_phpdoc_compiled',
+ 'connection_aborted','connection_status','constant',
+ 'convert_cyr_string','convert_uudecode','convert_uuencode','copy',
+ 'cos','cosh','count','count_chars','cpdf_add_annotation',
+ 'cpdf_add_outline','cpdf_arc','cpdf_begin_text','cpdf_circle',
+ 'cpdf_clip','cpdf_close','cpdf_closepath',
+ 'cpdf_closepath_fill_stroke','cpdf_closepath_stroke',
+ 'cpdf_continue_text','cpdf_curveto','cpdf_end_text','cpdf_fill',
+ 'cpdf_fill_stroke','cpdf_finalize','cpdf_finalize_page',
+ 'cpdf_global_set_document_limits','cpdf_import_jpeg','cpdf_lineto',
+ 'cpdf_moveto','cpdf_newpath','cpdf_open','cpdf_output_buffer',
+ 'cpdf_page_init','cpdf_rect','cpdf_restore','cpdf_rlineto',
+ 'cpdf_rmoveto','cpdf_rotate','cpdf_rotate_text','cpdf_save',
+ 'cpdf_save_to_file','cpdf_scale','cpdf_set_action_url',
+ 'cpdf_set_char_spacing','cpdf_set_creator','cpdf_set_current_page',
+ 'cpdf_set_font','cpdf_set_font_directories',
+ 'cpdf_set_font_map_file','cpdf_set_horiz_scaling',
+ 'cpdf_set_keywords','cpdf_set_leading','cpdf_set_page_animation',
+ 'cpdf_set_subject','cpdf_set_text_matrix','cpdf_set_text_pos',
+ 'cpdf_set_text_rendering','cpdf_set_text_rise','cpdf_set_title',
+ 'cpdf_set_viewer_preferences','cpdf_set_word_spacing',
+ 'cpdf_setdash','cpdf_setflat','cpdf_setgray','cpdf_setgray_fill',
+ 'cpdf_setgray_stroke','cpdf_setlinecap','cpdf_setlinejoin',
+ 'cpdf_setlinewidth','cpdf_setmiterlimit','cpdf_setrgbcolor',
+ 'cpdf_setrgbcolor_fill','cpdf_setrgbcolor_stroke','cpdf_show',
+ 'cpdf_show_xy','cpdf_stringwidth','cpdf_stroke','cpdf_text',
+ 'cpdf_translate','crack_check','crack_closedict',
+ 'crack_getlastmessage','crack_opendict','crc32','create_function',
+ 'crypt','ctype_alnum','ctype_alpha','ctype_cntrl','ctype_digit',
+ 'ctype_graph','ctype_lower','ctype_print','ctype_punct',
+ 'ctype_space','ctype_upper','ctype_xdigit','curl_close',
+ 'curl_copy_handle','curl_errno','curl_error','curl_exec',
+ 'curl_getinfo','curl_init','curl_multi_add_handle',
+ 'curl_multi_close','curl_multi_exec','curl_multi_getcontent',
+ 'curl_multi_info_read','curl_multi_init','curl_multi_remove_handle',
+ 'curl_multi_select','curl_setopt','curl_setopt_array',
+ 'curl_version','current','cvsclient_connect','cvsclient_log',
+ 'cvsclient_login','cvsclient_retrieve','date','date_create',
+ 'date_date_set','date_default_timezone_get',
+ 'date_default_timezone_set','date_format','date_isodate_set',
+ 'date_modify','date_offset_get','date_parse','date_sun_info',
+ 'date_sunrise','date_sunset','date_time_set','date_timezone_get',
+ 'date_timezone_set','db_id_list','dba_close','dba_delete',
+ 'dba_exists','dba_fetch','dba_firstkey','dba_handlers','dba_insert',
+ 'dba_key_split','dba_list','dba_nextkey','dba_open','dba_optimize',
+ 'dba_popen','dba_replace','dba_sync','dbase_add_record',
+ 'dbase_close','dbase_create','dbase_delete_record',
+ 'dbase_get_header_info','dbase_get_record',
+ 'dbase_get_record_with_names','dbase_numfields','dbase_numrecords',
+ 'dbase_open','dbase_pack','dbase_replace_record',
+ 'dbg_get_all_contexts','dbg_get_all_module_names',
+ 'dbg_get_all_source_lines','dbg_get_context_name',
+ 'dbg_get_module_name','dbg_get_profiler_results',
+ 'dbg_get_source_context','dblist','dbmclose','dbmdelete',
+ 'dbmexists','dbmfetch','dbmfirstkey','dbminsert','dbmnextkey',
+ 'dbmopen','dbmreplace','dbx_close','dbx_compare','dbx_connect',
+ 'dbx_error','dbx_escape_string','dbx_fetch_row','dbx_query',
+ 'dbx_sort','dcgettext','dcngettext','deaggregate','debug_backtrace',
+ 'debug_zval_dump','debugbreak','decbin','dechex','decoct','define',
+ 'defined','define_syslog_variables','deg2rad','dgettext','die',
+ 'dio_close','dio_open','dio_read','dio_seek','dio_stat','dio_write',
+ 'dir','dirname','disk_free_space','disk_total_space',
+ 'diskfreespace','dl','dngettext','docblock_token_name',
+ 'docblock_tokenize','dom_import_simplexml','domxml_add_root',
+ 'domxml_attributes','domxml_children','domxml_doc_add_root',
+ 'domxml_doc_document_element','domxml_doc_get_element_by_id',
+ 'domxml_doc_get_elements_by_tagname','domxml_doc_get_root',
+ 'domxml_doc_set_root','domxml_doc_validate','domxml_doc_xinclude',
+ 'domxml_dump_mem','domxml_dump_mem_file','domxml_dump_node',
+ 'domxml_dumpmem','domxml_elem_get_attribute',
+ 'domxml_elem_set_attribute','domxml_get_attribute','domxml_getattr',
+ 'domxml_html_dump_mem','domxml_new_child','domxml_new_doc',
+ 'domxml_new_xmldoc','domxml_node','domxml_node_add_namespace',
+ 'domxml_node_attributes','domxml_node_children',
+ 'domxml_node_get_content','domxml_node_has_attributes',
+ 'domxml_node_new_child','domxml_node_set_content',
+ 'domxml_node_set_namespace','domxml_node_unlink_node',
+ 'domxml_open_file','domxml_open_mem','domxml_parser',
+ 'domxml_parser_add_chunk','domxml_parser_cdata_section',
+ 'domxml_parser_characters','domxml_parser_comment',
+ 'domxml_parser_end','domxml_parser_end_document',
+ 'domxml_parser_end_element','domxml_parser_entity_reference',
+ 'domxml_parser_get_document','domxml_parser_namespace_decl',
+ 'domxml_parser_processing_instruction',
+ 'domxml_parser_start_document','domxml_parser_start_element',
+ 'domxml_root','domxml_set_attribute','domxml_setattr',
+ 'domxml_substitute_entities_default','domxml_unlink_node',
+ 'domxml_version','domxml_xmltree','doubleval','each','easter_date',
+ 'easter_days','empty','end','ereg','ereg_replace','eregi',
+ 'eregi_replace','error_get_last','error_log','error_reporting',
+ 'escapeshellarg','escapeshellcmd','eval','event_deschedule',
+ 'event_dispatch','event_free','event_handle_signal',
+ 'event_have_events','event_init','event_new','event_pending',
+ 'event_priority_set','event_schedule','event_set','event_timeout',
+ 'exec','exif_imagetype','exif_read_data','exif_tagname',
+ 'exif_thumbnail','exit','exp','explode','expm1','extension_loaded',
+ 'extract','ezmlm_hash','fbird_add_user','fbird_affected_rows',
+ 'fbird_backup','fbird_blob_add','fbird_blob_cancel',
+ 'fbird_blob_close','fbird_blob_create','fbird_blob_echo',
+ 'fbird_blob_get','fbird_blob_import','fbird_blob_info',
+ 'fbird_blob_open','fbird_close','fbird_commit','fbird_commit_ret',
+ 'fbird_connect','fbird_db_info','fbird_delete_user','fbird_drop_db',
+ 'fbird_errcode','fbird_errmsg','fbird_execute','fbird_fetch_assoc',
+ 'fbird_fetch_object','fbird_fetch_row','fbird_field_info',
+ 'fbird_free_event_handler','fbird_free_query','fbird_free_result',
+ 'fbird_gen_id','fbird_maintain_db','fbird_modify_user',
+ 'fbird_name_result','fbird_num_fields','fbird_num_params',
+ 'fbird_param_info','fbird_pconnect','fbird_prepare','fbird_query',
+ 'fbird_restore','fbird_rollback','fbird_rollback_ret',
+ 'fbird_server_info','fbird_service_attach','fbird_service_detach',
+ 'fbird_set_event_handler','fbird_trans','fbird_wait_event','fclose',
+ 'fdf_add_doc_javascript','fdf_add_template','fdf_close',
+ 'fdf_create','fdf_enum_values','fdf_errno','fdf_error','fdf_get_ap',
+ 'fdf_get_attachment','fdf_get_encoding','fdf_get_file',
+ 'fdf_get_flags','fdf_get_opt','fdf_get_status','fdf_get_value',
+ 'fdf_get_version','fdf_header','fdf_next_field_name','fdf_open',
+ 'fdf_open_string','fdf_remove_item','fdf_save','fdf_save_string',
+ 'fdf_set_ap','fdf_set_encoding','fdf_set_file','fdf_set_flags',
+ 'fdf_set_javascript_action','fdf_set_on_import_javascript',
+ 'fdf_set_opt','fdf_set_status','fdf_set_submit_form_action',
+ 'fdf_set_target_frame','fdf_set_value','fdf_set_version','feof',
+ 'fflush','fgetc','fgetcsv','fgets','fgetss','file','file_exists',
+ 'file_get_contents','file_put_contents','fileatime','filectime',
+ 'filegroup','fileinode','filemtime','fileowner','fileperms',
+ 'filepro','filepro_fieldcount','filepro_fieldname',
+ 'filepro_fieldtype','filepro_fieldwidth','filepro_retrieve',
+ 'filepro_rowcount','filesize','filetype','filter_has_var',
+ 'filter_id','filter_input','filter_input_array','filter_list',
+ 'filter_var','filter_var_array','finfo_buffer','finfo_close',
+ 'finfo_file','finfo_open','finfo_set_flags','floatval','flock',
+ 'floor','flush','fmod','fnmatch','fopen','fpassthru','fprintf',
+ 'fputcsv','fputs','fread','frenchtojd','fribidi_charset_info',
+ 'fribidi_get_charsets','fribidi_log2vis','fscanf','fseek',
+ 'fsockopen','fstat','ftell','ftok','ftp_alloc','ftp_cdup',
+ 'ftp_chdir','ftp_chmod','ftp_close','ftp_connect','ftp_delete',
+ 'ftp_exec','ftp_fget','ftp_fput','ftp_get','ftp_get_option',
+ 'ftp_login','ftp_mdtm','ftp_mkdir','ftp_nb_continue','ftp_nb_fget',
+ 'ftp_nb_fput','ftp_nb_get','ftp_nb_put','ftp_nlist','ftp_pasv',
+ 'ftp_put','ftp_pwd','ftp_quit','ftp_raw','ftp_rawlist','ftp_rename',
+ 'ftp_rmdir','ftp_set_option','ftp_site','ftp_size',
+ 'ftp_ssl_connect','ftp_systype','ftruncate','function_exists',
+ 'func_get_arg','func_get_args','func_num_args','fwrite','gd_info',
+ 'getallheaders','getcwd','getdate','getenv','gethostbyaddr',
+ 'gethostbyname','gethostbynamel','getimagesize','getlastmod',
+ 'getmxrr','getmygid','getmyinode','getmypid','getmyuid','getopt',
+ 'getprotobyname','getprotobynumber','getrandmax','getrusage',
+ 'getservbyname','getservbyport','gettext','gettimeofday','gettype',
+ 'get_browser','get_cfg_var','get_class','get_class_methods',
+ 'get_class_vars','get_current_user','get_declared_classes',
+ 'get_defined_constants','get_defined_functions','get_defined_vars',
+ 'get_extension_funcs','get_headers','get_html_translation_table',
+ 'get_included_files','get_include_path','get_loaded_extensions',
+ 'get_magic_quotes_gpc','get_magic_quotes_runtime','get_meta_tags',
+ 'get_object_vars','get_parent_class','get_required_files',
+ 'get_resource_type','glob','gmdate','gmmktime','gmp_abs','gmp_add',
+ 'gmp_and','gmp_clrbit','gmp_cmp','gmp_com','gmp_div','gmp_div_q',
+ 'gmp_div_qr','gmp_div_r','gmp_divexact','gmp_fact','gmp_gcd',
+ 'gmp_gcdext','gmp_hamdist','gmp_init','gmp_intval','gmp_invert',
+ 'gmp_jacobi','gmp_legendre','gmp_mod','gmp_mul','gmp_neg',
+ 'gmp_nextprime','gmp_or','gmp_perfect_square','gmp_popcount',
+ 'gmp_pow','gmp_powm','gmp_prob_prime','gmp_random','gmp_scan0',
+ 'gmp_scan1','gmp_setbit','gmp_sign','gmp_sqrt','gmp_sqrtrem',
+ 'gmp_strval','gmp_sub','gmp_xor','gmstrftime','gopher_parsedir',
+ 'gregoriantojd','gzclose','gzcompress','gzdeflate','gzencode',
+ 'gzeof','gzfile','gzgetc','gzgets','gzgetss','gzinflate','gzopen',
+ 'gzpassthru','gzputs','gzread','gzrewind','gzseek','gztell',
+ 'gzuncompress','gzwrite','hash','hash_algos','hash_file',
+ 'hash_final','hash_hmac','hash_hmac_file','hash_init','hash_update',
+ 'hash_update_file','hash_update_stream','header','headers_list',
+ 'headers_sent','hebrev','hebrevc','hexdec','highlight_file',
+ 'highlight_string','html_doc','html_doc_file','html_entity_decode',
+ 'htmlentities','htmlspecialchars','htmlspecialchars_decode',
+ 'http_build_cookie','http_build_query','http_build_str',
+ 'http_build_url','http_cache_etag','http_cache_last_modified',
+ 'http_chunked_decode','http_date','http_deflate','http_get',
+ 'http_get_request_body','http_get_request_body_stream',
+ 'http_get_request_headers','http_head','http_inflate',
+ 'http_match_etag','http_match_modified','http_match_request_header',
+ 'http_negotiate_charset','http_negotiate_content_type',
+ 'http_negotiate_language','http_parse_cookie','http_parse_headers',
+ 'http_parse_message','http_parse_params',
+ 'http_persistent_handles_clean','http_persistent_handles_count',
+ 'http_persistent_handles_ident','http_post_data','http_post_fields',
+ 'http_put_data','http_put_file','http_put_stream','http_redirect',
+ 'http_request','http_request_body_encode',
+ 'http_request_method_exists','http_request_method_name',
+ 'http_request_method_register','http_request_method_unregister',
+ 'http_send_content_disposition','http_send_content_type',
+ 'http_send_data','http_send_file','http_send_last_modified',
+ 'http_send_status','http_send_stream','http_support',
+ 'http_throttle','hypot','i18n_convert','i18n_discover_encoding',
+ 'i18n_http_input','i18n_http_output','i18n_internal_encoding',
+ 'i18n_ja_jp_hantozen','i18n_mime_header_decode',
+ 'i18n_mime_header_encode','ibase_add_user','ibase_affected_rows',
+ 'ibase_backup','ibase_blob_add','ibase_blob_cancel',
+ 'ibase_blob_close','ibase_blob_create','ibase_blob_echo',
+ 'ibase_blob_get','ibase_blob_import','ibase_blob_info',
+ 'ibase_blob_open','ibase_close','ibase_commit','ibase_commit_ret',
+ 'ibase_connect','ibase_db_info','ibase_delete_user','ibase_drop_db',
+ 'ibase_errcode','ibase_errmsg','ibase_execute','ibase_fetch_assoc',
+ 'ibase_fetch_object','ibase_fetch_row','ibase_field_info',
+ 'ibase_free_event_handler','ibase_free_query','ibase_free_result',
+ 'ibase_gen_id','ibase_maintain_db','ibase_modify_user',
+ 'ibase_name_result','ibase_num_fields','ibase_num_params',
+ 'ibase_param_info','ibase_pconnect','ibase_prepare','ibase_query',
+ 'ibase_restore','ibase_rollback','ibase_rollback_ret',
+ 'ibase_server_info','ibase_service_attach','ibase_service_detach',
+ 'ibase_set_event_handler','ibase_trans','ibase_wait_event','iconv',
+ 'iconv_get_encoding','iconv_mime_decode',
+ 'iconv_mime_decode_headers','iconv_mime_encode',
+ 'iconv_set_encoding','iconv_strlen','iconv_strpos','iconv_strrpos',
+ 'iconv_substr','id3_get_frame_long_name','id3_get_frame_short_name',
+ 'id3_get_genre_id','id3_get_genre_list','id3_get_genre_name',
+ 'id3_get_tag','id3_get_version','id3_remove_tag','id3_set_tag',
+ 'idate','ignore_user_abort','image_type_to_extension',
+ 'image_type_to_mime_type','image2wbmp','imagealphablending',
+ 'imageantialias','imagearc','imagechar','imagecharup',
+ 'imagecolorallocate','imagecolorallocatealpha','imagecolorat',
+ 'imagecolorclosest','imagecolorclosestalpha','imagecolordeallocate',
+ 'imagecolorexact','imagecolorexactalpha','imagecolormatch',
+ 'imagecolorresolve','imagecolorresolvealpha','imagecolorset',
+ 'imagecolorsforindex','imagecolorstotal','imagecolortransparent',
+ 'imageconvolution','imagecopy','imagecopymerge',
+ 'imagecopymergegray','imagecopyresampled','imagecopyresized',
+ 'imagecreate','imagecreatefromgd','imagecreatefromgd2',
+ 'imagecreatefromgd2part','imagecreatefromgif','imagecreatefromjpeg',
+ 'imagecreatefrompng','imagecreatefromstring','imagecreatefromwbmp',
+ 'imagecreatefromxbm','imagecreatetruecolor','imagedashedline',
+ 'imagedestroy','imageellipse','imagefill','imagefilledarc',
+ 'imagefilledellipse','imagefilledpolygon','imagefilledrectangle',
+ 'imagefilltoborder','imagefilter','imagefontheight',
+ 'imagefontwidth','imageftbbox','imagefttext','imagegammacorrect',
+ 'imagegd','imagegd2','imagegif','imagegrabscreen','imagegrabwindow',
+ 'imageinterlace','imageistruecolor','imagejpeg','imagelayereffect',
+ 'imageline','imageloadfont','imagepalettecopy','imagepng',
+ 'imagepolygon','imagepsbbox','imagepsencodefont',
+ 'imagepsextendfont','imagepsfreefont','imagepsloadfont',
+ 'imagepsslantfont','imagepstext','imagerectangle','imagerotate',
+ 'imagesavealpha','imagesetbrush','imagesetpixel','imagesetstyle',
+ 'imagesetthickness','imagesettile','imagestring','imagestringup',
+ 'imagesx','imagesy','imagetruecolortopalette','imagettfbbox',
+ 'imagettftext','imagetypes','imagewbmp','imagexbm','imap_8bit',
+ 'imap_alerts','imap_append','imap_base64','imap_binary','imap_body',
+ 'imap_bodystruct','imap_check','imap_clearflag_full','imap_close',
+ 'imap_create','imap_createmailbox','imap_delete',
+ 'imap_deletemailbox','imap_errors','imap_expunge',
+ 'imap_fetch_overview','imap_fetchbody','imap_fetchheader',
+ 'imap_fetchstructure','imap_fetchtext','imap_get_quota',
+ 'imap_get_quotaroot','imap_getacl','imap_getmailboxes',
+ 'imap_getsubscribed','imap_header','imap_headerinfo','imap_headers',
+ 'imap_last_error','imap_list','imap_listmailbox',
+ 'imap_listsubscribed','imap_lsub','imap_mail','imap_mail_compose',
+ 'imap_mail_copy','imap_mail_move','imap_mailboxmsginfo',
+ 'imap_mime_header_decode','imap_msgno','imap_num_msg',
+ 'imap_num_recent','imap_open','imap_ping','imap_qprint',
+ 'imap_rename','imap_renamemailbox','imap_reopen',
+ 'imap_rfc822_parse_adrlist','imap_rfc822_parse_headers',
+ 'imap_rfc822_write_address','imap_savebody','imap_scan',
+ 'imap_scanmailbox','imap_search','imap_set_quota','imap_setacl',
+ 'imap_setflag_full','imap_sort','imap_status','imap_subscribe',
+ 'imap_thread','imap_timeout','imap_uid','imap_undelete',
+ 'imap_unsubscribe','imap_utf7_decode','imap_utf7_encode',
+ 'imap_utf8','implode','import_request_variables','in_array',
+ 'ini_alter','ini_get','ini_get_all','ini_restore','ini_set',
+ 'intval','ip2long','iptcembed','iptcparse','isset','is_a',
+ 'is_array','is_bool','is_callable','is_dir','is_double',
+ 'is_executable','is_file','is_finite','is_float','is_infinite',
+ 'is_int','is_integer','is_link','is_long','is_nan','is_null',
+ 'is_numeric','is_object','is_readable','is_real','is_resource',
+ 'is_scalar','is_soap_fault','is_string','is_subclass_of',
+ 'is_uploaded_file','is_writable','is_writeable','iterator_apply',
+ 'iterator_count','iterator_to_array','java_last_exception_clear',
+ 'java_last_exception_get','jddayofweek','jdmonthname','jdtofrench',
+ 'jdtogregorian','jdtojewish','jdtojulian','jdtounix','jewishtojd',
+ 'join','jpeg2wbmp','json_decode','json_encode','juliantojd','key',
+ 'key_exists','krsort','ksort','lcg_value','ldap_add','ldap_bind',
+ 'ldap_close','ldap_compare','ldap_connect','ldap_count_entries',
+ 'ldap_delete','ldap_dn2ufn','ldap_err2str','ldap_errno',
+ 'ldap_error','ldap_explode_dn','ldap_first_attribute',
+ 'ldap_first_entry','ldap_first_reference','ldap_free_result',
+ 'ldap_get_attributes','ldap_get_dn','ldap_get_entries',
+ 'ldap_get_option','ldap_get_values','ldap_get_values_len',
+ 'ldap_list','ldap_mod_add','ldap_mod_del','ldap_mod_replace',
+ 'ldap_modify','ldap_next_attribute','ldap_next_entry',
+ 'ldap_next_reference','ldap_parse_reference','ldap_parse_result',
+ 'ldap_read','ldap_rename','ldap_search','ldap_set_option',
+ 'ldap_sort','ldap_start_tls','ldap_unbind','levenshtein',
+ 'libxml_clear_errors','libxml_get_errors','libxml_get_last_error',
+ 'libxml_set_streams_context','libxml_use_internal_errors','link',
+ 'linkinfo','list','localeconv','localtime','log','log1p','log10',
+ 'long2ip','lstat','ltrim','lzf_compress','lzf_decompress',
+ 'lzf_optimized_for','magic_quotes_runtime','mail','max','mbereg',
+ 'mberegi','mberegi_replace','mbereg_match','mbereg_replace',
+ 'mbereg_search','mbereg_search_getpos','mbereg_search_getregs',
+ 'mbereg_search_init','mbereg_search_pos','mbereg_search_regs',
+ 'mbereg_search_setpos','mbregex_encoding','mbsplit','mbstrcut',
+ 'mbstrlen','mbstrpos','mbstrrpos','mbsubstr','mb_check_encoding',
+ 'mb_convert_case','mb_convert_encoding','mb_convert_kana',
+ 'mb_convert_variables','mb_decode_mimeheader',
+ 'mb_decode_numericentity','mb_detect_encoding','mb_detect_order',
+ 'mb_encode_mimeheader','mb_encode_numericentity','mb_ereg',
+ 'mb_eregi','mb_eregi_replace','mb_ereg_match','mb_ereg_replace',
+ 'mb_ereg_search','mb_ereg_search_getpos','mb_ereg_search_getregs',
+ 'mb_ereg_search_init','mb_ereg_search_pos','mb_ereg_search_regs',
+ 'mb_ereg_search_setpos','mb_get_info','mb_http_input',
+ 'mb_http_output','mb_internal_encoding','mb_language',
+ 'mb_list_encodings','mb_output_handler','mb_parse_str',
+ 'mb_preferred_mime_name','mb_regex_encoding','mb_regex_set_options',
+ 'mb_send_mail','mb_split','mb_strcut','mb_strimwidth','mb_stripos',
+ 'mb_stristr','mb_strlen','mb_strpos','mb_strrchr','mb_strrichr',
+ 'mb_strripos','mb_strrpos','mb_strstr','mb_strtolower',
+ 'mb_strtoupper','mb_strwidth','mb_substitute_character','mb_substr',
+ 'mb_substr_count','mcrypt_cbc','mcrypt_cfb','mcrypt_create_iv',
+ 'mcrypt_decrypt','mcrypt_ecb','mcrypt_enc_get_algorithms_name',
+ 'mcrypt_enc_get_block_size','mcrypt_enc_get_iv_size',
+ 'mcrypt_enc_get_key_size','mcrypt_enc_get_modes_name',
+ 'mcrypt_enc_get_supported_key_sizes',
+ 'mcrypt_enc_is_block_algorithm',
+ 'mcrypt_enc_is_block_algorithm_mode','mcrypt_enc_is_block_mode',
+ 'mcrypt_enc_self_test','mcrypt_encrypt','mcrypt_generic',
+ 'mcrypt_generic_deinit','mcrypt_generic_end','mcrypt_generic_init',
+ 'mcrypt_get_block_size','mcrypt_get_cipher_name',
+ 'mcrypt_get_iv_size','mcrypt_get_key_size','mcrypt_list_algorithms',
+ 'mcrypt_list_modes','mcrypt_module_close',
+ 'mcrypt_module_get_algo_block_size',
+ 'mcrypt_module_get_algo_key_size',
+ 'mcrypt_module_get_supported_key_sizes',
+ 'mcrypt_module_is_block_algorithm',
+ 'mcrypt_module_is_block_algorithm_mode',
+ 'mcrypt_module_is_block_mode','mcrypt_module_open',
+ 'mcrypt_module_self_test','mcrypt_ofb','md5','md5_file',
+ 'mdecrypt_generic','memcache_add','memcache_add_server',
+ 'memcache_close','memcache_connect','memcache_debug',
+ 'memcache_decrement','memcache_delete','memcache_flush',
+ 'memcache_get','memcache_get_extended_stats',
+ 'memcache_get_server_status','memcache_get_stats',
+ 'memcache_get_version','memcache_increment','memcache_pconnect',
+ 'memcache_replace','memcache_set','memcache_set_compress_threshold',
+ 'memcache_set_server_params','memory_get_peak_usage',
+ 'memory_get_usage','metaphone','mhash','mhash_count',
+ 'mhash_get_block_size','mhash_get_hash_name','mhash_keygen_s2k',
+ 'method_exists','microtime','mime_content_type','min',
+ 'ming_keypress','ming_setcubicthreshold','ming_setscale',
+ 'ming_useconstants','ming_useswfversion','mkdir','mktime',
+ 'money_format','move_uploaded_file','msql','msql_affected_rows',
+ 'msql_close','msql_connect','msql_create_db','msql_createdb',
+ 'msql_data_seek','msql_db_query','msql_dbname','msql_drop_db',
+ 'msql_dropdb','msql_error','msql_fetch_array','msql_fetch_field',
+ 'msql_fetch_object','msql_fetch_row','msql_field_flags',
+ 'msql_field_len','msql_field_name','msql_field_seek',
+ 'msql_field_table','msql_field_type','msql_fieldflags',
+ 'msql_fieldlen','msql_fieldname','msql_fieldtable','msql_fieldtype',
+ 'msql_free_result','msql_freeresult','msql_list_dbs',
+ 'msql_list_fields','msql_list_tables','msql_listdbs',
+ 'msql_listfields','msql_listtables','msql_num_fields',
+ 'msql_num_rows','msql_numfields','msql_numrows','msql_pconnect',
+ 'msql_query','msql_regcase','msql_result','msql_select_db',
+ 'msql_selectdb','msql_tablename','mssql_bind','mssql_close',
+ 'mssql_connect','mssql_data_seek','mssql_execute',
+ 'mssql_fetch_array','mssql_fetch_assoc','mssql_fetch_batch',
+ 'mssql_fetch_field','mssql_fetch_object','mssql_fetch_row',
+ 'mssql_field_length','mssql_field_name','mssql_field_seek',
+ 'mssql_field_type','mssql_free_result','mssql_free_statement',
+ 'mssql_get_last_message','mssql_guid_string','mssql_init',
+ 'mssql_min_error_severity','mssql_min_message_severity',
+ 'mssql_next_result','mssql_num_fields','mssql_num_rows',
+ 'mssql_pconnect','mssql_query','mssql_result','mssql_rows_affected',
+ 'mssql_select_db','mt_getrandmax','mt_rand','mt_srand','mysql',
+ 'mysql_affected_rows','mysql_client_encoding','mysql_close',
+ 'mysql_connect','mysql_createdb','mysql_create_db',
+ 'mysql_data_seek','mysql_dbname','mysql_db_name','mysql_db_query',
+ 'mysql_dropdb','mysql_drop_db','mysql_errno','mysql_error',
+ 'mysql_escape_string','mysql_fetch_array','mysql_fetch_assoc',
+ 'mysql_fetch_field','mysql_fetch_lengths','mysql_fetch_object',
+ 'mysql_fetch_row','mysql_fieldflags','mysql_fieldlen',
+ 'mysql_fieldname','mysql_fieldtable','mysql_fieldtype',
+ 'mysql_field_flags','mysql_field_len','mysql_field_name',
+ 'mysql_field_seek','mysql_field_table','mysql_field_type',
+ 'mysql_freeresult','mysql_free_result','mysql_get_client_info',
+ 'mysql_get_host_info','mysql_get_proto_info',
+ 'mysql_get_server_info','mysql_info','mysql_insert_id',
+ 'mysql_listdbs','mysql_listfields','mysql_listtables',
+ 'mysql_list_dbs','mysql_list_fields','mysql_list_processes',
+ 'mysql_list_tables','mysql_numfields','mysql_numrows',
+ 'mysql_num_fields','mysql_num_rows','mysql_pconnect','mysql_ping',
+ 'mysql_query','mysql_real_escape_string','mysql_result',
+ 'mysql_selectdb','mysql_select_db','mysql_set_charset','mysql_stat',
+ 'mysql_tablename','mysql_table_name','mysql_thread_id',
+ 'mysql_unbuffered_query','mysqli_affected_rows','mysqli_autocommit',
+ 'mysqli_bind_param','mysqli_bind_result','mysqli_change_user',
+ 'mysqli_character_set_name','mysqli_client_encoding','mysqli_close',
+ 'mysqli_commit','mysqli_connect','mysqli_connect_errno',
+ 'mysqli_connect_error','mysqli_data_seek','mysqli_debug',
+ 'mysqli_disable_reads_from_master','mysqli_disable_rpl_parse',
+ 'mysqli_dump_debug_info','mysqli_embedded_server_end',
+ 'mysqli_embedded_server_start','mysqli_enable_reads_from_master',
+ 'mysqli_enable_rpl_parse','mysqli_errno','mysqli_error',
+ 'mysqli_escape_string','mysqli_execute','mysqli_fetch',
+ 'mysqli_fetch_array','mysqli_fetch_assoc','mysqli_fetch_field',
+ 'mysqli_fetch_field_direct','mysqli_fetch_fields',
+ 'mysqli_fetch_lengths','mysqli_fetch_object','mysqli_fetch_row',
+ 'mysqli_field_count','mysqli_field_seek','mysqli_field_tell',
+ 'mysqli_free_result','mysqli_get_charset','mysqli_get_client_info',
+ 'mysqli_get_client_version','mysqli_get_host_info',
+ 'mysqli_get_metadata','mysqli_get_proto_info',
+ 'mysqli_get_server_info','mysqli_get_server_version',
+ 'mysqli_get_warnings','mysqli_info','mysqli_init',
+ 'mysqli_insert_id','mysqli_kill','mysqli_master_query',
+ 'mysqli_more_results','mysqli_multi_query','mysqli_next_result',
+ 'mysqli_num_fields','mysqli_num_rows','mysqli_options',
+ 'mysqli_param_count','mysqli_ping','mysqli_prepare','mysqli_query',
+ 'mysqli_real_connect','mysqli_real_escape_string',
+ 'mysqli_real_query','mysqli_report','mysqli_rollback',
+ 'mysqli_rpl_parse_enabled','mysqli_rpl_probe',
+ 'mysqli_rpl_query_type','mysqli_select_db','mysqli_send_long_data',
+ 'mysqli_send_query','mysqli_set_charset',
+ 'mysqli_set_local_infile_default','mysqli_set_local_infile_handler',
+ 'mysqli_set_opt','mysqli_slave_query','mysqli_sqlstate',
+ 'mysqli_ssl_set','mysqli_stat','mysqli_stmt_affected_rows',
+ 'mysqli_stmt_attr_get','mysqli_stmt_attr_set',
+ 'mysqli_stmt_bind_param','mysqli_stmt_bind_result',
+ 'mysqli_stmt_close','mysqli_stmt_data_seek','mysqli_stmt_errno',
+ 'mysqli_stmt_error','mysqli_stmt_execute','mysqli_stmt_fetch',
+ 'mysqli_stmt_field_count','mysqli_stmt_free_result',
+ 'mysqli_stmt_get_warnings','mysqli_stmt_init',
+ 'mysqli_stmt_insert_id','mysqli_stmt_num_rows',
+ 'mysqli_stmt_param_count','mysqli_stmt_prepare','mysqli_stmt_reset',
+ 'mysqli_stmt_result_metadata','mysqli_stmt_send_long_data',
+ 'mysqli_stmt_sqlstate','mysqli_stmt_store_result',
+ 'mysqli_store_result','mysqli_thread_id','mysqli_thread_safe',
+ 'mysqli_use_result','mysqli_warning_count','natcasesort','natsort',
+ 'new_xmldoc','next','ngettext','nl2br','nl_langinfo',
+ 'ntuser_getdomaincontroller','ntuser_getusergroups',
+ 'ntuser_getuserinfo','ntuser_getuserlist','number_format',
+ 'ob_clean','ob_deflatehandler','ob_end_clean','ob_end_flush',
+ 'ob_etaghandler','ob_flush','ob_get_clean','ob_get_contents',
+ 'ob_get_flush','ob_get_length','ob_get_level','ob_get_status',
+ 'ob_gzhandler','ob_iconv_handler','ob_implicit_flush',
+ 'ob_inflatehandler','ob_list_handlers','ob_start','ob_tidyhandler',
+ 'octdec','odbc_autocommit','odbc_binmode','odbc_close',
+ 'odbc_close_all','odbc_columnprivileges','odbc_columns',
+ 'odbc_commit','odbc_connect','odbc_cursor','odbc_data_source',
+ 'odbc_do','odbc_error','odbc_errormsg','odbc_exec','odbc_execute',
+ 'odbc_fetch_array','odbc_fetch_into','odbc_fetch_object',
+ 'odbc_fetch_row','odbc_field_len','odbc_field_name',
+ 'odbc_field_num','odbc_field_precision','odbc_field_scale',
+ 'odbc_field_type','odbc_foreignkeys','odbc_free_result',
+ 'odbc_gettypeinfo','odbc_longreadlen','odbc_next_result',
+ 'odbc_num_fields','odbc_num_rows','odbc_pconnect','odbc_prepare',
+ 'odbc_primarykeys','odbc_procedurecolumns','odbc_procedures',
+ 'odbc_result','odbc_result_all','odbc_rollback','odbc_setoption',
+ 'odbc_specialcolumns','odbc_statistics','odbc_tableprivileges',
+ 'odbc_tables','opendir','openlog','openssl_csr_export',
+ 'openssl_csr_export_to_file','openssl_csr_get_public_key',
+ 'openssl_csr_get_subject','openssl_csr_new','openssl_csr_sign',
+ 'openssl_error_string','openssl_free_key','openssl_get_privatekey',
+ 'openssl_get_publickey','openssl_open','openssl_pkcs12_export',
+ 'openssl_pkcs12_export_to_file','openssl_pkcs12_read',
+ 'openssl_pkcs7_decrypt','openssl_pkcs7_encrypt',
+ 'openssl_pkcs7_sign','openssl_pkcs7_verify','openssl_pkey_export',
+ 'openssl_pkey_export_to_file','openssl_pkey_free',
+ 'openssl_pkey_get_details','openssl_pkey_get_private',
+ 'openssl_pkey_get_public','openssl_pkey_new',
+ 'openssl_private_decrypt','openssl_private_encrypt',
+ 'openssl_public_decrypt','openssl_public_encrypt','openssl_seal',
+ 'openssl_sign','openssl_verify','openssl_x509_checkpurpose',
+ 'openssl_x509_check_private_key','openssl_x509_export',
+ 'openssl_x509_export_to_file','openssl_x509_free',
+ 'openssl_x509_parse','openssl_x509_read','ord',
+ 'output_add_rewrite_var','output_reset_rewrite_vars','overload',
+ 'outputdebugstring','pack','parse_ini_file','parse_str','parse_url',
+ 'parsekit_compile_file','parsekit_compile_string',
+ 'parsekit_func_arginfo','parsekit_opcode_flags',
+ 'parsekit_opcode_name','passthru','pathinfo','pclose',
+ 'pdf_add_bookmark','pdf_add_launchlink','pdf_add_locallink',
+ 'pdf_add_nameddest','pdf_add_note','pdf_add_pdflink',
+ 'pdf_add_thumbnail','pdf_add_weblink','pdf_arc','pdf_arcn',
+ 'pdf_attach_file','pdf_begin_font','pdf_begin_glyph',
+ 'pdf_begin_page','pdf_begin_pattern','pdf_begin_template',
+ 'pdf_circle','pdf_clip','pdf_close','pdf_close_image',
+ 'pdf_close_pdi','pdf_close_pdi_page','pdf_closepath',
+ 'pdf_closepath_fill_stroke','pdf_closepath_stroke','pdf_concat',
+ 'pdf_continue_text','pdf_create_gstate','pdf_create_pvf',
+ 'pdf_curveto','pdf_delete','pdf_delete_pvf','pdf_encoding_set_char',
+ 'pdf_end_font','pdf_end_glyph','pdf_end_page','pdf_end_pattern',
+ 'pdf_end_template','pdf_endpath','pdf_fill','pdf_fill_imageblock',
+ 'pdf_fill_pdfblock','pdf_fill_stroke','pdf_fill_textblock',
+ 'pdf_findfont','pdf_fit_image','pdf_fit_pdi_page',
+ 'pdf_fit_textline','pdf_get_apiname','pdf_get_buffer',
+ 'pdf_get_errmsg','pdf_get_errnum','pdf_get_parameter',
+ 'pdf_get_pdi_parameter','pdf_get_pdi_value','pdf_get_value',
+ 'pdf_initgraphics','pdf_lineto','pdf_load_font',
+ 'pdf_load_iccprofile','pdf_load_image','pdf_makespotcolor',
+ 'pdf_moveto','pdf_new','pdf_open_ccitt','pdf_open_file',
+ 'pdf_open_image','pdf_open_image_file','pdf_open_pdi',
+ 'pdf_open_pdi_page','pdf_place_image','pdf_place_pdi_page',
+ 'pdf_process_pdi','pdf_rect','pdf_restore','pdf_rotate','pdf_save',
+ 'pdf_scale','pdf_set_border_color','pdf_set_border_dash',
+ 'pdf_set_border_style','pdf_set_gstate','pdf_set_info',
+ 'pdf_set_parameter','pdf_set_text_pos','pdf_set_value',
+ 'pdf_setcolor','pdf_setdash','pdf_setdashpattern','pdf_setflat',
+ 'pdf_setfont','pdf_setlinecap','pdf_setlinejoin','pdf_setlinewidth',
+ 'pdf_setmatrix','pdf_setmiterlimit','pdf_setpolydash','pdf_shading',
+ 'pdf_shading_pattern','pdf_shfill','pdf_show','pdf_show_boxed',
+ 'pdf_show_xy','pdf_skew','pdf_stringwidth','pdf_stroke',
+ 'pdf_translate','pdo_drivers','pfsockopen','pg_affected_rows',
+ 'pg_cancel_query','pg_clientencoding','pg_client_encoding',
+ 'pg_close','pg_cmdtuples','pg_connect','pg_connection_busy',
+ 'pg_connection_reset','pg_connection_status','pg_convert',
+ 'pg_copy_from','pg_copy_to','pg_dbname','pg_delete','pg_end_copy',
+ 'pg_errormessage','pg_escape_bytea','pg_escape_string','pg_exec',
+ 'pg_execute','pg_fetch_all','pg_fetch_all_columns','pg_fetch_array',
+ 'pg_fetch_assoc','pg_fetch_object','pg_fetch_result','pg_fetch_row',
+ 'pg_fieldisnull','pg_fieldname','pg_fieldnum','pg_fieldprtlen',
+ 'pg_fieldsize','pg_fieldtype','pg_field_is_null','pg_field_name',
+ 'pg_field_num','pg_field_prtlen','pg_field_size','pg_field_table',
+ 'pg_field_type','pg_field_type_oid','pg_free_result',
+ 'pg_freeresult','pg_get_notify','pg_get_pid','pg_get_result',
+ 'pg_getlastoid','pg_host','pg_insert','pg_last_error',
+ 'pg_last_notice','pg_last_oid','pg_loclose','pg_locreate',
+ 'pg_loexport','pg_loimport','pg_loopen','pg_loread','pg_loreadall',
+ 'pg_lounlink','pg_lowrite','pg_lo_close','pg_lo_create',
+ 'pg_lo_export','pg_lo_import','pg_lo_open','pg_lo_read',
+ 'pg_lo_read_all','pg_lo_seek','pg_lo_tell','pg_lo_unlink',
+ 'pg_lo_write','pg_meta_data','pg_numfields','pg_numrows',
+ 'pg_num_fields','pg_num_rows','pg_options','pg_parameter_status',
+ 'pg_pconnect','pg_ping','pg_port','pg_prepare','pg_put_line',
+ 'pg_query','pg_query_params','pg_result','pg_result_error',
+ 'pg_result_error_field','pg_result_seek','pg_result_status',
+ 'pg_select','pg_send_execute','pg_send_prepare','pg_send_query',
+ 'pg_send_query_params','pg_set_client_encoding',
+ 'pg_set_error_verbosity','pg_setclientencoding','pg_trace',
+ 'pg_transaction_status','pg_tty','pg_unescape_bytea','pg_untrace',
+ 'pg_update','pg_version','php_egg_logo_guid','php_ini_loaded_file',
+ 'php_ini_scanned_files','php_logo_guid','php_real_logo_guid',
+ 'php_sapi_name','php_strip_whitespace','php_uname','phpcredits',
+ 'phpdoc_xml_from_string','phpinfo','phpversion','pi','png2wbmp',
+ 'pop3_close','pop3_delete_message','pop3_get_account_size',
+ 'pop3_get_message','pop3_get_message_count',
+ 'pop3_get_message_header','pop3_get_message_ids',
+ 'pop3_get_message_size','pop3_get_message_sizes','pop3_open',
+ 'pop3_undelete','popen','pos','posix_ctermid','posix_errno',
+ 'posix_getcwd','posix_getegid','posix_geteuid','posix_getgid',
+ 'posix_getgrgid','posix_getgrnam','posix_getgroups',
+ 'posix_getlogin','posix_getpgid','posix_getpgrp','posix_getpid',
+ 'posix_getppid','posix_getpwnam','posix_getpwuid','posix_getrlimit',
+ 'posix_getsid','posix_getuid','posix_get_last_error','posix_isatty',
+ 'posix_kill','posix_mkfifo','posix_setegid','posix_seteuid',
+ 'posix_setgid','posix_setpgid','posix_setsid','posix_setuid',
+ 'posix_strerror','posix_times','posix_ttyname','posix_uname','pow',
+ 'preg_grep','preg_last_error','preg_match','preg_match_all',
+ 'preg_quote','preg_replace','preg_replace_callback','preg_split',
+ 'prev','print_r','printf','proc_close','proc_get_status',
+ 'proc_open','proc_terminate','putenv','quoted_printable_decode',
+ 'quotemeta','rad2deg','radius_acct_open','radius_add_server',
+ 'radius_auth_open','radius_close','radius_config',
+ 'radius_create_request','radius_cvt_addr','radius_cvt_int',
+ 'radius_cvt_string','radius_demangle','radius_demangle_mppe_key',
+ 'radius_get_attr','radius_get_vendor_attr','radius_put_addr',
+ 'radius_put_attr','radius_put_int','radius_put_string',
+ 'radius_put_vendor_addr','radius_put_vendor_attr',
+ 'radius_put_vendor_int','radius_put_vendor_string',
+ 'radius_request_authenticator','radius_send_request',
+ 'radius_server_secret','radius_strerror','rand','range',
+ 'rawurldecode','rawurlencode','read_exif_data','readdir','readfile',
+ 'readgzfile','readlink','realpath','reg_close_key','reg_create_key',
+ 'reg_enum_key','reg_enum_value','reg_get_value','reg_open_key',
+ 'reg_set_value','register_shutdown_function',
+ 'register_tick_function','rename','res_close','res_get','res_list',
+ 'res_list_type','res_open','res_set','reset',
+ 'restore_error_handler','restore_include_path','rewind','rewinddir',
+ 'rmdir','round','rsort','rtrim','runkit_class_adopt',
+ 'runkit_class_emancipate','runkit_constant_add',
+ 'runkit_constant_redefine','runkit_constant_remove',
+ 'runkit_default_property_add','runkit_function_add',
+ 'runkit_function_copy','runkit_function_redefine',
+ 'runkit_function_remove','runkit_function_rename','runkit_import',
+ 'runkit_lint','runkit_lint_file','runkit_method_add',
+ 'runkit_method_copy','runkit_method_redefine',
+ 'runkit_method_remove','runkit_method_rename','runkit_object_id',
+ 'runkit_return_value_used','runkit_sandbox_output_handler',
+ 'runkit_superglobals','runkit_zval_inspect','scandir','sem_acquire',
+ 'sem_get','sem_release','sem_remove','serialize',
+ 'session_cache_expire','session_cache_limiter','session_commit',
+ 'session_decode','session_destroy','session_encode',
+ 'session_get_cookie_params','session_id','session_is_registered',
+ 'session_module_name','session_name','session_regenerate_id',
+ 'session_register','session_save_path','session_set_cookie_params',
+ 'session_set_save_handler','session_start','session_unregister',
+ 'session_unset','session_write_close','set_content',
+ 'set_error_handler','set_file_buffer','set_include_path',
+ 'set_magic_quotes_runtime','set_socket_blocking','set_time_limit',
+ 'setcookie','setlocale','setrawcookie','settype','sha1','sha1_file',
+ 'shell_exec','shmop_close','shmop_delete','shmop_open','shmop_read',
+ 'shmop_size','shmop_write','shm_attach','shm_detach','shm_get_var',
+ 'shm_put_var','shm_remove','shm_remove_var','show_source','shuffle',
+ 'similar_text','simplexml_import_dom','simplexml_load_file',
+ 'simplexml_load_string','sin','sinh','sizeof','sleep','smtp_close',
+ 'smtp_cmd_data','smtp_cmd_mail','smtp_cmd_rcpt','smtp_connect',
+ 'snmp_get_quick_print','snmp_get_valueretrieval','snmp_read_mib',
+ 'snmp_set_quick_print','snmp_set_valueretrieval','snmp2_get',
+ 'snmp2_getnext','snmp2_real_walk','snmp2_set','snmp2_walk',
+ 'snmp3_get','snmp3_getnext','snmp3_real_walk','snmp3_set',
+ 'snmp3_walk','snmpget','snmpgetnext','snmprealwalk','snmpset',
+ 'snmpwalk','snmpwalkoid','socket_accept','socket_bind',
+ 'socket_clear_error','socket_close','socket_connect',
+ 'socket_create','socket_create_listen','socket_create_pair',
+ 'socket_getopt','socket_getpeername','socket_getsockname',
+ 'socket_get_option','socket_get_status','socket_iovec_add',
+ 'socket_iovec_alloc','socket_iovec_delete','socket_iovec_fetch',
+ 'socket_iovec_free','socket_iovec_set','socket_last_error',
+ 'socket_listen','socket_read','socket_readv','socket_recv',
+ 'socket_recvfrom','socket_recvmsg','socket_select','socket_send',
+ 'socket_sendmsg','socket_sendto','socket_setopt','socket_set_block',
+ 'socket_set_blocking','socket_set_nonblock','socket_set_option',
+ 'socket_set_timeout','socket_shutdown','socket_strerror',
+ 'socket_write','socket_writev','sort','soundex','spl_autoload',
+ 'spl_autoload_call','spl_autoload_extensions',
+ 'spl_autoload_functions','spl_autoload_register',
+ 'spl_autoload_unregister','spl_classes','spl_object_hash','split',
+ 'spliti','sprintf','sql_regcase','sqlite_array_query',
+ 'sqlite_busy_timeout','sqlite_changes','sqlite_close',
+ 'sqlite_column','sqlite_create_aggregate','sqlite_create_function',
+ 'sqlite_current','sqlite_error_string','sqlite_escape_string',
+ 'sqlite_exec','sqlite_factory','sqlite_fetch_all',
+ 'sqlite_fetch_array','sqlite_fetch_column_types',
+ 'sqlite_fetch_object','sqlite_fetch_single','sqlite_fetch_string',
+ 'sqlite_field_name','sqlite_has_more','sqlite_has_prev',
+ 'sqlite_last_error','sqlite_last_insert_rowid','sqlite_libencoding',
+ 'sqlite_libversion','sqlite_next','sqlite_num_fields',
+ 'sqlite_num_rows','sqlite_open','sqlite_popen','sqlite_prev',
+ 'sqlite_query','sqlite_rewind','sqlite_seek','sqlite_single_query',
+ 'sqlite_udf_decode_binary','sqlite_udf_encode_binary',
+ 'sqlite_unbuffered_query','sqlite_valid','sqrt','srand','sscanf',
+ 'ssh2_auth_hostbased_file','ssh2_auth_none','ssh2_auth_password',
+ 'ssh2_auth_pubkey_file','ssh2_connect','ssh2_exec',
+ 'ssh2_fetch_stream','ssh2_fingerprint','ssh2_forward_accept',
+ 'ssh2_forward_listen','ssh2_methods_negotiated','ssh2_poll',
+ 'ssh2_publickey_add','ssh2_publickey_init','ssh2_publickey_list',
+ 'ssh2_publickey_remove','ssh2_scp_recv','ssh2_scp_send','ssh2_sftp',
+ 'ssh2_sftp_lstat','ssh2_sftp_mkdir','ssh2_sftp_readlink',
+ 'ssh2_sftp_realpath','ssh2_sftp_rename','ssh2_sftp_rmdir',
+ 'ssh2_sftp_stat','ssh2_sftp_symlink','ssh2_sftp_unlink',
+ 'ssh2_shell','ssh2_tunnel','stat','stats_absolute_deviation',
+ 'stats_cdf_beta','stats_cdf_binomial','stats_cdf_cauchy',
+ 'stats_cdf_chisquare','stats_cdf_exponential','stats_cdf_f',
+ 'stats_cdf_gamma','stats_cdf_laplace','stats_cdf_logistic',
+ 'stats_cdf_negative_binomial','stats_cdf_noncentral_chisquare',
+ 'stats_cdf_noncentral_f','stats_cdf_noncentral_t',
+ 'stats_cdf_normal','stats_cdf_poisson','stats_cdf_t',
+ 'stats_cdf_uniform','stats_cdf_weibull','stats_covariance',
+ 'stats_dens_beta','stats_dens_cauchy','stats_dens_chisquare',
+ 'stats_dens_exponential','stats_dens_f','stats_dens_gamma',
+ 'stats_dens_laplace','stats_dens_logistic','stats_dens_normal',
+ 'stats_dens_pmf_binomial','stats_dens_pmf_hypergeometric',
+ 'stats_dens_pmf_negative_binomial','stats_dens_pmf_poisson',
+ 'stats_dens_t','stats_dens_uniform','stats_dens_weibull',
+ 'stats_harmonic_mean','stats_kurtosis','stats_rand_gen_beta',
+ 'stats_rand_gen_chisquare','stats_rand_gen_exponential',
+ 'stats_rand_gen_f','stats_rand_gen_funiform','stats_rand_gen_gamma',
+ 'stats_rand_gen_ipoisson','stats_rand_gen_iuniform',
+ 'stats_rand_gen_noncenral_f','stats_rand_gen_noncentral_chisquare',
+ 'stats_rand_gen_noncentral_t','stats_rand_gen_normal',
+ 'stats_rand_gen_t','stats_rand_getsd','stats_rand_ibinomial',
+ 'stats_rand_ibinomial_negative','stats_rand_ignlgi',
+ 'stats_rand_phrase_to_seeds','stats_rand_ranf','stats_rand_setall',
+ 'stats_skew','stats_standard_deviation','stats_stat_binomial_coef',
+ 'stats_stat_correlation','stats_stat_factorial',
+ 'stats_stat_independent_t','stats_stat_innerproduct',
+ 'stats_stat_paired_t','stats_stat_percentile','stats_stat_powersum',
+ 'stats_variance','strcasecmp','strchr','strcmp','strcoll','strcspn',
+ 'stream_bucket_append','stream_bucket_make_writeable',
+ 'stream_bucket_new','stream_bucket_prepend','stream_context_create',
+ 'stream_context_get_default','stream_context_get_options',
+ 'stream_context_set_default','stream_context_set_option',
+ 'stream_context_set_params','stream_copy_to_stream',
+ 'stream_encoding','stream_filter_append','stream_filter_prepend',
+ 'stream_filter_register','stream_filter_remove',
+ 'stream_get_contents','stream_get_filters','stream_get_line',
+ 'stream_get_meta_data','stream_get_transports',
+ 'stream_get_wrappers','stream_is_local',
+ 'stream_notification_callback','stream_register_wrapper',
+ 'stream_resolve_include_path','stream_select','stream_set_blocking',
+ 'stream_set_timeout','stream_set_write_buffer',
+ 'stream_socket_accept','stream_socket_client',
+ 'stream_socket_enable_crypto','stream_socket_get_name',
+ 'stream_socket_pair','stream_socket_recvfrom',
+ 'stream_socket_sendto','stream_socket_server',
+ 'stream_socket_shutdown','stream_supports_lock',
+ 'stream_wrapper_register','stream_wrapper_restore',
+ 'stream_wrapper_unregister','strftime','stripcslashes','stripos',
+ 'stripslashes','strip_tags','stristr','strlen','strnatcasecmp',
+ 'strnatcmp','strpbrk','strncasecmp','strncmp','strpos','strrchr',
+ 'strrev','strripos','strrpos','strspn','strstr','strtok',
+ 'strtolower','strtotime','strtoupper','strtr','strval',
+ 'str_ireplace','str_pad','str_repeat','str_replace','str_rot13',
+ 'str_split','str_shuffle','str_word_count','substr',
+ 'substr_compare','substr_count','substr_replace','svn_add',
+ 'svn_auth_get_parameter','svn_auth_set_parameter','svn_cat',
+ 'svn_checkout','svn_cleanup','svn_client_version','svn_commit',
+ 'svn_diff','svn_export','svn_fs_abort_txn','svn_fs_apply_text',
+ 'svn_fs_begin_txn2','svn_fs_change_node_prop','svn_fs_check_path',
+ 'svn_fs_contents_changed','svn_fs_copy','svn_fs_delete',
+ 'svn_fs_dir_entries','svn_fs_file_contents','svn_fs_file_length',
+ 'svn_fs_is_dir','svn_fs_is_file','svn_fs_make_dir',
+ 'svn_fs_make_file','svn_fs_node_created_rev','svn_fs_node_prop',
+ 'svn_fs_props_changed','svn_fs_revision_prop',
+ 'svn_fs_revision_root','svn_fs_txn_root','svn_fs_youngest_rev',
+ 'svn_import','svn_info','svn_log','svn_ls','svn_repos_create',
+ 'svn_repos_fs','svn_repos_fs_begin_txn_for_commit',
+ 'svn_repos_fs_commit_txn','svn_repos_hotcopy','svn_repos_open',
+ 'svn_repos_recover','svn_status','svn_update','symlink',
+ 'sys_get_temp_dir','syslog','system','tan','tanh','tempnam',
+ 'textdomain','thread_get','thread_include','thread_lock',
+ 'thread_lock_try','thread_mutex_destroy','thread_mutex_init',
+ 'thread_set','thread_start','thread_unlock','tidy_access_count',
+ 'tidy_clean_repair','tidy_config_count','tidy_diagnose',
+ 'tidy_error_count','tidy_get_body','tidy_get_config',
+ 'tidy_get_error_buffer','tidy_get_head','tidy_get_html',
+ 'tidy_get_html_ver','tidy_get_output','tidy_get_release',
+ 'tidy_get_root','tidy_get_status','tidy_getopt','tidy_is_xhtml',
+ 'tidy_is_xml','tidy_parse_file','tidy_parse_string',
+ 'tidy_repair_file','tidy_repair_string','tidy_warning_count','time',
+ 'timezone_abbreviations_list','timezone_identifiers_list',
+ 'timezone_name_from_abbr','timezone_name_get','timezone_offset_get',
+ 'timezone_open','timezone_transitions_get','tmpfile',
+ 'token_get_all','token_name','touch','trigger_error',
+ 'transliterate','transliterate_filters_get','trim','uasort',
+ 'ucfirst','ucwords','uksort','umask','uniqid','unixtojd','unlink',
+ 'unpack','unregister_tick_function','unserialize','unset',
+ 'urldecode','urlencode','user_error','use_soap_error_handler',
+ 'usleep','usort','utf8_decode','utf8_encode','var_dump',
+ 'var_export','variant_abs','variant_add','variant_and',
+ 'variant_cast','variant_cat','variant_cmp',
+ 'variant_date_from_timestamp','variant_date_to_timestamp',
+ 'variant_div','variant_eqv','variant_fix','variant_get_type',
+ 'variant_idiv','variant_imp','variant_int','variant_mod',
+ 'variant_mul','variant_neg','variant_not','variant_or',
+ 'variant_pow','variant_round','variant_set','variant_set_type',
+ 'variant_sub','variant_xor','version_compare','virtual','vfprintf',
+ 'vprintf','vsprintf','wddx_add_vars','wddx_deserialize',
+ 'wddx_packet_end','wddx_packet_start','wddx_serialize_value',
+ 'wddx_serialize_vars','win_beep','win_browse_file',
+ 'win_browse_folder','win_create_link','win_message_box',
+ 'win_play_wav','win_shell_execute','win32_create_service',
+ 'win32_delete_service','win32_get_last_control_message',
+ 'win32_ps_list_procs','win32_ps_stat_mem','win32_ps_stat_proc',
+ 'win32_query_service_status','win32_scheduler_delete_task',
+ 'win32_scheduler_enum_tasks','win32_scheduler_get_task_info',
+ 'win32_scheduler_run','win32_scheduler_set_task_info',
+ 'win32_set_service_status','win32_start_service',
+ 'win32_start_service_ctrl_dispatcher','win32_stop_service',
+ 'wordwrap','xml_error_string','xml_get_current_byte_index',
+ 'xml_get_current_column_number','xml_get_current_line_number',
+ 'xml_get_error_code','xml_parse','xml_parser_create',
+ 'xml_parser_create_ns','xml_parser_free','xml_parser_get_option',
+ 'xml_parser_set_option','xml_parse_into_struct',
+ 'xml_set_character_data_handler','xml_set_default_handler',
+ 'xml_set_element_handler','xml_set_end_namespace_decl_handler',
+ 'xml_set_external_entity_ref_handler',
+ 'xml_set_notation_decl_handler','xml_set_object',
+ 'xml_set_processing_instruction_handler',
+ 'xml_set_start_namespace_decl_handler',
+ 'xml_set_unparsed_entity_decl_handler','xmldoc','xmldocfile',
+ 'xmlrpc_decode','xmlrpc_decode_request','xmlrpc_encode',
+ 'xmlrpc_encode_request','xmlrpc_get_type','xmlrpc_is_fault',
+ 'xmlrpc_parse_method_descriptions',
+ 'xmlrpc_server_add_introspection_data','xmlrpc_server_call_method',
+ 'xmlrpc_server_create','xmlrpc_server_destroy',
+ 'xmlrpc_server_register_introspection_callback',
+ 'xmlrpc_server_register_method','xmlrpc_set_type','xmltree',
+ 'xmlwriter_end_attribute','xmlwriter_end_cdata',
+ 'xmlwriter_end_comment','xmlwriter_end_document',
+ 'xmlwriter_end_dtd','xmlwriter_end_dtd_attlist',
+ 'xmlwriter_end_dtd_element','xmlwriter_end_dtd_entity',
+ 'xmlwriter_end_element','xmlwriter_end_pi','xmlwriter_flush',
+ 'xmlwriter_full_end_element','xmlwriter_open_memory',
+ 'xmlwriter_open_uri','xmlwriter_output_memory',
+ 'xmlwriter_set_indent','xmlwriter_set_indent_string',
+ 'xmlwriter_start_attribute','xmlwriter_start_attribute_ns',
+ 'xmlwriter_start_cdata','xmlwriter_start_comment',
+ 'xmlwriter_start_document','xmlwriter_start_dtd',
+ 'xmlwriter_start_dtd_attlist','xmlwriter_start_dtd_element',
+ 'xmlwriter_start_dtd_entity','xmlwriter_start_element',
+ 'xmlwriter_start_element_ns','xmlwriter_start_pi','xmlwriter_text',
+ 'xmlwriter_write_attribute','xmlwriter_write_attribute_ns',
+ 'xmlwriter_write_cdata','xmlwriter_write_comment',
+ 'xmlwriter_write_dtd','xmlwriter_write_dtd_attlist',
+ 'xmlwriter_write_dtd_element','xmlwriter_write_dtd_entity',
+ 'xmlwriter_write_element','xmlwriter_write_element_ns',
+ 'xmlwriter_write_pi','xmlwriter_write_raw','xpath_eval',
+ 'xpath_eval_expression','xpath_new_context','xpath_register_ns',
+ 'xpath_register_ns_auto','xptr_eval','xptr_new_context','yp_all',
+ 'yp_cat','yp_errno','yp_err_string','yp_first',
+ 'yp_get_default_domain','yp_master','yp_match','yp_next','yp_order',
+ 'zend_current_obfuscation_level','zend_get_cfg_var','zend_get_id',
+ 'zend_loader_current_file','zend_loader_enabled',
+ 'zend_loader_file_encoded','zend_loader_file_licensed',
+ 'zend_loader_install_license','zend_loader_version',
+ 'zend_logo_guid','zend_match_hostmasks','zend_obfuscate_class_name',
+ 'zend_obfuscate_function_name','zend_optimizer_version',
+ 'zend_runtime_obfuscate','zend_version','zip_close',
+ 'zip_entry_close','zip_entry_compressedsize',
+ 'zip_entry_compressionmethod','zip_entry_filesize','zip_entry_name',
+ 'zip_entry_open','zip_entry_read','zip_open','zip_read',
+ 'zlib_get_coding_type'
+ ),
+ 4 => array(
+ 'DEFAULT_INCLUDE_PATH', 'DIRECTORY_SEPARATOR', 'E_ALL',
+ 'E_COMPILE_ERROR', 'E_COMPILE_WARNING', 'E_CORE_ERROR',
+ 'E_CORE_WARNING', 'E_ERROR', 'E_NOTICE', 'E_PARSE', 'E_STRICT',
+ 'E_USER_ERROR', 'E_USER_NOTICE', 'E_USER_WARNING', 'E_WARNING',
+ 'ENT_COMPAT','ENT_QUOTES','ENT_NOQUOTES',
+ 'false', 'null', 'PEAR_EXTENSION_DIR', 'PEAR_INSTALL_DIR',
+ 'PHP_BINDIR', 'PHP_CONFIG_FILE_PATH', 'PHP_DATADIR',
+ 'PHP_EXTENSION_DIR', 'PHP_LIBDIR',
+ 'PHP_LOCALSTATEDIR', 'PHP_OS',
+ 'PHP_OUTPUT_HANDLER_CONT', 'PHP_OUTPUT_HANDLER_END',
+ 'PHP_OUTPUT_HANDLER_START', 'PHP_SYSCONFDIR',
+ 'PHP_VERSION', 'true', '__CLASS__', '__FILE__', '__FUNCTION__',
+ '__LINE__', '__METHOD__'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '<'.'%', '<'.'%=', '%'.'>', '<'.'?', '<'.'?=', '?'.'>'
+ ),
+ 0 => array(
+ '(', ')', '[', ']', '{', '}',
+ '!', '@', '%', '&', '|', '/',
+ '<', '>',
+ '=', '-', '+', '*',
+ '.', ':', ',', ';'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #990000;',
+ 4 => 'color: #009900; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #666666; font-style: italic;',
+ 3 => 'color: #0000cc; font-style: italic;',
+ 4 => 'color: #009933; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #006699; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold; font-style: italic;',
+ 6 => 'color: #009933; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;',
+ 'HARD' => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #004000;',
+ 2 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;',
+ 1 => 'color: #000000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #000088;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.php.net/{FNAMEL}',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '-&gt;',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ //Variables
+ 0 => "[\\$]+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<'.'?php' => '?'.'>'
+ ),
+ 1 => array(
+ '<'.'?' => '?'.'>'
+ ),
+ 2 => array(
+ '<'.'%' => '%'.'>'
+ ),
+ 3 => array(
+ '<script language="php">' => '</script>'
+ ),
+ 4 => "/(?P<start><\\?(?>php\b)?)(?:".
+ "(?>[^\"'?\\/<]+)|".
+ "\\?(?!>)|".
+ "(?>'(?>[^'\\\\]|\\\\'|\\\\\\\|\\\\)*')|".
+ "(?>\"(?>[^\"\\\\]|\\\\\"|\\\\\\\\|\\\\)*\")|".
+ "(?>\\/\\*(?>[^\\*]|(?!\\*\\/)\\*)*\\*\\/)|".
+ "\\/\\/(?>.*?(?:\\?>|$))|".
+ "#(?>.*?(?:\\?>|$))|".
+ "\\/(?=[^*\\/])|".
+ "<(?!<<)|".
+ "<<<(?P<phpdoc>\w+)\s.*?\s\k<phpdoc>".
+ ")*?(?P<end>\\?>|\Z)/sm",
+ 5 => "/(?P<start><%)(?:".
+ "(?>[^\"'%\\/<]+)|".
+ "%(?!>)|".
+ "(?>'(?>[^'\\\\]|\\\\'|\\\\\\\|\\\\)*')|".
+ "(?>\"(?>[^\\\"\\\\]|\\\\\"|\\\\\\\\|\\\\)*\")|".
+ "(?>\\/\\*(?>[^\\*]|(?!\\*\\/)\\*)*\\*\\/)|".
+ "\\/\\/(?>.*?(?:%>|$))|".
+ "#(?>.*?(?:%>|$))|".
+ "\\/(?=[^*\\/])|".
+ "<(?!<<)|".
+ "<<<(?P<phpdoc>\w+)\s.*?\s\k<phpdoc>".
+ ")*?(?P<end>%>|\Z)/sm",
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/pic16.php b/platform/www/vendor/geshi/geshi/src/geshi/pic16.php
new file mode 100644
index 0000000..da5e263
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/pic16.php
@@ -0,0 +1,139 @@
+<?php
+/*************************************************************************************
+ * pic16.php
+ * -------
+ * Author: Phil Mattison (mattison@ohmikron.com)
+ * Copyright: (c) 2008 Ohmikron Corp. (http://www.ohmikron.com/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/07/30
+ *
+ * PIC16 Assembler language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/30 (1.0.8)
+ * - First Release
+ *
+ * TODO (updated 2008/07/30)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'PIC16',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ /*Instructions*/
+ 1 => array(
+ 'addcf','adddcf','addlw','addwf','andlw','andwf','bc','bcf','bdc',
+ 'bnc','bndc','bnz','bsf','btfsc','btfss','bz','call','clrc','clrdc',
+ 'clrf','clrw','clrwdt','clrz','comf','decf','goto','incf','incfsz',
+ 'iorlw','iorwf','lcall','lgoto','movf','movfw','movlw','movwf',
+ 'option','negf','nop','retfie','retlw','return','rlf','rrf','setc',
+ 'setdc','setz','skpc','skpdc','skpnc','skpndc','skpnz','skpz',
+ 'sleep','subcf','subdcf','sublw','subwf','swapf','tris','tstf',
+ 'xorlw','xorwf'
+ ),
+ /*Registers*/
+ 2 => array(
+ 'INDF','TMR0','OPTION','PCL','STATUS','FSR','PORTA','PORTB','PORTC',
+ 'PORTD','PORTE','PORTF','TRISA','TRISB','TRISC','TRISD','TRISE',
+ 'TRISF','PCLATH','INTCON','PIR1','PIE1','PCON','CMCON','VRCON',
+ 'F','W'
+ ),
+ /*Directives*/
+ 3 => array(
+ '_BADRAM','BANKISEL','BANKSEL','CBLOCK','CODE','_CONFIG','CONSTANT',
+ 'DA','DATA','DB','DE','#DEFINE','DT','DW','ELSE','END','ENDC',
+ 'ENDIF','ENDM','ENDW','EQU','ERROR','ERRORLEVEL','EXITM','EXPAND',
+ 'EXTERN','FILL','GLOBAL','IDATA','_IDLOCS','IF','IFDEF','IFNDEF',
+ 'INCLUDE','#INCLUDE','LIST','LOCAL','MACRO','_MAXRAM','MESSG',
+ 'NOEXPAND','NOLIST','ORG','PAGE','PAGESEL','PROCESSOR','RADIX',
+ 'RES','SET','SPACE','SUBTITLE','TITLE','UDATA','UDATA_ACS',
+ 'UDATA_OVR','UDATA_SHR','#UNDEFINE','VARIABLE','WHILE',
+ 'D','H','O','B','A'
+ ),
+ ),
+ 'SYMBOLS' => array('=','.',',',':'),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000a0; font-weight: bold;',
+ 2 => 'color: #aa3300; font-weight: bold;',
+ 3 => 'color: #0000ff;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #00a000;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff7700;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff7700;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #7777ff;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC |
+ GESHI_NUMBER_BIN_SUFFIX |
+ GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_HEX_SUFFIX,
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "a-zA-Z0-9\$_\|\#>|^",
+ 'DISALLOWED_AFTER' => "a-zA-Z0-9_<\|%"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/pike.php b/platform/www/vendor/geshi/geshi/src/geshi/pike.php
new file mode 100644
index 0000000..b07a05e
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/pike.php
@@ -0,0 +1,101 @@
+<?php
+/*************************************************************************************
+ * pike.php
+ * --------
+ * Author: Rick E. (codeblock@eighthbit.net)
+ * Copyright: (c) 2009 Rick E.
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/12/10
+ *
+ * Pike language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/12/25 (1.0.8.6)
+ * - First Release
+ *
+ * TODO (updated 2009/12/25)
+ * -------------------------
+ *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Pike',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'goto', 'break', 'continue', 'return', 'case', 'default', 'if',
+ 'else', 'switch', 'while', 'foreach', 'do', 'for', 'gauge',
+ 'destruct', 'lambda', 'inherit', 'import', 'typeof', 'catch',
+ 'inline', 'nomask', 'private', 'protected', 'public', 'static'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '(', ')', '{', '}', '[', ']', '+', '-', '*', '/', '%', '=', '!', '&', '|', '?', ';'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(1 => ''),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(1 => '.'),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/pixelbender.php b/platform/www/vendor/geshi/geshi/src/geshi/pixelbender.php
new file mode 100644
index 0000000..bb9c2a4
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/pixelbender.php
@@ -0,0 +1,173 @@
+<?php
+/*************************************************************************************
+ * pixelbender.php
+ * ----------------
+ * Author: Richard Olsson (r@richardolsson.se)
+ * Copyright: (c) 2008 Richard Olsson (richardolsson.se)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/11/16
+ *
+ * Pixel Bender 1.0 language file for GeSHi.
+ *
+ *
+ * Please feel free to modify this file, although I would greatly appreciate
+ * it if you would then send some feedback on why the file needed to be
+ * changed, using the e-mail address above.
+ *
+ *
+ * The colors are inspired by those used in the Pixel Bender Toolkit, with
+ * some slight modifications.
+ *
+ * For more info on Pixel Bender, see the Adobe Labs Wiki article at
+ * http://labs.adobe.com/wiki/index.php/Pixel_Bender_Toolkit.
+ *
+ * Keyword groups are defined as follows (groups marked with an asterisk
+ * inherit their names from terminology used in the language specification
+ * included with the Pixel Bender Toolkit, see URL above.)
+ *
+ * 1. languageVersion & kernel keywords
+ * 2. Kernel Members *
+ * 3. Types *
+ * 4. Statements * & qualifiers (in, out, inout)
+ * 5. Built-in functions *
+ * 6. Meta-data names
+ * 7. Preprocessor & Pre-defined symbols *
+ *
+ *
+ * CHANGES
+ * -------
+ * 2008/11/16 (1.0.8.2)
+ * - Initial release
+ *
+ * TODO (updated 2008/11/16)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Pixel Bender 1.0',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'languageVersion', 'kernel'
+ ),
+ 2 => array(
+ 'import', 'parameter', 'dependent', 'const', 'input', 'output',
+ 'evaluatePixel', 'evaluateDependents', 'needed', 'changed', 'generated'
+ ),
+ 3 => array(
+ 'bool', 'bool2', 'bool3', 'bool4', 'int', 'int2', 'int3', 'int4',
+ 'float', 'float2', 'float3', 'float4', 'float2x2', 'float3x3', 'float4x4',
+ 'pixel2', 'pixel3', 'pixel4', 'region', 'image1', 'image2', 'image3', 'image4',
+ 'imageRef', 'void'
+ ),
+ 4 => array(
+ 'in', 'out', 'inout', 'if', 'else', 'for', 'while', 'do', 'break',
+ 'continue', 'return'
+ ),
+ 5 => array(
+ 'radians', 'degrees', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan', 'pow',
+ 'exp', 'exp2', 'log', 'log2', 'sqrt', 'inverseSqrt', 'abs', 'sign', 'floor',
+ 'ceil', 'fract', 'mod', 'min', 'max', 'step', 'clamp', 'mix', 'smoothStep',
+ 'length', 'distance', 'dot', 'cross', 'normalize', 'matrixCompMult', 'lessThan',
+ 'lessThanEqual', 'greaterThan', 'greaterThanEqual', 'equal', 'notEqual', 'any',
+ 'all', 'not', 'nowhere', 'everywhere', 'transform', 'union', 'intersect',
+ 'outset', 'inset', 'bounds', 'isEmpty', 'sample', 'sampleLinear', 'sampleNearest',
+ 'outCoord', 'dod', 'pixelSize', 'pixelAspectRatio'
+ ),
+ 6 => array(
+ 'namespace', 'vendor', 'version', 'minValue', 'maxValue', 'defaultValue', 'description'
+ ),
+ 7 => array(
+ '#if', '#endif', '#ifdef', '#elif', 'defined', '#define',
+ 'AIF_ATI', 'AIF_NVIDIA', 'AIF_FLASH_TARGET'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '!', '%', '&', '|', '+', '-', '*', '/', '=', '<', '>', '?', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0033ff;',
+ 2 => 'color: #0033ff; font-weight: bold;',
+ 3 => 'color: #0033ff;',
+ 4 => 'color: #9900cc; font-weight: bold;',
+ 5 => 'color: #333333;',
+ 6 => 'color: #666666;',
+ 7 => 'color: #990000;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #009900;',
+ 'MULTI' => 'color: #3f5fbf;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #990000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000; font-weight:bold;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #000000;',
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array('.'),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/pli.php b/platform/www/vendor/geshi/geshi/src/geshi/pli.php
new file mode 100644
index 0000000..ac52a4c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/pli.php
@@ -0,0 +1,198 @@
+<?php
+/*************************************************************************************
+ * pli.php
+ * --------
+ * Author: Robert AH Prins (robert@prino.org)
+ * Copyright: (c) 2011 Robert AH Prins (http://hitchwiki.org/en/User:Prino)
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/02/09
+ *
+ * PL/I language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2011/02/09 (1.0.8.10)
+ * - First Release - machine(ish) generated by http://rosettacode.org/geshi/
+ *
+ * TODO (updated 2011/02/09)
+ * -------------------------
+ *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'PL/I',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', '\''),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'abnormal', 'abs', 'acos', 'acosf', 'add', 'addbuff', 'addr',
+ 'addrdata', 'alias', 'aligned', 'all', 'alloc', 'allocate',
+ 'allocation', 'allocn', 'allocsize', 'any', 'anycondition', 'area',
+ 'ascii', 'asin', 'asinf', 'asm', 'asmtdli', 'assembler',
+ 'assignable', 'atan', 'atand', 'atanf', 'atanh', 'attach',
+ 'attention', 'attn', 'auto', 'automatic', 'availablearea',
+ 'backwards', 'based', 'begin', 'bigendian', 'bin', 'binary',
+ 'binaryvalue', 'bind', 'binvalue', 'bit', 'bitloc', 'bitlocation',
+ 'bkwd', 'blksize', 'bool', 'buf', 'buffered', 'buffers', 'bufnd',
+ 'bufni', 'bufoff', 'bufsp', 'builtin', 'bx', 'by', 'byaddr', 'byte',
+ 'byvalue', 'b4', 'call', 'cast', 'cds', 'ceil', 'center',
+ 'centerleft', 'centerright', 'centre', 'centreleft', 'centreright',
+ 'char', 'character', 'charg', 'chargraphic', 'charval', 'check',
+ 'checkstg', 'close', 'cmpat', 'cobol', 'col', 'collate', 'column',
+ 'comment', 'compare', 'compiledate', 'compiletime', 'completion',
+ 'complex', 'cond', 'condition', 'conjg', 'conn', 'connected',
+ 'consecutive', 'controlled', 'conv', 'conversion', 'copy', 'cos',
+ 'cosd', 'cosf', 'cosh', 'count', 'counter', 'cpln', 'cplx', 'cs',
+ 'cstg', 'ctl', 'ctlasa', 'ctl360', 'currentsize', 'currentstorage',
+ 'data', 'datafield', 'date', 'datetime', 'days', 'daystodate',
+ 'daystosecs', 'db', 'dcl', 'dec', 'decimal', 'declare', 'def',
+ 'default', 'define', 'defined', 'delay', 'delete', 'descriptor',
+ 'descriptors', 'detach', 'dft', 'dim', 'dimacross', 'dimension',
+ 'direct', 'display', 'divide', 'do', 'downthru', 'edit', 'else',
+ 'empty', 'end', 'endfile', 'endpage', 'entry', 'entryaddr', 'env',
+ 'environment', 'epsilon', 'erf', 'erfc', 'error', 'event', 'excl',
+ 'exclusive', 'exit', 'exp', 'expf', 'exponent', 'exports', 'ext',
+ 'external', 'fb', 'fbs', 'fetch', 'file', 'fileddint', 'fileddtest',
+ 'fileddword', 'fileid', 'fileopen', 'fileread', 'fileseek',
+ 'filetell', 'filewrite', 'finish', 'first', 'fixed', 'fixedbin',
+ 'fixeddec', 'fixedoverflow', 'float', 'floatbin', 'floatdec',
+ 'floor', 'flush', 'fofl', 'format', 'fortran', 'free', 'from',
+ 'fromalien', 'fs', 'gamma', 'generic', 'genkey', 'get', 'getenv',
+ 'go', 'goto', 'graphic', 'gx', 'handle', 'hbound', 'hex', 'hexadec',
+ 'heximage', 'high', 'huge', 'iand', 'ieee', 'ieor', 'if', 'ignore',
+ 'imag', 'in', 'index', 'indexarea', 'indexed', 'init', 'initial',
+ 'inline', 'inonly', 'inot', 'inout', 'input', 'int', 'inter',
+ 'internal', 'into', 'invalidop', 'ior', 'irred', 'irreducible',
+ 'isfinite', 'isigned', 'isinf', 'isll', 'ismain', 'isnan',
+ 'isnormal', 'isrl', 'iszero', 'iunsigned', 'key', 'keyed',
+ 'keyfrom', 'keylength', 'keyloc', 'keyto', 'label', 'last',
+ 'lbound', 'leave', 'left', 'length', 'like', 'limited', 'line',
+ 'lineno', 'linesize', 'linkage', 'list', 'littleendian', 'loc',
+ 'locate', 'location', 'log', 'logf', 'loggamma', 'log10', 'log10f',
+ 'log2', 'low', 'lowercase', 'lower2', 'maccol', 'maclmar',
+ 'macname', 'macrmar', 'main', 'max', 'maxexp', 'maxlength',
+ 'memconvert', 'memcu12', 'memcu14', 'memcu21', 'memcu24', 'memcu41',
+ 'memcu42', 'memindex', 'memsearch', 'memsearchr', 'memverify',
+ 'memverifyr', 'min', 'minexp', 'mod', 'mpstr', 'multiply', 'name',
+ 'native', 'ncp', 'new', 'nocharg', 'nochargraphic', 'nocheck',
+ 'nocmpat', 'noconv', 'noconversion', 'nodescriptor', 'noexecops',
+ 'nofixedoverflow', 'nofofl', 'noinline', 'nolock', 'nomap',
+ 'nomapin', 'nomapout', 'nonasgn', 'nonassignable', 'nonconnected',
+ 'nonnative', 'noofl', 'nooverflow', 'norescan', 'normal', 'nosize',
+ 'nostrg', 'nostringrange', 'nostringsize', 'nostrz', 'nosubrg',
+ 'nosubscriptrange', 'noufl', 'nounderflow', 'nowrite', 'nozdiv',
+ 'nozerodivide', 'null', 'offset', 'offsetadd', 'offsetdiff',
+ 'offsetsubtract', 'offsetvalue', 'ofl', 'omitted', 'on', 'onarea',
+ 'onchar', 'oncode', 'oncondcond', 'oncondid', 'oncount', 'onfile',
+ 'ongsource', 'onkey', 'online', 'onloc', 'onoffset', 'onsource',
+ 'onsubcode', 'onwchar', 'onwsource', 'open', 'optional', 'options',
+ 'order', 'ordinal', 'ordinalname', 'ordinalpred', 'ordinalsucc',
+ 'other', 'otherwise', 'outonly', 'output', 'overflow', 'package',
+ 'packagename', 'page', 'pageno', 'pagesize', 'parameter', 'parmset',
+ 'password', 'pending', 'pic', 'picspec', 'picture', 'places',
+ 'pliascii', 'plicanc', 'plickpt', 'plidelete', 'plidump',
+ 'pliebcdic', 'plifill', 'plifree', 'plimove', 'pliover', 'plirest',
+ 'pliretc', 'pliretv', 'plisaxa', 'plisaxb', 'plisaxc', 'plisaxd',
+ 'plisrta', 'plisrtb', 'plisrtc', 'plisrtd', 'plitdli', 'plitran11',
+ 'plitran12', 'plitran21', 'plitran22', 'pointer', 'pointeradd',
+ 'pointerdiff', 'pointersubtract', 'pointervalue', 'poly', 'pos',
+ 'position', 'prec', 'precision', 'pred', 'present', 'print',
+ 'priority', 'proc', 'procedure', 'procedurename', 'procname',
+ 'prod', 'ptr', 'ptradd', 'ptrdiff', 'ptrsubtract', 'ptrvalue',
+ 'put', 'putenv', 'quote', 'radix', 'raise2', 'random', 'range',
+ 'rank', 'read', 'real', 'record', 'recsize', 'recursive', 'red',
+ 'reducible', 'reentrant', 'refer', 'regional', 'reg12', 'release',
+ 'rem', 'reorder', 'repattern', 'repeat', 'replaceby2', 'reply',
+ 'reread', 'rescan', 'reserved', 'reserves', 'resignal', 'respec',
+ 'retcode', 'return', 'returns', 'reuse', 'reverse', 'revert',
+ 'rewrite', 'right', 'round', 'rounddec', 'samekey', 'scalarvarying',
+ 'scale', 'search', 'searchr', 'secs', 'secstodate', 'secstodays',
+ 'select', 'seql', 'sequential', 'serialize4', 'set', 'sign',
+ 'signal', 'signed', 'sin', 'sind', 'sinf', 'sinh', 'sis', 'size',
+ 'skip', 'snap', 'sourcefile', 'sourceline', 'sqrt', 'sqrtf',
+ 'stackaddr', 'statement', 'static', 'status', 'stg', 'stmt', 'stop',
+ 'storage', 'stream', 'strg', 'string', 'stringrange', 'stringsize',
+ 'structure', 'strz', 'subrg', 'subscriptrange', 'substr',
+ 'subtract', 'succ', 'sum', 'suppress', 'sysin', 'sysnull',
+ 'sysparm', 'sysprint', 'system', 'sysversion', 'tally', 'tan',
+ 'tand', 'tanf', 'tanh', 'task', 'then', 'thread', 'threadid',
+ 'time', 'tiny', 'title', 'to', 'total', 'tpk', 'tpm', 'transient',
+ 'translate', 'transmit', 'trim', 'trkofl', 'trunc', 'type', 'ufl',
+ 'ulength', 'ulength16', 'ulength8', 'unal', 'unaligned',
+ 'unallocated', 'unbuf', 'unbuffered', 'undefinedfile', 'underflow',
+ 'undf', 'unlock', 'unsigned', 'unspec', 'until', 'update', 'upos',
+ 'uppercase', 'upthru', 'usubstr', 'usurrogate', 'uvalid', 'uwidth',
+ 'valid', 'validdate', 'value', 'var', 'varglist', 'vargsize',
+ 'variable', 'varying', 'varyingz', 'vb', 'vbs', 'verify', 'verifyr',
+ 'vs', 'vsam', 'wait', 'wchar', 'wcharval', 'weekday', 'when',
+ 'whigh', 'while', 'widechar', 'wlow', 'write', 'xmlchar', 'y4date',
+ 'y4julian', 'y4year', 'zdiv', 'zerodivide'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '+', '-', '*', '/', '=', '<', '>', '&', '^', '|', ':', '(', ')', ';', ','
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(1 => ''),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(1 => '.'),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/plsql.php b/platform/www/vendor/geshi/geshi/src/geshi/plsql.php
new file mode 100644
index 0000000..70dfb13
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/plsql.php
@@ -0,0 +1,254 @@
+<?php
+/*************************************************************************************
+ * plsql.php
+ * -------
+ * Author: Victor Engmark <victor.engmark@gmail.com>
+ * Copyright: (c) 2006 Victor Engmark (http://l0b0.net/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/10/26
+ *
+ * Oracle 9.2 PL/SQL language file for GeSHi.
+ * Formatting is based on the default setup of TOAD 8.6.
+ *
+ * CHANGES
+ * -------
+ * 2006/10/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2006/10/27)
+ * -------------------------
+ * * Add < and > to brackets
+ * * Remove symbols which are also comment delimiters / quote marks?
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'PL/SQL',
+ 'COMMENT_SINGLE' => array(1 =>'--'), //http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/02_funds.htm#2930
+ 'COMMENT_MULTI' => array('/*' => '*/'), //http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/02_funds.htm#2950
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array("'", '"'), //http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/02_funds.htm
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ //PL/SQL reserved keywords (http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/f_words.htm#LNPLS019)
+ 1 => array('ZONE', 'YEAR', 'WRITE', 'WORK', 'WITH', 'WHILE', 'WHERE',
+ 'WHENEVER', 'WHEN', 'VIEW', 'VARCHAR2', 'VARCHAR', 'VALUES',
+ 'VALIDATE', 'USE', 'UPDATE', 'UNIQUE', 'UNION', 'TYPE', 'TRUE',
+ 'TRIGGER', 'TO', 'TIMEZONE_REGION', 'TIMEZONE_MINUTE', 'TIMEZONE_HOUR',
+ 'TIMEZONE_ABBR', 'TIMESTAMP', 'TIME', 'THEN', 'TABLE', 'SYNONYM',
+ 'SUCCESSFUL', 'SUBTYPE', 'START', 'SQLERRM', 'SQLCODE', 'SQL', 'SPACE',
+ 'SMALLINT', 'SHARE', 'SET', 'SEPARATE', 'SELECT', 'SECOND',
+ 'SAVEPOINT', 'ROWTYPE', 'ROWNUM', 'ROWID', 'ROW', 'ROLLBACK',
+ 'REVERSE', 'RETURN', 'RELEASE', 'RECORD', 'REAL', 'RAW', 'RANGE',
+ 'RAISE', 'PUBLIC', 'PROCEDURE', 'PRIVATE', 'PRIOR', 'PRAGMA',
+ 'POSITIVEN', 'POSITIVE', 'PLS_INTEGER', 'PCTFREE', 'PARTITION',
+ 'PACKAGE', 'OUT', 'OTHERS', 'ORGANIZATION', 'ORDER', 'OR', 'OPTION',
+ 'OPERATOR', 'OPEN', 'OPAQUE', 'ON', 'OF', 'OCIROWID', 'NUMBER_BASE',
+ 'NUMBER', 'NULL', 'NOWAIT', 'NOT', 'NOCOPY', 'NEXTVAL', 'NEW',
+ 'NATURALN', 'NATURAL', 'MONTH', 'MODE', 'MLSLABEL', 'MINUTE', 'MINUS',
+ 'LOOP', 'LONG', 'LOCK', 'LIMITED', 'LIKE', 'LEVEL', 'JAVA',
+ 'ISOLATION', 'IS', 'INTO', 'INTERVAL', 'INTERSECT', 'INTERFACE',
+ 'INTEGER', 'INSERT', 'INDICATOR', 'INDEX', 'IN', 'IMMEDIATE', 'IF',
+ 'HOUR', 'HEAP', 'HAVING', 'GROUP', 'GOTO', 'FUNCTION', 'FROM',
+ 'FORALL', 'FOR', 'FLOAT', 'FETCH', 'FALSE', 'EXTENDS', 'EXIT',
+ 'EXISTS', 'EXECUTE', 'EXCLUSIVE', 'EXCEPTION', 'END', 'ELSIF', 'ELSE',
+ 'DROP', 'DO', 'DISTINCT', 'DESC', 'DELETE', 'DEFAULT', 'DECLARE',
+ 'DECIMAL', 'DAY', 'DATE', 'CURSOR', 'CURRVAL', 'CURRENT', 'CREATE',
+ 'CONSTANT', 'CONNECT', 'COMPRESS', 'COMMIT', 'COMMENT', 'COLLECT',
+ 'CLUSTER', 'CLOSE', 'CHECK', 'CHAR_BASE', 'CHAR', 'CASE', 'BY', 'BULK',
+ 'BOOLEAN', 'BODY', 'BINARY_INTEGER', 'BETWEEN', 'BEGIN', 'AUTHID',
+ 'AT', 'ASC', 'AS', 'ARRAY', 'ANY', 'AND', 'ALTER', 'ALL'),
+ //SQL functions (http://download-uk.oracle.com/docs/cd/B10501_01/server.920/a96540/toc.htm & http://download-uk.oracle.com/docs/cd/B10501_01/server.920/a96540/functions101a.htm#85925)
+ 2 => array('XMLTRANSFORM', 'XMLSEQUENCE', 'XMLFOREST', 'XMLELEMENT',
+ 'XMLCONCAT', 'XMLCOLATTVAL', 'XMLAGG', 'WIDTH_BUCKET', 'VSIZE',
+ 'VARIANCE', 'VAR_SAMP', 'VAR_POP', 'VALUE', 'USERENV', 'USER', 'UPPER',
+ 'UPDATEXML', 'UNISTR', 'UID', 'TZ_OFFSET', 'TRUNC', 'TRIM', 'TREAT',
+ 'TRANSLATE', 'TO_YMINTERVAL', 'TO_TIMESTAMP_TZ', 'TO_TIMESTAMP',
+ 'TO_SINGLE_BYTE', 'TO_NUMBER', 'TO_NCLOB', 'TO_NCHAR', 'TO_MULTI_BYTE',
+ 'TO_LOB', 'TO_DSINTERVAL', 'TO_DATE', 'TO_CLOB', 'TO_CHAR', 'TANH',
+ 'TAN', 'SYSTIMESTAMP', 'SYSDATE', 'SYS_XMLGEN', 'SYS_XMLAGG',
+ 'SYS_TYPEID', 'SYS_GUID', 'SYS_EXTRACT_UTC', 'SYS_DBURIGEN',
+ 'SYS_CONTEXT', 'SYS_CONNECT_BY_PATH', 'SUM', 'SUBSTR', 'STDDEV_SAMP',
+ 'STDDEV_POP', 'STDDEV', 'SQRT', 'SOUNDEX', 'SINH', 'SIN', 'SIGN',
+ 'SESSIONTIMEZONE', 'RTRIM', 'RPAD', 'ROWIDTONCHAR', 'ROWIDTOCHAR',
+ 'ROW_NUMBER', 'ROUND', 'REPLACE', 'REGR_SYY', 'REGR_SXY', 'REGR_SXX',
+ 'REGR_SLOPE', 'REGR_R2', 'REGR_INTERCEPT', 'REGR_COUNT', 'REGR_AVGY',
+ 'REGR_AVGX', 'REFTOHEX', 'REF', 'RAWTONHEX', 'RAWTOHEX',
+ 'RATIO_TO_REPORT', 'RANK', 'POWER', 'PERCENTILE_DISC',
+ 'PERCENTILE_CONT', 'PERCENT_RANK', 'PATH', 'NVL2', 'NVL',
+ 'NUMTOYMINTERVAL', 'NUMTODSINTERVAL', 'NULLIF', 'NTILE', 'NLSSORT',
+ 'NLS_UPPER', 'NLS_LOWER', 'NLS_INITCAP', 'NLS_CHARSET_NAME',
+ 'NLS_CHARSET_ID', 'NLS_CHARSET_DECL_LEN', 'NEXT_DAY', 'NEW_TIME',
+ 'NCHR', 'MONTHS_BETWEEN', 'MOD', 'MIN', 'MAX', 'MAKE_REF', 'LTRIM',
+ 'LPAD', 'LOWER', 'LOG', 'LOCALTIMESTAMP', 'LN', 'LENGTH', 'LEAST',
+ 'LEAD', 'LAST_VALUE', 'LAST_DAY', 'LAST', 'LAG', 'INSTR', 'INITCAP',
+ 'HEXTORAW', 'GROUPING_ID', 'GROUPING', 'GROUP_ID', 'GREATEST',
+ 'FROM_TZ', 'FLOOR', 'FIRST_VALUE', 'FIRST', 'EXTRACTVALUE', 'EXTRACT',
+ 'EXP', 'EXISTSNODE', 'EMPTY_CLOB', 'EMPTY_BLOB', 'DUMP', 'DEREF',
+ 'DEPTH', 'DENSE_RANK', 'DECOMPOSE', 'DECODE', 'DBTIMEZONE',
+ 'CURRENT_TIMESTAMP', 'CURRENT_DATE', 'CUME_DIST', 'COVAR_SAMP',
+ 'COVAR_POP', 'COUNT', 'COSH', 'COS', 'CORR', 'CONVERT', 'CONCAT',
+ 'COMPOSE', 'COALESCE', 'CHR', 'CHARTOROWID', 'CEIL', 'CAST', 'BITAND',
+ 'BIN_TO_NUM', 'BFILENAME', 'AVG', 'ATAN2', 'ATAN', 'ASIN', 'ASCIISTR',
+ 'ASCII', 'ADD_MONTHS', 'ACOS', 'ABS'),
+ //PL/SQL packages (http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96612/intro2.htm#1025672)
+ 3 => array('UTL_URL', 'UTL_TCP', 'UTL_SMTP', 'UTL_REF', 'UTL_RAW',
+ 'UTL_PG', 'UTL_INADDR', 'UTL_HTTP', 'UTL_FILE', 'UTL_ENCODE',
+ 'UTL_COLL', 'SDO_UTIL', 'SDO_TUNE', 'SDO_MIGRATE', 'SDO_LRS',
+ 'SDO_GEOM', 'SDO_CS', 'DMBS_XMLQUERY', 'DMBS_FLASHBACK',
+ 'DMBS_DEFER_SYS', 'DEBUG_EXTPROC', 'DBMS_XSLPROCESSOR', 'DBMS_XPLAN',
+ 'DBMS_XMLSCHEMA', 'DBMS_XMLSAVE', 'DBMS_XMLPARSER', 'DBMS_XMLGEN',
+ 'DBMS_XMLDOM', 'DBMS_XDBT', 'DBMS_XDB_VERSION', 'DBMS_XDB', 'DBMS_WM',
+ 'DBMS_UTILITY', 'DBMS_TYPES', 'DBMS_TTS', 'DBMS_TRANSFORM',
+ 'DBMS_TRANSACTION', 'DBMS_TRACE', 'DBMS_STRM_A', 'DBMS_STRM',
+ 'DBMS_STORAGE_MAP', 'DBMS_STATS', 'DBMS_SQL', 'DBMS_SPACE_ADMIN',
+ 'DBMS_SPACE', 'DBMS_SHARED_POOL', 'DBMS_SESSION', 'DBMS_RULE_ADM',
+ 'DBMS_RULE', 'DBMS_ROWID', 'DBMS_RLS', 'DBMS_RESUMABLE',
+ 'DBMS_RESOURCE_MANAGER_PRIVS', 'DBMS_RESOURCE_MANAGER', 'DBMS_REPUTIL',
+ 'DBMS_REPCAT_RGT', 'DBMS_REPCAT_INSTATIATE', 'DBMS_REPCAT_ADMIN',
+ 'DBMS_REPCAT', 'DBMS_REPAIR', 'DBMS_REFRESH', 'DBMS_REDEFINITION',
+ 'DBMS_RECTIFIER_DIFF', 'DBMS_RANDOM', 'DBMS_PROPAGATION_ADM',
+ 'DBMS_PROFILER', 'DBMS_PIPE', 'DBMS_PCLXUTIL', 'DBMS_OUTPUT',
+ 'DBMS_OUTLN_EDIT', 'DBMS_OUTLN', 'DBMS_ORACLE_TRACE_USER',
+ 'DBMS_ORACLE_TRACE_AGENT', 'DBMS_OLAP', 'DBMS_OFFLINE_SNAPSHOT',
+ 'DBMS_OFFLINE_OG', 'DBMS_ODCI', 'DBMS_OBFUSCATION_TOOLKIT',
+ 'DBMS_MVIEW', 'DBMS_MGWMSG', 'DBMS_MGWADM', 'DBMS_METADATA',
+ 'DBMS_LOGSTDBY', 'DBMS_LOGMNR_D', 'DBMS_LOGMNR_CDC_SUBSCRIBE',
+ 'DBMS_LOGMNR_CDC_PUBLISH', 'DBMS_LOGMNR', 'DBMS_LOCK', 'DBMS_LOB',
+ 'DBMS_LIBCACHE', 'DBMS_LDAP', 'DBMS_JOB', 'DBMS_IOT',
+ 'DBMS_HS_PASSTHROUGH', 'DBMS_FGA', 'DBMS_DISTRIBUTED_TRUST_ADMIN',
+ 'DBMS_DESCRIBE', 'DBMS_DEFER_QUERY', 'DBMS_DEFER', 'DBMS_DEBUG',
+ 'DBMS_DDL', 'DBMS_CAPTURE_ADM', 'DBMS_AW', 'DBMS_AQELM', 'DBMS_AQADM',
+ 'DBMS_AQ', 'DBMS_APPLY_ADM', 'DBMS_APPLICATION_INFO', 'DBMS_ALERT',
+ 'CWM2_OLAP_AW_ACCESS'),
+ //PL/SQL predefined exceptions (http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/07_errs.htm#784)
+ 4 => array('ZERO_DIVIDE', 'VALUE_ERROR', 'TOO_MANY_ROWS',
+ 'TIMEOUT_ON_RESOURCE', 'SYS_INVALID_ROWID', 'SUBSCRIPT_OUTSIDE_LIMIT',
+ 'SUBSCRIPT_BEYOND_COUNT', 'STORAGE_ERROR', 'SELF_IS_NULL',
+ 'ROWTYPE_MISMATCH', 'PROGRAM_ERROR', 'NOT_LOGGED_ON', 'NO_DATA_FOUND',
+ 'LOGIN_DENIED', 'INVALID_NUMBER', 'INVALID_CURSOR', 'DUP_VAL_ON_INDEX',
+ 'CURSOR_ALREADY_OPEN', 'COLLECTION_IS_NULL', 'CASE_NOT_FOUND',
+ 'ACCESS_INTO_NULL'),
+ //Static data dictionary views (http://download-uk.oracle.com/docs/cd/B10501_01/server.920/a96536/ch2.htm)
+ 5 => array('USER_REPSITES', 'USER_REPSCHEMA',
+ 'USER_REPRESOLUTION_STATISTICS', 'USER_REPRESOLUTION_METHOD',
+ 'USER_REPRESOLUTION', 'USER_REPRESOL_STATS_CONTROL', 'USER_REPPROP',
+ 'USER_REPPRIORITY_GROUP', 'USER_REPPRIORITY',
+ 'USER_REPPARAMETER_COLUMN', 'USER_REPOBJECT', 'USER_REPKEY_COLUMNS',
+ 'USER_REPGROUPED_COLUMN', 'USER_REPGROUP_PRIVILEGES', 'USER_REPGROUP',
+ 'USER_REPGENOBJECTS', 'USER_REPGENERATED', 'USER_REPFLAVORS',
+ 'USER_REPFLAVOR_OBJECTS', 'USER_REPFLAVOR_COLUMNS', 'USER_REPDDL',
+ 'USER_REPCONFLICT', 'USER_REPCOLUMN_GROUP', 'USER_REPCOLUMN',
+ 'USER_REPCATLOG', 'USER_REPCAT_USER_PARM_VALUES',
+ 'USER_REPCAT_USER_AUTHORIZATIONS', 'USER_REPCAT_TEMPLATE_SITES',
+ 'USER_REPCAT_TEMPLATE_PARMS', 'USER_REPCAT_TEMPLATE_OBJECTS',
+ 'USER_REPCAT_REFRESH_TEMPLATES', 'USER_REPCAT', 'USER_REPAUDIT_COLUMN',
+ 'USER_REPAUDIT_ATTRIBUTE', 'DBA_REPSITES_NEW', 'DBA_REPSITES',
+ 'DBA_REPSCHEMA', 'DBA_REPRESOLUTION_STATISTICS',
+ 'DBA_REPRESOLUTION_METHOD', 'DBA_REPRESOLUTION',
+ 'DBA_REPRESOL_STATS_CONTROL', 'DBA_REPPROP', 'DBA_REPPRIORITY_GROUP',
+ 'DBA_REPPRIORITY', 'DBA_REPPARAMETER_COLUMN', 'DBA_REPOBJECT',
+ 'DBA_REPKEY_COLUMNS', 'DBA_REPGROUPED_COLUMN',
+ 'DBA_REPGROUP_PRIVILEGES', 'DBA_REPGROUP', 'DBA_REPGENOBJECTS',
+ 'DBA_REPGENERATED', 'DBA_REPFLAVORS', 'DBA_REPFLAVOR_OBJECTS',
+ 'DBA_REPFLAVOR_COLUMNS', 'DBA_REPEXTENSIONS', 'DBA_REPDDL',
+ 'DBA_REPCONFLICT', 'DBA_REPCOLUMN_GROUP', 'DBA_REPCOLUMN',
+ 'DBA_REPCATLOG', 'DBA_REPCAT_USER_PARM_VALUES',
+ 'DBA_REPCAT_USER_AUTHORIZATIONS', 'DBA_REPCAT_TEMPLATE_SITES',
+ 'DBA_REPCAT_TEMPLATE_PARMS', 'DBA_REPCAT_TEMPLATE_OBJECTS',
+ 'DBA_REPCAT_REFRESH_TEMPLATES', 'DBA_REPCAT_EXCEPTIONS', 'DBA_REPCAT',
+ 'DBA_REPAUDIT_COLUMN', 'DBA_REPAUDIT_ATTRIBUTE', 'ALL_REPSITES',
+ 'ALL_REPSCHEMA', 'ALL_REPRESOLUTION_STATISTICS',
+ 'ALL_REPRESOLUTION_METHOD', 'ALL_REPRESOLUTION',
+ 'ALL_REPRESOL_STATS_CONTROL', 'ALL_REPPROP', 'ALL_REPPRIORITY_GROUP',
+ 'ALL_REPPRIORITY', 'ALL_REPPARAMETER_COLUMN', 'ALL_REPOBJECT',
+ 'ALL_REPKEY_COLUMNS', 'ALL_REPGROUPED_COLUMN',
+ 'ALL_REPGROUP_PRIVILEGES', 'ALL_REPGROUP', 'ALL_REPGENOBJECTS',
+ 'ALL_REPGENERATED', 'ALL_REPFLAVORS', 'ALL_REPFLAVOR_OBJECTS',
+ 'ALL_REPFLAVOR_COLUMNS', 'ALL_REPDDL', 'ALL_REPCONFLICT',
+ 'ALL_REPCOLUMN_GROUP', 'ALL_REPCOLUMN', 'ALL_REPCATLOG',
+ 'ALL_REPCAT_USER_PARM_VALUES', 'ALL_REPCAT_USER_AUTHORIZATIONS',
+ 'ALL_REPCAT_TEMPLATE_SITES', 'ALL_REPCAT_TEMPLATE_PARMS',
+ 'ALL_REPCAT_TEMPLATE_OBJECTS', 'ALL_REPCAT_REFRESH_TEMPLATES',
+ 'ALL_REPCAT', 'ALL_REPAUDIT_COLUMN', 'ALL_REPAUDIT_ATTRIBUTE')
+ ),
+ 'SYMBOLS' => array(
+ //PL/SQL delimiters (http://download-uk.oracle.com/docs/cd/B10501_01/appdev.920/a96624/02_funds.htm#2732)
+ '+', '%', "'", '.', '/', '(', ')', ':', ',', '*', '"', '=', '<', '>', '@', ';', '-', ':=', '=>', '||', '**', '<<', '>>', '/*', '*/', '..', '<>', '!=', '~=', '^=', '<=', '>='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00F;',
+ 2 => 'color: #000;',
+ 3 => 'color: #00F;',
+ 4 => 'color: #F00;',
+ 5 => 'color: #800;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #080; font-style: italic;',
+ 'MULTI' => 'color: #080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #00F;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #F00;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #800;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #0F0;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #00F;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => 'color: #0F0;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.oracle.com/pls/db92/db92.drilldown?word={FNAMEU}',
+ 2 => 'http://www.oracle.com/pls/db92/db92.drilldown?word={FNAMEU}',
+ 3 => 'http://www.oracle.com/pls/db92/db92.drilldown?word={FNAMEU}',
+ 4 => 'http://www.oracle.com/pls/db92/db92.drilldown?word={FNAMEU}',
+ 5 => 'http://www.oracle.com/pls/db92/db92.drilldown?word={FNAMEU}'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/postgresql.php b/platform/www/vendor/geshi/geshi/src/geshi/postgresql.php
new file mode 100644
index 0000000..5a666c8
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/postgresql.php
@@ -0,0 +1,285 @@
+<?php
+/*************************************************************************************
+ * postgresql.php
+ * -----------
+ * Author: Christophe Chauvet (christophe_at_kryskool_dot_org)
+ * Contributors: Leif Biberg Kristensen <leif_at_solumslekt_dot_org> 2010-05-03
+ * Copyright: (c) 2007 Christophe Chauvet (http://kryskool.org/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/07/20
+ *
+ * PostgreSQL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2007/07/20 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2007/07/20)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'PostgreSQL',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"', '`'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ //Put PostgreSQL reserved keywords here. I like mine uppercase.
+ 1 => array(
+ 'ABORT','ABSOLUTE','ACCESS','ACTION','ADD','ADMIN','AFTER',
+ 'AGGREGATE','ALL','ALSO','ALTER','ALWAYS','ANALYSE','ANALYZE','AND',
+ 'ANY','AS','ASC,','ASSERTION','ASSIGNMENT','ASYMMETRIC','AT',
+ 'AUTHORIZATION','BACKWARD','BEFORE','BEGIN','BETWEEN','BOTH','BY',
+ 'CACHE','CALLED','CASCADE','CASCADED','CASE','CAST','CATALOG',
+ 'CHAIN','CHARACTERISTICS','CHECK','CHECKPOINT','CLASS','CLOSE',
+ 'CLUSTER','COALESCE','COLLATE','COLUMN','COMMENT','COMMIT',
+ 'COMMITTED','CONCURRENTLY','CONFIGURATION','CONNECTION',
+ 'CONSTRAINT','CONSTRAINTS','CONTENT','CONTINUE','CONVERSION','COPY',
+ 'COST','CREATE','CREATEDB','CREATEROLE','CREATEUSER','CROSS','CSV',
+ 'CURRENT','CURRENT_CATALOG','CURRENT_DATE','CURRENT_ROLE',
+ 'CURRENT_SCHEMA','CURRENT_TIME','CURRENT_TIMESTAMP','CURRENT_USER',
+ 'CURSOR','CYCLE','DATA','DATABASE','DAY','DEALLOCATE','DEC',
+ 'DECLARE','DEFAULT','DEFAULTS','DEFERRABLE','DEFERRED','DEFINER',
+ 'DELETE','DELIMITER','DELIMITERS','DESC','DICTIONARY','DISABLE',
+ 'DISCARD','DISTINCT','DO','DOCUMENT','DOMAIN','DOUBLE','DROP',
+ 'EACH','ELSE','ENABLE','ENCODING','ENCRYPTED','END','ESCAPE',
+ 'EXCEPT','EXCLUDING','EXCLUSIVE','EXECUTE','EXISTS','EXPLAIN',
+ 'EXTERNAL','EXTRACT','FALSE','FAMILY','FETCH','FIRST','FOLLOWING',
+ 'FOR','FORCE','FOREIGN','FORWARD','FREEZE','FROM','FULL','FUNCTION',
+ 'GLOBAL','GRANT','GRANTED','GREATEST','GROUP','HANDLER','HAVING',
+ 'HEADER','HOLD','HOUR','IDENTITY','IF','ILIKE','IMMEDIATE',
+ 'IMMUTABLE','IMPLICIT','IN','INCLUDING','INCREMENT','INDEX',
+ 'INDEXES','INHERIT','INHERITS','INITIALLY','INNER','INOUT','INPUT',
+ 'INSENSITIVE','INSERT','INSTEAD','INTERSECT','INTO','INVOKER','IS',
+ 'ISNULL','ISOLATION','JOIN','KEY','LANCOMPILER','LANGUAGE','LARGE',
+ 'LAST','LC_COLLATE','LC_CTYPE','LEADING','LEAST','LEFT','LEVEL',
+ 'LIKE','LIMIT','LISTEN','LOAD','LOCAL','LOCALTIME','LOCALTIMESTAMP',
+ 'LOCATION','LOCK','LOGIN','LOOP','MAPPING','MATCH','MAXVALUE',
+ 'MINUTE','MINVALUE','MODE','MONTH','MOVE','NAME','NAMES','NATIONAL',
+ 'NATURAL','NEW','NEXT','NO','NOCREATEDB','NOCREATEROLE',
+ 'NOCREATEUSER','NOINHERIT','NOLOGIN','NONE','NOSUPERUSER','NOT',
+ 'NOTHING','NOTIFY','NOTNULL','NOWAIT','NULL','NULLIF','NULLS',
+ 'NUMERIC','OBJECT','OF','OFF','OFFSET','OIDS','OLD','ON','ONLY',
+ 'OPERATOR','OPTION','OPTIONS','OR','ORDER','OUT','OUTER','OVER',
+ 'OVERLAPS','OVERLAY','OWNED','OWNER','PARSER','PARTIAL','PARTITION',
+ 'PASSWORD','PLACING','PLANS','POSITION','PRECEDING','PRECISION',
+ 'PREPARE','PREPARED','PRESERVE','PRIMARY','PRIOR','PRIVILEGES',
+ 'PROCEDURAL','PROCEDURE','QUOTE','RANGE','READ','REASSIGN',
+ 'RECHECK','RECURSIVE','REFERENCES','REINDEX','RELATIVE','RELEASE',
+ 'RENAME','REPEATABLE','REPLACE','REPLICA','RESET','RESTART',
+ 'RESTRICT','RETURN','RETURNING','RETURNS','REVOKE','RIGHT','ROLE',
+ 'ROLLBACK','ROW','ROWS','RULE','SAVEPOINT','SCHEMA','SCROLL',
+ 'SEARCH','SECOND',
+ 'SECURITY','SELECT','SEQUENCE','SERIALIZABLE','SERVER','SESSION',
+ 'SESSION_USER','SET','SETOF','SHARE','SHOW','SIMILAR','SIMPLE',
+ 'SOME','STABLE','STANDALONE','START','STATEMENT','STATISTICS',
+ 'STDIN','STDOUT','STORAGE','STRICT','STRIP','SUPERUSER',
+ 'SYMMETRIC','SYSID','SYSTEM','TABLE','TABLESPACE','TEMP','TEMPLATE',
+ 'TEMPORARY','THEN','TO','TRAILING','TRANSACTION','TREAT','TRIGGER',
+ 'TRUE','TRUNCATE','TRUSTED','TYPE','UNBOUNDED','UNCOMMITTED',
+ 'UNENCRYPTED','UNION','UNIQUE','UNKNOWN','UNLISTEN','UNTIL',
+ 'UPDATE','USER','USING','VACUUM','VALID','VALIDATOR','VALUE',
+ 'VALUES','VARIADIC','VERBOSE','VERSION','VIEW','VOLATILE','WHEN',
+ 'WHERE','WHILE','WHITESPACE','WINDOW','WITH','WITHOUT','WORK','WRAPPER',
+ 'WRITE','XMLATTRIBUTES','XMLCONCAT','XMLELEMENT','XMLFOREST',
+ 'XMLPARSE','XMLPI','XMLROOT','XMLSERIALIZE','YEAR','YES','ZONE'
+ ),
+
+ //Put functions here
+ 3 => array(
+ // mathematical functions
+ 'ABS','CBRT','CEIL','CEILING','DEGREES','DIV','EXP','FLOOR','LN',
+ 'LOG','MOD','PI','POWER','RADIANS','RANDOM','ROUND','SETSEED',
+ 'SIGN','SQRT','TRUNC','WIDTH_BUCKET',
+ // trigonometric functions
+ 'ACOS','ASIN','ATAN','ATAN2','COS','COT','SIN','TAN',
+ // string functions
+ 'BIT_LENGTH','CHAR_LENGTH','CHARACTER_LENGTH','LOWER',
+ 'OCTET_LENGTH','POSITION','SUBSTRING','TRIM','UPPER',
+ // other string functions
+ 'ASCII','BTRIM','CHR','CONVERT','CONVERT_FROM','CONVERT_TO',
+ 'DECODE','ENCODE','INITCAP','LENGTH','LPAD','LTRIM','MD5',
+ 'PG_CLIENT_ENCODING','QUOTE_IDENT','QUOTE_LITERAL','QUOTE_NULLABLE',
+ 'REGEXP_MATCHES','REGEXP_REPLACE','REGEXP_SPLIT_TO_ARRAY',
+ 'REGEXP_SPLIT_TO_TABLE','REPEAT','RPAD','RTRIM','SPLIT_PART',
+ 'STRPOS','SUBSTR','TO_ASCII','TO_HEX','TRANSLATE',
+ // binary string functions
+ 'GET_BIT','GET_BYTE','SET_BIT','SET_BYTE',
+ // data type formatting functions
+ 'TO_CHAR','TO_DATE','TO_NUMBER','TO_TIMESTAMP',
+ // date/time functions
+ 'AGE','CLOCK_TIMESTAMP','DATE_PART','DATE_TRUNC','EXTRACT',
+ 'ISFINITE','JUSTIFY_DAYS','JUSTIFY_HOURS','JUSTIFY_INTERVAL','NOW',
+ 'STATEMENT_TIMESTAMP','TIMEOFDAY','TRANSACTION_TIMESTAMP',
+ // enum support functions
+ 'ENUM_FIRST','ENUM_LAST','ENUM_RANGE',
+ // geometric functions
+ 'AREA','CENTER','DIAMETER','HEIGHT','ISCLOSED','ISOPEN','NPOINTS',
+ 'PCLOSE','POPEN','RADIUS','WIDTH',
+ 'BOX','CIRCLE','LSEG','PATH','POINT','POLYGON',
+ // cidr and inet functions
+ 'ABBREV','BROADCAST','FAMILY','HOST','HOSTMASK','MASKLEN','NETMASK',
+ 'NETWORK','SET_MASKLEN',
+ // text search functions
+ 'TO_TSVECTOR','SETWEIGHT','STRIP','TO_TSQUERY','PLAINTO_TSQUERY',
+ 'NUMNODE','QUERYTREE','TS_RANK','TS_RANK_CD','TS_HEADLINE',
+ 'TS_REWRITE','GET_CURRENT_TS_CONFIG','TSVECTOR_UPDATE_TRIGGER',
+ 'TSVECTOR_UPDATE_TRIGGER_COLUMN',
+ 'TS_DEBUG','TS_LEXISE','TS_PARSE','TS_TOKEN_TYPE','TS_STAT',
+ // XML functions
+ 'XMLCOMMENT','XMLCONCAT','XMLELEMENT','XMLFOREST','XMLPI','XMLROOT',
+ 'XMLAGG','XPATH','TABLE_TO_XMLSCHEMA','QUERY_TO_XMLSCHEMA',
+ 'CURSOR_TO_XMLSCHEMA','TABLE_TO_XML_AND_XMLSCHEMA',
+ 'QUERY_TO_XML_AND_XMLSCHEMA','SCHEMA_TO_XML','SCHEMA_TO_XMLSCHEMA',
+ 'SCHEMA_TO_XML_AND_XMLSCHEMA','DATABASE_TO_XML',
+ 'DATABASE_TO_XMLSCHEMA','DATABASE_TO_XML_AND_XMLSCHEMA',
+ // sequence manipulating functions
+ 'CURRVAL','LASTVAL','NEXTVAL','SETVAL',
+ // conditional expressions
+ 'COALESCE','NULLIF','GREATEST','LEAST',
+ // array functions
+ 'ARRAY_APPEND','ARRAY_CAT','ARRAY_NDIMS','ARRAY_DIMS','ARRAY_FILL',
+ 'ARRAY_LENGTH','ARRAY_LOWER','ARRAY_PREPEND','ARRAY_TO_STRING',
+ 'ARRAY_UPPER','STRING_TO_ARRAY','UNNEST',
+ // aggregate functions
+ 'ARRAY_AGG','AVG','BIT_AND','BIT_OR','BOOL_AND','BOOL_OR','COUNT',
+ 'EVERY','MAX','MIN','STRING_AGG','SUM',
+ // statistic aggregate functions
+ 'CORR','COVAR_POP','COVAR_SAMP','REGR_AVGX','REGR_AVGY',
+ 'REGR_COUNT','REGR_INTERCEPT','REGR_R2','REGR_SLOPE','REGR_SXX',
+ 'REGR_SXY','REGR_SYY','STDDEV','STDDEV_POP','STDDEV_SAMP',
+ 'VARIANCE','VAR_POP','VAR_SAMP',
+ // window functions
+ 'ROW_NUMBER','RANK','DENSE_RANK','PERCENT_RANK','CUME_DIST','NTILE',
+ 'LAG','LEAD','FIRST_VALUE','LAST_VALUE','NTH_VALUE',
+ // set returning functions
+ 'GENERATE_SERIES','GENERATE_SUBSCRIPTS'
+ // system information functions not currently included
+ ),
+
+ //Put your postgresql var
+ 4 => array(
+ 'client_encoding',
+ 'standard_conforming_strings'
+ ),
+
+ //Put your data types here
+ 5 => array(
+ 'ARRAY','ABSTIME','BIGINT','BIGSERIAL','BINARY','BIT','BIT VARYING',
+ 'BOOLEAN','BOX','BYTEA','CHAR','CHARACTER','CHARACTER VARYING',
+ 'CIDR','CIRCLE','DATE','DECIMAL','DOUBLE PRECISION','ENUM','FLOAT',
+ 'INET','INT','INTEGER','INTERVAL','NCHAR','REAL','SMALLINT','TEXT',
+ 'TIME','TIMESTAMP','VARCHAR','XML',
+ ),
+
+ // //Put your package names here
+ // 6 => array(
+ // ),
+
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '=', '<', '>', '|'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ // regular keywords
+ 1 => 'color: #000000; font-weight: bold; text-transform: uppercase;',
+ // inbuilt functions
+ 3 => 'color: #333399; font-weight: bold; text-transform: uppercase;',
+ // postgresql var(?)
+ 4 => 'color: #993333; font-weight: bold; text-transform: uppercase;',
+ // data types
+ 5 => 'color: #993333; font-weight: bold; text-transform: uppercase;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #ff0000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 3 => '',
+ 4 => 'http://paste.postgresql.fr/wiki/desc.php?def={FNAME}',
+ 5 => '',
+ ),
+
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'DISALLOWED_AFTER' => '(?![\(\w])'
+ ),
+
+ 3 => array(
+ 'DISALLOWED_AFTER' => '(?=\()'
+ ),
+
+ 4 => array(
+ 'DISALLOWED_AFTER' => '(?![\(\w])'
+ ),
+
+ 5 => array(
+ 'DISALLOWED_AFTER' => '(?![\(\w])'
+ ),
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/postscript.php b/platform/www/vendor/geshi/geshi/src/geshi/postscript.php
new file mode 100644
index 0000000..d29b8a7
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/postscript.php
@@ -0,0 +1,217 @@
+<?php
+/*************************************************************************************
+ * c.php
+ * -----
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2014 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2014/08/10
+ *
+ * PostScript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2014/08/10 (1.0.8.13)
+ * - First Release
+ *
+ * TODO (updated 2014/08/10)
+ * -------------------------
+ * - Get a list of inbuilt functions to add
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'PostScript',
+ 'COMMENT_SINGLE' => array(0 => '%'),
+ 'COMMENT_MULTI' => array(), //array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ // Strings
+ 1 => "/\((?:\\\\[0-7]{3}|\\\\.|(?R)|[^)])*\)/s",
+ // Hex Strings
+ 2 => "/<(?!<)[0-9a-f\s]*>/si",
+ // ASCII-85 Strings
+ 3 => "/<~.*~>/si",
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ ),
+ 'NUMBERS' => array(
+ 0 => GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_FLT_NONSCI | GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 1 => "\d+#[0-9a-zA-Z]+"
+ ),
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'countexecstack', 'def', 'dup', 'exch', 'exec', 'execstack', 'exit',
+ 'for', 'if', 'ifelse', 'loop', 'pop', 'repeat',
+
+ 'abs', 'add', 'atan', 'ceiling', 'cos', 'div', 'exp', 'floor',
+ 'idiv', 'ln', 'log', 'mul', 'mod', 'neg', 'rand', 'round', 'rrand',
+ 'sin', 'sqrt', 'srand', 'sub', 'truncate',
+
+ 'and', 'bitshift', 'eq', 'ge', 'gt', 'le', 'lt', 'ne', 'not', 'or', 'xor',
+ ),
+ 2 => array(
+ 'false', 'null', 'true', 'version'
+ ),
+ 3 => array(
+ 'quit', 'start', 'stop', 'stopped',
+
+ 'clear', 'cleartomark', 'copy', 'count', 'counttomark', 'index', 'roll',
+
+ 'aload', 'astore', 'begin', 'countdictstack', 'currentdict',
+ 'dictstack', 'end', 'errordict', 'forall', 'get',
+ 'getinterval', 'known', 'length', 'load', 'maxlength', 'put',
+ 'putinterval', 'store', 'systemdict', 'userdict', 'where',
+
+ 'anchorsearch', 'search', 'token',
+
+ 'cvi', 'cvlit', 'cvn', 'cvr', 'cvrs', 'cvs', 'cvx', 'executeonly',
+ 'noaccess', 'rcheck', 'readonly', 'type', 'wcheck', 'xcheck',
+
+ 'bytesavailable', 'closefile', 'currentfile', 'echo', 'file',
+ 'flush', 'flushfile', 'print', 'prompt', 'pstack', 'read',
+ 'readhexstring', 'readline', 'readstring', 'resetfile', 'restore',
+ 'run', 'save', 'stack', 'status', 'vmstatus', 'write',
+ 'writehexstring', 'writestring',
+
+ 'bind', 'usertime',
+
+ 'currentdash', 'currentflat', 'currentgray', 'currenthsbcolor',
+ 'currentlinecap', 'currentlinejoin', 'currentlinewidth',
+ 'currentmiterlimit', 'currentrgbcolor', 'currentscreen',
+ 'currenttransfer', 'grestore', 'grestoreall', 'gsave',
+ 'initgraphics', 'proc', 'setdash', 'setflat', 'setgray',
+ 'sethsbcolor', 'setlinecap', 'setlinejoin', 'setlinewidth',
+ 'setmiterlimit', 'setrgbcolor', 'setscreen', 'settransfer',
+
+ 'concat', 'concatmatrix', 'currentmatrix', 'defaultmatrix',
+ 'dtransform', 'identmatrix', 'idtransform', 'initmatrix',
+ 'invertmatrix', 'itransform', 'rotate', 'scale', 'setmatrix',
+ 'transform', 'translate',
+
+ 'arc', 'arcn', 'arcto', 'charpath', 'clip', 'clippath', 'closepath',
+ 'currentpoint', 'curveto', 'eoclip', 'eofill', 'erasepage', 'fill',
+ 'flattenpath', 'image', 'imagemask', 'initclip', 'lineto', 'moveto',
+ 'newpath', 'pathbbox', 'pathforall', 'rcurveto', 'reversepath',
+ 'rlineto', 'rmoveto', 'stroke', 'strokepath',
+
+ 'banddevice', 'copypage', 'framedevice', 'nulldevice', 'renderbands',
+ 'showpage',
+
+ 'ashow', 'awidthshow', 'currentfont', 'definefont', 'findfont',
+ 'fontdict', 'kshow', 'makefont', 'scalefont', 'setfont', 'show',
+ 'stringwidth', 'widthshow', 'FontDirectory', 'StandardEncoding',
+
+ 'cachestatus', 'setcachedevice', 'setcachelimit', 'setcharwidth',
+
+ 'dictfull', 'dictstackoverflow', 'dictstackunderflow',
+ 'execstackoverflow', 'handleerror', 'interrupt', 'invalidaccess',
+ 'invalidexit', 'invalidfileaccess', 'invalidfont', 'invalidrestore',
+ 'ioerror', 'limitcheck', 'nocurrentpoint', 'rangecheck',
+ 'stackoverflow', 'stackunderflow', 'syntaxerror', 'timeout',
+ 'typecheck', 'undefined', 'undefinedfilename', 'undefinedresult',
+ 'unmatchedmark', 'unregistered', 'VMerror'
+ ),
+ 4 => array(
+ 'array', 'dict', 'mark', 'matrix', 'string'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('==', '=', '/', '//'),
+ 1 => array('[', ']'),
+ 2 => array('{', '}'),
+ 3 => array('<<', '>>')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000066; font-weight: bold;',
+ 2 => 'color: #0000ff; font-weight: bold;',
+ 3 => 'color: #000000; font-weight: bold;',
+ 4 => 'color: #993333; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #333333; font-style: italic;',
+ 1 => 'color: #339933;',
+ 2 => 'color: #006600;',
+ 3 => 'color: #666666;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 'HARD' => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;',
+ 1 => 'color: #009900;',
+ 2 => 'color: #009900;',
+ 3 => 'color: #009900;'
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 1 => "#(?<=\\x2F)[\\w-]+#"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/povray.php b/platform/www/vendor/geshi/geshi/src/geshi/povray.php
new file mode 100644
index 0000000..e71efd7
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/povray.php
@@ -0,0 +1,198 @@
+<?php
+/*************************************************************************************
+ * povray.php
+ * --------
+ * Author: Carl Fürstenberg (azatoth@gmail.com)
+ * Copyright: © 2007 Carl Fürstenberg
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/07/11
+ *
+ * Povray language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/11 (1.0.8)
+ * - initial import to GeSHi SVN
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'POVRAY',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'yes', 'wrinkles', 'wood', 'width', 'waves', 'water_level', 'warp', 'vturbulence',
+ 'vstr', 'vrotate', 'vnormalize', 'vlength', 'vcross', 'vaxis_rotate', 'variance', 'v_steps',
+ 'uv_mapping', 'utf8', 'use_index', 'use_colour', 'use_color', 'use_alpha', 'up', 'undef',
+ 'ultra_wide_angle', 'u_steps', 'type', 'turbulence', 'turb_depth', 'ttf', 'true', 'triangle_wave',
+ 'translate', 'transform', 'trace', 'toroidal', 'tolerance', 'tiles', 'tile2', 'tightness',
+ 'tiff', 'threshold', 'thickness', 'tga', 'texture_map', 'target', 'sys', 'sum',
+ 'substr', 'sturm', 'strupr', 'strlwr', 'strength', 'str', 'statistics', 'sqr',
+ 'spotted', 'spotlight', 'split_union', 'spline', 'spiral2', 'spiral1', 'spherical', 'specular',
+ 'spacing', 'solid', 'smooth', 'slope', 'slice', 'sky', 'size', 'sine_wave',
+ 'shadowless', 'scattering', 'scallop_wave', 'scale', 'save_file', 'samples', 'roughness', 'rotate',
+ 'ripples', 'right', 'rgbt', 'rgbft', 'rgbf', 'rgb', 'repeat', 'render',
+ 'refraction', 'reflection_exponent', 'recursion_limit', 'reciprocal', 'ratio', 'ramp_wave', 'radius', 'radial',
+ 'quilted', 'quick_colour', 'quick_color', 'quaternion', 'quadratic_spline', 'pwr', 'projected_through', 'prod',
+ 'pretrace_start', 'pretrace_end', 'precompute', 'precision', 'ppm', 'pow', 'pot', 'poly_wave',
+ 'point_at', 'png', 'planar', 'pigment_pattern', 'pi', 'phong_size', 'phong', 'phase',
+ 'pgm', 'perspective', 'pattern', 'pass_through', 'parallel', 'panoramic', 'orthographic', 'orientation',
+ 'orient', 'open', 'onion', 'once', 'on', 'omnimax', 'omega', 'offset',
+ 'off', 'octaves', 'number_of_waves', 'noise_generator', 'no_shadow', 'no_reflection', 'no_image', 'no_bump_scale',
+ 'no', 'nearest_count', 'natural_spline', 'mortar', 'minimum_reuse', 'min_extent', 'metric', 'method',
+ 'metallic', 'media_interaction', 'media_attenuation', 'media', 'max_trace_level', 'max_trace', 'max_sample', 'max_iteration',
+ 'max_intersections', 'max_gradient', 'max_extent', 'matrix', 'material_map', 'marble', 'map_type', 'mandel',
+ 'major_radius', 'magnet', 'low_error_factor', 'look_at', 'location', 'load_file', 'linear_sweep', 'linear_spline',
+ 'leopard', 'lambda', 'julia', 'jpeg', 'jitter', 'irid_wavelength', 'ior', 'inverse',
+ 'intervals', 'interpolate', 'internal', 'inside_vector', 'inside', 'initial_frame', 'initial_clock', 'image_width',
+ 'image_pattern', 'image_height', 'iff', 'hypercomplex', 'hollow', 'hierarchy', 'hf_gray_16', 'hexagon',
+ 'gray_threshold', 'granite', 'gradient', 'global_lights', 'gif', 'gather', 'fresnel', 'frequency',
+ 'frame_number', 'form', 'fog_type', 'fog_offset', 'fog_alt', 'focal_point', 'flip', 'flatness',
+ 'fisheye', 'final_frame', 'final_clock', 'false', 'falloff_angle', 'falloff', 'fade_power', 'fade_distance',
+ 'fade_colour', 'fade_color', 'facets', 'extinction', 'exterior', 'exponent', 'expand_thresholds', 'evaluate',
+ 'error_bound', 'emission', 'eccentricity', 'double_illuminate', 'distance', 'dist_exp', 'dispersion_samples', 'dispersion',
+ 'direction', 'diffuse', 'df3', 'dents', 'density_map', 'density_file', 'density', 'cylindrical',
+ 'cutaway_textures', 'cubic_wave', 'cubic_spline', 'cube', 'crand', 'crackle', 'count', 'coords',
+ 'control1', 'control0', 'conserve_energy', 'conic_sweep', 'confidence', 'concat', 'composite', 'component',
+ 'colour_map', 'colour', 'color', 'collect', 'clock_on', 'clock_delta', 'clock', 'circular',
+ 'chr', 'checker', 'charset', 'cells', 'caustics', 'bumps', 'bump_size', 'brilliance',
+ 'brightness', 'brick_size', 'brick', 'bozo', 'boxed', 'blur_samples', 'black_hole', 'bezier_spline',
+ 'b_spline', 'average', 'autostop', 'assumed_gamma', 'ascii', 'array', 'area_light', 'arc_angle',
+ 'append', 'aperture', 'angle', 'ambient_light', 'ambient', 'always_sample', 'altitude', 'alpha',
+ 'all_intersections', 'all', 'agate_turb', 'agate', 'adc_bailout', 'adaptive', 'accuracy', 'absorption',
+ 'aa_threshold', 'aa_level', 'reflection'
+ ),
+ 2 => array(
+ 'abs', 'acos', 'acosh', 'asc', 'asin', 'asinh', 'atan', 'atanh',
+ 'atan2', 'ceil', 'cos', 'cosh', 'defined', 'degrees', 'dimensions', 'dimension_size',
+ 'div', 'exp', 'file_exists', 'floor', 'int', 'ln', 'log', 'max',
+ 'min', 'mod', 'pov', 'radians', 'rand', 'seed', 'select', 'sin',
+ 'sinh', 'sqrt', 'strcmp', 'strlen', 'tan', 'tanh', 'val', 'vdot',
+ 'vlenght',
+ ),
+ 3 => array (
+ 'x', 'y', 'z', 't', 'u', 'v', 'red', 'blue',
+ 'green', 'filter', 'transmit', 'gray', 'e',
+ ),
+ 4 => array (
+ 'camera', 'background', 'fog', 'sky_sphere', 'rainbow', 'global_settings', 'radiosity', 'photon',
+ 'object', 'blob', 'sphere', 'cylinder', 'box', 'cone', 'height_field', 'julia_fractal',
+ 'lathe', 'prism', 'sphere_sweep', 'superellipsoid', 'sor', 'text', 'torus', 'bicubic_patch',
+ 'disc', 'mesh', 'triangle', 'smooth_triangle', 'mesh2', 'vertex_vectors', 'normal_vectors', 'uv_vectors',
+ 'texture_list', 'face_indices', 'normal_indices', 'uv_indices', 'texture', 'polygon', 'plane', 'poly',
+ 'cubic', 'quartic', 'quadric', 'isosurface', 'function', 'contained_by', 'parametric', 'pigment',
+ 'union', 'intersection', 'difference', 'merge', 'light_source', 'looks_like', 'light_group', 'clipped_by',
+ 'bounded_by', 'interior', 'material', 'interior_texture', 'normal', 'finish', 'color_map', 'pigment_map',
+ 'image_map', 'bump_map', 'slope_map', 'normal_map', 'irid', 'photons',
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '!',
+ '@', '%', '&', '*', '|', '/', '<',
+ '>', '+', '-', '.', '=', '<=', '>=',
+ '!=',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #a63123;',
+ 2 => 'color: #2312bc;',
+ 3 => 'color: #cc1122; font-weight: bold;',
+ 4 => 'color: #116688; font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+// 2 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66aa;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #6666cc; font-weight: bold;',
+ 1 => 'color: #66cc66; font-weight: bold;',
+ 2 => 'color: #66cc66; font-weight: bold;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ # normal hash lines
+ 0 => '\#(?!(include|declare|local|fopen|fclose|read|write|default|version|if|else|end|ifdef|ifndef|switch|case|range|break|while|debug|error|warning|macro) )[[:word:]]*',
+ # syntax functions hash thingis
+ 1 => "\#(include|declare|local|fopen|fclose|read|write|default|version|if|else|end|ifdef|ifndef|switch|case|range|break|while|debug|error|warning|macro)",
+ 2 => array(
+ GESHI_SEARCH => "([a-zA-Z]+)(\n)(.*)(\n)(\\1;?)",
+ GESHI_REPLACE => '\3',
+ GESHI_BEFORE => '\1\2',
+ GESHI_AFTER => '\4\5',
+ GESHI_MODIFIERS => 'siU'
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/powerbuilder.php b/platform/www/vendor/geshi/geshi/src/geshi/powerbuilder.php
new file mode 100644
index 0000000..5e0cbc7
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/powerbuilder.php
@@ -0,0 +1,417 @@
+<?php
+/*************************************************************************************
+ * powerbuilder.php
+ * ------
+ * Author: Doug Porter (powerbuilder.geshi@gmail.com)
+ * Copyright: (c) 2009 Doug Porter
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/07/13
+ *
+ * PowerBuilder (PowerScript) language file for GeSHi.
+ *
+ * Based on the TextPad Syntax file for PowerBuilder
+ * built by Rafi Avital
+ *
+ * CHANGES
+ * -------
+ * 2009/07/13 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2009/07/13)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'PowerBuilder',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '~',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'alias', 'and', 'autoinstantiate', 'call',
+ 'case', 'catch', 'choose', 'close', 'commit', 'connect',
+ 'constant', 'continue', 'create', 'cursor', 'declare',
+ 'delete', 'describe', 'descriptor', 'destroy', 'disconnect',
+ 'do', 'dynamic', 'else', 'elseif', 'end', 'enumerated',
+ 'event', 'execute', 'exit', 'external', 'false', 'fetch',
+ 'first', 'for', 'forward', 'from', 'function', 'global',
+ 'goto', 'halt', 'if', 'immediate', 'indirect', 'insert',
+ 'into', 'intrinsic', 'is', 'last', 'library', 'loop', 'next',
+ 'not', 'of', 'on', 'open', 'or', 'parent', 'post', 'prepare',
+ 'prior', 'private', 'privateread', 'privatewrite', 'procedure',
+ 'protected', 'protectedread', 'protectedwrite', 'prototypes',
+ 'public', 'readonly', 'ref', 'return', 'rollback', 'rpcfunc',
+ 'select', 'selectblob', 'shared', 'static', 'step', 'subroutine',
+ 'super', 'system', 'systemread', 'systemwrite', 'then', 'this',
+ 'to', 'trigger', 'true', 'try', 'type', 'until', 'update', 'updateblob',
+ 'using', 'variables', 'where', 'while', 'with', 'within'
+ ),
+ 2 => array (
+ 'blob', 'boolean', 'char', 'character', 'date', 'datetime',
+ 'dec', 'decimal',
+ 'double', 'int', 'integer', 'long', 'real', 'string', 'time',
+ 'uint', 'ulong', 'unsignedint', 'unsignedinteger', 'unsignedlong'
+ ),
+ 3 => array (
+ 'abortretryignore!', 'actbegin!', 'acterror!', 'actesql!',
+ 'actgarbagecollect!', 'activate!', 'activatemanually!',
+ 'activateondoubleclick!',
+ 'activateongetfocus!', 'actline!', 'actobjectcreate!', 'actobjectdestroy!',
+ 'actprofile!', 'actroutine!', 'acttrace!', 'actual!',
+ 'actuser!', 'adoresultset!', 'adtdate!', 'adtdatetime!',
+ 'adtdefault!', 'adtdouble!', 'adttext!', 'adttime!',
+ 'aix!', 'alignatbottom!', 'alignatleft!', 'alignatright!',
+ 'alignattop!', 'all!', 'allowpartialchanges!', 'alpha!',
+ 'ansi!', 'any!', 'anycase!', 'anyfont!',
+ 'append!', 'application!', 'arabiccharset!', 'area3d!',
+ 'areagraph!', 'arraybounds!', 'arrow!', 'ascending!',
+ 'asstatement!', 'atbottom!', 'atleft!', 'atright!',
+ 'attop!', 'autosize!', 'background!', 'balticcharset!',
+ 'bar3dgraph!', 'bar3dobjgraph!', 'bargraph!', 'barstack3dobjgraph!',
+ 'barstackgraph!', 'bdiagonal!', 'beam!', 'begin!',
+ 'begindrag!', 'beginlabeledit!', 'beginrightdrag!', 'behind!',
+ 'blob!', 'bold!', 'boolean!', 'bottom!',
+ 'boundedarray!', 'box!', 'byreferenceargument!', 'byvalueargument!',
+ 'cancel!', 'cascade!', 'cascaded!', 'category!',
+ 'center!', 'character!', 'charsetansi!', 'charsetansiarabic!',
+ 'charsetansihebrew!', 'charsetdbcsjapanese!', 'charsetunicode!', 'checkbox!',
+ 'child!', 'childtreeitem!', 'chinesebig5!', 'classdefinition!',
+ 'classdefinitionobject!', 'classorstructuretype!', 'clicked!', 'clip!',
+ 'clipboard!', 'clipformatbitmap!', 'clipformatdib!', 'clipformatdif!',
+ 'clipformatenhmetafile!', 'clipformathdrop!', 'clipformatlocale!',
+ 'clipformatmetafilepict!',
+ 'clipformatoemtext!', 'clipformatpalette!', 'clipformatpendata!', 'clipformatriff!',
+ 'clipformatsylk!', 'clipformattext!', 'clipformattiff!', 'clipformatunicodetext!',
+ 'clipformatwave!', 'clock!', 'close!', 'closequery!',
+ 'col3dgraph!', 'col3dobjgraph!', 'colgraph!',
+ 'colstack3dobjgraph!', 'colstackgraph!', 'columnclick!', 'commandbutton!',
+ 'connection!', 'connectioninfo!', 'connectobject!', 'connectprivilege!',
+ 'connectwithadminprivilege!', 'constructor!', 'containsany!', 'containsembeddedonly!',
+ 'containslinkedonly!', 'contextinformation!', 'contextkeyword!', 'continuous!',
+ 'corbaobject!', 'corbaunion!', 'cplusplus!', 'cross!',
+ 'csv!', 'cumulative!', 'cumulativepercent!', 'currenttreeitem!',
+ 'customvisual!', 'dash!', 'dashdot!', 'dashdotdot!',
+ 'data!', 'datachange!', 'datamodified!', 'datastore!',
+ 'datawindow!', 'datawindowchild!', 'date!', 'datemask!',
+ 'datetime!', 'datetimemask!', 'dbase2!', 'dbase3!',
+ 'dberror!', 'deactivate!', 'decimal!', 'decimalmask!',
+ 'decorative!', 'default!', 'defaultcharset!', 'delete!',
+ 'deleteallitems!', 'deleteitem!', 'descending!', 'desktop!',
+ 'destructor!', 'detail!', 'diamond!', 'dif!',
+ 'dirall!', 'dirapplication!', 'dirdatawindow!', 'directionall!',
+ 'directiondown!', 'directionleft!', 'directionright!', 'directionup!',
+ 'dirfunction!', 'dirmenu!', 'dirpipeline!', 'dirproject!',
+ 'dirquery!', 'dirstructure!', 'diruserobject!', 'dirwindow!',
+ 'displayasactivexdocument!', 'displayascontent!', 'displayasicon!', 'dot!',
+ 'double!', 'doubleclicked!', 'dragdrop!', 'dragenter!',
+ 'dragleave!', 'dragobject!', 'dragwithin!', 'drawobject!',
+ 'dropdownlistbox!', 'dropdownpicturelistbox!', 'drophighlighttreeitem!', 'dwobject!',
+ 'dynamicdescriptionarea!', 'dynamicstagingarea!', 'easteuropecharset!', 'editchanged!',
+ 'editmask!', 'editmenu!', 'encodingansi!', 'encodingutf8!',
+ 'encodingutf16le!', 'encodingutf16be!', 'end!', 'endlabeledit!',
+ 'enterprise!', 'enterpriseonlyfeature!', 'enumeratedtype!', 'enumerationdefinition!',
+ 'enumerationitemdefinition!', 'environment!', 'error!', 'errorlogging!',
+ 'eventnotexisterror!', 'eventwrongprototypeerror!', 'excel!', 'excel5!',
+ 'exceptionfail!', 'exceptionignore!', 'exceptionretry!',
+ 'exceptionsubstitutereturnvalue!',
+ 'exclamation!', 'exclude!', 'exportapplication!', 'exportdatawindow!',
+ 'exportfunction!', 'exportmenu!', 'exportpipeline!', 'exportproject!',
+ 'exportquery!', 'exportstructure!', 'exportuserobject!', 'exportwindow!',
+ 'externalvisual!', 'extobject!', 'failonanyconflict!', 'fdiagonal!',
+ 'featurenotsupportederror!', 'filealreadyopenerror!', 'filecloseerror!',
+ 'fileexists!',
+ 'fileinvalidformaterror!', 'filemenu!', 'filenotopenerror!', 'filenotseterror!',
+ 'filereaderror!', 'filetyperichtext!', 'filetypetext!', 'filewriteerror!',
+ 'filter!', 'first!', 'firstvisibletreeitem!', 'fixed!',
+ 'floating!', 'focusrect!', 'footer!', 'foreground!',
+ 'frombeginning!', 'fromcurrent!', 'fromend!', 'functionobject!',
+ 'gb231charset!', 'getfocus!', 'graph!', 'graphicobject!',
+ 'graxis!', 'grdispattr!', 'greekcharset!', 'groupbox!',
+ 'hand!', 'hangeul!', 'header!', 'hebrewcharset!',
+ 'helpmenu!', 'hide!', 'horizontal!', 'hotlinkalarm!',
+ 'hourglass!', 'hppa!', 'hprogressbar!', 'hpux!',
+ 'hscrollbar!', 'hticksonboth!', 'hticksonbottom!', 'hticksonneither!',
+ 'hticksontop!', 'htmltable!', 'htrackbar!', 'i286!',
+ 'i386!', 'i486!', 'icon!', 'icons!',
+ 'idle!', 'importdatawindow!', 'indent!', 'index!',
+ 'inet!', 'information!', 'inplace!', 'inputfieldselected!',
+ 'insertitem!', 'inside!', 'integer!', 'internetresult!',
+ 'italic!', 'itemchanged!', 'itemchanging!', 'itemcollapsed!',
+ 'itemcollapsing!', 'itemerror!', 'itemexpanded!', 'itemexpanding!',
+ 'itemfocuschanged!', 'itempopulate!', 'jaguarorb!', 'johabcharset!',
+ 'justify!', 'key!', 'key0!', 'key1!',
+ 'key2!', 'key3!', 'key4!', 'key5!',
+ 'key6!', 'key7!', 'key8!', 'key9!',
+ 'keya!', 'keyadd!', 'keyalt!', 'keyapps!',
+ 'keyb!', 'keyback!', 'keybackquote!', 'keybackslash!',
+ 'keyc!', 'keycapslock!', 'keycomma!', 'keycontrol!',
+ 'keyd!', 'keydash!', 'keydecimal!', 'keydelete!',
+ 'keydivide!', 'keydownarrow!', 'keye!', 'keyend!',
+ 'keyenter!', 'keyequal!', 'keyescape!', 'keyf!',
+ 'keyf1!', 'keyf10!', 'keyf11!', 'keyf12!',
+ 'keyf2!', 'keyf3!', 'keyf4!', 'keyf5!',
+ 'keyf6!', 'keyf7!', 'keyf8!', 'keyf9!',
+ 'keyg!', 'keyh!', 'keyhome!', 'keyi!',
+ 'keyinsert!', 'keyj!', 'keyk!', 'keyl!',
+ 'keyleftarrow!', 'keyleftbracket!', 'keyleftbutton!', 'keyleftwindows!',
+ 'keym!', 'keymiddlebutton!', 'keymultiply!', 'keyn!',
+ 'keynull!', 'keynumlock!', 'keynumpad0!', 'keynumpad1!',
+ 'keynumpad2!', 'keynumpad3!', 'keynumpad4!', 'keynumpad5!',
+ 'keynumpad6!', 'keynumpad7!', 'keynumpad8!', 'keynumpad9!',
+ 'keyo!', 'keyp!', 'keypagedown!', 'keypageup!',
+ 'keypause!', 'keyperiod!', 'keyprintscreen!', 'keyq!',
+ 'keyquote!', 'keyr!', 'keyrightarrow!', 'keyrightbracket!',
+ 'keyrightbutton!', 'keyrightwindows!', 'keys!', 'keyscrolllock!',
+ 'keysemicolon!', 'keyshift!', 'keyslash!', 'keyspacebar!',
+ 'keysubtract!', 'keyt!', 'keytab!', 'keyu!',
+ 'keyuparrow!', 'keyv!', 'keyw!', 'keyword!',
+ 'keyx!', 'keyy!', 'keyz!', 'languageafrikaans!',
+ 'languagealbanian!', 'languagearabicalgeria!', 'languagearabicbahrain!',
+ 'languagearabicegypt!',
+ 'languagearabiciraq!', 'languagearabicjordan!', 'languagearabickuwait!',
+ 'languagearabiclebanon!',
+ 'languagearabiclibya!', 'languagearabicmorocco!', 'languagearabicoman!',
+ 'languagearabicqatar!',
+ 'languagearabicsaudiarabia!', 'languagearabicsyria!', 'languagearabictunisia!',
+ 'languagearabicuae!',
+ 'languagearabicyemen!', 'languagebasque!', 'languagebulgarian!', 'languagebyelorussian!',
+ 'languagecatalan!', 'languagechinese!', 'languagechinesehongkong!', 'languagechinesesimplified!',
+ 'languagechinesesingapore!', 'languagechinesetraditional!', 'languagecroatian!', 'languageczech!',
+ 'languagedanish!', 'languagedutch!', 'languagedutchbelgian!', 'languagedutchneutral!',
+ 'languageenglish!', 'languageenglishaustralian!', 'languageenglishcanadian!',
+ 'languageenglishirish!',
+ 'languageenglishnewzealand!', 'languageenglishsouthafrica!', 'languageenglishuk!',
+ 'languageenglishus!',
+ 'languageestonian!', 'languagefaeroese!', 'languagefarsi!', 'languagefinnish!',
+ 'languagefrench!', 'languagefrenchbelgian!', 'languagefrenchcanadian!', 'languagefrenchluxembourg!',
+ 'languagefrenchneutral!', 'languagefrenchswiss!', 'languagegerman!', 'languagegermanaustrian!',
+ 'languagegermanliechtenstein!', 'languagegermanluxembourg!', 'languagegermanneutral!',
+ 'languagegermanswiss!',
+ 'languagegreek!', 'languagehebrew!', 'languagehindi!', 'languagehungarian!',
+ 'languageicelandic!', 'languageindonesian!', 'languageitalian!', 'languageitalianneutral!',
+ 'languageitalianswiss!', 'languagejapanese!', 'languagekorean!', 'languagekoreanjohab!',
+ 'languagelatvian!', 'languagelithuanian!', 'languagemacedonian!', 'languagemaltese!',
+ 'languageneutral!', 'languagenorwegian!', 'languagenorwegianbokmal!', 'languagenorwegiannynorsk!',
+ 'languagepolish!', 'languageportuguese!', 'languageportuguese_brazilian!',
+ 'languageportugueseneutral!',
+ 'languagerhaetoromanic!', 'languageromanian!', 'languageromanianmoldavia!', 'languagerussian!',
+ 'languagerussianmoldavia!', 'languagesami!', 'languageserbian!', 'languageslovak!',
+ 'languageslovenian!', 'languagesorbian!', 'languagesortnative!', 'languagesortunicode!',
+ 'languagespanish!', 'languagespanishcastilian!', 'languagespanishmexican!', 'languagespanishmodern!',
+ 'languagesutu!', 'languageswedish!', 'languagesystemdefault!', 'languagethai!',
+ 'languagetsonga!', 'languagetswana!', 'languageturkish!', 'languageukrainian!',
+ 'languageurdu!', 'languageuserdefault!', 'languagevenda!', 'languagexhosa!',
+ 'languagezulu!', 'last!', 'layer!', 'layered!',
+ 'Left!', 'leftmargin!', 'line!', 'line3d!',
+ 'linear!', 'linecolor!', 'linedown!', 'linegraph!',
+ 'lineleft!', 'linemode!', 'lineright!', 'lineup!',
+ 'linkupdateautomatic!', 'linkupdatemanual!', 'listbox!', 'listview!',
+ 'listviewitem!', 'listviewlargeicon!', 'listviewlist!', 'listviewreport!',
+ 'listviewsmallicon!', 'lockread!', 'lockreadwrite!', 'lockwrite!',
+ 'log10!', 'loge!', 'long!', 'losefocus!',
+ 'lower!', 'lowered!', 'm68000!', 'm68020!',
+ 'm68030!', 'm68040!', 'maccharset!', 'macintosh!',
+ 'mailattach!', 'mailbcc!', 'mailbodyasfile!', 'mailcc!',
+ 'maildownload!', 'mailentiremessage!', 'mailenvelopeonly!', 'mailfiledescription!',
+ 'mailmessage!', 'mailnewsession!', 'mailnewsessionwithdownload!', 'mailole!',
+ 'mailolestatic!', 'mailoriginator!', 'mailrecipient!', 'mailreturnaccessdenied!',
+ 'mailreturnattachmentnotfound!', 'mailreturnattachmentopenfailure!',
+ 'mailreturnattachmentwritefailure!', 'mailreturndiskfull!',
+ 'mailreturnfailure!', 'mailreturninsufficientmemory!', 'mailreturninvalidmessage!',
+ 'mailreturnloginfailure!',
+ 'mailreturnmessageinuse!', 'mailreturnnomessages!', 'mailreturnsuccess!', 'mailreturntexttoolarge!',
+ 'mailreturntoomanyfiles!', 'mailreturntoomanyrecipients!', 'mailreturntoomanysessions!',
+ 'mailreturnunknownrecipient!',
+ 'mailreturnuserabort!', 'mailsession!', 'mailsuppressattachments!', 'mailto!',
+ 'main!', 'maximized!', 'mdi!', 'mdiclient!',
+ 'mdihelp!', 'menu!', 'menucascade!', 'menuitemtypeabout!',
+ 'menuitemtypeexit!', 'menuitemtypehelp!', 'menuitemtypenormal!', 'merge!',
+ 'message!', 'minimized!', 'mips!', 'modelexistserror!',
+ 'modelnotexistserror!', 'modern!', 'modified!', 'mousedown!',
+ 'mousemove!', 'mouseup!', 'moved!', 'multiline!',
+ 'multilineedit!', 'mutexcreateerror!', 'new!', 'newmodified!',
+ 'next!', 'nexttreeitem!', 'nextvisibletreeitem!', 'noborder!',
+ 'noconnectprivilege!', 'nolegend!', 'none!', 'nonvisualobject!',
+ 'normal!', 'nosymbol!', 'notic!', 'notmodified!',
+ 'notopmost!', 'notype!', 'numericmask!', 'objhandle!',
+ 'oem!', 'off!', 'offsite!', 'ok!',
+ 'okcancel!', 'olecontrol!', 'olecustomcontrol!', 'oleobject!',
+ 'olestorage!', 'olestream!', 'oletxnobject!', 'omcontrol!',
+ 'omcustomcontrol!', 'omembeddedcontrol!', 'omobject!', 'omstorage!',
+ 'omstream!', 'open!', 'orb!', 'original!',
+ 'osf1!', 'other!', 'outside!', 'oval!',
+ 'pagedown!', 'pageleft!', 'pageright!', 'pageup!',
+ 'parenttreeitem!', 'pbtocppobject!', 'pentium!', 'percentage!',
+ 'picture!', 'picturebutton!', 'picturehyperlink!', 'picturelistbox!',
+ 'pictureselected!', 'pie3d!', 'piegraph!', 'pipeend!',
+ 'pipeline!', 'pipemeter!', 'pipestart!', 'popup!',
+ 'powerobject!', 'powerpc!', 'powerrs!', 'ppc601!',
+ 'ppc603!', 'ppc604!', 'previewdelete!', 'previewfunctionreselectrow!',
+ 'previewfunctionretrieve!', 'previewfunctionupdate!', 'previewinsert!', 'previewselect!',
+ 'previewupdate!', 'previoustreeitem!', 'previousvisibletreeitem!', 'primary!',
+ 'printend!', 'printfooter!', 'printheader!', 'printpage!',
+ 'printstart!', 'prior!', 'private!', 'process!',
+ 'profilecall!', 'profileclass!', 'profileline!', 'profileroutine!',
+ 'profiling!', 'protected!', 'psreport!', 'public!',
+ 'question!', 'radiobutton!', 'raised!', 'rbuttondown!',
+ 'rbuttonup!', 'read!', 'readonlyargument!', 'real!',
+ 'rectangle!', 'regbinary!', 'regexpandstring!', 'reglink!',
+ 'regmultistring!', 'regstring!', 'regulong!', 'regulongbigendian!',
+ 'remoteexec!', 'remotehotlinkstart!', 'remotehotlinkstop!', 'remoteobject!',
+ 'remoterequest!', 'remotesend!', 'rename!', 'replace!',
+ 'resize!', 'resizeborder!', 'response!', 'resultset!',
+ 'resultsets!', 'retrieveend!', 'retrieverow!', 'retrievestart!',
+ 'retrycancel!', 'richtextedit!', 'Right!', 'rightclicked!',
+ 'rightdoubleclicked!', 'rightmargin!', 'rnddays!', 'rnddefault!',
+ 'rndhours!', 'rndmicroseconds!', 'rndminutes!', 'rndmonths!',
+ 'rndnumber!', 'rndseconds!', 'rndyears!', 'roman!',
+ 'roottreeitem!', 'roundrectangle!', 'routineesql!', 'routineevent!',
+ 'routinefunction!', 'routinegarbagecollection!', 'routineobjectcreation!',
+ 'routineobjectdestruction!',
+ 'routineroot!', 'rowfocuschanged!', 'russiancharset!', 'save!',
+ 'scalartype!', 'scattergraph!', 'script!', 'scriptdefinition!',
+ 'scriptevent!', 'scriptfunction!', 'scrollhorizontal!', 'scrollvertical!',
+ 'selected!', 'selectionchanged!', 'selectionchanging!', 'series!',
+ 'service!', 'shade!', 'shadowbox!', 'shared!',
+ 'sharedobjectcreateinstanceerror!', 'sharedobjectcreatepbsessionerror!',
+ 'sharedobjectexistserror!', 'sharedobjectnotexistserror!',
+ 'shiftjis!', 'show!', 'simpletype!', 'simpletypedefinition!',
+ 'singlelineedit!', 'size!', 'sizenesw!', 'sizens!',
+ 'sizenwse!', 'sizewe!', 'sol2!', 'solid!',
+ 'sort!', 'sourcepblerror!', 'spacing1!', 'spacing15!',
+ 'spacing2!', 'sparc!', 'sqlinsert!', 'sqlpreview!',
+ 'square!', 'sslcallback!', 'sslserviceprovider!', 'statichyperlink!',
+ 'statictext!', 'stgdenynone!', 'stgdenyread!', 'stgdenywrite!',
+ 'stgexclusive!', 'stgread!', 'stgreadwrite!', 'stgwrite!',
+ 'stopsign!', 'straddle!', 'streammode!', 'stretch!',
+ 'strikeout!', 'string!', 'stringmask!', 'structure!',
+ 'stylebox!', 'stylelowered!', 'styleraised!', 'styleshadowbox!',
+ 'subscript!', 'success!', 'superscript!', 'swiss!',
+ 'sylk!', 'symbol!', 'symbolhollowbox!', 'symbolhollowcircle!',
+ 'symbolhollowdiamond!', 'symbolhollowdownarrow!', 'symbolhollowuparrow!', 'symbolplus!',
+ 'symbolsolidbox!', 'symbolsolidcircle!', 'symbolsoliddiamond!', 'symbolsoliddownarrow!',
+ 'symbolsoliduparrow!', 'symbolstar!', 'symbolx!', 'system!',
+ 'systemerror!', 'systemfunctions!', 'systemkey!', 'tab!',
+ 'tabsonbottom!', 'tabsonbottomandtop!', 'tabsonleft!', 'tabsonleftandright!',
+ 'tabsonright!', 'tabsonrightandleft!', 'tabsontop!', 'tabsontopandbottom!',
+ 'text!', 'thaicharset!', 'thread!', 'tile!',
+ 'tilehorizontal!', 'time!', 'timemask!', 'timer!',
+ 'timernone!', 'timing!', 'tobottom!', 'toolbarmoved!',
+ 'top!', 'topic!', 'topmost!', 'totop!',
+ 'traceactivitynode!', 'traceatomic!', 'tracebeginend!', 'traceerror!',
+ 'traceesql!', 'tracefile!', 'tracegarbagecollect!', 'tracegeneralerror!',
+ 'tracein!', 'traceline!', 'tracenomorenodes!', 'tracenotstartederror!',
+ 'traceobject!', 'traceout!', 'traceroutine!', 'tracestartederror!',
+ 'tracetree!', 'tracetreeerror!', 'tracetreeesql!', 'tracetreegarbagecollect!',
+ 'tracetreeline!', 'tracetreenode!', 'tracetreeobject!', 'tracetreeroutine!',
+ 'tracetreeuser!', 'traceuser!', 'transaction!', 'transactionserver!',
+ 'transparent!', 'transport!', 'treeview!', 'treeviewitem!',
+ 'turkishcharset!', 'typeboolean!', 'typecategory!', 'typecategoryaxis!',
+ 'typecategorylabel!', 'typedata!', 'typedate!', 'typedatetime!',
+ 'typedecimal!', 'typedefinition!', 'typedouble!', 'typegraph!',
+ 'typeinteger!', 'typelegend!', 'typelong!', 'typereal!',
+ 'typeseries!', 'typeseriesaxis!', 'typeserieslabel!', 'typestring!',
+ 'typetime!', 'typetitle!', 'typeuint!', 'typeulong!',
+ 'typeunknown!', 'typevalueaxis!', 'typevaluelabel!', 'ultrasparc!',
+ 'unboundedarray!', 'underline!', 'underlined!', 'unsignedinteger!',
+ 'unsignedlong!', 'unsorted!', 'uparrow!', 'updateend!',
+ 'updatestart!', 'upper!', 'userdefinedsort!', 'userobject!',
+ 'variable!', 'variableargument!', 'variablecardinalitydefinition!', 'variabledefinition!',
+ 'variableglobal!', 'variableinstance!', 'variablelocal!', 'variableshared!',
+ 'varlistargument!', 'vbxvisual!', 'vcenter!', 'vertical!',
+ 'vietnamesecharset!', 'viewchange!', 'vprogressbar!', 'vscrollbar!',
+ 'vticksonboth!', 'vticksonleft!', 'vticksonneither!', 'vticksonright!',
+ 'vtrackbar!', 'window!', 'windowmenu!', 'windowobject!',
+ 'windows!', 'windowsnt!', 'wk1!', 'wks!',
+ 'wmf!', 'write!', 'xpixelstounits!', 'xunitstopixels!',
+ 'xvalue!', 'yesno!', 'yesnocancel!', 'ypixelstounits!',
+ 'yunitstopixels!',
+ 'yvalue!',
+ 'zoom!'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '[', ']', '{', '}'),
+ 1 => array('|'),
+ 2 => array('+', '-', '*', '/'),
+ 3 => array('=', '&lt;', '>', '^')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #008000; font-weight: bold;',
+ 2 => 'color: #990099; font-weight: bold;',
+ 3 => 'color: #330099; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #0000ff; font-weight: bold;',
+ 'MULTI' => 'color: #0000ff; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #800000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #330099; font-weight: bold;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;',
+ 1 => 'color: #ffff00; background-color:#993300; font-weight: bold',
+ 2 => 'color: #000000;',
+ 3 => 'color: #000000;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #800000; font-weight: bold;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/powershell.php b/platform/www/vendor/geshi/geshi/src/geshi/powershell.php
new file mode 100644
index 0000000..5b33306
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/powershell.php
@@ -0,0 +1,275 @@
+<?php
+/*************************************************************************************
+ * powershell.php
+ * ---------------------------------
+ * Author: Frode Aarebrot (frode@aarebrot.net)
+ * Copyright: (c) 2008 Frode Aarebrot (http://www.aarebrot.net)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/06/20
+ *
+ * PowerShell language file for GeSHi.
+ *
+ * I've tried to make this language file as true to the highlighting in PowerGUI as
+ * possible. Unfortunately it's not 100% complete, although it is pretty close.
+ *
+ * I've included some classes and their members, but there's tons and tons of these.
+ * I suggest you add the ones you need yourself. I've included a few Sharepoint ones
+ * in this language file.
+ *
+ * CHANGES
+ * -------
+ * 2008/06/20 (1.0.8)
+ * - First Release
+ *
+ * TODO (updated 2008/06/20)
+ * -------------------------
+ * - Color text between Cmdlets/Aliases and pipe/end-of-line
+ * - Try and get -- and ++ to work in the KEYWORDS array with the other operators
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'PowerShell',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array('<#' => '#>'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '`',
+ 'KEYWORDS' => array(
+ 1 => array(
+ // Cmdlets
+ 'Add-Content', 'Add-History', 'Add-Member', 'Add-PSSnapin', 'Clear-Content', 'Clear-Item',
+ 'Clear-ItemProperty', 'Clear-Variable', 'Compare-Object', 'ConvertFrom-SecureString',
+ 'Convert-Path', 'ConvertTo-Html', 'ConvertTo-SecureString', 'Copy-Item', 'Copy-ItemProperty',
+ 'Export-Alias', 'Export-Clixml', 'Export-Console', 'Export-Csv', 'ForEach-Object',
+ 'Format-Custom', 'Format-List', 'Format-Table', 'Format-Wide', 'Get-Acl', 'Get-Alias',
+ 'Get-AuthenticodeSignature', 'Get-ChildItem', 'Get-Command', 'Get-Content', 'Get-Credential',
+ 'Get-Culture', 'Get-Date', 'Get-EventLog', 'Get-ExecutionPolicy', 'Get-Help', 'Get-History',
+ 'Get-Host', 'Get-Item', 'Get-ItemProperty', 'Get-Location', 'Get-Member',
+ 'Get-PfxCertificate', 'Get-Process', 'Get-PSDrive', 'Get-PSProvider', 'Get-PSSnapin',
+ 'Get-Service', 'Get-TraceSource', 'Get-UICulture', 'Get-Unique', 'Get-Variable',
+ 'Get-WmiObject', 'Group-Object', 'Import-Alias', 'Import-Clixml', 'Import-Csv',
+ 'Invoke-Expression', 'Invoke-History', 'Invoke-Item', 'Join-Path', 'Measure-Command',
+ 'Measure-Object', 'Move-Item', 'Move-ItemProperty', 'New-Alias', 'New-Item',
+ 'New-ItemProperty', 'New-Object', 'New-PSDrive', 'New-Service', 'New-TimeSpan',
+ 'New-Variable', 'Out-Default', 'Out-File', 'Out-Host', 'Out-Null', 'Out-Printer',
+ 'Out-String', 'Pop-Location', 'Push-Location', 'Read-Host', 'Remove-Item',
+ 'Remove-ItemProperty', 'Remove-PSDrive', 'Remove-PSSnapin', 'Remove-Variable', 'Rename-Item',
+ 'Rename-ItemProperty', 'Resolve-Path', 'Restart-Service', 'Resume-Service', 'Select-Object',
+ 'Select-String', 'Set-Acl', 'Set-Alias', 'Set-AuthenticodeSignature', 'Set-Content',
+ 'Set-Date', 'Set-ExecutionPolicy', 'Set-Item', 'Set-ItemProperty', 'Set-Location',
+ 'Set-PSDebug', 'Set-Service', 'Set-TraceSource', 'Set-Variable', 'Sort-Object', 'Split-Path',
+ 'Start-Service', 'Start-Sleep', 'Start-Transcript', 'Stop-Process', 'Stop-Service',
+ 'Stop-Transcript', 'Suspend-Service', 'Tee-Object', 'Test-Path', 'Trace-Command',
+ 'Update-FormatData', 'Update-TypeData', 'Where-Object', 'Write-Debug', 'Write-Error',
+ 'Write-Host', 'Write-Output', 'Write-Progress', 'Write-Verbose', 'Write-Warning'
+ ),
+ 2 => array(
+ // Aliases
+ 'ac', 'asnp', 'clc', 'cli', 'clp', 'clv', 'cpi', 'cpp', 'cvpa', 'diff', 'epal', 'epcsv', 'fc',
+ 'fl', 'ft', 'fw', 'gal', 'gc', 'gci', 'gcm', 'gdr', 'ghy', 'gi', 'gl', 'gm',
+ 'gp', 'gps', 'group', 'gsv', 'gsnp', 'gu', 'gv', 'gwmi', 'iex', 'ihy', 'ii', 'ipal', 'ipcsv',
+ 'mi', 'mp', 'nal', 'ndr', 'ni', 'nv', 'oh', 'rdr', 'ri', 'rni', 'rnp', 'rp', 'rsnp', 'rv',
+ 'rvpa', 'sal', 'sasv', 'sc', 'select', 'si', 'sl', 'sleep', 'sort', 'sp', 'spps', 'spsv', 'sv',
+ 'tee', 'write', 'cat', 'cd', 'clear', 'cp', 'h', 'history', 'kill', 'lp', 'ls',
+ 'mount', 'mv', 'popd', 'ps', 'pushd', 'pwd', 'r', 'rm', 'rmdir', 'echo', 'cls', 'chdir',
+ 'copy', 'del', 'dir', 'erase', 'move', 'rd', 'ren', 'set', 'type'
+ ),
+ 3 => array(
+ // Reserved words
+ 'break', 'continue', 'do', 'for', 'foreach', 'while', 'if', 'switch', 'until', 'where',
+ 'function', 'filter', 'else', 'elseif', 'in', 'return', 'param', 'throw', 'trap'
+ ),
+ 4 => array(
+ // Operators
+ '-eq', '-ne', '-gt', '-ge', '-lt', '-le', '-ieq', '-ine', '-igt', '-ige', '-ilt', '-ile',
+ '-ceq', '-cne', '-cgt', '-cge', '-clt', '-cle', '-like', '-notlike', '-match', '-notmatch',
+ '-ilike', '-inotlike', '-imatch', '-inotmatch', '-clike', '-cnotlike', '-cmatch', '-cnotmatch',
+ '-contains', '-notcontains', '-icontains', '-inotcontains', '-ccontains', '-cnotcontains',
+ '-isnot', '-is', '-as', '-replace', '-ireplace', '-creplace', '-and', '-or', '-band', '-bor',
+ '-not', '-bnot', '-f', '-casesensitive', '-exact', '-file', '-regex', '-wildcard'
+ ),
+ 5 => array(
+ // Options
+ '-Year', '-Wrap', '-Word', '-Width', '-WhatIf', '-Wait', '-View', '-Verbose', '-Verb',
+ '-Variable', '-ValueOnly', '-Value', '-Unique', '-UFormat', '-TypeName', '-Trace', '-TotalCount',
+ '-Title', '-TimestampServer', '-TargetObject', '-Syntax', '-SyncWindow', '-Sum', '-String',
+ '-Strict', '-Stream', '-Step', '-Status', '-Static', '-StartupType', '-Start', '-StackName',
+ '-Stack', '-SourceId', '-SimpleMatch', '-ShowError', '-Separator', '-SecureString', '-SecureKey',
+ '-SecondValue', '-SecondsRemaining', '-Seconds', '-Second', '-Scope', '-Root', '-Role',
+ '-Resolve', '-RemoveListener', '-RemoveFileListener', '-Registered', '-ReferenceObject',
+ '-Recurse', '-RecommendedAction', '-ReadCount', '-Quiet', '-Query', '-Qualifier', '-PSSnapin',
+ '-PSProvider', '-PSHost', '-PSDrive', '-PropertyType', '-Property', '-Prompt', '-Process',
+ '-PrependPath', '-PercentComplete', '-Pattern', '-PathType', '-Path', '-PassThru', '-ParentId',
+ '-Parent', '-Parameter', '-Paging', '-OutVariable', '-OutBuffer', '-Option', '-OnType', '-Off',
+ '-Object', '-Noun', '-NoTypeInformation', '-NoQualifier', '-NoNewline', '-NoElement',
+ '-NoClobber', '-NewName', '-Newest', '-Namespace', '-Name', '-Month', '-Minutes', '-Minute',
+ '-Minimum', '-Milliseconds', '-Message', '-MemberType', '-Maximum', '-LogName', '-LiteralPath',
+ '-LiteralName', '-ListenerOption', '-List', '-Line', '-Leaf', '-Last', '-Key', '-ItemType',
+ '-IsValid', '-IsAbsolute', '-InputObject', '-IncludeEqual', '-IncludeChain', '-Include',
+ '-IgnoreWhiteSpace', '-Id', '-Hours', '-Hour', '-HideTableHeaders', '-Head', '-GroupBy',
+ '-Functionality', '-Full', '-Format', '-ForegroundColor', '-Force', '-First', '-FilterScript',
+ '-Filter', '-FilePath', '-Expression', '-ExpandProperty', '-Expand', '-ExecutionPolicy',
+ '-ExcludeProperty', '-ExcludeDifferent', '-Exclude', '-Exception', '-Examples', '-ErrorVariable',
+ '-ErrorRecord', '-ErrorId', '-ErrorAction', '-End', '-Encoding', '-DisplayName', '-DisplayHint',
+ '-DisplayError', '-DifferenceObject', '-Detailed', '-Destination', '-Description', '-Descending',
+ '-Depth', '-DependsOn', '-Delimiter', '-Debugger', '-Debug', '-Days', '-Day', '-Date',
+ '-CurrentOperation', '-Culture', '-Credential', '-Count', '-Container', '-Confirm',
+ '-ComputerName', '-Component', '-Completed', '-ComObject', '-CommandType', '-Command',
+ '-Column', '-Class', '-ChildPath', '-Character', '-Certificate', '-CategoryTargetType',
+ '-CategoryTargetName', '-CategoryReason', '-CategoryActivity', '-Category', '-CaseSensitive',
+ '-Body', '-BinaryPathName', '-Begin', '-BackgroundColor', '-Average', '-AutoSize', '-Audit',
+ '-AsString', '-AsSecureString', '-AsPlainText', '-As', '-ArgumentList', '-AppendPath', '-Append',
+ '-Adjust', '-Activity', '-AclObject'
+ ),
+ 6 => array(
+ '_','args','DebugPreference','Error','ErrorActionPreference',
+ 'foreach','Home','Host','Input','LASTEXITCODE','MaximumAliasCount',
+ 'MaximumDriveCount','MaximumFunctionCount','MaximumHistoryCount',
+ 'MaximumVariableCount','OFS','PsHome',
+ 'ReportErrorShowExceptionClass','ReportErrorShowInnerException',
+ 'ReportErrorShowSource','ReportErrorShowStackTrace',
+ 'ShouldProcessPreference','ShouldProcessReturnPreference',
+ 'StackTrace','VerbosePreference','WarningPreference','PWD'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '=', '<', '>', '@', '|', '&', ',', '?',
+ '+=', '-=', '*=', '/=', '%=', '*', '/', '%', '!', '+', '-', '++', '--'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #008080; font-weight: bold;',
+ 2 => 'color: #008080; font-weight: bold;',
+ 3 => 'color: #0000FF;',
+ 4 => 'color: #FF0000;',
+ 5 => 'color: #008080; font-style: italic;',
+ 6 => 'color: #000080;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000;',
+ 'MULTI' => 'color: #008000;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #008080; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #800000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #804000;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: pink;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: pink;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #800080;',
+ 3 => 'color: #008080;',
+ 4 => 'color: #008080;',
+ 5 => 'color: #800000;',
+ 6 => 'color: #000080;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => 'about:blank',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ // special after pipe
+ 3 => array(
+ GESHI_SEARCH => '(\[)(int|long|string|char|bool|byte|double|decimal|float|single|regex|array|xml|scriptblock|switch|hashtable|type|ref|psobject|wmi|wmisearcher|wmiclass|object)((\[.*\])?\])',
+ GESHI_REPLACE => '\2',
+ GESHI_MODIFIERS => 'si',
+ GESHI_BEFORE => '\1',
+ GESHI_AFTER => '\3'
+ ),
+ // Classes
+ 4 => array(
+ GESHI_SEARCH => '(\[)(System\.Reflection\.Assembly|System\.Net\.CredentialCache|Microsoft\.SharePoint\.SPFileLevel|Microsoft\.SharePoint\.Publishing\.PublishingWeb|Microsoft\.SharePoint\.Publishing|Microsoft\.SharePoint\.SPWeb)(\])',
+ GESHI_REPLACE => '\2',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '\1',
+ GESHI_AFTER => '\3'
+ ),
+ // Members
+ // There's about a hundred million of these, add the ones you need as you need them
+ 5 => array (
+ GESHI_SEARCH => '(::)(ReflectionOnlyLoadFrom|ReflectionOnlyLoad|ReferenceEquals|LoadWithPartialName|LoadFrom|LoadFile|Load|GetExecutingAssembly|GetEntryAssembly|GetCallingAssembly|GetAssembly|Equals|DefaultNetworkCredentials|DefaultCredentials|CreateQualifiedName|Checkout|Draft|Published|IsPublishingWeb)',
+ GESHI_REPLACE => '\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\1',
+ GESHI_AFTER => ''
+ ),
+ // Special variables
+ 6 => array(
+ GESHI_SEARCH => '(\$)(\$[_\^]?|\?)(?!\w)',
+ GESHI_REPLACE => '\1\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ // variables
+ //BenBE: Please note that changes here and in Keyword group 6 have to be synchronized in order to work properly.
+ //This Regexp must only match, if keyword group 6 doesn't. If this assumption fails
+ //Highlighting of the keywords will be incomplete or incorrect!
+ 0 => "(?<!\\\$|>)[\\\$](\w+)(?=[^|\w])",
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 4 => array(
+ 'DISALLOWED_AFTER' => '(?![a-zA-Z])',
+ 'DISALLOWED_BEFORE' => ''
+ ),
+ 6 => array(
+ 'DISALLOWED_BEFORE' => '(?<!\$>)\$'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/proftpd.php b/platform/www/vendor/geshi/geshi/src/geshi/proftpd.php
new file mode 100644
index 0000000..63d3924
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/proftpd.php
@@ -0,0 +1,372 @@
+<?php
+/*************************************************************************************
+ * proftpd.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2010 Benny Baumann (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/01/25
+ *
+ * ProFTPd language file for GeSHi.
+ * Words are scraped from their documentation
+ *
+ * CHANGES
+ * -------
+ * 2004/08/05 (1.0.8.10)
+ * - First Release
+ *
+ * TODO (updated 2011/01/25)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ProFTPd configuration',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ /*keywords*/
+ 1 => array(
+ //mod_auth
+ 'AccessDenyMsg', 'AccessGrantMsg', 'AnonRejectePasswords',
+ 'AnonRequirePassword', 'AuthAliasOnly', 'AuthUsingAlias',
+ 'CreateHome', 'DefaultChdir', 'DefaultRoot', 'GroupPassword',
+ 'LoginPasswordPrompt', 'MaxClients', 'MaxClientsPerClass',
+ 'MaxClientsPerHost', 'MaxClientsPerUser', 'MaxConnectionsPerHost',
+ 'MaxHostsPerUser', 'MaxLoginAttempts', 'RequireValidShell',
+ 'RootLogin', 'RootRevoke', 'TimeoutLogin', 'TimeoutSession',
+ 'UseFtpUsers', 'UserAlias', 'UserDirRoot', 'UserPassword',
+
+ //mod_auth_file
+ 'AuthGroupFile', 'AuthUserFile',
+
+ //mod_auth_pam
+ 'AuthPAM', 'AuthPAMConfig',
+
+ //mod_auth_unix
+ 'PersistentPasswd',
+
+ //mod_ban
+ 'BanControlsACLs', 'BanEngine', 'BanLog', 'BanMessage', 'BanOnEvent',
+ 'BanTable',
+
+ //mod_cap
+ 'CapabilitiesEngine', 'CapabilitiesSet',
+
+ //mod_core
+ 'Allow', 'AllowAll', 'AllowClass', 'AllowFilter',
+ 'AllowForeignAddress', 'AllowGroup', 'AllowOverride',
+ 'AllowRetrieveRestart', 'AllowStoreRestart', 'AllowUser',
+ 'AnonymousGroup', 'AuthOrder', 'Bind', 'CDPath', 'Class', 'Classes',
+ 'CommandBufferSize', 'DebugLevel', 'DefaultAddress',
+ 'DefaultServer', 'DefaultTransferMode', 'DeferWelcome', 'Define',
+ 'Deny', 'DenyAll', 'DenyClass', 'DenyFilter', 'DenyGroup',
+ 'DenyUser', 'DisplayChdir', 'DisplayConnect', 'DisplayFirstChdir',
+ 'DisplayGoAway', 'DisplayLogin', 'DisplayQuit', 'From', 'Group',
+ 'GroupOwner', 'HideFiles', 'HideGroup', 'HideNoAccess', 'HideUser',
+ 'IdentLookups', 'IgnoreHidden', 'Include', 'MasqueradeAddress',
+ 'MaxConnectionRate', 'MaxInstances', 'MultilineRFC2228', 'Order',
+ 'PassivePorts', 'PathAllowFilter', 'PathDenyFilter', 'PidFile',
+ 'Port', 'RLimitCPU', 'RLimitMemory', 'RLimitOpenFiles', 'Satisfy',
+ 'ScoreboardFile', 'ServerAdmin', 'ServerIdent', 'ServerName',
+ 'ServerType', 'SetEnv', 'SocketBindTight', 'SocketOptions',
+ 'SyslogFacility', 'SyslogLevel', 'tcpBackLog', 'tcpNoDelay',
+ 'TimeoutIdle', 'TimeoutLinger', 'TimesGMT', 'TransferLog', 'Umask',
+ 'UnsetEnv', 'UseIPv6', 'User', 'UseReverseDNS', 'UserOwner',
+ 'UseUTF8', 'WtmpLog',
+
+ //mod_ctrls_admin
+ 'AdminControlsACLs', 'AdminControlsEngine',
+
+ //mod_delay
+ 'DelayEngine', 'DelayTable',
+
+ //mod_dynmasq
+ 'DynMasqRefresh',
+
+ //mod_exec
+ 'ExecBeforeCommand', 'ExecEngine', 'ExecEnviron', 'ExecLog',
+ 'ExecOnCommand', 'ExecOnConnect', 'ExecOnError', 'ExecOnEvent',
+ 'ExecOnExit', 'ExecOnRestart', 'ExecOptions', 'ExecTimeout',
+
+ //mod_ldap
+ 'LDAPAliasDereference', 'LDAPAttr', 'LDAPAuthBinds',
+ 'LDAPDefaultAuthScheme', 'LDAPDefaultGID', 'LDAPDefaultUID',
+ 'LDAPDNInfo', 'LDAPDoAuth', 'LDAPDoGIDLookups',
+ 'LDAPDoQuotaLookups', 'LDAPDoUIDLookups',
+ 'LDAPForceGeneratedHomedir', 'LDAPForceHomedirOnDemand',
+ 'LDAPGenerateHomedir', 'LDAPGenerateHomedirPrefix',
+ 'LDAPGenerateHomedirPrefixNoUsername', 'LDAPHomedirOnDemand',
+ 'LDAPHomedirOnDemandPrefix', 'LDAPHomedirOnDemandPrefixNoUsername',
+ 'LDAPHomedirOnDemandSuffix', 'LDAPNegativeCache',
+ 'LDAPProtocolVersion', 'LDAPQueryTimeout', 'LDAPSearchScope',
+ 'LDAPServer',
+
+ //mod_load
+ 'MaxLoad',
+
+ //mod_log
+ 'AllowLogSymlinks', 'ExtendedLog', 'LogFormat', 'ServerLog',
+ 'SystemLog',
+
+ //mod_ls'
+ 'DirFakeGroup', 'DirFakeMode', 'DirFakeUser', 'ListOptions',
+ 'ShowSymlinks', 'UseGlobbing',
+
+ //mod_quotatab
+ 'QuotaDirectoryTally', 'QuotaDisplayUnits', 'QuotaEngine',
+ 'QuotaExcludeFilter', 'QuotaLimitTable', 'QuotaLock', 'QuotaLog',
+ 'QuotaOptions', 'QuotaShowQuotas', 'QuotaTallyTable',
+
+ //mod_quotatab_file
+
+ //mod_quotatab_ldap
+
+ //mod_quotatab_sql
+
+ //mod_radius
+ 'RadiusAcctServer', 'RadiusAuthServer', 'RadiusEngine',
+ 'RadiusGroupInfo', 'RadiusLog', 'RadiusNASIdentifier',
+ 'RadiusQuotaInfo', 'RadiusRealm', 'RadiusUserInfo', 'RadiusVendor',
+
+ //mod_ratio
+ 'AnonRatio', 'ByteRatioErrMsg', 'CwdRatioMsg', 'FileRatioErrMsg',
+ 'GroupRatio', 'HostRatio', 'LeechRatioMsg', 'RatioFile', 'Ratios',
+ 'RatioTempFile', 'SaveRatios', 'UserRatio',
+
+ //mod_readme
+ 'DisplayReadme',
+
+ //mod_rewrite
+ 'RewriteCondition', 'RewriteEngine', 'RewriteLock', 'RewriteLog',
+ 'RewriteMap', 'RewriteRule',
+
+ //mod_sftp
+ 'SFTPAcceptEnv', 'SFTPAuthMethods', 'SFTPAuthorizedHostKeys',
+ 'SFTPAuthorizedUserKeys', 'SFTPCiphers', 'SFTPClientMatch',
+ 'SFTPCompression', 'SFTPCryptoDevice', 'SFTPDHParamFile',
+ 'SFTPDigests', 'SFTPDisplayBanner', 'SFTPEngine', 'SFTPExtensions',
+ 'SFTPHostKey', 'SFTPKeyBlacklist', 'SFTPKeyExchanges', 'SFTPLog',
+ 'SFTPMaxChannels', 'SFTPOptions', 'SFTPPassPhraseProvider',
+ 'SFTPRekey', 'SFTPTrafficPolicy',
+
+ //mod_sftp_pam
+ 'SFTPPAMEngine', 'SFTPPAMOptions', 'SFTPPAMServiceName',
+
+ //mod_sftp_sql
+
+ //mod_shaper
+ 'ShaperAll', 'ShaperControlsACLs', 'ShaperEngine', 'ShaperLog',
+ 'ShaperSession', 'ShaperTable',
+
+ //mod_sql
+ 'SQLAuthenticate', 'SQLAuthTypes', 'SQLBackend', 'SQLConnectInfo',
+ 'SQLDefaultGID', 'SQLDefaultHomedir', 'SQLDefaultUID', 'SQLEngine',
+ 'SQLGroupInfo', 'SQLGroupWhereClause', 'SQLHomedirOnDemand',
+ 'SQLLog', 'SQLLogFile', 'SQLMinID', 'SQLMinUserGID',
+ 'SQLMinUserUID', 'SQLNamedQuery', 'SQLNegativeCache', 'SQLOptions',
+ 'SQLRatios', 'SQLRatioStats', 'SQLShowInfo', 'SQLUserInfo',
+ 'SQLUserWhereClause',
+
+ //mod_sql_passwd
+ 'SQLPasswordEncoding', 'SQLPasswordEngine', 'SQLPasswordSaltFile',
+ 'SQLPasswordUserSalt',
+
+ //mod_tls
+ 'TLSCACertificateFile', 'TLSCACertificatePath',
+ 'TLSCARevocationFile', 'TLSCARevocationPath',
+ 'TLSCertificateChainFile', 'TLSCipherSuite', 'TLSControlsACLs',
+ 'TLSCryptoDevice', 'TLSDHParamFile', 'TLSDSACertificateFile',
+ 'TLSDSACertificateKeyFile', 'TLSEngine', 'TLSLog', 'TLSOptions',
+ 'TLSPKCS12File', 'TLSPassPhraseProvider', 'TLSProtocol',
+ 'TLSRandomSeed', 'TLSRenegotiate', 'TLSRequired',
+ 'TLSRSACertificateFile', 'TLSRSACertificateKeyFile',
+ 'TLSSessionCache', 'TLSTimeoutHandshake', 'TLSVerifyClient',
+ 'TLSVerifyDepth', 'TLSVerifyOrder',
+
+ //mod_tls_shmcache
+
+ //mod_unique_id
+ 'UniqueIDEngine',
+
+ //mod_wrap
+ 'TCPAccessFiles', 'TCPAccessSyslogLevels', 'TCPGroupAccessFiles',
+ 'TCPServiceName', 'TCPUserAccessFiles',
+
+ //mod_wrap2
+ 'WrapAllowMsg', 'WrapDenyMsg', 'WrapEngine', 'WrapGroupTables',
+ 'WrapLog', 'WrapServiceName', 'WrapTables', 'WrapUserTables',
+
+ //mod_wrap2_file
+
+ //mod_wrap2_sql
+
+ //mod_xfer
+ 'AllowOverwrite', 'DeleteAbortedStores', 'DisplayFileTransfer',
+ 'HiddenStor', 'HiddenStores', 'MaxRetrieveFileSize',
+ 'MaxStoreFileSize', 'StoreUniquePrefix', 'TimeoutNoTransfer',
+ 'TimeoutStalled', 'TransferRate', 'UseSendfile',
+
+ //unknown
+ 'ScoreboardPath', 'ScoreboardScrub'
+ ),
+ /*keywords 3*/
+ 3 => array(
+ //mod_core
+ 'Anonymous',
+ 'Class',
+ 'Directory',
+ 'IfDefine',
+ 'IfModule',
+ 'Limit',
+ 'VirtualHost',
+
+ //mod_ifsession
+ 'IfClass', 'IfGroup', 'IfUser',
+
+ //mod_version
+ 'IfVersion'
+ ),
+ /*permissions*/
+ 4 => array(
+ //mod_core
+ 'ALL',
+ 'CDUP',
+ 'CMD',
+ 'CWD',
+ 'DELE',
+ 'DIRS',
+ 'LOGIN',
+ 'MKD',
+ 'READ',
+ 'RETR',
+ 'RMD',
+ 'RNFR',
+ 'RNTO',
+ 'STOR',
+ 'WRITE',
+ 'XCWD',
+ 'XMKD',
+ 'XRMD',
+
+ //mod_copy
+ 'SITE_CPFR', 'SITE_CPTO',
+
+ //mod_quotatab
+ 'SITE_QUOTA',
+
+ //mod_site
+ 'SITE_HELP', 'SITE_CHMOD', 'SITE_CHGRP',
+
+ //mod_site_misc
+ 'SITE_MKDIR', 'SITE_RMDIR', 'SITE_SYMLINK', 'SITE_UTIME',
+ ),
+ /*keywords 2*/
+ 2 => array(
+ 'all','on','off','yes','no',
+ 'standalone', 'inetd',
+ 'default', 'auth', 'write',
+ 'internet', 'local', 'limit', 'ip',
+ 'from'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '+', '-'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00007f;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #000000; font-weight:bold;',
+ 4 => 'color: #000080; font-weight:bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.google.com/search?hl=en&amp;q={FNAMEL}+site:www.proftpd.org+inurl:docs&amp;btnI=I%27m%20Feeling%20Lucky',
+ 2 => '',
+ 3 => 'http://www.google.com/search?hl=en&amp;q={FNAMEL}+site:www.proftpd.org+inurl:docs&amp;btnI=I%27m%20Feeling%20Lucky',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER,
+ 'SYMBOLS' => GESHI_NEVER
+ ),
+ 'KEYWORDS' => array(
+ 2 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\s)(?<!=)',
+ 'DISALLOWED_AFTER' => '(?!\+)(?!\w)',
+ ),
+ 3 => array(
+ 'DISALLOWED_BEFORE' => '(?<=&lt;|&lt;\/)',
+ 'DISALLOWED_AFTER' => '(?=\s|\/|&gt;)',
+ ),
+ 4 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\s)(?<!=)',
+ 'DISALLOWED_AFTER' => '(?!\+)(?=\/|(?:\s+\w+)*\s*&gt;)',
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/progress.php b/platform/www/vendor/geshi/geshi/src/geshi/progress.php
new file mode 100644
index 0000000..2160a3c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/progress.php
@@ -0,0 +1,483 @@
+<?php
+/*************************************************************************************
+ * progress.php
+ * --------
+ * Author: Marco Aurelio de Pasqual (marcop@hdi.com.br)
+ * Copyright: (c) 2008 Marco Aurelio de Pasqual, Benny Baumann (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/07/11
+ *
+ * Progress language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/11 (1.0.8)
+ * - First Release
+ *
+ * TODO (updated 2008/07/11)
+ * -------------------------
+ * * Clean up the keyword list
+ * * Sort Keyword lists by Control Structures, Predefined functions and other important keywords
+ * * Complete language support
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Progress',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array (
+ 1 => array(
+ 'ACCUMULATE','APPLY','ASSIGN','BELL','QUERY',
+ 'BUFFER-COMPARE','BUFFER-COPY','CALL','CASE',
+ 'CHOOSE','CLASS','CLOSE QUERY','each','WHERE',
+ 'CLOSE STORED-PROCEDURE','COLOR','COMPILE','CONNECT',
+ 'CONSTRUCTOR','COPY-LOB','CREATE','CREATE ALIAS',
+ 'CREATE BROWSE','CREATE BUFFER','CREATE CALL','CREATE CLIENT-PRINCIPAL',
+ 'CREATE DATABASE','CREATE DATASET','CREATE DATA-SOURCE','CREATE QUERY',
+ 'CREATE SAX-attributeS','CREATE SAX-READER','CREATE SAX-WRITER','CREATE SERVER',
+ 'CREATE SERVER-SOCKET','CREATE SOAP-HEADER','CREATE SOAP-HEADER-ENTRYREF','CREATE SOCKET',
+ 'CREATE TEMP-TABLE','CREATE WIDGET','CREATE widget-POOL','CREATE X-DOCUMENT',
+ 'CREATE X-NODEREF','CURRENT-LANGUAGE','CURRENT-VALUE','DDE ADVISE',
+ 'DDE EXECUTE','DDE GET','DDE INITIATE','DDE REQUEST',
+ 'DDE SEND','DDE TERMINATE','DEFINE BROWSE','DEFINE BUFFER','DEFINE',
+ 'DEFINE BUTTON','DEFINE DATASET','DEFINE DATA-SOURCE','DEFINE FRAME','DEF','VAR',
+ 'DEFINE IMAGE','DEFINE MENU','DEFINE PARAMETER','DEFINE property','PARAM',
+ 'DEFINE QUERY','DEFINE RECTANGLE','DEFINE STREAM','DEFINE SUB-MENU',
+ 'DEFINE TEMP-TABLE','DEFINE WORKFILE','DEFINE WORK-TABLE',
+ 'DELETE','DELETE ALIAS','DELETE object','DELETE PROCEDURE',
+ 'DELETE widget','DELETE widget-POOL','DESTRUCTOR','DICTIONARY',
+ 'DISABLE','DISABLE TRIGGERS','DISCONNECT','DISPLAY',
+ 'DO','DOS','DOWN','DYNAMIC-CURRENT-VALUE',
+ 'ELSE','EMPTY TEMP-TABLE','ENABLE','END',
+ 'ENTRY','FIND','AND',
+ 'FIX-CODEPAGE','FOR','FORM','FRAME-VALUE',
+ 'GET','GET-KEY-VALUE','HIDE','IF',
+ 'IMPORT','INPUT CLEAR','INPUT CLOSE','INPUT FROM','input',
+ 'INPUT THROUGH','INPUT-OUTPUT CLOSE','INPUT-OUTPUT THROUGH',
+ 'INTERFACE','LEAVE','BREAK',
+ 'LOAD-PICTURE','MESSAGE','method','NEXT','prev',
+ 'NEXT-PROMPT','ON','OPEN QUERY','OS-APPEND',
+ 'OS-COMMAND','OS-COPY','OS-CREATE-DIR','OS-DELETE',
+ 'OS-RENAME','OUTPUT CLOSE','OUTPUT THROUGH','OUTPUT TO',
+ 'OVERLAY','PAGE','PAUSE','PROCEDURE',
+ 'PROCESS EVENTS','PROMPT-FOR','PROMSGS','PROPATH',
+ 'PUBLISH','PUT','PUT CURSOR','PUT SCREEN',
+ 'PUT-BITS','PUT-BYTE','PUT-BYTES','PUT-DOUBLE',
+ 'PUT-FLOAT','PUT-INT64','PUT-KEY-VALUE','PUT-LONG',
+ 'PUT-SHORT','PUT-STRING','PUT-UNSIGNED-LONG','PUT-UNSIGNED-SHORT',
+ 'QUIT','RAW-TRANSFER','READKEY','RELEASE',
+ 'RELEASE EXTERNAL','RELEASE object','REPEAT','REPOSITION',
+ 'RUN','RUN STORED-PROCEDURE','RUN SUPER',
+ 'SAVE CACHE','SCROLL','SEEK','SET',
+ 'SET-BYTE-ORDER','SET-POINTER-VALUE','SET-SIZE','SHOW-STATS',
+ 'STATUS','STOP','SUBSCRIBE','SUBSTRING',
+ 'system-DIALOG COLOR','system-DIALOG FONT','system-DIALOG GET-DIR','system-DIALOG GET-FILE',
+ 'system-DIALOG PRINTER-SETUP','system-HELP','THEN','THIS-object',
+ 'TRANSACTION-MODE AUTOMATIC','TRIGGER PROCEDURE','UNDERLINE','UNDO',
+ 'UNIX','UNLOAD','UNSUBSCRIBE','UP','STRING',
+ 'UPDATE','USE','USING','substr','SKIP','CLOSE',
+ 'VIEW','WAIT-FOR','MODULO','NE','AVAIL',
+ 'NOT','OR','&GLOBAL-DEFINE','&IF','UNFORMATTED','NO-PAUSE',
+ '&THEN','&ELSEIF','&ELSE','&ENDIF','OPEN','NO-WAIT',
+ '&MESSAGE','&SCOPED-DEFINE','&UNDEFINE','DEFINED',
+ 'BROWSE','BUTTON','COMBO-BOX','CONTROL-FRAME',
+ 'DIALOG-BOX','EDITOR','FIELD-GROUP','FILL-IN',
+ 'FRAME','IMAGE','LITERAL','MENU',
+ 'MENU-ITEM','RADIO-SET','RECTANGLE','SELECTION-LIST',
+ 'SLIDER','SUB-MENU','TEXT','TOGGLE-BOX',
+ 'WINDOW','WITH','AT','OF','EDITING','ON ENDKEY','output',
+ 'ON ERROR','ON QUIT','ON STOP','PRESELECT',
+ 'QUERY-TUNING','SIZE','Trigger','VIEW-AS','ALERT-BOX',
+ 'Buffer','Data-relation','ProDataSet','SAX-attributes',
+ 'SAX-reader','SAX-writer','Server socket','SOAP-fault',
+ 'SOAP-header','SOAP-header-entryref','Socket','Temp-table',
+ 'X-noderef','Height','Left','Top','TO',
+ 'Width','ACTIVE-WINDOW','AUDIT-CONTROL','FIRST','LAST',
+ 'AUDIT-POLICY','CLIPBOARD','CODEBASE-LOCATOR','COLOR-TABLE',
+ 'COMPILER','COM-SELF','DEBUGGER','DEFAULT-WINDOW',
+ 'ERROR-STATUS','FILE-INFO','FOCUS','FONT-TABLE',
+ 'LAST-EVENT','LOG-MANAGER','RCODE-INFO','SECURITY-POLICY',
+ 'SELF','SESSION','SOURCE-PROCEDURE','TARGET-PROCEDURE','NO-LOCK','NO-error',
+ 'THIS-PROCEDURE','WEB-CONTEXT','FUNCTION','RETURNS','NO-UNDO'
+ ),
+ 2 => array(
+ 'ACCEPT-CHANGES','ACCEPT-ROW-CHANGES','ADD-BUFFER','ADD-CALC-COLUMN',
+ 'ADD-COLUMNS-FROM','ADD-EVENTS-PROCEDURE','ADD-FIELDS-FROM','ADD-FIRST',
+ 'ADD-HEADER-ENTRY','ADD-INDEX-FIELD','ADD-LAST','ADD-LIKE-COLUMN',
+ 'ADD-LIKE-FIELD','ADD-LIKE-INDEX','ADD-NEW-FIELD','ADD-NEW-INDEX',
+ 'ADD-RELATION','ADD-SCHEMA-LOCATION','ADD-SOURCE-BUFFER','ADD-SUPER-PROCEDURE',
+ 'APPEND-CHILD','APPLY-CALLBACK','ATTACH-DATA-SOURCE','AUTHENTICATION-FAILED',
+ 'BEGIN-EVENT-GROUP','BUFFER-CREATE',
+ 'BUFFER-DELETE','BUFFER-RELEASE','BUFFER-VALIDATE',
+ 'CANCEL-BREAK','CANCEL-REQUESTS','CLEAR','CLEAR-APPL-CONTEXT',
+ 'CLEAR-LOG','CLEAR-SELECTION','CLEAR-SORT-ARROWS','CLONE-NODE',
+ 'CLOSE-LOG','CONNECTED','CONVERT-TO-OFFSET',
+ 'COPY-DATASET','COPY-SAX-attributeS','COPY-TEMP-TABLE','CREATE-LIKE',
+ 'CREATE-NODE','CREATE-NODE-NAMESPACE','CREATE-RESULT-LIST-ENTRY','DEBUG',
+ 'DECLARE-NAMESPACE','DELETE-CHAR','DELETE-CURRENT-ROW',
+ 'DELETE-HEADER-ENTRY','DELETE-LINE','DELETE-NODE','DELETE-RESULT-LIST-ENTRY',
+ 'DELETE-SELECTED-ROW','DELETE-SELECTED-ROWS','DESELECT-FOCUSED-ROW','DESELECT-ROWS',
+ 'DESELECT-SELECTED-ROW','DETACH-DATA-SOURCE','DISABLE-CONNECTIONS',
+ 'DISABLE-DUMP-TRIGGERS','DISABLE-LOAD-TRIGGERS','DISPLAY-MESSAGE',
+ 'DUMP-LOGGING-NOW','EDIT-CLEAR','EDIT-COPY','EDIT-CUT',
+ 'EDIT-PASTE','EDIT-UNDO','EMPTY-DATASET','EMPTY-TEMP-TABLE',
+ 'ENABLE-CONNECTIONS','ENABLE-EVENTS','ENCRYPT-AUDIT-MAC-KEY',
+ 'END-DOCUMENT','END-ELEMENT','END-EVENT-GROUP','END-FILE-DROP',
+ 'EXPORT','EXPORT-PRINCIPAL','FETCH-SELECTED-ROW',
+ 'FILL','FIND-BY-ROWID','FIND-CURRENT','FIND-FIRST',
+ 'FIND-LAST','FIND-UNIQUE','GET-attribute','GET-attribute-NODE',
+ 'GET-BINARY-DATA','GET-BLUE-VALUE','GET-BROWSE-COLUMN','GET-BUFFER-HANDLE',
+ 'GET-BYTES-AVAILABLE','GET-CALLBACK-PROC-CONTEXT','GET-CALLBACK-PROC-NAME','GET-CGI-LIST',
+ 'GET-CGI-LONG-VALUE','GET-CGI-VALUE','GET-CHANGES','GET-CHILD',
+ 'GET-CHILD-RELATION','GET-CONFIG-VALUE','GET-CURRENT','GET-DATASET-BUFFER',
+ 'GET-DOCUMENT-ELEMENT','GET-DROPPED-FILE','GET-DYNAMIC','GET-ERROR-COLUMN ',
+ 'GET-ERROR-ROW ','GET-FILE-NAME ','GET-FILE-OFFSET ','GET-FIRST',
+ 'GET-GREEN-VALUE','GET-HEADER-ENTRY','GET-INDEX-BY-NAMESPACE-NAME','GET-INDEX-BY-QNAME',
+ 'GET-ITERATION','GET-LAST','GET-LOCALNAME-BY-INDEX','GET-MESSAGE',
+ 'GET-NEXT','GET-NODE','GET-NUMBER','GET-PARENT',
+ 'GET-PREV','GET-PRINTERS','GET-property','GET-QNAME-BY-INDEX',
+ 'GET-RED-VALUE','GET-RELATION','GET-REPOSITIONED-ROW','GET-RGB-VALUE',
+ 'GET-SELECTED-widget','GET-SERIALIZED','GET-SIGNATURE','GET-SOCKET-OPTION',
+ 'GET-SOURCE-BUFFER','GET-TAB-ITEM','GET-TEXT-HEIGHT-CHARS','GET-TEXT-HEIGHT-PIXELS',
+ 'GET-TEXT-WIDTH-CHARS','GET-TEXT-WIDTH-PIXELS','GET-TOP-BUFFER','GET-TYPE-BY-INDEX',
+ 'GET-TYPE-BY-NAMESPACE-NAME','GET-TYPE-BY-QNAME','GET-URI-BY-INDEX','GET-VALUE-BY-INDEX',
+ 'GET-VALUE-BY-NAMESPACE-NAME','GET-VALUE-BY-QNAME','GET-WAIT-STATE','IMPORT-NODE',
+ 'IMPORT-PRINCIPAL','INCREMENT-EXCLUSIVE-ID','INITIALIZE-DOCUMENT-TYPE',
+ 'INITIATE','INSERT','INSERT-attribute','INSERT-BACKTAB',
+ 'INSERT-BEFORE','INSERT-FILE','INSERT-ROW','INSERT-STRING',
+ 'INSERT-TAB','INVOKE','IS-ROW-SELECTED','IS-SELECTED',
+ 'LIST-property-NAMES','LOAD','LoadControls','LOAD-DOMAINS',
+ 'LOAD-ICON','LOAD-IMAGE','LOAD-IMAGE-DOWN','LOAD-IMAGE-INSENSITIVE',
+ 'LOAD-IMAGE-UP','LOAD-MOUSE-POINTER','LOAD-SMALL-ICON','LOCK-REGISTRATION',
+ 'LOG-AUDIT-EVENT','LOGOUT','LONGCHAR-TO-NODE-VALUE','LOOKUP',
+ 'MEMPTR-TO-NODE-VALUE','MERGE-CHANGES','MERGE-ROW-CHANGES','MOVE-AFTER-TAB-ITEM',
+ 'MOVE-BEFORE-TAB-ITEM','MOVE-COLUMN','MOVE-TO-BOTTOM','MOVE-TO-EOF',
+ 'MOVE-TO-TOP','NODE-VALUE-TO-LONGCHAR','NODE-VALUE-TO-MEMPTR','NORMALIZE',
+ 'QUERY-CLOSE','QUERY-OPEN','QUERY-PREPARE',
+ 'READ','READ-FILE','READ-XML','READ-XMLSCHEMA',
+ 'REFRESH','REFRESH-AUDIT-POLICY','REGISTER-DOMAIN','REJECT-CHANGES',
+ 'REJECT-ROW-CHANGES','REMOVE-attribute','REMOVE-CHILD','REMOVE-EVENTS-PROCEDURE',
+ 'REMOVE-SUPER-PROCEDURE','REPLACE','REPLACE-CHILD','REPLACE-SELECTION-TEXT',
+ 'REPOSITION-BACKWARD','REPOSITION-FORWARD','REPOSITION-TO-ROW','REPOSITION-TO-ROWID',
+ 'RESET','SAVE','SAVE-FILE','SAVE-ROW-CHANGES',
+ 'SAX-PARSE','SAX-PARSE-FIRST','SAX-PARSE-NEXT','SCROLL-TO-CURRENT-ROW',
+ 'SCROLL-TO-ITEM','SCROLL-TO-SELECTED-ROW','SEAL','SEARCH',
+ 'SELECT-ALL','SELECT-FOCUSED-ROW','SELECT-NEXT-ROW','SELECT-PREV-ROW',
+ 'SELECT-ROW','SET-ACTOR','SET-APPL-CONTEXT','SET-attribute',
+ 'SET-attribute-NODE','SET-BLUE-VALUE','SET-BREAK','SET-BUFFERS',
+ 'SET-CALLBACK','SET-CALLBACK-PROCEDURE','SET-CLIENT','SET-COMMIT',
+ 'SET-CONNECT-PROCEDURE','SET-DYNAMIC','SET-GREEN-VALUE','SET-INPUT-SOURCE',
+ 'SET-MUST-UNDERSTAND','SET-NODE','SET-NUMERIC-FORMAT','SET-OUTPUT-DESTINATION',
+ 'SET-PARAMETER','SET-property','SET-READ-RESPONSE-PROCEDURE','SET-RED-VALUE',
+ 'SET-REPOSITIONED-ROW','SET-RGB-VALUE','SET-ROLLBACK','SET-SELECTION',
+ 'SET-SERIALIZED','SET-SOCKET-OPTION','SET-SORT-ARROW','SET-WAIT-STATE',
+ 'START-DOCUMENT','START-ELEMENT','STOP-PARSING','SYNCHRONIZE',
+ 'TEMP-TABLE-PREPARE','UPDATE-attribute','URL-DECODE','URL-ENCODE',
+ 'VALIDATE','VALIDATE-SEAL','WRITE','WRITE-CDATA','USE-INDEX',
+ 'WRITE-CHARACTERS','WRITE-COMMENT','WRITE-DATA-ELEMENT','WRITE-EMPTY-ELEMENT',
+ 'WRITE-ENTITY-REF','WRITE-EXTERNAL-DTD','WRITE-FRAGMENT','WRITE-MESSAGE',
+ 'WRITE-PROCESSING-INSTRUCTION','WRITE-XML','WRITE-XMLSCHEMA','FALSE','true'
+ ),
+ 3 => array(
+ 'ABSOLUTE','ACCUM','ADD-INTERVAL','ALIAS','mod',
+ 'AMBIGUOUS','ASC','AUDIT-ENABLED','AVAILABLE',
+ 'BASE64-DECODE','BASE64-ENCODE','CAN-DO','CAN-FIND',
+ 'CAN-QUERY','CAN-SET','CAPS','CAST','OS-DIR',
+ 'CHR','CODEPAGE-CONVERT','COMPARE',
+ 'COUNT-OF','CURRENT-CHANGED','CURRENT-RESULT-ROW','DATASERVERS',
+ 'DATA-SOURCE-MODIFIED','DATETIME','DATETIME-TZ',
+ 'DAY','DBCODEPAGE','DBCOLLATION','DBNAME',
+ 'DBPARAM','DBRESTRICTIONS','DBTASKID','DBTYPE',
+ 'DBVERSION','DECIMAL','DECRYPT','DYNAMIC-function',
+ 'DYNAMIC-NEXT-VALUE','ENCODE','ENCRYPT','ENTERED',
+ 'ERROR','ETIME','EXP','ENDKEY','END-error',
+ 'FIRST-OF','FRAME-DB','FRAME-DOWN',
+ 'FRAME-FIELD','FRAME-FILE','FRAME-INDEX','FRAME-LINE',
+ 'GATEWAYS','GENERATE-PBE-KEY','GENERATE-PBE-SALT','GENERATE-RANDOM-KEY',
+ 'GENERATE-UUID','GET-BITS','GET-BYTE','GET-BYTE-ORDER',
+ 'GET-BYTES','GET-CODEPAGE','GET-CODEPAGES','GET-COLLATION',
+ 'GET-COLLATIONS','GET-DOUBLE','GET-FLOAT','GET-INT64',
+ 'GET-LONG','GET-POINTER-VALUE','GET-SHORT','GET-SIZE',
+ 'GET-STRING','GET-UNSIGNED-LONG','GET-UNSIGNED-SHORT','GO-PENDING',
+ 'GUID','HEX-DECODE','INDEX',
+ 'INT64','INTEGER','INTERVAL','IS-ATTR-SPACE',
+ 'IS-CODEPAGE-FIXED','IS-COLUMN-CODEPAGE','IS-LEAD-BYTE','ISO-DATE',
+ 'KBLABEL','KEYCODE','KEYFUNCTION','KEYLABEL',
+ 'KEYWORD','KEYWORD-ALL','LASTKEY',
+ 'LAST-OF','LC','LDBNAME','LEFT-TRIM',
+ 'LIBRARY','LINE-COUNTER','LIST-EVENTS','LIST-QUERY-ATTRS',
+ 'LIST-SET-ATTRS','LIST-widgetS','LOCKED',
+ 'LOGICAL','MAXIMUM','MD5-DIGEST',
+ 'MEMBER','MESSAGE-LINES','MINIMUM','MONTH',
+ 'MTIME','NEW','NEXT-VALUE','SHARED',
+ 'NOT ENTERED','NOW','NUM-ALIASES','NUM-DBS',
+ 'NUM-ENTRIES','NUM-RESULTS','OPSYS','OS-DRIVES',
+ 'OS-ERROR','OS-GETENV','PAGE-NUMBER','PAGE-SIZE',
+ 'PDBNAME','PROC-HANDLE','PROC-STATUS','PROGRAM-NAME',
+ 'PROGRESS','PROVERSION','QUERY-OFF-END','QUOTER',
+ 'RANDOM','RAW','RECID','REJECTED',
+ 'RETRY','RETURN-VALUE','RGB-VALUE',
+ 'RIGHT-TRIM','R-INDEX','ROUND','ROWID','LENGTH',
+ 'SDBNAME','SET-DB-CLIENT','SETUSERID',
+ 'SHA1-DIGEST','SQRT','SUBSTITUTE','VARIABLE',
+ 'SUPER','TERMINAL','TIME','TIMEZONE','external',
+ 'TODAY','TO-ROWID','TRIM','TRUNCATE','return',
+ 'TYPE-OF','USERID','VALID-EVENT','VALID-HANDLE',
+ 'VALID-object','WEEKDAY','YEAR','BEGINS','VALUE',
+ 'EQ','GE','GT','LE','LT','MATCHES','AS','BY','LIKE'
+ ),
+ 4 => array(
+ 'ACCELERATOR','ACTIVE','ACTOR','ADM-DATA',
+ 'AFTER-BUFFER','AFTER-ROWID','AFTER-TABLE','ALLOW-COLUMN-SEARCHING',
+ 'ALWAYS-ON-TOP','APPL-ALERT-BOXES','APPL-CONTEXT-ID','APPSERVER-INFO',
+ 'APPSERVER-PASSWORD','APPSERVER-USERID','ASYNCHRONOUS','ASYNC-REQUEST-COUNT',
+ 'ASYNC-REQUEST-HANDLE','ATTACHED-PAIRLIST','attribute-NAMES','ATTR-SPACE',
+ 'AUDIT-EVENT-CONTEXT','AUTO-COMPLETION','AUTO-DELETE','AUTO-DELETE-XML',
+ 'AUTO-END-KEY','AUTO-GO','AUTO-INDENT','AUTO-RESIZE',
+ 'AUTO-RETURN','AUTO-SYNCHRONIZE','AUTO-VALIDATE','AUTO-ZAP',
+ 'AVAILABLE-FORMATS','BACKGROUND','BASE-ADE','BASIC-LOGGING',
+ 'BATCH-MODE','BATCH-SIZE','BEFORE-BUFFER','BEFORE-ROWID',
+ 'BEFORE-TABLE','BGCOLOR','BLANK','BLOCK-ITERATION-DISPLAY',
+ 'BORDER-BOTTOM-CHARS','BORDER-BOTTOM-PIXELS','BORDER-LEFT-CHARS','BORDER-LEFT-PIXELS',
+ 'BORDER-RIGHT-CHARS','BORDER-RIGHT-PIXELS','BORDER-TOP-CHARS','BORDER-TOP-PIXELS',
+ 'BOX','BOX-SELECTABLE','BUFFER-CHARS','BUFFER-FIELD',
+ 'BUFFER-HANDLE','BUFFER-LINES','BUFFER-NAME','BUFFER-VALUE',
+ 'BYTES-READ','BYTES-WRITTEN','CACHE','CALL-NAME',
+ 'CALL-TYPE','CANCEL-BUTTON','CANCELLED','CAN-CREATE',
+ 'CAN-DELETE','CAN-READ','CAN-WRITE','CAREFUL-PAINT',
+ 'CASE-SENSITIVE','CENTERED','CHARSET','CHECKED',
+ 'CHILD-BUFFER','CHILD-NUM','CLASS-TYPE','CLIENT-CONNECTION-ID',
+ 'CLIENT-TTY','CLIENT-TYPE','CLIENT-WORKSTATION','CODE',
+ 'CODEPAGE','COLUMN','COLUMN-BGCOLOR','COLUMN-DCOLOR',
+ 'COLUMN-FGCOLOR','COLUMN-FONT','COLUMN-LABEL','COLUMN-MOVABLE',
+ 'COLUMN-PFCOLOR','COLUMN-READ-ONLY','COLUMN-RESIZABLE','COLUMN-SCROLLING',
+ 'COM-HANDLE','COMPLETE','CONFIG-NAME','CONTEXT-HELP',
+ 'CONTEXT-HELP-FILE','CONTEXT-HELP-ID','CONTROL-BOX','CONVERT-3D-COLORS',
+ 'CPCASE','CPCOLL','CPINTERNAL','CPLOG',
+ 'CPPRINT','CPRCODEIN','CPRCODEOUT','CPSTREAM',
+ 'CPTERM','CRC-VALUE','CURRENT-COLUMN','CURRENT-ENVIRONMENT',
+ 'CURRENT-ITERATION','CURRENT-ROW-MODIFIED','CURRENT-WINDOW','CURSOR-CHAR',
+ 'CURSOR-LINE','CURSOR-OFFSET','DATA-ENTRY-RETURN','DATASET',
+ 'DATA-SOURCE','DATA-SOURCE-COMPLETE-MAP','DATA-TYPE','DATE-FORMAT',
+ 'DB-REFERENCES','DCOLOR','DDE-ERROR','DDE-ID',
+ 'DDE-ITEM','DDE-NAME','DDE-TOPIC','DEBLANK',
+ 'DEBUG-ALERT','DECIMALS','DEFAULT','DEFAULT-BUFFER-HANDLE',
+ 'DEFAULT-BUTTON','DEFAULT-COMMIT','DELIMITER','DISABLE-AUTO-ZAP',
+ 'DISPLAY-TIMEZONE','DISPLAY-TYPE','DOMAIN-DESCRIPTION','DOMAIN-NAME',
+ 'DOMAIN-TYPE','DRAG-ENABLED','DROP-TARGET','DYNAMIC',
+ 'EDGE-CHARS','EDGE-PIXELS','EDIT-CAN-PASTE','EDIT-CAN-UNDO',
+ 'EMPTY','ENCODING','ENCRYPTION-SALT','END-USER-PROMPT',
+ 'ENTRY-TYPES-LIST','ERROR-COLUMN','ERROR-object-DETAIL','ERROR-ROW',
+ 'ERROR-STRING','EVENT-GROUP-ID','EVENT-PROCEDURE','EVENT-PROCEDURE-CONTEXT',
+ 'EVENT-TYPE','EXCLUSIVE-ID','EXECUTION-LOG','EXPAND',
+ 'EXPANDABLE','FGCOLOR','FILE-CREATE-DATE','FILE-CREATE-TIME',
+ 'FILE-MOD-DATE','FILE-MOD-TIME','FILE-NAME','FILE-OFFSET',
+ 'FILE-SIZE','FILE-TYPE','FILLED','FILL-MODE',
+ 'FILL-WHERE-STRING','FIRST-ASYNC-REQUEST','FIRST-BUFFER','FIRST-CHILD',
+ 'FIRST-COLUMN','FIRST-DATASET','FIRST-DATA-SOURCE','FIRST-object',
+ 'FIRST-PROCEDURE','FIRST-QUERY','FIRST-SERVER','FIRST-SERVER-SOCKET',
+ 'FIRST-SOCKET','FIRST-TAB-ITEM','FIT-LAST-COLUMN','FLAT-BUTTON',
+ 'FOCUSED-ROW','FOCUSED-ROW-SELECTED','FONT','FOREGROUND',
+ 'FORMAT','FORMATTED','FORM-INPUT','FORM-LONG-INPUT',
+ 'FORWARD-ONLY','FRAGMENT','FRAME-COL','FRAME-NAME',
+ 'FRAME-ROW','FRAME-SPACING','FRAME-X','FRAME-Y',
+ 'FREQUENCY','FULL-HEIGHT-CHARS','FULL-HEIGHT-PIXELS','FULL-PATHNAME',
+ 'FULL-WIDTH-CHARS','FULL-WIDTH-PIXELS','GRAPHIC-EDGE',
+ 'GRID-FACTOR-HORIZONTAL','GRID-FACTOR-VERTICAL','GRID-SNAP','GRID-UNIT-HEIGHT-CHARS',
+ 'GRID-UNIT-HEIGHT-PIXELS','GRID-UNIT-WIDTH-CHARS','GRID-UNIT-WIDTH-PIXELS','GRID-VISIBLE',
+ 'GROUP-BOX','HANDLE','HANDLER','HAS-LOBS',
+ 'HAS-RECORDS','HEIGHT-CHARS','HEIGHT-PIXELS','HELP',
+ 'HIDDEN','HORIZONTAL','HTML-CHARSET','HTML-END-OF-LINE',
+ 'HTML-END-OF-PAGE','HTML-FRAME-BEGIN','HTML-FRAME-END','HTML-HEADER-BEGIN',
+ 'HTML-HEADER-END','HTML-TITLE-BEGIN','HTML-TITLE-END','HWND',
+ 'ICFPARAMETER','ICON','IGNORE-CURRENT-MODIFIED','IMAGE-DOWN',
+ 'IMAGE-INSENSITIVE','IMAGE-UP','IMMEDIATE-DISPLAY','INDEX-INFORMATION',
+ 'IN-HANDLE','INHERIT-BGCOLOR','INHERIT-FGCOLOR','INITIAL','INIT',
+ 'INNER-CHARS','INNER-LINES','INPUT-VALUE','INSTANTIATING-PROCEDURE',
+ 'INTERNAL-ENTRIES','IS-CLASS','IS-OPEN','IS-PARAMETER-SET',
+ 'IS-XML','ITEMS-PER-ROW','KEEP-CONNECTION-OPEN','KEEP-FRAME-Z-ORDER',
+ 'KEEP-SECURITY-CACHE','KEY','KEYS','LABEL',
+ 'LABEL-BGCOLOR','LABEL-DCOLOR','LABEL-FGCOLOR','LABEL-FONT',
+ 'LABELS','LANGUAGES','LARGE','LARGE-TO-SMALL',
+ 'LAST-ASYNC-REQUEST','LAST-BATCH','LAST-CHILD','LAST-object',
+ 'LAST-PROCEDURE','LAST-SERVER','LAST-SERVER-SOCKET','LAST-SOCKET',
+ 'LAST-TAB-ITEM','LINE','LIST-ITEM-PAIRS','LIST-ITEMS',
+ 'LITERAL-QUESTION','LOCAL-HOST','LOCAL-NAME','LOCAL-PORT',
+ 'LOCATOR-COLUMN-NUMBER','LOCATOR-LINE-NUMBER','LOCATOR-PUBLIC-ID','LOCATOR-system-ID',
+ 'LOCATOR-TYPE','LOG-ENTRY-TYPES','LOGFILE-NAME','LOGGING-LEVEL',
+ 'LOGIN-EXPIRATION-TIMESTAMP','LOGIN-HOST','LOGIN-STATE','LOG-THRESHOLD',
+ 'MANDATORY','MANUAL-HIGHLIGHT','MAX-BUTTON','MAX-CHARS',
+ 'MAX-DATA-GUESS','MAX-HEIGHT-CHARS','MAX-HEIGHT-PIXELS','MAX-VALUE',
+ 'MAX-WIDTH-CHARS','MAX-WIDTH-PIXELS','MD5-VALUE','MENU-BAR',
+ 'MENU-KEY','MENU-MOUSE','MERGE-BY-FIELD','MESSAGE-AREA',
+ 'MESSAGE-AREA-FONT','MIN-BUTTON','MIN-COLUMN-WIDTH-CHARS','MIN-COLUMN-WIDTH-PIXELS',
+ 'MIN-HEIGHT-CHARS','MIN-HEIGHT-PIXELS','MIN-SCHEMA-MARSHAL','MIN-VALUE',
+ 'MIN-WIDTH-CHARS','MIN-WIDTH-PIXELS','MODIFIED','MOUSE-POINTER',
+ 'MOVABLE','MULTI-COMPILE','MULTIPLE','MULTITASKING-INTERVAL',
+ 'MUST-UNDERSTAND','NAME','NAMESPACE-PREFIX','NAMESPACE-URI',
+ 'NEEDS-APPSERVER-PROMPT','NEEDS-PROMPT','NESTED','NEW-ROW',
+ 'NEXT-COLUMN','NEXT-ROWID','NEXT-SIBLING','NEXT-TAB-ITEM', 'NO-BOX',
+ 'NO-CURRENT-VALUE','NODE-VALUE','NO-EMPTY-SPACE','NO-FOCUS',
+ 'NONAMESPACE-SCHEMA-LOCATION','NO-SCHEMA-MARSHAL','NO-VALIDATE','NUM-BUFFERS',
+ 'NUM-BUTTONS','NUM-CHILD-RELATIONS','NUM-CHILDREN','NUM-COLUMNS',
+ 'NUM-DROPPED-FILES','NUMERIC-DECIMAL-POINT','NUMERIC-FORMAT','NUMERIC-SEPARATOR',
+ 'NUM-FIELDS','NUM-FORMATS','NUM-HEADER-ENTRIES','NUM-ITEMS',
+ 'NUM-ITERATIONS','NUM-LINES','NUM-LOCKED-COLUMNS','NUM-LOG-FILES',
+ 'NUM-MESSAGES','NUM-PARAMETERS','NUM-REFERENCES','NUM-RELATIONS',
+ 'NUM-REPLACED','NUM-SELECTED-ROWS','NUM-SELECTED-WIDGETS','NUM-SOURCE-BUFFERS',
+ 'NUM-TABS','NUM-TOP-BUFFERS','NUM-TO-RETAIN','NUM-VISIBLE-COLUMNS',
+ 'ON-FRAME-BORDER','ORIGIN-HANDLE','ORIGIN-ROWID','OWNER',
+ 'OWNER-DOCUMENT','PAGE-BOTTOM','PAGE-TOP','PARAMETER',
+ 'PARENT','PARENT-BUFFER','PARENT-RELATION','PARSE-STATUS',
+ 'PASSWORD-FIELD','PATHNAME','PBE-HASH-ALGORITHM','PBE-KEY-ROUNDS',
+ 'PERSISTENT','PERSISTENT-CACHE-DISABLED','PERSISTENT-PROCEDURE','PFCOLOR',
+ 'PIXELS-PER-COLUMN','PIXELS-PER-ROW','POPUP-MENU','POPUP-ONLY',
+ 'POSITION','PREFER-DATASET','PREPARED','PREPARE-STRING',
+ 'PREV-COLUMN','PREV-SIBLING','PREV-TAB-ITEM','PRIMARY',
+ 'PRINTER-CONTROL-HANDLE','PRINTER-HDC','PRINTER-NAME','PRINTER-PORT',
+ 'PRIVATE-DATA','PROCEDURE-NAME','PROGRESS-SOURCE','PROXY',
+ 'PROXY-PASSWORD','PROXY-USERID','PUBLIC-ID','PUBLISHED-EVENTS',
+ 'RADIO-BUTTONS','READ-ONLY','RECORD-LENGTH',
+ 'REFRESHABLE','RELATION-FIELDS','RELATIONS-ACTIVE','REMOTE',
+ 'REMOTE-HOST','REMOTE-PORT','RESIZABLE','RESIZE',
+ 'RESTART-ROWID','RETAIN-SHAPE','RETURN-INSERTED','RETURN-VALUE-DATA-TYPE',
+ 'ROLES','ROUNDED','COL','ROW','ROW-HEIGHT-CHARS',
+ 'ROW-HEIGHT-PIXELS','ROW-MARKERS','ROW-RESIZABLE','ROW-STATE',
+ 'SAVE-WHERE-STRING','SCHEMA-CHANGE','SCHEMA-LOCATION','SCHEMA-MARSHAL',
+ 'SCHEMA-PATH','SCREEN-LINES','SCREEN-VALUE','SCROLLABLE',
+ 'SCROLLBAR-HORIZONTAL','SCROLL-BARS','SCROLLBAR-VERTICAL','SEAL-TIMESTAMP',
+ 'SELECTABLE','SELECTED','SELECTION-END','SELECTION-START',
+ 'SELECTION-TEXT','SENSITIVE','SEPARATOR-FGCOLOR','SEPARATORS',
+ 'SERVER','SERVER-CONNECTION-BOUND','SERVER-CONNECTION-BOUND-REQUEST','SERVER-CONNECTION-CONTEXT',
+ 'SERVER-CONNECTION-ID','SERVER-OPERATING-MODE','SESSION-END','SESSION-ID',
+ 'SHOW-IN-TASKBAR','SIDE-LABEL-HANDLE','SIDE-LABELS','SKIP-DELETED-RECORD',
+ 'SMALL-ICON','SMALL-TITLE','SOAP-FAULT-ACTOR','SOAP-FAULT-CODE',
+ 'SOAP-FAULT-DETAIL','SOAP-FAULT-STRING','SORT','SORT-ASCENDING',
+ 'SORT-NUMBER','SSL-SERVER-NAME','STANDALONE','STARTUP-PARAMETERS',
+ 'STATE-DETAIL','STATUS-AREA','STATUS-AREA-FONT','STOPPED',
+ 'STREAM','STRETCH-TO-FIT','STRICT','STRING-VALUE',
+ 'SUBTYPE','SUPER-PROCEDURES','SUPPRESS-NAMESPACE-PROCESSING','SUPPRESS-WARNINGS',
+ 'SYMMETRIC-ENCRYPTION-ALGORITHM','SYMMETRIC-ENCRYPTION-IV','SYMMETRIC-ENCRYPTION-KEY','SYMMETRIC-SUPPORT',
+ 'system-ALERT-BOXES','system-ID','TABLE','TABLE-CRC-LIST',
+ 'TABLE-HANDLE','TABLE-LIST','TABLE-NUMBER','TAB-POSITION',
+ 'TAB-STOP','TEMP-DIRECTORY','TEXT-SELECTED','THREE-D',
+ 'TIC-MARKS','TIME-SOURCE','TITLE','TITLE-BGCOLOR','FIELD',
+ 'TITLE-DCOLOR','TITLE-FGCOLOR','TITLE-FONT','TOOLTIP',
+ 'TOOLTIPS','TOP-ONLY','TRACKING-CHANGES','TRANSACTION',
+ 'TRANS-INIT-PROCEDURE','TRANSPARENT','TYPE','UNIQUE-ID',
+ 'UNIQUE-MATCH','URL','URL-PASSWORD','URL-USERID','EXTENT',
+ 'USER-ID','V6DISPLAY','VALIDATE-EXPRESSION','VALIDATE-MESSAGE',
+ 'VALIDATE-XML','VALIDATION-ENABLED','VIEW-FIRST-COLUMN-ON-REOPEN',
+ 'VIRTUAL-HEIGHT-CHARS','VIRTUAL-HEIGHT-PIXELS','VIRTUAL-WIDTH-CHARS','VIRTUAL-WIDTH-PIXELS',
+ 'VISIBLE','WARNING','WHERE-STRING','widget-ENTER','DATE',
+ 'widget-LEAVE','WIDTH-CHARS','WIDTH-PIXELS','WINDOW-STATE',
+ 'WINDOW-system','WORD-WRAP','WORK-AREA-HEIGHT-PIXELS','WORK-AREA-WIDTH-PIXELS',
+ 'WORK-AREA-X','WORK-AREA-Y','WRITE-STATUS','X','widget-Handle',
+ 'X-DOCUMENT','XML-DATA-TYPE','XML-NODE-TYPE','XML-SCHEMA-PATH',
+ 'XML-SUPPRESS-NAMESPACE-PROCESSING','Y','YEAR-OFFSET','CHARACTER',
+ 'LONGCHAR','MEMPTR','CHAR','DEC','INT','LOG','DECI','INTE','LOGI','long'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}',
+ '<', '>', '=',
+ '+', '-', '*', '/',
+ '!', '@', '%', '|', '$',
+ ':', '.', ';', ',',
+ '?', '<=','<>','>=', '\\'
+ ),
+ 'CASE_SENSITIVE' => array (
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array (
+ 'KEYWORDS' => array (
+ 1 => 'color: #0000ff; font-weight: bold;',
+ 2 => 'color: #1D16B2;',
+ 3 => 'color: #993333;',
+ 4 => 'color: #0000ff;'
+ ),
+ 'COMMENTS' => array (
+// 1 => 'color: #808080; font-style: italic;',
+// 2 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array (
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array (
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array (
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array (
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array (
+ 0 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array (
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array (
+ ),
+ 'SCRIPT' => array (
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 0 => ':'
+ ),
+ 'REGEXPS' => array (
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array (
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array (
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![\.\-a-zA-Z0-9_\$\#&])",
+ 'DISALLOWED_AFTER' => "(?![\-a-zA-Z0-9_%])",
+ 1 => array(
+ 'SPACE_AS_WHITESPACE' => true
+ ),
+ 2 => array(
+ 'SPACE_AS_WHITESPACE' => true
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/prolog.php b/platform/www/vendor/geshi/geshi/src/geshi/prolog.php
new file mode 100644
index 0000000..26d7448
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/prolog.php
@@ -0,0 +1,141 @@
+<?php
+/*************************************************************************************
+ * prolog.php
+ * --------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/10/02
+ *
+ * Prolog language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/02 (1.0.8.1)
+ * - First Release
+ *
+ * TODO (updated 2008/10/02)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Prolog',
+ 'COMMENT_SINGLE' => array(1 => '%'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array("\'"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'abolish','abs','arg','asserta','assertz','at_end_of_stream','atan',
+ 'atom','atom_chars','atom_codes','atom_concat','atom_length',
+ 'atomic','bagof','call','catch','ceiling','char_code',
+ 'char_conversion','clause','close','compound','consult','copy_term',
+ 'cos','current_char_conversion','current_input','current_op',
+ 'current_output','current_predicate','current_prolog_flag',
+ 'discontiguous','dynamic','ensure_loaded','exp','fail','findall',
+ 'float','float_fractional_part','float_integer_part','floor',
+ 'flush_output','functor','get_byte','get_char','get_code','halt',
+ 'include','initialization','integer','is','listing','log','mod',
+ 'multifile','nl','nonvar','notrace','number','number_chars',
+ 'number_codes','once','op','open','peek_byte','peek_char',
+ 'peek_code','put_byte','put_char','put_code','read','read_term',
+ 'rem','repeat','retract','round','set_input','set_output',
+ 'set_prolog_flag','set_stream_position','setof','sign','sin','sqrt',
+ 'stream_property','sub_atom','throw','trace','true','truncate',
+ 'unify_with_occurs_check','univ','var','write','write_canonical',
+ 'write_term','writeq'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '[', ']', '{', '}',),
+ 1 => array('?-', ':-', '=:='),
+ 2 => array('\-', '\+', '\*', '\/'),
+ 3 => array('-', '+', '*', '/'),
+ 4 => array('.', ':', ',', ';'),
+ 5 => array('!', '@', '&', '|'),
+ 6 => array('<', '>', '=')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #990000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;',
+ 'HARD' => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #800080;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;',
+ 1 => 'color: #339933;',
+ 2 => 'color: #339933;',
+ 3 => 'color: #339933;',
+ 4 => 'color: #339933;',
+ 5 => 'color: #339933;',
+ 6 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #008080;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://pauillac.inria.fr/~deransar/prolog/bips.html'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Variables
+ 0 => "(?<![a-zA-Z0-9_])(?!(?:PIPE|SEMI|DOT)[^a-zA-Z0-9_])[A-Z_][a-zA-Z0-9_]*(?![a-zA-Z0-9_])(?!\x7C)"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/properties.php b/platform/www/vendor/geshi/geshi/src/geshi/properties.php
new file mode 100644
index 0000000..89c6d62
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/properties.php
@@ -0,0 +1,125 @@
+<?php
+/*************************************************************************************
+ * properties.php
+ * --------
+ * Author: Edy Hinzen
+ * Copyright: (c) 2009 Edy Hinzen
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/04/03
+ *
+ * Property language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/04/03 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'PROPERTIES',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /* Common used variables */
+ 1 => array(
+ '${user.home}'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => ''
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #933;'
+ ),
+ 'NUMBERS' => array(
+ 0 => ''
+ ),
+ 'METHODS' => array(
+ 0 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #000080; font-weight:bold;',
+ 1 => 'color: #008000; font-weight:bold;'
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Entry names
+ 0 => array(
+ GESHI_SEARCH => '^(\s*)([.a-zA-Z0-9_\-]+)(\s*=)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ //Entry values
+ 1 => array(
+ // Evil hackery to get around GeSHi bug: <>" and ; are added so <span>s can be matched
+ // Explicit match on variable names because if a comment is before the first < of the span
+ // gets chewed up...
+ GESHI_SEARCH => '([<>";a-zA-Z0-9_]+\s*)=(.*)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1=',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/providex.php b/platform/www/vendor/geshi/geshi/src/geshi/providex.php
new file mode 100644
index 0000000..1a17865
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/providex.php
@@ -0,0 +1,297 @@
+<?php
+/******************************************************************************
+ * providex.php
+ * ----------
+ * Author: Jeff Wilder (jeff@coastallogix.com)
+ * Copyright: (c) 2008 Coastal Logix (http://www.coastallogix.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/10/18
+ *
+ * ProvideX language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/21 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ * 1. Create a regexp for numeric global variables (ex: %VarName = 3)
+ * 2. Add standard object control properties
+ *
+ ******************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *****************************************************************************/
+$language_data = array (
+ 'LANG_NAME' => 'ProvideX',
+ 'COMMENT_SINGLE' => array(1 => '!'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ // Single-Line Comments using REM command
+ 2 => "/\bREM\b.*?$/i"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ // Directives
+ '*break', '*continue', '*end', '*escape', '*next', '*proceed',
+ '*retry', '*return', '*same', 'accept', 'add index', 'addr',
+ 'auto', 'begin', 'break', 'button', 'bye', 'call', 'case',
+ 'chart', 'check_box', 'class', 'clear', 'clip_board', 'close',
+ 'continue', 'control', 'create required', 'create table',
+ 'cwdir', 'data', 'day_format', 'def', 'default', 'defctl',
+ 'defprt', 'deftty', 'delete required', 'dictionary', 'dim', 'direct',
+ 'directory', 'disable', 'drop', 'drop_box', 'dump', 'edit',
+ 'else', 'enable', 'end switch', 'end', 'end_if', 'endtrace',
+ 'enter', 'erase', 'error_handler', 'escape', 'event', 'execute',
+ 'exit', 'exitto', 'extract', 'file', 'find', 'floating point',
+ 'for', 'function', 'get_file_box', 'gosub', 'goto', 'grid',
+ 'h_scrollbar', 'hide', 'if', 'index', 'indexed', 'input',
+ 'insert', 'invoke', 'iolist', 'keyed', 'let', 'like',
+ 'line_switch', 'list', 'list_box', 'load', 'local', 'lock',
+ 'long_form', 'menu_bar', 'merge', 'message_lib', 'mnemonic',
+ 'msgbox', 'multi_line', 'multi_media', 'next', 'object', 'obtain',
+ 'on', 'open', 'password', 'perform', 'pop', 'popup_menu',
+ 'precision', 'prefix', 'preinput', 'print', 'process', 'program',
+ 'property', 'purge', 'quit', 'radio_button', 'randomize',
+ 'read', 'record', 'redim', 'refile', 'release', 'rem', 'remove',
+ 'rename', 'renumber', 'repeat', 'reset', 'restore', 'retry',
+ 'return', 'round', 'run', 'save', 'select', 'serial', 'server',
+ 'set_focus', 'set_nbf', 'set_param', 'setctl', 'setday', 'setdev',
+ 'setdrive', 'seterr', 'setesc', 'setfid', 'setmouse', 'settime',
+ 'settrace', 'short_form', 'show', 'sort', 'start', 'static',
+ 'step', 'stop', 'switch', 'system_help', 'system_jrnl', 'table',
+ 'then', 'to', 'translate', 'tristate_box', 'unlock', 'until',
+ 'update', 'user_lex', 'v_scrollbar', 'vardrop_box', 'varlist_box',
+ 'via', 'video_palette', 'wait', 'wend', 'while', 'winprt_setup',
+ 'with', 'write'
+ ),
+ 2 => array(
+ // System Functions
+ '@x', '@y', 'abs', 'acs', 'and', 'arg', 'asc', 'asn', 'ath',
+ 'atn', 'bin', 'bsz', 'chg', 'chr', 'cmp', 'cos', 'cpl',
+ 'crc', 'cse', 'ctl', 'cvs', 'dec', 'dir', 'dll', 'dsk',
+ 'dte', 'env', 'ept', 'err', 'evn', 'evs', 'exp', 'ffn',
+ 'fib', 'fid', 'fin', 'fpt', 'gap', 'gbl', 'gep', 'hsa',
+ 'hsh', 'hta', 'hwn', 'i3e', 'ind', 'int', 'iol', 'ior',
+ 'jul', 'jst', 'kec', 'kef', 'kel', 'ken', 'kep', 'key',
+ 'kgn', 'lcs', 'len', 'lno', 'log', 'lrc', 'lst', 'max',
+ 'mem', 'mid', 'min', 'mnm', 'mod', 'msg', 'msk', 'mxc',
+ 'mxl', 'new', 'not', 'nul', 'num', 'obj', 'opt', 'pad',
+ 'pck', 'pfx', 'pgm', 'pos', 'prc', 'prm', 'pth', 'pub',
+ 'rcd', 'rdx', 'rec', 'ref', 'rnd', 'rno', 'sep', 'sgn',
+ 'sin', 'sqr', 'srt', 'ssz', 'stk', 'stp', 'str', 'sub',
+ 'swp', 'sys', 'tan', 'tbl', 'tcb', 'tmr', 'trx', 'tsk',
+ 'txh', 'txw', 'ucp', 'ucs', 'upk', 'vin', 'vis', 'xeq',
+ 'xfa', 'xor', '_obj'
+ ),
+ 3 => array(
+ // System Variables
+ // Vars that are duplicates of functions
+ // 'ctl', 'err', 'pfx', 'prm', 'rnd', 'sep', 'sys',
+ 'bkg', 'chn', 'day', 'dlm', 'dsz', 'eom', 'ers', 'esc',
+ 'gfn', 'gid', 'hfn', 'hlp', 'hwd', 'lfa', 'lfo', 'lip',
+ 'lpg', 'lwd', 'mse', 'msl', 'nar', 'nid', 'pgn', 'psz',
+ 'quo', 'ret', 'sid', 'ssn', 'tim', 'tme', 'tms', 'tsm',
+ 'uid', 'unt', 'who'
+
+ ),
+ 4 => array(
+ // Nomads Variables
+ '%Flmaint_Lib$', '%Flmaint_Msg$', '%Nomads_Activation_Ok',
+ '%Nomads_Auto_Qry', '%Nomads_Disable_Debug',
+ '%Nomads_Disable_Trace', '%Nomads_Fkey_Handler$',
+ '%Nomads_Fkey_Tbl$', '%Nomads_Notest', '%Nomads_Onexit$',
+ '%Nomads_Post_Display', '%Nomads_Pre_Display$',
+ '%Nomads_Process$', '%Nomads_Trace_File$',
+ '%Nomad_Actv_Folder_Colors$', '%Nomad_Automation_Enabled',
+ '%Nomad_Auto_Close', '%Nomad_Center_Wdw', '%Nomad_Concurrent_Wdw',
+ '%Nomad_Custom_Define', '%Nomad_Custom_Dir$',
+ '%Nomad_Custom_Genmtc', '%Nomad_Custom_Skip_Definition',
+ '%Nomad_Def_Sfx$', '%Nomad_Enter_Tab', '%Nomad_Esc_Sel',
+ '%Nomad_Isjavx', '%Nomad_Iswindx', '%Nomad_Iswindx$',
+ '%Nomad_Menu$', '%Nomad_Menu_Leftedge_Clr$',
+ '%Nomad_Menu_Textbackground_Clr$', '%Nomad_Mln_Sep$',
+ '%Nomad_Msgmnt$', '%Nomad_Noplusw', '%Nomad_No_Customize',
+ '%Nomad_Object_Persistence', '%Nomad_Object_Resize',
+ '%Nomad_Open_Load', '%Nomad_Override_Font$',
+ '%Nomad_Palette_Loaded', '%Nomad_Panel_Info_Force',
+ '%Nomad_Panel_Info_Prog$', '%Nomad_Pnl_Def_Colour$',
+ '%Nomad_Pnl_Def_Font$', '%Nomad_Prg_Cache', '%Nomad_Qry_Attr$',
+ '%Nomad_Qry_Btn$', '%Nomad_Qry_Clear_Start', '%Nomad_Qry_Tip$',
+ '%Nomad_Qry_Wide', '%Nomad_Query_Clear_Status', '%Nomad_Query_Kno',
+ '%Nomad_Query_No_Gray', '%Nomad_Query_Odb_Ignore',
+ '%Nomad_Query_Retkno', '%Nomad_Query_Sbar_Max',
+ '%Nomad_Relative_Wdw', '%Nomad_Save_Qry_Path', '%Nomad_Script_Fn',
+ '%Nomad_Script_Log', '%Nomad_Script_Wdw',
+ '%Nomad_Skip_Change_Logic', '%Nomad_Skip_Onselect_Logic',
+ '%Nomad_Stk$', '%Nomad_Tab_Dir', '%Nomad_Timeout',
+ '%Nomad_Turbo_Off', '%Nomad_Visual_Effect',
+ '%Nomad_Visual_Override', '%Nomad_Win_Ver', '%Nomad_Xchar',
+ '%Nomad_Xmax', '%Nomad_Ychar', '%Nomad_Ymax', '%Scr_Def_Attr$',
+ '%Scr_Def_H_Fl$', '%Scr_Def_H_Id$', '%Scr_Lib', '%Scr_Lib$',
+ '%Z__Usr_Sec$', 'Alternate_Panel$', 'Alternate_Panel_Type$',
+ 'Arg_1$', 'Arg_10$', 'Arg_11$', 'Arg_12$', 'Arg_13$', 'Arg_14$',
+ 'Arg_15$', 'Arg_16$', 'Arg_17$', 'Arg_18$', 'Arg_19$', 'Arg_2$',
+ 'Arg_20$', 'Arg_3$', 'Arg_4$', 'Arg_5$', 'Arg_6$', 'Arg_7$',
+ 'Arg_8$', 'Arg_9$', 'Change_Flg', 'Cmd_Str$', 'Default_Prog$',
+ 'Disp_Cmd$', 'Entire_Record$', 'Exit_Cmd$', 'Fldr_Default_Prog$',
+ 'Folder_Id$', 'Id', 'Id$', 'Ignore_Exit', 'Initialize_Flg',
+ 'Init_Text$', 'Init_Val$', 'Main_Scrn_K$', 'Mnu_Ln$',
+ 'Next_Folder', 'Next_Id', 'Next_Id$', 'No_Flush', 'Prime_Key$',
+ 'Prior_Val', 'Prior_Val$', 'Qry_Val$', 'Refresh_Flg',
+ 'Replacement_Folder$', 'Replacement_Lib$', 'Replacement_Scrn$',
+ 'Scrn_Id$', 'Scrn_K$', 'Scrn_Lib$', 'Tab_Table$', '_Eom$'
+ ),
+ 5 => array(
+ // Mnemonics
+ "'!w'", "'*c'", "'*h'", "'*i'", "'*o'", "'*r'", "'*x'",
+ "'+b'", "'+d'", "'+e'", "'+f'", "'+i'", "'+n'",
+ "'+p'", "'+s'", "'+t'", "'+u'", "'+v'", "'+w'", "'+x'",
+ "'+z'", "'-b'", "'-d'", "'-e'", "'-f'", "'-i'",
+ "'-n'", "'-p'", "'-s'", "'-t'", "'-u'", "'-v'", "'-w'",
+ "'-x'", "'-z'", "'2d'", "'3d'", "'4d'", "'@@'", "'ab'",
+ "'arc'", "'at'", "'backgr'", "'bb'", "'be'", "'beep'",
+ "'bg'", "'bi'", "'bj'", "'bk'", "'black'", "'blue'",
+ "'bm'", "'bo'", "'box'", "'br'", "'bs'", "'bt'", "'bu'",
+ "'bw'", "'bx'", "'caption'", "'ce'", "'cf'", "'ch'",
+ "'ci'", "'circle'", "'cl'", "'colour'", "'cp'", "'cpi'",
+ "'cr'", "'cs'", "'cursor'", "'cyan''_cyan'", "'dc'",
+ "'default'", "'df'", "'dialogue'", "'dn'", "'do'",
+ "'drop'", "'eb'", "'ee'", "'ef'", "'eg'", "'ei'", "'ej'",
+ "'el'", "'em'", "'eo'", "'ep'", "'er'", "'es'", "'et'",
+ "'eu'", "'ew'", "'ff'", "'fill'", "'fl'", "'font'",
+ "'frame'", "'gd'", "'ge'", "'gf'", "'goto'", "'green'",
+ "'gs'", "'hide'", "'ic'", "'image'", "'jc'",
+ "'jd'", "'jl'", "'jn'", "'jr'", "'js'", "'l6'", "'l8'",
+ "'lc'", "'ld'", "'lf'", "'li'", "'line'", "'lm'",
+ "'lpi'", "'lt'", "'magenta'", "'maxsize'", "'me'",
+ "'message'", "'minsize'", "'mn'", "'mode'",
+ "'move'", "'mp'", "'ms'", "'ni'", "'offset'", "'option'",
+ "'pe'", "'pen'", "'picture'", "'pie'", "'pm'", "'polygon'",
+ "'pop'", "'ps'", "'push'", "'rb'", "'rc'", "'rectangle'",
+ "'red'", "'rl'", "'rm'", "'rp'", "'rs'", "'rt'", "'sb'",
+ "'scroll'", "'sd'", "'se'", "'sf'", "'show'", "'size'",
+ "'sl'", "'sn'", "'sp'", "'sr'", "'swap'", "'sx'", "'text'",
+ "'textwdw'", "'tr'", "'tw'", "'uc'", "'up'", "'vt'", "'wa'",
+ "'wc'", "'wd'", "'wg'", "'white'", "'window'", "'wm'",
+ "'wp'", "'wr'", "'wrap'", "'ws'", "'wx'", "'xp'", "'yellow'",
+ "'zx'", "'_black'", "'_blue'", "'_colour'", "'_green'",
+ "'_magenta'", "'_red'", "'_white'", "'_yellow'"
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('+', '-', '*', '/', '^', '|'),
+ 1 => array('++', '--', '+=', '-=', '*=', '/=', '^=', '|='),
+ 2 => array('&lt;', '&gt;', '='),
+ 3 => array('(', ')', '[', ']', '{', '}'),
+ 4 => array(',', '@', ';', '\\')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: navy;', // Directives
+ 2 => 'color: blue;', // System Functions
+ 3 => 'color: blue;', // System Variables
+ 4 => 'color: #6A5ACD; font-style: italic;', // Nomads Global Variables
+ 5 => 'color: #BDB76B;', // Mnemonics
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008080; font-style: italic;',
+ 2 => 'color: #008080;',
+ 'MULTI' => 'color: #008080; font-style: italic;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: green;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #00008B;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;',
+ 1 => 'color: #000099;',
+ 2 => 'color: #000099;',
+ 3 => 'color: #0000C9;',
+ 4 => 'color: #000099;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #006400; font-weight: bold',
+ 2 => 'color: #6A5ACD;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.allbasic.info./wiki/index.php/PX:Directive_{FNAME}',
+ 2 => 'http://www.allbasic.info./wiki/index.php/PX:System_function_{FNAME}',
+ 3 => 'http://www.allbasic.info./wiki/index.php/PX:System_variable_{FNAME}',
+ 4 => 'http://www.allbasic.info./wiki/index.php/PX:Nomads_{FNAME}',
+ 5 => 'http://www.allbasic.info./wiki/index.php/PX:Mnemonic_{FNAMEU}'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => "'"
+ ),
+ 'REGEXPS' => array(
+ 1 => array(
+ // Line Labels
+ GESHI_SEARCH => '([[:space:]])([a-zA-Z_][a-zA-Z0-9_]+)(:)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ 2 => array(
+ // Global String Variables
+ GESHI_SEARCH => '(\%)([a-zA-Z_][a-zA-Z0-9_]+)(\$)',
+ GESHI_REPLACE => '\\1\\2\\3',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'NUMBERS' => GESHI_NEVER
+ )
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/purebasic.php b/platform/www/vendor/geshi/geshi/src/geshi/purebasic.php
new file mode 100644
index 0000000..8b9b65e
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/purebasic.php
@@ -0,0 +1,301 @@
+<?php
+/*************************************************************************************
+ * purebasic.php
+ * -------
+ * Author: GuShH
+ * Copyright: (c) 2009 Gustavo Julio Fiorenza
+ * Release Version: 1.0.9.1
+ * Date Started: 13/06/2009
+ *
+ * PureBasic language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 13/06/2009 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2009/06/13)
+ * -------------------------
+ * Add the remaining ASM mnemonics and the 4.3x functions/etc.
+ * Better coloring (perhaps match the default scheme of PB?)
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'PureBasic',
+ 'COMMENT_SINGLE' => array( 1 => ";" ),
+ 'COMMENT_MULTI' => array( ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ // Keywords
+ 'And', 'As', 'Break', 'CallDebugger', 'Case', 'CompilerCase', 'CompilerDefault', 'CompilerElse', 'CompilerEndIf', 'CompilerEndSelect',
+ 'CompilerError', 'CompilerIf', 'CompilerSelect', 'Continue', 'Data', 'DataSection', 'EndDataSection', 'Debug', 'DebugLevel', 'Declare',
+ 'DeclareCDLL', 'DeclareDLL', 'Default', 'Define', 'Dim', 'DisableASM', 'DisableDebugger', 'DisableExplicit', 'Else', 'ElseIf', 'EnableASM',
+ 'EnableDebugger', 'EnableExplicit', 'End', 'EndEnumeration', 'EndIf', 'EndImport', 'EndInterface', 'EndMacro', 'EndProcedure',
+ 'EndSelect', 'EndStructure', 'EndStructureUnion', 'EndWith', 'Enumeration', 'Extends', 'FakeReturn', 'For', 'Next', 'ForEach',
+ 'ForEver', 'Global', 'Gosub', 'Goto', 'If', 'Import', 'ImportC', 'IncludeBinary', 'IncludeFile', 'IncludePath', 'Interface', 'Macro',
+ 'NewList', 'Not', 'Or', 'Procedure', 'ProcedureC', 'ProcedureCDLL', 'ProcedureDLL', 'ProcedureReturn', 'Protected', 'Prototype',
+ 'PrototypeC', 'Read', 'ReDim', 'Repeat', 'Until', 'Restore', 'Return', 'Select', 'Shared', 'Static', 'Step', 'Structure', 'StructureUnion',
+ 'Swap', 'To', 'Wend', 'While', 'With', 'XIncludeFile', 'XOr'
+ ),
+ 2 => array(
+ // All Functions
+ 'Abs', 'ACos', 'Add3DArchive', 'AddBillboard', 'AddDate', 'AddElement', 'AddGadgetColumn', 'AddGadgetItem',
+ 'AddKeyboardShortcut', 'AddMaterialLayer', 'AddPackFile', 'AddPackMemory', 'AddStatusBarField', 'AddSysTrayIcon',
+ 'AllocateMemory', 'AmbientColor', 'AnimateEntity', 'Asc', 'ASin', 'ATan', 'AudioCDLength', 'AudioCDName', 'AudioCDStatus',
+ 'AudioCDTrackLength', 'AudioCDTracks', 'AudioCDTrackSeconds', 'AvailableProgramOutput', 'AvailableScreenMemory',
+ 'BackColor', 'Base64Decoder', 'Base64Encoder', 'BillboardGroupLocate', 'BillboardGroupMaterial', 'BillboardGroupX',
+ 'BillboardGroupY', 'BillboardGroupZ', 'BillboardHeight', 'BillboardLocate', 'BillboardWidth', 'BillboardX', 'BillboardY', 'BillboardZ',
+ 'Bin', 'BinQ', 'Blue', 'Box', 'ButtonGadget', 'ButtonImageGadget', 'CalendarGadget', 'CallCFunction', 'CallCFunctionFast',
+ 'CallFunction', 'CallFunctionFast', 'CameraBackColor', 'CameraFOV', 'CameraLocate', 'CameraLookAt', 'CameraProjection',
+ 'CameraRange', 'CameraRenderMode', 'CameraX', 'CameraY', 'CameraZ', 'CatchImage', 'CatchSound', 'CatchSprite',
+ 'CatchXML', 'ChangeAlphaIntensity', 'ChangeCurrentElement', 'ChangeGamma', 'ChangeListIconGadgetDisplay',
+ 'ChangeSysTrayIcon', 'CheckBoxGadget', 'CheckEntityCollision', 'CheckFilename', 'ChildXMLNode', 'Chr', 'Circle',
+ 'ClearBillboards', 'ClearClipboard', 'ClearConsole', 'ClearError', 'ClearGadgetItemList', 'ClearList', 'ClearScreen', 'ClipSprite',
+ 'CloseConsole', 'CloseDatabase', 'CloseFile', 'CloseGadgetList', 'CloseHelp', 'CloseLibrary', 'CloseNetworkConnection',
+ 'CloseNetworkServer', 'ClosePack', 'ClosePreferences', 'CloseProgram', 'CloseScreen', 'CloseSubMenu', 'CloseWindow',
+ 'ColorRequester', 'ComboBoxGadget', 'CompareMemory', 'CompareMemoryString', 'ConnectionID', 'ConsoleColor',
+ 'ConsoleCursor', 'ConsoleError', 'ConsoleLocate', 'ConsoleTitle', 'ContainerGadget', 'CopyDirectory', 'CopyEntity',
+ 'CopyFile', 'CopyImage', 'CopyLight', 'CopyMaterial', 'CopyMemory', 'CopyMemoryString', 'CopyMesh', 'CopySprite',
+ 'CopyTexture', 'CopyXMLNode', 'Cos', 'CountBillboards', 'CountGadgetItems', 'CountLibraryFunctions', 'CountList',
+ 'CountMaterialLayers', 'CountProgramParameters', 'CountRenderedTriangles', 'CountString', 'CRC32Fingerprint',
+ 'CreateBillboardGroup', 'CreateCamera', 'CreateDirectory', 'CreateEntity', 'CreateFile', 'CreateGadgetList',
+ 'CreateImage', 'CreateLight', 'CreateMaterial', 'CreateMenu', 'CreateMesh', 'CreateMutex', 'CreateNetworkServer',
+ 'CreatePack', 'CreatePalette', 'CreateParticleEmitter', 'CreatePopupMenu', 'CreatePreferences', 'CreateSprite',
+ 'CreateSprite3D', 'CreateStatusBar', 'CreateTerrain', 'CreateTexture', 'CreateThread', 'CreateToolBar', 'CreateXML',
+ 'CreateXMLNode', 'DatabaseColumnName', 'DatabaseColumns', 'DatabaseColumnType', 'DatabaseDriverDescription',
+ 'DatabaseDriverName', 'DatabaseError', 'DatabaseQuery', 'DatabaseUpdate', 'Date', 'DateGadget', 'Day', 'DayOfWeek',
+ 'DayOfYear', 'DefaultPrinter', 'Defined', 'Delay', 'DeleteDirectory', 'DeleteElement', 'DeleteFile', 'DeleteXMLNode',
+ 'DESFingerprint', 'DesktopDepth', 'DesktopFrequency', 'DesktopHeight', 'DesktopMouseX', 'DesktopMouseY', 'DesktopName',
+ 'DesktopWidth', 'DirectoryEntryAttributes', 'DirectoryEntryDate', 'DirectoryEntryName', 'DirectoryEntrySize',
+ 'DirectoryEntryType', 'DisableGadget', 'DisableMaterialLighting', 'DisableMenuItem', 'DisableToolBarButton', 'DisableWindow',
+ 'DisASMCommand', 'DisplayAlphaSprite', 'DisplayPalette', 'DisplayPopupMenu', 'DisplayRGBFilter', 'DisplayShadowSprite',
+ 'DisplaySolidSprite', 'DisplaySprite', 'DisplaySprite3D', 'DisplayTranslucentSprite', 'DisplayTransparentSprite', 'DragFiles',
+ 'DragImage', 'DragOSFormats', 'DragPrivate', 'DragText', 'DrawAlphaImage', 'DrawImage', 'DrawingBuffer',
+ 'DrawingBufferPitch', 'DrawingBufferPixelFormat', 'DrawingFont', 'DrawingMode', 'DrawText', 'EditorGadget',
+ 'egrid_AddColumn', 'egrid_AddRows', 'egrid_AppendCells', 'egrid_ClearRows', 'egrid_CopyCells',
+ 'egrid_CreateCellCallback', 'egrid_CreateGrid', 'egrid_DeleteCells', 'egrid_FastDeleteCells', 'egrid_FreeGrid',
+ 'egrid_GetCellSelection', 'egrid_GetCellText', 'egrid_GetColumnOrderArray', 'egrid_HasSelectedCellChanged', 'egrid_Height',
+ 'egrid_HideEdit', 'egrid_HideGrid', 'egrid_MakeCellVisible', 'egrid_NumberOfColumns', 'egrid_NumberOfRows',
+ 'egrid_PasteCells', 'egrid_Register', 'egrid_RemoveCellCallback', 'egrid_RemoveColumn', 'egrid_RemoveRow', 'egrid_Resize',
+ 'egrid_SelectCell', 'egrid_SelectedColumn', 'egrid_SelectedRow', 'egrid_SetCellSelection', 'egrid_SetCellText',
+ 'egrid_SetColumnOrderArray', 'egrid_SetHeaderFont', 'egrid_SetHeaderHeight', 'egrid_SetOption', 'egrid_Width', 'egrid_x',
+ 'egrid_y', 'EjectAudioCD', 'ElapsedMilliseconds', 'Ellipse', 'EnableGadgetDrop', 'EnableGraphicalConsole',
+ 'EnableWindowDrop', 'EnableWorldCollisions', 'EnableWorldPhysics', 'Engine3DFrameRate', 'EntityAngleX',
+ 'EntityAnimationLength', 'EntityLocate', 'EntityMaterial', 'EntityMesh', 'EntityPhysicBody', 'EntityRenderMode',
+ 'EntityX', 'EntityY', 'EntityZ', 'EnvironmentVariableName', 'EnvironmentVariableValue', 'Eof', 'EventClient',
+ 'EventDropAction', 'EventDropBuffer', 'EventDropFiles', 'EventDropImage', 'EventDropPrivate', 'EventDropSize',
+ 'EventDropText', 'EventDropType', 'EventDropX', 'EventDropY', 'EventGadget', 'EventlParam', 'EventMenu', 'EventServer',
+ 'EventType', 'EventWindow', 'EventwParam', 'ExamineDatabaseDrivers', 'ExamineDesktops', 'ExamineDirectory',
+ 'ExamineEnvironmentVariables', 'ExamineIPAddresses', 'ExamineJoystick', 'ExamineKeyboard', 'ExamineLibraryFunctions',
+ 'ExamineMouse', 'ExaminePreferenceGroups', 'ExaminePreferenceKeys', 'ExamineScreenModes', 'ExamineWorldCollisions',
+ 'ExamineXMLAttributes', 'ExplorerComboGadget', 'ExplorerListGadget', 'ExplorerTreeGadget', 'ExportXML',
+ 'ExportXMLSize', 'FileBuffersSize', 'FileID', 'FileSeek', 'FileSize', 'FillArea', 'FindString', 'FinishDirectory',
+ 'FirstDatabaseRow', 'FirstElement', 'FirstWorldCollisionEntity', 'FlipBuffers', 'FlushFileBuffers', 'Fog', 'FontID',
+ 'FontRequester', 'FormatDate', 'FormatXML', 'Frame3DGadget', 'FreeBillboardGroup', 'FreeCamera', 'FreeEntity',
+ 'FreeFont', 'FreeGadget', 'FreeImage', 'FreeLight', 'FreeMaterial', 'FreeMemory', 'FreeMenu', 'FreeMesh',
+ 'FreeModule', 'FreeMovie', 'FreeMutex', 'FreePalette', 'FreeParticleEmitter', 'FreeSound', 'FreeSprite',
+ 'FreeSprite3D', 'FreeStatusBar', 'FreeTexture', 'FreeToolBar', 'FreeXML', 'FrontColor', 'GadgetHeight', 'GadgetID',
+ 'GadgetItemID', 'GadgetToolTip', 'GadgetType', 'GadgetWidth', 'GadgetX', 'GadgetY', 'GetActiveGadget',
+ 'GetActiveWindow', 'GetClientIP', 'GetClientPort', 'GetClipboardImage', 'GetClipboardText', 'GetCurrentDirectory',
+ 'GetCurrentEIP', 'GetDatabaseDouble', 'GetDatabaseFloat', 'GetDatabaseLong', 'GetDatabaseQuad', 'GetDatabaseString',
+ 'GetDisASMString', 'GetEntityAnimationTime', 'GetEntityFriction', 'GetEntityMass', 'GetEnvironmentVariable',
+ 'GetErrorAddress', 'GetErrorCounter', 'GetErrorDescription', 'GetErrorDLL', 'GetErrorLineNR', 'GetErrorModuleName',
+ 'GetErrorNumber', 'GetErrorRegister', 'GetExtensionPart', 'GetFileAttributes', 'GetFileDate', 'GetFilePart', 'GetFunction',
+ 'GetFunctionEntry', 'GetGadgetAttribute', 'GetGadgetColor', 'GetGadgetData', 'GetGadgetFont',
+ 'GetGadgetItemAttribute', 'GetGadgetItemColor', 'GetGadgetItemData', 'GetGadgetItemState', 'GetGadgetItemText',
+ 'GetGadgetState', 'GetGadgetText', 'GetHomeDirectory', 'GetMenuItemState', 'GetMenuItemText', 'GetMenuTitleText',
+ 'GetModulePosition', 'GetModuleRow', 'GetPaletteColor', 'GetPathPart', 'GetTemporaryDirectory',
+ 'GetToolBarButtonState', 'GetWindowColor', 'GetWindowState', 'GetWindowTitle', 'GetXMLAttribute', 'GetXMLEncoding',
+ 'GetXMLNodeName', 'GetXMLNodeOffset', 'GetXMLNodeText', 'GetXMLStandalone', 'GoToEIP', 'GrabImage', 'GrabSprite',
+ 'Green', 'Hex', 'HexQ', 'HideBillboardGroup', 'HideEntity', 'HideGadget', 'HideLight', 'HideMenu', 'HideParticleEmitter',
+ 'HideWindow', 'Hostname', 'Hour', 'HyperLinkGadget', 'ImageDepth', 'ImageGadget', 'ImageHeight', 'ImageID',
+ 'ImageOutput', 'ImageWidth', 'InitAudioCD', 'InitEngine3D', 'InitJoystick', 'InitKeyboard', 'InitMouse', 'InitMovie',
+ 'InitNetwork', 'InitPalette', 'InitScintilla', 'InitSound', 'InitSprite', 'InitSprite3D', 'Inkey', 'Input', 'InputRequester',
+ 'InsertElement', 'Int', 'IntQ', 'IPAddressField', 'IPAddressGadget', 'IPString', 'IsBillboardGroup', 'IsCamera', 'IsDatabase',
+ 'IsDirectory', 'IsEntity', 'IsFile', 'IsFont', 'IsGadget', 'IsImage', 'IsLibrary', 'IsLight', 'IsMaterial', 'IsMenu', 'IsMesh',
+ 'IsModule', 'IsMovie', 'IsPalette', 'IsParticleEmitter', 'IsProgram', 'IsScreenActive', 'IsSound', 'IsSprite', 'IsSprite3D',
+ 'IsStatusBar', 'IsSysTrayIcon', 'IsTexture', 'IsThread', 'IsToolBar', 'IsWindow', 'IsXML', 'JoystickAxisX', 'JoystickAxisY',
+ 'JoystickButton', 'KeyboardInkey', 'KeyboardMode', 'KeyboardPushed', 'KeyboardReleased', 'KillProgram', 'KillThread',
+ 'LastElement', 'LCase', 'Left', 'Len', 'LibraryFunctionAddress', 'LibraryFunctionName', 'LibraryID', 'LightColor',
+ 'LightLocate', 'LightSpecularColor', 'Line', 'LineXY', 'ListIconGadget', 'ListIndex', 'ListViewGadget', 'LoadFont',
+ 'LoadImage', 'LoadMesh', 'LoadModule', 'LoadMovie', 'LoadPalette', 'LoadSound', 'LoadSprite', 'LoadTexture',
+ 'LoadWorld', 'LoadXML', 'Loc', 'LockMutex', 'Lof', 'Log', 'Log10', 'LSet', 'LTrim', 'MainXMLNode', 'MakeIPAddress',
+ 'MaterialAmbientColor', 'MaterialBlendingMode', 'MaterialDiffuseColor', 'MaterialFilteringMode', 'MaterialID',
+ 'MaterialShadingMode', 'MaterialSpecularColor', 'MD5FileFingerprint', 'MD5Fingerprint', 'MDIGadget', 'MemorySize',
+ 'MemoryStringLength', 'MenuBar', 'MenuHeight', 'MenuID', 'MenuItem', 'MenuTitle', 'MeshID', 'MessageRequester',
+ 'Mid', 'Minute', 'ModuleVolume', 'Month', 'MouseButton', 'MouseDeltaX', 'MouseDeltaY', 'MouseLocate', 'MouseWheel',
+ 'MouseX', 'MouseY', 'MoveBillboard', 'MoveBillboardGroup', 'MoveCamera', 'MoveEntity', 'MoveLight', 'MoveMemory',
+ 'MoveParticleEmitter', 'MoveXMLNode', 'MovieAudio', 'MovieHeight', 'MovieInfo', 'MovieLength', 'MovieSeek',
+ 'MovieStatus', 'MovieWidth', 'NetworkClientEvent', 'NetworkServerEvent', 'NewPrinterPage', 'NextDatabaseDriver',
+ 'NextDatabaseRow', 'NextDirectoryEntry', 'NextElement', 'NextEnvironmentVariable', 'NextIPAddress',
+ 'NextLibraryFunction', 'NextPackFile', 'NextPreferenceGroup', 'NextPreferenceKey', 'NextScreenMode',
+ 'NextSelectedFileName', 'NextWorldCollision', 'NextXMLAttribute', 'NextXMLNode', 'OffsetOf', 'OnErrorExit',
+ 'OnErrorGosub', 'OnErrorGoto', 'OnErrorResume', 'OpenComPort', 'OpenConsole', 'OpenDatabase',
+ 'OpenDatabaseRequester', 'OpenFile', 'OpenFileRequester', 'OpenGadgetList', 'OpenHelp', 'OpenLibrary',
+ 'OpenNetworkConnection', 'OpenPack', 'OpenPreferences', 'OpenScreen', 'OpenSubMenu', 'OpenWindow',
+ 'OpenWindowedScreen', 'OptionGadget', 'OSVersion', 'PackerCallback', 'PackFileSize', 'PackMemory', 'PanelGadget',
+ 'ParentXMLNode', 'Parse3DScripts', 'ParseDate', 'ParticleColorFader', 'ParticleColorRange', 'ParticleEmissionRate',
+ 'ParticleEmitterDirection', 'ParticleEmitterLocate', 'ParticleEmitterX', 'ParticleEmitterY', 'ParticleEmitterZ',
+ 'ParticleMaterial', 'ParticleSize', 'ParticleTimeToLive', 'ParticleVelocity', 'PathRequester', 'PauseAudioCD',
+ 'PauseMovie', 'PauseThread', 'PeekB', 'PeekC', 'PeekD', 'PeekF', 'PeekL', 'PeekQ', 'PeekS', 'PeekW', 'PlayAudioCD',
+ 'PlayModule', 'PlayMovie', 'PlaySound', 'Plot', 'Point', 'PokeB', 'PokeC', 'PokeD', 'PokeF', 'PokeL', 'PokeQ', 'PokeS',
+ 'PokeW', 'Pow', 'PreferenceComment', 'PreferenceGroup', 'PreferenceGroupName', 'PreferenceKeyName',
+ 'PreferenceKeyValue', 'PreviousDatabaseRow', 'PreviousElement', 'PreviousXMLNode', 'Print', 'PrinterOutput',
+ 'PrinterPageHeight', 'PrinterPageWidth', 'PrintN', 'PrintRequester', 'ProgramExitCode', 'ProgramFilename',
+ 'ProgramID', 'ProgramParameter', 'ProgramRunning', 'ProgressBarGadget', 'Random', 'RandomSeed', 'RawKey',
+ 'ReadByte', 'ReadCharacter', 'ReadConsoleData', 'ReadData', 'ReadDouble', 'ReadFile', 'ReadFloat', 'ReadLong',
+ 'ReadPreferenceDouble', 'ReadPreferenceFloat', 'ReadPreferenceLong', 'ReadPreferenceQuad',
+ 'ReadPreferenceString', 'ReadProgramData', 'ReadProgramError', 'ReadProgramString', 'ReadQuad', 'ReadString',
+ 'ReadStringFormat', 'ReadWord', 'ReAllocateMemory', 'ReceiveNetworkData', 'ReceiveNetworkFile', 'Red',
+ 'Reg_DeleteEmptyKey', 'Reg_DeleteKey', 'Reg_DeleteValue', 'Reg_GetErrorMsg', 'Reg_GetErrorNr',
+ 'Reg_GetValueTyp', 'Reg_ListSubKey', 'Reg_ListSubValue', 'Reg_ReadBinary', 'Reg_ReadExpandString',
+ 'Reg_ReadLong', 'Reg_ReadMultiLineString', 'Reg_ReadQuad', 'Reg_ReadString', 'Reg_WriteBinary',
+ 'Reg_WriteExpandString', 'Reg_WriteLong', 'Reg_WriteMultiLineString', 'Reg_WriteQuad', 'Reg_WriteString',
+ 'ReleaseMouse', 'RemoveBillboard', 'RemoveEnvironmentVariable', 'RemoveGadgetColumn', 'RemoveGadgetItem',
+ 'RemoveKeyboardShortcut', 'RemoveMaterialLayer', 'RemovePreferenceGroup', 'RemovePreferenceKey',
+ 'RemoveString', 'RemoveSysTrayIcon', 'RemoveXMLAttribute', 'RenameFile', 'RenderMovieFrame', 'RenderWorld',
+ 'ReplaceString', 'ResetList', 'ResizeBillboard', 'ResizeEntity', 'ResizeGadget', 'ResizeImage', 'ResizeMovie',
+ 'ResizeParticleEmitter', 'ResizeWindow', 'ResolveXMLAttributeName', 'ResolveXMLNodeName', 'ResumeAudioCD',
+ 'ResumeMovie', 'ResumeThread', 'RGB', 'Right', 'RootXMLNode', 'RotateBillboardGroup', 'RotateCamera',
+ 'RotateEntity', 'RotateMaterial', 'RotateSprite3D', 'Round', 'RSet', 'RTrim', 'RunProgram', 'SaveFileRequester',
+ 'SaveImage', 'SaveSprite', 'SaveXML', 'ScaleEntity', 'ScaleMaterial', 'ScintillaGadget', 'ScintillaSendMessage',
+ 'ScreenID', 'ScreenModeDepth', 'ScreenModeHeight', 'ScreenModeRefreshRate', 'ScreenModeWidth',
+ 'ScreenOutput', 'ScrollAreaGadget', 'ScrollBarGadget', 'ScrollMaterial', 'Second', 'SecondWorldCollisionEntity',
+ 'SelectedFilePattern', 'SelectedFontColor', 'SelectedFontName', 'SelectedFontSize', 'SelectedFontStyle',
+ 'SelectElement', 'SendNetworkData', 'SendNetworkFile', 'SendNetworkString', 'SetActiveGadget',
+ 'SetActiveWindow', 'SetClipboardImage', 'SetClipboardText', 'SetCurrentDirectory', 'SetDragCallback',
+ 'SetDropCallback', 'SetEntityAnimationTime', 'SetEntityFriction', 'SetEntityMass', 'SetEnvironmentVariable',
+ 'SetErrorNumber', 'SetFileAttributes', 'SetFileDate', 'SetFrameRate', 'SetGadgetAttribute', 'SetGadgetColor',
+ 'SetGadgetData', 'SetGadgetFont', 'SetGadgetItemAttribute', 'SetGadgetItemColor', 'SetGadgetItemData',
+ 'SetGadgetItemState', 'SetGadgetItemText', 'SetGadgetState', 'SetGadgetText', 'SetMenuItemState',
+ 'SetMenuItemText', 'SetMenuTitleText', 'SetMeshData', 'SetModulePosition', 'SetPaletteColor', 'SetRefreshRate',
+ 'SetToolBarButtonState', 'SetWindowCallback', 'SetWindowColor', 'SetWindowState', 'SetWindowTitle',
+ 'SetXMLAttribute', 'SetXMLEncoding', 'SetXMLNodeName', 'SetXMLNodeOffset', 'SetXMLNodeText',
+ 'SetXMLStandalone', 'Sin', 'SizeOf', 'SkyBox', 'SkyDome', 'SmartWindowRefresh', 'SortArray', 'SortList',
+ 'SortStructuredArray', 'SortStructuredList', 'SoundFrequency', 'SoundPan', 'SoundVolume', 'Space',
+ 'SpinGadget', 'SplitterGadget', 'Sprite3DBlendingMode', 'Sprite3DQuality', 'SpriteCollision', 'SpriteDepth',
+ 'SpriteHeight', 'SpriteID', 'SpriteOutput', 'SpritePixelCollision', 'SpriteWidth', 'Sqr', 'Start3D', 'StartDrawing',
+ 'StartPrinting', 'StartSpecialFX', 'StatusBarHeight', 'StatusBarIcon', 'StatusBarID', 'StatusBarText',
+ 'StickyWindow', 'Stop3D', 'StopAudioCD', 'StopDrawing', 'StopModule', 'StopMovie', 'StopPrinting',
+ 'StopSound', 'StopSpecialFX', 'Str', 'StrD', 'StrF', 'StringByteLength', 'StringField', 'StringGadget', 'StrQ',
+ 'StrU', 'Subsystem', 'SwapElements', 'SysTrayIconToolTip', 'Tan', 'TerrainHeight', 'TextGadget', 'TextHeight',
+ 'TextureHeight', 'TextureID', 'TextureOutput', 'TextureWidth', 'TextWidth', 'ThreadID', 'ThreadPriority',
+ 'ToolBarHeight', 'ToolBarID', 'ToolBarImageButton', 'ToolBarSeparator', 'ToolBarStandardButton',
+ 'ToolBarToolTip', 'TrackBarGadget', 'TransformSprite3D', 'TransparentSpriteColor', 'TreeGadget', 'Trim',
+ 'TruncateFile', 'TryLockMutex', 'UCase', 'UnlockMutex', 'UnpackMemory', 'UseAudioCD', 'UseBuffer',
+ 'UseGadgetList', 'UseJPEGImageDecoder', 'UseJPEGImageEncoder', 'UseODBCDatabase', 'UseOGGSoundDecoder',
+ 'UsePNGImageDecoder', 'UsePNGImageEncoder', 'UseTGAImageDecoder', 'UseTIFFImageDecoder', 'Val', 'ValD',
+ 'ValF', 'ValQ', 'WaitProgram', 'WaitThread', 'WaitWindowEvent', 'WebGadget', 'WebGadgetPath', 'WindowEvent',
+ 'WindowHeight', 'WindowID', 'WindowMouseX', 'WindowMouseY', 'WindowOutput', 'WindowWidth', 'WindowX',
+ 'WindowY', 'WorldGravity', 'WorldShadows', 'WriteByte', 'WriteCharacter', 'WriteConsoleData', 'WriteData',
+ 'WriteDouble', 'WriteFloat', 'WriteLong', 'WritePreferenceDouble', 'WritePreferenceFloat', 'WritePreferenceLong',
+ 'WritePreferenceQuad', 'WritePreferenceString', 'WriteProgramData', 'WriteProgramString', 'WriteProgramStringN',
+ 'WriteQuad', 'WriteString', 'WriteStringFormat', 'WriteStringN', 'WriteWord', 'XMLAttributeName', 'XMLAttributeValue',
+ 'XMLChildCount', 'XMLError', 'XMLErrorLine', 'XMLErrorPosition', 'XMLNodeFromID', 'XMLNodeFromPath', 'XMLNodePath',
+ 'XMLNodeType', 'XMLStatus', 'Year', 'ZoomSprite3D'
+ ),
+ 3 => array(
+ // some ASM instructions
+ 'AAA', 'AAD', 'AAM', 'AAS', 'ADC', 'ADD', 'AND', 'ARPL', 'BOUND', 'BSF', 'BSR', 'BSWAP', 'BT', 'BTC', 'BTR',
+ 'BTS', 'CALL', 'CBW', 'CDQ', 'CLC', 'CLD', 'CLI', 'CLTS', 'CMC', 'CMP', 'CMPS', 'CMPXCHG', 'CWD', 'CWDE',
+ 'DAA', 'DAS', 'DB', 'DD', 'DEC', 'DIV', 'DW', 'ENTER', 'ESC', 'F2XM1', 'FABS', 'FADD', 'FCHS', 'FCLEX',
+ 'FCOM', 'FDIV', 'FDIVR', 'FFREE', 'FINCSTP', 'FINIT', 'FLD', 'FLD1', 'FLDCW', 'FMUL', 'FNOP', 'FPATAN',
+ 'FPREM', 'FRNDINT', 'FSAVE', 'FSCALE', 'FSETPM', 'FSIN', 'FSQRT', 'FST', 'FSTENV', 'FSTSW', 'FSUB',
+ 'FSUBR', 'FTST', 'FUCOM', 'FWAIT', 'FXAM', 'FXCH', 'FXTRACT', 'FYL2X', 'FYL2XP1', 'HLT', 'IDIV', 'IMUL',
+ 'IN', 'INC', 'INS', 'INT', 'INTO', 'INVLPG', 'IRET', 'IRETD', 'JA', 'JAE', 'JB', 'JBE', 'JC', 'JCXZ', 'JE', 'JECXZ',
+ 'JG', 'JGE', 'JL', 'JLE', 'JMP', 'JNA', 'JNAE', 'JNB', 'JNBE', 'JNC', 'JNE', 'JNG', 'JNGE', 'JNL', 'JNLE', 'JNO', 'JNP',
+ 'JNS', 'JNZ', 'JO', 'JP', 'JPE', 'JPO', 'JS', 'JZ', 'LAHF', 'LAR', 'LDS', 'LEA', 'LEAVE', 'LES', 'LFS', 'LGDT', 'LGS',
+ 'LIDT', 'LLDT', 'LMSW', 'LOCK', 'LODS', 'LOOP', 'LOOPE', 'LOOPNE', 'LOOPNZ', 'LOOPZ', 'LSL', 'LSS', 'LTR',
+ 'MOV', 'MOVS', 'MOVSX', 'MOVZX', 'MUL', 'NEG', 'NOP', 'NOT', 'OR', 'OUT', 'OUTS', 'POP', 'POPA', 'POPAD',
+ 'POPF', 'POPFD', 'PUSH', 'PUSHA', 'PUSHAD', 'PUSHF', 'PUSHFD', 'RCL', 'RCR', 'REP', 'REPE', 'REPNE',
+ 'REPNZ', 'REPZ', 'RET', 'RETF', 'ROL', 'ROR', 'SAHF', 'SAL', 'SAR', 'SBB', 'SCAS', 'SETAE', 'SETB', 'SETBE',
+ 'SETC', 'SETE', 'SETG', 'SETGE', 'SETL', 'SETLE', 'SETNA', 'SETNAE', 'SETNB', 'SETNC', 'SETNE', 'SETNG',
+ 'SETNGE', 'SETNL', 'SETNLE', 'SETNO', 'SETNP', 'SETNS', 'SETNZ', 'SETO', 'SETP', 'SETPE', 'SETPO',
+ 'SETS', 'SETZ', 'SGDT', 'SHL', 'SHLD', 'SHR', 'SHRD', 'SIDT', 'SLDT', 'SMSW', 'STC', 'STD', 'STI',
+ 'STOS', 'STR', 'SUB', 'TEST', 'VERR', 'VERW', 'WAIT', 'WBINVD', 'XCHG', 'XLAT', 'XLATB', 'XOR'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '+', '-', '*', '/', '\\', '>', '<', '=', '<=', '>=', '&', '|', '!', '~', '<>', '>>', '<<', '%'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000066; font-weight: bold;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #000fff;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #ff0000; font-style: italic;',
+ 'MULTI' => 'color: #ff0000; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #CC0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '\\'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => false,
+ 1 => false
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/pycon.php b/platform/www/vendor/geshi/geshi/src/geshi/pycon.php
new file mode 100644
index 0000000..4e372ac
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/pycon.php
@@ -0,0 +1,62 @@
+<?php
+/*************************************************************************************
+ * python.php
+ * ----------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/30
+ *
+ * Python language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/12/18
+ * - Added missing functions and keywords. Also added two new Python 3.0 types. SF#2441839
+ * 2005/05/26
+ * - Modifications by Tim (tim@skreak.com): added more keyword categories, tweaked colors
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/08/30 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+//This
+require(dirname(__FILE__).'/python.php');
+
+$language_data['LANG_NAME'] = 'Python (console mode)';
+
+$language_data['STRICT_MODE_APPLIES'] = GESHI_ALWAYS;
+$language_data['SCRIPT_DELIMITERS'][-1] = '/^(>>>).*?$(?:\n\.\.\..*?$)*($)/m';
+$language_data['HIGHLIGHT_STRICT_BLOCK'][-1] = true;
+
+$language_data['STYLES']['SCRIPT'][-1] = 'color: #222222;';
+
+if(!isset($language_data['COMMENT_REGEXP'])) {
+ $language_data['COMMENT_REGEXP'] = array();
+}
+
+$language_data['COMMENT_REGEXP'][-1] = '/(?:^|\A\s)(?:>>>|\.\.\.)/m';
+$language_data['STYLES']['COMMENTS'][-1] = 'color: #444444;';
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/pys60.php b/platform/www/vendor/geshi/geshi/src/geshi/pys60.php
new file mode 100644
index 0000000..54a1f59
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/pys60.php
@@ -0,0 +1,271 @@
+<?php
+/**************************************************************************************
+ * pys60.php
+ * ----------
+ * Author: Sohan Basak (ronnie.basak96 @gmail.com)
+ * Copyright: (c) 2012 Sohan Basak (http://tothepower.tk), Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/05/03
+ *
+ * Python for S60 language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * No Changes Till Date
+ *
+ * The python.php file is extended to pys60.php with required modifications
+ *
+ * NOTES
+ *
+ * -I have kept the ":" in Reserved chars, so that it gets highlighted differently than brackets and/or symbols
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Python for S60',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'", '"""',"'''",'""','""'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+
+ /*
+ ** Set 1: reserved words
+ ** http://python.org/doc/current/ref/keywords.html
+ */
+ 1 => array(
+ 'and', 'del', 'for', 'is', 'raise', 'assert', 'elif', 'from', 'lambda', 'return', 'break',
+ 'else', 'global', 'not', 'try', 'class', 'except', 'if', 'or', 'while', 'continue', 'exec',
+ 'import', 'pass', 'yield', 'def', 'finally', 'in', 'print', "<<", ">>", "as"
+ ),
+
+ /*
+ ** Set 2: builtins
+ ** http://python.org/doc/current/lib/built-in-funcs.html
+ */
+ 2 => array(
+ '__import__', 'abs', 'basestring', 'bool', 'callable', 'chr', 'classmethod', 'cmp',
+ 'compile', 'complex', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile',
+ 'file', 'filter', 'float', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help',
+ 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'list', 'locals',
+ 'long', 'map', 'max', 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'range',
+ 'raw_input', 'reduce', 'reload', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice',
+ 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode',
+ 'vars', 'xrange', 'zip',
+ // Built-in constants: http://python.org/doc/current/lib/node35.html
+ 'False', 'True', 'None', 'NotImplemented', 'Ellipsis',
+ // Built-in Exceptions: http://python.org/doc/current/lib/module-exceptions.html
+ 'Exception', 'StandardError', 'ArithmeticError', 'LookupError', 'EnvironmentError',
+ 'AssertionError', 'AttributeError', 'EOFError', 'FloatingPointError', 'IOError',
+ 'ImportError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'MemoryError', 'NameError',
+ 'NotImplementedError', 'OSError', 'OverflowError', 'ReferenceError', 'RuntimeError',
+ 'StopIteration', 'SyntaxError', 'SystemError', 'SystemExit', 'TypeError',
+ 'UnboundlocalError', 'UnicodeError', 'UnicodeEncodeError', 'UnicodeDecodeError',
+ 'UnicodeTranslateError', 'ValueError', 'WindowsError', 'ZeroDivisionError', 'Warning',
+ 'UserWarning', 'DeprecationWarning', 'PendingDeprecationWarning', 'SyntaxWarning',
+ 'RuntimeWarning', 'FutureWarning',
+ //Symbian Errors
+ "SymbianError", "KernelError",
+ // self: this is a common python convention (but not a reserved word)
+ 'self'
+ ),
+
+ /*
+ ** Set 3: standard library
+ ** http://python.org/doc/current/lib/modindex.html
+ */
+ 3 => array(
+ '__builtin__', '__future__', '__main__', '_winreg', 'aifc', 'AL', 'al', 'anydbm',
+ 'array', 'asynchat', 'asyncore', 'atexit', 'audioop', 'base64', 'BaseHTTPServer',
+ 'Bastion', 'binascii', 'binhex', 'bisect', 'bsddb', 'bz2', 'calendar', 'cd', 'cgi',
+ 'CGIHTTPServer', 'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop',
+ 'collections', 'colorsys', 'commands', 'compileall', 'compiler',
+ 'ConfigParser', 'Cookie', 'cookielib', 'copy', 'copy_reg', 'cPickle', 'crypt',
+ 'cStringIO', 'csv', 'curses', 'datetime', 'dbhash', 'dbm', 'decimal', 'DEVICE',
+ 'difflib', 'dircache', 'dis', 'distutils', 'dl', 'doctest', 'DocXMLRPCServer', 'dumbdbm',
+ 'dummy_thread', 'dummy_threading', 'email', 'encodings', 'errno', 'exceptions', 'fcntl',
+ 'filecmp', 'fileinput', 'FL', 'fl', 'flp', 'fm', 'fnmatch', 'formatter', 'fpectl',
+ 'fpformat', 'ftplib', 'gc', 'gdbm', 'getopt', 'getpass', 'gettext', 'GL', 'gl', 'glob',
+ 'gopherlib', 'grp', 'gzip', 'heapq', 'hmac', 'hotshot', 'htmlentitydefs', 'htmllib',
+ 'HTMLParser', 'httplib', 'imageop', 'imaplib', 'imgfile', 'imghdr', 'imp', 'inspect',
+ 'itertools', 'jpeg', 'keyword', 'linecache', 'locale', 'logging', 'mailbox', 'mailcap',
+ 'marshal', 'math', 'md5', 'mhlib', 'mimetools', 'mimetypes', 'MimeWriter', 'mimify',
+ 'mmap', 'msvcrt', 'multifile', 'mutex', 'netrc', 'new', 'nis', 'nntplib', 'operator',
+ 'optparse', 'os', 'ossaudiodev', 'parser', 'pdb', 'pickle', 'pickletools', 'pipes',
+ 'pkgutil', 'platform', 'popen2', 'poplib', 'posix', 'posixfile', 'pprint', 'profile',
+ 'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc', 'Queue', 'quopri', 'random',
+ 're', 'readline', 'resource', 'rexec', 'rgbimg', 'rlcompleter',
+ 'robotparser', 'sched', 'ScrolledText', 'select', 'sets', 'sgmllib', 'sha', 'shelve',
+ 'shlex', 'shutil', 'signal', 'SimpleHTTPServer', 'SimpleXMLRPCServer', 'site', 'smtpd',
+ 'smtplib', 'sndhdr', 'socket', 'SocketServer', 'stat', 'statcache', 'statvfs', 'string',
+ 'StringIO', 'stringprep', 'struct', 'subprocess', 'sunau', 'SUNAUDIODEV', 'sunaudiodev',
+ 'symbol', 'sys', 'syslog', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'termios',
+ 'test', 'textwrap', 'thread', 'threading', 'time', 'timeit', 'Tix', 'Tkinter', 'token',
+ 'tokenize', 'traceback', 'tty', 'turtle', 'types', 'unicodedata', 'unittest', 'urllib2',
+ 'urllib', 'urlparse', 'user', 'UserDict', 'UserList', 'UserString', 'uu', 'warnings',
+ 'wave', 'weakref', 'webbrowser', 'whichdb', 'whrandom', 'winsound', 'xdrlib', 'xml',
+ 'xmllib', 'xmlrpclib', 'zipfile', 'zipimport', 'zlib', "os.path", "sys.path",
+
+ //PythonS60 Standard Library
+ //http://pys60.garage.maemo.org/doc/s60/
+ //These are the standard modules in the archive
+
+ "appuifw", "globalui","e32", "telephone", "aosocket", "btsocket",
+ "sysinfo","camera","graphics","keycapture","key_codes","topwindow", "gles",
+ "glcanvas","sensor", "audio","messaging", "inbox","location","positioning",
+ "contacts", "e32calendar", "e32db","e32dbm","logs","scriptext",
+ "series60_console",
+
+ //These are external but very often usable modules
+
+ "appuifw2","ArchetypeUI","elementtree","lightblue",
+ "activaprofile","Adjustor","akntextutils","aosocketnativenew",
+ "appreciation","applicationmanager","appswitch","atextit","bt_teror","btconsole",
+ "btswitch","cElementTree","cenrep","cerealizer","cl_gui","clipboard",
+ "clipboard_CHN","debugger","decompile2",
+ "dir_iter","download","easydb","ECenrep","Edit_find","efeature","elocation","envy",
+ "EProfile","erestart","error","esyagent","Execwap","exprofile","fastcamera",
+ "feature","fgimage","filebrowser","firmware","fold","fonts","fraction","FTP",
+ "ftplibnew","fy_manager","fy_menu","gles_utils","gps_location","hack",
+ "HTML2TXT","iapconnect","icon_image","image_decoder",
+ "ini","interactive_console","inting","key_modifiers","key_tricks","keypress",
+ "landmarks","lite_fm","locationacq","locationrequestor",
+ "logo","markupbase","mbm","mbm2","minidb","miniinfo","MISC",
+ "misty","Msg","ntpath","odict","Paintbox","pathinfo","pexif","pickcolor",
+ "powlite_fm","powlite_fm2","powlite_fm3","powlite_fme","prgbar","prodb",
+ "profileengine","progressbar","progressbartw","progressnotes",
+ "ProgressBarTW2","proshivka","py_upload","pyConnection","PyFileMan",
+ "pykeylock","PyPyc","pyqq","pys60crypto","pys60usb","rfc822",
+ "RUSOS","scmk","scrollpage","SISFIELDS","SISFIELD","sisfile",
+ "SISINFO","sisreader","Sistools","smidi","smsreject","speechy","sre_compile",
+ "sre_constants","sre_parse","sre","sysagent","syslang","TextMan",
+ "textrenderer","TextWrap","topwind","tsocket","uikludge","uikludges","uitricks",
+ "walkfile","wallpaper","wfm_lite",
+ "wif_keys","wif","window","wlanmgmt","wlantools","wt_color","wt_requesters",
+ "zhkey",
+
+ //These are recent additions
+ "miffile"
+ ),
+
+ /*
+ ** Set 4: special methods
+ ** http://python.org/doc/current/ref/specialnames.html
+ */
+ 4 => array(
+ ///*
+ //// Iterator types: http://python.org/doc/current/lib/typeiter.html
+ //'__iter__', 'next',
+ //// String types: http://python.org/doc/current/lib/string-methods.html
+ //'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs',
+ //'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle',
+ //'isupper', 'join', 'ljust', 'lower', 'lstrip', 'replace', 'rfind', 'rindex', 'rjust',
+ //'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title',
+ //'translate', 'upper', 'zfill',
+ // */
+
+ // Basic customization: http://python.org/doc/current/ref/customization.html
+ '__new__', '__init__', '__del__', '__repr__', '__str__',
+ '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__cmp__', '__rcmp__',
+ '__hash__', '__nonzero__', '__unicode__', '__dict__',
+ // Attribute access: http://python.org/doc/current/ref/attribute-access.html
+ '__setattr__', '__delattr__', '__getattr__', '__getattribute__', '__get__', '__set__',
+ '__delete__', '__slots__',
+ // Class creation, callable objects
+ '__metaclass__', '__call__',
+ // Container types: http://python.org/doc/current/ref/sequence-types.html
+ '__len__', '__getitem__', '__setitem__', '__delitem__', '__iter__', '__contains__',
+ '__getslice__', '__setslice__', '__delslice__',
+ // Numeric types: http://python.org/doc/current/ref/numeric-types.html
+ '__abs__','__add__','__and__','__coerce__','__div__','__divmod__','__float__',
+ '__hex__','__iadd__','__isub__','__imod__','__idiv__','__ipow__','__iand__',
+ '__ior__','__ixor__', '__ilshift__','__irshift__','__invert__','__int__',
+ '__long__','__lshift__',
+ '__mod__','__mul__','__neg__','__oct__','__or__','__pos__','__pow__',
+ '__radd__','__rdiv__','__rdivmod__','__rmod__','__rpow__','__rlshift__','__rrshift__',
+ '__rshift__','__rsub__','__rmul__','__rand__','__rxor__','__ror__',
+ '__sub__','__xor__'
+ )
+
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '*', '&', '%', '!', ';', '<', '>', '?', '`'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #006000;font-weight:bold;', // Reserved
+ 2 => 'color: #800950;font-size:105%', // Built-ins + self
+ 3 => 'color: #003399;font-size:106%', // Standard lib
+ 4 => 'color: #0000cd;' // Special methods
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style:italic;font-size:92%',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #930; font-weight: bold;font-size:105%'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: maroon;font-size:102%;padding:2px'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #666;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #2356F8;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: navy;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66ccFF;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/python.php b/platform/www/vendor/geshi/geshi/src/geshi/python.php
new file mode 100644
index 0000000..a34ed74
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/python.php
@@ -0,0 +1,242 @@
+<?php
+/*************************************************************************************
+ * python.php
+ * ----------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/30
+ *
+ * Python language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/12/18
+ * - Added missing functions and keywords. Also added two new Python 3.0 types. SF#2441839
+ * 2005/05/26
+ * - Modifications by Tim (tim@skreak.com): added more keyword categories, tweaked colors
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/08/30 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Python',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ //Longest quotemarks ALWAYS first
+ 'QUOTEMARKS' => array('"""', "'''", '"', "'"),
+ 'ESCAPE_CHAR' => '\\',
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX_0O | GESHI_NUMBER_HEX_PREFIX |
+ GESHI_NUMBER_FLT_NONSCI | GESHI_NUMBER_FLT_NONSCI_F |
+ GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+
+ /*
+ ** Set 1: reserved words
+ ** http://python.org/doc/current/ref/keywords.html
+ */
+ 1 => array(
+ 'and', 'del', 'for', 'is', 'raise', 'assert', 'elif', 'from', 'lambda', 'return', 'break',
+ 'else', 'global', 'not', 'try', 'class', 'except', 'if', 'or', 'while', 'continue', 'exec',
+ 'import', 'pass', 'yield', 'def', 'finally', 'in', 'print', 'with', 'as', 'nonlocal'
+ ),
+
+ /*
+ ** Set 2: builtins
+ ** http://python.org/doc/current/lib/built-in-funcs.html
+ */
+ 2 => array(
+ '__import__', 'abs', 'basestring', 'bool', 'callable', 'chr', 'classmethod', 'cmp',
+ 'compile', 'complex', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'execfile',
+ 'file', 'filter', 'float', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help',
+ 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'list', 'locals',
+ 'long', 'map', 'max', 'min', 'object', 'oct', 'open', 'ord', 'pow', 'property', 'range',
+ 'raw_input', 'reduce', 'reload', 'reversed', 'round', 'set', 'setattr', 'slice',
+ 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'unichr', 'unicode',
+ 'vars', 'xrange', 'zip',
+ // Built-in constants: http://python.org/doc/current/lib/node35.html
+ 'False', 'True', 'None', 'NotImplemented', 'Ellipsis',
+ // Built-in Exceptions: http://python.org/doc/current/lib/module-exceptions.html
+ 'Exception', 'StandardError', 'ArithmeticError', 'LookupError', 'EnvironmentError',
+ 'AssertionError', 'AttributeError', 'EOFError', 'FloatingPointError', 'IOError',
+ 'ImportError', 'IndexError', 'KeyError', 'KeyboardInterrupt', 'MemoryError', 'NameError',
+ 'NotImplementedError', 'OSError', 'OverflowError', 'ReferenceError', 'RuntimeError',
+ 'StopIteration', 'SyntaxError', 'SystemError', 'SystemExit', 'TypeError',
+ 'UnboundlocalError', 'UnicodeError', 'UnicodeEncodeError', 'UnicodeDecodeError',
+ 'UnicodeTranslateError', 'ValueError', 'WindowsError', 'ZeroDivisionError', 'Warning',
+ 'UserWarning', 'DeprecationWarning', 'PendingDeprecationWarning', 'SyntaxWarning',
+ 'RuntimeWarning', 'FutureWarning',
+ // self: this is a common python convention (but not a reserved word)
+ 'self',
+ // other
+ 'any', 'all'
+ ),
+
+ /*
+ ** Set 3: standard library
+ ** http://python.org/doc/current/lib/modindex.html
+ */
+ 3 => array(
+ '__builtin__', '__future__', '__main__', '_winreg', 'aifc', 'AL', 'al', 'anydbm',
+ 'array', 'asynchat', 'asyncore', 'atexit', 'audioop', 'base64', 'BaseHTTPServer',
+ 'Bastion', 'binascii', 'binhex', 'bisect', 'bsddb', 'bz2', 'calendar', 'cd', 'cgi',
+ 'CGIHTTPServer', 'cgitb', 'chunk', 'cmath', 'cmd', 'code', 'codecs', 'codeop',
+ 'collections', 'colorsys', 'commands', 'compileall', 'compiler',
+ 'ConfigParser', 'Cookie', 'cookielib', 'copy', 'copy_reg', 'cPickle', 'crypt',
+ 'cStringIO', 'csv', 'curses', 'datetime', 'dbhash', 'dbm', 'decimal', 'DEVICE',
+ 'difflib', 'dircache', 'dis', 'distutils', 'dl', 'doctest', 'DocXMLRPCServer', 'dumbdbm',
+ 'dummy_thread', 'dummy_threading', 'email', 'encodings', 'errno', 'exceptions', 'fcntl',
+ 'filecmp', 'fileinput', 'FL', 'fl', 'flp', 'fm', 'fnmatch', 'formatter', 'fpectl',
+ 'fpformat', 'ftplib', 'gc', 'gdbm', 'getopt', 'getpass', 'gettext', 'GL', 'gl', 'glob',
+ 'gopherlib', 'grp', 'gzip', 'heapq', 'hmac', 'hotshot', 'htmlentitydefs', 'htmllib',
+ 'HTMLParser', 'httplib', 'imageop', 'imaplib', 'imgfile', 'imghdr', 'imp', 'inspect',
+ 'itertools', 'jpeg', 'keyword', 'linecache', 'locale', 'logging', 'mailbox', 'mailcap',
+ 'marshal', 'math', 'md5', 'mhlib', 'mimetools', 'mimetypes', 'MimeWriter', 'mimify',
+ 'mmap', 'msvcrt', 'multifile', 'mutex', 'netrc', 'new', 'nis', 'nntplib', 'operator',
+ 'optparse', 'os', 'ossaudiodev', 'parser', 'pdb', 'pickle', 'pickletools', 'pipes',
+ 'pkgutil', 'platform', 'popen2', 'poplib', 'posix', 'posixfile', 'pprint', 'profile',
+ 'pstats', 'pty', 'pwd', 'py_compile', 'pyclbr', 'pydoc', 'Queue', 'quopri', 'random',
+ 're', 'readline', 'repr', 'resource', 'rexec', 'rfc822', 'rgbimg', 'rlcompleter',
+ 'robotparser', 'sched', 'ScrolledText', 'select', 'sets', 'sgmllib', 'sha', 'shelve',
+ 'shlex', 'shutil', 'signal', 'SimpleHTTPServer', 'SimpleXMLRPCServer', 'site', 'smtpd',
+ 'smtplib', 'sndhdr', 'socket', 'SocketServer', 'stat', 'statcache', 'statvfs', 'string',
+ 'StringIO', 'stringprep', 'struct', 'subprocess', 'sunau', 'SUNAUDIODEV', 'sunaudiodev',
+ 'symbol', 'sys', 'syslog', 'tabnanny', 'tarfile', 'telnetlib', 'tempfile', 'termios',
+ 'test', 'textwrap', 'thread', 'threading', 'time', 'timeit', 'Tix', 'Tkinter', 'token',
+ 'tokenize', 'traceback', 'tty', 'turtle', 'types', 'unicodedata', 'unittest', 'urllib2',
+ 'urllib', 'urlparse', 'user', 'UserDict', 'UserList', 'UserString', 'uu', 'warnings',
+ 'wave', 'weakref', 'webbrowser', 'whichdb', 'whrandom', 'winsound', 'xdrlib', 'xml',
+ 'xmllib', 'xmlrpclib', 'zipfile', 'zipimport', 'zlib',
+ // Python 3.0
+ 'bytes', 'bytearray'
+ ),
+
+ /*
+ ** Set 4: special methods
+ ** http://python.org/doc/current/ref/specialnames.html
+ */
+ 4 => array(
+ /*
+ // Iterator types: http://python.org/doc/current/lib/typeiter.html
+ '__iter__', 'next',
+ // String types: http://python.org/doc/current/lib/string-methods.html
+ 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs',
+ 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle',
+ 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'replace', 'rfind', 'rindex', 'rjust',
+ 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title',
+ 'translate', 'upper', 'zfill',
+ */
+ // Basic customization: http://python.org/doc/current/ref/customization.html
+ '__new__', '__init__', '__del__', '__repr__', '__str__',
+ '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__cmp__', '__rcmp__',
+ '__hash__', '__nonzero__', '__unicode__', '__dict__',
+ // Attribute access: http://python.org/doc/current/ref/attribute-access.html
+ '__setattr__', '__delattr__', '__getattr__', '__getattribute__', '__get__', '__set__',
+ '__delete__', '__slots__',
+ // Class creation, callable objects
+ '__metaclass__', '__call__',
+ // Container types: http://python.org/doc/current/ref/sequence-types.html
+ '__len__', '__getitem__', '__setitem__', '__delitem__', '__iter__', '__contains__',
+ '__getslice__', '__setslice__', '__delslice__',
+ // Numeric types: http://python.org/doc/current/ref/numeric-types.html
+ '__abs__','__add__','__and__','__coerce__','__div__','__divmod__','__float__',
+ '__hex__','__iadd__','__isub__','__imod__','__idiv__','__ipow__','__iand__',
+ '__ior__','__ixor__', '__ilshift__','__irshift__','__invert__','__int__',
+ '__long__','__lshift__',
+ '__mod__','__mul__','__neg__','__oct__','__or__','__pos__','__pow__',
+ '__radd__','__rdiv__','__rdivmod__','__rmod__','__rpow__','__rlshift__','__rrshift__',
+ '__rshift__','__rsub__','__rmul__','__rand__','__rxor__','__ror__',
+ '__sub__','__xor__'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '<', '>', '=', '!', '<=', '>=', //·comparison·operators
+ '~', '@', //·unary·operators
+ ';', ',' //·statement·separator
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #ff7700;font-weight:bold;', // Reserved
+ 2 => 'color: #008000;', // Built-ins + self
+ 3 => 'color: #dc143c;', // Standard lib
+ 4 => 'color: #0000cd;' // Special methods
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: black;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #483d8b;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff4500;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: black;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/q.php b/platform/www/vendor/geshi/geshi/src/geshi/q.php
new file mode 100644
index 0000000..a6b005d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/q.php
@@ -0,0 +1,147 @@
+<?php
+/*************************************************************************************
+ * q.php
+ * -----
+ * Author: Ian Roddis (ian.roddis@proteanmind.net)
+ * Copyright: (c) 2008 Ian Roddis (http://proteanmind.net)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/01/21
+ *
+ * q/kdb+ language file for GeSHi.
+ *
+ * Based on information available from code.kx.com
+ *
+ * CHANGES
+ * -------
+ * 2010/01/21 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated <1.0.0>)
+ * -------------------------
+ * - Fix the handling of single line comments
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'q/kdb+',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 2 => '/ \s\/.*/', # This needs to get fixed up, since it won't catch some instances
+ # Multi line comments (Moved from REGEXPS)
+ 3 => '/^\/\s*?\n.*?\n\\\s*?\n/smi'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 4,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'abs', 'acos', 'all', 'and', 'any', 'asc', 'asin', 'asof', 'atan', 'attr', 'avg', 'avgs', 'bin', 'ceiling',
+ 'cols', 'cor', 'cos', 'count', 'cov', 'cross', 'cut', 'deltas', 'desc', 'dev', 'differ', 'distinct',
+ 'div', 'each', 'enlist', 'eval', 'except', 'exec', 'exit', 'exp', 'fills', 'first', 'flip', 'floor',
+ 'fkeys', 'get', 'getenv', 'group', 'gtime', 'hclose', 'hcount', 'hdel', 'hopen', 'hsym', 'iasc', 'idesc',
+ 'in', 'insert', 'inter', 'inv', 'joins', 'key', 'keys', 'last', 'like', 'load', 'log', 'lower',
+ 'lsq', 'ltime', 'ltrim', 'mavg', 'max', 'maxs', 'mcount', 'md5', 'mdev', 'med', 'meta', 'min', 'mins',
+ 'mmax', 'mmin', 'mmu', 'mod', 'msum', 'neg', 'next', 'not', 'null', 'or', 'over', 'parse', 'peach',
+ 'plist', 'prd', 'prds', 'prev', 'rand', 'rank', 'ratios', 'raze', 'read0', 'read1', 'reciprocal',
+ 'reverse', 'rload', 'rotate', 'rsave', 'rtrim', 'save', 'scan', 'set', 'setenv', 'show', 'signum',
+ 'sin', 'sqrt', 'ss', 'ssr', 'string', 'sublist', 'sum', 'sums', 'sv', 'system', 'tables', 'tan', 'til', 'trim',
+ 'txf', 'type', 'ungroup', 'union', 'upper', 'upsert', 'value', 'var', 'view', 'views', 'vs',
+ 'wavg', 'within', 'wsum', 'xasc', 'xbar', 'xcol', 'xcols', 'xdesc', 'xexp', 'xgroup', 'xkey',
+ 'xlog', 'xprev', 'xrank'
+ ),
+ # kdb database template keywords
+ 2 => array(
+ 'aj', 'by', 'delete', 'fby', 'from', 'ij', 'lj', 'pj', 'select', 'uj', 'update', 'where', 'wj',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '?', '#', ',', '_', '@', '.', '^', '~', '$', '!', '\\', '\\', '/:', '\:', "'", "':", '::', '+', '-', '%', '*'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #009900; font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #666666; font-style: italic;',
+ 3 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #990000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ 2 => 'color: #999900;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'REGEXPS' => array(
+ # Symbols
+ 2 => '`[^\s"]*',
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ ),
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/qbasic.php b/platform/www/vendor/geshi/geshi/src/geshi/qbasic.php
new file mode 100644
index 0000000..9f3be88
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/qbasic.php
@@ -0,0 +1,160 @@
+<?php
+/*************************************************************************************
+ * qbasic.php
+ * ----------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/20
+ *
+ * QBasic/QuickBASIC language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2004/11/27 (1.0.3)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ * - Added support for URLs
+ * 2004/08/05 (1.0.1)
+ * - Added support for symbols
+ * - Removed unnessecary slashes from some keywords
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Make sure all possible combinations of keywords with
+ * a space in them (EXIT FOR, END SELECT) are added
+ * to the first keyword group
+ * * Update colours, especially for the first keyword group
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+$language_data = array (
+ 'LANG_NAME' => 'QBasic/QuickBASIC',
+ 'COMMENT_SINGLE' => array(1 => "'"),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ //Single-Line Comments using REM command
+ 2 => "/\bREM.*?$/i",
+ //Line numbers
+ 3 => "/^\s*\d+/im"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT |
+ GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'DO', 'LOOP', 'WHILE', 'WEND', 'THEN', 'ELSE', 'ELSEIF', 'IF',
+ 'FOR', 'TO', 'NEXT', 'STEP', 'GOTO', 'GOSUB', 'CALL', 'CALLS',
+ 'SUB', 'FUNCTION', 'RETURN', 'RESUME', 'SELECT', 'CASE', 'UNTIL'
+ ),
+ 3 => array(
+ 'ABS', 'ABSOLUTE', 'ACCESS', 'ALIAS', 'AND', 'ANY', 'APPEND', 'AS', 'ASC', 'ATN',
+ 'BASE', 'BEEP', 'BINARY', 'BLOAD', 'BSAVE', 'BYVAL',
+ 'CDBL', 'CDECL', 'CHAIN', 'CHDIR', 'CHR$', 'CINT', 'CIRCLE', 'CLEAR',
+ 'CLNG', 'CLOSE', 'CLS', 'COM', 'COMMAND$', 'COMMON', 'CONST', 'COS', 'CSNG',
+ 'CSRLIN', 'CVD', 'CVDMBF', 'CVI', 'CVL', 'CVS', 'CVSMDF', 'DATA', 'DATE$',
+ 'DECLARE', 'DEF', 'FN', 'SEG', 'DEFDBL', 'DEFINT', 'DEFLNG', 'DEFSNG', 'DEFSTR',
+ 'DIM', 'DOUBLE', 'DRAW', 'END', 'ENVIRON', 'ENVIRON$', 'EOF', 'EQV', 'ERASE',
+ 'ERDEV', 'ERDEV$', 'ERL', 'ERR', 'ERROR', 'EXIT', 'EXP', 'FIELD', 'FILEATTR',
+ 'FILES', 'FIX', 'FRE', 'FREEFILE', 'GET', 'HEX$', 'IMP', 'INKEY$',
+ 'INP', 'INPUT', 'INPUT$', 'INSTR', 'INT', 'INTEGER', 'IOCTL', 'IOCTL$', 'IS',
+ 'KEY', 'KILL', 'LBOUND', 'LCASE$', 'LEFT$', 'LEN', 'LET', 'LINE', 'LIST', 'LOC',
+ 'LOCAL', 'LOCATE', 'LOCK', 'LOF', 'LOG', 'LONG', 'LPOS', 'LPRINT',
+ 'LSET', 'LTRIM$', 'MID$', 'MKD$', 'MKDIR', 'MKDMBF$', 'MKI$', 'MKL$',
+ 'MKS$', 'MKSMBF$', 'MOD', 'NAME', 'NOT', 'OCT$', 'OFF', 'ON', 'PEN', 'PLAY',
+ 'OPEN', 'OPTION', 'OR', 'OUT', 'OUTPUT',
+ 'PAINT', 'PALETTE', 'PCOPY', 'PEEK', 'PMAP', 'POINT', 'POKE', 'POS', 'PRESET',
+ 'PRINT', 'PSET', 'PUT', 'RANDOM', 'RANDOMIZE', 'READ', 'REDIM', 'RESET',
+ 'RESTORE', 'RIGHT$', 'RMDIR', 'RND', 'RSET', 'RTRIM$', 'RUN', 'SADD', 'SCREEN',
+ 'SEEK', 'SETMEM', 'SGN', 'SHARED', 'SHELL', 'SIGNAL', 'SIN', 'SINGLE', 'SLEEP',
+ 'SOUND', 'SPACE$', 'SPC', 'SQR', 'STATIC', 'STICK', 'STOP', 'STR$', 'STRIG',
+ 'STRING', 'STRING$', 'SWAP', 'SYSTEM', 'TAB', 'TAN', 'TIME$', 'TIMER',
+ 'TROFF', 'TRON', 'TYPE', 'UBOUND', 'UCASE$', 'UEVENT', 'UNLOCK', 'USING', 'VAL',
+ 'VARPTR', 'VARPTR$', 'VARSEG', 'VIEW', 'WAIT', 'WIDTH', 'WINDOW', 'WRITE', 'XOR'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', ',', '+', '-', '*', '/', '=', '<', '>', '^'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 3 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #a1a100;',
+ 3 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080;',
+ 2 => 'color: #808080;',
+ 3 => 'color: #8080C0;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #cc66cc;',
+ 2 => 'color: #339933;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 3 => 'http://www.qbasicnews.com/qboho/qck{FNAMEL}.shtml'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 1 => '&amp;(?:H[0-9a-fA-F]+|O[0-7]+)(?!\w)',
+ 2 => '#[0-9]+(?!\w)'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 8
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/qml.php b/platform/www/vendor/geshi/geshi/src/geshi/qml.php
new file mode 100644
index 0000000..fe89e45
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/qml.php
@@ -0,0 +1,351 @@
+<?php
+/*************************************************************************************
+ * qml.php
+ * --------------
+ * Author: J-P Nurmi <jpnurmi@gmail.com>
+ * Copyright: (c) 2012-2014 J-P Nurmi <jpnurmi@gmail.com>
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/08/19
+ *
+ * QML language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2014/06/29 (1.0.8.13)
+ * - Synced QML types from Qt 5.3:
+ * http://qt-project.org/doc/qt-5/modules-qml.html
+ * 2012/08/19
+ * - First version based on Qt 4
+ *
+ * TODO (updated 2014/06/29)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'QML',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ // comments
+ 2 => "/(?<=[\\s^])(s|tr|y)\\/(?!\*)(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])+(?<!\s)\\/(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])*(?<!\s)\\/[msixpogcde]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])(m|q[qrwx]?)?\\/(?!\*)(?!\s)(?:\\\\.|(?!\n)[^\\/\\\\])+(?<!\s)\\/[msixpogc]*(?=[\\s$\\.\\,\\;\\)])/iU",
+ // property binding
+ 3 => "/([a-z][\\w\\.]*)(?=:)/",
+ // TODO: property name (fixed length lookbehind assertion?)
+ 4 => "/(?<=property\\s+\\w+\\s+)(\\w+)/"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'as','alias','break','case','catch','continue','const','debugger',
+ 'default','delete','do','else','finally','for','function',
+ 'if','import','in','instanceof','new','on','public','property',
+ 'readonly','return','signal','switch','this','throw','try',
+ 'typeof','while','with'
+ ),
+ 2 => array(
+ 'action','bool','color','date','double','enumeration','font',
+ 'int','list','matrix4x4','point','quaternion','real','rect',
+ 'size','string','time','url','var','variant','vector2d',
+ 'vector3d','vector4d','void'
+ ),
+ // http://qt-project.org/doc/qt-5/qtbluetooth-qmlmodule.html
+ 3 => array(
+ 'BluetoothDiscoveryModel','BluetoothService','BluetoothSocket'
+ ),
+ // http://qt-project.org/doc/qt-5/qtgraphicaleffects-qmlmodule.html
+ 4 => array(
+ 'Blend','BrightnessContrast','ColorOverlay','Colorize',
+ 'ConicalGradient','Desaturate','DirectionalBlur','Displace',
+ 'DropShadow','FastBlur','GammaAdjust','GaussianBlur','Glow',
+ 'HueSaturation','InnerShadow','LevelAdjust','LinearGradient',
+ 'MaskedBlur','OpacityMask','RadialBlur','RadialGradient',
+ 'RectangularGlow','RecursiveBlur','ThresholdMask','ZoomBlur'
+ ),
+ // http://qt-project.org/doc/qt-5/qtaudioengine-qmlmodule.html
+ 5 => array(
+ 'AttenuationModelLinear','AttenuationModelInverse','AudioCategory',
+ 'AudioEngine','AudioListener','AudioSample','PlayVariation',
+ 'Sound','SoundInstance'
+ ),
+ // http://qt-project.org/doc/qt-5/qtmultimedia-qmlmodule.html
+ 6 => array(
+ 'Video','Audio','MediaPlayer','Camera','CameraCapture',
+ 'CameraExposure','CameraFlash','CameraFocus','CameraImageProcessing',
+ 'CameraRecorder','Radio','RadioData','Torch','SoundEffect','VideoOutput'
+ ),
+ // http://qt-project.org/doc/qt-5/qtnfc-qmlmodule.html
+ 7 => array(
+ 'NdefFilter','NdefMimeRecord','NdefTextRecord','NdefUriRecord',
+ 'NearField','NdefRecord'
+ ),
+ // http://qt-project.org/doc/qt-5/qtpositioning-qmlmodule.html
+ 8 => array(
+ 'QtPositioning','CoordinateAnimation','Position','PositionSource',
+ 'Address','Location'
+ ),
+ // http://qt-project.org/doc/qt-5/qtqml-models-qmlmodule.html
+ 9 => array(
+ 'DelegateModel','DelegateModelGroup','ListModel','ListElement','ObjectModel'
+ ),
+ // http://qt-project.org/doc/qt-5/qtqml-qmlmodule.html
+ 10 => array(
+ 'Binding','Component','Connections','Date','Instantiator',
+ 'Locale','Number','Qt','QtObject','String','Timer'
+ ),
+ // http://qt-project.org/doc/qt-5/qt-labs-folderlistmodel-qmlmodule.html
+ 11 => array(
+ 'FolderListModel'
+ ),
+ // http://qt-project.org/doc/qt-5/qtquick-localstorage-qmlmodule.html
+ 12 => array(
+ 'openDatabaseSync'
+ ),
+ // http://qt-project.org/doc/qt-5/qt-labs-settings-qmlmodule.html
+ 13 => array(
+ 'Settings'
+ ),
+ // http://qt-project.org/doc/qt-5/qtquick-window-qmlmodule.html
+ 14 => array(
+ 'Screen','Window','CloseEvent'
+ ),
+ // http://qt-project.org/doc/qt-5/qtquick-xmllistmodel-qmlmodule.html
+ 15 => array(
+ 'XmlRole','XmlListModel'
+ ),
+ // http://qt-project.org/doc/qt-5/qtquick-particles-qmlmodule.html
+ 16 => array(
+ 'Age','AngleDirection','CumulativeDirection','CustomParticle',
+ 'Direction','EllipseShape','Friction','Gravity','GroupGoal',
+ 'ImageParticle','ItemParticle','LineShape','MaskShape','Affector',
+ 'Emitter','Shape','ParticleGroup','ParticlePainter','ParticleSystem',
+ 'Attractor','PointDirection','RectangleShape','SpriteGoal',
+ 'TargetDirection','TrailEmitter','Turbulence','Particle','Wander'
+ ),
+ // http://qt-project.org/doc/qt-5/qttest-qmlmodule.html
+ 17 => array(
+ 'SignalSpy','TestCase'
+ ),
+ // http://qt-project.org/doc/qt-5/qtquick-qmltypereference.html
+ 18 => array(
+ 'Item','Rectangle','Image','BorderImage','AnimatedImage','AnimatedSprite',
+ 'SpriteSequence','Text','Accessible','Gradient','GradientStop','SystemPalette',
+ 'Sprite','FontLoader','Repeater','Loader','Visual Item Transformations','Transform',
+ 'Scale','Rotation','Translate','MouseArea','Keys','KeyNavigation','FocusScope',
+ 'Flickable','PinchArea','MultiPointTouchArea','Drag','DropArea','TextInput',
+ 'TextEdit','IntValidator','DoubleValidator','RegExpValidator','TouchPoint',
+ 'PinchEvent','WheelEvent','MouseEvent','KeyEvent','DragEvent','Positioner',
+ 'Column','Row','Grid','Flow','LayoutMirroring','State','PropertyChanges',
+ 'StateGroup','StateChangeScript','ParentChange','AnchorChanges','Transition',
+ 'ViewTransition','SequentialAnimation','ParallelAnimation','Behavior','PropertyAction',
+ 'PauseAnimation','SmoothedAnimation','SpringAnimation','ScriptAction','PropertyAnimation',
+ 'NumberAnimation','Vector3dAnimation','ColorAnimation','RotationAnimation','ParentAnimation',
+ 'AnchorAnimation','PathAnimation','XAnimator','YAnimator','ScaleAnimator','RotationAnimator',
+ 'OpacityAnimator','UniformAnimator','Lower-level Animation Types','PathInterpolator',
+ 'AnimationController','Path','PathLine','PathQuad','PathCubic','PathArc','PathCurve',
+ 'PathSvg','PathAttribute','PathPercent','VisualItemModel','VisualDataModel','VisualDataGroup',
+ 'ListView','GridView','PathView','Package','Flipable','ShaderEffect','ShaderEffectSource',
+ 'GridMesh','WorkerScript','Canvas','Context2D','CanvasGradient','CanvasPixelArray',
+ 'CanvasImageData','TextMetrics',
+ ),
+ // http://qt-project.org/doc/qt-5/qtquick-controls-qmlmodule.html
+ 19 => array(
+ 'ApplicationWindow','BusyIndicator','Button','Calendar',
+ 'CheckBox','ComboBox','GroupBox','Label','Menu','MenuBar',
+ 'ProgressBar','RadioButton','ScrollView','Slider','SpinBox',
+ 'SplitView','StackView','StackViewDelegate','StatusBar',
+ 'Switch','Tab','TabView','TableView','TableViewColumn',
+ 'TextArea','TextField','ToolBar','ToolButton','Action',
+ 'ExclusiveGroup','MenuSeparator','MenuItem','Stack'
+ ),
+ // http://qt-project.org/doc/qt-5/qtquick-dialogs-qmlmodule.html
+ 20 => array(
+ 'Dialog','ColorDialog','FileDialog','FontDialog','MessageDialog'
+ ),
+ // http://qt-project.org/doc/qt-5/qtquick-layouts-qmlmodule.html
+ 21 => array(
+ 'Layout','RowLayout','ColumnLayout','GridLayout'
+ ),
+ // http://qt-project.org/doc/qt-5/qtsensors-qmlmodule.html
+ 22 => array(
+ 'Accelerometer','AccelerometerReading','Altimeter','AltimeterReading',
+ 'AmbientLightReading','AmbientLightSensor','AmbientTemperatureReading',
+ 'AmbientTemperatureSensor','Compass','CompassReading','Gyroscope',
+ 'GyroscopeReading','HolsterReading','HolsterSensor','IRProximityReading',
+ 'IRProximitySensor','LightReading','LightSensor','Magnetometer',
+ 'MagnetometerReading','OrientationReading','OrientationSensor',
+ 'PressureReading','PressureSensor','ProximityReading','ProximitySensor',
+ 'RotationReading','RotationSensor','SensorGesture','SensorGlobal',
+ 'SensorReading','TapReading','TapSensor','TiltReading','TiltSensor'
+ ),
+ // http://qt-project.org/doc/qt-5/qtwinextras-qmlmodule.html
+ 23 => array(
+ 'JumpListDestination','JumpListLink','JumpListSeparator','DwmFeatures',
+ 'JumpList','JumpListCategory','TaskbarButton','ThumbnailToolBar','ThumbnailToolButton'
+ ),
+ // http://qt-project.org/doc/qt-5/qtwebkit-qmlmodule.html
+ 24 => array(
+ 'WebView','WebLoadRequest'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}',
+ '+', '-', '*', '/', '%',
+ '!', '@', '&', '|', '^',
+ '<', '>', '=',
+ ',', ';', '?', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true,
+ 10 => true,
+ 11 => true,
+ 12 => true,
+ 13 => true,
+ 14 => true,
+ 15 => true,
+ 16 => true,
+ 17 => true,
+ 18 => true,
+ 19 => true,
+ 20 => true,
+ 21 => true,
+ 22 => true,
+ 23 => true,
+ 24 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #808041;',
+ 2 => 'color: #808041;',
+ 3 => 'color: #800780;',
+ 4 => 'color: #800780;',
+ 5 => 'color: #800780;',
+ 6 => 'color: #800780;',
+ 7 => 'color: #800780;',
+ 8 => 'color: #800780;',
+ 9 => 'color: #800780;',
+ 10 => 'color: #800780;',
+ 11 => 'color: #800780;',
+ 12 => 'color: #800780;',
+ 13 => 'color: #800780;',
+ 14 => 'color: #800780;',
+ 15 => 'color: #800780;',
+ 16 => 'color: #800780;',
+ 17 => 'color: #800780;',
+ 18 => 'color: #800780;',
+ 19 => 'color: #800780;',
+ 20 => 'color: #800780;',
+ 21 => 'color: #800780;',
+ 22 => 'color: #800780;',
+ 23 => 'color: #800780;',
+ 24 => 'color: #800780;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008025;',
+ 2 => 'color: #008025;',
+ 3 => 'color: #970009;',
+ 4 => 'color: #970009;',
+ 'MULTI' => 'color: #008025;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #008025;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #000000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://qt-project.org/doc/qt-5/qml-qtbluetooth-{FNAMEL}.html',
+ 4 => 'http://qt-project.org/doc/qt-5/qml-qtgraphicaleffects-{FNAMEL}.html',
+ 5 => 'http://qt-project.org/doc/qt-5/qml-qtaudioengine-{FNAMEL}.html',
+ 6 => 'http://qt-project.org/doc/qt-5/qml-qtmultimedia-{FNAMEL}.html',
+ 7 => 'http://qt-project.org/doc/qt-5/qml-qtnfc-{FNAMEL}.html',
+ 8 => 'http://qt-project.org/doc/qt-5/qml-qtpositioning-{FNAMEL}.html',
+ 9 => 'http://qt-project.org/doc/qt-5/qml-qtqml-models-{FNAMEL}.html',
+ 10 => 'http://qt-project.org/doc/qt-5/qml-qtqml-{FNAMEL}.html',
+ 11 => 'http://qt-project.org/doc/qt-5/qml-qt-labs-folderlistmodel-{FNAMEL}.html',
+ 12 => 'http://qt-project.org/doc/qt-5/qtquick-localstorage-qmlmodule.html',
+ 13 => 'http://qt-project.org/doc/qt-5/qml-qt-labs-settings-{FNAMEL}.html',
+ 14 => 'http://qt-project.org/doc/qt-5/qml-qtquick-window-{FNAMEL}.html',
+ 15 => 'http://qt-project.org/doc/qt-5/qml-qtquick-xmllistmodel-{FNAMEL}.html',
+ 16 => 'http://qt-project.org/doc/qt-5/qml-qtquick-particles-{FNAMEL}.html',
+ 17 => 'http://qt-project.org/doc/qt-5/qml-qttest-{FNAMEL}.html',
+ 18 => 'http://qt-project.org/doc/qt-5/qml-qtquick-{FNAMEL}.html',
+ 19 => 'http://qt-project.org/doc/qt-5/qml-qtquick-controls-{FNAMEL}.html',
+ 20 => 'http://qt-project.org/doc/qt-5/qml-qtquick-dialogs-{FNAMEL}.html',
+ 21 => 'http://qt-project.org/doc/qt-5/qml-qtquick-layouts-{FNAMEL}.html',
+ 22 => 'http://qt-project.org/doc/qt-5/qml-qtsensors-{FNAMEL}.html',
+ 23 => 'http://qt-project.org/doc/qt-5/qml-qtwinextras-{FNAMEL}.html',
+ 24 => 'http://qt-project.org/doc/qt-5/qml-qtwebkit-{FNAMEL}.html'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<script type="text/javascript">' => '</script>'
+ ),
+ 1 => array(
+ '<script language="javascript">' => '</script>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/racket.php b/platform/www/vendor/geshi/geshi/src/geshi/racket.php
new file mode 100644
index 0000000..c26ea60
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/racket.php
@@ -0,0 +1,964 @@
+<?php
+/*************************************************************************************
+ * racket.php
+ * ----------
+ * Author: Tim Brown (tim@timb.net)
+ * Copyright: (c) 2013 Tim Brown ((https://github.com/tim-brown/geshi-racket))
+ * Release Version: 1.0.9.1
+ * Date Started: 2013-03-01
+ *
+ * Racket language file for GeSHi.
+ *
+ * This file was built automatically from the scripts in
+ * https://github.com/tim-brown/geshi-racket (you didn't think
+ * I typed those NUMBER regular expressions in myself, did you?).
+ * Use those scripts to regenerate the file.
+ *
+ * CHANGES
+ * -------
+ * 1.0 (2013-03-31)
+ * - Initial Release1.1 (2013-03-31)
+ * - Added URLs, "symbol"-like identifiers moved to SYMBOLS*
+ *
+ * TODO (updated 2013-04-25)
+ * -------------------------
+ * * better handling of empty and short arrays
+ * * care more about indentation and line lengths
+ * * most compound regexps are possibly over-bracketed: (or ...)
+ * * most compound regexps are possibly over-bracketed: (: ...)
+ * * URLs should be formed more smartly by discovering which module they came from.
+ * * '|...| identifiers
+ * * #<<HERE strings
+ * * #;(...) comments -- (note: requires balanced parenthesis regexp)
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Racket',
+ 'COMMENT_SINGLE' => array(
+ 1 => ';',
+ ),
+ 'COMMENT_MULTI' => array(
+ '#|' => '|#',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"',
+ ),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'abort-current-continuation', 'abs', 'absolute-path?', 'acos', 'add1',
+ 'alarm-evt', 'always-evt', 'andmap', 'angle', 'append',
+ 'arithmetic-shift', 'arity-at-least-value', 'arity-at-least?',
+ 'asin', 'assf', 'assoc', 'assq', 'assv', 'atan', 'banner',
+ 'bitwise-and', 'bitwise-bit-field', 'bitwise-bit-set?',
+ 'bitwise-ior', 'bitwise-not', 'bitwise-xor', 'boolean?',
+ 'bound-identifier=?', 'box', 'box-cas!', 'box-immutable', 'box?',
+ 'break-enabled', 'break-thread', 'build-list', 'build-path',
+ 'build-path/convention-type', 'build-string', 'build-vector',
+ 'byte-pregexp', 'byte-pregexp?', 'byte-ready?', 'byte-regexp',
+ 'byte-regexp?', 'byte?', 'bytes', 'bytes&gt;?', 'bytes&lt;?',
+ 'bytes-&gt;immutable-bytes', 'bytes-&gt;list', 'bytes-&gt;path',
+ 'bytes-&gt;path-element', 'bytes-&gt;string/latin-1',
+ 'bytes-&gt;string/locale', 'bytes-&gt;string/utf-8',
+ 'bytes-append', 'bytes-close-converter', 'bytes-convert',
+ 'bytes-convert-end', 'bytes-converter?', 'bytes-copy',
+ 'bytes-copy!', 'bytes-fill!', 'bytes-length',
+ 'bytes-open-converter', 'bytes-ref', 'bytes-set!',
+ 'bytes-utf-8-index', 'bytes-utf-8-length', 'bytes-utf-8-ref',
+ 'bytes=?', 'bytes?', 'caaaar', 'caaadr', 'caaar', 'caadar',
+ 'caaddr', 'caadr', 'caar', 'cadaar', 'cadadr', 'cadar', 'caddar',
+ 'cadddr', 'caddr', 'cadr', 'call-in-nested-thread',
+ 'call-with-break-parameterization',
+ 'call-with-composable-continuation',
+ 'call-with-continuation-barrier', 'call-with-continuation-prompt',
+ 'call-with-current-continuation', 'call-with-escape-continuation',
+ 'call-with-exception-handler',
+ 'call-with-immediate-continuation-mark',
+ 'call-with-parameterization', 'call-with-semaphore',
+ 'call-with-semaphore/enable-break', 'call-with-values', 'call/cc',
+ 'call/ec', 'car', 'cdaaar', 'cdaadr', 'cdaar', 'cdadar', 'cdaddr',
+ 'cdadr', 'cdar', 'cddaar', 'cddadr', 'cddar', 'cdddar', 'cddddr',
+ 'cdddr', 'cddr', 'cdr', 'ceiling', 'channel-get', 'channel-put',
+ 'channel-put-evt', 'channel-put-evt?', 'channel-try-get',
+ 'channel?', 'chaperone-box', 'chaperone-continuation-mark-key',
+ 'chaperone-evt', 'chaperone-hash', 'chaperone-of?',
+ 'chaperone-procedure', 'chaperone-prompt-tag', 'chaperone-struct',
+ 'chaperone-struct-type', 'chaperone-vector', 'chaperone?',
+ 'char&gt;=?', 'char&gt;?', 'char&lt;=?', 'char&lt;?',
+ 'char-&gt;integer', 'char-alphabetic?', 'char-blank?',
+ 'char-ci&gt;=?', 'char-ci&gt;?', 'char-ci&lt;=?', 'char-ci&lt;?',
+ 'char-ci=?', 'char-downcase', 'char-foldcase',
+ 'char-general-category', 'char-graphic?', 'char-iso-control?',
+ 'char-lower-case?', 'char-numeric?', 'char-punctuation?',
+ 'char-ready?', 'char-symbolic?', 'char-title-case?',
+ 'char-titlecase', 'char-upcase', 'char-upper-case?',
+ 'char-utf-8-length', 'char-whitespace?', 'char=?', 'char?',
+ 'check-duplicate-identifier',
+ 'checked-procedure-check-and-extract', 'choice-evt',
+ 'cleanse-path', 'close-input-port', 'close-output-port',
+ 'collect-garbage', 'collection-file-path', 'collection-path',
+ 'compile', 'compile-allow-set!-undefined',
+ 'compile-context-preservation-enabled',
+ 'compile-enforce-module-constants', 'compile-syntax',
+ 'compiled-expression?', 'compiled-module-expression?',
+ 'complete-path?', 'complex?', 'compose', 'compose1', 'cons',
+ 'continuation-mark-key?', 'continuation-mark-set-&gt;context',
+ 'continuation-mark-set-&gt;list',
+ 'continuation-mark-set-&gt;list*', 'continuation-mark-set-first',
+ 'continuation-mark-set?', 'continuation-marks',
+ 'continuation-prompt-available?', 'continuation-prompt-tag?',
+ 'continuation?', 'copy-file', 'cos',
+ 'current-break-parameterization', 'current-code-inspector',
+ 'current-command-line-arguments', 'current-compile',
+ 'current-compiled-file-roots', 'current-continuation-marks',
+ 'current-custodian', 'current-directory', 'current-drive',
+ 'current-error-port', 'current-eval',
+ 'current-evt-pseudo-random-generator', 'current-gc-milliseconds',
+ 'current-get-interaction-input-port',
+ 'current-inexact-milliseconds', 'current-input-port',
+ 'current-inspector', 'current-library-collection-paths',
+ 'current-load', 'current-load-extension',
+ 'current-load-relative-directory', 'current-load/use-compiled',
+ 'current-locale', 'current-logger', 'current-memory-use',
+ 'current-milliseconds', 'current-module-declare-name',
+ 'current-module-declare-source', 'current-module-name-resolver',
+ 'current-namespace', 'current-output-port',
+ 'current-parameterization', 'current-preserved-thread-cell-values',
+ 'current-print', 'current-process-milliseconds',
+ 'current-prompt-read', 'current-pseudo-random-generator',
+ 'current-read-interaction', 'current-reader-guard',
+ 'current-readtable', 'current-seconds', 'current-security-guard',
+ 'current-subprocess-custodian-mode', 'current-thread',
+ 'current-thread-group', 'current-thread-initial-stack-size',
+ 'current-write-relative-directory', 'custodian-box-value',
+ 'custodian-box?', 'custodian-limit-memory',
+ 'custodian-managed-list', 'custodian-memory-accounting-available?',
+ 'custodian-require-memory', 'custodian-shutdown-all', 'custodian?',
+ 'custom-print-quotable-accessor', 'custom-print-quotable?',
+ 'custom-write-accessor', 'custom-write?', 'date*-nanosecond',
+ 'date*-time-zone-name', 'date*?', 'date-day', 'date-dst?',
+ 'date-hour', 'date-minute', 'date-month', 'date-second',
+ 'date-time-zone-offset', 'date-week-day', 'date-year',
+ 'date-year-day', 'date?', 'datum-&gt;syntax',
+ 'datum-intern-literal', 'default-continuation-prompt-tag',
+ 'delete-directory', 'delete-file', 'denominator',
+ 'directory-exists?', 'directory-list', 'display', 'displayln',
+ 'double-flonum?', 'dump-memory-stats', 'dynamic-require',
+ 'dynamic-require-for-syntax', 'dynamic-wind', 'eof', 'eof-object?',
+ 'ephemeron-value', 'ephemeron?', 'eprintf', 'eq-hash-code', 'eq?',
+ 'equal-hash-code', 'equal-secondary-hash-code', 'equal?',
+ 'equal?/recur', 'eqv-hash-code', 'eqv?', 'error',
+ 'error-display-handler', 'error-escape-handler',
+ 'error-print-context-length', 'error-print-source-location',
+ 'error-print-width', 'error-value-&gt;string-handler', 'eval',
+ 'eval-jit-enabled', 'eval-syntax', 'even?', 'evt?',
+ 'exact-&gt;inexact', 'exact-integer?',
+ 'exact-nonnegative-integer?', 'exact-positive-integer?', 'exact?',
+ 'executable-yield-handler', 'exit', 'exit-handler',
+ 'exn-continuation-marks', 'exn-message', 'exn:break-continuation',
+ 'exn:break:hang-up?', 'exn:break:terminate?', 'exn:break?',
+ 'exn:fail:contract:arity?', 'exn:fail:contract:continuation?',
+ 'exn:fail:contract:divide-by-zero?',
+ 'exn:fail:contract:non-fixnum-result?',
+ 'exn:fail:contract:variable-id', 'exn:fail:contract:variable?',
+ 'exn:fail:contract?', 'exn:fail:filesystem:errno-errno',
+ 'exn:fail:filesystem:errno?', 'exn:fail:filesystem:exists?',
+ 'exn:fail:filesystem:version?', 'exn:fail:filesystem?',
+ 'exn:fail:network:errno-errno', 'exn:fail:network:errno?',
+ 'exn:fail:network?', 'exn:fail:out-of-memory?',
+ 'exn:fail:read-srclocs', 'exn:fail:read:eof?',
+ 'exn:fail:read:non-char?', 'exn:fail:read?',
+ 'exn:fail:syntax-exprs', 'exn:fail:syntax:unbound?',
+ 'exn:fail:syntax?', 'exn:fail:unsupported?', 'exn:fail:user?',
+ 'exn:fail?', 'exn:srclocs-accessor', 'exn:srclocs?', 'exn?', 'exp',
+ 'expand', 'expand-once', 'expand-syntax', 'expand-syntax-once',
+ 'expand-syntax-to-top-form', 'expand-to-top-form',
+ 'expand-user-path', 'expt', 'file-exists?',
+ 'file-or-directory-identity', 'file-or-directory-modify-seconds',
+ 'file-or-directory-permissions', 'file-position', 'file-position*',
+ 'file-size', 'file-stream-buffer-mode', 'file-stream-port?',
+ 'filesystem-root-list', 'filter', 'find-executable-path',
+ 'find-library-collection-paths', 'find-system-path', 'findf',
+ 'fixnum?', 'floating-point-bytes-&gt;real', 'flonum?', 'floor',
+ 'flush-output', 'foldl', 'foldr', 'for-each', 'format', 'fprintf',
+ 'free-identifier=?', 'free-label-identifier=?',
+ 'free-template-identifier=?', 'free-transformer-identifier=?',
+ 'gcd', 'generate-temporaries', 'gensym', 'get-output-bytes',
+ 'get-output-string', 'getenv', 'global-port-print-handler',
+ 'guard-evt', 'handle-evt', 'handle-evt?', 'hash', 'hash-&gt;list',
+ 'hash-copy', 'hash-count', 'hash-eq?', 'hash-equal?', 'hash-eqv?',
+ 'hash-for-each', 'hash-has-key?', 'hash-iterate-first',
+ 'hash-iterate-key', 'hash-iterate-next', 'hash-iterate-value',
+ 'hash-keys', 'hash-map', 'hash-placeholder?', 'hash-ref',
+ 'hash-ref!', 'hash-remove', 'hash-remove!', 'hash-set',
+ 'hash-set!', 'hash-set*', 'hash-set*!', 'hash-update',
+ 'hash-update!', 'hash-values', 'hash-weak?', 'hash?', 'hasheq',
+ 'hasheqv', 'identifier-binding', 'identifier-label-binding',
+ 'identifier-prune-lexical-context',
+ 'identifier-prune-to-source-module',
+ 'identifier-remove-from-definition-context',
+ 'identifier-template-binding', 'identifier-transformer-binding',
+ 'identifier?', 'imag-part', 'immutable?', 'impersonate-box',
+ 'impersonate-continuation-mark-key', 'impersonate-hash',
+ 'impersonate-procedure', 'impersonate-prompt-tag',
+ 'impersonate-struct', 'impersonate-vector', 'impersonator-of?',
+ 'impersonator-prop:application-mark',
+ 'impersonator-property-accessor-procedure?',
+ 'impersonator-property?', 'impersonator?', 'in-cycle',
+ 'in-directory', 'in-hash', 'in-hash-keys', 'in-hash-pairs',
+ 'in-hash-values', 'in-parallel', 'in-sequences',
+ 'in-values*-sequence', 'in-values-sequence', 'inexact-&gt;exact',
+ 'inexact-real?', 'inexact?', 'input-port?', 'inspector?',
+ 'integer-&gt;char', 'integer-&gt;integer-bytes',
+ 'integer-bytes-&gt;integer', 'integer-length', 'integer-sqrt',
+ 'integer-sqrt/remainder', 'integer?',
+ 'internal-definition-context-seal', 'internal-definition-context?',
+ 'keyword&lt;?', 'keyword-&gt;string', 'keyword-apply', 'keyword?',
+ 'kill-thread', 'lcm', 'length', 'liberal-define-context?',
+ 'link-exists?', 'list', 'list*', 'list-&gt;bytes',
+ 'list-&gt;string', 'list-&gt;vector', 'list-ref', 'list-tail',
+ 'list?', 'load', 'load-extension', 'load-on-demand-enabled',
+ 'load-relative', 'load-relative-extension', 'load/cd',
+ 'load/use-compiled', 'local-expand', 'local-expand/capture-lifts',
+ 'local-transformer-expand',
+ 'local-transformer-expand/capture-lifts', 'locale-string-encoding',
+ 'log', 'log-level?', 'log-max-level', 'log-message',
+ 'log-receiver?', 'logger-name', 'logger?', 'magnitude',
+ 'make-arity-at-least', 'make-base-empty-namespace',
+ 'make-base-namespace', 'make-bytes', 'make-channel',
+ 'make-continuation-mark-key', 'make-continuation-prompt-tag',
+ 'make-custodian', 'make-custodian-box', 'make-date', 'make-date*',
+ 'make-derived-parameter', 'make-directory', 'make-do-sequence',
+ 'make-empty-namespace', 'make-ephemeron', 'make-exn',
+ 'make-exn:break', 'make-exn:break:hang-up',
+ 'make-exn:break:terminate', 'make-exn:fail',
+ 'make-exn:fail:contract', 'make-exn:fail:contract:arity',
+ 'make-exn:fail:contract:continuation',
+ 'make-exn:fail:contract:divide-by-zero',
+ 'make-exn:fail:contract:non-fixnum-result',
+ 'make-exn:fail:contract:variable', 'make-exn:fail:filesystem',
+ 'make-exn:fail:filesystem:errno',
+ 'make-exn:fail:filesystem:exists',
+ 'make-exn:fail:filesystem:version', 'make-exn:fail:network',
+ 'make-exn:fail:network:errno', 'make-exn:fail:out-of-memory',
+ 'make-exn:fail:read', 'make-exn:fail:read:eof',
+ 'make-exn:fail:read:non-char', 'make-exn:fail:syntax',
+ 'make-exn:fail:syntax:unbound', 'make-exn:fail:unsupported',
+ 'make-exn:fail:user', 'make-file-or-directory-link', 'make-hash',
+ 'make-hash-placeholder', 'make-hasheq', 'make-hasheq-placeholder',
+ 'make-hasheqv', 'make-hasheqv-placeholder', 'make-immutable-hash',
+ 'make-immutable-hasheq', 'make-immutable-hasheqv',
+ 'make-impersonator-property', 'make-input-port', 'make-inspector',
+ 'make-keyword-procedure', 'make-known-char-range-list',
+ 'make-log-receiver', 'make-logger', 'make-output-port',
+ 'make-parameter', 'make-phantom-bytes', 'make-pipe',
+ 'make-placeholder', 'make-polar', 'make-prefab-struct',
+ 'make-pseudo-random-generator', 'make-reader-graph',
+ 'make-readtable', 'make-rectangular', 'make-rename-transformer',
+ 'make-resolved-module-path', 'make-security-guard',
+ 'make-semaphore', 'make-set!-transformer', 'make-shared-bytes',
+ 'make-sibling-inspector', 'make-special-comment', 'make-srcloc',
+ 'make-string', 'make-struct-field-accessor',
+ 'make-struct-field-mutator', 'make-struct-type',
+ 'make-struct-type-property', 'make-syntax-delta-introducer',
+ 'make-syntax-introducer', 'make-thread-cell', 'make-thread-group',
+ 'make-vector', 'make-weak-box', 'make-weak-hash',
+ 'make-weak-hasheq', 'make-weak-hasheqv', 'make-will-executor',
+ 'map', 'max', 'mcar', 'mcdr', 'mcons', 'member', 'memf', 'memq',
+ 'memv', 'min', 'module-&gt;exports', 'module-&gt;imports',
+ 'module-&gt;language-info', 'module-&gt;namespace',
+ 'module-compiled-exports', 'module-compiled-imports',
+ 'module-compiled-language-info', 'module-compiled-name',
+ 'module-compiled-submodules', 'module-declared?',
+ 'module-path-index-join', 'module-path-index-resolve',
+ 'module-path-index-split', 'module-path-index-submodule',
+ 'module-path-index?', 'module-path?', 'module-predefined?',
+ 'module-provide-protected?', 'modulo', 'mpair?', 'nack-guard-evt',
+ 'namespace-anchor-&gt;empty-namespace',
+ 'namespace-anchor-&gt;namespace', 'namespace-anchor?',
+ 'namespace-attach-module', 'namespace-attach-module-declaration',
+ 'namespace-base-phase', 'namespace-mapped-symbols',
+ 'namespace-module-identifier', 'namespace-module-registry',
+ 'namespace-require', 'namespace-require/constant',
+ 'namespace-require/copy', 'namespace-require/expansion-time',
+ 'namespace-set-variable-value!', 'namespace-symbol-&gt;identifier',
+ 'namespace-syntax-introduce', 'namespace-undefine-variable!',
+ 'namespace-unprotect-module', 'namespace-variable-value',
+ 'namespace?', 'negative?', 'never-evt', 'newline',
+ 'normal-case-path', 'not', 'null', 'null?', 'number-&gt;string',
+ 'number?', 'numerator', 'object-name', 'odd?', 'open-input-bytes',
+ 'open-input-string', 'open-output-bytes', 'open-output-string',
+ 'ormap', 'output-port?', 'pair?', 'parameter-procedure=?',
+ 'parameter?', 'parameterization?', 'path-&gt;bytes',
+ 'path-&gt;complete-path', 'path-&gt;directory-path',
+ 'path-&gt;string', 'path-add-suffix', 'path-convention-type',
+ 'path-element-&gt;bytes', 'path-element-&gt;string',
+ 'path-for-some-system?', 'path-list-string-&gt;path-list',
+ 'path-replace-suffix', 'path-string?', 'path?', 'peek-byte',
+ 'peek-byte-or-special', 'peek-bytes', 'peek-bytes!',
+ 'peek-bytes-avail!', 'peek-bytes-avail!*',
+ 'peek-bytes-avail!/enable-break', 'peek-char',
+ 'peek-char-or-special', 'peek-string', 'peek-string!',
+ 'phantom-bytes?', 'pipe-content-length', 'placeholder-get',
+ 'placeholder-set!', 'placeholder?', 'poll-guard-evt',
+ 'port-closed-evt', 'port-closed?', 'port-commit-peeked',
+ 'port-count-lines!', 'port-count-lines-enabled',
+ 'port-display-handler', 'port-file-identity', 'port-file-unlock',
+ 'port-next-location', 'port-print-handler', 'port-progress-evt',
+ 'port-provides-progress-evts?', 'port-read-handler',
+ 'port-try-file-lock?', 'port-write-handler', 'port-writes-atomic?',
+ 'port-writes-special?', 'port?', 'positive?',
+ 'prefab-key-&gt;struct-type', 'prefab-key?', 'prefab-struct-key',
+ 'pregexp', 'pregexp?', 'primitive-closure?',
+ 'primitive-result-arity', 'primitive?', 'print',
+ 'print-as-expression', 'print-boolean-long-form', 'print-box',
+ 'print-graph', 'print-hash-table', 'print-mpair-curly-braces',
+ 'print-pair-curly-braces', 'print-reader-abbreviations',
+ 'print-struct', 'print-syntax-width', 'print-unreadable',
+ 'print-vector-length', 'printf', 'procedure-&gt;method',
+ 'procedure-arity', 'procedure-arity-includes?', 'procedure-arity?',
+ 'procedure-closure-contents-eq?', 'procedure-extract-target',
+ 'procedure-keywords', 'procedure-reduce-arity',
+ 'procedure-reduce-keyword-arity', 'procedure-rename',
+ 'procedure-struct-type?', 'procedure?', 'progress-evt?',
+ 'prop:arity-string', 'prop:checked-procedure',
+ 'prop:custom-print-quotable', 'prop:custom-write',
+ 'prop:equal+hash', 'prop:evt', 'prop:exn:srclocs',
+ 'prop:impersonator-of', 'prop:input-port',
+ 'prop:liberal-define-context', 'prop:output-port',
+ 'prop:procedure', 'prop:rename-transformer', 'prop:sequence',
+ 'prop:set!-transformer', 'pseudo-random-generator-&gt;vector',
+ 'pseudo-random-generator-vector?', 'pseudo-random-generator?',
+ 'putenv', 'quotient', 'quotient/remainder', 'raise',
+ 'raise-argument-error', 'raise-arguments-error',
+ 'raise-arity-error', 'raise-mismatch-error', 'raise-range-error',
+ 'raise-result-error', 'raise-syntax-error', 'raise-type-error',
+ 'raise-user-error', 'random', 'random-seed', 'rational?',
+ 'rationalize', 'read', 'read-accept-bar-quote', 'read-accept-box',
+ 'read-accept-compiled', 'read-accept-dot', 'read-accept-graph',
+ 'read-accept-infix-dot', 'read-accept-lang',
+ 'read-accept-quasiquote', 'read-accept-reader', 'read-byte',
+ 'read-byte-or-special', 'read-bytes', 'read-bytes!',
+ 'read-bytes-avail!', 'read-bytes-avail!*',
+ 'read-bytes-avail!/enable-break', 'read-bytes-line',
+ 'read-case-sensitive', 'read-char', 'read-char-or-special',
+ 'read-curly-brace-as-paren', 'read-decimal-as-inexact',
+ 'read-eval-print-loop', 'read-language', 'read-line',
+ 'read-on-demand-source', 'read-square-bracket-as-paren',
+ 'read-string', 'read-string!', 'read-syntax',
+ 'read-syntax/recursive', 'read/recursive', 'readtable-mapping',
+ 'readtable?', 'real-&gt;decimal-string', 'real-&gt;double-flonum',
+ 'real-&gt;floating-point-bytes', 'real-&gt;single-flonum',
+ 'real-part', 'real?', 'regexp', 'regexp-match',
+ 'regexp-match-exact?', 'regexp-match-peek',
+ 'regexp-match-peek-immediate', 'regexp-match-peek-positions',
+ 'regexp-match-peek-positions-immediate',
+ 'regexp-match-peek-positions-immediate/end',
+ 'regexp-match-peek-positions/end', 'regexp-match-positions',
+ 'regexp-match-positions/end', 'regexp-match/end', 'regexp-match?',
+ 'regexp-max-lookbehind', 'regexp-quote', 'regexp-replace',
+ 'regexp-replace*', 'regexp-replace-quote', 'regexp-replaces',
+ 'regexp-split', 'regexp-try-match', 'regexp?', 'relative-path?',
+ 'remainder', 'remove', 'remove*', 'remq', 'remq*', 'remv', 'remv*',
+ 'rename-file-or-directory', 'rename-transformer-target',
+ 'rename-transformer?', 'reroot-path', 'resolve-path',
+ 'resolved-module-path-name', 'resolved-module-path?', 'reverse',
+ 'round', 'seconds-&gt;date', 'security-guard?',
+ 'semaphore-peek-evt', 'semaphore-peek-evt?', 'semaphore-post',
+ 'semaphore-try-wait?', 'semaphore-wait',
+ 'semaphore-wait/enable-break', 'semaphore?', 'sequence-&gt;stream',
+ 'sequence-generate', 'sequence-generate*', 'sequence?',
+ 'set!-transformer-procedure', 'set!-transformer?', 'set-box!',
+ 'set-mcar!', 'set-mcdr!', 'set-phantom-bytes!',
+ 'set-port-next-location!', 'shared-bytes', 'shell-execute',
+ 'simplify-path', 'sin', 'single-flonum?', 'sleep',
+ 'special-comment-value', 'special-comment?', 'split-path', 'sqrt',
+ 'srcloc-column', 'srcloc-line', 'srcloc-position', 'srcloc-source',
+ 'srcloc-span', 'srcloc?', 'stop-after', 'stop-before', 'string',
+ 'string&gt;=?', 'string&gt;?', 'string&lt;=?', 'string&lt;?',
+ 'string-&gt;bytes/latin-1', 'string-&gt;bytes/locale',
+ 'string-&gt;bytes/utf-8', 'string-&gt;immutable-string',
+ 'string-&gt;keyword', 'string-&gt;list', 'string-&gt;number',
+ 'string-&gt;path', 'string-&gt;path-element', 'string-&gt;symbol',
+ 'string-&gt;uninterned-symbol', 'string-&gt;unreadable-symbol',
+ 'string-append', 'string-ci&gt;=?', 'string-ci&gt;?',
+ 'string-ci&lt;=?', 'string-ci&lt;?', 'string-ci=?', 'string-copy',
+ 'string-copy!', 'string-downcase', 'string-fill!',
+ 'string-foldcase', 'string-length', 'string-locale&gt;?',
+ 'string-locale&lt;?', 'string-locale-ci&gt;?',
+ 'string-locale-ci&lt;?', 'string-locale-ci=?',
+ 'string-locale-downcase', 'string-locale-upcase',
+ 'string-locale=?', 'string-normalize-nfc', 'string-normalize-nfd',
+ 'string-normalize-nfkc', 'string-normalize-nfkd', 'string-ref',
+ 'string-set!', 'string-titlecase', 'string-upcase',
+ 'string-utf-8-length', 'string=?', 'string?', 'struct-&gt;vector',
+ 'struct-accessor-procedure?', 'struct-constructor-procedure?',
+ 'struct-info', 'struct-mutator-procedure?',
+ 'struct-predicate-procedure?', 'struct-type-info',
+ 'struct-type-make-constructor', 'struct-type-make-predicate',
+ 'struct-type-property-accessor-procedure?',
+ 'struct-type-property?', 'struct-type?', 'struct:arity-at-least',
+ 'struct:date', 'struct:date*', 'struct:exn', 'struct:exn:break',
+ 'struct:exn:break:hang-up', 'struct:exn:break:terminate',
+ 'struct:exn:fail', 'struct:exn:fail:contract',
+ 'struct:exn:fail:contract:arity',
+ 'struct:exn:fail:contract:continuation',
+ 'struct:exn:fail:contract:divide-by-zero',
+ 'struct:exn:fail:contract:non-fixnum-result',
+ 'struct:exn:fail:contract:variable', 'struct:exn:fail:filesystem',
+ 'struct:exn:fail:filesystem:errno',
+ 'struct:exn:fail:filesystem:exists',
+ 'struct:exn:fail:filesystem:version', 'struct:exn:fail:network',
+ 'struct:exn:fail:network:errno', 'struct:exn:fail:out-of-memory',
+ 'struct:exn:fail:read', 'struct:exn:fail:read:eof',
+ 'struct:exn:fail:read:non-char', 'struct:exn:fail:syntax',
+ 'struct:exn:fail:syntax:unbound', 'struct:exn:fail:unsupported',
+ 'struct:exn:fail:user', 'struct:srcloc', 'struct?', 'sub1',
+ 'subbytes', 'subprocess', 'subprocess-group-enabled',
+ 'subprocess-kill', 'subprocess-pid', 'subprocess-status',
+ 'subprocess-wait', 'subprocess?', 'substring', 'symbol-&gt;string',
+ 'symbol-interned?', 'symbol-unreadable?', 'symbol?', 'sync',
+ 'sync/enable-break', 'sync/timeout', 'sync/timeout/enable-break',
+ 'syntax-&gt;datum', 'syntax-&gt;list', 'syntax-arm',
+ 'syntax-column', 'syntax-disarm', 'syntax-e', 'syntax-line',
+ 'syntax-local-bind-syntaxes', 'syntax-local-certifier',
+ 'syntax-local-context', 'syntax-local-expand-expression',
+ 'syntax-local-get-shadower', 'syntax-local-introduce',
+ 'syntax-local-lift-context', 'syntax-local-lift-expression',
+ 'syntax-local-lift-module-end-declaration',
+ 'syntax-local-lift-provide', 'syntax-local-lift-require',
+ 'syntax-local-lift-values-expression',
+ 'syntax-local-make-definition-context',
+ 'syntax-local-make-delta-introducer',
+ 'syntax-local-module-defined-identifiers',
+ 'syntax-local-module-exports',
+ 'syntax-local-module-required-identifiers', 'syntax-local-name',
+ 'syntax-local-phase-level', 'syntax-local-submodules',
+ 'syntax-local-transforming-module-provides?', 'syntax-local-value',
+ 'syntax-local-value/immediate', 'syntax-original?',
+ 'syntax-position', 'syntax-property',
+ 'syntax-property-symbol-keys', 'syntax-protect', 'syntax-rearm',
+ 'syntax-recertify', 'syntax-shift-phase-level', 'syntax-source',
+ 'syntax-source-module', 'syntax-span', 'syntax-taint',
+ 'syntax-tainted?', 'syntax-track-origin',
+ 'syntax-transforming-module-expression?', 'syntax-transforming?',
+ 'syntax?', 'system-big-endian?', 'system-idle-evt',
+ 'system-language+country', 'system-library-subpath',
+ 'system-path-convention-type', 'system-type', 'tan',
+ 'terminal-port?', 'thread', 'thread-cell-ref', 'thread-cell-set!',
+ 'thread-cell-values?', 'thread-cell?', 'thread-dead-evt',
+ 'thread-dead?', 'thread-group?', 'thread-receive',
+ 'thread-receive-evt', 'thread-resume', 'thread-resume-evt',
+ 'thread-rewind-receive', 'thread-running?', 'thread-send',
+ 'thread-suspend', 'thread-suspend-evt', 'thread-try-receive',
+ 'thread-wait', 'thread/suspend-to-kill', 'thread?', 'time-apply',
+ 'truncate', 'unbox', 'uncaught-exception-handler',
+ 'use-collection-link-paths', 'use-compiled-file-paths',
+ 'use-user-specific-search-paths', 'values',
+ 'variable-reference-&gt;empty-namespace',
+ 'variable-reference-&gt;module-base-phase',
+ 'variable-reference-&gt;module-declaration-inspector',
+ 'variable-reference-&gt;module-path-index',
+ 'variable-reference-&gt;module-source',
+ 'variable-reference-&gt;namespace', 'variable-reference-&gt;phase',
+ 'variable-reference-&gt;resolved-module-path',
+ 'variable-reference-constant?', 'variable-reference?', 'vector',
+ 'vector-&gt;immutable-vector', 'vector-&gt;list',
+ 'vector-&gt;pseudo-random-generator',
+ 'vector-&gt;pseudo-random-generator!', 'vector-&gt;values',
+ 'vector-copy!', 'vector-fill!', 'vector-immutable',
+ 'vector-length', 'vector-ref', 'vector-set!',
+ 'vector-set-performance-stats!', 'vector?', 'version', 'void',
+ 'void?', 'weak-box-value', 'weak-box?', 'will-execute',
+ 'will-executor?', 'will-register', 'will-try-execute', 'wrap-evt',
+ 'write', 'write-byte', 'write-bytes', 'write-bytes-avail',
+ 'write-bytes-avail*', 'write-bytes-avail-evt',
+ 'write-bytes-avail/enable-break', 'write-char', 'write-special',
+ 'write-special-avail*', 'write-special-evt', 'write-string',
+ 'zero?',
+ ),
+
+ 2 => array(
+ '#%app', '#%datum', '#%expression', '#%module-begin', '#%plain-app',
+ '#%plain-lambda', '#%plain-module-begin', '#%provide', '#%require',
+ '#%stratified-body', '#%top', '#%top-interaction',
+ '#%variable-reference', ':do-in', 'all-defined-out',
+ 'all-from-out', 'and', 'apply', 'arity-at-least', 'begin',
+ 'begin-for-syntax', 'begin0', 'call-with-input-file',
+ 'call-with-input-file*', 'call-with-output-file',
+ 'call-with-output-file*', 'case', 'case-lambda', 'combine-in',
+ 'combine-out', 'cond', 'date', 'date*', 'define',
+ 'define-for-syntax', 'define-logger', 'define-namespace-anchor',
+ 'define-sequence-syntax', 'define-struct', 'define-struct/derived',
+ 'define-syntax', 'define-syntax-rule', 'define-syntaxes',
+ 'define-values', 'define-values-for-syntax', 'do', 'else',
+ 'except-in', 'except-out', 'exn', 'exn:break', 'exn:break:hang-up',
+ 'exn:break:terminate', 'exn:fail', 'exn:fail:contract',
+ 'exn:fail:contract:arity', 'exn:fail:contract:continuation',
+ 'exn:fail:contract:divide-by-zero',
+ 'exn:fail:contract:non-fixnum-result',
+ 'exn:fail:contract:variable', 'exn:fail:filesystem',
+ 'exn:fail:filesystem:errno', 'exn:fail:filesystem:exists',
+ 'exn:fail:filesystem:version', 'exn:fail:network',
+ 'exn:fail:network:errno', 'exn:fail:out-of-memory',
+ 'exn:fail:read', 'exn:fail:read:eof', 'exn:fail:read:non-char',
+ 'exn:fail:syntax', 'exn:fail:syntax:unbound',
+ 'exn:fail:unsupported', 'exn:fail:user', 'file', 'for', 'for*',
+ 'for*/and', 'for*/first', 'for*/fold', 'for*/fold/derived',
+ 'for*/hash', 'for*/hasheq', 'for*/hasheqv', 'for*/last',
+ 'for*/list', 'for*/lists', 'for*/or', 'for*/product', 'for*/sum',
+ 'for*/vector', 'for-label', 'for-meta', 'for-syntax',
+ 'for-template', 'for/and', 'for/first', 'for/fold',
+ 'for/fold/derived', 'for/hash', 'for/hasheq', 'for/hasheqv',
+ 'for/last', 'for/list', 'for/lists', 'for/or', 'for/product',
+ 'for/sum', 'for/vector', 'gen:custom-write', 'gen:equal+hash',
+ 'if', 'in-bytes', 'in-bytes-lines', 'in-indexed',
+ 'in-input-port-bytes', 'in-input-port-chars', 'in-lines',
+ 'in-list', 'in-mlist', 'in-naturals', 'in-port', 'in-producer',
+ 'in-range', 'in-string', 'in-value', 'in-vector', 'lambda', 'let',
+ 'let*', 'let*-values', 'let-syntax', 'let-syntaxes', 'let-values',
+ 'let/cc', 'let/ec', 'letrec', 'letrec-syntax', 'letrec-syntaxes',
+ 'letrec-syntaxes+values', 'letrec-values', 'lib', 'local-require',
+ 'log-debug', 'log-error', 'log-fatal', 'log-info', 'log-warning',
+ 'module', 'module*', 'module+', 'only-in', 'only-meta-in',
+ 'open-input-file', 'open-input-output-file', 'open-output-file',
+ 'or', 'parameterize', 'parameterize*', 'parameterize-break',
+ 'planet', 'prefix-in', 'prefix-out', 'protect-out', 'provide',
+ 'quasiquote', 'quasisyntax', 'quasisyntax/loc', 'quote',
+ 'quote-syntax', 'quote-syntax/prune', 'regexp-match*',
+ 'regexp-match-peek-positions*', 'regexp-match-positions*',
+ 'relative-in', 'rename-in', 'rename-out', 'require', 'set!',
+ 'set!-values', 'sort', 'srcloc', 'struct', 'struct-copy',
+ 'struct-field-index', 'struct-out', 'submod', 'syntax',
+ 'syntax-case', 'syntax-case*', 'syntax-id-rules', 'syntax-rules',
+ 'syntax/loc', 'time', 'unless', 'unquote', 'unquote-splicing',
+ 'unsyntax', 'unsyntax-splicing', 'when', 'with-continuation-mark',
+ 'with-handlers', 'with-handlers*', 'with-input-from-file',
+ 'with-output-to-file', 'with-syntax', 'λ',
+ ),
+
+ 3 => array(
+ '&gt;/c', '&lt;/c', 'append*', 'append-map', 'argmax', 'argmin',
+ 'bad-number-of-results', 'base-&gt;-doms/c', 'base-&gt;-rngs/c',
+ 'base-&gt;?', 'blame-add-unknown-context', 'blame-context',
+ 'blame-contract', 'blame-fmt-&gt;-string', 'blame-negative',
+ 'blame-original?', 'blame-positive', 'blame-replace-negative',
+ 'blame-source', 'blame-swap', 'blame-swapped?', 'blame-value',
+ 'blame?', 'boolean=?', 'build-chaperone-contract-property',
+ 'build-compound-type-name', 'build-contract-property',
+ 'build-flat-contract-property', 'bytes-append*', 'bytes-join',
+ 'bytes-no-nuls?', 'call-with-input-bytes',
+ 'call-with-input-string', 'call-with-output-bytes',
+ 'call-with-output-string', 'chaperone-contract-property?',
+ 'chaperone-contract?', 'class-&gt;interface', 'class-info',
+ 'class?', 'coerce-chaperone-contract',
+ 'coerce-chaperone-contracts', 'coerce-contract',
+ 'coerce-contract/f', 'coerce-contracts', 'coerce-flat-contract',
+ 'coerce-flat-contracts', 'conjugate', 'cons?', 'const',
+ 'contract-first-order', 'contract-first-order-passes?',
+ 'contract-name', 'contract-proc', 'contract-projection',
+ 'contract-property?', 'contract-random-generate',
+ 'contract-stronger?', 'contract-struct-exercise',
+ 'contract-struct-generate', 'contract?', 'convert-stream',
+ 'copy-directory/files', 'copy-port', 'cosh', 'count',
+ 'current-blame-format', 'current-future', 'curry', 'curryr',
+ 'degrees-&gt;radians', 'delete-directory/files',
+ 'deserialize-info:set-v0', 'dict-iter-contract',
+ 'dict-key-contract', 'dict-value-contract', 'drop', 'drop-right',
+ 'dup-input-port', 'dup-output-port', 'dynamic-get-field',
+ 'dynamic-send', 'dynamic-set-field!', 'eighth', 'empty',
+ 'empty-sequence', 'empty-stream', 'empty?', 'env-stash',
+ 'eq-contract-val', 'eq-contract?', 'equal&lt;%&gt;',
+ 'equal-contract-val', 'equal-contract?', 'exact-ceiling',
+ 'exact-floor', 'exact-round', 'exact-truncate',
+ 'exn:fail:contract:blame-object', 'exn:fail:contract:blame?',
+ 'exn:fail:object?', 'exn:misc:match?', 'explode-path',
+ 'externalizable&lt;%&gt;', 'false', 'false/c', 'false?',
+ 'field-names', 'fifth', 'file-name-from-path',
+ 'filename-extension', 'filter-map', 'filter-not',
+ 'filter-read-input-port', 'find-files', 'first', 'flat-contract',
+ 'flat-contract-predicate', 'flat-contract-property?',
+ 'flat-contract?', 'flat-named-contract', 'flatten', 'fold-files',
+ 'force', 'fourth', 'fsemaphore-count', 'fsemaphore-post',
+ 'fsemaphore-try-wait?', 'fsemaphore-wait', 'fsemaphore?', 'future',
+ 'future?', 'futures-enabled?', 'generate-ctc-fail?',
+ 'generate-env', 'generate-member-key', 'generate/choose',
+ 'generate/direct', 'generic?', 'group-execute-bit',
+ 'group-read-bit', 'group-write-bit', 'has-contract?', 'identity',
+ 'impersonator-contract?', 'impersonator-prop:contracted',
+ 'implementation?', 'implementation?/c', 'in-dict', 'in-dict-keys',
+ 'in-dict-pairs', 'in-dict-values', 'infinite?',
+ 'input-port-append', 'instanceof/c', 'interface-&gt;method-names',
+ 'interface-extension?', 'interface?', 'is-a?', 'is-a?/c', 'last',
+ 'last-pair', 'list-&gt;set', 'list-&gt;seteq', 'list-&gt;seteqv',
+ 'make-chaperone-contract', 'make-contract', 'make-custom-hash',
+ 'make-directory*', 'make-exn:fail:contract:blame',
+ 'make-exn:fail:object', 'make-flat-contract', 'make-fsemaphore',
+ 'make-generate-ctc-fail', 'make-generic',
+ 'make-immutable-custom-hash', 'make-input-port/read-to-peek',
+ 'make-limited-input-port', 'make-list', 'make-lock-file-name',
+ 'make-mixin-contract', 'make-none/c', 'make-pipe-with-specials',
+ 'make-primitive-class', 'make-proj-contract',
+ 'make-tentative-pretty-print-output-port', 'make-weak-custom-hash',
+ 'match-equality-test', 'matches-arity-exactly?',
+ 'member-name-key-hash-code', 'member-name-key=?',
+ 'member-name-key?', 'merge-input', 'method-in-interface?',
+ 'mixin-contract', 'n-&gt;th', 'nan?', 'natural-number/c', 'negate',
+ 'new-∀/c', 'new-∃/c', 'ninth', 'normalize-path', 'object%',
+ 'object-&gt;vector', 'object-info', 'object-interface',
+ 'object-method-arity-includes?', 'object=?', 'object?',
+ 'open-output-nowhere', 'order-of-magnitude', 'other-execute-bit',
+ 'other-read-bit', 'other-write-bit', 'parse-command-line',
+ 'partition', 'path-element?', 'path-only', 'pathlist-closure',
+ 'pi', 'pi.f', 'place-break', 'place-channel', 'place-channel-get',
+ 'place-channel-put', 'place-channel-put/get', 'place-channel?',
+ 'place-dead-evt', 'place-enabled?', 'place-kill',
+ 'place-message-allowed?', 'place-sleep', 'place-wait', 'place?',
+ 'port-&gt;bytes', 'port-&gt;list', 'port-&gt;string',
+ 'predicate/c', 'preferences-lock-file-mode', 'pretty-display',
+ 'pretty-format', 'pretty-print',
+ 'pretty-print-.-symbol-without-bars',
+ 'pretty-print-abbreviate-read-macros', 'pretty-print-columns',
+ 'pretty-print-current-style-table', 'pretty-print-depth',
+ 'pretty-print-exact-as-decimal', 'pretty-print-extend-style-table',
+ 'pretty-print-handler', 'pretty-print-newline',
+ 'pretty-print-post-print-hook', 'pretty-print-pre-print-hook',
+ 'pretty-print-print-hook', 'pretty-print-print-line',
+ 'pretty-print-remap-stylable', 'pretty-print-show-inexactness',
+ 'pretty-print-size-hook', 'pretty-print-style-table?',
+ 'pretty-printing', 'pretty-write', 'printable&lt;%&gt;',
+ 'printable/c', 'process', 'process*', 'process*/ports',
+ 'process/ports', 'processor-count', 'promise-forced?',
+ 'promise-running?', 'promise?', 'prop:chaperone-contract',
+ 'prop:contract', 'prop:contracted', 'prop:dict',
+ 'prop:flat-contract', 'prop:opt-chaperone-contract',
+ 'prop:opt-chaperone-contract-get-test',
+ 'prop:opt-chaperone-contract?', 'prop:stream', 'proper-subset?',
+ 'put-preferences', 'radians-&gt;degrees', 'raise-blame-error',
+ 'raise-contract-error', 'range', 'reencode-input-port',
+ 'reencode-output-port', 'relocate-input-port',
+ 'relocate-output-port', 'rest', 'second', 'sequence-&gt;list',
+ 'sequence-add-between', 'sequence-andmap', 'sequence-append',
+ 'sequence-count', 'sequence-filter', 'sequence-fold',
+ 'sequence-for-each', 'sequence-length', 'sequence-map',
+ 'sequence-ormap', 'sequence-ref', 'sequence-tail', 'set',
+ 'set-&gt;list', 'set-add', 'set-count', 'set-empty?', 'set-eq?',
+ 'set-equal?', 'set-eqv?', 'set-first', 'set-for-each',
+ 'set-intersect', 'set-map', 'set-member?', 'set-remove',
+ 'set-rest', 'set-subtract', 'set-symmetric-difference',
+ 'set-union', 'set/c', 'set=?', 'set?', 'seteq', 'seteqv',
+ 'seventh', 'sgn', 'shuffle', 'simple-form-path', 'sinh', 'sixth',
+ 'skip-projection-wrapper?', 'some-system-path-&gt;string',
+ 'special-filter-input-port', 'split-at', 'split-at-right', 'sqr',
+ 'stream-&gt;list', 'stream-add-between', 'stream-andmap',
+ 'stream-append', 'stream-count', 'stream-empty?', 'stream-filter',
+ 'stream-first', 'stream-fold', 'stream-for-each', 'stream-length',
+ 'stream-map', 'stream-ormap', 'stream-ref', 'stream-rest',
+ 'stream-tail', 'stream?', 'string-&gt;some-system-path',
+ 'string-append*', 'string-no-nuls?', 'struct-type-property/c',
+ 'struct:exn:fail:contract:blame', 'struct:exn:fail:object',
+ 'subclass?', 'subclass?/c', 'subset?', 'symbol=?', 'system',
+ 'system*', 'system*/exit-code', 'system/exit-code', 'take',
+ 'take-right', 'tanh', 'tcp-abandon-port', 'tcp-accept',
+ 'tcp-accept-evt', 'tcp-accept-ready?', 'tcp-accept/enable-break',
+ 'tcp-addresses', 'tcp-close', 'tcp-connect',
+ 'tcp-connect/enable-break', 'tcp-listen', 'tcp-listener?',
+ 'tcp-port?', 'tentative-pretty-print-port-cancel',
+ 'tentative-pretty-print-port-transfer', 'tenth',
+ 'the-unsupplied-arg', 'third', 'touch', 'transplant-input-port',
+ 'transplant-output-port', 'true', 'udp-addresses', 'udp-bind!',
+ 'udp-bound?', 'udp-close', 'udp-connect!', 'udp-connected?',
+ 'udp-open-socket', 'udp-receive!', 'udp-receive!*',
+ 'udp-receive!-evt', 'udp-receive!/enable-break',
+ 'udp-receive-ready-evt', 'udp-send', 'udp-send*', 'udp-send-evt',
+ 'udp-send-ready-evt', 'udp-send-to', 'udp-send-to*',
+ 'udp-send-to-evt', 'udp-send-to/enable-break',
+ 'udp-send/enable-break', 'udp?', 'unit?', 'unsupplied-arg?',
+ 'user-execute-bit', 'user-read-bit', 'user-write-bit',
+ 'value-contract', 'vector-append', 'vector-argmax',
+ 'vector-argmin', 'vector-copy', 'vector-count', 'vector-drop',
+ 'vector-drop-right', 'vector-filter', 'vector-filter-not',
+ 'vector-map', 'vector-map!', 'vector-member', 'vector-memq',
+ 'vector-memv', 'vector-set*!', 'vector-split-at',
+ 'vector-split-at-right', 'vector-take', 'vector-take-right',
+ 'with-input-from-bytes', 'with-input-from-string',
+ 'with-output-to-bytes', 'with-output-to-string', 'would-be-future',
+ 'writable&lt;%&gt;', 'xor',
+ ),
+ 4 => array(
+ '&gt;=/c', '&lt;=/c', '-&gt;*m', '-&gt;d', '-&gt;dm', '-&gt;i', '-&gt;m',
+ '=/c', 'absent', 'abstract', 'add-between', 'and/c', 'any',
+ 'any/c', 'augment', 'augment*', 'augment-final', 'augment-final*',
+ 'augride', 'augride*', 'between/c', 'blame-add-context',
+ 'box-immutable/c', 'box/c', 'call-with-file-lock/timeout',
+ 'case-&gt;', 'case-&gt;m', 'class', 'class*',
+ 'class-field-accessor', 'class-field-mutator', 'class/c',
+ 'class/derived', 'command-line', 'compound-unit',
+ 'compound-unit/infer', 'cons/c', 'continuation-mark-key/c',
+ 'contract', 'contract-out', 'contract-struct', 'contracted',
+ 'current-contract-region', 'define-compound-unit',
+ 'define-compound-unit/infer', 'define-contract-struct',
+ 'define-local-member-name', 'define-match-expander',
+ 'define-member-name', 'define-opt/c', 'define-serializable-class',
+ 'define-serializable-class*', 'define-signature',
+ 'define-signature-form', 'define-struct/contract', 'define-unit',
+ 'define-unit-binding', 'define-unit-from-context',
+ 'define-unit/contract', 'define-unit/new-import-export',
+ 'define-unit/s', 'define-values-for-export',
+ 'define-values/invoke-unit', 'define-values/invoke-unit/infer',
+ 'define/augment', 'define/augment-final', 'define/augride',
+ 'define/contract', 'define/final-prop', 'define/match',
+ 'define/overment', 'define/override', 'define/override-final',
+ 'define/private', 'define/public', 'define/public-final',
+ 'define/pubment', 'define/subexpression-pos-prop', 'delay',
+ 'delay/idle', 'delay/name', 'delay/strict', 'delay/sync',
+ 'delay/thread', 'dict-&gt;list', 'dict-can-functional-set?',
+ 'dict-can-remove-keys?', 'dict-count', 'dict-for-each',
+ 'dict-has-key?', 'dict-iterate-first', 'dict-iterate-key',
+ 'dict-iterate-next', 'dict-iterate-value', 'dict-keys', 'dict-map',
+ 'dict-mutable?', 'dict-ref', 'dict-ref!', 'dict-remove',
+ 'dict-remove!', 'dict-set', 'dict-set!', 'dict-set*', 'dict-set*!',
+ 'dict-update', 'dict-update!', 'dict-values', 'dict?',
+ 'display-lines', 'display-lines-to-file', 'display-to-file',
+ 'dynamic-place', 'dynamic-place*', 'eof-evt', 'except',
+ 'exn:fail:contract:blame', 'exn:fail:object', 'export', 'extends',
+ 'field', 'field-bound?', 'file-&gt;bytes', 'file-&gt;bytes-lines',
+ 'file-&gt;lines', 'file-&gt;list', 'file-&gt;string',
+ 'file-&gt;value', 'find-relative-path', 'flat-murec-contract',
+ 'flat-rec-contract', 'for*/set', 'for*/seteq', 'for*/seteqv',
+ 'for/set', 'for/seteq', 'for/seteqv', 'gen:dict', 'gen:stream',
+ 'generic', 'get-field', 'get-preference', 'hash/c', 'implies',
+ 'import', 'in-set', 'in-stream', 'include',
+ 'include-at/relative-to', 'include-at/relative-to/reader',
+ 'include/reader', 'inherit', 'inherit-field', 'inherit/inner',
+ 'inherit/super', 'init', 'init-depend', 'init-field', 'init-rest',
+ 'inner', 'inspect', 'instantiate', 'integer-in', 'interface',
+ 'interface*', 'invoke-unit', 'invoke-unit/infer', 'lazy', 'link',
+ 'list/c', 'listof', 'local', 'make-handle-get-preference-locked',
+ 'make-object', 'make-temporary-file', 'match', 'match*',
+ 'match*/derived', 'match-define', 'match-define-values',
+ 'match-lambda', 'match-lambda*', 'match-lambda**', 'match-let',
+ 'match-let*', 'match-let*-values', 'match-let-values',
+ 'match-letrec', 'match/derived', 'match/values', 'member-name-key',
+ 'method-contract?', 'mixin', 'nand', 'new', 'non-empty-listof',
+ 'none/c', 'nor', 'not/c', 'object-contract', 'object/c',
+ 'one-of/c', 'only', 'open', 'opt/c', 'or/c', 'overment',
+ 'overment*', 'override', 'override*', 'override-final',
+ 'override-final*', 'parameter/c', 'parametric-&gt;/c',
+ 'peek-bytes!-evt', 'peek-bytes-avail!-evt', 'peek-bytes-evt',
+ 'peek-string!-evt', 'peek-string-evt', 'peeking-input-port',
+ 'place', 'place*', 'port-&gt;bytes-lines', 'port-&gt;lines',
+ 'prefix', 'private', 'private*', 'procedure-arity-includes/c',
+ 'promise/c', 'prompt-tag/c', 'prop:dict/contract',
+ 'provide-signature-elements', 'provide/contract', 'public',
+ 'public*', 'public-final', 'public-final*', 'pubment', 'pubment*',
+ 'read-bytes!-evt', 'read-bytes-avail!-evt', 'read-bytes-evt',
+ 'read-bytes-line-evt', 'read-line-evt', 'read-string!-evt',
+ 'read-string-evt', 'real-in', 'recursive-contract',
+ 'regexp-match-evt', 'remove-duplicates', 'rename', 'rename-inner',
+ 'rename-super', 'send', 'send*', 'send+', 'send-generic',
+ 'send/apply', 'send/keyword-apply', 'set-field!', 'shared',
+ 'stream', 'stream-cons', 'string-join', 'string-len/c',
+ 'string-normalize-spaces', 'string-replace', 'string-split',
+ 'string-trim', 'struct*', 'struct/c', 'struct/ctc', 'struct/dc',
+ 'super', 'super-instantiate', 'super-make-object', 'super-new',
+ 'symbols', 'syntax/c', 'tag', 'this', 'this%', 'thunk', 'thunk*',
+ 'unconstrained-domain-&gt;', 'unit', 'unit-from-context', 'unit/c',
+ 'unit/new-import-export', 'unit/s', 'vector-immutable/c',
+ 'vector-immutableof', 'vector/c', 'vectorof', 'with-contract',
+ 'with-method', 'write-to-file', '~.a', '~.s', '~.v', '~a', '~e',
+ '~r', '~s', '~v',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '&gt;', '&gt;=', '&lt;', '&lt;=', '*', '+', '-', '-&gt;', '-&gt;*', '...', '/',
+ '=', '=&gt;', '==', '_', '#fl', '#fx', '#s', '#', '#f', '#F',
+ '#false', '#t', '#T', '#true', '#lang', '#reader', '.', '\'', '#`',
+ '#,@', '#,', '#\'', '`', '@', ',', '#%', '#$', '#&', '#~', '#rx',
+ '#px', '#<<', '#;', '#hash', '#',
+ ),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'NUMBERS' => array(
+ 1 => '(((#x#e)|(#e#x)|(#x#i)|(#i#x)|(#x))((((((((((((-)|(\+)))?(((('.
+ '(([0-9])+)?(\.)?(([0-9a-fA-F])+(#)*)))|(((([0-9a-fA-F])+(#)*)'.
+ '(\.)?(#)*))|(((([0-9a-fA-F])+(#)*)\\/(([0-9a-fA-F])+(#)*))))('.
+ '([sl]((((-)|(\+)))?([0-9])+)))?)))|((((-)|(\+))(((inf\.)|(nan'.
+ '\.))[0f])))))?((-)|(\+))(((((((([0-9])+)?(\.)?(([0-9a-fA-F])+'.
+ '(#)*)))|(((([0-9a-fA-F])+(#)*)(\.)?(#)*))|(((([0-9a-fA-F])+(#'.
+ ')*)\\/(([0-9a-fA-F])+(#)*))))(([sl]((((-)|(\+)))?([0-9])+)))?'.
+ '))|((((inf\.)|(nan\.))[0f])))i))|((((((((-)|(\+)))?(((((([0-9'.
+ '])+)?(\.)?(([0-9a-fA-F])+(#)*)))|(((([0-9a-fA-F])+(#)*)(\.)?('.
+ '#)*))|(((([0-9a-fA-F])+(#)*)\\/(([0-9a-fA-F])+(#)*))))(([sl]('.
+ '(((-)|(\+)))?([0-9])+)))?)))|((((-)|(\+))(((inf\.)|(nan\.))[0'.
+ 'f]))))@((((((-)|(\+)))?(((((([0-9])+)?(\.)?(([0-9a-fA-F])+(#)'.
+ '*)))|(((([0-9a-fA-F])+(#)*)(\.)?(#)*))|(((([0-9a-fA-F])+(#)*)'.
+ '\\/(([0-9a-fA-F])+(#)*))))(([sl]((((-)|(\+)))?([0-9])+)))?)))'.
+ '|((((-)|(\+))(((inf\.)|(nan\.))[0f]))))))))|((((((-)|(\+)))?('.
+ '([0-9])+\\/([0-9])+))((-)|(\+))(([0-9])+\\/([0-9])+)i))|((((('.
+ '-)|(\+)))?(([0-9])+\\/([0-9])+)))|(((((((-)|(\+)))?(((((([0-9'.
+ '])+)?(\.)?(([0-9a-fA-F])+(#)*)))|(((([0-9a-fA-F])+(#)*)(\.)?('.
+ '#)*))|(((([0-9a-fA-F])+(#)*)\\/(([0-9a-fA-F])+(#)*))))(([sl]('.
+ '(((-)|(\+)))?([0-9])+)))?)))|((((-)|(\+))(((inf\.)|(nan\.))[0'.
+ 'f])))))|(((((-)|(\+)))?([0-9])+))))',
+ 2 => '(((#o#e)|(#e#o)|(#o#i)|(#i#o)|(#o))((((((((((((-)|(\+)))?(((('.
+ '(([0-9])+)?(\.)?(([0-7])+(#)*)))|(((([0-7])+(#)*)(\.)?(#)*))|'.
+ '(((([0-7])+(#)*)\\/(([0-7])+(#)*))))(((([sl])|([def]))((((-)|'.
+ '(\+)))?([0-9])+)))?)))|((((-)|(\+))(((inf\.)|(nan\.))[0f]))))'.
+ ')?((-)|(\+))(((((((([0-9])+)?(\.)?(([0-7])+(#)*)))|(((([0-7])'.
+ '+(#)*)(\.)?(#)*))|(((([0-7])+(#)*)\\/(([0-7])+(#)*))))(((([sl'.
+ '])|([def]))((((-)|(\+)))?([0-9])+)))?))|((((inf\.)|(nan\.))[0'.
+ 'f])))i))|((((((((-)|(\+)))?(((((([0-9])+)?(\.)?(([0-7])+(#)*)'.
+ '))|(((([0-7])+(#)*)(\.)?(#)*))|(((([0-7])+(#)*)\\/(([0-7])+(#'.
+ ')*))))(((([sl])|([def]))((((-)|(\+)))?([0-9])+)))?)))|((((-)|'.
+ '(\+))(((inf\.)|(nan\.))[0f]))))@((((((-)|(\+)))?(((((([0-9])+'.
+ ')?(\.)?(([0-7])+(#)*)))|(((([0-7])+(#)*)(\.)?(#)*))|(((([0-7]'.
+ ')+(#)*)\\/(([0-7])+(#)*))))(((([sl])|([def]))((((-)|(\+)))?(['.
+ '0-9])+)))?)))|((((-)|(\+))(((inf\.)|(nan\.))[0f]))))))))|(((('.
+ '((-)|(\+)))?(([0-9])+\\/([0-9])+))((-)|(\+))(([0-9])+\\/([0-9'.
+ '])+)i))|(((((-)|(\+)))?(([0-9])+\\/([0-9])+)))|(((((((-)|(\+)'.
+ '))?(((((([0-9])+)?(\.)?(([0-7])+(#)*)))|(((([0-7])+(#)*)(\.)?'.
+ '(#)*))|(((([0-7])+(#)*)\\/(([0-7])+(#)*))))(((([sl])|([def]))'.
+ '((((-)|(\+)))?([0-9])+)))?)))|((((-)|(\+))(((inf\.)|(nan\.))['.
+ '0f])))))|(((((-)|(\+)))?([0-9])+))))',
+ 3 => '(((#b#e)|(#e#b)|(#b#i)|(#i#b)|(#b))((((((((((((-)|(\+)))?(((('.
+ '(([0-9])+)?(\.)?(([0-1])+(#)*)))|(((([0-1])+(#)*)(\.)?(#)*))|'.
+ '(((([0-1])+(#)*)\\/(([0-1])+(#)*))))(((([sl])|([def]))((((-)|'.
+ '(\+)))?([0-9])+)))?)))|((((-)|(\+))(((inf\.)|(nan\.))[0f]))))'.
+ ')?((-)|(\+))(((((((([0-9])+)?(\.)?(([0-1])+(#)*)))|(((([0-1])'.
+ '+(#)*)(\.)?(#)*))|(((([0-1])+(#)*)\\/(([0-1])+(#)*))))(((([sl'.
+ '])|([def]))((((-)|(\+)))?([0-9])+)))?))|((((inf\.)|(nan\.))[0'.
+ 'f])))i))|((((((((-)|(\+)))?(((((([0-9])+)?(\.)?(([0-1])+(#)*)'.
+ '))|(((([0-1])+(#)*)(\.)?(#)*))|(((([0-1])+(#)*)\\/(([0-1])+(#'.
+ ')*))))(((([sl])|([def]))((((-)|(\+)))?([0-9])+)))?)))|((((-)|'.
+ '(\+))(((inf\.)|(nan\.))[0f]))))@((((((-)|(\+)))?(((((([0-9])+'.
+ ')?(\.)?(([0-1])+(#)*)))|(((([0-1])+(#)*)(\.)?(#)*))|(((([0-1]'.
+ ')+(#)*)\\/(([0-1])+(#)*))))(((([sl])|([def]))((((-)|(\+)))?(['.
+ '0-9])+)))?)))|((((-)|(\+))(((inf\.)|(nan\.))[0f]))))))))|(((('.
+ '((-)|(\+)))?(([0-9])+\\/([0-9])+))((-)|(\+))(([0-9])+\\/([0-9'.
+ '])+)i))|(((((-)|(\+)))?(([0-9])+\\/([0-9])+)))|(((((((-)|(\+)'.
+ '))?(((((([0-9])+)?(\.)?(([0-1])+(#)*)))|(((([0-1])+(#)*)(\.)?'.
+ '(#)*))|(((([0-1])+(#)*)\\/(([0-1])+(#)*))))(((([sl])|([def]))'.
+ '((((-)|(\+)))?([0-9])+)))?)))|((((-)|(\+))(((inf\.)|(nan\.))['.
+ '0f])))))|(((((-)|(\+)))?([0-9])+))))',
+ 4 => '((((#d#e)|(#e#d)|(#d#i)|(#i#d)|(#e)|(#i)|(#d)))?((((((((((((-'.
+ ')|(\+)))?(((((([0-9])+)?(\.)?(([0-9])+(#)*)))|(((([0-9])+(#)*'.
+ ')(\.)?(#)*))|(((([0-9])+(#)*)\\/(([0-9])+(#)*))))(((([sl])|(['.
+ 'def]))((((-)|(\+)))?([0-9])+)))?)))|((((-)|(\+))(((inf\.)|(na'.
+ 'n\.))[0f])))))?((-)|(\+))(((((((([0-9])+)?(\.)?(([0-9])+(#)*)'.
+ '))|(((([0-9])+(#)*)(\.)?(#)*))|(((([0-9])+(#)*)\\/(([0-9])+(#'.
+ ')*))))(((([sl])|([def]))((((-)|(\+)))?([0-9])+)))?))|((((inf'.
+ '\.)|(nan\.))[0f])))i))|((((((((-)|(\+)))?(((((([0-9])+)?(\.)?'.
+ '(([0-9])+(#)*)))|(((([0-9])+(#)*)(\.)?(#)*))|(((([0-9])+(#)*)'.
+ '\\/(([0-9])+(#)*))))(((([sl])|([def]))((((-)|(\+)))?([0-9])+)'.
+ '))?)))|((((-)|(\+))(((inf\.)|(nan\.))[0f]))))@((((((-)|(\+)))'.
+ '?(((((([0-9])+)?(\.)?(([0-9])+(#)*)))|(((([0-9])+(#)*)(\.)?(#'.
+ ')*))|(((([0-9])+(#)*)\\/(([0-9])+(#)*))))(((([sl])|([def]))(('.
+ '((-)|(\+)))?([0-9])+)))?)))|((((-)|(\+))(((inf\.)|(nan\.))[0f'.
+ ']))))))))|((((((-)|(\+)))?(([0-9])+\\/([0-9])+))((-)|(\+))((['.
+ '0-9])+\\/([0-9])+)i))|(((((-)|(\+)))?(([0-9])+\\/([0-9])+)))|'.
+ '(((((((-)|(\+)))?(((((([0-9])+)?(\.)?(([0-9])+(#)*)))|(((([0-'.
+ '9])+(#)*)(\.)?(#)*))|(((([0-9])+(#)*)\\/(([0-9])+(#)*))))(((('.
+ '[sl])|([def]))((((-)|(\+)))?([0-9])+)))?)))|((((-)|(\+))(((in'.
+ 'f\.)|(nan\.))[0f])))))|(((((-)|(\+)))?([0-9])+))))',
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: blue;',
+ 2 => 'color: rgb(34, 34, 139);',
+ 3 => 'color: blue;',
+ 4 => 'color: rgb(34, 34, 139);',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: rgb(194, 116, 31);',
+ 'MULTI' => 'color: rgb(194, 116, 31);',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: rgb(132, 60,36);',
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: rgb(34, 139, 34);',
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: rgb(34, 139, 34);',
+ 1 => 'color: rgb(34, 139, 34);',
+ 2 => 'color: rgb(34, 139, 34);',
+ 3 => 'color: rgb(34, 139, 34);',
+ 4 => 'color: rgb(34, 139, 34);',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #202020;',
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: rgb(132, 60,36);',
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: rgb(34, 139, 34);',
+ 2 => 'color: rgb(132, 60,36);',
+ 3 => 'color: rgb(34, 139, 34);',
+ ),
+ 'SCRIPT' => array(
+ ),
+ ),
+ 'URLS' => array(
+ 1 => 'http://docs.racket-lang.org/reference/',
+ 2 => 'http://docs.racket-lang.org/reference/',
+ 3 => 'http://docs.racket-lang.org/reference/',
+ 4 => 'http://docs.racket-lang.org/reference/',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 1 => '#\\\\(nul|null|backspace|tab|newline|linefeed|vtab|page|retur'.
+ 'n|space|rubout|([0-7]{1,3})|(u[[:xdigit:]]{1,4})|(U[[:xdigit:'.
+ ']]{1,6})|[a-z])',
+ 2 => '#:[^[:space:]()[\\]{}",\']+',
+ 3 => '\'((\\\\ )|([^[:space:]()[\\]{}",\']))+',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => '[[:space:]()[\\]{}",\']',
+ ),
+ 'ENABLE_FLAGS' => array(
+ 'SYMBOLS' => GESHI_MAYBE,
+ 'BRACKETS' => GESHI_MAYBE,
+ 'REGEXPS' => GESHI_MAYBE,
+ 'ESCAPE_CHAR' => GESHI_MAYBE,
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/rails.php b/platform/www/vendor/geshi/geshi/src/geshi/rails.php
new file mode 100644
index 0000000..9ca7046
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/rails.php
@@ -0,0 +1,404 @@
+<?php
+/*************************************************************************************
+ * rails.php
+ * ---------
+ * Author: Moises Deniz
+ * Copyright: (c) 2005 Moises Deniz
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/03/21
+ *
+ * Ruby (with Ruby on Rails Framework) language file for GeSHi.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Rails',
+ 'COMMENT_SINGLE' => array(1 => "#"),
+ 'COMMENT_MULTI' => array("=begin" => "=end"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', '`','\''),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'alias', 'and', 'begin', 'break', 'case', 'class',
+ 'def', 'defined', 'do', 'else', 'elsif', 'end',
+ 'ensure', 'for', 'if', 'in', 'module', 'while',
+ 'next', 'not', 'or', 'redo', 'rescue', 'yield',
+ 'retry', 'super', 'then', 'undef', 'unless',
+ 'until', 'when', 'BEGIN', 'END', 'include'
+ ),
+ 2 => array(
+ '__FILE__', '__LINE__', 'false', 'nil', 'self', 'true',
+ 'return'
+ ),
+ 3 => array(
+ 'Array', 'Float', 'Integer', 'String', 'at_exit',
+ 'autoload', 'binding', 'caller', 'catch', 'chop', 'chop!',
+ 'chomp', 'chomp!', 'eval', 'exec', 'exit', 'exit!', 'fail',
+ 'fork', 'format', 'gets', 'global_variables', 'gsub', 'gsub!',
+ 'iterator?', 'lambda', 'load', 'local_variables', 'loop',
+ 'open', 'p', 'print', 'printf', 'proc', 'putc', 'puts',
+ 'raise', 'rand', 'readline', 'readlines', 'require', 'select',
+ 'sleep', 'split', 'sprintf', 'srand', 'sub', 'sub!', 'syscall',
+ 'system', 'trace_var', 'trap', 'untrace_var'
+ ),
+ 4 => array(
+ 'Abbrev', 'ArgumentError', 'Base64', 'Benchmark',
+ 'Benchmark::Tms', 'Bignum', 'Binding', 'CGI', 'CGI::Cookie',
+ 'CGI::HtmlExtension', 'CGI::QueryExtension',
+ 'CGI::Session', 'CGI::Session::FileStore',
+ 'CGI::Session::MemoryStore', 'Class', 'Comparable', 'Complex',
+ 'ConditionVariable', 'Continuation', 'Data',
+ 'Date', 'DateTime', 'Delegator', 'Dir', 'EOFError', 'ERB',
+ 'ERB::Util', 'Enumerable', 'Enumerable::Enumerator', 'Errno',
+ 'Exception', 'FalseClass', 'File',
+ 'File::Constants', 'File::Stat', 'FileTest', 'FileUtils',
+ 'FileUtils::DryRun', 'FileUtils::NoWrite',
+ 'FileUtils::StreamUtils_', 'FileUtils::Verbose', 'Find',
+ 'Fixnum', 'FloatDomainError', 'Forwardable', 'GC', 'Generator',
+ 'Hash', 'IO', 'IOError', 'Iconv', 'Iconv::BrokenLibrary',
+ 'Iconv::Failure', 'Iconv::IllegalSequence',
+ 'Iconv::InvalidCharacter', 'Iconv::InvalidEncoding',
+ 'Iconv::OutOfRange', 'IndexError', 'Interrupt', 'Kernel',
+ 'LoadError', 'LocalJumpError', 'Logger', 'Logger::Application',
+ 'Logger::Error', 'Logger::Formatter', 'Logger::LogDevice',
+ 'Logger::LogDevice::LogDeviceMutex', 'Logger::Severity',
+ 'Logger::ShiftingError', 'Marshal', 'MatchData',
+ 'Math', 'Matrix', 'Method', 'Module', 'Mutex', 'NameError',
+ 'NameError::message', 'NilClass', 'NoMemoryError',
+ 'NoMethodError', 'NotImplementedError', 'Numeric', 'Object',
+ 'ObjectSpace', 'Observable', 'PStore', 'PStore::Error',
+ 'Pathname', 'Precision', 'Proc', 'Process', 'Process::GID',
+ 'Process::Status', 'Process::Sys', 'Process::UID', 'Queue',
+ 'Range', 'RangeError', 'Rational', 'Regexp', 'RegexpError',
+ 'RuntimeError', 'ScriptError', 'SecurityError', 'Set',
+ 'Shellwords', 'Signal', 'SignalException', 'SimpleDelegator',
+ 'SingleForwardable', 'Singleton', 'SingletonClassMethods',
+ 'SizedQueue', 'SortedSet', 'StandardError', 'StringIO',
+ 'StringScanner', 'StringScanner::Error', 'Struct', 'Symbol',
+ 'SyncEnumerator', 'SyntaxError', 'SystemCallError',
+ 'SystemExit', 'SystemStackError', 'Tempfile',
+ 'Test::Unit::TestCase', 'Test::Unit', 'Test', 'Thread',
+ 'ThreadError', 'ThreadGroup',
+ 'ThreadsWait', 'Time', 'TrueClass', 'TypeError', 'URI',
+ 'URI::BadURIError', 'URI::Error', 'URI::Escape', 'URI::FTP',
+ 'URI::Generic', 'URI::HTTP', 'URI::HTTPS',
+ 'URI::InvalidComponentError', 'URI::InvalidURIError',
+ 'URI::LDAP', 'URI::MailTo', 'URI::REGEXP',
+ 'URI::REGEXP::PATTERN', 'UnboundMethod', 'Vector', 'YAML',
+ 'ZeroDivisionError', 'Zlib',
+ 'Zlib::BufError', 'Zlib::DataError', 'Zlib::Deflate',
+ 'Zlib::Error', 'Zlib::GzipFile', 'Zlib::GzipFile::CRCError',
+ 'Zlib::GzipFile::Error', 'Zlib::GzipFile::LengthError',
+ 'Zlib::GzipFile::NoFooter', 'Zlib::GzipReader',
+ 'Zlib::GzipWriter', 'Zlib::Inflate', 'Zlib::MemError',
+ 'Zlib::NeedDict', 'Zlib::StreamEnd', 'Zlib::StreamError',
+ 'Zlib::VersionError',
+ 'Zlib::ZStream',
+ 'ActionController::AbstractRequest',
+ 'ActionController::Assertions::DomAssertions',
+ 'ActionController::Assertions::ModelAssertions',
+ 'ActionController::Assertions::ResponseAssertions',
+ 'ActionController::Assertions::RoutingAssertions',
+ 'ActionController::Assertions::SelectorAssertions',
+ 'ActionController::Assertions::TagAssertions',
+ 'ActionController::Base',
+ 'ActionController::Benchmarking::ClassMethods',
+ 'ActionController::Caching',
+ 'ActionController::Caching::Actions',
+ 'ActionController::Caching::Actions::ActionCachePath',
+ 'ActionController::Caching::Fragments',
+ 'ActionController::Caching::Pages',
+ 'ActionController::Caching::Pages::ClassMethods',
+ 'ActionController::Caching::Sweeping',
+ 'ActionController::Components',
+ 'ActionController::Components::ClassMethods',
+ 'ActionController::Components::InstanceMethods',
+ 'ActionController::Cookies',
+ 'ActionController::Filters::ClassMethods',
+ 'ActionController::Flash',
+ 'ActionController::Flash::FlashHash',
+ 'ActionController::Helpers::ClassMethods',
+ 'ActionController::Integration::Session',
+ 'ActionController::IntegrationTest',
+ 'ActionController::Layout::ClassMethods',
+ 'ActionController::Macros',
+ 'ActionController::Macros::AutoComplete::ClassMethods',
+ 'ActionController::Macros::InPlaceEditing::ClassMethods',
+ 'ActionController::MimeResponds::InstanceMethods',
+ 'ActionController::Pagination',
+ 'ActionController::Pagination::ClassMethods',
+ 'ActionController::Pagination::Paginator',
+ 'ActionController::Pagination::Paginator::Page',
+ 'ActionController::Pagination::Paginator::Window',
+ 'ActionController::Rescue', 'ActionController::Resources',
+ 'ActionController::Routing',
+ 'ActionController::Scaffolding::ClassMethods',
+ 'ActionController::SessionManagement::ClassMethods',
+ 'ActionController::Streaming', 'ActionController::TestProcess',
+ 'ActionController::TestUploadedFile',
+ 'ActionController::UrlWriter',
+ 'ActionController::Verification::ClassMethods',
+ 'ActionMailer::Base', 'ActionView::Base',
+ 'ActionView::Helpers::ActiveRecordHelper',
+ 'ActionView::Helpers::AssetTagHelper',
+ 'ActionView::Helpers::BenchmarkHelper',
+ 'ActionView::Helpers::CacheHelper',
+ 'ActionView::Helpers::CaptureHelper',
+ 'ActionView::Helpers::DateHelper',
+ 'ActionView::Helpers::DebugHelper',
+ 'ActionView::Helpers::FormHelper',
+ 'ActionView::Helpers::FormOptionsHelper',
+ 'ActionView::Helpers::FormTagHelper',
+ 'ActionView::Helpers::JavaScriptHelper',
+ 'ActionView::Helpers::JavaScriptMacrosHelper',
+ 'ActionView::Helpers::NumberHelper',
+ 'ActionView::Helpers::PaginationHelper',
+ 'ActionView::Helpers::PrototypeHelper',
+ 'ActionView::Helpers::PrototypeHelper::JavaScriptGenerator::GeneratorMethods',
+ 'ActionView::Helpers::ScriptaculousHelper',
+ 'ActionView::Helpers::TagHelper',
+ 'ActionView::Helpers::TextHelper',
+ 'ActionView::Helpers::UrlHelper', 'ActionView::Partials',
+ 'ActionWebService::API::Method', 'ActionWebService::Base',
+ 'ActionWebService::Client::Soap',
+ 'ActionWebService::Client::XmlRpc',
+ 'ActionWebService::Container::ActionController::ClassMethods',
+ 'ActionWebService::Container::Delegated::ClassMethods',
+ 'ActionWebService::Container::Direct::ClassMethods',
+ 'ActionWebService::Invocation::ClassMethods',
+ 'ActionWebService::Scaffolding::ClassMethods',
+ 'ActionWebService::SignatureTypes', 'ActionWebService::Struct',
+ 'ActiveRecord::Acts::List::ClassMethods',
+ 'ActiveRecord::Acts::List::InstanceMethods',
+ 'ActiveRecord::Acts::NestedSet::ClassMethods',
+ 'ActiveRecord::Acts::NestedSet::InstanceMethods',
+ 'ActiveRecord::Acts::Tree::ClassMethods',
+ 'ActiveRecord::Acts::Tree::InstanceMethods',
+ 'ActiveRecord::Aggregations::ClassMethods',
+ 'ActiveRecord::Associations::ClassMethods',
+ 'ActiveRecord::AttributeMethods::ClassMethods',
+ 'ActiveRecord::Base',
+ 'ActiveRecord::Calculations::ClassMethods',
+ 'ActiveRecord::Callbacks',
+ 'ActiveRecord::ConnectionAdapters::AbstractAdapter',
+ 'ActiveRecord::ConnectionAdapters::Column',
+ 'ActiveRecord::ConnectionAdapters::DB2Adapter',
+ 'ActiveRecord::ConnectionAdapters::DatabaseStatements',
+ 'ActiveRecord::ConnectionAdapters::FirebirdAdapter',
+ 'ActiveRecord::ConnectionAdapters::FrontBaseAdapter',
+ 'ActiveRecord::ConnectionAdapters::MysqlAdapter',
+ 'ActiveRecord::ConnectionAdapters::OpenBaseAdapter',
+ 'ActiveRecord::ConnectionAdapters::OracleAdapter',
+ 'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter',
+ 'ActiveRecord::ConnectionAdapters::Quoting',
+ 'ActiveRecord::ConnectionAdapters::SQLServerAdapter',
+ 'ActiveRecord::ConnectionAdapters::SQLiteAdapter',
+ 'ActiveRecord::ConnectionAdapters::SchemaStatements',
+ 'ActiveRecord::ConnectionAdapters::SybaseAdapter::ColumnWithIdentity',
+ 'ActiveRecord::ConnectionAdapters::SybaseAdapterContext',
+ 'ActiveRecord::ConnectionAdapters::TableDefinition',
+ 'ActiveRecord::Errors', 'ActiveRecord::Locking',
+ 'ActiveRecord::Locking::Optimistic',
+ 'ActiveRecord::Locking::Optimistic::ClassMethods',
+ 'ActiveRecord::Locking::Pessimistic',
+ 'ActiveRecord::Migration', 'ActiveRecord::Observer',
+ 'ActiveRecord::Observing::ClassMethods',
+ 'ActiveRecord::Reflection::ClassMethods',
+ 'ActiveRecord::Reflection::MacroReflection',
+ 'ActiveRecord::Schema', 'ActiveRecord::Timestamp',
+ 'ActiveRecord::Transactions::ClassMethods',
+ 'ActiveRecord::Validations',
+ 'ActiveRecord::Validations::ClassMethods',
+ 'ActiveRecord::XmlSerialization',
+ 'ActiveSupport::CachingTools::HashCaching',
+ 'ActiveSupport::CoreExtensions::Array::Conversions',
+ 'ActiveSupport::CoreExtensions::Array::Grouping',
+ 'ActiveSupport::CoreExtensions::Date::Conversions',
+ 'ActiveSupport::CoreExtensions::Hash::Conversions',
+ 'ActiveSupport::CoreExtensions::Hash::Conversions::ClassMethods',
+ 'ActiveSupport::CoreExtensions::Hash::Diff',
+ 'ActiveSupport::CoreExtensions::Hash::Keys',
+ 'ActiveSupport::CoreExtensions::Hash::ReverseMerge',
+ 'ActiveSupport::CoreExtensions::Integer::EvenOdd',
+ 'ActiveSupport::CoreExtensions::Integer::Inflections',
+ 'ActiveSupport::CoreExtensions::Numeric::Bytes',
+ 'ActiveSupport::CoreExtensions::Numeric::Time',
+ 'ActiveSupport::CoreExtensions::Pathname::CleanWithin',
+ 'ActiveSupport::CoreExtensions::Range::Conversions',
+ 'ActiveSupport::CoreExtensions::String::Access',
+ 'ActiveSupport::CoreExtensions::String::Conversions',
+ 'ActiveSupport::CoreExtensions::String::Inflections',
+ 'ActiveSupport::CoreExtensions::String::Iterators',
+ 'ActiveSupport::CoreExtensions::String::StartsEndsWith',
+ 'ActiveSupport::CoreExtensions::String::Unicode',
+ 'ActiveSupport::CoreExtensions::Time::Calculations',
+ 'ActiveSupport::CoreExtensions::Time::Calculations::ClassMethods',
+ 'ActiveSupport::CoreExtensions::Time::Conversions',
+ 'ActiveSupport::Multibyte::Chars',
+ 'ActiveSupport::Multibyte::Handlers::UTF8Handler',
+ 'Breakpoint', 'Builder::BlankSlate', 'Builder::XmlMarkup',
+ 'Fixtures',
+ 'HTML::Selector', 'HashWithIndifferentAccess', 'Inflector',
+ 'Inflector::Inflections', 'Mime', 'Mime::Type',
+ 'OCI8AutoRecover', 'TimeZone', 'XmlSimple'
+ ),
+ 5 => array(
+ 'image_tag', 'link_to', 'link_to_remote', 'javascript_include_tag',
+ 'assert_equal', 'assert_not_equal', 'before_filter',
+ 'after_filter', 'render', 'redirect_to', 'hide_action',
+ 'render_to_string', 'url_for', 'controller_name',
+ 'controller_class_name', 'controller_path', 'session',
+ 'render_component', 'render_component_as_string', 'cookie',
+ 'layout', 'flash', 'auto_complete_for', 'in_place_editor_for',
+ 'respond_to', 'paginate', 'current_page', 'each', 'first',
+ 'first_page', 'last_page', 'last', 'length', 'new', 'page_count',
+ 'previous', 'scaffold', 'send_data',
+ 'send_file', 'deliver', 'receive', 'error_messages_for',
+ 'error_message_on', 'form', 'input', 'stylesheet_link_tag',
+ 'stylesheet_path', 'content_for', 'select_date', 'ago',
+ 'month', 'day', 'check_box', 'fields_for', 'file_field',
+ 'form_for', 'hidden_field', 'text_area', 'password_field',
+ 'collection_select', 'options_for_select',
+ 'options_from_collection_for_select', 'file_field_tag',
+ 'form_for_tag', 'hidden_field_tag', 'text_area_tag',
+ 'password_field_tag', 'link_to_function', 'javascript_tag',
+ 'human_size', 'number_to_currency', 'pagination_links',
+ 'form_remote_tag', 'form_remote_for',
+ 'submit_to_remote', 'remote_function', 'observe_form',
+ 'observe_field', 'remote_form_for', 'options_for_ajax', 'alert',
+ 'call', 'assign', 'show', 'hide', 'insert_html', 'sortable',
+ 'toggle', 'visual_effect', 'replace', 'replace_html', 'remove',
+ 'save', 'save!', 'draggable', 'drop_receiving', 'literal',
+ 'draggable_element', 'drop_receiving_element', 'sortable_element',
+ 'content_tag', 'tag', 'link_to_image', 'link_to_if',
+ 'link_to_unless', 'mail_to', 'link_image_to', 'button_to',
+ 'current_page?', 'act_as_list', 'act_as_nested', 'act_as_tree',
+ 'has_many', 'has_one', 'belongs_to', 'has_many_and_belogns_to',
+ 'delete', 'destroy', 'destroy_all', 'clone', 'deep_clone', 'copy',
+ 'update', 'table_name', 'primary_key', 'sum', 'maximun', 'minimum',
+ 'count', 'size', 'after_save', 'after_create', 'before_save',
+ 'before_create', 'add_to_base', 'errors', 'add', 'validate',
+ 'validates_presence_of', 'validates_numericality_of',
+ 'validates_uniqueness_of', 'validates_length_of',
+ 'validates_format_of', 'validates_size_of', 'to_a', 'to_s',
+ 'to_xml', 'to_i'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '%', '&', '*', '|', '/', '<', '>',
+ '+', '-', '=>', '<<'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color:#9966CC; font-weight:bold;',
+ 2 => 'color:#0000FF; font-weight:bold;',
+ 3 => 'color:#CC0066; font-weight:bold;',
+ 4 => 'color:#CC00FF; font-weight:bold;',
+ 5 => 'color:#5A0A0A; font-weight:bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color:#008000; font-style:italic;',
+ 'MULTI' => 'color:#000080; font-style:italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color:#000099;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color:#006600; font-weight:bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color:#996600;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color:#006666;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color:#9900CC;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color:#006600; font-weight:bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color:#ff6633; font-weight:bold;',
+ 1 => 'color:#0066ff; font-weight:bold;',
+ 2 => 'color:#6666ff; font-weight:bold;',
+ 3 => 'color:#ff3333; font-weight:bold;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ 0 => array(
+ GESHI_SEARCH => "([[:space:]])(\\$[a-zA-Z_][a-zA-Z0-9_]*)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 1 => array(
+ GESHI_SEARCH => "([[:space:]])(@[a-zA-Z_][a-zA-Z0-9_]*)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 2 => "([A-Z][a-zA-Z0-9_]*::)+[A-Z][a-zA-Z0-9_]*", //Static OOP References
+ 3 => array(
+ GESHI_SEARCH => "([[:space:]]|\[|\()(:[a-zA-Z_][a-zA-Z0-9_]*)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<%' => '%>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/rbs.php b/platform/www/vendor/geshi/geshi/src/geshi/rbs.php
new file mode 100644
index 0000000..6e9e775
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/rbs.php
@@ -0,0 +1,224 @@
+<?php
+/*************************************************************************************
+ * rbs.php
+ * ------
+ * Author: Deng Wen Gang (deng@priity.com)
+ * Copyright: (c) 2013 Deng Wen Gang
+ * Release Version: 1.0.9.1
+ * Date Started: 2013/01/15
+ *
+ * RBScript language file for GeSHi.
+ *
+ * RBScript official website: http://docs.realsoftware.com/index.php/Rbscript
+ *
+ * CHANGES
+ * -------
+ * 2013/01/15 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'RBScript',
+ 'COMMENT_SINGLE' => array( 1 => '//', 2 => "'" ),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 3 => '/REM\s.*$/im',
+ 4 => '/&b[01]+/',
+ 5 => '/&o[0-7]+/',
+ 6 => '/&h[a-f0-9]+/i',
+ 7 => '/&c[a-f0-9]+/i',
+ 8 => '/&u[a-f0-9]+/i',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'Int8', 'Int16', 'Int32', 'Int64', 'Uint8', 'Uint16', 'Uint32', 'Uint64', 'Byte', 'Integer',
+ 'Single', 'Double', 'Boolean', 'String', 'Color', 'Object', 'Variant'
+ ),
+ 2 => array(
+ 'Private', 'Public', 'Protected',
+ 'Sub', 'Function', 'Delegate', 'Exception',
+ ),
+ 3 => array(
+ 'IsA',
+ 'And', 'Or', 'Not', 'Xor',
+ 'If', 'Then', 'Else', 'ElseIf',
+ 'Select', 'Case',
+ 'For', 'Each', 'In', 'To', 'Step', 'Next',
+ 'Do', 'Loop', 'Until',
+ 'While', 'Wend',
+ 'Continue', 'Exit', 'Goto', 'End',
+ ),
+ 4 => array(
+ 'Const', 'Static',
+ 'Dim', 'As', 'Redim',
+ 'Me', 'Self', 'Super', 'Extends', 'Implements',
+ 'ByRef', 'ByVal', 'Assigns', 'ParamArray',
+ 'Mod',
+ 'Raise',
+ ),
+ 5 => array(
+ 'False', 'True', 'Nil'
+ ),
+ 6 => array(
+ 'Abs',
+ 'Acos',
+ 'Asc',
+ 'AscB',
+ 'Asin',
+ 'Atan',
+ 'Atan2',
+ 'CDbl',
+ 'Ceil',
+ 'Chr',
+ 'ChrB',
+ 'CMY',
+ 'Cos',
+ 'CountFields',
+ 'CStr',
+ 'Exp',
+ 'Floor',
+ 'Format',
+ 'Hex',
+ 'HSV',
+ 'InStr',
+ 'InStrB',
+ 'Left',
+ 'LeftB',
+ 'Len',
+ 'LenB',
+ 'Log',
+ 'Lowercase',
+ 'LTrim',
+ 'Max',
+ 'Microseconds',
+ 'Mid',
+ 'MidB',
+ 'Min',
+ 'NthField',
+ 'Oct',
+ 'Pow',
+ 'Replace',
+ 'ReplaceB',
+ 'ReplaceAll',
+ 'ReplaceAllB',
+ 'RGB',
+ 'Right',
+ 'RightB',
+ 'Rnd',
+ 'Round',
+ 'RTrim',
+ 'Sin',
+ 'Sqrt',
+ 'Str',
+ 'StrComp',
+ 'Tan',
+ 'Ticks',
+ 'Titlecase',
+ 'Trim',
+ 'UBound',
+ 'Uppercase',
+ 'Val',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '+', '-', '*', '/', '\\', '^', '<', '>', '=', '<>', '&'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #F660AB; font-weight: bold;',
+ 2 => 'color: #E56717; font-weight: bold;',
+ 3 => 'color: #8D38C9; font-weight: bold;',
+ 4 => 'color: #151B8D; font-weight: bold;',
+ 5 => 'color: #00C2FF; font-weight: bold;',
+ 6 => 'color: #3EA99F; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000;',
+ 2 => 'color: #008000;',
+ 3 => 'color: #008000;',
+
+ 4 => 'color: #800000;',
+ 5 => 'color: #800000;',
+ 6 => 'color: #800000;',
+ 7 => 'color: #800000;',
+ 8 => 'color: #800000;',
+ ),
+ 'BRACKETS' => array(
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #800000;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #800000; font-weight: bold;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER,
+ 'SYMBOLS' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/rebol.php b/platform/www/vendor/geshi/geshi/src/geshi/rebol.php
new file mode 100644
index 0000000..16c4cea
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/rebol.php
@@ -0,0 +1,194 @@
+<?php
+/*************************************************************************************
+ * rebol.php
+ * --------
+ * Author: Lecanu Guillaume (Guillaume@LyA.fr)
+ * Copyright: (c) 2004-2005 Lecanu Guillaume (Guillaume@LyA.fr)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/12/22
+ *
+ * Rebol language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/01/26 (1.0.8.3)
+ * - Adapted language file to comply to GeSHi language file guidelines
+ * 2004/11/25 (1.0.3)
+ * - Added support for multiple object splitters
+ * - Fixed &new problem
+ * 2004/10/27 (1.0.2)
+ * - Added URL support
+ * - Added extra constants
+ * 2004/08/05 (1.0.1)
+ * - Added support for symbols
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * * Make sure the last few function I may have missed
+ * (like eval()) are included for highlighting
+ * * Split to several files - php4, php5 etc
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'REBOL',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array('rebol [' => ']', 'comment [' => ']'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'binary!','block!','char!','date!','decimal!','email!','file!',
+ 'hash!','integer!','issue!','list!','logic!','money!','none!',
+ 'object!','paren!','pair!','path!','string!','tag!','time!',
+ 'tuple!','url!',
+ ),
+ 2 => array(
+ 'all','any','attempt','break','catch','compose','disarm','dispatch',
+ 'do','do-events','does','either','else','exit','for','forall',
+ 'foreach','forever','forskip','func','function','halt','has','if',
+ 'launch','loop','next','quit','reduce','remove-each','repeat',
+ 'return','secure','switch','throw','try','until','wait','while',
+ ),
+ 3 => array(
+ 'about','abs','absolute','add','alert','alias','alter','and',
+ 'any-block?','any-function?','any-string?','any-type?','any-word?',
+ 'append','arccosine','arcsine','arctangent','array','as-pair',
+ 'ask','at','back','binary?','bind','bitset?','block?','brightness?',
+ 'browse','build-tag','caret-to-offset','center-face','change',
+ 'change-dir','char?','charset','checksum','choose','clean-path',
+ 'clear','clear-fields','close','comment','complement','component?',
+ 'compress','confirm','connected?','construct','context','copy',
+ 'cosine','datatype?','date?','debase','decimal?','decode-cgi',
+ 'decompress','dehex','delete','detab','difference','dir?','dirize',
+ 'divide','dump-face','dump-obj','echo','email?','empty?','enbase',
+ 'entab','equal?','error?','even?','event?','exclude','exists?',
+ 'exp','extract','fifth','file?','find','first','flash','focus',
+ 'form','found?','fourth','free','function?','get','get-modes',
+ 'get-word?','greater-or-equal?','greater?','hash?','head','head?',
+ 'help','hide','hide-popup','image?','import-email','in',
+ 'in-window?','index?','info?','inform','input','input?','insert',
+ 'integer?','intersect','issue?','join','last','layout','length?',
+ 'lesser-or-equal?','lesser?','library?','license','link?',
+ 'list-dir','list?','lit-path?','lit-word?','load','load-image',
+ 'log-10','log-2','log-e','logic?','lowercase','make','make-dir',
+ 'make-face','max','maximum','maximum-of','min','minimum',
+ 'minimum-of','modified?','mold','money?','multiply','native?',
+ 'negate','negative?','none?','not','not-equal?','now','number?',
+ 'object?','odd?','offset-to-caret','offset?','op?','open','or',
+ 'pair?','paren?','parse','parse-xml','path?','pick','poke','port?',
+ 'positive?','power','prin','print','probe','protect',
+ 'protect-system','query','random','read','read-io','recycle',
+ 'refinement?','reform','rejoin','remainder','remold','remove',
+ 'rename',
+ //'repeat',
+ 'repend','replace','request','request-color','request-date',
+ 'request-download','request-file','request-list','request-pass',
+ 'request-text','resend','reverse','routine?','same?','save',
+ 'script?','second','select','send','series?','set','set-modes',
+ 'set-net','set-path?','set-word?','show','show-popup','sign?',
+ 'sine','size-text','size?','skip','sort','source','span?',
+ 'split-path','square-root','strict-equal?','strict-not-equal?',
+ 'string?','struct?','stylize','subtract','suffix?','tag?','tail',
+ 'tail?','tangent','third','time?','to','to-binary','to-bitset',
+ 'to-block','to-char','to-date','to-decimal','to-email','to-file',
+ 'to-get-word','to-hash','to-hex','to-idate','to-image','to-integer',
+ 'to-issue','to-list','to-lit-path','to-lit-word','to-local-file',
+ 'to-logic','to-money','to-pair','to-paren','to-path',
+ 'to-rebol-file','to-refinement','to-set-path','to-set-word',
+ 'to-string','to-tag','to-time','to-tuple','to-url','to-word',
+ 'trace','trim','tuple?','type?','unfocus','union','unique',
+ 'unprotect','unset','unset?','unview','update','upgrade',
+ 'uppercase','url?','usage','use','value?','view','viewed?','what',
+ 'what-dir','within?','word?','write','write-io','xor','zero?',
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '!', '@', '%', '&', '*', '|', '/', '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+// 2 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+// 2 => 'includes/dico_rebol.php?word={FNAME}',
+// 3 => 'includes/dico_rebol.php?word={FNAME}'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*",
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/reg.php b/platform/www/vendor/geshi/geshi/src/geshi/reg.php
new file mode 100644
index 0000000..c966674
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/reg.php
@@ -0,0 +1,231 @@
+<?php
+/*************************************************************************************
+ * reg.php
+ * -------
+ * Author: Sean Hanna (smokingrope@gmail.com)
+ * Copyright: (c) 2006 Sean Hanna
+ * Release Version: 1.0.9.1
+ * Date Started: 03/15/2006
+ *
+ * Microsoft Registry Editor language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * - Updated and optimized most regular expressions
+ * 03/15/2006 (0.5.0)
+ * - Syntax File Created
+ * 04/27/2006 (0.9.5)
+ * - Syntax Coloring Cleaned Up
+ * - First Release
+ * 04/29/2006 (1.0.0)
+ * - Updated a few coloring settings
+ *
+ * TODO (updated 4/27/2006)
+ * -------------------------
+ * - Add a verification to the multi-line portion of the hex field regex
+ * for a '\' character on the line preceding the line of the multi-line
+ * hex field.
+ *
+ * KNOWN ISSUES (updated 4/27/2006)
+ * ---------------------------------
+ *
+ * - There are two regexes for the multiline hex value regex. The regex for
+ * all lines after the first does not verify that the previous line contains
+ * a line continuation character '\'. This regex also does not check for
+ * end of line as it should.
+ *
+ * - If number_highlighting is enabled during processing of this syntax file
+ * many of the regexps used will appear slightly incorrect.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+
+ ************************************************************************************/
+$language_data = array (
+ 'LANG_NAME' => 'Microsoft Registry',
+ 'COMMENT_SINGLE' => array(1 =>';'),
+ 'COMMENT_MULTI' => array( ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+// 1 => array(),
+// 2 => array(),
+ /* Registry Key Constants Not Used */
+ 3 => array(
+ 'HKEY_LOCAL_MACHINE',
+ 'HKEY_CLASSES_ROOT',
+ 'HKEY_CURRENT_USER',
+ 'HKEY_USERS',
+ 'HKEY_CURRENT_CONFIG',
+ 'HKEY_DYN_DATA',
+ 'HKLM', 'HKCR', 'HKCU', 'HKU', 'HKCC', 'HKDD'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+// 1 => false,
+// 2 => false,
+ 3 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+// 1 => 'color: #00CCFF;',
+// 2 => 'color: #0000FF;',
+ 3 => 'color: #800000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #009900;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #00CCFF;',
+ 1 => 'color: #0000FF;',
+ 2 => '',
+ 3 => 'color: #0000FF;',
+ 4 => 'color: #0000FF;',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => 'color: #FF6600;',
+ )
+ ),
+ 'URLS' => array(
+// 1 => '',
+// 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ // Highlight Key Delimiters
+ 0 => array(
+ GESHI_SEARCH => '((^|\\n)\\s*)(\\\\\\[(.*)\\\\\\])(\\s*(\\n|$))',
+ GESHI_REPLACE => '\\3',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\5'
+// GESHI_CLASS => 'kw1'
+ ),
+ // Highlight File Format Header Version 5
+ 1 => array(
+ GESHI_SEARCH => '(^\s*)(Windows Registry Editor Version \d+\.\d+)(\s*$)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3',
+ GESHI_CLASS => 'geshi_registry_header'
+ ),
+ // Highlight File Format Header Version 4
+ 2 => array(
+ GESHI_SEARCH => '(^\\s*)(REGEDIT\s?\d+)(\s*$)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3',
+ GESHI_CLASS => 'geshi_registry_header'
+ ),
+ // Highlight dword: 32 bit integer values
+ 3 => array(
+ GESHI_SEARCH => '(=\s*)(dword:[0-9a-fA-F]{8})(\s*$)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+// GESHI_CLASS => 'kw2'
+ ),
+ // Highlight variable names
+ 4 => array(
+ GESHI_SEARCH => '(^\s*)(\&quot;.*?\&quot;)(\s*=)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3',
+ GESHI_CLASS => 'geshi_variable'
+ ),
+ // Highlight String Values
+ 5 => array(
+ GESHI_SEARCH => '(=\s*)(\&quot;.*?\&quot;)(\s*$)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3',
+ GESHI_CLASS => 'st0'
+ ),
+ // Highlight Hexadecimal Values (Single-Line and Multi-Line)
+ 6 => array(
+ GESHI_SEARCH => '(=\s*\n?\s*)(hex:[0-9a-fA-F]{2}(,(\\\s*\n\s*)?[0-9a-fA-F]{2})*)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '',
+ GESHI_CLASS => 'kw2'
+ ),
+ // Highlight Default Variable
+ 7 => array(
+ GESHI_SEARCH => '(^\s*)(@)(\s*=)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3',
+ GESHI_CLASS => 'geshi_variable'
+ ),
+ // Highlight GUID's found anywhere.
+ 8 => array(
+ GESHI_SEARCH => '(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\})',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '',
+ GESHI_CLASS => 'geshi_guid'
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'NUMBERS' => GESHI_NEVER,
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/rexx.php b/platform/www/vendor/geshi/geshi/src/geshi/rexx.php
new file mode 100644
index 0000000..6a4f1a8
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/rexx.php
@@ -0,0 +1,160 @@
+<?php
+/*************************************************************************************
+ * rexx.php
+ * ---------------------------------
+ * Author: Jon Wolfers (sahananda@windhorse.biz)
+ * Contributors:
+ * - Walter Pachl (pachl@chello.at)
+ * Copyright: (c) 2008 Jon Wolfers, (c) 2012 Walter Pachl
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/01/07
+ *
+ * Rexx language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2012/07/29 (1.0.0)
+ * - tried to get it syntactically right
+ *
+ * TODO (updated 2012/07/29)
+ * -------------------------
+ * - Get it working on rosettacode.org
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'rexx',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'address', 'arg', 'attribute', 'call', 'constant', 'do',
+ 'drop', 'exit', 'forward', 'if',
+ 'interpret', 'iterate', 'leave', 'loop', 'nop', 'numeric',
+ 'options', 'parse', 'procedure', 'pull', 'push', 'queue',
+ 'raise', 'return', 'say', 'select', 'signal', 'trace'
+ ),
+ 2 => array(
+ 'by', 'digits', 'engineering', 'error', 'expose',
+ 'failure', 'for', 'forever', 'form', 'fuzz', 'halt',
+ 'name', 'novalue', 'off', 'on', 'over', 'scientific', 'source',
+ 'syntax', 'to', 'until', 'upper', 'version',
+ 'while', 'with'
+ ),
+ 3 => array(
+ 'else', 'end', 'otherwise', 'then', 'when'
+ ),
+ 4 => array(
+ 'rc', 'result', 'sigl'
+ ),
+ 5 => array(
+ 'placeholderforoorexxdirectives'
+ ),
+ 6 => array(
+ 'abbrev', 'abs', 'beep', 'bitand', 'bitor',
+ 'bitxor', 'b2x', 'center', 'centre', 'changestr', 'charin',
+ 'charout', 'chars', 'compare', 'condition', 'copies',
+ 'countstr', 'c2d', 'c2x', 'datatype', 'date', 'delstr',
+ 'delword', 'directory', 'd2c', 'd2x', 'endlocal',
+ 'errortext', 'filespec', 'format', 'insert',
+ 'lastpos', 'left', 'length', 'linein', 'lineout', 'lines',
+ 'lower', 'max', 'min', 'overlay', 'pos', 'queued', 'random',
+ 'reverse', 'right', 'rxfuncadd', 'rxfuncdrop', 'rxfuncquery',
+ 'rxqueue', 'setlocal', 'sign', 'sourceline', 'space',
+ 'stream', 'strip', 'substr', 'subword', 'symbol', 'time',
+ 'translate', 'trunc', 'userid', 'value',
+ 'var', 'verify', 'word', 'wordindex', 'wordlength', 'wordpos',
+ 'words', 'xrange', 'x2b', 'x2c', 'x2d'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '<', '>', '=', '+', '-', '*', '**', '/', '|', '%', '^', '&', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #ff0000; font-weight: bold;',
+ 3 => 'color: #00ff00; font-weight: bold;',
+ 4 => 'color: #0000ff; font-weight: bold;',
+ 5 => 'color: #880088; font-weight: bold;',
+ 6 => 'color: #888800; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666;',
+ 'MULTI' => 'color: #808080;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/robots.php b/platform/www/vendor/geshi/geshi/src/geshi/robots.php
new file mode 100644
index 0000000..92863c3
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/robots.php
@@ -0,0 +1,98 @@
+<?php
+/*************************************************************************************
+ * robots.php
+ * --------
+ * Author: Christian Lescuyer (cl@goelette.net)
+ * Copyright: (c) 2006 Christian Lescuyer http://xtian.goelette.info
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/02/17
+ *
+ * robots.txt language file for GeSHi.
+ *
+ * 2006/02/17 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'robots.txt',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(1 => "/^Comment:.*?/m"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'Allow', 'Crawl-delay', 'Disallow', 'Request-rate', 'Robot-version',
+ 'Sitemap', 'User-agent', 'Visit-time'
+ )
+ ),
+ 'SYMBOLS' => array(
+ ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.robotstxt.org/wc/norobots.html'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/roff.php b/platform/www/vendor/geshi/geshi/src/geshi/roff.php
new file mode 100644
index 0000000..6f87690
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/roff.php
@@ -0,0 +1,510 @@
+<?php
+/*************************************************************************************
+ * roff.php
+ * ---------------------------------
+ * Author: Artur Iwicki (iwicki DOT artur AT svgames DOT pl)
+ * Copyright: (c) 2017 Artur Iwicki
+ * Release Version: 1.0.9.1
+ * Date Started: 2017-11-17
+ *
+ * roff (Unix man page) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2018-12-06 (1.0.1)
+ * - Fix reqex for line-start requests (must start with [.'], not [\.'])
+ * - Add some missing whitespace escapes
+ * 2017-11-20 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'roff',
+ 'COMMENT_SINGLE' => array(
+ 1 => '\\"',
+ 2 => '\\#',
+ ),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 1 => '/^\\.\\\\"[[:print:]]*/m'
+ ),
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ ),
+ 'KEYWORDS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '\\[-D]', '\\(-D',
+ '\\[Sd]', '\\(Sd',
+ '\\[TP]', '\\(TP',
+ '\\[Tp]', '\\(Tp',
+ '\\[ss]', '\\(ss',
+ '\\[ff]', '\\(ff',
+ '\\[fi]', '\\(fi',
+ '\\[fl]', '\\(fl',
+ '\\[Fi]', '\\(Fi',
+ '\\[Fl]', '\\(Fl',
+ '\\[/L]', '\\(/L',
+ '\\[/l]', '\\(/l',
+ '\\[/O]', '\\(/O',
+ '\\[/o]', '\\(/o',
+ '\\[AE]', '\\(AE',
+ '\\[ae]', '\\(ae',
+ '\\[OE]', '\\(OE',
+ '\\[oe]', '\\(oe',
+ '\\[IJ]', '\\(IJ',
+ '\\[ij]', '\\(ij',
+ '\\[.i]', '\\(.i',
+ '\\[.j]', '\\(.j',
+ '\\[\'A]', '\\(\'A',
+ '\\[\'C]', '\\(\'C',
+ '\\[\'E]', '\\(\'E',
+ '\\[\'I]', '\\(\'I',
+ '\\[\'O]', '\\(\'O',
+ '\\[\'U]', '\\(\'U',
+ '\\[\'Y]', '\\(\'Y',
+ '\\[\'a]', '\\(\'a',
+ '\\[\'c]', '\\(\'c',
+ '\\[\'e]', '\\(\'e',
+ '\\[\'i]', '\\(\'i',
+ '\\[\'o]', '\\(\'o',
+ '\\[\'u]', '\\(\'u',
+ '\\[\'y]', '\\(\'y',
+ '\\[:A]', '\\(:A',
+ '\\[:E]', '\\(:E',
+ '\\[:I]', '\\(:I',
+ '\\[:O]', '\\(:O',
+ '\\[:U]', '\\(:U',
+ '\\[:Y]', '\\(:Y',
+ '\\[:a]', '\\(:a',
+ '\\[:e]', '\\(:e',
+ '\\[:i]', '\\(:i',
+ '\\[:o]', '\\(:o',
+ '\\[:u]', '\\(:u',
+ '\\[:y]', '\\(:y',
+ '\\[^A]', '\\(^A',
+ '\\[^E]', '\\(^E',
+ '\\[^I]', '\\(^I',
+ '\\[^O]', '\\(^O',
+ '\\[^U]', '\\(^U',
+ '\\[^a]', '\\(^a',
+ '\\[^e]', '\\(^e',
+ '\\[^i]', '\\(^i',
+ '\\[^o]', '\\(^o',
+ '\\[^u]', '\\(^u',
+ '\\[`A]', '\\(`A',
+ '\\[`E]', '\\(`E',
+ '\\[`I]', '\\(`I',
+ '\\[`O]', '\\(`O',
+ '\\[`U]', '\\(`U',
+ '\\[`a]', '\\(`a',
+ '\\[`e]', '\\(`e',
+ '\\[`i]', '\\(`i',
+ '\\[`o]', '\\(`o',
+ '\\[`u]', '\\(`u',
+ '\\[~A]', '\\(~A',
+ '\\[~N]', '\\(~N',
+ '\\[~O]', '\\(~O',
+ '\\[~a]', '\\(~a',
+ '\\[~n]', '\\(~n',
+ '\\[~o]', '\\(~o',
+ '\\[vS]', '\\(vS',
+ '\\[vs]', '\\(vs',
+ '\\[vZ]', '\\(vZ',
+ '\\[vz]', '\\(vz',
+ '\\[,C]', '\\(,C',
+ '\\[,c]', '\\(,c',
+ '\\[oA]', '\\(oA',
+ '\\[oa]', '\\(oa',
+ '\\[a"]', '\\(a"',
+ '\\[a-]', '\\(a-',
+ '\\[a.]', '\\(a.',
+ '\\[a^]', '\\(a^',
+ '\\[aa]', '\\(aa',
+ '\\[ga]', '\\(ga',
+ '\\[ab]', '\\(ab',
+ '\\[ac]', '\\(ac',
+ '\\[ad]', '\\(ad',
+ '\\[ah]', '\\(ah',
+ '\\[ao]', '\\(ao',
+ '\\[a~]', '\\(a~',
+ '\\[ho]', '\\(ho',
+ '\\[ha]', '\\(ha',
+ '\\[ti]', '\\(ti',
+ '\\[Bq]', '\\(Bq',
+ '\\[bq]', '\\(bq',
+ '\\[lq]', '\\(lq',
+ '\\[rq]', '\\(rq',
+ '\\[oq]', '\\(oq',
+ '\\[cq]', '\\(cq',
+ '\\[aq]', '\\(aq',
+ '\\[dq]', '\\(dq',
+ '\\[Fo]', '\\(Fo',
+ '\\[Fc]', '\\(Fc',
+ '\\[fo]', '\\(fo',
+ '\\[fc]', '\\(fc',
+ '\\[r!]', '\\(r!',
+ '\\[r?]', '\\(r?',
+ '\\[em]', '\\(em',
+ '\\[en]', '\\(en',
+ '\\[hy]', '\\(hy',
+ '\\[lB]', '\\(lB',
+ '\\[rB]', '\\(rB',
+ '\\[lC]', '\\(lC',
+ '\\[rC]', '\\(rC',
+ '\\[la]', '\\(la',
+ '\\[ra]', '\\(ra',
+ '\\[bv]', '\\(bv',
+ '\\[braceex]',
+ '\\[bracketlefttp]',
+ '\\[bracketleftbt]',
+ '\\[bracketleftex]',
+ '\\[bracketrighttp]',
+ '\\[bracketrightbt]',
+ '\\[bracketrightex]',
+ '\\[lt]', '\\(lt',
+ '\\[bracelefttp]',
+ '\\[lk]', '\\(lk',
+ '\\[braceleftmid]',
+ '\\[lb]', '\\(lb',
+ '\\[braceleftbt]',
+ '\\[braceleftex]',
+ '\\[rt]', '\\(rt',
+ '\\[bracerighttp]',
+ '\\[rk]', '\\(rk',
+ '\\[bracerightmid]',
+ '\\[rb]', '\\(rb',
+ '\\[bracerightbt]',
+ '\\[bracerightex]',
+ '\\[parenlefttp]',
+ '\\[parenleftbt]',
+ '\\[parenleftex]',
+ '\\[parenrighttp]',
+ '\\[parenrightbt]',
+ '\\[parenrightex]',
+ '\\[&lt;-]', '\\(&lt;-',
+ '\\[-&gt;]', '\\(-&gt;',
+ '\\[&lt;&gt;]', '\\(&lt;&gt;',
+ '\\[da]', '\\(da',
+ '\\[ua]', '\\(ua',
+ '\\[va]', '\\(va',
+ '\\[lA]', '\\(lA',
+ '\\[rA]', '\\(rA',
+ '\\[hA]', '\\(hA',
+ '\\[dA]', '\\(dA',
+ '\\[uA]', '\\(uA',
+ '\\[vA]', '\\(vA',
+ '\\[an]', '\\(an',
+ '\\[ba]', '\\(ba',
+ '\\[br]', '\\(br',
+ '\\[ul]', '\\(ul',
+ '\\[rn]', '\\(rn',
+ '\\[ru]', '\\(ru',
+ '\\[bb]', '\\(bb',
+ '\\[sl]', '\\(sl',
+ '\\[rs]', '\\(rs',
+ '\\[ci]', '\\(ci',
+ '\\[bu]', '\\(bu',
+ '\\[dd]', '\\(dd',
+ '\\[dg]', '\\(dg',
+ '\\[lz]', '\\(lz',
+ '\\[sq]', '\\(sq',
+ '\\[ps]', '\\(ps',
+ '\\[sc]', '\\(sc',
+ '\\[lh]', '\\(lh',
+ '\\[rh]', '\\(rh',
+ '\\[at]', '\\(at',
+ '\\[sh]', '\\(sh',
+ '\\[CR]', '\\(CR',
+ '\\[OK]', '\\(OK',
+ '\\[co]', '\\(co',
+ '\\[rg]', '\\(rg',
+ '\\[tm]', '\\(tm',
+ '\\[bs]', '\\(bs',
+ '\\[Do]', '\\(Do',
+ '\\[ct]', '\\(ct',
+ '\\[eu]', '\\(eu',
+ '\\[Eu]', '\\(Eu',
+ '\\[Ye]', '\\(Ye',
+ '\\[Po]', '\\(Po',
+ '\\[Cs]', '\\(Cs',
+ '\\[Fn]', '\\(Fn',
+ '\\[de]', '\\(de',
+ '\\[%0]', '\\(%0',
+ '\\[fm]', '\\(fm',
+ '\\[sd]', '\\(sd',
+ '\\[mc]', '\\(mc',
+ '\\[Of]', '\\(Of',
+ '\\[Om]', '\\(Om',
+ '\\[AN]', '\\(AN',
+ '\\[OR]', '\\(OR',
+ '\\[no]', '\\(no',
+ '\\[tno]',
+ '\\[te]', '\\(te',
+ '\\[fa]', '\\(fa',
+ '\\[st]', '\\(st',
+ '\\[3d]', '\\(3d',
+ '\\[tf]', '\\(tf',
+ '\\[or]', '\\(or',
+ '\\[12]', '\\(12',
+ '\\[14]', '\\(14',
+ '\\[34]', '\\(34',
+ '\\[18]', '\\(18',
+ '\\[38]', '\\(38',
+ '\\[58]', '\\(58',
+ '\\[78]', '\\(78',
+ '\\[S1]', '\\(S1',
+ '\\[S2]', '\\(S2',
+ '\\[S3]', '\\(S3',
+ '\\[pl]', '\\(pl',
+ '\\[mi]', '\\(mi',
+ '\\[-+]', '\\(-+',
+ '\\[+-]', '\\(+-',
+ '\\[t+-]',
+ '\\[pc]', '\\(pc',
+ '\\[md]', '\\(md',
+ '\\[mu]', '\\(mu',
+ '\\[tmu]',
+ '\\[c*]', '\\(c*',
+ '\\[c+]', '\\(c+',
+ '\\[di]', '\\(di',
+ '\\[tdi]',
+ '\\[f/]', '\\(f/',
+ '\\[**]', '\\(**',
+ '\\[&lt;=]', '\\(&lt;=',
+ '\\[&gt;=]', '\\(&gt;=',
+ '\\[&lt;&lt;]', '\\(&lt;&lt;',
+ '\\[&gt;&gt;]', '\\(&gt;&gt;',
+ '\\[eq]', '\\(eq',
+ '\\[!=]', '\\(!=',
+ '\\[==]', '\\(==',
+ '\\[ne]', '\\(ne',
+ '\\[=~]', '\\(=~',
+ '\\[|=]', '\\(|=',
+ '\\[ap]', '\\(ap',
+ '\\[~~]', '\\(~~',
+ '\\[~=]', '\\(~=',
+ '\\[pt]', '\\(pt',
+ '\\[es]', '\\(es',
+ '\\[mo]', '\\(mo',
+ '\\[nm]', '\\(nm',
+ '\\[sb]', '\\(sb',
+ '\\[nb]', '\\(nb',
+ '\\[sp]', '\\(sp',
+ '\\[nc]', '\\(nc',
+ '\\[ib]', '\\(ib',
+ '\\[ip]', '\\(ip',
+ '\\[ca]', '\\(ca',
+ '\\[cu]', '\\(cu',
+ '\\[/_]', '\\(/_',
+ '\\[pp]', '\\(pp',
+ '\\[is]', '\\(is',
+ '\\[integral]',
+ '\\[sum]',
+ '\\[product]',
+ '\\[coproduct]',
+ '\\[gr]', '\\(gr',
+ '\\[sr]', '\\(sr',
+ '\\[sqrt]',
+ '\\[radicalex]',
+ '\\[sqrtex]',
+ '\\[lc]', '\\(lc',
+ '\\[rc]', '\\(rc',
+ '\\[lf]', '\\(lf',
+ '\\[rf]', '\\(rf',
+ '\\[if]', '\\(if',
+ '\\[Ah]', '\\(Ah',
+ '\\[Im]', '\\(Im',
+ '\\[Re]', '\\(Re',
+ '\\[wp]', '\\(wp',
+ '\\[pd]', '\\(pd',
+ '\\[-h]', '\\(-h',
+ '\\[hbar]',
+ '\\[*A]', '\\(*A',
+ '\\[*B]', '\\(*B',
+ '\\[*G]', '\\(*G',
+ '\\[*D]', '\\(*D',
+ '\\[*E]', '\\(*E',
+ '\\[*Z]', '\\(*Z',
+ '\\[*Y]', '\\(*Y',
+ '\\[*H]', '\\(*H',
+ '\\[*I]', '\\(*I',
+ '\\[*K]', '\\(*K',
+ '\\[*L]', '\\(*L',
+ '\\[*M]', '\\(*M',
+ '\\[*N]', '\\(*N',
+ '\\[*C]', '\\(*C',
+ '\\[*O]', '\\(*O',
+ '\\[*P]', '\\(*P',
+ '\\[*R]', '\\(*R',
+ '\\[*S]', '\\(*S',
+ '\\[*T]', '\\(*T',
+ '\\[*U]', '\\(*U',
+ '\\[*F]', '\\(*F',
+ '\\[*X]', '\\(*X',
+ '\\[*Q]', '\\(*Q',
+ '\\[*W]', '\\(*W',
+ '\\[*a]', '\\(*a',
+ '\\[*b]', '\\(*b',
+ '\\[*g]', '\\(*g',
+ '\\[*d]', '\\(*d',
+ '\\[*e]', '\\(*e',
+ '\\[*z]', '\\(*z',
+ '\\[*y]', '\\(*y',
+ '\\[*h]', '\\(*h',
+ '\\[*i]', '\\(*i',
+ '\\[*k]', '\\(*k',
+ '\\[*l]', '\\(*l',
+ '\\[*m]', '\\(*m',
+ '\\[*n]', '\\(*n',
+ '\\[*c]', '\\(*c',
+ '\\[*o]', '\\(*o',
+ '\\[*p]', '\\(*p',
+ '\\[*r]', '\\(*r',
+ '\\[ts]', '\\(ts',
+ '\\[*s]', '\\(*s',
+ '\\[*t]', '\\(*t',
+ '\\[*u]', '\\(*u',
+ '\\[*f]', '\\(*f',
+ '\\[*x]', '\\(*x',
+ '\\[*q]', '\\(*q',
+ '\\[*w]', '\\(*w',
+ '\\[+h]', '\\(+h',
+ '\\[+f]', '\\(+f',
+ '\\[+p]', '\\(+p',
+ '\\[+e]', '\\(+e',
+ '\\[CL]', '\\(CL',
+ '\\[SP]', '\\(SP',
+ '\\[HE]', '\\(HE',
+ '\\[DI]', '\\(DI',
+ ),
+ 1 => array(
+ // Special characters
+ '\\\\', '\\´', '\\`', '\\-',
+ '\\_', '\\.', '\\%', '\\!',
+ '\\0', '\\|', '\\^', '\\&',
+ '\\)', '\\/', '\\,', '\\~',
+ '\\:', '\\{', '\\}', '\\a',
+ '\\c', '\\d', '\\e', '\\E',
+ '\\p', '\\r', '\\t', '\\u',
+
+ // Whitespace escapes
+ '\\ ', '\\h', "\\\n",
+
+ // Text modifiers
+ '\\fB', '\\fI', '\\fR', '\\fP',
+ '\\f0', '\\f1', '\\f2', '\\f3', '\\f4', '\\f5', '\\f6', '\\f7', '\\f8', '\\f9',
+ ),
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #ffff55;',
+ 2 => 'color: #ffff55;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ ),
+ 'STRINGS' => array(
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #00aaaa',
+ 1 => 'color: #aa00aa',
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #ffff55;',
+ 1 => 'font-weight: bold;',
+ 2 => 'font-style: italic;',
+ 3 => 'font-weight: bold;',
+ 4 => 'font-style: italic;',
+ 5 => 'color: #55aaff;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'REGEXPS' => array(
+ 0 => array(
+ // Unicode characters
+ GESHI_SEARCH => '\\\\\\[u([[:xdigit:]]{4,5})\\]',
+ GESHI_REPLACE => '\\\\[\\1]',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '',
+ ),
+ 1 => array(
+ // Bold text - formatted using .B or 'B
+ GESHI_SEARCH => "^([\\.']{1}B[[:blank:]]*\\n{0,1})([[:print:]]+)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '',
+ ),
+ 2 => array(
+ // Italic text - formatted using .I or 'I
+ GESHI_SEARCH => "^([\\.']{1}I[[:blank:]]*\\n{0,1})([[:print:]]+)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '',
+ ),
+ 3 => array(
+ // Bold text - formatted inline
+ GESHI_SEARCH => '(\\\\fB)([[:print:]]+?)(\\\\fR)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3',
+ ),
+ 4 => array (
+ // Italic text - formatted inline
+ GESHI_SEARCH => '(\\\\fI)([[:print:]]+?)(\\\\fR)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3',
+ ),
+ 5 => array(
+ // Line start macros (.TP, .SH, et cetera)
+ GESHI_SEARCH => "^([.']{1}[a-zA-Z]+)",
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'm',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '',
+ ),
+ ),
+ 'URLS' => array(),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/rpmspec.php b/platform/www/vendor/geshi/geshi/src/geshi/rpmspec.php
new file mode 100644
index 0000000..49c4106
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/rpmspec.php
@@ -0,0 +1,131 @@
+<?php
+/*************************************************************************************
+ * rpmspec.php
+ * ---------------------------------
+ * Author: Paul Grinberg (gri6507 TA unity-linux TOD org)
+ * Copyright: (c) 2010 Paul Grinberg
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/04/27
+ *
+ * RPM Spec language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/04/27 (0.1)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'RPM Specification File',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'QUOTEMARKS' => array('"','`'),
+ 'ESCAPE_CHAR' => '\\',
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ ),
+ 'KEYWORDS' => array(
+ ),
+ 'SYMBOLS' => array(
+ '<', '>', '=',
+ '!', '@', '~', '&', '|', '^',
+ '+','-', '*', '/', '%',
+ ',', ';', '?', '.', ':'
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #009999;',
+ 3 => 'color: #000000; font-weight: bold;',
+ 4 => 'color: #ff6600; font-style: italic;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'REGEXPS' => array(
+ 1 => array(
+ // search for generic macros
+ GESHI_SEARCH => '(%{?[a-zA-Z0-9_]+}?)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '',
+ ),
+ 2 => array(
+ // search for special macros
+ GESHI_SEARCH => '(%(?:define|patch\d*|mklibname|mkrel|configure\S+|makeinstall\S+|make_session|make|defattr|config|doc|setup))',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '',
+ ),
+ 3 => array (
+ // special definitions
+ GESHI_SEARCH => '((?:summary|license|buildroot|buildrequires|provides|version|release|source\d*|group|buildarch|autoreqprov|provides|obsoletes|vendor|distribution|suggests|autoreq|autoprov|conflicts|name|url|requires|patch\d*):)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '',
+ ),
+ 4 => array (
+ // section delimiting words
+ GESHI_SEARCH => '(%(?:description|package|prep|build|install|clean|postun|preun|post|pre|files|changelog))',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '',
+ ),
+ ),
+ 'URLS' => array(),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/rsplus.php b/platform/www/vendor/geshi/geshi/src/geshi/rsplus.php
new file mode 100644
index 0000000..4dad7db
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/rsplus.php
@@ -0,0 +1,481 @@
+<?php
+/*************************************************************************************
+ * rsplus.php
+ * ———–
+ * Author: Ron Fredericks (ronf@LectureMaker.com)
+ * Contributors:
+ * - Benilton Carvalho (beniltoncarvalho@gmail.com)
+ * - Fernando Henrique Ferraz Pereira da Rosa (mentus@gmail.com)
+ * Copyright: (c) 2009 Ron Fredericks (http://www.LectureMaker.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/03/28
+ *
+ * R language file for GeSHi.
+ *
+ * CHANGES
+ * ——-
+ * 2009/04/06
+ * - Add references to Sekhon’s R Package docs
+ * 2009/03/29 (1.0.8.5)
+ * - First Release
+ * 2009/07/16 (1.0.8.6)
+ * - Added functions from base packages (Benilton Carvalho - carvalho@bclab.org)
+ *
+ * References
+ * ———-
+ * Some online R Package documentation:
+ * http://sekhon.berkeley.edu/library/index.html 2.4 docs
+ * http://astrostatistics.psu.edu/su07/R/html 2.5 docs
+ *
+ * Another R GeSHi with no meat?
+ * http://organicdesign.co.nz/GeSHi/R.php
+ * SourceForge R discussion:
+ * http://sourceforge.net/tracker/?func=detail&aid=2276025&group_id=114997&atid=670234
+ *
+ * TODO (updated 2007/02/06)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'R / S+',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'"),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'else','global','in', 'otherwise','persistent',
+ ),
+ 2 => array( // base package
+ '$.package_version', '$<-', '$<-.data.frame', 'abbreviate', 'abs', 'acos', 'acosh', 'addNA', 'addTaskCallback',
+ 'agrep', 'alist', 'all', 'all.equal', 'all.equal.character', 'all.equal.default', 'all.equal.factor',
+ 'all.equal.formula', 'all.equal.language', 'all.equal.list', 'all.equal.numeric', 'all.equal.POSIXct',
+ 'all.equal.raw', 'all.names', 'all.vars', 'any', 'aperm', 'append', 'apply', 'Arg', 'args', 'array', 'as.array',
+ 'as.array.default', 'as.call', 'as.character', 'as.character.condition', 'as.character.Date', 'as.character.default',
+ 'as.character.error', 'as.character.factor', 'as.character.hexmode', 'as.character.numeric_version', 'as.character.octmode',
+ 'as.character.POSIXt', 'as.character.srcref', 'as.complex', 'as.data.frame', 'as.data.frame.array', 'as.data.frame.AsIs',
+ 'as.data.frame.character', 'as.data.frame.complex', 'as.data.frame.data.frame', 'as.data.frame.Date', 'as.data.frame.default',
+ 'as.data.frame.difftime', 'as.data.frame.factor', 'as.data.frame.integer', 'as.data.frame.list', 'as.data.frame.logical',
+ 'as.data.frame.matrix', 'as.data.frame.model.matrix', 'as.data.frame.numeric', 'as.data.frame.numeric_version',
+ 'as.data.frame.ordered', 'as.data.frame.POSIXct', 'as.data.frame.POSIXlt', 'as.data.frame.raw', 'as.data.frame.table',
+ 'as.data.frame.ts', 'as.data.frame.vector', 'as.Date', 'as.Date.character', 'as.Date.date', 'as.Date.dates',
+ 'as.Date.default', 'as.Date.factor', 'as.Date.numeric', 'as.Date.POSIXct', 'as.Date.POSIXlt', 'as.difftime', 'as.double',
+ 'as.double.difftime', 'as.double.POSIXlt', 'as.environment', 'as.expression', 'as.expression.default', 'as.factor',
+ 'as.function', 'as.function.default', 'as.hexmode', 'as.integer', 'as.list', 'as.list.data.frame', 'as.list.default',
+ 'as.list.environment', 'as.list.factor', 'as.list.function', 'as.list.numeric_version', 'as.logical', 'as.matrix',
+ 'as.matrix.data.frame', 'as.matrix.default', 'as.matrix.noquote', 'as.matrix.POSIXlt', 'as.name', 'as.null', 'as.null.default',
+ 'as.numeric', 'as.numeric_version', 'as.octmode', 'as.ordered', 'as.package_version', 'as.pairlist', 'as.POSIXct',
+ 'as.POSIXct.date', 'as.POSIXct.Date', 'as.POSIXct.dates', 'as.POSIXct.default', 'as.POSIXct.numeric', 'as.POSIXct.POSIXlt',
+ 'as.POSIXlt', 'as.POSIXlt.character', 'as.POSIXlt.date', 'as.POSIXlt.Date', 'as.POSIXlt.dates', 'as.POSIXlt.default',
+ 'as.POSIXlt.factor', 'as.POSIXlt.numeric', 'as.POSIXlt.POSIXct', 'as.qr', 'as.raw', 'as.real', 'as.single',
+ 'as.single.default', 'as.symbol', 'as.table', 'as.table.default', 'as.vector', 'as.vector.factor', 'asin', 'asinh',
+ 'asNamespace', 'asS4', 'assign', 'atan', 'atan2', 'atanh', 'attach', 'attachNamespace', 'attr', 'attr.all.equal',
+ 'attr<-', 'attributes', 'attributes<-', 'autoload', 'autoloader', 'backsolve', 'baseenv', 'basename', 'besselI',
+ 'besselJ', 'besselK', 'besselY', 'beta', 'bindingIsActive', 'bindingIsLocked', 'bindtextdomain', 'body', 'body<-',
+ 'bquote', 'break', 'browser', 'builtins', 'by', 'by.data.frame', 'by.default', 'bzfile', 'c', 'c.Date', 'c.noquote',
+ 'c.numeric_version', 'c.POSIXct', 'c.POSIXlt', 'call', 'callCC', 'capabilities', 'casefold', 'cat', 'category',
+ 'cbind', 'cbind.data.frame', 'ceiling', 'char.expand', 'character', 'charmatch', 'charToRaw', 'chartr', 'check_tzones',
+ 'chol', 'chol.default', 'chol2inv', 'choose', 'class', 'class<-', 'close', 'close.connection', 'close.srcfile',
+ 'closeAllConnections', 'codes', 'codes.factor', 'codes.ordered', 'codes<-', 'col', 'colMeans', 'colnames',
+ 'colnames<-', 'colSums', 'commandArgs', 'comment', 'comment<-', 'complex', 'computeRestarts', 'conditionCall',
+ 'conditionCall.condition', 'conditionMessage', 'conditionMessage.condition', 'conflicts', 'Conj', 'contributors',
+ 'cos', 'cosh', 'crossprod', 'Cstack_info', 'cummax', 'cummin', 'cumprod', 'cumsum', 'cut', 'cut.Date', 'cut.default',
+ 'cut.POSIXt', 'data.class', 'data.frame', 'data.matrix', 'date', 'debug', 'default.stringsAsFactors', 'delay',
+ 'delayedAssign', 'deparse', 'det', 'detach', 'determinant', 'determinant.matrix', 'dget', 'diag', 'diag<-', 'diff',
+ 'diff.Date', 'diff.default', 'diff.POSIXt', 'difftime', 'digamma', 'dim', 'dim.data.frame', 'dim<-', 'dimnames',
+ 'dimnames.data.frame', 'dimnames<-', 'dimnames<-.data.frame', 'dir', 'dir.create', 'dirname', 'do.call', 'double',
+ 'dput', 'dQuote', 'drop', 'dump', 'duplicated', 'duplicated.array', 'duplicated.data.frame', 'duplicated.default',
+ 'duplicated.matrix', 'duplicated.numeric_version', 'duplicated.POSIXlt', 'dyn.load', 'dyn.unload', 'eapply', 'eigen',
+ 'emptyenv', 'encodeString', 'Encoding', 'Encoding<-', 'env.profile', 'environment', 'environment<-', 'environmentIsLocked',
+ 'environmentName', 'eval', 'eval.parent', 'evalq', 'exists', 'exp', 'expand.grid', 'expm1', 'expression', 'F', 'factor',
+ 'factorial', 'fifo', 'file', 'file.access', 'file.append', 'file.choose', 'file.copy', 'file.create', 'file.exists',
+ 'file.info', 'file.path', 'file.remove', 'file.rename', 'file.show', 'file.symlink', 'Filter', 'Find', 'findInterval',
+ 'findPackageEnv', 'findRestart', 'floor', 'flush', 'flush.connection', 'for', 'force', 'formals', 'formals<-',
+ 'format', 'format.AsIs', 'format.char', 'format.data.frame', 'format.Date', 'format.default', 'format.difftime',
+ 'format.factor', 'format.hexmode', 'format.info', 'format.octmode', 'format.POSIXct', 'format.POSIXlt',
+ 'format.pval', 'formatC', 'formatDL', 'forwardsolve', 'function', 'gamma', 'gammaCody', 'gc', 'gc.time',
+ 'gcinfo', 'gctorture', 'get', 'getAllConnections', 'getCallingDLL', 'getCallingDLLe', 'getCConverterDescriptions',
+ 'getCConverterStatus', 'getConnection', 'getDLLRegisteredRoutines', 'getDLLRegisteredRoutines.character',
+ 'getDLLRegisteredRoutines.DLLInfo', 'getenv', 'geterrmessage', 'getExportedValue', 'getHook', 'getLoadedDLLs',
+ 'getNamespace', 'getNamespaceExports', 'getNamespaceImports', 'getNamespaceInfo', 'getNamespaceName',
+ 'getNamespaceUsers', 'getNamespaceVersion', 'getNativeSymbolInfo', 'getNumCConverters', 'getOption', 'getRversion',
+ 'getSrcLines', 'getTaskCallbackNames', 'gettext', 'gettextf', 'getwd', 'gl', 'globalenv', 'gregexpr', 'grep',
+ 'grepl', 'gsub', 'gzcon', 'gzfile', 'httpclient', 'I', 'iconv', 'iconvlist', 'icuSetCollate', 'identical', 'identity',
+ 'if', 'ifelse', 'Im', 'importIntoEnv', 'inherits', 'integer', 'interaction', 'interactive', 'intersect', 'intToBits',
+ 'intToUtf8', 'inverse.rle', 'invisible', 'invokeRestart', 'invokeRestartInteractively', 'is.array', 'is.atomic',
+ 'is.call', 'is.character', 'is.complex', 'is.data.frame', 'is.double', 'is.element', 'is.environment',
+ 'is.expression', 'is.factor', 'is.finite', 'is.function', 'is.infinite', 'is.integer', 'is.language',
+ 'is.list', 'is.loaded', 'is.logical', 'is.matrix', 'is.na', 'is.na.data.frame', 'is.na.POSIXlt', 'is.na<-',
+ 'is.na<-.default', 'is.na<-.factor', 'is.name', 'is.nan', 'is.null', 'is.numeric', 'is.numeric_version',
+ 'is.numeric.Date', 'is.numeric.POSIXt', 'is.object', 'is.ordered', 'is.package_version', 'is.pairlist', 'is.primitive',
+ 'is.qr', 'is.R', 'is.raw', 'is.real', 'is.recursive', 'is.single', 'is.symbol', 'is.table', 'is.unsorted', 'is.vector',
+ 'isBaseNamespace', 'isdebugged', 'isIncomplete', 'isNamespace', 'ISOdate', 'ISOdatetime', 'isOpen', 'isRestart', 'isS4',
+ 'isSeekable', 'isSymmetric', 'isSymmetric.matrix', 'isTRUE', 'jitter', 'julian', 'julian.Date', 'julian.POSIXt', 'kappa',
+ 'kappa.default', 'kappa.lm', 'kappa.qr', 'kappa.tri', 'kronecker', 'l10n_info', 'La.chol', 'La.chol2inv', 'La.eigen',
+ 'La.svd', 'labels', 'labels.default', 'lapply', 'lazyLoad', 'lazyLoadDBfetch', 'lbeta', 'lchoose', 'length', 'length<-',
+ 'length<-.factor', 'letters', 'LETTERS', 'levels', 'levels.default', 'levels<-', 'levels<-.factor', 'lfactorial', 'lgamma',
+ 'library', 'library.dynam', 'library.dynam.unload', 'licence', 'license', 'list', 'list.files', 'load', 'loadedNamespaces',
+ 'loadingNamespaceInfo', 'loadNamespace', 'loadURL', 'local', 'lockBinding', 'lockEnvironment', 'log', 'log10', 'log1p', 'log2',
+ 'logb', 'logical', 'lower.tri', 'ls', 'machine', 'Machine', 'make.names', 'make.unique', 'makeActiveBinding', 'manglePackageName',
+ 'Map', 'mapply', 'margin.table', 'mat.or.vec', 'match', 'match.arg', 'match.call', 'match.fun', 'Math.data.frame', 'Math.Date',
+ 'Math.difftime', 'Math.factor', 'Math.POSIXt', 'matrix', 'max', 'max.col', 'mean', 'mean.data.frame', 'mean.Date', 'mean.default',
+ 'mean.difftime', 'mean.POSIXct', 'mean.POSIXlt', 'mem.limits', 'memory.profile', 'merge', 'merge.data.frame', 'merge.default',
+ 'message', 'mget', 'min', 'missing', 'Mod', 'mode', 'mode<-', 'month.abb', 'month.name', 'months', 'months.Date',
+ 'months.POSIXt', 'mostattributes<-', 'names', 'names<-', 'namespaceExport', 'namespaceImport', 'namespaceImportClasses',
+ 'namespaceImportFrom', 'namespaceImportMethods', 'nargs', 'nchar', 'ncol', 'NCOL', 'Negate', 'new.env', 'next', 'NextMethod',
+ 'ngettext', 'nlevels', 'noquote', 'nrow', 'NROW', 'numeric', 'numeric_version', 'nzchar', 'objects', 'oldClass',
+ 'oldClass<-', 'on.exit', 'open', 'open.connection', 'open.srcfile', 'open.srcfilecopy', 'Ops.data.frame', 'Ops.Date',
+ 'Ops.difftime', 'Ops.factor', 'Ops.numeric_version', 'Ops.ordered', 'Ops.POSIXt', 'options', 'order', 'ordered',
+ 'outer', 'package_version', 'package.description', 'packageEvent', 'packageHasNamespace', 'packageStartupMessage',
+ 'packBits', 'pairlist', 'parent.env', 'parent.env<-', 'parent.frame', 'parse', 'parse.dcf', 'parseNamespaceFile',
+ 'paste', 'path.expand', 'pentagamma', 'pi', 'pipe', 'Platform', 'pmatch', 'pmax', 'pmax.int', 'pmin', 'pmin.int',
+ 'polyroot', 'pos.to.env', 'Position', 'pretty', 'prettyNum', 'print', 'print.AsIs', 'print.atomic', 'print.by',
+ 'print.condition', 'print.connection', 'print.data.frame', 'print.Date', 'print.default', 'print.difftime',
+ 'print.DLLInfo', 'print.DLLInfoList', 'print.DLLRegisteredRoutines', 'print.factor', 'print.hexmode', 'print.libraryIQR',
+ 'print.listof', 'print.NativeRoutineList', 'print.noquote', 'print.numeric_version', 'print.octmode', 'print.packageInfo',
+ 'print.POSIXct', 'print.POSIXlt', 'print.proc_time', 'print.restart', 'print.rle', 'print.simple.list',
+ 'print.srcfile', 'print.srcref', 'print.summary.table', 'print.table', 'print.warnings', 'printNoClass',
+ 'prmatrix', 'proc.time', 'prod', 'prop.table', 'provide', 'psigamma', 'pushBack', 'pushBackLength', 'q', 'qr',
+ 'qr.coef', 'qr.default', 'qr.fitted', 'qr.Q', 'qr.qty', 'qr.qy', 'qr.R', 'qr.resid', 'qr.solve', 'qr.X', 'quarters',
+ 'quarters.Date', 'quarters.POSIXt', 'quit', 'quote', 'R_system_version', 'R.home', 'R.version', 'R.Version',
+ 'R.version.string', 'range', 'range.default', 'rank', 'rapply', 'raw', 'rawConnection', 'rawConnectionValue',
+ 'rawShift', 'rawToBits', 'rawToChar', 'rbind', 'rbind.data.frame', 'rcond', 'Re', 'read.dcf', 'read.table.url',
+ 'readBin', 'readChar', 'readline', 'readLines', 'real', 'Recall', 'Reduce', 'reg.finalizer', 'regexpr',
+ 'registerS3method', 'registerS3methods', 'remove', 'removeCConverter', 'removeTaskCallback', 'rep', 'rep.Date',
+ 'rep.factor', 'rep.int', 'rep.numeric_version', 'rep.POSIXct', 'rep.POSIXlt', 'repeat', 'replace', 'replicate',
+ 'require', 'restart', 'restartDescription', 'restartFormals', 'retracemem', 'return', 'rev', 'rev.default', 'rle',
+ 'rm', 'RNGkind', 'RNGversion', 'round', 'round.Date', 'round.difftime', 'round.POSIXt', 'row', 'row.names',
+ 'row.names.data.frame', 'row.names.default', 'row.names<-', 'row.names<-.data.frame', 'row.names<-.default',
+ 'rowMeans', 'rownames', 'rownames<-', 'rowsum', 'rowsum.data.frame', 'rowsum.default', 'rowSums', 'sample',
+ 'sample.int', 'sapply', 'save', 'save.image', 'saveNamespaceImage', 'scale', 'scale.default', 'scan', 'scan.url',
+ 'search', 'searchpaths', 'seek', 'seek.connection', 'seq', 'seq_along', 'seq_len', 'seq.Date', 'seq.default',
+ 'seq.int', 'seq.POSIXt', 'sequence', 'serialize', 'set.seed', 'setCConverterStatus', 'setdiff', 'setequal',
+ 'setHook', 'setNamespaceInfo', 'setSessionTimeLimit', 'setTimeLimit', 'setwd', 'showConnections', 'shQuote',
+ 'sign', 'signalCondition', 'signif', 'simpleCondition', 'simpleError', 'simpleMessage', 'simpleWarning', 'sin',
+ 'single', 'sinh', 'sink', 'sink.number', 'slice.index', 'socketConnection', 'socketSelect', 'solve', 'solve.default',
+ 'solve.qr', 'sort', 'sort.default', 'sort.int', 'sort.list', 'sort.POSIXlt', 'source', 'source.url', 'split',
+ 'split.data.frame', 'split.Date', 'split.default', 'split.POSIXct', 'split<-', 'split<-.data.frame', 'split<-.default',
+ 'sprintf', 'sqrt', 'sQuote', 'srcfile', 'srcfilecopy', 'srcref', 'standardGeneric', 'stderr', 'stdin', 'stdout',
+ 'stop', 'stopifnot', 'storage.mode', 'storage.mode<-', 'strftime', 'strptime', 'strsplit', 'strtrim', 'structure',
+ 'strwrap', 'sub', 'subset', 'subset.data.frame', 'subset.default', 'subset.matrix', 'substitute', 'substr',
+ 'substr<-', 'substring', 'substring<-', 'sum', 'summary', 'summary.connection', 'summary.data.frame',
+ 'Summary.data.frame', 'summary.Date', 'Summary.Date', 'summary.default', 'Summary.difftime',
+ 'summary.factor', 'Summary.factor', 'summary.matrix', 'Summary.numeric_version', 'summary.POSIXct',
+ 'Summary.POSIXct', 'summary.POSIXlt', 'Summary.POSIXlt', 'summary.table', 'suppressMessages',
+ 'suppressPackageStartupMessages', 'suppressWarnings', 'svd', 'sweep', 'switch', 'symbol.C',
+ 'symbol.For', 'sys.call', 'sys.calls', 'Sys.chmod', 'Sys.Date', 'sys.frame', 'sys.frames',
+ 'sys.function', 'Sys.getenv', 'Sys.getlocale', 'Sys.getpid', 'Sys.glob', 'Sys.info', 'sys.load.image',
+ 'Sys.localeconv', 'sys.nframe', 'sys.on.exit', 'sys.parent', 'sys.parents', 'Sys.putenv',
+ 'sys.save.image', 'Sys.setenv', 'Sys.setlocale', 'Sys.sleep', 'sys.source', 'sys.status',
+ 'Sys.time', 'Sys.timezone', 'Sys.umask', 'Sys.unsetenv', 'Sys.which', 'system', 'system.file',
+ 'system.time', 't', 'T', 't.data.frame', 't.default', 'table', 'tabulate', 'tan', 'tanh', 'tapply',
+ 'taskCallbackManager', 'tcrossprod', 'tempdir', 'tempfile', 'testPlatformEquivalence', 'tetragamma',
+ 'textConnection', 'textConnectionValue', 'tolower', 'topenv', 'toString', 'toString.default', 'toupper',
+ 'trace', 'traceback', 'tracemem', 'tracingState', 'transform', 'transform.data.frame', 'transform.default',
+ 'trigamma', 'trunc', 'trunc.Date', 'trunc.POSIXt', 'truncate', 'truncate.connection', 'try', 'tryCatch',
+ 'typeof', 'unclass', 'undebug', 'union', 'unique', 'unique.array', 'unique.data.frame', 'unique.default',
+ 'unique.matrix', 'unique.numeric_version', 'unique.POSIXlt', 'units', 'units.difftime', 'units<-',
+ 'units<-.difftime', 'unix', 'unix.time', 'unlink', 'unlist', 'unloadNamespace', 'unlockBinding',
+ 'unname', 'unserialize', 'unsplit', 'untrace', 'untracemem', 'unz', 'upper.tri', 'url', 'UseMethod',
+ 'utf8ToInt', 'vector', 'Vectorize', 'version', 'Version', 'warning', 'warnings', 'weekdays',
+ 'weekdays.Date', 'weekdays.POSIXt', 'which', 'which.max', 'which.min', 'while', 'with',
+ 'with.default', 'withCallingHandlers', 'within', 'within.data.frame', 'within.list', 'withRestarts',
+ 'withVisible', 'write', 'write.dcf', 'write.table0', 'writeBin', 'writeChar', 'writeLines', 'xor',
+ 'xpdrows.data.frame', 'xtfrm', 'xtfrm.Date', 'xtfrm.default', 'xtfrm.factor', 'xtfrm.numeric_version',
+ 'xtfrm.POSIXct', 'xtfrm.POSIXlt', 'xtfrm.Surv', 'zapsmall',
+ ),
+ 3 => array( // Datasets
+ 'ability.cov', 'airmiles', 'AirPassengers', 'airquality',
+ 'anscombe', 'attenu', 'attitude', 'austres', 'beaver1',
+ 'beaver2', 'BJsales', 'BJsales.lead', 'BOD', 'cars',
+ 'ChickWeight', 'chickwts', 'co2', 'crimtab',
+ 'discoveries', 'DNase', 'esoph', 'euro', 'euro.cross',
+ 'eurodist', 'EuStockMarkets', 'faithful', 'fdeaths',
+ 'Formaldehyde', 'freeny', 'freeny.x', 'freeny.y',
+ 'HairEyeColor', 'Harman23.cor', 'Harman74.cor', 'Indometh',
+ 'infert', 'InsectSprays', 'iris', 'iris3', 'islands',
+ 'JohnsonJohnson', 'LakeHuron', 'ldeaths', 'lh', 'LifeCycleSavings',
+ 'Loblolly', 'longley', 'lynx', 'mdeaths', 'morley', 'mtcars',
+ 'nhtemp', 'Nile', 'nottem', 'occupationalStatus', 'Orange',
+ 'OrchardSprays', 'PlantGrowth', 'precip', 'presidents',
+ 'pressure', 'Puromycin', 'quakes', 'randu', 'rivers', 'rock',
+ 'Seatbelts', 'sleep', 'stack.loss', 'stack.x', 'stackloss',
+ 'state.abb', 'state.area', 'state.center', 'state.division',
+ 'state.name', 'state.region', 'state.x77', 'sunspot.month',
+ 'sunspot.year', 'sunspots', 'swiss', 'Theoph', 'Titanic', 'ToothGrowth',
+ 'treering', 'trees', 'UCBAdmissions', 'UKDriverDeaths', 'UKgas',
+ 'USAccDeaths', 'USArrests', 'USJudgeRatings', 'USPersonalExpenditure',
+ 'uspop', 'VADeaths', 'volcano', 'warpbreaks', 'women', 'WorldPhones',
+ 'WWWusage',
+ ),
+ 4 => array( // graphics package
+ 'abline', 'arrows', 'assocplot', 'axis', 'Axis', 'axis.Date', 'axis.POSIXct',
+ 'axTicks', 'barplot', 'barplot.default', 'box', 'boxplot', 'boxplot.default',
+ 'boxplot.matrix', 'bxp', 'cdplot', 'clip', 'close.screen', 'co.intervals',
+ 'contour', 'contour.default', 'coplot', 'curve', 'dotchart', 'erase.screen',
+ 'filled.contour', 'fourfoldplot', 'frame', 'grconvertX', 'grconvertY', 'grid',
+ 'hist', 'hist.default', 'identify', 'image', 'image.default', 'layout',
+ 'layout.show', 'lcm', 'legend', 'lines', 'lines.default', 'locator', 'matlines',
+ 'matplot', 'matpoints', 'mosaicplot', 'mtext', 'pairs', 'pairs.default',
+ 'panel.smooth', 'par', 'persp', 'pie', 'piechart', 'plot', 'plot.default',
+ 'plot.design', 'plot.new', 'plot.window', 'plot.xy', 'points', 'points.default',
+ 'polygon', 'rect', 'rug', 'screen', 'segments', 'smoothScatter', 'spineplot',
+ 'split.screen', 'stars', 'stem', 'strheight', 'stripchart', 'strwidth', 'sunflowerplot',
+ 'symbols', 'text', 'text.default', 'title', 'xinch', 'xspline', 'xyinch', 'yinch',
+ ),
+ 5 => array( // grDevices pkg
+ 'as.graphicsAnnot', 'bitmap', 'blues9', 'bmp', 'boxplot.stats', 'cairo_pdf', 'cairo_ps', 'check.options',
+ 'chull', 'CIDFont', 'cm', 'cm.colors', 'col2rgb', 'colorConverter', 'colorRamp', 'colorRampPalette',
+ 'colors', 'colorspaces', 'colours', 'contourLines', 'convertColor', 'densCols', 'dev.control', 'dev.copy',
+ 'dev.copy2eps', 'dev.copy2pdf', 'dev.cur', 'dev.interactive', 'dev.list', 'dev.new', 'dev.next', 'dev.off',
+ 'dev.prev', 'dev.print', 'dev.set', 'dev.size', 'dev2bitmap', 'devAskNewPage', 'deviceIsInteractive',
+ 'embedFonts', 'extendrange', 'getGraphicsEvent', 'graphics.off', 'gray', 'gray.colors', 'grey', 'grey.colors',
+ 'hcl', 'heat.colors', 'Hershey', 'hsv', 'jpeg', 'make.rgb', 'n2mfrow', 'nclass.FD', 'nclass.scott',
+ 'nclass.Sturges', 'palette', 'pdf', 'pdf.options', 'pdfFonts', 'pictex', 'png', 'postscript', 'postscriptFont',
+ 'postscriptFonts', 'ps.options', 'quartz', 'quartz.options', 'quartzFont', 'quartzFonts', 'rainbow',
+ 'recordGraphics', 'recordPlot', 'replayPlot', 'rgb', 'rgb2hsv', 'savePlot', 'setEPS', 'setPS', 'svg',
+ 'terrain.colors', 'tiff', 'topo.colors', 'trans3d', 'Type1Font', 'x11', 'X11', 'X11.options', 'X11Font',
+ 'X11Fonts', 'xfig', 'xy.coords', 'xyTable', 'xyz.coords',
+ ),
+ 6 => array( // methods package
+ 'addNextMethod', 'allGenerics', 'allNames', 'Arith', 'as', 'as<-',
+ 'asMethodDefinition', 'assignClassDef', 'assignMethodsMetaData', 'balanceMethodsList',
+ 'cacheGenericsMetaData', 'cacheMetaData', 'cacheMethod', 'callGeneric',
+ 'callNextMethod', 'canCoerce', 'cbind2', 'checkSlotAssignment', 'classesToAM',
+ 'classMetaName', 'coerce', 'coerce<-', 'Compare', 'completeClassDefinition',
+ 'completeExtends', 'completeSubclasses', 'Complex', 'conformMethod', 'defaultDumpName',
+ 'defaultPrototype', 'doPrimitiveMethod', 'dumpMethod', 'dumpMethods', 'el', 'el<-',
+ 'elNamed', 'elNamed<-', 'empty.dump', 'emptyMethodsList', 'existsFunction', 'existsMethod',
+ 'extends', 'finalDefaultMethod', 'findClass', 'findFunction', 'findMethod', 'findMethods',
+ 'findMethodSignatures', 'findUnique', 'fixPre1.8', 'formalArgs', 'functionBody',
+ 'functionBody<-', 'generic.skeleton', 'getAccess', 'getAllMethods', 'getAllSuperClasses',
+ 'getClass', 'getClassDef', 'getClasses', 'getClassName', 'getClassPackage', 'getDataPart',
+ 'getExtends', 'getFunction', 'getGeneric', 'getGenerics', 'getGroup', 'getGroupMembers',
+ 'getMethod', 'getMethods', 'getMethodsForDispatch', 'getMethodsMetaData', 'getPackageName',
+ 'getProperties', 'getPrototype', 'getSlots', 'getSubclasses', 'getValidity', 'getVirtual',
+ 'hasArg', 'hasMethod', 'hasMethods', 'implicitGeneric', 'initialize', 'insertMethod', 'is',
+ 'isClass', 'isClassDef', 'isClassUnion', 'isGeneric', 'isGrammarSymbol', 'isGroup',
+ 'isSealedClass', 'isSealedMethod', 'isVirtualClass', 'isXS3Class', 'languageEl', 'languageEl<-',
+ 'linearizeMlist', 'listFromMethods', 'listFromMlist', 'loadMethod', 'Logic',
+ 'makeClassRepresentation', 'makeExtends', 'makeGeneric', 'makeMethodsList',
+ 'makePrototypeFromClassDef', 'makeStandardGeneric', 'matchSignature', 'Math', 'Math2', 'mergeMethods',
+ 'metaNameUndo', 'method.skeleton', 'MethodAddCoerce', 'methodSignatureMatrix', 'MethodsList',
+ 'MethodsListSelect', 'methodsPackageMetaName', 'missingArg', 'mlistMetaName', 'new', 'newBasic',
+ 'newClassRepresentation', 'newEmptyObject', 'Ops', 'packageSlot', 'packageSlot<-', 'possibleExtends',
+ 'prohibitGeneric', 'promptClass', 'promptMethods', 'prototype', 'Quote', 'rbind2',
+ 'reconcilePropertiesAndPrototype', 'registerImplicitGenerics', 'rematchDefinition',
+ 'removeClass', 'removeGeneric', 'removeMethod', 'removeMethods', 'removeMethodsObject', 'representation',
+ 'requireMethods', 'resetClass', 'resetGeneric', 'S3Class', 'S3Class<-', 'S3Part', 'S3Part<-', 'sealClass',
+ 'seemsS4Object', 'selectMethod', 'selectSuperClasses', 'sessionData', 'setAs', 'setClass', 'setClassUnion',
+ 'setDataPart', 'setGeneric', 'setGenericImplicit', 'setGroupGeneric', 'setIs', 'setMethod', 'setOldClass',
+ 'setPackageName', 'setPrimitiveMethods', 'setReplaceMethod', 'setValidity', 'show', 'showClass', 'showDefault',
+ 'showExtends', 'showMethods', 'showMlist', 'signature', 'SignatureMethod', 'sigToEnv', 'slot', 'slot<-',
+ 'slotNames', 'slotsFromS3', 'substituteDirect', 'substituteFunctionArgs', 'Summary', 'superClassDepth',
+ 'testInheritedMethods', 'testVirtual', 'traceOff', 'traceOn', 'tryNew', 'trySilent', 'unRematchDefinition',
+ 'validObject', 'validSlotNames',
+ ),
+ 7 => array( // stats pkg
+ 'acf', 'acf2AR', 'add.scope', 'add1', 'addmargins', 'aggregate',
+ 'aggregate.data.frame', 'aggregate.default', 'aggregate.ts', 'AIC',
+ 'alias', 'anova', 'anova.glm', 'anova.glmlist', 'anova.lm', 'anova.lmlist',
+ 'anova.mlm', 'anovalist.lm', 'ansari.test', 'aov', 'approx', 'approxfun',
+ 'ar', 'ar.burg', 'ar.mle', 'ar.ols', 'ar.yw', 'arima', 'arima.sim',
+ 'arima0', 'arima0.diag', 'ARMAacf', 'ARMAtoMA', 'as.dendrogram', 'as.dist',
+ 'as.formula', 'as.hclust', 'as.stepfun', 'as.ts', 'asOneSidedFormula', 'ave',
+ 'bandwidth.kernel', 'bartlett.test', 'binom.test', 'binomial', 'biplot',
+ 'Box.test', 'bw.bcv', 'bw.nrd', 'bw.nrd0', 'bw.SJ', 'bw.ucv', 'C', 'cancor',
+ 'case.names', 'ccf', 'chisq.test', 'clearNames', 'cmdscale', 'coef', 'coefficients',
+ 'complete.cases', 'confint', 'confint.default', 'constrOptim', 'contr.helmert',
+ 'contr.poly', 'contr.SAS', 'contr.sum', 'contr.treatment', 'contrasts', 'contrasts<-',
+ 'convolve', 'cooks.distance', 'cophenetic', 'cor', 'cor.test', 'cov', 'cov.wt',
+ 'cov2cor', 'covratio', 'cpgram', 'cutree', 'cycle', 'D', 'dbeta', 'dbinom', 'dcauchy',
+ 'dchisq', 'decompose', 'delete.response', 'deltat', 'dendrapply', 'density', 'density.default',
+ 'deriv', 'deriv.default', 'deriv.formula', 'deriv3', 'deriv3.default', 'deriv3.formula',
+ 'deviance', 'dexp', 'df', 'df.kernel', 'df.residual', 'dfbeta', 'dfbetas', 'dffits',
+ 'dgamma', 'dgeom', 'dhyper', 'diff.ts', 'diffinv', 'dist', 'dlnorm', 'dlogis',
+ 'dmultinom', 'dnbinom', 'dnorm', 'dpois', 'drop.scope', 'drop.terms', 'drop1',
+ 'dsignrank', 'dt', 'dummy.coef', 'dunif', 'dweibull', 'dwilcox', 'ecdf', 'eff.aovlist',
+ 'effects', 'embed', 'end', 'estVar', 'expand.model.frame', 'extractAIC', 'factanal',
+ 'factor.scope', 'family', 'fft', 'filter', 'fisher.test', 'fitted', 'fitted.values',
+ 'fivenum', 'fligner.test', 'formula', 'frequency', 'friedman.test', 'ftable', 'Gamma',
+ 'gaussian', 'get_all_vars', 'getInitial', 'glm', 'glm.control', 'glm.fit', 'glm.fit.null',
+ 'hasTsp', 'hat', 'hatvalues', 'hatvalues.lm', 'hclust', 'heatmap', 'HoltWinters', 'influence',
+ 'influence.measures', 'integrate', 'interaction.plot', 'inverse.gaussian', 'IQR',
+ 'is.empty.model', 'is.leaf', 'is.mts', 'is.stepfun', 'is.ts', 'is.tskernel', 'isoreg',
+ 'KalmanForecast', 'KalmanLike', 'KalmanRun', 'KalmanSmooth', 'kernapply', 'kernel', 'kmeans',
+ 'knots', 'kruskal.test', 'ks.test', 'ksmooth', 'lag', 'lag.plot', 'line', 'lines.ts', 'lm',
+ 'lm.fit', 'lm.fit.null', 'lm.influence', 'lm.wfit', 'lm.wfit.null', 'loadings', 'loess',
+ 'loess.control', 'loess.smooth', 'logLik', 'loglin', 'lowess', 'ls.diag', 'ls.print', 'lsfit',
+ 'mad', 'mahalanobis', 'make.link', 'makeARIMA', 'makepredictcall', 'manova', 'mantelhaen.test',
+ 'mauchley.test', 'mauchly.test', 'mcnemar.test', 'median', 'median.default', 'medpolish',
+ 'model.extract', 'model.frame', 'model.frame.aovlist', 'model.frame.default', 'model.frame.glm',
+ 'model.frame.lm', 'model.matrix', 'model.matrix.default', 'model.matrix.lm', 'model.offset',
+ 'model.response', 'model.tables', 'model.weights', 'monthplot', 'mood.test', 'mvfft', 'na.action',
+ 'na.contiguous', 'na.exclude', 'na.fail', 'na.omit', 'na.pass', 'napredict', 'naprint', 'naresid',
+ 'nextn', 'nlm', 'nlminb', 'nls', 'nls.control', 'NLSstAsymptotic', 'NLSstClosestX', 'NLSstLfAsymptote',
+ 'NLSstRtAsymptote', 'numericDeriv', 'offset', 'oneway.test', 'optim', 'optimise', 'optimize',
+ 'order.dendrogram', 'p.adjust', 'p.adjust.methods', 'pacf', 'pairwise.prop.test', 'pairwise.t.test',
+ 'pairwise.table', 'pairwise.wilcox.test', 'pbeta', 'pbinom', 'pbirthday', 'pcauchy', 'pchisq', 'pexp',
+ 'pf', 'pgamma', 'pgeom', 'phyper', 'plclust', 'plnorm', 'plogis', 'plot.density', 'plot.ecdf', 'plot.lm',
+ 'plot.mlm', 'plot.spec', 'plot.spec.coherency', 'plot.spec.phase', 'plot.stepfun', 'plot.ts', 'plot.TukeyHSD',
+ 'pnbinom', 'pnorm', 'poisson', 'poisson.test', 'poly', 'polym', 'power', 'power.anova.test', 'power.prop.test',
+ 'power.t.test', 'PP.test', 'ppoints', 'ppois', 'ppr', 'prcomp', 'predict', 'predict.glm', 'predict.lm',
+ 'predict.mlm', 'predict.poly', 'preplot', 'princomp', 'print.anova', 'print.coefmat', 'print.density',
+ 'print.family', 'print.formula', 'print.ftable', 'print.glm', 'print.infl', 'print.integrate', 'print.lm',
+ 'print.logLik', 'print.terms', 'print.ts', 'printCoefmat', 'profile', 'proj', 'promax', 'prop.test',
+ 'prop.trend.test', 'psignrank', 'pt', 'ptukey', 'punif', 'pweibull', 'pwilcox', 'qbeta', 'qbinom',
+ 'qbirthday', 'qcauchy', 'qchisq', 'qexp', 'qf', 'qgamma', 'qgeom', 'qhyper', 'qlnorm', 'qlogis',
+ 'qnbinom', 'qnorm', 'qpois', 'qqline', 'qqnorm', 'qqnorm.default', 'qqplot', 'qsignrank', 'qt',
+ 'qtukey', 'quade.test', 'quantile', 'quantile.default', 'quasi', 'quasibinomial', 'quasipoisson',
+ 'qunif', 'qweibull', 'qwilcox', 'r2dtable', 'rbeta', 'rbinom', 'rcauchy', 'rchisq', 'read.ftable',
+ 'rect.hclust', 'reformulate', 'relevel', 'reorder', 'replications', 'reshape', 'reshapeLong', 'reshapeWide',
+ 'resid', 'residuals', 'residuals.default', 'residuals.glm', 'residuals.lm', 'rexp', 'rf', 'rgamma', 'rgeom',
+ 'rhyper', 'rlnorm', 'rlogis', 'rmultinom', 'rnbinom', 'rnorm', 'rpois', 'rsignrank', 'rstandard', 'rstandard.glm',
+ 'rstandard.lm', 'rstudent', 'rstudent.glm', 'rstudent.lm', 'rt', 'runif', 'runmed', 'rweibull', 'rwilcox',
+ 'scatter.smooth', 'screeplot', 'sd', 'se.contrast', 'selfStart', 'setNames', 'shapiro.test', 'simulate',
+ 'smooth', 'smooth.spline', 'smoothEnds', 'sortedXyData', 'spec.ar', 'spec.pgram', 'spec.taper', 'spectrum',
+ 'spline', 'splinefun', 'splinefunH', 'SSasymp', 'SSasympOff', 'SSasympOrig', 'SSbiexp', 'SSD', 'SSfol',
+ 'SSfpl', 'SSgompertz', 'SSlogis', 'SSmicmen', 'SSweibull', 'start', 'stat.anova', 'step', 'stepfun', 'stl',
+ 'StructTS', 'summary.aov', 'summary.aovlist', 'summary.glm', 'summary.infl', 'summary.lm', 'summary.manova',
+ 'summary.mlm', 'summary.stepfun', 'supsmu', 'symnum', 't.test', 'termplot', 'terms', 'terms.aovlist',
+ 'terms.default', 'terms.formula', 'terms.terms', 'time', 'toeplitz', 'ts', 'ts.intersect', 'ts.plot',
+ 'ts.union', 'tsdiag', 'tsp', 'tsp<-', 'tsSmooth', 'TukeyHSD', 'TukeyHSD.aov', 'uniroot', 'update',
+ 'update.default', 'update.formula', 'var', 'var.test', 'variable.names', 'varimax', 'vcov', 'weighted.mean',
+ 'weighted.residuals', 'weights', 'wilcox.test', 'window', 'window<-', 'write.ftable', 'xtabs',
+ ),
+ 8 => array( // utils pkg
+ 'alarm', 'apropos', 'argsAnywhere', 'as.person', 'as.personList', 'as.relistable', 'as.roman',
+ 'assignInNamespace', 'available.packages', 'browseEnv', 'browseURL', 'browseVignettes', 'bug.report',
+ 'capture.output', 'checkCRAN', 'chooseCRANmirror', 'citation', 'citEntry', 'citFooter', 'citHeader',
+ 'close.socket', 'combn', 'compareVersion', 'contrib.url', 'count.fields', 'CRAN.packages', 'data',
+ 'data.entry', 'dataentry', 'de', 'de.ncols', 'de.restore', 'de.setup', 'debugger', 'demo', 'download.file',
+ 'download.packages', 'dump.frames', 'edit', 'emacs', 'example', 'file_test', 'file.edit', 'find', 'fix',
+ 'fixInNamespace', 'flush.console', 'formatOL', 'formatUL', 'getAnywhere', 'getCRANmirrors', 'getFromNamespace',
+ 'getS3method', 'getTxtProgressBar', 'glob2rx', 'head', 'head.matrix', 'help', 'help.request', 'help.search',
+ 'help.start', 'history', 'index.search', 'install.packages', 'installed.packages', 'is.relistable',
+ 'limitedLabels', 'loadhistory', 'localeToCharset', 'ls.str', 'lsf.str', 'make.packages.html', 'make.socket',
+ 'makeRweaveLatexCodeRunner', 'memory.limit', 'memory.size', 'menu', 'mirror2html', 'modifyList',
+ 'new.packages', 'normalizePath', 'nsl', 'object.size', 'old.packages', 'package.contents', 'package.skeleton',
+ 'packageDescription', 'packageStatus', 'page', 'person', 'personList', 'pico', 'prompt', 'promptData',
+ 'promptPackage', 'rc.getOption', 'rc.options', 'rc.settings', 'rc.status', 'read.csv', 'read.csv2', 'read.delim',
+ 'read.delim2', 'read.DIF', 'read.fortran', 'read.fwf', 'read.socket', 'read.table', 'readCitationFile', 'recover',
+ 'relist', 'remove.packages', 'Rprof', 'Rprofmem', 'RShowDoc', 'RSiteSearch', 'rtags', 'Rtangle', 'RtangleSetup',
+ 'RtangleWritedoc', 'RweaveChunkPrefix', 'RweaveEvalWithOpt', 'RweaveLatex', 'RweaveLatexFinish', 'RweaveLatexOptions',
+ 'RweaveLatexSetup', 'RweaveLatexWritedoc', 'RweaveTryStop', 'savehistory', 'select.list', 'sessionInfo',
+ 'setRepositories', 'setTxtProgressBar', 'stack', 'Stangle', 'str', 'strOptions', 'summaryRprof', 'Sweave',
+ 'SweaveHooks', 'SweaveSyntaxLatex', 'SweaveSyntaxNoweb', 'SweaveSyntConv', 'tail', 'tail.matrix', 'timestamp',
+ 'toBibtex', 'toLatex', 'txtProgressBar', 'type.convert', 'unstack', 'unzip', 'update.packages', 'update.packageStatus',
+ 'upgrade', 'url.show', 'URLdecode', 'URLencode', 'vi', 'View', 'vignette', 'write.csv', 'write.csv2', 'write.socket',
+ 'write.table', 'wsbrowser', 'xedit', 'xemacs', 'zip.file.extract',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '!', '%', '^', '&', '/','+','-','*','=','<','>',';','|','<-','->',
+ '^', '-', ':', '::', ':::', '!', '!=', '*', '?',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF; font-weight: bold;',
+ 2 => 'color: #0000FF; font-weight: bold;',
+ 3 => 'color: #CC9900; font-weight: bold;',
+ 4 => 'color: #0000FF; font-weight: bold;',
+ 5 => 'color: #0000FF; font-weight: bold;',
+ 6 => 'color: #0000FF; font-weight: bold;',
+ 7 => 'color: #0000FF; font-weight: bold;',
+ 8 => 'color: #0000FF; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #228B22;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'METHODS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #080;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color:#A020F0;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '' )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => 'http://stat.ethz.ch/R-manual/R-devel/library/base/html/{FNAME}.html', // Base Package
+ 3 => 'http://stat.ethz.ch/R-manual/R-devel/library/datasets/html/{FNAME}.html', // Datasets
+ 4 => 'http://stat.ethz.ch/R-manual/R-devel/library/graphics/html/{FNAME}.html', // Graphics Package
+ 5 => 'http://stat.ethz.ch/R-manual/R-devel/library/grDevices/html/{FNAME}.html', // grDevices
+ 6 => 'http://stat.ethz.ch/R-manual/R-devel/library/methods/html/{FNAME}.html', // methods
+ 7 => 'http://stat.ethz.ch/R-manual/R-devel/library/stats/html/{FNAME}.html', // stats
+ 8 => 'http://stat.ethz.ch/R-manual/R-devel/library/utils/html/{FNAME}.html' // utils
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ 0 => array(
+ GESHI_SEARCH => "([^\w])'([^\\n\\r']*)'",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => "\\1'",
+ GESHI_AFTER => "'"
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#;>|^&\\.])(?<!\/html\/)",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_\|%\\-&;\\.])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/ruby.php b/platform/www/vendor/geshi/geshi/src/geshi/ruby.php
new file mode 100644
index 0000000..0b8aa33
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/ruby.php
@@ -0,0 +1,229 @@
+<?php
+/*************************************************************************************
+ * ruby.php
+ * --------
+ * Author: Moises Deniz
+ * Copyright: (c) 2007 Moises Deniz
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/03/21
+ *
+ * Ruby language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2007/03/21 (1.0.7.19)
+ * - Initial release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Ruby',
+ 'COMMENT_SINGLE' => array(1 => "#"),
+ 'COMMENT_MULTI' => array("=begin" => "=end"),
+ 'COMMENT_REGEXP' => array(
+ //Heredoc
+ 4 => '/<<\s*?(\w+)\\n.*?\\n\\1(?![a-zA-Z0-9])/si',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', '`','\''),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'alias', 'and', 'begin', 'break', 'case', 'class',
+ 'def', 'defined', 'do', 'else', 'elsif', 'end',
+ 'ensure', 'for', 'if', 'in', 'module', 'while',
+ 'next', 'not', 'or', 'redo', 'rescue', 'yield',
+ 'retry', 'super', 'then', 'undef', 'unless',
+ 'until', 'when', 'include'
+ ),
+ 2 => array(
+ '__FILE__', '__LINE__', 'false', 'nil', 'self', 'true',
+ 'return'
+ ),
+ 3 => array(
+ 'Array', 'Float', 'Integer', 'String', 'at_exit',
+ 'autoload', 'binding', 'caller', 'catch', 'chop', 'chop!',
+ 'chomp', 'chomp!', 'eval', 'exec', 'exit', 'exit!', 'fail',
+ 'fork', 'format', 'gets', 'global_variables', 'gsub', 'gsub!',
+ 'iterator?', 'lambda', 'load', 'local_variables', 'loop',
+ 'open', 'p', 'print', 'printf', 'proc', 'putc', 'puts',
+ 'raise', 'rand', 'readline', 'readlines', 'require', 'select',
+ 'sleep', 'split', 'sprintf', 'srand', 'sub', 'sub!', 'syscall',
+ 'system', 'trace_var', 'trap', 'untrace_var'
+ ),
+ 4 => array(
+ 'Abbrev', 'ArgumentError', 'Base64', 'Benchmark',
+ 'Benchmark::Tms', 'Bignum', 'Binding', 'CGI', 'CGI::Cookie',
+ 'CGI::HtmlExtension', 'CGI::QueryExtension',
+ 'CGI::Session', 'CGI::Session::FileStore',
+ 'CGI::Session::MemoryStore', 'Class', 'Comparable', 'Complex',
+ 'ConditionVariable', 'Continuation', 'Data',
+ 'Date', 'DateTime', 'Delegator', 'Dir', 'EOFError', 'ERB',
+ 'ERB::Util', 'Enumerable', 'Enumerable::Enumerator', 'Errno',
+ 'Exception', 'FalseClass', 'File',
+ 'File::Constants', 'File::Stat', 'FileTest', 'FileUtils',
+ 'FileUtils::DryRun', 'FileUtils::NoWrite',
+ 'FileUtils::StreamUtils_', 'FileUtils::Verbose', 'Find',
+ 'Fixnum', 'FloatDomainError', 'Forwardable', 'GC', 'Generator',
+ 'Hash', 'IO', 'IOError', 'Iconv', 'Iconv::BrokenLibrary',
+ 'Iconv::Failure', 'Iconv::IllegalSequence',
+ 'Iconv::InvalidCharacter', 'Iconv::InvalidEncoding',
+ 'Iconv::OutOfRange', 'IndexError', 'Interrupt', 'Kernel',
+ 'LoadError', 'LocalJumpError', 'Logger', 'Logger::Application',
+ 'Logger::Error', 'Logger::Formatter', 'Logger::LogDevice',
+ 'Logger::LogDevice::LogDeviceMutex', 'Logger::Severity',
+ 'Logger::ShiftingError', 'Marshal', 'MatchData',
+ 'Math', 'Matrix', 'Method', 'Module', 'Mutex', 'NameError',
+ 'NameError::message', 'NilClass', 'NoMemoryError',
+ 'NoMethodError', 'NotImplementedError', 'Numeric', 'Object',
+ 'ObjectSpace', 'Observable', 'PStore', 'PStore::Error',
+ 'Pathname', 'Precision', 'Proc', 'Process', 'Process::GID',
+ 'Process::Status', 'Process::Sys', 'Process::UID', 'Queue',
+ 'Range', 'RangeError', 'Rational', 'Regexp', 'RegexpError',
+ 'RuntimeError', 'ScriptError', 'SecurityError', 'Set',
+ 'Shellwords', 'Signal', 'SignalException', 'SimpleDelegator',
+ 'SingleForwardable', 'Singleton', 'SingletonClassMethods',
+ 'SizedQueue', 'SortedSet', 'StandardError', 'StringIO',
+ 'StringScanner', 'StringScanner::Error', 'Struct', 'Symbol',
+ 'SyncEnumerator', 'SyntaxError', 'SystemCallError',
+ 'SystemExit', 'SystemStackError', 'Tempfile',
+ 'Test::Unit::TestCase', 'Test::Unit', 'Test', 'Thread',
+ 'ThreadError', 'ThreadGroup',
+ 'ThreadsWait', 'Time', 'TrueClass', 'TypeError', 'URI',
+ 'URI::BadURIError', 'URI::Error', 'URI::Escape', 'URI::FTP',
+ 'URI::Generic', 'URI::HTTP', 'URI::HTTPS',
+ 'URI::InvalidComponentError', 'URI::InvalidURIError',
+ 'URI::LDAP', 'URI::MailTo', 'URI::REGEXP',
+ 'URI::REGEXP::PATTERN', 'UnboundMethod', 'Vector', 'YAML',
+ 'ZeroDivisionError', 'Zlib',
+ 'Zlib::BufError', 'Zlib::DataError', 'Zlib::Deflate',
+ 'Zlib::Error', 'Zlib::GzipFile', 'Zlib::GzipFile::CRCError',
+ 'Zlib::GzipFile::Error', 'Zlib::GzipFile::LengthError',
+ 'Zlib::GzipFile::NoFooter', 'Zlib::GzipReader',
+ 'Zlib::GzipWriter', 'Zlib::Inflate', 'Zlib::MemError',
+ 'Zlib::NeedDict', 'Zlib::StreamEnd', 'Zlib::StreamError',
+ 'Zlib::VersionError',
+ 'Zlib::ZStream',
+ 'HTML::Selector', 'HashWithIndifferentAccess', 'Inflector',
+ 'Inflector::Inflections', 'Mime', 'Mime::Type',
+ 'OCI8AutoRecover', 'TimeZone', 'XmlSimple'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '%', '&', '*', '|', '/', '<', '>',
+ '+', '-', '=>', '<<'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color:#9966CC; font-weight:bold;',
+ 2 => 'color:#0000FF; font-weight:bold;',
+ 3 => 'color:#CC0066; font-weight:bold;',
+ 4 => 'color:#CC00FF; font-weight:bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color:#008000; font-style:italic;',
+ 4 => 'color: #cc0000; font-style: italic;',
+ 'MULTI' => 'color:#000080; font-style:italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color:#000099;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color:#006600; font-weight:bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color:#996600;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color:#006666;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color:#9900CC;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color:#006600; font-weight:bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color:#ff6633; font-weight:bold;',
+ 1 => 'color:#0066ff; font-weight:bold;',
+ 2 => 'color:#6666ff; font-weight:bold;',
+ 3 => 'color:#ff3333; font-weight:bold;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ 0 => array(//Variables
+ GESHI_SEARCH => "([[:space:]])(\\$[a-zA-Z_][a-zA-Z0-9_]*)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 1 => array(//Arrays
+ GESHI_SEARCH => "([[:space:]])(@[a-zA-Z_][a-zA-Z0-9_]*)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 2 => "([A-Z][a-zA-Z0-9_]*::)+[A-Z][a-zA-Z0-9_]*",//Static OOP symbols
+ 3 => array(
+ GESHI_SEARCH => "([[:space:]]|\[|\()(:[a-zA-Z_][a-zA-Z0-9_]*)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<%' => '%>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ ),
+ 'TAB_WIDTH' => 2
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/rust.php b/platform/www/vendor/geshi/geshi/src/geshi/rust.php
new file mode 100644
index 0000000..3fb5c36
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/rust.php
@@ -0,0 +1,235 @@
+<?php
+/*************************************************************************************
+ * rust.php
+ * --------
+ * Author: Edward Hart (edward.dan.hart@gmail.com)
+ * Copyright: (c) 2013 Edward Hart
+ * Release Version: 1.0.9.1
+ * Date Started: 2013/10/20
+ *
+ * Rust language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2014/03/18
+ * - Added support for raw strings
+ * - Color symbols
+ * 2013/10/20
+ * - First Release
+ *
+ * TODO (updated 2013/10/20)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Rust',
+
+ 'COMMENT_SINGLE' => array('//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ // Raw strings
+ 1 => '/\\br(\\#*)".*?"\\1/'
+ ),
+
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[\\\\nrt\'\"?\n]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+
+ 'KEYWORDS' => array(
+ // Keywords
+ 1 => array(
+ 'alt', 'as', 'assert', 'break', 'const', 'continue', 'copy', 'do',
+ 'else', 'enum', 'extern', 'fn', 'for', 'if',
+ 'impl', 'in', 'let', 'log', 'loop', 'match', 'mod', 'mut', 'of',
+ 'priv', 'pub', 'ref', 'return', 'self', 'static', 'struct', 'super',
+ 'to', 'trait', 'type', 'unsafe', 'use', 'with', 'while'
+ ),
+ // Boolean values
+ 2 => array( 'true', 'false' ),
+ // Structs and built-in types
+ 3 => array(
+ 'u8', 'i8',
+ 'u16', 'i16',
+ 'u32', 'i32',
+ 'u64', 'i64',
+ 'f32', 'f64',
+ 'int', 'uint',
+ 'float',
+ 'bool',
+ 'str', 'char',
+ 'Argument', 'AsyncWatcher', 'BorrowRecord', 'BufReader',
+ 'BufWriter', 'BufferedReader', 'BufferedStream', 'BufferedWriter',
+ 'ByRef', 'ByteIterator', 'CFile', 'CString', 'CStringIterator',
+ 'Cell', 'Chain', 'Chan', 'ChanOne', 'CharIterator',
+ 'CharOffsetIterator', 'CharRange', 'CharSplitIterator',
+ 'CharSplitNIterator', 'ChunkIter', 'Condition', 'ConnectRequest',
+ 'Coroutine', 'Counter', 'CrateMap', 'Cycle', 'DeflateWriter',
+ 'Display', 'ElementSwaps', 'Enumerate', 'Exp', 'Exp1', 'FileDesc',
+ 'FileReader', 'FileStat', 'FileStream', 'FileWriter', 'Filter',
+ 'FilterMap', 'FlatMap', 'FormatSpec', 'Formatter', 'FsRequest',
+ 'Fuse', 'GarbageCollector', 'GetAddrInfoRequest', 'Handle',
+ 'HashMap', 'HashMapIterator', 'HashMapMoveIterator',
+ 'HashMapMutIterator', 'HashSet', 'HashSetIterator',
+ 'HashSetMoveIterator', 'Hint', 'IdleWatcher', 'InflateReader',
+ 'Info', 'Inspect', 'Invert', 'IoError', 'Isaac64Rng', 'IsaacRng',
+ 'LineBufferedWriter', 'Listener', 'LocalHeap', 'LocalStorage',
+ 'Loop', 'Map', 'MatchesIndexIterator', 'MemReader', 'MemWriter',
+ 'MemoryMap', 'ModEntry', 'MoveIterator', 'MovePtrAdaptor',
+ 'MoveRevIterator', 'NoOpRunnable', 'NonCopyable', 'Normal',
+ 'OSRng', 'OptionIterator', 'Parser', 'Path', 'Peekable',
+ 'Permutations', 'Pipe', 'PipeStream', 'PluralArm', 'Port',
+ 'PortOne', 'Process', 'ProcessConfig', 'ProcessOptions',
+ 'ProcessOutput', 'RC', 'RSplitIterator', 'RandSample', 'Range',
+ 'RangeInclusive', 'RangeStep', 'RangeStepInclusive', 'Rc', 'RcMut',
+ 'ReaderRng', 'Repeat', 'ReprVisitor', 'RequestData',
+ 'ReseedWithDefault', 'ReseedingRng', 'Scan', 'SchedOpts',
+ 'SelectArm', 'SharedChan', 'SharedPort', 'SignalWatcher',
+ 'SipState', 'Skip', 'SkipWhile', 'SocketAddr', 'SplitIterator',
+ 'StackPool', 'StackSegment', 'StandardNormal', 'StdErrLogger',
+ 'StdIn', 'StdOut', 'StdReader', 'StdRng', 'StdWriter',
+ 'StrSplitIterator', 'StreamWatcher', 'TTY', 'Take', 'TakeWhile',
+ 'Task', 'TaskBuilder', 'TaskOpts', 'TcpAcceptor', 'TcpListener',
+ 'TcpStream', 'TcpWatcher', 'Timer', 'TimerWatcher', 'TrieMap',
+ 'TrieMapIterator', 'TrieSet', 'TrieSetIterator', 'Tube',
+ 'UdpSendRequest', 'UdpSocket', 'UdpStream', 'UdpWatcher', 'Unfold',
+ 'UnixAcceptor', 'UnixListener', 'UnixStream', 'Unwinder',
+ 'UvAddrInfo', 'UvError', 'UvEventLoop', 'UvFileStream',
+ 'UvIoFactory', 'UvPausibleIdleCallback', 'UvPipeStream',
+ 'UvProcess', 'UvRemoteCallback', 'UvSignal', 'UvTTY',
+ 'UvTcpAcceptor', 'UvTcpListener', 'UvTcpStream', 'UvTimer',
+ 'UvUdpSocket', 'UvUnboundPipe', 'UvUnixAcceptor', 'UvUnixListener',
+ 'VecIterator', 'VecMutIterator', 'Weighted', 'WeightedChoice',
+ 'WindowIter', 'WriteRequest', 'XorShiftRng', 'Zip', 'addrinfo',
+ 'uv_buf_t', 'uv_err_data', 'uv_process_options_t', 'uv_stat_t',
+ 'uv_stdio_container_t', 'uv_timespec_t'
+ ),
+ // Enums
+ 4 => array(
+ 'Alignment', 'Count', 'Either', 'ExponentFormat', 'FPCategory',
+ 'FileAccess', 'FileMode', 'Flag', 'IoErrorKind', 'IpAddr',
+ 'KeyValue', 'MapError', 'MapOption', 'MemoryMapKind', 'Method',
+ 'NullByteResolution', 'Option', 'Ordering', 'PathPrefix', 'Piece',
+ 'PluralKeyword', 'Position', 'Protocol', 'Result', 'SchedHome',
+ 'SchedMode', 'SeekStyle', 'SendStr', 'SignFormat',
+ 'SignificantDigits', 'Signum', 'SocketType', 'StdioContainer',
+ 'TaskResult', 'TaskType', 'UvSocketAddr', 'Void', 'uv_handle_type',
+ 'uv_membership', 'uv_req_type'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']',
+ '+', '-', '*', '/', '%',
+ '&', '|', '^', '!', '<', '>', '~', '@',
+ ':',
+ ';', ',',
+ '='
+ ),
+
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true
+ ),
+
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #708;',
+ 2 => 'color: #219;',
+ 3 => 'color: #05a;',
+ 4 => 'color: #800;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #a50; font-style: italic;',
+ 1 => 'color: #a11;',
+ 'MULTI' => 'color: #a50; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => ''
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #a11;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'BRACKETS' => array(''),
+ 'METHODS' => array(
+ 1 => 'color: #164;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/sas.php b/platform/www/vendor/geshi/geshi/src/geshi/sas.php
new file mode 100644
index 0000000..3d370be
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/sas.php
@@ -0,0 +1,288 @@
+<?php
+/*************************************************************************************
+ * sas.php
+ * -------
+ * Author: Galen Johnson (solitaryr@gmail.com)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/12/27
+ *
+ * SAS language file for GeSHi. Based on the sas vim file.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * - Cleaned up code style
+ * 2005/12/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2005/12/27)
+ * -------------------------
+ * * Check highlighting stuff works
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'SAS',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('/*' => '*/', '*' => ';'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ '_ALL_','_CHARACTER_','_INFILE_','_N_','_NULL_','_NUMERIC_',
+ '_WEBOUT_'
+ ),
+ 2 => array(
+ '%BQUOTE','%CMPRES','%COMPSTOR','%DATATYP','%DISPLAY','%DO','%ELSE',
+ '%END','%EVAL','%GLOBAL','%GOTO','%IF','%INDEX','%INPUT','%KEYDEF',
+ '%LABEL','%LEFT','%LENGTH','%LET','%LOCAL','%LOWCASE','%MACRO',
+ '%MEND','%NRBQUOTE','%NRQUOTE','%NRSTR','%PUT','%QCMPRES','%QLEFT',
+ '%QLOWCASE','%QSCAN','%QSUBSTR','%QSYSFUNC','%QTRIM','%QUOTE',
+ '%QUPCASE','%SCAN','%STR','%SUBSTR','%SUPERQ','%SYSCALL',
+ '%SYSEVALF','%SYSEXEC','%SYSFUNC','%SYSGET','%SYSLPUT','%SYSPROD',
+ '%SYSRC','%SYSRPUT','%THEN','%TO','%TRIM','%UNQUOTE','%UNTIL',
+ '%UPCASE','%VERIFY','%WHILE','%WINDOW'
+ ),
+ 3 => array(
+ 'ABS','ADDR','AIRY','ARCOS','ARSIN','ATAN','ATTRC','ATTRN','BAND',
+ 'BETAINV','BLSHIFT','BNOT','BOR','BRSHIFT','BXOR','BYTE','CDF',
+ 'CEIL','CEXIST','CINV','CLOSE','CNONCT','COLLATE','COMPBL',
+ 'COMPOUND','COMPRESS','COSH','COS','CSS','CUROBS','CV','DACCDBSL',
+ 'DACCDB','DACCSL','DACCSYD','DACCTAB','DAIRY','DATETIME','DATEJUL',
+ 'DATEPART','DATE','DAY','DCLOSE','DEPDBSL','DEPDB','DEPSL','DEPSYD',
+ 'DEPTAB','DEQUOTE','DHMS','DIF','DIGAMMA','DIM','DINFO','DNUM',
+ 'DOPEN','DOPTNAME','DOPTNUM','DREAD','DROPNOTE','DSNAME','ERFC',
+ 'ERF','EXIST','EXP','FAPPEND','FCLOSE','FCOL','FDELETE','FETCHOBS',
+ 'FETCH','FEXIST','FGET','FILEEXIST','FILENAME','FILEREF','FINFO',
+ 'FINV','FIPNAMEL','FIPNAME','FIPSTATE','FLOOR','FNONCT','FNOTE',
+ 'FOPEN','FOPTNAME','FOPTNUM','FPOINT','FPOS','FPUT','FREAD',
+ 'FREWIND','FRLEN','FSEP','FUZZ','FWRITE','GAMINV','GAMMA',
+ 'GETOPTION','GETVARC','GETVARN','HBOUND','HMS','HOSTHELP','HOUR',
+ 'IBESSEL','INDEXW','INDEXC','INDEX','INPUTN','INPUTC','INPUT',
+ 'INTRR','INTCK','INTNX','INT','IRR','JBESSEL','JULDATE','KURTOSIS',
+ 'LAG','LBOUND','LEFT','LENGTH','LGAMMA','LIBNAME','LIBREF','LOG10',
+ 'LOG2','LOGPDF','LOGPMF','LOGSDF','LOG','LOWCASE','MAX','MDY',
+ 'MEAN','MINUTE','MIN','MOD','MONTH','MOPEN','MORT','NETPV','NMISS',
+ 'NORMAL','NPV','N','OPEN','ORDINAL','PATHNAME','PDF','PEEKC','PEEK',
+ 'PMF','POINT','POISSON','POKE','PROBBETA','PROBBNML','PROBCHI',
+ 'PROBF','PROBGAM','PROBHYPR','PROBIT','PROBNEGB','PROBNORM','PROBT',
+ 'PUTN','PUTC','PUT','QTR','QUOTE','RANBIN','RANCAU','RANEXP',
+ 'RANGAM','RANGE','RANK','RANNOR','RANPOI','RANTBL','RANTRI',
+ 'RANUNI','REPEAT','RESOLVE','REVERSE','REWIND','RIGHT','ROUND',
+ 'SAVING','SCAN','SDF','SECOND','SIGN','SINH','SIN','SKEWNESS',
+ 'SOUNDEX','SPEDIS','SQRT','STDERR','STD','STFIPS','STNAME',
+ 'STNAMEL','SUBSTR','SUM','SYMGET','SYSGET','SYSMSG','SYSPROD',
+ 'SYSRC','SYSTEM','TANH','TAN','TIMEPART','TIME','TINV','TNONCT',
+ 'TODAY','TRANSLATE','TRANWRD','TRIGAMMA','TRIMN','TRIM','TRUNC',
+ 'UNIFORM','UPCASE','USS','VARFMT','VARINFMT','VARLABEL','VARLEN',
+ 'VARNAME','VARNUM','VARRAYX','VARRAY','VARTYPE','VAR','VERIFY',
+ 'VFORMATX','VFORMATDX','VFORMATD','VFORMATNX','VFORMATN',
+ 'VFORMATWX','VFORMATW','VFORMAT','VINARRAYX','VINARRAY',
+ 'VINFORMATX','VINFORMATDX','VINFORMATD','VINFORMATNX','VINFORMATN',
+ 'VINFORMATWX','VINFORMATW','VINFORMAT','VLABELX','VLABEL',
+ 'VLENGTHX','VLENGTH','VNAMEX','VNAME','VTYPEX','VTYPE','WEEKDAY',
+ 'YEAR','YYQ','ZIPFIPS','ZIPNAME','ZIPNAMEL','ZIPSTATE'
+ ),
+ 4 => array(
+ 'ABORT','ADD','ALTER','AND','ARRAY','AS','ATTRIB','BY','CALL',
+ 'CARDS4','CASCADE','CATNAME','CHECK','CONTINUE','CREATE',
+ 'DATALINES4','DELETE','DESCRIBE','DISPLAY','DISTINCT','DM','DROP',
+ 'ENDSAS','FILE','FOOTNOTE','FOREIGN','FORMAT','FROM',
+ 'GOTO','GROUP','HAVING','IN','INFILE','INFORMAT',
+ 'INSERT','INTO','KEEP','KEY','LABEL','LEAVE',
+ 'LIKE','LINK','LIST','LOSTCARD','MERGE','MESSAGE','MISSING',
+ 'MODIFY','MSGTYPE','NOT','NULL','ON','OPTIONS','OR','ORDER',
+ 'OUTPUT','PAGE','PRIMARY','REDIRECT','REFERENCES','REMOVE',
+ 'RENAME','REPLACE','RESET','RESTRICT','RETAIN','RETURN','SELECT',
+ 'SET','SKIP','STARTSAS','STOP','SYSTASK','TABLE','TITLE','UNIQUE',
+ 'UPDATE','VALIDATE','VIEW','WAITSAS','WHERE','WINDOW','X'
+ ),
+ 5 => array(
+ 'DO','ELSE','END','IF','THEN','UNTIL','WHILE'
+ ),
+ 6 => array(
+ 'RUN','QUIT','DATA'
+ ),
+ 7 => array(
+ 'ERROR'
+ ),
+ 8 => array(
+ 'WARNING'
+ ),
+ 9 => array(
+ 'NOTE'
+ )
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ 8 => false,
+ 9 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #0000ff;',
+ 4 => 'color: #0000ff;',
+ 5 => 'color: #0000ff;',
+ 6 => 'color: #000080; font-weight: bold;',
+ 7 => 'color: #ff0000;',
+ 8 => 'color: #00ff00;',
+ 9 => 'color: #0000ff;'
+ ),
+ 'COMMENTS' => array(
+// 1 => 'color: #006400; font-style: italic;',
+ 'MULTI' => 'color: #006400; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #a020f0;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #2e8b57; font-weight: bold;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000ff; font-weight: bold;',
+ 1 => 'color: #000080; font-weight: bold;',
+ 2 => 'color: #006400; font-style: italic;',
+ 3 => 'color: #006400; font-style: italic;',
+ 4 => 'color: #006400; font-style: italic;',
+ 5 => 'color: #ff0000; font-weight: bold;',
+ 6 => 'color: #00ff00; font-style: italic;',
+ 7 => 'color: #0000ff; font-style: normal;',
+ 8 => 'color: #b218b2; font-weight: bold;',
+ 9 => 'color: #b218b2; font-weight: bold;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+ 9 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => "&amp;[a-zA-Z_][a-zA-Z0-9_]*",
+ 1 => array(//Procedures
+ GESHI_SEARCH => '(^\\s*)(PROC \\w+)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'im',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 2 => array(
+ GESHI_SEARCH => '(^\\s*)(\\*.*;)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'im',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 3 => array(
+ GESHI_SEARCH => '(.*;\\s*)(\\*.*;)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'im',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 4 => array(
+ GESHI_SEARCH => '(^\\s*)(%\\*.*;)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'im',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 5 => array(//Error messages
+ GESHI_SEARCH => '(^ERROR.*)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'im',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 6 => array(//Warning messages
+ GESHI_SEARCH => '(^WARNING.*)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'im',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 7 => array(//Notice messages
+ GESHI_SEARCH => '(^NOTE.*)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'im',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 8 => array(
+ GESHI_SEARCH => '(^\\s*)(CARDS.*)(^\\s*;\\s*$)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'sim',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+ 9 => array(
+ GESHI_SEARCH => '(^\\s*)(DATALINES.*)(^\\s*;\\s*$)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'sim',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/sass.php b/platform/www/vendor/geshi/geshi/src/geshi/sass.php
new file mode 100644
index 0000000..725435a
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/sass.php
@@ -0,0 +1,590 @@
+<?php
+/*************************************************************************************
+ * sass.php
+ * -------
+ * Author: Javier Eguiluz (javier.eguiluz@gmail.com)
+ * Copyright: (c) 2014 Javier Eguiluz (javier.eguiluz@gmail.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2014/05/10
+ *
+ * SASS language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2014/05/10 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Sass',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'"),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ // properties
+ 1 => array(
+ 'azimuth',
+ 'background-attachment',
+ 'background-color',
+ 'background-image',
+ 'background-position',
+ 'background-repeat',
+ 'background',
+ 'border-bottom-color',
+ 'border-radius',
+ 'border-top-left-radius',
+ 'border-top-right-radius',
+ 'border-bottom-right-radius',
+ 'border-bottom-left-radius',
+ 'border-bottom-style',
+ 'border-bottom-width',
+ 'border-left-color',
+ 'border-left-style',
+ 'border-left-width',
+ 'border-right',
+ 'border-right-color',
+ 'border-right-style',
+ 'border-right-width',
+ 'border-top-color',
+ 'border-top-style',
+ 'border-top-width',
+ 'border-bottom',
+ 'border-collapse',
+ 'border-left',
+ 'border-width',
+ 'border-color',
+ 'border-spacing',
+ 'border-style',
+ 'border-top',
+ 'border',
+ 'box-shadow',
+ 'caption-side',
+ 'clear',
+ 'clip',
+ 'color',
+ 'content',
+ 'counter-increment',
+ 'counter-reset',
+ 'cue-after',
+ 'cue-before',
+ 'cue',
+ 'cursor',
+ 'direction',
+ 'display',
+ 'elevation',
+ 'empty-cells',
+ 'float',
+ 'font-family',
+ 'font-size',
+ 'font-size-adjust',
+ 'font-stretch',
+ 'font-style',
+ 'font-variant',
+ 'font-weight',
+ 'font',
+ 'line-height',
+ 'letter-spacing',
+ 'list-style',
+ 'list-style-image',
+ 'list-style-position',
+ 'list-style-type',
+ 'margin-bottom',
+ 'margin-left',
+ 'margin-right',
+ 'margin-top',
+ 'margin',
+ 'marker-offset',
+ 'marks',
+ 'max-height',
+ 'max-width',
+ 'min-height',
+ 'min-width',
+ 'orphans',
+ 'outline',
+ 'outline-color',
+ 'outline-style',
+ 'outline-width',
+ 'overflow',
+ 'padding-bottom',
+ 'padding-left',
+ 'padding-right',
+ 'padding-top',
+ 'padding',
+ 'page',
+ 'page-break-after',
+ 'page-break-before',
+ 'page-break-inside',
+ 'pause-after',
+ 'pause-before',
+ 'pause',
+ 'pitch',
+ 'pitch-range',
+ 'play-during',
+ 'position',
+ 'quotes',
+ 'richness',
+ 'right',
+ 'size',
+ 'speak-header',
+ 'speak-numeral',
+ 'speak-punctuation',
+ 'speak',
+ 'speech-rate',
+ 'stress',
+ 'table-layout',
+ 'text-align',
+ 'text-decoration',
+ 'text-indent',
+ 'text-shadow',
+ 'text-transform',
+ 'top',
+ 'unicode-bidi',
+ 'vertical-align',
+ 'visibility',
+ 'voice-family',
+ 'volume',
+ 'white-space',
+ 'widows',
+ 'width',
+ 'word-spacing',
+ 'z-index',
+ 'bottom',
+ 'left',
+ 'height',
+ // media queries
+ 'screen',
+ 'orientation',
+ 'min-device-width',
+ 'max-device-width',
+ ),
+ // reserved words for values
+ 2 => array(
+ // colors
+ 'aqua',
+ 'black',
+ 'blue',
+ 'fuchsia',
+ 'gray',
+ 'green',
+ 'lime',
+ 'maroon',
+ 'navy',
+ 'olive',
+ 'orange',
+ 'purple',
+ 'red',
+ 'silver',
+ 'teal',
+ 'white',
+ 'yellow',
+ // media queries
+ 'landscape',
+ 'portrait',
+ // other
+ 'above',
+ 'absolute',
+ 'always',
+ 'armenian',
+ 'aural',
+ 'auto',
+ 'avoid',
+ 'baseline',
+ 'behind',
+ 'below',
+ 'bidi-override',
+ 'blink',
+ 'block',
+ 'bold',
+ 'bolder',
+ 'both',
+ 'capitalize',
+ 'center-left',
+ 'center-right',
+ 'center',
+ 'circle',
+ 'cjk-ideographic',
+ 'close-quote',
+ 'collapse',
+ 'condensed',
+ 'continuous',
+ 'crop',
+ 'crosshair',
+ 'cross',
+ 'cursive',
+ 'dashed',
+ 'decimal-leading-zero',
+ 'decimal',
+ 'default',
+ 'digits',
+ 'disc',
+ 'dotted',
+ 'double',
+ 'e-resize',
+ 'embed',
+ 'extra-condensed',
+ 'extra-expanded',
+ 'expanded',
+ 'fantasy',
+ 'far-left',
+ 'far-right',
+ 'faster',
+ 'fast',
+ 'fixed',
+ 'georgian',
+ 'groove',
+ 'hebrew',
+ 'help',
+ 'hidden',
+ 'hide',
+ 'higher',
+ 'high',
+ 'hiragana-iroha',
+ 'hiragana',
+ 'icon',
+ 'inherit',
+ 'inline-table',
+ 'inline',
+ 'inline-block',
+ 'inset',
+ 'inside',
+ 'italic',
+ 'justify',
+ 'katakana-iroha',
+ 'katakana',
+ 'larger',
+ 'large',
+ 'left-side',
+ 'leftwards',
+ 'level',
+ 'lighter',
+ 'line-through',
+ 'list-item',
+ 'loud',
+ 'lower-alpha',
+ 'lower-greek',
+ 'lower-roman',
+ 'lowercase',
+ 'ltr',
+ 'lower',
+ 'low',
+ 'medium',
+ 'message-box',
+ 'middle',
+ 'monospace',
+ 'n-resize',
+ 'narrower',
+ 'ne-resize',
+ 'no-close-quote',
+ 'no-open-quote',
+ 'no-repeat',
+ 'none',
+ 'normal',
+ 'nowrap',
+ 'nw-resize',
+ 'oblique',
+ 'once',
+ 'open-quote',
+ 'outset',
+ 'outside',
+ 'overline',
+ 'pointer',
+ 'px',
+ 'relative',
+ 'repeat-x',
+ 'repeat-y',
+ 'repeat',
+ 'ridge',
+ 'right-side',
+ 'rightwards',
+ 's-resize',
+ 'sans-serif',
+ 'scroll',
+ 'se-resize',
+ 'semi-condensed',
+ 'semi-expanded',
+ 'separate',
+ 'serif',
+ 'show',
+ 'silent',
+ 'slow',
+ 'slower',
+ 'small-caps',
+ 'small-caption',
+ 'smaller',
+ 'soft',
+ 'solid',
+ 'spell-out',
+ 'square',
+ 'static',
+ 'status-bar',
+ 'super',
+ 'sw-resize',
+ 'table-caption',
+ 'table-cell',
+ 'table-column',
+ 'table-column-group',
+ 'table-footer-group',
+ 'table-header-group',
+ 'table-row',
+ 'table-row-group',
+ 'text',
+ 'text-bottom',
+ 'text-top',
+ 'thick',
+ 'thin',
+ 'transparent',
+ 'ultra-condensed',
+ 'ultra-expanded',
+ 'underline',
+ 'upper-alpha',
+ 'upper-latin',
+ 'upper-roman',
+ 'uppercase',
+ 'url',
+ 'visible',
+ 'w-resize',
+ 'wait',
+ 'wider',
+ 'x-fast',
+ 'x-high',
+ 'x-large',
+ 'x-loud',
+ 'x-low',
+ 'x-small',
+ 'x-soft',
+ 'xx-large',
+ 'xx-small',
+ 'yes'
+ ),
+ // directives
+ 3 => array(
+ '@at-root',
+ '@charset',
+ '@content',
+ '@debug',
+ '@each',
+ '@else',
+ '@elseif',
+ '@else if',
+ '@extend',
+ '@font-face',
+ '@for',
+ '@function',
+ '@if',
+ '@import',
+ '@include',
+ '@media',
+ '@mixin',
+ '@namespace',
+ '@page',
+ '@return',
+ '@warn',
+ '@while',
+ ),
+ // built-in Sass functions
+ 4 => array(
+ 'rgb',
+ 'rgba',
+ 'mix',
+ 'hsl',
+ 'hsla',
+ 'hue',
+ 'saturation',
+ 'lightness',
+ 'adjust-hue',
+ 'lighten',
+ 'darken',
+ 'saturate',
+ 'desaturate',
+ 'grayscale',
+ 'complement',
+ 'invert',
+ 'alpha',
+ 'opacify',
+ 'transparentize',
+ 'adjust-color',
+ 'scale-color',
+ 'change-color',
+ 'ie-hex-str',
+ 'unquote',
+ 'quote',
+ 'str-length',
+ 'str-insert',
+ 'str-index',
+ 'str-slice',
+ 'to-upper-case',
+ 'to-lower-case',
+ 'percentage',
+ 'round',
+ 'ceil',
+ 'floor',
+ 'abs',
+ 'min',
+ 'max',
+ 'random',
+ 'length',
+ 'nth',
+ 'join',
+ 'append',
+ 'zip',
+ 'index',
+ 'list-separator',
+ 'map-get',
+ 'map-merge',
+ 'map-remove',
+ 'map-keys',
+ 'map-values',
+ 'map-has-key',
+ 'keywords',
+ 'feature-exists',
+ 'variable-exists',
+ 'global-variable-exists',
+ 'function-exists',
+ 'mixin-exists',
+ 'inspect',
+ 'type-of',
+ 'unit',
+ 'unitless',
+ 'comparable',
+ 'call',
+ 'if',
+ 'unique-id',
+ ),
+ // reserved words
+ 5 => array(
+ '!important',
+ '!default',
+ '!optional',
+ 'true',
+ 'false',
+ 'with',
+ 'without',
+ 'null',
+ 'from',
+ 'through',
+ 'to',
+ 'in',
+ 'and',
+ 'or',
+ 'only',
+ 'not',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(',
+ ')',
+ '{',
+ '}',
+ ':',
+ ';',
+ '>',
+ '+',
+ '*',
+ ',',
+ '^',
+ '=',
+ '&',
+ '~',
+ '!',
+ '%',
+ '?',
+ '...',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #993333;',
+ 3 => 'color: #990000;',
+ 4 => 'color: #000000; font-weight: bold;',
+ 5 => 'color: #009900;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #006600; font-style: italic;',
+ 'MULTI' => 'color: #006600; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(),
+ 'BRACKETS' => array(
+ 0 => 'color: #00AA00;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(),
+ 'SYMBOLS' => array(
+ 0 => 'color: #00AA00;'
+ ),
+ 'SCRIPT' => array(),
+ 'REGEXPS' => array(
+ 0 => 'color: #cc00cc;',
+ 1 => 'color: #6666ff;',
+ 2 => 'color: #3333ff;',
+ 3 => 'color: #933;',
+ 4 => 'color: #ff6633;',
+ 5 => 'color: #0066ff;',
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ // Variables
+ 0 => "[$][a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*",
+ // Hexadecimal colors
+ 1 => "\#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})",
+ // CSS Pseudo classes
+ // note: & is needed for &gt; (i.e. > )
+ 2 => "(?<!\\\\):(?!\d)[a-zA-Z0-9\-]+\b(?:\s*(?=[\{\.#a-zA-Z,:+*&](.|\n)|<\|))",
+ // Measurements
+ 3 => "[+\-]?(\d+|(\d*\.\d+))(em|ex|pt|px|cm|in|%)",
+ // Interpolation
+ 4 => "(\#\{.*\})",
+ // Browser prefixed properties
+ 5 => "(\-(moz|ms|o|webkit)\-[a-z\-]*)",
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 2,
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/scala.php b/platform/www/vendor/geshi/geshi/src/geshi/scala.php
new file mode 100644
index 0000000..d9b0bac
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/scala.php
@@ -0,0 +1,136 @@
+<?php
+/*************************************************************************************
+ * scala.php
+ * ----------
+ * Author: Franco Lombardo (franco@francolombardo.net)
+ * Copyright: (c) 2008 Franco Lombardo, Benny Baumann
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/02/08
+ *
+ * Scala language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/02/08 (1.0.7.22)
+ * - First Release
+ *
+ * TODO (updated 2007/04/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Scala',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(2 => "/\\'(?!\w\\'|\\\\)\w+(?=\s)/"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'",'"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[nfrtv\$\"\n\\\\]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{1,2}#i",
+ //Hexadecimal Char Specs (unicode)
+ 3 => "#\\\\u[\da-fA-F]{1,4}#",
+ //Hexadecimal Char Specs (Extended Unicode)
+ 4 => "#\\\\U[\da-fA-F]{1,8}#",
+ ),
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'abstract', 'case', 'catch', 'class', 'def',
+ 'do', 'else', 'extends', 'false', 'final',
+ 'finally', 'for', 'forSome', 'if', 'implicit',
+ 'import', 'match', 'new', 'null', 'object',
+ 'override', 'package', 'private', 'protected', 'requires',
+ 'return', 'sealed', 'super', 'this', 'throw',
+ 'trait', 'try', 'true', 'type', 'val',
+ 'var', 'while', 'with', 'yield'
+ ),
+ 2 => array(
+ 'void', 'double', 'int', 'boolean', 'byte', 'short', 'long', 'char', 'float'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '*', '&', '%', '!', ';', '<', '>', '?',
+ '_', ':', '=', '=>', '<<:',
+ '<%', '>:', '#', '@'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff; font-weight: bold;',
+ 2 => 'color: #9999cc; font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000; font-style: italic;',
+ 2 => 'color: #CC66FF;',
+ 'MULTI' => 'color: #00ff00; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #6666ff; font-weight: bold;',
+ 1 => 'color: #6666ff; font-weight: bold;',
+ 2 => 'color: #5555ff; font-weight: bold;',
+ 3 => 'color: #4444ff; font-weight: bold;',
+ 4 => 'color: #3333ff; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #F78811;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #6666FF;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #F78811;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #000000;',
+ 2 => 'color: #000000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000080;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://scala-lang.org',
+ 2 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/scheme.php b/platform/www/vendor/geshi/geshi/src/geshi/scheme.php
new file mode 100644
index 0000000..e5a289a
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/scheme.php
@@ -0,0 +1,168 @@
+<?php
+/*************************************************************************************
+ * scheme.php
+ * ----------
+ * Author: Jon Raphaelson (jonraphaelson@gmail.com)
+ * Copyright: (c) 2005 Jon Raphaelson, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/30
+ *
+ * Scheme language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/09/22 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2005/09/22)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Scheme',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array('#|' => '|#'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'abs', 'acos', 'and', 'angle', 'append', 'appply', 'approximate',
+ 'asin', 'assoc', 'assq', 'assv', 'atan',
+
+ 'begin', 'boolean?', 'bound-identifier=?',
+
+ 'caar', 'caddr', 'cadr', 'call-with-current-continuation',
+ 'call-with-input-file', 'call-with-output-file', 'call/cc', 'car',
+ 'case', 'catch', 'cdddar', 'cddddr', 'cdr', 'ceiling', 'char->integer',
+ 'char-alphabetic?', 'char-ci<=?', 'char-ci<?', 'char-ci?', 'char-ci>=?',
+ 'char-ci>?', 'char-ci=?', 'char-downcase', 'char-lower-case?',
+ 'char-numeric', 'char-ready', 'char-ready?', 'char-upcase',
+ 'char-upper-case?', 'char-whitespace?', 'char<=?', 'char<?', 'char=?',
+ 'char>=?', 'char>?', 'char?', 'close-input-port', 'close-output-port',
+ 'complex?', 'cond', 'cons', 'construct-identifier', 'cos',
+ 'current-input-port', 'current-output-port',
+
+ 'd', 'define', 'define-syntax', 'delay', 'denominator', 'display', 'do',
+
+ 'e', 'eof-object?', 'eq?', 'equal?', 'eqv?', 'even?', 'exact->inexact',
+ 'exact?', 'exp', 'expt', 'else',
+
+ 'f', 'floor', 'for-each', 'force', 'free-identifer=?',
+
+ 'gcd', 'gen-counter', 'gen-loser', 'generate-identifier',
+
+ 'identifier->symbol', 'identifier', 'if', 'imag-part', 'inexact->exact',
+ 'inexact?', 'input-port?', 'integer->char', 'integer?', 'integrate-system',
+
+ 'l', 'lambda', 'last-pair', 'lcm', 'length', 'let', 'let*', 'letrec',
+ 'list', 'list->string', 'list->vector', 'list-ref', 'list-tail', 'list?',
+ 'load', 'log',
+
+ 'magnitude', 'make-polar', 'make-promise', 'make-rectangular',
+ 'make-string', 'make-vector', 'map', 'map-streams', 'max', 'member',
+ 'memq', 'memv', 'min', 'modulo',
+
+ 'negative', 'newline', 'nil', 'not', 'null?', 'number->string', 'number?',
+ 'numerator',
+
+ 'odd?', 'open-input-file', 'open-output-file', 'or', 'output-port',
+
+ 'pair?', 'peek-char', 'positive?', 'procedure?',
+
+ 'quasiquote', 'quote', 'quotient',
+
+ 'rational', 'rationalize', 'read', 'read-char', 'real-part', 'real?',
+ 'remainder', 'return', 'reverse',
+
+ 's', 'sequence', 'set!', 'set-char!', 'set-cdr!', 'sin', 'sqrt', 'string',
+ 'string->list', 'string->number', 'string->symbol', 'string-append',
+ 'string-ci<=?', 'string-ci<?', 'string-ci=?', 'string-ci>=?',
+ 'string-ci>?', 'string-copy', 'string-fill!', 'string-length',
+ 'string-ref', 'string-set!', 'string<=?', 'string<?', 'string=?',
+ 'string>=?', 'string>?', 'string?', 'substring', 'symbol->string',
+ 'symbol?', 'syntax', 'syntax-rules',
+
+ 't', 'tan', 'template', 'transcript-off', 'transcript-on', 'truncate',
+
+ 'unquote', 'unquote-splicing', 'unwrap-syntax',
+
+ 'vector', 'vector->list', 'vector-fill!', 'vector-length', 'vector-ref',
+ 'vector-set!', 'vector?',
+
+ 'with-input-from-file', 'with-output-to-file', 'write', 'write-char',
+
+ 'zero?'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '!', '%', '^', '&', '/','+','-','*','=','<','>',';','|'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/scilab.php b/platform/www/vendor/geshi/geshi/src/geshi/scilab.php
new file mode 100644
index 0000000..dbe8a39
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/scilab.php
@@ -0,0 +1,293 @@
+<?php
+/*************************************************************************************
+ * scilab.php
+ * --------
+ * Author: Christophe David (geshi@christophedavid.org)
+ * Copyright: (c) 2008 Christophe David (geshi@christophedavid.org)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/08/04
+ *
+ * SciLab language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/08/25 (1.0.8.1)
+ * - Corrected with the help of Benny Baumann (BenBE@geshi.org)
+ * 2008/08/04 (0.0.0.1)
+ * - First beta Release - known problem with ' used to transpose matrices considered as start of strings
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'SciLab',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 2 => "/(?<=\)|\]|\w)'/"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'HARDQUOTE' => array("'", "'"),
+ 'HARDESCAPE' => array(),
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'if', 'else', 'elseif', 'end', 'select', 'case', 'for', 'while', 'break'
+ ),
+ 2 => array(
+ 'STDIN', 'STDOUT', 'STDERR',
+ '%i', '%pi', '%e', '%eps', '%nan', '%inf', '%s', '%t', '%f',
+ 'usual', 'polynomial', 'boolean', 'character', 'function', 'rational', 'state-space',
+ 'sparse', 'boolean sparse', 'list', 'tlist', 'library', 'endfunction'
+ ),
+ 3 => array(
+ '%asn', '%helps', '%k', '%sn', 'abcd', 'abinv', 'abort', 'about', 'About_M2SCI_tools',
+ 'abs', 'acos', 'acosh', 'acoshm', 'acosm', 'AdCommunications', 'add_demo', 'add_edge',
+ 'add_help_chapter', 'add_node', 'add_palette', 'addcolor', 'addf', 'addinter', 'addmenu',
+ 'adj_lists', 'adj2sp', 'aff2ab', 'alufunctions', 'amell', 'analpf', 'analyze', 'and',
+ 'ans', 'apropos', 'arc_graph', 'arc_number', 'arc_properties', 'argn', 'arhnk', 'arl2',
+ 'arma', 'arma2p', 'armac', 'armax', 'armax1', 'arsimul', 'artest', 'articul', 'ascii',
+ 'asciimat', 'asin', 'asinh', 'asinhm', 'asinm', 'assignation', 'atan', 'atanh', 'atanhm',
+ 'atanm', 'augment', 'auread', 'auwrite', 'axes_properties', 'axis_properties', 'backslash',
+ 'balanc', 'balreal', 'bandwr', 'banner','bar', 'barh', 'barhomogenize', 'basename', 'bdiag',
+ 'beep', 'besselh', 'besseli', 'besselj', 'besselk', 'bessely', 'best_match', 'beta','bezout',
+ 'bifish', 'bilin', 'binomial', 'black', 'bloc2exp', 'bloc2ss', 'bode', 'bool2s',
+ 'boucle', 'brackets', 'browsevar', 'bsplin3val', 'bstap', 'buttmag', 'buttondialog',
+ 'bvode', 'bvodeS', 'c_link', 'cainv', 'calendar', 'calerf', 'calfrq', 'call', 'canon', 'casc',
+ 'cat', 'catch', 'ccontrg', 'cd', 'cdfbet', 'cdfbin', 'cdfchi', 'cdfchn', 'cdff', 'cdffnc',
+ 'cdfgam', 'cdfnbn', 'cdfnor', 'cdfpoi', 'cdft', 'ceil', 'cell', 'cell2mat', 'cellstr', 'center',
+ 'cepstrum', 'chain_struct', 'chaintest', 'champ', 'champ_properties', 'champ1', 'char', 'chart',
+ 'chartooem', 'chdir', 'cheb1mag', 'cheb2mag', 'check_graph', 'chepol', 'chfact', 'chol', 'chsolve',
+ 'circuit', 'classmarkov', 'clc', 'clean', 'clear', 'clear_pixmap', 'clearfun', 'clearglobal','clf',
+ 'clipboard', 'close', 'cls2dls', 'cmb_lin', 'cmndred', 'cmoment', 'code2str', 'coeff', 'coff', 'coffg',
+ 'colcomp', 'colcompr', 'colinout', 'colon', 'color', 'color_list', 'colorbar', 'colordef', 'colormap',
+ 'colregul', 'comma', 'comments', 'comp', 'companion', 'comparison', 'Compound_properties', 'con_nodes',
+ 'cond', 'config', 'configure_msvc', 'conj', 'connex', 'console', 'cont_frm', 'cont_mat', 'Contents',
+ 'continue', 'contour', 'contour2d', 'contour2di', 'contourf', 'contr', 'contract_edge', 'contrss',
+ 'convex_hull', 'convol', 'convstr', 'copfac', 'copy', 'corr', 'correl', 'cos', 'cosh', 'coshm',
+ 'cosm', 'cotg', 'coth', 'cothm', 'covar', 'create_palette', 'cshep2d', 'csim', 'cspect', 'Cste',
+ 'ctr_gram', 'cumprod', 'cumsum', 'cycle_basis', 'czt', 'dasrt', 'dassl', 'datafit', 'date', 'datenum',
+ 'datevec', 'dbphi', 'dcf', 'ddp', 'debug', 'dec2hex', 'deff', 'definedfields', 'degree', 'delbpt',
+ 'delete', 'delete_arcs', 'delete_nodes', 'delip', 'delmenu', 'demoplay', 'denom', 'derivat', 'derivative',
+ 'des2ss', 'des2tf', 'det', 'determ', 'detr', 'detrend', 'dft', 'dhinf', 'dhnorm', 'diag', 'diary',
+ 'diff', 'diophant', 'dir', 'dirname', 'disp', 'dispbpt', 'dispfiles', 'dlgamma', 'dnaupd', 'do', 'dot',
+ 'double', 'dragrect', 'draw', 'drawaxis', 'drawlater', 'drawnow', 'driver', 'dsaupd', 'dscr',
+ 'dsearch', 'dsimul', 'dt_ility', 'dtsi', 'edge_number', 'edit', 'edit_curv', 'edit_error',
+ 'edit_graph', 'edit_graph_menus', 'editvar', 'eigenmarkov', 'ell1mag',
+ 'empty', 'emptystr', 'eqfir', 'eqiir', 'equal', 'Equal', 'equil', 'equil1',
+ 'ereduc', 'erf', 'erfc', 'erfcx', 'errbar', 'errcatch', 'errclear', 'error', 'error_table', 'etime',
+ 'eval', 'eval_cshep2d', 'eval3d', 'eval3dp', 'evans', 'evstr', 'excel2sci', 'exec', 'execstr', 'exists',
+ 'exit', 'exp', 'expm', 'external', 'extraction', 'eye', 'fac3d', 'factorial', 'factors', 'faurre', 'fchamp',
+ 'fcontour', 'fcontour2d', 'fec', 'fec_properties', 'feedback', 'feval', 'ffilt', 'fft', 'fft2', 'fftshift',
+ 'fgrayplot', 'figure', 'figure_properties', 'figure_style', 'file', 'fileinfo', 'fileparts', 'filter', 'find',
+ 'find_freq', 'find_path', 'findABCD', 'findAC', 'findBD', 'findBDK', 'findm', 'findmsvccompiler', 'findobj',
+ 'findR', 'findx0BD', 'firstnonsingleton', 'fit_dat', 'fix', 'floor', 'flts', 'foo', 'format',
+ 'formatman', 'fort', 'fourplan', 'fplot2d', 'fplot3d', 'fplot3d1', 'fprintf', 'fprintfMat', 'frep2tf',
+ 'freq', 'freson', 'frexp', 'frfit', 'frmag', 'fscanf', 'fscanfMat', 'fsfirlin', 'fsolve', 'fspecg',
+ 'fstabst', 'fstair', 'ftest', 'ftuneq', 'full', 'fullfile', 'fullrf', 'fullrfk', 'fun2string', 'Funcall',
+ 'funcprot', 'functions', 'funptr', 'fusee', 'G_make', 'g_margin', 'gainplot', 'gamitg',
+ 'gamma', 'gammaln', 'gca', 'gcare', 'gcd', 'gce', 'gcf', 'gda', 'gdf', 'gen_net', 'genfac3d', 'genlib',
+ 'genmarkov', 'geom3d', 'geomean', 'get', 'get_contents_infer', 'get_function_path', 'getcolor', 'getcwd',
+ 'getd', 'getdate', 'getenv', 'getf', 'getfield', 'getfont', 'gethistory', 'getio', 'getlinestyle',
+ 'getlongpathname', 'getmark', 'getmemory', 'getos', 'getpid', 'getscilabkeywords', 'getshell',
+ 'getshortpathname', 'getsymbol', 'getvalue', 'getversion', 'gfare', 'gfrancis', 'girth', 'givens',
+ 'glever', 'glist', 'global', 'GlobalProperty', 'glue', 'gmres', 'gpeche', 'gr_menu', 'graduate', 'grand',
+ 'graph_2_mat', 'graph_center', 'graph_complement', 'graph_diameter', 'graph_power', 'graph_simp', 'graph_sum',
+ 'graph_union', 'graphic', 'Graphics', 'graphics_entities', 'graph-list', 'graycolormap', 'grayplot',
+ 'grayplot_properties', 'graypolarplot', 'great', 'grep', 'group', 'gschur', 'gsort', 'gspec', 'gstacksize',
+ 'gtild', 'h_cl', 'h_inf', 'h_inf_st', 'h_norm', 'h2norm', 'halt', 'hamilton', 'hank', 'hankelsv', 'harmean',
+ 'hat', 'havewindow', 'head_comments', 'help', 'help_skeleton', 'hermit', 'hess', 'hex2dec', 'hilb', 'hinf',
+ 'hist3d', 'histplot', 'horner', 'host', 'hotcolormap', 'householder', 'hrmt', 'hsv2rgb', 'hsvcolormap',
+ 'htrianr', 'hypermat', 'hypermatrices', 'iconvert', 'ieee', 'ifft', 'iir', 'iirgroup', 'iirlp',
+ 'ilib_build', 'ilib_compile', 'ilib_for_link', 'ilib_gen_gateway', 'ilib_gen_loader', 'ilib_gen_Make',
+ 'im_inv', 'imag', 'impl', 'imrep2ss', 'imult', 'ind2sub', 'Infer', 'inistate', 'input', 'insertion', 'int',
+ 'int16', 'int2d', 'int32', 'int3d', 'int8', 'intc', 'intdec', 'integrate', 'interp', 'interp1', 'interp2d',
+ 'interp3d', 'interpln', 'intersci', 'intersect', 'intg', 'intl', 'intppty', 'intsplin', 'inttrap', 'inttype',
+ 'inv', 'inv_coeff', 'invr', 'invsyslin', 'iqr', 'is_connex', 'iscellstr', 'isdef', 'isdir', 'isempty',
+ 'isequal', 'isequalbitwise', 'iserror', 'isglobal', 'isinf', 'isnan', 'isoview', 'isreal', 'javasci',
+ 'jetcolormap', 'jmat', 'justify', 'kalm', 'karmarkar', 'kernel', 'keyboard', 'knapsack', 'kpure', 'krac2',
+ 'kron', 'kroneck', 'label_properties', 'labostat', 'LANGUAGE', 'lasterror', 'lattn', 'lattp', 'lcf', 'lcm',
+ 'lcmdiag', 'ldiv', 'ldivf', 'leastsq', 'left', 'legend', 'legend_properties', 'legendre', 'legends', 'length',
+ 'leqr', 'less', 'lev', 'levin', 'lex_sort', 'lft', 'lgfft', 'lib', 'lin', 'lin2mu', 'lindquist',
+ 'line_graph', 'linear_interpn', 'lines', 'LineSpec', 'linf', 'linfn', 'link', 'linmeq', 'linpro', 'linsolve',
+ 'linspace', 'listfiles', 'listvarinfile', 'lmisolver', 'lmitool', 'load', 'load_graph', 'loadhistory',
+ 'loadmatfile', 'loadplots', 'loadwave', 'locate', 'log', 'log10', 'log1p', 'log2', 'logm', 'logspace',
+ 'lotest', 'lqe', 'lqg', 'lqg_ltr', 'lqg2stan', 'lqr', 'ls', 'lsq', 'lsq_splin', 'lsqrsolve', 'lsslist',
+ 'lstcat', 'lstsize', 'ltitr', 'lu', 'ludel', 'lufact', 'luget', 'lusolve', 'lyap', 'm_circle', 'm2scideclare',
+ 'macglov', 'macr2lst', 'macr2tree', 'macro', 'macrovar', 'mad', 'make_graph', 'make_index', 'makecell', 'man',
+ 'manedit', 'mapsound', 'markp2ss', 'mat_2_graph', 'matfile2sci', 'Matlab-Scilab_character_strings', 'Matplot',
+ 'Matplot_properties', 'Matplot1', 'matrices', 'matrix', 'max', 'max_cap_path', 'max_clique', 'max_flow',
+ 'maxi', 'mcisendstring', 'mclearerr', 'mclose', 'mdelete', 'mean', 'meanf', 'median', 'menus', 'meof',
+ 'merror', 'mese', 'mesh', 'mesh2d', 'meshgrid', 'mfft', 'mfile2sci', 'mfprintf', 'mfscanf', 'mget', 'mgeti',
+ 'mgetl', 'mgetstr', 'milk_drop', 'min', 'min_lcost_cflow', 'min_lcost_flow1', 'min_lcost_flow2',
+ 'min_qcost_flow', 'min_weight_tree', 'mine', 'mini', 'minreal', 'minss', 'minus', 'mkdir', 'mlist', 'mode',
+ 'modulo', 'moment', 'mopen', 'move', 'mprintf', 'mps2linpro', 'mput', 'mputl', 'mputstr', 'mrfit', 'mscanf',
+ 'msd', 'mseek', 'msprintf', 'msscanf', 'mstr2sci', 'mtell', 'mtlb_0', 'mtlb_a', 'mtlb_all', 'mtlb_any',
+ 'mtlb_axis', 'mtlb_beta', 'mtlb_box', 'mtlb_close', 'mtlb_colordef', 'mtlb_conv', 'mtlb_cumprod', 'mtlb_cumsum',
+ 'mtlb_dec2hex', 'mtlb_delete', 'mtlb_diag', 'mtlb_diff', 'mtlb_dir', 'mtlb_double', 'mtlb_e', 'mtlb_echo',
+ 'mtlb_eig', 'mtlb_eval', 'mtlb_exist', 'mtlb_eye', 'mtlb_false', 'mtlb_fft', 'mtlb_fftshift', 'mtlb_find',
+ 'mtlb_findstr', 'mtlb_fliplr', 'mtlb_fopen', 'mtlb_format', 'mtlb_fprintf', 'mtlb_fread', 'mtlb_fscanf',
+ 'mtlb_full', 'mtlb_fwrite', 'mtlb_grid', 'mtlb_hold', 'mtlb_i', 'mtlb_ifft', 'mtlb_imp', 'mtlb_int16',
+ 'mtlb_int32', 'mtlb_int8', 'mtlb_is', 'mtlb_isa', 'mtlb_isfield', 'mtlb_isletter', 'mtlb_isspace', 'mtlb_l',
+ 'mtlb_legendre', 'mtlb_linspace', 'mtlb_load', 'mtlb_logic', 'mtlb_logical', 'mtlb_lower', 'mtlb_max',
+ 'mtlb_min', 'mtlb_mode', 'mtlb_more', 'mtlb_num2str', 'mtlb_ones', 'mtlb_plot', 'mtlb_prod', 'mtlb_rand',
+ 'mtlb_randn', 'mtlb_rcond', 'mtlb_realmax', 'mtlb_realmin', 'mtlb_repmat', 'mtlb_s', 'mtlb_save',
+ 'mtlb_setstr', 'mtlb_size', 'mtlb_sort', 'mtlb_sparse', 'mtlb_strcmp', 'mtlb_strcmpi', 'mtlb_strfind',
+ 'mtlb_strrep', 'mtlb_sum', 'mtlb_t', 'mtlb_toeplitz', 'mtlb_tril', 'mtlb_triu', 'mtlb_true', 'mtlb_uint16',
+ 'mtlb_uint32', 'mtlb_uint8', 'mtlb_upper', 'mtlb_zeros', 'mu2lin', 'mucomp', 'mulf', 'mvvacov', 'name2rgb',
+ 'names', 'nancumsum', 'nand2mean', 'nanmax', 'nanmean', 'nanmeanf', 'nanmedian', 'nanmin', 'nanstdev',
+ 'nansum', 'narsimul', 'NDcost', 'ndgrid', 'ndims', 'nearfloat', 'nehari', 'neighbors', 'netclose', 'netwindow',
+ 'netwindows', 'new', 'newaxes', 'newest', 'newfun', 'nextpow2', 'nf3d', 'nfreq', 'nlev', 'nnz', 'node_number',
+ 'nodes_2_path', 'nodes_degrees', 'noisegen', 'norm', 'not', 'null', 'number_properties', 'numdiff', 'numer',
+ 'nyquist', 'object_editor', 'obs_gram', 'obscont', 'obscont1', 'observer', 'obsv_mat', 'obsvss', 'ode',
+ 'ode_discrete', 'ode_optional_output', 'ode_root', 'odedc', 'odeoptions', 'oemtochar', 'old_style',
+ 'oldbesseli', 'oldbesselj', 'oldbesselk', 'oldbessely', 'oldload', 'oldplot', 'oldsave', 'ones',
+ 'Operation', 'optim', 'or', 'orth', 'overloading', 'p_margin', 'param3d', 'param3d_properties',
+ 'param3d1', 'paramfplot2d', 'parents', 'parrot', 'part', 'path_2_nodes', 'pathconvert', 'pause', 'pbig',
+ 'pca', 'pcg', 'pdiv', 'pen2ea', 'pencan', 'penlaur', 'percent', 'perctl', 'perfect_match', 'perl',
+ 'perms', 'permute', 'pertrans', 'pfss', 'phasemag', 'phc', 'pie', 'pinv', 'pipe_network', 'playsnd', 'plot',
+ 'plot_graph', 'plot2d', 'plot2d_old_version', 'plot2d1', 'plot2d2', 'plot2d3', 'plot2d4', 'plot3d',
+ 'plot3d_old_version', 'plot3d1', 'plot3d2', 'plot3d3', 'plotframe', 'plotprofile', 'plus', 'plzr',
+ 'pmodulo', 'pol2des', 'pol2str', 'pol2tex', 'polar', 'polarplot', 'polfact', 'poly', 'polyline_properties',
+ 'portr3d', 'portrait', 'power', 'ppol', 'prbs_a', 'predecessors', 'predef', 'print', 'printf',
+ 'printf_conversion', 'printing', 'printsetupbox', 'prod', 'profile', 'progressionbar', 'proj', 'projsl',
+ 'projspec', 'psmall', 'pspect', 'pvm', 'pvm_addhosts', 'pvm_barrier', 'pvm_bcast', 'pvm_bufinfo', 'pvm_config',
+ 'pvm_delhosts', 'pvm_error', 'pvm_exit', 'pvm_f772sci', 'pvm_get_timer', 'pvm_getinst', 'pvm_gettid',
+ 'pvm_gsize', 'pvm_halt', 'pvm_joingroup', 'pvm_kill', 'pvm_lvgroup', 'pvm_mytid', 'pvm_parent', 'pvm_probe',
+ 'pvm_recv', 'pvm_reduce', 'pvm_sci2f77', 'pvm_send', 'pvm_set_timer', 'pvm_spawn', 'pvm_spawn_independent',
+ 'pvm_start', 'pvm_tasks', 'pvm_tidtohost', 'pvmd3', 'pwd', 'qassign', 'qld', 'qmr', 'qr', 'quapro', 'quart',
+ 'quaskro', 'quit', 'quote', 'rand', 'randpencil', 'range', 'rank', 'rankqr', 'rat', 'rcond',
+ 'rdivf', 'read', 'read4b', 'readb', 'readc_', 'readmps', 'readxls', 'real', 'realtime', 'realtimeinit',
+ 'rectangle_properties', 'recur', 'reglin', 'regress', 'remez', 'remezb', 'repfreq', 'replot', 'resethistory',
+ 'residu', 'resume', 'return', 'rgb2name', 'ric_desc', 'ricc', 'riccati', 'rlist', 'rmdir', 'roots', 'rotate',
+ 'round', 'routh_t', 'rowcomp', 'rowcompr', 'rowinout', 'rowregul', 'rowshuff', 'rpem', 'rref', 'rtitr',
+ 'rubberbox', 'salesman', 'sample', 'samplef', 'samwr', 'save', 'save_format', 'save_graph', 'savehistory',
+ 'savematfile', 'savewave', 'sca', 'scaling', 'scanf', 'scanf_conversion', 'scf', 'schur', 'sci_files',
+ 'sci2exp', 'sci2for', 'sci2map', 'sciargs', 'SciComplex', 'SciComplexArray', 'SciDouble', 'SciDoubleArray',
+ 'ScilabEval', 'scilink', 'scipad', 'SciString', 'SciStringArray', 'sd2sci', 'sda', 'sdf',
+ 'secto3d', 'segs_properties', 'semi', 'semicolon', 'semidef', 'sensi', 'set', 'set_posfig_dim',
+ 'setbpt', 'setdiff', 'setenv', 'seteventhandler', 'setfield', 'sethomedirectory', 'setlanguage', 'setmenu',
+ 'sfact', 'Sfgrayplot', 'Sgrayplot', 'sgrid', 'shortest_path', 'show_arcs', 'show_graph', 'show_nodes',
+ 'show_pixmap', 'showprofile', 'sident', 'sign', 'Signal', 'signm', 'simp', 'simp_mode', 'sin', 'sinc',
+ 'sincd', 'sinh', 'sinhm', 'sinm', 'size', 'slash', 'sleep', 'sm2des', 'sm2ss', 'smooth', 'solve',
+ 'sorder', 'sort', 'sound', 'soundsec', 'sp2adj', 'spaninter', 'spanplus', 'spantwo', 'spchol',
+ 'spcompack', 'spec', 'specfact', 'speye', 'spget', 'splin', 'splin2d', 'splin3d', 'split_edge', 'spones',
+ 'sprand', 'sprintf', 'spzeros', 'sqroot', 'sqrt', 'sqrtm', 'square', 'squarewave', 'srfaur', 'srkf', 'ss2des',
+ 'ss2ss', 'ss2tf', 'sscanf', 'sskf', 'ssprint', 'ssrand', 'st_deviation', 'st_ility', 'stabil', 'stacksize',
+ 'star', 'startup', 'stdev', 'stdevf', 'str2code', 'strange', 'strcat', 'strindex', 'string', 'stringbox',
+ 'strings', 'stripblanks', 'strong_con_nodes', 'strong_connex', 'strsplit', 'strsubst', 'struct', 'sub2ind',
+ 'subf', 'subgraph', 'subplot', 'successors', 'sum', 'supernode', 'surf', 'surface_properties', 'sva',
+ 'svd', 'svplot', 'sylm', 'sylv', 'symbols', 'sysconv', 'sysdiag', 'sysfact', 'syslin', 'syssize', 'system',
+ 'systems', 'systmat', 'tabul', 'tan', 'tangent', 'tanh', 'tanhm', 'tanm', 'TCL_CreateSlave', 'TCL_DeleteInterp',
+ 'TCL_EvalFile', 'TCL_EvalStr', 'TCL_ExistInterp', 'TCL_ExistVar', 'TCL_GetVar', 'TCL_GetVersion', 'TCL_SetVar',
+ 'TCL_UnsetVar', 'TCL_UpVar', 'tdinit', 'testmatrix', 'texprint', 'text_properties', 'tf2des', 'tf2ss', 'then',
+ 'thrownan', 'tic', 'tilda', 'time_id', 'timer', 'title', 'titlepage', 'TK_EvalFile', 'TK_EvalStr', 'tk_getdir',
+ 'tk_getfile', 'TK_GetVar', 'tk_savefile', 'TK_SetVar', 'toc', 'toeplitz', 'tohome', 'tokenpos',
+ 'tokens', 'toolbar', 'toprint', 'trace', 'trans', 'trans_closure', 'translatepaths', 'tree2code', 'trfmod',
+ 'trianfml', 'tril', 'trimmean', 'trisolve', 'triu', 'try', 'trzeros', 'twinkle', 'type', 'Type', 'typename',
+ 'typeof', 'ui_observer', 'uicontrol', 'uimenu', 'uint16', 'uint32', 'uint8', 'ulink', 'unglue', 'union',
+ 'unique', 'unix', 'unix_g', 'unix_s', 'unix_w', 'unix_x', 'unobs', 'unsetmenu', 'unzoom', 'user', 'varargin',
+ 'varargout', 'Variable', 'variance', 'variancef', 'varn', 'vectorfind', 'waitbar', 'warning', 'wavread',
+ 'wavwrite', 'wcenter', 'wfir', 'what', 'where', 'whereami', 'whereis', 'who', 'who_user', 'whos',
+ 'wiener', 'wigner', 'winclose', 'window', 'winlist', 'winopen', 'winqueryreg', 'winsid', 'with_atlas',
+ 'with_gtk', 'with_javasci', 'with_pvm', 'with_texmacs', 'with_tk', 'writb', 'write', 'write4b', 'x_choices',
+ 'x_choose', 'x_dialog', 'x_matrix', 'x_mdialog', 'x_message', 'x_message_modeless', 'xarc', 'xarcs', 'xarrows',
+ 'xaxis', 'xbasc', 'xbasimp', 'xbasr', 'xchange', 'xclea', 'xclear', 'xclick', 'xclip', 'xdel', 'xend',
+ 'xfarc', 'xfarcs', 'xfpoly', 'xfpolys', 'xfrect', 'xget', 'xgetech', 'xgetfile', 'xgetmouse', 'xgraduate',
+ 'xgrid', 'xinfo', 'xinit', 'xlfont', 'xload', 'xls_open', 'xls_read', 'xmltohtml', 'xname', 'xnumb', 'xpause',
+ 'xpoly', 'xpolys', 'xrect', 'xrects', 'xrpoly', 'xs2bmp', 'xs2emf', 'xs2eps', 'xs2fig', 'xs2gif', 'xs2ppm',
+ 'xs2ps', 'xsave', 'xsegs', 'xselect', 'xset', 'xsetech', 'xsetm', 'xstring', 'xstringb', 'xstringl', 'xtape',
+ 'xtitle', 'yulewalk', 'zeropen', 'zeros', 'zgrid', 'zoom_rect', 'zpbutt', 'zpch1', 'zpch2', 'zpell'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '<', '>', '=',
+ '!', '@', '~', '&', '|',
+ '+','-', '*', '/', '%',
+ ',', ';', '?', ':', "'"
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => '',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ 'HARD' => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;',
+ 2 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000ff;',
+ 4 => 'color: #009999;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://www.scilab.org/product/dic-mat-sci/M2SCI_doc.htm',
+ 2 => 'http://www.scilab.org/product/dic-mat-sci/M2SCI_doc.htm',
+ 3 => 'http://www.scilab.org/product/dic-mat-sci/M2SCI_doc.htm'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '-&gt;',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ //Variable
+ 0 => '[\\$%@]+[a-zA-Z_][a-zA-Z0-9_]*',
+ //File Descriptor
+ 4 => '&lt;[a-zA-Z_][a-zA-Z0-9_]*&gt;',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/scl.php b/platform/www/vendor/geshi/geshi/src/geshi/scl.php
new file mode 100644
index 0000000..17bad11
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/scl.php
@@ -0,0 +1,148 @@
+<?php
+/*************************************************************************************
+ * <scl.php>
+ * ---------------------------------
+ * Author: Leonhard Hösch (leonhard.hoesch@siemens.com)
+ * Copyright: (c) 2008 by Leonhard Hösch (siemens.de)
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/09/25
+ *
+ * SCL language file for GeSHi.
+ *
+ * A SCL langauge file.
+ *
+ * CHANGES
+ * -------
+ * <date-of-release> (<GeSHi release>)
+ * - First Release
+ *
+ * TODO (updated <date-of-release>)
+ * -------------------------
+ * <things-to-do>
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'SCL',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('(*' => '*)'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array("'"),
+ 'ESCAPE_CHAR' => '$',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'AND','ANY','ARRAY','AT','BEGIN','BLOCK_DB','BLOCK_FB','BLOCK_FC','BLOCK_SDB',
+ 'BLOCK_SFB','BLOCK_SFC','BOOL','BY','BYTE','CASE','CHAR','CONST','CONTINUE','COUNTER',
+ 'DATA_BLOCK','DATE','DATE_AND_TIME','DINT','DIV','DO','DT','DWORD','ELSE','ELSIF',
+ 'EN','END_CASE','END_CONST','END_DATA_BLOCK','END_FOR','END_FUNCTION',
+ 'END_FUNCTION_BLOCK','END_IF','END_LABEL','END_TYPE','END_ORGANIZATION_BLOCK',
+ 'END_REPEAT','END_STRUCT','END_VAR','END_WHILE','ENO','EXIT','FALSE','FOR','FUNCTION',
+ 'FUNCTION_BLOCK','GOTO','IF','INT','LABEL','MOD','NIL','NOT','OF','OK','OR',
+ 'ORGANIZATION_BLOCK','POINTER','PROGRAM','REAL','REPEAT','RETURN','S5TIME','STRING',
+ 'STRUCT','THEN','TIME','TIMER','TIME_OF_DAY','TO','TOD','TRUE','TYPE','VAR',
+ 'VAR_TEMP','UNTIL','VAR_INPUT','VAR_IN_OUT','VAR_OUTPUT','VOID','WHILE','WORD','XOR'
+ ),
+ 2 =>array(
+ 'UBLKMOV','FILL','CREAT_DB','DEL_DB','TEST_DB','COMPRESS','REPL_VAL','CREA_DBL','READ_DBL',
+ 'WRIT_DBL','CREA_DB','RE_TRIGR','STP','WAIT','MP_ALM','CiR','PROTECT','SET_CLK','READ_CLK',
+ 'SNC_RTCB','SET_CLKS','RTM','SET_RTM','CTRL_RTM','READ_RTM','TIME_TCK','RD_DPARM',
+ 'RD_DPARA','WR_PARM','WR_DPARM','PARM_MOD','WR_REC','RD_REC','RD_DPAR','RDREC','WRREC','RALRM',
+ 'SALRM','RCVREC','PRVREC','SET_TINT','CAN_TINT','ACT_TINT','QRY_TINT','SRT_DINT','QRY_DINT',
+ 'CAN_DINT','MSK_FLT','DMSK_FLT','READ_ERR','DIS_IRT','EN_IRT','DIS_AIRT','EN_AIRT','RD_SINFO',
+ 'RDSYSST','WR_USMSG','OB_RT','C_DIAG','DP_TOPOL','UPDAT_PI','UPDAT_PO','SYNC_PI','SYNC_PO',
+ 'SET','RSET','DRUM','GADR_LGC','LGC_GADR','RD_LGADR','GEO_LOG','LOG_GEO','DP_PRAL','DPSYC_FR',
+ 'D_ACT_DP','DPNRM_DG','DPRD_DAT','DPWR_DAT','PN_IN','PN_OUT','PN_DP','WWW','IP_CONF','GETIO',
+ 'SETIO','GETIO_PART','SETIO_PART','GD_SND','GD_RCV','USEND','URCV','BSEND','BRCV','PUT','GET',
+ 'PRINT','START','STOP','RESUME','STATUS','USTATUS','CONTROL','C_CNTRL','X_SEND','X_RCV',
+ 'X_GET','X_PUT','X_ABORT','I_GET','I_PUT','I_ABORT','TCON','TDISCON','TSEND','TRCV','TUSEND',
+ 'TURCV','NOTIFY','NOTIFY_8P','ALARM','ALARM_8P','ALARM_8','AR_SEND','DIS_MSG','EN_MSG',
+ 'ALARM_SQ','ALARM_S','ALARM_SC','ALARM_DQ','LARM_D','READ_SI','DEL_SI','TP','TON','TOF','CTU',
+ 'CTD','CTUD','CONT_C','CONT_S','PULSEGEN','Analog','DIGITAL','COUNT','FREQUENC','PULSE',
+ 'SEND_PTP','RECV_PTP','RES_RECV','SEND_RK','FETCH_RK','SERVE_RK','H_CTRL','state'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '.', '"', '|', ';', ',', '=>', '>=', '<=', ':=', '=', '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #ff6f00;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #009600; font-style: italic;',
+ 'MULTI' => 'color: #009600; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'NUMBERS' => GESHI_NUMBER_INT_BASIC,
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<?php11!!' => '!!11?>'
+ ),
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => false,
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/sdlbasic.php b/platform/www/vendor/geshi/geshi/src/geshi/sdlbasic.php
new file mode 100644
index 0000000..b5fc9fa
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/sdlbasic.php
@@ -0,0 +1,163 @@
+<?php
+/*************************************************************************************
+ * sdlbasic.php
+ * ------------
+ * Author: Roberto Rossi
+ * Copyright: (c) 2005 Roberto Rossi (http://rsoftware.altervista.org)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/08/19
+ *
+ * sdlBasic (http://sdlbasic.sf.net) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2005/08/19 (1.0.0)
+ * - First Release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'sdlBasic',
+ 'COMMENT_SINGLE' => array(1 => "'", 2 => "rem", 3 => "!", 4 => "#"),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'const', 'option', 'explicit', 'qbasic', 'include', 'argc',
+ 'argv', 'command', 'command$', 'run', 'shell', 'os', 'declare',
+ 'sub', 'function', 'return', 'while', 'wend', 'exit', 'end',
+ 'continue', 'if', 'then', 'else', 'elseif',
+ 'select', 'case', 'for', 'each', 'step',
+ 'next', 'to', 'dim', 'shared', 'common', 'lbound', 'bound',
+ 'erase', 'asc', 'chr', 'chr$', 'insert', 'insert$', 'instr', 'lcase',
+ 'lcase$', 'left', 'left$', 'len', 'length', 'ltrim', 'ltrim$', 'mid',
+ 'mid$', 'replace', 'replace$', 'replacesubstr', 'replacesubstr$',
+ 'reverse', 'reverse$', 'right', 'right$', 'rinstr', 'rtrim', 'rtrim$',
+ 'space', 'space$', 'str', 'str$', 'strf', 'strf$', 'string', 'string$',
+ 'tally', 'trim', 'trim$', 'typeof', 'typeof$', 'ucase', 'ucase$', 'val',
+ 'abs', 'acos', 'andbit', 'asin', 'atan', 'bitwiseand', 'bitwiseor',
+ 'bitwisexor', 'cos', 'exp', 'fix', 'floor', 'frac', 'hex', 'hex$', 'int',
+ 'log', 'min', 'max', 'orbit', 'randomize', 'rnd', 'round', 'sgn', 'sin',
+ 'sqr', 'tan', 'xorbit', 'open', 'as', 'file', 'input', 'close', 'output',
+ 'append', 'eof', 'fileexists', 'filecopy', 'filemove', 'filerename',
+ 'freefile', 'kill', 'loc', 'lof', 'readbyte', 'rename', 'seek',
+ 'writebyte', 'chdir', 'dir', 'dir$', 'direxists', 'dirfirst', 'dirnext',
+ 'mkdir', 'rmdir', 'print', 'date', 'date$', 'time', 'time$', 'ticks',
+ 'data', 'read', 'reservebank', 'freebank', 'copybank', 'loadbank',
+ 'savebank', 'setbank', 'sizebank', 'poke', 'doke', 'loke', 'peek', 'deek',
+ 'leek', 'memcopy', 'setdisplay', 'setcaption', 'caption', 'displaywidth',
+ 'displayheight', 'displaybpp', 'screen', 'directscreen', 'screenopen',
+ 'screenclose', 'screenclone', 'screencopy', 'screenfade', 'screenfadein',
+ 'screencrossfade', 'screenalpha', 'screenlock', 'screenunlock',
+ 'screenrect', 'xscreenrect', 'yscreenrect', 'wscreenrect', 'hscreenrect',
+ 'flagscreenrect', 'screenwidth', 'screenheight', 'offset', 'xoffset',
+ 'yoffset', 'cls', 'screenswap', 'autoback', 'setautoback',
+ 'dualplayfield', 'waitvbl', 'fps', 'rgb', 'enablepalette', 'color',
+ 'palette', 'colorcycling', 'ink', 'point', 'dot', 'plot', 'line', 'box',
+ 'bar', 'circle', 'fillcircle', 'ellipse', 'fillellipse', 'paint',
+ 'loadimage', 'saveimage', 'loadsound', 'savesound', 'loadmusic',
+ 'hotspot', 'setcolorkey', 'imageexists', 'imagewidth', 'imageheight',
+ 'deleteimage', 'copyimage', 'setalpha', 'zoomimage', 'rotateimage',
+ 'rotozoomimage', 'blt', 'pastebob', 'pasteicon', 'grab', 'spriteclip',
+ 'sprite', 'deletesprite', 'xsprite', 'ysprite', 'spritewidth',
+ 'spriteheight', 'frsprite', 'livesprite', 'spritehit', 'autoupdatesprite',
+ 'updatesprite', 'setbob', 'bob', 'deletebob', 'xbob', 'ybob', 'bobwidth',
+ 'bobheight', 'frbob', 'livebob', 'bobhit', 'autoupdatebob', 'updatebob',
+ 'text', 'setfont', 'textrender', 'pen', 'paper', 'prints', 'locate',
+ 'atx', 'aty', 'curson', 'cursoff', 'inputs', 'zoneinputs',
+ 'isenabledsound', 'soundexists', 'deletesound', 'copysound',
+ 'musicexists', 'playsound', 'volumesound', 'stopsound', 'pausesound',
+ 'resumesound', 'vumetersound', 'positionsound', 'soundchannels',
+ 'playmusic', 'positionmusic', 'stopmusic', 'fademusic', 'pausemusic',
+ 'resumemusic', 'rewindmusic', 'volumemusic', 'speedmusic', 'numdrivescd',
+ 'namecd', 'getfreecd', 'opencd', 'indrivecd', 'trackscd', 'curtrackcd',
+ 'curframecd', 'playcd', 'playtrackscd',
+ 'pausecd', 'resumecd', 'stopcd', 'ejectcd', 'closecd', 'tracktypecd',
+ 'tracklengthcd', 'trackoffsetcd', 'key', 'inkey', 'waitkey', 'xmouse',
+ 'ymouse', 'xmousescreen', 'ymousescreen', 'bmouse', 'changemouse',
+ 'locatemouse', 'mouseshow', 'mousehide', 'mousezone', 'numjoysticks',
+ 'namejoystick', 'numaxesjoystick', 'numballsjoystick', 'numhatsjoystick',
+ 'numbuttonsjoystick', 'getaxisjoystick', 'gethatjoystick',
+ 'getbuttonjoystick', 'xgetballjoystick', 'ygetballjoystick', 'joy',
+ 'bjoy', 'wait', 'timer', 'isenabledsock', 'getfreesock', 'opensock',
+ 'acceptsock', 'isserverready', 'connectsock', 'connectionreadysock',
+ 'isclientready', 'losesock', 'peeksock', 'readsock', 'readbytesock',
+ 'readlinesock', 'writesock', 'writebytesock', 'writelinesock',
+ 'getremoteip', 'getremoteport', 'getlocalip'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080;',
+ 2 => 'color: #808080;',
+ 3 => 'color: #808080;',
+ 4 => 'color: #808080;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/smalltalk.php b/platform/www/vendor/geshi/geshi/src/geshi/smalltalk.php
new file mode 100644
index 0000000..faa0798
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/smalltalk.php
@@ -0,0 +1,152 @@
+<?php
+/*************************************************************************************
+ * smalltalk.php
+ * --------
+ * Author: Bananeweizen (Bananeweizen@gmx.de)
+ * Copyright: (c) 2005 Bananeweizen (www.bananeweizen.de)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/03/27
+ *
+ * Smalltalk language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2006-05-24 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * -------------------------
+ * * recognize nested array symbols correctly
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Smalltalk',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('"' => '"'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'"),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'self','super','true','false','nil'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '=' , ':=', '(', ')', '#'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #7f007f;'
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #007f00; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => ''
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #7f0000;'
+ ),
+ 'METHODS' => array(
+ 0 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066; font-weight:bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000ff;',
+ 1 => 'color: #7f0000;',
+ 2 => 'color: #7f0000;',
+ 3 => 'color: #00007f;',
+ 5 => 'color: #00007f;',
+ 6 => 'color: #00007f;'
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => array(
+ GESHI_SEARCH => '([^a-zA-Z0-9_#<])([A-Z]+[a-zA-Z0-9_]*)(?!>)', //class names
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 1 => array(
+ GESHI_SEARCH => '(#+)([a-zA-Z0-9_]+)', //symbols
+ GESHI_REPLACE => '\\1\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 2 => array(
+ GESHI_SEARCH => '(#\s*\([^)]*\))', //array symbols
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 3 => array(
+ GESHI_SEARCH => '<PIPE>([a-zA-Z0-9_\s]+)<PIPE>', //temporary variables
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '|',
+ GESHI_AFTER => '|'
+ ),
+ 5 => array(
+ GESHI_SEARCH => '([:(,=[.*\/+-]\s*(?!\d+\/))([a-zA-Z0-9_]+)', //message parameters, message receivers
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 's',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 6 => array(
+ GESHI_SEARCH => '([a-zA-Z0-9_]+)(\s*:=)', //assignment targets
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '\\2'
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/smarty.php b/platform/www/vendor/geshi/geshi/src/geshi/smarty.php
new file mode 100644
index 0000000..62b37f2
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/smarty.php
@@ -0,0 +1,190 @@
+<?php
+/*************************************************************************************
+ * smarty.php
+ * ----------
+ * Author: Alan Juden (alan@judenware.org)
+ * Copyright: (c) 2004 Alan Juden, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/07/10
+ *
+ * Smarty template language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.0)
+ * - Initial Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Smarty',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('{*' => '*}'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ '$smarty', 'now', 'const', 'capture', 'config', 'section', 'foreach', 'template', 'version', 'ldelim', 'rdelim',
+ 'foreachelse', 'include', 'include_php', 'insert', 'if', 'elseif', 'else', 'php',
+ 'sectionelse', 'is_cached',
+ ),
+ 2 => array(
+ 'capitalize', 'count_characters', 'cat', 'count_paragraphs', 'count_sentences', 'count_words', 'date_format',
+ 'default', 'escape', 'indent', 'lower', 'nl2br', 'regex_replace', 'replace', 'spacify', 'string_format',
+ 'strip', 'strip_tags', 'truncate', 'upper', 'wordwrap',
+ ),
+ 3 => array(
+ 'counter', 'cycle', 'debug', 'eval', 'html_checkboxes', 'html_image', 'html_options',
+ 'html_radios', 'html_select_date', 'html_select_time', 'html_table', 'math', 'mailto', 'popup_init',
+ 'popup', 'textformat'
+ ),
+ 4 => array(
+ '$template_dir', '$compile_dir', '$config_dir', '$plugins_dir', '$debugging', '$debug_tpl',
+ '$debugging_ctrl', '$autoload_filters', '$compile_check', '$force_compile', '$caching', '$cache_dir',
+ '$cache_lifetime', '$cache_handler_func', '$cache_modified_check', '$config_overwrite',
+ '$config_booleanize', '$config_read_hidden', '$config_fix_newlines', '$default_template_handler_func',
+ '$php_handling', '$security', '$secure_dir', '$security_settings', '$trusted_dir', '$left_delimiter',
+ '$right_delimiter', '$compiler_class', '$request_vars_order', '$request_use_auto_globals',
+ '$error_reporting', '$compile_id', '$use_sub_dirs', '$default_modifiers', '$default_resource_type'
+ ),
+ 5 => array(
+ 'append', 'append_by_ref', 'assign', 'assign_by_ref', 'clear_all_assign', 'clear_all_cache',
+ 'clear_assign', 'clear_cache', 'clear_compiled_tpl', 'clear_config', 'config_load', 'display',
+ 'fetch', 'get_config_vars', 'get_registered_object', 'get_template_vars',
+ 'load_filter', 'register_block', 'register_compiler_function', 'register_function',
+ 'register_modifier', 'register_object', 'register_outputfilter', 'register_postfilter',
+ 'register_prefilter', 'register_resource', 'trigger_error', 'template_exists', 'unregister_block',
+ 'unregister_compiler_function', 'unregister_function', 'unregister_modifier', 'unregister_object',
+ 'unregister_outputfilter', 'unregister_postfilter', 'unregister_prefilter', 'unregister_resource'
+ ),
+ 6 => array(
+ 'name', 'file', 'scope', 'global', 'key', 'once', 'script',
+ 'loop', 'start', 'step', 'max', 'show', 'values', 'value', 'from', 'item'
+ ),
+ 7 => array(
+ 'eq', 'neq', 'ne', 'lte', 'gte', 'ge', 'le', 'not', 'mod'
+ ),
+ 8 => array(
+ // some common php functions
+ 'isset', 'is_array', 'empty', 'count', 'sizeof'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '/', '=', '==', '!=', '>', '<', '>=', '<=', '!', '%'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ 8 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0600FF;', //Functions
+ 2 => 'color: #008000;', //Modifiers
+ 3 => 'color: #0600FF;', //Custom Functions
+ 4 => 'color: #804040;', //Variables
+ 5 => 'color: #008000;', //Methods
+ 6 => 'color: #6A0A0A;', //Attributes
+ 7 => 'color: #D36900;', //Text-based symbols
+ 8 => 'color: #0600FF;' //php functions
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #008080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #D36900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #D36900;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #009000;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #00aaff;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://smarty.php.net/{FNAMEL}',
+ 2 => 'http://smarty.php.net/{FNAMEL}',
+ 3 => 'http://smarty.php.net/{FNAMEL}',
+ 4 => 'http://smarty.php.net/{FNAMEL}',
+ 5 => 'http://smarty.php.net/{FNAMEL}',
+ 6 => '',
+ 7 => 'http://smarty.php.net/{FNAMEL}',
+ 8 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ // variables
+ 0 => '\$[a-zA-Z][a-zA-Z0-9_]*'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '{' => '}'
+ ),
+ 1 => array(
+ '<!--' => '-->',
+ ),
+ 2 => array(
+ '<' => '>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => false,
+ 2 => false
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#;>|^])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%\\-&])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/spark.php b/platform/www/vendor/geshi/geshi/src/geshi/spark.php
new file mode 100644
index 0000000..0d722e7
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/spark.php
@@ -0,0 +1,127 @@
+<?php
+/*************************************************************************************
+ * ada.php
+ * -------
+ * Author: Phil Thornley (tux@inmail.cz)
+ * Copyright: (c) 2004 Phil Thornley (http://www.sparksure.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/08/22
+ *
+ * SPARK language file for GeSHi.
+ *
+ * Created by modifying Ada file version 1.0.2
+ * Words are from SciTe configuration file
+ *
+ * CHANGES
+ * -------
+ * 2010/08/28 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2010/08/22)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'SPARK',
+ 'COMMENT_SINGLE' => array(1 => '--', 2 => '--#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'begin', 'declare', 'do', 'else', 'elsif', 'exception', 'for', 'if',
+ 'is', 'loop', 'while', 'then', 'end', 'select', 'case', 'until',
+ 'goto', 'return'
+ ),
+ 2 => array(
+ 'abs', 'and', 'at', 'mod', 'not', 'or', 'rem', 'xor'
+ ),
+ 3 => array(
+ 'abort', 'abstract', 'accept', 'access', 'aliased', 'all', 'array',
+ 'body', 'constant', 'delay', 'delta', 'digits', 'entry', 'exit',
+ 'function', 'generic', 'in', 'interface', 'limited', 'new', 'null',
+ 'of', 'others', 'out', 'overriding', 'package', 'pragma', 'private',
+ 'procedure', 'protected', 'raise', 'range', 'record', 'renames',
+ 'requeue', 'reverse', 'separate', 'subtype', 'synchronized',
+ 'tagged', 'task', 'terminate', 'type', 'use', 'when', 'with'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00007f;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #46aa03; font-weight:bold;',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ 2 => 'color: #adadad; font-style: italic; font-weight: bold;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/sparql.php b/platform/www/vendor/geshi/geshi/src/geshi/sparql.php
new file mode 100644
index 0000000..d5847f2
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/sparql.php
@@ -0,0 +1,153 @@
+<?php
+/*************************************************************************************
+ * sparql.php
+ * -------
+ * Author: Karima Rafes (karima.rafes@bordercloud.com)
+ * Copyright: (c) 2011 Bourdercloud.com
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/11/05
+ *
+ * SPARQL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2011/11/05 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'SPARQL',
+ 'COMMENT_SINGLE' => array('#'),
+ 'COMMENT_MULTI' => array('/*' => '*/' ),
+ 'COMMENT_REGEXP' => array(
+ //IRI (it's not a comment ;)
+ 1 => "/<[^> ]*>/i"
+ ),
+ 'CASE_KEYWORDS' => 1,
+ 'QUOTEMARKS' => array("'", '"', '`'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'BASE','PREFIX','SELECT','DISTINCT','REDUCED','CONSTRUCT','DESCRIBE','ASK','FROM',
+ 'NAMED','WHERE','ORDER','BY','ASC','DESC','LIMIT','OFFSET','OPTIONAL','GRAPH',
+ 'UNION','FILTER','STR','LANG','LANGMATCHES','DATATYPE','BOUND','SAMETERM',
+ 'ISIRI','ISURI','ISBLANK',
+ 'ISLITERAL','REGEX','SUBSTR','TRUE',
+ 'FALSE','LOAD','CLEAR',
+ 'DROP','ADD','MOVE','COPY',
+ 'CREATE','DELETE','INSERT',
+ 'USING','SILENT','DEFAULT','ALL',
+ 'DATA','WITH','INTO','TO',
+ 'AS','GROUP','HAVING','UNDEF',
+ 'BINDINGS','SERVICE','BIND','MINUS_KEYWORD',
+ 'IRI','URI', 'BNODE',
+ 'RAND','ABS','CEIL','FLOOR','ROUND',
+ 'CONCAT','STRLEN',
+ 'UCASE','LCASE','ENCODE_FOR_URI',
+ 'CONTAINS','STRSTARTS',
+ 'STRENDS','STRBEFORE',
+ 'STRAFTER','REPLACE',
+ 'YEAR','MONTH',
+ 'DAY','HOURS',
+ 'MINUTES','SECONDS',
+ 'TIMEZONE','TZ',
+ 'NOW','MD5',
+ 'SHA1','SHA224',
+ 'SHA256','SHA384',
+ 'SHA512','COALESCE',
+ 'IF','STRLANG','STRDT',
+ 'ISNUMERIC','COUNT',
+ 'SUM','MIN',
+ 'MAX','AVG','SAMPLE',
+ 'GROUP_CONCAT ','NOT',
+ 'IN','EXISTS','SEPARATOR'
+ )
+ ),
+ 'REGEXPS' => array(
+ //Variables without braces
+ 1 => "\\?[a-zA-Z_][a-zA-Z0-9_]*",
+ //prefix
+ 2 => "[a-zA-Z_.\\-0-9]*:",
+ //tag lang
+ 3 => "@[^ .)}]*",
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '{', '}' , '.', ';'
+ ),
+ 1 => array(
+ '^^',
+ '<=','>=','!=','=','<','>','|',
+ '&&','||',
+ '(',')','[', ']',
+ '+','-','*','!','/'
+ ),
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #993333; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #808080; font-style: italic;',
+ 1 => 'color: #000078;',
+ //2 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF63C3;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #0000FF;',
+ 1 => 'color: #FF8000; font-weight: bold;'
+ ),
+ 'SCRIPT' => array(),
+ 'REGEXPS' => array(
+ 1 => 'color: #007800;',
+ 2 => 'color: #780078;',
+ 3 => 'color: #005078;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/sql.php b/platform/www/vendor/geshi/geshi/src/geshi/sql.php
new file mode 100644
index 0000000..73e2109
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/sql.php
@@ -0,0 +1,168 @@
+<?php
+/*************************************************************************************
+ * sql.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Contributors:
+ * - Jürgen Thomas (Juergen.Thomas@vs-polis.de)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/04
+ *
+ * SQL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/07/19 (1.0.8.9)
+ * - Added many more keywords
+ * 2008/05/23 (1.0.7.22)
+ * - Added additional symbols for highlighting
+ * 2004/11/27 (1.0.3)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.2)
+ * - Added "`" string delimiter
+ * - Added "#" single comment starter
+ * 2004/08/05 (1.0.1)
+ * - Added support for symbols
+ * - Added many more keywords (mostly MYSQL keywords)
+ * 2004/07/14 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Add all keywords
+ * * Split this to several sql files - mysql-sql, ansi-sql etc
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'SQL',
+ 'COMMENT_SINGLE' => array(1 =>'--'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => 1,
+ 'QUOTEMARKS' => array("'", '"', '`'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC', 'AUTO_INCREMENT',
+ 'BEFORE', 'BEGIN', 'BETWEEN', 'BIGINT', 'BINARY', 'BLOB', 'BOOLEAN', 'BOTH', 'BY',
+ 'CALL', 'CASE', 'CAST', 'CEIL', 'CEILING', 'CHANGE', 'CHAR', 'CHAR_LENGTH', 'CHARACTER',
+ 'CHARACTER_LENGTH', 'CHECK', 'CLOB', 'COALESCE', 'COLLATE', 'COLUMN', 'COLUMNS',
+ 'CONNECT', 'CONSTRAINT', 'CONVERT', 'COUNT', 'CREATE', 'CROSS', 'CURRENT',
+ 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER',
+ 'DATA', 'DATABASE', 'DATABASES', 'DATE', 'DAY', 'DEC', 'DECIMAL', 'DECLARE',
+ 'DEFAULT', 'DEFERRABLE', 'DEFERRED', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DISTINCT', 'DOUBLE',
+ 'DOMAIN', 'DROP',
+ 'ELSE', 'ELSEIF', 'ENCLOSED', 'END', 'ESCAPED', 'EXCEPT', 'EXEC', 'EXECUTE', 'EXISTS',
+ 'EXP', 'EXPLAIN', 'EXTRACT',
+ 'FALSE', 'FIELD', 'FIELDS', 'FILTER', 'FIRST', 'FLOAT', 'FLOOR', 'FLUSH', 'FOR',
+ 'FOREIGN', 'FROM', 'FULL', 'FUNCTION',
+ 'GET', 'GROUP', 'GROUPING', 'GO', 'GOTO', 'GRANT', 'GRANTED',
+ 'HAVING', 'HOUR',
+ 'IDENTIFIED', 'IDENTITY', 'IF', 'IGNORE', 'IMMEDIATE', 'IN', 'INCREMENT', 'INDEX', 'INFILE', 'INITIALLY', 'INNER',
+ 'INOUT', 'INPUT', 'INSERT', 'INT', 'INTEGER', 'INTERSECT', 'INTERSECTION', 'INTERVAL',
+ 'INTO', 'IS',
+ 'JOIN',
+ 'KEY', 'KEYS', 'KILL',
+ 'LANGUAGE', 'LARGE', 'LAST', 'LEADING', 'LEFT', 'LENGTH', 'LIKE', 'LIMIT', 'LINES', 'LOAD',
+ 'LOCAL', 'LOCK', 'LOW_PRIORITY', 'LOWER',
+ 'MATCH', 'MAX', 'MERGE', 'MIN', 'MINUTE', 'MOD', 'MODIFIES', 'MODIFY', 'MONTH',
+ 'NATIONAL', 'NATURAL', 'NCHAR', 'NEW', 'NEXT', 'NEXTVAL', 'NONE', 'NOT',
+ 'NULL', 'NULLABLE', 'NULLIF', 'NULLS', 'NUMBER', 'NUMERIC',
+ 'OF', 'OLD', 'ON', 'ONLY', 'OPEN', 'OPTIMIZE', 'OPTION',
+ 'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'OVER',
+ 'POSITION', 'POWER', 'PRECISION', 'PREPARE', 'PRIMARY', 'PROCEDURAL', 'PROCEDURE',
+ 'READ', 'REAL', 'REF', 'REFERENCES', 'REFERENCING', 'REGEXP', 'RENAME', 'REPLACE',
+ 'RESULT', 'RETURN', 'RETURNS', 'REVOKE', 'RIGHT', 'RLIKE', 'ROLLBACK', 'ROW',
+ 'ROW_NUMBER', 'ROWS', 'RESTRICT', 'ROLE', 'ROUTINE', 'ROW_COUNT',
+ 'SAVEPOINT', 'SEARCH', 'SECOND', 'SECTION', 'SELECT', 'SELF', 'SEQUENCE',
+ 'SESSION', 'SET', 'SETVAL', 'SHOW', 'SIMILAR', 'SIZE', 'SMALLINT', 'SOME',
+ 'SONAME', 'SOURCE', 'SPACE', 'SQL', 'SQRT', 'START', 'STATUS',
+ 'STRAIGHT_JOIN', 'STRUCTURE', 'STYLE', 'SUBSTRING', 'SUM',
+ 'TABLE', 'TABLE_NAME', 'TABLES', 'TERMINATED', 'TEMPORARY', 'THEN', 'TIME',
+ 'TIMESTAMP', 'TO', 'TRAILING', 'TRANSACTION', 'TRIGGER', 'TRIM', 'TRUE', 'TRUNCATE',
+ 'TRUSTED', 'TYPE',
+ 'UNDER', 'UNION', 'UNIQUE', 'UNKNOWN', 'UNLOCK', 'UNSIGNED',
+ 'UPDATE', 'UPPER', 'USE', 'USER', 'USING',
+ 'VALUE', 'VALUES', 'VARCHAR', 'VARIABLES', 'VARYING', 'VIEW',
+ 'WHEN', 'WHERE', 'WITH', 'WITHIN', 'WITHOUT', 'WORK', 'WRITE',
+ 'XOR',
+ 'YEAR',
+ 'ZEROFILL'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '=', '<', '>', '|', ',', '.', '+', '-', '*', '/'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #993333; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ //2 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array( //'
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\.\|\#|^&])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/sshconfig.php b/platform/www/vendor/geshi/geshi/src/geshi/sshconfig.php
new file mode 100644
index 0000000..d38cc46
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/sshconfig.php
@@ -0,0 +1,165 @@
+<?php
+/*************************************************************************************
+ * sshconfig.php
+ * --------
+ * Author: Kevin Ernst (kevin.ernst -at- cchmc.org)
+ * Copyright: (c) 2017 Kevin Ernst
+ * Release Version: 1.0.9.1
+ * Date Started: 2017/12/01
+ *
+ * OpenSSH config file (~/.ssh/config) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2017/12/02 (1.0.0)
+ * - First release; couldn't figure out how to separately highlight negated
+ * hostnames/wildcards, but it's good enough for a basic ~/.ssh/config
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'sshconfig',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(0 => '/^\s*#.*?$/m'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 0 => array(
+ 'Host',
+ ),
+ 1 => array(
+ "Hostname", "Match", "AddKeysToAgent", "AddressFamily", "BatchMode",
+ "BindAddress", "CanonicalDomains", "CanonicalizeFallbackLocal",
+ "CanonicalizeHostname", "CanonicalizeMaxDots",
+ "CanonicalizePermittedCNAMEs", "CertificateFile",
+ "ChallengeResponseAuthentication", "CheckHostIP", "Ciphers",
+ "ClearAllForwardings", "Compression", "ConnectionAttempts",
+ "ConnectTimeout", "ControlMaster", "ControlPath", "ControlPersist",
+ "DynamicForward", "EnableSSHKeysign", "EscapeChar",
+ "ExitOnForwardFailure", "FingerprintHash", "ForwardAgent",
+ "ForwardX11", "ForwardX11Timeout", "ForwardX11Trusted",
+ "GatewayPorts", "GlobalKnownHostsFile", "GSSAPIAuthentication",
+ "GSSAPIDelegateCredentials", "HashKnownHosts",
+ "HostbasedAuthentication", "HostbasedKeyTypes", "HostKeyAlgorithms",
+ "HostKeyAlias", "HostName", "IdentitiesOnly", "IdentityAgent",
+ "IdentityFile", "IgnoreUnknown", "Include", "IPQoS",
+ "KbdInteractiveAuthentication", "KbdInteractiveDevices",
+ "KexAlgorithms", "LocalCommand", "LocalForward", "LogLevel", "MACs",
+ "NoHostAuthenticationForLocalhost", "NumberOfPasswordPrompts",
+ "PasswordAuthentication", "PermitLocalCommand", "PKCS11Provider",
+ "Port", "PreferredAuthentications", "ProxyCommand", "ProxyJump",
+ "ProxyUseFdpass", "PubkeyAcceptedKeyTypes", "PubkeyAuthentication",
+ "RekeyLimit", "RemoteCommand", "RemoteForward", "RequestTTY",
+ "RevokedHostKeys", "SendEnv", "ServerAliveCountMax",
+ "ServerAliveInterval", "StreamLocalBindMask",
+ "StreamLocalBindUnlink", "StrictHostKeyChecking", "SyslogFacility",
+ "TCPKeepAlive", "Tunnel", "TunnelDevice", "UpdateHostKeys",
+ "UsePrivilegedPort", "User", "UserKnownHostsFile",
+ "VerifyHostKeyDNS", "VisualHostKey", "XAuthLocation",
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array(
+ '%h', '%p',
+ ),
+ // these get clobbered by regexes anyway
+ //1 => array( '!'),
+ //2 => array( '*')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 0 => true,
+ 1 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 0 => 'color: green; font-weight: bold',
+ 1 => 'color: blue',
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => ''
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #933;'
+ ),
+ 'NUMBERS' => array(
+ 0 => ''
+ ),
+ 'METHODS' => array(
+ 0 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: lightseagreen; font-weight: bold',
+ // these two get clobbered by regexes below anyway
+ 1 => 'color: red; font-weight: bold',
+ 1 => 'color: darkmagenta; font-weight: bold',
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: darkmagenta;',
+ //1 => 'color: red; font-weight: bold',
+ 2 => 'color: magenta; font-weight: bold',
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 0=> 'https://man.openbsd.org/ssh_config#{FNAME}',
+ 1=> 'https://man.openbsd.org/ssh_config#{FNAME}',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ // Hostnames
+ 0 => array(
+ GESHI_SEARCH => '(Host(name)?.*?)(?<=\s)(.*)',
+ GESHI_REPLACE => '\\3',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ // Negated hostanmes (doesn't work)
+ //1 => array(
+ // GESHI_SEARCH => '([([{,<+*-\/=\s!]|&lt;)(?!(?:PIPE|SEMI|DOT|NUM|REG3XP\d*)\W)(![a-zA-Z*]\w*)(?!\w)',
+ // GESHI_SEARCH => '(?<=!)(.*?)',
+ // GESH_REPLACE => '\\2',
+ // GESHI_MODIFIERS => '',
+ // GESHI_BEFORE => '\\1',
+ // GESHI_AFTER => ''
+ // ),
+ // Wildcards
+ 2 => '\*'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/standardml.php b/platform/www/vendor/geshi/geshi/src/geshi/standardml.php
new file mode 100644
index 0000000..c48494c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/standardml.php
@@ -0,0 +1,216 @@
+<?php
+/*************************************************************************************
+ * standardml.php
+ * ----------
+ * Author: eldesh (nephits@gmail.com)
+ * Copyright: (c) 2014 eldesh (http://d.hatena.ne.jp/eldesh/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2014/02/04
+ *
+ * SML (StandardML'97) language file for GeSHi.
+ * This file also support some implementation dependent keywords by SML/NJ and SML#.
+ *
+ * CHANGES
+ * -------
+ * 2014/02/05 (1.0.8.11)
+ * - First Release
+ *
+ * TODO (updated 2014/02/04)
+ * -------------------------
+ * - support character literal
+ * - support Vector expressions and patterns (http://www.smlnj.org/doc/features.html)
+ * - support more Basis functions...?
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'StandardML',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('(*' => '*)'),
+ 'COMMENT_REGEXP' => array(1 => '/\(\*(?:(?R)|.)+?\*\)/s'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'NUMBERS' =>
+ array(
+ /* integer dec */
+ 0 => GESHI_NUMBER_INT_BASIC,
+ /* integer hex */
+ 1 => GESHI_NUMBER_HEX_PREFIX,
+ /* real */
+ 2 => GESHI_NUMBER_FLT_SCI_ZERO,
+ /* word dec */
+ 3 => '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0w[0-9]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)',
+ /* word hex */
+ 4 => '(?<![0-9a-z_\.])(?<![\d\.]e[+\-])0wx[0-9a-fA-F]+?(?![0-9a-z]|\.(?:[eE][+\-]?)?\d)'
+ ),
+ 'KEYWORDS' => array(
+ /* main SML keywords */
+ 1 => array(
+ /* deprecated: SML90 */
+ 'abstype',
+
+ 'and', 'andalso', 'as', 'case', 'datatype', 'else',
+ 'end', 'exception', 'fn', 'fun', 'functor',
+ 'if', 'in', 'infix', 'infixr', 'let', 'local', 'nonfix',
+ 'of', 'op', 'open', 'orelse',
+ 'rec', 'raise', 'sharing', 'sig', 'signature', 'struct', 'structure', 'then',
+ 'type', 'val', 'while', 'with', 'withtype'
+ ),
+ /* Top-level type and constructors */
+ 2 => array(
+ 'unit', 'int', 'word', 'real', 'char', 'string', 'substring', 'exn',
+ 'array', 'vector', 'bool', 'option',
+ 'list'
+ ),
+ /* standard structures/signatures/functors provided by Basis library */
+ 3 => array(
+ 'ARRAY', 'Array', 'Array2', 'ARRAY2', 'ArraySlice', 'ARRAY_SLICE',
+ 'BinIO', 'BIT_FLAGS', 'Bool', 'BOOL', 'Byte', 'CHAR', 'Char',
+ 'CommandLine', 'Date', 'General', 'GenericSock', 'IEEEReal', 'IMPERATIVE_IO',
+ 'ImperativeIO', 'INetSock', 'INTEGER', 'Int', 'IntInf', 'IO', 'List', 'ListPair',
+ 'MATH', 'MONO_ARRAY', 'MONO_ARRAY2', 'MONO_ARRAY_SLICE', 'MONO_VECTOR',
+ 'MONO_VECTOR_SLICE', 'NetHostDB', 'NetProtDB', 'NetServDB', 'Option',
+ 'OS', 'OS.FileSys', 'OS.IO', 'OS.Path', 'OS.Process', 'PACK_REAL', 'PACK_WORD',
+ 'Posix', 'Posix.Error', 'Posix.FileSys', 'Posix.IO', 'Posix.ProcEnv', 'Posix.Process',
+ 'Posix.Signal', 'Posix.SysDB', 'Posix.TTY', 'PRIM_IO', 'PrimIO', 'REAL', 'Real', 'Socket',
+ 'STREAM_IO', 'StreamIO', 'STRING', 'String', 'StringCvt', 'SUBSTRING', 'Substring', 'TEXT', 'TEXT_IO',
+ 'TEXT_STREAM_IO', 'Time', 'Timer', 'Unix', 'UnixSock', 'VECTOR', 'Vector', 'VECTOR_SLICE',
+ 'Windows', 'WORD', 'Word'
+ ),
+ /* Top-level value identifiers / constructors */
+ 4 => array(
+ 'app', 'before', 'ceil', 'chr', 'concat', 'exnMessage', 'exnName', 'explode',
+ 'floor', 'foldl', 'foldr', 'getOpt', 'hd', 'ignore', 'implode', 'isSome', 'length', 'map', 'not',
+ 'null', 'o', 'ord', 'print', 'rev', 'round', 'size', 'str', 'tl', 'trunc',
+ 'use', 'valOf',
+ /* constructors */
+ 'ref', 'true', 'false', 'NONE', 'SOME', 'LESS', 'EQUAL', 'GREATER', 'nil',
+ /* overloaded identifiers */
+ 'div', 'mod', 'abs'
+ ),
+ /* standard exceptions */
+ 5 => array (
+ 'Bind', 'Chr', 'Div', 'Domain', 'Empty', 'Fail', 'Match', 'Overflow', 'Size', 'Span', 'Subscript'
+ ),
+ /* implementation dependent keyword (not be sorted) */
+ 6 => array (
+ /** SML/NJ */
+ /* functor signature > http://www.smlnj.org/doc/features.html */
+ 'funsig',
+ /* lazy evaluation */
+ 'lazy',
+ /** SML# */
+ /* binding to C function */
+ '_import',
+ /* read other source */
+ '_require',
+ /* export aggregated interface files */
+ 'include',
+ /* integrated sql */
+ '_sqlserver', '_sql', 'from', 'where', '_sqleval', '_sqlexec',
+ 'select', 'insert', 'update', 'begin', 'commit', 'rollback',
+ 'values', 'delete'
+ )
+ ),
+ /* highlighting symbols */
+ 'SYMBOLS' => array(
+ 0 => array('=', ':', ':>', '=>', '(', ')', '|', '_', '==', ';', '.'),
+ 1 => array('!', ':=', '@', '^'),
+ 2 => array('[', ']', '::', '{', '}'),
+ /* overloaded identifiers */
+ 3 => array('+', '-', '*', '/', '~', '<', '>', '<=', '>=')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true, /* keywords */
+ 2 => true, /* top level types */
+ 3 => true, /* structures */
+ 4 => true, /* top level identifiers */
+ 5 => true, /* top level exceptions */
+ 6 => true /* implementation dependent keyword */
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #557cde; font-weight: bold;',
+ 2 => 'color: #8dda4a; font-weight: bold;',
+ 3 => 'color: #0066cc; font-weight: bold;',
+ 4 => 'color: #5c8cbb;',
+ 5 => 'color: #f33e64; font-weight: bold;',
+ 6 => 'color: #f33e64;'
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #5d478b; font-style: italic;', /* light purple */
+ 1 => 'color: #5d478b; font-style: italic;' /* light purple */
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #79c200;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #488614;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #fb7600;',
+ 1 => 'color: #fb7600;',
+ 2 => 'color: #fb7600;',
+ 3 => 'color: #fb7600;',
+ 4 => 'color: #fb7600;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0066cc;'
+ ),
+ 'REGEXPS' => array(
+ 1 => 'font-style:italic; color:#9f7eff;',
+ 2 => 'font-weight:bold; color:#8dda4a;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #ff4bcf;',
+ 1 => 'color: #ff4bcf; font-weight: bold;', // pink
+ 2 => 'color: #90f963;', // orange
+ 3 => 'color: #fa5bf8;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => 'http://www.standardml.org/Basis/top-level-chapter.html',
+ 3 => '',
+ 4 => '',
+ 5 => 'http://www.standardml.org/Basis/top-level-chapter.html#section:2',
+ 6 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ 1 => '(?<!\w)#\w+', /* record field access */
+ 2 => '(?:(?<![0-9a-zA-Z]))\'[a-z]+' /* type variable */
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/stonescript.php b/platform/www/vendor/geshi/geshi/src/geshi/stonescript.php
new file mode 100644
index 0000000..cdf8991
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/stonescript.php
@@ -0,0 +1,305 @@
+<?php
+/*************************************************************************************
+ * stonescript.php
+ * --------
+ * Author: Archimmersion ( based on ruby.php by Moises Deniz )
+ * Copyright: (c) 2011 Archimmersion ( http://www.archimmersion.com )
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/03/30
+ *
+ * StoneScript language file for GeSHi.
+ *
+ * StonesCript is a Lua based script language for the ShiVa3D game engine ( http://www.stonetrip.com )
+ *
+ * More information can be found at http://www.stonetrip.com/developer/doc/api/introduction
+ *
+ * CHANGES
+ * -------
+ * 2011/04/18 (1.0.8.11)
+ * - Initial release
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'StoneScript',
+ 'COMMENT_SINGLE' => array(1 => "--"),
+ 'COMMENT_MULTI' => array("--[[" => "]]"),
+ 'COMMENT_REGEXP' => array(
+ 4 => '/<<\s*?(\w+)\\n.*?\\n\\1(?![a-zA-Z0-9])/si',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', '`','\''),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ // Blue - General Keywords
+ 1 => array(
+ 'and', 'begin', 'break', 'do', 'else', 'elseif', 'end',
+ 'for', 'if', 'in', 'while', 'next', 'not', 'or', 'redo',
+ 'then', 'unless', 'until', 'when', 'false', 'nil', 'self',
+ 'true', 'local', 'this', 'return',
+ ),
+ // Dark Blue - Main API names
+ 2 => array(
+ 'animation', 'application', 'cache', 'camera', 'debug',
+ 'dynamics', 'group', 'hashtable', 'hud', 'input', 'light',
+ 'log', 'math', 'mesh', 'microphone', 'music', 'navigation',
+ 'network', 'object', 'pixelmap', 'projector', 'scene',
+ 'sensor', 'server', 'session', 'sfx', 'shape', 'sound',
+ 'string', 'system', 'table', 'user', 'video', 'xml',
+ // Plugin API names
+ 'plasma', 'watersim',
+ 'winDirectories',
+ 'ActionSheet', 'Alert', 'Mail', 'Picker', 'StatusBar',
+ ),
+ // Constants
+ // Can be commented out if performance is crucial -> then these keywords will appear in a slightly lighter color
+ 3 => array(
+ //Animation
+ 'kPlaybackModeLoop', 'kPlaybackModeLoopMirrored', 'kPlaybackModeLoopReversed',
+ 'kPlaybackModeOnce', 'kPlaybackModeOnceReversed',
+ //Application - Environment
+ 'kStatusLoading', 'kStatusReady', 'kStatusSaving', // 'kStatusNone'
+ //Application - Options
+ 'kOptionAudioMasterVolume', 'kOptionAutomaticVirtualKeyboard', 'kOptionDynamicShadowsBufferCount',
+ 'kOptionDynamicShadowsBufferSize', 'kOptionDynamicShadowsConstantSampling', 'kOptionDynamicShadowsPCFSampleCount',
+ 'kOptionDynamicShadowsQuality', 'kOptionDynamicShadowsScreenSpaceBlur', 'kOptionFullscreen',
+ 'kOptionFullscreenHeight', 'kOptionFullscreenWidth', 'kOptionHardwareOcclusion',
+ 'kOptionMaxEventBouncesPerFrame', 'kOptionNetworkStreams', 'kOptionNetworkStreamsUseBrowser',
+ 'kOptionPrioritizeEventBounces', 'kOptionRenderingEnabled', 'kOptionShadersQuality',
+ 'kOptionSwapInterval', 'kOptionTerrainsQuality', 'kOptionTexturesAnisotropyLevel',
+ 'kOptionTexturesMipmapBias', 'kOptionTexturesQuality', 'kOptionViewportRotation',
+ //Application - Resource Types
+ 'kResourceTypeAnimBank', 'kResourceTypeFont', 'kResourceTypeHUD',
+ 'kResourceTypeMaterial', 'kResourceTypeMesh', 'kResourceTypeParticle',
+ 'kResourceTypePixelMap', 'kResourceTypeSoundBank', 'kResourceTypeTexture',
+ 'kResourceTypeTextureClip', 'kResourceTypeTrail',
+ //Cache
+ 'kPropertyHeight', 'kPropertySize', 'kPropertyWidth',
+ //Dynamics
+ 'kAxisX', 'kAxisY', 'kAxisZ',
+ 'kTypeBox', 'kTypeCapsule', 'kTypeSphere',
+ //HUD
+ 'kAddressingModeClamp', 'kAddressingModeRepeat', 'kAlignCenter', 'kAlignJustify','kAlignLeft', 'kAlignRight',
+ 'kAlignTop', 'kBlendModeAdd', 'kBlendModeDefault', 'kBlendModeModulate', 'kCaseFixed', 'kCaseVariable',
+ 'kCommandTypeCallAction', 'kCommandTypeCopyCheckStateToRegister', 'kCommandTypeCopyEditTextToRegister',
+ 'kCommandTypeCopyListItemTextToRegister', 'kCommandTypeCopyListLastSelectedItemToRegister',
+ 'kCommandTypeCopyProgressValueToRegister', 'kCommandTypeCopySliderValueToRegister', 'kCommandTypeCopyTagToRegister',
+ 'kCommandTypeEnterModalMode', 'kCommandTypeInterpolateBackgroundColor', 'kCommandTypeInterpolateBorderColor',
+ 'kCommandTypeInterpolateForegroundColor', 'kCommandTypeInterpolateHeight', 'kCommandTypeInterpolateOpacity',
+ 'kCommandTypeInterpolatePosition', 'kCommandTypeInterpolateProgressValue', 'kCommandTypeInterpolateRotation',
+ 'kCommandTypeInterpolateSize', 'kCommandTypeInterpolateWidth', 'kCommandTypeLeaveModalMode',
+ 'kCommandTypeMatchScreenSpaceBottomLeftCorner', 'kCommandTypeMatchScreenSpaceBottomRightCorner',
+ 'kCommandTypeMatchScreenSpaceCenter', 'kCommandTypeMatchScreenSpaceHeight', 'kCommandTypeMatchScreenSpaceTopLeftCorner',
+ 'kCommandTypeMatchScreenSpaceTopRightCorner', 'kCommandTypeMatchScreenSpaceWidth', 'kCommandTypePauseMovie',
+ 'kCommandTypePauseSound', 'kCommandTypePauseTimer', 'kCommandTypePlayMovie', 'kCommandTypePlaySound',
+ 'kCommandTypePlaySoundLoop', 'kCommandTypeResumeSound', 'kCommandTypeSendEventToUser', 'kCommandTypeSetActive',
+ 'kCommandTypeSetBackgroundColor', 'kCommandTypeSetBackgroundImage', 'kCommandTypeSetBackgroundImageUVOffset',
+ 'kCommandTypeSetBackgroundImageUVScale', 'kCommandTypeSetBorderColor', 'kCommandTypeSetButtonText',
+ 'kCommandTypeSetCheckState', 'kCommandTypeSetCheckText', 'kCommandTypeSetCursorPosition', 'kCommandTypeSetCursorVisible',
+ 'kCommandTypeSetEditText', 'kCommandTypeSetFocus', 'kCommandTypeSetForegroundColor', 'kCommandTypeSetHeight',
+ 'kCommandTypeSetLabelText', 'kCommandTypeSetOpacity', 'kCommandTypeSetPosition', 'kCommandTypeSetRotation',
+ 'kCommandTypeSetSize', 'kCommandTypeSetVisible', 'kCommandTypeSetWidth', 'kCommandTypeSleep', 'kCommandTypeStartTimer',
+ 'kCommandTypeStopAction', 'kCommandTypeStopMovie', 'kCommandTypeStopSound', 'kCommandTypeStopTimer',
+ 'kComponentTypeButton', 'kComponentTypeCheck', 'kComponentTypeContainer', 'kComponentTypeEdit', 'kComponentTypeLabel',
+ 'kComponentTypeList', 'kComponentTypeMovie', 'kComponentTypePicture', 'kComponentTypePixelMap', 'kComponentTypeProgress',
+ 'kComponentTypeRenderMap', 'kComponentTypeSlider', 'kCursorShapeCross', 'kCursorShapeDefault', 'kCursorShapeHandPointing',
+ 'kCursorShapeIBeam', 'kCursorShapeNone', 'kCursorShapeWaiting', 'kDirectionLeftToRight', 'kDirectionRightToLeft',
+ 'kEncodingASCII', 'kEncodingUTF8', 'kEventTypeGainFocus', 'kEventTypeLooseFocus', 'kEventTypeMouseEnter',
+ 'kEventTypeMouseLeave', 'kFillModeSolid', 'kInterpolatorTypeLinear', 'kInterpolatorTypePower2', 'kInterpolatorTypePower3',
+ 'kInterpolatorTypePower4', 'kInterpolatorTypeRoot2', 'kInterpolatorTypeRoot3', 'kInterpolatorTypeRoot4',
+ 'kInterpolatorTypeSpring1', 'kInterpolatorTypeSpring2', 'kInterpolatorTypeSpring3', 'kInterpolatorTypeSpring4',
+ 'kInterpolatorTypeSpring5', 'kInterpolatorTypeSpring6',
+ 'kOriginBottom', 'kOriginBottomLeft', 'kOriginBottomRight', 'kOriginCenter', 'kOriginLeft', 'kOriginRight',
+ 'kOriginTop', 'kOriginTopLeft', 'kOriginTopRight', 'kProgressTypeBottomToTop', 'kProgressTypeLeftToRight',
+ 'kProgressTypeRightToLeft', 'kProgressTypeTopToBottom', 'kRuntimeValueCallArgument0', 'kRuntimeValueCallArgument1',
+ 'kRuntimeValueCallArgument2', 'kRuntimeValueCallArgument3', 'kRuntimeValueCurrentUser', 'kRuntimeValueCurrentUserMainCamera',
+ 'kRuntimeValueRegister0', 'kRuntimeValueRegister1', 'kRuntimeValueRegister2', 'kRuntimeValueRegister3',
+ 'kShapeTypeEllipsoid', 'kShapeTypeRectangle', 'kShapeTypeRoundRectangle', 'kSliderTypeBottomToTop',
+ 'kSliderTypeLeftToRight', 'kSliderTypeRightToLeft', 'kSliderTypeTopToBottom', 'kWaveTypeConstant',
+ 'kWaveTypeSawtooth', 'kWaveTypeSawtoothInv', 'kWaveTypeSinus', 'kWaveTypeSinusNoise', 'kWaveTypeSquare', 'kWaveTypeTriangle',
+ //Input
+ 'kJoypadTypeIPhone', 'kJoypadTypeNone', 'kJoypadTypePhone', 'kJoypadTypeStandard', 'kJoypadTypeWiimote',
+ 'kKey0', 'kKey1', 'kKey2', 'kKey3', 'kKey4', 'kKey5', 'kKey6', 'kKey7', 'kKey8', 'kKey9', 'kKeyA', 'kKeyB',
+ 'kKeyBackspace', 'kKeyC', 'kKeyD', 'kKeyDelete', 'kKeyDown', 'kKeyE', 'kKeyEnd', 'kKeyEscape', 'kKeyF',
+ 'kKeyF1', 'kKeyF10', 'kKeyF11', 'kKeyF12', 'kKeyF2', 'kKeyF3', 'kKeyF4', 'kKeyF5', 'kKeyF6', 'kKeyF7',
+ 'kKeyF8', 'kKeyF9', 'kKeyG', 'kKeyH', 'kKeyHome', 'kKeyI', 'kKeyInsert', 'kKeyJ', 'kKeyK', 'kKeyL',
+ 'kKeyLAlt', 'kKeyLControl', 'kKeyLeft', 'kKeyLShift', 'kKeyM', 'kKeyN', 'kKeyO', 'kKeyP', 'kKeyPageDown',
+ 'kKeyPageUp', 'kKeyQ', 'kKeyR', 'kKeyRAlt', 'kKeyRControl', 'kKeyReturn', 'kKeyRight', 'kKeyRShift',
+ 'kKeyS', 'kKeySpace', 'kKeyT', 'kKeyTab', 'kKeyU', 'kKeyUp', 'kKeyV', 'kKeyW', 'kKeyX', 'kKeyY',
+ 'kKeyZ', 'kJoypadButtonPSPCircle', 'kJoypadButtonPSPCross', 'kJoypadButtonPSPDown', 'kJoypadButtonPSPL',
+ 'kJoypadButtonPSPLeft', 'kJoypadButtonPSPR', 'kJoypadButtonPSPRight', 'kJoypadButtonPSPSelect',
+ 'kJoypadButtonPSPSquare', 'kJoypadButtonPSPStart', 'kJoypadButtonPSPTriangle', 'kJoypadButtonPSPUp',
+ 'kJoypadTypePSP', 'kJoypadButtonWiimoteA', 'kJoypadButtonWiimoteB', 'kJoypadButtonWiimoteC',
+ 'kJoypadButtonWiimoteDown', 'kJoypadButtonWiimoteHome', 'kJoypadButtonWiimoteLeft',
+ 'kJoypadButtonWiimoteMinus', 'kJoypadButtonWiimoteOne', 'kJoypadButtonWiimotePlus',
+ 'kJoypadButtonWiimoteRight', 'kJoypadButtonWiimoteTwo', 'kJoypadButtonWiimoteUp', 'kJoypadButtonWiimoteZ',
+ //Light
+ 'kTypeDirectional', 'kTypePoint',
+ //Math
+ 'kEpsilon', 'kInfinity', 'kPi',
+ //Mesh
+ 'kLockModeRead', 'kLockModeWrite', 'kLockReadWrite',
+ //Network
+ 'kBluetoothServerPort', 'kDefaultServerPort', 'kStatusAuthenticated', 'kStatusSearchFinished', // 'kStatusNone', 'kStatusPending',
+ //Object
+ 'kControllerTypeAI', 'kControllerTypeAnimation', 'kControllerTypeAny', 'kControllerTypeDynamics',
+ 'kControllerTypeNavigation', 'kControllerTypeSound', 'kGlobalSpace', 'kLocalSpace', 'kParentSpace',
+ 'kTransformOptionInheritsParentRotation', 'kTransformOptionInheritsParentScale', 'kTransformOptionInheritsParentTranslation',
+ 'kTransformOptionTranslationAffectedByParentRotation', 'kTransformOptionTranslationAffectedByParentScale', 'kTypeCamera',
+ 'kTypeCollider', 'kTypeDummy', 'kTypeGroup', 'kTypeLight', 'kTypeOccluder', 'kTypeProjector', 'kTypeReflector',
+ 'kTypeSensor', 'kTypeSfx', 'kTypeShape',
+ //Pixelmap
+ 'kBlendModeDecal', 'kBlendModeReplace', 'kFillModeBrush', 'kFillModeNone', 'kPenModeBrush', // 'kFillModeSolid',
+ 'kPenModeNone', 'kPenModeSolid',
+ //Projector
+ 'kMapTypeMovie', 'kMapTypePixelMap', 'kMapTypeRenderMap', 'kMapTypeTexture', 'kMapTypeTextureClip',
+ //Scene
+ 'kFilteringModeBilinear', 'kFilteringModeNearest', 'kFilteringModeTrilinear', // 'kAddressingModeClamp', 'kAddressingModeRepeat',
+ 'kSkyBoxFaceBack', 'kSkyBoxFaceBottom', 'kSkyBoxFaceFront', 'kSkyBoxFaceLeft', 'kSkyBoxFaceRight', 'kSkyBoxFaceTop',
+ //Sensor
+ 'kShapeTypeBox', 'kShapeTypeSphere',
+ //Server
+ 'kStatusConnected', 'kStatusNone', 'kStatusPending',
+ //Session - duplicate keywords
+ //'kStatusConnected', 'kStatusNone', 'kStatusPending',
+ //Shape
+ 'kMapTypeUnknown', 'kCurveTypeBezier', 'kCurveTypeBSpline', 'kCurveTypeCatmullRom', 'kCurveTypePolyLine',
+ // 'kMapTypeMovie', 'kMapTypePixelMap', 'kMapTypeRenderMap', 'kMapTypeTexture', 'kMapTypeTextureClip',
+
+ //System
+ 'kOSType3DS', 'kOSTypeBada', 'kOSTypeBrew', 'kOSTypePalm', 'kOSTypePS3',
+ 'kClientTypeEditor', 'kClientTypeEmbedded', 'kClientTypeStandalone',
+ 'kGPUCapabilityBloomFilterSupport', 'kGPUCapabilityContrastFilterSupport', 'kGPUCapabilityDepthBlurFilterSupport',
+ 'kGPUCapabilityDistortionFilterSupport', 'kGPUCapabilityDynamicShadowsSupport', 'kGPUCapabilityHardwareOcclusionSupport',
+ 'kGPUCapabilityHardwareRenderingSupport', 'kGPUCapabilityMonochromeFilterSupport', 'kGPUCapabilityMotionBlurFilterSupport',
+ 'kGPUCapabilityPixelShaderSupport', 'kGPUCapabilityVelocityBlurFilterSupport', 'kGPUCapabilityVertexShaderSupport',
+ 'kLanguageAlbanian', 'kLanguageArabic', 'kLanguageBulgarian', 'kLanguageCatalan', 'kLanguageCzech', 'kLanguageDanish',
+ 'kLanguageDutch', 'kLanguageEnglish', 'kLanguageFinnish', 'kLanguageFrench', 'kLanguageGerman', 'kLanguageGreek',
+ 'kLanguageHebrew', 'kLanguageHungarian', 'kLanguageIcelandic', 'kLanguageItalian', 'kLanguageJapanese', 'kLanguageKorean',
+ 'kLanguageNorwegian', 'kLanguagePolish', 'kLanguagePortuguese', 'kLanguageRomanian', 'kLanguageRussian',
+ 'kLanguageSerboCroatian', 'kLanguageSlovak', 'kLanguageSpanish', 'kLanguageSwedish', 'kLanguageThai',
+ 'kLanguageTurkish', 'kLanguageUnknown', 'kLanguageUrdu', 'kOSTypeAndroid', 'kOSTypeAngstrom', 'kOSTypeIPhone',
+ 'kOSTypeLinux', 'kOSTypeMac', 'kOSTypePSP', 'kOSTypeSymbian', 'kOSTypeWii', 'kOSTypeWindows', 'kOSTypeWindowsCE',
+ ),
+ // Not used yet
+ 4 => array(
+ 'dummycommand',
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '%', '&', '*', '|', '/', '<', '>',
+ '+', '-', '=>', '<<'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color:#0000FF; font-weight:bold;',
+ 2 => 'color:#000088; font-weight:bold;',
+ 3 => 'color:#C088C0; font-weight:bold;',
+ 4 => 'color:#00FEFE; font-weight:bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color:#008000; font-style:italic;',
+ 4 => 'color: #cc0000; font-style: italic;',
+ 'MULTI' => 'color:#008000; font-style:italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color:#000099;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color:#000000; font-weight:bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color:#888800;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color:#AA0000;'
+ ),
+ // names after "."
+ 'METHODS' => array(
+ 1 => 'color:#FF00FF; font-weight:bold;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color:#000000; font-weight:bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color:#ff6633; font-weight:bold;',
+ 1 => 'color:#0066ff; font-weight:bold;',
+ 2 => 'color:#6666ff; font-weight:bold;',
+ 3 => 'color:#ff3333; font-weight:bold;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ 0 => array(//Variables
+ GESHI_SEARCH => "([[:space:]])(\\$[a-zA-Z_][a-zA-Z0-9_]*)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 1 => array(//Arrays
+ GESHI_SEARCH => "([[:space:]])(@[a-zA-Z_][a-zA-Z0-9_]*)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 2 => "([A-Z][a-zA-Z0-9_]*::)+[A-Z][a-zA-Z0-9_]*",//Static OOP symbols
+ 3 => array(
+ GESHI_SEARCH => "([[:space:]]|\[|\()(:[a-zA-Z_][a-zA-Z0-9_]*)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '<%' => '%>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ ),
+ 'TAB_WIDTH' => 2
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/swift.php b/platform/www/vendor/geshi/geshi/src/geshi/swift.php
new file mode 100644
index 0000000..93091bb
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/swift.php
@@ -0,0 +1,557 @@
+<?php
+/*************************************************************************************
+ * swift.php
+ * ----------
+ * Author: Ken Woo (ikenwoo@gmail.com)
+ * Copyright: (c) 2015 Ken Woo
+ * Release Version: 1.0.9.1
+ * Date Started: 2015/05/20
+ *
+ * Swift language file for GeSHi.
+ * To mirror official Apple documentation, set the overall style like so:
+ * $geshi->set_overall_style('font-family: Menlo, monospace; font-size: 0.85em; color: #508187;', false);
+ *
+ * CHANGES
+ * -------
+ * 2015/05/20
+ * - First Release
+ *
+ * TODO (updated 2015/05/20)
+ * -------------------------
+ * - Only added keywords for Swift, Foundation, Core Foundation, Core Graphics, UIKit and AppKit.
+ * There are many other frameworks that can be added like SpriteKit, MapKit, HealthKit, etc.
+ * - Hex regex is a bit wonky when combined with method highlghting and not working
+ * with negative exponents
+ * - Swift strings can include expressions via "sum is: \( 2 + 3 )" and the expression
+ * shouldn't be highlighted as a string. This isn't supported yet.
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Swift',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'NUMBERS' => array(
+ # Decimals
+ 0 => '\b[0-9][0-9_]*(\.[0-9][0-9_]*)?([eE][+-]?[0-9][0-9_]*)?\b',
+ # Hex
+ 1 => '\b0x[0-9A-Fa-f][0-9A-Fa-f_]*((\.[0-9A-Fa-f][0-9A-Fa-f_]*)?([pP][+-]?[0-9][0-9_]*))?\b',
+ # Octal
+ 2 => '\b0o[0-7][0-7_]*\b',
+ # Binary
+ 3 => '\b0b[01][01_]*\b'
+ ),
+ 'KEYWORDS' => array(
+ /*
+ ** Swift Keywords
+ */
+ 1 => array(
+ 'Protocol', 'Self', 'Type', 'as', 'associativity', 'awillSet', 'break', 'case', 'class',
+ 'continue', 'convenience', 'default', 'deinit', 'didSet', 'do', 'dynamic', 'dynamicType',
+ 'else', 'enum', 'extension', 'fallthrough', 'false', 'final', 'for', 'func', 'get', 'if',
+ 'import', 'in', 'infix', 'init', 'inout', 'internal', 'is', 'lazy', 'left', 'let', 'mutating',
+ 'nil', 'none', 'nonmutating', 'operator', 'optional', 'override', 'postfix', 'precedence',
+ 'prefix', 'private', 'protocol', 'public', 'required', 'return', 'right', 'self', 'set',
+ 'static', 'struct', 'subscript', 'super', 'switch', 'true', 'typealias', 'unowned', 'var',
+ 'weak', 'where', 'while', '__COLUMN__', '__FILE__', '__FUNCTION__', '__LINE__',
+ ),
+
+ /*
+ ** Swift Attributes
+ */
+ 2 => array(
+ '@availability', '@autoclosure', '@IBAction', '@IBDesignable', '@IBInspectable', '@IBOutlet',
+ '@noescape', '@noreturn', '@NSApplicationMain', '@NSCopying', '@NSManaged', '@objc', '@UIApplicationMain'
+ ),
+ /*
+ ** Swift Builtin Functions
+ **
+ */
+ 3 => array(
+ 'abs', 'advance', 'alignof', 'alignofValue', 'assert', 'assertionFailure', 'contains', 'count', 'debugPrint',
+ 'debugPrintln', 'distance', 'dropFirst', 'dropLast', 'dump', 'enumerate', 'equal', 'extend', 'fatalError',
+ 'filter', 'find', 'first', 'flatMap', 'getVaList', 'indices', 'insert', 'isEmpty', 'isUniquelyReferenced',
+ 'isUniquelyReferencedNonObjC', 'join', 'last', 'lexicographicalCompare', 'map', 'max', 'maxElement',
+ 'min', 'minElement', 'numericCast', 'overlaps', 'partition', 'precondition', 'preconditionFailure',
+ 'print', 'println', 'reduce', 'reflect', 'removeAll', 'removeAtIndex', 'removeLast', 'removeRange', 'reverse',
+ 'sizeof', 'sizeofValue', 'sort', 'sorted', 'splice', 'split', 'startsWith', 'stride', 'strideof', 'strideofValue',
+ 'suffix', 'swap', 'toDebugString', 'toString', 'transcode', 'underestimateCount', 'unsafeAddressOf', 'unsafeBitCast',
+ 'unsafeDowncast', 'unsafeUnwrap', 'withExtendedLifetime', 'withUnsafeMutablePointer', 'withUnsafeMutablePointers',
+ 'withUnsafePointer', 'withUnsafePointers', 'withVaList', 'zip'
+ ),
+ /*
+ ** Swift Types
+ */
+ 4 => array(
+ 'Array', 'ArraySlice', 'AutoreleasingUnsafeMutablePointer', 'BidirectionalReverseView', 'Bit', 'Bool',
+ 'CFunctionPointer', 'COpaquePointer', 'CVaListPointer', 'Character', 'ClosedInterval', 'CollectionOfOne',
+ 'ContiguousArray', 'Dictionary', 'DictionaryGenerator', 'DictionaryIndex', 'Double', 'EmptyCollection',
+ 'EmptyGenerator', 'EnumerateGenerator', 'EnumerateSequence', 'FilterCollectionView', 'FilterCollectionViewIndex',
+ 'FilterGenerator', 'FilterSequenceView', 'Float', 'Float80', 'FloatingPointClassification', 'GeneratorOf',
+ 'GeneratorOfOne', 'GeneratorSequence', 'HalfOpenInterval', 'ImplicitlyUnwrappedOptional', 'IndexingGenerator',
+ 'Int', 'Int16', 'Int32', 'Int64', 'Int8', 'LazyBidirectionalCollection', 'LazyForwardCollection',
+ 'LazyRandomAccessCollection', 'LazySequence', 'ManagedBuffer', 'ManagedBufferPointer', 'ManagedProtoBuffer',
+ 'MapCollectionView', 'MapSequenceGenerator', 'MapSequenceView', 'MirrorDisposition', 'NonObjectiveCBase',
+ 'ObjectIdentifier', 'Optional', 'PermutationGenerator', 'Process', 'QuickLookObject', 'RandomAccessReverseView',
+ 'Range', 'RangeGenerator', 'RawByte', 'Repeat', 'ReverseBidirectionalIndex', 'ReverseRandomAccessIndex',
+ 'SequenceOf', 'Set', 'SetGenerator', 'SetIndex', 'SinkOf', 'StaticString', 'StrideThrough', 'StrideThroughGenerator',
+ 'StrideTo', 'StrideToGenerator', 'String', 'String.Index', 'String.UTF16View', 'String.UTF16View.Index',
+ 'String.UTF8View', 'String.UTF8View.Index', 'String.UnicodeScalarView', 'String.UnicodeScalarView.Generator',
+ 'String.UnicodeScalarView.Index', 'UInt', 'UInt16', 'UInt32', 'UInt64', 'UInt8', 'UTF16', 'UTF32', 'UTF8',
+ 'UnicodeDecodingResult', 'UnicodeScalar', 'UnicodeScalar.UTF16View', 'Unmanaged', 'UnsafeBufferPointer',
+ 'UnsafeBufferPointerGenerator', 'UnsafeMutableBufferPointer', 'UnsafeMutablePointer', 'UnsafePointer',
+ 'VaListBuilder', 'Zip2', 'ZipGenerator2'
+ ),
+ /*
+ ** Swift Type Aliases
+ */
+ 5 => array(
+ 'Any', 'AnyClass', 'CBool', 'CChar', 'CChar16', 'CChar32', 'CDouble', 'CFloat', 'CInt', 'CLong',
+ 'CLongLong', 'CShort', 'CSignedChar', 'CUnsignedChar', 'CUnsignedInt', 'CUnsignedLong', 'CUnsignedLongLong',
+ 'CUnsignedShort', 'CWideChar', 'ExtendedGraphemeClusterType', 'Float32', 'Float64', 'FloatLiteralType', 'IntMax',
+ 'IntegerLiteralType', 'StringLiteralType', 'UIntMax', 'UWord', 'UnicodeScalarType', 'Void', 'Word'
+ ),
+ /*
+ ** Swift Protocols
+ */
+ 6 => array(
+ 'AbsoluteValuable', 'AnyObject', 'ArrayLiteralConvertible', 'BidirectionalIndexType', 'BitwiseOperationsType',
+ 'BooleanLiteralConvertible', 'BooleanType', 'CVarArgType', 'CollectionType', 'Comparable', 'DebugPrintable',
+ 'DictionaryLiteralConvertible', 'Equatable', 'ExtendedGraphemeClusterLiteralConvertible', 'ExtensibleCollectionType',
+ 'FloatLiteralConvertible', 'FloatingPointType', 'ForwardIndexType', 'GeneratorType', 'Hashable', 'IntegerArithmeticType',
+ 'IntegerLiteralConvertible', 'IntegerType', 'IntervalType', 'MirrorType', 'MutableCollectionType', 'MutableSliceable',
+ 'NilLiteralConvertible', 'OutputStreamType', 'Printable', 'RandomAccessIndexType', 'RangeReplaceableCollectionType',
+ 'RawOptionSetType', 'RawRepresentable', 'Reflectable', 'SequenceType', 'SignedIntegerType', 'SignedNumberType',
+ 'SinkType', 'Sliceable', 'Streamable', 'Strideable', 'StringInterpolationConvertible', 'StringLiteralConvertible',
+ 'UnicodeCodecType', 'UnicodeScalarLiteralConvertible', 'UnsignedIntegerType', '_ArrayBufferType', '_ArrayType',
+ '_BidirectionalIndexType', '_CVarArgPassedAsDouble', '_CocoaStringType', '_CollectionType', '_Comparable',
+ '_DestructorSafeContainer', '_ExtensibleCollectionType', '_ForwardIndexType', '_Incrementable', '_IntegerArithmeticType',
+ '_IntegerType', '_NSArrayCoreType', '_NSCopyingType', '_NSDictionaryCoreType', '_NSDictionaryType', '_NSEnumeratorType',
+ '_NSFastEnumerationType', '_NSSetCoreType', '_NSSetType', '_NSStringCoreType', '_ObjectiveCBridgeable', '_PointerType',
+ '_RandomAccessIndexType', '_RawOptionSetType', '_SequenceType', '_Sequence_Type', '_ShadowProtocol', '_SignedIntegerType',
+ '_SignedNumberType', '_Sliceable', '_Strideable', '_StringElementType', '_UnsignedIntegerType', '__ArrayType'
+ ),
+
+ /*
+ ** Foundation Classes
+ */
+ 7 => array(
+ 'NSObject', 'NSAffineTransform', 'NSAppleEventDescriptor', 'NSAppleEventManager', 'NSAppleScript', 'NSArray', 'NSMutableArray',
+ 'NSAssertionHandler', 'NSAttributedString', 'NSMutableAttributedString', 'NSAutoreleasePool', 'NSBackgroundActivityScheduler',
+ 'NSBundle', 'NSCache', 'NSCachedURLResponse', 'NSCalendar', 'NSCharacterSet', 'NSMutableCharacterSet', 'NSClassDescription',
+ 'NSScriptClassDescription', 'NSCoder', 'NSArchiver', 'NSKeyedArchiver', 'NSKeyedUnarchiver', 'NSPortCoder', 'NSUnarchiver',
+ 'NSCondition', 'NSConditionLock', 'NSConnection', 'NSData', 'NSMutableData', 'NSPurgeableData', 'NSDate', 'NSCalendarDate',
+ 'NSDateComponents', 'NSDecimalNumberHandler', 'NSDictionary', 'NSMutableDictionary', 'NSDistantObjectRequest', 'NSDistributedLock',
+ 'NSEnumerator', 'NSDirectoryEnumerator', 'NSError', 'NSException', 'NSExpression', 'NSExtensionContext', 'NSExtensionItem',
+ 'NSFileAccessIntent', 'NSFileCoordinator', 'NSFileHandle', 'NSFileManager', 'NSFileSecurity', 'NSFileVersion', 'NSFileWrapper',
+ 'NSFormatter', 'NSByteCountFormatter', 'NSDateComponentsFormatter', 'NSDateFormatter', 'NSDateIntervalFormatter',
+ 'NSEnergyFormatter', 'NSLengthFormatter', 'NSMassFormatter', 'NSNumberFormatter', 'NSGarbageCollector', 'NSHashTable', 'NSHost',
+ 'NSHTTPCookie', 'NSHTTPCookieStorage', 'NSIndexPath', 'NSIndexSet', 'NSMutableIndexSet', 'NSInvocation', 'NSItemProvider',
+ 'NSJSONSerialization', 'NSLinguisticTagger', 'NSLocale', 'NSLock', 'NSMapTable', 'NSMetadataItem', 'NSMetadataQuery',
+ 'NSMetadataQueryAttributeValueTuple', 'NSMetadataQueryResultGroup', 'NSMethodSignature', 'NSNetService', 'NSNetServiceBrowser',
+ 'NSNotification', 'NSNotificationCenter', 'NSDistributedNotificationCenter', 'NSNotificationQueue', 'NSNull', 'NSOperation',
+ 'NSBlockOperation', 'NSInvocationOperation', 'NSOperationQueue', 'NSOrderedSet', 'NSMutableOrderedSet', 'NSOrthography', 'NSPipe',
+ 'NSPointerArray', 'NSPointerFunctions', 'NSPort', 'NSMachPort', 'NSMessagePort', 'NSSocketPort', 'NSPortMessage', 'NSPortNameServer',
+ 'NSMachBootstrapServer', 'NSMessagePortNameServer', 'NSSocketPortNameServer', 'NSPositionalSpecifier', 'NSPredicate',
+ 'NSComparisonPredicate', 'NSCompoundPredicate', 'NSProcessInfo', 'NSProgress', 'NSPropertyListSerialization', 'NSRecursiveLock',
+ 'NSRegularExpression', 'NSDataDetector', 'NSRunLoop', 'NSScanner', 'NSScriptCoercionHandler', 'NSScriptCommand', 'NSCloneCommand',
+ 'NSCloseCommand', 'NSCountCommand', 'NSCreateCommand', 'NSDeleteCommand', 'NSExistsCommand', 'NSGetCommand', 'NSMoveCommand',
+ 'NSQuitCommand', 'NSSetCommand', 'NSScriptCommandDescription', 'NSScriptExecutionContext', 'NSScriptObjectSpecifier',
+ 'NSIndexSpecifier', 'NSMiddleSpecifier', 'NSNameSpecifier', 'NSPropertySpecifier', 'NSRandomSpecifier', 'NSRangeSpecifier',
+ 'NSRelativeSpecifier', 'NSUniqueIDSpecifier', 'NSWhoseSpecifier', 'NSScriptSuiteRegistry', 'NSScriptWhoseTest', 'NSLogicalTest',
+ 'NSSpecifierTest', 'NSSet', 'NSMutableSet', 'NSCountedSet', 'NSSortDescriptor', 'NSSpellServer', 'NSStream', 'NSInputStream',
+ 'NSOutputStream', 'NSString', 'NSMutableString', 'NSTask', 'NSTextCheckingResult', 'NSThread', 'NSTimer', 'NSTimeZone',
+ 'NSUbiquitousKeyValueStore', 'NSUndoManager', 'NSURL', 'NSURLAuthenticationChallenge', 'NSURLCache', 'NSURLComponents',
+ 'NSURLConnection', 'NSURLCredential', 'NSURLCredentialStorage', 'NSURLDownload', 'NSURLHandle', 'NSURLProtectionSpace',
+ 'NSURLProtocol', 'NSURLQueryItem', 'NSURLRequest', 'NSMutableURLRequest', 'NSURLResponse', 'NSHTTPURLResponse', 'NSURLSession',
+ 'NSURLSessionConfiguration', 'NSURLSessionTask', 'NSURLSessionDataTask', 'NSURLSessionUploadTask', 'NSURLSessionDownloadTask',
+ 'NSUserActivity', 'NSUserDefaults', 'NSUserNotification', 'NSUserNotificationAction', 'NSUserNotificationCenter',
+ 'NSUserScriptTask', 'NSUserAppleScriptTask', 'NSUserAutomatorTask', 'NSUserUnixTask', 'NSUUID', 'NSValue', 'NSNumber',
+ 'NSDecimalNumber', 'NSValueTransformer', 'NSXMLNode', 'NSXMLDocument', 'NSXMLDTD', 'NSXMLDTDNode', 'NSXMLElement', 'NSXMLParser',
+ 'NSXPCConnection', 'NSXPCInterface', 'NSXPCListener', 'NSXPCListenerEndpoint', 'NSProxy', 'NSDistantObject', 'NSProtocolChecker'
+ ),
+ /*
+ ** Foundation Protocols
+ */
+ 8 => array(
+ 'NSCacheDelegate', 'NSCoding', 'NSComparisonMethods', 'NSConnectionDelegate', 'NSCopying', 'NSDecimalNumberBehaviors',
+ 'NSDiscardableContent', 'NSErrorRecoveryAttempting', 'NSExtensionRequestHandling', 'NSFastEnumeration', 'NSFileManagerDelegate',
+ 'NSFilePresenter', 'NSKeyValueCoding', 'NSKeyValueObserving', 'NSKeyedArchiverDelegate', 'NSKeyedUnarchiverDelegate', 'NSLocking',
+ 'NSMachPortDelegate', 'NSMetadataQueryDelegate', 'NSMutableCopying', 'NSNetServiceBrowserDelegate', 'NSNetServiceDelegate',
+ 'NSPortDelegate', 'NSScriptKeyValueCoding', 'NSScriptObjectSpecifiers', 'NSScriptingComparisonMethods',
+ 'NSSecureCoding', 'NSSpellServerDelegate', 'NSStreamDelegate', 'NSURLAuthenticationChallengeSender',
+ 'NSURLConnectionDataDelegate', 'NSURLConnectionDelegate', 'NSURLDownloadDelegate', 'NSURLHandleClient', 'NSURLProtocolClient',
+ 'NSURLSessionDataDelegate', 'NSURLSessionDelegate', 'NSURLSessionDownloadDelegate', 'NSURLSessionTaskDelegate',
+ 'NSUserActivityDelegate', 'NSUserNotificationCenterDelegate', 'NSXMLParserDelegate', 'NSXPCListenerDelegate',
+ 'NSXPCProxyCreating'
+ ),
+ /*
+ ** Core Foundation Protocols
+ **
+ */
+ 9 => array(
+ 'CFAllocator', 'CFArray', 'CFAttributedString', 'CFBag', 'CFBinaryHeap', 'CFBitVector', 'CFBoolean', 'CFBundle', 'CFCalendar',
+ 'CFCharacterSet', 'CFData', 'CFDate', 'CFDateFormatter', 'CFDictionary', 'CFError', 'CFFileDescriptor', 'CFLocale', 'CFMachPort',
+ 'CFMessagePort', 'CFMutableArray', 'CFMutableAttributedString', 'CFMutableBag', 'CFMutableBitVector', 'CFMutableCharacterSet',
+ 'CFMutableData', 'CFMutableDictionary', 'CFMutableSet', 'CFMutableString', 'CFNotificationCenter', 'CFNull', 'CFNumber',
+ 'CFNumberFormatter', 'CFPlugIn', 'CFPlugInInstance', 'CFPropertyList', 'CFReadStream', 'CFRunLoop', 'CFRunLoopObserver',
+ 'CFRunLoopSource', 'CFRunLoopTimer', 'CFSet', 'CFSocket', 'CFString', 'CFStringTokenizer', 'CFTimeZone', 'CFTree', 'CFType', 'CFURL',
+ 'CFUUID', 'CFUserNotification', 'CFWriteStream', 'CFXMLNode', 'CFXMLParser', 'CFXMLTree'
+ ),
+
+ /*
+ ** Core Foundation Data Types
+ **
+ */
+ 10 => array(
+ 'CFAbsoluteTime', 'CFAllocatorContext', 'CFAllocatorRef', 'CFArrayCallBacks', 'CFArrayRef', 'CFAttributedStringRef',
+ 'CFBagCallBacks', 'CFBagRef', 'CFBinaryHeapCallBacks', 'CFBinaryHeapCompareContext', 'CFBinaryHeapRef', 'CFBit', 'CFBitVectorRef',
+ 'CFBooleanRef', 'CFBundleRef', 'CFBundleRefNum', 'CFCalendarRef', 'CFCharacterSetPredefinedSet',
+ 'CFCharacterSetPredefinedSet.AlphaNumeric', 'CFCharacterSetPredefinedSet.CapitalizedLetter',
+ 'CFCharacterSetPredefinedSet.Control', 'CFCharacterSetPredefinedSet.DecimalDigit',
+ 'CFCharacterSetPredefinedSet.Decomposable', 'CFCharacterSetPredefinedSet.Illegal', 'CFCharacterSetPredefinedSet.Letter',
+ 'CFCharacterSetPredefinedSet.LowercaseLetter', 'CFCharacterSetPredefinedSet.Newline', 'CFCharacterSetPredefinedSet.NonBase',
+ 'CFCharacterSetPredefinedSet.Punctuation', 'CFCharacterSetPredefinedSet.Symbol',
+ 'CFCharacterSetPredefinedSet.UppercaseLetter', 'CFCharacterSetPredefinedSet.Whitespace',
+ 'CFCharacterSetPredefinedSet.WhitespaceAndNewline', 'CFCharacterSetRef', 'CFDataRef', 'CFDataSearchFlags', 'CFDateFormatterRef',
+ 'CFDateFormatterStyle', 'CFDateFormatterStyle.FullStyle', 'CFDateFormatterStyle.LongStyle', 'CFDateFormatterStyle.MediumStyle',
+ 'CFDateFormatterStyle.NoStyle', 'CFDateFormatterStyle.ShortStyle', 'CFDateRef', 'CFDictionaryKeyCallBacks', 'CFDictionaryRef',
+ 'CFDictionaryValueCallBacks', 'CFErrorRef', 'CFFileDescriptorCallBack', 'CFFileDescriptorContext',
+ 'CFFileDescriptorNativeDescriptor', 'CFFileDescriptorRef', 'CFGregorianDate', 'CFGregorianUnits', 'CFHashCode', 'CFIndex',
+ 'CFLocaleRef', 'CFMachPortContext', 'CFMachPortRef', 'CFMessagePortContext', 'CFMessagePortRef', 'CFMutableArrayRef',
+ 'CFMutableAttributedStringRef', 'CFMutableBagRef', 'CFMutableBitVectorRef', 'CFMutableCharacterSetRef', 'CFMutableDataRef',
+ 'CFMutableDictionaryRef', 'CFMutableSetRef', 'CFMutableStringRef', 'CFNotificationCenterRef', 'CFNullRef',
+ 'CFNumberFormatterOptionFlags', 'CFNumberFormatterPadPosition', 'CFNumberFormatterPadPosition.AfterPrefix',
+ 'CFNumberFormatterPadPosition.AfterSuffix', 'CFNumberFormatterPadPosition.BeforePrefix',
+ 'CFNumberFormatterPadPosition.BeforeSuffix', 'CFNumberFormatterRef', 'CFNumberFormatterStyle',
+ 'CFNumberFormatterStyle.CurrencyStyle', 'CFNumberFormatterStyle.DecimalStyle', 'CFNumberFormatterStyle.NoStyle',
+ 'CFNumberFormatterStyle.PercentStyle', 'CFNumberFormatterStyle.ScientificStyle', 'CFNumberFormatterStyle.SpellOutStyle',
+ 'CFNumberRef', 'CFOptionFlags', 'CFPlugInInstanceRef', 'CFPlugInRef', 'CFPropertyListMutabilityOptions', 'CFPropertyListRef',
+ 'CFRange', 'CFReadStreamRef', 'CFRunLoopObserverContext', 'CFRunLoopObserverRef', 'CFRunLoopRef', 'CFRunLoopSourceContext',
+ 'CFRunLoopSourceContext1', 'CFRunLoopSourceRef', 'CFRunLoopTimerContext', 'CFRunLoopTimerRef', 'CFSetCallBacks', 'CFSetRef',
+ 'CFSocketContext', 'CFSocketNativeHandle', 'CFSocketRef', 'CFSocketSignature', 'CFStreamClientContext', 'CFStreamError',
+ 'CFStringCompareFlags', 'CFStringEncoding', 'CFStringEncodings', 'CFStringEncodings.ANSEL', 'CFStringEncodings.Big5',
+ 'CFStringEncodings.Big5_E', 'CFStringEncodings.Big5_HKSCS_1999', 'CFStringEncodings.CNS_11643_92_P1',
+ 'CFStringEncodings.CNS_11643_92_P2', 'CFStringEncodings.CNS_11643_92_P3', 'CFStringEncodings.DOSArabic',
+ 'CFStringEncodings.DOSBalticRim', 'CFStringEncodings.DOSCanadianFrench', 'CFStringEncodings.DOSChineseSimplif',
+ 'CFStringEncodings.DOSChineseTrad', 'CFStringEncodings.DOSCyrillic', 'CFStringEncodings.DOSGreek',
+ 'CFStringEncodings.DOSGreek1', 'CFStringEncodings.DOSGreek2', 'CFStringEncodings.DOSHebrew', 'CFStringEncodings.DOSIcelandic',
+ 'CFStringEncodings.DOSJapanese', 'CFStringEncodings.DOSKorean', 'CFStringEncodings.DOSLatin1', 'CFStringEncodings.DOSLatin2',
+ 'CFStringEncodings.DOSLatinUS', 'CFStringEncodings.DOSNordic', 'CFStringEncodings.DOSPortuguese',
+ 'CFStringEncodings.DOSRussian', 'CFStringEncodings.DOSThai', 'CFStringEncodings.DOSTurkish', 'CFStringEncodings.EBCDIC_CP037',
+ 'CFStringEncodings.EBCDIC_US', 'CFStringEncodings.EUC_CN', 'CFStringEncodings.EUC_JP', 'CFStringEncodings.EUC_KR',
+ 'CFStringEncodings.EUC_TW', 'CFStringEncodings.GBK_95', 'CFStringEncodings.GB_18030_2000', 'CFStringEncodings.GB_2312_80',
+ 'CFStringEncodings.HZ_GB_2312', 'CFStringEncodings.ISOLatin10', 'CFStringEncodings.ISOLatin2', 'CFStringEncodings.ISOLatin3',
+ 'CFStringEncodings.ISOLatin4', 'CFStringEncodings.ISOLatin5', 'CFStringEncodings.ISOLatin6', 'CFStringEncodings.ISOLatin7',
+ 'CFStringEncodings.ISOLatin8', 'CFStringEncodings.ISOLatin9', 'CFStringEncodings.ISOLatinArabic',
+ 'CFStringEncodings.ISOLatinCyrillic', 'CFStringEncodings.ISOLatinGreek', 'CFStringEncodings.ISOLatinHebrew',
+ 'CFStringEncodings.ISOLatinThai', 'CFStringEncodings.ISO_2022_CN', 'CFStringEncodings.ISO_2022_CN_EXT',
+ 'CFStringEncodings.ISO_2022_JP', 'CFStringEncodings.ISO_2022_JP_1', 'CFStringEncodings.ISO_2022_JP_2',
+ 'CFStringEncodings.ISO_2022_JP_3', 'CFStringEncodings.ISO_2022_KR', 'CFStringEncodings.JIS_C6226_78',
+ 'CFStringEncodings.JIS_X0201_76', 'CFStringEncodings.JIS_X0208_83', 'CFStringEncodings.JIS_X0208_90',
+ 'CFStringEncodings.JIS_X0212_90', 'CFStringEncodings.KOI8_R', 'CFStringEncodings.KOI8_U', 'CFStringEncodings.KSC_5601_87',
+ 'CFStringEncodings.KSC_5601_92_Johab', 'CFStringEncodings.MacArabic', 'CFStringEncodings.MacArmenian',
+ 'CFStringEncodings.MacBengali', 'CFStringEncodings.MacBurmese', 'CFStringEncodings.MacCeltic',
+ 'CFStringEncodings.MacCentralEurRoman', 'CFStringEncodings.MacChineseSimp', 'CFStringEncodings.MacChineseTrad',
+ 'CFStringEncodings.MacCroatian', 'CFStringEncodings.MacCyrillic', 'CFStringEncodings.MacDevanagari',
+ 'CFStringEncodings.MacDingbats', 'CFStringEncodings.MacEthiopic', 'CFStringEncodings.MacExtArabic',
+ 'CFStringEncodings.MacFarsi', 'CFStringEncodings.MacGaelic', 'CFStringEncodings.MacGeorgian', 'CFStringEncodings.MacGreek',
+ 'CFStringEncodings.MacGujarati', 'CFStringEncodings.MacGurmukhi', 'CFStringEncodings.MacHFS', 'CFStringEncodings.MacHebrew',
+ 'CFStringEncodings.MacIcelandic', 'CFStringEncodings.MacInuit', 'CFStringEncodings.MacJapanese',
+ 'CFStringEncodings.MacKannada', 'CFStringEncodings.MacKhmer', 'CFStringEncodings.MacKorean', 'CFStringEncodings.MacLaotian',
+ 'CFStringEncodings.MacMalayalam', 'CFStringEncodings.MacMongolian', 'CFStringEncodings.MacOriya',
+ 'CFStringEncodings.MacRomanLatin1', 'CFStringEncodings.MacRomanian', 'CFStringEncodings.MacSinhalese',
+ 'CFStringEncodings.MacSymbol', 'CFStringEncodings.MacTamil', 'CFStringEncodings.MacTelugu', 'CFStringEncodings.MacThai',
+ 'CFStringEncodings.MacTibetan', 'CFStringEncodings.MacTurkish', 'CFStringEncodings.MacUkrainian', 'CFStringEncodings.MacVT100',
+ 'CFStringEncodings.MacVietnamese', 'CFStringEncodings.NextStepJapanese', 'CFStringEncodings.ShiftJIS',
+ 'CFStringEncodings.ShiftJIS_X0213', 'CFStringEncodings.ShiftJIS_X0213_MenKuTen', 'CFStringEncodings.UTF7',
+ 'CFStringEncodings.UTF7_IMAP', 'CFStringEncodings.VISCII', 'CFStringEncodings.WindowsArabic',
+ 'CFStringEncodings.WindowsBalticRim', 'CFStringEncodings.WindowsCyrillic', 'CFStringEncodings.WindowsGreek',
+ 'CFStringEncodings.WindowsHebrew', 'CFStringEncodings.WindowsKoreanJohab', 'CFStringEncodings.WindowsLatin2',
+ 'CFStringEncodings.WindowsLatin5', 'CFStringEncodings.WindowsVietnamese', 'CFStringInlineBuffer', 'CFStringRef',
+ 'CFStringTokenizerRef', 'CFSwappedFloat32', 'CFSwappedFloat64', 'CFTimeInterval', 'CFTimeZoneNameStyle',
+ 'CFTimeZoneNameStyle.DaylightSaving', 'CFTimeZoneNameStyle.Generic', 'CFTimeZoneNameStyle.ShortDaylightSaving',
+ 'CFTimeZoneNameStyle.ShortGeneric', 'CFTimeZoneNameStyle.ShortStandard', 'CFTimeZoneNameStyle.Standard', 'CFTimeZoneRef',
+ 'CFTreeContext', 'CFTreeRef', 'CFTypeID', 'CFTypeRef', 'CFURLBookmarkCreationOptions', 'CFURLBookmarkFileCreationOptions',
+ 'CFURLBookmarkResolutionOptions', 'CFURLRef', 'CFUUIDBytes', 'CFUUIDRef', 'CFUserNotificationRef', 'CFWriteStreamRef',
+ 'CFXMLAttributeDeclarationInfo', 'CFXMLAttributeListDeclarationInfo', 'CFXMLDocumentInfo', 'CFXMLDocumentTypeInfo',
+ 'CFXMLElementInfo', 'CFXMLElementTypeDeclarationInfo', 'CFXMLEntityInfo', 'CFXMLEntityReferenceInfo', 'CFXMLExternalID',
+ 'CFXMLNodeRef', 'CFXMLNotationInfo', 'CFXMLParserCallBacks', 'CFXMLParserContext', 'CFXMLParserRef',
+ 'CFXMLProcessingInstructionInfo', 'CFXMLTreeRef'
+ ),
+ /*
+ ** Core Graphics Protocols
+ **
+ */
+ 11 => array(
+ 'CGBitmapContext', 'CGColor', 'CGColorSpace', 'CGContext', 'CGDataConsumer', 'CGDataProvider', 'CGFont', 'CGFunction', 'CGGradient',
+ 'CGImage', 'CGLayer', 'CGPath', 'CGPattern', 'CGPDFArray', 'CGPDFContentStream', 'CGPDFContext', 'CGPDFDictionary', 'CGPDFDocument',
+ 'CGPDFObject', 'CGPDFOperatorTable', 'CGPDFPage', 'CGPDFScanner', 'CGPDFStream', 'CGPDFString', 'CGShading'
+ ),
+
+ /*
+ ** Core Graphics Data Types
+ **
+ */
+ 12 => array(
+ 'CGBitmapContextReleaseDataCallback', 'CGColorRef', 'CGColorSpaceRef', 'CGContextRef', 'CGDataConsumerCallbacks',
+ 'CGDataConsumerRef', 'CGDataProviderRef', 'CGDataProviderDirectCallbacks', 'CGDataProviderSequentialCallbacks', 'CGFontRef',
+ 'CGFontIndex', 'CGGlyph', 'CGFunctionRef', 'CGFunctionCallbacks', 'CGGradientRef', 'CGImageRef', 'CGLayerRef', 'CGPathRef',
+ 'CGMutablePathRef', 'CGPathElement', 'CGPatternRef', 'CGPatternCallbacks', 'CGPDFArrayRef', 'CGPDFContentStreamRef',
+ 'CGPDFDictionaryRef', 'CGPDFDocumentRef', 'CGPDFObjectRef', 'CGPDFBoolean', 'CGPDFInteger', 'CGPDFReal', 'CGPDFOperatorTableRef',
+ 'CGPDFPageRef', 'CGPDFScannerRef', 'CGPDFStreamRef', 'CGPDFStringRef', 'CGShadingRef', 'CGAffineTransform', 'CGFloat', 'CGPoint', 'CGRect',
+ 'CGSize', 'CGVector', 'CGError'
+ ),
+ /*
+ ** UIKit Classes
+ **
+ */
+ 13 => array(
+ 'NSFileProviderExtension', 'NSLayoutConstraint', 'NSLayoutManager', 'NSParagraphStyle', 'NSMutableParagraphStyle',
+ 'NSShadow', 'NSStringDrawingContext', 'NSTextAttachment', 'NSTextContainer', 'NSTextTab', 'UIAcceleration', 'UIAccelerometer',
+ 'UIAccessibilityCustomAction', 'UIAccessibilityElement', 'UIActivity', 'UIAlertAction', 'UIBarItem', 'UIBarButtonItem',
+ 'UITabBarItem', 'UIBezierPath', 'UICollectionViewLayout', 'UICollectionViewFlowLayout', 'UICollectionViewTransitionLayout',
+ 'UICollectionViewLayoutAttributes', 'UICollectionViewLayoutInvalidationContext',
+ 'UICollectionViewFlowLayoutInvalidationContext', 'UICollectionViewUpdateItem', 'UIColor', 'UIDevice', 'UIDictationPhrase',
+ 'UIDocument', 'UIManagedDocument', 'UIDocumentInteractionController', 'UIDynamicAnimator', 'UIDynamicBehavior',
+ 'UIAttachmentBehavior', 'UICollisionBehavior', 'UIDynamicItemBehavior', 'UIGravityBehavior', 'UIPushBehavior', 'UISnapBehavior',
+ 'UIEvent', 'UIFont', 'UIFontDescriptor', 'UIGestureRecognizer', 'UILongPressGestureRecognizer', 'UIPanGestureRecognizer',
+ 'UIScreenEdgePanGestureRecognizer', 'UIPinchGestureRecognizer', 'UIRotationGestureRecognizer', 'UISwipeGestureRecognizer',
+ 'UITapGestureRecognizer', 'UIImage', 'UIImageAsset', 'UIKeyCommand', 'UILexicon', 'UILexiconEntry', 'UILocalNotification',
+ 'UILocalizedIndexedCollation', 'UIMenuController', 'UIMenuItem', 'UIMotionEffect', 'UIInterpolatingMotionEffect',
+ 'UIMotionEffectGroup', 'UINavigationItem', 'UINib', 'UIPasteboard', 'UIPercentDrivenInteractiveTransition', 'UIPopoverController',
+ 'UIPresentationController', 'UIPopoverPresentationController', 'UIPrintFormatter', 'UIMarkupTextPrintFormatter',
+ 'UISimpleTextPrintFormatter', 'UIViewPrintFormatter', 'UIPrintInfo', 'UIPrintInteractionController', 'UIPrintPageRenderer',
+ 'UIPrintPaper', 'UIPrinter', 'UIPrinterPickerController', 'UIResponder', 'UIApplication', 'UIView', 'UIActionSheet',
+ 'UIActivityIndicatorView', 'UIAlertView', 'UICollectionReusableView', 'UICollectionViewCell', 'UIControl', 'UIButton',
+ 'UIDatePicker', 'UIPageControl', 'UIRefreshControl', 'UISegmentedControl', 'UISlider', 'UIStepper', 'UISwitch', 'UITextField',
+ 'UIImageView', 'UIInputView', 'UILabel', 'UINavigationBar', 'UIPickerView', 'UIPopoverBackgroundView', 'UIProgressView',
+ 'UIScrollView', 'UICollectionView', 'UITableView', 'UITextView', 'UISearchBar', 'UITabBar', 'UITableViewCell',
+ 'UITableViewHeaderFooterView', 'UIToolbar', 'UIVisualEffectView', 'UIWebView', 'UIWindow', 'UIViewController',
+ 'UIActivityViewController', 'UIAlertController', 'UICollectionViewController', 'UIDocumentMenuViewController',
+ 'UIDocumentPickerExtensionViewController', 'UIDocumentPickerViewController', 'UIInputViewController', 'UINavigationController',
+ 'UIImagePickerController', 'UIVideoEditorController', 'UIPageViewController', 'UIReferenceLibraryViewController',
+ 'UISearchController', 'UISplitViewController', 'UITabBarController', 'UITableViewController', 'UIScreen', 'UIScreenMode',
+ 'UISearchDisplayController', 'UIStoryboard', 'UIStoryboardSegue', 'UIStoryboardPopoverSegue', 'UITableViewRowAction',
+ 'UITextChecker', 'UITextInputMode', 'UITextInputStringTokenizer', 'UITextPosition', 'UITextRange', 'UITextSelectionRect', 'UITouch',
+ 'UITraitCollection', 'UIUserNotificationAction', 'UIMutableUserNotificationAction', 'UIUserNotificationCategory',
+ 'UIMutableUserNotificationCategory', 'UIUserNotificationSettings', 'UIVisualEffect', 'UIBlurEffect', 'UIVibrancyEffect',
+ 'NSTextStorage', 'UIActivityItemProvider'
+ ),
+ /*
+ ** UIKit Protocols
+ **
+ */
+ 14 => array(
+ 'NSLayoutManagerDelegate', 'NSTextAttachmentContainer', 'NSTextLayoutOrientationProvider', 'NSTextStorageDelegate',
+ 'UIAccelerometerDelegate', 'UIAccessibility', 'UIAccessibilityAction', 'UIAccessibilityContainer', 'UIAccessibilityFocus',
+ 'UIAccessibilityIdentification', 'UIAccessibilityReadingContent', 'UIActionSheetDelegate', 'UIActivityItemSource',
+ 'UIAdaptivePresentationControllerDelegate', 'UIAlertViewDelegate', 'UIAppearance', 'UIAppearanceContainer',
+ 'UIApplicationDelegate', 'UIBarPositioning', 'UIBarPositioningDelegate', 'UICollectionViewDataSource',
+ 'UICollectionViewDelegate', 'UICollectionViewDelegateFlowLayout', 'UICollisionBehaviorDelegate', 'UIContentContainer',
+ 'UICoordinateSpace', 'UIDataSourceModelAssociation', 'UIDocumentInteractionControllerDelegate', 'UIDocumentMenuDelegate',
+ 'UIDocumentPickerDelegate', 'UIDynamicAnimatorDelegate', 'UIDynamicItem', 'UIGestureRecognizerDelegate',
+ 'UIGuidedAccessRestrictionDelegate', 'UIImagePickerControllerDelegate', 'UIInputViewAudioFeedback', 'UIKeyInput',
+ 'UILayoutSupport', 'UINavigationBarDelegate', 'UINavigationControllerDelegate', 'UIObjectRestoration',
+ 'UIPageViewControllerDataSource', 'UIPageViewControllerDelegate', 'UIPickerViewAccessibilityDelegate',
+ 'UIPickerViewDataSource', 'UIPickerViewDelegate', 'UIPopoverBackgroundViewMethods', 'UIPopoverControllerDelegate',
+ 'UIPopoverPresentationControllerDelegate', 'UIPrintInteractionControllerDelegate', 'UIPrinterPickerControllerDelegate',
+ 'UIResponderStandardEditActions', 'UIScrollViewAccessibilityDelegate', 'UIScrollViewDelegate', 'UISearchBarDelegate',
+ 'UISearchControllerDelegate', 'UISearchDisplayDelegate', 'UISearchResultsUpdating', 'UISplitViewControllerDelegate',
+ 'UIStateRestoring', 'UITabBarControllerDelegate', 'UITabBarDelegate', 'UITableViewDataSource', 'UITableViewDelegate',
+ 'UITextDocumentProxy', 'UITextFieldDelegate', 'UITextInput', 'UITextInputDelegate', 'UITextInputTokenizer', 'UITextInputTraits',
+ 'UITextViewDelegate', 'UIToolbarDelegate', 'UITraitEnvironment', 'UIVideoEditorControllerDelegate',
+ 'UIViewControllerAnimatedTransitioning', 'UIViewControllerContextTransitioning', 'UIViewControllerInteractiveTransitioning',
+ 'UIViewControllerRestoration', 'UIViewControllerTransitionCoordinator', 'UIViewControllerTransitionCoordinatorContext',
+ 'UIViewControllerTransitioningDelegate', 'UIWebViewDelegate'
+ ),
+ /*
+ ** AppKit Classes
+ **
+ */
+ 15 => array(
+ 'NSAccessibilityElement', 'NSAlert', 'NSAnimation', 'NSViewAnimation', 'NSAnimationContext', 'NSAppearance',
+ 'NSBezierPath', 'NSCell', 'NSActionCell', 'NSButtonCell', 'NSMenuItemCell', 'NSPopUpButtonCell', 'NSDatePickerCell', 'NSFormCell',
+ 'NSLevelIndicatorCell', 'NSPathCell', 'NSSegmentedCell', 'NSSliderCell', 'NSStepperCell', 'NSTextFieldCell', 'NSComboBoxCell',
+ 'NSPathComponentCell', 'NSSearchFieldCell', 'NSSecureTextFieldCell', 'NSTableHeaderCell', 'NSTokenFieldCell', 'NSBrowserCell',
+ 'NSImageCell', 'NSTextAttachmentCell', 'NSColor', 'NSColorList', 'NSColorPicker', 'NSColorSpace', 'NSController', 'NSObjectController',
+ 'NSArrayController', 'NSDictionaryController', 'NSTreeController', 'NSUserDefaultsController', 'NSCursor', 'NSDockTile',
+ 'NSDocument', 'NSPersistentDocument', 'NSDocumentController', 'NSDraggingImageComponent', 'NSDraggingItem', 'NSDraggingSession',
+ 'NSEvent', 'NSFont', 'NSFontCollection', 'NSMutableFontCollection', 'NSFontDescriptor', 'NSFontManager', 'NSGestureRecognizer',
+ 'NSClickGestureRecognizer', 'NSMagnificationGestureRecognizer', 'NSPanGestureRecognizer', 'NSPressGestureRecognizer',
+ 'NSRotationGestureRecognizer', 'NSGlyphGenerator', 'NSGlyphInfo', 'NSGradient', 'NSGraphicsContext', 'NSHelpManager', 'NSImage',
+ 'NSImageRep', 'NSBitmapImageRep', 'NSCachedImageRep', 'NSCIImageRep', 'NSCustomImageRep', 'NSEPSImageRep', 'NSPDFImageRep',
+ 'NSPICTImageRep', 'NSInputManager', 'NSInputServer', 'NSMediaLibraryBrowserController',
+ 'NSMenu', 'NSMenuItem', 'NSMovie', 'NSNib', 'NSNibConnector', 'NSNibControlConnector', 'NSNibOutletConnector', 'NSOpenGLContext',
+ 'NSOpenGLPixelBuffer', 'NSOpenGLPixelFormat', 'NSPageLayout', 'NSPasteboard',
+ 'NSPasteboardItem', 'NSPathControlItem', 'NSPDFInfo', 'NSPDFPanel', 'NSPredicateEditorRowTemplate', 'NSPrinter', 'NSPrintInfo',
+ 'NSPrintOperation', 'NSPrintPanel', 'NSResponder', 'NSApplication', 'NSDrawer', 'NSPopover', 'NSView', 'NSBox', 'NSClipView',
+ 'NSCollectionView', 'NSControl', 'NSBrowser', 'NSButton', 'NSPopUpButton', 'NSStatusBarButton', 'NSColorWell', 'NSDatePicker',
+ 'NSImageView', 'NSLevelIndicator', 'NSMatrix', 'NSForm', 'NSPathControl', 'NSRuleEditor', 'NSPredicateEditor', 'NSScroller',
+ 'NSSegmentedControl', 'NSSlider', 'NSStepper', 'NSTableView', 'NSOutlineView', 'NSTextField', 'NSComboBox', 'NSSearchField',
+ 'NSSecureTextField', 'NSTokenField', 'NSMenuView', 'NSMovieView', 'NSOpenGLView', 'NSProgressIndicator', 'NSQuickDrawView',
+ 'NSRulerView', 'NSScrollView', 'NSSplitView', 'NSStackView', 'NSTableCellView', 'NSTableHeaderView', 'NSTableRowView', 'NSTabView',
+ 'NSText', 'NSTextView', 'NSVisualEffectView', 'NSViewController', 'NSCollectionViewItem', 'NSPageController',
+ 'NSSplitViewController', 'NSTabViewController', 'NSTitlebarAccessoryViewController', 'NSWindow', 'NSPanel', 'NSColorPanel',
+ 'NSFontPanel', 'NSSavePanel', 'NSOpenPanel', 'NSWindowController', 'NSRulerMarker', 'NSRunningApplication', 'NSScreen',
+ 'NSSharingService', 'NSSharingServicePicker', 'NSSound', 'NSSpeechRecognizer', 'NSSpeechSynthesizer', 'NSSpellChecker',
+ 'NSSplitViewItem', 'NSStatusBar', 'NSStatusItem', 'NSStoryboard', 'NSStoryboardSegue', 'NSTableColumn', 'NSTabViewItem',
+ 'NSTextAlternatives', 'NSTextBlock', 'NSTextTable', 'NSTextTableBlock', 'NSTextFinder',
+ 'NSTextInputContext', 'NSTextList', 'NSToolbar', 'NSToolbarItem', 'NSToolbarItemGroup', 'NSTouch', 'NSTrackingArea',
+ 'NSTreeNode', 'NSTypesetter', 'NSATSTypesetter', 'NSWorkspace', 'CAOpenGLLayer',
+ 'NSOpenGLLayer'
+ ),
+ /*
+ ** AppKit Protocols
+ **
+ */
+ 16 => array(
+ 'NSAccessibility', 'NSAccessibility Informal', 'NSAccessibilityButton', 'NSAccessibilityCheckBox',
+ 'NSAccessibilityContainsTransientUI', 'NSAccessibilityGroup', 'NSAccessibilityImage',
+ 'NSAccessibilityLayoutArea', 'NSAccessibilityLayoutItem', 'NSAccessibilityList', 'NSAccessibilityNavigableStaticText',
+ 'NSAccessibilityOutline', 'NSAccessibilityProgressIndicator', 'NSAccessibilityRadioButton', 'NSAccessibilityRow',
+ 'NSAccessibilitySlider', 'NSAccessibilityStaticText', 'NSAccessibilityStepper', 'NSAccessibilitySwitch', 'NSAccessibilityTable',
+ 'NSAlertDelegate', 'NSAnimatablePropertyContainer', 'NSAnimationDelegate', 'NSAppearanceCustomization', 'NSApplicationDelegate',
+ 'NSBrowserDelegate', 'NSChangeSpelling', 'NSCollectionViewDelegate', 'NSColorPickingCustom', 'NSColorPickingDefault',
+ 'NSComboBoxCellDataSource', 'NSComboBoxDataSource', 'NSComboBoxDelegate', 'NSControlTextEditingDelegate',
+ 'NSDatePickerCellDelegate', 'NSDictionaryControllerKeyValuePair', 'NSDraggingDestination', 'NSDraggingInfo', 'NSDraggingSource',
+ 'NSDrawerDelegate', 'NSEditor', 'NSEditorRegistration', 'NSFontPanelValidation', 'NSGestureRecognizerDelegate', 'NSGlyphStorage',
+ 'NSIgnoreMisspelledWords', 'NSImageDelegate', 'NSKeyValueBindingCreation', 'NSLayerDelegateContentsScaleUpdating',
+ 'NSMatrixDelegate', 'NSMenuDelegate', 'NSMenuValidation', 'NSNibAwaking', 'NSOpenSavePanelDelegate',
+ 'NSOutlineViewDataSource', 'NSOutlineViewDelegate', 'NSPageControllerDelegate', 'NSPasteboardItemDataProvider',
+ 'NSPasteboardReading', 'NSPasteboardWriting', 'NSPathCellDelegate', 'NSPathControlDelegate', 'NSPlaceholders', 'NSPopoverDelegate',
+ 'NSPrintPanelAccessorizing', 'NSRuleEditorDelegate', 'NSSeguePerforming', 'NSServicesMenuRequestor', 'NSSharingServiceDelegate',
+ 'NSSharingServicePickerDelegate', 'NSSoundDelegate', 'NSSpeechRecognizerDelegate', 'NSSpeechSynthesizerDelegate',
+ 'NSSplitViewDelegate', 'NSStackViewDelegate', 'NSTabViewDelegate', 'NSTableViewDataSource', 'NSTableViewDelegate',
+ 'NSTextDelegate', 'NSTextFieldDelegate', 'NSTextFinderBarContainer', 'NSTextFinderClient', 'NSTextInput',
+ 'NSTextInputClient', 'NSTextViewDelegate',
+ 'NSTokenFieldCellDelegate', 'NSTokenFieldDelegate', 'NSToolTipOwner', 'NSToolbarDelegate', 'NSToolbarItemValidation',
+ 'NSUserInterfaceItemIdentification', 'NSUserInterfaceItemSearchDataSource', 'NSUserInterfaceItemSearching',
+ 'NSUserInterfaceValidations', 'NSValidatedUserInterfaceItem', 'NSViewControllerPresentationAnimator', 'NSWindowDelegate',
+ 'NSWindowRestoration', 'NSWindowScripting'
+ )
+ ),
+ 'SYMBOLS' => array(
+ # Operators
+ 1 => array(
+ '!=', '!==', '%', '%=', '&', '&&', '&*', '&+', '&-', '&=', '*', '*=', '+', '++', '+=', '-', '--', '-=', '...', '..<', '/',
+ '/=', '<', '<<', '<<=', '<=', '==', '===', '>', '>=', '>>', '>>=', '??', '^', '^=', '|', '|=', '||', '~=', '~>', '!', '~'
+ ),
+ # Structure
+ 2 => array(
+ '(', ')', '[', ']', '{', '}', ',', ';', ':'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true,
+ 10 => true,
+ 11 => true,
+ 12 => true,
+ 13 => true,
+ 14 => true,
+ 15 => true,
+ 16 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #B833A1;', // Keywords
+ 2 => 'color: #B833A1;', // Attributes
+ 3 => 'color: #508187;', // Builtin Functions
+ 4 => 'color: #6F41A7;', // Types
+ 5 => 'color: #6F41A7;',
+ 6 => 'color: #6F41A7;',
+ 7 => 'color: #6F41A7;',
+ 8 => 'color: #6F41A7;',
+ 9 => 'color: #6F41A7;',
+ 10 => 'color: #6F41A7;',
+ 11 => 'color: #6F41A7;',
+ 12 => 'color: #6F41A7;',
+ 13 => 'color: #6F41A7;',
+ 14 => 'color: #6F41A7;',
+ 15 => 'color: #6F41A7;',
+ 16 => 'color: #6F41A7;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008312;',
+ 'MULTI' => 'color: #008312;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #C41A16;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: black;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #C41A16;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #1C00CF;',
+ 1 => 'color: #1C00CF;',
+ 2 => 'color: #1C00CF;',
+ 3 => 'color: #1C00CF;',
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #508187;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: black;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => '',
+ 9 => '',
+ 10 => '',
+ 11 => '',
+ 12 => '',
+ 13 => '',
+ 14 => '',
+ 15 => '',
+ 16 => '',
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/systemverilog.php b/platform/www/vendor/geshi/geshi/src/geshi/systemverilog.php
new file mode 100644
index 0000000..6d3124b
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/systemverilog.php
@@ -0,0 +1,315 @@
+<?php
+/************************************************************************************
+ * systemverilog.php
+ * -------
+ * Author: Sean O'Boyle
+ * Copyright: (C) 2008 IntelligentDV
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/06/25
+ *
+ * SystemVerilog IEEE 1800-2009(draft8) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/06/25 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2008/06/25)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ ************************************************************************
+ * Title: SystemVerilog Language Keywords File for GeSHi
+ * Description: This file contains the SV keywords defined in the
+ * IEEE1800-2009 Draft Standard in the format expected by
+ * GeSHi.
+ *
+ * Original Author: Sean O'Boyle
+ * Contact: seanoboyle@intelligentdv.com
+ * Company: Intelligent Design Verification
+ * Company URL: http://intelligentdv.com
+ *
+ * Download the most recent version here:
+ * http://intelligentdv.com/downloads
+ *
+ * File Bugs Here: http://bugs.intelligentdv.com
+ * Project: SyntaxFiles
+ *
+ * File: systemverilog.php
+ * $LastChangedBy$
+ * $LastChangedDate$
+ * $LastChangedRevision$
+ *
+ ************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'SystemVerilog',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ // system tasks
+ 1 => array(
+ 'acos','acosh','asin','asinh','assertfailoff','assertfailon',
+ 'assertkill','assertnonvacuouson','assertoff','asserton',
+ 'assertpassoff','assertpasson','assertvacuousoff','async$and$array',
+ 'async$and$plane','async$nand$array','async$nand$plane',
+ 'async$nor$array','async$nor$plane','async$or$array',
+ 'async$or$plane','atan','atan2','atanh','bits','bitstoreal',
+ 'bitstoshortreal','cast','ceil','changed','changed_gclk',
+ 'changing_gclk','clog2','cos','cosh','countones','coverage_control',
+ 'coverage_get','coverage_get_max','coverage_merge','coverage_save',
+ 'dimensions','display','displayb','displayh','displayo',
+ 'dist_chi_square','dist_erlang','dist_exponential','dist_normal',
+ 'dist_poisson','dist_t','dist_uniform','dumpall','dumpfile',
+ 'dumpflush','dumplimit','dumpoff','dumpon','dumpports',
+ 'dumpportsall','dumpportsflush','dumpportslimit','dumpportsoff',
+ 'dumpportson','dumpvars','error','exit','exp','falling_gclk',
+ 'fclose','fdisplay','fdisplayb','fdisplayh','fdisplayo','fell',
+ 'fell_gclk','feof','ferror','fflush','fgetc','fgets','finish',
+ 'floor','fmonitor','fmonitorb','fmonitorh','fmonitoro','fopen',
+ 'fread','fscanf','fseek','fstrobe','fstrobeb','fstrobeh','fstrobeo',
+ 'ftell','future_gclk','fwrite','fwriteb','fwriteh','fwriteo',
+ 'get_coverage','high','hypot','increment','info','isunbounded',
+ 'isunknown','itor','left','ln','load_coverage_db','log10','low',
+ 'monitor','monitorb','monitorh','monitoro','monitoroff','monitoron',
+ 'onehot','onehot0','past','past_gclk','pow','printtimescale',
+ 'q_add','q_exam','q_full','q_initialize','q_remove','random',
+ 'readmemb','readmemh','realtime','realtobits','rewind','right',
+ 'rising_gclk','rose','rose_gclk','rtoi','sampled',
+ 'set_coverage_db_name','sformat','sformatf','shortrealtobits',
+ 'signed','sin','sinh','size','sqrt','sscanf','stable','stable_gclk',
+ 'steady_gclk','stime','stop','strobe','strobeb','strobeh','strobeo',
+ 'swrite','swriteb','swriteh','swriteo','sync$and$array',
+ 'sync$and$plane','sync$nand$array','sync$nand$plane',
+ 'sync$nor$array','sync$nor$plane','sync$or$array','sync$or$plane',
+ 'system','tan','tanh','test$plusargs','time','timeformat',
+ 'typename','ungetc','unpacked_dimensions','unsigned',
+ 'value$plusargs','warning','write','writeb','writeh','writememb',
+ 'writememh','writeo',
+ ),
+ // compiler directives
+ 2 => array(
+ '`__FILE__', '`__LINE__', '`begin_keywords', '`case', '`celldefine',
+ '`endcelldefine', '`default_nettype', '`define', '`default', '`else',
+ '`elsif', '`end_keywords', '`endfor', '`endif',
+ '`endprotect', '`endswitch', '`endwhile', '`for', '`format',
+ '`if', '`ifdef', '`ifndef', '`include', '`let',
+ '`line', '`nounconnected_drive', '`pragma', '`protect', '`resetall',
+ '`switch', '`timescale', '`unconnected_drive', '`undef', '`undefineall',
+ '`while'
+ ),
+ // keywords
+ 3 => array(
+ 'assert', 'assume', 'cover', 'expect', 'disable',
+ 'iff', 'binsof', 'intersect', 'first_match', 'throughout',
+ 'within', 'coverpoint', 'cross', 'wildcard', 'bins',
+ 'ignore_bins', 'illegal_bins', 'genvar', 'if', 'else',
+ 'unique', 'priority', 'matches', 'default', 'forever',
+ 'repeat', 'while', 'for', 'do', 'foreach',
+ 'break', 'continue', 'return', 'pulsestyle_onevent', 'pulsestyle_ondetect',
+ 'noshowcancelled', 'showcancelled', 'ifnone', 'posedge', 'negedge',
+ 'edge', 'wait', 'wait_order', 'timeunit', 'timeprecision',
+ 's', 'ms', 'us', 'ns',
+ 'ps', 'fs', 'step', 'new', 'extends',
+ 'this', 'super', 'protected', 'local', 'rand',
+ 'randc', 'bind', 'constraint', 'solve', 'before',
+ 'dist', 'inside', 'with', 'virtual', 'extern',
+ 'pure', 'forkjoin', 'design', 'instance', 'cell',
+ 'liblist', 'use', 'library', 'incdir', 'include',
+ 'modport', 'sync_accept_on', 'reject_on', 'accept_on',
+ 'sync_reject_on', 'restrict', 'let', 'until', 'until_with',
+ 'unique0', 'eventually', 's_until', 's_always', 's_eventually',
+ 's_nexttime', 's_until_with', 'global', 'untyped', 'implies',
+ 'weak', 'strong', 'nexttime'
+ ),
+ // block keywords
+ 4 => array(
+ 'begin', 'end', 'package', 'endpackage', 'macromodule',
+ 'module', 'endmodule', 'generate', 'endgenerate', 'program',
+ 'endprogram', 'class', 'endclass', 'function', 'endfunction',
+ 'case', 'casex', 'casez', 'randcase', 'endcase',
+ 'interface', 'endinterface', 'clocking', 'endclocking', 'task',
+ 'endtask', 'primitive', 'endprimitive', 'fork', 'join',
+ 'join_any', 'join_none', 'covergroup', 'endgroup', 'checker',
+ 'endchecker', 'property', 'endproperty', 'randsequence', 'sequence',
+ 'endsequence', 'specify', 'endspecify', 'config', 'endconfig',
+ 'table', 'endtable', 'initial', 'final', 'always',
+ 'always_comb', 'always_ff', 'always_latch', 'alias', 'assign',
+ 'force', 'release'
+ ),
+
+ // types
+ 5 => array(
+ 'parameter', 'localparam', 'specparam', 'input', 'output',
+ 'inout', 'ref', 'byte', 'shortint', 'int',
+ 'integer', 'longint', 'time', 'bit', 'logic',
+ 'reg', 'supply0', 'supply1', 'tri', 'triand',
+ 'trior', 'trireg', 'tri0', 'tri1', 'wire',
+ 'uwire', 'wand', 'wor', 'signed', 'unsigned',
+ 'shortreal', 'real', 'realtime', 'type', 'void',
+ 'struct', 'union', 'tagged', 'const', 'var',
+ 'automatic', 'static', 'packed', 'vectored', 'scalared',
+ 'typedef', 'enum', 'string', 'chandle', 'event',
+ 'null', 'pullup', 'pulldown', 'cmos', 'rcmos',
+ 'nmos', 'pmos', 'rnmos', 'rpmos', 'and',
+ 'nand', 'or', 'nor', 'xor', 'xnor',
+ 'not', 'buf', 'tran', 'rtran', 'tranif0',
+ 'tranif1', 'rtranif0', 'rtranif1', 'bufif0', 'bufif1',
+ 'notif0', 'notif1', 'strong0', 'strong1', 'pull0',
+ 'pull1', 'weak0', 'weak1', 'highz0', 'highz1',
+ 'small', 'medium', 'large'
+ ),
+
+ // DPI
+ 6 => array(
+ 'DPI', 'DPI-C', 'import', 'export', 'context'
+ ),
+
+ // stdlib
+ 7 => array(
+ 'randomize', 'mailbox', 'semaphore', 'put', 'get',
+ 'try_put', 'try_get', 'peek', 'try_peek', 'process',
+ 'state', 'self', 'status', 'kill', 'await',
+ 'suspend', 'resume', 'size', 'delete', 'insert',
+ 'num', 'first', 'last', 'next', 'prev',
+ 'pop_front', 'pop_back', 'push_front', 'push_back', 'find',
+ 'find_index', 'find_first', 'find_last', 'find_last_index', 'min',
+ 'max', 'unique_index', 'reverse', 'sort', 'rsort',
+ 'shuffle', 'sum', 'product', 'List', 'List_Iterator',
+ 'neq', 'eq', 'data', 'empty', 'front',
+ 'back', 'start', 'finish', 'insert_range', 'erase',
+ 'erase_range', 'set', 'swap', 'clear', 'purge'
+ ),
+
+ // key_deprecated
+ 8 => array(
+ 'defparam', 'deassign', 'TODO'
+ ),
+
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%',
+ '^', '&', '|', '~',
+ '?', ':',
+ '#', '<<', '<<<',
+ '>', '<', '>=', '<=',
+ '@', ';', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #996666; font-weight: bold;',
+ 2 => 'color: #336600; font-weight: bold;',
+ 3 => 'color: #996600; font-weight: bold;',
+ 4 => 'color: #000033; font-weight: bold;',
+ 5 => 'color: #330033; font-weight: bold;',
+ 6 => 'color: #996600; font-weight: bold;',
+ 7 => 'color: #CC9900; font-weight: bold;',
+ 8 => 'color: #990000; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #00008B; font-style: italic;',
+ 'MULTI' => 'color: #00008B; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #9F79EE'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #9F79EE;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #FF00FF;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0055;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #5D478B;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #ff0055;',
+ 1 => 'color: #ff0055;',
+ 2 => 'color: #ff0055;',
+ 3 => 'color: #ff0055;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => ''
+ ),
+ 'REGEXPS' => array(
+ // integer
+ 0 => "\d'[bdh][0-9_a-fA-FxXzZ]+",
+ // realtime
+ 1 => "\d*\.\d+[munpf]?s",
+ // time s, ms, us, ns, ps, of fs
+ 2 => "\d+[munpf]?s",
+ // real
+ 3 => "\d*\.\d+"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => ''
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true
+ ),
+ 'TAB_WIDTH' => 3,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'DISALLOWED_BEFORE' => '(?<=$)'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/tcl.php b/platform/www/vendor/geshi/geshi/src/geshi/tcl.php
new file mode 100644
index 0000000..ddaf134
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/tcl.php
@@ -0,0 +1,192 @@
+<?php
+/*************************************************************************************
+ * tcl.php
+ * ---------------------------------
+ * Author: Reid van Melle (rvanmelle@gmail.com)
+ * Copyright: (c) 2004 Reid van Melle (sorry@nowhere)
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/05/05
+ *
+ * TCL/iTCL language file for GeSHi.
+ *
+ * This was thrown together in about an hour so I don't expect
+ * really great things. However, it is a good start. I never
+ * got a change to try out the iTCL or object-based support but
+ * this is not widely used anyway.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2006/05/05 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2006/05/05)
+ * -------------------------
+ * - Get TCL built-in special variables highlighted with a new color..
+ * currently, these are listed in //special variables in the keywords
+ * section, but they get covered by the general REGEXP for symbols
+ * - General cleanup, testing, and verification
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'TCL',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 1 => '/(?:^|(?<=\{|;))\s*#(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //2 => '/{[^}\n]+}/'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ /*
+ * Set 1: reserved words
+ * http://python.org/doc/current/ref/keywords.html
+ */
+ 1 => array(
+ 'proc', 'global', 'upvar', 'if', 'then', 'else', 'elseif', 'for', 'foreach',
+ 'break', 'continue', 'while', 'set', 'eval', 'case', 'in', 'switch',
+ 'default', 'exit', 'error', 'return', 'uplevel', 'loop',
+ 'for_array_keys', 'for_recursive_glob', 'for_file', 'unwind_protect',
+ 'expr', 'catch', 'namespace', 'rename', 'variable',
+ // itcl
+ 'method', 'itcl_class', 'public', 'protected'),
+
+ /*
+ * Set 2: builtins
+ * http://asps.activatestate.com/ASPN/docs/ActiveTcl/8.4/tcl/tcl_2_contents.htm
+ */
+ 2 => array(
+ // string handling
+ 'append', 'binary', 'format', 're_syntax', 'regexp', 'regsub',
+ 'scan', 'string', 'subst',
+ // list handling
+ 'concat', 'join', 'lappend', 'lindex', 'list', 'llength', 'lrange',
+ 'lreplace', 'lsearch', 'lset', 'lsort', 'split',
+ // procedures and output
+ 'incr', 'close', 'eof', 'fblocked', 'fconfigure', 'fcopy', 'file',
+ 'fileevent', 'flush', 'gets', 'open', 'puts', 'read', 'seek',
+ 'socket', 'tell',
+ // packages and source files
+ 'load', 'loadTk', 'package', 'pgk::create', 'pgk_mkIndex', 'source',
+ // interpreter routines
+ 'bgerror', 'history', 'info', 'interp', 'memory', 'unknown',
+ // library routines
+ 'enconding', 'http', 'msgcat',
+ // system related
+ 'cd', 'clock', 'exec', 'glob', 'pid', 'pwd', 'time',
+ // platform specified
+ 'dde', 'registry', 'resource',
+ // special variables
+ '$argc', '$argv', '$errorCode', '$errorInfo', '$argv0',
+ '$auto_index', '$auto_oldpath', '$auto_path', '$env',
+ '$tcl_interactive', '$tcl_libpath', '$tcl_library',
+ '$tcl_pkgPath', '$tcl_platform', '$tcl_precision', '$tcl_traceExec',
+ ),
+
+ /*
+ * Set 3: standard library
+ */
+ 3 => array(
+ 'comment', 'filename', 'library', 'packagens', 'tcltest', 'tclvars',
+ ),
+
+ /*
+ * Set 4: special methods
+ */
+// 4 => array(
+// )
+
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '$', '*', '&', '%', '!', ';', '<', '>', '?'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+// 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #ff7700;font-weight:bold;', // Reserved
+ 2 => 'color: #008000;', // Built-ins + self
+ 3 => 'color: #dc143c;', // Standard lib
+// 4 => 'color: #0000cd;' // Special methods
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+// 2 => 'color: #483d8b;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: black;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #483d8b;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff4500;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: black;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #ff3333;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+// 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '::'
+ ),
+ 'REGEXPS' => array(
+ //Special variables
+ 0 => '[\\$]+[a-zA-Z_][a-zA-Z0-9_]*',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'COMMENTS' => array(
+ 'DISALLOWED_BEFORE' => '\\'
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/tclegg.php b/platform/www/vendor/geshi/geshi/src/geshi/tclegg.php
new file mode 100644
index 0000000..725e1e2
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/tclegg.php
@@ -0,0 +1,501 @@
+<?php
+/*************************************************************************************
+ * tclegg.php
+ * ---------------------------------
+ * Author: Reid van Melle (rvanmelle@gmail.com)
+ * Copyright: (c) 2004 Reid van Melle (sorry@nowhere)
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/05/05
+ *
+ * TCL/iTCL language file for GeSHi.
+ *
+ * This was thrown together in about an hour so I don't expect
+ * really great things. However, it is a good start. I never
+ * got a change to try out the iTCL or object-based support but
+ * this is not widely used anyway.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2006/05/05 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2006/05/05)
+ * -------------------------
+ * - Get TCL built-in special variables highlighted with a new color..
+ * currently, these are listed in //special variables in the keywords
+ * section, but they get covered by the general REGEXP for symbols
+ * - General cleanup, testing, and verification
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'TCLEGG',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 1 => '/(?<!\\\\)#(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //2 => '/{[^}\n]+}/'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', "'"),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ /*
+ * Set 1: reserved words
+ * http://python.org/doc/current/ref/keywords.html
+ */
+ 1 => array(
+ 'break',
+ 'case',
+ 'catch',
+ 'continue',
+ 'default',
+ 'else',
+ 'elseif',
+ 'error',
+ 'eval',
+ 'exit',
+ 'expr',
+ 'for',
+ 'for_array_keys',
+ 'for_file',
+ 'for_recursive_glob',
+ 'foreach',
+ 'global',
+ 'if',
+ 'in',
+ 'itcl_class',
+ 'loop',
+ 'method',
+ 'namespace',
+ 'proc',
+ 'protected',
+ 'public',
+ 'rename',
+ 'return',
+ 'set',
+ 'switch',
+ 'then',
+ 'unwind_protect',
+ 'uplevel',
+ 'upvar',
+ 'variable',
+ 'while',
+ ),
+
+ /*
+ * Set 2: builtins
+ * http://asps.activatestate.com/ASPN/docs/ActiveTcl/8.4/tcl/tcl_2_contents.htm
+ */
+ 2 => array(
+ // string handling
+ 'append', 'binary', 'format', 're_syntax', 'regexp', 'regsub',
+ 'scan', 'string', 'subst',
+ // list handling
+ 'concat', 'join', 'lappend', 'lindex', 'list', 'llength', 'lrange',
+ 'lreplace', 'lsearch', 'lset', 'lsort', 'split',
+ // procedures and output
+ 'incr', 'close', 'eof', 'fblocked', 'fconfigure', 'fcopy', 'file',
+ 'fileevent', 'flush', 'gets', 'open', 'puts', 'read', 'seek',
+ 'socket', 'tell',
+ // packages and source files
+ 'load', 'loadTk', 'package', 'pgk::create', 'pgk_mkIndex', 'source',
+ // interpreter routines
+ 'bgerror', 'history', 'info', 'interp', 'memory', 'unknown',
+ // library routines
+ 'enconding', 'http', 'msgcat',
+ // system related
+ 'cd', 'clock', 'exec', 'glob', 'pid', 'pwd', 'time',
+ // platform specified
+ 'dde', 'registry', 'resource',
+ // special variables
+ '$argc', '$argv', '$errorCode', '$errorInfo', '$argv0',
+ '$auto_index', '$auto_oldpath', '$auto_path', '$env',
+ '$tcl_interactive', '$tcl_libpath', '$tcl_library',
+ '$tcl_pkgPath', '$tcl_platform', '$tcl_precision', '$tcl_traceExec',
+ ),
+
+ /*
+ * Set 3: standard library
+ * Replaced by binds
+ */
+ 3 => array(
+ //'comment', 'filename', 'library', 'packagens', 'tcltest', 'tclvars',
+ 'act',
+ 'away',
+ 'bcst',
+ 'bot',
+ 'chat',
+ 'chjn',
+ 'chof',
+ 'chon',
+ 'chpt',
+ 'cron',
+ 'ctcp',
+ 'ctcr',
+ 'dcc',
+ 'disc',
+ 'evnt',
+ 'fil',
+ 'filt',
+ 'flud',
+ 'kick',
+ 'link',
+ 'log',
+ 'lost',
+ 'mode',
+ 'msg',
+ 'msgm',
+ 'need',
+ 'nick',
+ 'nkch',
+ 'notc',
+ 'note',
+ 'out',
+ 'part',
+ 'pub',
+ 'pubm',
+ 'raw',
+ 'rcvd',
+ 'rejn',
+ 'sent',
+ 'sign',
+ 'splt',
+ 'topc',
+ 'tout',
+ 'unld',
+ 'wall',
+ ),
+
+ /*
+ * Set 4: tcl-commands (eggdrop dedicated)
+ */
+ 4 => array(
+ 'addbot',
+ 'addchanrec',
+ 'adduser',
+ 'assoc',
+
+ 'backup',
+ 'banlist',
+ 'bind',
+ 'binds',
+ 'boot',
+ 'botattr',
+ 'botishalfop',
+ 'botisop',
+ 'botisvoice',
+ 'botlist',
+ 'botonchan',
+ 'bots',
+
+ 'callevent',
+ 'chanbans',
+ 'chanexempts',
+ 'chaninvites',
+ 'chanlist',
+ 'channel',
+ 'channels',
+ 'chansettype',
+ 'chattr',
+ 'chhandle',
+ 'clearqueue',
+ 'compressfile',
+ 'connect',
+ 'console',
+ 'control',
+ 'countusers',
+ 'cp',
+ 'ctime',
+
+ 'dccbroadcast',
+ 'dccdumpfile',
+ 'dcclist',
+ 'dccputchan',
+ 'dccsend',
+ 'dccsimul',
+ 'dccused',
+ 'decrypt',
+ 'delchanrec',
+ 'delhost',
+ 'deludef',
+ 'deluser',
+ 'die',
+ 'dnslookup',
+ 'dumpfile',
+ 'duration',
+
+ 'echo',
+ 'encpass',
+ 'encrypt',
+ 'erasenotes',
+ 'exemptlist',
+
+ 'filesend',
+ 'finduser',
+ 'flushmode',
+
+ 'getchan',
+ 'getchanhost',
+ 'getchanidle',
+ 'getchaninfo',
+ 'getchanjoin',
+ 'getchanmode',
+ 'getdccaway',
+ 'getdccidle',
+ 'getdesc',
+ 'getdirs',
+ 'getfileq',
+ 'getfiles',
+ 'getfilesendtime',
+ 'getflags',
+ 'getlink',
+ 'getowner',
+ 'getpwd',
+ 'getting',
+ 'getudefs',
+ 'getuser',
+
+ 'hand',
+ 'handonchan',
+
+ 'idx',
+ 'ignorelist',
+ 'invitelist',
+ 'isban',
+ 'isbansticky',
+ 'isbotnick',
+ 'ischanban',
+ 'ischanexempt',
+ 'ischaninvite',
+ 'ischanjuped',
+ 'iscompressed',
+ 'isdynamic',
+ 'isexempt',
+ 'isexemptsticky',
+ 'ishalfop',
+ 'isignore',
+ 'isinvite',
+ 'isinvitesticky',
+ 'islinked',
+ 'isop',
+ 'ispermban',
+ 'ispermexempt',
+ 'isperminvite',
+ 'isvoice',
+
+ 'jump',
+
+ 'killassoc',
+ 'killban',
+ 'killchanban',
+ 'killchanexempt',
+ 'killchaninvite',
+ 'killdcc',
+ 'killexempt',
+ 'killignore',
+ 'killinvite',
+ 'killtimer',
+ 'killutimer',
+
+ 'listen',
+ 'listnotes',
+ 'loadchannels',
+ 'loadhelp',
+ 'loadmodule',
+ 'logfile',
+
+ 'maskhost',
+ 'matchaddr',
+ 'matchattr',
+ 'matchban',
+ 'matchcidr',
+ 'matchexempt',
+ 'matchinvite',
+ 'matchstr',
+ 'md',
+ 'mkdir',
+ 'modules',
+ 'mv',
+ 'myip',
+
+ 'newban',
+ 'newchanban',
+ 'newchanexempt',
+ 'newchaninvite',
+ 'newexempt',
+ 'newignore',
+ 'newinvite',
+ 'notes',
+
+ 'onchan',
+ 'onchansplit',
+
+ 'passwdok',
+ 'pushmode',
+ 'putallbots',
+ 'putbot',
+ 'putcmdlog',
+ 'putdcc',
+ 'puthelp',
+ 'putkick',
+ 'putlog',
+ 'putloglev',
+ 'putnow',
+ 'putquick',
+ 'putserv',
+ 'putxferlog',
+
+ 'queuesize',
+
+ 'rand',
+ 'rehash',
+ 'reload',
+ 'reloadhelp',
+ 'renudef',
+ 'resetbans',
+ 'resetchan',
+ 'resetchanidle',
+ 'resetchanjoin',
+ 'resetexempts',
+ 'resetinvites',
+ 'restart',
+ 'rmdir',
+
+ 'save',
+ 'savechannels',
+ 'sendnote',
+ 'setchan',
+ 'setchaninfo',
+ 'setdccaway',
+ 'setdesc',
+ 'setflags',
+ 'setlink',
+ 'setowner',
+ 'setpwd',
+ 'setudef',
+ 'setuser',
+ 'stickban',
+ 'stickexempt',
+ 'stickinvite',
+ 'storenote',
+ 'strftime',
+ 'strip',
+ 'stripcodes',
+
+ 'timer',
+ 'timers',
+ 'topic',
+ 'traffic',
+
+ 'unames',
+ 'unbind',
+ 'uncompressfile',
+ 'unixtime',
+ 'unlink',
+ 'unloadhelp',
+ 'unloadmodule',
+ 'unstickban',
+ 'unstickexempt',
+ 'unstickinvite',
+ 'userlist',
+ 'utimer',
+ 'utimers',
+
+ 'validchan',
+ 'valididx',
+ 'validuser',
+
+ 'washalfop',
+ 'wasop',
+ 'whom',
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '$', '*', '&', '%', '!', ';', '<', '>', '?'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #ff7700;font-weight:bold;', // Reserved
+ 2 => 'color: #008000;', // Built-ins + self
+ 3 => 'color: #dc143c;', // Standard lib
+ 4 => 'color: #0000cd;' // Special methods
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+// 2 => 'color: #483d8b;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: black;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #483d8b;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff4500;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: black;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #ff3333;'
+ ),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => 'http://wiki.tcl.tk/{FNAMEL}',
+ 2 => 'http://wiki.tcl.tk/{FNAMEUF}',
+ 3 => 'http://wiki.eggdrop.fr/Binds#{FNAMEU}',
+ 4 => 'http://wiki.eggdrop.fr/{FNAMEUF}'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '::'
+ ),
+ 'REGEXPS' => array(
+ //Special variables
+ 0 => '[\\$]+[a-zA-Z_][a-zA-Z0-9_]*',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'PARSER_CONTROL' => array(
+ 'COMMENTS' => array(
+ 'DISALLOWED_BEFORE' => '\\'
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/teraterm.php b/platform/www/vendor/geshi/geshi/src/geshi/teraterm.php
new file mode 100644
index 0000000..9f04b7b
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/teraterm.php
@@ -0,0 +1,352 @@
+<?php
+/*************************************************************************************
+ * teraterm.php
+ * --------
+ * Author: Boris Maisuradze (boris at logmett.com)
+ * Copyright: (c) 2008 Boris Maisuradze (http://logmett.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/09/26
+ *
+ * Tera Term Macro language file for GeSHi.
+ *
+ *
+ * This version of teraterm.php was created for Tera Term 4.62 and LogMeTT 2.9.4.
+ * Newer versions of these application can contain additional Macro commands
+ * and/or keywords that are not listed here. The latest release of teraterm.php
+ * can be downloaded from Download section of LogMeTT.com
+ *
+ * CHANGES
+ * -------
+ * 2008/09/26 (1.0.0)
+ * - First Release for Tera Term 4.60 and below.
+ * 2009/03/22 (1.1.0)
+ * - First Release for Tera Term 4.62 and below.
+ * 2009/04/25 (1.1.1)
+ * - Second Release for Tera Term 4.62 and below.
+ * 2010/09/12 (1.1.2)
+ * - Second Release for Tera Term 4.67, LogMeTT 2.97, TTLEditor 1.2.1 and below.
+ *
+ * TODO (updated 2010/09/12)
+ * -------------------------
+ * *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Tera Term Macro',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /* Commands */
+ 1 => array(
+ 'Beep',
+ 'BplusRecv',
+ 'BplusSend',
+ 'Break',
+ 'Call',
+ 'CallMenu',
+ 'ChangeDir',
+ 'ClearScreen',
+ 'Clipb2Var',
+ 'ClosesBox',
+ 'CloseTT',
+ 'Code2Str',
+ 'Connect',
+ 'CRC32',
+ 'CRC32File',
+ 'CygConnect',
+ 'DelPassword',
+ 'Disconnect',
+ 'DispStr',
+ 'Do',
+ 'Else',
+ 'ElseIf',
+ 'EnableKeyb',
+ 'End',
+ 'EndIf',
+ 'EndUntil',
+ 'EndWhile',
+ 'Exec',
+ 'ExecCmnd',
+ 'Exit',
+ 'FileClose',
+ 'FileConcat',
+ 'FileCopy',
+ 'FileCreate',
+ 'FileDelete',
+ 'FileMarkPtr',
+ 'FileNameBox',
+ 'FileOpen',
+ 'FileRead',
+ 'FileReadln',
+ 'FileRename',
+ 'FileSearch',
+ 'FileSeek',
+ 'FileSeekBack',
+ 'FileStat',
+ 'FileStrSeek',
+ 'FileStrSeek2',
+ 'FileTruncate',
+ 'FileWrite',
+ 'FileWriteLn',
+ 'FindClose',
+ 'FindFirst',
+ 'FindNext',
+ 'FlushRecv',
+ 'For',
+ 'GetDate',
+ 'GetDir',
+ 'GetEnv',
+ 'GetHostname',
+ 'GetPassword',
+ 'GetTime',
+ 'GetTitle',
+ 'GetTTDir',
+ 'Getver',
+ 'GoTo',
+ 'If',
+ 'IfDefined',
+ 'Include',
+ 'InputBox',
+ 'Int2Str',
+ 'KmtFinish',
+ 'KmtGet',
+ 'KmtRecv',
+ 'KmtSend',
+ 'LoadKeymap',
+ 'LogClose',
+ 'LogOpen',
+ 'LogPause',
+ 'LogStart',
+ 'LogWrite',
+ 'Loop',
+ 'MakePath',
+ 'MessageBox',
+ 'MPause',
+ 'Next',
+ 'PasswordBox',
+ 'Pause',
+ 'QuickVANRecv',
+ 'QuickVANSend',
+ 'Random',
+ 'RecvLn',
+ 'RestoreSetup',
+ 'Return',
+ 'RotateLeft',
+ 'RotateRight',
+ 'ScpRecv',
+ 'ScpSend',
+ 'Send',
+ 'SendBreak',
+ 'SendBroadcast',
+ 'SendFile',
+ 'SendKCode',
+ 'SendLn',
+ 'SendLnBroadcast',
+ 'SendMulticast',
+ 'SetBaud',
+ 'SetDate',
+ 'SetDebug',
+ 'SetDir',
+ 'SetDlgPos',
+ 'SetDTR',
+ 'SetEcho',
+ 'SetEnv',
+ 'SetExitCode',
+ 'SetMulticastName',
+ 'SetRTS',
+ 'SetSync',
+ 'SetTime',
+ 'SetTitle',
+ 'Show',
+ 'ShowTT',
+ 'SPrintF',
+ 'SPrintF2',
+ 'StatusBox',
+ 'Str2Code',
+ 'Str2Int',
+ 'StrCompare',
+ 'StrConcat',
+ 'StrCopy',
+ 'StrInsert',
+ 'StrJoin',
+ 'StrLen',
+ 'StrMatch',
+ 'StrRemove',
+ 'StrReplace',
+ 'StrScan',
+ 'StrSpecial',
+ 'StrSplit',
+ 'StrTrim',
+ 'TestLink',
+ 'Then',
+ 'ToLower',
+ 'ToUpper',
+ 'UnLink',
+ 'Until',
+ 'Var2Clipb',
+ 'Wait',
+ 'Wait4All',
+ 'WaitEvent',
+ 'WaitLn',
+ 'WaitN',
+ 'WaitRecv',
+ 'WaitRegEx',
+ 'While',
+ 'XmodemRecv',
+ 'XmodemSend',
+ 'YesNoBox',
+ 'YmodemRecv',
+ 'YmodemSend',
+ 'ZmodemRecv',
+ 'ZmodemSend'
+ ),
+ /* System Variables */
+ 2 => array(
+ 'groupmatchstr1',
+ 'groupmatchstr2',
+ 'groupmatchstr3',
+ 'groupmatchstr4',
+ 'groupmatchstr5',
+ 'groupmatchstr6',
+ 'groupmatchstr7',
+ 'groupmatchstr8',
+ 'groupmatchstr9',
+ 'inputstr',
+ 'matchstr',
+ 'mtimeout',
+ 'param2',
+ 'param3',
+ 'param4',
+ 'param5',
+ 'param6',
+ 'param7',
+ 'param8',
+ 'param9',
+ 'result',
+ 'timeout'
+ ),
+ /* LogMeTT Key Words */
+ 3 => array(
+ '$[1]',
+ '$[2]',
+ '$[3]',
+ '$[4]',
+ '$[5]',
+ '$[6]',
+ '$[7]',
+ '$[8]',
+ '$[9]',
+ '$branch$',
+ '$computername$',
+ '$connection$',
+ '$email$',
+ '$logdir$',
+ '$logfilename$',
+ '$lttfilename$',
+ '$mobile$',
+ '$name$',
+ '$pager$',
+ '$parent$',
+ '$phone$',
+ '$snippet$',
+ '$ttdir$',
+ '$user$',
+ '$windir$',
+ ),
+ /* Keyword Symbols */
+ 4 => array(
+ 'and',
+ 'not',
+ 'or',
+ 'xor'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}',
+ '+', '-', '*', '/', '%',
+ '!', '&', '|', '^',
+ '<', '>', '=',
+ '?', ':', ';',
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000080; font-weight: bold!important;',
+ 2 => 'color: #808000; font-weight: bold;', // System Variables
+ 3 => 'color: #ff0000; font-weight: bold;', // LogMeTT Key Words
+ 4 => 'color: #ff00ff; font-weight: bold;' // Keyword Symbols
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(),
+ 'BRACKETS' => array(
+ 0 => 'color: #ff00ff; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #800080;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #008080;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #ff00ff; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000ff; font-weight: bold;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ 0 => array (
+ GESHI_SEARCH => '(\:[_a-zA-Z][_a-zA-Z0-9]+)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/texgraph.php b/platform/www/vendor/geshi/geshi/src/geshi/texgraph.php
new file mode 100644
index 0000000..1f82d42
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/texgraph.php
@@ -0,0 +1,1137 @@
+<?php
+/*************************************************************************************
+ * texgraph.php
+ * -----------
+ * Author: Patrick Fradin (patrick.fradin@gmail.com)
+ * Copyright: (c) 2011 Patrick Fradin
+ * Release Version: 1.0.9.1
+ * Date Started: 2011-09-18
+ *
+ * TeXgraph language file for GeSHi.
+ *
+ * http://texgraph.tuxfamily.org/
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'TeXgraph',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array(
+ '{'=>'}'
+ ),
+ 'COMMENT_REGEXP' => array(
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array( //file construction
+ 'TeXgraph', 'Cmd', 'Var', 'Mac', 'Graph', 'Include'
+ ),
+ 2 => array( //programmation structure
+ 'if', 'else', 'elif', 'fi',
+ 'for', 'do', 'od', 'by', 'By',
+ 'step', 'until', 'in', 'to', 'repeat', 'from', 'odfi', 'andif',
+ 'And', 'Or', 'CutA', 'CutB', 'Inside', 'Inter', 'InterL'
+ ),
+ 3 => array( // commandes prédéfinies
+ 'Aretes',
+ 'Arg',
+ 'Args',
+ 'Assign',
+ 'Axes',
+ 'Bezier',
+ 'Bord',
+ 'Border',
+ 'Build3D',
+ 'Cartesienne',
+ 'ChangeAttr',
+ 'Clip2D',
+ 'Clip3DLine',
+ 'ClipFacet',
+ 'Close',
+ 'CloseFile',
+ 'ComposeMatrix',
+ 'ComposeMatrix3D',
+ 'Concat',
+ 'ConvertToObj',
+ 'ConvertToObjN',
+ 'Copy',
+ 'Courbe',
+ 'Creer',
+ 'DefMac',
+ 'DefVar',
+ 'DefaultAttr',
+ 'Del',
+ 'DelGraph',
+ 'DelMac',
+ 'DelVar',
+ 'Der',
+ 'Diff',
+ 'Display3D',
+ 'DistCam',
+ 'Droite',
+ 'Dup',
+ 'Echange',
+ 'Ellipse',
+ 'EllipticArc',
+ 'Ent',
+ 'EpsCoord',
+ 'EquaDif',
+ 'Eval',
+ 'Exec',
+ 'Export',
+ 'ExportObject',
+ 'ExportPathData',
+ 'Fenetre',
+ 'FileExists',
+ 'For',
+ 'Free',
+ 'Fvisible',
+ 'Get',
+ 'Get3D',
+ 'GetAttr',
+ 'GetMatrix',
+ 'GetMatrix3D',
+ 'GetSpline',
+ 'GetStr',
+ 'GetSurface',
+ 'GrayScale',
+ 'Grille',
+ 'HexaColor',
+ 'IdMatrix',
+ 'IdMatrix3D',
+ 'Im',
+ 'Implicit',
+ 'Inc',
+ 'Input',
+ 'InputMac',
+ 'Inserer3D',
+ 'Insert',
+ 'Int',
+ 'IsMac',
+ 'IsString',
+ 'IsVar',
+ 'Label',
+ 'Ligne',
+ 'Liste',
+ 'Load',
+ 'LoadImage',
+ 'Loop',
+ 'LowerCase',
+ 'M',
+ 'MakePoly',
+ 'Map',
+ 'Marges',
+ 'Merge',
+ 'Message',
+ 'Mix',
+ 'ModelView',
+ 'Mtransform',
+ 'Mtransform3D',
+ 'MyExport',
+ 'Nargs',
+ 'NewGraph',
+ 'NewMac',
+ 'NewVar',
+ 'Nops',
+ 'Norm',
+ 'Normal',
+ 'OpenFile',
+ 'OriginalCoord',
+ 'PaintFacet',
+ 'PaintVertex',
+ 'Path',
+ 'PermuteWith',
+ 'Point',
+ 'Polaire',
+ 'PosCam',
+ 'Prodscal',
+ 'Prodvec',
+ 'Proj3D',
+ 'Rand',
+ 'Re',
+ 'ReCalc',
+ 'ReadData',
+ 'ReadFlatPs',
+ 'ReadObj',
+ 'RenCommand',
+ 'RenMac',
+ 'RestoreAttr',
+ 'Reverse',
+ 'Rgb',
+ 'Round',
+ 'Saut',
+ 'SaveAttr',
+ 'ScientificF',
+ 'Seq',
+ 'Set',
+ 'SetAttr',
+ 'SetMatrix',
+ 'SetMatrix3D',
+ 'Si',
+ 'Solve',
+ 'Sommets',
+ 'Sort',
+ 'SortFacet',
+ 'Special',
+ 'Spline',
+ 'Str',
+ 'StrArgs',
+ 'StrComp',
+ 'StrCopy',
+ 'StrDel',
+ 'StrEval',
+ 'StrLength',
+ 'StrPos',
+ 'StrReplace',
+ 'String',
+ 'TeX2FlatPs',
+ 'UpperCase',
+ 'While',
+ 'WriteFile',
+ 'abs',
+ 'arccos',
+ 'arccot',
+ 'arcsin',
+ 'arctan',
+ 'argch',
+ 'argcth',
+ 'argsh',
+ 'argth',
+ 'bar',
+ 'ch',
+ 'cos',
+ 'cot',
+ 'cth',
+ 'draw',
+ 'opp',
+ 'sh',
+ 'sin',
+ 'sqr',
+ 'sqrt',
+ 'tan',
+ 'th',
+ ),
+ 4 => array( //commandes relatives à l'interface graphique
+ 'AddMenu2D',
+ 'AddMenu3D',
+ 'Attributs',
+ 'DelBitmap',
+ 'DelButton',
+ 'DelItem',
+ 'DelText',
+ 'Delay',
+ 'Hide',
+ 'ListFiles',
+ 'ListWords',
+ 'MaxPixels',
+ 'Move',
+ 'NewBitmap',
+ 'NewButton',
+ 'NewItem',
+ 'NewText',
+ 'NotXor',
+ 'Pixel',
+ 'Pixel2Scr',
+ 'ReDraw',
+ 'Scr2Pixel',
+ 'Show',
+ 'Stroke',
+ 'Timer',
+ 'TimerMac',
+ 'UpdateLocalDatabase',
+ 'VisibleGraph',
+ ),
+ 5 => array( //constantes prédéfinies
+ 'Data',
+ 'Diese',
+ 'DirSep',
+ 'DocPath',
+ 'ExportMode',
+ 'GUI',
+ 'Huge',
+ 'ImageViewer',
+ 'InitialPath',
+ 'JavaviewPath',
+ 'LARGE',
+ 'LF',
+ 'Large',
+ 'Nil',
+ 'PdfReader',
+ 'Thicklines',
+ 'TmpPath',
+ 'UserMacPath',
+ 'WebLoad',
+ 'Windows',
+ 'Xmax',
+ 'Xmin',
+ 'Xscale',
+ 'Ymax',
+ 'Ymin',
+ 'Yscale',
+ 'aliceblue',
+ 'antiquewhite',
+ 'aqua',
+ 'aquamarine',
+ 'asterisk',
+ 'azure',
+ 'baseline',
+ 'bdiag',
+ 'beige',
+ 'bevel',
+ 'bezier',
+ 'bigdot',
+ 'bisque',
+ 'black',
+ 'blanchedalmond',
+ 'blue',
+ 'blueviolet',
+ 'bmp',
+ 'bottom',
+ 'brown',
+ 'burlywood',
+ 'butt',
+ 'cadetblue',
+ 'center',
+ 'centered',
+ 'central',
+ 'chartreuse',
+ 'chocolate',
+ 'circle',
+ 'closepath',
+ 'comp',
+ 'coral',
+ 'cornflowerblue',
+ 'cornsilk',
+ 'crimson',
+ 'cross',
+ 'curve',
+ 'cyan',
+ 'darkblue',
+ 'darkcyan',
+ 'darkgoldenrod',
+ 'darkgray',
+ 'darkgreen',
+ 'darkkhaki',
+ 'darkmagenta',
+ 'darkolivegreen',
+ 'darkorange',
+ 'darkorchid',
+ 'darkred',
+ 'darksalmon',
+ 'darkseagreen',
+ 'darkslateblue',
+ 'darkslategray',
+ 'darkturquoise',
+ 'darkviolet',
+ 'dashed',
+ 'deeppink',
+ 'deepskyblue',
+ 'diagcross',
+ 'diamond',
+ 'dimgray',
+ 'dodgerblue',
+ 'dot',
+ 'dotcircle',
+ 'dotted',
+ 'e',
+ 'ellipse',
+ 'ellipticArc',
+ 'eps',
+ 'epsc',
+ 'fdiag',
+ 'firebrick',
+ 'floralwhite',
+ 'footnotesize',
+ 'forestgreen',
+ 'framed',
+ 'fuchsia',
+ 'full',
+ 'gainsboro',
+ 'geom',
+ 'ghostwhite',
+ 'gold',
+ 'goldenrod',
+ 'gray',
+ 'green',
+ 'greenyellow',
+ 'honeydew',
+ 'horizontal',
+ 'hotpink',
+ 'huge',
+ 'hvcross',
+ 'i',
+ 'indianred',
+ 'indigo',
+ 'ivory',
+ 'jump',
+ 'jvx',
+ 'khaki',
+ 'large',
+ 'lavender',
+ 'lavenderblush',
+ 'lawngreen',
+ 'left',
+ 'lemonchiffon',
+ 'lightblue',
+ 'lightcoral',
+ 'lightcyan',
+ 'lightgoldenrodyellow',
+ 'lightgray',
+ 'lightgreen',
+ 'lightpink',
+ 'lightsalmon',
+ 'lightseagreen',
+ 'lightskyblue',
+ 'lightslategray',
+ 'lightsteelblue',
+ 'lightyellow',
+ 'lime',
+ 'limegreen',
+ 'line',
+ 'linearc',
+ 'linen',
+ 'magenta',
+ 'margeB',
+ 'margeD',
+ 'margeG',
+ 'margeH',
+ 'maroon',
+ 'mediumaquamarine',
+ 'mediumblue',
+ 'mediumorchid',
+ 'mediumpurple',
+ 'mediumseagreen',
+ 'mediumslateblue',
+ 'mediumspringgreen',
+ 'mediumturquoise',
+ 'mediumvioletred',
+ 'midnightblue',
+ 'mintcream',
+ 'mistyrose',
+ 'miter',
+ 'moccasin',
+ 'move',
+ 'navajowhite',
+ 'navy',
+ 'noline',
+ 'none',
+ 'normalsize',
+ 'obj',
+ 'oldlace',
+ 'olive',
+ 'olivedrab',
+ 'oplus',
+ 'orange',
+ 'orangered',
+ 'orchid',
+ 'ortho',
+ 'otimes',
+ 'palegoldenrod',
+ 'palegreen',
+ 'paleturquoise',
+ 'palevioletred',
+ 'papayawhip',
+ 'pdf',
+ 'pdfc',
+ 'peachpuff',
+ 'pentagon',
+ 'peru',
+ 'pgf',
+ 'pi',
+ 'pink',
+ 'plum',
+ 'plus',
+ 'powderblue',
+ 'psf',
+ 'pst',
+ 'purple',
+ 'red',
+ 'right',
+ 'rosybrown',
+ 'round',
+ 'royalblue',
+ 'saddlebrown',
+ 'salmon',
+ 'sandybrown',
+ 'scriptsize',
+ 'seagreen',
+ 'seashell',
+ 'sep',
+ 'sep3D',
+ 'sienna',
+ 'silver',
+ 'skyblue',
+ 'slateblue',
+ 'slategray',
+ 'small',
+ 'snow',
+ 'solid',
+ 'special',
+ 'springgreen',
+ 'square',
+ 'src4latex',
+ 'stacked',
+ 'steelblue',
+ 'svg',
+ 'teal',
+ 'teg',
+ 'tex',
+ 'texsrc',
+ 'thicklines',
+ 'thinlines',
+ 'thistle',
+ 'times',
+ 'tiny',
+ 'tkz',
+ 'tomato',
+ 'top',
+ 'triangle',
+ 'turquoise',
+ 'user',
+ 'userdash',
+ 'version',
+ 'vertical',
+ 'violet',
+ 'wheat',
+ 'white',
+ 'whitesmoke',
+ 'yellow',
+ 'yellowgreen',
+ ),
+ 6 => array( //macros prédéfinies
+ 'Abs',
+ 'Anp',
+ 'Apercu',
+ 'Arc',
+ 'Arc3D',
+ 'AretesNum',
+ 'AxeX3D',
+ 'AxeY3D',
+ 'AxeZ3D',
+ 'Axes3D',
+ 'Bcolor',
+ 'Bouton',
+ 'BoxAxes3D',
+ 'BrightColor',
+ 'Bsave',
+ 'Ceil',
+ 'Cercle',
+ 'Cercle3D',
+ 'Chanfrein',
+ 'ChangeWinTo',
+ 'Clip',
+ 'Clip3D',
+ 'ColorJump',
+ 'CompVer',
+ 'CompileEps',
+ 'CompilePdf',
+ 'Cone',
+ 'Courbe3D',
+ 'CpCopy',
+ 'CpDel',
+ 'CpNops',
+ 'CpReplace',
+ 'CpReverse',
+ 'CplColor',
+ 'Cvx2d',
+ 'Cvx3d',
+ 'Cvx3dAux',
+ 'Cylindre',
+ 'Dark',
+ 'Dbissec',
+ 'Dcarre',
+ 'Dcone',
+ 'Dcylindre',
+ 'Ddroite',
+ 'Dmed',
+ 'Dparallel',
+ 'Dparallelep',
+ 'Dparallelo',
+ 'Dperp',
+ 'Dpolyreg',
+ 'DpqGoneReg',
+ 'DpqGoneReg3D',
+ 'Dprisme',
+ 'Dpyramide',
+ 'DrawAretes',
+ 'DrawDdroite',
+ 'DrawDot',
+ 'DrawDroite',
+ 'DrawFaces',
+ 'DrawFacet',
+ 'DrawFlatFacet',
+ 'DrawGouraudTr',
+ 'DrawPlan',
+ 'DrawPoly',
+ 'DrawPolyNC',
+ 'DrawSmoothFacet',
+ 'Drectangle',
+ 'Dsphere',
+ 'Dsurface',
+ 'Dtetraedre',
+ 'Esave',
+ 'ExportGouraudTr',
+ 'ExportSmoothFacet',
+ 'FacesNum',
+ 'Gcolor',
+ 'GradDroite',
+ 'HollowFacet',
+ 'Hsb',
+ 'HueColor',
+ 'Incfrac',
+ 'Intersec',
+ 'Intersection',
+ 'IsAlign',
+ 'IsAlign3d',
+ 'IsIn',
+ 'IsPlan',
+ 'KillDup',
+ 'KillDup3D',
+ 'LabelArc',
+ 'LabelAxe',
+ 'LabelDot',
+ 'LabelDot3D',
+ 'LabelSeg',
+ 'Lcolor',
+ 'Light',
+ 'Ligne3D',
+ 'MakeVer',
+ 'Map3D',
+ 'MapBy',
+ 'Merge3d',
+ 'MixColor',
+ 'MouseZoom',
+ 'NewLabel',
+ 'NewLabelDot',
+ 'NewLabelDot3D',
+ 'NewTeXlabel',
+ 'Nops3d',
+ 'Ordonner',
+ 'Palette',
+ 'Parallelep',
+ 'Point3D',
+ 'Pos',
+ 'Pos3d',
+ 'Prisme',
+ 'Pyramide',
+ 'Rarc',
+ 'Rcercle',
+ 'Rcolor',
+ 'RealArg',
+ 'RealCoord',
+ 'RealCoordV',
+ 'Rellipse',
+ 'RellipticArc',
+ 'RestoreTphi',
+ 'RestoreWin',
+ 'RestoreWin3d',
+ 'Rgb2Gray',
+ 'Rgb2Hexa',
+ 'Rgb2Hsb',
+ 'RgbL',
+ 'Ryb',
+ 'SatColor',
+ 'SaveTphi',
+ 'SaveWin',
+ 'SaveWin3d',
+ 'SceneToGeom',
+ 'SceneToJvx',
+ 'SceneToObj',
+ 'ScrCoord',
+ 'ScrCoordV',
+ 'ScreenCenter',
+ 'ScreenPos',
+ 'ScreenX',
+ 'ScreenY',
+ 'Section',
+ 'Section2',
+ 'Seg',
+ 'SetStr',
+ 'Snapshot',
+ 'SortWith',
+ 'Sphere',
+ 'StrListAdd',
+ 'StrListCopy',
+ 'StrListDelKey',
+ 'StrListDelVal',
+ 'StrListGetKey',
+ 'StrListInit',
+ 'StrListInsert',
+ 'StrListKill',
+ 'StrListReplace',
+ 'StrListReplaceKey',
+ 'StrListShow',
+ 'StrNum',
+ 'SvgCoord',
+ 'TeXCoord',
+ 'Tetra',
+ 'VarGlob',
+ 'WriteObj',
+ 'WriteOff',
+ 'Xde',
+ 'Yde',
+ 'Zde',
+ 'addfrac',
+ 'affin',
+ 'aire3d',
+ 'angle',
+ 'angle3d',
+ 'angleD',
+ 'antirot3d',
+ 'arc',
+ 'arcBezier',
+ 'axeX',
+ 'axeY',
+ 'axes',
+ 'background',
+ 'bande',
+ 'bary',
+ 'bary3d',
+ 'bbox',
+ 'bdAngleD',
+ 'bdArc',
+ 'bdAxes',
+ 'bdCercle',
+ 'bdCone',
+ 'bdCurve',
+ 'bdCylinder',
+ 'bdDot',
+ 'bdDroite',
+ 'bdFacet',
+ 'bdLabel',
+ 'bdLine',
+ 'bdPlan',
+ 'bdPlanEqn',
+ 'bdPrism',
+ 'bdPyramid',
+ 'bdSphere',
+ 'bdSurf',
+ 'bdTorus',
+ 'bdWall',
+ 'binom',
+ 'bissec',
+ 'bordsAjour',
+ 'cap',
+ 'capB',
+ 'carre',
+ 'centerView',
+ 'chaine',
+ 'class_Path',
+ 'clipCurve',
+ 'clipPoly',
+ 'compileFormule',
+ 'conv2Facet',
+ 'conv2FlatPs',
+ 'coord',
+ 'cup',
+ 'cupB',
+ 'curve2Cone',
+ 'curve2Cylinder',
+ 'curveTube',
+ 'cutBezier',
+ 'defAff',
+ 'defAff3d',
+ 'del',
+ 'det',
+ 'det3d',
+ 'div',
+ 'domaine1',
+ 'domaine2',
+ 'domaine3',
+ 'dproj3d',
+ 'dproj3dO',
+ 'drawFlatPs',
+ 'drawSet',
+ 'drawTeXlabel',
+ 'drawTeXlabel3d',
+ 'drawWin3d',
+ 'dsym3d',
+ 'dsym3dO',
+ 'ecart',
+ 'ellipseArc',
+ 'engineerF',
+ 'epsCoord',
+ 'extractFlatPs',
+ 'fact',
+ 'flecher',
+ 'free',
+ 'ftransform',
+ 'ftransform3d',
+ 'geomview',
+ 'getdot',
+ 'getdroite',
+ 'getplan',
+ 'getplanEqn',
+ 'grille3d',
+ 'help',
+ 'hom',
+ 'hom3d',
+ 'interDD',
+ 'interDP',
+ 'interLP',
+ 'interPP',
+ 'inv',
+ 'inv3d',
+ 'invmatrix',
+ 'invmatrix3d',
+ 'isobar',
+ 'isobar3d',
+ 'javaview',
+ 'label',
+ 'labelarc',
+ 'length',
+ 'length3d',
+ 'line2Cone',
+ 'line2Cylinder',
+ 'lineTube',
+ 'loadFlatPs',
+ 'makeLabel3d',
+ 'markangle',
+ 'markseg',
+ 'markseg3d',
+ 'matrix',
+ 'matrix3d',
+ 'max',
+ 'med',
+ 'median',
+ 'min',
+ 'mod',
+ 'moy',
+ 'mtransform',
+ 'mtransform3d',
+ 'mulmatrix',
+ 'mulmatrix3d',
+ 'n',
+ 'newxlegend',
+ 'newylegend',
+ 'newzlegend',
+ 'nil',
+ 'normalize',
+ 'not',
+ 'parallel',
+ 'parallelo',
+ 'pdfprog',
+ 'periodic',
+ 'permute',
+ 'permute3d',
+ 'perp',
+ 'pgcd',
+ 'planEqn',
+ 'polyreg',
+ 'ppcm',
+ 'pqGoneReg',
+ 'pqGoneReg3D',
+ 'prod',
+ 'proj',
+ 'proj3d',
+ 'proj3dO',
+ 'projO',
+ 'purge3d',
+ 'putAbove',
+ 'px',
+ 'pxy',
+ 'pxz',
+ 'py',
+ 'pyz',
+ 'pz',
+ 'rect',
+ 'rectangle',
+ 'rectangle3d',
+ 'replace',
+ 'replace3d',
+ 'reverse',
+ 'reverse3d',
+ 'rot',
+ 'rot3d',
+ 'rotCurve',
+ 'rotLine',
+ 'set',
+ 'setB',
+ 'setminus',
+ 'setminusB',
+ 'shift',
+ 'shift3d',
+ 'simil',
+ 'size',
+ 'split2facet1',
+ 'split2facet2',
+ 'suite',
+ 'sum',
+ 'svgCoord',
+ 'sym',
+ 'sym3d',
+ 'sym3dO',
+ 'symG',
+ 'symO',
+ 'tangente',
+ 'tangenteP',
+ 'texCoord',
+ 'transformbox3d',
+ 'trianguler',
+ 'var',
+ 'view',
+ 'view3D',
+ 'viewDir',
+ 'visible',
+ 'wedge',
+ 'zoom',
+ ),
+ 7 => array( //variables prédéfinies
+ 'AngleStep',
+ 'Arrows',
+ 'AutoReCalc',
+ 'Color',
+ 'ComptGraph',
+ 'ComptLabel3d',
+ 'DashPattern',
+ 'DeltaB',
+ 'DotAngle',
+ 'DotScale',
+ 'DotSize',
+ 'DotStyle',
+ 'Eofill',
+ 'FillColor',
+ 'FillOpacity',
+ 'FillStyle',
+ 'ForMinToMax',
+ 'HideColor',
+ 'HideStyle',
+ 'HideWidth',
+ 'IsVisible',
+ 'LabelAngle',
+ 'LabelSize',
+ 'LabelStyle',
+ 'LineCap',
+ 'LineJoin',
+ 'LineStyle',
+ 'MiterLimit',
+ 'MouseCode',
+ 'NbBoutons',
+ 'NbPoints',
+ 'Origin',
+ 'PenMode',
+ 'RefPoint',
+ 'ScriptExt',
+ 'StrokeOpacity',
+ 'TeXLabel',
+ 'TeXify',
+ 'TeXifyLabels',
+ 'TphiList',
+ 'Width',
+ 'Xfact',
+ 'Xinf',
+ 'Xsup',
+ 'Yfact',
+ 'Yinf',
+ 'Ysup',
+ 'Zinf',
+ 'ZoomList',
+ 'Zsup',
+ 'above',
+ 'arrows',
+ 'arrowscale',
+ 'axeOrigin',
+ 'backcolor',
+ 'backculling',
+ 'border',
+ 'bordercolor',
+ 'cleanLabel',
+ 'clip',
+ 'clipwin',
+ 'close',
+ 'color',
+ 'contrast',
+ 'cube',
+ 'defaultMatrix',
+ 'deg',
+ 'dir',
+ 'disc',
+ 'dollar',
+ 'dotcolor',
+ 'dotscale',
+ 'dotstyle',
+ 'drawbox',
+ 'flip',
+ 'grid',
+ 'gridcolor',
+ 'gridwidth',
+ 'height',
+ 'hidden',
+ 'hiddenLines',
+ 'hollow',
+ 'inside',
+ 'label3d',
+ 'labeldir',
+ 'labelpos',
+ 'labels',
+ 'labelsep',
+ 'labelsize',
+ 'labelstyle',
+ 'legendpos',
+ 'linestyle',
+ 'maxGrad',
+ 'mirror',
+ 'mm',
+ 'nbdeci',
+ 'nbdot',
+ 'nbfacet',
+ 'normal',
+ 'numericFormat',
+ 'opacity',
+ 'originlabel',
+ 'outside',
+ 'phi',
+ 'position',
+ 'rad',
+ 'radius',
+ 'radiusscale',
+ 'radscale',
+ 'rotation',
+ 'scale',
+ 'select',
+ 'showdot',
+ 'smooth',
+ 'stock',
+ 'stock1',
+ 'stock2',
+ 'stock3',
+ 'stock4',
+ 'stock5',
+ 't',
+ 'tMax',
+ 'tMin',
+ 'tailleB',
+ 'theta',
+ 'tickdir',
+ 'tickpos',
+ 'tube',
+ 'twoside',
+ 'u',
+ 'usecomma',
+ 'v',
+ 'vecI',
+ 'vecJ',
+ 'vecK',
+ 'width',
+ 'win2dList',
+ 'win3dList',
+ 'xaxe',
+ 'xgradlimits',
+ 'xlabelsep',
+ 'xlabelstyle',
+ 'xlegendsep',
+ 'xlimits',
+ 'xstep',
+ 'xylabelpos',
+ 'xylabelsep',
+ 'xyticks',
+ 'yaxe',
+ 'ygradlimits',
+ 'ylabelsep',
+ 'ylabelstyle',
+ 'ylegendsep',
+ 'ylimits',
+ 'ystep',
+ 'zaxe',
+ 'zgradlimits',
+ 'zlabelsep',
+ 'zlabelstyle',
+ 'zlegendsep',
+ 'zlimits',
+ 'zstep',
+ )
+ ),
+ 'SYMBOLS' => array(
+ ':=', '=', '+', '-', '*', '/',
+ '<', '>', '>=', '<=', '<>',
+ '\\', '@', ', ', ';', '#'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #3ad900;font-weight: bold;',// file construction
+ 2 => 'color: #A53;',// programmation structure
+ 3 => 'color: #35A;font-weight: bold;',// commandes prédéfinies
+ 4 => 'color: #472;',// commandes relatives à l'interface graphique
+ 5 => 'color: #008080;',// constantes prédéfinies
+ 6 => 'color: #808000;font-weight: bold;',// macros prédéfinies
+ 7 => 'color: #000;font-weight: bold;',// variables prédéfinies
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #777;',
+ 'MULTI' => 'color: #880;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #820;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #880;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000;'
+ ),
+ 'METHODS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://melusine.eu.org/syracuse/G/geshi/docs/texgraph/#{FNAME}',
+ 4 => '',
+ 5 => '',
+ 6 => 'http://melusine.eu.org/syracuse/G/geshi/docs/texgraph/#{FNAME}',
+ 7 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/text.php b/platform/www/vendor/geshi/geshi/src/geshi/text.php
new file mode 100644
index 0000000..217e9c0
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/text.php
@@ -0,0 +1,82 @@
+<?php
+/*************************************************************************************
+ * text.php
+ * --------
+ * Author: Sean Hanna (smokingrope@gmail.com)
+ * Copyright: (c) 2006 Sean Hanna
+ * Release Version: 1.0.9.1
+ * Date Started: 04/23/2006
+ *
+ * Standard Text File (No Syntax Highlighting).
+ * Plaintext language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 04/23/2006 (0.5.0)
+ * - Syntax File Created
+ *
+ * 04/27/2006 (1.0.0)
+ * - Documentation Cleaned Up
+ * - First Release
+ *
+ * TODO (updated 04/27/2006)
+ * -------------------------
+ *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Text',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(),
+ 'SYMBOLS' => array(),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(),
+ 'COMMENTS' => array(),
+ 'ESCAPE_CHAR' => array(),
+ 'BRACKETS' => array(),
+ 'STRINGS' => array(),
+ 'NUMBERS' => array(),
+ 'METHODS' => array(),
+ 'SYMBOLS' => array(),
+ 'SCRIPT' => array(),
+ 'REGEXPS' => array()
+ ),
+ 'URLS' => array(),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'ALL' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/thinbasic.php b/platform/www/vendor/geshi/geshi/src/geshi/thinbasic.php
new file mode 100644
index 0000000..a8b413e
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/thinbasic.php
@@ -0,0 +1,866 @@
+<?php
+/*************************************************************************************
+ * thinbasic.php
+ * ------
+ * Author: Eros Olmi (eros.olmi@thinbasic.com)
+ * Copyright: (c) 2006 Eros Olmi (http://www.thinbasic.com), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/05/12
+ *
+ * thinBasic language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2006/05/12 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2006/05/12)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'thinBasic',
+ 'COMMENT_SINGLE' => array(1 => "'"),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'XOR','XML_TREETOSTRING','XML_PARSEFILE','XML_PARSE','XML_PARENT','XML_NODETYPE','XML_NODETOSTRING','XML_NEXTSIBLING',
+ 'XML_LASTERROR','XML_GETTAG','XML_FREE','XML_FINDNODE','XML_DECODEPARAM','XML_CHILDDATA','XML_CHILD','XML_ATTRIBVALUE',
+ 'XML_ATTRIBNAME','XML_ATTRIBCOUNT','WORD','WITH','WIN_SHOW','WIN_SETTITLE','WIN_SETFOREGROUND','WIN_ISZOOMED',
+ 'WIN_ISVISIBLE','WIN_ISICONIC','WIN_GETTITLE','WIN_GETFOREGROUND','WIN_GETCLASS','WIN_GETACTIVE','WIN_FLASH','WIN_FINDBYTITLE',
+ 'WIN_FINDBYCLASS','WHILE','WEND','VERIFY','VARPTR','VARIANTVT$','VARIANTVT','VARIANT',
+ 'VARIABLE_GETINFO','VARIABLE_EXISTS','VARIABLE_EXIST','VALUE','VAL','USING$','USING','USES',
+ 'USER','UNTIL','UNITS','UNION','UNICODE2ASCII','UDP_SEND','UDP_RECV','UDP_OPENSERVER',
+ 'UDP_OPEN','UDP_FREEFILE','UDP_CLOSE','UCODE$','UCASE$','UBOUND','TYPE','TRIMFULL$',
+ 'TRIM$','TOOLTIP','TOKENIZER_MOVETOEOL','TOKENIZER_KEYSETUSERSTRING','TOKENIZER_KEYSETUSERNUMBER','TOKENIZER_KEYGETUSERSTRING','TOKENIZER_KEYGETUSERNUMBER','TOKENIZER_KEYGETSUBTYPE',
+ 'TOKENIZER_KEYGETNAME','TOKENIZER_KEYGETMAINTYPE','TOKENIZER_KEYFIND','TOKENIZER_KEYADD','TOKENIZER_GETNEXTTOKEN','TOKENIZER_DEFAULT_SET','TOKENIZER_DEFAULT_GET','TOKENIZER_DEFAULT_CODE',
+ 'TOKENIZER_DEFAULT_CHAR','TO','TIMER','TIME$','THEN','TEXTBOX','TEXT','TCP_SEND',
+ 'TCP_RECV','TCP_PRINT','TCP_OPEN','TCP_LINEINPUT','TCP_FREEFILE','TCP_CLOSE','TB_IMGCTX_SETIMAGEADJUSTMENT','TB_IMGCTX_LOADIMAGE',
+ 'TB_IMGCTX_GETIMAGEADJUSTMENT','TBGL_VIEWPORT','TBGL_VERTEX','TBGL_USETEXTUREFLAG','TBGL_USETEXTURE','TBGL_USELINESTIPPLEFLAG','TBGL_USELINESTIPPLE','TBGL_USELIGHTSOURCEFLAG',
+ 'TBGL_USELIGHTSOURCE','TBGL_USELIGHTINGFLAG','TBGL_USELIGHTING','TBGL_USEFOGFLAG','TBGL_USEFOG','TBGL_USEDEPTHMASK','TBGL_USEDEPTHFLAG','TBGL_USEDEPTH',
+ 'TBGL_USECLIPPLANEFLAG','TBGL_USECLIPPLANE','TBGL_USEBLENDFLAG','TBGL_USEBLEND','TBGL_USEALPHATEST','TBGL_TRANSLATE','TBGL_TORUS','TBGL_TEXCOORD2D',
+ 'TBGL_SPHERE','TBGL_SHOWWINDOW','TBGL_SHOWCURSOR','TBGL_SETWINDOWTITLE','TBGL_SETUPLIGHTSOURCE','TBGL_SETUPFOG','TBGL_SETUPCLIPPLANE','TBGL_SETPRIMITIVEQUALITY',
+ 'TBGL_SETLIGHTPARAMETER','TBGL_SETDRAWDISTANCE','TBGL_SCALE','TBGL_SAVESCREENSHOT','TBGL_ROTATEXYZ','TBGL_ROTATE','TBGL_RESETMATRIX','TBGL_RENDERTOTEXTURE',
+ 'TBGL_RENDERMATRIX3D','TBGL_RENDERMATRIX2D','TBGL_PUSHMATRIX','TBGL_PRINTFONT','TBGL_PRINTBMP','TBGL_PRINT','TBGL_POS3DTOPOS2D','TBGL_POPMATRIX',
+ 'TBGL_POLYGONLOOK','TBGL_POINTSIZE','TBGL_POINTINSIDE3D','TBGL_NORMAL','TBGL_NEWLIST','TBGL_MOUSEGETWHEELDELTA','TBGL_MOUSEGETRBUTTON','TBGL_MOUSEGETPOSY',
+ 'TBGL_MOUSEGETPOSX','TBGL_MOUSEGETMBUTTON','TBGL_MOUSEGETLBUTTON','TBGL_M15SETVERTEXZ','TBGL_M15SETVERTEXY','TBGL_M15SETVERTEXXYZ','TBGL_M15SETVERTEXX','TBGL_M15SETVERTEXTEXY',
+ 'TBGL_M15SETVERTEXTEXXY','TBGL_M15SETVERTEXTEXX','TBGL_M15SETVERTEXTEXN','TBGL_M15SETVERTEXRGB','TBGL_M15SETVERTEXR','TBGL_M15SETVERTEXPSTOP','TBGL_M15SETVERTEXPARAM','TBGL_M15SETVERTEXLAYER',
+ 'TBGL_M15SETVERTEXG','TBGL_M15SETVERTEXB','TBGL_M15SETMODELVERTEXCOUNT','TBGL_M15SETBONECHILD','TBGL_M15ROTBONEZ','TBGL_M15ROTBONEY','TBGL_M15ROTBONEX','TBGL_M15ROTBONE',
+ 'TBGL_M15RESETBONES','TBGL_M15RECALCNORMALS','TBGL_M15LOADMODEL','TBGL_M15INITMODELBUFFERS','TBGL_M15GETVERTEXZ','TBGL_M15GETVERTEXY','TBGL_M15GETVERTEXXYZ','TBGL_M15GETVERTEXX',
+ 'TBGL_M15GETVERTEXTEXY','TBGL_M15GETVERTEXTEXXY','TBGL_M15GETVERTEXTEXX','TBGL_M15GETVERTEXTEXN','TBGL_M15GETVERTEXRGB','TBGL_M15GETVERTEXR','TBGL_M15GETVERTEXPSTOP','TBGL_M15GETVERTEXPARAM',
+ 'TBGL_M15GETVERTEXLAYER','TBGL_M15GETVERTEXG','TBGL_M15GETVERTEXB','TBGL_M15GETMODELVERTEXCOUNT','TBGL_M15GETMODELPOLYCOUNT','TBGL_M15ERASECHILDBONES','TBGL_M15DRAWMODEL','TBGL_M15DEFBONERESET',
+ 'TBGL_M15DEFBONELAYER','TBGL_M15DEFBONEBOX','TBGL_M15DEFBONEANCHOR','TBGL_M15DEFBONEADDVERTEX','TBGL_M15CLEARMODEL','TBGL_M15APPLYBONES','TBGL_M15ADDBONETREEITEM','TBGL_LOADTEXTURE',
+ 'TBGL_LOADFONT','TBGL_LOADBMPFONT','TBGL_LINEWIDTH','TBGL_LINESTIPPLE','TBGL_KILLFONT','TBGL_ISWINDOW','TBGL_ISPOINTVISIBLE','TBGL_ISPOINTBEHINDVIEW',
+ 'TBGL_GETWINDOWMULTIKEYSTATE','TBGL_GETWINDOWKEYSTATE','TBGL_GETWINDOWKEYONCE','TBGL_GETWINDOWCLIENT','TBGL_GETTEXTURENAME','TBGL_GETTEXTURELIST','TBGL_GETPIXELINFO','TBGL_GETMULTIASYNCKEYSTATE',
+ 'TBGL_GETLASTGLERROR','TBGL_GETFRAMERATE','TBGL_GETDESKTOPINFO','TBGL_GETASYNCKEYSTATE','TBGL_ERRORMESSAGES','TBGL_ENDPOLY','TBGL_ENDLIST','TBGL_DRAWFRAME',
+ 'TBGL_DESTROYWINDOW','TBGL_DELETELIST','TBGL_CYLINDER','TBGL_CREATEWINDOWEX','TBGL_CREATEWINDOW','TBGL_COLORALPHA','TBGL_COLOR','TBGL_CLEARFRAME',
+ 'TBGL_CAMERA','TBGL_CALLLIST','TBGL_BUILDFONT','TBGL_BOX','TBGL_BLENDFUNC','TBGL_BINDTEXTURE','TBGL_BEGINPOLY','TBGL_BACKCOLOR',
+ 'TBGL_ALPHAFUNC','TBDI_JOYZ','TBDI_JOYY','TBDI_JOYX','TBDI_JOYSTOPEFFECT','TBDI_JOYSLIDER','TBDI_JOYSETRANGEZ','TBDI_JOYSETRANGEY',
+ 'TBDI_JOYSETRANGEXYZ','TBDI_JOYSETRANGEX','TBDI_JOYSETDEADZONEZ','TBDI_JOYSETDEADZONEY','TBDI_JOYSETDEADZONEXYZ','TBDI_JOYSETDEADZONEX','TBDI_JOYSETAUTOCENTER','TBDI_JOYRZ',
+ 'TBDI_JOYRY','TBDI_JOYRX','TBDI_JOYPOV','TBDI_JOYPLAYEFFECT','TBDI_JOYLOADEFFECT','TBDI_JOYHASFF','TBDI_JOYHASEFFECT','TBDI_JOYGETEFFECTNAME',
+ 'TBDI_JOYGETEFFECTGUID','TBDI_JOYCREATEEFFECT','TBDI_JOYCOUNTPOV','TBDI_JOYCOUNTEFFECTS','TBDI_JOYCOUNTBTN','TBDI_JOYCOUNTAXES','TBDI_JOYBUTTON','TBDI_JOYAVAIL',
+ 'TBDI_INIT','TBASS_STREAMFREE','TBASS_STREAMCREATEFILE','TBASS_SETVOLUME','TBASS_SETEAXPRESET','TBASS_SETEAXPARAMETERS','TBASS_SETCONFIG','TBASS_SET3DPOSITION',
+ 'TBASS_SET3DFACTORS','TBASS_SAMPLELOAD','TBASS_SAMPLEGETCHANNEL','TBASS_MUSICLOAD','TBASS_MUSICFREE','TBASS_INIT','TBASS_GETVOLUME','TBASS_GETVERSION',
+ 'TBASS_GETCONFIG','TBASS_FREE','TBASS_ERRORGETCODE','TBASS_CHANNELSTOP','TBASS_CHANNELSETPOSITION','TBASS_CHANNELSETATTRIBUTES','TBASS_CHANNELSET3DPOSITION','TBASS_CHANNELPLAY',
+ 'TBASS_CHANNELPAUSE','TBASS_CHANNELISACTIVE','TBASS_CHANNELGETPOSITION','TBASS_CHANNELGETLENGTH','TBASS_CHANNELGETATTRIBUTES','TBASS_APPLY3D','TANH','TANGENT',
+ 'TAN','TALLY','TABCTRL_ONNOTIFY','TABCTRL_INSERTITEM','TABCTRL_GETCURSEL','SWAP','SUB','STRZIP$',
+ 'STRUNZIP$','STRREVERSE$','STRPTRLEN','STRPTR','STRINSERT$','STRING$','STRING','STRDELETE$',
+ 'STR$','STOP','STEP','STDOUT','STDIN','STAT_SUM','STAT_STDERROR','STAT_STDDEVIATION',
+ 'STAT_RANDOM','STAT_PRODUCT','STAT_MIN','STAT_MEDIAN','STAT_MEANHARMONIC','STAT_MEANGEOMETRIC','STAT_MEANARITHMETIC','STAT_MAX',
+ 'STAT_INVERSESUM','STAT_HISTOGRAM','STAT_FILLARRAY','STAT_COUNT','STAT_COPYARRAY','STAT_CLONEARRAY','STAT_CHISQUARE','STATIC',
+ 'STATE','SQR','SPLIT','SORT','SMTP_STATISTICS','SMTP_SETOPTION','SMTP_SETLOGFILE','SMTP_SENDHTML',
+ 'SMTP_SENDEMAIL','SMTP_GETERROR','SMTP_FINISHED','SMTP_DEBUG','SMTP_CONNECT','SMTP_CLOSE','SLEEP','SIZEOF',
+ 'SIZE','SINH','SINGLE','SIN','SIGNED','SHOW','SHIFT','SHAPETOBMP',
+ 'SGN','SETAT','SET','SENDMESSAGE','SENDKEYSBULK','SENDKEYS','SEND','SELECTEXPRESSION',
+ 'SELECT','SECH','SEC','SCAN','SAPI_SPEAK','SAPI_SETVOLUME','SAPI_SETRATE','SAPI_MODULELOADED',
+ 'SAPI_GETVOLUME','SAPI_GETRATE','RTRIM$','RTF_SETTEXT','RTF_SETFONTSIZE','RTF_SETFONTNAME','RTF_SETFGCOLOR','RTF_SETEFFECT',
+ 'RTF_SETBGCOLOR','RTF_SETALIGN','RTF_SAVETOFILE','RTF_LOADFROMFILE','RTF_GETTEXT','RTF_GETFONTSIZE','RTF_GETFONTNAME','RTF_GETEFFECT',
+ 'RTF_GETCLASS','RTF_APPENDTEXT','RSET$','ROUND','RNDF','RND','RIGHT$','RIGHT',
+ 'RGB','RESOURCE','RESIZE','RESET','REPLACE$','REPEAT$','REMOVE$','REM',
+ 'REGISTRY_SETVALUE','REGISTRY_SETTXTNUM','REGISTRY_SETTXTBOOL','REGISTRY_SETDWORD','REGISTRY_GETVALUE','REGISTRY_GETTXTNUM','REGISTRY_GETTXTBOOL','REGISTRY_GETDWORD',
+ 'REGISTRY_GETALLKEYS','REGISTRY_DELVALUE','REGISTRY_DELKEY','REFERENCE','REF','REDRAW','REDIM','RAS_SETPARAMS',
+ 'RAS_OPENDIALUPDIALOG','RAS_LOADENTRIES','RAS_HANGUPALL','RAS_HANGUP','RAS_GETENTRY','RAS_BEGINDIAL','RANDOMIZE','RADTODEG',
+ 'QUERYPERFORMANCEFREQUENCY','QUERYPERFORMANCECOUNTER','QUAD','PTR','PRESERVE','POST','POPUP','POKE$',
+ 'POKE','PIXELS','PI','PERMUTATIONS','PEEKMESSAGE','PEEK$','PEEK','PC_SYSTEMUPFROM',
+ 'PC_SUSPENDSTATE','PC_SHUTDOWN','PC_SHOWCARET','PC_SETCARETBLINKTIME','PC_RESTARTDIALOG','PC_PREVENTSHUTDOWN','PC_LOCK','PC_INSERTCD',
+ 'PC_HIDECARET','PC_GETSTATEONOFF','PC_GETSCROLLLOCKKEYSTATE','PC_GETNUMLOCKKEYSTATE','PC_GETCARETBLINKTIME','PC_GETCAPSLOCKKEYSTATE','PC_EMPTYBIN','PC_EJECTCD',
+ 'PC_DECODECDERROR','PCT','PARSESET$','PARSECOUNT','PARSE$','PARSE','PARAMETERS','OUTSIDE',
+ 'OS_WINVERSIONTEXT','OS_WINGETVERSIONTIMELINE','OS_SHELLEXECUTE','OS_SHELLABOUT','OS_SHELL','OS_SETLASTCALLDLLERROR','OS_SERVICESTOP','OS_SERVICESTATUSDESCRIPTION',
+ 'OS_SERVICESTARTTYPEDESCRIPTION','OS_SERVICESTART','OS_SERVICESETSTARTTYPE','OS_SERVICEQUERY','OS_SERVICEGETSTARTTYPE','OS_SERVICEGETLIST','OS_PROCESSKILLBYNAME','OS_PROCESSKILLBYID',
+ 'OS_PROCESSISRUNNING','OS_PROCESSGETLIST','OS_PROCESSGETID','OS_PROCESSARERUNNING','OS_MESSAGEBEEP','OS_ISWOW64','OS_ISFEATUREPRESENT','OS_IEVERSION',
+ 'OS_GETWINDOWSDIR','OS_GETUSERNAME','OS_GETTEMPDIR','OS_GETSYSTEMDIR','OS_GETSPECIALFOLDER','OS_GETLASTCALLDLLSTATUS','OS_GETLASTCALLDLLERROR','OS_GETCURRENTTHREADID',
+ 'OS_GETCURRENTPROCESSID','OS_GETCOMPUTERNAME','OS_GETCOMMANDS','OS_GETCOMMAND','OS_FLASHWINDOW','OS_FATALAPPEXIT','OS_ENVIRON','OS_CALLDLL',
+ 'OR','OPTIONAL','OPTION','OPT','ONCE','ON','OFF','NUMBER',
+ 'NOT','NEXT','NEW','MSGBOX','MOUSEPTR','MODULE','MODELESS','MODAL',
+ 'MOD','MKWRD$','MKS$','MKQ$','MKL$','MKI$','MKE$','MKDWD$',
+ 'MKD$','MKCUX$','MKCUR$','MKBYT$','MIN$','MIN','MID$','MENU',
+ 'MDI_CREATE','MCASE$','MAX$','MAX','MAKWRD','MAKLNG','MAKINT','MAKDWR',
+ 'LTRIM$','LSET$','LOWRD','LOOP','LONG','LOINT','LOG_WRITE','LOGB',
+ 'LOG2','LOG10','LOG','LOCAL','LOC','LL_UPDATEBYNAME','LL_UPDATE','LL_TOSTRING',
+ 'LL_TOFILE','LL_NAME','LL_GETITEM','LL_GETBYNUMBER','LL_FROMFILE','LL_FREE','LL_FINDLAST','LL_FINDBYNAME',
+ 'LL_FINDBYDATA','LL_DELETELIKE','LL_DELETEBYNAME','LL_DELETE','LL_DATABYNAME','LL_DATA','LL_COUNT','LL_ADD',
+ 'LISTBOX','LINE','LIBRARY_EXISTS','LIB','LEN','LEFT$','LEFT','LCASE$',
+ 'LBOUND','LABEL','KILL','JOIN$','ITERATE','ISWINDOW','ISUNICODE','ISTRUE',
+ 'ISODD','ISLIKE','ISFALSE','ISEVEN','IP_TOSTRING','IP_ADDR','INTERNALINFO','INTEGER',
+ 'INT','INSTR','INSIDE','INPUTBOX$','INI_SETKEY','INI_GETSECTIONSLIST','INI_GETSECTIONKEYLIST','INI_GETKEY',
+ 'INET_URLDOWNLOAD','INET_PING','INET_OPENDIALUPDIALOG','INET_GETSTATE','INET_GETREMOTEMACADDRESS','INET_GETIP','INET_GETCONNECTIONMODE','INCR',
+ 'IN','IMAGE','IIF$','IIF','IF','ICRYPTO_TESTSHA1','ICRYPTO_TESTMD5','ICRYPTO_TESTCRC32',
+ 'ICRYPTO_TESTCRC16','ICRYPTO_STRING2ASCII','ICRYPTO_SHA1','ICRYPTO_MD5','ICRYPTO_ENCRYPTRIJNDAEL','ICRYPTO_ENCRYPTRC4','ICRYPTO_DECRYPTRIJNDAEL','ICRYPTO_DECRYPTRC4',
+ 'ICRYPTO_CRC32','ICRYPTO_CRC16','ICRYPTO_BYTEXOR','ICRYPTO_BIN2ASCII','ICRYPTO_ASCII2STRING','ICRYPTO_ASCII2BIN','HOST_ADDR','HOSTNAME_TOIP',
+ 'HOSTIP_TONAME','HIWRD','HIINT','HEX$','HASH','HANDLE','GUIDTXT$','GUID$',
+ 'GRAPHIC','GLVOID','GLUSHORT','GLUINT','GLUBYTE','GLSIZEI','GLSHORT','GLOBAL',
+ 'GLINT','GLFLOAT','GLENUM','GLDOUBLE','GLCLAMPF','GLCLAMPD','GLBYTE','GLBOOLEAN',
+ 'GLBITFIELD','GETWINDOWMULTIKEYSTATE','GETWINDOWKEYSTATE','GETTICKCOUNT','GETS','GETMULTIASYNCKEYSTATE','GETMESSAGE','GETCURRENTINSTANCE',
+ 'GETAT','GETASYNCKEYSTATE','GET','FUNCTION_NPARAMS','FUNCTION_EXISTS','FUNCTION_CPARAMS','FUNCTION','FTP_SETSTRING',
+ 'FTP_SETSERVERDIR','FTP_SETNUMBER','FTP_SETMODE','FTP_SETLOGFILE','FTP_SETLOCALDIR','FTP_QUIT','FTP_PUTFILE','FTP_GETSTRING',
+ 'FTP_GETSERVERDIR','FTP_GETNUMBER','FTP_GETLOCALDIR','FTP_GETLIST','FTP_GETFILE','FTP_GETERRORSTRING','FTP_GETERRORNUMBER','FTP_FINISHED',
+ 'FTP_EXTRACT','FTP_DELFILE','FTP_CONNECT','FTP_COMMAND','FRAME','FRAC','FORMAT$','FOR',
+ 'FONT_LIST','FONT_CREATE','FONT','FOCUS','FLUSH','FIX','FILE_SIZE','FILE_SHELLDELETE',
+ 'FILE_SHELLCOPY','FILE_SETDATETIME','FILE_SEEK','FILE_SAVE','FILE_RENAME','FILE_PUT','FILE_PATHSPLIT','FILE_OPEN',
+ 'FILE_LOF','FILE_LOAD','FILE_LINEPRINT','FILE_LINEINPUT','FILE_KILL','FILE_GETVERSIONSTRING','FILE_GETVERSION','FILE_GETTIME',
+ 'FILE_GETDATETIMESTAMP','FILE_GETDATETIME','FILE_GETDATE','FILE_GET','FILE_EXISTS','FILE_EOF','FILE_COPY','FILE_CLOSE',
+ 'FILE_CHANGED','FILE_APPEND','FACTORIAL','EXTRACT$','EXT','EXPORT','EXP2','EXP10',
+ 'EXP','EXIT','EVAL_STRING','EVAL_SETSTRING','EVAL_SETNUMBER','EVAL_MATH','EVAL_LINKEXT','EVAL_GETSTRING',
+ 'EVAL_GETNUMBER','EVAL_ERRORGETTOKEN','EVAL_ERRORDESCRIPTION','EVAL_ERRORCLEAR','EVAL','ERRCLEAR','ERR','ENGINE_GETCURRENTTOKEN',
+ 'ENDIF','END','ENABLE','ELSEIF','ELSE','ECHO','DWORD','DT_YEAR',
+ 'DT_TIMETOSEC','DT_TIMESUBSECONDS','DT_TIMEFORMAT','DT_TIMEADDSECONDS','DT_SETTIMESEPARATOR','DT_SETDATESEPARATOR','DT_SETDATECENTURY','DT_SECTOTIME',
+ 'DT_SECTODATE','DT_SECOND','DT_MONTH','DT_MINUTE','DT_LASTDAYOFMONTH','DT_ISVALIDDATE','DT_ISLEAPYEAR','DT_HOUR',
+ 'DT_GETWEEKDAYNAME','DT_GETWEEKDAY','DT_GETTIMESTAMP','DT_GETTIMESEPARATOR','DT_GETMONTHNAME','DT_GETDATESEPARATOR','DT_GETDATECENTURY','DT_DAY',
+ 'DT_DATETOSEC','DT_DATETIMESUBSECONDS','DT_DATETIMEADDSECONDS','DT_DATESUBDAYS','DT_DATEFORMAT','DT_DATEDIFF','DT_DATEADDDAYS','DT_COOKIEDATE',
+ 'DRAW','DOUBLE','DOEVENTS','DO','DISABLE','DIR_REMOVE','DIR_MAKEALL','DIR_MAKE',
+ 'DIR_LISTARRAY','DIR_LIST','DIR_ISEMPTY','DIR_ISDIR','DIR_GETCURRENT','DIR_EXISTS','DIR_CHANGEDRIVE','DIR_CHANGE',
+ 'DIM','DICTIONARY_MEMINFO','DICTIONARY_LISTKEYS','DICTIONARY_FREE','DICTIONARY_FIND','DICTIONARY_EXISTS','DICTIONARY_CREATE','DICTIONARY_COUNT',
+ 'DICTIONARY_ADD','DIALOG_STOPEVENTS','DIALOG_SAVEFILE','DIALOG_OPENFILE','DIALOG_GETCONTROL','DIALOG_CHOOSECOLOR','DIALOG_BROWSEFORFOLDER','DIALOG',
+ 'DESKTOP','DESCENDING','DESCEND','DELETEOBJECT','DELETE','DEGTORAD','DECR','DECLARE',
+ 'DATE$','CVWRD','CVS','CVQ','CVL','CVI','CVE','CVDWD',
+ 'CVD','CVCUX','CVCUR','CVBYT','CURRENCY','CUR','CSET$','CSCH',
+ 'CSC','CRYPTO_GETPROVIDERTYPESCOUNT','CRYPTO_GETPROVIDERSCOUNT','CRYPTO_GETDEFAULTPROVIDER','CRYPTO_GENRANDOMSTRING','CRYPTO_ENUMPROVIDERTYPES','CRYPTO_ENUMPROVIDERS','CRYPTO_ENCRYPT',
+ 'CRYPTO_DECRYPT','CREATEFONT','COTH','COTAN','COSH','COS','CONTROL_SETTEXT','CONTROL_GETTEXT',
+ 'CONTROL_GETNUMBER','CONTROL','CONST','CONSOLE_WRITELINE','CONSOLE_WRITE','CONSOLE_WAITKEY','CONSOLE_SHOWWINDOW','CONSOLE_SHOWCURSOR',
+ 'CONSOLE_SETTITLE','CONSOLE_SETTEXTATTRIBUTE','CONSOLE_SETSTDHANDLE','CONSOLE_SETSCREENBUFFERSIZE','CONSOLE_SETPROGRESSBARCHAR','CONSOLE_SETOUTPUTMODE','CONSOLE_SETOUTPUTCP','CONSOLE_SETINPUTMODE',
+ 'CONSOLE_SETFILEAPISTOOEM','CONSOLE_SETFILEAPISTOANSI','CONSOLE_SETCURSORSIZE','CONSOLE_SETCURSORPOSITION','CONSOLE_SETCP','CONSOLE_SETACTIVESCREENBUFFER','CONSOLE_SCROLLWINDOW','CONSOLE_SCROLLBUFFERONEROW',
+ 'CONSOLE_SCROLLBUFFER','CONSOLE_SAVESCREEN','CONSOLE_RESTORESCREEN','CONSOLE_READLINE','CONSOLE_READ','CONSOLE_PROGRESSBAR','CONSOLE_PRINTLINE','CONSOLE_PRINTAT',
+ 'CONSOLE_PRINT','CONSOLE_NORMALSCREEN','CONSOLE_LINE','CONSOLE_INKEYB','CONSOLE_INKEY','CONSOLE_HIDECURSOR','CONSOLE_GETTITLE','CONSOLE_GETTEXTATTRIBUTE',
+ 'CONSOLE_GETSTDHANDLE','CONSOLE_GETSIZEY','CONSOLE_GETSIZEX','CONSOLE_GETPROGRESSBARCHAR','CONSOLE_GETOUTPUTMODE','CONSOLE_GETOUTPUTCP','CONSOLE_GETNUMBEROFMOUSEBUTTONS','CONSOLE_GETINPUTMODE',
+ 'CONSOLE_GETCURSORY','CONSOLE_GETCURSORX','CONSOLE_GETCURSORSIZE','CONSOLE_GETCURRENTFONTINDEX','CONSOLE_GETCP','CONSOLE_GENERATECTRLEVENT','CONSOLE_FULLSCREEN','CONSOLE_FREE',
+ 'CONSOLE_FOREGROUNDRGB','CONSOLE_ENABLECTRLC','CONSOLE_DISABLECTRLC','CONSOLE_CREATESCREENBUFFER','CONSOLE_COLORAT','CONSOLE_CLS','CONSOLE_BOX','CONSOLE_BACKGROUNDRGB',
+ 'CONSOLE_ATTACH','CONSOLE_AREFILEAPISANSI','CONSOLE_ALLOC','COM_VARIANTINIT','COM_VARIANTCOPY','COM_VARIANTCLEAR','COM_SUCCEEDED','COM_STRINGFROMCLSID',
+ 'COM_RELEASE','COM_QUERYINTERFACE','COM_PROGIDFROMCLSID','COM_ISEQUALIID','COM_ISEQUALGUID','COM_ISEQUALCLSID','COM_GETOBJECT','COM_GETENGINEGUID',
+ 'COM_EXECUTE','COM_DISPLAYERROR','COM_CREATEOBJECT','COM_CLSIDFROMSTRING','COM_CLSIDFROMPROGID','COM_BUILDVARIANT','COMBOBOX','COMBINATIONS',
+ 'COLOR','CLIPBOARD_SETTEXT','CLIPBOARD_GETTEXT','CLIENT','CLEARMESSAGES','CHR$','CHOOSE$','CHOOSE',
+ 'CHECKBOX','CHECK3STATE','CHECK','CGI_WRITELOGFILE','CGI_WRITE','CGI_URLDECODESTRING','CGI_UPLOADFILESTIME','CGI_UPLOADFILESNUMBER',
+ 'CGI_UPLOADFILESIZE','CGI_STARTSESSION','CGI_SETSESSIONVARIABLE','CGI_RESETDEFAULTSETTINGS','CGI_REMOVESPECIALCHARSPREFIX','CGI_REMOVEQUOTE','CGI_READ','CGI_LOADCONFIGFILE',
+ 'CGI_HEADER','CGI_GETSESSIONVARIABLE','CGI_GETREQUESTMETHOD','CGI_GETQUERYVALUE','CGI_GETCURRENTSESSION','CGI_GETCURRENTGUID','CGI_ENVIRON','CGI_CFGSETOPTION',
+ 'CGI_CFGGETOPTION','CGI_ADDSPECIALCHARSPREFIX','CGI_ADDQUOTE','CEIL','CASE','CALL','BYVAL','BYTE',
+ 'BYREF','BYCMD','BUTTON','BUNDLE_SETSCRIPTPARAMETERS','BUNDLE_SETSCRIPTNAME','BUNDLE_SETFLAGOBFUSCATEMAINSCRIPT','BUNDLE_SETFLAGDELETEAFTERRUN','BUNDLE_SETFLAGCOMPRESSALLFILES',
+ 'BUNDLE_SETFLAGASKBEFOREEXTRACT','BUNDLE_SETEXTRACTIONFOLDER','BUNDLE_SETCREATIONFOLDER','BUNDLE_SETBUNDLENAME','BUNDLE_RESET','BUNDLE_MAKE','BUNDLE_BUILDER','BUNDLE_ADDFOLDER',
+ 'BUNDLE_ADDFILE','BOUNDCHECK','BIN$','BIFF_WRITETEXT','BIFF_WRITENUMBER','BIFF_WRITEDATE','BIFF_SETROWHEIGHT','BIFF_SETCOLWIDTH',
+ 'BIFF_SETBUFFER','BIFF_CREATEFILE','BIFF_CLOSEFILE','BETWEEN','BEEP','BAR','ATTACH','ATN',
+ 'AT','ASSIGN','ASCIZ','ASCIIZ','ASCII2UNICODE','ASCENDING','ASCEND','ASC',
+ 'AS','ARRAY','ARCTANH','ARCSINH','ARCSIN','ARCSECH','ARCSEC','ARCCSCH',
+ 'ARCCSC','ARCCOTH','ARCCOT','ARCCOSH','ARCCOS','APP_TIMER','APP_SOURCEPATH','APP_SOURCENAME',
+ 'APP_SOURCEFULLNAME','APP_PATH','APP_NAME','APP_LISTVARIABLES','APP_LISTKEYWORDS','APP_LISTFUNCTIONS','APP_LISTEQUATES','APP_INCLUDEPATH',
+ 'APP_GETMODULEFULLPATH','APP_COUNTER','APPEND','ANY','ANIMATE_STOP','ANIMATE_PLAY','ANIMATE_OPEN','AND',
+ 'ALIAS','ALERT','ADD','ACODE$','ABS','%DEF','#MINVERSION','#IF',
+ '#ENDIF','#ELSEIF','#ELSE','#DEFAULT','#DEF','SQLWRITEPRIVATEPROFILESTRING','SQLWRITEFILEDSN','SQLWRITEDSNTOINI',
+ 'SQLVALIDDSN','SQLTRANSACT','SQLTABLES','SQLTABLEPRIVILEGES','SQLSTATISTICS','SQLSPECIALCOLUMNS','SQLSETSTMTOPTION','SQLSETSTMTATTR',
+ 'SQLSETSCROLLOPTIONS','SQLSETPOS','SQLSETPARAM','SQLSETENVATTR','SQLSETDESCREC','SQLSETDESCFIELD','SQLSETCURSORNAME','SQLSETCONNECTOPTION',
+ 'SQLSETCONNECTATTR','SQLSETCONFIGMODE','SQLROWCOUNT','SQLREMOVETRANSLATOR','SQLREMOVEDSNFROMINI','SQLREMOVEDRIVERMANAGER','SQLREMOVEDRIVER','SQLREADFILEDSN',
+ 'SQLPUTDATA','SQLPROCEDURES','SQLPROCEDURECOLUMNS','SQLPRIMARYKEYS','SQLPREPARE','SQLPOSTINSTALLERERROR','SQLPARAMOPTIONS','SQLPARAMDATA',
+ 'SQLNUMRESULTCOLS','SQLNUMPARAMS','SQLNATIVESQL','SQLMORERESULTS','SQLMANAGEDATASOURCES','SQLINSTALLTRANSLATOREX','SQLINSTALLERERROR','SQLINSTALLDRIVERMANAGER',
+ 'SQLINSTALLDRIVEREX','SQLGETTYPEINFO','SQLGETTRANSLATOR','SQLGETSTMTOPTION','SQLGETSTMTATTR','SQLGETPRIVATEPROFILESTRING','SQLGETINSTALLEDDRIVERS','SQLGETINFO',
+ 'SQLGETFUNCTIONS','SQLGETENVATTR','SQLGETDIAGREC','SQLGETDIAGFIELD','SQLGETDESCREC','SQLGETDESCFIELD','SQLGETDATA','SQLGETCURSORNAME',
+ 'SQLGETCONNECTOPTION','SQLGETCONNECTATTR','SQLGETCONFIGMODE','SQLFREESTMT','SQLFREEHANDLE','SQLFREEENV','SQLFREECONNECT','SQLFOREIGNKEYS',
+ 'SQLFETCHSCROLL','SQLFETCH','SQLEXTENDEDFETCH','SQLEXECUTE','SQLEXECDIRECT','SQLERROR','SQLENDTRAN','SQLDRIVERS',
+ 'SQLDRIVERCONNECT','SQLDISCONNECT','SQLDESCRIBEPARAM','SQLDESCRIBECOL','SQLDATASOURCES','SQLCREATEDATASOURCE','SQLCOPYDESC','SQLCONNECT',
+ 'SQLCONFIGDRIVER','SQLCONFIGDATASOURCE','SQLCOLUMNS','SQLCOLUMNPRIVILEGES','SQLCOLATTRIBUTES','SQLCOLATTRIBUTE','SQLCLOSECURSOR','SQLCANCEL',
+ 'SQLBULKOPERATIONS','SQLBROWSECONNECT','SQLBINDPARAMETER','SQLBINDPARAM','SQLBINDCOL','SQLALLOCSTMT','SQLALLOCHANDLE','SQLALLOCENV',
+ 'SQLALLOCCONNECT','ODBCWRONGDRIVER','ODBCWRITEPRIVATEPROFILESTRING','ODBCWRITEFILEDSN','ODBCWRITEDSNTOINI','ODBCVALIDDSN','ODBCUPDATERECORD','ODBCUPDATEBYBOOKMARK',
+ 'ODBCUNLOCKRECORD','ODBCUNBINDCOLUMNS','ODBCUNBINDCOL','ODBCTABLESCOUNT','ODBCTABLES','ODBCTABLEPRIVILEGESCOUNT','ODBCTABLEPRIVILEGES','ODBCSUPPORTS',
+ 'ODBCSTATTABLESCHEMANAME','ODBCSTATTABLEPAGES','ODBCSTATTABLECATALOGNAME','ODBCSTATTABLECARDINALITY','ODBCSTATISTICSCOUNT','ODBCSTATISTICS','ODBCSTATINDEXSORTSEQUENCE','ODBCSTATINDEXSCHEMANAME',
+ 'ODBCSTATINDEXQUALIFIER','ODBCSTATINDEXPAGES','ODBCSTATINDEXFILTERCONDITION','ODBCSTATINDEXCOLUMNORDINALPOSITION','ODBCSTATINDEXCOLUMNNAME','ODBCSTATINDEXCATALOGNAME','ODBCSTATINDEXCARDINALITY','ODBCSTATINDEXALLOWDUPLICATES',
+ 'ODBCSPECIALCOLUMNSCOUNT','ODBCSPECIALCOLUMNS','ODBCSETTXNISOLATION','ODBCSETTRANSLATELIB','ODBCSETTRACEFILE','ODBCSETTRACE','ODBCSETSTMTUSEBOOKMARKS','ODBCSETSTMTSIMULATECURSOR',
+ 'ODBCSETSTMTROWSTATUSPTR','ODBCSETSTMTROWSFETCHEDPTR','ODBCSETSTMTROWOPERATIONPTR','ODBCSETSTMTROWBINDTYPE','ODBCSETSTMTROWBINDOFFSETPTR','ODBCSETSTMTROWARRAYSIZE','ODBCSETSTMTRETRIEVEDATA','ODBCSETSTMTQUERYTIMEOUT',
+ 'ODBCSETSTMTPARAMSTATUSPTR','ODBCSETSTMTPARAMSPROCESSEDPTR','ODBCSETSTMTPARAMSETSIZE','ODBCSETSTMTPARAMOPERATIONPTR','ODBCSETSTMTPARAMBINDTYPE','ODBCSETSTMTPARAMBINDOFFSETPTR','ODBCSETSTMTNOSCAN','ODBCSETSTMTMETADATAID',
+ 'ODBCSETSTMTMAXROWS','ODBCSETSTMTMAXLENGTH','ODBCSETSTMTKEYSETSIZE','ODBCSETSTMTFETCHBOOKMARKPTR','ODBCSETSTMTENABLEAUTOIPD','ODBCSETSTMTCURSORTYPE','ODBCSETSTMTCURSORSENSITIVITY','ODBCSETSTMTCURSORSCROLLABLE',
+ 'ODBCSETSTMTCONCURRENCY','ODBCSETSTMTATTR','ODBCSETSTMTASYNCENABLE','ODBCSETSTMTAPPROWDESC','ODBCSETSTMTAPPPARAMDESC','ODBCSETSTATICCURSOR','ODBCSETROWVERCONCURRENCY','ODBCSETRESULT',
+ 'ODBCSETRELATIVEPOSITION','ODBCSETREADONLYCONCURRENCY','ODBCSETQUIETMODE','ODBCSETPOSITION','ODBCSETPOS','ODBCSETPACKETMODE','ODBCSETOPTIMISTICCONCURRENCY','ODBCSETODBCCURSORS',
+ 'ODBCSETMULTIUSERKEYSETCURSOR','ODBCSETMETADATAID','ODBCSETLOGINTIMEOUT','ODBCSETLOCKCONCURRENCY','ODBCSETKEYSETDRIVENCURSOR','ODBCSETFORWARDONLYCURSOR','ODBCSETENVOUTPUTNTS','ODBCSETENVODBCVERSION',
+ 'ODBCSETENVCPMATCH','ODBCSETENVCONNECTIONPOOLING','ODBCSETENVATTR','ODBCSETDYNAMICCURSOR','ODBCSETDESCREC','ODBCSETDESCFIELD','ODBCSETCURSORTYPE','ODBCSETCURSORSENSITIVITY',
+ 'ODBCSETCURSORSCROLLABILITY','ODBCSETCURSORNAME','ODBCSETCURSORLOCKTYPE','ODBCSETCURSORKEYSETSIZE','ODBCSETCURSORCONCURRENCY','ODBCSETCURRENTCATALOG','ODBCSETCONNECTIONTIMEOUT','ODBCSETCONNECTATTR',
+ 'ODBCSETCONFIGMODE','ODBCSETCONCURVALUESCONCURRENCY','ODBCSETAUTOCOMMITON','ODBCSETAUTOCOMMITOFF','ODBCSETAUTOCOMMIT','ODBCSETASYNCENABLE','ODBCSETACCESSMODE','ODBCSETABSOLUTEPOSITION',
+ 'ODBCROWCOUNT','ODBCROLLBACKTRAN','ODBCROLLBACKENVTRAN','ODBCROLLBACKDBCTRAN','ODBCRESULT','ODBCRESETPARAMS','ODBCREMOVETRANSLATOR','ODBCREMOVEDSNFROMINI',
+ 'ODBCREMOVEDRIVERMANAGER','ODBCREMOVEDRIVER','ODBCREFRESHRECORD','ODBCRECORDCOUNT','ODBCREADFILEDSN','ODBCQUOTEDIDENTIFIERCASE','ODBCPUTDATA','ODBCPROCEDURESCOUNT',
+ 'ODBCPROCEDURES','ODBCPROCEDURECOLUMNSCOUNT','ODBCPROCEDURECOLUMNS','ODBCPRIMARYKEYSCOUNT','ODBCPRIMARYKEYS','ODBCPREPARE','ODBCPOSTINSTALLERERROR','ODBCPARAMDATA',
+ 'ODBCOPENSTMT','ODBCOPENCONNECTION','ODBCNUMRESULTCOLS','ODBCNUMPARAMS','ODBCNATIVESQL','ODBCMOVEPREVIOUS','ODBCMOVENEXT','ODBCMOVELAST',
+ 'ODBCMOVEFIRST','ODBCMOVE','ODBCMORERESULTS','ODBCMANAGEDATASOURCES','ODBCLOCKRECORD','ODBCINSTALLTRANSLATOREX','ODBCINSTALLERERROR','ODBCINSTALLDRIVERMANAGER',
+ 'ODBCINSTALLDRIVEREX','ODBCGETXOPENCLIYEAR','ODBCGETUSERNAME','ODBCGETUNION','ODBCGETTYPEINFOCOUNT','ODBCGETTYPEINFO','ODBCGETTXNISOLATIONOPTION','ODBCGETTXNISOLATION',
+ 'ODBCGETTXNCAPABLE','ODBCGETTRANSLATOR','ODBCGETTRANSLATELIB','ODBCGETTRACEFILE','ODBCGETTRACE','ODBCGETTIMEDATEFUNCTIONS','ODBCGETTIMEDATEDIFFINTERVALS','ODBCGETTIMEDATEADDINTERVALS',
+ 'ODBCGETTABLETERM','ODBCGETSYSTEMFUNCTIONS','ODBCGETSUBQUERIES','ODBCGETSTRINGFUNCTIONS','ODBCGETSTMTUSEBOOKMARKS','ODBCGETSTMTSQLSTATE','ODBCGETSTMTSIMULATECURSOR','ODBCGETSTMTROWSTATUSPTR',
+ 'ODBCGETSTMTROWSFETCHEDPTR','ODBCGETSTMTROWOPERATIONPTR','ODBCGETSTMTROWNUMBER','ODBCGETSTMTROWBINDTYPE','ODBCGETSTMTROWBINDOFFSETPTR','ODBCGETSTMTROWARRAYSIZE','ODBCGETSTMTRETRIEVEDATA','ODBCGETSTMTQUERYTIMEOUT',
+ 'ODBCGETSTMTPARAMSTATUSPTR','ODBCGETSTMTPARAMSPROCESSEDPTR','ODBCGETSTMTPARAMSETSIZE','ODBCGETSTMTPARAMOPERATIONPTR','ODBCGETSTMTPARAMBINDTYPE','ODBCGETSTMTPARAMBINDOFFSETPTR','ODBCGETSTMTNOSCAN','ODBCGETSTMTMETADATAID',
+ 'ODBCGETSTMTMAXROWS','ODBCGETSTMTMAXLENGTH','ODBCGETSTMTKEYSETSIZE','ODBCGETSTMTIMPROWDESC','ODBCGETSTMTIMPPARAMDESC','ODBCGETSTMTFETCHBOOKMARKPTR','ODBCGETSTMTERRORINFO','ODBCGETSTMTENABLEAUTOIPD',
+ 'ODBCGETSTMTCURSORTYPE','ODBCGETSTMTCURSORSENSITIVITY','ODBCGETSTMTCURSORSCROLLABLE','ODBCGETSTMTCONCURRENCY','ODBCGETSTMTATTR','ODBCGETSTMTASYNCENABLE','ODBCGETSTMTAPPROWDESC','ODBCGETSTMTAPPPARAMDESC',
+ 'ODBCGETSTATICCURSORATTRIBUTES2','ODBCGETSTATICCURSORATTRIBUTES1','ODBCGETSTATEMENTSQLSTATE','ODBCGETSTATEMENTERRORINFO','ODBCGETSTANDARDCLICONFORMANCE','ODBCGETSQLSTATE','ODBCGETSQLCONFORMANCE','ODBCGETSQL92VALUEEXPRESSIONS',
+ 'ODBCGETSQL92STRINGFUNCTIONS','ODBCGETSQL92ROWVALUECONSTRUCTOR','ODBCGETSQL92REVOKE','ODBCGETSQL92RELATIONALJOINOPERATORS','ODBCGETSQL92PREDICATES','ODBCGETSQL92NUMERICVALUEFUNCTIONS','ODBCGETSQL92GRANT','ODBCGETSQL92FOREIGNKEYUPDATERULE',
+ 'ODBCGETSQL92FOREIGNKEYDELETERULE','ODBCGETSQL92DATETIMEFUNCTIONS','ODBCGETSPECIALCHARACTERS','ODBCGETSERVERNAME','ODBCGETSEARCHPATTERNESCAPE','ODBCGETSCROLLOPTIONS','ODBCGETSCHEMAUSAGE','ODBCGETSCHEMATERM',
+ 'ODBCGETROWUPDATES','ODBCGETQUIETMODE','ODBCGETPROCEDURETERM','ODBCGETPROCEDURESSUPPORT','ODBCGETPRIVATEPROFILESTRING','ODBCGETPOSOPERATIONS','ODBCGETPARAMARRAYSELECTS','ODBCGETPARAMARRAYROWCOUNTS',
+ 'ODBCGETPACKETMODE','ODBCGETOUTERJOINS','ODBCGETORDERBYCOLUMNSINSELECT','ODBCGETOJCAPABILITIES','ODBCGETODBCVER','ODBCGETODBCINTERFACECONFORMANCE','ODBCGETODBCCURSORS','ODBCGETNUMERICFUNCTIONS',
+ 'ODBCGETNULLCOLLATION','ODBCGETNONNULLABLECOLUMNS','ODBCGETNEEDLONGDATALEN','ODBCGETMULTRESULTSETS','ODBCGETMULTIPLEACTIVETXN','ODBCGETMETADATAID','ODBCGETMAXUSERNAMELEN','ODBCGETMAXTABLESINSELECT',
+ 'ODBCGETMAXTABLENAMELEN','ODBCGETMAXSTATEMENTLEN','ODBCGETMAXSCHEMANAMELEN','ODBCGETMAXROWSIZEINCLUDESLONG','ODBCGETMAXROWSIZE','ODBCGETMAXPROCEDURENAMELEN','ODBCGETMAXINDEXSIZE','ODBCGETMAXIDENTIFIERLEN',
+ 'ODBCGETMAXDRIVERCONNECTIONS','ODBCGETMAXCURSORNAMELEN','ODBCGETMAXCONCURRENTACTIVITIES','ODBCGETMAXCOLUMNSINTABLE','ODBCGETMAXCOLUMNSINSELECT','ODBCGETMAXCOLUMNSINORDERBY','ODBCGETMAXCOLUMNSININDEX','ODBCGETMAXCOLUMNSINGROUPBY',
+ 'ODBCGETMAXCOLUMNNAMELEN','ODBCGETMAXCHARLITERALLEN','ODBCGETMAXCATALOGNAMELEN','ODBCGETMAXBINARYLITERALLEN','ODBCGETMAXASYNCCONCURRENTSTATEMENTS','ODBCGETLONGVARCHARDATABYCOLNAME','ODBCGETLONGVARCHARDATA','ODBCGETLOGINTIMEOUT',
+ 'ODBCGETLIKEESCAPECLAUSE','ODBCGETKEYWORDS','ODBCGETKEYSETCURSORATTRIBUTES2','ODBCGETKEYSETCURSORATTRIBUTES1','ODBCGETINTEGRITY','ODBCGETINSTALLERERRORMESSAGE','ODBCGETINSTALLERERRORCODE','ODBCGETINSTALLEDDRIVERS',
+ 'ODBCGETINSERTSTATEMENT','ODBCGETINFOSTR','ODBCGETINFOSCHEMAVIEWS','ODBCGETINFOLONG','ODBCGETINFOINT','ODBCGETINFO','ODBCGETINDEXKEYWORDS','ODBCGETIMPROWDESCREC',
+ 'ODBCGETIMPROWDESCFIELDTYPE','ODBCGETIMPROWDESCFIELDSCALE','ODBCGETIMPROWDESCFIELDPRECISION','ODBCGETIMPROWDESCFIELDOCTETLENGTH','ODBCGETIMPROWDESCFIELDNULLABLE','ODBCGETIMPROWDESCFIELDNAME','ODBCGETIMPROWDESCFIELD','ODBCGETIMPPARAMDESCREC',
+ 'ODBCGETIMPPARAMDESCFIELDTYPE','ODBCGETIMPPARAMDESCFIELDSCALE','ODBCGETIMPPARAMDESCFIELDPRECISION','ODBCGETIMPPARAMDESCFIELDOCTETLENGTH','ODBCGETIMPPARAMDESCFIELDNULLABLE','ODBCGETIMPPARAMDESCFIELDNAME','ODBCGETIMPPARAMDESCFIELD','ODBCGETIDENTIFIERQUOTECHAR',
+ 'ODBCGETIDENTIFIERCASE','ODBCGETGROUPBY','ODBCGETFUNCTIONS','ODBCGETFORWARDONLYCURSORATTRIBUTES2','ODBCGETFORWARDONLYCURSORATTRIBUTES1','ODBCGETFILEUSAGE','ODBCGETEXPRESSIONSINORDERBY','ODBCGETERRORINFO',
+ 'ODBCGETENVSQLSTATE','ODBCGETENVOUTPUTNTS','ODBCGETENVODBCVERSION','ODBCGETENVIRONMENTSQLSTATE','ODBCGETENVIRONMENTERRORINFO','ODBCGETENVERRORINFO','ODBCGETENVCPMATCH','ODBCGETENVCONNECTIONPOOLING',
+ 'ODBCGETENVATTR','ODBCGETDYNAMICCURSORATTRIBUTES2','ODBCGETDYNAMICCURSORATTRIBUTES1','ODBCGETDROPVIEW','ODBCGETDROPTRANSLATION','ODBCGETDROPTABLE','ODBCGETDROPSCHEMA','ODBCGETDROPDOMAIN',
+ 'ODBCGETDROPCOLLATION','ODBCGETDROPCHARACTERSET','ODBCGETDROPASSERTION','ODBCGETDRIVERVER','ODBCGETDRIVERODBCVER','ODBCGETDRIVERNAME','ODBCGETDRIVERMANAGERINSTALLPATH','ODBCGETDRIVERHLIB',
+ 'ODBCGETDRIVERHENV','ODBCGETDRIVERHDBC','ODBCGETDMVERMINOR','ODBCGETDMVERMAJOR','ODBCGETDMVER','ODBCGETDIAGREC','ODBCGETDIAGFIELD','ODBCGETDESCSQLSTATE',
+ 'ODBCGETDESCRIPTORSQLSTATE','ODBCGETDESCRIPTORERRORINFO','ODBCGETDESCRIBEPARAMETER','ODBCGETDESCREC','ODBCGETDESCFIELD','ODBCGETDESCERRORINFO','ODBCGETDEFAULTTXNISOLATION','ODBCGETDDLINDEX',
+ 'ODBCGETDBMSVER','ODBCGETDBMSNAME','ODBCGETDBCSQLSTATE','ODBCGETDBCERRORINFO','ODBCGETDATETIMELITERALS','ODBCGETDATASTRINGBYCOLNAME','ODBCGETDATASTRING','ODBCGETDATASOURCEREADONLY',
+ 'ODBCGETDATASOURCENAME','ODBCGETDATAEXTENSIONS','ODBCGETDATABASENAME','ODBCGETDATA','ODBCGETCURSORTYPE','ODBCGETCURSORSENSITIVITYSUPPORT','ODBCGETCURSORSENSITIVITY','ODBCGETCURSORSCROLLABILITY',
+ 'ODBCGETCURSORROLLBACKBEHAVIOR','ODBCGETCURSORNAME','ODBCGETCURSORLOCKTYPE','ODBCGETCURSORKEYSETSIZE','ODBCGETCURSORCONCURRENCY','ODBCGETCURSORCOMMITBEHAVIOR','ODBCGETCURRENTCATALOG','ODBCGETCREATEVIEW',
+ 'ODBCGETCREATETRANSLATION','ODBCGETCREATETABLE','ODBCGETCREATESCHEMA','ODBCGETCREATEDOMAIN','ODBCGETCREATECOLLATION','ODBCGETCREATECHARACTERSET','ODBCGETCREATEASSERTION','ODBCGETCORRELATIONNAME',
+ 'ODBCGETCONVERTVARCHAR','ODBCGETCONVERTVARBINARY','ODBCGETCONVERTTINYINT','ODBCGETCONVERTTIMESTAMP','ODBCGETCONVERTTIME','ODBCGETCONVERTSMALLINT','ODBCGETCONVERTREAL','ODBCGETCONVERTNUMERIC',
+ 'ODBCGETCONVERTLONGVARCHAR','ODBCGETCONVERTLONGVARBINARY','ODBCGETCONVERTINTERVALYEARMONTH','ODBCGETCONVERTINTERVALDAYTIME','ODBCGETCONVERTINTEGER','ODBCGETCONVERTFUNCTIONS','ODBCGETCONVERTFLOAT','ODBCGETCONVERTDOUBLE',
+ 'ODBCGETCONVERTDECIMAL','ODBCGETCONVERTDATE','ODBCGETCONVERTCHAR','ODBCGETCONVERTBIT','ODBCGETCONVERTBINARY','ODBCGETCONVERTBIGINT','ODBCGETCONNECTIONTIMEOUT','ODBCGETCONNECTIONSQLSTATE',
+ 'ODBCGETCONNECTIONERRORINFO','ODBCGETCONNECTIONDEAD','ODBCGETCONNECTATTR','ODBCGETCONFIGMODE','ODBCGETCONCATNULLBEHAVIOR','ODBCGETCOLUMNALIAS','ODBCGETCOLLATIONSEQ','ODBCGETCATALOGUSAGE',
+ 'ODBCGETCATALOGTERM','ODBCGETCATALOGNAMESEPARATOR','ODBCGETCATALOGNAME','ODBCGETCATALOGLOCATION','ODBCGETBOOKMARKPERSISTENCE','ODBCGETBATCHSUPPORT','ODBCGETBATCHROWCOUNT','ODBCGETAUTOIPD',
+ 'ODBCGETAUTOCOMMIT','ODBCGETASYNCMODE','ODBCGETASYNCENABLE','ODBCGETALTERTABLE','ODBCGETALTERDOMAIN','ODBCGETAGGREGATEFUNCTIONS','ODBCGETACTIVEENVIRONMENTS','ODBCGETACCESSMODE',
+ 'ODBCGETACCESSIBLETABLES','ODBCGETACCESSIBLEPROCEDURES','ODBCFREESTMT','ODBCFREEHANDLE','ODBCFREEENV','ODBCFREEDESC','ODBCFREEDBC','ODBCFREECONNECT',
+ 'ODBCFOREIGNKEYSCOUNT','ODBCFOREIGNKEYS','ODBCFETCHSCROLL','ODBCFETCHBYBOOKMARK','ODBCFETCH','ODBCEXTENDEDFETCH','ODBCEXECUTE','ODBCEXECDIRECT',
+ 'ODBCERROR','ODBCEOF','ODBCENDTRAN','ODBCDRIVERSCOUNT','ODBCDRIVERS','ODBCDRIVERCONNECT','ODBCDISCONNECT','ODBCDESCRIBEPARAM',
+ 'ODBCDESCRIBECOL','ODBCDELETERECORD','ODBCDELETEBYBOOKMARK','ODBCDATASOURCES','ODBCCREATEDATASOURCE','ODBCCOPYDESC','ODBCCONNECTIONISDEAD','ODBCCONNECTIONISALIVE',
+ 'ODBCCONNECT','ODBCCONFIGDRIVER','ODBCCONFIGDATASOURCE','ODBCCOMMITTRAN','ODBCCOMMITENVTRAN','ODBCCOMMITDBCTRAN','ODBCCOLUPDATABLE','ODBCCOLUNSIGNED',
+ 'ODBCCOLUNNAMED','ODBCCOLUMNSCOUNT','ODBCCOLUMNS','ODBCCOLUMNPRIVILEGESCOUNT','ODBCCOLUMNPRIVILEGES','ODBCCOLUMN','ODBCCOLTYPENAME','ODBCCOLTYPE',
+ 'ODBCCOLTABLENAME','ODBCCOLSEARCHABLE','ODBCCOLSCHEMANAME','ODBCCOLSCALE','ODBCCOLPRECISION','ODBCCOLOCTETLENGTH','ODBCCOLNUMPRECRADIX','ODBCCOLNULLABLE',
+ 'ODBCCOLNAME','ODBCCOLLOCALTYPENAME','ODBCCOLLITERALSUFFIX','ODBCCOLLITERALPREFIX','ODBCCOLLENGTH','ODBCCOLLABEL','ODBCCOLISNULL','ODBCCOLFIXEDPRECSCALE',
+ 'ODBCCOLDISPLAYSIZE','ODBCCOLCOUNT','ODBCCOLCONCISETYPE','ODBCCOLCATALOGNAME','ODBCCOLCASESENSITIVE','ODBCCOLBASETABLENAME','ODBCCOLBASECOLUMNNAME','ODBCCOLAUTOUNIQUEVALUE',
+ 'ODBCCOLATTRIBUTE','ODBCCLOSESTMTCURSOR','ODBCCLOSESTMT','ODBCCLOSECURSOR','ODBCCLOSECONNECTION','ODBCCLEARRESULT','ODBCCANCEL','ODBCBULKOPERATIONS',
+ 'ODBCBROWSECONNECT','ODBCBINDPARAMETER','ODBCBINDCOLTOWORD','ODBCBINDCOLTOTIMESTAMP','ODBCBINDCOLTOTIME','ODBCBINDCOLTOSTRING','ODBCBINDCOLTOSINGLE','ODBCBINDCOLTOQUAD',
+ 'ODBCBINDCOLTONUMERIC','ODBCBINDCOLTOLONG','ODBCBINDCOLTOINTEGER','ODBCBINDCOLTODWORD','ODBCBINDCOLTODOUBLE','ODBCBINDCOLTODECIMAL','ODBCBINDCOLTODATE','ODBCBINDCOLTOCURRENCY',
+ 'ODBCBINDCOLTOBYTE','ODBCBINDCOLTOBIT','ODBCBINDCOLTOBINARY','ODBCBINDCOL','ODBCALLOCSTMT','ODBCALLOCHANDLE','ODBCALLOCENV','ODBCALLOCDESC',
+ 'ODBCALLOCDBC','ODBCALLOCCONNECT','ODBCADDRECORD','GLVIEWPORT','GLVERTEXPOINTER','GLVERTEX4SV','GLVERTEX4S','GLVERTEX4IV',
+ 'GLVERTEX4I','GLVERTEX4FV','GLVERTEX4F','GLVERTEX4DV','GLVERTEX4D','GLVERTEX3SV','GLVERTEX3S','GLVERTEX3IV',
+ 'GLVERTEX3I','GLVERTEX3FV','GLVERTEX3F','GLVERTEX3DV','GLVERTEX3D','GLVERTEX2SV','GLVERTEX2S','GLVERTEX2IV',
+ 'GLVERTEX2I','GLVERTEX2FV','GLVERTEX2F','GLVERTEX2DV','GLVERTEX2D','GLUUNPROJECT','GLUTESSVERTEX','GLUTESSPROPERTY',
+ 'GLUTESSNORMAL','GLUTESSENDPOLYGON','GLUTESSENDCONTOUR','GLUTESSCALLBACK','GLUTESSBEGINPOLYGON','GLUTESSBEGINCONTOUR','GLUSPHERE','GLUSCALEIMAGE',
+ 'GLUQUADRICTEXTURE','GLUQUADRICORIENTATION','GLUQUADRICNORMALS','GLUQUADRICDRAWSTYLE','GLUQUADRICCALLBACK','GLUPWLCURVE','GLUPROJECT','GLUPICKMATRIX',
+ 'GLUPERSPECTIVE','GLUPARTIALDISK','GLUORTHO2D','GLUNURBSSURFACE','GLUNURBSPROPERTY','GLUNURBSCURVE','GLUNURBSCALLBACK','GLUNEXTCONTOUR',
+ 'GLUNEWTESS','GLUNEWQUADRIC','GLUNEWNURBSRENDERER','GLULOOKAT','GLULOADSAMPLINGMATRICES','GLUGETTESSPROPERTY','GLUGETSTRING','GLUGETNURBSPROPERTY',
+ 'GLUERRORSTRING','GLUENDTRIM','GLUENDSURFACE','GLUENDPOLYGON','GLUENDCURVE','GLUDISK','GLUDELETETESS','GLUDELETEQUADRIC',
+ 'GLUDELETENURBSRENDERER','GLUCYLINDER','GLUBUILD2DMIPMAPS','GLUBUILD1DMIPMAPS','GLUBEGINTRIM','GLUBEGINSURFACE','GLUBEGINPOLYGON','GLUBEGINCURVE',
+ 'GLTRANSLATEF','GLTRANSLATED','GLTEXSUBIMAGE2D','GLTEXSUBIMAGE1D','GLTEXPARAMETERIV','GLTEXPARAMETERI','GLTEXPARAMETERFV','GLTEXPARAMETERF',
+ 'GLTEXIMAGE2D','GLTEXIMAGE1D','GLTEXGENIV','GLTEXGENI','GLTEXGENFV','GLTEXGENF','GLTEXGENDV','GLTEXGEND',
+ 'GLTEXENVIV','GLTEXENVI','GLTEXENVFV','GLTEXENVF','GLTEXCOORDPOINTER','GLTEXCOORD4SV','GLTEXCOORD4S','GLTEXCOORD4IV',
+ 'GLTEXCOORD4I','GLTEXCOORD4FV','GLTEXCOORD4F','GLTEXCOORD4DV','GLTEXCOORD4D','GLTEXCOORD3SV','GLTEXCOORD3S','GLTEXCOORD3IV',
+ 'GLTEXCOORD3I','GLTEXCOORD3FV','GLTEXCOORD3F','GLTEXCOORD3DV','GLTEXCOORD3D','GLTEXCOORD2SV','GLTEXCOORD2S','GLTEXCOORD2IV',
+ 'GLTEXCOORD2I','GLTEXCOORD2FV','GLTEXCOORD2F','GLTEXCOORD2DV','GLTEXCOORD2D','GLTEXCOORD1SV','GLTEXCOORD1S','GLTEXCOORD1IV',
+ 'GLTEXCOORD1I','GLTEXCOORD1FV','GLTEXCOORD1F','GLTEXCOORD1DV','GLTEXCOORD1D','GLSTENCILOP','GLSTENCILMASK','GLSTENCILFUNC',
+ 'GLSHADEMODEL','GLSELECTBUFFER','GLSCISSOR','GLSCALEF','GLSCALED','GLROTATEF','GLROTATED','GLRENDERMODE',
+ 'GLRECTSV','GLRECTS','GLRECTIV','GLRECTI','GLRECTFV','GLRECTF','GLRECTDV','GLRECTD',
+ 'GLREADPIXELS','GLREADBUFFER','GLRASTERPOS4SV','GLRASTERPOS4S','GLRASTERPOS4IV','GLRASTERPOS4I','GLRASTERPOS4FV','GLRASTERPOS4F',
+ 'GLRASTERPOS4DV','GLRASTERPOS4D','GLRASTERPOS3SV','GLRASTERPOS3S','GLRASTERPOS3IV','GLRASTERPOS3I','GLRASTERPOS3FV','GLRASTERPOS3F',
+ 'GLRASTERPOS3DV','GLRASTERPOS3D','GLRASTERPOS2SV','GLRASTERPOS2S','GLRASTERPOS2IV','GLRASTERPOS2I','GLRASTERPOS2FV','GLRASTERPOS2F',
+ 'GLRASTERPOS2DV','GLRASTERPOS2D','GLPUSHNAME','GLPUSHMATRIX','GLPUSHCLIENTATTRIB','GLPUSHATTRIB','GLPRIORITIZETEXTURES','GLPOPNAME',
+ 'GLPOPMATRIX','GLPOPCLIENTATTRIB','GLPOPATTRIB','GLPOLYGONSTIPPLE','GLPOLYGONOFFSET','GLPOLYGONMODE','GLPOINTSIZE','GLPIXELZOOM',
+ 'GLPIXELTRANSFERI','GLPIXELTRANSFERF','GLPIXELSTOREI','GLPIXELSTOREF','GLPIXELMAPUSV','GLPIXELMAPUIV','GLPIXELMAPFV','GLPASSTHROUGH',
+ 'GLORTHO','GLNORMALPOINTER','GLNORMAL3SV','GLNORMAL3S','GLNORMAL3IV','GLNORMAL3I','GLNORMAL3FV','GLNORMAL3F',
+ 'GLNORMAL3DV','GLNORMAL3D','GLNORMAL3BV','GLNORMAL3B','GLNEWLIST','GLMULTMATRIXF','GLMULTMATRIXD','GLMATRIXMODE',
+ 'GLMATERIALIV','GLMATERIALI','GLMATERIALFV','GLMATERIALF','GLMAPGRID2F','GLMAPGRID2D','GLMAPGRID1F','GLMAPGRID1D',
+ 'GLMAP2F','GLMAP2D','GLMAP1F','GLMAP1D','GLLOGICOP','GLLOADNAME','GLLOADMATRIXF','GLLOADMATRIXD',
+ 'GLLOADIDENTITY','GLLISTBASE','GLLINEWIDTH','GLLINESTIPPLE','GLLIGHTMODELIV','GLLIGHTMODELI','GLLIGHTMODELFV','GLLIGHTMODELF',
+ 'GLLIGHTIV','GLLIGHTI','GLLIGHTFV','GLLIGHTF','GLISTEXTURE','GLISLIST','GLISENABLED','GLINTERLEAVEDARRAYS',
+ 'GLINITNAMES','GLINDEXUBV','GLINDEXUB','GLINDEXSV','GLINDEXS','GLINDEXPOINTER','GLINDEXMASK','GLINDEXIV',
+ 'GLINDEXI','GLINDEXFV','GLINDEXF','GLINDEXDV','GLINDEXD','GLHINT','GLGETTEXPARAMETERIV','GLGETTEXPARAMETERFV',
+ 'GLGETTEXLEVELPARAMETERIV','GLGETTEXLEVELPARAMETERFV','GLGETTEXIMAGE','GLGETTEXGENIV','GLGETTEXGENFV','GLGETTEXGENDV','GLGETTEXENVIV','GLGETTEXENVFV',
+ 'GLGETSTRING','GLGETPOLYGONSTIPPLE','GLGETPOINTERV','GLGETPIXELMAPUSV','GLGETPIXELMAPUIV','GLGETPIXELMAPFV','GLGETMATERIALIV','GLGETMATERIALFV',
+ 'GLGETMAPIV','GLGETMAPFV','GLGETMAPDV','GLGETLIGHTIV','GLGETLIGHTFV','GLGETINTEGERV','GLGETFLOATV','GLGETERROR',
+ 'GLGETDOUBLEV','GLGETCLIPPLANE','GLGETBOOLEANV','GLGENTEXTURES','GLGENLISTS','GLFRUSTUM','GLFRONTFACE','GLFOGIV',
+ 'GLFOGI','GLFOGFV','GLFOGF','GLFLUSH','GLFINISH','GLFEEDBACKBUFFER','GLEVALPOINT2','GLEVALPOINT1',
+ 'GLEVALMESH2','GLEVALMESH1','GLEVALCOORD2FV','GLEVALCOORD2F','GLEVALCOORD2DV','GLEVALCOORD2D','GLEVALCOORD1FV','GLEVALCOORD1F',
+ 'GLEVALCOORD1DV','GLEVALCOORD1D','GLENDLIST','GLEND','GLENABLECLIENTSTATE','GLENABLE','GLEDGEFLAGV','GLEDGEFLAGPOINTER',
+ 'GLEDGEFLAG','GLDRAWPIXELS','GLDRAWELEMENTS','GLDRAWBUFFER','GLDRAWARRAYS','GLDISABLECLIENTSTATE','GLDISABLE','GLDEPTHRANGE',
+ 'GLDEPTHMASK','GLDEPTHFUNC','GLDELETETEXTURES','GLDELETELISTS','GLCULLFACE','GLCOPYTEXSUBIMAGE2D','GLCOPYTEXSUBIMAGE1D','GLCOPYTEXIMAGE2D',
+ 'GLCOPYTEXIMAGE1D','GLCOPYPIXELS','GLCOLORPOINTER','GLCOLORMATERIAL','GLCOLORMASK','GLCOLOR4USV','GLCOLOR4US','GLCOLOR4UIV',
+ 'GLCOLOR4UI','GLCOLOR4UBV','GLCOLOR4UB','GLCOLOR4SV','GLCOLOR4S','GLCOLOR4IV','GLCOLOR4I','GLCOLOR4FV',
+ 'GLCOLOR4F','GLCOLOR4DV','GLCOLOR4D','GLCOLOR4BV','GLCOLOR4B','GLCOLOR3USV','GLCOLOR3US','GLCOLOR3UIV',
+ 'GLCOLOR3UI','GLCOLOR3UBV','GLCOLOR3UB','GLCOLOR3SV','GLCOLOR3S','GLCOLOR3IV','GLCOLOR3I','GLCOLOR3FV',
+ 'GLCOLOR3F','GLCOLOR3DV','GLCOLOR3D','GLCOLOR3BV','GLCOLOR3B','GLCLIPPLANE','GLCLEARSTENCIL','GLCLEARINDEX',
+ 'GLCLEARDEPTH','GLCLEARCOLOR','GLCLEARACCUM','GLCLEAR','GLCALLLISTS','GLCALLLIST','GLBLENDFUNC','GLBITMAP',
+ 'GLBINDTEXTURE','GLBEGIN','GLARRAYELEMENT','GLARETEXTURESRESIDENT','GLALPHAFUNC','GLACCUM'),
+ 2 => array(
+ '$BEL','$BS','$CR','$CRLF','$DQ','$DT_DATE_SEPARATOR','$DT_LANGUAGE','$DT_TIME_SEPARATOR',
+ '$ESC','$FF','$LF','$NUL','$PC_SD_MY_PC','$SPC','$SQL_OPT_TRACE_FILE_DEFAULT','$SQL_SPEC_STRING',
+ '$TAB','$TRACKBAR_CLASS','$VT','%ACM_OPEN','%ACM_OPENW','%ACM_PLAY','%ACM_STOP','%ACN_START',
+ '%ACN_STOP','%ACS_AUTOPLAY','%ACS_CENTER','%ACS_TIMER','%ACS_TRANSPARENT','%APP_COUNTER_FUNLOOKUP','%APP_COUNTER_KEYLOOKUP','%APP_COUNTER_LOOKUP',
+ '%APP_COUNTER_TESTALPHA','%APP_COUNTER_UDTLOOKUP','%APP_COUNTER_VARLOOKUP','%APP_TIMER_EXECTOTAL','%APP_TIMER_INIT','%APP_TIMER_LOAD','%APP_TIMER_PREPROCESSOR','%AW_ACTIVATE',
+ '%AW_BLEND','%AW_CENTER','%AW_HIDE','%AW_HOR_NEGATIVE','%AW_HOR_POSITIVE','%AW_SLIDE','%AW_VER_NEGATIVE','%AW_VER_POSITIVE',
+ '%BCM_FIRST','%BLACK','%BLUE','%BM_GETCHECK','%BM_SETCHECK','%BST_CHECKED','%BST_UNCHECKED','%BS_AUTOCHECKBOX',
+ '%BS_BOTTOM','%BS_CENTER','%BS_DEFAULT','%BS_DEFPUSHBUTTON','%BS_FLAT','%BS_LEFT','%BS_LEFTTEXT','%BS_MULTILINE',
+ '%BS_NOTIFY','%BS_OWNERDRAW','%BS_PUSHLIKE','%BS_RIGHT','%BS_TOP','%BS_VCENTER','%BUNDLE_BUILDER_CANCELLED','%CBM_FIRST',
+ '%CBN_CLOSEUP','%CBN_DBLCLK','%CBN_DROPDOWN','%CBN_EDITCHANGE','%CBN_EDITUPDATE','%CBN_ERRSPACE','%CBN_KILLFOCUS','%CBN_SELCANCEL',
+ '%CBN_SELCHANGE','%CBN_SELENDCANCEL','%CBN_SELENDOK','%CBN_SETFOCUS','%CBS_AUTOHSCROLL','%CBS_DISABLENOSCROLL','%CBS_DROPDOWN','%CBS_DROPDOWNLIST',
+ '%CBS_HASSTRINGS','%CBS_LOWERCASE','%CBS_NOINTEGRALHEIGHT','%CBS_SIMPLE','%CBS_SORT','%CBS_UPPERCASE','%CB_SELECTSTRING','%CCM_FIRST',
+ '%CC_ANYCOLOR','%CC_ENABLEHOOK','%CC_ENABLETEMPLATE','%CC_ENABLETEMPLATEHANDLE','%CC_FULLOPEN','%CC_PREVENTFULLOPEN','%CC_RGBINIT','%CC_SHOWHELP',
+ '%CC_SOLIDCOLOR','%CFE_BOLD','%CFE_ITALIC','%CFE_LINK','%CFE_PROTECTED','%CFE_STRIKEOUT','%CFE_UNDERLINE','%CFM_ANIMATION',
+ '%CFM_BACKCOLOR','%CFM_BOLD','%CFM_CHARSET','%CFM_COLOR','%CFM_FACE','%CFM_ITALIC','%CFM_KERNING','%CFM_LCID',
+ '%CFM_LINK','%CFM_OFFSET','%CFM_PROTECTED','%CFM_REVAUTHOR','%CFM_SIZE','%CFM_SPACING','%CFM_STRIKEOUT','%CFM_STYLE',
+ '%CFM_UNDERLINE','%CFM_UNDERLINETYPE','%CFM_WEIGHT','%CGI_ACCEPT_FILE_UPLOAD','%CGI_AUTO_ADD_SPECIAL_CHARS_PREFIX','%CGI_AUTO_CREATE_VARS','%CGI_BUFFERIZE_OUTPUT','%CGI_DOUBLE_QUOTE',
+ '%CGI_FILE_UPLOAD_BASEPATH','%CGI_FORCE_SESSION_VALIDATION','%CGI_MAX_BYTE_FROM_STD_IN','%CGI_REQUEST_METHOD_GET','%CGI_REQUEST_METHOD_POST','%CGI_SESSION_FILE_BASEPATH','%CGI_SINGLE_QUOTE','%CGI_SPECIAL_CHARS_PREFIX',
+ '%CGI_TEMPORARY_UPLOAD_PATH','%CGI_UPLOAD_CAN_OVERWRITE','%CGI_WRITE_LOG_FILE','%CGI_WRITE_VARS_INTO_LOG_FILE','%CONOLE_ATTACH_PARENT_PROCESS','%CONSOLE_BACKGROUND_BLUE','%CONSOLE_BACKGROUND_GREEN','%CONSOLE_BACKGROUND_INTENSITY',
+ '%CONSOLE_BACKGROUND_RED','%CONSOLE_BOX_FLAG_3DOFF','%CONSOLE_BOX_FLAG_3DON','%CONSOLE_BOX_FLAG_SHADOW','%CONSOLE_COMMON_LVB_GRID_HORIZONTAL','%CONSOLE_COMMON_LVB_GRID_LVERTICAL','%CONSOLE_COMMON_LVB_GRID_RVERTICAL','%CONSOLE_COMMON_LVB_LEADING_BYTE',
+ '%CONSOLE_COMMON_LVB_REVERSE_VIDEO','%CONSOLE_COMMON_LVB_TRAILING_BYTE','%CONSOLE_COMMON_LVB_UNDERSCORE','%CONSOLE_CTRL_BREAK_EVENT','%CONSOLE_CTRL_C_EVENT','%CONSOLE_DOUBLE_CLICK','%CONSOLE_ENABLE_AUTO_POSITION','%CONSOLE_ENABLE_ECHO_INPUT',
+ '%CONSOLE_ENABLE_EXTENDED_FLAGS','%CONSOLE_ENABLE_INSERT_MODE','%CONSOLE_ENABLE_LINE_INPUT','%CONSOLE_ENABLE_MOUSE_INPUT','%CONSOLE_ENABLE_PROCESSED_INPUT','%CONSOLE_ENABLE_PROCESSED_OUTPUT','%CONSOLE_ENABLE_QUICK_EDIT_MODE','%CONSOLE_ENABLE_WINDOW_INPUT',
+ '%CONSOLE_ENABLE_WRAP_AT_EOL_OUTPUT','%CONSOLE_FOREGROUND_BLUE','%CONSOLE_FOREGROUND_GREEN','%CONSOLE_FOREGROUND_INTENSITY','%CONSOLE_FOREGROUND_RED','%CONSOLE_LBUTTON','%CONSOLE_LINE_HORIZONTAL','%CONSOLE_LINE_VERTICAL',
+ '%CONSOLE_MBUTTON','%CONSOLE_MOUSE_MOVED','%CONSOLE_MOUSE_WHEELED','%CONSOLE_RBUTTON','%CONSOLE_SCROLLBUF_DOWN','%CONSOLE_SCROLLBUF_UP','%CONSOLE_SCROLLWND_ABSOLUTE','%CONSOLE_SCROLLWND_RELATIVE',
+ '%CONSOLE_STD_ERROR_HANDLE','%CONSOLE_STD_INPUT_HANDLE','%CONSOLE_STD_OUTPUT_HANDLE','%CONSOLE_SW_FORCEMINIMIZE','%CONSOLE_SW_HIDE','%CONSOLE_SW_MAXIMIZE','%CONSOLE_SW_MINIMIZE','%CONSOLE_SW_RESTORE',
+ '%CONSOLE_SW_SHOW','%CONSOLE_SW_SHOWDEFAULT','%CONSOLE_SW_SHOWMAXIMIZED','%CONSOLE_SW_SHOWMINIMIZED','%CONSOLE_SW_SHOWMINNOACTIVE','%CONSOLE_SW_SHOWNA','%CONSOLE_SW_SHOWNOACTIVATE','%CONSOLE_SW_SHOWNORMAL',
+ '%CONSOLE_UNAVAILABLE','%CRYPTO_CALG_DES','%CRYPTO_CALG_RC2','%CRYPTO_CALG_RC4','%CRYPTO_PROV_DH_SCHANNEL','%CRYPTO_PROV_DSS','%CRYPTO_PROV_DSS_DH','%CRYPTO_PROV_FORTEZZA',
+ '%CRYPTO_PROV_MS_EXCHANGE','%CRYPTO_PROV_RSA_FULL','%CRYPTO_PROV_RSA_SCHANNEL','%CRYPTO_PROV_RSA_SIG','%CRYPTO_PROV_SSL','%CSIDL_ADMINTOOLS','%CSIDL_ALTSTARTUP','%CSIDL_APPDATA',
+ '%CSIDL_BITBUCKET','%CSIDL_CDBURN_AREA','%CSIDL_COMMON_ADMINTOOLS','%CSIDL_COMMON_ALTSTARTUP','%CSIDL_COMMON_APPDATA','%CSIDL_COMMON_DESKTOPDIRECTORY','%CSIDL_COMMON_DOCUMENTS','%CSIDL_COMMON_FAVORITES',
+ '%CSIDL_COMMON_MUSIC','%CSIDL_COMMON_PICTURES','%CSIDL_COMMON_PROGRAMS','%CSIDL_COMMON_STARTMENU','%CSIDL_COMMON_STARTUP','%CSIDL_COMMON_TEMPLATES','%CSIDL_COMMON_VIDEO','%CSIDL_CONTROLS',
+ '%CSIDL_COOKIES','%CSIDL_DESKTOP','%CSIDL_DESKTOPDIRECTORY','%CSIDL_DRIVES','%CSIDL_FAVORITES','%CSIDL_FLAG_CREATE','%CSIDL_FONTS','%CSIDL_HISTORY',
+ '%CSIDL_INTERNET','%CSIDL_INTERNET_CACHE','%CSIDL_LOCAL_APPDATA','%CSIDL_MYDOCUMENTS','%CSIDL_MYMUSIC','%CSIDL_MYPICTURES','%CSIDL_MYVIDEO','%CSIDL_NETHOOD',
+ '%CSIDL_NETWORK','%CSIDL_PERSONAL','%CSIDL_PRINTERS','%CSIDL_PRINTHOOD','%CSIDL_PROFILE','%CSIDL_PROGRAMS','%CSIDL_PROGRAM_FILES','%CSIDL_PROGRAM_FILES_COMMON',
+ '%CSIDL_RECENT','%CSIDL_SENDTO','%CSIDL_STARTMENU','%CSIDL_STARTUP','%CSIDL_SYSTEM','%CSIDL_TEMPLATES','%CSIDL_WINDOWS','%CW_USEDEFAULT',
+ '%CYAN','%DATE_TIME_FILE_CREATION','%DATE_TIME_LAST_FILE_ACCESS','%DATE_TIME_LAST_FILE_WRITE','%DICTIONARY_MEMINFO_DATA','%DICTIONARY_MEMINFO_KEYS','%DICTIONARY_MEMINFO_TOTAL','%DICTIONARY_SORTDESCENDING',
+ '%DICTIONARY_SORTKEYS','%DSCAPS_CERTIFIED','%DSCAPS_CONTINUOUSRATE','%DSCAPS_EMULDRIVER','%DSCAPS_SECONDARY16BIT','%DSCAPS_SECONDARY8BIT','%DSCAPS_SECONDARYMONO','%DSCAPS_SECONDARYSTEREO',
+ '%DSCCAPS_CERTIFIED','%DSCCAPS_EMULDRIVER','%DS_3DLOOK','%DS_ABSALIGN','%DS_CENTER','%DS_CENTERMOUSE','%DS_CONTEXTHELP','%DS_CONTROL',
+ '%DS_MODALFRAME','%DS_NOFAILCREATE','%DS_SETFONT','%DS_SETFOREGROUND','%DS_SYSMODAL','%DTM_FIRST','%DTM_GETMCCOLOR','%DTM_GETMCFONT',
+ '%DTM_GETMONTHCAL','%DTM_GETRANGE','%DTM_GETSYSTEMTIME','%DTM_SETFORMAT','%DTM_SETFORMATW','%DTM_SETMCCOLOR','%DTM_SETMCFONT','%DTM_SETRANGE',
+ '%DTM_SETSYSTEMTIME','%DTN_CLOSEUP','%DTN_DATETIMECHANGE','%DTN_DROPDOWN','%DTN_FORMAT','%DTN_FORMATQUERY','%DTN_FORMATQUERYW','%DTN_FORMATW',
+ '%DTN_USERSTRING','%DTN_USERSTRINGW','%DTN_WMKEYDOWN','%DTN_WMKEYDOWNW','%DTS_APPCANPARSE','%DTS_LONGDATEFORMAT','%DTS_RIGHTALIGN','%DTS_SHORTDATECENTURYFORMAT',
+ '%DTS_SHORTDATEFORMAT','%DTS_SHOWNONE','%DTS_TIMEFORMAT','%DTS_UPDOWN','%DT_DATE_CENTURY','%DT_DATE_OK','%DT_DAY_IN_YEAR','%DT_DIFF_IN_DAYS',
+ '%DT_DIFF_IN_HOURS','%DT_DIFF_IN_MINUTES','%DT_DIFF_IN_SECONDS','%DT_HOURS_IN_DAY','%DT_MINUTES_IN_HOUR','%DT_SECONDS_IN_DAY','%DT_SECONDS_IN_HOUR','%DT_SECONDS_IN_MINUTE',
+ '%DT_SECONDS_IN_YEAR','%DT_USE_LONG_FORM','%DT_USE_SHORT_FORM','%DT_WRONG_DATE','%DT_WRONG_DAY','%DT_WRONG_MONTH','%ECM_FIRST','%ECOOP_AND',
+ '%ECOOP_OR','%ECOOP_SET','%ECOOP_XOR','%ECO_AUTOHSCROLL','%ECO_AUTOVSCROLL','%ECO_AUTOWORDSELECTION','%ECO_NOHIDESEL','%ECO_READONLY',
+ '%ECO_SELECTIONBAR','%ECO_WANTRETURN','%EM_AUTOURLDETECT','%EM_CANPASTE','%EM_CANREDO','%EM_CANUNDO','%EM_CHARFROMPOS','%EM_DISPLAYBAND',
+ '%EM_EMPTYUNDOBUFFER','%EM_EXGETSEL','%EM_EXLIMITTEXT','%EM_EXLINEFROMCHAR','%EM_EXSETSEL','%EM_FINDTEXT','%EM_FINDTEXTEX','%EM_FINDWORDBREAK',
+ '%EM_FMTLINES','%EM_FORMATRANGE','%EM_GETAUTOURLDETECT','%EM_GETCHARFORMAT','%EM_GETEDITSTYLE','%EM_GETEVENTMASK','%EM_GETFIRSTVISIBLELINE','%EM_GETHANDLE',
+ '%EM_GETIMESTATUS','%EM_GETLIMITTEXT','%EM_GETLINE','%EM_GETLINECOUNT','%EM_GETMARGINS','%EM_GETMODIFY','%EM_GETOLEINTERFACE','%EM_GETOPTIONS',
+ '%EM_GETPARAFORMAT','%EM_GETPASSWORDCHAR','%EM_GETRECT','%EM_GETREDONAME','%EM_GETSCROLLPOS','%EM_GETSEL','%EM_GETSELTEXT','%EM_GETTEXTMODE',
+ '%EM_GETTEXTRANGE','%EM_GETTHUMB','%EM_GETUNDONAME','%EM_GETWORDBREAKPROC','%EM_GETWORDBREAKPROCEX','%EM_HIDESELECTION','%EM_LIMITTEXT','%EM_LINEFROMCHAR',
+ '%EM_LINEINDEX','%EM_LINELENGTH','%EM_LINESCROLL','%EM_PASTESPECIAL','%EM_POSFROMCHAR','%EM_REDO','%EM_REPLACESEL','%EM_REQUESTRESIZE',
+ '%EM_SCROLL','%EM_SCROLLCARET','%EM_SELECTIONTYPE','%EM_SETBKGNDCOLOR','%EM_SETCHARFORMAT','%EM_SETEDITSTYLE','%EM_SETEVENTMASK','%EM_SETHANDLE',
+ '%EM_SETIMESTATUS','%EM_SETLIMITTEXT','%EM_SETMARGINS','%EM_SETMODIFY','%EM_SETOLECALLBACK','%EM_SETOPTIONS','%EM_SETPARAFORMAT','%EM_SETPASSWORDCHAR',
+ '%EM_SETREADONLY','%EM_SETRECT','%EM_SETRECTNP','%EM_SETSCROLLPOS','%EM_SETSEL','%EM_SETTABSTOPS','%EM_SETTARGETDEVICE','%EM_SETTEXTMODE',
+ '%EM_SETUNDOLIMIT','%EM_SETWORDBREAKPROC','%EM_SETWORDBREAKPROCEX','%EM_SETWORDWRAPMODE','%EM_SETZOOM','%EM_STOPGROUPTYPING','%EM_STREAMIN','%EM_STREAMOUT',
+ '%EM_UNDO','%ENM_CHANGE','%ENM_CORRECTTEXT','%ENM_DRAGDROPDONE','%ENM_DROPFILES','%ENM_KEYEVENTS','%ENM_MOUSEEVENTS','%ENM_NONE',
+ '%ENM_PARAGRAPHEXPANDED','%ENM_PROTECTED','%ENM_REQUESTRESIZE','%ENM_SCROLL','%ENM_SCROLLEVENTS','%ENM_SELCHANGE','%ENM_UPDATE','%EN_CHANGE',
+ '%EN_MSGFILTER','%EN_SELCHANGE','%EN_UPDATE','%ES_AUTOHSCROLL','%ES_AUTOVSCROLL','%ES_CENTER','%ES_DISABLENOSCROLL','%ES_EX_NOCALLOLEINIT',
+ '%ES_LEFT','%ES_LOWERCASE','%ES_MULTILINE','%ES_NOHIDESEL','%ES_NOOLEDRAGDROP','%ES_NUMBER','%ES_OEMCONVERT','%ES_PASSWORD',
+ '%ES_READONLY','%ES_RIGHT','%ES_SAVESEL','%ES_SELECTIONBAR','%ES_SUNKEN','%ES_UPPERCASE','%ES_WANTRETURN','%EVAL_EXEC_STRING',
+ '%FALSE','%FILE_ADDPATH','%FILE_ARCHIVE','%FILE_BUILDVERSION','%FILE_HIDDEN','%FILE_MAJORVERSION','%FILE_MINORVERSION','%FILE_NORMAL',
+ '%FILE_READONLY','%FILE_REVISIONVERSION','%FILE_SUBDIR','%FILE_SYSTEM','%FILE_VLABEL','%FTP_GET_CONNECT_STATUS','%FTP_GET_FILE_BYTES_RCVD','%FTP_GET_FILE_BYTES_SENT',
+ '%FTP_GET_LAST_RESPONSE','%FTP_GET_LOCAL_IP','%FTP_GET_SERVER_IP','%FTP_GET_TOTAL_BYTES_RCVD','%FTP_GET_TOTAL_BYTES_SENT','%FTP_LIST_FULLLIST','%FTP_LIST_FULLLISTDIR','%FTP_LIST_FULLLISTFILE',
+ '%FTP_SET_ASYNC','%FTP_SET_CONNECT_WAIT','%FTP_SET_MAX_LISTEN_WAIT','%FTP_SET_MAX_RESPONSE_WAIT','%FTP_SET_PASSIVE','%FTP_SET_SYNC','%FW_BLACK','%FW_BOLD',
+ '%FW_DEMIBOLD','%FW_DONTCARE','%FW_EXTRABOLD','%FW_EXTRALIGHT','%FW_HEAVY','%FW_LIGHT','%FW_MEDIUM','%FW_NORMAL',
+ '%FW_REGULAR','%FW_SEMIBOLD','%FW_THIN','%FW_ULTRABOLD','%FW_ULTRALIGHT','%GDTR_MAX','%GDTR_MIN','%GLU_AUTO_LOAD_MATRIX',
+ '%GLU_BEGIN','%GLU_CCW','%GLU_CULLING','%GLU_CW','%GLU_DISPLAY_MODE','%GLU_DOMAIN_DISTANCE','%GLU_EDGE_FLAG','%GLU_END',
+ '%GLU_ERROR','%GLU_EXTENSIONS','%GLU_EXTERIOR','%GLU_FALSE','%GLU_FILL','%GLU_FLAT','%GLU_INCOMPATIBLE_GL_VERSION','%GLU_INSIDE',
+ '%GLU_INTERIOR','%GLU_INVALID_ENUM','%GLU_INVALID_VALUE','%GLU_LINE','%GLU_MAP1_TRIM_2','%GLU_MAP1_TRIM_3','%GLU_NONE','%GLU_NURBS_ERROR1',
+ '%GLU_NURBS_ERROR10','%GLU_NURBS_ERROR11','%GLU_NURBS_ERROR12','%GLU_NURBS_ERROR13','%GLU_NURBS_ERROR14','%GLU_NURBS_ERROR15','%GLU_NURBS_ERROR16','%GLU_NURBS_ERROR17',
+ '%GLU_NURBS_ERROR18','%GLU_NURBS_ERROR19','%GLU_NURBS_ERROR2','%GLU_NURBS_ERROR20','%GLU_NURBS_ERROR21','%GLU_NURBS_ERROR22','%GLU_NURBS_ERROR23','%GLU_NURBS_ERROR24',
+ '%GLU_NURBS_ERROR25','%GLU_NURBS_ERROR26','%GLU_NURBS_ERROR27','%GLU_NURBS_ERROR28','%GLU_NURBS_ERROR29','%GLU_NURBS_ERROR3','%GLU_NURBS_ERROR30','%GLU_NURBS_ERROR31',
+ '%GLU_NURBS_ERROR32','%GLU_NURBS_ERROR33','%GLU_NURBS_ERROR34','%GLU_NURBS_ERROR35','%GLU_NURBS_ERROR36','%GLU_NURBS_ERROR37','%GLU_NURBS_ERROR4','%GLU_NURBS_ERROR5',
+ '%GLU_NURBS_ERROR6','%GLU_NURBS_ERROR7','%GLU_NURBS_ERROR8','%GLU_NURBS_ERROR9','%GLU_OUTLINE_PATCH','%GLU_OUTLINE_POLYGON','%GLU_OUTSIDE','%GLU_OUT_OF_MEMORY',
+ '%GLU_PARAMETRIC_ERROR','%GLU_PARAMETRIC_TOLERANCE','%GLU_PATH_LENGTH','%GLU_POINT','%GLU_SAMPLING_METHOD','%GLU_SAMPLING_TOLERANCE','%GLU_SILHOUETTE','%GLU_SMOOTH',
+ '%GLU_TESS_BEGIN','%GLU_TESS_BEGIN_DATA','%GLU_TESS_BOUNDARY_ONLY','%GLU_TESS_COMBINE','%GLU_TESS_COMBINE_DATA','%GLU_TESS_COORD_TOO_LARGE','%GLU_TESS_EDGE_FLAG','%GLU_TESS_EDGE_FLAG_DATA',
+ '%GLU_TESS_END','%GLU_TESS_END_DATA','%GLU_TESS_ERROR','%GLU_TESS_ERROR1','%GLU_TESS_ERROR2','%GLU_TESS_ERROR3','%GLU_TESS_ERROR4','%GLU_TESS_ERROR5',
+ '%GLU_TESS_ERROR6','%GLU_TESS_ERROR7','%GLU_TESS_ERROR8','%GLU_TESS_ERROR_DATA','%GLU_TESS_MISSING_BEGIN_CONTOUR','%GLU_TESS_MISSING_BEGIN_POLYGON','%GLU_TESS_MISSING_END_CONTOUR','%GLU_TESS_MISSING_END_POLYGON',
+ '%GLU_TESS_NEED_COMBINE_CALLBACK','%GLU_TESS_TOLERANCE','%GLU_TESS_VERTEX','%GLU_TESS_VERTEX_DATA','%GLU_TESS_WINDING_ABS_GEQ_TWO','%GLU_TESS_WINDING_NEGATIVE','%GLU_TESS_WINDING_NONZERO','%GLU_TESS_WINDING_ODD',
+ '%GLU_TESS_WINDING_POSITIVE','%GLU_TESS_WINDING_RULE','%GLU_TRUE','%GLU_UNKNOWN','%GLU_U_STEP','%GLU_VERSION','%GLU_VERSION_1_1','%GLU_VERSION_1_2',
+ '%GLU_VERTEX','%GLU_V_STEP','%GL_2D','%GL_2_BYTES','%GL_3D','%GL_3D_COLOR','%GL_3D_COLOR_TEXTURE','%GL_3_BYTES',
+ '%GL_4D_COLOR_TEXTURE','%GL_4_BYTES','%GL_ABGR_EXT','%GL_ACCUM','%GL_ACCUM_ALPHA_BITS','%GL_ACCUM_BLUE_BITS','%GL_ACCUM_BUFFER_BIT','%GL_ACCUM_CLEAR_VALUE',
+ '%GL_ACCUM_GREEN_BITS','%GL_ACCUM_RED_BITS','%GL_ADD','%GL_ALL_ATTRIB_BITS','%GL_ALPHA','%GL_ALPHA12','%GL_ALPHA16','%GL_ALPHA4',
+ '%GL_ALPHA8','%GL_ALPHA_BIAS','%GL_ALPHA_BITS','%GL_ALPHA_SCALE','%GL_ALPHA_TEST','%GL_ALPHA_TEST_FUNC','%GL_ALPHA_TEST_REF','%GL_ALWAYS',
+ '%GL_AMBIENT','%GL_AMBIENT_AND_DIFFUSE','%GL_AND','%GL_AND_INVERTED','%GL_AND_REVERSE','%GL_ARRAY_ELEMENT_LOCK_COUNT_EXT','%GL_ARRAY_ELEMENT_LOCK_FIRST_EXT','%GL_ATTRIB_STACK_DEPTH',
+ '%GL_AUTO_NORMAL','%GL_AUX0','%GL_AUX1','%GL_AUX2','%GL_AUX3','%GL_AUX_BUFFERS','%GL_BACK','%GL_BACK_LEFT',
+ '%GL_BACK_RIGHT','%GL_BGRA_EXT','%GL_BGR_EXT','%GL_BITMAP','%GL_BITMAP_TOKEN','%GL_BLEND','%GL_BLEND_COLOR_EXT','%GL_BLEND_DST',
+ '%GL_BLEND_EQUATION_EXT','%GL_BLEND_SRC','%GL_BLUE','%GL_BLUE_BIAS','%GL_BLUE_BITS','%GL_BLUE_SCALE','%GL_BYTE','%GL_C3F_V3F',
+ '%GL_C4F_N3F_V3F','%GL_C4UB_V2F','%GL_C4UB_V3F','%GL_CCW','%GL_CLAMP','%GL_CLEAR','%GL_CLIENT_ALL_ATTRIB_BITS','%GL_CLIENT_ATTRIB_STACK_DEPTH',
+ '%GL_CLIENT_PIXEL_STORE_BIT','%GL_CLIENT_VERTEX_ARRAY_BIT','%GL_CLIP_PLANE0','%GL_CLIP_PLANE1','%GL_CLIP_PLANE2','%GL_CLIP_PLANE3','%GL_CLIP_PLANE4','%GL_CLIP_PLANE5',
+ '%GL_CLIP_VOLUME_CLIPPING_HINT_EXT','%GL_COEFF','%GL_COLOR','%GL_COLOR_ARRAY','%GL_COLOR_ARRAY_COUNT_EXT','%GL_COLOR_ARRAY_EXT','%GL_COLOR_ARRAY_POINTER','%GL_COLOR_ARRAY_POINTER_EXT',
+ '%GL_COLOR_ARRAY_SIZE','%GL_COLOR_ARRAY_SIZE_EXT','%GL_COLOR_ARRAY_STRIDE','%GL_COLOR_ARRAY_STRIDE_EXT','%GL_COLOR_ARRAY_TYPE','%GL_COLOR_ARRAY_TYPE_EXT','%GL_COLOR_BUFFER_BIT','%GL_COLOR_CLEAR_VALUE',
+ '%GL_COLOR_INDEX','%GL_COLOR_INDEX12_EXT','%GL_COLOR_INDEX16_EXT','%GL_COLOR_INDEX1_EXT','%GL_COLOR_INDEX2_EXT','%GL_COLOR_INDEX4_EXT','%GL_COLOR_INDEX8_EXT','%GL_COLOR_INDEXES',
+ '%GL_COLOR_LOGIC_OP','%GL_COLOR_MATERIAL','%GL_COLOR_MATERIAL_FACE','%GL_COLOR_MATERIAL_PARAMETER','%GL_COLOR_SUM_EXT','%GL_COLOR_TABLE_ALPHA_SIZE_EXT','%GL_COLOR_TABLE_BIAS_EXT','%GL_COLOR_TABLE_BLUE_SIZE_EXT',
+ '%GL_COLOR_TABLE_EXT','%GL_COLOR_TABLE_FORMAT_EXT','%GL_COLOR_TABLE_GREEN_SIZE_EXT','%GL_COLOR_TABLE_INTENSITY_SIZE_EXT','%GL_COLOR_TABLE_LUMINANCE_SIZE_EXT','%GL_COLOR_TABLE_RED_SIZE_EXT','%GL_COLOR_TABLE_SCALE_EXT','%GL_COLOR_TABLE_WIDTH_EXT',
+ '%GL_COLOR_WRITEMASK','%GL_COMPILE','%GL_COMPILE_AND_EXECUTE','%GL_CONSTANT_ALPHA_EXT','%GL_CONSTANT_ATTENUATION','%GL_CONSTANT_COLOR_EXT','%GL_CONVOLUTION_1D_EXT','%GL_CONVOLUTION_2D_EXT',
+ '%GL_CONVOLUTION_BORDER_MODE_EXT','%GL_CONVOLUTION_FILTER_BIAS_EXT','%GL_CONVOLUTION_FILTER_SCALE_EXT','%GL_CONVOLUTION_FORMAT_EXT','%GL_CONVOLUTION_HEIGHT_EXT','%GL_CONVOLUTION_WIDTH_EXT','%GL_COPY','%GL_COPY_INVERTED',
+ '%GL_COPY_PIXEL_TOKEN','%GL_CULL_FACE','%GL_CULL_FACE_MODE','%GL_CULL_VERTEX_EXT','%GL_CULL_VERTEX_EYE_POSITION_EXT','%GL_CULL_VERTEX_OBJECT_POSITION_EXT','%GL_CURRENT_BIT','%GL_CURRENT_COLOR',
+ '%GL_CURRENT_INDEX','%GL_CURRENT_NORMAL','%GL_CURRENT_RASTER_COLOR','%GL_CURRENT_RASTER_DISTANCE','%GL_CURRENT_RASTER_INDEX','%GL_CURRENT_RASTER_POSITION','%GL_CURRENT_RASTER_POSITION_VALID','%GL_CURRENT_RASTER_TEXTURE_COORDS',
+ '%GL_CURRENT_SECONDARY_COLOR_EXT','%GL_CURRENT_TEXTURE_COORDS','%GL_CW','%GL_DECAL','%GL_DECR','%GL_DEPTH','%GL_DEPTH_BIAS','%GL_DEPTH_BITS',
+ '%GL_DEPTH_BUFFER_BIT','%GL_DEPTH_CLEAR_VALUE','%GL_DEPTH_COMPONENT','%GL_DEPTH_FUNC','%GL_DEPTH_RANGE','%GL_DEPTH_SCALE','%GL_DEPTH_TEST','%GL_DEPTH_WRITEMASK',
+ '%GL_DIFFUSE','%GL_DITHER','%GL_DOMAIN','%GL_DONT_CARE','%GL_DOUBLE','%GL_DOUBLEBUFFER','%GL_DOUBLE_EXT','%GL_DRAW_BUFFER',
+ '%GL_DRAW_PIXEL_TOKEN','%GL_DST_ALPHA','%GL_DST_COLOR','%GL_EDGE_FLAG','%GL_EDGE_FLAG_ARRAY','%GL_EDGE_FLAG_ARRAY_COUNT_EXT','%GL_EDGE_FLAG_ARRAY_EXT','%GL_EDGE_FLAG_ARRAY_POINTER',
+ '%GL_EDGE_FLAG_ARRAY_POINTER_EXT','%GL_EDGE_FLAG_ARRAY_STRIDE','%GL_EDGE_FLAG_ARRAY_STRIDE_EXT','%GL_EMISSION','%GL_ENABLE_BIT','%GL_EQUAL','%GL_EQUIV','%GL_EVAL_BIT',
+ '%GL_EXP','%GL_EXP2','%GL_EXTENSIONS','%GL_EXT_ABGR','%GL_EXT_BGRA','%GL_EXT_BLEND_COLOR','%GL_EXT_BLEND_MINMAX','%GL_EXT_BLEND_SUBTRACT',
+ '%GL_EXT_CLIP_VOLUME_HINT','%GL_EXT_COLOR_TABLE','%GL_EXT_COMPILED_VERTEX_ARRAY','%GL_EXT_CONVOLUTION','%GL_EXT_CULL_VERTEX','%GL_EXT_HISTOGRAM','%GL_EXT_PACKED_PIXELS','%GL_EXT_PALETTED_TEXTURE',
+ '%GL_EXT_POLYGON_OFFSET','%GL_EXT_SECONDARY_COLOR','%GL_EXT_SEPARATE_SPECULAR_COLOR','%GL_EXT_VERTEX_ARRAY','%GL_EYE_LINEAR','%GL_EYE_PLANE','%GL_FALSE','%GL_FASTEST',
+ '%GL_FEEDBACK','%GL_FEEDBACK_BUFFER_POINTER','%GL_FEEDBACK_BUFFER_SIZE','%GL_FEEDBACK_BUFFER_TYPE','%GL_FILL','%GL_FLAT','%GL_FLOAT','%GL_FOG',
+ '%GL_FOG_BIT','%GL_FOG_COLOR','%GL_FOG_DENSITY','%GL_FOG_END','%GL_FOG_HINT','%GL_FOG_INDEX','%GL_FOG_MODE','%GL_FOG_START',
+ '%GL_FRONT','%GL_FRONT_AND_BACK','%GL_FRONT_FACE','%GL_FRONT_LEFT','%GL_FRONT_RIGHT','%GL_FUNC_ADD_EXT','%GL_FUNC_REVERSE_SUBTRACT_EXT','%GL_FUNC_SUBTRACT_EXT',
+ '%GL_GEQUAL','%GL_GREATER','%GL_GREEN','%GL_GREEN_BIAS','%GL_GREEN_BITS','%GL_GREEN_SCALE','%GL_HINT_BIT','%GL_HISTOGRAM_ALPHA_SIZE_EXT',
+ '%GL_HISTOGRAM_BLUE_SIZE_EXT','%GL_HISTOGRAM_EXT','%GL_HISTOGRAM_FORMAT_EXT','%GL_HISTOGRAM_GREEN_SIZE_EXT','%GL_HISTOGRAM_LUMINANCE_SIZE_EXT','%GL_HISTOGRAM_RED_SIZE_EXT','%GL_HISTOGRAM_SINK_EXT','%GL_HISTOGRAM_WIDTH_EXT',
+ '%GL_INCR','%GL_INDEX_ARRAY','%GL_INDEX_ARRAY_COUNT_EXT','%GL_INDEX_ARRAY_EXT','%GL_INDEX_ARRAY_POINTER','%GL_INDEX_ARRAY_POINTER_EXT','%GL_INDEX_ARRAY_STRIDE','%GL_INDEX_ARRAY_STRIDE_EXT',
+ '%GL_INDEX_ARRAY_TYPE','%GL_INDEX_ARRAY_TYPE_EXT','%GL_INDEX_BITS','%GL_INDEX_CLEAR_VALUE','%GL_INDEX_LOGIC_OP','%GL_INDEX_MODE','%GL_INDEX_OFFSET','%GL_INDEX_SHIFT',
+ '%GL_INDEX_WRITEMASK','%GL_INT','%GL_INTENSITY','%GL_INTENSITY12','%GL_INTENSITY16','%GL_INTENSITY4','%GL_INTENSITY8','%GL_INVALID_ENUM',
+ '%GL_INVALID_OPERATION','%GL_INVALID_VALUE','%GL_INVERT','%GL_KEEP','%GL_LEFT','%GL_LEQUAL','%GL_LESS','%GL_LIGHT0',
+ '%GL_LIGHT1','%GL_LIGHT2','%GL_LIGHT3','%GL_LIGHT4','%GL_LIGHT5','%GL_LIGHT6','%GL_LIGHT7','%GL_LIGHTING',
+ '%GL_LIGHTING_BIT','%GL_LIGHT_MODEL_AMBIENT','%GL_LIGHT_MODEL_COLOR_CONTROL_EXT','%GL_LIGHT_MODEL_LOCAL_VIEWER','%GL_LIGHT_MODEL_TWO_SIDE','%GL_LINE','%GL_LINEAR','%GL_LINEAR_ATTENUATION',
+ '%GL_LINEAR_MIPMAP_LINEAR','%GL_LINEAR_MIPMAP_NEAREST','%GL_LINES','%GL_LINE_BIT','%GL_LINE_LOOP','%GL_LINE_RESET_TOKEN','%GL_LINE_SMOOTH','%GL_LINE_SMOOTH_HINT',
+ '%GL_LINE_STIPPLE','%GL_LINE_STIPPLE_PATTERN','%GL_LINE_STIPPLE_REPEAT','%GL_LINE_STRIP','%GL_LINE_TOKEN','%GL_LINE_WIDTH','%GL_LINE_WIDTH_GRANULARITY','%GL_LINE_WIDTH_RANGE',
+ '%GL_LIST_BASE','%GL_LIST_BIT','%GL_LIST_INDEX','%GL_LIST_MODE','%GL_LOAD','%GL_LOGIC_OP','%GL_LOGIC_OP_MODE','%GL_LUMINANCE',
+ '%GL_LUMINANCE12','%GL_LUMINANCE12_ALPHA12','%GL_LUMINANCE12_ALPHA4','%GL_LUMINANCE16','%GL_LUMINANCE16_ALPHA16','%GL_LUMINANCE4','%GL_LUMINANCE4_ALPHA4','%GL_LUMINANCE6_ALPHA2',
+ '%GL_LUMINANCE8','%GL_LUMINANCE8_ALPHA8','%GL_LUMINANCE_ALPHA','%GL_MAP1_COLOR_4','%GL_MAP1_GRID_DOMAIN','%GL_MAP1_GRID_SEGMENTS','%GL_MAP1_INDEX','%GL_MAP1_NORMAL',
+ '%GL_MAP1_TEXTURE_COORD_1','%GL_MAP1_TEXTURE_COORD_2','%GL_MAP1_TEXTURE_COORD_3','%GL_MAP1_TEXTURE_COORD_4','%GL_MAP1_VERTEX_3','%GL_MAP1_VERTEX_4','%GL_MAP2_COLOR_4','%GL_MAP2_GRID_DOMAIN',
+ '%GL_MAP2_GRID_SEGMENTS','%GL_MAP2_INDEX','%GL_MAP2_NORMAL','%GL_MAP2_TEXTURE_COORD_1','%GL_MAP2_TEXTURE_COORD_2','%GL_MAP2_TEXTURE_COORD_3','%GL_MAP2_TEXTURE_COORD_4','%GL_MAP2_VERTEX_3',
+ '%GL_MAP2_VERTEX_4','%GL_MAP_COLOR','%GL_MAP_STENCIL','%GL_MATRIX_MODE','%GL_MAX_ATTRIB_STACK_DEPTH','%GL_MAX_CLIENT_ATTRIB_STACK_DEPTH','%GL_MAX_CLIP_PLANES','%GL_MAX_CONVOLUTION_HEIGHT_EXT',
+ '%GL_MAX_CONVOLUTION_WIDTH_EXT','%GL_MAX_EVAL_ORDER','%GL_MAX_EXT','%GL_MAX_LIGHTS','%GL_MAX_LIST_NESTING','%GL_MAX_MODELVIEW_STACK_DEPTH','%GL_MAX_NAME_STACK_DEPTH','%GL_MAX_PIXEL_MAP_TABLE',
+ '%GL_MAX_PROJECTION_STACK_DEPTH','%GL_MAX_TEXTURE_SIZE','%GL_MAX_TEXTURE_STACK_DEPTH','%GL_MAX_VIEWPORT_DIMS','%GL_MINMAX_EXT','%GL_MINMAX_FORMAT_EXT','%GL_MINMAX_SINK_EXT','%GL_MIN_EXT',
+ '%GL_MODELVIEW','%GL_MODELVIEW_MATRIX','%GL_MODELVIEW_STACK_DEPTH','%GL_MODULATE','%GL_MULT','%GL_N3F_V3F','%GL_NAME_STACK_DEPTH','%GL_NAND',
+ '%GL_NEAREST','%GL_NEAREST_MIPMAP_LINEAR','%GL_NEAREST_MIPMAP_NEAREST','%GL_NEVER','%GL_NICEST','%GL_NONE','%GL_NOOP','%GL_NOR',
+ '%GL_NORMALIZE','%GL_NORMAL_ARRAY','%GL_NORMAL_ARRAY_COUNT_EXT','%GL_NORMAL_ARRAY_EXT','%GL_NORMAL_ARRAY_POINTER','%GL_NORMAL_ARRAY_POINTER_EXT','%GL_NORMAL_ARRAY_STRIDE','%GL_NORMAL_ARRAY_STRIDE_EXT',
+ '%GL_NORMAL_ARRAY_TYPE','%GL_NORMAL_ARRAY_TYPE_EXT','%GL_NOTEQUAL','%GL_NO_ERROR','%GL_OBJECT_LINEAR','%GL_OBJECT_PLANE','%GL_ONE','%GL_ONE_MINUS_CONSTANT_ALPHA_EXT',
+ '%GL_ONE_MINUS_CONSTANT_COLOR_EXT','%GL_ONE_MINUS_DST_ALPHA','%GL_ONE_MINUS_DST_COLOR','%GL_ONE_MINUS_SRC_ALPHA','%GL_ONE_MINUS_SRC_COLOR','%GL_OR','%GL_ORDER','%GL_OR_INVERTED',
+ '%GL_OR_REVERSE','%GL_OUT_OF_MEMORY','%GL_PACK_ALIGNMENT','%GL_PACK_LSB_FIRST','%GL_PACK_ROW_LENGTH','%GL_PACK_SKIP_PIXELS','%GL_PACK_SKIP_ROWS','%GL_PACK_SWAP_BYTES',
+ '%GL_PASS_THROUGH_TOKEN','%GL_PERSPECTIVE_CORRECTION_HINT','%GL_PIXEL_MAP_A_TO_A','%GL_PIXEL_MAP_A_TO_A_SIZE','%GL_PIXEL_MAP_B_TO_B','%GL_PIXEL_MAP_B_TO_B_SIZE','%GL_PIXEL_MAP_G_TO_G','%GL_PIXEL_MAP_G_TO_G_SIZE',
+ '%GL_PIXEL_MAP_I_TO_A','%GL_PIXEL_MAP_I_TO_A_SIZE','%GL_PIXEL_MAP_I_TO_B','%GL_PIXEL_MAP_I_TO_B_SIZE','%GL_PIXEL_MAP_I_TO_G','%GL_PIXEL_MAP_I_TO_G_SIZE','%GL_PIXEL_MAP_I_TO_I','%GL_PIXEL_MAP_I_TO_I_SIZE',
+ '%GL_PIXEL_MAP_I_TO_R','%GL_PIXEL_MAP_I_TO_R_SIZE','%GL_PIXEL_MAP_R_TO_R','%GL_PIXEL_MAP_R_TO_R_SIZE','%GL_PIXEL_MAP_S_TO_S','%GL_PIXEL_MAP_S_TO_S_SIZE','%GL_PIXEL_MODE_BIT','%GL_POINT',
+ '%GL_POINTS','%GL_POINT_BIT','%GL_POINT_SIZE','%GL_POINT_SIZE_GRANULARITY','%GL_POINT_SIZE_RANGE','%GL_POINT_SMOOTH','%GL_POINT_SMOOTH_HINT','%GL_POINT_TOKEN',
+ '%GL_POLYGON','%GL_POLYGON_BIT','%GL_POLYGON_MODE','%GL_POLYGON_OFFSET_BIAS_EXT','%GL_POLYGON_OFFSET_EXT','%GL_POLYGON_OFFSET_FACTOR','%GL_POLYGON_OFFSET_FACTOR_EXT','%GL_POLYGON_OFFSET_FILL',
+ '%GL_POLYGON_OFFSET_LINE','%GL_POLYGON_OFFSET_POINT','%GL_POLYGON_OFFSET_UNITS','%GL_POLYGON_SMOOTH','%GL_POLYGON_SMOOTH_HINT','%GL_POLYGON_STIPPLE','%GL_POLYGON_STIPPLE_BIT','%GL_POLYGON_TOKEN',
+ '%GL_POSITION','%GL_POST_COLOR_MATRIX_COLOR_TABLE_EXT','%GL_POST_CONVOLUTION_ALPHA_BIAS_EXT','%GL_POST_CONVOLUTION_ALPHA_SCALE_EXT','%GL_POST_CONVOLUTION_BLUE_BIAS_EXT','%GL_POST_CONVOLUTION_BLUE_SCALE_EXT','%GL_POST_CONVOLUTION_COLOR_TABLE_EXT','%GL_POST_CONVOLUTION_GREEN_BIAS_EXT',
+ '%GL_POST_CONVOLUTION_GREEN_SCALE_EXT','%GL_POST_CONVOLUTION_RED_BIAS_EXT','%GL_POST_CONVOLUTION_RED_SCALE_EXT','%GL_PROJECTION','%GL_PROJECTION_MATRIX','%GL_PROJECTION_STACK_DEPTH','%GL_PROXY_COLOR_TABLE_EXT','%GL_PROXY_HISTOGRAM_EXT',
+ '%GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_EXT','%GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_EXT','%GL_PROXY_TEXTURE_1D','%GL_PROXY_TEXTURE_2D','%GL_Q','%GL_QUADRATIC_ATTENUATION','%GL_QUADS','%GL_QUAD_STRIP',
+ '%GL_R','%GL_R3_G3_B2','%GL_READ_BUFFER','%GL_RED','%GL_REDUCE_EXT','%GL_RED_BIAS','%GL_RED_BITS','%GL_RED_SCALE',
+ '%GL_RENDER','%GL_RENDERER','%GL_RENDER_MODE','%GL_REPEAT','%GL_REPLACE','%GL_RETURN','%GL_RGB','%GL_RGB10',
+ '%GL_RGB10_A2','%GL_RGB12','%GL_RGB16','%GL_RGB4','%GL_RGB5','%GL_RGB5_A1','%GL_RGB8','%GL_RGBA',
+ '%GL_RGBA12','%GL_RGBA16','%GL_RGBA2','%GL_RGBA4','%GL_RGBA8','%GL_RGBA_MODE','%GL_RIGHT','%GL_S',
+ '%GL_SCISSOR_BIT','%GL_SCISSOR_BOX','%GL_SCISSOR_TEST','%GL_SECONDARY_COLOR_ARRAY_EXT','%GL_SECONDARY_COLOR_ARRAY_POINTER_EXT','%GL_SECONDARY_COLOR_ARRAY_SIZE_EXT','%GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT','%GL_SECONDARY_COLOR_ARRAY_TYPE_EXT',
+ '%GL_SELECT','%GL_SELECTION_BUFFER_POINTER','%GL_SELECTION_BUFFER_SIZE','%GL_SEPARABLE_2D_EXT','%GL_SEPARATE_SPECULAR_COLOR_EXT','%GL_SET','%GL_SHADE_MODEL','%GL_SHININESS',
+ '%GL_SHORT','%GL_SINGLE_COLOR_EXT','%GL_SMOOTH','%GL_SPECULAR','%GL_SPHERE_MAP','%GL_SPOT_CUTOFF','%GL_SPOT_DIRECTION','%GL_SPOT_EXPONENT',
+ '%GL_SRC_ALPHA','%GL_SRC_ALPHA_SATURATE','%GL_SRC_COLOR','%GL_STACK_OVERFLOW','%GL_STACK_UNDERFLOW','%GL_STENCIL','%GL_STENCIL_BITS','%GL_STENCIL_BUFFER_BIT',
+ '%GL_STENCIL_CLEAR_VALUE','%GL_STENCIL_FAIL','%GL_STENCIL_FUNC','%GL_STENCIL_INDEX','%GL_STENCIL_PASS_DEPTH_FAIL','%GL_STENCIL_PASS_DEPTH_PASS','%GL_STENCIL_REF','%GL_STENCIL_TEST',
+ '%GL_STENCIL_VALUE_MASK','%GL_STENCIL_WRITEMASK','%GL_STEREO','%GL_SUBPIXEL_BITS','%GL_T','%GL_T2F_C3F_V3F','%GL_T2F_C4F_N3F_V3F','%GL_T2F_C4UB_V3F',
+ '%GL_T2F_N3F_V3F','%GL_T2F_V3F','%GL_T4F_C4F_N3F_V4F','%GL_T4F_V4F','%GL_TABLE_TOO_LARGE_EXT','%GL_TEXTURE','%GL_TEXTURE_1D','%GL_TEXTURE_2D',
+ '%GL_TEXTURE_ALPHA_SIZE','%GL_TEXTURE_BINDING_1D','%GL_TEXTURE_BINDING_2D','%GL_TEXTURE_BIT','%GL_TEXTURE_BLUE_SIZE','%GL_TEXTURE_BORDER','%GL_TEXTURE_BORDER_COLOR','%GL_TEXTURE_COMPONENTS',
+ '%GL_TEXTURE_COORD_ARRAY','%GL_TEXTURE_COORD_ARRAY_COUNT_EXT','%GL_TEXTURE_COORD_ARRAY_EXT','%GL_TEXTURE_COORD_ARRAY_POINTER','%GL_TEXTURE_COORD_ARRAY_POINTER_EXT','%GL_TEXTURE_COORD_ARRAY_SIZE','%GL_TEXTURE_COORD_ARRAY_SIZE_EXT','%GL_TEXTURE_COORD_ARRAY_STRIDE',
+ '%GL_TEXTURE_COORD_ARRAY_STRIDE_EXT','%GL_TEXTURE_COORD_ARRAY_TYPE','%GL_TEXTURE_COORD_ARRAY_TYPE_EXT','%GL_TEXTURE_ENV','%GL_TEXTURE_ENV_COLOR','%GL_TEXTURE_ENV_MODE','%GL_TEXTURE_GEN_MODE','%GL_TEXTURE_GEN_Q',
+ '%GL_TEXTURE_GEN_R','%GL_TEXTURE_GEN_S','%GL_TEXTURE_GEN_T','%GL_TEXTURE_GREEN_SIZE','%GL_TEXTURE_HEIGHT','%GL_TEXTURE_INTENSITY_SIZE','%GL_TEXTURE_INTERNAL_FORMAT','%GL_TEXTURE_LUMINANCE_SIZE',
+ '%GL_TEXTURE_MAG_FILTER','%GL_TEXTURE_MATRIX','%GL_TEXTURE_MIN_FILTER','%GL_TEXTURE_PRIORITY','%GL_TEXTURE_RED_SIZE','%GL_TEXTURE_RESIDENT','%GL_TEXTURE_STACK_DEPTH','%GL_TEXTURE_WIDTH',
+ '%GL_TEXTURE_WRAP_S','%GL_TEXTURE_WRAP_T','%GL_TRANSFORM_BIT','%GL_TRIANGLES','%GL_TRIANGLE_FAN','%GL_TRIANGLE_STRIP','%GL_TRUE','%GL_UNPACK_ALIGNMENT',
+ '%GL_UNPACK_LSB_FIRST','%GL_UNPACK_ROW_LENGTH','%GL_UNPACK_SKIP_PIXELS','%GL_UNPACK_SKIP_ROWS','%GL_UNPACK_SWAP_BYTES','%GL_UNSIGNED_BYTE','%GL_UNSIGNED_BYTE_3_3_2_EXT','%GL_UNSIGNED_INT',
+ '%GL_UNSIGNED_INT_10_10_10_2_EXT','%GL_UNSIGNED_INT_8_8_8_8_EXT','%GL_UNSIGNED_SHORT','%GL_UNSIGNED_SHORT_4_4_4_4_EXT','%GL_UNSIGNED_SHORT_5_5_5_1_EXT','%GL_V2F','%GL_V3F','%GL_VENDOR',
+ '%GL_VERSION','%GL_VERSION_1_1','%GL_VERTEX_ARRAY','%GL_VERTEX_ARRAY_COUNT_EXT','%GL_VERTEX_ARRAY_EXT','%GL_VERTEX_ARRAY_POINTER','%GL_VERTEX_ARRAY_POINTER_EXT','%GL_VERTEX_ARRAY_SIZE',
+ '%GL_VERTEX_ARRAY_SIZE_EXT','%GL_VERTEX_ARRAY_STRIDE','%GL_VERTEX_ARRAY_STRIDE_EXT','%GL_VERTEX_ARRAY_TYPE','%GL_VERTEX_ARRAY_TYPE_EXT','%GL_VIEWPORT','%GL_VIEWPORT_BIT','%GL_WIN_SWAP_HINT',
+ '%GL_XOR','%GL_ZERO','%GL_ZOOM_X','%GL_ZOOM_Y','%GRAY','%GREEN','%GWLP_HINSTANCE','%GWLP_HWNDPARENT',
+ '%GWLP_ID','%GWLP_USERDATA','%GWLP_WNDPROC','%GWL_EXSTYLE','%GWL_HINSTANCE','%GWL_HWNDPARENT','%GWL_ID','%GWL_STYLE',
+ '%GWL_USERDATA','%GWL_WNDPROC','%HDM_FIRST','%HTCAPTION','%HWND_BOTTOM','%HWND_DESKTOP','%HWND_MESSAGE','%HWND_NOTOPMOST',
+ '%HWND_TOP','%HWND_TOPMOST','%ICRYPTO_XOR_DECREASE','%ICRYPTO_XOR_INCREASE','%ICRYPTO_XOR_NORMAL','%IDABORT','%IDCANCEL','%IDCONTINUE',
+ '%IDIGNORE','%IDNO','%IDOK','%IDRETRY','%IDTIMEOUT','%IDTRYAGAIN','%IDYES','%INTERNET_CONNECTION_CONFIGURED',
+ '%INTERNET_CONNECTION_LAN','%INTERNET_CONNECTION_MODEM','%INTERNET_CONNECTION_MODEM_BUSY','%INTERNET_CONNECTION_OFFLINE','%INTERNET_CONNECTION_PROXY','%INTERNET_RAS_INSTALLED','%LBN_DBLCLK','%LBN_KILLFOCUS',
+ '%LBN_SELCANCEL','%LBN_SELCHANGE','%LBN_SETFOCUS','%LBS_DISABLENOSCROLL','%LBS_EXTENDEDSEL','%LBS_MULTICOLUMN','%LBS_MULTIPLESEL','%LBS_NOINTEGRALHEIGHT',
+ '%LBS_NOSEL','%LBS_NOTIFY','%LBS_SORT','%LBS_STANDARD','%LBS_USETABSTOPS','%LB_ADDFILE','%LB_ADDSTRING','%LB_DELETESTRING',
+ '%LB_DIR','%LB_FINDSTRING','%LB_FINDSTRINGEXACT','%LB_GETANCHORINDEX','%LB_GETCARETINDEX','%LB_GETCOUNT','%LB_GETCURSEL','%LB_GETHORIZONTALEXTENT',
+ '%LB_GETITEMDATA','%LB_GETITEMHEIGHT','%LB_GETITEMRECT','%LB_GETLISTBOXINFO','%LB_GETLOCALE','%LB_GETSEL','%LB_GETSELCOUNT','%LB_GETSELITEMS',
+ '%LB_GETTEXT','%LB_GETTEXTLEN','%LB_GETTOPINDEX','%LB_INITSTORAGE','%LB_INSERTSTRING','%LB_ITEMFROMPOINT','%LB_MULTIPLEADDSTRING','%LB_RESETCONTENT',
+ '%LB_SELECTSTRING','%LB_SELITEMRANGE','%LB_SELITEMRANGEEX','%LB_SETANCHORINDEX','%LB_SETCARETINDEX','%LB_SETCOLUMNWIDTH','%LB_SETCOUNT','%LB_SETCURSEL',
+ '%LB_SETHORIZONTALEXTENT','%LB_SETITEMDATA','%LB_SETITEMHEIGHT','%LB_SETLOCALE','%LB_SETSEL','%LB_SETTABSTOPS','%LB_SETTOPINDEX','%LF_FACESIZE',
+ '%LTGRAY','%LVM_FIRST','%LWA_ALPHA','%LWA_COLORKEY','%MAGENTA','%MAXBYTE','%MAXCHAR','%MAXDWORD',
+ '%MAXSHORT','%MAXWORD','%MAX_PATH','%MB_ABORTRETRYIGNORE','%MB_APPLMODAL','%MB_CANCELTRYCONTINUE','%MB_DEFBUTTON1','%MB_DEFBUTTON2',
+ '%MB_DEFBUTTON3','%MB_HELP','%MB_ICONASTERISK','%MB_ICONERROR','%MB_ICONEXCLAMATION','%MB_ICONHAND','%MB_ICONINFORMATION','%MB_ICONQUESTION',
+ '%MB_ICONSTOP','%MB_ICONWARNING','%MB_OK','%MB_OKCANCEL','%MB_RETRYCANCEL','%MB_SIMPLE','%MB_SYSTEMMODAL','%MB_TOPMOST',
+ '%MB_YESNO','%MB_YESNOCANCEL','%MF_CHECKED','%MF_DISABLED','%MF_ENABLED','%MF_GRAYED','%MF_SEPARATOR','%MF_UNCHECKED',
+ '%MINCHAR','%MINLONG','%MINSHORT','%NULL','%ODBC352_INC','%ODBCVER','%ODBC_ADD_DSN','%ODBC_ADD_SYS_DSN',
+ '%ODBC_BOTH_DSN','%ODBC_CONFIG_DRIVER','%ODBC_CONFIG_DRIVER_MAX','%ODBC_CONFIG_DSN','%ODBC_CONFIG_SYS_DSN','%ODBC_DRIVER_VERSION','%ODBC_ERROR_COMPONENT_NOT_FOUND','%ODBC_ERROR_CREATE_DSN_FAILED',
+ '%ODBC_ERROR_GENERAL_ERR','%ODBC_ERROR_INVALID_BUFF_LEN','%ODBC_ERROR_INVALID_DSN','%ODBC_ERROR_INVALID_HWND','%ODBC_ERROR_INVALID_INF','%ODBC_ERROR_INVALID_KEYWORD_VALUE','%ODBC_ERROR_INVALID_LOG_FILE','%ODBC_ERROR_INVALID_NAME',
+ '%ODBC_ERROR_INVALID_PARAM_SEQUENCE','%ODBC_ERROR_INVALID_PATH','%ODBC_ERROR_INVALID_REQUEST_TYPE','%ODBC_ERROR_INVALID_STR','%ODBC_ERROR_LOAD_LIB_FAILED','%ODBC_ERROR_OUTPUT_STRING_TRUNCATED','%ODBC_ERROR_OUT_OF_MEM','%ODBC_ERROR_REMOVE_DSN_FAILED',
+ '%ODBC_ERROR_REQUEST_FAILED','%ODBC_ERROR_USAGE_UPDATE_FAILED','%ODBC_ERROR_USER_CANCELED','%ODBC_ERROR_WRITING_SYSINFO_FAILED','%ODBC_INSTALL_COMPLETE','%ODBC_INSTALL_DRIVER','%ODBC_INSTALL_INQUIRY','%ODBC_REMOVE_DEFAULT_DSN',
+ '%ODBC_REMOVE_DRIVER','%ODBC_REMOVE_DSN','%ODBC_REMOVE_SYS_DSN','%ODBC_SYSTEM_DSN','%ODBC_USER_DSN','%OFN_ALLOWMULTISELECT','%OFN_CREATEPROMPT','%OFN_ENABLEHOOK',
+ '%OFN_ENABLEINCLUDENOTIFY','%OFN_ENABLESIZING','%OFN_ENABLETEMPLATE','%OFN_ENABLETEMPLATEHANDLE','%OFN_EXPLORER','%OFN_EXTENSIONDIFFERENT','%OFN_FILEMUSTEXIST','%OFN_HIDEREADONLY',
+ '%OFN_LONGNAMES','%OFN_NOCHANGEDIR','%OFN_NODEREFERENCELINKS','%OFN_NOLONGNAMES','%OFN_NONETWORKBUTTON','%OFN_NOREADONLYRETURN','%OFN_NOTESTFILECREATE','%OFN_NOVALIDATE',
+ '%OFN_OVERWRITEPROMPT','%OFN_PATHMUSTEXIST','%OFN_READONLY','%OFN_SHAREAWARE','%OFN_SHOWHELP','%OS_ERROR_CALLFUNCTION','%OS_ERROR_EMPTYSTRING','%OS_ERROR_LOADLIBRARY',
+ '%OS_ERROR_SUCCESS','%OS_ERROR_WRONGPARAMETER','%OS_SHELL_ASYNC','%OS_SHELL_SYNC','%OS_WINDOWS_2K','%OS_WINDOWS_95','%OS_WINDOWS_95_OSR2','%OS_WINDOWS_98',
+ '%OS_WINDOWS_98_SE','%OS_WINDOWS_ME','%OS_WINDOWS_NT','%OS_WINDOWS_SERVER_2003','%OS_WINDOWS_SERVER_LONGHORN','%OS_WINDOWS_SERVER_LONGHORN_DC','%OS_WINDOWS_VISTA','%OS_WINDOWS_XP',
+ '%OS_WNDSTYLE_HIDE','%OS_WNDSTYLE_MAXIMIZED','%OS_WNDSTYLE_MINIMIZED','%OS_WNDSTYLE_MINIMIZEDNOFOCUS','%OS_WNDSTYLE_NORMAL','%OS_WNDSTYLE_NORMALNOFOCUS','%PATH_EXT','%PATH_FILE',
+ '%PATH_FILEEXT','%PATH_ROOT','%PATH_ROOTPATH','%PATH_ROOTPATHPROG','%PATH_ROOTPATHPROGEXT','%PBM_DELTAPOS','%PBM_GETPOS','%PBM_GETRANGE',
+ '%PBM_SETBARCOLOR','%PBM_SETBKCOLOR','%PBM_SETPOS','%PBM_SETRANGE','%PBM_SETRANGE32','%PBM_SETSTEP','%PBM_STEPIT','%PBS_SMOOTH',
+ '%PBS_VERTICAL','%PC_DISABLEWAKEEVENT_OFF','%PC_DISABLEWAKEEVENT_ON','%PC_EB_NOCONFIRMATION','%PC_EB_NOPROGRESSUI','%PC_EB_NORMAL','%PC_EB_NOSOUND','%PC_FORCECRITICAL_OFF',
+ '%PC_FORCECRITICAL_ON','%PC_HIBERNATE_OFF','%PC_HIBERNATE_ON','%PC_RD_FORCE','%PC_RD_FORCEIFHUNG','%PC_RD_LOGOFF','%PC_RD_POWEROFF','%PC_RD_REBOOT',
+ '%PC_RD_SHUTDOWN','%PC_SD_DONOT_FORCE','%PC_SD_DONOT_REBOOT','%PC_SD_FORCE','%PC_SD_REBOOT','%PFA_CENTER','%PFA_LEFT','%PFA_RIGHT',
+ '%PF_3DNOW_INSTRUCTIONS_AVAILABLE','%PF_CHANNELS_ENABLED','%PF_COMPARE64_EXCHANGE128','%PF_COMPARE_EXCHANGE128','%PF_COMPARE_EXCHANGE_DOUBLE','%PF_FLOATING_POINT_EMULATED','%PF_FLOATING_POINT_PRECISION_ERRATA','%PF_MMX_INSTRUCTIONS_AVAILABLE',
+ '%PF_NX_ENABLED','%PF_PAE_ENABLED','%PF_RDTSC_INSTRUCTION_AVAILABLE','%PF_SSE3_INSTRUCTIONS_AVAILABLE','%PF_XMMI64_INSTRUCTIONS_AVAILABLE','%PF_XMMI_INSTRUCTIONS_AVAILABLE','%PGM_FIRST','%RED',
+ '%RTF_UBB','%SAPI_SVSFDEFAULT','%SAPI_SVSFISFILENAME','%SAPI_SVSFISNOTXML','%SAPI_SVSFISXML','%SAPI_SVSFLAGSASYNC','%SAPI_SVSFNLPMASK','%SAPI_SVSFNLPSPEAKPUNC',
+ '%SAPI_SVSFPERSISTXML','%SAPI_SVSFPURGEBEFORESPEAK','%SAPI_SVSFUNUSEDFLAGS','%SAPI_SVSFVOICEMASK','%SBS_SIZEGRIP','%SB_BOTTOM','%SB_ENDSCROLL','%SB_LEFT',
+ '%SB_LINEDOWN','%SB_LINELEFT','%SB_LINERIGHT','%SB_LINEUP','%SB_PAGEDOWN','%SB_PAGELEFT','%SB_PAGERIGHT','%SB_PAGEUP',
+ '%SB_RIGHT','%SB_SETPARTS','%SB_SETTEXT','%SB_THUMBPOSITION','%SB_THUMBTRACK','%SB_TOP','%SCF_ALL','%SCF_ASSOCIATEFONT',
+ '%SCF_DEFAULT','%SCF_NOKBUPDATE','%SCF_SELECTION','%SCF_USEUIRULES','%SCF_WORD','%SC_CLOSE','%SC_CONTEXTHELP','%SC_HOTKEY',
+ '%SC_HSCROLL','%SC_KEYMENU','%SC_MAXIMIZE','%SC_MINIMIZE','%SC_MONITORPOWER','%SC_MOUSEMENU','%SC_MOVE','%SC_NEXTWINDOW',
+ '%SC_PREVWINDOW','%SC_RESTORE','%SC_SCREENSAVE','%SC_SIZE','%SC_TASKLIST','%SC_VSCROLL','%SERVICE_ACTIVE','%SERVICE_AUTO_START',
+ '%SERVICE_BOOT_START','%SERVICE_CONTINUE_PENDING','%SERVICE_DEMAND_START','%SERVICE_DISABLED','%SERVICE_DRIVER','%SERVICE_INACTIVE','%SERVICE_INFO_DISPLAY_NAME','%SERVICE_INFO_NAME',
+ '%SERVICE_PAUSED','%SERVICE_PAUSE_PENDING','%SERVICE_RUNNING','%SERVICE_START_PENDING','%SERVICE_STATE_ALL','%SERVICE_STOPPED','%SERVICE_STOP_PENDING','%SERVICE_SYSTEM_START',
+ '%SERVICE_TYPE_ALL','%SERVICE_WIN32','%SES_ALLOWBEEPS','%SES_BEEPONMAXTEXT','%SES_BIDI','%SES_EMULATE10','%SES_EMULATESYSEDIT','%SES_EXTENDBACKCOLOR',
+ '%SES_LOWERCASE','%SES_MAPCPS','%SES_NOIME','%SES_NOINPUTSEQUENCECHK','%SES_SCROLLONKILLFOCUS','%SES_UPPERCASE','%SES_USEAIMM','%SES_USECRLF',
+ '%SES_XLTCRCRLFTOCR','%SF_RTF','%SF_TEXT','%SMTP_SET_ATTACH_CONTENT_TYPE','%SMTP_SET_CONTENT_TYPE_PREFIX','%SQL_AA_FALSE','%SQL_AA_TRUE','%SQL_ACCESSIBLE_PROCEDURES',
+ '%SQL_ACCESSIBLE_TABLES','%SQL_ACCESS_MODE','%SQL_ACTIVE_CONNECTIONS','%SQL_ACTIVE_ENVIRONMENTS','%SQL_ACTIVE_STATEMENTS','%SQL_ADD','%SQL_AD_ADD_CONSTRAINT_DEFERRABLE','%SQL_AD_ADD_CONSTRAINT_INITIALLY_DEFERRED',
+ '%SQL_AD_ADD_CONSTRAINT_INITIALLY_IMMEDIATE','%SQL_AD_ADD_CONSTRAINT_NON_DEFERRABLE','%SQL_AD_ADD_DOMAIN_CONSTRAINT','%SQL_AD_ADD_DOMAIN_DEFAULT','%SQL_AD_CONSTRAINT_NAME_DEFINITION','%SQL_AD_DROP_DOMAIN_CONSTRAINT','%SQL_AD_DROP_DOMAIN_DEFAULT','%SQL_AF_ALL',
+ '%SQL_AF_AVG','%SQL_AF_COUNT','%SQL_AF_DISTINCT','%SQL_AF_MAX','%SQL_AF_MIN','%SQL_AF_SUM','%SQL_AGGREGATE_FUNCTIONS','%SQL_ALL_EXCEPT_LIKE',
+ '%SQL_ALL_TYPES','%SQL_ALTER_DOMAIN','%SQL_ALTER_TABLE','%SQL_AM_CONNECTION','%SQL_AM_NONE','%SQL_AM_STATEMENT','%SQL_API_ALL_FUNCTIONS','%SQL_API_LOADBYORDINAL',
+ '%SQL_API_ODBC3_ALL_FUNCTIONS','%SQL_API_ODBC3_ALL_FUNCTIONS_SIZE','%SQL_API_SQLALLOCCONNECT','%SQL_API_SQLALLOCENV','%SQL_API_SQLALLOCHANDLE','%SQL_API_SQLALLOCHANDLESTD','%SQL_API_SQLALLOCSTMT','%SQL_API_SQLBINDCOL',
+ '%SQL_API_SQLBINDPARAM','%SQL_API_SQLBINDPARAMETER','%SQL_API_SQLBROWSECONNECT','%SQL_API_SQLBULKOPERATIONS','%SQL_API_SQLCANCEL','%SQL_API_SQLCLOSECURSOR','%SQL_API_SQLCOLATTRIBUTE','%SQL_API_SQLCOLATTRIBUTES',
+ '%SQL_API_SQLCOLUMNPRIVILEGES','%SQL_API_SQLCOLUMNS','%SQL_API_SQLCONNECT','%SQL_API_SQLCOPYDESC','%SQL_API_SQLDATASOURCES','%SQL_API_SQLDESCRIBECOL','%SQL_API_SQLDESCRIBEPARAM','%SQL_API_SQLDISCONNECT',
+ '%SQL_API_SQLDRIVERCONNECT','%SQL_API_SQLDRIVERS','%SQL_API_SQLENDTRAN','%SQL_API_SQLERROR','%SQL_API_SQLEXECDIRECT','%SQL_API_SQLEXECUTE','%SQL_API_SQLEXTENDEDFETCH','%SQL_API_SQLFETCH',
+ '%SQL_API_SQLFETCHSCROLL','%SQL_API_SQLFOREIGNKEYS','%SQL_API_SQLFREECONNECT','%SQL_API_SQLFREEENV','%SQL_API_SQLFREEHANDLE','%SQL_API_SQLFREESTMT','%SQL_API_SQLGETCONNECTATTR','%SQL_API_SQLGETCONNECTOPTION',
+ '%SQL_API_SQLGETCURSORNAME','%SQL_API_SQLGETDATA','%SQL_API_SQLGETDESCFIELD','%SQL_API_SQLGETDESCREC','%SQL_API_SQLGETDIAGFIELD','%SQL_API_SQLGETDIAGREC','%SQL_API_SQLGETENVATTR','%SQL_API_SQLGETFUNCTIONS',
+ '%SQL_API_SQLGETINFO','%SQL_API_SQLGETSTMTATTR','%SQL_API_SQLGETSTMTOPTION','%SQL_API_SQLGETTYPEINFO','%SQL_API_SQLMORERESULTS','%SQL_API_SQLNATIVESQL','%SQL_API_SQLNUMPARAMS','%SQL_API_SQLNUMRESULTCOLS',
+ '%SQL_API_SQLPARAMDATA','%SQL_API_SQLPARAMOPTIONS','%SQL_API_SQLPREPARE','%SQL_API_SQLPRIMARYKEYS','%SQL_API_SQLPROCEDURECOLUMNS','%SQL_API_SQLPROCEDURES','%SQL_API_SQLPUTDATA','%SQL_API_SQLROWCOUNT',
+ '%SQL_API_SQLSETCONNECTATTR','%SQL_API_SQLSETCONNECTOPTION','%SQL_API_SQLSETCURSORNAME','%SQL_API_SQLSETDESCFIELD','%SQL_API_SQLSETDESCREC','%SQL_API_SQLSETENVATTR','%SQL_API_SQLSETPARAM','%SQL_API_SQLSETPOS',
+ '%SQL_API_SQLSETSCROLLOPTIONS','%SQL_API_SQLSETSTMTATTR','%SQL_API_SQLSETSTMTOPTION','%SQL_API_SQLSPECIALCOLUMNS','%SQL_API_SQLSTATISTICS','%SQL_API_SQLTABLEPRIVILEGES','%SQL_API_SQLTABLES','%SQL_API_SQLTRANSACT',
+ '%SQL_ARD_TYPE','%SQL_ASYNC_ENABLE','%SQL_ASYNC_ENABLE_DEFAULT','%SQL_ASYNC_ENABLE_OFF','%SQL_ASYNC_ENABLE_ON','%SQL_ASYNC_MODE','%SQL_ATTR_ACCESS_MODE','%SQL_ATTR_ANSI_APP',
+ '%SQL_ATTR_APP_PARAM_DESC','%SQL_ATTR_APP_ROW_DESC','%SQL_ATTR_ASYNC_ENABLE','%SQL_ATTR_AUTOCOMMIT','%SQL_ATTR_AUTO_IPD','%SQL_ATTR_CONCURRENCY','%SQL_ATTR_CONNECTION_DEAD','%SQL_ATTR_CONNECTION_POOLING',
+ '%SQL_ATTR_CONNECTION_TIMEOUT','%SQL_ATTR_CP_MATCH','%SQL_ATTR_CURRENT_CATALOG','%SQL_ATTR_CURSOR_SCROLLABLE','%SQL_ATTR_CURSOR_SENSITIVITY','%SQL_ATTR_CURSOR_TYPE','%SQL_ATTR_DISCONNECT_BEHAVIOR','%SQL_ATTR_ENABLE_AUTO_IPD',
+ '%SQL_ATTR_ENLIST_IN_DTC','%SQL_ATTR_ENLIST_IN_XA','%SQL_ATTR_FETCH_BOOKMARK_PTR','%SQL_ATTR_IMP_PARAM_DESC','%SQL_ATTR_IMP_ROW_DESC','%SQL_ATTR_KEYSET_SIZE','%SQL_ATTR_LOGIN_TIMEOUT','%SQL_ATTR_MAX_LENGTH',
+ '%SQL_ATTR_MAX_ROWS','%SQL_ATTR_METADATA_ID','%SQL_ATTR_NOSCAN','%SQL_ATTR_ODBC_CURSORS','%SQL_ATTR_ODBC_VERSION','%SQL_ATTR_OUTPUT_NTS','%SQL_ATTR_PACKET_SIZE','%SQL_ATTR_PARAMSET_SIZE',
+ '%SQL_ATTR_PARAMS_PROCESSED_PTR','%SQL_ATTR_PARAM_BIND_OFFSET_PTR','%SQL_ATTR_PARAM_BIND_TYPE','%SQL_ATTR_PARAM_OPERATION_PTR','%SQL_ATTR_PARAM_STATUS_PTR','%SQL_ATTR_QUERY_TIMEOUT','%SQL_ATTR_QUIET_MODE','%SQL_ATTR_READONLY',
+ '%SQL_ATTR_READWRITE_UNKNOWN','%SQL_ATTR_RETRIEVE_DATA','%SQL_ATTR_ROWS_FETCHED_PTR','%SQL_ATTR_ROW_ARRAY_SIZE','%SQL_ATTR_ROW_BIND_OFFSET_PTR','%SQL_ATTR_ROW_BIND_TYPE','%SQL_ATTR_ROW_NUMBER','%SQL_ATTR_ROW_OPERATION_PTR',
+ '%SQL_ATTR_ROW_STATUS_PTR','%SQL_ATTR_SIMULATE_CURSOR','%SQL_ATTR_TRACE','%SQL_ATTR_TRACEFILE','%SQL_ATTR_TRANSLATE_LIB','%SQL_ATTR_TRANSLATE_OPTION','%SQL_ATTR_TXN_ISOLATION','%SQL_ATTR_USE_BOOKMARKS',
+ '%SQL_ATTR_WRITE','%SQL_AT_ADD_COLUMN','%SQL_AT_ADD_COLUMN_COLLATION','%SQL_AT_ADD_COLUMN_DEFAULT','%SQL_AT_ADD_COLUMN_SINGLE','%SQL_AT_ADD_CONSTRAINT','%SQL_AT_ADD_TABLE_CONSTRAINT','%SQL_AT_CONSTRAINT_DEFERRABLE',
+ '%SQL_AT_CONSTRAINT_INITIALLY_DEFERRED','%SQL_AT_CONSTRAINT_INITIALLY_IMMEDIATE','%SQL_AT_CONSTRAINT_NAME_DEFINITION','%SQL_AT_CONSTRAINT_NON_DEFERRABLE','%SQL_AT_DROP_COLUMN','%SQL_AT_DROP_COLUMN_CASCADE','%SQL_AT_DROP_COLUMN_DEFAULT','%SQL_AT_DROP_COLUMN_RESTRICT',
+ '%SQL_AT_DROP_TABLE_CONSTRAINT_CASCADE','%SQL_AT_DROP_TABLE_CONSTRAINT_RESTRICT','%SQL_AT_SET_COLUMN_DEFAULT','%SQL_AUTOCOMMIT','%SQL_AUTOCOMMIT_DEFAULT','%SQL_AUTOCOMMIT_OFF','%SQL_AUTOCOMMIT_ON','%SQL_BATCH_ROW_COUNT',
+ '%SQL_BATCH_SUPPORT','%SQL_BEST_ROWID','%SQL_BIGINT','%SQL_BINARY','%SQL_BIND_BY_COLUMN','%SQL_BIND_TYPE','%SQL_BIND_TYPE_DEFAULT','%SQL_BIT',
+ '%SQL_BOOKMARK_PERSISTENCE','%SQL_BP_CLOSE','%SQL_BP_DELETE','%SQL_BP_DROP','%SQL_BP_OTHER_HSTMT','%SQL_BP_SCROLL','%SQL_BP_TRANSACTION','%SQL_BP_UPDATE',
+ '%SQL_BRC_EXPLICIT','%SQL_BRC_PROCEDURES','%SQL_BRC_ROLLED_UP','%SQL_BS_ROW_COUNT_EXPLICIT','%SQL_BS_ROW_COUNT_PROC','%SQL_BS_SELECT_EXPLICIT','%SQL_BS_SELECT_PROC','%SQL_CA1_ABSOLUTE',
+ '%SQL_CA1_BOOKMARK','%SQL_CA1_BULK_ADD','%SQL_CA1_BULK_DELETE_BY_BOOKMARK','%SQL_CA1_BULK_FETCH_BY_BOOKMARK','%SQL_CA1_BULK_UPDATE_BY_BOOKMARK','%SQL_CA1_LOCK_EXCLUSIVE','%SQL_CA1_LOCK_NO_CHANGE','%SQL_CA1_LOCK_UNLOCK',
+ '%SQL_CA1_NEXT','%SQL_CA1_POSITIONED_DELETE','%SQL_CA1_POSITIONED_UPDATE','%SQL_CA1_POS_DELETE','%SQL_CA1_POS_POSITION','%SQL_CA1_POS_REFRESH','%SQL_CA1_POS_UPDATE','%SQL_CA1_RELATIVE',
+ '%SQL_CA1_SELECT_FOR_UPDATE','%SQL_CA2_CRC_APPROXIMATE','%SQL_CA2_CRC_EXACT','%SQL_CA2_LOCK_CONCURRENCY','%SQL_CA2_MAX_ROWS_AFFECTS_ALL','%SQL_CA2_MAX_ROWS_CATALOG','%SQL_CA2_MAX_ROWS_DELETE','%SQL_CA2_MAX_ROWS_INSERT',
+ '%SQL_CA2_MAX_ROWS_SELECT','%SQL_CA2_MAX_ROWS_UPDATE','%SQL_CA2_OPT_ROWVER_CONCURRENCY','%SQL_CA2_OPT_VALUES_CONCURRENCY','%SQL_CA2_READ_ONLY_CONCURRENCY','%SQL_CA2_SENSITIVITY_ADDITIONS','%SQL_CA2_SENSITIVITY_DELETIONS','%SQL_CA2_SENSITIVITY_UPDATES',
+ '%SQL_CA2_SIMULATE_NON_UNIQUE','%SQL_CA2_SIMULATE_TRY_UNIQUE','%SQL_CA2_SIMULATE_UNIQUE','%SQL_CASCADE','%SQL_CATALOG_LOCATION','%SQL_CATALOG_NAME','%SQL_CATALOG_NAME_SEPARATOR','%SQL_CATALOG_TERM',
+ '%SQL_CATALOG_USAGE','%SQL_CA_CONSTRAINT_DEFERRABLE','%SQL_CA_CONSTRAINT_INITIALLY_DEFERRED','%SQL_CA_CONSTRAINT_INITIALLY_IMMEDIATE','%SQL_CA_CONSTRAINT_NON_DEFERRABLE','%SQL_CA_CREATE_ASSERTION','%SQL_CB_CLOSE','%SQL_CB_DELETE',
+ '%SQL_CB_NON_NULL','%SQL_CB_NULL','%SQL_CB_PRESERVE','%SQL_CCOL_CREATE_COLLATION','%SQL_CCS_COLLATE_CLAUSE','%SQL_CCS_CREATE_CHARACTER_SET','%SQL_CCS_LIMITED_COLLATION','%SQL_CC_CLOSE',
+ '%SQL_CC_DELETE','%SQL_CC_PRESERVE','%SQL_CDO_COLLATION','%SQL_CDO_CONSTRAINT','%SQL_CDO_CONSTRAINT_DEFERRABLE','%SQL_CDO_CONSTRAINT_INITIALLY_DEFERRED','%SQL_CDO_CONSTRAINT_INITIALLY_IMMEDIATE','%SQL_CDO_CONSTRAINT_NAME_DEFINITION',
+ '%SQL_CDO_CONSTRAINT_NON_DEFERRABLE','%SQL_CDO_CREATE_DOMAIN','%SQL_CDO_DEFAULT','%SQL_CD_FALSE','%SQL_CD_TRUE','%SQL_CHAR','%SQL_CLOSE','%SQL_CL_END',
+ '%SQL_CL_START','%SQL_CN_ANY','%SQL_CN_DIFFERENT','%SQL_CN_NONE','%SQL_CODE_DATE','%SQL_CODE_DAY','%SQL_CODE_DAY_TO_HOUR','%SQL_CODE_DAY_TO_MINUTE',
+ '%SQL_CODE_DAY_TO_SECOND','%SQL_CODE_HOUR','%SQL_CODE_HOUR_TO_MINUTE','%SQL_CODE_HOUR_TO_SECOND','%SQL_CODE_MINUTE','%SQL_CODE_MINUTE_TO_SECOND','%SQL_CODE_MONTH','%SQL_CODE_SECOND',
+ '%SQL_CODE_TIME','%SQL_CODE_TIMESTAMP','%SQL_CODE_YEAR','%SQL_CODE_YEAR_TO_MONTH','%SQL_COLATT_OPT_MAX','%SQL_COLATT_OPT_MIN','%SQL_COLLATION_SEQ','%SQL_COLUMN_ALIAS',
+ '%SQL_COLUMN_AUTO_INCREMENT','%SQL_COLUMN_CASE_SENSITIVE','%SQL_COLUMN_COUNT','%SQL_COLUMN_DISPLAY_SIZE','%SQL_COLUMN_IGNORE','%SQL_COLUMN_LABEL','%SQL_COLUMN_LENGTH','%SQL_COLUMN_MONEY',
+ '%SQL_COLUMN_NAME','%SQL_COLUMN_NULLABLE','%SQL_COLUMN_NUMBER_UNKNOWN','%SQL_COLUMN_OWNER_NAME','%SQL_COLUMN_PRECISION','%SQL_COLUMN_QUALIFIER_NAME','%SQL_COLUMN_SCALE','%SQL_COLUMN_SEARCHABLE',
+ '%SQL_COLUMN_TABLE_NAME','%SQL_COLUMN_TYPE','%SQL_COLUMN_TYPE_NAME','%SQL_COLUMN_UNSIGNED','%SQL_COLUMN_UPDATABLE','%SQL_COL_PRED_BASIC','%SQL_COL_PRED_CHAR','%SQL_COMMIT',
+ '%SQL_CONCAT_NULL_BEHAVIOR','%SQL_CONCURRENCY','%SQL_CONCUR_DEFAULT','%SQL_CONCUR_LOCK','%SQL_CONCUR_READ_ONLY','%SQL_CONCUR_ROWVER','%SQL_CONCUR_TIMESTAMP','%SQL_CONCUR_VALUES',
+ '%SQL_CONVERT_BIGINT','%SQL_CONVERT_BINARY','%SQL_CONVERT_BIT','%SQL_CONVERT_CHAR','%SQL_CONVERT_DATE','%SQL_CONVERT_DECIMAL','%SQL_CONVERT_DOUBLE','%SQL_CONVERT_FLOAT',
+ '%SQL_CONVERT_FUNCTIONS','%SQL_CONVERT_GUID','%SQL_CONVERT_INTEGER','%SQL_CONVERT_INTERVAL_DAY_TIME','%SQL_CONVERT_INTERVAL_YEAR_MONTH','%SQL_CONVERT_LONGVARBINARY','%SQL_CONVERT_LONGVARCHAR','%SQL_CONVERT_NUMERIC',
+ '%SQL_CONVERT_REAL','%SQL_CONVERT_SMALLINT','%SQL_CONVERT_TIME','%SQL_CONVERT_TIMESTAMP','%SQL_CONVERT_TINYINT','%SQL_CONVERT_VARBINARY','%SQL_CONVERT_VARCHAR','%SQL_CONVERT_WCHAR',
+ '%SQL_CONVERT_WLONGVARCHAR','%SQL_CONVERT_WVARCHAR','%SQL_CORRELATION_NAME','%SQL_CP_DEFAULT','%SQL_CP_MATCH_DEFAULT','%SQL_CP_OFF','%SQL_CP_ONE_PER_DRIVER','%SQL_CP_ONE_PER_HENV',
+ '%SQL_CP_RELAXED_MATCH','%SQL_CP_STRICT_MATCH','%SQL_CREATE_ASSERTION','%SQL_CREATE_CHARACTER_SET','%SQL_CREATE_COLLATION','%SQL_CREATE_DOMAIN','%SQL_CREATE_SCHEMA','%SQL_CREATE_TABLE',
+ '%SQL_CREATE_TRANSLATION','%SQL_CREATE_VIEW','%SQL_CR_CLOSE','%SQL_CR_DELETE','%SQL_CR_PRESERVE','%SQL_CS_AUTHORIZATION','%SQL_CS_CREATE_SCHEMA','%SQL_CS_DEFAULT_CHARACTER_SET',
+ '%SQL_CTR_CREATE_TRANSLATION','%SQL_CT_COLUMN_COLLATION','%SQL_CT_COLUMN_CONSTRAINT','%SQL_CT_COLUMN_DEFAULT','%SQL_CT_COMMIT_DELETE','%SQL_CT_COMMIT_PRESERVE','%SQL_CT_CONSTRAINT_DEFERRABLE','%SQL_CT_CONSTRAINT_INITIALLY_DEFERRED',
+ '%SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE','%SQL_CT_CONSTRAINT_NAME_DEFINITION','%SQL_CT_CONSTRAINT_NON_DEFERRABLE','%SQL_CT_CREATE_TABLE','%SQL_CT_GLOBAL_TEMPORARY','%SQL_CT_LOCAL_TEMPORARY','%SQL_CT_TABLE_CONSTRAINT','%SQL_CURRENT_QUALIFIER',
+ '%SQL_CURSOR_COMMIT_BEHAVIOR','%SQL_CURSOR_DYNAMIC','%SQL_CURSOR_FORWARD_ONLY','%SQL_CURSOR_KEYSET_DRIVEN','%SQL_CURSOR_ROLLBACK_BEHAVIOR','%SQL_CURSOR_SENSITIVITY','%SQL_CURSOR_STATIC','%SQL_CURSOR_TYPE',
+ '%SQL_CURSOR_TYPE_DEFAULT','%SQL_CUR_DEFAULT','%SQL_CUR_USE_DRIVER','%SQL_CUR_USE_IF_NEEDED','%SQL_CUR_USE_ODBC','%SQL_CU_DML_STATEMENTS','%SQL_CU_INDEX_DEFINITION','%SQL_CU_PRIVILEGE_DEFINITION',
+ '%SQL_CU_PROCEDURE_INVOCATION','%SQL_CU_TABLE_DEFINITION','%SQL_CVT_BIGINT','%SQL_CVT_BINARY','%SQL_CVT_BIT','%SQL_CVT_CHAR','%SQL_CVT_DATE','%SQL_CVT_DECIMAL',
+ '%SQL_CVT_DOUBLE','%SQL_CVT_FLOAT','%SQL_CVT_GUID','%SQL_CVT_INTEGER','%SQL_CVT_INTERVAL_DAY_TIME','%SQL_CVT_INTERVAL_YEAR_MONTH','%SQL_CVT_LONGVARBINARY','%SQL_CVT_LONGVARCHAR',
+ '%SQL_CVT_NUMERIC','%SQL_CVT_REAL','%SQL_CVT_SMALLINT','%SQL_CVT_TIME','%SQL_CVT_TIMESTAMP','%SQL_CVT_TINYINT','%SQL_CVT_VARBINARY','%SQL_CVT_VARCHAR',
+ '%SQL_CVT_WCHAR','%SQL_CVT_WLONGVARCHAR','%SQL_CVT_WVARCHAR','%SQL_CV_CASCADED','%SQL_CV_CHECK_OPTION','%SQL_CV_CREATE_VIEW','%SQL_CV_LOCAL','%SQL_C_BINARY',
+ '%SQL_C_BIT','%SQL_C_BOOKMARK','%SQL_C_CHAR','%SQL_C_DATE','%SQL_C_DEFAULT','%SQL_C_DOUBLE','%SQL_C_FLOAT','%SQL_C_GUID',
+ '%SQL_C_INTERVAL_DAY','%SQL_C_INTERVAL_DAY_TO_HOUR','%SQL_C_INTERVAL_DAY_TO_MINUTE','%SQL_C_INTERVAL_DAY_TO_SECOND','%SQL_C_INTERVAL_HOUR','%SQL_C_INTERVAL_HOUR_TO_MINUTE','%SQL_C_INTERVAL_HOUR_TO_SECOND','%SQL_C_INTERVAL_MINUTE',
+ '%SQL_C_INTERVAL_MINUTE_TO_SECOND','%SQL_C_INTERVAL_MONTH','%SQL_C_INTERVAL_SECOND','%SQL_C_INTERVAL_YEAR','%SQL_C_INTERVAL_YEAR_TO_MONTH','%SQL_C_LONG','%SQL_C_NUMERIC','%SQL_C_SBIGINT',
+ '%SQL_C_SHORT','%SQL_C_SLONG','%SQL_C_SSHORT','%SQL_C_STINYINT','%SQL_C_TIME','%SQL_C_TIMESTAMP','%SQL_C_TINYINT','%SQL_C_TYPE_DATE',
+ '%SQL_C_TYPE_TIME','%SQL_C_TYPE_TIMESTAMP','%SQL_C_UBIGINT','%SQL_C_ULONG','%SQL_C_USHORT','%SQL_C_UTINYINT','%SQL_C_VARBOOKMARK','%SQL_DATABASE_NAME',
+ '%SQL_DATA_AT_EXEC','%SQL_DATA_SOURCE_NAME','%SQL_DATA_SOURCE_READ_ONLY','%SQL_DATE','%SQL_DATETIME','%SQL_DATETIME_LITERALS','%SQL_DATE_LEN','%SQL_DAY',
+ '%SQL_DAY_TO_HOUR','%SQL_DAY_TO_MINUTE','%SQL_DAY_TO_SECOND','%SQL_DA_DROP_ASSERTION','%SQL_DBMS_NAME','%SQL_DBMS_VER','%SQL_DB_DEFAULT','%SQL_DB_DISCONNECT',
+ '%SQL_DB_RETURN_TO_POOL','%SQL_DCS_DROP_CHARACTER_SET','%SQL_DC_DROP_COLLATION','%SQL_DDL_INDEX','%SQL_DD_CASCADE','%SQL_DD_DROP_DOMAIN','%SQL_DD_RESTRICT','%SQL_DECIMAL',
+ '%SQL_DEFAULT','%SQL_DEFAULT_PARAM','%SQL_DEFAULT_TXN_ISOLATION','%SQL_DELETE','%SQL_DELETE_BY_BOOKMARK','%SQL_DESCRIBE_PARAMETER','%SQL_DESC_ALLOC_AUTO','%SQL_DESC_ALLOC_TYPE',
+ '%SQL_DESC_ALLOC_USER','%SQL_DESC_ARRAY_SIZE','%SQL_DESC_ARRAY_STATUS_PTR','%SQL_DESC_AUTO_UNIQUE_VALUE','%SQL_DESC_BASE_COLUMN_NAME','%SQL_DESC_BASE_TABLE_NAME','%SQL_DESC_BIND_OFFSET_PTR','%SQL_DESC_BIND_TYPE',
+ '%SQL_DESC_CASE_SENSITIVE','%SQL_DESC_CATALOG_NAME','%SQL_DESC_CONCISE_TYPE','%SQL_DESC_COUNT','%SQL_DESC_DATA_PTR','%SQL_DESC_DATETIME_INTERVAL_CODE','%SQL_DESC_DATETIME_INTERVAL_PRECISION','%SQL_DESC_DISPLAY_SIZE',
+ '%SQL_DESC_FIXED_PREC_SCALE','%SQL_DESC_INDICATOR_PTR','%SQL_DESC_LABEL','%SQL_DESC_LENGTH','%SQL_DESC_LITERAL_PREFIX','%SQL_DESC_LITERAL_SUFFIX','%SQL_DESC_LOCAL_TYPE_NAME','%SQL_DESC_MAXIMUM_SCALE',
+ '%SQL_DESC_MINIMUM_SCALE','%SQL_DESC_NAME','%SQL_DESC_NULLABLE','%SQL_DESC_NUM_PREC_RADIX','%SQL_DESC_OCTET_LENGTH','%SQL_DESC_OCTET_LENGTH_PTR','%SQL_DESC_PARAMETER_TYPE','%SQL_DESC_PRECISION',
+ '%SQL_DESC_ROWS_PROCESSED_PTR','%SQL_DESC_SCALE','%SQL_DESC_SCHEMA_NAME','%SQL_DESC_SEARCHABLE','%SQL_DESC_TABLE_NAME','%SQL_DESC_TYPE','%SQL_DESC_TYPE_NAME','%SQL_DESC_UNNAMED',
+ '%SQL_DESC_UNSIGNED','%SQL_DESC_UPDATABLE','%SQL_DIAG_ALTER_TABLE','%SQL_DIAG_CALL','%SQL_DIAG_CLASS_ORIGIN','%SQL_DIAG_COLUMN_NUMBER','%SQL_DIAG_CONNECTION_NAME','%SQL_DIAG_CREATE_INDEX',
+ '%SQL_DIAG_CREATE_TABLE','%SQL_DIAG_CREATE_VIEW','%SQL_DIAG_CURSOR_ROW_COUNT','%SQL_DIAG_DELETE_WHERE','%SQL_DIAG_DROP_INDEX','%SQL_DIAG_DROP_TABLE','%SQL_DIAG_DROP_VIEW','%SQL_DIAG_DYNAMIC_DELETE_CURSOR',
+ '%SQL_DIAG_DYNAMIC_FUNCTION','%SQL_DIAG_DYNAMIC_FUNCTION_CODE','%SQL_DIAG_DYNAMIC_UPDATE_CURSOR','%SQL_DIAG_GRANT','%SQL_DIAG_INSERT','%SQL_DIAG_MESSAGE_TEXT','%SQL_DIAG_NATIVE','%SQL_DIAG_NUMBER',
+ '%SQL_DIAG_RETURNCODE','%SQL_DIAG_REVOKE','%SQL_DIAG_ROW_COUNT','%SQL_DIAG_ROW_NUMBER','%SQL_DIAG_SELECT_CURSOR','%SQL_DIAG_SERVER_NAME','%SQL_DIAG_SQLSTATE','%SQL_DIAG_SUBCLASS_ORIGIN',
+ '%SQL_DIAG_UNKNOWN_STATEMENT','%SQL_DIAG_UPDATE_WHERE','%SQL_DI_CREATE_INDEX','%SQL_DI_DROP_INDEX','%SQL_DL_SQL92_DATE','%SQL_DL_SQL92_INTERVAL_DAY','%SQL_DL_SQL92_INTERVAL_DAY_TO_HOUR','%SQL_DL_SQL92_INTERVAL_DAY_TO_MINUTE',
+ '%SQL_DL_SQL92_INTERVAL_DAY_TO_SECOND','%SQL_DL_SQL92_INTERVAL_HOUR','%SQL_DL_SQL92_INTERVAL_HOUR_TO_MINUTE','%SQL_DL_SQL92_INTERVAL_HOUR_TO_SECOND','%SQL_DL_SQL92_INTERVAL_MINUTE','%SQL_DL_SQL92_INTERVAL_MINUTE_TO_SECOND','%SQL_DL_SQL92_INTERVAL_MONTH','%SQL_DL_SQL92_INTERVAL_SECOND',
+ '%SQL_DL_SQL92_INTERVAL_YEAR','%SQL_DL_SQL92_INTERVAL_YEAR_TO_MONTH','%SQL_DL_SQL92_TIME','%SQL_DL_SQL92_TIMESTAMP','%SQL_DM_VER','%SQL_DOUBLE','%SQL_DRIVER_COMPLETE','%SQL_DRIVER_COMPLETE_REQUIRED',
+ '%SQL_DRIVER_HDBC','%SQL_DRIVER_HDESC','%SQL_DRIVER_HENV','%SQL_DRIVER_HLIB','%SQL_DRIVER_HSTMT','%SQL_DRIVER_NAME','%SQL_DRIVER_NOPROMPT','%SQL_DRIVER_ODBC_VER',
+ '%SQL_DRIVER_PROMPT','%SQL_DRIVER_VER','%SQL_DROP','%SQL_DROP_ASSERTION','%SQL_DROP_CHARACTER_SET','%SQL_DROP_COLLATION','%SQL_DROP_DOMAIN','%SQL_DROP_SCHEMA',
+ '%SQL_DROP_TABLE','%SQL_DROP_TRANSLATION','%SQL_DROP_VIEW','%SQL_DS_CASCADE','%SQL_DS_DROP_SCHEMA','%SQL_DS_RESTRICT','%SQL_DTC_DONE','%SQL_DTC_ENLIST_EXPENSIVE',
+ '%SQL_DTC_TRANSITION_COST','%SQL_DTC_UNENLIST_EXPENSIVE','%SQL_DTR_DROP_TRANSLATION','%SQL_DT_CASCADE','%SQL_DT_DROP_TABLE','%SQL_DT_RESTRICT','%SQL_DV_CASCADE','%SQL_DV_DROP_VIEW',
+ '%SQL_DV_RESTRICT','%SQL_DYNAMIC_CURSOR_ATTRIBUTES1','%SQL_DYNAMIC_CURSOR_ATTRIBUTES2','%SQL_ENSURE','%SQL_ENTIRE_ROWSET','%SQL_ERROR','%SQL_EXPRESSIONS_IN_ORDERBY','%SQL_FALSE',
+ '%SQL_FD_FETCH_ABSOLUTE','%SQL_FD_FETCH_BOOKMARK','%SQL_FD_FETCH_FIRST','%SQL_FD_FETCH_LAST','%SQL_FD_FETCH_NEXT','%SQL_FD_FETCH_PREV','%SQL_FD_FETCH_PRIOR','%SQL_FD_FETCH_RELATIVE',
+ '%SQL_FETCH_ABSOLUTE','%SQL_FETCH_BOOKMARK','%SQL_FETCH_BY_BOOKMARK','%SQL_FETCH_DIRECTION','%SQL_FETCH_FIRST','%SQL_FETCH_FIRST_SYSTEM','%SQL_FETCH_FIRST_USER','%SQL_FETCH_LAST',
+ '%SQL_FETCH_NEXT','%SQL_FETCH_PREV','%SQL_FETCH_PRIOR','%SQL_FETCH_RELATIVE','%SQL_FILE_CATALOG','%SQL_FILE_NOT_SUPPORTED','%SQL_FILE_QUALIFIER','%SQL_FILE_TABLE',
+ '%SQL_FILE_USAGE','%SQL_FLOAT','%SQL_FN_CVT_CAST','%SQL_FN_CVT_CONVERT','%SQL_FN_NUM_ABS','%SQL_FN_NUM_ACOS','%SQL_FN_NUM_ASIN','%SQL_FN_NUM_ATAN',
+ '%SQL_FN_NUM_ATAN2','%SQL_FN_NUM_CEILING','%SQL_FN_NUM_COS','%SQL_FN_NUM_COT','%SQL_FN_NUM_DEGREES','%SQL_FN_NUM_EXP','%SQL_FN_NUM_FLOOR','%SQL_FN_NUM_LOG',
+ '%SQL_FN_NUM_LOG10','%SQL_FN_NUM_MOD','%SQL_FN_NUM_PI','%SQL_FN_NUM_POWER','%SQL_FN_NUM_RADIANS','%SQL_FN_NUM_RAND','%SQL_FN_NUM_ROUND','%SQL_FN_NUM_SIGN',
+ '%SQL_FN_NUM_SIN','%SQL_FN_NUM_SQRT','%SQL_FN_NUM_TAN','%SQL_FN_NUM_TRUNCATE','%SQL_FN_STR_ASCII','%SQL_FN_STR_BIT_LENGTH','%SQL_FN_STR_CHAR','%SQL_FN_STR_CHARACTER_LENGTH',
+ '%SQL_FN_STR_CHAR_LENGTH','%SQL_FN_STR_CONCAT','%SQL_FN_STR_DIFFERENCE','%SQL_FN_STR_INSERT','%SQL_FN_STR_LCASE','%SQL_FN_STR_LEFT','%SQL_FN_STR_LENGTH','%SQL_FN_STR_LOCATE',
+ '%SQL_FN_STR_LOCATE_2','%SQL_FN_STR_LTRIM','%SQL_FN_STR_OCTET_LENGTH','%SQL_FN_STR_POSITION','%SQL_FN_STR_REPEAT','%SQL_FN_STR_REPLACE','%SQL_FN_STR_RIGHT','%SQL_FN_STR_RTRIM',
+ '%SQL_FN_STR_SOUNDEX','%SQL_FN_STR_SPACE','%SQL_FN_STR_SUBSTRING','%SQL_FN_STR_UCASE','%SQL_FN_SYS_DBNAME','%SQL_FN_SYS_IFNULL','%SQL_FN_SYS_USERNAME','%SQL_FN_TD_CURDATE',
+ '%SQL_FN_TD_CURRENT_DATE','%SQL_FN_TD_CURRENT_TIME','%SQL_FN_TD_CURRENT_TIMESTAMP','%SQL_FN_TD_CURTIME','%SQL_FN_TD_DAYNAME','%SQL_FN_TD_DAYOFMONTH','%SQL_FN_TD_DAYOFWEEK','%SQL_FN_TD_DAYOFYEAR',
+ '%SQL_FN_TD_EXTRACT','%SQL_FN_TD_HOUR','%SQL_FN_TD_MINUTE','%SQL_FN_TD_MONTH','%SQL_FN_TD_MONTHNAME','%SQL_FN_TD_NOW','%SQL_FN_TD_QUARTER','%SQL_FN_TD_SECOND',
+ '%SQL_FN_TD_TIMESTAMPADD','%SQL_FN_TD_TIMESTAMPDIFF','%SQL_FN_TD_WEEK','%SQL_FN_TD_YEAR','%SQL_FN_TSI_DAY','%SQL_FN_TSI_FRAC_SECOND','%SQL_FN_TSI_HOUR','%SQL_FN_TSI_MINUTE',
+ '%SQL_FN_TSI_MONTH','%SQL_FN_TSI_QUARTER','%SQL_FN_TSI_SECOND','%SQL_FN_TSI_WEEK','%SQL_FN_TSI_YEAR','%SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1','%SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2','%SQL_GB_COLLATE',
+ '%SQL_GB_GROUP_BY_CONTAINS_SELECT','%SQL_GB_GROUP_BY_EQUALS_SELECT','%SQL_GB_NOT_SUPPORTED','%SQL_GB_NO_RELATION','%SQL_GD_ANY_COLUMN','%SQL_GD_ANY_ORDER','%SQL_GD_BLOCK','%SQL_GD_BOUND',
+ '%SQL_GETDATA_EXTENSIONS','%SQL_GET_BOOKMARK','%SQL_GROUP_BY','%SQL_GUID','%SQL_HANDLE_DBC','%SQL_HANDLE_DESC','%SQL_HANDLE_ENV','%SQL_HANDLE_SENV',
+ '%SQL_HANDLE_STMT','%SQL_HOUR','%SQL_HOUR_TO_MINUTE','%SQL_HOUR_TO_SECOND','%SQL_IC_LOWER','%SQL_IC_MIXED','%SQL_IC_SENSITIVE','%SQL_IC_UPPER',
+ '%SQL_IDENTIFIER_CASE','%SQL_IDENTIFIER_QUOTE_CHAR','%SQL_IGNORE','%SQL_IK_ALL','%SQL_IK_ASC','%SQL_IK_DESC','%SQL_IK_NONE','%SQL_INDEX_ALL',
+ '%SQL_INDEX_CLUSTERED','%SQL_INDEX_HASHED','%SQL_INDEX_KEYWORDS','%SQL_INDEX_OTHER','%SQL_INDEX_UNIQUE','%SQL_INFO_FIRST','%SQL_INFO_SCHEMA_VIEWS','%SQL_INITIALLY_DEFERRED',
+ '%SQL_INITIALLY_IMMEDIATE','%SQL_INSENSITIVE','%SQL_INSERT_STATEMENT','%SQL_INTEGER','%SQL_INTEGRITY','%SQL_INTERVAL','%SQL_INTERVAL_DAY','%SQL_INTERVAL_DAY_TO_HOUR',
+ '%SQL_INTERVAL_DAY_TO_MINUTE','%SQL_INTERVAL_DAY_TO_SECOND','%SQL_INTERVAL_HOUR','%SQL_INTERVAL_HOUR_TO_MINUTE','%SQL_INTERVAL_HOUR_TO_SECOND','%SQL_INTERVAL_MINUTE','%SQL_INTERVAL_MINUTE_TO_SECOND','%SQL_INTERVAL_MONTH',
+ '%SQL_INTERVAL_SECOND','%SQL_INTERVAL_YEAR','%SQL_INTERVAL_YEAR_TO_MONTH','%SQL_INVALID_HANDLE','%SQL_ISV_ASSERTIONS','%SQL_ISV_CHARACTER_SETS','%SQL_ISV_CHECK_CONSTRAINTS','%SQL_ISV_COLLATIONS',
+ '%SQL_ISV_COLUMNS','%SQL_ISV_COLUMN_DOMAIN_USAGE','%SQL_ISV_COLUMN_PRIVILEGES','%SQL_ISV_CONSTRAINT_COLUMN_USAGE','%SQL_ISV_CONSTRAINT_TABLE_USAGE','%SQL_ISV_DOMAINS','%SQL_ISV_DOMAIN_CONSTRAINTS','%SQL_ISV_KEY_COLUMN_USAGE',
+ '%SQL_ISV_REFERENTIAL_CONSTRAINTS','%SQL_ISV_SCHEMATA','%SQL_ISV_SQL_LANGUAGES','%SQL_ISV_TABLES','%SQL_ISV_TABLE_CONSTRAINTS','%SQL_ISV_TABLE_PRIVILEGES','%SQL_ISV_TRANSLATIONS','%SQL_ISV_USAGE_PRIVILEGES',
+ '%SQL_ISV_VIEWS','%SQL_ISV_VIEW_COLUMN_USAGE','%SQL_ISV_VIEW_TABLE_USAGE','%SQL_IS_DAY','%SQL_IS_DAY_TO_HOUR','%SQL_IS_DAY_TO_MINUTE','%SQL_IS_DAY_TO_SECOND','%SQL_IS_HOUR',
+ '%SQL_IS_HOUR_TO_MINUTE','%SQL_IS_HOUR_TO_SECOND','%SQL_IS_INSERT_LITERALS','%SQL_IS_INSERT_SEARCHED','%SQL_IS_INTEGER','%SQL_IS_MINUTE','%SQL_IS_MINUTE_TO_SECOND','%SQL_IS_MONTH',
+ '%SQL_IS_POINTER','%SQL_IS_SECOND','%SQL_IS_SELECT_INTO','%SQL_IS_SMALLINT','%SQL_IS_UINTEGER','%SQL_IS_USMALLINT','%SQL_IS_YEAR','%SQL_IS_YEAR_TO_MONTH',
+ '%SQL_KEYSET_CURSOR_ATTRIBUTES1','%SQL_KEYSET_CURSOR_ATTRIBUTES2','%SQL_KEYSET_SIZE','%SQL_KEYSET_SIZE_DEFAULT','%SQL_KEYWORDS','%SQL_LCK_EXCLUSIVE','%SQL_LCK_NO_CHANGE','%SQL_LCK_UNLOCK',
+ '%SQL_LEN_BINARY_ATTR_OFFSET','%SQL_LEN_DATA_AT_EXEC_OFFSET','%SQL_LIKE_ESCAPE_CLAUSE','%SQL_LIKE_ONLY','%SQL_LOCK_EXCLUSIVE','%SQL_LOCK_NO_CHANGE','%SQL_LOCK_TYPES','%SQL_LOCK_UNLOCK',
+ '%SQL_LOGIN_TIMEOUT','%SQL_LOGIN_TIMEOUT_DEFAULT','%SQL_LONGVARBINARY','%SQL_LONGVARCHAR','%SQL_MAXIMUM_CATALOG_NAME_LENGTH','%SQL_MAXIMUM_COLUMNS_IN_GROUP_BY','%SQL_MAXIMUM_COLUMNS_IN_INDEX','%SQL_MAXIMUM_COLUMNS_IN_ORDER_BY',
+ '%SQL_MAXIMUM_COLUMNS_IN_SELECT','%SQL_MAXIMUM_COLUMN_NAME_LENGTH','%SQL_MAXIMUM_CONCURRENT_ACTIVITIES','%SQL_MAXIMUM_CURSOR_NAME_LENGTH','%SQL_MAXIMUM_DRIVER_CONNECTIONS','%SQL_MAXIMUM_IDENTIFIER_LENGTH','%SQL_MAXIMUM_INDEX_SIZE','%SQL_MAXIMUM_ROW_SIZE',
+ '%SQL_MAXIMUM_SCHEMA_NAME_LENGTH','%SQL_MAXIMUM_STATEMENT_LENGTH','%SQL_MAXIMUM_TABLES_IN_SELECT','%SQL_MAXIMUM_USER_NAME_LENGTH','%SQL_MAX_ASYNC_CONCURRENT_STATEMENTS','%SQL_MAX_BINARY_LITERAL_LEN','%SQL_MAX_CATALOG_NAME_LEN','%SQL_MAX_CHAR_LITERAL_LEN',
+ '%SQL_MAX_COLUMNS_IN_GROUP_BY','%SQL_MAX_COLUMNS_IN_INDEX','%SQL_MAX_COLUMNS_IN_ORDER_BY','%SQL_MAX_COLUMNS_IN_SELECT','%SQL_MAX_COLUMNS_IN_TABLE','%SQL_MAX_COLUMN_NAME_LEN','%SQL_MAX_CONCURRENT_ACTIVITIES','%SQL_MAX_CURSOR_NAME_LEN',
+ '%SQL_MAX_DRIVER_CONNECTIONS','%SQL_MAX_DSN_LENGTH','%SQL_MAX_IDENTIFIER_LEN','%SQL_MAX_INDEX_SIZE','%SQL_MAX_LENGTH','%SQL_MAX_LENGTH_DEFAULT','%SQL_MAX_MESSAGE_LENGTH','%SQL_MAX_NUMERIC_LEN',
+ '%SQL_MAX_OPTION_STRING_LENGTH','%SQL_MAX_OWNER_NAME_LEN','%SQL_MAX_PROCEDURE_NAME_LEN','%SQL_MAX_QUALIFIER_NAME_LEN','%SQL_MAX_ROWS','%SQL_MAX_ROWS_DEFAULT','%SQL_MAX_ROW_SIZE','%SQL_MAX_ROW_SIZE_INCLUDES_LONG',
+ '%SQL_MAX_SCHEMA_NAME_LEN','%SQL_MAX_STATEMENT_LEN','%SQL_MAX_TABLES_IN_SELECT','%SQL_MAX_TABLE_NAME_LEN','%SQL_MAX_USER_NAME_LEN','%SQL_MINUTE','%SQL_MINUTE_TO_SECOND','%SQL_MODE_DEFAULT',
+ '%SQL_MODE_READ_ONLY','%SQL_MODE_READ_WRITE','%SQL_MONTH','%SQL_MULTIPLE_ACTIVE_TXN','%SQL_MULT_RESULT_SETS','%SQL_NAMED','%SQL_NC_END','%SQL_NC_HIGH',
+ '%SQL_NC_LOW','%SQL_NC_START','%SQL_NEED_DATA','%SQL_NEED_LONG_DATA_LEN','%SQL_NNC_NON_NULL','%SQL_NNC_NULL','%SQL_NONSCROLLABLE','%SQL_NON_NULLABLE_COLUMNS',
+ '%SQL_NOSCAN','%SQL_NOSCAN_DEFAULT','%SQL_NOSCAN_OFF','%SQL_NOSCAN_ON','%SQL_NOT_DEFERRABLE','%SQL_NO_ACTION','%SQL_NO_COLUMN_NUMBER','%SQL_NO_DATA',
+ '%SQL_NO_DATA_FOUND','%SQL_NO_NULLS','%SQL_NO_ROW_NUMBER','%SQL_NO_TOTAL','%SQL_NTS','%SQL_NTSL','%SQL_NULLABLE','%SQL_NULLABLE_UNKNOWN',
+ '%SQL_NULL_COLLATION','%SQL_NULL_DATA','%SQL_NULL_HANDLE','%SQL_NULL_HDBC','%SQL_NULL_HDESC','%SQL_NULL_HENV','%SQL_NULL_HSTMT','%SQL_NUMERIC',
+ '%SQL_NUMERIC_FUNCTIONS','%SQL_OAC_LEVEL1','%SQL_OAC_LEVEL2','%SQL_OAC_NONE','%SQL_ODBC_API_CONFORMANCE','%SQL_ODBC_CURSORS','%SQL_ODBC_INTERFACE_CONFORMANCE','%SQL_ODBC_SAG_CLI_CONFORMANCE',
+ '%SQL_ODBC_SQL_CONFORMANCE','%SQL_ODBC_SQL_OPT_IEF','%SQL_ODBC_VER','%SQL_OIC_CORE','%SQL_OIC_LEVEL1','%SQL_OIC_LEVEL2','%SQL_OJ_ALL_COMPARISON_OPS','%SQL_OJ_CAPABILITIES',
+ '%SQL_OJ_FULL','%SQL_OJ_INNER','%SQL_OJ_LEFT','%SQL_OJ_NESTED','%SQL_OJ_NOT_ORDERED','%SQL_OJ_RIGHT','%SQL_OPT_TRACE','%SQL_OPT_TRACEFILE',
+ '%SQL_OPT_TRACE_DEFAULT','%SQL_OPT_TRACE_OFF','%SQL_OPT_TRACE_ON','%SQL_ORDER_BY_COLUMNS_IN_SELECT','%SQL_OSCC_COMPLIANT','%SQL_OSCC_NOT_COMPLIANT','%SQL_OSC_CORE','%SQL_OSC_EXTENDED',
+ '%SQL_OSC_MINIMUM','%SQL_OUTER_JOINS','%SQL_OUTER_JOIN_CAPABILITIES','%SQL_OU_DML_STATEMENTS','%SQL_OU_INDEX_DEFINITION','%SQL_OU_PRIVILEGE_DEFINITION','%SQL_OU_PROCEDURE_INVOCATION','%SQL_OU_TABLE_DEFINITION',
+ '%SQL_OV_ODBC2','%SQL_OV_ODBC3','%SQL_OWNER_TERM','%SQL_OWNER_USAGE','%SQL_PACKET_SIZE','%SQL_PARAM_ARRAY_ROW_COUNTS','%SQL_PARAM_ARRAY_SELECTS','%SQL_PARAM_BIND_BY_COLUMN',
+ '%SQL_PARAM_BIND_TYPE_DEFAULT','%SQL_PARAM_DIAG_UNAVAILABLE','%SQL_PARAM_ERROR','%SQL_PARAM_IGNORE','%SQL_PARAM_INPUT','%SQL_PARAM_INPUT_OUTPUT','%SQL_PARAM_OUTPUT','%SQL_PARAM_PROCEED',
+ '%SQL_PARAM_SUCCESS','%SQL_PARAM_SUCCESS_WITH_INFO','%SQL_PARAM_TYPE_DEFAULT','%SQL_PARAM_TYPE_UNKNOWN','%SQL_PARAM_UNUSED','%SQL_PARC_BATCH','%SQL_PARC_NO_BATCH','%SQL_PAS_BATCH',
+ '%SQL_PAS_NO_BATCH','%SQL_PAS_NO_SELECT','%SQL_PC_NON_PSEUDO','%SQL_PC_NOT_PSEUDO','%SQL_PC_PSEUDO','%SQL_PC_UNKNOWN','%SQL_POSITION','%SQL_POSITIONED_STATEMENTS',
+ '%SQL_POS_ADD','%SQL_POS_DELETE','%SQL_POS_OPERATIONS','%SQL_POS_POSITION','%SQL_POS_REFRESH','%SQL_POS_UPDATE','%SQL_PRED_BASIC','%SQL_PRED_CHAR',
+ '%SQL_PRED_NONE','%SQL_PRED_SEARCHABLE','%SQL_PROCEDURES','%SQL_PROCEDURE_TERM','%SQL_PS_POSITIONED_DELETE','%SQL_PS_POSITIONED_UPDATE','%SQL_PS_SELECT_FOR_UPDATE','%SQL_PT_FUNCTION',
+ '%SQL_PT_PROCEDURE','%SQL_PT_UNKNOWN','%SQL_QL_END','%SQL_QL_START','%SQL_QUALIFIER_LOCATION','%SQL_QUALIFIER_NAME_SEPARATOR','%SQL_QUALIFIER_TERM','%SQL_QUALIFIER_USAGE',
+ '%SQL_QUERY_TIMEOUT','%SQL_QUERY_TIMEOUT_DEFAULT','%SQL_QUICK','%SQL_QUIET_MODE','%SQL_QUOTED_IDENTIFIER_CASE','%SQL_QU_DML_STATEMENTS','%SQL_QU_INDEX_DEFINITION','%SQL_QU_PRIVILEGE_DEFINITION',
+ '%SQL_QU_PROCEDURE_INVOCATION','%SQL_QU_TABLE_DEFINITION','%SQL_RD_DEFAULT','%SQL_RD_OFF','%SQL_RD_ON','%SQL_REAL','%SQL_REFRESH','%SQL_RESET_PARAMS',
+ '%SQL_RESTRICT','%SQL_RESULT_COL','%SQL_RETRIEVE_DATA','%SQL_RETURN_VALUE','%SQL_ROLLBACK','%SQL_ROWSET_SIZE','%SQL_ROWSET_SIZE_DEFAULT','%SQL_ROWVER',
+ '%SQL_ROW_ADDED','%SQL_ROW_DELETED','%SQL_ROW_ERROR','%SQL_ROW_IDENTIFIER','%SQL_ROW_IGNORE','%SQL_ROW_NOROW','%SQL_ROW_NUMBER','%SQL_ROW_NUMBER_UNKNOWN',
+ '%SQL_ROW_PROCEED','%SQL_ROW_SUCCESS','%SQL_ROW_SUCCESS_WITH_INFO','%SQL_ROW_UPDATED','%SQL_ROW_UPDATES','%SQL_SCCO_LOCK','%SQL_SCCO_OPT_ROWVER','%SQL_SCCO_OPT_TIMESTAMP',
+ '%SQL_SCCO_OPT_VALUES','%SQL_SCCO_READ_ONLY','%SQL_SCC_ISO92_CLI','%SQL_SCC_XOPEN_CLI_VERSION1','%SQL_SCHEMA_TERM','%SQL_SCHEMA_USAGE','%SQL_SCOPE_CURROW','%SQL_SCOPE_SESSION',
+ '%SQL_SCOPE_TRANSACTION','%SQL_SCROLLABLE','%SQL_SCROLL_CONCURRENCY','%SQL_SCROLL_DYNAMIC','%SQL_SCROLL_FORWARD_ONLY','%SQL_SCROLL_KEYSET_DRIVEN','%SQL_SCROLL_OPTIONS','%SQL_SCROLL_STATIC',
+ '%SQL_SC_FIPS127_2_TRANSITIONAL','%SQL_SC_NON_UNIQUE','%SQL_SC_SQL92_ENTRY','%SQL_SC_SQL92_FULL','%SQL_SC_SQL92_INTERMEDIATE','%SQL_SC_TRY_UNIQUE','%SQL_SC_UNIQUE','%SQL_SDF_CURRENT_DATE',
+ '%SQL_SDF_CURRENT_TIME','%SQL_SDF_CURRENT_TIMESTAMP','%SQL_SEARCHABLE','%SQL_SEARCH_PATTERN_ESCAPE','%SQL_SECOND','%SQL_SENSITIVE','%SQL_SERVER_NAME','%SQL_SETPARAM_VALUE_MAX',
+ '%SQL_SETPOS_MAX_LOCK_VALUE','%SQL_SETPOS_MAX_OPTION_VALUE','%SQL_SET_DEFAULT','%SQL_SET_NULL','%SQL_SFKD_CASCADE','%SQL_SFKD_NO_ACTION','%SQL_SFKD_SET_DEFAULT','%SQL_SFKD_SET_NULL',
+ '%SQL_SFKU_CASCADE','%SQL_SFKU_NO_ACTION','%SQL_SFKU_SET_DEFAULT','%SQL_SFKU_SET_NULL','%SQL_SG_DELETE_TABLE','%SQL_SG_INSERT_COLUMN','%SQL_SG_INSERT_TABLE','%SQL_SG_REFERENCES_COLUMN',
+ '%SQL_SG_REFERENCES_TABLE','%SQL_SG_SELECT_TABLE','%SQL_SG_UPDATE_COLUMN','%SQL_SG_UPDATE_TABLE','%SQL_SG_USAGE_ON_CHARACTER_SET','%SQL_SG_USAGE_ON_COLLATION','%SQL_SG_USAGE_ON_DOMAIN','%SQL_SG_USAGE_ON_TRANSLATION',
+ '%SQL_SG_WITH_GRANT_OPTION','%SQL_SIGNED_OFFSET','%SQL_SIMULATE_CURSOR','%SQL_SMALLINT','%SQL_SNVF_BIT_LENGTH','%SQL_SNVF_CHARACTER_LENGTH','%SQL_SNVF_CHAR_LENGTH','%SQL_SNVF_EXTRACT',
+ '%SQL_SNVF_OCTET_LENGTH','%SQL_SNVF_POSITION','%SQL_SO_DYNAMIC','%SQL_SO_FORWARD_ONLY','%SQL_SO_KEYSET_DRIVEN','%SQL_SO_MIXED','%SQL_SO_STATIC','%SQL_SPECIAL_CHARACTERS',
+ '%SQL_SPEC_MAJOR','%SQL_SPEC_MINOR','%SQL_SP_BETWEEN','%SQL_SP_COMPARISON','%SQL_SP_EXISTS','%SQL_SP_IN','%SQL_SP_ISNOTNULL','%SQL_SP_ISNULL',
+ '%SQL_SP_LIKE','%SQL_SP_MATCH_FULL','%SQL_SP_MATCH_PARTIAL','%SQL_SP_MATCH_UNIQUE_FULL','%SQL_SP_MATCH_UNIQUE_PARTIAL','%SQL_SP_OVERLAPS','%SQL_SP_QUANTIFIED_COMPARISON','%SQL_SP_UNIQUE',
+ '%SQL_SQL92_DATETIME_FUNCTIONS','%SQL_SQL92_FOREIGN_KEY_DELETE_RULE','%SQL_SQL92_FOREIGN_KEY_UPDATE_RULE','%SQL_SQL92_GRANT','%SQL_SQL92_NUMERIC_VALUE_FUNCTIONS','%SQL_SQL92_PREDICATES','%SQL_SQL92_RELATIONAL_JOIN_OPERATORS','%SQL_SQL92_REVOKE',
+ '%SQL_SQL92_ROW_VALUE_CONSTRUCTOR','%SQL_SQL92_STRING_FUNCTIONS','%SQL_SQL92_VALUE_EXPRESSIONS','%SQL_SQLSTATE_SIZE','%SQL_SQL_CONFORMANCE','%SQL_SQ_COMPARISON','%SQL_SQ_CORRELATED_SUBQUERIES','%SQL_SQ_EXISTS',
+ '%SQL_SQ_IN','%SQL_SQ_QUANTIFIED','%SQL_SRJO_CORRESPONDING_CLAUSE','%SQL_SRJO_CROSS_JOIN','%SQL_SRJO_EXCEPT_JOIN','%SQL_SRJO_FULL_OUTER_JOIN','%SQL_SRJO_INNER_JOIN','%SQL_SRJO_INTERSECT_JOIN',
+ '%SQL_SRJO_LEFT_OUTER_JOIN','%SQL_SRJO_NATURAL_JOIN','%SQL_SRJO_RIGHT_OUTER_JOIN','%SQL_SRJO_UNION_JOIN','%SQL_SRVC_DEFAULT','%SQL_SRVC_NULL','%SQL_SRVC_ROW_SUBQUERY','%SQL_SRVC_VALUE_EXPRESSION',
+ '%SQL_SR_CASCADE','%SQL_SR_DELETE_TABLE','%SQL_SR_GRANT_OPTION_FOR','%SQL_SR_INSERT_COLUMN','%SQL_SR_INSERT_TABLE','%SQL_SR_REFERENCES_COLUMN','%SQL_SR_REFERENCES_TABLE','%SQL_SR_RESTRICT',
+ '%SQL_SR_SELECT_TABLE','%SQL_SR_UPDATE_COLUMN','%SQL_SR_UPDATE_TABLE','%SQL_SR_USAGE_ON_CHARACTER_SET','%SQL_SR_USAGE_ON_COLLATION','%SQL_SR_USAGE_ON_DOMAIN','%SQL_SR_USAGE_ON_TRANSLATION','%SQL_SSF_CONVERT',
+ '%SQL_SSF_LOWER','%SQL_SSF_SUBSTRING','%SQL_SSF_TRANSLATE','%SQL_SSF_TRIM_BOTH','%SQL_SSF_TRIM_LEADING','%SQL_SSF_TRIM_TRAILING','%SQL_SSF_UPPER','%SQL_SS_ADDITIONS',
+ '%SQL_SS_DELETIONS','%SQL_SS_UPDATES','%SQL_STANDARD_CLI_CONFORMANCE','%SQL_STATIC_CURSOR_ATTRIBUTES1','%SQL_STATIC_CURSOR_ATTRIBUTES2','%SQL_STATIC_SENSITIVITY','%SQL_STILL_EXECUTING','%SQL_STRING_FUNCTIONS',
+ '%SQL_SUBQUERIES','%SQL_SUCCESS','%SQL_SUCCESS_WITH_INFO','%SQL_SU_DML_STATEMENTS','%SQL_SU_INDEX_DEFINITION','%SQL_SU_PRIVILEGE_DEFINITION','%SQL_SU_PROCEDURE_INVOCATION','%SQL_SU_TABLE_DEFINITION',
+ '%SQL_SVE_CASE','%SQL_SVE_CAST','%SQL_SVE_COALESCE','%SQL_SVE_NULLIF','%SQL_SYSTEM_FUNCTIONS','%SQL_TABLE_STAT','%SQL_TABLE_TERM','%SQL_TC_ALL',
+ '%SQL_TC_DDL_COMMIT','%SQL_TC_DDL_IGNORE','%SQL_TC_DML','%SQL_TC_NONE','%SQL_TIME','%SQL_TIMEDATE_ADD_INTERVALS','%SQL_TIMEDATE_DIFF_INTERVALS','%SQL_TIMEDATE_FUNCTIONS',
+ '%SQL_TIMESTAMP','%SQL_TIMESTAMP_LEN','%SQL_TIME_LEN','%SQL_TINYINT','%SQL_TRANSACTION_CAPABLE','%SQL_TRANSACTION_ISOLATION_OPTION','%SQL_TRANSACTION_READ_COMMITTED','%SQL_TRANSACTION_READ_UNCOMMITTED',
+ '%SQL_TRANSACTION_REPEATABLE_READ','%SQL_TRANSACTION_SERIALIZABLE','%SQL_TRANSLATE_DLL','%SQL_TRANSLATE_OPTION','%SQL_TRUE','%SQL_TXN_CAPABLE','%SQL_TXN_ISOLATION','%SQL_TXN_ISOLATION_OPTION',
+ '%SQL_TXN_READ_COMMITTED','%SQL_TXN_READ_UNCOMMITTED','%SQL_TXN_REPEATABLE_READ','%SQL_TXN_SERIALIZABLE','%SQL_TYPE_DATE','%SQL_TYPE_NULL','%SQL_TYPE_TIME','%SQL_TYPE_TIMESTAMP',
+ '%SQL_UB_DEFAULT','%SQL_UB_FIXED','%SQL_UB_OFF','%SQL_UB_ON','%SQL_UB_VARIABLE','%SQL_UNBIND','%SQL_UNICODE','%SQL_UNICODE_CHAR',
+ '%SQL_UNICODE_LONGVARCHAR','%SQL_UNICODE_VARCHAR','%SQL_UNION','%SQL_UNION_STATEMENT','%SQL_UNKNOWN_TYPE','%SQL_UNNAMED','%SQL_UNSEARCHABLE','%SQL_UNSIGNED_OFFSET',
+ '%SQL_UNSPECIFIED','%SQL_UPDATE','%SQL_UPDATE_BY_BOOKMARK','%SQL_USER_NAME','%SQL_USE_BOOKMARKS','%SQL_US_UNION','%SQL_US_UNION_ALL','%SQL_U_UNION',
+ '%SQL_U_UNION_ALL','%SQL_VARBINARY','%SQL_VARCHAR','%SQL_XOPEN_CLI_YEAR','%SQL_YEAR','%SQL_YEAR_TO_MONTH','%SRCCOPY','%SS_BITMAP',
+ '%SS_BLACKFRAME','%SS_BLACKRECT','%SS_CENTER','%SS_CENTERIMAGE','%SS_ENDELLIPSIS','%SS_ETCHEDFRAME','%SS_ETCHEDHORZ','%SS_ETCHEDVERT',
+ '%SS_GRAYFRAME','%SS_GRAYRECT','%SS_LEFT','%SS_NOPREFIX','%SS_NOTIFY','%SS_NOWORDWRAP','%SS_PATHELLIPSIS','%SS_RIGHT',
+ '%SS_RIGHTJUST','%SS_SIMPLE','%SS_SUNKEN','%SS_WHITEFRAME','%SS_WHITERECT','%SS_WORDELLIPSIS','%STAT_FILL_FROM_MEMORY','%STAT_FILL_NATURAL',
+ '%STAT_FILL_NATURAL_ERASTONE','%STAT_FILL_NATURAL_EVEN','%STAT_FILL_NATURAL_FIBONACCI','%STAT_FILL_NATURAL_ODD','%STAT_FILL_WITH_NUMBER','%STAT_MINMAX_INDEX','%STAT_MINMAX_VALUE','%STAT_TYPE_BYTE',
+ '%STAT_TYPE_CURRENCY','%STAT_TYPE_DOUBLE','%STAT_TYPE_DWORD','%STAT_TYPE_EXT','%STAT_TYPE_INTEGER','%STAT_TYPE_LONG','%STAT_TYPE_QUAD','%STAT_TYPE_SINGLE',
+ '%STAT_TYPE_WORD','%SWP_ASYNCWINDOWPOS','%SWP_DEFERERASE','%SWP_DRAWFRAME','%SWP_FRAMECHANGED','%SWP_HIDEWINDOW','%SWP_NOACTIVATE','%SWP_NOCOPYBITS',
+ '%SWP_NOMOVE','%SWP_NOOWNERZORDER','%SWP_NOREDRAW','%SWP_NOREPOSITION','%SWP_NOSENDCHANGING','%SWP_NOSIZE','%SWP_NOZORDER','%SWP_SHOWWINDOW',
+ '%SW_FORCEMINIMIZE','%SW_HIDE','%SW_MAXIMIZE','%SW_MINIMIZE','%SW_NORMAL','%SW_RESTORE','%SW_SHOW','%SW_SHOWDEFAULT',
+ '%SW_SHOWMAXIMIZED','%SW_SHOWMINIMIZED','%SW_SHOWMINNOACTIVE','%SW_SHOWNA','%SW_SHOWNOACTIVATE','%SW_SHOWNORMAL','%TBASS_3DALG_DEFAULT','%TBASS_3DALG_FULL',
+ '%TBASS_3DALG_LIGHT','%TBASS_3DALG_OFF','%TBASS_3DMODE_NORMAL','%TBASS_3DMODE_OFF','%TBASS_3DMODE_RELATIVE','%TBASS_ACTIVE_PAUSED','%TBASS_ACTIVE_PLAYING','%TBASS_ACTIVE_STALLED',
+ '%TBASS_ACTIVE_STOPPED','%TBASS_CONFIG_3DALGORITHM','%TBASS_CONFIG_BUFFER','%TBASS_CONFIG_CURVE_PAN','%TBASS_CONFIG_CURVE_VOL','%TBASS_CONFIG_FLOATDSP','%TBASS_CONFIG_GVOL_MUSIC','%TBASS_CONFIG_GVOL_SAMPLE',
+ '%TBASS_CONFIG_GVOL_STREAM','%TBASS_CONFIG_MAXVOL','%TBASS_CONFIG_MP3_CODEC','%TBASS_CONFIG_NET_AGENT','%TBASS_CONFIG_NET_BUFFER','%TBASS_CONFIG_NET_PASSIVE','%TBASS_CONFIG_NET_PREBUF','%TBASS_CONFIG_NET_PROXY',
+ '%TBASS_CONFIG_NET_TIMEOUT','%TBASS_CONFIG_PAUSE_NOPLAY','%TBASS_CONFIG_UPDATEPERIOD','%TBASS_CTYPE_MUSIC_IT','%TBASS_CTYPE_MUSIC_MO3','%TBASS_CTYPE_MUSIC_MOD','%TBASS_CTYPE_MUSIC_MTM','%TBASS_CTYPE_MUSIC_S3M',
+ '%TBASS_CTYPE_MUSIC_XM','%TBASS_CTYPE_RECORD','%TBASS_CTYPE_SAMPLE','%TBASS_CTYPE_STREAM','%TBASS_CTYPE_STREAM_AIFF','%TBASS_CTYPE_STREAM_MP1','%TBASS_CTYPE_STREAM_MP2','%TBASS_CTYPE_STREAM_MP3',
+ '%TBASS_CTYPE_STREAM_OGG','%TBASS_CTYPE_STREAM_WAV','%TBASS_CTYPE_STREAM_WAV_FLOAT','%TBASS_CTYPE_STREAM_WAV_PCM','%TBASS_DATA_AVAILABLE','%TBASS_DATA_FFT1024','%TBASS_DATA_FFT2048','%TBASS_DATA_FFT4096',
+ '%TBASS_DATA_FFT512','%TBASS_DATA_FFT_INDIVIDUAL','%TBASS_DATA_FFT_NOWINDOW','%TBASS_DATA_FLOAT','%TBASS_DEVICE_3D','%TBASS_DEVICE_8BITS','%TBASS_DEVICE_LATENCY','%TBASS_DEVICE_MONO',
+ '%TBASS_DEVICE_NOSPEAKER','%TBASS_DEVICE_SPEAKERS','%TBASS_EAX_ENVIRONMENT_ALLEY','%TBASS_EAX_ENVIRONMENT_ARENA','%TBASS_EAX_ENVIRONMENT_AUDITORIUM','%TBASS_EAX_ENVIRONMENT_BATHROOM','%TBASS_EAX_ENVIRONMENT_CARPETEDHALLWAY','%TBASS_EAX_ENVIRONMENT_CAVE',
+ '%TBASS_EAX_ENVIRONMENT_CITY','%TBASS_EAX_ENVIRONMENT_CONCERTHALL','%TBASS_EAX_ENVIRONMENT_COUNT','%TBASS_EAX_ENVIRONMENT_DIZZY','%TBASS_EAX_ENVIRONMENT_DRUGGED','%TBASS_EAX_ENVIRONMENT_FOREST','%TBASS_EAX_ENVIRONMENT_GENERIC','%TBASS_EAX_ENVIRONMENT_HALLWAY',
+ '%TBASS_EAX_ENVIRONMENT_HANGAR','%TBASS_EAX_ENVIRONMENT_LIVINGROOM','%TBASS_EAX_ENVIRONMENT_MOUNTAINS','%TBASS_EAX_ENVIRONMENT_PADDEDCELL','%TBASS_EAX_ENVIRONMENT_PARKINGLOT','%TBASS_EAX_ENVIRONMENT_PLAIN','%TBASS_EAX_ENVIRONMENT_PSYCHOTIC','%TBASS_EAX_ENVIRONMENT_QUARRY',
+ '%TBASS_EAX_ENVIRONMENT_ROOM','%TBASS_EAX_ENVIRONMENT_SEWERPIPE','%TBASS_EAX_ENVIRONMENT_STONECORRIDOR','%TBASS_EAX_ENVIRONMENT_STONEROOM','%TBASS_EAX_ENVIRONMENT_UNDERWATER','%TBASS_ERROR_ALREADY','%TBASS_ERROR_BUFLOST','%TBASS_ERROR_CODEC',
+ '%TBASS_ERROR_CREATE','%TBASS_ERROR_DECODE','%TBASS_ERROR_DEVICE','%TBASS_ERROR_DRIVER','%TBASS_ERROR_DX','%TBASS_ERROR_EMPTY','%TBASS_ERROR_FILEFORM','%TBASS_ERROR_FILEOPEN',
+ '%TBASS_ERROR_FORMAT','%TBASS_ERROR_FREQ','%TBASS_ERROR_HANDLE','%TBASS_ERROR_ILLPARAM','%TBASS_ERROR_ILLTYPE','%TBASS_ERROR_INIT','%TBASS_ERROR_MEM','%TBASS_ERROR_NO3D',
+ '%TBASS_ERROR_NOCHAN','%TBASS_ERROR_NOEAX','%TBASS_ERROR_NOFX','%TBASS_ERROR_NOHW','%TBASS_ERROR_NONET','%TBASS_ERROR_NOPAUSE','%TBASS_ERROR_NOPLAY','%TBASS_ERROR_NOTAVAIL',
+ '%TBASS_ERROR_NOTFILE','%TBASS_ERROR_PLAYING','%TBASS_ERROR_POSITION','%TBASS_ERROR_SPEAKER','%TBASS_ERROR_START','%TBASS_ERROR_TIMEOUT','%TBASS_ERROR_UNKNOWN','%TBASS_ERROR_VERSION',
+ '%TBASS_FALSE','%TBASS_FILEPOS_CURRENT','%TBASS_FILEPOS_DECODE','%TBASS_FILEPOS_DOWNLOAD','%TBASS_FILEPOS_END','%TBASS_FILEPOS_START','%TBASS_FILE_CLOSE','%TBASS_FILE_LEN',
+ '%TBASS_FILE_READ','%TBASS_FILE_SEEK','%TBASS_FX_CHORUS','%TBASS_FX_COMPRESSOR','%TBASS_FX_DISTORTION','%TBASS_FX_ECHO','%TBASS_FX_FLANGER','%TBASS_FX_GARGLE',
+ '%TBASS_FX_I3DL2REVERB','%TBASS_FX_PARAMEQ','%TBASS_FX_PHASE_180','%TBASS_FX_PHASE_90','%TBASS_FX_PHASE_NEG_180','%TBASS_FX_PHASE_NEG_90','%TBASS_FX_PHASE_ZERO','%TBASS_FX_REVERB',
+ '%TBASS_INPUT_LEVEL','%TBASS_INPUT_OFF','%TBASS_INPUT_ON','%TBASS_INPUT_TYPE_ANALOG','%TBASS_INPUT_TYPE_AUX','%TBASS_INPUT_TYPE_CD','%TBASS_INPUT_TYPE_DIGITAL','%TBASS_INPUT_TYPE_LINE',
+ '%TBASS_INPUT_TYPE_MASK','%TBASS_INPUT_TYPE_MIC','%TBASS_INPUT_TYPE_PHONE','%TBASS_INPUT_TYPE_SPEAKER','%TBASS_INPUT_TYPE_SYNTH','%TBASS_INPUT_TYPE_UNDEF','%TBASS_INPUT_TYPE_WAVE','%TBASS_MP3_SETPOS',
+ '%TBASS_MUSIC_3D','%TBASS_MUSIC_ATTRIB_AMPLIFY','%TBASS_MUSIC_ATTRIB_BPM','%TBASS_MUSIC_ATTRIB_PANSEP','%TBASS_MUSIC_ATTRIB_PSCALER','%TBASS_MUSIC_ATTRIB_SPEED','%TBASS_MUSIC_ATTRIB_VOL_CHAN','%TBASS_MUSIC_ATTRIB_VOL_GLOBAL',
+ '%TBASS_MUSIC_ATTRIB_VOL_INST','%TBASS_MUSIC_AUTOFREE','%TBASS_MUSIC_CALCLEN','%TBASS_MUSIC_DECODE','%TBASS_MUSIC_FLOAT','%TBASS_MUSIC_FT2MOD','%TBASS_MUSIC_FX','%TBASS_MUSIC_LOOP',
+ '%TBASS_MUSIC_MONO','%TBASS_MUSIC_NONINTER','%TBASS_MUSIC_NOSAMPLE','%TBASS_MUSIC_POSRESET','%TBASS_MUSIC_POSRESETEX','%TBASS_MUSIC_PRESCAN','%TBASS_MUSIC_PT1MOD','%TBASS_MUSIC_RAMP',
+ '%TBASS_MUSIC_RAMPS','%TBASS_MUSIC_STOPBACK','%TBASS_MUSIC_SURROUND','%TBASS_MUSIC_SURROUND2','%TBASS_OBJECT_DS','%TBASS_OBJECT_DS3DL','%TBASS_OK','%TBASS_RECORD_PAUSE',
+ '%TBASS_SAMPLE_3D','%TBASS_SAMPLE_8BITS','%TBASS_SAMPLE_FLOAT','%TBASS_SAMPLE_FX','%TBASS_SAMPLE_LOOP','%TBASS_SAMPLE_MONO','%TBASS_SAMPLE_MUTEMAX','%TBASS_SAMPLE_OVER_DIST',
+ '%TBASS_SAMPLE_OVER_POS','%TBASS_SAMPLE_OVER_VOL','%TBASS_SAMPLE_SOFTWARE','%TBASS_SAMPLE_VAM','%TBASS_SLIDE_FREQ','%TBASS_SLIDE_PAN','%TBASS_SLIDE_VOL','%TBASS_SPEAKER_CENLFE',
+ '%TBASS_SPEAKER_CENTER','%TBASS_SPEAKER_FRONT','%TBASS_SPEAKER_FRONTLEFT','%TBASS_SPEAKER_FRONTRIGHT','%TBASS_SPEAKER_LEFT','%TBASS_SPEAKER_LFE','%TBASS_SPEAKER_REAR','%TBASS_SPEAKER_REAR2',
+ '%TBASS_SPEAKER_REAR2LEFT','%TBASS_SPEAKER_REAR2RIGHT','%TBASS_SPEAKER_REARLEFT','%TBASS_SPEAKER_REARRIGHT','%TBASS_SPEAKER_RIGHT','%TBASS_STREAMPROC_END','%TBASS_STREAM_AUTOFREE','%TBASS_STREAM_BLOCK',
+ '%TBASS_STREAM_DECODE','%TBASS_STREAM_PRESCAN','%TBASS_STREAM_RESTRATE','%TBASS_STREAM_STATUS','%TBASS_SYNC_DOWNLOAD','%TBASS_SYNC_END','%TBASS_SYNC_FREE','%TBASS_SYNC_MESSAGE',
+ '%TBASS_SYNC_META','%TBASS_SYNC_MIXTIME','%TBASS_SYNC_MUSICFX','%TBASS_SYNC_MUSICINST','%TBASS_SYNC_MUSICPOS','%TBASS_SYNC_ONETIME','%TBASS_SYNC_POS','%TBASS_SYNC_SLIDE',
+ '%TBASS_SYNC_STALL','%TBASS_TAG_HTTP','%TBASS_TAG_ICY','%TBASS_TAG_ID3','%TBASS_TAG_ID3V2','%TBASS_TAG_META','%TBASS_TAG_MUSIC_INST','%TBASS_TAG_MUSIC_MESSAGE',
+ '%TBASS_TAG_MUSIC_NAME','%TBASS_TAG_MUSIC_SAMPLE','%TBASS_TAG_OGG','%TBASS_TAG_RIFF_INFO','%TBASS_TAG_VENDOR','%TBASS_TRUE','%TBASS_UNICODE','%TBASS_VAM_HARDWARE',
+ '%TBASS_VAM_SOFTWARE','%TBASS_VAM_TERM_DIST','%TBASS_VAM_TERM_PRIO','%TBASS_VAM_TERM_TIME','%TBASS_VERSION','%TBCD_CHANNEL','%TBCD_THUMB','%TBCD_TICS',
+ '%TBGL_ALIGN_CENTER','%TBGL_ALIGN_CENTER_CENTER','%TBGL_ALIGN_CENTER_DOWN','%TBGL_ALIGN_CENTER_UP','%TBGL_ALIGN_LEFT','%TBGL_ALIGN_LEFT_CENTER','%TBGL_ALIGN_LEFT_DOWN','%TBGL_ALIGN_LEFT_UP',
+ '%TBGL_ALIGN_RIGHT','%TBGL_ALIGN_RIGHT_CENTER','%TBGL_ALIGN_RIGHT_DOWN','%TBGL_ALIGN_RIGHT_UP','%TBGL_ALWAYS','%TBGL_EQUAL','%TBGL_ERROR_FILE','%TBGL_ERROR_MSGBOX',
+ '%TBGL_ERROR_NONE','%TBGL_GEQUAL','%TBGL_GREATER','%TBGL_LEQUAL','%TBGL_LESS','%TBGL_LIGHT_AMBIENT','%TBGL_LIGHT_CONSTANT_ATTENUATION','%TBGL_LIGHT_DIFFUSE',
+ '%TBGL_LIGHT_LINEAR_ATTENUATION','%TBGL_LIGHT_POSITION','%TBGL_LIGHT_QUADRATIC_ATTENUATION','%TBGL_LIGHT_SPECULAR','%TBGL_LIGHT_SPOT_CUTOFF','%TBGL_LIGHT_SPOT_DIRECTION','%TBGL_LIGHT_SPOT_EXPONENT','%TBGL_M15B',
+ '%TBGL_M15G','%TBGL_M15LAYER','%TBGL_M15PSTOP','%TBGL_M15R','%TBGL_M15TEXN','%TBGL_M15TEXX','%TBGL_M15TEXY','%TBGL_M15X',
+ '%TBGL_M15Y','%TBGL_M15Z','%TBGL_NEVER','%TBGL_NORMAL_NONE','%TBGL_NORMAL_PRECISE','%TBGL_NORMAL_SMOOTH','%TBGL_NOTEQUAL','%TBGL_OBJ_CUBE',
+ '%TBGL_OBJ_CUBE3','%TBGL_OBJ_CYLINDER','%TBGL_OBJ_SPHERE','%TBGL_PINFO_RGB','%TBGL_PINFO_XYZ','%TBGL_TEX_LINEAR','%TBGL_TEX_MIPMAP','%TBGL_TEX_NEAREST',
+ '%TBM_CLEARSEL','%TBM_CLEARTICS','%TBM_GETBUDDY','%TBM_GETCHANNELRECT','%TBM_GETLINESIZE','%TBM_GETNUMTICS','%TBM_GETPAGESIZE','%TBM_GETPOS',
+ '%TBM_GETPTICS','%TBM_GETRANGEMAX','%TBM_GETRANGEMIN','%TBM_GETSELEND','%TBM_GETSELSTART','%TBM_GETTHUMBLENGTH','%TBM_GETTHUMBRECT','%TBM_GETTIC',
+ '%TBM_GETTICPOS','%TBM_GETTOOLTIPS','%TBM_GETUNICODEFORMAT','%TBM_SETBUDDY','%TBM_SETLINESIZE','%TBM_SETPAGESIZE','%TBM_SETPOS','%TBM_SETRANGE',
+ '%TBM_SETRANGEMAX','%TBM_SETRANGEMIN','%TBM_SETSEL','%TBM_SETSELEND','%TBM_SETSELSTART','%TBM_SETTHUMBLENGTH','%TBM_SETTIC','%TBM_SETTICFREQ',
+ '%TBM_SETTIPSIDE','%TBM_SETTOOLTIPS','%TBM_SETUNICODEFORMAT','%TBS_AUTOTICKS','%TBS_BOTH','%TBS_BOTTOM','%TBS_DOWNISLEFT','%TBS_ENABLESELRANGE',
+ '%TBS_FIXEDLENGTH','%TBS_HORZ','%TBS_LEFT','%TBS_NOTHUMB','%TBS_NOTICKS','%TBS_REVERSED','%TBS_RIGHT','%TBS_TOOLTIPS',
+ '%TBS_TOP','%TBS_VERT','%TBTS_BOTTOM','%TBTS_LEFT','%TBTS_RIGHT','%TBTS_TOP','%TB_%VT_BSTR','%TB_%VT_CY',
+ '%TB_%VT_DATE','%TB_%VT_EMPTY','%TB_%VT_I2','%TB_%VT_I4','%TB_%VT_NULL','%TB_%VT_R4','%TB_%VT_R8','%TB_BOTTOM',
+ '%TB_CLASS_E_NOAGGREGATION','%TB_CO_E_CLASSSTRING','%TB_DISPATCH_METHOD','%TB_DISPATCH_PROPERTYGET','%TB_DISPATCH_PROPERTYPUT','%TB_DISPATCH_PROPERTYPUTREF','%TB_ENDTRACK','%TB_E_INVALIDARG',
+ '%TB_E_NOINTERFACE','%TB_E_OUTOFMEMORY','%TB_IMGCTX_ACTUALSIZE','%TB_IMGCTX_AUTOSIZE','%TB_IMGCTX_FITTOHEIGHT','%TB_IMGCTX_FITTOWIDTH','%TB_IMGCTX_STRETCH','%TB_LINEDOWN',
+ '%TB_LINEUP','%TB_MK_E_CONNECTMANUALLY','%TB_MK_E_EXCEEDEDDEADLINE','%TB_MK_E_INTERMEDIATEINTERFACENOTSUPPORTED','%TB_MK_E_NOOBJECT','%TB_MK_E_SYNTAX','%TB_PAGEDOWN','%TB_PAGEUP',
+ '%TB_REGDB_E_CLASSNOTREG','%TB_REGDB_E_WRITEREGDB','%TB_SIZEOF_TBVARIANT','%TB_S_FALSE','%TB_S_OK','%TB_THUMBPOSITION','%TB_THUMBTRACK','%TB_TOP',
+ '%TCM_FIRST','%TCM_GETCURSEL','%TCN_FOCUSCHANGE','%TCN_GETOBJECT','%TCN_SELCHANGE','%TCN_SELCHANGING','%TCS_BOTTOM','%TCS_BUTTONS',
+ '%TCS_EX_FLATSEPARATORS','%TCS_EX_REGISTERDROP','%TCS_FIXEDWIDTH','%TCS_FLATBUTTONS','%TCS_FOCUSNEVER','%TCS_FOCUSONBUTTONDOWN','%TCS_FORCEICONLEFT','%TCS_FORCELABELLEFT',
+ '%TCS_HOTTRACK','%TCS_MULTILINE','%TCS_MULTISELECT','%TCS_OWNERDRAWFIXED','%TCS_RAGGEDRIGHT','%TCS_RIGHT','%TCS_RIGHTJUSTIFY','%TCS_SCROLLOPPOSITE',
+ '%TCS_SINGLELINE','%TCS_TABS','%TCS_TOOLTIPS','%TCS_VERTICAL','%TM_PLAINTEXT','%TM_RICHTEXT','%TOKENIZER_DEFAULT_ALPHA','%TOKENIZER_DEFAULT_DELIM',
+ '%TOKENIZER_DEFAULT_DQUOTE','%TOKENIZER_DEFAULT_NEWLINE','%TOKENIZER_DEFAULT_NUMERIC','%TOKENIZER_DEFAULT_SPACE','%TOKENIZER_DELIMITER','%TOKENIZER_EOL','%TOKENIZER_ERROR','%TOKENIZER_FINISHED',
+ '%TOKENIZER_NUMBER','%TOKENIZER_QUOTE','%TOKENIZER_STRING','%TOKENIZER_UNDEFTOK','%TRUE','%TV_FIRST','%UDM_GETACCEL','%UDM_GETBASE',
+ '%UDM_GETBUDDY','%UDM_GETPOS','%UDM_GETPOS32','%UDM_GETRANGE','%UDM_GETRANGE32','%UDM_GETUNICODEFORMAT','%UDM_SETACCEL','%UDM_SETBASE',
+ '%UDM_SETBUDDY','%UDM_SETPOS','%UDM_SETPOS32','%UDM_SETRANGE','%UDM_SETRANGE32','%UDM_SETUNICODEFORMAT','%UDS_ALIGNLEFT','%UDS_ALIGNRIGHT',
+ '%UDS_ARROWKEYS','%UDS_AUTOBUDDY','%UDS_HORZ','%UDS_HOTTRACK','%UDS_NOTHOUSANDS','%UDS_SETBUDDYINT','%UDS_WRAP','%UD_MAXVAL',
+ '%UD_MINVAL','%VK_0','%VK_1','%VK_2','%VK_3','%VK_4','%VK_5','%VK_6',
+ '%VK_7','%VK_8','%VK_9','%VK_A','%VK_ACCEPT','%VK_ADD','%VK_APPS','%VK_B',
+ '%VK_BACK','%VK_C','%VK_CANCEL','%VK_CAPITAL','%VK_CLEAR','%VK_CONTROL','%VK_CONVERT','%VK_D',
+ '%VK_DECIMAL','%VK_DELETE','%VK_DIVIDE','%VK_DOWN','%VK_E','%VK_END','%VK_ESCAPE','%VK_EXECUTE',
+ '%VK_F','%VK_F1','%VK_F10','%VK_F11','%VK_F12','%VK_F13','%VK_F14','%VK_F15',
+ '%VK_F16','%VK_F17','%VK_F18','%VK_F19','%VK_F2','%VK_F20','%VK_F21','%VK_F22',
+ '%VK_F23','%VK_F24','%VK_F3','%VK_F4','%VK_F5','%VK_F6','%VK_F7','%VK_F8',
+ '%VK_F9','%VK_FINAL','%VK_G','%VK_H','%VK_HANGEUL','%VK_HANGUL','%VK_HANJA','%VK_HELP',
+ '%VK_HOME','%VK_I','%VK_INSERT','%VK_J','%VK_JUNJA','%VK_K','%VK_KANA','%VK_KANJI',
+ '%VK_L','%VK_LBUTTON','%VK_LEFT','%VK_LINEFEED','%VK_LWIN','%VK_M','%VK_MBUTTON','%VK_MENU',
+ '%VK_MODECHANGE','%VK_MULTIPLY','%VK_N','%VK_NEXT','%VK_NONCONVERT','%VK_NUMLOCK','%VK_NUMPAD0','%VK_NUMPAD1',
+ '%VK_NUMPAD2','%VK_NUMPAD3','%VK_NUMPAD4','%VK_NUMPAD5','%VK_NUMPAD6','%VK_NUMPAD7','%VK_NUMPAD8','%VK_NUMPAD9',
+ '%VK_O','%VK_P','%VK_PAUSE','%VK_PGDN','%VK_PGUP','%VK_PRINT','%VK_PRIOR','%VK_Q',
+ '%VK_R','%VK_RBUTTON','%VK_RETURN','%VK_RIGHT','%VK_RWIN','%VK_S','%VK_SCROLL','%VK_SELECT',
+ '%VK_SEPARATOR','%VK_SHIFT','%VK_SLEEP','%VK_SNAPSHOT','%VK_SPACE','%VK_SUBTRACT','%VK_T','%VK_TAB',
+ '%VK_U','%VK_UP','%VK_V','%VK_W','%VK_X','%VK_XBUTTON1','%VK_XBUTTON2','%VK_Y',
+ '%VK_Z','%VT_ARRAY','%VT_BLOB','%VT_BLOB_OBJECT','%VT_BOOL','%VT_BSTR','%VT_BYREF','%VT_CARRAY',
+ '%VT_CF','%VT_CLSID','%VT_CY','%VT_DATE','%VT_DISPATCH','%VT_EMPTY','%VT_ERROR','%VT_FILETIME',
+ '%VT_HRESULT','%VT_I1','%VT_I2','%VT_I4','%VT_I8','%VT_INT','%VT_LPSTR','%VT_LPWSTR',
+ '%VT_NULL','%VT_PTR','%VT_R4','%VT_R8','%VT_RECORD','%VT_RESERVED','%VT_SAFEARRAY','%VT_STORAGE',
+ '%VT_STORED_OBJECT','%VT_STREAM','%VT_STREAMED_OBJECT','%VT_UI1','%VT_UI2','%VT_UI4','%VT_UI8','%VT_UINT',
+ '%VT_UNKNOWN','%VT_USERDEFINED','%VT_VARIANT','%VT_VECTOR','%VT_VOID','%WAVE_FORMAT_1M08','%WAVE_FORMAT_1M16','%WAVE_FORMAT_1S08',
+ '%WAVE_FORMAT_1S16','%WAVE_FORMAT_2M08','%WAVE_FORMAT_2M16','%WAVE_FORMAT_2S08','%WAVE_FORMAT_2S16','%WAVE_FORMAT_4M08','%WAVE_FORMAT_4M16','%WAVE_FORMAT_4S08',
+ '%WAVE_FORMAT_4S16','%WBF_CUSTOM','%WBF_LEVEL1','%WBF_LEVEL2','%WBF_OVERFLOW','%WBF_WORDBREAK','%WBF_WORDWRAP','%WHITE',
+ '%WIN_FINDTITLECONTAIN','%WIN_FINDTITLEEND','%WIN_FINDTITLEEQUAL','%WIN_FINDTITLESTART','%WM_ACTIVATE','%WM_ACTIVATEAPP','%WM_CAPTURECHANGED','%WM_CHAR',
+ '%WM_CLOSE','%WM_COMMAND','%WM_DESTROY','%WM_DROPFILES','%WM_ERASEBKGND','%WM_GETTEXTLENGTH','%WM_HOTKEY','%WM_HSCROLL',
+ '%WM_IDLE','%WM_INITDIALOG','%WM_KEYDOWN','%WM_KEYUP','%WM_KILLFOCUS','%WM_LBUTTONDBLCLK','%WM_LBUTTONDOWN','%WM_LBUTTONUP',
+ '%WM_MBUTTONDBLCLK','%WM_MBUTTONDOWN','%WM_MBUTTONUP','%WM_MOUSEFIRST','%WM_MOUSEMOVE','%WM_MOUSEWHEEL','%WM_MOVE','%WM_MOVING',
+ '%WM_NCLBUTTONDOWN','%WM_NCRBUTTONDOWN','%WM_NEXTDLGCTL','%WM_NOTIFY','%WM_PAINT','%WM_QUIT','%WM_RBUTTONDBLCLK','%WM_RBUTTONDOWN',
+ '%WM_RBUTTONUP','%WM_SETFOCUS','%WM_SETFONT','%WM_SETTEXT','%WM_SIZE','%WM_SIZING','%WM_SYSCOMMAND','%WM_TIMER',
+ '%WM_USER','%WM_VSCROLL','%WS_BORDER','%WS_CAPTION','%WS_CHILD','%WS_CLIPCHILDREN','%WS_CLIPSIBLINGS','%WS_DISABLED',
+ '%WS_DLGFRAME','%WS_EX_ACCEPTFILES','%WS_EX_APPWINDOW','%WS_EX_CLIENTEDGE','%WS_EX_CONTEXTHELP','%WS_EX_CONTROLPARENT','%WS_EX_LAYERED','%WS_EX_LEFT',
+ '%WS_EX_LEFTSCROLLBAR','%WS_EX_LTRREADING','%WS_EX_MDICHILD','%WS_EX_NOPARENTNOTIFY','%WS_EX_OVERLAPPEDWINDOW','%WS_EX_PALETTEWINDOW','%WS_EX_RIGHT','%WS_EX_RIGHTSCROLLBAR',
+ '%WS_EX_RTLREADING','%WS_EX_STATICEDGE','%WS_EX_TOOLWINDOW','%WS_EX_TOPMOST','%WS_EX_TRANSPARENT','%WS_EX_WINDOWEDGE','%WS_GROUP','%WS_HSCROLL',
+ '%WS_ICONIC','%WS_MAXIMIZE','%WS_MAXIMIZEBOX','%WS_MINIMIZE','%WS_MINIMIZEBOX','%WS_OVERLAPPEDWINDOW','%WS_POPUP','%WS_POPUPWINDOW',
+ '%WS_SYSMENU','%WS_TABSTOP','%WS_THICKFRAME','%WS_VISIBLE','%WS_VSCROLL','%YELLOW','%ZERO','CRLF',
+ 'FALSE','M_E','M_PI','NULL','TAB','TRUE'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%', '^', '&', ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF; font-weight: bold;',
+ 2 => 'color: #993333; font-style: italic; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #333333;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #800080;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #CC0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #66cc66;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #333333;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '_'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/tsql.php b/platform/www/vendor/geshi/geshi/src/geshi/tsql.php
new file mode 100644
index 0000000..a20ac91
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/tsql.php
@@ -0,0 +1,819 @@
+<?php
+/*************************************************************************************
+ * tsql.php
+ * --------
+ * Author: Duncan Lock (dunc@dflock.co.uk)
+ * Copyright: (c) 2006 Duncan Lock (http://dflock.co.uk/), Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/11/22
+ *
+ * T-SQL language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/01/23 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2006/01/23)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'T-SQL',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'"),
+ 'HARDQUOTE' => array("N'", "'"),
+ 'ESCAPE_CHAR' => '[',
+ 'KEYWORDS' => array(
+ 1 => array(
+ /*
+ Built-in functions
+ Highlighted in pink.
+ Moved these to first array so that functions like @@ROWCOUNT
+ weren't broken up into @@ in black and ROWCOUNT in blue
+ This would prevent the correct pink coloring from taking place.
+ Not sure of any other downsides to this.
+ */
+
+ //Configuration Functions
+ '@@DATEFIRST','@@OPTIONS','@@DBTS','@@REMSERVER','@@LANGID','@@SERVERNAME',
+ '@@LANGUAGE','@@SERVICENAME','@@LOCK_TIMEOUT','@@SPID','@@MAX_CONNECTIONS',
+ '@@TEXTSIZE','@@MAX_PRECISION','@@VERSION','@@NESTLEVEL',
+
+ //Cursor Functions
+ '@@CURSOR_ROWS','@@FETCH_STATUS',
+
+ //Date and Time Functions
+ 'DATEADD','DATEDIFF','DATENAME','DATEPART','GETDATE','GETUTCDATE',
+ 'DATEFROMPARTS','DATETIMEFROMPARTS', 'SMALLDATETIMEFROMPARTS', 'DATETIME2FROMPARTS', 'TIMEFROMPARTS',
+ 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'SYSDATETIME', 'SYSUTCDATETIME',
+ 'YEAR', 'QUARTER', 'MONTH', 'DAY', 'HOUR', 'MINUTE', 'SECOND',
+ 'EOMONTH',
+
+ //Mathematical Functions
+ 'ABS','DEGREES','RAND','ACOS','EXP','ROUND','ASIN','FLOOR','SIGN',
+ 'ATAN','LOG','SIN','ATN2','LOG10','SQUARE','CEILING','PI','SQRT','COS',
+ 'POWER','TAN','COT','RADIANS', 'RANK',
+
+ //Meta Data Functions
+ 'COL_LENGTH','COL_NAME','FULLTEXTCATALOGPROPERTY',
+ 'COLUMNPROPERTY','FULLTEXTSERVICEPROPERTY','DATABASEPROPERTY','INDEX_COL',
+ 'DATABASEPROPERTYEX','INDEXKEY_PROPERTY','DB_ID','INDEXPROPERTY','DB_NAME',
+ 'OBJECT_ID','FILE_ID','OBJECT_NAME','FILE_NAME','OBJECTPROPERTY','FILEGROUP_ID',
+ '@@PROCID','FILEGROUP_NAME','SQL_VARIANT_PROPERTY','FILEGROUPPROPERTY',
+ 'TYPEPROPERTY','FILEPROPERTY','OBJECT_SCHEMA_NAME', 'SCHEMA_ID', 'SCHEMA_NAME', 'OBJECT_DEFINITION',
+
+ //Security Functions
+ 'IS_SRVROLEMEMBER','SUSER_SID','SUSER_SNAME','USER_NAME', 'SUSER_NAME', 'USER_ID',
+ 'HAS_DBACCESS','IS_MEMBER', 'CURRENT_USER',
+
+ //String Functions
+ 'ASCII','SOUNDEX','PATINDEX','CHARINDEX','REPLACE','STR','LEFT', 'RIGHT','DATALENGTH','HASHBYTES',
+ 'DIFFERENCE','QUOTENAME','STUFF','REPLICATE','SUBSTRING','LEN',
+ 'REVERSE','UNICODE','LOWER','UPPER','LTRIM','RTRIM','FORMAT','TRY_CONVERT','TRY_PARSE','PARSE','CONVERT','CONCAT',
+
+ //System Functions
+ 'APP_NAME','COLLATIONPROPERTY','@@ERROR','FORMATMESSAGE',
+ 'GETANSINULL','HOST_ID','HOST_NAME','IDENT_CURRENT','IDENT_INCR',
+ 'IDENT_SEED','@@IDENTITY','ISDATE','ISNUMERIC','PARSENAME','PERMISSIONS','PROGRAM_NAME',
+ '@@ROWCOUNT','ROWCOUNT_BIG','SCOPE_IDENTITY','SERVERPROPERTY','SESSIONPROPERTY',
+ 'STATS_DATE','@@TRANCOUNT',
+
+ // Error handling
+ 'ERROR_STATE', 'ERROR_SEVERITY', 'ERROR_NUMBER', 'ERROR_MESSAGE', 'ERROR_LINE', 'ERROR_PROCEDURE',
+
+ //System Statistical Functions
+ '@@CONNECTIONS','@@PACK_RECEIVED','@@CPU_BUSY','@@PACK_SENT',
+ '@@TIMETICKS','@@IDLE','@@TOTAL_ERRORS','@@IO_BUSY',
+ '@@TOTAL_READ','@@PACKET_ERRORS','@@TOTAL_WRITE',
+
+ //Text and Image Functions
+ 'TEXTPTR','TEXTVALID',
+
+ //Aggregate functions
+ 'AVG', 'MAX', 'BINARY_CHECKSUM', 'MIN', 'CHECKSUM', 'SUM', 'CHECKSUM_AGG',
+ 'STDEV', 'COUNT', 'STDEVP', 'COUNT_BIG', 'VAR', 'VARP', 'ROW_NUMBER',
+ 'LAG', 'LEAD', 'PERCENT_RANK', 'CUME_DIST', 'FIRST_VALUE', 'LAST_VALUE',
+ 'PERCENTILE_CONT', 'PERCENTILE_DESC',
+
+ // Logic functions
+ 'CHOOSE', 'IIF', 'ISNULL', 'COALESCE', 'NULLIF',
+
+ // GUID
+ 'NEWID', 'NEWSEQUENTIALID',
+ ),
+ 2 => array(
+ // Datatypes
+ 'bigint', 'tinyint', 'money',
+ 'smallmoney', 'datetime', 'smalldatetime',
+ 'text', 'nvarchar', 'ntext', 'varbinary', 'image',
+ 'sql_variant', 'uniqueidentifier', 'smallint', 'int',
+ 'xml', 'hierarchyid', 'geography', 'geometry', 'varchar', 'char', 'nchar',
+ 'numeric', 'decimal', 'bit', 'sysname', 'date', 'time', 'datetime2', 'datetimeoffset',
+
+ // Keywords
+ 'ABSOLUTE', 'ACTION', 'ADD', 'ADMIN', 'AFTER', 'AGGREGATE', 'ALIAS', 'ALLOCATE', 'ALLOWED', 'ALTER', 'ARE', 'ARRAY', 'AS',
+ 'ASC', 'ASSERTION', 'AT', 'ATOMIC', 'AUDIT', 'AUTHORIZATION', 'AVAILABILITY', 'BACKUP', 'BEFORE', 'BEGIN', 'BINARY', 'BLOB', 'BOOLEAN', 'BOTH', 'BREADTH',
+ 'BREAK', 'BROWSE', 'BUCKET_COUNT', 'BULK', 'BY', 'CACHE', 'CALL', 'CASCADE', 'CASCADED', 'CASE', 'CAST', 'CATALOG', 'CHARACTER', 'CHECK', 'CHECKCONSTRAINTS',
+ 'CHECKDB', 'CHECKPOINT',
+ 'CLASS', 'CLEAR', 'CLOB', 'CLOSE', 'CLUSTERED', 'COLLATE', 'COLLATION', 'COLUMN', 'COLUMNSTORE', 'COMMIT',
+ 'COMMITTED', 'COMPLETION', 'COMPUTE', 'CONFIGURATION',
+ 'CONNECT', 'CONNECTION', 'CONSTRAINT', 'CONSTRAINTS', 'CONSTRUCTOR', 'CONTAINMENT', 'CONTAINS', 'CONTAINSTABLE', 'CONTINUE', 'CORRESPONDING', 'CREATE',
+ 'CUBE', 'CURRENT', 'CURRENT_DATE', 'CURRENT_PATH', 'CURRENT_ROLE',
+ 'CURSOR', 'CYCLE', 'DATA', 'DATA_MIRRORING', 'DATABASE', 'DBCC', 'DEALLOCATE', 'DEC', 'DECLARE', 'DEFAULT', 'DEFERRABLE',
+ 'DEFERRED', 'DELAY', 'DELAYED_DURABILITY', 'DELETE', 'DENY', 'DEPTH', 'DEREF', 'DESC', 'DESCRIBE', 'DESCRIPTOR', 'DESTROY', 'DESTRUCTOR', 'DETERMINISTIC',
+ 'DIAGNOSTICS', 'DIALOG', 'DICTIONARY', 'DISABLED', 'DISCONNECT', 'DISK', 'DISTINCT', 'DISTRIBUTED', 'DOMAIN', 'DOUBLE', 'DROP', 'DROPCLEANBUFFERS', 'DROP_EXISTING',
+ 'DUMMY', 'DUMP', 'DURABILITY', 'DYNAMIC',
+ 'EACH', 'ELSE', 'END', 'END-EXEC', 'EQUALS', 'ERRLVL', 'ESCAPE', 'EVERY', 'EXCEPT', 'EXCEPTION', 'EXEC', 'EXECUTE', 'EXIT',
+ 'EXTERNAL', 'FALSE', 'FETCH', 'FILE', 'FILLFACTOR', 'FIRST', 'FLOAT', 'FOR', 'FOR ATTACH', 'FOR ATTACH_REBUILD_LOG', 'FORCESCAN', 'FORCESEEK', 'FOREIGN', 'FOUND', 'FREE',
+ 'FREEPROCCACHE', 'FREETEXT', 'FREETEXTTABLE',
+ 'FROM', 'FUNCTION', 'GENERAL', 'GET', 'GLOBAL', 'GO', 'GOTO', 'GRANT', 'GROUP', 'GROUPING', 'HAVING', 'HOLDLOCK', 'HOST',
+ 'IDENTITY', 'IDENTITY_INSERT', 'IDENTITYCOL', 'IF', 'IGNORE', 'IMMEDIATE', 'INDEX', 'INDICATOR', 'INITIALIZE', 'INITIALLY',
+ 'INOUT', 'INPUT', 'INSERT', 'INTEGER', 'INTERSECT', 'INTERVAL', 'INTO', 'IS', 'ISOLATION', 'ITERATE', 'KEY',
+ 'KILL', 'LANGUAGE', 'LARGE', 'LAST', 'LATERAL', 'LEADING', 'LESS', 'LEVEL', 'LIMIT', 'LINENO', 'LOAD', 'LOCAL',
+ 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCATOR', 'MAP', 'MASTER KEY', 'MATCH', 'MATCHED', 'MEMORY_OPTIMIZED', 'MEMORY_OPTIMIZED_DATA', 'MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT', 'MESSAGE', 'MILLISECOND', 'MODIFIES', 'MODIFY', 'MODULE', 'NAMES', 'NANOSECOND', 'NATIONAL', 'NATIVE_COMPILATION',
+ 'NATURAL', 'NCLOB', 'NEW', 'NEXT', 'NO', 'NO_INFOMSGS', 'NOCHECK', 'NOCOUNT', 'NONCLUSTERED', 'NONE', 'OBJECT', 'OF',
+ 'OFF', 'OFFSET', 'OFFSETS', 'OLD', 'ON', 'ONLY', 'OPEN', 'OPENDATASOURCE', 'OPENQUERY', 'OPENROWSET', 'OPENXML', 'OPERATION', 'OPTION',
+ 'OPTIMIZER_WHATIF',
+ 'ORDER', 'ORDINALITY', 'OUT', 'OUTPUT', 'OVER', 'OWNER', 'PAD', 'PARAMETER', 'PARTIAL', 'PARTITION', 'PASSWORD', 'PATH', 'PERCENT', 'PLAN',
+ 'POSTFIX', 'PREFIX', 'PREORDER', 'PREPARE', 'PRESERVE', 'PRECEDING', 'PREVIOUS', 'PRIMARY', 'PRINT', 'PRIOR', 'PRIVILEGES', 'PROC', 'PROCEDURE',
+ 'PUBLIC', 'QUERYRULEOFF', 'QUERYTRACEON', 'RAISERROR', 'RANGE', 'READ', 'READS', 'READTEXT', 'REAL', 'REBUILD', 'RECEIVE', 'RECONFIGURE', 'RECURSIVE', 'REF', 'REFERENCES', 'REFERENCING', 'RELATIVE',
+ 'REPEATABLE', 'REPLICATION', 'RESTORE', 'RESTRICT', 'RESULT', 'RETURN', 'RETURNS', 'REVOKE', 'ROLE', 'ROLLBACK', 'ROLLUP', 'ROUTINE', 'ROW', 'ROWCOUNT',
+ 'ROWGUIDCOL', 'ROWS', 'RULE', 'SAVE', 'SAVEPOINT', 'SCHEMA', 'SCHEMA_AND_DATA', 'SCOPE', 'SCROLL', 'SEARCH', 'SECONDS', 'SECTION', 'SELECT', 'SEND', 'SENT',
+ 'SEQUENCE', 'SERIALIZABLE', 'SERVER', 'SESSION', 'SESSION_USER', 'SET', 'SETCPUWEIGHT', 'SETIOWEIGHT',
+ 'SETS', 'SETUSER', 'SHOW_STATISTICS', 'SHOWWEIGHTS', 'SHUTDOWN', 'SIZE', 'SNAPSHOT', 'SPACE', 'SPECIFIC', 'SPECIFICATION',
+ 'SPECIFICTYPE', 'SQL', 'SQLEXCEPTION', 'SQLPERF', 'SQLSTATE', 'SQLWARNING', 'START', 'STAT_HEADER', 'STATE', 'STATEMENT', 'STATIC', 'STATISTICS', 'STRUCTURE',
+ 'SYSTEM_USER', 'TABLE', 'TEMPORARY', 'TERMINATE', 'TEXTSIZE', 'THAN', 'THEN', 'THROW', 'TIES', 'TIMESTAMP', 'TIMEZONE_HOUR', 'TIMEZONE_MINUTE',
+ 'TO', 'TOP', 'TRAILING', 'TRAN', 'TRANSACTION', 'TRANSLATION', 'TREAT', 'TRIGGER', 'TRUE', 'TRUNCATE', 'TSEQUAL', 'TYPE', 'UNBOUNDED', 'UNCOMMITTED',
+ 'UNDEFINED', 'UNDER', 'UNION', 'UNIQUE', 'UNKNOWN', 'UNNEST', 'UPDATE', 'UPDATETEXT', 'USAGE', 'USE', 'USER', 'USING', 'VALUE', 'VALUES',
+ 'VARIABLE', 'VARYING', 'VIEW', 'WAITFOR', 'WHEN', 'WHENEVER', 'WHERE', 'WHILE', 'WITH', 'WITHIN', 'WITHOUT', 'WORK', 'WRITE', 'WRITETEXT', 'ZONE',
+
+ // cursor keywords
+ 'FORWARD_ONLY', 'READ_ONLY', 'FAST_FORWARD',
+
+ // resource governor
+ 'RESOURCE', 'GOVERNOR', 'POOL', 'WORKLOAD',
+
+ // other keywords that were missing or are new in SQL Server 2012.
+ 'ANSI_NULL_DFLT_ON',
+ 'ACCENT_SENSITIVITY', 'ACTIVATION', 'ACTIVE', 'ADDRESS', 'AES', 'AFFINITY', 'ALGORITHM', 'ALL_SPARSE_COLUMNS', 'ALLOW_MULTIPLE_EVENT_LOSS',
+ 'ALLOW_PAGE_LOCKS', 'ALLOW_ROW_LOCKS', 'ALLOW_SINGLE_EVENT_LOSS', 'ALLOW_SNAPSHOT_ISOLATION', 'ANONYMOUS', 'ANSI_DEFAULTS', 'ANSI_NULL_DEFAULT',
+ 'ANSI_NULL_DFLT_OFF', 'ANSI_NULLS', 'ANSI_PADDING', 'ANSI_WARNINGS', 'ARITHABORT', 'ARITHIGNORE', 'ASSEMBLY', 'ASYMMETRIC', 'ATTACH_REBUILD_LOG', 'AUTO', 'AUTO_CLEANUP',
+ 'AUTO_CLOSE', 'AUTO_CREATE_STATISTICS', 'AUTO_SHRINK', 'AUTO_UPDATE_STATISTICS', 'AUTO_UPDATE_STATISTICS_ASYNC', 'BATCHSIZE', 'BEGIN_DIALOG',
+ 'BINDING', 'BROKER', 'BROKER_INSTANCE', 'BULK_LOGGED', 'CAP_CPU_PERCENT', 'CATALOG_DEFAULT', 'CATCH', 'CERTIFICATE', 'CHANGE_RETENTION',
+ 'CHANGE_TRACKING', 'CHECK_EXPIRATION', 'CHECK_POLICY', 'CLASSIFIER_FUNCTION', 'CLUSTER', 'CODEPAGE', 'COLLECTION',
+ 'COLUMN_SET', 'COMPATIBILITY_LEVEL', 'COMPRESSION', 'CONCAT_NULL_YIELDS_NULL', 'CONTENT', 'CONTRACT', 'CONVERSATION', 'CPU', 'CPU_ID', 'CREDENTIAL',
+ 'CRYPTOGRAPHIC', 'CURSOR_CLOSE_ON_COMMIT', 'CURSOR_DEFAULT', 'DATA_COMPRESSION', 'DATABASE_MIRRORING', 'DATAFILETYPE', 'DATE_CORRELATION_OPTIMIZATION',
+ 'DATEFIRST', 'DATEFORMAT', 'DAYS', 'DB_CHAINING', 'DEADLOCK_PRIORITY', 'DECRYPTION', 'DEFAULT_DATABASE', 'DEFAULT_FULLTEXT_LANGUAGE', 'DEFAULT_LANGUAGE',
+ 'DEFAULT_SCHEMA', 'DIRECTORY_NAME', 'DISABLE_BROKER', 'DOCUMENT', 'EMERGENCY', 'ENABLE_BROKER', 'ENCRYPTION', 'ENDPOINT', 'ERROR_BROKER_CONVERSATIONS',
+ 'ERRORFILE', 'EVENT', 'EVENT_RETENTION_MODE', 'EXPAND', 'EXTERNAL_ACCESS', 'FAILOVER', 'FAST', 'FIELDTERMINATOR', 'FILEGROUP', 'FILEGROWTH', 'FILENAME',
+ 'FILEPATH', 'FILESTREAM', 'FILESTREAM_ON', 'FILETABLE_DIRECTORY', 'FILETABLE_NAMESPACE', 'FIPS_FLAGGER', 'FIRE_TRIGGERS', 'FIRSTROW', 'FMTONLY', 'FORCE',
+ 'FORCE_SERVICE_ALLOW_DATA_LOSS', 'FORCED', 'FORCEPLAN', 'FORMATFILE', 'FULLTEXT', 'GROUP_MAX_REQUESTS', 'HASH', 'HIGH', 'HONOR_BROKER_PRIORITY', 'HOURS',
+ 'HTTP', 'IGNORE_CONSTRAINTS', 'IGNORE_DUP_KEY', 'IGNORE_NONCLUSTERED_COLUMNSTORE_INDEX', 'IGNORE_TRIGGERS', 'IMPLICIT_TRANSACTIONS', 'IMPORTANCE',
+ 'INCLUDE', 'INCREMENT', 'INCREMENTAL', 'INFINITE', 'INIT', 'INITIATOR', 'INSTEAD', 'IO', 'KB', 'KEEP', 'KEEPDEFAULTS', 'KEEPFIXED', 'KEEPIDENTITY',
+ 'KEEPNULLS', 'KERBEROS', 'KILOBYTES_PER_BATCH', 'LASTROW', 'LIFETIME', 'LIST', 'LISTENER_IP', 'LISTENER_PORT', 'LOCAL_SERVICE_NAME', 'LOCK_ESCALATION',
+ 'LOCK_TIMEOUT', 'LOOP', 'LOW', 'MAX_CPU_PERCENT', 'MAX_DISPATCH_LATENCY', 'MAX_DOP', 'MAX_EVENT_SIZE', 'MAX_FILES', 'MAX_MEMORY', 'MAX_MEMORY_PERCENT',
+ 'MAX_QUEUE_READERS', 'MAX_ROLLOVER_FILES', 'MAXDOP', 'MAXERRORS', 'MAXRECURSION', 'MAXSIZE', 'MAXVALUE', 'MB', 'MEDIUM', 'MEMORY_PARTITION_MODE',
+ 'MERGE', 'MESSAGE_FORWARD_SIZE', 'MESSAGE_FORWARDING', 'MIN_CPU_PERCENT', 'MIN_MEMORY_PERCENT', 'MINUTES', 'MINVALUE', 'MIRROR_ADDRESS', 'MOVE',
+ 'MULTI_USER', 'MUST_CHANGE', 'NEGOTIATE', 'NESTED_TRIGGERS', 'NEW_ACCOUNT', 'NEW_BROKER', 'NEWNAME', 'NO_COMPRESSION', 'NO_EVENT_LOSS', 'NO_WAIT', 'NOEXEC', 'NOEXPAND',
+ 'NOLOCK', 'NON_TRANSACTED_ACESS', 'NOWAIT', 'NTLM', 'NUMA_NODE_ID', 'NUMANODE', 'NUMERIC_ROUNDABORT', 'OFFLINE', 'OLD_ACCOUNT', 'ON_FAILURE', 'ONLINE',
+ 'OPTIMIZE', 'OVERRIDE', 'PAD_INDEX', 'PAGE', 'PAGE_VERIFY', 'PAGLOCK', 'PARAMETERIZATION', 'PARSEONLY', 'PARTITIONS', 'PARTNER', 'PER_CPU', 'PER_NODE',
+ 'PERMISSION_SET', 'PERSISTED', 'POISON_MESSAGE_HANDLING', 'POPULATION', 'PRIORITY', 'PRIORITY_LEVEL', 'PRIVATE', 'PROCEDURE_NAME', 'PROCESS', 'PROFILE',
+ 'PROPERTY', 'PROPERTY_DESCRIPTION', 'PROPERTY_INT_ID', 'PROPERTY_SET_GUID', 'PROVIDER', 'QUERY_GOVERNOR_COST_LIMIT', 'QUEUE', 'QUEUE_DELAY',
+ 'QUOTED_IDENTIFIER', 'RC4', 'READ_COMMITTED_SNAPSHOT', 'READ_WRITE', 'READCOMMITTED', 'READCOMMITTEDLOCK', 'READONLY', 'READPAST', 'READUNCOMMITTED',
+ 'READWRITE', 'RECOMPILE', 'RECOVERY', 'RECOVERY FULL', 'RECOVERY SIMPLE', 'RECURSIVE_TRIGGERS', 'REGENERATE', 'REMOTE', 'REMOTE_PROC_TRANSACTIONS', 'REMOTE_SERVICE_NAME', 'REMOVE',
+ 'REPEATABLEREAD', 'REQUEST_MAX_CPU_TIME_SEC', 'REQUEST_MAX_MEMORY_GRANT_PERCENT', 'REQUEST_MEMORY_GRANT_TIMEOUT_SEC', 'REQUIRED', 'RESERVE_DISK_SPACE',
+ 'RESET', 'RESTART', 'RESTRICTED_USER', 'RESUME', 'RETENTION', 'ROBUST', 'ROUTE', 'ROWLOCK', 'ROWS_PER_BATCH', 'ROWTERMINATOR', 'SAFE', 'SAFETY',
+ 'SCHEDULER', 'SCHEMABINDING', 'SCHEME', 'SECRET', 'SERVICE', 'SERVICE_BROKER', 'SERVICE_NAME', 'SETERROR', 'SHOWPLAN', 'SHOWPLAN_ALL', 'SHOWPLAN_TEXT',
+ 'SHOWPLAN_XML', 'SIMPLE', 'SINGLE_USER', 'SORT_IN_TEMPDB', 'SOURCE', 'SPARSE', 'SPATIAL_WINDOW_MAX_CELLS', 'SPLIT', 'STARTED', 'STARTUP_STATE',
+ 'STATISTICAL_SEMANTICS', 'STATISTICS_NORECOMPUTE', 'STATUS', 'STOP', 'STOPLIST', 'STOPPED', 'SUPPORTED', 'SUSPEND', 'SWITCH', 'SYMMETRIC', 'SYNONYM',
+ 'SYSTEM', 'TABLOCK', 'TABLOCKX', 'TARGET', 'TARGET_RECOVERY_TIME', 'TCP', 'TIMEOUT', 'TORN_PAGE_DETECTION', 'TRACK_CAUSALITY', 'TRACK_COLUMNS_UPDATED',
+ 'TRANSFER', 'TRANSFORM_NOISE_WORDS', 'TRUSTWORTHY', 'TRY', 'TSQL', 'TWO_DIGIT_YEAR_CUTOFF', 'UNCHECKED', 'UNLIMITED', 'UNLOCK', 'UNSAFE', 'UPDLOCK',
+ 'USED', 'VALID_XML', 'VALIDATION', 'VIEW_METADATA', 'VISIBILITY', 'WEEKDAY', 'WELL_FORMED_XML', 'WINDOWS', 'WITH SUBJECT', 'WITNESS', 'XACT_ABORT', 'XLOCK',
+
+ /* AlwaysOn stuff */
+ 'AUTHENTICATION', 'ENDPOINT_URL', 'LISTENER', 'COPY_ONLY', 'NORECOVERY', 'NOUNLOAD', 'HADR', 'PORT',
+ 'FAILOVER_MODE', 'MANUAL', 'AVAILABILITY_MODE', 'ASYNCHRONOUS_COMMIT', 'SYNCHRONOUS_COMMIT', 'AUTOMATIC', 'REPLICA', 'READ_ONLY_ROUTING_URL', 'BACKUP_PRIORITY', 'SECONDARY_ROLE', 'ALLOW_CONNECTIONS', 'AUTOMATED_BACKUP_PREFERENCE', 'SECONDARY', 'SECONDARY_ONLY', 'PRIMARY_ROLE', 'READ_ONLY_ROUTING_LIST',
+ ),
+ 3 => array(
+ /*
+ System stored procedures
+ Higlighted dark brown
+ */
+
+ // CLR stored procedures
+ 'sp_FuzzyLookupTableMaintenanceInstall', 'sp_FuzzyLookupTableMaintenanceInvoke', 'sp_FuzzyLookupTableMaintenanceUninstall',
+
+ // system procedures named with xp_
+ 'xp_grantlogin', 'xp_logininfo', 'xp_repl_convert_encrypt_sysadmin_wrapper', 'xp_revokelogin',
+
+ // extended procedures
+ 'xp_availablemedia', 'xp_cmdshell', 'xp_create_subdir', 'xp_delete_file', 'xp_dirtree', 'xp_enum_oledb_providers',
+ 'xp_enumerrorlogs', 'xp_enumgroups', 'xp_fileexist', 'xp_fixeddrives', 'xp_get_script', 'xp_get_tape_devices',
+ 'xp_getnetname', 'xp_instance_regaddmultistring', 'xp_instance_regdeletekey', 'xp_instance_regdeletevalue',
+ 'xp_instance_regenumkeys', 'xp_instance_regenumvalues', 'xp_instance_regread', 'xp_instance_regremovemultistring',
+ 'xp_instance_regwrite', 'xp_logevent', 'xp_loginconfig', 'xp_msver', 'xp_msx_enlist', 'xp_passAgentInfo',
+ 'xp_prop_oledb_provider', 'xp_qv', 'xp_readerrorlog', 'xp_regaddmultistring', 'xp_regdeletekey', 'xp_regdeletevalue',
+ 'xp_regenumkeys', 'xp_regenumvalues', 'xp_regread', 'xp_regremovemultistring', 'xp_regwrite', 'xp_replposteor',
+ 'xp_servicecontrol', 'xp_sprintf', 'xp_sqlagent_enum_jobs', 'xp_sqlagent_is_starting', 'xp_sqlagent_monitor',
+ 'xp_sqlagent_notify', 'xp_sqlagent_param', 'xp_sqlmaint', 'xp_sscanf', 'xp_subdirs', 'xp_sysmail_activate',
+ 'xp_sysmail_attachment_load', 'xp_sysmail_format_query',
+
+ // extended procedures named with sp_
+ 'sp_AddFunctionalUnitToComponent', 'sp_audit_write', 'sp_availability_group_command_internal', 'sp_begin_parallel_nested_tran',
+ 'sp_bindsession', 'sp_change_tracking_waitforchanges', 'sp_commit_parallel_nested_tran', 'sp_control_dbmasterkey_password',
+ 'sp_createorphan', 'sp_cursor', 'sp_cursorclose', 'sp_cursorexecute', 'sp_cursorfetch', 'sp_cursoropen', 'sp_cursoroption',
+ 'sp_cursorprepare', 'sp_cursorprepexec', 'sp_cursorunprepare', 'sp_delete_http_namespace_reservation',
+ 'sp_describe_first_result_set', 'sp_describe_undeclared_parameters', 'sp_droporphans', 'sp_enable_sql_debug', 'sp_execute',
+ 'sp_executesql', 'sp_fulltext_getdata', 'sp_fulltext_keymappings', 'sp_fulltext_pendingchanges', 'sp_get_query_template',
+ 'sp_getbindtoken', 'sp_getschemalock', 'sp_http_generate_wsdl_complex', 'sp_http_generate_wsdl_simple',
+ 'sp_migrate_user_to_contained', 'sp_new_parallel_nested_tran_id', 'sp_OACreate', 'sp_OADestroy', 'sp_OAGetErrorInfo',
+ 'sp_OAGetProperty', 'sp_OAMethod', 'sp_OASetProperty', 'sp_OAStop', 'sp_PostAgentInfo', 'sp_prepare', 'sp_prepexec',
+ 'sp_prepexecrpc', 'sp_releaseschemalock', 'sp_repl_generateevent', 'sp_replcmds', 'sp_replcounters', 'sp_replddlparser',
+ 'sp_repldone', 'sp_replflush', 'sp_replhelp', 'sp_replsendtoqueue', 'sp_replsetsyncstatus', 'sp_repltrans',
+ 'sp_replwritetovarbin', 'sp_reserve_http_namespace', 'sp_reset_connection', 'sp_resyncexecute', 'sp_resyncexecutesql',
+ 'sp_resyncprepare', 'sp_resyncuniquetable', 'sp_rollback_parallel_nested_tran', 'sp_server_diagnostics',
+ 'sp_SetOBDCertificate', 'sp_setuserbylogin', 'sp_showmemo_xml', 'sp_start_user_instance', 'sp_testlinkedserver',
+ 'sp_trace_create', 'sp_trace_generateevent', 'sp_trace_setevent', 'sp_trace_setfilter', 'sp_trace_setstatus', 'sp_unprepare',
+ 'sp_update_user_instance', 'sp_xml_preparedocument', 'sp_xml_removedocument', 'sp_xp_cmdshell_proxy_account'
+
+ ),
+ 4 => array(
+ // DMVs/DMFs/catalog views etc. highlighted green.
+
+ //schemas
+ 'sys', 'INFORMATION_SCHEMA',
+
+ // inline TVFs
+ 'dm_cryptographic_provider_algorithms','dm_cryptographic_provider_keys','dm_cryptographic_provider_sessions',
+ 'dm_db_database_page_allocations','dm_db_index_operational_stats','dm_db_index_physical_stats',
+ 'dm_db_missing_index_columns','dm_db_objects_disabled_on_compatibility_level_change',
+ 'dm_exec_cached_plan_dependent_objects','dm_exec_cursors','dm_exec_describe_first_result_set',
+ 'dm_exec_describe_first_result_set_for_object','dm_exec_plan_attributes','dm_exec_query_plan','dm_exec_sql_text',
+ 'dm_exec_text_query_plan','dm_exec_xml_handles','dm_fts_index_keywords','dm_fts_index_keywords_by_document',
+ 'dm_fts_index_keywords_by_property','dm_fts_parser','dm_io_virtual_file_stats','dm_logconsumer_cachebufferrefs',
+ 'dm_logconsumer_privatecachebuffers','dm_logpool_consumers','dm_logpool_sharedcachebuffers','dm_logpoolmgr_freepools',
+ 'dm_logpoolmgr_respoolsize','dm_logpoolmgr_stats','dm_os_volume_stats','dm_sql_referenced_entities',
+ 'dm_sql_referencing_entities','fn_builtin_permissions','fn_check_object_signatures','fn_dblog','fn_dump_dblog',
+ 'fn_get_audit_file','fn_get_sql','fn_helpcollations','fn_MSxe_read_event_stream','fn_trace_gettable',
+ 'fn_translate_permissions', 'fn_validate_plan_guide', 'fn_xe_file_target_read_file',
+
+ // multi-statement TVFs
+ 'fn_EnumCurrentPrincipals', 'fn_helpdatatypemap', 'fn_listextendedproperty', 'fn_my_permissions',
+ 'fn_PhysLocCracker', 'fn_replgetcolidfrombitmap', 'fn_RowDumpCracker', 'fn_servershareddrives',
+ 'fn_trace_geteventinfo', 'fn_trace_getfilterinfo', 'fn_trace_getinfo', 'fn_virtualfilestats',
+ 'fn_virtualservernodes',
+
+ // aggregate functions
+ 'GeographyCollectionAggregate', 'GeographyConvexHullAggregate', 'GeographyEnvelopeAggregate', 'GeographyUnionAggregate',
+ 'GeometryCollectionAggregate', 'GeometryConvexHullAggregate', 'GeometryEnvelopeAggregate', 'GeometryUnionAggregate',
+ 'ORMask',
+
+ // scalar functions
+ 'fn_cColvEntries_80','fn_cdc_check_parameters','fn_cdc_get_column_ordinal','fn_cdc_get_max_lsn','fn_cdc_get_min_lsn',
+ 'fn_cdc_has_column_changed','fn_cdc_hexstrtobin','fn_cdc_map_lsn_to_time','fn_cdc_map_time_to_lsn','fn_fIsColTracked',
+ 'fn_GetCurrentPrincipal','fn_GetRowsetIdFromRowDump','fn_hadr_backup_is_preferred_replica','fn_IsBitSetInBitmask',
+ 'fn_isrolemember','fn_MapSchemaType','fn_MSdayasnumber','fn_MSgeneration_downloadonly','fn_MSget_dynamic_filter_login',
+ 'fn_MSorbitmaps','fn_MSrepl_map_resolver_clsid','fn_MStestbit','fn_MSvector_downloadonly','fn_numberOf1InBinaryAfterLoc',
+ 'fn_numberOf1InVarBinary','fn_PhysLocFormatter','fn_repladjustcolumnmap','fn_repldecryptver4','fn_replformatdatetime',
+ 'fn_replgetparsedddlcmd','fn_replp2pversiontotranid', 'fn_replreplacesinglequote',
+ 'fn_replreplacesinglequoteplusprotectstring', 'fn_repluniquename', 'fn_replvarbintoint', 'fn_sqlvarbasetostr',
+ 'fn_varbintohexstr', 'fn_varbintohexsubstring', 'fn_yukonsecuritymodelrequired',
+
+ // service queues
+ 'EventNotificationErrorsQueue', 'QueryNotificationErrorsQueue', 'ServiceBrokerQueue',
+
+ // system tables
+ 'sysallocunits','sysasymkeys','sysaudacts','sysbinobjs','sysbinsubobjs','sysbrickfiles','syscerts','syschildinsts','sysclones','sysclsobjs',
+ 'syscolpars','syscompfragments','sysconvgroup','syscscolsegments','syscsdictionaries','sysdbfiles','sysdbfrag','sysdbreg','sysdercv','sysdesend',
+ 'sysendpts','sysfgfrag','sysfiles1','sysfoqueues','sysfos','sysftinds','sysftproperties','sysftsemanticsdb','sysftstops','sysguidrefs',
+ 'sysidxstats','sysiscols','syslnklgns','sysmultiobjrefs','sysnsobjs','sysobjkeycrypts','sysobjvalues','sysowners','sysphfg','syspriorities',
+ 'sysprivs','syspru','sysprufiles','sysqnames','sysremsvcbinds','sysrmtlgns','sysrowsetrefs','sysrowsets','sysrscols','sysrts',
+ 'sysscalartypes','sysschobjs','sysseobjvalues','syssingleobjrefs','syssoftobjrefs','syssqlguides','systypedsubobjs','sysusermsgs','syswebmethods',
+ 'sysxlgns','sysxmitbody', 'sysxmitqueue', 'sysxmlcomponent', 'sysxmlfacet', 'sysxmlplacement', 'sysxprops', 'sysxsrvs',
+
+ // user tables (these are currently in dbo schema but will be fixed)
+ 'trace_xe_action_map', 'trace_xe_event_map',
+
+ // backward compatibility views
+ 'sysaltfiles', 'syscacheobjects', 'syscharsets', 'syscolumns', 'syscomments', 'sysconfigures', 'sysconstraints', 'syscurconfigs', 'syscursorcolumns',
+ 'syscursorrefs', 'syscursors', 'syscursortables', 'sysdatabases', 'sysdepends', 'sysdevices', 'sysfilegroups', 'sysfiles', 'sysforeignkeys',
+ 'sysfulltextcatalogs', 'sysindexes', 'sysindexkeys', 'syslanguages', 'syslockinfo', 'syslogins', 'sysmembers', 'sysmessages', 'sysobjects',
+ 'sysoledbusers', 'sysopentapes', 'sysperfinfo', 'syspermissions', 'sysprocesses', 'sysprotects', 'sysreferences', 'sysremotelogins', 'sysservers',
+ 'systypes', 'sysusers',
+
+ // INFORMATION_SCHEMA views
+ 'COLUMN_DOMAIN_USAGE', 'COLUMN_PRIVILEGES', 'COLUMNS', 'CONSTRAINT_COLUMN_USAGE',
+ 'CONSTRAINT_TABLE_USAGE', 'KEY_COLUMN_USAGE', 'PARAMETERS', 'REFERENTIAL_CONSTRAINTS', 'ROUTINE_COLUMNS',
+ 'ROUTINES', 'SCHEMATA', 'SEQUENCES', 'TABLE_CONSTRAINTS', 'TABLE_PRIVILEGES', 'TABLES', 'VIEW_COLUMN_USAGE',
+ 'VIEW_TABLE_USAGE', 'VIEWS',
+
+ // catalog views
+ 'default_constraints',
+ 'all_columns', 'all_objects', 'all_parameters', 'all_sql_modules', 'all_views', 'allocation_units',
+ 'assemblies', 'assembly_files', 'assembly_modules', 'assembly_references', 'assembly_types', 'asymmetric_keys',
+ 'availability_databases_cluster', 'availability_group_listener_ip_addresses', 'availability_group_listeners',
+ 'availability_groups', 'availability_groups_cluster', 'availability_read_only_routing_lists',
+ 'availability_replicas', 'backup_devices', 'certificates', 'change_tracking_databases', 'change_tracking_tables',
+ 'check_constraints', 'column_store_dictionaries', 'column_store_index_stats', 'column_store_segments',
+ 'column_type_usages', 'column_xml_schema_collection_usages', 'computed_columns', 'configurations',
+ 'conversation_endpoints', 'conversation_groups', 'conversation_priorities', 'credentials', 'crypt_properties',
+ 'cryptographic_providers', 'databases', 'endpoint_webmethods', 'endpoints', 'event_notification_event_types',
+ 'event_notifications', 'events', 'extended_procedures', 'extended_properties', 'filegroups',
+ 'filetable_system_defined_objects', 'filetables', 'foreign_key_columns', 'foreign_keys', 'fulltext_catalogs',
+ 'fulltext_document_types', 'fulltext_index_catalog_usages', 'fulltext_index_columns', 'fulltext_index_fragments',
+ 'fulltext_indexes', 'fulltext_languages', 'fulltext_semantic_language_statistics_database',
+ 'fulltext_semantic_languages', 'fulltext_stoplists', 'fulltext_stopwords', 'fulltext_system_stopwords',
+ 'function_order_columns', 'http_endpoints', 'identity_columns', 'index_columns', 'indexes', 'internal_tables',
+ 'key_constraints', 'key_encryptions', 'linked_logins', 'login_token', 'master_files', 'numbered_procedure_parameters',
+ 'numbered_procedures', 'objects', 'openkeys', 'parameter_type_usages', 'parameter_xml_schema_collection_usages',
+ 'partition_functions', 'partition_parameters', 'partition_range_values', 'partition_schemes',
+ 'partitions', 'plan_guides', 'procedures', 'registered_search_properties', 'registered_search_property_lists',
+ 'remote_logins', 'remote_service_bindings', 'resource_governor_configuration', 'resource_governor_resource_pool_affinity',
+ 'resource_governor_resource_pools', 'resource_governor_workload_groups', 'routes', 'schemas', 'securable_classes',
+ 'server_assembly_modules', 'server_audit_specification_details', 'server_audit_specifications',
+ 'server_audits', 'server_event_notifications', 'server_event_session_actions', 'server_event_session_events',
+ 'server_event_session_fields', 'server_event_session_targets', 'server_event_sessions', 'server_events',
+ 'server_file_audits', 'server_permissions', 'server_principal_credentials', 'server_principals', 'server_role_members',
+ 'server_sql_modules', 'server_trigger_events', 'server_triggers', 'servers', 'service_broker_endpoints',
+ 'service_contract_message_usages', 'service_contract_usages', 'service_contracts', 'service_message_types',
+ 'service_queue_usages', 'service_queues', 'services', 'soap_endpoints', 'spatial_index_tessellations', 'spatial_indexes',
+ 'spatial_reference_systems', 'sql_dependencies', 'sql_expression_dependencies', 'sql_logins', 'sql_modules', 'stats',
+ 'stats_columns', 'symmetric_keys', 'synonyms', 'system_columns', 'system_components_surface_area_configuration',
+ 'system_internals_allocation_units', 'system_internals_partition_columns', 'system_internals_partitions', 'system_objects',
+ 'system_parameters', 'system_sql_modules', 'system_views', 'table_types', 'tcp_endpoints', 'trace_categories',
+ 'trace_columns', 'trace_event_bindings', 'trace_events', 'trace_subclass_values', 'traces', 'transmission_queue',
+ 'trigger_event_types', 'trigger_events', 'triggers', 'type_assembly_usages', 'types', 'user_token', 'via_endpoints',
+ 'xml_indexes', 'xml_schema_attributes', 'xml_schema_collections', 'xml_schema_component_placements',
+ 'xml_schema_components', 'xml_schema_elements', 'xml_schema_facets', 'xml_schema_model_groups', 'xml_schema_namespaces',
+ 'xml_schema_types', 'xml_schema_wildcard_namespaces', 'xml_schema_wildcards',
+
+ // DMVs / DMFs
+ 'dm_audit_actions', 'dm_audit_class_type_map', 'dm_broker_activated_tasks', 'dm_broker_connections', 'dm_broker_forwarded_messages',
+ 'dm_broker_queue_monitors', 'dm_cdc_errors', 'dm_cdc_log_scan_sessions', 'dm_clr_appdomains', 'dm_clr_loaded_assemblies',
+ 'dm_clr_properties', 'dm_clr_tasks', 'dm_cryptographic_provider_properties', 'dm_database_encryption_keys', 'dm_db_file_space_usage',
+ 'dm_db_fts_index_physical_stats', 'dm_db_index_usage_stats', 'dm_db_log_space_usage', 'dm_db_mirroring_auto_page_repair',
+ 'dm_db_mirroring_connections', 'dm_db_mirroring_past_actions', 'dm_db_missing_index_details', 'dm_db_missing_index_group_stats',
+ 'dm_db_missing_index_groups', 'dm_db_partition_stats', 'dm_db_persisted_sku_features', 'dm_db_script_level', 'dm_db_session_space_usage',
+ 'dm_db_task_space_usage', 'dm_db_uncontained_entities', 'dm_exec_background_job_queue', 'dm_exec_background_job_queue_stats',
+ 'dm_exec_cached_plans', 'dm_exec_connections', 'dm_exec_procedure_stats', 'dm_exec_query_memory_grants', 'dm_exec_query_optimizer_info', 'dm_exec_query_profiles',
+ 'dm_exec_query_resource_semaphores', 'dm_exec_query_stats', 'dm_exec_query_transformation_stats', 'dm_exec_requests', 'dm_exec_sessions',
+ 'dm_exec_trigger_stats', 'dm_filestream_file_io_handles', 'dm_filestream_file_io_requests', 'dm_filestream_non_transacted_handles',
+ 'dm_fts_active_catalogs', 'dm_fts_fdhosts', 'dm_fts_index_population', 'dm_fts_memory_buffers', 'dm_fts_memory_pools',
+ 'dm_fts_outstanding_batches', 'dm_fts_population_ranges', 'dm_fts_semantic_similarity_population', 'dm_hadr_auto_page_repair',
+ 'dm_hadr_availability_group_states', 'dm_hadr_availability_replica_cluster_nodes', 'dm_hadr_availability_replica_cluster_states',
+ 'dm_hadr_availability_replica_states', 'dm_hadr_cluster', 'dm_hadr_cluster_members', 'dm_hadr_cluster_networks',
+ 'dm_hadr_database_replica_cluster_states', 'dm_hadr_database_replica_states', 'dm_hadr_instance_node_map', 'dm_hadr_name_id_map',
+ 'dm_io_backup_tapes', 'dm_io_cluster_shared_drives', 'dm_io_pending_io_requests', 'dm_logpool_hashentries',
+ 'dm_logpool_stats', 'dm_os_buffer_descriptors', 'dm_os_child_instances', 'dm_os_cluster_nodes', 'dm_os_cluster_properties',
+ 'dm_os_dispatcher_pools', 'dm_os_dispatchers', 'dm_os_hosts', 'dm_os_latch_stats', 'dm_os_loaded_modules',
+ 'dm_os_memory_allocations', 'dm_os_memory_broker_clerks', 'dm_os_memory_brokers', 'dm_os_memory_cache_clock_hands',
+ 'dm_os_memory_cache_counters', 'dm_os_memory_cache_entries', 'dm_os_memory_cache_hash_tables', 'dm_os_memory_clerks',
+ 'dm_os_memory_node_access_stats', 'dm_os_memory_nodes', 'dm_os_memory_objects', 'dm_os_memory_pools', 'dm_os_nodes',
+ 'dm_os_performance_counters', 'dm_os_process_memory', 'dm_os_ring_buffers', 'dm_os_schedulers',
+ 'dm_os_server_diagnostics_log_configurations', 'dm_os_spinlock_stats', 'dm_os_stacks', 'dm_os_sublatches', 'dm_os_sys_info',
+ 'dm_os_sys_memory', 'dm_os_tasks', 'dm_os_threads', 'dm_os_virtual_address_dump', 'dm_os_wait_stats', 'dm_os_waiting_tasks',
+ 'dm_os_windows_info', 'dm_os_worker_local_storage', 'dm_os_workers', 'dm_qn_subscriptions', 'dm_repl_articles', 'dm_repl_schemas',
+ 'dm_repl_tranhash', 'dm_repl_traninfo', 'dm_resource_governor_configuration', 'dm_resource_governor_resource_pool_affinity',
+ 'dm_resource_governor_resource_pools', 'dm_resource_governor_workload_groups', 'dm_server_audit_status', 'dm_server_memory_dumps',
+ 'dm_server_registry', 'dm_server_services', 'dm_tcp_listener_states', 'dm_tran_active_snapshot_database_transactions',
+ 'dm_tran_active_transactions', 'dm_tran_commit_table', 'dm_tran_current_snapshot', 'dm_tran_current_transaction',
+ 'dm_tran_database_transactions', 'dm_tran_locks', 'dm_tran_session_transactions', 'dm_tran_top_version_generators',
+ 'dm_tran_transactions_snapshot', 'dm_tran_version_store', 'dm_xe_map_values', 'dm_xe_object_columns', 'dm_xe_objects', 'dm_xe_packages', 'dm_xe_sessions', 'dm_xe_session_targets',
+ ),
+ 5 => array(
+
+ // system procedures (sorry, not categorized, but definitely more complete and updated for Denali)
+ // moved these to their own array because they overloaded array 3
+
+ 'sp_add_agent_parameter', 'sp_add_agent_profile', 'sp_add_data_file_recover_suspect_db', 'sp_add_log_file_recover_suspect_db',
+ 'sp_add_log_shipping_alert_job', 'sp_add_log_shipping_primary_database', 'sp_add_log_shipping_primary_secondary',
+ 'sp_add_log_shipping_secondary_database', 'sp_add_log_shipping_secondary_primary', 'sp_addapprole', 'sp_addarticle',
+ 'sp_adddatatype', 'sp_adddatatypemapping', 'sp_adddistpublisher', 'sp_adddistributiondb', 'sp_adddistributor',
+ 'sp_adddynamicsnapshot_job', 'sp_addextendedproc', 'sp_addextendedproperty', 'sp_addlinkedserver', 'sp_addlinkedsrvlogin',
+ 'sp_addlogin', 'sp_addlogreader_agent', 'sp_addmergealternatepublisher', 'sp_addmergearticle', 'sp_addmergefilter',
+ 'sp_addmergelogsettings', 'sp_addmergepartition', 'sp_addmergepublication', 'sp_addmergepullsubscription',
+ 'sp_addmergepullsubscription_agent', 'sp_addmergepushsubscription_agent', 'sp_addmergesubscription', 'sp_addmessage',
+ 'sp_addpublication', 'sp_addpublication_snapshot', 'sp_addpullsubscription', 'sp_addpullsubscription_agent',
+ 'sp_addpushsubscription_agent', 'sp_addqreader_agent', 'sp_addqueued_artinfo', 'sp_addremotelogin', 'sp_addrole',
+ 'sp_addrolemember', 'sp_addscriptexec', 'sp_addserver', 'sp_addsrvrolemember', 'sp_addsubscriber', 'sp_addsubscriber_schedule',
+ 'sp_addsubscription', 'sp_addsynctriggers', 'sp_addsynctriggerscore', 'sp_addtabletocontents', 'sp_addtype', 'sp_addumpdevice',
+ 'sp_adduser', 'sp_adjustpublisheridentityrange', 'sp_altermessage', 'sp_approlepassword', 'sp_article_validation',
+ 'sp_articlecolumn', 'sp_articlefilter', 'sp_articleview', 'sp_assemblies_rowset', 'sp_assemblies_rowset_rmt',
+ 'sp_assemblies_rowset2', 'sp_assembly_dependencies_rowset', 'sp_assembly_dependencies_rowset_rmt',
+ 'sp_assembly_dependencies_rowset2', 'sp_attach_db', 'sp_attach_single_file_db', 'sp_attachsubscription', 'sp_autostats',
+ 'sp_bcp_dbcmptlevel', 'sp_bindefault', 'sp_bindrule', 'sp_browsemergesnapshotfolder', 'sp_browsereplcmds',
+ 'sp_browsesnapshotfolder', 'sp_can_tlog_be_applied', 'sp_catalogs', 'sp_catalogs_rowset', 'sp_catalogs_rowset_rmt',
+ 'sp_catalogs_rowset2', 'sp_cdc_add_job', 'sp_cdc_change_job', 'sp_cdc_cleanup_change_table', 'sp_cdc_dbsnapshotLSN',
+ 'sp_cdc_disable_db', 'sp_cdc_disable_table', 'sp_cdc_drop_job', 'sp_cdc_enable_db', 'sp_cdc_enable_table',
+ 'sp_cdc_generate_wrapper_function', 'sp_cdc_get_captured_columns', 'sp_cdc_get_ddl_history', 'sp_cdc_help_change_data_capture',
+ 'sp_cdc_help_jobs', 'sp_cdc_restoredb', 'sp_cdc_scan', 'sp_cdc_start_job', 'sp_cdc_stop_job', 'sp_cdc_vupgrade',
+ 'sp_cdc_vupgrade_databases', 'sp_certify_removable', 'sp_change_agent_parameter', 'sp_change_agent_profile',
+ 'sp_change_log_shipping_primary_database', 'sp_change_log_shipping_secondary_database', 'sp_change_log_shipping_secondary_primary',
+ 'sp_change_subscription_properties', 'sp_change_users_login', 'sp_changearticle', 'sp_changearticlecolumndatatype',
+ 'sp_changedbowner', 'sp_changedistpublisher', 'sp_changedistributiondb', 'sp_changedistributor_password',
+ 'sp_changedistributor_property', 'sp_changedynamicsnapshot_job', 'sp_changelogreader_agent', 'sp_changemergearticle',
+ 'sp_changemergefilter', 'sp_changemergelogsettings', 'sp_changemergepublication', 'sp_changemergepullsubscription',
+ 'sp_changemergesubscription', 'sp_changeobjectowner', 'sp_changepublication', 'sp_changepublication_snapshot',
+ 'sp_changeqreader_agent', 'sp_changereplicationserverpasswords', 'sp_changesubscriber', 'sp_changesubscriber_schedule',
+ 'sp_changesubscription', 'sp_changesubscriptiondtsinfo', 'sp_changesubstatus', 'sp_check_constbytable_rowset',
+ 'sp_check_constbytable_rowset2', 'sp_check_constraints_rowset', 'sp_check_constraints_rowset2', 'sp_check_dynamic_filters',
+ 'sp_check_for_sync_trigger', 'sp_check_join_filter', 'sp_check_log_shipping_monitor_alert', 'sp_check_publication_access',
+ 'sp_check_removable', 'sp_check_subset_filter', 'sp_check_sync_trigger', 'sp_checkinvalidivarticle',
+ 'sp_checkOraclepackageversion', 'sp_clean_db_file_free_space', 'sp_clean_db_free_space', 'sp_cleanmergelogfiles',
+ 'sp_cleanup_log_shipping_history', 'sp_cleanupdbreplication', 'sp_column_privileges', 'sp_column_privileges_ex',
+ 'sp_column_privileges_rowset', 'sp_column_privileges_rowset_rmt', 'sp_column_privileges_rowset2', 'sp_columns', 'sp_columns_100',
+ 'sp_columns_100_rowset', 'sp_columns_100_rowset2', 'sp_columns_90', 'sp_columns_90_rowset', 'sp_columns_90_rowset_rmt',
+ 'sp_columns_90_rowset2', 'sp_columns_ex', 'sp_columns_ex_100', 'sp_columns_ex_90', 'sp_columns_managed', 'sp_columns_rowset',
+ 'sp_columns_rowset_rmt', 'sp_columns_rowset2', 'sp_configure', 'sp_configure_peerconflictdetection', 'sp_constr_col_usage_rowset',
+ 'sp_constr_col_usage_rowset2', 'sp_control_plan_guide', 'sp_copymergesnapshot', 'sp_copysnapshot', 'sp_copysubscription',
+ 'sp_create_plan_guide', 'sp_create_plan_guide_from_handle', 'sp_create_removable', 'sp_createmergepalrole', 'sp_createstats',
+ 'sp_createtranpalrole', 'sp_cursor_list', 'sp_cycle_errorlog', 'sp_databases', 'sp_datatype_info', 'sp_datatype_info_100',
+ 'sp_datatype_info_90', 'sp_db_increased_partitions', 'sp_db_vardecimal_storage_format', 'sp_dbcmptlevel', 'sp_dbfixedrolepermission',
+ 'sp_dbmmonitoraddmonitoring', 'sp_dbmmonitorchangealert', 'sp_dbmmonitorchangemonitoring', 'sp_dbmmonitordropalert',
+ 'sp_dbmmonitordropmonitoring', 'sp_dbmmonitorhelpalert', 'sp_dbmmonitorhelpmonitoring', 'sp_dbmmonitorresults', 'sp_dbmmonitorupdate',
+ 'sp_dbremove', 'sp_ddopen', 'sp_defaultdb', 'sp_defaultlanguage', 'sp_delete_log_shipping_alert_job',
+ 'sp_delete_log_shipping_primary_database', 'sp_delete_log_shipping_primary_secondary', 'sp_delete_log_shipping_secondary_database',
+ 'sp_delete_log_shipping_secondary_primary', 'sp_deletemergeconflictrow', 'sp_deletepeerrequesthistory', 'sp_deletetracertokenhistory',
+ 'sp_denylogin', 'sp_depends', 'sp_describe_cursor', 'sp_describe_cursor_columns', 'sp_describe_cursor_tables', 'sp_detach_db',
+ 'sp_disableagentoffload', 'sp_distcounters', 'sp_drop_agent_parameter', 'sp_drop_agent_profile', 'sp_dropanonymousagent',
+ 'sp_dropanonymoussubscription', 'sp_dropapprole', 'sp_droparticle', 'sp_dropdatatypemapping', 'sp_dropdevice', 'sp_dropdistpublisher',
+ 'sp_dropdistributiondb', 'sp_dropdistributor', 'sp_dropdynamicsnapshot_job', 'sp_dropextendedproc', 'sp_dropextendedproperty',
+ 'sp_droplinkedsrvlogin', 'sp_droplogin', 'sp_dropmergealternatepublisher', 'sp_dropmergearticle', 'sp_dropmergefilter',
+ 'sp_dropmergelogsettings', 'sp_dropmergepartition', 'sp_dropmergepublication', 'sp_dropmergepullsubscription',
+ 'sp_dropmergesubscription', 'sp_dropmessage', 'sp_droppublication', 'sp_droppublisher', 'sp_droppullsubscription',
+ 'sp_dropremotelogin', 'sp_dropreplsymmetrickey', 'sp_droprole', 'sp_droprolemember', 'sp_dropserver', 'sp_dropsrvrolemember',
+ 'sp_dropsubscriber', 'sp_dropsubscription', 'sp_droptype', 'sp_dropuser', 'sp_dsninfo', 'sp_enable_heterogeneous_subscription',
+ 'sp_enableagentoffload', 'sp_enum_oledb_providers', 'sp_enumcustomresolvers', 'sp_enumdsn', 'sp_enumeratependingschemachanges',
+ 'sp_enumerrorlogs', 'sp_enumfullsubscribers', 'sp_enumoledbdatasources', 'sp_estimate_data_compression_savings',
+ 'sp_estimated_rowsize_reduction_for_vardecimal', 'sp_expired_subscription_cleanup', 'sp_filestream_force_garbage_collection',
+ 'sp_filestream_recalculate_container_size', 'sp_firstonly_bitmap', 'sp_fkeys', 'sp_flush_commit_table',
+ 'sp_flush_commit_table_on_demand', 'sp_foreign_keys_rowset', 'sp_foreign_keys_rowset_rmt', 'sp_foreign_keys_rowset2',
+ 'sp_foreign_keys_rowset3', 'sp_foreignkeys', 'sp_fulltext_catalog', 'sp_fulltext_column', 'sp_fulltext_database',
+ 'sp_fulltext_load_thesaurus_file', 'sp_fulltext_recycle_crawl_log', 'sp_fulltext_semantic_register_language_statistics_db',
+ 'sp_fulltext_semantic_unregister_language_statistics_db', 'sp_fulltext_service', 'sp_fulltext_table', 'sp_generate_agent_parameter',
+ 'sp_generatefilters', 'sp_get_distributor', 'sp_get_job_status_mergesubscription_agent', 'sp_get_mergepublishedarticleproperties',
+ 'sp_get_Oracle_publisher_metadata', 'sp_get_redirected_publisher', 'sp_getagentparameterlist', 'sp_getapplock',
+ 'sp_getdefaultdatatypemapping', 'sp_getmergedeletetype', 'sp_getProcessorUsage', 'sp_getpublisherlink',
+ 'sp_getqueuedarticlesynctraninfo', 'sp_getqueuedrows', 'sp_getsqlqueueversion', 'sp_getsubscription_status_hsnapshot',
+ 'sp_getsubscriptiondtspackagename', 'sp_gettopologyinfo', 'sp_getVolumeFreeSpace', 'sp_grant_publication_access', 'sp_grantdbaccess',
+ 'sp_grantlogin', 'sp_help', 'sp_help_agent_default', 'sp_help_agent_parameter', 'sp_help_agent_profile', 'sp_help_datatype_mapping',
+ 'sp_help_fulltext_catalog_components', 'sp_help_fulltext_catalogs', 'sp_help_fulltext_catalogs_cursor', 'sp_help_fulltext_columns',
+ 'sp_help_fulltext_columns_cursor', 'sp_help_fulltext_system_components', 'sp_help_fulltext_tables', 'sp_help_fulltext_tables_cursor',
+ 'sp_help_log_shipping_alert_job', 'sp_help_log_shipping_monitor', 'sp_help_log_shipping_monitor_primary',
+ 'sp_help_log_shipping_monitor_secondary', 'sp_help_log_shipping_primary_database', 'sp_help_log_shipping_primary_secondary',
+ 'sp_help_log_shipping_secondary_database', 'sp_help_log_shipping_secondary_primary', 'sp_help_peerconflictdetection',
+ 'sp_help_publication_access', 'sp_help_spatial_geography_histogram', 'sp_help_spatial_geography_index',
+ 'sp_help_spatial_geography_index_xml', 'sp_help_spatial_geometry_histogram', 'sp_help_spatial_geometry_index',
+ 'sp_help_spatial_geometry_index_xml', 'sp_helpallowmerge_publication', 'sp_helparticle', 'sp_helparticlecolumns', 'sp_helparticledts',
+ 'sp_helpconstraint', 'sp_helpdatatypemap', 'sp_helpdb', 'sp_helpdbfixedrole', 'sp_helpdevice', 'sp_helpdistpublisher',
+ 'sp_helpdistributiondb', 'sp_helpdistributor', 'sp_helpdistributor_properties', 'sp_helpdynamicsnapshot_job', 'sp_helpextendedproc',
+ 'sp_helpfile', 'sp_helpfilegroup', 'sp_helpindex', 'sp_helplanguage', 'sp_helplinkedsrvlogin', 'sp_helplogins', 'sp_helplogreader_agent',
+ 'sp_helpmergealternatepublisher', 'sp_helpmergearticle', 'sp_helpmergearticlecolumn', 'sp_helpmergearticleconflicts',
+ 'sp_helpmergeconflictrows', 'sp_helpmergedeleteconflictrows', 'sp_helpmergefilter', 'sp_helpmergelogfiles',
+ 'sp_helpmergelogfileswithdata', 'sp_helpmergelogsettings', 'sp_helpmergepartition', 'sp_helpmergepublication',
+ 'sp_helpmergepullsubscription', 'sp_helpmergesubscription', 'sp_helpntgroup', 'sp_helppeerrequests', 'sp_helppeerresponses',
+ 'sp_helppublication', 'sp_helppublication_snapshot', 'sp_helppublicationsync', 'sp_helppullsubscription', 'sp_helpqreader_agent',
+ 'sp_helpremotelogin', 'sp_helpreplfailovermode', 'sp_helpreplicationdb', 'sp_helpreplicationdboption', 'sp_helpreplicationoption',
+ 'sp_helprole', 'sp_helprolemember', 'sp_helprotect', 'sp_helpserver', 'sp_helpsort', 'sp_helpsrvrole', 'sp_helpsrvrolemember',
+ 'sp_helpstats', 'sp_helpsubscriberinfo', 'sp_helpsubscription', 'sp_helpsubscription_properties', 'sp_helpsubscriptionerrors',
+ 'sp_helptext', 'sp_helptracertokenhistory', 'sp_helptracertokens', 'sp_helptrigger', 'sp_helpuser', 'sp_helpxactsetjob',
+ 'sp_hexadecimal', 'sp_http_generate_wsdl_defaultcomplexorsimple', 'sp_http_generate_wsdl_defaultsimpleorcomplex',
+ 'sp_identitycolumnforreplication', 'sp_IH_LR_GetCacheData', 'sp_IHadd_sync_command', 'sp_IHarticlecolumn',
+ 'sp_IHget_loopback_detection', 'sp_IHScriptIdxFile', 'sp_IHScriptSchFile', 'sp_IHValidateRowFilter', 'sp_IHXactSetJob',
+ 'sp_indexcolumns_managed', 'sp_indexes', 'sp_indexes_100_rowset', 'sp_indexes_100_rowset2', 'sp_indexes_90_rowset',
+ 'sp_indexes_90_rowset_rmt', 'sp_indexes_90_rowset2', 'sp_indexes_managed', 'sp_indexes_rowset', 'sp_indexes_rowset_rmt',
+ 'sp_indexes_rowset2', 'sp_indexoption', 'sp_invalidate_textptr', 'sp_is_makegeneration_needed', 'sp_ivindexhasnullcols',
+ 'sp_kill_filestream_non_transacted_handles', 'sp_lightweightmergemetadataretentioncleanup', 'sp_link_publication',
+ 'sp_linkedservers', 'sp_linkedservers_rowset', 'sp_linkedservers_rowset2', 'sp_lock', 'sp_logshippinginstallmetadata',
+ 'sp_lookupcustomresolver', 'sp_mapdown_bitmap', 'sp_markpendingschemachange', 'sp_marksubscriptionvalidation', 'sp_mergearticlecolumn',
+ 'sp_mergecleanupmetadata', 'sp_mergedummyupdate', 'sp_mergemetadataretentioncleanup', 'sp_mergesubscription_cleanup',
+ 'sp_mergesubscriptionsummary', 'sp_monitor',
+ 'sp_objectfilegroup',
+ 'sp_oledb_database', 'sp_oledb_defdb', 'sp_oledb_deflang', 'sp_oledb_language', 'sp_oledb_ro_usrname', 'sp_oledbinfo', 'sp_ORbitmap',
+ 'sp_password', 'sp_peerconflictdetection_tableaug', 'sp_pkeys', 'sp_posttracertoken', 'sp_primary_keys_rowset',
+ 'sp_primary_keys_rowset_rmt', 'sp_primary_keys_rowset2', 'sp_primarykeys', 'sp_procedure_params_100_managed',
+ 'sp_procedure_params_100_rowset', 'sp_procedure_params_100_rowset2', 'sp_procedure_params_90_rowset', 'sp_procedure_params_90_rowset2',
+ 'sp_procedure_params_managed', 'sp_procedure_params_rowset', 'sp_procedure_params_rowset2', 'sp_procedures_rowset', 'sp_procedures_rowset2',
+ 'sp_processlogshippingmonitorhistory', 'sp_processlogshippingmonitorprimary', 'sp_processlogshippingmonitorsecondary',
+ 'sp_processlogshippingretentioncleanup', 'sp_procoption', 'sp_prop_oledb_provider', 'sp_provider_types_100_rowset',
+ 'sp_provider_types_90_rowset', 'sp_provider_types_rowset', 'sp_publication_validation', 'sp_publicationsummary', 'sp_publishdb',
+ 'sp_publisherproperty', 'sp_readerrorlog', 'sp_recompile', 'sp_redirect_publisher', 'sp_refresh_heterogeneous_publisher',
+ 'sp_refresh_log_shipping_monitor', 'sp_refreshsqlmodule', 'sp_refreshsubscriptions', 'sp_refreshview', 'sp_register_custom_scripting',
+ 'sp_registercustomresolver', 'sp_reinitmergepullsubscription', 'sp_reinitmergesubscription', 'sp_reinitpullsubscription',
+ 'sp_reinitsubscription', 'sp_releaseapplock', 'sp_remoteoption', 'sp_removedbreplication', 'sp_removedistpublisherdbreplication',
+ 'sp_removesrvreplication', 'sp_rename', 'sp_renamedb', 'sp_repladdcolumn', 'sp_replcleanupccsprocs', 'sp_repldeletequeuedtran',
+ 'sp_repldropcolumn', 'sp_replgetparsedddlcmd', 'sp_replica', 'sp_replication_agent_checkup', 'sp_replicationdboption', 'sp_replincrementlsn',
+ 'sp_replmonitorchangepublicationthreshold', 'sp_replmonitorhelpmergesession', 'sp_replmonitorhelpmergesessiondetail',
+ 'sp_replmonitorhelpmergesubscriptionmoreinfo', 'sp_replmonitorhelppublication', 'sp_replmonitorhelppublicationthresholds',
+ 'sp_replmonitorhelppublisher', 'sp_replmonitorhelpsubscription', 'sp_replmonitorrefreshjob', 'sp_replmonitorsubscriptionpendingcmds',
+ 'sp_replpostsyncstatus', 'sp_replqueuemonitor', 'sp_replrestart', 'sp_replrethrow', 'sp_replsetoriginator', 'sp_replshowcmds',
+ 'sp_replsqlqgetrows', 'sp_replsync', 'sp_requestpeerresponse', 'sp_requestpeertopologyinfo', 'sp_resetsnapshotdeliveryprogress',
+ 'sp_resetstatus', 'sp_resign_database', 'sp_resolve_logins', 'sp_restoredbreplication', 'sp_restoremergeidentityrange',
+ 'sp_resyncmergesubscription', 'sp_revoke_publication_access', 'sp_revokedbaccess', 'sp_revokelogin', 'sp_schemafilter', 'sp_schemata_rowset',
+ 'sp_script_reconciliation_delproc', 'sp_script_reconciliation_insproc', 'sp_script_reconciliation_sinsproc',
+ 'sp_script_reconciliation_vdelproc', 'sp_script_reconciliation_xdelproc', 'sp_script_synctran_commands', 'sp_scriptdelproc',
+ 'sp_scriptdynamicupdproc', 'sp_scriptinsproc', 'sp_scriptmappedupdproc', 'sp_scriptpublicationcustomprocs', 'sp_scriptsinsproc',
+ 'sp_scriptsubconflicttable', 'sp_scriptsupdproc', 'sp_scriptupdproc', 'sp_scriptvdelproc', 'sp_scriptvupdproc', 'sp_scriptxdelproc',
+ 'sp_scriptxupdproc', 'sp_sequence_get_range', 'sp_server_info', 'sp_serveroption', 'sp_setapprole', 'sp_SetAutoSAPasswordAndDisable',
+ 'sp_setdefaultdatatypemapping', 'sp_setnetname', 'sp_setOraclepackageversion', 'sp_setreplfailovermode', 'sp_setsubscriptionxactseqno',
+ 'sp_settriggerorder', 'sp_showcolv', 'sp_showlineage', 'sp_showpendingchanges', 'sp_showrowreplicainfo', 'sp_spaceused',
+ 'sp_sparse_columns_100_rowset', 'sp_special_columns', 'sp_special_columns_100', 'sp_special_columns_90', 'sp_sproc_columns',
+ 'sp_sproc_columns_100', 'sp_sproc_columns_90', 'sp_sqlexec', 'sp_srvrolepermission', 'sp_startmergepullsubscription_agent',
+ 'sp_startmergepushsubscription_agent', 'sp_startpublication_snapshot', 'sp_startpullsubscription_agent', 'sp_startpushsubscription_agent',
+ 'sp_statistics', 'sp_statistics_100', 'sp_statistics_rowset', 'sp_statistics_rowset2', 'sp_stopmergepullsubscription_agent',
+ 'sp_stopmergepushsubscription_agent', 'sp_stoppublication_snapshot', 'sp_stoppullsubscription_agent', 'sp_stoppushsubscription_agent',
+ 'sp_stored_procedures', 'sp_subscribe', 'sp_subscription_cleanup', 'sp_subscriptionsummary', 'sp_syspolicy_execute_policy',
+ 'sp_syspolicy_subscribe_to_policy_category', 'sp_syspolicy_unsubscribe_from_policy_category', 'sp_syspolicy_update_ddl_trigger',
+ 'sp_syspolicy_update_event_notification', 'sp_table_constraints_rowset', 'sp_table_constraints_rowset2', 'sp_table_privileges',
+ 'sp_table_privileges_ex', 'sp_table_privileges_rowset', 'sp_table_privileges_rowset_rmt', 'sp_table_privileges_rowset2',
+ 'sp_table_statistics_rowset', 'sp_table_statistics2_rowset', 'sp_table_type_columns_100', 'sp_table_type_columns_100_rowset',
+ 'sp_table_type_pkeys', 'sp_table_type_primary_keys_rowset', 'sp_table_types', 'sp_table_types_rowset', 'sp_table_validation',
+ 'sp_tablecollations', 'sp_tablecollations_100', 'sp_tablecollations_90', 'sp_tableoption', 'sp_tables', 'sp_tables_ex',
+ 'sp_tables_info_90_rowset', 'sp_tables_info_90_rowset_64', 'sp_tables_info_90_rowset2', 'sp_tables_info_90_rowset2_64',
+ 'sp_tables_info_rowset', 'sp_tables_info_rowset_64', 'sp_tables_info_rowset2', 'sp_tables_info_rowset2_64', 'sp_tables_rowset',
+ 'sp_tables_rowset_rmt', 'sp_tables_rowset2', 'sp_tableswc', 'sp_trace_getdata', 'sp_unbindefault', 'sp_unbindrule',
+ 'sp_unregister_custom_scripting', 'sp_unregistercustomresolver', 'sp_unsetapprole', 'sp_unsubscribe', 'sp_update_agent_profile',
+ 'sp_updateextendedproperty', 'sp_updatestats', 'sp_upgrade_log_shipping', 'sp_user_counter1', 'sp_user_counter10', 'sp_user_counter2',
+ 'sp_user_counter3', 'sp_user_counter4', 'sp_user_counter5', 'sp_user_counter6', 'sp_user_counter7', 'sp_user_counter8', 'sp_user_counter9',
+ 'sp_usertypes_rowset', 'sp_usertypes_rowset_rmt', 'sp_usertypes_rowset2', 'sp_validate_redirected_publisher',
+ 'sp_validate_replica_hosts_as_publishers', 'sp_validatecache', 'sp_validatelogins', 'sp_validatemergepublication',
+ 'sp_validatemergepullsubscription', 'sp_validatemergesubscription', 'sp_validlang', 'sp_validname', 'sp_verifypublisher', 'sp_views_rowset',
+ 'sp_views_rowset2', 'sp_vupgrade_mergeobjects', 'sp_vupgrade_mergetables', 'sp_vupgrade_replication', 'sp_vupgrade_replsecurity_metadata',
+ 'sp_who', 'sp_who2', 'sp_xml_schema_rowset', 'sp_xml_schema_rowset2',
+ ),
+ 6 => array(
+
+ // system MS procedures, marked brown.
+
+ 'sp_MS_marksystemobject', 'sp_MS_replication_installed', 'sp_MSacquireHeadofQueueLock',
+ 'sp_MSacquireserverresourcefordynamicsnapshot', 'sp_MSacquireSlotLock', 'sp_MSacquiresnapshotdeliverysessionlock',
+ 'sp_MSactivate_auto_sub', 'sp_MSactivatelogbasedarticleobject', 'sp_MSactivateprocedureexecutionarticleobject',
+ 'sp_MSadd_anonymous_agent', 'sp_MSadd_article', 'sp_MSadd_compensating_cmd', 'sp_MSadd_distribution_agent',
+ 'sp_MSadd_distribution_history', 'sp_MSadd_dynamic_snapshot_location', 'sp_MSadd_filteringcolumn', 'sp_MSadd_log_shipping_error_detail',
+ 'sp_MSadd_log_shipping_history_detail', 'sp_MSadd_logreader_agent', 'sp_MSadd_logreader_history', 'sp_MSadd_merge_agent',
+ 'sp_MSadd_merge_anonymous_agent', 'sp_MSadd_merge_history', 'sp_MSadd_merge_history90', 'sp_MSadd_merge_subscription',
+ 'sp_MSadd_mergereplcommand', 'sp_MSadd_mergesubentry_indistdb', 'sp_MSadd_publication', 'sp_MSadd_qreader_agent',
+ 'sp_MSadd_qreader_history', 'sp_MSadd_repl_alert', 'sp_MSadd_repl_command', 'sp_MSadd_repl_commands27hp', 'sp_MSadd_repl_error',
+ 'sp_MSadd_replcmds_mcit', 'sp_MSadd_replmergealert', 'sp_MSadd_snapshot_agent', 'sp_MSadd_snapshot_history', 'sp_MSadd_subscriber_info',
+ 'sp_MSadd_subscriber_schedule', 'sp_MSadd_subscription', 'sp_MSadd_subscription_3rd', 'sp_MSadd_tracer_history', 'sp_MSadd_tracer_token',
+ 'sp_MSaddanonymousreplica', 'sp_MSadddynamicsnapshotjobatdistributor', 'sp_MSaddguidcolumn', 'sp_MSaddguidindex', 'sp_MSaddinitialarticle',
+ 'sp_MSaddinitialpublication', 'sp_MSaddinitialschemaarticle', 'sp_MSaddinitialsubscription', 'sp_MSaddlightweightmergearticle',
+ 'sp_MSaddmergedynamicsnapshotjob', 'sp_MSaddmergetriggers', 'sp_MSaddmergetriggers_from_template', 'sp_MSaddmergetriggers_internal',
+ 'sp_MSaddpeerlsn', 'sp_MSaddsubscriptionarticles', 'sp_MSadjust_pub_identity', 'sp_MSagent_retry_stethoscope', 'sp_MSagent_stethoscope',
+ 'sp_MSallocate_new_identity_range', 'sp_MSalreadyhavegeneration', 'sp_MSanonymous_status', 'sp_MSarticlecleanup',
+ 'sp_MSbrowsesnapshotfolder', 'sp_MScache_agent_parameter', 'sp_MScdc_capture_job', 'sp_MScdc_cleanup_job', 'sp_MScdc_db_ddl_event',
+ 'sp_MScdc_ddl_event', 'sp_MScdc_logddl', 'sp_MSchange_article', 'sp_MSchange_distribution_agent_properties',
+ 'sp_MSchange_logreader_agent_properties', 'sp_MSchange_merge_agent_properties', 'sp_MSchange_mergearticle', 'sp_MSchange_mergepublication',
+ 'sp_MSchange_originatorid', 'sp_MSchange_priority', 'sp_MSchange_publication', 'sp_MSchange_retention', 'sp_MSchange_retention_period_unit',
+ 'sp_MSchange_snapshot_agent_properties', 'sp_MSchange_subscription_dts_info', 'sp_MSchangearticleresolver',
+ 'sp_MSchangedynamicsnapshotjobatdistributor', 'sp_MSchangedynsnaplocationatdistributor', 'sp_MSchangeobjectowner',
+ 'sp_MScheck_agent_instance', 'sp_MScheck_Jet_Subscriber', 'sp_MScheck_logicalrecord_metadatamatch', 'sp_MScheck_merge_subscription_count',
+ 'sp_MScheck_pub_identity', 'sp_MScheck_pull_access', 'sp_MScheck_snapshot_agent', 'sp_MScheck_subscription', 'sp_MScheck_subscription_expiry',
+ 'sp_MScheck_subscription_partition', 'sp_MScheck_tran_retention', 'sp_MScheckexistsgeneration', 'sp_MScheckexistsrecguid',
+ 'sp_MScheckfailedprevioussync', 'sp_MScheckidentityrange', 'sp_MScheckIsPubOfSub', 'sp_MSchecksharedagentforpublication',
+ 'sp_MSchecksnapshotstatus', 'sp_MScleanup_agent_entry', 'sp_MScleanup_conflict', 'sp_MScleanup_publication_ADinfo',
+ 'sp_MScleanup_subscription_distside_entry', 'sp_MScleanupdynamicsnapshotfolder', 'sp_MScleanupdynsnapshotvws', 'sp_MSCleanupForPullReinit',
+ 'sp_MScleanupmergepublisher_internal', 'sp_MSclear_dynamic_snapshot_location', 'sp_MSclearresetpartialsnapshotprogressbit',
+ 'sp_MScomputelastsentgen', 'sp_MScomputemergearticlescreationorder', 'sp_MScomputemergeunresolvedrefs', 'sp_MSconflicttableexists',
+ 'sp_MScreate_all_article_repl_views', 'sp_MScreate_article_repl_views', 'sp_MScreate_dist_tables', 'sp_MScreate_logical_record_views',
+ 'sp_MScreate_sub_tables', 'sp_MScreate_tempgenhistorytable', 'sp_MScreatedisabledmltrigger', 'sp_MScreatedummygeneration',
+ 'sp_MScreateglobalreplica', 'sp_MScreatelightweightinsertproc', 'sp_MScreatelightweightmultipurposeproc',
+ 'sp_MScreatelightweightprocstriggersconstraints', 'sp_MScreatelightweightupdateproc', 'sp_MScreatemergedynamicsnapshot',
+ 'sp_MScreateretry', 'sp_MSdbuseraccess', 'sp_MSdbuserpriv', 'sp_MSdefer_check', 'sp_MSdelete_tracer_history', 'sp_MSdeletefoldercontents',
+ 'sp_MSdeletemetadataactionrequest', 'sp_MSdeletepeerconflictrow', 'sp_MSdeleteretry', 'sp_MSdeletetranconflictrow', 'sp_MSdelgenzero',
+ 'sp_MSdelrow', 'sp_MSdelrowsbatch', 'sp_MSdelrowsbatch_downloadonly', 'sp_MSdelsubrows', 'sp_MSdelsubrowsbatch', 'sp_MSdependencies',
+ 'sp_MSdetect_nonlogged_shutdown', 'sp_MSdetectinvalidpeerconfiguration', 'sp_MSdetectinvalidpeersubscription', 'sp_MSdist_activate_auto_sub',
+ 'sp_MSdist_adjust_identity', 'sp_MSdistpublisher_cleanup', 'sp_MSdistribution_counters', 'sp_MSdistributoravailable',
+ 'sp_MSdodatabasesnapshotinitiation', 'sp_MSdopartialdatabasesnapshotinitiation', 'sp_MSdrop_6x_publication', 'sp_MSdrop_6x_replication_agent',
+ 'sp_MSdrop_anonymous_entry', 'sp_MSdrop_article', 'sp_MSdrop_distribution_agent', 'sp_MSdrop_distribution_agentid_dbowner_proxy',
+ 'sp_MSdrop_dynamic_snapshot_agent', 'sp_MSdrop_logreader_agent', 'sp_MSdrop_merge_agent', 'sp_MSdrop_merge_subscription',
+ 'sp_MSdrop_publication', 'sp_MSdrop_qreader_history', 'sp_MSdrop_snapshot_agent', 'sp_MSdrop_snapshot_dirs', 'sp_MSdrop_subscriber_info',
+ 'sp_MSdrop_subscription', 'sp_MSdrop_subscription_3rd', 'sp_MSdrop_tempgenhistorytable', 'sp_MSdroparticleconstraints',
+ 'sp_MSdroparticletombstones', 'sp_MSdropconstraints', 'sp_MSdropdynsnapshotvws', 'sp_MSdropfkreferencingarticle', 'sp_MSdropmergearticle',
+ 'sp_MSdropmergedynamicsnapshotjob', 'sp_MSdropretry', 'sp_MSdroptemptable', 'sp_MSdummyupdate', 'sp_MSdummyupdate_logicalrecord',
+ 'sp_MSdummyupdate90', 'sp_MSdummyupdatelightweight', 'sp_MSdynamicsnapshotjobexistsatdistributor', 'sp_MSenable_publication_for_het_sub',
+ 'sp_MSensure_single_instance', 'sp_MSenum_distribution', 'sp_MSenum_distribution_s', 'sp_MSenum_distribution_sd',
+ 'sp_MSenum_logicalrecord_changes', 'sp_MSenum_logreader', 'sp_MSenum_logreader_s', 'sp_MSenum_logreader_sd', 'sp_MSenum_merge',
+ 'sp_MSenum_merge_agent_properties', 'sp_MSenum_merge_s', 'sp_MSenum_merge_sd', 'sp_MSenum_merge_subscriptions',
+ 'sp_MSenum_merge_subscriptions_90_publication', 'sp_MSenum_merge_subscriptions_90_publisher', 'sp_MSenum_metadataaction_requests',
+ 'sp_MSenum_qreader', 'sp_MSenum_qreader_s', 'sp_MSenum_qreader_sd', 'sp_MSenum_replication_agents', 'sp_MSenum_replication_job',
+ 'sp_MSenum_replqueues', 'sp_MSenum_replsqlqueues', 'sp_MSenum_snapshot', 'sp_MSenum_snapshot_s', 'sp_MSenum_snapshot_sd',
+ 'sp_MSenum_subscriptions', 'sp_MSenumallpublications', 'sp_MSenumallsubscriptions', 'sp_MSenumarticleslightweight', 'sp_MSenumchanges',
+ 'sp_MSenumchanges_belongtopartition', 'sp_MSenumchanges_notbelongtopartition', 'sp_MSenumchangesdirect', 'sp_MSenumchangeslightweight',
+ 'sp_MSenumcolumns', 'sp_MSenumcolumnslightweight', 'sp_MSenumdeletes_forpartition', 'sp_MSenumdeleteslightweight', 'sp_MSenumdeletesmetadata',
+ 'sp_MSenumdistributionagentproperties', 'sp_MSenumerate_PAL', 'sp_MSenumgenerations', 'sp_MSenumgenerations90', 'sp_MSenumpartialchanges',
+ 'sp_MSenumpartialchangesdirect', 'sp_MSenumpartialdeletes', 'sp_MSenumpubreferences', 'sp_MSenumreplicas', 'sp_MSenumreplicas90',
+ 'sp_MSenumretries', 'sp_MSenumschemachange', 'sp_MSenumsubscriptions', 'sp_MSenumthirdpartypublicationvendornames',
+ 'sp_MSestimatemergesnapshotworkload', 'sp_MSestimatesnapshotworkload', 'sp_MSevalsubscriberinfo',
+ 'sp_MSevaluate_change_membership_for_all_articles_in_pubid', 'sp_MSevaluate_change_membership_for_pubid',
+ 'sp_MSevaluate_change_membership_for_row', 'sp_MSexecwithlsnoutput', 'sp_MSfast_delete_trans', 'sp_MSfetchAdjustidentityrange',
+ 'sp_MSfetchidentityrange', 'sp_MSfillupmissingcols', 'sp_MSfilterclause', 'sp_MSfix_6x_tasks', 'sp_MSfixlineageversions',
+ 'sp_MSFixSubColumnBitmaps', 'sp_MSfixupbeforeimagetables', 'sp_MSflush_access_cache', 'sp_MSforce_drop_distribution_jobs',
+ 'sp_MSforcereenumeration', 'sp_MSforeach_worker', 'sp_MSforeachdb', 'sp_MSforeachtable', 'sp_MSgenerateexpandproc', 'sp_MSget_agent_names',
+ 'sp_MSget_attach_state', 'sp_MSget_DDL_after_regular_snapshot', 'sp_MSget_dynamic_snapshot_location', 'sp_MSget_identity_range_info',
+ 'sp_MSget_jobstate', 'sp_MSget_last_transaction', 'sp_MSget_latest_peerlsn', 'sp_MSget_load_hint', 'sp_MSget_log_shipping_new_sessionid',
+ 'sp_MSget_logicalrecord_lineage', 'sp_MSget_max_used_identity', 'sp_MSget_min_seqno', 'sp_MSget_MSmerge_rowtrack_colinfo',
+ 'sp_MSget_new_xact_seqno', 'sp_MSget_oledbinfo', 'sp_MSget_partitionid_eval_proc', 'sp_MSget_publication_from_taskname',
+ 'sp_MSget_publisher_rpc', 'sp_MSget_repl_cmds_anonymous', 'sp_MSget_repl_commands', 'sp_MSget_repl_error', 'sp_MSget_session_statistics',
+ 'sp_MSget_shared_agent', 'sp_MSget_snapshot_history', 'sp_MSget_subscriber_partition_id', 'sp_MSget_subscription_dts_info',
+ 'sp_MSget_subscription_guid', 'sp_MSget_synctran_commands', 'sp_MSget_type_wrapper', 'sp_MSgetagentoffloadinfo', 'sp_MSgetalertinfo',
+ 'sp_MSgetalternaterecgens', 'sp_MSgetarticlereinitvalue', 'sp_MSgetchangecount', 'sp_MSgetconflictinsertproc', 'sp_MSgetconflicttablename',
+ 'sp_MSGetCurrentPrincipal', 'sp_MSgetdatametadatabatch', 'sp_MSgetdbversion', 'sp_MSgetdynamicsnapshotapplock',
+ 'sp_MSgetdynsnapvalidationtoken', 'sp_MSgetisvalidwindowsloginfromdistributor', 'sp_MSgetlastrecgen', 'sp_MSgetlastsentgen',
+ 'sp_MSgetlastsentrecgens', 'sp_MSgetlastupdatedtime', 'sp_MSgetlightweightmetadatabatch', 'sp_MSgetmakegenerationapplock',
+ 'sp_MSgetmakegenerationapplock_90', 'sp_MSgetmaxbcpgen', 'sp_MSgetmaxsnapshottimestamp', 'sp_MSgetmergeadminapplock',
+ 'sp_MSgetmetadata_changedlogicalrecordmembers', 'sp_MSgetmetadatabatch', 'sp_MSgetmetadatabatch90', 'sp_MSgetmetadatabatch90new',
+ 'sp_MSgetonerow', 'sp_MSgetonerowlightweight', 'sp_MSgetpeerconflictrow', 'sp_MSgetpeerlsns', 'sp_MSgetpeertopeercommands',
+ 'sp_MSgetpeerwinnerrow', 'sp_MSgetpubinfo', 'sp_MSgetreplicainfo', 'sp_MSgetreplicastate', 'sp_MSgetrowmetadata',
+ 'sp_MSgetrowmetadatalightweight', 'sp_MSGetServerProperties', 'sp_MSgetsetupbelong_cost', 'sp_MSgetsubscriberinfo',
+ 'sp_MSgetsupportabilitysettings', 'sp_MSgettrancftsrcrow', 'sp_MSgettranconflictrow', 'sp_MSgetversion', 'sp_MSgrantconnectreplication',
+ 'sp_MShaschangeslightweight', 'sp_MShasdbaccess', 'sp_MShelp_article', 'sp_MShelp_distdb', 'sp_MShelp_distribution_agentid',
+ 'sp_MShelp_identity_property', 'sp_MShelp_logreader_agentid', 'sp_MShelp_merge_agentid', 'sp_MShelp_profile', 'sp_MShelp_profilecache',
+ 'sp_MShelp_publication', 'sp_MShelp_repl_agent', 'sp_MShelp_replication_status', 'sp_MShelp_replication_table', 'sp_MShelp_snapshot_agent',
+ 'sp_MShelp_snapshot_agentid', 'sp_MShelp_subscriber_info', 'sp_MShelp_subscription', 'sp_MShelp_subscription_status', 'sp_MShelpcolumns',
+ 'sp_MShelpconflictpublications', 'sp_MShelpcreatebeforetable', 'sp_MShelpdestowner', 'sp_MShelpdynamicsnapshotjobatdistributor',
+ 'sp_MShelpfulltextindex', 'sp_MShelpfulltextscript', 'sp_MShelpindex', 'sp_MShelplogreader_agent', 'sp_MShelpmergearticles',
+ 'sp_MShelpmergeconflictcounts', 'sp_MShelpmergedynamicsnapshotjob', 'sp_MShelpmergeidentity', 'sp_MShelpmergeschemaarticles',
+ 'sp_MShelpobjectpublications', 'sp_MShelpreplicationtriggers', 'sp_MShelpsnapshot_agent', 'sp_MShelpsummarypublication',
+ 'sp_MShelptracertokenhistory', 'sp_MShelptracertokens', 'sp_MShelptranconflictcounts', 'sp_MShelptype', 'sp_MShelpvalidationdate',
+ 'sp_MSIfExistsSubscription', 'sp_MSindexspace', 'sp_MSinit_publication_access', 'sp_MSinit_subscription_agent', 'sp_MSinitdynamicsubscriber',
+ 'sp_MSinsert_identity', 'sp_MSinsertdeleteconflict', 'sp_MSinserterrorlineage', 'sp_MSinsertgenerationschemachanges', 'sp_MSinsertgenhistory',
+ 'sp_MSinsertlightweightschemachange', 'sp_MSinsertschemachange', 'sp_MSinvalidate_snapshot', 'sp_MSisnonpkukupdateinconflict',
+ 'sp_MSispeertopeeragent', 'sp_MSispkupdateinconflict', 'sp_MSispublicationqueued', 'sp_MSisreplmergeagent', 'sp_MSissnapshotitemapplied',
+ 'sp_MSkilldb', 'sp_MSlock_auto_sub', 'sp_MSlock_distribution_agent', 'sp_MSlocktable', 'sp_MSloginmappings', 'sp_MSmakearticleprocs',
+ 'sp_MSmakebatchinsertproc', 'sp_MSmakebatchupdateproc', 'sp_MSmakeconflictinsertproc', 'sp_MSmakectsview', 'sp_MSmakedeleteproc',
+ 'sp_MSmakedynsnapshotvws', 'sp_MSmakeexpandproc', 'sp_MSmakegeneration', 'sp_MSmakeinsertproc', 'sp_MSmakemetadataselectproc',
+ 'sp_MSmakeselectproc', 'sp_MSmakesystableviews', 'sp_MSmakeupdateproc', 'sp_MSmap_partitionid_to_generations', 'sp_MSmarkreinit',
+ 'sp_MSmatchkey', 'sp_MSmerge_alterschemaonly', 'sp_MSmerge_altertrigger', 'sp_MSmerge_alterview', 'sp_MSmerge_ddldispatcher',
+ 'sp_MSmerge_getgencount', 'sp_MSmerge_getgencur_public', 'sp_MSmerge_is_snapshot_required', 'sp_MSmerge_log_identity_range_allocations',
+ 'sp_MSmerge_parsegenlist', 'sp_MSmerge_upgrade_subscriber', 'sp_MSmergesubscribedb', 'sp_MSmergeupdatelastsyncinfo',
+ 'sp_MSneedmergemetadataretentioncleanup', 'sp_MSNonSQLDDL', 'sp_MSNonSQLDDLForSchemaDDL', 'sp_MSobjectprivs', 'sp_MSpeerapplyresponse',
+ 'sp_MSpeerapplytopologyinfo', 'sp_MSpeerconflictdetection_statuscollection_applyresponse',
+ 'sp_MSpeerconflictdetection_statuscollection_sendresponse', 'sp_MSpeerconflictdetection_topology_applyresponse', 'sp_MSpeerdbinfo',
+ 'sp_MSpeersendresponse', 'sp_MSpeersendtopologyinfo', 'sp_MSpeertopeerfwdingexec', 'sp_MSpost_auto_proc',
+ 'sp_MSpostapplyscript_forsubscriberprocs', 'sp_MSprep_exclusive', 'sp_MSprepare_mergearticle', 'sp_MSprofile_in_use',
+ 'sp_MSproxiedmetadata', 'sp_MSproxiedmetadatabatch', 'sp_MSproxiedmetadatalightweight', 'sp_MSpub_adjust_identity',
+ 'sp_MSpublication_access', 'sp_MSpublicationcleanup', 'sp_MSpublicationview', 'sp_MSquery_syncstates', 'sp_MSquerysubtype',
+ 'sp_MSrecordsnapshotdeliveryprogress', 'sp_MSreenable_check', 'sp_MSrefresh_anonymous', 'sp_MSrefresh_publisher_idrange',
+ 'sp_MSregenerate_mergetriggersprocs', 'sp_MSregisterdynsnapseqno', 'sp_MSregistermergesnappubid', 'sp_MSregistersubscription',
+ 'sp_MSreinit_failed_subscriptions', 'sp_MSreinit_hub', 'sp_MSreinit_subscription', 'sp_MSreinitoverlappingmergepublications',
+ 'sp_MSreleasedynamicsnapshotapplock', 'sp_MSreleasemakegenerationapplock', 'sp_MSreleasemergeadminapplock', 'sp_MSreleaseSlotLock',
+ 'sp_MSreleasesnapshotdeliverysessionlock', 'sp_MSremove_mergereplcommand', 'sp_MSremoveoffloadparameter', 'sp_MSrepl_agentstatussummary',
+ 'sp_MSrepl_backup_complete', 'sp_MSrepl_backup_start', 'sp_MSrepl_check_publisher', 'sp_MSrepl_createdatatypemappings',
+ 'sp_MSrepl_distributionagentstatussummary', 'sp_MSrepl_dropdatatypemappings', 'sp_MSrepl_enumarticlecolumninfo',
+ 'sp_MSrepl_enumpublications', 'sp_MSrepl_enumpublishertables', 'sp_MSrepl_enumsubscriptions', 'sp_MSrepl_enumtablecolumninfo',
+ 'sp_MSrepl_FixPALRole', 'sp_MSrepl_getdistributorinfo', 'sp_MSrepl_getpkfkrelation', 'sp_MSrepl_gettype_mappings',
+ 'sp_MSrepl_helparticlermo', 'sp_MSrepl_init_backup_lsns', 'sp_MSrepl_isdbowner', 'sp_MSrepl_IsLastPubInSharedSubscription',
+ 'sp_MSrepl_IsUserInAnyPAL', 'sp_MSrepl_linkedservers_rowset', 'sp_MSrepl_mergeagentstatussummary', 'sp_MSrepl_PAL_rolecheck',
+ 'sp_MSrepl_raiserror', 'sp_MSrepl_schema', 'sp_MSrepl_setNFR', 'sp_MSrepl_snapshot_helparticlecolumns',
+ 'sp_MSrepl_snapshot_helppublication', 'sp_MSrepl_startup_internal', 'sp_MSrepl_subscription_rowset', 'sp_MSrepl_testadminconnection',
+ 'sp_MSrepl_testconnection', 'sp_MSreplagentjobexists', 'sp_MSreplcheck_permission', 'sp_MSreplcheck_pull', 'sp_MSreplcheck_subscribe',
+ 'sp_MSreplcheck_subscribe_withddladmin', 'sp_MSreplcheckoffloadserver', 'sp_MSreplcopyscriptfile', 'sp_MSreplraiserror',
+ 'sp_MSreplremoveuncdir', 'sp_MSreplupdateschema', 'sp_MSrequestreenumeration', 'sp_MSrequestreenumeration_lightweight',
+ 'sp_MSreset_attach_state', 'sp_MSreset_queued_reinit', 'sp_MSreset_subscription', 'sp_MSreset_subscription_seqno',
+ 'sp_MSreset_synctran_bit', 'sp_MSreset_transaction', 'sp_MSresetsnapshotdeliveryprogress', 'sp_MSrestoresavedforeignkeys',
+ 'sp_MSretrieve_publication_attributes', 'sp_MSscript_article_view', 'sp_MSscript_dri', 'sp_MSscript_pub_upd_trig',
+ 'sp_MSscript_sync_del_proc', 'sp_MSscript_sync_del_trig', 'sp_MSscript_sync_ins_proc', 'sp_MSscript_sync_ins_trig',
+ 'sp_MSscript_sync_upd_proc', 'sp_MSscript_sync_upd_trig', 'sp_MSscriptcustomdelproc', 'sp_MSscriptcustominsproc',
+ 'sp_MSscriptcustomupdproc', 'sp_MSscriptdatabase', 'sp_MSscriptdb_worker', 'sp_MSscriptforeignkeyrestore', 'sp_MSscriptsubscriberprocs',
+ 'sp_MSscriptviewproc', 'sp_MSsendtosqlqueue', 'sp_MSset_dynamic_filter_options', 'sp_MSset_logicalrecord_metadata',
+ 'sp_MSset_new_identity_range', 'sp_MSset_oledb_prop', 'sp_MSset_snapshot_xact_seqno', 'sp_MSset_sub_guid',
+ 'sp_MSset_subscription_properties', 'sp_MSsetaccesslist', 'sp_MSsetalertinfo', 'sp_MSsetartprocs', 'sp_MSsetbit',
+ 'sp_MSsetconflictscript', 'sp_MSsetconflicttable', 'sp_MSsetcontext_bypasswholeddleventbit', 'sp_MSsetcontext_replagent',
+ 'sp_MSsetgentozero', 'sp_MSsetlastrecgen', 'sp_MSsetlastsentgen', 'sp_MSsetreplicainfo', 'sp_MSsetreplicaschemaversion',
+ 'sp_MSsetreplicastatus', 'sp_MSsetrowmetadata', 'sp_MSSetServerProperties', 'sp_MSsetsubscriberinfo', 'sp_MSsettopology',
+ 'sp_MSsetup_identity_range', 'sp_MSsetup_partition_groups', 'sp_MSsetup_use_partition_groups', 'sp_MSsetupbelongs',
+ 'sp_MSsetupnosyncsubwithlsnatdist', 'sp_MSsetupnosyncsubwithlsnatdist_cleanup', 'sp_MSsetupnosyncsubwithlsnatdist_helper',
+ 'sp_MSSharedFixedDisk', 'sp_MSSQLDMO70_version', 'sp_MSSQLDMO80_version', 'sp_MSSQLDMO90_version', 'sp_MSSQLOLE_version',
+ 'sp_MSSQLOLE65_version', 'sp_MSstartdistribution_agent', 'sp_MSstartmerge_agent', 'sp_MSstartsnapshot_agent',
+ 'sp_MSstopdistribution_agent', 'sp_MSstopmerge_agent', 'sp_MSstopsnapshot_agent', 'sp_MSsub_check_identity', 'sp_MSsub_set_identity',
+ 'sp_MSsubscription_status', 'sp_MSsubscriptionvalidated', 'sp_MStablechecks', 'sp_MStablekeys', 'sp_MStablerefs', 'sp_MStablespace',
+ 'sp_MStestbit', 'sp_MStran_ddlrepl', 'sp_MStran_is_snapshot_required', 'sp_MStrypurgingoldsnapshotdeliveryprogress', 'sp_MSuniquename',
+ 'sp_MSunmarkifneeded', 'sp_MSunmarkreplinfo', 'sp_MSunmarkschemaobject', 'sp_MSunregistersubscription', 'sp_MSupdate_agenttype_default',
+ 'sp_MSupdate_singlelogicalrecordmetadata', 'sp_MSupdate_subscriber_info', 'sp_MSupdate_subscriber_schedule',
+ 'sp_MSupdate_subscriber_tracer_history', 'sp_MSupdate_subscription', 'sp_MSupdate_tracer_history', 'sp_MSupdatecachedpeerlsn',
+ 'sp_MSupdategenerations_afterbcp', 'sp_MSupdategenhistory', 'sp_MSupdateinitiallightweightsubscription', 'sp_MSupdatelastsyncinfo',
+ 'sp_MSupdatepeerlsn', 'sp_MSupdaterecgen', 'sp_MSupdatereplicastate', 'sp_MSupdatesysmergearticles', 'sp_MSuplineageversion',
+ 'sp_MSuploadsupportabilitydata', 'sp_MSuselightweightreplication', 'sp_MSvalidate_dest_recgen', 'sp_MSvalidate_subscription',
+ 'sp_MSvalidate_wellpartitioned_articles', 'sp_MSvalidatearticle', 'sp_MSwritemergeperfcounter',
+
+ ),
+ 7 => array(
+ 'APPLY', 'FULL', 'ALL', 'AND', 'ANY', 'BETWEEN', 'CROSS',
+ 'EXISTS', 'IN', 'INNER', 'JOIN', 'LIKE', 'NOT', 'NULL', 'OR', 'OUTER', 'SOME'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '!', '!=', '%', '&', '&&', '(', ')', '*', '+', '-', '/', '<', '<<', '<=', ';', '::', ',', '.',
+ '<=>', '<>', '=', '>', '>=', '>>', '^', '|', '||', '~'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #FF00FF;',
+ 2 => 'color: #0000FF;',
+ 3 => 'color: #AF0000;',
+ 4 => 'color: #00AF00;',
+ 5 => 'color: #AF0000;',
+ 6 => 'color: #AF0000;',
+ 7 => 'color: #808080;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #009E00;',
+ 'MULTI' => 'color: #009E00;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #808080;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #FF0000;',
+ 'HARD' => 'color: #FF0000;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 'HARD' => 'color: #FF0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #808080;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #cc3333;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ // variables
+ 0 => "[\\@]+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 2 => array(
+ 'DISALLOWED_BEFORE' => "(?<![@\[a-zA-Z0-9\$_\|\#|^&'\"])",
+ 'DISALLOWED_AFTER' => "(?![\]a-zA-Z0-9_\|%\-&;'\"])",
+ ),
+ 7 => array(
+ 'DISALLOWED_BEFORE' => "(?<![@\[a-zA-Z0-9\$_\|\#|^&'\"])",
+ 'DISALLOWED_AFTER' => "(?![\]a-zA-Z0-9_\|%\-&;'\"])",
+ ),
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/twig.php b/platform/www/vendor/geshi/geshi/src/geshi/twig.php
new file mode 100644
index 0000000..62b193d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/twig.php
@@ -0,0 +1,286 @@
+<?php
+/*************************************************************************************
+ * twig.php
+ * ----------
+ * Author: Keyvan Akbary (keyvan@kiwwito.com)
+ * Copyright: (c) 2011 Keyvan Akbary (http://www.kiwwito.com/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/12/05
+ *
+ * Twig template language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2012/09/28 (1.9.0 by José Andrés Puertas y Javier Eguiluz)
+ * - Added new tags, filters and functions
+ * - Added regexps for variables, objects and properties
+ * - Lots of other minor tweaks (delimites, comments, ...)
+ *
+ * 2011/12/05 (1.0.0 by Keyvan Akbary)
+ * - Initial Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Twig',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('{#' => '#}'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ //TWIG
+ //Tags
+ 1 => array(
+ 'autoescape',
+ 'endautoescape',
+ 'block',
+ 'endblock',
+ 'do',
+ 'embed',
+ 'endembed',
+ 'extends',
+ 'filter',
+ 'endfilter',
+ 'for',
+ 'endfor',
+ 'from',
+ 'if',
+ 'else',
+ 'elseif',
+ 'endif',
+ 'import',
+ 'include',
+ 'macro',
+ 'endmacro',
+ 'raw',
+ 'endraw',
+ 'sandbox',
+ 'set',
+ 'endset',
+ 'spaceless',
+ 'endspaceless',
+ 'use',
+ 'verbatim',
+ 'endverbatim',
+ 'trans',
+ 'endtrans',
+ 'transchoice',
+ 'endtranschoice'
+ ),
+ //Filters
+ 2 => array(
+ 'abs',
+ 'batch',
+ 'capitalize',
+ 'convert_encoding',
+ 'date',
+ 'date_modify',
+ 'default',
+ 'escape',
+ 'first',
+ 'format',
+ 'join',
+ 'json_encode',
+ 'keys',
+ 'last',
+ 'length',
+ 'lower',
+ 'merge',
+ 'nl2br',
+ 'number_format',
+ 'replace',
+ 'reverse',
+ 'slice',
+ 'sort',
+ 'split',
+ 'striptags',
+ 'title',
+ 'trim',
+ 'upper',
+ 'url_encode'
+ ),
+ //Functions
+ 3 => array(
+ 'attribute',
+ 'cycle',
+ 'dump',
+ 'parent',
+ 'random',
+ 'range',
+ 'source',
+ 'template_from_string'
+ ),
+ //Tests
+ 4 => array(
+ 'constant',
+ 'defined',
+ 'divisibleby',
+ 'empty',
+ 'even',
+ 'iterable',
+ 'null',
+ 'odd',
+ 'sameas'
+ ),
+ //Operators
+ 5 => array(
+ 'in',
+ 'is',
+ 'and',
+ 'b-and',
+ 'or',
+ 'b-or',
+ 'b-xor',
+ 'not',
+ 'into',
+ 'starts with',
+ 'ends with',
+ 'matches'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '{{',
+ '}}',
+ '{%',
+ '%}',
+ '+',
+ '-',
+ '/',
+ '/',
+ '*',
+ '**', //Math operators
+ '==',
+ '!=',
+ '<',
+ '>',
+ '>=',
+ '<=',
+ '===', //Logic operators
+ '..',
+ '|',
+ '~',
+ '[',
+ ']',
+ '.',
+ '?',
+ ':',
+ '(',
+ ')', //Other
+ '=' //HTML (attributes)
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ //Twig
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0600FF;', //Tags
+ 2 => 'color: #008000;', //Filters
+ 3 => 'color: #0600FF;', //Functions
+ 4 => 'color: #804040;', //Tests
+ 5 => 'color: #008000;'
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: #008080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #D36900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #D36900;'
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #009000;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #00aaff;',
+ 1 => 'color: #00aaff;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://twig.sensiolabs.org/doc/tags/{FNAMEL}.html',
+ 2 => 'http://twig.sensiolabs.org/doc/filters/{FNAMEL}.html',
+ 3 => 'http://twig.sensiolabs.org/doc/functions/{FNAMEL}.html',
+ 4 => 'http://twig.sensiolabs.org/doc/tests/{FNAMEL}.html',
+ 5 => '',
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ ),
+ 'REGEXPS' => array(
+ 0 => array(
+ GESHI_SEARCH => "([[:space:]])([a-zA-Z_][a-zA-Z0-9_]*)",
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+ 1 => array(
+ GESHI_SEARCH => "\.([a-zA-Z_][a-zA-Z0-9_]*)",
+ GESHI_REPLACE => '.\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+ 'SCRIPT_DELIMITERS' => array(
+ 0 => array(
+ '{{' => '}}',
+ '{%' => '%}'
+ ),
+ 1 => array(
+ '{#' => '#}',
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true,
+ 2 => true
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array()
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/typoscript.php b/platform/www/vendor/geshi/geshi/src/geshi/typoscript.php
new file mode 100644
index 0000000..4fa2fd9
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/typoscript.php
@@ -0,0 +1,298 @@
+<?php
+/*************************************************************************************
+ * typoscript.php
+ * --------
+ * Author: Jan-Philipp Halle (typo3@jphalle.de)
+ * Copyright: (c) 2005 Jan-Philipp Halle (http://www.jphalle.de/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/07/29
+ *
+ * TypoScript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/07/11 (1.0.8)
+ * - Michiel Roos <geshi@typofree.org> Complete rewrite
+ * 2005/07/29 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * <things-to-do>
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'TypoScript',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(2 => '/(?<!(#|\'|"))(?:#(?!(?:[a-fA-F0-9]{6}|[a-fA-F0-9]{3}))[^\n#]+|#{2}[^\n#]+|#{7,999}[^\n]+)/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ // Conditions: http://documentation.typo3.org/documentation/tsref/conditions/
+ 1 => array(
+ 'browser', 'compatVersion', 'dayofmonth', 'dayofweek', 'device',
+ 'globalString', 'globalVars', 'hostname', 'hour',
+ 'ip', 'language', 'loginUser', 'loginuser', 'minute',
+ 'month', 'PIDinRootline', 'PIDupinRootline',
+ 'system', 'treelevel', 'useragent', 'userFunc',
+ 'usergroup', 'version'
+ ),
+
+ // Functions: http://documentation.typo3.org/documentation/tsref/functions/
+ 2 => array(
+ 'addParams', 'encapsLines', 'filelink', 'HTMLparser',
+ 'HTMLparser_tags', 'if', 'imageLinkWrap',
+ 'imgResource', 'makelinks', 'numRows', 'parseFunc',
+ 'select', 'split', 'stdWrap', 'tableStyle', 'tags',
+ 'textStyle', 'typolink'
+ ),
+
+ // Toplevel objects: http://documentation.typo3.org/documentation/tsref/tlo-objects/
+ 3 => array(
+ 'CARRAY', 'CONFIG', 'CONSTANTS', 'FE_DATA', 'FE_TABLE', 'FRAME',
+ 'FRAMESET', 'META', 'PAGE', 'plugin'
+ ),
+
+ // Content Objects (cObject) : http://documentation.typo3.org/documentation/tsref/cobjects/
+ 4 => array(
+ 'CASE', 'CLEARGIF', 'COA', 'COA_INT', 'COBJ_ARRAY', 'COLUMNS',
+ 'CONTENT', 'CTABLE', 'EDITPANEL', 'FILE', 'FORM',
+ 'HMENU', 'HRULER', 'HTML', 'IMAGE', 'IMGTEXT',
+ 'IMG_RESOURCE', 'LOAD_REGISTER', 'MULTIMEDIA',
+ 'OTABLE', 'PHP_SCRIPT', 'PHP_SCRIPT_EXT',
+ 'PHP_SCRIPT_INT', 'RECORDS', 'RESTORE_REGISTER',
+ 'SEARCHRESULT', 'TEMPLATE', 'TEXT', 'USER',
+ 'USER_INT'
+ ),
+
+ // GIFBUILDER toplevel link: http://documentation.typo3.org/documentation/tsref/gifbuilder/
+ 5 => array(
+ 'GIFBUILDER',
+ ),
+
+ // GIFBUILDER: http://documentation.typo3.org/documentation/tsref/gifbuilder/
+ // skipped fields: IMAGE, TEXT
+ // NOTE! the IMAGE and TEXT field already are linked in group 4, they
+ // cannot be linked twice . . . . unfortunately
+ 6 => array(
+ 'ADJUST', 'BOX', 'CROP', 'EFFECT', 'EMBOSS',
+ 'IMGMAP', 'OUTLINE', 'SCALE', 'SHADOW',
+ 'WORKAREA'
+ ),
+
+ // MENU Objects: http://documentation.typo3.org/documentation/tsref/menu/
+ 7 => array(
+ 'GMENU', 'GMENU_FOLDOUT', 'GMENU_LAYERS', 'IMGMENU',
+ 'IMGMENUITEM', 'JSMENU', 'JSMENUITEM', 'TMENU',
+ 'TMENUITEM', 'TMENU_LAYERS'
+ ),
+
+ // MENU common properties: http://documentation.typo3.org/documentation/tsref/menu/common-properties/
+ 8 => array(
+ 'alternativeSortingField', 'begin', 'debugItemConf',
+ 'imgNameNotRandom', 'imgNamePrefix',
+ 'itemArrayProcFunc', 'JSWindow', 'maxItems',
+ 'minItems', 'overrideId', 'sectionIndex',
+ 'showAccessRestrictedPages', 'submenuObjSuffixes'
+ ),
+
+ // MENU item states: http://documentation.typo3.org/documentation/tsref/menu/item-states/
+ 9 => array(
+ 'ACT', 'ACTIFSUB', 'ACTIFSUBRO', 'ACTRO', 'CUR', 'CURIFSUB',
+ 'CURIFSUBRO', 'CURRO', 'IFSUB', 'IFSUBRO', 'NO',
+ 'SPC', 'USERDEF1', 'USERDEF1RO', 'USERDEF2',
+ 'USERDEF2RO', 'USR', 'USRRO'
+ ),
+ ),
+
+ // Does not include '-' because of stuff like htmlTag_langKey = en-GB and
+ // lib.nav-sub
+ 'SYMBOLS' => array(
+ 0 => array(
+ '|',
+ '+', '*', '/', '%',
+ '!', '&&', '^',
+ '<', '>', '=',
+ '?', ':',
+ '.'
+ ),
+ 1 => array(
+ '(', ')', '{', '}', '[', ']'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true,
+ 9 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #ed7d14;',
+ 2 => 'font-weight: bold;',
+ 3 => 'color: #990000; font-weight: bold;',
+ 4 => 'color: #990000; font-weight: bold;',
+ 5 => 'color: #990000; font-weight: bold;',
+ 6 => 'color: #990000; font-weight: bold;',
+ 7 => 'color: #990000; font-weight: bold;',
+ 8 => 'font-weight: bold;',
+ 9 => 'color: #990000; font-weight: bold;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #aaa; font-style: italic;',
+ 2 => 'color: #aaa; font-style: italic;',
+ 'MULTI' => 'color: #aaa; font-style: italic;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ac14aa;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0000e0; font-weight: bold;',
+ 2 => 'color: #0000e0; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933; font-weight: bold;',
+ // Set this to the same value as brackets above
+ 1 => 'color: #009900; font-weight: bold;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #009900;',
+ 1 => 'color: #009900; font-weight: bold;',
+ 2 => 'color: #3366CC;',
+ 3 => 'color: #000066; font-weight: bold;',
+ 4 => 'color: #ed7d14;',
+ 5 => 'color: #000066; font-weight: bold;',
+ 6 => 'color: #009900;',
+ 7 => 'color: #3366CC;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => 'http://documentation.typo3.org/documentation/tsref/conditions/{FNAME}/',
+ 2 => 'http://documentation.typo3.org/documentation/tsref/functions/{FNAME}/',
+ 3 => 'http://documentation.typo3.org/documentation/tsref/tlo-objects/{FNAME}/',
+ 4 => 'http://documentation.typo3.org/documentation/tsref/cobjects/{FNAME}/',
+ 5 => 'http://documentation.typo3.org/documentation/tsref/gifbuilder/',
+ 6 => 'http://documentation.typo3.org/documentation/tsref/gifbuilder/{FNAME}/',
+ 7 => 'http://documentation.typo3.org/documentation/tsref/menu/{FNAME}/',
+ 8 => 'http://documentation.typo3.org/documentation/tsref/menu/common-properties/',
+ 9 => 'http://documentation.typo3.org/documentation/tsref/menu/item-states/'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ // xhtml tag
+ 2 => array(
+ GESHI_SEARCH => '(&lt;)([a-zA-Z\\/][^\\/\\\x7C]*?)(&gt;)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 's',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+
+ // Constant
+ 0 => array(
+ GESHI_SEARCH => '(\{)(\$[a-zA-Z_\.]+[a-zA-Z0-9_\.]*)(\})',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => '\\3'
+ ),
+
+ // Constant dollar sign
+ 1 => array(
+ GESHI_SEARCH => '(\$)([a-zA-Z_\.]+[a-zA-Z0-9_\.]*)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '\\2'
+ ),
+
+ // extension keys / tables: (static|user|ttx|tx|tt|fe)_something[_something]
+ 3 => array(
+ GESHI_SEARCH => '(plugin\.|[^\.]\b)((?:static|user|ttx|tx|tt|fe)(?:_[0-9A-Za-z_]+?)\b)',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+
+ // conditions and controls
+ 4 => array(
+ GESHI_SEARCH => '(\[)(globalVar|global|end)\b',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+
+ // lowlevel setup and constant objects
+ 5 => array(
+ GESHI_SEARCH => '([^\.\$-\{]\b)(cObj|field|config|content|file|frameset|includeLibs|lib|page|plugin|register|resources|sitemap|sitetitle|styles|temp|tt_content|tt_news|types|xmlnews)\b',
+ GESHI_REPLACE => '\\2',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '\\1',
+ GESHI_AFTER => ''
+ ),
+
+ // markers
+ 6 => array(
+ GESHI_SEARCH => '(###[^#]+###)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+
+ // hex color codes
+ 7 => array(
+ GESHI_SEARCH => '(#[a-fA-F0-9]{6}\b|#[a-fA-F0-9]{3}\b)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/unicon.php b/platform/www/vendor/geshi/geshi/src/geshi/unicon.php
new file mode 100644
index 0000000..736c29d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/unicon.php
@@ -0,0 +1,208 @@
+<?php
+/*************************************************************************************
+ * unicon.php
+ * --------
+ * Author: Matt Oates (mattoates@gmail.com)
+ * Copyright: (c) 2010 Matt Oates (http://mattoates.co.uk)
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/04/20
+ *
+ * Unicon the Unified Extended Dialect of Icon language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2010/04/24 (0.0.0.2)
+ * - Validated with Geshi langcheck.php FAILED due to preprocessor keywords looking like symbols
+ * - Hard wrapped to improve readability
+ * 2010/04/20 (0.0.0.1)
+ * - First Release
+ *
+ * TODO (updated 2010/04/20)
+ * -------------------------
+ * - Do the &amp; need replacing with &?
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Unicon (Unified Extended Dialect of Icon)',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', '\''),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'break', 'case', 'class', 'continue', 'create', 'default', 'do',
+ 'else', 'end', 'every', 'fail', 'for', 'if', 'import', 'initial', 'initially',
+ 'invocable', 'link', 'method', 'next', 'not', 'of', 'package', 'procedure', 'record',
+ 'repeat', 'return', 'switch', 'suspend', 'then', 'to', 'until', 'while'
+ ),
+ 2 => array(
+ 'global', 'local', 'static'
+ ),
+ 3 => array(
+ 'allocated', 'ascii', 'clock', 'collections',
+ 'column', 'cset', 'current', 'date', 'dateline', 'digits',
+ 'dump', 'e', 'error', 'errornumber', 'errortext',
+ 'errorvalue', 'errout', 'eventcode', 'eventsource', 'eventvalue',
+ 'fail', 'features', 'file', 'host', 'input', 'lcase',
+ 'letters', 'level', 'line', 'main', 'now', 'null',
+ 'output', 'phi', 'pi', 'pos', 'progname', 'random',
+ 'regions', 'source', 'storage', 'subject', 'syserr', 'time',
+ 'trace', 'ucase', 'version', 'col', 'control', 'interval',
+ 'ldrag', 'lpress', 'lrelease', 'mdrag', 'meta', 'mpress',
+ 'mrelease', 'rdrag', 'resize', 'row', 'rpress', 'rrelease',
+ 'shift', 'window', 'x', 'y'
+ ),
+ 4 => array(
+ 'abs', 'acos', 'any', 'args', 'asin', 'atan', 'bal', 'center', 'char',
+ 'chmod', 'close', 'cofail', 'collect', 'copy', 'cos', 'cset', 'ctime', 'dbcolumns',
+ 'dbdriver', 'dbkeys', 'dblimits', 'dbproduction', 'dbtables', 'delay', 'delete', 'detab',
+ 'display', 'dtor', 'entab', 'errorclear', 'event', 'eventmask', 'EvGet', 'exit', 'exp',
+ 'fetch', 'fieldnames', 'find', 'flock', 'flush', 'function', 'get', 'getch', 'getche',
+ 'getenv', 'gettimeofday', 'globalnames', 'gtime', 'iand', 'icom', 'image', 'insert',
+ 'integer', 'ior', 'ishift', 'ixor', 'key', 'left', 'list', 'load', 'loadfunc',
+ 'localnames', 'log', 'many', 'map', 'match', 'member', 'mkdir', 'move', 'name', 'numeric',
+ 'open', 'opmask', 'ord', 'paramnames', 'parent', 'pipe', 'pop', 'pos', 'proc', 'pull',
+ 'push', 'put', 'read', 'reads', 'real', 'receive', 'remove', 'rename', 'repl', 'reverse',
+ 'right', 'rmdir', 'rtod', 'runerr', 'seek', 'select', 'send', 'seq', 'serial', 'set',
+ 'setenv', 'sort', 'sortf', 'sql', 'sqrt', 'stat', 'staticnames', 'stop', 'string', 'system', 'tab',
+ 'table', 'tan', 'trap', 'trim', 'truncate', 'type', 'upto', 'utime', 'variable', 'where',
+ 'write', 'writes'
+ ),
+ 5 => array(
+ 'Active', 'Alert', 'Bg', 'Clip', 'Clone', 'Color', 'ColorValue',
+ 'CopyArea', 'Couple', 'DrawArc', 'DrawCircle', 'DrawCurve', 'DrawCylinder', 'DrawDisk',
+ 'DrawImage', 'DrawLine', 'DrawPoint', 'DrawPolygon', 'DrawRectangle', 'DrawSegment',
+ 'DrawSphere', 'DrawString', 'DrawTorus', 'EraseArea', 'Event', 'Fg', 'FillArc',
+ 'FillCircle', 'FillPolygon', 'FillRectangle', 'Font', 'FreeColor', 'GotoRC', 'GotoXY',
+ 'IdentifyMatrix', 'Lower', 'MatrixMode', 'NewColor', 'PaletteChars', 'PaletteColor',
+ 'PaletteKey', 'Pattern', 'Pending', 'Pixel', 'PopMatrix', 'PushMatrix', 'PushRotate',
+ 'PushScale', 'PushTranslate', 'QueryPointer', 'Raise', 'ReadImage', 'Refresh', 'Rotate',
+ 'Scale', 'Texcoord', 'TextWidth', 'Texture', 'Translate', 'Uncouple', 'WAttrib',
+ 'WDefault', 'WFlush', 'WindowContents', 'WriteImage', 'WSync'
+ ),
+ 6 => array(
+ 'define', 'include', 'ifdef', 'ifndef', 'else', 'endif', 'error',
+ 'line', 'undef'
+ ),
+ 7 => array(
+ '_V9', '_AMIGA', '_ACORN', '_CMS', '_MACINTOSH', '_MSDOS_386',
+ '_MS_WINDOWS_NT', '_MSDOS', '_MVS', '_OS2', '_POR', 'T', '_UNIX', '_POSIX', '_DBM',
+ '_VMS', '_ASCII', '_EBCDIC', '_CO_EXPRESSIONS', '_CONSOLE_WINDOW', '_DYNAMIC_LOADING',
+ '_EVENT_MONITOR', '_EXTERNAL_FUNCTIONS', '_KEYBOARD_FUNCTIONS', '_LARGE_INTEGERS',
+ '_MULTITASKING', '_PIPES', '_RECORD_IO', '_SYSTEM_FUNCTION', '_MESSAGING', '_GRAPHICS',
+ '_X_WINDOW_SYSTEM', '_MS_WINDOWS', '_WIN32', '_PRESENTATION_MGR', '_ARM_FUNCTIONS',
+ '_DOS_FUNCTIONS'
+ ),
+ 8 => array(
+ 'line')
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '(', ')', '{', '}', '[', ']', '+', '-', '*', '/', '\\', '%', '=', '<', '>', '!', '^',
+ '&', '|', '?', ':', ';', ',', '.', '~', '@'
+ ),
+ 2 => array(
+ '$(', '$)', '$<', '$>'
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ 5 => true,
+ 6 => true,
+ 7 => true,
+ 8 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #b1b100;',
+ 3 => 'color: #b1b100;',
+ 4 => 'color: #b1b100;',
+ 5 => 'color: #b1b100;',
+ 6 => 'color: #b1b100;',
+ 7 => 'color: #b1b100;',
+ 8 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(1 => '.'),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 3 => array(
+ 'DISALLOWED_BEFORE' => '(?<=&amp;)'
+ ),
+ 4 => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9_\"\'])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_\"\'])"
+ ),
+ 6 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\$)'
+ ),
+ 8 => array(
+ 'DISALLOWED_BEFORE' => '(?<=#)'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/upc.php b/platform/www/vendor/geshi/geshi/src/geshi/upc.php
new file mode 100644
index 0000000..228940d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/upc.php
@@ -0,0 +1,268 @@
+<?php
+/*************************************************************************************
+ * upc.php
+ * -----
+ * Author: Viraj Sinha (viraj@indent.com)
+ * Contributors:
+ * - Nigel McNie (nigel@geshi.org)
+ * - Jack Lloyd (lloyd@randombit.net)
+ * - Michael Mol (mikemol@gmail.com)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/04
+ *
+ * UPC language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2011/06/14 (1.0.8.11)
+ * - This file is a revision of c.php with UPC keywords added
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'UPC',
+ 'COMMENT_SINGLE' => array(1 => '//', 2 => '#'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Multiline-continued single-line comments
+ 1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Multiline-continued preprocessor define
+ 2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[\\\\abfnrtv\'\"?\n]#i",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#"
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'if', 'return', 'while', 'case', 'continue', 'default',
+ 'do', 'else', 'for', 'switch', 'goto',
+
+ 'upc_forall', 'upc_barrier', 'upc_notify', 'upc_wait', 'upc_fence'
+ ),
+ 2 => array(
+ 'null', 'false', 'break', 'true', 'function', 'enum', 'extern', 'inline'
+ ),
+ 3 => array(
+ // assert.h
+ 'assert',
+
+ //complex.h
+ 'cabs', 'cacos', 'cacosh', 'carg', 'casin', 'casinh', 'catan',
+ 'catanh', 'ccos', 'ccosh', 'cexp', 'cimag', 'cis', 'clog', 'conj',
+ 'cpow', 'cproj', 'creal', 'csin', 'csinh', 'csqrt', 'ctan', 'ctanh',
+
+ //ctype.h
+ 'digittoint', 'isalnum', 'isalpha', 'isascii', 'isblank', 'iscntrl',
+ 'isdigit', 'isgraph', 'islower', 'isprint', 'ispunct', 'isspace',
+ 'isupper', 'isxdigit', 'toascii', 'tolower', 'toupper',
+
+ //inttypes.h
+ 'imaxabs', 'imaxdiv', 'strtoimax', 'strtoumax', 'wcstoimax',
+ 'wcstoumax',
+
+ //locale.h
+ 'localeconv', 'setlocale',
+
+ //math.h
+ 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh', 'exp',
+ 'fabs', 'floor', 'frexp', 'ldexp', 'log', 'log10', 'modf', 'pow',
+ 'sin', 'sinh', 'sqrt', 'tan', 'tanh',
+
+ //setjmp.h
+ 'longjmp', 'setjmp',
+
+ //signal.h
+ 'raise',
+
+ //stdarg.h
+ 'va_arg', 'va_copy', 'va_end', 'va_start',
+
+ //stddef.h
+ 'offsetof',
+
+ //stdio.h
+ 'clearerr', 'fclose', 'fdopen', 'feof', 'ferror', 'fflush', 'fgetc',
+ 'fgetpos', 'fgets', 'fopen', 'fprintf', 'fputc', 'fputchar',
+ 'fputs', 'fread', 'freopen', 'fscanf', 'fseek', 'fsetpos', 'ftell',
+ 'fwrite', 'getc', 'getch', 'getchar', 'gets', 'perror', 'printf',
+ 'putc', 'putchar', 'puts', 'remove', 'rename', 'rewind', 'scanf',
+ 'setbuf', 'setvbuf', 'snprintf', 'sprintf', 'sscanf', 'tmpfile',
+ 'tmpnam', 'ungetc', 'vfprintf', 'vfscanf', 'vprintf', 'vscanf',
+ 'vsprintf', 'vsscanf',
+
+ //stdlib.h
+ 'abort', 'abs', 'atexit', 'atof', 'atoi', 'atol', 'bsearch',
+ 'calloc', 'div', 'exit', 'free', 'getenv', 'itoa', 'labs', 'ldiv',
+ 'ltoa', 'malloc', 'qsort', 'rand', 'realloc', 'srand', 'strtod',
+ 'strtol', 'strtoul', 'system',
+
+ //string.h
+ 'memchr', 'memcmp', 'memcpy', 'memmove', 'memset', 'strcat',
+ 'strchr', 'strcmp', 'strcoll', 'strcpy', 'strcspn', 'strerror',
+ 'strlen', 'strncat', 'strncmp', 'strncpy', 'strpbrk', 'strrchr',
+ 'strspn', 'strstr', 'strtok', 'strxfrm',
+
+ //time.h
+ 'asctime', 'clock', 'ctime', 'difftime', 'gmtime', 'localtime',
+ 'mktime', 'strftime', 'time',
+
+ //wchar.h
+ 'btowc', 'fgetwc', 'fgetws', 'fputwc', 'fputws', 'fwide',
+ 'fwprintf', 'fwscanf', 'getwc', 'getwchar', 'mbrlen', 'mbrtowc',
+ 'mbsinit', 'mbsrtowcs', 'putwc', 'putwchar', 'swprintf', 'swscanf',
+ 'ungetwc', 'vfwprintf', 'vswprintf', 'vwprintf', 'wcrtomb',
+ 'wcscat', 'wcschr', 'wcscmp', 'wcscoll', 'wcscpy', 'wcscspn',
+ 'wcsftime', 'wcslen', 'wcsncat', 'wcsncmp', 'wcsncpy', 'wcspbrk',
+ 'wcsrchr', 'wcsrtombs', 'wcsspn', 'wcsstr', 'wcstod', 'wcstok',
+ 'wcstol', 'wcstoul', 'wcsxfrm', 'wctob', 'wmemchr', 'wmemcmp',
+ 'wmemcpy', 'wmemmove', 'wmemset', 'wprintf', 'wscanf',
+
+ //wctype.h
+ 'iswalnum', 'iswalpha', 'iswcntrl', 'iswctype', 'iswdigit',
+ 'iswgraph', 'iswlower', 'iswprint', 'iswpunct', 'iswspace',
+ 'iswupper', 'iswxdigit', 'towctrans', 'towlower', 'towupper',
+ 'wctrans', 'wctype'
+ ),
+ 4 => array(
+ 'auto', 'char', 'const', 'double', 'float', 'int', 'long',
+ 'register', 'short', 'signed', 'sizeof', 'static', 'struct',
+ 'typedef', 'union', 'unsigned', 'void', 'volatile', 'wchar_t',
+
+ 'int8', 'int16', 'int32', 'int64',
+ 'uint8', 'uint16', 'uint32', 'uint64',
+
+ 'int_fast8_t', 'int_fast16_t', 'int_fast32_t', 'int_fast64_t',
+ 'uint_fast8_t', 'uint_fast16_t', 'uint_fast32_t', 'uint_fast64_t',
+
+ 'int_least8_t', 'int_least16_t', 'int_least32_t', 'int_least64_t',
+ 'uint_least8_t', 'uint_least16_t', 'uint_least32_t', 'uint_least64_t',
+
+ 'int8_t', 'int16_t', 'int32_t', 'int64_t',
+ 'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t',
+
+ 'intmax_t', 'uintmax_t', 'intptr_t', 'uintptr_t',
+ 'size_t', 'off_t',
+
+ 'upc_lock_t', 'shared', 'strict', 'relaxed', 'upc_blocksizeof',
+ 'upc_localsizeof', 'upc_elemsizeof'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']',
+ '+', '-', '*', '/', '%',
+ '=', '<', '>',
+ '!', '^', '&', '|',
+ '?', ':',
+ ';', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #993333;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #339933;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 1 => 'color: #000099; font-weight: bold;',
+ 2 => 'color: #660099; font-weight: bold;',
+ 3 => 'color: #660099; font-weight: bold;',
+ 4 => 'color: #660099; font-weight: bold;',
+ 5 => 'color: #006699; font-weight: bold;',
+ 'HARD' => '',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;',
+ GESHI_NUMBER_BIN_PREFIX_0B => 'color: #208080;',
+ GESHI_NUMBER_OCT_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_HEX_PREFIX => 'color: #208080;',
+ GESHI_NUMBER_FLT_SCI_SHORT => 'color:#800080;',
+ GESHI_NUMBER_FLT_SCI_ZERO => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI_F => 'color:#800080;',
+ GESHI_NUMBER_FLT_NONSCI => 'color:#800080;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.opengroup.org/onlinepubs/009695399/functions/{FNAMEL}.html',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/urbi.php b/platform/www/vendor/geshi/geshi/src/geshi/urbi.php
new file mode 100644
index 0000000..236a331
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/urbi.php
@@ -0,0 +1,198 @@
+<?php
+/*************************************************************************************
+ * urbi.php
+ * -------
+ * Author: Alexandre Morgand (morgand.alexandre@gmail.com)
+ * Copyright: (c) 2011 Morgand (http://gostai.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2011/09/10
+ *
+ * Urbi language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Urbi',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Multiline-continued single-line comments
+ 1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ //Multiline-continued preprocessor define
+ 2 => '/#(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ // Urbi warning.
+ 3 => "#\[[0-9a-f]{8}:warning\].*#",
+ // Urbi message from echo.
+ 4 => '#\[[0-9a-f]{8}\] \*\*\*.*#',
+ // Urbi error message.
+ 6 => '#\[[0-9a-f]{8}:error\].*#',
+ // Urbi system message.
+ 5 => '#\[00.*\].*#',
+ // Nested comment. Max depth 4.
+ 7 => '#\/\*(.|\n)*\/\*(.|\n)*\*\/(.|\n)*\*\/#',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(
+ 0 => '"',
+ 1 => '\'',
+ ),
+ // For Urbi, disable escape char is better.
+ 'ESCAPE_CHAR' => '\\',
+ 'ESCAPE_REGEXP' => array(
+ //Simple Single Char Escapes
+ 1 => "#\\\\[abfnrtv\\\'\"?\n]#",
+ //Hexadecimal Char Specs
+ 2 => "#\\\\x[\da-fA-F]{2}#",
+ //Hexadecimal Char Specs
+ 3 => "#\\\\u[\da-fA-F]{4}#",
+ //Hexadecimal Char Specs
+ 4 => "#\\\\U[\da-fA-F]{8}#",
+ //Octal Char Specs
+ 5 => "#\\\\[0-7]{1,3}#",
+ ),
+ 'NUMBERS' =>
+ GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE | GESHI_NUMBER_BIN_PREFIX_0B |
+ GESHI_NUMBER_OCT_PREFIX | GESHI_NUMBER_HEX_PREFIX | GESHI_NUMBER_FLT_NONSCI |
+ GESHI_NUMBER_FLT_NONSCI_F | GESHI_NUMBER_FLT_SCI_SHORT | GESHI_NUMBER_FLT_SCI_ZERO,
+ 'KEYWORDS' => array(
+ // Condition keywords.
+ 1 => array(
+ 'at', 'at;', 'at|', 'at&', 'at,', 'break', 'call', 'case', 'catch', 'continue',
+ 'do', 'else', 'every', 'every&', 'every,', 'every;', 'every|', 'for', 'for&',
+ 'for,', 'for;', 'foreach', 'for|', 'freezeif', 'goto', 'if', 'in', 'loop',
+ 'loop&', 'loop,', 'loop;', 'loop|', 'or_eq', 'stopif', 'switch', 'try',
+ 'waituntil', 'when', 'whenever', 'while', 'while&', 'while,', 'while;',
+ 'while|', 'throw', 'onleave', 'watch', 'return', 'and_eq', 'default', 'finally',
+ 'timeout', 'xor_eq'
+ ),
+ // Type.
+ 2 => array(
+ 'virtual', 'using', 'namespace', 'inline', 'protected', 'private', 'public',
+ 'typename', 'typeid', 'class', 'const_cast', 'dynamic_cast', 'friend',
+ 'template', 'enum', 'static_cast', 'reinterpret_cast', 'mutable', 'explicit'
+ ),
+ // Standard function.
+ 3 => array(
+ 'this', 'sizeof', 'delete', 'assert', 'isdef', 'compl', 'detach',
+ 'disown', '__HERE__', 'asm'
+ ),
+ // Type.
+ 4 => array(
+ 'char', 'const', 'double', 'int', 'long', 'typedef', 'union',
+ 'unsigned', 'var', 'short', 'wchar_t', 'volatile', 'signed', 'bool',
+ 'float', 'struct', 'auto', 'register', 'static', 'extern', 'function',
+ 'export', 'external', 'internal', 'closure', 'BIN'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 0 => array('(', ')', '{', '}', '[', ']'),
+ 1 => array('<', '>','=', '!=', '==', '==='),
+ 2 => array('+', '-', '*', '/', '%', 'bitand', 'bitor', 'xor'),
+ 3 => array('!', '^', '&', '|'),
+ 4 => array('?', ':', ';')
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #0000dd;',
+ 4 => 'color: #0000ff;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666;',
+ 2 => 'color: #339900;',
+ 3 => 'color: #d46b0f;',
+ 4 => 'color: #20b537;',
+ 5 => 'color: #73776f;',
+ 6 => 'color: #a71616;',
+ 7 => 'color: #666666;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #ff0000;',
+ 1 => 'color: #ff0000;',
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #7a0874; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;',
+ 1 => 'color: #007788;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000dd;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #007788;',
+ 2 => 'color: #007788;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;',
+ 1 => 'color: #0000f8;',
+ 2 => 'color: #000040;',
+ 3 => 'color: #000040; font-weight: bold;',
+ 4 => 'color: #008080;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000dd',
+ 1 => 'color: #0000dd;',
+ 2 => 'color: #0000dd;',
+ 3 => 'color: #0000dd;',
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::',
+ // FIXME: add -> splitter.
+ ),
+ 'REGEXPS' => array(
+ 0 => '0x[0-9a-fA-F]([0-9a-fA-F_]*[0-9a-fA-F])*',
+ 1 => '[0-9]([0-9_]*[0-9])*(e|E)(-|\+)?[0-9]([0-9_]*[0-9])*',
+ 2 => '[0-9]([0-9_]*[0-9])*(min|s|ms|h|d)',
+ 3 => '[0-9]+_([0-9_])*[0-9]',
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/uscript.php b/platform/www/vendor/geshi/geshi/src/geshi/uscript.php
new file mode 100644
index 0000000..eb385db
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/uscript.php
@@ -0,0 +1,297 @@
+<?php
+/*************************************************************************************
+ * uscript.php
+ * ---------------------------------
+ * Author: pospi (pospi@spadgos.com)
+ * Copyright: (c) 2007 pospi (http://pospi.spadgos.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/05/21
+ *
+ * UnrealScript language file for GeSHi.
+ *
+ * Comments:
+ * * Main purpose at this time is for Unreal Engine 2 / 2.5
+ * * Mostly taken from UltraEdit unrealScript wordfile.
+ *
+ * CHANGES
+ * -------
+ * 2007/05/21 (1.0.8.10)
+ * - First Release
+ *
+ * TODO (updated 2007/05/21)
+ * -------------------------
+ * * Update to feature any UE3 classes / keywords when UT3 comes out
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Unreal Script',
+ 'COMMENT_SINGLE' => array(
+ 1 => '//',
+ 2 => '#'
+ ),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array( //declaration keywords
+ 'simulated', 'state', 'class', 'function', 'event', 'var', 'local',
+ 'ignores', 'globalconfig', 'config', 'abstract', 'nativereplication', 'native',
+ 'auto', 'coerce', 'const', 'default',
+ 'defaultproperties',
+ 'enum', 'extends', 'expands', 'final', 'guid', 'latent', 'localized',
+ 'new', 'noexport', 'operator', 'preoperator', 'optional', 'out',
+ 'private', 'public', 'protected', 'reliable', 'replication',
+ 'singular', 'static', 'struct', 'transient', 'unreliable',
+ 'hidedropdown', 'cacheexempt', 'exec', 'delegate', 'import', 'placeable', 'exportstructs'
+ ),
+ 2 => array( //control flow keywords
+ 'for', 'while', 'do', 'if', 'else', 'switch', 'case', 'return', 'break', 'continue',
+ 'begin', 'loop', 'assert',
+ 'foreach', 'AllActors', 'DynamicActors', 'ChildActors', 'BasedActors', 'TouchingActors',
+ 'TraceActors', 'RadiusActors', 'VisibleActors', 'CollidingActors', 'VisibleCollidingActors'
+ ),
+ 3 => array( //global (object) functions
+ 'log', 'warn', 'rot', 'vect', 'Rand', 'Min', 'Max', 'Clamp', 'Abs', 'Sin', 'ASin',
+ 'Cos', 'ACos', 'Tan', 'ATan', 'Exp', 'Loge', 'Sqrt', 'Square', 'FRand', 'FMin', 'FMax', 'FClamp',
+ 'Lerp', 'Smerp', 'Ceil', 'Round', 'VSize', 'Normal', 'Invert', 'VRand', 'MirrorVectorByNormal',
+ 'GetAxes', 'GetUnAxes', 'RotRand', 'OrthoRotation', 'Normalize', 'ClockwiseFrom',
+ 'Len', 'InStr', 'Mid', 'Left', 'Right', 'Caps', 'Chr', 'Asc', 'Locs',
+ 'Divide', 'Split', 'StrCmp', 'Repl', 'Eval',
+ 'InterpCurveEval', 'InterpCurveGetOutputRange', 'InterpCurveGetInputDomain',
+ 'QuatProduct', 'QuatInvert', 'QuatRotateVector', 'QuatFindBetween', 'QuatFromAxisAndAngle',
+ 'QuatFromRotator', 'QuatToRotator', 'QuatSlerp',
+ 'Localize', 'GotoState', 'IsInState', 'GetStateName',
+ 'ClassIsChildOf', 'IsA', 'Enable', 'Disable',
+ 'GetPropertyText', 'SetPropertyText', 'GetEnum', 'DynamicLoadObject', 'FindObject',
+ 'SaveConfig', 'ClearConfig', 'StaticSaveConfig', 'ResetConfig', 'StaticClearConfig',
+ 'GetPerObjectNames', 'RandRange', 'StopWatch', 'IsOnConsole', 'IsSoaking',
+ 'PlatformIsMacOS', 'PlatformIsUnix', 'PlatformIsWindows', 'PlatformIs64Bit',
+ 'BeginState', 'EndState', 'Created', 'AllObjects', 'GetReferencers', 'GetItemName',
+ 'ReplaceText', 'EatStr'
+ ),
+ 4 => array( //common almost-global (actor) functions
+ 'ClientMessage', 'ConsoleCommand', 'CopyObjectToClipboard', 'TextToSpeech',
+ 'Error', 'Sleep', 'SetCollision', 'SetCollisionSize', 'SetDrawScale', 'SetDrawScale3D',
+ 'SetStaticMesh', 'SetDrawType', 'Move', 'SetLocation', 'SetRotation',
+ 'SetRelativeLocation', 'SetRelativeRotation', 'MoveSmooth', 'AutonomousPhysics',
+ 'SetBase', 'SetOwner', 'IsJoinedTo', 'GetMeshName', 'PlayAnim', 'LoopAnim', 'TweenAnim',
+ 'IsAnimating', 'FinishAnim', 'HasAnim', 'StopAnimating', 'FreezeFrameAt', 'SetAnimFrame',
+ 'IsTweening', 'AnimStopLooping', 'AnimEnd', 'LinkSkelAnim', 'LinkMesh', 'BoneRefresh',
+ 'GetBoneCoords', 'GetBoneRotation', 'GetRootLocation', 'GetRootRotation', 'AttachToBone',
+ 'DetachFromBone', 'SetBoneScale', 'UpdateURL', 'GetURLOption', 'SetPhysics', 'KAddImpulse',
+ 'KImpact', 'KApplyForce', 'Clock', 'UnClock', 'Destroyed', 'GainedChild', 'LostChild',
+ 'Tick', 'PostNetReceive', 'ClientTrigger', 'Trigger', 'UnTrigger', 'BeginEvent', 'EndEvent',
+ 'Timer', 'HitWall', 'Falling', 'Landed', 'ZoneChange', 'PhysicsVolumeChange', 'Touch',
+ 'PostTouch', 'UnTouch', 'Bump', 'BaseChange', 'Attach', 'Detach', 'SpecialHandling',
+ 'EncroachingOn', 'EncroachedBy', 'RanInto', 'FinishedInterpolation', 'EndedRotation',
+ 'UsedBy', 'FellOutOfWorld', 'KilledBy', 'TakeDamage', 'HealDamage', 'Trace', 'FastTrace',
+ 'TraceThisActor', 'spawn', 'Destroy', 'TornOff', 'SetTimer', 'PlaySound', 'PlayOwnedSound',
+ 'GetSoundDuration', 'MakeNoise', 'BeginPlay', 'GetAllInt', 'RenderOverlays', 'RenderTexture',
+ 'PreBeginPlay', 'PostBeginPlay', 'PostNetBeginPlay', 'HurtRadius', 'Reset', 'Crash'
+ ),
+ 5 => array( //data types
+ 'none', 'null',
+ 'float', 'int', 'bool', 'byte', 'char', 'double', 'iterator', 'name', 'string', //primitive
+ 'plane', 'rotator', 'vector', 'spline', 'coords', 'Quat', 'Range', 'RangeVector', //structs
+ 'Scale', 'Color', 'Box', 'IntBox', 'FloatBox', 'BoundingVolume', 'Matrix', 'InterpCurvePoint',
+ 'InterpCurve', 'CompressedPosition', 'TMultiMap', 'PointRegion',
+ 'KRigidBodyState', 'KSimParams', 'AnimRep', 'FireProperties',
+ 'lodmesh', 'skeletalmesh', 'mesh', 'StaticMesh', 'MeshInstance', //3d resources
+ 'sound', //sound resources
+ 'material', 'texture', 'combiner', 'modifier', 'ColorModifier', 'FinalBlend', //2d resources
+ 'MaterialSequence', 'MaterialSwitch', 'OpacityModifier', 'TexModifier', 'TexEnvMap',
+ 'TexCoordSource', 'TexMatrix', 'TexOscillator', 'TexPanner', 'TexRotator', 'TexScaler',
+ 'RenderedMaterial', 'BitmapMaterial', 'ScriptedTexture', 'ShadowBitmapMaterial', 'Cubemap',
+ 'FractalTexture', 'FireTexture', 'IceTexture', 'WaterTexture', 'FluidTexture', 'WaveTexture',
+ 'WetTexture', 'ConstantMaterial', 'ConstantColor', 'FadeColor', 'ParticleMaterial',
+ 'ProjectorMaterial', 'Shader', 'TerrainMaterial', 'VertexColor'
+ ),
+ 6 => array( //misc keywords
+ 'false', 'true', 'self', 'super', 'MaxInt', 'Pi'
+ ),
+ 7 => array( //common actor enums & variables
+ 'DT_None', 'DT_Sprite', 'DT_Mesh', 'DT_Brush', 'DT_RopeSprite',
+ 'DT_VerticalSprite', 'DT_TerraForm', 'DT_SpriteAnimOnce', 'DT_StaticMesh', 'DT_DrawType',
+ 'DT_Particle', 'DT_AntiPortal', 'DT_FluidSurface',
+ 'PHYS_None', 'PHYS_Walking', 'PHYS_Falling', 'PHYS_Swimming', 'PHYS_Flying',
+ 'PHYS_Rotating', 'PHYS_Projectile', 'PHYS_Interpolating', 'PHYS_MovingBrush', 'PHYS_Spider',
+ 'PHYS_Trailer', 'PHYS_Ladder', 'PHYS_RootMotion', 'PHYS_Karma', 'PHYS_KarmaRagDoll',
+ 'PHYS_Hovering', 'PHYS_CinMotion',
+ 'ROLE_None', 'ROLE_DumbProxy', 'ROLE_SimulatedProxy',
+ 'ROLE_AutonomousProxy', 'ROLE_Authority',
+ 'STY_None', 'STY_Normal', 'STY_Masked', 'STY_Translucent', 'STY_Modulated', 'STY_Alpha',
+ 'STY_Additive', 'STY_Subtractive', 'STY_Particle', 'STY_AlphaZ',
+ 'OCCLUSION_None', 'OCCLUSION_BSP', 'OCCLUSION_Default', 'OCCLUSION_StaticMeshes',
+ 'SLOT_None', 'SLOT_Misc', 'SLOT_Pain', 'SLOT_Interact', 'SLOT_Ambient', 'SLOT_Talk',
+ 'SLOT_Interface', 'MTRAN_None', 'MTRAN_Instant', 'MTRAN_Segue', 'MTRAN_Fade',
+ 'MTRAN_FastFade', 'MTRAN_SlowFade',
+
+ 'DrawType', 'Physics', 'Owner', 'Base', 'Level', 'Game', 'Instigator', 'RemoteRole', 'Role',
+ 'LifeSpan', 'Tag', 'Event', 'Location', 'Rotation', 'Velocity', 'Acceleration',
+ 'RelativeLocation', 'RelativeRotation', 'DrawScale', 'DrawScale3D', 'Skins', 'Style',
+ 'SoundVolume', 'SoundPitch', 'SoundRadius', 'TransientSoundVolume', 'TransientSoundRadius',
+ 'CollisionRadius', 'CollisionHeight', 'Mass', 'Buoyancy', 'RotationRate', 'DesiredRotation'
+ ),
+ 8 => array( //common non-actor uscript classes
+ 'Object',
+ 'CacheManager', 'CameraEffect', 'Canvas', 'CheatManager', 'Commandlet', 'DecoText', 'GUI',
+ 'InteractionMaster', 'Interactions', 'Interaction', 'KarmaParamsCollision', 'KarmaParamsRBFull',
+ 'KarmaParamsSkel', 'KarmaParams', 'LevelSummary', 'Locale', 'Manifest', 'MaterialFactory',
+ 'MeshObject', 'ObjectPool', 'Pallete',
+ 'ParticleEmitter', 'MeshEmitter', 'BeamEmitter', 'SpriteEmitter', 'SparkEmitter', 'TrailEmitter',
+ 'Player', 'PlayerInput', 'PlayInfo', 'ReachSpec', 'Resource', 'LatentScriptedAction', 'ScriptedAction',
+ 'speciesType', 'StreamBase', 'Stream', 'EditorEngine', 'Engine', 'Time', 'WeaponFire',
+ 'WebApplication', 'WebRequest', 'WebResponse', 'WebSkin', 'xPawnGibGroup', 'xPawnSoundGroup',
+ 'xUtil'
+ ),
+ 9 => array( //common actor-based uscript classes
+ 'Actor',
+ 'Controller', 'AIController', 'ScriptedController', 'Bot', 'xBot',
+ 'PlayerController', 'UnrealPlayer', 'xPlayer',
+ 'DamageType', 'WeaponDamageType', 'Effects', 'Emitter', 'NetworkEmitter',
+ 'Gib', 'HUD', 'HudBase', 'Info', 'FluidSurfaceInfo', 'Combo',
+ 'GameInfo', 'UnrealMPGameInfo', 'DeathMatch', 'TeamGame', 'CTFGame',
+ 'xCTFGame', 'xBombingRun', 'xDoubleDom', 'xTeamGame',
+ 'ASGameInfo', 'Invasion', 'ONSOnslaughtGame', 'xDeathmatch',
+ 'Mutator', 'Inventory', 'Ammunition', 'KeyInventory', 'Powerups', 'Armor', 'Weapon',
+ 'InventoryAttachment', 'WeaponAttachment',
+ 'KActor', 'KConstraint', 'KBSJoint', 'KCarWheelJoint', 'KConeLimit', 'KHinge', 'KTire',
+ 'KVehicleFactory', 'Keypoint', 'AIScript', 'ScriptedSequence', 'ScriptedTrigger',
+ 'AmbientSound', 'Light', 'SpotLight', 'SunLight', 'TriggerLight',
+ 'MeshEffect', 'NavigationPoint', 'GameObjective', 'DestroyableObjective',
+ 'PathNode', 'FlyingPathNode', 'RoadPathNode', 'InventorySpot', 'PlayerStart',
+ 'Pawn', 'Vehicle', 'UnrealPawn', 'xPawn', 'Monster', 'ASVehicle', 'KVehicle', 'KCar',
+ 'ONSWeaponPawn', 'SVehicle', 'ONSVehicle', 'ONSChopperCraft', 'ONSHoverCraft',
+ 'ONSPlaneCraft', 'ONSTreadCraft', 'ONSWheeledCraft',
+ 'Pickup', 'Ammo', 'UTAmmoPickup', 'ArmorPickup', 'KeyPickup', 'TournamentPickup',
+ 'Projectile', 'Projector', 'DynamicProjector', 'ShadowProjector', 'xScorch',
+ 'xEmitter', 'xPickupBase', 'xProcMesh', 'xWeatherEffect', 'PhysicsVolume', 'Volume'
+ ),
+ 10 => array( //symbol-like operators
+ 'dot','cross'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '+','-','=','/','*','-','%','>','<','&','^','!','|','`','(',')','[',']','{','}',
+ '<<','>>','$','@'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false,
+ 7 => false,
+ 8 => false,
+ 9 => false,
+ 10 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF;',
+ 2 => 'color: #0000FF;',
+ 3 => 'color: #0066AA;',
+ 4 => 'color: #0088FF;',
+ 5 => 'color: #E000E0;',
+ 6 => 'color: #900000;',
+ 7 => 'color: #888800;',
+ 8 => 'color: #AA6600;',
+ 9 => 'color: #FF8800;',
+ 10 => 'color: #0000FF;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008080; font-style: italic;',
+ 2 => 'color: #000000; font-weight: bold;',
+ 'MULTI' => 'color: #008080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #999999;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #669966;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #E000E0;',
+ 1 => 'color: #E000E0;'
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => '',
+ 7 => '',
+ 8 => 'http://wiki.beyondunreal.com/wiki?search={FNAME}',
+ 9 => 'http://wiki.beyondunreal.com/wiki?search={FNAME}',
+ 10 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array('.'),
+ 'REGEXPS' => array( //handle template-style variable definitions
+ 0 => array(
+ GESHI_SEARCH => '(class\s*)<(\s*(\w+)\s*)>',
+ GESHI_REPLACE => "\${1}",
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => "< \${3} >"
+ ),
+ 1 => array(
+ GESHI_SEARCH => '(array\s*)<(\s*(\w+)\s*)>',
+ GESHI_REPLACE => "\${1}",
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => "< \${3} >"
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 10 => array(
+ 'DISALLOWED_BEFORE' => '(?<!<)(?=DOT>)'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/vala.php b/platform/www/vendor/geshi/geshi/src/geshi/vala.php
new file mode 100644
index 0000000..d69354d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/vala.php
@@ -0,0 +1,149 @@
+<?php
+/*************************************************************************************
+ * vala.php
+ * ----------
+ * Author: Nicolas Joseph (nicolas.joseph@valaide.org)
+ * Copyright: (c) 2009 Nicolas Joseph
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/04/29
+ *
+ * Vala language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Vala',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ //Using and Namespace directives (basic support)
+ //Please note that the alias syntax for using is not supported
+ 3 => '/(?:(?<=using[\\n\\s])|(?<=namespace[\\n\\s]))[\\n\\s]*([a-zA-Z0-9_]+\\.)*[a-zA-Z0-9_]+[\n\s]*(?=[;=])/i'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'HARDQUOTE' => array('"""'),
+ 'HARDESCAPE' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'as', 'abstract', 'base', 'break', 'case', 'catch', 'const',
+ 'construct', 'continue', 'default', 'delete', 'dynamic', 'do',
+ 'else', 'ensures', 'extern', 'false', 'finally', 'for', 'foreach',
+ 'get', 'if', 'in', 'inline', 'internal', 'lock', 'namespace',
+ 'null', 'out', 'override', 'private', 'protected', 'public', 'ref',
+ 'requires', 'return', 'set', 'static', 'switch', 'this', 'throw',
+ 'throws', 'true', 'try', 'using', 'value', 'var', 'virtual',
+ 'volatile', 'void', 'yield', 'yields', 'while'
+ ),
+ 2 => array(
+ '#elif', '#endif', '#else', '#if'
+ ),
+ 3 => array(
+ 'is', 'new', 'owned', 'sizeof', 'typeof', 'unchecked', 'unowned', 'weak'
+ ),
+ 4 => array(
+ 'bool', 'char', 'class', 'delegate', 'double', 'enum',
+ 'errordomain', 'float', 'int', 'int8', 'int16', 'int32', 'int64',
+ 'interface', 'long', 'short', 'signal', 'size_t', 'ssize_t',
+ 'string', 'struct', 'uchar', 'uint', 'uint8', 'uint16', 'uint32',
+ 'ulong', 'unichar', 'ushort'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '+', '-', '*', '?', '=', '/', '%', '&', '>', '<', '^', '!', ':', ';',
+ '(', ')', '{', '}', '[', ']', '|'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true,
+ 4 => true,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0600FF;',
+ 2 => 'color: #FF8000; font-weight: bold;',
+ 3 => 'color: #008000;',
+ 4 => 'color: #FF0000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008080; font-style: italic;',
+ 3 => 'color: #008080;',
+ 'MULTI' => 'color: #008080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #008080; font-weight: bold;',
+ 'HARD' => 'color: #008080; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #666666;',
+ 'HARD' => 'color: #666666;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #FF0000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #0000FF;',
+ 2 => 'color: #0000FF;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'DISALLOWED_BEFORE' => "(?<![a-zA-Z0-9\$_\|\#>|^])",
+ 'DISALLOWED_AFTER' => "(?![a-zA-Z0-9_<\|%\\-])"
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/vb.php b/platform/www/vendor/geshi/geshi/src/geshi/vb.php
new file mode 100644
index 0000000..3a44053
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/vb.php
@@ -0,0 +1,155 @@
+<?php
+/*************************************************************************************
+ * vb.php
+ * ------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org),
+ * Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/08/30
+ *
+ * Visual Basic language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/08/27 (1.0.8.1)
+ * - changed keyword list for better Visual Studio compliance
+ * 2008/08/26 (1.0.8.1)
+ * - Fixed multiline comments
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/08/30 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Visual Basic',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ // Comments (either single or multiline with _
+ 1 => '/\'.*(?<! _)$/sUm',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'Binary', 'Boolean', 'Byte', 'Currency', 'Date', 'Decimal', 'Double',
+ 'String', 'Enum', 'Integer', 'Long', 'Object', 'Single', 'Variant'
+ ),
+ 2 => array(
+ 'CreateObject', 'GetObject', 'New', 'Option', 'Function',
+ 'Call', 'Private', 'Public', 'Sub', 'Explicit', 'Compare', 'Exit'
+ ),
+ 3 => array(
+ 'And', 'Case', 'Do', 'Each', 'Else', 'ElseIf', 'End', 'For', 'GoSub',
+ 'Goto', 'If', 'Is', 'Loop', 'Next', 'Not', 'Or', 'Resume', 'Select',
+ 'Step', 'Then', 'To', 'Until', 'While', 'With', 'Xor', 'WithEvents',
+ 'DoEvents', 'Close', 'Like', 'In'
+ ),
+ 4 => array(
+ 'As', 'Dim', 'Get', 'Set', 'ReDim', 'Error',
+ 'Declare', 'Let', 'ByRef', 'ByVal',
+ 'Optional', 'Property', 'Control', 'UBound', 'Mod',
+ 'Implements', 'Input', 'LBound', 'Static', 'Stop',
+ 'Type', 'TypeOf', 'On', 'Open', 'Output', 'ParamArray',
+ 'Preserve', 'Print', 'RaiseEvent', 'Random', 'Line'
+ ),
+ 5 => array(
+ 'Nothing', 'False', 'True', 'Null', 'Empty'
+ ),
+ 6 => array(
+ 'ErrorHandler','ExitProc', 'PublishReport'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 6 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #F660AB; font-weight: bold;',
+ 2 => 'color: #E56717; font-weight: bold;',
+ 3 => 'color: #8D38C9; font-weight: bold;',
+ 4 => 'color: #151B8D; font-weight: bold;',
+ 5 => 'color: #00C2FF; font-weight: bold;',
+ 6 => 'color: #3EA99F; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000;'
+ ),
+ 'BRACKETS' => array(
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #800000;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #800000; font-weight: bold;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => '',
+ 6 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER,
+ 'SYMBOLS' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/vbnet.php b/platform/www/vendor/geshi/geshi/src/geshi/vbnet.php
new file mode 100644
index 0000000..3932c52
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/vbnet.php
@@ -0,0 +1,180 @@
+<?php
+/*************************************************************************************
+ * vbnet.php
+ * ---------
+ * Author: Alan Juden (alan@judenware.org)
+ * Copyright: (c) 2004 Alan Juden, Nigel McNie (http://qbnz.com/highlighter)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/06/04
+ *
+ * VB.NET language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2004/11/27 (1.0.0)
+ * - Initial release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'vb.net',
+ 'COMMENT_SINGLE' => array(1 => "'"),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ //Keywords
+ 1 => array(
+ 'AddHandler', 'AddressOf', 'Alias', 'And', 'AndAlso', 'As', 'ByRef', 'ByVal',
+ 'Call', 'Case', 'Catch', 'Char', 'Class', 'Const', 'Continue',
+ 'Declare', 'Default',
+ 'Delegate', 'Dim', 'DirectCast', 'Do', 'Each', 'Else', 'ElseIf', 'End', 'EndIf',
+ 'Enum', 'Erase', 'Error', 'Event', 'Exit', 'False', 'Finally', 'For', 'Friend', 'Function',
+ 'Get', 'GetType', 'GetXMLNamespace', 'Global', 'GoSub', 'GoTo', 'Handles', 'If', 'Implements',
+ 'Imports', 'In', 'Inherits', 'Interface', 'Is', 'IsNot', 'Let', 'Lib', 'Like', 'Loop', 'Me',
+ 'Mod', 'Module', 'Module Statement', 'MustInherit', 'MustOverride', 'MyBase', 'MyClass', 'Namespace',
+ 'Narrowing', 'New', 'Next', 'Not', 'Nothing', 'NotInheritable', 'NotOverridable', 'Of', 'On',
+ 'Operator', 'Option', 'Optional', 'Or', 'OrElse', 'Out', 'Overloads', 'Overridable', 'Overrides',
+ 'ParamArray', 'Partial', 'Private', 'Property', 'Protected', 'Public', 'RaiseEvent', 'ReadOnly', 'ReDim',
+ 'REM', 'RemoveHandler', 'Resume', 'Return', 'Select','Set', 'Shadows', 'Shared', 'Static', 'Step',
+ 'Stop', 'Structure', 'Sub', 'SyncLock', 'Then', 'Throw', 'To', 'True', 'Try', 'TryCast', 'TypeOf',
+ 'Using', 'Wend', 'When', 'While', 'Widening', 'With', 'WithEvents', 'WriteOnly', 'Xor'
+ ),
+ //Data Types
+ 2 => array(
+ 'Boolean', 'Byte', 'Date', 'Decimal', 'Double', 'Integer', 'Long', 'Object',
+ 'SByte', 'Short', 'Single', 'String', 'UInteger', 'ULong', 'UShort'
+ ),
+ //Compiler Directives
+ 3 => array(
+ '#Const', '#Else', '#ElseIf', '#End', '#If'
+ ),
+ //Constants
+ 4 => array(
+ 'CBool', 'CByte', 'CChar', 'CChr', 'CDate', 'CDbl', 'CDec','CInt', 'CLng', 'CLng8', 'CObj', 'CSByte', 'CShort',
+ 'CSng', 'CStr', 'CType', 'CUInt', 'CULng', 'CUShort'
+ ),
+ //Linq
+ 5 => array(
+ 'By','From','Group','Where'
+ ),
+ //Built-in functions
+ 7 => array(
+ 'ABS', 'ARRAY', 'ASC', 'ASCB', 'ASCW', 'CALLBYNAME', 'CHOOSE', 'CHR', 'CHR$', 'CHRB', 'CHRB$', 'CHRW',
+ 'CLOSE', 'COMMAND', 'COMMAND$', 'CONVERSION',
+ 'COS', 'CREATEOBJECT', 'CURDIR', 'CVDATE', 'DATEADD',
+ 'DATEDIFF', 'DATEPART', 'DATESERIAL', 'DATEVALUE', 'DAY', 'DDB', 'DIR', 'DIR$',
+ 'EOF', 'ERROR$', 'EXP', 'FILEATTR', 'FILECOPY', 'FILEDATATIME', 'FILELEN', 'FILTER',
+ 'FIX', 'FORMAT', 'FORMAT$', 'FORMATCURRENCY', 'FORMATDATETIME', 'FORMATNUMBER',
+ 'FORMATPERCENT', 'FREEFILE', 'FV', 'GETALLSETTINGS', 'GETATTRGETOBJECT', 'GETSETTING',
+ 'HEX', 'HEX$', 'HOUR', 'IIF', 'IMESTATUS', 'INPUT$', 'INPUTB', 'INPUTB$', 'INPUTBOX',
+ 'INSTR', 'INSTRB', 'INSTRREV', 'INT', 'IPMT', 'IRR', 'ISARRAY', 'ISDATE', 'ISEMPTY',
+ 'ISERROR', 'ISNULL', 'ISNUMERIC', 'ISOBJECT', 'JOIN', 'LBOUND', 'LCASE', 'LCASE$',
+ 'LEFT', 'LEFT$', 'LEFTB', 'LEFTB$', 'LENB', 'LINEINPUT', 'LOC', 'LOF', 'LOG', 'LTRIM',
+ 'LTRIM$', 'MID$', 'MIDB', 'MIDB$', 'MINUTE', 'MIRR', 'MKDIR', 'MONTH', 'MONTHNAME',
+ 'MSGBOX', 'NOW', 'NPER', 'NPV', 'OCT', 'OCT$', 'PARTITION', 'PMT', 'PPMT', 'PV',
+ 'RATE', 'REPLACE', 'RIGHT', 'RIGHT$', 'RIGHTB', 'RIGHTB$', 'RMDIR', 'RND', 'RTRIM',
+ 'RTRIM$', 'SECOND', 'SIN', 'SLN', 'SPACE', 'SPACE$', 'SPC', 'SPLIT', 'SQRT', 'STR', 'STR$',
+ 'STRCOMP', 'STRCONV', 'STRING$', 'STRREVERSE', 'SYD', 'TAB', 'TAN', 'TIMEOFDAY',
+ 'TIMER', 'TIMESERIAL', 'TIMEVALUE', 'TODAY', 'TRIM', 'TRIM$', 'TYPENAME', 'UBOUND',
+ 'UCASE', 'UCASE$', 'VAL', 'WEEKDAY', 'WEEKDAYNAME', 'YEAR'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '+', '-', '*', '?', '=', '/', '%', '&', '>', '<', '^', '!',
+ '(', ')', '{', '}', '.'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false,
+ 7 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF; font-weight: bold;', //Keywords
+ 2 => 'color: #6a5acd;', //primitive Data Types
+ 3 => 'color: #6a5acd; font-weight: bold;', //preprocessor-commands
+ 4 => 'color: #cd6a5a;', //Constants
+ 5 => 'color: #cd6a5a; font-weight: bold;', //LinQ
+ 7 => 'color: #000066;', //Built-in functions
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000; font-style: italic;',
+ 'MULTI' => 'color: #008000; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #008080; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #a52a2a; back-color: #fffacd;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #a52a2a; back-color: #fffacd;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #000000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.google.com/search?q={FNAMEU}+site:msdn.microsoft.com',
+ 4 => '',
+ 5 => '',
+ 7 => 'http://www.google.com/search?q={FNAMEU}+site:msdn.microsoft.com'
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 =>'.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 7 => array(
+ 'DISALLOWED_AFTER' => '(?!\w)(?=\s*\()'
+ )
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/vbscript.php b/platform/www/vendor/geshi/geshi/src/geshi/vbscript.php
new file mode 100644
index 0000000..66796ec
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/vbscript.php
@@ -0,0 +1,153 @@
+<?php
+/*************************************************************************************
+ * vbscript.php
+ * ------
+ * Author: Roberto Rossi (rsoftware@altervista.org)
+ * Copyright: (c) 2004 Roberto Rossi (http://rsoftware.altervista.org),
+ * Nigel McNie (http://qbnz.com/highlighter),
+ * Rory Prendergast (http://www.tanium.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2012/08/20
+ *
+ * VBScript language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2012/08/20 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'VBScript',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ // Comments (either single or multiline with _
+ 1 => '/\'.*(?<! _)\n/sU',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'Empty', 'Nothing', 'Null', 'vbArray', 'vbBoolean', 'vbByte',
+ 'vbCr', 'vbCrLf', 'vbCurrency', 'vbDate', 'vbDouble', 'vbEmpty',
+ 'vbError', 'vbFirstFourDays', 'vbFirstFullWeek', 'vbFirstJan1',
+ 'vbFormFeed', 'vbFriday', 'vbInteger', 'vbLf', 'vbLong', 'vbMonday',
+ 'vbNewLine', 'vbNull', 'vbNullChar', 'vbNullString', 'vbObject',
+ 'vbSaturday', 'vbSingle', 'vbString', 'vbSunday', 'vbTab',
+ 'vbThursday', 'vbTuesday', 'vbUseSystem', 'vbUseSystemDayOfWeek',
+ 'vbVariant', 'vbWednesday', 'FALSE', 'TRUE'
+ ),
+ 2 => array(
+ 'bs', 'Array', 'Asc', 'Atn', 'CBool', 'CByte', 'CDate', 'CDbl', 'Chr',
+ 'CInt', 'CLng', 'Cos', 'CreateObject', 'CSng', 'CStr', 'Date', 'DateAdd',
+ 'DateDiff', 'DatePart', 'DateSerial', 'DateValue', 'Day', 'Eval', 'Exp',
+ 'Filter', 'Fix', 'FormatDateTime', 'FormatNumber', 'FormatPercent',
+ 'GetObject', 'Hex', 'Hour', 'InputBox', 'InStr', 'InstrRev', 'Int',
+ 'IsArray', 'IsDate', 'IsEmpty', 'IsNull', 'IsNumeric', 'IsObject', 'Join',
+ 'LBound', 'LCase', 'Left', 'Len', 'Log', 'LTrim', 'Mid', 'Minute', 'Month',
+ 'MonthName', 'MsgBox', 'Now', 'Oct', 'Replace', 'RGB', 'Right', 'Rnd',
+ 'Round', 'RTrim', 'ScriptEngine', 'ScriptEngineBuildVersion',
+ 'ScriptEngineMajorVersion', 'ScriptEngineMinorVersion', 'Second',
+ 'Sgn', 'Sin', 'Space', 'Split', 'Sqr', 'StrComp', 'String', 'StrReverse',
+ 'Tan', 'Time', 'TimeSerial', 'TimeValue', 'Trim', 'TypeName', 'UBound',
+ 'UCase', 'VarType', 'Weekday', 'WeekdayName', 'Year'
+ ),
+ 3 => array(
+ 'Call', 'Case', 'Const', 'Dim', 'Do', 'Each', 'Else', 'End', 'Erase',
+ 'Execute', 'Exit', 'For', 'Function', 'Gosub', 'Goto', 'If', 'Loop',
+ 'Next', 'On Error', 'Option Explicit', 'Private', 'Public',
+ 'Randomize', 'ReDim', 'Rem', 'Resume', 'Select', 'Set', 'Sub', 'Then',
+ 'Wend', 'While', 'With', 'In', 'To', 'Step'
+ ),
+ 4 => array(
+ 'And', 'Eqv', 'Imp', 'Is', 'Mod', 'Not', 'Or', 'Xor'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '-', '&', '*', '/', '\\', '^', '+', '<', '<=', '<>', '=', '>', '>='
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #F660AB; font-weight: bold;',
+ 2 => 'color: #E56717; font-weight: bold;',
+ 3 => 'color: #8D38C9; font-weight: bold;',
+ 4 => 'color: #151B8D; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000;'
+ ),
+ 'BRACKETS' => array(
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #800000;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #800000; font-weight: bold;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 'SPACE_AS_WHITESPACE' => true
+ ),
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/vedit.php b/platform/www/vendor/geshi/geshi/src/geshi/vedit.php
new file mode 100644
index 0000000..4a6e1c6
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/vedit.php
@@ -0,0 +1,101 @@
+<?php
+/*************************************************************************************
+ * vedit.php
+ * --------
+ * Author: Pauli Lindgren (pauli0212@yahoo.com)
+ * Copyright: (c) 2009 Pauli Lindgren (http://koti.mbnet.fi/pkl/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/12/16
+ *
+ * Vedit macro language language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2009/12/16 (1.0.8.11)
+ * - First Release
+ *
+ * TODO (updated 2009/12/16)
+ * -------------------------
+ * - Add keyword groups 2, 3 and 4.
+ *
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Vedit macro language',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"', '\''),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'break', 'breakout', 'break_out', 'continue', 'do', 'else', 'for',
+ 'goto', 'if', 'repeat', 'return', 'while'
+ )
+ ),
+ 'SYMBOLS' => array(
+ 1 => array(
+ '(', ')', '{', '}', '[', ']', '+', '-', '*', '/', '%',
+ '=', '<', '>', '!', '^', '&', '|', '?', ':', ';', ','
+ )
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;',
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #004000;'
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: #339933;'
+ ),
+ 'REGEXPS' => array(),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(1 => ''),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/verilog.php b/platform/www/vendor/geshi/geshi/src/geshi/verilog.php
new file mode 100644
index 0000000..afcd91e
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/verilog.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * verilog.php
+ * -----------
+ * Author: Günter Dannoritzer <dannoritzer@web.de>
+ * Copyright: (C) 2008 Günter Dannoritzer
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/05/28
+ *
+ * Verilog language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/29
+ * - added regular expression to find numbers of the form 4'b001xz
+ * - added regular expression to find values for `timescale command
+ * - extended macro keywords
+ *
+ * TODO (updated 2008/05/29)
+ * -------------------------
+ *
+ * 2013/01/08
+ * - extended keywords to include system keywords
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Verilog',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(1 => '/\/\/(?:\\\\\\\\|\\\\\\n|.)*$/m'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ // keywords
+ 1 => array(
+ 'accept_on','alias',
+ 'always','always_comb','always_ff','always_latch','and','assert',
+ 'assign','assume','automatic','before','begin','bind','bins','binsof',
+ 'bit','break','buf','bufif0','bufif1','byte','case','casex','casez',
+ 'cell','chandle','checker','class','clocking','cmos','config','const',
+ 'constraint','context','continue','cover','covergroup','coverpoint','cross',
+ 'deassign','default','defparam','design','disable','dist','do','edge','else',
+ 'end','endcase','endchecker','endclass','endclocking','endconfig',
+ 'endfunction','endgenerate','endgroup','endinterface','endmodule',
+ 'endpackage','endprimitive','endprogram','endproperty','endspecify',
+ 'endsequence','endtable','endtask','enum','event','eventually','expect',
+ 'export','extends','extern','final','first_match','for','force','foreach',
+ 'forever','fork','forkjoin','function','generate','genvar','global',
+ 'highz0','highz1','if','iff','ifnone','ignore_bins','illegal_bins',
+ 'implies','import','incdir','include','initial','inout','input','inside',
+ 'instance','int','integer','interface','intersect','join','join_any',
+ 'join_none','large','let','liblist','library','local','localparam',
+ 'logic','longint','macromodule','matches','medium','modport','module','nand',
+ 'negedge','new','nexttime','nmos','nor','noshowcancelled','not','notif0',
+ 'notif1','null','or','output','package','packed','parameter','pmos','posedge',
+ 'primitive','priority','program','property','protected','pull0','pull1',
+ 'pulldown','pullup','pulsestyle_ondetect','pulsestyle_onevent','pure',
+ 'rand','randc','randcase','randsequence','rcmos','real','realtime','ref',
+ 'reg','reject_on','release','repeat','restrict','return','rnmos','rpmos',
+ 'rtran','rtranif0','rtranif1','s_always','s_eventually','s_nexttime',
+ 's_until','s_until_with','scalared','sequence','shortint','shortreal',
+ 'showcancelled','signed','small','solve','specify','specparam','static',
+ 'string','strong','strong0','strong1','struct','super','supply0','supply1',
+ 'sync_accept_on','sync_reject_on','table','tagged','task','this','throughout',
+ 'time','timeprecision','timeunit','tran','tranif0','tranif1','tri','tri0',
+ 'tri1','triand','trior','trireg','type','typedef','union','unique','unique0',
+ 'unsigned','until','until_with','untyped','use','uwire','var','vectored',
+ 'virtual','void','wait','wait_order','wand','weak','weak0','weak1','while',
+ 'wildcard','wire','with','within','wor','xnor','xor'
+ ),
+ // system tasks
+ 2 => array(
+ '$display', '$monitor',
+ '$dumpall', '$dumpfile', '$dumpflush', '$dumplimit', '$dumpoff',
+ '$dumpon', '$dumpvars',
+ '$fclose', '$fdisplay', '$fopen',
+ '$finish', '$fmonitor', '$fstrobe', '$fwrite',
+ '$fgetc', '$ungetc', '$fgets', '$fscanf', '$fread', '$ftell',
+ '$fseek', '$frewind', '$ferror', '$fflush', '$feof',
+ '$random',
+ '$readmemb', '$readmemh', '$readmemx',
+ '$signed', '$stime', '$stop',
+ '$strobe', '$time', '$unsigned', '$write'
+ ),
+ // macros
+ 3 => array(
+ '`default-net', '`define',
+ '`celldefine', '`default_nettype', '`else', '`elsif', '`endcelldefine',
+ '`endif', '`ifdef', '`ifndef', '`include', '`line', '`nounconnected_drive',
+ '`resetall', '`timescale', '`unconnected_drive', '`undef'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '{', '}', '[', ']', '=', '+', '-', '*', '/', '!', '%',
+ '^', '&', '|', '~',
+ '?', ':',
+ '#', '<<', '<<<',
+ '>', '<', '>=', '<=',
+ '@', ';', ','
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #A52A2A; font-weight: bold;',
+ 2 => 'color: #9932CC;',
+ 3 => 'color: #008800;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #00008B; font-style: italic;',
+ 'MULTI' => 'color: #00008B; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #9F79EE'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #9F79EE;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #FF00FF;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0055;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #202020;',
+ 2 => 'color: #202020;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #5D478B;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #ff0055;',
+ 1 => 'color: #ff0055;',
+ ),
+ 'SCRIPT' => array(
+ 0 => '',
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => ''
+ ),
+ 'REGEXPS' => array(
+ // numbers
+ 0 => "\d'[bdh][0-9_a-fA-FxXzZ]+",
+ // time -> 1, 10, or 100; s, ms, us, ns, ps, of fs
+ 1 => "1[0]{0,2}[munpf]?s"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ 1 => ''
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ 0 => true,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/vhdl.php b/platform/www/vendor/geshi/geshi/src/geshi/vhdl.php
new file mode 100644
index 0000000..9ff11ec
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/vhdl.php
@@ -0,0 +1,181 @@
+<?php
+/*************************************************************************************
+ * vhdl.php
+ * --------
+ * Author: Alexander 'E-Razor' Krause (admin@erazor-zone.de)
+ * Contributors:
+ * - Kevin Thibedeau (kevinpt@yahoo.com)
+ * Copyright: (c) 2005 Alexander Krause
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/06/15
+ *
+ * VHDL (VHSICADL, very high speed integrated circuit HDL) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2012/4/30 (1.0.8.10)
+ * - Reworked to support new features of VHDL-2008.
+ * - Changes include: multi-line comments, all new keywords, PSL keywords and metacomments,
+ * - based literals, attribute highlighting, preprocessor macros (from PSL), and other small
+ * - improvements.
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * - Optimized regexp group 0 somewhat
+ * 2006/06/15 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'VHDL',
+ 'COMMENT_SINGLE' => array(1 => '--'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'COMMENT_REGEXP' => array(
+ // PSL adds C-preprocessor support
+ 1 => '/(?<=\s)#(?:\\\\\\\\|\\\\\\n|.)*$/m',
+ // PSL metacomments (single-line only for now)
+ 2 => '/--\s*@?psl(?:.)*?;$/m',
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /*keywords*/
+ 1 => array(
+ 'access','after','alias','all','attribute','architecture','array','begin',
+ 'block','body','buffer','bus','case','case?','component','configuration','constant','context',
+ 'disconnect','downto','else','elsif','end','entity','exit','file','for','force',
+ 'function','generate','generic','group','guarded','if','impure','in',
+ 'inertial','inout','is','label','library','linkage','literal','loop',
+ 'map','new','next','null','of','on','open','others','out','package',
+ 'port','postponed','procedure','process','protected','pure','range','record','register',
+ 'reject','release','report','return','select','severity','shared','signal','subtype',
+ 'then','to','transport','type','unaffected','units','until','use','variable',
+ 'wait','when','while','with'
+ ),
+ /*types and standard libs*/
+ 2 => array(
+ 'bit','bit_vector','character','boolean','integer','real','time','delay_length','string',
+ 'severity_level','positive','natural','signed','unsigned','line','text',
+ 'std_logic','std_logic_vector','std_ulogic','std_ulogic_vector',
+ 'sfixed','ufixed','float','float32','float64','float128',
+ 'work','ieee','std_logic_1164','math_real','math_complex','textio',
+ 'numeric_std','numeric_std_signed','numeric_std_unsigned','numeric_bit'
+ ),
+ /*operators*/
+ 3 => array(
+ 'abs','and','mod','nor','not','or','rem','rol','ror','sla','sll','sra','srl','xnor','xor'
+ ),
+ /*psl*/
+ 4 => array(
+ 'assert','assume','assume_guarantee','clock','const','countones','cover','default',
+ 'endpoint','fairness','fell','forall','inf','inherit','isunknown','onehot','onehot0','property',
+ 'prev','restrict','restrict_guarantee','rose','sequence','stable','strong','union','vmode','vprop','vunit'
+ ),
+ /*psl operators*/
+ 5 => array(
+ 'abort','always','before','before!','before!_','before_','eventually!','never',
+ 'next!','next_a','next_a!','next_e','next_e!','next_event','next_event!','next_event_a','next_event_a!',
+ 'next_event_e','next_event_e!','until!','until!_','until_','within'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '(', ')',
+ ';',':',
+ '<','>','=','+','-','*','/','&','|','?'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000080; font-weight: bold;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #000066;',
+ 4 => 'color: #000080; font-weight: bold;',
+ 5 => 'color: #000066;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000; font-style: italic;',
+ 2 => 'color: #ff0000; font-weight: bold;',
+ 'MULTI' => 'color: #008000; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000066;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #ff0000;',
+ //1 => 'color: #ff0000;',
+ 2 => 'color: #ee82ee;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Based literals, scientific notation, and time units
+ 0 => '(\b\d+#[[:xdigit:]_]+#)|'.
+ '(\b[\d_]+(\.[\d_]+)?[eE][+\-]?[\d_]+)|'.
+ '(\b(hr|min|sec|ms|us|ns|ps|fs)\b)',
+ //Character literals
+ /* GeSHi won't match this pattern for some reason and QUOTEMARKS
+ * can't be used because it interferes with attribute parsing */
+ /*1 => "\b'.'\b",*/
+ //Attributes
+ 2 => "'\w+(?!')"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/vim.php b/platform/www/vendor/geshi/geshi/src/geshi/vim.php
new file mode 100644
index 0000000..6f959a0
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/vim.php
@@ -0,0 +1,418 @@
+<?php
+/*************************************************************************************
+ * vim.php
+ * ----------------
+ * Author: Swaroop C H (swaroop@swaroopch.com)
+ * Contributors:
+ * - Laurent Peuch (psycojoker@gmail.com)
+ * Copyright: (c) 2008 Swaroop C H (http://www.swaroopch.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/10/19
+ *
+ * Vim scripting language file for GeSHi.
+ *
+ * Reference: http://qbnz.com/highlighter/geshi-doc.html#language-files
+ * All keywords scraped from `:help expression-commands`.
+ * All method names scraped from `:help function-list`.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/19 (1.0.8.2)
+ * - Started.
+ * 2009/07/05
+ * - Fill out list of zillion commands (maybe somes still miss).
+ * - fix a part of the regex, now works for comment that have white space before the "
+ *
+ * TODO (updated 2009/07/05)
+ * -------------------------
+ * - Make this damn string with "" work correctly. I've just remove it for my wiki.
+ * - Make the comment regex able to find comment after some code.
+ * (i.e: let rocks " unworking comment)
+ * - Make <F1> <F2> ... <Esc> <CR> ... works event if they aren't surround by space.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Vim Script',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_REGEXP' => array(
+ 1 => "/\s*\"[^\"]*?$/m",
+ //Regular expressions (Ported from perl.php)
+// 2 => "/(?<=[\\s^])(s|tr|y)\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/(?:\\\\.|(?!\n)[^\\/\\\\])*\\/[msixpogcde]*(?=[\\s$\\.\\;])|(?<=[\\s^(=])(m|q[qrwx]?)?\\/(?:\\\\.|(?!\n)[^\\/\\\\])+\\/[msixpogc]*(?=[\\s$\\.\\,\\;\\)])/iU",
+ ),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'au', 'augroup', 'autocmd', 'brea', 'break', 'bufadd',
+ 'bufcreate', 'bufdelete', 'bufenter', 'buffilepost',
+ 'buffilepre', 'bufleave', 'bufnew', 'bufnewfile',
+ 'bufread', 'bufreadcmd', 'bufreadpost', 'bufreadpre',
+ 'bufunload', 'bufwinenter', 'bufwinleave', 'bufwipeout',
+ 'bufwrite', 'bufwritecmd', 'bufwritepost', 'bufwritepre',
+ 'call', 'cat', 'catc', 'catch', 'cmd-event', 'cmdwinenter',
+ 'cmdwinleave', 'colorscheme', 'con', 'confirm', 'cont', 'conti',
+ 'contin', 'continu', 'continue', 'cursorhold', 'cursorholdi',
+ 'cursormoved', 'cursormovedi', 'ec', 'echo', 'echoe',
+ 'echoer', 'echoerr', 'echoh', 'echohl', 'echom', 'echoms',
+ 'echomsg', 'echon', 'el', 'els', 'else', 'elsei', 'elseif',
+ 'en', 'encodingchanged', 'end', 'endfo', 'endfor', 'endi',
+ 'endif', 'endt', 'endtr', 'endtry', 'endw', 'endwh', 'endwhi',
+ 'endwhil', 'endwhile', 'exe', 'exec', 'execu', 'execut',
+ 'execute', 'fileappendcmd', 'fileappendpost', 'fileappendpre',
+ 'filechangedro', 'filechangedshell', 'filechangedshellpost',
+ 'filereadcmd', 'filereadpost', 'filereadpre',
+ 'filetype', 'filewritecmd', 'filewritepost', 'filewritepre',
+ 'filterreadpost', 'filterreadpre', 'filterwritepost',
+ 'filterwritepre', 'fina', 'final', 'finall', 'finally',
+ 'finish', 'focusgained', 'focuslost', 'for', 'fun', 'func',
+ 'funct', 'functi', 'functio', 'function', 'funcundefined',
+ 'guienter', 'guifailed', 'hi', 'highlight', 'if', 'in',
+ 'insertchange', 'insertenter', 'insertleave', 'let', 'lockv',
+ 'lockva', 'lockvar', 'map', 'match', 'menupopup', 'nnoremap',
+ 'quickfixcmdpost', 'quickfixcmdpre', 'remotereply', 'retu',
+ 'retur', 'return', 'sessionloadpost', 'set', 'setlocal',
+ 'shellcmdpost', 'shellfilterpost', 'sourcecmd', 'sourcepre',
+ 'spellfilemissing', 'stdinreadpost', 'stdinreadpre',
+ 'swapexists', 'syntax', 'tabenter', 'tableave', 'termchanged',
+ 'termresponse', 'th', 'thr', 'thro', 'throw', 'tr', 'try', 'unl',
+ 'unle', 'unlet', 'unlo', 'unloc', 'unlock', 'unlockv',
+ 'unlockva', 'unlockvar', 'user', 'usergettingbored',
+ 'vimenter', 'vimleave', 'vimleavepre', 'vimresized', 'wh',
+ 'whi', 'whil', 'while', 'winenter', 'winleave'
+ ),
+ 2 => array(
+ '&lt;CR&gt;', '&lt;Esc&gt;', '&lt;F1&gt;', '&lt;F10&gt;',
+ '&lt;F11&gt;', '&lt;F12&gt;', '&lt;F2&gt;', '&lt;F3&gt;',
+ '&lt;F4&gt;', '&lt;F5&gt;', '&lt;F6&gt;', '&lt;F7&gt;',
+ '&lt;F8&gt;', '&lt;F9&gt;', '&lt;cr&gt;', '&lt;silent&gt;',
+ '-nargs', 'acd', 'ai', 'akm', 'al', 'aleph',
+ 'allowrevins', 'altkeymap', 'ambiwidth', 'ambw',
+ 'anti', 'antialias', 'ar', 'arab', 'arabic',
+ 'arabicshape', 'ari', 'arshape', 'autochdir',
+ 'autoindent', 'autoread', 'autowrite', 'autowriteall',
+ 'aw', 'awa', 'background', 'backspace', 'backup',
+ 'backupcopy', 'backupdir', 'backupext',
+ 'backupskip', 'balloondelay', 'ballooneval', 'balloonexpr',
+ 'bdir', 'bdlay', 'beval', 'bex', 'bexpr', 'bg',
+ 'bh', 'bin', 'binary', 'biosk', 'bioskey',
+ 'bk', 'bkc', 'bl', 'bomb', 'breakat', 'brk',
+ 'bs', 'bsdir', 'bsk', 'bt', 'bufhidden',
+ 'buftype', 'casemap', 'cb',
+ 'ccv', 'cd', 'cdpath', 'cedit', 'cf', 'cfu', 'ch',
+ 'charconvert', 'ci', 'cin', 'cink',
+ 'cinkeys', 'cino', 'cinoptions', 'cinw', 'cinwords',
+ 'clipboard', 'cmdheight', 'cmdwinheight',
+ 'cmp', 'cms', 'co', 'columns', 'com',
+ 'comc', 'comcl', 'comcle', 'comclea', 'comclear', 'comm',
+ 'comma', 'comman', 'command', 'comments', 'commentstring',
+ 'compatible', 'completefunc', 'completeopt',
+ 'consk', 'conskey', 'copyindent',
+ 'cot', 'cp', 'cpo', 'cpoptions', 'cpt',
+ 'cscopepathcomp', 'cscopeprg', 'cscopequickfix', 'cscopetag',
+ 'cscopetagorder', 'cscopeverbose',
+ 'cspc', 'csprg', 'csqf', 'cst', 'csto', 'csverb', 'cuc',
+ 'cul', 'cursorcolumn', 'cursorline', 'cwh', 'debug',
+ 'deco', 'def', 'define', 'delc', 'delco', 'delcom',
+ 'delcombine', 'delcomm', 'delcomman', 'delcommand', 'dex',
+ 'dg', 'dict', 'dictionary', 'diff', 'diffexpr',
+ 'diffopt', 'digraph', 'dip', 'dir', 'directory', 'display',
+ 'dlcomma', 'dy', 'ea', 'ead', 'eadirection',
+ 'eb', 'ed', 'edcompatible', 'ef', 'efm',
+ 'ei', 'ek', 'enc', 'encoding', 'endfun', 'endofline',
+ 'eol', 'ep', 'equalalways', 'equalprg', 'errorbells',
+ 'errorfile', 'errorformat', 'esckeys', 'et',
+ 'eventignore', 'ex', 'expandtab', 'exrc', 'fcl',
+ 'fcs', 'fdc', 'fde', 'fdi', 'fdl', 'fdls', 'fdm',
+ 'fdn', 'fdo', 'fdt', 'fen', 'fenc', 'fencs', 'fex',
+ 'ff', 'ffs', 'fileencoding', 'fileencodings', 'fileformat',
+ 'fileformats', /*'filetype',*/ 'fillchars', 'fk',
+ 'fkmap', 'flp', 'fml', 'fmr', 'fo', 'foldclose',
+ 'foldcolumn', 'foldenable', 'foldexpr', 'foldignore',
+ 'foldlevelstart', 'foldmarker', 'foldmethod', 'foldminlines',
+ 'foldnestmax', 'foldopen', 'formatexpr', 'formatlistpat',
+ 'formatoptions', 'formatprg', 'fp', 'fs', 'fsync', 'ft',
+ 'gcr', 'gd', 'gdefault', 'gfm', 'gfn', 'gfs', 'gfw',
+ 'ghr', 'go', 'gp', 'grepformat', 'grepprg', 'gtl',
+ 'gtt', 'guicursor', 'guifont', 'guifontset',
+ 'guifontwide', 'guiheadroom', 'guioptions', 'guipty',
+ 'guitablabel', 'guitabtooltip', 'helpfile',
+ 'helpheight', 'helplang', 'hf', 'hh', 'hid', 'hidden',
+ 'history', 'hk', 'hkmap', 'hkmapp', 'hkp', 'hl',
+ 'hlg', 'hls', 'hlsearch', 'ic', 'icon', 'iconstring',
+ 'ignorecase', 'im', 'imactivatekey', 'imak', 'imc',
+ 'imcmdline', 'imd', 'imdisable', 'imi', 'iminsert', 'ims',
+ 'imsearch', 'inc', 'include', 'includeexpr',
+ 'incsearch', 'inde', 'indentexpr', 'indentkeys',
+ 'indk', 'inex', 'inf', 'infercase', 'insertmode', 'is', 'isf',
+ 'isfname', 'isi', 'isident', 'isk', 'iskeyword',
+ 'isp', 'isprint', 'joinspaces', 'js', 'key',
+ 'keymap', 'keymodel', 'keywordprg', 'km', 'kmp', 'kp',
+ 'langmap', 'langmenu', 'laststatus', 'lazyredraw', 'lbr',
+ 'lcs', 'linebreak', 'lines', 'linespace', 'lisp',
+ 'lispwords', 'list', 'listchars', 'lm', 'lmap',
+ 'loadplugins', 'lpl', 'ls', 'lsp', 'lw', 'lz', 'ma',
+ 'macatsui', 'magic', 'makeef', 'makeprg', 'mat',
+ 'matchpairs', 'matchtime', 'maxcombine', 'maxfuncdepth',
+ 'maxmapdepth', 'maxmem', 'maxmempattern',
+ 'maxmemtot', 'mco', 'mef', 'menuitems', 'mfd', 'mh',
+ 'mis', 'mkspellmem', 'ml', 'mls', 'mm', 'mmd', 'mmp',
+ 'mmt', 'mod', 'modeline', 'modelines', 'modifiable',
+ 'modified', 'more', 'mouse', 'mousef', 'mousefocus',
+ 'mousehide', 'mousem', 'mousemodel', 'mouses',
+ 'mouseshape', 'mouset', 'mousetime', 'mp', 'mps', 'msm',
+ 'mzq', 'mzquantum', 'nf', 'noacd', 'noai', 'noakm',
+ 'noallowrevins', 'noaltkeymap', 'noanti', 'noantialias',
+ 'noar', 'noarab', 'noarabic', 'noarabicshape', 'noari',
+ 'noarshape', 'noautochdir', 'noautoindent', 'noautoread',
+ 'noautowrite', 'noautowriteall', 'noaw', 'noawa', 'nobackup',
+ 'noballooneval', 'nobeval', 'nobin', 'nobinary', 'nobiosk',
+ 'nobioskey', 'nobk', 'nobl', 'nobomb', 'nobuflisted', 'nocf',
+ 'noci', 'nocin', 'nocindent', 'nocompatible', 'noconfirm',
+ 'noconsk', 'noconskey', 'nocopyindent', 'nocp', 'nocscopetag',
+ 'nocscopeverbose', 'nocst', 'nocsverb', 'nocuc', 'nocul',
+ 'nocursorcolumn', 'nocursorline', 'nodeco', 'nodelcombine',
+ 'nodg', 'nodiff', 'nodigraph', 'nodisable', 'noea', 'noeb',
+ 'noed', 'noedcompatible', 'noek', 'noendofline', 'noeol',
+ 'noequalalways', 'noerrorbells', 'noesckeys', 'noet',
+ 'noex', 'noexpandtab', 'noexrc', 'nofen', 'nofk', 'nofkmap',
+ 'nofoldenable', 'nogd', 'nogdefault', 'noguipty', 'nohid',
+ 'nohidden', 'nohk', 'nohkmap', 'nohkmapp', 'nohkp', 'nohls',
+ 'nohlsearch', 'noic', 'noicon', 'noignorecase', 'noim',
+ 'noimc', 'noimcmdline', 'noimd', 'noincsearch', 'noinf',
+ 'noinfercase', 'noinsertmode', 'nois', 'nojoinspaces',
+ 'nojs', 'nolazyredraw', 'nolbr', 'nolinebreak', 'nolisp',
+ 'nolist', 'noloadplugins', 'nolpl', 'nolz', 'noma',
+ 'nomacatsui', 'nomagic', 'nomh', 'noml', 'nomod',
+ 'nomodeline', 'nomodifiable', 'nomodified', 'nomore',
+ 'nomousef', 'nomousefocus', 'nomousehide', 'nonu',
+ 'nonumber', 'noodev', 'noopendevice', 'nopaste', 'nopi',
+ 'nopreserveindent', 'nopreviewwindow', 'noprompt', 'nopvw',
+ 'noreadonly', 'noremap', 'norestorescreen', 'norevins',
+ 'nori', 'norightleft', 'norightleftcmd', 'norl', 'norlc',
+ 'noro', 'nors', 'noru', 'noruler', 'nosb', 'nosc', 'noscb',
+ 'noscrollbind', 'noscs', 'nosecure', 'nosft', 'noshellslash',
+ 'noshelltemp', 'noshiftround', 'noshortname', 'noshowcmd',
+ 'noshowfulltag', 'noshowmatch', 'noshowmode', 'nosi', 'nosm',
+ 'nosmartcase', 'nosmartindent', 'nosmarttab', 'nosmd',
+ 'nosn', 'nosol', 'nospell', 'nosplitbelow', 'nosplitright',
+ 'nospr', 'nosr', 'nossl', 'nosta', 'nostartofline',
+ 'nostmp', 'noswapfile', 'noswf', 'nota', 'notagbsearch',
+ 'notagrelative', 'notagstack', 'notbi', 'notbidi', 'notbs',
+ 'notermbidi', 'noterse', 'notextauto', 'notextmode',
+ 'notf', 'notgst', 'notildeop', 'notimeout', 'notitle',
+ 'noto', 'notop', 'notr', 'nottimeout', 'nottybuiltin',
+ 'nottyfast', 'notx', 'novb', 'novisualbell', 'nowa',
+ 'nowarn', 'nowb', 'noweirdinvert', 'nowfh', 'nowfw',
+ 'nowildmenu', 'nowinfixheight', 'nowinfixwidth', 'nowiv',
+ 'nowmnu', 'nowrap', 'nowrapscan', 'nowrite', 'nowriteany',
+ 'nowritebackup', 'nows', 'nrformats', 'nu', 'number',
+ 'numberwidth', 'nuw', 'odev', 'oft', 'ofu',
+ 'omnifunc', 'opendevice', 'operatorfunc', 'opfunc',
+ 'osfiletype', 'pa', 'para', 'paragraphs',
+ 'paste', 'pastetoggle', 'patchexpr',
+ 'patchmode', 'path', 'pdev', 'penc', 'pex', 'pexpr',
+ 'pfn', 'ph', 'pheader', 'pi', 'pm', 'pmbcs',
+ 'pmbfn', 'popt', 'preserveindent', 'previewheight',
+ 'previewwindow', 'printdevice', 'printencoding', 'printexpr',
+ 'printfont', 'printheader', 'printmbcharset',
+ 'printmbfont', 'printoptions', 'prompt', 'pt', 'pumheight',
+ 'pvh', 'pvw', 'qe', 'quoteescape', 'rdt',
+ 'readonly', 'redrawtime', 'remap', 'report',
+ 'restorescreen', 'revins', 'ri', 'rightleft', 'rightleftcmd',
+ 'rl', 'rlc', 'ro', 'rs', 'rtp', 'ru',
+ 'ruf', 'ruler', 'rulerformat', 'runtimepath', 'sb', 'sbo',
+ 'sbr', 'sc', 'scb', 'scr', 'scroll', 'scrollbind',
+ 'scrolljump', 'scrolloff', 'scrollopt',
+ 'scs', 'sect', 'sections', 'secure', 'sel',
+ 'selection', 'selectmode', 'sessionoptions', 'sft',
+ 'sh', 'shcf', 'shell', 'shellcmdflag', 'shellpipe',
+ 'shellquote', 'shellredir', 'shellslash',
+ 'shelltemp', 'shelltype', 'shellxquote', 'shiftround',
+ 'shiftwidth', 'shm', 'shortmess', 'shortname',
+ 'showbreak', 'showcmd', 'showfulltag', 'showmatch',
+ 'showmode', 'showtabline', 'shq', 'si', 'sidescroll',
+ 'sidescrolloff', 'siso', 'sj', 'slm', 'sm', 'smartcase',
+ 'smartindent', 'smarttab', 'smc', 'smd', 'sn',
+ 'so', 'softtabstop', 'sol', 'sp', 'spc', 'spell',
+ 'spellcapcheck', 'spellfile', 'spelllang',
+ 'spf', 'spl', 'splitbelow', 'splitright', 'spr',
+ 'sps', 'sr', 'srr', 'ss', 'ssl', 'ssop', 'st', 'sta',
+ 'stal', 'startofline', 'statusline', 'stl', 'stmp',
+ 'sts', 'su', 'sua', 'suffixes', 'suffixesadd', 'sw',
+ 'swapfile', 'swapsync', 'swb', 'swf', 'switchbuf',
+ 'sws', 'sxq', 'syn', 'synmaxcol', 'ta',
+ 'tabline', 'tabpagemax', 'tabstop', 'tag',
+ 'tagbsearch', 'taglength', 'tagrelative', 'tags', 'tagstack',
+ 'tal', 'tb', 'tbi', 'tbidi', 'tbis', 'tbs',
+ 'tenc', 'term', 'termbidi', 'termencoding', 'terse',
+ 'textauto', 'textmode', 'textwidth', 'tf', 'tgst',
+ 'thesaurus', 'tildeop', 'timeout', 'timeoutlen',
+ 'title', 'titlelen', 'titleold', 'titlestring',
+ 'tl', 'tm', 'to', 'toolbar', 'toolbariconsize', 'top',
+ 'tpm', 'ts', 'tsl', 'tsr', 'ttimeout',
+ 'ttimeoutlen', 'ttm', 'tty', 'ttybuiltin', 'ttyfast', 'ttym',
+ 'ttymouse', 'ttyscroll', 'ttytype', 'tw', 'tx', 'uc',
+ 'ul', 'undolevels', 'updatecount', 'updatetime', 'ut',
+ 'vb', 'vbs', 'vdir', 've', 'verbose', 'verbosefile',
+ 'vfile', 'vi', 'viewdir', 'viewoptions', 'viminfo',
+ 'virtualedit', 'visualbell', 'vop', 'wa', 'wak',
+ 'warn', 'wb', 'wc', 'wcm', 'wd', 'weirdinvert', 'wfh',
+ 'wfw', /*'wh',*/ 'whichwrap', 'wi', 'wig', 'wildchar',
+ 'wildcharm', 'wildignore', 'wildmenu',
+ 'wildmode', 'wildoptions', 'wim', 'winaltkeys', 'window',
+ 'winfixheight', 'winfixwidth', 'winheight',
+ 'winminheight', 'winminwidth', 'winwidth', 'wiv',
+ 'wiw', 'wm', 'wmh', 'wmnu', 'wmw', 'wop', 'wrap',
+ 'wrapmargin', 'wrapscan', 'write', 'writeany',
+ 'writebackup', 'writedelay', 'ws', 'ww'
+ ),
+ 3 => array(
+ 'BufAdd', 'BufCreate', 'BufDelete', 'BufEnter', 'BufFilePost',
+ 'BufFilePre', 'BufHidden', 'BufLeave', 'BufNew', 'BufNewFile',
+ 'BufRead', 'BufReadCmd', 'BufReadPost', 'BufReadPre',
+ 'BufUnload', 'BufWinEnter', 'BufWinLeave', 'BufWipeout',
+ 'BufWrite', 'BufWriteCmd', 'BufWritePost', 'BufWritePre',
+ 'Cmd-event', 'CmdwinEnter', 'CmdwinLeave', 'ColorScheme',
+ 'CursorHold', 'CursorHoldI', 'CursorMoved', 'CursorMovedI',
+ 'EncodingChanged', 'FileAppendCmd', 'FileAppendPost',
+ 'FileAppendPre', 'FileChangedRO', 'FileChangedShell',
+ 'FileChangedShellPost', 'FileEncoding', 'FileReadCmd',
+ 'FileReadPost', 'FileReadPre', 'FileType',
+ 'FileWriteCmd', 'FileWritePost', 'FileWritePre',
+ 'FilterReadPost', 'FilterReadPre', 'FilterWritePost',
+ 'FilterWritePre', 'FocusGained', 'FocusLost', 'FuncUndefined',
+ 'GUIEnter', 'GUIFailed', 'InsertChange', 'InsertEnter',
+ 'InsertLeave', 'MenuPopup', 'QuickFixCmdPost',
+ 'QuickFixCmdPre', 'RemoteReply', 'SessionLoadPost',
+ 'ShellCmdPost', 'ShellFilterPost', 'SourceCmd',
+ 'SourcePre', 'SpellFileMissing', 'StdinReadPost',
+ 'StdinReadPre', 'SwapExists', 'Syntax', 'TabEnter',
+ 'TabLeave', 'TermChanged', 'TermResponse', 'User',
+ 'UserGettingBored', 'VimEnter', 'VimLeave', 'VimLeavePre',
+ 'VimResized', 'WinEnter', 'WinLeave', 'abs', 'add', 'append',
+ 'argc', 'argidx', 'argv', 'atan', 'browse', 'browsedir',
+ 'bufexists', 'buflisted', 'bufloaded', 'bufname', 'bufnr',
+ 'bufwinnr', 'byte2line', 'byteidx', 'ceil', 'changenr',
+ 'char2nr', 'cindent', 'clearmatches', 'col', 'complete',
+ 'complete_add', 'complete_check', 'copy',
+ 'cos', 'count', 'cscope_connection', 'cursor', 'deepcopy',
+ 'delete', 'did_filetype', 'diff_filler', 'diff_hlID',
+ 'empty', 'escape', 'eval', 'eventhandler', 'executable',
+ 'exists', 'expand', 'extend', 'feedkeys', 'filereadable',
+ 'filewritable', 'filter', 'finddir', 'findfile', 'float2nr',
+ 'floor', 'fnameescape', 'fnamemodify', 'foldclosed',
+ 'foldclosedend', 'foldlevel', 'foldtext', 'foldtextresult',
+ 'foreground', 'garbagecollect', 'get', 'getbufline',
+ 'getbufvar', 'getchar', 'getcharmod', 'getcmdline',
+ 'getcmdpos', 'getcmdtype', 'getcwd', 'getfontname',
+ 'getfperm', 'getfsize', 'getftime', 'getftype', 'getline',
+ 'getloclist', 'getmatches', 'getpid', 'getpos', 'getqflist',
+ 'getreg', 'getregtype', 'gettabwinvar', 'getwinposx',
+ 'getwinposy', 'getwinvar', 'glob', 'globpath', 'has',
+ 'has_key', 'haslocaldir', 'hasmapto', 'histadd', 'histdel',
+ 'histget', 'histnr', 'hlID', 'hlexists', 'hostname', 'iconv',
+ 'indent', 'index', 'input', 'inputdialog', 'inputlist',
+ 'inputrestore', 'inputsave', 'inputsecret', 'insert',
+ 'isdirectory', 'islocked', 'items', 'join', 'keys', 'len',
+ 'libcall', 'libcallnr', 'line', 'line2byte', 'lispindent',
+ 'localtime', 'log10', 'maparg', 'mapcheck', 'matchadd',
+ 'matcharg', 'matchdelete', 'matchend', 'matchlist',
+ 'matchstr', 'max', 'min', 'mkdir', 'mode', 'nextnonblank',
+ 'nr2char', 'off', 'on', 'pathshorten', 'plugin', 'pow',
+ 'prevnonblank', 'printf', 'pumvisible', 'range', 'readfile',
+ 'reltime', 'reltimestr', 'remote_expr', 'remote_foreground',
+ 'remote_peek', 'remote_read', 'remote_send', 'remove',
+ 'rename', 'repeat', 'resolve', 'reverse', 'round', 'search',
+ 'searchdecl', 'searchpair', 'searchpairpos', 'searchpos',
+ 'server2client', 'serverlist', 'setbufvar', 'setcmdpos',
+ 'setline', 'setloclist', 'setmatches', 'setpos', 'setqflist',
+ 'setreg', 'settabwinvar', 'setwinvar', 'shellescape',
+ 'simplify', 'sin', 'sort', 'soundfold', 'spellbadword',
+ 'spellsuggest', 'split', 'sqrt', 'str2float', 'str2nr',
+ 'strftime', 'stridx', 'string', 'strlen', 'strpart',
+ 'strridx', 'strtrans', 'submatch', 'substitute',
+ 'synID', 'synIDattr', 'synIDtrans', 'synstack', 'system',
+ 'tabpagebuflist', 'tabpagenr', 'tabpagewinnr', 'tagfiles',
+ 'taglist', 'tempname', 'tolower', 'toupper', 'trunc',
+ 'type', 'values', 'virtcol', 'visualmode', 'winbufnr',
+ 'wincol', 'winline', 'winnr', 'winrestcmd',
+ 'winrestview', 'winsaveview', 'writefile'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '!', '%', '&', '*', '|', '/', '<', '>',
+ '^', '-', '+', '~', '?', ':', '$', '@', '.'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ ),
+ 'STYLES' => array(
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+// 2 => 'color: #009966; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => ''
+ ),
+ 'KEYWORDS' => array(
+ 1 => 'color: #804040;',
+ 2 => 'color: #668080;',
+ 3 => 'color: #25BB4D;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #000000;',
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000; font-weight:bold;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #C5A22D;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false, //Save some time as OO identifiers aren't used
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/visualfoxpro.php b/platform/www/vendor/geshi/geshi/src/geshi/visualfoxpro.php
new file mode 100644
index 0000000..cda3d5a
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/visualfoxpro.php
@@ -0,0 +1,454 @@
+<?php
+/*************************************************************************************
+ * visualfoxpro.php
+ * ----------------
+ * Author: Roberto Armellin (r.armellin@tin.it)
+ * Copyright: (c) 2004 Roberto Armellin, Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/09/17
+ *
+ * Visual FoxPro language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Removed tab as a symbol char
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/10/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Visual Fox Pro',
+ 'COMMENT_SINGLE' => array(1 => "//", 2 => "\n*"),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'Case', 'Else', '#Else', 'Then',
+ 'Endcase', 'Enddefine', 'Enddo', 'Endfor', 'Endfunc', 'Endif', 'Endprintjob',
+ 'Endproc', 'Endscan', 'Endtext', 'Endwith', '#Endif',
+ '#Elif','#Define','#If','#Include',
+ '#Itsexpression','#Readclauses','#Region','#Section','#Undef','#Wname',
+ 'Define','Do',
+ 'For','Function','Hidden',
+ 'If','Local','Lparameter','Lparameters','Next','Otherwise',
+ 'Parameters','Printjob','Procedure','Protected','Public','Scan',
+ 'Text','While','With','Abs','Accept','Access','Aclass','Acopy',
+ 'Acos','Adatabases','Adbobjects','Addbs','Addrelationtoenv','Addtabletoenv',
+ 'Adel','Adir','Aelement','Aerror','Afields','Afont',
+ 'Agetclass','Agetfileversion','Ains','Ainstance','Alen','Align',
+ 'Alines','Alltrim','Alter','Amembers','Amouseobj','Anetresources',
+ 'Ansitooem','Append','Aprinters','Ascan','Aselobj','Asin',
+ 'Asort','Assert','Asserts','Assist','Asubscript','Asynchronous',
+ 'At_c','Atan','Atc','Atcc','Atcline','Atline',
+ 'Atn2','Aused','Autoform','Autoreport','Avcxclasses','Average',
+ 'BarCount','BarPrompt','BatchMode','BatchUpdateCount','Begin','BellSound',
+ 'BinToC','Bitand','Bitclear','Bitlshift','Bitnot',
+ 'Bitor','Bitrshift','Bitset','Bittest','Bitxor','Bof',
+ 'Browse','BrowseRefresh','Buffering','BuilderLock','COMArray','COMReturnError',
+ 'CToBin','Calculate','Call','Capslock','Cd','Cdow',
+ 'Ceiling','Central','Change','Char','Chdir','Chr',
+ 'Chrsaw','Chrtran','Chrtranc','Close','Cmonth','Cntbar',
+ 'Cntpad','Col','Comclassinfo','CommandTargetQuery','Compile','Completed',
+ 'Compobj','Compute','Concat','ConnectBusy','ConnectHandle','ConnectName',
+ 'ConnectString','ConnectTimeOut','ContainerReleaseType','Continue','Copy','Cos',
+ 'Cot','Count','Coverage','Cpconvert','Cpcurrent','Cpdbf',
+ 'Cpnotrans','Create','CreateBinary','Createobject','Createobjectex','Createoffline',
+ 'CrsBuffering','CrsFetchMemo','CrsFetchSize','CrsMaxRows','CrsMethodUsed','CrsNumBatch',
+ 'CrsShareConnection','CrsUseMemoSize','CrsWhereClause','Ctod','Ctot',
+ 'Curdate','Curdir','CurrLeft','CurrSymbol','CursorGetProp','CursorSetProp',
+ 'Curtime','Curval','DBGetProp','DBSetProp','DB_BufLockRow','DB_BufLockTable',
+ 'DB_BufOff','DB_BufOptRow','DB_BufOptTable','DB_Complette','DB_DeleteInsert','DB_KeyAndModified',
+ 'DB_KeyAndTimestamp','DB_KeyAndUpdatable','DB_LocalSQL','DB_NoPrompt','DB_Prompt','DB_RemoteSQL',
+ 'DB_TransAuto','DB_TransManual','DB_TransNone','DB_Update','Datetime','Day',
+ 'Dayname','Dayofmonth','Dayofweek','Dayofyear','Dbalias','Dbused',
+ 'Ddeaborttrans','Ddeadvise','Ddeenabled','Ddeexecute','Ddeinitiate','Ddelasterror',
+ 'Ddepoke','Dderequest','Ddesetoption','Ddesetservice','Ddesettopic','Ddeterminate',
+ 'Debugout','Declare','DefOLELCid','DefaultValue','Defaultext','Degrees',
+ 'DeleteTrigger','Desc','Description','Difference','Dimension','Dir',
+ 'Directory','Diskspace','DispLogin','DispWarnings','Display','Dll',
+ 'Dmy','DoDefault','DoEvents','Doc','Dow',
+ 'Drivetype','Drop','Dropoffline','Dtoc','Dtor','Dtos',
+ 'Dtot','DynamicInputMask','Each','Edit','Eject','Elif',
+ 'End','Eof','Erase','Evaluate','Event','Eventtracking',
+ 'Exclude','Exclusive','Exit','Exp','Export','External',
+ 'FDate','FTime','Fchsize','Fclose','Fcount','Fcreate',
+ 'Feof','Ferror','FetchMemo','FetchSize','Fflush','Fgets',
+ 'Filer','Filetostr','Find','Fklabel','Fkmax','Fldlist',
+ 'Flock','Floor','Flush','Fontmetric','Fopen','Forceext',
+ 'Forcepath','FormSetClass','FormSetLib','FormsClass','FormsLib','Found',
+ 'FoxPro','Foxcode','Foxdoc','Foxgen','Foxgraph','Foxview',
+ 'Fputs','Fread','French','Fseek','Fsize','Fv',
+ 'Fwrite','Gather','German','GetPem','Getbar','Getcolor',
+ 'Getcp','Getdir','Getenv','Getexpr','Getfile','Getfldstate',
+ 'Getfont','Gethost','Getnextmodified','Getobject','Getpad','Getpict',
+ 'Getprinter','Go','Gomonth','Goto','Graph','GridHorz',
+ 'GridShow','GridShowPos','GridSnap','GridVert','Help','HelpOn',
+ 'HelpTo','HighLightRow','Home','Hour','IMEStatus','IdleTimeOut',
+ 'Idxcollate','Ifdef','Ifndef','Iif','Import','Include',
+ 'Indbc','Index','Indexseek','Inkey','Inlist','Input',
+ 'Insert','InsertTrigger','Insmode','IsBlank','IsFLocked','IsLeadByte',
+ 'IsMouse','IsNull','IsRLocked','Isalpha','Iscolor','Isdigit',
+ 'IsExclusive','Ishosted','IsLower','IsReadOnly',
+ 'IsUpper','Italian','Japan','Join','Justdrive','Justext',
+ 'Justfname','Justpath','Juststem','KeyField','KeyFieldList','Keyboard'
+ ),
+ 2 => array('Keymatch','LastProject','Lastkey','Lcase','Leftc','Len',
+ 'Lenc','Length','Likec','Lineno','LoadPicture',
+ 'Locate','Locfile','Log','Log10','Logout','Lookup',
+ 'Loop','Lower','Ltrim','Lupdate','Mail','MaxRecords',
+ 'Mcol','Md','Mdown','Mdx','Mdy','Memlines',
+ 'Menu','Messagebox','Minute','Mkdir','Mline','Modify',
+ 'Month','Monthname','Mouse','Mrkbar','Mrkpad','Mrow',
+ 'Mtdll','Mton','Mwindow','Native','Ndx','Network',
+ 'NoFilter','Nodefault','Normalize','Note','Now','Ntom',
+ 'NullString','Numlock','Nvl','ODBChdbc','ODBChstmt','OLEDropTextInsertion',
+ 'OLELCid','Objnum','Objref','Objtoclient','Objvar','Occurs',
+ 'Oemtoansi','Oldval','OlePublic','Olereturnerror','On','Open',
+ 'Oracle','Order','Os','Outer','PCount','Pack',
+ 'PacketSize','Padc','Padl','Padr','Payment','Pcol',
+ 'PemStatus','Pi','Pivot','Play','Pop','Popup',
+ 'Power','PrimaryKey','Printstatus','Private','Prmbar','Prmpad',
+ 'ProjectClick','Proper','Prow','Prtinfo','Push','Putfile',
+ 'Pv','Qpr','Quater','QueryTimeOut','Quit','Radians',
+ 'Rand','Rat','Ratc','Ratline','Rd','Rdlevel',
+ 'Read','Readkey','Recall','Reccount','RecentlyUsedFiles','Recno',
+ 'Recsize','Regional','Reindex','RelatedChild','RelatedTable','RelatedTag',
+ 'Remove','Rename','Repeat','Replace','Replicate','Report',
+ 'ResHeight','ResWidth','ResourceOn','ResourceTo','Resources','Restore',
+ 'Resume','Retry','Return','Revertoffline','Rgbscheme','Rightc',
+ 'Rlock','Rmdir','Rollback','Round','Rtod','Rtrim',
+ 'RuleExpression','RuleText','Run','Runscript','Rview','SQLAsynchronous',
+ 'SQLBatchMode','SQLCancel','SQLColumns','SQLConnect','SQLConnectTimeOut','SQLDisconnect',
+ 'SQLDispLogin','SQLDispWarnings','SQLExec','SQLGetProp','SQLIdleTimeOut','SQLMoreResults',
+ 'SQLPrepare','SQLQueryTimeOut','SQLSetProp','SQLTables','SQLTransactions','SQLWaitTime',
+ 'Save','SavePicture','ScaleUnits','Scatter','Scols',
+ 'Scroll','Sec','Second','Seek','Select','SendUpdates',
+ 'Set','SetDefault','Setfldstate','Setup','ShareConnection','ShowOLEControls',
+ 'ShowOLEInsertable','ShowVCXs','Sign','Sin','Size','SizeBox',
+ 'Skpbar','Skppad','Sort','Soundex','SourceName','Sqlcommit',
+ 'Sqll','Sqlrollback','Sqlstringconnect','Sqrt','Srows','StatusBar',
+ 'Store','Str','Strconv','Strtofile','Strtran','Stuff',
+ 'Stuffc','Substr','Substrc','Substring','Sum','Suspend',
+ 'Sys','Sysmetric','TabOrdering','Table','TableRefresh','Tablerevert',
+ 'Tableupdate','TagCount','TagNo','Tan','Target','This',
+ 'Thisform','Thisformset','Timestamp','Timestampdiff','Total','Transactions',
+ 'Transform','Trim','Truncate','Ttoc','Ttod','Txnlevel',
+ 'Txtwidth','Type','Ucase','Undefine','Unlock','Unpack',
+ 'Updatable','UpdatableFieldList','Update','UpdateName','UpdateNameList','UpdateTrigger',
+ 'UpdateType','Updated','Upper','Upsizing','Usa','Use',
+ 'UseMemoSize','Used','Val','Validate','Varread','Vartype',
+ 'Version','VersionLanguage','Wait','WaitTime','Wborder','Wchild',
+ 'Wcols','Week','Wexist','Wfont','WhereType','Windcmd',
+ 'Windhelp','Windmemo','Windmenu','Windmodify','Windquery','Windscreen',
+ 'Windsnip','Windstproc','WizardPrompt','Wlast','Wlcol','Wlrow',
+ 'Wmaximum','Wminimum','Wontop','Woutput','Wparent','Wread',
+ 'Wrows','Wtitle','Wvisible','Year','Zap','_Alignment',
+ '_Asciicols','_Asciirows','_Assist','_Beautify','_Box','_Browser',
+ '_Builder','_Calcmem','_Calcvalue','_Cliptext','_Converter','_Coverage',
+ '_Curobj','_Dblclick','_Diarydate','_Dos','_Foxdoc','_Foxgraph',
+ '_Gallery','_Gengraph','_Genhtml','_Genmenu','_Genpd','_Genscrn',
+ '_Genxtab','_Getexpr','_Include','_Indent','_Lmargin','_Mac',
+ '_Mbr_appnd','_Mbr_cpart','_Mbr_delet','_Mbr_font','_Mbr_goto','_Mbr_grid',
+ '_Mbr_link','_Mbr_mode','_Mbr_mvfld','_Mbr_mvprt','_Mbr_seek','_Mbr_sp100',
+ '_Mbr_sp200','_Mbr_szfld','_Mbrowse','_Mda_appnd','_Mda_avg','_Mda_brow',
+ '_Mda_calc','_Mda_copy','_Mda_count','_Mda_label','_Mda_pack','_Mda_reprt',
+ '_Mda_rindx','_Mda_setup','_Mda_sort','_Mda_sp100','_Mda_sp200','_Mda_sp300',
+ '_Mda_sum','_Mda_total','_Mdata','_Mdiary','_Med_clear','_Med_copy',
+ '_Med_cut','_Med_cvtst','_Med_find','_Med_finda','_Med_goto','_Med_insob',
+ '_Med_link','_Med_obj','_Med_paste','_Med_pref','_Med_pstlk','_Med_redo',
+ '_Med_repl','_Med_repla','_Med_slcta','_Med_sp100','_Med_sp200','_Med_sp300',
+ '_Med_sp400','_Med_sp500','_Med_undo','_Medit','_Mfi_clall','_Mfi_close',
+ '_Mfi_export','_Mfi_import','_Mfi_new','_Mfi_open','_Mfi_pgset','_Mfi_prevu',
+ '_Mfi_print','_Mfi_quit','_Mfi_revrt','_Mfi_savas','_Mfi_save','_Mfi_send',
+ '_Mfi_setup','_Mfi_sp100','_Mfi_sp200','_Mfi_sp300','_Mfi_sp400','_Mfile',
+ '_Mfiler','_Mfirst','_Mlabel','_Mlast','_Mline','_Mmacro',
+ '_Mmbldr','_Mpr_beaut','_Mpr_cancl','_Mpr_compl','_Mpr_do','_Mpr_docum',
+ '_Mpr_formwz','_Mpr_gener','_Mpr_graph','_Mpr_resum','_Mpr_sp100','_Mpr_sp200',
+ '_Mpr_sp300','_Mpr_suspend','_Mprog','_Mproj','_Mrc_appnd','_Mrc_chnge',
+ '_Mrc_cont','_Mrc_delet','_Mrc_goto','_Mrc_locat','_Mrc_recal','_Mrc_repl',
+ '_Mrc_seek','_Mrc_sp100','_Mrc_sp200','_Mrecord','_Mreport','_Mrqbe',
+ '_Mscreen','_Msm_data','_Msm_edit','_Msm_file','_Msm_format','_Msm_prog',
+ '_Msm_recrd','_Msm_systm','_Msm_text','_Msm_tools','_Msm_view','_Msm_windo',
+ '_Mst_about','_Mst_ascii','_Mst_calcu','_Mst_captr','_Mst_dbase','_Mst_diary',
+ '_Mst_filer','_Mst_help','_Mst_hphow','_Mst_hpsch','_Mst_macro','_Mst_office',
+ '_Mst_puzzl','_Mst_sp100','_Mst_sp200','_Mst_sp300','_Mst_specl','_Msysmenu',
+ '_Msystem','_Mtable','_Mtb_appnd','_Mtb_cpart','_Mtb_delet','_Mtb_delrc',
+ '_Mtb_goto','_Mtb_link','_Mtb_mvfld','_Mtb_mvprt','_Mtb_props','_Mtb_recal',
+ '_Mtb_sp100','_Mtb_sp200','_Mtb_sp300','_Mtb_sp400','_Mtb_szfld','_Mwi_arran',
+ '_Mwi_clear','_Mwi_cmd','_Mwi_color','_Mwi_debug','_Mwi_hide','_Mwi_hidea',
+ '_Mwi_min','_Mwi_move','_Mwi_rotat','_Mwi_showa','_Mwi_size','_Mwi_sp100',
+ '_Mwi_sp200','_Mwi_toolb','_Mwi_trace','_Mwi_view','_Mwi_zoom','_Mwindow',
+ '_Mwizards','_Mwz_all','_Mwz_form','_Mwz_foxdoc','_Mwz_import','_Mwz_label',
+ '_Mwz_mail','_Mwz_pivot','_Mwz_query','_Mwz_reprt','_Mwz_setup','_Mwz_table',
+ '_Mwz_upsizing','_Netware','_Oracle','_Padvance','_Pageno','_Pbpage',
+ '_Pcolno','_Pcopies','_Pdparms','_Pdriver','_Pdsetup','_Pecode',
+ '_Peject','_Pepage','_Pform','_Plength','_Plineno','_Ploffset',
+ '_Ppitch','_Pquality','_Pretext','_Pscode','_Pspacing','_Pwait',
+ '_Rmargin','_Runactivedoc','_Samples','_Screen','_Shell','_Spellchk',
+ '_Sqlserver','_Startup','_Tabs','_Tally','_Text','_Throttle',
+ '_Transport','_Triggerlevel','_Unix','_WebDevOnly','_WebMenu','_WebMsftHomePage',
+ '_WebVFPHomePage','_WebVfpOnlineSupport','_Windows','_Wizard','_Wrap','_scctext',
+ '_vfp','Additive','After','Again','Aindent','Alignright',
+ 'All','Alt','Alternate','And','Ansi','Any',
+ 'Aplabout','App','Array','As','Asc','Ascending',
+ 'Ascii','At','Attributes','Automatic','Autosave','Avg',
+ 'Bar','Before','Bell','Between','Bitmap','Blank',
+ 'Blink','Blocksize','Border','Bottom','Brstatus','Bucket',
+ 'Buffers','By','Candidate','Carry','Cascade','Catalog',
+ 'Cdx','Center','Century','Cga','Character','Check',
+ 'Classlib','Clock','Cnt','Codepage','Collate','Color',
+ 'Com1','Com2','Command','Compact','Compatible','Compress',
+ 'Confirm','Connection','Connections','Connstring','Console','Copies',
+ 'Cpcompile','Cpdialog','Csv','Currency','Cycle','Databases',
+ 'Datasource','Date','Db4','Dbc','Dbf','Dbmemo3',
+ 'Debug','Decimals','Defaultsource','Deletetables','Delimited','Delimiters',
+ 'Descending','Design','Development','Device','Dif','Disabled',
+ 'Distinct','Dlls','Dohistory','Dos','Dosmem','Double',
+ 'Driver','Duplex','Echo','Editwork','Ega25','Ega43',
+ 'Ems','Ems64','Encrypt','Encryption','Environment','Escape',
+ 'Events','Exact','Except','Exe','Exists','Expression',
+ 'Extended','F','Fdow','Fetch','Field','Fields',
+ 'File','Files','Fill','Fixed','Float','Foldconst',
+ 'Font','Footer','Force','Foreign','Fox2x','Foxplus',
+ 'Free','Freeze','From','Fullpath','Fw2','Fweek',
+ 'Get','Gets','Global','Group','Grow','Halfheight',
+ 'Having','Heading','Headings','Helpfilter','History','Hmemory',
+ 'Hours','Id','In','Indexes','Information','Instruct',
+ 'Int','Integer','Intensity','Intersect','Into','Is',
+ 'Isometric','Key','Keycolumns','Keycomp','Keyset','Last',
+ 'Ledit','Level','Library','Like','Linked','Lock',
+ 'Logerrors','Long','Lpartition','Mac','Macdesktop','Machelp',
+ 'Mackey','Macros','Mark','Master','Max','Maxmem',
+ 'Mdi','Memlimit','Memory','Memos','Memowidth','Memvar',
+ 'Menus','Messages','Middle','Min','Minimize','Minus',
+ 'Mod','Modal','Module','Mono43','Movers','Multilocks',
+ 'Mvarsiz','Mvcount','N','Near','Negotiate','Noalias',
+ 'Noappend','Noclear','Noclose','Noconsole','Nocptrans','Nodata',
+ 'Nodebug','Nodelete','Nodup','Noedit','Noeject','Noenvironment',
+ 'Nofloat','Nofollow','Nogrow','Noinit','Nolgrid','Nolink',
+ 'Nolock','Nomargin','Nomdi','Nomenu','Nominimize','Nomodify'
+ ),
+ 3 => array('Nomouse','None','Nooptimize','Nooverwrite','Noprojecthook','Noprompt',
+ 'Noread','Norefresh','Norequery','Norgrid','Norm','Normal',
+ 'Nosave','Noshadow','Noshow','Nospace','Not','Notab',
+ 'Notify','Noupdate','Novalidate','Noverify','Nowait','Nowindow',
+ 'Nowrap','Nozoom','Npv','Null','Number','Objects',
+ 'Odometer','Of','Off','Oleobjects','Only','Optimize',
+ 'Or','Orientation','Output','Outshow','Overlay','Overwrite',
+ 'Pad','Palette','Paperlength','Papersize','Paperwidth','Password',
+ 'Path','Pattern','Pause','Pdox','Pdsetup','Pen',
+ 'Pfs','Pixels','Plain','Popups','Precision','Preference',
+ 'Preview','Primary','Printer','Printquality','Procedures','Production',
+ 'Program','Progwork','Project','Prompt','Query','Random',
+ 'Range','Readborder','Readerror','Record','Recover','Redit',
+ 'Reference','References','Relative','Remote','Reprocess','Resource',
+ 'Rest','Restrict','Rgb','Right','Row','Rowset',
+ 'Rpd','Runtime','Safety','Same','Sample','Say',
+ 'Scale','Scheme','Scoreboard','Screen','Sdf','Seconds',
+ 'Selection','Shadows','Shared','Sheet','Shell','Shift',
+ 'Shutdown','Single','Some','Sortwork','Space','Sql',
+ 'Standalone','Status','Std','Step','Sticky','String',
+ 'Structure','Subclass','Summary','Sylk','Sysformats','Sysmenus',
+ 'System','T','Tab','Tables','Talk','Tedit',
+ 'Textmerge','Time','Timeout','Titles','Tmpfiles','To',
+ 'Topic','Transaction','Trap','Trbetween','Trigger','Ttoption',
+ 'Typeahead','Udfparms','Union','Unique','Userid','Users',
+ 'Values','Var','Verb','Vga25','Vga50','Views',
+ 'Volume','Where','Windows','Wk1','Wk3','Wks',
+ 'Workarea','Wp','Wr1','Wrap','Wrk','Xcmdfile',
+ 'Xl5','Xl8','Xls','Y','Yresolution','Zoom',
+ 'Activate','ActivateCell','Add','AddColumn','AddItem','AddListItem',
+ 'AddObject','AddProperty','AddToSCC','AfterBuild','AfterCloseTables','AfterDock',
+ 'AfterRowColChange','BeforeBuild','BeforeDock','BeforeOpenTables','BeforeRowColChange','Box',
+ 'Build','CheckIn','CheckOut','Circle','Clear','ClearData',
+ 'Cleanup','Click','CloneObject','CloseEditor','CloseTables','Cls',
+ 'CommandTargetExec','CommandTargetQueryStas','ContainerRelease','DataToClip','DblClick','Deactivate',
+ 'Delete','DeleteColumn','Deleted','Destroy','DoCmd','Dock',
+ 'DoScroll','DoVerb','DownClick','Drag','DragDrop','DragOver',
+ 'DropDown','Draw','EnterFocus','Error','ErrorMessage','Eval',
+ 'ExitFocus','FormatChange','GetData','GetFormat','GetLatestVersion','GoBack',
+ 'GotFocus','GoForward','GridHitTest','Hide','HideDoc','IndexToItemId',
+ 'Init','InteractiveChange','Item','ItemIdToIndex','KeyPress','Line',
+ 'Load','LostFocus','Message','MiddleClick','MouseDown','MouseMove',
+ 'MouseUp','MouseWheel','Move','Moved','NavigateTo','Newobject',
+ 'OLECompleteDrag','OLEDrag','OLEDragDrop','OLEDragOver','OLEGiveFeedback','OLESetData',
+ 'OLEStartDrag','OpenEditor','OpenTables','Paint','Point','Print',
+ 'ProgrammaticChange','PSet','QueryAddFile','QueryModifyFile','QueryRemoveFile','QueryRunFile',
+ 'QueryUnload','RangeHigh','RangeLow','ReadActivate','ReadExpression','ReadDeactivate',
+ 'ReadMethod','ReadShow','ReadValid','ReadWhen','Refresh','Release',
+ 'RemoveFromSCC','RemoveItem','RemoveListItem','RemoveObject','Requery','RequestData',
+ 'Reset','ResetToDefault','Resize','RightClick','SaveAs','SaveAsClass',
+ 'Scrolled','SetAll','SetData','SetFocus','SetFormat','SetMain',
+ 'SetVar','SetViewPort','ShowDoc','ShowWhatsThis','TextHeight','TextWidth',
+ 'Timer','UIEnable','UnDock','UndoCheckOut','Unload','UpClick',
+ 'Valid','WhatsThisMode','When','WriteExpression','WriteMethod','ZOrder',
+ 'ATGetColors','ATListColors','Accelerate','ActiveColumn','ActiveControl','ActiveForm',
+ 'ActiveObjectId','ActivePage','ActiveProject','ActiveRow','AddLineFeeds','Alias',
+ 'Alignment','AllowAddNew','AllowHeaderSizing','AllowResize','AllowRowSizing','AllowTabs',
+ 'AlwaysOnTop','Application','AutoActivate','AutoCenter','AutoCloseTables','AutoIncrement',
+ 'AutoOpenTables','AutoRelease','AutoSize','AutoVerbMenu','AutoYield','AvailNum',
+ 'BackColor','BackStyle','BaseClass','BorderColor','BorderStyle','BorderWidth',
+ 'Bound','BoundColumn','BoundTo','BrowseAlignment','BrowseCellMarg','BrowseDestWidth',
+ 'BufferMode','BufferModeOverride','BuildDateTime','ButtonCount','ButtonIndex','Buttons',
+ 'CLSID','CanAccelerate','CanGetFocus','CanLoseFocus','Cancel','Caption',
+ 'ChildAlias','ChildOrder','Class','ClassLibrary','ClipControls','ClipRect',
+ 'Closable','ColorScheme','ColorSource','ColumnCount','ColumnHeaders','ColumnLines',
+ 'ColumnOrder','ColumnWidths','Columns','Comment','ContinuousScroll','ControlBox',
+ 'ControlCount','ControlIndex','ControlSource','Controls','CurrentControl','CurrentX',
+ 'CurrentY','CursorSource','Curvature','DataSession','DataSessionId','DataSourceObj',
+ 'DataType','Database','DateFormat','DateMark','DefButton','DefButtonOrig',
+ 'DefHeight','DefLeft','DefTop','DefWidth','Default','DefaultFilePath',
+ 'DefineWindows','DeleteMark','Desktop','Dirty','DisabledBackColor','DisabledByEOF',
+ 'DisabledForeColor','DisabledItemBackColor','DisabledItemForeColor','DisabledPicture','DispPageHeight','DispPageWidth',
+ 'DisplayCount','DisplayValue','DoCreate','DockPosition','Docked','DocumentFile',
+ 'DownPicture','DragIcon','DragMode','DragState','DrawMode','DrawStyle',
+ 'DrawWidth','DynamicAlignment','DynamicBackColor','DynamicCurrentControl','DynamicFontBold','DynamicFontItalic',
+ 'DynamicFontName','DynamicFontOutline','DynamicFontShadow','DynamicFontSize','DynamicFontStrikethru','DynamicFontUnderline',
+ 'DynamicForeColor','EditFlags','Enabled','EnabledByReadLock','Encrypted','EnvLevel',
+ 'ErasePage','FileClass','FileClassLibrary','FillColor','FillStyle','Filter',
+ 'FirstElement','FontBold','FontItalic','FontName','FontOutline','FontShadow',
+ 'FontSize','FontStrikethru','FontUnderline','ForceFocus','ForeColor','FormCount',
+ 'FormIndex','FormPageCount','FormPageIndex','Format','Forms','FoxFont',
+ 'FullName','GoFirst','GoLast','GridLineColor','GridLineWidth','GridLines'
+ ),
+ 4 => array('HPROJ','HWnd','HalfHeightCaption','HasClip','HeaderGap','HeaderHeight',
+ 'Height','HelpContextID','HideSelection','Highlight','HomeDir','HostName',
+ 'HotKey','HscrollSmallChange','IMEMode','Icon','IgnoreInsert','InResize',
+ 'Increment','IncrementalSearch','InitialSelectedAlias','InputMask','Instancing','IntegralHeight',
+ 'Interval','ItemBackColor','ItemData','ItemForeColor','ItemIDData','ItemTips',
+ 'JustReadLocked','KeyPreview','KeyboardHighValue','KeyboardLowValue','LastModified','Left',
+ 'LeftColumn','LineSlant','LinkMaster','List','ListCount','ListIndex',
+ 'ListItem','ListItemId','LockDataSource','LockScreen','MDIForm','MainClass',
+ 'MainFile','Margin','MaxButton','MaxHeight','MaxLeft','MaxLength',
+ 'MaxTop','MaxWidth','MemoWindow','MinButton','MinHeight','MinWidth',
+ 'MouseIcon','MousePointer','Movable','MoverBars','MultiSelect','Name',
+ 'NapTime','NewIndex','NewItemId','NoDataOnLoad','NoDefine','NotifyContainer',
+ 'NullDisplay','NumberOfElements','OLEDragMode','OLEDragPicture','OLEDropEffects','OLEDropHasData',
+ 'OLEDropMode','OLERequestPendingTimeOut','OLEServerBusyRaiseError','OLEServerBusyTimeOut','OLETypeAllowed','OleClass',
+ 'OleClassId','OleControlContainer','OleIDispInValue','OleIDispOutValue','OleIDispatchIncoming','OleIDispatchOutgoing',
+ 'OnResize','OneToMany','OpenViews','OpenWindow','PageCount','PageHeight',
+ 'PageOrder','PageWidth','Pages','Panel','PanelLink','Parent',
+ 'ParentAlias','ParentClass','Partition','PasswordChar','Picture','ProcessID',
+ 'ProgID','ProjectHookClass','ProjectHookLibrary','Projects','ReadColors','ReadCycle',
+ 'ReadFiller','ReadLock','ReadMouse','ReadOnly','ReadSave','ReadSize',
+ 'ReadTimeout','RecordMark','RecordSource','RecordSourceType','Rect','RelationalExpr',
+ 'RelativeColumn','RelativeRow','ReleaseErase','ReleaseType','ReleaseWindows','Resizable',
+ 'RightToLeft','RowHeight','RowSource','RowSourceType','SCCProvider','SCCStatus',
+ 'SDIForm','ScaleMode','ScrollBars','SelLength','SelStart','SelText',
+ 'SelectOnEntry','Selected','SelectedBackColor','SelectedForeColor','SelectedID','SelectedItemBackColor',
+ 'SelectedItemForeColor','SelfEdit','ServerClass','ServerClassLibrary','ServerHelpFile','ServerName',
+ 'ServerProject','ShowTips','ShowWindow','Sizable','Size<height>','Size<maxlength>',
+ 'Size<width>','Skip','SkipForm','Sorted','SourceType','Sparse',
+ 'SpecialEffect','SpinnerHighValue','SpinnerLowValue','SplitBar','StartMode','StatusBarText',
+ 'Stretch','StrictDateEntry','Style','SystemRefCount','TabIndex','TabStop',
+ 'TabStretch','TabStyle','Tabhit','Tabs','Tag','TerminateRead',
+ 'ThreadID','TitleBar','ToolTipText','Top','TopIndex','TopItemId',
+ 'TypeLibCLSID','TypeLibDesc','TypeLibName','UnlockDataSource','Value','ValueDirty',
+ 'VersionComments','VersionCompany','VersionCopyright','VersionDescription','VersionNumber','VersionProduct',
+ 'VersionTrademarks','View','ViewPortHeight','ViewPortLeft','ViewPortTop','ViewPortWidth',
+ 'Visible','VscrollSmallChange','WasActive','WasOpen','WhatsThisButton','WhatsThisHelp',
+ 'WhatsThisHelpID','Width','WindowList','WindowNTIList','WindowState','WindowType',
+ 'WordWrap','ZOrderSet','ActiveDoc','Checkbox','Column','ComboBox',
+ 'CommandButton','CommandGroup','Container','Control','Cursor','Custom',
+ 'DataEnvironment','EditBox','Empty','FontClass','Form','Formset',
+ 'General','Grid','Header','HyperLink','Image','Label',
+ 'ListBox','Memo','OleBaseControl','OleBoundControl','OleClassIDispOut','OleControl',
+ 'OptionButton','OptionGroup','Page','PageFrame','ProjectHook','RectClass',
+ 'Relation','Session','Shape','Spinner','TextBox' ,'Toolbar'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ "!", "@", "$", "%",
+ "(", ")", "{", "}", "[", "]",
+ "-", "+", "*", "/",
+ "=", "<", ">",
+ ":", ";", ",", ".", "&",
+ "?", "??", "???"
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: blue;',
+ 2 => 'color: blue;',
+ 3 => 'color: blue;',
+ 4 => 'color: blue;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: green; font-style: italic;',
+ 2 => 'color: green; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: blue;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: blue;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/visualprolog.php b/platform/www/vendor/geshi/geshi/src/geshi/visualprolog.php
new file mode 100644
index 0000000..edb186c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/visualprolog.php
@@ -0,0 +1,127 @@
+<?php
+/*************************************************************************************
+ * visualprolog.php
+ * ----------
+ * Author: Thomas Linder Puls (puls@pdc.dk)
+ * Copyright: (c) 2008 Thomas Linder Puls (puls@pdc.dk)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/11/20
+ *
+ * Visual Prolog language file for GeSHi.
+ *
+ * CHANGES
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Visual Prolog',
+ 'COMMENT_SINGLE' => array(1 => '%'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'HARDQUOTE' => array('@"', '"'),
+ 'HARDESCAPE' => array('""'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'clauses','constants','constructors','delegate','domains','facts',
+ 'goal','guards','inherits','monitor','namespace','open',
+ 'predicates','properties','resolve','supports'
+ ),
+ 2 => array(
+ 'align','and','anyflow','as','bitsize','catch','determ','digits',
+ 'div','do','else','elseif','erroneous','externally','failure',
+ 'finally','from','language','mod','multi','nondeterm','or',
+ 'procedure','quot','rem','single','then','to'
+ ),
+ 3 => array(
+ '#bininclude','#else','#elseif','#endif','#error','#export',
+ '#externally','#if','#import','#include','#message','#options',
+ '#orrequires','#requires','#then','#warning'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '+', '-', '*', '?', '=', '/', '>', '<', '^', '!', ':', '(', ')', '{', '}', '[', ']'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => true,
+ 1 => true,
+ 2 => true,
+ 3 => true
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #808000;',
+ 2 => 'color: #333399;',
+ 3 => 'color: #800080;',
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #AA77BD',
+ 'MULTI' => 'color: #AA77BD'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #008080;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #00B7B7;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #0000FF;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #008000;',
+ 1 => 'color: #808000;',
+ 2 => 'color: #333399;',
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => ':',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ 0 => "(?<![a-zA-Z0-9_])(?!(?:PIPE|SEMI)>)[A-Z_]\w*(?!\w)",
+ 1 => "\\b(end\\s+)?(implement|class|interface)\\b",
+ 2 => "\\b(end\\s+)?(foreach|if|try)\\b",
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/whitespace.php b/platform/www/vendor/geshi/geshi/src/geshi/whitespace.php
new file mode 100644
index 0000000..c11f69f
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/whitespace.php
@@ -0,0 +1,119 @@
+<?php
+/*************************************************************************************
+ * whitespace.php
+ * ----------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2009/10/31
+ *
+ * Whitespace language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/10/31 (1.0.8.1)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+$language_data = array (
+ 'LANG_NAME' => 'Whitespace',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ 3 => "/[^\n\x20\x09]+/s"
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ ),
+ 'COMMENTS' => array(
+ 3 => 'color: #666666; font-style: italic;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ 2 => 'background-color: #FF9999;',
+ 3 => 'background-color: #9999FF;'
+ )
+ ),
+ 'URLS' => array(
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 2 => array(
+ GESHI_SEARCH => "(?<!\\A)\x20",
+ GESHI_REPLACE => "&#32;",
+ GESHI_MODIFIERS => 's',
+ GESHI_BEFORE => "",
+ GESHI_AFTER => ""
+ ),
+ 3 => array(
+ GESHI_SEARCH => "\x09",
+ GESHI_REPLACE => "&#9;",
+ GESHI_MODIFIERS => 's',
+ GESHI_BEFORE => "",
+ GESHI_AFTER => ""
+ ),
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'KEYWORDS' => GESHI_NEVER,
+ 'SYMBOLS' => GESHI_NEVER,
+ 'STRINGS' => GESHI_NEVER,
+// 'REGEXPS' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/whois.php b/platform/www/vendor/geshi/geshi/src/geshi/whois.php
new file mode 100644
index 0000000..e429d25
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/whois.php
@@ -0,0 +1,178 @@
+<?php
+/*************************************************************************************
+ * whois.php
+ * --------
+ * Author: Benny Baumann (BenBE@geshi.org)
+ * Copyright: (c) 2008 Benny Baumann (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/09/14
+ *
+ * Whois response (RPSL format) language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/09/14 (1.0.0)
+ * - First Release
+ *
+ * TODO
+ * ----
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Whois (RPSL format)',
+ 'COMMENT_SINGLE' => array(1 => '% ', 2 => '%ERROR:'),
+ 'COMMENT_MULTI' => array(),
+ 'COMMENT_REGEXP' => array(
+ //Description
+ 3 => '/(?:(?<=^remarks:)|(?<=^descr:))(.|\n\s)*$/mi',
+
+ //Contact Details
+ 4 => '/(?<=^address:)(.|\n\s)*$/mi',
+ 5 => '/\+\d+(?:(?:\s\(\d+(\s\d+)*\))?(?:\s\d+)+|-\d+-\d+)/',
+ 6 => '/\b(?!-|\.)[\w\-\.]+(?!-|\.)@((?!-)[\w\-]+\.)+\w+\b/',
+
+ //IP, Networks and AS information\links
+ 7 => '/\b(?<!\.|\-)(?:[\da-f:]+(?!\.)|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})(?:\/1?\d\d?)?(?<!\.|\-)\b/',
+ 8 => '/\bAS\d+\b/'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array(),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array( //Object Types
+ 'as-block','as-set','aut-num','domain','filter-set','inet-rtr',
+ 'inet6num','inetnum','irt','key-cert','limerick','mntner',
+ 'organisation','peering-set','person','poem','role','route-set',
+ 'route','route6','rtr-set'
+ ),
+ 2 => array( //Field Types
+ 'abuse-mailbox','address','admin-c','aggr-bndry','aggr-mtd','alias',
+ 'as-block','as-name','as-set','aut-num','auth','author','certif',
+ 'changed','components','country','default','descr','dom-net',
+ 'domain','ds-rdata','e-mail','encryption','export','export-comps',
+ 'fax-no','filter','filter-set','fingerpr','form','holes','ifaddr',
+ 'import','inet-rtr','inet6num','inetnum','inject','interface','irt',
+ 'irt-nfy','key-cert','limerick','local-as','mbrs-by-ref',
+ 'member-of','members','method','mnt-by','mnt-domains','mnt-irt',
+ 'mnt-lower','mnt-nfy','mnt-ref','mnt-routes','mntner','mp-default',
+ 'mp-export','mp-filter','mp-import','mp-members','mp-peer',
+ 'mp-peering','netname','nic-hdl','notify','nserver','org',
+ 'org-name','org-type','organisation','origin','owner','peer',
+ 'peering','peering-set','person','phone','poem','ref-nfy','refer',
+ 'referral-by','remarks','rev-srv','role','route','route-set',
+ 'route6','rtr-set','signature','source','status','sub-dom','tech-c',
+ 'text','upd-to','zone-c'
+ ),
+ 3 => array( //RPSL reserved
+ 'accept','action','and','announce','any','as-any','at','atomic',
+ 'except','from','inbound','into','networks','not','or','outbound',
+ 'peeras','refine','rs-any','to'
+ )
+ ),
+ 'SYMBOLS' => array(
+ ':'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF; font-weight: bold;',
+ 2 => 'color: #000080; font-weight: bold;',
+ 3 => 'color: #990000; font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #666666; font-style: italic;',
+ 2 => 'color: #666666; font-style: italic;',
+ 3 => 'color: #404080;',
+ 4 => 'color: #408040;',
+ 5 => 'color: #408040;',
+ 6 => 'color: #408040;',
+ 7 => 'color: #804040;',
+ 8 => 'color: #804040;',
+ 'MULTI' => 'color: #666666; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;',
+ 'HARD' => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #009900;'
+ ),
+ 'STRINGS' => array(
+ 0 => '',
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000080;',
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #0000FF;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #000088;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.irr.net/docs/rpsl.html'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Variables
+ 0 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4,
+ 'PARSER_CONTROL' => array(
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'DISALLOWED_BEFORE' => '(?<=\A |\A \n(?m:^)|\n\n(?m:^))'
+ ),
+ 2 => array(
+ 'DISALLOWED_BEFORE' => '(?m:^)'
+ )
+ ),
+ 'ENABLE_FLAGS' => array(
+ 'BRACKETS' => GESHI_NEVER,
+ 'SYMBOLS' => GESHI_NEVER,
+ 'STRINGS' => GESHI_NEVER,
+ 'ESCAPE_CHAR' => GESHI_NEVER,
+ 'NUMBERS' => GESHI_NEVER,
+ 'METHODS' => GESHI_NEVER,
+ 'SCRIPT' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/winbatch.php b/platform/www/vendor/geshi/geshi/src/geshi/winbatch.php
new file mode 100644
index 0000000..618fb6e
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/winbatch.php
@@ -0,0 +1,367 @@
+<?php
+/*************************************************************************************
+ * winbatch.php
+ * ------------
+ * Author: Craig Storey (storey.craig@gmail.com)
+ * Copyright: (c) 2004 Craig Storey (craig.xcottawa.ca)
+ * Release Version: 1.0.9.1
+ * Date Started: 2006/05/19
+ *
+ * WinBatch language file for GeSHi.
+ *
+ * WinBatch is a Windows scripting language - www.winbatch.com.
+ * The keywords were pulled from the winbatch/system/WIL.clr file for v2005G.
+ * Not all extender functions are added, but a very large set of the most common.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2006/05/05 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/07/14)
+ * -------------------------
+ * - Right now any ':Subroutine' is treated as a comment. This highlights the
+ * Subroutine's name, but it's not a perfect fix. I should use a RegEx in
+ * GeSHI_Search&Replace features..
+ * - Update the list of extender functions.
+ * - Use a regular expression to comment UDFs that start with 'udf_'.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Winbatch',
+ 'COMMENT_SINGLE' => array(1 => ';', 2 => ':'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"', '`'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'While', 'To', 'Then', 'Switch', 'Select', 'Return', 'Next', 'IntControl', 'Include', 'In', 'If',
+ 'Goto', 'GoSub', 'ForEach', 'For', 'Exit', 'Execute', 'ErrorMode', 'EndWhile', 'EndSwitch', '#EndSubRoutine',
+ 'EndSelect', 'EndIf', '#EEndFunction', 'EndFor', 'End', 'Else', 'DropWild', 'Drop', '#DefineSubRoutine',
+ '#DefineFunction', 'Debug', 'Continue', 'Case', 'CallExt', 'Call', 'By', 'BreakPoint', 'Break'
+ ),
+ 2 => array(
+ 'ZOOMED', 'YES', 'WORD4', 'WORD2', 'WORD1', 'WHOLESECTION', 'WAIT', 'UNSORTED', 'UNCHECK', 'TRUE', 'TILE',
+ 'TAB', 'STRING', 'STACK', 'SPC2NET', 'SORTED', 'SOK', 'SNET2PC', 'SINGLE', 'SHIFT', 'SERVER', 'SERRWINSOCK',
+ 'SERRVOICE', 'SERRSOCKET', 'SERRSERVICE', 'SERRSELECT', 'SERRPARAM', 'SERROUTOFMEM', 'SERRNOTFOUND', 'SERRNOCONN',
+ 'SERRNOANSWER', 'SERRMUSTWAIT', 'SERRIPADDR', 'SERRHOSTNAME', 'SERRFAILURE', 'SERRBUSY', 'SCROLLLOCK', 'SCANCEL',
+ 'SAVE', 'SALREADY', 'ROWS', 'REGUSERS', 'REGROOT', 'REGMACHINE', 'REGCURRENT', 'REGCLASSES', 'RDBLCLICK', 'RCLICK',
+ 'RBUTTON', 'RAD2DEG', 'QSUCCESSINFO', 'QSUCCESS', 'QSTILLEX', 'QROLLBACK', 'QNULL', 'QNODATA', 'QNEXT', 'QNEEDDATA',
+ 'QFIRST', 'QCOMMIT', 'QBADHANDLE', 'PRINTER', 'PLANCKJOULES', 'PLANCKERGS', 'PI', 'PARSEONLY', 'PARSEC', 'P3ERRREPLY',
+ 'OPEN', 'ON', 'OFF', 'NUMLOCK', 'NOWAIT', 'NOTIFY', 'NORMAL', 'NORESIZE', 'NONE', 'NO', 'NCSAFORMAT', 'MULTIPLE',
+ 'MSFORMAT', 'MPLAYRDBLCK', 'MPLAYRCLK', 'MPLAYRBUTTON', 'MPLAYMDBLCK', 'MPLAYMCLK', 'MPLAYMBUTTON', 'MPLAYLDBLCK',
+ 'MPLAYLCLK', 'MPLAYLBUTTON', 'MINOR', 'MDBLCLICK', 'MCLICK', 'MBYESNO', 'MBUTTON', 'MBOKCANCEL', 'MAJOR', 'MAGFIELD',
+ 'LOCALGROUP', 'LIGHTMTPS', 'LIGHTMPS', 'LF', 'LDBLCLICK', 'LCLICK', 'LBUTTON', 'LAFFDBERROR', 'ICON', 'HTTPS', 'HTTP',
+ 'HNOHEADER', 'HMETHODPOST', 'HMETHODGET', 'HIDDEN', 'HHEADERONLY', 'HHEADER', 'GRAVITATION', 'GOPHER', 'GOLDENRATIO',
+ 'GMTSEC', 'GLOBALGROUP', 'GFTSEC', 'GETPROCID', 'GETEXITCODE', 'FWDSCAN', 'FTPPASSIVE', 'FTP', 'FLOAT8', 'FARADAY',
+ 'FALSE', 'EXTENDED', 'EULERS', 'ENABLE', 'ELECTRIC', 'DRIVE', 'DISABLE', 'DESCENDING', 'DEG2RAD', 'DEFAULT', 'CTRL',
+ 'CRLF', 'CR', 'COMMONFORMAT', 'COLUMNS', 'CHECK', 'CAPSLOCK', 'CANCEL', 'BOLTZMANN', 'BACKSCAN', 'AVOGADRO', 'ATTR_X',
+ 'ATTR_T', 'ATTR_SY', 'ATTR_SH', 'ATTR_RO', 'ATTR_RI', 'ATTR_P', 'ATTR_IC', 'ATTR_H', 'ATTR_DM', 'ATTR_DI', 'ATTR_DC',
+ 'ATTR_CI', 'ATTR_A', 'ASCENDING', 'ARRANGE', 'AMC', 'ACC_WRITE', 'ACC_READ_NT', 'ACC_READ_95', 'ACC_READ', 'ACC_PRINT_NT',
+ 'ACC_PMANG_NT', 'ACC_PFULL_NT', 'ACC_LIST', 'ACC_FULL_NT', 'ACC_FULL_95', 'ACC_DELETE', 'ACC_CREATE', 'ACC_CONTROL',
+ 'ACC_CHNG_NT', 'ACC_ATTRIB', 'ABOVEICONS'
+ ),
+ 3 => array(
+ 'Yields', 'Yield', 'WinZoom', 'WinWaitExist', 'WinWaitClose', 'WinWaitChild', 'WinVersion', 'WinTitle', 'WinSysInfo',
+ 'WinState', 'WinShow', 'WinResources', 'WinPositionChild', 'WinPosition', 'WinPlaceSet', 'WinPlaceGet', 'WinPlaceChild',
+ 'WinPlace', 'WinParmSet', 'WinParmGet', 'WinName', 'WinMetrics', 'WinItemProcId', 'WinItemNameId', 'WinItemizeEx',
+ 'WinItemize', 'WinItemChild', 'WinIsDos', 'WinIdGet', 'WinIconize', 'WinHide', 'WinHelp', 'WinGetactive', 'WinExistchild',
+ 'WinExist', 'WinExename', 'WinConfig', 'WinClosenot', 'WinClose', 'WinArrange', 'WinActivechild', 'WinActivchild',
+ 'WinActivate', 'WebVerifyCard', 'WebSetTimeout', 'WebParamSize', 'WebParamNames', 'WebParamFile', 'WebParamData',
+ 'WebParamBuf', 'WebOutFile', 'WebOutBinary', 'WebOut', 'WebDumpError', 'WebDatData', 'WebCounter', 'WebConSize', 'WebConData',
+ 'WebConBuf', 'WebCmdData', 'WebBaseConv', 'Wallpaper', 'WaitForKeyEX', 'WaitForKey', 'VersionDLL', 'Version', 'VarType',
+ 'TimeYmdHms', 'TimeWait', 'TimeSubtract', 'TimeJulToYmd', 'TimeJulianDay', 'TimeDiffSecs', 'TimeDiffDays', 'TimeDiff', 'TimeDelay',
+ 'TimeDate', 'TimeAdd', 'TextSelect', 'TextBoxSort', 'TextBox', 'Terminate', 'Tanh', 'Tan', 'SysParamInfo', 'SvcWaitForCmd',
+ 'SvcSetState', 'SvcSetAccept', 'StrUpper', 'StrTrim', 'StrSubWild', 'StrSub', 'StrScan', 'StrReplace', 'StrLower', 'StrLenWild',
+ 'StrLen', 'StrIndexWild', 'StrIndexNC', 'StrIndex', 'StriCmp', 'StrFixLeft', 'StrFixCharsL', 'StrFixChars', 'StrFix', 'StrFill',
+ 'StrCnt', 'StrCmp', 'StrClean', 'StrCharCount', 'StrCat', 'StrByteCount', 'Sqrt', 'SoundVolume', 'Sounds', 'Snapshot', 'Sinh', 'Sin',
+ 'ShortCutMake', 'ShortCutInfo', 'ShortCutExtra', 'ShortCutEdit', 'ShortCutDir', 'ShellExecute', 'SendMenusToEx', 'SendMenusTo',
+ 'SendKeysTo', 'SendKeysChild', 'SendKey', 'RunZoomWait', 'RunZoom', 'RunWithLogon', 'RunWait', 'RunShell', 'RunIconWait',
+ 'RunIcon', 'RunHideWait', 'RunHide', 'RunExit', 'RunEnviron', 'Run', 'RtStatus', 'Reload', 'RegUnloadHive', 'RegSetValue',
+ 'RegSetQword', 'RegSetMulSz', 'RegSetExpSz', 'RegSetEx', 'RegSetDword', 'RegSetBin', 'RegQueryValue', 'RegQueryStr',
+ 'RegQueryQword', 'RegQueryMulSz', 'RegQueryKeys', 'RegQueryKeyLastWriteTime', 'RegQueryKey', 'RegQueryItem', 'RegQueryExpSz',
+ 'RegQueryEx', 'RegQueryDword', 'RegQueryBin', 'RegOpenKeyEx', 'RegOpenKey', 'RegOpenFlags', 'RegLoadHive', 'RegExistValue',
+ 'RegExistKey', 'RegEntryType', 'RegDelValue', 'RegDeleteKey', 'RegCreateKey', 'RegConnect', 'RegCloseKey', 'RegApp', 'Random',
+ 'PtrPersistent', 'PtrGlobalDefine', 'PtrGlobal', 'Print', 'PlayWaveform', 'PlayMidi', 'PlayMedia', 'PipeServerWrite', 'PipeServerRead',
+ 'PipeServerCreate', 'PipeServerClose', 'PipeInfo', 'PipeClientSendRecvData', 'PipeClientOpen', 'PipeClientClose', 'Pause',
+ 'ParseData', 'ObjectTypeGet', 'ObjectType', 'ObjectOpen', 'ObjectGet', 'ObjectEventRemove', 'ObjectEventAdd',
+ 'ObjectCreate', 'ObjectConstToArray', 'ObjectConstantsGet', 'ObjectCollectionOpen', 'ObjectCollectionNext',
+ 'ObjectCollectionClose', 'ObjectClose', 'ObjectAccess', 'Num2Char', 'NetInfo', 'MsgTextGet', 'MousePlay', 'MouseMove', 'MouseInfo',
+ 'MouseDrag', 'MouseCoords', 'MouseClickBtn', 'MouseClick', 'mod', 'Min', 'Message', 'Max', 'Loge', 'LogDisk', 'Log10', 'LastError',
+ 'KeyToggleSet', 'KeyToggleGet', 'ItemSortNc', 'ItemSort', 'ItemSelect', 'ItemReplace', 'ItemRemove', 'ItemLocate', 'ItemInsert',
+ 'ItemExtractCSV', 'ItemExtract', 'ItemCountCSV', 'ItemCount', 'IsNumber', 'IsLicensed', 'IsKeyDown', 'IsInt', 'IsFloat', 'IsDefined',
+ 'Int', 'InstallFile', 'IniWritePvt', 'IniWrite', 'IniReadPvt', 'IniRead', 'IniItemizePvt', 'IniItemize', 'IniDeletePvt', 'IniDelete',
+ 'IgnoreInput', 'IconReplace', 'IconInfo', 'IconExtract', 'IconArrange', 'GetTickCount', 'GetObject', 'GetExactTime', 'Floor',
+ 'FindWindow', 'FileYmdHms', 'FileWrite', 'FileVerInfo', 'FileTimeTouch', 'FileTimeSetEx', 'FileTimeSet', 'FileTimeGetEx',
+ 'FileTimeGet', 'FileTimeCode', 'FileSizeEx', 'FileSize', 'FileRoot', 'FileRename', 'FileRead', 'FilePutW', 'FilePut', 'FilePath',
+ 'FileOpen', 'FileNameShort', 'FileNameLong', 'FileNameEval2', 'FileNameEval1', 'FileMoveAttr', 'FileMove', 'FileMapName',
+ 'FileLocate', 'FileItemPath', 'FileItemize', 'FileInfoToArray', 'FileGetW', 'FileGet', 'FileFullname', 'FileExtension', 'FileExist',
+ 'FileDelete', 'FileCreateTemp', 'FileCopyAttr', 'FileCopy', 'FileCompare', 'FileClose', 'FileBaseName', 'FileAttrSetEx',
+ 'FileAttrSet', 'FileAttrGetEx', 'FileAttrGet', 'FileAppend', 'Fabs', 'ExtractAttachedFile', 'Exp', 'ExeTypeInfo', 'Exclusive',
+ 'EnvItemize', 'EnvironSet', 'Environment', 'EndSession', 'DosVersion', 'DllLoad', 'DllLastError', 'DllHwnd', 'DllHinst',
+ 'DllFree', 'DllCallCDecl', 'DllCall', 'Display', 'DiskVolinfo', 'DiskSize', 'DiskScan', 'DiskInfo', 'DiskFree', 'DiskExist',
+ 'DirWindows', 'DirSize', 'DirScript', 'DirRename', 'DirRemove', 'DirMake', 'DirItemize', 'DirInfoToArray', 'DirHome', 'DirGet',
+ 'DirExist', 'DirChange', 'DirAttrSetEx', 'DirAttrSet', 'DirAttrGetEx', 'DirAttrGet', 'DialogProcOptions', 'DialogObject',
+ 'DialogControlState', 'DialogControlSet', 'DialogControlGet', 'DialogBox', 'Dialog', 'Delay', 'Decimals', 'DebugTrace',
+ 'DebugData', 'DDETimeout', 'DDETerminate', 'DDERequest', 'DDEPoke', 'DDEInitiate', 'DDEExecute', 'DateTime', 'CurrFilepath',
+ 'CurrentPath', 'CurrentFile', 'CreateObject', 'Cosh', 'Cos', 'ClipPut', 'ClipHasFormat', 'ClipGetEx', 'ClipGet', 'ClipAppend',
+ 'ChrUnicodeToString', 'ChrUnicodeToHex', 'ChrStringToUnicode', 'ChrSetCodepage', 'ChrHexToUnicode', 'ChrGetCodepage',
+ 'Char2Num', 'Ceiling', 'ButtonNames', 'BoxUpdates', 'BoxTitle', 'BoxTextFont', 'BoxTextColor', 'BoxText', 'BoxShut', 'BoxPen',
+ 'BoxOpen', 'BoxNew', 'BoxMapmode', 'BoxesUp', 'BoxDrawText', 'BoxDrawRect', 'BoxDrawLine', 'BoxDrawCircle', 'BoxDestroy',
+ 'BoxDataTag', 'BoxDataClear', 'BoxColor', 'BoxCaption', 'BoxButtonWait', 'BoxButtonStat', 'BoxButtonKill', 'BoxButtonDraw',
+ 'BoxBitMap', 'BinaryXor', 'BinaryXlate', 'BinaryWriteEx', 'BinaryWrite', 'BinaryTagRepl', 'BinaryTagLen', 'BinaryTagInit',
+ 'BinaryTagIndex', 'BinaryTagFind', 'BinaryTagExtr', 'BinaryStrCnt', 'BinarySort', 'BinaryReplace', 'BinaryReadEx',
+ 'BinaryRead', 'BinaryPokeStrW', 'BinaryPokeStr', 'BinaryPokeHex', 'BinaryPokeFlt', 'BinaryPoke4', 'BinaryPoke2', 'BinaryPoke',
+ 'BinaryPeekStrW', 'BinaryPeekStr', 'BinaryPeekHex', 'BinaryPeekFlt', 'BinaryPeek4', 'BinaryPeek2', 'BinaryPeek', 'BinaryOr',
+ 'BinaryOleType', 'BinaryIndexNc', 'BinaryIndexEx', 'BinaryIndexBin', 'BinaryIndex', 'BinaryIncrFlt', 'BinaryIncr4',
+ 'BinaryIncr2', 'BinaryIncr', 'BinaryHashRec', 'BinaryFree', 'BinaryEodSet', 'BinaryEodGet', 'BinaryCopy', 'BinaryConvert',
+ 'BinaryCompare', 'BinaryClipPut', 'BinaryClipGet', 'BinaryChecksum', 'BinaryBufInfo', 'BinaryAnd', 'BinaryAllocArray',
+ 'BinaryAlloc', 'Beep', 'Average', 'Atan', 'AskYesNo', 'AskTextbox', 'AskPassword', 'AskLine', 'AskItemlist', 'AskFont',
+ 'AskFiletext', 'AskFilename', 'AskDirectory', 'AskColor', 'Asin', 'ArrInitialize', 'ArrInfo', 'ArrDimension',
+ 'Arrayize', 'ArrayFilePutCSV', 'ArrayFilePut', 'ArrayFileGetCSV', 'ArrayFileGet', 'AppWaitClose', 'AppExist', 'AddExtender',
+ 'Acos', 'Abs', 'About'
+ ),
+ 4 => array(
+ 'zZipFiles', 'zVersionInfo', 'zVersion', 'zUnZipFiles', 'zSetPortBit', 'zRPortShift', 'zPortOut', 'zPortIn', 'zNotPortBit',
+ 'zLPortShift', 'zGetPortBit', 'zClrPortBit', 'xVerifyCCard', 'xSendMessage', 'xMessageBox', 'xMemCompact', 'xHex', 'xGetElapsed',
+ 'xGetChildHwnd', 'xExtenderInfo', 'xEnumStreams', 'xEjectMedia', 'xDriveReady', 'xDiskLabelGet', 'xCursorSet', 'xBaseConvert',
+ 'wxPing', 'wxParmSet', 'wxParmGet', 'wxMsgSetHdr', 'wxMsgGetHdr', 'wxMsgGetBody', 'wxHost2Addr', 'wxGetLastErr', 'wxGetInfo',
+ 'wxGetErrDesc', 'wxAddr2Host', 'wtsWaitSystemEvent', 'wtsVersion', 'wtsTerminateProcess', 'wtsShutdownSystem', 'wtsSendMessage',
+ 'wtsQuerySessionInfo', 'wtsProcIdToSessId', 'wtsLogoffSession', 'wtsLastErrMsg', 'wtsIsTSEnabled', 'wtsIsCitrixEnabled',
+ 'wtsGetActiveConsoleSessId', 'wtsEnumSessions', 'wtsEnumProcesses', 'wtsDisconnectSession', 'wnWrkGroups', 'wnVersion', 'wntWtsUserSet',
+ 'wntWtsUserGet', 'wntVersion', 'wntUserSidChk', 'wntUserSetDat', 'wntUserRename', 'wntUserProps', 'wntUserList', 'wntUserInfo',
+ 'wntUserGetDat', 'wntUserFiles', 'wntUserExist', 'wntUserDel', 'wntUserAddDat', 'wntUserAdd', 'wntSvcStatus', 'wntSvcStart',
+ 'wntSvcList', 'wntSvcDelete', 'wntSvcCreate', 'wntSvcControl', 'wntSvcCfgSet', 'wntSvcCfgGet', 'wntShutdown', 'wntShareUsers',
+ 'wntShareSet', 'wntShareList', 'wntShareInfo', 'wntShareDel', 'wntShareAdd', 'wntServiceInf', 'wntServiceAt', 'wntServerType',
+ 'wntServerList', 'wntServerInfo', 'wntSecurityGet', 'wntRunAsUser', 'wntResources2', 'wntResources', 'wntRemoteTime', 'wntRasUserSet',
+ 'wntRasUserGet', 'wntProfileInfo', 'wntProfileDel', 'wntPrivUsers', 'wntPrivList', 'wntPrivGet', 'wntPrivDel', 'wntPrivAdd',
+ 'wntOwnerSet', 'wntOwnerGet', 'wntMemberSet', 'wntMemberLst2', 'wntMemberList', 'wntMemberGrps', 'wntMemberGet', 'wntMemberDel',
+ 'wntLsaPolSet', 'wntLsaPolGet', 'wntListGroups', 'wntLastErrMsg', 'wntGroupRen', 'wntGroupInfo', 'wntGroupEdit', 'wntGroupDel',
+ 'wntGroupAdd', 'wntGetUser', 'wntGetDrive', 'wntGetDc', 'wntGetCon', 'wntFileUsers', 'wntFilesOpen', 'wntFileClose', 'wntEventWrite',
+ 'wntEventLog', 'wntDomainSync', 'wntDirDialog', 'wntDfsList', 'wntDfsGetInfo', 'wntCurrUsers', 'wntChgPswd', 'wntCancelCon',
+ 'wntAuditMod', 'wntAuditList', 'wntAuditGet', 'wntAuditDel', 'wntAuditAdd2', 'wntAuditAdd', 'wntAddPrinter', 'wntAddDrive',
+ 'wntAcctPolSet', 'wntAcctPolGet', 'wntAcctList', 'wntAcctInfo', 'wntAccessMod', 'wntAccessList', 'wntAccessGet', 'wntAccessDel',
+ 'wntaccessadd2', 'wntAccessAdd', 'wnShares', 'wnSharePath', 'wnShareName', 'wnShareCnt', 'wnServers', 'wnRestore', 'wnNetNames',
+ 'wnGetUser', 'wnGetCon', 'wnGetCaps', 'wnDlgShare', 'wnDlgNoShare', 'wnDlgDiscon', 'wnDlgCon4', 'wnDlgCon3', 'wnDlgCon2', 'wnDlgCon',
+ 'wnDlgBrowse', 'wnDialog', 'wnCmptrInfo', 'wnCancelCon', 'wnAddCon', 'WaitSRQ', 'w9xVersion', 'w9xUserSetDat', 'w9xUserRename',
+ 'w9xUserprops', 'w9xUserList', 'w9xUserinfo', 'w9xUserGetDat', 'w9xUserExist', 'w9xUserDel', 'w9xUserAddDat', 'w9xUserAdd', 'w9xShareSet',
+ 'w9xShareInfo', 'w9xShareDel', 'w9xShareAdd', 'w9xServiceAt', 'w9xServerList', 'w9xRemoteTime', 'w9xOwnerGet', 'w9xMemberSet',
+ 'w9xMemberList', 'w9xMemberGrps', 'w9xMemberGet', 'w9xMemberDel', 'w9xListGroups', 'w9xGroupInfo', 'w9xGroupDel', 'w9xGroupAdd',
+ 'w9xGetDC', 'w9xFileUsers', 'w9xAccessList', 'w9xAccessGet', 'w9xAccessDel', 'w9xAccessAdd', 'w95Version', 'w95ShareUsers',
+ 'w95ShareSet', 'w95ShareList', 'w95ShareInfo', 'w95ShareDel', 'w95ShareAdd', 'w95ServiceInf', 'w95ServiceAt', 'w95ServerType',
+ 'w95ServerInfo', 'w95Resources', 'w95GetUser', 'w95GetDrive', 'w95GetCon', 'w95FileUsers', 'w95FileClose', 'w95DirDialog',
+ 'w95CancelCon', 'w95AddPrinter', 'w95AddDrive', 'w95AccessDel', 'w95AccessAdd', 'w3Version', 'w3PrtBrowse', 'w3NetGetUser',
+ 'w3NetDialog', 'w3GetCon', 'w3GetCaps', 'w3DirBrowse', 'w3CancelCon', 'w3AddCon', 'urlGetScheme', 'urlEncode', 'urlDecode',
+ 'tVersion', 'tSetPriority', 'TriggerList', 'Trigger', 'tRemoteConn', 'tOpenProc', 'tListProc', 'tListMod', 'tKillProc', 'tGetProcInfo',
+ 'tGetPriority', 'tGetModInfo', 'tGetLastError', 'tGetData', 'TestSys', 'TestSRQ', 'tCountProc', 'tCompatible', 'tCloseProc',
+ 'tBrowseCntrs', 'sSendString', 'sSendNum', 'sSendLine', 'sSendBinary', 'sRecvNum', 'sRecvLine', 'sRecvBinary', 'SrchVersion',
+ 'SrchNext', 'SrchInit', 'SrchFree', 'sOpen', 'sOK2Send', 'sOK2Recv', 'smtpSendText', 'smtpSendFile', 'sListen', 'SetRWLS',
+ 'SendSetup', 'SendLLO', 'SendList', 'SendIFC', 'SendDataBytes', 'SendCmds', 'Send', 'sConnect', 'sClose', 'SByteOrder32',
+ 'sByteOrder16', 'sAccept', 'rRegVersion', 'rRegSearch', 'ResetSys', 'ReceiveSetup', 'Receive', 'ReadStsByte', 'RcvRespMsg',
+ 'RasVersion', 'RasTypeSize', 'RasRename', 'RasNumCons', 'RasNameValid', 'RasListActCon', 'RasItemize', 'RasHangUp', 'RasGetLastErr',
+ 'RasGetConStat', 'RasEntrySet', 'RasEntryInfo', 'RasEntryExist', 'RasEntryDel', 'RasEntryAdd', 'RasDialInfo', 'RasDial',
+ 'RasCopy', 'RasConStatus', 'qVersionInfo', 'qTransact', 'qTables', 'qSpecial', 'qSetConnOpt', 'qNumRsltCol', 'qNativeSql', 'qLastCode',
+ 'qGetData', 'qFreeStmt', 'qFreeEnv', 'qFreeConnect', 'qFetch', 'qExecDirect', 'qError', 'qDriverList', 'qDriverCon', 'qDisconnect',
+ 'qDataSources', 'qConnect', 'qConfigError', 'qConfigData', 'qColumns', 'qBindCol', 'qAllocStmt', 'qAllocEnv', 'qAllocConnect',
+ 'pWaitFor', 'pVersionInfo', 'pTimeout', 'pSetPublish', 'pSetPrtInfo', 'pSetPrtAttrib', 'pSetDefPrtEx', 'pSetDefPrt', 'pSendFile',
+ 'pRecvFile', 'pPutString', 'pPutLine', 'pPutChar', 'pPutByte', 'pPutBinary', 'PPollUnconfig', 'PPollConfig', 'PPoll', 'pPeekChar',
+ 'pPeekByte', 'pPaperSizes', 'pPaperBins', 'pModemSReg', 'pModemParams', 'pModemInit', 'pModemHangUp', 'pModemDial', 'pModemControl',
+ 'pModemConnect', 'pModemCommand', 'pModemAnsRing', 'pModemAnsCall', 'pMediaTypes', 'pGetString', 'pGetPublish', 'pGetPrtList',
+ 'pGetPrtInfo', 'pGetPrtAttrib', 'pGetLine', 'pGetLastError', 'pGetErrorMsg', 'pGetErrorCode', 'pGetDefPrtInf', 'pGetChar',
+ 'pGetByte', 'pGetBinary', 'pDelPrtConn', 'pDelPrinter', 'pComOpen', 'pComModify', 'pComInfo', 'pComControl', 'pComClose',
+ 'pCheckSum', 'pCheckBinary', 'pCaptureOn', 'pCaptureOff', 'pCaptureLog', 'PassControl', 'pAddPrtConn', 'pAddPrinter', 'p3RecvText',
+ 'p3RecvFile', 'p3Peek', 'p3Open', 'p3GetReply', 'p3Delete', 'p3Count', 'p3Close', 'nwWhoAmI', 'nwVfyPassword', 'nwVersion',
+ 'nwSrvShutdown', 'nwSrvNLMMgr', 'nwSrvGenGUID', 'nwSrvExecNCF', 'nwSetVolLimit', 'nwSetSrvParam', 'nwSetSrvInfo', 'nwSetPrimServ',
+ 'nwSetPassword', 'nwSetOptions', 'nwSetFileInfo', 'nwSetDirLimit', 'nwSetDirInfo', 'nwSetContext', 'nwSetBcastMode', 'nwServerList',
+ 'nwSendBcastMsg', 'nwSearchObjects', 'nwSearchFilter', 'nwRenameObject', 'nwRemoveObject', 'nwReceiveBcastMsg', 'nwNameConvert',
+ 'nwMutateObject', 'nwMoveObject', 'nwModifyObject', 'nwMapDelete', 'nwMap', 'nwLogout', 'nwLogin', 'nwListUserGroups',
+ 'nwListObjects', 'nwListGroupMembers', 'nwLastErrMsg', 'nwIsUserInGroup', 'nwGetVolLimit', 'nwGetSrvStats', 'nwGetSrvParam',
+ 'nwGetSrvInfo', 'nwGetSrvCfg', 'nwGetOptions', 'nwGetObjValue', 'nwGetObjInfo', 'nwGetNLMInfo', 'nwGetMapped', 'nwGetFileInfo',
+ 'nwGetDirLimit', 'nwGetDirInfo', 'nwGetContext', 'nwGetConnInfo', 'nwGetCapture', 'nwGetBcastMode', 'nwGetAttrInfo',
+ 'nwDriveStatus', 'nwDrivePath', 'nwDetachFromServer', 'nwDelUserFromGroup', 'nwDelConnNum', 'nwCompareObject', 'nwClientInfo',
+ 'nwChgPassword', 'nwAttachToServer', 'nwAddUserToGroup', 'nwAddObject', 'netVersion', 'netResources', 'netGetUser', 'netGetCon',
+ 'netDirDialog', 'netCancelCon', 'netAddPrinter', 'netAddDrive', 'n4Version', 'n4UserGroups', 'n4UserGroupEx', 'n4SetPrimServ',
+ 'n4SetOptions', 'n4SetContextG', 'n4SetContext', 'n4ServerList', 'n4ServerInfo', 'n4ObjSearch', 'n4ObjRename', 'n4ObjOptions',
+ 'n4ObjMove', 'n4ObjGetVal', 'n4ObjectProps', 'n4ObjectList', 'n4ObjectInfo', 'n4ObjDelete', 'n4NameConvert', 'n4MsgsEndAll',
+ 'n4MsgsEnd', 'n4MemberSet', 'n4MemberGet', 'n4MemberDel', 'n4MapRoot', 'n4MapDir', 'n4MapDelete', 'n4Map', 'n4LogoutTree',
+ 'n4Logout', 'n4Login', 'n4GetUserName', 'n4GetUserId', 'n4GetUser', 'n4GetNetAddr', 'n4GetMapped', 'n4GetContext',
+ 'n4GetConnNum', 'n4FileUsers', 'n4FileTimeGet', 'n4FileAttrSet', 'n4FileAttrGet', 'n4DriveStatus', 'n4DrivePath', 'n4DirTimeGet',
+ 'n4DirAttrSet', 'n4DirAttrGet', 'n4Detach', 'n4ChgPassword', 'n4CapturePrt', 'n4CaptureGet', 'n4CaptureEnd', 'n4Attach',
+ 'n3Version', 'n3UserGroups', 'n3ServerList', 'n3ServerInfo', 'n3MsgsEndAll', 'n3MsgsEnd', 'n3MemberSet', 'n3MemberGet',
+ 'n3MemberDel', 'n3Maproot', 'n3Mapdir', 'n3Mapdelete', 'n3Map', 'n3Logout', 'n3GetUserId', 'n3GetUser', 'n3GetNetAddr',
+ 'n3GetMapped', 'n3GetConnNum', 'n3FileTimeGet', 'n3FileAttrSet', 'n3FileAttrGet', 'n3DriveStatus', 'n3DrivePath',
+ 'n3DirTimeGet', 'n3DirAttrSet', 'n3DirAttrGet', 'n3Detach', 'n3ChgPassword', 'n3CapturePrt', 'n3CaptureGet',
+ 'n3CaptureEnd', 'n3Attach', 'mVersion', 'mSyncMail', 'mSendMailEx', 'mSendMail', 'mrecvmail', 'mReadNextMsg', 'mLogOn',
+ 'mLogOff', 'mFindNext', 'mError', 'mCompatible', 'kVerInfo', 'kStatusInfo', 'kSendText', 'kSendFile', 'kManageImap4',
+ 'kInit', 'kGetMail', 'kExtra', 'kDest', 'kDeletePop3', 'iWriteDataBuf', 'iWriteData', 'iVersion', 'IUrlOpen', 'iUrlEncode',
+ 'iUrlDecode', 'iReadDataBuf', 'iReadData', 'ipVersion', 'ipPing', 'iPing', 'ipHost2Addr', 'ipGetLastErr', 'ipGetAddress',
+ 'iParseURL', 'ipAddr2Host', 'iOptionSet', 'iOptionGet', 'ImgWave', 'ImgVersion', 'ImgUnsharpMask', 'ImgThreshold', 'ImgSwirl',
+ 'ImgSpread', 'ImgSolarize', 'ImgShear', 'ImgSharpen', 'ImgShade', 'ImgScale', 'ImgSample', 'ImgRotate', 'ImgResize',
+ 'ImgReduceNoise', 'ImgRaise', 'ImgOilPaint', 'ImgNormalize', 'ImgNegate', 'ImgMotionBlur', 'ImgModulate', 'ImgMinify',
+ 'ImgMedianFilter', 'ImgMagnify', 'ImgLevel', 'ImgIsValid', 'ImgIsPalette', 'ImgIsMono', 'ImgIsGray', 'ImgInfo', 'ImgImplode',
+ 'ImgGetImageType', 'ImgGetColorCount', 'ImgGaussianBlur', 'ImgGamma', 'ImgFrame', 'ImgFlop', 'ImgFlip', 'ImgEqualize',
+ 'ImgEnhance', 'ImgEmboss', 'ImgCrop', 'ImgConvert', 'ImgContrast', 'ImgCompare', 'ImgColorize', 'ImgChop', 'ImgCharcoal',
+ 'ImgBorder', 'ImgBlur', 'ImgAddNoise', 'iLocFindNext', 'iLocFindInit', 'iHttpOpen', 'iHttpInit', 'iHttpHeaders', 'iHttpAccept',
+ 'iHostConnect', 'iHost2Addr', 'iGetResponse', 'iGetLastError', 'iGetIEVer', 'iGetConStatEx', 'iGetConState', 'iFtpRename',
+ 'iFtpPut', 'iFtpOpen', 'iFtpGet', 'iFtpFindNext', 'iFtpFindInit', 'iFtpDirRemove', 'iFtpDirMake', 'iFtpDirGet', 'iFtpDirChange',
+ 'iFtpDialog', 'iFtpDelete', 'iFtpCmd', 'iErrorDialog', 'iDialItemize', 'iDialHangUp', 'iDial', 'iCookieSet', 'iCookieGet',
+ 'iContentURL', 'iContentFile', 'iContentData', 'iClose', 'ibWrtf', 'ibWrt', 'ibWait', 'ibVersion', 'ibUnlock', 'ibTrg',
+ 'ibTmo', 'ibStop', 'ibStatus', 'ibSta', 'ibSre', 'ibSic', 'ibSad', 'ibRsv', 'ibRsp', 'ibRsc', 'ibRpp', 'ibRdf', 'ibRd',
+ 'ibPpc', 'ibPoke', 'ibPct', 'ibPad', 'ibOnl', 'ibMakeAddr', 'ibLock', 'ibLoc', 'ibLn', 'ibLines', 'ibIst', 'ibInit',
+ 'ibGts', 'ibGetSad', 'ibGetPad', 'ibFind', 'ibEvent', 'ibErr', 'ibEot', 'ibEos', 'iBegin', 'ibDma', 'ibDev', 'ibConfig',
+ 'ibCntl', 'ibCnt', 'ibCmda', 'ibCmd', 'ibClr', 'ibCac', 'ibBna', 'ibAsk', 'iAddr2Host', 'huge_Thousands', 'huge_Subtract',
+ 'huge_SetOptions', 'huge_Multiply', 'huge_GetLastError', 'huge_ExtenderInfo', 'huge_Divide', 'huge_Decimal', 'huge_Add',
+ 'httpStripHTML', 'httpRecvTextF', 'httpRecvText', 'httpRecvQuery', 'httpRecvQryF', 'httpRecvFile', 'httpGetServer',
+ 'httpGetQuery', 'httpGetPath', 'httpGetFile', 'httpGetDir', 'httpGetAnchor', 'httpFullPath', 'httpFirewall', 'httpAuth',
+ 'ftpRename', 'ftpQuote', 'ftpPut', 'ftpOpen', 'ftpList', 'ftpGet', 'ftpFirewall', 'ftpDelete', 'ftpClose', 'ftpChDir',
+ 'FindRQS', 'FindLstn', 'EnvSetVar', 'EnvPathDel', 'EnvPathChk', 'EnvPathAdd', 'EnvListVars', 'EnvGetVar', 'EnvGetInfo',
+ 'EnableRemote', 'EnableLocal', 'ehllapiWait', 'ehllapiVersion', 'ehllapiUninit', 'ehllapiStopKeyIntercept', 'ehllapiStopHostNotify',
+ 'ehllapiStopCloseIntercept', 'ehllapiStartKeyIntercept', 'ehllapiStartHostNotify', 'ehllapiStartCloseIntercept',
+ 'ehllapiSetWindowStatus', 'ehllapiSetSessionParams', 'ehllapiSetPSWindowName', 'ehllapiSetCursorLoc', 'ehllapiSendKey',
+ 'ehllapiSendFile', 'ehllapiSearchPS', 'ehllapiSearchField', 'ehllapiRunProfile', 'ehllapiResetSystem', 'ehllapiReserve',
+ 'ehllapiRelease', 'ehllapiReceiveFile', 'ehllapiQuerySystem', 'ehllapiQueryPSStatus', 'ehllapiQueryHostNotify',
+ 'ehllapiQueryFieldAttr', 'ehllapiQueryCursorLoc', 'ehllapiQueryCloseIntercept', 'ehllapiPostInterceptStatus',
+ 'ehllapiPause', 'ehllapiLastErrMsg', 'ehllapiInit', 'ehllapiGetWindowStatus', 'ehllapiGetPSHWND', 'ehllapiGetKey',
+ 'ehllapiFindFieldPos', 'ehllapiFindFieldLen', 'ehllapiDisconnectPS', 'ehllapiCvtRCToPos', 'ehllapiCvtPosToRC',
+ 'ehllapiCopyTextToPS', 'ehllapiCopyTextToField', 'ehllapiCopyTextFromPS', 'ehllapiCopyTextFromField', 'ehllapiCopyOIA',
+ 'ehllapiConnectPS', 'dunItemize', 'dunDisconnect', 'dunConnectEx', 'dunConnect', 'dsTestParam', 'dsSIDtoHexStr', 'dsSetSecProp',
+ 'dsSetProperty', 'dsSetPassword', 'dsSetObj', 'dsSetCredentX', 'dsSetCredent', 'dsRemFromGrp', 'dsRelSecObj', 'dsMoveObj',
+ 'dsIsObject', 'dsIsMemberGrp', 'dsIsContainer', 'dsGetUsersGrps', 'dsGetSecProp', 'dsGetPropName', 'dsGetProperty',
+ 'dsGetPrntPath', 'dsGetPrimGrp', 'dsGetMemGrp', 'dsGetInfo', 'dsGetClass', 'dsGetChldPath', 'dsFindPath', 'dsDeleteObj',
+ 'dsCreatSecObj', 'dsCreateObj', 'dsCopySecObj', 'dsAddToGrp', 'dsAclRemAce', 'dsAclOrderAce', 'dsAclGetAces', 'dsAclAddAce',
+ 'DevClearList', 'DevClear', 'dbTest', 'dbSwapColumns', 'dbSort', 'dbSetRecordField', 'dbSetOptions', 'dbSetErrorReporting',
+ 'dbSetEntireRecord', 'dbSetDelimiter', 'dbSave', 'dbOpen', 'dbNameColumn', 'dbMakeNewItem', 'dbInsertColumn', 'dbGetVersion',
+ 'dbGetSaveStatus', 'dbGetRecordField', 'dbGetRecordCount', 'dbGetNextItem', 'dbGetLastError', 'dbGetEntireRecord',
+ 'dbGetColumnType', 'dbGetColumnNumber', 'dbGetColumnName', 'dbGetColumnCount', 'dbFindRecord', 'dbExist', 'dbEasterEgg',
+ 'dbDeleteRecord', 'dbDeleteColumn', 'dbDebug', 'dbCookDatabases', 'dbClose', 'dbCloneRecord', 'dbBindCol', 'cWndState',
+ 'cWndinfo', 'cWndGetWndSpecName', 'cWndGetWndSpec', 'cWndexist', 'cWndByWndSpecName', 'cWndByWndSpec', 'cWndbyseq',
+ 'cWndbyname', 'cWndbyid', 'cWndbyclass', 'cWinIDConvert', 'cVersionInfo', 'cVendorId', 'cSetWndText', 'cSetUpDownPos',
+ 'cSetTvItem', 'cSetTrackPos', 'cSetTabItem', 'cSetLvItem', 'cSetLbItemEx', 'cSetLbItem', 'cSetIpAddr', 'cSetFocus',
+ 'cSetEditText', 'cSetDtpDate', 'cSetCbItem', 'cSetCalDate', 'cSendMessage', 'cRadioButton', 'cPostMessage', 'cPostButton',
+ 'cMemStat', 'cGetWndCursor', 'cGetUpDownPos', 'cGetUpDownMin', 'cGetUpDownMax', 'cGetTVItem', 'cGetTrackPos', 'cGetTrackMin',
+ 'cGetTrackMax', 'cGetTbText', 'cGetSbText', 'cGetLvText', 'cGetLvSelText', 'cGetLvFocText', 'cGetLvDdtText', 'cGetLvColText',
+ 'cGetLbText', 'cGetLbSelText', 'cGetLbCount', 'cGetIpAddr', 'cGetInfo', 'cGetHrText', 'cGetFocus', 'cGetEditText', 'cGetDtpDate',
+ 'cGetControlImageCRC', 'cGetCBText', 'cGetCbCount', 'cGetCalDate', 'cFindByName', 'cFindByClass', 'cEnablestate', 'cDblClickItem',
+ 'cCpuSupt', 'cCpuSpeed', 'cCpuIdExt', 'cCpuId', 'cCpuFeat', 'cCpuBenchmark', 'cCloneCheck', 'cClickToolbar', 'cClickButton',
+ 'cClearTvItem', 'cClearLvItem', 'cClearLbAll', 'cCheckbox', 'aVersion', 'aStatusbar', 'aShellFolder', 'aMsgTimeout', 'AllSPoll',
+ 'aGetLastError', 'aFileRename', 'aFileMove', 'aFileDelete', 'aFileCopy'
+ ),
+ 5 => array(
+ 'wWordRight', 'wWordLeft', 'wWinTile', 'wWinRestore', 'wWinNext', 'wWinMinimize', 'wWinMaximize', 'wWinCloseAll', 'wWinClose',
+ 'wWinCascade', 'wWinArricons', 'wViewOutput', 'wViewOptions', 'wViewHtml', 'wUpperCase', 'wUpline', 'wUndo', 'wTopOfFile', 'wToggleIns',
+ 'wTab', 'wStatusMsg', 'wStartSel', 'wSpellcheck', 'wSetProject', 'wSetPrefs', 'wSetColblk', 'wSetBookmark', 'wSelWordRight',
+ 'wSelWordLeft', 'wSelUp', 'wSelTop', 'wSelRight', 'wSelPgUp', 'wSelPgDn', 'wSelLeft', 'wSelInfo', 'wSelHome', 'wSelEnd', 'wSelectAll',
+ 'wSelDown', 'wSelBottom', 'wRunRebuild', 'wRunMake', 'wRunExecute', 'wRunDebug', 'wRunConfig', 'wRunCompile', 'wRunCommand', 'wRight',
+ 'wRepeat', 'wRedo', 'wRecord', 'wProperties', 'wPrintDirect', 'wPrinSetup', 'wPrevError', 'wPaste', 'wPageUp', 'wPageDown', 'wNextError',
+ 'wNewLine', 'wLowerCase', 'wLineCount', 'wLeft', 'wInvertCase', 'wInsString', 'wInsLine', 'wHome', 'wHelpKeyword', 'wHelpKeybrd',
+ 'wHelpIndex', 'wHelpHelp', 'wHelpCmds', 'wHelpAbout', 'wGotoLine', 'wGotoCol', 'wGetWrap', 'wGetWord', 'wGetUndo', 'wGetSelstate',
+ 'wGetRedo', 'wGetOutput', 'wGetModified', 'wGetLineNo', 'wGetIns', 'wGetFilename', 'wGetColNo', 'wGetChar', 'wFtpOpen', 'wFindNext',
+ 'wFindInFiles', 'wFind', 'wFileSaveAs', 'wFileSave', 'wFileRevert', 'wFilePrint', 'wFilePgSetup', 'wFileOpen', 'wFileNew', 'wFileMerge',
+ 'wFileList', 'wFileExit', 'wEndSel', 'wEndOfFile', 'wEnd', 'wEdWrap', 'wEdWordRight', 'wEdWordLeft', 'wEdUpLine', 'wEdUndo', 'wEdTopOfFile',
+ 'wEdToggleIns', 'wEdTab', 'wEdStartSel', 'wEdSetColBlk', 'wEdSelectAll', 'wEdRight', 'wEdRedo', 'wEdPaste', 'wEdPageUp', 'wEdPageDown',
+ 'wEdNewLine', 'wEdLeft', 'wEdInsString', 'wEdHome', 'wEdGoToLine', 'wEdGoToCol', 'wEdGetWord', 'wEdEndSel', 'wEdEndOfFile', 'wEdEnd',
+ 'wEdDownLine', 'wEdDelete', 'wEdCutLine', 'wEdCut', 'wEdCopyLine', 'wEdCopy', 'wEdClearSel', 'wEdBackTab', 'wEdBackspace', 'wDownLine',
+ 'wDelete', 'wDelButton', 'wCutMarked', 'wCutLine', 'wCutAppend', 'wCut', 'wCopyMarked', 'wCopyLine', 'wCopyAppend', 'wCopy', 'wCompile',
+ 'wClearSel', 'wChange', 'wCallMacro', 'wBackTab', 'wBackspace', 'wAutoIndent', 'wAddButton', 'edWindowTile', 'edWindowRestore',
+ 'edWindowNext', 'edWindowMinimize', 'edWindowMaximize', 'edWindowCloseall', 'edWindowClose', 'edWindowCascade', 'edWindowArrangeIcons',
+ 'edStatusMsg', 'edSearchViewOutput', 'edSearchRepeat', 'edSearchPrevError', 'edSearchNextError', 'edSearchFind', 'edSearchChange',
+ 'edRunRebuild', 'edRunMake', 'edRunExecute', 'edRunDebug', 'edRunConfigure', 'edRunCompile', 'edRunCommand', 'edRecord', 'edHelpProcedures',
+ 'edHelpKeyword', 'edHelpKeyboard', 'edHelpIndex', 'edHelpHelp', 'edHelpCommands', 'edHelpAbout', 'edGetWordWrapState', 'edGetWindowName',
+ 'edGetUndoState', 'edGetSelectionState', 'edGetRedoState', 'edGetModifiedStatus', 'edGetLineNumber', 'edGetInsertState', 'edGetColumnNumber',
+ 'edGetChar', 'edFileSetPreferences', 'edFileSaveAs', 'edFileSave', 'edFilePrinterSetup', 'edFilePrint', 'edFilePageSetup', 'edFileOpen',
+ 'edFileNew', 'edFileMerge', 'edFileList', 'edFileExit', 'edEditWrap', 'edEditWordRight', 'edEditWordLeft', 'edEditUpLine', 'edEditUndo',
+ 'edEditToggleIns', 'edEditTab', 'edEditStartSelection', 'edEditSetColumnBlock', 'edEditSetBookmark', 'edEditSelectAll', 'edEditRight',
+ 'edEditRedo', 'edEditPaste', 'edEditPageUp', 'edEditPageDown', 'edEditLeft', 'edEditInsertString', 'edEditGoToLine', 'edEditGoToColumn',
+ 'edEditGoToBookmark', 'edEditGetCurrentWord', 'edEditEndSelection', 'edEditEndOfLine', 'edEditEndOfFile', 'edEditDownline', 'edEditDelete',
+ 'edEditCutline', 'edEditCut', 'edEditCopyline', 'edEditCopy', 'edEditClearSelection', 'edEditBeginningOfLine', 'edEditBeginningOfFile',
+ 'edEditBackTab', 'edEditBackspace', 'edDeleteButton', 'edAddButton'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '{', '}', '!', '+', '-', '~', '$', '^', '?', '@', '%', '#', '&', '*', '|', '/', '<', '>'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false,
+ 5 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #800080;',
+ 2 => 'color: #0080FF; font-weight: bold;',
+ 3 => 'color: #0000FF;',
+ 4 => 'color: #FF00FF;',
+ 5 => 'color: #008000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #008000; font-style: italic;',
+ 2 => 'color: #FF1010; font-weight: bold;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #006600;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => '',
+ 5 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(//Variable names
+ 0 => "[\\$]{1,2}[a-zA-Z_][a-zA-Z0-9_]*"
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_MAYBE,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/wolfram.php b/platform/www/vendor/geshi/geshi/src/geshi/wolfram.php
new file mode 100644
index 0000000..9ea9e3c
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/wolfram.php
@@ -0,0 +1,967 @@
+<?php
+/******************************************************************************
+ * wolfram.php
+ * ----------
+ * Author: Mysterious Light (youngmysteriouslight@gmail.com)
+ * Copyright: (c) 2018 Mysterious Light (youngmysteriouslight@gmail.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2018/01/12
+ *
+ * Wolfram language file for GeSHi.
+ *
+ ******************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *****************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Wolfram',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array('(*' => '*)'),
+ 'COMMENT_REGEXP' => array(
+ 2 => '/\\(\\*.*\\*\\)/',
+ 3 => '/\\\\\\[\\w+]/'
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ /* main wolfram keywords */
+ 1 => array(
+ 'AbelianGroup', '$Aborted', 'AbortKernels', 'Abort', 'Abs', 'All',
+ 'AbortProtect', 'AbsoluteCurrentValue', 'AbsoluteDashing', 'AddTo',
+ 'AbsoluteFileName', 'AbsoluteOptions', 'AbsolutePointSize', 'And',
+ 'AbsoluteThickness', 'AbsoluteTime', 'AbsoluteTiming', 'Accuracy',
+ 'AccountingForm', 'Accumulate', 'AccuracyGoal', 'ActionMenu', 'C',
+ 'Active', 'ActiveStyle', 'AcyclicGraphQ', 'AddOnHelpPath', 'Alias',
+ 'AdjacencyGraph', 'AdjacencyMatrix', 'AdjustmentBox', 'AiryAi',
+ 'AffineTransform', 'AiryAiPrime', 'AiryAiZero', 'AiryBi', 'AngerJ',
+ 'AiryBiPrime', 'AiryBiZero', 'AlgebraicIntegerQ', 'AlgebraicRules',
+ 'AlgebraicNumberDenominator', 'AlgebraicNumber', 'Algebraics', 'D',
+ 'AlgebraicNumberNorm', 'AlgebraicNumberPolynomial', 'Alignment',
+ 'AlgebraicNumberTrace', 'AlgebraicUnitQ', 'AlignmentPoint', 'Arg',
+ 'AllowGroupClose', 'AllowInlineCells', 'AllowReverseGroupClose',
+ 'AllowScriptLevelChange', 'AlphaChannel', 'AlternatingGroup', 'Do',
+ 'AlternativeHypothesis', 'Alternatives', 'AmbientLight', 'Animate',
+ 'AnchoredSearch', 'AndersonDarlingTest', 'AngleBracket', 'Annuity',
+ 'AnimationCycleOffset', 'AnimationCycleRepetitions', 'Animator',
+ 'AnimationDirection', 'AnimationDisplayTime', 'AnimationRate', 'E',
+ 'AnimationRepetitions', 'AnimationRunning', 'Annotation', 'Apart',
+ 'AnnuityDue', 'Antialiasing', 'ApartSquareFree', 'Appearance', 'I',
+ 'AppearanceElements', 'AppellF1', 'Append', 'AppendTo', 'Apply',
+ 'ArcCosh', 'ArcCos', 'ArcCoth', 'ArcCot', 'ArcCsch', 'ArcCsc', 'N',
+ 'ArcSech', 'ArcSec', 'ArcSinDistribution', 'ArcSinh', 'ArcSin',
+ 'ArcTanh', 'ArcTan', 'ArgMax', 'ArgMin', 'ArithmeticGeometricMean',
+ 'ArrayComponents', 'ArrayDepth', 'ArrayFlatten', 'Array', 'ArrayQ',
+ 'ArrayPad', 'ArrayPlot', 'ArrayRules', 'Arrowheads', 'Arrow', 'Dt',
+ 'AspectRatioFixed', 'AspectRatio', '$AssertFunction', 'Assert',
+ 'Assuming', '$Assumptions', 'Assumptions', 'AstronomicalData', 'O',
+ 'Asynchronous', 'AtomQ', 'Attributes', 'AutoAction', 'AutoDelete',
+ 'AugmentedSymmetricPolynomial', 'AutoGeneratedPackage', 'AxesEdge',
+ 'AutoIndent', 'AutoItalicWords', 'AutoloadPath', 'Automatic', 'If',
+ 'AutoMultiplicationSymbol', 'AutoOpenNotebooks', 'AutoScroll',
+ 'AutoOpenPalettes', 'AutorunSequencing', 'AutoSpacing', 'Axes',
+ 'AxesLabel', 'AxesOrigin', 'AxesStyle', 'Axis', 'Background', 'Im',
+ 'BabyMonsterGroupB', 'Back', 'Backslash', 'Backward', 'Band', 'In',
+ 'BarabasiAlbertGraphDistribution', 'BarChart3D', 'BarChart', 'Cap',
+ 'BarnesG', 'BarOrigin', 'BarSpacing', '$BaseDirectory', 'BaseForm',
+ 'Baseline', 'BaselinePosition', 'BaseStyle', '$BatchInput', 'Beep',
+ '$BatchOutput', 'BatesDistribution', 'BattleLemarieWavelet', 'CDF',
+ 'Because', 'BeckmannDistribution', 'BeginDialogPacket', 'Begin',
+ 'BeginPackage', 'BellB', 'BellY', 'BenfordDistribution', 'BesselI',
+ 'BeniniDistribution', 'BenktanderGibratDistribution', 'BernoulliB',
+ 'BenktanderWeibullDistribution', 'BernoulliDistribution', 'Beta',
+ 'BernoulliGraphDistribution', 'BernsteinBasis', 'BesselJ', 'BitOr',
+ 'BesselJZero', 'BesselK', 'BesselY', 'BesselYZero', 'BezierCurve',
+ 'BetaBinomialDistribution', 'BetaDistribution', 'BetaRegularized',
+ 'BetaNegativeBinomialDistribution', 'BetaPrimeDistribution', 'Cos',
+ 'BetweennessCentrality', 'BezierFunction', 'BilateralFilter', 'On',
+ 'Binarize', 'BinaryFormat', 'BinaryImageQ', 'BinaryReadList', 'Or',
+ 'BinaryRead', 'BinaryWrite', 'BinCounts', 'BinLists', 'Binomial',
+ 'BinomialDistribution', 'BinormalDistribution', 'BipartiteGraphQ',
+ 'BiorthogonalSplineWavelet', 'BirnbaumSaundersDistribution', 'Cot',
+ 'BitAnd', 'BitClear', 'BitGet', 'BitLength', 'BitNot', 'BitSet',
+ 'BitShiftLeft', 'BitShiftRight', 'BitXor', 'Black', 'Blank', 'Csc',
+ 'BlankNullSequence', 'BlankSequence', 'Blend', 'Block', 'Blue',
+ 'BlockRandom', 'Blur', 'BodePlot', 'Bold', 'Bookmarks', 'Booleans',
+ 'BooleanConvert', 'BooleanCountingFunction', 'BooleanFunction',
+ 'BooleanGraph', 'BooleanMaxterms', 'BooleanMinimize', 'Boole',
+ 'BooleanMinterms', 'BooleanTable', 'BooleanVariables', 'Bottom',
+ 'BorderDimensions', 'BorelTannerDistribution', 'BoundaryStyle',
+ 'BottomHatTransform', 'BoxBaselineShift', 'BoxData', 'Boxed', 'Pi',
+ 'BoxFormFormatTypes', 'BoxFrame', 'BoxMargins', 'BoxMatrix', 'Cup',
+ 'BoxRatios', 'BoxStyle', 'BoxWhiskerChart', 'BracketingBar', 'Del',
+ 'BrayCurtisDistance', 'BreadthFirstScan', 'Break', 'Brown', 'Byte',
+ 'BrownForsytheTest', 'BSplineBasis', 'BSplineCurve', 'BubbleChart',
+ 'BSplineFunction', 'BSplineSurface', 'BubbleChart3D', 'ButtonBar',
+ 'BubbleScale', 'BubbleSizes', 'ButterflyGraph', 'ButtonBox', 'Det',
+ 'ButtonBoxOptions', 'ButtonData', 'ButtonEvaluator', 'ButtonFrame',
+ 'ButtonExpandable', 'ButtonFunction', 'ButtonMargins', 'Button',
+ 'ButtonMinHeight', 'ButtonNotebook', 'ButtonNote', 'ButtonSource',
+ 'ButtonStyle', 'ByteCount', '$ByteOrdering', 'ByteOrdering', 'Dot',
+ 'CallPacket', 'CanberraDistance', 'CancelButton', '$Canceled',
+ 'Cancel', 'CandlestickChart', 'CapForm', 'CapitalDifferentialD',
+ 'CarmichaelLambda', 'Cases', 'Cashflow', 'Casoratian', 'Catalan',
+ 'CatalanNumber', 'Catch', 'CauchyDistribution', 'CayleyGraph',
+ 'CDFWavelet', 'Ceiling', 'CellArray', 'CellAutoOverwrite', 'Cell',
+ 'CellBaseline', 'CellBracketOptions', 'CellChangeTimes', 'Center',
+ 'CellContext', 'CellDingbat', 'CellDynamicExpression', 'CellFrame',
+ 'CellEditDuplicate', 'CellEpilog', 'CellEvaluationDuplicate', 'Re',
+ 'CellEvaluationFunction', 'CellEventActions', 'CellFrameColor',
+ 'CellFrameLabelMargins', 'CellFrameLabels', 'CellFrameMargins',
+ 'CellGroupData', 'CellGrouping', 'CellGroupingRules', 'CellGroup',
+ 'CellHorizontalScrolling', 'CellLabelAutoDelete', 'CellLabel',
+ 'CellLabelMargins', 'CellLabelPositioning', 'CellMargins', 'CForm',
+ 'CellOpen', 'CellPrint', 'CellProlog', 'CellSize', 'CellTags',
+ 'CellularAutomaton', 'CensoredDistribution', 'Censoring', 'Check',
+ 'CenterDot', 'CentralMomentGeneratingFunction', 'CentralMoment',
+ 'ChampernowneNumber', 'ChanVeseBinarize', '$CharacterEncoding',
+ 'CharacterEncoding', '$CharacterEncodings', 'Character', 'Chop',
+ 'CharacterEncodingsPath', 'CharacteristicFunction', 'Characters',
+ 'CharacteristicPolynomial', 'CharacterRange', 'ChartBaseStyle',
+ 'ChartElementFunction', 'ChartElements', 'ChartLabels', 'Checkbox',
+ 'ChartLayout', 'ChartLegends', 'ChartStyle', 'ChebyshevDistance',
+ 'ChebyshevT', 'ChebyshevU', 'CheckAbort', 'CheckboxBar', 'Circle',
+ 'ChemicalData', 'ChessboardDistance', 'ChiDistribution', 'Clear',
+ 'ChineseRemainder', 'ChiSquareDistribution', 'ChoiceButtons', 'Tr',
+ 'ChoiceDialog', 'CholeskyDecomposition', 'CircleDot', 'CirclePlus',
+ 'CircleMinus', 'CircleTimes', 'CirculantGraph', 'CityData', 'Clip',
+ 'ClearAll', 'ClearAttributes', 'ClearSystemCache', 'ClebschGordan',
+ 'ClickPane', 'ClipFill', 'ClippingStyle', 'Clock', 'CloseKernels',
+ 'Close', 'ClosenessCentrality', 'ClosingAutoSave', 'Closing',
+ 'ClusteringComponents', 'CMYKColor', 'CoefficientArrays', 'Colon',
+ 'CoefficientList', 'Coefficient', 'CoefficientRules', 'Collect',
+ 'CoifletWavelet', 'ColorCombine', 'ColorConvert', 'ColorData',
+ 'ColorDataFunction', 'ColorFunction', 'ColorFunctionScaling',
+ 'Colorize', 'ColorNegate', 'ColorOutput', 'ColorQuantize', 'Cone',
+ 'ColorRules', 'ColorSelectorSettings', 'ColorSeparate', 'Column',
+ 'ColorSetter', 'ColorSlider', 'ColorSpace', 'ColumnAlignments',
+ 'ColumnForm', 'ColumnLines', 'ColumnsEqual', 'ColumnSpacings',
+ 'ColumnWidths', '$CommandLine', 'CommonDefaultFormatTypes', 'Cosh',
+ 'CommonestFilter', 'Commonest', 'CompilationOptions', 'Compiled',
+ '$CompilationTarget', 'CompilationTarget', 'CompiledFunction',
+ 'Compile', 'Complement', 'CompleteGraph', 'CompleteGraphQ', 'Coth',
+ 'CompleteKaryTree', 'Complexes', 'ComplexExpand', 'Complex', 'End',
+ 'ComplexInfinity', 'ComplexityFunction', 'ComponentMeasurements',
+ 'ComposeList', 'Compose', 'ComposeSeries', 'Composition', 'Count',
+ 'CompoundExpression', 'Compress', 'ConditionalExpression', 'Cross',
+ 'Conditioned', 'Condition', 'ConfidenceLevel', 'ConfigurationPath',
+ '$ConfiguredKernels', 'Congruent', 'Conjugate', 'Conjunction',
+ 'ConjugateTranspose', 'ConnectedComponents', 'ConnectedGraphQ',
+ 'ConoverTest', 'ConstantArray', 'Constant', 'Constants', 'Context',
+ 'ConstrainedMax', 'ConstrainedMin', 'ContentPadding', '$Context',
+ 'ContentSelectable', 'ContentSize', '$ContextPath', 'Contexts',
+ 'ContextToFileName', 'ContinuedFractionK', 'ContinuedFraction',
+ 'Continue', 'ContinuousAction', 'ContinuousTimeModelQ', 'Contours',
+ 'ContinuousWaveletData', 'ContinuousWaveletTransform', 'Control',
+ 'ContourDetect', 'ContourGraphics', 'ContourLabels', 'ContourPlot',
+ 'ContourLevels', 'ContourLines', 'ContourPlot3D', 'ContourShading',
+ 'ContourSpacing', 'ContourStyle', 'ContraharmonicMean', 'Convolve',
+ 'ControlActive', '$ControlActiveSetting', 'ControllabilityGramian',
+ 'ControllabilityMatrix', 'ControllableDecomposition', 'CoprimeQ',
+ 'ControllableModelQ', 'ControllerInformation', 'ControllerLinking',
+ 'ControllerManipulate', 'ControllerMethod', 'ControllerPath',
+ 'ControllerState', 'ControlPlacement', 'ControlsRendering', 'Csch',
+ 'ControlType', 'Convergents', 'ConversionOptions', 'Coproduct',
+ 'ConversionRules', 'ConwayGroupCo1', 'ConwayGroupCo2', 'Copyable',
+ 'ConwayGroupCo3', 'CoordinatesToolOptions', 'CopulaDistribution',
+ 'CopyDirectory', 'CopyFile', 'CopyToClipboard', 'CornerFilter',
+ 'CornerNeighbors', 'CorrelationDistance', 'Correlation', 'Cubics',
+ 'CoshIntegral', 'CosineDistance', 'CosIntegral', 'CounterFunction',
+ 'CounterAssignments', 'CounterIncrements', 'CountRoots', 'Cuboid',
+ 'CounterStyleMenuListing', 'CountryData', 'Covariance', 'Cumulant',
+ 'CovarianceEstimatorFunction', 'CramerVonMisesTest', 'CrossMatrix',
+ 'CreateArchive', 'CreateDialog', 'CreateDirectory', 'CreateWindow',
+ 'CreateDocument', 'CreateIntermediateDirectories', 'CreatePalette',
+ 'CreateScheduledTask', '$CreationDate', 'CriticalSection', 'Cyan',
+ 'CrossingDetect', 'CumulantGeneratingFunction', 'CupCap', 'Cycles',
+ 'CurrentImage', '$CurrentLink', 'CurrentValue', 'CurveClosed',
+ 'CurvatureFlowFilter', 'CycleGraph', 'CyclicGroup', 'Cyclotomic',
+ 'Cylinder', 'CylindricalDecomposition', 'DagumDistribution', 'Erf',
+ 'DamerauLevenshteinDistance', 'Darker', 'Dashed', 'Dashing', 'Exp',
+ 'DataDistribution', 'DataRange', 'DataReversed', 'DateDifference',
+ 'DateFunction', 'DateListLogPlot', 'DateList', 'DateListPlot',
+ 'Date', 'DatePattern', 'DatePlus', '$DateStringFormat', 'DawsonF',
+ 'DateString', 'DateTicksFormat', 'DaubechiesWavelet', 'Debug',
+ 'DavisDistribution', 'DeBruijnGraph', 'DeclarePackage', 'Default',
+ 'Decompose', 'Decrement', 'DedekindEta', 'DefaultAxesStyle', 'Fit',
+ 'DefaultBaseStyle', 'DefaultBoxStyle', 'DefaultButton', 'Defer',
+ 'DefaultColor', 'DefaultDuplicateCellStyle', 'DefaultDuration',
+ 'DefaultElement', 'DefaultFaceGridsStyle', 'DefaultFieldHintStyle',
+ '$DefaultFont', 'DefaultFont', 'DefaultFontProperties', 'Degree',
+ 'DefaultFormatType', 'DefaultFrameStyle', 'DefaultFrameTicksStyle',
+ 'DefaultGridLinesStyle', '$DefaultImagingDevice', 'DefaultOptions',
+ 'DefaultInlineFormatType', 'DefaultLabelStyle', 'DefaultMenuStyle',
+ 'DefaultNaturalLanguage', 'DefaultNewCellStyle', 'DefaultNotebook',
+ 'DefaultNewInlineCellStyle', 'DefaultStyleDefinitions', 'Delete',
+ 'DefaultTicksStyle', 'Definition', 'DegreeCentrality', 'Deletable',
+ 'DegreeGraphDistribution', 'Deinitialization', 'DeleteCases',
+ 'DeleteBorderComponents', 'DeleteContents', 'DeleteDirectory',
+ 'DeleteDuplicates', 'DeleteFile', 'DeleteSmallComponents', 'Depth',
+ 'DeletionWarning', 'DelimiterFlashTime', 'DelimiterMatching',
+ 'Delimiter', 'Denominator', 'DensityGraphics', 'DensityHistogram',
+ 'DensityPlot', 'DependentVariables', 'Deployed', 'Deploy', 'Disk',
+ 'DepthFirstScan', 'DerivativeFilter', 'Derivative', 'DesignMatrix',
+ 'DGaussianWavelet', 'DiacriticalPositioning', 'DiagonalMatrix',
+ 'Diagonal', 'DialogInput', 'Dialog', 'DialogNotebook', 'Diamond',
+ 'DialogProlog', 'DialogReturn', 'DialogSymbols', 'DiamondMatrix',
+ 'DiceDissimilarity', 'DictionaryLookup', 'DifferenceDelta', 'Drop',
+ 'DifferenceRoot', 'DifferenceRootReduce', 'Differences', 'DigitQ',
+ 'DifferentialD', 'DifferentialRoot', 'DifferentialRootReduce',
+ 'DigitBlock', 'DigitCharacter', 'DigitCount', 'DihedralGroup',
+ 'Dilation', 'Dimensions', 'DiracComb', 'DiracDelta', 'Direction',
+ 'DirectedEdge', 'DirectedEdges', 'DirectedGraph', 'DirectedGraphQ',
+ 'DirectedInfinity', 'Directive', 'DirectoryName', 'Directory',
+ 'DirectoryQ', 'DirectoryStack', 'DirichletCharacter', 'DirichletL',
+ 'DirichletConvolve', 'DirichletDistribution', 'DirichletTransform',
+ 'DiscreteConvolve', 'DiscreteDelta', 'DiscreteIndicator', 'Divide',
+ 'DiscreteLQEstimatorGains', 'DiscreteLQRegulatorGains', 'Dispatch',
+ 'DiscreteLyapunovSolve', 'DiscretePlot3D', 'DiscretePlot', 'Dump',
+ 'DiscreteRatio', 'DiscreteRiccatiSolve', 'DiscreteShift', 'Dotted',
+ 'DiscreteTimeModelQ', 'DiscreteUniformDistribution', 'Disjunction',
+ 'DiscreteWaveletData', 'DiscreteWaveletPacketTransform', 'Display',
+ 'DiscreteWaveletTransform', 'Discriminant', 'DiskMatrix', 'DSolve',
+ 'DispersionEstimatorFunction', 'DisplayAllSteps', 'DisplayForm',
+ 'DisplayEndPacket', '$DisplayFunction', 'DisplayFunction', '$Echo',
+ '$Display', 'DisplayPacket', 'DisplayString', 'DistanceFunction',
+ 'DistanceTransform', '$DistributedContexts', 'DistributedContexts',
+ 'DistributeDefinitions', 'Distributed', 'Distribute', 'Dithering',
+ 'DistributionChart', 'DistributionFitTest', 'DivideBy', 'Dividers',
+ 'DistributionParameterAssumptions', 'DistributionParameterQ',
+ 'Divisible', 'DivisorSigma', 'Divisors', 'DivisorSum', 'DMSList',
+ 'DMSString', 'DockedCells', 'DocumentNotebook', 'DotDashed', 'For',
+ 'DotEqual', 'DoubleBracketingBar', 'DoubleDownArrow', 'DownArrow',
+ 'DoubleLeftArrow', 'DoubleLeftRightArrow', 'DoubleLongLeftArrow',
+ 'DoubleLongLeftRightArrow', 'DoubleLongRightArrow', 'DownArrowBar',
+ 'DoubleRightArrow', 'DoubleUpArrow', 'DoubleUpDownArrow', 'EdgeQ',
+ 'DoubleVerticalBar', 'DownArrowUpArrow', 'DownLeftRightVector',
+ 'DownLeftTeeVector', 'DownLeftVectorBar', 'DownLeftVector', 'Erfc',
+ 'DownRightTeeVector', 'DownRightVectorBar', 'DownRightVector',
+ 'DownTeeArrow', 'DownValues', 'DragAndDrop', 'DSolveConstants',
+ 'DualSystemsModel', 'DumpSave', '$DynamicEvaluation', 'Dynamic',
+ 'DynamicEvaluationTimeout', 'DynamicModule', 'DynamicModuleValues',
+ 'DynamicSetting', 'DynamicWrapper', 'EdgeAdd', 'EdgeCount', 'Erfi',
+ 'EdgeCoverQ', 'EdgeDelete', 'EdgeDetect', 'EdgeForm', 'EdgeIndex',
+ 'EdgeLabeling', 'EdgeLabels', 'EdgeLabelStyle', 'EdgeList', 'Exit',
+ 'EdgeRenderingFunction', 'EdgeRules', 'EdgeShapeFunction', 'Equal',
+ 'EdgeStyle', 'EdgeWeight', 'Editable', 'EditCellTagsSettings',
+ 'EditDistance', 'EffectiveInterest', 'Eigensystem', 'Eigenvalues',
+ 'EigenvectorCentrality', 'Eigenvectors', 'ElementData', 'Element',
+ 'Eliminate', 'EllipticE', 'EllipticExp', 'EllipticExpPrime', 'GCD',
+ 'EllipticF', 'EllipticK', 'EllipticLog', 'EllipticNomeQ', 'Encode',
+ 'EllipticPi', 'EllipticTheta', 'EllipticThetaPrime', 'EmitSound',
+ 'EmpiricalDistribution', 'EmptyGraphQ', 'Enabled', 'EndOfFile',
+ 'EndDialogPacket', 'EndOfLine', 'EndOfString', 'EndPackage', 'Get',
+ 'EngineeringForm', 'EnterExpressionPacket', 'EnterTextPacket',
+ 'EntropyFilter', 'Entropy', 'Environment', '$Epilog', 'Epilog',
+ 'EqualTilde', 'Equilibrium', 'Equivalent', 'ErlangDistribution',
+ 'Erosion', 'ErrorBox', 'ErrorBoxOptions', 'EstimatedDistribution',
+ 'EstimatorGains', 'EstimatorRegulator', 'EuclideanDistance', 'Hue',
+ 'EulerE', 'EulerGamma', 'EulerianGraphQ', 'EulerPhi', 'Evaluate',
+ 'Evaluatable', 'EvaluatePacket', 'EvaluationCompletionAction',
+ 'EvaluationElements', 'EvaluationMonitor', 'EvaluationNotebook',
+ 'EvaluationObject', 'EvaluatorNames', 'Evaluator', 'EvenQ', 'Find',
+ 'EventHandler', 'EventLabels', 'ExactNumberQ', 'ExampleData',
+ 'Except', 'ExcludedForms', 'ExcludePods', 'Exclusions', 'Exists',
+ 'ExclusionsStyle', 'ExpandAll', 'ExpandDenominator', 'Expand',
+ 'ExpandFileName', 'ExpandNumerator', 'Expectation', 'ExpIntegralE',
+ 'ExpectedValue', 'ExpGammaDistribution', 'ExpIntegralEi', 'Export',
+ 'ExponentFunction', 'ExponentialDistribution', 'ExponentialFamily',
+ 'ExponentialGeneratingFunction', 'ExponentialMovingAverage', 'LCM',
+ 'ExponentialPowerDistribution', 'Exponent', 'ExponentPosition',
+ 'ExponentStep', 'ExportAutoReplacements', '$ExportFormats', 'Flat',
+ 'ExportString', 'ExpressionCell', 'Expression', 'ExpToTrig', 'Log',
+ 'ExtendedGCD', 'Extension', 'ExtentElementFunction', 'ExtentSize',
+ 'ExtentMarkers', 'ExternalDataCharacterEncoding', 'ExtractArchive',
+ 'Extract', 'ExtremeValueDistribution', 'FaceForm', 'FaceGrids',
+ 'FaceGridsStyle', 'FactorComplete', 'Factorial2', 'Factorial',
+ 'FactorialMomentGeneratingFunction', 'FactorialMoment', 'Factor',
+ 'FactorialPower', 'FactorInteger', 'FactorList', 'FactorTermsList',
+ 'FactorSquareFreeList', 'FactorSquareFree', 'FactorTerms', 'False',
+ '$Failed', 'FeedbackType', 'Fibonacci', 'FieldHint', 'FieldMasked',
+ 'FieldHintStyle', 'FieldSize', 'FileBaseName', 'FileByteCount',
+ 'FileDate', 'FileExistsQ', 'FileExtension', 'FileFormat', 'First',
+ 'FileHash', 'FileNameDepth', 'FileNameDialogSettings', 'FileNames',
+ 'FileNameDrop', 'FileNameJoin', 'FileNameSetter', 'FileNameSplit',
+ 'FileNameTake', 'FilePrint', 'FileType', 'FilledCurve', 'Filling',
+ 'FillingStyle', 'FillingTransform', 'FilterRules', 'FinancialBond',
+ 'FinancialData', 'FinancialDerivative', 'FinancialIndicator',
+ 'FindArgMax', 'FindArgMin', 'FindClique', 'FindClusters', 'Floor',
+ 'FindCurvePath', 'FindDistributionParameters', 'FindDivisions',
+ 'FindEdgeCover', 'FindEulerianCycle', 'FindFile', 'FindFit', 'Map',
+ 'FindGeneratingFunction', 'FindGeoLocation', 'FindInstance', 'Max',
+ 'FindGeometricTransform', 'FindGraphIsomorphism', 'FindLibrary',
+ 'FindHamiltonianCycle', 'FindIndependentEdgeSet', 'FindList',
+ 'FindIndependentVertexSet', 'FindIntegerNullVector', 'FindMaximum',
+ 'FindLinearRecurrence', 'FindMaxValue', 'FindMinimum', 'FindRoot',
+ 'FindMinValue', 'FindPermutation', 'FindSequenceFunction', 'Fold',
+ 'FindSettings', 'FindShortestPath', 'FindShortestTour', 'Flatten',
+ 'FindThreshold', 'FindVertexCover', 'FinishDynamic', 'FittedModel',
+ 'FiniteAbelianGroupCount', 'FiniteGroupCount', 'FiniteGroupData',
+ 'FischerGroupFi22', 'FischerGroupFi23', 'FischerGroupFi24Prime',
+ 'FisherHypergeometricDistribution', 'FisherRatioTest', 'FlattenAt',
+ 'FisherZDistribution', 'FixedPointList', 'FixedPoint', 'FlipView',
+ 'FoldList', 'FontColor', 'FontFamily', 'FontForm', 'FontSize',
+ 'FontProperties', 'FontSlant', 'FontSubstitutions', 'FontTracking',
+ 'FontVariations', 'FontWeight', 'ForAll', 'Format', '$FormatType',
+ 'FormatTypeAutoConvert', 'FormatType', 'FormBox', 'FormBoxOptions',
+ 'FortranForm', 'ForwardBackward', 'Forward', 'FourierCoefficient',
+ 'FourierCosCoefficient', 'FourierCosSeries', 'FourierCosTransform',
+ 'FourierDCT', 'FourierDST', 'Fourier', 'FourierParameters', 'Full',
+ 'FourierSequenceTransform', 'FourierSeries', 'FourierSinSeries',
+ 'FourierSinCoefficient', 'FourierSinTransform', 'FourierTransform',
+ 'FourierTrigSeries', 'FractionalPart', 'FractionBox', 'FrameBox',
+ 'FractionBoxOptions', 'FractionLine', 'FrameBoxOptions', 'Framed',
+ 'FrameLabel', 'FrameMargins', 'Frame', 'FrameStyle', 'FrameTicks',
+ 'FrameTicksStyle', 'FRatioDistribution', 'FrechetDistribution',
+ 'FreeQ', 'FresnelC', 'FresnelS', 'FrobeniusNumber', 'FromASCII',
+ 'FrobeniusSolve', 'FromCharacterCode', 'FromCoefficientRules',
+ 'FromContinuedFraction', 'FromDate', 'FromDigits', 'FromDMS',
+ 'FrontEndDynamicExpression', 'FrontEndEventActions', '$FrontEnd',
+ 'FrontEndExecute', '$FrontEndSession', 'FrontEndStackSize', 'Glow',
+ 'FrontEndTokenExecute', 'FrontEndToken', 'Front', 'FullDefinition',
+ 'FullForm', 'FullGraphics', 'FullOptions', 'FullSimplify', 'Gamma',
+ 'FunctionExpand', 'FunctionInterpolation', 'Function', 'GatherBy',
+ 'FunctionSpace', 'GaborWavelet', 'GainMargins', 'GainPhaseMargins',
+ 'GammaDistribution', 'GammaRegularized', 'GapPenalty', 'Gather',
+ 'GaussianFilter', 'GaussianIntegers', 'GaussianMatrix', 'General',
+ 'GegenbauerC', 'GeneralizedLinearModelFit', 'GenerateConditions',
+ 'GeneratedCell', 'GeneratedParameters', 'GeneratingFunction',
+ 'GenericCylindricalDecomposition', 'GenomeData', 'GenomeLookup',
+ 'GeodesicDilation', 'GeodesicErosion', 'GeoDestination', 'Goto',
+ 'GeodesyData', 'GeoDirection', 'GeoDistance', 'GeoGridPosition',
+ '$GeoLocation', 'GeometricDistribution', 'GeometricMeanFilter',
+ 'GeometricMean', 'GeometricTransformation', 'GeoPositionENU',
+ 'GeoPosition', 'GeoPositionXYZ', 'GeoProjectionData', 'Glaisher',
+ 'GoldenRatio', 'GompertzMakehamDistribution', 'GradientFilter',
+ 'Gradient', 'GraphCenter', 'GraphComplement', 'GraphData', 'Graph',
+ 'GraphDiameter', 'GraphDifference', 'GraphDisjointUnion', 'GraphQ',
+ 'GraphDistanceMatrix', 'GraphDistance', 'GraphHighlight', 'Gray',
+ 'GraphHighlightStyle', 'Graphics3D', 'GraphicsArray', 'Graphics',
+ 'GraphicsColumn', 'GraphicsComplex', 'GraphicsGrid', 'GraphicsRow',
+ 'GraphicsGroup', 'GraphicsSpacing', 'GraphIntersection', 'Greater',
+ 'GraphLayout', 'GraphPeriphery', 'GraphPlot3D', 'GraphPlot', 'Min',
+ 'GraphPower', 'GraphRadius', 'GraphStyle', 'GraphUnion', 'Green',
+ 'GrayLevel', 'GreaterEqualLess', 'GreaterEqual', 'GreaterGreater',
+ 'GreaterFullEqual', 'GreaterLess', 'GreaterSlantEqual', 'GridBox',
+ 'GreaterTilde', 'GridBaseline', 'GridCreationSettings', 'Grid',
+ 'GridDefaultElement', 'GridFrameMargins', 'GridFrame', 'GridGraph',
+ 'GridLines', 'GridLinesStyle', 'GroebnerBasis', 'GroupActionBase',
+ 'GroupCentralizer', 'GroupElementPosition', 'GroupElementQ', 'Mod',
+ 'GroupElements', 'GroupGenerators', 'GroupMultiplicationTable',
+ 'GroupOrbits', 'GroupOrder', 'GroupPageBreakWithin', 'HaarWavelet',
+ 'GroupSetwiseStabilizer', 'GroupStabilizerChain', 'Gudermannian',
+ 'GroupStabilizer', 'GumbelDistribution', 'HalfNormalDistribution',
+ 'HamiltonianGraphQ', 'HammingDistance', 'HankelH1', 'HankelH2',
+ 'HankelMatrix', 'HaradaNortonGroupHN', 'HararyGraph', 'Hash',
+ 'HarmonicMeanFilter', 'HarmonicMean', 'HarmonicNumber', 'Head',
+ 'Haversine', 'HazardFunction', 'Heads', 'HeavisideLambda', 'Hold',
+ 'HeavisidePi', 'HeavisideTheta', 'HeldGroupHe', 'HeldPart', 'Item',
+ 'HelpBrowserSettings', 'HermiteDecomposition', 'HermiteH', 'Image',
+ 'HermitianMatrixQ', 'HessenbergDecomposition', 'HiddenSurface',
+ 'HexadecimalCharacter', 'HighlightGraph', 'HigmanSimsGroupHS',
+ 'HilbertMatrix', 'Histogram3D', 'HistogramDistribution', 'HoldAll',
+ 'HistogramList', 'Histogram', '$HistoryLength', 'HitMissTransform',
+ 'HITSCentrality', 'HoldAllComplete', 'HoldComplete', 'HoldFirst',
+ 'HoldForm', 'HoldPattern', 'HoldRest', '$HomeDirectory', 'ImageQ',
+ 'HomeDirectory', 'HornerForm', 'HotellingTSquareDistribution',
+ 'HoytDistribution', 'HTMLSave', 'HumpDownHump', 'HumpEqual', 'Nor',
+ 'HurwitzLerchPhi', 'HurwitzZeta', 'HyperbolicDistribution', 'Join',
+ 'HypercubeGraph', 'Hyperfactorial', 'Hypergeometric0F1', 'Implies',
+ 'Hypergeometric0F1Regularized', 'Hypergeometric1F1', 'Hyperlink',
+ 'Hypergeometric1F1Regularized', 'Hypergeometric2F1', 'Hyphenation',
+ 'Hypergeometric2F1Regularized', 'HypergeometricDistribution',
+ 'HypergeometricPFQ', 'HypergeometricPFQRegularized', 'Identity',
+ 'HypergeometricU', 'HypothesisTestData', 'IdentityMatrix', 'Infix',
+ 'IgnoreCase', '$IgnoreEOF', 'ImageAdd', 'ImageAdjust', 'ImageClip',
+ 'ImageAlign', 'ImageApply', 'ImageAspectRatio', 'ImageAssemble',
+ 'ImageCapture', 'ImageChannels', 'ImageColorSpace', 'ImageCompose',
+ 'ImageConvolve', 'ImageCooccurrence', 'ImageCorrelate', 'ImagePad',
+ 'ImageCorrespondingPoints', 'ImageCrop', 'ImageData', 'ImageLines',
+ 'ImageDeconvolve', 'ImageDifference', 'ImageDimensions', 'Import',
+ 'ImageEffect', 'ImageFilter', 'ImageForestingComponents', 'Inner',
+ 'ImageForwardTransformation', 'ImageHistogram', 'ImageKeypoints',
+ 'ImageLevels', 'ImageMargins', 'ImageMultiply', 'ImagePadding',
+ 'ImagePartition', 'ImagePerspectiveTransformation', 'ImageReflect',
+ 'ImageRegion', 'ImageResize', 'ImageResolution', 'ImageRotated',
+ 'ImageRotate', 'ImageScaled', 'ImageSizeAction', 'ImageSize',
+ 'ImageSizeMultipliers', 'ImageSubtract', 'ImageTake', 'ImageTrim',
+ 'ImageTransformation', 'ImageType', 'ImageValue', '$ImportFormats',
+ '$ImagingDevices', 'ImportAutoReplacements', 'ImportString', 'Not',
+ 'IncidenceGraph', 'IncidenceMatrix', 'IncludeConstantBasis', 'Off',
+ 'IncludeFileExtension', 'IncludePods', 'Increment', 'IndexGraph',
+ 'IndependentEdgeSetQ', 'IndependentVertexSetQ', 'Indeterminate',
+ 'InexactNumberQ', 'Infinity', 'Information', 'Inherited', '$Input',
+ '$InitialDirectory', 'InitializationCellEvaluation', 'Inpaint',
+ 'InitializationCell', 'InitializationCellWarning', 'InputAliases',
+ 'InitializationGroup', 'Initialization', 'InputAssumptions', 'Out',
+ 'InputAutoReplacements', 'InputField', '$InputFileName', 'Input',
+ 'InputForm', 'InputNamePacket', 'InputNotebook', 'InputPacket',
+ 'InputStream', 'InputString', 'InputStringPacket', 'Insert', 'PDF',
+ 'InsertResults', 'Inset', '$Inspector', '$InstallationDate', 'Put',
+ '$InstallationDirectory', 'Install', 'InstallService', 'InString',
+ 'IntegerDigits', 'IntegerExponent', 'IntegerLength', 'Integer',
+ 'IntegerPartitions', 'IntegerPart', 'IntegerQ', 'Integers', 'Last',
+ 'IntegerString', 'Integrate', 'InteractiveTradingChart', 'Inverse',
+ 'Interleaving', 'InternallyBalancedDecomposition', 'Interpolation',
+ 'InterpolatingFunction', 'InterpolatingPolynomial', 'Interrupt',
+ 'InterpolationOrder', 'InterpolationPoints', 'InterpretationBox',
+ 'InterpretationBoxOptions', 'Interpretation', 'InterquartileRange',
+ 'Intersection', 'IntervalIntersection', 'IntervalMemberQ', 'Label',
+ 'Interval', 'IntervalUnion', 'InverseBetaRegularized', 'Invisible',
+ 'InverseCDF', 'InverseChiSquareDistribution', 'InverseErfc', 'Raw',
+ 'InverseContinuousWaveletTransform', 'InverseDistanceTransform',
+ 'InverseEllipticNomeQ', 'InverseErf', 'InverseFourierCosTransform',
+ 'InverseFourier', 'InverseFourierSequenceTransform', 'IsotopeData',
+ 'InverseFourierSinTransform', 'InverseFourierTransform', 'Italic',
+ 'InverseFunction', 'InverseFunctions', 'InverseGammaDistribution',
+ 'InverseGammaRegularized', 'InverseGaussianDistribution', 'Joined',
+ 'InverseGudermannian', 'InverseHaversine', 'InverseJacobiCD',
+ 'InverseJacobiCN', 'InverseJacobiCS', 'InverseJacobiDC', 'JacobiP',
+ 'InverseJacobiDN', 'InverseJacobiDS', 'InverseJacobiNC', 'Kernels',
+ 'InverseJacobiND', 'InverseJacobiNS', 'InverseJacobiSC', 'Labeled',
+ 'InverseJacobiSD', 'InverseJacobiSN', 'InverseLaplaceTransform',
+ 'InversePermutation', 'InverseRadon', 'InverseSeries', 'ItemSize',
+ 'InverseSurvivalFunction', 'InverseWaveletTransform', 'ItemStyle',
+ 'InverseWeierstrassP', 'InverseZTransform', 'IsolatingInterval',
+ 'IrreduciblePolynomialQ', 'IsomorphicGraphQ', 'ItemAspectRatio',
+ '$IterationLimit', 'JaccardDissimilarity', 'JacobiAmplitude',
+ 'JacobiCD', 'JacobiCN', 'JacobiCS', 'JacobiDC', 'JacobiDN', 'Left',
+ 'JacobiDS', 'JacobiNC', 'JacobiND', 'JacobiNS', 'JacobiSC', 'Less',
+ 'JacobiSD', 'JacobiSN', 'JacobiSymbol', 'JacobiZeta', 'JoinForm',
+ 'JankoGroupJ1', 'JankoGroupJ2', 'JankoGroupJ3', 'JankoGroupJ4',
+ 'JarqueBeraALMTest', 'JohnsonDistribution', 'JoinedCurve', 'Large',
+ 'JordanDecomposition', 'JordanModelDecomposition', 'KagiChart',
+ 'KalmanEstimator', 'KarhunenLoeveDecomposition', 'KaryTree', 'Red',
+ 'KatzCentrality', 'KCoreComponents', 'KDistribution', 'KelvinBei',
+ 'KelvinBer', 'KelvinKei', 'KelvinKer', '$KernelCount', '$KernelID',
+ 'KernelMixtureDistribution', 'KernelObject', 'Khinchin', 'Larger',
+ 'KirchhoffGraph', 'KirchhoffMatrix', 'KleinInvariantJ', 'KnotData',
+ 'KnightTourGraph', 'KolmogorovSmirnovTest', 'KroneckerDelta',
+ 'KroneckerProduct', 'KroneckerSymbol', 'KuiperTest', 'Kurtosis',
+ 'KumaraswamyDistribution', 'KuwaharaFilter', 'LabelingFunction',
+ 'LabelStyle', 'LaguerreL', 'LandauDistribution', '$Language',
+ 'LanguageCategory', 'Language', 'LaplaceDistribution', 'Latitude',
+ 'LaplaceTransform', 'LaplacianFilter', 'LaplacianGaussianFilter',
+ 'LatitudeLongitude', 'LatticeData', 'LatticeReduce', 'LeafCount',
+ 'LaunchKernels', 'LayeredGraphPlot', 'LayerSizeFunction', 'Length',
+ 'LeastSquares', 'LeftArrowBar', 'LeftArrow', 'LeftArrowRightArrow',
+ 'LeftDownTeeVector', 'LeftDownVectorBar', 'LeftDownVector', 'Line',
+ 'LeftRightArrow', 'LeftRightVector', 'LeftTeeArrow', 'LeftVector',
+ 'LeftTeeVector', 'LeftTriangleBar', 'LeftTriangleEqual', 'LetterQ',
+ 'LeftTriangle', 'LeftUpDownVector', 'LeftUpTeeVector', 'Legended',
+ 'LeftUpVectorBar', 'LeftUpVector', 'LeftVectorBar', 'LegendreP',
+ 'LegendAppearance', 'LegendreQ', 'LegendreType', 'LengthWhile',
+ 'LerchPhi', 'LessEqualGreater', 'LessEqual', 'LessFullEqual',
+ 'LessGreater', 'LessLess', 'LessSlantEqual', 'LessTilde', 'Level',
+ 'LetterCharacter', 'LeveneTest', 'LeviCivitaTensor', 'LibraryLoad',
+ 'LevyDistribution', 'LibraryFunctionError', 'LibraryFunctionLoad',
+ 'LibraryFunctionInformation', 'LibraryFunction', '$LibraryPath',
+ 'LibraryFunctionUnload', 'LibraryUnload', '$LicenseExpirationDate',
+ '$LicenseID', '$LicenseServer', 'LiftingFilterData', 'LightBlue',
+ 'LiftingWaveletTransform', 'LightBrown', 'LightCyan', 'Lighter',
+ 'LightGray', 'LightGreen', 'LightingAngle', 'Lighting', 'LightRed',
+ 'LightMagenta', 'LightOrange', 'LightPink', 'LightPurple', 'Limit',
+ 'LightSources', 'LightYellow', 'Likelihood', 'LimitsPositioning',
+ 'LimitsPositioningTokens', 'LindleyDistribution', 'LinearModelFit',
+ 'LinearFractionalTransform', 'LinearOffsetFunction', 'LinearSolve',
+ 'LinearProgramming', 'LinearRecurrence', 'LinearSolveFunction',
+ 'LinebreakAdjustments', 'LineBreakChart', 'LineBreakWithin', 'Row',
+ 'LineGraph', 'LineIndentMaxFraction', 'LineIndent', '$Line', 'Run',
+ 'LineIntegralConvolutionPlot', 'LineIntegralConvolutionScale',
+ 'LineSpacing', 'LinkClose', 'LinkConnect', 'LinkCreate', '$Linked',
+ 'LinkFunction', 'LinkInterrupt', 'LinkLaunch', 'LinkObject', 'Sec',
+ 'LinkOpen', 'LinkPatterns', 'LinkProtocol', 'LinkRead', 'Links',
+ 'LinkReadyQ', 'LinkWrite', 'LiouvilleLambda', 'Listable', 'List',
+ 'ListAnimate', 'ListContourPlot3D', 'ListContourPlot', 'ListPlay',
+ 'ListConvolve', 'ListCorrelate', 'ListCurvePathPlot', 'ListPlot3D',
+ 'ListDeconvolve', 'ListDensityPlot', 'ListInterpolation', 'Locked',
+ 'ListLineIntegralConvolutionPlot', 'ListLinePlot', 'ListLogPlot',
+ 'ListLogLinearPlot', 'ListLogLogPlot', 'ListPlot', 'ListPolarPlot',
+ 'ListPointPlot3D', 'ListStreamDensityPlot', 'ListStreamPlot',
+ 'ListSurfacePlot3D', 'ListVectorDensityPlot', 'ListVectorPlot3D',
+ 'ListVectorPlot', 'Literal', 'LocalizeVariables', 'LocationTest',
+ 'LocationEquivalenceTest', 'LocatorAutoCreate', 'Locator', 'Log10',
+ 'LocatorPane', 'LocatorRegion', 'Log2', 'LogBarnesG', 'LogGamma',
+ 'LogGammaDistribution', 'LogicalExpand', 'LogIntegral', 'LogPlot',
+ 'LogisticDistribution', 'LogitModelFit', 'LogLikelihood', 'LucasL',
+ 'LogLinearPlot', 'LogLogisticDistribution', 'LogLogPlot', 'Manual',
+ 'LogNormalDistribution', 'LogSeriesDistribution', 'LongestMatch',
+ 'LongestCommonSequence', 'LongestCommonSubsequence', 'Longest',
+ 'Longitude', 'LongLeftArrow', 'LongLeftRightArrow', 'LowerCaseQ',
+ 'LongRightArrow', 'LoopFreeGraphQ', 'LowerLeftArrow', '$MachineID',
+ 'LowerRightArrow', 'LowerTriangularize', 'LQEstimatorGains', 'Set',
+ 'LQGRegulator', 'LQOutputRegulatorGains', 'LQRegulatorGains',
+ 'LUBackSubstitution', 'LUDecomposition', 'LyapunovSolve', 'MapAll',
+ 'LyonsGroupLy', '$MachineAddresses', '$MachineDomain', 'Magenta',
+ '$MachineDomains', '$MachineEpsilon', '$MachineName', 'Magnify',
+ 'MachineNumberQ', '$MachinePrecision', 'MachinePrecision', 'MapAt',
+ '$MachineType', 'Magnification', 'Majority', 'MakeBoxes', 'MatchQ',
+ 'MakeExpression', 'MangoldtLambda', 'ManhattanDistance', 'MarcumQ',
+ 'Manipulate', 'Manipulator', 'MannWhitneyTest', 'MantissaExponent',
+ 'MapIndexed', 'MapThread', 'MardiaCombinedTest', 'Masking', 'Mean',
+ 'MardiaKurtosisTest', 'MardiaSkewnessTest', 'MarginalDistribution',
+ 'MatchingDissimilarity', 'MatchLocalNames', 'MathieuC', 'MathieuS',
+ 'MathieuCharacteristicA', 'MathieuCharacteristicB', 'MathMLForm',
+ 'MathieuCharacteristicExponent', 'MathieuCPrime', 'MathieuSPrime',
+ 'MathieuGroupM11', 'MathieuGroupM12', 'MathieuGroupM22', 'MatrixQ',
+ 'MathieuGroupM23', 'MathieuGroupM24', 'MatrixExp', 'MatrixForm',
+ 'MatrixPlot', 'MatrixPower', 'MatrixRank', 'MaxDetect', 'Maximize',
+ 'MaxExtraBandwidths', 'MaxExtraConditions', '$MaxExtraPrecision',
+ 'MaxFilter', 'MaxIterations', '$MaxMachineNumber', 'MaxMemoryUsed',
+ 'MaxMixtureKernels', '$MaxNumber', '$MaxPiecewiseCases', '$$Media',
+ 'MaxPlotPoints', '$MaxPrecision', 'MaxRecursion', '$MaxRootDegree',
+ 'MaxStableDistribution', 'MaxStepFraction', 'MaxStepSize', 'Mesh',
+ 'MaxSteps', 'MaxValue', 'MaxwellDistribution', 'MeanDeviation',
+ 'McLaughlinGroupMcL', 'MeanFilter', 'MeanShiftFilter', 'MeanShift',
+ 'MedianDeviation', 'MedianFilter', 'Median', 'Medium', 'MeijerG',
+ 'MemberQ', 'MemoryConstrained', 'MemoryInUse', 'MenuCommandKey',
+ 'MenuPacket', 'MenuSortingValue', 'MenuStyle', 'MenuView', 'Minus',
+ 'MeshFunctions', 'MeshRange', 'MeshShading', 'MeshStyle', 'Method',
+ 'MessageDialog', '$MessageGroups', '$MessageList', 'MessageList',
+ 'MessageName', 'Message', 'MessagePacket', '$MessagePrePrint',
+ '$Messages', 'Messages', 'MexicanHatWavelet', 'MeyerWavelet',
+ 'MinDetect', 'MinFilter', 'MinimalPolynomial', 'Minimize', 'Modal',
+ 'MinimalStateSpaceModel', '$MinMachineNumber', '$MinNumber', 'Sin',
+ 'Minors', '$MinPrecision', 'MinStableDistribution', 'MinusPlus',
+ 'MinValue', 'Missing', 'MixtureDistribution', 'ModularLambda',
+ 'Module', '$ModuleNumber', 'Modulus', 'MoebiusMu', 'MomentConvert',
+ 'MomentEvaluate', 'MomentGeneratingFunction', 'Moment', 'Monitor',
+ 'MonomialList', 'MonsterGroupM', 'MorletWavelet', 'Most', 'NameQ',
+ 'MorphologicalBinarize', 'MorphologicalBranchPoints', 'Mouseover',
+ 'MorphologicalComponents', 'MorphologicalEulerNumber', 'Names',
+ 'MorphologicalGraph', 'MorphologicalPerimeter', 'MouseAnnotation',
+ 'MorphologicalTransform', 'MouseAppearance', 'MousePosition',
+ 'MovingAverage', 'MovingMedian', 'MoyalDistribution', 'Nand',
+ 'MultiedgeStyle', 'MultilaunchWarning', 'MultilineFunction', 'Sow',
+ 'MultinomialDistribution', 'Multinomial', 'MultiplicativeOrder',
+ 'MultinormalDistribution', 'MultivariatePoissonDistribution',
+ 'MultivariateHypergeometricDistribution', 'NakagamiDistribution',
+ 'MultivariateTDistribution', 'NArgMax', 'NArgMin', 'NCache', 'Sum',
+ 'NDSolve', 'NearestFunction', 'Nearest', 'Needs', 'Negative',
+ 'NeedlemanWunschSimilarity', 'NegativeBinomialDistribution', 'Tan',
+ 'NegativeMultinomialDistribution', 'NeighborhoodGraph', 'NestList',
+ 'NestedGreaterGreater', 'NestedLessLess', 'Nest', 'NestWhileList',
+ 'NestWhile', 'NevilleThetaC', 'NevilleThetaD', 'NevilleThetaN',
+ 'NevilleThetaS', '$NewMessage', '$NewSymbol', 'NExpectation',
+ 'NextPrime', 'NHoldAll', 'NHoldFirst', 'NHoldRest', 'NicholsPlot',
+ 'NicholsGridLines', 'NIntegrate', 'NMaximize', 'NMaxValue', 'None',
+ 'NMinimize', 'NMinValue', 'NominalVariables', 'NonConstants',
+ 'NoncentralBetaDistribution', 'NoncentralChiSquareDistribution',
+ 'NoncentralFRatioDistribution', 'NoncentralStudentTDistribution',
+ 'NonCommutativeMultiply', 'NonlinearModelFit', 'NonNegative',
+ 'NonPositive', 'NorlundB', 'NormalDistribution', 'Normalize',
+ 'NormalizedSquaredEuclideanDistance', 'Normal', 'NormalsFunction',
+ 'NormFunction', 'Norm', 'NotCongruent', 'NotCupCap', 'NotebookGet',
+ 'NotDoubleVerticalBar', 'NotebookApply', 'NotebookAutoSave', 'Top',
+ 'NotebookBrowseDirectory', 'NotebookClose', 'NotebookCreate',
+ 'NotebookConvertSettings', 'NotebookDelete', 'NotebookDirectory',
+ 'NotebookDynamicExpression', 'NotebookEvaluate', 'NotebookFind',
+ 'NotebookEventActions', 'NotebookFileName', 'NotebookInformation',
+ 'NotebookLocate', 'Notebook', 'NotebookObject', 'NotebookOpen',
+ 'NotebookPath', 'NotebookPrint', 'NotebookPut', 'NotebookRead',
+ 'NotebookSave', 'NotebookSelection', 'NotebooksMenu', '$Notebooks',
+ 'Notebooks', 'NotebookWrite', 'NotElement', 'NotEqualTilde', 'Vee',
+ 'NotExists', 'NotGreaterEqual', 'NotGreaterFullEqual', 'NotLess',
+ 'NotGreaterGreater', 'NotGreaterLess', 'NotGreater', 'NotLessLess',
+ 'NotGreaterSlantEqual', 'NotGreaterTilde', 'NotHumpDownHump',
+ 'NotHumpEqual', 'NotLeftTriangleBar', 'NotLeftTriangleEqual',
+ 'NotLeftTriangle', 'NotLessEqual', 'NotLessFullEqual', 'NotSubset',
+ 'NotLessGreater', 'NotLessSlantEqual', 'NotLessTilde', 'NotTilde',
+ 'NotNestedGreaterGreater', 'NotNestedLessLess', 'NotPrecedesEqual',
+ 'NotPrecedes', 'NotPrecedesSlantEqual', 'NotPrecedesTilde', 'NSum',
+ 'NotReverseElement', 'NotRightTriangleBar', 'NotRightTriangle',
+ 'NotRightTriangleEqual', 'NotSquareSubsetEqual', 'NotSquareSubset',
+ 'NotSquareSupersetEqual', 'NotSquareSuperset', 'NotSubsetEqual',
+ 'NotSucceedsEqual', 'NotSucceeds', 'NotSucceedsSlantEqual', 'Null',
+ 'NotSucceedsTilde', 'NotSupersetEqual', 'NotSuperset', 'NProduct',
+ 'NotTildeEqual', 'NotTildeFullEqual', 'NotTildeTilde', 'NRoots',
+ 'NotVerticalBar', 'NProbability', 'NSolve', 'NullRecords', 'OddQ',
+ 'NullSpace', 'NullWords', 'NumberFieldClassNumber', 'NumberFormat',
+ 'NumberFieldDiscriminant', 'NumberFieldFundamentalUnits', 'Number',
+ 'NumberFieldIntegralBasis', 'NumberFieldNormRepresentatives',
+ 'NumberFieldRegulator', 'NumberFieldRootsOfUnity', 'NumberForm',
+ 'NumberFieldSignature', '$NumberMarks', 'NumberMarks', 'NumberQ',
+ 'NumberMultiplier', 'NumberPadding', 'NumberPoint', 'NumberSigns',
+ 'NumberSeparator', 'NumberString', 'Numerator', 'NumericFunction',
+ 'NumericQ', 'NyquistGridLines', 'NyquistPlot', 'ObservableModelQ',
+ 'ObservabilityGramian', 'ObservabilityMatrix', 'Offset', 'Opacity',
+ 'ObservableDecomposition', 'ONanGroupON', 'OneIdentity', 'Opener',
+ 'OpenAppend', 'OpenerView', 'Opening', 'OpenRead', 'OpenTemporary',
+ 'OpenWrite', 'Operate', '$OperatingSystem', 'OperatingSystem',
+ 'Optional', 'OptionInspectorSettings', 'Options', 'OptionsPattern',
+ 'OptionValue', 'Orange', 'OrderDistribution', 'OrderedQ', 'Order',
+ 'Ordering', 'Orderless', 'Orthogonalize', 'Outer', 'OutputForm',
+ 'OutputAutoOverwrite', 'OutputControllabilityMatrix', '$Output',
+ 'OutputControllableModelQ', 'OutputNamePacket', 'OutputResponse',
+ '$OutputSizeLimit', 'OutputSizeLimit', 'OutputStream', 'OverBar',
+ 'OverDot', 'Overflow', 'OverHat', 'Overlaps', 'Overlay', 'OwenT',
+ 'OverscriptBox', 'OverscriptBoxOptions', 'Overscript', 'OverTilde',
+ 'OverVector', 'OwnValues', '$Packages', 'PackingMethod', 'Padding',
+ 'PaddedForm', 'PadeApproximant', 'PadLeft', 'PadRight', 'Paneled',
+ 'PageBreakAbove', 'PageBreakBelow', 'PageBreakWithin', 'PageWidth',
+ 'PageFooterLines', 'PageFooters', 'PageHeaderLines', 'PageHeaders',
+ 'PageRankCentrality', 'PairedBarChart', 'PairedHistogram', 'Panel',
+ 'PairedTTest', 'PairedZTest', 'PaletteNotebook', 'PalettePath',
+ 'Pane', 'PaneSelector', 'ParabolicCylinderD', 'ParagraphIndent',
+ 'ParagraphSpacing', 'ParallelArray', 'ParallelCombine', 'Part',
+ 'ParallelDo', 'ParallelEvaluate', 'Parallelization', 'Parallelize',
+ 'ParallelMap', 'ParallelNeeds', 'ParallelProduct', 'ParallelSum',
+ 'ParallelSubmit', 'ParallelTable', 'ParallelTry', 'ParametricPlot',
+ 'ParameterEstimator', 'ParameterMixtureDistribution', 'Partition',
+ 'ParametricPlot3D', 'ParentDirectory', '$ParentLink', 'Paste',
+ '$ParentProcessID', 'ParetoDistribution', 'ParticleData', '$Path',
+ 'PartitionsP', 'PartitionsQ', 'PascalDistribution', 'PassEventsUp',
+ 'PassEventsDown', 'PasteBoxFormInlineCells', 'PasteButton', 'Path',
+ 'PathGraph', 'PathGraphQ', '$PathnameSeparator', 'Pattern', 'Pick',
+ 'PatternSequence', 'PatternTest', 'PauliMatrix', 'PaulWavelet',
+ 'Pause', 'PearsonChiSquareTest', 'PearsonDistribution', 'Permute',
+ '$PerformanceGoal', 'PerformanceGoal', 'PermutationCycles', 'Pink',
+ 'PermutationCyclesQ', 'PermutationGroup', 'PermutationLength',
+ 'PermutationList', 'PermutationListQ', 'PermutationMax', 'Placed',
+ 'PermutationMin', 'PermutationOrder', 'PermutationPower', 'Plain',
+ 'PermutationProduct', 'PermutationReplace', 'Permutations', 'Play',
+ 'PermutationSupport', 'PeronaMalikFilter', 'PERTDistribution',
+ 'PetersenGraph', 'PhaseMargins', 'PiecewiseExpand', 'Piecewise',
+ 'PieChart3D', 'PieChart', 'PixelConstrained', 'PixelValue', 'Plot',
+ 'Placeholder', 'PlaceholderReplace', 'PlayRange', 'Plot3D', 'Plus',
+ 'Plot3Matrix', 'PlotDivision', 'PlotJoined', 'PlotLabel', 'Point',
+ 'PlotLayout', 'PlotMarkers', 'PlotPoints', 'PlotRangeClipping',
+ 'PlotRange', 'PlotRangePadding', 'PlotRegion', 'PlotStyle', '$Pre',
+ 'PlusMinus', 'Pochhammer', 'PodStates', 'PodWidth', 'PointSize',
+ 'PointFigureChart', 'PoissonConsulDistribution', 'PolarAxes',
+ 'PoissonDistribution', 'PolarAxesOrigin', 'PolarGridLines', 'Quit',
+ 'PolarPlot', 'PolarTicks', 'PoleZeroMarkers', 'PolyGamma', '$Post',
+ 'PolyaAeppliDistribution', 'PolygonIntersections', 'Polygon',
+ 'PolyhedronData', 'PolyLog', 'PolynomialExtendedGCD', 'PopupMenu',
+ 'PolynomialGCD', 'PolynomialLCM', 'PolynomialMod', 'PolynomialQ',
+ 'PolynomialQuotient', 'PolynomialQuotientRemainder', 'PopupView',
+ 'PolynomialReduce', 'PolynomialRemainder', 'PopupWindow', 'Power',
+ 'Position', 'PositiveDefiniteMatrixQ', 'Positive', 'PossibleZeroQ',
+ 'Postfix', 'PowerDistribution', 'PowerExpand', 'PowerModList',
+ 'PowerMod', 'PowersRepresentations', 'PowerSymmetricPolynomial',
+ 'PrecedenceForm', 'PrecedesEqual', 'Precedes', 'PrecedesTilde',
+ 'PrecedesSlantEqual', 'PrecisionGoal', 'Precision', 'PreDecrement',
+ 'PreemptProtect', 'PreferencesPath', 'Prefix', 'PreIncrement',
+ 'Prepend', 'PrependTo', '$PrePrint', '$PreRead', 'Prime', 'PrimeQ',
+ 'PreserveImageOptions', 'PriceGraphDistribution', 'PrimeNu', 'Xor',
+ 'PrimeOmega', 'PrimePi', 'PrimePowerQ', 'Primes', 'PrimeZetaP',
+ 'PrimitiveRoot', 'PrincipalComponents', 'PrincipalValue', 'Print',
+ 'PrintAction', 'PrintingCopies', 'PrintingOptions', 'PrivatePaths',
+ 'PrintingPageRange', 'PrintingStartingPageNumber', 'Probability',
+ 'PrintingStyleEnvironment', 'PrintPrecision', 'PrintTemporary',
+ 'PrivateEvaluationOptions', 'PrivateFontOptions', 'ProbitModelFit',
+ 'PrivateNotebookOptions', 'ProbabilityDistribution', '$ProcessID',
+ 'ProbabilityPlot', 'ProbabilityScalePlot', '$ProcessorCount',
+ '$ProcessorType', 'ProductDistribution', '$ProductInformation',
+ 'ProductLog', 'Product', 'ProgressIndicator', 'Projection', 'Read',
+ 'Prolog', 'Properties', 'PropertyList', 'Property', 'Proportional',
+ 'PropertyValue', 'Proportion', 'Protected', 'Protect', 'Pruning',
+ 'ProteinData', 'PseudoInverse', 'Purple', 'PutAppend', 'QBinomial',
+ 'QFactorial', 'QGamma', 'QHypergeometricPFQ', 'QPochhammer',
+ 'QPolyGamma', 'QRDecomposition', 'QuadraticIrrationalQ', 'Quiet',
+ 'Quantile', 'QuantilePlot', 'Quartics', 'QuartileDeviation',
+ 'QuartileSkewness', 'Quartiles', 'Quotient', 'QuotientRemainder',
+ 'RadicalBox', 'RadicalBoxOptions', 'RadioButtonBar', 'RadioButton',
+ 'Radon', 'RamanujanTauL', 'RamanujanTau', 'RamanujanTauTheta',
+ 'RamanujanTauZ', 'RandomChoice', 'RandomComplex', 'RandomGraph',
+ 'RandomImage', 'RandomInteger', 'Random', 'RandomPermutation',
+ 'RandomPrime', 'RandomReal', 'RandomSample', '$RandomState',
+ 'RandomVariate', 'RangeFilter', 'Range', 'RankedMax', 'RankedMin',
+ 'RasterArray', 'Rasterize', 'Raster', 'RasterSize', 'Rationalize',
+ 'Rational', 'Rationals', 'Ratios', 'RawBoxes', 'RawData', 'Real',
+ 'RayleighDistribution', 'ReadList', 'ReadProtected', 'RealDigits',
+ 'RealBlockDiagonalForm', 'RealExponent', 'Reals', 'Reap', 'Record',
+ 'RecordLists', 'RecordSeparators', 'RectangleChart3D', 'Rectangle',
+ 'RectangleChart', 'RecurrenceTable', '$RecursionLimit', 'Reduce',
+ 'ReferenceLineStyle', 'Refine', 'ReflectionMatrix', 'Refresh',
+ 'ReflectionTransform', 'RefreshRate', 'RegionBinarize', 'Release',
+ 'RegionFunction', 'RegionPlot3D', 'RegionPlot', 'Regularization',
+ 'RegularExpression', 'ReleaseHold', '$ReleaseNumber', 'ReliefPlot',
+ 'ReliefImage', 'RemoveAlphaChannel', 'Remove', 'RemoveProperty',
+ 'RemoveScheduledTask', 'RenameDirectory', 'RenameFile', 'Repeated',
+ 'RenderAll', 'RenkoChart', 'RepeatedNull', 'ReplaceAll', 'Replace',
+ 'ReplaceHeldPart', 'ReplaceList', 'ReplacePart', 'ReplaceRepeated',
+ 'Resampling', 'Rescale', 'RescalingTransform', 'ResetDirectory',
+ 'ResetMedium', 'ResetScheduledTask', 'Residue', 'Resolve', 'Rest',
+ 'Resultant', 'ResumePacket', 'ReturnExpressionPacket', 'Return',
+ 'ReturnPacket', 'ReturnTextPacket', 'ReverseElement', 'Reverse',
+ 'ReverseBiorthogonalSplineWavelet', 'ReverseEquilibrium', 'Riffle',
+ 'ReverseGraph', 'ReverseUpEquilibrium', 'RevolutionAxis', 'Right',
+ 'RevolutionPlot3D', 'RGBColor', 'RiccatiSolve', 'RiceDistribution',
+ 'RidgeFilter', 'RiemannR', 'RiemannSiegelTheta', 'RiemannSiegelZ',
+ 'RightArrowBar', 'RightArrowLeftArrow', 'RightArrow', 'Root',
+ 'RightCosetRepresentative', 'RightDownTeeVector', 'RightTeeArrow',
+ 'RightDownVectorBar', 'RightDownVector', 'RightTeeVector', 'Roots',
+ 'RightTriangleBar', 'RightTriangleEqual', 'RightTriangle', 'Round',
+ 'RightUpDownVector', 'RightUpTeeVector', 'RightUpVectorBar',
+ 'RightUpVector', 'RightVectorBar', 'RightVector', '$RootDirectory',
+ 'RogersTanimotoDissimilarity', 'RootApproximant', 'RootIntervals',
+ 'RootLocusPlot', 'RootMeanSquare', 'RootOfUnityQ', 'RootReduce',
+ 'RootSum', 'RotateLabel', 'RotateLeft', 'Rotate', 'RotateRight',
+ 'RotationAction', 'RotationMatrix', 'RotationTransform', 'RowBox',
+ 'RoundingRadius', 'RowAlignments', 'RowLines', 'RowMinHeight',
+ 'RowReduce', 'RowsEqual', 'RowSpacings', 'RSolve', 'RuleDelayed',
+ 'RudvalisGroupRu', 'Rule', 'RulerUnits', 'RunScheduledTask',
+ 'RunThrough', 'RuntimeAttributes', 'RuntimeOptions', 'SameQ',
+ 'RussellRaoDissimilarity', 'SameTest', 'SampleDepth', 'SampleRate',
+ 'SampledSoundFunction', 'SampledSoundList', 'SamplingPeriod',
+ 'SatisfiabilityCount', 'SatisfiabilityInstances', 'SatisfiableQ',
+ 'Saveable', 'SaveAutoDelete', 'SaveDefinitions', 'Save', 'Scaled',
+ 'SawtoothWave', 'Scale', 'ScalingFunctions', 'ScalingMatrix',
+ 'ScalingTransform', 'Scan', '$ScheduledTask', 'ScheduledTasks',
+ 'ScheduledTaskObject', 'SchurDecomposition', 'ScientificForm',
+ 'ScreenRectangle', 'ScreenStyleEnvironment', '$ScriptCommandLine',
+ 'ScriptBaselineShifts', 'ScriptLevel', 'ScriptMinSize', 'Sech',
+ 'ScriptSizeMultipliers', 'Scrollbars', 'ScrollingOptions', 'Share',
+ 'ScrollPosition', 'SechDistribution', 'SectorChart3D', 'Select',
+ 'SectorChart', 'SectorOrigin', 'SectorSpacing', 'SeedRandom',
+ 'Selectable', 'SelectComponents', 'SelectedNotebook', 'SendMail',
+ 'SelectionAnimate', 'SelectionCreateCell', 'SelectionEvaluate',
+ 'SelectionEvaluateCreateCell', 'SelectionMove', 'SelfLoopStyle',
+ 'SemialgebraicComponentInstances', 'SequenceAlignment', 'Sequence',
+ 'SequenceForm', 'SequenceHold', 'SeriesCoefficient', 'SeriesData',
+ 'Series', '$SessionID', 'SessionTime', 'SetAccuracy', 'SetDelayed',
+ 'SetAlphaChannel', 'SetAttributes', 'SetDirectory', 'SetFileDate',
+ 'SetOptions', 'SetPrecision', 'SetProperty', 'SetSelectedNotebook',
+ 'SetSharedFunction', 'SetSharedVariable', 'SetStreamPosition',
+ 'SetSystemOptions', 'SetterBar', 'Setter', 'Setting', 'Shading',
+ 'Shallow', 'ShannonWavelet', 'ShapiroWilkTest', '$SharedFunctions',
+ '$SharedVariables', 'Sharpen', 'ShearingMatrix', 'ShortDownArrow',
+ 'ShearingTransform', 'ShortestMatch', 'Shortest', 'ShortLeftArrow',
+ 'ShortestPathFunction', 'Short', 'ShortRightArrow', 'ShortUpArrow',
+ 'ShowAutoStyles', 'ShowCellBracket', 'ShowCellLabel', 'Show',
+ 'ShowCellTags', 'ShowClosedCellArea', 'ShowContents', 'Signature',
+ 'ShowCursorTracker', 'ShowGroupOpener', 'ShowPageBreaks', 'Sign',
+ 'ShowSelection', 'ShowShortBoxForm', 'ShowSpecialCharacters',
+ 'ShowStringCharacters', 'ShrinkingDelay', 'SiegelTheta', 'Sinc',
+ 'SiegelTukeyTest', 'SignedRankTest', 'SignificanceLevel', 'Sinh',
+ 'SignPadding', 'SignTest', 'SimilarityRules', 'SimpleGraph',
+ 'SimpleGraphQ', 'Simplify', 'SinghMaddalaDistribution', 'Skeleton',
+ 'SingleLetterItalics', 'SingularValueDecomposition', 'SinIntegral',
+ 'SingularValueList', 'SingularValuePlot', 'SingularValues', 'Skip',
+ 'SinhIntegral', 'SixJSymbol', 'SkeletonTransform', 'Skewness',
+ 'SkellamDistribution', 'SkewNormalDistribution', 'Slider2D',
+ 'Slider', 'SlideView', 'Slot', 'SlotSequence', 'SmallCircle',
+ 'Smaller', 'Small', 'SmithWatermanSimilarity', 'SmoothHistogram3D',
+ 'SmoothDensityHistogram', 'SmoothHistogram', 'SolveAlways', 'Sort',
+ 'SmoothKernelDistribution', 'SokalSneathDissimilarity', 'Solve',
+ 'SortBy', '$SoundDisplayFunction', 'Sound', 'SoundNote', 'Spacer',
+ 'SoundVolume', 'Spacings', 'SpanAdjustments', 'SpanFromAbove',
+ 'SpanCharacterRounding', 'SpanFromBoth', 'SpanFromLeft', 'Span',
+ 'SpanLineThickness', 'SpanMaxSize', 'SpanMinSize', 'SpanSymmetric',
+ 'SparseArray', 'Speak', 'Specularity', 'SpellingCorrection',
+ 'SpellingDictionaries', 'SpellingDictionariesPath', 'Sphere',
+ 'SpellingOptions', 'SphericalBesselJ', 'SphericalBesselY', 'Split',
+ 'SphericalHankelH1', 'SphericalHankelH2', 'SphericalHarmonicY',
+ 'SphericalPlot3D', 'SphericalRegion', 'SpheroidalEigenvalue',
+ 'SpheroidalJoiningFactor', 'SpheroidalPS', 'SpheroidalPSPrime',
+ 'SpheroidalQS', 'SpheroidalQSPrime', 'SpheroidalRadialFactor',
+ 'SpheroidalS1', 'SpheroidalS1Prime', 'SpheroidalS2', 'Splice',
+ 'SpheroidalS2Prime', 'SplineClosed', 'SplineDegree', 'SplineKnots',
+ 'SplineWeights', 'SplitBy', 'SpokenString', 'SqrtBox', 'Sqrt',
+ 'SquaredEuclideanDistance', 'SquareFreeQ', 'SquareIntersection',
+ 'Square', 'SquaresR', 'SquareSubsetEqual', 'SquareSubset', 'Stack',
+ 'SquareSupersetEqual', 'SquareSuperset', 'SquareUnion', 'Star',
+ 'SquareWave', 'StabilityMargins', 'StabilityMarginsStyle', 'Stub',
+ 'StableDistribution', 'StackBegin', 'StackComplete', 'Standardize',
+ 'StackInhibit', 'StandardDeviationFilter', 'StandardDeviation',
+ 'StandardForm', 'StarGraph', 'StartingStepSize', 'StartOfLine',
+ 'StartOfString', 'StartProcess', 'StartScheduledTask', 'Streams',
+ 'StartupSound', 'StateFeedbackGains', 'StateOutputEstimator',
+ 'StateResponse', 'StateSpaceModel', 'StateSpaceRealization',
+ 'StateSpaceTransform', 'StationaryWaveletPacketTransform', 'Style',
+ 'StationaryWaveletTransform', 'StatusArea', 'StepMonitor', 'Table',
+ 'StieltjesGamma', 'StirlingS1', 'StirlingS2', 'StopScheduledTask',
+ 'StreamColorFunction', 'StreamColorFunctionScaling', 'StreamPlot',
+ 'StreamDensityPlot', 'StreamPoints', 'StreamPosition', 'String',
+ 'StreamScale', 'StreamStyle', 'StringCases', 'StringCount', 'Take',
+ 'StringDrop', 'StringExpression', 'StringFormat', 'StringForm',
+ 'StringFreeQ', 'StringInsert', 'StringJoin', 'StringLength',
+ 'StringMatchQ', 'StringPosition', 'StringQ', 'StringReplaceList',
+ 'StringReplace', 'StringReplacePart', 'StringReverse', 'StruveH',
+ 'StringSkeleton', 'StringSplit', 'StringTake', 'StringToStream',
+ 'StringTrim', 'StructuredSelection', 'StruveL', 'StyleBox', 'Tanh',
+ 'StudentTDistribution', 'StyleBoxAutoDelete', 'StyleData', 'Tally',
+ 'StyleDefinitions', 'StyleForm', 'StyleMenuListing', 'StylePrint',
+ 'StyleNameDialogSettings', 'StyleSheetPath', 'Subfactorial',
+ 'Subgraph', 'SubMinus', 'SubPlus', 'Subresultants', 'SubscriptBox',
+ 'SubscriptBoxOptions', 'Subscripted', 'Subscript', 'SubsetEqual',
+ 'Subset', 'Subsets', 'SubStar', 'SubsuperscriptBox', 'Subtract',
+ 'SubsuperscriptBoxOptions', 'Subsuperscript', 'SubtractFrom',
+ 'SucceedsEqual', 'Succeeds', 'SucceedsSlantEqual', 'SucceedsTilde',
+ 'SuchThat', 'SumConvergence', 'SuperDagger', 'SuperMinus', 'Text',
+ 'SuperPlus', 'SuperscriptBox', 'SuperscriptBoxOptions', 'Superset',
+ 'Superscript', 'SupersetEqual', 'SuperStar', 'SurfaceColor',
+ 'SurfaceGraphics', 'SurvivalDistribution', 'SurvivalFunction',
+ 'SuspendPacket', 'SuzukiDistribution', 'SuzukiGroupSuz', 'Switch',
+ 'SymbolName', 'Symbol', 'SymletWavelet', 'SymmetricGroup', 'Thick',
+ 'SymmetricMatrixQ', 'SymmetricPolynomial', 'SymmetricReduction',
+ 'SynchronousInitialization', 'SynchronousUpdating', 'SyntaxForm',
+ '$SyntaxHandler', 'SyntaxInformation', 'SyntaxLength', 'SyntaxQ',
+ 'SyntaxPacket', '$SystemCharacterEncoding', 'SystemDialogInput',
+ 'SystemHelpPath', '$SystemID', 'SystemInformation', '$System',
+ 'SystemOpen', 'SystemOptions', 'SystemsModelDelete', 'TabFilling',
+ 'SystemsModelDimensions', 'SystemsModelExtract', 'TableAlignments',
+ 'SystemsModelFeedbackConnect', 'SystemsModelLabels', 'TableDepth',
+ 'SystemsModelOrder', 'SystemsModelParallelConnect', 'TableForm',
+ 'SystemsModelSeriesConnect', 'SystemsModelStateFeedbackConnect',
+ '$SystemWordLength', 'TableDirections', 'TableHeadings', 'TabView',
+ 'TableSpacing', 'TabSpacings', 'TagBox', 'TaggingRules', 'TagSet',
+ 'TagSetDelayed', 'TagUnset', 'TakeWhile', 'TargetFunctions',
+ 'TautologyQ', '$TemporaryDirectory', 'Temporary', 'TensorRank',
+ '$TemporaryPrefix', 'TeXForm', 'TeXSave', 'TextAlignment', 'Thin',
+ 'TextCell', 'TextClipboardType', 'TextData', 'TextJustification',
+ 'TextPacket', 'TextRecognize', '$TextStyle', 'TextStyle', 'Thread',
+ 'TextureCoordinateFunction', 'TextureCoordinateScaling', 'Texture',
+ 'Therefore', 'Thickness', 'Thinning', 'ThompsonGroupTh', 'Through',
+ 'ThreeJSymbol', 'Threshold', 'Throw', 'Thumbnail', 'Ticks', 'Tiny',
+ 'TicksStyle', 'TildeEqual', 'TildeFullEqual', 'Tilde', '$TimedOut',
+ 'TildeTilde', 'TimeConstrained', 'TimeConstraint', 'TimesBy',
+ 'Times', '$TimeUnit', 'TimeUsed', 'TimeValue', '$TimeZone', 'Trig',
+ 'TimeZone', 'Timing', 'TitsGroupT', 'ToASCII', 'ToBoxes', 'ToDate',
+ 'ToCharacterCode', 'ToContinuousTimeModel', 'ToDiscreteTimeModel',
+ 'ToeplitzMatrix', 'ToExpression', 'ToFileName', 'Together', 'True',
+ 'TogglerBar', 'Toggler', 'ToHeldExpression', 'TokenWords', 'Total',
+ 'Tolerance', 'ToLowerCase', 'ToNumberField', 'TooltipDelay',
+ 'Tooltip', '$TopDirectory', 'TopHatTransform', 'TopologicalSort',
+ 'ToRadicals', 'ToRules', 'ToString', 'TotalVariationFilter',
+ 'TotalWidth', 'ToUpperCase', 'TraceAbove', 'TraceBackward', 'Tube',
+ 'TraceDepth', 'TraceDialog', 'TraceForward', 'Trace', 'TraceOff',
+ 'TraceOn', 'TraceOriginal', 'TracePrint', 'TraceScan', 'Translate',
+ 'TrackedSymbols', 'TradingChart', 'TraditionalForm', 'Transparent',
+ 'TraditionalFunctionNotation', 'TransferFunctionCancel', 'Trigger',
+ 'TransferFunctionExpand', 'TransferFunctionFactor', 'Transpose',
+ 'TransferFunctionModel', 'TransferFunctionPoles', 'TreeForm',
+ 'TransferFunctionZeros', 'TransformationFunction', 'TreeGraph',
+ 'TransformationFunctions', 'TransformationMatrix', 'TreeGraphQ',
+ 'TransformedDistribution', 'TranslationTransform', 'TreePlot',
+ 'TrendStyle', 'TriangleWave', 'TriangularDistribution', 'TrueQ',
+ 'TrigExpand', 'TrigFactorList', 'TrigFactor', 'TrigReduce', 'With',
+ 'TrigToExp', 'TrimmedMean', 'TruncatedDistribution', 'TTest',
+ 'TukeyLambdaDistribution', 'Tuples', 'TuranGraph', 'TuringMachine',
+ 'Uncompress', 'Undefined', 'UnderBar', 'Underflow', 'Underlined',
+ 'UnderoverscriptBox', 'UnderoverscriptBoxOptions', 'Underscript',
+ 'Underoverscript', 'UnderscriptBox', 'UnderscriptBoxOptions',
+ 'UndirectedEdge', 'UndirectedGraph', 'UndirectedGraphQ', 'Unequal',
+ 'Unevaluated', 'UniformDistribution', 'UniformGraphDistribution',
+ 'UniformSumDistribution', 'Uninstall', 'Union', 'UnionPlus',
+ 'Unique', 'UnitBox', 'Unitize', 'UnitStep', 'UnitTriangle', 'Word',
+ 'UnitVector', 'Unprotect', 'UnsameQ', 'UnsavedVariables', 'Unset',
+ 'UnsetShared', 'UpArrowBar', 'UpArrowDownArrow', 'UpArrow', 'Xnor',
+ 'UpdateInterval', 'Update', 'UpDownArrow', 'UpEquilibrium', 'Zeta',
+ 'UpperCaseQ', 'UpperLeftArrow', 'UpperRightArrow', 'UpSetDelayed',
+ 'UpperTriangularize', 'UpSet', 'UpTeeArrow', 'UpValues', '$Urgent',
+ '$UserAddOnsDirectory', '$UserBaseDirectory', '$UserName', 'Wedge',
+ '$UserDocumentsDirectory', 'UsingFrontEnd', 'ValidationLength',
+ 'ValueQ', 'Variables', 'VarianceEquivalenceTest', 'Variance',
+ 'VarianceEstimatorFunction', 'VarianceTest', 'VectorAngle',
+ 'VectorColorFunction', 'VectorColorFunctionScaling', 'VectorPlot',
+ 'VectorDensityPlot', 'VectorPlot3D', 'VectorPoints', 'VectorQ',
+ 'VectorScale', 'VectorStyle', 'Verbatim', 'VerifyConvergence',
+ 'VerifyTestAssumptions', '$Version', '$VersionNumber', 'VertexAdd',
+ 'VertexColors', 'VertexComponent', 'VertexCoordinateRules',
+ 'VertexCoordinates', 'VertexCount', 'VertexCoverQ', 'VertexDegree',
+ 'VertexDelete', 'VertexEccentricity', 'VertexInComponent', 'Which',
+ 'VertexInDegree', 'VertexIndex', 'VertexLabeling', 'VertexLabels',
+ 'VertexLabelStyle', 'VertexList', 'VertexNormals', 'VertexQ',
+ 'VertexOutComponent', 'VertexOutDegree', 'VertexRenderingFunction',
+ 'VertexReplace', 'VertexShapeFunction', 'VertexShape', 'ViewAngle',
+ 'VertexSize', 'VertexStyle', 'VertexTextureCoordinates', 'Visible',
+ 'VertexWeight', 'VerticalBar', 'VerticalSeparator', 'ViewCenter',
+ 'VerticalSlider', 'VerticalTilde', 'ViewMatrix', 'ViewPoint',
+ 'ViewRange', 'ViewVector', 'ViewVertical', 'VonMisesDistribution',
+ 'WaitAll', 'WaitNext', 'WakebyDistribution', 'WatershedComponents',
+ 'WalleniusHypergeometricDistribution', 'WaringYuleDistribution',
+ 'WatsonUSquareTest', 'WattsStrogatzGraphDistribution', 'WeberE',
+ 'WaveletBestBasis', 'WaveletFilterCoefficients', 'WaveletListPlot',
+ 'WaveletImagePlot', 'WaveletMapIndexed', 'WaveletMatrixPlot',
+ 'WaveletPhi', 'WaveletPsi', 'WaveletScale', 'WaveletScalogram',
+ 'WaveletThreshold', 'WeatherData', 'WeibullDistribution', 'While',
+ 'WeierstrassHalfPeriods', 'WeierstrassInvariants', 'WeierstrassP',
+ 'WeierstrassPPrime', 'WeierstrassSigma', 'WeierstrassZeta',
+ 'WeightedAdjacencyGraph', 'WeightedAdjacencyMatrix', 'Weights',
+ 'WeightedGraphQ', 'WheelGraph', 'White', 'WhitespaceCharacter',
+ 'Whitespace', 'WhittakerM', 'WhittakerW', 'WienerFilter', 'Write',
+ 'WignerD', 'WignerSemicircleDistribution', 'WindowClickSelect',
+ 'WindowElements', 'WindowFloating', 'WindowFrameElements', 'ZTest',
+ 'WindowFrame', 'WindowMargins', 'WindowMovable', 'WindowOpacity',
+ 'WindowSize', 'WindowStatusArea', 'WindowTitle', 'WindowToolbars',
+ 'WolframAlpha', 'WordBoundary', 'WordCharacter', 'WordData',
+ 'WordSearch', 'WordSeparators', 'WorkingPrecision', 'WriteString',
+ 'Wronskian', 'XMLElement', 'XMLObject', 'Yellow', 'ZernikeR',
+ 'YuleDissimilarity', 'ZeroTest', 'ZeroWidthTimes', 'ZetaZero',
+ 'ZipfDistribution', 'ZTransform'
+ )
+ ),
+ /* Most symbol combinations can be valid Wolfram operators */
+ 'SYMBOLS' => array(
+ '!', '@', '#', '$', '%', '&', '*', '-', '+', '=',
+ '^', '~', '|', '\\', '>', '<', ':', '?', '/'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => true /* Wolfram is a case sensitive language */
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'font-weight: bold;', /* make the system functions bold */
+ ),
+ 'COMMENTS' => array(
+ 'MULTI' => 'color: grey;',
+ 2 => 'color: grey;', /* nested comments are grey as well */
+ 3 => 'color: #000aa; font-weight: bold;' /* complex symbols */
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'background-color: #3cb371; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: green; font-weight: bold;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: grey; font-weight: bold;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: red;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #060;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #339933; font-weight: bold;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ /* online documentation for system functions */
+ 1 => 'http://reference.wolfram.com/language/ref/{FNAME}.html'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/xbasic.php b/platform/www/vendor/geshi/geshi/src/geshi/xbasic.php
new file mode 100644
index 0000000..c78a7b9
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/xbasic.php
@@ -0,0 +1,141 @@
+<?php
+/*************************************************************************************
+ * xbasic.php
+ * ----------
+ * Author: José Gabriel Moya Yangüela (josemoya@gmail.com)
+ * Copyright: (c) 2005 José Gabriel Moya Yangüela (http://aprenderadesaprender.6te.net)
+ * Release Version: 1.0.9.1
+ * Date Started: 2005/11/23
+ *
+ * XBasic language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * - Removed duplicate keywords
+ * - Tabs converted in spaces.
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'XBasic',
+ 'COMMENT_SINGLE' => array(1 => "'"),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'WHILE', 'UNTIL', 'TRUE', 'TO', 'THEN', 'SUB', 'STOP', 'STEP',
+ 'SELECT', 'RETURN', 'PROGRAM', 'NEXT', 'LOOP', 'IFZ',
+ 'IFT', 'IFF', 'IF', 'GOTO', 'GOSUB', 'FOR', 'FALSE', 'EXIT',
+ 'ENDIF', 'END', 'ELSE', 'DO', 'CASE', 'ALL'
+ ),
+ 2 => array(
+ 'XMAKE', 'XLONGAT', 'XLONG', 'WRITE', 'VOID', 'VERSION$', 'VERSION',
+ 'USHORTAT', 'USHORT', 'UNION', 'ULONGAT', 'ULONG', 'UCASE$',
+ 'UBYTEAT', 'UBYTE', 'UBOUND', 'TYPE','TRIM$', 'TAB', 'SWAP',
+ 'SUBADDRESS', 'SUBADDR', 'STUFF$', 'STRING', 'STRING$', 'STR$',
+ 'STATIC', 'SSHORTAT', 'SSHORT', 'SPACE$', 'SMAKE', 'SLONGAT', 'SLONG',
+ 'SIZE', 'SINGLEAT', 'SINGLE', 'SIGNED$', 'SIGN', 'SHELL', 'SHARED',
+ 'SGN', 'SFUNCTION', 'SET', 'SEEK', 'SCOMPLEX', 'SBYTEAT', 'SBYTE',
+ 'RTRIM$', 'ROTATER', 'ROTATEL', 'RJUST$', 'RINSTRI', 'RINSTR',
+ 'RINCHRI', 'RINCHR', 'RIGHT$', 'REDIM', 'READ', 'RCLIP$', 'QUIT',
+ 'PROGRAM$', 'PRINT', 'POF', 'OPEN', 'OCTO$', 'OCT$', 'NULL$', 'MIN',
+ 'MID$', 'MAX', 'MAKE', 'LTRIM$', 'LOF', 'LJUST$', 'LIBRARY', 'LEN',
+ 'LEFT$', 'LCLIP$', 'LCASE$', 'INTERNAL', 'INT', 'INSTRI', 'INSTR',
+ 'INLINE$', 'INFILE$', 'INCHRI', 'INCHR', 'INC', 'IMPORT', 'HIGH1',
+ 'HIGH0', 'HEXX$', 'HEX$', 'GOADDRESS', 'GOADDR', 'GMAKE', 'GLOW',
+ 'GIANTAT', 'GIANT', 'GHIGH', 'FUNCTION', 'FUNCADDRESS', 'FUNCADDR',
+ 'FORMAT$', 'FIX', 'EXTU', 'EXTS', 'EXTERNAL', 'ERROR', 'ERROR$',
+ 'EOF', 'DOUBLEAT', 'DOUBLE', 'DMAKE', 'DLOW', 'DIM', 'DHIGH',
+ 'DECLARE', 'DEC', 'DCOMPLEX', 'CSTRING$', 'CSIZE', 'CSIZE$', 'CLR',
+ 'CLOSE', 'CLEAR', 'CJUST$', 'CHR$', 'CFUNCTION', 'BITFIELD', 'BINB$',
+ 'BIN$', 'AUTOX', 'AUTOS', 'AUTO', 'ATTACH', 'ASC', 'ABS'
+ ),
+ 3 => array(
+ 'XOR', 'OR', 'NOT', 'MOD', 'AND'
+ ),
+ 4 => array(
+ 'TANH', 'TAN', 'SQRT', 'SINH', 'SIN', 'SECH', 'SEC', 'POWER',
+ 'LOG10', 'LOG', 'EXP10', 'EXP', 'CSCH', 'CSC', 'COTH', 'COT', 'COSH',
+ 'COS', 'ATANH', 'ATAN', 'ASINH', 'ASIN', 'ASECH', 'ASEC', 'ACSCH',
+ 'ACSC', 'ACOSH', 'ACOS'
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')', '[', ']', '!', '@', '%', '&', '*', '|', '/', '<', '>',
+ '=','+','-'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #00a1a1;font-weight: bold',
+ 2 => 'color: #000066;font-weight: bold',
+ 3 => 'color: #00a166;font-weight: bold',
+ 4 => 'color: #0066a1;font-weight: bold'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => 'http://www.xbasic.org',
+ 4 => 'http://www.xbasic.org'
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/xml.php b/platform/www/vendor/geshi/geshi/src/geshi/xml.php
new file mode 100644
index 0000000..6f12739
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/xml.php
@@ -0,0 +1,155 @@
+<?php
+/*************************************************************************************
+ * xml.php
+ * -------
+ * Author: Nigel McNie (nigel@geshi.org)
+ * Copyright: (c) 2004 Nigel McNie (http://qbnz.com/highlighter/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2004/09/01
+ *
+ * XML language file for GeSHi. Based on the idea/file by Christian Weiske
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2005/12/28 (1.0.2)
+ * - Removed escape character for strings
+ * 2004/11/27 (1.0.1)
+ * - Added support for multiple object splitters
+ * 2004/10/27 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2004/11/27)
+ * -------------------------
+ * * Check regexps work and correctly highlight XML stuff and nothing else
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'XML',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ ),
+ 'COMMENTS' => array(
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SCRIPT' => array(
+ -1 => 'color: #808080; font-style: italic;', // comments
+ 0 => 'color: #00bbdd;',
+ 1 => 'color: #ddbb00;',
+ 2 => 'color: #339933;',
+ 3 => 'color: #009900;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #000066;',
+ 1 => 'color: #000000; font-weight: bold;',
+ 2 => 'color: #000000; font-weight: bold;'
+ )
+ ),
+ 'URLS' => array(
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ 0 => array(//attribute names
+ GESHI_SEARCH => '([a-z_:][\w\-\.:]*)(=)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => '\\2'
+ ),
+ 1 => array(//Initial header line
+ GESHI_SEARCH => '(&lt;[\/?|(\?xml)]?[a-z_:][\w\-\.:]*(\??&gt;)?)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 2 => array(//Tag end markers
+ GESHI_SEARCH => '(([\/|\?])?&gt;)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => 'i',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_ALWAYS,
+ 'SCRIPT_DELIMITERS' => array(
+ -1 => array(
+ '<!--' => '-->'
+ ),
+ 0 => array(
+ '<!DOCTYPE' => '>'
+ ),
+ 1 => array(
+ '&' => ';'
+ ),
+ 2 => array(
+ '<![CDATA[' => ']]>'
+ ),
+ 3 => array(
+ '<' => '>'
+ )
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ -1 => false,
+ 0 => false,
+ 1 => false,
+ 2 => false,
+ 3 => true
+ ),
+ 'TAB_WIDTH' => 2,
+ 'PARSER_CONTROL' => array(
+ 'ENABLE_FLAGS' => array(
+ 'NUMBERS' => GESHI_NEVER
+ )
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/xojo.php b/platform/www/vendor/geshi/geshi/src/geshi/xojo.php
new file mode 100644
index 0000000..abd2525
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/xojo.php
@@ -0,0 +1,279 @@
+<?php
+/*************************************************************************************
+ * xojo.php
+ * --------
+ * Author: Dr Garry Pettet (contact@garrypettet.com)
+ * Copyright: (c) 2014 Dr Garry Pettet (http://garrypettet.com)
+ * Release Version: 1.0.9.1
+ * Date Started: 2014/10/19
+ *
+ * Xojo language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2014/10/19 (1.0.8.13)
+ * - First Release
+ *
+ * TODO (updated 2014/10/19)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array(
+ 'LANG_NAME' => 'Xojo',
+ 'COMMENT_SINGLE' => array(1 => "'", 2 => '//', 3 => 'rem'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'NUMBERS' => array(
+ 1 => GESHI_NUMBER_INT_BASIC | GESHI_NUMBER_INT_CSTYLE, // integers
+ 2 => GESHI_NUMBER_FLT_NONSCI // floating point numbers
+ ),
+ 'KEYWORDS' => array(
+ //Keywords
+ 1 => array(
+ 'AddHandler',
+ 'AddressOf',
+ 'Aggregates',
+ 'And',
+ 'Array',
+ 'As',
+ 'Assigns',
+ 'Attributes',
+ 'Break',
+ 'ByRef',
+ 'ByVal',
+ 'Call',
+ 'Case',
+ 'Catch',
+ 'Class',
+ 'Const',
+ 'Continue',
+ 'CType',
+ 'Declare',
+ 'Delegate',
+ 'Dim',
+ 'Do',
+ 'DownTo',
+ 'Each',
+ 'Else',
+ 'Elseif',
+ 'End',
+ 'Enum',
+ 'Event',
+ 'Exception',
+ 'Exit',
+ 'Extends',
+ 'False',
+ 'Finally',
+ 'For',
+ 'Function',
+ 'Global',
+ 'GoTo',
+ 'Handles',
+ 'If',
+ 'Implements',
+ 'In',
+ 'Inherits',
+ 'Inline68K',
+ 'Interface',
+ 'Is',
+ 'IsA',
+ 'Lib',
+ 'Loop',
+ 'Me',
+ 'Mod',
+ 'Module',
+ 'Namespace',
+ 'New',
+ 'Next',
+ 'Nil',
+ 'Not',
+ 'Object',
+ 'Of',
+ 'Optional',
+ 'Or',
+ 'ParamArray',
+ 'Private',
+ 'Property',
+ 'Protected',
+ 'Public',
+ 'Raise',
+ 'RaiseEvent',
+ 'Rect',
+ 'Redim',
+ 'RemoveHandler',
+ 'Return',
+ 'Select',
+ 'Self',
+ 'Shared',
+ 'Soft',
+ 'Static',
+ 'Step',
+ 'Sub',
+ 'Super',
+ 'Then',
+ 'To',
+ 'True',
+ 'Try',
+ 'Until',
+ 'Using',
+ 'Wend',
+ 'While',
+ 'With',
+ 'WeakAddressOf',
+ 'Xor'
+ ),
+ //Data Types
+ 2 => array(
+ 'Boolean',
+ 'CFStringRef',
+ 'CString',
+ 'Currency',
+ 'Double',
+ 'Int8',
+ 'Int16',
+ 'Int32',
+ 'Int64',
+ 'Integer',
+ 'OSType',
+ 'PString',
+ 'Ptr',
+ 'Short',
+ 'Single',
+ 'String',
+ 'Structure',
+ 'UInt8',
+ 'UInt16',
+ 'UInt32',
+ 'UInt64',
+ 'UShort',
+ 'WindowPtr',
+ 'WString',
+ 'XMLNodeType'
+ ),
+ //Compiler Directives
+ 3 => array(
+ '#Bad',
+ '#Else',
+ '#Endif',
+ '#If',
+ '#Pragma',
+ '#Tag'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '+',
+ '-',
+ '*',
+ '=',
+ '/',
+ '>',
+ '<',
+ '^',
+ '(',
+ ')',
+ '.'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000FF;', // keywords
+ 2 => 'color: #0000FF;', // primitive data types
+ 3 => 'color: #0000FF;', // compiler commands
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #7F0000;',
+ 2 => 'color: #7F0000;',
+ 3 => 'color: #7F0000;',
+ 'MULTI' => 'color: #7F0000;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #008080;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #6500FE;'
+ ),
+ 'NUMBERS' => array(
+ 1 => 'color: #326598;', // integers
+ 2 => 'color: #006532;', // floating point numbers
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #000000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'REGEXPS' => array(
+ 1 => 'color: #326598;', // &h hex numbers
+ 2 => 'color: #326598;', // &b hex numbers
+ 3 => 'color: #326598;', // &o hex numbers
+ ),
+ 'SCRIPT' => array()
+ ),
+ 'URLS' => array(
+ 1 => 'http://docs.xojo.com/index.php/{FNAMEU}',
+ 2 => 'http://docs.xojo.com/index.php/{FNAMEU}',
+ 3 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ 1 => array( // &h numbers
+ // search for &h, then any number of letters a-f or numbers 0-9
+ GESHI_SEARCH => '(&amp;h[0-9a-fA-F]*\b)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 2 => array( // &b numbers
+ // search for &b, then any number of 0-1 digits
+ GESHI_SEARCH => '(&amp;b[0-1]*\b)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ ),
+ 3 => array( // &o octal numbers
+ // search for &o, then any number of 0-7 digits
+ GESHI_SEARCH => '(&amp;o[0-7]*\b)',
+ GESHI_REPLACE => '\\1',
+ GESHI_MODIFIERS => '',
+ GESHI_BEFORE => '',
+ GESHI_AFTER => ''
+ )
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/xorg_conf.php b/platform/www/vendor/geshi/geshi/src/geshi/xorg_conf.php
new file mode 100644
index 0000000..b9280bb
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/xorg_conf.php
@@ -0,0 +1,122 @@
+<?php
+/*************************************************************************************
+ * xorg_conf.php
+ * ----------
+ * Author: Milian Wolff (mail@milianw.de)
+ * Copyright: (c) 2008 Milian Wolff (http://milianw.de)
+ * Release Version: 1.0.9.1
+ * Date Started: 2008/06/18
+ *
+ * xorg.conf language file for GeSHi.
+ *
+ * CHANGES
+ * -------
+ * 2008/06/18 (1.0.8)
+ * - Initial import
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'Xorg configuration',
+ 'COMMENT_SINGLE' => array(1 => '#'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ // sections
+ 1 => array(
+ 'Section', 'EndSection', 'SubSection', 'EndSubSection'
+ ),
+ 2 => array(
+ // see http://www.x.org/archive/X11R6.9.0/doc/html/xorg.conf.5.html
+ 'BiosBase', 'Black', 'Boardname', 'BusID', 'ChipID', 'ChipRev',
+ 'Chipset', 'ClockChip', 'Clocks', 'DacSpeed',
+ 'DefaultDepth', 'DefaultFbBpp', 'Depth', 'Device',
+ 'DisplaySize', 'Driver', 'FbBpp', 'Gamma',
+ 'HorizSync', 'IOBase', 'Identifier', 'InputDevice',
+ 'Load', 'MemBase', 'Mode', 'Modeline', 'Modelname',
+ 'Modes', 'Monitor', 'Option', 'Ramdac', 'RgbPath',
+ 'Screen', 'TextClockFreq', 'UseModes', 'VendorName',
+ 'VertRefresh', 'VideoAdaptor', 'VideoRam',
+ 'ViewPort', 'Virtual', 'Visual', 'Weight', 'White'
+ ),
+ 3 => array(
+ // some sub-keywords
+ // screen position
+ 'Above', 'Absolute', 'Below', 'LeftOf', 'Relative', 'RightOf',
+ // modes
+ 'DotClock', 'Flags', 'HSkew', 'HTimings', 'VScan', 'VTimings'
+ ),
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #b1b100;',
+ 2 => 'color: #990000;',
+ 3 => 'color: #550000;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #0000ff;',
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #cc66cc;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 4
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/xpp.php b/platform/www/vendor/geshi/geshi/src/geshi/xpp.php
new file mode 100644
index 0000000..0e57f4d
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/xpp.php
@@ -0,0 +1,434 @@
+<?php
+/*************************************************************************************
+ * xpp.php
+ * -------
+ * Author: Simon Butcher (simon@butcher.name)
+ * Copyright: (c) 2007 Simon Butcher (http://simon.butcher.name/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/02/27
+ *
+ * Axapta/Dynamics Ax X++ language file for GeSHi.
+ * For details, see <http://msdn.microsoft.com/en-us/library/aa867122.aspx>
+ *
+ * CHANGES
+ * -------
+ * 2007/02/28 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2007/02/27)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'X++',
+ 'COMMENT_SINGLE' => array(1 => '//'),
+ 'COMMENT_MULTI' => array('/*' => '*/'),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array( // Primitive types
+ 'void',
+ 'str',
+ 'real',
+ 'int64',
+ 'int',
+ 'date',
+ 'container',
+ 'boolean',
+ 'anytype'
+ ),
+ 2 => array( // Keywords
+ 'window',
+ 'while',
+ 'try',
+ 'true',
+ 'throw',
+ 'switch',
+ 'super',
+ 'static',
+ 'server',
+ 'right',
+ 'return',
+ 'retry',
+ 'public',
+ 'protected',
+ 'private',
+ 'print',
+ 'pause',
+ 'null',
+ 'new',
+ 'mod',
+ 'left',
+ 'interface',
+ 'implements',
+ 'if',
+ 'for',
+ 'final',
+ 'false',
+ 'extends',
+ 'else',
+ 'edit',
+ 'do',
+ 'div',
+ 'display',
+ 'default',
+ 'continue',
+ 'client',
+ 'class',
+ 'changeCompany',
+ 'case',
+ 'breakpoint',
+ 'break',
+ 'at',
+ 'abstract'
+ ),
+ 3 => array( // Functions within the Axapta kernel
+ 'year',
+ 'wkofyr',
+ 'webwebpartstr',
+ 'webstaticfilestr',
+ 'websitetempstr',
+ 'websitedefstr',
+ 'webreportstr',
+ 'webpagedefstr',
+ 'weboutputcontentitemstr',
+ 'webmenustr',
+ 'webletitemstr',
+ 'webformstr',
+ 'webdisplaycontentitemstr',
+ 'webactionitemstr',
+ 'varstr',
+ 'utilmoyr',
+ 'uint2str',
+ 'typeof',
+ 'typeid',
+ 'trunc',
+ 'today',
+ 'timenow',
+ 'time2str',
+ 'term',
+ 'tanh',
+ 'tan',
+ 'tablestr',
+ 'tablestaticmethodstr',
+ 'tablepname',
+ 'tablenum',
+ 'tablename2id',
+ 'tablemethodstr',
+ 'tableid2pname',
+ 'tableid2name',
+ 'tablefieldgroupstr',
+ 'tablecollectionstr',
+ 'systemdateset',
+ 'systemdateget',
+ 'syd',
+ 'substr',
+ 'strupr',
+ 'strscan',
+ 'strrtrim',
+ 'strrep',
+ 'strrem',
+ 'strprompt',
+ 'strpoke',
+ 'strnfind',
+ 'strlwr',
+ 'strltrim',
+ 'strline',
+ 'strlen',
+ 'strkeep',
+ 'strins',
+ 'strfmt',
+ 'strfind',
+ 'strdel',
+ 'strcolseq',
+ 'strcmp',
+ 'stralpha',
+ 'str2time',
+ 'str2num',
+ 'str2int64',
+ 'str2int',
+ 'str2guid',
+ 'str2enum',
+ 'str2date',
+ 'staticmethodstr',
+ 'sln',
+ 'sleep',
+ 'sinh',
+ 'sin',
+ 'setprefix',
+ 'sessionid',
+ 'securitykeystr',
+ 'securitykeynum',
+ 'runbuf',
+ 'runas',
+ 'round',
+ 'resourcestr',
+ 'reportstr',
+ 'refprintall',
+ 'rate',
+ 'querystr',
+ 'pv',
+ 'pt',
+ 'prmisdefault',
+ 'primoyr',
+ 'prevyr',
+ 'prevqtr',
+ 'prevmth',
+ 'power',
+ 'pmt',
+ 'num2str',
+ 'num2date',
+ 'num2char',
+ 'nextyr',
+ 'nextqtr',
+ 'nextmth',
+ 'newguid',
+ 'mthofyr',
+ 'mthname',
+ 'mkdate',
+ 'minint',
+ 'min',
+ 'methodstr',
+ 'menustr',
+ 'menuitemoutputstr',
+ 'menuitemdisplaystr',
+ 'menuitemactionstr',
+ 'maxint',
+ 'maxdate',
+ 'max',
+ 'match',
+ 'logn',
+ 'log10',
+ 'literalstr',
+ 'licensecodestr',
+ 'licensecodenum',
+ 'intvnorm',
+ 'intvno',
+ 'intvname',
+ 'intvmax',
+ 'int64str',
+ 'indexstr',
+ 'indexnum',
+ 'indexname2id',
+ 'indexid2name',
+ 'idg',
+ 'identifierstr',
+ 'helpfilestr',
+ 'helpdevstr',
+ 'helpapplstr',
+ 'guid2str',
+ 'getprefix',
+ 'getCurrentUTCTime',
+ 'fv',
+ 'funcname',
+ 'frac',
+ 'formstr',
+ 'fieldstr',
+ 'fieldpname',
+ 'fieldnum',
+ 'fieldname2id',
+ 'fieldid2pname',
+ 'fieldid2name',
+ 'extendedTypeStr',
+ 'extendedTypeNum',
+ 'exp10',
+ 'exp',
+ 'evalbuf',
+ 'enumstr',
+ 'enumnum',
+ 'enumcnt',
+ 'enum2str',
+ 'endmth',
+ 'dimof',
+ 'dg',
+ 'decround',
+ 'ddb',
+ 'dayofyr',
+ 'dayofwk',
+ 'dayofmth',
+ 'dayname',
+ 'date2str',
+ 'date2num',
+ 'curuserid',
+ 'curext',
+ 'cterm',
+ 'cosh',
+ 'cos',
+ 'corrflagset',
+ 'corrflagget',
+ 'convertUTCTimeToLocalTime',
+ 'convertUTCDateToLocalDate',
+ 'conpoke',
+ 'conpeek',
+ 'connull',
+ 'conlen',
+ 'conins',
+ 'confind',
+ 'configurationkeystr',
+ 'configurationkeynum',
+ 'condel',
+ 'classstr',
+ 'classnum',
+ 'classidget',
+ 'char2num',
+ 'beep',
+ 'atan',
+ 'asin',
+ 'ascii2ansi',
+ 'any2str',
+ 'any2real',
+ 'any2int64',
+ 'any2int',
+ 'any2guid',
+ 'any2enum',
+ 'any2date',
+ 'ansi2ascii',
+ 'acos',
+ 'abs'
+ ),
+ 4 => array( // X++ SQL stuff
+ 'where',
+ 'update_recordset',
+ 'ttsCommit',
+ 'ttsBegin',
+ 'ttsAbort',
+ 'sum',
+ 'setting',
+ 'select',
+ 'reverse',
+ 'pessimisticLock',
+ 'outer',
+ 'order by',
+ 'optimisticLock',
+ 'notExists',
+ 'noFetch',
+ 'next',
+ 'minof',
+ 'maxof',
+ 'like',
+ 'join',
+ 'insert_recordset',
+ 'index hint',
+ 'index',
+ 'group by',
+ 'from',
+ 'forUpdate',
+ 'forceSelectOrder',
+ 'forcePlaceholders',
+ 'forceNestedLoop',
+ 'forceLiterals',
+ 'flush',
+ 'firstOnly',
+ 'firstFast',
+ 'exists',
+ 'desc',
+ 'delete_from',
+ 'count',
+ 'avg',
+ 'asc'
+ )
+ ),
+ 'SYMBOLS' => array( // X++ symbols
+ '!',
+ '&',
+ '(',
+ ')',
+ '*',
+ '^',
+ '|',
+ '~',
+ '+',
+ ',',
+ '-',
+ '/',
+ ':',
+ '<',
+ '=',
+ '>',
+ '?',
+ '[',
+ ']',
+ '{',
+ '}'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #0000ff;',
+ 4 => 'color: #0000ff;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #007f00;',
+ 'MULTI' => 'color: #007f00; font-style: italic;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #ff0000;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #000000;'
+ ),
+ 'METHODS' => array(
+ 1 => 'color: #000000;',
+ 2 => 'color: #000000;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #00007f;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.',
+ 2 => '::'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/yaml.php b/platform/www/vendor/geshi/geshi/src/geshi/yaml.php
new file mode 100644
index 0000000..e423717
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/yaml.php
@@ -0,0 +1,149 @@
+<?php
+/*************************************************************************************
+ * yaml.php
+ * --------
+ * Author: Josh Ventura (JoshV10@gmail.com)
+ * Copyright: (c) 2010 Josh Ventura
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/12/14
+ *
+ * YAML language file for GeSHi.
+ *
+ * YAML gets hairy sometimes. If anything needs fixed, drop me an email and
+ * I'll probably spit up on it. This is, in general, not a long format.
+ *
+ * CHANGES
+ * ---------
+ * 2010/12/14
+ * - Started project in rage over GML support but not YAML support. WTFH?
+ * 2010/12/15
+ * - Submitted to Ben.
+ *
+ * TODO (not updated since release)
+ * ----------------------------------
+ * - Field testing and necessary corrections: this grammar file is usable, but not
+ * completely accurate. There are, in fact, multiple cases in which it will mess
+ * up, and some of it may need moved around. It is the most temperamental parser
+ * I have ever associated my name with. Points of interest follow:
+ * * Improvised support for | and >: since PHP offers no variable-width lookbehind,
+ * these blocks will still be highlighted even when commented out. As it happens,
+ * any line ending with | or > could result in the unintentional highlighting of
+ * all remaining lines in the file, just because I couldn't check for this regex
+ * as a lookbehind: '/:(\s+)(!!(\w+)(\s+))?/'
+ * If there is a workaround for that, it needs implemented.
+ * * I may be missing some operators. I deliberately omitted inline array notation
+ * as, in general, it's ugly and tends to conflict with plain-text. Ensuring all
+ * highlighted list delimiters are not plain text would be as simple as checking
+ * that they follow a colon directly. Alas, without variable-length lookbehinds,
+ * if there is a way to do so in GeSHi I am unaware of it.
+ * * I kind of whored the comment regexp array. It seemed like a safe bet, so it's
+ * where I crammed everything. Some of it may need moved elsewhere for neatness.
+ * * The !!typename highlight needs not to interfere with ": |" and ": >": Pairing
+ * key: !!type | value is perfectly legal, but again due to lookbehind issues, I
+ * can't add a case for that. Also, it is likely that multiple spaces can be put
+ * between the colon and pipe symbol, which would also break it.
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'YAML',
+ 'COMMENT_SINGLE' => array(),
+ 'COMMENT_MULTI' => array(),
+ //Keys
+ 'COMMENT_REGEXP' => array( // ENTRY ZERO SHOULD CHECK FOR (\n(\s*)([^#%]+?):(\s+)(!!(\w+)(\s+))?) AS A LOOKBEHIND, BUT IT CAN'T.
+ 0 => '/(?<=\s[\|>]\n)(\s+)(.*)((?=[\n$])(([\n^](\1(.*)|(?=[\n$])))*)|$)/', // Pipe blocks and > blocks.
+ 1 => '/#(.*)/', // Blue # comments
+ 2 => '/%(.*)/', // Red % comments
+ 3 => '/(^|\n)([^#%^\n]+?)(?=: )/', // Key-value names
+ 4 => '/(^|\n)([^#%^\n]+?)(?=:\n)/',// Key-group names
+ 5 => '/(?<=^---)(\s*)!(\S+)/', // Comments after ---
+ 6 => '/(?<=: )(\s*)\&(\S+)/', // References
+ 7 => '/(?<=: )(\s*)\*(\S+)/', // Dereferences
+ 8 => '/!!(\w+)/', // Types
+ //9 => '/(?<=\n)(\s*)-(?!-)/', // List items: This needs to search within comments 3 and 4, but I don't know how.
+ ),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '',
+ 'NUMBERS' => array(),
+ 'KEYWORDS' => array(
+ 1 => array(
+ 'all','any','none', "yes", "no"
+ ),
+ ),
+ 'SYMBOLS' => array(
+ 1 => array('---', '...'),
+ 2 => array(': ', ">\n", "|\n", '<<:', ":\n") // It'd be nice if I could specify that the colon must
+ // follow comment 3 or 4 to be considered, and the > and |
+ // must follow such a colon.
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'font-weight: bold;'
+ ),
+ 'COMMENTS' => array(
+ 0 => 'color: #303050;background-color: #F5F5F5',
+ 1 => 'color: blue;',
+ 2 => 'font-weight: bold; color: red;',
+ 3 => 'color: green;',
+ 4 => 'color: #007F45;',
+ 5 => 'color: #7f7fFF;',
+ 6 => 'color: #FF7000;',
+ 7 => 'color: #FF45C0;',
+ 8 => 'font-weight: bold; color: #005F5F;',
+ //9 => 'font-weight: bold; color: #000000;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ ),
+ 'BRACKETS' => array(
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #CF00CF;'
+ ),
+ 'NUMBERS' => array(
+ // 0 => 'color: #33f;' // Don't highlight numbers, really...
+ ),
+ 'METHODS' => array(
+ 1 => '',
+ 2 => ''
+ ),
+ 'SYMBOLS' => array(
+ 1 => 'color: cyan;',
+ 2 => 'font-weight: bold; color: brown;'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'SCRIPT' => array(
+ 0 => ''
+ )
+ ),
+ 'URLS' => array(1 => ''),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(),
+ 'REGEXPS' => array(),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(),
+ 'HIGHLIGHT_STRICT_BLOCK' => array()
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/z80.php b/platform/www/vendor/geshi/geshi/src/geshi/z80.php
new file mode 100644
index 0000000..d934933
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/z80.php
@@ -0,0 +1,142 @@
+<?php
+/*************************************************************************************
+ * z80.php
+ * -------
+ * Author: Benny Baumann (BenBE@omorphia.de)
+ * Copyright: (c) 2007-2008 Benny Baumann (http://www.omorphia.de/)
+ * Release Version: 1.0.9.1
+ * Date Started: 2007/02/06
+ *
+ * ZiLOG Z80 Assembler language file for GeSHi.
+ * Syntax definition as commonly used with table assembler TASM32
+ * This file will contain some undocumented opcodes.
+ *
+ * CHANGES
+ * -------
+ * 2008/05/23 (1.0.7.22)
+ * - Added description of extra language features (SF#1970248)
+ * 2007/06/03 (1.0.1)
+ * - Fixed two typos in the language file
+ * 2007/02/06 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2007/02/06)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ZiLOG Z80 Assembler',
+ 'COMMENT_SINGLE' => array(1 => ';'),
+ 'COMMENT_MULTI' => array(),
+ 'CASE_KEYWORDS' => GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array("'", '"'),
+ 'ESCAPE_CHAR' => '',
+ 'KEYWORDS' => array(
+ /*CPU*/
+ 1 => array(
+ 'adc','add','and','bit','call','ccf','cp','cpd','cpdr','cpir','cpi',
+ 'cpl','daa','dec','di','djnz','ei','ex','exx','halt','im','in',
+ 'in0','inc','ind','indr','inir','ini','jp','jr','ld','ldd','lddr',
+ 'ldir','ldi','mlt','neg','nop','or','otdm','otdmr','otdr','otim',
+ 'otimr','otir','out','out0','outd','outi','pop','push','res','ret',
+ 'reti','retn','rl','rla','rlc','rlca','rld','rr','rra','rrc','rrca',
+ 'rrd','rst','sbc','scf','set','sla','sl1','sll','slp','sra','srl',
+ 'sub','tst','tstio','xor'
+ ),
+ /*registers*/
+ 2 => array(
+ 'a','b','c','d','e','h','l',
+ 'af','bc','de','hl','ix','iy','sp',
+ 'af\'','ixh','ixl','iyh','iyl'
+ ),
+ /*Directive*/
+ 3 => array(
+ '#define','#endif','#else','#ifdef','#ifndef','#include','#undef',
+ '.db','.dd','.df','.dq','.dt','.dw','.end','.org','equ'
+ ),
+ ),
+ 'SYMBOLS' => array(
+ '[', ']', '(', ')', '?', '+', '-', '*', '/', '%', '$'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #0000ff; font-weight:bold;',
+ 2 => 'color: #0000ff;',
+ 3 => 'color: #46aa03; font-weight:bold;'
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #adadad; font-style: italic;',
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099; font-weight: bold;'
+ ),
+ 'BRACKETS' => array(
+ 0 => 'color: #0000ff;'
+ ),
+ 'STRINGS' => array(
+ 0 => 'color: #7f007f;'
+ ),
+ 'NUMBERS' => array(
+ 0 => 'color: #dd22dd;'
+ ),
+ 'METHODS' => array(
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #008000;'
+ ),
+ 'REGEXPS' => array(
+ 0 => 'color: #22bbff;',
+ 1 => 'color: #22bbff;',
+ 2 => 'color: #993333;'
+ ),
+ 'SCRIPT' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => ''
+ ),
+ 'OOLANG' => false,
+ 'OBJECT_SPLITTERS' => array(
+ ),
+ 'REGEXPS' => array(
+ //Hex numbers
+ 0 => '0[0-9a-fA-F]{1,32}[hH]',
+ //Binary numbers
+ 1 => '\%[01]{1,64}|[01]{1,64}[bB]?(?![^<]*>)',
+ //Labels
+ 2 => '^[_a-zA-Z][_a-zA-Z0-9]?\:'
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ ),
+ 'TAB_WIDTH' => 8
+);
diff --git a/platform/www/vendor/geshi/geshi/src/geshi/zxbasic.php b/platform/www/vendor/geshi/geshi/src/geshi/zxbasic.php
new file mode 100644
index 0000000..ec90e79
--- /dev/null
+++ b/platform/www/vendor/geshi/geshi/src/geshi/zxbasic.php
@@ -0,0 +1,148 @@
+<?php
+/*************************************************************************************
+ * zxbasic.php
+ * -------------
+ * Author: Jose Rodriguez (a.k.a. Boriel)
+ * Based on Copyright: (c) 2005 Roberto Rossi (http://rsoftware.altervista.org) Freebasic template
+ * Release Version: 1.0.9.1
+ * Date Started: 2010/06/19
+ *
+ * ZXBasic language file for GeSHi.
+ *
+ * More details at http://www.zxbasic.net/
+ *
+ * CHANGES
+ * -------
+ * 2010/06/19 (1.0.0)
+ * - First Release
+ *
+ * TODO (updated 2007/02/06)
+ * -------------------------
+ *
+ *************************************************************************************
+ *
+ * This file is part of GeSHi.
+ *
+ * GeSHi 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.
+ *
+ * GeSHi 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 GeSHi; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ ************************************************************************************/
+
+$language_data = array (
+ 'LANG_NAME' => 'ZXBasic',
+ 'COMMENT_SINGLE' => array(
+ 1 => "'",
+ 2 => '#',
+ 3 => 'REM'
+ ),
+ 'COMMENT_MULTI' => array("/'" => "'/"),
+ 'CASE_KEYWORDS' => GESHI_CAPS_UPPER, //GESHI_CAPS_NO_CHANGE,
+ 'QUOTEMARKS' => array('"'),
+ 'ESCAPE_CHAR' => '\\',
+ 'KEYWORDS' => array(
+ 1 => array(
+ "ASM", "BEEP", "BOLD", "BORDER", "BRIGHT", "ByRef", "ByVal", "CAST",
+ "CIRCLE", "CLS", "CONST", "CONTINUE", "DECLARE", "DIM", "DO",
+ "DRAW", "ELSE", "ELSEIF", "END", "EXIT", "FastCall", "FLASH", "FOR",
+ "FUNCTION", "GOTO", "GOSUB", "GO", "IF", "INK", "INVERSE", "ITALIC",
+ "LET", "LOAD", "LOOP", "NEXT", "OVER", "PAPER", "PAUSE", "PI",
+ "PLOT", "POKE", "PRINT", "RANDOMIZE", "REM", "RETURN", "SAVE",
+ "StdCall", "Sub", "THEN", "TO", "UNTIL", "VERIFY", "WEND", "WHILE",
+ ),
+
+ // types
+ 2 => array(
+ 'byte', 'ubyte', 'integer', 'uinteger', 'long', 'ulong', 'fixed',
+ 'float', 'string'
+ ),
+
+ // Functions
+ 3 => array(
+ "ABS", "ACS", "ASN", "ATN", "CHR", "CODE", "COS", "CSRLIN", "EXP",
+ "HEX", "HEX16", "INKEY", "INT", "LEN", "LN", "PEEK", "POS", "RND",
+ "SCREEN$", "SGN", "SIN", "SQR", "STR", "TAN", "VAL",
+ ),
+
+ // Operators and modifiers
+ 4 => array(
+ "AT", "AS", "AND", "MOD", "NOT", "OR", "SHL", "SHR", "STEP", "XOR"
+ )
+ ),
+ 'SYMBOLS' => array(
+ '(', ')'
+ ),
+ 'CASE_SENSITIVE' => array(
+ GESHI_COMMENTS => false,
+ 1 => false,
+ 2 => false,
+ 3 => false,
+ 4 => false
+ ),
+ 'STYLES' => array(
+ 'KEYWORDS' => array(
+ 1 => 'color: #000080; font-weight: bold;', // Commands
+ 2 => 'color: #800080; font-weight: bold;', // Types
+ 3 => 'color: #006000; font-weight: bold;', // Functions
+ 4 => 'color: #801010; font-weight: bold;' // Operators and Modifiers
+ ),
+ 'COMMENTS' => array(
+ 1 => 'color: #808080; font-style: italic;',
+ 2 => 'color: #339933;',
+ 3 => 'color: #808080; font-style: italic;',
+ 'MULTI' => 'color: #808080; font-style: italic;'
+ ),
+ 'BRACKETS' => array(
+ //0 => 'color: #66cc66;'
+ 0 => 'color: #007676;'
+ ),
+ 'STRINGS' => array(
+ //0 => 'color: #ff0000;'
+ 0 => 'color: #A00000; font-style: italic;'
+ ),
+ 'NUMBERS' => array(
+ //0 => 'color: #cc66cc;'
+ 0 => 'color: #b05103;'// font-weight: bold;'
+ ),
+ 'METHODS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'SYMBOLS' => array(
+ 0 => 'color: #66cc66;'
+ ),
+ 'ESCAPE_CHAR' => array(
+ 0 => 'color: #000099;'
+ ),
+ 'SCRIPT' => array(
+ ),
+ 'REGEXPS' => array(
+ )
+ ),
+ 'URLS' => array(
+ 1 => '',
+ 2 => '',
+ 3 => '',
+ 4 => ''
+ ),
+ 'OOLANG' => true,
+ 'OBJECT_SPLITTERS' => array(
+ 1 => '.'
+ ),
+ 'REGEXPS' => array(
+ ),
+ 'STRICT_MODE_APPLIES' => GESHI_NEVER,
+ 'SCRIPT_DELIMITERS' => array(
+ ),
+ 'HIGHLIGHT_STRICT_BLOCK' => array(
+ )
+);
diff --git a/platform/www/vendor/marcusschwarz/lesserphp/HISTORY.md b/platform/www/vendor/marcusschwarz/lesserphp/HISTORY.md
new file mode 100644
index 0000000..4a55d82
--- /dev/null
+++ b/platform/www/vendor/marcusschwarz/lesserphp/HISTORY.md
@@ -0,0 +1,34 @@
+# lesserphp v0.5.4
+
+Originally written by Leaf Corcoran, obviously abandoned circa 2014
+https://github.com/leafo/lessphp
+
+Last version provided by Leaf was 0.5.0
+
+### v.0.5.4
+* 2020-01-19: added 7.4 support to travis and removed antique php versions (@phy25)
+* 2020-01-19: fixed wrong array access in lib_luma
+* 2020-01-19: removed HHVM profile from travis. HHVM support is now broken anyway
+
+### v.0.5.1
+* 2016-09-30: renaming it to lesserphp for easier distinction
+* 2016-09-30: applying some pull requests of the origin repository
+ * https://github.com/leafo/lessphp/pull/584
+ * https://github.com/leafo/lessphp/pull/607
+ * https://github.com/leafo/lessphp/pull/619
+* 2016-09-29: applying some pull requests of the origin repository
+ * https://github.com/leafo/lessphp/pull/590
+ * https://github.com/leafo/lessphp/pull/523
+ * https://github.com/leafo/lessphp/pull/540
+ * https://github.com/leafo/lessphp/pull/564
+ * https://github.com/leafo/lessphp/pull/566
+* 2016-09-26: applying some pull requests of the origin repository
+ * https://github.com/leafo/lessphp/pull/592
+ * https://github.com/leafo/lessphp/pull/601
+ * https://github.com/leafo/lessphp/pull/603
+ * https://github.com/leafo/lessphp/pull/604
+ * https://github.com/leafo/lessphp/pull/605
+ * https://github.com/leafo/lessphp/pull/610
+ * https://github.com/leafo/lessphp/pull/616
+* 2016-09-26: making it compatible with php7.x
+* 2016-09-26: Forking master from https://github.com/leafo/lessphp
diff --git a/platform/www/vendor/marcusschwarz/lesserphp/LICENSE b/platform/www/vendor/marcusschwarz/lesserphp/LICENSE
new file mode 100644
index 0000000..5290202
--- /dev/null
+++ b/platform/www/vendor/marcusschwarz/lesserphp/LICENSE
@@ -0,0 +1,661 @@
+For ease of distribution, lessphp 0.5.1 is under a dual license.
+You are free to pick which one suits your needs.
+
+
+
+
+MIT LICENSE
+
+
+
+
+Copyright (c) 2013 - 2015 Leaf Corcoran, http://leafo.net/lessphp
+Copyright (c) 2016 - Marcus Schwarz, https://www.maswaba.de
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+
+
+GPL VERSION 3
+
+
+
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
diff --git a/platform/www/vendor/marcusschwarz/lesserphp/README.md b/platform/www/vendor/marcusschwarz/lesserphp/README.md
new file mode 100644
index 0000000..8c26ab1
--- /dev/null
+++ b/platform/www/vendor/marcusschwarz/lesserphp/README.md
@@ -0,0 +1,97 @@
+[![Build Status](https://travis-ci.org/MarcusSchwarz/lesserphp.svg)](https://travis-ci.org/MarcusSchwarz/lesserphp)
+
+# lesserphp v0.5.4
+### <http://github.com/MarcusSchwarz/lesserphp>
+
+`lesserphp` is a compiler for LESS written in PHP. It is based on lessphp bei leafo.
+The documentation is great,
+so check it out: <http://leafo.net/lessphp/docs/>.
+
+Here's a quick tutorial:
+
+### How to use in your PHP project
+
+The only file required is `lessc.inc.php`, so copy that to your include directory.
+
+The typical flow of **lesserphp** is to create a new instance of `lessc`,
+configure it how you like, then tell it to compile something using one built in
+compile methods.
+
+The `compile` method compiles a string of LESS code to CSS.
+
+```php
+<?php
+require "lessc.inc.php";
+
+$less = new lessc;
+echo $less->compile(".block { padding: 3 + 4px }");
+```
+
+The `compileFile` method reads and compiles a file. It will either return the
+result or write it to the path specified by an optional second argument.
+
+```php
+<?php
+echo $less->compileFile("input.less");
+```
+
+The `checkedCompile` method is like `compileFile`, but it only compiles if the output
+file doesn't exist or it's older than the input file:
+
+```php
+<?php
+$less->checkedCompile("input.less", "output.css");
+```
+
+If there any problem compiling your code, an exception is thrown with a helpful message:
+
+```php
+<?php
+try {
+ $less->compile("invalid LESS } {");
+} catch (\Exception $e) {
+ echo "fatal error: " . $e->getMessage();
+}
+```
+
+The `lessc` object can be configured through an assortment of instance methods.
+Some possible configuration options include [changing the output format][1],
+[setting variables from PHP][2], and [controlling the preservation of
+comments][3], writing [custom functions][4] and much more. It's all described
+in [the documentation][0].
+
+
+ [0]: http://leafo.net/lessphp/docs/
+ [1]: http://leafo.net/lessphp/docs/#output_formatting
+ [2]: http://leafo.net/lessphp/docs/#setting_variables_from_php
+ [3]: http://leafo.net/lessphp/docs/#preserving_comments
+ [4]: http://leafo.net/lessphp/docs/#custom_functions
+
+
+### How to use from the command line
+
+An additional script has been included to use the compiler from the command
+line. In the simplest invocation, you specify an input file and the compiled
+css is written to standard out:
+
+ $ plessc input.less > output.css
+
+Using the -r flag, you can specify LESS code directly as an argument or, if
+the argument is left off, from standard in:
+
+ $ plessc -r "my less code here"
+
+Finally, by using the -w flag you can watch a specified input file and have it
+compile as needed to the output file:
+
+ $ plessc -w input-file output-file
+
+Errors from watch mode are written to standard out.
+
+The -f flag sets the [output formatter][1]. For example, to compress the
+output run this:
+
+ $ plessc -f=compressed myfile.less
+
+For more help, run `plessc --help`
+
diff --git a/platform/www/vendor/marcusschwarz/lesserphp/lessc.inc.php b/platform/www/vendor/marcusschwarz/lesserphp/lessc.inc.php
new file mode 100644
index 0000000..4764b28
--- /dev/null
+++ b/platform/www/vendor/marcusschwarz/lesserphp/lessc.inc.php
@@ -0,0 +1,4019 @@
+<?php
+
+/**
+ * lessphp v0.5.2
+ * http://leafo.net/lessphp
+ *
+ * LESS CSS compiler, adapted from http://lesscss.org
+ *
+ * Copyright 2013, Leaf Corcoran <leafot@gmail.com>
+ * Copyright 2016, Marcus Schwarz <github@maswaba.de>
+ * Licensed under MIT or GPLv3, see LICENSE
+ */
+
+
+/**
+ * The LESS compiler and parser.
+ *
+ * Converting LESS to CSS is a three stage process. The incoming file is parsed
+ * by `lessc_parser` into a syntax tree, then it is compiled into another tree
+ * representing the CSS structure by `lessc`. The CSS tree is fed into a
+ * formatter, like `lessc_formatter` which then outputs CSS as a string.
+ *
+ * During the first compile, all values are *reduced*, which means that their
+ * types are brought to the lowest form before being dump as strings. This
+ * handles math equations, variable dereferences, and the like.
+ *
+ * The `parse` function of `lessc` is the entry point.
+ *
+ * In summary:
+ *
+ * The `lessc` class creates an instance of the parser, feeds it LESS code,
+ * then transforms the resulting tree to a CSS tree. This class also holds the
+ * evaluation context, such as all available mixins and variables at any given
+ * time.
+ *
+ * The `lessc_parser` class is only concerned with parsing its input.
+ *
+ * The `lessc_formatter` takes a CSS tree, and dumps it to a formatted string,
+ * handling things like indentation.
+ */
+class lessc {
+ static public $VERSION = "v0.5.2";
+
+ static public $TRUE = array("keyword", "true");
+ static public $FALSE = array("keyword", "false");
+
+ protected $libFunctions = array();
+ protected $registeredVars = array();
+ protected $preserveComments = false;
+
+ public $vPrefix = '@'; // prefix of abstract properties
+ public $mPrefix = '$'; // prefix of abstract blocks
+ public $parentSelector = '&';
+
+ static public $lengths = array( "px", "m", "cm", "mm", "in", "pt", "pc" );
+ static public $times = array( "s", "ms" );
+ static public $angles = array( "rad", "deg", "grad", "turn" );
+
+ static public $lengths_to_base = array( 1, 3779.52755906, 37.79527559, 3.77952756, 96, 1.33333333, 16 );
+ public $importDisabled = false;
+ public $importDir = array();
+
+ protected $numberPrecision = null;
+
+ protected $allParsedFiles = array();
+
+ // set to the parser that generated the current line when compiling
+ // so we know how to create error messages
+ protected $sourceParser = null;
+ protected $sourceLoc = null;
+
+ static protected $nextImportId = 0; // uniquely identify imports
+
+ // attempts to find the path of an import url, returns null for css files
+ protected function findImport($url) {
+ foreach ((array)$this->importDir as $dir) {
+ $full = $dir.(substr($dir, -1) != '/' ? '/' : '').$url;
+ if ($this->fileExists($file = $full.'.less') || $this->fileExists($file = $full)) {
+ return $file;
+ }
+ }
+
+ return null;
+ }
+
+ protected function fileExists($name) {
+ return is_file($name);
+ }
+
+ static public function compressList($items, $delim) {
+ if (!isset($items[1]) && isset($items[0])) return $items[0];
+ else return array('list', $delim, $items);
+ }
+
+ static public function preg_quote($what) {
+ return preg_quote($what, '/');
+ }
+
+ protected function tryImport($importPath, $parentBlock, $out) {
+ if ($importPath[0] == "function" && $importPath[1] == "url") {
+ $importPath = $this->flattenList($importPath[2]);
+ }
+
+ $str = $this->coerceString($importPath);
+ if ($str === null) return false;
+
+ $url = $this->compileValue($this->lib_e($str));
+
+ // don't import if it ends in css
+ if (substr_compare($url, '.css', -4, 4) === 0) return false;
+
+ $realPath = $this->findImport($url);
+
+ if ($realPath === null) return false;
+
+ if ($this->importDisabled) {
+ return array(false, "/* import disabled */");
+ }
+
+ if (isset($this->allParsedFiles[realpath($realPath)])) {
+ return array(false, null);
+ }
+
+ $this->addParsedFile($realPath);
+ $parser = $this->makeParser($realPath);
+ $root = $parser->parse(file_get_contents($realPath));
+
+ // set the parents of all the block props
+ foreach ($root->props as $prop) {
+ if ($prop[0] == "block") {
+ $prop[1]->parent = $parentBlock;
+ }
+ }
+
+ // copy mixins into scope, set their parents
+ // bring blocks from import into current block
+ // TODO: need to mark the source parser these came from this file
+ foreach ($root->children as $childName => $child) {
+ if (isset($parentBlock->children[$childName])) {
+ $parentBlock->children[$childName] = array_merge(
+ $parentBlock->children[$childName],
+ $child);
+ } else {
+ $parentBlock->children[$childName] = $child;
+ }
+ }
+
+ $pi = pathinfo($realPath);
+ $dir = $pi["dirname"];
+
+ list($top, $bottom) = $this->sortProps($root->props, true);
+ $this->compileImportedProps($top, $parentBlock, $out, $parser, $dir);
+
+ return array(true, $bottom, $parser, $dir);
+ }
+
+ protected function compileImportedProps($props, $block, $out, $sourceParser, $importDir) {
+ $oldSourceParser = $this->sourceParser;
+
+ $oldImport = $this->importDir;
+
+ // TODO: this is because the importDir api is stupid
+ $this->importDir = (array)$this->importDir;
+ array_unshift($this->importDir, $importDir);
+
+ foreach ($props as $prop) {
+ $this->compileProp($prop, $block, $out);
+ }
+
+ $this->importDir = $oldImport;
+ $this->sourceParser = $oldSourceParser;
+ }
+
+ /**
+ * Recursively compiles a block.
+ *
+ * A block is analogous to a CSS block in most cases. A single LESS document
+ * is encapsulated in a block when parsed, but it does not have parent tags
+ * so all of it's children appear on the root level when compiled.
+ *
+ * Blocks are made up of props and children.
+ *
+ * Props are property instructions, array tuples which describe an action
+ * to be taken, eg. write a property, set a variable, mixin a block.
+ *
+ * The children of a block are just all the blocks that are defined within.
+ * This is used to look up mixins when performing a mixin.
+ *
+ * Compiling the block involves pushing a fresh environment on the stack,
+ * and iterating through the props, compiling each one.
+ *
+ * See lessc::compileProp()
+ *
+ */
+ protected function compileBlock($block) {
+ switch ($block->type) {
+ case "root":
+ $this->compileRoot($block);
+ break;
+ case null:
+ $this->compileCSSBlock($block);
+ break;
+ case "media":
+ $this->compileMedia($block);
+ break;
+ case "directive":
+ $name = "@" . $block->name;
+ if (!empty($block->value)) {
+ $name .= " " . $this->compileValue($this->reduce($block->value));
+ }
+
+ $this->compileNestedBlock($block, array($name));
+ break;
+ default:
+ $block->parser->throwError("unknown block type: $block->type\n", $block->count);
+ }
+ }
+
+ protected function compileCSSBlock($block) {
+ $env = $this->pushEnv();
+
+ $selectors = $this->compileSelectors($block->tags);
+ $env->selectors = $this->multiplySelectors($selectors);
+ $out = $this->makeOutputBlock(null, $env->selectors);
+
+ $this->scope->children[] = $out;
+ $this->compileProps($block, $out);
+
+ $block->scope = $env; // mixins carry scope with them!
+ $this->popEnv();
+ }
+
+ protected function compileMedia($media) {
+ $env = $this->pushEnv($media);
+ $parentScope = $this->mediaParent($this->scope);
+
+ $query = $this->compileMediaQuery($this->multiplyMedia($env));
+
+ $this->scope = $this->makeOutputBlock($media->type, array($query));
+ $parentScope->children[] = $this->scope;
+
+ $this->compileProps($media, $this->scope);
+
+ if (count($this->scope->lines) > 0) {
+ $orphanSelelectors = $this->findClosestSelectors();
+ if (!is_null($orphanSelelectors)) {
+ $orphan = $this->makeOutputBlock(null, $orphanSelelectors);
+ $orphan->lines = $this->scope->lines;
+ array_unshift($this->scope->children, $orphan);
+ $this->scope->lines = array();
+ }
+ }
+
+ $this->scope = $this->scope->parent;
+ $this->popEnv();
+ }
+
+ protected function mediaParent($scope) {
+ while (!empty($scope->parent)) {
+ if (!empty($scope->type) && $scope->type != "media") {
+ break;
+ }
+ $scope = $scope->parent;
+ }
+
+ return $scope;
+ }
+
+ protected function compileNestedBlock($block, $selectors) {
+ $this->pushEnv($block);
+ $this->scope = $this->makeOutputBlock($block->type, $selectors);
+ $this->scope->parent->children[] = $this->scope;
+
+ $this->compileProps($block, $this->scope);
+
+ $this->scope = $this->scope->parent;
+ $this->popEnv();
+ }
+
+ protected function compileRoot($root) {
+ $this->pushEnv();
+ $this->scope = $this->makeOutputBlock($root->type);
+ $this->compileProps($root, $this->scope);
+ $this->popEnv();
+ }
+
+ protected function compileProps($block, $out) {
+ foreach ($this->sortProps($block->props) as $prop) {
+ $this->compileProp($prop, $block, $out);
+ }
+ $out->lines = $this->deduplicate($out->lines);
+ }
+
+ /**
+ * Deduplicate lines in a block. Comments are not deduplicated. If a
+ * duplicate rule is detected, the comments immediately preceding each
+ * occurence are consolidated.
+ */
+ protected function deduplicate($lines) {
+ $unique = array();
+ $comments = array();
+
+ foreach($lines as $line) {
+ if (strpos($line, '/*') === 0) {
+ $comments[] = $line;
+ continue;
+ }
+ if (!in_array($line, $unique)) {
+ $unique[] = $line;
+ }
+ array_splice($unique, array_search($line, $unique), 0, $comments);
+ $comments = array();
+ }
+ return array_merge($unique, $comments);
+ }
+
+ protected function sortProps($props, $split = false) {
+ $vars = array();
+ $imports = array();
+ $other = array();
+ $stack = array();
+
+ foreach ($props as $prop) {
+ switch ($prop[0]) {
+ case "comment":
+ $stack[] = $prop;
+ break;
+ case "assign":
+ $stack[] = $prop;
+ if (isset($prop[1][0]) && $prop[1][0] == $this->vPrefix) {
+ $vars = array_merge($vars, $stack);
+ } else {
+ $other = array_merge($other, $stack);
+ }
+ $stack = array();
+ break;
+ case "import":
+ $id = self::$nextImportId++;
+ $prop[] = $id;
+ $stack[] = $prop;
+ $imports = array_merge($imports, $stack);
+ $other[] = array("import_mixin", $id);
+ $stack = array();
+ break;
+ default:
+ $stack[] = $prop;
+ $other = array_merge($other, $stack);
+ $stack = array();
+ break;
+ }
+ }
+ $other = array_merge($other, $stack);
+
+ if ($split) {
+ return array(array_merge($vars, $imports, $vars), $other);
+ } else {
+ return array_merge($vars, $imports, $vars, $other);
+ }
+ }
+
+ protected function compileMediaQuery($queries) {
+ $compiledQueries = array();
+ foreach ($queries as $query) {
+ $parts = array();
+ foreach ($query as $q) {
+ switch ($q[0]) {
+ case "mediaType":
+ $parts[] = implode(" ", array_slice($q, 1));
+ break;
+ case "mediaExp":
+ if (isset($q[2])) {
+ $parts[] = "($q[1]: " .
+ $this->compileValue($this->reduce($q[2])) . ")";
+ } else {
+ $parts[] = "($q[1])";
+ }
+ break;
+ case "variable":
+ $parts[] = $this->compileValue($this->reduce($q));
+ break;
+ }
+ }
+
+ if (count($parts) > 0) {
+ $compiledQueries[] = implode(" and ", $parts);
+ }
+ }
+
+ $out = "@media";
+ if (!empty($parts)) {
+ $out .= " " .
+ implode($this->formatter->selectorSeparator, $compiledQueries);
+ }
+ return $out;
+ }
+
+ protected function multiplyMedia($env, $childQueries = null) {
+ if (is_null($env) ||
+ !empty($env->block->type) && $env->block->type != "media")
+ {
+ return $childQueries;
+ }
+
+ // plain old block, skip
+ if (empty($env->block->type)) {
+ return $this->multiplyMedia($env->parent, $childQueries);
+ }
+
+ $out = array();
+ $queries = $env->block->queries;
+ if (is_null($childQueries)) {
+ $out = $queries;
+ } else {
+ foreach ($queries as $parent) {
+ foreach ($childQueries as $child) {
+ $out[] = array_merge($parent, $child);
+ }
+ }
+ }
+
+ return $this->multiplyMedia($env->parent, $out);
+ }
+
+ protected function expandParentSelectors(&$tag, $replace) {
+ $parts = explode("$&$", $tag);
+ $count = 0;
+ foreach ($parts as &$part) {
+ $part = str_replace($this->parentSelector, $replace, $part, $c);
+ $count += $c;
+ }
+ $tag = implode($this->parentSelector, $parts);
+ return $count;
+ }
+
+ protected function findClosestSelectors() {
+ $env = $this->env;
+ $selectors = null;
+ while ($env !== null) {
+ if (isset($env->selectors)) {
+ $selectors = $env->selectors;
+ break;
+ }
+ $env = $env->parent;
+ }
+
+ return $selectors;
+ }
+
+
+ // multiply $selectors against the nearest selectors in env
+ protected function multiplySelectors($selectors) {
+ // find parent selectors
+
+ $parentSelectors = $this->findClosestSelectors();
+ if (is_null($parentSelectors)) {
+ // kill parent reference in top level selector
+ foreach ($selectors as &$s) {
+ $this->expandParentSelectors($s, "");
+ }
+
+ return $selectors;
+ }
+
+ $out = array();
+ foreach ($parentSelectors as $parent) {
+ foreach ($selectors as $child) {
+ $count = $this->expandParentSelectors($child, $parent);
+
+ // don't prepend the parent tag if & was used
+ if ($count > 0) {
+ $out[] = trim($child);
+ } else {
+ $out[] = trim($parent . ' ' . $child);
+ }
+ }
+ }
+
+ return $out;
+ }
+
+ // reduces selector expressions
+ protected function compileSelectors($selectors) {
+ $out = array();
+
+ foreach ($selectors as $s) {
+ if (is_array($s)) {
+ list(, $value) = $s;
+ $out[] = trim($this->compileValue($this->reduce($value)));
+ } else {
+ $out[] = $s;
+ }
+ }
+
+ return $out;
+ }
+
+ protected function eq($left, $right) {
+ return $left == $right;
+ }
+
+ protected function patternMatch($block, $orderedArgs, $keywordArgs) {
+ // match the guards if it has them
+ // any one of the groups must have all its guards pass for a match
+ if (!empty($block->guards)) {
+ $groupPassed = false;
+ foreach ($block->guards as $guardGroup) {
+ foreach ($guardGroup as $guard) {
+ $this->pushEnv();
+ $this->zipSetArgs($block->args, $orderedArgs, $keywordArgs);
+
+ $negate = false;
+ if ($guard[0] == "negate") {
+ $guard = $guard[1];
+ $negate = true;
+ }
+
+ $passed = $this->reduce($guard) == self::$TRUE;
+ if ($negate) $passed = !$passed;
+
+ $this->popEnv();
+
+ if ($passed) {
+ $groupPassed = true;
+ } else {
+ $groupPassed = false;
+ break;
+ }
+ }
+
+ if ($groupPassed) break;
+ }
+
+ if (!$groupPassed) {
+ return false;
+ }
+ }
+
+ if (empty($block->args)) {
+ return $block->isVararg || empty($orderedArgs) && empty($keywordArgs);
+ }
+
+ $remainingArgs = $block->args;
+ if ($keywordArgs) {
+ $remainingArgs = array();
+ foreach ($block->args as $arg) {
+ if ($arg[0] == "arg" && isset($keywordArgs[$arg[1]])) {
+ continue;
+ }
+
+ $remainingArgs[] = $arg;
+ }
+ }
+
+ $i = -1; // no args
+ // try to match by arity or by argument literal
+ foreach ($remainingArgs as $i => $arg) {
+ switch ($arg[0]) {
+ case "lit":
+ if (empty($orderedArgs[$i]) || !$this->eq($arg[1], $orderedArgs[$i])) {
+ return false;
+ }
+ break;
+ case "arg":
+ // no arg and no default value
+ if (!isset($orderedArgs[$i]) && !isset($arg[2])) {
+ return false;
+ }
+ break;
+ case "rest":
+ $i--; // rest can be empty
+ break 2;
+ }
+ }
+
+ if ($block->isVararg) {
+ return true; // not having enough is handled above
+ } else {
+ $numMatched = $i + 1;
+ // greater than because default values always match
+ return $numMatched >= count($orderedArgs);
+ }
+ }
+
+ protected function patternMatchAll($blocks, $orderedArgs, $keywordArgs, $skip=array()) {
+ $matches = null;
+ foreach ($blocks as $block) {
+ // skip seen blocks that don't have arguments
+ if (isset($skip[$block->id]) && !isset($block->args)) {
+ continue;
+ }
+
+ if ($this->patternMatch($block, $orderedArgs, $keywordArgs)) {
+ $matches[] = $block;
+ }
+ }
+
+ return $matches;
+ }
+
+ // attempt to find blocks matched by path and args
+ protected function findBlocks($searchIn, $path, $orderedArgs, $keywordArgs, $seen=array()) {
+ if ($searchIn == null) return null;
+ if (isset($seen[$searchIn->id])) return null;
+ $seen[$searchIn->id] = true;
+
+ $name = $path[0];
+
+ if (isset($searchIn->children[$name])) {
+ $blocks = $searchIn->children[$name];
+ if (count($path) == 1) {
+ $matches = $this->patternMatchAll($blocks, $orderedArgs, $keywordArgs, $seen);
+ if (!empty($matches)) {
+ // This will return all blocks that match in the closest
+ // scope that has any matching block, like lessjs
+ return $matches;
+ }
+ } else {
+ $matches = array();
+ foreach ($blocks as $subBlock) {
+ $subMatches = $this->findBlocks($subBlock,
+ array_slice($path, 1), $orderedArgs, $keywordArgs, $seen);
+
+ if (!is_null($subMatches)) {
+ foreach ($subMatches as $sm) {
+ $matches[] = $sm;
+ }
+ }
+ }
+
+ return count($matches) > 0 ? $matches : null;
+ }
+ }
+ if ($searchIn->parent === $searchIn) return null;
+ return $this->findBlocks($searchIn->parent, $path, $orderedArgs, $keywordArgs, $seen);
+ }
+
+ // sets all argument names in $args to either the default value
+ // or the one passed in through $values
+ protected function zipSetArgs($args, $orderedValues, $keywordValues) {
+ $assignedValues = array();
+
+ $i = 0;
+ foreach ($args as $a) {
+ if ($a[0] == "arg") {
+ if (isset($keywordValues[$a[1]])) {
+ // has keyword arg
+ $value = $keywordValues[$a[1]];
+ } elseif (isset($orderedValues[$i])) {
+ // has ordered arg
+ $value = $orderedValues[$i];
+ $i++;
+ } elseif (isset($a[2])) {
+ // has default value
+ $value = $a[2];
+ } else {
+ $this->throwError("Failed to assign arg " . $a[1]);
+ $value = null; // :(
+ }
+
+ $value = $this->reduce($value);
+ $this->set($a[1], $value);
+ $assignedValues[] = $value;
+ } else {
+ // a lit
+ $i++;
+ }
+ }
+
+ // check for a rest
+ $last = end($args);
+ if ($last !== false && $last[0] === "rest") {
+ $rest = array_slice($orderedValues, count($args) - 1);
+ $this->set($last[1], $this->reduce(array("list", " ", $rest)));
+ }
+
+ // wow is this the only true use of PHP's + operator for arrays?
+ $this->env->arguments = $assignedValues + $orderedValues;
+ }
+
+ // compile a prop and update $lines or $blocks appropriately
+ protected function compileProp($prop, $block, $out) {
+ // set error position context
+ $this->sourceLoc = isset($prop[-1]) ? $prop[-1] : -1;
+
+ switch ($prop[0]) {
+ case 'assign':
+ list(, $name, $value) = $prop;
+ if ($name[0] == $this->vPrefix) {
+ $this->set($name, $value);
+ } else {
+ $out->lines[] = $this->formatter->property($name,
+ $this->compileValue($this->reduce($value)));
+ }
+ break;
+ case 'block':
+ list(, $child) = $prop;
+ $this->compileBlock($child);
+ break;
+ case 'ruleset':
+ case 'mixin':
+ list(, $path, $args, $suffix) = $prop;
+
+ $orderedArgs = array();
+ $keywordArgs = array();
+ foreach ((array)$args as $arg) {
+ $argval = null;
+ switch ($arg[0]) {
+ case "arg":
+ if (!isset($arg[2])) {
+ $orderedArgs[] = $this->reduce(array("variable", $arg[1]));
+ } else {
+ $keywordArgs[$arg[1]] = $this->reduce($arg[2]);
+ }
+ break;
+
+ case "lit":
+ $orderedArgs[] = $this->reduce($arg[1]);
+ break;
+ default:
+ $this->throwError("Unknown arg type: " . $arg[0]);
+ }
+ }
+
+ $mixins = $this->findBlocks($block, $path, $orderedArgs, $keywordArgs);
+
+ if ($mixins === null) {
+ $block->parser->throwError("{$prop[1][0]} is undefined", $block->count);
+ }
+
+ if(strpos($prop[1][0], "$") === 0) {
+ //Use Ruleset Logic - Only last element
+ $mixins = array(array_pop($mixins));
+ }
+
+ foreach ($mixins as $mixin) {
+ if ($mixin === $block && !$orderedArgs) {
+ continue;
+ }
+
+ $haveScope = false;
+ if (isset($mixin->parent->scope)) {
+ $haveScope = true;
+ $mixinParentEnv = $this->pushEnv();
+ $mixinParentEnv->storeParent = $mixin->parent->scope;
+ }
+
+ $haveArgs = false;
+ if (isset($mixin->args)) {
+ $haveArgs = true;
+ $this->pushEnv();
+ $this->zipSetArgs($mixin->args, $orderedArgs, $keywordArgs);
+ }
+
+ $oldParent = $mixin->parent;
+ if ($mixin != $block) $mixin->parent = $block;
+
+ foreach ($this->sortProps($mixin->props) as $subProp) {
+ if ($suffix !== null &&
+ $subProp[0] == "assign" &&
+ is_string($subProp[1]) &&
+ $subProp[1]{0} != $this->vPrefix)
+ {
+ $subProp[2] = array(
+ 'list', ' ',
+ array($subProp[2], array('keyword', $suffix))
+ );
+ }
+
+ $this->compileProp($subProp, $mixin, $out);
+ }
+
+ $mixin->parent = $oldParent;
+
+ if ($haveArgs) $this->popEnv();
+ if ($haveScope) $this->popEnv();
+ }
+
+ break;
+ case 'raw':
+ $out->lines[] = $prop[1];
+ break;
+ case "directive":
+ list(, $name, $value) = $prop;
+ $out->lines[] = "@$name " . $this->compileValue($this->reduce($value)).';';
+ break;
+ case "comment":
+ $out->lines[] = $prop[1];
+ break;
+ case "import";
+ list(, $importPath, $importId) = $prop;
+ $importPath = $this->reduce($importPath);
+
+ if (!isset($this->env->imports)) {
+ $this->env->imports = array();
+ }
+
+ $result = $this->tryImport($importPath, $block, $out);
+
+ $this->env->imports[$importId] = $result === false ?
+ array(false, "@import " . $this->compileValue($importPath).";") :
+ $result;
+
+ break;
+ case "import_mixin":
+ list(,$importId) = $prop;
+ $import = $this->env->imports[$importId];
+ if ($import[0] === false) {
+ if (isset($import[1])) {
+ $out->lines[] = $import[1];
+ }
+ } else {
+ list(, $bottom, $parser, $importDir) = $import;
+ $this->compileImportedProps($bottom, $block, $out, $parser, $importDir);
+ }
+
+ break;
+ default:
+ $block->parser->throwError("unknown op: {$prop[0]}\n", $block->count);
+ }
+ }
+
+
+ /**
+ * Compiles a primitive value into a CSS property value.
+ *
+ * Values in lessphp are typed by being wrapped in arrays, their format is
+ * typically:
+ *
+ * array(type, contents [, additional_contents]*)
+ *
+ * The input is expected to be reduced. This function will not work on
+ * things like expressions and variables.
+ */
+ public function compileValue($value) {
+ switch ($value[0]) {
+ case 'list':
+ // [1] - delimiter
+ // [2] - array of values
+ return implode($value[1], array_map(array($this, 'compileValue'), $value[2]));
+ case 'raw_color':
+ if (!empty($this->formatter->compressColors)) {
+ return $this->compileValue($this->coerceColor($value));
+ }
+ return $value[1];
+ case 'keyword':
+ // [1] - the keyword
+ return $value[1];
+ case 'number':
+ list(, $num, $unit) = $value;
+ // [1] - the number
+ // [2] - the unit
+ if ($this->numberPrecision !== null) {
+ $num = round($num, $this->numberPrecision);
+ }
+ return $num . $unit;
+ case 'string':
+ // [1] - contents of string (includes quotes)
+ list(, $delim, $content) = $value;
+ foreach ($content as &$part) {
+ if (is_array($part)) {
+ $part = $this->compileValue($part);
+ }
+ }
+ return $delim . implode($content) . $delim;
+ case 'color':
+ // [1] - red component (either number or a %)
+ // [2] - green component
+ // [3] - blue component
+ // [4] - optional alpha component
+ list(, $r, $g, $b) = $value;
+ $r = round($r);
+ $g = round($g);
+ $b = round($b);
+
+ if (count($value) == 5 && $value[4] != 1) { // rgba
+ return 'rgba('.$r.','.$g.','.$b.','.$value[4].')';
+ }
+
+ $h = sprintf("#%02x%02x%02x", $r, $g, $b);
+
+ if (!empty($this->formatter->compressColors)) {
+ // Converting hex color to short notation (e.g. #003399 to #039)
+ if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) {
+ $h = '#' . $h[1] . $h[3] . $h[5];
+ }
+ }
+
+ return $h;
+
+ case 'function':
+ list(, $name, $args) = $value;
+ return $name.'('.$this->compileValue($args).')';
+ default: // assumed to be unit
+ $this->throwError("unknown value type: $value[0]");
+ }
+ }
+
+ protected function lib_pow($args) {
+ list($base, $exp) = $this->assertArgs($args, 2, "pow");
+ return array( "number", pow($this->assertNumber($base), $this->assertNumber($exp)), $args[2][0][2] );
+ }
+
+ protected function lib_pi() {
+ return pi();
+ }
+
+ protected function lib_mod($args) {
+ list($a, $b) = $this->assertArgs($args, 2, "mod");
+ return array( "number", $this->assertNumber($a) % $this->assertNumber($b), $args[2][0][2] );
+ }
+
+ protected function lib_convert($args) {
+ list($value, $to) = $this->assertArgs($args, 2, "convert");
+
+ // If it's a keyword, grab the string version instead
+ if( is_array( $to ) && $to[0] == "keyword" )
+ $to = $to[1];
+
+ return $this->convert( $value, $to );
+ }
+
+ protected function lib_abs($num) {
+ return array( "number", abs($this->assertNumber($num)), $num[2] );
+ }
+
+ protected function lib_min($args) {
+ $values = $this->assertMinArgs($args, 1, "min");
+
+ $first_format = $values[0][2];
+
+ $min_index = 0;
+ $min_value = $values[0][1];
+
+ for( $a = 0; $a < sizeof( $values ); $a++ )
+ {
+ $converted = $this->convert( $values[$a], $first_format );
+
+ if( $converted[1] < $min_value )
+ {
+ $min_index = $a;
+ $min_value = $values[$a][1];
+ }
+ }
+
+ return $values[ $min_index ];
+ }
+
+ protected function lib_max($args) {
+ $values = $this->assertMinArgs($args, 1, "max");
+
+ $first_format = $values[0][2];
+
+ $max_index = 0;
+ $max_value = $values[0][1];
+
+ for( $a = 0; $a < sizeof( $values ); $a++ )
+ {
+ $converted = $this->convert( $values[$a], $first_format );
+
+ if( $converted[1] > $max_value )
+ {
+ $max_index = $a;
+ $max_value = $values[$a][1];
+ }
+ }
+
+ return $values[ $max_index ];
+ }
+
+ protected function lib_tan($num) {
+ return tan($this->assertNumber($num));
+ }
+
+ protected function lib_sin($num) {
+ return sin($this->assertNumber($num));
+ }
+
+ protected function lib_cos($num) {
+ return cos($this->assertNumber($num));
+ }
+
+ protected function lib_atan($num) {
+ $num = atan($this->assertNumber($num));
+ return array("number", $num, "rad");
+ }
+
+ protected function lib_asin($num) {
+ $num = asin($this->assertNumber($num));
+ return array("number", $num, "rad");
+ }
+
+ protected function lib_acos($num) {
+ $num = acos($this->assertNumber($num));
+ return array("number", $num, "rad");
+ }
+
+ protected function lib_sqrt($num) {
+ return sqrt($this->assertNumber($num));
+ }
+
+ protected function lib_extract($value) {
+ list($list, $idx) = $this->assertArgs($value, 2, "extract");
+ $idx = $this->assertNumber($idx);
+ // 1 indexed
+ if ($list[0] == "list" && isset($list[2][$idx - 1])) {
+ return $list[2][$idx - 1];
+ }
+ }
+
+ protected function lib_isnumber($value) {
+ return $this->toBool($value[0] == "number");
+ }
+
+ protected function lib_isstring($value) {
+ return $this->toBool($value[0] == "string");
+ }
+
+ protected function lib_iscolor($value) {
+ return $this->toBool($this->coerceColor($value));
+ }
+
+ protected function lib_iskeyword($value) {
+ return $this->toBool($value[0] == "keyword");
+ }
+
+ protected function lib_ispixel($value) {
+ return $this->toBool($value[0] == "number" && $value[2] == "px");
+ }
+
+ protected function lib_ispercentage($value) {
+ return $this->toBool($value[0] == "number" && $value[2] == "%");
+ }
+
+ protected function lib_isem($value) {
+ return $this->toBool($value[0] == "number" && $value[2] == "em");
+ }
+
+ protected function lib_isrem($value) {
+ return $this->toBool($value[0] == "number" && $value[2] == "rem");
+ }
+
+ protected function lib_rgbahex($color) {
+ $color = $this->coerceColor($color);
+ if (is_null($color))
+ $this->throwError("color expected for rgbahex");
+
+ return sprintf("#%02x%02x%02x%02x",
+ isset($color[4]) ? $color[4]*255 : 255,
+ $color[1],$color[2], $color[3]);
+ }
+
+ protected function lib_argb($color){
+ return $this->lib_rgbahex($color);
+ }
+
+ /**
+ * Given an url, decide whether to output a regular link or the base64-encoded contents of the file
+ *
+ * @param array $value either an argument list (two strings) or a single string
+ * @return string formatted url(), either as a link or base64-encoded
+ */
+ protected function lib_data_uri($value) {
+ $mime = ($value[0] === 'list') ? $value[2][0][2] : null;
+ $url = ($value[0] === 'list') ? $value[2][1][2][0] : $value[2][0];
+
+ $fullpath = $this->findImport($url);
+
+ if($fullpath && ($fsize = filesize($fullpath)) !== false) {
+ // IE8 can't handle data uris larger than 32KB
+ if($fsize/1024 < 32) {
+ if(is_null($mime)) {
+ if(class_exists('finfo')) { // php 5.3+
+ $finfo = new finfo(FILEINFO_MIME);
+ $mime = explode('; ', $finfo->file($fullpath));
+ $mime = $mime[0];
+ } elseif(function_exists('mime_content_type')) { // PHP 5.2
+ $mime = mime_content_type($fullpath);
+ }
+ }
+
+ if(!is_null($mime)) // fallback if the mime type is still unknown
+ $url = sprintf('data:%s;base64,%s', $mime, base64_encode(file_get_contents($fullpath)));
+ }
+ }
+
+ return 'url("'.$url.'")';
+ }
+
+ // utility func to unquote a string
+ protected function lib_e($arg) {
+ switch ($arg[0]) {
+ case "list":
+ $items = $arg[2];
+ if (isset($items[0])) {
+ return $this->lib_e($items[0]);
+ }
+ $this->throwError("unrecognised input");
+ case "string":
+ $arg[1] = "";
+ return $arg;
+ case "keyword":
+ return $arg;
+ default:
+ return array("keyword", $this->compileValue($arg));
+ }
+ }
+
+ protected function lib__sprintf($args) {
+ if ($args[0] != "list") return $args;
+ $values = $args[2];
+ $string = array_shift($values);
+ $template = $this->compileValue($this->lib_e($string));
+
+ $i = 0;
+ if (preg_match_all('/%[dsa]/', $template, $m)) {
+ foreach ($m[0] as $match) {
+ $val = isset($values[$i]) ?
+ $this->reduce($values[$i]) : array('keyword', '');
+
+ // lessjs compat, renders fully expanded color, not raw color
+ if ($color = $this->coerceColor($val)) {
+ $val = $color;
+ }
+
+ $i++;
+ $rep = $this->compileValue($this->lib_e($val));
+ $template = preg_replace('/'.self::preg_quote($match).'/',
+ $rep, $template, 1);
+ }
+ }
+
+ $d = $string[0] == "string" ? $string[1] : '"';
+ return array("string", $d, array($template));
+ }
+
+ protected function lib_floor($arg) {
+ $value = $this->assertNumber($arg);
+ return array("number", floor($value), $arg[2]);
+ }
+
+ protected function lib_ceil($arg) {
+ $value = $this->assertNumber($arg);
+ return array("number", ceil($value), $arg[2]);
+ }
+
+ protected function lib_round($arg) {
+ if($arg[0] != "list") {
+ $value = $this->assertNumber($arg);
+ return array("number", round($value), $arg[2]);
+ } else {
+ $value = $this->assertNumber($arg[2][0]);
+ $precision = $this->assertNumber($arg[2][1]);
+ return array("number", round($value, $precision), $arg[2][0][2]);
+ }
+ }
+
+ protected function lib_unit($arg) {
+ if ($arg[0] == "list") {
+ list($number, $newUnit) = $arg[2];
+ return array("number", $this->assertNumber($number),
+ $this->compileValue($this->lib_e($newUnit)));
+ } else {
+ return array("number", $this->assertNumber($arg), "");
+ }
+ }
+
+ /**
+ * Helper function to get arguments for color manipulation functions.
+ * takes a list that contains a color like thing and a percentage
+ */
+ public function colorArgs($args) {
+ if ($args[0] != 'list' || count($args[2]) < 2) {
+ return array(array('color', 0, 0, 0), 0);
+ }
+ list($color, $delta) = $args[2];
+ $color = $this->assertColor($color);
+ $delta = floatval($delta[1]);
+
+ return array($color, $delta);
+ }
+
+ protected function lib_darken($args) {
+ list($color, $delta) = $this->colorArgs($args);
+
+ $hsl = $this->toHSL($color);
+ $hsl[3] = $this->clamp($hsl[3] - $delta, 100);
+ return $this->toRGB($hsl);
+ }
+
+ protected function lib_lighten($args) {
+ list($color, $delta) = $this->colorArgs($args);
+
+ $hsl = $this->toHSL($color);
+ $hsl[3] = $this->clamp($hsl[3] + $delta, 100);
+ return $this->toRGB($hsl);
+ }
+
+ protected function lib_saturate($args) {
+ list($color, $delta) = $this->colorArgs($args);
+
+ $hsl = $this->toHSL($color);
+ $hsl[2] = $this->clamp($hsl[2] + $delta, 100);
+ return $this->toRGB($hsl);
+ }
+
+ protected function lib_desaturate($args) {
+ list($color, $delta) = $this->colorArgs($args);
+
+ $hsl = $this->toHSL($color);
+ $hsl[2] = $this->clamp($hsl[2] - $delta, 100);
+ return $this->toRGB($hsl);
+ }
+
+ protected function lib_spin($args) {
+ list($color, $delta) = $this->colorArgs($args);
+
+ $hsl = $this->toHSL($color);
+
+ $hsl[1] = $hsl[1] + $delta % 360;
+ if ($hsl[1] < 0) $hsl[1] += 360;
+
+ return $this->toRGB($hsl);
+ }
+
+ protected function lib_fadeout($args) {
+ list($color, $delta) = $this->colorArgs($args);
+ $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) - $delta/100);
+ return $color;
+ }
+
+ protected function lib_fadein($args) {
+ list($color, $delta) = $this->colorArgs($args);
+ $color[4] = $this->clamp((isset($color[4]) ? $color[4] : 1) + $delta/100);
+ return $color;
+ }
+
+ protected function lib_hue($color) {
+ $hsl = $this->toHSL($this->assertColor($color));
+ return round($hsl[1]);
+ }
+
+ protected function lib_saturation($color) {
+ $hsl = $this->toHSL($this->assertColor($color));
+ return round($hsl[2]);
+ }
+
+ protected function lib_lightness($color) {
+ $hsl = $this->toHSL($this->assertColor($color));
+ return round($hsl[3]);
+ }
+
+ // get the alpha of a color
+ // defaults to 1 for non-colors or colors without an alpha
+ protected function lib_alpha($value) {
+ if (!is_null($color = $this->coerceColor($value))) {
+ return isset($color[4]) ? $color[4] : 1;
+ }
+ }
+
+ // set the alpha of the color
+ protected function lib_fade($args) {
+ list($color, $alpha) = $this->colorArgs($args);
+ $color[4] = $this->clamp($alpha / 100.0);
+ return $color;
+ }
+
+ protected function lib_percentage($arg) {
+ $num = $this->assertNumber($arg);
+ return array("number", $num*100, "%");
+ }
+
+ // mixes two colors by weight
+ // mix(@color1, @color2, [@weight: 50%]);
+ // http://sass-lang.com/docs/yardoc/Sass/Script/Functions.html#mix-instance_method
+ protected function lib_mix($args) {
+ if ($args[0] != "list" || count($args[2]) < 2)
+ $this->throwError("mix expects (color1, color2, weight)");
+
+ list($first, $second) = $args[2];
+ $first = $this->assertColor($first);
+ $second = $this->assertColor($second);
+
+ $first_a = $this->lib_alpha($first);
+ $second_a = $this->lib_alpha($second);
+
+ if (isset($args[2][2])) {
+ $weight = $args[2][2][1] / 100.0;
+ } else {
+ $weight = 0.5;
+ }
+
+ $w = $weight * 2 - 1;
+ $a = $first_a - $second_a;
+
+ $w1 = (($w * $a == -1 ? $w : ($w + $a)/(1 + $w * $a)) + 1) / 2.0;
+ $w2 = 1.0 - $w1;
+
+ $new = array('color',
+ $w1 * $first[1] + $w2 * $second[1],
+ $w1 * $first[2] + $w2 * $second[2],
+ $w1 * $first[3] + $w2 * $second[3],
+ );
+
+ if ($first_a != 1.0 || $second_a != 1.0) {
+ $new[] = $first_a * $weight + $second_a * ($weight - 1);
+ }
+
+ return $this->fixColor($new);
+ }
+
+ protected function lib_contrast($args) {
+ $darkColor = array('color', 0, 0, 0);
+ $lightColor = array('color', 255, 255, 255);
+ $threshold = 0.43;
+
+ if ( $args[0] == 'list' ) {
+ $inputColor = ( isset($args[2][0]) ) ? $this->assertColor($args[2][0]) : $lightColor;
+ $darkColor = ( isset($args[2][1]) ) ? $this->assertColor($args[2][1]) : $darkColor;
+ $lightColor = ( isset($args[2][2]) ) ? $this->assertColor($args[2][2]) : $lightColor;
+ if( isset($args[2][3]) ) {
+ if( isset($args[2][3][2]) && $args[2][3][2] == '%' ) {
+ $args[2][3][1] /= 100;
+ unset($args[2][3][2]);
+ }
+ $threshold = $this->assertNumber($args[2][3]);
+ }
+ }
+ else {
+ $inputColor = $this->assertColor($args);
+ }
+
+ $inputColor = $this->coerceColor($inputColor);
+ $darkColor = $this->coerceColor($darkColor);
+ $lightColor = $this->coerceColor($lightColor);
+
+ //Figure out which is actually light and dark!
+ if ( $this->lib_luma($darkColor) > $this->lib_luma($lightColor) ) {
+ $t = $lightColor;
+ $lightColor = $darkColor;
+ $darkColor = $t;
+ }
+
+ $inputColor_alpha = $this->lib_alpha($inputColor);
+ if ( ( $this->lib_luma($inputColor) * $inputColor_alpha) < $threshold) {
+ return $lightColor;
+ }
+ return $darkColor;
+ }
+
+ protected function lib_luma($color) {
+ $color = $this->coerceColor($color);
+ return (0.2126 * $color[1] / 255) + (0.7152 * $color[2] / 255) + (0.0722 * $color[3] / 255);
+ }
+
+
+ public function assertColor($value, $error = "expected color value") {
+ $color = $this->coerceColor($value);
+ if (is_null($color)) $this->throwError($error);
+ return $color;
+ }
+
+ public function assertNumber($value, $error = "expecting number") {
+ if ($value[0] == "number") return $value[1];
+ $this->throwError($error);
+ }
+
+ public function assertArgs($value, $expectedArgs, $name="") {
+ if ($expectedArgs == 1) {
+ return $value;
+ } else {
+ if ($value[0] !== "list" || $value[1] != ",") $this->throwError("expecting list");
+ $values = $value[2];
+ $numValues = count($values);
+ if ($expectedArgs != $numValues) {
+ if ($name) {
+ $name = $name . ": ";
+ }
+
+ $this->throwError("${name}expecting $expectedArgs arguments, got $numValues");
+ }
+
+ return $values;
+ }
+ }
+
+ public function assertMinArgs($value, $expectedMinArgs, $name="") {
+ if ($value[0] !== "list" || $value[1] != ",") $this->throwError("expecting list");
+ $values = $value[2];
+ $numValues = count($values);
+ if ($expectedMinArgs > $numValues) {
+ if ($name) {
+ $name = $name . ": ";
+ }
+
+ $this->throwError("${name}expecting at least $expectedMinArgs arguments, got $numValues");
+ }
+
+ return $values;
+}
+
+ protected function toHSL($color) {
+ if ($color[0] == 'hsl') return $color;
+
+ $r = $color[1] / 255;
+ $g = $color[2] / 255;
+ $b = $color[3] / 255;
+
+ $min = min($r, $g, $b);
+ $max = max($r, $g, $b);
+
+ $L = ($min + $max) / 2;
+ if ($min == $max) {
+ $S = $H = 0;
+ } else {
+ if ($L < 0.5)
+ $S = ($max - $min)/($max + $min);
+ else
+ $S = ($max - $min)/(2.0 - $max - $min);
+
+ if ($r == $max) $H = ($g - $b)/($max - $min);
+ elseif ($g == $max) $H = 2.0 + ($b - $r)/($max - $min);
+ elseif ($b == $max) $H = 4.0 + ($r - $g)/($max - $min);
+
+ }
+
+ $out = array('hsl',
+ ($H < 0 ? $H + 6 : $H)*60,
+ $S*100,
+ $L*100,
+ );
+
+ if (count($color) > 4) $out[] = $color[4]; // copy alpha
+ return $out;
+ }
+
+ protected function toRGB_helper($comp, $temp1, $temp2) {
+ if ($comp < 0) $comp += 1.0;
+ elseif ($comp > 1) $comp -= 1.0;
+
+ if (6 * $comp < 1) return $temp1 + ($temp2 - $temp1) * 6 * $comp;
+ if (2 * $comp < 1) return $temp2;
+ if (3 * $comp < 2) return $temp1 + ($temp2 - $temp1)*((2/3) - $comp) * 6;
+
+ return $temp1;
+ }
+
+ /**
+ * Converts a hsl array into a color value in rgb.
+ * Expects H to be in range of 0 to 360, S and L in 0 to 100
+ */
+ protected function toRGB($color) {
+ if ($color[0] == 'color') return $color;
+
+ $H = $color[1] / 360;
+ $S = $color[2] / 100;
+ $L = $color[3] / 100;
+
+ if ($S == 0) {
+ $r = $g = $b = $L;
+ } else {
+ $temp2 = $L < 0.5 ?
+ $L*(1.0 + $S) :
+ $L + $S - $L * $S;
+
+ $temp1 = 2.0 * $L - $temp2;
+
+ $r = $this->toRGB_helper($H + 1/3, $temp1, $temp2);
+ $g = $this->toRGB_helper($H, $temp1, $temp2);
+ $b = $this->toRGB_helper($H - 1/3, $temp1, $temp2);
+ }
+
+ // $out = array('color', round($r*255), round($g*255), round($b*255));
+ $out = array('color', $r*255, $g*255, $b*255);
+ if (count($color) > 4) $out[] = $color[4]; // copy alpha
+ return $out;
+ }
+
+ protected function clamp($v, $max = 1, $min = 0) {
+ return min($max, max($min, $v));
+ }
+
+ /**
+ * Convert the rgb, rgba, hsl color literals of function type
+ * as returned by the parser into values of color type.
+ */
+ protected function funcToColor($func) {
+ $fname = $func[1];
+ if ($func[2][0] != 'list') return false; // need a list of arguments
+ $rawComponents = $func[2][2];
+
+ if ($fname == 'hsl' || $fname == 'hsla') {
+ $hsl = array('hsl');
+ $i = 0;
+ foreach ($rawComponents as $c) {
+ $val = $this->reduce($c);
+ $val = isset($val[1]) ? floatval($val[1]) : 0;
+
+ if ($i == 0) $clamp = 360;
+ elseif ($i < 3) $clamp = 100;
+ else $clamp = 1;
+
+ $hsl[] = $this->clamp($val, $clamp);
+ $i++;
+ }
+
+ while (count($hsl) < 4) $hsl[] = 0;
+ return $this->toRGB($hsl);
+
+ } elseif ($fname == 'rgb' || $fname == 'rgba') {
+ $components = array();
+ $i = 1;
+ foreach ($rawComponents as $c) {
+ $c = $this->reduce($c);
+ if ($i < 4) {
+ if ($c[0] == "number" && $c[2] == "%") {
+ $components[] = 255 * ($c[1] / 100);
+ } else {
+ $components[] = floatval($c[1]);
+ }
+ } elseif ($i == 4) {
+ if ($c[0] == "number" && $c[2] == "%") {
+ $components[] = 1.0 * ($c[1] / 100);
+ } else {
+ $components[] = floatval($c[1]);
+ }
+ } else break;
+
+ $i++;
+ }
+ while (count($components) < 3) $components[] = 0;
+ array_unshift($components, 'color');
+ return $this->fixColor($components);
+ }
+
+ return false;
+ }
+
+ protected function reduce($value, $forExpression = false) {
+ switch ($value[0]) {
+ case "interpolate":
+ $reduced = $this->reduce($value[1]);
+ $var = $this->compileValue($reduced);
+ $res = $this->reduce(array("variable", $this->vPrefix . $var));
+
+ if ($res[0] == "raw_color") {
+ $res = $this->coerceColor($res);
+ }
+
+ if (empty($value[2])) $res = $this->lib_e($res);
+
+ return $res;
+ case "variable":
+ $key = $value[1];
+ if (is_array($key)) {
+ $key = $this->reduce($key);
+ $key = $this->vPrefix . $this->compileValue($this->lib_e($key));
+ }
+
+ $seen =& $this->env->seenNames;
+
+ if (!empty($seen[$key])) {
+ $this->throwError("infinite loop detected: $key");
+ }
+
+ $seen[$key] = true;
+ $out = $this->reduce($this->get($key));
+ $seen[$key] = false;
+ return $out;
+ case "list":
+ foreach ($value[2] as &$item) {
+ $item = $this->reduce($item, $forExpression);
+ }
+ return $value;
+ case "expression":
+ return $this->evaluate($value);
+ case "string":
+ foreach ($value[2] as &$part) {
+ if (is_array($part)) {
+ $strip = $part[0] == "variable";
+ $part = $this->reduce($part);
+ if ($strip) $part = $this->lib_e($part);
+ }
+ }
+ return $value;
+ case "escape":
+ list(,$inner) = $value;
+ return $this->lib_e($this->reduce($inner));
+ case "function":
+ $color = $this->funcToColor($value);
+ if ($color) return $color;
+
+ list(, $name, $args) = $value;
+ if ($name == "%") $name = "_sprintf";
+
+ $f = isset($this->libFunctions[$name]) ?
+ $this->libFunctions[$name] : array($this, 'lib_'.str_replace('-', '_', $name));
+
+ if (is_callable($f)) {
+ if ($args[0] == 'list')
+ $args = self::compressList($args[2], $args[1]);
+
+ $ret = call_user_func($f, $this->reduce($args, true), $this);
+
+ if (is_null($ret)) {
+ return array("string", "", array(
+ $name, "(", $args, ")"
+ ));
+ }
+
+ // convert to a typed value if the result is a php primitive
+ if (is_numeric($ret)) $ret = array('number', $ret, "");
+ elseif (!is_array($ret)) $ret = array('keyword', $ret);
+
+ return $ret;
+ }
+
+ // plain function, reduce args
+ $value[2] = $this->reduce($value[2]);
+ return $value;
+ case "unary":
+ list(, $op, $exp) = $value;
+ $exp = $this->reduce($exp);
+
+ if ($exp[0] == "number") {
+ switch ($op) {
+ case "+":
+ return $exp;
+ case "-":
+ $exp[1] *= -1;
+ return $exp;
+ }
+ }
+ return array("string", "", array($op, $exp));
+ }
+
+ if ($forExpression) {
+ switch ($value[0]) {
+ case "keyword":
+ if ($color = $this->coerceColor($value)) {
+ return $color;
+ }
+ break;
+ case "raw_color":
+ return $this->coerceColor($value);
+ }
+ }
+
+ return $value;
+ }
+
+
+ // coerce a value for use in color operation
+ protected function coerceColor($value) {
+ switch($value[0]) {
+ case 'color': return $value;
+ case 'raw_color':
+ $c = array("color", 0, 0, 0);
+ $colorStr = substr($value[1], 1);
+ $num = hexdec($colorStr);
+ $width = strlen($colorStr) == 3 ? 16 : 256;
+
+ for ($i = 3; $i > 0; $i--) { // 3 2 1
+ $t = $num % $width;
+ $num /= $width;
+
+ $c[$i] = $t * (256/$width) + $t * floor(16/$width);
+ }
+
+ return $c;
+ case 'keyword':
+ $name = $value[1];
+ if (isset(self::$cssColors[$name])) {
+ $rgba = explode(',', self::$cssColors[$name]);
+
+ if(isset($rgba[3]))
+ return array('color', $rgba[0], $rgba[1], $rgba[2], $rgba[3]);
+
+ return array('color', $rgba[0], $rgba[1], $rgba[2]);
+ }
+ return null;
+ }
+ }
+
+ // make something string like into a string
+ protected function coerceString($value) {
+ switch ($value[0]) {
+ case "string":
+ return $value;
+ case "keyword":
+ return array("string", "", array($value[1]));
+ }
+ return null;
+ }
+
+ // turn list of length 1 into value type
+ protected function flattenList($value) {
+ if ($value[0] == "list" && count($value[2]) == 1) {
+ return $this->flattenList($value[2][0]);
+ }
+ return $value;
+ }
+
+ public function toBool($a) {
+ if ($a) return self::$TRUE;
+ else return self::$FALSE;
+ }
+
+ // evaluate an expression
+ protected function evaluate($exp) {
+ list(, $op, $left, $right, $whiteBefore, $whiteAfter) = $exp;
+
+ $left = $this->reduce($left, true);
+ $right = $this->reduce($right, true);
+
+ if ($leftColor = $this->coerceColor($left)) {
+ $left = $leftColor;
+ }
+
+ if ($rightColor = $this->coerceColor($right)) {
+ $right = $rightColor;
+ }
+
+ $ltype = $left[0];
+ $rtype = $right[0];
+
+ // operators that work on all types
+ if ($op == "and") {
+ return $this->toBool($left == self::$TRUE && $right == self::$TRUE);
+ }
+
+ if ($op == "=") {
+ return $this->toBool($this->eq($left, $right) );
+ }
+
+ if ($op == "+" && !is_null($str = $this->stringConcatenate($left, $right))) {
+ return $str;
+ }
+
+ // type based operators
+ $fname = "op_${ltype}_${rtype}";
+ if (is_callable(array($this, $fname))) {
+ $out = $this->$fname($op, $left, $right);
+ if (!is_null($out)) return $out;
+ }
+
+ // make the expression look it did before being parsed
+ $paddedOp = $op;
+ if ($whiteBefore) $paddedOp = " " . $paddedOp;
+ if ($whiteAfter) $paddedOp .= " ";
+
+ return array("string", "", array($left, $paddedOp, $right));
+ }
+
+ protected function stringConcatenate($left, $right) {
+ if ($strLeft = $this->coerceString($left)) {
+ if ($right[0] == "string") {
+ $right[1] = "";
+ }
+ $strLeft[2][] = $right;
+ return $strLeft;
+ }
+
+ if ($strRight = $this->coerceString($right)) {
+ array_unshift($strRight[2], $left);
+ return $strRight;
+ }
+ }
+
+ protected function convert( $number, $to )
+ {
+ $value = $this->assertNumber( $number );
+ $from = $number[2];
+
+ // easy out
+ if( $from == $to )
+ return $number;
+
+ // check if the from value is a length
+ if( ( $from_index = array_search( $from, self::$lengths ) ) !== false ) {
+ // make sure to value is too
+ if( in_array( $to, self::$lengths ) ) {
+ // do the actual conversion
+ $to_index = array_search( $to, self::$lengths );
+ $px = $value * self::$lengths_to_base[ $from_index ];
+ $result = $px * ( 1 / self::$lengths_to_base[ $to_index ] );
+
+ $result = round( $result, 8 );
+ return array( "number", $result, $to );
+ }
+ }
+
+ // do the same check for times
+ if( in_array( $from, self::$times ) ) {
+ if( in_array( $to, self::$times ) ) {
+ // currently only ms and s are valid
+ if( $to == "ms" )
+ $result = $value * 1000;
+ else
+ $result = $value / 1000;
+
+ $result = round( $result, 8 );
+ return array( "number", $result, $to );
+ }
+ }
+
+ // lastly check for an angle
+ if( in_array( $from, self::$angles ) ) {
+ // convert whatever angle it is into degrees
+ if( $from == "rad" )
+ $deg = rad2deg( $value );
+
+ else if( $from == "turn" )
+ $deg = $value * 360;
+
+ else if( $from == "grad" )
+ $deg = $value / (400 / 360);
+
+ else
+ $deg = $value;
+
+ // Then convert it from degrees into desired unit
+ if( $to == "deg" )
+ $result = $deg;
+
+ if( $to == "rad" )
+ $result = deg2rad( $deg );
+
+ if( $to == "turn" )
+ $result = $value / 360;
+
+ if( $to == "grad" )
+ $result = $value * (400 / 360);
+
+ $result = round( $result, 8 );
+ return array( "number", $result, $to );
+ }
+
+ // we don't know how to convert these
+ $this->throwError( "Cannot convert {$from} to {$to}" );
+ }
+
+ // make sure a color's components don't go out of bounds
+ protected function fixColor($c) {
+ foreach (range(1, 3) as $i) {
+ if ($c[$i] < 0) $c[$i] = 0;
+ if ($c[$i] > 255) $c[$i] = 255;
+ }
+
+ return $c;
+ }
+
+ protected function op_number_color($op, $lft, $rgt) {
+ if ($op == '+' || $op == '*') {
+ return $this->op_color_number($op, $rgt, $lft);
+ }
+ }
+
+ protected function op_color_number($op, $lft, $rgt) {
+ if ($rgt[0] == '%') $rgt[1] /= 100;
+
+ return $this->op_color_color($op, $lft,
+ array_fill(1, count($lft) - 1, $rgt[1]));
+ }
+
+ protected function op_color_color($op, $left, $right) {
+ $out = array('color');
+ $max = count($left) > count($right) ? count($left) : count($right);
+ foreach (range(1, $max - 1) as $i) {
+ $lval = isset($left[$i]) ? $left[$i] : 0;
+ $rval = isset($right[$i]) ? $right[$i] : 0;
+ switch ($op) {
+ case '+':
+ $out[] = $lval + $rval;
+ break;
+ case '-':
+ $out[] = $lval - $rval;
+ break;
+ case '*':
+ $out[] = $lval * $rval;
+ break;
+ case '%':
+ $out[] = $lval % $rval;
+ break;
+ case '/':
+ if ($rval == 0) $this->throwError("evaluate error: can't divide by zero");
+ $out[] = $lval / $rval;
+ break;
+ default:
+ $this->throwError('evaluate error: color op number failed on op '.$op);
+ }
+ }
+ return $this->fixColor($out);
+ }
+
+ function lib_red($color){
+ $color = $this->coerceColor($color);
+ if (is_null($color)) {
+ $this->throwError('color expected for red()');
+ }
+
+ return $color[1];
+ }
+
+ function lib_green($color){
+ $color = $this->coerceColor($color);
+ if (is_null($color)) {
+ $this->throwError('color expected for green()');
+ }
+
+ return $color[2];
+ }
+
+ function lib_blue($color){
+ $color = $this->coerceColor($color);
+ if (is_null($color)) {
+ $this->throwError('color expected for blue()');
+ }
+
+ return $color[3];
+ }
+
+
+ // operator on two numbers
+ protected function op_number_number($op, $left, $right) {
+ $unit = empty($left[2]) ? $right[2] : $left[2];
+
+ $value = 0;
+ switch ($op) {
+ case '+':
+ $value = $left[1] + $right[1];
+ break;
+ case '*':
+ $value = $left[1] * $right[1];
+ break;
+ case '-':
+ $value = $left[1] - $right[1];
+ break;
+ case '%':
+ $value = $left[1] % $right[1];
+ break;
+ case '/':
+ if ($right[1] == 0) $this->throwError('parse error: divide by zero');
+ $value = $left[1] / $right[1];
+ break;
+ case '<':
+ return $this->toBool($left[1] < $right[1]);
+ case '>':
+ return $this->toBool($left[1] > $right[1]);
+ case '>=':
+ return $this->toBool($left[1] >= $right[1]);
+ case '=<':
+ return $this->toBool($left[1] <= $right[1]);
+ default:
+ $this->throwError('parse error: unknown number operator: '.$op);
+ }
+
+ return array("number", $value, $unit);
+ }
+
+
+ /* environment functions */
+
+ protected function makeOutputBlock($type, $selectors = null) {
+ $b = new stdclass;
+ $b->lines = array();
+ $b->children = array();
+ $b->selectors = $selectors;
+ $b->type = $type;
+ $b->parent = $this->scope;
+ return $b;
+ }
+
+ // the state of execution
+ protected function pushEnv($block = null) {
+ $e = new stdclass;
+ $e->parent = $this->env;
+ $e->store = array();
+ $e->block = $block;
+
+ $this->env = $e;
+ return $e;
+ }
+
+ // pop something off the stack
+ protected function popEnv() {
+ $old = $this->env;
+ $this->env = $this->env->parent;
+ return $old;
+ }
+
+ // set something in the current env
+ protected function set($name, $value) {
+ $this->env->store[$name] = $value;
+ }
+
+
+ // get the highest occurrence entry for a name
+ protected function get($name) {
+ $current = $this->env;
+
+ // track scope to evaluate
+ $scope_secondary = array();
+
+ $isArguments = $name == $this->vPrefix . 'arguments';
+ while ($current) {
+ if ($isArguments && isset($current->arguments)) {
+ return array('list', ' ', $current->arguments);
+ }
+
+ if (isset($current->store[$name]))
+ return $current->store[$name];
+ // has secondary scope?
+ if (isset($current->storeParent))
+ $scope_secondary[] = $current->storeParent;
+
+ if (isset($current->parent))
+ $current = $current->parent;
+ else
+ $current = null;
+ }
+
+ while (count($scope_secondary)) {
+ // pop one off
+ $current = array_shift($scope_secondary);
+ while ($current) {
+ if ($isArguments && isset($current->arguments)) {
+ return array('list', ' ', $current->arguments);
+ }
+
+ if (isset($current->store[$name])) {
+ return $current->store[$name];
+ }
+
+ // has secondary scope?
+ if (isset($current->storeParent)) {
+ $scope_secondary[] = $current->storeParent;
+ }
+
+ if (isset($current->parent)) {
+ $current = $current->parent;
+ } else {
+ $current = null;
+ }
+ }
+ }
+
+ $this->throwError("variable $name is undefined");
+ }
+
+ // inject array of unparsed strings into environment as variables
+ protected function injectVariables($args) {
+ $this->pushEnv();
+ $parser = new lessc_parser($this, __METHOD__);
+ foreach ($args as $name => $strValue) {
+ if ($name[0] != '@') $name = '@'.$name;
+ $parser->count = 0;
+ $parser->buffer = (string)$strValue;
+ if (!$parser->propertyValue($value)) {
+ throw new \Exception("failed to parse passed in variable $name: $strValue");
+ }
+
+ $this->set($name, $value);
+ }
+ }
+
+ /**
+ * Initialize any static state, can initialize parser for a file
+ * $opts isn't used yet
+ */
+ public function __construct($fname = null) {
+ if ($fname !== null) {
+ // used for deprecated parse method
+ $this->_parseFile = $fname;
+ }
+ }
+
+ public function compile($string, $name = null) {
+ $locale = setlocale(LC_NUMERIC, 0);
+ setlocale(LC_NUMERIC, "C");
+
+ $this->parser = $this->makeParser($name);
+ $root = $this->parser->parse($string);
+
+ $this->env = null;
+ $this->scope = null;
+ $this->allParsedFiles = array();
+
+ $this->formatter = $this->newFormatter();
+
+ if (!empty($this->registeredVars)) {
+ $this->injectVariables($this->registeredVars);
+ }
+
+ $this->sourceParser = $this->parser; // used for error messages
+ $this->compileBlock($root);
+
+ ob_start();
+ $this->formatter->block($this->scope);
+ $out = ob_get_clean();
+ setlocale(LC_NUMERIC, $locale);
+ return $out;
+ }
+
+ public function compileFile($fname, $outFname = null) {
+ if (!is_readable($fname)) {
+ throw new \Exception('load error: failed to find '.$fname);
+ }
+
+ $pi = pathinfo($fname);
+
+ $oldImport = $this->importDir;
+
+ $this->importDir = (array)$this->importDir;
+ $this->importDir[] = $pi['dirname'].'/';
+
+ $this->addParsedFile($fname);
+
+ $out = $this->compile(file_get_contents($fname), $fname);
+
+ $this->importDir = $oldImport;
+
+ if ($outFname !== null) {
+ return file_put_contents($outFname, $out);
+ }
+
+ return $out;
+ }
+
+ /**
+ * Based on explicit input/output files does a full change check on cache before compiling.
+ *
+ * @param string $in
+ * @param string $out
+ * @param boolean $force
+ * @return string Compiled CSS results
+ * @throws Exception
+ */
+ public function checkedCachedCompile($in, $out, $force = false) {
+ if (!is_file($in) || !is_readable($in)) {
+ throw new Exception('Invalid or unreadable input file specified.');
+ }
+ if (is_dir($out) || !is_writable(file_exists($out) ? $out : dirname($out))) {
+ throw new Exception('Invalid or unwritable output file specified.');
+ }
+
+ $outMeta = $out . '.meta';
+ $metadata = null;
+ if (!$force && is_file($outMeta)) {
+ $metadata = unserialize(file_get_contents($outMeta));
+ }
+
+ $output = $this->cachedCompile($metadata ? $metadata : $in);
+
+ if (!$metadata || $metadata['updated'] != $output['updated']) {
+ $css = $output['compiled'];
+ unset($output['compiled']);
+ file_put_contents($out, $css);
+ file_put_contents($outMeta, serialize($output));
+ } else {
+ $css = file_get_contents($out);
+ }
+
+ return $css;
+ }
+
+ // compile only if changed input has changed or output doesn't exist
+ public function checkedCompile($in, $out) {
+ if (!is_file($out) || filemtime($in) > filemtime($out)) {
+ $this->compileFile($in, $out);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Execute lessphp on a .less file or a lessphp cache structure
+ *
+ * The lessphp cache structure contains information about a specific
+ * less file having been parsed. It can be used as a hint for future
+ * calls to determine whether or not a rebuild is required.
+ *
+ * The cache structure contains two important keys that may be used
+ * externally:
+ *
+ * compiled: The final compiled CSS
+ * updated: The time (in seconds) the CSS was last compiled
+ *
+ * The cache structure is a plain-ol' PHP associative array and can
+ * be serialized and unserialized without a hitch.
+ *
+ * @param mixed $in Input
+ * @param bool $force Force rebuild?
+ * @return array lessphp cache structure
+ */
+ public function cachedCompile($in, $force = false) {
+ // assume no root
+ $root = null;
+
+ if (is_string($in)) {
+ $root = $in;
+ } elseif (is_array($in) and isset($in['root'])) {
+ if ($force or ! isset($in['files'])) {
+ // If we are forcing a recompile or if for some reason the
+ // structure does not contain any file information we should
+ // specify the root to trigger a rebuild.
+ $root = $in['root'];
+ } elseif (isset($in['files']) and is_array($in['files'])) {
+ foreach ($in['files'] as $fname => $ftime ) {
+ if (!file_exists($fname) or filemtime($fname) > $ftime) {
+ // One of the files we knew about previously has changed
+ // so we should look at our incoming root again.
+ $root = $in['root'];
+ break;
+ }
+ }
+ }
+ } else {
+ // TODO: Throw an exception? We got neither a string nor something
+ // that looks like a compatible lessphp cache structure.
+ return null;
+ }
+
+ if ($root !== null) {
+ // If we have a root value which means we should rebuild.
+ $out = array();
+ $out['root'] = $root;
+ $out['compiled'] = $this->compileFile($root);
+ $out['files'] = $this->allParsedFiles();
+ $out['updated'] = time();
+ return $out;
+ } else {
+ // No changes, pass back the structure
+ // we were given initially.
+ return $in;
+ }
+
+ }
+
+ // parse and compile buffer
+ // This is deprecated
+ public function parse($str = null, $initialVariables = null) {
+ if (is_array($str)) {
+ $initialVariables = $str;
+ $str = null;
+ }
+
+ $oldVars = $this->registeredVars;
+ if ($initialVariables !== null) {
+ $this->setVariables($initialVariables);
+ }
+
+ if ($str == null) {
+ if (empty($this->_parseFile)) {
+ throw new \Exception("nothing to parse");
+ }
+
+ $out = $this->compileFile($this->_parseFile);
+ } else {
+ $out = $this->compile($str);
+ }
+
+ $this->registeredVars = $oldVars;
+ return $out;
+ }
+
+ protected function makeParser($name) {
+ $parser = new lessc_parser($this, $name);
+ $parser->writeComments = $this->preserveComments;
+
+ return $parser;
+ }
+
+ public function setFormatter($name) {
+ $this->formatterName = $name;
+ }
+
+ protected function newFormatter() {
+ $className = "lessc_formatter_lessjs";
+ if (!empty($this->formatterName)) {
+ if (!is_string($this->formatterName))
+ return $this->formatterName;
+ $className = "lessc_formatter_$this->formatterName";
+ }
+
+ return new $className;
+ }
+
+ public function setPreserveComments($preserve) {
+ $this->preserveComments = $preserve;
+ }
+
+ public function registerFunction($name, $func) {
+ $this->libFunctions[$name] = $func;
+ }
+
+ public function unregisterFunction($name) {
+ unset($this->libFunctions[$name]);
+ }
+
+ public function setVariables($variables) {
+ $this->registeredVars = array_merge($this->registeredVars, $variables);
+ }
+
+ public function unsetVariable($name) {
+ unset($this->registeredVars[$name]);
+ }
+
+ public function setImportDir($dirs) {
+ $this->importDir = (array)$dirs;
+ }
+
+ public function addImportDir($dir) {
+ $this->importDir = (array)$this->importDir;
+ $this->importDir[] = $dir;
+ }
+
+ public function allParsedFiles() {
+ return $this->allParsedFiles;
+ }
+
+ public function addParsedFile($file) {
+ $this->allParsedFiles[realpath($file)] = filemtime($file);
+ }
+
+ /**
+ * Uses the current value of $this->count to show line and line number
+ */
+ public function throwError($msg = null) {
+ if ($this->sourceLoc >= 0) {
+ $this->sourceParser->throwError($msg, $this->sourceLoc);
+ }
+ throw new \Exception($msg);
+ }
+
+ // compile file $in to file $out if $in is newer than $out
+ // returns true when it compiles, false otherwise
+ public static function ccompile($in, $out, $less = null) {
+ if ($less === null) {
+ $less = new self;
+ }
+ return $less->checkedCompile($in, $out);
+ }
+
+ public static function cexecute($in, $force = false, $less = null) {
+ if ($less === null) {
+ $less = new self;
+ }
+ return $less->cachedCompile($in, $force);
+ }
+
+ static protected $cssColors = array(
+ 'aliceblue' => '240,248,255',
+ 'antiquewhite' => '250,235,215',
+ 'aqua' => '0,255,255',
+ 'aquamarine' => '127,255,212',
+ 'azure' => '240,255,255',
+ 'beige' => '245,245,220',
+ 'bisque' => '255,228,196',
+ 'black' => '0,0,0',
+ 'blanchedalmond' => '255,235,205',
+ 'blue' => '0,0,255',
+ 'blueviolet' => '138,43,226',
+ 'brown' => '165,42,42',
+ 'burlywood' => '222,184,135',
+ 'cadetblue' => '95,158,160',
+ 'chartreuse' => '127,255,0',
+ 'chocolate' => '210,105,30',
+ 'coral' => '255,127,80',
+ 'cornflowerblue' => '100,149,237',
+ 'cornsilk' => '255,248,220',
+ 'crimson' => '220,20,60',
+ 'cyan' => '0,255,255',
+ 'darkblue' => '0,0,139',
+ 'darkcyan' => '0,139,139',
+ 'darkgoldenrod' => '184,134,11',
+ 'darkgray' => '169,169,169',
+ 'darkgreen' => '0,100,0',
+ 'darkgrey' => '169,169,169',
+ 'darkkhaki' => '189,183,107',
+ 'darkmagenta' => '139,0,139',
+ 'darkolivegreen' => '85,107,47',
+ 'darkorange' => '255,140,0',
+ 'darkorchid' => '153,50,204',
+ 'darkred' => '139,0,0',
+ 'darksalmon' => '233,150,122',
+ 'darkseagreen' => '143,188,143',
+ 'darkslateblue' => '72,61,139',
+ 'darkslategray' => '47,79,79',
+ 'darkslategrey' => '47,79,79',
+ 'darkturquoise' => '0,206,209',
+ 'darkviolet' => '148,0,211',
+ 'deeppink' => '255,20,147',
+ 'deepskyblue' => '0,191,255',
+ 'dimgray' => '105,105,105',
+ 'dimgrey' => '105,105,105',
+ 'dodgerblue' => '30,144,255',
+ 'firebrick' => '178,34,34',
+ 'floralwhite' => '255,250,240',
+ 'forestgreen' => '34,139,34',
+ 'fuchsia' => '255,0,255',
+ 'gainsboro' => '220,220,220',
+ 'ghostwhite' => '248,248,255',
+ 'gold' => '255,215,0',
+ 'goldenrod' => '218,165,32',
+ 'gray' => '128,128,128',
+ 'green' => '0,128,0',
+ 'greenyellow' => '173,255,47',
+ 'grey' => '128,128,128',
+ 'honeydew' => '240,255,240',
+ 'hotpink' => '255,105,180',
+ 'indianred' => '205,92,92',
+ 'indigo' => '75,0,130',
+ 'ivory' => '255,255,240',
+ 'khaki' => '240,230,140',
+ 'lavender' => '230,230,250',
+ 'lavenderblush' => '255,240,245',
+ 'lawngreen' => '124,252,0',
+ 'lemonchiffon' => '255,250,205',
+ 'lightblue' => '173,216,230',
+ 'lightcoral' => '240,128,128',
+ 'lightcyan' => '224,255,255',
+ 'lightgoldenrodyellow' => '250,250,210',
+ 'lightgray' => '211,211,211',
+ 'lightgreen' => '144,238,144',
+ 'lightgrey' => '211,211,211',
+ 'lightpink' => '255,182,193',
+ 'lightsalmon' => '255,160,122',
+ 'lightseagreen' => '32,178,170',
+ 'lightskyblue' => '135,206,250',
+ 'lightslategray' => '119,136,153',
+ 'lightslategrey' => '119,136,153',
+ 'lightsteelblue' => '176,196,222',
+ 'lightyellow' => '255,255,224',
+ 'lime' => '0,255,0',
+ 'limegreen' => '50,205,50',
+ 'linen' => '250,240,230',
+ 'magenta' => '255,0,255',
+ 'maroon' => '128,0,0',
+ 'mediumaquamarine' => '102,205,170',
+ 'mediumblue' => '0,0,205',
+ 'mediumorchid' => '186,85,211',
+ 'mediumpurple' => '147,112,219',
+ 'mediumseagreen' => '60,179,113',
+ 'mediumslateblue' => '123,104,238',
+ 'mediumspringgreen' => '0,250,154',
+ 'mediumturquoise' => '72,209,204',
+ 'mediumvioletred' => '199,21,133',
+ 'midnightblue' => '25,25,112',
+ 'mintcream' => '245,255,250',
+ 'mistyrose' => '255,228,225',
+ 'moccasin' => '255,228,181',
+ 'navajowhite' => '255,222,173',
+ 'navy' => '0,0,128',
+ 'oldlace' => '253,245,230',
+ 'olive' => '128,128,0',
+ 'olivedrab' => '107,142,35',
+ 'orange' => '255,165,0',
+ 'orangered' => '255,69,0',
+ 'orchid' => '218,112,214',
+ 'palegoldenrod' => '238,232,170',
+ 'palegreen' => '152,251,152',
+ 'paleturquoise' => '175,238,238',
+ 'palevioletred' => '219,112,147',
+ 'papayawhip' => '255,239,213',
+ 'peachpuff' => '255,218,185',
+ 'peru' => '205,133,63',
+ 'pink' => '255,192,203',
+ 'plum' => '221,160,221',
+ 'powderblue' => '176,224,230',
+ 'purple' => '128,0,128',
+ 'red' => '255,0,0',
+ 'rosybrown' => '188,143,143',
+ 'royalblue' => '65,105,225',
+ 'saddlebrown' => '139,69,19',
+ 'salmon' => '250,128,114',
+ 'sandybrown' => '244,164,96',
+ 'seagreen' => '46,139,87',
+ 'seashell' => '255,245,238',
+ 'sienna' => '160,82,45',
+ 'silver' => '192,192,192',
+ 'skyblue' => '135,206,235',
+ 'slateblue' => '106,90,205',
+ 'slategray' => '112,128,144',
+ 'slategrey' => '112,128,144',
+ 'snow' => '255,250,250',
+ 'springgreen' => '0,255,127',
+ 'steelblue' => '70,130,180',
+ 'tan' => '210,180,140',
+ 'teal' => '0,128,128',
+ 'thistle' => '216,191,216',
+ 'tomato' => '255,99,71',
+ 'transparent' => '0,0,0,0',
+ 'turquoise' => '64,224,208',
+ 'violet' => '238,130,238',
+ 'wheat' => '245,222,179',
+ 'white' => '255,255,255',
+ 'whitesmoke' => '245,245,245',
+ 'yellow' => '255,255,0',
+ 'yellowgreen' => '154,205,50'
+ );
+}
+
+// responsible for taking a string of LESS code and converting it into a
+// syntax tree
+class lessc_parser {
+ static protected $nextBlockId = 0; // used to uniquely identify blocks
+
+ static protected $precedence = array(
+ '=<' => 0,
+ '>=' => 0,
+ '=' => 0,
+ '<' => 0,
+ '>' => 0,
+
+ '+' => 1,
+ '-' => 1,
+ '*' => 2,
+ '/' => 2,
+ '%' => 2,
+ );
+
+ static protected $whitePattern;
+ static protected $commentMulti;
+
+ static protected $commentSingle = "//";
+ static protected $commentMultiLeft = "/*";
+ static protected $commentMultiRight = "*/";
+
+ // regex string to match any of the operators
+ static protected $operatorString;
+
+ // these properties will supress division unless it's inside parenthases
+ static protected $supressDivisionProps =
+ array('/border-radius$/i', '/^font$/i');
+
+ protected $blockDirectives = array("font-face", "keyframes", "page", "-moz-document", "viewport", "-moz-viewport", "-o-viewport", "-ms-viewport");
+ protected $lineDirectives = array("charset");
+
+ /**
+ * if we are in parens we can be more liberal with whitespace around
+ * operators because it must evaluate to a single value and thus is less
+ * ambiguous.
+ *
+ * Consider:
+ * property1: 10 -5; // is two numbers, 10 and -5
+ * property2: (10 -5); // should evaluate to 5
+ */
+ protected $inParens = false;
+
+ // caches preg escaped literals
+ static protected $literalCache = array();
+
+ public function __construct($lessc, $sourceName = null) {
+ $this->eatWhiteDefault = true;
+ // reference to less needed for vPrefix, mPrefix, and parentSelector
+ $this->lessc = $lessc;
+
+ $this->sourceName = $sourceName; // name used for error messages
+
+ $this->writeComments = false;
+
+ if (!self::$operatorString) {
+ self::$operatorString =
+ '('.implode('|', array_map(array('lessc', 'preg_quote'),
+ array_keys(self::$precedence))).')';
+
+ $commentSingle = lessc::preg_quote(self::$commentSingle);
+ $commentMultiLeft = lessc::preg_quote(self::$commentMultiLeft);
+ $commentMultiRight = lessc::preg_quote(self::$commentMultiRight);
+
+ self::$commentMulti = $commentMultiLeft.'.*?'.$commentMultiRight;
+ self::$whitePattern = '/'.$commentSingle.'[^\n]*\s*|('.self::$commentMulti.')\s*|\s+/Ais';
+ }
+ }
+
+ public function parse($buffer) {
+ $this->count = 0;
+ $this->line = 1;
+
+ $this->env = null; // block stack
+ $this->buffer = $this->writeComments ? $buffer : $this->removeComments($buffer);
+ $this->pushSpecialBlock("root");
+ $this->eatWhiteDefault = true;
+ $this->seenComments = array();
+
+ // trim whitespace on head
+ // if (preg_match('/^\s+/', $this->buffer, $m)) {
+ // $this->line += substr_count($m[0], "\n");
+ // $this->buffer = ltrim($this->buffer);
+ // }
+ $this->whitespace();
+
+ // parse the entire file
+ while (false !== $this->parseChunk());
+
+ if ($this->count != strlen($this->buffer))
+ $this->throwError();
+
+ // TODO report where the block was opened
+ if ( !property_exists($this->env, 'parent') || !is_null($this->env->parent) )
+ throw new \Exception('parse error: unclosed block');
+
+ return $this->env;
+ }
+
+ /**
+ * Parse a single chunk off the head of the buffer and append it to the
+ * current parse environment.
+ * Returns false when the buffer is empty, or when there is an error.
+ *
+ * This function is called repeatedly until the entire document is
+ * parsed.
+ *
+ * This parser is most similar to a recursive descent parser. Single
+ * functions represent discrete grammatical rules for the language, and
+ * they are able to capture the text that represents those rules.
+ *
+ * Consider the function lessc::keyword(). (all parse functions are
+ * structured the same)
+ *
+ * The function takes a single reference argument. When calling the
+ * function it will attempt to match a keyword on the head of the buffer.
+ * If it is successful, it will place the keyword in the referenced
+ * argument, advance the position in the buffer, and return true. If it
+ * fails then it won't advance the buffer and it will return false.
+ *
+ * All of these parse functions are powered by lessc::match(), which behaves
+ * the same way, but takes a literal regular expression. Sometimes it is
+ * more convenient to use match instead of creating a new function.
+ *
+ * Because of the format of the functions, to parse an entire string of
+ * grammatical rules, you can chain them together using &&.
+ *
+ * But, if some of the rules in the chain succeed before one fails, then
+ * the buffer position will be left at an invalid state. In order to
+ * avoid this, lessc::seek() is used to remember and set buffer positions.
+ *
+ * Before parsing a chain, use $s = $this->seek() to remember the current
+ * position into $s. Then if a chain fails, use $this->seek($s) to
+ * go back where we started.
+ */
+ protected function parseChunk() {
+ if (empty($this->buffer)) return false;
+ $s = $this->seek();
+
+ if ($this->whitespace()) {
+ return true;
+ }
+
+ // setting a property
+ if ($this->keyword($key) && $this->assign() &&
+ $this->propertyValue($value, $key) && $this->end())
+ {
+ $this->append(array('assign', $key, $value), $s);
+ return true;
+ } else {
+ $this->seek($s);
+ }
+
+
+ // look for special css blocks
+ if ($this->literal('@', false)) {
+ $this->count--;
+
+ // media
+ if ($this->literal('@media')) {
+ if (($this->mediaQueryList($mediaQueries) || true)
+ && $this->literal('{'))
+ {
+ $media = $this->pushSpecialBlock("media");
+ $media->queries = is_null($mediaQueries) ? array() : $mediaQueries;
+ return true;
+ } else {
+ $this->seek($s);
+ return false;
+ }
+ }
+
+ if ($this->literal("@", false) && $this->keyword($dirName)) {
+ if ($this->isDirective($dirName, $this->blockDirectives)) {
+ if (($this->openString("{", $dirValue, null, array(";")) || true) &&
+ $this->literal("{"))
+ {
+ $dir = $this->pushSpecialBlock("directive");
+ $dir->name = $dirName;
+ if (isset($dirValue)) $dir->value = $dirValue;
+ return true;
+ }
+ } elseif ($this->isDirective($dirName, $this->lineDirectives)) {
+ if ($this->propertyValue($dirValue) && $this->end()) {
+ $this->append(array("directive", $dirName, $dirValue));
+ return true;
+ }
+ } elseif ($this->literal(":", true)) {
+ //Ruleset Definition
+ if (($this->openString("{", $dirValue, null, array(";")) || true) &&
+ $this->literal("{"))
+ {
+ $dir = $this->pushBlock($this->fixTags(array("@".$dirName)));
+ $dir->name = $dirName;
+ if (isset($dirValue)) $dir->value = $dirValue;
+ return true;
+ }
+ }
+ }
+
+ $this->seek($s);
+ }
+
+ // setting a variable
+ if ($this->variable($var) && $this->assign() &&
+ $this->propertyValue($value) && $this->end())
+ {
+ $this->append(array('assign', $var, $value), $s);
+ return true;
+ } else {
+ $this->seek($s);
+ }
+
+ if ($this->import($importValue)) {
+ $this->append($importValue, $s);
+ return true;
+ }
+
+ // opening parametric mixin
+ if ($this->tag($tag, true) && $this->argumentDef($args, $isVararg) &&
+ ($this->guards($guards) || true) &&
+ $this->literal('{'))
+ {
+ $block = $this->pushBlock($this->fixTags(array($tag)));
+ $block->args = $args;
+ $block->isVararg = $isVararg;
+ if (!empty($guards)) $block->guards = $guards;
+ return true;
+ } else {
+ $this->seek($s);
+ }
+
+ // opening a simple block
+ if ($this->tags($tags) && $this->literal('{', false)) {
+ $tags = $this->fixTags($tags);
+ $this->pushBlock($tags);
+ return true;
+ } else {
+ $this->seek($s);
+ }
+
+ // closing a block
+ if ($this->literal('}', false)) {
+ try {
+ $block = $this->pop();
+ } catch (\Exception $e) {
+ $this->seek($s);
+ $this->throwError($e->getMessage());
+ }
+
+ $hidden = false;
+ if (is_null($block->type)) {
+ $hidden = true;
+ if (!isset($block->args)) {
+ foreach ($block->tags as $tag) {
+ if (!is_string($tag) || $tag{0} != $this->lessc->mPrefix) {
+ $hidden = false;
+ break;
+ }
+ }
+ }
+
+ foreach ($block->tags as $tag) {
+ if (is_string($tag)) {
+ $this->env->children[$tag][] = $block;
+ }
+ }
+ }
+
+ if (!$hidden) {
+ $this->append(array('block', $block), $s);
+ }
+
+ // this is done here so comments aren't bundled into he block that
+ // was just closed
+ $this->whitespace();
+ return true;
+ }
+
+ // mixin
+ if ($this->mixinTags($tags) &&
+ ($this->argumentDef($argv, $isVararg) || true) &&
+ ($this->keyword($suffix) || true) && $this->end())
+ {
+ $tags = $this->fixTags($tags);
+ $this->append(array('mixin', $tags, $argv, $suffix), $s);
+ return true;
+ } else {
+ $this->seek($s);
+ }
+
+ // spare ;
+ if ($this->literal(';')) return true;
+
+ return false; // got nothing, throw error
+ }
+
+ protected function isDirective($dirname, $directives) {
+ // TODO: cache pattern in parser
+ $pattern = implode("|",
+ array_map(array("lessc", "preg_quote"), $directives));
+ $pattern = '/^(-[a-z-]+-)?(' . $pattern . ')$/i';
+
+ return preg_match($pattern, $dirname);
+ }
+
+ protected function fixTags($tags) {
+ // move @ tags out of variable namespace
+ foreach ($tags as &$tag) {
+ if ($tag{0} == $this->lessc->vPrefix)
+ $tag[0] = $this->lessc->mPrefix;
+ }
+ return $tags;
+ }
+
+ // a list of expressions
+ protected function expressionList(&$exps) {
+ $values = array();
+
+ while ($this->expression($exp)) {
+ $values[] = $exp;
+ }
+
+ if (count($values) == 0) return false;
+
+ $exps = lessc::compressList($values, ' ');
+ return true;
+ }
+
+ /**
+ * Attempt to consume an expression.
+ * @link http://en.wikipedia.org/wiki/Operator-precedence_parser#Pseudo-code
+ */
+ protected function expression(&$out) {
+ if ($this->value($lhs)) {
+ $out = $this->expHelper($lhs, 0);
+
+ // look for / shorthand
+ if (!empty($this->env->supressedDivision)) {
+ unset($this->env->supressedDivision);
+ $s = $this->seek();
+ if ($this->literal("/") && $this->value($rhs)) {
+ $out = array("list", "",
+ array($out, array("keyword", "/"), $rhs));
+ } else {
+ $this->seek($s);
+ }
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * recursively parse infix equation with $lhs at precedence $minP
+ */
+ protected function expHelper($lhs, $minP) {
+ $this->inExp = true;
+ $ss = $this->seek();
+
+ while (true) {
+ $whiteBefore = isset($this->buffer[$this->count - 1]) &&
+ ctype_space($this->buffer[$this->count - 1]);
+
+ // If there is whitespace before the operator, then we require
+ // whitespace after the operator for it to be an expression
+ $needWhite = $whiteBefore && !$this->inParens;
+
+ if ($this->match(self::$operatorString.($needWhite ? '\s' : ''), $m) && self::$precedence[$m[1]] >= $minP) {
+ if (!$this->inParens && isset($this->env->currentProperty) && $m[1] == "/" && empty($this->env->supressedDivision)) {
+ foreach (self::$supressDivisionProps as $pattern) {
+ if (preg_match($pattern, $this->env->currentProperty)) {
+ $this->env->supressedDivision = true;
+ break 2;
+ }
+ }
+ }
+
+
+ $whiteAfter = isset($this->buffer[$this->count - 1]) &&
+ ctype_space($this->buffer[$this->count - 1]);
+
+ if (!$this->value($rhs)) break;
+
+ // peek for next operator to see what to do with rhs
+ if ($this->peek(self::$operatorString, $next) && self::$precedence[$next[1]] > self::$precedence[$m[1]]) {
+ $rhs = $this->expHelper($rhs, self::$precedence[$next[1]]);
+ }
+
+ $lhs = array('expression', $m[1], $lhs, $rhs, $whiteBefore, $whiteAfter);
+ $ss = $this->seek();
+
+ continue;
+ }
+
+ break;
+ }
+
+ $this->seek($ss);
+
+ return $lhs;
+ }
+
+ // consume a list of values for a property
+ public function propertyValue(&$value, $keyName = null) {
+ $values = array();
+
+ if ($keyName !== null) $this->env->currentProperty = $keyName;
+
+ $s = null;
+ while ($this->expressionList($v)) {
+ $values[] = $v;
+ $s = $this->seek();
+ if (!$this->literal(',')) break;
+ }
+
+ if ($s) $this->seek($s);
+
+ if ($keyName !== null) unset($this->env->currentProperty);
+
+ if (count($values) == 0) return false;
+
+ $value = lessc::compressList($values, ', ');
+ return true;
+ }
+
+ protected function parenValue(&$out) {
+ $s = $this->seek();
+
+ // speed shortcut
+ if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "(") {
+ return false;
+ }
+
+ $inParens = $this->inParens;
+ if ($this->literal("(") &&
+ ($this->inParens = true) && $this->expression($exp) &&
+ $this->literal(")"))
+ {
+ $out = $exp;
+ $this->inParens = $inParens;
+ return true;
+ } else {
+ $this->inParens = $inParens;
+ $this->seek($s);
+ }
+
+ return false;
+ }
+
+ // a single value
+ protected function value(&$value) {
+ $s = $this->seek();
+
+ // speed shortcut
+ if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "-") {
+ // negation
+ if ($this->literal("-", false) &&
+ (($this->variable($inner) && $inner = array("variable", $inner)) ||
+ $this->unit($inner) ||
+ $this->parenValue($inner)))
+ {
+ $value = array("unary", "-", $inner);
+ return true;
+ } else {
+ $this->seek($s);
+ }
+ }
+
+ if ($this->parenValue($value)) return true;
+ if ($this->unit($value)) return true;
+ if ($this->color($value)) return true;
+ if ($this->func($value)) return true;
+ if ($this->stringValue($value)) return true;
+
+ if ($this->keyword($word)) {
+ $value = array('keyword', $word);
+ return true;
+ }
+
+ // try a variable
+ if ($this->variable($var)) {
+ $value = array('variable', $var);
+ return true;
+ }
+
+ // unquote string (should this work on any type?
+ if ($this->literal("~") && $this->stringValue($str)) {
+ $value = array("escape", $str);
+ return true;
+ } else {
+ $this->seek($s);
+ }
+
+ // css hack: \0
+ if ($this->literal('\\') && $this->match('([0-9]+)', $m)) {
+ $value = array('keyword', '\\'.$m[1]);
+ return true;
+ } else {
+ $this->seek($s);
+ }
+
+ return false;
+ }
+
+ // an import statement
+ protected function import(&$out) {
+ if (!$this->literal('@import')) return false;
+
+ // @import "something.css" media;
+ // @import url("something.css") media;
+ // @import url(something.css) media;
+
+ if ($this->propertyValue($value)) {
+ $out = array("import", $value);
+ return true;
+ }
+ }
+
+ protected function mediaQueryList(&$out) {
+ if ($this->genericList($list, "mediaQuery", ",", false)) {
+ $out = $list[2];
+ return true;
+ }
+ return false;
+ }
+
+ protected function mediaQuery(&$out) {
+ $s = $this->seek();
+
+ $expressions = null;
+ $parts = array();
+
+ if (($this->literal("only") && ($only = true) || $this->literal("not") && ($not = true) || true) && $this->keyword($mediaType)) {
+ $prop = array("mediaType");
+ if (isset($only)) $prop[] = "only";
+ if (isset($not)) $prop[] = "not";
+ $prop[] = $mediaType;
+ $parts[] = $prop;
+ } else {
+ $this->seek($s);
+ }
+
+
+ if (!empty($mediaType) && !$this->literal("and")) {
+ // ~
+ } else {
+ $this->genericList($expressions, "mediaExpression", "and", false);
+ if (is_array($expressions)) $parts = array_merge($parts, $expressions[2]);
+ }
+
+ if (count($parts) == 0) {
+ $this->seek($s);
+ return false;
+ }
+
+ $out = $parts;
+ return true;
+ }
+
+ protected function mediaExpression(&$out) {
+ $s = $this->seek();
+ $value = null;
+ if ($this->literal("(") &&
+ $this->keyword($feature) &&
+ ($this->literal(":") && $this->expression($value) || true) &&
+ $this->literal(")"))
+ {
+ $out = array("mediaExp", $feature);
+ if ($value) $out[] = $value;
+ return true;
+ } elseif ($this->variable($variable)) {
+ $out = array('variable', $variable);
+ return true;
+ }
+
+ $this->seek($s);
+ return false;
+ }
+
+ // an unbounded string stopped by $end
+ protected function openString($end, &$out, $nestingOpen=null, $rejectStrs = null) {
+ $oldWhite = $this->eatWhiteDefault;
+ $this->eatWhiteDefault = false;
+
+ $stop = array("'", '"', "@{", $end);
+ $stop = array_map(array("lessc", "preg_quote"), $stop);
+ // $stop[] = self::$commentMulti;
+
+ if (!is_null($rejectStrs)) {
+ $stop = array_merge($stop, $rejectStrs);
+ }
+
+ $patt = '(.*?)('.implode("|", $stop).')';
+
+ $nestingLevel = 0;
+
+ $content = array();
+ while ($this->match($patt, $m, false)) {
+ if (!empty($m[1])) {
+ $content[] = $m[1];
+ if ($nestingOpen) {
+ $nestingLevel += substr_count($m[1], $nestingOpen);
+ }
+ }
+
+ $tok = $m[2];
+
+ $this->count-= strlen($tok);
+ if ($tok == $end) {
+ if ($nestingLevel == 0) {
+ break;
+ } else {
+ $nestingLevel--;
+ }
+ }
+
+ if (($tok == "'" || $tok == '"') && $this->stringValue($str)) {
+ $content[] = $str;
+ continue;
+ }
+
+ if ($tok == "@{" && $this->interpolation($inter)) {
+ $content[] = $inter;
+ continue;
+ }
+
+ if (!empty($rejectStrs) && in_array($tok, $rejectStrs)) {
+ break;
+ }
+
+ $content[] = $tok;
+ $this->count+= strlen($tok);
+ }
+
+ $this->eatWhiteDefault = $oldWhite;
+
+ if (count($content) == 0) return false;
+
+ // trim the end
+ if (is_string(end($content))) {
+ $content[count($content) - 1] = rtrim(end($content));
+ }
+
+ $out = array("string", "", $content);
+ return true;
+ }
+
+ protected function stringValue(&$out) {
+ $s = $this->seek();
+ if ($this->literal('"', false)) {
+ $delim = '"';
+ } elseif ($this->literal("'", false)) {
+ $delim = "'";
+ } else {
+ return false;
+ }
+
+ $content = array();
+
+ // look for either ending delim , escape, or string interpolation
+ $patt = '([^\n]*?)(@\{|\\\\|' .
+ lessc::preg_quote($delim).')';
+
+ $oldWhite = $this->eatWhiteDefault;
+ $this->eatWhiteDefault = false;
+
+ while ($this->match($patt, $m, false)) {
+ $content[] = $m[1];
+ if ($m[2] == "@{") {
+ $this->count -= strlen($m[2]);
+ if ($this->interpolation($inter, false)) {
+ $content[] = $inter;
+ } else {
+ $this->count += strlen($m[2]);
+ $content[] = "@{"; // ignore it
+ }
+ } elseif ($m[2] == '\\') {
+ $content[] = $m[2];
+ if ($this->literal($delim, false)) {
+ $content[] = $delim;
+ }
+ } else {
+ $this->count -= strlen($delim);
+ break; // delim
+ }
+ }
+
+ $this->eatWhiteDefault = $oldWhite;
+
+ if ($this->literal($delim)) {
+ $out = array("string", $delim, $content);
+ return true;
+ }
+
+ $this->seek($s);
+ return false;
+ }
+
+ protected function interpolation(&$out) {
+ $oldWhite = $this->eatWhiteDefault;
+ $this->eatWhiteDefault = true;
+
+ $s = $this->seek();
+ if ($this->literal("@{") &&
+ $this->openString("}", $interp, null, array("'", '"', ";")) &&
+ $this->literal("}", false))
+ {
+ $out = array("interpolate", $interp);
+ $this->eatWhiteDefault = $oldWhite;
+ if ($this->eatWhiteDefault) $this->whitespace();
+ return true;
+ }
+
+ $this->eatWhiteDefault = $oldWhite;
+ $this->seek($s);
+ return false;
+ }
+
+ protected function unit(&$unit) {
+ // speed shortcut
+ if (isset($this->buffer[$this->count])) {
+ $char = $this->buffer[$this->count];
+ if (!ctype_digit($char) && $char != ".") return false;
+ }
+
+ if ($this->match('([0-9]+(?:\.[0-9]*)?|\.[0-9]+)([%a-zA-Z]+)?', $m)) {
+ $unit = array("number", $m[1], empty($m[2]) ? "" : $m[2]);
+ return true;
+ }
+ return false;
+ }
+
+ // a # color
+ protected function color(&$out) {
+ if ($this->match('(#(?:[0-9a-f]{8}|[0-9a-f]{6}|[0-9a-f]{3}))', $m)) {
+ if (strlen($m[1]) > 7) {
+ $out = array("string", "", array($m[1]));
+ } else {
+ $out = array("raw_color", $m[1]);
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ // consume an argument definition list surrounded by ()
+ // each argument is a variable name with optional value
+ // or at the end a ... or a variable named followed by ...
+ // arguments are separated by , unless a ; is in the list, then ; is the
+ // delimiter.
+ protected function argumentDef(&$args, &$isVararg) {
+ $s = $this->seek();
+ if (!$this->literal('(')) return false;
+
+ $values = array();
+ $delim = ",";
+ $method = "expressionList";
+
+ $isVararg = false;
+ while (true) {
+ if ($this->literal("...")) {
+ $isVararg = true;
+ break;
+ }
+
+ if ($this->$method($value)) {
+ if ($value[0] == "variable") {
+ $arg = array("arg", $value[1]);
+ $ss = $this->seek();
+
+ if ($this->assign() && $this->$method($rhs)) {
+ $arg[] = $rhs;
+ } else {
+ $this->seek($ss);
+ if ($this->literal("...")) {
+ $arg[0] = "rest";
+ $isVararg = true;
+ }
+ }
+
+ $values[] = $arg;
+ if ($isVararg) break;
+ continue;
+ } else {
+ $values[] = array("lit", $value);
+ }
+ }
+
+
+ if (!$this->literal($delim)) {
+ if ($delim == "," && $this->literal(";")) {
+ // found new delim, convert existing args
+ $delim = ";";
+ $method = "propertyValue";
+
+ // transform arg list
+ if (isset($values[1])) { // 2 items
+ $newList = array();
+ foreach ($values as $i => $arg) {
+ switch($arg[0]) {
+ case "arg":
+ if ($i) {
+ $this->throwError("Cannot mix ; and , as delimiter types");
+ }
+ $newList[] = $arg[2];
+ break;
+ case "lit":
+ $newList[] = $arg[1];
+ break;
+ case "rest":
+ $this->throwError("Unexpected rest before semicolon");
+ }
+ }
+
+ $newList = array("list", ", ", $newList);
+
+ switch ($values[0][0]) {
+ case "arg":
+ $newArg = array("arg", $values[0][1], $newList);
+ break;
+ case "lit":
+ $newArg = array("lit", $newList);
+ break;
+ }
+
+ } elseif ($values) { // 1 item
+ $newArg = $values[0];
+ }
+
+ if ($newArg) {
+ $values = array($newArg);
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ if (!$this->literal(')')) {
+ $this->seek($s);
+ return false;
+ }
+
+ $args = $values;
+
+ return true;
+ }
+
+ // consume a list of tags
+ // this accepts a hanging delimiter
+ protected function tags(&$tags, $simple = false, $delim = ',') {
+ $tags = array();
+ while ($this->tag($tt, $simple)) {
+ $tags[] = $tt;
+ if (!$this->literal($delim)) break;
+ }
+ if (count($tags) == 0) return false;
+
+ return true;
+ }
+
+ // list of tags of specifying mixin path
+ // optionally separated by > (lazy, accepts extra >)
+ protected function mixinTags(&$tags) {
+ $tags = array();
+ while ($this->tag($tt, true)) {
+ $tags[] = $tt;
+ $this->literal(">");
+ }
+
+ if (count($tags) == 0) return false;
+
+ return true;
+ }
+
+ // a bracketed value (contained within in a tag definition)
+ protected function tagBracket(&$parts, &$hasExpression) {
+ // speed shortcut
+ if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] != "[") {
+ return false;
+ }
+
+ $s = $this->seek();
+
+ $hasInterpolation = false;
+
+ if ($this->literal("[", false)) {
+ $attrParts = array("[");
+ // keyword, string, operator
+ while (true) {
+ if ($this->literal("]", false)) {
+ $this->count--;
+ break; // get out early
+ }
+
+ if ($this->match('\s+', $m)) {
+ $attrParts[] = " ";
+ continue;
+ }
+ if ($this->stringValue($str)) {
+ // escape parent selector, (yuck)
+ foreach ($str[2] as &$chunk) {
+ $chunk = str_replace($this->lessc->parentSelector, "$&$", $chunk);
+ }
+
+ $attrParts[] = $str;
+ $hasInterpolation = true;
+ continue;
+ }
+
+ if ($this->keyword($word)) {
+ $attrParts[] = $word;
+ continue;
+ }
+
+ if ($this->interpolation($inter, false)) {
+ $attrParts[] = $inter;
+ $hasInterpolation = true;
+ continue;
+ }
+
+ // operator, handles attr namespace too
+ if ($this->match('[|-~\$\*\^=]+', $m)) {
+ $attrParts[] = $m[0];
+ continue;
+ }
+
+ break;
+ }
+
+ if ($this->literal("]", false)) {
+ $attrParts[] = "]";
+ foreach ($attrParts as $part) {
+ $parts[] = $part;
+ }
+ $hasExpression = $hasExpression || $hasInterpolation;
+ return true;
+ }
+ $this->seek($s);
+ }
+
+ $this->seek($s);
+ return false;
+ }
+
+ // a space separated list of selectors
+ protected function tag(&$tag, $simple = false) {
+ if ($simple)
+ $chars = '^@,:;{}\][>\(\) "\'';
+ else
+ $chars = '^@,;{}["\'';
+
+ $s = $this->seek();
+
+ $hasExpression = false;
+ $parts = array();
+ while ($this->tagBracket($parts, $hasExpression));
+
+ $oldWhite = $this->eatWhiteDefault;
+ $this->eatWhiteDefault = false;
+
+ while (true) {
+ if ($this->match('(['.$chars.'0-9]['.$chars.']*)', $m)) {
+ $parts[] = $m[1];
+ if ($simple) break;
+
+ while ($this->tagBracket($parts, $hasExpression));
+ continue;
+ }
+
+ if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == "@") {
+ if ($this->interpolation($interp)) {
+ $hasExpression = true;
+ $interp[2] = true; // don't unescape
+ $parts[] = $interp;
+ continue;
+ }
+
+ if ($this->literal("@")) {
+ $parts[] = "@";
+ continue;
+ }
+ }
+
+ if ($this->unit($unit)) { // for keyframes
+ $parts[] = $unit[1];
+ $parts[] = $unit[2];
+ continue;
+ }
+
+ break;
+ }
+
+ $this->eatWhiteDefault = $oldWhite;
+ if (!$parts) {
+ $this->seek($s);
+ return false;
+ }
+
+ if ($hasExpression) {
+ $tag = array("exp", array("string", "", $parts));
+ } else {
+ $tag = trim(implode($parts));
+ }
+
+ $this->whitespace();
+ return true;
+ }
+
+ // a css function
+ protected function func(&$func) {
+ $s = $this->seek();
+
+ if ($this->match('(%|[\w\-_][\w\-_:\.]+|[\w_])', $m) && $this->literal('(')) {
+ $fname = $m[1];
+
+ $sPreArgs = $this->seek();
+
+ $args = array();
+ while (true) {
+ $ss = $this->seek();
+ // this ugly nonsense is for ie filter properties
+ if ($this->keyword($name) && $this->literal('=') && $this->expressionList($value)) {
+ $args[] = array("string", "", array($name, "=", $value));
+ } else {
+ $this->seek($ss);
+ if ($this->expressionList($value)) {
+ $args[] = $value;
+ }
+ }
+
+ if (!$this->literal(',')) break;
+ }
+ $args = array('list', ',', $args);
+
+ if ($this->literal(')')) {
+ $func = array('function', $fname, $args);
+ return true;
+ } elseif ($fname == 'url') {
+ // couldn't parse and in url? treat as string
+ $this->seek($sPreArgs);
+ if ($this->openString(")", $string) && $this->literal(")")) {
+ $func = array('function', $fname, $string);
+ return true;
+ }
+ }
+ }
+
+ $this->seek($s);
+ return false;
+ }
+
+ // consume a less variable
+ protected function variable(&$name) {
+ $s = $this->seek();
+ if ($this->literal($this->lessc->vPrefix, false) &&
+ ($this->variable($sub) || $this->keyword($name)))
+ {
+ if (!empty($sub)) {
+ $name = array('variable', $sub);
+ } else {
+ $name = $this->lessc->vPrefix.$name;
+ }
+ return true;
+ }
+
+ $name = null;
+ $this->seek($s);
+ return false;
+ }
+
+ /**
+ * Consume an assignment operator
+ * Can optionally take a name that will be set to the current property name
+ */
+ protected function assign($name = null) {
+ if ($name) $this->currentProperty = $name;
+ return $this->literal(':') || $this->literal('=');
+ }
+
+ // consume a keyword
+ protected function keyword(&$word) {
+ if ($this->match('([\w_\-\*!"][\w\-_"]*)', $m)) {
+ $word = $m[1];
+ return true;
+ }
+ return false;
+ }
+
+ // consume an end of statement delimiter
+ protected function end() {
+ if ($this->literal(';', false)) {
+ return true;
+ } elseif ($this->count == strlen($this->buffer) || $this->buffer[$this->count] == '}') {
+ // if there is end of file or a closing block next then we don't need a ;
+ return true;
+ }
+ return false;
+ }
+
+ protected function guards(&$guards) {
+ $s = $this->seek();
+
+ if (!$this->literal("when")) {
+ $this->seek($s);
+ return false;
+ }
+
+ $guards = array();
+
+ while ($this->guardGroup($g)) {
+ $guards[] = $g;
+ if (!$this->literal(",")) break;
+ }
+
+ if (count($guards) == 0) {
+ $guards = null;
+ $this->seek($s);
+ return false;
+ }
+
+ return true;
+ }
+
+ // a bunch of guards that are and'd together
+ // TODO rename to guardGroup
+ protected function guardGroup(&$guardGroup) {
+ $s = $this->seek();
+ $guardGroup = array();
+ while ($this->guard($guard)) {
+ $guardGroup[] = $guard;
+ if (!$this->literal("and")) break;
+ }
+
+ if (count($guardGroup) == 0) {
+ $guardGroup = null;
+ $this->seek($s);
+ return false;
+ }
+
+ return true;
+ }
+
+ protected function guard(&$guard) {
+ $s = $this->seek();
+ $negate = $this->literal("not");
+
+ if ($this->literal("(") && $this->expression($exp) && $this->literal(")")) {
+ $guard = $exp;
+ if ($negate) $guard = array("negate", $guard);
+ return true;
+ }
+
+ $this->seek($s);
+ return false;
+ }
+
+ /* raw parsing functions */
+
+ protected function literal($what, $eatWhitespace = null) {
+ if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault;
+
+ // shortcut on single letter
+ if (!isset($what[1]) && isset($this->buffer[$this->count])) {
+ if ($this->buffer[$this->count] == $what) {
+ if (!$eatWhitespace) {
+ $this->count++;
+ return true;
+ }
+ // goes below...
+ } else {
+ return false;
+ }
+ }
+
+ if (!isset(self::$literalCache[$what])) {
+ self::$literalCache[$what] = lessc::preg_quote($what);
+ }
+
+ return $this->match(self::$literalCache[$what], $m, $eatWhitespace);
+ }
+
+ protected function genericList(&$out, $parseItem, $delim="", $flatten=true) {
+ $s = $this->seek();
+ $items = array();
+ while ($this->$parseItem($value)) {
+ $items[] = $value;
+ if ($delim) {
+ if (!$this->literal($delim)) break;
+ }
+ }
+
+ if (count($items) == 0) {
+ $this->seek($s);
+ return false;
+ }
+
+ if ($flatten && count($items) == 1) {
+ $out = $items[0];
+ } else {
+ $out = array("list", $delim, $items);
+ }
+
+ return true;
+ }
+
+
+ // advance counter to next occurrence of $what
+ // $until - don't include $what in advance
+ // $allowNewline, if string, will be used as valid char set
+ protected function to($what, &$out, $until = false, $allowNewline = false) {
+ if (is_string($allowNewline)) {
+ $validChars = $allowNewline;
+ } else {
+ $validChars = $allowNewline ? "." : "[^\n]";
+ }
+ if (!$this->match('('.$validChars.'*?)'.lessc::preg_quote($what), $m, !$until)) return false;
+ if ($until) $this->count -= strlen($what); // give back $what
+ $out = $m[1];
+ return true;
+ }
+
+ // try to match something on head of buffer
+ protected function match($regex, &$out, $eatWhitespace = null) {
+ if ($eatWhitespace === null) $eatWhitespace = $this->eatWhiteDefault;
+
+ $r = '/'.$regex.($eatWhitespace && !$this->writeComments ? '\s*' : '').'/Ais';
+ if (preg_match($r, $this->buffer, $out, null, $this->count)) {
+ $this->count += strlen($out[0]);
+ if ($eatWhitespace && $this->writeComments) $this->whitespace();
+ return true;
+ }
+ return false;
+ }
+
+ // match some whitespace
+ protected function whitespace() {
+ if ($this->writeComments) {
+ $gotWhite = false;
+ while (preg_match(self::$whitePattern, $this->buffer, $m, null, $this->count)) {
+ if (isset($m[1]) && empty($this->seenComments[$this->count])) {
+ $this->append(array("comment", $m[1]));
+ $this->seenComments[$this->count] = true;
+ }
+ $this->count += strlen($m[0]);
+ $gotWhite = true;
+ }
+ return $gotWhite;
+ } else {
+ $this->match("", $m);
+ return strlen($m[0]) > 0;
+ }
+ }
+
+ // match something without consuming it
+ protected function peek($regex, &$out = null, $from=null) {
+ if (is_null($from)) $from = $this->count;
+ $r = '/'.$regex.'/Ais';
+ $result = preg_match($r, $this->buffer, $out, null, $from);
+
+ return $result;
+ }
+
+ // seek to a spot in the buffer or return where we are on no argument
+ protected function seek($where = null) {
+ if ($where === null) return $this->count;
+ else $this->count = $where;
+ return true;
+ }
+
+ /* misc functions */
+
+ public function throwError($msg = "parse error", $count = null) {
+ $count = is_null($count) ? $this->count : $count;
+
+ $line = $this->line +
+ substr_count(substr($this->buffer, 0, $count), "\n");
+
+ if (!empty($this->sourceName)) {
+ $loc = "$this->sourceName on line $line";
+ } else {
+ $loc = "line: $line";
+ }
+
+ // TODO this depends on $this->count
+ if ($this->peek("(.*?)(\n|$)", $m, $count)) {
+ throw new \Exception("$msg: failed at `$m[1]` $loc");
+ } else {
+ throw new \Exception("$msg: $loc");
+ }
+ }
+
+ protected function pushBlock($selectors=null, $type=null) {
+ $b = new \stdClass();
+ $b->parent = $this->env;
+
+ $b->type = $type;
+ $b->id = self::$nextBlockId++;
+
+ $b->isVararg = false; // TODO: kill me from here
+ $b->tags = $selectors;
+
+ $b->props = array();
+ $b->children = array();
+
+ // add a reference to the parser so
+ // we can access the parser to throw errors
+ // or retrieve the sourceName of this block.
+ $b->parser = $this;
+
+ // so we know the position of this block
+ $b->count = $this->count;
+
+ $this->env = $b;
+ return $b;
+ }
+
+ // push a block that doesn't multiply tags
+ protected function pushSpecialBlock($type) {
+ return $this->pushBlock(null, $type);
+ }
+
+ // append a property to the current block
+ protected function append($prop, $pos = null) {
+ if ($pos !== null) $prop[-1] = $pos;
+ $this->env->props[] = $prop;
+ }
+
+ // pop something off the stack
+ protected function pop() {
+ $old = $this->env;
+ $this->env = $this->env->parent;
+ return $old;
+ }
+
+ // remove comments from $text
+ // todo: make it work for all functions, not just url
+ protected function removeComments($text) {
+ $look = array(
+ 'url(', '//', '/*', '"', "'"
+ );
+
+ $out = '';
+ $min = null;
+ while (true) {
+ // find the next item
+ foreach ($look as $token) {
+ $pos = strpos($text, $token);
+ if ($pos !== false) {
+ if (!isset($min) || $pos < $min[1]) $min = array($token, $pos);
+ }
+ }
+
+ if (is_null($min)) break;
+
+ $count = $min[1];
+ $skip = 0;
+ $newlines = 0;
+ switch ($min[0]) {
+ case 'url(':
+ if (preg_match('/url\(.*?\)/', $text, $m, 0, $count))
+ $count += strlen($m[0]) - strlen($min[0]);
+ break;
+ case '"':
+ case "'":
+ if (preg_match('/'.$min[0].'.*?(?<!\\\\)'.$min[0].'/', $text, $m, 0, $count))
+ $count += strlen($m[0]) - 1;
+ break;
+ case '//':
+ $skip = strpos($text, "\n", $count);
+ if ($skip === false) $skip = strlen($text) - $count;
+ else $skip -= $count;
+ break;
+ case '/*':
+ if (preg_match('/\/\*.*?\*\//s', $text, $m, 0, $count)) {
+ $skip = strlen($m[0]);
+ $newlines = substr_count($m[0], "\n");
+ }
+ break;
+ }
+
+ if ($skip == 0) $count += strlen($min[0]);
+
+ $out .= substr($text, 0, $count).str_repeat("\n", $newlines);
+ $text = substr($text, $count + $skip);
+
+ $min = null;
+ }
+
+ return $out.$text;
+ }
+
+}
+
+class lessc_formatter_classic {
+ public $indentChar = " ";
+
+ public $break = "\n";
+ public $open = " {";
+ public $close = "}";
+ public $selectorSeparator = ", ";
+ public $assignSeparator = ":";
+
+ public $openSingle = " { ";
+ public $closeSingle = " }";
+
+ public $disableSingle = false;
+ public $breakSelectors = false;
+
+ public $compressColors = false;
+
+ public function __construct() {
+ $this->indentLevel = 0;
+ }
+
+ public function indentStr($n = 0) {
+ return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
+ }
+
+ public function property($name, $value) {
+ return $name . $this->assignSeparator . $value . ";";
+ }
+
+ protected function isEmpty($block) {
+ if (empty($block->lines)) {
+ foreach ($block->children as $child) {
+ if (!$this->isEmpty($child)) return false;
+ }
+
+ return true;
+ }
+ return false;
+ }
+
+ public function block($block) {
+ if ($this->isEmpty($block)) return;
+
+ $inner = $pre = $this->indentStr();
+
+ $isSingle = !$this->disableSingle &&
+ is_null($block->type) && count($block->lines) == 1;
+
+ if (!empty($block->selectors)) {
+ $this->indentLevel++;
+
+ if ($this->breakSelectors) {
+ $selectorSeparator = $this->selectorSeparator . $this->break . $pre;
+ } else {
+ $selectorSeparator = $this->selectorSeparator;
+ }
+
+ echo $pre .
+ implode($selectorSeparator, $block->selectors);
+ if ($isSingle) {
+ echo $this->openSingle;
+ $inner = "";
+ } else {
+ echo $this->open . $this->break;
+ $inner = $this->indentStr();
+ }
+
+ }
+
+ if (!empty($block->lines)) {
+ $glue = $this->break.$inner;
+ echo $inner . implode($glue, $block->lines);
+ if (!$isSingle && !empty($block->children)) {
+ echo $this->break;
+ }
+ }
+
+ foreach ($block->children as $child) {
+ $this->block($child);
+ }
+
+ if (!empty($block->selectors)) {
+ if (!$isSingle && empty($block->children)) echo $this->break;
+
+ if ($isSingle) {
+ echo $this->closeSingle . $this->break;
+ } else {
+ echo $pre . $this->close . $this->break;
+ }
+
+ $this->indentLevel--;
+ }
+ }
+}
+
+class lessc_formatter_compressed extends lessc_formatter_classic {
+ public $disableSingle = true;
+ public $open = "{";
+ public $selectorSeparator = ",";
+ public $assignSeparator = ":";
+ public $break = "";
+ public $compressColors = true;
+
+ public function indentStr($n = 0) {
+ return "";
+ }
+}
+
+class lessc_formatter_lessjs extends lessc_formatter_classic {
+ public $disableSingle = true;
+ public $breakSelectors = true;
+ public $assignSeparator = ": ";
+ public $selectorSeparator = ",";
+}
+
+
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/README.md b/platform/www/vendor/openpsa/universalfeedcreator/README.md
new file mode 100644
index 0000000..4f4c723
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/README.md
@@ -0,0 +1,161 @@
+UniversalFeedCreator
+====================
+
+RSS and Atom feed generator by Kai Blankenhorn, slightly cleaned up and packaged for Composer.
+
+Supported formats: RSS0.91, RSS1.0, RSS2.0, PIE0.1 (deprecated), MBOX, OPML, ATOM, ATOM0.3,
+HTML, JS, PHP
+
+[![Build Status](https://travis-ci.org/flack/UniversalFeedCreator.png?branch=master)](https://travis-ci.org/flack/UniversalFeedCreator)
+
+## General Usage
+
+```php
+require 'vendor/autoload.php';
+
+$rss = new UniversalFeedCreator();
+$rss->useCached(); // use cached version if age < 1 hour
+$rss->title = "PHP news";
+$rss->description = "daily news from the PHP scripting world";
+
+//optional
+$rss->descriptionTruncSize = 500;
+$rss->descriptionHtmlSyndicated = true;
+
+$rss->link = "http://www.dailyphp.net/news";
+$rss->syndicationURL = "http://www.dailyphp.net/" . $_SERVER["PHP_SELF"];
+
+$image = new FeedImage();
+$image->title = "dailyphp.net logo";
+$image->url = "http://www.dailyphp.net/images/logo.gif";
+$image->link = "http://www.dailyphp.net";
+$image->description = "Feed provided by dailyphp.net. Click to visit.";
+
+//optional
+$image->descriptionTruncSize = 500;
+$image->descriptionHtmlSyndicated = true;
+
+$rss->image = $image;
+
+// get your news items from somewhere, e.g. your database:
+mysql_select_db($dbHost, $dbUser, $dbPass);
+$res = mysql_query("SELECT * FROM news ORDER BY newsdate DESC");
+while ($data = mysql_fetch_object($res)) {
+ $item = new FeedItem();
+ $item->title = $data->title;
+ $item->link = $data->url;
+ $item->description = $data->short;
+
+ //optional
+ $item->descriptionTruncSize = 500;
+ $item->descriptionHtmlSyndicated = true;
+
+ $item->date = $data->newsdate;
+ $item->source = "http://www.dailyphp.net";
+ $item->author = "John Doe";
+
+ $rss->addItem($item);
+}
+
+echo $rss->saveFeed("RSS1.0", "news/feed.xml");
+```
+
+## Changelog:
+
+```
+v1.8 12-03-13
+ packaged for Composer & cleaned up slightly
+
+v1.7.7(BH) 28-03-06
+ added GPX Feed (Barry Hunter)
+
+
+v1.7.6(BH) 20-02-06
+ added GeoRSS Feed (Barry Hunter)
+
+
+v1.7.5(BH) 16-11-05
+ added BASE Feed (Barry Hunter)
+
+v1.7.4(BH) 05-07-05
+ added KML Feed (Barry Hunter)
+
+v1.7.3(BH) 05-07-05
+ added PHP Feed (Barry Hunter)
+
+v1.7.2 10-11-04
+ license changed to LGPL
+
+v1.7.1
+ fixed a syntax bug
+ fixed left over debug code
+
+v1.7 07-18-04
+ added HTML and JavaScript feeds (configurable via CSS) (thanks to Pascal Van Hecke)
+ added HTML descriptions for all feed formats (thanks to Pascal Van Hecke)
+ added a switch to select an external stylesheet (thanks to Pascal Van Hecke)
+ changed default content-type to application/xml
+ added character encoding setting
+ fixed numerous smaller bugs (thanks to Sören Fuhrmann of golem.de)
+ improved changing ATOM versions handling (thanks to August Trometer)
+ improved the UniversalFeedCreator's useCached method (thanks to Sören Fuhrmann of golem.de)
+ added charset output in HTTP headers (thanks to Sören Fuhrmann of golem.de)
+ added Slashdot namespace to RSS 1.0 (thanks to Sören Fuhrmann of golem.de)
+
+v1.6 05-10-04
+ added stylesheet to RSS 1.0 feeds
+ fixed generator comment (thanks Kevin L. Papendick and Tanguy Pruvot)
+ fixed RFC822 date bug (thanks Tanguy Pruvot)
+ added TimeZone customization for RFC8601 (thanks Tanguy Pruvot)
+ fixed Content-type could be empty (thanks Tanguy Pruvot)
+ fixed author/creator in RSS1.0 (thanks Tanguy Pruvot)
+
+v1.6 beta 02-28-04
+ added Atom 0.3 support (not all features, though)
+ improved OPML 1.0 support (hopefully - added more elements)
+ added support for arbitrary additional elements (use with caution)
+ code beautification :-)
+ considered beta due to some internal changes
+
+v1.5.1 01-27-04
+ fixed some RSS 1.0 glitches (thanks to Stéphane Vanpoperynghe)
+ fixed some inconsistencies between documentation and code (thanks to Timothy Martin)
+
+v1.5 01-06-04
+ added support for OPML 1.0
+ added more documentation
+
+v1.4 11-11-03
+ optional feed saving and caching
+ improved documentation
+ minor improvements
+
+v1.3 10-02-03
+ renamed to FeedCreator, as it not only creates RSS anymore
+ added support for mbox
+ tentative support for echo/necho/atom/pie/???
+
+v1.2 07-20-03
+ intelligent auto-truncating of RSS 0.91 attributes
+ don't create some attributes when they're not set
+ documentation improved
+ fixed a real and a possible bug with date conversions
+ code cleanup
+
+v1.1 06-29-03
+ added images to feeds
+ now includes most RSS 0.91 attributes
+ added RSS 2.0 feeds
+
+v1.0 06-24-03
+ initial release
+```
+
+## Credits
+```
+originally (c) Kai Blankenhorn
+www.bitfolge.de
+kaib@bitfolge.de
+v1.3 work by Scott Reynen (scott@randomchaos.com) and Kai Blankenhorn
+v1.5 OPML support by Dirk Clemens
+```
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/AtomCreator03.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/AtomCreator03.php
new file mode 100644
index 0000000..2ec95a4
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/AtomCreator03.php
@@ -0,0 +1,94 @@
+<?php
+
+/**
+ * AtomCreator03 is a FeedCreator that implements the atom specification,
+ * as in http://www.intertwingly.net/wiki/pie/FrontPage.
+ * Please note that just by using AtomCreator03 you won't automatically
+ * produce valid atom files. For example, you have to specify either an editor
+ * for the feed or an author for every single feed item.
+ * Some elements have not been implemented yet. These are (incomplete list):
+ * author URL, item author's email and URL, item contents, alternate links,
+ * other link content types than text/html. Some of them may be created with
+ * AtomCreator03::additionalElements.
+ *
+ * @see FeedCreator#additionalElements
+ * @since 1.6
+ * @author Kai Blankenhorn <kaib@bitfolge.de>, Scott Reynen <scott@randomchaos.com>
+ */
+class AtomCreator03 extends FeedCreator
+{
+
+ /**
+ * AtomCreator03 constructor.
+ */
+ public function __construct()
+ {
+ $this->contentType = "application/atom+xml";
+ $this->encoding = "utf-8";
+ }
+
+ /** @inheritdoc */
+ public function createFeed()
+ {
+ $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+ $feed .= $this->_createGeneratorComment();
+ $feed .= $this->_createStylesheetReferences();
+ $feed .= "<feed version=\"0.3\" xmlns=\"http://purl.org/atom/ns#\"";
+ if ($this->format == 'TOOLBAR') {
+ $feed .= " xmlns:gtb=\"http://toolbar.google.com/custombuttons/\"";
+ }
+ if ($this->language != "") {
+ $feed .= " xml:lang=\"".$this->language."\"";
+ }
+ $feed .= ">\n";
+ $feed .= " <title>".htmlspecialchars($this->title)."</title>\n";
+ $feed .= " <tagline>".htmlspecialchars($this->description)."</tagline>\n";
+ $feed .= " <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->link)."\"/>\n";
+ $feed .= " <id>".htmlspecialchars($this->link)."</id>\n";
+ $now = new FeedDate();
+ $feed .= " <modified>".htmlspecialchars($now->iso8601())."</modified>\n";
+ if ($this->editor != "") {
+ $feed .= " <author>\n";
+ $feed .= " <name>".$this->editor."</name>\n";
+ if ($this->editorEmail != "") {
+ $feed .= " <email>".$this->editorEmail."</email>\n";
+ }
+ $feed .= " </author>\n";
+ }
+ $feed .= " <generator>".FEEDCREATOR_VERSION."</generator>\n";
+ $feed .= $this->_createAdditionalElements($this->additionalElements, " ");
+ for ($i = 0; $i < count($this->items); $i++) {
+ $feed .= " <entry>\n";
+ $feed .= " <title>".htmlspecialchars(strip_tags($this->items[$i]->title))."</title>\n";
+ $feed .= " <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars(
+ $this->items[$i]->link
+ )."\"/>\n";
+ if ($this->items[$i]->date == "") {
+ $this->items[$i]->date = time();
+ }
+ $itemDate = new FeedDate($this->items[$i]->date);
+ $feed .= " <created>".htmlspecialchars($itemDate->iso8601())."</created>\n";
+ $feed .= " <issued>".htmlspecialchars($itemDate->iso8601())."</issued>\n";
+ $feed .= " <modified>".htmlspecialchars($itemDate->iso8601())."</modified>\n";
+ $feed .= " <id>".htmlspecialchars($this->items[$i]->link)."</id>\n";
+ $feed .= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
+ if ($this->items[$i]->author != "") {
+ $feed .= " <author>\n";
+ $feed .= " <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
+ $feed .= " </author>\n";
+ }
+ if ($this->items[$i]->description != "") {
+ $feed .= " <summary>".htmlspecialchars($this->items[$i]->description)."</summary>\n";
+ }
+ if (isset($this->items[$i]->thumbdata)) {
+ $feed .= " <gtb:icon mode=\"base64\" type=\"image/jpeg\">\n";
+ $feed .= chunk_split(base64_encode($this->items[$i]->thumbdata))."\n";
+ $feed .= " </gtb:icon>\n";
+ }
+ $feed .= " </entry>\n";
+ }
+ $feed .= "</feed>\n";
+
+ return $feed;
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/AtomCreator10.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/AtomCreator10.php
new file mode 100644
index 0000000..2f45322
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/AtomCreator10.php
@@ -0,0 +1,164 @@
+<?php
+
+/**
+ * AtomCreator10 is a FeedCreator that implements the atom specification,
+ * as in http://www.atomenabled.org/developers/syndication/atom-format-spec.php
+ * Please note that just by using AtomCreator10 you won't automatically
+ * produce valid atom files. For example, you have to specify either an editor
+ * for the feed or an author for every single feed item.
+ * Some elements have not been implemented yet. These are (incomplete list):
+ * author URL, item author's email and URL, item contents, alternate links,
+ * other link content types than text/html. Some of them may be created with
+ * AtomCreator10::additionalElements.
+ *
+ * @see FeedCreator#additionalElements
+ * @since 1.7.2-mod (modified)
+ * @author Mohammad Hafiz Ismail (mypapit@gmail.com)
+ */
+class AtomCreator10 extends FeedCreator
+{
+
+ /**
+ * AtomCreator10 constructor.
+ */
+ public function __construct()
+ {
+ $this->contentType = "application/atom+xml";
+ $this->encoding = "utf-8";
+ }
+
+ /** @inheritdoc */
+ public function createFeed()
+ {
+ $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+ $feed .= $this->_createGeneratorComment();
+ $feed .= $this->_createStylesheetReferences();
+ $feed .= "<feed xmlns=\"http://www.w3.org/2005/Atom\"";
+ if (!empty($this->items[0]->lat)) {
+ $feed .= " xmlns:georss=\"http://www.georss.org/georss\"\n";
+ }
+ if ($this->language != "") {
+ $feed .= " xml:lang=\"".$this->language."\"";
+ }
+ $feed .= ">\n";
+ $feed .= " <title>".htmlspecialchars($this->title)."</title>\n";
+ $feed .= " <subtitle>".htmlspecialchars($this->description)."</subtitle>\n";
+ $feed .= " <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars($this->link)."\"/>\n";
+ $feed .= " <id>".htmlspecialchars($this->link)."</id>\n";
+ $now = new FeedDate();
+ $feed .= " <updated>".htmlspecialchars($now->iso8601())."</updated>\n";
+ if ($this->editor != "") {
+ $feed .= " <author>\n";
+ $feed .= " <name>".$this->editor."</name>\n";
+ if ($this->editorEmail != "") {
+ $feed .= " <email>".$this->editorEmail."</email>\n";
+ }
+ $feed .= " </author>\n";
+ }
+ if ($this->category != "") {
+
+ $feed .= " <category term=\"".htmlspecialchars($this->category)."\" />\n";
+ }
+ if ($this->copyright != "") {
+ $feed .= " <rights>".FeedCreator::iTrunc(htmlspecialchars($this->copyright), 100)."</rights>\n";
+ }
+ $feed .= " <generator>".$this->version()."</generator>\n";
+
+ $feed .= " <link rel=\"self\" type=\"application/atom+xml\" href=\"".htmlspecialchars(
+ $this->syndicationURL
+ )."\" />\n";
+ $feed .= $this->_createAdditionalElements($this->additionalElements, " ");
+ for ($i = 0; $i < count($this->items); $i++) {
+ $feed .= " <entry>\n";
+ $feed .= " <title>".htmlspecialchars(strip_tags($this->items[$i]->title))."</title>\n";
+ $feed .= " <link rel=\"alternate\" type=\"text/html\" href=\"".htmlspecialchars(
+ $this->items[$i]->link
+ )."\"/>\n";
+ if ($this->items[$i]->date == "") {
+ $this->items[$i]->date = time();
+ }
+ $itemDate = new FeedDate($this->items[$i]->date);
+ $feed .= " <published>".htmlspecialchars($itemDate->iso8601())."</published>\n";
+ $feed .= " <updated>".htmlspecialchars($itemDate->iso8601())."</updated>\n";
+
+ $tempguid = $this->items[$i]->link;
+ if ($this->items[$i]->guid != "") {
+ $tempguid = $this->items[$i]->guid;
+ }
+
+ $feed .= " <id>".htmlspecialchars($tempguid)."</id>\n";
+ $feed .= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
+ if ($this->items[$i]->author != "") {
+ $feed .= " <author>\n";
+ $feed .= " <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
+ if ($this->items[$i]->authorEmail != "") {
+ $feed .= " <email>".htmlspecialchars($this->items[$i]->authorEmail)."</email>\n";
+ }
+
+ if ($this->items[$i]->authorURL != "") {
+ $feed .= " <uri>".htmlspecialchars($this->items[$i]->authorURL)."</uri>\n";
+ }
+
+ $feed .= " </author>\n";
+ }
+
+ if (!empty($this->items[$i]->category)) {
+ foreach ((array) $this->items[$i]->category as $category) {
+ $feed .= " <category ";
+
+ if ($this->items[$i]->categoryScheme != "") {
+ $feed .= " scheme=\"".htmlspecialchars($this->items[$i]->categoryScheme)."\" ";
+ }
+
+ $feed .= " term=\"".htmlspecialchars($category)."\" />\n";
+ }
+ }
+
+ if ($this->items[$i]->description != "") {
+
+ /*
+ * ATOM should have at least summary tag, however this implementation may be inaccurate
+ */
+ $tempdesc = $this->items[$i]->getDescription();
+ $temptype = "";
+
+ if ($this->items[$i]->descriptionHtmlSyndicated) {
+ $temptype = " type=\"html\"";
+ $tempdesc = $this->items[$i]->getDescription();
+
+ }
+
+ if (empty($this->items[$i]->descriptionTruncSize)) {
+ $feed .= " <content".$temptype.">".$tempdesc."</content>\n";
+ }
+
+ $feed .= " <summary".$temptype.">".$tempdesc."</summary>\n";
+ } else {
+
+ $feed .= " <summary>no summary</summary>\n";
+
+ }
+
+ if ($this->items[$i]->enclosure != null) {
+ $feed .= " <link rel=\"enclosure\" href=\"".$this->items[$i]->enclosure->url."\" type=\"".$this->items[$i]->enclosure->type."\" length=\"".$this->items[$i]->enclosure->length."\"";
+
+ if ($this->items[$i]->enclosure->language != "") {
+ $feed .= " xml:lang=\"".$this->items[$i]->enclosure->language."\" ";
+ }
+
+ if ($this->items[$i]->enclosure->title != "") {
+ $feed .= " title=\"".$this->items[$i]->enclosure->title."\" ";
+ }
+
+ $feed .= " /> \n";
+ }
+ if ($this->items[$i]->lat != "") {
+ $feed .= " <georss:point>".$this->items[$i]->lat." ".$this->items[$i]->long."</georss:point>\n";
+ }
+ $feed .= " </entry>\n";
+ }
+ $feed .= "</feed>\n";
+
+ return $feed;
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/FeedCreator.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/FeedCreator.php
new file mode 100644
index 0000000..907ca83
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/FeedCreator.php
@@ -0,0 +1,273 @@
+<?php
+
+/**
+ * FeedCreator is the abstract base implementation for concrete
+ * implementations that implement a specific format of syndication.
+ *
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ * @since 1.4
+ */
+abstract class FeedCreator extends HtmlDescribable
+{
+
+ /**
+ * Mandatory attributes of a feed.
+ */
+ public $title, $description, $link;
+ public $format = 'BASE';
+
+ /**
+ * Optional attributes of a feed.
+ */
+ public $syndicationURL, $image, $language, $copyright, $pubDate, $lastBuildDate, $editor, $editorEmail, $webmaster, $category, $docs, $ttl, $rating, $skipHours, $skipDays;
+
+ /**
+ * The url of the external xsl stylesheet used to format the naked rss feed.
+ * Ignored in the output when empty.
+ */
+ public $xslStyleSheet = "";
+
+
+ /** @var FeedItem[] */
+ public $items = Array();
+
+ /**
+ * Generator string
+ */
+ public $generator = "info@mypapit.net";
+
+ /**
+ * This feed's MIME content type.
+ *
+ * @since 1.4
+ * @access private
+ */
+ protected $contentType = "application/xml";
+
+ /**
+ * This feed's character encoding.
+ *
+ * @since 1.6.1
+ */
+ protected $encoding = "UTF-8"; //"ISO-8859-1";
+
+ /**
+ * Any additional elements to include as an associated array. All $key => $value pairs
+ * will be included unencoded in the feed in the form
+ * <$key>$value</$key>
+ * Again: No encoding will be used! This means you can invalidate or enhance the feed
+ * if $value contains markup. This may be abused to embed tags not implemented by
+ * the FeedCreator class used.
+ */
+ public $additionalElements = Array();
+
+ /**
+ * Adds a FeedItem to the feed.
+ *
+ * @param FeedItem $item The FeedItem to add to the feed.
+ */
+ public function addItem($item)
+ {
+ $this->items[] = $item;
+ }
+
+ /**
+ * Get the version string for the generator
+ *
+ * @return string
+ */
+ public function version()
+ {
+ return FEEDCREATOR_VERSION." (".$this->generator.")";
+ }
+
+ /**
+ * Truncates a string to a certain length at the most sensible point.
+ * First, if there's a '.' character near the end of the string, the string is truncated after this character.
+ * If there is no '.', the string is truncated after the last ' ' character.
+ * If the string is truncated, " ..." is appended.
+ * If the string is already shorter than $length, it is returned unchanged.
+ *
+ * @param string $string A string to be truncated.
+ * @param int $length the maximum length the string should be truncated to
+ * @return string the truncated string
+ */
+ public static function iTrunc($string, $length)
+ {
+ if (strlen($string) <= $length) {
+ return $string;
+ }
+
+ $pos = strrpos($string, ".");
+ if ($pos >= $length - 4) {
+ $string = substr($string, 0, $length - 4);
+ $pos = strrpos($string, ".");
+ }
+ if ($pos >= $length * 0.4) {
+ return substr($string, 0, $pos + 1)." ...";
+ }
+
+ $pos = strrpos($string, " ");
+ if ($pos >= $length - 4) {
+ $string = substr($string, 0, $length - 4);
+ $pos = strrpos($string, " ");
+ }
+ if ($pos >= $length * 0.4) {
+ return substr($string, 0, $pos)." ...";
+ }
+
+ return substr($string, 0, $length - 4)." ...";
+
+ }
+
+ /**
+ * Creates a comment indicating the generator of this feed.
+ * The format of this comment seems to be recognized by
+ * Syndic8.com.
+ */
+ protected function _createGeneratorComment()
+ {
+ return "<!-- generator=\"".FEEDCREATOR_VERSION."\" -->\n";
+ }
+
+ /**
+ * Creates a string containing all additional elements specified in
+ * $additionalElements.
+ *
+ * @param array $elements an associative array containing key => value pairs
+ * @param string $indentString a string that will be inserted before every generated line
+ * @return string the XML tags corresponding to $additionalElements
+ */
+ protected function _createAdditionalElements($elements, $indentString = "")
+ {
+ $ae = "";
+ if (is_array($elements)) {
+ foreach ($elements AS $key => $value) {
+ $ae .= $indentString."<$key>$value</$key>\n";
+ }
+ }
+
+ return $ae;
+ }
+
+ protected function _createStylesheetReferences()
+ {
+ $xml = "";
+ if (!empty($this->cssStyleSheet)) {
+ $xml .= "<?xml-stylesheet href=\"".$this->cssStyleSheet."\" type=\"text/css\"?>\n";
+ }
+ if (!empty($this->xslStyleSheet)) {
+ $xml .= "<?xml-stylesheet href=\"".$this->xslStyleSheet."\" type=\"text/xsl\"?>\n";
+ }
+
+ return $xml;
+ }
+
+ /**
+ * Builds the feed's text.
+ *
+ * @return string the feed's complete text
+ */
+ abstract public function createFeed();
+
+ /**
+ * Generate a filename for the feed cache file. The result will be $_SERVER["PHP_SELF"] with the extension changed
+ * to .xml. For example: echo $_SERVER["PHP_SELF"]."\n"; echo FeedCreator::_generateFilename(); would produce:
+ * /rss/latestnews.php
+ * latestnews.xml
+ *
+ * @return string the feed cache filename
+ * @since 1.4
+ * @access private
+ */
+ protected function _generateFilename()
+ {
+ $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+
+ return substr($fileInfo["basename"], 0, -(strlen($fileInfo["extension"]) + 1)).".xml";
+ }
+
+ /**
+ * Send given file to Browser
+ *
+ * @since 1.4
+ * @param string $filename
+ */
+ protected function _redirect($filename)
+ {
+ // attention, heavily-commented-out-area
+
+ // maybe use this in addition to file time checking
+ //header("Expires: ".date("r",time()+$this->_timeout));
+
+ /* no caching at all, doesn't seem to work as good:
+ header("Cache-Control: no-cache");
+ header("Pragma: no-cache");
+ */
+
+ // HTTP redirect, some feed readers' simple HTTP implementations don't follow it
+ //header("Location: ".$filename);
+
+ header("Content-Type: ".$this->contentType."; charset=".$this->encoding."; filename=".basename($filename));
+ if (preg_match('/\.(kml|gpx)$/', $filename)) {
+ header("Content-Disposition: attachment; filename=".basename($filename));
+ } else {
+ header("Content-Disposition: inline; filename=".basename($filename));
+ }
+ readfile($filename);
+ exit();
+ }
+
+ /**
+ * Turns on caching and checks if there is a recent version of this feed in the cache.
+ * If there is, an HTTP redirect header is sent.
+ * To effectively use caching, you should create the FeedCreator object and call this method
+ * before anything else, especially before you do the time consuming task to build the feed
+ * (web fetching, for example).
+ *
+ * @since 1.4
+ * @param string $filename optional the filename where a recent version of the feed is saved. If not specified,
+ * the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see
+ * _generateFilename()).
+ * @param int $timeout optional the timeout in seconds before a cached version is refreshed (defaults to
+ * 3600 = 1 hour)
+ */
+ public function useCached($filename = "", $timeout = 3600)
+ {
+ $this->_timeout = $timeout;
+ if ($filename == "") {
+ $filename = $this->_generateFilename();
+ }
+ if (file_exists($filename) AND (time() - filemtime($filename) < $timeout)) {
+ $this->_redirect($filename);
+ }
+ }
+
+ /**
+ * Saves this feed as a file on the local disk. After the file is saved, a redirect
+ * header may be sent to redirect the user to the newly created file.
+ *
+ * @since 1.4
+ * @param string $filename optional the filename where a recent version of the feed is saved. If not
+ * specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to .xml
+ * (see _generateFilename()).
+ * @param bool $displayContents optional send an HTTP redirect header or not. If true, the user will be
+ * automatically redirected to the created file.
+ */
+ public function saveFeed($filename = "", $displayContents = true)
+ {
+ if ($filename == "") {
+ $filename = $this->_generateFilename();
+ }
+ $feedFile = fopen($filename, "w+");
+ if ($feedFile) {
+ fputs($feedFile, $this->createFeed());
+ fclose($feedFile);
+ if ($displayContents) {
+ $this->_redirect($filename);
+ }
+ } else {
+ echo "<br /><b>Error creating feed file, please check write permissions.</b><br />";
+ }
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/GPXCreator.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/GPXCreator.php
new file mode 100644
index 0000000..367fb46
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/GPXCreator.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * GPXCreator is a FeedCreator that implements a GPX output, suitable for a GIS packages
+ *
+ * @since 1.7.6
+ * @author Barry Hunter <geo@barryhunter.co.uk>
+ */
+class GPXCreator extends FeedCreator
+{
+
+ /**
+ * GPXCreator constructor.
+ */
+ public function __construct()
+ {
+ $this->contentType = "text/xml";
+ $this->encoding = "utf-8";
+ }
+
+ /** @inheritdoc */
+ public function createFeed()
+ {
+ $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+ $feed .= $this->_createStylesheetReferences();
+ $feed .= "<gpx xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"1.0\"
+ creator=\"".FEEDCREATOR_VERSION."\"
+ xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\" xmlns=\"http://www.topografix.com/GPX/1/0\">\n";
+
+ $now = new FeedDate();
+ $feed .= "<desc>".FeedCreator::iTrunc(htmlspecialchars($this->title), 100)."</desc>
+ <author>{$http_host}</author>
+ <url>".htmlspecialchars($this->link)."</url>
+ <time>".htmlspecialchars($now->iso8601())."</time>
+ \n";
+
+ for ($i = 0; $i < count($this->items); $i++) {
+ $feed .= "<wpt lat=\"".$this->items[$i]->lat."\" lon=\"".$this->items[$i]->long."\">
+ <name>".substr(htmlspecialchars(strip_tags($this->items[$i]->title)), 0, 6)."</name>
+ <desc>".htmlspecialchars(strip_tags($this->items[$i]->title))."</desc>
+ <src>".htmlspecialchars($this->items[$i]->author)."</src>
+ <url>".htmlspecialchars($this->items[$i]->link)."</url>
+ </wpt>\n";
+ }
+ $feed .= "</gpx>\n";
+
+ return $feed;
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/HTMLCreator.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/HTMLCreator.php
new file mode 100644
index 0000000..e02a8d7
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/HTMLCreator.php
@@ -0,0 +1,161 @@
+<?php
+
+/**
+ * HTMLCreator is a FeedCreator that writes an HTML feed file to a specific
+ * location, overriding the createFeed method of the parent FeedCreator.
+ * The HTML produced can be included over http by scripting languages, or serve
+ * as the source for an IFrame.
+ * All output by this class is embedded in <div></div> tags to enable formatting
+ * using CSS.
+ *
+ * @author Pascal Van Hecke
+ * @since 1.7
+ */
+class HTMLCreator extends FeedCreator
+{
+
+ protected $contentType = "text/html";
+
+ /**
+ * Contains HTML to be output at the start of the feed's html representation.
+ */
+ public $header;
+
+ /**
+ * Contains HTML to be output at the end of the feed's html representation.
+ */
+ public $footer;
+
+ /**
+ * Contains HTML to be output between entries. A separator is only used in
+ * case of multiple entries.
+ */
+ public $separator;
+
+ /**
+ * Used to prefix the stylenames to make sure they are unique
+ * and do not clash with stylenames on the user's page.
+ */
+ public $stylePrefix;
+
+ /** @var bool Determines whether the links open in a new window or not. */
+ public $openInNewWindow = true;
+
+ /** @var string image alignments in output */
+ public $imageAlign = "right";
+
+ /**
+ * In case of very simple output you may want to get rid of the style tags,
+ * hence this variable. There's no equivalent on item level, but of course you can
+ * add strings to it while iterating over the items ($this->stylelessOutput .= ...)
+ * and when it is non-empty, ONLY the styleless output is printed, the rest is ignored
+ * in the function createFeed().
+ */
+ public $stylelessOutput = "";
+
+ /**
+ * Writes the HTML.
+ *
+ * @inheritdoc
+ */
+ public function createFeed()
+ {
+ // if there is styleless output, use the content of this variable and ignore the rest
+ if ($this->stylelessOutput != "") {
+ return $this->stylelessOutput;
+ }
+
+ //if no stylePrefix is set, generate it yourself depending on the script name
+ if ($this->stylePrefix == "") {
+ $this->stylePrefix = str_replace(".", "_", $this->_generateFilename())."_";
+ }
+
+ //set an openInNewWindow_token_to be inserted or not
+ if ($this->openInNewWindow) {
+ $targetInsert = " class='target_blank'";
+ } else {
+ $targetInsert = '';
+ }
+
+ // use this array to put the lines in and implode later with "document.write" javascript
+ $feedArray = array();
+ if ($this->image != null) {
+ $imageStr = "<a href='".$this->image->link."'".$targetInsert.">".
+ "<img src='".$this->image->url."' border='0' alt='".
+ FeedCreator::iTrunc(htmlspecialchars($this->image->title), 100).
+ "' align='".$this->imageAlign."' ";
+ if ($this->image->width) {
+ $imageStr .= " width='".$this->image->width."' ";
+ }
+ if ($this->image->height) {
+ $imageStr .= " height='".$this->image->height."' ";
+ }
+ $imageStr .= "/></a>";
+ $feedArray[] = $imageStr;
+ }
+
+ if ($this->title) {
+ $feedArray[] = "<div class='".$this->stylePrefix."title'><a href='".$this->link."' ".$targetInsert." class='".$this->stylePrefix."title'>".
+ FeedCreator::iTrunc(htmlspecialchars($this->title), 100)."</a></div>";
+ }
+ if ($this->getDescription()) {
+ $feedArray[] = "<div class='".$this->stylePrefix."description'>".
+ str_replace("]]>", "", str_replace("<![CDATA[", "", $this->getDescription())).
+ "</div>";
+ }
+
+ if ($this->header) {
+ $feedArray[] = "<div class='".$this->stylePrefix."header'>".$this->header."</div>";
+ }
+
+ for ($i = 0; $i < count($this->items); $i++) {
+ if ($this->separator and $i > 0) {
+ $feedArray[] = "<div class='".$this->stylePrefix."separator'>".$this->separator."</div>";
+ }
+
+ if ($this->items[$i]->title) {
+ if ($this->items[$i]->link) {
+ $feedArray[] =
+ "<div class='".$this->stylePrefix."item_title'><a href='".$this->items[$i]->link."' class='".$this->stylePrefix.
+ "item_title'".$targetInsert.">".FeedCreator::iTrunc(
+ htmlspecialchars(strip_tags($this->items[$i]->title)),
+ 100
+ ).
+ "</a></div>";
+ } else {
+ $feedArray[] =
+ "<div class='".$this->stylePrefix."item_title'>".
+ FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)), 100).
+ "</div>";
+ }
+ }
+ if ($this->items[$i]->getDescription()) {
+ $feedArray[] =
+ "<div class='".$this->stylePrefix."item_description'>".
+ str_replace("]]>", "", str_replace("<![CDATA[", "", $this->items[$i]->getDescription())).
+ "</div>";
+ }
+ }
+ if ($this->footer) {
+ $feedArray[] = "<div class='".$this->stylePrefix."footer'>".$this->footer."</div>";
+ }
+
+ $feed = "".join($feedArray, "\r\n");
+
+ return $feed;
+ }
+
+ /**
+ * Overrides parent to produce .html extensions
+ *
+ * @return string the feed cache filename
+ * @since 1.4
+ * @access private
+ */
+ protected function _generateFilename()
+ {
+ $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+
+ return substr($fileInfo["basename"], 0, -(strlen($fileInfo["extension"]) + 1)).".html";
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/JSCreator.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/JSCreator.php
new file mode 100644
index 0000000..5aa31fa
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/JSCreator.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * JSCreator is a class that writes a js file to a specific
+ * location, overriding the createFeed method of the parent HTMLCreator.
+ *
+ * @author Pascal Van Hecke
+ */
+class JSCreator extends HTMLCreator
+{
+ protected $contentType = "text/javascript";
+
+ /**
+ * writes the javascript
+ *
+ * @inheritdoc
+ */
+ public function createFeed()
+ {
+ $feed = parent::createFeed();
+ $feedArray = explode("\n", $feed);
+
+ $jsFeed = "";
+ foreach ($feedArray as $value) {
+ $jsFeed .= "document.write('".trim(addslashes($value))."');\n";
+ }
+
+ return $jsFeed;
+ }
+
+ /**
+ * Overrides parent to produce .js extensions
+ *
+ * @return string the feed cache filename
+ * @since 1.4
+ * @access private
+ */
+ protected function _generateFilename()
+ {
+ $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+
+ return substr($fileInfo["basename"], 0, -(strlen($fileInfo["extension"]) + 1)).".js";
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/KMLCreator.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/KMLCreator.php
new file mode 100644
index 0000000..31073d8
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/KMLCreator.php
@@ -0,0 +1,106 @@
+<?php
+
+/**
+ * KMLCreator is a FeedCreator that implements a KML output, suitable for Keyhole/Google Earth
+ *
+ * @since 1.7.3
+ * @author Barry Hunter <geo@barryhunter.co.uk>
+ */
+class KMLCreator extends FeedCreator
+{
+
+ /**
+ * KMLCreator constructor.
+ */
+ public function __construct()
+ {
+ $this->contentType = "application/vnd.google-earth.kml+xml";
+ $this->encoding = "utf-8";
+ }
+
+ /** @inheritdoc */
+ public function createFeed()
+ {
+ $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+ $feed .= $this->_createStylesheetReferences();
+ $feed .= "<kml xmlns=\"http://earth.google.com/kml/2.0\">\n";
+ $feed .= "<Document>\n";
+ if ($_GET['LinkControl']) {
+ $feed .= "<NetworkLinkControl>\n<minRefreshPeriod>3600</minRefreshPeriod>\n</NetworkLinkControl>\n";
+ }
+ if (!empty($_GET['simple']) && count($this->items) > 0) {
+ $feed .= "<Style id=\"defaultIcon\">
+ <LabelStyle>
+ <scale>0</scale>
+ </LabelStyle>
+ </Style>
+ <Style id=\"hoverIcon\">".
+ (($this->items[0]->thumb != "") ? "
+ <IconStyle id=\"hoverIcon\">
+ <scale>2.1</scale>
+ </IconStyle>" : '')."
+ </Style>
+ <StyleMap id=\"defaultStyle\">
+ <Pair>
+ <key>normal</key>
+ <styleUrl>#defaultIcon</styleUrl>
+ </Pair>
+ <Pair>
+ <key>highlight</key>
+ <styleUrl>#hoverIcon</styleUrl>
+ </Pair>
+ </StyleMap>
+ ";
+ $style = "#defaultStyle";
+ } else {
+ $style = "root://styleMaps#default?iconId=0x307";
+ }
+ $feed .= "<Folder>\n";
+ $feed .= " <name>".FeedCreator::iTrunc(htmlspecialchars($this->title), 100)."</name>
+ <description>".$this->getDescription()."</description>
+ <visibility>1</visibility>\n";
+ $this->truncSize = 500;
+
+ for ($i = 0; $i < count($this->items); $i++) {
+ //added here beucase description gets auto surrounded by cdata
+ $this->items[$i]->description = "<b>".$this->items[$i]->description."</b><br/>
+ ".$this->items[$i]->licence."
+ <br/><br/><a href=\"".htmlspecialchars($this->items[$i]->link)."\">View Online</a>";
+
+ $feed .= "
+ <Placemark>
+ <description>".$this->items[$i]->getDescription(true)."</description>
+ <name>".FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)), 100)."</name>
+ <visibility>1</visibility>
+ <Point>
+ <coordinates>".$this->items[$i]->long.",".$this->items[$i]->lat.",25</coordinates>
+ </Point>";
+ if ($this->items[$i]->thumb != "") {
+ $feed .= "
+ <styleUrl>$style</styleUrl>
+ <Style>
+ <icon>".htmlspecialchars($this->items[$i]->thumb)."</icon>
+ </Style>";
+ }
+ $feed .= "
+ </Placemark>\n";
+ }
+ $feed .= "</Folder>\n</Document>\n</kml>\n";
+
+ return $feed;
+ }
+
+ /**
+ * Generate a filename for the feed cache file. Overridden from FeedCreator to prevent XML data types.
+ *
+ * @return string the feed cache filename
+ * @since 1.4
+ * @access private
+ */
+ protected function _generateFilename()
+ {
+ $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+
+ return substr($fileInfo["basename"], 0, -(strlen($fileInfo["extension"]) + 1)).".kml";
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/MBOXCreator.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/MBOXCreator.php
new file mode 100644
index 0000000..9198f1f
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/MBOXCreator.php
@@ -0,0 +1,110 @@
+<?php
+
+/**
+ * MBOXCreator is a FeedCreator that implements the mbox format
+ * as described in http://www.qmail.org/man/man5/mbox.html
+ *
+ * @since 1.3
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class MBOXCreator extends FeedCreator
+{
+
+ /**
+ * MBOXCreator constructor.
+ */
+ public function __construct()
+ {
+ $this->contentType = "text/plain";
+ $this->encoding = "ISO-8859-15";
+ }
+
+ /**
+ * Quoted Printable encoding
+ *
+ * @param string $input
+ * @param int $line_max wrap lines after these number of characters
+ * @return string
+ */
+ protected function qp_enc($input = "", $line_max = 76)
+ {
+ $hex = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
+ $lines = preg_split("/(?:\r\n|\r|\n)/", $input);
+ $eol = "\r\n";
+ $escape = "=";
+ $output = "";
+ foreach ($lines as $line) {
+ $linlen = strlen($line);
+ $newline = "";
+ for ($i = 0; $i < $linlen; $i++) {
+ $c = substr($line, $i, 1);
+ $dec = ord($c);
+ if (($dec == 32) && ($i == ($linlen - 1))) { // convert space at eol only
+ $c = "=20";
+ } elseif (($dec == 61) || ($dec < 32) || ($dec > 126)) { // always encode "\t", which is *not* required
+ $h2 = floor($dec / 16);
+ $h1 = floor($dec % 16);
+ $c = $escape.$hex["$h2"].$hex["$h1"];
+ }
+ if ((strlen($newline) + strlen($c)) >= $line_max) { // CRLF is not counted
+ $output .= $newline.$escape.$eol; // soft line break; " =\r\n" is okay
+ $newline = "";
+ }
+ $newline .= $c;
+ } // end of for
+ $output .= $newline.$eol;
+ }
+
+ return trim($output);
+ }
+
+ /**
+ * Builds the MBOX contents.
+ *
+ * @inheritdoc
+ */
+ public function createFeed()
+ {
+ $feed = '';
+ for ($i = 0; $i < count($this->items); $i++) {
+ if ($this->items[$i]->author != "") {
+ $from = $this->items[$i]->author;
+ } else {
+ $from = $this->title;
+ }
+ $itemDate = new FeedDate($this->items[$i]->date);
+ $feed .= "From ".strtr(MBOXCreator::qp_enc($from), " ", "_")." ".date(
+ "D M d H:i:s Y",
+ $itemDate->unix()
+ )."\n";
+ $feed .= "Content-Type: text/plain;\n";
+ $feed .= " charset=\"".$this->encoding."\"\n";
+ $feed .= "Content-Transfer-Encoding: quoted-printable\n";
+ $feed .= "Content-Type: text/plain\n";
+ $feed .= "From: \"".MBOXCreator::qp_enc($from)."\"\n";
+ $feed .= "Date: ".$itemDate->rfc822()."\n";
+ $feed .= "Subject: ".MBOXCreator::qp_enc(FeedCreator::iTrunc($this->items[$i]->title, 100))."\n";
+ $feed .= "\n";
+ $body = chunk_split(MBOXCreator::qp_enc($this->items[$i]->description));
+ $feed .= preg_replace("~\nFrom ([^\n]*)(\n?)~", "\n>From $1$2\n", $body);
+ $feed .= "\n";
+ $feed .= "\n";
+ }
+
+ return $feed;
+ }
+
+ /**
+ * Generate a filename for the feed cache file. Overridden from FeedCreator to prevent XML data types.
+ *
+ * @return string the feed cache filename
+ * @since 1.4
+ * @access private
+ */
+ protected function _generateFilename()
+ {
+ $fileInfo = pathinfo($_SERVER["PHP_SELF"]);
+
+ return substr($fileInfo["basename"], 0, -(strlen($fileInfo["extension"]) + 1)).".mbox";
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/OPMLCreator.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/OPMLCreator.php
new file mode 100644
index 0000000..b795558
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/OPMLCreator.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * OPMLCreator is a FeedCreator that implements OPML 1.0.
+ *
+ * @see http://opml.scripting.com/spec
+ * @author Dirk Clemens, Kai Blankenhorn
+ * @since 1.5
+ */
+class OPMLCreator extends FeedCreator
+{
+
+ /**
+ * OPMLCreator constructor.
+ */
+ public function __construct()
+ {
+ $this->encoding = "utf-8";
+ }
+
+ /** @inheritdoc */
+ public function createFeed()
+ {
+ $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+ $feed .= $this->_createGeneratorComment();
+ $feed .= $this->_createStylesheetReferences();
+ $feed .= "<opml xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n";
+ $feed .= " <head>\n";
+ $feed .= " <title>".htmlspecialchars($this->title)."</title>\n";
+ if ($this->pubDate != "") {
+ $date = new FeedDate($this->pubDate);
+ $feed .= " <dateCreated>".$date->rfc822()."</dateCreated>\n";
+ }
+ if ($this->lastBuildDate != "") {
+ $date = new FeedDate($this->lastBuildDate);
+ $feed .= " <dateModified>".$date->rfc822()."</dateModified>\n";
+ }
+ if ($this->editor != "") {
+ $feed .= " <ownerName>".$this->editor."</ownerName>\n";
+ }
+ if ($this->editorEmail != "") {
+ $feed .= " <ownerEmail>".$this->editorEmail."</ownerEmail>\n";
+ }
+ $feed .= " </head>\n";
+ $feed .= " <body>\n";
+ for ($i = 0; $i < count($this->items); $i++) {
+ $feed .= " <outline type=\"rss\" ";
+ $title = htmlspecialchars(strip_tags(strtr($this->items[$i]->title, "\n\r", " ")));
+ $feed .= " title=\"".$title."\"";
+ $feed .= " text=\"".$title."\"";
+
+ if (isset($this->items[$i]->xmlUrl)) {
+ $feed .= " xmlUrl=\"".htmlspecialchars($this->items[$i]->xmlUrl)."\"";
+ }
+
+ if (isset($this->items[$i]->link)) {
+ $feed .= " url=\"".htmlspecialchars($this->items[$i]->link)."\"";
+ }
+
+ $feed .= "/>\n";
+ }
+ $feed .= " </body>\n";
+ $feed .= "</opml>\n";
+
+ return $feed;
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/PHPCreator.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/PHPCreator.php
new file mode 100644
index 0000000..fe61a3f
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/PHPCreator.php
@@ -0,0 +1,56 @@
+<?php
+
+/**
+ * PHPCreator is a FeedCreator that implements a PHP output, suitable for an include
+ *
+ * @since 1.7.3
+ * @author Barry Hunter <geo@barryhunter.co.uk>
+ */
+class PHPCreator extends FeedCreator
+{
+
+ /**
+ * PHPCreator constructor.
+ */
+ public function __construct()
+ {
+ $this->contentType = "text/plain";
+ $this->encoding = "utf-8";
+ }
+
+ /** @inheritdoc */
+ public function createFeed()
+ {
+ $feed = "<?php\n";
+ $feed .= "class FeedItem {}\n";
+ $feed .= " \$feedTitle='".addslashes(FeedCreator::iTrunc(htmlspecialchars($this->title), 100))."';\n";
+ $this->truncSize = 500;
+ $feed .= " \$feedDescription='".addslashes($this->getDescription())."';\n";
+ $feed .= " \$feedLink='".$this->link."';\n";
+ $feed .= " \$feedItem = array();\n";
+ for ($i = 0; $i < count($this->items); $i++) {
+ $feed .= " \$feedItem[$i] = new FeedItem();\n";
+ if ($this->items[$i]->guid != "") {
+ $feed .= " \$feedItem[$i]->id='".htmlspecialchars($this->items[$i]->guid)."';\n";
+ }
+ $feed .= " \$feedItem[$i]->title='".addslashes(
+ FeedCreator::iTrunc(htmlspecialchars(strip_tags($this->items[$i]->title)), 100)
+ )."';\n";
+ $feed .= " \$feedItem[$i]->link='".htmlspecialchars($this->items[$i]->link)."';\n";
+ $feed .= " \$feedItem[$i]->date=".htmlspecialchars($this->items[$i]->date).";\n";
+ if ($this->items[$i]->author != "") {
+ $feed .= " \$feedItem[$i]->author='".htmlspecialchars($this->items[$i]->author)."';\n";
+ if ($this->items[$i]->authorEmail != "") {
+ $feed .= " \$feedItem[$i]->authorEmail='".$this->items[$i]->authorEmail."';\n";
+ }
+ }
+ $feed .= " \$feedItem[$i]->description='".addslashes($this->items[$i]->getDescription())."';\n";
+ if ($this->items[$i]->thumb != "") {
+ $feed .= " \$feedItem[$i]->thumbURL='".htmlspecialchars($this->items[$i]->thumb)."';\n";
+ }
+ }
+ $feed .= "?>\n";
+
+ return $feed;
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/PIECreator01.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/PIECreator01.php
new file mode 100644
index 0000000..2f069aa
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/PIECreator01.php
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * PIECreator01 is a FeedCreator that implements the emerging PIE specification,
+ * as in http://intertwingly.net/wiki/pie/Syntax.
+ *
+ * @deprecated
+ * @since 1.3
+ * @author Scott Reynen <scott@randomchaos.com> and Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class PIECreator01 extends FeedCreator
+{
+
+ /**
+ * PIECreator01 constructor.
+ */
+ public function __construct()
+ {
+ $this->encoding = "utf-8";
+ }
+
+ /** @inheritdoc */
+ public function createFeed()
+ {
+ $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+ $feed .= $this->_createStylesheetReferences();
+ $feed .= "<feed version=\"0.1\" xmlns=\"http://example.com/newformat#\">\n";
+ $feed .= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->title), 100)."</title>\n";
+ $this->truncSize = 500;
+ $feed .= " <subtitle>".$this->getDescription()."</subtitle>\n";
+ $feed .= " <link>".$this->link."</link>\n";
+ for ($i = 0; $i < count($this->items); $i++) {
+ $feed .= " <entry>\n";
+ $feed .= " <title>".FeedCreator::iTrunc(
+ htmlspecialchars(strip_tags($this->items[$i]->title)),
+ 100
+ )."</title>\n";
+ $feed .= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
+ $itemDate = new FeedDate($this->items[$i]->date);
+ $feed .= " <created>".htmlspecialchars($itemDate->iso8601())."</created>\n";
+ $feed .= " <issued>".htmlspecialchars($itemDate->iso8601())."</issued>\n";
+ $feed .= " <modified>".htmlspecialchars($itemDate->iso8601())."</modified>\n";
+ $feed .= " <id>".htmlspecialchars($this->items[$i]->guid)."</id>\n";
+ if ($this->items[$i]->author != "") {
+ $feed .= " <author>\n";
+ $feed .= " <name>".htmlspecialchars($this->items[$i]->author)."</name>\n";
+ if ($this->items[$i]->authorEmail != "") {
+ $feed .= " <email>".$this->items[$i]->authorEmail."</email>\n";
+ }
+ $feed .= " </author>\n";
+ }
+ $feed .= " <content type=\"text/html\" xml:lang=\"en-us\">\n";
+ $feed .= " <div xmlns=\"http://www.w3.org/1999/xhtml\">".$this->items[$i]->getDescription(
+ )."</div>\n";
+ $feed .= " </content>\n";
+ $feed .= " </entry>\n";
+ }
+ $feed .= "</feed>\n";
+
+ return $feed;
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator091.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator091.php
new file mode 100644
index 0000000..7b13acd
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator091.php
@@ -0,0 +1,197 @@
+<?php
+
+/**
+ * RSSCreator091 is a FeedCreator that implements RSS 0.91 Spec, revision 3.
+ *
+ * @see http://my.netscape.com/publish/formats/rss-spec-0.91.html
+ * @since 1.3
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class RSSCreator091 extends FeedCreator
+{
+
+ /** @var string Stores this RSS feed's version number. */
+ protected $RSSVersion;
+
+ /**
+ * RSSCreator091 constructor.
+ */
+ function __construct()
+ {
+ $this->_setRSSVersion("0.91");
+ $this->contentType = "application/rss+xml";
+ }
+
+ /**
+ * Sets this RSS feed's version number.
+ *
+ * @param string $version
+ */
+ protected function _setRSSVersion($version)
+ {
+ $this->RSSVersion = $version;
+ }
+
+ /** @inheritdoc */
+ public function createFeed()
+ {
+ $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+ $feed .= $this->_createGeneratorComment();
+ $feed .= $this->_createStylesheetReferences();
+ $feed .= "<rss version=\"".$this->RSSVersion."\"";
+
+ if (count($this->items) > 0
+ && !empty($this->items[0]->lat)
+ ) {
+ $feed .= " xmlns:georss=\"http://www.georss.org/georss/\"\n";
+ }
+ if (count($this->items) > 0
+ && isset($this->items[0]->additionalElements['xcal:dtstart'])
+ ) {
+ $feed .= " xmlns:xcal=\"urn:ietf:params:xml:ns:xcal\"\n";
+ }
+ $feed .= ">\n";
+ if ($this->format == 'BASE') {
+ $feed .= " <channel xmlns:g=\"http://base.google.com/ns/1.0\">\n";
+ } else {
+ $feed .= " <channel>\n";
+ }
+ $feed .= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->title), 100)."</title>\n";
+ $this->descriptionTruncSize = 500;
+ $feed .= " <description>".$this->getDescription()."</description>\n";
+ $feed .= " <link>".$this->link."</link>\n";
+ $now = new FeedDate();
+ $feed .= " <lastBuildDate>".htmlspecialchars(
+ $this->lastBuildDate ?: $now->rfc822()
+ )."</lastBuildDate>\n";
+ $feed .= " <generator>".FEEDCREATOR_VERSION."</generator>\n";
+
+ if ($this->image != null) {
+ $feed .= " <image>\n";
+ $feed .= " <url>".$this->image->url."</url>\n";
+ $feed .= " <title>".FeedCreator::iTrunc(htmlspecialchars($this->image->title), 100)."</title>\n";
+ $feed .= " <link>".$this->image->link."</link>\n";
+ if ($this->image->width != "") {
+ $feed .= " <width>".$this->image->width."</width>\n";
+ }
+ if ($this->image->height != "") {
+ $feed .= " <height>".$this->image->height."</height>\n";
+ }
+ if ($this->image->description != "") {
+ $feed .= " <description>".htmlspecialchars($this->image->description)."</description>\n";
+ }
+ $feed .= " </image>\n";
+ }
+ if ($this->language != "") {
+ $feed .= " <language>".$this->language."</language>\n";
+ }
+ if ($this->copyright != "") {
+ $feed .= " <copyright>".FeedCreator::iTrunc(
+ htmlspecialchars($this->copyright),
+ 100
+ )."</copyright>\n";
+ }
+ if ($this->editor != "") {
+ $feed .= " <managingEditor>".FeedCreator::iTrunc(
+ htmlspecialchars($this->editor),
+ 100
+ )."</managingEditor>\n";
+ }
+ if ($this->webmaster != "") {
+ $feed .= " <webMaster>".FeedCreator::iTrunc(
+ htmlspecialchars($this->webmaster),
+ 100
+ )."</webMaster>\n";
+ }
+ if ($this->pubDate != "") {
+ $pubDate = new FeedDate($this->pubDate);
+ $feed .= " <pubDate>".htmlspecialchars($pubDate->rfc822())."</pubDate>\n";
+ }
+ if ($this->category != "") {
+ $feed .= " <category>".htmlspecialchars($this->category)."</category>\n";
+ }
+ if ($this->docs != "") {
+ $feed .= " <docs>".FeedCreator::iTrunc(htmlspecialchars($this->docs), 500)."</docs>\n";
+ }
+ if ($this->ttl != "") {
+ $feed .= " <ttl>".htmlspecialchars($this->ttl)."</ttl>\n";
+ }
+ if ($this->rating != "") {
+ $feed .= " <rating>".FeedCreator::iTrunc(htmlspecialchars($this->rating), 500)."</rating>\n";
+ }
+ if ($this->skipHours != "") {
+ $feed .= " <skipHours>".htmlspecialchars($this->skipHours)."</skipHours>\n";
+ }
+ if ($this->skipDays != "") {
+ $feed .= " <skipDays>".htmlspecialchars($this->skipDays)."</skipDays>\n";
+ }
+ $feed .= $this->_createAdditionalElements($this->additionalElements, " ");
+
+ for ($i = 0; $i < count($this->items); $i++) {
+ $feed .= " <item>\n";
+ $feed .= " <title>".FeedCreator::iTrunc(
+ htmlspecialchars(strip_tags($this->items[$i]->title)),
+ 100
+ )."</title>\n";
+ $feed .= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
+ $feed .= " <description>".$this->items[$i]->getDescription()."</description>\n";
+
+ $creator = $this->getAuthor($this->items[$i]->author, $this->items[$i]->authorEmail);
+ if ($creator) {
+ $feed .= " <author>".htmlspecialchars($creator)."</author>\n";
+ }
+
+ /*
+ // on hold
+ if ($this->items[$i]->source!="") {
+ $feed.= " <source>".htmlspecialchars($this->items[$i]->source)."</source>\n";
+ }
+ */
+ if ($this->items[$i]->lat != "") {
+ $feed .= " <georss:point>".$this->items[$i]->lat." ".$this->items[$i]->long."</georss:point>\n";
+ }
+ if (is_array($this->items[$i]->category)) {
+ foreach ($this->items[$i]->category as $cat) {
+ $feed .= " <category>".htmlspecialchars($cat)."</category>\n";
+ }
+ } else {
+ if ($this->items[$i]->category != "") {
+ $feed .= " <category>".htmlspecialchars($this->items[$i]->category)."</category>\n";
+ }
+ }
+ if ($this->items[$i]->comments != "") {
+ $feed .= " <comments>".htmlspecialchars($this->items[$i]->comments)."</comments>\n";
+ }
+ if ($this->items[$i]->date != "") {
+ $itemDate = new FeedDate($this->items[$i]->date);
+ $feed .= " <pubDate>".htmlspecialchars($itemDate->rfc822())."</pubDate>\n";
+ }
+ if ($this->items[$i]->guid != "") {
+ $feed .= " <guid>".htmlspecialchars($this->items[$i]->guid)."</guid>\n";
+ }
+ if ($this->items[$i]->thumb != "") {
+ $feed .= " <g:image_link>".htmlspecialchars($this->items[$i]->thumb)."</g:image_link>\n";
+ }
+ $feed .= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
+ $feed .= " </item>\n";
+ }
+ $feed .= " </channel>\n";
+ $feed .= "</rss>\n";
+
+ return $feed;
+ }
+
+ /**
+ * Compose the RSS-0.91 and RSS-2.0 author field.
+ *
+ * @author Joe Lapp <joe.lapp@pobox.com>
+ */
+ function getAuthor($author, $email)
+ {
+ if ($author && $email) {
+ return $email.' ('.$author.')';
+ }
+
+ return $email;
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator10.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator10.php
new file mode 100644
index 0000000..8d0c1ca
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator10.php
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * RSSCreator10 is a FeedCreator that implements RDF Site Summary (RSS) 1.0.
+ *
+ * @see http://www.purl.org/rss/1.0/
+ * @since 1.3
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class RSSCreator10 extends FeedCreator
+{
+
+ /** @inheritdoc */
+ public function createFeed()
+ {
+ $feed = "<?xml version=\"1.0\" encoding=\"".$this->encoding."\"?>\n";
+ $feed .= $this->_createGeneratorComment();
+ if (empty($this->cssStyleSheet)) {
+ $this->cssStyleSheet = "http://www.w3.org/2000/08/w3c-synd/style.css";
+ }
+ $feed .= $this->_createStylesheetReferences();
+ $feed .= "<rdf:RDF\n";
+ $feed .= " xmlns=\"http://purl.org/rss/1.0/\"\n";
+ $feed .= " xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n";
+ $feed .= " xmlns:slash=\"http://purl.org/rss/1.0/modules/slash/\"\n";
+ if (!empty($this->items[0]->thumb)) {
+ $feed .= " xmlns:photo=\"http://www.pheed.com/pheed/\"\n";
+ }
+ if (!empty($this->items[0]->lat)) {
+ $feed .= " xmlns:georss=\"http://www.georss.org/georss\"\n";
+ }
+ $feed .= " xmlns:dc=\"http://purl.org/dc/elements/1.1/\">\n";
+ $feed .= " <channel rdf:about=\"".$this->syndicationURL."\">\n";
+ $feed .= " <title>".htmlspecialchars($this->title)."</title>\n";
+ $feed .= " <description>".htmlspecialchars($this->description)."</description>\n";
+ $feed .= " <link>".$this->link."</link>\n";
+ if ($this->image != null) {
+ $feed .= " <image rdf:resource=\"".$this->image->url."\" />\n";
+ }
+ $now = new FeedDate();
+ $feed .= " <dc:date>".htmlspecialchars($now->iso8601())."</dc:date>\n";
+ $feed .= " <items>\n";
+ $feed .= " <rdf:Seq>\n";
+ for ($i = 0; $i < count($this->items); $i++) {
+ $feed .= " <rdf:li rdf:resource=\"".htmlspecialchars($this->items[$i]->link)."\"/>\n";
+ }
+ $feed .= " </rdf:Seq>\n";
+ $feed .= " </items>\n";
+ $feed .= " </channel>\n";
+ if ($this->image != null) {
+ $feed .= " <image rdf:about=\"".$this->image->url."\">\n";
+ $feed .= " <title>".$this->image->title."</title>\n";
+ $feed .= " <link>".$this->image->link."</link>\n";
+ $feed .= " <url>".$this->image->url."</url>\n";
+ $feed .= " </image>\n";
+ }
+ $feed .= $this->_createAdditionalElements($this->additionalElements, " ");
+
+ for ($i = 0; $i < count($this->items); $i++) {
+ $feed .= " <item rdf:about=\"".htmlspecialchars($this->items[$i]->link)."\">\n";
+ $feed .= " <dc:format>text/html</dc:format>\n";
+ if ($this->items[$i]->date != null) {
+ $itemDate = new FeedDate($this->items[$i]->date);
+ $feed .= " <dc:date>".htmlspecialchars($itemDate->iso8601())."</dc:date>\n";
+ }
+ if ($this->items[$i]->source != "") {
+ $feed .= " <dc:source>".htmlspecialchars($this->items[$i]->source)."</dc:source>\n";
+ }
+ $creator = $this->getAuthor($this->items[$i]->author, $this->items[$i]->authorEmail);
+ if ($creator) {
+ $feed .= " <dc:creator>".htmlspecialchars($creator)."</dc:creator>\n";
+ }
+ if ($this->items[$i]->lat != "") {
+ $feed .= " <georss:point>".$this->items[$i]->lat." ".$this->items[$i]->long."</georss:point>\n";
+ }
+ if ($this->items[$i]->thumb != "") {
+ $feed .= " <photo:thumbnail>".htmlspecialchars($this->items[$i]->thumb)."</photo:thumbnail>\n";
+ }
+ $feed .= " <title>".htmlspecialchars(
+ strip_tags(strtr($this->items[$i]->title, "\n\r", " "))
+ )."</title>\n";
+ $feed .= " <link>".htmlspecialchars($this->items[$i]->link)."</link>\n";
+ $feed .= " <description>".htmlspecialchars($this->items[$i]->description)."</description>\n";
+ $feed .= $this->_createAdditionalElements($this->items[$i]->additionalElements, " ");
+ $feed .= " </item>\n";
+ }
+ $feed .= "</rdf:RDF>\n";
+
+ return $feed;
+ }
+
+ /**
+ * Compose the RSS-1.0 author field.
+ *
+ * @author Joe Lapp <joe.lapp@pobox.com>
+ * @param string $author
+ * @param string $email
+ * @return string
+ */
+ protected function getAuthor($author, $email)
+ {
+ if ($author) {
+ if ($email) {
+ return $author.' ('.$email.')';
+ }
+
+ return $author;
+ }
+
+ return $email;
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator20.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator20.php
new file mode 100644
index 0000000..fb39efe
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Creator/RSSCreator20.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * RSSCreator20 is a FeedCreator that implements RDF Site Summary (RSS) 2.0.
+ *
+ * @see http://backend.userland.com/rss
+ * @since 1.3
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class RSSCreator20 extends RSSCreator091
+{
+
+ /**
+ * RSSCreator20 constructor.
+ */
+ public function __construct()
+ {
+ parent::__construct();
+ parent::_setRSSVersion("2.0");
+ }
+
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedDate.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedDate.php
new file mode 100644
index 0000000..249f96c
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedDate.php
@@ -0,0 +1,124 @@
+<?php
+
+/**
+ * FeedDate is an internal class that stores a date for a feed or feed item.
+ * Usually, you won't need to use this.
+ */
+class FeedDate
+{
+ protected $unix;
+
+ /**
+ * Creates a new instance of FeedDate representing a given date.
+ * Accepts RFC 822, ISO 8601 date formats as well as unix time stamps.
+ *
+ * @param mixed $dateString optional the date this FeedDate will represent. If not specified, the current date and
+ * time is used.
+ */
+ public function __construct($dateString = "")
+ {
+ if ($dateString == "") {
+ $dateString = date("r");
+ }
+
+ if (is_integer($dateString)) {
+ $this->unix = $dateString;
+
+ return;
+ }
+ $tzOffset = 0;
+ if (preg_match(
+ "~(?:(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun),\\s+)?(\\d{1,2})\\s+([a-zA-Z]{3})\\s+(\\d{4})\\s+(\\d{2}):(\\d{2}):(\\d{2})\\s+(.*)~",
+ $dateString,
+ $matches
+ )) {
+ $months = Array(
+ "Jan" => 1,
+ "Feb" => 2,
+ "Mar" => 3,
+ "Apr" => 4,
+ "May" => 5,
+ "Jun" => 6,
+ "Jul" => 7,
+ "Aug" => 8,
+ "Sep" => 9,
+ "Oct" => 10,
+ "Nov" => 11,
+ "Dec" => 12,
+ );
+ $this->unix = mktime($matches[4], $matches[5], $matches[6], $months[$matches[2]], $matches[1], $matches[3]);
+ if (substr($matches[7], 0, 1) == '+' OR substr($matches[7], 0, 1) == '-') {
+ $tzOffset = (((int)substr($matches[7], 0, 3) * 60) + (int)substr($matches[7], -2)) * 60;
+ } else {
+ if (strlen($matches[7]) == 1) {
+ $oneHour = 3600;
+ $ord = ord($matches[7]);
+ if ($ord < ord("M")) {
+ $tzOffset = (ord("A") - $ord - 1) * $oneHour;
+ } elseif ($ord >= ord("M") AND $matches[7] != "Z") {
+ $tzOffset = ($ord - ord("M")) * $oneHour;
+ } elseif ($matches[7] == "Z") {
+ $tzOffset = 0;
+ }
+ }
+ switch ($matches[7]) {
+ case "UT":
+ case "GMT":
+ $tzOffset = 0;
+ }
+ }
+ $this->unix += $tzOffset;
+
+ return;
+ }
+ if (preg_match("~(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(.*)~", $dateString, $matches)) {
+ $this->unix = mktime($matches[4], $matches[5], $matches[6], $matches[2], $matches[3], $matches[1]);
+ if (substr($matches[7], 0, 1) == '+' OR substr($matches[7], 0, 1) == '-') {
+ $tzOffset = (((int)substr($matches[7], 0, 3) * 60) + (int)substr($matches[7], -2)) * 60;
+ } else {
+ if ($matches[7] == "Z") {
+ $tzOffset = 0;
+ }
+ }
+ $this->unix += $tzOffset;
+
+ return;
+ }
+ $this->unix = 0;
+ }
+
+ /**
+ * Gets the date stored in this FeedDate as an RFC 822 date.
+ *
+ * @return string a date in RFC 822 format
+ */
+ public function rfc822()
+ {
+ //return gmdate("r",$this->unix);
+ $date = gmdate("D, d M Y H:i:s O", $this->unix);
+
+ return $date;
+ }
+
+ /**
+ * Gets the date stored in this FeedDate as an ISO 8601 date.
+ *
+ * @return string a date in ISO 8601 format
+ */
+ public function iso8601()
+ {
+ $date = gmdate("Y-m-d\TH:i:sP", $this->unix);
+
+ return $date;
+ }
+
+ /**
+ * Gets the date stored in this FeedDate as unix time stamp.
+ *
+ * @return int a date as a unix time stamp
+ */
+ public function unix()
+ {
+ return $this->unix;
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedHtmlField.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedHtmlField.php
new file mode 100644
index 0000000..84f0ac4
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedHtmlField.php
@@ -0,0 +1,59 @@
+<?php
+
+/**
+ * A FeedHtmlField describes and generates
+ * a feed, item or image html field (probably a description). Output is
+ * generated based on $truncSize, $syndicateHtml properties.
+ *
+ * @author Pascal Van Hecke <feedcreator.class.php@vanhecke.info>
+ * @version 1.6
+ */
+class FeedHtmlField
+{
+ /**
+ * Mandatory attributes of a FeedHtmlField.
+ */
+ protected $rawFieldContent;
+
+ /**
+ * Optional attributes of a FeedHtmlField.
+ */
+ public $truncSize, $syndicateHtml;
+
+ /**
+ * Creates a new instance of FeedHtmlField.
+ *
+ * @param string $parFieldContent if given, sets the rawFieldContent property
+ */
+ public function __construct($parFieldContent)
+ {
+ if ($parFieldContent) {
+ $this->rawFieldContent = $parFieldContent;
+ }
+ }
+
+ /**
+ * Creates the right output, depending on $truncSize, $syndicateHtml properties.
+ *
+ * @return string the formatted field
+ */
+ public function output()
+ {
+ // when field available and syndicated in html we assume
+ // - valid html in $rawFieldContent and we enclose in CDATA tags
+ // - no truncation (truncating risks producing invalid html)
+ if (!$this->rawFieldContent) {
+ $result = "";
+ } elseif ($this->syndicateHtml) {
+ $result = "<![CDATA[".$this->rawFieldContent."]]>";
+ } else {
+ if ($this->truncSize and is_int($this->truncSize)) {
+ $result = FeedCreator::iTrunc(htmlspecialchars($this->rawFieldContent), $this->truncSize);
+ } else {
+ $result = htmlspecialchars($this->rawFieldContent);
+ }
+ }
+
+ return $result;
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedImage.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedImage.php
new file mode 100644
index 0000000..cc9df46
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedImage.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * A FeedImage may be added to a FeedCreator feed.
+ *
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ * @since 1.3
+ */
+class FeedImage extends HtmlDescribable
+{
+ /**
+ * Mandatory attributes of an image.
+ */
+ public $title, $url, $link;
+
+ /**
+ * Optional attributes of an image.
+ */
+ public $width, $height, $description;
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedItem.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedItem.php
new file mode 100644
index 0000000..3b51cc2
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/FeedItem.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * A FeedItem is a part of a FeedCreator feed.
+ *
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ * @since 1.3
+ */
+class FeedItem extends HtmlDescribable
+{
+ /**
+ * Mandatory attributes of an item.
+ */
+ public $title, $description, $link;
+
+ /**
+ * Optional attributes of an item.
+ */
+ public $author, $authorEmail, $authorURL, $image, $category, $categoryScheme, $comments, $guid, $source, $creator, $contributor, $lat, $long, $thumb;
+
+ /**
+ * Publishing date of an item. May be in one of the following formats:
+ * RFC 822:
+ * "Mon, 20 Jan 03 18:05:41 +0400"
+ * "20 Jan 03 18:05:41 +0000"
+ * ISO 8601:
+ * "2003-01-20T18:05:41+04:00"
+ * Unix:
+ * 1043082341
+ */
+ public $date;
+
+ /**
+ * Add <enclosure> element tag RSS 2.0, supported by ATOM 1.0 too
+ * modified by : Mohammad Hafiz bin Ismail (mypapit@gmail.com)
+ * display :
+ * <enclosure length="17691" url="http://something.com/picture.jpg" type="image/jpeg" />
+ */
+ public $enclosure;
+
+ /**
+ * Any additional elements to include as an associated array. All $key => $value pairs
+ * will be included unencoded in the feed item in the form
+ * <$key>$value</$key>
+ * Again: No encoding will be used! This means you can invalidate or enhance the feed
+ * if $value contains markup. This may be abused to embed tags not implemented by
+ * the FeedCreator class used.
+ */
+ public $additionalElements = Array();
+
+ // on hold
+ // var $source;
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/HtmlDescribable.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/HtmlDescribable.php
new file mode 100644
index 0000000..e34e2b1
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/Element/HtmlDescribable.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * An HtmlDescribable is an item within a feed that can have a description that may
+ * include HTML markup.
+ */
+class HtmlDescribable
+{
+ /**
+ * Indicates whether the description field should be rendered in HTML.
+ */
+ public $descriptionHtmlSyndicated;
+
+ /**
+ * Indicates whether and to how many characters a description should be truncated.
+ */
+ public $descriptionTruncSize;
+
+ /** @var string the Description */
+ public $description;
+
+ /**
+ * Returns a formatted description field, depending on descriptionHtmlSyndicated and
+ * $descriptionTruncSize properties
+ *
+ * @param bool $overrideSyndicateHtml
+ * @return string the formatted description
+ */
+ public function getDescription($overrideSyndicateHtml = false)
+ {
+ $descriptionField = new FeedHtmlField($this->description);
+ $descriptionField->syndicateHtml = $overrideSyndicateHtml || $this->descriptionHtmlSyndicated;
+ $descriptionField->truncSize = $this->descriptionTruncSize;
+
+ return $descriptionField->output();
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/UniversalFeedCreator.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/UniversalFeedCreator.php
new file mode 100644
index 0000000..4b7afe6
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/UniversalFeedCreator.php
@@ -0,0 +1,160 @@
+<?php
+/**
+ * UniversalFeedCreator lets you choose during runtime which
+ * format to build.
+ * For general usage of a feed class, see the FeedCreator class
+ * below or the example above.
+ *
+ * @since 1.3
+ * @author Kai Blankenhorn <kaib@bitfolge.de>
+ */
+class UniversalFeedCreator extends FeedCreator
+{
+ /** @var FeedCreator */
+ protected $_feed;
+
+ /**
+ * @param string $format
+ */
+ protected function _setFormat($format)
+ {
+ switch (strtoupper($format)) {
+
+ case "BASE":
+ $this->format = $format;
+ case "2.0":
+ // fall through
+ case "RSS2.0":
+ $this->_feed = new RSSCreator20();
+ break;
+
+ case "GEOPHOTORSS":
+ case "PHOTORSS":
+ case "GEORSS":
+ $this->format = $format;
+ case "1.0":
+ // fall through
+ case "RSS1.0":
+ $this->_feed = new RSSCreator10();
+ break;
+
+ case "0.91":
+ // fall through
+ case "RSS0.91":
+ $this->_feed = new RSSCreator091();
+ break;
+
+ case "PIE0.1":
+ $this->_feed = new PIECreator01();
+ break;
+
+ case "MBOX":
+ $this->_feed = new MBOXCreator();
+ break;
+
+ case "OPML":
+ $this->_feed = new OPMLCreator();
+ break;
+
+ case "TOOLBAR":
+ $this->format = $format;
+
+ case "ATOM":
+ // fall through: always the latest ATOM version
+ case "ATOM1.0":
+ $this->_feed = new AtomCreator10();
+ break;
+
+ case "ATOM0.3":
+ $this->_feed = new AtomCreator03();
+ break;
+
+ case "HTML":
+ $this->_feed = new HTMLCreator();
+ break;
+
+ case "PHP":
+ $this->_feed = new PHPCreator();
+ break;
+ case "GPX":
+ $this->_feed = new GPXCreator();
+ break;
+ case "KML":
+ $this->_feed = new KMLCreator();
+ break;
+ case "JS":
+ // fall through
+ case "JAVASCRIPT":
+ $this->_feed = new JSCreator();
+ break;
+
+ default:
+ $this->_feed = new RSSCreator091();
+ break;
+ }
+
+ $vars = get_object_vars($this);
+ foreach ($vars as $key => $value) {
+ // prevent overwriting of properties "contentType", "encoding"; do not copy "_feed" itself
+ if (!in_array($key, array("_feed", "contentType", "encoding"))) {
+ $this->_feed->{$key} = $this->{$key};
+ }
+ }
+ }
+
+ /**
+ * Creates a syndication feed based on the items previously added.
+ *
+ * @see FeedCreator::addItem()
+ * @param string $format format the feed should comply to. Valid values are:
+ * "PIE0.1", "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3", "HTML", "JS"
+ * @return string the contents of the feed.
+ */
+ public function createFeed($format = "RSS0.91")
+ {
+ $this->_setFormat($format);
+
+ return $this->_feed->createFeed();
+ }
+
+ /**
+ * Saves this feed as a file on the local disk. After the file is saved, an HTTP redirect
+ * header may be sent to redirect the use to the newly created file.
+ *
+ * @since 1.4
+ * @param string $format format the feed should comply to. Valid values are:
+ * "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM",
+ * "ATOM0.3", "HTML", "JS"
+ * @param string $filename optional the filename where a recent version of the feed is saved. If not
+ * specified, the filename is $_SERVER["PHP_SELF"] with the extension changed to
+ * .xml (see _generateFilename()).
+ * @param boolean $displayContents optional send the content of the file or not. If true, the file will be sent
+ * in the body of the response.
+ */
+ public function saveFeed($format = "RSS0.91", $filename = "", $displayContents = true)
+ {
+ $this->_setFormat($format);
+ $this->_feed->saveFeed($filename, $displayContents);
+ }
+
+ /**
+ * Turns on caching and checks if there is a recent version of this feed in the cache.
+ * If there is, an HTTP redirect header is sent.
+ * To effectively use caching, you should create the FeedCreator object and call this method
+ * before anything else, especially before you do the time consuming task to build the feed
+ * (web fetching, for example).
+ *
+ * @param string $format format the feed should comply to. Valid values are:
+ * "PIE0.1" (deprecated), "mbox", "RSS0.91", "RSS1.0", "RSS2.0", "OPML", "ATOM0.3".
+ * @param string $filename optional the filename where a recent version of the feed is saved. If not specified, the
+ * filename is $_SERVER["PHP_SELF"] with the extension changed to .xml (see
+ * _generateFilename()).
+ * @param int $timeout optional the timeout in seconds before a cached version is refreshed (defaults to 3600 =
+ * 1 hour)
+ */
+ public function useCached($format = "RSS0.91", $filename = "", $timeout = 3600)
+ {
+ $this->_setFormat($format);
+ $this->_feed->useCached($filename, $timeout);
+ }
+}
diff --git a/platform/www/vendor/openpsa/universalfeedcreator/lib/constants.php b/platform/www/vendor/openpsa/universalfeedcreator/lib/constants.php
new file mode 100644
index 0000000..146c189
--- /dev/null
+++ b/platform/www/vendor/openpsa/universalfeedcreator/lib/constants.php
@@ -0,0 +1,10 @@
+<?php
+// your local timezone, set to "" to disable or for GMT
+if (!defined('TIME_ZONE')) {
+ define("TIME_ZONE", date("O", time()));
+}
+
+/**
+ * Version string.
+ */
+define("FEEDCREATOR_VERSION", "FeedCreator 1.8");
diff --git a/platform/www/vendor/paragonie/random_compat/LICENSE b/platform/www/vendor/paragonie/random_compat/LICENSE
new file mode 100644
index 0000000..45c7017
--- /dev/null
+++ b/platform/www/vendor/paragonie/random_compat/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Paragon Initiative Enterprises
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/platform/www/vendor/paragonie/random_compat/lib/byte_safe_strings.php b/platform/www/vendor/paragonie/random_compat/lib/byte_safe_strings.php
new file mode 100644
index 0000000..ef24488
--- /dev/null
+++ b/platform/www/vendor/paragonie/random_compat/lib/byte_safe_strings.php
@@ -0,0 +1,195 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+if (!is_callable('RandomCompat_strlen')) {
+ if (
+ defined('MB_OVERLOAD_STRING')
+ &&
+ ((int) ini_get('mbstring.func_overload')) & MB_OVERLOAD_STRING
+ ) {
+ /**
+ * strlen() implementation that isn't brittle to mbstring.func_overload
+ *
+ * This version uses mb_strlen() in '8bit' mode to treat strings as raw
+ * binary rather than UTF-8, ISO-8859-1, etc
+ *
+ * @param string $binary_string
+ *
+ * @throws TypeError
+ *
+ * @return int
+ */
+ function RandomCompat_strlen($binary_string)
+ {
+ if (!is_string($binary_string)) {
+ throw new TypeError(
+ 'RandomCompat_strlen() expects a string'
+ );
+ }
+
+ return (int) mb_strlen($binary_string, '8bit');
+ }
+
+ } else {
+ /**
+ * strlen() implementation that isn't brittle to mbstring.func_overload
+ *
+ * This version just used the default strlen()
+ *
+ * @param string $binary_string
+ *
+ * @throws TypeError
+ *
+ * @return int
+ */
+ function RandomCompat_strlen($binary_string)
+ {
+ if (!is_string($binary_string)) {
+ throw new TypeError(
+ 'RandomCompat_strlen() expects a string'
+ );
+ }
+ return (int) strlen($binary_string);
+ }
+ }
+}
+
+if (!is_callable('RandomCompat_substr')) {
+
+ if (
+ defined('MB_OVERLOAD_STRING')
+ &&
+ ((int) ini_get('mbstring.func_overload')) & MB_OVERLOAD_STRING
+ ) {
+ /**
+ * substr() implementation that isn't brittle to mbstring.func_overload
+ *
+ * This version uses mb_substr() in '8bit' mode to treat strings as raw
+ * binary rather than UTF-8, ISO-8859-1, etc
+ *
+ * @param string $binary_string
+ * @param int $start
+ * @param int|null $length (optional)
+ *
+ * @throws TypeError
+ *
+ * @return string
+ */
+ function RandomCompat_substr($binary_string, $start, $length = null)
+ {
+ if (!is_string($binary_string)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): First argument should be a string'
+ );
+ }
+
+ if (!is_int($start)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): Second argument should be an integer'
+ );
+ }
+
+ if ($length === null) {
+ /**
+ * mb_substr($str, 0, NULL, '8bit') returns an empty string on
+ * PHP 5.3, so we have to find the length ourselves.
+ */
+ /** @var int $length */
+ $length = RandomCompat_strlen($binary_string) - $start;
+ } elseif (!is_int($length)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): Third argument should be an integer, or omitted'
+ );
+ }
+
+ // Consistency with PHP's behavior
+ if ($start === RandomCompat_strlen($binary_string) && $length === 0) {
+ return '';
+ }
+ if ($start > RandomCompat_strlen($binary_string)) {
+ return '';
+ }
+
+ return (string) mb_substr(
+ (string) $binary_string,
+ (int) $start,
+ (int) $length,
+ '8bit'
+ );
+ }
+
+ } else {
+
+ /**
+ * substr() implementation that isn't brittle to mbstring.func_overload
+ *
+ * This version just uses the default substr()
+ *
+ * @param string $binary_string
+ * @param int $start
+ * @param int|null $length (optional)
+ *
+ * @throws TypeError
+ *
+ * @return string
+ */
+ function RandomCompat_substr($binary_string, $start, $length = null)
+ {
+ if (!is_string($binary_string)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): First argument should be a string'
+ );
+ }
+
+ if (!is_int($start)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): Second argument should be an integer'
+ );
+ }
+
+ if ($length !== null) {
+ if (!is_int($length)) {
+ throw new TypeError(
+ 'RandomCompat_substr(): Third argument should be an integer, or omitted'
+ );
+ }
+
+ return (string) substr(
+ (string )$binary_string,
+ (int) $start,
+ (int) $length
+ );
+ }
+
+ return (string) substr(
+ (string) $binary_string,
+ (int) $start
+ );
+ }
+ }
+}
diff --git a/platform/www/vendor/paragonie/random_compat/lib/cast_to_int.php b/platform/www/vendor/paragonie/random_compat/lib/cast_to_int.php
new file mode 100644
index 0000000..1b1bbfe
--- /dev/null
+++ b/platform/www/vendor/paragonie/random_compat/lib/cast_to_int.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+if (!is_callable('RandomCompat_intval')) {
+
+ /**
+ * Cast to an integer if we can, safely.
+ *
+ * If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
+ * (non-inclusive), it will sanely cast it to an int. If you it's equal to
+ * ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
+ * lose precision, so the <= and => operators might accidentally let a float
+ * through.
+ *
+ * @param int|float $number The number we want to convert to an int
+ * @param bool $fail_open Set to true to not throw an exception
+ *
+ * @return float|int
+ * @psalm-suppress InvalidReturnType
+ *
+ * @throws TypeError
+ */
+ function RandomCompat_intval($number, $fail_open = false)
+ {
+ if (is_int($number) || is_float($number)) {
+ $number += 0;
+ } elseif (is_numeric($number)) {
+ /** @psalm-suppress InvalidOperand */
+ $number += 0;
+ }
+ /** @var int|float $number */
+
+ if (
+ is_float($number)
+ &&
+ $number > ~PHP_INT_MAX
+ &&
+ $number < PHP_INT_MAX
+ ) {
+ $number = (int) $number;
+ }
+
+ if (is_int($number)) {
+ return (int) $number;
+ } elseif (!$fail_open) {
+ throw new TypeError(
+ 'Expected an integer.'
+ );
+ }
+ return $number;
+ }
+}
diff --git a/platform/www/vendor/paragonie/random_compat/lib/error_polyfill.php b/platform/www/vendor/paragonie/random_compat/lib/error_polyfill.php
new file mode 100644
index 0000000..c02c5c8
--- /dev/null
+++ b/platform/www/vendor/paragonie/random_compat/lib/error_polyfill.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+if (!class_exists('Error', false)) {
+ // We can't really avoid making this extend Exception in PHP 5.
+ class Error extends Exception
+ {
+
+ }
+}
+
+if (!class_exists('TypeError', false)) {
+ if (is_subclass_of('Error', 'Exception')) {
+ class TypeError extends Error
+ {
+
+ }
+ } else {
+ class TypeError extends Exception
+ {
+
+ }
+ }
+}
diff --git a/platform/www/vendor/paragonie/random_compat/lib/random.php b/platform/www/vendor/paragonie/random_compat/lib/random.php
new file mode 100644
index 0000000..36245f5
--- /dev/null
+++ b/platform/www/vendor/paragonie/random_compat/lib/random.php
@@ -0,0 +1,225 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * @version 2.0.17
+ * @released 2018-07-04
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+if (!defined('PHP_VERSION_ID')) {
+ // This constant was introduced in PHP 5.2.7
+ $RandomCompatversion = array_map('intval', explode('.', PHP_VERSION));
+ define(
+ 'PHP_VERSION_ID',
+ $RandomCompatversion[0] * 10000
+ + $RandomCompatversion[1] * 100
+ + $RandomCompatversion[2]
+ );
+ $RandomCompatversion = null;
+}
+
+/**
+ * PHP 7.0.0 and newer have these functions natively.
+ */
+if (PHP_VERSION_ID >= 70000) {
+ return;
+}
+
+if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
+ define('RANDOM_COMPAT_READ_BUFFER', 8);
+}
+
+$RandomCompatDIR = dirname(__FILE__);
+
+require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'byte_safe_strings.php';
+require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'cast_to_int.php';
+require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'error_polyfill.php';
+
+if (!is_callable('random_bytes')) {
+ /**
+ * PHP 5.2.0 - 5.6.x way to implement random_bytes()
+ *
+ * We use conditional statements here to define the function in accordance
+ * to the operating environment. It's a micro-optimization.
+ *
+ * In order of preference:
+ * 1. Use libsodium if available.
+ * 2. fread() /dev/urandom if available (never on Windows)
+ * 3. mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM)
+ * 4. COM('CAPICOM.Utilities.1')->GetRandom()
+ *
+ * See RATIONALE.md for our reasoning behind this particular order
+ */
+ if (extension_loaded('libsodium')) {
+ // See random_bytes_libsodium.php
+ if (PHP_VERSION_ID >= 50300 && is_callable('\\Sodium\\randombytes_buf')) {
+ require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_libsodium.php';
+ } elseif (method_exists('Sodium', 'randombytes_buf')) {
+ require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_libsodium_legacy.php';
+ }
+ }
+
+ /**
+ * Reading directly from /dev/urandom:
+ */
+ if (DIRECTORY_SEPARATOR === '/') {
+ // DIRECTORY_SEPARATOR === '/' on Unix-like OSes -- this is a fast
+ // way to exclude Windows.
+ $RandomCompatUrandom = true;
+ $RandomCompat_basedir = ini_get('open_basedir');
+
+ if (!empty($RandomCompat_basedir)) {
+ $RandomCompat_open_basedir = explode(
+ PATH_SEPARATOR,
+ strtolower($RandomCompat_basedir)
+ );
+ $RandomCompatUrandom = (array() !== array_intersect(
+ array('/dev', '/dev/', '/dev/urandom'),
+ $RandomCompat_open_basedir
+ ));
+ $RandomCompat_open_basedir = null;
+ }
+
+ if (
+ !is_callable('random_bytes')
+ &&
+ $RandomCompatUrandom
+ &&
+ @is_readable('/dev/urandom')
+ ) {
+ // Error suppression on is_readable() in case of an open_basedir
+ // or safe_mode failure. All we care about is whether or not we
+ // can read it at this point. If the PHP environment is going to
+ // panic over trying to see if the file can be read in the first
+ // place, that is not helpful to us here.
+
+ // See random_bytes_dev_urandom.php
+ require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_dev_urandom.php';
+ }
+ // Unset variables after use
+ $RandomCompat_basedir = null;
+ } else {
+ $RandomCompatUrandom = false;
+ }
+
+ /**
+ * mcrypt_create_iv()
+ *
+ * We only want to use mcypt_create_iv() if:
+ *
+ * - random_bytes() hasn't already been defined
+ * - the mcrypt extensions is loaded
+ * - One of these two conditions is true:
+ * - We're on Windows (DIRECTORY_SEPARATOR !== '/')
+ * - We're not on Windows and /dev/urandom is readabale
+ * (i.e. we're not in a chroot jail)
+ * - Special case:
+ * - If we're not on Windows, but the PHP version is between
+ * 5.6.10 and 5.6.12, we don't want to use mcrypt. It will
+ * hang indefinitely. This is bad.
+ * - If we're on Windows, we want to use PHP >= 5.3.7 or else
+ * we get insufficient entropy errors.
+ */
+ if (
+ !is_callable('random_bytes')
+ &&
+ // Windows on PHP < 5.3.7 is broken, but non-Windows is not known to be.
+ (DIRECTORY_SEPARATOR === '/' || PHP_VERSION_ID >= 50307)
+ &&
+ // Prevent this code from hanging indefinitely on non-Windows;
+ // see https://bugs.php.net/bug.php?id=69833
+ (
+ DIRECTORY_SEPARATOR !== '/' ||
+ (PHP_VERSION_ID <= 50609 || PHP_VERSION_ID >= 50613)
+ )
+ &&
+ extension_loaded('mcrypt')
+ ) {
+ // See random_bytes_mcrypt.php
+ require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_mcrypt.php';
+ }
+ $RandomCompatUrandom = null;
+
+ /**
+ * This is a Windows-specific fallback, for when the mcrypt extension
+ * isn't loaded.
+ */
+ if (
+ !is_callable('random_bytes')
+ &&
+ extension_loaded('com_dotnet')
+ &&
+ class_exists('COM')
+ ) {
+ $RandomCompat_disabled_classes = preg_split(
+ '#\s*,\s*#',
+ strtolower(ini_get('disable_classes'))
+ );
+
+ if (!in_array('com', $RandomCompat_disabled_classes)) {
+ try {
+ $RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
+ if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
+ // See random_bytes_com_dotnet.php
+ require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_bytes_com_dotnet.php';
+ }
+ } catch (com_exception $e) {
+ // Don't try to use it.
+ }
+ }
+ $RandomCompat_disabled_classes = null;
+ $RandomCompatCOMtest = null;
+ }
+
+ /**
+ * throw new Exception
+ */
+ if (!is_callable('random_bytes')) {
+ /**
+ * We don't have any more options, so let's throw an exception right now
+ * and hope the developer won't let it fail silently.
+ *
+ * @param mixed $length
+ * @psalm-suppress InvalidReturnType
+ * @throws Exception
+ * @return string
+ */
+ function random_bytes($length)
+ {
+ unset($length); // Suppress "variable not used" warnings.
+ throw new Exception(
+ 'There is no suitable CSPRNG installed on your system'
+ );
+ return '';
+ }
+ }
+}
+
+if (!is_callable('random_int')) {
+ require_once $RandomCompatDIR . DIRECTORY_SEPARATOR . 'random_int.php';
+}
+
+$RandomCompatDIR = null;
diff --git a/platform/www/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php b/platform/www/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php
new file mode 100644
index 0000000..537d02b
--- /dev/null
+++ b/platform/www/vendor/paragonie/random_compat/lib/random_bytes_com_dotnet.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+if (!is_callable('random_bytes')) {
+ /**
+ * Windows with PHP < 5.3.0 will not have the function
+ * openssl_random_pseudo_bytes() available, so let's use
+ * CAPICOM to work around this deficiency.
+ *
+ * @param int $bytes
+ *
+ * @throws Exception
+ *
+ * @return string
+ */
+ function random_bytes($bytes)
+ {
+ try {
+ /** @var int $bytes */
+ $bytes = RandomCompat_intval($bytes);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_bytes(): $bytes must be an integer'
+ );
+ }
+
+ if ($bytes < 1) {
+ throw new Error(
+ 'Length must be greater than 0'
+ );
+ }
+
+ /** @var string $buf */
+ $buf = '';
+ if (!class_exists('COM')) {
+ throw new Error(
+ 'COM does not exist'
+ );
+ }
+ /** @var COM $util */
+ $util = new COM('CAPICOM.Utilities.1');
+ $execCount = 0;
+
+ /**
+ * Let's not let it loop forever. If we run N times and fail to
+ * get N bytes of random data, then CAPICOM has failed us.
+ */
+ do {
+ $buf .= base64_decode((string) $util->GetRandom($bytes, 0));
+ if (RandomCompat_strlen($buf) >= $bytes) {
+ /**
+ * Return our random entropy buffer here:
+ */
+ return (string) RandomCompat_substr($buf, 0, $bytes);
+ }
+ ++$execCount;
+ } while ($execCount < $bytes);
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Could not gather sufficient random data'
+ );
+ }
+}
diff --git a/platform/www/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php b/platform/www/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php
new file mode 100644
index 0000000..c4e31cc
--- /dev/null
+++ b/platform/www/vendor/paragonie/random_compat/lib/random_bytes_dev_urandom.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+if (!defined('RANDOM_COMPAT_READ_BUFFER')) {
+ define('RANDOM_COMPAT_READ_BUFFER', 8);
+}
+
+if (!is_callable('random_bytes')) {
+ /**
+ * Unless open_basedir is enabled, use /dev/urandom for
+ * random numbers in accordance with best practices
+ *
+ * Why we use /dev/urandom and not /dev/random
+ * @ref https://www.2uo.de/myths-about-urandom
+ * @ref http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers
+ *
+ * @param int $bytes
+ *
+ * @throws Exception
+ *
+ * @return string
+ */
+ function random_bytes($bytes)
+ {
+ /** @var resource $fp */
+ static $fp = null;
+
+ /**
+ * This block should only be run once
+ */
+ if (empty($fp)) {
+ /**
+ * We don't want to ever read C:\dev\random, only /dev/urandom on
+ * Unix-like operating systems. While we guard against this
+ * condition in random.php, it doesn't hurt to be defensive in depth
+ * here.
+ *
+ * To that end, we only try to open /dev/urandom if we're on a Unix-
+ * like operating system (which means the directory separator is set
+ * to "/" not "\".
+ */
+ if (DIRECTORY_SEPARATOR === '/') {
+ if (!is_readable('/dev/urandom')) {
+ throw new Exception(
+ 'Environment misconfiguration: ' .
+ '/dev/urandom cannot be read.'
+ );
+ }
+ /**
+ * We use /dev/urandom if it is a char device.
+ * We never fall back to /dev/random
+ */
+ /** @var resource|bool $fp */
+ $fp = fopen('/dev/urandom', 'rb');
+ if (is_resource($fp)) {
+ /** @var array<string, int> $st */
+ $st = fstat($fp);
+ if (($st['mode'] & 0170000) !== 020000) {
+ fclose($fp);
+ $fp = false;
+ }
+ }
+ }
+
+ if (is_resource($fp)) {
+ /**
+ * stream_set_read_buffer() does not exist in HHVM
+ *
+ * If we don't set the stream's read buffer to 0, PHP will
+ * internally buffer 8192 bytes, which can waste entropy
+ *
+ * stream_set_read_buffer returns 0 on success
+ */
+ if (is_callable('stream_set_read_buffer')) {
+ stream_set_read_buffer($fp, RANDOM_COMPAT_READ_BUFFER);
+ }
+ if (is_callable('stream_set_chunk_size')) {
+ stream_set_chunk_size($fp, RANDOM_COMPAT_READ_BUFFER);
+ }
+ }
+ }
+
+ try {
+ /** @var int $bytes */
+ $bytes = RandomCompat_intval($bytes);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_bytes(): $bytes must be an integer'
+ );
+ }
+
+ if ($bytes < 1) {
+ throw new Error(
+ 'Length must be greater than 0'
+ );
+ }
+
+ /**
+ * This if() block only runs if we managed to open a file handle
+ *
+ * It does not belong in an else {} block, because the above
+ * if (empty($fp)) line is logic that should only be run once per
+ * page load.
+ */
+ if (is_resource($fp)) {
+ /**
+ * @var int
+ */
+ $remaining = $bytes;
+
+ /**
+ * @var string|bool
+ */
+ $buf = '';
+
+ /**
+ * We use fread() in a loop to protect against partial reads
+ */
+ do {
+ /**
+ * @var string|bool
+ */
+ $read = fread($fp, $remaining);
+ if (!is_string($read)) {
+ /**
+ * We cannot safely read from the file. Exit the
+ * do-while loop and trigger the exception condition
+ *
+ * @var string|bool
+ */
+ $buf = false;
+ break;
+ }
+ /**
+ * Decrease the number of bytes returned from remaining
+ */
+ $remaining -= RandomCompat_strlen($read);
+ /**
+ * @var string $buf
+ */
+ $buf .= $read;
+ } while ($remaining > 0);
+
+ /**
+ * Is our result valid?
+ * @var string|bool $buf
+ */
+ if (is_string($buf)) {
+ if (RandomCompat_strlen($buf) === $bytes) {
+ /**
+ * Return our random entropy buffer here:
+ */
+ return $buf;
+ }
+ }
+ }
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Error reading from source device'
+ );
+ }
+}
diff --git a/platform/www/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php b/platform/www/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php
new file mode 100644
index 0000000..2e56290
--- /dev/null
+++ b/platform/www/vendor/paragonie/random_compat/lib/random_bytes_libsodium.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+if (!is_callable('random_bytes')) {
+ /**
+ * If the libsodium PHP extension is loaded, we'll use it above any other
+ * solution.
+ *
+ * libsodium-php project:
+ * @ref https://github.com/jedisct1/libsodium-php
+ *
+ * @param int $bytes
+ *
+ * @throws Exception
+ *
+ * @return string
+ */
+ function random_bytes($bytes)
+ {
+ try {
+ /** @var int $bytes */
+ $bytes = RandomCompat_intval($bytes);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_bytes(): $bytes must be an integer'
+ );
+ }
+
+ if ($bytes < 1) {
+ throw new Error(
+ 'Length must be greater than 0'
+ );
+ }
+
+ /**
+ * \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
+ * generated in one invocation.
+ */
+ /** @var string|bool $buf */
+ if ($bytes > 2147483647) {
+ $buf = '';
+ for ($i = 0; $i < $bytes; $i += 1073741824) {
+ $n = ($bytes - $i) > 1073741824
+ ? 1073741824
+ : $bytes - $i;
+ $buf .= \Sodium\randombytes_buf($n);
+ }
+ } else {
+ /** @var string|bool $buf */
+ $buf = \Sodium\randombytes_buf($bytes);
+ }
+
+ if (is_string($buf)) {
+ if (RandomCompat_strlen($buf) === $bytes) {
+ return $buf;
+ }
+ }
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Could not gather sufficient random data'
+ );
+ }
+}
diff --git a/platform/www/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php b/platform/www/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php
new file mode 100644
index 0000000..f78b219
--- /dev/null
+++ b/platform/www/vendor/paragonie/random_compat/lib/random_bytes_libsodium_legacy.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+if (!is_callable('random_bytes')) {
+ /**
+ * If the libsodium PHP extension is loaded, we'll use it above any other
+ * solution.
+ *
+ * libsodium-php project:
+ * @ref https://github.com/jedisct1/libsodium-php
+ *
+ * @param int $bytes
+ *
+ * @throws Exception
+ *
+ * @return string
+ */
+ function random_bytes($bytes)
+ {
+ try {
+ /** @var int $bytes */
+ $bytes = RandomCompat_intval($bytes);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_bytes(): $bytes must be an integer'
+ );
+ }
+
+ if ($bytes < 1) {
+ throw new Error(
+ 'Length must be greater than 0'
+ );
+ }
+
+ /**
+ * @var string
+ */
+ $buf = '';
+
+ /**
+ * \Sodium\randombytes_buf() doesn't allow more than 2147483647 bytes to be
+ * generated in one invocation.
+ */
+ if ($bytes > 2147483647) {
+ for ($i = 0; $i < $bytes; $i += 1073741824) {
+ $n = ($bytes - $i) > 1073741824
+ ? 1073741824
+ : $bytes - $i;
+ $buf .= Sodium::randombytes_buf((int) $n);
+ }
+ } else {
+ $buf .= Sodium::randombytes_buf((int) $bytes);
+ }
+
+ if (is_string($buf)) {
+ if (RandomCompat_strlen($buf) === $bytes) {
+ return $buf;
+ }
+ }
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Could not gather sufficient random data'
+ );
+ }
+}
diff --git a/platform/www/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php b/platform/www/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php
new file mode 100644
index 0000000..0b13fa7
--- /dev/null
+++ b/platform/www/vendor/paragonie/random_compat/lib/random_bytes_mcrypt.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+if (!is_callable('random_bytes')) {
+ /**
+ * Powered by ext/mcrypt (and thankfully NOT libmcrypt)
+ *
+ * @ref https://bugs.php.net/bug.php?id=55169
+ * @ref https://github.com/php/php-src/blob/c568ffe5171d942161fc8dda066bce844bdef676/ext/mcrypt/mcrypt.c#L1321-L1386
+ *
+ * @param int $bytes
+ *
+ * @throws Exception
+ *
+ * @return string
+ */
+ function random_bytes($bytes)
+ {
+ try {
+ /** @var int $bytes */
+ $bytes = RandomCompat_intval($bytes);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_bytes(): $bytes must be an integer'
+ );
+ }
+
+ if ($bytes < 1) {
+ throw new Error(
+ 'Length must be greater than 0'
+ );
+ }
+
+ /** @var string|bool $buf */
+ $buf = @mcrypt_create_iv((int) $bytes, (int) MCRYPT_DEV_URANDOM);
+ if (
+ is_string($buf)
+ &&
+ RandomCompat_strlen($buf) === $bytes
+ ) {
+ /**
+ * Return our random entropy buffer here:
+ */
+ return $buf;
+ }
+
+ /**
+ * If we reach here, PHP has failed us.
+ */
+ throw new Exception(
+ 'Could not gather sufficient random data'
+ );
+ }
+}
diff --git a/platform/www/vendor/paragonie/random_compat/lib/random_int.php b/platform/www/vendor/paragonie/random_compat/lib/random_int.php
new file mode 100644
index 0000000..ff80dfa
--- /dev/null
+++ b/platform/www/vendor/paragonie/random_compat/lib/random_int.php
@@ -0,0 +1,204 @@
+<?php
+
+if (!is_callable('random_int')) {
+ /**
+ * Random_* Compatibility Library
+ * for using the new PHP 7 random_* API in PHP 5 projects
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+ /**
+ * Fetch a random integer between $min and $max inclusive
+ *
+ * @param int $min
+ * @param int $max
+ *
+ * @throws Exception
+ *
+ * @return int
+ */
+ function random_int($min, $max)
+ {
+ /**
+ * Type and input logic checks
+ *
+ * If you pass it a float in the range (~PHP_INT_MAX, PHP_INT_MAX)
+ * (non-inclusive), it will sanely cast it to an int. If you it's equal to
+ * ~PHP_INT_MAX or PHP_INT_MAX, we let it fail as not an integer. Floats
+ * lose precision, so the <= and => operators might accidentally let a float
+ * through.
+ */
+
+ try {
+ /** @var int $min */
+ $min = RandomCompat_intval($min);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_int(): $min must be an integer'
+ );
+ }
+
+ try {
+ /** @var int $max */
+ $max = RandomCompat_intval($max);
+ } catch (TypeError $ex) {
+ throw new TypeError(
+ 'random_int(): $max must be an integer'
+ );
+ }
+
+ /**
+ * Now that we've verified our weak typing system has given us an integer,
+ * let's validate the logic then we can move forward with generating random
+ * integers along a given range.
+ */
+ if ($min > $max) {
+ throw new Error(
+ 'Minimum value must be less than or equal to the maximum value'
+ );
+ }
+
+ if ($max === $min) {
+ return (int) $min;
+ }
+
+ /**
+ * Initialize variables to 0
+ *
+ * We want to store:
+ * $bytes => the number of random bytes we need
+ * $mask => an integer bitmask (for use with the &) operator
+ * so we can minimize the number of discards
+ */
+ $attempts = $bits = $bytes = $mask = $valueShift = 0;
+ /** @var int $attempts */
+ /** @var int $bits */
+ /** @var int $bytes */
+ /** @var int $mask */
+ /** @var int $valueShift */
+
+ /**
+ * At this point, $range is a positive number greater than 0. It might
+ * overflow, however, if $max - $min > PHP_INT_MAX. PHP will cast it to
+ * a float and we will lose some precision.
+ *
+ * @var int|float $range
+ */
+ $range = $max - $min;
+
+ /**
+ * Test for integer overflow:
+ */
+ if (!is_int($range)) {
+
+ /**
+ * Still safely calculate wider ranges.
+ * Provided by @CodesInChaos, @oittaa
+ *
+ * @ref https://gist.github.com/CodesInChaos/03f9ea0b58e8b2b8d435
+ *
+ * We use ~0 as a mask in this case because it generates all 1s
+ *
+ * @ref https://eval.in/400356 (32-bit)
+ * @ref http://3v4l.org/XX9r5 (64-bit)
+ */
+ $bytes = PHP_INT_SIZE;
+ /** @var int $mask */
+ $mask = ~0;
+
+ } else {
+
+ /**
+ * $bits is effectively ceil(log($range, 2)) without dealing with
+ * type juggling
+ */
+ while ($range > 0) {
+ if ($bits % 8 === 0) {
+ ++$bytes;
+ }
+ ++$bits;
+ $range >>= 1;
+ /** @var int $mask */
+ $mask = $mask << 1 | 1;
+ }
+ $valueShift = $min;
+ }
+
+ /** @var int $val */
+ $val = 0;
+ /**
+ * Now that we have our parameters set up, let's begin generating
+ * random integers until one falls between $min and $max
+ */
+ /** @psalm-suppress RedundantCondition */
+ do {
+ /**
+ * The rejection probability is at most 0.5, so this corresponds
+ * to a failure probability of 2^-128 for a working RNG
+ */
+ if ($attempts > 128) {
+ throw new Exception(
+ 'random_int: RNG is broken - too many rejections'
+ );
+ }
+
+ /**
+ * Let's grab the necessary number of random bytes
+ */
+ $randomByteString = random_bytes($bytes);
+
+ /**
+ * Let's turn $randomByteString into an integer
+ *
+ * This uses bitwise operators (<< and |) to build an integer
+ * out of the values extracted from ord()
+ *
+ * Example: [9F] | [6D] | [32] | [0C] =>
+ * 159 + 27904 + 3276800 + 201326592 =>
+ * 204631455
+ */
+ $val &= 0;
+ for ($i = 0; $i < $bytes; ++$i) {
+ $val |= ord($randomByteString[$i]) << ($i * 8);
+ }
+ /** @var int $val */
+
+ /**
+ * Apply mask
+ */
+ $val &= $mask;
+ $val += $valueShift;
+
+ ++$attempts;
+ /**
+ * If $val overflows to a floating point number,
+ * ... or is larger than $max,
+ * ... or smaller than $min,
+ * then try again.
+ */
+ } while (!is_int($val) || $val > $max || $val < $min);
+
+ return (int) $val;
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/AUTHORS b/platform/www/vendor/phpseclib/phpseclib/AUTHORS
new file mode 100644
index 0000000..a08b309
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/AUTHORS
@@ -0,0 +1,6 @@
+phpseclib Lead Developer: TerraFrost (Jim Wigginton)
+
+phpseclib Developers: monnerat (Patrick Monnerat)
+ bantu (Andreas Fischer)
+ petrich (Hans-Jürgen Petrich)
+ GrahamCampbell (Graham Campbell)
diff --git a/platform/www/vendor/phpseclib/phpseclib/BACKERS.md b/platform/www/vendor/phpseclib/phpseclib/BACKERS.md
new file mode 100644
index 0000000..e03152c
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/BACKERS.md
@@ -0,0 +1,8 @@
+# Backers
+
+phpseclib ongoing development is made possible by [Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme) and by contributions by users like you. Thank you.
+
+## Backers
+
+- Zane Hooper
+- [Setasign](https://www.setasign.com/) \ No newline at end of file
diff --git a/platform/www/vendor/phpseclib/phpseclib/LICENSE b/platform/www/vendor/phpseclib/phpseclib/LICENSE
new file mode 100644
index 0000000..e7214eb
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2011-2019 TerraFrost and other contributors
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/platform/www/vendor/phpseclib/phpseclib/README.md b/platform/www/vendor/phpseclib/phpseclib/README.md
new file mode 100644
index 0000000..ac0eb2f
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/README.md
@@ -0,0 +1,86 @@
+# phpseclib - PHP Secure Communications Library
+
+[![Build Status](https://travis-ci.org/phpseclib/phpseclib.svg?branch=2.0)](https://travis-ci.org/phpseclib/phpseclib)
+
+## Supporting phpseclib
+
+- [Become a backer or sponsor on Patreon](https://www.patreon.com/phpseclib)
+- [One-time donation via PayPal or crypto-currencies](http://sourceforge.net/donate/index.php?group_id=198487)
+- [Subscribe to Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme)
+
+## Introduction
+
+MIT-licensed pure-PHP implementations of an arbitrary-precision integer
+arithmetic library, fully PKCS#1 (v2.1) compliant RSA, DES, 3DES, RC4, Rijndael,
+AES, Blowfish, Twofish, SSH-1, SSH-2, SFTP, and X.509
+
+* [Browse Git](https://github.com/phpseclib/phpseclib)
+
+## Documentation
+
+* [Documentation / Manual](http://phpseclib.sourceforge.net/)
+* [API Documentation](https://api.phpseclib.org/2.0/) (generated by Sami)
+
+## Branches
+
+### master
+
+* Development Branch
+* Unstable API
+* Do not use in production
+
+### 2.0
+
+* Long term support (LTS) release
+* Modernized version of 1.0
+* Minimum PHP version: 5.3.3
+* PSR-4 autoloading with namespace rooted at `\phpseclib`
+* Install via Composer: `composer require phpseclib/phpseclib:~2.0`
+
+### 1.0
+
+* Long term support (LTS) release
+* PHP4 compatible
+* Composer compatible (PSR-0 autoloading)
+* Install using Composer: `composer require phpseclib/phpseclib:~1.0`
+* Install using PEAR: See [phpseclib PEAR Channel Documentation](http://phpseclib.sourceforge.net/pear.htm)
+* [Download 1.0.18 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.18.zip/download)
+
+## Security contact information
+
+To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure.
+
+## Support
+
+Need Support?
+
+* [Checkout Questions and Answers on Stack Overflow](http://stackoverflow.com/questions/tagged/phpseclib)
+* [Create a Support Ticket on GitHub](https://github.com/phpseclib/phpseclib/issues/new)
+* [Browse the Support Forum](http://www.frostjedi.com/phpbb/viewforum.php?f=46) (no longer in use)
+
+## Contributing
+
+1. Fork the Project
+
+2. Ensure you have Composer installed (see [Composer Download Instructions](https://getcomposer.org/download/))
+
+3. Install Development Dependencies
+
+ ``` sh
+ composer install
+ ```
+
+4. Create a Feature Branch
+
+5. (Recommended) Run the Test Suite
+
+ ``` sh
+ vendor/bin/phpunit
+ ```
+6. (Recommended) Check whether your code conforms to our Coding Standards by running
+
+ ``` sh
+ vendor/bin/phing -f build/build.xml sniff
+ ```
+
+7. Send us a Pull Request
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php
new file mode 100644
index 0000000..7d8cb8b
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php
@@ -0,0 +1,126 @@
+<?php
+
+/**
+ * Pure-PHP implementation of AES.
+ *
+ * Uses mcrypt, if available/possible, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * NOTE: Since AES.php is (for compatibility and phpseclib-historical reasons) virtually
+ * just a wrapper to Rijndael.php you may consider using Rijndael.php instead of
+ * to save one include_once().
+ *
+ * If {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
+ * {@link self::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's 136-bits
+ * it'll be null-padded to 192-bits and 192 bits will be the key length until {@link self::setKey() setKey()}
+ * is called, again, at which point, it'll be recalculated.
+ *
+ * Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, some functions are available to be called that, in the context of AES, don't
+ * make a whole lot of sense. {@link self::setBlockLength() setBlockLength()}, for instance. Calling that function,
+ * however possible, won't do anything (AES has a fixed block length whereas Rijndael has a variable one).
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $aes = new \phpseclib\Crypt\AES();
+ *
+ * $aes->setKey('abcdefghijklmnop');
+ *
+ * $size = 10 * 1024;
+ * $plaintext = '';
+ * for ($i = 0; $i < $size; $i++) {
+ * $plaintext.= 'a';
+ * }
+ *
+ * echo $aes->decrypt($aes->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package AES
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2008 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of AES.
+ *
+ * @package AES
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class AES extends Rijndael
+{
+ /**
+ * Dummy function
+ *
+ * Since \phpseclib\Crypt\AES extends \phpseclib\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything.
+ *
+ * @see \phpseclib\Crypt\Rijndael::setBlockLength()
+ * @access public
+ * @param int $length
+ */
+ function setBlockLength($length)
+ {
+ return;
+ }
+
+ /**
+ * Sets the key length
+ *
+ * Valid key lengths are 128, 192, and 256. If the length is less than 128, it will be rounded up to
+ * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
+ *
+ * @see \phpseclib\Crypt\Rijndael:setKeyLength()
+ * @access public
+ * @param int $length
+ */
+ function setKeyLength($length)
+ {
+ switch ($length) {
+ case 160:
+ $length = 192;
+ break;
+ case 224:
+ $length = 256;
+ }
+ parent::setKeyLength($length);
+ }
+
+ /**
+ * Sets the key.
+ *
+ * Rijndael supports five different key lengths, AES only supports three.
+ *
+ * @see \phpseclib\Crypt\Rijndael:setKey()
+ * @see setKeyLength()
+ * @access public
+ * @param string $key
+ */
+ function setKey($key)
+ {
+ parent::setKey($key);
+
+ if (!$this->explicit_key_length) {
+ $length = strlen($key);
+ switch (true) {
+ case $length <= 16:
+ $this->key_length = 16;
+ break;
+ case $length <= 24:
+ $this->key_length = 24;
+ break;
+ default:
+ $this->key_length = 32;
+ }
+ $this->_setEngine();
+ }
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
new file mode 100644
index 0000000..03b176e
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Base.php
@@ -0,0 +1,2708 @@
+<?php
+
+/**
+ * Base Class for all \phpseclib\Crypt\* cipher classes
+ *
+ * PHP version 5
+ *
+ * Internally for phpseclib developers:
+ * If you plan to add a new cipher class, please note following rules:
+ *
+ * - The new \phpseclib\Crypt\* cipher class should extend \phpseclib\Crypt\Base
+ *
+ * - Following methods are then required to be overridden/overloaded:
+ *
+ * - _encryptBlock()
+ *
+ * - _decryptBlock()
+ *
+ * - _setupKey()
+ *
+ * - All other methods are optional to be overridden/overloaded
+ *
+ * - Look at the source code of the current ciphers how they extend \phpseclib\Crypt\Base
+ * and take one of them as a start up for the new cipher class.
+ *
+ * - Please read all the other comments/notes/hints here also for each class var/method
+ *
+ * @category Crypt
+ * @package Base
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
+ * @copyright 2007 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Base Class for all \phpseclib\Crypt\* cipher classes
+ *
+ * @package Base
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
+ */
+abstract class Base
+{
+ /**#@+
+ * @access public
+ * @see \phpseclib\Crypt\Base::encrypt()
+ * @see \phpseclib\Crypt\Base::decrypt()
+ */
+ /**
+ * Encrypt / decrypt using the Counter mode.
+ *
+ * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
+ */
+ const MODE_CTR = -1;
+ /**
+ * Encrypt / decrypt using the Electronic Code Book mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
+ */
+ const MODE_ECB = 1;
+ /**
+ * Encrypt / decrypt using the Code Book Chaining mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
+ */
+ const MODE_CBC = 2;
+ /**
+ * Encrypt / decrypt using the Cipher Feedback mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
+ */
+ const MODE_CFB = 3;
+ /**
+ * Encrypt / decrypt using the Cipher Feedback mode (8bit)
+ */
+ const MODE_CFB8 = 38;
+ /**
+ * Encrypt / decrypt using the Output Feedback mode.
+ *
+ * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
+ */
+ const MODE_OFB = 4;
+ /**
+ * Encrypt / decrypt using streaming mode.
+ */
+ const MODE_STREAM = 5;
+ /**#@-*/
+
+ /**
+ * Whirlpool available flag
+ *
+ * @see \phpseclib\Crypt\Base::_hashInlineCryptFunction()
+ * @var bool
+ * @access private
+ */
+ static $WHIRLPOOL_AVAILABLE;
+
+ /**#@+
+ * @access private
+ * @see \phpseclib\Crypt\Base::__construct()
+ */
+ /**
+ * Base value for the internal implementation $engine switch
+ */
+ const ENGINE_INTERNAL = 1;
+ /**
+ * Base value for the mcrypt implementation $engine switch
+ */
+ const ENGINE_MCRYPT = 2;
+ /**
+ * Base value for the mcrypt implementation $engine switch
+ */
+ const ENGINE_OPENSSL = 3;
+ /**#@-*/
+
+ /**
+ * The Encryption Mode
+ *
+ * @see self::__construct()
+ * @var int
+ * @access private
+ */
+ var $mode;
+
+ /**
+ * The Block Length of the block cipher
+ *
+ * @var int
+ * @access private
+ */
+ var $block_size = 16;
+
+ /**
+ * The Key
+ *
+ * @see self::setKey()
+ * @var string
+ * @access private
+ */
+ var $key = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
+
+ /**
+ * The Initialization Vector
+ *
+ * @see self::setIV()
+ * @var string
+ * @access private
+ */
+ var $iv;
+
+ /**
+ * A "sliding" Initialization Vector
+ *
+ * @see self::enableContinuousBuffer()
+ * @see self::_clearBuffers()
+ * @var string
+ * @access private
+ */
+ var $encryptIV;
+
+ /**
+ * A "sliding" Initialization Vector
+ *
+ * @see self::enableContinuousBuffer()
+ * @see self::_clearBuffers()
+ * @var string
+ * @access private
+ */
+ var $decryptIV;
+
+ /**
+ * Continuous Buffer status
+ *
+ * @see self::enableContinuousBuffer()
+ * @var bool
+ * @access private
+ */
+ var $continuousBuffer = false;
+
+ /**
+ * Encryption buffer for CTR, OFB and CFB modes
+ *
+ * @see self::encrypt()
+ * @see self::_clearBuffers()
+ * @var array
+ * @access private
+ */
+ var $enbuffer;
+
+ /**
+ * Decryption buffer for CTR, OFB and CFB modes
+ *
+ * @see self::decrypt()
+ * @see self::_clearBuffers()
+ * @var array
+ * @access private
+ */
+ var $debuffer;
+
+ /**
+ * mcrypt resource for encryption
+ *
+ * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
+ * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
+ *
+ * @see self::encrypt()
+ * @var resource
+ * @access private
+ */
+ var $enmcrypt;
+
+ /**
+ * mcrypt resource for decryption
+ *
+ * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
+ * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
+ *
+ * @see self::decrypt()
+ * @var resource
+ * @access private
+ */
+ var $demcrypt;
+
+ /**
+ * Does the enmcrypt resource need to be (re)initialized?
+ *
+ * @see \phpseclib\Crypt\Twofish::setKey()
+ * @see \phpseclib\Crypt\Twofish::setIV()
+ * @var bool
+ * @access private
+ */
+ var $enchanged = true;
+
+ /**
+ * Does the demcrypt resource need to be (re)initialized?
+ *
+ * @see \phpseclib\Crypt\Twofish::setKey()
+ * @see \phpseclib\Crypt\Twofish::setIV()
+ * @var bool
+ * @access private
+ */
+ var $dechanged = true;
+
+ /**
+ * mcrypt resource for CFB mode
+ *
+ * mcrypt's CFB mode, in (and only in) buffered context,
+ * is broken, so phpseclib implements the CFB mode by it self,
+ * even when the mcrypt php extension is available.
+ *
+ * In order to do the CFB-mode work (fast) phpseclib
+ * use a separate ECB-mode mcrypt resource.
+ *
+ * @link http://phpseclib.sourceforge.net/cfb-demo.phps
+ * @see self::encrypt()
+ * @see self::decrypt()
+ * @see self::_setupMcrypt()
+ * @var resource
+ * @access private
+ */
+ var $ecb;
+
+ /**
+ * Optimizing value while CFB-encrypting
+ *
+ * Only relevant if $continuousBuffer enabled
+ * and $engine == self::ENGINE_MCRYPT
+ *
+ * It's faster to re-init $enmcrypt if
+ * $buffer bytes > $cfb_init_len than
+ * using the $ecb resource furthermore.
+ *
+ * This value depends of the chosen cipher
+ * and the time it would be needed for it's
+ * initialization [by mcrypt_generic_init()]
+ * which, typically, depends on the complexity
+ * on its internaly Key-expanding algorithm.
+ *
+ * @see self::encrypt()
+ * @var int
+ * @access private
+ */
+ var $cfb_init_len = 600;
+
+ /**
+ * Does internal cipher state need to be (re)initialized?
+ *
+ * @see self::setKey()
+ * @see self::setIV()
+ * @see self::disableContinuousBuffer()
+ * @var bool
+ * @access private
+ */
+ var $changed = true;
+
+ /**
+ * Padding status
+ *
+ * @see self::enablePadding()
+ * @var bool
+ * @access private
+ */
+ var $padding = true;
+
+ /**
+ * Is the mode one that is paddable?
+ *
+ * @see self::__construct()
+ * @var bool
+ * @access private
+ */
+ var $paddable = false;
+
+ /**
+ * Holds which crypt engine internaly should be use,
+ * which will be determined automatically on __construct()
+ *
+ * Currently available $engines are:
+ * - self::ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required)
+ * - self::ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required)
+ * - self::ENGINE_INTERNAL (slower, pure php-engine, no php-extension required)
+ *
+ * @see self::_setEngine()
+ * @see self::encrypt()
+ * @see self::decrypt()
+ * @var int
+ * @access private
+ */
+ var $engine;
+
+ /**
+ * Holds the preferred crypt engine
+ *
+ * @see self::_setEngine()
+ * @see self::setPreferredEngine()
+ * @var int
+ * @access private
+ */
+ var $preferredEngine;
+
+ /**
+ * The mcrypt specific name of the cipher
+ *
+ * Only used if $engine == self::ENGINE_MCRYPT
+ *
+ * @link http://www.php.net/mcrypt_module_open
+ * @link http://www.php.net/mcrypt_list_algorithms
+ * @see self::_setupMcrypt()
+ * @var string
+ * @access private
+ */
+ var $cipher_name_mcrypt;
+
+ /**
+ * The openssl specific name of the cipher
+ *
+ * Only used if $engine == self::ENGINE_OPENSSL
+ *
+ * @link http://www.php.net/openssl-get-cipher-methods
+ * @var string
+ * @access private
+ */
+ var $cipher_name_openssl;
+
+ /**
+ * The openssl specific name of the cipher in ECB mode
+ *
+ * If OpenSSL does not support the mode we're trying to use (CTR)
+ * it can still be emulated with ECB mode.
+ *
+ * @link http://www.php.net/openssl-get-cipher-methods
+ * @var string
+ * @access private
+ */
+ var $cipher_name_openssl_ecb;
+
+ /**
+ * The default salt used by setPassword()
+ *
+ * @see self::setPassword()
+ * @var string
+ * @access private
+ */
+ var $password_default_salt = 'phpseclib/salt';
+
+ /**
+ * The name of the performance-optimized callback function
+ *
+ * Used by encrypt() / decrypt()
+ * only if $engine == self::ENGINE_INTERNAL
+ *
+ * @see self::encrypt()
+ * @see self::decrypt()
+ * @see self::_setupInlineCrypt()
+ * @see self::$use_inline_crypt
+ * @var Callback
+ * @access private
+ */
+ var $inline_crypt;
+
+ /**
+ * Holds whether performance-optimized $inline_crypt() can/should be used.
+ *
+ * @see self::encrypt()
+ * @see self::decrypt()
+ * @see self::inline_crypt
+ * @var mixed
+ * @access private
+ */
+ var $use_inline_crypt;
+
+ /**
+ * If OpenSSL can be used in ECB but not in CTR we can emulate CTR
+ *
+ * @see self::_openssl_ctr_process()
+ * @var bool
+ * @access private
+ */
+ var $openssl_emulate_ctr = false;
+
+ /**
+ * Determines what options are passed to openssl_encrypt/decrypt
+ *
+ * @see self::isValidEngine()
+ * @var mixed
+ * @access private
+ */
+ var $openssl_options;
+
+ /**
+ * Has the key length explicitly been set or should it be derived from the key, itself?
+ *
+ * @see self::setKeyLength()
+ * @var bool
+ * @access private
+ */
+ var $explicit_key_length = false;
+
+ /**
+ * Don't truncate / null pad key
+ *
+ * @see self::_clearBuffers()
+ * @var bool
+ * @access private
+ */
+ var $skip_key_adjustment = false;
+
+ /**
+ * Default Constructor.
+ *
+ * Determines whether or not the mcrypt extension should be used.
+ *
+ * $mode could be:
+ *
+ * - self::MODE_ECB
+ *
+ * - self::MODE_CBC
+ *
+ * - self::MODE_CTR
+ *
+ * - self::MODE_CFB
+ *
+ * - self::MODE_OFB
+ *
+ * If not explicitly set, self::MODE_CBC will be used.
+ *
+ * @param int $mode
+ * @access public
+ */
+ function __construct($mode = self::MODE_CBC)
+ {
+ // $mode dependent settings
+ switch ($mode) {
+ case self::MODE_ECB:
+ $this->paddable = true;
+ $this->mode = self::MODE_ECB;
+ break;
+ case self::MODE_CTR:
+ case self::MODE_CFB:
+ case self::MODE_CFB8:
+ case self::MODE_OFB:
+ case self::MODE_STREAM:
+ $this->mode = $mode;
+ break;
+ case self::MODE_CBC:
+ default:
+ $this->paddable = true;
+ $this->mode = self::MODE_CBC;
+ }
+
+ $this->_setEngine();
+
+ // Determining whether inline crypting can be used by the cipher
+ if ($this->use_inline_crypt !== false) {
+ $this->use_inline_crypt = version_compare(PHP_VERSION, '5.3.0') >= 0 || function_exists('create_function');
+ }
+ }
+
+ /**
+ * Sets the initialization vector. (optional)
+ *
+ * SetIV is not required when self::MODE_ECB (or ie for AES: \phpseclib\Crypt\AES::MODE_ECB) is being used. If not explicitly set, it'll be assumed
+ * to be all zero's.
+ *
+ * @access public
+ * @param string $iv
+ * @internal Can be overwritten by a sub class, but does not have to be
+ */
+ function setIV($iv)
+ {
+ if ($this->mode == self::MODE_ECB) {
+ return;
+ }
+
+ $this->iv = $iv;
+ $this->changed = true;
+ }
+
+ /**
+ * Sets the key length.
+ *
+ * Keys with explicitly set lengths need to be treated accordingly
+ *
+ * @access public
+ * @param int $length
+ */
+ function setKeyLength($length)
+ {
+ $this->explicit_key_length = true;
+ $this->changed = true;
+ $this->_setEngine();
+ }
+
+ /**
+ * Returns the current key length in bits
+ *
+ * @access public
+ * @return int
+ */
+ function getKeyLength()
+ {
+ return $this->key_length << 3;
+ }
+
+ /**
+ * Returns the current block length in bits
+ *
+ * @access public
+ * @return int
+ */
+ function getBlockLength()
+ {
+ return $this->block_size << 3;
+ }
+
+ /**
+ * Sets the key.
+ *
+ * The min/max length(s) of the key depends on the cipher which is used.
+ * If the key not fits the length(s) of the cipher it will paded with null bytes
+ * up to the closest valid key length. If the key is more than max length,
+ * we trim the excess bits.
+ *
+ * If the key is not explicitly set, it'll be assumed to be all null bytes.
+ *
+ * @access public
+ * @param string $key
+ * @internal Could, but not must, extend by the child Crypt_* class
+ */
+ function setKey($key)
+ {
+ if (!$this->explicit_key_length) {
+ $this->setKeyLength(strlen($key) << 3);
+ $this->explicit_key_length = false;
+ }
+
+ $this->key = $key;
+ $this->changed = true;
+ $this->_setEngine();
+ }
+
+ /**
+ * Sets the password.
+ *
+ * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
+ * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1:
+ * $hash, $salt, $count, $dkLen
+ *
+ * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php
+ *
+ * @see Crypt/Hash.php
+ * @param string $password
+ * @param string $method
+ * @return bool
+ * @access public
+ * @internal Could, but not must, extend by the child Crypt_* class
+ */
+ function setPassword($password, $method = 'pbkdf2')
+ {
+ $key = '';
+
+ switch ($method) {
+ default: // 'pbkdf2' or 'pbkdf1'
+ $func_args = func_get_args();
+
+ // Hash function
+ $hash = isset($func_args[2]) ? $func_args[2] : 'sha1';
+
+ // WPA and WPA2 use the SSID as the salt
+ $salt = isset($func_args[3]) ? $func_args[3] : $this->password_default_salt;
+
+ // RFC2898#section-4.2 uses 1,000 iterations by default
+ // WPA and WPA2 use 4,096.
+ $count = isset($func_args[4]) ? $func_args[4] : 1000;
+
+ // Keylength
+ if (isset($func_args[5])) {
+ $dkLen = $func_args[5];
+ } else {
+ $dkLen = $method == 'pbkdf1' ? 2 * $this->key_length : $this->key_length;
+ }
+
+ switch (true) {
+ case $method == 'pbkdf1':
+ $hashObj = new Hash();
+ $hashObj->setHash($hash);
+ if ($dkLen > $hashObj->getLength()) {
+ user_error('Derived key too long');
+ return false;
+ }
+ $t = $password . $salt;
+ for ($i = 0; $i < $count; ++$i) {
+ $t = $hashObj->hash($t);
+ }
+ $key = substr($t, 0, $dkLen);
+
+ $this->setKey(substr($key, 0, $dkLen >> 1));
+ $this->setIV(substr($key, $dkLen >> 1));
+
+ return true;
+ // Determining if php[>=5.5.0]'s hash_pbkdf2() function avail- and useable
+ case !function_exists('hash_pbkdf2'):
+ case !function_exists('hash_algos'):
+ case !in_array($hash, hash_algos()):
+ $i = 1;
+ $hmac = new Hash();
+ $hmac->setHash($hash);
+ $hmac->setKey($password);
+ while (strlen($key) < $dkLen) {
+ $f = $u = $hmac->hash($salt . pack('N', $i++));
+ for ($j = 2; $j <= $count; ++$j) {
+ $u = $hmac->hash($u);
+ $f^= $u;
+ }
+ $key.= $f;
+ }
+ $key = substr($key, 0, $dkLen);
+ break;
+ default:
+ $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true);
+ }
+ }
+
+ $this->setKey($key);
+
+ return true;
+ }
+
+ /**
+ * Encrypts a message.
+ *
+ * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher
+ * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's
+ * necessary are discussed in the following
+ * URL:
+ *
+ * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
+ *
+ * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
+ * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that
+ * length.
+ *
+ * @see self::decrypt()
+ * @access public
+ * @param string $plaintext
+ * @return string $ciphertext
+ * @internal Could, but not must, extend by the child Crypt_* class
+ */
+ function encrypt($plaintext)
+ {
+ if ($this->paddable) {
+ $plaintext = $this->_pad($plaintext);
+ }
+
+ if ($this->engine === self::ENGINE_OPENSSL) {
+ if ($this->changed) {
+ $this->_clearBuffers();
+ $this->changed = false;
+ }
+ switch ($this->mode) {
+ case self::MODE_STREAM:
+ return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+ case self::MODE_ECB:
+ $result = @openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+ return !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
+ case self::MODE_CBC:
+ $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
+ if (!defined('OPENSSL_RAW_DATA')) {
+ $result = substr($result, 0, -$this->block_size);
+ }
+ if ($this->continuousBuffer) {
+ $this->encryptIV = substr($result, -$this->block_size);
+ }
+ return $result;
+ case self::MODE_CTR:
+ return $this->_openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer);
+ case self::MODE_CFB:
+ // cfb loosely routines inspired by openssl's:
+ // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
+ $ciphertext = '';
+ if ($this->continuousBuffer) {
+ $iv = &$this->encryptIV;
+ $pos = &$this->enbuffer['pos'];
+ } else {
+ $iv = $this->encryptIV;
+ $pos = 0;
+ }
+ $len = strlen($plaintext);
+ $i = 0;
+ if ($pos) {
+ $orig_pos = $pos;
+ $max = $this->block_size - $pos;
+ if ($len >= $max) {
+ $i = $max;
+ $len-= $max;
+ $pos = 0;
+ } else {
+ $i = $len;
+ $pos+= $len;
+ $len = 0;
+ }
+ // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
+ $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
+ $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
+ $plaintext = substr($plaintext, $i);
+ }
+
+ $overflow = $len % $this->block_size;
+
+ if ($overflow) {
+ $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+ $iv = $this->_string_pop($ciphertext, $this->block_size);
+
+ $size = $len - $overflow;
+ $block = $iv ^ substr($plaintext, -$overflow);
+ $iv = substr_replace($iv, $block, 0, $overflow);
+ $ciphertext.= $block;
+ $pos = $overflow;
+ } elseif ($len) {
+ $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+ $iv = substr($ciphertext, -$this->block_size);
+ }
+
+ return $ciphertext;
+ case self::MODE_CFB8:
+ $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->encryptIV);
+ if ($this->continuousBuffer) {
+ if (($len = strlen($ciphertext)) >= $this->block_size) {
+ $this->encryptIV = substr($ciphertext, -$this->block_size);
+ } else {
+ $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len);
+ }
+ }
+ return $ciphertext;
+ case self::MODE_OFB:
+ return $this->_openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer);
+ }
+ }
+
+ if ($this->engine === self::ENGINE_MCRYPT) {
+ if ($this->changed) {
+ $this->_setupMcrypt();
+ $this->changed = false;
+ }
+ if ($this->enchanged) {
+ @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
+ $this->enchanged = false;
+ }
+
+ // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
+ // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's
+ // rewritten CFB implementation the above outputs the same thing twice.
+ if ($this->mode == self::MODE_CFB && $this->continuousBuffer) {
+ $block_size = $this->block_size;
+ $iv = &$this->encryptIV;
+ $pos = &$this->enbuffer['pos'];
+ $len = strlen($plaintext);
+ $ciphertext = '';
+ $i = 0;
+ if ($pos) {
+ $orig_pos = $pos;
+ $max = $block_size - $pos;
+ if ($len >= $max) {
+ $i = $max;
+ $len-= $max;
+ $pos = 0;
+ } else {
+ $i = $len;
+ $pos+= $len;
+ $len = 0;
+ }
+ $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
+ $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
+ $this->enbuffer['enmcrypt_init'] = true;
+ }
+ if ($len >= $block_size) {
+ if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) {
+ if ($this->enbuffer['enmcrypt_init'] === true) {
+ @mcrypt_generic_init($this->enmcrypt, $this->key, $iv);
+ $this->enbuffer['enmcrypt_init'] = false;
+ }
+ $ciphertext.= @mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size));
+ $iv = substr($ciphertext, -$block_size);
+ $len%= $block_size;
+ } else {
+ while ($len >= $block_size) {
+ $iv = @mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size);
+ $ciphertext.= $iv;
+ $len-= $block_size;
+ $i+= $block_size;
+ }
+ }
+ }
+
+ if ($len) {
+ $iv = @mcrypt_generic($this->ecb, $iv);
+ $block = $iv ^ substr($plaintext, -$len);
+ $iv = substr_replace($iv, $block, 0, $len);
+ $ciphertext.= $block;
+ $pos = $len;
+ }
+
+ return $ciphertext;
+ }
+
+ $ciphertext = @mcrypt_generic($this->enmcrypt, $plaintext);
+
+ if (!$this->continuousBuffer) {
+ @mcrypt_generic_init($this->enmcrypt, $this->key, $this->encryptIV);
+ }
+
+ return $ciphertext;
+ }
+
+ if ($this->changed) {
+ $this->_setup();
+ $this->changed = false;
+ }
+ if ($this->use_inline_crypt) {
+ $inline = $this->inline_crypt;
+ return $inline('encrypt', $this, $plaintext);
+ }
+
+ $buffer = &$this->enbuffer;
+ $block_size = $this->block_size;
+ $ciphertext = '';
+ switch ($this->mode) {
+ case self::MODE_ECB:
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+ $ciphertext.= $this->_encryptBlock(substr($plaintext, $i, $block_size));
+ }
+ break;
+ case self::MODE_CBC:
+ $xor = $this->encryptIV;
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+ $block = substr($plaintext, $i, $block_size);
+ $block = $this->_encryptBlock($block ^ $xor);
+ $xor = $block;
+ $ciphertext.= $block;
+ }
+ if ($this->continuousBuffer) {
+ $this->encryptIV = $xor;
+ }
+ break;
+ case self::MODE_CTR:
+ $xor = $this->encryptIV;
+ if (strlen($buffer['ciphertext'])) {
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+ $block = substr($plaintext, $i, $block_size);
+ if (strlen($block) > strlen($buffer['ciphertext'])) {
+ $buffer['ciphertext'].= $this->_encryptBlock($xor);
+ }
+ $this->_increment_str($xor);
+ $key = $this->_string_shift($buffer['ciphertext'], $block_size);
+ $ciphertext.= $block ^ $key;
+ }
+ } else {
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+ $block = substr($plaintext, $i, $block_size);
+ $key = $this->_encryptBlock($xor);
+ $this->_increment_str($xor);
+ $ciphertext.= $block ^ $key;
+ }
+ }
+ if ($this->continuousBuffer) {
+ $this->encryptIV = $xor;
+ if ($start = strlen($plaintext) % $block_size) {
+ $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
+ }
+ }
+ break;
+ case self::MODE_CFB:
+ // cfb loosely routines inspired by openssl's:
+ // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
+ if ($this->continuousBuffer) {
+ $iv = &$this->encryptIV;
+ $pos = &$buffer['pos'];
+ } else {
+ $iv = $this->encryptIV;
+ $pos = 0;
+ }
+ $len = strlen($plaintext);
+ $i = 0;
+ if ($pos) {
+ $orig_pos = $pos;
+ $max = $block_size - $pos;
+ if ($len >= $max) {
+ $i = $max;
+ $len-= $max;
+ $pos = 0;
+ } else {
+ $i = $len;
+ $pos+= $len;
+ $len = 0;
+ }
+ // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
+ $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
+ $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
+ }
+ while ($len >= $block_size) {
+ $iv = $this->_encryptBlock($iv) ^ substr($plaintext, $i, $block_size);
+ $ciphertext.= $iv;
+ $len-= $block_size;
+ $i+= $block_size;
+ }
+ if ($len) {
+ $iv = $this->_encryptBlock($iv);
+ $block = $iv ^ substr($plaintext, $i);
+ $iv = substr_replace($iv, $block, 0, $len);
+ $ciphertext.= $block;
+ $pos = $len;
+ }
+ break;
+ case self::MODE_CFB8:
+ $ciphertext = '';
+ $len = strlen($plaintext);
+ $iv = $this->encryptIV;
+
+ for ($i = 0; $i < $len; ++$i) {
+ $ciphertext .= ($c = $plaintext[$i] ^ $this->_encryptBlock($iv));
+ $iv = substr($iv, 1) . $c;
+ }
+
+ if ($this->continuousBuffer) {
+ if ($len >= $block_size) {
+ $this->encryptIV = substr($ciphertext, -$block_size);
+ } else {
+ $this->encryptIV = substr($this->encryptIV, $len - $block_size) . substr($ciphertext, -$len);
+ }
+ }
+ break;
+ case self::MODE_OFB:
+ $xor = $this->encryptIV;
+ if (strlen($buffer['xor'])) {
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+ $block = substr($plaintext, $i, $block_size);
+ if (strlen($block) > strlen($buffer['xor'])) {
+ $xor = $this->_encryptBlock($xor);
+ $buffer['xor'].= $xor;
+ }
+ $key = $this->_string_shift($buffer['xor'], $block_size);
+ $ciphertext.= $block ^ $key;
+ }
+ } else {
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+ $xor = $this->_encryptBlock($xor);
+ $ciphertext.= substr($plaintext, $i, $block_size) ^ $xor;
+ }
+ $key = $xor;
+ }
+ if ($this->continuousBuffer) {
+ $this->encryptIV = $xor;
+ if ($start = strlen($plaintext) % $block_size) {
+ $buffer['xor'] = substr($key, $start) . $buffer['xor'];
+ }
+ }
+ break;
+ case self::MODE_STREAM:
+ $ciphertext = $this->_encryptBlock($plaintext);
+ break;
+ }
+
+ return $ciphertext;
+ }
+
+ /**
+ * Decrypts a message.
+ *
+ * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until
+ * it is.
+ *
+ * @see self::encrypt()
+ * @access public
+ * @param string $ciphertext
+ * @return string $plaintext
+ * @internal Could, but not must, extend by the child Crypt_* class
+ */
+ function decrypt($ciphertext)
+ {
+ if ($this->paddable) {
+ // we pad with chr(0) since that's what mcrypt_generic does. to quote from {@link http://www.php.net/function.mcrypt-generic}:
+ // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
+ $ciphertext = str_pad($ciphertext, strlen($ciphertext) + ($this->block_size - strlen($ciphertext) % $this->block_size) % $this->block_size, chr(0));
+ }
+
+ if ($this->engine === self::ENGINE_OPENSSL) {
+ if ($this->changed) {
+ $this->_clearBuffers();
+ $this->changed = false;
+ }
+ switch ($this->mode) {
+ case self::MODE_STREAM:
+ $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+ break;
+ case self::MODE_ECB:
+ if (!defined('OPENSSL_RAW_DATA')) {
+ $ciphertext.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $this->key, true);
+ }
+ $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options);
+ break;
+ case self::MODE_CBC:
+ if (!defined('OPENSSL_RAW_DATA')) {
+ $padding = str_repeat(chr($this->block_size), $this->block_size) ^ substr($ciphertext, -$this->block_size);
+ $ciphertext.= substr(@openssl_encrypt($padding, $this->cipher_name_openssl_ecb, $this->key, true), 0, $this->block_size);
+ $offset = 2 * $this->block_size;
+ } else {
+ $offset = $this->block_size;
+ }
+ $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV);
+ if ($this->continuousBuffer) {
+ $this->decryptIV = substr($ciphertext, -$offset, $this->block_size);
+ }
+ break;
+ case self::MODE_CTR:
+ $plaintext = $this->_openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer);
+ break;
+ case self::MODE_CFB:
+ // cfb loosely routines inspired by openssl's:
+ // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1}
+ $plaintext = '';
+ if ($this->continuousBuffer) {
+ $iv = &$this->decryptIV;
+ $pos = &$this->buffer['pos'];
+ } else {
+ $iv = $this->decryptIV;
+ $pos = 0;
+ }
+ $len = strlen($ciphertext);
+ $i = 0;
+ if ($pos) {
+ $orig_pos = $pos;
+ $max = $this->block_size - $pos;
+ if ($len >= $max) {
+ $i = $max;
+ $len-= $max;
+ $pos = 0;
+ } else {
+ $i = $len;
+ $pos+= $len;
+ $len = 0;
+ }
+ // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize
+ $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
+ $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
+ $ciphertext = substr($ciphertext, $i);
+ }
+ $overflow = $len % $this->block_size;
+ if ($overflow) {
+ $plaintext.= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+ if ($len - $overflow) {
+ $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow);
+ }
+ $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+ $plaintext.= $iv ^ substr($ciphertext, -$overflow);
+ $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow);
+ $pos = $overflow;
+ } elseif ($len) {
+ $plaintext.= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $iv);
+ $iv = substr($ciphertext, -$this->block_size);
+ }
+ break;
+ case self::MODE_CFB8:
+ $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, $this->openssl_options, $this->decryptIV);
+ if ($this->continuousBuffer) {
+ if (($len = strlen($ciphertext)) >= $this->block_size) {
+ $this->decryptIV = substr($ciphertext, -$this->block_size);
+ } else {
+ $this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len);
+ }
+ }
+ break;
+ case self::MODE_OFB:
+ $plaintext = $this->_openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer);
+ }
+
+ return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
+ }
+
+ if ($this->engine === self::ENGINE_MCRYPT) {
+ $block_size = $this->block_size;
+ if ($this->changed) {
+ $this->_setupMcrypt();
+ $this->changed = false;
+ }
+ if ($this->dechanged) {
+ @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
+ $this->dechanged = false;
+ }
+
+ if ($this->mode == self::MODE_CFB && $this->continuousBuffer) {
+ $iv = &$this->decryptIV;
+ $pos = &$this->debuffer['pos'];
+ $len = strlen($ciphertext);
+ $plaintext = '';
+ $i = 0;
+ if ($pos) {
+ $orig_pos = $pos;
+ $max = $block_size - $pos;
+ if ($len >= $max) {
+ $i = $max;
+ $len-= $max;
+ $pos = 0;
+ } else {
+ $i = $len;
+ $pos+= $len;
+ $len = 0;
+ }
+ // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
+ $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
+ $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
+ }
+ if ($len >= $block_size) {
+ $cb = substr($ciphertext, $i, $len - $len % $block_size);
+ $plaintext.= @mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
+ $iv = substr($cb, -$block_size);
+ $len%= $block_size;
+ }
+ if ($len) {
+ $iv = @mcrypt_generic($this->ecb, $iv);
+ $plaintext.= $iv ^ substr($ciphertext, -$len);
+ $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
+ $pos = $len;
+ }
+
+ return $plaintext;
+ }
+
+ $plaintext = @mdecrypt_generic($this->demcrypt, $ciphertext);
+
+ if (!$this->continuousBuffer) {
+ @mcrypt_generic_init($this->demcrypt, $this->key, $this->decryptIV);
+ }
+
+ return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
+ }
+
+ if ($this->changed) {
+ $this->_setup();
+ $this->changed = false;
+ }
+ if ($this->use_inline_crypt) {
+ $inline = $this->inline_crypt;
+ return $inline('decrypt', $this, $ciphertext);
+ }
+
+ $block_size = $this->block_size;
+
+ $buffer = &$this->debuffer;
+ $plaintext = '';
+ switch ($this->mode) {
+ case self::MODE_ECB:
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+ $plaintext.= $this->_decryptBlock(substr($ciphertext, $i, $block_size));
+ }
+ break;
+ case self::MODE_CBC:
+ $xor = $this->decryptIV;
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+ $block = substr($ciphertext, $i, $block_size);
+ $plaintext.= $this->_decryptBlock($block) ^ $xor;
+ $xor = $block;
+ }
+ if ($this->continuousBuffer) {
+ $this->decryptIV = $xor;
+ }
+ break;
+ case self::MODE_CTR:
+ $xor = $this->decryptIV;
+ if (strlen($buffer['ciphertext'])) {
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+ $block = substr($ciphertext, $i, $block_size);
+ if (strlen($block) > strlen($buffer['ciphertext'])) {
+ $buffer['ciphertext'].= $this->_encryptBlock($xor);
+ $this->_increment_str($xor);
+ }
+ $key = $this->_string_shift($buffer['ciphertext'], $block_size);
+ $plaintext.= $block ^ $key;
+ }
+ } else {
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+ $block = substr($ciphertext, $i, $block_size);
+ $key = $this->_encryptBlock($xor);
+ $this->_increment_str($xor);
+ $plaintext.= $block ^ $key;
+ }
+ }
+ if ($this->continuousBuffer) {
+ $this->decryptIV = $xor;
+ if ($start = strlen($ciphertext) % $block_size) {
+ $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
+ }
+ }
+ break;
+ case self::MODE_CFB:
+ if ($this->continuousBuffer) {
+ $iv = &$this->decryptIV;
+ $pos = &$buffer['pos'];
+ } else {
+ $iv = $this->decryptIV;
+ $pos = 0;
+ }
+ $len = strlen($ciphertext);
+ $i = 0;
+ if ($pos) {
+ $orig_pos = $pos;
+ $max = $block_size - $pos;
+ if ($len >= $max) {
+ $i = $max;
+ $len-= $max;
+ $pos = 0;
+ } else {
+ $i = $len;
+ $pos+= $len;
+ $len = 0;
+ }
+ // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize
+ $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
+ $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
+ }
+ while ($len >= $block_size) {
+ $iv = $this->_encryptBlock($iv);
+ $cb = substr($ciphertext, $i, $block_size);
+ $plaintext.= $iv ^ $cb;
+ $iv = $cb;
+ $len-= $block_size;
+ $i+= $block_size;
+ }
+ if ($len) {
+ $iv = $this->_encryptBlock($iv);
+ $plaintext.= $iv ^ substr($ciphertext, $i);
+ $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len);
+ $pos = $len;
+ }
+ break;
+ case self::MODE_CFB8:
+ $plaintext = '';
+ $len = strlen($ciphertext);
+ $iv = $this->decryptIV;
+
+ for ($i = 0; $i < $len; ++$i) {
+ $plaintext .= $ciphertext[$i] ^ $this->_encryptBlock($iv);
+ $iv = substr($iv, 1) . $ciphertext[$i];
+ }
+
+ if ($this->continuousBuffer) {
+ if ($len >= $block_size) {
+ $this->decryptIV = substr($ciphertext, -$block_size);
+ } else {
+ $this->decryptIV = substr($this->decryptIV, $len - $block_size) . substr($ciphertext, -$len);
+ }
+ }
+ break;
+ case self::MODE_OFB:
+ $xor = $this->decryptIV;
+ if (strlen($buffer['xor'])) {
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+ $block = substr($ciphertext, $i, $block_size);
+ if (strlen($block) > strlen($buffer['xor'])) {
+ $xor = $this->_encryptBlock($xor);
+ $buffer['xor'].= $xor;
+ }
+ $key = $this->_string_shift($buffer['xor'], $block_size);
+ $plaintext.= $block ^ $key;
+ }
+ } else {
+ for ($i = 0; $i < strlen($ciphertext); $i+=$block_size) {
+ $xor = $this->_encryptBlock($xor);
+ $plaintext.= substr($ciphertext, $i, $block_size) ^ $xor;
+ }
+ $key = $xor;
+ }
+ if ($this->continuousBuffer) {
+ $this->decryptIV = $xor;
+ if ($start = strlen($ciphertext) % $block_size) {
+ $buffer['xor'] = substr($key, $start) . $buffer['xor'];
+ }
+ }
+ break;
+ case self::MODE_STREAM:
+ $plaintext = $this->_decryptBlock($ciphertext);
+ break;
+ }
+ return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
+ }
+
+ /**
+ * OpenSSL CTR Processor
+ *
+ * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
+ * for CTR is the same for both encrypting and decrypting this function is re-used by both Base::encrypt()
+ * and Base::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this
+ * function will emulate CTR with ECB when necessary.
+ *
+ * @see self::encrypt()
+ * @see self::decrypt()
+ * @param string $plaintext
+ * @param string $encryptIV
+ * @param array $buffer
+ * @return string
+ * @access private
+ */
+ function _openssl_ctr_process($plaintext, &$encryptIV, &$buffer)
+ {
+ $ciphertext = '';
+
+ $block_size = $this->block_size;
+ $key = $this->key;
+
+ if ($this->openssl_emulate_ctr) {
+ $xor = $encryptIV;
+ if (strlen($buffer['ciphertext'])) {
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+ $block = substr($plaintext, $i, $block_size);
+ if (strlen($block) > strlen($buffer['ciphertext'])) {
+ $result = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+ $result = !defined('OPENSSL_RAW_DATA') ? substr($result, 0, -$this->block_size) : $result;
+ $buffer['ciphertext'].= $result;
+ }
+ $this->_increment_str($xor);
+ $otp = $this->_string_shift($buffer['ciphertext'], $block_size);
+ $ciphertext.= $block ^ $otp;
+ }
+ } else {
+ for ($i = 0; $i < strlen($plaintext); $i+=$block_size) {
+ $block = substr($plaintext, $i, $block_size);
+ $otp = @openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+ $otp = !defined('OPENSSL_RAW_DATA') ? substr($otp, 0, -$this->block_size) : $otp;
+ $this->_increment_str($xor);
+ $ciphertext.= $block ^ $otp;
+ }
+ }
+ if ($this->continuousBuffer) {
+ $encryptIV = $xor;
+ if ($start = strlen($plaintext) % $block_size) {
+ $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
+ }
+ }
+
+ return $ciphertext;
+ }
+
+ if (strlen($buffer['ciphertext'])) {
+ $ciphertext = $plaintext ^ $this->_string_shift($buffer['ciphertext'], strlen($plaintext));
+ $plaintext = substr($plaintext, strlen($ciphertext));
+
+ if (!strlen($plaintext)) {
+ return $ciphertext;
+ }
+ }
+
+ $overflow = strlen($plaintext) % $block_size;
+ if ($overflow) {
+ $plaintext2 = $this->_string_pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2
+ $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+ $temp = $this->_string_pop($encrypted, $block_size);
+ $ciphertext.= $encrypted . ($plaintext2 ^ $temp);
+ if ($this->continuousBuffer) {
+ $buffer['ciphertext'] = substr($temp, $overflow);
+ $encryptIV = $temp;
+ }
+ } elseif (!strlen($buffer['ciphertext'])) {
+ $ciphertext.= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+ $temp = $this->_string_pop($ciphertext, $block_size);
+ if ($this->continuousBuffer) {
+ $encryptIV = $temp;
+ }
+ }
+ if ($this->continuousBuffer) {
+ if (!defined('OPENSSL_RAW_DATA')) {
+ $encryptIV.= @openssl_encrypt('', $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+ }
+ $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, $this->openssl_options);
+ if ($overflow) {
+ $this->_increment_str($encryptIV);
+ }
+ }
+
+ return $ciphertext;
+ }
+
+ /**
+ * OpenSSL OFB Processor
+ *
+ * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream
+ * for OFB is the same for both encrypting and decrypting this function is re-used by both Base::encrypt()
+ * and Base::decrypt().
+ *
+ * @see self::encrypt()
+ * @see self::decrypt()
+ * @param string $plaintext
+ * @param string $encryptIV
+ * @param array $buffer
+ * @return string
+ * @access private
+ */
+ function _openssl_ofb_process($plaintext, &$encryptIV, &$buffer)
+ {
+ if (strlen($buffer['xor'])) {
+ $ciphertext = $plaintext ^ $buffer['xor'];
+ $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext));
+ $plaintext = substr($plaintext, strlen($ciphertext));
+ } else {
+ $ciphertext = '';
+ }
+
+ $block_size = $this->block_size;
+
+ $len = strlen($plaintext);
+ $key = $this->key;
+ $overflow = $len % $block_size;
+
+ if (strlen($plaintext)) {
+ if ($overflow) {
+ $ciphertext.= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+ $xor = $this->_string_pop($ciphertext, $block_size);
+ if ($this->continuousBuffer) {
+ $encryptIV = $xor;
+ }
+ $ciphertext.= $this->_string_shift($xor, $overflow) ^ substr($plaintext, -$overflow);
+ if ($this->continuousBuffer) {
+ $buffer['xor'] = $xor;
+ }
+ } else {
+ $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, $this->openssl_options, $encryptIV);
+ if ($this->continuousBuffer) {
+ $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size);
+ }
+ }
+ }
+
+ return $ciphertext;
+ }
+
+ /**
+ * phpseclib <-> OpenSSL Mode Mapper
+ *
+ * May need to be overwritten by classes extending this one in some cases
+ *
+ * @return int
+ * @access private
+ */
+ function _openssl_translate_mode()
+ {
+ switch ($this->mode) {
+ case self::MODE_ECB:
+ return 'ecb';
+ case self::MODE_CBC:
+ return 'cbc';
+ case self::MODE_CTR:
+ return 'ctr';
+ case self::MODE_CFB:
+ return 'cfb';
+ case self::MODE_CFB8:
+ return 'cfb8';
+ case self::MODE_OFB:
+ return 'ofb';
+ }
+ }
+
+ /**
+ * Pad "packets".
+ *
+ * Block ciphers working by encrypting between their specified [$this->]block_size at a time
+ * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to
+ * pad the input so that it is of the proper length.
+ *
+ * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH,
+ * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
+ * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
+ * transmitted separately)
+ *
+ * @see self::disablePadding()
+ * @access public
+ */
+ function enablePadding()
+ {
+ $this->padding = true;
+ }
+
+ /**
+ * Do not pad packets.
+ *
+ * @see self::enablePadding()
+ * @access public
+ */
+ function disablePadding()
+ {
+ $this->padding = false;
+ }
+
+ /**
+ * Treat consecutive "packets" as if they are a continuous buffer.
+ *
+ * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets
+ * will yield different outputs:
+ *
+ * <code>
+ * echo $rijndael->encrypt(substr($plaintext, 0, 16));
+ * echo $rijndael->encrypt(substr($plaintext, 16, 16));
+ * </code>
+ * <code>
+ * echo $rijndael->encrypt($plaintext);
+ * </code>
+ *
+ * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
+ * another, as demonstrated with the following:
+ *
+ * <code>
+ * $rijndael->encrypt(substr($plaintext, 0, 16));
+ * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
+ * </code>
+ * <code>
+ * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16)));
+ * </code>
+ *
+ * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
+ * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
+ * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
+ *
+ * Put another way, when the continuous buffer is enabled, the state of the \phpseclib\Crypt\*() object changes after each
+ * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
+ * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
+ * however, they are also less intuitive and more likely to cause you problems.
+ *
+ * @see self::disableContinuousBuffer()
+ * @access public
+ * @internal Could, but not must, extend by the child Crypt_* class
+ */
+ function enableContinuousBuffer()
+ {
+ if ($this->mode == self::MODE_ECB) {
+ return;
+ }
+
+ $this->continuousBuffer = true;
+
+ $this->_setEngine();
+ }
+
+ /**
+ * Treat consecutive packets as if they are a discontinuous buffer.
+ *
+ * The default behavior.
+ *
+ * @see self::enableContinuousBuffer()
+ * @access public
+ * @internal Could, but not must, extend by the child Crypt_* class
+ */
+ function disableContinuousBuffer()
+ {
+ if ($this->mode == self::MODE_ECB) {
+ return;
+ }
+ if (!$this->continuousBuffer) {
+ return;
+ }
+
+ $this->continuousBuffer = false;
+ $this->changed = true;
+
+ $this->_setEngine();
+ }
+
+ /**
+ * Test for engine validity
+ *
+ * @see self::__construct()
+ * @param int $engine
+ * @access public
+ * @return bool
+ */
+ function isValidEngine($engine)
+ {
+ switch ($engine) {
+ case self::ENGINE_OPENSSL:
+ if ($this->mode == self::MODE_STREAM && $this->continuousBuffer) {
+ return false;
+ }
+ $this->openssl_emulate_ctr = false;
+ $result = $this->cipher_name_openssl &&
+ extension_loaded('openssl') &&
+ // PHP 5.3.0 - 5.3.2 did not let you set IV's
+ version_compare(PHP_VERSION, '5.3.3', '>=');
+ if (!$result) {
+ return false;
+ }
+
+ // prior to PHP 5.4.0 OPENSSL_RAW_DATA and OPENSSL_ZERO_PADDING were not defined. instead of expecting an integer
+ // $options openssl_encrypt expected a boolean $raw_data.
+ if (!defined('OPENSSL_RAW_DATA')) {
+ $this->openssl_options = true;
+ } else {
+ $this->openssl_options = OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING;
+ }
+
+ $methods = openssl_get_cipher_methods();
+ if (in_array($this->cipher_name_openssl, $methods)) {
+ return true;
+ }
+ // not all of openssl's symmetric cipher's support ctr. for those
+ // that don't we'll emulate it
+ switch ($this->mode) {
+ case self::MODE_CTR:
+ if (in_array($this->cipher_name_openssl_ecb, $methods)) {
+ $this->openssl_emulate_ctr = true;
+ return true;
+ }
+ }
+ return false;
+ case self::ENGINE_MCRYPT:
+ return $this->cipher_name_mcrypt &&
+ extension_loaded('mcrypt') &&
+ in_array($this->cipher_name_mcrypt, @mcrypt_list_algorithms());
+ case self::ENGINE_INTERNAL:
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Sets the preferred crypt engine
+ *
+ * Currently, $engine could be:
+ *
+ * - \phpseclib\Crypt\Base::ENGINE_OPENSSL [very fast]
+ *
+ * - \phpseclib\Crypt\Base::ENGINE_MCRYPT [fast]
+ *
+ * - \phpseclib\Crypt\Base::ENGINE_INTERNAL [slow]
+ *
+ * If the preferred crypt engine is not available the fastest available one will be used
+ *
+ * @see self::__construct()
+ * @param int $engine
+ * @access public
+ */
+ function setPreferredEngine($engine)
+ {
+ switch ($engine) {
+ //case self::ENGINE_OPENSSL;
+ case self::ENGINE_MCRYPT:
+ case self::ENGINE_INTERNAL:
+ $this->preferredEngine = $engine;
+ break;
+ default:
+ $this->preferredEngine = self::ENGINE_OPENSSL;
+ }
+
+ $this->_setEngine();
+ }
+
+ /**
+ * Returns the engine currently being utilized
+ *
+ * @see self::_setEngine()
+ * @access public
+ */
+ function getEngine()
+ {
+ return $this->engine;
+ }
+
+ /**
+ * Sets the engine as appropriate
+ *
+ * @see self::__construct()
+ * @access private
+ */
+ function _setEngine()
+ {
+ $this->engine = null;
+
+ $candidateEngines = array(
+ $this->preferredEngine,
+ self::ENGINE_OPENSSL,
+ self::ENGINE_MCRYPT
+ );
+ foreach ($candidateEngines as $engine) {
+ if ($this->isValidEngine($engine)) {
+ $this->engine = $engine;
+ break;
+ }
+ }
+ if (!$this->engine) {
+ $this->engine = self::ENGINE_INTERNAL;
+ }
+
+ if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) {
+ // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed,
+ // (re)open them with the module named in $this->cipher_name_mcrypt
+ @mcrypt_module_close($this->enmcrypt);
+ @mcrypt_module_close($this->demcrypt);
+ $this->enmcrypt = null;
+ $this->demcrypt = null;
+
+ if ($this->ecb) {
+ @mcrypt_module_close($this->ecb);
+ $this->ecb = null;
+ }
+ }
+
+ $this->changed = true;
+ }
+
+ /**
+ * Encrypts a block
+ *
+ * Note: Must be extended by the child \phpseclib\Crypt\* class
+ *
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ abstract function _encryptBlock($in);
+
+ /**
+ * Decrypts a block
+ *
+ * Note: Must be extended by the child \phpseclib\Crypt\* class
+ *
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ abstract function _decryptBlock($in);
+
+ /**
+ * Setup the key (expansion)
+ *
+ * Only used if $engine == self::ENGINE_INTERNAL
+ *
+ * Note: Must extend by the child \phpseclib\Crypt\* class
+ *
+ * @see self::_setup()
+ * @access private
+ */
+ abstract function _setupKey();
+
+ /**
+ * Setup the self::ENGINE_INTERNAL $engine
+ *
+ * (re)init, if necessary, the internal cipher $engine and flush all $buffers
+ * Used (only) if $engine == self::ENGINE_INTERNAL
+ *
+ * _setup() will be called each time if $changed === true
+ * typically this happens when using one or more of following public methods:
+ *
+ * - setKey()
+ *
+ * - setIV()
+ *
+ * - disableContinuousBuffer()
+ *
+ * - First run of encrypt() / decrypt() with no init-settings
+ *
+ * @see self::setKey()
+ * @see self::setIV()
+ * @see self::disableContinuousBuffer()
+ * @access private
+ * @internal _setup() is always called before en/decryption.
+ * @internal Could, but not must, extend by the child Crypt_* class
+ */
+ function _setup()
+ {
+ $this->_clearBuffers();
+ $this->_setupKey();
+
+ if ($this->use_inline_crypt) {
+ $this->_setupInlineCrypt();
+ }
+ }
+
+ /**
+ * Setup the self::ENGINE_MCRYPT $engine
+ *
+ * (re)init, if necessary, the (ext)mcrypt resources and flush all $buffers
+ * Used (only) if $engine = self::ENGINE_MCRYPT
+ *
+ * _setupMcrypt() will be called each time if $changed === true
+ * typically this happens when using one or more of following public methods:
+ *
+ * - setKey()
+ *
+ * - setIV()
+ *
+ * - disableContinuousBuffer()
+ *
+ * - First run of encrypt() / decrypt()
+ *
+ * @see self::setKey()
+ * @see self::setIV()
+ * @see self::disableContinuousBuffer()
+ * @access private
+ * @internal Could, but not must, extend by the child Crypt_* class
+ */
+ function _setupMcrypt()
+ {
+ $this->_clearBuffers();
+ $this->enchanged = $this->dechanged = true;
+
+ if (!isset($this->enmcrypt)) {
+ static $mcrypt_modes = array(
+ self::MODE_CTR => 'ctr',
+ self::MODE_ECB => MCRYPT_MODE_ECB,
+ self::MODE_CBC => MCRYPT_MODE_CBC,
+ self::MODE_CFB => 'ncfb',
+ self::MODE_CFB8 => MCRYPT_MODE_CFB,
+ self::MODE_OFB => MCRYPT_MODE_NOFB,
+ self::MODE_STREAM => MCRYPT_MODE_STREAM,
+ );
+
+ $this->demcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
+ $this->enmcrypt = @mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], '');
+
+ // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer()
+ // to workaround mcrypt's broken ncfb implementation in buffered mode
+ // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps}
+ if ($this->mode == self::MODE_CFB) {
+ $this->ecb = @mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, '');
+ }
+ } // else should mcrypt_generic_deinit be called?
+
+ if ($this->mode == self::MODE_CFB) {
+ @mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size));
+ }
+ }
+
+ /**
+ * Pads a string
+ *
+ * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize.
+ * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to
+ * chr($this->block_size - (strlen($text) % $this->block_size)
+ *
+ * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
+ * and padding will, hence forth, be enabled.
+ *
+ * @see self::_unpad()
+ * @param string $text
+ * @access private
+ * @return string
+ */
+ function _pad($text)
+ {
+ $length = strlen($text);
+
+ if (!$this->padding) {
+ if ($length % $this->block_size == 0) {
+ return $text;
+ } else {
+ user_error("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size})");
+ $this->padding = true;
+ }
+ }
+
+ $pad = $this->block_size - ($length % $this->block_size);
+
+ return str_pad($text, $length + $pad, chr($pad));
+ }
+
+ /**
+ * Unpads a string.
+ *
+ * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
+ * and false will be returned.
+ *
+ * @see self::_pad()
+ * @param string $text
+ * @access private
+ * @return string
+ */
+ function _unpad($text)
+ {
+ if (!$this->padding) {
+ return $text;
+ }
+
+ $length = ord($text[strlen($text) - 1]);
+
+ if (!$length || $length > $this->block_size) {
+ return false;
+ }
+
+ return substr($text, 0, -$length);
+ }
+
+ /**
+ * Clears internal buffers
+ *
+ * Clearing/resetting the internal buffers is done everytime
+ * after disableContinuousBuffer() or on cipher $engine (re)init
+ * ie after setKey() or setIV()
+ *
+ * @access public
+ * @internal Could, but not must, extend by the child Crypt_* class
+ */
+ function _clearBuffers()
+ {
+ $this->enbuffer = $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
+
+ // mcrypt's handling of invalid's $iv:
+ // $this->encryptIV = $this->decryptIV = strlen($this->iv) == $this->block_size ? $this->iv : str_repeat("\0", $this->block_size);
+ $this->encryptIV = $this->decryptIV = str_pad(substr($this->iv, 0, $this->block_size), $this->block_size, "\0");
+
+ if (!$this->skip_key_adjustment) {
+ $this->key = str_pad(substr($this->key, 0, $this->key_length), $this->key_length, "\0");
+ }
+ }
+
+ /**
+ * String Shift
+ *
+ * Inspired by array_shift
+ *
+ * @param string $string
+ * @param int $index
+ * @access private
+ * @return string
+ */
+ function _string_shift(&$string, $index = 1)
+ {
+ $substr = substr($string, 0, $index);
+ $string = substr($string, $index);
+ return $substr;
+ }
+
+ /**
+ * String Pop
+ *
+ * Inspired by array_pop
+ *
+ * @param string $string
+ * @param int $index
+ * @access private
+ * @return string
+ */
+ function _string_pop(&$string, $index = 1)
+ {
+ $substr = substr($string, -$index);
+ $string = substr($string, 0, -$index);
+ return $substr;
+ }
+
+ /**
+ * Increment the current string
+ *
+ * @see self::decrypt()
+ * @see self::encrypt()
+ * @param string $var
+ * @access private
+ */
+ function _increment_str(&$var)
+ {
+ for ($i = 4; $i <= strlen($var); $i+= 4) {
+ $temp = substr($var, -$i, 4);
+ switch ($temp) {
+ case "\xFF\xFF\xFF\xFF":
+ $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4);
+ break;
+ case "\x7F\xFF\xFF\xFF":
+ $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4);
+ return;
+ default:
+ $temp = unpack('Nnum', $temp);
+ $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4);
+ return;
+ }
+ }
+
+ $remainder = strlen($var) % 4;
+
+ if ($remainder == 0) {
+ return;
+ }
+
+ $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT));
+ $temp = substr(pack('N', $temp['num'] + 1), -$remainder);
+ $var = substr_replace($var, $temp, 0, $remainder);
+ }
+
+ /**
+ * Setup the performance-optimized function for de/encrypt()
+ *
+ * Stores the created (or existing) callback function-name
+ * in $this->inline_crypt
+ *
+ * Internally for phpseclib developers:
+ *
+ * _setupInlineCrypt() would be called only if:
+ *
+ * - $engine == self::ENGINE_INTERNAL and
+ *
+ * - $use_inline_crypt === true
+ *
+ * - each time on _setup(), after(!) _setupKey()
+ *
+ *
+ * This ensures that _setupInlineCrypt() has always a
+ * full ready2go initializated internal cipher $engine state
+ * where, for example, the keys allready expanded,
+ * keys/block_size calculated and such.
+ *
+ * It is, each time if called, the responsibility of _setupInlineCrypt():
+ *
+ * - to set $this->inline_crypt to a valid and fully working callback function
+ * as a (faster) replacement for encrypt() / decrypt()
+ *
+ * - NOT to create unlimited callback functions (for memory reasons!)
+ * no matter how often _setupInlineCrypt() would be called. At some
+ * point of amount they must be generic re-useable.
+ *
+ * - the code of _setupInlineCrypt() it self,
+ * and the generated callback code,
+ * must be, in following order:
+ * - 100% safe
+ * - 100% compatible to encrypt()/decrypt()
+ * - using only php5+ features/lang-constructs/php-extensions if
+ * compatibility (down to php4) or fallback is provided
+ * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-)
+ * - >= 10% faster than encrypt()/decrypt() [which is, by the way,
+ * the reason for the existence of _setupInlineCrypt() :-)]
+ * - memory-nice
+ * - short (as good as possible)
+ *
+ * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code.
+ * - In case of using inline crypting, _setupInlineCrypt() must extend by the child \phpseclib\Crypt\* class.
+ * - The following variable names are reserved:
+ * - $_* (all variable names prefixed with an underscore)
+ * - $self (object reference to it self. Do not use $this, but $self instead)
+ * - $in (the content of $in has to en/decrypt by the generated code)
+ * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only
+ *
+ *
+ * @see self::_setup()
+ * @see self::_createInlineCryptFunction()
+ * @see self::encrypt()
+ * @see self::decrypt()
+ * @access private
+ * @internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()
+ */
+ function _setupInlineCrypt()
+ {
+ // If, for any reason, an extending \phpseclib\Crypt\Base() \phpseclib\Crypt\* class
+ // not using inline crypting then it must be ensured that: $this->use_inline_crypt = false
+ // ie in the class var declaration of $use_inline_crypt in general for the \phpseclib\Crypt\* class,
+ // in the constructor at object instance-time
+ // or, if it's runtime-specific, at runtime
+
+ $this->use_inline_crypt = false;
+ }
+
+ /**
+ * Creates the performance-optimized function for en/decrypt()
+ *
+ * Internally for phpseclib developers:
+ *
+ * _createInlineCryptFunction():
+ *
+ * - merge the $cipher_code [setup'ed by _setupInlineCrypt()]
+ * with the current [$this->]mode of operation code
+ *
+ * - create the $inline function, which called by encrypt() / decrypt()
+ * as its replacement to speed up the en/decryption operations.
+ *
+ * - return the name of the created $inline callback function
+ *
+ * - used to speed up en/decryption
+ *
+ *
+ *
+ * The main reason why can speed up things [up to 50%] this way are:
+ *
+ * - using variables more effective then regular.
+ * (ie no use of expensive arrays but integers $k_0, $k_1 ...
+ * or even, for example, the pure $key[] values hardcoded)
+ *
+ * - avoiding 1000's of function calls of ie _encryptBlock()
+ * but inlining the crypt operations.
+ * in the mode of operation for() loop.
+ *
+ * - full loop unroll the (sometimes key-dependent) rounds
+ * avoiding this way ++$i counters and runtime-if's etc...
+ *
+ * The basic code architectur of the generated $inline en/decrypt()
+ * lambda function, in pseudo php, is:
+ *
+ * <code>
+ * +----------------------------------------------------------------------------------------------+
+ * | callback $inline = create_function: |
+ * | lambda_function_0001_crypt_ECB($action, $text) |
+ * | { |
+ * | INSERT PHP CODE OF: |
+ * | $cipher_code['init_crypt']; // general init code. |
+ * | // ie: $sbox'es declarations used for |
+ * | // encrypt and decrypt'ing. |
+ * | |
+ * | switch ($action) { |
+ * | case 'encrypt': |
+ * | INSERT PHP CODE OF: |
+ * | $cipher_code['init_encrypt']; // encrypt sepcific init code. |
+ * | ie: specified $key or $box |
+ * | declarations for encrypt'ing. |
+ * | |
+ * | foreach ($ciphertext) { |
+ * | $in = $block_size of $ciphertext; |
+ * | |
+ * | INSERT PHP CODE OF: |
+ * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: |
+ * | // strlen($in) == $this->block_size |
+ * | // here comes the cipher algorithm in action |
+ * | // for encryption. |
+ * | // $cipher_code['encrypt_block'] has to |
+ * | // encrypt the content of the $in variable |
+ * | |
+ * | $plaintext .= $in; |
+ * | } |
+ * | return $plaintext; |
+ * | |
+ * | case 'decrypt': |
+ * | INSERT PHP CODE OF: |
+ * | $cipher_code['init_decrypt']; // decrypt sepcific init code |
+ * | ie: specified $key or $box |
+ * | declarations for decrypt'ing. |
+ * | foreach ($plaintext) { |
+ * | $in = $block_size of $plaintext; |
+ * | |
+ * | INSERT PHP CODE OF: |
+ * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always |
+ * | // strlen($in) == $this->block_size |
+ * | // here comes the cipher algorithm in action |
+ * | // for decryption. |
+ * | // $cipher_code['decrypt_block'] has to |
+ * | // decrypt the content of the $in variable |
+ * | $ciphertext .= $in; |
+ * | } |
+ * | return $ciphertext; |
+ * | } |
+ * | } |
+ * +----------------------------------------------------------------------------------------------+
+ * </code>
+ *
+ * See also the \phpseclib\Crypt\*::_setupInlineCrypt()'s for
+ * productive inline $cipher_code's how they works.
+ *
+ * Structure of:
+ * <code>
+ * $cipher_code = array(
+ * 'init_crypt' => (string) '', // optional
+ * 'init_encrypt' => (string) '', // optional
+ * 'init_decrypt' => (string) '', // optional
+ * 'encrypt_block' => (string) '', // required
+ * 'decrypt_block' => (string) '' // required
+ * );
+ * </code>
+ *
+ * @see self::_setupInlineCrypt()
+ * @see self::encrypt()
+ * @see self::decrypt()
+ * @param array $cipher_code
+ * @access private
+ * @return string (the name of the created callback function)
+ */
+ function _createInlineCryptFunction($cipher_code)
+ {
+ $block_size = $this->block_size;
+
+ // optional
+ $init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : '';
+ $init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : '';
+ $init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : '';
+ // required
+ $encrypt_block = $cipher_code['encrypt_block'];
+ $decrypt_block = $cipher_code['decrypt_block'];
+
+ // Generating mode of operation inline code,
+ // merged with the $cipher_code algorithm
+ // for encrypt- and decryption.
+ switch ($this->mode) {
+ case self::MODE_ECB:
+ $encrypt = $init_encrypt . '
+ $_ciphertext = "";
+ $_plaintext_len = strlen($_text);
+
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+ $in = substr($_text, $_i, '.$block_size.');
+ '.$encrypt_block.'
+ $_ciphertext.= $in;
+ }
+
+ return $_ciphertext;
+ ';
+
+ $decrypt = $init_decrypt . '
+ $_plaintext = "";
+ $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
+ $_ciphertext_len = strlen($_text);
+
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+ $in = substr($_text, $_i, '.$block_size.');
+ '.$decrypt_block.'
+ $_plaintext.= $in;
+ }
+
+ return $self->_unpad($_plaintext);
+ ';
+ break;
+ case self::MODE_CTR:
+ $encrypt = $init_encrypt . '
+ $_ciphertext = "";
+ $_plaintext_len = strlen($_text);
+ $_xor = $self->encryptIV;
+ $_buffer = &$self->enbuffer;
+ if (strlen($_buffer["ciphertext"])) {
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+ $_block = substr($_text, $_i, '.$block_size.');
+ if (strlen($_block) > strlen($_buffer["ciphertext"])) {
+ $in = $_xor;
+ '.$encrypt_block.'
+ $self->_increment_str($_xor);
+ $_buffer["ciphertext"].= $in;
+ }
+ $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
+ $_ciphertext.= $_block ^ $_key;
+ }
+ } else {
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+ $_block = substr($_text, $_i, '.$block_size.');
+ $in = $_xor;
+ '.$encrypt_block.'
+ $self->_increment_str($_xor);
+ $_key = $in;
+ $_ciphertext.= $_block ^ $_key;
+ }
+ }
+ if ($self->continuousBuffer) {
+ $self->encryptIV = $_xor;
+ if ($_start = $_plaintext_len % '.$block_size.') {
+ $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
+ }
+ }
+
+ return $_ciphertext;
+ ';
+
+ $decrypt = $init_encrypt . '
+ $_plaintext = "";
+ $_ciphertext_len = strlen($_text);
+ $_xor = $self->decryptIV;
+ $_buffer = &$self->debuffer;
+
+ if (strlen($_buffer["ciphertext"])) {
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+ $_block = substr($_text, $_i, '.$block_size.');
+ if (strlen($_block) > strlen($_buffer["ciphertext"])) {
+ $in = $_xor;
+ '.$encrypt_block.'
+ $self->_increment_str($_xor);
+ $_buffer["ciphertext"].= $in;
+ }
+ $_key = $self->_string_shift($_buffer["ciphertext"], '.$block_size.');
+ $_plaintext.= $_block ^ $_key;
+ }
+ } else {
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+ $_block = substr($_text, $_i, '.$block_size.');
+ $in = $_xor;
+ '.$encrypt_block.'
+ $self->_increment_str($_xor);
+ $_key = $in;
+ $_plaintext.= $_block ^ $_key;
+ }
+ }
+ if ($self->continuousBuffer) {
+ $self->decryptIV = $_xor;
+ if ($_start = $_ciphertext_len % '.$block_size.') {
+ $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"];
+ }
+ }
+
+ return $_plaintext;
+ ';
+ break;
+ case self::MODE_CFB:
+ $encrypt = $init_encrypt . '
+ $_ciphertext = "";
+ $_buffer = &$self->enbuffer;
+
+ if ($self->continuousBuffer) {
+ $_iv = &$self->encryptIV;
+ $_pos = &$_buffer["pos"];
+ } else {
+ $_iv = $self->encryptIV;
+ $_pos = 0;
+ }
+ $_len = strlen($_text);
+ $_i = 0;
+ if ($_pos) {
+ $_orig_pos = $_pos;
+ $_max = '.$block_size.' - $_pos;
+ if ($_len >= $_max) {
+ $_i = $_max;
+ $_len-= $_max;
+ $_pos = 0;
+ } else {
+ $_i = $_len;
+ $_pos+= $_len;
+ $_len = 0;
+ }
+ $_ciphertext = substr($_iv, $_orig_pos) ^ $_text;
+ $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i);
+ }
+ while ($_len >= '.$block_size.') {
+ $in = $_iv;
+ '.$encrypt_block.';
+ $_iv = $in ^ substr($_text, $_i, '.$block_size.');
+ $_ciphertext.= $_iv;
+ $_len-= '.$block_size.';
+ $_i+= '.$block_size.';
+ }
+ if ($_len) {
+ $in = $_iv;
+ '.$encrypt_block.'
+ $_iv = $in;
+ $_block = $_iv ^ substr($_text, $_i);
+ $_iv = substr_replace($_iv, $_block, 0, $_len);
+ $_ciphertext.= $_block;
+ $_pos = $_len;
+ }
+ return $_ciphertext;
+ ';
+
+ $decrypt = $init_encrypt . '
+ $_plaintext = "";
+ $_buffer = &$self->debuffer;
+
+ if ($self->continuousBuffer) {
+ $_iv = &$self->decryptIV;
+ $_pos = &$_buffer["pos"];
+ } else {
+ $_iv = $self->decryptIV;
+ $_pos = 0;
+ }
+ $_len = strlen($_text);
+ $_i = 0;
+ if ($_pos) {
+ $_orig_pos = $_pos;
+ $_max = '.$block_size.' - $_pos;
+ if ($_len >= $_max) {
+ $_i = $_max;
+ $_len-= $_max;
+ $_pos = 0;
+ } else {
+ $_i = $_len;
+ $_pos+= $_len;
+ $_len = 0;
+ }
+ $_plaintext = substr($_iv, $_orig_pos) ^ $_text;
+ $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i);
+ }
+ while ($_len >= '.$block_size.') {
+ $in = $_iv;
+ '.$encrypt_block.'
+ $_iv = $in;
+ $cb = substr($_text, $_i, '.$block_size.');
+ $_plaintext.= $_iv ^ $cb;
+ $_iv = $cb;
+ $_len-= '.$block_size.';
+ $_i+= '.$block_size.';
+ }
+ if ($_len) {
+ $in = $_iv;
+ '.$encrypt_block.'
+ $_iv = $in;
+ $_plaintext.= $_iv ^ substr($_text, $_i);
+ $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len);
+ $_pos = $_len;
+ }
+
+ return $_plaintext;
+ ';
+ break;
+ case self::MODE_CFB8:
+ $encrypt = $init_encrypt . '
+ $_ciphertext = "";
+ $_len = strlen($_text);
+ $_iv = $self->encryptIV;
+
+ for ($_i = 0; $_i < $_len; ++$_i) {
+ $in = $_iv;
+ '.$encrypt_block.'
+ $_ciphertext .= ($_c = $_text[$_i] ^ $in);
+ $_iv = substr($_iv, 1) . $_c;
+ }
+
+ if ($self->continuousBuffer) {
+ if ($_len >= '.$block_size.') {
+ $self->encryptIV = substr($_ciphertext, -'.$block_size.');
+ } else {
+ $self->encryptIV = substr($self->encryptIV, $_len - '.$block_size.') . substr($_ciphertext, -$_len);
+ }
+ }
+
+ return $_ciphertext;
+ ';
+ $decrypt = $init_encrypt . '
+ $_plaintext = "";
+ $_len = strlen($_text);
+ $_iv = $self->decryptIV;
+
+ for ($_i = 0; $_i < $_len; ++$_i) {
+ $in = $_iv;
+ '.$encrypt_block.'
+ $_plaintext .= $_text[$_i] ^ $in;
+ $_iv = substr($_iv, 1) . $_text[$_i];
+ }
+
+ if ($self->continuousBuffer) {
+ if ($_len >= '.$block_size.') {
+ $self->decryptIV = substr($_text, -'.$block_size.');
+ } else {
+ $self->decryptIV = substr($self->decryptIV, $_len - '.$block_size.') . substr($_text, -$_len);
+ }
+ }
+
+ return $_plaintext;
+ ';
+ break;
+ case self::MODE_OFB:
+ $encrypt = $init_encrypt . '
+ $_ciphertext = "";
+ $_plaintext_len = strlen($_text);
+ $_xor = $self->encryptIV;
+ $_buffer = &$self->enbuffer;
+
+ if (strlen($_buffer["xor"])) {
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+ $_block = substr($_text, $_i, '.$block_size.');
+ if (strlen($_block) > strlen($_buffer["xor"])) {
+ $in = $_xor;
+ '.$encrypt_block.'
+ $_xor = $in;
+ $_buffer["xor"].= $_xor;
+ }
+ $_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
+ $_ciphertext.= $_block ^ $_key;
+ }
+ } else {
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+ $in = $_xor;
+ '.$encrypt_block.'
+ $_xor = $in;
+ $_ciphertext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
+ }
+ $_key = $_xor;
+ }
+ if ($self->continuousBuffer) {
+ $self->encryptIV = $_xor;
+ if ($_start = $_plaintext_len % '.$block_size.') {
+ $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
+ }
+ }
+ return $_ciphertext;
+ ';
+
+ $decrypt = $init_encrypt . '
+ $_plaintext = "";
+ $_ciphertext_len = strlen($_text);
+ $_xor = $self->decryptIV;
+ $_buffer = &$self->debuffer;
+
+ if (strlen($_buffer["xor"])) {
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+ $_block = substr($_text, $_i, '.$block_size.');
+ if (strlen($_block) > strlen($_buffer["xor"])) {
+ $in = $_xor;
+ '.$encrypt_block.'
+ $_xor = $in;
+ $_buffer["xor"].= $_xor;
+ }
+ $_key = $self->_string_shift($_buffer["xor"], '.$block_size.');
+ $_plaintext.= $_block ^ $_key;
+ }
+ } else {
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+ $in = $_xor;
+ '.$encrypt_block.'
+ $_xor = $in;
+ $_plaintext.= substr($_text, $_i, '.$block_size.') ^ $_xor;
+ }
+ $_key = $_xor;
+ }
+ if ($self->continuousBuffer) {
+ $self->decryptIV = $_xor;
+ if ($_start = $_ciphertext_len % '.$block_size.') {
+ $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"];
+ }
+ }
+ return $_plaintext;
+ ';
+ break;
+ case self::MODE_STREAM:
+ $encrypt = $init_encrypt . '
+ $_ciphertext = "";
+ '.$encrypt_block.'
+ return $_ciphertext;
+ ';
+ $decrypt = $init_decrypt . '
+ $_plaintext = "";
+ '.$decrypt_block.'
+ return $_plaintext;
+ ';
+ break;
+ // case self::MODE_CBC:
+ default:
+ $encrypt = $init_encrypt . '
+ $_ciphertext = "";
+ $_plaintext_len = strlen($_text);
+
+ $in = $self->encryptIV;
+
+ for ($_i = 0; $_i < $_plaintext_len; $_i+= '.$block_size.') {
+ $in = substr($_text, $_i, '.$block_size.') ^ $in;
+ '.$encrypt_block.'
+ $_ciphertext.= $in;
+ }
+
+ if ($self->continuousBuffer) {
+ $self->encryptIV = $in;
+ }
+
+ return $_ciphertext;
+ ';
+
+ $decrypt = $init_decrypt . '
+ $_plaintext = "";
+ $_text = str_pad($_text, strlen($_text) + ('.$block_size.' - strlen($_text) % '.$block_size.') % '.$block_size.', chr(0));
+ $_ciphertext_len = strlen($_text);
+
+ $_iv = $self->decryptIV;
+
+ for ($_i = 0; $_i < $_ciphertext_len; $_i+= '.$block_size.') {
+ $in = $_block = substr($_text, $_i, '.$block_size.');
+ '.$decrypt_block.'
+ $_plaintext.= $in ^ $_iv;
+ $_iv = $_block;
+ }
+
+ if ($self->continuousBuffer) {
+ $self->decryptIV = $_iv;
+ }
+
+ return $self->_unpad($_plaintext);
+ ';
+ break;
+ }
+
+ // Create the $inline function and return its name as string. Ready to run!
+ if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
+ eval('$func = function ($_action, &$self, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' } };');
+ return $func;
+ }
+
+ return create_function('$_action, &$self, $_text', $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }');
+ }
+
+ /**
+ * Holds the lambda_functions table (classwide)
+ *
+ * Each name of the lambda function, created from
+ * _setupInlineCrypt() && _createInlineCryptFunction()
+ * is stored, classwide (!), here for reusing.
+ *
+ * The string-based index of $function is a classwide
+ * unique value representing, at least, the $mode of
+ * operation (or more... depends of the optimizing level)
+ * for which $mode the lambda function was created.
+ *
+ * @access private
+ * @return array &$functions
+ */
+ function &_getLambdaFunctions()
+ {
+ static $functions = array();
+ return $functions;
+ }
+
+ /**
+ * Generates a digest from $bytes
+ *
+ * @see self::_setupInlineCrypt()
+ * @access private
+ * @param $bytes
+ * @return string
+ */
+ function _hashInlineCryptFunction($bytes)
+ {
+ if (!isset(self::$WHIRLPOOL_AVAILABLE)) {
+ self::$WHIRLPOOL_AVAILABLE = extension_loaded('hash') && in_array('whirlpool', hash_algos());
+ }
+
+ $result = '';
+ $hash = $bytes;
+
+ switch (true) {
+ case self::$WHIRLPOOL_AVAILABLE:
+ foreach (str_split($bytes, 64) as $t) {
+ $hash = hash('whirlpool', $hash, true);
+ $result .= $t ^ $hash;
+ }
+ return $result . hash('whirlpool', $hash, true);
+ default:
+ $len = strlen($bytes);
+ for ($i = 0; $i < $len; $i+=20) {
+ $t = substr($bytes, $i, 20);
+ $hash = pack('H*', sha1($hash));
+ $result .= $t ^ $hash;
+ }
+ return $result . pack('H*', sha1($hash));
+ }
+ }
+
+ /**
+ * Convert float to int
+ *
+ * On ARM CPUs converting floats to ints doesn't always work
+ *
+ * @access private
+ * @param string $x
+ * @return int
+ */
+ function safe_intval($x)
+ {
+ switch (true) {
+ case is_int($x):
+ // PHP 5.3, per http://php.net/releases/5_3_0.php, introduced "more consistent float rounding"
+ case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
+ return $x;
+ }
+ return (fmod($x, 0x80000000) & 0x7FFFFFFF) |
+ ((fmod(floor($x / 0x80000000), 2) & 1) << 31);
+ }
+
+ /**
+ * eval()'able string for in-line float to int
+ *
+ * @access private
+ * @return string
+ */
+ function safe_intval_inline()
+ {
+ switch (true) {
+ case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8:
+ case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM':
+ return '%s';
+ break;
+ default:
+ $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | ';
+ return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))';
+ }
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
new file mode 100644
index 0000000..74cc49d
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php
@@ -0,0 +1,571 @@
+<?php
+
+/**
+ * Pure-PHP implementation of Blowfish.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * Useful resources are as follows:
+ *
+ * - {@link http://en.wikipedia.org/wiki/Blowfish_(cipher) Wikipedia description of Blowfish}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $blowfish = new \phpseclib\Crypt\Blowfish();
+ *
+ * $blowfish->setKey('12345678901234567890123456789012');
+ *
+ * $plaintext = str_repeat('a', 1024);
+ *
+ * echo $blowfish->decrypt($blowfish->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package Blowfish
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
+ * @copyright 2007 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of Blowfish.
+ *
+ * @package Blowfish
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
+ * @access public
+ */
+class Blowfish extends Base
+{
+ /**
+ * Block Length of the cipher
+ *
+ * @see \phpseclib\Crypt\Base::block_size
+ * @var int
+ * @access private
+ */
+ var $block_size = 8;
+
+ /**
+ * The mcrypt specific name of the cipher
+ *
+ * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+ * @var string
+ * @access private
+ */
+ var $cipher_name_mcrypt = 'blowfish';
+
+ /**
+ * Optimizing value while CFB-encrypting
+ *
+ * @see \phpseclib\Crypt\Base::cfb_init_len
+ * @var int
+ * @access private
+ */
+ var $cfb_init_len = 500;
+
+ /**
+ * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each
+ *
+ * S-Box 0
+ *
+ * @access private
+ * @var array
+ */
+ var $sbox0 = array(
+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
+ );
+
+ /**
+ * S-Box 1
+ *
+ * @access private
+ * @var array
+ */
+ var $sbox1 = array(
+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
+ );
+
+ /**
+ * S-Box 2
+ *
+ * @access private
+ * @var array
+ */
+ var $sbox2 = array(
+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
+ );
+
+ /**
+ * S-Box 3
+ *
+ * @access private
+ * @var array
+ */
+ var $sbox3 = array(
+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
+ );
+
+ /**
+ * P-Array consists of 18 32-bit subkeys
+ *
+ * @var array
+ * @access private
+ */
+ var $parray = array(
+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
+ 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
+ );
+
+ /**
+ * The BCTX-working Array
+ *
+ * Holds the expanded key [p] and the key-depended s-boxes [sb]
+ *
+ * @var array
+ * @access private
+ */
+ var $bctx;
+
+ /**
+ * Holds the last used key
+ *
+ * @var array
+ * @access private
+ */
+ var $kl;
+
+ /**
+ * The Key Length (in bytes)
+ *
+ * @see \phpseclib\Crypt\Base::setKeyLength()
+ * @var int
+ * @access private
+ * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
+ * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could
+ * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
+ * of that, we'll just precompute it once.
+ */
+ var $key_length = 16;
+
+ /**
+ * Sets the key length.
+ *
+ * Key lengths can be between 32 and 448 bits.
+ *
+ * @access public
+ * @param int $length
+ */
+ function setKeyLength($length)
+ {
+ if ($length < 32) {
+ $this->key_length = 4;
+ } elseif ($length > 448) {
+ $this->key_length = 56;
+ } else {
+ $this->key_length = $length >> 3;
+ }
+
+ parent::setKeyLength($length);
+ }
+
+ /**
+ * Test for engine validity
+ *
+ * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+ *
+ * @see \phpseclib\Crypt\Base::isValidEngine()
+ * @param int $engine
+ * @access public
+ * @return bool
+ */
+ function isValidEngine($engine)
+ {
+ if ($engine == self::ENGINE_OPENSSL) {
+ if (version_compare(PHP_VERSION, '5.3.7') < 0 && $this->key_length != 16) {
+ return false;
+ }
+ if ($this->key_length < 16) {
+ return false;
+ }
+ $this->cipher_name_openssl_ecb = 'bf-ecb';
+ $this->cipher_name_openssl = 'bf-' . $this->_openssl_translate_mode();
+ }
+
+ return parent::isValidEngine($engine);
+ }
+
+ /**
+ * Setup the key (expansion)
+ *
+ * @see \phpseclib\Crypt\Base::_setupKey()
+ * @access private
+ */
+ function _setupKey()
+ {
+ if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
+ // already expanded
+ return;
+ }
+ $this->kl = array('key' => $this->key);
+
+ /* key-expanding p[] and S-Box building sb[] */
+ $this->bctx = array(
+ 'p' => array(),
+ 'sb' => array(
+ $this->sbox0,
+ $this->sbox1,
+ $this->sbox2,
+ $this->sbox3
+ )
+ );
+
+ // unpack binary string in unsigned chars
+ $key = array_values(unpack('C*', $this->key));
+ $keyl = count($key);
+ for ($j = 0, $i = 0; $i < 18; ++$i) {
+ // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ...
+ for ($data = 0, $k = 0; $k < 4; ++$k) {
+ $data = ($data << 8) | $key[$j];
+ if (++$j >= $keyl) {
+ $j = 0;
+ }
+ }
+ $this->bctx['p'][] = $this->parray[$i] ^ $data;
+ }
+
+ // encrypt the zero-string, replace P1 and P2 with the encrypted data,
+ // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys
+ $data = "\0\0\0\0\0\0\0\0";
+ for ($i = 0; $i < 18; $i += 2) {
+ list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
+ $this->bctx['p'][$i ] = $l;
+ $this->bctx['p'][$i + 1] = $r;
+ }
+ for ($i = 0; $i < 4; ++$i) {
+ for ($j = 0; $j < 256; $j += 2) {
+ list($l, $r) = array_values(unpack('N*', $data = $this->_encryptBlock($data)));
+ $this->bctx['sb'][$i][$j ] = $l;
+ $this->bctx['sb'][$i][$j + 1] = $r;
+ }
+ }
+ }
+
+ /**
+ * Encrypts a block
+ *
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ function _encryptBlock($in)
+ {
+ $p = $this->bctx["p"];
+ // extract($this->bctx["sb"], EXTR_PREFIX_ALL, "sb"); // slower
+ $sb_0 = $this->bctx["sb"][0];
+ $sb_1 = $this->bctx["sb"][1];
+ $sb_2 = $this->bctx["sb"][2];
+ $sb_3 = $this->bctx["sb"][3];
+
+ $in = unpack("N*", $in);
+ $l = $in[1];
+ $r = $in[2];
+
+ for ($i = 0; $i < 16; $i+= 2) {
+ $l^= $p[$i];
+ $r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
+ $sb_2[$l >> 8 & 0xff]) +
+ $sb_3[$l & 0xff]);
+
+ $r^= $p[$i + 1];
+ $l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
+ $sb_2[$r >> 8 & 0xff]) +
+ $sb_3[$r & 0xff]);
+ }
+ return pack("N*", $r ^ $p[17], $l ^ $p[16]);
+ }
+
+ /**
+ * Decrypts a block
+ *
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ function _decryptBlock($in)
+ {
+ $p = $this->bctx["p"];
+ $sb_0 = $this->bctx["sb"][0];
+ $sb_1 = $this->bctx["sb"][1];
+ $sb_2 = $this->bctx["sb"][2];
+ $sb_3 = $this->bctx["sb"][3];
+
+ $in = unpack("N*", $in);
+ $l = $in[1];
+ $r = $in[2];
+
+ for ($i = 17; $i > 2; $i-= 2) {
+ $l^= $p[$i];
+ $r^= $this->safe_intval(($this->safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^
+ $sb_2[$l >> 8 & 0xff]) +
+ $sb_3[$l & 0xff]);
+
+ $r^= $p[$i - 1];
+ $l^= $this->safe_intval(($this->safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^
+ $sb_2[$r >> 8 & 0xff]) +
+ $sb_3[$r & 0xff]);
+ }
+ return pack("N*", $r ^ $p[0], $l ^ $p[1]);
+ }
+
+ /**
+ * Setup the performance-optimized function for de/encrypt()
+ *
+ * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
+ * @access private
+ */
+ function _setupInlineCrypt()
+ {
+ $lambda_functions =& self::_getLambdaFunctions();
+
+ // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
+ // (Currently, for Blowfish, one generated $lambda_function cost on php5.5@32bit ~100kb unfreeable mem and ~180kb on php5.5@64bit)
+ // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
+ $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
+
+ // Generation of a unique hash for our generated code
+ $code_hash = "Crypt_Blowfish, {$this->mode}";
+ if ($gen_hi_opt_code) {
+ $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+ }
+
+ $safeint = $this->safe_intval_inline();
+
+ if (!isset($lambda_functions[$code_hash])) {
+ switch (true) {
+ case $gen_hi_opt_code:
+ $p = $this->bctx['p'];
+ $init_crypt = '
+ static $sb_0, $sb_1, $sb_2, $sb_3;
+ if (!$sb_0) {
+ $sb_0 = $self->bctx["sb"][0];
+ $sb_1 = $self->bctx["sb"][1];
+ $sb_2 = $self->bctx["sb"][2];
+ $sb_3 = $self->bctx["sb"][3];
+ }
+ ';
+ break;
+ default:
+ $p = array();
+ for ($i = 0; $i < 18; ++$i) {
+ $p[] = '$p_' . $i;
+ }
+ $init_crypt = '
+ list($sb_0, $sb_1, $sb_2, $sb_3) = $self->bctx["sb"];
+ list(' . implode(',', $p) . ') = $self->bctx["p"];
+
+ ';
+ }
+
+ // Generating encrypt code:
+ $encrypt_block = '
+ $in = unpack("N*", $in);
+ $l = $in[1];
+ $r = $in[2];
+ ';
+ for ($i = 0; $i < 16; $i+= 2) {
+ $encrypt_block.= '
+ $l^= ' . $p[$i] . ';
+ $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
+ $sb_2[$l >> 8 & 0xff]) +
+ $sb_3[$l & 0xff]') . ';
+
+ $r^= ' . $p[$i + 1] . ';
+ $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
+ $sb_2[$r >> 8 & 0xff]) +
+ $sb_3[$r & 0xff]') . ';
+ ';
+ }
+ $encrypt_block.= '
+ $in = pack("N*",
+ $r ^ ' . $p[17] . ',
+ $l ^ ' . $p[16] . '
+ );
+ ';
+
+ // Generating decrypt code:
+ $decrypt_block = '
+ $in = unpack("N*", $in);
+ $l = $in[1];
+ $r = $in[2];
+ ';
+
+ for ($i = 17; $i > 2; $i-= 2) {
+ $decrypt_block.= '
+ $l^= ' . $p[$i] . ';
+ $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^
+ $sb_2[$l >> 8 & 0xff]) +
+ $sb_3[$l & 0xff]') . ';
+
+ $r^= ' . $p[$i - 1] . ';
+ $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^
+ $sb_2[$r >> 8 & 0xff]) +
+ $sb_3[$r & 0xff]') . ';
+ ';
+ }
+
+ $decrypt_block.= '
+ $in = pack("N*",
+ $r ^ ' . $p[0] . ',
+ $l ^ ' . $p[1] . '
+ );
+ ';
+
+ $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
+ array(
+ 'init_crypt' => $init_crypt,
+ 'init_encrypt' => '',
+ 'init_decrypt' => '',
+ 'encrypt_block' => $encrypt_block,
+ 'decrypt_block' => $decrypt_block
+ )
+ );
+ }
+ $this->inline_crypt = $lambda_functions[$code_hash];
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
new file mode 100644
index 0000000..9a8225f
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php
@@ -0,0 +1,1443 @@
+<?php
+
+/**
+ * Pure-PHP implementation of DES.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * Useful resources are as follows:
+ *
+ * - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
+ * - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
+ * - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $des = new \phpseclib\Crypt\DES();
+ *
+ * $des->setKey('abcdefgh');
+ *
+ * $size = 10 * 1024;
+ * $plaintext = '';
+ * for ($i = 0; $i < $size; $i++) {
+ * $plaintext.= 'a';
+ * }
+ *
+ * echo $des->decrypt($des->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package DES
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of DES.
+ *
+ * @package DES
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class DES extends Base
+{
+ /**#@+
+ * @access private
+ * @see \phpseclib\Crypt\DES::_setupKey()
+ * @see \phpseclib\Crypt\DES::_processBlock()
+ */
+ /**
+ * Contains $keys[self::ENCRYPT]
+ */
+ const ENCRYPT = 0;
+ /**
+ * Contains $keys[self::DECRYPT]
+ */
+ const DECRYPT = 1;
+ /**#@-*/
+
+ /**
+ * Block Length of the cipher
+ *
+ * @see \phpseclib\Crypt\Base::block_size
+ * @var int
+ * @access private
+ */
+ var $block_size = 8;
+
+ /**
+ * Key Length (in bytes)
+ *
+ * @see \phpseclib\Crypt\Base::setKeyLength()
+ * @var int
+ * @access private
+ */
+ var $key_length = 8;
+
+ /**
+ * The mcrypt specific name of the cipher
+ *
+ * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+ * @var string
+ * @access private
+ */
+ var $cipher_name_mcrypt = 'des';
+
+ /**
+ * The OpenSSL names of the cipher / modes
+ *
+ * @see \phpseclib\Crypt\Base::openssl_mode_names
+ * @var array
+ * @access private
+ */
+ var $openssl_mode_names = array(
+ self::MODE_ECB => 'des-ecb',
+ self::MODE_CBC => 'des-cbc',
+ self::MODE_CFB => 'des-cfb',
+ self::MODE_OFB => 'des-ofb'
+ // self::MODE_CTR is undefined for DES
+ );
+
+ /**
+ * Optimizing value while CFB-encrypting
+ *
+ * @see \phpseclib\Crypt\Base::cfb_init_len
+ * @var int
+ * @access private
+ */
+ var $cfb_init_len = 500;
+
+ /**
+ * Switch for DES/3DES encryption
+ *
+ * Used only if $engine == self::ENGINE_INTERNAL
+ *
+ * @see self::_setupKey()
+ * @see self::_processBlock()
+ * @var int
+ * @access private
+ */
+ var $des_rounds = 1;
+
+ /**
+ * max possible size of $key
+ *
+ * @see self::setKey()
+ * @var string
+ * @access private
+ */
+ var $key_length_max = 8;
+
+ /**
+ * The Key Schedule
+ *
+ * @see self::_setupKey()
+ * @var array
+ * @access private
+ */
+ var $keys;
+
+ /**
+ * Shuffle table.
+ *
+ * For each byte value index, the entry holds an 8-byte string
+ * with each byte containing all bits in the same state as the
+ * corresponding bit in the index value.
+ *
+ * @see self::_processBlock()
+ * @see self::_setupKey()
+ * @var array
+ * @access private
+ */
+ var $shuffle = array(
+ "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF",
+ "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF",
+ "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF",
+ "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF",
+ "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF",
+ "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF",
+ "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF",
+ "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
+ "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF",
+ "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF",
+ "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF",
+ "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF",
+ "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF",
+ "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF",
+ "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF",
+ "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF",
+ "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF",
+ "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF",
+ "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF",
+ "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF",
+ "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF",
+ "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF",
+ "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF",
+ "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF",
+ "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF",
+ "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF",
+ "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF",
+ "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF",
+ "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF",
+ "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF",
+ "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF",
+ "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",
+ "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF",
+ "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF",
+ "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF",
+ "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF",
+ "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF",
+ "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF",
+ "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF",
+ "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF",
+ "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF",
+ "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF",
+ "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF",
+ "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF",
+ "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF",
+ "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF",
+ "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF",
+ "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF",
+ "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF",
+ "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF",
+ "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF",
+ "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF",
+ "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF",
+ "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF",
+ "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF",
+ "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF",
+ "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF",
+ "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF",
+ "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF",
+ "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF",
+ "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF",
+ "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF",
+ "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF",
+ "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
+ "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF",
+ "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF",
+ "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF",
+ "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF",
+ "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF",
+ "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF",
+ "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF",
+ "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF",
+ "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF",
+ "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF",
+ "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF",
+ "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF",
+ "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF",
+ "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF",
+ "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF",
+ "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF",
+ "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF",
+ "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF",
+ "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF",
+ "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF",
+ "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF",
+ "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF",
+ "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF",
+ "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF",
+ "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF",
+ "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF",
+ "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF",
+ "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF",
+ "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF",
+ "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF",
+ "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF",
+ "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF",
+ "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF",
+ "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF",
+ "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF",
+ "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF",
+ "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF",
+ "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF",
+ "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF",
+ "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF",
+ "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF",
+ "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF",
+ "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF",
+ "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF",
+ "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF",
+ "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF",
+ "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF",
+ "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF",
+ "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF",
+ "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF",
+ "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF",
+ "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF",
+ "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF",
+ "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF",
+ "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF",
+ "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF",
+ "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF",
+ "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF",
+ "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF",
+ "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF",
+ "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF",
+ "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF",
+ "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF",
+ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ );
+
+ /**
+ * IP mapping helper table.
+ *
+ * Indexing this table with each source byte performs the initial bit permutation.
+ *
+ * @var array
+ * @access private
+ */
+ var $ipmap = array(
+ 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31,
+ 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33,
+ 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71,
+ 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73,
+ 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35,
+ 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37,
+ 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75,
+ 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77,
+ 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1,
+ 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3,
+ 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1,
+ 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3,
+ 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5,
+ 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7,
+ 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5,
+ 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7,
+ 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39,
+ 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B,
+ 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79,
+ 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B,
+ 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D,
+ 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
+ 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D,
+ 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
+ 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9,
+ 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB,
+ 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9,
+ 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB,
+ 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD,
+ 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF,
+ 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD,
+ 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF
+ );
+
+ /**
+ * Inverse IP mapping helper table.
+ * Indexing this table with a byte value reverses the bit order.
+ *
+ * @var array
+ * @access private
+ */
+ var $invipmap = array(
+ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+ 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+ 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+ 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+ 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+ 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+ 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+ 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+ 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+ 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+ 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+ 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+ 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+ 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+ 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+ 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+ 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+ 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+ 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+ 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+ 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+ 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+ 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+ 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+ 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+ 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+ 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+ 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+ 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+ 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+ 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+ 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+ );
+
+ /**
+ * Pre-permuted S-box1
+ *
+ * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
+ * P table: concatenation can then be replaced by exclusive ORs.
+ *
+ * @var array
+ * @access private
+ */
+ var $sbox1 = array(
+ 0x00808200, 0x00000000, 0x00008000, 0x00808202,
+ 0x00808002, 0x00008202, 0x00000002, 0x00008000,
+ 0x00000200, 0x00808200, 0x00808202, 0x00000200,
+ 0x00800202, 0x00808002, 0x00800000, 0x00000002,
+ 0x00000202, 0x00800200, 0x00800200, 0x00008200,
+ 0x00008200, 0x00808000, 0x00808000, 0x00800202,
+ 0x00008002, 0x00800002, 0x00800002, 0x00008002,
+ 0x00000000, 0x00000202, 0x00008202, 0x00800000,
+ 0x00008000, 0x00808202, 0x00000002, 0x00808000,
+ 0x00808200, 0x00800000, 0x00800000, 0x00000200,
+ 0x00808002, 0x00008000, 0x00008200, 0x00800002,
+ 0x00000200, 0x00000002, 0x00800202, 0x00008202,
+ 0x00808202, 0x00008002, 0x00808000, 0x00800202,
+ 0x00800002, 0x00000202, 0x00008202, 0x00808200,
+ 0x00000202, 0x00800200, 0x00800200, 0x00000000,
+ 0x00008002, 0x00008200, 0x00000000, 0x00808002
+ );
+
+ /**
+ * Pre-permuted S-box2
+ *
+ * @var array
+ * @access private
+ */
+ var $sbox2 = array(
+ 0x40084010, 0x40004000, 0x00004000, 0x00084010,
+ 0x00080000, 0x00000010, 0x40080010, 0x40004010,
+ 0x40000010, 0x40084010, 0x40084000, 0x40000000,
+ 0x40004000, 0x00080000, 0x00000010, 0x40080010,
+ 0x00084000, 0x00080010, 0x40004010, 0x00000000,
+ 0x40000000, 0x00004000, 0x00084010, 0x40080000,
+ 0x00080010, 0x40000010, 0x00000000, 0x00084000,
+ 0x00004010, 0x40084000, 0x40080000, 0x00004010,
+ 0x00000000, 0x00084010, 0x40080010, 0x00080000,
+ 0x40004010, 0x40080000, 0x40084000, 0x00004000,
+ 0x40080000, 0x40004000, 0x00000010, 0x40084010,
+ 0x00084010, 0x00000010, 0x00004000, 0x40000000,
+ 0x00004010, 0x40084000, 0x00080000, 0x40000010,
+ 0x00080010, 0x40004010, 0x40000010, 0x00080010,
+ 0x00084000, 0x00000000, 0x40004000, 0x00004010,
+ 0x40000000, 0x40080010, 0x40084010, 0x00084000
+ );
+
+ /**
+ * Pre-permuted S-box3
+ *
+ * @var array
+ * @access private
+ */
+ var $sbox3 = array(
+ 0x00000104, 0x04010100, 0x00000000, 0x04010004,
+ 0x04000100, 0x00000000, 0x00010104, 0x04000100,
+ 0x00010004, 0x04000004, 0x04000004, 0x00010000,
+ 0x04010104, 0x00010004, 0x04010000, 0x00000104,
+ 0x04000000, 0x00000004, 0x04010100, 0x00000100,
+ 0x00010100, 0x04010000, 0x04010004, 0x00010104,
+ 0x04000104, 0x00010100, 0x00010000, 0x04000104,
+ 0x00000004, 0x04010104, 0x00000100, 0x04000000,
+ 0x04010100, 0x04000000, 0x00010004, 0x00000104,
+ 0x00010000, 0x04010100, 0x04000100, 0x00000000,
+ 0x00000100, 0x00010004, 0x04010104, 0x04000100,
+ 0x04000004, 0x00000100, 0x00000000, 0x04010004,
+ 0x04000104, 0x00010000, 0x04000000, 0x04010104,
+ 0x00000004, 0x00010104, 0x00010100, 0x04000004,
+ 0x04010000, 0x04000104, 0x00000104, 0x04010000,
+ 0x00010104, 0x00000004, 0x04010004, 0x00010100
+ );
+
+ /**
+ * Pre-permuted S-box4
+ *
+ * @var array
+ * @access private
+ */
+ var $sbox4 = array(
+ 0x80401000, 0x80001040, 0x80001040, 0x00000040,
+ 0x00401040, 0x80400040, 0x80400000, 0x80001000,
+ 0x00000000, 0x00401000, 0x00401000, 0x80401040,
+ 0x80000040, 0x00000000, 0x00400040, 0x80400000,
+ 0x80000000, 0x00001000, 0x00400000, 0x80401000,
+ 0x00000040, 0x00400000, 0x80001000, 0x00001040,
+ 0x80400040, 0x80000000, 0x00001040, 0x00400040,
+ 0x00001000, 0x00401040, 0x80401040, 0x80000040,
+ 0x00400040, 0x80400000, 0x00401000, 0x80401040,
+ 0x80000040, 0x00000000, 0x00000000, 0x00401000,
+ 0x00001040, 0x00400040, 0x80400040, 0x80000000,
+ 0x80401000, 0x80001040, 0x80001040, 0x00000040,
+ 0x80401040, 0x80000040, 0x80000000, 0x00001000,
+ 0x80400000, 0x80001000, 0x00401040, 0x80400040,
+ 0x80001000, 0x00001040, 0x00400000, 0x80401000,
+ 0x00000040, 0x00400000, 0x00001000, 0x00401040
+ );
+
+ /**
+ * Pre-permuted S-box5
+ *
+ * @var array
+ * @access private
+ */
+ var $sbox5 = array(
+ 0x00000080, 0x01040080, 0x01040000, 0x21000080,
+ 0x00040000, 0x00000080, 0x20000000, 0x01040000,
+ 0x20040080, 0x00040000, 0x01000080, 0x20040080,
+ 0x21000080, 0x21040000, 0x00040080, 0x20000000,
+ 0x01000000, 0x20040000, 0x20040000, 0x00000000,
+ 0x20000080, 0x21040080, 0x21040080, 0x01000080,
+ 0x21040000, 0x20000080, 0x00000000, 0x21000000,
+ 0x01040080, 0x01000000, 0x21000000, 0x00040080,
+ 0x00040000, 0x21000080, 0x00000080, 0x01000000,
+ 0x20000000, 0x01040000, 0x21000080, 0x20040080,
+ 0x01000080, 0x20000000, 0x21040000, 0x01040080,
+ 0x20040080, 0x00000080, 0x01000000, 0x21040000,
+ 0x21040080, 0x00040080, 0x21000000, 0x21040080,
+ 0x01040000, 0x00000000, 0x20040000, 0x21000000,
+ 0x00040080, 0x01000080, 0x20000080, 0x00040000,
+ 0x00000000, 0x20040000, 0x01040080, 0x20000080
+ );
+
+ /**
+ * Pre-permuted S-box6
+ *
+ * @var array
+ * @access private
+ */
+ var $sbox6 = array(
+ 0x10000008, 0x10200000, 0x00002000, 0x10202008,
+ 0x10200000, 0x00000008, 0x10202008, 0x00200000,
+ 0x10002000, 0x00202008, 0x00200000, 0x10000008,
+ 0x00200008, 0x10002000, 0x10000000, 0x00002008,
+ 0x00000000, 0x00200008, 0x10002008, 0x00002000,
+ 0x00202000, 0x10002008, 0x00000008, 0x10200008,
+ 0x10200008, 0x00000000, 0x00202008, 0x10202000,
+ 0x00002008, 0x00202000, 0x10202000, 0x10000000,
+ 0x10002000, 0x00000008, 0x10200008, 0x00202000,
+ 0x10202008, 0x00200000, 0x00002008, 0x10000008,
+ 0x00200000, 0x10002000, 0x10000000, 0x00002008,
+ 0x10000008, 0x10202008, 0x00202000, 0x10200000,
+ 0x00202008, 0x10202000, 0x00000000, 0x10200008,
+ 0x00000008, 0x00002000, 0x10200000, 0x00202008,
+ 0x00002000, 0x00200008, 0x10002008, 0x00000000,
+ 0x10202000, 0x10000000, 0x00200008, 0x10002008
+ );
+
+ /**
+ * Pre-permuted S-box7
+ *
+ * @var array
+ * @access private
+ */
+ var $sbox7 = array(
+ 0x00100000, 0x02100001, 0x02000401, 0x00000000,
+ 0x00000400, 0x02000401, 0x00100401, 0x02100400,
+ 0x02100401, 0x00100000, 0x00000000, 0x02000001,
+ 0x00000001, 0x02000000, 0x02100001, 0x00000401,
+ 0x02000400, 0x00100401, 0x00100001, 0x02000400,
+ 0x02000001, 0x02100000, 0x02100400, 0x00100001,
+ 0x02100000, 0x00000400, 0x00000401, 0x02100401,
+ 0x00100400, 0x00000001, 0x02000000, 0x00100400,
+ 0x02000000, 0x00100400, 0x00100000, 0x02000401,
+ 0x02000401, 0x02100001, 0x02100001, 0x00000001,
+ 0x00100001, 0x02000000, 0x02000400, 0x00100000,
+ 0x02100400, 0x00000401, 0x00100401, 0x02100400,
+ 0x00000401, 0x02000001, 0x02100401, 0x02100000,
+ 0x00100400, 0x00000000, 0x00000001, 0x02100401,
+ 0x00000000, 0x00100401, 0x02100000, 0x00000400,
+ 0x02000001, 0x02000400, 0x00000400, 0x00100001
+ );
+
+ /**
+ * Pre-permuted S-box8
+ *
+ * @var array
+ * @access private
+ */
+ var $sbox8 = array(
+ 0x08000820, 0x00000800, 0x00020000, 0x08020820,
+ 0x08000000, 0x08000820, 0x00000020, 0x08000000,
+ 0x00020020, 0x08020000, 0x08020820, 0x00020800,
+ 0x08020800, 0x00020820, 0x00000800, 0x00000020,
+ 0x08020000, 0x08000020, 0x08000800, 0x00000820,
+ 0x00020800, 0x00020020, 0x08020020, 0x08020800,
+ 0x00000820, 0x00000000, 0x00000000, 0x08020020,
+ 0x08000020, 0x08000800, 0x00020820, 0x00020000,
+ 0x00020820, 0x00020000, 0x08020800, 0x00000800,
+ 0x00000020, 0x08020020, 0x00000800, 0x00020820,
+ 0x08000800, 0x00000020, 0x08000020, 0x08020000,
+ 0x08020020, 0x08000000, 0x00020000, 0x08000820,
+ 0x00000000, 0x08020820, 0x00020020, 0x08000020,
+ 0x08020000, 0x08000800, 0x08000820, 0x00000000,
+ 0x08020820, 0x00020800, 0x00020800, 0x00000820,
+ 0x00000820, 0x00020020, 0x08000000, 0x08020800
+ );
+
+ /**
+ * Test for engine validity
+ *
+ * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+ *
+ * @see \phpseclib\Crypt\Base::isValidEngine()
+ * @param int $engine
+ * @access public
+ * @return bool
+ */
+ function isValidEngine($engine)
+ {
+ if ($this->key_length_max == 8) {
+ if ($engine == self::ENGINE_OPENSSL) {
+ $this->cipher_name_openssl_ecb = 'des-ecb';
+ $this->cipher_name_openssl = 'des-' . $this->_openssl_translate_mode();
+ }
+ }
+
+ return parent::isValidEngine($engine);
+ }
+
+ /**
+ * Sets the key.
+ *
+ * Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
+ * only use the first eight, if $key has more then eight characters in it, and pad $key with the
+ * null byte if it is less then eight characters long.
+ *
+ * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
+ *
+ * If the key is not explicitly set, it'll be assumed to be all zero's.
+ *
+ * @see \phpseclib\Crypt\Base::setKey()
+ * @access public
+ * @param string $key
+ */
+ function setKey($key)
+ {
+ // We check/cut here only up to max length of the key.
+ // Key padding to the proper length will be done in _setupKey()
+ if (strlen($key) > $this->key_length_max) {
+ $key = substr($key, 0, $this->key_length_max);
+ }
+
+ // Sets the key
+ parent::setKey($key);
+ }
+
+ /**
+ * Encrypts a block
+ *
+ * @see \phpseclib\Crypt\Base::_encryptBlock()
+ * @see \phpseclib\Crypt\Base::encrypt()
+ * @see self::encrypt()
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ function _encryptBlock($in)
+ {
+ return $this->_processBlock($in, self::ENCRYPT);
+ }
+
+ /**
+ * Decrypts a block
+ *
+ * @see \phpseclib\Crypt\Base::_decryptBlock()
+ * @see \phpseclib\Crypt\Base::decrypt()
+ * @see self::decrypt()
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ function _decryptBlock($in)
+ {
+ return $this->_processBlock($in, self::DECRYPT);
+ }
+
+ /**
+ * Encrypts or decrypts a 64-bit block
+ *
+ * $mode should be either self::ENCRYPT or self::DECRYPT. See
+ * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
+ * idea of what this function does.
+ *
+ * @see self::_encryptBlock()
+ * @see self::_decryptBlock()
+ * @access private
+ * @param string $block
+ * @param int $mode
+ * @return string
+ */
+ function _processBlock($block, $mode)
+ {
+ static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
+ if (!$sbox1) {
+ $sbox1 = array_map("intval", $this->sbox1);
+ $sbox2 = array_map("intval", $this->sbox2);
+ $sbox3 = array_map("intval", $this->sbox3);
+ $sbox4 = array_map("intval", $this->sbox4);
+ $sbox5 = array_map("intval", $this->sbox5);
+ $sbox6 = array_map("intval", $this->sbox6);
+ $sbox7 = array_map("intval", $this->sbox7);
+ $sbox8 = array_map("intval", $this->sbox8);
+ /* Merge $shuffle with $[inv]ipmap */
+ for ($i = 0; $i < 256; ++$i) {
+ $shuffleip[] = $this->shuffle[$this->ipmap[$i]];
+ $shuffleinvip[] = $this->shuffle[$this->invipmap[$i]];
+ }
+ }
+
+ $keys = $this->keys[$mode];
+ $ki = -1;
+
+ // Do the initial IP permutation.
+ $t = unpack('Nl/Nr', $block);
+ list($l, $r) = array($t['l'], $t['r']);
+ $block = ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
+ ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
+ ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
+ ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
+ ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
+ ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
+ ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
+ ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
+
+ // Extract L0 and R0.
+ $t = unpack('Nl/Nr', $block);
+ list($l, $r) = array($t['l'], $t['r']);
+
+ for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
+ // Perform the 16 steps.
+ for ($i = 0; $i < 16; $i++) {
+ // start of "the Feistel (F) function" - see the following URL:
+ // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
+ // Merge key schedule.
+ $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[++$ki];
+ $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[++$ki];
+
+ // S-box indexing.
+ $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
+ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
+ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
+ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $l;
+ // end of "the Feistel (F) function"
+
+ $l = $r;
+ $r = $t;
+ }
+
+ // Last step should not permute L & R.
+ $t = $l;
+ $l = $r;
+ $r = $t;
+ }
+
+ // Perform the inverse IP permutation.
+ return ($shuffleinvip[($r >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
+ ($shuffleinvip[($l >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
+ ($shuffleinvip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
+ ($shuffleinvip[($l >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
+ ($shuffleinvip[($r >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
+ ($shuffleinvip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
+ ($shuffleinvip[ $r & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
+ ($shuffleinvip[ $l & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
+ }
+
+ /**
+ * Creates the key schedule
+ *
+ * @see \phpseclib\Crypt\Base::_setupKey()
+ * @access private
+ */
+ function _setupKey()
+ {
+ if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) {
+ // already expanded
+ return;
+ }
+ $this->kl = array('key' => $this->key, 'des_rounds' => $this->des_rounds);
+
+ static $shifts = array( // number of key bits shifted per round
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+ );
+
+ static $pc1map = array(
+ 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C,
+ 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E,
+ 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C,
+ 0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E,
+ 0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C,
+ 0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E,
+ 0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C,
+ 0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E,
+ 0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C,
+ 0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E,
+ 0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C,
+ 0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E,
+ 0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C,
+ 0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E,
+ 0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C,
+ 0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E,
+ 0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C,
+ 0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E,
+ 0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C,
+ 0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E,
+ 0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC,
+ 0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE,
+ 0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC,
+ 0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE,
+ 0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC,
+ 0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE,
+ 0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC,
+ 0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE,
+ 0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC,
+ 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE,
+ 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC,
+ 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE
+ );
+
+ // Mapping tables for the PC-2 transformation.
+ static $pc2mapc1 = array(
+ 0x00000000, 0x00000400, 0x00200000, 0x00200400,
+ 0x00000001, 0x00000401, 0x00200001, 0x00200401,
+ 0x02000000, 0x02000400, 0x02200000, 0x02200400,
+ 0x02000001, 0x02000401, 0x02200001, 0x02200401
+ );
+ static $pc2mapc2 = array(
+ 0x00000000, 0x00000800, 0x08000000, 0x08000800,
+ 0x00010000, 0x00010800, 0x08010000, 0x08010800,
+ 0x00000000, 0x00000800, 0x08000000, 0x08000800,
+ 0x00010000, 0x00010800, 0x08010000, 0x08010800,
+ 0x00000100, 0x00000900, 0x08000100, 0x08000900,
+ 0x00010100, 0x00010900, 0x08010100, 0x08010900,
+ 0x00000100, 0x00000900, 0x08000100, 0x08000900,
+ 0x00010100, 0x00010900, 0x08010100, 0x08010900,
+ 0x00000010, 0x00000810, 0x08000010, 0x08000810,
+ 0x00010010, 0x00010810, 0x08010010, 0x08010810,
+ 0x00000010, 0x00000810, 0x08000010, 0x08000810,
+ 0x00010010, 0x00010810, 0x08010010, 0x08010810,
+ 0x00000110, 0x00000910, 0x08000110, 0x08000910,
+ 0x00010110, 0x00010910, 0x08010110, 0x08010910,
+ 0x00000110, 0x00000910, 0x08000110, 0x08000910,
+ 0x00010110, 0x00010910, 0x08010110, 0x08010910,
+ 0x00040000, 0x00040800, 0x08040000, 0x08040800,
+ 0x00050000, 0x00050800, 0x08050000, 0x08050800,
+ 0x00040000, 0x00040800, 0x08040000, 0x08040800,
+ 0x00050000, 0x00050800, 0x08050000, 0x08050800,
+ 0x00040100, 0x00040900, 0x08040100, 0x08040900,
+ 0x00050100, 0x00050900, 0x08050100, 0x08050900,
+ 0x00040100, 0x00040900, 0x08040100, 0x08040900,
+ 0x00050100, 0x00050900, 0x08050100, 0x08050900,
+ 0x00040010, 0x00040810, 0x08040010, 0x08040810,
+ 0x00050010, 0x00050810, 0x08050010, 0x08050810,
+ 0x00040010, 0x00040810, 0x08040010, 0x08040810,
+ 0x00050010, 0x00050810, 0x08050010, 0x08050810,
+ 0x00040110, 0x00040910, 0x08040110, 0x08040910,
+ 0x00050110, 0x00050910, 0x08050110, 0x08050910,
+ 0x00040110, 0x00040910, 0x08040110, 0x08040910,
+ 0x00050110, 0x00050910, 0x08050110, 0x08050910,
+ 0x01000000, 0x01000800, 0x09000000, 0x09000800,
+ 0x01010000, 0x01010800, 0x09010000, 0x09010800,
+ 0x01000000, 0x01000800, 0x09000000, 0x09000800,
+ 0x01010000, 0x01010800, 0x09010000, 0x09010800,
+ 0x01000100, 0x01000900, 0x09000100, 0x09000900,
+ 0x01010100, 0x01010900, 0x09010100, 0x09010900,
+ 0x01000100, 0x01000900, 0x09000100, 0x09000900,
+ 0x01010100, 0x01010900, 0x09010100, 0x09010900,
+ 0x01000010, 0x01000810, 0x09000010, 0x09000810,
+ 0x01010010, 0x01010810, 0x09010010, 0x09010810,
+ 0x01000010, 0x01000810, 0x09000010, 0x09000810,
+ 0x01010010, 0x01010810, 0x09010010, 0x09010810,
+ 0x01000110, 0x01000910, 0x09000110, 0x09000910,
+ 0x01010110, 0x01010910, 0x09010110, 0x09010910,
+ 0x01000110, 0x01000910, 0x09000110, 0x09000910,
+ 0x01010110, 0x01010910, 0x09010110, 0x09010910,
+ 0x01040000, 0x01040800, 0x09040000, 0x09040800,
+ 0x01050000, 0x01050800, 0x09050000, 0x09050800,
+ 0x01040000, 0x01040800, 0x09040000, 0x09040800,
+ 0x01050000, 0x01050800, 0x09050000, 0x09050800,
+ 0x01040100, 0x01040900, 0x09040100, 0x09040900,
+ 0x01050100, 0x01050900, 0x09050100, 0x09050900,
+ 0x01040100, 0x01040900, 0x09040100, 0x09040900,
+ 0x01050100, 0x01050900, 0x09050100, 0x09050900,
+ 0x01040010, 0x01040810, 0x09040010, 0x09040810,
+ 0x01050010, 0x01050810, 0x09050010, 0x09050810,
+ 0x01040010, 0x01040810, 0x09040010, 0x09040810,
+ 0x01050010, 0x01050810, 0x09050010, 0x09050810,
+ 0x01040110, 0x01040910, 0x09040110, 0x09040910,
+ 0x01050110, 0x01050910, 0x09050110, 0x09050910,
+ 0x01040110, 0x01040910, 0x09040110, 0x09040910,
+ 0x01050110, 0x01050910, 0x09050110, 0x09050910
+ );
+ static $pc2mapc3 = array(
+ 0x00000000, 0x00000004, 0x00001000, 0x00001004,
+ 0x00000000, 0x00000004, 0x00001000, 0x00001004,
+ 0x10000000, 0x10000004, 0x10001000, 0x10001004,
+ 0x10000000, 0x10000004, 0x10001000, 0x10001004,
+ 0x00000020, 0x00000024, 0x00001020, 0x00001024,
+ 0x00000020, 0x00000024, 0x00001020, 0x00001024,
+ 0x10000020, 0x10000024, 0x10001020, 0x10001024,
+ 0x10000020, 0x10000024, 0x10001020, 0x10001024,
+ 0x00080000, 0x00080004, 0x00081000, 0x00081004,
+ 0x00080000, 0x00080004, 0x00081000, 0x00081004,
+ 0x10080000, 0x10080004, 0x10081000, 0x10081004,
+ 0x10080000, 0x10080004, 0x10081000, 0x10081004,
+ 0x00080020, 0x00080024, 0x00081020, 0x00081024,
+ 0x00080020, 0x00080024, 0x00081020, 0x00081024,
+ 0x10080020, 0x10080024, 0x10081020, 0x10081024,
+ 0x10080020, 0x10080024, 0x10081020, 0x10081024,
+ 0x20000000, 0x20000004, 0x20001000, 0x20001004,
+ 0x20000000, 0x20000004, 0x20001000, 0x20001004,
+ 0x30000000, 0x30000004, 0x30001000, 0x30001004,
+ 0x30000000, 0x30000004, 0x30001000, 0x30001004,
+ 0x20000020, 0x20000024, 0x20001020, 0x20001024,
+ 0x20000020, 0x20000024, 0x20001020, 0x20001024,
+ 0x30000020, 0x30000024, 0x30001020, 0x30001024,
+ 0x30000020, 0x30000024, 0x30001020, 0x30001024,
+ 0x20080000, 0x20080004, 0x20081000, 0x20081004,
+ 0x20080000, 0x20080004, 0x20081000, 0x20081004,
+ 0x30080000, 0x30080004, 0x30081000, 0x30081004,
+ 0x30080000, 0x30080004, 0x30081000, 0x30081004,
+ 0x20080020, 0x20080024, 0x20081020, 0x20081024,
+ 0x20080020, 0x20080024, 0x20081020, 0x20081024,
+ 0x30080020, 0x30080024, 0x30081020, 0x30081024,
+ 0x30080020, 0x30080024, 0x30081020, 0x30081024,
+ 0x00000002, 0x00000006, 0x00001002, 0x00001006,
+ 0x00000002, 0x00000006, 0x00001002, 0x00001006,
+ 0x10000002, 0x10000006, 0x10001002, 0x10001006,
+ 0x10000002, 0x10000006, 0x10001002, 0x10001006,
+ 0x00000022, 0x00000026, 0x00001022, 0x00001026,
+ 0x00000022, 0x00000026, 0x00001022, 0x00001026,
+ 0x10000022, 0x10000026, 0x10001022, 0x10001026,
+ 0x10000022, 0x10000026, 0x10001022, 0x10001026,
+ 0x00080002, 0x00080006, 0x00081002, 0x00081006,
+ 0x00080002, 0x00080006, 0x00081002, 0x00081006,
+ 0x10080002, 0x10080006, 0x10081002, 0x10081006,
+ 0x10080002, 0x10080006, 0x10081002, 0x10081006,
+ 0x00080022, 0x00080026, 0x00081022, 0x00081026,
+ 0x00080022, 0x00080026, 0x00081022, 0x00081026,
+ 0x10080022, 0x10080026, 0x10081022, 0x10081026,
+ 0x10080022, 0x10080026, 0x10081022, 0x10081026,
+ 0x20000002, 0x20000006, 0x20001002, 0x20001006,
+ 0x20000002, 0x20000006, 0x20001002, 0x20001006,
+ 0x30000002, 0x30000006, 0x30001002, 0x30001006,
+ 0x30000002, 0x30000006, 0x30001002, 0x30001006,
+ 0x20000022, 0x20000026, 0x20001022, 0x20001026,
+ 0x20000022, 0x20000026, 0x20001022, 0x20001026,
+ 0x30000022, 0x30000026, 0x30001022, 0x30001026,
+ 0x30000022, 0x30000026, 0x30001022, 0x30001026,
+ 0x20080002, 0x20080006, 0x20081002, 0x20081006,
+ 0x20080002, 0x20080006, 0x20081002, 0x20081006,
+ 0x30080002, 0x30080006, 0x30081002, 0x30081006,
+ 0x30080002, 0x30080006, 0x30081002, 0x30081006,
+ 0x20080022, 0x20080026, 0x20081022, 0x20081026,
+ 0x20080022, 0x20080026, 0x20081022, 0x20081026,
+ 0x30080022, 0x30080026, 0x30081022, 0x30081026,
+ 0x30080022, 0x30080026, 0x30081022, 0x30081026
+ );
+ static $pc2mapc4 = array(
+ 0x00000000, 0x00100000, 0x00000008, 0x00100008,
+ 0x00000200, 0x00100200, 0x00000208, 0x00100208,
+ 0x00000000, 0x00100000, 0x00000008, 0x00100008,
+ 0x00000200, 0x00100200, 0x00000208, 0x00100208,
+ 0x04000000, 0x04100000, 0x04000008, 0x04100008,
+ 0x04000200, 0x04100200, 0x04000208, 0x04100208,
+ 0x04000000, 0x04100000, 0x04000008, 0x04100008,
+ 0x04000200, 0x04100200, 0x04000208, 0x04100208,
+ 0x00002000, 0x00102000, 0x00002008, 0x00102008,
+ 0x00002200, 0x00102200, 0x00002208, 0x00102208,
+ 0x00002000, 0x00102000, 0x00002008, 0x00102008,
+ 0x00002200, 0x00102200, 0x00002208, 0x00102208,
+ 0x04002000, 0x04102000, 0x04002008, 0x04102008,
+ 0x04002200, 0x04102200, 0x04002208, 0x04102208,
+ 0x04002000, 0x04102000, 0x04002008, 0x04102008,
+ 0x04002200, 0x04102200, 0x04002208, 0x04102208,
+ 0x00000000, 0x00100000, 0x00000008, 0x00100008,
+ 0x00000200, 0x00100200, 0x00000208, 0x00100208,
+ 0x00000000, 0x00100000, 0x00000008, 0x00100008,
+ 0x00000200, 0x00100200, 0x00000208, 0x00100208,
+ 0x04000000, 0x04100000, 0x04000008, 0x04100008,
+ 0x04000200, 0x04100200, 0x04000208, 0x04100208,
+ 0x04000000, 0x04100000, 0x04000008, 0x04100008,
+ 0x04000200, 0x04100200, 0x04000208, 0x04100208,
+ 0x00002000, 0x00102000, 0x00002008, 0x00102008,
+ 0x00002200, 0x00102200, 0x00002208, 0x00102208,
+ 0x00002000, 0x00102000, 0x00002008, 0x00102008,
+ 0x00002200, 0x00102200, 0x00002208, 0x00102208,
+ 0x04002000, 0x04102000, 0x04002008, 0x04102008,
+ 0x04002200, 0x04102200, 0x04002208, 0x04102208,
+ 0x04002000, 0x04102000, 0x04002008, 0x04102008,
+ 0x04002200, 0x04102200, 0x04002208, 0x04102208,
+ 0x00020000, 0x00120000, 0x00020008, 0x00120008,
+ 0x00020200, 0x00120200, 0x00020208, 0x00120208,
+ 0x00020000, 0x00120000, 0x00020008, 0x00120008,
+ 0x00020200, 0x00120200, 0x00020208, 0x00120208,
+ 0x04020000, 0x04120000, 0x04020008, 0x04120008,
+ 0x04020200, 0x04120200, 0x04020208, 0x04120208,
+ 0x04020000, 0x04120000, 0x04020008, 0x04120008,
+ 0x04020200, 0x04120200, 0x04020208, 0x04120208,
+ 0x00022000, 0x00122000, 0x00022008, 0x00122008,
+ 0x00022200, 0x00122200, 0x00022208, 0x00122208,
+ 0x00022000, 0x00122000, 0x00022008, 0x00122008,
+ 0x00022200, 0x00122200, 0x00022208, 0x00122208,
+ 0x04022000, 0x04122000, 0x04022008, 0x04122008,
+ 0x04022200, 0x04122200, 0x04022208, 0x04122208,
+ 0x04022000, 0x04122000, 0x04022008, 0x04122008,
+ 0x04022200, 0x04122200, 0x04022208, 0x04122208,
+ 0x00020000, 0x00120000, 0x00020008, 0x00120008,
+ 0x00020200, 0x00120200, 0x00020208, 0x00120208,
+ 0x00020000, 0x00120000, 0x00020008, 0x00120008,
+ 0x00020200, 0x00120200, 0x00020208, 0x00120208,
+ 0x04020000, 0x04120000, 0x04020008, 0x04120008,
+ 0x04020200, 0x04120200, 0x04020208, 0x04120208,
+ 0x04020000, 0x04120000, 0x04020008, 0x04120008,
+ 0x04020200, 0x04120200, 0x04020208, 0x04120208,
+ 0x00022000, 0x00122000, 0x00022008, 0x00122008,
+ 0x00022200, 0x00122200, 0x00022208, 0x00122208,
+ 0x00022000, 0x00122000, 0x00022008, 0x00122008,
+ 0x00022200, 0x00122200, 0x00022208, 0x00122208,
+ 0x04022000, 0x04122000, 0x04022008, 0x04122008,
+ 0x04022200, 0x04122200, 0x04022208, 0x04122208,
+ 0x04022000, 0x04122000, 0x04022008, 0x04122008,
+ 0x04022200, 0x04122200, 0x04022208, 0x04122208
+ );
+ static $pc2mapd1 = array(
+ 0x00000000, 0x00000001, 0x08000000, 0x08000001,
+ 0x00200000, 0x00200001, 0x08200000, 0x08200001,
+ 0x00000002, 0x00000003, 0x08000002, 0x08000003,
+ 0x00200002, 0x00200003, 0x08200002, 0x08200003
+ );
+ static $pc2mapd2 = array(
+ 0x00000000, 0x00100000, 0x00000800, 0x00100800,
+ 0x00000000, 0x00100000, 0x00000800, 0x00100800,
+ 0x04000000, 0x04100000, 0x04000800, 0x04100800,
+ 0x04000000, 0x04100000, 0x04000800, 0x04100800,
+ 0x00000004, 0x00100004, 0x00000804, 0x00100804,
+ 0x00000004, 0x00100004, 0x00000804, 0x00100804,
+ 0x04000004, 0x04100004, 0x04000804, 0x04100804,
+ 0x04000004, 0x04100004, 0x04000804, 0x04100804,
+ 0x00000000, 0x00100000, 0x00000800, 0x00100800,
+ 0x00000000, 0x00100000, 0x00000800, 0x00100800,
+ 0x04000000, 0x04100000, 0x04000800, 0x04100800,
+ 0x04000000, 0x04100000, 0x04000800, 0x04100800,
+ 0x00000004, 0x00100004, 0x00000804, 0x00100804,
+ 0x00000004, 0x00100004, 0x00000804, 0x00100804,
+ 0x04000004, 0x04100004, 0x04000804, 0x04100804,
+ 0x04000004, 0x04100004, 0x04000804, 0x04100804,
+ 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
+ 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
+ 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
+ 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
+ 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
+ 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
+ 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
+ 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
+ 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
+ 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
+ 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
+ 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
+ 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
+ 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
+ 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
+ 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
+ 0x00020000, 0x00120000, 0x00020800, 0x00120800,
+ 0x00020000, 0x00120000, 0x00020800, 0x00120800,
+ 0x04020000, 0x04120000, 0x04020800, 0x04120800,
+ 0x04020000, 0x04120000, 0x04020800, 0x04120800,
+ 0x00020004, 0x00120004, 0x00020804, 0x00120804,
+ 0x00020004, 0x00120004, 0x00020804, 0x00120804,
+ 0x04020004, 0x04120004, 0x04020804, 0x04120804,
+ 0x04020004, 0x04120004, 0x04020804, 0x04120804,
+ 0x00020000, 0x00120000, 0x00020800, 0x00120800,
+ 0x00020000, 0x00120000, 0x00020800, 0x00120800,
+ 0x04020000, 0x04120000, 0x04020800, 0x04120800,
+ 0x04020000, 0x04120000, 0x04020800, 0x04120800,
+ 0x00020004, 0x00120004, 0x00020804, 0x00120804,
+ 0x00020004, 0x00120004, 0x00020804, 0x00120804,
+ 0x04020004, 0x04120004, 0x04020804, 0x04120804,
+ 0x04020004, 0x04120004, 0x04020804, 0x04120804,
+ 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
+ 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
+ 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
+ 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
+ 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
+ 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
+ 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
+ 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
+ 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
+ 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
+ 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
+ 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
+ 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
+ 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
+ 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
+ 0x04020204, 0x04120204, 0x04020A04, 0x04120A04
+ );
+ static $pc2mapd3 = array(
+ 0x00000000, 0x00010000, 0x02000000, 0x02010000,
+ 0x00000020, 0x00010020, 0x02000020, 0x02010020,
+ 0x00040000, 0x00050000, 0x02040000, 0x02050000,
+ 0x00040020, 0x00050020, 0x02040020, 0x02050020,
+ 0x00002000, 0x00012000, 0x02002000, 0x02012000,
+ 0x00002020, 0x00012020, 0x02002020, 0x02012020,
+ 0x00042000, 0x00052000, 0x02042000, 0x02052000,
+ 0x00042020, 0x00052020, 0x02042020, 0x02052020,
+ 0x00000000, 0x00010000, 0x02000000, 0x02010000,
+ 0x00000020, 0x00010020, 0x02000020, 0x02010020,
+ 0x00040000, 0x00050000, 0x02040000, 0x02050000,
+ 0x00040020, 0x00050020, 0x02040020, 0x02050020,
+ 0x00002000, 0x00012000, 0x02002000, 0x02012000,
+ 0x00002020, 0x00012020, 0x02002020, 0x02012020,
+ 0x00042000, 0x00052000, 0x02042000, 0x02052000,
+ 0x00042020, 0x00052020, 0x02042020, 0x02052020,
+ 0x00000010, 0x00010010, 0x02000010, 0x02010010,
+ 0x00000030, 0x00010030, 0x02000030, 0x02010030,
+ 0x00040010, 0x00050010, 0x02040010, 0x02050010,
+ 0x00040030, 0x00050030, 0x02040030, 0x02050030,
+ 0x00002010, 0x00012010, 0x02002010, 0x02012010,
+ 0x00002030, 0x00012030, 0x02002030, 0x02012030,
+ 0x00042010, 0x00052010, 0x02042010, 0x02052010,
+ 0x00042030, 0x00052030, 0x02042030, 0x02052030,
+ 0x00000010, 0x00010010, 0x02000010, 0x02010010,
+ 0x00000030, 0x00010030, 0x02000030, 0x02010030,
+ 0x00040010, 0x00050010, 0x02040010, 0x02050010,
+ 0x00040030, 0x00050030, 0x02040030, 0x02050030,
+ 0x00002010, 0x00012010, 0x02002010, 0x02012010,
+ 0x00002030, 0x00012030, 0x02002030, 0x02012030,
+ 0x00042010, 0x00052010, 0x02042010, 0x02052010,
+ 0x00042030, 0x00052030, 0x02042030, 0x02052030,
+ 0x20000000, 0x20010000, 0x22000000, 0x22010000,
+ 0x20000020, 0x20010020, 0x22000020, 0x22010020,
+ 0x20040000, 0x20050000, 0x22040000, 0x22050000,
+ 0x20040020, 0x20050020, 0x22040020, 0x22050020,
+ 0x20002000, 0x20012000, 0x22002000, 0x22012000,
+ 0x20002020, 0x20012020, 0x22002020, 0x22012020,
+ 0x20042000, 0x20052000, 0x22042000, 0x22052000,
+ 0x20042020, 0x20052020, 0x22042020, 0x22052020,
+ 0x20000000, 0x20010000, 0x22000000, 0x22010000,
+ 0x20000020, 0x20010020, 0x22000020, 0x22010020,
+ 0x20040000, 0x20050000, 0x22040000, 0x22050000,
+ 0x20040020, 0x20050020, 0x22040020, 0x22050020,
+ 0x20002000, 0x20012000, 0x22002000, 0x22012000,
+ 0x20002020, 0x20012020, 0x22002020, 0x22012020,
+ 0x20042000, 0x20052000, 0x22042000, 0x22052000,
+ 0x20042020, 0x20052020, 0x22042020, 0x22052020,
+ 0x20000010, 0x20010010, 0x22000010, 0x22010010,
+ 0x20000030, 0x20010030, 0x22000030, 0x22010030,
+ 0x20040010, 0x20050010, 0x22040010, 0x22050010,
+ 0x20040030, 0x20050030, 0x22040030, 0x22050030,
+ 0x20002010, 0x20012010, 0x22002010, 0x22012010,
+ 0x20002030, 0x20012030, 0x22002030, 0x22012030,
+ 0x20042010, 0x20052010, 0x22042010, 0x22052010,
+ 0x20042030, 0x20052030, 0x22042030, 0x22052030,
+ 0x20000010, 0x20010010, 0x22000010, 0x22010010,
+ 0x20000030, 0x20010030, 0x22000030, 0x22010030,
+ 0x20040010, 0x20050010, 0x22040010, 0x22050010,
+ 0x20040030, 0x20050030, 0x22040030, 0x22050030,
+ 0x20002010, 0x20012010, 0x22002010, 0x22012010,
+ 0x20002030, 0x20012030, 0x22002030, 0x22012030,
+ 0x20042010, 0x20052010, 0x22042010, 0x22052010,
+ 0x20042030, 0x20052030, 0x22042030, 0x22052030
+ );
+ static $pc2mapd4 = array(
+ 0x00000000, 0x00000400, 0x01000000, 0x01000400,
+ 0x00000000, 0x00000400, 0x01000000, 0x01000400,
+ 0x00000100, 0x00000500, 0x01000100, 0x01000500,
+ 0x00000100, 0x00000500, 0x01000100, 0x01000500,
+ 0x10000000, 0x10000400, 0x11000000, 0x11000400,
+ 0x10000000, 0x10000400, 0x11000000, 0x11000400,
+ 0x10000100, 0x10000500, 0x11000100, 0x11000500,
+ 0x10000100, 0x10000500, 0x11000100, 0x11000500,
+ 0x00080000, 0x00080400, 0x01080000, 0x01080400,
+ 0x00080000, 0x00080400, 0x01080000, 0x01080400,
+ 0x00080100, 0x00080500, 0x01080100, 0x01080500,
+ 0x00080100, 0x00080500, 0x01080100, 0x01080500,
+ 0x10080000, 0x10080400, 0x11080000, 0x11080400,
+ 0x10080000, 0x10080400, 0x11080000, 0x11080400,
+ 0x10080100, 0x10080500, 0x11080100, 0x11080500,
+ 0x10080100, 0x10080500, 0x11080100, 0x11080500,
+ 0x00000008, 0x00000408, 0x01000008, 0x01000408,
+ 0x00000008, 0x00000408, 0x01000008, 0x01000408,
+ 0x00000108, 0x00000508, 0x01000108, 0x01000508,
+ 0x00000108, 0x00000508, 0x01000108, 0x01000508,
+ 0x10000008, 0x10000408, 0x11000008, 0x11000408,
+ 0x10000008, 0x10000408, 0x11000008, 0x11000408,
+ 0x10000108, 0x10000508, 0x11000108, 0x11000508,
+ 0x10000108, 0x10000508, 0x11000108, 0x11000508,
+ 0x00080008, 0x00080408, 0x01080008, 0x01080408,
+ 0x00080008, 0x00080408, 0x01080008, 0x01080408,
+ 0x00080108, 0x00080508, 0x01080108, 0x01080508,
+ 0x00080108, 0x00080508, 0x01080108, 0x01080508,
+ 0x10080008, 0x10080408, 0x11080008, 0x11080408,
+ 0x10080008, 0x10080408, 0x11080008, 0x11080408,
+ 0x10080108, 0x10080508, 0x11080108, 0x11080508,
+ 0x10080108, 0x10080508, 0x11080108, 0x11080508,
+ 0x00001000, 0x00001400, 0x01001000, 0x01001400,
+ 0x00001000, 0x00001400, 0x01001000, 0x01001400,
+ 0x00001100, 0x00001500, 0x01001100, 0x01001500,
+ 0x00001100, 0x00001500, 0x01001100, 0x01001500,
+ 0x10001000, 0x10001400, 0x11001000, 0x11001400,
+ 0x10001000, 0x10001400, 0x11001000, 0x11001400,
+ 0x10001100, 0x10001500, 0x11001100, 0x11001500,
+ 0x10001100, 0x10001500, 0x11001100, 0x11001500,
+ 0x00081000, 0x00081400, 0x01081000, 0x01081400,
+ 0x00081000, 0x00081400, 0x01081000, 0x01081400,
+ 0x00081100, 0x00081500, 0x01081100, 0x01081500,
+ 0x00081100, 0x00081500, 0x01081100, 0x01081500,
+ 0x10081000, 0x10081400, 0x11081000, 0x11081400,
+ 0x10081000, 0x10081400, 0x11081000, 0x11081400,
+ 0x10081100, 0x10081500, 0x11081100, 0x11081500,
+ 0x10081100, 0x10081500, 0x11081100, 0x11081500,
+ 0x00001008, 0x00001408, 0x01001008, 0x01001408,
+ 0x00001008, 0x00001408, 0x01001008, 0x01001408,
+ 0x00001108, 0x00001508, 0x01001108, 0x01001508,
+ 0x00001108, 0x00001508, 0x01001108, 0x01001508,
+ 0x10001008, 0x10001408, 0x11001008, 0x11001408,
+ 0x10001008, 0x10001408, 0x11001008, 0x11001408,
+ 0x10001108, 0x10001508, 0x11001108, 0x11001508,
+ 0x10001108, 0x10001508, 0x11001108, 0x11001508,
+ 0x00081008, 0x00081408, 0x01081008, 0x01081408,
+ 0x00081008, 0x00081408, 0x01081008, 0x01081408,
+ 0x00081108, 0x00081508, 0x01081108, 0x01081508,
+ 0x00081108, 0x00081508, 0x01081108, 0x01081508,
+ 0x10081008, 0x10081408, 0x11081008, 0x11081408,
+ 0x10081008, 0x10081408, 0x11081008, 0x11081408,
+ 0x10081108, 0x10081508, 0x11081108, 0x11081508,
+ 0x10081108, 0x10081508, 0x11081108, 0x11081508
+ );
+
+ $keys = array();
+ for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) {
+ // pad the key and remove extra characters as appropriate.
+ $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0");
+
+ // Perform the PC/1 transformation and compute C and D.
+ $t = unpack('Nl/Nr', $key);
+ list($l, $r) = array($t['l'], $t['r']);
+ $key = ($this->shuffle[$pc1map[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") |
+ ($this->shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") |
+ ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") |
+ ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") |
+ ($this->shuffle[$pc1map[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") |
+ ($this->shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") |
+ ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") |
+ ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00");
+ $key = unpack('Nc/Nd', $key);
+ $c = ( $key['c'] >> 4) & 0x0FFFFFFF;
+ $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
+
+ $keys[$des_round] = array(
+ self::ENCRYPT => array(),
+ self::DECRYPT => array_fill(0, 32, 0)
+ );
+ for ($i = 0, $ki = 31; $i < 16; ++$i, $ki-= 2) {
+ $c <<= $shifts[$i];
+ $c = ($c | ($c >> 28)) & 0x0FFFFFFF;
+ $d <<= $shifts[$i];
+ $d = ($d | ($d >> 28)) & 0x0FFFFFFF;
+
+ // Perform the PC-2 transformation.
+ $cp = $pc2mapc1[ $c >> 24 ] | $pc2mapc2[($c >> 16) & 0xFF] |
+ $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[ $c & 0xFF];
+ $dp = $pc2mapd1[ $d >> 24 ] | $pc2mapd2[($d >> 16) & 0xFF] |
+ $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF];
+
+ // Reorder: odd bytes/even bytes. Push the result in key schedule.
+ $val1 = ( $cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
+ (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF);
+ $val2 = (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
+ (($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF);
+ $keys[$des_round][self::ENCRYPT][ ] = $val1;
+ $keys[$des_round][self::DECRYPT][$ki - 1] = $val1;
+ $keys[$des_round][self::ENCRYPT][ ] = $val2;
+ $keys[$des_round][self::DECRYPT][$ki ] = $val2;
+ }
+ }
+
+ switch ($this->des_rounds) {
+ case 3: // 3DES keys
+ $this->keys = array(
+ self::ENCRYPT => array_merge(
+ $keys[0][self::ENCRYPT],
+ $keys[1][self::DECRYPT],
+ $keys[2][self::ENCRYPT]
+ ),
+ self::DECRYPT => array_merge(
+ $keys[2][self::DECRYPT],
+ $keys[1][self::ENCRYPT],
+ $keys[0][self::DECRYPT]
+ )
+ );
+ break;
+ // case 1: // DES keys
+ default:
+ $this->keys = array(
+ self::ENCRYPT => $keys[0][self::ENCRYPT],
+ self::DECRYPT => $keys[0][self::DECRYPT]
+ );
+ }
+ }
+
+ /**
+ * Setup the performance-optimized function for de/encrypt()
+ *
+ * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
+ * @access private
+ */
+ function _setupInlineCrypt()
+ {
+ $lambda_functions =& self::_getLambdaFunctions();
+
+ // Engine configuration for:
+ // - DES ($des_rounds == 1) or
+ // - 3DES ($des_rounds == 3)
+ $des_rounds = $this->des_rounds;
+
+ // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
+ // (Currently, for DES, one generated $lambda_function cost on php5.5@32bit ~135kb unfreeable mem and ~230kb on php5.5@64bit)
+ // (Currently, for TripleDES, one generated $lambda_function cost on php5.5@32bit ~240kb unfreeable mem and ~340kb on php5.5@64bit)
+ // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one
+ $gen_hi_opt_code = (bool)( count($lambda_functions) < 10 );
+
+ // Generation of a unique hash for our generated code
+ $code_hash = "Crypt_DES, $des_rounds, {$this->mode}";
+ if ($gen_hi_opt_code) {
+ // For hi-optimized code, we create for each combination of
+ // $mode, $des_rounds and $this->key its own encrypt/decrypt function.
+ // After max 10 hi-optimized functions, we create generic
+ // (still very fast.. but not ultra) functions for each $mode/$des_rounds
+ // Currently 2 * 5 generic functions will be then max. possible.
+ $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+ }
+
+ // Is there a re-usable $lambda_functions in there? If not, we have to create it.
+ if (!isset($lambda_functions[$code_hash])) {
+ // Init code for both, encrypt and decrypt.
+ $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip;
+ if (!$sbox1) {
+ $sbox1 = array_map("intval", $self->sbox1);
+ $sbox2 = array_map("intval", $self->sbox2);
+ $sbox3 = array_map("intval", $self->sbox3);
+ $sbox4 = array_map("intval", $self->sbox4);
+ $sbox5 = array_map("intval", $self->sbox5);
+ $sbox6 = array_map("intval", $self->sbox6);
+ $sbox7 = array_map("intval", $self->sbox7);
+ $sbox8 = array_map("intval", $self->sbox8);'
+ /* Merge $shuffle with $[inv]ipmap */ . '
+ for ($i = 0; $i < 256; ++$i) {
+ $shuffleip[] = $self->shuffle[$self->ipmap[$i]];
+ $shuffleinvip[] = $self->shuffle[$self->invipmap[$i]];
+ }
+ }
+ ';
+
+ switch (true) {
+ case $gen_hi_opt_code:
+ // In Hi-optimized code mode, we use our [3]DES key schedule as hardcoded integers.
+ // No futher initialisation of the $keys schedule is necessary.
+ // That is the extra performance boost.
+ $k = array(
+ self::ENCRYPT => $this->keys[self::ENCRYPT],
+ self::DECRYPT => $this->keys[self::DECRYPT]
+ );
+ $init_encrypt = '';
+ $init_decrypt = '';
+ break;
+ default:
+ // In generic optimized code mode, we have to use, as the best compromise [currently],
+ // our key schedule as $ke/$kd arrays. (with hardcoded indexes...)
+ $k = array(
+ self::ENCRYPT => array(),
+ self::DECRYPT => array()
+ );
+ for ($i = 0, $c = count($this->keys[self::ENCRYPT]); $i < $c; ++$i) {
+ $k[self::ENCRYPT][$i] = '$ke[' . $i . ']';
+ $k[self::DECRYPT][$i] = '$kd[' . $i . ']';
+ }
+ $init_encrypt = '$ke = $self->keys[$self::ENCRYPT];';
+ $init_decrypt = '$kd = $self->keys[$self::DECRYPT];';
+ break;
+ }
+
+ // Creating code for en- and decryption.
+ $crypt_block = array();
+ foreach (array(self::ENCRYPT, self::DECRYPT) as $c) {
+ /* Do the initial IP permutation. */
+ $crypt_block[$c] = '
+ $in = unpack("N*", $in);
+ $l = $in[1];
+ $r = $in[2];
+ $in = unpack("N*",
+ ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
+ ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
+ ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
+ ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
+ ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
+ ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
+ ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
+ ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01")
+ );
+ ' . /* Extract L0 and R0 */ '
+ $l = $in[1];
+ $r = $in[2];
+ ';
+
+ $l = '$l';
+ $r = '$r';
+
+ // Perform DES or 3DES.
+ for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) {
+ // Perform the 16 steps.
+ for ($i = 0; $i < 16; ++$i) {
+ // start of "the Feistel (F) function" - see the following URL:
+ // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
+ // Merge key schedule.
+ $crypt_block[$c].= '
+ $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . ';
+ $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' .
+ /* S-box indexing. */
+ $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
+ $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
+ $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
+ $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . ';
+ ';
+ // end of "the Feistel (F) function"
+
+ // swap L & R
+ list($l, $r) = array($r, $l);
+ }
+ list($l, $r) = array($r, $l);
+ }
+
+ // Perform the inverse IP permutation.
+ $crypt_block[$c].= '$in =
+ ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
+ ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
+ ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
+ ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
+ ($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
+ ($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
+ ($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
+ ($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01");
+ ';
+ }
+
+ // Creates the inline-crypt function
+ $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
+ array(
+ 'init_crypt' => $init_crypt,
+ 'init_encrypt' => $init_encrypt,
+ 'init_decrypt' => $init_decrypt,
+ 'encrypt_block' => $crypt_block[self::ENCRYPT],
+ 'decrypt_block' => $crypt_block[self::DECRYPT]
+ )
+ );
+ }
+
+ // Set the inline-crypt function as callback in: $this->inline_crypt
+ $this->inline_crypt = $lambda_functions[$code_hash];
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
new file mode 100644
index 0000000..a616682
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php
@@ -0,0 +1,894 @@
+<?php
+
+/**
+ * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
+ *
+ * Uses hash() or mhash() if available and an internal implementation, otherwise. Currently supports the following:
+ *
+ * md2, md5, md5-96, sha1, sha1-96, sha256, sha256-96, sha384, and sha512, sha512-96
+ *
+ * If {@link self::setKey() setKey()} is called, {@link self::hash() hash()} will return the HMAC as opposed to
+ * the hash. If no valid algorithm is provided, sha1 will be used.
+ *
+ * PHP version 5
+ *
+ * {@internal The variable names are the same as those in
+ * {@link http://tools.ietf.org/html/rfc2104#section-2 RFC2104}.}}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $hash = new \phpseclib\Crypt\Hash('sha1');
+ *
+ * $hash->setKey('abcdefg');
+ *
+ * echo base64_encode($hash->hash('abcdefg'));
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package Hash
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+use phpseclib\Math\BigInteger;
+
+/**
+ * Pure-PHP implementations of keyed-hash message authentication codes (HMACs) and various cryptographic hashing functions.
+ *
+ * @package Hash
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class Hash
+{
+ /**#@+
+ * @access private
+ * @see \phpseclib\Crypt\Hash::__construct()
+ */
+ /**
+ * Toggles the internal implementation
+ */
+ const MODE_INTERNAL = 1;
+ /**
+ * Toggles the mhash() implementation, which has been deprecated on PHP 5.3.0+.
+ */
+ const MODE_MHASH = 2;
+ /**
+ * Toggles the hash() implementation, which works on PHP 5.1.2+.
+ */
+ const MODE_HASH = 3;
+ /**#@-*/
+
+ /**
+ * Hash Parameter
+ *
+ * @see self::setHash()
+ * @var int
+ * @access private
+ */
+ var $hashParam;
+
+ /**
+ * Byte-length of compression blocks / key (Internal HMAC)
+ *
+ * @see self::setAlgorithm()
+ * @var int
+ * @access private
+ */
+ var $b;
+
+ /**
+ * Byte-length of hash output (Internal HMAC)
+ *
+ * @see self::setHash()
+ * @var int
+ * @access private
+ */
+ var $l = false;
+
+ /**
+ * Hash Algorithm
+ *
+ * @see self::setHash()
+ * @var string
+ * @access private
+ */
+ var $hash;
+
+ /**
+ * Key
+ *
+ * @see self::setKey()
+ * @var string
+ * @access private
+ */
+ var $key = false;
+
+ /**
+ * Computed Key
+ *
+ * @see self::_computeKey()
+ * @var string
+ * @access private
+ */
+ var $computedKey = false;
+
+ /**
+ * Outer XOR (Internal HMAC)
+ *
+ * @see self::setKey()
+ * @var string
+ * @access private
+ */
+ var $opad;
+
+ /**
+ * Inner XOR (Internal HMAC)
+ *
+ * @see self::setKey()
+ * @var string
+ * @access private
+ */
+ var $ipad;
+
+ /**
+ * Engine
+ *
+ * @see self::setHash()
+ * @var string
+ * @access private
+ */
+ var $engine;
+
+ /**
+ * Default Constructor.
+ *
+ * @param string $hash
+ * @return \phpseclib\Crypt\Hash
+ * @access public
+ */
+ function __construct($hash = 'sha1')
+ {
+ if (!defined('CRYPT_HASH_MODE')) {
+ switch (true) {
+ case extension_loaded('hash'):
+ define('CRYPT_HASH_MODE', self::MODE_HASH);
+ break;
+ case extension_loaded('mhash'):
+ define('CRYPT_HASH_MODE', self::MODE_MHASH);
+ break;
+ default:
+ define('CRYPT_HASH_MODE', self::MODE_INTERNAL);
+ }
+ }
+
+ $this->setHash($hash);
+ }
+
+ /**
+ * Sets the key for HMACs
+ *
+ * Keys can be of any length.
+ *
+ * @access public
+ * @param string $key
+ */
+ function setKey($key = false)
+ {
+ $this->key = $key;
+ $this->_computeKey();
+ }
+
+ /**
+ * Pre-compute the key used by the HMAC
+ *
+ * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes
+ * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC."
+ *
+ * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/
+ * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during
+ * every call
+ *
+ * @access private
+ */
+ function _computeKey()
+ {
+ if ($this->key === false) {
+ $this->computedKey = false;
+ return;
+ }
+
+ if (strlen($this->key) <= $this->b) {
+ $this->computedKey = $this->key;
+ return;
+ }
+
+ switch ($this->engine) {
+ case self::MODE_MHASH:
+ $this->computedKey = mhash($this->hash, $this->key);
+ break;
+ case self::MODE_HASH:
+ $this->computedKey = hash($this->hash, $this->key, true);
+ break;
+ case self::MODE_INTERNAL:
+ $this->computedKey = call_user_func($this->hash, $this->key);
+ }
+ }
+
+ /**
+ * Gets the hash function.
+ *
+ * As set by the constructor or by the setHash() method.
+ *
+ * @access public
+ * @return string
+ */
+ function getHash()
+ {
+ return $this->hashParam;
+ }
+
+ /**
+ * Sets the hash function.
+ *
+ * @access public
+ * @param string $hash
+ */
+ function setHash($hash)
+ {
+ $this->hashParam = $hash = strtolower($hash);
+ switch ($hash) {
+ case 'md5-96':
+ case 'sha1-96':
+ case 'sha256-96':
+ case 'sha512-96':
+ $hash = substr($hash, 0, -3);
+ $this->l = 12; // 96 / 8 = 12
+ break;
+ case 'md2':
+ case 'md5':
+ $this->l = 16;
+ break;
+ case 'sha1':
+ $this->l = 20;
+ break;
+ case 'sha256':
+ $this->l = 32;
+ break;
+ case 'sha384':
+ $this->l = 48;
+ break;
+ case 'sha512':
+ $this->l = 64;
+ }
+
+ switch ($hash) {
+ case 'md2-96':
+ case 'md2':
+ $this->b = 16;
+ case 'md5-96':
+ case 'sha1-96':
+ case 'sha224-96':
+ case 'sha256-96':
+ case 'md2':
+ case 'md5':
+ case 'sha1':
+ case 'sha224':
+ case 'sha256':
+ $this->b = 64;
+ break;
+ default:
+ $this->b = 128;
+ }
+
+ switch ($hash) {
+ case 'md2':
+ $this->engine = CRYPT_HASH_MODE == self::MODE_HASH && in_array('md2', hash_algos()) ?
+ self::MODE_HASH : self::MODE_INTERNAL;
+ break;
+ case 'sha384':
+ case 'sha512':
+ $this->engine = CRYPT_HASH_MODE == self::MODE_MHASH ? self::MODE_INTERNAL : CRYPT_HASH_MODE;
+ break;
+ default:
+ $this->engine = CRYPT_HASH_MODE;
+ }
+
+ switch ($this->engine) {
+ case self::MODE_MHASH:
+ switch ($hash) {
+ case 'md5':
+ $this->hash = MHASH_MD5;
+ break;
+ case 'sha256':
+ $this->hash = MHASH_SHA256;
+ break;
+ case 'sha1':
+ default:
+ $this->hash = MHASH_SHA1;
+ }
+ $this->_computeKey(self::MODE_MHASH);
+ return;
+ case self::MODE_HASH:
+ switch ($hash) {
+ case 'md5':
+ $this->hash = 'md5';
+ return;
+ case 'md2':
+ case 'sha256':
+ case 'sha384':
+ case 'sha512':
+ $this->hash = $hash;
+ return;
+ case 'sha1':
+ default:
+ $this->hash = 'sha1';
+ }
+ $this->_computeKey(self::MODE_HASH);
+ return;
+ }
+
+ switch ($hash) {
+ case 'md2':
+ $this->hash = array($this, '_md2');
+ break;
+ case 'md5':
+ $this->hash = array($this, '_md5');
+ break;
+ case 'sha256':
+ $this->hash = array($this, '_sha256');
+ break;
+ case 'sha384':
+ case 'sha512':
+ $this->hash = array($this, '_sha512');
+ break;
+ case 'sha1':
+ default:
+ $this->hash = array($this, '_sha1');
+ }
+
+ $this->ipad = str_repeat(chr(0x36), $this->b);
+ $this->opad = str_repeat(chr(0x5C), $this->b);
+
+ $this->_computeKey(self::MODE_INTERNAL);
+ }
+
+ /**
+ * Compute the HMAC.
+ *
+ * @access public
+ * @param string $text
+ * @return string
+ */
+ function hash($text)
+ {
+ if (!empty($this->key) || is_string($this->key)) {
+ switch ($this->engine) {
+ case self::MODE_MHASH:
+ $output = mhash($this->hash, $text, $this->computedKey);
+ break;
+ case self::MODE_HASH:
+ $output = hash_hmac($this->hash, $text, $this->computedKey, true);
+ break;
+ case self::MODE_INTERNAL:
+ $key = str_pad($this->computedKey, $this->b, chr(0)); // step 1
+ $temp = $this->ipad ^ $key; // step 2
+ $temp .= $text; // step 3
+ $temp = call_user_func($this->hash, $temp); // step 4
+ $output = $this->opad ^ $key; // step 5
+ $output.= $temp; // step 6
+ $output = call_user_func($this->hash, $output); // step 7
+ }
+ } else {
+ switch ($this->engine) {
+ case self::MODE_MHASH:
+ $output = mhash($this->hash, $text);
+ break;
+ case self::MODE_HASH:
+ $output = hash($this->hash, $text, true);
+ break;
+ case self::MODE_INTERNAL:
+ $output = call_user_func($this->hash, $text);
+ }
+ }
+
+ return substr($output, 0, $this->l);
+ }
+
+ /**
+ * Returns the hash length (in bytes)
+ *
+ * @access public
+ * @return int
+ */
+ function getLength()
+ {
+ return $this->l;
+ }
+
+ /**
+ * Wrapper for MD5
+ *
+ * @access private
+ * @param string $m
+ */
+ function _md5($m)
+ {
+ return pack('H*', md5($m));
+ }
+
+ /**
+ * Wrapper for SHA1
+ *
+ * @access private
+ * @param string $m
+ */
+ function _sha1($m)
+ {
+ return pack('H*', sha1($m));
+ }
+
+ /**
+ * Pure-PHP implementation of MD2
+ *
+ * See {@link http://tools.ietf.org/html/rfc1319 RFC1319}.
+ *
+ * @access private
+ * @param string $m
+ */
+ function _md2($m)
+ {
+ static $s = array(
+ 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
+ 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
+ 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
+ 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
+ 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
+ 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
+ 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
+ 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
+ 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
+ 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
+ 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
+ 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
+ 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
+ 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
+ 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
+ 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
+ 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
+ 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
+ );
+
+ // Step 1. Append Padding Bytes
+ $pad = 16 - (strlen($m) & 0xF);
+ $m.= str_repeat(chr($pad), $pad);
+
+ $length = strlen($m);
+
+ // Step 2. Append Checksum
+ $c = str_repeat(chr(0), 16);
+ $l = chr(0);
+ for ($i = 0; $i < $length; $i+= 16) {
+ for ($j = 0; $j < 16; $j++) {
+ // RFC1319 incorrectly states that C[j] should be set to S[c xor L]
+ //$c[$j] = chr($s[ord($m[$i + $j] ^ $l)]);
+ // per <http://www.rfc-editor.org/errata_search.php?rfc=1319>, however, C[j] should be set to S[c xor L] xor C[j]
+ $c[$j] = chr($s[ord($m[$i + $j] ^ $l)] ^ ord($c[$j]));
+ $l = $c[$j];
+ }
+ }
+ $m.= $c;
+
+ $length+= 16;
+
+ // Step 3. Initialize MD Buffer
+ $x = str_repeat(chr(0), 48);
+
+ // Step 4. Process Message in 16-Byte Blocks
+ for ($i = 0; $i < $length; $i+= 16) {
+ for ($j = 0; $j < 16; $j++) {
+ $x[$j + 16] = $m[$i + $j];
+ $x[$j + 32] = $x[$j + 16] ^ $x[$j];
+ }
+ $t = chr(0);
+ for ($j = 0; $j < 18; $j++) {
+ for ($k = 0; $k < 48; $k++) {
+ $x[$k] = $t = $x[$k] ^ chr($s[ord($t)]);
+ //$t = $x[$k] = $x[$k] ^ chr($s[ord($t)]);
+ }
+ $t = chr(ord($t) + $j);
+ }
+ }
+
+ // Step 5. Output
+ return substr($x, 0, 16);
+ }
+
+ /**
+ * Pure-PHP implementation of SHA256
+ *
+ * See {@link http://en.wikipedia.org/wiki/SHA_hash_functions#SHA-256_.28a_SHA-2_variant.29_pseudocode SHA-256 (a SHA-2 variant) pseudocode - Wikipedia}.
+ *
+ * @access private
+ * @param string $m
+ */
+ function _sha256($m)
+ {
+ if (extension_loaded('suhosin')) {
+ return pack('H*', sha256($m));
+ }
+
+ // Initialize variables
+ $hash = array(
+ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+ );
+ // Initialize table of round constants
+ // (first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
+ static $k = array(
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ );
+
+ // Pre-processing
+ $length = strlen($m);
+ // to round to nearest 56 mod 64, we'll add 64 - (length + (64 - 56)) % 64
+ $m.= str_repeat(chr(0), 64 - (($length + 8) & 0x3F));
+ $m[$length] = chr(0x80);
+ // we don't support hashing strings 512MB long
+ $m.= pack('N2', 0, $length << 3);
+
+ // Process the message in successive 512-bit chunks
+ $chunks = str_split($m, 64);
+ foreach ($chunks as $chunk) {
+ $w = array();
+ for ($i = 0; $i < 16; $i++) {
+ extract(unpack('Ntemp', $this->_string_shift($chunk, 4)));
+ $w[] = $temp;
+ }
+
+ // Extend the sixteen 32-bit words into sixty-four 32-bit words
+ for ($i = 16; $i < 64; $i++) {
+ // @codingStandardsIgnoreStart
+ $s0 = $this->_rightRotate($w[$i - 15], 7) ^
+ $this->_rightRotate($w[$i - 15], 18) ^
+ $this->_rightShift( $w[$i - 15], 3);
+ $s1 = $this->_rightRotate($w[$i - 2], 17) ^
+ $this->_rightRotate($w[$i - 2], 19) ^
+ $this->_rightShift( $w[$i - 2], 10);
+ // @codingStandardsIgnoreEnd
+ $w[$i] = $this->_add($w[$i - 16], $s0, $w[$i - 7], $s1);
+ }
+
+ // Initialize hash value for this chunk
+ list($a, $b, $c, $d, $e, $f, $g, $h) = $hash;
+
+ // Main loop
+ for ($i = 0; $i < 64; $i++) {
+ $s0 = $this->_rightRotate($a, 2) ^
+ $this->_rightRotate($a, 13) ^
+ $this->_rightRotate($a, 22);
+ $maj = ($a & $b) ^
+ ($a & $c) ^
+ ($b & $c);
+ $t2 = $this->_add($s0, $maj);
+
+ $s1 = $this->_rightRotate($e, 6) ^
+ $this->_rightRotate($e, 11) ^
+ $this->_rightRotate($e, 25);
+ $ch = ($e & $f) ^
+ ($this->_not($e) & $g);
+ $t1 = $this->_add($h, $s1, $ch, $k[$i], $w[$i]);
+
+ $h = $g;
+ $g = $f;
+ $f = $e;
+ $e = $this->_add($d, $t1);
+ $d = $c;
+ $c = $b;
+ $b = $a;
+ $a = $this->_add($t1, $t2);
+ }
+
+ // Add this chunk's hash to result so far
+ $hash = array(
+ $this->_add($hash[0], $a),
+ $this->_add($hash[1], $b),
+ $this->_add($hash[2], $c),
+ $this->_add($hash[3], $d),
+ $this->_add($hash[4], $e),
+ $this->_add($hash[5], $f),
+ $this->_add($hash[6], $g),
+ $this->_add($hash[7], $h)
+ );
+ }
+
+ // Produce the final hash value (big-endian)
+ return pack('N8', $hash[0], $hash[1], $hash[2], $hash[3], $hash[4], $hash[5], $hash[6], $hash[7]);
+ }
+
+ /**
+ * Pure-PHP implementation of SHA384 and SHA512
+ *
+ * @access private
+ * @param string $m
+ */
+ function _sha512($m)
+ {
+ static $init384, $init512, $k;
+
+ if (!isset($k)) {
+ // Initialize variables
+ $init384 = array( // initial values for SHA384
+ 'cbbb9d5dc1059ed8', '629a292a367cd507', '9159015a3070dd17', '152fecd8f70e5939',
+ '67332667ffc00b31', '8eb44a8768581511', 'db0c2e0d64f98fa7', '47b5481dbefa4fa4'
+ );
+ $init512 = array( // initial values for SHA512
+ '6a09e667f3bcc908', 'bb67ae8584caa73b', '3c6ef372fe94f82b', 'a54ff53a5f1d36f1',
+ '510e527fade682d1', '9b05688c2b3e6c1f', '1f83d9abfb41bd6b', '5be0cd19137e2179'
+ );
+
+ for ($i = 0; $i < 8; $i++) {
+ $init384[$i] = new BigInteger($init384[$i], 16);
+ $init384[$i]->setPrecision(64);
+ $init512[$i] = new BigInteger($init512[$i], 16);
+ $init512[$i]->setPrecision(64);
+ }
+
+ // Initialize table of round constants
+ // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
+ $k = array(
+ '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc',
+ '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118',
+ 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2',
+ '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694',
+ 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65',
+ '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5',
+ '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4',
+ 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70',
+ '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df',
+ '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b',
+ 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30',
+ 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8',
+ '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8',
+ '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3',
+ '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec',
+ '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b',
+ 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178',
+ '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b',
+ '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c',
+ '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817'
+ );
+
+ for ($i = 0; $i < 80; $i++) {
+ $k[$i] = new BigInteger($k[$i], 16);
+ }
+ }
+
+ $hash = $this->l == 48 ? $init384 : $init512;
+
+ // Pre-processing
+ $length = strlen($m);
+ // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128
+ $m.= str_repeat(chr(0), 128 - (($length + 16) & 0x7F));
+ $m[$length] = chr(0x80);
+ // we don't support hashing strings 512MB long
+ $m.= pack('N4', 0, 0, 0, $length << 3);
+
+ // Process the message in successive 1024-bit chunks
+ $chunks = str_split($m, 128);
+ foreach ($chunks as $chunk) {
+ $w = array();
+ for ($i = 0; $i < 16; $i++) {
+ $temp = new BigInteger($this->_string_shift($chunk, 8), 256);
+ $temp->setPrecision(64);
+ $w[] = $temp;
+ }
+
+ // Extend the sixteen 32-bit words into eighty 32-bit words
+ for ($i = 16; $i < 80; $i++) {
+ $temp = array(
+ $w[$i - 15]->bitwise_rightRotate(1),
+ $w[$i - 15]->bitwise_rightRotate(8),
+ $w[$i - 15]->bitwise_rightShift(7)
+ );
+ $s0 = $temp[0]->bitwise_xor($temp[1]);
+ $s0 = $s0->bitwise_xor($temp[2]);
+ $temp = array(
+ $w[$i - 2]->bitwise_rightRotate(19),
+ $w[$i - 2]->bitwise_rightRotate(61),
+ $w[$i - 2]->bitwise_rightShift(6)
+ );
+ $s1 = $temp[0]->bitwise_xor($temp[1]);
+ $s1 = $s1->bitwise_xor($temp[2]);
+ $w[$i] = $w[$i - 16]->copy();
+ $w[$i] = $w[$i]->add($s0);
+ $w[$i] = $w[$i]->add($w[$i - 7]);
+ $w[$i] = $w[$i]->add($s1);
+ }
+
+ // Initialize hash value for this chunk
+ $a = $hash[0]->copy();
+ $b = $hash[1]->copy();
+ $c = $hash[2]->copy();
+ $d = $hash[3]->copy();
+ $e = $hash[4]->copy();
+ $f = $hash[5]->copy();
+ $g = $hash[6]->copy();
+ $h = $hash[7]->copy();
+
+ // Main loop
+ for ($i = 0; $i < 80; $i++) {
+ $temp = array(
+ $a->bitwise_rightRotate(28),
+ $a->bitwise_rightRotate(34),
+ $a->bitwise_rightRotate(39)
+ );
+ $s0 = $temp[0]->bitwise_xor($temp[1]);
+ $s0 = $s0->bitwise_xor($temp[2]);
+ $temp = array(
+ $a->bitwise_and($b),
+ $a->bitwise_and($c),
+ $b->bitwise_and($c)
+ );
+ $maj = $temp[0]->bitwise_xor($temp[1]);
+ $maj = $maj->bitwise_xor($temp[2]);
+ $t2 = $s0->add($maj);
+
+ $temp = array(
+ $e->bitwise_rightRotate(14),
+ $e->bitwise_rightRotate(18),
+ $e->bitwise_rightRotate(41)
+ );
+ $s1 = $temp[0]->bitwise_xor($temp[1]);
+ $s1 = $s1->bitwise_xor($temp[2]);
+ $temp = array(
+ $e->bitwise_and($f),
+ $g->bitwise_and($e->bitwise_not())
+ );
+ $ch = $temp[0]->bitwise_xor($temp[1]);
+ $t1 = $h->add($s1);
+ $t1 = $t1->add($ch);
+ $t1 = $t1->add($k[$i]);
+ $t1 = $t1->add($w[$i]);
+
+ $h = $g->copy();
+ $g = $f->copy();
+ $f = $e->copy();
+ $e = $d->add($t1);
+ $d = $c->copy();
+ $c = $b->copy();
+ $b = $a->copy();
+ $a = $t1->add($t2);
+ }
+
+ // Add this chunk's hash to result so far
+ $hash = array(
+ $hash[0]->add($a),
+ $hash[1]->add($b),
+ $hash[2]->add($c),
+ $hash[3]->add($d),
+ $hash[4]->add($e),
+ $hash[5]->add($f),
+ $hash[6]->add($g),
+ $hash[7]->add($h)
+ );
+ }
+
+ // Produce the final hash value (big-endian)
+ // (\phpseclib\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here)
+ $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() .
+ $hash[4]->toBytes() . $hash[5]->toBytes();
+ if ($this->l != 48) {
+ $temp.= $hash[6]->toBytes() . $hash[7]->toBytes();
+ }
+
+ return $temp;
+ }
+
+ /**
+ * Right Rotate
+ *
+ * @access private
+ * @param int $int
+ * @param int $amt
+ * @see self::_sha256()
+ * @return int
+ */
+ function _rightRotate($int, $amt)
+ {
+ $invamt = 32 - $amt;
+ $mask = (1 << $invamt) - 1;
+ return (($int << $invamt) & 0xFFFFFFFF) | (($int >> $amt) & $mask);
+ }
+
+ /**
+ * Right Shift
+ *
+ * @access private
+ * @param int $int
+ * @param int $amt
+ * @see self::_sha256()
+ * @return int
+ */
+ function _rightShift($int, $amt)
+ {
+ $mask = (1 << (32 - $amt)) - 1;
+ return ($int >> $amt) & $mask;
+ }
+
+ /**
+ * Not
+ *
+ * @access private
+ * @param int $int
+ * @see self::_sha256()
+ * @return int
+ */
+ function _not($int)
+ {
+ return ~$int & 0xFFFFFFFF;
+ }
+
+ /**
+ * Add
+ *
+ * _sha256() adds multiple unsigned 32-bit integers. Since PHP doesn't support unsigned integers and since the
+ * possibility of overflow exists, care has to be taken. BigInteger could be used but this should be faster.
+ *
+ * @param int $...
+ * @return int
+ * @see self::_sha256()
+ * @access private
+ */
+ function _add()
+ {
+ static $mod;
+ if (!isset($mod)) {
+ $mod = pow(2, 32);
+ }
+
+ $result = 0;
+ $arguments = func_get_args();
+ foreach ($arguments as $argument) {
+ $result+= $argument < 0 ? ($argument & 0x7FFFFFFF) + 0x80000000 : $argument;
+ }
+
+ if ((php_uname('m') & "\xDF\xDF\xDF") != 'ARM') {
+ return fmod($result, $mod);
+ }
+
+ return (fmod($result, 0x80000000) & 0x7FFFFFFF) |
+ ((fmod(floor($result / 0x80000000), 2) & 1) << 31);
+ }
+
+ /**
+ * String Shift
+ *
+ * Inspired by array_shift
+ *
+ * @param string $string
+ * @param int $index
+ * @return string
+ * @access private
+ */
+ function _string_shift(&$string, $index = 1)
+ {
+ $substr = substr($string, 0, $index);
+ $string = substr($string, $index);
+ return $substr;
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php
new file mode 100644
index 0000000..b2b9d48
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php
@@ -0,0 +1,688 @@
+<?php
+
+/**
+ * Pure-PHP implementation of RC2.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * Useful resources are as follows:
+ *
+ * - {@link http://tools.ietf.org/html/rfc2268}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $rc2 = new \phpseclib\Crypt\RC2();
+ *
+ * $rc2->setKey('abcdefgh');
+ *
+ * $plaintext = str_repeat('a', 1024);
+ *
+ * echo $rc2->decrypt($rc2->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package RC2
+ * @author Patrick Monnerat <pm@datasphere.ch>
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of RC2.
+ *
+ * @package RC2
+ * @access public
+ */
+class RC2 extends Base
+{
+ /**
+ * Block Length of the cipher
+ *
+ * @see \phpseclib\Crypt\Base::block_size
+ * @var int
+ * @access private
+ */
+ var $block_size = 8;
+
+ /**
+ * The Key
+ *
+ * @see \phpseclib\Crypt\Base::key
+ * @see self::setKey()
+ * @var string
+ * @access private
+ */
+ var $key;
+
+ /**
+ * The Original (unpadded) Key
+ *
+ * @see \phpseclib\Crypt\Base::key
+ * @see self::setKey()
+ * @see self::encrypt()
+ * @see self::decrypt()
+ * @var string
+ * @access private
+ */
+ var $orig_key;
+
+ /**
+ * Don't truncate / null pad key
+ *
+ * @see \phpseclib\Crypt\Base::_clearBuffers()
+ * @var bool
+ * @access private
+ */
+ var $skip_key_adjustment = true;
+
+ /**
+ * Key Length (in bytes)
+ *
+ * @see \phpseclib\Crypt\RC2::setKeyLength()
+ * @var int
+ * @access private
+ */
+ var $key_length = 16; // = 128 bits
+
+ /**
+ * The mcrypt specific name of the cipher
+ *
+ * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+ * @var string
+ * @access private
+ */
+ var $cipher_name_mcrypt = 'rc2';
+
+ /**
+ * Optimizing value while CFB-encrypting
+ *
+ * @see \phpseclib\Crypt\Base::cfb_init_len
+ * @var int
+ * @access private
+ */
+ var $cfb_init_len = 500;
+
+ /**
+ * The key length in bits.
+ *
+ * @see self::setKeyLength()
+ * @see self::setKey()
+ * @var int
+ * @access private
+ * @internal Should be in range [1..1024].
+ * @internal Changing this value after setting the key has no effect.
+ */
+ var $default_key_length = 1024;
+
+ /**
+ * The key length in bits.
+ *
+ * @see self::isValidEnine()
+ * @see self::setKey()
+ * @var int
+ * @access private
+ * @internal Should be in range [1..1024].
+ */
+ var $current_key_length;
+
+ /**
+ * The Key Schedule
+ *
+ * @see self::_setupKey()
+ * @var array
+ * @access private
+ */
+ var $keys;
+
+ /**
+ * Key expansion randomization table.
+ * Twice the same 256-value sequence to save a modulus in key expansion.
+ *
+ * @see self::setKey()
+ * @var array
+ * @access private
+ */
+ var $pitable = array(
+ 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
+ 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
+ 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
+ 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
+ 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
+ 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
+ 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
+ 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
+ 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
+ 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
+ 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
+ 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
+ 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
+ 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
+ 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
+ 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
+ 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
+ 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
+ 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
+ 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
+ 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
+ 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
+ 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
+ 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
+ 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
+ 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
+ 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
+ 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
+ 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
+ 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
+ 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
+ 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD,
+ 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED,
+ 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D,
+ 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E,
+ 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2,
+ 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13,
+ 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32,
+ 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B,
+ 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82,
+ 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C,
+ 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC,
+ 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1,
+ 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26,
+ 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57,
+ 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03,
+ 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7,
+ 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7,
+ 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7,
+ 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A,
+ 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74,
+ 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC,
+ 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC,
+ 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39,
+ 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A,
+ 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31,
+ 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE,
+ 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9,
+ 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C,
+ 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9,
+ 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0,
+ 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E,
+ 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77,
+ 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD
+ );
+
+ /**
+ * Inverse key expansion randomization table.
+ *
+ * @see self::setKey()
+ * @var array
+ * @access private
+ */
+ var $invpitable = array(
+ 0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66,
+ 0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4,
+ 0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20,
+ 0x9D, 0x04, 0x91, 0xE3, 0x47, 0x6A, 0x7E, 0x53,
+ 0xFA, 0x3A, 0x3B, 0xB4, 0xA8, 0xBC, 0x5F, 0x68,
+ 0x08, 0xCA, 0x8F, 0x14, 0xD7, 0xC0, 0xEF, 0x7B,
+ 0x5B, 0xBF, 0x2F, 0xE5, 0xE2, 0x8C, 0xBA, 0x12,
+ 0xE1, 0xAF, 0xB2, 0x54, 0x5D, 0x59, 0x76, 0xDB,
+ 0x32, 0xA2, 0x58, 0x6E, 0x1C, 0x29, 0x64, 0xF3,
+ 0xE9, 0x96, 0x0C, 0x98, 0x19, 0x8D, 0x3E, 0x26,
+ 0xAB, 0xA5, 0x85, 0x16, 0x40, 0xBD, 0x49, 0x67,
+ 0xDC, 0x22, 0x94, 0xBB, 0x3C, 0xC1, 0x9B, 0xEB,
+ 0x45, 0x28, 0x18, 0xD8, 0x1A, 0x42, 0x7D, 0xCC,
+ 0xFB, 0x65, 0x8E, 0x3D, 0xCD, 0x2A, 0xA3, 0x60,
+ 0xAE, 0x93, 0x8A, 0x48, 0x97, 0x51, 0x15, 0xF7,
+ 0x01, 0x0B, 0xB7, 0x36, 0xB1, 0x2E, 0x11, 0xFD,
+ 0x84, 0x2D, 0x3F, 0x13, 0x88, 0xB3, 0x34, 0x24,
+ 0x1B, 0xDE, 0xC5, 0x1D, 0x4D, 0x2B, 0x17, 0x31,
+ 0x74, 0xA9, 0xC6, 0x43, 0x6D, 0x39, 0x90, 0xBE,
+ 0xC3, 0xB0, 0x21, 0x6B, 0xF6, 0x0F, 0xD5, 0x99,
+ 0x0D, 0xAC, 0x1F, 0x5C, 0x9E, 0xF5, 0xF9, 0x4C,
+ 0xD6, 0xDF, 0x89, 0xE4, 0x8B, 0xFF, 0xC7, 0xAA,
+ 0xE7, 0xED, 0x46, 0x25, 0xB6, 0x06, 0x5E, 0x35,
+ 0xB5, 0xEC, 0xCE, 0xE8, 0x6C, 0x30, 0x55, 0x61,
+ 0x4A, 0xFE, 0xA0, 0x79, 0x03, 0xF0, 0x10, 0x72,
+ 0x7C, 0xCF, 0x52, 0xA6, 0xA7, 0xEE, 0x44, 0xD3,
+ 0x9A, 0x57, 0x92, 0xD0, 0x5A, 0x7A, 0x41, 0x7F,
+ 0x0E, 0x00, 0x63, 0xF2, 0x4F, 0x05, 0x83, 0xC9,
+ 0xA1, 0xD4, 0xDD, 0xC4, 0x56, 0xF4, 0xD2, 0x77,
+ 0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75,
+ 0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87,
+ 0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6
+ );
+
+ /**
+ * Test for engine validity
+ *
+ * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+ *
+ * @see \phpseclib\Crypt\Base::__construct()
+ * @param int $engine
+ * @access public
+ * @return bool
+ */
+ function isValidEngine($engine)
+ {
+ switch ($engine) {
+ case self::ENGINE_OPENSSL:
+ if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) {
+ return false;
+ }
+ $this->cipher_name_openssl_ecb = 'rc2-ecb';
+ $this->cipher_name_openssl = 'rc2-' . $this->_openssl_translate_mode();
+ }
+
+ return parent::isValidEngine($engine);
+ }
+
+ /**
+ * Sets the key length.
+ *
+ * Valid key lengths are 8 to 1024.
+ * Calling this function after setting the key has no effect until the next
+ * \phpseclib\Crypt\RC2::setKey() call.
+ *
+ * @access public
+ * @param int $length in bits
+ */
+ function setKeyLength($length)
+ {
+ if ($length < 8) {
+ $this->default_key_length = 1;
+ } elseif ($length > 1024) {
+ $this->default_key_length = 128;
+ } else {
+ $this->default_key_length = $length;
+ }
+ $this->current_key_length = $this->default_key_length;
+
+ parent::setKeyLength($length);
+ }
+
+ /**
+ * Returns the current key length
+ *
+ * @access public
+ * @return int
+ */
+ function getKeyLength()
+ {
+ return $this->current_key_length;
+ }
+
+ /**
+ * Sets the key.
+ *
+ * Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg.
+ * strlen($key) <= 128), however, we only use the first 128 bytes if $key
+ * has more then 128 bytes in it, and set $key to a single null byte if
+ * it is empty.
+ *
+ * If the key is not explicitly set, it'll be assumed to be a single
+ * null byte.
+ *
+ * @see \phpseclib\Crypt\Base::setKey()
+ * @access public
+ * @param string $key
+ * @param int $t1 optional Effective key length in bits.
+ */
+ function setKey($key, $t1 = 0)
+ {
+ $this->orig_key = $key;
+
+ if ($t1 <= 0) {
+ $t1 = $this->default_key_length;
+ } elseif ($t1 > 1024) {
+ $t1 = 1024;
+ }
+ $this->current_key_length = $t1;
+ // Key byte count should be 1..128.
+ $key = strlen($key) ? substr($key, 0, 128) : "\x00";
+ $t = strlen($key);
+
+ // The mcrypt RC2 implementation only supports effective key length
+ // of 1024 bits. It is however possible to handle effective key
+ // lengths in range 1..1024 by expanding the key and applying
+ // inverse pitable mapping to the first byte before submitting it
+ // to mcrypt.
+
+ // Key expansion.
+ $l = array_values(unpack('C*', $key));
+ $t8 = ($t1 + 7) >> 3;
+ $tm = 0xFF >> (8 * $t8 - $t1);
+
+ // Expand key.
+ $pitable = $this->pitable;
+ for ($i = $t; $i < 128; $i++) {
+ $l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]];
+ }
+ $i = 128 - $t8;
+ $l[$i] = $pitable[$l[$i] & $tm];
+ while ($i--) {
+ $l[$i] = $pitable[$l[$i + 1] ^ $l[$i + $t8]];
+ }
+
+ // Prepare the key for mcrypt.
+ $l[0] = $this->invpitable[$l[0]];
+ array_unshift($l, 'C*');
+
+ parent::setKey(call_user_func_array('pack', $l));
+ }
+
+ /**
+ * Encrypts a message.
+ *
+ * Mostly a wrapper for \phpseclib\Crypt\Base::encrypt, with some additional OpenSSL handling code
+ *
+ * @see self::decrypt()
+ * @access public
+ * @param string $plaintext
+ * @return string $ciphertext
+ */
+ function encrypt($plaintext)
+ {
+ if ($this->engine == self::ENGINE_OPENSSL) {
+ $temp = $this->key;
+ $this->key = $this->orig_key;
+ $result = parent::encrypt($plaintext);
+ $this->key = $temp;
+ return $result;
+ }
+
+ return parent::encrypt($plaintext);
+ }
+
+ /**
+ * Decrypts a message.
+ *
+ * Mostly a wrapper for \phpseclib\Crypt\Base::decrypt, with some additional OpenSSL handling code
+ *
+ * @see self::encrypt()
+ * @access public
+ * @param string $ciphertext
+ * @return string $plaintext
+ */
+ function decrypt($ciphertext)
+ {
+ if ($this->engine == self::ENGINE_OPENSSL) {
+ $temp = $this->key;
+ $this->key = $this->orig_key;
+ $result = parent::decrypt($ciphertext);
+ $this->key = $temp;
+ return $result;
+ }
+
+ return parent::decrypt($ciphertext);
+ }
+
+ /**
+ * Encrypts a block
+ *
+ * @see \phpseclib\Crypt\Base::_encryptBlock()
+ * @see \phpseclib\Crypt\Base::encrypt()
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ function _encryptBlock($in)
+ {
+ list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
+ $keys = $this->keys;
+ $limit = 20;
+ $actions = array($limit => 44, 44 => 64);
+ $j = 0;
+
+ for (;;) {
+ // Mixing round.
+ $r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
+ $r0 |= $r0 >> 16;
+ $r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
+ $r1 |= $r1 >> 16;
+ $r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
+ $r2 |= $r2 >> 16;
+ $r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
+ $r3 |= $r3 >> 16;
+
+ if ($j === $limit) {
+ if ($limit === 64) {
+ break;
+ }
+
+ // Mashing round.
+ $r0 += $keys[$r3 & 0x3F];
+ $r1 += $keys[$r0 & 0x3F];
+ $r2 += $keys[$r1 & 0x3F];
+ $r3 += $keys[$r2 & 0x3F];
+ $limit = $actions[$limit];
+ }
+ }
+
+ return pack('vvvv', $r0, $r1, $r2, $r3);
+ }
+
+ /**
+ * Decrypts a block
+ *
+ * @see \phpseclib\Crypt\Base::_decryptBlock()
+ * @see \phpseclib\Crypt\Base::decrypt()
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ function _decryptBlock($in)
+ {
+ list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in));
+ $keys = $this->keys;
+ $limit = 44;
+ $actions = array($limit => 20, 20 => 0);
+ $j = 64;
+
+ for (;;) {
+ // R-mixing round.
+ $r3 = ($r3 | ($r3 << 16)) >> 5;
+ $r3 = ($r3 - $keys[--$j] - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
+ $r2 = ($r2 | ($r2 << 16)) >> 3;
+ $r2 = ($r2 - $keys[--$j] - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
+ $r1 = ($r1 | ($r1 << 16)) >> 2;
+ $r1 = ($r1 - $keys[--$j] - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
+ $r0 = ($r0 | ($r0 << 16)) >> 1;
+ $r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;
+
+ if ($j === $limit) {
+ if ($limit === 0) {
+ break;
+ }
+
+ // R-mashing round.
+ $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
+ $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
+ $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
+ $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;
+ $limit = $actions[$limit];
+ }
+ }
+
+ return pack('vvvv', $r0, $r1, $r2, $r3);
+ }
+
+ /**
+ * Setup the \phpseclib\Crypt\Base::ENGINE_MCRYPT $engine
+ *
+ * @see \phpseclib\Crypt\Base::_setupMcrypt()
+ * @access private
+ */
+ function _setupMcrypt()
+ {
+ if (!isset($this->key)) {
+ $this->setKey('');
+ }
+
+ parent::_setupMcrypt();
+ }
+
+ /**
+ * Creates the key schedule
+ *
+ * @see \phpseclib\Crypt\Base::_setupKey()
+ * @access private
+ */
+ function _setupKey()
+ {
+ if (!isset($this->key)) {
+ $this->setKey('');
+ }
+
+ // Key has already been expanded in \phpseclib\Crypt\RC2::setKey():
+ // Only the first value must be altered.
+ $l = unpack('Ca/Cb/v*', $this->key);
+ array_unshift($l, $this->pitable[$l['a']] | ($l['b'] << 8));
+ unset($l['a']);
+ unset($l['b']);
+ $this->keys = $l;
+ }
+
+ /**
+ * Setup the performance-optimized function for de/encrypt()
+ *
+ * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
+ * @access private
+ */
+ function _setupInlineCrypt()
+ {
+ $lambda_functions =& self::_getLambdaFunctions();
+
+ // The first 10 generated $lambda_functions will use the $keys hardcoded as integers
+ // for the mixing rounds, for better inline crypt performance [~20% faster].
+ // But for memory reason we have to limit those ultra-optimized $lambda_functions to an amount of 10.
+ // (Currently, for Crypt_RC2, one generated $lambda_function cost on php5.5@32bit ~60kb unfreeable mem and ~100kb on php5.5@64bit)
+ $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
+
+ // Generation of a unique hash for our generated code
+ $code_hash = "Crypt_RC2, {$this->mode}";
+ if ($gen_hi_opt_code) {
+ $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+ }
+
+ // Is there a re-usable $lambda_functions in there?
+ // If not, we have to create it.
+ if (!isset($lambda_functions[$code_hash])) {
+ // Init code for both, encrypt and decrypt.
+ $init_crypt = '$keys = $self->keys;';
+
+ switch (true) {
+ case $gen_hi_opt_code:
+ $keys = $this->keys;
+ default:
+ $keys = array();
+ foreach ($this->keys as $k => $v) {
+ $keys[$k] = '$keys[' . $k . ']';
+ }
+ }
+
+ // $in is the current 8 bytes block which has to be en/decrypt
+ $encrypt_block = $decrypt_block = '
+ $in = unpack("v4", $in);
+ $r0 = $in[1];
+ $r1 = $in[2];
+ $r2 = $in[3];
+ $r3 = $in[4];
+ ';
+
+ // Create code for encryption.
+ $limit = 20;
+ $actions = array($limit => 44, 44 => 64);
+ $j = 0;
+
+ for (;;) {
+ // Mixing round.
+ $encrypt_block .= '
+ $r0 = (($r0 + ' . $keys[$j++] . ' +
+ ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1;
+ $r0 |= $r0 >> 16;
+ $r1 = (($r1 + ' . $keys[$j++] . ' +
+ ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2;
+ $r1 |= $r1 >> 16;
+ $r2 = (($r2 + ' . $keys[$j++] . ' +
+ ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3;
+ $r2 |= $r2 >> 16;
+ $r3 = (($r3 + ' . $keys[$j++] . ' +
+ ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5;
+ $r3 |= $r3 >> 16;';
+
+ if ($j === $limit) {
+ if ($limit === 64) {
+ break;
+ }
+
+ // Mashing round.
+ $encrypt_block .= '
+ $r0 += $keys[$r3 & 0x3F];
+ $r1 += $keys[$r0 & 0x3F];
+ $r2 += $keys[$r1 & 0x3F];
+ $r3 += $keys[$r2 & 0x3F];';
+ $limit = $actions[$limit];
+ }
+ }
+
+ $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
+
+ // Create code for decryption.
+ $limit = 44;
+ $actions = array($limit => 20, 20 => 0);
+ $j = 64;
+
+ for (;;) {
+ // R-mixing round.
+ $decrypt_block .= '
+ $r3 = ($r3 | ($r3 << 16)) >> 5;
+ $r3 = ($r3 - ' . $keys[--$j] . ' -
+ ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF;
+ $r2 = ($r2 | ($r2 << 16)) >> 3;
+ $r2 = ($r2 - ' . $keys[--$j] . ' -
+ ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF;
+ $r1 = ($r1 | ($r1 << 16)) >> 2;
+ $r1 = ($r1 - ' . $keys[--$j] . ' -
+ ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF;
+ $r0 = ($r0 | ($r0 << 16)) >> 1;
+ $r0 = ($r0 - ' . $keys[--$j] . ' -
+ ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;';
+
+ if ($j === $limit) {
+ if ($limit === 0) {
+ break;
+ }
+
+ // R-mashing round.
+ $decrypt_block .= '
+ $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF;
+ $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF;
+ $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF;
+ $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;';
+ $limit = $actions[$limit];
+ }
+ }
+
+ $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);';
+
+ // Creates the inline-crypt function
+ $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
+ array(
+ 'init_crypt' => $init_crypt,
+ 'encrypt_block' => $encrypt_block,
+ 'decrypt_block' => $decrypt_block
+ )
+ );
+ }
+
+ // Set the inline-crypt function as callback in: $this->inline_crypt
+ $this->inline_crypt = $lambda_functions[$code_hash];
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php
new file mode 100644
index 0000000..25e4ff8
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php
@@ -0,0 +1,342 @@
+<?php
+
+/**
+ * Pure-PHP implementation of RC4.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * Useful resources are as follows:
+ *
+ * - {@link http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt ARCFOUR Algorithm}
+ * - {@link http://en.wikipedia.org/wiki/RC4 - Wikipedia: RC4}
+ *
+ * RC4 is also known as ARCFOUR or ARC4. The reason is elaborated upon at Wikipedia. This class is named RC4 and not
+ * ARCFOUR or ARC4 because RC4 is how it is referred to in the SSH1 specification.
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $rc4 = new \phpseclib\Crypt\RC4();
+ *
+ * $rc4->setKey('abcdefgh');
+ *
+ * $size = 10 * 1024;
+ * $plaintext = '';
+ * for ($i = 0; $i < $size; $i++) {
+ * $plaintext.= 'a';
+ * }
+ *
+ * echo $rc4->decrypt($rc4->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package RC4
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of RC4.
+ *
+ * @package RC4
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class RC4 extends Base
+{
+ /**#@+
+ * @access private
+ * @see \phpseclib\Crypt\RC4::_crypt()
+ */
+ const ENCRYPT = 0;
+ const DECRYPT = 1;
+ /**#@-*/
+
+ /**
+ * Block Length of the cipher
+ *
+ * RC4 is a stream cipher
+ * so we the block_size to 0
+ *
+ * @see \phpseclib\Crypt\Base::block_size
+ * @var int
+ * @access private
+ */
+ var $block_size = 0;
+
+ /**
+ * Key Length (in bytes)
+ *
+ * @see \phpseclib\Crypt\RC4::setKeyLength()
+ * @var int
+ * @access private
+ */
+ var $key_length = 128; // = 1024 bits
+
+ /**
+ * The mcrypt specific name of the cipher
+ *
+ * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+ * @var string
+ * @access private
+ */
+ var $cipher_name_mcrypt = 'arcfour';
+
+ /**
+ * Holds whether performance-optimized $inline_crypt() can/should be used.
+ *
+ * @see \phpseclib\Crypt\Base::inline_crypt
+ * @var mixed
+ * @access private
+ */
+ var $use_inline_crypt = false; // currently not available
+
+ /**
+ * The Key
+ *
+ * @see self::setKey()
+ * @var string
+ * @access private
+ */
+ var $key;
+
+ /**
+ * The Key Stream for decryption and encryption
+ *
+ * @see self::setKey()
+ * @var array
+ * @access private
+ */
+ var $stream;
+
+ /**
+ * Default Constructor.
+ *
+ * Determines whether or not the mcrypt extension should be used.
+ *
+ * @see \phpseclib\Crypt\Base::__construct()
+ * @return \phpseclib\Crypt\RC4
+ * @access public
+ */
+ function __construct()
+ {
+ parent::__construct(Base::MODE_STREAM);
+ }
+
+ /**
+ * Test for engine validity
+ *
+ * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+ *
+ * @see \phpseclib\Crypt\Base::__construct()
+ * @param int $engine
+ * @access public
+ * @return bool
+ */
+ function isValidEngine($engine)
+ {
+ if ($engine == Base::ENGINE_OPENSSL) {
+ if (version_compare(PHP_VERSION, '5.3.7') >= 0) {
+ $this->cipher_name_openssl = 'rc4-40';
+ } else {
+ switch (strlen($this->key)) {
+ case 5:
+ $this->cipher_name_openssl = 'rc4-40';
+ break;
+ case 8:
+ $this->cipher_name_openssl = 'rc4-64';
+ break;
+ case 16:
+ $this->cipher_name_openssl = 'rc4';
+ break;
+ default:
+ return false;
+ }
+ }
+ }
+
+ return parent::isValidEngine($engine);
+ }
+
+ /**
+ * Dummy function.
+ *
+ * Some protocols, such as WEP, prepend an "initialization vector" to the key, effectively creating a new key [1].
+ * If you need to use an initialization vector in this manner, feel free to prepend it to the key, yourself, before
+ * calling setKey().
+ *
+ * [1] WEP's initialization vectors (IV's) are used in a somewhat insecure way. Since, in that protocol,
+ * the IV's are relatively easy to predict, an attack described by
+ * {@link http://www.drizzle.com/~aboba/IEEE/rc4_ksaproc.pdf Scott Fluhrer, Itsik Mantin, and Adi Shamir}
+ * can be used to quickly guess at the rest of the key. The following links elaborate:
+ *
+ * {@link http://www.rsa.com/rsalabs/node.asp?id=2009 http://www.rsa.com/rsalabs/node.asp?id=2009}
+ * {@link http://en.wikipedia.org/wiki/Related_key_attack http://en.wikipedia.org/wiki/Related_key_attack}
+ *
+ * @param string $iv
+ * @see self::setKey()
+ * @access public
+ */
+ function setIV($iv)
+ {
+ }
+
+ /**
+ * Sets the key length
+ *
+ * Keys can be between 1 and 256 bytes long.
+ *
+ * @access public
+ * @param int $length
+ */
+ function setKeyLength($length)
+ {
+ if ($length < 8) {
+ $this->key_length = 1;
+ } elseif ($length > 2048) {
+ $this->key_length = 256;
+ } else {
+ $this->key_length = $length >> 3;
+ }
+
+ parent::setKeyLength($length);
+ }
+
+ /**
+ * Encrypts a message.
+ *
+ * @see \phpseclib\Crypt\Base::decrypt()
+ * @see self::_crypt()
+ * @access public
+ * @param string $plaintext
+ * @return string $ciphertext
+ */
+ function encrypt($plaintext)
+ {
+ if ($this->engine != Base::ENGINE_INTERNAL) {
+ return parent::encrypt($plaintext);
+ }
+ return $this->_crypt($plaintext, self::ENCRYPT);
+ }
+
+ /**
+ * Decrypts a message.
+ *
+ * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)).
+ * At least if the continuous buffer is disabled.
+ *
+ * @see \phpseclib\Crypt\Base::encrypt()
+ * @see self::_crypt()
+ * @access public
+ * @param string $ciphertext
+ * @return string $plaintext
+ */
+ function decrypt($ciphertext)
+ {
+ if ($this->engine != Base::ENGINE_INTERNAL) {
+ return parent::decrypt($ciphertext);
+ }
+ return $this->_crypt($ciphertext, self::DECRYPT);
+ }
+
+ /**
+ * Encrypts a block
+ *
+ * @access private
+ * @param string $in
+ */
+ function _encryptBlock($in)
+ {
+ // RC4 does not utilize this method
+ }
+
+ /**
+ * Decrypts a block
+ *
+ * @access private
+ * @param string $in
+ */
+ function _decryptBlock($in)
+ {
+ // RC4 does not utilize this method
+ }
+
+ /**
+ * Setup the key (expansion)
+ *
+ * @see \phpseclib\Crypt\Base::_setupKey()
+ * @access private
+ */
+ function _setupKey()
+ {
+ $key = $this->key;
+ $keyLength = strlen($key);
+ $keyStream = range(0, 255);
+ $j = 0;
+ for ($i = 0; $i < 256; $i++) {
+ $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255;
+ $temp = $keyStream[$i];
+ $keyStream[$i] = $keyStream[$j];
+ $keyStream[$j] = $temp;
+ }
+
+ $this->stream = array();
+ $this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = array(
+ 0, // index $i
+ 0, // index $j
+ $keyStream
+ );
+ }
+
+ /**
+ * Encrypts or decrypts a message.
+ *
+ * @see self::encrypt()
+ * @see self::decrypt()
+ * @access private
+ * @param string $text
+ * @param int $mode
+ * @return string $text
+ */
+ function _crypt($text, $mode)
+ {
+ if ($this->changed) {
+ $this->_setup();
+ $this->changed = false;
+ }
+
+ $stream = &$this->stream[$mode];
+ if ($this->continuousBuffer) {
+ $i = &$stream[0];
+ $j = &$stream[1];
+ $keyStream = &$stream[2];
+ } else {
+ $i = $stream[0];
+ $j = $stream[1];
+ $keyStream = $stream[2];
+ }
+
+ $len = strlen($text);
+ for ($k = 0; $k < $len; ++$k) {
+ $i = ($i + 1) & 255;
+ $ksi = $keyStream[$i];
+ $j = ($j + $ksi) & 255;
+ $ksj = $keyStream[$j];
+
+ $keyStream[$i] = $ksj;
+ $keyStream[$j] = $ksi;
+ $text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]);
+ }
+
+ return $text;
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
new file mode 100644
index 0000000..72be6ee
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php
@@ -0,0 +1,3201 @@
+<?php
+
+/**
+ * Pure-PHP PKCS#1 (v2.1) compliant implementation of RSA.
+ *
+ * PHP version 5
+ *
+ * Here's an example of how to encrypt and decrypt text with this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $rsa = new \phpseclib\Crypt\RSA();
+ * extract($rsa->createKey());
+ *
+ * $plaintext = 'terrafrost';
+ *
+ * $rsa->loadKey($privatekey);
+ * $ciphertext = $rsa->encrypt($plaintext);
+ *
+ * $rsa->loadKey($publickey);
+ * echo $rsa->decrypt($ciphertext);
+ * ?>
+ * </code>
+ *
+ * Here's an example of how to create signatures and verify signatures with this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $rsa = new \phpseclib\Crypt\RSA();
+ * extract($rsa->createKey());
+ *
+ * $plaintext = 'terrafrost';
+ *
+ * $rsa->loadKey($privatekey);
+ * $signature = $rsa->sign($plaintext);
+ *
+ * $rsa->loadKey($publickey);
+ * echo $rsa->verify($plaintext, $signature) ? 'verified' : 'unverified';
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package RSA
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2009 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+use phpseclib\Math\BigInteger;
+
+/**
+ * Pure-PHP PKCS#1 compliant implementation of RSA.
+ *
+ * @package RSA
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class RSA
+{
+ /**#@+
+ * @access public
+ * @see self::encrypt()
+ * @see self::decrypt()
+ */
+ /**
+ * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding}
+ * (OAEP) for encryption / decryption.
+ *
+ * Uses sha1 by default.
+ *
+ * @see self::setHash()
+ * @see self::setMGFHash()
+ */
+ const ENCRYPTION_OAEP = 1;
+ /**
+ * Use PKCS#1 padding.
+ *
+ * Although self::ENCRYPTION_OAEP offers more security, including PKCS#1 padding is necessary for purposes of backwards
+ * compatibility with protocols (like SSH-1) written before OAEP's introduction.
+ */
+ const ENCRYPTION_PKCS1 = 2;
+ /**
+ * Do not use any padding
+ *
+ * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy
+ * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc.
+ */
+ const ENCRYPTION_NONE = 3;
+ /**#@-*/
+
+ /**#@+
+ * @access public
+ * @see self::sign()
+ * @see self::verify()
+ * @see self::setHash()
+ */
+ /**
+ * Use the Probabilistic Signature Scheme for signing
+ *
+ * Uses sha1 by default.
+ *
+ * @see self::setSaltLength()
+ * @see self::setMGFHash()
+ */
+ const SIGNATURE_PSS = 1;
+ /**
+ * Use the PKCS#1 scheme by default.
+ *
+ * Although self::SIGNATURE_PSS offers more security, including PKCS#1 signing is necessary for purposes of backwards
+ * compatibility with protocols (like SSH-2) written before PSS's introduction.
+ */
+ const SIGNATURE_PKCS1 = 2;
+ /**#@-*/
+
+ /**#@+
+ * @access private
+ * @see \phpseclib\Crypt\RSA::createKey()
+ */
+ /**
+ * ASN1 Integer
+ */
+ const ASN1_INTEGER = 2;
+ /**
+ * ASN1 Bit String
+ */
+ const ASN1_BITSTRING = 3;
+ /**
+ * ASN1 Octet String
+ */
+ const ASN1_OCTETSTRING = 4;
+ /**
+ * ASN1 Object Identifier
+ */
+ const ASN1_OBJECT = 6;
+ /**
+ * ASN1 Sequence (with the constucted bit set)
+ */
+ const ASN1_SEQUENCE = 48;
+ /**#@-*/
+
+ /**#@+
+ * @access private
+ * @see \phpseclib\Crypt\RSA::__construct()
+ */
+ /**
+ * To use the pure-PHP implementation
+ */
+ const MODE_INTERNAL = 1;
+ /**
+ * To use the OpenSSL library
+ *
+ * (if enabled; otherwise, the internal implementation will be used)
+ */
+ const MODE_OPENSSL = 2;
+ /**#@-*/
+
+ /**#@+
+ * @access public
+ * @see \phpseclib\Crypt\RSA::createKey()
+ * @see \phpseclib\Crypt\RSA::setPrivateKeyFormat()
+ */
+ /**
+ * PKCS#1 formatted private key
+ *
+ * Used by OpenSSH
+ */
+ const PRIVATE_FORMAT_PKCS1 = 0;
+ /**
+ * PuTTY formatted private key
+ */
+ const PRIVATE_FORMAT_PUTTY = 1;
+ /**
+ * XML formatted private key
+ */
+ const PRIVATE_FORMAT_XML = 2;
+ /**
+ * PKCS#8 formatted private key
+ */
+ const PRIVATE_FORMAT_PKCS8 = 8;
+ /**
+ * OpenSSH formatted private key
+ */
+ const PRIVATE_FORMAT_OPENSSH = 9;
+ /**#@-*/
+
+ /**#@+
+ * @access public
+ * @see \phpseclib\Crypt\RSA::createKey()
+ * @see \phpseclib\Crypt\RSA::setPublicKeyFormat()
+ */
+ /**
+ * Raw public key
+ *
+ * An array containing two \phpseclib\Math\BigInteger objects.
+ *
+ * The exponent can be indexed with any of the following:
+ *
+ * 0, e, exponent, publicExponent
+ *
+ * The modulus can be indexed with any of the following:
+ *
+ * 1, n, modulo, modulus
+ */
+ const PUBLIC_FORMAT_RAW = 3;
+ /**
+ * PKCS#1 formatted public key (raw)
+ *
+ * Used by File/X509.php
+ *
+ * Has the following header:
+ *
+ * -----BEGIN RSA PUBLIC KEY-----
+ *
+ * Analogous to ssh-keygen's pem format (as specified by -m)
+ */
+ const PUBLIC_FORMAT_PKCS1 = 4;
+ const PUBLIC_FORMAT_PKCS1_RAW = 4;
+ /**
+ * XML formatted public key
+ */
+ const PUBLIC_FORMAT_XML = 5;
+ /**
+ * OpenSSH formatted public key
+ *
+ * Place in $HOME/.ssh/authorized_keys
+ */
+ const PUBLIC_FORMAT_OPENSSH = 6;
+ /**
+ * PKCS#1 formatted public key (encapsulated)
+ *
+ * Used by PHP's openssl_public_encrypt() and openssl's rsautl (when -pubin is set)
+ *
+ * Has the following header:
+ *
+ * -----BEGIN PUBLIC KEY-----
+ *
+ * Analogous to ssh-keygen's pkcs8 format (as specified by -m). Although PKCS8
+ * is specific to private keys it's basically creating a DER-encoded wrapper
+ * for keys. This just extends that same concept to public keys (much like ssh-keygen)
+ */
+ const PUBLIC_FORMAT_PKCS8 = 7;
+ /**#@-*/
+
+ /**
+ * Precomputed Zero
+ *
+ * @var \phpseclib\Math\BigInteger
+ * @access private
+ */
+ var $zero;
+
+ /**
+ * Precomputed One
+ *
+ * @var \phpseclib\Math\BigInteger
+ * @access private
+ */
+ var $one;
+
+ /**
+ * Private Key Format
+ *
+ * @var int
+ * @access private
+ */
+ var $privateKeyFormat = self::PRIVATE_FORMAT_PKCS1;
+
+ /**
+ * Public Key Format
+ *
+ * @var int
+ * @access public
+ */
+ var $publicKeyFormat = self::PUBLIC_FORMAT_PKCS8;
+
+ /**
+ * Modulus (ie. n)
+ *
+ * @var \phpseclib\Math\BigInteger
+ * @access private
+ */
+ var $modulus;
+
+ /**
+ * Modulus length
+ *
+ * @var \phpseclib\Math\BigInteger
+ * @access private
+ */
+ var $k;
+
+ /**
+ * Exponent (ie. e or d)
+ *
+ * @var \phpseclib\Math\BigInteger
+ * @access private
+ */
+ var $exponent;
+
+ /**
+ * Primes for Chinese Remainder Theorem (ie. p and q)
+ *
+ * @var array
+ * @access private
+ */
+ var $primes;
+
+ /**
+ * Exponents for Chinese Remainder Theorem (ie. dP and dQ)
+ *
+ * @var array
+ * @access private
+ */
+ var $exponents;
+
+ /**
+ * Coefficients for Chinese Remainder Theorem (ie. qInv)
+ *
+ * @var array
+ * @access private
+ */
+ var $coefficients;
+
+ /**
+ * Hash name
+ *
+ * @var string
+ * @access private
+ */
+ var $hashName;
+
+ /**
+ * Hash function
+ *
+ * @var \phpseclib\Crypt\Hash
+ * @access private
+ */
+ var $hash;
+
+ /**
+ * Length of hash function output
+ *
+ * @var int
+ * @access private
+ */
+ var $hLen;
+
+ /**
+ * Length of salt
+ *
+ * @var int
+ * @access private
+ */
+ var $sLen;
+
+ /**
+ * Hash function for the Mask Generation Function
+ *
+ * @var \phpseclib\Crypt\Hash
+ * @access private
+ */
+ var $mgfHash;
+
+ /**
+ * Length of MGF hash function output
+ *
+ * @var int
+ * @access private
+ */
+ var $mgfHLen;
+
+ /**
+ * Encryption mode
+ *
+ * @var int
+ * @access private
+ */
+ var $encryptionMode = self::ENCRYPTION_OAEP;
+
+ /**
+ * Signature mode
+ *
+ * @var int
+ * @access private
+ */
+ var $signatureMode = self::SIGNATURE_PSS;
+
+ /**
+ * Public Exponent
+ *
+ * @var mixed
+ * @access private
+ */
+ var $publicExponent = false;
+
+ /**
+ * Password
+ *
+ * @var string
+ * @access private
+ */
+ var $password = false;
+
+ /**
+ * Components
+ *
+ * For use with parsing XML formatted keys. PHP's XML Parser functions use utilized - instead of PHP's DOM functions -
+ * because PHP's XML Parser functions work on PHP4 whereas PHP's DOM functions - although surperior - don't.
+ *
+ * @see self::_start_element_handler()
+ * @var array
+ * @access private
+ */
+ var $components = array();
+
+ /**
+ * Current String
+ *
+ * For use with parsing XML formatted keys.
+ *
+ * @see self::_character_handler()
+ * @see self::_stop_element_handler()
+ * @var mixed
+ * @access private
+ */
+ var $current;
+
+ /**
+ * OpenSSL configuration file name.
+ *
+ * Set to null to use system configuration file.
+ * @see self::createKey()
+ * @var mixed
+ * @Access public
+ */
+ var $configFile;
+
+ /**
+ * Public key comment field.
+ *
+ * @var string
+ * @access private
+ */
+ var $comment = 'phpseclib-generated-key';
+
+ /**
+ * The constructor
+ *
+ * If you want to make use of the openssl extension, you'll need to set the mode manually, yourself. The reason
+ * \phpseclib\Crypt\RSA doesn't do it is because OpenSSL doesn't fail gracefully. openssl_pkey_new(), in particular, requires
+ * openssl.cnf be present somewhere and, unfortunately, the only real way to find out is too late.
+ *
+ * @return \phpseclib\Crypt\RSA
+ * @access public
+ */
+ function __construct()
+ {
+ $this->configFile = dirname(__FILE__) . '/../openssl.cnf';
+
+ if (!defined('CRYPT_RSA_MODE')) {
+ switch (true) {
+ // Math/BigInteger's openssl requirements are a little less stringent than Crypt/RSA's. in particular,
+ // Math/BigInteger doesn't require an openssl.cfg file whereas Crypt/RSA does. so if Math/BigInteger
+ // can't use OpenSSL it can be pretty trivially assumed, then, that Crypt/RSA can't either.
+ case defined('MATH_BIGINTEGER_OPENSSL_DISABLE'):
+ define('CRYPT_RSA_MODE', self::MODE_INTERNAL);
+ break;
+ case extension_loaded('openssl') && file_exists($this->configFile):
+ // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
+ $versions = array();
+
+ // avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems)
+ if (strpos(ini_get('disable_functions'), 'phpinfo') === false) {
+ ob_start();
+ @phpinfo();
+ $content = ob_get_contents();
+ ob_end_clean();
+
+ preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
+
+ if (!empty($matches[1])) {
+ for ($i = 0; $i < count($matches[1]); $i++) {
+ $fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
+
+ // Remove letter part in OpenSSL version
+ if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
+ $versions[$matches[1][$i]] = $fullVersion;
+ } else {
+ $versions[$matches[1][$i]] = $m[0];
+ }
+ }
+ }
+ }
+
+ // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+
+ switch (true) {
+ case !isset($versions['Header']):
+ case !isset($versions['Library']):
+ case $versions['Header'] == $versions['Library']:
+ case version_compare($versions['Header'], '1.0.0') >= 0 && version_compare($versions['Library'], '1.0.0') >= 0:
+ define('CRYPT_RSA_MODE', self::MODE_OPENSSL);
+ break;
+ default:
+ define('CRYPT_RSA_MODE', self::MODE_INTERNAL);
+ define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
+ }
+ break;
+ default:
+ define('CRYPT_RSA_MODE', self::MODE_INTERNAL);
+ }
+ }
+
+ $this->zero = new BigInteger();
+ $this->one = new BigInteger(1);
+
+ $this->hash = new Hash('sha1');
+ $this->hLen = $this->hash->getLength();
+ $this->hashName = 'sha1';
+ $this->mgfHash = new Hash('sha1');
+ $this->mgfHLen = $this->mgfHash->getLength();
+ }
+
+ /**
+ * Create public / private key pair
+ *
+ * Returns an array with the following three elements:
+ * - 'privatekey': The private key.
+ * - 'publickey': The public key.
+ * - 'partialkey': A partially computed key (if the execution time exceeded $timeout).
+ * Will need to be passed back to \phpseclib\Crypt\RSA::createKey() as the third parameter for further processing.
+ *
+ * @access public
+ * @param int $bits
+ * @param int $timeout
+ * @param array $p
+ */
+ function createKey($bits = 1024, $timeout = false, $partial = array())
+ {
+ if (!defined('CRYPT_RSA_EXPONENT')) {
+ // http://en.wikipedia.org/wiki/65537_%28number%29
+ define('CRYPT_RSA_EXPONENT', '65537');
+ }
+ // per <http://cseweb.ucsd.edu/~hovav/dist/survey.pdf#page=5>, this number ought not result in primes smaller
+ // than 256 bits. as a consequence if the key you're trying to create is 1024 bits and you've set CRYPT_RSA_SMALLEST_PRIME
+ // to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). at least if
+ // CRYPT_RSA_MODE is set to self::MODE_INTERNAL. if CRYPT_RSA_MODE is set to self::MODE_OPENSSL then
+ // CRYPT_RSA_SMALLEST_PRIME is ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key
+ // generation when there's a chance neither gmp nor OpenSSL are installed)
+ if (!defined('CRYPT_RSA_SMALLEST_PRIME')) {
+ define('CRYPT_RSA_SMALLEST_PRIME', 4096);
+ }
+
+ // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum
+ if (CRYPT_RSA_MODE == self::MODE_OPENSSL && $bits >= 384 && CRYPT_RSA_EXPONENT == 65537) {
+ $config = array();
+ if (isset($this->configFile)) {
+ $config['config'] = $this->configFile;
+ }
+ $rsa = openssl_pkey_new(array('private_key_bits' => $bits) + $config);
+ openssl_pkey_export($rsa, $privatekey, null, $config);
+ $publickey = openssl_pkey_get_details($rsa);
+ $publickey = $publickey['key'];
+
+ $privatekey = call_user_func_array(array($this, '_convertPrivateKey'), array_values($this->_parseKey($privatekey, self::PRIVATE_FORMAT_PKCS1)));
+ $publickey = call_user_func_array(array($this, '_convertPublicKey'), array_values($this->_parseKey($publickey, self::PUBLIC_FORMAT_PKCS1)));
+
+ // clear the buffer of error strings stemming from a minimalistic openssl.cnf
+ while (openssl_error_string() !== false) {
+ }
+
+ return array(
+ 'privatekey' => $privatekey,
+ 'publickey' => $publickey,
+ 'partialkey' => false
+ );
+ }
+
+ static $e;
+ if (!isset($e)) {
+ $e = new BigInteger(CRYPT_RSA_EXPONENT);
+ }
+
+ extract($this->_generateMinMax($bits));
+ $absoluteMin = $min;
+ $temp = $bits >> 1; // divide by two to see how many bits P and Q would be
+ if ($temp > CRYPT_RSA_SMALLEST_PRIME) {
+ $num_primes = floor($bits / CRYPT_RSA_SMALLEST_PRIME);
+ $temp = CRYPT_RSA_SMALLEST_PRIME;
+ } else {
+ $num_primes = 2;
+ }
+ extract($this->_generateMinMax($temp + $bits % $temp));
+ $finalMax = $max;
+ extract($this->_generateMinMax($temp));
+
+ $generator = new BigInteger();
+
+ $n = $this->one->copy();
+ if (!empty($partial)) {
+ extract(unserialize($partial));
+ } else {
+ $exponents = $coefficients = $primes = array();
+ $lcm = array(
+ 'top' => $this->one->copy(),
+ 'bottom' => false
+ );
+ }
+
+ $start = time();
+ $i0 = count($primes) + 1;
+
+ do {
+ for ($i = $i0; $i <= $num_primes; $i++) {
+ if ($timeout !== false) {
+ $timeout-= time() - $start;
+ $start = time();
+ if ($timeout <= 0) {
+ return array(
+ 'privatekey' => '',
+ 'publickey' => '',
+ 'partialkey' => serialize(array(
+ 'primes' => $primes,
+ 'coefficients' => $coefficients,
+ 'lcm' => $lcm,
+ 'exponents' => $exponents
+ ))
+ );
+ }
+ }
+
+ if ($i == $num_primes) {
+ list($min, $temp) = $absoluteMin->divide($n);
+ if (!$temp->equals($this->zero)) {
+ $min = $min->add($this->one); // ie. ceil()
+ }
+ $primes[$i] = $generator->randomPrime($min, $finalMax, $timeout);
+ } else {
+ $primes[$i] = $generator->randomPrime($min, $max, $timeout);
+ }
+
+ if ($primes[$i] === false) { // if we've reached the timeout
+ if (count($primes) > 1) {
+ $partialkey = '';
+ } else {
+ array_pop($primes);
+ $partialkey = serialize(array(
+ 'primes' => $primes,
+ 'coefficients' => $coefficients,
+ 'lcm' => $lcm,
+ 'exponents' => $exponents
+ ));
+ }
+
+ return array(
+ 'privatekey' => '',
+ 'publickey' => '',
+ 'partialkey' => $partialkey
+ );
+ }
+
+ // the first coefficient is calculated differently from the rest
+ // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1])
+ if ($i > 2) {
+ $coefficients[$i] = $n->modInverse($primes[$i]);
+ }
+
+ $n = $n->multiply($primes[$i]);
+
+ $temp = $primes[$i]->subtract($this->one);
+
+ // textbook RSA implementations use Euler's totient function instead of the least common multiple.
+ // see http://en.wikipedia.org/wiki/Euler%27s_totient_function
+ $lcm['top'] = $lcm['top']->multiply($temp);
+ $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp);
+
+ $exponents[$i] = $e->modInverse($temp);
+ }
+
+ list($temp) = $lcm['top']->divide($lcm['bottom']);
+ $gcd = $temp->gcd($e);
+ $i0 = 1;
+ } while (!$gcd->equals($this->one));
+
+ $d = $e->modInverse($temp);
+
+ $coefficients[2] = $primes[2]->modInverse($primes[1]);
+
+ // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.2>:
+ // RSAPrivateKey ::= SEQUENCE {
+ // version Version,
+ // modulus INTEGER, -- n
+ // publicExponent INTEGER, -- e
+ // privateExponent INTEGER, -- d
+ // prime1 INTEGER, -- p
+ // prime2 INTEGER, -- q
+ // exponent1 INTEGER, -- d mod (p-1)
+ // exponent2 INTEGER, -- d mod (q-1)
+ // coefficient INTEGER, -- (inverse of q) mod p
+ // otherPrimeInfos OtherPrimeInfos OPTIONAL
+ // }
+
+ return array(
+ 'privatekey' => $this->_convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients),
+ 'publickey' => $this->_convertPublicKey($n, $e),
+ 'partialkey' => false
+ );
+ }
+
+ /**
+ * Convert a private key to the appropriate format.
+ *
+ * @access private
+ * @see self::setPrivateKeyFormat()
+ * @param string $RSAPrivateKey
+ * @return string
+ */
+ function _convertPrivateKey($n, $e, $d, $primes, $exponents, $coefficients)
+ {
+ $signed = $this->privateKeyFormat != self::PRIVATE_FORMAT_XML;
+ $num_primes = count($primes);
+ $raw = array(
+ 'version' => $num_primes == 2 ? chr(0) : chr(1), // two-prime vs. multi
+ 'modulus' => $n->toBytes($signed),
+ 'publicExponent' => $e->toBytes($signed),
+ 'privateExponent' => $d->toBytes($signed),
+ 'prime1' => $primes[1]->toBytes($signed),
+ 'prime2' => $primes[2]->toBytes($signed),
+ 'exponent1' => $exponents[1]->toBytes($signed),
+ 'exponent2' => $exponents[2]->toBytes($signed),
+ 'coefficient' => $coefficients[2]->toBytes($signed)
+ );
+
+ // if the format in question does not support multi-prime rsa and multi-prime rsa was used,
+ // call _convertPublicKey() instead.
+ switch ($this->privateKeyFormat) {
+ case self::PRIVATE_FORMAT_XML:
+ if ($num_primes != 2) {
+ return false;
+ }
+ return "<RSAKeyValue>\r\n" .
+ ' <Modulus>' . base64_encode($raw['modulus']) . "</Modulus>\r\n" .
+ ' <Exponent>' . base64_encode($raw['publicExponent']) . "</Exponent>\r\n" .
+ ' <P>' . base64_encode($raw['prime1']) . "</P>\r\n" .
+ ' <Q>' . base64_encode($raw['prime2']) . "</Q>\r\n" .
+ ' <DP>' . base64_encode($raw['exponent1']) . "</DP>\r\n" .
+ ' <DQ>' . base64_encode($raw['exponent2']) . "</DQ>\r\n" .
+ ' <InverseQ>' . base64_encode($raw['coefficient']) . "</InverseQ>\r\n" .
+ ' <D>' . base64_encode($raw['privateExponent']) . "</D>\r\n" .
+ '</RSAKeyValue>';
+ break;
+ case self::PRIVATE_FORMAT_PUTTY:
+ if ($num_primes != 2) {
+ return false;
+ }
+ $key = "PuTTY-User-Key-File-2: ssh-rsa\r\nEncryption: ";
+ $encryption = (!empty($this->password) || is_string($this->password)) ? 'aes256-cbc' : 'none';
+ $key.= $encryption;
+ $key.= "\r\nComment: " . $this->comment . "\r\n";
+ $public = pack(
+ 'Na*Na*Na*',
+ strlen('ssh-rsa'),
+ 'ssh-rsa',
+ strlen($raw['publicExponent']),
+ $raw['publicExponent'],
+ strlen($raw['modulus']),
+ $raw['modulus']
+ );
+ $source = pack(
+ 'Na*Na*Na*Na*',
+ strlen('ssh-rsa'),
+ 'ssh-rsa',
+ strlen($encryption),
+ $encryption,
+ strlen($this->comment),
+ $this->comment,
+ strlen($public),
+ $public
+ );
+ $public = base64_encode($public);
+ $key.= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n";
+ $key.= chunk_split($public, 64);
+ $private = pack(
+ 'Na*Na*Na*Na*',
+ strlen($raw['privateExponent']),
+ $raw['privateExponent'],
+ strlen($raw['prime1']),
+ $raw['prime1'],
+ strlen($raw['prime2']),
+ $raw['prime2'],
+ strlen($raw['coefficient']),
+ $raw['coefficient']
+ );
+ if (empty($this->password) && !is_string($this->password)) {
+ $source.= pack('Na*', strlen($private), $private);
+ $hashkey = 'putty-private-key-file-mac-key';
+ } else {
+ $private.= Random::string(16 - (strlen($private) & 15));
+ $source.= pack('Na*', strlen($private), $private);
+ $sequence = 0;
+ $symkey = '';
+ while (strlen($symkey) < 32) {
+ $temp = pack('Na*', $sequence++, $this->password);
+ $symkey.= pack('H*', sha1($temp));
+ }
+ $symkey = substr($symkey, 0, 32);
+ $crypto = new AES();
+
+ $crypto->setKey($symkey);
+ $crypto->disablePadding();
+ $private = $crypto->encrypt($private);
+ $hashkey = 'putty-private-key-file-mac-key' . $this->password;
+ }
+
+ $private = base64_encode($private);
+ $key.= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n";
+ $key.= chunk_split($private, 64);
+ $hash = new Hash('sha1');
+ $hash->setKey(pack('H*', sha1($hashkey)));
+ $key.= 'Private-MAC: ' . bin2hex($hash->hash($source)) . "\r\n";
+
+ return $key;
+ case self::PRIVATE_FORMAT_OPENSSH:
+ if ($num_primes != 2) {
+ return false;
+ }
+ $publicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($raw['publicExponent']), $raw['publicExponent'], strlen($raw['modulus']), $raw['modulus']);
+ $privateKey = pack(
+ 'Na*Na*Na*Na*Na*Na*Na*',
+ strlen('ssh-rsa'),
+ 'ssh-rsa',
+ strlen($raw['modulus']),
+ $raw['modulus'],
+ strlen($raw['publicExponent']),
+ $raw['publicExponent'],
+ strlen($raw['privateExponent']),
+ $raw['privateExponent'],
+ strlen($raw['coefficient']),
+ $raw['coefficient'],
+ strlen($raw['prime1']),
+ $raw['prime1'],
+ strlen($raw['prime2']),
+ $raw['prime2']
+ );
+ $checkint = Random::string(4);
+ $paddedKey = pack(
+ 'a*Na*',
+ $checkint . $checkint . $privateKey,
+ strlen($this->comment),
+ $this->comment
+ );
+ $paddingLength = (7 * strlen($paddedKey)) % 8;
+ for ($i = 1; $i <= $paddingLength; $i++) {
+ $paddedKey.= chr($i);
+ }
+ $key = pack(
+ 'Na*Na*Na*NNa*Na*',
+ strlen('none'),
+ 'none',
+ strlen('none'),
+ 'none',
+ 0,
+ '',
+ 1,
+ strlen($publicKey),
+ $publicKey,
+ strlen($paddedKey),
+ $paddedKey
+ );
+ $key = "openssh-key-v1\0$key";
+
+ return "-----BEGIN OPENSSH PRIVATE KEY-----\r\n" .
+ chunk_split(base64_encode($key), 70) .
+ "-----END OPENSSH PRIVATE KEY-----";
+ default: // eg. self::PRIVATE_FORMAT_PKCS1
+ $components = array();
+ foreach ($raw as $name => $value) {
+ $components[$name] = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($value)), $value);
+ }
+
+ $RSAPrivateKey = implode('', $components);
+
+ if ($num_primes > 2) {
+ $OtherPrimeInfos = '';
+ for ($i = 3; $i <= $num_primes; $i++) {
+ // OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
+ //
+ // OtherPrimeInfo ::= SEQUENCE {
+ // prime INTEGER, -- ri
+ // exponent INTEGER, -- di
+ // coefficient INTEGER -- ti
+ // }
+ $OtherPrimeInfo = pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($primes[$i]->toBytes(true))), $primes[$i]->toBytes(true));
+ $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($exponents[$i]->toBytes(true))), $exponents[$i]->toBytes(true));
+ $OtherPrimeInfo.= pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($coefficients[$i]->toBytes(true))), $coefficients[$i]->toBytes(true));
+ $OtherPrimeInfos.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfo)), $OtherPrimeInfo);
+ }
+ $RSAPrivateKey.= pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($OtherPrimeInfos)), $OtherPrimeInfos);
+ }
+
+ $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
+
+ if ($this->privateKeyFormat == self::PRIVATE_FORMAT_PKCS8) {
+ $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
+ $RSAPrivateKey = pack(
+ 'Ca*a*Ca*a*',
+ self::ASN1_INTEGER,
+ "\01\00",
+ $rsaOID,
+ 4,
+ $this->_encodeLength(strlen($RSAPrivateKey)),
+ $RSAPrivateKey
+ );
+ $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
+ if (!empty($this->password) || is_string($this->password)) {
+ $salt = Random::string(8);
+ $iterationCount = 2048;
+
+ $crypto = new DES();
+ $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
+ $RSAPrivateKey = $crypto->encrypt($RSAPrivateKey);
+
+ $parameters = pack(
+ 'Ca*a*Ca*N',
+ self::ASN1_OCTETSTRING,
+ $this->_encodeLength(strlen($salt)),
+ $salt,
+ self::ASN1_INTEGER,
+ $this->_encodeLength(4),
+ $iterationCount
+ );
+ $pbeWithMD5AndDES_CBC = "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03";
+
+ $encryptionAlgorithm = pack(
+ 'Ca*a*Ca*a*',
+ self::ASN1_OBJECT,
+ $this->_encodeLength(strlen($pbeWithMD5AndDES_CBC)),
+ $pbeWithMD5AndDES_CBC,
+ self::ASN1_SEQUENCE,
+ $this->_encodeLength(strlen($parameters)),
+ $parameters
+ );
+
+ $RSAPrivateKey = pack(
+ 'Ca*a*Ca*a*',
+ self::ASN1_SEQUENCE,
+ $this->_encodeLength(strlen($encryptionAlgorithm)),
+ $encryptionAlgorithm,
+ self::ASN1_OCTETSTRING,
+ $this->_encodeLength(strlen($RSAPrivateKey)),
+ $RSAPrivateKey
+ );
+
+ $RSAPrivateKey = pack('Ca*a*', self::ASN1_SEQUENCE, $this->_encodeLength(strlen($RSAPrivateKey)), $RSAPrivateKey);
+
+ $RSAPrivateKey = "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" .
+ chunk_split(base64_encode($RSAPrivateKey), 64) .
+ '-----END ENCRYPTED PRIVATE KEY-----';
+ } else {
+ $RSAPrivateKey = "-----BEGIN PRIVATE KEY-----\r\n" .
+ chunk_split(base64_encode($RSAPrivateKey), 64) .
+ '-----END PRIVATE KEY-----';
+ }
+ return $RSAPrivateKey;
+ }
+
+ if (!empty($this->password) || is_string($this->password)) {
+ $iv = Random::string(8);
+ $symkey = pack('H*', md5($this->password . $iv)); // symkey is short for symmetric key
+ $symkey.= substr(pack('H*', md5($symkey . $this->password . $iv)), 0, 8);
+ $des = new TripleDES();
+ $des->setKey($symkey);
+ $des->setIV($iv);
+ $iv = strtoupper(bin2hex($iv));
+ $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
+ "Proc-Type: 4,ENCRYPTED\r\n" .
+ "DEK-Info: DES-EDE3-CBC,$iv\r\n" .
+ "\r\n" .
+ chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) .
+ '-----END RSA PRIVATE KEY-----';
+ } else {
+ $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
+ chunk_split(base64_encode($RSAPrivateKey), 64) .
+ '-----END RSA PRIVATE KEY-----';
+ }
+
+ return $RSAPrivateKey;
+ }
+ }
+
+ /**
+ * Convert a public key to the appropriate format
+ *
+ * @access private
+ * @see self::setPublicKeyFormat()
+ * @param string $RSAPrivateKey
+ * @return string
+ */
+ function _convertPublicKey($n, $e)
+ {
+ $signed = $this->publicKeyFormat != self::PUBLIC_FORMAT_XML;
+
+ $modulus = $n->toBytes($signed);
+ $publicExponent = $e->toBytes($signed);
+
+ switch ($this->publicKeyFormat) {
+ case self::PUBLIC_FORMAT_RAW:
+ return array('e' => $e->copy(), 'n' => $n->copy());
+ case self::PUBLIC_FORMAT_XML:
+ return "<RSAKeyValue>\r\n" .
+ ' <Modulus>' . base64_encode($modulus) . "</Modulus>\r\n" .
+ ' <Exponent>' . base64_encode($publicExponent) . "</Exponent>\r\n" .
+ '</RSAKeyValue>';
+ break;
+ case self::PUBLIC_FORMAT_OPENSSH:
+ // from <http://tools.ietf.org/html/rfc4253#page-15>:
+ // string "ssh-rsa"
+ // mpint e
+ // mpint n
+ $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
+ $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $this->comment;
+
+ return $RSAPublicKey;
+ default: // eg. self::PUBLIC_FORMAT_PKCS1_RAW or self::PUBLIC_FORMAT_PKCS1
+ // from <http://tools.ietf.org/html/rfc3447#appendix-A.1.1>:
+ // RSAPublicKey ::= SEQUENCE {
+ // modulus INTEGER, -- n
+ // publicExponent INTEGER -- e
+ // }
+ $components = array(
+ 'modulus' => pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($modulus)), $modulus),
+ 'publicExponent' => pack('Ca*a*', self::ASN1_INTEGER, $this->_encodeLength(strlen($publicExponent)), $publicExponent)
+ );
+
+ $RSAPublicKey = pack(
+ 'Ca*a*a*',
+ self::ASN1_SEQUENCE,
+ $this->_encodeLength(strlen($components['modulus']) + strlen($components['publicExponent'])),
+ $components['modulus'],
+ $components['publicExponent']
+ );
+
+ if ($this->publicKeyFormat == self::PUBLIC_FORMAT_PKCS1_RAW) {
+ $RSAPublicKey = "-----BEGIN RSA PUBLIC KEY-----\r\n" .
+ chunk_split(base64_encode($RSAPublicKey), 64) .
+ '-----END RSA PUBLIC KEY-----';
+ } else {
+ // sequence(oid(1.2.840.113549.1.1.1), null)) = rsaEncryption.
+ $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
+ $RSAPublicKey = chr(0) . $RSAPublicKey;
+ $RSAPublicKey = chr(3) . $this->_encodeLength(strlen($RSAPublicKey)) . $RSAPublicKey;
+
+ $RSAPublicKey = pack(
+ 'Ca*a*',
+ self::ASN1_SEQUENCE,
+ $this->_encodeLength(strlen($rsaOID . $RSAPublicKey)),
+ $rsaOID . $RSAPublicKey
+ );
+
+ $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
+ chunk_split(base64_encode($RSAPublicKey), 64) .
+ '-----END PUBLIC KEY-----';
+ }
+
+ return $RSAPublicKey;
+ }
+ }
+
+ /**
+ * Break a public or private key down into its constituant components
+ *
+ * @access private
+ * @see self::_convertPublicKey()
+ * @see self::_convertPrivateKey()
+ * @param string|array $key
+ * @param int $type
+ * @return array|bool
+ */
+ function _parseKey($key, $type)
+ {
+ if ($type != self::PUBLIC_FORMAT_RAW && !is_string($key)) {
+ return false;
+ }
+
+ switch ($type) {
+ case self::PUBLIC_FORMAT_RAW:
+ if (!is_array($key)) {
+ return false;
+ }
+ $components = array();
+ switch (true) {
+ case isset($key['e']):
+ $components['publicExponent'] = $key['e']->copy();
+ break;
+ case isset($key['exponent']):
+ $components['publicExponent'] = $key['exponent']->copy();
+ break;
+ case isset($key['publicExponent']):
+ $components['publicExponent'] = $key['publicExponent']->copy();
+ break;
+ case isset($key[0]):
+ $components['publicExponent'] = $key[0]->copy();
+ }
+ switch (true) {
+ case isset($key['n']):
+ $components['modulus'] = $key['n']->copy();
+ break;
+ case isset($key['modulo']):
+ $components['modulus'] = $key['modulo']->copy();
+ break;
+ case isset($key['modulus']):
+ $components['modulus'] = $key['modulus']->copy();
+ break;
+ case isset($key[1]):
+ $components['modulus'] = $key[1]->copy();
+ }
+ return isset($components['modulus']) && isset($components['publicExponent']) ? $components : false;
+ case self::PRIVATE_FORMAT_PKCS1:
+ case self::PRIVATE_FORMAT_PKCS8:
+ case self::PUBLIC_FORMAT_PKCS1:
+ /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is
+ "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to
+ protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding
+ two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here:
+
+ http://tools.ietf.org/html/rfc1421#section-4.6.1.1
+ http://tools.ietf.org/html/rfc1421#section-4.6.1.3
+
+ DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell.
+ DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation
+ function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's
+ own implementation. ie. the implementation *is* the standard and any bugs that may exist in that
+ implementation are part of the standard, as well.
+
+ * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */
+ if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) {
+ $iv = pack('H*', trim($matches[2]));
+ $symkey = pack('H*', md5($this->password . substr($iv, 0, 8))); // symkey is short for symmetric key
+ $symkey.= pack('H*', md5($symkey . $this->password . substr($iv, 0, 8)));
+ // remove the Proc-Type / DEK-Info sections as they're no longer needed
+ $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key);
+ $ciphertext = $this->_extractBER($key);
+ if ($ciphertext === false) {
+ $ciphertext = $key;
+ }
+ switch ($matches[1]) {
+ case 'AES-256-CBC':
+ $crypto = new AES();
+ break;
+ case 'AES-128-CBC':
+ $symkey = substr($symkey, 0, 16);
+ $crypto = new AES();
+ break;
+ case 'DES-EDE3-CFB':
+ $crypto = new TripleDES(Base::MODE_CFB);
+ break;
+ case 'DES-EDE3-CBC':
+ $symkey = substr($symkey, 0, 24);
+ $crypto = new TripleDES();
+ break;
+ case 'DES-CBC':
+ $crypto = new DES();
+ break;
+ default:
+ return false;
+ }
+ $crypto->setKey($symkey);
+ $crypto->setIV($iv);
+ $decoded = $crypto->decrypt($ciphertext);
+ } else {
+ $decoded = $this->_extractBER($key);
+ }
+
+ if ($decoded !== false) {
+ $key = $decoded;
+ }
+
+ $components = array();
+
+ if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) {
+ return false;
+ }
+ if ($this->_decodeLength($key) != strlen($key)) {
+ return false;
+ }
+
+ $tag = ord($this->_string_shift($key));
+ /* intended for keys for which OpenSSL's asn1parse returns the following:
+
+ 0:d=0 hl=4 l= 631 cons: SEQUENCE
+ 4:d=1 hl=2 l= 1 prim: INTEGER :00
+ 7:d=1 hl=2 l= 13 cons: SEQUENCE
+ 9:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
+ 20:d=2 hl=2 l= 0 prim: NULL
+ 22:d=1 hl=4 l= 609 prim: OCTET STRING
+
+ ie. PKCS8 keys*/
+
+ if ($tag == self::ASN1_INTEGER && substr($key, 0, 3) == "\x01\x00\x30") {
+ $this->_string_shift($key, 3);
+ $tag = self::ASN1_SEQUENCE;
+ }
+
+ if ($tag == self::ASN1_SEQUENCE) {
+ $temp = $this->_string_shift($key, $this->_decodeLength($key));
+ if (ord($this->_string_shift($temp)) != self::ASN1_OBJECT) {
+ return false;
+ }
+ $length = $this->_decodeLength($temp);
+ switch ($this->_string_shift($temp, $length)) {
+ case "\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01": // rsaEncryption
+ break;
+ case "\x2a\x86\x48\x86\xf7\x0d\x01\x05\x03": // pbeWithMD5AndDES-CBC
+ /*
+ PBEParameter ::= SEQUENCE {
+ salt OCTET STRING (SIZE(8)),
+ iterationCount INTEGER }
+ */
+ if (ord($this->_string_shift($temp)) != self::ASN1_SEQUENCE) {
+ return false;
+ }
+ if ($this->_decodeLength($temp) != strlen($temp)) {
+ return false;
+ }
+ $this->_string_shift($temp); // assume it's an octet string
+ $salt = $this->_string_shift($temp, $this->_decodeLength($temp));
+ if (ord($this->_string_shift($temp)) != self::ASN1_INTEGER) {
+ return false;
+ }
+ $this->_decodeLength($temp);
+ list(, $iterationCount) = unpack('N', str_pad($temp, 4, chr(0), STR_PAD_LEFT));
+ $this->_string_shift($key); // assume it's an octet string
+ $length = $this->_decodeLength($key);
+ if (strlen($key) != $length) {
+ return false;
+ }
+
+ $crypto = new DES();
+ $crypto->setPassword($this->password, 'pbkdf1', 'md5', $salt, $iterationCount);
+ $key = $crypto->decrypt($key);
+ if ($key === false) {
+ return false;
+ }
+ return $this->_parseKey($key, self::PRIVATE_FORMAT_PKCS1);
+ default:
+ return false;
+ }
+ /* intended for keys for which OpenSSL's asn1parse returns the following:
+
+ 0:d=0 hl=4 l= 290 cons: SEQUENCE
+ 4:d=1 hl=2 l= 13 cons: SEQUENCE
+ 6:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
+ 17:d=2 hl=2 l= 0 prim: NULL
+ 19:d=1 hl=4 l= 271 prim: BIT STRING */
+ $tag = ord($this->_string_shift($key)); // skip over the BIT STRING / OCTET STRING tag
+ $this->_decodeLength($key); // skip over the BIT STRING / OCTET STRING length
+ // "The initial octet shall encode, as an unsigned binary integer wtih bit 1 as the least significant bit, the number of
+ // unused bits in the final subsequent octet. The number shall be in the range zero to seven."
+ // -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf (section 8.6.2.2)
+ if ($tag == self::ASN1_BITSTRING) {
+ $this->_string_shift($key);
+ }
+ if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) {
+ return false;
+ }
+ if ($this->_decodeLength($key) != strlen($key)) {
+ return false;
+ }
+ $tag = ord($this->_string_shift($key));
+ }
+ if ($tag != self::ASN1_INTEGER) {
+ return false;
+ }
+
+ $length = $this->_decodeLength($key);
+ $temp = $this->_string_shift($key, $length);
+ if (strlen($temp) != 1 || ord($temp) > 2) {
+ $components['modulus'] = new BigInteger($temp, 256);
+ $this->_string_shift($key); // skip over self::ASN1_INTEGER
+ $length = $this->_decodeLength($key);
+ $components[$type == self::PUBLIC_FORMAT_PKCS1 ? 'publicExponent' : 'privateExponent'] = new BigInteger($this->_string_shift($key, $length), 256);
+
+ return $components;
+ }
+ if (ord($this->_string_shift($key)) != self::ASN1_INTEGER) {
+ return false;
+ }
+ $length = $this->_decodeLength($key);
+ $components['modulus'] = new BigInteger($this->_string_shift($key, $length), 256);
+ $this->_string_shift($key);
+ $length = $this->_decodeLength($key);
+ $components['publicExponent'] = new BigInteger($this->_string_shift($key, $length), 256);
+ $this->_string_shift($key);
+ $length = $this->_decodeLength($key);
+ $components['privateExponent'] = new BigInteger($this->_string_shift($key, $length), 256);
+ $this->_string_shift($key);
+ $length = $this->_decodeLength($key);
+ $components['primes'] = array(1 => new BigInteger($this->_string_shift($key, $length), 256));
+ $this->_string_shift($key);
+ $length = $this->_decodeLength($key);
+ $components['primes'][] = new BigInteger($this->_string_shift($key, $length), 256);
+ $this->_string_shift($key);
+ $length = $this->_decodeLength($key);
+ $components['exponents'] = array(1 => new BigInteger($this->_string_shift($key, $length), 256));
+ $this->_string_shift($key);
+ $length = $this->_decodeLength($key);
+ $components['exponents'][] = new BigInteger($this->_string_shift($key, $length), 256);
+ $this->_string_shift($key);
+ $length = $this->_decodeLength($key);
+ $components['coefficients'] = array(2 => new BigInteger($this->_string_shift($key, $length), 256));
+
+ if (!empty($key)) {
+ if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) {
+ return false;
+ }
+ $this->_decodeLength($key);
+ while (!empty($key)) {
+ if (ord($this->_string_shift($key)) != self::ASN1_SEQUENCE) {
+ return false;
+ }
+ $this->_decodeLength($key);
+ $key = substr($key, 1);
+ $length = $this->_decodeLength($key);
+ $components['primes'][] = new BigInteger($this->_string_shift($key, $length), 256);
+ $this->_string_shift($key);
+ $length = $this->_decodeLength($key);
+ $components['exponents'][] = new BigInteger($this->_string_shift($key, $length), 256);
+ $this->_string_shift($key);
+ $length = $this->_decodeLength($key);
+ $components['coefficients'][] = new BigInteger($this->_string_shift($key, $length), 256);
+ }
+ }
+
+ return $components;
+ case self::PUBLIC_FORMAT_OPENSSH:
+ $parts = explode(' ', $key, 3);
+
+ $key = isset($parts[1]) ? base64_decode($parts[1]) : false;
+ if ($key === false) {
+ return false;
+ }
+
+ $comment = isset($parts[2]) ? $parts[2] : false;
+
+ $cleanup = substr($key, 0, 11) == "\0\0\0\7ssh-rsa";
+
+ if (strlen($key) <= 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($key, 4)));
+ $publicExponent = new BigInteger($this->_string_shift($key, $length), -256);
+ if (strlen($key) <= 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($key, 4)));
+ $modulus = new BigInteger($this->_string_shift($key, $length), -256);
+
+ if ($cleanup && strlen($key)) {
+ if (strlen($key) <= 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($key, 4)));
+ $realModulus = new BigInteger($this->_string_shift($key, $length), -256);
+ return strlen($key) ? false : array(
+ 'modulus' => $realModulus,
+ 'publicExponent' => $modulus,
+ 'comment' => $comment
+ );
+ } else {
+ return strlen($key) ? false : array(
+ 'modulus' => $modulus,
+ 'publicExponent' => $publicExponent,
+ 'comment' => $comment
+ );
+ }
+ // http://www.w3.org/TR/xmldsig-core/#sec-RSAKeyValue
+ // http://en.wikipedia.org/wiki/XML_Signature
+ case self::PRIVATE_FORMAT_XML:
+ case self::PUBLIC_FORMAT_XML:
+ $this->components = array();
+
+ $xml = xml_parser_create('UTF-8');
+ xml_set_object($xml, $this);
+ xml_set_element_handler($xml, '_start_element_handler', '_stop_element_handler');
+ xml_set_character_data_handler($xml, '_data_handler');
+ // add <xml></xml> to account for "dangling" tags like <BitStrength>...</BitStrength> that are sometimes added
+ if (!xml_parse($xml, '<xml>' . $key . '</xml>')) {
+ xml_parser_free($xml);
+ unset($xml);
+ return false;
+ }
+
+ xml_parser_free($xml);
+ unset($xml);
+
+ return isset($this->components['modulus']) && isset($this->components['publicExponent']) ? $this->components : false;
+ // from PuTTY's SSHPUBK.C
+ case self::PRIVATE_FORMAT_PUTTY:
+ $components = array();
+ $key = preg_split('#\r\n|\r|\n#', $key);
+ $type = trim(preg_replace('#PuTTY-User-Key-File-2: (.+)#', '$1', $key[0]));
+ if ($type != 'ssh-rsa') {
+ return false;
+ }
+ $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1]));
+ $comment = trim(preg_replace('#Comment: (.+)#', '$1', $key[2]));
+
+ $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3]));
+ $public = base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength))));
+ $public = substr($public, 11);
+ extract(unpack('Nlength', $this->_string_shift($public, 4)));
+ $components['publicExponent'] = new BigInteger($this->_string_shift($public, $length), -256);
+ extract(unpack('Nlength', $this->_string_shift($public, 4)));
+ $components['modulus'] = new BigInteger($this->_string_shift($public, $length), -256);
+
+ $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$publicLength + 4]));
+ $private = base64_decode(implode('', array_map('trim', array_slice($key, $publicLength + 5, $privateLength))));
+
+ switch ($encryption) {
+ case 'aes256-cbc':
+ $symkey = '';
+ $sequence = 0;
+ while (strlen($symkey) < 32) {
+ $temp = pack('Na*', $sequence++, $this->password);
+ $symkey.= pack('H*', sha1($temp));
+ }
+ $symkey = substr($symkey, 0, 32);
+ $crypto = new AES();
+ }
+
+ if ($encryption != 'none') {
+ $crypto->setKey($symkey);
+ $crypto->disablePadding();
+ $private = $crypto->decrypt($private);
+ if ($private === false) {
+ return false;
+ }
+ }
+
+ extract(unpack('Nlength', $this->_string_shift($private, 4)));
+ if (strlen($private) < $length) {
+ return false;
+ }
+ $components['privateExponent'] = new BigInteger($this->_string_shift($private, $length), -256);
+ extract(unpack('Nlength', $this->_string_shift($private, 4)));
+ if (strlen($private) < $length) {
+ return false;
+ }
+ $components['primes'] = array(1 => new BigInteger($this->_string_shift($private, $length), -256));
+ extract(unpack('Nlength', $this->_string_shift($private, 4)));
+ if (strlen($private) < $length) {
+ return false;
+ }
+ $components['primes'][] = new BigInteger($this->_string_shift($private, $length), -256);
+
+ $temp = $components['primes'][1]->subtract($this->one);
+ $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
+ $temp = $components['primes'][2]->subtract($this->one);
+ $components['exponents'][] = $components['publicExponent']->modInverse($temp);
+
+ extract(unpack('Nlength', $this->_string_shift($private, 4)));
+ if (strlen($private) < $length) {
+ return false;
+ }
+ $components['coefficients'] = array(2 => new BigInteger($this->_string_shift($private, $length), -256));
+
+ return $components;
+ case self::PRIVATE_FORMAT_OPENSSH:
+ $components = array();
+ $decoded = $this->_extractBER($key);
+ $magic = $this->_string_shift($decoded, 15);
+ if ($magic !== "openssh-key-v1\0") {
+ return false;
+ }
+ $options = $this->_string_shift($decoded, 24);
+ // \0\0\0\4none = ciphername
+ // \0\0\0\4none = kdfname
+ // \0\0\0\0 = kdfoptions
+ // \0\0\0\1 = numkeys
+ if ($options != "\0\0\0\4none\0\0\0\4none\0\0\0\0\0\0\0\1") {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
+ if (strlen($decoded) < $length) {
+ return false;
+ }
+ $publicKey = $this->_string_shift($decoded, $length);
+ extract(unpack('Nlength', $this->_string_shift($decoded, 4)));
+ if (strlen($decoded) < $length) {
+ return false;
+ }
+ $paddedKey = $this->_string_shift($decoded, $length);
+
+ if ($this->_string_shift($publicKey, 11) !== "\0\0\0\7ssh-rsa") {
+ return false;
+ }
+
+ $checkint1 = $this->_string_shift($paddedKey, 4);
+ $checkint2 = $this->_string_shift($paddedKey, 4);
+ if (strlen($checkint1) != 4 || $checkint1 !== $checkint2) {
+ return false;
+ }
+
+ if ($this->_string_shift($paddedKey, 11) !== "\0\0\0\7ssh-rsa") {
+ return false;
+ }
+
+ $values = array(
+ &$components['modulus'],
+ &$components['publicExponent'],
+ &$components['privateExponent'],
+ &$components['coefficients'][2],
+ &$components['primes'][1],
+ &$components['primes'][2]
+ );
+
+ foreach ($values as &$value) {
+ extract(unpack('Nlength', $this->_string_shift($paddedKey, 4)));
+ if (strlen($paddedKey) < $length) {
+ return false;
+ }
+ $value = new BigInteger($this->_string_shift($paddedKey, $length), -256);
+ }
+
+ extract(unpack('Nlength', $this->_string_shift($paddedKey, 4)));
+ if (strlen($paddedKey) < $length) {
+ return false;
+ }
+ $components['comment'] = $this->_string_shift($decoded, $length);
+
+ $temp = $components['primes'][1]->subtract($this->one);
+ $components['exponents'] = array(1 => $components['publicExponent']->modInverse($temp));
+ $temp = $components['primes'][2]->subtract($this->one);
+ $components['exponents'][] = $components['publicExponent']->modInverse($temp);
+
+ return $components;
+ }
+ }
+
+ /**
+ * Returns the key size
+ *
+ * More specifically, this returns the size of the modulo in bits.
+ *
+ * @access public
+ * @return int
+ */
+ function getSize()
+ {
+ return !isset($this->modulus) ? 0 : strlen($this->modulus->toBits());
+ }
+
+ /**
+ * Start Element Handler
+ *
+ * Called by xml_set_element_handler()
+ *
+ * @access private
+ * @param resource $parser
+ * @param string $name
+ * @param array $attribs
+ */
+ function _start_element_handler($parser, $name, $attribs)
+ {
+ //$name = strtoupper($name);
+ switch ($name) {
+ case 'MODULUS':
+ $this->current = &$this->components['modulus'];
+ break;
+ case 'EXPONENT':
+ $this->current = &$this->components['publicExponent'];
+ break;
+ case 'P':
+ $this->current = &$this->components['primes'][1];
+ break;
+ case 'Q':
+ $this->current = &$this->components['primes'][2];
+ break;
+ case 'DP':
+ $this->current = &$this->components['exponents'][1];
+ break;
+ case 'DQ':
+ $this->current = &$this->components['exponents'][2];
+ break;
+ case 'INVERSEQ':
+ $this->current = &$this->components['coefficients'][2];
+ break;
+ case 'D':
+ $this->current = &$this->components['privateExponent'];
+ }
+ $this->current = '';
+ }
+
+ /**
+ * Stop Element Handler
+ *
+ * Called by xml_set_element_handler()
+ *
+ * @access private
+ * @param resource $parser
+ * @param string $name
+ */
+ function _stop_element_handler($parser, $name)
+ {
+ if (isset($this->current)) {
+ $this->current = new BigInteger(base64_decode($this->current), 256);
+ unset($this->current);
+ }
+ }
+
+ /**
+ * Data Handler
+ *
+ * Called by xml_set_character_data_handler()
+ *
+ * @access private
+ * @param resource $parser
+ * @param string $data
+ */
+ function _data_handler($parser, $data)
+ {
+ if (!isset($this->current) || is_object($this->current)) {
+ return;
+ }
+ $this->current.= trim($data);
+ }
+
+ /**
+ * Loads a public or private key
+ *
+ * Returns true on success and false on failure (ie. an incorrect password was provided or the key was malformed)
+ *
+ * @access public
+ * @param string|RSA|array $key
+ * @param bool|int $type optional
+ * @return bool
+ */
+ function loadKey($key, $type = false)
+ {
+ if ($key instanceof RSA) {
+ $this->privateKeyFormat = $key->privateKeyFormat;
+ $this->publicKeyFormat = $key->publicKeyFormat;
+ $this->k = $key->k;
+ $this->hLen = $key->hLen;
+ $this->sLen = $key->sLen;
+ $this->mgfHLen = $key->mgfHLen;
+ $this->encryptionMode = $key->encryptionMode;
+ $this->signatureMode = $key->signatureMode;
+ $this->password = $key->password;
+ $this->configFile = $key->configFile;
+ $this->comment = $key->comment;
+
+ if (is_object($key->hash)) {
+ $this->hash = new Hash($key->hash->getHash());
+ }
+ if (is_object($key->mgfHash)) {
+ $this->mgfHash = new Hash($key->mgfHash->getHash());
+ }
+
+ if (is_object($key->modulus)) {
+ $this->modulus = $key->modulus->copy();
+ }
+ if (is_object($key->exponent)) {
+ $this->exponent = $key->exponent->copy();
+ }
+ if (is_object($key->publicExponent)) {
+ $this->publicExponent = $key->publicExponent->copy();
+ }
+
+ $this->primes = array();
+ $this->exponents = array();
+ $this->coefficients = array();
+
+ foreach ($this->primes as $prime) {
+ $this->primes[] = $prime->copy();
+ }
+ foreach ($this->exponents as $exponent) {
+ $this->exponents[] = $exponent->copy();
+ }
+ foreach ($this->coefficients as $coefficient) {
+ $this->coefficients[] = $coefficient->copy();
+ }
+
+ return true;
+ }
+
+ if ($type === false) {
+ $types = array(
+ self::PUBLIC_FORMAT_RAW,
+ self::PRIVATE_FORMAT_PKCS1,
+ self::PRIVATE_FORMAT_XML,
+ self::PRIVATE_FORMAT_PUTTY,
+ self::PUBLIC_FORMAT_OPENSSH,
+ self::PRIVATE_FORMAT_OPENSSH
+ );
+ foreach ($types as $type) {
+ $components = $this->_parseKey($key, $type);
+ if ($components !== false) {
+ break;
+ }
+ }
+ } else {
+ $components = $this->_parseKey($key, $type);
+ }
+
+ if ($components === false) {
+ $this->comment = null;
+ $this->modulus = null;
+ $this->k = null;
+ $this->exponent = null;
+ $this->primes = null;
+ $this->exponents = null;
+ $this->coefficients = null;
+ $this->publicExponent = null;
+
+ return false;
+ }
+
+ if (isset($components['comment']) && $components['comment'] !== false) {
+ $this->comment = $components['comment'];
+ }
+ $this->modulus = $components['modulus'];
+ $this->k = strlen($this->modulus->toBytes());
+ $this->exponent = isset($components['privateExponent']) ? $components['privateExponent'] : $components['publicExponent'];
+ if (isset($components['primes'])) {
+ $this->primes = $components['primes'];
+ $this->exponents = $components['exponents'];
+ $this->coefficients = $components['coefficients'];
+ $this->publicExponent = $components['publicExponent'];
+ } else {
+ $this->primes = array();
+ $this->exponents = array();
+ $this->coefficients = array();
+ $this->publicExponent = false;
+ }
+
+ switch ($type) {
+ case self::PUBLIC_FORMAT_OPENSSH:
+ case self::PUBLIC_FORMAT_RAW:
+ $this->setPublicKey();
+ break;
+ case self::PRIVATE_FORMAT_PKCS1:
+ switch (true) {
+ case strpos($key, '-BEGIN PUBLIC KEY-') !== false:
+ case strpos($key, '-BEGIN RSA PUBLIC KEY-') !== false:
+ $this->setPublicKey();
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets the password
+ *
+ * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false.
+ * Or rather, pass in $password such that empty($password) && !is_string($password) is true.
+ *
+ * @see self::createKey()
+ * @see self::loadKey()
+ * @access public
+ * @param string $password
+ */
+ function setPassword($password = false)
+ {
+ $this->password = $password;
+ }
+
+ /**
+ * Defines the public key
+ *
+ * Some private key formats define the public exponent and some don't. Those that don't define it are problematic when
+ * used in certain contexts. For example, in SSH-2, RSA authentication works by sending the public key along with a
+ * message signed by the private key to the server. The SSH-2 server looks the public key up in an index of public keys
+ * and if it's present then proceeds to verify the signature. Problem is, if your private key doesn't include the public
+ * exponent this won't work unless you manually add the public exponent. phpseclib tries to guess if the key being used
+ * is the public key but in the event that it guesses incorrectly you might still want to explicitly set the key as being
+ * public.
+ *
+ * Do note that when a new key is loaded the index will be cleared.
+ *
+ * Returns true on success, false on failure
+ *
+ * @see self::getPublicKey()
+ * @access public
+ * @param string $key optional
+ * @param int $type optional
+ * @return bool
+ */
+ function setPublicKey($key = false, $type = false)
+ {
+ // if a public key has already been loaded return false
+ if (!empty($this->publicExponent)) {
+ return false;
+ }
+
+ if ($key === false && !empty($this->modulus)) {
+ $this->publicExponent = $this->exponent;
+ return true;
+ }
+
+ if ($type === false) {
+ $types = array(
+ self::PUBLIC_FORMAT_RAW,
+ self::PUBLIC_FORMAT_PKCS1,
+ self::PUBLIC_FORMAT_XML,
+ self::PUBLIC_FORMAT_OPENSSH
+ );
+ foreach ($types as $type) {
+ $components = $this->_parseKey($key, $type);
+ if ($components !== false) {
+ break;
+ }
+ }
+ } else {
+ $components = $this->_parseKey($key, $type);
+ }
+
+ if ($components === false) {
+ return false;
+ }
+
+ if (empty($this->modulus) || !$this->modulus->equals($components['modulus'])) {
+ $this->modulus = $components['modulus'];
+ $this->exponent = $this->publicExponent = $components['publicExponent'];
+ return true;
+ }
+
+ $this->publicExponent = $components['publicExponent'];
+
+ return true;
+ }
+
+ /**
+ * Defines the private key
+ *
+ * If phpseclib guessed a private key was a public key and loaded it as such it might be desirable to force
+ * phpseclib to treat the key as a private key. This function will do that.
+ *
+ * Do note that when a new key is loaded the index will be cleared.
+ *
+ * Returns true on success, false on failure
+ *
+ * @see self::getPublicKey()
+ * @access public
+ * @param string $key optional
+ * @param int $type optional
+ * @return bool
+ */
+ function setPrivateKey($key = false, $type = false)
+ {
+ if ($key === false && !empty($this->publicExponent)) {
+ $this->publicExponent = false;
+ return true;
+ }
+
+ $rsa = new RSA();
+ if (!$rsa->loadKey($key, $type)) {
+ return false;
+ }
+ $rsa->publicExponent = false;
+
+ // don't overwrite the old key if the new key is invalid
+ $this->loadKey($rsa);
+ return true;
+ }
+
+ /**
+ * Returns the public key
+ *
+ * The public key is only returned under two circumstances - if the private key had the public key embedded within it
+ * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this
+ * function won't return it since this library, for the most part, doesn't distinguish between public and private keys.
+ *
+ * @see self::getPublicKey()
+ * @access public
+ * @param string $key
+ * @param int $type optional
+ */
+ function getPublicKey($type = self::PUBLIC_FORMAT_PKCS8)
+ {
+ if (empty($this->modulus) || empty($this->publicExponent)) {
+ return false;
+ }
+
+ $oldFormat = $this->publicKeyFormat;
+ $this->publicKeyFormat = $type;
+ $temp = $this->_convertPublicKey($this->modulus, $this->publicExponent);
+ $this->publicKeyFormat = $oldFormat;
+ return $temp;
+ }
+
+ /**
+ * Returns the public key's fingerprint
+ *
+ * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is
+ * no public key currently loaded, false is returned.
+ * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716)
+ *
+ * @access public
+ * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned
+ * for invalid values.
+ * @return mixed
+ */
+ function getPublicKeyFingerprint($algorithm = 'md5')
+ {
+ if (empty($this->modulus) || empty($this->publicExponent)) {
+ return false;
+ }
+
+ $modulus = $this->modulus->toBytes(true);
+ $publicExponent = $this->publicExponent->toBytes(true);
+
+ $RSAPublicKey = pack('Na*Na*Na*', strlen('ssh-rsa'), 'ssh-rsa', strlen($publicExponent), $publicExponent, strlen($modulus), $modulus);
+
+ switch ($algorithm) {
+ case 'sha256':
+ $hash = new Hash('sha256');
+ $base = base64_encode($hash->hash($RSAPublicKey));
+ return substr($base, 0, strlen($base) - 1);
+ case 'md5':
+ return substr(chunk_split(md5($RSAPublicKey), 2, ':'), 0, -1);
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Returns the private key
+ *
+ * The private key is only returned if the currently loaded key contains the constituent prime numbers.
+ *
+ * @see self::getPublicKey()
+ * @access public
+ * @param string $key
+ * @param int $type optional
+ * @return mixed
+ */
+ function getPrivateKey($type = self::PUBLIC_FORMAT_PKCS1)
+ {
+ if (empty($this->primes)) {
+ return false;
+ }
+
+ $oldFormat = $this->privateKeyFormat;
+ $this->privateKeyFormat = $type;
+ $temp = $this->_convertPrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients);
+ $this->privateKeyFormat = $oldFormat;
+ return $temp;
+ }
+
+ /**
+ * Returns a minimalistic private key
+ *
+ * Returns the private key without the prime number constituants. Structurally identical to a public key that
+ * hasn't been set as the public key
+ *
+ * @see self::getPrivateKey()
+ * @access private
+ * @param string $key
+ * @param int $type optional
+ */
+ function _getPrivatePublicKey($mode = self::PUBLIC_FORMAT_PKCS8)
+ {
+ if (empty($this->modulus) || empty($this->exponent)) {
+ return false;
+ }
+
+ $oldFormat = $this->publicKeyFormat;
+ $this->publicKeyFormat = $mode;
+ $temp = $this->_convertPublicKey($this->modulus, $this->exponent);
+ $this->publicKeyFormat = $oldFormat;
+ return $temp;
+ }
+
+ /**
+ * __toString() magic method
+ *
+ * @access public
+ * @return string
+ */
+ function __toString()
+ {
+ $key = $this->getPrivateKey($this->privateKeyFormat);
+ if ($key !== false) {
+ return $key;
+ }
+ $key = $this->_getPrivatePublicKey($this->publicKeyFormat);
+ return $key !== false ? $key : '';
+ }
+
+ /**
+ * __clone() magic method
+ *
+ * @access public
+ * @return Crypt_RSA
+ */
+ function __clone()
+ {
+ $key = new RSA();
+ $key->loadKey($this);
+ return $key;
+ }
+
+ /**
+ * Generates the smallest and largest numbers requiring $bits bits
+ *
+ * @access private
+ * @param int $bits
+ * @return array
+ */
+ function _generateMinMax($bits)
+ {
+ $bytes = $bits >> 3;
+ $min = str_repeat(chr(0), $bytes);
+ $max = str_repeat(chr(0xFF), $bytes);
+ $msb = $bits & 7;
+ if ($msb) {
+ $min = chr(1 << ($msb - 1)) . $min;
+ $max = chr((1 << $msb) - 1) . $max;
+ } else {
+ $min[0] = chr(0x80);
+ }
+
+ return array(
+ 'min' => new BigInteger($min, 256),
+ 'max' => new BigInteger($max, 256)
+ );
+ }
+
+ /**
+ * DER-decode the length
+ *
+ * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
+ * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
+ *
+ * @access private
+ * @param string $string
+ * @return int
+ */
+ function _decodeLength(&$string)
+ {
+ $length = ord($this->_string_shift($string));
+ if ($length & 0x80) { // definite length, long form
+ $length&= 0x7F;
+ $temp = $this->_string_shift($string, $length);
+ list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4));
+ }
+ return $length;
+ }
+
+ /**
+ * DER-encode the length
+ *
+ * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
+ * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
+ *
+ * @access private
+ * @param int $length
+ * @return string
+ */
+ function _encodeLength($length)
+ {
+ if ($length <= 0x7F) {
+ return chr($length);
+ }
+
+ $temp = ltrim(pack('N', $length), chr(0));
+ return pack('Ca*', 0x80 | strlen($temp), $temp);
+ }
+
+ /**
+ * String Shift
+ *
+ * Inspired by array_shift
+ *
+ * @param string $string
+ * @param int $index
+ * @return string
+ * @access private
+ */
+ function _string_shift(&$string, $index = 1)
+ {
+ $substr = substr($string, 0, $index);
+ $string = substr($string, $index);
+ return $substr;
+ }
+
+ /**
+ * Determines the private key format
+ *
+ * @see self::createKey()
+ * @access public
+ * @param int $format
+ */
+ function setPrivateKeyFormat($format)
+ {
+ $this->privateKeyFormat = $format;
+ }
+
+ /**
+ * Determines the public key format
+ *
+ * @see self::createKey()
+ * @access public
+ * @param int $format
+ */
+ function setPublicKeyFormat($format)
+ {
+ $this->publicKeyFormat = $format;
+ }
+
+ /**
+ * Determines which hashing function should be used
+ *
+ * Used with signature production / verification and (if the encryption mode is self::ENCRYPTION_OAEP) encryption and
+ * decryption. If $hash isn't supported, sha1 is used.
+ *
+ * @access public
+ * @param string $hash
+ */
+ function setHash($hash)
+ {
+ // \phpseclib\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
+ switch ($hash) {
+ case 'md2':
+ case 'md5':
+ case 'sha1':
+ case 'sha256':
+ case 'sha384':
+ case 'sha512':
+ $this->hash = new Hash($hash);
+ $this->hashName = $hash;
+ break;
+ default:
+ $this->hash = new Hash('sha1');
+ $this->hashName = 'sha1';
+ }
+ $this->hLen = $this->hash->getLength();
+ }
+
+ /**
+ * Determines which hashing function should be used for the mask generation function
+ *
+ * The mask generation function is used by self::ENCRYPTION_OAEP and self::SIGNATURE_PSS and although it's
+ * best if Hash and MGFHash are set to the same thing this is not a requirement.
+ *
+ * @access public
+ * @param string $hash
+ */
+ function setMGFHash($hash)
+ {
+ // \phpseclib\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example.
+ switch ($hash) {
+ case 'md2':
+ case 'md5':
+ case 'sha1':
+ case 'sha256':
+ case 'sha384':
+ case 'sha512':
+ $this->mgfHash = new Hash($hash);
+ break;
+ default:
+ $this->mgfHash = new Hash('sha1');
+ }
+ $this->mgfHLen = $this->mgfHash->getLength();
+ }
+
+ /**
+ * Determines the salt length
+ *
+ * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}:
+ *
+ * Typical salt lengths in octets are hLen (the length of the output
+ * of the hash function Hash) and 0.
+ *
+ * @access public
+ * @param int $format
+ */
+ function setSaltLength($sLen)
+ {
+ $this->sLen = $sLen;
+ }
+
+ /**
+ * Integer-to-Octet-String primitive
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}.
+ *
+ * @access private
+ * @param \phpseclib\Math\BigInteger $x
+ * @param int $xLen
+ * @return string
+ */
+ function _i2osp($x, $xLen)
+ {
+ $x = $x->toBytes();
+ if (strlen($x) > $xLen) {
+ user_error('Integer too large');
+ return false;
+ }
+ return str_pad($x, $xLen, chr(0), STR_PAD_LEFT);
+ }
+
+ /**
+ * Octet-String-to-Integer primitive
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}.
+ *
+ * @access private
+ * @param string $x
+ * @return \phpseclib\Math\BigInteger
+ */
+ function _os2ip($x)
+ {
+ return new BigInteger($x, 256);
+ }
+
+ /**
+ * Exponentiate with or without Chinese Remainder Theorem
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.2}.
+ *
+ * @access private
+ * @param \phpseclib\Math\BigInteger $x
+ * @return \phpseclib\Math\BigInteger
+ */
+ function _exponentiate($x)
+ {
+ switch (true) {
+ case empty($this->primes):
+ case $this->primes[1]->equals($this->zero):
+ case empty($this->coefficients):
+ case $this->coefficients[2]->equals($this->zero):
+ case empty($this->exponents):
+ case $this->exponents[1]->equals($this->zero):
+ return $x->modPow($this->exponent, $this->modulus);
+ }
+
+ $num_primes = count($this->primes);
+
+ if (defined('CRYPT_RSA_DISABLE_BLINDING')) {
+ $m_i = array(
+ 1 => $x->modPow($this->exponents[1], $this->primes[1]),
+ 2 => $x->modPow($this->exponents[2], $this->primes[2])
+ );
+ $h = $m_i[1]->subtract($m_i[2]);
+ $h = $h->multiply($this->coefficients[2]);
+ list(, $h) = $h->divide($this->primes[1]);
+ $m = $m_i[2]->add($h->multiply($this->primes[2]));
+
+ $r = $this->primes[1];
+ for ($i = 3; $i <= $num_primes; $i++) {
+ $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]);
+
+ $r = $r->multiply($this->primes[$i - 1]);
+
+ $h = $m_i->subtract($m);
+ $h = $h->multiply($this->coefficients[$i]);
+ list(, $h) = $h->divide($this->primes[$i]);
+
+ $m = $m->add($r->multiply($h));
+ }
+ } else {
+ $smallest = $this->primes[1];
+ for ($i = 2; $i <= $num_primes; $i++) {
+ if ($smallest->compare($this->primes[$i]) > 0) {
+ $smallest = $this->primes[$i];
+ }
+ }
+
+ $one = new BigInteger(1);
+
+ $r = $one->random($one, $smallest->subtract($one));
+
+ $m_i = array(
+ 1 => $this->_blind($x, $r, 1),
+ 2 => $this->_blind($x, $r, 2)
+ );
+ $h = $m_i[1]->subtract($m_i[2]);
+ $h = $h->multiply($this->coefficients[2]);
+ list(, $h) = $h->divide($this->primes[1]);
+ $m = $m_i[2]->add($h->multiply($this->primes[2]));
+
+ $r = $this->primes[1];
+ for ($i = 3; $i <= $num_primes; $i++) {
+ $m_i = $this->_blind($x, $r, $i);
+
+ $r = $r->multiply($this->primes[$i - 1]);
+
+ $h = $m_i->subtract($m);
+ $h = $h->multiply($this->coefficients[$i]);
+ list(, $h) = $h->divide($this->primes[$i]);
+
+ $m = $m->add($r->multiply($h));
+ }
+ }
+
+ return $m;
+ }
+
+ /**
+ * Performs RSA Blinding
+ *
+ * Protects against timing attacks by employing RSA Blinding.
+ * Returns $x->modPow($this->exponents[$i], $this->primes[$i])
+ *
+ * @access private
+ * @param \phpseclib\Math\BigInteger $x
+ * @param \phpseclib\Math\BigInteger $r
+ * @param int $i
+ * @return \phpseclib\Math\BigInteger
+ */
+ function _blind($x, $r, $i)
+ {
+ $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i]));
+ $x = $x->modPow($this->exponents[$i], $this->primes[$i]);
+
+ $r = $r->modInverse($this->primes[$i]);
+ $x = $x->multiply($r);
+ list(, $x) = $x->divide($this->primes[$i]);
+
+ return $x;
+ }
+
+ /**
+ * Performs blinded RSA equality testing
+ *
+ * Protects against a particular type of timing attack described.
+ *
+ * See {@link http://codahale.com/a-lesson-in-timing-attacks/ A Lesson In Timing Attacks (or, Don't use MessageDigest.isEquals)}
+ *
+ * Thanks for the heads up singpolyma!
+ *
+ * @access private
+ * @param string $x
+ * @param string $y
+ * @return bool
+ */
+ function _equals($x, $y)
+ {
+ if (function_exists('hash_equals')) {
+ return hash_equals($x, $y);
+ }
+
+ if (strlen($x) != strlen($y)) {
+ return false;
+ }
+
+ $result = "\0";
+ $x^= $y;
+ for ($i = 0; $i < strlen($x); $i++) {
+ $result|= $x[$i];
+ }
+
+ return $result === "\0";
+ }
+
+ /**
+ * RSAEP
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}.
+ *
+ * @access private
+ * @param \phpseclib\Math\BigInteger $m
+ * @return \phpseclib\Math\BigInteger
+ */
+ function _rsaep($m)
+ {
+ if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
+ user_error('Message representative out of range');
+ return false;
+ }
+ return $this->_exponentiate($m);
+ }
+
+ /**
+ * RSADP
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}.
+ *
+ * @access private
+ * @param \phpseclib\Math\BigInteger $c
+ * @return \phpseclib\Math\BigInteger
+ */
+ function _rsadp($c)
+ {
+ if ($c->compare($this->zero) < 0 || $c->compare($this->modulus) > 0) {
+ user_error('Ciphertext representative out of range');
+ return false;
+ }
+ return $this->_exponentiate($c);
+ }
+
+ /**
+ * RSASP1
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}.
+ *
+ * @access private
+ * @param \phpseclib\Math\BigInteger $m
+ * @return \phpseclib\Math\BigInteger
+ */
+ function _rsasp1($m)
+ {
+ if ($m->compare($this->zero) < 0 || $m->compare($this->modulus) > 0) {
+ user_error('Message representative out of range');
+ return false;
+ }
+ return $this->_exponentiate($m);
+ }
+
+ /**
+ * RSAVP1
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}.
+ *
+ * @access private
+ * @param \phpseclib\Math\BigInteger $s
+ * @return \phpseclib\Math\BigInteger
+ */
+ function _rsavp1($s)
+ {
+ if ($s->compare($this->zero) < 0 || $s->compare($this->modulus) > 0) {
+ user_error('Signature representative out of range');
+ return false;
+ }
+ return $this->_exponentiate($s);
+ }
+
+ /**
+ * MGF1
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}.
+ *
+ * @access private
+ * @param string $mgfSeed
+ * @param int $mgfLen
+ * @return string
+ */
+ function _mgf1($mgfSeed, $maskLen)
+ {
+ // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output.
+
+ $t = '';
+ $count = ceil($maskLen / $this->mgfHLen);
+ for ($i = 0; $i < $count; $i++) {
+ $c = pack('N', $i);
+ $t.= $this->mgfHash->hash($mgfSeed . $c);
+ }
+
+ return substr($t, 0, $maskLen);
+ }
+
+ /**
+ * RSAES-OAEP-ENCRYPT
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and
+ * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}.
+ *
+ * @access private
+ * @param string $m
+ * @param string $l
+ * @return string
+ */
+ function _rsaes_oaep_encrypt($m, $l = '')
+ {
+ $mLen = strlen($m);
+
+ // Length checking
+
+ // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
+ // be output.
+
+ if ($mLen > $this->k - 2 * $this->hLen - 2) {
+ user_error('Message too long');
+ return false;
+ }
+
+ // EME-OAEP encoding
+
+ $lHash = $this->hash->hash($l);
+ $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2);
+ $db = $lHash . $ps . chr(1) . $m;
+ $seed = Random::string($this->hLen);
+ $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
+ $maskedDB = $db ^ $dbMask;
+ $seedMask = $this->_mgf1($maskedDB, $this->hLen);
+ $maskedSeed = $seed ^ $seedMask;
+ $em = chr(0) . $maskedSeed . $maskedDB;
+
+ // RSA encryption
+
+ $m = $this->_os2ip($em);
+ $c = $this->_rsaep($m);
+ $c = $this->_i2osp($c, $this->k);
+
+ // Output the ciphertext C
+
+ return $c;
+ }
+
+ /**
+ * RSAES-OAEP-DECRYPT
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error
+ * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2:
+ *
+ * Note. Care must be taken to ensure that an opponent cannot
+ * distinguish the different error conditions in Step 3.g, whether by
+ * error message or timing, or, more generally, learn partial
+ * information about the encoded message EM. Otherwise an opponent may
+ * be able to obtain useful information about the decryption of the
+ * ciphertext C, leading to a chosen-ciphertext attack such as the one
+ * observed by Manger [36].
+ *
+ * As for $l... to quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}:
+ *
+ * Both the encryption and the decryption operations of RSAES-OAEP take
+ * the value of a label L as input. In this version of PKCS #1, L is
+ * the empty string; other uses of the label are outside the scope of
+ * this document.
+ *
+ * @access private
+ * @param string $c
+ * @param string $l
+ * @return string
+ */
+ function _rsaes_oaep_decrypt($c, $l = '')
+ {
+ // Length checking
+
+ // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
+ // be output.
+
+ if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) {
+ user_error('Decryption error');
+ return false;
+ }
+
+ // RSA decryption
+
+ $c = $this->_os2ip($c);
+ $m = $this->_rsadp($c);
+ if ($m === false) {
+ user_error('Decryption error');
+ return false;
+ }
+ $em = $this->_i2osp($m, $this->k);
+
+ // EME-OAEP decoding
+
+ $lHash = $this->hash->hash($l);
+ $y = ord($em[0]);
+ $maskedSeed = substr($em, 1, $this->hLen);
+ $maskedDB = substr($em, $this->hLen + 1);
+ $seedMask = $this->_mgf1($maskedDB, $this->hLen);
+ $seed = $maskedSeed ^ $seedMask;
+ $dbMask = $this->_mgf1($seed, $this->k - $this->hLen - 1);
+ $db = $maskedDB ^ $dbMask;
+ $lHash2 = substr($db, 0, $this->hLen);
+ $m = substr($db, $this->hLen);
+ $hashesMatch = $this->_equals($lHash, $lHash2);
+ $leadingZeros = 1;
+ $patternMatch = 0;
+ $offset = 0;
+ for ($i = 0; $i < strlen($m); $i++) {
+ $patternMatch|= $leadingZeros & ($m[$i] === "\1");
+ $leadingZeros&= $m[$i] === "\0";
+ $offset+= $patternMatch ? 0 : 1;
+ }
+
+ // we do & instead of && to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation
+ // to protect against timing attacks
+ if (!$hashesMatch & !$patternMatch) {
+ user_error('Decryption error');
+ return false;
+ }
+
+ // Output the message M
+
+ return substr($m, $offset + 1);
+ }
+
+ /**
+ * Raw Encryption / Decryption
+ *
+ * Doesn't use padding and is not recommended.
+ *
+ * @access private
+ * @param string $m
+ * @return string
+ */
+ function _raw_encrypt($m)
+ {
+ $temp = $this->_os2ip($m);
+ $temp = $this->_rsaep($temp);
+ return $this->_i2osp($temp, $this->k);
+ }
+
+ /**
+ * RSAES-PKCS1-V1_5-ENCRYPT
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}.
+ *
+ * @access private
+ * @param string $m
+ * @return string
+ */
+ function _rsaes_pkcs1_v1_5_encrypt($m)
+ {
+ $mLen = strlen($m);
+
+ // Length checking
+
+ if ($mLen > $this->k - 11) {
+ user_error('Message too long');
+ return false;
+ }
+
+ // EME-PKCS1-v1_5 encoding
+
+ $psLen = $this->k - $mLen - 3;
+ $ps = '';
+ while (strlen($ps) != $psLen) {
+ $temp = Random::string($psLen - strlen($ps));
+ $temp = str_replace("\x00", '', $temp);
+ $ps.= $temp;
+ }
+ $type = 2;
+ // see the comments of _rsaes_pkcs1_v1_5_decrypt() to understand why this is being done
+ if (defined('CRYPT_RSA_PKCS15_COMPAT') && (!isset($this->publicExponent) || $this->exponent !== $this->publicExponent)) {
+ $type = 1;
+ // "The padding string PS shall consist of k-3-||D|| octets. ... for block type 01, they shall have value FF"
+ $ps = str_repeat("\xFF", $psLen);
+ }
+ $em = chr(0) . chr($type) . $ps . chr(0) . $m;
+
+ // RSA encryption
+ $m = $this->_os2ip($em);
+ $c = $this->_rsaep($m);
+ $c = $this->_i2osp($c, $this->k);
+
+ // Output the ciphertext C
+
+ return $c;
+ }
+
+ /**
+ * RSAES-PKCS1-V1_5-DECRYPT
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}.
+ *
+ * For compatibility purposes, this function departs slightly from the description given in RFC3447.
+ * The reason being that RFC2313#section-8.1 (PKCS#1 v1.5) states that ciphertext's encrypted by the
+ * private key should have the second byte set to either 0 or 1 and that ciphertext's encrypted by the
+ * public key should have the second byte set to 2. In RFC3447 (PKCS#1 v2.1), the second byte is supposed
+ * to be 2 regardless of which key is used. For compatibility purposes, we'll just check to make sure the
+ * second byte is 2 or less. If it is, we'll accept the decrypted string as valid.
+ *
+ * As a consequence of this, a private key encrypted ciphertext produced with \phpseclib\Crypt\RSA may not decrypt
+ * with a strictly PKCS#1 v1.5 compliant RSA implementation. Public key encrypted ciphertext's should but
+ * not private key encrypted ciphertext's.
+ *
+ * @access private
+ * @param string $c
+ * @return string
+ */
+ function _rsaes_pkcs1_v1_5_decrypt($c)
+ {
+ // Length checking
+
+ if (strlen($c) != $this->k) { // or if k < 11
+ user_error('Decryption error');
+ return false;
+ }
+
+ // RSA decryption
+
+ $c = $this->_os2ip($c);
+ $m = $this->_rsadp($c);
+
+ if ($m === false) {
+ user_error('Decryption error');
+ return false;
+ }
+ $em = $this->_i2osp($m, $this->k);
+
+ // EME-PKCS1-v1_5 decoding
+
+ if (ord($em[0]) != 0 || ord($em[1]) > 2) {
+ user_error('Decryption error');
+ return false;
+ }
+
+ $ps = substr($em, 2, strpos($em, chr(0), 2) - 2);
+ $m = substr($em, strlen($ps) + 3);
+
+ if (strlen($ps) < 8) {
+ user_error('Decryption error');
+ return false;
+ }
+
+ // Output M
+
+ return $m;
+ }
+
+ /**
+ * EMSA-PSS-ENCODE
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}.
+ *
+ * @access private
+ * @param string $m
+ * @param int $emBits
+ */
+ function _emsa_pss_encode($m, $emBits)
+ {
+ // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
+ // be output.
+
+ $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8)
+ $sLen = $this->sLen !== null ? $this->sLen : $this->hLen;
+
+ $mHash = $this->hash->hash($m);
+ if ($emLen < $this->hLen + $sLen + 2) {
+ user_error('Encoding error');
+ return false;
+ }
+
+ $salt = Random::string($sLen);
+ $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;
+ $h = $this->hash->hash($m2);
+ $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2);
+ $db = $ps . chr(1) . $salt;
+ $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);
+ $maskedDB = $db ^ $dbMask;
+ $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0];
+ $em = $maskedDB . $h . chr(0xBC);
+
+ return $em;
+ }
+
+ /**
+ * EMSA-PSS-VERIFY
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}.
+ *
+ * @access private
+ * @param string $m
+ * @param string $em
+ * @param int $emBits
+ * @return string
+ */
+ function _emsa_pss_verify($m, $em, $emBits)
+ {
+ // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error
+ // be output.
+
+ $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8);
+ $sLen = $this->sLen !== null ? $this->sLen : $this->hLen;
+
+ $mHash = $this->hash->hash($m);
+ if ($emLen < $this->hLen + $sLen + 2) {
+ return false;
+ }
+
+ if ($em[strlen($em) - 1] != chr(0xBC)) {
+ return false;
+ }
+
+ $maskedDB = substr($em, 0, -$this->hLen - 1);
+ $h = substr($em, -$this->hLen - 1, $this->hLen);
+ $temp = chr(0xFF << ($emBits & 7));
+ if ((~$maskedDB[0] & $temp) != $temp) {
+ return false;
+ }
+ $dbMask = $this->_mgf1($h, $emLen - $this->hLen - 1);
+ $db = $maskedDB ^ $dbMask;
+ $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0];
+ $temp = $emLen - $this->hLen - $sLen - 2;
+ if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) {
+ return false;
+ }
+ $salt = substr($db, $temp + 1); // should be $sLen long
+ $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt;
+ $h2 = $this->hash->hash($m2);
+ return $this->_equals($h, $h2);
+ }
+
+ /**
+ * RSASSA-PSS-SIGN
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}.
+ *
+ * @access private
+ * @param string $m
+ * @return string
+ */
+ function _rsassa_pss_sign($m)
+ {
+ // EMSA-PSS encoding
+
+ $em = $this->_emsa_pss_encode($m, 8 * $this->k - 1);
+
+ // RSA signature
+
+ $m = $this->_os2ip($em);
+ $s = $this->_rsasp1($m);
+ $s = $this->_i2osp($s, $this->k);
+
+ // Output the signature S
+
+ return $s;
+ }
+
+ /**
+ * RSASSA-PSS-VERIFY
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}.
+ *
+ * @access private
+ * @param string $m
+ * @param string $s
+ * @return string
+ */
+ function _rsassa_pss_verify($m, $s)
+ {
+ // Length checking
+
+ if (strlen($s) != $this->k) {
+ user_error('Invalid signature');
+ return false;
+ }
+
+ // RSA verification
+
+ $modBits = strlen($this->modulus->toBits());
+
+ $s2 = $this->_os2ip($s);
+ $m2 = $this->_rsavp1($s2);
+ if ($m2 === false) {
+ user_error('Invalid signature');
+ return false;
+ }
+ $em = $this->_i2osp($m2, $this->k);
+ if ($em === false) {
+ user_error('Invalid signature');
+ return false;
+ }
+
+ // EMSA-PSS verification
+
+ return $this->_emsa_pss_verify($m, $em, $modBits - 1);
+ }
+
+ /**
+ * EMSA-PKCS1-V1_5-ENCODE
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}.
+ *
+ * @access private
+ * @param string $m
+ * @param int $emLen
+ * @return string
+ */
+ function _emsa_pkcs1_v1_5_encode($m, $emLen)
+ {
+ $h = $this->hash->hash($m);
+ if ($h === false) {
+ return false;
+ }
+
+ // see http://tools.ietf.org/html/rfc3447#page-43
+ switch ($this->hashName) {
+ case 'md2':
+ $t = pack('H*', '3020300c06082a864886f70d020205000410');
+ break;
+ case 'md5':
+ $t = pack('H*', '3020300c06082a864886f70d020505000410');
+ break;
+ case 'sha1':
+ $t = pack('H*', '3021300906052b0e03021a05000414');
+ break;
+ case 'sha256':
+ $t = pack('H*', '3031300d060960864801650304020105000420');
+ break;
+ case 'sha384':
+ $t = pack('H*', '3041300d060960864801650304020205000430');
+ break;
+ case 'sha512':
+ $t = pack('H*', '3051300d060960864801650304020305000440');
+ }
+ $t.= $h;
+ $tLen = strlen($t);
+
+ if ($emLen < $tLen + 11) {
+ user_error('Intended encoded message length too short');
+ return false;
+ }
+
+ $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3);
+
+ $em = "\0\1$ps\0$t";
+
+ return $em;
+ }
+
+ /**
+ * RSASSA-PKCS1-V1_5-SIGN
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}.
+ *
+ * @access private
+ * @param string $m
+ * @return string
+ */
+ function _rsassa_pkcs1_v1_5_sign($m)
+ {
+ // EMSA-PKCS1-v1_5 encoding
+
+ $em = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
+ if ($em === false) {
+ user_error('RSA modulus too short');
+ return false;
+ }
+
+ // RSA signature
+
+ $m = $this->_os2ip($em);
+ $s = $this->_rsasp1($m);
+ $s = $this->_i2osp($s, $this->k);
+
+ // Output the signature S
+
+ return $s;
+ }
+
+ /**
+ * RSASSA-PKCS1-V1_5-VERIFY
+ *
+ * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}.
+ *
+ * @access private
+ * @param string $m
+ * @return string
+ */
+ function _rsassa_pkcs1_v1_5_verify($m, $s)
+ {
+ // Length checking
+
+ if (strlen($s) != $this->k) {
+ user_error('Invalid signature');
+ return false;
+ }
+
+ // RSA verification
+
+ $s = $this->_os2ip($s);
+ $m2 = $this->_rsavp1($s);
+ if ($m2 === false) {
+ user_error('Invalid signature');
+ return false;
+ }
+ $em = $this->_i2osp($m2, $this->k);
+ if ($em === false) {
+ user_error('Invalid signature');
+ return false;
+ }
+
+ // EMSA-PKCS1-v1_5 encoding
+
+ $em2 = $this->_emsa_pkcs1_v1_5_encode($m, $this->k);
+ if ($em2 === false) {
+ user_error('RSA modulus too short');
+ return false;
+ }
+
+ // Compare
+ return $this->_equals($em, $em2);
+ }
+
+ /**
+ * Set Encryption Mode
+ *
+ * Valid values include self::ENCRYPTION_OAEP and self::ENCRYPTION_PKCS1.
+ *
+ * @access public
+ * @param int $mode
+ */
+ function setEncryptionMode($mode)
+ {
+ $this->encryptionMode = $mode;
+ }
+
+ /**
+ * Set Signature Mode
+ *
+ * Valid values include self::SIGNATURE_PSS and self::SIGNATURE_PKCS1
+ *
+ * @access public
+ * @param int $mode
+ */
+ function setSignatureMode($mode)
+ {
+ $this->signatureMode = $mode;
+ }
+
+ /**
+ * Set public key comment.
+ *
+ * @access public
+ * @param string $comment
+ */
+ function setComment($comment)
+ {
+ $this->comment = $comment;
+ }
+
+ /**
+ * Get public key comment.
+ *
+ * @access public
+ * @return string
+ */
+ function getComment()
+ {
+ return $this->comment;
+ }
+
+ /**
+ * Encryption
+ *
+ * Both self::ENCRYPTION_OAEP and self::ENCRYPTION_PKCS1 both place limits on how long $plaintext can be.
+ * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will
+ * be concatenated together.
+ *
+ * @see self::decrypt()
+ * @access public
+ * @param string $plaintext
+ * @return string
+ */
+ function encrypt($plaintext)
+ {
+ switch ($this->encryptionMode) {
+ case self::ENCRYPTION_NONE:
+ $plaintext = str_split($plaintext, $this->k);
+ $ciphertext = '';
+ foreach ($plaintext as $m) {
+ $ciphertext.= $this->_raw_encrypt($m);
+ }
+ return $ciphertext;
+ case self::ENCRYPTION_PKCS1:
+ $length = $this->k - 11;
+ if ($length <= 0) {
+ return false;
+ }
+
+ $plaintext = str_split($plaintext, $length);
+ $ciphertext = '';
+ foreach ($plaintext as $m) {
+ $ciphertext.= $this->_rsaes_pkcs1_v1_5_encrypt($m);
+ }
+ return $ciphertext;
+ //case self::ENCRYPTION_OAEP:
+ default:
+ $length = $this->k - 2 * $this->hLen - 2;
+ if ($length <= 0) {
+ return false;
+ }
+
+ $plaintext = str_split($plaintext, $length);
+ $ciphertext = '';
+ foreach ($plaintext as $m) {
+ $ciphertext.= $this->_rsaes_oaep_encrypt($m);
+ }
+ return $ciphertext;
+ }
+ }
+
+ /**
+ * Decryption
+ *
+ * @see self::encrypt()
+ * @access public
+ * @param string $plaintext
+ * @return string
+ */
+ function decrypt($ciphertext)
+ {
+ if ($this->k <= 0) {
+ return false;
+ }
+
+ $ciphertext = str_split($ciphertext, $this->k);
+ $ciphertext[count($ciphertext) - 1] = str_pad($ciphertext[count($ciphertext) - 1], $this->k, chr(0), STR_PAD_LEFT);
+
+ $plaintext = '';
+
+ switch ($this->encryptionMode) {
+ case self::ENCRYPTION_NONE:
+ $decrypt = '_raw_encrypt';
+ break;
+ case self::ENCRYPTION_PKCS1:
+ $decrypt = '_rsaes_pkcs1_v1_5_decrypt';
+ break;
+ //case self::ENCRYPTION_OAEP:
+ default:
+ $decrypt = '_rsaes_oaep_decrypt';
+ }
+
+ foreach ($ciphertext as $c) {
+ $temp = $this->$decrypt($c);
+ if ($temp === false) {
+ return false;
+ }
+ $plaintext.= $temp;
+ }
+
+ return $plaintext;
+ }
+
+ /**
+ * Create a signature
+ *
+ * @see self::verify()
+ * @access public
+ * @param string $message
+ * @return string
+ */
+ function sign($message)
+ {
+ if (empty($this->modulus) || empty($this->exponent)) {
+ return false;
+ }
+
+ switch ($this->signatureMode) {
+ case self::SIGNATURE_PKCS1:
+ return $this->_rsassa_pkcs1_v1_5_sign($message);
+ //case self::SIGNATURE_PSS:
+ default:
+ return $this->_rsassa_pss_sign($message);
+ }
+ }
+
+ /**
+ * Verifies a signature
+ *
+ * @see self::sign()
+ * @access public
+ * @param string $message
+ * @param string $signature
+ * @return bool
+ */
+ function verify($message, $signature)
+ {
+ if (empty($this->modulus) || empty($this->exponent)) {
+ return false;
+ }
+
+ switch ($this->signatureMode) {
+ case self::SIGNATURE_PKCS1:
+ return $this->_rsassa_pkcs1_v1_5_verify($message, $signature);
+ //case self::SIGNATURE_PSS:
+ default:
+ return $this->_rsassa_pss_verify($message, $signature);
+ }
+ }
+
+ /**
+ * Extract raw BER from Base64 encoding
+ *
+ * @access private
+ * @param string $str
+ * @return string
+ */
+ function _extractBER($str)
+ {
+ /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
+ * above and beyond the ceritificate.
+ * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
+ *
+ * Bag Attributes
+ * localKeyID: 01 00 00 00
+ * subject=/O=organization/OU=org unit/CN=common name
+ * issuer=/O=organization/CN=common name
+ */
+ $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1);
+ // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
+ $temp = preg_replace('#-+[^-]+-+#', '', $temp);
+ // remove new lines
+ $temp = str_replace(array("\r", "\n", ' '), '', $temp);
+ $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
+ return $temp != false ? $temp : $str;
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php
new file mode 100644
index 0000000..8f53eb3
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php
@@ -0,0 +1,277 @@
+<?php
+
+/**
+ * Random Number Generator
+ *
+ * PHP version 5
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * echo bin2hex(\phpseclib\Crypt\Random::string(8));
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package Random
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP Random Number Generator
+ *
+ * @package Random
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class Random
+{
+ /**
+ * Generate a random string.
+ *
+ * Although microoptimizations are generally discouraged as they impair readability this function is ripe with
+ * microoptimizations because this function has the potential of being called a huge number of times.
+ * eg. for RSA key generation.
+ *
+ * @param int $length
+ * @return string
+ */
+ static function string($length)
+ {
+ if (!$length) {
+ return '';
+ }
+
+ if (version_compare(PHP_VERSION, '7.0.0', '>=')) {
+ try {
+ return \random_bytes($length);
+ } catch (\Throwable $e) {
+ // If a sufficient source of randomness is unavailable, random_bytes() will throw an
+ // object that implements the Throwable interface (Exception, TypeError, Error).
+ // We don't actually need to do anything here. The string() method should just continue
+ // as normal. Note, however, that if we don't have a sufficient source of randomness for
+ // random_bytes(), most of the other calls here will fail too, so we'll end up using
+ // the PHP implementation.
+ }
+ }
+
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+ // method 1. prior to PHP 5.3 this would call rand() on windows hence the function_exists('class_alias') call.
+ // ie. class_alias is a function that was introduced in PHP 5.3
+ if (extension_loaded('mcrypt') && function_exists('class_alias')) {
+ return @mcrypt_create_iv($length);
+ }
+ // method 2. openssl_random_pseudo_bytes was introduced in PHP 5.3.0 but prior to PHP 5.3.4 there was,
+ // to quote <http://php.net/ChangeLog-5.php#5.3.4>, "possible blocking behavior". as of 5.3.4
+ // openssl_random_pseudo_bytes and mcrypt_create_iv do the exact same thing on Windows. ie. they both
+ // call php_win32_get_random_bytes():
+ //
+ // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/openssl/openssl.c#L5008
+ // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1392
+ //
+ // php_win32_get_random_bytes() is defined thusly:
+ //
+ // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/win32/winutil.c#L80
+ //
+ // we're calling it, all the same, in the off chance that the mcrypt extension is not available
+ if (extension_loaded('openssl') && version_compare(PHP_VERSION, '5.3.4', '>=')) {
+ return openssl_random_pseudo_bytes($length);
+ }
+ } else {
+ // method 1. the fastest
+ if (extension_loaded('openssl')) {
+ return openssl_random_pseudo_bytes($length);
+ }
+ // method 2
+ static $fp = true;
+ if ($fp === true) {
+ // warning's will be output unles the error suppression operator is used. errors such as
+ // "open_basedir restriction in effect", "Permission denied", "No such file or directory", etc.
+ $fp = @fopen('/dev/urandom', 'rb');
+ }
+ if ($fp !== true && $fp !== false) { // surprisingly faster than !is_bool() or is_resource()
+ $temp = fread($fp, $length);
+ if (strlen($temp) == $length) {
+ return $temp;
+ }
+ }
+ // method 3. pretty much does the same thing as method 2 per the following url:
+ // https://github.com/php/php-src/blob/7014a0eb6d1611151a286c0ff4f2238f92c120d6/ext/mcrypt/mcrypt.c#L1391
+ // surprisingly slower than method 2. maybe that's because mcrypt_create_iv does a bunch of error checking that we're
+ // not doing. regardless, this'll only be called if this PHP script couldn't open /dev/urandom due to open_basedir
+ // restrictions or some such
+ if (extension_loaded('mcrypt')) {
+ return @mcrypt_create_iv($length, MCRYPT_DEV_URANDOM);
+ }
+ }
+ // at this point we have no choice but to use a pure-PHP CSPRNG
+
+ // cascade entropy across multiple PHP instances by fixing the session and collecting all
+ // environmental variables, including the previous session data and the current session
+ // data.
+ //
+ // mt_rand seeds itself by looking at the PID and the time, both of which are (relatively)
+ // easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but
+ // PHP isn't low level to be able to use those as sources and on a web server there's not likely
+ // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use
+ // however, a ton of people visiting the website. obviously you don't want to base your seeding
+ // soley on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled
+ // by the user and (2) this isn't just looking at the data sent by the current user - it's based
+ // on the data sent by all users. one user requests the page and a hash of their info is saved.
+ // another user visits the page and the serialization of their data is utilized along with the
+ // server envirnment stuff and a hash of the previous http request data (which itself utilizes
+ // a hash of the session data before that). certainly an attacker should be assumed to have
+ // full control over his own http requests. he, however, is not going to have control over
+ // everyone's http requests.
+ static $crypto = false, $v;
+ if ($crypto === false) {
+ // save old session data
+ $old_session_id = session_id();
+ $old_use_cookies = ini_get('session.use_cookies');
+ $old_session_cache_limiter = session_cache_limiter();
+ $_OLD_SESSION = isset($_SESSION) ? $_SESSION : false;
+ if ($old_session_id != '') {
+ session_write_close();
+ }
+
+ session_id(1);
+ ini_set('session.use_cookies', 0);
+ session_cache_limiter('');
+ session_start();
+
+ $v = $seed = $_SESSION['seed'] = pack('H*', sha1(
+ (isset($_SERVER) ? phpseclib_safe_serialize($_SERVER) : '') .
+ (isset($_POST) ? phpseclib_safe_serialize($_POST) : '') .
+ (isset($_GET) ? phpseclib_safe_serialize($_GET) : '') .
+ (isset($_COOKIE) ? phpseclib_safe_serialize($_COOKIE) : '') .
+ phpseclib_safe_serialize($GLOBALS) .
+ phpseclib_safe_serialize($_SESSION) .
+ phpseclib_safe_serialize($_OLD_SESSION)
+ ));
+ if (!isset($_SESSION['count'])) {
+ $_SESSION['count'] = 0;
+ }
+ $_SESSION['count']++;
+
+ session_write_close();
+
+ // restore old session data
+ if ($old_session_id != '') {
+ session_id($old_session_id);
+ session_start();
+ ini_set('session.use_cookies', $old_use_cookies);
+ session_cache_limiter($old_session_cache_limiter);
+ } else {
+ if ($_OLD_SESSION !== false) {
+ $_SESSION = $_OLD_SESSION;
+ unset($_OLD_SESSION);
+ } else {
+ unset($_SESSION);
+ }
+ }
+
+ // in SSH2 a shared secret and an exchange hash are generated through the key exchange process.
+ // the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C.
+ // if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the
+ // original hash and the current hash. we'll be emulating that. for more info see the following URL:
+ //
+ // http://tools.ietf.org/html/rfc4253#section-7.2
+ //
+ // see the is_string($crypto) part for an example of how to expand the keys
+ $key = pack('H*', sha1($seed . 'A'));
+ $iv = pack('H*', sha1($seed . 'C'));
+
+ // ciphers are used as per the nist.gov link below. also, see this link:
+ //
+ // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives
+ switch (true) {
+ case class_exists('\phpseclib\Crypt\AES'):
+ $crypto = new AES(Base::MODE_CTR);
+ break;
+ case class_exists('\phpseclib\Crypt\Twofish'):
+ $crypto = new Twofish(Base::MODE_CTR);
+ break;
+ case class_exists('\phpseclib\Crypt\Blowfish'):
+ $crypto = new Blowfish(Base::MODE_CTR);
+ break;
+ case class_exists('\phpseclib\Crypt\TripleDES'):
+ $crypto = new TripleDES(Base::MODE_CTR);
+ break;
+ case class_exists('\phpseclib\Crypt\DES'):
+ $crypto = new DES(Base::MODE_CTR);
+ break;
+ case class_exists('\phpseclib\Crypt\RC4'):
+ $crypto = new RC4();
+ break;
+ default:
+ user_error(__CLASS__ . ' requires at least one symmetric cipher be loaded');
+ return false;
+ }
+
+ $crypto->setKey($key);
+ $crypto->setIV($iv);
+ $crypto->enableContinuousBuffer();
+ }
+
+ //return $crypto->encrypt(str_repeat("\0", $length));
+
+ // the following is based off of ANSI X9.31:
+ //
+ // http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf
+ //
+ // OpenSSL uses that same standard for it's random numbers:
+ //
+ // http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c
+ // (do a search for "ANS X9.31 A.2.4")
+ $result = '';
+ while (strlen($result) < $length) {
+ $i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21
+ $r = $crypto->encrypt($i ^ $v); // strlen($v) == 20
+ $v = $crypto->encrypt($r ^ $i); // strlen($r) == 20
+ $result.= $r;
+ }
+ return substr($result, 0, $length);
+ }
+}
+
+if (!function_exists('phpseclib_safe_serialize')) {
+ /**
+ * Safely serialize variables
+ *
+ * If a class has a private __sleep() method it'll give a fatal error on PHP 5.2 and earlier.
+ * PHP 5.3 will emit a warning.
+ *
+ * @param mixed $arr
+ * @access public
+ */
+ function phpseclib_safe_serialize(&$arr)
+ {
+ if (is_object($arr)) {
+ return '';
+ }
+ if (!is_array($arr)) {
+ return serialize($arr);
+ }
+ // prevent circular array recursion
+ if (isset($arr['__phpseclib_marker'])) {
+ return '';
+ }
+ $safearr = array();
+ $arr['__phpseclib_marker'] = true;
+ foreach (array_keys($arr) as $key) {
+ // do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage
+ if ($key !== '__phpseclib_marker') {
+ $safearr[$key] = phpseclib_safe_serialize($arr[$key]);
+ }
+ }
+ unset($arr['__phpseclib_marker']);
+ return serialize($safearr);
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
new file mode 100644
index 0000000..3648a19
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php
@@ -0,0 +1,936 @@
+<?php
+
+/**
+ * Pure-PHP implementation of Rijndael.
+ *
+ * Uses mcrypt, if available/possible, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * If {@link self::setBlockLength() setBlockLength()} isn't called, it'll be assumed to be 128 bits. If
+ * {@link self::setKeyLength() setKeyLength()} isn't called, it'll be calculated from
+ * {@link self::setKey() setKey()}. ie. if the key is 128-bits, the key length will be 128-bits. If it's
+ * 136-bits it'll be null-padded to 192-bits and 192 bits will be the key length until
+ * {@link self::setKey() setKey()} is called, again, at which point, it'll be recalculated.
+ *
+ * Not all Rijndael implementations may support 160-bits or 224-bits as the block length / key length. mcrypt, for example,
+ * does not. AES, itself, only supports block lengths of 128 and key lengths of 128, 192, and 256.
+ * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=10 Rijndael-ammended.pdf#page=10} defines the
+ * algorithm for block lengths of 192 and 256 but not for block lengths / key lengths of 160 and 224. Indeed, 160 and 224
+ * are first defined as valid key / block lengths in
+ * {@link http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=44 Rijndael-ammended.pdf#page=44}:
+ * Extensions: Other block and Cipher Key lengths.
+ * Note: Use of 160/224-bit Keys must be explicitly set by setKeyLength(160) respectively setKeyLength(224).
+ *
+ * {@internal The variable names are the same as those in
+ * {@link http://www.csrc.nist.gov/publications/fips/fips197/fips-197.pdf#page=10 fips-197.pdf#page=10}.}}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $rijndael = new \phpseclib\Crypt\Rijndael();
+ *
+ * $rijndael->setKey('abcdefghijklmnop');
+ *
+ * $size = 10 * 1024;
+ * $plaintext = '';
+ * for ($i = 0; $i < $size; $i++) {
+ * $plaintext.= 'a';
+ * }
+ *
+ * echo $rijndael->decrypt($rijndael->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package Rijndael
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2008 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of Rijndael.
+ *
+ * @package Rijndael
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class Rijndael extends Base
+{
+ /**
+ * The mcrypt specific name of the cipher
+ *
+ * Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not.
+ * \phpseclib\Crypt\Rijndael determines automatically whether mcrypt is useable
+ * or not for the current $block_size/$key_length.
+ * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly.
+ *
+ * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+ * @see \phpseclib\Crypt\Base::engine
+ * @see self::isValidEngine()
+ * @var string
+ * @access private
+ */
+ var $cipher_name_mcrypt = 'rijndael-128';
+
+ /**
+ * The default salt used by setPassword()
+ *
+ * @see \phpseclib\Crypt\Base::password_default_salt
+ * @see \phpseclib\Crypt\Base::setPassword()
+ * @var string
+ * @access private
+ */
+ var $password_default_salt = 'phpseclib';
+
+ /**
+ * The Key Schedule
+ *
+ * @see self::_setup()
+ * @var array
+ * @access private
+ */
+ var $w;
+
+ /**
+ * The Inverse Key Schedule
+ *
+ * @see self::_setup()
+ * @var array
+ * @access private
+ */
+ var $dw;
+
+ /**
+ * The Block Length divided by 32
+ *
+ * @see self::setBlockLength()
+ * @var int
+ * @access private
+ * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size
+ * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could
+ * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
+ * of that, we'll just precompute it once.
+ */
+ var $Nb = 4;
+
+ /**
+ * The Key Length (in bytes)
+ *
+ * @see self::setKeyLength()
+ * @var int
+ * @access private
+ * @internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk
+ * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could
+ * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu
+ * of that, we'll just precompute it once.
+ */
+ var $key_length = 16;
+
+ /**
+ * The Key Length divided by 32
+ *
+ * @see self::setKeyLength()
+ * @var int
+ * @access private
+ * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4
+ */
+ var $Nk = 4;
+
+ /**
+ * The Number of Rounds
+ *
+ * @var int
+ * @access private
+ * @internal The max value is 14, the min value is 10.
+ */
+ var $Nr;
+
+ /**
+ * Shift offsets
+ *
+ * @var array
+ * @access private
+ */
+ var $c;
+
+ /**
+ * Holds the last used key- and block_size information
+ *
+ * @var array
+ * @access private
+ */
+ var $kl;
+
+ /**
+ * Sets the key length.
+ *
+ * Valid key lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
+ * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
+ *
+ * Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined
+ * and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to
+ * 192/256 bits as, for example, mcrypt will do.
+ *
+ * That said, if you want be compatible with other Rijndael and AES implementations,
+ * you should not setKeyLength(160) or setKeyLength(224).
+ *
+ * Additional: In case of 160- and 224-bit keys, phpseclib will/can, for that reason, not use
+ * the mcrypt php extension, even if available.
+ * This results then in slower encryption.
+ *
+ * @access public
+ * @param int $length
+ */
+ function setKeyLength($length)
+ {
+ switch (true) {
+ case $length <= 128:
+ $this->key_length = 16;
+ break;
+ case $length <= 160:
+ $this->key_length = 20;
+ break;
+ case $length <= 192:
+ $this->key_length = 24;
+ break;
+ case $length <= 224:
+ $this->key_length = 28;
+ break;
+ default:
+ $this->key_length = 32;
+ }
+
+ parent::setKeyLength($length);
+ }
+
+ /**
+ * Sets the block length
+ *
+ * Valid block lengths are 128, 160, 192, 224, and 256. If the length is less than 128, it will be rounded up to
+ * 128. If the length is greater than 128 and invalid, it will be rounded down to the closest valid amount.
+ *
+ * @access public
+ * @param int $length
+ */
+ function setBlockLength($length)
+ {
+ $length >>= 5;
+ if ($length > 8) {
+ $length = 8;
+ } elseif ($length < 4) {
+ $length = 4;
+ }
+ $this->Nb = $length;
+ $this->block_size = $length << 2;
+ $this->changed = true;
+ $this->_setEngine();
+ }
+
+ /**
+ * Test for engine validity
+ *
+ * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+ *
+ * @see \phpseclib\Crypt\Base::__construct()
+ * @param int $engine
+ * @access public
+ * @return bool
+ */
+ function isValidEngine($engine)
+ {
+ switch ($engine) {
+ case self::ENGINE_OPENSSL:
+ if ($this->block_size != 16) {
+ return false;
+ }
+ $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb';
+ $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->_openssl_translate_mode();
+ break;
+ case self::ENGINE_MCRYPT:
+ $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3);
+ if ($this->key_length % 8) { // is it a 160/224-bit key?
+ // mcrypt is not usable for them, only for 128/192/256-bit keys
+ return false;
+ }
+ }
+
+ return parent::isValidEngine($engine);
+ }
+
+ /**
+ * Encrypts a block
+ *
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ function _encryptBlock($in)
+ {
+ static $tables;
+ if (empty($tables)) {
+ $tables = &$this->_getTables();
+ }
+ $t0 = $tables[0];
+ $t1 = $tables[1];
+ $t2 = $tables[2];
+ $t3 = $tables[3];
+ $sbox = $tables[4];
+
+ $state = array();
+ $words = unpack('N*', $in);
+
+ $c = $this->c;
+ $w = $this->w;
+ $Nb = $this->Nb;
+ $Nr = $this->Nr;
+
+ // addRoundKey
+ $wc = $Nb - 1;
+ foreach ($words as $word) {
+ $state[] = $word ^ $w[++$wc];
+ }
+
+ // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components -
+ // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding
+ // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf.
+ // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization.
+ // Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1],
+ // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well.
+
+ // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf
+ $temp = array();
+ for ($round = 1; $round < $Nr; ++$round) {
+ $i = 0; // $c[0] == 0
+ $j = $c[1];
+ $k = $c[2];
+ $l = $c[3];
+
+ while ($i < $Nb) {
+ $temp[$i] = $t0[$state[$i] >> 24 & 0x000000FF] ^
+ $t1[$state[$j] >> 16 & 0x000000FF] ^
+ $t2[$state[$k] >> 8 & 0x000000FF] ^
+ $t3[$state[$l] & 0x000000FF] ^
+ $w[++$wc];
+ ++$i;
+ $j = ($j + 1) % $Nb;
+ $k = ($k + 1) % $Nb;
+ $l = ($l + 1) % $Nb;
+ }
+ $state = $temp;
+ }
+
+ // subWord
+ for ($i = 0; $i < $Nb; ++$i) {
+ $state[$i] = $sbox[$state[$i] & 0x000000FF] |
+ ($sbox[$state[$i] >> 8 & 0x000000FF] << 8) |
+ ($sbox[$state[$i] >> 16 & 0x000000FF] << 16) |
+ ($sbox[$state[$i] >> 24 & 0x000000FF] << 24);
+ }
+
+ // shiftRows + addRoundKey
+ $i = 0; // $c[0] == 0
+ $j = $c[1];
+ $k = $c[2];
+ $l = $c[3];
+ while ($i < $Nb) {
+ $temp[$i] = ($state[$i] & 0xFF000000) ^
+ ($state[$j] & 0x00FF0000) ^
+ ($state[$k] & 0x0000FF00) ^
+ ($state[$l] & 0x000000FF) ^
+ $w[$i];
+ ++$i;
+ $j = ($j + 1) % $Nb;
+ $k = ($k + 1) % $Nb;
+ $l = ($l + 1) % $Nb;
+ }
+
+ switch ($Nb) {
+ case 8:
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
+ case 7:
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
+ case 6:
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
+ case 5:
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
+ default:
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
+ }
+ }
+
+ /**
+ * Decrypts a block
+ *
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ function _decryptBlock($in)
+ {
+ static $invtables;
+ if (empty($invtables)) {
+ $invtables = &$this->_getInvTables();
+ }
+ $dt0 = $invtables[0];
+ $dt1 = $invtables[1];
+ $dt2 = $invtables[2];
+ $dt3 = $invtables[3];
+ $isbox = $invtables[4];
+
+ $state = array();
+ $words = unpack('N*', $in);
+
+ $c = $this->c;
+ $dw = $this->dw;
+ $Nb = $this->Nb;
+ $Nr = $this->Nr;
+
+ // addRoundKey
+ $wc = $Nb - 1;
+ foreach ($words as $word) {
+ $state[] = $word ^ $dw[++$wc];
+ }
+
+ $temp = array();
+ for ($round = $Nr - 1; $round > 0; --$round) {
+ $i = 0; // $c[0] == 0
+ $j = $Nb - $c[1];
+ $k = $Nb - $c[2];
+ $l = $Nb - $c[3];
+
+ while ($i < $Nb) {
+ $temp[$i] = $dt0[$state[$i] >> 24 & 0x000000FF] ^
+ $dt1[$state[$j] >> 16 & 0x000000FF] ^
+ $dt2[$state[$k] >> 8 & 0x000000FF] ^
+ $dt3[$state[$l] & 0x000000FF] ^
+ $dw[++$wc];
+ ++$i;
+ $j = ($j + 1) % $Nb;
+ $k = ($k + 1) % $Nb;
+ $l = ($l + 1) % $Nb;
+ }
+ $state = $temp;
+ }
+
+ // invShiftRows + invSubWord + addRoundKey
+ $i = 0; // $c[0] == 0
+ $j = $Nb - $c[1];
+ $k = $Nb - $c[2];
+ $l = $Nb - $c[3];
+
+ while ($i < $Nb) {
+ $word = ($state[$i] & 0xFF000000) |
+ ($state[$j] & 0x00FF0000) |
+ ($state[$k] & 0x0000FF00) |
+ ($state[$l] & 0x000000FF);
+
+ $temp[$i] = $dw[$i] ^ ($isbox[$word & 0x000000FF] |
+ ($isbox[$word >> 8 & 0x000000FF] << 8) |
+ ($isbox[$word >> 16 & 0x000000FF] << 16) |
+ ($isbox[$word >> 24 & 0x000000FF] << 24));
+ ++$i;
+ $j = ($j + 1) % $Nb;
+ $k = ($k + 1) % $Nb;
+ $l = ($l + 1) % $Nb;
+ }
+
+ switch ($Nb) {
+ case 8:
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6], $temp[7]);
+ case 7:
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5], $temp[6]);
+ case 6:
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4], $temp[5]);
+ case 5:
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3], $temp[4]);
+ default:
+ return pack('N*', $temp[0], $temp[1], $temp[2], $temp[3]);
+ }
+ }
+
+ /**
+ * Setup the key (expansion)
+ *
+ * @see \phpseclib\Crypt\Base::_setupKey()
+ * @access private
+ */
+ function _setupKey()
+ {
+ // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field.
+ // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse
+ static $rcon = array(0,
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
+ 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000,
+ 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000,
+ 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000,
+ 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000,
+ 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000
+ );
+
+ if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) {
+ // already expanded
+ return;
+ }
+ $this->kl = array('key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size);
+
+ $this->Nk = $this->key_length >> 2;
+ // see Rijndael-ammended.pdf#page=44
+ $this->Nr = max($this->Nk, $this->Nb) + 6;
+
+ // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44,
+ // "Table 8: Shift offsets in Shiftrow for the alternative block lengths"
+ // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14,
+ // "Table 2: Shift offsets for different block lengths"
+ switch ($this->Nb) {
+ case 4:
+ case 5:
+ case 6:
+ $this->c = array(0, 1, 2, 3);
+ break;
+ case 7:
+ $this->c = array(0, 1, 2, 4);
+ break;
+ case 8:
+ $this->c = array(0, 1, 3, 4);
+ }
+
+ $w = array_values(unpack('N*words', $this->key));
+
+ $length = $this->Nb * ($this->Nr + 1);
+ for ($i = $this->Nk; $i < $length; $i++) {
+ $temp = $w[$i - 1];
+ if ($i % $this->Nk == 0) {
+ // according to <http://php.net/language.types.integer>, "the size of an integer is platform-dependent".
+ // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine,
+ // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and'
+ // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is.
+ $temp = (($temp << 8) & 0xFFFFFF00) | (($temp >> 24) & 0x000000FF); // rotWord
+ $temp = $this->_subWord($temp) ^ $rcon[$i / $this->Nk];
+ } elseif ($this->Nk > 6 && $i % $this->Nk == 4) {
+ $temp = $this->_subWord($temp);
+ }
+ $w[$i] = $w[$i - $this->Nk] ^ $temp;
+ }
+
+ // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns
+ // and generate the inverse key schedule. more specifically,
+ // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=23> (section 5.3.3),
+ // "The key expansion for the Inverse Cipher is defined as follows:
+ // 1. Apply the Key Expansion.
+ // 2. Apply InvMixColumn to all Round Keys except the first and the last one."
+ // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher"
+ list($dt0, $dt1, $dt2, $dt3) = $this->_getInvTables();
+ $temp = $this->w = $this->dw = array();
+ for ($i = $row = $col = 0; $i < $length; $i++, $col++) {
+ if ($col == $this->Nb) {
+ if ($row == 0) {
+ $this->dw[0] = $this->w[0];
+ } else {
+ // subWord + invMixColumn + invSubWord = invMixColumn
+ $j = 0;
+ while ($j < $this->Nb) {
+ $dw = $this->_subWord($this->w[$row][$j]);
+ $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^
+ $dt1[$dw >> 16 & 0x000000FF] ^
+ $dt2[$dw >> 8 & 0x000000FF] ^
+ $dt3[$dw & 0x000000FF];
+ $j++;
+ }
+ $this->dw[$row] = $temp;
+ }
+
+ $col = 0;
+ $row++;
+ }
+ $this->w[$row][$col] = $w[$i];
+ }
+
+ $this->dw[$row] = $this->w[$row];
+
+ // Converting to 1-dim key arrays (both ascending)
+ $this->dw = array_reverse($this->dw);
+ $w = array_pop($this->w);
+ $dw = array_pop($this->dw);
+ foreach ($this->w as $r => $wr) {
+ foreach ($wr as $c => $wc) {
+ $w[] = $wc;
+ $dw[] = $this->dw[$r][$c];
+ }
+ }
+ $this->w = $w;
+ $this->dw = $dw;
+ }
+
+ /**
+ * Performs S-Box substitutions
+ *
+ * @access private
+ * @param int $word
+ */
+ function _subWord($word)
+ {
+ static $sbox;
+ if (empty($sbox)) {
+ list(, , , , $sbox) = $this->_getTables();
+ }
+
+ return $sbox[$word & 0x000000FF] |
+ ($sbox[$word >> 8 & 0x000000FF] << 8) |
+ ($sbox[$word >> 16 & 0x000000FF] << 16) |
+ ($sbox[$word >> 24 & 0x000000FF] << 24);
+ }
+
+ /**
+ * Provides the mixColumns and sboxes tables
+ *
+ * @see self::_encryptBlock()
+ * @see self::_setupInlineCrypt()
+ * @see self::_subWord()
+ * @access private
+ * @return array &$tables
+ */
+ function &_getTables()
+ {
+ static $tables;
+ if (empty($tables)) {
+ // according to <http://csrc.nist.gov/archive/aes/rijndael/Rijndael-ammended.pdf#page=19> (section 5.2.1),
+ // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so
+ // those are the names we'll use.
+ $t3 = array_map('intval', array(
+ // with array_map('intval', ...) we ensure we have only int's and not
+ // some slower floats converted by php automatically on high values
+ 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491,
+ 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC,
+ 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB,
+ 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B,
+ 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83,
+ 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A,
+ 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F,
+ 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA,
+ 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B,
+ 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713,
+ 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6,
+ 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85,
+ 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411,
+ 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B,
+ 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1,
+ 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF,
+ 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E,
+ 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6,
+ 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B,
+ 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD,
+ 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8,
+ 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2,
+ 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049,
+ 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810,
+ 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197,
+ 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F,
+ 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C,
+ 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927,
+ 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733,
+ 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5,
+ 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0,
+ 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C
+ ));
+
+ foreach ($t3 as $t3i) {
+ $t0[] = (($t3i << 24) & 0xFF000000) | (($t3i >> 8) & 0x00FFFFFF);
+ $t1[] = (($t3i << 16) & 0xFFFF0000) | (($t3i >> 16) & 0x0000FFFF);
+ $t2[] = (($t3i << 8) & 0xFFFFFF00) | (($t3i >> 24) & 0x000000FF);
+ }
+
+ $tables = array(
+ // The Precomputed mixColumns tables t0 - t3
+ $t0,
+ $t1,
+ $t2,
+ $t3,
+ // The SubByte S-Box
+ array(
+ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+ 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+ 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+ 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+ 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+ 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+ 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+ 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+ 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+ 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+ 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+ 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+ 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+ 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+ 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+ 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+ )
+ );
+ }
+ return $tables;
+ }
+
+ /**
+ * Provides the inverse mixColumns and inverse sboxes tables
+ *
+ * @see self::_decryptBlock()
+ * @see self::_setupInlineCrypt()
+ * @see self::_setupKey()
+ * @access private
+ * @return array &$tables
+ */
+ function &_getInvTables()
+ {
+ static $tables;
+ if (empty($tables)) {
+ $dt3 = array_map('intval', array(
+ 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B,
+ 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5,
+ 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B,
+ 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E,
+ 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D,
+ 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9,
+ 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66,
+ 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED,
+ 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4,
+ 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD,
+ 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60,
+ 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79,
+ 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C,
+ 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24,
+ 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C,
+ 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814,
+ 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B,
+ 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084,
+ 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077,
+ 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22,
+ 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F,
+ 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582,
+ 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB,
+ 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF,
+ 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035,
+ 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17,
+ 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46,
+ 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D,
+ 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A,
+ 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678,
+ 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF,
+ 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0
+ ));
+
+ foreach ($dt3 as $dt3i) {
+ $dt0[] = (($dt3i << 24) & 0xFF000000) | (($dt3i >> 8) & 0x00FFFFFF);
+ $dt1[] = (($dt3i << 16) & 0xFFFF0000) | (($dt3i >> 16) & 0x0000FFFF);
+ $dt2[] = (($dt3i << 8) & 0xFFFFFF00) | (($dt3i >> 24) & 0x000000FF);
+ };
+
+ $tables = array(
+ // The Precomputed inverse mixColumns tables dt0 - dt3
+ $dt0,
+ $dt1,
+ $dt2,
+ $dt3,
+ // The inverse SubByte S-Box
+ array(
+ 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+ 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+ 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+ 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+ 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+ 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+ 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+ 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+ 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+ 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+ 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+ 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+ 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+ 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+ 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+ )
+ );
+ }
+ return $tables;
+ }
+
+ /**
+ * Setup the performance-optimized function for de/encrypt()
+ *
+ * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
+ * @access private
+ */
+ function _setupInlineCrypt()
+ {
+ // Note: _setupInlineCrypt() will be called only if $this->changed === true
+ // So here we are'nt under the same heavy timing-stress as we are in _de/encryptBlock() or de/encrypt().
+ // However...the here generated function- $code, stored as php callback in $this->inline_crypt, must work as fast as even possible.
+
+ $lambda_functions =& self::_getLambdaFunctions();
+
+ // We create max. 10 hi-optimized code for memory reason. Means: For each $key one ultra fast inline-crypt function.
+ // (Currently, for Crypt_Rijndael/AES, one generated $lambda_function cost on php5.5@32bit ~80kb unfreeable mem and ~130kb on php5.5@64bit)
+ // After that, we'll still create very fast optimized code but not the hi-ultimative code, for each $mode one.
+ $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
+
+ // Generation of a uniqe hash for our generated code
+ $code_hash = "Crypt_Rijndael, {$this->mode}, {$this->Nr}, {$this->Nb}";
+ if ($gen_hi_opt_code) {
+ $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+ }
+
+ if (!isset($lambda_functions[$code_hash])) {
+ switch (true) {
+ case $gen_hi_opt_code:
+ // The hi-optimized $lambda_functions will use the key-words hardcoded for better performance.
+ $w = $this->w;
+ $dw = $this->dw;
+ $init_encrypt = '';
+ $init_decrypt = '';
+ break;
+ default:
+ for ($i = 0, $cw = count($this->w); $i < $cw; ++$i) {
+ $w[] = '$w[' . $i . ']';
+ $dw[] = '$dw[' . $i . ']';
+ }
+ $init_encrypt = '$w = $self->w;';
+ $init_decrypt = '$dw = $self->dw;';
+ }
+
+ $Nr = $this->Nr;
+ $Nb = $this->Nb;
+ $c = $this->c;
+
+ // Generating encrypt code:
+ $init_encrypt.= '
+ static $tables;
+ if (empty($tables)) {
+ $tables = &$self->_getTables();
+ }
+ $t0 = $tables[0];
+ $t1 = $tables[1];
+ $t2 = $tables[2];
+ $t3 = $tables[3];
+ $sbox = $tables[4];
+ ';
+
+ $s = 'e';
+ $e = 's';
+ $wc = $Nb - 1;
+
+ // Preround: addRoundKey
+ $encrypt_block = '$in = unpack("N*", $in);'."\n";
+ for ($i = 0; $i < $Nb; ++$i) {
+ $encrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$w[++$wc].";\n";
+ }
+
+ // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
+ for ($round = 1; $round < $Nr; ++$round) {
+ list($s, $e) = array($e, $s);
+ for ($i = 0; $i < $Nb; ++$i) {
+ $encrypt_block.=
+ '$'.$e.$i.' =
+ $t0[($'.$s.$i .' >> 24) & 0xff] ^
+ $t1[($'.$s.(($i + $c[1]) % $Nb).' >> 16) & 0xff] ^
+ $t2[($'.$s.(($i + $c[2]) % $Nb).' >> 8) & 0xff] ^
+ $t3[ $'.$s.(($i + $c[3]) % $Nb).' & 0xff] ^
+ '.$w[++$wc].";\n";
+ }
+ }
+
+ // Finalround: subWord + shiftRows + addRoundKey
+ for ($i = 0; $i < $Nb; ++$i) {
+ $encrypt_block.=
+ '$'.$e.$i.' =
+ $sbox[ $'.$e.$i.' & 0xff] |
+ ($sbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
+ ($sbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
+ ($sbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
+ }
+ $encrypt_block .= '$in = pack("N*"'."\n";
+ for ($i = 0; $i < $Nb; ++$i) {
+ $encrypt_block.= ',
+ ($'.$e.$i .' & '.((int)0xFF000000).') ^
+ ($'.$e.(($i + $c[1]) % $Nb).' & 0x00FF0000 ) ^
+ ($'.$e.(($i + $c[2]) % $Nb).' & 0x0000FF00 ) ^
+ ($'.$e.(($i + $c[3]) % $Nb).' & 0x000000FF ) ^
+ '.$w[$i]."\n";
+ }
+ $encrypt_block .= ');';
+
+ // Generating decrypt code:
+ $init_decrypt.= '
+ static $invtables;
+ if (empty($invtables)) {
+ $invtables = &$self->_getInvTables();
+ }
+ $dt0 = $invtables[0];
+ $dt1 = $invtables[1];
+ $dt2 = $invtables[2];
+ $dt3 = $invtables[3];
+ $isbox = $invtables[4];
+ ';
+
+ $s = 'e';
+ $e = 's';
+ $wc = $Nb - 1;
+
+ // Preround: addRoundKey
+ $decrypt_block = '$in = unpack("N*", $in);'."\n";
+ for ($i = 0; $i < $Nb; ++$i) {
+ $decrypt_block .= '$s'.$i.' = $in['.($i + 1).'] ^ '.$dw[++$wc].';'."\n";
+ }
+
+ // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey
+ for ($round = 1; $round < $Nr; ++$round) {
+ list($s, $e) = array($e, $s);
+ for ($i = 0; $i < $Nb; ++$i) {
+ $decrypt_block.=
+ '$'.$e.$i.' =
+ $dt0[($'.$s.$i .' >> 24) & 0xff] ^
+ $dt1[($'.$s.(($Nb + $i - $c[1]) % $Nb).' >> 16) & 0xff] ^
+ $dt2[($'.$s.(($Nb + $i - $c[2]) % $Nb).' >> 8) & 0xff] ^
+ $dt3[ $'.$s.(($Nb + $i - $c[3]) % $Nb).' & 0xff] ^
+ '.$dw[++$wc].";\n";
+ }
+ }
+
+ // Finalround: subWord + shiftRows + addRoundKey
+ for ($i = 0; $i < $Nb; ++$i) {
+ $decrypt_block.=
+ '$'.$e.$i.' =
+ $isbox[ $'.$e.$i.' & 0xff] |
+ ($isbox[($'.$e.$i.' >> 8) & 0xff] << 8) |
+ ($isbox[($'.$e.$i.' >> 16) & 0xff] << 16) |
+ ($isbox[($'.$e.$i.' >> 24) & 0xff] << 24);'."\n";
+ }
+ $decrypt_block .= '$in = pack("N*"'."\n";
+ for ($i = 0; $i < $Nb; ++$i) {
+ $decrypt_block.= ',
+ ($'.$e.$i. ' & '.((int)0xFF000000).') ^
+ ($'.$e.(($Nb + $i - $c[1]) % $Nb).' & 0x00FF0000 ) ^
+ ($'.$e.(($Nb + $i - $c[2]) % $Nb).' & 0x0000FF00 ) ^
+ ($'.$e.(($Nb + $i - $c[3]) % $Nb).' & 0x000000FF ) ^
+ '.$dw[$i]."\n";
+ }
+ $decrypt_block .= ');';
+
+ $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
+ array(
+ 'init_crypt' => '',
+ 'init_encrypt' => $init_encrypt,
+ 'init_decrypt' => $init_decrypt,
+ 'encrypt_block' => $encrypt_block,
+ 'decrypt_block' => $decrypt_block
+ )
+ );
+ }
+ $this->inline_crypt = $lambda_functions[$code_hash];
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php
new file mode 100644
index 0000000..a2c4166
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php
@@ -0,0 +1,460 @@
+<?php
+
+/**
+ * Pure-PHP implementation of Triple DES.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise. Operates in the EDE3 mode (encrypt-decrypt-encrypt).
+ *
+ * PHP version 5
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $des = new \phpseclib\Crypt\TripleDES();
+ *
+ * $des->setKey('abcdefghijklmnopqrstuvwx');
+ *
+ * $size = 10 * 1024;
+ * $plaintext = '';
+ * for ($i = 0; $i < $size; $i++) {
+ * $plaintext.= 'a';
+ * }
+ *
+ * echo $des->decrypt($des->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package TripleDES
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of Triple DES.
+ *
+ * @package TripleDES
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class TripleDES extends DES
+{
+ /**
+ * Encrypt / decrypt using inner chaining
+ *
+ * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (self::MODE_CBC3).
+ */
+ const MODE_3CBC = -2;
+
+ /**
+ * Encrypt / decrypt using outer chaining
+ *
+ * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib\Crypt\Base::MODE_CBC.
+ */
+ const MODE_CBC3 = Base::MODE_CBC;
+
+ /**
+ * Key Length (in bytes)
+ *
+ * @see \phpseclib\Crypt\TripleDES::setKeyLength()
+ * @var int
+ * @access private
+ */
+ var $key_length = 24;
+
+ /**
+ * The default salt used by setPassword()
+ *
+ * @see \phpseclib\Crypt\Base::password_default_salt
+ * @see \phpseclib\Crypt\Base::setPassword()
+ * @var string
+ * @access private
+ */
+ var $password_default_salt = 'phpseclib';
+
+ /**
+ * The mcrypt specific name of the cipher
+ *
+ * @see \phpseclib\Crypt\DES::cipher_name_mcrypt
+ * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+ * @var string
+ * @access private
+ */
+ var $cipher_name_mcrypt = 'tripledes';
+
+ /**
+ * Optimizing value while CFB-encrypting
+ *
+ * @see \phpseclib\Crypt\Base::cfb_init_len
+ * @var int
+ * @access private
+ */
+ var $cfb_init_len = 750;
+
+ /**
+ * max possible size of $key
+ *
+ * @see self::setKey()
+ * @see \phpseclib\Crypt\DES::setKey()
+ * @var string
+ * @access private
+ */
+ var $key_length_max = 24;
+
+ /**
+ * Internal flag whether using self::MODE_3CBC or not
+ *
+ * @var bool
+ * @access private
+ */
+ var $mode_3cbc;
+
+ /**
+ * The \phpseclib\Crypt\DES objects
+ *
+ * Used only if $mode_3cbc === true
+ *
+ * @var array
+ * @access private
+ */
+ var $des;
+
+ /**
+ * Default Constructor.
+ *
+ * Determines whether or not the mcrypt extension should be used.
+ *
+ * $mode could be:
+ *
+ * - \phpseclib\Crypt\Base::MODE_ECB
+ *
+ * - \phpseclib\Crypt\Base::MODE_CBC
+ *
+ * - \phpseclib\Crypt\Base::MODE_CTR
+ *
+ * - \phpseclib\Crypt\Base::MODE_CFB
+ *
+ * - \phpseclib\Crypt\Base::MODE_OFB
+ *
+ * - \phpseclib\Crypt\TripleDES::MODE_3CBC
+ *
+ * If not explicitly set, \phpseclib\Crypt\Base::MODE_CBC will be used.
+ *
+ * @see \phpseclib\Crypt\DES::__construct()
+ * @see \phpseclib\Crypt\Base::__construct()
+ * @param int $mode
+ * @access public
+ */
+ function __construct($mode = Base::MODE_CBC)
+ {
+ switch ($mode) {
+ // In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC
+ // and additional flag us internally as 3CBC
+ case self::MODE_3CBC:
+ parent::__construct(Base::MODE_CBC);
+ $this->mode_3cbc = true;
+
+ // This three $des'es will do the 3CBC work (if $key > 64bits)
+ $this->des = array(
+ new DES(Base::MODE_CBC),
+ new DES(Base::MODE_CBC),
+ new DES(Base::MODE_CBC),
+ );
+
+ // we're going to be doing the padding, ourselves, so disable it in the \phpseclib\Crypt\DES objects
+ $this->des[0]->disablePadding();
+ $this->des[1]->disablePadding();
+ $this->des[2]->disablePadding();
+ break;
+ // If not 3CBC, we init as usual
+ default:
+ parent::__construct($mode);
+ }
+ }
+
+ /**
+ * Test for engine validity
+ *
+ * This is mainly just a wrapper to set things up for \phpseclib\Crypt\Base::isValidEngine()
+ *
+ * @see \phpseclib\Crypt\Base::__construct()
+ * @param int $engine
+ * @access public
+ * @return bool
+ */
+ function isValidEngine($engine)
+ {
+ if ($engine == self::ENGINE_OPENSSL) {
+ $this->cipher_name_openssl_ecb = 'des-ede3';
+ $mode = $this->_openssl_translate_mode();
+ $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode;
+ }
+
+ return parent::isValidEngine($engine);
+ }
+
+ /**
+ * Sets the initialization vector. (optional)
+ *
+ * SetIV is not required when \phpseclib\Crypt\Base::MODE_ECB is being used. If not explicitly set, it'll be assumed
+ * to be all zero's.
+ *
+ * @see \phpseclib\Crypt\Base::setIV()
+ * @access public
+ * @param string $iv
+ */
+ function setIV($iv)
+ {
+ parent::setIV($iv);
+ if ($this->mode_3cbc) {
+ $this->des[0]->setIV($iv);
+ $this->des[1]->setIV($iv);
+ $this->des[2]->setIV($iv);
+ }
+ }
+
+ /**
+ * Sets the key length.
+ *
+ * Valid key lengths are 64, 128 and 192
+ *
+ * @see \phpseclib\Crypt\Base:setKeyLength()
+ * @access public
+ * @param int $length
+ */
+ function setKeyLength($length)
+ {
+ $length >>= 3;
+ switch (true) {
+ case $length <= 8:
+ $this->key_length = 8;
+ break;
+ case $length <= 16:
+ $this->key_length = 16;
+ break;
+ default:
+ $this->key_length = 24;
+ }
+
+ parent::setKeyLength($length);
+ }
+
+ /**
+ * Sets the key.
+ *
+ * Keys can be of any length. Triple DES, itself, can use 128-bit (eg. strlen($key) == 16) or
+ * 192-bit (eg. strlen($key) == 24) keys. This function pads and truncates $key as appropriate.
+ *
+ * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
+ *
+ * If the key is not explicitly set, it'll be assumed to be all null bytes.
+ *
+ * @access public
+ * @see \phpseclib\Crypt\DES::setKey()
+ * @see \phpseclib\Crypt\Base::setKey()
+ * @param string $key
+ */
+ function setKey($key)
+ {
+ $length = $this->explicit_key_length ? $this->key_length : strlen($key);
+ if ($length > 8) {
+ $key = str_pad(substr($key, 0, 24), 24, chr(0));
+ // if $key is between 64 and 128-bits, use the first 64-bits as the last, per this:
+ // http://php.net/function.mcrypt-encrypt#47973
+ $key = $length <= 16 ? substr_replace($key, substr($key, 0, 8), 16) : substr($key, 0, 24);
+ } else {
+ $key = str_pad($key, 8, chr(0));
+ }
+ parent::setKey($key);
+
+ // And in case of self::MODE_3CBC:
+ // if key <= 64bits we not need the 3 $des to work,
+ // because we will then act as regular DES-CBC with just a <= 64bit key.
+ // So only if the key > 64bits (> 8 bytes) we will call setKey() for the 3 $des.
+ if ($this->mode_3cbc && $length > 8) {
+ $this->des[0]->setKey(substr($key, 0, 8));
+ $this->des[1]->setKey(substr($key, 8, 8));
+ $this->des[2]->setKey(substr($key, 16, 8));
+ }
+ }
+
+ /**
+ * Encrypts a message.
+ *
+ * @see \phpseclib\Crypt\Base::encrypt()
+ * @access public
+ * @param string $plaintext
+ * @return string $cipertext
+ */
+ function encrypt($plaintext)
+ {
+ // parent::en/decrypt() is able to do all the work for all modes and keylengths,
+ // except for: self::MODE_3CBC (inner chaining CBC) with a key > 64bits
+
+ // if the key is smaller then 8, do what we'd normally do
+ if ($this->mode_3cbc && strlen($this->key) > 8) {
+ return $this->des[2]->encrypt(
+ $this->des[1]->decrypt(
+ $this->des[0]->encrypt(
+ $this->_pad($plaintext)
+ )
+ )
+ );
+ }
+
+ return parent::encrypt($plaintext);
+ }
+
+ /**
+ * Decrypts a message.
+ *
+ * @see \phpseclib\Crypt\Base::decrypt()
+ * @access public
+ * @param string $ciphertext
+ * @return string $plaintext
+ */
+ function decrypt($ciphertext)
+ {
+ if ($this->mode_3cbc && strlen($this->key) > 8) {
+ return $this->_unpad(
+ $this->des[0]->decrypt(
+ $this->des[1]->encrypt(
+ $this->des[2]->decrypt(
+ str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0")
+ )
+ )
+ )
+ );
+ }
+
+ return parent::decrypt($ciphertext);
+ }
+
+ /**
+ * Treat consecutive "packets" as if they are a continuous buffer.
+ *
+ * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
+ * will yield different outputs:
+ *
+ * <code>
+ * echo $des->encrypt(substr($plaintext, 0, 8));
+ * echo $des->encrypt(substr($plaintext, 8, 8));
+ * </code>
+ * <code>
+ * echo $des->encrypt($plaintext);
+ * </code>
+ *
+ * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
+ * another, as demonstrated with the following:
+ *
+ * <code>
+ * $des->encrypt(substr($plaintext, 0, 8));
+ * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
+ * </code>
+ * <code>
+ * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
+ * </code>
+ *
+ * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
+ * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
+ * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
+ *
+ * Put another way, when the continuous buffer is enabled, the state of the \phpseclib\Crypt\DES() object changes after each
+ * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
+ * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
+ * however, they are also less intuitive and more likely to cause you problems.
+ *
+ * @see \phpseclib\Crypt\Base::enableContinuousBuffer()
+ * @see self::disableContinuousBuffer()
+ * @access public
+ */
+ function enableContinuousBuffer()
+ {
+ parent::enableContinuousBuffer();
+ if ($this->mode_3cbc) {
+ $this->des[0]->enableContinuousBuffer();
+ $this->des[1]->enableContinuousBuffer();
+ $this->des[2]->enableContinuousBuffer();
+ }
+ }
+
+ /**
+ * Treat consecutive packets as if they are a discontinuous buffer.
+ *
+ * The default behavior.
+ *
+ * @see \phpseclib\Crypt\Base::disableContinuousBuffer()
+ * @see self::enableContinuousBuffer()
+ * @access public
+ */
+ function disableContinuousBuffer()
+ {
+ parent::disableContinuousBuffer();
+ if ($this->mode_3cbc) {
+ $this->des[0]->disableContinuousBuffer();
+ $this->des[1]->disableContinuousBuffer();
+ $this->des[2]->disableContinuousBuffer();
+ }
+ }
+
+ /**
+ * Creates the key schedule
+ *
+ * @see \phpseclib\Crypt\DES::_setupKey()
+ * @see \phpseclib\Crypt\Base::_setupKey()
+ * @access private
+ */
+ function _setupKey()
+ {
+ switch (true) {
+ // if $key <= 64bits we configure our internal pure-php cipher engine
+ // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same.
+ case strlen($this->key) <= 8:
+ $this->des_rounds = 1;
+ break;
+
+ // otherwise, if $key > 64bits, we configure our engine to work as 3DES.
+ default:
+ $this->des_rounds = 3;
+
+ // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately.
+ if ($this->mode_3cbc) {
+ $this->des[0]->_setupKey();
+ $this->des[1]->_setupKey();
+ $this->des[2]->_setupKey();
+
+ // because $des[0-2] will, now, do all the work we can return here
+ // not need unnecessary stress parent::_setupKey() with our, now unused, $key.
+ return;
+ }
+ }
+ // setup our key
+ parent::_setupKey();
+ }
+
+ /**
+ * Sets the internal crypt engine
+ *
+ * @see \phpseclib\Crypt\Base::__construct()
+ * @see \phpseclib\Crypt\Base::setPreferredEngine()
+ * @param int $engine
+ * @access public
+ * @return int
+ */
+ function setPreferredEngine($engine)
+ {
+ if ($this->mode_3cbc) {
+ $this->des[0]->setPreferredEngine($engine);
+ $this->des[1]->setPreferredEngine($engine);
+ $this->des[2]->setPreferredEngine($engine);
+ }
+
+ return parent::setPreferredEngine($engine);
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
new file mode 100644
index 0000000..70980a2
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php
@@ -0,0 +1,816 @@
+<?php
+
+/**
+ * Pure-PHP implementation of Twofish.
+ *
+ * Uses mcrypt, if available, and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * Useful resources are as follows:
+ *
+ * - {@link http://en.wikipedia.org/wiki/Twofish Wikipedia description of Twofish}
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $twofish = new \phpseclib\Crypt\Twofish();
+ *
+ * $twofish->setKey('12345678901234567890123456789012');
+ *
+ * $plaintext = str_repeat('a', 1024);
+ *
+ * echo $twofish->decrypt($twofish->encrypt($plaintext));
+ * ?>
+ * </code>
+ *
+ * @category Crypt
+ * @package Twofish
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
+ * @copyright 2007 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Crypt;
+
+/**
+ * Pure-PHP implementation of Twofish.
+ *
+ * @package Twofish
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @author Hans-Juergen Petrich <petrich@tronic-media.com>
+ * @access public
+ */
+class Twofish extends Base
+{
+ /**
+ * The mcrypt specific name of the cipher
+ *
+ * @see \phpseclib\Crypt\Base::cipher_name_mcrypt
+ * @var string
+ * @access private
+ */
+ var $cipher_name_mcrypt = 'twofish';
+
+ /**
+ * Optimizing value while CFB-encrypting
+ *
+ * @see \phpseclib\Crypt\Base::cfb_init_len
+ * @var int
+ * @access private
+ */
+ var $cfb_init_len = 800;
+
+ /**
+ * Q-Table
+ *
+ * @var array
+ * @access private
+ */
+ var $q0 = array(
+ 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76,
+ 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38,
+ 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
+ 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48,
+ 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23,
+ 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
+ 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C,
+ 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61,
+ 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
+ 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1,
+ 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66,
+ 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
+ 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA,
+ 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71,
+ 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
+ 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7,
+ 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2,
+ 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
+ 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB,
+ 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF,
+ 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
+ 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64,
+ 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A,
+ 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
+ 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02,
+ 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D,
+ 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
+ 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34,
+ 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8,
+ 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
+ 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00,
+ 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0
+ );
+
+ /**
+ * Q-Table
+ *
+ * @var array
+ * @access private
+ */
+ var $q1 = array(
+ 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8,
+ 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B,
+ 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
+ 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F,
+ 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D,
+ 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
+ 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3,
+ 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51,
+ 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
+ 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C,
+ 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70,
+ 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
+ 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC,
+ 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2,
+ 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
+ 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17,
+ 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3,
+ 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
+ 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49,
+ 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9,
+ 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
+ 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48,
+ 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19,
+ 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
+ 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5,
+ 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69,
+ 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
+ 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC,
+ 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB,
+ 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
+ 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2,
+ 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91
+ );
+
+ /**
+ * M-Table
+ *
+ * @var array
+ * @access private
+ */
+ var $m0 = array(
+ 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8,
+ 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B,
+ 0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1,
+ 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F,
+ 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D,
+ 0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5,
+ 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3,
+ 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51,
+ 0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796,
+ 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C,
+ 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70,
+ 0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8,
+ 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC,
+ 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2,
+ 0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9,
+ 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17,
+ 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3,
+ 0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E,
+ 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149,
+ 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9,
+ 0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01,
+ 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48,
+ 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519,
+ 0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64,
+ 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5,
+ 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969,
+ 0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E,
+ 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC,
+ 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB,
+ 0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9,
+ 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2,
+ 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91
+ );
+
+ /**
+ * M-Table
+ *
+ * @var array
+ * @access private
+ */
+ var $m1 = array(
+ 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4,
+ 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A,
+ 0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141,
+ 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E,
+ 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060,
+ 0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757,
+ 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D,
+ 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7,
+ 0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656,
+ 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B,
+ 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8,
+ 0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3,
+ 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D,
+ 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB,
+ 0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282,
+ 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7,
+ 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B,
+ 0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC,
+ 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E,
+ 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9,
+ 0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272,
+ 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F,
+ 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED,
+ 0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5,
+ 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7,
+ 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2,
+ 0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3,
+ 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323,
+ 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA,
+ 0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF,
+ 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000,
+ 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8
+ );
+
+ /**
+ * M-Table
+ *
+ * @var array
+ * @access private
+ */
+ var $m2 = array(
+ 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA,
+ 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7,
+ 0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783,
+ 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE,
+ 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0,
+ 0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA,
+ 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065,
+ 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F,
+ 0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07,
+ 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF,
+ 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C,
+ 0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96,
+ 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF,
+ 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E,
+ 0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD,
+ 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC,
+ 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71,
+ 0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85,
+ 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101,
+ 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5,
+ 0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B,
+ 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A,
+ 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45,
+ 0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D,
+ 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6,
+ 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929,
+ 0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D,
+ 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB,
+ 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F,
+ 0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9,
+ 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746,
+ 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF
+ );
+
+ /**
+ * M-Table
+ *
+ * @var array
+ * @access private
+ */
+ var $m3 = array(
+ 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF,
+ 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836,
+ 0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77,
+ 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A,
+ 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5,
+ 0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216,
+ 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63,
+ 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123,
+ 0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7,
+ 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197,
+ 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB,
+ 0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C,
+ 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20,
+ 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137,
+ 0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE,
+ 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730,
+ 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252,
+ 0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4,
+ 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F,
+ 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A,
+ 0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB,
+ 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D,
+ 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0,
+ 0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8,
+ 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6,
+ 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38,
+ 0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA,
+ 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439,
+ 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6,
+ 0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D,
+ 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000,
+ 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8
+ );
+
+ /**
+ * The Key Schedule Array
+ *
+ * @var array
+ * @access private
+ */
+ var $K = array();
+
+ /**
+ * The Key depended S-Table 0
+ *
+ * @var array
+ * @access private
+ */
+ var $S0 = array();
+
+ /**
+ * The Key depended S-Table 1
+ *
+ * @var array
+ * @access private
+ */
+ var $S1 = array();
+
+ /**
+ * The Key depended S-Table 2
+ *
+ * @var array
+ * @access private
+ */
+ var $S2 = array();
+
+ /**
+ * The Key depended S-Table 3
+ *
+ * @var array
+ * @access private
+ */
+ var $S3 = array();
+
+ /**
+ * Holds the last used key
+ *
+ * @var array
+ * @access private
+ */
+ var $kl;
+
+ /**
+ * The Key Length (in bytes)
+ *
+ * @see Crypt_Twofish::setKeyLength()
+ * @var int
+ * @access private
+ */
+ var $key_length = 16;
+
+ /**
+ * Sets the key length.
+ *
+ * Valid key lengths are 128, 192 or 256 bits
+ *
+ * @access public
+ * @param int $length
+ */
+ function setKeyLength($length)
+ {
+ switch (true) {
+ case $length <= 128:
+ $this->key_length = 16;
+ break;
+ case $length <= 192:
+ $this->key_length = 24;
+ break;
+ default:
+ $this->key_length = 32;
+ }
+
+ parent::setKeyLength($length);
+ }
+
+ /**
+ * Setup the key (expansion)
+ *
+ * @see \phpseclib\Crypt\Base::_setupKey()
+ * @access private
+ */
+ function _setupKey()
+ {
+ if (isset($this->kl['key']) && $this->key === $this->kl['key']) {
+ // already expanded
+ return;
+ }
+ $this->kl = array('key' => $this->key);
+
+ /* Key expanding and generating the key-depended s-boxes */
+ $le_longs = unpack('V*', $this->key);
+ $key = unpack('C*', $this->key);
+ $m0 = $this->m0;
+ $m1 = $this->m1;
+ $m2 = $this->m2;
+ $m3 = $this->m3;
+ $q0 = $this->q0;
+ $q1 = $this->q1;
+
+ $K = $S0 = $S1 = $S2 = $S3 = array();
+
+ switch (strlen($this->key)) {
+ case 16:
+ list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[1], $le_longs[2]);
+ list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[3], $le_longs[4]);
+ for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
+ $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^
+ $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^
+ $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^
+ $m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]];
+ $B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^
+ $m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^
+ $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^
+ $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]];
+ $B = ($B << 8) | ($B >> 24 & 0xff);
+ $A = $this->safe_intval($A + $B);
+ $K[] = $A;
+ $A = $this->safe_intval($A + $B);
+ $K[] = ($A << 9 | $A >> 23 & 0x1ff);
+ }
+ for ($i = 0; $i < 256; ++$i) {
+ $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0];
+ $S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1];
+ $S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2];
+ $S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3];
+ }
+ break;
+ case 24:
+ list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[1], $le_longs[2]);
+ list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[3], $le_longs[4]);
+ list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[5], $le_longs[6]);
+ for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
+ $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
+ $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
+ $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
+ $m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]];
+ $B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
+ $m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
+ $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
+ $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]];
+ $B = ($B << 8) | ($B >> 24 & 0xff);
+ $A = $this->safe_intval($A + $B);
+ $K[] = $A;
+ $A = $this->safe_intval($A + $B);
+ $K[] = ($A << 9 | $A >> 23 & 0x1ff);
+ }
+ for ($i = 0; $i < 256; ++$i) {
+ $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0];
+ $S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1];
+ $S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2];
+ $S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3];
+ }
+ break;
+ default: // 32
+ list($sf, $se, $sd, $sc) = $this->_mdsrem($le_longs[1], $le_longs[2]);
+ list($sb, $sa, $s9, $s8) = $this->_mdsrem($le_longs[3], $le_longs[4]);
+ list($s7, $s6, $s5, $s4) = $this->_mdsrem($le_longs[5], $le_longs[6]);
+ list($s3, $s2, $s1, $s0) = $this->_mdsrem($le_longs[7], $le_longs[8]);
+ for ($i = 0, $j = 1; $i < 40; $i+= 2, $j+= 2) {
+ $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^
+ $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^
+ $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^
+ $m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]];
+ $B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^
+ $m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^
+ $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^
+ $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]];
+ $B = ($B << 8) | ($B >> 24 & 0xff);
+ $A = $this->safe_intval($A + $B);
+ $K[] = $A;
+ $A = $this->safe_intval($A + $B);
+ $K[] = ($A << 9 | $A >> 23 & 0x1ff);
+ }
+ for ($i = 0; $i < 256; ++$i) {
+ $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0];
+ $S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1];
+ $S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2];
+ $S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3];
+ }
+ }
+
+ $this->K = $K;
+ $this->S0 = $S0;
+ $this->S1 = $S1;
+ $this->S2 = $S2;
+ $this->S3 = $S3;
+ }
+
+ /**
+ * _mdsrem function using by the twofish cipher algorithm
+ *
+ * @access private
+ * @param string $A
+ * @param string $B
+ * @return array
+ */
+ function _mdsrem($A, $B)
+ {
+ // No gain by unrolling this loop.
+ for ($i = 0; $i < 8; ++$i) {
+ // Get most significant coefficient.
+ $t = 0xff & ($B >> 24);
+
+ // Shift the others up.
+ $B = ($B << 8) | (0xff & ($A >> 24));
+ $A<<= 8;
+
+ $u = $t << 1;
+
+ // Subtract the modular polynomial on overflow.
+ if ($t & 0x80) {
+ $u^= 0x14d;
+ }
+
+ // Remove t * (a * x^2 + 1).
+ $B ^= $t ^ ($u << 16);
+
+ // Form u = a*t + t/a = t*(a + 1/a).
+ $u^= 0x7fffffff & ($t >> 1);
+
+ // Add the modular polynomial on underflow.
+ if ($t & 0x01) {
+ $u^= 0xa6 ;
+ }
+
+ // Remove t * (a + 1/a) * (x^3 + x).
+ $B^= ($u << 24) | ($u << 8);
+ }
+
+ return array(
+ 0xff & $B >> 24,
+ 0xff & $B >> 16,
+ 0xff & $B >> 8,
+ 0xff & $B);
+ }
+
+ /**
+ * Encrypts a block
+ *
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ function _encryptBlock($in)
+ {
+ $S0 = $this->S0;
+ $S1 = $this->S1;
+ $S2 = $this->S2;
+ $S3 = $this->S3;
+ $K = $this->K;
+
+ $in = unpack("V4", $in);
+ $R0 = $K[0] ^ $in[1];
+ $R1 = $K[1] ^ $in[2];
+ $R2 = $K[2] ^ $in[3];
+ $R3 = $K[3] ^ $in[4];
+
+ $ki = 7;
+ while ($ki < 39) {
+ $t0 = $S0[ $R0 & 0xff] ^
+ $S1[($R0 >> 8) & 0xff] ^
+ $S2[($R0 >> 16) & 0xff] ^
+ $S3[($R0 >> 24) & 0xff];
+ $t1 = $S0[($R1 >> 24) & 0xff] ^
+ $S1[ $R1 & 0xff] ^
+ $S2[($R1 >> 8) & 0xff] ^
+ $S3[($R1 >> 16) & 0xff];
+ $R2^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
+ $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
+ $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
+
+ $t0 = $S0[ $R2 & 0xff] ^
+ $S1[($R2 >> 8) & 0xff] ^
+ $S2[($R2 >> 16) & 0xff] ^
+ $S3[($R2 >> 24) & 0xff];
+ $t1 = $S0[($R3 >> 24) & 0xff] ^
+ $S1[ $R3 & 0xff] ^
+ $S2[($R3 >> 8) & 0xff] ^
+ $S3[($R3 >> 16) & 0xff];
+ $R0^= $this->safe_intval($t0 + $t1 + $K[++$ki]);
+ $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
+ $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ $this->safe_intval($t0 + ($t1 << 1) + $K[++$ki]);
+ }
+
+ // @codingStandardsIgnoreStart
+ return pack("V4", $K[4] ^ $R2,
+ $K[5] ^ $R3,
+ $K[6] ^ $R0,
+ $K[7] ^ $R1);
+ // @codingStandardsIgnoreEnd
+ }
+
+ /**
+ * Decrypts a block
+ *
+ * @access private
+ * @param string $in
+ * @return string
+ */
+ function _decryptBlock($in)
+ {
+ $S0 = $this->S0;
+ $S1 = $this->S1;
+ $S2 = $this->S2;
+ $S3 = $this->S3;
+ $K = $this->K;
+
+ $in = unpack("V4", $in);
+ $R0 = $K[4] ^ $in[1];
+ $R1 = $K[5] ^ $in[2];
+ $R2 = $K[6] ^ $in[3];
+ $R3 = $K[7] ^ $in[4];
+
+ $ki = 40;
+ while ($ki > 8) {
+ $t0 = $S0[$R0 & 0xff] ^
+ $S1[$R0 >> 8 & 0xff] ^
+ $S2[$R0 >> 16 & 0xff] ^
+ $S3[$R0 >> 24 & 0xff];
+ $t1 = $S0[$R1 >> 24 & 0xff] ^
+ $S1[$R1 & 0xff] ^
+ $S2[$R1 >> 8 & 0xff] ^
+ $S3[$R1 >> 16 & 0xff];
+ $R3^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
+ $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
+ $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
+
+ $t0 = $S0[$R2 & 0xff] ^
+ $S1[$R2 >> 8 & 0xff] ^
+ $S2[$R2 >> 16 & 0xff] ^
+ $S3[$R2 >> 24 & 0xff];
+ $t1 = $S0[$R3 >> 24 & 0xff] ^
+ $S1[$R3 & 0xff] ^
+ $S2[$R3 >> 8 & 0xff] ^
+ $S3[$R3 >> 16 & 0xff];
+ $R1^= $this->safe_intval($t0 + ($t1 << 1) + $K[--$ki]);
+ $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
+ $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ $this->safe_intval($t0 + $t1 + $K[--$ki]);
+ }
+
+ // @codingStandardsIgnoreStart
+ return pack("V4", $K[0] ^ $R2,
+ $K[1] ^ $R3,
+ $K[2] ^ $R0,
+ $K[3] ^ $R1);
+ // @codingStandardsIgnoreEnd
+ }
+
+ /**
+ * Setup the performance-optimized function for de/encrypt()
+ *
+ * @see \phpseclib\Crypt\Base::_setupInlineCrypt()
+ * @access private
+ */
+ function _setupInlineCrypt()
+ {
+ $lambda_functions =& self::_getLambdaFunctions();
+
+ // Max. 10 Ultra-Hi-optimized inline-crypt functions. After that, we'll (still) create very fast code, but not the ultimate fast one.
+ // (Currently, for Crypt_Twofish, one generated $lambda_function cost on php5.5@32bit ~140kb unfreeable mem and ~240kb on php5.5@64bit)
+ $gen_hi_opt_code = (bool)(count($lambda_functions) < 10);
+
+ // Generation of a unique hash for our generated code
+ $code_hash = "Crypt_Twofish, {$this->mode}";
+ if ($gen_hi_opt_code) {
+ $code_hash = str_pad($code_hash, 32) . $this->_hashInlineCryptFunction($this->key);
+ }
+
+ $safeint = $this->safe_intval_inline();
+
+ if (!isset($lambda_functions[$code_hash])) {
+ switch (true) {
+ case $gen_hi_opt_code:
+ $K = $this->K;
+ $init_crypt = '
+ static $S0, $S1, $S2, $S3;
+ if (!$S0) {
+ for ($i = 0; $i < 256; ++$i) {
+ $S0[] = (int)$self->S0[$i];
+ $S1[] = (int)$self->S1[$i];
+ $S2[] = (int)$self->S2[$i];
+ $S3[] = (int)$self->S3[$i];
+ }
+ }
+ ';
+ break;
+ default:
+ $K = array();
+ for ($i = 0; $i < 40; ++$i) {
+ $K[] = '$K_' . $i;
+ }
+ $init_crypt = '
+ $S0 = $self->S0;
+ $S1 = $self->S1;
+ $S2 = $self->S2;
+ $S3 = $self->S3;
+ list(' . implode(',', $K) . ') = $self->K;
+ ';
+ }
+
+ // Generating encrypt code:
+ $encrypt_block = '
+ $in = unpack("V4", $in);
+ $R0 = '.$K[0].' ^ $in[1];
+ $R1 = '.$K[1].' ^ $in[2];
+ $R2 = '.$K[2].' ^ $in[3];
+ $R3 = '.$K[3].' ^ $in[4];
+ ';
+ for ($ki = 7, $i = 0; $i < 8; ++$i) {
+ $encrypt_block.= '
+ $t0 = $S0[ $R0 & 0xff] ^
+ $S1[($R0 >> 8) & 0xff] ^
+ $S2[($R0 >> 16) & 0xff] ^
+ $S3[($R0 >> 24) & 0xff];
+ $t1 = $S0[($R1 >> 24) & 0xff] ^
+ $S1[ $R1 & 0xff] ^
+ $S2[($R1 >> 8) & 0xff] ^
+ $S3[($R1 >> 16) & 0xff];
+ $R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . ';
+ $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31);
+ $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
+
+ $t0 = $S0[ $R2 & 0xff] ^
+ $S1[($R2 >> 8) & 0xff] ^
+ $S2[($R2 >> 16) & 0xff] ^
+ $S3[($R2 >> 24) & 0xff];
+ $t1 = $S0[($R3 >> 24) & 0xff] ^
+ $S1[ $R3 & 0xff] ^
+ $S2[($R3 >> 8) & 0xff] ^
+ $S3[($R3 >> 16) & 0xff];
+ $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . ';
+ $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31);
+ $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . ';
+ ';
+ }
+ $encrypt_block.= '
+ $in = pack("V4", ' . $K[4] . ' ^ $R2,
+ ' . $K[5] . ' ^ $R3,
+ ' . $K[6] . ' ^ $R0,
+ ' . $K[7] . ' ^ $R1);
+ ';
+
+ // Generating decrypt code:
+ $decrypt_block = '
+ $in = unpack("V4", $in);
+ $R0 = '.$K[4].' ^ $in[1];
+ $R1 = '.$K[5].' ^ $in[2];
+ $R2 = '.$K[6].' ^ $in[3];
+ $R3 = '.$K[7].' ^ $in[4];
+ ';
+ for ($ki = 40, $i = 0; $i < 8; ++$i) {
+ $decrypt_block.= '
+ $t0 = $S0[$R0 & 0xff] ^
+ $S1[$R0 >> 8 & 0xff] ^
+ $S2[$R0 >> 16 & 0xff] ^
+ $S3[$R0 >> 24 & 0xff];
+ $t1 = $S0[$R1 >> 24 & 0xff] ^
+ $S1[$R1 & 0xff] ^
+ $S2[$R1 >> 8 & 0xff] ^
+ $S3[$R1 >> 16 & 0xff];
+ $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
+ $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31;
+ $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
+
+ $t0 = $S0[$R2 & 0xff] ^
+ $S1[$R2 >> 8 & 0xff] ^
+ $S2[$R2 >> 16 & 0xff] ^
+ $S3[$R2 >> 24 & 0xff];
+ $t1 = $S0[$R3 >> 24 & 0xff] ^
+ $S1[$R3 & 0xff] ^
+ $S2[$R3 >> 8 & 0xff] ^
+ $S3[$R3 >> 16 & 0xff];
+ $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . ';
+ $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31;
+ $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + '.$K[--$ki] . ')') . ';
+ ';
+ }
+ $decrypt_block.= '
+ $in = pack("V4", ' . $K[0] . ' ^ $R2,
+ ' . $K[1] . ' ^ $R3,
+ ' . $K[2] . ' ^ $R0,
+ ' . $K[3] . ' ^ $R1);
+ ';
+
+ $lambda_functions[$code_hash] = $this->_createInlineCryptFunction(
+ array(
+ 'init_crypt' => $init_crypt,
+ 'init_encrypt' => '',
+ 'init_decrypt' => '',
+ 'encrypt_block' => $encrypt_block,
+ 'decrypt_block' => $decrypt_block
+ )
+ );
+ }
+ $this->inline_crypt = $lambda_functions[$code_hash];
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php
new file mode 100644
index 0000000..5ff1f2e
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php
@@ -0,0 +1,577 @@
+<?php
+
+/**
+ * Pure-PHP ANSI Decoder
+ *
+ * PHP version 5
+ *
+ * If you call read() in \phpseclib\Net\SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back.
+ * They'd look like chr(0x1B) . '[00m' or whatever (0x1B = ESC). They tell a
+ * {@link http://en.wikipedia.org/wiki/Terminal_emulator terminal emulator} how to format the characters, what
+ * color to display them in, etc. \phpseclib\File\ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator.
+ *
+ * @category File
+ * @package ANSI
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2012 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\File;
+
+/**
+ * Pure-PHP ANSI Decoder
+ *
+ * @package ANSI
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class ANSI
+{
+ /**
+ * Max Width
+ *
+ * @var int
+ * @access private
+ */
+ var $max_x;
+
+ /**
+ * Max Height
+ *
+ * @var int
+ * @access private
+ */
+ var $max_y;
+
+ /**
+ * Max History
+ *
+ * @var int
+ * @access private
+ */
+ var $max_history;
+
+ /**
+ * History
+ *
+ * @var array
+ * @access private
+ */
+ var $history;
+
+ /**
+ * History Attributes
+ *
+ * @var array
+ * @access private
+ */
+ var $history_attrs;
+
+ /**
+ * Current Column
+ *
+ * @var int
+ * @access private
+ */
+ var $x;
+
+ /**
+ * Current Row
+ *
+ * @var int
+ * @access private
+ */
+ var $y;
+
+ /**
+ * Old Column
+ *
+ * @var int
+ * @access private
+ */
+ var $old_x;
+
+ /**
+ * Old Row
+ *
+ * @var int
+ * @access private
+ */
+ var $old_y;
+
+ /**
+ * An empty attribute cell
+ *
+ * @var object
+ * @access private
+ */
+ var $base_attr_cell;
+
+ /**
+ * The current attribute cell
+ *
+ * @var object
+ * @access private
+ */
+ var $attr_cell;
+
+ /**
+ * An empty attribute row
+ *
+ * @var array
+ * @access private
+ */
+ var $attr_row;
+
+ /**
+ * The current screen text
+ *
+ * @var array
+ * @access private
+ */
+ var $screen;
+
+ /**
+ * The current screen attributes
+ *
+ * @var array
+ * @access private
+ */
+ var $attrs;
+
+ /**
+ * Current ANSI code
+ *
+ * @var string
+ * @access private
+ */
+ var $ansi;
+
+ /**
+ * Tokenization
+ *
+ * @var array
+ * @access private
+ */
+ var $tokenization;
+
+ /**
+ * Default Constructor.
+ *
+ * @return \phpseclib\File\ANSI
+ * @access public
+ */
+ function __construct()
+ {
+ $attr_cell = new \stdClass();
+ $attr_cell->bold = false;
+ $attr_cell->underline = false;
+ $attr_cell->blink = false;
+ $attr_cell->background = 'black';
+ $attr_cell->foreground = 'white';
+ $attr_cell->reverse = false;
+ $this->base_attr_cell = clone $attr_cell;
+ $this->attr_cell = clone $attr_cell;
+
+ $this->setHistory(200);
+ $this->setDimensions(80, 24);
+ }
+
+ /**
+ * Set terminal width and height
+ *
+ * Resets the screen as well
+ *
+ * @param int $x
+ * @param int $y
+ * @access public
+ */
+ function setDimensions($x, $y)
+ {
+ $this->max_x = $x - 1;
+ $this->max_y = $y - 1;
+ $this->x = $this->y = 0;
+ $this->history = $this->history_attrs = array();
+ $this->attr_row = array_fill(0, $this->max_x + 2, $this->base_attr_cell);
+ $this->screen = array_fill(0, $this->max_y + 1, '');
+ $this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row);
+ $this->ansi = '';
+ }
+
+ /**
+ * Set the number of lines that should be logged past the terminal height
+ *
+ * @param int $x
+ * @param int $y
+ * @access public
+ */
+ function setHistory($history)
+ {
+ $this->max_history = $history;
+ }
+
+ /**
+ * Load a string
+ *
+ * @param string $source
+ * @access public
+ */
+ function loadString($source)
+ {
+ $this->setDimensions($this->max_x + 1, $this->max_y + 1);
+ $this->appendString($source);
+ }
+
+ /**
+ * Appdend a string
+ *
+ * @param string $source
+ * @access public
+ */
+ function appendString($source)
+ {
+ $this->tokenization = array('');
+ for ($i = 0; $i < strlen($source); $i++) {
+ if (strlen($this->ansi)) {
+ $this->ansi.= $source[$i];
+ $chr = ord($source[$i]);
+ // http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements
+ // single character CSI's not currently supported
+ switch (true) {
+ case $this->ansi == "\x1B=":
+ $this->ansi = '';
+ continue 2;
+ case strlen($this->ansi) == 2 && $chr >= 64 && $chr <= 95 && $chr != ord('['):
+ case strlen($this->ansi) > 2 && $chr >= 64 && $chr <= 126:
+ break;
+ default:
+ continue 2;
+ }
+ $this->tokenization[] = $this->ansi;
+ $this->tokenization[] = '';
+ // http://ascii-table.com/ansi-escape-sequences-vt-100.php
+ switch ($this->ansi) {
+ case "\x1B[H": // Move cursor to upper left corner
+ $this->old_x = $this->x;
+ $this->old_y = $this->y;
+ $this->x = $this->y = 0;
+ break;
+ case "\x1B[J": // Clear screen from cursor down
+ $this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y));
+ $this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, ''));
+
+ $this->history_attrs = array_merge($this->history_attrs, array_slice(array_splice($this->attrs, $this->y + 1), 0, $this->old_y));
+ $this->attrs = array_merge($this->attrs, array_fill($this->y, $this->max_y, $this->attr_row));
+
+ if (count($this->history) == $this->max_history) {
+ array_shift($this->history);
+ array_shift($this->history_attrs);
+ }
+ case "\x1B[K": // Clear screen from cursor right
+ $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);
+
+ array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - $this->x - 1, $this->base_attr_cell));
+ break;
+ case "\x1B[2K": // Clear entire line
+ $this->screen[$this->y] = str_repeat(' ', $this->x);
+ $this->attrs[$this->y] = $this->attr_row;
+ break;
+ case "\x1B[?1h": // set cursor key to application
+ case "\x1B[?25h": // show the cursor
+ case "\x1B(B": // set united states g0 character set
+ break;
+ case "\x1BE": // Move to next line
+ $this->_newLine();
+ $this->x = 0;
+ break;
+ default:
+ switch (true) {
+ case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines
+ $this->old_y = $this->y;
+ $this->y+= $match[1];
+ break;
+ case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h
+ $this->old_x = $this->x;
+ $this->old_y = $this->y;
+ $this->x = $match[2] - 1;
+ $this->y = $match[1] - 1;
+ break;
+ case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines
+ $this->old_x = $this->x;
+ $this->x+= $match[1];
+ break;
+ case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines
+ $this->old_x = $this->x;
+ $this->x-= $match[1];
+ if ($this->x < 0) {
+ $this->x = 0;
+ }
+ break;
+ case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
+ break;
+ case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes
+ $attr_cell = &$this->attr_cell;
+ $mods = explode(';', $match[1]);
+ foreach ($mods as $mod) {
+ switch ($mod) {
+ case 0: // Turn off character attributes
+ $attr_cell = clone $this->base_attr_cell;
+ break;
+ case 1: // Turn bold mode on
+ $attr_cell->bold = true;
+ break;
+ case 4: // Turn underline mode on
+ $attr_cell->underline = true;
+ break;
+ case 5: // Turn blinking mode on
+ $attr_cell->blink = true;
+ break;
+ case 7: // Turn reverse video on
+ $attr_cell->reverse = !$attr_cell->reverse;
+ $temp = $attr_cell->background;
+ $attr_cell->background = $attr_cell->foreground;
+ $attr_cell->foreground = $temp;
+ break;
+ default: // set colors
+ //$front = $attr_cell->reverse ? &$attr_cell->background : &$attr_cell->foreground;
+ $front = &$attr_cell->{ $attr_cell->reverse ? 'background' : 'foreground' };
+ //$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background;
+ $back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' };
+ switch ($mod) {
+ // @codingStandardsIgnoreStart
+ case 30: $front = 'black'; break;
+ case 31: $front = 'red'; break;
+ case 32: $front = 'green'; break;
+ case 33: $front = 'yellow'; break;
+ case 34: $front = 'blue'; break;
+ case 35: $front = 'magenta'; break;
+ case 36: $front = 'cyan'; break;
+ case 37: $front = 'white'; break;
+
+ case 40: $back = 'black'; break;
+ case 41: $back = 'red'; break;
+ case 42: $back = 'green'; break;
+ case 43: $back = 'yellow'; break;
+ case 44: $back = 'blue'; break;
+ case 45: $back = 'magenta'; break;
+ case 46: $back = 'cyan'; break;
+ case 47: $back = 'white'; break;
+ // @codingStandardsIgnoreEnd
+
+ default:
+ //user_error('Unsupported attribute: ' . $mod);
+ $this->ansi = '';
+ break 2;
+ }
+ }
+ }
+ break;
+ default:
+ //user_error("{$this->ansi} is unsupported\r\n");
+ }
+ }
+ $this->ansi = '';
+ continue;
+ }
+
+ $this->tokenization[count($this->tokenization) - 1].= $source[$i];
+ switch ($source[$i]) {
+ case "\r":
+ $this->x = 0;
+ break;
+ case "\n":
+ $this->_newLine();
+ break;
+ case "\x08": // backspace
+ if ($this->x) {
+ $this->x--;
+ $this->attrs[$this->y][$this->x] = clone $this->base_attr_cell;
+ $this->screen[$this->y] = substr_replace(
+ $this->screen[$this->y],
+ $source[$i],
+ $this->x,
+ 1
+ );
+ }
+ break;
+ case "\x0F": // shift
+ break;
+ case "\x1B": // start ANSI escape code
+ $this->tokenization[count($this->tokenization) - 1] = substr($this->tokenization[count($this->tokenization) - 1], 0, -1);
+ //if (!strlen($this->tokenization[count($this->tokenization) - 1])) {
+ // array_pop($this->tokenization);
+ //}
+ $this->ansi.= "\x1B";
+ break;
+ default:
+ $this->attrs[$this->y][$this->x] = clone $this->attr_cell;
+ if ($this->x > strlen($this->screen[$this->y])) {
+ $this->screen[$this->y] = str_repeat(' ', $this->x);
+ }
+ $this->screen[$this->y] = substr_replace(
+ $this->screen[$this->y],
+ $source[$i],
+ $this->x,
+ 1
+ );
+
+ if ($this->x > $this->max_x) {
+ $this->x = 0;
+ $this->_newLine();
+ } else {
+ $this->x++;
+ }
+ }
+ }
+ }
+
+ /**
+ * Add a new line
+ *
+ * Also update the $this->screen and $this->history buffers
+ *
+ * @access private
+ */
+ function _newLine()
+ {
+ //if ($this->y < $this->max_y) {
+ // $this->y++;
+ //}
+
+ while ($this->y >= $this->max_y) {
+ $this->history = array_merge($this->history, array(array_shift($this->screen)));
+ $this->screen[] = '';
+
+ $this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs)));
+ $this->attrs[] = $this->attr_row;
+
+ if (count($this->history) >= $this->max_history) {
+ array_shift($this->history);
+ array_shift($this->history_attrs);
+ }
+
+ $this->y--;
+ }
+ $this->y++;
+ }
+
+ /**
+ * Returns the current coordinate without preformating
+ *
+ * @access private
+ * @return string
+ */
+ function _processCoordinate($last_attr, $cur_attr, $char)
+ {
+ $output = '';
+
+ if ($last_attr != $cur_attr) {
+ $close = $open = '';
+ if ($last_attr->foreground != $cur_attr->foreground) {
+ if ($cur_attr->foreground != 'white') {
+ $open.= '<span style="color: ' . $cur_attr->foreground . '">';
+ }
+ if ($last_attr->foreground != 'white') {
+ $close = '</span>' . $close;
+ }
+ }
+ if ($last_attr->background != $cur_attr->background) {
+ if ($cur_attr->background != 'black') {
+ $open.= '<span style="background: ' . $cur_attr->background . '">';
+ }
+ if ($last_attr->background != 'black') {
+ $close = '</span>' . $close;
+ }
+ }
+ if ($last_attr->bold != $cur_attr->bold) {
+ if ($cur_attr->bold) {
+ $open.= '<b>';
+ } else {
+ $close = '</b>' . $close;
+ }
+ }
+ if ($last_attr->underline != $cur_attr->underline) {
+ if ($cur_attr->underline) {
+ $open.= '<u>';
+ } else {
+ $close = '</u>' . $close;
+ }
+ }
+ if ($last_attr->blink != $cur_attr->blink) {
+ if ($cur_attr->blink) {
+ $open.= '<blink>';
+ } else {
+ $close = '</blink>' . $close;
+ }
+ }
+ $output.= $close . $open;
+ }
+
+ $output.= htmlspecialchars($char);
+
+ return $output;
+ }
+
+ /**
+ * Returns the current screen without preformating
+ *
+ * @access private
+ * @return string
+ */
+ function _getScreen()
+ {
+ $output = '';
+ $last_attr = $this->base_attr_cell;
+ for ($i = 0; $i <= $this->max_y; $i++) {
+ for ($j = 0; $j <= $this->max_x; $j++) {
+ $cur_attr = $this->attrs[$i][$j];
+ $output.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : '');
+ $last_attr = $this->attrs[$i][$j];
+ }
+ $output.= "\r\n";
+ }
+ $output = substr($output, 0, -2);
+ // close any remaining open tags
+ $output.= $this->_processCoordinate($last_attr, $this->base_attr_cell, '');
+ return rtrim($output);
+ }
+
+ /**
+ * Returns the current screen
+ *
+ * @access public
+ * @return string
+ */
+ function getScreen()
+ {
+ return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $this->_getScreen() . '</pre>';
+ }
+
+ /**
+ * Returns the current screen and the x previous lines
+ *
+ * @access public
+ * @return string
+ */
+ function getHistory()
+ {
+ $scrollback = '';
+ $last_attr = $this->base_attr_cell;
+ for ($i = 0; $i < count($this->history); $i++) {
+ for ($j = 0; $j <= $this->max_x + 1; $j++) {
+ $cur_attr = $this->history_attrs[$i][$j];
+ $scrollback.= $this->_processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : '');
+ $last_attr = $this->history_attrs[$i][$j];
+ }
+ $scrollback.= "\r\n";
+ }
+ $base_attr_cell = $this->base_attr_cell;
+ $this->base_attr_cell = $last_attr;
+ $scrollback.= $this->_getScreen();
+ $this->base_attr_cell = $base_attr_cell;
+
+ return '<pre width="' . ($this->max_x + 1) . '" style="color: white; background: black">' . $scrollback . '</span></pre>';
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
new file mode 100644
index 0000000..a304a00
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php
@@ -0,0 +1,1414 @@
+<?php
+
+/**
+ * Pure-PHP ASN.1 Parser
+ *
+ * PHP version 5
+ *
+ * ASN.1 provides the semantics for data encoded using various schemes. The most commonly
+ * utilized scheme is DER or the "Distinguished Encoding Rules". PEM's are base64 encoded
+ * DER blobs.
+ *
+ * \phpseclib\File\ASN1 decodes and encodes DER formatted messages and places them in a semantic context.
+ *
+ * Uses the 1988 ASN.1 syntax.
+ *
+ * @category File
+ * @package ASN1
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2012 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\File;
+
+use phpseclib\File\ASN1\Element;
+use phpseclib\Math\BigInteger;
+use DateTime;
+use DateTimeZone;
+
+/**
+ * Pure-PHP ASN.1 Parser
+ *
+ * @package ASN1
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class ASN1
+{
+ /**#@+
+ * Tag Classes
+ *
+ * @access private
+ * @link http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=12
+ */
+ const CLASS_UNIVERSAL = 0;
+ const CLASS_APPLICATION = 1;
+ const CLASS_CONTEXT_SPECIFIC = 2;
+ const CLASS_PRIVATE = 3;
+ /**#@-*/
+
+ /**#@+
+ * Tag Classes
+ *
+ * @access private
+ * @link http://www.obj-sys.com/asn1tutorial/node124.html
+ */
+ const TYPE_BOOLEAN = 1;
+ const TYPE_INTEGER = 2;
+ const TYPE_BIT_STRING = 3;
+ const TYPE_OCTET_STRING = 4;
+ const TYPE_NULL = 5;
+ const TYPE_OBJECT_IDENTIFIER = 6;
+ //const TYPE_OBJECT_DESCRIPTOR = 7;
+ //const TYPE_INSTANCE_OF = 8; // EXTERNAL
+ const TYPE_REAL = 9;
+ const TYPE_ENUMERATED = 10;
+ //const TYPE_EMBEDDED = 11;
+ const TYPE_UTF8_STRING = 12;
+ //const TYPE_RELATIVE_OID = 13;
+ const TYPE_SEQUENCE = 16; // SEQUENCE OF
+ const TYPE_SET = 17; // SET OF
+ /**#@-*/
+ /**#@+
+ * More Tag Classes
+ *
+ * @access private
+ * @link http://www.obj-sys.com/asn1tutorial/node10.html
+ */
+ const TYPE_NUMERIC_STRING = 18;
+ const TYPE_PRINTABLE_STRING = 19;
+ const TYPE_TELETEX_STRING = 20; // T61String
+ const TYPE_VIDEOTEX_STRING = 21;
+ const TYPE_IA5_STRING = 22;
+ const TYPE_UTC_TIME = 23;
+ const TYPE_GENERALIZED_TIME = 24;
+ const TYPE_GRAPHIC_STRING = 25;
+ const TYPE_VISIBLE_STRING = 26; // ISO646String
+ const TYPE_GENERAL_STRING = 27;
+ const TYPE_UNIVERSAL_STRING = 28;
+ //const TYPE_CHARACTER_STRING = 29;
+ const TYPE_BMP_STRING = 30;
+ /**#@-*/
+
+ /**#@+
+ * Tag Aliases
+ *
+ * These tags are kinda place holders for other tags.
+ *
+ * @access private
+ */
+ const TYPE_CHOICE = -1;
+ const TYPE_ANY = -2;
+ /**#@-*/
+
+ /**
+ * ASN.1 object identifier
+ *
+ * @var array
+ * @access private
+ * @link http://en.wikipedia.org/wiki/Object_identifier
+ */
+ var $oids = array();
+
+ /**
+ * Default date format
+ *
+ * @var string
+ * @access private
+ * @link http://php.net/class.datetime
+ */
+ var $format = 'D, d M Y H:i:s O';
+
+ /**
+ * Default date format
+ *
+ * @var array
+ * @access private
+ * @see self::setTimeFormat()
+ * @see self::asn1map()
+ * @link http://php.net/class.datetime
+ */
+ var $encoded;
+
+ /**
+ * Filters
+ *
+ * If the mapping type is self::TYPE_ANY what do we actually encode it as?
+ *
+ * @var array
+ * @access private
+ * @see self::_encode_der()
+ */
+ var $filters;
+
+ /**
+ * Type mapping table for the ANY type.
+ *
+ * Structured or unknown types are mapped to a \phpseclib\File\ASN1\Element.
+ * Unambiguous types get the direct mapping (int/real/bool).
+ * Others are mapped as a choice, with an extra indexing level.
+ *
+ * @var array
+ * @access public
+ */
+ var $ANYmap = array(
+ self::TYPE_BOOLEAN => true,
+ self::TYPE_INTEGER => true,
+ self::TYPE_BIT_STRING => 'bitString',
+ self::TYPE_OCTET_STRING => 'octetString',
+ self::TYPE_NULL => 'null',
+ self::TYPE_OBJECT_IDENTIFIER => 'objectIdentifier',
+ self::TYPE_REAL => true,
+ self::TYPE_ENUMERATED => 'enumerated',
+ self::TYPE_UTF8_STRING => 'utf8String',
+ self::TYPE_NUMERIC_STRING => 'numericString',
+ self::TYPE_PRINTABLE_STRING => 'printableString',
+ self::TYPE_TELETEX_STRING => 'teletexString',
+ self::TYPE_VIDEOTEX_STRING => 'videotexString',
+ self::TYPE_IA5_STRING => 'ia5String',
+ self::TYPE_UTC_TIME => 'utcTime',
+ self::TYPE_GENERALIZED_TIME => 'generalTime',
+ self::TYPE_GRAPHIC_STRING => 'graphicString',
+ self::TYPE_VISIBLE_STRING => 'visibleString',
+ self::TYPE_GENERAL_STRING => 'generalString',
+ self::TYPE_UNIVERSAL_STRING => 'universalString',
+ //self::TYPE_CHARACTER_STRING => 'characterString',
+ self::TYPE_BMP_STRING => 'bmpString'
+ );
+
+ /**
+ * String type to character size mapping table.
+ *
+ * Non-convertable types are absent from this table.
+ * size == 0 indicates variable length encoding.
+ *
+ * @var array
+ * @access public
+ */
+ var $stringTypeSize = array(
+ self::TYPE_UTF8_STRING => 0,
+ self::TYPE_BMP_STRING => 2,
+ self::TYPE_UNIVERSAL_STRING => 4,
+ self::TYPE_PRINTABLE_STRING => 1,
+ self::TYPE_TELETEX_STRING => 1,
+ self::TYPE_IA5_STRING => 1,
+ self::TYPE_VISIBLE_STRING => 1,
+ );
+
+ /**
+ * Parse BER-encoding
+ *
+ * Serves a similar purpose to openssl's asn1parse
+ *
+ * @param string $encoded
+ * @return array
+ * @access public
+ */
+ function decodeBER($encoded)
+ {
+ if ($encoded instanceof Element) {
+ $encoded = $encoded->element;
+ }
+
+ $this->encoded = $encoded;
+ // encapsulate in an array for BC with the old decodeBER
+ return array($this->_decode_ber($encoded));
+ }
+
+ /**
+ * Parse BER-encoding (Helper function)
+ *
+ * Sometimes we want to get the BER encoding of a particular tag. $start lets us do that without having to reencode.
+ * $encoded is passed by reference for the recursive calls done for self::TYPE_BIT_STRING and
+ * self::TYPE_OCTET_STRING. In those cases, the indefinite length is used.
+ *
+ * @param string $encoded
+ * @param int $start
+ * @param int $encoded_pos
+ * @return array
+ * @access private
+ */
+ function _decode_ber($encoded, $start = 0, $encoded_pos = 0)
+ {
+ $current = array('start' => $start);
+
+ $type = ord($encoded[$encoded_pos++]);
+ $start++;
+
+ $constructed = ($type >> 5) & 1;
+
+ $tag = $type & 0x1F;
+ if ($tag == 0x1F) {
+ $tag = 0;
+ // process septets (since the eighth bit is ignored, it's not an octet)
+ do {
+ $temp = ord($encoded[$encoded_pos++]);
+ $loop = $temp >> 7;
+ $tag <<= 7;
+ $tag |= $temp & 0x7F;
+ $start++;
+ } while ($loop);
+ }
+
+ // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13
+ $length = ord($encoded[$encoded_pos++]);
+ $start++;
+ if ($length == 0x80) { // indefinite length
+ // "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all
+ // immediately available." -- paragraph 8.1.3.2.c
+ $length = strlen($encoded) - $encoded_pos;
+ } elseif ($length & 0x80) { // definite length, long form
+ // technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only
+ // support it up to four.
+ $length&= 0x7F;
+ $temp = substr($encoded, $encoded_pos, $length);
+ $encoded_pos += $length;
+ // tags of indefinte length don't really have a header length; this length includes the tag
+ $current+= array('headerlength' => $length + 2);
+ $start+= $length;
+ extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)));
+ } else {
+ $current+= array('headerlength' => 2);
+ }
+
+ if ($length > (strlen($encoded) - $encoded_pos)) {
+ return false;
+ }
+
+ $content = substr($encoded, $encoded_pos, $length);
+ $content_pos = 0;
+
+ // at this point $length can be overwritten. it's only accurate for definite length things as is
+
+ /* Class is UNIVERSAL, APPLICATION, PRIVATE, or CONTEXT-SPECIFIC. The UNIVERSAL class is restricted to the ASN.1
+ built-in types. It defines an application-independent data type that must be distinguishable from all other
+ data types. The other three classes are user defined. The APPLICATION class distinguishes data types that
+ have a wide, scattered use within a particular presentation context. PRIVATE distinguishes data types within
+ a particular organization or country. CONTEXT-SPECIFIC distinguishes members of a sequence or set, the
+ alternatives of a CHOICE, or universally tagged set members. Only the class number appears in braces for this
+ data type; the term CONTEXT-SPECIFIC does not appear.
+
+ -- http://www.obj-sys.com/asn1tutorial/node12.html */
+ $class = ($type >> 6) & 3;
+ switch ($class) {
+ case self::CLASS_APPLICATION:
+ case self::CLASS_PRIVATE:
+ case self::CLASS_CONTEXT_SPECIFIC:
+ if (!$constructed) {
+ return array(
+ 'type' => $class,
+ 'constant' => $tag,
+ 'content' => $content,
+ 'length' => $length + $start - $current['start']
+ );
+ }
+
+ $newcontent = array();
+ $remainingLength = $length;
+ while ($remainingLength > 0) {
+ $temp = $this->_decode_ber($content, $start, $content_pos);
+ if ($temp === false) {
+ break;
+ }
+ $length = $temp['length'];
+ // end-of-content octets - see paragraph 8.1.5
+ if (substr($content, $content_pos + $length, 2) == "\0\0") {
+ $length+= 2;
+ $start+= $length;
+ $newcontent[] = $temp;
+ break;
+ }
+ $start+= $length;
+ $remainingLength-= $length;
+ $newcontent[] = $temp;
+ $content_pos += $length;
+ }
+
+ return array(
+ 'type' => $class,
+ 'constant' => $tag,
+ // the array encapsulation is for BC with the old format
+ 'content' => $newcontent,
+ // the only time when $content['headerlength'] isn't defined is when the length is indefinite.
+ // the absence of $content['headerlength'] is how we know if something is indefinite or not.
+ // technically, it could be defined to be 2 and then another indicator could be used but whatever.
+ 'length' => $start - $current['start']
+ ) + $current;
+ }
+
+ $current+= array('type' => $tag);
+
+ // decode UNIVERSAL tags
+ switch ($tag) {
+ case self::TYPE_BOOLEAN:
+ // "The contents octets shall consist of a single octet." -- paragraph 8.2.1
+ //if (strlen($content) != 1) {
+ // return false;
+ //}
+ $current['content'] = (bool) ord($content[$content_pos]);
+ break;
+ case self::TYPE_INTEGER:
+ case self::TYPE_ENUMERATED:
+ $current['content'] = new BigInteger(substr($content, $content_pos), -256);
+ break;
+ case self::TYPE_REAL: // not currently supported
+ return false;
+ case self::TYPE_BIT_STRING:
+ // The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit,
+ // the number of unused bits in the final subsequent octet. The number shall be in the range zero to
+ // seven.
+ if (!$constructed) {
+ $current['content'] = substr($content, $content_pos);
+ } else {
+ $temp = $this->_decode_ber($content, $start, $content_pos);
+ if ($temp === false) {
+ return false;
+ }
+ $length-= (strlen($content) - $content_pos);
+ $last = count($temp) - 1;
+ for ($i = 0; $i < $last; $i++) {
+ // all subtags should be bit strings
+ //if ($temp[$i]['type'] != self::TYPE_BIT_STRING) {
+ // return false;
+ //}
+ $current['content'].= substr($temp[$i]['content'], 1);
+ }
+ // all subtags should be bit strings
+ //if ($temp[$last]['type'] != self::TYPE_BIT_STRING) {
+ // return false;
+ //}
+ $current['content'] = $temp[$last]['content'][0] . $current['content'] . substr($temp[$i]['content'], 1);
+ }
+ break;
+ case self::TYPE_OCTET_STRING:
+ if (!$constructed) {
+ $current['content'] = substr($content, $content_pos);
+ } else {
+ $current['content'] = '';
+ $length = 0;
+ while (substr($content, $content_pos, 2) != "\0\0") {
+ $temp = $this->_decode_ber($content, $length + $start, $content_pos);
+ if ($temp === false) {
+ return false;
+ }
+ $content_pos += $temp['length'];
+ // all subtags should be octet strings
+ //if ($temp['type'] != self::TYPE_OCTET_STRING) {
+ // return false;
+ //}
+ $current['content'].= $temp['content'];
+ $length+= $temp['length'];
+ }
+ if (substr($content, $content_pos, 2) == "\0\0") {
+ $length+= 2; // +2 for the EOC
+ }
+ }
+ break;
+ case self::TYPE_NULL:
+ // "The contents octets shall not contain any octets." -- paragraph 8.8.2
+ //if (strlen($content)) {
+ // return false;
+ //}
+ break;
+ case self::TYPE_SEQUENCE:
+ case self::TYPE_SET:
+ $offset = 0;
+ $current['content'] = array();
+ $content_len = strlen($content);
+ while ($content_pos < $content_len) {
+ // if indefinite length construction was used and we have an end-of-content string next
+ // see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2
+ if (!isset($current['headerlength']) && substr($content, $content_pos, 2) == "\0\0") {
+ $length = $offset + 2; // +2 for the EOC
+ break 2;
+ }
+ $temp = $this->_decode_ber($content, $start + $offset, $content_pos);
+ if ($temp === false) {
+ return false;
+ }
+ $content_pos += $temp['length'];
+ $current['content'][] = $temp;
+ $offset+= $temp['length'];
+ }
+ break;
+ case self::TYPE_OBJECT_IDENTIFIER:
+ $current['content'] = $this->_decodeOID(substr($content, $content_pos));
+ break;
+ /* Each character string type shall be encoded as if it had been declared:
+ [UNIVERSAL x] IMPLICIT OCTET STRING
+
+ -- X.690-0207.pdf#page=23 (paragraph 8.21.3)
+
+ Per that, we're not going to do any validation. If there are any illegal characters in the string,
+ we don't really care */
+ case self::TYPE_NUMERIC_STRING:
+ // 0,1,2,3,4,5,6,7,8,9, and space
+ case self::TYPE_PRINTABLE_STRING:
+ // Upper and lower case letters, digits, space, apostrophe, left/right parenthesis, plus sign, comma,
+ // hyphen, full stop, solidus, colon, equal sign, question mark
+ case self::TYPE_TELETEX_STRING:
+ // The Teletex character set in CCITT's T61, space, and delete
+ // see http://en.wikipedia.org/wiki/Teletex#Character_sets
+ case self::TYPE_VIDEOTEX_STRING:
+ // The Videotex character set in CCITT's T.100 and T.101, space, and delete
+ case self::TYPE_VISIBLE_STRING:
+ // Printing character sets of international ASCII, and space
+ case self::TYPE_IA5_STRING:
+ // International Alphabet 5 (International ASCII)
+ case self::TYPE_GRAPHIC_STRING:
+ // All registered G sets, and space
+ case self::TYPE_GENERAL_STRING:
+ // All registered C and G sets, space and delete
+ case self::TYPE_UTF8_STRING:
+ // ????
+ case self::TYPE_BMP_STRING:
+ $current['content'] = substr($content, $content_pos);
+ break;
+ case self::TYPE_UTC_TIME:
+ case self::TYPE_GENERALIZED_TIME:
+ $current['content'] = $this->_decodeTime(substr($content, $content_pos), $tag);
+ default:
+ }
+
+ $start+= $length;
+
+ // ie. length is the length of the full TLV encoding - it's not just the length of the value
+ return $current + array('length' => $start - $current['start']);
+ }
+
+ /**
+ * ASN.1 Map
+ *
+ * Provides an ASN.1 semantic mapping ($mapping) from a parsed BER-encoding to a human readable format.
+ *
+ * "Special" mappings may be applied on a per tag-name basis via $special.
+ *
+ * @param array $decoded
+ * @param array $mapping
+ * @param array $special
+ * @return array
+ * @access public
+ */
+ function asn1map($decoded, $mapping, $special = array())
+ {
+ if (!is_array($decoded)) {
+ return false;
+ }
+
+ if (isset($mapping['explicit']) && is_array($decoded['content'])) {
+ $decoded = $decoded['content'][0];
+ }
+
+ switch (true) {
+ case $mapping['type'] == self::TYPE_ANY:
+ $intype = $decoded['type'];
+ if (isset($decoded['constant']) || !isset($this->ANYmap[$intype]) || (ord($this->encoded[$decoded['start']]) & 0x20)) {
+ return new Element(substr($this->encoded, $decoded['start'], $decoded['length']));
+ }
+ $inmap = $this->ANYmap[$intype];
+ if (is_string($inmap)) {
+ return array($inmap => $this->asn1map($decoded, array('type' => $intype) + $mapping, $special));
+ }
+ break;
+ case $mapping['type'] == self::TYPE_CHOICE:
+ foreach ($mapping['children'] as $key => $option) {
+ switch (true) {
+ case isset($option['constant']) && $option['constant'] == $decoded['constant']:
+ case !isset($option['constant']) && $option['type'] == $decoded['type']:
+ $value = $this->asn1map($decoded, $option, $special);
+ break;
+ case !isset($option['constant']) && $option['type'] == self::TYPE_CHOICE:
+ $v = $this->asn1map($decoded, $option, $special);
+ if (isset($v)) {
+ $value = $v;
+ }
+ }
+ if (isset($value)) {
+ if (isset($special[$key])) {
+ $value = call_user_func($special[$key], $value);
+ }
+ return array($key => $value);
+ }
+ }
+ return null;
+ case isset($mapping['implicit']):
+ case isset($mapping['explicit']):
+ case $decoded['type'] == $mapping['type']:
+ break;
+ default:
+ // if $decoded['type'] and $mapping['type'] are both strings, but different types of strings,
+ // let it through
+ switch (true) {
+ case $decoded['type'] < 18: // self::TYPE_NUMERIC_STRING == 18
+ case $decoded['type'] > 30: // self::TYPE_BMP_STRING == 30
+ case $mapping['type'] < 18:
+ case $mapping['type'] > 30:
+ return null;
+ }
+ }
+
+ if (isset($mapping['implicit'])) {
+ $decoded['type'] = $mapping['type'];
+ }
+
+ switch ($decoded['type']) {
+ case self::TYPE_SEQUENCE:
+ $map = array();
+
+ // ignore the min and max
+ if (isset($mapping['min']) && isset($mapping['max'])) {
+ $child = $mapping['children'];
+ foreach ($decoded['content'] as $content) {
+ if (($map[] = $this->asn1map($content, $child, $special)) === null) {
+ return null;
+ }
+ }
+
+ return $map;
+ }
+
+ $n = count($decoded['content']);
+ $i = 0;
+
+ foreach ($mapping['children'] as $key => $child) {
+ $maymatch = $i < $n; // Match only existing input.
+ if ($maymatch) {
+ $temp = $decoded['content'][$i];
+
+ if ($child['type'] != self::TYPE_CHOICE) {
+ // Get the mapping and input class & constant.
+ $childClass = $tempClass = self::CLASS_UNIVERSAL;
+ $constant = null;
+ if (isset($temp['constant'])) {
+ $tempClass = $temp['type'];
+ }
+ if (isset($child['class'])) {
+ $childClass = $child['class'];
+ $constant = $child['cast'];
+ } elseif (isset($child['constant'])) {
+ $childClass = self::CLASS_CONTEXT_SPECIFIC;
+ $constant = $child['constant'];
+ }
+
+ if (isset($constant) && isset($temp['constant'])) {
+ // Can only match if constants and class match.
+ $maymatch = $constant == $temp['constant'] && $childClass == $tempClass;
+ } else {
+ // Can only match if no constant expected and type matches or is generic.
+ $maymatch = !isset($child['constant']) && array_search($child['type'], array($temp['type'], self::TYPE_ANY, self::TYPE_CHOICE)) !== false;
+ }
+ }
+ }
+
+ if ($maymatch) {
+ // Attempt submapping.
+ $candidate = $this->asn1map($temp, $child, $special);
+ $maymatch = $candidate !== null;
+ }
+
+ if ($maymatch) {
+ // Got the match: use it.
+ if (isset($special[$key])) {
+ $candidate = call_user_func($special[$key], $candidate);
+ }
+ $map[$key] = $candidate;
+ $i++;
+ } elseif (isset($child['default'])) {
+ $map[$key] = $child['default']; // Use default.
+ } elseif (!isset($child['optional'])) {
+ return null; // Syntax error.
+ }
+ }
+
+ // Fail mapping if all input items have not been consumed.
+ return $i < $n ? null: $map;
+
+ // the main diff between sets and sequences is the encapsulation of the foreach in another for loop
+ case self::TYPE_SET:
+ $map = array();
+
+ // ignore the min and max
+ if (isset($mapping['min']) && isset($mapping['max'])) {
+ $child = $mapping['children'];
+ foreach ($decoded['content'] as $content) {
+ if (($map[] = $this->asn1map($content, $child, $special)) === null) {
+ return null;
+ }
+ }
+
+ return $map;
+ }
+
+ for ($i = 0; $i < count($decoded['content']); $i++) {
+ $temp = $decoded['content'][$i];
+ $tempClass = self::CLASS_UNIVERSAL;
+ if (isset($temp['constant'])) {
+ $tempClass = $temp['type'];
+ }
+
+ foreach ($mapping['children'] as $key => $child) {
+ if (isset($map[$key])) {
+ continue;
+ }
+ $maymatch = true;
+ if ($child['type'] != self::TYPE_CHOICE) {
+ $childClass = self::CLASS_UNIVERSAL;
+ $constant = null;
+ if (isset($child['class'])) {
+ $childClass = $child['class'];
+ $constant = $child['cast'];
+ } elseif (isset($child['constant'])) {
+ $childClass = self::CLASS_CONTEXT_SPECIFIC;
+ $constant = $child['constant'];
+ }
+
+ if (isset($constant) && isset($temp['constant'])) {
+ // Can only match if constants and class match.
+ $maymatch = $constant == $temp['constant'] && $childClass == $tempClass;
+ } else {
+ // Can only match if no constant expected and type matches or is generic.
+ $maymatch = !isset($child['constant']) && array_search($child['type'], array($temp['type'], self::TYPE_ANY, self::TYPE_CHOICE)) !== false;
+ }
+ }
+
+ if ($maymatch) {
+ // Attempt submapping.
+ $candidate = $this->asn1map($temp, $child, $special);
+ $maymatch = $candidate !== null;
+ }
+
+ if (!$maymatch) {
+ break;
+ }
+
+ // Got the match: use it.
+ if (isset($special[$key])) {
+ $candidate = call_user_func($special[$key], $candidate);
+ }
+ $map[$key] = $candidate;
+ break;
+ }
+ }
+
+ foreach ($mapping['children'] as $key => $child) {
+ if (!isset($map[$key])) {
+ if (isset($child['default'])) {
+ $map[$key] = $child['default'];
+ } elseif (!isset($child['optional'])) {
+ return null;
+ }
+ }
+ }
+ return $map;
+ case self::TYPE_OBJECT_IDENTIFIER:
+ return isset($this->oids[$decoded['content']]) ? $this->oids[$decoded['content']] : $decoded['content'];
+ case self::TYPE_UTC_TIME:
+ case self::TYPE_GENERALIZED_TIME:
+ // for explicitly tagged optional stuff
+ if (is_array($decoded['content'])) {
+ $decoded['content'] = $decoded['content'][0]['content'];
+ }
+ // for implicitly tagged optional stuff
+ // in theory, doing isset($mapping['implicit']) would work but malformed certs do exist
+ // in the wild that OpenSSL decodes without issue so we'll support them as well
+ if (!is_object($decoded['content'])) {
+ $decoded['content'] = $this->_decodeTime($decoded['content'], $decoded['type']);
+ }
+ return $decoded['content'] ? $decoded['content']->format($this->format) : false;
+ case self::TYPE_BIT_STRING:
+ if (isset($mapping['mapping'])) {
+ $offset = ord($decoded['content'][0]);
+ $size = (strlen($decoded['content']) - 1) * 8 - $offset;
+ /*
+ From X.680-0207.pdf#page=46 (21.7):
+
+ "When a "NamedBitList" is used in defining a bitstring type ASN.1 encoding rules are free to add (or remove)
+ arbitrarily any trailing 0 bits to (or from) values that are being encoded or decoded. Application designers should
+ therefore ensure that different semantics are not associated with such values which differ only in the number of trailing
+ 0 bits."
+ */
+ $bits = count($mapping['mapping']) == $size ? array() : array_fill(0, count($mapping['mapping']) - $size, false);
+ for ($i = strlen($decoded['content']) - 1; $i > 0; $i--) {
+ $current = ord($decoded['content'][$i]);
+ for ($j = $offset; $j < 8; $j++) {
+ $bits[] = (bool) ($current & (1 << $j));
+ }
+ $offset = 0;
+ }
+ $values = array();
+ $map = array_reverse($mapping['mapping']);
+ foreach ($map as $i => $value) {
+ if ($bits[$i]) {
+ $values[] = $value;
+ }
+ }
+ return $values;
+ }
+ case self::TYPE_OCTET_STRING:
+ return base64_encode($decoded['content']);
+ case self::TYPE_NULL:
+ return '';
+ case self::TYPE_BOOLEAN:
+ return $decoded['content'];
+ case self::TYPE_NUMERIC_STRING:
+ case self::TYPE_PRINTABLE_STRING:
+ case self::TYPE_TELETEX_STRING:
+ case self::TYPE_VIDEOTEX_STRING:
+ case self::TYPE_IA5_STRING:
+ case self::TYPE_GRAPHIC_STRING:
+ case self::TYPE_VISIBLE_STRING:
+ case self::TYPE_GENERAL_STRING:
+ case self::TYPE_UNIVERSAL_STRING:
+ case self::TYPE_UTF8_STRING:
+ case self::TYPE_BMP_STRING:
+ return $decoded['content'];
+ case self::TYPE_INTEGER:
+ case self::TYPE_ENUMERATED:
+ $temp = $decoded['content'];
+ if (isset($mapping['implicit'])) {
+ $temp = new BigInteger($decoded['content'], -256);
+ }
+ if (isset($mapping['mapping'])) {
+ $temp = (int) $temp->toString();
+ return isset($mapping['mapping'][$temp]) ?
+ $mapping['mapping'][$temp] :
+ false;
+ }
+ return $temp;
+ }
+ }
+
+ /**
+ * ASN.1 Encode
+ *
+ * DER-encodes an ASN.1 semantic mapping ($mapping). Some libraries would probably call this function
+ * an ASN.1 compiler.
+ *
+ * "Special" mappings can be applied via $special.
+ *
+ * @param string $source
+ * @param string $mapping
+ * @param int $idx
+ * @return string
+ * @access public
+ */
+ function encodeDER($source, $mapping, $special = array())
+ {
+ $this->location = array();
+ return $this->_encode_der($source, $mapping, null, $special);
+ }
+
+ /**
+ * ASN.1 Encode (Helper function)
+ *
+ * @param string $source
+ * @param string $mapping
+ * @param int $idx
+ * @return string
+ * @access private
+ */
+ function _encode_der($source, $mapping, $idx = null, $special = array())
+ {
+ if ($source instanceof Element) {
+ return $source->element;
+ }
+
+ // do not encode (implicitly optional) fields with value set to default
+ if (isset($mapping['default']) && $source === $mapping['default']) {
+ return '';
+ }
+
+ if (isset($idx)) {
+ if (isset($special[$idx])) {
+ $source = call_user_func($special[$idx], $source);
+ }
+ $this->location[] = $idx;
+ }
+
+ $tag = $mapping['type'];
+
+ switch ($tag) {
+ case self::TYPE_SET: // Children order is not important, thus process in sequence.
+ case self::TYPE_SEQUENCE:
+ $tag|= 0x20; // set the constructed bit
+
+ // ignore the min and max
+ if (isset($mapping['min']) && isset($mapping['max'])) {
+ $value = array();
+ $child = $mapping['children'];
+
+ foreach ($source as $content) {
+ $temp = $this->_encode_der($content, $child, null, $special);
+ if ($temp === false) {
+ return false;
+ }
+ $value[]= $temp;
+ }
+ /* "The encodings of the component values of a set-of value shall appear in ascending order, the encodings being compared
+ as octet strings with the shorter components being padded at their trailing end with 0-octets.
+ NOTE - The padding octets are for comparison purposes only and do not appear in the encodings."
+
+ -- sec 11.6 of http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf */
+ if ($mapping['type'] == self::TYPE_SET) {
+ sort($value);
+ }
+ $value = implode('', $value);
+ break;
+ }
+
+ $value = '';
+ foreach ($mapping['children'] as $key => $child) {
+ if (!array_key_exists($key, $source)) {
+ if (!isset($child['optional'])) {
+ return false;
+ }
+ continue;
+ }
+
+ $temp = $this->_encode_der($source[$key], $child, $key, $special);
+ if ($temp === false) {
+ return false;
+ }
+
+ // An empty child encoding means it has been optimized out.
+ // Else we should have at least one tag byte.
+ if ($temp === '') {
+ continue;
+ }
+
+ // if isset($child['constant']) is true then isset($child['optional']) should be true as well
+ if (isset($child['constant'])) {
+ /*
+ From X.680-0207.pdf#page=58 (30.6):
+
+ "The tagging construction specifies explicit tagging if any of the following holds:
+ ...
+ c) the "Tag Type" alternative is used and the value of "TagDefault" for the module is IMPLICIT TAGS or
+ AUTOMATIC TAGS, but the type defined by "Type" is an untagged choice type, an untagged open type, or
+ an untagged "DummyReference" (see ITU-T Rec. X.683 | ISO/IEC 8824-4, 8.3)."
+ */
+ if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) {
+ $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']);
+ $temp = $subtag . $this->_encodeLength(strlen($temp)) . $temp;
+ } else {
+ $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']);
+ $temp = $subtag . substr($temp, 1);
+ }
+ }
+ $value.= $temp;
+ }
+ break;
+ case self::TYPE_CHOICE:
+ $temp = false;
+
+ foreach ($mapping['children'] as $key => $child) {
+ if (!isset($source[$key])) {
+ continue;
+ }
+
+ $temp = $this->_encode_der($source[$key], $child, $key, $special);
+ if ($temp === false) {
+ return false;
+ }
+
+ // An empty child encoding means it has been optimized out.
+ // Else we should have at least one tag byte.
+ if ($temp === '') {
+ continue;
+ }
+
+ $tag = ord($temp[0]);
+
+ // if isset($child['constant']) is true then isset($child['optional']) should be true as well
+ if (isset($child['constant'])) {
+ if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) {
+ $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']);
+ $temp = $subtag . $this->_encodeLength(strlen($temp)) . $temp;
+ } else {
+ $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']);
+ $temp = $subtag . substr($temp, 1);
+ }
+ }
+ }
+
+ if (isset($idx)) {
+ array_pop($this->location);
+ }
+
+ if ($temp && isset($mapping['cast'])) {
+ $temp[0] = chr(($mapping['class'] << 6) | ($tag & 0x20) | $mapping['cast']);
+ }
+
+ return $temp;
+ case self::TYPE_INTEGER:
+ case self::TYPE_ENUMERATED:
+ if (!isset($mapping['mapping'])) {
+ if (is_numeric($source)) {
+ $source = new BigInteger($source);
+ }
+ $value = $source->toBytes(true);
+ } else {
+ $value = array_search($source, $mapping['mapping']);
+ if ($value === false) {
+ return false;
+ }
+ $value = new BigInteger($value);
+ $value = $value->toBytes(true);
+ }
+ if (!strlen($value)) {
+ $value = chr(0);
+ }
+ break;
+ case self::TYPE_UTC_TIME:
+ case self::TYPE_GENERALIZED_TIME:
+ $format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y';
+ $format.= 'mdHis';
+ $date = new DateTime($source, new DateTimeZone('GMT'));
+ $value = $date->format($format) . 'Z';
+ break;
+ case self::TYPE_BIT_STRING:
+ if (isset($mapping['mapping'])) {
+ $bits = array_fill(0, count($mapping['mapping']), 0);
+ $size = 0;
+ for ($i = 0; $i < count($mapping['mapping']); $i++) {
+ if (in_array($mapping['mapping'][$i], $source)) {
+ $bits[$i] = 1;
+ $size = $i;
+ }
+ }
+
+ if (isset($mapping['min']) && $mapping['min'] >= 1 && $size < $mapping['min']) {
+ $size = $mapping['min'] - 1;
+ }
+
+ $offset = 8 - (($size + 1) & 7);
+ $offset = $offset !== 8 ? $offset : 0;
+
+ $value = chr($offset);
+
+ for ($i = $size + 1; $i < count($mapping['mapping']); $i++) {
+ unset($bits[$i]);
+ }
+
+ $bits = implode('', array_pad($bits, $size + $offset + 1, 0));
+ $bytes = explode(' ', rtrim(chunk_split($bits, 8, ' ')));
+ foreach ($bytes as $byte) {
+ $value.= chr(bindec($byte));
+ }
+
+ break;
+ }
+ case self::TYPE_OCTET_STRING:
+ /* The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit,
+ the number of unused bits in the final subsequent octet. The number shall be in the range zero to seven.
+
+ -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=16 */
+ $value = base64_decode($source);
+ break;
+ case self::TYPE_OBJECT_IDENTIFIER:
+ $value = $this->_encodeOID($source);
+ break;
+ case self::TYPE_ANY:
+ $loc = $this->location;
+ if (isset($idx)) {
+ array_pop($this->location);
+ }
+
+ switch (true) {
+ case !isset($source):
+ return $this->_encode_der(null, array('type' => self::TYPE_NULL) + $mapping, null, $special);
+ case is_int($source):
+ case $source instanceof BigInteger:
+ return $this->_encode_der($source, array('type' => self::TYPE_INTEGER) + $mapping, null, $special);
+ case is_float($source):
+ return $this->_encode_der($source, array('type' => self::TYPE_REAL) + $mapping, null, $special);
+ case is_bool($source):
+ return $this->_encode_der($source, array('type' => self::TYPE_BOOLEAN) + $mapping, null, $special);
+ case is_array($source) && count($source) == 1:
+ $typename = implode('', array_keys($source));
+ $outtype = array_search($typename, $this->ANYmap, true);
+ if ($outtype !== false) {
+ return $this->_encode_der($source[$typename], array('type' => $outtype) + $mapping, null, $special);
+ }
+ }
+
+ $filters = $this->filters;
+ foreach ($loc as $part) {
+ if (!isset($filters[$part])) {
+ $filters = false;
+ break;
+ }
+ $filters = $filters[$part];
+ }
+ if ($filters === false) {
+ user_error('No filters defined for ' . implode('/', $loc));
+ return false;
+ }
+ return $this->_encode_der($source, $filters + $mapping, null, $special);
+ case self::TYPE_NULL:
+ $value = '';
+ break;
+ case self::TYPE_NUMERIC_STRING:
+ case self::TYPE_TELETEX_STRING:
+ case self::TYPE_PRINTABLE_STRING:
+ case self::TYPE_UNIVERSAL_STRING:
+ case self::TYPE_UTF8_STRING:
+ case self::TYPE_BMP_STRING:
+ case self::TYPE_IA5_STRING:
+ case self::TYPE_VISIBLE_STRING:
+ case self::TYPE_VIDEOTEX_STRING:
+ case self::TYPE_GRAPHIC_STRING:
+ case self::TYPE_GENERAL_STRING:
+ $value = $source;
+ break;
+ case self::TYPE_BOOLEAN:
+ $value = $source ? "\xFF" : "\x00";
+ break;
+ default:
+ user_error('Mapping provides no type definition for ' . implode('/', $this->location));
+ return false;
+ }
+
+ if (isset($idx)) {
+ array_pop($this->location);
+ }
+
+ if (isset($mapping['cast'])) {
+ if (isset($mapping['explicit']) || $mapping['type'] == self::TYPE_CHOICE) {
+ $value = chr($tag) . $this->_encodeLength(strlen($value)) . $value;
+ $tag = ($mapping['class'] << 6) | 0x20 | $mapping['cast'];
+ } else {
+ $tag = ($mapping['class'] << 6) | (ord($temp[0]) & 0x20) | $mapping['cast'];
+ }
+ }
+
+ return chr($tag) . $this->_encodeLength(strlen($value)) . $value;
+ }
+
+ /**
+ * DER-encode the length
+ *
+ * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See
+ * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information.
+ *
+ * @access private
+ * @param int $length
+ * @return string
+ */
+ function _encodeLength($length)
+ {
+ if ($length <= 0x7F) {
+ return chr($length);
+ }
+
+ $temp = ltrim(pack('N', $length), chr(0));
+ return pack('Ca*', 0x80 | strlen($temp), $temp);
+ }
+
+ /**
+ * BER-decode the OID
+ *
+ * Called by _decode_ber()
+ *
+ * @access private
+ * @param string $content
+ * @return string
+ */
+ function _decodeOID($content)
+ {
+ static $eighty;
+ if (!$eighty) {
+ $eighty = new BigInteger(80);
+ }
+
+ $oid = array();
+ $pos = 0;
+ $len = strlen($content);
+ $n = new BigInteger();
+ while ($pos < $len) {
+ $temp = ord($content[$pos++]);
+ $n = $n->bitwise_leftShift(7);
+ $n = $n->bitwise_or(new BigInteger($temp & 0x7F));
+ if (~$temp & 0x80) {
+ $oid[] = $n;
+ $n = new BigInteger();
+ }
+ }
+ $part1 = array_shift($oid);
+ $first = floor(ord($content[0]) / 40);
+ /*
+ "This packing of the first two object identifier components recognizes that only three values are allocated from the root
+ node, and at most 39 subsequent values from nodes reached by X = 0 and X = 1."
+
+ -- https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=22
+ */
+ if ($first <= 2) { // ie. 0 <= ord($content[0]) < 120 (0x78)
+ array_unshift($oid, ord($content[0]) % 40);
+ array_unshift($oid, $first);
+ } else {
+ array_unshift($oid, $part1->subtract($eighty));
+ array_unshift($oid, 2);
+ }
+
+ return implode('.', $oid);
+ }
+
+ /**
+ * DER-encode the OID
+ *
+ * Called by _encode_der()
+ *
+ * @access private
+ * @param string $content
+ * @return string
+ */
+ function _encodeOID($source)
+ {
+ static $mask, $zero, $forty;
+ if (!$mask) {
+ $mask = new BigInteger(0x7F);
+ $zero = new BigInteger();
+ $forty = new BigInteger(40);
+ }
+
+ $oid = preg_match('#(?:\d+\.)+#', $source) ? $source : array_search($source, $this->oids);
+ if ($oid === false) {
+ user_error('Invalid OID');
+ return false;
+ }
+ $parts = explode('.', $oid);
+ $part1 = array_shift($parts);
+ $part2 = array_shift($parts);
+
+ $first = new BigInteger($part1);
+ $first = $first->multiply($forty);
+ $first = $first->add(new BigInteger($part2));
+
+ array_unshift($parts, $first->toString());
+
+ $value = '';
+ foreach ($parts as $part) {
+ if (!$part) {
+ $temp = "\0";
+ } else {
+ $temp = '';
+ $part = new BigInteger($part);
+ while (!$part->equals($zero)) {
+ $submask = $part->bitwise_and($mask);
+ $submask->setPrecision(8);
+ $temp = (chr(0x80) | $submask->toBytes()) . $temp;
+ $part = $part->bitwise_rightShift(7);
+ }
+ $temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F);
+ }
+ $value.= $temp;
+ }
+
+ return $value;
+ }
+
+ /**
+ * BER-decode the time
+ *
+ * Called by _decode_ber() and in the case of implicit tags asn1map().
+ *
+ * @access private
+ * @param string $content
+ * @param int $tag
+ * @return string
+ */
+ function _decodeTime($content, $tag)
+ {
+ /* UTCTime:
+ http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
+ http://www.obj-sys.com/asn1tutorial/node15.html
+
+ GeneralizedTime:
+ http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2
+ http://www.obj-sys.com/asn1tutorial/node14.html */
+
+ $format = 'YmdHis';
+
+ if ($tag == self::TYPE_UTC_TIME) {
+ // https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=28 says "the seconds
+ // element shall always be present" but none-the-less I've seen X509 certs where it isn't and if the
+ // browsers parse it phpseclib ought to too
+ if (preg_match('#^(\d{10})(Z|[+-]\d{4})$#', $content, $matches)) {
+ $content = $matches[1] . '00' . $matches[2];
+ }
+ $prefix = substr($content, 0, 2) >= 50 ? '19' : '20';
+ $content = $prefix . $content;
+ } elseif (strpos($content, '.') !== false) {
+ $format.= '.u';
+ }
+
+ if ($content[strlen($content) - 1] == 'Z') {
+ $content = substr($content, 0, -1) . '+0000';
+ }
+
+ if (strpos($content, '-') !== false || strpos($content, '+') !== false) {
+ $format.= 'O';
+ }
+
+ // error supression isn't necessary as of PHP 7.0:
+ // http://php.net/manual/en/migration70.other-changes.php
+ return @DateTime::createFromFormat($format, $content);
+ }
+
+ /**
+ * Set the time format
+ *
+ * Sets the time / date format for asn1map().
+ *
+ * @access public
+ * @param string $format
+ */
+ function setTimeFormat($format)
+ {
+ $this->format = $format;
+ }
+
+ /**
+ * Load OIDs
+ *
+ * Load the relevant OIDs for a particular ASN.1 semantic mapping.
+ *
+ * @access public
+ * @param array $oids
+ */
+ function loadOIDs($oids)
+ {
+ $this->oids = $oids;
+ }
+
+ /**
+ * Load filters
+ *
+ * See \phpseclib\File\X509, etc, for an example.
+ *
+ * @access public
+ * @param array $filters
+ */
+ function loadFilters($filters)
+ {
+ $this->filters = $filters;
+ }
+
+ /**
+ * String Shift
+ *
+ * Inspired by array_shift
+ *
+ * @param string $string
+ * @param int $index
+ * @return string
+ * @access private
+ */
+ function _string_shift(&$string, $index = 1)
+ {
+ $substr = substr($string, 0, $index);
+ $string = substr($string, $index);
+ return $substr;
+ }
+
+ /**
+ * String type conversion
+ *
+ * This is a lazy conversion, dealing only with character size.
+ * No real conversion table is used.
+ *
+ * @param string $in
+ * @param int $from
+ * @param int $to
+ * @return string
+ * @access public
+ */
+ function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING)
+ {
+ if (!isset($this->stringTypeSize[$from]) || !isset($this->stringTypeSize[$to])) {
+ return false;
+ }
+ $insize = $this->stringTypeSize[$from];
+ $outsize = $this->stringTypeSize[$to];
+ $inlength = strlen($in);
+ $out = '';
+
+ for ($i = 0; $i < $inlength;) {
+ if ($inlength - $i < $insize) {
+ return false;
+ }
+
+ // Get an input character as a 32-bit value.
+ $c = ord($in[$i++]);
+ switch (true) {
+ case $insize == 4:
+ $c = ($c << 8) | ord($in[$i++]);
+ $c = ($c << 8) | ord($in[$i++]);
+ case $insize == 2:
+ $c = ($c << 8) | ord($in[$i++]);
+ case $insize == 1:
+ break;
+ case ($c & 0x80) == 0x00:
+ break;
+ case ($c & 0x40) == 0x00:
+ return false;
+ default:
+ $bit = 6;
+ do {
+ if ($bit > 25 || $i >= $inlength || (ord($in[$i]) & 0xC0) != 0x80) {
+ return false;
+ }
+ $c = ($c << 6) | (ord($in[$i++]) & 0x3F);
+ $bit += 5;
+ $mask = 1 << $bit;
+ } while ($c & $bit);
+ $c &= $mask - 1;
+ break;
+ }
+
+ // Convert and append the character to output string.
+ $v = '';
+ switch (true) {
+ case $outsize == 4:
+ $v .= chr($c & 0xFF);
+ $c >>= 8;
+ $v .= chr($c & 0xFF);
+ $c >>= 8;
+ case $outsize == 2:
+ $v .= chr($c & 0xFF);
+ $c >>= 8;
+ case $outsize == 1:
+ $v .= chr($c & 0xFF);
+ $c >>= 8;
+ if ($c) {
+ return false;
+ }
+ break;
+ case ($c & 0x80000000) != 0:
+ return false;
+ case $c >= 0x04000000:
+ $v .= chr(0x80 | ($c & 0x3F));
+ $c = ($c >> 6) | 0x04000000;
+ case $c >= 0x00200000:
+ $v .= chr(0x80 | ($c & 0x3F));
+ $c = ($c >> 6) | 0x00200000;
+ case $c >= 0x00010000:
+ $v .= chr(0x80 | ($c & 0x3F));
+ $c = ($c >> 6) | 0x00010000;
+ case $c >= 0x00000800:
+ $v .= chr(0x80 | ($c & 0x3F));
+ $c = ($c >> 6) | 0x00000800;
+ case $c >= 0x00000080:
+ $v .= chr(0x80 | ($c & 0x3F));
+ $c = ($c >> 6) | 0x000000C0;
+ default:
+ $v .= chr($c);
+ break;
+ }
+ $out .= strrev($v);
+ }
+ return $out;
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php
new file mode 100644
index 0000000..68246e2
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Pure-PHP ASN.1 Parser
+ *
+ * PHP version 5
+ *
+ * @category File
+ * @package ASN1
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2012 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\File\ASN1;
+
+/**
+ * ASN.1 Element
+ *
+ * Bypass normal encoding rules in phpseclib\File\ASN1::encodeDER()
+ *
+ * @package ASN1
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class Element
+{
+ /**
+ * Raw element value
+ *
+ * @var string
+ * @access private
+ */
+ var $element;
+
+ /**
+ * Constructor
+ *
+ * @param string $encoded
+ * @return \phpseclib\File\ASN1\Element
+ * @access public
+ */
+ function __construct($encoded)
+ {
+ $this->element = $encoded;
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
new file mode 100644
index 0000000..ddbc615
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/File/X509.php
@@ -0,0 +1,5092 @@
+<?php
+
+/**
+ * Pure-PHP X.509 Parser
+ *
+ * PHP version 5
+ *
+ * Encode and decode X.509 certificates.
+ *
+ * The extensions are from {@link http://tools.ietf.org/html/rfc5280 RFC5280} and
+ * {@link http://web.archive.org/web/19961027104704/http://www3.netscape.com/eng/security/cert-exts.html Netscape Certificate Extensions}.
+ *
+ * Note that loading an X.509 certificate and resaving it may invalidate the signature. The reason being that the signature is based on a
+ * portion of the certificate that contains optional parameters with default values. ie. if the parameter isn't there the default value is
+ * used. Problem is, if the parameter is there and it just so happens to have the default value there are two ways that that parameter can
+ * be encoded. It can be encoded explicitly or left out all together. This would effect the signature value and thus may invalidate the
+ * the certificate all together unless the certificate is re-signed.
+ *
+ * @category File
+ * @package X509
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2012 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\File;
+
+use phpseclib\Crypt\Hash;
+use phpseclib\Crypt\Random;
+use phpseclib\Crypt\RSA;
+use phpseclib\File\ASN1\Element;
+use phpseclib\Math\BigInteger;
+use DateTime;
+use DateTimeZone;
+
+/**
+ * Pure-PHP X.509 Parser
+ *
+ * @package X509
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class X509
+{
+ /**
+ * Flag to only accept signatures signed by certificate authorities
+ *
+ * Not really used anymore but retained all the same to suppress E_NOTICEs from old installs
+ *
+ * @access public
+ */
+ const VALIDATE_SIGNATURE_BY_CA = 1;
+
+ /**#@+
+ * @access public
+ * @see \phpseclib\File\X509::getDN()
+ */
+ /**
+ * Return internal array representation
+ */
+ const DN_ARRAY = 0;
+ /**
+ * Return string
+ */
+ const DN_STRING = 1;
+ /**
+ * Return ASN.1 name string
+ */
+ const DN_ASN1 = 2;
+ /**
+ * Return OpenSSL compatible array
+ */
+ const DN_OPENSSL = 3;
+ /**
+ * Return canonical ASN.1 RDNs string
+ */
+ const DN_CANON = 4;
+ /**
+ * Return name hash for file indexing
+ */
+ const DN_HASH = 5;
+ /**#@-*/
+
+ /**#@+
+ * @access public
+ * @see \phpseclib\File\X509::saveX509()
+ * @see \phpseclib\File\X509::saveCSR()
+ * @see \phpseclib\File\X509::saveCRL()
+ */
+ /**
+ * Save as PEM
+ *
+ * ie. a base64-encoded PEM with a header and a footer
+ */
+ const FORMAT_PEM = 0;
+ /**
+ * Save as DER
+ */
+ const FORMAT_DER = 1;
+ /**
+ * Save as a SPKAC
+ *
+ * Only works on CSRs. Not currently supported.
+ */
+ const FORMAT_SPKAC = 2;
+ /**
+ * Auto-detect the format
+ *
+ * Used only by the load*() functions
+ */
+ const FORMAT_AUTO_DETECT = 3;
+ /**#@-*/
+
+ /**
+ * Attribute value disposition.
+ * If disposition is >= 0, this is the index of the target value.
+ */
+ const ATTR_ALL = -1; // All attribute values (array).
+ const ATTR_APPEND = -2; // Add a value.
+ const ATTR_REPLACE = -3; // Clear first, then add a value.
+
+ /**
+ * ASN.1 syntax for X.509 certificates
+ *
+ * @var array
+ * @access private
+ */
+ var $Certificate;
+
+ /**#@+
+ * ASN.1 syntax for various extensions
+ *
+ * @access private
+ */
+ var $DirectoryString;
+ var $PKCS9String;
+ var $AttributeValue;
+ var $Extensions;
+ var $KeyUsage;
+ var $ExtKeyUsageSyntax;
+ var $BasicConstraints;
+ var $KeyIdentifier;
+ var $CRLDistributionPoints;
+ var $AuthorityKeyIdentifier;
+ var $CertificatePolicies;
+ var $AuthorityInfoAccessSyntax;
+ var $SubjectAltName;
+ var $SubjectDirectoryAttributes;
+ var $PrivateKeyUsagePeriod;
+ var $IssuerAltName;
+ var $PolicyMappings;
+ var $NameConstraints;
+
+ var $CPSuri;
+ var $UserNotice;
+
+ var $netscape_cert_type;
+ var $netscape_comment;
+ var $netscape_ca_policy_url;
+
+ var $Name;
+ var $RelativeDistinguishedName;
+ var $CRLNumber;
+ var $CRLReason;
+ var $IssuingDistributionPoint;
+ var $InvalidityDate;
+ var $CertificateIssuer;
+ var $HoldInstructionCode;
+ var $SignedPublicKeyAndChallenge;
+ /**#@-*/
+
+ /**#@+
+ * ASN.1 syntax for various DN attributes
+ *
+ * @access private
+ */
+ var $PostalAddress;
+ /**#@-*/
+
+ /**
+ * ASN.1 syntax for Certificate Signing Requests (RFC2986)
+ *
+ * @var array
+ * @access private
+ */
+ var $CertificationRequest;
+
+ /**
+ * ASN.1 syntax for Certificate Revocation Lists (RFC5280)
+ *
+ * @var array
+ * @access private
+ */
+ var $CertificateList;
+
+ /**
+ * Distinguished Name
+ *
+ * @var array
+ * @access private
+ */
+ var $dn;
+
+ /**
+ * Public key
+ *
+ * @var string
+ * @access private
+ */
+ var $publicKey;
+
+ /**
+ * Private key
+ *
+ * @var string
+ * @access private
+ */
+ var $privateKey;
+
+ /**
+ * Object identifiers for X.509 certificates
+ *
+ * @var array
+ * @access private
+ * @link http://en.wikipedia.org/wiki/Object_identifier
+ */
+ var $oids;
+
+ /**
+ * The certificate authorities
+ *
+ * @var array
+ * @access private
+ */
+ var $CAs;
+
+ /**
+ * The currently loaded certificate
+ *
+ * @var array
+ * @access private
+ */
+ var $currentCert;
+
+ /**
+ * The signature subject
+ *
+ * There's no guarantee \phpseclib\File\X509 is going to re-encode an X.509 cert in the same way it was originally
+ * encoded so we take save the portion of the original cert that the signature would have made for.
+ *
+ * @var string
+ * @access private
+ */
+ var $signatureSubject;
+
+ /**
+ * Certificate Start Date
+ *
+ * @var string
+ * @access private
+ */
+ var $startDate;
+
+ /**
+ * Certificate End Date
+ *
+ * @var string
+ * @access private
+ */
+ var $endDate;
+
+ /**
+ * Serial Number
+ *
+ * @var string
+ * @access private
+ */
+ var $serialNumber;
+
+ /**
+ * Key Identifier
+ *
+ * See {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.1 RFC5280#section-4.2.1.1} and
+ * {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.2 RFC5280#section-4.2.1.2}.
+ *
+ * @var string
+ * @access private
+ */
+ var $currentKeyIdentifier;
+
+ /**
+ * CA Flag
+ *
+ * @var bool
+ * @access private
+ */
+ var $caFlag = false;
+
+ /**
+ * SPKAC Challenge
+ *
+ * @var string
+ * @access private
+ */
+ var $challenge;
+
+ /**
+ * Recursion Limit
+ *
+ * @var int
+ * @access private
+ */
+ static $recur_limit = 5;
+
+ /**
+ * URL fetch flag
+ *
+ * @var bool
+ * @access private
+ */
+ static $disable_url_fetch = false;
+
+ /**
+ * Default Constructor.
+ *
+ * @return \phpseclib\File\X509
+ * @access public
+ */
+ function __construct()
+ {
+ // Explicitly Tagged Module, 1988 Syntax
+ // http://tools.ietf.org/html/rfc5280#appendix-A.1
+
+ $this->DirectoryString = array(
+ 'type' => ASN1::TYPE_CHOICE,
+ 'children' => array(
+ 'teletexString' => array('type' => ASN1::TYPE_TELETEX_STRING),
+ 'printableString' => array('type' => ASN1::TYPE_PRINTABLE_STRING),
+ 'universalString' => array('type' => ASN1::TYPE_UNIVERSAL_STRING),
+ 'utf8String' => array('type' => ASN1::TYPE_UTF8_STRING),
+ 'bmpString' => array('type' => ASN1::TYPE_BMP_STRING)
+ )
+ );
+
+ $this->PKCS9String = array(
+ 'type' => ASN1::TYPE_CHOICE,
+ 'children' => array(
+ 'ia5String' => array('type' => ASN1::TYPE_IA5_STRING),
+ 'directoryString' => $this->DirectoryString
+ )
+ );
+
+ $this->AttributeValue = array('type' => ASN1::TYPE_ANY);
+
+ $AttributeType = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER);
+
+ $AttributeTypeAndValue = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'type' => $AttributeType,
+ 'value'=> $this->AttributeValue
+ )
+ );
+
+ /*
+ In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare,
+ but they can be useful at times when either there is no unique attribute in the entry or you
+ want to ensure that the entry's DN contains some useful identifying information.
+
+ - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName
+ */
+ $this->RelativeDistinguishedName = array(
+ 'type' => ASN1::TYPE_SET,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $AttributeTypeAndValue
+ );
+
+ // http://tools.ietf.org/html/rfc5280#section-4.1.2.4
+ $RDNSequence = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ // RDNSequence does not define a min or a max, which means it doesn't have one
+ 'min' => 0,
+ 'max' => -1,
+ 'children' => $this->RelativeDistinguishedName
+ );
+
+ $this->Name = array(
+ 'type' => ASN1::TYPE_CHOICE,
+ 'children' => array(
+ 'rdnSequence' => $RDNSequence
+ )
+ );
+
+ // http://tools.ietf.org/html/rfc5280#section-4.1.1.2
+ $AlgorithmIdentifier = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'algorithm' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER),
+ 'parameters' => array(
+ 'type' => ASN1::TYPE_ANY,
+ 'optional' => true
+ )
+ )
+ );
+
+ /*
+ A certificate using system MUST reject the certificate if it encounters
+ a critical extension it does not recognize; however, a non-critical
+ extension may be ignored if it is not recognized.
+
+ http://tools.ietf.org/html/rfc5280#section-4.2
+ */
+ $Extension = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'extnId' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER),
+ 'critical' => array(
+ 'type' => ASN1::TYPE_BOOLEAN,
+ 'optional' => true,
+ 'default' => false
+ ),
+ 'extnValue' => array('type' => ASN1::TYPE_OCTET_STRING)
+ )
+ );
+
+ $this->Extensions = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ // technically, it's MAX, but we'll assume anything < 0 is MAX
+ 'max' => -1,
+ // if 'children' isn't an array then 'min' and 'max' must be defined
+ 'children' => $Extension
+ );
+
+ $SubjectPublicKeyInfo = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'algorithm' => $AlgorithmIdentifier,
+ 'subjectPublicKey' => array('type' => ASN1::TYPE_BIT_STRING)
+ )
+ );
+
+ $UniqueIdentifier = array('type' => ASN1::TYPE_BIT_STRING);
+
+ $Time = array(
+ 'type' => ASN1::TYPE_CHOICE,
+ 'children' => array(
+ 'utcTime' => array('type' => ASN1::TYPE_UTC_TIME),
+ 'generalTime' => array('type' => ASN1::TYPE_GENERALIZED_TIME)
+ )
+ );
+
+ // http://tools.ietf.org/html/rfc5280#section-4.1.2.5
+ $Validity = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'notBefore' => $Time,
+ 'notAfter' => $Time
+ )
+ );
+
+ $CertificateSerialNumber = array('type' => ASN1::TYPE_INTEGER);
+
+ $Version = array(
+ 'type' => ASN1::TYPE_INTEGER,
+ 'mapping' => array('v1', 'v2', 'v3')
+ );
+
+ // assert($TBSCertificate['children']['signature'] == $Certificate['children']['signatureAlgorithm'])
+ $TBSCertificate = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ // technically, default implies optional, but we'll define it as being optional, none-the-less, just to
+ // reenforce that fact
+ 'version' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'explicit' => true,
+ 'default' => 'v1'
+ ) + $Version,
+ 'serialNumber' => $CertificateSerialNumber,
+ 'signature' => $AlgorithmIdentifier,
+ 'issuer' => $this->Name,
+ 'validity' => $Validity,
+ 'subject' => $this->Name,
+ 'subjectPublicKeyInfo' => $SubjectPublicKeyInfo,
+ // implicit means that the T in the TLV structure is to be rewritten, regardless of the type
+ 'issuerUniqueID' => array(
+ 'constant' => 1,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $UniqueIdentifier,
+ 'subjectUniqueID' => array(
+ 'constant' => 2,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $UniqueIdentifier,
+ // <http://tools.ietf.org/html/rfc2459#page-74> doesn't use the EXPLICIT keyword but if
+ // it's not IMPLICIT, it's EXPLICIT
+ 'extensions' => array(
+ 'constant' => 3,
+ 'optional' => true,
+ 'explicit' => true
+ ) + $this->Extensions
+ )
+ );
+
+ $this->Certificate = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'tbsCertificate' => $TBSCertificate,
+ 'signatureAlgorithm' => $AlgorithmIdentifier,
+ 'signature' => array('type' => ASN1::TYPE_BIT_STRING)
+ )
+ );
+
+ $this->KeyUsage = array(
+ 'type' => ASN1::TYPE_BIT_STRING,
+ 'mapping' => array(
+ 'digitalSignature',
+ 'nonRepudiation',
+ 'keyEncipherment',
+ 'dataEncipherment',
+ 'keyAgreement',
+ 'keyCertSign',
+ 'cRLSign',
+ 'encipherOnly',
+ 'decipherOnly'
+ )
+ );
+
+ $this->BasicConstraints = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'cA' => array(
+ 'type' => ASN1::TYPE_BOOLEAN,
+ 'optional' => true,
+ 'default' => false
+ ),
+ 'pathLenConstraint' => array(
+ 'type' => ASN1::TYPE_INTEGER,
+ 'optional' => true
+ )
+ )
+ );
+
+ $this->KeyIdentifier = array('type' => ASN1::TYPE_OCTET_STRING);
+
+ $OrganizationalUnitNames = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => 4, // ub-organizational-units
+ 'children' => array('type' => ASN1::TYPE_PRINTABLE_STRING)
+ );
+
+ $PersonalName = array(
+ 'type' => ASN1::TYPE_SET,
+ 'children' => array(
+ 'surname' => array(
+ 'type' => ASN1::TYPE_PRINTABLE_STRING,
+ 'constant' => 0,
+ 'optional' => true,
+ 'implicit' => true
+ ),
+ 'given-name' => array(
+ 'type' => ASN1::TYPE_PRINTABLE_STRING,
+ 'constant' => 1,
+ 'optional' => true,
+ 'implicit' => true
+ ),
+ 'initials' => array(
+ 'type' => ASN1::TYPE_PRINTABLE_STRING,
+ 'constant' => 2,
+ 'optional' => true,
+ 'implicit' => true
+ ),
+ 'generation-qualifier' => array(
+ 'type' => ASN1::TYPE_PRINTABLE_STRING,
+ 'constant' => 3,
+ 'optional' => true,
+ 'implicit' => true
+ )
+ )
+ );
+
+ $NumericUserIdentifier = array('type' => ASN1::TYPE_NUMERIC_STRING);
+
+ $OrganizationName = array('type' => ASN1::TYPE_PRINTABLE_STRING);
+
+ $PrivateDomainName = array(
+ 'type' => ASN1::TYPE_CHOICE,
+ 'children' => array(
+ 'numeric' => array('type' => ASN1::TYPE_NUMERIC_STRING),
+ 'printable' => array('type' => ASN1::TYPE_PRINTABLE_STRING)
+ )
+ );
+
+ $TerminalIdentifier = array('type' => ASN1::TYPE_PRINTABLE_STRING);
+
+ $NetworkAddress = array('type' => ASN1::TYPE_NUMERIC_STRING);
+
+ $AdministrationDomainName = array(
+ 'type' => ASN1::TYPE_CHOICE,
+ // if class isn't present it's assumed to be \phpseclib\File\ASN1::CLASS_UNIVERSAL or
+ // (if constant is present) \phpseclib\File\ASN1::CLASS_CONTEXT_SPECIFIC
+ 'class' => ASN1::CLASS_APPLICATION,
+ 'cast' => 2,
+ 'children' => array(
+ 'numeric' => array('type' => ASN1::TYPE_NUMERIC_STRING),
+ 'printable' => array('type' => ASN1::TYPE_PRINTABLE_STRING)
+ )
+ );
+
+ $CountryName = array(
+ 'type' => ASN1::TYPE_CHOICE,
+ // if class isn't present it's assumed to be \phpseclib\File\ASN1::CLASS_UNIVERSAL or
+ // (if constant is present) \phpseclib\File\ASN1::CLASS_CONTEXT_SPECIFIC
+ 'class' => ASN1::CLASS_APPLICATION,
+ 'cast' => 1,
+ 'children' => array(
+ 'x121-dcc-code' => array('type' => ASN1::TYPE_NUMERIC_STRING),
+ 'iso-3166-alpha2-code' => array('type' => ASN1::TYPE_PRINTABLE_STRING)
+ )
+ );
+
+ $AnotherName = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'type-id' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER),
+ 'value' => array(
+ 'type' => ASN1::TYPE_ANY,
+ 'constant' => 0,
+ 'optional' => true,
+ 'explicit' => true
+ )
+ )
+ );
+
+ $ExtensionAttribute = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'extension-attribute-type' => array(
+ 'type' => ASN1::TYPE_PRINTABLE_STRING,
+ 'constant' => 0,
+ 'optional' => true,
+ 'implicit' => true
+ ),
+ 'extension-attribute-value' => array(
+ 'type' => ASN1::TYPE_ANY,
+ 'constant' => 1,
+ 'optional' => true,
+ 'explicit' => true
+ )
+ )
+ );
+
+ $ExtensionAttributes = array(
+ 'type' => ASN1::TYPE_SET,
+ 'min' => 1,
+ 'max' => 256, // ub-extension-attributes
+ 'children' => $ExtensionAttribute
+ );
+
+ $BuiltInDomainDefinedAttribute = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'type' => array('type' => ASN1::TYPE_PRINTABLE_STRING),
+ 'value' => array('type' => ASN1::TYPE_PRINTABLE_STRING)
+ )
+ );
+
+ $BuiltInDomainDefinedAttributes = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => 4, // ub-domain-defined-attributes
+ 'children' => $BuiltInDomainDefinedAttribute
+ );
+
+ $BuiltInStandardAttributes = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'country-name' => array('optional' => true) + $CountryName,
+ 'administration-domain-name' => array('optional' => true) + $AdministrationDomainName,
+ 'network-address' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $NetworkAddress,
+ 'terminal-identifier' => array(
+ 'constant' => 1,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $TerminalIdentifier,
+ 'private-domain-name' => array(
+ 'constant' => 2,
+ 'optional' => true,
+ 'explicit' => true
+ ) + $PrivateDomainName,
+ 'organization-name' => array(
+ 'constant' => 3,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $OrganizationName,
+ 'numeric-user-identifier' => array(
+ 'constant' => 4,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $NumericUserIdentifier,
+ 'personal-name' => array(
+ 'constant' => 5,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $PersonalName,
+ 'organizational-unit-names' => array(
+ 'constant' => 6,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $OrganizationalUnitNames
+ )
+ );
+
+ $ORAddress = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'built-in-standard-attributes' => $BuiltInStandardAttributes,
+ 'built-in-domain-defined-attributes' => array('optional' => true) + $BuiltInDomainDefinedAttributes,
+ 'extension-attributes' => array('optional' => true) + $ExtensionAttributes
+ )
+ );
+
+ $EDIPartyName = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'nameAssigner' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $this->DirectoryString,
+ // partyName is technically required but \phpseclib\File\ASN1 doesn't currently support non-optional constants and
+ // setting it to optional gets the job done in any event.
+ 'partyName' => array(
+ 'constant' => 1,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $this->DirectoryString
+ )
+ );
+
+ $GeneralName = array(
+ 'type' => ASN1::TYPE_CHOICE,
+ 'children' => array(
+ 'otherName' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $AnotherName,
+ 'rfc822Name' => array(
+ 'type' => ASN1::TYPE_IA5_STRING,
+ 'constant' => 1,
+ 'optional' => true,
+ 'implicit' => true
+ ),
+ 'dNSName' => array(
+ 'type' => ASN1::TYPE_IA5_STRING,
+ 'constant' => 2,
+ 'optional' => true,
+ 'implicit' => true
+ ),
+ 'x400Address' => array(
+ 'constant' => 3,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $ORAddress,
+ 'directoryName' => array(
+ 'constant' => 4,
+ 'optional' => true,
+ 'explicit' => true
+ ) + $this->Name,
+ 'ediPartyName' => array(
+ 'constant' => 5,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $EDIPartyName,
+ 'uniformResourceIdentifier' => array(
+ 'type' => ASN1::TYPE_IA5_STRING,
+ 'constant' => 6,
+ 'optional' => true,
+ 'implicit' => true
+ ),
+ 'iPAddress' => array(
+ 'type' => ASN1::TYPE_OCTET_STRING,
+ 'constant' => 7,
+ 'optional' => true,
+ 'implicit' => true
+ ),
+ 'registeredID' => array(
+ 'type' => ASN1::TYPE_OBJECT_IDENTIFIER,
+ 'constant' => 8,
+ 'optional' => true,
+ 'implicit' => true
+ )
+ )
+ );
+
+ $GeneralNames = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $GeneralName
+ );
+
+ $this->IssuerAltName = $GeneralNames;
+
+ $ReasonFlags = array(
+ 'type' => ASN1::TYPE_BIT_STRING,
+ 'mapping' => array(
+ 'unused',
+ 'keyCompromise',
+ 'cACompromise',
+ 'affiliationChanged',
+ 'superseded',
+ 'cessationOfOperation',
+ 'certificateHold',
+ 'privilegeWithdrawn',
+ 'aACompromise'
+ )
+ );
+
+ $DistributionPointName = array(
+ 'type' => ASN1::TYPE_CHOICE,
+ 'children' => array(
+ 'fullName' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $GeneralNames,
+ 'nameRelativeToCRLIssuer' => array(
+ 'constant' => 1,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $this->RelativeDistinguishedName
+ )
+ );
+
+ $DistributionPoint = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'distributionPoint' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'explicit' => true
+ ) + $DistributionPointName,
+ 'reasons' => array(
+ 'constant' => 1,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $ReasonFlags,
+ 'cRLIssuer' => array(
+ 'constant' => 2,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $GeneralNames
+ )
+ );
+
+ $this->CRLDistributionPoints = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $DistributionPoint
+ );
+
+ $this->AuthorityKeyIdentifier = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'keyIdentifier' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $this->KeyIdentifier,
+ 'authorityCertIssuer' => array(
+ 'constant' => 1,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $GeneralNames,
+ 'authorityCertSerialNumber' => array(
+ 'constant' => 2,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $CertificateSerialNumber
+ )
+ );
+
+ $PolicyQualifierId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER);
+
+ $PolicyQualifierInfo = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'policyQualifierId' => $PolicyQualifierId,
+ 'qualifier' => array('type' => ASN1::TYPE_ANY)
+ )
+ );
+
+ $CertPolicyId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER);
+
+ $PolicyInformation = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'policyIdentifier' => $CertPolicyId,
+ 'policyQualifiers' => array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 0,
+ 'max' => -1,
+ 'optional' => true,
+ 'children' => $PolicyQualifierInfo
+ )
+ )
+ );
+
+ $this->CertificatePolicies = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $PolicyInformation
+ );
+
+ $this->PolicyMappings = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'issuerDomainPolicy' => $CertPolicyId,
+ 'subjectDomainPolicy' => $CertPolicyId
+ )
+ )
+ );
+
+ $KeyPurposeId = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER);
+
+ $this->ExtKeyUsageSyntax = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $KeyPurposeId
+ );
+
+ $AccessDescription = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'accessMethod' => array('type' => ASN1::TYPE_OBJECT_IDENTIFIER),
+ 'accessLocation' => $GeneralName
+ )
+ );
+
+ $this->AuthorityInfoAccessSyntax = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $AccessDescription
+ );
+
+ $this->SubjectInfoAccessSyntax = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $AccessDescription
+ );
+
+ $this->SubjectAltName = $GeneralNames;
+
+ $this->PrivateKeyUsagePeriod = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'notBefore' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'implicit' => true,
+ 'type' => ASN1::TYPE_GENERALIZED_TIME),
+ 'notAfter' => array(
+ 'constant' => 1,
+ 'optional' => true,
+ 'implicit' => true,
+ 'type' => ASN1::TYPE_GENERALIZED_TIME)
+ )
+ );
+
+ $BaseDistance = array('type' => ASN1::TYPE_INTEGER);
+
+ $GeneralSubtree = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'base' => $GeneralName,
+ 'minimum' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'implicit' => true,
+ 'default' => new BigInteger(0)
+ ) + $BaseDistance,
+ 'maximum' => array(
+ 'constant' => 1,
+ 'optional' => true,
+ 'implicit' => true,
+ ) + $BaseDistance
+ )
+ );
+
+ $GeneralSubtrees = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $GeneralSubtree
+ );
+
+ $this->NameConstraints = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'permittedSubtrees' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $GeneralSubtrees,
+ 'excludedSubtrees' => array(
+ 'constant' => 1,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $GeneralSubtrees
+ )
+ );
+
+ $this->CPSuri = array('type' => ASN1::TYPE_IA5_STRING);
+
+ $DisplayText = array(
+ 'type' => ASN1::TYPE_CHOICE,
+ 'children' => array(
+ 'ia5String' => array('type' => ASN1::TYPE_IA5_STRING),
+ 'visibleString' => array('type' => ASN1::TYPE_VISIBLE_STRING),
+ 'bmpString' => array('type' => ASN1::TYPE_BMP_STRING),
+ 'utf8String' => array('type' => ASN1::TYPE_UTF8_STRING)
+ )
+ );
+
+ $NoticeReference = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'organization' => $DisplayText,
+ 'noticeNumbers' => array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => 200,
+ 'children' => array('type' => ASN1::TYPE_INTEGER)
+ )
+ )
+ );
+
+ $this->UserNotice = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'noticeRef' => array(
+ 'optional' => true,
+ 'implicit' => true
+ ) + $NoticeReference,
+ 'explicitText' => array(
+ 'optional' => true,
+ 'implicit' => true
+ ) + $DisplayText
+ )
+ );
+
+ // mapping is from <http://www.mozilla.org/projects/security/pki/nss/tech-notes/tn3.html>
+ $this->netscape_cert_type = array(
+ 'type' => ASN1::TYPE_BIT_STRING,
+ 'mapping' => array(
+ 'SSLClient',
+ 'SSLServer',
+ 'Email',
+ 'ObjectSigning',
+ 'Reserved',
+ 'SSLCA',
+ 'EmailCA',
+ 'ObjectSigningCA'
+ )
+ );
+
+ $this->netscape_comment = array('type' => ASN1::TYPE_IA5_STRING);
+ $this->netscape_ca_policy_url = array('type' => ASN1::TYPE_IA5_STRING);
+
+ // attribute is used in RFC2986 but we're using the RFC5280 definition
+
+ $Attribute = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'type' => $AttributeType,
+ 'value'=> array(
+ 'type' => ASN1::TYPE_SET,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $this->AttributeValue
+ )
+ )
+ );
+
+ $this->SubjectDirectoryAttributes = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $Attribute
+ );
+
+ // adapted from <http://tools.ietf.org/html/rfc2986>
+
+ $Attributes = array(
+ 'type' => ASN1::TYPE_SET,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $Attribute
+ );
+
+ $CertificationRequestInfo = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'version' => array(
+ 'type' => ASN1::TYPE_INTEGER,
+ 'mapping' => array('v1')
+ ),
+ 'subject' => $this->Name,
+ 'subjectPKInfo' => $SubjectPublicKeyInfo,
+ 'attributes' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $Attributes,
+ )
+ );
+
+ $this->CertificationRequest = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'certificationRequestInfo' => $CertificationRequestInfo,
+ 'signatureAlgorithm' => $AlgorithmIdentifier,
+ 'signature' => array('type' => ASN1::TYPE_BIT_STRING)
+ )
+ );
+
+ $RevokedCertificate = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'userCertificate' => $CertificateSerialNumber,
+ 'revocationDate' => $Time,
+ 'crlEntryExtensions' => array(
+ 'optional' => true
+ ) + $this->Extensions
+ )
+ );
+
+ $TBSCertList = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'version' => array(
+ 'optional' => true,
+ 'default' => 'v1'
+ ) + $Version,
+ 'signature' => $AlgorithmIdentifier,
+ 'issuer' => $this->Name,
+ 'thisUpdate' => $Time,
+ 'nextUpdate' => array(
+ 'optional' => true
+ ) + $Time,
+ 'revokedCertificates' => array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'optional' => true,
+ 'min' => 0,
+ 'max' => -1,
+ 'children' => $RevokedCertificate
+ ),
+ 'crlExtensions' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'explicit' => true
+ ) + $this->Extensions
+ )
+ );
+
+ $this->CertificateList = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'tbsCertList' => $TBSCertList,
+ 'signatureAlgorithm' => $AlgorithmIdentifier,
+ 'signature' => array('type' => ASN1::TYPE_BIT_STRING)
+ )
+ );
+
+ $this->CRLNumber = array('type' => ASN1::TYPE_INTEGER);
+
+ $this->CRLReason = array('type' => ASN1::TYPE_ENUMERATED,
+ 'mapping' => array(
+ 'unspecified',
+ 'keyCompromise',
+ 'cACompromise',
+ 'affiliationChanged',
+ 'superseded',
+ 'cessationOfOperation',
+ 'certificateHold',
+ // Value 7 is not used.
+ 8 => 'removeFromCRL',
+ 'privilegeWithdrawn',
+ 'aACompromise'
+ )
+ );
+
+ $this->IssuingDistributionPoint = array('type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'distributionPoint' => array(
+ 'constant' => 0,
+ 'optional' => true,
+ 'explicit' => true
+ ) + $DistributionPointName,
+ 'onlyContainsUserCerts' => array(
+ 'type' => ASN1::TYPE_BOOLEAN,
+ 'constant' => 1,
+ 'optional' => true,
+ 'default' => false,
+ 'implicit' => true
+ ),
+ 'onlyContainsCACerts' => array(
+ 'type' => ASN1::TYPE_BOOLEAN,
+ 'constant' => 2,
+ 'optional' => true,
+ 'default' => false,
+ 'implicit' => true
+ ),
+ 'onlySomeReasons' => array(
+ 'constant' => 3,
+ 'optional' => true,
+ 'implicit' => true
+ ) + $ReasonFlags,
+ 'indirectCRL' => array(
+ 'type' => ASN1::TYPE_BOOLEAN,
+ 'constant' => 4,
+ 'optional' => true,
+ 'default' => false,
+ 'implicit' => true
+ ),
+ 'onlyContainsAttributeCerts' => array(
+ 'type' => ASN1::TYPE_BOOLEAN,
+ 'constant' => 5,
+ 'optional' => true,
+ 'default' => false,
+ 'implicit' => true
+ )
+ )
+ );
+
+ $this->InvalidityDate = array('type' => ASN1::TYPE_GENERALIZED_TIME);
+
+ $this->CertificateIssuer = $GeneralNames;
+
+ $this->HoldInstructionCode = array('type' => ASN1::TYPE_OBJECT_IDENTIFIER);
+
+ $PublicKeyAndChallenge = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'spki' => $SubjectPublicKeyInfo,
+ 'challenge' => array('type' => ASN1::TYPE_IA5_STRING)
+ )
+ );
+
+ $this->SignedPublicKeyAndChallenge = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'children' => array(
+ 'publicKeyAndChallenge' => $PublicKeyAndChallenge,
+ 'signatureAlgorithm' => $AlgorithmIdentifier,
+ 'signature' => array('type' => ASN1::TYPE_BIT_STRING)
+ )
+ );
+
+ $this->PostalAddress = array(
+ 'type' => ASN1::TYPE_SEQUENCE,
+ 'optional' => true,
+ 'min' => 1,
+ 'max' => -1,
+ 'children' => $this->DirectoryString
+ );
+
+ // OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2
+ $this->oids = array(
+ '1.3.6.1.5.5.7' => 'id-pkix',
+ '1.3.6.1.5.5.7.1' => 'id-pe',
+ '1.3.6.1.5.5.7.2' => 'id-qt',
+ '1.3.6.1.5.5.7.3' => 'id-kp',
+ '1.3.6.1.5.5.7.48' => 'id-ad',
+ '1.3.6.1.5.5.7.2.1' => 'id-qt-cps',
+ '1.3.6.1.5.5.7.2.2' => 'id-qt-unotice',
+ '1.3.6.1.5.5.7.48.1' =>'id-ad-ocsp',
+ '1.3.6.1.5.5.7.48.2' => 'id-ad-caIssuers',
+ '1.3.6.1.5.5.7.48.3' => 'id-ad-timeStamping',
+ '1.3.6.1.5.5.7.48.5' => 'id-ad-caRepository',
+ '2.5.4' => 'id-at',
+ '2.5.4.41' => 'id-at-name',
+ '2.5.4.4' => 'id-at-surname',
+ '2.5.4.42' => 'id-at-givenName',
+ '2.5.4.43' => 'id-at-initials',
+ '2.5.4.44' => 'id-at-generationQualifier',
+ '2.5.4.3' => 'id-at-commonName',
+ '2.5.4.7' => 'id-at-localityName',
+ '2.5.4.8' => 'id-at-stateOrProvinceName',
+ '2.5.4.10' => 'id-at-organizationName',
+ '2.5.4.11' => 'id-at-organizationalUnitName',
+ '2.5.4.12' => 'id-at-title',
+ '2.5.4.13' => 'id-at-description',
+ '2.5.4.46' => 'id-at-dnQualifier',
+ '2.5.4.6' => 'id-at-countryName',
+ '2.5.4.5' => 'id-at-serialNumber',
+ '2.5.4.65' => 'id-at-pseudonym',
+ '2.5.4.17' => 'id-at-postalCode',
+ '2.5.4.9' => 'id-at-streetAddress',
+ '2.5.4.45' => 'id-at-uniqueIdentifier',
+ '2.5.4.72' => 'id-at-role',
+ '2.5.4.16' => 'id-at-postalAddress',
+
+ '0.9.2342.19200300.100.1.25' => 'id-domainComponent',
+ '1.2.840.113549.1.9' => 'pkcs-9',
+ '1.2.840.113549.1.9.1' => 'pkcs-9-at-emailAddress',
+ '2.5.29' => 'id-ce',
+ '2.5.29.35' => 'id-ce-authorityKeyIdentifier',
+ '2.5.29.14' => 'id-ce-subjectKeyIdentifier',
+ '2.5.29.15' => 'id-ce-keyUsage',
+ '2.5.29.16' => 'id-ce-privateKeyUsagePeriod',
+ '2.5.29.32' => 'id-ce-certificatePolicies',
+ '2.5.29.32.0' => 'anyPolicy',
+
+ '2.5.29.33' => 'id-ce-policyMappings',
+ '2.5.29.17' => 'id-ce-subjectAltName',
+ '2.5.29.18' => 'id-ce-issuerAltName',
+ '2.5.29.9' => 'id-ce-subjectDirectoryAttributes',
+ '2.5.29.19' => 'id-ce-basicConstraints',
+ '2.5.29.30' => 'id-ce-nameConstraints',
+ '2.5.29.36' => 'id-ce-policyConstraints',
+ '2.5.29.31' => 'id-ce-cRLDistributionPoints',
+ '2.5.29.37' => 'id-ce-extKeyUsage',
+ '2.5.29.37.0' => 'anyExtendedKeyUsage',
+ '1.3.6.1.5.5.7.3.1' => 'id-kp-serverAuth',
+ '1.3.6.1.5.5.7.3.2' => 'id-kp-clientAuth',
+ '1.3.6.1.5.5.7.3.3' => 'id-kp-codeSigning',
+ '1.3.6.1.5.5.7.3.4' => 'id-kp-emailProtection',
+ '1.3.6.1.5.5.7.3.8' => 'id-kp-timeStamping',
+ '1.3.6.1.5.5.7.3.9' => 'id-kp-OCSPSigning',
+ '2.5.29.54' => 'id-ce-inhibitAnyPolicy',
+ '2.5.29.46' => 'id-ce-freshestCRL',
+ '1.3.6.1.5.5.7.1.1' => 'id-pe-authorityInfoAccess',
+ '1.3.6.1.5.5.7.1.11' => 'id-pe-subjectInfoAccess',
+ '2.5.29.20' => 'id-ce-cRLNumber',
+ '2.5.29.28' => 'id-ce-issuingDistributionPoint',
+ '2.5.29.27' => 'id-ce-deltaCRLIndicator',
+ '2.5.29.21' => 'id-ce-cRLReasons',
+ '2.5.29.29' => 'id-ce-certificateIssuer',
+ '2.5.29.23' => 'id-ce-holdInstructionCode',
+ '1.2.840.10040.2' => 'holdInstruction',
+ '1.2.840.10040.2.1' => 'id-holdinstruction-none',
+ '1.2.840.10040.2.2' => 'id-holdinstruction-callissuer',
+ '1.2.840.10040.2.3' => 'id-holdinstruction-reject',
+ '2.5.29.24' => 'id-ce-invalidityDate',
+
+ '1.2.840.113549.2.2' => 'md2',
+ '1.2.840.113549.2.5' => 'md5',
+ '1.3.14.3.2.26' => 'id-sha1',
+ '1.2.840.10040.4.1' => 'id-dsa',
+ '1.2.840.10040.4.3' => 'id-dsa-with-sha1',
+ '1.2.840.113549.1.1' => 'pkcs-1',
+ '1.2.840.113549.1.1.1' => 'rsaEncryption',
+ '1.2.840.113549.1.1.2' => 'md2WithRSAEncryption',
+ '1.2.840.113549.1.1.4' => 'md5WithRSAEncryption',
+ '1.2.840.113549.1.1.5' => 'sha1WithRSAEncryption',
+ '1.2.840.10046.2.1' => 'dhpublicnumber',
+ '2.16.840.1.101.2.1.1.22' => 'id-keyExchangeAlgorithm',
+ '1.2.840.10045' => 'ansi-X9-62',
+ '1.2.840.10045.4' => 'id-ecSigType',
+ '1.2.840.10045.4.1' => 'ecdsa-with-SHA1',
+ '1.2.840.10045.1' => 'id-fieldType',
+ '1.2.840.10045.1.1' => 'prime-field',
+ '1.2.840.10045.1.2' => 'characteristic-two-field',
+ '1.2.840.10045.1.2.3' => 'id-characteristic-two-basis',
+ '1.2.840.10045.1.2.3.1' => 'gnBasis',
+ '1.2.840.10045.1.2.3.2' => 'tpBasis',
+ '1.2.840.10045.1.2.3.3' => 'ppBasis',
+ '1.2.840.10045.2' => 'id-publicKeyType',
+ '1.2.840.10045.2.1' => 'id-ecPublicKey',
+ '1.2.840.10045.3' => 'ellipticCurve',
+ '1.2.840.10045.3.0' => 'c-TwoCurve',
+ '1.2.840.10045.3.0.1' => 'c2pnb163v1',
+ '1.2.840.10045.3.0.2' => 'c2pnb163v2',
+ '1.2.840.10045.3.0.3' => 'c2pnb163v3',
+ '1.2.840.10045.3.0.4' => 'c2pnb176w1',
+ '1.2.840.10045.3.0.5' => 'c2pnb191v1',
+ '1.2.840.10045.3.0.6' => 'c2pnb191v2',
+ '1.2.840.10045.3.0.7' => 'c2pnb191v3',
+ '1.2.840.10045.3.0.8' => 'c2pnb191v4',
+ '1.2.840.10045.3.0.9' => 'c2pnb191v5',
+ '1.2.840.10045.3.0.10' => 'c2pnb208w1',
+ '1.2.840.10045.3.0.11' => 'c2pnb239v1',
+ '1.2.840.10045.3.0.12' => 'c2pnb239v2',
+ '1.2.840.10045.3.0.13' => 'c2pnb239v3',
+ '1.2.840.10045.3.0.14' => 'c2pnb239v4',
+ '1.2.840.10045.3.0.15' => 'c2pnb239v5',
+ '1.2.840.10045.3.0.16' => 'c2pnb272w1',
+ '1.2.840.10045.3.0.17' => 'c2pnb304w1',
+ '1.2.840.10045.3.0.18' => 'c2pnb359v1',
+ '1.2.840.10045.3.0.19' => 'c2pnb368w1',
+ '1.2.840.10045.3.0.20' => 'c2pnb431r1',
+ '1.2.840.10045.3.1' => 'primeCurve',
+ '1.2.840.10045.3.1.1' => 'prime192v1',
+ '1.2.840.10045.3.1.2' => 'prime192v2',
+ '1.2.840.10045.3.1.3' => 'prime192v3',
+ '1.2.840.10045.3.1.4' => 'prime239v1',
+ '1.2.840.10045.3.1.5' => 'prime239v2',
+ '1.2.840.10045.3.1.6' => 'prime239v3',
+ '1.2.840.10045.3.1.7' => 'prime256v1',
+ '1.2.840.113549.1.1.7' => 'id-RSAES-OAEP',
+ '1.2.840.113549.1.1.9' => 'id-pSpecified',
+ '1.2.840.113549.1.1.10' => 'id-RSASSA-PSS',
+ '1.2.840.113549.1.1.8' => 'id-mgf1',
+ '1.2.840.113549.1.1.14' => 'sha224WithRSAEncryption',
+ '1.2.840.113549.1.1.11' => 'sha256WithRSAEncryption',
+ '1.2.840.113549.1.1.12' => 'sha384WithRSAEncryption',
+ '1.2.840.113549.1.1.13' => 'sha512WithRSAEncryption',
+ '2.16.840.1.101.3.4.2.4' => 'id-sha224',
+ '2.16.840.1.101.3.4.2.1' => 'id-sha256',
+ '2.16.840.1.101.3.4.2.2' => 'id-sha384',
+ '2.16.840.1.101.3.4.2.3' => 'id-sha512',
+ '1.2.643.2.2.4' => 'id-GostR3411-94-with-GostR3410-94',
+ '1.2.643.2.2.3' => 'id-GostR3411-94-with-GostR3410-2001',
+ '1.2.643.2.2.20' => 'id-GostR3410-2001',
+ '1.2.643.2.2.19' => 'id-GostR3410-94',
+ // Netscape Object Identifiers from "Netscape Certificate Extensions"
+ '2.16.840.1.113730' => 'netscape',
+ '2.16.840.1.113730.1' => 'netscape-cert-extension',
+ '2.16.840.1.113730.1.1' => 'netscape-cert-type',
+ '2.16.840.1.113730.1.13' => 'netscape-comment',
+ '2.16.840.1.113730.1.8' => 'netscape-ca-policy-url',
+ // the following are X.509 extensions not supported by phpseclib
+ '1.3.6.1.5.5.7.1.12' => 'id-pe-logotype',
+ '1.2.840.113533.7.65.0' => 'entrustVersInfo',
+ '2.16.840.1.113733.1.6.9' => 'verisignPrivate',
+ // for Certificate Signing Requests
+ // see http://tools.ietf.org/html/rfc2985
+ '1.2.840.113549.1.9.2' => 'pkcs-9-at-unstructuredName', // PKCS #9 unstructured name
+ '1.2.840.113549.1.9.7' => 'pkcs-9-at-challengePassword', // Challenge password for certificate revocations
+ '1.2.840.113549.1.9.14' => 'pkcs-9-at-extensionRequest' // Certificate extension request
+ );
+ }
+
+ /**
+ * Load X.509 certificate
+ *
+ * Returns an associative array describing the X.509 cert or a false if the cert failed to load
+ *
+ * @param string $cert
+ * @param int $mode
+ * @access public
+ * @return mixed
+ */
+ function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT)
+ {
+ if (is_array($cert) && isset($cert['tbsCertificate'])) {
+ unset($this->currentCert);
+ unset($this->currentKeyIdentifier);
+ $this->dn = $cert['tbsCertificate']['subject'];
+ if (!isset($this->dn)) {
+ return false;
+ }
+ $this->currentCert = $cert;
+
+ $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier');
+ $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null;
+
+ unset($this->signatureSubject);
+
+ return $cert;
+ }
+
+ $asn1 = new ASN1();
+
+ if ($mode != self::FORMAT_DER) {
+ $newcert = $this->_extractBER($cert);
+ if ($mode == self::FORMAT_PEM && $cert == $newcert) {
+ return false;
+ }
+ $cert = $newcert;
+ }
+
+ if ($cert === false) {
+ $this->currentCert = false;
+ return false;
+ }
+
+ $asn1->loadOIDs($this->oids);
+ $decoded = $asn1->decodeBER($cert);
+
+ if (!empty($decoded)) {
+ $x509 = $asn1->asn1map($decoded[0], $this->Certificate);
+ }
+ if (!isset($x509) || $x509 === false) {
+ $this->currentCert = false;
+ return false;
+ }
+
+ $this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
+
+ if ($this->_isSubArrayValid($x509, 'tbsCertificate/extensions')) {
+ $this->_mapInExtensions($x509, 'tbsCertificate/extensions', $asn1);
+ }
+ $this->_mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence', $asn1);
+ $this->_mapInDNs($x509, 'tbsCertificate/subject/rdnSequence', $asn1);
+
+ $key = &$x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'];
+ $key = $this->_reformatKey($x509['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], $key);
+
+ $this->currentCert = $x509;
+ $this->dn = $x509['tbsCertificate']['subject'];
+
+ $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier');
+ $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null;
+
+ return $x509;
+ }
+
+ /**
+ * Save X.509 certificate
+ *
+ * @param array $cert
+ * @param int $format optional
+ * @access public
+ * @return string
+ */
+ function saveX509($cert, $format = self::FORMAT_PEM)
+ {
+ if (!is_array($cert) || !isset($cert['tbsCertificate'])) {
+ return false;
+ }
+
+ switch (true) {
+ // "case !$a: case !$b: break; default: whatever();" is the same thing as "if ($a && $b) whatever()"
+ case !($algorithm = $this->_subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')):
+ case is_object($cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']):
+ break;
+ default:
+ switch ($algorithm) {
+ case 'rsaEncryption':
+ $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']
+ = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])));
+ /* "[For RSA keys] the parameters field MUST have ASN.1 type NULL for this algorithm identifier."
+ -- https://tools.ietf.org/html/rfc3279#section-2.3.1
+
+ given that and the fact that RSA keys appear ot be the only key type for which the parameters field can be blank,
+ it seems like perhaps the ASN.1 description ought not say the parameters field is OPTIONAL, but whatever.
+ */
+ $cert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['parameters'] = null;
+ // https://tools.ietf.org/html/rfc3279#section-2.2.1
+ $cert['signatureAlgorithm']['parameters'] = null;
+ $cert['tbsCertificate']['signature']['parameters'] = null;
+ }
+ }
+
+ $asn1 = new ASN1();
+ $asn1->loadOIDs($this->oids);
+
+ $filters = array();
+ $type_utf8_string = array('type' => ASN1::TYPE_UTF8_STRING);
+ $filters['tbsCertificate']['signature']['parameters'] = $type_utf8_string;
+ $filters['tbsCertificate']['signature']['issuer']['rdnSequence']['value'] = $type_utf8_string;
+ $filters['tbsCertificate']['issuer']['rdnSequence']['value'] = $type_utf8_string;
+ $filters['tbsCertificate']['subject']['rdnSequence']['value'] = $type_utf8_string;
+ $filters['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['parameters'] = $type_utf8_string;
+ $filters['signatureAlgorithm']['parameters'] = $type_utf8_string;
+ $filters['authorityCertIssuer']['directoryName']['rdnSequence']['value'] = $type_utf8_string;
+ //$filters['policyQualifiers']['qualifier'] = $type_utf8_string;
+ $filters['distributionPoint']['fullName']['directoryName']['rdnSequence']['value'] = $type_utf8_string;
+ $filters['directoryName']['rdnSequence']['value'] = $type_utf8_string;
+
+ /* in the case of policyQualifiers/qualifier, the type has to be \phpseclib\File\ASN1::TYPE_IA5_STRING.
+ \phpseclib\File\ASN1::TYPE_PRINTABLE_STRING will cause OpenSSL's X.509 parser to spit out random
+ characters.
+ */
+ $filters['policyQualifiers']['qualifier']
+ = array('type' => ASN1::TYPE_IA5_STRING);
+
+ $asn1->loadFilters($filters);
+
+ $this->_mapOutExtensions($cert, 'tbsCertificate/extensions', $asn1);
+ $this->_mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence', $asn1);
+ $this->_mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence', $asn1);
+
+ $cert = $asn1->encodeDER($cert, $this->Certificate);
+
+ switch ($format) {
+ case self::FORMAT_DER:
+ return $cert;
+ // case self::FORMAT_PEM:
+ default:
+ return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(base64_encode($cert), 64) . '-----END CERTIFICATE-----';
+ }
+ }
+
+ /**
+ * Map extension values from octet string to extension-specific internal
+ * format.
+ *
+ * @param array ref $root
+ * @param string $path
+ * @param object $asn1
+ * @access private
+ */
+ function _mapInExtensions(&$root, $path, $asn1)
+ {
+ $extensions = &$this->_subArrayUnchecked($root, $path);
+
+ if ($extensions) {
+ for ($i = 0; $i < count($extensions); $i++) {
+ $id = $extensions[$i]['extnId'];
+ $value = &$extensions[$i]['extnValue'];
+ $value = base64_decode($value);
+ $decoded = $asn1->decodeBER($value);
+ /* [extnValue] contains the DER encoding of an ASN.1 value
+ corresponding to the extension type identified by extnID */
+ $map = $this->_getMapping($id);
+ if (!is_bool($map)) {
+ $decoder = $id == 'id-ce-nameConstraints' ?
+ array($this, '_decodeNameConstraintIP') :
+ array($this, '_decodeIP');
+ $mapped = $asn1->asn1map($decoded[0], $map, array('iPAddress' => $decoder));
+ $value = $mapped === false ? $decoded[0] : $mapped;
+
+ if ($id == 'id-ce-certificatePolicies') {
+ for ($j = 0; $j < count($value); $j++) {
+ if (!isset($value[$j]['policyQualifiers'])) {
+ continue;
+ }
+ for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) {
+ $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId'];
+ $map = $this->_getMapping($subid);
+ $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier'];
+ if ($map !== false) {
+ $decoded = $asn1->decodeBER($subvalue);
+ $mapped = $asn1->asn1map($decoded[0], $map);
+ $subvalue = $mapped === false ? $decoded[0] : $mapped;
+ }
+ }
+ }
+ }
+ } else {
+ $value = base64_encode($value);
+ }
+ }
+ }
+ }
+
+ /**
+ * Map extension values from extension-specific internal format to
+ * octet string.
+ *
+ * @param array ref $root
+ * @param string $path
+ * @param object $asn1
+ * @access private
+ */
+ function _mapOutExtensions(&$root, $path, $asn1)
+ {
+ $extensions = &$this->_subArray($root, $path);
+
+ if (is_array($extensions)) {
+ $size = count($extensions);
+ for ($i = 0; $i < $size; $i++) {
+ if ($extensions[$i] instanceof Element) {
+ continue;
+ }
+
+ $id = $extensions[$i]['extnId'];
+ $value = &$extensions[$i]['extnValue'];
+
+ switch ($id) {
+ case 'id-ce-certificatePolicies':
+ for ($j = 0; $j < count($value); $j++) {
+ if (!isset($value[$j]['policyQualifiers'])) {
+ continue;
+ }
+ for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) {
+ $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId'];
+ $map = $this->_getMapping($subid);
+ $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier'];
+ if ($map !== false) {
+ // by default \phpseclib\File\ASN1 will try to render qualifier as a \phpseclib\File\ASN1::TYPE_IA5_STRING since it's
+ // actual type is \phpseclib\File\ASN1::TYPE_ANY
+ $subvalue = new Element($asn1->encodeDER($subvalue, $map));
+ }
+ }
+ }
+ break;
+ case 'id-ce-authorityKeyIdentifier': // use 00 as the serial number instead of an empty string
+ if (isset($value['authorityCertSerialNumber'])) {
+ if ($value['authorityCertSerialNumber']->toBytes() == '') {
+ $temp = chr((ASN1::CLASS_CONTEXT_SPECIFIC << 6) | 2) . "\1\0";
+ $value['authorityCertSerialNumber'] = new Element($temp);
+ }
+ }
+ }
+
+ /* [extnValue] contains the DER encoding of an ASN.1 value
+ corresponding to the extension type identified by extnID */
+ $map = $this->_getMapping($id);
+ if (is_bool($map)) {
+ if (!$map) {
+ user_error($id . ' is not a currently supported extension');
+ unset($extensions[$i]);
+ }
+ } else {
+ $temp = $asn1->encodeDER($value, $map, array('iPAddress' => array($this, '_encodeIP')));
+ $value = base64_encode($temp);
+ }
+ }
+ }
+ }
+
+ /**
+ * Map attribute values from ANY type to attribute-specific internal
+ * format.
+ *
+ * @param array ref $root
+ * @param string $path
+ * @param object $asn1
+ * @access private
+ */
+ function _mapInAttributes(&$root, $path, $asn1)
+ {
+ $attributes = &$this->_subArray($root, $path);
+
+ if (is_array($attributes)) {
+ for ($i = 0; $i < count($attributes); $i++) {
+ $id = $attributes[$i]['type'];
+ /* $value contains the DER encoding of an ASN.1 value
+ corresponding to the attribute type identified by type */
+ $map = $this->_getMapping($id);
+ if (is_array($attributes[$i]['value'])) {
+ $values = &$attributes[$i]['value'];
+ for ($j = 0; $j < count($values); $j++) {
+ $value = $asn1->encodeDER($values[$j], $this->AttributeValue);
+ $decoded = $asn1->decodeBER($value);
+ if (!is_bool($map)) {
+ $mapped = $asn1->asn1map($decoded[0], $map);
+ if ($mapped !== false) {
+ $values[$j] = $mapped;
+ }
+ if ($id == 'pkcs-9-at-extensionRequest' && $this->_isSubArrayValid($values, $j)) {
+ $this->_mapInExtensions($values, $j, $asn1);
+ }
+ } elseif ($map) {
+ $values[$j] = base64_encode($value);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Map attribute values from attribute-specific internal format to
+ * ANY type.
+ *
+ * @param array ref $root
+ * @param string $path
+ * @param object $asn1
+ * @access private
+ */
+ function _mapOutAttributes(&$root, $path, $asn1)
+ {
+ $attributes = &$this->_subArray($root, $path);
+
+ if (is_array($attributes)) {
+ $size = count($attributes);
+ for ($i = 0; $i < $size; $i++) {
+ /* [value] contains the DER encoding of an ASN.1 value
+ corresponding to the attribute type identified by type */
+ $id = $attributes[$i]['type'];
+ $map = $this->_getMapping($id);
+ if ($map === false) {
+ user_error($id . ' is not a currently supported attribute', E_USER_NOTICE);
+ unset($attributes[$i]);
+ } elseif (is_array($attributes[$i]['value'])) {
+ $values = &$attributes[$i]['value'];
+ for ($j = 0; $j < count($values); $j++) {
+ switch ($id) {
+ case 'pkcs-9-at-extensionRequest':
+ $this->_mapOutExtensions($values, $j, $asn1);
+ break;
+ }
+
+ if (!is_bool($map)) {
+ $temp = $asn1->encodeDER($values[$j], $map);
+ $decoded = $asn1->decodeBER($temp);
+ $values[$j] = $asn1->asn1map($decoded[0], $this->AttributeValue);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Map DN values from ANY type to DN-specific internal
+ * format.
+ *
+ * @param array ref $root
+ * @param string $path
+ * @param object $asn1
+ * @access private
+ */
+ function _mapInDNs(&$root, $path, $asn1)
+ {
+ $dns = &$this->_subArray($root, $path);
+
+ if (is_array($dns)) {
+ for ($i = 0; $i < count($dns); $i++) {
+ for ($j = 0; $j < count($dns[$i]); $j++) {
+ $type = $dns[$i][$j]['type'];
+ $value = &$dns[$i][$j]['value'];
+ if (is_object($value) && $value instanceof Element) {
+ $map = $this->_getMapping($type);
+ if (!is_bool($map)) {
+ $decoded = $asn1->decodeBER($value);
+ $value = $asn1->asn1map($decoded[0], $map);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Map DN values from DN-specific internal format to
+ * ANY type.
+ *
+ * @param array ref $root
+ * @param string $path
+ * @param object $asn1
+ * @access private
+ */
+ function _mapOutDNs(&$root, $path, $asn1)
+ {
+ $dns = &$this->_subArray($root, $path);
+
+ if (is_array($dns)) {
+ $size = count($dns);
+ for ($i = 0; $i < $size; $i++) {
+ for ($j = 0; $j < count($dns[$i]); $j++) {
+ $type = $dns[$i][$j]['type'];
+ $value = &$dns[$i][$j]['value'];
+ if (is_object($value) && $value instanceof Element) {
+ continue;
+ }
+
+ $map = $this->_getMapping($type);
+ if (!is_bool($map)) {
+ $value = new Element($asn1->encodeDER($value, $map));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Associate an extension ID to an extension mapping
+ *
+ * @param string $extnId
+ * @access private
+ * @return mixed
+ */
+ function _getMapping($extnId)
+ {
+ if (!is_string($extnId)) { // eg. if it's a \phpseclib\File\ASN1\Element object
+ return true;
+ }
+
+ switch ($extnId) {
+ case 'id-ce-keyUsage':
+ return $this->KeyUsage;
+ case 'id-ce-basicConstraints':
+ return $this->BasicConstraints;
+ case 'id-ce-subjectKeyIdentifier':
+ return $this->KeyIdentifier;
+ case 'id-ce-cRLDistributionPoints':
+ return $this->CRLDistributionPoints;
+ case 'id-ce-authorityKeyIdentifier':
+ return $this->AuthorityKeyIdentifier;
+ case 'id-ce-certificatePolicies':
+ return $this->CertificatePolicies;
+ case 'id-ce-extKeyUsage':
+ return $this->ExtKeyUsageSyntax;
+ case 'id-pe-authorityInfoAccess':
+ return $this->AuthorityInfoAccessSyntax;
+ case 'id-pe-subjectInfoAccess':
+ return $this->SubjectInfoAccessSyntax;
+ case 'id-ce-subjectAltName':
+ return $this->SubjectAltName;
+ case 'id-ce-subjectDirectoryAttributes':
+ return $this->SubjectDirectoryAttributes;
+ case 'id-ce-privateKeyUsagePeriod':
+ return $this->PrivateKeyUsagePeriod;
+ case 'id-ce-issuerAltName':
+ return $this->IssuerAltName;
+ case 'id-ce-policyMappings':
+ return $this->PolicyMappings;
+ case 'id-ce-nameConstraints':
+ return $this->NameConstraints;
+
+ case 'netscape-cert-type':
+ return $this->netscape_cert_type;
+ case 'netscape-comment':
+ return $this->netscape_comment;
+ case 'netscape-ca-policy-url':
+ return $this->netscape_ca_policy_url;
+
+ // since id-qt-cps isn't a constructed type it will have already been decoded as a string by the time it gets
+ // back around to asn1map() and we don't want it decoded again.
+ //case 'id-qt-cps':
+ // return $this->CPSuri;
+ case 'id-qt-unotice':
+ return $this->UserNotice;
+
+ // the following OIDs are unsupported but we don't want them to give notices when calling saveX509().
+ case 'id-pe-logotype': // http://www.ietf.org/rfc/rfc3709.txt
+ case 'entrustVersInfo':
+ // http://support.microsoft.com/kb/287547
+ case '1.3.6.1.4.1.311.20.2': // szOID_ENROLL_CERTTYPE_EXTENSION
+ case '1.3.6.1.4.1.311.21.1': // szOID_CERTSRV_CA_VERSION
+ // "SET Secure Electronic Transaction Specification"
+ // http://www.maithean.com/docs/set_bk3.pdf
+ case '2.23.42.7.0': // id-set-hashedRootKey
+ // "Certificate Transparency"
+ // https://tools.ietf.org/html/rfc6962
+ case '1.3.6.1.4.1.11129.2.4.2':
+ // "Qualified Certificate statements"
+ // https://tools.ietf.org/html/rfc3739#section-3.2.6
+ case '1.3.6.1.5.5.7.1.3':
+ return true;
+
+ // CSR attributes
+ case 'pkcs-9-at-unstructuredName':
+ return $this->PKCS9String;
+ case 'pkcs-9-at-challengePassword':
+ return $this->DirectoryString;
+ case 'pkcs-9-at-extensionRequest':
+ return $this->Extensions;
+
+ // CRL extensions.
+ case 'id-ce-cRLNumber':
+ return $this->CRLNumber;
+ case 'id-ce-deltaCRLIndicator':
+ return $this->CRLNumber;
+ case 'id-ce-issuingDistributionPoint':
+ return $this->IssuingDistributionPoint;
+ case 'id-ce-freshestCRL':
+ return $this->CRLDistributionPoints;
+ case 'id-ce-cRLReasons':
+ return $this->CRLReason;
+ case 'id-ce-invalidityDate':
+ return $this->InvalidityDate;
+ case 'id-ce-certificateIssuer':
+ return $this->CertificateIssuer;
+ case 'id-ce-holdInstructionCode':
+ return $this->HoldInstructionCode;
+ case 'id-at-postalAddress':
+ return $this->PostalAddress;
+ }
+
+ return false;
+ }
+
+ /**
+ * Load an X.509 certificate as a certificate authority
+ *
+ * @param string $cert
+ * @access public
+ * @return bool
+ */
+ function loadCA($cert)
+ {
+ $olddn = $this->dn;
+ $oldcert = $this->currentCert;
+ $oldsigsubj = $this->signatureSubject;
+ $oldkeyid = $this->currentKeyIdentifier;
+
+ $cert = $this->loadX509($cert);
+ if (!$cert) {
+ $this->dn = $olddn;
+ $this->currentCert = $oldcert;
+ $this->signatureSubject = $oldsigsubj;
+ $this->currentKeyIdentifier = $oldkeyid;
+
+ return false;
+ }
+
+ /* From RFC5280 "PKIX Certificate and CRL Profile":
+
+ If the keyUsage extension is present, then the subject public key
+ MUST NOT be used to verify signatures on certificates or CRLs unless
+ the corresponding keyCertSign or cRLSign bit is set. */
+ //$keyUsage = $this->getExtension('id-ce-keyUsage');
+ //if ($keyUsage && !in_array('keyCertSign', $keyUsage)) {
+ // return false;
+ //}
+
+ /* From RFC5280 "PKIX Certificate and CRL Profile":
+
+ The cA boolean indicates whether the certified public key may be used
+ to verify certificate signatures. If the cA boolean is not asserted,
+ then the keyCertSign bit in the key usage extension MUST NOT be
+ asserted. If the basic constraints extension is not present in a
+ version 3 certificate, or the extension is present but the cA boolean
+ is not asserted, then the certified public key MUST NOT be used to
+ verify certificate signatures. */
+ //$basicConstraints = $this->getExtension('id-ce-basicConstraints');
+ //if (!$basicConstraints || !$basicConstraints['cA']) {
+ // return false;
+ //}
+
+ $this->CAs[] = $cert;
+
+ $this->dn = $olddn;
+ $this->currentCert = $oldcert;
+ $this->signatureSubject = $oldsigsubj;
+
+ return true;
+ }
+
+ /**
+ * Validate an X.509 certificate against a URL
+ *
+ * From RFC2818 "HTTP over TLS":
+ *
+ * Matching is performed using the matching rules specified by
+ * [RFC2459]. If more than one identity of a given type is present in
+ * the certificate (e.g., more than one dNSName name, a match in any one
+ * of the set is considered acceptable.) Names may contain the wildcard
+ * character * which is considered to match any single domain name
+ * component or component fragment. E.g., *.a.com matches foo.a.com but
+ * not bar.foo.a.com. f*.com matches foo.com but not bar.com.
+ *
+ * @param string $url
+ * @access public
+ * @return bool
+ */
+ function validateURL($url)
+ {
+ if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) {
+ return false;
+ }
+
+ $components = parse_url($url);
+ if (!isset($components['host'])) {
+ return false;
+ }
+
+ if ($names = $this->getExtension('id-ce-subjectAltName')) {
+ foreach ($names as $name) {
+ foreach ($name as $key => $value) {
+ $value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value);
+ switch ($key) {
+ case 'dNSName':
+ /* From RFC2818 "HTTP over TLS":
+
+ If a subjectAltName extension of type dNSName is present, that MUST
+ be used as the identity. Otherwise, the (most specific) Common Name
+ field in the Subject field of the certificate MUST be used. Although
+ the use of the Common Name is existing practice, it is deprecated and
+ Certification Authorities are encouraged to use the dNSName instead. */
+ if (preg_match('#^' . $value . '$#', $components['host'])) {
+ return true;
+ }
+ break;
+ case 'iPAddress':
+ /* From RFC2818 "HTTP over TLS":
+
+ In some cases, the URI is specified as an IP address rather than a
+ hostname. In this case, the iPAddress subjectAltName must be present
+ in the certificate and must exactly match the IP in the URI. */
+ if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ if ($value = $this->getDNProp('id-at-commonName')) {
+ $value = str_replace(array('.', '*'), array('\.', '[^.]*'), $value[0]);
+ return preg_match('#^' . $value . '$#', $components['host']);
+ }
+
+ return false;
+ }
+
+ /**
+ * Validate a date
+ *
+ * If $date isn't defined it is assumed to be the current date.
+ *
+ * @param \DateTime|string $date optional
+ * @access public
+ */
+ function validateDate($date = null)
+ {
+ if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) {
+ return false;
+ }
+
+ if (!isset($date)) {
+ $date = new DateTime(null, new DateTimeZone(@date_default_timezone_get()));
+ }
+
+ $notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore'];
+ $notBefore = isset($notBefore['generalTime']) ? $notBefore['generalTime'] : $notBefore['utcTime'];
+
+ $notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter'];
+ $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime'];
+
+ if (is_string($date)) {
+ $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
+ }
+
+ $notBefore = new DateTime($notBefore, new DateTimeZone(@date_default_timezone_get()));
+ $notAfter = new DateTime($notAfter, new DateTimeZone(@date_default_timezone_get()));
+
+ switch (true) {
+ case $date < $notBefore:
+ case $date > $notAfter:
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Fetches a URL
+ *
+ * @param string $url
+ * @access private
+ * @return bool|string
+ */
+ static function _fetchURL($url)
+ {
+ if (self::$disable_url_fetch) {
+ return false;
+ }
+
+ $parts = parse_url($url);
+ $data = '';
+ switch ($parts['scheme']) {
+ case 'http':
+ $fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80);
+ if (!$fsock) {
+ return false;
+ }
+ fputs($fsock, "GET $parts[path] HTTP/1.0\r\n");
+ fputs($fsock, "Host: $parts[host]\r\n\r\n");
+ $line = fgets($fsock, 1024);
+ if (strlen($line) < 3) {
+ return false;
+ }
+ preg_match('#HTTP/1.\d (\d{3})#', $line, $temp);
+ if ($temp[1] != '200') {
+ return false;
+ }
+
+ // skip the rest of the headers in the http response
+ while (!feof($fsock) && fgets($fsock, 1024) != "\r\n") {
+ }
+
+ while (!feof($fsock)) {
+ $temp = fread($fsock, 1024);
+ if ($temp === false) {
+ return false;
+ }
+ $data.= $temp;
+ }
+
+ break;
+ //case 'ftp':
+ //case 'ldap':
+ //default:
+ }
+
+ return $data;
+ }
+
+ /**
+ * Validates an intermediate cert as identified via authority info access extension
+ *
+ * See https://tools.ietf.org/html/rfc4325 for more info
+ *
+ * @param bool $caonly
+ * @param int $count
+ * @access private
+ * @return bool
+ */
+ function _testForIntermediate($caonly, $count)
+ {
+ $opts = $this->getExtension('id-pe-authorityInfoAccess');
+ if (!is_array($opts)) {
+ return false;
+ }
+ foreach ($opts as $opt) {
+ if ($opt['accessMethod'] == 'id-ad-caIssuers') {
+ // accessLocation is a GeneralName. GeneralName fields support stuff like email addresses, IP addresses, LDAP,
+ // etc, but we're only supporting URI's. URI's and LDAP are the only thing https://tools.ietf.org/html/rfc4325
+ // discusses
+ if (isset($opt['accessLocation']['uniformResourceIdentifier'])) {
+ $url = $opt['accessLocation']['uniformResourceIdentifier'];
+ break;
+ }
+ }
+ }
+
+ if (!isset($url)) {
+ return false;
+ }
+
+ $cert = static::_fetchURL($url);
+ if (!is_string($cert)) {
+ return false;
+ }
+
+ $parent = new static();
+ $parent->CAs = $this->CAs;
+ /*
+ "Conforming applications that support HTTP or FTP for accessing
+ certificates MUST be able to accept .cer files and SHOULD be able
+ to accept .p7c files." -- https://tools.ietf.org/html/rfc4325
+
+ A .p7c file is 'a "certs-only" CMS message as specified in RFC 2797"
+
+ These are currently unsupported
+ */
+ if (!is_array($parent->loadX509($cert))) {
+ return false;
+ }
+
+ if (!$parent->_validateSignatureCountable($caonly, ++$count)) {
+ return false;
+ }
+
+ $this->CAs[] = $parent->currentCert;
+ //$this->loadCA($cert);
+
+ return true;
+ }
+
+ /**
+ * Validate a signature
+ *
+ * Works on X.509 certs, CSR's and CRL's.
+ * Returns true if the signature is verified, false if it is not correct or null on error
+ *
+ * By default returns false for self-signed certs. Call validateSignature(false) to make this support
+ * self-signed.
+ *
+ * The behavior of this function is inspired by {@link http://php.net/openssl-verify openssl_verify}.
+ *
+ * @param bool $caonly optional
+ * @access public
+ * @return mixed
+ */
+ function validateSignature($caonly = true)
+ {
+ return $this->_validateSignatureCountable($caonly, 0);
+ }
+
+ /**
+ * Validate a signature
+ *
+ * Performs said validation whilst keeping track of how many times validation method is called
+ *
+ * @param bool $caonly
+ * @param int $count
+ * @access private
+ * @return mixed
+ */
+ function _validateSignatureCountable($caonly, $count)
+ {
+ if (!is_array($this->currentCert) || !isset($this->signatureSubject)) {
+ return null;
+ }
+
+ if ($count == self::$recur_limit) {
+ return false;
+ }
+
+ /* TODO:
+ "emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")."
+ -- http://tools.ietf.org/html/rfc5280#section-4.1.2.6
+
+ implement pathLenConstraint in the id-ce-basicConstraints extension */
+
+ switch (true) {
+ case isset($this->currentCert['tbsCertificate']):
+ // self-signed cert
+ switch (true) {
+ case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']:
+ case defined('FILE_X509_IGNORE_TYPE') && $this->getIssuerDN(self::DN_STRING) === $this->getDN(self::DN_STRING):
+ $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
+ $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier');
+ switch (true) {
+ case !is_array($authorityKey):
+ case !$subjectKeyID:
+ case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
+ $signingCert = $this->currentCert; // working cert
+ }
+ }
+
+ if (!empty($this->CAs)) {
+ for ($i = 0; $i < count($this->CAs); $i++) {
+ // even if the cert is a self-signed one we still want to see if it's a CA;
+ // if not, we'll conditionally return an error
+ $ca = $this->CAs[$i];
+ switch (true) {
+ case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']:
+ case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertificate']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']):
+ $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
+ $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
+ switch (true) {
+ case !is_array($authorityKey):
+ case !$subjectKeyID:
+ case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
+ if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) {
+ break 2; // serial mismatch - check other ca
+ }
+ $signingCert = $ca; // working cert
+ break 3;
+ }
+ }
+ }
+ if (count($this->CAs) == $i && $caonly) {
+ return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
+ }
+ } elseif (!isset($signingCert) || $caonly) {
+ return $this->_testForIntermediate($caonly, $count) && $this->validateSignature($caonly);
+ }
+ return $this->_validateSignature(
+ $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
+ $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'],
+ $this->currentCert['signatureAlgorithm']['algorithm'],
+ substr(base64_decode($this->currentCert['signature']), 1),
+ $this->signatureSubject
+ );
+ case isset($this->currentCert['certificationRequestInfo']):
+ return $this->_validateSignature(
+ $this->currentCert['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'],
+ $this->currentCert['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'],
+ $this->currentCert['signatureAlgorithm']['algorithm'],
+ substr(base64_decode($this->currentCert['signature']), 1),
+ $this->signatureSubject
+ );
+ case isset($this->currentCert['publicKeyAndChallenge']):
+ return $this->_validateSignature(
+ $this->currentCert['publicKeyAndChallenge']['spki']['algorithm']['algorithm'],
+ $this->currentCert['publicKeyAndChallenge']['spki']['subjectPublicKey'],
+ $this->currentCert['signatureAlgorithm']['algorithm'],
+ substr(base64_decode($this->currentCert['signature']), 1),
+ $this->signatureSubject
+ );
+ case isset($this->currentCert['tbsCertList']):
+ if (!empty($this->CAs)) {
+ for ($i = 0; $i < count($this->CAs); $i++) {
+ $ca = $this->CAs[$i];
+ switch (true) {
+ case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertList']['issuer'] === $ca['tbsCertificate']['subject']:
+ case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertList']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']):
+ $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier');
+ $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
+ switch (true) {
+ case !is_array($authorityKey):
+ case !$subjectKeyID:
+ case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
+ if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) {
+ break 2; // serial mismatch - check other ca
+ }
+ $signingCert = $ca; // working cert
+ break 3;
+ }
+ }
+ }
+ }
+ if (!isset($signingCert)) {
+ return false;
+ }
+ return $this->_validateSignature(
+ $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'],
+ $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'],
+ $this->currentCert['signatureAlgorithm']['algorithm'],
+ substr(base64_decode($this->currentCert['signature']), 1),
+ $this->signatureSubject
+ );
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Validates a signature
+ *
+ * Returns true if the signature is verified, false if it is not correct or null on error
+ *
+ * @param string $publicKeyAlgorithm
+ * @param string $publicKey
+ * @param string $signatureAlgorithm
+ * @param string $signature
+ * @param string $signatureSubject
+ * @access private
+ * @return int
+ */
+ function _validateSignature($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject)
+ {
+ switch ($publicKeyAlgorithm) {
+ case 'rsaEncryption':
+ $rsa = new RSA();
+ $rsa->loadKey($publicKey);
+
+ switch ($signatureAlgorithm) {
+ case 'md2WithRSAEncryption':
+ case 'md5WithRSAEncryption':
+ case 'sha1WithRSAEncryption':
+ case 'sha224WithRSAEncryption':
+ case 'sha256WithRSAEncryption':
+ case 'sha384WithRSAEncryption':
+ case 'sha512WithRSAEncryption':
+ $rsa->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm));
+ $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
+ if (!@$rsa->verify($signatureSubject, $signature)) {
+ return false;
+ }
+ break;
+ default:
+ return null;
+ }
+ break;
+ default:
+ return null;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets the recursion limit
+ *
+ * When validating a signature it may be necessary to download intermediate certs from URI's.
+ * An intermediate cert that linked to itself would result in an infinite loop so to prevent
+ * that we set a recursion limit. A negative number means that there is no recursion limit.
+ *
+ * @param int $count
+ * @access public
+ */
+ static function setRecurLimit($count)
+ {
+ self::$recur_limit = $count;
+ }
+
+ /**
+ * Prevents URIs from being automatically retrieved
+ *
+ * @access public
+ */
+ static function disableURLFetch()
+ {
+ self::$disable_url_fetch = true;
+ }
+
+ /**
+ * Allows URIs to be automatically retrieved
+ *
+ * @access public
+ */
+ static function enableURLFetch()
+ {
+ self::$disable_url_fetch = false;
+ }
+
+ /**
+ * Reformat public keys
+ *
+ * Reformats a public key to a format supported by phpseclib (if applicable)
+ *
+ * @param string $algorithm
+ * @param string $key
+ * @access private
+ * @return string
+ */
+ function _reformatKey($algorithm, $key)
+ {
+ switch ($algorithm) {
+ case 'rsaEncryption':
+ return
+ "-----BEGIN RSA PUBLIC KEY-----\r\n" .
+ // subjectPublicKey is stored as a bit string in X.509 certs. the first byte of a bit string represents how many bits
+ // in the last byte should be ignored. the following only supports non-zero stuff but as none of the X.509 certs Firefox
+ // uses as a cert authority actually use a non-zero bit I think it's safe to assume that none do.
+ chunk_split(base64_encode(substr(base64_decode($key), 1)), 64) .
+ '-----END RSA PUBLIC KEY-----';
+ default:
+ return $key;
+ }
+ }
+
+ /**
+ * Decodes an IP address
+ *
+ * Takes in a base64 encoded "blob" and returns a human readable IP address
+ *
+ * @param string $ip
+ * @access private
+ * @return string
+ */
+ function _decodeIP($ip)
+ {
+ return inet_ntop(base64_decode($ip));
+ }
+
+ /**
+ * Decodes an IP address in a name constraints extension
+ *
+ * Takes in a base64 encoded "blob" and returns a human readable IP address / mask
+ *
+ * @param string $ip
+ * @access private
+ * @return array
+ */
+ function _decodeNameConstraintIP($ip)
+ {
+ $ip = base64_decode($ip);
+ $size = strlen($ip) >> 1;
+ $mask = substr($ip, $size);
+ $ip = substr($ip, 0, $size);
+ return array(inet_ntop($ip), inet_ntop($mask));
+ }
+
+ /**
+ * Encodes an IP address
+ *
+ * Takes a human readable IP address into a base64-encoded "blob"
+ *
+ * @param string|array $ip
+ * @access private
+ * @return string
+ */
+ function _encodeIP($ip)
+ {
+ return is_string($ip) ?
+ base64_encode(inet_pton($ip)) :
+ base64_encode(inet_pton($ip[0]) . inet_pton($ip[1]));
+ }
+
+ /**
+ * "Normalizes" a Distinguished Name property
+ *
+ * @param string $propName
+ * @access private
+ * @return mixed
+ */
+ function _translateDNProp($propName)
+ {
+ switch (strtolower($propName)) {
+ case 'id-at-countryname':
+ case 'countryname':
+ case 'c':
+ return 'id-at-countryName';
+ case 'id-at-organizationname':
+ case 'organizationname':
+ case 'o':
+ return 'id-at-organizationName';
+ case 'id-at-dnqualifier':
+ case 'dnqualifier':
+ return 'id-at-dnQualifier';
+ case 'id-at-commonname':
+ case 'commonname':
+ case 'cn':
+ return 'id-at-commonName';
+ case 'id-at-stateorprovincename':
+ case 'stateorprovincename':
+ case 'state':
+ case 'province':
+ case 'provincename':
+ case 'st':
+ return 'id-at-stateOrProvinceName';
+ case 'id-at-localityname':
+ case 'localityname':
+ case 'l':
+ return 'id-at-localityName';
+ case 'id-emailaddress':
+ case 'emailaddress':
+ return 'pkcs-9-at-emailAddress';
+ case 'id-at-serialnumber':
+ case 'serialnumber':
+ return 'id-at-serialNumber';
+ case 'id-at-postalcode':
+ case 'postalcode':
+ return 'id-at-postalCode';
+ case 'id-at-streetaddress':
+ case 'streetaddress':
+ return 'id-at-streetAddress';
+ case 'id-at-name':
+ case 'name':
+ return 'id-at-name';
+ case 'id-at-givenname':
+ case 'givenname':
+ return 'id-at-givenName';
+ case 'id-at-surname':
+ case 'surname':
+ case 'sn':
+ return 'id-at-surname';
+ case 'id-at-initials':
+ case 'initials':
+ return 'id-at-initials';
+ case 'id-at-generationqualifier':
+ case 'generationqualifier':
+ return 'id-at-generationQualifier';
+ case 'id-at-organizationalunitname':
+ case 'organizationalunitname':
+ case 'ou':
+ return 'id-at-organizationalUnitName';
+ case 'id-at-pseudonym':
+ case 'pseudonym':
+ return 'id-at-pseudonym';
+ case 'id-at-title':
+ case 'title':
+ return 'id-at-title';
+ case 'id-at-description':
+ case 'description':
+ return 'id-at-description';
+ case 'id-at-role':
+ case 'role':
+ return 'id-at-role';
+ case 'id-at-uniqueidentifier':
+ case 'uniqueidentifier':
+ case 'x500uniqueidentifier':
+ return 'id-at-uniqueIdentifier';
+ case 'postaladdress':
+ case 'id-at-postaladdress':
+ return 'id-at-postalAddress';
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Set a Distinguished Name property
+ *
+ * @param string $propName
+ * @param mixed $propValue
+ * @param string $type optional
+ * @access public
+ * @return bool
+ */
+ function setDNProp($propName, $propValue, $type = 'utf8String')
+ {
+ if (empty($this->dn)) {
+ $this->dn = array('rdnSequence' => array());
+ }
+
+ if (($propName = $this->_translateDNProp($propName)) === false) {
+ return false;
+ }
+
+ foreach ((array) $propValue as $v) {
+ if (!is_array($v) && isset($type)) {
+ $v = array($type => $v);
+ }
+ $this->dn['rdnSequence'][] = array(
+ array(
+ 'type' => $propName,
+ 'value'=> $v
+ )
+ );
+ }
+
+ return true;
+ }
+
+ /**
+ * Remove Distinguished Name properties
+ *
+ * @param string $propName
+ * @access public
+ */
+ function removeDNProp($propName)
+ {
+ if (empty($this->dn)) {
+ return;
+ }
+
+ if (($propName = $this->_translateDNProp($propName)) === false) {
+ return;
+ }
+
+ $dn = &$this->dn['rdnSequence'];
+ $size = count($dn);
+ for ($i = 0; $i < $size; $i++) {
+ if ($dn[$i][0]['type'] == $propName) {
+ unset($dn[$i]);
+ }
+ }
+
+ $dn = array_values($dn);
+ // fix for https://bugs.php.net/75433 affecting PHP 7.2
+ if (!isset($dn[0])) {
+ $dn = array_splice($dn, 0, 0);
+ }
+ }
+
+ /**
+ * Get Distinguished Name properties
+ *
+ * @param string $propName
+ * @param array $dn optional
+ * @param bool $withType optional
+ * @return mixed
+ * @access public
+ */
+ function getDNProp($propName, $dn = null, $withType = false)
+ {
+ if (!isset($dn)) {
+ $dn = $this->dn;
+ }
+
+ if (empty($dn)) {
+ return false;
+ }
+
+ if (($propName = $this->_translateDNProp($propName)) === false) {
+ return false;
+ }
+
+ $asn1 = new ASN1();
+ $asn1->loadOIDs($this->oids);
+ $filters = array();
+ $filters['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
+ $asn1->loadFilters($filters);
+ $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
+ $dn = $dn['rdnSequence'];
+ $result = array();
+ for ($i = 0; $i < count($dn); $i++) {
+ if ($dn[$i][0]['type'] == $propName) {
+ $v = $dn[$i][0]['value'];
+ if (!$withType) {
+ if (is_array($v)) {
+ foreach ($v as $type => $s) {
+ $type = array_search($type, $asn1->ANYmap, true);
+ if ($type !== false && isset($asn1->stringTypeSize[$type])) {
+ $s = $asn1->convert($s, $type);
+ if ($s !== false) {
+ $v = $s;
+ break;
+ }
+ }
+ }
+ if (is_array($v)) {
+ $v = array_pop($v); // Always strip data type.
+ }
+ } elseif (is_object($v) && $v instanceof Element) {
+ $map = $this->_getMapping($propName);
+ if (!is_bool($map)) {
+ $decoded = $asn1->decodeBER($v);
+ $v = $asn1->asn1map($decoded[0], $map);
+ }
+ }
+ }
+ $result[] = $v;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Set a Distinguished Name
+ *
+ * @param mixed $dn
+ * @param bool $merge optional
+ * @param string $type optional
+ * @access public
+ * @return bool
+ */
+ function setDN($dn, $merge = false, $type = 'utf8String')
+ {
+ if (!$merge) {
+ $this->dn = null;
+ }
+
+ if (is_array($dn)) {
+ if (isset($dn['rdnSequence'])) {
+ $this->dn = $dn; // No merge here.
+ return true;
+ }
+
+ // handles stuff generated by openssl_x509_parse()
+ foreach ($dn as $prop => $value) {
+ if (!$this->setDNProp($prop, $value, $type)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // handles everything else
+ $results = preg_split('#((?:^|, *|/)(?:C=|O=|OU=|CN=|L=|ST=|SN=|postalCode=|streetAddress=|emailAddress=|serialNumber=|organizationalUnitName=|title=|description=|role=|x500UniqueIdentifier=|postalAddress=))#', $dn, -1, PREG_SPLIT_DELIM_CAPTURE);
+ for ($i = 1; $i < count($results); $i+=2) {
+ $prop = trim($results[$i], ', =/');
+ $value = $results[$i + 1];
+ if (!$this->setDNProp($prop, $value, $type)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the Distinguished Name for a certificates subject
+ *
+ * @param mixed $format optional
+ * @param array $dn optional
+ * @access public
+ * @return bool
+ */
+ function getDN($format = self::DN_ARRAY, $dn = null)
+ {
+ if (!isset($dn)) {
+ $dn = isset($this->currentCert['tbsCertList']) ? $this->currentCert['tbsCertList']['issuer'] : $this->dn;
+ }
+
+ switch ((int) $format) {
+ case self::DN_ARRAY:
+ return $dn;
+ case self::DN_ASN1:
+ $asn1 = new ASN1();
+ $asn1->loadOIDs($this->oids);
+ $filters = array();
+ $filters['rdnSequence']['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
+ $asn1->loadFilters($filters);
+ $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
+ return $asn1->encodeDER($dn, $this->Name);
+ case self::DN_CANON:
+ // No SEQUENCE around RDNs and all string values normalized as
+ // trimmed lowercase UTF-8 with all spacing as one blank.
+ // constructed RDNs will not be canonicalized
+ $asn1 = new ASN1();
+ $asn1->loadOIDs($this->oids);
+ $filters = array();
+ $filters['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
+ $asn1->loadFilters($filters);
+ $result = '';
+ $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
+ foreach ($dn['rdnSequence'] as $rdn) {
+ foreach ($rdn as $i => $attr) {
+ $attr = &$rdn[$i];
+ if (is_array($attr['value'])) {
+ foreach ($attr['value'] as $type => $v) {
+ $type = array_search($type, $asn1->ANYmap, true);
+ if ($type !== false && isset($asn1->stringTypeSize[$type])) {
+ $v = $asn1->convert($v, $type);
+ if ($v !== false) {
+ $v = preg_replace('/\s+/', ' ', $v);
+ $attr['value'] = strtolower(trim($v));
+ break;
+ }
+ }
+ }
+ }
+ }
+ $result .= $asn1->encodeDER($rdn, $this->RelativeDistinguishedName);
+ }
+ return $result;
+ case self::DN_HASH:
+ $dn = $this->getDN(self::DN_CANON, $dn);
+ $hash = new Hash('sha1');
+ $hash = $hash->hash($dn);
+ extract(unpack('Vhash', $hash));
+ return strtolower(bin2hex(pack('N', $hash)));
+ }
+
+ // Default is to return a string.
+ $start = true;
+ $output = '';
+
+ $result = array();
+ $asn1 = new ASN1();
+ $asn1->loadOIDs($this->oids);
+ $filters = array();
+ $filters['rdnSequence']['value'] = array('type' => ASN1::TYPE_UTF8_STRING);
+ $asn1->loadFilters($filters);
+ $this->_mapOutDNs($dn, 'rdnSequence', $asn1);
+
+ foreach ($dn['rdnSequence'] as $field) {
+ $prop = $field[0]['type'];
+ $value = $field[0]['value'];
+
+ $delim = ', ';
+ switch ($prop) {
+ case 'id-at-countryName':
+ $desc = 'C';
+ break;
+ case 'id-at-stateOrProvinceName':
+ $desc = 'ST';
+ break;
+ case 'id-at-organizationName':
+ $desc = 'O';
+ break;
+ case 'id-at-organizationalUnitName':
+ $desc = 'OU';
+ break;
+ case 'id-at-commonName':
+ $desc = 'CN';
+ break;
+ case 'id-at-localityName':
+ $desc = 'L';
+ break;
+ case 'id-at-surname':
+ $desc = 'SN';
+ break;
+ case 'id-at-uniqueIdentifier':
+ $delim = '/';
+ $desc = 'x500UniqueIdentifier';
+ break;
+ case 'id-at-postalAddress':
+ $delim = '/';
+ $desc = 'postalAddress';
+ break;
+ default:
+ $delim = '/';
+ $desc = preg_replace('#.+-([^-]+)$#', '$1', $prop);
+ }
+
+ if (!$start) {
+ $output.= $delim;
+ }
+ if (is_array($value)) {
+ foreach ($value as $type => $v) {
+ $type = array_search($type, $asn1->ANYmap, true);
+ if ($type !== false && isset($asn1->stringTypeSize[$type])) {
+ $v = $asn1->convert($v, $type);
+ if ($v !== false) {
+ $value = $v;
+ break;
+ }
+ }
+ }
+ if (is_array($value)) {
+ $value = array_pop($value); // Always strip data type.
+ }
+ } elseif (is_object($value) && $value instanceof Element) {
+ $callback = function ($x) {
+ return "\x" . bin2hex($x[0]);
+ };
+ $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element));
+ }
+ $output.= $desc . '=' . $value;
+ $result[$desc] = isset($result[$desc]) ?
+ array_merge((array) $result[$desc], array($value)) :
+ $value;
+ $start = false;
+ }
+
+ return $format == self::DN_OPENSSL ? $result : $output;
+ }
+
+ /**
+ * Get the Distinguished Name for a certificate/crl issuer
+ *
+ * @param int $format optional
+ * @access public
+ * @return mixed
+ */
+ function getIssuerDN($format = self::DN_ARRAY)
+ {
+ switch (true) {
+ case !isset($this->currentCert) || !is_array($this->currentCert):
+ break;
+ case isset($this->currentCert['tbsCertificate']):
+ return $this->getDN($format, $this->currentCert['tbsCertificate']['issuer']);
+ case isset($this->currentCert['tbsCertList']):
+ return $this->getDN($format, $this->currentCert['tbsCertList']['issuer']);
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the Distinguished Name for a certificate/csr subject
+ * Alias of getDN()
+ *
+ * @param int $format optional
+ * @access public
+ * @return mixed
+ */
+ function getSubjectDN($format = self::DN_ARRAY)
+ {
+ switch (true) {
+ case !empty($this->dn):
+ return $this->getDN($format);
+ case !isset($this->currentCert) || !is_array($this->currentCert):
+ break;
+ case isset($this->currentCert['tbsCertificate']):
+ return $this->getDN($format, $this->currentCert['tbsCertificate']['subject']);
+ case isset($this->currentCert['certificationRequestInfo']):
+ return $this->getDN($format, $this->currentCert['certificationRequestInfo']['subject']);
+ }
+
+ return false;
+ }
+
+ /**
+ * Get an individual Distinguished Name property for a certificate/crl issuer
+ *
+ * @param string $propName
+ * @param bool $withType optional
+ * @access public
+ * @return mixed
+ */
+ function getIssuerDNProp($propName, $withType = false)
+ {
+ switch (true) {
+ case !isset($this->currentCert) || !is_array($this->currentCert):
+ break;
+ case isset($this->currentCert['tbsCertificate']):
+ return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['issuer'], $withType);
+ case isset($this->currentCert['tbsCertList']):
+ return $this->getDNProp($propName, $this->currentCert['tbsCertList']['issuer'], $withType);
+ }
+
+ return false;
+ }
+
+ /**
+ * Get an individual Distinguished Name property for a certificate/csr subject
+ *
+ * @param string $propName
+ * @param bool $withType optional
+ * @access public
+ * @return mixed
+ */
+ function getSubjectDNProp($propName, $withType = false)
+ {
+ switch (true) {
+ case !empty($this->dn):
+ return $this->getDNProp($propName, null, $withType);
+ case !isset($this->currentCert) || !is_array($this->currentCert):
+ break;
+ case isset($this->currentCert['tbsCertificate']):
+ return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['subject'], $withType);
+ case isset($this->currentCert['certificationRequestInfo']):
+ return $this->getDNProp($propName, $this->currentCert['certificationRequestInfo']['subject'], $withType);
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the certificate chain for the current cert
+ *
+ * @access public
+ * @return mixed
+ */
+ function getChain()
+ {
+ $chain = array($this->currentCert);
+
+ if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) {
+ return false;
+ }
+ if (empty($this->CAs)) {
+ return $chain;
+ }
+ while (true) {
+ $currentCert = $chain[count($chain) - 1];
+ for ($i = 0; $i < count($this->CAs); $i++) {
+ $ca = $this->CAs[$i];
+ if ($currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) {
+ $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier', $currentCert);
+ $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca);
+ switch (true) {
+ case !is_array($authorityKey):
+ case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID:
+ if ($currentCert === $ca) {
+ break 3;
+ }
+ $chain[] = $ca;
+ break 2;
+ }
+ }
+ }
+ if ($i == count($this->CAs)) {
+ break;
+ }
+ }
+ foreach ($chain as $key => $value) {
+ $chain[$key] = new X509();
+ $chain[$key]->loadX509($value);
+ }
+ return $chain;
+ }
+
+ /**
+ * Set public key
+ *
+ * Key needs to be a \phpseclib\Crypt\RSA object
+ *
+ * @param object $key
+ * @access public
+ * @return bool
+ */
+ function setPublicKey($key)
+ {
+ $key->setPublicKey();
+ $this->publicKey = $key;
+ }
+
+ /**
+ * Set private key
+ *
+ * Key needs to be a \phpseclib\Crypt\RSA object
+ *
+ * @param object $key
+ * @access public
+ */
+ function setPrivateKey($key)
+ {
+ $this->privateKey = $key;
+ }
+
+ /**
+ * Set challenge
+ *
+ * Used for SPKAC CSR's
+ *
+ * @param string $challenge
+ * @access public
+ */
+ function setChallenge($challenge)
+ {
+ $this->challenge = $challenge;
+ }
+
+ /**
+ * Gets the public key
+ *
+ * Returns a \phpseclib\Crypt\RSA object or a false.
+ *
+ * @access public
+ * @return mixed
+ */
+ function getPublicKey()
+ {
+ if (isset($this->publicKey)) {
+ return $this->publicKey;
+ }
+
+ if (isset($this->currentCert) && is_array($this->currentCert)) {
+ foreach (array('tbsCertificate/subjectPublicKeyInfo', 'certificationRequestInfo/subjectPKInfo') as $path) {
+ $keyinfo = $this->_subArray($this->currentCert, $path);
+ if (!empty($keyinfo)) {
+ break;
+ }
+ }
+ }
+ if (empty($keyinfo)) {
+ return false;
+ }
+
+ $key = $keyinfo['subjectPublicKey'];
+
+ switch ($keyinfo['algorithm']['algorithm']) {
+ case 'rsaEncryption':
+ $publicKey = new RSA();
+ $publicKey->loadKey($key);
+ $publicKey->setPublicKey();
+ break;
+ default:
+ return false;
+ }
+
+ return $publicKey;
+ }
+
+ /**
+ * Load a Certificate Signing Request
+ *
+ * @param string $csr
+ * @access public
+ * @return mixed
+ */
+ function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT)
+ {
+ if (is_array($csr) && isset($csr['certificationRequestInfo'])) {
+ unset($this->currentCert);
+ unset($this->currentKeyIdentifier);
+ unset($this->signatureSubject);
+ $this->dn = $csr['certificationRequestInfo']['subject'];
+ if (!isset($this->dn)) {
+ return false;
+ }
+
+ $this->currentCert = $csr;
+ return $csr;
+ }
+
+ // see http://tools.ietf.org/html/rfc2986
+
+ $asn1 = new ASN1();
+
+ if ($mode != self::FORMAT_DER) {
+ $newcsr = $this->_extractBER($csr);
+ if ($mode == self::FORMAT_PEM && $csr == $newcsr) {
+ return false;
+ }
+ $csr = $newcsr;
+ }
+ $orig = $csr;
+
+ if ($csr === false) {
+ $this->currentCert = false;
+ return false;
+ }
+
+ $asn1->loadOIDs($this->oids);
+ $decoded = $asn1->decodeBER($csr);
+
+ if (empty($decoded)) {
+ $this->currentCert = false;
+ return false;
+ }
+
+ $csr = $asn1->asn1map($decoded[0], $this->CertificationRequest);
+ if (!isset($csr) || $csr === false) {
+ $this->currentCert = false;
+ return false;
+ }
+
+ $this->_mapInAttributes($csr, 'certificationRequestInfo/attributes', $asn1);
+ $this->_mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1);
+
+ $this->dn = $csr['certificationRequestInfo']['subject'];
+
+ $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
+
+ $algorithm = &$csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'];
+ $key = &$csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'];
+ $key = $this->_reformatKey($algorithm, $key);
+
+ switch ($algorithm) {
+ case 'rsaEncryption':
+ $this->publicKey = new RSA();
+ $this->publicKey->loadKey($key);
+ $this->publicKey->setPublicKey();
+ break;
+ default:
+ $this->publicKey = null;
+ }
+
+ $this->currentKeyIdentifier = null;
+ $this->currentCert = $csr;
+
+ return $csr;
+ }
+
+ /**
+ * Save CSR request
+ *
+ * @param array $csr
+ * @param int $format optional
+ * @access public
+ * @return string
+ */
+ function saveCSR($csr, $format = self::FORMAT_PEM)
+ {
+ if (!is_array($csr) || !isset($csr['certificationRequestInfo'])) {
+ return false;
+ }
+
+ switch (true) {
+ case !($algorithm = $this->_subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')):
+ case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']):
+ break;
+ default:
+ switch ($algorithm) {
+ case 'rsaEncryption':
+ $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']
+ = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])));
+ $csr['certificationRequestInfo']['subjectPKInfo']['algorithm']['parameters'] = null;
+ $csr['signatureAlgorithm']['parameters'] = null;
+ $csr['certificationRequestInfo']['signature']['parameters'] = null;
+ }
+ }
+
+ $asn1 = new ASN1();
+
+ $asn1->loadOIDs($this->oids);
+
+ $filters = array();
+ $filters['certificationRequestInfo']['subject']['rdnSequence']['value']
+ = array('type' => ASN1::TYPE_UTF8_STRING);
+
+ $asn1->loadFilters($filters);
+
+ $this->_mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence', $asn1);
+ $this->_mapOutAttributes($csr, 'certificationRequestInfo/attributes', $asn1);
+ $csr = $asn1->encodeDER($csr, $this->CertificationRequest);
+
+ switch ($format) {
+ case self::FORMAT_DER:
+ return $csr;
+ // case self::FORMAT_PEM:
+ default:
+ return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(base64_encode($csr), 64) . '-----END CERTIFICATE REQUEST-----';
+ }
+ }
+
+ /**
+ * Load a SPKAC CSR
+ *
+ * SPKAC's are produced by the HTML5 keygen element:
+ *
+ * https://developer.mozilla.org/en-US/docs/HTML/Element/keygen
+ *
+ * @param string $csr
+ * @access public
+ * @return mixed
+ */
+ function loadSPKAC($spkac)
+ {
+ if (is_array($spkac) && isset($spkac['publicKeyAndChallenge'])) {
+ unset($this->currentCert);
+ unset($this->currentKeyIdentifier);
+ unset($this->signatureSubject);
+ $this->currentCert = $spkac;
+ return $spkac;
+ }
+
+ // see http://www.w3.org/html/wg/drafts/html/master/forms.html#signedpublickeyandchallenge
+
+ $asn1 = new ASN1();
+
+ // OpenSSL produces SPKAC's that are preceded by the string SPKAC=
+ $temp = preg_replace('#(?:SPKAC=)|[ \r\n\\\]#', '', $spkac);
+ $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
+ if ($temp != false) {
+ $spkac = $temp;
+ }
+ $orig = $spkac;
+
+ if ($spkac === false) {
+ $this->currentCert = false;
+ return false;
+ }
+
+ $asn1->loadOIDs($this->oids);
+ $decoded = $asn1->decodeBER($spkac);
+
+ if (empty($decoded)) {
+ $this->currentCert = false;
+ return false;
+ }
+
+ $spkac = $asn1->asn1map($decoded[0], $this->SignedPublicKeyAndChallenge);
+
+ if (!isset($spkac) || $spkac === false) {
+ $this->currentCert = false;
+ return false;
+ }
+
+ $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
+
+ $algorithm = &$spkac['publicKeyAndChallenge']['spki']['algorithm']['algorithm'];
+ $key = &$spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'];
+ $key = $this->_reformatKey($algorithm, $key);
+
+ switch ($algorithm) {
+ case 'rsaEncryption':
+ $this->publicKey = new RSA();
+ $this->publicKey->loadKey($key);
+ $this->publicKey->setPublicKey();
+ break;
+ default:
+ $this->publicKey = null;
+ }
+
+ $this->currentKeyIdentifier = null;
+ $this->currentCert = $spkac;
+
+ return $spkac;
+ }
+
+ /**
+ * Save a SPKAC CSR request
+ *
+ * @param array $csr
+ * @param int $format optional
+ * @access public
+ * @return string
+ */
+ function saveSPKAC($spkac, $format = self::FORMAT_PEM)
+ {
+ if (!is_array($spkac) || !isset($spkac['publicKeyAndChallenge'])) {
+ return false;
+ }
+
+ $algorithm = $this->_subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm');
+ switch (true) {
+ case !$algorithm:
+ case is_object($spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']):
+ break;
+ default:
+ switch ($algorithm) {
+ case 'rsaEncryption':
+ $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']
+ = base64_encode("\0" . base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'])));
+ }
+ }
+
+ $asn1 = new ASN1();
+
+ $asn1->loadOIDs($this->oids);
+ $spkac = $asn1->encodeDER($spkac, $this->SignedPublicKeyAndChallenge);
+
+ switch ($format) {
+ case self::FORMAT_DER:
+ return $spkac;
+ // case self::FORMAT_PEM:
+ default:
+ // OpenSSL's implementation of SPKAC requires the SPKAC be preceded by SPKAC= and since there are pretty much
+ // no other SPKAC decoders phpseclib will use that same format
+ return 'SPKAC=' . base64_encode($spkac);
+ }
+ }
+
+ /**
+ * Load a Certificate Revocation List
+ *
+ * @param string $crl
+ * @access public
+ * @return mixed
+ */
+ function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT)
+ {
+ if (is_array($crl) && isset($crl['tbsCertList'])) {
+ $this->currentCert = $crl;
+ unset($this->signatureSubject);
+ return $crl;
+ }
+
+ $asn1 = new ASN1();
+
+ if ($mode != self::FORMAT_DER) {
+ $newcrl = $this->_extractBER($crl);
+ if ($mode == self::FORMAT_PEM && $crl == $newcrl) {
+ return false;
+ }
+ $crl = $newcrl;
+ }
+ $orig = $crl;
+
+ if ($crl === false) {
+ $this->currentCert = false;
+ return false;
+ }
+
+ $asn1->loadOIDs($this->oids);
+ $decoded = $asn1->decodeBER($crl);
+
+ if (empty($decoded)) {
+ $this->currentCert = false;
+ return false;
+ }
+
+ $crl = $asn1->asn1map($decoded[0], $this->CertificateList);
+ if (!isset($crl) || $crl === false) {
+ $this->currentCert = false;
+ return false;
+ }
+
+ $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']);
+
+ $this->_mapInDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1);
+ if ($this->_isSubArrayValid($crl, 'tbsCertList/crlExtensions')) {
+ $this->_mapInExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
+ }
+ if ($this->_isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) {
+ $rclist_ref = &$this->_subArrayUnchecked($crl, 'tbsCertList/revokedCertificates');
+ if ($rclist_ref) {
+ $rclist = $crl['tbsCertList']['revokedCertificates'];
+ foreach ($rclist as $i => $extension) {
+ if ($this->_isSubArrayValid($rclist, "$i/crlEntryExtensions", $asn1)) {
+ $this->_mapInExtensions($rclist_ref, "$i/crlEntryExtensions", $asn1);
+ }
+ }
+ }
+ }
+
+ $this->currentKeyIdentifier = null;
+ $this->currentCert = $crl;
+
+ return $crl;
+ }
+
+ /**
+ * Save Certificate Revocation List.
+ *
+ * @param array $crl
+ * @param int $format optional
+ * @access public
+ * @return string
+ */
+ function saveCRL($crl, $format = self::FORMAT_PEM)
+ {
+ if (!is_array($crl) || !isset($crl['tbsCertList'])) {
+ return false;
+ }
+
+ $asn1 = new ASN1();
+
+ $asn1->loadOIDs($this->oids);
+
+ $filters = array();
+ $filters['tbsCertList']['issuer']['rdnSequence']['value']
+ = array('type' => ASN1::TYPE_UTF8_STRING);
+ $filters['tbsCertList']['signature']['parameters']
+ = array('type' => ASN1::TYPE_UTF8_STRING);
+ $filters['signatureAlgorithm']['parameters']
+ = array('type' => ASN1::TYPE_UTF8_STRING);
+
+ if (empty($crl['tbsCertList']['signature']['parameters'])) {
+ $filters['tbsCertList']['signature']['parameters']
+ = array('type' => ASN1::TYPE_NULL);
+ }
+
+ if (empty($crl['signatureAlgorithm']['parameters'])) {
+ $filters['signatureAlgorithm']['parameters']
+ = array('type' => ASN1::TYPE_NULL);
+ }
+
+ $asn1->loadFilters($filters);
+
+ $this->_mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence', $asn1);
+ $this->_mapOutExtensions($crl, 'tbsCertList/crlExtensions', $asn1);
+ $rclist = &$this->_subArray($crl, 'tbsCertList/revokedCertificates');
+ if (is_array($rclist)) {
+ foreach ($rclist as $i => $extension) {
+ $this->_mapOutExtensions($rclist, "$i/crlEntryExtensions", $asn1);
+ }
+ }
+
+ $crl = $asn1->encodeDER($crl, $this->CertificateList);
+
+ switch ($format) {
+ case self::FORMAT_DER:
+ return $crl;
+ // case self::FORMAT_PEM:
+ default:
+ return "-----BEGIN X509 CRL-----\r\n" . chunk_split(base64_encode($crl), 64) . '-----END X509 CRL-----';
+ }
+ }
+
+ /**
+ * Helper function to build a time field according to RFC 3280 section
+ * - 4.1.2.5 Validity
+ * - 5.1.2.4 This Update
+ * - 5.1.2.5 Next Update
+ * - 5.1.2.6 Revoked Certificates
+ * by choosing utcTime iff year of date given is before 2050 and generalTime else.
+ *
+ * @param string $date in format date('D, d M Y H:i:s O')
+ * @access private
+ * @return array
+ */
+ function _timeField($date)
+ {
+ if ($date instanceof Element) {
+ return $date;
+ }
+ $dateObj = new DateTime($date, new DateTimeZone('GMT'));
+ $year = $dateObj->format('Y'); // the same way ASN1.php parses this
+ if ($year < 2050) {
+ return array('utcTime' => $date);
+ } else {
+ return array('generalTime' => $date);
+ }
+ }
+
+ /**
+ * Sign an X.509 certificate
+ *
+ * $issuer's private key needs to be loaded.
+ * $subject can be either an existing X.509 cert (if you want to resign it),
+ * a CSR or something with the DN and public key explicitly set.
+ *
+ * @param \phpseclib\File\X509 $issuer
+ * @param \phpseclib\File\X509 $subject
+ * @param string $signatureAlgorithm optional
+ * @access public
+ * @return mixed
+ */
+ function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption')
+ {
+ if (!is_object($issuer->privateKey) || empty($issuer->dn)) {
+ return false;
+ }
+
+ if (isset($subject->publicKey) && !($subjectPublicKey = $subject->_formatSubjectPublicKey())) {
+ return false;
+ }
+
+ $currentCert = isset($this->currentCert) ? $this->currentCert : null;
+ $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null;
+
+ if (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertificate'])) {
+ $this->currentCert = $subject->currentCert;
+ $this->currentCert['tbsCertificate']['signature']['algorithm'] = $signatureAlgorithm;
+ $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm;
+
+ if (!empty($this->startDate)) {
+ $this->currentCert['tbsCertificate']['validity']['notBefore'] = $this->_timeField($this->startDate);
+ }
+ if (!empty($this->endDate)) {
+ $this->currentCert['tbsCertificate']['validity']['notAfter'] = $this->_timeField($this->endDate);
+ }
+ if (!empty($this->serialNumber)) {
+ $this->currentCert['tbsCertificate']['serialNumber'] = $this->serialNumber;
+ }
+ if (!empty($subject->dn)) {
+ $this->currentCert['tbsCertificate']['subject'] = $subject->dn;
+ }
+ if (!empty($subject->publicKey)) {
+ $this->currentCert['tbsCertificate']['subjectPublicKeyInfo'] = $subjectPublicKey;
+ }
+ $this->removeExtension('id-ce-authorityKeyIdentifier');
+ if (isset($subject->domains)) {
+ $this->removeExtension('id-ce-subjectAltName');
+ }
+ } elseif (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertList'])) {
+ return false;
+ } else {
+ if (!isset($subject->publicKey)) {
+ return false;
+ }
+
+ $startDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
+ $startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O');
+
+ $endDate = new DateTime('+1 year', new DateTimeZone(@date_default_timezone_get()));
+ $endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O');
+
+ /* "The serial number MUST be a positive integer"
+ "Conforming CAs MUST NOT use serialNumber values longer than 20 octets."
+ -- https://tools.ietf.org/html/rfc5280#section-4.1.2.2
+
+ for the integer to be positive the leading bit needs to be 0 hence the
+ application of a bitmap
+ */
+ $serialNumber = !empty($this->serialNumber) ?
+ $this->serialNumber :
+ new BigInteger(Random::string(20) & ("\x7F" . str_repeat("\xFF", 19)), 256);
+
+ $this->currentCert = array(
+ 'tbsCertificate' =>
+ array(
+ 'version' => 'v3',
+ 'serialNumber' => $serialNumber, // $this->setSerialNumber()
+ 'signature' => array('algorithm' => $signatureAlgorithm),
+ 'issuer' => false, // this is going to be overwritten later
+ 'validity' => array(
+ 'notBefore' => $this->_timeField($startDate), // $this->setStartDate()
+ 'notAfter' => $this->_timeField($endDate) // $this->setEndDate()
+ ),
+ 'subject' => $subject->dn,
+ 'subjectPublicKeyInfo' => $subjectPublicKey
+ ),
+ 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+ 'signature' => false // this is going to be overwritten later
+ );
+
+ // Copy extensions from CSR.
+ $csrexts = $subject->getAttribute('pkcs-9-at-extensionRequest', 0);
+
+ if (!empty($csrexts)) {
+ $this->currentCert['tbsCertificate']['extensions'] = $csrexts;
+ }
+ }
+
+ $this->currentCert['tbsCertificate']['issuer'] = $issuer->dn;
+
+ if (isset($issuer->currentKeyIdentifier)) {
+ $this->setExtension('id-ce-authorityKeyIdentifier', array(
+ //'authorityCertIssuer' => array(
+ // array(
+ // 'directoryName' => $issuer->dn
+ // )
+ //),
+ 'keyIdentifier' => $issuer->currentKeyIdentifier
+ ));
+ //$extensions = &$this->currentCert['tbsCertificate']['extensions'];
+ //if (isset($issuer->serialNumber)) {
+ // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber;
+ //}
+ //unset($extensions);
+ }
+
+ if (isset($subject->currentKeyIdentifier)) {
+ $this->setExtension('id-ce-subjectKeyIdentifier', $subject->currentKeyIdentifier);
+ }
+
+ $altName = array();
+
+ if (isset($subject->domains) && count($subject->domains)) {
+ $altName = array_map(array('\phpseclib\File\X509', '_dnsName'), $subject->domains);
+ }
+
+ if (isset($subject->ipAddresses) && count($subject->ipAddresses)) {
+ // should an IP address appear as the CN if no domain name is specified? idk
+ //$ips = count($subject->domains) ? $subject->ipAddresses : array_slice($subject->ipAddresses, 1);
+ $ipAddresses = array();
+ foreach ($subject->ipAddresses as $ipAddress) {
+ $encoded = $subject->_ipAddress($ipAddress);
+ if ($encoded !== false) {
+ $ipAddresses[] = $encoded;
+ }
+ }
+ if (count($ipAddresses)) {
+ $altName = array_merge($altName, $ipAddresses);
+ }
+ }
+
+ if (!empty($altName)) {
+ $this->setExtension('id-ce-subjectAltName', $altName);
+ }
+
+ if ($this->caFlag) {
+ $keyUsage = $this->getExtension('id-ce-keyUsage');
+ if (!$keyUsage) {
+ $keyUsage = array();
+ }
+
+ $this->setExtension(
+ 'id-ce-keyUsage',
+ array_values(array_unique(array_merge($keyUsage, array('cRLSign', 'keyCertSign'))))
+ );
+
+ $basicConstraints = $this->getExtension('id-ce-basicConstraints');
+ if (!$basicConstraints) {
+ $basicConstraints = array();
+ }
+
+ $this->setExtension(
+ 'id-ce-basicConstraints',
+ array_unique(array_merge(array('cA' => true), $basicConstraints)),
+ true
+ );
+
+ if (!isset($subject->currentKeyIdentifier)) {
+ $this->setExtension('id-ce-subjectKeyIdentifier', base64_encode($this->computeKeyIdentifier($this->currentCert)), false, false);
+ }
+ }
+
+ // resync $this->signatureSubject
+ // save $tbsCertificate in case there are any \phpseclib\File\ASN1\Element objects in it
+ $tbsCertificate = $this->currentCert['tbsCertificate'];
+ $this->loadX509($this->saveX509($this->currentCert));
+
+ $result = $this->_sign($issuer->privateKey, $signatureAlgorithm);
+ $result['tbsCertificate'] = $tbsCertificate;
+
+ $this->currentCert = $currentCert;
+ $this->signatureSubject = $signatureSubject;
+
+ return $result;
+ }
+
+ /**
+ * Sign a CSR
+ *
+ * @access public
+ * @return mixed
+ */
+ function signCSR($signatureAlgorithm = 'sha1WithRSAEncryption')
+ {
+ if (!is_object($this->privateKey) || empty($this->dn)) {
+ return false;
+ }
+
+ $origPublicKey = $this->publicKey;
+ $class = get_class($this->privateKey);
+ $this->publicKey = new $class();
+ $this->publicKey->loadKey($this->privateKey->getPublicKey());
+ $this->publicKey->setPublicKey();
+ if (!($publicKey = $this->_formatSubjectPublicKey())) {
+ return false;
+ }
+ $this->publicKey = $origPublicKey;
+
+ $currentCert = isset($this->currentCert) ? $this->currentCert : null;
+ $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null;
+
+ if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['certificationRequestInfo'])) {
+ $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm;
+ if (!empty($this->dn)) {
+ $this->currentCert['certificationRequestInfo']['subject'] = $this->dn;
+ }
+ $this->currentCert['certificationRequestInfo']['subjectPKInfo'] = $publicKey;
+ } else {
+ $this->currentCert = array(
+ 'certificationRequestInfo' =>
+ array(
+ 'version' => 'v1',
+ 'subject' => $this->dn,
+ 'subjectPKInfo' => $publicKey
+ ),
+ 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+ 'signature' => false // this is going to be overwritten later
+ );
+ }
+
+ // resync $this->signatureSubject
+ // save $certificationRequestInfo in case there are any \phpseclib\File\ASN1\Element objects in it
+ $certificationRequestInfo = $this->currentCert['certificationRequestInfo'];
+ $this->loadCSR($this->saveCSR($this->currentCert));
+
+ $result = $this->_sign($this->privateKey, $signatureAlgorithm);
+ $result['certificationRequestInfo'] = $certificationRequestInfo;
+
+ $this->currentCert = $currentCert;
+ $this->signatureSubject = $signatureSubject;
+
+ return $result;
+ }
+
+ /**
+ * Sign a SPKAC
+ *
+ * @access public
+ * @return mixed
+ */
+ function signSPKAC($signatureAlgorithm = 'sha1WithRSAEncryption')
+ {
+ if (!is_object($this->privateKey)) {
+ return false;
+ }
+
+ $origPublicKey = $this->publicKey;
+ $class = get_class($this->privateKey);
+ $this->publicKey = new $class();
+ $this->publicKey->loadKey($this->privateKey->getPublicKey());
+ $this->publicKey->setPublicKey();
+ $publicKey = $this->_formatSubjectPublicKey();
+ if (!$publicKey) {
+ return false;
+ }
+ $this->publicKey = $origPublicKey;
+
+ $currentCert = isset($this->currentCert) ? $this->currentCert : null;
+ $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject: null;
+
+ // re-signing a SPKAC seems silly but since everything else supports re-signing why not?
+ if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['publicKeyAndChallenge'])) {
+ $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm;
+ $this->currentCert['publicKeyAndChallenge']['spki'] = $publicKey;
+ if (!empty($this->challenge)) {
+ // the bitwise AND ensures that the output is a valid IA5String
+ $this->currentCert['publicKeyAndChallenge']['challenge'] = $this->challenge & str_repeat("\x7F", strlen($this->challenge));
+ }
+ } else {
+ $this->currentCert = array(
+ 'publicKeyAndChallenge' =>
+ array(
+ 'spki' => $publicKey,
+ // quoting <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/keygen>,
+ // "A challenge string that is submitted along with the public key. Defaults to an empty string if not specified."
+ // both Firefox and OpenSSL ("openssl spkac -key private.key") behave this way
+ // we could alternatively do this instead if we ignored the specs:
+ // Random::string(8) & str_repeat("\x7F", 8)
+ 'challenge' => !empty($this->challenge) ? $this->challenge : ''
+ ),
+ 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+ 'signature' => false // this is going to be overwritten later
+ );
+ }
+
+ // resync $this->signatureSubject
+ // save $publicKeyAndChallenge in case there are any \phpseclib\File\ASN1\Element objects in it
+ $publicKeyAndChallenge = $this->currentCert['publicKeyAndChallenge'];
+ $this->loadSPKAC($this->saveSPKAC($this->currentCert));
+
+ $result = $this->_sign($this->privateKey, $signatureAlgorithm);
+ $result['publicKeyAndChallenge'] = $publicKeyAndChallenge;
+
+ $this->currentCert = $currentCert;
+ $this->signatureSubject = $signatureSubject;
+
+ return $result;
+ }
+
+ /**
+ * Sign a CRL
+ *
+ * $issuer's private key needs to be loaded.
+ *
+ * @param \phpseclib\File\X509 $issuer
+ * @param \phpseclib\File\X509 $crl
+ * @param string $signatureAlgorithm optional
+ * @access public
+ * @return mixed
+ */
+ function signCRL($issuer, $crl, $signatureAlgorithm = 'sha1WithRSAEncryption')
+ {
+ if (!is_object($issuer->privateKey) || empty($issuer->dn)) {
+ return false;
+ }
+
+ $currentCert = isset($this->currentCert) ? $this->currentCert : null;
+ $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null;
+
+ $thisUpdate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
+ $thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O');
+
+ if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) {
+ $this->currentCert = $crl->currentCert;
+ $this->currentCert['tbsCertList']['signature']['algorithm'] = $signatureAlgorithm;
+ $this->currentCert['signatureAlgorithm']['algorithm'] = $signatureAlgorithm;
+ } else {
+ $this->currentCert = array(
+ 'tbsCertList' =>
+ array(
+ 'version' => 'v2',
+ 'signature' => array('algorithm' => $signatureAlgorithm),
+ 'issuer' => false, // this is going to be overwritten later
+ 'thisUpdate' => $this->_timeField($thisUpdate) // $this->setStartDate()
+ ),
+ 'signatureAlgorithm' => array('algorithm' => $signatureAlgorithm),
+ 'signature' => false // this is going to be overwritten later
+ );
+ }
+
+ $tbsCertList = &$this->currentCert['tbsCertList'];
+ $tbsCertList['issuer'] = $issuer->dn;
+ $tbsCertList['thisUpdate'] = $this->_timeField($thisUpdate);
+
+ if (!empty($this->endDate)) {
+ $tbsCertList['nextUpdate'] = $this->_timeField($this->endDate); // $this->setEndDate()
+ } else {
+ unset($tbsCertList['nextUpdate']);
+ }
+
+ if (!empty($this->serialNumber)) {
+ $crlNumber = $this->serialNumber;
+ } else {
+ $crlNumber = $this->getExtension('id-ce-cRLNumber');
+ // "The CRL number is a non-critical CRL extension that conveys a
+ // monotonically increasing sequence number for a given CRL scope and
+ // CRL issuer. This extension allows users to easily determine when a
+ // particular CRL supersedes another CRL."
+ // -- https://tools.ietf.org/html/rfc5280#section-5.2.3
+ $crlNumber = $crlNumber !== false ? $crlNumber->add(new BigInteger(1)) : null;
+ }
+
+ $this->removeExtension('id-ce-authorityKeyIdentifier');
+ $this->removeExtension('id-ce-issuerAltName');
+
+ // Be sure version >= v2 if some extension found.
+ $version = isset($tbsCertList['version']) ? $tbsCertList['version'] : 0;
+ if (!$version) {
+ if (!empty($tbsCertList['crlExtensions'])) {
+ $version = 1; // v2.
+ } elseif (!empty($tbsCertList['revokedCertificates'])) {
+ foreach ($tbsCertList['revokedCertificates'] as $cert) {
+ if (!empty($cert['crlEntryExtensions'])) {
+ $version = 1; // v2.
+ }
+ }
+ }
+
+ if ($version) {
+ $tbsCertList['version'] = $version;
+ }
+ }
+
+ // Store additional extensions.
+ if (!empty($tbsCertList['version'])) { // At least v2.
+ if (!empty($crlNumber)) {
+ $this->setExtension('id-ce-cRLNumber', $crlNumber);
+ }
+
+ if (isset($issuer->currentKeyIdentifier)) {
+ $this->setExtension('id-ce-authorityKeyIdentifier', array(
+ //'authorityCertIssuer' => array(
+ // array(
+ // 'directoryName' => $issuer->dn
+ // )
+ //),
+ 'keyIdentifier' => $issuer->currentKeyIdentifier
+ ));
+ //$extensions = &$tbsCertList['crlExtensions'];
+ //if (isset($issuer->serialNumber)) {
+ // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber;
+ //}
+ //unset($extensions);
+ }
+
+ $issuerAltName = $this->getExtension('id-ce-subjectAltName', $issuer->currentCert);
+
+ if ($issuerAltName !== false) {
+ $this->setExtension('id-ce-issuerAltName', $issuerAltName);
+ }
+ }
+
+ if (empty($tbsCertList['revokedCertificates'])) {
+ unset($tbsCertList['revokedCertificates']);
+ }
+
+ unset($tbsCertList);
+
+ // resync $this->signatureSubject
+ // save $tbsCertList in case there are any \phpseclib\File\ASN1\Element objects in it
+ $tbsCertList = $this->currentCert['tbsCertList'];
+ $this->loadCRL($this->saveCRL($this->currentCert));
+
+ $result = $this->_sign($issuer->privateKey, $signatureAlgorithm);
+ $result['tbsCertList'] = $tbsCertList;
+
+ $this->currentCert = $currentCert;
+ $this->signatureSubject = $signatureSubject;
+
+ return $result;
+ }
+
+ /**
+ * X.509 certificate signing helper function.
+ *
+ * @param object $key
+ * @param \phpseclib\File\X509 $subject
+ * @param string $signatureAlgorithm
+ * @access public
+ * @return mixed
+ */
+ function _sign($key, $signatureAlgorithm)
+ {
+ if ($key instanceof RSA) {
+ switch ($signatureAlgorithm) {
+ case 'md2WithRSAEncryption':
+ case 'md5WithRSAEncryption':
+ case 'sha1WithRSAEncryption':
+ case 'sha224WithRSAEncryption':
+ case 'sha256WithRSAEncryption':
+ case 'sha384WithRSAEncryption':
+ case 'sha512WithRSAEncryption':
+ $key->setHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm));
+ $key->setSignatureMode(RSA::SIGNATURE_PKCS1);
+
+ $this->currentCert['signature'] = base64_encode("\0" . $key->sign($this->signatureSubject));
+ return $this->currentCert;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Set certificate start date
+ *
+ * @param string $date
+ * @access public
+ */
+ function setStartDate($date)
+ {
+ if (!is_object($date) || !is_a($date, 'DateTime')) {
+ $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
+ }
+
+ $this->startDate = $date->format('D, d M Y H:i:s O');
+ }
+
+ /**
+ * Set certificate end date
+ *
+ * @param string $date
+ * @access public
+ */
+ function setEndDate($date)
+ {
+ /*
+ To indicate that a certificate has no well-defined expiration date,
+ the notAfter SHOULD be assigned the GeneralizedTime value of
+ 99991231235959Z.
+
+ -- http://tools.ietf.org/html/rfc5280#section-4.1.2.5
+ */
+ if (strtolower($date) == 'lifetime') {
+ $temp = '99991231235959Z';
+ $asn1 = new ASN1();
+ $temp = chr(ASN1::TYPE_GENERALIZED_TIME) . $asn1->_encodeLength(strlen($temp)) . $temp;
+ $this->endDate = new Element($temp);
+ } else {
+ if (!is_object($date) || !is_a($date, 'DateTime')) {
+ $date = new DateTime($date, new DateTimeZone(@date_default_timezone_get()));
+ }
+
+ $this->endDate = $date->format('D, d M Y H:i:s O');
+ }
+ }
+
+ /**
+ * Set Serial Number
+ *
+ * @param string $serial
+ * @param $base optional
+ * @access public
+ */
+ function setSerialNumber($serial, $base = -256)
+ {
+ $this->serialNumber = new BigInteger($serial, $base);
+ }
+
+ /**
+ * Turns the certificate into a certificate authority
+ *
+ * @access public
+ */
+ function makeCA()
+ {
+ $this->caFlag = true;
+ }
+
+ /**
+ * Check for validity of subarray
+ *
+ * This is intended for use in conjunction with _subArrayUnchecked(),
+ * implementing the checks included in _subArray() but without copying
+ * a potentially large array by passing its reference by-value to is_array().
+ *
+ * @param array $root
+ * @param string $path
+ * @return boolean
+ * @access private
+ */
+ function _isSubArrayValid($root, $path)
+ {
+ if (!is_array($root)) {
+ return false;
+ }
+
+ foreach (explode('/', $path) as $i) {
+ if (!is_array($root)) {
+ return false;
+ }
+
+ if (!isset($root[$i])) {
+ return true;
+ }
+
+ $root = $root[$i];
+ }
+
+ return true;
+ }
+
+ /**
+ * Get a reference to a subarray
+ *
+ * This variant of _subArray() does no is_array() checking,
+ * so $root should be checked with _isSubArrayValid() first.
+ *
+ * This is here for performance reasons:
+ * Passing a reference (i.e. $root) by-value (i.e. to is_array())
+ * creates a copy. If $root is an especially large array, this is expensive.
+ *
+ * @param array $root
+ * @param string $path absolute path with / as component separator
+ * @param bool $create optional
+ * @access private
+ * @return array|false
+ */
+ function &_subArrayUnchecked(&$root, $path, $create = false)
+ {
+ $false = false;
+
+ foreach (explode('/', $path) as $i) {
+ if (!isset($root[$i])) {
+ if (!$create) {
+ return $false;
+ }
+
+ $root[$i] = array();
+ }
+
+ $root = &$root[$i];
+ }
+
+ return $root;
+ }
+
+ /**
+ * Get a reference to a subarray
+ *
+ * @param array $root
+ * @param string $path absolute path with / as component separator
+ * @param bool $create optional
+ * @access private
+ * @return array|false
+ */
+ function &_subArray(&$root, $path, $create = false)
+ {
+ $false = false;
+
+ if (!is_array($root)) {
+ return $false;
+ }
+
+ foreach (explode('/', $path) as $i) {
+ if (!is_array($root)) {
+ return $false;
+ }
+
+ if (!isset($root[$i])) {
+ if (!$create) {
+ return $false;
+ }
+
+ $root[$i] = array();
+ }
+
+ $root = &$root[$i];
+ }
+
+ return $root;
+ }
+
+ /**
+ * Get a reference to an extension subarray
+ *
+ * @param array $root
+ * @param string $path optional absolute path with / as component separator
+ * @param bool $create optional
+ * @access private
+ * @return array|false
+ */
+ function &_extensions(&$root, $path = null, $create = false)
+ {
+ if (!isset($root)) {
+ $root = $this->currentCert;
+ }
+
+ switch (true) {
+ case !empty($path):
+ case !is_array($root):
+ break;
+ case isset($root['tbsCertificate']):
+ $path = 'tbsCertificate/extensions';
+ break;
+ case isset($root['tbsCertList']):
+ $path = 'tbsCertList/crlExtensions';
+ break;
+ case isset($root['certificationRequestInfo']):
+ $pth = 'certificationRequestInfo/attributes';
+ $attributes = &$this->_subArray($root, $pth, $create);
+
+ if (is_array($attributes)) {
+ foreach ($attributes as $key => $value) {
+ if ($value['type'] == 'pkcs-9-at-extensionRequest') {
+ $path = "$pth/$key/value/0";
+ break 2;
+ }
+ }
+ if ($create) {
+ $key = count($attributes);
+ $attributes[] = array('type' => 'pkcs-9-at-extensionRequest', 'value' => array());
+ $path = "$pth/$key/value/0";
+ }
+ }
+ break;
+ }
+
+ $extensions = &$this->_subArray($root, $path, $create);
+
+ if (!is_array($extensions)) {
+ $false = false;
+ return $false;
+ }
+
+ return $extensions;
+ }
+
+ /**
+ * Remove an Extension
+ *
+ * @param string $id
+ * @param string $path optional
+ * @access private
+ * @return bool
+ */
+ function _removeExtension($id, $path = null)
+ {
+ $extensions = &$this->_extensions($this->currentCert, $path);
+
+ if (!is_array($extensions)) {
+ return false;
+ }
+
+ $result = false;
+ foreach ($extensions as $key => $value) {
+ if ($value['extnId'] == $id) {
+ unset($extensions[$key]);
+ $result = true;
+ }
+ }
+
+ $extensions = array_values($extensions);
+ // fix for https://bugs.php.net/75433 affecting PHP 7.2
+ if (!isset($extensions[0])) {
+ $extensions = array_splice($extensions, 0, 0);
+ }
+ return $result;
+ }
+
+ /**
+ * Get an Extension
+ *
+ * Returns the extension if it exists and false if not
+ *
+ * @param string $id
+ * @param array $cert optional
+ * @param string $path optional
+ * @access private
+ * @return mixed
+ */
+ function _getExtension($id, $cert = null, $path = null)
+ {
+ $extensions = $this->_extensions($cert, $path);
+
+ if (!is_array($extensions)) {
+ return false;
+ }
+
+ foreach ($extensions as $key => $value) {
+ if ($value['extnId'] == $id) {
+ return $value['extnValue'];
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a list of all extensions in use
+ *
+ * @param array $cert optional
+ * @param string $path optional
+ * @access private
+ * @return array
+ */
+ function _getExtensions($cert = null, $path = null)
+ {
+ $exts = $this->_extensions($cert, $path);
+ $extensions = array();
+
+ if (is_array($exts)) {
+ foreach ($exts as $extension) {
+ $extensions[] = $extension['extnId'];
+ }
+ }
+
+ return $extensions;
+ }
+
+ /**
+ * Set an Extension
+ *
+ * @param string $id
+ * @param mixed $value
+ * @param bool $critical optional
+ * @param bool $replace optional
+ * @param string $path optional
+ * @access private
+ * @return bool
+ */
+ function _setExtension($id, $value, $critical = false, $replace = true, $path = null)
+ {
+ $extensions = &$this->_extensions($this->currentCert, $path, true);
+
+ if (!is_array($extensions)) {
+ return false;
+ }
+
+ $newext = array('extnId' => $id, 'critical' => $critical, 'extnValue' => $value);
+
+ foreach ($extensions as $key => $value) {
+ if ($value['extnId'] == $id) {
+ if (!$replace) {
+ return false;
+ }
+
+ $extensions[$key] = $newext;
+ return true;
+ }
+ }
+
+ $extensions[] = $newext;
+ return true;
+ }
+
+ /**
+ * Remove a certificate, CSR or CRL Extension
+ *
+ * @param string $id
+ * @access public
+ * @return bool
+ */
+ function removeExtension($id)
+ {
+ return $this->_removeExtension($id);
+ }
+
+ /**
+ * Get a certificate, CSR or CRL Extension
+ *
+ * Returns the extension if it exists and false if not
+ *
+ * @param string $id
+ * @param array $cert optional
+ * @access public
+ * @return mixed
+ */
+ function getExtension($id, $cert = null)
+ {
+ return $this->_getExtension($id, $cert);
+ }
+
+ /**
+ * Returns a list of all extensions in use in certificate, CSR or CRL
+ *
+ * @param array $cert optional
+ * @access public
+ * @return array
+ */
+ function getExtensions($cert = null)
+ {
+ return $this->_getExtensions($cert);
+ }
+
+ /**
+ * Set a certificate, CSR or CRL Extension
+ *
+ * @param string $id
+ * @param mixed $value
+ * @param bool $critical optional
+ * @param bool $replace optional
+ * @access public
+ * @return bool
+ */
+ function setExtension($id, $value, $critical = false, $replace = true)
+ {
+ return $this->_setExtension($id, $value, $critical, $replace);
+ }
+
+ /**
+ * Remove a CSR attribute.
+ *
+ * @param string $id
+ * @param int $disposition optional
+ * @access public
+ * @return bool
+ */
+ function removeAttribute($id, $disposition = self::ATTR_ALL)
+ {
+ $attributes = &$this->_subArray($this->currentCert, 'certificationRequestInfo/attributes');
+
+ if (!is_array($attributes)) {
+ return false;
+ }
+
+ $result = false;
+ foreach ($attributes as $key => $attribute) {
+ if ($attribute['type'] == $id) {
+ $n = count($attribute['value']);
+ switch (true) {
+ case $disposition == self::ATTR_APPEND:
+ case $disposition == self::ATTR_REPLACE:
+ return false;
+ case $disposition >= $n:
+ $disposition -= $n;
+ break;
+ case $disposition == self::ATTR_ALL:
+ case $n == 1:
+ unset($attributes[$key]);
+ $result = true;
+ break;
+ default:
+ unset($attributes[$key]['value'][$disposition]);
+ $attributes[$key]['value'] = array_values($attributes[$key]['value']);
+ $result = true;
+ break;
+ }
+ if ($result && $disposition != self::ATTR_ALL) {
+ break;
+ }
+ }
+ }
+
+ $attributes = array_values($attributes);
+ return $result;
+ }
+
+ /**
+ * Get a CSR attribute
+ *
+ * Returns the attribute if it exists and false if not
+ *
+ * @param string $id
+ * @param int $disposition optional
+ * @param array $csr optional
+ * @access public
+ * @return mixed
+ */
+ function getAttribute($id, $disposition = self::ATTR_ALL, $csr = null)
+ {
+ if (empty($csr)) {
+ $csr = $this->currentCert;
+ }
+
+ $attributes = $this->_subArray($csr, 'certificationRequestInfo/attributes');
+
+ if (!is_array($attributes)) {
+ return false;
+ }
+
+ foreach ($attributes as $key => $attribute) {
+ if ($attribute['type'] == $id) {
+ $n = count($attribute['value']);
+ switch (true) {
+ case $disposition == self::ATTR_APPEND:
+ case $disposition == self::ATTR_REPLACE:
+ return false;
+ case $disposition == self::ATTR_ALL:
+ return $attribute['value'];
+ case $disposition >= $n:
+ $disposition -= $n;
+ break;
+ default:
+ return $attribute['value'][$disposition];
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a list of all CSR attributes in use
+ *
+ * @param array $csr optional
+ * @access public
+ * @return array
+ */
+ function getAttributes($csr = null)
+ {
+ if (empty($csr)) {
+ $csr = $this->currentCert;
+ }
+
+ $attributes = $this->_subArray($csr, 'certificationRequestInfo/attributes');
+ $attrs = array();
+
+ if (is_array($attributes)) {
+ foreach ($attributes as $attribute) {
+ $attrs[] = $attribute['type'];
+ }
+ }
+
+ return $attrs;
+ }
+
+ /**
+ * Set a CSR attribute
+ *
+ * @param string $id
+ * @param mixed $value
+ * @param bool $disposition optional
+ * @access public
+ * @return bool
+ */
+ function setAttribute($id, $value, $disposition = self::ATTR_ALL)
+ {
+ $attributes = &$this->_subArray($this->currentCert, 'certificationRequestInfo/attributes', true);
+
+ if (!is_array($attributes)) {
+ return false;
+ }
+
+ switch ($disposition) {
+ case self::ATTR_REPLACE:
+ $disposition = self::ATTR_APPEND;
+ case self::ATTR_ALL:
+ $this->removeAttribute($id);
+ break;
+ }
+
+ foreach ($attributes as $key => $attribute) {
+ if ($attribute['type'] == $id) {
+ $n = count($attribute['value']);
+ switch (true) {
+ case $disposition == self::ATTR_APPEND:
+ $last = $key;
+ break;
+ case $disposition >= $n:
+ $disposition -= $n;
+ break;
+ default:
+ $attributes[$key]['value'][$disposition] = $value;
+ return true;
+ }
+ }
+ }
+
+ switch (true) {
+ case $disposition >= 0:
+ return false;
+ case isset($last):
+ $attributes[$last]['value'][] = $value;
+ break;
+ default:
+ $attributes[] = array('type' => $id, 'value' => $disposition == self::ATTR_ALL ? $value: array($value));
+ break;
+ }
+
+ return true;
+ }
+
+ /**
+ * Sets the subject key identifier
+ *
+ * This is used by the id-ce-authorityKeyIdentifier and the id-ce-subjectKeyIdentifier extensions.
+ *
+ * @param string $value
+ * @access public
+ */
+ function setKeyIdentifier($value)
+ {
+ if (empty($value)) {
+ unset($this->currentKeyIdentifier);
+ } else {
+ $this->currentKeyIdentifier = base64_encode($value);
+ }
+ }
+
+ /**
+ * Compute a public key identifier.
+ *
+ * Although key identifiers may be set to any unique value, this function
+ * computes key identifiers from public key according to the two
+ * recommended methods (4.2.1.2 RFC 3280).
+ * Highly polymorphic: try to accept all possible forms of key:
+ * - Key object
+ * - \phpseclib\File\X509 object with public or private key defined
+ * - Certificate or CSR array
+ * - \phpseclib\File\ASN1\Element object
+ * - PEM or DER string
+ *
+ * @param mixed $key optional
+ * @param int $method optional
+ * @access public
+ * @return string binary key identifier
+ */
+ function computeKeyIdentifier($key = null, $method = 1)
+ {
+ if (is_null($key)) {
+ $key = $this;
+ }
+
+ switch (true) {
+ case is_string($key):
+ break;
+ case is_array($key) && isset($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']):
+ return $this->computeKeyIdentifier($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $method);
+ case is_array($key) && isset($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']):
+ return $this->computeKeyIdentifier($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], $method);
+ case !is_object($key):
+ return false;
+ case $key instanceof Element:
+ // Assume the element is a bitstring-packed key.
+ $asn1 = new ASN1();
+ $decoded = $asn1->decodeBER($key->element);
+ if (empty($decoded)) {
+ return false;
+ }
+ $raw = $asn1->asn1map($decoded[0], array('type' => ASN1::TYPE_BIT_STRING));
+ if (empty($raw)) {
+ return false;
+ }
+ $raw = base64_decode($raw);
+ // If the key is private, compute identifier from its corresponding public key.
+ $key = new RSA();
+ if (!$key->loadKey($raw)) {
+ return false; // Not an unencrypted RSA key.
+ }
+ if ($key->getPrivateKey() !== false) { // If private.
+ return $this->computeKeyIdentifier($key, $method);
+ }
+ $key = $raw; // Is a public key.
+ break;
+ case $key instanceof X509:
+ if (isset($key->publicKey)) {
+ return $this->computeKeyIdentifier($key->publicKey, $method);
+ }
+ if (isset($key->privateKey)) {
+ return $this->computeKeyIdentifier($key->privateKey, $method);
+ }
+ if (isset($key->currentCert['tbsCertificate']) || isset($key->currentCert['certificationRequestInfo'])) {
+ return $this->computeKeyIdentifier($key->currentCert, $method);
+ }
+ return false;
+ default: // Should be a key object (i.e.: \phpseclib\Crypt\RSA).
+ $key = $key->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1);
+ break;
+ }
+
+ // If in PEM format, convert to binary.
+ $key = $this->_extractBER($key);
+
+ // Now we have the key string: compute its sha-1 sum.
+ $hash = new Hash('sha1');
+ $hash = $hash->hash($key);
+
+ if ($method == 2) {
+ $hash = substr($hash, -8);
+ $hash[0] = chr((ord($hash[0]) & 0x0F) | 0x40);
+ }
+
+ return $hash;
+ }
+
+ /**
+ * Format a public key as appropriate
+ *
+ * @access private
+ * @return array
+ */
+ function _formatSubjectPublicKey()
+ {
+ if ($this->publicKey instanceof RSA) {
+ // the following two return statements do the same thing. i dunno.. i just prefer the later for some reason.
+ // the former is a good example of how to do fuzzing on the public key
+ //return new Element(base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->getPublicKey())));
+ return array(
+ 'algorithm' => array('algorithm' => 'rsaEncryption'),
+ 'subjectPublicKey' => $this->publicKey->getPublicKey(RSA::PUBLIC_FORMAT_PKCS1)
+ );
+ }
+
+ return false;
+ }
+
+ /**
+ * Set the domain name's which the cert is to be valid for
+ *
+ * @access public
+ * @return array
+ */
+ function setDomain()
+ {
+ $this->domains = func_get_args();
+ $this->removeDNProp('id-at-commonName');
+ $this->setDNProp('id-at-commonName', $this->domains[0]);
+ }
+
+ /**
+ * Set the IP Addresses's which the cert is to be valid for
+ *
+ * @access public
+ * @param string $ipAddress optional
+ */
+ function setIPAddress()
+ {
+ $this->ipAddresses = func_get_args();
+ /*
+ if (!isset($this->domains)) {
+ $this->removeDNProp('id-at-commonName');
+ $this->setDNProp('id-at-commonName', $this->ipAddresses[0]);
+ }
+ */
+ }
+
+ /**
+ * Helper function to build domain array
+ *
+ * @access private
+ * @param string $domain
+ * @return array
+ */
+ function _dnsName($domain)
+ {
+ return array('dNSName' => $domain);
+ }
+
+ /**
+ * Helper function to build IP Address array
+ *
+ * (IPv6 is not currently supported)
+ *
+ * @access private
+ * @param string $address
+ * @return array
+ */
+ function _iPAddress($address)
+ {
+ return array('iPAddress' => $address);
+ }
+
+ /**
+ * Get the index of a revoked certificate.
+ *
+ * @param array $rclist
+ * @param string $serial
+ * @param bool $create optional
+ * @access private
+ * @return int|false
+ */
+ function _revokedCertificate(&$rclist, $serial, $create = false)
+ {
+ $serial = new BigInteger($serial);
+
+ foreach ($rclist as $i => $rc) {
+ if (!($serial->compare($rc['userCertificate']))) {
+ return $i;
+ }
+ }
+
+ if (!$create) {
+ return false;
+ }
+
+ $i = count($rclist);
+ $revocationDate = new DateTime('now', new DateTimeZone(@date_default_timezone_get()));
+ $rclist[] = array('userCertificate' => $serial,
+ 'revocationDate' => $this->_timeField($revocationDate->format('D, d M Y H:i:s O')));
+ return $i;
+ }
+
+ /**
+ * Revoke a certificate.
+ *
+ * @param string $serial
+ * @param string $date optional
+ * @access public
+ * @return bool
+ */
+ function revoke($serial, $date = null)
+ {
+ if (isset($this->currentCert['tbsCertList'])) {
+ if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) {
+ if ($this->_revokedCertificate($rclist, $serial) === false) { // If not yet revoked
+ if (($i = $this->_revokedCertificate($rclist, $serial, true)) !== false) {
+ if (!empty($date)) {
+ $rclist[$i]['revocationDate'] = $this->_timeField($date);
+ }
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Unrevoke a certificate.
+ *
+ * @param string $serial
+ * @access public
+ * @return bool
+ */
+ function unrevoke($serial)
+ {
+ if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) {
+ if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) {
+ unset($rclist[$i]);
+ $rclist = array_values($rclist);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get a revoked certificate.
+ *
+ * @param string $serial
+ * @access public
+ * @return mixed
+ */
+ function getRevoked($serial)
+ {
+ if (is_array($rclist = $this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) {
+ if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) {
+ return $rclist[$i];
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * List revoked certificates
+ *
+ * @param array $crl optional
+ * @access public
+ * @return array
+ */
+ function listRevoked($crl = null)
+ {
+ if (!isset($crl)) {
+ $crl = $this->currentCert;
+ }
+
+ if (!isset($crl['tbsCertList'])) {
+ return false;
+ }
+
+ $result = array();
+
+ if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) {
+ foreach ($rclist as $rc) {
+ $result[] = $rc['userCertificate']->toString();
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Remove a Revoked Certificate Extension
+ *
+ * @param string $serial
+ * @param string $id
+ * @access public
+ * @return bool
+ */
+ function removeRevokedCertificateExtension($serial, $id)
+ {
+ if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) {
+ if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) {
+ return $this->_removeExtension($id, "tbsCertList/revokedCertificates/$i/crlEntryExtensions");
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Get a Revoked Certificate Extension
+ *
+ * Returns the extension if it exists and false if not
+ *
+ * @param string $serial
+ * @param string $id
+ * @param array $crl optional
+ * @access public
+ * @return mixed
+ */
+ function getRevokedCertificateExtension($serial, $id, $crl = null)
+ {
+ if (!isset($crl)) {
+ $crl = $this->currentCert;
+ }
+
+ if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) {
+ if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) {
+ return $this->_getExtension($id, $crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions");
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a list of all extensions in use for a given revoked certificate
+ *
+ * @param string $serial
+ * @param array $crl optional
+ * @access public
+ * @return array
+ */
+ function getRevokedCertificateExtensions($serial, $crl = null)
+ {
+ if (!isset($crl)) {
+ $crl = $this->currentCert;
+ }
+
+ if (is_array($rclist = $this->_subArray($crl, 'tbsCertList/revokedCertificates'))) {
+ if (($i = $this->_revokedCertificate($rclist, $serial)) !== false) {
+ return $this->_getExtensions($crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions");
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Set a Revoked Certificate Extension
+ *
+ * @param string $serial
+ * @param string $id
+ * @param mixed $value
+ * @param bool $critical optional
+ * @param bool $replace optional
+ * @access public
+ * @return bool
+ */
+ function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true)
+ {
+ if (isset($this->currentCert['tbsCertList'])) {
+ if (is_array($rclist = &$this->_subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) {
+ if (($i = $this->_revokedCertificate($rclist, $serial, true)) !== false) {
+ return $this->_setExtension($id, $value, $critical, $replace, "tbsCertList/revokedCertificates/$i/crlEntryExtensions");
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Extract raw BER from Base64 encoding
+ *
+ * @access private
+ * @param string $str
+ * @return string
+ */
+ function _extractBER($str)
+ {
+ /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them
+ * above and beyond the ceritificate.
+ * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line:
+ *
+ * Bag Attributes
+ * localKeyID: 01 00 00 00
+ * subject=/O=organization/OU=org unit/CN=common name
+ * issuer=/O=organization/CN=common name
+ */
+ $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1);
+ // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff
+ $temp = preg_replace('#-+[^-]+-+#', '', $temp);
+ // remove new lines
+ $temp = str_replace(array("\r", "\n", ' '), '', $temp);
+ $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? base64_decode($temp) : false;
+ return $temp != false ? $temp : $str;
+ }
+
+ /**
+ * Returns the OID corresponding to a name
+ *
+ * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if
+ * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version
+ * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able
+ * to work from version to version.
+ *
+ * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that
+ * what's being passed to it already is an OID and return that instead. A few examples.
+ *
+ * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1'
+ * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1'
+ * getOID('zzz') == 'zzz'
+ *
+ * @access public
+ * @return string
+ */
+ function getOID($name)
+ {
+ static $reverseMap;
+ if (!isset($reverseMap)) {
+ $reverseMap = array_flip($this->oids);
+ }
+ return isset($reverseMap[$name]) ? $reverseMap[$name] : $name;
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
new file mode 100644
index 0000000..e7f6646
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php
@@ -0,0 +1,3787 @@
+<?php
+
+/**
+ * Pure-PHP arbitrary precision integer arithmetic library.
+ *
+ * Supports base-2, base-10, base-16, and base-256 numbers. Uses the GMP or BCMath extensions, if available,
+ * and an internal implementation, otherwise.
+ *
+ * PHP version 5
+ *
+ * {@internal (all DocBlock comments regarding implementation - such as the one that follows - refer to the
+ * {@link self::MODE_INTERNAL self::MODE_INTERNAL} mode)
+ *
+ * BigInteger uses base-2**26 to perform operations such as multiplication and division and
+ * base-2**52 (ie. two base 2**26 digits) to perform addition and subtraction. Because the largest possible
+ * value when multiplying two base-2**26 numbers together is a base-2**52 number, double precision floating
+ * point numbers - numbers that should be supported on most hardware and whose significand is 53 bits - are
+ * used. As a consequence, bitwise operators such as >> and << cannot be used, nor can the modulo operator %,
+ * which only supports integers. Although this fact will slow this library down, the fact that such a high
+ * base is being used should more than compensate.
+ *
+ * Numbers are stored in {@link http://en.wikipedia.org/wiki/Endianness little endian} format. ie.
+ * (new \phpseclib\Math\BigInteger(pow(2, 26)))->value = array(0, 1)
+ *
+ * Useful resources are as follows:
+ *
+ * - {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf Handbook of Applied Cryptography (HAC)}
+ * - {@link http://math.libtomcrypt.com/files/tommath.pdf Multi-Precision Math (MPM)}
+ * - Java's BigInteger classes. See /j2se/src/share/classes/java/math in jdk-1_5_0-src-jrl.zip
+ *
+ * Here's an example of how to use this library:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger(2);
+ * $b = new \phpseclib\Math\BigInteger(3);
+ *
+ * $c = $a->add($b);
+ *
+ * echo $c->toString(); // outputs 5
+ * ?>
+ * </code>
+ *
+ * @category Math
+ * @package BigInteger
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2006 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ */
+
+namespace phpseclib\Math;
+
+use phpseclib\Crypt\Random;
+
+/**
+ * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256
+ * numbers.
+ *
+ * @package BigInteger
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class BigInteger
+{
+ /**#@+
+ * Reduction constants
+ *
+ * @access private
+ * @see BigInteger::_reduce()
+ */
+ /**
+ * @see BigInteger::_montgomery()
+ * @see BigInteger::_prepMontgomery()
+ */
+ const MONTGOMERY = 0;
+ /**
+ * @see BigInteger::_barrett()
+ */
+ const BARRETT = 1;
+ /**
+ * @see BigInteger::_mod2()
+ */
+ const POWEROF2 = 2;
+ /**
+ * @see BigInteger::_remainder()
+ */
+ const CLASSIC = 3;
+ /**
+ * @see BigInteger::__clone()
+ */
+ const NONE = 4;
+ /**#@-*/
+
+ /**#@+
+ * Array constants
+ *
+ * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and
+ * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them.
+ *
+ * @access private
+ */
+ /**
+ * $result[self::VALUE] contains the value.
+ */
+ const VALUE = 0;
+ /**
+ * $result[self::SIGN] contains the sign.
+ */
+ const SIGN = 1;
+ /**#@-*/
+
+ /**#@+
+ * @access private
+ * @see BigInteger::_montgomery()
+ * @see BigInteger::_barrett()
+ */
+ /**
+ * Cache constants
+ *
+ * $cache[self::VARIABLE] tells us whether or not the cached data is still valid.
+ */
+ const VARIABLE = 0;
+ /**
+ * $cache[self::DATA] contains the cached data.
+ */
+ const DATA = 1;
+ /**#@-*/
+
+ /**#@+
+ * Mode constants.
+ *
+ * @access private
+ * @see BigInteger::__construct()
+ */
+ /**
+ * To use the pure-PHP implementation
+ */
+ const MODE_INTERNAL = 1;
+ /**
+ * To use the BCMath library
+ *
+ * (if enabled; otherwise, the internal implementation will be used)
+ */
+ const MODE_BCMATH = 2;
+ /**
+ * To use the GMP library
+ *
+ * (if present; otherwise, either the BCMath or the internal implementation will be used)
+ */
+ const MODE_GMP = 3;
+ /**#@-*/
+
+ /**
+ * Karatsuba Cutoff
+ *
+ * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication?
+ *
+ * @access private
+ */
+ const KARATSUBA_CUTOFF = 25;
+
+ /**#@+
+ * Static properties used by the pure-PHP implementation.
+ *
+ * @see __construct()
+ */
+ protected static $base;
+ protected static $baseFull;
+ protected static $maxDigit;
+ protected static $msb;
+
+ /**
+ * $max10 in greatest $max10Len satisfying
+ * $max10 = 10**$max10Len <= 2**$base.
+ */
+ protected static $max10;
+
+ /**
+ * $max10Len in greatest $max10Len satisfying
+ * $max10 = 10**$max10Len <= 2**$base.
+ */
+ protected static $max10Len;
+ protected static $maxDigit2;
+ /**#@-*/
+
+ /**
+ * Holds the BigInteger's value.
+ *
+ * @var array
+ * @access private
+ */
+ var $value;
+
+ /**
+ * Holds the BigInteger's magnitude.
+ *
+ * @var bool
+ * @access private
+ */
+ var $is_negative = false;
+
+ /**
+ * Precision
+ *
+ * @see self::setPrecision()
+ * @access private
+ */
+ var $precision = -1;
+
+ /**
+ * Precision Bitmask
+ *
+ * @see self::setPrecision()
+ * @access private
+ */
+ var $bitmask = false;
+
+ /**
+ * Mode independent value used for serialization.
+ *
+ * If the bcmath or gmp extensions are installed $this->value will be a non-serializable resource, hence the need for
+ * a variable that'll be serializable regardless of whether or not extensions are being used. Unlike $this->value,
+ * however, $this->hex is only calculated when $this->__sleep() is called.
+ *
+ * @see self::__sleep()
+ * @see self::__wakeup()
+ * @var string
+ * @access private
+ */
+ var $hex;
+
+ /**
+ * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers.
+ *
+ * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using
+ * two's compliment. The sole exception to this is -10, which is treated the same as 10 is.
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger('0x32', 16); // 50 in base-16
+ *
+ * echo $a->toString(); // outputs 50
+ * ?>
+ * </code>
+ *
+ * @param $x base-10 number or base-$base number if $base set.
+ * @param int $base
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ */
+ function __construct($x = 0, $base = 10)
+ {
+ if (!defined('MATH_BIGINTEGER_MODE')) {
+ switch (true) {
+ case extension_loaded('gmp'):
+ define('MATH_BIGINTEGER_MODE', self::MODE_GMP);
+ break;
+ case extension_loaded('bcmath'):
+ define('MATH_BIGINTEGER_MODE', self::MODE_BCMATH);
+ break;
+ default:
+ define('MATH_BIGINTEGER_MODE', self::MODE_INTERNAL);
+ }
+ }
+
+ if (extension_loaded('openssl') && !defined('MATH_BIGINTEGER_OPENSSL_DISABLE') && !defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
+ // some versions of XAMPP have mismatched versions of OpenSSL which causes it not to work
+ $versions = array();
+
+ // avoid generating errors (even with suppression) when phpinfo() is disabled (common in production systems)
+ if (strpos(ini_get('disable_functions'), 'phpinfo') === false) {
+ ob_start();
+ @phpinfo();
+ $content = ob_get_contents();
+ ob_end_clean();
+
+ preg_match_all('#OpenSSL (Header|Library) Version(.*)#im', $content, $matches);
+
+ if (!empty($matches[1])) {
+ for ($i = 0; $i < count($matches[1]); $i++) {
+ $fullVersion = trim(str_replace('=>', '', strip_tags($matches[2][$i])));
+
+ // Remove letter part in OpenSSL version
+ if (!preg_match('/(\d+\.\d+\.\d+)/i', $fullVersion, $m)) {
+ $versions[$matches[1][$i]] = $fullVersion;
+ } else {
+ $versions[$matches[1][$i]] = $m[0];
+ }
+ }
+ }
+ }
+
+ // it doesn't appear that OpenSSL versions were reported upon until PHP 5.3+
+ switch (true) {
+ case !isset($versions['Header']):
+ case !isset($versions['Library']):
+ case $versions['Header'] == $versions['Library']:
+ case version_compare($versions['Header'], '1.0.0') >= 0 && version_compare($versions['Library'], '1.0.0') >= 0:
+ define('MATH_BIGINTEGER_OPENSSL_ENABLED', true);
+ break;
+ default:
+ define('MATH_BIGINTEGER_OPENSSL_DISABLE', true);
+ }
+ }
+
+ if (!defined('PHP_INT_SIZE')) {
+ define('PHP_INT_SIZE', 4);
+ }
+
+ if (empty(self::$base) && MATH_BIGINTEGER_MODE == self::MODE_INTERNAL) {
+ switch (PHP_INT_SIZE) {
+ case 8: // use 64-bit integers if int size is 8 bytes
+ self::$base = 31;
+ self::$baseFull = 0x80000000;
+ self::$maxDigit = 0x7FFFFFFF;
+ self::$msb = 0x40000000;
+ self::$max10 = 1000000000;
+ self::$max10Len = 9;
+ self::$maxDigit2 = pow(2, 62);
+ break;
+ //case 4: // use 64-bit floats if int size is 4 bytes
+ default:
+ self::$base = 26;
+ self::$baseFull = 0x4000000;
+ self::$maxDigit = 0x3FFFFFF;
+ self::$msb = 0x2000000;
+ self::$max10 = 10000000;
+ self::$max10Len = 7;
+ self::$maxDigit2 = pow(2, 52); // pow() prevents truncation
+ }
+ }
+
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ switch (true) {
+ case is_resource($x) && get_resource_type($x) == 'GMP integer':
+ // PHP 5.6 switched GMP from using resources to objects
+ case $x instanceof \GMP:
+ $this->value = $x;
+ return;
+ }
+ $this->value = gmp_init(0);
+ break;
+ case self::MODE_BCMATH:
+ $this->value = '0';
+ break;
+ default:
+ $this->value = array();
+ }
+
+ // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48
+ // '0' is the only value like this per http://php.net/empty
+ if (empty($x) && (abs($base) != 256 || $x !== '0')) {
+ return;
+ }
+
+ switch ($base) {
+ case -256:
+ if (ord($x[0]) & 0x80) {
+ $x = ~$x;
+ $this->is_negative = true;
+ }
+ case 256:
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $this->value = function_exists('gmp_import') ?
+ gmp_import($x) :
+ gmp_init('0x' . bin2hex($x));
+ if ($this->is_negative) {
+ $this->value = gmp_neg($this->value);
+ }
+ break;
+ case self::MODE_BCMATH:
+ // round $len to the nearest 4 (thanks, DavidMJ!)
+ $len = (strlen($x) + 3) & 0xFFFFFFFC;
+
+ $x = str_pad($x, $len, chr(0), STR_PAD_LEFT);
+
+ for ($i = 0; $i < $len; $i+= 4) {
+ $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32
+ $this->value = bcadd($this->value, 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord($x[$i + 2]) << 8) | ord($x[$i + 3])), 0);
+ }
+
+ if ($this->is_negative) {
+ $this->value = '-' . $this->value;
+ }
+
+ break;
+ // converts a base-2**8 (big endian / msb) number to base-2**26 (little endian / lsb)
+ default:
+ while (strlen($x)) {
+ $this->value[] = $this->_bytes2int($this->_base256_rshift($x, self::$base));
+ }
+ }
+
+ if ($this->is_negative) {
+ if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
+ $this->is_negative = false;
+ }
+ $temp = $this->add(new static('-1'));
+ $this->value = $temp->value;
+ }
+ break;
+ case 16:
+ case -16:
+ if ($base > 0 && $x[0] == '-') {
+ $this->is_negative = true;
+ $x = substr($x, 1);
+ }
+
+ $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#', '$1', $x);
+
+ $is_negative = false;
+ if ($base < 0 && hexdec($x[0]) >= 8) {
+ $this->is_negative = $is_negative = true;
+ $x = bin2hex(~pack('H*', $x));
+ }
+
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $temp = $this->is_negative ? '-0x' . $x : '0x' . $x;
+ $this->value = gmp_init($temp);
+ $this->is_negative = false;
+ break;
+ case self::MODE_BCMATH:
+ $x = (strlen($x) & 1) ? '0' . $x : $x;
+ $temp = new static(pack('H*', $x), 256);
+ $this->value = $this->is_negative ? '-' . $temp->value : $temp->value;
+ $this->is_negative = false;
+ break;
+ default:
+ $x = (strlen($x) & 1) ? '0' . $x : $x;
+ $temp = new static(pack('H*', $x), 256);
+ $this->value = $temp->value;
+ }
+
+ if ($is_negative) {
+ $temp = $this->add(new static('-1'));
+ $this->value = $temp->value;
+ }
+ break;
+ case 10:
+ case -10:
+ // (?<!^)(?:-).*: find any -'s that aren't at the beginning and then any characters that follow that
+ // (?<=^|-)0*: find any 0's that are preceded by the start of the string or by a - (ie. octals)
+ // [^-0-9].*: find any non-numeric characters and then any characters that follow that
+ $x = preg_replace('#(?<!^)(?:-).*|(?<=^|-)0*|[^-0-9].*#', '', $x);
+ if (!strlen($x) || $x == '-') {
+ $x = '0';
+ }
+
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $this->value = gmp_init($x);
+ break;
+ case self::MODE_BCMATH:
+ // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different
+ // results then doing it on '-1' does (modInverse does $x[0])
+ $this->value = $x === '-' ? '0' : (string) $x;
+ break;
+ default:
+ $temp = new static();
+
+ $multiplier = new static();
+ $multiplier->value = array(self::$max10);
+
+ if ($x[0] == '-') {
+ $this->is_negative = true;
+ $x = substr($x, 1);
+ }
+
+ $x = str_pad($x, strlen($x) + ((self::$max10Len - 1) * strlen($x)) % self::$max10Len, 0, STR_PAD_LEFT);
+ while (strlen($x)) {
+ $temp = $temp->multiply($multiplier);
+ $temp = $temp->add(new static($this->_int2bytes(substr($x, 0, self::$max10Len)), 256));
+ $x = substr($x, self::$max10Len);
+ }
+
+ $this->value = $temp->value;
+ }
+ break;
+ case 2: // base-2 support originally implemented by Lluis Pamies - thanks!
+ case -2:
+ if ($base > 0 && $x[0] == '-') {
+ $this->is_negative = true;
+ $x = substr($x, 1);
+ }
+
+ $x = preg_replace('#^([01]*).*#', '$1', $x);
+ $x = str_pad($x, strlen($x) + (3 * strlen($x)) % 4, 0, STR_PAD_LEFT);
+
+ $str = '0x';
+ while (strlen($x)) {
+ $part = substr($x, 0, 4);
+ $str.= dechex(bindec($part));
+ $x = substr($x, 4);
+ }
+
+ if ($this->is_negative) {
+ $str = '-' . $str;
+ }
+
+ $temp = new static($str, 8 * $base); // ie. either -16 or +16
+ $this->value = $temp->value;
+ $this->is_negative = $temp->is_negative;
+
+ break;
+ default:
+ // base not supported, so we'll let $this == 0
+ }
+ }
+
+ /**
+ * Converts a BigInteger to a byte string (eg. base-256).
+ *
+ * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
+ * saved as two's compliment.
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger('65');
+ *
+ * echo $a->toBytes(); // outputs chr(65)
+ * ?>
+ * </code>
+ *
+ * @param bool $twos_compliment
+ * @return string
+ * @access public
+ * @internal Converts a base-2**26 number to base-2**8
+ */
+ function toBytes($twos_compliment = false)
+ {
+ if ($twos_compliment) {
+ $comparison = $this->compare(new static());
+ if ($comparison == 0) {
+ return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
+ }
+
+ $temp = $comparison < 0 ? $this->add(new static(1)) : $this->copy();
+ $bytes = $temp->toBytes();
+
+ if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1
+ $bytes = chr(0);
+ }
+
+ if ($this->precision <= 0 && (ord($bytes[0]) & 0x80)) {
+ $bytes = chr(0) . $bytes;
+ }
+
+ return $comparison < 0 ? ~$bytes : $bytes;
+ }
+
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ if (gmp_cmp($this->value, gmp_init(0)) == 0) {
+ return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
+ }
+
+ if (function_exists('gmp_export')) {
+ $temp = gmp_export($this->value);
+ } else {
+ $temp = gmp_strval(gmp_abs($this->value), 16);
+ $temp = (strlen($temp) & 1) ? '0' . $temp : $temp;
+ $temp = pack('H*', $temp);
+ }
+
+ return $this->precision > 0 ?
+ substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
+ ltrim($temp, chr(0));
+ case self::MODE_BCMATH:
+ if ($this->value === '0') {
+ return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
+ }
+
+ $value = '';
+ $current = $this->value;
+
+ if ($current[0] == '-') {
+ $current = substr($current, 1);
+ }
+
+ while (bccomp($current, '0', 0) > 0) {
+ $temp = bcmod($current, '16777216');
+ $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value;
+ $current = bcdiv($current, '16777216', 0);
+ }
+
+ return $this->precision > 0 ?
+ substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) :
+ ltrim($value, chr(0));
+ }
+
+ if (!count($this->value)) {
+ return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : '';
+ }
+ $result = $this->_int2bytes($this->value[count($this->value) - 1]);
+
+ $temp = $this->copy();
+
+ for ($i = count($temp->value) - 2; $i >= 0; --$i) {
+ $temp->_base256_lshift($result, self::$base);
+ $result = $result | str_pad($temp->_int2bytes($temp->value[$i]), strlen($result), chr(0), STR_PAD_LEFT);
+ }
+
+ return $this->precision > 0 ?
+ str_pad(substr($result, -(($this->precision + 7) >> 3)), ($this->precision + 7) >> 3, chr(0), STR_PAD_LEFT) :
+ $result;
+ }
+
+ /**
+ * Converts a BigInteger to a hex string (eg. base-16)).
+ *
+ * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
+ * saved as two's compliment.
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger('65');
+ *
+ * echo $a->toHex(); // outputs '41'
+ * ?>
+ * </code>
+ *
+ * @param bool $twos_compliment
+ * @return string
+ * @access public
+ * @internal Converts a base-2**26 number to base-2**8
+ */
+ function toHex($twos_compliment = false)
+ {
+ return bin2hex($this->toBytes($twos_compliment));
+ }
+
+ /**
+ * Converts a BigInteger to a bit string (eg. base-2).
+ *
+ * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're
+ * saved as two's compliment.
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger('65');
+ *
+ * echo $a->toBits(); // outputs '1000001'
+ * ?>
+ * </code>
+ *
+ * @param bool $twos_compliment
+ * @return string
+ * @access public
+ * @internal Converts a base-2**26 number to base-2**2
+ */
+ function toBits($twos_compliment = false)
+ {
+ $hex = $this->toHex($twos_compliment);
+ $bits = '';
+ for ($i = strlen($hex) - 8, $start = strlen($hex) & 7; $i >= $start; $i-=8) {
+ $bits = str_pad(decbin(hexdec(substr($hex, $i, 8))), 32, '0', STR_PAD_LEFT) . $bits;
+ }
+ if ($start) { // hexdec('') == 0
+ $bits = str_pad(decbin(hexdec(substr($hex, 0, $start))), 8, '0', STR_PAD_LEFT) . $bits;
+ }
+ $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0');
+
+ if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) {
+ return '0' . $result;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Converts a BigInteger to a base-10 number.
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger('50');
+ *
+ * echo $a->toString(); // outputs 50
+ * ?>
+ * </code>
+ *
+ * @return string
+ * @access public
+ * @internal Converts a base-2**26 number to base-10**7 (which is pretty much base-10)
+ */
+ function toString()
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ return gmp_strval($this->value);
+ case self::MODE_BCMATH:
+ if ($this->value === '0') {
+ return '0';
+ }
+
+ return ltrim($this->value, '0');
+ }
+
+ if (!count($this->value)) {
+ return '0';
+ }
+
+ $temp = $this->copy();
+ $temp->bitmask = false;
+ $temp->is_negative = false;
+
+ $divisor = new static();
+ $divisor->value = array(self::$max10);
+ $result = '';
+ while (count($temp->value)) {
+ list($temp, $mod) = $temp->divide($divisor);
+ $result = str_pad(isset($mod->value[0]) ? $mod->value[0] : '', self::$max10Len, '0', STR_PAD_LEFT) . $result;
+ }
+ $result = ltrim($result, '0');
+ if (empty($result)) {
+ $result = '0';
+ }
+
+ if ($this->is_negative) {
+ $result = '-' . $result;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Copy an object
+ *
+ * PHP5 passes objects by reference while PHP4 passes by value. As such, we need a function to guarantee
+ * that all objects are passed by value, when appropriate. More information can be found here:
+ *
+ * {@link http://php.net/language.oop5.basic#51624}
+ *
+ * @access public
+ * @see self::__clone()
+ * @return \phpseclib\Math\BigInteger
+ */
+ function copy()
+ {
+ $temp = new static();
+ $temp->value = $this->value;
+ $temp->is_negative = $this->is_negative;
+ $temp->precision = $this->precision;
+ $temp->bitmask = $this->bitmask;
+ return $temp;
+ }
+
+ /**
+ * __toString() magic method
+ *
+ * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call
+ * toString().
+ *
+ * @access public
+ * @internal Implemented per a suggestion by Techie-Michael - thanks!
+ */
+ function __toString()
+ {
+ return $this->toString();
+ }
+
+ /**
+ * __clone() magic method
+ *
+ * Although you can call BigInteger::__toString() directly in PHP5, you cannot call BigInteger::__clone() directly
+ * in PHP5. You can in PHP4 since it's not a magic method, but in PHP5, you have to call it by using the PHP5
+ * only syntax of $y = clone $x. As such, if you're trying to write an application that works on both PHP4 and
+ * PHP5, call BigInteger::copy(), instead.
+ *
+ * @access public
+ * @see self::copy()
+ * @return \phpseclib\Math\BigInteger
+ */
+ function __clone()
+ {
+ return $this->copy();
+ }
+
+ /**
+ * __sleep() magic method
+ *
+ * Will be called, automatically, when serialize() is called on a BigInteger object.
+ *
+ * @see self::__wakeup()
+ * @access public
+ */
+ function __sleep()
+ {
+ $this->hex = $this->toHex(true);
+ $vars = array('hex');
+ if ($this->precision > 0) {
+ $vars[] = 'precision';
+ }
+ return $vars;
+ }
+
+ /**
+ * __wakeup() magic method
+ *
+ * Will be called, automatically, when unserialize() is called on a BigInteger object.
+ *
+ * @see self::__sleep()
+ * @access public
+ */
+ function __wakeup()
+ {
+ $temp = new static($this->hex, -16);
+ $this->value = $temp->value;
+ $this->is_negative = $temp->is_negative;
+ if ($this->precision > 0) {
+ // recalculate $this->bitmask
+ $this->setPrecision($this->precision);
+ }
+ }
+
+ /**
+ * __debugInfo() magic method
+ *
+ * Will be called, automatically, when print_r() or var_dump() are called
+ *
+ * @access public
+ */
+ function __debugInfo()
+ {
+ $opts = array();
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $engine = 'gmp';
+ break;
+ case self::MODE_BCMATH:
+ $engine = 'bcmath';
+ break;
+ case self::MODE_INTERNAL:
+ $engine = 'internal';
+ $opts[] = PHP_INT_SIZE == 8 ? '64-bit' : '32-bit';
+ }
+ if (MATH_BIGINTEGER_MODE != self::MODE_GMP && defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
+ $opts[] = 'OpenSSL';
+ }
+ if (!empty($opts)) {
+ $engine.= ' (' . implode('.', $opts) . ')';
+ }
+ return array(
+ 'value' => '0x' . $this->toHex(true),
+ 'engine' => $engine
+ );
+ }
+
+ /**
+ * Adds two BigIntegers.
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger('10');
+ * $b = new \phpseclib\Math\BigInteger('20');
+ *
+ * $c = $a->add($b);
+ *
+ * echo $c->toString(); // outputs 30
+ * ?>
+ * </code>
+ *
+ * @param \phpseclib\Math\BigInteger $y
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ * @internal Performs base-2**52 addition
+ */
+ function add($y)
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $temp = new static();
+ $temp->value = gmp_add($this->value, $y->value);
+
+ return $this->_normalize($temp);
+ case self::MODE_BCMATH:
+ $temp = new static();
+ $temp->value = bcadd($this->value, $y->value, 0);
+
+ return $this->_normalize($temp);
+ }
+
+ $temp = $this->_add($this->value, $this->is_negative, $y->value, $y->is_negative);
+
+ $result = new static();
+ $result->value = $temp[self::VALUE];
+ $result->is_negative = $temp[self::SIGN];
+
+ return $this->_normalize($result);
+ }
+
+ /**
+ * Performs addition.
+ *
+ * @param array $x_value
+ * @param bool $x_negative
+ * @param array $y_value
+ * @param bool $y_negative
+ * @return array
+ * @access private
+ */
+ function _add($x_value, $x_negative, $y_value, $y_negative)
+ {
+ $x_size = count($x_value);
+ $y_size = count($y_value);
+
+ if ($x_size == 0) {
+ return array(
+ self::VALUE => $y_value,
+ self::SIGN => $y_negative
+ );
+ } elseif ($y_size == 0) {
+ return array(
+ self::VALUE => $x_value,
+ self::SIGN => $x_negative
+ );
+ }
+
+ // subtract, if appropriate
+ if ($x_negative != $y_negative) {
+ if ($x_value == $y_value) {
+ return array(
+ self::VALUE => array(),
+ self::SIGN => false
+ );
+ }
+
+ $temp = $this->_subtract($x_value, false, $y_value, false);
+ $temp[self::SIGN] = $this->_compare($x_value, false, $y_value, false) > 0 ?
+ $x_negative : $y_negative;
+
+ return $temp;
+ }
+
+ if ($x_size < $y_size) {
+ $size = $x_size;
+ $value = $y_value;
+ } else {
+ $size = $y_size;
+ $value = $x_value;
+ }
+
+ $value[count($value)] = 0; // just in case the carry adds an extra digit
+
+ $carry = 0;
+ for ($i = 0, $j = 1; $j < $size; $i+=2, $j+=2) {
+ $sum = $x_value[$j] * self::$baseFull + $x_value[$i] + $y_value[$j] * self::$baseFull + $y_value[$i] + $carry;
+ $carry = $sum >= self::$maxDigit2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
+ $sum = $carry ? $sum - self::$maxDigit2 : $sum;
+
+ $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31);
+
+ $value[$i] = (int) ($sum - self::$baseFull * $temp); // eg. a faster alternative to fmod($sum, 0x4000000)
+ $value[$j] = $temp;
+ }
+
+ if ($j == $size) { // ie. if $y_size is odd
+ $sum = $x_value[$i] + $y_value[$i] + $carry;
+ $carry = $sum >= self::$baseFull;
+ $value[$i] = $carry ? $sum - self::$baseFull : $sum;
+ ++$i; // ie. let $i = $j since we've just done $value[$i]
+ }
+
+ if ($carry) {
+ for (; $value[$i] == self::$maxDigit; ++$i) {
+ $value[$i] = 0;
+ }
+ ++$value[$i];
+ }
+
+ return array(
+ self::VALUE => $this->_trim($value),
+ self::SIGN => $x_negative
+ );
+ }
+
+ /**
+ * Subtracts two BigIntegers.
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger('10');
+ * $b = new \phpseclib\Math\BigInteger('20');
+ *
+ * $c = $a->subtract($b);
+ *
+ * echo $c->toString(); // outputs -10
+ * ?>
+ * </code>
+ *
+ * @param \phpseclib\Math\BigInteger $y
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ * @internal Performs base-2**52 subtraction
+ */
+ function subtract($y)
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $temp = new static();
+ $temp->value = gmp_sub($this->value, $y->value);
+
+ return $this->_normalize($temp);
+ case self::MODE_BCMATH:
+ $temp = new static();
+ $temp->value = bcsub($this->value, $y->value, 0);
+
+ return $this->_normalize($temp);
+ }
+
+ $temp = $this->_subtract($this->value, $this->is_negative, $y->value, $y->is_negative);
+
+ $result = new static();
+ $result->value = $temp[self::VALUE];
+ $result->is_negative = $temp[self::SIGN];
+
+ return $this->_normalize($result);
+ }
+
+ /**
+ * Performs subtraction.
+ *
+ * @param array $x_value
+ * @param bool $x_negative
+ * @param array $y_value
+ * @param bool $y_negative
+ * @return array
+ * @access private
+ */
+ function _subtract($x_value, $x_negative, $y_value, $y_negative)
+ {
+ $x_size = count($x_value);
+ $y_size = count($y_value);
+
+ if ($x_size == 0) {
+ return array(
+ self::VALUE => $y_value,
+ self::SIGN => !$y_negative
+ );
+ } elseif ($y_size == 0) {
+ return array(
+ self::VALUE => $x_value,
+ self::SIGN => $x_negative
+ );
+ }
+
+ // add, if appropriate (ie. -$x - +$y or +$x - -$y)
+ if ($x_negative != $y_negative) {
+ $temp = $this->_add($x_value, false, $y_value, false);
+ $temp[self::SIGN] = $x_negative;
+
+ return $temp;
+ }
+
+ $diff = $this->_compare($x_value, $x_negative, $y_value, $y_negative);
+
+ if (!$diff) {
+ return array(
+ self::VALUE => array(),
+ self::SIGN => false
+ );
+ }
+
+ // switch $x and $y around, if appropriate.
+ if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) {
+ $temp = $x_value;
+ $x_value = $y_value;
+ $y_value = $temp;
+
+ $x_negative = !$x_negative;
+
+ $x_size = count($x_value);
+ $y_size = count($y_value);
+ }
+
+ // at this point, $x_value should be at least as big as - if not bigger than - $y_value
+
+ $carry = 0;
+ for ($i = 0, $j = 1; $j < $y_size; $i+=2, $j+=2) {
+ $sum = $x_value[$j] * self::$baseFull + $x_value[$i] - $y_value[$j] * self::$baseFull - $y_value[$i] - $carry;
+ $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1
+ $sum = $carry ? $sum + self::$maxDigit2 : $sum;
+
+ $temp = self::$base === 26 ? intval($sum / 0x4000000) : ($sum >> 31);
+
+ $x_value[$i] = (int) ($sum - self::$baseFull * $temp);
+ $x_value[$j] = $temp;
+ }
+
+ if ($j == $y_size) { // ie. if $y_size is odd
+ $sum = $x_value[$i] - $y_value[$i] - $carry;
+ $carry = $sum < 0;
+ $x_value[$i] = $carry ? $sum + self::$baseFull : $sum;
+ ++$i;
+ }
+
+ if ($carry) {
+ for (; !$x_value[$i]; ++$i) {
+ $x_value[$i] = self::$maxDigit;
+ }
+ --$x_value[$i];
+ }
+
+ return array(
+ self::VALUE => $this->_trim($x_value),
+ self::SIGN => $x_negative
+ );
+ }
+
+ /**
+ * Multiplies two BigIntegers
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger('10');
+ * $b = new \phpseclib\Math\BigInteger('20');
+ *
+ * $c = $a->multiply($b);
+ *
+ * echo $c->toString(); // outputs 200
+ * ?>
+ * </code>
+ *
+ * @param \phpseclib\Math\BigInteger $x
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ */
+ function multiply($x)
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $temp = new static();
+ $temp->value = gmp_mul($this->value, $x->value);
+
+ return $this->_normalize($temp);
+ case self::MODE_BCMATH:
+ $temp = new static();
+ $temp->value = bcmul($this->value, $x->value, 0);
+
+ return $this->_normalize($temp);
+ }
+
+ $temp = $this->_multiply($this->value, $this->is_negative, $x->value, $x->is_negative);
+
+ $product = new static();
+ $product->value = $temp[self::VALUE];
+ $product->is_negative = $temp[self::SIGN];
+
+ return $this->_normalize($product);
+ }
+
+ /**
+ * Performs multiplication.
+ *
+ * @param array $x_value
+ * @param bool $x_negative
+ * @param array $y_value
+ * @param bool $y_negative
+ * @return array
+ * @access private
+ */
+ function _multiply($x_value, $x_negative, $y_value, $y_negative)
+ {
+ //if ( $x_value == $y_value ) {
+ // return array(
+ // self::VALUE => $this->_square($x_value),
+ // self::SIGN => $x_sign != $y_value
+ // );
+ //}
+
+ $x_length = count($x_value);
+ $y_length = count($y_value);
+
+ if (!$x_length || !$y_length) { // a 0 is being multiplied
+ return array(
+ self::VALUE => array(),
+ self::SIGN => false
+ );
+ }
+
+ return array(
+ self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ?
+ $this->_trim($this->_regularMultiply($x_value, $y_value)) :
+ $this->_trim($this->_karatsuba($x_value, $y_value)),
+ self::SIGN => $x_negative != $y_negative
+ );
+ }
+
+ /**
+ * Performs long multiplication on two BigIntegers
+ *
+ * Modeled after 'multiply' in MutableBigInteger.java.
+ *
+ * @param array $x_value
+ * @param array $y_value
+ * @return array
+ * @access private
+ */
+ function _regularMultiply($x_value, $y_value)
+ {
+ $x_length = count($x_value);
+ $y_length = count($y_value);
+
+ if (!$x_length || !$y_length) { // a 0 is being multiplied
+ return array();
+ }
+
+ if ($x_length < $y_length) {
+ $temp = $x_value;
+ $x_value = $y_value;
+ $y_value = $temp;
+
+ $x_length = count($x_value);
+ $y_length = count($y_value);
+ }
+
+ $product_value = $this->_array_repeat(0, $x_length + $y_length);
+
+ // the following for loop could be removed if the for loop following it
+ // (the one with nested for loops) initially set $i to 0, but
+ // doing so would also make the result in one set of unnecessary adds,
+ // since on the outermost loops first pass, $product->value[$k] is going
+ // to always be 0
+
+ $carry = 0;
+
+ for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0
+ $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
+ $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+ $product_value[$j] = (int) ($temp - self::$baseFull * $carry);
+ }
+
+ $product_value[$j] = $carry;
+
+ // the above for loop is what the previous comment was talking about. the
+ // following for loop is the "one with nested for loops"
+ for ($i = 1; $i < $y_length; ++$i) {
+ $carry = 0;
+
+ for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) {
+ $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
+ $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+ $product_value[$k] = (int) ($temp - self::$baseFull * $carry);
+ }
+
+ $product_value[$k] = $carry;
+ }
+
+ return $product_value;
+ }
+
+ /**
+ * Performs Karatsuba multiplication on two BigIntegers
+ *
+ * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
+ * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}.
+ *
+ * @param array $x_value
+ * @param array $y_value
+ * @return array
+ * @access private
+ */
+ function _karatsuba($x_value, $y_value)
+ {
+ $m = min(count($x_value) >> 1, count($y_value) >> 1);
+
+ if ($m < self::KARATSUBA_CUTOFF) {
+ return $this->_regularMultiply($x_value, $y_value);
+ }
+
+ $x1 = array_slice($x_value, $m);
+ $x0 = array_slice($x_value, 0, $m);
+ $y1 = array_slice($y_value, $m);
+ $y0 = array_slice($y_value, 0, $m);
+
+ $z2 = $this->_karatsuba($x1, $y1);
+ $z0 = $this->_karatsuba($x0, $y0);
+
+ $z1 = $this->_add($x1, false, $x0, false);
+ $temp = $this->_add($y1, false, $y0, false);
+ $z1 = $this->_karatsuba($z1[self::VALUE], $temp[self::VALUE]);
+ $temp = $this->_add($z2, false, $z0, false);
+ $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false);
+
+ $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
+ $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]);
+
+ $xy = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]);
+ $xy = $this->_add($xy[self::VALUE], $xy[self::SIGN], $z0, false);
+
+ return $xy[self::VALUE];
+ }
+
+ /**
+ * Performs squaring
+ *
+ * @param array $x
+ * @return array
+ * @access private
+ */
+ function _square($x = false)
+ {
+ return count($x) < 2 * self::KARATSUBA_CUTOFF ?
+ $this->_trim($this->_baseSquare($x)) :
+ $this->_trim($this->_karatsubaSquare($x));
+ }
+
+ /**
+ * Performs traditional squaring on two BigIntegers
+ *
+ * Squaring can be done faster than multiplying a number by itself can be. See
+ * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} /
+ * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information.
+ *
+ * @param array $value
+ * @return array
+ * @access private
+ */
+ function _baseSquare($value)
+ {
+ if (empty($value)) {
+ return array();
+ }
+ $square_value = $this->_array_repeat(0, 2 * count($value));
+
+ for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) {
+ $i2 = $i << 1;
+
+ $temp = $square_value[$i2] + $value[$i] * $value[$i];
+ $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+ $square_value[$i2] = (int) ($temp - self::$baseFull * $carry);
+
+ // note how we start from $i+1 instead of 0 as we do in multiplication.
+ for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) {
+ $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry;
+ $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+ $square_value[$k] = (int) ($temp - self::$baseFull * $carry);
+ }
+
+ // the following line can yield values larger 2**15. at this point, PHP should switch
+ // over to floats.
+ $square_value[$i + $max_index + 1] = $carry;
+ }
+
+ return $square_value;
+ }
+
+ /**
+ * Performs Karatsuba "squaring" on two BigIntegers
+ *
+ * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and
+ * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}.
+ *
+ * @param array $value
+ * @return array
+ * @access private
+ */
+ function _karatsubaSquare($value)
+ {
+ $m = count($value) >> 1;
+
+ if ($m < self::KARATSUBA_CUTOFF) {
+ return $this->_baseSquare($value);
+ }
+
+ $x1 = array_slice($value, $m);
+ $x0 = array_slice($value, 0, $m);
+
+ $z2 = $this->_karatsubaSquare($x1);
+ $z0 = $this->_karatsubaSquare($x0);
+
+ $z1 = $this->_add($x1, false, $x0, false);
+ $z1 = $this->_karatsubaSquare($z1[self::VALUE]);
+ $temp = $this->_add($z2, false, $z0, false);
+ $z1 = $this->_subtract($z1, false, $temp[self::VALUE], false);
+
+ $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2);
+ $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]);
+
+ $xx = $this->_add($z2, false, $z1[self::VALUE], $z1[self::SIGN]);
+ $xx = $this->_add($xx[self::VALUE], $xx[self::SIGN], $z0, false);
+
+ return $xx[self::VALUE];
+ }
+
+ /**
+ * Divides two BigIntegers.
+ *
+ * Returns an array whose first element contains the quotient and whose second element contains the
+ * "common residue". If the remainder would be positive, the "common residue" and the remainder are the
+ * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder
+ * and the divisor (basically, the "common residue" is the first positive modulo).
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger('10');
+ * $b = new \phpseclib\Math\BigInteger('20');
+ *
+ * list($quotient, $remainder) = $a->divide($b);
+ *
+ * echo $quotient->toString(); // outputs 0
+ * echo "\r\n";
+ * echo $remainder->toString(); // outputs 10
+ * ?>
+ * </code>
+ *
+ * @param \phpseclib\Math\BigInteger $y
+ * @return array
+ * @access public
+ * @internal This function is based off of {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}.
+ */
+ function divide($y)
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $quotient = new static();
+ $remainder = new static();
+
+ list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value);
+
+ if (gmp_sign($remainder->value) < 0) {
+ $remainder->value = gmp_add($remainder->value, gmp_abs($y->value));
+ }
+
+ return array($this->_normalize($quotient), $this->_normalize($remainder));
+ case self::MODE_BCMATH:
+ $quotient = new static();
+ $remainder = new static();
+
+ $quotient->value = bcdiv($this->value, $y->value, 0);
+ $remainder->value = bcmod($this->value, $y->value);
+
+ if ($remainder->value[0] == '-') {
+ $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0);
+ }
+
+ return array($this->_normalize($quotient), $this->_normalize($remainder));
+ }
+
+ if (count($y->value) == 1) {
+ list($q, $r) = $this->_divide_digit($this->value, $y->value[0]);
+ $quotient = new static();
+ $remainder = new static();
+ $quotient->value = $q;
+ $remainder->value = array($r);
+ $quotient->is_negative = $this->is_negative != $y->is_negative;
+ return array($this->_normalize($quotient), $this->_normalize($remainder));
+ }
+
+ static $zero;
+ if (!isset($zero)) {
+ $zero = new static();
+ }
+
+ $x = $this->copy();
+ $y = $y->copy();
+
+ $x_sign = $x->is_negative;
+ $y_sign = $y->is_negative;
+
+ $x->is_negative = $y->is_negative = false;
+
+ $diff = $x->compare($y);
+
+ if (!$diff) {
+ $temp = new static();
+ $temp->value = array(1);
+ $temp->is_negative = $x_sign != $y_sign;
+ return array($this->_normalize($temp), $this->_normalize(new static()));
+ }
+
+ if ($diff < 0) {
+ // if $x is negative, "add" $y.
+ if ($x_sign) {
+ $x = $y->subtract($x);
+ }
+ return array($this->_normalize(new static()), $this->_normalize($x));
+ }
+
+ // normalize $x and $y as described in HAC 14.23 / 14.24
+ $msb = $y->value[count($y->value) - 1];
+ for ($shift = 0; !($msb & self::$msb); ++$shift) {
+ $msb <<= 1;
+ }
+ $x->_lshift($shift);
+ $y->_lshift($shift);
+ $y_value = &$y->value;
+
+ $x_max = count($x->value) - 1;
+ $y_max = count($y->value) - 1;
+
+ $quotient = new static();
+ $quotient_value = &$quotient->value;
+ $quotient_value = $this->_array_repeat(0, $x_max - $y_max + 1);
+
+ static $temp, $lhs, $rhs;
+ if (!isset($temp)) {
+ $temp = new static();
+ $lhs = new static();
+ $rhs = new static();
+ }
+ $temp_value = &$temp->value;
+ $rhs_value = &$rhs->value;
+
+ // $temp = $y << ($x_max - $y_max-1) in base 2**26
+ $temp_value = array_merge($this->_array_repeat(0, $x_max - $y_max), $y_value);
+
+ while ($x->compare($temp) >= 0) {
+ // calculate the "common residue"
+ ++$quotient_value[$x_max - $y_max];
+ $x = $x->subtract($temp);
+ $x_max = count($x->value) - 1;
+ }
+
+ for ($i = $x_max; $i >= $y_max + 1; --$i) {
+ $x_value = &$x->value;
+ $x_window = array(
+ isset($x_value[$i]) ? $x_value[$i] : 0,
+ isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0,
+ isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0
+ );
+ $y_window = array(
+ $y_value[$y_max],
+ ($y_max > 0) ? $y_value[$y_max - 1] : 0
+ );
+
+ $q_index = $i - $y_max - 1;
+ if ($x_window[0] == $y_window[0]) {
+ $quotient_value[$q_index] = self::$maxDigit;
+ } else {
+ $quotient_value[$q_index] = $this->_safe_divide(
+ $x_window[0] * self::$baseFull + $x_window[1],
+ $y_window[0]
+ );
+ }
+
+ $temp_value = array($y_window[1], $y_window[0]);
+
+ $lhs->value = array($quotient_value[$q_index]);
+ $lhs = $lhs->multiply($temp);
+
+ $rhs_value = array($x_window[2], $x_window[1], $x_window[0]);
+
+ while ($lhs->compare($rhs) > 0) {
+ --$quotient_value[$q_index];
+
+ $lhs->value = array($quotient_value[$q_index]);
+ $lhs = $lhs->multiply($temp);
+ }
+
+ $adjust = $this->_array_repeat(0, $q_index);
+ $temp_value = array($quotient_value[$q_index]);
+ $temp = $temp->multiply($y);
+ $temp_value = &$temp->value;
+ if (count($temp_value)) {
+ $temp_value = array_merge($adjust, $temp_value);
+ }
+
+ $x = $x->subtract($temp);
+
+ if ($x->compare($zero) < 0) {
+ $temp_value = array_merge($adjust, $y_value);
+ $x = $x->add($temp);
+
+ --$quotient_value[$q_index];
+ }
+
+ $x_max = count($x_value) - 1;
+ }
+
+ // unnormalize the remainder
+ $x->_rshift($shift);
+
+ $quotient->is_negative = $x_sign != $y_sign;
+
+ // calculate the "common residue", if appropriate
+ if ($x_sign) {
+ $y->_rshift($shift);
+ $x = $y->subtract($x);
+ }
+
+ return array($this->_normalize($quotient), $this->_normalize($x));
+ }
+
+ /**
+ * Divides a BigInteger by a regular integer
+ *
+ * abc / x = a00 / x + b0 / x + c / x
+ *
+ * @param array $dividend
+ * @param array $divisor
+ * @return array
+ * @access private
+ */
+ function _divide_digit($dividend, $divisor)
+ {
+ $carry = 0;
+ $result = array();
+
+ for ($i = count($dividend) - 1; $i >= 0; --$i) {
+ $temp = self::$baseFull * $carry + $dividend[$i];
+ $result[$i] = $this->_safe_divide($temp, $divisor);
+ $carry = (int) ($temp - $divisor * $result[$i]);
+ }
+
+ return array($result, $carry);
+ }
+
+ /**
+ * Performs modular exponentiation.
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger('10');
+ * $b = new \phpseclib\Math\BigInteger('20');
+ * $c = new \phpseclib\Math\BigInteger('30');
+ *
+ * $c = $a->modPow($b, $c);
+ *
+ * echo $c->toString(); // outputs 10
+ * ?>
+ * </code>
+ *
+ * @param \phpseclib\Math\BigInteger $e
+ * @param \phpseclib\Math\BigInteger $n
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ * @internal The most naive approach to modular exponentiation has very unreasonable requirements, and
+ * and although the approach involving repeated squaring does vastly better, it, too, is impractical
+ * for our purposes. The reason being that division - by far the most complicated and time-consuming
+ * of the basic operations (eg. +,-,*,/) - occurs multiple times within it.
+ *
+ * Modular reductions resolve this issue. Although an individual modular reduction takes more time
+ * then an individual division, when performed in succession (with the same modulo), they're a lot faster.
+ *
+ * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction,
+ * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the
+ * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because
+ * the product of two odd numbers is odd), but what about when RSA isn't used?
+ *
+ * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a
+ * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the
+ * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however,
+ * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and
+ * the other, a power of two - and recombine them, later. This is the method that this modPow function uses.
+ * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates.
+ */
+ function modPow($e, $n)
+ {
+ $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs();
+
+ if ($e->compare(new static()) < 0) {
+ $e = $e->abs();
+
+ $temp = $this->modInverse($n);
+ if ($temp === false) {
+ return false;
+ }
+
+ return $this->_normalize($temp->modPow($e, $n));
+ }
+
+ if (MATH_BIGINTEGER_MODE == self::MODE_GMP) {
+ $temp = new static();
+ $temp->value = gmp_powm($this->value, $e->value, $n->value);
+
+ return $this->_normalize($temp);
+ }
+
+ if ($this->compare(new static()) < 0 || $this->compare($n) > 0) {
+ list(, $temp) = $this->divide($n);
+ return $temp->modPow($e, $n);
+ }
+
+ if (defined('MATH_BIGINTEGER_OPENSSL_ENABLED')) {
+ $components = array(
+ 'modulus' => $n->toBytes(true),
+ 'publicExponent' => $e->toBytes(true)
+ );
+
+ $components = array(
+ 'modulus' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['modulus'])), $components['modulus']),
+ 'publicExponent' => pack('Ca*a*', 2, $this->_encodeASN1Length(strlen($components['publicExponent'])), $components['publicExponent'])
+ );
+
+ $RSAPublicKey = pack(
+ 'Ca*a*a*',
+ 48,
+ $this->_encodeASN1Length(strlen($components['modulus']) + strlen($components['publicExponent'])),
+ $components['modulus'],
+ $components['publicExponent']
+ );
+
+ $rsaOID = pack('H*', '300d06092a864886f70d0101010500'); // hex version of MA0GCSqGSIb3DQEBAQUA
+ $RSAPublicKey = chr(0) . $RSAPublicKey;
+ $RSAPublicKey = chr(3) . $this->_encodeASN1Length(strlen($RSAPublicKey)) . $RSAPublicKey;
+
+ $encapsulated = pack(
+ 'Ca*a*',
+ 48,
+ $this->_encodeASN1Length(strlen($rsaOID . $RSAPublicKey)),
+ $rsaOID . $RSAPublicKey
+ );
+
+ $RSAPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" .
+ chunk_split(base64_encode($encapsulated)) .
+ '-----END PUBLIC KEY-----';
+
+ $plaintext = str_pad($this->toBytes(), strlen($n->toBytes(true)) - 1, "\0", STR_PAD_LEFT);
+
+ if (openssl_public_encrypt($plaintext, $result, $RSAPublicKey, OPENSSL_NO_PADDING)) {
+ return new static($result, 256);
+ }
+ }
+
+ if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
+ $temp = new static();
+ $temp->value = bcpowmod($this->value, $e->value, $n->value, 0);
+
+ return $this->_normalize($temp);
+ }
+
+ if (empty($e->value)) {
+ $temp = new static();
+ $temp->value = array(1);
+ return $this->_normalize($temp);
+ }
+
+ if ($e->value == array(1)) {
+ list(, $temp) = $this->divide($n);
+ return $this->_normalize($temp);
+ }
+
+ if ($e->value == array(2)) {
+ $temp = new static();
+ $temp->value = $this->_square($this->value);
+ list(, $temp) = $temp->divide($n);
+ return $this->_normalize($temp);
+ }
+
+ return $this->_normalize($this->_slidingWindow($e, $n, self::BARRETT));
+
+ // the following code, although not callable, can be run independently of the above code
+ // although the above code performed better in my benchmarks the following could might
+ // perform better under different circumstances. in lieu of deleting it it's just been
+ // made uncallable
+
+ // is the modulo odd?
+ if ($n->value[0] & 1) {
+ return $this->_normalize($this->_slidingWindow($e, $n, self::MONTGOMERY));
+ }
+ // if it's not, it's even
+
+ // find the lowest set bit (eg. the max pow of 2 that divides $n)
+ for ($i = 0; $i < count($n->value); ++$i) {
+ if ($n->value[$i]) {
+ $temp = decbin($n->value[$i]);
+ $j = strlen($temp) - strrpos($temp, '1') - 1;
+ $j+= 26 * $i;
+ break;
+ }
+ }
+ // at this point, 2^$j * $n/(2^$j) == $n
+
+ $mod1 = $n->copy();
+ $mod1->_rshift($j);
+ $mod2 = new static();
+ $mod2->value = array(1);
+ $mod2->_lshift($j);
+
+ $part1 = ($mod1->value != array(1)) ? $this->_slidingWindow($e, $mod1, self::MONTGOMERY) : new static();
+ $part2 = $this->_slidingWindow($e, $mod2, self::POWEROF2);
+
+ $y1 = $mod2->modInverse($mod1);
+ $y2 = $mod1->modInverse($mod2);
+
+ $result = $part1->multiply($mod2);
+ $result = $result->multiply($y1);
+
+ $temp = $part2->multiply($mod1);
+ $temp = $temp->multiply($y2);
+
+ $result = $result->add($temp);
+ list(, $result) = $result->divide($n);
+
+ return $this->_normalize($result);
+ }
+
+ /**
+ * Performs modular exponentiation.
+ *
+ * Alias for modPow().
+ *
+ * @param \phpseclib\Math\BigInteger $e
+ * @param \phpseclib\Math\BigInteger $n
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ */
+ function powMod($e, $n)
+ {
+ return $this->modPow($e, $n);
+ }
+
+ /**
+ * Sliding Window k-ary Modular Exponentiation
+ *
+ * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} /
+ * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims,
+ * however, this function performs a modular reduction after every multiplication and squaring operation.
+ * As such, this function has the same preconditions that the reductions being used do.
+ *
+ * @param \phpseclib\Math\BigInteger $e
+ * @param \phpseclib\Math\BigInteger $n
+ * @param int $mode
+ * @return \phpseclib\Math\BigInteger
+ * @access private
+ */
+ function _slidingWindow($e, $n, $mode)
+ {
+ static $window_ranges = array(7, 25, 81, 241, 673, 1793); // from BigInteger.java's oddModPow function
+ //static $window_ranges = array(0, 7, 36, 140, 450, 1303, 3529); // from MPM 7.3.1
+
+ $e_value = $e->value;
+ $e_length = count($e_value) - 1;
+ $e_bits = decbin($e_value[$e_length]);
+ for ($i = $e_length - 1; $i >= 0; --$i) {
+ $e_bits.= str_pad(decbin($e_value[$i]), self::$base, '0', STR_PAD_LEFT);
+ }
+
+ $e_length = strlen($e_bits);
+
+ // calculate the appropriate window size.
+ // $window_size == 3 if $window_ranges is between 25 and 81, for example.
+ for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) {
+ }
+
+ $n_value = $n->value;
+
+ // precompute $this^0 through $this^$window_size
+ $powers = array();
+ $powers[1] = $this->_prepareReduce($this->value, $n_value, $mode);
+ $powers[2] = $this->_squareReduce($powers[1], $n_value, $mode);
+
+ // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end
+ // in a 1. ie. it's supposed to be odd.
+ $temp = 1 << ($window_size - 1);
+ for ($i = 1; $i < $temp; ++$i) {
+ $i2 = $i << 1;
+ $powers[$i2 + 1] = $this->_multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $mode);
+ }
+
+ $result = array(1);
+ $result = $this->_prepareReduce($result, $n_value, $mode);
+
+ for ($i = 0; $i < $e_length;) {
+ if (!$e_bits[$i]) {
+ $result = $this->_squareReduce($result, $n_value, $mode);
+ ++$i;
+ } else {
+ for ($j = $window_size - 1; $j > 0; --$j) {
+ if (!empty($e_bits[$i + $j])) {
+ break;
+ }
+ }
+
+ // eg. the length of substr($e_bits, $i, $j + 1)
+ for ($k = 0; $k <= $j; ++$k) {
+ $result = $this->_squareReduce($result, $n_value, $mode);
+ }
+
+ $result = $this->_multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $mode);
+
+ $i += $j + 1;
+ }
+ }
+
+ $temp = new static();
+ $temp->value = $this->_reduce($result, $n_value, $mode);
+
+ return $temp;
+ }
+
+ /**
+ * Modular reduction
+ *
+ * For most $modes this will return the remainder.
+ *
+ * @see self::_slidingWindow()
+ * @access private
+ * @param array $x
+ * @param array $n
+ * @param int $mode
+ * @return array
+ */
+ function _reduce($x, $n, $mode)
+ {
+ switch ($mode) {
+ case self::MONTGOMERY:
+ return $this->_montgomery($x, $n);
+ case self::BARRETT:
+ return $this->_barrett($x, $n);
+ case self::POWEROF2:
+ $lhs = new static();
+ $lhs->value = $x;
+ $rhs = new static();
+ $rhs->value = $n;
+ return $x->_mod2($n);
+ case self::CLASSIC:
+ $lhs = new static();
+ $lhs->value = $x;
+ $rhs = new static();
+ $rhs->value = $n;
+ list(, $temp) = $lhs->divide($rhs);
+ return $temp->value;
+ case self::NONE:
+ return $x;
+ default:
+ // an invalid $mode was provided
+ }
+ }
+
+ /**
+ * Modular reduction preperation
+ *
+ * @see self::_slidingWindow()
+ * @access private
+ * @param array $x
+ * @param array $n
+ * @param int $mode
+ * @return array
+ */
+ function _prepareReduce($x, $n, $mode)
+ {
+ if ($mode == self::MONTGOMERY) {
+ return $this->_prepMontgomery($x, $n);
+ }
+ return $this->_reduce($x, $n, $mode);
+ }
+
+ /**
+ * Modular multiply
+ *
+ * @see self::_slidingWindow()
+ * @access private
+ * @param array $x
+ * @param array $y
+ * @param array $n
+ * @param int $mode
+ * @return array
+ */
+ function _multiplyReduce($x, $y, $n, $mode)
+ {
+ if ($mode == self::MONTGOMERY) {
+ return $this->_montgomeryMultiply($x, $y, $n);
+ }
+ $temp = $this->_multiply($x, false, $y, false);
+ return $this->_reduce($temp[self::VALUE], $n, $mode);
+ }
+
+ /**
+ * Modular square
+ *
+ * @see self::_slidingWindow()
+ * @access private
+ * @param array $x
+ * @param array $n
+ * @param int $mode
+ * @return array
+ */
+ function _squareReduce($x, $n, $mode)
+ {
+ if ($mode == self::MONTGOMERY) {
+ return $this->_montgomeryMultiply($x, $x, $n);
+ }
+ return $this->_reduce($this->_square($x), $n, $mode);
+ }
+
+ /**
+ * Modulos for Powers of Two
+ *
+ * Calculates $x%$n, where $n = 2**$e, for some $e. Since this is basically the same as doing $x & ($n-1),
+ * we'll just use this function as a wrapper for doing that.
+ *
+ * @see self::_slidingWindow()
+ * @access private
+ * @param \phpseclib\Math\BigInteger
+ * @return \phpseclib\Math\BigInteger
+ */
+ function _mod2($n)
+ {
+ $temp = new static();
+ $temp->value = array(1);
+ return $this->bitwise_and($n->subtract($temp));
+ }
+
+ /**
+ * Barrett Modular Reduction
+ *
+ * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} /
+ * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly,
+ * so as not to require negative numbers (initially, this script didn't support negative numbers).
+ *
+ * Employs "folding", as described at
+ * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from
+ * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x."
+ *
+ * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that
+ * usable on account of (1) its not using reasonable radix points as discussed in
+ * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable
+ * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that
+ * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line
+ * comments for details.
+ *
+ * @see self::_slidingWindow()
+ * @access private
+ * @param array $n
+ * @param array $m
+ * @return array
+ */
+ function _barrett($n, $m)
+ {
+ static $cache = array(
+ self::VARIABLE => array(),
+ self::DATA => array()
+ );
+
+ $m_length = count($m);
+
+ // if ($this->_compare($n, $this->_square($m)) >= 0) {
+ if (count($n) > 2 * $m_length) {
+ $lhs = new static();
+ $rhs = new static();
+ $lhs->value = $n;
+ $rhs->value = $m;
+ list(, $temp) = $lhs->divide($rhs);
+ return $temp->value;
+ }
+
+ // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced
+ if ($m_length < 5) {
+ return $this->_regularBarrett($n, $m);
+ }
+
+ // n = 2 * m.length
+
+ if (($key = array_search($m, $cache[self::VARIABLE])) === false) {
+ $key = count($cache[self::VARIABLE]);
+ $cache[self::VARIABLE][] = $m;
+
+ $lhs = new static();
+ $lhs_value = &$lhs->value;
+ $lhs_value = $this->_array_repeat(0, $m_length + ($m_length >> 1));
+ $lhs_value[] = 1;
+ $rhs = new static();
+ $rhs->value = $m;
+
+ list($u, $m1) = $lhs->divide($rhs);
+ $u = $u->value;
+ $m1 = $m1->value;
+
+ $cache[self::DATA][] = array(
+ 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1)
+ 'm1'=> $m1 // m.length
+ );
+ } else {
+ extract($cache[self::DATA][$key]);
+ }
+
+ $cutoff = $m_length + ($m_length >> 1);
+ $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1)
+ $msd = array_slice($n, $cutoff); // m.length >> 1
+ $lsd = $this->_trim($lsd);
+ $temp = $this->_multiply($msd, false, $m1, false);
+ $n = $this->_add($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1
+
+ if ($m_length & 1) {
+ return $this->_regularBarrett($n[self::VALUE], $m);
+ }
+
+ // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2
+ $temp = array_slice($n[self::VALUE], $m_length - 1);
+ // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2
+ // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1
+ $temp = $this->_multiply($temp, false, $u, false);
+ // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1
+ // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1)
+ $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1);
+ // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1
+ // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1)
+ $temp = $this->_multiply($temp, false, $m, false);
+
+ // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit
+ // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop
+ // following this comment would loop a lot (hence our calling _regularBarrett() in that situation).
+
+ $result = $this->_subtract($n[self::VALUE], false, $temp[self::VALUE], false);
+
+ while ($this->_compare($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) {
+ $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $m, false);
+ }
+
+ return $result[self::VALUE];
+ }
+
+ /**
+ * (Regular) Barrett Modular Reduction
+ *
+ * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this
+ * is that this function does not fold the denominator into a smaller form.
+ *
+ * @see self::_slidingWindow()
+ * @access private
+ * @param array $x
+ * @param array $n
+ * @return array
+ */
+ function _regularBarrett($x, $n)
+ {
+ static $cache = array(
+ self::VARIABLE => array(),
+ self::DATA => array()
+ );
+
+ $n_length = count($n);
+
+ if (count($x) > 2 * $n_length) {
+ $lhs = new static();
+ $rhs = new static();
+ $lhs->value = $x;
+ $rhs->value = $n;
+ list(, $temp) = $lhs->divide($rhs);
+ return $temp->value;
+ }
+
+ if (($key = array_search($n, $cache[self::VARIABLE])) === false) {
+ $key = count($cache[self::VARIABLE]);
+ $cache[self::VARIABLE][] = $n;
+ $lhs = new static();
+ $lhs_value = &$lhs->value;
+ $lhs_value = $this->_array_repeat(0, 2 * $n_length);
+ $lhs_value[] = 1;
+ $rhs = new static();
+ $rhs->value = $n;
+ list($temp, ) = $lhs->divide($rhs); // m.length
+ $cache[self::DATA][] = $temp->value;
+ }
+
+ // 2 * m.length - (m.length - 1) = m.length + 1
+ $temp = array_slice($x, $n_length - 1);
+ // (m.length + 1) + m.length = 2 * m.length + 1
+ $temp = $this->_multiply($temp, false, $cache[self::DATA][$key], false);
+ // (2 * m.length + 1) - (m.length - 1) = m.length + 2
+ $temp = array_slice($temp[self::VALUE], $n_length + 1);
+
+ // m.length + 1
+ $result = array_slice($x, 0, $n_length + 1);
+ // m.length + 1
+ $temp = $this->_multiplyLower($temp, false, $n, false, $n_length + 1);
+ // $temp == array_slice($temp->_multiply($temp, false, $n, false)->value, 0, $n_length + 1)
+
+ if ($this->_compare($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) {
+ $corrector_value = $this->_array_repeat(0, $n_length + 1);
+ $corrector_value[count($corrector_value)] = 1;
+ $result = $this->_add($result, false, $corrector_value, false);
+ $result = $result[self::VALUE];
+ }
+
+ // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits
+ $result = $this->_subtract($result, false, $temp[self::VALUE], $temp[self::SIGN]);
+ while ($this->_compare($result[self::VALUE], $result[self::SIGN], $n, false) > 0) {
+ $result = $this->_subtract($result[self::VALUE], $result[self::SIGN], $n, false);
+ }
+
+ return $result[self::VALUE];
+ }
+
+ /**
+ * Performs long multiplication up to $stop digits
+ *
+ * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved.
+ *
+ * @see self::_regularBarrett()
+ * @param array $x_value
+ * @param bool $x_negative
+ * @param array $y_value
+ * @param bool $y_negative
+ * @param int $stop
+ * @return array
+ * @access private
+ */
+ function _multiplyLower($x_value, $x_negative, $y_value, $y_negative, $stop)
+ {
+ $x_length = count($x_value);
+ $y_length = count($y_value);
+
+ if (!$x_length || !$y_length) { // a 0 is being multiplied
+ return array(
+ self::VALUE => array(),
+ self::SIGN => false
+ );
+ }
+
+ if ($x_length < $y_length) {
+ $temp = $x_value;
+ $x_value = $y_value;
+ $y_value = $temp;
+
+ $x_length = count($x_value);
+ $y_length = count($y_value);
+ }
+
+ $product_value = $this->_array_repeat(0, $x_length + $y_length);
+
+ // the following for loop could be removed if the for loop following it
+ // (the one with nested for loops) initially set $i to 0, but
+ // doing so would also make the result in one set of unnecessary adds,
+ // since on the outermost loops first pass, $product->value[$k] is going
+ // to always be 0
+
+ $carry = 0;
+
+ for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i
+ $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0
+ $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+ $product_value[$j] = (int) ($temp - self::$baseFull * $carry);
+ }
+
+ if ($j < $stop) {
+ $product_value[$j] = $carry;
+ }
+
+ // the above for loop is what the previous comment was talking about. the
+ // following for loop is the "one with nested for loops"
+
+ for ($i = 1; $i < $y_length; ++$i) {
+ $carry = 0;
+
+ for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) {
+ $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry;
+ $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+ $product_value[$k] = (int) ($temp - self::$baseFull * $carry);
+ }
+
+ if ($k < $stop) {
+ $product_value[$k] = $carry;
+ }
+ }
+
+ return array(
+ self::VALUE => $this->_trim($product_value),
+ self::SIGN => $x_negative != $y_negative
+ );
+ }
+
+ /**
+ * Montgomery Modular Reduction
+ *
+ * ($x->_prepMontgomery($n))->_montgomery($n) yields $x % $n.
+ * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=170 MPM 6.3} provides insights on how this can be
+ * improved upon (basically, by using the comba method). gcd($n, 2) must be equal to one for this function
+ * to work correctly.
+ *
+ * @see self::_prepMontgomery()
+ * @see self::_slidingWindow()
+ * @access private
+ * @param array $x
+ * @param array $n
+ * @return array
+ */
+ function _montgomery($x, $n)
+ {
+ static $cache = array(
+ self::VARIABLE => array(),
+ self::DATA => array()
+ );
+
+ if (($key = array_search($n, $cache[self::VARIABLE])) === false) {
+ $key = count($cache[self::VARIABLE]);
+ $cache[self::VARIABLE][] = $x;
+ $cache[self::DATA][] = $this->_modInverse67108864($n);
+ }
+
+ $k = count($n);
+
+ $result = array(self::VALUE => $x);
+
+ for ($i = 0; $i < $k; ++$i) {
+ $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key];
+ $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
+ $temp = $this->_regularMultiply(array($temp), $n);
+ $temp = array_merge($this->_array_repeat(0, $i), $temp);
+ $result = $this->_add($result[self::VALUE], false, $temp, false);
+ }
+
+ $result[self::VALUE] = array_slice($result[self::VALUE], $k);
+
+ if ($this->_compare($result, false, $n, false) >= 0) {
+ $result = $this->_subtract($result[self::VALUE], false, $n, false);
+ }
+
+ return $result[self::VALUE];
+ }
+
+ /**
+ * Montgomery Multiply
+ *
+ * Interleaves the montgomery reduction and long multiplication algorithms together as described in
+ * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36}
+ *
+ * @see self::_prepMontgomery()
+ * @see self::_montgomery()
+ * @access private
+ * @param array $x
+ * @param array $y
+ * @param array $m
+ * @return array
+ */
+ function _montgomeryMultiply($x, $y, $m)
+ {
+ $temp = $this->_multiply($x, false, $y, false);
+ return $this->_montgomery($temp[self::VALUE], $m);
+
+ // the following code, although not callable, can be run independently of the above code
+ // although the above code performed better in my benchmarks the following could might
+ // perform better under different circumstances. in lieu of deleting it it's just been
+ // made uncallable
+
+ static $cache = array(
+ self::VARIABLE => array(),
+ self::DATA => array()
+ );
+
+ if (($key = array_search($m, $cache[self::VARIABLE])) === false) {
+ $key = count($cache[self::VARIABLE]);
+ $cache[self::VARIABLE][] = $m;
+ $cache[self::DATA][] = $this->_modInverse67108864($m);
+ }
+
+ $n = max(count($x), count($y), count($m));
+ $x = array_pad($x, $n, 0);
+ $y = array_pad($y, $n, 0);
+ $m = array_pad($m, $n, 0);
+ $a = array(self::VALUE => $this->_array_repeat(0, $n + 1));
+ for ($i = 0; $i < $n; ++$i) {
+ $temp = $a[self::VALUE][0] + $x[$i] * $y[0];
+ $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
+ $temp = $temp * $cache[self::DATA][$key];
+ $temp = $temp - self::$baseFull * (self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31));
+ $temp = $this->_add($this->_regularMultiply(array($x[$i]), $y), false, $this->_regularMultiply(array($temp), $m), false);
+ $a = $this->_add($a[self::VALUE], false, $temp[self::VALUE], false);
+ $a[self::VALUE] = array_slice($a[self::VALUE], 1);
+ }
+ if ($this->_compare($a[self::VALUE], false, $m, false) >= 0) {
+ $a = $this->_subtract($a[self::VALUE], false, $m, false);
+ }
+ return $a[self::VALUE];
+ }
+
+ /**
+ * Prepare a number for use in Montgomery Modular Reductions
+ *
+ * @see self::_montgomery()
+ * @see self::_slidingWindow()
+ * @access private
+ * @param array $x
+ * @param array $n
+ * @return array
+ */
+ function _prepMontgomery($x, $n)
+ {
+ $lhs = new static();
+ $lhs->value = array_merge($this->_array_repeat(0, count($n)), $x);
+ $rhs = new static();
+ $rhs->value = $n;
+
+ list(, $temp) = $lhs->divide($rhs);
+ return $temp->value;
+ }
+
+ /**
+ * Modular Inverse of a number mod 2**26 (eg. 67108864)
+ *
+ * Based off of the bnpInvDigit function implemented and justified in the following URL:
+ *
+ * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js}
+ *
+ * The following URL provides more info:
+ *
+ * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85}
+ *
+ * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For
+ * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields
+ * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't
+ * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that
+ * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the
+ * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to
+ * 40 bits, which only 64-bit floating points will support.
+ *
+ * Thanks to Pedro Gimeno Fortea for input!
+ *
+ * @see self::_montgomery()
+ * @access private
+ * @param array $x
+ * @return int
+ */
+ function _modInverse67108864($x) // 2**26 == 67,108,864
+ {
+ $x = -$x[0];
+ $result = $x & 0x3; // x**-1 mod 2**2
+ $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4
+ $result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8
+ $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16
+ $result = fmod($result * (2 - fmod($x * $result, self::$baseFull)), self::$baseFull); // x**-1 mod 2**26
+ return $result & self::$maxDigit;
+ }
+
+ /**
+ * Calculates modular inverses.
+ *
+ * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses.
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger(30);
+ * $b = new \phpseclib\Math\BigInteger(17);
+ *
+ * $c = $a->modInverse($b);
+ * echo $c->toString(); // outputs 4
+ *
+ * echo "\r\n";
+ *
+ * $d = $a->multiply($c);
+ * list(, $d) = $d->divide($b);
+ * echo $d; // outputs 1 (as per the definition of modular inverse)
+ * ?>
+ * </code>
+ *
+ * @param \phpseclib\Math\BigInteger $n
+ * @return \phpseclib\Math\BigInteger|false
+ * @access public
+ * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.
+ */
+ function modInverse($n)
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $temp = new static();
+ $temp->value = gmp_invert($this->value, $n->value);
+
+ return ($temp->value === false) ? false : $this->_normalize($temp);
+ }
+
+ static $zero, $one;
+ if (!isset($zero)) {
+ $zero = new static();
+ $one = new static(1);
+ }
+
+ // $x mod -$n == $x mod $n.
+ $n = $n->abs();
+
+ if ($this->compare($zero) < 0) {
+ $temp = $this->abs();
+ $temp = $temp->modInverse($n);
+ return $this->_normalize($n->subtract($temp));
+ }
+
+ extract($this->extendedGCD($n));
+
+ if (!$gcd->equals($one)) {
+ return false;
+ }
+
+ $x = $x->compare($zero) < 0 ? $x->add($n) : $x;
+
+ return $this->compare($zero) < 0 ? $this->_normalize($n->subtract($x)) : $this->_normalize($x);
+ }
+
+ /**
+ * Calculates the greatest common divisor and Bezout's identity.
+ *
+ * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that
+ * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which
+ * combination is returned is dependent upon which mode is in use. See
+ * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information.
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger(693);
+ * $b = new \phpseclib\Math\BigInteger(609);
+ *
+ * extract($a->extendedGCD($b));
+ *
+ * echo $gcd->toString() . "\r\n"; // outputs 21
+ * echo $a->toString() * $x->toString() + $b->toString() * $y->toString(); // outputs 21
+ * ?>
+ * </code>
+ *
+ * @param \phpseclib\Math\BigInteger $n
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ * @internal Calculates the GCD using the binary xGCD algorithim described in
+ * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=19 HAC 14.61}. As the text above 14.61 notes,
+ * the more traditional algorithim requires "relatively costly multiple-precision divisions".
+ */
+ function extendedGCD($n)
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ extract(gmp_gcdext($this->value, $n->value));
+
+ return array(
+ 'gcd' => $this->_normalize(new static($g)),
+ 'x' => $this->_normalize(new static($s)),
+ 'y' => $this->_normalize(new static($t))
+ );
+ case self::MODE_BCMATH:
+ // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works
+ // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is,
+ // the basic extended euclidean algorithim is what we're using.
+
+ $u = $this->value;
+ $v = $n->value;
+
+ $a = '1';
+ $b = '0';
+ $c = '0';
+ $d = '1';
+
+ while (bccomp($v, '0', 0) != 0) {
+ $q = bcdiv($u, $v, 0);
+
+ $temp = $u;
+ $u = $v;
+ $v = bcsub($temp, bcmul($v, $q, 0), 0);
+
+ $temp = $a;
+ $a = $c;
+ $c = bcsub($temp, bcmul($a, $q, 0), 0);
+
+ $temp = $b;
+ $b = $d;
+ $d = bcsub($temp, bcmul($b, $q, 0), 0);
+ }
+
+ return array(
+ 'gcd' => $this->_normalize(new static($u)),
+ 'x' => $this->_normalize(new static($a)),
+ 'y' => $this->_normalize(new static($b))
+ );
+ }
+
+ $y = $n->copy();
+ $x = $this->copy();
+ $g = new static();
+ $g->value = array(1);
+
+ while (!(($x->value[0] & 1)|| ($y->value[0] & 1))) {
+ $x->_rshift(1);
+ $y->_rshift(1);
+ $g->_lshift(1);
+ }
+
+ $u = $x->copy();
+ $v = $y->copy();
+
+ $a = new static();
+ $b = new static();
+ $c = new static();
+ $d = new static();
+
+ $a->value = $d->value = $g->value = array(1);
+ $b->value = $c->value = array();
+
+ while (!empty($u->value)) {
+ while (!($u->value[0] & 1)) {
+ $u->_rshift(1);
+ if ((!empty($a->value) && ($a->value[0] & 1)) || (!empty($b->value) && ($b->value[0] & 1))) {
+ $a = $a->add($y);
+ $b = $b->subtract($x);
+ }
+ $a->_rshift(1);
+ $b->_rshift(1);
+ }
+
+ while (!($v->value[0] & 1)) {
+ $v->_rshift(1);
+ if ((!empty($d->value) && ($d->value[0] & 1)) || (!empty($c->value) && ($c->value[0] & 1))) {
+ $c = $c->add($y);
+ $d = $d->subtract($x);
+ }
+ $c->_rshift(1);
+ $d->_rshift(1);
+ }
+
+ if ($u->compare($v) >= 0) {
+ $u = $u->subtract($v);
+ $a = $a->subtract($c);
+ $b = $b->subtract($d);
+ } else {
+ $v = $v->subtract($u);
+ $c = $c->subtract($a);
+ $d = $d->subtract($b);
+ }
+ }
+
+ return array(
+ 'gcd' => $this->_normalize($g->multiply($v)),
+ 'x' => $this->_normalize($c),
+ 'y' => $this->_normalize($d)
+ );
+ }
+
+ /**
+ * Calculates the greatest common divisor
+ *
+ * Say you have 693 and 609. The GCD is 21.
+ *
+ * Here's an example:
+ * <code>
+ * <?php
+ * $a = new \phpseclib\Math\BigInteger(693);
+ * $b = new \phpseclib\Math\BigInteger(609);
+ *
+ * $gcd = a->extendedGCD($b);
+ *
+ * echo $gcd->toString() . "\r\n"; // outputs 21
+ * ?>
+ * </code>
+ *
+ * @param \phpseclib\Math\BigInteger $n
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ */
+ function gcd($n)
+ {
+ extract($this->extendedGCD($n));
+ return $gcd;
+ }
+
+ /**
+ * Absolute value.
+ *
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ */
+ function abs()
+ {
+ $temp = new static();
+
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $temp->value = gmp_abs($this->value);
+ break;
+ case self::MODE_BCMATH:
+ $temp->value = (bccomp($this->value, '0', 0) < 0) ? substr($this->value, 1) : $this->value;
+ break;
+ default:
+ $temp->value = $this->value;
+ }
+
+ return $temp;
+ }
+
+ /**
+ * Compares two numbers.
+ *
+ * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is
+ * demonstrated thusly:
+ *
+ * $x > $y: $x->compare($y) > 0
+ * $x < $y: $x->compare($y) < 0
+ * $x == $y: $x->compare($y) == 0
+ *
+ * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y).
+ *
+ * @param \phpseclib\Math\BigInteger $y
+ * @return int < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal.
+ * @access public
+ * @see self::equals()
+ * @internal Could return $this->subtract($x), but that's not as fast as what we do do.
+ */
+ function compare($y)
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $r = gmp_cmp($this->value, $y->value);
+ if ($r < -1) {
+ $r = -1;
+ }
+ if ($r > 1) {
+ $r = 1;
+ }
+ return $r;
+ case self::MODE_BCMATH:
+ return bccomp($this->value, $y->value, 0);
+ }
+
+ return $this->_compare($this->value, $this->is_negative, $y->value, $y->is_negative);
+ }
+
+ /**
+ * Compares two numbers.
+ *
+ * @param array $x_value
+ * @param bool $x_negative
+ * @param array $y_value
+ * @param bool $y_negative
+ * @return int
+ * @see self::compare()
+ * @access private
+ */
+ function _compare($x_value, $x_negative, $y_value, $y_negative)
+ {
+ if ($x_negative != $y_negative) {
+ return (!$x_negative && $y_negative) ? 1 : -1;
+ }
+
+ $result = $x_negative ? -1 : 1;
+
+ if (count($x_value) != count($y_value)) {
+ return (count($x_value) > count($y_value)) ? $result : -$result;
+ }
+ $size = max(count($x_value), count($y_value));
+
+ $x_value = array_pad($x_value, $size, 0);
+ $y_value = array_pad($y_value, $size, 0);
+
+ for ($i = count($x_value) - 1; $i >= 0; --$i) {
+ if ($x_value[$i] != $y_value[$i]) {
+ return ($x_value[$i] > $y_value[$i]) ? $result : -$result;
+ }
+ }
+
+ return 0;
+ }
+
+ /**
+ * Tests the equality of two numbers.
+ *
+ * If you need to see if one number is greater than or less than another number, use BigInteger::compare()
+ *
+ * @param \phpseclib\Math\BigInteger $x
+ * @return bool
+ * @access public
+ * @see self::compare()
+ */
+ function equals($x)
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ return gmp_cmp($this->value, $x->value) == 0;
+ default:
+ return $this->value === $x->value && $this->is_negative == $x->is_negative;
+ }
+ }
+
+ /**
+ * Set Precision
+ *
+ * Some bitwise operations give different results depending on the precision being used. Examples include left
+ * shift, not, and rotates.
+ *
+ * @param int $bits
+ * @access public
+ */
+ function setPrecision($bits)
+ {
+ $this->precision = $bits;
+ if (MATH_BIGINTEGER_MODE != self::MODE_BCMATH) {
+ $this->bitmask = new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256);
+ } else {
+ $this->bitmask = new static(bcpow('2', $bits, 0));
+ }
+
+ $temp = $this->_normalize($this);
+ $this->value = $temp->value;
+ }
+
+ /**
+ * Logical And
+ *
+ * @param \phpseclib\Math\BigInteger $x
+ * @access public
+ * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
+ * @return \phpseclib\Math\BigInteger
+ */
+ function bitwise_and($x)
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $temp = new static();
+ $temp->value = gmp_and($this->value, $x->value);
+
+ return $this->_normalize($temp);
+ case self::MODE_BCMATH:
+ $left = $this->toBytes();
+ $right = $x->toBytes();
+
+ $length = max(strlen($left), strlen($right));
+
+ $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
+ $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
+
+ return $this->_normalize(new static($left & $right, 256));
+ }
+
+ $result = $this->copy();
+
+ $length = min(count($x->value), count($this->value));
+
+ $result->value = array_slice($result->value, 0, $length);
+
+ for ($i = 0; $i < $length; ++$i) {
+ $result->value[$i]&= $x->value[$i];
+ }
+
+ return $this->_normalize($result);
+ }
+
+ /**
+ * Logical Or
+ *
+ * @param \phpseclib\Math\BigInteger $x
+ * @access public
+ * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
+ * @return \phpseclib\Math\BigInteger
+ */
+ function bitwise_or($x)
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $temp = new static();
+ $temp->value = gmp_or($this->value, $x->value);
+
+ return $this->_normalize($temp);
+ case self::MODE_BCMATH:
+ $left = $this->toBytes();
+ $right = $x->toBytes();
+
+ $length = max(strlen($left), strlen($right));
+
+ $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
+ $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
+
+ return $this->_normalize(new static($left | $right, 256));
+ }
+
+ $length = max(count($this->value), count($x->value));
+ $result = $this->copy();
+ $result->value = array_pad($result->value, $length, 0);
+ $x->value = array_pad($x->value, $length, 0);
+
+ for ($i = 0; $i < $length; ++$i) {
+ $result->value[$i]|= $x->value[$i];
+ }
+
+ return $this->_normalize($result);
+ }
+
+ /**
+ * Logical Exclusive-Or
+ *
+ * @param \phpseclib\Math\BigInteger $x
+ * @access public
+ * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
+ * @return \phpseclib\Math\BigInteger
+ */
+ function bitwise_xor($x)
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ $temp = new static();
+ $temp->value = gmp_xor(gmp_abs($this->value), gmp_abs($x->value));
+ return $this->_normalize($temp);
+ case self::MODE_BCMATH:
+ $left = $this->toBytes();
+ $right = $x->toBytes();
+
+ $length = max(strlen($left), strlen($right));
+
+ $left = str_pad($left, $length, chr(0), STR_PAD_LEFT);
+ $right = str_pad($right, $length, chr(0), STR_PAD_LEFT);
+
+ return $this->_normalize(new static($left ^ $right, 256));
+ }
+
+ $length = max(count($this->value), count($x->value));
+ $result = $this->copy();
+ $result->is_negative = false;
+ $result->value = array_pad($result->value, $length, 0);
+ $x->value = array_pad($x->value, $length, 0);
+
+ for ($i = 0; $i < $length; ++$i) {
+ $result->value[$i]^= $x->value[$i];
+ }
+
+ return $this->_normalize($result);
+ }
+
+ /**
+ * Logical Not
+ *
+ * @access public
+ * @internal Implemented per a request by Lluis Pamies i Juarez <lluis _a_ pamies.cat>
+ * @return \phpseclib\Math\BigInteger
+ */
+ function bitwise_not()
+ {
+ // calculuate "not" without regard to $this->precision
+ // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0)
+ $temp = $this->toBytes();
+ if ($temp == '') {
+ return $this->_normalize(new static());
+ }
+ $pre_msb = decbin(ord($temp[0]));
+ $temp = ~$temp;
+ $msb = decbin(ord($temp[0]));
+ if (strlen($msb) == 8) {
+ $msb = substr($msb, strpos($msb, '0'));
+ }
+ $temp[0] = chr(bindec($msb));
+
+ // see if we need to add extra leading 1's
+ $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8;
+ $new_bits = $this->precision - $current_bits;
+ if ($new_bits <= 0) {
+ return $this->_normalize(new static($temp, 256));
+ }
+
+ // generate as many leading 1's as we need to.
+ $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3);
+ $this->_base256_lshift($leading_ones, $current_bits);
+
+ $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT);
+
+ return $this->_normalize(new static($leading_ones | $temp, 256));
+ }
+
+ /**
+ * Logical Right Shift
+ *
+ * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift.
+ *
+ * @param int $shift
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ * @internal The only version that yields any speed increases is the internal version.
+ */
+ function bitwise_rightShift($shift)
+ {
+ $temp = new static();
+
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ static $two;
+
+ if (!isset($two)) {
+ $two = gmp_init('2');
+ }
+
+ $temp->value = gmp_div_q($this->value, gmp_pow($two, $shift));
+
+ break;
+ case self::MODE_BCMATH:
+ $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0);
+
+ break;
+ default: // could just replace _lshift with this, but then all _lshift() calls would need to be rewritten
+ // and I don't want to do that...
+ $temp->value = $this->value;
+ $temp->_rshift($shift);
+ }
+
+ return $this->_normalize($temp);
+ }
+
+ /**
+ * Logical Left Shift
+ *
+ * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift.
+ *
+ * @param int $shift
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ * @internal The only version that yields any speed increases is the internal version.
+ */
+ function bitwise_leftShift($shift)
+ {
+ $temp = new static();
+
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ static $two;
+
+ if (!isset($two)) {
+ $two = gmp_init('2');
+ }
+
+ $temp->value = gmp_mul($this->value, gmp_pow($two, $shift));
+
+ break;
+ case self::MODE_BCMATH:
+ $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0);
+
+ break;
+ default: // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten
+ // and I don't want to do that...
+ $temp->value = $this->value;
+ $temp->_lshift($shift);
+ }
+
+ return $this->_normalize($temp);
+ }
+
+ /**
+ * Logical Left Rotate
+ *
+ * Instead of the top x bits being dropped they're appended to the shifted bit string.
+ *
+ * @param int $shift
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ */
+ function bitwise_leftRotate($shift)
+ {
+ $bits = $this->toBytes();
+
+ if ($this->precision > 0) {
+ $precision = $this->precision;
+ if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
+ $mask = $this->bitmask->subtract(new static(1));
+ $mask = $mask->toBytes();
+ } else {
+ $mask = $this->bitmask->toBytes();
+ }
+ } else {
+ $temp = ord($bits[0]);
+ for ($i = 0; $temp >> $i; ++$i) {
+ }
+ $precision = 8 * strlen($bits) - 8 + $i;
+ $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3);
+ }
+
+ if ($shift < 0) {
+ $shift+= $precision;
+ }
+ $shift%= $precision;
+
+ if (!$shift) {
+ return $this->copy();
+ }
+
+ $left = $this->bitwise_leftShift($shift);
+ $left = $left->bitwise_and(new static($mask, 256));
+ $right = $this->bitwise_rightShift($precision - $shift);
+ $result = MATH_BIGINTEGER_MODE != self::MODE_BCMATH ? $left->bitwise_or($right) : $left->add($right);
+ return $this->_normalize($result);
+ }
+
+ /**
+ * Logical Right Rotate
+ *
+ * Instead of the bottom x bits being dropped they're prepended to the shifted bit string.
+ *
+ * @param int $shift
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ */
+ function bitwise_rightRotate($shift)
+ {
+ return $this->bitwise_leftRotate(-$shift);
+ }
+
+ /**
+ * Generates a random BigInteger
+ *
+ * Byte length is equal to $length. Uses \phpseclib\Crypt\Random if it's loaded and mt_rand if it's not.
+ *
+ * @param int $length
+ * @return \phpseclib\Math\BigInteger
+ * @access private
+ */
+ function _random_number_helper($size)
+ {
+ if (class_exists('\phpseclib\Crypt\Random')) {
+ $random = Random::string($size);
+ } else {
+ $random = '';
+
+ if ($size & 1) {
+ $random.= chr(mt_rand(0, 255));
+ }
+
+ $blocks = $size >> 1;
+ for ($i = 0; $i < $blocks; ++$i) {
+ // mt_rand(-2147483648, 0x7FFFFFFF) always produces -2147483648 on some systems
+ $random.= pack('n', mt_rand(0, 0xFFFF));
+ }
+ }
+
+ return new static($random, 256);
+ }
+
+ /**
+ * Generate a random number
+ *
+ * Returns a random number between $min and $max where $min and $max
+ * can be defined using one of the two methods:
+ *
+ * $min->random($max)
+ * $max->random($min)
+ *
+ * @param \phpseclib\Math\BigInteger $arg1
+ * @param \phpseclib\Math\BigInteger $arg2
+ * @return \phpseclib\Math\BigInteger
+ * @access public
+ * @internal The API for creating random numbers used to be $a->random($min, $max), where $a was a BigInteger object.
+ * That method is still supported for BC purposes.
+ */
+ function random($arg1, $arg2 = false)
+ {
+ if ($arg1 === false) {
+ return false;
+ }
+
+ if ($arg2 === false) {
+ $max = $arg1;
+ $min = $this;
+ } else {
+ $min = $arg1;
+ $max = $arg2;
+ }
+
+ $compare = $max->compare($min);
+
+ if (!$compare) {
+ return $this->_normalize($min);
+ } elseif ($compare < 0) {
+ // if $min is bigger then $max, swap $min and $max
+ $temp = $max;
+ $max = $min;
+ $min = $temp;
+ }
+
+ static $one;
+ if (!isset($one)) {
+ $one = new static(1);
+ }
+
+ $max = $max->subtract($min->subtract($one));
+ $size = strlen(ltrim($max->toBytes(), chr(0)));
+
+ /*
+ doing $random % $max doesn't work because some numbers will be more likely to occur than others.
+ eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145
+ would produce 5 whereas the only value of random that could produce 139 would be 139. ie.
+ not all numbers would be equally likely. some would be more likely than others.
+
+ creating a whole new random number until you find one that is within the range doesn't work
+ because, for sufficiently small ranges, the likelihood that you'd get a number within that range
+ would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability
+ would be pretty high that $random would be greater than $max.
+
+ phpseclib works around this using the technique described here:
+
+ http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string
+ */
+ $random_max = new static(chr(1) . str_repeat("\0", $size), 256);
+ $random = $this->_random_number_helper($size);
+
+ list($max_multiple) = $random_max->divide($max);
+ $max_multiple = $max_multiple->multiply($max);
+
+ while ($random->compare($max_multiple) >= 0) {
+ $random = $random->subtract($max_multiple);
+ $random_max = $random_max->subtract($max_multiple);
+ $random = $random->bitwise_leftShift(8);
+ $random = $random->add($this->_random_number_helper(1));
+ $random_max = $random_max->bitwise_leftShift(8);
+ list($max_multiple) = $random_max->divide($max);
+ $max_multiple = $max_multiple->multiply($max);
+ }
+ list(, $random) = $random->divide($max);
+
+ return $this->_normalize($random->add($min));
+ }
+
+ /**
+ * Generate a random prime number.
+ *
+ * If there's not a prime within the given range, false will be returned.
+ * If more than $timeout seconds have elapsed, give up and return false.
+ *
+ * @param \phpseclib\Math\BigInteger $arg1
+ * @param \phpseclib\Math\BigInteger $arg2
+ * @param int $timeout
+ * @return Math_BigInteger|false
+ * @access public
+ * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=15 HAC 4.44}.
+ */
+ function randomPrime($arg1, $arg2 = false, $timeout = false)
+ {
+ if ($arg1 === false) {
+ return false;
+ }
+
+ if ($arg2 === false) {
+ $max = $arg1;
+ $min = $this;
+ } else {
+ $min = $arg1;
+ $max = $arg2;
+ }
+
+ $compare = $max->compare($min);
+
+ if (!$compare) {
+ return $min->isPrime() ? $min : false;
+ } elseif ($compare < 0) {
+ // if $min is bigger then $max, swap $min and $max
+ $temp = $max;
+ $max = $min;
+ $min = $temp;
+ }
+
+ static $one, $two;
+ if (!isset($one)) {
+ $one = new static(1);
+ $two = new static(2);
+ }
+
+ $start = time();
+
+ $x = $this->random($min, $max);
+
+ // gmp_nextprime() requires PHP 5 >= 5.2.0 per <http://php.net/gmp-nextprime>.
+ if (MATH_BIGINTEGER_MODE == self::MODE_GMP && extension_loaded('gmp')) {
+ $p = new static();
+ $p->value = gmp_nextprime($x->value);
+
+ if ($p->compare($max) <= 0) {
+ return $p;
+ }
+
+ if (!$min->equals($x)) {
+ $x = $x->subtract($one);
+ }
+
+ return $x->randomPrime($min, $x);
+ }
+
+ if ($x->equals($two)) {
+ return $x;
+ }
+
+ $x->_make_odd();
+ if ($x->compare($max) > 0) {
+ // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range
+ if ($min->equals($max)) {
+ return false;
+ }
+ $x = $min->copy();
+ $x->_make_odd();
+ }
+
+ $initial_x = $x->copy();
+
+ while (true) {
+ if ($timeout !== false && time() - $start > $timeout) {
+ return false;
+ }
+
+ if ($x->isPrime()) {
+ return $x;
+ }
+
+ $x = $x->add($two);
+
+ if ($x->compare($max) > 0) {
+ $x = $min->copy();
+ if ($x->equals($two)) {
+ return $x;
+ }
+ $x->_make_odd();
+ }
+
+ if ($x->equals($initial_x)) {
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Make the current number odd
+ *
+ * If the current number is odd it'll be unchanged. If it's even, one will be added to it.
+ *
+ * @see self::randomPrime()
+ * @access private
+ */
+ function _make_odd()
+ {
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ gmp_setbit($this->value, 0);
+ break;
+ case self::MODE_BCMATH:
+ if ($this->value[strlen($this->value) - 1] % 2 == 0) {
+ $this->value = bcadd($this->value, '1');
+ }
+ break;
+ default:
+ $this->value[0] |= 1;
+ }
+ }
+
+ /**
+ * Checks a numer to see if it's prime
+ *
+ * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the
+ * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads
+ * on a website instead of just one.
+ *
+ * @param \phpseclib\Math\BigInteger $t
+ * @return bool
+ * @access public
+ * @internal Uses the
+ * {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. See
+ * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24}.
+ */
+ function isPrime($t = false)
+ {
+ $length = strlen($this->toBytes());
+
+ if (!$t) {
+ // see HAC 4.49 "Note (controlling the error probability)"
+ // @codingStandardsIgnoreStart
+ if ($length >= 163) { $t = 2; } // floor(1300 / 8)
+ else if ($length >= 106) { $t = 3; } // floor( 850 / 8)
+ else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8)
+ else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8)
+ else if ($length >= 56 ) { $t = 6; } // floor( 450 / 8)
+ else if ($length >= 50 ) { $t = 7; } // floor( 400 / 8)
+ else if ($length >= 43 ) { $t = 8; } // floor( 350 / 8)
+ else if ($length >= 37 ) { $t = 9; } // floor( 300 / 8)
+ else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8)
+ else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8)
+ else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8)
+ else { $t = 27; }
+ // @codingStandardsIgnoreEnd
+ }
+
+ // ie. gmp_testbit($this, 0)
+ // ie. isEven() or !isOdd()
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ return gmp_prob_prime($this->value, $t) != 0;
+ case self::MODE_BCMATH:
+ if ($this->value === '2') {
+ return true;
+ }
+ if ($this->value[strlen($this->value) - 1] % 2 == 0) {
+ return false;
+ }
+ break;
+ default:
+ if ($this->value == array(2)) {
+ return true;
+ }
+ if (~$this->value[0] & 1) {
+ return false;
+ }
+ }
+
+ static $primes, $zero, $one, $two;
+
+ if (!isset($primes)) {
+ $primes = array(
+ 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829,
+ 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947,
+ 953, 967, 971, 977, 983, 991, 997
+ );
+
+ if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
+ for ($i = 0; $i < count($primes); ++$i) {
+ $primes[$i] = new static($primes[$i]);
+ }
+ }
+
+ $zero = new static();
+ $one = new static(1);
+ $two = new static(2);
+ }
+
+ if ($this->equals($one)) {
+ return false;
+ }
+
+ // see HAC 4.4.1 "Random search for probable primes"
+ if (MATH_BIGINTEGER_MODE != self::MODE_INTERNAL) {
+ foreach ($primes as $prime) {
+ list(, $r) = $this->divide($prime);
+ if ($r->equals($zero)) {
+ return $this->equals($prime);
+ }
+ }
+ } else {
+ $value = $this->value;
+ foreach ($primes as $prime) {
+ list(, $r) = $this->_divide_digit($value, $prime);
+ if (!$r) {
+ return count($value) == 1 && $value[0] == $prime;
+ }
+ }
+ }
+
+ $n = $this->copy();
+ $n_1 = $n->subtract($one);
+ $n_2 = $n->subtract($two);
+
+ $r = $n_1->copy();
+ $r_value = $r->value;
+ // ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s));
+ if (MATH_BIGINTEGER_MODE == self::MODE_BCMATH) {
+ $s = 0;
+ // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals($one) check earlier
+ while ($r->value[strlen($r->value) - 1] % 2 == 0) {
+ $r->value = bcdiv($r->value, '2', 0);
+ ++$s;
+ }
+ } else {
+ for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) {
+ $temp = ~$r_value[$i] & 0xFFFFFF;
+ for ($j = 1; ($temp >> $j) & 1; ++$j) {
+ }
+ if ($j != 25) {
+ break;
+ }
+ }
+ $s = 26 * $i + $j;
+ $r->_rshift($s);
+ }
+
+ for ($i = 0; $i < $t; ++$i) {
+ $a = $this->random($two, $n_2);
+ $y = $a->modPow($r, $n);
+
+ if (!$y->equals($one) && !$y->equals($n_1)) {
+ for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) {
+ $y = $y->modPow($two, $n);
+ if ($y->equals($one)) {
+ return false;
+ }
+ }
+
+ if (!$y->equals($n_1)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Logical Left Shift
+ *
+ * Shifts BigInteger's by $shift bits.
+ *
+ * @param int $shift
+ * @access private
+ */
+ function _lshift($shift)
+ {
+ if ($shift == 0) {
+ return;
+ }
+
+ $num_digits = (int) ($shift / self::$base);
+ $shift %= self::$base;
+ $shift = 1 << $shift;
+
+ $carry = 0;
+
+ for ($i = 0; $i < count($this->value); ++$i) {
+ $temp = $this->value[$i] * $shift + $carry;
+ $carry = self::$base === 26 ? intval($temp / 0x4000000) : ($temp >> 31);
+ $this->value[$i] = (int) ($temp - $carry * self::$baseFull);
+ }
+
+ if ($carry) {
+ $this->value[count($this->value)] = $carry;
+ }
+
+ while ($num_digits--) {
+ array_unshift($this->value, 0);
+ }
+ }
+
+ /**
+ * Logical Right Shift
+ *
+ * Shifts BigInteger's by $shift bits.
+ *
+ * @param int $shift
+ * @access private
+ */
+ function _rshift($shift)
+ {
+ if ($shift == 0) {
+ return;
+ }
+
+ $num_digits = (int) ($shift / self::$base);
+ $shift %= self::$base;
+ $carry_shift = self::$base - $shift;
+ $carry_mask = (1 << $shift) - 1;
+
+ if ($num_digits) {
+ $this->value = array_slice($this->value, $num_digits);
+ }
+
+ $carry = 0;
+
+ for ($i = count($this->value) - 1; $i >= 0; --$i) {
+ $temp = $this->value[$i] >> $shift | $carry;
+ $carry = ($this->value[$i] & $carry_mask) << $carry_shift;
+ $this->value[$i] = $temp;
+ }
+
+ $this->value = $this->_trim($this->value);
+ }
+
+ /**
+ * Normalize
+ *
+ * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision
+ *
+ * @param \phpseclib\Math\BigInteger
+ * @return \phpseclib\Math\BigInteger
+ * @see self::_trim()
+ * @access private
+ */
+ function _normalize($result)
+ {
+ $result->precision = $this->precision;
+ $result->bitmask = $this->bitmask;
+
+ switch (MATH_BIGINTEGER_MODE) {
+ case self::MODE_GMP:
+ if ($this->bitmask !== false) {
+ $flip = gmp_cmp($result->value, gmp_init(0)) < 0;
+ if ($flip) {
+ $result->value = gmp_neg($result->value);
+ }
+ $result->value = gmp_and($result->value, $result->bitmask->value);
+ if ($flip) {
+ $result->value = gmp_neg($result->value);
+ }
+ }
+
+ return $result;
+ case self::MODE_BCMATH:
+ if (!empty($result->bitmask->value)) {
+ $result->value = bcmod($result->value, $result->bitmask->value);
+ }
+
+ return $result;
+ }
+
+ $value = &$result->value;
+
+ if (!count($value)) {
+ $result->is_negative = false;
+ return $result;
+ }
+
+ $value = $this->_trim($value);
+
+ if (!empty($result->bitmask->value)) {
+ $length = min(count($value), count($this->bitmask->value));
+ $value = array_slice($value, 0, $length);
+
+ for ($i = 0; $i < $length; ++$i) {
+ $value[$i] = $value[$i] & $this->bitmask->value[$i];
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Trim
+ *
+ * Removes leading zeros
+ *
+ * @param array $value
+ * @return \phpseclib\Math\BigInteger
+ * @access private
+ */
+ function _trim($value)
+ {
+ for ($i = count($value) - 1; $i >= 0; --$i) {
+ if ($value[$i]) {
+ break;
+ }
+ unset($value[$i]);
+ }
+
+ return $value;
+ }
+
+ /**
+ * Array Repeat
+ *
+ * @param $input Array
+ * @param $multiplier mixed
+ * @return array
+ * @access private
+ */
+ function _array_repeat($input, $multiplier)
+ {
+ return ($multiplier) ? array_fill(0, $multiplier, $input) : array();
+ }
+
+ /**
+ * Logical Left Shift
+ *
+ * Shifts binary strings $shift bits, essentially multiplying by 2**$shift.
+ *
+ * @param $x String
+ * @param $shift Integer
+ * @return string
+ * @access private
+ */
+ function _base256_lshift(&$x, $shift)
+ {
+ if ($shift == 0) {
+ return;
+ }
+
+ $num_bytes = $shift >> 3; // eg. floor($shift/8)
+ $shift &= 7; // eg. $shift % 8
+
+ $carry = 0;
+ for ($i = strlen($x) - 1; $i >= 0; --$i) {
+ $temp = ord($x[$i]) << $shift | $carry;
+ $x[$i] = chr($temp);
+ $carry = $temp >> 8;
+ }
+ $carry = ($carry != 0) ? chr($carry) : '';
+ $x = $carry . $x . str_repeat(chr(0), $num_bytes);
+ }
+
+ /**
+ * Logical Right Shift
+ *
+ * Shifts binary strings $shift bits, essentially dividing by 2**$shift and returning the remainder.
+ *
+ * @param $x String
+ * @param $shift Integer
+ * @return string
+ * @access private
+ */
+ function _base256_rshift(&$x, $shift)
+ {
+ if ($shift == 0) {
+ $x = ltrim($x, chr(0));
+ return '';
+ }
+
+ $num_bytes = $shift >> 3; // eg. floor($shift/8)
+ $shift &= 7; // eg. $shift % 8
+
+ $remainder = '';
+ if ($num_bytes) {
+ $start = $num_bytes > strlen($x) ? -strlen($x) : -$num_bytes;
+ $remainder = substr($x, $start);
+ $x = substr($x, 0, -$num_bytes);
+ }
+
+ $carry = 0;
+ $carry_shift = 8 - $shift;
+ for ($i = 0; $i < strlen($x); ++$i) {
+ $temp = (ord($x[$i]) >> $shift) | $carry;
+ $carry = (ord($x[$i]) << $carry_shift) & 0xFF;
+ $x[$i] = chr($temp);
+ }
+ $x = ltrim($x, chr(0));
+
+ $remainder = chr($carry >> $carry_shift) . $remainder;
+
+ return ltrim($remainder, chr(0));
+ }
+
+ // one quirk about how the following functions are implemented is that PHP defines N to be an unsigned long
+ // at 32-bits, while java's longs are 64-bits.
+
+ /**
+ * Converts 32-bit integers to bytes.
+ *
+ * @param int $x
+ * @return string
+ * @access private
+ */
+ function _int2bytes($x)
+ {
+ return ltrim(pack('N', $x), chr(0));
+ }
+
+ /**
+ * Converts bytes to 32-bit integers
+ *
+ * @param string $x
+ * @return int
+ * @access private
+ */
+ function _bytes2int($x)
+ {
+ $temp = unpack('Nint', str_pad($x, 4, chr(0), STR_PAD_LEFT));
+ return $temp['int'];
+ }
+
+ /**
+ * DER-encode an integer
+ *
+ * The ability to DER-encode integers is needed to create RSA public keys for use with OpenSSL
+ *
+ * @see self::modPow()
+ * @access private
+ * @param int $length
+ * @return string
+ */
+ function _encodeASN1Length($length)
+ {
+ if ($length <= 0x7F) {
+ return chr($length);
+ }
+
+ $temp = ltrim(pack('N', $length), chr(0));
+ return pack('Ca*', 0x80 | strlen($temp), $temp);
+ }
+
+ /**
+ * Single digit division
+ *
+ * Even if int64 is being used the division operator will return a float64 value
+ * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't
+ * have the precision of int64 this is a problem so, when int64 is being used,
+ * we'll guarantee that the dividend is divisible by first subtracting the remainder.
+ *
+ * @access private
+ * @param int $x
+ * @param int $y
+ * @return int
+ */
+ function _safe_divide($x, $y)
+ {
+ if (self::$base === 26) {
+ return (int) ($x / $y);
+ }
+
+ // self::$base === 31
+ return ($x - ($x % $y)) / $y;
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
new file mode 100644
index 0000000..cf13496
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SCP.php
@@ -0,0 +1,342 @@
+<?php
+
+/**
+ * Pure-PHP implementation of SCP.
+ *
+ * PHP version 5
+ *
+ * The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}.
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
+ * if (!$ssh->login('username', 'password')) {
+ * exit('bad login');
+ * }
+ * $scp = new \phpseclib\Net\SCP($ssh);
+ *
+ * $scp->put('abcd', str_repeat('x', 1024*1024));
+ * ?>
+ * </code>
+ *
+ * @category Net
+ * @package SCP
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2010 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Net;
+
+/**
+ * Pure-PHP implementations of SCP.
+ *
+ * @package SCP
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class SCP
+{
+ /**#@+
+ * @access public
+ * @see \phpseclib\Net\SCP::put()
+ */
+ /**
+ * Reads data from a local file.
+ */
+ const SOURCE_LOCAL_FILE = 1;
+ /**
+ * Reads data from a string.
+ */
+ const SOURCE_STRING = 2;
+ /**#@-*/
+
+ /**#@+
+ * @access private
+ * @see \phpseclib\Net\SCP::_send()
+ * @see \phpseclib\Net\SCP::_receive()
+ */
+ /**
+ * SSH1 is being used.
+ */
+ const MODE_SSH1 = 1;
+ /**
+ * SSH2 is being used.
+ */
+ const MODE_SSH2 = 2;
+ /**#@-*/
+
+ /**
+ * SSH Object
+ *
+ * @var object
+ * @access private
+ */
+ var $ssh;
+
+ /**
+ * Packet Size
+ *
+ * @var int
+ * @access private
+ */
+ var $packet_size;
+
+ /**
+ * Mode
+ *
+ * @var int
+ * @access private
+ */
+ var $mode;
+
+ /**
+ * Default Constructor.
+ *
+ * Connects to an SSH server
+ *
+ * @param \phpseclib\Net\SSH1|\phpseclib\Net\SSH2 $ssh
+ * @return \phpseclib\Net\SCP
+ * @access public
+ */
+ function __construct($ssh)
+ {
+ if ($ssh instanceof SSH2) {
+ $this->mode = self::MODE_SSH2;
+ } elseif ($ssh instanceof SSH1) {
+ $this->packet_size = 50000;
+ $this->mode = self::MODE_SSH1;
+ } else {
+ return;
+ }
+
+ $this->ssh = $ssh;
+ }
+
+ /**
+ * Uploads a file to the SCP server.
+ *
+ * By default, \phpseclib\Net\SCP::put() does not read from the local filesystem. $data is dumped directly into $remote_file.
+ * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SCP::get(), you will get a file, twelve bytes
+ * long, containing 'filename.ext' as its contents.
+ *
+ * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will
+ * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
+ * large $remote_file will be, as well.
+ *
+ * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
+ * care of that, yourself.
+ *
+ * @param string $remote_file
+ * @param string $data
+ * @param int $mode
+ * @param callable $callback
+ * @return bool
+ * @access public
+ */
+ function put($remote_file, $data, $mode = self::SOURCE_STRING, $callback = null)
+ {
+ if (!isset($this->ssh)) {
+ return false;
+ }
+
+ if (empty($remote_file)) {
+ user_error('remote_file cannot be blank', E_USER_NOTICE);
+ return false;
+ }
+
+ if (!$this->ssh->exec('scp -t ' . escapeshellarg($remote_file), false)) { // -t = to
+ return false;
+ }
+
+ $temp = $this->_receive();
+ if ($temp !== chr(0)) {
+ return false;
+ }
+
+ if ($this->mode == self::MODE_SSH2) {
+ $this->packet_size = $this->ssh->packet_size_client_to_server[SSH2::CHANNEL_EXEC] - 4;
+ }
+
+ $remote_file = basename($remote_file);
+
+ if ($mode == self::SOURCE_STRING) {
+ $size = strlen($data);
+ } else {
+ if (!is_file($data)) {
+ user_error("$data is not a valid file", E_USER_NOTICE);
+ return false;
+ }
+
+ $fp = @fopen($data, 'rb');
+ if (!$fp) {
+ return false;
+ }
+ $size = filesize($data);
+ }
+
+ $this->_send('C0644 ' . $size . ' ' . $remote_file . "\n");
+
+ $temp = $this->_receive();
+ if ($temp !== chr(0)) {
+ return false;
+ }
+
+ $sent = 0;
+ while ($sent < $size) {
+ $temp = $mode & self::SOURCE_STRING ? substr($data, $sent, $this->packet_size) : fread($fp, $this->packet_size);
+ $this->_send($temp);
+ $sent+= strlen($temp);
+
+ if (is_callable($callback)) {
+ call_user_func($callback, $sent);
+ }
+ }
+ $this->_close();
+
+ if ($mode != self::SOURCE_STRING) {
+ fclose($fp);
+ }
+
+ return true;
+ }
+
+ /**
+ * Downloads a file from the SCP server.
+ *
+ * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if
+ * the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the
+ * operation
+ *
+ * @param string $remote_file
+ * @param string $local_file
+ * @return mixed
+ * @access public
+ */
+ function get($remote_file, $local_file = false)
+ {
+ if (!isset($this->ssh)) {
+ return false;
+ }
+
+ if (!$this->ssh->exec('scp -f ' . escapeshellarg($remote_file), false)) { // -f = from
+ return false;
+ }
+
+ $this->_send("\0");
+
+ if (!preg_match('#(?<perms>[^ ]+) (?<size>\d+) (?<name>.+)#', rtrim($this->_receive()), $info)) {
+ return false;
+ }
+
+ $this->_send("\0");
+
+ $size = 0;
+
+ if ($local_file !== false) {
+ $fp = @fopen($local_file, 'wb');
+ if (!$fp) {
+ return false;
+ }
+ }
+
+ $content = '';
+ while ($size < $info['size']) {
+ $data = $this->_receive();
+ // SCP usually seems to split stuff out into 16k chunks
+ $size+= strlen($data);
+
+ if ($local_file === false) {
+ $content.= $data;
+ } else {
+ fputs($fp, $data);
+ }
+ }
+
+ $this->_close();
+
+ if ($local_file !== false) {
+ fclose($fp);
+ return true;
+ }
+
+ return $content;
+ }
+
+ /**
+ * Sends a packet to an SSH server
+ *
+ * @param string $data
+ * @access private
+ */
+ function _send($data)
+ {
+ switch ($this->mode) {
+ case self::MODE_SSH2:
+ $this->ssh->_send_channel_packet(SSH2::CHANNEL_EXEC, $data);
+ break;
+ case self::MODE_SSH1:
+ $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($data), $data);
+ $this->ssh->_send_binary_packet($data);
+ }
+ }
+
+ /**
+ * Receives a packet from an SSH server
+ *
+ * @return string
+ * @access private
+ */
+ function _receive()
+ {
+ switch ($this->mode) {
+ case self::MODE_SSH2:
+ return $this->ssh->_get_channel_packet(SSH2::CHANNEL_EXEC, true);
+ case self::MODE_SSH1:
+ if (!$this->ssh->bitmap) {
+ return false;
+ }
+ while (true) {
+ $response = $this->ssh->_get_binary_packet();
+ switch ($response[SSH1::RESPONSE_TYPE]) {
+ case NET_SSH1_SMSG_STDOUT_DATA:
+ if (strlen($response[SSH1::RESPONSE_DATA]) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $response[SSH1::RESPONSE_DATA]));
+ return $this->ssh->_string_shift($response[SSH1::RESPONSE_DATA], $length);
+ case NET_SSH1_SMSG_STDERR_DATA:
+ break;
+ case NET_SSH1_SMSG_EXITSTATUS:
+ $this->ssh->_send_binary_packet(chr(NET_SSH1_CMSG_EXIT_CONFIRMATION));
+ fclose($this->ssh->fsock);
+ $this->ssh->bitmap = 0;
+ return false;
+ default:
+ user_error('Unknown packet received', E_USER_NOTICE);
+ return false;
+ }
+ }
+ }
+ }
+
+ /**
+ * Closes the connection to an SSH server
+ *
+ * @access private
+ */
+ function _close()
+ {
+ switch ($this->mode) {
+ case self::MODE_SSH2:
+ $this->ssh->_close_channel(SSH2::CHANNEL_EXEC, true);
+ break;
+ case self::MODE_SSH1:
+ $this->ssh->disconnect();
+ }
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
new file mode 100644
index 0000000..bf7ef36
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php
@@ -0,0 +1,3173 @@
+<?php
+
+/**
+ * Pure-PHP implementation of SFTP.
+ *
+ * PHP version 5
+ *
+ * Currently only supports SFTPv2 and v3, which, according to wikipedia.org, "is the most widely used version,
+ * implemented by the popular OpenSSH SFTP server". If you want SFTPv4/5/6 support, provide me with access
+ * to an SFTPv4/5/6 server.
+ *
+ * The API for this library is modeled after the API from PHP's {@link http://php.net/book.ftp FTP extension}.
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $sftp = new \phpseclib\Net\SFTP('www.domain.tld');
+ * if (!$sftp->login('username', 'password')) {
+ * exit('Login Failed');
+ * }
+ *
+ * echo $sftp->pwd() . "\r\n";
+ * $sftp->put('filename.ext', 'hello, world!');
+ * print_r($sftp->nlist());
+ * ?>
+ * </code>
+ *
+ * @category Net
+ * @package SFTP
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2009 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Net;
+
+/**
+ * Pure-PHP implementations of SFTP.
+ *
+ * @package SFTP
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class SFTP extends SSH2
+{
+ /**
+ * SFTP channel constant
+ *
+ * \phpseclib\Net\SSH2::exec() uses 0 and \phpseclib\Net\SSH2::read() / \phpseclib\Net\SSH2::write() use 1.
+ *
+ * @see \phpseclib\Net\SSH2::_send_channel_packet()
+ * @see \phpseclib\Net\SSH2::_get_channel_packet()
+ * @access private
+ */
+ const CHANNEL = 0x100;
+
+ /**#@+
+ * @access public
+ * @see \phpseclib\Net\SFTP::put()
+ */
+ /**
+ * Reads data from a local file.
+ */
+ const SOURCE_LOCAL_FILE = 1;
+ /**
+ * Reads data from a string.
+ */
+ // this value isn't really used anymore but i'm keeping it reserved for historical reasons
+ const SOURCE_STRING = 2;
+ /**
+ * Reads data from callback:
+ * function callback($length) returns string to proceed, null for EOF
+ */
+ const SOURCE_CALLBACK = 16;
+ /**
+ * Resumes an upload
+ */
+ const RESUME = 4;
+ /**
+ * Append a local file to an already existing remote file
+ */
+ const RESUME_START = 8;
+ /**#@-*/
+
+ /**
+ * Packet Types
+ *
+ * @see self::__construct()
+ * @var array
+ * @access private
+ */
+ var $packet_types = array();
+
+ /**
+ * Status Codes
+ *
+ * @see self::__construct()
+ * @var array
+ * @access private
+ */
+ var $status_codes = array();
+
+ /**
+ * The Request ID
+ *
+ * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
+ * concurrent actions, so it's somewhat academic, here.
+ *
+ * @var boolean
+ * @see self::_send_sftp_packet()
+ * @access private
+ */
+ var $use_request_id = false;
+
+ /**
+ * The Packet Type
+ *
+ * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support
+ * concurrent actions, so it's somewhat academic, here.
+ *
+ * @var int
+ * @see self::_get_sftp_packet()
+ * @access private
+ */
+ var $packet_type = -1;
+
+ /**
+ * Packet Buffer
+ *
+ * @var string
+ * @see self::_get_sftp_packet()
+ * @access private
+ */
+ var $packet_buffer = '';
+
+ /**
+ * Extensions supported by the server
+ *
+ * @var array
+ * @see self::_initChannel()
+ * @access private
+ */
+ var $extensions = array();
+
+ /**
+ * Server SFTP version
+ *
+ * @var int
+ * @see self::_initChannel()
+ * @access private
+ */
+ var $version;
+
+ /**
+ * Current working directory
+ *
+ * @var string
+ * @see self::realpath()
+ * @see self::chdir()
+ * @access private
+ */
+ var $pwd = false;
+
+ /**
+ * Packet Type Log
+ *
+ * @see self::getLog()
+ * @var array
+ * @access private
+ */
+ var $packet_type_log = array();
+
+ /**
+ * Packet Log
+ *
+ * @see self::getLog()
+ * @var array
+ * @access private
+ */
+ var $packet_log = array();
+
+ /**
+ * Error information
+ *
+ * @see self::getSFTPErrors()
+ * @see self::getLastSFTPError()
+ * @var array
+ * @access private
+ */
+ var $sftp_errors = array();
+
+ /**
+ * Stat Cache
+ *
+ * Rather than always having to open a directory and close it immediately there after to see if a file is a directory
+ * we'll cache the results.
+ *
+ * @see self::_update_stat_cache()
+ * @see self::_remove_from_stat_cache()
+ * @see self::_query_stat_cache()
+ * @var array
+ * @access private
+ */
+ var $stat_cache = array();
+
+ /**
+ * Max SFTP Packet Size
+ *
+ * @see self::__construct()
+ * @see self::get()
+ * @var array
+ * @access private
+ */
+ var $max_sftp_packet;
+
+ /**
+ * Stat Cache Flag
+ *
+ * @see self::disableStatCache()
+ * @see self::enableStatCache()
+ * @var bool
+ * @access private
+ */
+ var $use_stat_cache = true;
+
+ /**
+ * Sort Options
+ *
+ * @see self::_comparator()
+ * @see self::setListOrder()
+ * @var array
+ * @access private
+ */
+ var $sortOptions = array();
+
+ /**
+ * Canonicalization Flag
+ *
+ * Determines whether or not paths should be canonicalized before being
+ * passed on to the remote server.
+ *
+ * @see self::enablePathCanonicalization()
+ * @see self::disablePathCanonicalization()
+ * @see self::realpath()
+ * @var bool
+ * @access private
+ */
+ var $canonicalize_paths = true;
+
+ /**
+ * Request Buffers
+ *
+ * @see self::_get_sftp_packet()
+ * @var array
+ * @access private
+ */
+ var $requestBuffer = array();
+
+ /**
+ * Default Constructor.
+ *
+ * Connects to an SFTP server
+ *
+ * @param string $host
+ * @param int $port
+ * @param int $timeout
+ * @return \phpseclib\Net\SFTP
+ * @access public
+ */
+ function __construct($host, $port = 22, $timeout = 10)
+ {
+ parent::__construct($host, $port, $timeout);
+
+ $this->max_sftp_packet = 1 << 15;
+
+ $this->packet_types = array(
+ 1 => 'NET_SFTP_INIT',
+ 2 => 'NET_SFTP_VERSION',
+ /* the format of SSH_FXP_OPEN changed between SFTPv4 and SFTPv5+:
+ SFTPv5+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.1
+ pre-SFTPv5 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 */
+ 3 => 'NET_SFTP_OPEN',
+ 4 => 'NET_SFTP_CLOSE',
+ 5 => 'NET_SFTP_READ',
+ 6 => 'NET_SFTP_WRITE',
+ 7 => 'NET_SFTP_LSTAT',
+ 9 => 'NET_SFTP_SETSTAT',
+ 11 => 'NET_SFTP_OPENDIR',
+ 12 => 'NET_SFTP_READDIR',
+ 13 => 'NET_SFTP_REMOVE',
+ 14 => 'NET_SFTP_MKDIR',
+ 15 => 'NET_SFTP_RMDIR',
+ 16 => 'NET_SFTP_REALPATH',
+ 17 => 'NET_SFTP_STAT',
+ /* the format of SSH_FXP_RENAME changed between SFTPv4 and SFTPv5+:
+ SFTPv5+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3
+ pre-SFTPv5 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.5 */
+ 18 => 'NET_SFTP_RENAME',
+ 19 => 'NET_SFTP_READLINK',
+ 20 => 'NET_SFTP_SYMLINK',
+
+ 101=> 'NET_SFTP_STATUS',
+ 102=> 'NET_SFTP_HANDLE',
+ /* the format of SSH_FXP_NAME changed between SFTPv3 and SFTPv4+:
+ SFTPv4+: http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.4
+ pre-SFTPv4 : http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-7 */
+ 103=> 'NET_SFTP_DATA',
+ 104=> 'NET_SFTP_NAME',
+ 105=> 'NET_SFTP_ATTRS',
+
+ 200=> 'NET_SFTP_EXTENDED'
+ );
+ $this->status_codes = array(
+ 0 => 'NET_SFTP_STATUS_OK',
+ 1 => 'NET_SFTP_STATUS_EOF',
+ 2 => 'NET_SFTP_STATUS_NO_SUCH_FILE',
+ 3 => 'NET_SFTP_STATUS_PERMISSION_DENIED',
+ 4 => 'NET_SFTP_STATUS_FAILURE',
+ 5 => 'NET_SFTP_STATUS_BAD_MESSAGE',
+ 6 => 'NET_SFTP_STATUS_NO_CONNECTION',
+ 7 => 'NET_SFTP_STATUS_CONNECTION_LOST',
+ 8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED',
+ 9 => 'NET_SFTP_STATUS_INVALID_HANDLE',
+ 10 => 'NET_SFTP_STATUS_NO_SUCH_PATH',
+ 11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS',
+ 12 => 'NET_SFTP_STATUS_WRITE_PROTECT',
+ 13 => 'NET_SFTP_STATUS_NO_MEDIA',
+ 14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM',
+ 15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED',
+ 16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL',
+ 17 => 'NET_SFTP_STATUS_LOCK_CONFLICT',
+ 18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY',
+ 19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY',
+ 20 => 'NET_SFTP_STATUS_INVALID_FILENAME',
+ 21 => 'NET_SFTP_STATUS_LINK_LOOP',
+ 22 => 'NET_SFTP_STATUS_CANNOT_DELETE',
+ 23 => 'NET_SFTP_STATUS_INVALID_PARAMETER',
+ 24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY',
+ 25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT',
+ 26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED',
+ 27 => 'NET_SFTP_STATUS_DELETE_PENDING',
+ 28 => 'NET_SFTP_STATUS_FILE_CORRUPT',
+ 29 => 'NET_SFTP_STATUS_OWNER_INVALID',
+ 30 => 'NET_SFTP_STATUS_GROUP_INVALID',
+ 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK'
+ );
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1
+ // the order, in this case, matters quite a lot - see \phpseclib\Net\SFTP::_parseAttributes() to understand why
+ $this->attributes = array(
+ 0x00000001 => 'NET_SFTP_ATTR_SIZE',
+ 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+
+ 0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS',
+ 0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME',
+ // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers
+ // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in
+ // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000.
+ // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored.
+ (-1 << 31) & 0xFFFFFFFF => 'NET_SFTP_ATTR_EXTENDED'
+ );
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3
+ // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name
+ // the array for that $this->open5_flags and similarly alter the constant names.
+ $this->open_flags = array(
+ 0x00000001 => 'NET_SFTP_OPEN_READ',
+ 0x00000002 => 'NET_SFTP_OPEN_WRITE',
+ 0x00000004 => 'NET_SFTP_OPEN_APPEND',
+ 0x00000008 => 'NET_SFTP_OPEN_CREATE',
+ 0x00000010 => 'NET_SFTP_OPEN_TRUNCATE',
+ 0x00000020 => 'NET_SFTP_OPEN_EXCL'
+ );
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2
+ // see \phpseclib\Net\SFTP::_parseLongname() for an explanation
+ $this->file_types = array(
+ 1 => 'NET_SFTP_TYPE_REGULAR',
+ 2 => 'NET_SFTP_TYPE_DIRECTORY',
+ 3 => 'NET_SFTP_TYPE_SYMLINK',
+ 4 => 'NET_SFTP_TYPE_SPECIAL',
+ 5 => 'NET_SFTP_TYPE_UNKNOWN',
+ // the followin types were first defined for use in SFTPv5+
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2
+ 6 => 'NET_SFTP_TYPE_SOCKET',
+ 7 => 'NET_SFTP_TYPE_CHAR_DEVICE',
+ 8 => 'NET_SFTP_TYPE_BLOCK_DEVICE',
+ 9 => 'NET_SFTP_TYPE_FIFO'
+ );
+ $this->_define_array(
+ $this->packet_types,
+ $this->status_codes,
+ $this->attributes,
+ $this->open_flags,
+ $this->file_types
+ );
+
+ if (!defined('NET_SFTP_QUEUE_SIZE')) {
+ define('NET_SFTP_QUEUE_SIZE', 32);
+ }
+ if (!defined('NET_SFTP_UPLOAD_QUEUE_SIZE')) {
+ define('NET_SFTP_UPLOAD_QUEUE_SIZE', 1024);
+ }
+ }
+
+ /**
+ * Login
+ *
+ * @param string $username
+ * @param string $password
+ * @return bool
+ * @access public
+ */
+ function login($username)
+ {
+ if (!call_user_func_array('parent::login', func_get_args())) {
+ return false;
+ }
+
+ $this->window_size_server_to_client[self::CHANNEL] = $this->window_size;
+
+ $packet = pack(
+ 'CNa*N3',
+ NET_SSH2_MSG_CHANNEL_OPEN,
+ strlen('session'),
+ 'session',
+ self::CHANNEL,
+ $this->window_size,
+ 0x4000
+ );
+
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_OPEN;
+
+ $response = $this->_get_channel_packet(self::CHANNEL, true);
+ if ($response === false) {
+ return false;
+ }
+
+ $packet = pack(
+ 'CNNa*CNa*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL],
+ strlen('subsystem'),
+ 'subsystem',
+ 1,
+ strlen('sftp'),
+ 'sftp'
+ );
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+ $response = $this->_get_channel_packet(self::CHANNEL, true);
+ if ($response === false) {
+ // from PuTTY's psftp.exe
+ $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" .
+ "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n" .
+ "exec sftp-server";
+ // we don't do $this->exec($command, false) because exec() operates on a different channel and plus the SSH_MSG_CHANNEL_OPEN that exec() does
+ // is redundant
+ $packet = pack(
+ 'CNNa*CNa*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL],
+ strlen('exec'),
+ 'exec',
+ 1,
+ strlen($command),
+ $command
+ );
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+ $response = $this->_get_channel_packet(self::CHANNEL, true);
+ if ($response === false) {
+ return false;
+ }
+ }
+
+ $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA;
+
+ if (!$this->_send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3")) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ if ($this->packet_type != NET_SFTP_VERSION) {
+ user_error('Expected SSH_FXP_VERSION');
+ return false;
+ }
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nversion', $this->_string_shift($response, 4)));
+ $this->version = $version;
+ while (!empty($response)) {
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $key = $this->_string_shift($response, $length);
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $value = $this->_string_shift($response, $length);
+ $this->extensions[$key] = $value;
+ }
+
+ /*
+ SFTPv4+ defines a 'newline' extension. SFTPv3 seems to have unofficial support for it via 'newline@vandyke.com',
+ however, I'm not sure what 'newline@vandyke.com' is supposed to do (the fact that it's unofficial means that it's
+ not in the official SFTPv3 specs) and 'newline@vandyke.com' / 'newline' are likely not drop-in substitutes for
+ one another due to the fact that 'newline' comes with a SSH_FXF_TEXT bitmask whereas it seems unlikely that
+ 'newline@vandyke.com' would.
+ */
+ /*
+ if (isset($this->extensions['newline@vandyke.com'])) {
+ $this->extensions['newline'] = $this->extensions['newline@vandyke.com'];
+ unset($this->extensions['newline@vandyke.com']);
+ }
+ */
+
+ $this->use_request_id = true;
+
+ /*
+ A Note on SFTPv4/5/6 support:
+ <http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-5.1> states the following:
+
+ "If the client wishes to interoperate with servers that support noncontiguous version
+ numbers it SHOULD send '3'"
+
+ Given that the server only sends its version number after the client has already done so, the above
+ seems to be suggesting that v3 should be the default version. This makes sense given that v3 is the
+ most popular.
+
+ <http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-5.5> states the following;
+
+ "If the server did not send the "versions" extension, or the version-from-list was not included, the
+ server MAY send a status response describing the failure, but MUST then close the channel without
+ processing any further requests."
+
+ So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and
+ a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4? If it only implements
+ v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed
+ in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what \phpseclib\Net\SFTP would do is close the
+ channel and reopen it with a new and updated SSH_FXP_INIT packet.
+ */
+ switch ($this->version) {
+ case 2:
+ case 3:
+ break;
+ default:
+ return false;
+ }
+
+ $this->pwd = $this->_realpath('.');
+
+ $this->_update_stat_cache($this->pwd, array());
+
+ return true;
+ }
+
+ /**
+ * Disable the stat cache
+ *
+ * @access public
+ */
+ function disableStatCache()
+ {
+ $this->use_stat_cache = false;
+ }
+
+ /**
+ * Enable the stat cache
+ *
+ * @access public
+ */
+ function enableStatCache()
+ {
+ $this->use_stat_cache = true;
+ }
+
+ /**
+ * Clear the stat cache
+ *
+ * @access public
+ */
+ function clearStatCache()
+ {
+ $this->stat_cache = array();
+ }
+
+ /**
+ * Enable path canonicalization
+ *
+ * @access public
+ */
+ function enablePathCanonicalization()
+ {
+ $this->canonicalize_paths = true;
+ }
+
+ /**
+ * Enable path canonicalization
+ *
+ * @access public
+ */
+ function disablePathCanonicalization()
+ {
+ $this->canonicalize_paths = false;
+ }
+
+ /**
+ * Returns the current directory name
+ *
+ * @return mixed
+ * @access public
+ */
+ function pwd()
+ {
+ return $this->pwd;
+ }
+
+ /**
+ * Logs errors
+ *
+ * @param string $response
+ * @param int $status
+ * @access public
+ */
+ function _logError($response, $status = -1)
+ {
+ if ($status == -1) {
+ if (strlen($response) < 4) {
+ return;
+ }
+ extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+ }
+
+ $error = $this->status_codes[$status];
+
+ if ($this->version > 2 || strlen($response) < 4) {
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $this->sftp_errors[] = $error . ': ' . $this->_string_shift($response, $length);
+ } else {
+ $this->sftp_errors[] = $error;
+ }
+ }
+
+ /**
+ * Returns canonicalized absolute pathname
+ *
+ * realpath() expands all symbolic links and resolves references to '/./', '/../' and extra '/' characters in the input
+ * path and returns the canonicalized absolute pathname.
+ *
+ * @param string $path
+ * @return mixed
+ * @access public
+ */
+ function realpath($path)
+ {
+ return $this->_realpath($path);
+ }
+
+ /**
+ * Canonicalize the Server-Side Path Name
+ *
+ * SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns
+ * the absolute (canonicalized) path.
+ *
+ * If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is.
+ *
+ * @see self::chdir()
+ * @see self::disablePathCanonicalization()
+ * @param string $path
+ * @return mixed
+ * @access private
+ */
+ function _realpath($path)
+ {
+ if (!$this->canonicalize_paths) {
+ return $path;
+ }
+
+ if ($this->pwd === false) {
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9
+ if (!$this->_send_sftp_packet(NET_SFTP_REALPATH, pack('Na*', strlen($path), $path))) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_NAME:
+ // although SSH_FXP_NAME is implemented differently in SFTPv3 than it is in SFTPv4+, the following
+ // should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks
+ // at is the first part and that part is defined the same in SFTP versions 3 through 6.
+ $this->_string_shift($response, 4); // skip over the count - it should be 1, anyway
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ return $this->_string_shift($response, $length);
+ case NET_SFTP_STATUS:
+ $this->_logError($response);
+ return false;
+ default:
+ user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
+ return false;
+ }
+ }
+
+ if ($path[0] != '/') {
+ $path = $this->pwd . '/' . $path;
+ }
+
+ $path = explode('/', $path);
+ $new = array();
+ foreach ($path as $dir) {
+ if (!strlen($dir)) {
+ continue;
+ }
+ switch ($dir) {
+ case '..':
+ array_pop($new);
+ case '.':
+ break;
+ default:
+ $new[] = $dir;
+ }
+ }
+
+ return '/' . implode('/', $new);
+ }
+
+ /**
+ * Changes the current directory
+ *
+ * @param string $dir
+ * @return bool
+ * @access public
+ */
+ function chdir($dir)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ // assume current dir if $dir is empty
+ if ($dir === '') {
+ $dir = './';
+ // suffix a slash if needed
+ } elseif ($dir[strlen($dir) - 1] != '/') {
+ $dir.= '/';
+ }
+
+ $dir = $this->_realpath($dir);
+
+ // confirm that $dir is, in fact, a valid directory
+ if ($this->use_stat_cache && is_array($this->_query_stat_cache($dir))) {
+ $this->pwd = $dir;
+ return true;
+ }
+
+ // we could do a stat on the alleged $dir to see if it's a directory but that doesn't tell us
+ // the currently logged in user has the appropriate permissions or not. maybe you could see if
+ // the file's uid / gid match the currently logged in user's uid / gid but how there's no easy
+ // way to get those with SFTP
+
+ if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) {
+ return false;
+ }
+
+ // see \phpseclib\Net\SFTP::nlist() for a more thorough explanation of the following
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_HANDLE:
+ $handle = substr($response, 4);
+ break;
+ case NET_SFTP_STATUS:
+ $this->_logError($response);
+ return false;
+ default:
+ user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+ return false;
+ }
+
+ if (!$this->_close_handle($handle)) {
+ return false;
+ }
+
+ $this->_update_stat_cache($dir, array());
+
+ $this->pwd = $dir;
+ return true;
+ }
+
+ /**
+ * Returns a list of files in the given directory
+ *
+ * @param string $dir
+ * @param bool $recursive
+ * @return mixed
+ * @access public
+ */
+ function nlist($dir = '.', $recursive = false)
+ {
+ return $this->_nlist_helper($dir, $recursive, '');
+ }
+
+ /**
+ * Helper method for nlist
+ *
+ * @param string $dir
+ * @param bool $recursive
+ * @param string $relativeDir
+ * @return mixed
+ * @access private
+ */
+ function _nlist_helper($dir, $recursive, $relativeDir)
+ {
+ $files = $this->_list($dir, false);
+
+ if (!$recursive || $files === false) {
+ return $files;
+ }
+
+ $result = array();
+ foreach ($files as $value) {
+ if ($value == '.' || $value == '..') {
+ if ($relativeDir == '') {
+ $result[] = $value;
+ }
+ continue;
+ }
+ if (is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $value)))) {
+ $temp = $this->_nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/');
+ $temp = is_array($temp) ? $temp : array();
+ $result = array_merge($result, $temp);
+ } else {
+ $result[] = $relativeDir . $value;
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns a detailed list of files in the given directory
+ *
+ * @param string $dir
+ * @param bool $recursive
+ * @return mixed
+ * @access public
+ */
+ function rawlist($dir = '.', $recursive = false)
+ {
+ $files = $this->_list($dir, true);
+ if (!$recursive || $files === false) {
+ return $files;
+ }
+
+ static $depth = 0;
+
+ foreach ($files as $key => $value) {
+ if ($depth != 0 && $key == '..') {
+ unset($files[$key]);
+ continue;
+ }
+ $is_directory = false;
+ if ($key != '.' && $key != '..') {
+ if ($this->use_stat_cache) {
+ $is_directory = is_array($this->_query_stat_cache($this->_realpath($dir . '/' . $key)));
+ } else {
+ $stat = $this->lstat($dir . '/' . $key);
+ $is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY;
+ }
+ }
+
+ if ($is_directory) {
+ $depth++;
+ $files[$key] = $this->rawlist($dir . '/' . $key, true);
+ $depth--;
+ } else {
+ $files[$key] = (object) $value;
+ }
+ }
+
+ return $files;
+ }
+
+ /**
+ * Reads a list, be it detailed or not, of files in the given directory
+ *
+ * @param string $dir
+ * @param bool $raw
+ * @return mixed
+ * @access private
+ */
+ function _list($dir, $raw = true)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $dir = $this->_realpath($dir . '/');
+ if ($dir === false) {
+ return false;
+ }
+
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.2
+ if (!$this->_send_sftp_packet(NET_SFTP_OPENDIR, pack('Na*', strlen($dir), $dir))) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_HANDLE:
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.2
+ // since 'handle' is the last field in the SSH_FXP_HANDLE packet, we'll just remove the first four bytes that
+ // represent the length of the string and leave it at that
+ $handle = substr($response, 4);
+ break;
+ case NET_SFTP_STATUS:
+ // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+ $this->_logError($response);
+ return false;
+ default:
+ user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+ return false;
+ }
+
+ $this->_update_stat_cache($dir, array());
+
+ $contents = array();
+ while (true) {
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.2
+ // why multiple SSH_FXP_READDIR packets would be sent when the response to a single one can span arbitrarily many
+ // SSH_MSG_CHANNEL_DATA messages is not known to me.
+ if (!$this->_send_sftp_packet(NET_SFTP_READDIR, pack('Na*', strlen($handle), $handle))) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_NAME:
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Ncount', $this->_string_shift($response, 4)));
+ for ($i = 0; $i < $count; $i++) {
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $shortname = $this->_string_shift($response, $length);
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $longname = $this->_string_shift($response, $length);
+ $attributes = $this->_parseAttributes($response);
+ if (!isset($attributes['type'])) {
+ $fileType = $this->_parseLongname($longname);
+ if ($fileType) {
+ $attributes['type'] = $fileType;
+ }
+ }
+ $contents[$shortname] = $attributes + array('filename' => $shortname);
+
+ if (isset($attributes['type']) && $attributes['type'] == NET_SFTP_TYPE_DIRECTORY && ($shortname != '.' && $shortname != '..')) {
+ $this->_update_stat_cache($dir . '/' . $shortname, array());
+ } else {
+ if ($shortname == '..') {
+ $temp = $this->_realpath($dir . '/..') . '/.';
+ } else {
+ $temp = $dir . '/' . $shortname;
+ }
+ $this->_update_stat_cache($temp, (object) array('lstat' => $attributes));
+ }
+ // SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the
+ // final SSH_FXP_STATUS packet should tell us that, already.
+ }
+ break;
+ case NET_SFTP_STATUS:
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+ if ($status != NET_SFTP_STATUS_EOF) {
+ $this->_logError($response, $status);
+ return false;
+ }
+ break 2;
+ default:
+ user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
+ return false;
+ }
+ }
+
+ if (!$this->_close_handle($handle)) {
+ return false;
+ }
+
+ if (count($this->sortOptions)) {
+ uasort($contents, array(&$this, '_comparator'));
+ }
+
+ return $raw ? $contents : array_keys($contents);
+ }
+
+ /**
+ * Compares two rawlist entries using parameters set by setListOrder()
+ *
+ * Intended for use with uasort()
+ *
+ * @param array $a
+ * @param array $b
+ * @return int
+ * @access private
+ */
+ function _comparator($a, $b)
+ {
+ switch (true) {
+ case $a['filename'] === '.' || $b['filename'] === '.':
+ if ($a['filename'] === $b['filename']) {
+ return 0;
+ }
+ return $a['filename'] === '.' ? -1 : 1;
+ case $a['filename'] === '..' || $b['filename'] === '..':
+ if ($a['filename'] === $b['filename']) {
+ return 0;
+ }
+ return $a['filename'] === '..' ? -1 : 1;
+ case isset($a['type']) && $a['type'] === NET_SFTP_TYPE_DIRECTORY:
+ if (!isset($b['type'])) {
+ return 1;
+ }
+ if ($b['type'] !== $a['type']) {
+ return -1;
+ }
+ break;
+ case isset($b['type']) && $b['type'] === NET_SFTP_TYPE_DIRECTORY:
+ return 1;
+ }
+ foreach ($this->sortOptions as $sort => $order) {
+ if (!isset($a[$sort]) || !isset($b[$sort])) {
+ if (isset($a[$sort])) {
+ return -1;
+ }
+ if (isset($b[$sort])) {
+ return 1;
+ }
+ return 0;
+ }
+ switch ($sort) {
+ case 'filename':
+ $result = strcasecmp($a['filename'], $b['filename']);
+ if ($result) {
+ return $order === SORT_DESC ? -$result : $result;
+ }
+ break;
+ case 'permissions':
+ case 'mode':
+ $a[$sort]&= 07777;
+ $b[$sort]&= 07777;
+ default:
+ if ($a[$sort] === $b[$sort]) {
+ break;
+ }
+ return $order === SORT_ASC ? $a[$sort] - $b[$sort] : $b[$sort] - $a[$sort];
+ }
+ }
+ }
+
+ /**
+ * Defines how nlist() and rawlist() will be sorted - if at all.
+ *
+ * If sorting is enabled directories and files will be sorted independently with
+ * directories appearing before files in the resultant array that is returned.
+ *
+ * Any parameter returned by stat is a valid sort parameter for this function.
+ * Filename comparisons are case insensitive.
+ *
+ * Examples:
+ *
+ * $sftp->setListOrder('filename', SORT_ASC);
+ * $sftp->setListOrder('size', SORT_DESC, 'filename', SORT_ASC);
+ * $sftp->setListOrder(true);
+ * Separates directories from files but doesn't do any sorting beyond that
+ * $sftp->setListOrder();
+ * Don't do any sort of sorting
+ *
+ * @access public
+ */
+ function setListOrder()
+ {
+ $this->sortOptions = array();
+ $args = func_get_args();
+ if (empty($args)) {
+ return;
+ }
+ $len = count($args) & 0x7FFFFFFE;
+ for ($i = 0; $i < $len; $i+=2) {
+ $this->sortOptions[$args[$i]] = $args[$i + 1];
+ }
+ if (!count($this->sortOptions)) {
+ $this->sortOptions = array('bogus' => true);
+ }
+ }
+
+ /**
+ * Returns the file size, in bytes, or false, on failure
+ *
+ * Files larger than 4GB will show up as being exactly 4GB.
+ *
+ * @param string $filename
+ * @return mixed
+ * @access public
+ */
+ function size($filename)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $result = $this->stat($filename);
+ if ($result === false) {
+ return false;
+ }
+ return isset($result['size']) ? $result['size'] : -1;
+ }
+
+ /**
+ * Save files / directories to cache
+ *
+ * @param string $path
+ * @param mixed $value
+ * @access private
+ */
+ function _update_stat_cache($path, $value)
+ {
+ if ($this->use_stat_cache === false) {
+ return;
+ }
+
+ // preg_replace('#^/|/(?=/)|/$#', '', $dir) == str_replace('//', '/', trim($path, '/'))
+ $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path));
+
+ $temp = &$this->stat_cache;
+ $max = count($dirs) - 1;
+ foreach ($dirs as $i => $dir) {
+ // if $temp is an object that means one of two things.
+ // 1. a file was deleted and changed to a directory behind phpseclib's back
+ // 2. it's a symlink. when lstat is done it's unclear what it's a symlink to
+ if (is_object($temp)) {
+ $temp = array();
+ }
+ if (!isset($temp[$dir])) {
+ $temp[$dir] = array();
+ }
+ if ($i === $max) {
+ if (is_object($temp[$dir]) && is_object($value)) {
+ if (!isset($value->stat) && isset($temp[$dir]->stat)) {
+ $value->stat = $temp[$dir]->stat;
+ }
+ if (!isset($value->lstat) && isset($temp[$dir]->lstat)) {
+ $value->lstat = $temp[$dir]->lstat;
+ }
+ }
+ $temp[$dir] = $value;
+ break;
+ }
+ $temp = &$temp[$dir];
+ }
+ }
+
+ /**
+ * Remove files / directories from cache
+ *
+ * @param string $path
+ * @return bool
+ * @access private
+ */
+ function _remove_from_stat_cache($path)
+ {
+ $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path));
+
+ $temp = &$this->stat_cache;
+ $max = count($dirs) - 1;
+ foreach ($dirs as $i => $dir) {
+ if ($i === $max) {
+ unset($temp[$dir]);
+ return true;
+ }
+ if (!isset($temp[$dir])) {
+ return false;
+ }
+ $temp = &$temp[$dir];
+ }
+ }
+
+ /**
+ * Checks cache for path
+ *
+ * Mainly used by file_exists
+ *
+ * @param string $dir
+ * @return mixed
+ * @access private
+ */
+ function _query_stat_cache($path)
+ {
+ $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path));
+
+ $temp = &$this->stat_cache;
+ foreach ($dirs as $dir) {
+ if (!isset($temp[$dir])) {
+ return null;
+ }
+ $temp = &$temp[$dir];
+ }
+ return $temp;
+ }
+
+ /**
+ * Returns general information about a file.
+ *
+ * Returns an array on success and false otherwise.
+ *
+ * @param string $filename
+ * @return mixed
+ * @access public
+ */
+ function stat($filename)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $filename = $this->_realpath($filename);
+ if ($filename === false) {
+ return false;
+ }
+
+ if ($this->use_stat_cache) {
+ $result = $this->_query_stat_cache($filename);
+ if (is_array($result) && isset($result['.']) && isset($result['.']->stat)) {
+ return $result['.']->stat;
+ }
+ if (is_object($result) && isset($result->stat)) {
+ return $result->stat;
+ }
+ }
+
+ $stat = $this->_stat($filename, NET_SFTP_STAT);
+ if ($stat === false) {
+ $this->_remove_from_stat_cache($filename);
+ return false;
+ }
+ if (isset($stat['type'])) {
+ if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) {
+ $filename.= '/.';
+ }
+ $this->_update_stat_cache($filename, (object) array('stat' => $stat));
+ return $stat;
+ }
+
+ $pwd = $this->pwd;
+ $stat['type'] = $this->chdir($filename) ?
+ NET_SFTP_TYPE_DIRECTORY :
+ NET_SFTP_TYPE_REGULAR;
+ $this->pwd = $pwd;
+
+ if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) {
+ $filename.= '/.';
+ }
+ $this->_update_stat_cache($filename, (object) array('stat' => $stat));
+
+ return $stat;
+ }
+
+ /**
+ * Returns general information about a file or symbolic link.
+ *
+ * Returns an array on success and false otherwise.
+ *
+ * @param string $filename
+ * @return mixed
+ * @access public
+ */
+ function lstat($filename)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $filename = $this->_realpath($filename);
+ if ($filename === false) {
+ return false;
+ }
+
+ if ($this->use_stat_cache) {
+ $result = $this->_query_stat_cache($filename);
+ if (is_array($result) && isset($result['.']) && isset($result['.']->lstat)) {
+ return $result['.']->lstat;
+ }
+ if (is_object($result) && isset($result->lstat)) {
+ return $result->lstat;
+ }
+ }
+
+ $lstat = $this->_stat($filename, NET_SFTP_LSTAT);
+ if ($lstat === false) {
+ $this->_remove_from_stat_cache($filename);
+ return false;
+ }
+ if (isset($lstat['type'])) {
+ if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) {
+ $filename.= '/.';
+ }
+ $this->_update_stat_cache($filename, (object) array('lstat' => $lstat));
+ return $lstat;
+ }
+
+ $stat = $this->_stat($filename, NET_SFTP_STAT);
+
+ if ($lstat != $stat) {
+ $lstat = array_merge($lstat, array('type' => NET_SFTP_TYPE_SYMLINK));
+ $this->_update_stat_cache($filename, (object) array('lstat' => $lstat));
+ return $stat;
+ }
+
+ $pwd = $this->pwd;
+ $lstat['type'] = $this->chdir($filename) ?
+ NET_SFTP_TYPE_DIRECTORY :
+ NET_SFTP_TYPE_REGULAR;
+ $this->pwd = $pwd;
+
+ if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) {
+ $filename.= '/.';
+ }
+ $this->_update_stat_cache($filename, (object) array('lstat' => $lstat));
+
+ return $lstat;
+ }
+
+ /**
+ * Returns general information about a file or symbolic link
+ *
+ * Determines information without calling \phpseclib\Net\SFTP::realpath().
+ * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT.
+ *
+ * @param string $filename
+ * @param int $type
+ * @return mixed
+ * @access private
+ */
+ function _stat($filename, $type)
+ {
+ // SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
+ $packet = pack('Na*', strlen($filename), $filename);
+ if (!$this->_send_sftp_packet($type, $packet)) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_ATTRS:
+ return $this->_parseAttributes($response);
+ case NET_SFTP_STATUS:
+ $this->_logError($response);
+ return false;
+ }
+
+ user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
+ return false;
+ }
+
+ /**
+ * Truncates a file to a given length
+ *
+ * @param string $filename
+ * @param int $new_size
+ * @return bool
+ * @access public
+ */
+ function truncate($filename, $new_size)
+ {
+ $attr = pack('N3', NET_SFTP_ATTR_SIZE, $new_size / 4294967296, $new_size); // 4294967296 == 0x100000000 == 1<<32
+
+ return $this->_setstat($filename, $attr, false);
+ }
+
+ /**
+ * Sets access and modification time of file.
+ *
+ * If the file does not exist, it will be created.
+ *
+ * @param string $filename
+ * @param int $time
+ * @param int $atime
+ * @return bool
+ * @access public
+ */
+ function touch($filename, $time = null, $atime = null)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $filename = $this->_realpath($filename);
+ if ($filename === false) {
+ return false;
+ }
+
+ if (!isset($time)) {
+ $time = time();
+ }
+ if (!isset($atime)) {
+ $atime = $time;
+ }
+
+ $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE | NET_SFTP_OPEN_EXCL;
+ $attr = pack('N3', NET_SFTP_ATTR_ACCESSTIME, $time, $atime);
+ $packet = pack('Na*Na*', strlen($filename), $filename, $flags, $attr);
+ if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_HANDLE:
+ return $this->_close_handle(substr($response, 4));
+ case NET_SFTP_STATUS:
+ $this->_logError($response);
+ break;
+ default:
+ user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+ return false;
+ }
+
+ return $this->_setstat($filename, $attr, false);
+ }
+
+ /**
+ * Changes file or directory owner
+ *
+ * Returns true on success or false on error.
+ *
+ * @param string $filename
+ * @param int $uid
+ * @param bool $recursive
+ * @return bool
+ * @access public
+ */
+ function chown($filename, $uid, $recursive = false)
+ {
+ // quoting from <http://www.kernel.org/doc/man-pages/online/pages/man2/chown.2.html>,
+ // "if the owner or group is specified as -1, then that ID is not changed"
+ $attr = pack('N3', NET_SFTP_ATTR_UIDGID, $uid, -1);
+
+ return $this->_setstat($filename, $attr, $recursive);
+ }
+
+ /**
+ * Changes file or directory group
+ *
+ * Returns true on success or false on error.
+ *
+ * @param string $filename
+ * @param int $gid
+ * @param bool $recursive
+ * @return bool
+ * @access public
+ */
+ function chgrp($filename, $gid, $recursive = false)
+ {
+ $attr = pack('N3', NET_SFTP_ATTR_UIDGID, -1, $gid);
+
+ return $this->_setstat($filename, $attr, $recursive);
+ }
+
+ /**
+ * Set permissions on a file.
+ *
+ * Returns the new file permissions on success or false on error.
+ * If $recursive is true than this just returns true or false.
+ *
+ * @param int $mode
+ * @param string $filename
+ * @param bool $recursive
+ * @return mixed
+ * @access public
+ */
+ function chmod($mode, $filename, $recursive = false)
+ {
+ if (is_string($mode) && is_int($filename)) {
+ $temp = $mode;
+ $mode = $filename;
+ $filename = $temp;
+ }
+
+ $attr = pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777);
+ if (!$this->_setstat($filename, $attr, $recursive)) {
+ return false;
+ }
+ if ($recursive) {
+ return true;
+ }
+
+ $filename = $this->realpath($filename);
+ // rather than return what the permissions *should* be, we'll return what they actually are. this will also
+ // tell us if the file actually exists.
+ // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following:
+ $packet = pack('Na*', strlen($filename), $filename);
+ if (!$this->_send_sftp_packet(NET_SFTP_STAT, $packet)) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_ATTRS:
+ $attrs = $this->_parseAttributes($response);
+ return $attrs['permissions'];
+ case NET_SFTP_STATUS:
+ $this->_logError($response);
+ return false;
+ }
+
+ user_error('Expected SSH_FXP_ATTRS or SSH_FXP_STATUS');
+ return false;
+ }
+
+ /**
+ * Sets information about a file
+ *
+ * @param string $filename
+ * @param string $attr
+ * @param bool $recursive
+ * @return bool
+ * @access private
+ */
+ function _setstat($filename, $attr, $recursive)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $filename = $this->_realpath($filename);
+ if ($filename === false) {
+ return false;
+ }
+
+ $this->_remove_from_stat_cache($filename);
+
+ if ($recursive) {
+ $i = 0;
+ $result = $this->_setstat_recursive($filename, $attr, $i);
+ $this->_read_put_responses($i);
+ return $result;
+ }
+
+ // SFTPv4+ has an additional byte field - type - that would need to be sent, as well. setting it to
+ // SSH_FILEXFER_TYPE_UNKNOWN might work. if not, we'd have to do an SSH_FXP_STAT before doing an SSH_FXP_SETSTAT.
+ if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, pack('Na*a*', strlen($filename), $filename, $attr))) {
+ return false;
+ }
+
+ /*
+ "Because some systems must use separate system calls to set various attributes, it is possible that a failure
+ response will be returned, but yet some of the attributes may be have been successfully modified. If possible,
+ servers SHOULD avoid this situation; however, clients MUST be aware that this is possible."
+
+ -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6
+ */
+ $response = $this->_get_sftp_packet();
+ if ($this->packet_type != NET_SFTP_STATUS) {
+ user_error('Expected SSH_FXP_STATUS');
+ return false;
+ }
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+ if ($status != NET_SFTP_STATUS_OK) {
+ $this->_logError($response, $status);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Recursively sets information on directories on the SFTP server
+ *
+ * Minimizes directory lookups and SSH_FXP_STATUS requests for speed.
+ *
+ * @param string $path
+ * @param string $attr
+ * @param int $i
+ * @return bool
+ * @access private
+ */
+ function _setstat_recursive($path, $attr, &$i)
+ {
+ if (!$this->_read_put_responses($i)) {
+ return false;
+ }
+ $i = 0;
+ $entries = $this->_list($path, true);
+
+ if ($entries === false) {
+ return $this->_setstat($path, $attr, false);
+ }
+
+ // normally $entries would have at least . and .. but it might not if the directories
+ // permissions didn't allow reading
+ if (empty($entries)) {
+ return false;
+ }
+
+ unset($entries['.'], $entries['..']);
+ foreach ($entries as $filename => $props) {
+ if (!isset($props['type'])) {
+ return false;
+ }
+
+ $temp = $path . '/' . $filename;
+ if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) {
+ if (!$this->_setstat_recursive($temp, $attr, $i)) {
+ return false;
+ }
+ } else {
+ if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, pack('Na*a*', strlen($temp), $temp, $attr))) {
+ return false;
+ }
+
+ $i++;
+
+ if ($i >= NET_SFTP_QUEUE_SIZE) {
+ if (!$this->_read_put_responses($i)) {
+ return false;
+ }
+ $i = 0;
+ }
+ }
+ }
+
+ if (!$this->_send_sftp_packet(NET_SFTP_SETSTAT, pack('Na*a*', strlen($path), $path, $attr))) {
+ return false;
+ }
+
+ $i++;
+
+ if ($i >= NET_SFTP_QUEUE_SIZE) {
+ if (!$this->_read_put_responses($i)) {
+ return false;
+ }
+ $i = 0;
+ }
+
+ return true;
+ }
+
+ /**
+ * Return the target of a symbolic link
+ *
+ * @param string $link
+ * @return mixed
+ * @access public
+ */
+ function readlink($link)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $link = $this->_realpath($link);
+
+ if (!$this->_send_sftp_packet(NET_SFTP_READLINK, pack('Na*', strlen($link), $link))) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_NAME:
+ break;
+ case NET_SFTP_STATUS:
+ $this->_logError($response);
+ return false;
+ default:
+ user_error('Expected SSH_FXP_NAME or SSH_FXP_STATUS');
+ return false;
+ }
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Ncount', $this->_string_shift($response, 4)));
+ // the file isn't a symlink
+ if (!$count) {
+ return false;
+ }
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ return $this->_string_shift($response, $length);
+ }
+
+ /**
+ * Create a symlink
+ *
+ * symlink() creates a symbolic link to the existing target with the specified name link.
+ *
+ * @param string $target
+ * @param string $link
+ * @return bool
+ * @access public
+ */
+ function symlink($target, $link)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ //$target = $this->_realpath($target);
+ $link = $this->_realpath($link);
+
+ $packet = pack('Na*Na*', strlen($target), $target, strlen($link), $link);
+ if (!$this->_send_sftp_packet(NET_SFTP_SYMLINK, $packet)) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ if ($this->packet_type != NET_SFTP_STATUS) {
+ user_error('Expected SSH_FXP_STATUS');
+ return false;
+ }
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+ if ($status != NET_SFTP_STATUS_OK) {
+ $this->_logError($response, $status);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Creates a directory.
+ *
+ * @param string $dir
+ * @return bool
+ * @access public
+ */
+ function mkdir($dir, $mode = -1, $recursive = false)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $dir = $this->_realpath($dir);
+
+ if ($recursive) {
+ $dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir));
+ if (empty($dirs[0])) {
+ array_shift($dirs);
+ $dirs[0] = '/' . $dirs[0];
+ }
+ for ($i = 0; $i < count($dirs); $i++) {
+ $temp = array_slice($dirs, 0, $i + 1);
+ $temp = implode('/', $temp);
+ $result = $this->_mkdir_helper($temp, $mode);
+ }
+ return $result;
+ }
+
+ return $this->_mkdir_helper($dir, $mode);
+ }
+
+ /**
+ * Helper function for directory creation
+ *
+ * @param string $dir
+ * @return bool
+ * @access private
+ */
+ function _mkdir_helper($dir, $mode)
+ {
+ // send SSH_FXP_MKDIR without any attributes (that's what the \0\0\0\0 is doing)
+ if (!$this->_send_sftp_packet(NET_SFTP_MKDIR, pack('Na*a*', strlen($dir), $dir, "\0\0\0\0"))) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ if ($this->packet_type != NET_SFTP_STATUS) {
+ user_error('Expected SSH_FXP_STATUS');
+ return false;
+ }
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+ if ($status != NET_SFTP_STATUS_OK) {
+ $this->_logError($response, $status);
+ return false;
+ }
+
+ if ($mode !== -1) {
+ $this->chmod($mode, $dir);
+ }
+
+ return true;
+ }
+
+ /**
+ * Removes a directory.
+ *
+ * @param string $dir
+ * @return bool
+ * @access public
+ */
+ function rmdir($dir)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $dir = $this->_realpath($dir);
+ if ($dir === false) {
+ return false;
+ }
+
+ if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($dir), $dir))) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ if ($this->packet_type != NET_SFTP_STATUS) {
+ user_error('Expected SSH_FXP_STATUS');
+ return false;
+ }
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+ if ($status != NET_SFTP_STATUS_OK) {
+ // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED?
+ $this->_logError($response, $status);
+ return false;
+ }
+
+ $this->_remove_from_stat_cache($dir);
+ // the following will do a soft delete, which would be useful if you deleted a file
+ // and then tried to do a stat on the deleted file. the above, in contrast, does
+ // a hard delete
+ //$this->_update_stat_cache($dir, false);
+
+ return true;
+ }
+
+ /**
+ * Uploads a file to the SFTP server.
+ *
+ * By default, \phpseclib\Net\SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file.
+ * So, for example, if you set $data to 'filename.ext' and then do \phpseclib\Net\SFTP::get(), you will get a file, twelve bytes
+ * long, containing 'filename.ext' as its contents.
+ *
+ * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will
+ * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how
+ * large $remote_file will be, as well.
+ *
+ * Setting $mode to self::SOURCE_CALLBACK will use $data as callback function, which gets only one parameter -- number of bytes to return, and returns a string if there is some data or null if there is no more data
+ *
+ * If $data is a resource then it'll be used as a resource instead.
+ *
+ * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take
+ * care of that, yourself.
+ *
+ * $mode can take an additional two parameters - self::RESUME and self::RESUME_START. These are bitwise AND'd with
+ * $mode. So if you want to resume upload of a 300mb file on the local file system you'd set $mode to the following:
+ *
+ * self::SOURCE_LOCAL_FILE | self::RESUME
+ *
+ * If you wanted to simply append the full contents of a local file to the full contents of a remote file you'd replace
+ * self::RESUME with self::RESUME_START.
+ *
+ * If $mode & (self::RESUME | self::RESUME_START) then self::RESUME_START will be assumed.
+ *
+ * $start and $local_start give you more fine grained control over this process and take precident over self::RESUME
+ * when they're non-negative. ie. $start could let you write at the end of a file (like self::RESUME) or in the middle
+ * of one. $local_start could let you start your reading from the end of a file (like self::RESUME_START) or in the
+ * middle of one.
+ *
+ * Setting $local_start to > 0 or $mode | self::RESUME_START doesn't do anything unless $mode | self::SOURCE_LOCAL_FILE.
+ *
+ * @param string $remote_file
+ * @param string|resource $data
+ * @param int $mode
+ * @param int $start
+ * @param int $local_start
+ * @param callable|null $progressCallback
+ * @return bool
+ * @access public
+ * @internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib\Net\SFTP::setMode().
+ */
+ function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $remote_file = $this->_realpath($remote_file);
+ if ($remote_file === false) {
+ return false;
+ }
+
+ $this->_remove_from_stat_cache($remote_file);
+
+ $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE;
+ // according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file."
+ // in practice, it doesn't seem to do that.
+ //$flags|= ($mode & self::RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE;
+
+ if ($start >= 0) {
+ $offset = $start;
+ } elseif ($mode & self::RESUME) {
+ // if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called
+ $size = $this->size($remote_file);
+ $offset = $size !== false ? $size : 0;
+ } else {
+ $offset = 0;
+ $flags|= NET_SFTP_OPEN_TRUNCATE;
+ }
+
+ $packet = pack('Na*N2', strlen($remote_file), $remote_file, $flags, 0);
+ if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_HANDLE:
+ $handle = substr($response, 4);
+ break;
+ case NET_SFTP_STATUS:
+ $this->_logError($response);
+ return false;
+ default:
+ user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+ return false;
+ }
+
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3
+ $dataCallback = false;
+ switch (true) {
+ case $mode & self::SOURCE_CALLBACK:
+ if (!is_callable($data)) {
+ user_error("\$data should be is_callable() if you specify SOURCE_CALLBACK flag");
+ }
+ $dataCallback = $data;
+ // do nothing
+ break;
+ case is_resource($data):
+ $mode = $mode & ~self::SOURCE_LOCAL_FILE;
+ $info = stream_get_meta_data($data);
+ if ($info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') {
+ $fp = fopen('php://memory', 'w+');
+ stream_copy_to_stream($data, $fp);
+ rewind($fp);
+ } else {
+ $fp = $data;
+ }
+ break;
+ case $mode & self::SOURCE_LOCAL_FILE:
+ if (!is_file($data)) {
+ user_error("$data is not a valid file");
+ return false;
+ }
+ $fp = @fopen($data, 'rb');
+ if (!$fp) {
+ return false;
+ }
+ }
+
+ if (isset($fp)) {
+ $stat = fstat($fp);
+ $size = !empty($stat) ? $stat['size'] : 0;
+
+ if ($local_start >= 0) {
+ fseek($fp, $local_start);
+ $size-= $local_start;
+ }
+ } elseif ($dataCallback) {
+ $size = 0;
+ } else {
+ $size = strlen($data);
+ }
+
+ $sent = 0;
+ $size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size;
+
+ $sftp_packet_size = 4096; // PuTTY uses 4096
+ // make the SFTP packet be exactly 4096 bytes by including the bytes in the NET_SFTP_WRITE packets "header"
+ $sftp_packet_size-= strlen($handle) + 25;
+ $i = $j = 0;
+ while ($dataCallback || ($size === 0 || $sent < $size)) {
+ if ($dataCallback) {
+ $temp = call_user_func($dataCallback, $sftp_packet_size);
+ if (is_null($temp)) {
+ break;
+ }
+ } else {
+ $temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size);
+ if ($temp === false || $temp === '') {
+ break;
+ }
+ }
+
+ $subtemp = $offset + $sent;
+ $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp);
+ if (!$this->_send_sftp_packet(NET_SFTP_WRITE, $packet, $j)) {
+ if ($mode & self::SOURCE_LOCAL_FILE) {
+ fclose($fp);
+ }
+ return false;
+ }
+ $sent+= strlen($temp);
+ if (is_callable($progressCallback)) {
+ call_user_func($progressCallback, $sent);
+ }
+
+ $i++;
+ $j++;
+
+ if ($i == NET_SFTP_UPLOAD_QUEUE_SIZE) {
+ if (!$this->_read_put_responses($i)) {
+ $i = 0;
+ break;
+ }
+ $i = 0;
+ }
+ }
+
+ if (!$this->_read_put_responses($i)) {
+ if ($mode & self::SOURCE_LOCAL_FILE) {
+ fclose($fp);
+ }
+ $this->_close_handle($handle);
+ return false;
+ }
+
+ if ($mode & self::SOURCE_LOCAL_FILE) {
+ fclose($fp);
+ }
+
+ return $this->_close_handle($handle);
+ }
+
+ /**
+ * Reads multiple successive SSH_FXP_WRITE responses
+ *
+ * Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i
+ * SSH_FXP_WRITEs, in succession, and then reading $i responses.
+ *
+ * @param int $i
+ * @return bool
+ * @access private
+ */
+ function _read_put_responses($i)
+ {
+ while ($i--) {
+ $response = $this->_get_sftp_packet();
+ if ($this->packet_type != NET_SFTP_STATUS) {
+ user_error('Expected SSH_FXP_STATUS');
+ return false;
+ }
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+ if ($status != NET_SFTP_STATUS_OK) {
+ $this->_logError($response, $status);
+ break;
+ }
+ }
+
+ return $i < 0;
+ }
+
+ /**
+ * Close handle
+ *
+ * @param string $handle
+ * @return bool
+ * @access private
+ */
+ function _close_handle($handle)
+ {
+ if (!$this->_send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle))) {
+ return false;
+ }
+
+ // "The client MUST release all resources associated with the handle regardless of the status."
+ // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3
+ $response = $this->_get_sftp_packet();
+ if ($this->packet_type != NET_SFTP_STATUS) {
+ user_error('Expected SSH_FXP_STATUS');
+ return false;
+ }
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+ if ($status != NET_SFTP_STATUS_OK) {
+ $this->_logError($response, $status);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Downloads a file from the SFTP server.
+ *
+ * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if
+ * the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the
+ * operation.
+ *
+ * $offset and $length can be used to download files in chunks.
+ *
+ * @param string $remote_file
+ * @param string $local_file
+ * @param int $offset
+ * @param int $length
+ * @param callable|null $progressCallback
+ * @return mixed
+ * @access public
+ */
+ function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $remote_file = $this->_realpath($remote_file);
+ if ($remote_file === false) {
+ return false;
+ }
+
+ $packet = pack('Na*N2', strlen($remote_file), $remote_file, NET_SFTP_OPEN_READ, 0);
+ if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_HANDLE:
+ $handle = substr($response, 4);
+ break;
+ case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+ $this->_logError($response);
+ return false;
+ default:
+ user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+ return false;
+ }
+
+ if (is_resource($local_file)) {
+ $fp = $local_file;
+ $stat = fstat($fp);
+ $res_offset = $stat['size'];
+ } else {
+ $res_offset = 0;
+ if ($local_file !== false) {
+ $fp = fopen($local_file, 'wb');
+ if (!$fp) {
+ return false;
+ }
+ } else {
+ $content = '';
+ }
+ }
+
+ $fclose_check = $local_file !== false && !is_resource($local_file);
+
+ $start = $offset;
+ $read = 0;
+ while (true) {
+ $i = 0;
+
+ while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) {
+ $tempoffset = $start + $read;
+
+ $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet;
+
+ $packet = pack('Na*N3', strlen($handle), $handle, $tempoffset / 4294967296, $tempoffset, $packet_size);
+ if (!$this->_send_sftp_packet(NET_SFTP_READ, $packet, $i)) {
+ if ($fclose_check) {
+ fclose($fp);
+ }
+ return false;
+ }
+ $packet = null;
+ $read+= $packet_size;
+ if (is_callable($progressCallback)) {
+ call_user_func($progressCallback, $read);
+ }
+ $i++;
+ }
+
+ if (!$i) {
+ break;
+ }
+
+ $packets_sent = $i - 1;
+
+ $clear_responses = false;
+ while ($i > 0) {
+ $i--;
+
+ if ($clear_responses) {
+ $this->_get_sftp_packet($packets_sent - $i);
+ continue;
+ } else {
+ $response = $this->_get_sftp_packet($packets_sent - $i);
+ }
+
+ switch ($this->packet_type) {
+ case NET_SFTP_DATA:
+ $temp = substr($response, 4);
+ $offset+= strlen($temp);
+ if ($local_file === false) {
+ $content.= $temp;
+ } else {
+ fputs($fp, $temp);
+ }
+ $temp = null;
+ break;
+ case NET_SFTP_STATUS:
+ // could, in theory, return false if !strlen($content) but we'll hold off for the time being
+ $this->_logError($response);
+ $clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses
+ break;
+ default:
+ if ($fclose_check) {
+ fclose($fp);
+ }
+ user_error('Expected SSH_FX_DATA or SSH_FXP_STATUS');
+ }
+ $response = null;
+ }
+
+ if ($clear_responses) {
+ break;
+ }
+ }
+
+ if ($length > 0 && $length <= $offset - $start) {
+ if ($local_file === false) {
+ $content = substr($content, 0, $length);
+ } else {
+ ftruncate($fp, $length + $res_offset);
+ }
+ }
+
+ if ($fclose_check) {
+ fclose($fp);
+ }
+
+ if (!$this->_close_handle($handle)) {
+ return false;
+ }
+
+ // if $content isn't set that means a file was written to
+ return isset($content) ? $content : true;
+ }
+
+ /**
+ * Deletes a file on the SFTP server.
+ *
+ * @param string $path
+ * @param bool $recursive
+ * @return bool
+ * @access public
+ */
+ function delete($path, $recursive = true)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ if (is_object($path)) {
+ // It's an object. Cast it as string before we check anything else.
+ $path = (string) $path;
+ }
+
+ if (!is_string($path) || $path == '') {
+ return false;
+ }
+
+ $path = $this->_realpath($path);
+ if ($path === false) {
+ return false;
+ }
+
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3
+ if (!$this->_send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path))) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ if ($this->packet_type != NET_SFTP_STATUS) {
+ user_error('Expected SSH_FXP_STATUS');
+ return false;
+ }
+
+ // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+ if ($status != NET_SFTP_STATUS_OK) {
+ $this->_logError($response, $status);
+ if (!$recursive) {
+ return false;
+ }
+ $i = 0;
+ $result = $this->_delete_recursive($path, $i);
+ $this->_read_put_responses($i);
+ return $result;
+ }
+
+ $this->_remove_from_stat_cache($path);
+
+ return true;
+ }
+
+ /**
+ * Recursively deletes directories on the SFTP server
+ *
+ * Minimizes directory lookups and SSH_FXP_STATUS requests for speed.
+ *
+ * @param string $path
+ * @param int $i
+ * @return bool
+ * @access private
+ */
+ function _delete_recursive($path, &$i)
+ {
+ if (!$this->_read_put_responses($i)) {
+ return false;
+ }
+ $i = 0;
+ $entries = $this->_list($path, true);
+
+ // normally $entries would have at least . and .. but it might not if the directories
+ // permissions didn't allow reading
+ if (empty($entries)) {
+ return false;
+ }
+
+ unset($entries['.'], $entries['..']);
+ foreach ($entries as $filename => $props) {
+ if (!isset($props['type'])) {
+ return false;
+ }
+
+ $temp = $path . '/' . $filename;
+ if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) {
+ if (!$this->_delete_recursive($temp, $i)) {
+ return false;
+ }
+ } else {
+ if (!$this->_send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($temp), $temp))) {
+ return false;
+ }
+ $this->_remove_from_stat_cache($temp);
+
+ $i++;
+
+ if ($i >= NET_SFTP_QUEUE_SIZE) {
+ if (!$this->_read_put_responses($i)) {
+ return false;
+ }
+ $i = 0;
+ }
+ }
+ }
+
+ if (!$this->_send_sftp_packet(NET_SFTP_RMDIR, pack('Na*', strlen($path), $path))) {
+ return false;
+ }
+ $this->_remove_from_stat_cache($path);
+
+ $i++;
+
+ if ($i >= NET_SFTP_QUEUE_SIZE) {
+ if (!$this->_read_put_responses($i)) {
+ return false;
+ }
+ $i = 0;
+ }
+
+ return true;
+ }
+
+ /**
+ * Checks whether a file or directory exists
+ *
+ * @param string $path
+ * @return bool
+ * @access public
+ */
+ function file_exists($path)
+ {
+ if ($this->use_stat_cache) {
+ $path = $this->_realpath($path);
+
+ $result = $this->_query_stat_cache($path);
+
+ if (isset($result)) {
+ // return true if $result is an array or if it's an stdClass object
+ return $result !== false;
+ }
+ }
+
+ return $this->stat($path) !== false;
+ }
+
+ /**
+ * Tells whether the filename is a directory
+ *
+ * @param string $path
+ * @return bool
+ * @access public
+ */
+ function is_dir($path)
+ {
+ $result = $this->_get_stat_cache_prop($path, 'type');
+ if ($result === false) {
+ return false;
+ }
+ return $result === NET_SFTP_TYPE_DIRECTORY;
+ }
+
+ /**
+ * Tells whether the filename is a regular file
+ *
+ * @param string $path
+ * @return bool
+ * @access public
+ */
+ function is_file($path)
+ {
+ $result = $this->_get_stat_cache_prop($path, 'type');
+ if ($result === false) {
+ return false;
+ }
+ return $result === NET_SFTP_TYPE_REGULAR;
+ }
+
+ /**
+ * Tells whether the filename is a symbolic link
+ *
+ * @param string $path
+ * @return bool
+ * @access public
+ */
+ function is_link($path)
+ {
+ $result = $this->_get_lstat_cache_prop($path, 'type');
+ if ($result === false) {
+ return false;
+ }
+ return $result === NET_SFTP_TYPE_SYMLINK;
+ }
+
+ /**
+ * Tells whether a file exists and is readable
+ *
+ * @param string $path
+ * @return bool
+ * @access public
+ */
+ function is_readable($path)
+ {
+ $path = $this->_realpath($path);
+
+ $packet = pack('Na*N2', strlen($path), $path, NET_SFTP_OPEN_READ, 0);
+ if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_HANDLE:
+ return true;
+ case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+ return false;
+ default:
+ user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+ return false;
+ }
+ }
+
+ /**
+ * Tells whether the filename is writable
+ *
+ * @param string $path
+ * @return bool
+ * @access public
+ */
+ function is_writable($path)
+ {
+ $path = $this->_realpath($path);
+
+ $packet = pack('Na*N2', strlen($path), $path, NET_SFTP_OPEN_WRITE, 0);
+ if (!$this->_send_sftp_packet(NET_SFTP_OPEN, $packet)) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ switch ($this->packet_type) {
+ case NET_SFTP_HANDLE:
+ return true;
+ case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+ return false;
+ default:
+ user_error('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS');
+ return false;
+ }
+ }
+
+ /**
+ * Tells whether the filename is writeable
+ *
+ * Alias of is_writable
+ *
+ * @param string $path
+ * @return bool
+ * @access public
+ */
+ function is_writeable($path)
+ {
+ return $this->is_writable($path);
+ }
+
+ /**
+ * Gets last access time of file
+ *
+ * @param string $path
+ * @return mixed
+ * @access public
+ */
+ function fileatime($path)
+ {
+ return $this->_get_stat_cache_prop($path, 'atime');
+ }
+
+ /**
+ * Gets file modification time
+ *
+ * @param string $path
+ * @return mixed
+ * @access public
+ */
+ function filemtime($path)
+ {
+ return $this->_get_stat_cache_prop($path, 'mtime');
+ }
+
+ /**
+ * Gets file permissions
+ *
+ * @param string $path
+ * @return mixed
+ * @access public
+ */
+ function fileperms($path)
+ {
+ return $this->_get_stat_cache_prop($path, 'permissions');
+ }
+
+ /**
+ * Gets file owner
+ *
+ * @param string $path
+ * @return mixed
+ * @access public
+ */
+ function fileowner($path)
+ {
+ return $this->_get_stat_cache_prop($path, 'uid');
+ }
+
+ /**
+ * Gets file group
+ *
+ * @param string $path
+ * @return mixed
+ * @access public
+ */
+ function filegroup($path)
+ {
+ return $this->_get_stat_cache_prop($path, 'gid');
+ }
+
+ /**
+ * Gets file size
+ *
+ * @param string $path
+ * @return mixed
+ * @access public
+ */
+ function filesize($path)
+ {
+ return $this->_get_stat_cache_prop($path, 'size');
+ }
+
+ /**
+ * Gets file type
+ *
+ * @param string $path
+ * @return mixed
+ * @access public
+ */
+ function filetype($path)
+ {
+ $type = $this->_get_stat_cache_prop($path, 'type');
+ if ($type === false) {
+ return false;
+ }
+
+ switch ($type) {
+ case NET_SFTP_TYPE_BLOCK_DEVICE:
+ return 'block';
+ case NET_SFTP_TYPE_CHAR_DEVICE:
+ return 'char';
+ case NET_SFTP_TYPE_DIRECTORY:
+ return 'dir';
+ case NET_SFTP_TYPE_FIFO:
+ return 'fifo';
+ case NET_SFTP_TYPE_REGULAR:
+ return 'file';
+ case NET_SFTP_TYPE_SYMLINK:
+ return 'link';
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Return a stat properity
+ *
+ * Uses cache if appropriate.
+ *
+ * @param string $path
+ * @param string $prop
+ * @return mixed
+ * @access private
+ */
+ function _get_stat_cache_prop($path, $prop)
+ {
+ return $this->_get_xstat_cache_prop($path, $prop, 'stat');
+ }
+
+ /**
+ * Return an lstat properity
+ *
+ * Uses cache if appropriate.
+ *
+ * @param string $path
+ * @param string $prop
+ * @return mixed
+ * @access private
+ */
+ function _get_lstat_cache_prop($path, $prop)
+ {
+ return $this->_get_xstat_cache_prop($path, $prop, 'lstat');
+ }
+
+ /**
+ * Return a stat or lstat properity
+ *
+ * Uses cache if appropriate.
+ *
+ * @param string $path
+ * @param string $prop
+ * @return mixed
+ * @access private
+ */
+ function _get_xstat_cache_prop($path, $prop, $type)
+ {
+ if ($this->use_stat_cache) {
+ $path = $this->_realpath($path);
+
+ $result = $this->_query_stat_cache($path);
+
+ if (is_object($result) && isset($result->$type)) {
+ return $result->{$type}[$prop];
+ }
+ }
+
+ $result = $this->$type($path);
+
+ if ($result === false || !isset($result[$prop])) {
+ return false;
+ }
+
+ return $result[$prop];
+ }
+
+ /**
+ * Renames a file or a directory on the SFTP server
+ *
+ * @param string $oldname
+ * @param string $newname
+ * @return bool
+ * @access public
+ */
+ function rename($oldname, $newname)
+ {
+ if (!($this->bitmap & SSH2::MASK_LOGIN)) {
+ return false;
+ }
+
+ $oldname = $this->_realpath($oldname);
+ $newname = $this->_realpath($newname);
+ if ($oldname === false || $newname === false) {
+ return false;
+ }
+
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3
+ $packet = pack('Na*Na*', strlen($oldname), $oldname, strlen($newname), $newname);
+ if (!$this->_send_sftp_packet(NET_SFTP_RENAME, $packet)) {
+ return false;
+ }
+
+ $response = $this->_get_sftp_packet();
+ if ($this->packet_type != NET_SFTP_STATUS) {
+ user_error('Expected SSH_FXP_STATUS');
+ return false;
+ }
+
+ // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nstatus', $this->_string_shift($response, 4)));
+ if ($status != NET_SFTP_STATUS_OK) {
+ $this->_logError($response, $status);
+ return false;
+ }
+
+ // don't move the stat cache entry over since this operation could very well change the
+ // atime and mtime attributes
+ //$this->_update_stat_cache($newname, $this->_query_stat_cache($oldname));
+ $this->_remove_from_stat_cache($oldname);
+ $this->_remove_from_stat_cache($newname);
+
+ return true;
+ }
+
+ /**
+ * Parse Attributes
+ *
+ * See '7. File Attributes' of draft-ietf-secsh-filexfer-13 for more info.
+ *
+ * @param string $response
+ * @return array
+ * @access private
+ */
+ function _parseAttributes(&$response)
+ {
+ $attr = array();
+ if (strlen($response) < 4) {
+ user_error('Malformed file attributes');
+ return array();
+ }
+ extract(unpack('Nflags', $this->_string_shift($response, 4)));
+ // SFTPv4+ have a type field (a byte) that follows the above flag field
+ foreach ($this->attributes as $key => $value) {
+ switch ($flags & $key) {
+ case NET_SFTP_ATTR_SIZE: // 0x00000001
+ // The size attribute is defined as an unsigned 64-bit integer.
+ // The following will use floats on 32-bit platforms, if necessary.
+ // As can be seen in the BigInteger class, floats are generally
+ // IEEE 754 binary64 "double precision" on such platforms and
+ // as such can represent integers of at least 2^50 without loss
+ // of precision. Interpreted in filesize, 2^50 bytes = 1024 TiB.
+ $attr['size'] = hexdec(bin2hex($this->_string_shift($response, 8)));
+ break;
+ case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only)
+ if (strlen($response) < 8) {
+ user_error('Malformed file attributes');
+ return $attr;
+ }
+ $attr+= unpack('Nuid/Ngid', $this->_string_shift($response, 8));
+ break;
+ case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004
+ if (strlen($response) < 4) {
+ user_error('Malformed file attributes');
+ return $attr;
+ }
+ $attr+= unpack('Npermissions', $this->_string_shift($response, 4));
+ // mode == permissions; permissions was the original array key and is retained for bc purposes.
+ // mode was added because that's the more industry standard terminology
+ $attr+= array('mode' => $attr['permissions']);
+ $fileType = $this->_parseMode($attr['permissions']);
+ if ($fileType !== false) {
+ $attr+= array('type' => $fileType);
+ }
+ break;
+ case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008
+ if (strlen($response) < 8) {
+ user_error('Malformed file attributes');
+ return $attr;
+ }
+ $attr+= unpack('Natime/Nmtime', $this->_string_shift($response, 8));
+ break;
+ case NET_SFTP_ATTR_EXTENDED: // 0x80000000
+ if (strlen($response) < 4) {
+ user_error('Malformed file attributes');
+ return $attr;
+ }
+ extract(unpack('Ncount', $this->_string_shift($response, 4)));
+ for ($i = 0; $i < $count; $i++) {
+ if (strlen($response) < 4) {
+ user_error('Malformed file attributes');
+ return $attr;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $key = $this->_string_shift($response, $length);
+ if (strlen($response) < 4) {
+ user_error('Malformed file attributes');
+ return $attr;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $attr[$key] = $this->_string_shift($response, $length);
+ }
+ }
+ }
+ return $attr;
+ }
+
+ /**
+ * Attempt to identify the file type
+ *
+ * Quoting the SFTP RFC, "Implementations MUST NOT send bits that are not defined" but they seem to anyway
+ *
+ * @param int $mode
+ * @return int
+ * @access private
+ */
+ function _parseMode($mode)
+ {
+ // values come from http://lxr.free-electrons.com/source/include/uapi/linux/stat.h#L12
+ // see, also, http://linux.die.net/man/2/stat
+ switch ($mode & 0170000) {// ie. 1111 0000 0000 0000
+ case 0000000: // no file type specified - figure out the file type using alternative means
+ return false;
+ case 0040000:
+ return NET_SFTP_TYPE_DIRECTORY;
+ case 0100000:
+ return NET_SFTP_TYPE_REGULAR;
+ case 0120000:
+ return NET_SFTP_TYPE_SYMLINK;
+ // new types introduced in SFTPv5+
+ // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2
+ case 0010000: // named pipe (fifo)
+ return NET_SFTP_TYPE_FIFO;
+ case 0020000: // character special
+ return NET_SFTP_TYPE_CHAR_DEVICE;
+ case 0060000: // block special
+ return NET_SFTP_TYPE_BLOCK_DEVICE;
+ case 0140000: // socket
+ return NET_SFTP_TYPE_SOCKET;
+ case 0160000: // whiteout
+ // "SPECIAL should be used for files that are of
+ // a known type which cannot be expressed in the protocol"
+ return NET_SFTP_TYPE_SPECIAL;
+ default:
+ return NET_SFTP_TYPE_UNKNOWN;
+ }
+ }
+
+ /**
+ * Parse Longname
+ *
+ * SFTPv3 doesn't provide any easy way of identifying a file type. You could try to open
+ * a file as a directory and see if an error is returned or you could try to parse the
+ * SFTPv3-specific longname field of the SSH_FXP_NAME packet. That's what this function does.
+ * The result is returned using the
+ * {@link http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 SFTPv4 type constants}.
+ *
+ * If the longname is in an unrecognized format bool(false) is returned.
+ *
+ * @param string $longname
+ * @return mixed
+ * @access private
+ */
+ function _parseLongname($longname)
+ {
+ // http://en.wikipedia.org/wiki/Unix_file_types
+ // http://en.wikipedia.org/wiki/Filesystem_permissions#Notation_of_traditional_Unix_permissions
+ if (preg_match('#^[^/]([r-][w-][xstST-]){3}#', $longname)) {
+ switch ($longname[0]) {
+ case '-':
+ return NET_SFTP_TYPE_REGULAR;
+ case 'd':
+ return NET_SFTP_TYPE_DIRECTORY;
+ case 'l':
+ return NET_SFTP_TYPE_SYMLINK;
+ default:
+ return NET_SFTP_TYPE_SPECIAL;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Sends SFTP Packets
+ *
+ * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info.
+ *
+ * @param int $type
+ * @param string $data
+ * @see self::_get_sftp_packet()
+ * @see self::_send_channel_packet()
+ * @return bool
+ * @access private
+ */
+ function _send_sftp_packet($type, $data, $request_id = 1)
+ {
+ $packet = $this->use_request_id ?
+ pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) :
+ pack('NCa*', strlen($data) + 1, $type, $data);
+
+ $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+ $result = $this->_send_channel_packet(self::CHANNEL, $packet);
+ $stop = strtok(microtime(), ' ') + strtok('');
+
+ if (defined('NET_SFTP_LOGGING')) {
+ $packet_type = '-> ' . $this->packet_types[$type] .
+ ' (' . round($stop - $start, 4) . 's)';
+ if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
+ echo "<pre>\r\n" . $this->_format_log(array($data), array($packet_type)) . "\r\n</pre>\r\n";
+ flush();
+ ob_flush();
+ } else {
+ $this->packet_type_log[] = $packet_type;
+ if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
+ $this->packet_log[] = $data;
+ }
+ }
+ }
+
+ return $result;
+ }
+
+ /**
+ * Resets a connection for re-use
+ *
+ * @param int $reason
+ * @access private
+ */
+ function _reset_connection($reason)
+ {
+ parent::_reset_connection($reason);
+ $this->use_request_id = false;
+ $this->pwd = false;
+ $this->requestBuffer = array();
+ }
+
+ /**
+ * Receives SFTP Packets
+ *
+ * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info.
+ *
+ * Incidentally, the number of SSH_MSG_CHANNEL_DATA messages has no bearing on the number of SFTP packets present.
+ * There can be one SSH_MSG_CHANNEL_DATA messages containing two SFTP packets or there can be two SSH_MSG_CHANNEL_DATA
+ * messages containing one SFTP packet.
+ *
+ * @see self::_send_sftp_packet()
+ * @return string
+ * @access private
+ */
+ function _get_sftp_packet($request_id = null)
+ {
+ if (isset($request_id) && isset($this->requestBuffer[$request_id])) {
+ $this->packet_type = $this->requestBuffer[$request_id]['packet_type'];
+ $temp = $this->requestBuffer[$request_id]['packet'];
+ unset($this->requestBuffer[$request_id]);
+ return $temp;
+ }
+
+ // in SSH2.php the timeout is cumulative per function call. eg. exec() will
+ // timeout after 10s. but for SFTP.php it's cumulative per packet
+ $this->curTimeout = $this->timeout;
+
+ $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+
+ // SFTP packet length
+ while (strlen($this->packet_buffer) < 4) {
+ $temp = $this->_get_channel_packet(self::CHANNEL, true);
+ if (is_bool($temp)) {
+ $this->packet_type = false;
+ $this->packet_buffer = '';
+ return false;
+ }
+ $this->packet_buffer.= $temp;
+ }
+ if (strlen($this->packet_buffer) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($this->packet_buffer, 4)));
+ $tempLength = $length;
+ $tempLength-= strlen($this->packet_buffer);
+
+
+ // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h
+ if ($tempLength > 256 * 1024) {
+ user_error('Invalid SFTP packet size');
+ return false;
+ }
+
+ // SFTP packet type and data payload
+ while ($tempLength > 0) {
+ $temp = $this->_get_channel_packet(self::CHANNEL, true);
+ if (is_bool($temp)) {
+ $this->packet_type = false;
+ $this->packet_buffer = '';
+ return false;
+ }
+ $this->packet_buffer.= $temp;
+ $tempLength-= strlen($temp);
+ }
+
+ $stop = strtok(microtime(), ' ') + strtok('');
+
+ $this->packet_type = ord($this->_string_shift($this->packet_buffer));
+
+ if ($this->use_request_id) {
+ extract(unpack('Npacket_id', $this->_string_shift($this->packet_buffer, 4))); // remove the request id
+ $length-= 5; // account for the request id and the packet type
+ } else {
+ $length-= 1; // account for the packet type
+ }
+
+ $packet = $this->_string_shift($this->packet_buffer, $length);
+
+ if (defined('NET_SFTP_LOGGING')) {
+ $packet_type = '<- ' . $this->packet_types[$this->packet_type] .
+ ' (' . round($stop - $start, 4) . 's)';
+ if (NET_SFTP_LOGGING == self::LOG_REALTIME) {
+ echo "<pre>\r\n" . $this->_format_log(array($packet), array($packet_type)) . "\r\n</pre>\r\n";
+ flush();
+ ob_flush();
+ } else {
+ $this->packet_type_log[] = $packet_type;
+ if (NET_SFTP_LOGGING == self::LOG_COMPLEX) {
+ $this->packet_log[] = $packet;
+ }
+ }
+ }
+
+ if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) {
+ $this->requestBuffer[$packet_id] = array(
+ 'packet_type' => $this->packet_type,
+ 'packet' => $packet
+ );
+ return $this->_get_sftp_packet($request_id);
+ }
+
+ return $packet;
+ }
+
+ /**
+ * Returns a log of the packets that have been sent and received.
+ *
+ * Returns a string if NET_SFTP_LOGGING == NET_SFTP_LOG_COMPLEX, an array if NET_SFTP_LOGGING == NET_SFTP_LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING')
+ *
+ * @access public
+ * @return string or Array
+ */
+ function getSFTPLog()
+ {
+ if (!defined('NET_SFTP_LOGGING')) {
+ return false;
+ }
+
+ switch (NET_SFTP_LOGGING) {
+ case self::LOG_COMPLEX:
+ return $this->_format_log($this->packet_log, $this->packet_type_log);
+ break;
+ //case self::LOG_SIMPLE:
+ default:
+ return $this->packet_type_log;
+ }
+ }
+
+ /**
+ * Returns all errors
+ *
+ * @return array
+ * @access public
+ */
+ function getSFTPErrors()
+ {
+ return $this->sftp_errors;
+ }
+
+ /**
+ * Returns the last error
+ *
+ * @return string
+ * @access public
+ */
+ function getLastSFTPError()
+ {
+ return count($this->sftp_errors) ? $this->sftp_errors[count($this->sftp_errors) - 1] : '';
+ }
+
+ /**
+ * Get supported SFTP versions
+ *
+ * @return array
+ * @access public
+ */
+ function getSupportedVersions()
+ {
+ $temp = array('version' => $this->version);
+ if (isset($this->extensions['versions'])) {
+ $temp['extensions'] = $this->extensions['versions'];
+ }
+ return $temp;
+ }
+
+ /**
+ * Disconnect
+ *
+ * @param int $reason
+ * @return bool
+ * @access private
+ */
+ function _disconnect($reason)
+ {
+ $this->pwd = false;
+ parent::_disconnect($reason);
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php
new file mode 100644
index 0000000..d2c4425
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php
@@ -0,0 +1,795 @@
+<?php
+
+/**
+ * SFTP Stream Wrapper
+ *
+ * Creates an sftp:// protocol handler that can be used with, for example, fopen(), dir(), etc.
+ *
+ * PHP version 5
+ *
+ * @category Net
+ * @package SFTP
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2013 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Net\SFTP;
+
+use phpseclib\Crypt\RSA;
+use phpseclib\Net\SFTP;
+
+/**
+ * SFTP Stream Wrapper
+ *
+ * @package SFTP
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class Stream
+{
+ /**
+ * SFTP instances
+ *
+ * Rather than re-create the connection we re-use instances if possible
+ *
+ * @var array
+ */
+ static $instances;
+
+ /**
+ * SFTP instance
+ *
+ * @var object
+ * @access private
+ */
+ var $sftp;
+
+ /**
+ * Path
+ *
+ * @var string
+ * @access private
+ */
+ var $path;
+
+ /**
+ * Mode
+ *
+ * @var string
+ * @access private
+ */
+ var $mode;
+
+ /**
+ * Position
+ *
+ * @var int
+ * @access private
+ */
+ var $pos;
+
+ /**
+ * Size
+ *
+ * @var int
+ * @access private
+ */
+ var $size;
+
+ /**
+ * Directory entries
+ *
+ * @var array
+ * @access private
+ */
+ var $entries;
+
+ /**
+ * EOF flag
+ *
+ * @var bool
+ * @access private
+ */
+ var $eof;
+
+ /**
+ * Context resource
+ *
+ * Technically this needs to be publically accessible so PHP can set it directly
+ *
+ * @var resource
+ * @access public
+ */
+ var $context;
+
+ /**
+ * Notification callback function
+ *
+ * @var callable
+ * @access public
+ */
+ var $notification;
+
+ /**
+ * Registers this class as a URL wrapper.
+ *
+ * @param string $protocol The wrapper name to be registered.
+ * @return bool True on success, false otherwise.
+ * @access public
+ */
+ static function register($protocol = 'sftp')
+ {
+ if (in_array($protocol, stream_get_wrappers(), true)) {
+ return false;
+ }
+ return stream_wrapper_register($protocol, get_called_class());
+ }
+
+ /**
+ * The Constructor
+ *
+ * @access public
+ */
+ function __construct()
+ {
+ if (defined('NET_SFTP_STREAM_LOGGING')) {
+ echo "__construct()\r\n";
+ }
+ }
+
+ /**
+ * Path Parser
+ *
+ * Extract a path from a URI and actually connect to an SSH server if appropriate
+ *
+ * If "notification" is set as a context parameter the message code for successful login is
+ * NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE.
+ *
+ * @param string $path
+ * @return string
+ * @access private
+ */
+ function _parse_path($path)
+ {
+ $orig = $path;
+ extract(parse_url($path) + array('port' => 22));
+ if (isset($query)) {
+ $path.= '?' . $query;
+ } elseif (preg_match('/(\?|\?#)$/', $orig)) {
+ $path.= '?';
+ }
+ if (isset($fragment)) {
+ $path.= '#' . $fragment;
+ } elseif ($orig[strlen($orig) - 1] == '#') {
+ $path.= '#';
+ }
+
+ if (!isset($host)) {
+ return false;
+ }
+
+ if (isset($this->context)) {
+ $context = stream_context_get_params($this->context);
+ if (isset($context['notification'])) {
+ $this->notification = $context['notification'];
+ }
+ }
+
+ if ($host[0] == '$') {
+ $host = substr($host, 1);
+ global ${$host};
+ if (($$host instanceof SFTP) === false) {
+ return false;
+ }
+ $this->sftp = $$host;
+ } else {
+ if (isset($this->context)) {
+ $context = stream_context_get_options($this->context);
+ }
+ if (isset($context[$scheme]['session'])) {
+ $sftp = $context[$scheme]['session'];
+ }
+ if (isset($context[$scheme]['sftp'])) {
+ $sftp = $context[$scheme]['sftp'];
+ }
+ if (isset($sftp) && $sftp instanceof SFTP) {
+ $this->sftp = $sftp;
+ return $path;
+ }
+ if (isset($context[$scheme]['username'])) {
+ $user = $context[$scheme]['username'];
+ }
+ if (isset($context[$scheme]['password'])) {
+ $pass = $context[$scheme]['password'];
+ }
+ if (isset($context[$scheme]['privkey']) && $context[$scheme]['privkey'] instanceof RSA) {
+ $pass = $context[$scheme]['privkey'];
+ }
+
+ if (!isset($user) || !isset($pass)) {
+ return false;
+ }
+
+ // casting $pass to a string is necessary in the event that it's a \phpseclib\Crypt\RSA object
+ if (isset(self::$instances[$host][$port][$user][(string) $pass])) {
+ $this->sftp = self::$instances[$host][$port][$user][(string) $pass];
+ } else {
+ $this->sftp = new SFTP($host, $port);
+ $this->sftp->disableStatCache();
+ if (isset($this->notification) && is_callable($this->notification)) {
+ /* if !is_callable($this->notification) we could do this:
+
+ user_error('fopen(): failed to call user notifier', E_USER_WARNING);
+
+ the ftp wrapper gives errors like that when the notifier isn't callable.
+ i've opted not to do that, however, since the ftp wrapper gives the line
+ on which the fopen occurred as the line number - not the line that the
+ user_error is on.
+ */
+ call_user_func($this->notification, STREAM_NOTIFY_CONNECT, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
+ call_user_func($this->notification, STREAM_NOTIFY_AUTH_REQUIRED, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0);
+ if (!$this->sftp->login($user, $pass)) {
+ call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_ERR, 'Login Failure', NET_SSH2_MSG_USERAUTH_FAILURE, 0, 0);
+ return false;
+ }
+ call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_INFO, 'Login Success', NET_SSH2_MSG_USERAUTH_SUCCESS, 0, 0);
+ } else {
+ if (!$this->sftp->login($user, $pass)) {
+ return false;
+ }
+ }
+ self::$instances[$host][$port][$user][(string) $pass] = $this->sftp;
+ }
+ }
+
+ return $path;
+ }
+
+ /**
+ * Opens file or URL
+ *
+ * @param string $path
+ * @param string $mode
+ * @param int $options
+ * @param string $opened_path
+ * @return bool
+ * @access public
+ */
+ function _stream_open($path, $mode, $options, &$opened_path)
+ {
+ $path = $this->_parse_path($path);
+
+ if ($path === false) {
+ return false;
+ }
+ $this->path = $path;
+
+ $this->size = $this->sftp->size($path);
+ $this->mode = preg_replace('#[bt]$#', '', $mode);
+ $this->eof = false;
+
+ if ($this->size === false) {
+ if ($this->mode[0] == 'r') {
+ return false;
+ } else {
+ $this->sftp->touch($path);
+ $this->size = 0;
+ }
+ } else {
+ switch ($this->mode[0]) {
+ case 'x':
+ return false;
+ case 'w':
+ $this->sftp->truncate($path, 0);
+ $this->size = 0;
+ }
+ }
+
+ $this->pos = $this->mode[0] != 'a' ? 0 : $this->size;
+
+ return true;
+ }
+
+ /**
+ * Read from stream
+ *
+ * @param int $count
+ * @return mixed
+ * @access public
+ */
+ function _stream_read($count)
+ {
+ switch ($this->mode) {
+ case 'w':
+ case 'a':
+ case 'x':
+ case 'c':
+ return false;
+ }
+
+ // commented out because some files - eg. /dev/urandom - will say their size is 0 when in fact it's kinda infinite
+ //if ($this->pos >= $this->size) {
+ // $this->eof = true;
+ // return false;
+ //}
+
+ $result = $this->sftp->get($this->path, false, $this->pos, $count);
+ if (isset($this->notification) && is_callable($this->notification)) {
+ if ($result === false) {
+ call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
+ return 0;
+ }
+ // seems that PHP calls stream_read in 8k chunks
+ call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($result), $this->size);
+ }
+
+ if (empty($result)) { // ie. false or empty string
+ $this->eof = true;
+ return false;
+ }
+ $this->pos+= strlen($result);
+
+ return $result;
+ }
+
+ /**
+ * Write to stream
+ *
+ * @param string $data
+ * @return mixed
+ * @access public
+ */
+ function _stream_write($data)
+ {
+ switch ($this->mode) {
+ case 'r':
+ return false;
+ }
+
+ $result = $this->sftp->put($this->path, $data, SFTP::SOURCE_STRING, $this->pos);
+ if (isset($this->notification) && is_callable($this->notification)) {
+ if (!$result) {
+ call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0);
+ return 0;
+ }
+ // seems that PHP splits up strings into 8k blocks before calling stream_write
+ call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($data), strlen($data));
+ }
+
+ if ($result === false) {
+ return false;
+ }
+ $this->pos+= strlen($data);
+ if ($this->pos > $this->size) {
+ $this->size = $this->pos;
+ }
+ $this->eof = false;
+ return strlen($data);
+ }
+
+ /**
+ * Retrieve the current position of a stream
+ *
+ * @return int
+ * @access public
+ */
+ function _stream_tell()
+ {
+ return $this->pos;
+ }
+
+ /**
+ * Tests for end-of-file on a file pointer
+ *
+ * In my testing there are four classes functions that normally effect the pointer:
+ * fseek, fputs / fwrite, fgets / fread and ftruncate.
+ *
+ * Only fgets / fread, however, results in feof() returning true. do fputs($fp, 'aaa') on a blank file and feof()
+ * will return false. do fread($fp, 1) and feof() will then return true. do fseek($fp, 10) on ablank file and feof()
+ * will return false. do fread($fp, 1) and feof() will then return true.
+ *
+ * @return bool
+ * @access public
+ */
+ function _stream_eof()
+ {
+ return $this->eof;
+ }
+
+ /**
+ * Seeks to specific location in a stream
+ *
+ * @param int $offset
+ * @param int $whence
+ * @return bool
+ * @access public
+ */
+ function _stream_seek($offset, $whence)
+ {
+ switch ($whence) {
+ case SEEK_SET:
+ if ($offset >= $this->size || $offset < 0) {
+ return false;
+ }
+ break;
+ case SEEK_CUR:
+ $offset+= $this->pos;
+ break;
+ case SEEK_END:
+ $offset+= $this->size;
+ }
+
+ $this->pos = $offset;
+ $this->eof = false;
+ return true;
+ }
+
+ /**
+ * Change stream options
+ *
+ * @param string $path
+ * @param int $option
+ * @param mixed $var
+ * @return bool
+ * @access public
+ */
+ function _stream_metadata($path, $option, $var)
+ {
+ $path = $this->_parse_path($path);
+ if ($path === false) {
+ return false;
+ }
+
+ // stream_metadata was introduced in PHP 5.4.0 but as of 5.4.11 the constants haven't been defined
+ // see http://www.php.net/streamwrapper.stream-metadata and https://bugs.php.net/64246
+ // and https://github.com/php/php-src/blob/master/main/php_streams.h#L592
+ switch ($option) {
+ case 1: // PHP_STREAM_META_TOUCH
+ return $this->sftp->touch($path, $var[0], $var[1]);
+ case 2: // PHP_STREAM_OWNER_NAME
+ case 3: // PHP_STREAM_GROUP_NAME
+ return false;
+ case 4: // PHP_STREAM_META_OWNER
+ return $this->sftp->chown($path, $var);
+ case 5: // PHP_STREAM_META_GROUP
+ return $this->sftp->chgrp($path, $var);
+ case 6: // PHP_STREAM_META_ACCESS
+ return $this->sftp->chmod($path, $var) !== false;
+ }
+ }
+
+ /**
+ * Retrieve the underlaying resource
+ *
+ * @param int $cast_as
+ * @return resource
+ * @access public
+ */
+ function _stream_cast($cast_as)
+ {
+ return $this->sftp->fsock;
+ }
+
+ /**
+ * Advisory file locking
+ *
+ * @param int $operation
+ * @return bool
+ * @access public
+ */
+ function _stream_lock($operation)
+ {
+ return false;
+ }
+
+ /**
+ * Renames a file or directory
+ *
+ * Attempts to rename oldname to newname, moving it between directories if necessary.
+ * If newname exists, it will be overwritten. This is a departure from what \phpseclib\Net\SFTP
+ * does.
+ *
+ * @param string $path_from
+ * @param string $path_to
+ * @return bool
+ * @access public
+ */
+ function _rename($path_from, $path_to)
+ {
+ $path1 = parse_url($path_from);
+ $path2 = parse_url($path_to);
+ unset($path1['path'], $path2['path']);
+ if ($path1 != $path2) {
+ return false;
+ }
+
+ $path_from = $this->_parse_path($path_from);
+ $path_to = parse_url($path_to);
+ if ($path_from === false) {
+ return false;
+ }
+
+ $path_to = $path_to['path']; // the $component part of parse_url() was added in PHP 5.1.2
+ // "It is an error if there already exists a file with the name specified by newpath."
+ // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.5
+ if (!$this->sftp->rename($path_from, $path_to)) {
+ if ($this->sftp->stat($path_to)) {
+ return $this->sftp->delete($path_to, true) && $this->sftp->rename($path_from, $path_to);
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Open directory handle
+ *
+ * The only $options is "whether or not to enforce safe_mode (0x04)". Since safe mode was deprecated in 5.3 and
+ * removed in 5.4 I'm just going to ignore it.
+ *
+ * Also, nlist() is the best that this function is realistically going to be able to do. When an SFTP client
+ * sends a SSH_FXP_READDIR packet you don't generally get info on just one file but on multiple files. Quoting
+ * the SFTP specs:
+ *
+ * The SSH_FXP_NAME response has the following format:
+ *
+ * uint32 id
+ * uint32 count
+ * repeats count times:
+ * string filename
+ * string longname
+ * ATTRS attrs
+ *
+ * @param string $path
+ * @param int $options
+ * @return bool
+ * @access public
+ */
+ function _dir_opendir($path, $options)
+ {
+ $path = $this->_parse_path($path);
+ if ($path === false) {
+ return false;
+ }
+ $this->pos = 0;
+ $this->entries = $this->sftp->nlist($path);
+ return $this->entries !== false;
+ }
+
+ /**
+ * Read entry from directory handle
+ *
+ * @return mixed
+ * @access public
+ */
+ function _dir_readdir()
+ {
+ if (isset($this->entries[$this->pos])) {
+ return $this->entries[$this->pos++];
+ }
+ return false;
+ }
+
+ /**
+ * Rewind directory handle
+ *
+ * @return bool
+ * @access public
+ */
+ function _dir_rewinddir()
+ {
+ $this->pos = 0;
+ return true;
+ }
+
+ /**
+ * Close directory handle
+ *
+ * @return bool
+ * @access public
+ */
+ function _dir_closedir()
+ {
+ return true;
+ }
+
+ /**
+ * Create a directory
+ *
+ * Only valid $options is STREAM_MKDIR_RECURSIVE
+ *
+ * @param string $path
+ * @param int $mode
+ * @param int $options
+ * @return bool
+ * @access public
+ */
+ function _mkdir($path, $mode, $options)
+ {
+ $path = $this->_parse_path($path);
+ if ($path === false) {
+ return false;
+ }
+
+ return $this->sftp->mkdir($path, $mode, $options & STREAM_MKDIR_RECURSIVE);
+ }
+
+ /**
+ * Removes a directory
+ *
+ * Only valid $options is STREAM_MKDIR_RECURSIVE per <http://php.net/streamwrapper.rmdir>, however,
+ * <http://php.net/rmdir> does not have a $recursive parameter as mkdir() does so I don't know how
+ * STREAM_MKDIR_RECURSIVE is supposed to be set. Also, when I try it out with rmdir() I get 8 as
+ * $options. What does 8 correspond to?
+ *
+ * @param string $path
+ * @param int $mode
+ * @param int $options
+ * @return bool
+ * @access public
+ */
+ function _rmdir($path, $options)
+ {
+ $path = $this->_parse_path($path);
+ if ($path === false) {
+ return false;
+ }
+
+ return $this->sftp->rmdir($path);
+ }
+
+ /**
+ * Flushes the output
+ *
+ * See <http://php.net/fflush>. Always returns true because \phpseclib\Net\SFTP doesn't cache stuff before writing
+ *
+ * @return bool
+ * @access public
+ */
+ function _stream_flush()
+ {
+ return true;
+ }
+
+ /**
+ * Retrieve information about a file resource
+ *
+ * @return mixed
+ * @access public
+ */
+ function _stream_stat()
+ {
+ $results = $this->sftp->stat($this->path);
+ if ($results === false) {
+ return false;
+ }
+ return $results;
+ }
+
+ /**
+ * Delete a file
+ *
+ * @param string $path
+ * @return bool
+ * @access public
+ */
+ function _unlink($path)
+ {
+ $path = $this->_parse_path($path);
+ if ($path === false) {
+ return false;
+ }
+
+ return $this->sftp->delete($path, false);
+ }
+
+ /**
+ * Retrieve information about a file
+ *
+ * Ignores the STREAM_URL_STAT_QUIET flag because the entirety of \phpseclib\Net\SFTP\Stream is quiet by default
+ * might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll
+ * cross that bridge when and if it's reached
+ *
+ * @param string $path
+ * @param int $flags
+ * @return mixed
+ * @access public
+ */
+ function _url_stat($path, $flags)
+ {
+ $path = $this->_parse_path($path);
+ if ($path === false) {
+ return false;
+ }
+
+ $results = $flags & STREAM_URL_STAT_LINK ? $this->sftp->lstat($path) : $this->sftp->stat($path);
+ if ($results === false) {
+ return false;
+ }
+
+ return $results;
+ }
+
+ /**
+ * Truncate stream
+ *
+ * @param int $new_size
+ * @return bool
+ * @access public
+ */
+ function _stream_truncate($new_size)
+ {
+ if (!$this->sftp->truncate($this->path, $new_size)) {
+ return false;
+ }
+
+ $this->eof = false;
+ $this->size = $new_size;
+
+ return true;
+ }
+
+ /**
+ * Change stream options
+ *
+ * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't.
+ * The other two aren't supported because of limitations in \phpseclib\Net\SFTP.
+ *
+ * @param int $option
+ * @param int $arg1
+ * @param int $arg2
+ * @return bool
+ * @access public
+ */
+ function _stream_set_option($option, $arg1, $arg2)
+ {
+ return false;
+ }
+
+ /**
+ * Close an resource
+ *
+ * @access public
+ */
+ function _stream_close()
+ {
+ }
+
+ /**
+ * __call Magic Method
+ *
+ * When you're utilizing an SFTP stream you're not calling the methods in this class directly - PHP is calling them for you.
+ * Which kinda begs the question... what methods is PHP calling and what parameters is it passing to them? This function
+ * lets you figure that out.
+ *
+ * If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not
+ * NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method.
+ *
+ * @param string
+ * @param array
+ * @return mixed
+ * @access public
+ */
+ function __call($name, $arguments)
+ {
+ if (defined('NET_SFTP_STREAM_LOGGING')) {
+ echo $name . '(';
+ $last = count($arguments) - 1;
+ foreach ($arguments as $i => $argument) {
+ var_export($argument);
+ if ($i != $last) {
+ echo ',';
+ }
+ }
+ echo ")\r\n";
+ }
+ $name = '_' . $name;
+ if (!method_exists($this, $name)) {
+ return false;
+ }
+ return call_user_func_array(array($this, $name), $arguments);
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php
new file mode 100644
index 0000000..ff48d54
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SSH1.php
@@ -0,0 +1,1645 @@
+<?php
+
+/**
+ * Pure-PHP implementation of SSHv1.
+ *
+ * PHP version 5
+ *
+ * Here's a short example of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $ssh = new \phpseclib\Net\SSH1('www.domain.tld');
+ * if (!$ssh->login('username', 'password')) {
+ * exit('Login Failed');
+ * }
+ *
+ * echo $ssh->exec('ls -la');
+ * ?>
+ * </code>
+ *
+ * Here's another short example:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $ssh = new \phpseclib\Net\SSH1('www.domain.tld');
+ * if (!$ssh->login('username', 'password')) {
+ * exit('Login Failed');
+ * }
+ *
+ * echo $ssh->read('username@username:~$');
+ * $ssh->write("ls -la\n");
+ * echo $ssh->read('username@username:~$');
+ * ?>
+ * </code>
+ *
+ * More information on the SSHv1 specification can be found by reading
+ * {@link http://www.snailbook.com/docs/protocol-1.5.txt protocol-1.5.txt}.
+ *
+ * @category Net
+ * @package SSH1
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Net;
+
+use phpseclib\Crypt\DES;
+use phpseclib\Crypt\Random;
+use phpseclib\Crypt\TripleDES;
+use phpseclib\Math\BigInteger;
+
+/**
+ * Pure-PHP implementation of SSHv1.
+ *
+ * @package SSH1
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class SSH1
+{
+ /**#@+
+ * Encryption Methods
+ *
+ * @see \phpseclib\Net\SSH1::getSupportedCiphers()
+ * @access public
+ */
+ /**
+ * No encryption
+ *
+ * Not supported.
+ */
+ const CIPHER_NONE = 0;
+ /**
+ * IDEA in CFB mode
+ *
+ * Not supported.
+ */
+ const CIPHER_IDEA = 1;
+ /**
+ * DES in CBC mode
+ */
+ const CIPHER_DES = 2;
+ /**
+ * Triple-DES in CBC mode
+ *
+ * All implementations are required to support this
+ */
+ const CIPHER_3DES = 3;
+ /**
+ * TRI's Simple Stream encryption CBC
+ *
+ * Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, does define it (see cipher.h),
+ * although it doesn't use it (see cipher.c)
+ */
+ const CIPHER_BROKEN_TSS = 4;
+ /**
+ * RC4
+ *
+ * Not supported.
+ *
+ * @internal According to the SSH1 specs:
+ *
+ * "The first 16 bytes of the session key are used as the key for
+ * the server to client direction. The remaining 16 bytes are used
+ * as the key for the client to server direction. This gives
+ * independent 128-bit keys for each direction."
+ *
+ * This library currently only supports encryption when the same key is being used for both directions. This is
+ * because there's only one $crypto object. Two could be added ($encrypt and $decrypt, perhaps).
+ */
+ const CIPHER_RC4 = 5;
+ /**
+ * Blowfish
+ *
+ * Not supported nor is it defined in the official SSH1 specs. OpenSSH, however, defines it (see cipher.h) and
+ * uses it (see cipher.c)
+ */
+ const CIPHER_BLOWFISH = 6;
+ /**#@-*/
+
+ /**#@+
+ * Authentication Methods
+ *
+ * @see \phpseclib\Net\SSH1::getSupportedAuthentications()
+ * @access public
+ */
+ /**
+ * .rhosts or /etc/hosts.equiv
+ */
+ const AUTH_RHOSTS = 1;
+ /**
+ * pure RSA authentication
+ */
+ const AUTH_RSA = 2;
+ /**
+ * password authentication
+ *
+ * This is the only method that is supported by this library.
+ */
+ const AUTH_PASSWORD = 3;
+ /**
+ * .rhosts with RSA host authentication
+ */
+ const AUTH_RHOSTS_RSA = 4;
+ /**#@-*/
+
+ /**#@+
+ * Terminal Modes
+ *
+ * @link http://3sp.com/content/developer/maverick-net/docs/Maverick.SSH.PseudoTerminalModesMembers.html
+ * @access private
+ */
+ const TTY_OP_END = 0;
+ /**#@-*/
+
+ /**
+ * The Response Type
+ *
+ * @see \phpseclib\Net\SSH1::_get_binary_packet()
+ * @access private
+ */
+ const RESPONSE_TYPE = 1;
+
+ /**
+ * The Response Data
+ *
+ * @see \phpseclib\Net\SSH1::_get_binary_packet()
+ * @access private
+ */
+ const RESPONSE_DATA = 2;
+
+ /**#@+
+ * Execution Bitmap Masks
+ *
+ * @see \phpseclib\Net\SSH1::bitmap
+ * @access private
+ */
+ const MASK_CONSTRUCTOR = 0x00000001;
+ const MASK_CONNECTED = 0x00000002;
+ const MASK_LOGIN = 0x00000004;
+ const MASK_SHELL = 0x00000008;
+ /**#@-*/
+
+ /**#@+
+ * @access public
+ * @see \phpseclib\Net\SSH1::getLog()
+ */
+ /**
+ * Returns the message numbers
+ */
+ const LOG_SIMPLE = 1;
+ /**
+ * Returns the message content
+ */
+ const LOG_COMPLEX = 2;
+ /**
+ * Outputs the content real-time
+ */
+ const LOG_REALTIME = 3;
+ /**
+ * Dumps the content real-time to a file
+ */
+ const LOG_REALTIME_FILE = 4;
+ /**#@-*/
+
+ /**#@+
+ * @access public
+ * @see \phpseclib\Net\SSH1::read()
+ */
+ /**
+ * Returns when a string matching $expect exactly is found
+ */
+ const READ_SIMPLE = 1;
+ /**
+ * Returns when a string matching the regular expression $expect is found
+ */
+ const READ_REGEX = 2;
+ /**#@-*/
+
+ /**
+ * The SSH identifier
+ *
+ * @var string
+ * @access private
+ */
+ var $identifier = 'SSH-1.5-phpseclib';
+
+ /**
+ * The Socket Object
+ *
+ * @var object
+ * @access private
+ */
+ var $fsock;
+
+ /**
+ * The cryptography object
+ *
+ * @var object
+ * @access private
+ */
+ var $crypto = false;
+
+ /**
+ * Execution Bitmap
+ *
+ * The bits that are set represent functions that have been called already. This is used to determine
+ * if a requisite function has been successfully executed. If not, an error should be thrown.
+ *
+ * @var int
+ * @access private
+ */
+ var $bitmap = 0;
+
+ /**
+ * The Server Key Public Exponent
+ *
+ * Logged for debug purposes
+ *
+ * @see self::getServerKeyPublicExponent()
+ * @var string
+ * @access private
+ */
+ var $server_key_public_exponent;
+
+ /**
+ * The Server Key Public Modulus
+ *
+ * Logged for debug purposes
+ *
+ * @see self::getServerKeyPublicModulus()
+ * @var string
+ * @access private
+ */
+ var $server_key_public_modulus;
+
+ /**
+ * The Host Key Public Exponent
+ *
+ * Logged for debug purposes
+ *
+ * @see self::getHostKeyPublicExponent()
+ * @var string
+ * @access private
+ */
+ var $host_key_public_exponent;
+
+ /**
+ * The Host Key Public Modulus
+ *
+ * Logged for debug purposes
+ *
+ * @see self::getHostKeyPublicModulus()
+ * @var string
+ * @access private
+ */
+ var $host_key_public_modulus;
+
+ /**
+ * Supported Ciphers
+ *
+ * Logged for debug purposes
+ *
+ * @see self::getSupportedCiphers()
+ * @var array
+ * @access private
+ */
+ var $supported_ciphers = array(
+ self::CIPHER_NONE => 'No encryption',
+ self::CIPHER_IDEA => 'IDEA in CFB mode',
+ self::CIPHER_DES => 'DES in CBC mode',
+ self::CIPHER_3DES => 'Triple-DES in CBC mode',
+ self::CIPHER_BROKEN_TSS => 'TRI\'s Simple Stream encryption CBC',
+ self::CIPHER_RC4 => 'RC4',
+ self::CIPHER_BLOWFISH => 'Blowfish'
+ );
+
+ /**
+ * Supported Authentications
+ *
+ * Logged for debug purposes
+ *
+ * @see self::getSupportedAuthentications()
+ * @var array
+ * @access private
+ */
+ var $supported_authentications = array(
+ self::AUTH_RHOSTS => '.rhosts or /etc/hosts.equiv',
+ self::AUTH_RSA => 'pure RSA authentication',
+ self::AUTH_PASSWORD => 'password authentication',
+ self::AUTH_RHOSTS_RSA => '.rhosts with RSA host authentication'
+ );
+
+ /**
+ * Server Identification
+ *
+ * @see self::getServerIdentification()
+ * @var string
+ * @access private
+ */
+ var $server_identification = '';
+
+ /**
+ * Protocol Flags
+ *
+ * @see self::__construct()
+ * @var array
+ * @access private
+ */
+ var $protocol_flags = array();
+
+ /**
+ * Protocol Flag Log
+ *
+ * @see self::getLog()
+ * @var array
+ * @access private
+ */
+ var $protocol_flag_log = array();
+
+ /**
+ * Message Log
+ *
+ * @see self::getLog()
+ * @var array
+ * @access private
+ */
+ var $message_log = array();
+
+ /**
+ * Real-time log file pointer
+ *
+ * @see self::_append_log()
+ * @var resource
+ * @access private
+ */
+ var $realtime_log_file;
+
+ /**
+ * Real-time log file size
+ *
+ * @see self::_append_log()
+ * @var int
+ * @access private
+ */
+ var $realtime_log_size;
+
+ /**
+ * Real-time log file wrap boolean
+ *
+ * @see self::_append_log()
+ * @var bool
+ * @access private
+ */
+ var $realtime_log_wrap;
+
+ /**
+ * Interactive Buffer
+ *
+ * @see self::read()
+ * @var array
+ * @access private
+ */
+ var $interactiveBuffer = '';
+
+ /**
+ * Timeout
+ *
+ * @see self::setTimeout()
+ * @access private
+ */
+ var $timeout;
+
+ /**
+ * Current Timeout
+ *
+ * @see self::_get_channel_packet()
+ * @access private
+ */
+ var $curTimeout;
+
+ /**
+ * Log Boundary
+ *
+ * @see self::_format_log()
+ * @access private
+ */
+ var $log_boundary = ':';
+
+ /**
+ * Log Long Width
+ *
+ * @see self::_format_log()
+ * @access private
+ */
+ var $log_long_width = 65;
+
+ /**
+ * Log Short Width
+ *
+ * @see self::_format_log()
+ * @access private
+ */
+ var $log_short_width = 16;
+
+ /**
+ * Hostname
+ *
+ * @see self::__construct()
+ * @see self::_connect()
+ * @var string
+ * @access private
+ */
+ var $host;
+
+ /**
+ * Port Number
+ *
+ * @see self::__construct()
+ * @see self::_connect()
+ * @var int
+ * @access private
+ */
+ var $port;
+
+ /**
+ * Timeout for initial connection
+ *
+ * Set by the constructor call. Calling setTimeout() is optional. If it's not called functions like
+ * exec() won't timeout unless some PHP setting forces it too. The timeout specified in the constructor,
+ * however, is non-optional. There will be a timeout, whether or not you set it. If you don't it'll be
+ * 10 seconds. It is used by fsockopen() in that function.
+ *
+ * @see self::__construct()
+ * @see self::_connect()
+ * @var int
+ * @access private
+ */
+ var $connectionTimeout;
+
+ /**
+ * Default cipher
+ *
+ * @see self::__construct()
+ * @see self::_connect()
+ * @var int
+ * @access private
+ */
+ var $cipher;
+
+ /**
+ * Default Constructor.
+ *
+ * Connects to an SSHv1 server
+ *
+ * @param string $host
+ * @param int $port
+ * @param int $timeout
+ * @param int $cipher
+ * @return \phpseclib\Net\SSH1
+ * @access public
+ */
+ function __construct($host, $port = 22, $timeout = 10, $cipher = self::CIPHER_3DES)
+ {
+ $this->protocol_flags = array(
+ 1 => 'NET_SSH1_MSG_DISCONNECT',
+ 2 => 'NET_SSH1_SMSG_PUBLIC_KEY',
+ 3 => 'NET_SSH1_CMSG_SESSION_KEY',
+ 4 => 'NET_SSH1_CMSG_USER',
+ 9 => 'NET_SSH1_CMSG_AUTH_PASSWORD',
+ 10 => 'NET_SSH1_CMSG_REQUEST_PTY',
+ 12 => 'NET_SSH1_CMSG_EXEC_SHELL',
+ 13 => 'NET_SSH1_CMSG_EXEC_CMD',
+ 14 => 'NET_SSH1_SMSG_SUCCESS',
+ 15 => 'NET_SSH1_SMSG_FAILURE',
+ 16 => 'NET_SSH1_CMSG_STDIN_DATA',
+ 17 => 'NET_SSH1_SMSG_STDOUT_DATA',
+ 18 => 'NET_SSH1_SMSG_STDERR_DATA',
+ 19 => 'NET_SSH1_CMSG_EOF',
+ 20 => 'NET_SSH1_SMSG_EXITSTATUS',
+ 33 => 'NET_SSH1_CMSG_EXIT_CONFIRMATION'
+ );
+
+ $this->_define_array($this->protocol_flags);
+
+ $this->host = $host;
+ $this->port = $port;
+ $this->connectionTimeout = $timeout;
+ $this->cipher = $cipher;
+ }
+
+ /**
+ * Connect to an SSHv1 server
+ *
+ * @return bool
+ * @access private
+ */
+ function _connect()
+ {
+ $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->connectionTimeout);
+ if (!$this->fsock) {
+ user_error(rtrim("Cannot connect to {$this->host}:{$this->port}. Error $errno. $errstr"));
+ return false;
+ }
+
+ $this->server_identification = $init_line = fgets($this->fsock, 255);
+
+ if (defined('NET_SSH1_LOGGING')) {
+ $this->_append_log('<-', $this->server_identification);
+ $this->_append_log('->', $this->identifier . "\r\n");
+ }
+
+ if (!preg_match('#SSH-([0-9\.]+)-(.+)#', $init_line, $parts)) {
+ user_error('Can only connect to SSH servers');
+ return false;
+ }
+ if ($parts[1][0] != 1) {
+ user_error("Cannot connect to SSH $parts[1] servers");
+ return false;
+ }
+
+ fputs($this->fsock, $this->identifier."\r\n");
+
+ $response = $this->_get_binary_packet();
+ if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_PUBLIC_KEY) {
+ user_error('Expected SSH_SMSG_PUBLIC_KEY');
+ return false;
+ }
+
+ $anti_spoofing_cookie = $this->_string_shift($response[self::RESPONSE_DATA], 8);
+
+ $this->_string_shift($response[self::RESPONSE_DATA], 4);
+
+ if (strlen($response[self::RESPONSE_DATA]) < 2) {
+ return false;
+ }
+ $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
+ $server_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
+ $this->server_key_public_exponent = $server_key_public_exponent;
+
+ if (strlen($response[self::RESPONSE_DATA]) < 2) {
+ return false;
+ }
+ $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
+ $server_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
+
+ $this->server_key_public_modulus = $server_key_public_modulus;
+
+ $this->_string_shift($response[self::RESPONSE_DATA], 4);
+
+ if (strlen($response[self::RESPONSE_DATA]) < 2) {
+ return false;
+ }
+ $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
+ $host_key_public_exponent = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
+ $this->host_key_public_exponent = $host_key_public_exponent;
+
+ if (strlen($response[self::RESPONSE_DATA]) < 2) {
+ return false;
+ }
+ $temp = unpack('nlen', $this->_string_shift($response[self::RESPONSE_DATA], 2));
+ $host_key_public_modulus = new BigInteger($this->_string_shift($response[self::RESPONSE_DATA], ceil($temp['len'] / 8)), 256);
+
+ $this->host_key_public_modulus = $host_key_public_modulus;
+
+ $this->_string_shift($response[self::RESPONSE_DATA], 4);
+
+ // get a list of the supported ciphers
+ if (strlen($response[self::RESPONSE_DATA]) < 4) {
+ return false;
+ }
+ extract(unpack('Nsupported_ciphers_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
+
+ foreach ($this->supported_ciphers as $mask => $name) {
+ if (($supported_ciphers_mask & (1 << $mask)) == 0) {
+ unset($this->supported_ciphers[$mask]);
+ }
+ }
+
+ // get a list of the supported authentications
+ if (strlen($response[self::RESPONSE_DATA]) < 4) {
+ return false;
+ }
+ extract(unpack('Nsupported_authentications_mask', $this->_string_shift($response[self::RESPONSE_DATA], 4)));
+ foreach ($this->supported_authentications as $mask => $name) {
+ if (($supported_authentications_mask & (1 << $mask)) == 0) {
+ unset($this->supported_authentications[$mask]);
+ }
+ }
+
+ $session_id = pack('H*', md5($host_key_public_modulus->toBytes() . $server_key_public_modulus->toBytes() . $anti_spoofing_cookie));
+
+ $session_key = Random::string(32);
+ $double_encrypted_session_key = $session_key ^ str_pad($session_id, 32, chr(0));
+
+ if ($server_key_public_modulus->compare($host_key_public_modulus) < 0) {
+ $double_encrypted_session_key = $this->_rsa_crypt(
+ $double_encrypted_session_key,
+ array(
+ $server_key_public_exponent,
+ $server_key_public_modulus
+ )
+ );
+ $double_encrypted_session_key = $this->_rsa_crypt(
+ $double_encrypted_session_key,
+ array(
+ $host_key_public_exponent,
+ $host_key_public_modulus
+ )
+ );
+ } else {
+ $double_encrypted_session_key = $this->_rsa_crypt(
+ $double_encrypted_session_key,
+ array(
+ $host_key_public_exponent,
+ $host_key_public_modulus
+ )
+ );
+ $double_encrypted_session_key = $this->_rsa_crypt(
+ $double_encrypted_session_key,
+ array(
+ $server_key_public_exponent,
+ $server_key_public_modulus
+ )
+ );
+ }
+
+ $cipher = isset($this->supported_ciphers[$this->cipher]) ? $this->cipher : self::CIPHER_3DES;
+ $data = pack('C2a*na*N', NET_SSH1_CMSG_SESSION_KEY, $cipher, $anti_spoofing_cookie, 8 * strlen($double_encrypted_session_key), $double_encrypted_session_key, 0);
+
+ if (!$this->_send_binary_packet($data)) {
+ user_error('Error sending SSH_CMSG_SESSION_KEY');
+ return false;
+ }
+
+ switch ($cipher) {
+ //case self::CIPHER_NONE:
+ // $this->crypto = new \phpseclib\Crypt\Null();
+ // break;
+ case self::CIPHER_DES:
+ $this->crypto = new DES();
+ $this->crypto->disablePadding();
+ $this->crypto->enableContinuousBuffer();
+ $this->crypto->setKey(substr($session_key, 0, 8));
+ break;
+ case self::CIPHER_3DES:
+ $this->crypto = new TripleDES(TripleDES::MODE_3CBC);
+ $this->crypto->disablePadding();
+ $this->crypto->enableContinuousBuffer();
+ $this->crypto->setKey(substr($session_key, 0, 24));
+ break;
+ //case self::CIPHER_RC4:
+ // $this->crypto = new RC4();
+ // $this->crypto->enableContinuousBuffer();
+ // $this->crypto->setKey(substr($session_key, 0, 16));
+ // break;
+ }
+
+ $response = $this->_get_binary_packet();
+
+ if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
+ user_error('Expected SSH_SMSG_SUCCESS');
+ return false;
+ }
+
+ $this->bitmap = self::MASK_CONNECTED;
+
+ return true;
+ }
+
+ /**
+ * Login
+ *
+ * @param string $username
+ * @param string $password
+ * @return bool
+ * @access public
+ */
+ function login($username, $password = '')
+ {
+ if (!($this->bitmap & self::MASK_CONSTRUCTOR)) {
+ $this->bitmap |= self::MASK_CONSTRUCTOR;
+ if (!$this->_connect()) {
+ return false;
+ }
+ }
+
+ if (!($this->bitmap & self::MASK_CONNECTED)) {
+ return false;
+ }
+
+ $data = pack('CNa*', NET_SSH1_CMSG_USER, strlen($username), $username);
+
+ if (!$this->_send_binary_packet($data)) {
+ user_error('Error sending SSH_CMSG_USER');
+ return false;
+ }
+
+ $response = $this->_get_binary_packet();
+
+ if ($response === true) {
+ return false;
+ }
+ if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
+ $this->bitmap |= self::MASK_LOGIN;
+ return true;
+ } elseif ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_FAILURE) {
+ user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
+ return false;
+ }
+
+ $data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen($password), $password);
+
+ if (!$this->_send_binary_packet($data)) {
+ user_error('Error sending SSH_CMSG_AUTH_PASSWORD');
+ return false;
+ }
+
+ // remove the username and password from the last logged packet
+ if (defined('NET_SSH1_LOGGING') && NET_SSH1_LOGGING == self::LOG_COMPLEX) {
+ $data = pack('CNa*', NET_SSH1_CMSG_AUTH_PASSWORD, strlen('password'), 'password');
+ $this->message_log[count($this->message_log) - 1] = $data;
+ }
+
+ $response = $this->_get_binary_packet();
+
+ if ($response === true) {
+ return false;
+ }
+ if ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_SUCCESS) {
+ $this->bitmap |= self::MASK_LOGIN;
+ return true;
+ } elseif ($response[self::RESPONSE_TYPE] == NET_SSH1_SMSG_FAILURE) {
+ return false;
+ } else {
+ user_error('Expected SSH_SMSG_SUCCESS or SSH_SMSG_FAILURE');
+ return false;
+ }
+ }
+
+ /**
+ * Set Timeout
+ *
+ * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout.
+ * Setting $timeout to false or 0 will mean there is no timeout.
+ *
+ * @param mixed $timeout
+ */
+ function setTimeout($timeout)
+ {
+ $this->timeout = $this->curTimeout = $timeout;
+ }
+
+ /**
+ * Executes a command on a non-interactive shell, returns the output, and quits.
+ *
+ * An SSH1 server will close the connection after a command has been executed on a non-interactive shell. SSH2
+ * servers don't, however, this isn't an SSH2 client. The way this works, on the server, is by initiating a
+ * shell with the -s option, as discussed in the following links:
+ *
+ * {@link http://www.faqs.org/docs/bashman/bashref_65.html http://www.faqs.org/docs/bashman/bashref_65.html}
+ * {@link http://www.faqs.org/docs/bashman/bashref_62.html http://www.faqs.org/docs/bashman/bashref_62.html}
+ *
+ * To execute further commands, a new \phpseclib\Net\SSH1 object will need to be created.
+ *
+ * Returns false on failure and the output, otherwise.
+ *
+ * @see self::interactiveRead()
+ * @see self::interactiveWrite()
+ * @param string $cmd
+ * @return mixed
+ * @access public
+ */
+ function exec($cmd, $block = true)
+ {
+ if (!($this->bitmap & self::MASK_LOGIN)) {
+ user_error('Operation disallowed prior to login()');
+ return false;
+ }
+
+ $data = pack('CNa*', NET_SSH1_CMSG_EXEC_CMD, strlen($cmd), $cmd);
+
+ if (!$this->_send_binary_packet($data)) {
+ user_error('Error sending SSH_CMSG_EXEC_CMD');
+ return false;
+ }
+
+ if (!$block) {
+ return true;
+ }
+
+ $output = '';
+ $response = $this->_get_binary_packet();
+
+ if ($response !== false) {
+ do {
+ $output.= substr($response[self::RESPONSE_DATA], 4);
+ $response = $this->_get_binary_packet();
+ } while (is_array($response) && $response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_EXITSTATUS);
+ }
+
+ $data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION);
+
+ // i don't think it's really all that important if this packet gets sent or not.
+ $this->_send_binary_packet($data);
+
+ fclose($this->fsock);
+
+ // reset the execution bitmap - a new \phpseclib\Net\SSH1 object needs to be created.
+ $this->bitmap = 0;
+
+ return $output;
+ }
+
+ /**
+ * Creates an interactive shell
+ *
+ * @see self::interactiveRead()
+ * @see self::interactiveWrite()
+ * @return bool
+ * @access private
+ */
+ function _initShell()
+ {
+ // connect using the sample parameters in protocol-1.5.txt.
+ // according to wikipedia.org's entry on text terminals, "the fundamental type of application running on a text
+ // terminal is a command line interpreter or shell". thus, opening a terminal session to run the shell.
+ $data = pack('CNa*N4C', NET_SSH1_CMSG_REQUEST_PTY, strlen('vt100'), 'vt100', 24, 80, 0, 0, self::TTY_OP_END);
+
+ if (!$this->_send_binary_packet($data)) {
+ user_error('Error sending SSH_CMSG_REQUEST_PTY');
+ return false;
+ }
+
+ $response = $this->_get_binary_packet();
+
+ if ($response === true) {
+ return false;
+ }
+ if ($response[self::RESPONSE_TYPE] != NET_SSH1_SMSG_SUCCESS) {
+ user_error('Expected SSH_SMSG_SUCCESS');
+ return false;
+ }
+
+ $data = pack('C', NET_SSH1_CMSG_EXEC_SHELL);
+
+ if (!$this->_send_binary_packet($data)) {
+ user_error('Error sending SSH_CMSG_EXEC_SHELL');
+ return false;
+ }
+
+ $this->bitmap |= self::MASK_SHELL;
+
+ //stream_set_blocking($this->fsock, 0);
+
+ return true;
+ }
+
+ /**
+ * Inputs a command into an interactive shell.
+ *
+ * @see self::interactiveWrite()
+ * @param string $cmd
+ * @return bool
+ * @access public
+ */
+ function write($cmd)
+ {
+ return $this->interactiveWrite($cmd);
+ }
+
+ /**
+ * Returns the output of an interactive shell when there's a match for $expect
+ *
+ * $expect can take the form of a string literal or, if $mode == self::READ_REGEX,
+ * a regular expression.
+ *
+ * @see self::write()
+ * @param string $expect
+ * @param int $mode
+ * @return bool
+ * @access public
+ */
+ function read($expect, $mode = self::READ_SIMPLE)
+ {
+ if (!($this->bitmap & self::MASK_LOGIN)) {
+ user_error('Operation disallowed prior to login()');
+ return false;
+ }
+
+ if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
+ user_error('Unable to initiate an interactive shell session');
+ return false;
+ }
+
+ $match = $expect;
+ while (true) {
+ if ($mode == self::READ_REGEX) {
+ preg_match($expect, $this->interactiveBuffer, $matches);
+ $match = isset($matches[0]) ? $matches[0] : '';
+ }
+ $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false;
+ if ($pos !== false) {
+ return $this->_string_shift($this->interactiveBuffer, $pos + strlen($match));
+ }
+ $response = $this->_get_binary_packet();
+
+ if ($response === true) {
+ return $this->_string_shift($this->interactiveBuffer, strlen($this->interactiveBuffer));
+ }
+ $this->interactiveBuffer.= substr($response[self::RESPONSE_DATA], 4);
+ }
+ }
+
+ /**
+ * Inputs a command into an interactive shell.
+ *
+ * @see self::interactiveRead()
+ * @param string $cmd
+ * @return bool
+ * @access public
+ */
+ function interactiveWrite($cmd)
+ {
+ if (!($this->bitmap & self::MASK_LOGIN)) {
+ user_error('Operation disallowed prior to login()');
+ return false;
+ }
+
+ if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
+ user_error('Unable to initiate an interactive shell session');
+ return false;
+ }
+
+ $data = pack('CNa*', NET_SSH1_CMSG_STDIN_DATA, strlen($cmd), $cmd);
+
+ if (!$this->_send_binary_packet($data)) {
+ user_error('Error sending SSH_CMSG_STDIN');
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the output of an interactive shell when no more output is available.
+ *
+ * Requires PHP 4.3.0 or later due to the use of the stream_select() function. If you see stuff like
+ * "^[[00m", you're seeing ANSI escape codes. According to
+ * {@link http://support.microsoft.com/kb/101875 How to Enable ANSI.SYS in a Command Window}, "Windows NT
+ * does not support ANSI escape sequences in Win32 Console applications", so if you're a Windows user,
+ * there's not going to be much recourse.
+ *
+ * @see self::interactiveRead()
+ * @return string
+ * @access public
+ */
+ function interactiveRead()
+ {
+ if (!($this->bitmap & self::MASK_LOGIN)) {
+ user_error('Operation disallowed prior to login()');
+ return false;
+ }
+
+ if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
+ user_error('Unable to initiate an interactive shell session');
+ return false;
+ }
+
+ $read = array($this->fsock);
+ $write = $except = null;
+ if (stream_select($read, $write, $except, 0)) {
+ $response = $this->_get_binary_packet();
+ return substr($response[self::RESPONSE_DATA], 4);
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Disconnect
+ *
+ * @access public
+ */
+ function disconnect()
+ {
+ $this->_disconnect();
+ }
+
+ /**
+ * Destructor.
+ *
+ * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call
+ * disconnect().
+ *
+ * @access public
+ */
+ function __destruct()
+ {
+ $this->_disconnect();
+ }
+
+ /**
+ * Disconnect
+ *
+ * @param string $msg
+ * @access private
+ */
+ function _disconnect($msg = 'Client Quit')
+ {
+ if ($this->bitmap) {
+ $data = pack('C', NET_SSH1_CMSG_EOF);
+ $this->_send_binary_packet($data);
+ /*
+ $response = $this->_get_binary_packet();
+ if ($response === true) {
+ $response = array(self::RESPONSE_TYPE => -1);
+ }
+ switch ($response[self::RESPONSE_TYPE]) {
+ case NET_SSH1_SMSG_EXITSTATUS:
+ $data = pack('C', NET_SSH1_CMSG_EXIT_CONFIRMATION);
+ break;
+ default:
+ $data = pack('CNa*', NET_SSH1_MSG_DISCONNECT, strlen($msg), $msg);
+ }
+ */
+ $data = pack('CNa*', NET_SSH1_MSG_DISCONNECT, strlen($msg), $msg);
+
+ $this->_send_binary_packet($data);
+ fclose($this->fsock);
+ $this->bitmap = 0;
+ }
+ }
+
+ /**
+ * Gets Binary Packets
+ *
+ * See 'The Binary Packet Protocol' of protocol-1.5.txt for more info.
+ *
+ * Also, this function could be improved upon by adding detection for the following exploit:
+ * http://www.securiteam.com/securitynews/5LP042K3FY.html
+ *
+ * @see self::_send_binary_packet()
+ * @return array
+ * @access private
+ */
+ function _get_binary_packet()
+ {
+ if (feof($this->fsock)) {
+ //user_error('connection closed prematurely');
+ return false;
+ }
+
+ if ($this->curTimeout) {
+ $read = array($this->fsock);
+ $write = $except = null;
+
+ $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+ $sec = floor($this->curTimeout);
+ $usec = 1000000 * ($this->curTimeout - $sec);
+ // on windows this returns a "Warning: Invalid CRT parameters detected" error
+ if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
+ //$this->_disconnect('Timeout');
+ return true;
+ }
+ $elapsed = strtok(microtime(), ' ') + strtok('') - $start;
+ $this->curTimeout-= $elapsed;
+ }
+
+ $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+ $data = fread($this->fsock, 4);
+ if (strlen($data) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $data);
+
+ $padding_length = 8 - ($temp['length'] & 7);
+ $length = $temp['length'] + $padding_length;
+ $raw = '';
+
+ while ($length > 0) {
+ $temp = fread($this->fsock, $length);
+ if (strlen($temp) != $length) {
+ return false;
+ }
+ $raw.= $temp;
+ $length-= strlen($temp);
+ }
+ $stop = strtok(microtime(), ' ') + strtok('');
+
+ if (strlen($raw) && $this->crypto !== false) {
+ $raw = $this->crypto->decrypt($raw);
+ }
+
+ $padding = substr($raw, 0, $padding_length);
+ $type = $raw[$padding_length];
+ $data = substr($raw, $padding_length + 1, -4);
+
+ if (strlen($raw) < 4) {
+ return false;
+ }
+ $temp = unpack('Ncrc', substr($raw, -4));
+
+ //if ( $temp['crc'] != $this->_crc($padding . $type . $data) ) {
+ // user_error('Bad CRC in packet from server');
+ // return false;
+ //}
+
+ $type = ord($type);
+
+ if (defined('NET_SSH1_LOGGING')) {
+ $temp = isset($this->protocol_flags[$type]) ? $this->protocol_flags[$type] : 'UNKNOWN';
+ $temp = '<- ' . $temp .
+ ' (' . round($stop - $start, 4) . 's)';
+ $this->_append_log($temp, $data);
+ }
+
+ return array(
+ self::RESPONSE_TYPE => $type,
+ self::RESPONSE_DATA => $data
+ );
+ }
+
+ /**
+ * Sends Binary Packets
+ *
+ * Returns true on success, false on failure.
+ *
+ * @see self::_get_binary_packet()
+ * @param string $data
+ * @return bool
+ * @access private
+ */
+ function _send_binary_packet($data)
+ {
+ if (feof($this->fsock)) {
+ //user_error('connection closed prematurely');
+ return false;
+ }
+
+ $length = strlen($data) + 4;
+
+ $padding = Random::string(8 - ($length & 7));
+
+ $orig = $data;
+ $data = $padding . $data;
+ $data.= pack('N', $this->_crc($data));
+
+ if ($this->crypto !== false) {
+ $data = $this->crypto->encrypt($data);
+ }
+
+ $packet = pack('Na*', $length, $data);
+
+ $start = strtok(microtime(), ' ') + strtok(''); // http://php.net/microtime#61838
+ $result = strlen($packet) == fputs($this->fsock, $packet);
+ $stop = strtok(microtime(), ' ') + strtok('');
+
+ if (defined('NET_SSH1_LOGGING')) {
+ $temp = isset($this->protocol_flags[ord($orig[0])]) ? $this->protocol_flags[ord($orig[0])] : 'UNKNOWN';
+ $temp = '-> ' . $temp .
+ ' (' . round($stop - $start, 4) . 's)';
+ $this->_append_log($temp, $orig);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Cyclic Redundancy Check (CRC)
+ *
+ * PHP's crc32 function is implemented slightly differently than the one that SSH v1 uses, so
+ * we've reimplemented it. A more detailed discussion of the differences can be found after
+ * $crc_lookup_table's initialization.
+ *
+ * @see self::_get_binary_packet()
+ * @see self::_send_binary_packet()
+ * @param string $data
+ * @return int
+ * @access private
+ */
+ function _crc($data)
+ {
+ static $crc_lookup_table = array(
+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
+ );
+
+ // For this function to yield the same output as PHP's crc32 function, $crc would have to be
+ // set to 0xFFFFFFFF, initially - not 0x00000000 as it currently is.
+ $crc = 0x00000000;
+ $length = strlen($data);
+
+ for ($i=0; $i<$length; $i++) {
+ // We AND $crc >> 8 with 0x00FFFFFF because we want the eight newly added bits to all
+ // be zero. PHP, unfortunately, doesn't always do this. 0x80000000 >> 8, as an example,
+ // yields 0xFF800000 - not 0x00800000. The following link elaborates:
+ // http://www.php.net/manual/en/language.operators.bitwise.php#57281
+ $crc = (($crc >> 8) & 0x00FFFFFF) ^ $crc_lookup_table[($crc & 0xFF) ^ ord($data[$i])];
+ }
+
+ // In addition to having to set $crc to 0xFFFFFFFF, initially, the return value must be XOR'd with
+ // 0xFFFFFFFF for this function to return the same thing that PHP's crc32 function would.
+ return $crc;
+ }
+
+ /**
+ * String Shift
+ *
+ * Inspired by array_shift
+ *
+ * @param string $string
+ * @param int $index
+ * @return string
+ * @access private
+ */
+ function _string_shift(&$string, $index = 1)
+ {
+ $substr = substr($string, 0, $index);
+ $string = substr($string, $index);
+ return $substr;
+ }
+
+ /**
+ * RSA Encrypt
+ *
+ * Returns mod(pow($m, $e), $n), where $n should be the product of two (large) primes $p and $q and where $e
+ * should be a number with the property that gcd($e, ($p - 1) * ($q - 1)) == 1. Could just make anything that
+ * calls this call modexp, instead, but I think this makes things clearer, maybe...
+ *
+ * @see self::__construct()
+ * @param BigInteger $m
+ * @param array $key
+ * @return BigInteger
+ * @access private
+ */
+ function _rsa_crypt($m, $key)
+ {
+ /*
+ $rsa = new RSA();
+ $rsa->loadKey($key, RSA::PUBLIC_FORMAT_RAW);
+ $rsa->setEncryptionMode(RSA::ENCRYPTION_PKCS1);
+ return $rsa->encrypt($m);
+ */
+
+ // To quote from protocol-1.5.txt:
+ // The most significant byte (which is only partial as the value must be
+ // less than the public modulus, which is never a power of two) is zero.
+ //
+ // The next byte contains the value 2 (which stands for public-key
+ // encrypted data in the PKCS standard [PKCS#1]). Then, there are non-
+ // zero random bytes to fill any unused space, a zero byte, and the data
+ // to be encrypted in the least significant bytes, the last byte of the
+ // data in the least significant byte.
+
+ // Presumably the part of PKCS#1 they're refering to is "Section 7.2.1 Encryption Operation",
+ // under "7.2 RSAES-PKCS1-v1.5" and "7 Encryption schemes" of the following URL:
+ // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
+ $modulus = $key[1]->toBytes();
+ $length = strlen($modulus) - strlen($m) - 3;
+ $random = '';
+ while (strlen($random) != $length) {
+ $block = Random::string($length - strlen($random));
+ $block = str_replace("\x00", '', $block);
+ $random.= $block;
+ }
+ $temp = chr(0) . chr(2) . $random . chr(0) . $m;
+
+ $m = new BigInteger($temp, 256);
+ $m = $m->modPow($key[0], $key[1]);
+
+ return $m->toBytes();
+ }
+
+ /**
+ * Define Array
+ *
+ * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of
+ * named constants from it, using the value as the name of the constant and the index as the value of the constant.
+ * If any of the constants that would be defined already exists, none of the constants will be defined.
+ *
+ * @param array $array
+ * @access private
+ */
+ function _define_array()
+ {
+ $args = func_get_args();
+ foreach ($args as $arg) {
+ foreach ($arg as $key => $value) {
+ if (!defined($value)) {
+ define($value, $key);
+ } else {
+ break 2;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a log of the packets that have been sent and received.
+ *
+ * Returns a string if NET_SSH1_LOGGING == self::LOG_COMPLEX, an array if NET_SSH1_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH1_LOGGING')
+ *
+ * @access public
+ * @return array|false|string
+ */
+ function getLog()
+ {
+ if (!defined('NET_SSH1_LOGGING')) {
+ return false;
+ }
+
+ switch (NET_SSH1_LOGGING) {
+ case self::LOG_SIMPLE:
+ return $this->message_number_log;
+ break;
+ case self::LOG_COMPLEX:
+ return $this->_format_log($this->message_log, $this->protocol_flags_log);
+ break;
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Formats a log for printing
+ *
+ * @param array $message_log
+ * @param array $message_number_log
+ * @access private
+ * @return string
+ */
+ function _format_log($message_log, $message_number_log)
+ {
+ $output = '';
+ for ($i = 0; $i < count($message_log); $i++) {
+ $output.= $message_number_log[$i] . "\r\n";
+ $current_log = $message_log[$i];
+ $j = 0;
+ do {
+ if (strlen($current_log)) {
+ $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 ';
+ }
+ $fragment = $this->_string_shift($current_log, $this->log_short_width);
+ $hex = substr(preg_replace_callback('#.#s', array($this, '_format_log_helper'), $fragment), strlen($this->log_boundary));
+ // replace non ASCII printable characters with dots
+ // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters
+ // also replace < with a . since < messes up the output on web browsers
+ $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment);
+ $output.= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n";
+ $j++;
+ } while (strlen($current_log));
+ $output.= "\r\n";
+ }
+
+ return $output;
+ }
+
+ /**
+ * Helper function for _format_log
+ *
+ * For use with preg_replace_callback()
+ *
+ * @param array $matches
+ * @access private
+ * @return string
+ */
+ function _format_log_helper($matches)
+ {
+ return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT);
+ }
+
+ /**
+ * Return the server key public exponent
+ *
+ * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
+ * the raw bytes. This behavior is similar to PHP's md5() function.
+ *
+ * @param bool $raw_output
+ * @return string
+ * @access public
+ */
+ function getServerKeyPublicExponent($raw_output = false)
+ {
+ return $raw_output ? $this->server_key_public_exponent->toBytes() : $this->server_key_public_exponent->toString();
+ }
+
+ /**
+ * Return the server key public modulus
+ *
+ * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
+ * the raw bytes. This behavior is similar to PHP's md5() function.
+ *
+ * @param bool $raw_output
+ * @return string
+ * @access public
+ */
+ function getServerKeyPublicModulus($raw_output = false)
+ {
+ return $raw_output ? $this->server_key_public_modulus->toBytes() : $this->server_key_public_modulus->toString();
+ }
+
+ /**
+ * Return the host key public exponent
+ *
+ * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
+ * the raw bytes. This behavior is similar to PHP's md5() function.
+ *
+ * @param bool $raw_output
+ * @return string
+ * @access public
+ */
+ function getHostKeyPublicExponent($raw_output = false)
+ {
+ return $raw_output ? $this->host_key_public_exponent->toBytes() : $this->host_key_public_exponent->toString();
+ }
+
+ /**
+ * Return the host key public modulus
+ *
+ * Returns, by default, the base-10 representation. If $raw_output is set to true, returns, instead,
+ * the raw bytes. This behavior is similar to PHP's md5() function.
+ *
+ * @param bool $raw_output
+ * @return string
+ * @access public
+ */
+ function getHostKeyPublicModulus($raw_output = false)
+ {
+ return $raw_output ? $this->host_key_public_modulus->toBytes() : $this->host_key_public_modulus->toString();
+ }
+
+ /**
+ * Return a list of ciphers supported by SSH1 server.
+ *
+ * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output
+ * is set to true, returns, instead, an array of constants. ie. instead of array('Triple-DES in CBC mode'), you'll
+ * get array(self::CIPHER_3DES).
+ *
+ * @param bool $raw_output
+ * @return array
+ * @access public
+ */
+ function getSupportedCiphers($raw_output = false)
+ {
+ return $raw_output ? array_keys($this->supported_ciphers) : array_values($this->supported_ciphers);
+ }
+
+ /**
+ * Return a list of authentications supported by SSH1 server.
+ *
+ * Just because a cipher is supported by an SSH1 server doesn't mean it's supported by this library. If $raw_output
+ * is set to true, returns, instead, an array of constants. ie. instead of array('password authentication'), you'll
+ * get array(self::AUTH_PASSWORD).
+ *
+ * @param bool $raw_output
+ * @return array
+ * @access public
+ */
+ function getSupportedAuthentications($raw_output = false)
+ {
+ return $raw_output ? array_keys($this->supported_authentications) : array_values($this->supported_authentications);
+ }
+
+ /**
+ * Return the server identification.
+ *
+ * @return string
+ * @access public
+ */
+ function getServerIdentification()
+ {
+ return rtrim($this->server_identification);
+ }
+
+ /**
+ * Logs data packets
+ *
+ * Makes sure that only the last 1MB worth of packets will be logged
+ *
+ * @param string $data
+ * @access private
+ */
+ function _append_log($protocol_flags, $message)
+ {
+ switch (NET_SSH1_LOGGING) {
+ // useful for benchmarks
+ case self::LOG_SIMPLE:
+ $this->protocol_flags_log[] = $protocol_flags;
+ break;
+ // the most useful log for SSH1
+ case self::LOG_COMPLEX:
+ $this->protocol_flags_log[] = $protocol_flags;
+ $this->_string_shift($message);
+ $this->log_size+= strlen($message);
+ $this->message_log[] = $message;
+ while ($this->log_size > self::LOG_MAX_SIZE) {
+ $this->log_size-= strlen(array_shift($this->message_log));
+ array_shift($this->protocol_flags_log);
+ }
+ break;
+ // dump the output out realtime; packets may be interspersed with non packets,
+ // passwords won't be filtered out and select other packets may not be correctly
+ // identified
+ case self::LOG_REALTIME:
+ echo "<pre>\r\n" . $this->_format_log(array($message), array($protocol_flags)) . "\r\n</pre>\r\n";
+ @flush();
+ @ob_flush();
+ break;
+ // basically the same thing as self::LOG_REALTIME with the caveat that self::LOG_REALTIME_FILE
+ // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE.
+ // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily
+ // at the beginning of the file
+ case self::LOG_REALTIME_FILE:
+ if (!isset($this->realtime_log_file)) {
+ // PHP doesn't seem to like using constants in fopen()
+ $filename = self::LOG_REALTIME_FILE;
+ $fp = fopen($filename, 'w');
+ $this->realtime_log_file = $fp;
+ }
+ if (!is_resource($this->realtime_log_file)) {
+ break;
+ }
+ $entry = $this->_format_log(array($message), array($protocol_flags));
+ if ($this->realtime_log_wrap) {
+ $temp = "<<< START >>>\r\n";
+ $entry.= $temp;
+ fseek($this->realtime_log_file, ftell($this->realtime_log_file) - strlen($temp));
+ }
+ $this->realtime_log_size+= strlen($entry);
+ if ($this->realtime_log_size > self::LOG_MAX_SIZE) {
+ fseek($this->realtime_log_file, 0);
+ $this->realtime_log_size = strlen($entry);
+ $this->realtime_log_wrap = true;
+ }
+ fputs($this->realtime_log_file, $entry);
+ }
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
new file mode 100644
index 0000000..f37a049
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php
@@ -0,0 +1,5091 @@
+<?php
+
+/**
+ * Pure-PHP implementation of SSHv2.
+ *
+ * PHP version 5
+ *
+ * Here are some examples of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
+ * if (!$ssh->login('username', 'password')) {
+ * exit('Login Failed');
+ * }
+ *
+ * echo $ssh->exec('pwd');
+ * echo $ssh->exec('ls -la');
+ * ?>
+ * </code>
+ *
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $key = new \phpseclib\Crypt\RSA();
+ * //$key->setPassword('whatever');
+ * $key->loadKey(file_get_contents('privatekey'));
+ *
+ * $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
+ * if (!$ssh->login('username', $key)) {
+ * exit('Login Failed');
+ * }
+ *
+ * echo $ssh->read('username@username:~$');
+ * $ssh->write("ls -la\n");
+ * echo $ssh->read('username@username:~$');
+ * ?>
+ * </code>
+ *
+ * @category Net
+ * @package SSH2
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2007 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ */
+
+namespace phpseclib\Net;
+
+use phpseclib\Crypt\Base;
+use phpseclib\Crypt\Blowfish;
+use phpseclib\Crypt\Hash;
+use phpseclib\Crypt\Random;
+use phpseclib\Crypt\RC4;
+use phpseclib\Crypt\Rijndael;
+use phpseclib\Crypt\RSA;
+use phpseclib\Crypt\TripleDES;
+use phpseclib\Crypt\Twofish;
+use phpseclib\Math\BigInteger; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification.
+use phpseclib\System\SSH\Agent;
+
+/**
+ * Pure-PHP implementation of SSHv2.
+ *
+ * @package SSH2
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class SSH2
+{
+ /**#@+
+ * Execution Bitmap Masks
+ *
+ * @see \phpseclib\Net\SSH2::bitmap
+ * @access private
+ */
+ const MASK_CONSTRUCTOR = 0x00000001;
+ const MASK_CONNECTED = 0x00000002;
+ const MASK_LOGIN_REQ = 0x00000004;
+ const MASK_LOGIN = 0x00000008;
+ const MASK_SHELL = 0x00000010;
+ const MASK_WINDOW_ADJUST = 0x00000020;
+ /**#@-*/
+
+ /**#@+
+ * Channel constants
+ *
+ * RFC4254 refers not to client and server channels but rather to sender and recipient channels. we don't refer
+ * to them in that way because RFC4254 toggles the meaning. the client sends a SSH_MSG_CHANNEL_OPEN message with
+ * a sender channel and the server sends a SSH_MSG_CHANNEL_OPEN_CONFIRMATION in response, with a sender and a
+ * recepient channel. at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel
+ * would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snipet:
+ * The 'recipient channel' is the channel number given in the original
+ * open request, and 'sender channel' is the channel number allocated by
+ * the other side.
+ *
+ * @see \phpseclib\Net\SSH2::_send_channel_packet()
+ * @see \phpseclib\Net\SSH2::_get_channel_packet()
+ * @access private
+ */
+ const CHANNEL_EXEC = 1; // PuTTy uses 0x100
+ const CHANNEL_SHELL = 2;
+ const CHANNEL_SUBSYSTEM = 3;
+ const CHANNEL_AGENT_FORWARD = 4;
+ const CHANNEL_KEEP_ALIVE = 5;
+ /**#@-*/
+
+ /**#@+
+ * @access public
+ * @see \phpseclib\Net\SSH2::getLog()
+ */
+ /**
+ * Returns the message numbers
+ */
+ const LOG_SIMPLE = 1;
+ /**
+ * Returns the message content
+ */
+ const LOG_COMPLEX = 2;
+ /**
+ * Outputs the content real-time
+ */
+ const LOG_REALTIME = 3;
+ /**
+ * Dumps the content real-time to a file
+ */
+ const LOG_REALTIME_FILE = 4;
+ /**
+ * Make sure that the log never gets larger than this
+ */
+ const LOG_MAX_SIZE = 1048576; // 1024 * 1024
+ /**#@-*/
+
+ /**#@+
+ * @access public
+ * @see \phpseclib\Net\SSH2::read()
+ */
+ /**
+ * Returns when a string matching $expect exactly is found
+ */
+ const READ_SIMPLE = 1;
+ /**
+ * Returns when a string matching the regular expression $expect is found
+ */
+ const READ_REGEX = 2;
+ /**
+ * Returns whenever a data packet is received.
+ *
+ * Some data packets may only contain a single character so it may be necessary
+ * to call read() multiple times when using this option
+ */
+ const READ_NEXT = 3;
+ /**#@-*/
+
+ /**
+ * The SSH identifier
+ *
+ * @var string
+ * @access private
+ */
+ var $identifier;
+
+ /**
+ * The Socket Object
+ *
+ * @var object
+ * @access private
+ */
+ var $fsock;
+
+ /**
+ * Execution Bitmap
+ *
+ * The bits that are set represent functions that have been called already. This is used to determine
+ * if a requisite function has been successfully executed. If not, an error should be thrown.
+ *
+ * @var int
+ * @access private
+ */
+ var $bitmap = 0;
+
+ /**
+ * Error information
+ *
+ * @see self::getErrors()
+ * @see self::getLastError()
+ * @var string
+ * @access private
+ */
+ var $errors = array();
+
+ /**
+ * Server Identifier
+ *
+ * @see self::getServerIdentification()
+ * @var array|false
+ * @access private
+ */
+ var $server_identifier = false;
+
+ /**
+ * Key Exchange Algorithms
+ *
+ * @see self::getKexAlgorithims()
+ * @var array|false
+ * @access private
+ */
+ var $kex_algorithms = false;
+
+ /**
+ * Key Exchange Algorithm
+ *
+ * @see self::getMethodsNegotiated()
+ * @var string|false
+ * @access private
+ */
+ var $kex_algorithm = false;
+
+ /**
+ * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
+ *
+ * @see self::_key_exchange()
+ * @var int
+ * @access private
+ */
+ var $kex_dh_group_size_min = 1536;
+
+ /**
+ * Preferred Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
+ *
+ * @see self::_key_exchange()
+ * @var int
+ * @access private
+ */
+ var $kex_dh_group_size_preferred = 2048;
+
+ /**
+ * Maximum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods
+ *
+ * @see self::_key_exchange()
+ * @var int
+ * @access private
+ */
+ var $kex_dh_group_size_max = 4096;
+
+ /**
+ * Server Host Key Algorithms
+ *
+ * @see self::getServerHostKeyAlgorithms()
+ * @var array|false
+ * @access private
+ */
+ var $server_host_key_algorithms = false;
+
+ /**
+ * Encryption Algorithms: Client to Server
+ *
+ * @see self::getEncryptionAlgorithmsClient2Server()
+ * @var array|false
+ * @access private
+ */
+ var $encryption_algorithms_client_to_server = false;
+
+ /**
+ * Encryption Algorithms: Server to Client
+ *
+ * @see self::getEncryptionAlgorithmsServer2Client()
+ * @var array|false
+ * @access private
+ */
+ var $encryption_algorithms_server_to_client = false;
+
+ /**
+ * MAC Algorithms: Client to Server
+ *
+ * @see self::getMACAlgorithmsClient2Server()
+ * @var array|false
+ * @access private
+ */
+ var $mac_algorithms_client_to_server = false;
+
+ /**
+ * MAC Algorithms: Server to Client
+ *
+ * @see self::getMACAlgorithmsServer2Client()
+ * @var array|false
+ * @access private
+ */
+ var $mac_algorithms_server_to_client = false;
+
+ /**
+ * Compression Algorithms: Client to Server
+ *
+ * @see self::getCompressionAlgorithmsClient2Server()
+ * @var array|false
+ * @access private
+ */
+ var $compression_algorithms_client_to_server = false;
+
+ /**
+ * Compression Algorithms: Server to Client
+ *
+ * @see self::getCompressionAlgorithmsServer2Client()
+ * @var array|false
+ * @access private
+ */
+ var $compression_algorithms_server_to_client = false;
+
+ /**
+ * Languages: Server to Client
+ *
+ * @see self::getLanguagesServer2Client()
+ * @var array|false
+ * @access private
+ */
+ var $languages_server_to_client = false;
+
+ /**
+ * Languages: Client to Server
+ *
+ * @see self::getLanguagesClient2Server()
+ * @var array|false
+ * @access private
+ */
+ var $languages_client_to_server = false;
+
+ /**
+ * Preferred Algorithms
+ *
+ * @see self::setPreferredAlgorithms()
+ * @var array
+ * @access private
+ */
+ var $preferred = array();
+
+ /**
+ * Block Size for Server to Client Encryption
+ *
+ * "Note that the length of the concatenation of 'packet_length',
+ * 'padding_length', 'payload', and 'random padding' MUST be a multiple
+ * of the cipher block size or 8, whichever is larger. This constraint
+ * MUST be enforced, even when using stream ciphers."
+ *
+ * -- http://tools.ietf.org/html/rfc4253#section-6
+ *
+ * @see self::__construct()
+ * @see self::_send_binary_packet()
+ * @var int
+ * @access private
+ */
+ var $encrypt_block_size = 8;
+
+ /**
+ * Block Size for Client to Server Encryption
+ *
+ * @see self::__construct()
+ * @see self::_get_binary_packet()
+ * @var int
+ * @access private
+ */
+ var $decrypt_block_size = 8;
+
+ /**
+ * Server to Client Encryption Object
+ *
+ * @see self::_get_binary_packet()
+ * @var object
+ * @access private
+ */
+ var $decrypt = false;
+
+ /**
+ * Client to Server Encryption Object
+ *
+ * @see self::_send_binary_packet()
+ * @var object
+ * @access private
+ */
+ var $encrypt = false;
+
+ /**
+ * Client to Server HMAC Object
+ *
+ * @see self::_send_binary_packet()
+ * @var object
+ * @access private
+ */
+ var $hmac_create = false;
+
+ /**
+ * Server to Client HMAC Object
+ *
+ * @see self::_get_binary_packet()
+ * @var object
+ * @access private
+ */
+ var $hmac_check = false;
+
+ /**
+ * Size of server to client HMAC
+ *
+ * We need to know how big the HMAC will be for the server to client direction so that we know how many bytes to read.
+ * For the client to server side, the HMAC object will make the HMAC as long as it needs to be. All we need to do is
+ * append it.
+ *
+ * @see self::_get_binary_packet()
+ * @var int
+ * @access private
+ */
+ var $hmac_size = false;
+
+ /**
+ * Server Public Host Key
+ *
+ * @see self::getServerPublicHostKey()
+ * @var string
+ * @access private
+ */
+ var $server_public_host_key;
+
+ /**
+ * Session identifier
+ *
+ * "The exchange hash H from the first key exchange is additionally
+ * used as the session identifier, which is a unique identifier for
+ * this connection."
+ *
+ * -- http://tools.ietf.org/html/rfc4253#section-7.2
+ *
+ * @see self::_key_exchange()
+ * @var string
+ * @access private
+ */
+ var $session_id = false;
+
+ /**
+ * Exchange hash
+ *
+ * The current exchange hash
+ *
+ * @see self::_key_exchange()
+ * @var string
+ * @access private
+ */
+ var $exchange_hash = false;
+
+ /**
+ * Message Numbers
+ *
+ * @see self::__construct()
+ * @var array
+ * @access private
+ */
+ var $message_numbers = array();
+
+ /**
+ * Disconnection Message 'reason codes' defined in RFC4253
+ *
+ * @see self::__construct()
+ * @var array
+ * @access private
+ */
+ var $disconnect_reasons = array();
+
+ /**
+ * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254
+ *
+ * @see self::__construct()
+ * @var array
+ * @access private
+ */
+ var $channel_open_failure_reasons = array();
+
+ /**
+ * Terminal Modes
+ *
+ * @link http://tools.ietf.org/html/rfc4254#section-8
+ * @see self::__construct()
+ * @var array
+ * @access private
+ */
+ var $terminal_modes = array();
+
+ /**
+ * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes
+ *
+ * @link http://tools.ietf.org/html/rfc4254#section-5.2
+ * @see self::__construct()
+ * @var array
+ * @access private
+ */
+ var $channel_extended_data_type_codes = array();
+
+ /**
+ * Send Sequence Number
+ *
+ * See 'Section 6.4. Data Integrity' of rfc4253 for more info.
+ *
+ * @see self::_send_binary_packet()
+ * @var int
+ * @access private
+ */
+ var $send_seq_no = 0;
+
+ /**
+ * Get Sequence Number
+ *
+ * See 'Section 6.4. Data Integrity' of rfc4253 for more info.
+ *
+ * @see self::_get_binary_packet()
+ * @var int
+ * @access private
+ */
+ var $get_seq_no = 0;
+
+ /**
+ * Server Channels
+ *
+ * Maps client channels to server channels
+ *
+ * @see self::_get_channel_packet()
+ * @see self::exec()
+ * @var array
+ * @access private
+ */
+ var $server_channels = array();
+
+ /**
+ * Channel Buffers
+ *
+ * If a client requests a packet from one channel but receives two packets from another those packets should
+ * be placed in a buffer
+ *
+ * @see self::_get_channel_packet()
+ * @see self::exec()
+ * @var array
+ * @access private
+ */
+ var $channel_buffers = array();
+
+ /**
+ * Channel Status
+ *
+ * Contains the type of the last sent message
+ *
+ * @see self::_get_channel_packet()
+ * @var array
+ * @access private
+ */
+ var $channel_status = array();
+
+ /**
+ * Packet Size
+ *
+ * Maximum packet size indexed by channel
+ *
+ * @see self::_send_channel_packet()
+ * @var array
+ * @access private
+ */
+ var $packet_size_client_to_server = array();
+
+ /**
+ * Message Number Log
+ *
+ * @see self::getLog()
+ * @var array
+ * @access private
+ */
+ var $message_number_log = array();
+
+ /**
+ * Message Log
+ *
+ * @see self::getLog()
+ * @var array
+ * @access private
+ */
+ var $message_log = array();
+
+ /**
+ * The Window Size
+ *
+ * Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 2GB)
+ *
+ * @var int
+ * @see self::_send_channel_packet()
+ * @see self::exec()
+ * @access private
+ */
+ var $window_size = 0x7FFFFFFF;
+
+ /**
+ * What we resize the window to
+ *
+ * When PuTTY resizes the window it doesn't add an additional 0x7FFFFFFF bytes - it adds 0x40000000 bytes.
+ * Some SFTP clients (GoAnywhere) don't support adding 0x7FFFFFFF to the window size after the fact so
+ * we'll just do what PuTTY does
+ *
+ * @var int
+ * @see self::_send_channel_packet()
+ * @see self::exec()
+ * @access private
+ */
+ var $window_resize = 0x40000000;
+
+ /**
+ * Window size, server to client
+ *
+ * Window size indexed by channel
+ *
+ * @see self::_send_channel_packet()
+ * @var array
+ * @access private
+ */
+ var $window_size_server_to_client = array();
+
+ /**
+ * Window size, client to server
+ *
+ * Window size indexed by channel
+ *
+ * @see self::_get_channel_packet()
+ * @var array
+ * @access private
+ */
+ var $window_size_client_to_server = array();
+
+ /**
+ * Server signature
+ *
+ * Verified against $this->session_id
+ *
+ * @see self::getServerPublicHostKey()
+ * @var string
+ * @access private
+ */
+ var $signature = '';
+
+ /**
+ * Server signature format
+ *
+ * ssh-rsa or ssh-dss.
+ *
+ * @see self::getServerPublicHostKey()
+ * @var string
+ * @access private
+ */
+ var $signature_format = '';
+
+ /**
+ * Interactive Buffer
+ *
+ * @see self::read()
+ * @var array
+ * @access private
+ */
+ var $interactiveBuffer = '';
+
+ /**
+ * Current log size
+ *
+ * Should never exceed self::LOG_MAX_SIZE
+ *
+ * @see self::_send_binary_packet()
+ * @see self::_get_binary_packet()
+ * @var int
+ * @access private
+ */
+ var $log_size;
+
+ /**
+ * Timeout
+ *
+ * @see self::setTimeout()
+ * @access private
+ */
+ var $timeout;
+
+ /**
+ * Current Timeout
+ *
+ * @see self::_get_channel_packet()
+ * @access private
+ */
+ var $curTimeout;
+
+ /**
+ * Real-time log file pointer
+ *
+ * @see self::_append_log()
+ * @var resource
+ * @access private
+ */
+ var $realtime_log_file;
+
+ /**
+ * Real-time log file size
+ *
+ * @see self::_append_log()
+ * @var int
+ * @access private
+ */
+ var $realtime_log_size;
+
+ /**
+ * Has the signature been validated?
+ *
+ * @see self::getServerPublicHostKey()
+ * @var bool
+ * @access private
+ */
+ var $signature_validated = false;
+
+ /**
+ * Real-time log file wrap boolean
+ *
+ * @see self::_append_log()
+ * @access private
+ */
+ var $realtime_log_wrap;
+
+ /**
+ * Flag to suppress stderr from output
+ *
+ * @see self::enableQuietMode()
+ * @access private
+ */
+ var $quiet_mode = false;
+
+ /**
+ * Time of first network activity
+ *
+ * @var int
+ * @access private
+ */
+ var $last_packet;
+
+ /**
+ * Exit status returned from ssh if any
+ *
+ * @var int
+ * @access private
+ */
+ var $exit_status;
+
+ /**
+ * Flag to request a PTY when using exec()
+ *
+ * @var bool
+ * @see self::enablePTY()
+ * @access private
+ */
+ var $request_pty = false;
+
+ /**
+ * Flag set while exec() is running when using enablePTY()
+ *
+ * @var bool
+ * @access private
+ */
+ var $in_request_pty_exec = false;
+
+ /**
+ * Flag set after startSubsystem() is called
+ *
+ * @var bool
+ * @access private
+ */
+ var $in_subsystem;
+
+ /**
+ * Contents of stdError
+ *
+ * @var string
+ * @access private
+ */
+ var $stdErrorLog;
+
+ /**
+ * The Last Interactive Response
+ *
+ * @see self::_keyboard_interactive_process()
+ * @var string
+ * @access private
+ */
+ var $last_interactive_response = '';
+
+ /**
+ * Keyboard Interactive Request / Responses
+ *
+ * @see self::_keyboard_interactive_process()
+ * @var array
+ * @access private
+ */
+ var $keyboard_requests_responses = array();
+
+ /**
+ * Banner Message
+ *
+ * Quoting from the RFC, "in some jurisdictions, sending a warning message before
+ * authentication may be relevant for getting legal protection."
+ *
+ * @see self::_filter()
+ * @see self::getBannerMessage()
+ * @var string
+ * @access private
+ */
+ var $banner_message = '';
+
+ /**
+ * Did read() timeout or return normally?
+ *
+ * @see self::isTimeout()
+ * @var bool
+ * @access private
+ */
+ var $is_timeout = false;
+
+ /**
+ * Log Boundary
+ *
+ * @see self::_format_log()
+ * @var string
+ * @access private
+ */
+ var $log_boundary = ':';
+
+ /**
+ * Log Long Width
+ *
+ * @see self::_format_log()
+ * @var int
+ * @access private
+ */
+ var $log_long_width = 65;
+
+ /**
+ * Log Short Width
+ *
+ * @see self::_format_log()
+ * @var int
+ * @access private
+ */
+ var $log_short_width = 16;
+
+ /**
+ * Hostname
+ *
+ * @see self::__construct()
+ * @see self::_connect()
+ * @var string
+ * @access private
+ */
+ var $host;
+
+ /**
+ * Port Number
+ *
+ * @see self::__construct()
+ * @see self::_connect()
+ * @var int
+ * @access private
+ */
+ var $port;
+
+ /**
+ * Number of columns for terminal window size
+ *
+ * @see self::getWindowColumns()
+ * @see self::setWindowColumns()
+ * @see self::setWindowSize()
+ * @var int
+ * @access private
+ */
+ var $windowColumns = 80;
+
+ /**
+ * Number of columns for terminal window size
+ *
+ * @see self::getWindowRows()
+ * @see self::setWindowRows()
+ * @see self::setWindowSize()
+ * @var int
+ * @access private
+ */
+ var $windowRows = 24;
+
+ /**
+ * Crypto Engine
+ *
+ * @see self::setCryptoEngine()
+ * @see self::_key_exchange()
+ * @var int
+ * @access private
+ */
+ var $crypto_engine = false;
+
+ /**
+ * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario
+ *
+ * @var System_SSH_Agent
+ * @access private
+ */
+ var $agent;
+
+ /**
+ * Send the identification string first?
+ *
+ * @var bool
+ * @access private
+ */
+ var $send_id_string_first = true;
+
+ /**
+ * Send the key exchange initiation packet first?
+ *
+ * @var bool
+ * @access private
+ */
+ var $send_kex_first = true;
+
+ /**
+ * Some versions of OpenSSH incorrectly calculate the key size
+ *
+ * @var bool
+ * @access private
+ */
+ var $bad_key_size_fix = false;
+
+ /**
+ * Should we try to re-connect to re-establish keys?
+ *
+ * @var bool
+ * @access private
+ */
+ var $retry_connect = false;
+
+ /**
+ * Binary Packet Buffer
+ *
+ * @var string|false
+ * @access private
+ */
+ var $binary_packet_buffer = false;
+
+ /**
+ * Preferred Signature Format
+ *
+ * @var string|false
+ * @access private
+ */
+ var $preferred_signature_format = false;
+
+ /**
+ * Authentication Credentials
+ *
+ * @var array
+ * @access private
+ */
+ var $auth = array();
+
+ /**
+ * Default Constructor.
+ *
+ * $host can either be a string, representing the host, or a stream resource.
+ *
+ * @param mixed $host
+ * @param int $port
+ * @param int $timeout
+ * @see self::login()
+ * @return \phpseclib\Net\SSH2
+ * @access public
+ */
+ function __construct($host, $port = 22, $timeout = 10)
+ {
+ $this->message_numbers = array(
+ 1 => 'NET_SSH2_MSG_DISCONNECT',
+ 2 => 'NET_SSH2_MSG_IGNORE',
+ 3 => 'NET_SSH2_MSG_UNIMPLEMENTED',
+ 4 => 'NET_SSH2_MSG_DEBUG',
+ 5 => 'NET_SSH2_MSG_SERVICE_REQUEST',
+ 6 => 'NET_SSH2_MSG_SERVICE_ACCEPT',
+ 20 => 'NET_SSH2_MSG_KEXINIT',
+ 21 => 'NET_SSH2_MSG_NEWKEYS',
+ 30 => 'NET_SSH2_MSG_KEXDH_INIT',
+ 31 => 'NET_SSH2_MSG_KEXDH_REPLY',
+ 50 => 'NET_SSH2_MSG_USERAUTH_REQUEST',
+ 51 => 'NET_SSH2_MSG_USERAUTH_FAILURE',
+ 52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS',
+ 53 => 'NET_SSH2_MSG_USERAUTH_BANNER',
+
+ 80 => 'NET_SSH2_MSG_GLOBAL_REQUEST',
+ 81 => 'NET_SSH2_MSG_REQUEST_SUCCESS',
+ 82 => 'NET_SSH2_MSG_REQUEST_FAILURE',
+ 90 => 'NET_SSH2_MSG_CHANNEL_OPEN',
+ 91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION',
+ 92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE',
+ 93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST',
+ 94 => 'NET_SSH2_MSG_CHANNEL_DATA',
+ 95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA',
+ 96 => 'NET_SSH2_MSG_CHANNEL_EOF',
+ 97 => 'NET_SSH2_MSG_CHANNEL_CLOSE',
+ 98 => 'NET_SSH2_MSG_CHANNEL_REQUEST',
+ 99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS',
+ 100 => 'NET_SSH2_MSG_CHANNEL_FAILURE'
+ );
+ $this->disconnect_reasons = array(
+ 1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT',
+ 2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR',
+ 3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED',
+ 4 => 'NET_SSH2_DISCONNECT_RESERVED',
+ 5 => 'NET_SSH2_DISCONNECT_MAC_ERROR',
+ 6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR',
+ 7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE',
+ 8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED',
+ 9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE',
+ 10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST',
+ 11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION',
+ 12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS',
+ 13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER',
+ 14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE',
+ 15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME'
+ );
+ $this->channel_open_failure_reasons = array(
+ 1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED'
+ );
+ $this->terminal_modes = array(
+ 0 => 'NET_SSH2_TTY_OP_END'
+ );
+ $this->channel_extended_data_type_codes = array(
+ 1 => 'NET_SSH2_EXTENDED_DATA_STDERR'
+ );
+
+ $this->_define_array(
+ $this->message_numbers,
+ $this->disconnect_reasons,
+ $this->channel_open_failure_reasons,
+ $this->terminal_modes,
+ $this->channel_extended_data_type_codes,
+ array(60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'),
+ array(60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'),
+ array(60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST',
+ 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'),
+ // RFC 4419 - diffie-hellman-group-exchange-sha{1,256}
+ array(30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD',
+ 31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP',
+ 32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT',
+ 33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY',
+ 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'),
+ // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org)
+ array(30 => 'NET_SSH2_MSG_KEX_ECDH_INIT',
+ 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY')
+ );
+
+ if (is_resource($host)) {
+ $this->fsock = $host;
+ return;
+ }
+
+ if (is_string($host)) {
+ $this->host = $host;
+ $this->port = $port;
+ $this->timeout = $timeout;
+ }
+ }
+
+ /**
+ * Set Crypto Engine Mode
+ *
+ * Possible $engine values:
+ * CRYPT_MODE_INTERNAL, CRYPT_MODE_MCRYPT
+ *
+ * @param int $engine
+ * @access public
+ */
+ function setCryptoEngine($engine)
+ {
+ $this->crypto_engine = $engine;
+ }
+
+ /**
+ * Send Identification String First
+ *
+ * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established,
+ * both sides MUST send an identification string". It does not say which side sends it first. In
+ * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+ *
+ * @access public
+ */
+ function sendIdentificationStringFirst()
+ {
+ $this->send_id_string_first = true;
+ }
+
+ /**
+ * Send Identification String Last
+ *
+ * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established,
+ * both sides MUST send an identification string". It does not say which side sends it first. In
+ * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+ *
+ * @access public
+ */
+ function sendIdentificationStringLast()
+ {
+ $this->send_id_string_first = false;
+ }
+
+ /**
+ * Send SSH_MSG_KEXINIT First
+ *
+ * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending
+ * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory
+ * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+ *
+ * @access public
+ */
+ function sendKEXINITFirst()
+ {
+ $this->send_kex_first = true;
+ }
+
+ /**
+ * Send SSH_MSG_KEXINIT Last
+ *
+ * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending
+ * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory
+ * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy
+ *
+ * @access public
+ */
+ function sendKEXINITLast()
+ {
+ $this->send_kex_first = false;
+ }
+
+ /**
+ * Connect to an SSHv2 server
+ *
+ * @return bool
+ * @access private
+ */
+ function _connect()
+ {
+ if ($this->bitmap & self::MASK_CONSTRUCTOR) {
+ return false;
+ }
+
+ $this->bitmap |= self::MASK_CONSTRUCTOR;
+
+ $this->curTimeout = $this->timeout;
+
+ $this->last_packet = microtime(true);
+
+ if (!is_resource($this->fsock)) {
+ $start = microtime(true);
+ // with stream_select a timeout of 0 means that no timeout takes place;
+ // with fsockopen a timeout of 0 means that you instantly timeout
+ // to resolve this incompatibility a timeout of 100,000 will be used for fsockopen if timeout is 0
+ $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout == 0 ? 100000 : $this->curTimeout);
+ if (!$this->fsock) {
+ $host = $this->host . ':' . $this->port;
+ user_error(rtrim("Cannot connect to $host. Error $errno. $errstr"));
+ return false;
+ }
+ $elapsed = microtime(true) - $start;
+
+ if ($this->curTimeout) {
+ $this->curTimeout-= $elapsed;
+ if ($this->curTimeout < 0) {
+ $this->is_timeout = true;
+ return false;
+ }
+ }
+ }
+
+ $this->identifier = $this->_generate_identifier();
+
+ if ($this->send_id_string_first) {
+ fputs($this->fsock, $this->identifier . "\r\n");
+ }
+
+ /* According to the SSH2 specs,
+
+ "The server MAY send other lines of data before sending the version
+ string. Each line SHOULD be terminated by a Carriage Return and Line
+ Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded
+ in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients
+ MUST be able to process such lines." */
+ $data = '';
+ while (!feof($this->fsock) && !preg_match('#(.*)^(SSH-(\d\.\d+).*)#ms', $data, $matches)) {
+ $line = '';
+ while (true) {
+ if ($this->curTimeout) {
+ if ($this->curTimeout < 0) {
+ $this->is_timeout = true;
+ return false;
+ }
+ $read = array($this->fsock);
+ $write = $except = null;
+ $start = microtime(true);
+ $sec = floor($this->curTimeout);
+ $usec = 1000000 * ($this->curTimeout - $sec);
+ // on windows this returns a "Warning: Invalid CRT parameters detected" error
+ // the !count() is done as a workaround for <https://bugs.php.net/42682>
+ if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
+ $this->is_timeout = true;
+ return false;
+ }
+ $elapsed = microtime(true) - $start;
+ $this->curTimeout-= $elapsed;
+ }
+
+ $temp = stream_get_line($this->fsock, 255, "\n");
+ if (strlen($temp) == 255) {
+ continue;
+ }
+ if ($temp === false) {
+ return false;
+ }
+
+ $line.= "$temp\n";
+
+ // quoting RFC4253, "Implementers who wish to maintain
+ // compatibility with older, undocumented versions of this protocol may
+ // want to process the identification string without expecting the
+ // presence of the carriage return character for reasons described in
+ // Section 5 of this document."
+
+ //if (substr($line, -2) == "\r\n") {
+ // break;
+ //}
+
+ break;
+ }
+
+ $data.= $line;
+ }
+
+ if (feof($this->fsock)) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ $extra = $matches[1];
+
+ if (defined('NET_SSH2_LOGGING')) {
+ $this->_append_log('<-', $matches[0]);
+ $this->_append_log('->', $this->identifier . "\r\n");
+ }
+
+ $this->server_identifier = trim($temp, "\r\n");
+ if (strlen($extra)) {
+ $this->errors[] = $data;
+ }
+
+ if (version_compare($matches[3], '1.99', '<')) {
+ user_error("Cannot connect to SSH $matches[3] servers");
+ return false;
+ }
+
+ if (!$this->send_id_string_first) {
+ fputs($this->fsock, $this->identifier . "\r\n");
+ }
+
+ if (!$this->send_kex_first) {
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (!strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) {
+ user_error('Expected SSH_MSG_KEXINIT');
+ return false;
+ }
+
+ if (!$this->_key_exchange($response)) {
+ return false;
+ }
+ }
+
+ if ($this->send_kex_first && !$this->_key_exchange()) {
+ return false;
+ }
+
+ $this->bitmap|= self::MASK_CONNECTED;
+
+ return true;
+ }
+
+ /**
+ * Generates the SSH identifier
+ *
+ * You should overwrite this method in your own class if you want to use another identifier
+ *
+ * @access protected
+ * @return string
+ */
+ function _generate_identifier()
+ {
+ $identifier = 'SSH-2.0-phpseclib_2.0';
+
+ $ext = array();
+ if (function_exists('sodium_crypto_box_publickey_from_secretkey')) {
+ $ext[] = 'libsodium';
+ }
+
+ if (extension_loaded('openssl')) {
+ $ext[] = 'openssl';
+ } elseif (extension_loaded('mcrypt')) {
+ $ext[] = 'mcrypt';
+ }
+
+ if (extension_loaded('gmp')) {
+ $ext[] = 'gmp';
+ } elseif (extension_loaded('bcmath')) {
+ $ext[] = 'bcmath';
+ }
+
+ if (!empty($ext)) {
+ $identifier .= ' (' . implode(', ', $ext) . ')';
+ }
+
+ return $identifier;
+ }
+
+ /**
+ * Key Exchange
+ *
+ * @param string $kexinit_payload_server optional
+ * @access private
+ */
+ function _key_exchange($kexinit_payload_server = false)
+ {
+ $preferred = $this->preferred;
+
+ $kex_algorithms = isset($preferred['kex']) ?
+ $preferred['kex'] :
+ $this->getSupportedKEXAlgorithms();
+ $server_host_key_algorithms = isset($preferred['hostkey']) ?
+ $preferred['hostkey'] :
+ $this->getSupportedHostKeyAlgorithms();
+ $s2c_encryption_algorithms = isset($preferred['server_to_client']['crypt']) ?
+ $preferred['server_to_client']['crypt'] :
+ $this->getSupportedEncryptionAlgorithms();
+ $c2s_encryption_algorithms = isset($preferred['client_to_server']['crypt']) ?
+ $preferred['client_to_server']['crypt'] :
+ $this->getSupportedEncryptionAlgorithms();
+ $s2c_mac_algorithms = isset($preferred['server_to_client']['mac']) ?
+ $preferred['server_to_client']['mac'] :
+ $this->getSupportedMACAlgorithms();
+ $c2s_mac_algorithms = isset($preferred['client_to_server']['mac']) ?
+ $preferred['client_to_server']['mac'] :
+ $this->getSupportedMACAlgorithms();
+ $s2c_compression_algorithms = isset($preferred['server_to_client']['comp']) ?
+ $preferred['server_to_client']['comp'] :
+ $this->getSupportedCompressionAlgorithms();
+ $c2s_compression_algorithms = isset($preferred['client_to_server']['comp']) ?
+ $preferred['client_to_server']['comp'] :
+ $this->getSupportedCompressionAlgorithms();
+
+ // some SSH servers have buggy implementations of some of the above algorithms
+ switch (true) {
+ case $this->server_identifier == 'SSH-2.0-SSHD':
+ case substr($this->server_identifier, 0, 13) == 'SSH-2.0-DLINK':
+ if (!isset($preferred['server_to_client']['mac'])) {
+ $s2c_mac_algorithms = array_values(array_diff(
+ $s2c_mac_algorithms,
+ array('hmac-sha1-96', 'hmac-md5-96')
+ ));
+ }
+ if (!isset($preferred['client_to_server']['mac'])) {
+ $c2s_mac_algorithms = array_values(array_diff(
+ $c2s_mac_algorithms,
+ array('hmac-sha1-96', 'hmac-md5-96')
+ ));
+ }
+ }
+
+ $str_kex_algorithms = implode(',', $kex_algorithms);
+ $str_server_host_key_algorithms = implode(',', $server_host_key_algorithms);
+ $encryption_algorithms_server_to_client = implode(',', $s2c_encryption_algorithms);
+ $encryption_algorithms_client_to_server = implode(',', $c2s_encryption_algorithms);
+ $mac_algorithms_server_to_client = implode(',', $s2c_mac_algorithms);
+ $mac_algorithms_client_to_server = implode(',', $c2s_mac_algorithms);
+ $compression_algorithms_server_to_client = implode(',', $s2c_compression_algorithms);
+ $compression_algorithms_client_to_server = implode(',', $c2s_compression_algorithms);
+
+ $client_cookie = Random::string(16);
+
+ $kexinit_payload_client = pack(
+ 'Ca*Na*Na*Na*Na*Na*Na*Na*Na*Na*Na*CN',
+ NET_SSH2_MSG_KEXINIT,
+ $client_cookie,
+ strlen($str_kex_algorithms),
+ $str_kex_algorithms,
+ strlen($str_server_host_key_algorithms),
+ $str_server_host_key_algorithms,
+ strlen($encryption_algorithms_client_to_server),
+ $encryption_algorithms_client_to_server,
+ strlen($encryption_algorithms_server_to_client),
+ $encryption_algorithms_server_to_client,
+ strlen($mac_algorithms_client_to_server),
+ $mac_algorithms_client_to_server,
+ strlen($mac_algorithms_server_to_client),
+ $mac_algorithms_server_to_client,
+ strlen($compression_algorithms_client_to_server),
+ $compression_algorithms_client_to_server,
+ strlen($compression_algorithms_server_to_client),
+ $compression_algorithms_server_to_client,
+ 0,
+ '',
+ 0,
+ '',
+ 0,
+ 0
+ );
+
+ if ($this->send_kex_first) {
+ if (!$this->_send_binary_packet($kexinit_payload_client)) {
+ return false;
+ }
+
+ $kexinit_payload_server = $this->_get_binary_packet();
+ if ($kexinit_payload_server === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (!strlen($kexinit_payload_server) || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT) {
+ user_error('Expected SSH_MSG_KEXINIT');
+ return false;
+ }
+ }
+
+ $response = $kexinit_payload_server;
+ $this->_string_shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT)
+ $server_cookie = $this->_string_shift($response, 16);
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->kex_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->server_host_key_algorithms = explode(',', $this->_string_shift($response, $temp['length']));
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->encryption_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->encryption_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->mac_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->mac_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->compression_algorithms_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->compression_algorithms_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->languages_client_to_server = explode(',', $this->_string_shift($response, $temp['length']));
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->languages_server_to_client = explode(',', $this->_string_shift($response, $temp['length']));
+
+ if (!strlen($response)) {
+ return false;
+ }
+ extract(unpack('Cfirst_kex_packet_follows', $this->_string_shift($response, 1)));
+ $first_kex_packet_follows = $first_kex_packet_follows != 0;
+
+ if (!$this->send_kex_first && !$this->_send_binary_packet($kexinit_payload_client)) {
+ return false;
+ }
+
+ // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange
+ // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the
+ // diffie-hellman key exchange as fast as possible
+ $decrypt = $this->_array_intersect_first($s2c_encryption_algorithms, $this->encryption_algorithms_server_to_client);
+ $decryptKeyLength = $this->_encryption_algorithm_to_key_size($decrypt);
+ if ($decryptKeyLength === null) {
+ user_error('No compatible server to client encryption algorithms found');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+
+ $encrypt = $this->_array_intersect_first($c2s_encryption_algorithms, $this->encryption_algorithms_client_to_server);
+ $encryptKeyLength = $this->_encryption_algorithm_to_key_size($encrypt);
+ if ($encryptKeyLength === null) {
+ user_error('No compatible client to server encryption algorithms found');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+
+ // through diffie-hellman key exchange a symmetric key is obtained
+ $this->kex_algorithm = $kex_algorithm = $this->_array_intersect_first($kex_algorithms, $this->kex_algorithms);
+ if ($kex_algorithm === false) {
+ user_error('No compatible key exchange algorithms found');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+
+ // Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty.
+ $exchange_hash_rfc4419 = '';
+
+ if ($kex_algorithm === 'curve25519-sha256@libssh.org') {
+ $x = Random::string(32);
+ $eBytes = sodium_crypto_box_publickey_from_secretkey($x);
+ $clientKexInitMessage = 'NET_SSH2_MSG_KEX_ECDH_INIT';
+ $serverKexReplyMessage = 'NET_SSH2_MSG_KEX_ECDH_REPLY';
+ $kexHash = new Hash('sha256');
+ } else {
+ if (strpos($kex_algorithm, 'diffie-hellman-group-exchange') === 0) {
+ $dh_group_sizes_packed = pack(
+ 'NNN',
+ $this->kex_dh_group_size_min,
+ $this->kex_dh_group_size_preferred,
+ $this->kex_dh_group_size_max
+ );
+ $packet = pack(
+ 'Ca*',
+ NET_SSH2_MSG_KEXDH_GEX_REQUEST,
+ $dh_group_sizes_packed
+ );
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+ $this->_updateLogHistory('UNKNOWN (34)', 'NET_SSH2_MSG_KEXDH_GEX_REQUEST');
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+ if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) {
+ user_error('Expected SSH_MSG_KEX_DH_GEX_GROUP');
+ return false;
+ }
+ $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEXDH_GEX_GROUP');
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('NprimeLength', $this->_string_shift($response, 4)));
+ $primeBytes = $this->_string_shift($response, $primeLength);
+ $prime = new BigInteger($primeBytes, -256);
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('NgLength', $this->_string_shift($response, 4)));
+ $gBytes = $this->_string_shift($response, $gLength);
+ $g = new BigInteger($gBytes, -256);
+
+ $exchange_hash_rfc4419 = pack(
+ 'a*Na*Na*',
+ $dh_group_sizes_packed,
+ $primeLength,
+ $primeBytes,
+ $gLength,
+ $gBytes
+ );
+
+ $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_GEX_INIT';
+ $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_GEX_REPLY';
+ } else {
+ switch ($kex_algorithm) {
+ // see http://tools.ietf.org/html/rfc2409#section-6.2 and
+ // http://tools.ietf.org/html/rfc2412, appendex E
+ case 'diffie-hellman-group1-sha1':
+ $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
+ '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
+ '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
+ 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF';
+ break;
+ // see http://tools.ietf.org/html/rfc3526#section-3
+ case 'diffie-hellman-group14-sha1':
+ $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' .
+ '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' .
+ '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' .
+ 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' .
+ '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' .
+ '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' .
+ 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' .
+ '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF';
+ break;
+ }
+ // For both diffie-hellman-group1-sha1 and diffie-hellman-group14-sha1
+ // the generator field element is 2 (decimal) and the hash function is sha1.
+ $g = new BigInteger(2);
+ $prime = new BigInteger($prime, 16);
+ $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_INIT';
+ $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_REPLY';
+ }
+
+ switch ($kex_algorithm) {
+ case 'diffie-hellman-group-exchange-sha256':
+ $kexHash = new Hash('sha256');
+ break;
+ default:
+ $kexHash = new Hash('sha1');
+ }
+
+ /* To increase the speed of the key exchange, both client and server may
+ reduce the size of their private exponents. It should be at least
+ twice as long as the key material that is generated from the shared
+ secret. For more details, see the paper by van Oorschot and Wiener
+ [VAN-OORSCHOT].
+
+ -- http://tools.ietf.org/html/rfc4419#section-6.2 */
+ $one = new BigInteger(1);
+ $keyLength = min($kexHash->getLength(), max($encryptKeyLength, $decryptKeyLength));
+ $max = $one->bitwise_leftShift(16 * $keyLength); // 2 * 8 * $keyLength
+ $max = $max->subtract($one);
+
+ $x = $one->random($one, $max);
+ $e = $g->modPow($x, $prime);
+
+ $eBytes = $e->toBytes(true);
+ }
+ $data = pack('CNa*', constant($clientKexInitMessage), strlen($eBytes), $eBytes);
+
+ if (!$this->_send_binary_packet($data)) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+ switch ($clientKexInitMessage) {
+ case 'NET_SSH2_MSG_KEX_ECDH_INIT':
+ $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_INIT', 'NET_SSH2_MSG_KEX_ECDH_INIT');
+ break;
+ case 'NET_SSH2_MSG_KEXDH_GEX_INIT':
+ $this->_updateLogHistory('UNKNOWN (32)', 'NET_SSH2_MSG_KEXDH_GEX_INIT');
+ }
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+ if (!strlen($response)) {
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+ if ($type != constant($serverKexReplyMessage)) {
+ user_error("Expected $serverKexReplyMessage");
+ return false;
+ }
+ switch ($serverKexReplyMessage) {
+ case 'NET_SSH2_MSG_KEX_ECDH_REPLY':
+ $this->_updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEX_ECDH_REPLY');
+ break;
+ case 'NET_SSH2_MSG_KEXDH_GEX_REPLY':
+ $this->_updateLogHistory('UNKNOWN (33)', 'NET_SSH2_MSG_KEXDH_GEX_REPLY');
+ }
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->server_public_host_key = $server_public_host_key = $this->_string_shift($response, $temp['length']);
+
+ if (strlen($server_public_host_key) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+ $public_key_format = $this->_string_shift($server_public_host_key, $temp['length']);
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $fBytes = $this->_string_shift($response, $temp['length']);
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($response, 4));
+ $this->signature = $this->_string_shift($response, $temp['length']);
+
+ if (strlen($this->signature) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($this->signature, 4));
+ $this->signature_format = $this->_string_shift($this->signature, $temp['length']);
+
+ if ($kex_algorithm === 'curve25519-sha256@libssh.org') {
+ if (strlen($fBytes) !== 32) {
+ user_error('Received curve25519 public key of invalid length.');
+ return false;
+ }
+ $key = new BigInteger(sodium_crypto_scalarmult($x, $fBytes), 256);
+ // sodium_compat doesn't emulate sodium_memzero
+ // also, with v1 of libsodium API the extension identifies itself as
+ // libsodium whereas v2 of the libsodium API (what PHP 7.2+ includes)
+ // identifies itself as sodium. sodium_compat uses the v1 API to
+ // emulate the v2 API if it's the v1 API that's available
+ if (extension_loaded('sodium') || extension_loaded('libsodium')) {
+ sodium_memzero($x);
+ }
+ } else {
+ $f = new BigInteger($fBytes, -256);
+ $key = $f->modPow($x, $prime);
+ }
+ $keyBytes = $key->toBytes(true);
+
+ $this->exchange_hash = pack(
+ 'Na*Na*Na*Na*Na*a*Na*Na*Na*',
+ strlen($this->identifier),
+ $this->identifier,
+ strlen($this->server_identifier),
+ $this->server_identifier,
+ strlen($kexinit_payload_client),
+ $kexinit_payload_client,
+ strlen($kexinit_payload_server),
+ $kexinit_payload_server,
+ strlen($this->server_public_host_key),
+ $this->server_public_host_key,
+ $exchange_hash_rfc4419,
+ strlen($eBytes),
+ $eBytes,
+ strlen($fBytes),
+ $fBytes,
+ strlen($keyBytes),
+ $keyBytes
+ );
+
+ $this->exchange_hash = $kexHash->hash($this->exchange_hash);
+
+ if ($this->session_id === false) {
+ $this->session_id = $this->exchange_hash;
+ }
+
+ $server_host_key_algorithm = $this->_array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms);
+ if ($server_host_key_algorithm === false) {
+ user_error('No compatible server host key algorithms found');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+
+ switch ($server_host_key_algorithm) {
+ case 'ssh-dss':
+ $expected_key_format = 'ssh-dss';
+ break;
+ //case 'rsa-sha2-256':
+ //case 'rsa-sha2-512':
+ //case 'ssh-rsa':
+ default:
+ $expected_key_format = 'ssh-rsa';
+ }
+
+ if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) {
+ switch (true) {
+ case $this->signature_format == $server_host_key_algorithm:
+ case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512':
+ case $this->signature_format != 'ssh-rsa':
+ user_error('Server Host Key Algorithm Mismatch');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+ }
+
+ $packet = pack(
+ 'C',
+ NET_SSH2_MSG_NEWKEYS
+ );
+
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $response = $this->_get_binary_packet();
+
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (!strlen($response)) {
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+ if ($type != NET_SSH2_MSG_NEWKEYS) {
+ user_error('Expected SSH_MSG_NEWKEYS');
+ return false;
+ }
+
+ $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes);
+
+ $this->encrypt = $this->_encryption_algorithm_to_crypt_instance($encrypt);
+ if ($this->encrypt) {
+ if ($this->crypto_engine) {
+ $this->encrypt->setPreferredEngine($this->crypto_engine);
+ }
+ if ($this->encrypt->block_size) {
+ $this->encrypt_block_size = $this->encrypt->block_size;
+ }
+ $this->encrypt->enableContinuousBuffer();
+ $this->encrypt->disablePadding();
+
+ if ($this->encrypt->getBlockLength()) {
+ $this->encrypt_block_size = $this->encrypt->getBlockLength() >> 3;
+ }
+
+ $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id);
+ while ($this->encrypt_block_size > strlen($iv)) {
+ $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
+ }
+ $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size));
+
+ $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id);
+ while ($encryptKeyLength > strlen($key)) {
+ $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
+ }
+ $this->encrypt->setKey(substr($key, 0, $encryptKeyLength));
+
+ $this->encrypt->name = $decrypt;
+ }
+
+ $this->decrypt = $this->_encryption_algorithm_to_crypt_instance($decrypt);
+ if ($this->decrypt) {
+ if ($this->crypto_engine) {
+ $this->decrypt->setPreferredEngine($this->crypto_engine);
+ }
+ if ($this->decrypt->block_size) {
+ $this->decrypt_block_size = $this->decrypt->block_size;
+ }
+ $this->decrypt->enableContinuousBuffer();
+ $this->decrypt->disablePadding();
+
+ if ($this->decrypt->getBlockLength()) {
+ $this->decrypt_block_size = $this->decrypt->getBlockLength() >> 3;
+ }
+
+ $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id);
+ while ($this->decrypt_block_size > strlen($iv)) {
+ $iv.= $kexHash->hash($keyBytes . $this->exchange_hash . $iv);
+ }
+ $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size));
+
+ $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id);
+ while ($decryptKeyLength > strlen($key)) {
+ $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
+ }
+ $this->decrypt->setKey(substr($key, 0, $decryptKeyLength));
+
+ $this->decrypt->name = $decrypt;
+ }
+
+ /* The "arcfour128" algorithm is the RC4 cipher, as described in
+ [SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream
+ generated by the cipher MUST be discarded, and the first byte of the
+ first encrypted packet MUST be encrypted using the 1537th byte of
+ keystream.
+
+ -- http://tools.ietf.org/html/rfc4345#section-4 */
+ if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') {
+ $this->encrypt->encrypt(str_repeat("\0", 1536));
+ }
+ if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') {
+ $this->decrypt->decrypt(str_repeat("\0", 1536));
+ }
+
+ $mac_algorithm = $this->_array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server);
+ if ($mac_algorithm === false) {
+ user_error('No compatible client to server message authentication algorithms found');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+
+ $createKeyLength = 0; // ie. $mac_algorithm == 'none'
+ switch ($mac_algorithm) {
+ case 'hmac-sha2-256':
+ $this->hmac_create = new Hash('sha256');
+ $createKeyLength = 32;
+ break;
+ case 'hmac-sha1':
+ $this->hmac_create = new Hash('sha1');
+ $createKeyLength = 20;
+ break;
+ case 'hmac-sha1-96':
+ $this->hmac_create = new Hash('sha1-96');
+ $createKeyLength = 20;
+ break;
+ case 'hmac-md5':
+ $this->hmac_create = new Hash('md5');
+ $createKeyLength = 16;
+ break;
+ case 'hmac-md5-96':
+ $this->hmac_create = new Hash('md5-96');
+ $createKeyLength = 16;
+ }
+ $this->hmac_create->name = $mac_algorithm;
+
+ $mac_algorithm = $this->_array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client);
+ if ($mac_algorithm === false) {
+ user_error('No compatible server to client message authentication algorithms found');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+
+ $checkKeyLength = 0;
+ $this->hmac_size = 0;
+ switch ($mac_algorithm) {
+ case 'hmac-sha2-256':
+ $this->hmac_check = new Hash('sha256');
+ $checkKeyLength = 32;
+ $this->hmac_size = 32;
+ break;
+ case 'hmac-sha1':
+ $this->hmac_check = new Hash('sha1');
+ $checkKeyLength = 20;
+ $this->hmac_size = 20;
+ break;
+ case 'hmac-sha1-96':
+ $this->hmac_check = new Hash('sha1-96');
+ $checkKeyLength = 20;
+ $this->hmac_size = 12;
+ break;
+ case 'hmac-md5':
+ $this->hmac_check = new Hash('md5');
+ $checkKeyLength = 16;
+ $this->hmac_size = 16;
+ break;
+ case 'hmac-md5-96':
+ $this->hmac_check = new Hash('md5-96');
+ $checkKeyLength = 16;
+ $this->hmac_size = 12;
+ }
+ $this->hmac_check->name = $mac_algorithm;
+
+ $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id);
+ while ($createKeyLength > strlen($key)) {
+ $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
+ }
+ $this->hmac_create->setKey(substr($key, 0, $createKeyLength));
+
+ $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id);
+ while ($checkKeyLength > strlen($key)) {
+ $key.= $kexHash->hash($keyBytes . $this->exchange_hash . $key);
+ }
+ $this->hmac_check->setKey(substr($key, 0, $checkKeyLength));
+
+ $compression_algorithm = $this->_array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server);
+ if ($compression_algorithm === false) {
+ user_error('No compatible client to server compression algorithms found');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+ //$this->decompress = $compression_algorithm == 'zlib';
+
+ $compression_algorithm = $this->_array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_client_to_server);
+ if ($compression_algorithm === false) {
+ user_error('No compatible server to client compression algorithms found');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+ //$this->compress = $compression_algorithm == 'zlib';
+
+ return true;
+ }
+
+ /**
+ * Maps an encryption algorithm name to the number of key bytes.
+ *
+ * @param string $algorithm Name of the encryption algorithm
+ * @return int|null Number of bytes as an integer or null for unknown
+ * @access private
+ */
+ function _encryption_algorithm_to_key_size($algorithm)
+ {
+ if ($this->bad_key_size_fix && $this->_bad_algorithm_candidate($algorithm)) {
+ return 16;
+ }
+
+ switch ($algorithm) {
+ case 'none':
+ return 0;
+ case 'aes128-cbc':
+ case 'aes128-ctr':
+ case 'arcfour':
+ case 'arcfour128':
+ case 'blowfish-cbc':
+ case 'blowfish-ctr':
+ case 'twofish128-cbc':
+ case 'twofish128-ctr':
+ return 16;
+ case '3des-cbc':
+ case '3des-ctr':
+ case 'aes192-cbc':
+ case 'aes192-ctr':
+ case 'twofish192-cbc':
+ case 'twofish192-ctr':
+ return 24;
+ case 'aes256-cbc':
+ case 'aes256-ctr':
+ case 'arcfour256':
+ case 'twofish-cbc':
+ case 'twofish256-cbc':
+ case 'twofish256-ctr':
+ return 32;
+ }
+ return null;
+ }
+
+ /**
+ * Maps an encryption algorithm name to an instance of a subclass of
+ * \phpseclib\Crypt\Base.
+ *
+ * @param string $algorithm Name of the encryption algorithm
+ * @return mixed Instance of \phpseclib\Crypt\Base or null for unknown
+ * @access private
+ */
+ function _encryption_algorithm_to_crypt_instance($algorithm)
+ {
+ switch ($algorithm) {
+ case '3des-cbc':
+ return new TripleDES();
+ case '3des-ctr':
+ return new TripleDES(Base::MODE_CTR);
+ case 'aes256-cbc':
+ case 'aes192-cbc':
+ case 'aes128-cbc':
+ return new Rijndael();
+ case 'aes256-ctr':
+ case 'aes192-ctr':
+ case 'aes128-ctr':
+ return new Rijndael(Base::MODE_CTR);
+ case 'blowfish-cbc':
+ return new Blowfish();
+ case 'blowfish-ctr':
+ return new Blowfish(Base::MODE_CTR);
+ case 'twofish128-cbc':
+ case 'twofish192-cbc':
+ case 'twofish256-cbc':
+ case 'twofish-cbc':
+ return new Twofish();
+ case 'twofish128-ctr':
+ case 'twofish192-ctr':
+ case 'twofish256-ctr':
+ return new Twofish(Base::MODE_CTR);
+ case 'arcfour':
+ case 'arcfour128':
+ case 'arcfour256':
+ return new RC4();
+ }
+ return null;
+ }
+
+ /**
+ * Tests whether or not proposed algorithm has a potential for issues
+ *
+ * @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html
+ * @link https://bugzilla.mindrot.org/show_bug.cgi?id=1291
+ * @param string $algorithm Name of the encryption algorithm
+ * @return bool
+ * @access private
+ */
+ function _bad_algorithm_candidate($algorithm)
+ {
+ switch ($algorithm) {
+ case 'arcfour256':
+ case 'aes192-ctr':
+ case 'aes256-ctr':
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Login
+ *
+ * The $password parameter can be a plaintext password, a \phpseclib\Crypt\RSA object or an array
+ *
+ * @param string $username
+ * @param mixed $password
+ * @param mixed $...
+ * @return bool
+ * @see self::_login()
+ * @access public
+ */
+ function login($username)
+ {
+ $args = func_get_args();
+ $this->auth[] = $args;
+
+ // try logging with 'none' as an authentication method first since that's what
+ // PuTTY does
+ if ($this->_login($username)) {
+ return true;
+ }
+ if (count($args) == 1) {
+ return false;
+ }
+ return call_user_func_array(array(&$this, '_login'), $args);
+ }
+
+ /**
+ * Login Helper
+ *
+ * @param string $username
+ * @param mixed $password
+ * @param mixed $...
+ * @return bool
+ * @see self::_login_helper()
+ * @access private
+ */
+ function _login($username)
+ {
+ if (!($this->bitmap & self::MASK_CONSTRUCTOR)) {
+ if (!$this->_connect()) {
+ return false;
+ }
+ }
+
+ $args = array_slice(func_get_args(), 1);
+ if (empty($args)) {
+ return $this->_login_helper($username);
+ }
+
+ foreach ($args as $arg) {
+ if ($this->_login_helper($username, $arg)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Login Helper
+ *
+ * @param string $username
+ * @param string $password
+ * @return bool
+ * @access private
+ * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
+ * by sending dummy SSH_MSG_IGNORE messages.
+ */
+ function _login_helper($username, $password = null)
+ {
+ if (!($this->bitmap & self::MASK_CONNECTED)) {
+ return false;
+ }
+
+ if (!($this->bitmap & self::MASK_LOGIN_REQ)) {
+ $packet = pack(
+ 'CNa*',
+ NET_SSH2_MSG_SERVICE_REQUEST,
+ strlen('ssh-userauth'),
+ 'ssh-userauth'
+ );
+
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ if ($this->retry_connect) {
+ $this->retry_connect = false;
+ if (!$this->_connect()) {
+ return false;
+ }
+ return $this->_login_helper($username, $password);
+ }
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+ if ($type != NET_SSH2_MSG_SERVICE_ACCEPT) {
+ user_error('Expected SSH_MSG_SERVICE_ACCEPT');
+ return false;
+ }
+ $this->bitmap |= self::MASK_LOGIN_REQ;
+ }
+
+ if (strlen($this->last_interactive_response)) {
+ return !is_string($password) && !is_array($password) ? false : $this->_keyboard_interactive_process($password);
+ }
+
+ if ($password instanceof RSA) {
+ return $this->_privatekey_login($username, $password);
+ } elseif ($password instanceof Agent) {
+ return $this->_ssh_agent_login($username, $password);
+ }
+
+ if (is_array($password)) {
+ if ($this->_keyboard_interactive_login($username, $password)) {
+ $this->bitmap |= self::MASK_LOGIN;
+ return true;
+ }
+ return false;
+ }
+
+ if (!isset($password)) {
+ $packet = pack(
+ 'CNa*Na*Na*',
+ NET_SSH2_MSG_USERAUTH_REQUEST,
+ strlen($username),
+ $username,
+ strlen('ssh-connection'),
+ 'ssh-connection',
+ strlen('none'),
+ 'none'
+ );
+
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (!strlen($response)) {
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+ switch ($type) {
+ case NET_SSH2_MSG_USERAUTH_SUCCESS:
+ $this->bitmap |= self::MASK_LOGIN;
+ return true;
+ //case NET_SSH2_MSG_USERAUTH_FAILURE:
+ default:
+ return false;
+ }
+ }
+
+ $packet = pack(
+ 'CNa*Na*Na*CNa*',
+ NET_SSH2_MSG_USERAUTH_REQUEST,
+ strlen($username),
+ $username,
+ strlen('ssh-connection'),
+ 'ssh-connection',
+ strlen('password'),
+ 'password',
+ 0,
+ strlen($password),
+ $password
+ );
+
+ // remove the username and password from the logged packet
+ if (!defined('NET_SSH2_LOGGING')) {
+ $logged = null;
+ } else {
+ $logged = pack(
+ 'CNa*Na*Na*CNa*',
+ NET_SSH2_MSG_USERAUTH_REQUEST,
+ strlen('username'),
+ 'username',
+ strlen('ssh-connection'),
+ 'ssh-connection',
+ strlen('password'),
+ 'password',
+ 0,
+ strlen('password'),
+ 'password'
+ );
+ }
+
+ if (!$this->_send_binary_packet($packet, $logged)) {
+ return false;
+ }
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (!strlen($response)) {
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+ switch ($type) {
+ case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed
+ $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ');
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $this->_string_shift($response, $length);
+ return $this->_disconnect(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
+ case NET_SSH2_MSG_USERAUTH_FAILURE:
+ // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees
+ // multi-factor authentication
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $auth_methods = explode(',', $this->_string_shift($response, $length));
+ if (!strlen($response)) {
+ return false;
+ }
+ extract(unpack('Cpartial_success', $this->_string_shift($response, 1)));
+ $partial_success = $partial_success != 0;
+
+ if (!$partial_success && in_array('keyboard-interactive', $auth_methods)) {
+ if ($this->_keyboard_interactive_login($username, $password)) {
+ $this->bitmap |= self::MASK_LOGIN;
+ return true;
+ }
+ return false;
+ }
+ return false;
+ case NET_SSH2_MSG_USERAUTH_SUCCESS:
+ $this->bitmap |= self::MASK_LOGIN;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Login via keyboard-interactive authentication
+ *
+ * See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator.
+ *
+ * @param string $username
+ * @param string $password
+ * @return bool
+ * @access private
+ */
+ function _keyboard_interactive_login($username, $password)
+ {
+ $packet = pack(
+ 'CNa*Na*Na*Na*Na*',
+ NET_SSH2_MSG_USERAUTH_REQUEST,
+ strlen($username),
+ $username,
+ strlen('ssh-connection'),
+ 'ssh-connection',
+ strlen('keyboard-interactive'),
+ 'keyboard-interactive',
+ 0,
+ '',
+ 0,
+ ''
+ );
+
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ return $this->_keyboard_interactive_process($password);
+ }
+
+ /**
+ * Handle the keyboard-interactive requests / responses.
+ *
+ * @param string $responses...
+ * @return bool
+ * @access private
+ */
+ function _keyboard_interactive_process()
+ {
+ $responses = func_get_args();
+
+ if (strlen($this->last_interactive_response)) {
+ $response = $this->last_interactive_response;
+ } else {
+ $orig = $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+ }
+
+ if (!strlen($response)) {
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+ switch ($type) {
+ case NET_SSH2_MSG_USERAUTH_INFO_REQUEST:
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $this->_string_shift($response, $length); // name; may be empty
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $this->_string_shift($response, $length); // instruction; may be empty
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $this->_string_shift($response, $length); // language tag; may be empty
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nnum_prompts', $this->_string_shift($response, 4)));
+
+ for ($i = 0; $i < count($responses); $i++) {
+ if (is_array($responses[$i])) {
+ foreach ($responses[$i] as $key => $value) {
+ $this->keyboard_requests_responses[$key] = $value;
+ }
+ unset($responses[$i]);
+ }
+ }
+ $responses = array_values($responses);
+
+ if (isset($this->keyboard_requests_responses)) {
+ for ($i = 0; $i < $num_prompts; $i++) {
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ // prompt - ie. "Password: "; must not be empty
+ $prompt = $this->_string_shift($response, $length);
+ //$echo = $this->_string_shift($response) != chr(0);
+ foreach ($this->keyboard_requests_responses as $key => $value) {
+ if (substr($prompt, 0, strlen($key)) == $key) {
+ $responses[] = $value;
+ break;
+ }
+ }
+ }
+ }
+
+ // see http://tools.ietf.org/html/rfc4256#section-3.2
+ if (strlen($this->last_interactive_response)) {
+ $this->last_interactive_response = '';
+ } else {
+ $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST');
+ }
+
+ if (!count($responses) && $num_prompts) {
+ $this->last_interactive_response = $orig;
+ return false;
+ }
+
+ /*
+ After obtaining the requested information from the user, the client
+ MUST respond with an SSH_MSG_USERAUTH_INFO_RESPONSE message.
+ */
+ // see http://tools.ietf.org/html/rfc4256#section-3.4
+ $packet = $logged = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses));
+ for ($i = 0; $i < count($responses); $i++) {
+ $packet.= pack('Na*', strlen($responses[$i]), $responses[$i]);
+ $logged.= pack('Na*', strlen('dummy-answer'), 'dummy-answer');
+ }
+
+ if (!$this->_send_binary_packet($packet, $logged)) {
+ return false;
+ }
+
+ $this->_updateLogHistory('UNKNOWN (61)', 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE');
+
+ /*
+ After receiving the response, the server MUST send either an
+ SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another
+ SSH_MSG_USERAUTH_INFO_REQUEST message.
+ */
+ // maybe phpseclib should force close the connection after x request / responses? unless something like that is done
+ // there could be an infinite loop of request / responses.
+ return $this->_keyboard_interactive_process();
+ case NET_SSH2_MSG_USERAUTH_SUCCESS:
+ return true;
+ case NET_SSH2_MSG_USERAUTH_FAILURE:
+ return false;
+ }
+
+ return false;
+ }
+
+ /**
+ * Login with an ssh-agent provided key
+ *
+ * @param string $username
+ * @param \phpseclib\System\SSH\Agent $agent
+ * @return bool
+ * @access private
+ */
+ function _ssh_agent_login($username, $agent)
+ {
+ $this->agent = $agent;
+ $keys = $agent->requestIdentities();
+ foreach ($keys as $key) {
+ if ($this->_privatekey_login($username, $key)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Login with an RSA private key
+ *
+ * @param string $username
+ * @param \phpseclib\Crypt\RSA $password
+ * @return bool
+ * @access private
+ * @internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis}
+ * by sending dummy SSH_MSG_IGNORE messages.
+ */
+ function _privatekey_login($username, $privatekey)
+ {
+ // see http://tools.ietf.org/html/rfc4253#page-15
+ $publickey = $privatekey->getPublicKey(RSA::PUBLIC_FORMAT_RAW);
+ if ($publickey === false) {
+ return false;
+ }
+
+ $publickey = array(
+ 'e' => $publickey['e']->toBytes(true),
+ 'n' => $publickey['n']->toBytes(true)
+ );
+ $publickey = pack(
+ 'Na*Na*Na*',
+ strlen('ssh-rsa'),
+ 'ssh-rsa',
+ strlen($publickey['e']),
+ $publickey['e'],
+ strlen($publickey['n']),
+ $publickey['n']
+ );
+
+ switch ($this->signature_format) {
+ case 'rsa-sha2-512':
+ $hash = 'sha512';
+ $signatureType = 'rsa-sha2-512';
+ break;
+ case 'rsa-sha2-256':
+ $hash = 'sha256';
+ $signatureType = 'rsa-sha2-256';
+ break;
+ //case 'ssh-rsa':
+ default:
+ $hash = 'sha1';
+ $signatureType = 'ssh-rsa';
+ }
+
+ $part1 = pack(
+ 'CNa*Na*Na*',
+ NET_SSH2_MSG_USERAUTH_REQUEST,
+ strlen($username),
+ $username,
+ strlen('ssh-connection'),
+ 'ssh-connection',
+ strlen('publickey'),
+ 'publickey'
+ );
+ $part2 = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($publickey), $publickey);
+
+ $packet = $part1 . chr(0) . $part2;
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (!strlen($response)) {
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+ switch ($type) {
+ case NET_SSH2_MSG_USERAUTH_FAILURE:
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE: ' . $this->_string_shift($response, $length);
+ return false;
+ case NET_SSH2_MSG_USERAUTH_PK_OK:
+ // we'll just take it on faith that the public key blob and the public key algorithm name are as
+ // they should be
+ $this->_updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK');
+ }
+
+ $packet = $part1 . chr(1) . $part2;
+ $privatekey->setSignatureMode(RSA::SIGNATURE_PKCS1);
+ $privatekey->setHash($hash);
+ $signature = $privatekey->sign(pack('Na*a*', strlen($this->session_id), $this->session_id, $packet));
+ $signature = pack('Na*Na*', strlen($signatureType), $signatureType, strlen($signature), $signature);
+ $packet.= pack('Na*', strlen($signature), $signature);
+
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (!strlen($response)) {
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+ switch ($type) {
+ case NET_SSH2_MSG_USERAUTH_FAILURE:
+ // either the login is bad or the server employs multi-factor authentication
+ return false;
+ case NET_SSH2_MSG_USERAUTH_SUCCESS:
+ $this->bitmap |= self::MASK_LOGIN;
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Set Timeout
+ *
+ * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout.
+ * Setting $timeout to false or 0 will mean there is no timeout.
+ *
+ * @param mixed $timeout
+ * @access public
+ */
+ function setTimeout($timeout)
+ {
+ $this->timeout = $this->curTimeout = $timeout;
+ }
+
+ /**
+ * Get the output from stdError
+ *
+ * @access public
+ */
+ function getStdError()
+ {
+ return $this->stdErrorLog;
+ }
+
+ /**
+ * Execute Command
+ *
+ * If $callback is set to false then \phpseclib\Net\SSH2::_get_channel_packet(self::CHANNEL_EXEC) will need to be called manually.
+ * In all likelihood, this is not a feature you want to be taking advantage of.
+ *
+ * @param string $command
+ * @param Callback $callback
+ * @return string
+ * @access public
+ */
+ function exec($command, $callback = null)
+ {
+ $this->curTimeout = $this->timeout;
+ $this->is_timeout = false;
+ $this->stdErrorLog = '';
+
+ if (!$this->isAuthenticated()) {
+ return false;
+ }
+
+ if ($this->in_request_pty_exec) {
+ user_error('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.');
+ return false;
+ }
+
+ // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to
+ // be adjusted". 0x7FFFFFFF is, at 2GB, the max size. technically, it should probably be decremented, but,
+ // honestly, if you're transferring more than 2GB, you probably shouldn't be using phpseclib, anyway.
+ // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info
+ $this->window_size_server_to_client[self::CHANNEL_EXEC] = $this->window_size;
+ // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy
+ // uses 0x4000, that's what will be used here, as well.
+ $packet_size = 0x4000;
+
+ $packet = pack(
+ 'CNa*N3',
+ NET_SSH2_MSG_CHANNEL_OPEN,
+ strlen('session'),
+ 'session',
+ self::CHANNEL_EXEC,
+ $this->window_size_server_to_client[self::CHANNEL_EXEC],
+ $packet_size
+ );
+
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_OPEN;
+
+ $response = $this->_get_channel_packet(self::CHANNEL_EXEC);
+ if ($response === false) {
+ return false;
+ }
+
+ if ($this->request_pty === true) {
+ $terminal_modes = pack('C', NET_SSH2_TTY_OP_END);
+ $packet = pack(
+ 'CNNa*CNa*N5a*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL_EXEC],
+ strlen('pty-req'),
+ 'pty-req',
+ 1,
+ strlen('vt100'),
+ 'vt100',
+ $this->windowColumns,
+ $this->windowRows,
+ 0,
+ 0,
+ strlen($terminal_modes),
+ $terminal_modes
+ );
+
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (!strlen($response)) {
+ return false;
+ }
+ list(, $type) = unpack('C', $this->_string_shift($response, 1));
+
+ switch ($type) {
+ case NET_SSH2_MSG_CHANNEL_SUCCESS:
+ break;
+ case NET_SSH2_MSG_CHANNEL_FAILURE:
+ default:
+ user_error('Unable to request pseudo-terminal');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+ }
+ $this->in_request_pty_exec = true;
+ }
+
+ // sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things
+ // down. the one place where it might be desirable is if you're doing something like \phpseclib\Net\SSH2::exec('ping localhost &').
+ // with a pty-req SSH_MSG_CHANNEL_REQUEST, exec() will return immediately and the ping process will then
+ // then immediately terminate. without such a request exec() will loop indefinitely. the ping process won't end but
+ // neither will your script.
+
+ // although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by
+ // SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the
+ // "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA. RFC4254#section-5.2 corroborates.
+ $packet = pack(
+ 'CNNa*CNa*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL_EXEC],
+ strlen('exec'),
+ 'exec',
+ 1,
+ strlen($command),
+ $command
+ );
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+ $response = $this->_get_channel_packet(self::CHANNEL_EXEC);
+ if ($response === false) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA;
+
+ if ($callback === false || $this->in_request_pty_exec) {
+ return true;
+ }
+
+ $output = '';
+ while (true) {
+ $temp = $this->_get_channel_packet(self::CHANNEL_EXEC);
+ switch (true) {
+ case $temp === true:
+ return is_callable($callback) ? true : $output;
+ case $temp === false:
+ return false;
+ default:
+ if (is_callable($callback)) {
+ if (call_user_func($callback, $temp) === true) {
+ $this->_close_channel(self::CHANNEL_EXEC);
+ return true;
+ }
+ } else {
+ $output.= $temp;
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates an interactive shell
+ *
+ * @see self::read()
+ * @see self::write()
+ * @return bool
+ * @access private
+ */
+ function _initShell()
+ {
+ if ($this->in_request_pty_exec === true) {
+ return true;
+ }
+
+ $this->window_size_server_to_client[self::CHANNEL_SHELL] = $this->window_size;
+ $packet_size = 0x4000;
+
+ $packet = pack(
+ 'CNa*N3',
+ NET_SSH2_MSG_CHANNEL_OPEN,
+ strlen('session'),
+ 'session',
+ self::CHANNEL_SHELL,
+ $this->window_size_server_to_client[self::CHANNEL_SHELL],
+ $packet_size
+ );
+
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_OPEN;
+
+ $response = $this->_get_channel_packet(self::CHANNEL_SHELL);
+ if ($response === false) {
+ return false;
+ }
+
+ $terminal_modes = pack('C', NET_SSH2_TTY_OP_END);
+ $packet = pack(
+ 'CNNa*CNa*N5a*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL_SHELL],
+ strlen('pty-req'),
+ 'pty-req',
+ 1,
+ strlen('vt100'),
+ 'vt100',
+ $this->windowColumns,
+ $this->windowRows,
+ 0,
+ 0,
+ strlen($terminal_modes),
+ $terminal_modes
+ );
+
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $response = $this->_get_binary_packet();
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+
+ if (!strlen($response)) {
+ return false;
+ }
+ list(, $type) = unpack('C', $this->_string_shift($response, 1));
+
+ switch ($type) {
+ case NET_SSH2_MSG_CHANNEL_SUCCESS:
+ // if a pty can't be opened maybe commands can still be executed
+ case NET_SSH2_MSG_CHANNEL_FAILURE:
+ break;
+ default:
+ user_error('Unable to request pseudo-terminal');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+ }
+
+ $packet = pack(
+ 'CNNa*C',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL_SHELL],
+ strlen('shell'),
+ 'shell',
+ 1
+ );
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+ $response = $this->_get_channel_packet(self::CHANNEL_SHELL);
+ if ($response === false) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA;
+
+ $this->bitmap |= self::MASK_SHELL;
+
+ return true;
+ }
+
+ /**
+ * Return the channel to be used with read() / write()
+ *
+ * @see self::read()
+ * @see self::write()
+ * @return int
+ * @access public
+ */
+ function _get_interactive_channel()
+ {
+ switch (true) {
+ case $this->in_subsystem:
+ return self::CHANNEL_SUBSYSTEM;
+ case $this->in_request_pty_exec:
+ return self::CHANNEL_EXEC;
+ default:
+ return self::CHANNEL_SHELL;
+ }
+ }
+
+ /**
+ * Return an available open channel
+ *
+ * @return int
+ * @access public
+ */
+ function _get_open_channel()
+ {
+ $channel = self::CHANNEL_EXEC;
+ do {
+ if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_OPEN) {
+ return $channel;
+ }
+ } while ($channel++ < self::CHANNEL_SUBSYSTEM);
+
+ return false;
+ }
+
+ /**
+ * Returns the output of an interactive shell
+ *
+ * Returns when there's a match for $expect, which can take the form of a string literal or,
+ * if $mode == self::READ_REGEX, a regular expression.
+ *
+ * @see self::write()
+ * @param string $expect
+ * @param int $mode
+ * @return string
+ * @access public
+ */
+ function read($expect = '', $mode = self::READ_SIMPLE)
+ {
+ $this->curTimeout = $this->timeout;
+ $this->is_timeout = false;
+
+ if (!$this->isAuthenticated()) {
+ user_error('Operation disallowed prior to login()');
+ return false;
+ }
+
+ if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
+ user_error('Unable to initiate an interactive shell session');
+ return false;
+ }
+
+ $channel = $this->_get_interactive_channel();
+
+ if ($mode == self::READ_NEXT) {
+ return $this->_get_channel_packet($channel);
+ }
+
+ $match = $expect;
+ while (true) {
+ if ($mode == self::READ_REGEX) {
+ preg_match($expect, substr($this->interactiveBuffer, -1024), $matches);
+ $match = isset($matches[0]) ? $matches[0] : '';
+ }
+ $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false;
+ if ($pos !== false) {
+ return $this->_string_shift($this->interactiveBuffer, $pos + strlen($match));
+ }
+ $response = $this->_get_channel_packet($channel);
+ if (is_bool($response)) {
+ $this->in_request_pty_exec = false;
+ return $response ? $this->_string_shift($this->interactiveBuffer, strlen($this->interactiveBuffer)) : false;
+ }
+
+ $this->interactiveBuffer.= $response;
+ }
+ }
+
+ /**
+ * Inputs a command into an interactive shell.
+ *
+ * @see self::read()
+ * @param string $cmd
+ * @return bool
+ * @access public
+ */
+ function write($cmd)
+ {
+ if (!$this->isAuthenticated()) {
+ user_error('Operation disallowed prior to login()');
+ return false;
+ }
+
+ if (!($this->bitmap & self::MASK_SHELL) && !$this->_initShell()) {
+ user_error('Unable to initiate an interactive shell session');
+ return false;
+ }
+
+ return $this->_send_channel_packet($this->_get_interactive_channel(), $cmd);
+ }
+
+ /**
+ * Start a subsystem.
+ *
+ * Right now only one subsystem at a time is supported. To support multiple subsystem's stopSubsystem() could accept
+ * a string that contained the name of the subsystem, but at that point, only one subsystem of each type could be opened.
+ * To support multiple subsystem's of the same name maybe it'd be best if startSubsystem() generated a new channel id and
+ * returns that and then that that was passed into stopSubsystem() but that'll be saved for a future date and implemented
+ * if there's sufficient demand for such a feature.
+ *
+ * @see self::stopSubsystem()
+ * @param string $subsystem
+ * @return bool
+ * @access public
+ */
+ function startSubsystem($subsystem)
+ {
+ $this->window_size_server_to_client[self::CHANNEL_SUBSYSTEM] = $this->window_size;
+
+ $packet = pack(
+ 'CNa*N3',
+ NET_SSH2_MSG_CHANNEL_OPEN,
+ strlen('session'),
+ 'session',
+ self::CHANNEL_SUBSYSTEM,
+ $this->window_size,
+ 0x4000
+ );
+
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_OPEN;
+
+ $response = $this->_get_channel_packet(self::CHANNEL_SUBSYSTEM);
+ if ($response === false) {
+ return false;
+ }
+
+ $packet = pack(
+ 'CNNa*CNa*',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $this->server_channels[self::CHANNEL_SUBSYSTEM],
+ strlen('subsystem'),
+ 'subsystem',
+ 1,
+ strlen($subsystem),
+ $subsystem
+ );
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+ $response = $this->_get_channel_packet(self::CHANNEL_SUBSYSTEM);
+
+ if ($response === false) {
+ return false;
+ }
+
+ $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA;
+
+ $this->bitmap |= self::MASK_SHELL;
+ $this->in_subsystem = true;
+
+ return true;
+ }
+
+ /**
+ * Stops a subsystem.
+ *
+ * @see self::startSubsystem()
+ * @return bool
+ * @access public
+ */
+ function stopSubsystem()
+ {
+ $this->in_subsystem = false;
+ $this->_close_channel(self::CHANNEL_SUBSYSTEM);
+ return true;
+ }
+
+ /**
+ * Closes a channel
+ *
+ * If read() timed out you might want to just close the channel and have it auto-restart on the next read() call
+ *
+ * @access public
+ */
+ function reset()
+ {
+ $this->_close_channel($this->_get_interactive_channel());
+ }
+
+ /**
+ * Is timeout?
+ *
+ * Did exec() or read() return because they timed out or because they encountered the end?
+ *
+ * @access public
+ */
+ function isTimeout()
+ {
+ return $this->is_timeout;
+ }
+
+ /**
+ * Disconnect
+ *
+ * @access public
+ */
+ function disconnect()
+ {
+ $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+ if (isset($this->realtime_log_file) && is_resource($this->realtime_log_file)) {
+ fclose($this->realtime_log_file);
+ }
+ }
+
+ /**
+ * Destructor.
+ *
+ * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call
+ * disconnect().
+ *
+ * @access public
+ */
+ function __destruct()
+ {
+ $this->disconnect();
+ }
+
+ /**
+ * Is the connection still active?
+ *
+ * @return bool
+ * @access public
+ */
+ function isConnected()
+ {
+ return (bool) ($this->bitmap & self::MASK_CONNECTED);
+ }
+
+ /**
+ * Have you successfully been logged in?
+ *
+ * @return bool
+ * @access public
+ */
+ function isAuthenticated()
+ {
+ return (bool) ($this->bitmap & self::MASK_LOGIN);
+ }
+
+ /**
+ * Pings a server connection, or tries to reconnect if the connection has gone down
+ *
+ * Inspired by http://php.net/manual/en/mysqli.ping.php
+ *
+ * @return bool
+ * @access public
+ */
+ function ping()
+ {
+ if (!$this->isAuthenticated()) {
+ if (!empty($this->auth)) {
+ return $this->_reconnect();
+ }
+ return false;
+ }
+
+ $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE] = $this->window_size;
+ $packet_size = 0x4000;
+ $packet = pack(
+ 'CNa*N3',
+ NET_SSH2_MSG_CHANNEL_OPEN,
+ strlen('session'),
+ 'session',
+ self::CHANNEL_KEEP_ALIVE,
+ $this->window_size_server_to_client[self::CHANNEL_KEEP_ALIVE],
+ $packet_size
+ );
+
+ if (!@$this->_send_binary_packet($packet)) {
+ return $this->_reconnect();
+ }
+
+ $this->channel_status[self::CHANNEL_KEEP_ALIVE] = NET_SSH2_MSG_CHANNEL_OPEN;
+
+ $response = @$this->_get_channel_packet(self::CHANNEL_KEEP_ALIVE);
+ if ($response !== false) {
+ $this->_close_channel(self::CHANNEL_KEEP_ALIVE);
+ return true;
+ }
+
+ return $this->_reconnect();
+ }
+
+ /**
+ * In situ reconnect method
+ *
+ * @return boolean
+ * @access private
+ */
+ function _reconnect()
+ {
+ $this->_reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST);
+ $this->retry_connect = true;
+ if (!$this->_connect()) {
+ return false;
+ }
+ foreach ($this->auth as $auth) {
+ $result = call_user_func_array(array(&$this, 'login'), $auth);
+ }
+ return $result;
+ }
+
+ /**
+ * Resets a connection for re-use
+ *
+ * @param int $reason
+ * @access private
+ */
+ function _reset_connection($reason)
+ {
+ $this->_disconnect($reason);
+ $this->decrypt = $this->encrypt = false;
+ $this->decrypt_block_size = $this->encrypt_block_size = 8;
+ $this->hmac_check = $this->hmac_create = false;
+ $this->hmac_size = false;
+ $this->session_id = false;
+ $this->retry_connect = true;
+ $this->get_seq_no = $this->send_seq_no = 0;
+ }
+
+ /**
+ * Gets Binary Packets
+ *
+ * See '6. Binary Packet Protocol' of rfc4253 for more info.
+ *
+ * @see self::_send_binary_packet()
+ * @return string
+ * @access private
+ */
+ function _get_binary_packet($skip_channel_filter = false)
+ {
+ if (!is_resource($this->fsock) || feof($this->fsock)) {
+ $this->bitmap = 0;
+ user_error('Connection closed prematurely');
+ return false;
+ }
+
+ $start = microtime(true);
+ $raw = stream_get_contents($this->fsock, $this->decrypt_block_size);
+
+ if (!strlen($raw)) {
+ return '';
+ }
+
+ if ($this->decrypt !== false) {
+ $raw = $this->decrypt->decrypt($raw);
+ }
+ if ($raw === false) {
+ user_error('Unable to decrypt content');
+ return false;
+ }
+
+ if (strlen($raw) < 5) {
+ return false;
+ }
+ extract(unpack('Npacket_length/Cpadding_length', $this->_string_shift($raw, 5)));
+
+ $remaining_length = $packet_length + 4 - $this->decrypt_block_size;
+
+ // quoting <http://tools.ietf.org/html/rfc4253#section-6.1>,
+ // "implementations SHOULD check that the packet length is reasonable"
+ // PuTTY uses 0x9000 as the actual max packet size and so to shall we
+ if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) {
+ if (!$this->bad_key_size_fix && $this->_bad_algorithm_candidate($this->decrypt->name) && !($this->bitmap & SSH2::MASK_LOGIN)) {
+ $this->bad_key_size_fix = true;
+ $this->_reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ return false;
+ }
+ user_error('Invalid size');
+ return false;
+ }
+
+ $buffer = '';
+ while ($remaining_length > 0) {
+ $temp = stream_get_contents($this->fsock, $remaining_length);
+ if ($temp === false || feof($this->fsock)) {
+ $this->bitmap = 0;
+ user_error('Error reading from socket');
+ return false;
+ }
+ $buffer.= $temp;
+ $remaining_length-= strlen($temp);
+ }
+
+ $stop = microtime(true);
+ if (strlen($buffer)) {
+ $raw.= $this->decrypt !== false ? $this->decrypt->decrypt($buffer) : $buffer;
+ }
+
+ $payload = $this->_string_shift($raw, $packet_length - $padding_length - 1);
+ $padding = $this->_string_shift($raw, $padding_length); // should leave $raw empty
+
+ if ($this->hmac_check !== false) {
+ $hmac = stream_get_contents($this->fsock, $this->hmac_size);
+ if ($hmac === false || strlen($hmac) != $this->hmac_size) {
+ $this->bitmap = 0;
+ user_error('Error reading socket');
+ return false;
+ } elseif ($hmac != $this->hmac_check->hash(pack('NNCa*', $this->get_seq_no, $packet_length, $padding_length, $payload . $padding))) {
+ user_error('Invalid HMAC');
+ return false;
+ }
+ }
+
+ //if ($this->decompress) {
+ // $payload = gzinflate(substr($payload, 2));
+ //}
+
+ $this->get_seq_no++;
+
+ if (defined('NET_SSH2_LOGGING')) {
+ $current = microtime(true);
+ $message_number = isset($this->message_numbers[ord($payload[0])]) ? $this->message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')';
+ $message_number = '<- ' . $message_number .
+ ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
+ $this->_append_log($message_number, $payload);
+ $this->last_packet = $current;
+ }
+
+ return $this->_filter($payload, $skip_channel_filter);
+ }
+
+ /**
+ * Filter Binary Packets
+ *
+ * Because some binary packets need to be ignored...
+ *
+ * @see self::_get_binary_packet()
+ * @return string
+ * @access private
+ */
+ function _filter($payload, $skip_channel_filter)
+ {
+ switch (ord($payload[0])) {
+ case NET_SSH2_MSG_DISCONNECT:
+ $this->_string_shift($payload, 1);
+ if (strlen($payload) < 8) {
+ return false;
+ }
+ extract(unpack('Nreason_code/Nlength', $this->_string_shift($payload, 8)));
+ $this->errors[] = 'SSH_MSG_DISCONNECT: ' . $this->disconnect_reasons[$reason_code] . "\r\n" . $this->_string_shift($payload, $length);
+ $this->bitmap = 0;
+ return false;
+ case NET_SSH2_MSG_IGNORE:
+ $payload = $this->_get_binary_packet($skip_channel_filter);
+ break;
+ case NET_SSH2_MSG_DEBUG:
+ $this->_string_shift($payload, 2);
+ if (strlen($payload) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($payload, 4)));
+ $this->errors[] = 'SSH_MSG_DEBUG: ' . $this->_string_shift($payload, $length);
+ $payload = $this->_get_binary_packet($skip_channel_filter);
+ break;
+ case NET_SSH2_MSG_UNIMPLEMENTED:
+ return false;
+ case NET_SSH2_MSG_KEXINIT:
+ if ($this->session_id !== false) {
+ $this->send_kex_first = false;
+ if (!$this->_key_exchange($payload)) {
+ $this->bitmap = 0;
+ return false;
+ }
+ $payload = $this->_get_binary_packet($skip_channel_filter);
+ }
+ }
+
+ // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in
+ if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) {
+ $this->_string_shift($payload, 1);
+ if (strlen($payload) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($payload, 4)));
+ $this->banner_message = $this->_string_shift($payload, $length);
+ $payload = $this->_get_binary_packet();
+ }
+
+ // only called when we've already logged in
+ if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) {
+ switch (ord($payload[0])) {
+ case NET_SSH2_MSG_CHANNEL_DATA:
+ case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
+ case NET_SSH2_MSG_CHANNEL_REQUEST:
+ case NET_SSH2_MSG_CHANNEL_CLOSE:
+ case NET_SSH2_MSG_CHANNEL_EOF:
+ if (!$skip_channel_filter && !empty($this->server_channels)) {
+ $this->binary_packet_buffer = $payload;
+ $this->_get_channel_packet(true);
+ $payload = $this->_get_binary_packet();
+ }
+ break;
+ case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4
+ if (strlen($payload) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($payload, 4)));
+ $this->errors[] = 'SSH_MSG_GLOBAL_REQUEST: ' . $this->_string_shift($payload, $length);
+
+ if (!$this->_send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE))) {
+ return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+ }
+
+ $payload = $this->_get_binary_packet($skip_channel_filter);
+ break;
+ case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1
+ $this->_string_shift($payload, 1);
+ if (strlen($payload) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($payload, 4)));
+ $data = $this->_string_shift($payload, $length);
+ if (strlen($payload) < 4) {
+ return false;
+ }
+ extract(unpack('Nserver_channel', $this->_string_shift($payload, 4)));
+ switch ($data) {
+ case 'auth-agent':
+ case 'auth-agent@openssh.com':
+ if (isset($this->agent)) {
+ $new_channel = self::CHANNEL_AGENT_FORWARD;
+
+ if (strlen($payload) < 8) {
+ return false;
+ }
+ extract(unpack('Nremote_window_size', $this->_string_shift($payload, 4)));
+ extract(unpack('Nremote_maximum_packet_size', $this->_string_shift($payload, 4)));
+
+ $this->packet_size_client_to_server[$new_channel] = $remote_window_size;
+ $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size;
+ $this->window_size_client_to_server[$new_channel] = $this->window_size;
+
+ $packet_size = 0x4000;
+
+ $packet = pack(
+ 'CN4',
+ NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION,
+ $server_channel,
+ $new_channel,
+ $packet_size,
+ $packet_size
+ );
+
+ $this->server_channels[$new_channel] = $server_channel;
+ $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION;
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+ }
+ break;
+ default:
+ $packet = pack(
+ 'CN3a*Na*',
+ NET_SSH2_MSG_REQUEST_FAILURE,
+ $server_channel,
+ NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED,
+ 0,
+ '',
+ 0,
+ ''
+ );
+
+ if (!$this->_send_binary_packet($packet)) {
+ return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+ }
+ }
+ $payload = $this->_get_binary_packet($skip_channel_filter);
+ break;
+ case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
+ $this->_string_shift($payload, 1);
+ if (strlen($payload) < 8) {
+ return false;
+ }
+ extract(unpack('Nchannel', $this->_string_shift($payload, 4)));
+ extract(unpack('Nwindow_size', $this->_string_shift($payload, 4)));
+ $this->window_size_client_to_server[$channel]+= $window_size;
+
+ $payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->_get_binary_packet($skip_channel_filter);
+ }
+ }
+
+ return $payload;
+ }
+
+ /**
+ * Enable Quiet Mode
+ *
+ * Suppress stderr from output
+ *
+ * @access public
+ */
+ function enableQuietMode()
+ {
+ $this->quiet_mode = true;
+ }
+
+ /**
+ * Disable Quiet Mode
+ *
+ * Show stderr in output
+ *
+ * @access public
+ */
+ function disableQuietMode()
+ {
+ $this->quiet_mode = false;
+ }
+
+ /**
+ * Returns whether Quiet Mode is enabled or not
+ *
+ * @see self::enableQuietMode()
+ * @see self::disableQuietMode()
+ * @access public
+ * @return bool
+ */
+ function isQuietModeEnabled()
+ {
+ return $this->quiet_mode;
+ }
+
+ /**
+ * Enable request-pty when using exec()
+ *
+ * @access public
+ */
+ function enablePTY()
+ {
+ $this->request_pty = true;
+ }
+
+ /**
+ * Disable request-pty when using exec()
+ *
+ * @access public
+ */
+ function disablePTY()
+ {
+ if ($this->in_request_pty_exec) {
+ $this->_close_channel(self::CHANNEL_EXEC);
+ $this->in_request_pty_exec = false;
+ }
+ $this->request_pty = false;
+ }
+
+ /**
+ * Returns whether request-pty is enabled or not
+ *
+ * @see self::enablePTY()
+ * @see self::disablePTY()
+ * @access public
+ * @return bool
+ */
+ function isPTYEnabled()
+ {
+ return $this->request_pty;
+ }
+
+ /**
+ * Gets channel data
+ *
+ * Returns the data as a string if it's available and false if not.
+ *
+ * @param $client_channel
+ * @return mixed
+ * @access private
+ */
+ function _get_channel_packet($client_channel, $skip_extended = false)
+ {
+ if (!empty($this->channel_buffers[$client_channel])) {
+ return array_shift($this->channel_buffers[$client_channel]);
+ }
+
+ while (true) {
+ if ($this->binary_packet_buffer !== false) {
+ $response = $this->binary_packet_buffer;
+ $this->binary_packet_buffer = false;
+ } else {
+ $read = array($this->fsock);
+ $write = $except = null;
+
+ if (!$this->curTimeout) {
+ @stream_select($read, $write, $except, null);
+ } else {
+ if ($this->curTimeout < 0) {
+ $this->is_timeout = true;
+ return true;
+ }
+
+ $read = array($this->fsock);
+ $write = $except = null;
+
+ $start = microtime(true);
+ $sec = floor($this->curTimeout);
+ $usec = 1000000 * ($this->curTimeout - $sec);
+ // on windows this returns a "Warning: Invalid CRT parameters detected" error
+ if (!@stream_select($read, $write, $except, $sec, $usec) && !count($read)) {
+ $this->is_timeout = true;
+ if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) {
+ $this->_close_channel($client_channel);
+ }
+ return true;
+ }
+ $elapsed = microtime(true) - $start;
+ $this->curTimeout-= $elapsed;
+ }
+
+ $response = $this->_get_binary_packet(true);
+ if ($response === false) {
+ $this->bitmap = 0;
+ user_error('Connection closed by server');
+ return false;
+ }
+ }
+
+ if ($client_channel == -1 && $response === true) {
+ return true;
+ }
+ if (!strlen($response)) {
+ return false;
+ }
+ extract(unpack('Ctype', $this->_string_shift($response, 1)));
+
+ if (strlen($response) < 4) {
+ return false;
+ }
+ if ($type == NET_SSH2_MSG_CHANNEL_OPEN) {
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ } else {
+ extract(unpack('Nchannel', $this->_string_shift($response, 4)));
+ }
+
+ // will not be setup yet on incoming channel open request
+ if (isset($channel) && isset($this->channel_status[$channel]) && isset($this->window_size_server_to_client[$channel])) {
+ $this->window_size_server_to_client[$channel]-= strlen($response);
+
+ // resize the window, if appropriate
+ if ($this->window_size_server_to_client[$channel] < 0) {
+ // PuTTY does something more analogous to the following:
+ //if ($this->window_size_server_to_client[$channel] < 0x3FFFFFFF) {
+ $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_resize);
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+ $this->window_size_server_to_client[$channel]+= $this->window_resize;
+ }
+
+ switch ($type) {
+ case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA:
+ /*
+ if ($client_channel == self::CHANNEL_EXEC) {
+ $this->_send_channel_packet($client_channel, chr(0));
+ }
+ */
+ // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR
+ if (strlen($response) < 8) {
+ return false;
+ }
+ extract(unpack('Ndata_type_code/Nlength', $this->_string_shift($response, 8)));
+ $data = $this->_string_shift($response, $length);
+ $this->stdErrorLog.= $data;
+ if ($skip_extended || $this->quiet_mode) {
+ continue 2;
+ }
+ if ($client_channel == $channel && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA) {
+ return $data;
+ }
+ if (!isset($this->channel_buffers[$channel])) {
+ $this->channel_buffers[$channel] = array();
+ }
+ $this->channel_buffers[$channel][] = $data;
+
+ continue 2;
+ case NET_SSH2_MSG_CHANNEL_REQUEST:
+ if ($this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_CLOSE) {
+ continue 2;
+ }
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $value = $this->_string_shift($response, $length);
+ switch ($value) {
+ case 'exit-signal':
+ $this->_string_shift($response, 1);
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $this->errors[] = 'SSH_MSG_CHANNEL_REQUEST (exit-signal): ' . $this->_string_shift($response, $length);
+ $this->_string_shift($response, 1);
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ if ($length) {
+ $this->errors[count($this->errors)].= "\r\n" . $this->_string_shift($response, $length);
+ }
+
+ $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel]));
+ $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel]));
+
+ $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF;
+
+ continue 3;
+ case 'exit-status':
+ if (strlen($response) < 5) {
+ return false;
+ }
+ extract(unpack('Cfalse/Nexit_status', $this->_string_shift($response, 5)));
+ $this->exit_status = $exit_status;
+
+ // "The client MAY ignore these messages."
+ // -- http://tools.ietf.org/html/rfc4254#section-6.10
+
+ continue 3;
+ default:
+ // "Some systems may not implement signals, in which case they SHOULD ignore this message."
+ // -- http://tools.ietf.org/html/rfc4254#section-6.9
+ continue 3;
+ }
+ }
+
+ switch ($this->channel_status[$channel]) {
+ case NET_SSH2_MSG_CHANNEL_OPEN:
+ switch ($type) {
+ case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nserver_channel', $this->_string_shift($response, 4)));
+ $this->server_channels[$channel] = $server_channel;
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nwindow_size', $this->_string_shift($response, 4)));
+ if ($window_size < 0) {
+ $window_size&= 0x7FFFFFFF;
+ $window_size+= 0x80000000;
+ }
+ $this->window_size_client_to_server[$channel] = $window_size;
+ if (strlen($response) < 4) {
+ return false;
+ }
+ $temp = unpack('Npacket_size_client_to_server', $this->_string_shift($response, 4));
+ $this->packet_size_client_to_server[$channel] = $temp['packet_size_client_to_server'];
+ $result = $client_channel == $channel ? true : $this->_get_channel_packet($client_channel, $skip_extended);
+ $this->_on_channel_open();
+ return $result;
+ //case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE:
+ default:
+ user_error('Unable to open channel');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+ }
+ break;
+ case NET_SSH2_MSG_CHANNEL_REQUEST:
+ switch ($type) {
+ case NET_SSH2_MSG_CHANNEL_SUCCESS:
+ return true;
+ case NET_SSH2_MSG_CHANNEL_FAILURE:
+ return false;
+ default:
+ user_error('Unable to fulfill channel request');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+ }
+ case NET_SSH2_MSG_CHANNEL_CLOSE:
+ return $type == NET_SSH2_MSG_CHANNEL_CLOSE ? true : $this->_get_channel_packet($client_channel, $skip_extended);
+ }
+ }
+
+ // ie. $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA
+
+ switch ($type) {
+ case NET_SSH2_MSG_CHANNEL_DATA:
+ /*
+ if ($channel == self::CHANNEL_EXEC) {
+ // SCP requires null packets, such as this, be sent. further, in the case of the ssh.com SSH server
+ // this actually seems to make things twice as fast. more to the point, the message right after
+ // SSH_MSG_CHANNEL_DATA (usually SSH_MSG_IGNORE) won't block for as long as it would have otherwise.
+ // in OpenSSH it slows things down but only by a couple thousandths of a second.
+ $this->_send_channel_packet($channel, chr(0));
+ }
+ */
+ if (strlen($response) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($response, 4)));
+ $data = $this->_string_shift($response, $length);
+
+ if ($channel == self::CHANNEL_AGENT_FORWARD) {
+ $agent_response = $this->agent->_forward_data($data);
+ if (!is_bool($agent_response)) {
+ $this->_send_channel_packet($channel, $agent_response);
+ }
+ break;
+ }
+
+ if ($client_channel == $channel) {
+ return $data;
+ }
+ if (!isset($this->channel_buffers[$channel])) {
+ $this->channel_buffers[$channel] = array();
+ }
+ $this->channel_buffers[$channel][] = $data;
+ break;
+ case NET_SSH2_MSG_CHANNEL_CLOSE:
+ $this->curTimeout = 0;
+
+ if ($this->bitmap & self::MASK_SHELL) {
+ $this->bitmap&= ~self::MASK_SHELL;
+ }
+ if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) {
+ $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel]));
+ }
+
+ $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE;
+ if ($client_channel == $channel) {
+ return true;
+ }
+ case NET_SSH2_MSG_CHANNEL_EOF:
+ break;
+ default:
+ user_error('Error reading channel data');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_BY_APPLICATION);
+ }
+ }
+ }
+
+ /**
+ * Sends Binary Packets
+ *
+ * See '6. Binary Packet Protocol' of rfc4253 for more info.
+ *
+ * @param string $data
+ * @param string $logged
+ * @see self::_get_binary_packet()
+ * @return bool
+ * @access private
+ */
+ function _send_binary_packet($data, $logged = null)
+ {
+ if (!is_resource($this->fsock) || feof($this->fsock)) {
+ $this->bitmap = 0;
+ user_error('Connection closed prematurely');
+ return false;
+ }
+
+ //if ($this->compress) {
+ // // the -4 removes the checksum:
+ // // http://php.net/function.gzcompress#57710
+ // $data = substr(gzcompress($data), 0, -4);
+ //}
+
+ // 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9
+ $packet_length = strlen($data) + 9;
+ // round up to the nearest $this->encrypt_block_size
+ $packet_length+= (($this->encrypt_block_size - 1) * $packet_length) % $this->encrypt_block_size;
+ // subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length
+ $padding_length = $packet_length - strlen($data) - 5;
+ $padding = Random::string($padding_length);
+
+ // we subtract 4 from packet_length because the packet_length field isn't supposed to include itself
+ $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding);
+
+ $hmac = $this->hmac_create !== false ? $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)) : '';
+ $this->send_seq_no++;
+
+ if ($this->encrypt !== false) {
+ $packet = $this->encrypt->encrypt($packet);
+ }
+
+ $packet.= $hmac;
+
+ $start = microtime(true);
+ $result = strlen($packet) == fputs($this->fsock, $packet);
+ $stop = microtime(true);
+
+ if (defined('NET_SSH2_LOGGING')) {
+ $current = microtime(true);
+ $message_number = isset($this->message_numbers[ord($data[0])]) ? $this->message_numbers[ord($data[0])] : 'UNKNOWN (' . ord($data[0]) . ')';
+ $message_number = '-> ' . $message_number .
+ ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)';
+ $this->_append_log($message_number, isset($logged) ? $logged : $data);
+ $this->last_packet = $current;
+ }
+
+ return $result;
+ }
+
+ /**
+ * Logs data packets
+ *
+ * Makes sure that only the last 1MB worth of packets will be logged
+ *
+ * @param string $data
+ * @access private
+ */
+ function _append_log($message_number, $message)
+ {
+ // remove the byte identifying the message type from all but the first two messages (ie. the identification strings)
+ if (strlen($message_number) > 2) {
+ $this->_string_shift($message);
+ }
+
+ switch (NET_SSH2_LOGGING) {
+ // useful for benchmarks
+ case self::LOG_SIMPLE:
+ $this->message_number_log[] = $message_number;
+ break;
+ // the most useful log for SSH2
+ case self::LOG_COMPLEX:
+ $this->message_number_log[] = $message_number;
+ $this->log_size+= strlen($message);
+ $this->message_log[] = $message;
+ while ($this->log_size > self::LOG_MAX_SIZE) {
+ $this->log_size-= strlen(array_shift($this->message_log));
+ array_shift($this->message_number_log);
+ }
+ break;
+ // dump the output out realtime; packets may be interspersed with non packets,
+ // passwords won't be filtered out and select other packets may not be correctly
+ // identified
+ case self::LOG_REALTIME:
+ switch (PHP_SAPI) {
+ case 'cli':
+ $start = $stop = "\r\n";
+ break;
+ default:
+ $start = '<pre>';
+ $stop = '</pre>';
+ }
+ echo $start . $this->_format_log(array($message), array($message_number)) . $stop;
+ @flush();
+ @ob_flush();
+ break;
+ // basically the same thing as self::LOG_REALTIME with the caveat that self::LOG_REALTIME_FILE
+ // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE.
+ // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily
+ // at the beginning of the file
+ case self::LOG_REALTIME_FILE:
+ if (!isset($this->realtime_log_file)) {
+ // PHP doesn't seem to like using constants in fopen()
+ $filename = self::LOG_REALTIME_FILENAME;
+ $fp = fopen($filename, 'w');
+ $this->realtime_log_file = $fp;
+ }
+ if (!is_resource($this->realtime_log_file)) {
+ break;
+ }
+ $entry = $this->_format_log(array($message), array($message_number));
+ if ($this->realtime_log_wrap) {
+ $temp = "<<< START >>>\r\n";
+ $entry.= $temp;
+ fseek($this->realtime_log_file, ftell($this->realtime_log_file) - strlen($temp));
+ }
+ $this->realtime_log_size+= strlen($entry);
+ if ($this->realtime_log_size > self::LOG_MAX_SIZE) {
+ fseek($this->realtime_log_file, 0);
+ $this->realtime_log_size = strlen($entry);
+ $this->realtime_log_wrap = true;
+ }
+ fputs($this->realtime_log_file, $entry);
+ }
+ }
+
+ /**
+ * Sends channel data
+ *
+ * Spans multiple SSH_MSG_CHANNEL_DATAs if appropriate
+ *
+ * @param int $client_channel
+ * @param string $data
+ * @return bool
+ * @access private
+ */
+ function _send_channel_packet($client_channel, $data)
+ {
+ while (strlen($data)) {
+ if (!$this->window_size_client_to_server[$client_channel]) {
+ $this->bitmap^= self::MASK_WINDOW_ADJUST;
+ // using an invalid channel will let the buffers be built up for the valid channels
+ $this->_get_channel_packet(-1);
+ $this->bitmap^= self::MASK_WINDOW_ADJUST;
+ }
+
+ /* The maximum amount of data allowed is determined by the maximum
+ packet size for the channel, and the current window size, whichever
+ is smaller.
+ -- http://tools.ietf.org/html/rfc4254#section-5.2 */
+ $max_size = min(
+ $this->packet_size_client_to_server[$client_channel],
+ $this->window_size_client_to_server[$client_channel]
+ );
+
+ $temp = $this->_string_shift($data, $max_size);
+ $packet = pack(
+ 'CN2a*',
+ NET_SSH2_MSG_CHANNEL_DATA,
+ $this->server_channels[$client_channel],
+ strlen($temp),
+ $temp
+ );
+ $this->window_size_client_to_server[$client_channel]-= strlen($temp);
+ if (!$this->_send_binary_packet($packet)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Closes and flushes a channel
+ *
+ * \phpseclib\Net\SSH2 doesn't properly close most channels. For exec() channels are normally closed by the server
+ * and for SFTP channels are presumably closed when the client disconnects. This functions is intended
+ * for SCP more than anything.
+ *
+ * @param int $client_channel
+ * @param bool $want_reply
+ * @return bool
+ * @access private
+ */
+ function _close_channel($client_channel, $want_reply = false)
+ {
+ // see http://tools.ietf.org/html/rfc4254#section-5.3
+
+ $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel]));
+
+ if (!$want_reply) {
+ $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel]));
+ }
+
+ $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE;
+
+ $this->curTimeout = 0;
+
+ while (!is_bool($this->_get_channel_packet($client_channel))) {
+ }
+
+ if ($want_reply) {
+ $this->_send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel]));
+ }
+
+ if ($this->bitmap & self::MASK_SHELL) {
+ $this->bitmap&= ~self::MASK_SHELL;
+ }
+ }
+
+ /**
+ * Disconnect
+ *
+ * @param int $reason
+ * @return bool
+ * @access private
+ */
+ function _disconnect($reason)
+ {
+ if ($this->bitmap & self::MASK_CONNECTED) {
+ $data = pack('CNNa*Na*', NET_SSH2_MSG_DISCONNECT, $reason, 0, '', 0, '');
+ $this->_send_binary_packet($data);
+ }
+
+ $this->bitmap = 0;
+ if (is_resource($this->fsock) && get_resource_type($this->fsock) == 'stream') {
+ fclose($this->fsock);
+ }
+
+ return false;
+ }
+
+ /**
+ * String Shift
+ *
+ * Inspired by array_shift
+ *
+ * @param string $string
+ * @param int $index
+ * @return string
+ * @access private
+ */
+ function _string_shift(&$string, $index = 1)
+ {
+ $substr = substr($string, 0, $index);
+ $string = substr($string, $index);
+ return $substr;
+ }
+
+ /**
+ * Define Array
+ *
+ * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of
+ * named constants from it, using the value as the name of the constant and the index as the value of the constant.
+ * If any of the constants that would be defined already exists, none of the constants will be defined.
+ *
+ * @param array $array
+ * @access private
+ */
+ function _define_array()
+ {
+ $args = func_get_args();
+ foreach ($args as $arg) {
+ foreach ($arg as $key => $value) {
+ if (!defined($value)) {
+ define($value, $key);
+ } else {
+ break 2;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns a log of the packets that have been sent and received.
+ *
+ * Returns a string if NET_SSH2_LOGGING == self::LOG_COMPLEX, an array if NET_SSH2_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING')
+ *
+ * @access public
+ * @return array|false|string
+ */
+ function getLog()
+ {
+ if (!defined('NET_SSH2_LOGGING')) {
+ return false;
+ }
+
+ switch (NET_SSH2_LOGGING) {
+ case self::LOG_SIMPLE:
+ return $this->message_number_log;
+ case self::LOG_COMPLEX:
+ $log = $this->_format_log($this->message_log, $this->message_number_log);
+ return PHP_SAPI == 'cli' ? $log : '<pre>' . $log . '</pre>';
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * Formats a log for printing
+ *
+ * @param array $message_log
+ * @param array $message_number_log
+ * @access private
+ * @return string
+ */
+ function _format_log($message_log, $message_number_log)
+ {
+ $output = '';
+ for ($i = 0; $i < count($message_log); $i++) {
+ $output.= $message_number_log[$i] . "\r\n";
+ $current_log = $message_log[$i];
+ $j = 0;
+ do {
+ if (strlen($current_log)) {
+ $output.= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 ';
+ }
+ $fragment = $this->_string_shift($current_log, $this->log_short_width);
+ $hex = substr(preg_replace_callback('#.#s', array($this, '_format_log_helper'), $fragment), strlen($this->log_boundary));
+ // replace non ASCII printable characters with dots
+ // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters
+ // also replace < with a . since < messes up the output on web browsers
+ $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment);
+ $output.= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n";
+ $j++;
+ } while (strlen($current_log));
+ $output.= "\r\n";
+ }
+
+ return $output;
+ }
+
+ /**
+ * Helper function for _format_log
+ *
+ * For use with preg_replace_callback()
+ *
+ * @param array $matches
+ * @access private
+ * @return string
+ */
+ function _format_log_helper($matches)
+ {
+ return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT);
+ }
+
+ /**
+ * Helper function for agent->_on_channel_open()
+ *
+ * Used when channels are created to inform agent
+ * of said channel opening. Must be called after
+ * channel open confirmation received
+ *
+ * @access private
+ */
+ function _on_channel_open()
+ {
+ if (isset($this->agent)) {
+ $this->agent->_on_channel_open($this);
+ }
+ }
+
+ /**
+ * Returns the first value of the intersection of two arrays or false if
+ * the intersection is empty. The order is defined by the first parameter.
+ *
+ * @param array $array1
+ * @param array $array2
+ * @return mixed False if intersection is empty, else intersected value.
+ * @access private
+ */
+ function _array_intersect_first($array1, $array2)
+ {
+ foreach ($array1 as $value) {
+ if (in_array($value, $array2)) {
+ return $value;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns all errors
+ *
+ * @return string[]
+ * @access public
+ */
+ function getErrors()
+ {
+ return $this->errors;
+ }
+
+ /**
+ * Returns the last error
+ *
+ * @return string
+ * @access public
+ */
+ function getLastError()
+ {
+ $count = count($this->errors);
+
+ if ($count > 0) {
+ return $this->errors[$count - 1];
+ }
+ }
+
+ /**
+ * Return the server identification.
+ *
+ * @return string
+ * @access public
+ */
+ function getServerIdentification()
+ {
+ $this->_connect();
+
+ return $this->server_identifier;
+ }
+
+ /**
+ * Return a list of the key exchange algorithms the server supports.
+ *
+ * @return array
+ * @access public
+ */
+ function getKexAlgorithms()
+ {
+ $this->_connect();
+
+ return $this->kex_algorithms;
+ }
+
+ /**
+ * Return a list of the host key (public key) algorithms the server supports.
+ *
+ * @return array
+ * @access public
+ */
+ function getServerHostKeyAlgorithms()
+ {
+ $this->_connect();
+
+ return $this->server_host_key_algorithms;
+ }
+
+ /**
+ * Return a list of the (symmetric key) encryption algorithms the server supports, when receiving stuff from the client.
+ *
+ * @return array
+ * @access public
+ */
+ function getEncryptionAlgorithmsClient2Server()
+ {
+ $this->_connect();
+
+ return $this->encryption_algorithms_client_to_server;
+ }
+
+ /**
+ * Return a list of the (symmetric key) encryption algorithms the server supports, when sending stuff to the client.
+ *
+ * @return array
+ * @access public
+ */
+ function getEncryptionAlgorithmsServer2Client()
+ {
+ $this->_connect();
+
+ return $this->encryption_algorithms_server_to_client;
+ }
+
+ /**
+ * Return a list of the MAC algorithms the server supports, when receiving stuff from the client.
+ *
+ * @return array
+ * @access public
+ */
+ function getMACAlgorithmsClient2Server()
+ {
+ $this->_connect();
+
+ return $this->mac_algorithms_client_to_server;
+ }
+
+ /**
+ * Return a list of the MAC algorithms the server supports, when sending stuff to the client.
+ *
+ * @return array
+ * @access public
+ */
+ function getMACAlgorithmsServer2Client()
+ {
+ $this->_connect();
+
+ return $this->mac_algorithms_server_to_client;
+ }
+
+ /**
+ * Return a list of the compression algorithms the server supports, when receiving stuff from the client.
+ *
+ * @return array
+ * @access public
+ */
+ function getCompressionAlgorithmsClient2Server()
+ {
+ $this->_connect();
+
+ return $this->compression_algorithms_client_to_server;
+ }
+
+ /**
+ * Return a list of the compression algorithms the server supports, when sending stuff to the client.
+ *
+ * @return array
+ * @access public
+ */
+ function getCompressionAlgorithmsServer2Client()
+ {
+ $this->_connect();
+
+ return $this->compression_algorithms_server_to_client;
+ }
+
+ /**
+ * Return a list of the languages the server supports, when sending stuff to the client.
+ *
+ * @return array
+ * @access public
+ */
+ function getLanguagesServer2Client()
+ {
+ $this->_connect();
+
+ return $this->languages_server_to_client;
+ }
+
+ /**
+ * Return a list of the languages the server supports, when receiving stuff from the client.
+ *
+ * @return array
+ * @access public
+ */
+ function getLanguagesClient2Server()
+ {
+ $this->_connect();
+
+ return $this->languages_client_to_server;
+ }
+
+ /**
+ * Returns a list of algorithms the server supports
+ *
+ * @return array
+ * @access public
+ */
+ function getServerAlgorithms()
+ {
+ $this->_connect();
+
+ return array(
+ 'kex' => $this->kex_algorithms,
+ 'hostkey' => $this->server_host_key_algorithms,
+ 'client_to_server' => array(
+ 'crypt' => $this->encryption_algorithms_client_to_server,
+ 'mac' => $this->mac_algorithms_client_to_server,
+ 'comp' => $this->compression_algorithms_client_to_server,
+ 'lang' => $this->languages_client_to_server
+ ),
+ 'server_to_client' => array(
+ 'crypt' => $this->encryption_algorithms_server_to_client,
+ 'mac' => $this->mac_algorithms_server_to_client,
+ 'comp' => $this->compression_algorithms_server_to_client,
+ 'lang' => $this->languages_server_to_client
+ )
+ );
+ }
+
+ /**
+ * Returns a list of KEX algorithms that phpseclib supports
+ *
+ * @return array
+ * @access public
+ */
+ function getSupportedKEXAlgorithms()
+ {
+ $kex_algorithms = array(
+ // Elliptic Curve Diffie-Hellman Key Agreement (ECDH) using
+ // Curve25519. See doc/curve25519-sha256@libssh.org.txt in the
+ // libssh repository for more information.
+ 'curve25519-sha256@libssh.org',
+
+ 'diffie-hellman-group-exchange-sha256',// RFC 4419
+ 'diffie-hellman-group-exchange-sha1', // RFC 4419
+
+ // Diffie-Hellman Key Agreement (DH) using integer modulo prime
+ // groups.
+ 'diffie-hellman-group14-sha1', // REQUIRED
+ 'diffie-hellman-group1-sha1', // REQUIRED
+ );
+
+ if (!function_exists('sodium_crypto_box_publickey_from_secretkey')) {
+ $kex_algorithms = array_diff(
+ $kex_algorithms,
+ array('curve25519-sha256@libssh.org')
+ );
+ }
+
+ return $kex_algorithms;
+ }
+
+ /**
+ * Returns a list of host key algorithms that phpseclib supports
+ *
+ * @return array
+ * @access public
+ */
+ function getSupportedHostKeyAlgorithms()
+ {
+ return array(
+ 'rsa-sha2-256', // RFC 8332
+ 'rsa-sha2-512', // RFC 8332
+ 'ssh-rsa', // RECOMMENDED sign Raw RSA Key
+ 'ssh-dss' // REQUIRED sign Raw DSS Key
+ );
+ }
+
+ /**
+ * Returns a list of symmetric key algorithms that phpseclib supports
+ *
+ * @return array
+ * @access public
+ */
+ function getSupportedEncryptionAlgorithms()
+ {
+ $algos = array(
+ // from <http://tools.ietf.org/html/rfc4345#section-4>:
+ 'arcfour256',
+ 'arcfour128',
+
+ //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key
+
+ // CTR modes from <http://tools.ietf.org/html/rfc4344#section-4>:
+ 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key
+ 'aes192-ctr', // RECOMMENDED AES with 192-bit key
+ 'aes256-ctr', // RECOMMENDED AES with 256-bit key
+
+ 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key
+ 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key
+ 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key
+
+ 'aes128-cbc', // RECOMMENDED AES with a 128-bit key
+ 'aes192-cbc', // OPTIONAL AES with a 192-bit key
+ 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key
+
+ 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key
+ 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key
+ 'twofish256-cbc',
+ 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc"
+ // (this is being retained for historical reasons)
+
+ 'blowfish-ctr', // OPTIONAL Blowfish in SDCTR mode
+
+ 'blowfish-cbc', // OPTIONAL Blowfish in CBC mode
+
+ '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode
+
+ '3des-cbc', // REQUIRED three-key 3DES in CBC mode
+
+ //'none' // OPTIONAL no encryption; NOT RECOMMENDED
+ );
+
+ $engines = array(
+ Base::ENGINE_OPENSSL,
+ Base::ENGINE_MCRYPT,
+ Base::ENGINE_INTERNAL
+ );
+
+ $ciphers = array();
+ foreach ($engines as $engine) {
+ foreach ($algos as $algo) {
+ $obj = $this->_encryption_algorithm_to_crypt_instance($algo);
+ if ($obj instanceof Rijndael) {
+ $obj->setKeyLength(preg_replace('#[^\d]#', '', $algo));
+ }
+ switch ($algo) {
+ case 'arcfour128':
+ case 'arcfour256':
+ if ($engine != Base::ENGINE_INTERNAL) {
+ continue 2;
+ }
+ }
+ if ($obj->isValidEngine($engine)) {
+ $algos = array_diff($algos, array($algo));
+ $ciphers[] = $algo;
+ }
+ }
+ }
+
+ return $ciphers;
+ }
+
+ /**
+ * Returns a list of MAC algorithms that phpseclib supports
+ *
+ * @return array
+ * @access public
+ */
+ function getSupportedMACAlgorithms()
+ {
+ return array(
+ // from <http://www.ietf.org/rfc/rfc6668.txt>:
+ 'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32)
+
+ 'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20)
+ 'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20)
+ 'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16)
+ 'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16)
+ //'none' // OPTIONAL no MAC; NOT RECOMMENDED
+ );
+ }
+
+ /**
+ * Returns a list of compression algorithms that phpseclib supports
+ *
+ * @return array
+ * @access public
+ */
+ function getSupportedCompressionAlgorithms()
+ {
+ return array(
+ 'none' // REQUIRED no compression
+ //'zlib' // OPTIONAL ZLIB (LZ77) compression
+ );
+ }
+
+ /**
+ * Return list of negotiated algorithms
+ *
+ * Uses the same format as https://www.php.net/ssh2-methods-negotiated
+ *
+ * @return array
+ * @access public
+ */
+ function getAlgorithmsNegotiated()
+ {
+ $this->_connect();
+
+ return array(
+ 'kex' => $this->kex_algorithm,
+ 'hostkey' => $this->signature_format,
+ 'client_to_server' => array(
+ 'crypt' => $this->encrypt->name,
+ 'mac' => $this->hmac_create->name,
+ 'comp' => 'none',
+ ),
+ 'server_to_client' => array(
+ 'crypt' => $this->decrypt->name,
+ 'mac' => $this->hmac_check->name,
+ 'comp' => 'none',
+ )
+ );
+ }
+
+ /**
+ * Accepts an associative array with up to four parameters as described at
+ * <https://www.php.net/manual/en/function.ssh2-connect.php>
+ *
+ * @param array $methods
+ * @access public
+ */
+ function setPreferredAlgorithms($methods)
+ {
+ $preferred = $methods;
+
+ if (isset($preferred['kex'])) {
+ $preferred['kex'] = array_intersect(
+ $preferred['kex'],
+ $this->getSupportedKEXAlgorithms()
+ );
+ }
+
+ if (isset($preferred['hostkey'])) {
+ $preferred['hostkey'] = array_intersect(
+ $preferred['hostkey'],
+ $this->getSupportedHostKeyAlgorithms()
+ );
+ }
+
+ $keys = array('client_to_server', 'server_to_client');
+ foreach ($keys as $key) {
+ if (isset($preferred[$key])) {
+ $a = &$preferred[$key];
+ if (isset($a['crypt'])) {
+ $a['crypt'] = array_intersect(
+ $a['crypt'],
+ $this->getSupportedEncryptionAlgorithms()
+ );
+ }
+ if (isset($a['comp'])) {
+ $a['comp'] = array_intersect(
+ $a['comp'],
+ $this->getSupportedCompressionAlgorithms()
+ );
+ }
+ if (isset($a['mac'])) {
+ $a['mac'] = array_intersect(
+ $a['mac'],
+ $this->getSupportedMACAlgorithms()
+ );
+ }
+ }
+ }
+
+ $keys = array(
+ 'kex',
+ 'hostkey',
+ 'client_to_server/crypt',
+ 'client_to_server/comp',
+ 'client_to_server/mac',
+ 'server_to_client/crypt',
+ 'server_to_client/comp',
+ 'server_to_client/mac',
+ );
+ foreach ($keys as $key) {
+ $p = $preferred;
+ $m = $methods;
+
+ $subkeys = explode('/', $key);
+ foreach ($subkeys as $subkey) {
+ if (!isset($p[$subkey])) {
+ continue 2;
+ }
+ $p = $p[$subkey];
+ $m = $m[$subkey];
+ }
+
+ if (count($p) != count($m)) {
+ $diff = array_diff($m, $p);
+ $msg = count($diff) == 1 ?
+ ' is not a supported algorithm' :
+ ' are not supported algorithms';
+ user_error(implode(', ', $diff) . $msg);
+ return false;
+ }
+ }
+
+ $this->preferred = $preferred;
+ }
+
+ /**
+ * Returns the banner message.
+ *
+ * Quoting from the RFC, "in some jurisdictions, sending a warning message before
+ * authentication may be relevant for getting legal protection."
+ *
+ * @return string
+ * @access public
+ */
+ function getBannerMessage()
+ {
+ return $this->banner_message;
+ }
+
+ /**
+ * Returns the server public host key.
+ *
+ * Caching this the first time you connect to a server and checking the result on subsequent connections
+ * is recommended. Returns false if the server signature is not signed correctly with the public host key.
+ *
+ * @return mixed
+ * @access public
+ */
+ function getServerPublicHostKey()
+ {
+ if (!($this->bitmap & self::MASK_CONSTRUCTOR)) {
+ if (!$this->_connect()) {
+ return false;
+ }
+ }
+
+ $signature = $this->signature;
+ $server_public_host_key = $this->server_public_host_key;
+
+ if (strlen($server_public_host_key) < 4) {
+ return false;
+ }
+ extract(unpack('Nlength', $this->_string_shift($server_public_host_key, 4)));
+ $this->_string_shift($server_public_host_key, $length);
+
+ if ($this->signature_validated) {
+ return $this->bitmap ?
+ $this->signature_format . ' ' . base64_encode($this->server_public_host_key) :
+ false;
+ }
+
+ $this->signature_validated = true;
+
+ switch ($this->signature_format) {
+ case 'ssh-dss':
+ $zero = new BigInteger();
+
+ if (strlen($server_public_host_key) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+ $p = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
+
+ if (strlen($server_public_host_key) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+ $q = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
+
+ if (strlen($server_public_host_key) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+ $g = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
+
+ if (strlen($server_public_host_key) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+ $y = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
+
+ /* The value for 'dss_signature_blob' is encoded as a string containing
+ r, followed by s (which are 160-bit integers, without lengths or
+ padding, unsigned, and in network byte order). */
+ $temp = unpack('Nlength', $this->_string_shift($signature, 4));
+ if ($temp['length'] != 40) {
+ user_error('Invalid signature');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+
+ $r = new BigInteger($this->_string_shift($signature, 20), 256);
+ $s = new BigInteger($this->_string_shift($signature, 20), 256);
+
+ switch (true) {
+ case $r->equals($zero):
+ case $r->compare($q) >= 0:
+ case $s->equals($zero):
+ case $s->compare($q) >= 0:
+ user_error('Invalid signature');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+
+ $w = $s->modInverse($q);
+
+ $u1 = $w->multiply(new BigInteger(sha1($this->exchange_hash), 16));
+ list(, $u1) = $u1->divide($q);
+
+ $u2 = $w->multiply($r);
+ list(, $u2) = $u2->divide($q);
+
+ $g = $g->modPow($u1, $p);
+ $y = $y->modPow($u2, $p);
+
+ $v = $g->multiply($y);
+ list(, $v) = $v->divide($p);
+ list(, $v) = $v->divide($q);
+
+ if (!$v->equals($r)) {
+ user_error('Bad server signature');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
+ }
+
+ break;
+ case 'ssh-rsa':
+ case 'rsa-sha2-256':
+ case 'rsa-sha2-512':
+ if (strlen($server_public_host_key) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+ $e = new BigInteger($this->_string_shift($server_public_host_key, $temp['length']), -256);
+
+ if (strlen($server_public_host_key) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($server_public_host_key, 4));
+ $rawN = $this->_string_shift($server_public_host_key, $temp['length']);
+ $n = new BigInteger($rawN, -256);
+ $nLength = strlen(ltrim($rawN, "\0"));
+
+ /*
+ if (strlen($signature) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($signature, 4));
+ $signature = $this->_string_shift($signature, $temp['length']);
+
+ $rsa = new RSA();
+ switch ($this->signature_format) {
+ case 'rsa-sha2-512':
+ $hash = 'sha512';
+ break;
+ case 'rsa-sha2-256':
+ $hash = 'sha256';
+ break;
+ //case 'ssh-rsa':
+ default:
+ $hash = 'sha1';
+ }
+ $rsa->setHash($hash);
+ $rsa->setSignatureMode(RSA::SIGNATURE_PKCS1);
+ $rsa->loadKey(array('e' => $e, 'n' => $n), RSA::PUBLIC_FORMAT_RAW);
+
+ if (!$rsa->verify($this->exchange_hash, $signature)) {
+ user_error('Bad server signature');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
+ }
+ */
+
+ if (strlen($signature) < 4) {
+ return false;
+ }
+ $temp = unpack('Nlength', $this->_string_shift($signature, 4));
+ $s = new BigInteger($this->_string_shift($signature, $temp['length']), 256);
+
+ // validate an RSA signature per "8.2 RSASSA-PKCS1-v1_5", "5.2.2 RSAVP1", and "9.1 EMSA-PSS" in the
+ // following URL:
+ // ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf
+
+ // also, see SSHRSA.c (rsa2_verifysig) in PuTTy's source.
+
+ if ($s->compare(new BigInteger()) < 0 || $s->compare($n->subtract(new BigInteger(1))) > 0) {
+ user_error('Invalid signature');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED);
+ }
+
+ $s = $s->modPow($e, $n);
+ $s = $s->toBytes();
+
+ switch ($this->signature_format) {
+ case 'rsa-sha2-512':
+ $hash = 'sha512';
+ break;
+ case 'rsa-sha2-256':
+ $hash = 'sha256';
+ break;
+ //case 'ssh-rsa':
+ default:
+ $hash = 'sha1';
+ }
+ $hashObj = new Hash($hash);
+ switch ($this->signature_format) {
+ case 'rsa-sha2-512':
+ $h = pack('N5a*', 0x00305130, 0x0D060960, 0x86480165, 0x03040203, 0x05000440, $hashObj->hash($this->exchange_hash));
+ break;
+ case 'rsa-sha2-256':
+ $h = pack('N5a*', 0x00303130, 0x0D060960, 0x86480165, 0x03040201, 0x05000420, $hashObj->hash($this->exchange_hash));
+ break;
+ //case 'ssh-rsa':
+ default:
+ $hash = 'sha1';
+ $h = pack('N4a*', 0x00302130, 0x0906052B, 0x0E03021A, 0x05000414, $hashObj->hash($this->exchange_hash));
+ }
+ $h = chr(0x01) . str_repeat(chr(0xFF), $nLength - 2 - strlen($h)) . $h;
+
+ if ($s != $h) {
+ user_error('Bad server signature');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
+ }
+ break;
+ default:
+ user_error('Unsupported signature format');
+ return $this->_disconnect(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE);
+ }
+
+ return $this->signature_format . ' ' . base64_encode($this->server_public_host_key);
+ }
+
+ /**
+ * Returns the exit status of an SSH command or false.
+ *
+ * @return false|int
+ * @access public
+ */
+ function getExitStatus()
+ {
+ if (is_null($this->exit_status)) {
+ return false;
+ }
+ return $this->exit_status;
+ }
+
+ /**
+ * Returns the number of columns for the terminal window size.
+ *
+ * @return int
+ * @access public
+ */
+ function getWindowColumns()
+ {
+ return $this->windowColumns;
+ }
+
+ /**
+ * Returns the number of rows for the terminal window size.
+ *
+ * @return int
+ * @access public
+ */
+ function getWindowRows()
+ {
+ return $this->windowRows;
+ }
+
+ /**
+ * Sets the number of columns for the terminal window size.
+ *
+ * @param int $value
+ * @access public
+ */
+ function setWindowColumns($value)
+ {
+ $this->windowColumns = $value;
+ }
+
+ /**
+ * Sets the number of rows for the terminal window size.
+ *
+ * @param int $value
+ * @access public
+ */
+ function setWindowRows($value)
+ {
+ $this->windowRows = $value;
+ }
+
+ /**
+ * Sets the number of columns and rows for the terminal window size.
+ *
+ * @param int $columns
+ * @param int $rows
+ * @access public
+ */
+ function setWindowSize($columns = 80, $rows = 24)
+ {
+ $this->windowColumns = $columns;
+ $this->windowRows = $rows;
+ }
+
+ /**
+ * Update packet types in log history
+ *
+ * @param string $old
+ * @param string $new
+ * @access private
+ */
+ function _updateLogHistory($old, $new)
+ {
+ if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == self::LOG_COMPLEX) {
+ $this->message_number_log[count($this->message_number_log) - 1] = str_replace(
+ $old,
+ $new,
+ $this->message_number_log[count($this->message_number_log) - 1]
+ );
+ }
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
new file mode 100644
index 0000000..2b25250
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php
@@ -0,0 +1,351 @@
+<?php
+
+/**
+ * Pure-PHP ssh-agent client.
+ *
+ * PHP version 5
+ *
+ * Here are some examples of how to use this library:
+ * <code>
+ * <?php
+ * include 'vendor/autoload.php';
+ *
+ * $agent = new \phpseclib\System\SSH\Agent();
+ *
+ * $ssh = new \phpseclib\Net\SSH2('www.domain.tld');
+ * if (!$ssh->login('username', $agent)) {
+ * exit('Login Failed');
+ * }
+ *
+ * echo $ssh->exec('pwd');
+ * echo $ssh->exec('ls -la');
+ * ?>
+ * </code>
+ *
+ * @category System
+ * @package SSH\Agent
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2014 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ * @internal See http://api.libssh.org/rfc/PROTOCOL.agent
+ */
+
+namespace phpseclib\System\SSH;
+
+use phpseclib\Crypt\RSA;
+use phpseclib\System\SSH\Agent\Identity;
+
+/**
+ * Pure-PHP ssh-agent client identity factory
+ *
+ * requestIdentities() method pumps out \phpseclib\System\SSH\Agent\Identity objects
+ *
+ * @package SSH\Agent
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access public
+ */
+class Agent
+{
+ /**#@+
+ * Message numbers
+ *
+ * @access private
+ */
+ // to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1)
+ const SSH_AGENTC_REQUEST_IDENTITIES = 11;
+ // this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2).
+ const SSH_AGENT_IDENTITIES_ANSWER = 12;
+ // the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3)
+ const SSH_AGENTC_SIGN_REQUEST = 13;
+ // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4)
+ const SSH_AGENT_SIGN_RESPONSE = 14;
+ /**#@-*/
+
+ /**@+
+ * Agent forwarding status
+ *
+ * @access private
+ */
+ // no forwarding requested and not active
+ const FORWARD_NONE = 0;
+ // request agent forwarding when opportune
+ const FORWARD_REQUEST = 1;
+ // forwarding has been request and is active
+ const FORWARD_ACTIVE = 2;
+ /**#@-*/
+
+ /**
+ * Unused
+ */
+ const SSH_AGENT_FAILURE = 5;
+
+ /**
+ * Socket Resource
+ *
+ * @var resource
+ * @access private
+ */
+ var $fsock;
+
+ /**
+ * Agent forwarding status
+ *
+ * @access private
+ */
+ var $forward_status = self::FORWARD_NONE;
+
+ /**
+ * Buffer for accumulating forwarded authentication
+ * agent data arriving on SSH data channel destined
+ * for agent unix socket
+ *
+ * @access private
+ */
+ var $socket_buffer = '';
+
+ /**
+ * Tracking the number of bytes we are expecting
+ * to arrive for the agent socket on the SSH data
+ * channel
+ */
+ var $expected_bytes = 0;
+
+ /**
+ * Default Constructor
+ *
+ * @return \phpseclib\System\SSH\Agent
+ * @access public
+ */
+ function __construct($address = null)
+ {
+ if (!$address) {
+ switch (true) {
+ case isset($_SERVER['SSH_AUTH_SOCK']):
+ $address = $_SERVER['SSH_AUTH_SOCK'];
+ break;
+ case isset($_ENV['SSH_AUTH_SOCK']):
+ $address = $_ENV['SSH_AUTH_SOCK'];
+ break;
+ default:
+ user_error('SSH_AUTH_SOCK not found');
+ return false;
+ }
+ }
+
+ $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr);
+ if (!$this->fsock) {
+ user_error("Unable to connect to ssh-agent (Error $errno: $errstr)");
+ }
+ }
+
+ /**
+ * Request Identities
+ *
+ * See "2.5.2 Requesting a list of protocol 2 keys"
+ * Returns an array containing zero or more \phpseclib\System\SSH\Agent\Identity objects
+ *
+ * @return array
+ * @access public
+ */
+ function requestIdentities()
+ {
+ if (!$this->fsock) {
+ return array();
+ }
+
+ $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES);
+ if (strlen($packet) != fputs($this->fsock, $packet)) {
+ user_error('Connection closed while requesting identities');
+ return array();
+ }
+
+ $temp = fread($this->fsock, 4);
+ if (strlen($temp) != 4) {
+ user_error('Connection closed while requesting identities');
+ return array();
+ }
+ $length = current(unpack('N', $temp));
+ $type = ord(fread($this->fsock, 1));
+ if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) {
+ user_error('Unable to request identities');
+ return array();
+ }
+
+ $identities = array();
+ $temp = fread($this->fsock, 4);
+ if (strlen($temp) != 4) {
+ user_error('Connection closed while requesting identities');
+ return array();
+ }
+ $keyCount = current(unpack('N', $temp));
+ for ($i = 0; $i < $keyCount; $i++) {
+ $temp = fread($this->fsock, 4);
+ if (strlen($temp) != 4) {
+ user_error('Connection closed while requesting identities');
+ return array();
+ }
+ $length = current(unpack('N', $temp));
+ $key_blob = fread($this->fsock, $length);
+ if (strlen($key_blob) != $length) {
+ user_error('Connection closed while requesting identities');
+ return array();
+ }
+ $key_str = 'ssh-rsa ' . base64_encode($key_blob);
+ $temp = fread($this->fsock, 4);
+ if (strlen($temp) != 4) {
+ user_error('Connection closed while requesting identities');
+ return array();
+ }
+ $length = current(unpack('N', $temp));
+ if ($length) {
+ $temp = fread($this->fsock, $length);
+ if (strlen($temp) != $length) {
+ user_error('Connection closed while requesting identities');
+ return array();
+ }
+ $key_str.= ' ' . $temp;
+ }
+ $length = current(unpack('N', substr($key_blob, 0, 4)));
+ $key_type = substr($key_blob, 4, $length);
+ switch ($key_type) {
+ case 'ssh-rsa':
+ $key = new RSA();
+ $key->loadKey($key_str);
+ break;
+ case 'ssh-dss':
+ // not currently supported
+ break;
+ }
+ // resources are passed by reference by default
+ if (isset($key)) {
+ $identity = new Identity($this->fsock);
+ $identity->setPublicKey($key);
+ $identity->setPublicKeyBlob($key_blob);
+ $identities[] = $identity;
+ unset($key);
+ }
+ }
+
+ return $identities;
+ }
+
+ /**
+ * Signal that agent forwarding should
+ * be requested when a channel is opened
+ *
+ * @param Net_SSH2 $ssh
+ * @return bool
+ * @access public
+ */
+ function startSSHForwarding($ssh)
+ {
+ if ($this->forward_status == self::FORWARD_NONE) {
+ $this->forward_status = self::FORWARD_REQUEST;
+ }
+ }
+
+ /**
+ * Request agent forwarding of remote server
+ *
+ * @param Net_SSH2 $ssh
+ * @return bool
+ * @access private
+ */
+ function _request_forwarding($ssh)
+ {
+ $request_channel = $ssh->_get_open_channel();
+ if ($request_channel === false) {
+ return false;
+ }
+
+ $packet = pack(
+ 'CNNa*C',
+ NET_SSH2_MSG_CHANNEL_REQUEST,
+ $ssh->server_channels[$request_channel],
+ strlen('auth-agent-req@openssh.com'),
+ 'auth-agent-req@openssh.com',
+ 1
+ );
+
+ $ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST;
+
+ if (!$ssh->_send_binary_packet($packet)) {
+ return false;
+ }
+
+ $response = $ssh->_get_channel_packet($request_channel);
+ if ($response === false) {
+ return false;
+ }
+
+ $ssh->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN;
+ $this->forward_status = self::FORWARD_ACTIVE;
+
+ return true;
+ }
+
+ /**
+ * On successful channel open
+ *
+ * This method is called upon successful channel
+ * open to give the SSH Agent an opportunity
+ * to take further action. i.e. request agent forwarding
+ *
+ * @param Net_SSH2 $ssh
+ * @access private
+ */
+ function _on_channel_open($ssh)
+ {
+ if ($this->forward_status == self::FORWARD_REQUEST) {
+ $this->_request_forwarding($ssh);
+ }
+ }
+
+ /**
+ * Forward data to SSH Agent and return data reply
+ *
+ * @param string $data
+ * @return data from SSH Agent
+ * @access private
+ */
+ function _forward_data($data)
+ {
+ if ($this->expected_bytes > 0) {
+ $this->socket_buffer.= $data;
+ $this->expected_bytes -= strlen($data);
+ } else {
+ $agent_data_bytes = current(unpack('N', $data));
+ $current_data_bytes = strlen($data);
+ $this->socket_buffer = $data;
+ if ($current_data_bytes != $agent_data_bytes + 4) {
+ $this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes;
+ return false;
+ }
+ }
+
+ if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) {
+ user_error('Connection closed attempting to forward data to SSH agent');
+ return false;
+ }
+
+ $this->socket_buffer = '';
+ $this->expected_bytes = 0;
+
+ $temp = fread($this->fsock, 4);
+ if (strlen($temp) != 4) {
+ user_error('Connection closed while reading data response');
+ return false;
+ }
+ $agent_reply_bytes = current(unpack('N', $temp));
+
+ $agent_reply_data = fread($this->fsock, $agent_reply_bytes);
+ if (strlen($agent_reply_data) != $agent_reply_bytes) {
+ user_error('Connection closed while reading data response');
+ return false;
+ }
+ $agent_reply_data = current(unpack('a*', $agent_reply_data));
+
+ return pack('Na*', $agent_reply_bytes, $agent_reply_data);
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php
new file mode 100644
index 0000000..68b6bfd
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php
@@ -0,0 +1,241 @@
+<?php
+/**
+ * Pure-PHP ssh-agent client.
+ *
+ * PHP version 5
+ *
+ * @category System
+ * @package SSH\Agent
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @copyright 2009 Jim Wigginton
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ * @link http://phpseclib.sourceforge.net
+ * @internal See http://api.libssh.org/rfc/PROTOCOL.agent
+ */
+
+namespace phpseclib\System\SSH\Agent;
+
+use phpseclib\System\SSH\Agent;
+
+/**
+ * Pure-PHP ssh-agent client identity object
+ *
+ * Instantiation should only be performed by \phpseclib\System\SSH\Agent class.
+ * This could be thought of as implementing an interface that phpseclib\Crypt\RSA
+ * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something.
+ * The methods in this interface would be getPublicKey and sign since those are the
+ * methods phpseclib looks for to perform public key authentication.
+ *
+ * @package SSH\Agent
+ * @author Jim Wigginton <terrafrost@php.net>
+ * @access internal
+ */
+class Identity
+{
+ /**@+
+ * Signature Flags
+ *
+ * See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3
+ *
+ * @access private
+ */
+ const SSH_AGENT_RSA2_256 = 2;
+ const SSH_AGENT_RSA2_512 = 4;
+ /**#@-*/
+
+ /**
+ * Key Object
+ *
+ * @var \phpseclib\Crypt\RSA
+ * @access private
+ * @see self::getPublicKey()
+ */
+ var $key;
+
+ /**
+ * Key Blob
+ *
+ * @var string
+ * @access private
+ * @see self::sign()
+ */
+ var $key_blob;
+
+ /**
+ * Socket Resource
+ *
+ * @var resource
+ * @access private
+ * @see self::sign()
+ */
+ var $fsock;
+
+ /**
+ * Signature flags
+ *
+ * @var int
+ * @access private
+ * @see self::sign()
+ * @see self::setHash()
+ */
+ var $flags = 0;
+
+ /**
+ * Default Constructor.
+ *
+ * @param resource $fsock
+ * @return \phpseclib\System\SSH\Agent\Identity
+ * @access private
+ */
+ function __construct($fsock)
+ {
+ $this->fsock = $fsock;
+ }
+
+ /**
+ * Set Public Key
+ *
+ * Called by \phpseclib\System\SSH\Agent::requestIdentities()
+ *
+ * @param \phpseclib\Crypt\RSA $key
+ * @access private
+ */
+ function setPublicKey($key)
+ {
+ $this->key = $key;
+ $this->key->setPublicKey();
+ }
+
+ /**
+ * Set Public Key
+ *
+ * Called by \phpseclib\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key
+ * but this saves a small amount of computation.
+ *
+ * @param string $key_blob
+ * @access private
+ */
+ function setPublicKeyBlob($key_blob)
+ {
+ $this->key_blob = $key_blob;
+ }
+
+ /**
+ * Get Public Key
+ *
+ * Wrapper for $this->key->getPublicKey()
+ *
+ * @param int $format optional
+ * @return mixed
+ * @access public
+ */
+ function getPublicKey($format = null)
+ {
+ return !isset($format) ? $this->key->getPublicKey() : $this->key->getPublicKey($format);
+ }
+
+ /**
+ * Set Signature Mode
+ *
+ * Doesn't do anything as ssh-agent doesn't let you pick and choose the signature mode. ie.
+ * ssh-agent's only supported mode is \phpseclib\Crypt\RSA::SIGNATURE_PKCS1
+ *
+ * @param int $mode
+ * @access public
+ */
+ function setSignatureMode($mode)
+ {
+ }
+
+ /**
+ * Set Hash
+ *
+ * ssh-agent doesn't support using hashes for RSA other than SHA1
+ *
+ * @param string $hash
+ * @access public
+ */
+ function setHash($hash)
+ {
+ $this->flags = 0;
+ switch ($hash) {
+ case 'sha1':
+ break;
+ case 'sha256':
+ $this->flags = self::SSH_AGENT_RSA2_256;
+ break;
+ case 'sha512':
+ $this->flags = self::SSH_AGENT_RSA2_512;
+ break;
+ default:
+ user_error('The only supported hashes for RSA are sha1, sha256 and sha512');
+ }
+ }
+
+ /**
+ * Create a signature
+ *
+ * See "2.6.2 Protocol 2 private key signature request"
+ *
+ * @param string $message
+ * @return string
+ * @access public
+ */
+ function sign($message)
+ {
+ // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE
+ $packet = pack('CNa*Na*N', Agent::SSH_AGENTC_SIGN_REQUEST, strlen($this->key_blob), $this->key_blob, strlen($message), $message, $this->flags);
+ $packet = pack('Na*', strlen($packet), $packet);
+ if (strlen($packet) != fputs($this->fsock, $packet)) {
+ user_error('Connection closed during signing');
+ return false;
+ }
+
+ $temp = fread($this->fsock, 4);
+ if (strlen($temp) != 4) {
+ user_error('Connection closed during signing');
+ return false;
+ }
+ $length = current(unpack('N', $temp));
+ $type = ord(fread($this->fsock, 1));
+ if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) {
+ user_error('Unable to retrieve signature');
+ return false;
+ }
+
+ $signature_blob = fread($this->fsock, $length - 1);
+ if (strlen($signature_blob) != $length - 1) {
+ user_error('Connection closed during signing');
+ return false;
+ }
+ $length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
+ if ($length != strlen($signature_blob)) {
+ user_error('Malformed signature blob');
+ }
+ $length = current(unpack('N', $this->_string_shift($signature_blob, 4)));
+ if ($length > strlen($signature_blob) + 4) {
+ user_error('Malformed signature blob');
+ }
+ $type = $this->_string_shift($signature_blob, $length);
+ $this->_string_shift($signature_blob, 4);
+
+ return $signature_blob;
+ }
+
+ /**
+ * String Shift
+ *
+ * Inspired by array_shift
+ *
+ * @param string $string
+ * @param int $index
+ * @return string
+ * @access private
+ */
+ function _string_shift(&$string, $index = 1)
+ {
+ $substr = substr($string, 0, $index);
+ $string = substr($string, $index);
+ return $substr;
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php b/platform/www/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php
new file mode 100644
index 0000000..0da0999
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Bootstrapping File for phpseclib
+ *
+ * @license http://www.opensource.org/licenses/mit-license.html MIT License
+ */
+
+if (extension_loaded('mbstring')) {
+ // 2 - MB_OVERLOAD_STRING
+ if (ini_get('mbstring.func_overload') & 2) {
+ throw new \UnexpectedValueException(
+ 'Overloading of string functions using mbstring.func_overload ' .
+ 'is not supported by phpseclib.'
+ );
+ }
+}
diff --git a/platform/www/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf b/platform/www/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
new file mode 100644
index 0000000..2b8b52f
--- /dev/null
+++ b/platform/www/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf
@@ -0,0 +1,6 @@
+# minimalist openssl.cnf file for use with phpseclib
+
+HOME = .
+RANDFILE = $ENV::HOME/.rnd
+
+[ v3_ca ]
diff --git a/platform/www/vendor/simplepie/simplepie/CHANGELOG.md b/platform/www/vendor/simplepie/simplepie/CHANGELOG.md
new file mode 100644
index 0000000..60395f0
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/CHANGELOG.md
@@ -0,0 +1,134 @@
+## 1.5.5 (May 1, 2020)
+
+* Ensure that feeds retrieved with `force_feed` do not share the same cache as those retrieved without. [#643](https://github.com/simplepie/simplepie/pull/643)
+* Removed references to removed PHP directives and some PHP < 5.6 checks. [#645](https://github.com/simplepie/simplepie/pull/645)
+* Corrected incorrect alumni name. [#638](https://github.com/simplepie/simplepie/pull/638)
+
+## 1.5.4 (December 17, 2019)
+
+* PHP 5.6 or newer is now required. [#625](https://github.com/simplepie/simplepie/pull/625)
+* Fixed invalid docblock parameter types [#633](https://github.com/simplepie/simplepie/pull/633)
+* Added support for German short forms for weekdays and months. [#632](https://github.com/simplepie/simplepie/pull/632)
+* PHP 7.4 support: Fixed instances of accessing array offset on null type values. [#628](https://github.com/simplepie/simplepie/pull/628)
+* Return an effective feed URL when asking for non-permanent `subscribe_url`. [#627](https://github.com/simplepie/simplepie/pull/627)
+
+## 1.5.3 (September 22, 2019)
+
+* Replaced `pow()` call with `**` operator (micro performance optimization). [#622](https://github.com/simplepie/simplepie/pull/622)
+* Match links containing `feed` in the Locator class. [#621](https://github.com/simplepie/simplepie/pull/621)
+* PHP 7.4 support: Ensure the proper argument order for `implode()` calls. [#617](https://github.com/simplepie/simplepie/pull/617)
+* Added support for Russian dates. [#607](https://github.com/simplepie/simplepie/pull/607)
+* Preemptively changed `is_writeable()` calls to `is_writable()` in case the former is deprecated in PHP. [#604](https://github.com/simplepie/simplepie/pull/604)
+
+## 1.5.2 (August 2, 2018)
+
+* Added support for PHPUnit 6. [#565](https://github.com/simplepie/simplepie/pull/565)
+* Added PHP module requirements to Composer. [#590](https://github.com/simplepie/simplepie/pull/590)
+* Added support for Redis password and database. [#589](https://github.com/simplepie/simplepie/pull/589)
+* Changed the spelling of `writeable` to `writable` within inline documentation. [#586](https://github.com/simplepie/simplepie/pull/586)
+* Fixed various issues in the test suite and Travis. [#576](https://github.com/simplepie/simplepie/pull/576)
+* Removed ambiguous tests failing on `usort()` in PHP 7. [#578](https://github.com/simplepie/simplepie/pull/578)
+* Simplified logic for some function returns. [#573](https://github.com/simplepie/simplepie/pull/573)
+* Fixed inline documentation for return value types for accuracy. [#570](https://github.com/simplepie/simplepie/pull/570)
+* Fixed Travis to run `composer install`. [#567](https://github.com/simplepie/simplepie/pull/567)
+* Removed unnecessary `else`s when a value has already been returned. [#566](https://github.com/simplepie/simplepie/pull/566)
+* Fixed a bug where URL fragments are included when `SimplePie_File` normalizes URLs when really old versions of cURL are used. [#564](https://github.com/simplepie/simplepie/pull/564)
+* Updated `SimplePie_Locator` to respect cURL options specified. [#561](https://github.com/simplepie/simplepie/pull/561)
+
+## 1.5.1 (November 17, 2017)
+
+* Fixed photos so they are not added if the URL is empty. [#530](https://github.com/simplepie/simplepie/pull/530)
+* Fixed issues with retrieving feeds from behind a proxy. [#512](https://github.com/simplepie/simplepie/pull/512)/[#548](https://github.com/simplepie/simplepie/pull/548)
+* Updated favicon URL in `get_favicon()`. [#525](https://github.com/simplepie/simplepie/pull/525)
+* Fixed inline documentation typo. [#540](https://github.com/simplepie/simplepie/pull/540)
+* Removed extra closing `<a>` tag. [#537](https://github.com/simplepie/simplepie/pull/537)
+* Removed and updated feed URLs in the demo. [#535](https://github.com/simplepie/simplepie/pull/535)
+* Improvements to microformat feed parsing. [#533](https://github.com/simplepie/simplepie/pull/533)
+* Switched from regex to xpath for microformats discovery. [#536](https://github.com/simplepie/simplepie/pull/536)
+* Update the registry if the Sanitize class has been changed. [#532](https://github.com/simplepie/simplepie/pull/532)
+* Changed the sanitization type for author and category back to text from HTML. [#531](https://github.com/simplepie/simplepie/pull/531)
+
+## 1.5 (April 17, 2017)
+
+* Introduced `SimplePie_Category->get_type()` for retrieving category type. [#492](https://github.com/simplepie/simplepie/pull/492)
+* Added `$enable_exceptions` to the class property declarations for `SimplePie` class. [#504](https://github.com/simplepie/simplepie/pull/504)
+* Titles are now parsed for ATOM10 enclosure links. [#507](https://github.com/simplepie/simplepie/pull/507)
+* `$item->get_id()` can now be forced to return the supplied ID instead of generating a new one. [#509](https://github.com/simplepie/simplepie/pull/509)
+
+## 1.4.3 (November 26, 2016)
+
+* Removed support for PHP 5.2. [#469](https://github.com/simplepie/simplepie/pull/469)
+* Added support for the PHP `UConverter` class. [#485](https://github.com/simplepie/simplepie/pull/485)
+* PHP 7.1 Support: Fixed PHP error when trying to use a non-numeric value in `round()`. [#458](https://github.com/simplepie/simplepie/pull/458)
+* PHP 7 Support: Fixed deprecated message for old style constructors. [#489](https://github.com/simplepie/simplepie/pull/489)
+* Fixed the error message shown when a feed has an empty body. [#487](https://github.com/simplepie/simplepie/pull/487)
+* Added an error message when the XML or PCRE PHP extensions are missing. [#468](https://github.com/simplepie/simplepie/pull/468)
+* Check the result of sanitize before returning in `get_content()` and `get_description()`. [#494](https://github.com/simplepie/simplepie/pull/494)
+* Use `saveHTML()` to fix issues with non UTF-8 characters. [#470](https://github.com/simplepie/simplepie/pull/470)
+* Stop passing compressed data through `trim()`. [#455](https://github.com/simplepie/simplepie/pull/455)
+* Refactored the UTF-8 conversion error message. [#467](https://github.com/simplepie/simplepie/pull/467)
+* Updated the readme file. [#486](https://github.com/simplepie/simplepie/pull/486)
+* Added command line support for compayibility test. [#481](https://github.com/simplepie/simplepie/pull/481)
+* Added PHP 7.1 to the testing matrix. [#462](https://github.com/simplepie/simplepie/pull/462)
+* Use the latest HHVM version in testing (3.15.2). [#480](https://github.com/simplepie/simplepie/pull/480)
+* Added PHPUnit as a `dev-dependency` in Composer. [#463](https://github.com/simplepie/simplepie/pull/463)
+* Added `mf2/mf2` as a suggestion in Composer for use with microformats. [#491](https://github.com/simplepie/simplepie/pull/491)
+* Fixed misspelled occurrences of "separated". [#459](https://github.com/simplepie/simplepie/pull/459)
+* Improvements to the compatibility test and error messages. [#488](https://github.com/simplepie/simplepie/pull/488)
+
+## 1.4.2 (June 14, 2016)
+
+* Fixed a bug with IRI parsing.
+* More cleanly separates discovery of microformats and parsing when php-mf2 is not present.
+
+## 1.4.1 (June 2, 2016)
+
+* Fixed inconsistent hash results in `SimplePie_Item->get_id()`.
+* Leading and trailing whitespace is now trimmed from XML feed content to prevent errors. [#445](https://github.com/simplepie/simplepie/pull/445)
+* Improved support for microformat feeds.
+
+## 1.4.0 (April 25, 2016)
+
+* Dropped support for PHP 5.2. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Serialized data is now used for hashing in `SimplePie_Item->get_id()`. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Added support for PHP 5.5 and 5.6. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Added the `add_attributes()` method to `SimplePie`. [#394](https://github.com/simplepie/simplepie/pull/394)
+* Added the `force_cache_fallback()` method to `SimplePie` to allow an expired cache to be used when a feed is unavailable. [#389](https://github.com/simplepie/simplepie/pull/389)
+* Added Memcached. [#386](https://github.com/simplepie/simplepie/pull/386)
+* Added `set_curl_options()` method to `SimplePie` to allow custom options. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Added Redis Caching. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Added the CEST timezone. [#380](https://github.com/simplepie/simplepie/pull/380)
+* Added support for HTTP 301 Moved Permanently. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Added support for `application/x-rss+xml` in `SimplePie_Locator`. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Added photo de-duping in microformats. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Added decoding for special characters in MAYBE_HTML. [#400](https://github.com/simplepie/simplepie/pull/400)
+* Added `SimplePie_Exception` for internally reporting errors. Also, use this to show an error when trying to load the class instead of causing a failure. [#241](https://github.com/simplepie/simplepie/pull/241)
+* Added sanitization of the `</html>` and `</body>` tags. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Added support for media thumbnails through `SimplePie_Item->get_thumbnail()`. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Added the `feed_url` to a returned error message. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Added cache purging after a specified period of time when using MySQL cache. [#329](https://github.com/simplepie/simplepie/pull/329)
+* Added backwards compatibility for removed `subscribe_*()` and `enable_xml_dump()` methods. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Re-added the deprecated `get/set_favicon()` methods for backwards compatibility.
+* Charsets are now compared without case sensitivity to avoid duplicates. [#352](https://github.com/simplepie/simplepie/pull/352)
+* Fixed encoding of ampersands in `SimplePie->subscribe_url()`. [#348](https://github.com/simplepie/simplepie/pull/348)
+* The feed URL is now updated based on the URL returned by cURL. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Explicitly use UTF-8 in `SimplePie_Misc->get_element()` and `Simple_ie_Misc->element_implode()`. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Improved support, feed and authorship discovery, and parsing for microformats. [#348](https://github.com/simplepie/simplepie/pull/348)
+* `rss:pubDate` is now used over `atom:updated` when determining the posting date. [#288](https://github.com/simplepie/simplepie/pull/288)
+* Simplified the use of `mtime()` and `touch()`. [#403](https://github.com/simplepie/simplepie/pull/403)
+* All items are now forced to have a timestamp. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Fixed typo in the date parser that incorrectly identified September as month 8. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Fixed backwards compatibility with cache subclasses. [#243](https://github.com/simplepie/simplepie/pull/243)
+* Fixed a bug where the updated date was not fetched correctly. [#239](https://github.com/simplepie/simplepie/pull/239)
+* Fixed the datatype for `items.data` to be more appropriate in when using MySQL cache. [#302](https://github.com/simplepie/simplepie/pull/302)
+* Fixed cURL not failing when the server returns an error. [#425](https://github.com/simplepie/simplepie/pull/425)
+* Fixed an error caused when trying to instantiate a `SimplePie_File` object with a bad URI. [#272](https://github.com/simplepie/simplepie/pull/272)
+* Fixed a PHP notice that occurs when a date starts with `(`. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Fixed uninitialized string offeset PHP notices. [#353](https://github.com/simplepie/simplepie/pull/353)
+* Fixed call to non-existent property in Memcache. [#311](https://github.com/simplepie/simplepie/pull/311)
+* Fixed a bug where MySQL statements were not being passed thorugh `prepare()`. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Fixed an instance where an error message in `SimplePie` was not being triggered correctly. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Fixed a bug with Russian feeds. [#348](https://github.com/simplepie/simplepie/pull/348)
+* Fixed an issue with memory leaks. [#287](https://github.com/simplepie/simplepie/pull/287)
+* Fixed use of `DOMElement` as array. [#315](https://github.com/simplepie/simplepie/pull/315)
+* Improved the error message when a feed cannot be found. [#348](https://github.com/simplepie/simplepie/pull/348)
diff --git a/platform/www/vendor/simplepie/simplepie/LICENSE.txt b/platform/www/vendor/simplepie/simplepie/LICENSE.txt
new file mode 100644
index 0000000..6503e83
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/LICENSE.txt
@@ -0,0 +1,26 @@
+Copyright (c) 2004-2007, Ryan Parman and Sam Sneddon.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice, this list
+ of conditions and the following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+ * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ to endorse or promote products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file
diff --git a/platform/www/vendor/simplepie/simplepie/README.markdown b/platform/www/vendor/simplepie/simplepie/README.markdown
new file mode 100644
index 0000000..9fcc129
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/README.markdown
@@ -0,0 +1,111 @@
+SimplePie
+=========
+
+SimplePie is a very fast and easy-to-use class, written in PHP, that puts the
+'simple' back into 'really simple syndication'. Flexible enough to suit
+beginners and veterans alike, SimplePie is focused on [speed, ease of use,
+compatibility and standards compliance][what_is].
+
+[what_is]: http://simplepie.org/wiki/faq/what_is_simplepie
+
+
+Requirements
+------------
+* PHP 5.6+ (Required since SimplePie 1.5.3)
+* libxml2 (certain 2.7.x releases are too buggy for words, and will crash)
+* One of iconv, mbstring or intl extensions
+* cURL or fsockopen()
+* PCRE support
+
+
+What comes in the package?
+--------------------------
+1. `library/` - SimplePie classes for use with the autoloader
+2. `autoloader.php` - The SimplePie Autoloader if you want to use the separate
+ file version.
+3. `README.markdown` - This document.
+4. `LICENSE.txt` - A copy of the BSD license.
+5. `compatibility_test/` - The SimplePie compatibility test that checks your
+ server for required settings.
+6. `demo/` - A basic feed reader demo that shows off some of SimplePie's more
+ noticeable features.
+7. `idn/` - A third-party library that SimplePie can optionally use to
+ understand Internationalized Domain Names (IDNs).
+8. `build/` - Scripts related to generating pieces of SimplePie
+9. `test/` - SimplePie's unit test suite.
+
+### Where's `simplepie.inc`?
+Since SimplePie 1.3, we've split the classes into separate files to make it easier
+to maintain and use.
+
+If you'd like a single monolithic file, you can run `php build/compile.php` to
+generate `SimplePie.compiled.php`.
+
+To start the demo
+-----------------
+1. Upload this package to your webserver.
+2. Make sure that the cache folder inside of the demo folder is server-writable.
+3. Navigate your browser to the demo folder.
+
+
+Need support?
+-------------
+For further setup and install documentation, function references, etc., visit
+[the wiki][wiki]. If you're using the latest version off GitHub, you can also
+check out the [API documentation][].
+
+If you can't find an answer to your question in the documentation, head on over
+to one of our [support channels][]. For bug reports and feature requests, visit
+the [issue tracker][].
+
+[API documentation]: http://dev.simplepie.org/api/
+[wiki]: http://simplepie.org/wiki/
+[support channels]: http://simplepie.org/support/
+[issue tracker]: http://github.com/simplepie/simplepie/issues
+
+
+Project status
+--------------
+SimplePie is currently maintained by Malcolm Blaney.
+
+As an open source project, SimplePie is maintained on a somewhat sporadic basis.
+This means that feature requests may not be fulfilled straight away, as time has
+to be prioritized.
+
+If you'd like to contribute to SimplePie, the best way to get started is to fork
+the project on GitHub and send pull requests for patches. When doing so, please
+be aware of our [coding standards][].
+
+[coding standards]: http://simplepie.org/wiki/misc/coding_standards
+
+
+Authors and contributors
+------------------------
+### Current
+* [Malcolm Blaney][] (Maintainer, support)
+
+### Alumni
+* [Ryan McCue][] (developer, support)
+* [Ryan Parman][] (Creator, developer, evangelism, support)
+* [Sam Sneddon][] (Lead developer)
+* [Michael Shipley][] (Submitter of patches, support)
+* [Steve Minutillo][] (Submitter of patches)
+
+[Malcolm Blaney]: https://unicyclic.com/mal
+[Ryan McCue]: http://ryanmccue.info
+[Ryan Parman]: http://ryanparman.com
+[Sam Sneddon]: https://gsnedders.com
+[Michael Shipley]: http://michaelpshipley.com
+[Steve Minutillo]: http://minutillo.com/steve/
+
+
+### Contributors
+For a complete list of contributors:
+
+1. Pull down the latest SimplePie code
+2. In the `simplepie` directory, run `git shortlog -ns`
+
+
+License
+-------
+[New BSD license](http://www.opensource.org/licenses/BSD-3-Clause)
diff --git a/platform/www/vendor/simplepie/simplepie/autoloader.php b/platform/www/vendor/simplepie/simplepie/autoloader.php
new file mode 100644
index 0000000..e42f07b
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/autoloader.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+
+// autoloader
+spl_autoload_register(array(new SimplePie_Autoloader(), 'autoload'));
+
+if (!class_exists('SimplePie'))
+{
+ trigger_error('Autoloader not registered properly', E_USER_ERROR);
+}
+
+/**
+ * Autoloader class
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Autoloader
+{
+ /**
+ * Constructor
+ */
+ public function __construct()
+ {
+ $this->path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'library';
+ }
+
+ /**
+ * Autoloader
+ *
+ * @param string $class The name of the class to attempt to load.
+ */
+ public function autoload($class)
+ {
+ // Only load the class if it starts with "SimplePie"
+ if (strpos($class, 'SimplePie') !== 0)
+ {
+ return;
+ }
+
+ $filename = $this->path . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
+ include $filename;
+ }
+} \ No newline at end of file
diff --git a/platform/www/vendor/simplepie/simplepie/idn/LICENCE b/platform/www/vendor/simplepie/simplepie/idn/LICENCE
new file mode 100644
index 0000000..25a1d22
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/idn/LICENCE
@@ -0,0 +1,502 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, 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 library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete 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 distribute a copy of this License along with the
+Library.
+
+ 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 Library or any portion
+of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+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 Library, 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 Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you 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.
+
+ If distribution of 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 satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be 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.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library 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.
+
+ 9. 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 Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+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 with
+this License.
+
+ 11. 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 Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library 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 Library.
+
+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.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library 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.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+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 Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+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
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. 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 LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. 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 library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/platform/www/vendor/simplepie/simplepie/idn/ReadMe.txt b/platform/www/vendor/simplepie/simplepie/idn/ReadMe.txt
new file mode 100644
index 0000000..7ca8c7e
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/idn/ReadMe.txt
@@ -0,0 +1,123 @@
+*******************************************************************************
+* *
+* IDNA Convert (idna_convert.class.php) *
+* *
+* http://idnaconv.phlymail.de mailto:phlymail@phlylabs.de *
+*******************************************************************************
+* (c) 2004-2007 phlyLabs, Berlin *
+* This file is encoded in UTF-8 *
+*******************************************************************************
+
+Introduction
+------------
+
+The class idna_convert allows to convert internationalized domain names
+(see RFC 3490, 3491, 3492 and 3454 for detials) as they can be used with various
+registries worldwide to be translated between their original (localized) form
+and their encoded form as it will be used in the DNS (Domain Name System).
+
+The class provides two public methods, encode() and decode(), which do exactly
+what you would expect them to do. You are allowed to use complete domain names,
+simple strings and complete email addresses as well. That means, that you might
+use any of the following notations:
+
+- www.nörgler.com
+- xn--nrgler-wxa
+- xn--brse-5qa.xn--knrz-1ra.info
+
+Errors, incorrectly encoded or invalid strings will lead to either a FALSE
+response (when in strict mode) or to only partially converted strings.
+You can query the occured error by calling the method get_last_error().
+
+Unicode strings are expected to be either UTF-8 strings, UCS-4 strings or UCS-4
+arrays. The default format is UTF-8. For setting different encodings, you can
+call the method setParams() - please see the inline documentation for details.
+ACE strings (the Punycode form) are always 7bit ASCII strings.
+
+ATTENTION: We no longer supply the PHP5 version of the class. It is not
+necessary for achieving a successfull conversion, since the supplied PHP code is
+compatible with both PHP4 and PHP5. We expect to see no compatibility issues
+with the upcoming PHP6, too.
+
+
+Files
+-----
+
+idna_convert.class.php - The actual class
+idna_convert.create.npdata.php - Useful for (re)creating the NPData file
+npdata.ser - Serialized data for NamePrep
+example.php - An example web page for converting
+ReadMe.txt - This file
+LICENCE - The LGPL licence file
+
+The class is contained in idna_convert.class.php.
+MAKE SURE to copy the npdata.ser file into the same folder as the class file
+itself!
+
+
+Examples
+--------
+
+1. Say we wish to encode the domain name nörgler.com:
+
+// Include the class
+include_once('idna_convert.class.php');
+// Instantiate it *
+$IDN = new idna_convert();
+// The input string, if input is not UTF-8 or UCS-4, it must be converted before
+$input = utf8_encode('nörgler.com');
+// Encode it to its punycode presentation
+$output = $IDN->encode($input);
+// Output, what we got now
+echo $output; // This will read: xn--nrgler-wxa.com
+
+
+2. We received an email from a punycoded domain and are willing to learn, how
+ the domain name reads originally
+
+// Include the class
+include_once('idna_convert.class.php');
+// Instantiate it (depending on the version you are using) with
+$IDN = new idna_convert();
+// The input string
+$input = 'andre@xn--brse-5qa.xn--knrz-1ra.info';
+// Encode it to its punycode presentation
+$output = $IDN->decode($input);
+// Output, what we got now, if output should be in a format different to UTF-8
+// or UCS-4, you will have to convert it before outputting it
+echo utf8_decode($output); // This will read: andre@börse.knörz.info
+
+
+3. The input is read from a UCS-4 coded file and encoded line by line. By
+ appending the optional second parameter we tell enode() about the input
+ format to be used
+
+// Include the class
+include_once('idna_convert.class.php');
+// Instantiate it
+$IDN = new dinca_convert();
+// Iterate through the input file line by line
+foreach (file('ucs4-domains.txt') as $line) {
+ echo $IDN->encode(trim($line), 'ucs4_string');
+ echo "\n";
+}
+
+
+NPData
+------
+
+Should you need to recreate the npdata.ser file, which holds all necessary translation
+tables in a serialized format, you can run the file idna_convert.create.npdata.php, which
+creates the file for you and stores it in the same folder, where it is placed.
+Should you need to do changes to the tables you can do so, but beware of the consequences.
+
+
+Contact us
+----------
+
+In case of errors, bugs, questions, wishes, please don't hesitate to contact us
+under the email address above.
+
+The team of phlyLabs
+http://phlylabs.de
+mailto:phlymail@phlylabs.de \ No newline at end of file
diff --git a/platform/www/vendor/simplepie/simplepie/idn/idna_convert.class.php b/platform/www/vendor/simplepie/simplepie/idn/idna_convert.class.php
new file mode 100644
index 0000000..ec137dc
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/idn/idna_convert.class.php
@@ -0,0 +1,969 @@
+<?php
+// {{{ license
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
+//
+// +----------------------------------------------------------------------+
+// | This library is free software; you can redistribute it and/or modify |
+// | it under the terms of the GNU Lesser General Public License as |
+// | published by the Free Software Foundation; either version 2.1 of the |
+// | License, or (at your option) any later version. |
+// | |
+// | This library 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 |
+// | Lesser General Public License for more details. |
+// | |
+// | You should have received a copy of the GNU Lesser General Public |
+// | License along with this library; if not, write to the Free Software |
+// | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
+// | USA. |
+// +----------------------------------------------------------------------+
+//
+
+// }}}
+
+/**
+ * Encode/decode Internationalized Domain Names.
+ *
+ * The class allows to convert internationalized domain names
+ * (see RFC 3490 for details) as they can be used with various registries worldwide
+ * to be translated between their original (localized) form and their encoded form
+ * as it will be used in the DNS (Domain Name System).
+ *
+ * The class provides two public methods, encode() and decode(), which do exactly
+ * what you would expect them to do. You are allowed to use complete domain names,
+ * simple strings and complete email addresses as well. That means, that you might
+ * use any of the following notations:
+ *
+ * - www.nörgler.com
+ * - xn--nrgler-wxa
+ * - xn--brse-5qa.xn--knrz-1ra.info
+ *
+ * Unicode input might be given as either UTF-8 string, UCS-4 string or UCS-4
+ * array. Unicode output is available in the same formats.
+ * You can select your preferred format via {@link set_paramter()}.
+ *
+ * ACE input and output is always expected to be ASCII.
+ *
+ * @author Matthias Sommerfeld <mso@phlylabs.de>
+ * @copyright 2004-2007 phlyLabs Berlin, http://phlylabs.de
+ * @version 0.5.1
+ *
+ */
+class idna_convert
+{
+ /**
+ * Holds all relevant mapping tables, loaded from a seperate file on construct
+ * See RFC3454 for details
+ *
+ * @var array
+ * @access private
+ */
+ var $NP = array();
+
+ // Internal settings, do not mess with them
+ var $_punycode_prefix = 'xn--';
+ var $_invalid_ucs = 0x80000000;
+ var $_max_ucs = 0x10FFFF;
+ var $_base = 36;
+ var $_tmin = 1;
+ var $_tmax = 26;
+ var $_skew = 38;
+ var $_damp = 700;
+ var $_initial_bias = 72;
+ var $_initial_n = 0x80;
+ var $_sbase = 0xAC00;
+ var $_lbase = 0x1100;
+ var $_vbase = 0x1161;
+ var $_tbase = 0x11A7;
+ var $_lcount = 19;
+ var $_vcount = 21;
+ var $_tcount = 28;
+ var $_ncount = 588; // _vcount * _tcount
+ var $_scount = 11172; // _lcount * _tcount * _vcount
+ var $_error = false;
+
+ // See {@link set_paramter()} for details of how to change the following
+ // settings from within your script / application
+ var $_api_encoding = 'utf8'; // Default input charset is UTF-8
+ var $_allow_overlong = false; // Overlong UTF-8 encodings are forbidden
+ var $_strict_mode = false; // Behave strict or not
+
+ // The constructor
+ function __construct($options = false)
+ {
+ $this->slast = $this->_sbase + $this->_lcount * $this->_vcount * $this->_tcount;
+ if (function_exists('file_get_contents')) {
+ $this->NP = unserialize(file_get_contents(dirname(__FILE__).'/npdata.ser'));
+ } else {
+ $this->NP = unserialize(join('', file(dirname(__FILE__).'/npdata.ser')));
+ }
+ // If parameters are given, pass these to the respective method
+ if (is_array($options)) {
+ return $this->set_parameter($options);
+ }
+ return true;
+ }
+
+ /**
+ * Sets a new option value. Available options and values:
+ * [encoding - Use either UTF-8, UCS4 as array or UCS4 as string as input ('utf8' for UTF-8,
+ * 'ucs4_string' and 'ucs4_array' respectively for UCS4); The output is always UTF-8]
+ * [overlong - Unicode does not allow unnecessarily long encodings of chars,
+ * to allow this, set this parameter to true, else to false;
+ * default is false.]
+ * [strict - true: strict mode, good for registration purposes - Causes errors
+ * on failures; false: loose mode, ideal for "wildlife" applications
+ * by silently ignoring errors and returning the original input instead
+ *
+ * @param mixed Parameter to set (string: single parameter; array of Parameter => Value pairs)
+ * @param string Value to use (if parameter 1 is a string)
+ * @return boolean true on success, false otherwise
+ * @access public
+ */
+ function set_parameter($option, $value = false)
+ {
+ if (!is_array($option)) {
+ $option = array($option => $value);
+ }
+ foreach ($option as $k => $v) {
+ switch ($k) {
+ case 'encoding':
+ switch ($v) {
+ case 'utf8':
+ case 'ucs4_string':
+ case 'ucs4_array':
+ $this->_api_encoding = $v;
+ break;
+ default:
+ $this->_error('Set Parameter: Unknown parameter '.$v.' for option '.$k);
+ return false;
+ }
+ break;
+ case 'overlong':
+ $this->_allow_overlong = ($v) ? true : false;
+ break;
+ case 'strict':
+ $this->_strict_mode = ($v) ? true : false;
+ break;
+ default:
+ $this->_error('Set Parameter: Unknown option '.$k);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Decode a given ACE domain name
+ * @param string Domain name (ACE string)
+ * [@param string Desired output encoding, see {@link set_parameter}]
+ * @return string Decoded Domain name (UTF-8 or UCS-4)
+ * @access public
+ */
+ function decode($input, $one_time_encoding = false)
+ {
+ // Optionally set
+ if ($one_time_encoding) {
+ switch ($one_time_encoding) {
+ case 'utf8':
+ case 'ucs4_string':
+ case 'ucs4_array':
+ break;
+ default:
+ $this->_error('Unknown encoding '.$one_time_encoding);
+ return false;
+ }
+ }
+ // Make sure to drop any newline characters around
+ $input = trim($input);
+
+ // Negotiate input and try to determine, whether it is a plain string,
+ // an email address or something like a complete URL
+ if (strpos($input, '@')) { // Maybe it is an email address
+ // No no in strict mode
+ if ($this->_strict_mode) {
+ $this->_error('Only simple domain name parts can be handled in strict mode');
+ return false;
+ }
+ list ($email_pref, $input) = explode('@', $input, 2);
+ $arr = explode('.', $input);
+ foreach ($arr as $k => $v) {
+ if (preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $v)) {
+ $conv = $this->_decode($v);
+ if ($conv) $arr[$k] = $conv;
+ }
+ }
+ $input = join('.', $arr);
+ $arr = explode('.', $email_pref);
+ foreach ($arr as $k => $v) {
+ if (preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $v)) {
+ $conv = $this->_decode($v);
+ if ($conv) $arr[$k] = $conv;
+ }
+ }
+ $email_pref = join('.', $arr);
+ $return = $email_pref . '@' . $input;
+ } elseif (preg_match('![:\./]!', $input)) { // Or a complete domain name (with or without paths / parameters)
+ // No no in strict mode
+ if ($this->_strict_mode) {
+ $this->_error('Only simple domain name parts can be handled in strict mode');
+ return false;
+ }
+ $parsed = parse_url($input);
+ if (isset($parsed['host'])) {
+ $arr = explode('.', $parsed['host']);
+ foreach ($arr as $k => $v) {
+ $conv = $this->_decode($v);
+ if ($conv) $arr[$k] = $conv;
+ }
+ $parsed['host'] = join('.', $arr);
+ $return =
+ (empty($parsed['scheme']) ? '' : $parsed['scheme'].(strtolower($parsed['scheme']) == 'mailto' ? ':' : '://'))
+ .(empty($parsed['user']) ? '' : $parsed['user'].(empty($parsed['pass']) ? '' : ':'.$parsed['pass']).'@')
+ .$parsed['host']
+ .(empty($parsed['port']) ? '' : ':'.$parsed['port'])
+ .(empty($parsed['path']) ? '' : $parsed['path'])
+ .(empty($parsed['query']) ? '' : '?'.$parsed['query'])
+ .(empty($parsed['fragment']) ? '' : '#'.$parsed['fragment']);
+ } else { // parse_url seems to have failed, try without it
+ $arr = explode('.', $input);
+ foreach ($arr as $k => $v) {
+ $conv = $this->_decode($v);
+ $arr[$k] = ($conv) ? $conv : $v;
+ }
+ $return = join('.', $arr);
+ }
+ } else { // Otherwise we consider it being a pure domain name string
+ $return = $this->_decode($input);
+ if (!$return) $return = $input;
+ }
+ // The output is UTF-8 by default, other output formats need conversion here
+ // If one time encoding is given, use this, else the objects property
+ switch (($one_time_encoding) ? $one_time_encoding : $this->_api_encoding) {
+ case 'utf8':
+ return $return;
+ break;
+ case 'ucs4_string':
+ return $this->_ucs4_to_ucs4_string($this->_utf8_to_ucs4($return));
+ break;
+ case 'ucs4_array':
+ return $this->_utf8_to_ucs4($return);
+ break;
+ default:
+ $this->_error('Unsupported output format');
+ return false;
+ }
+ }
+
+ /**
+ * Encode a given UTF-8 domain name
+ * @param string Domain name (UTF-8 or UCS-4)
+ * [@param string Desired input encoding, see {@link set_parameter}]
+ * @return string Encoded Domain name (ACE string)
+ * @access public
+ */
+ function encode($decoded, $one_time_encoding = false)
+ {
+ // Forcing conversion of input to UCS4 array
+ // If one time encoding is given, use this, else the objects property
+ switch ($one_time_encoding ? $one_time_encoding : $this->_api_encoding) {
+ case 'utf8':
+ $decoded = $this->_utf8_to_ucs4($decoded);
+ break;
+ case 'ucs4_string':
+ $decoded = $this->_ucs4_string_to_ucs4($decoded);
+ case 'ucs4_array':
+ break;
+ default:
+ $this->_error('Unsupported input format: '.($one_time_encoding ? $one_time_encoding : $this->_api_encoding));
+ return false;
+ }
+
+ // No input, no output, what else did you expect?
+ if (empty($decoded)) return '';
+
+ // Anchors for iteration
+ $last_begin = 0;
+ // Output string
+ $output = '';
+ foreach ($decoded as $k => $v) {
+ // Make sure to use just the plain dot
+ switch($v) {
+ case 0x3002:
+ case 0xFF0E:
+ case 0xFF61:
+ $decoded[$k] = 0x2E;
+ // Right, no break here, the above are converted to dots anyway
+ // Stumbling across an anchoring character
+ case 0x2E:
+ case 0x2F:
+ case 0x3A:
+ case 0x3F:
+ case 0x40:
+ // Neither email addresses nor URLs allowed in strict mode
+ if ($this->_strict_mode) {
+ $this->_error('Neither email addresses nor URLs are allowed in strict mode.');
+ return false;
+ }
+
+ // Skip first char
+ if ($k) {
+ $encoded = '';
+ $encoded = $this->_encode(array_slice($decoded, $last_begin, (($k)-$last_begin)));
+ if ($encoded) {
+ $output .= $encoded;
+ } else {
+ $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($k)-$last_begin)));
+ }
+ $output .= chr($decoded[$k]);
+ }
+ $last_begin = $k + 1;
+ }
+ }
+ // Catch the rest of the string
+ if ($last_begin) {
+ $inp_len = sizeof($decoded);
+ $encoded = '';
+ $encoded = $this->_encode(array_slice($decoded, $last_begin, (($inp_len)-$last_begin)));
+ if ($encoded) {
+ $output .= $encoded;
+ } else {
+ $output .= $this->_ucs4_to_utf8(array_slice($decoded, $last_begin, (($inp_len)-$last_begin)));
+ }
+ return $output;
+ }
+
+ if ($output = $this->_encode($decoded)) {
+ return $output;
+ }
+
+ return $this->_ucs4_to_utf8($decoded);
+ }
+
+ /**
+ * Use this method to get the last error ocurred
+ * @param void
+ * @return string The last error, that occured
+ * @access public
+ */
+ function get_last_error()
+ {
+ return $this->_error;
+ }
+
+ /**
+ * The actual decoding algorithm
+ * @access private
+ */
+ function _decode($encoded)
+ {
+ // We do need to find the Punycode prefix
+ if (!preg_match('!^'.preg_quote($this->_punycode_prefix, '!').'!', $encoded)) {
+ $this->_error('This is not a punycode string');
+ return false;
+ }
+ $encode_test = preg_replace('!^'.preg_quote($this->_punycode_prefix, '!').'!', '', $encoded);
+ // If nothing left after removing the prefix, it is hopeless
+ if (!$encode_test) {
+ $this->_error('The given encoded string was empty');
+ return false;
+ }
+ // Find last occurence of the delimiter
+ $delim_pos = strrpos($encoded, '-');
+ if ($delim_pos > strlen($this->_punycode_prefix)) {
+ for ($k = strlen($this->_punycode_prefix); $k < $delim_pos; ++$k) {
+ $decoded[] = ord($encoded{$k});
+ }
+ } else {
+ $decoded = array();
+ }
+ $deco_len = count($decoded);
+ $enco_len = strlen($encoded);
+
+ // Wandering through the strings; init
+ $is_first = true;
+ $bias = $this->_initial_bias;
+ $idx = 0;
+ $char = $this->_initial_n;
+
+ for ($enco_idx = ($delim_pos) ? ($delim_pos + 1) : 0; $enco_idx < $enco_len; ++$deco_len) {
+ for ($old_idx = $idx, $w = 1, $k = $this->_base; 1 ; $k += $this->_base) {
+ $digit = $this->_decode_digit($encoded{$enco_idx++});
+ $idx += $digit * $w;
+ $t = ($k <= $bias) ? $this->_tmin :
+ (($k >= $bias + $this->_tmax) ? $this->_tmax : ($k - $bias));
+ if ($digit < $t) break;
+ $w = (int) ($w * ($this->_base - $t));
+ }
+ $bias = $this->_adapt($idx - $old_idx, $deco_len + 1, $is_first);
+ $is_first = false;
+ $char += (int) ($idx / ($deco_len + 1));
+ $idx %= ($deco_len + 1);
+ if ($deco_len > 0) {
+ // Make room for the decoded char
+ for ($i = $deco_len; $i > $idx; $i--) {
+ $decoded[$i] = $decoded[($i - 1)];
+ }
+ }
+ $decoded[$idx++] = $char;
+ }
+ return $this->_ucs4_to_utf8($decoded);
+ }
+
+ /**
+ * The actual encoding algorithm
+ * @access private
+ */
+ function _encode($decoded)
+ {
+ // We cannot encode a domain name containing the Punycode prefix
+ $extract = strlen($this->_punycode_prefix);
+ $check_pref = $this->_utf8_to_ucs4($this->_punycode_prefix);
+ $check_deco = array_slice($decoded, 0, $extract);
+
+ if ($check_pref == $check_deco) {
+ $this->_error('This is already a punycode string');
+ return false;
+ }
+ // We will not try to encode strings consisting of basic code points only
+ $encodable = false;
+ foreach ($decoded as $k => $v) {
+ if ($v > 0x7a) {
+ $encodable = true;
+ break;
+ }
+ }
+ if (!$encodable) {
+ $this->_error('The given string does not contain encodable chars');
+ return false;
+ }
+
+ // Do NAMEPREP
+ $decoded = $this->_nameprep($decoded);
+ if (!$decoded || !is_array($decoded)) return false; // NAMEPREP failed
+
+ $deco_len = count($decoded);
+ if (!$deco_len) return false; // Empty array
+
+ $codecount = 0; // How many chars have been consumed
+
+ $encoded = '';
+ // Copy all basic code points to output
+ for ($i = 0; $i < $deco_len; ++$i) {
+ $test = $decoded[$i];
+ // Will match [-0-9a-zA-Z]
+ if ((0x2F < $test && $test < 0x40) || (0x40 < $test && $test < 0x5B)
+ || (0x60 < $test && $test <= 0x7B) || (0x2D == $test)) {
+ $encoded .= chr($decoded[$i]);
+ $codecount++;
+ }
+ }
+ if ($codecount == $deco_len) return $encoded; // All codepoints were basic ones
+
+ // Start with the prefix; copy it to output
+ $encoded = $this->_punycode_prefix.$encoded;
+
+ // If we have basic code points in output, add an hyphen to the end
+ if ($codecount) $encoded .= '-';
+
+ // Now find and encode all non-basic code points
+ $is_first = true;
+ $cur_code = $this->_initial_n;
+ $bias = $this->_initial_bias;
+ $delta = 0;
+ while ($codecount < $deco_len) {
+ // Find the smallest code point >= the current code point and
+ // remember the last ouccrence of it in the input
+ for ($i = 0, $next_code = $this->_max_ucs; $i < $deco_len; $i++) {
+ if ($decoded[$i] >= $cur_code && $decoded[$i] <= $next_code) {
+ $next_code = $decoded[$i];
+ }
+ }
+
+ $delta += ($next_code - $cur_code) * ($codecount + 1);
+ $cur_code = $next_code;
+
+ // Scan input again and encode all characters whose code point is $cur_code
+ for ($i = 0; $i < $deco_len; $i++) {
+ if ($decoded[$i] < $cur_code) {
+ $delta++;
+ } elseif ($decoded[$i] == $cur_code) {
+ for ($q = $delta, $k = $this->_base; 1; $k += $this->_base) {
+ $t = ($k <= $bias) ? $this->_tmin :
+ (($k >= $bias + $this->_tmax) ? $this->_tmax : $k - $bias);
+ if ($q < $t) break;
+ $encoded .= $this->_encode_digit(intval($t + (($q - $t) % ($this->_base - $t)))); //v0.4.5 Changed from ceil() to intval()
+ $q = (int) (($q - $t) / ($this->_base - $t));
+ }
+ $encoded .= $this->_encode_digit($q);
+ $bias = $this->_adapt($delta, $codecount+1, $is_first);
+ $codecount++;
+ $delta = 0;
+ $is_first = false;
+ }
+ }
+ $delta++;
+ $cur_code++;
+ }
+ return $encoded;
+ }
+
+ /**
+ * Adapt the bias according to the current code point and position
+ * @access private
+ */
+ function _adapt($delta, $npoints, $is_first)
+ {
+ $delta = intval($is_first ? ($delta / $this->_damp) : ($delta / 2));
+ $delta += intval($delta / $npoints);
+ for ($k = 0; $delta > (($this->_base - $this->_tmin) * $this->_tmax) / 2; $k += $this->_base) {
+ $delta = intval($delta / ($this->_base - $this->_tmin));
+ }
+ return intval($k + ($this->_base - $this->_tmin + 1) * $delta / ($delta + $this->_skew));
+ }
+
+ /**
+ * Encoding a certain digit
+ * @access private
+ */
+ function _encode_digit($d)
+ {
+ return chr($d + 22 + 75 * ($d < 26));
+ }
+
+ /**
+ * Decode a certain digit
+ * @access private
+ */
+ function _decode_digit($cp)
+ {
+ $cp = ord($cp);
+ return ($cp - 48 < 10) ? $cp - 22 : (($cp - 65 < 26) ? $cp - 65 : (($cp - 97 < 26) ? $cp - 97 : $this->_base));
+ }
+
+ /**
+ * Internal error handling method
+ * @access private
+ */
+ function _error($error = '')
+ {
+ $this->_error = $error;
+ }
+
+ /**
+ * Do Nameprep according to RFC3491 and RFC3454
+ * @param array Unicode Characters
+ * @return string Unicode Characters, Nameprep'd
+ * @access private
+ */
+ function _nameprep($input)
+ {
+ $output = array();
+ $error = false;
+ //
+ // Mapping
+ // Walking through the input array, performing the required steps on each of
+ // the input chars and putting the result into the output array
+ // While mapping required chars we apply the cannonical ordering
+ foreach ($input as $v) {
+ // Map to nothing == skip that code point
+ if (in_array($v, $this->NP['map_nothing'])) continue;
+
+ // Try to find prohibited input
+ if (in_array($v, $this->NP['prohibit']) || in_array($v, $this->NP['general_prohibited'])) {
+ $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v));
+ return false;
+ }
+ foreach ($this->NP['prohibit_ranges'] as $range) {
+ if ($range[0] <= $v && $v <= $range[1]) {
+ $this->_error('NAMEPREP: Prohibited input U+'.sprintf('%08X', $v));
+ return false;
+ }
+ }
+ //
+ // Hangul syllable decomposition
+ if (0xAC00 <= $v && $v <= 0xD7AF) {
+ foreach ($this->_hangul_decompose($v) as $out) {
+ $output[] = (int) $out;
+ }
+ // There's a decomposition mapping for that code point
+ } elseif (isset($this->NP['replacemaps'][$v])) {
+ foreach ($this->_apply_cannonical_ordering($this->NP['replacemaps'][$v]) as $out) {
+ $output[] = (int) $out;
+ }
+ } else {
+ $output[] = (int) $v;
+ }
+ }
+ // Before applying any Combining, try to rearrange any Hangul syllables
+ $output = $this->_hangul_compose($output);
+ //
+ // Combine code points
+ //
+ $last_class = 0;
+ $last_starter = 0;
+ $out_len = count($output);
+ for ($i = 0; $i < $out_len; ++$i) {
+ $class = $this->_get_combining_class($output[$i]);
+ if ((!$last_class || $last_class > $class) && $class) {
+ // Try to match
+ $seq_len = $i - $last_starter;
+ $out = $this->_combine(array_slice($output, $last_starter, $seq_len));
+ // On match: Replace the last starter with the composed character and remove
+ // the now redundant non-starter(s)
+ if ($out) {
+ $output[$last_starter] = $out;
+ if (count($out) != $seq_len) {
+ for ($j = $i+1; $j < $out_len; ++$j) {
+ $output[$j-1] = $output[$j];
+ }
+ unset($output[$out_len]);
+ }
+ // Rewind the for loop by one, since there can be more possible compositions
+ $i--;
+ $out_len--;
+ $last_class = ($i == $last_starter) ? 0 : $this->_get_combining_class($output[$i-1]);
+ continue;
+ }
+ }
+ // The current class is 0
+ if (!$class) $last_starter = $i;
+ $last_class = $class;
+ }
+ return $output;
+ }
+
+ /**
+ * Decomposes a Hangul syllable
+ * (see http://www.unicode.org/unicode/reports/tr15/#Hangul
+ * @param integer 32bit UCS4 code point
+ * @return array Either Hangul Syllable decomposed or original 32bit value as one value array
+ * @access private
+ */
+ function _hangul_decompose($char)
+ {
+ $sindex = (int) $char - $this->_sbase;
+ if ($sindex < 0 || $sindex >= $this->_scount) {
+ return array($char);
+ }
+ $result = array();
+ $result[] = (int) $this->_lbase + $sindex / $this->_ncount;
+ $result[] = (int) $this->_vbase + ($sindex % $this->_ncount) / $this->_tcount;
+ $T = intval($this->_tbase + $sindex % $this->_tcount);
+ if ($T != $this->_tbase) $result[] = $T;
+ return $result;
+ }
+ /**
+ * Ccomposes a Hangul syllable
+ * (see http://www.unicode.org/unicode/reports/tr15/#Hangul
+ * @param array Decomposed UCS4 sequence
+ * @return array UCS4 sequence with syllables composed
+ * @access private
+ */
+ function _hangul_compose($input)
+ {
+ $inp_len = count($input);
+ if (!$inp_len) return array();
+ $result = array();
+ $last = (int) $input[0];
+ $result[] = $last; // copy first char from input to output
+
+ for ($i = 1; $i < $inp_len; ++$i) {
+ $char = (int) $input[$i];
+ $sindex = $last - $this->_sbase;
+ $lindex = $last - $this->_lbase;
+ $vindex = $char - $this->_vbase;
+ $tindex = $char - $this->_tbase;
+ // Find out, whether two current characters are LV and T
+ if (0 <= $sindex && $sindex < $this->_scount && ($sindex % $this->_tcount == 0)
+ && 0 <= $tindex && $tindex <= $this->_tcount) {
+ // create syllable of form LVT
+ $last += $tindex;
+ $result[(count($result) - 1)] = $last; // reset last
+ continue; // discard char
+ }
+ // Find out, whether two current characters form L and V
+ if (0 <= $lindex && $lindex < $this->_lcount && 0 <= $vindex && $vindex < $this->_vcount) {
+ // create syllable of form LV
+ $last = (int) $this->_sbase + ($lindex * $this->_vcount + $vindex) * $this->_tcount;
+ $result[(count($result) - 1)] = $last; // reset last
+ continue; // discard char
+ }
+ // if neither case was true, just add the character
+ $last = $char;
+ $result[] = $char;
+ }
+ return $result;
+ }
+
+ /**
+ * Returns the combining class of a certain wide char
+ * @param integer Wide char to check (32bit integer)
+ * @return integer Combining class if found, else 0
+ * @access private
+ */
+ function _get_combining_class($char)
+ {
+ return isset($this->NP['norm_combcls'][$char]) ? $this->NP['norm_combcls'][$char] : 0;
+ }
+
+ /**
+ * Apllies the cannonical ordering of a decomposed UCS4 sequence
+ * @param array Decomposed UCS4 sequence
+ * @return array Ordered USC4 sequence
+ * @access private
+ */
+ function _apply_cannonical_ordering($input)
+ {
+ $swap = true;
+ $size = count($input);
+ while ($swap) {
+ $swap = false;
+ $last = $this->_get_combining_class(intval($input[0]));
+ for ($i = 0; $i < $size-1; ++$i) {
+ $next = $this->_get_combining_class(intval($input[$i+1]));
+ if ($next != 0 && $last > $next) {
+ // Move item leftward until it fits
+ for ($j = $i + 1; $j > 0; --$j) {
+ if ($this->_get_combining_class(intval($input[$j-1])) <= $next) break;
+ $t = intval($input[$j]);
+ $input[$j] = intval($input[$j-1]);
+ $input[$j-1] = $t;
+ $swap = true;
+ }
+ // Reentering the loop looking at the old character again
+ $next = $last;
+ }
+ $last = $next;
+ }
+ }
+ return $input;
+ }
+
+ /**
+ * Do composition of a sequence of starter and non-starter
+ * @param array UCS4 Decomposed sequence
+ * @return array Ordered USC4 sequence
+ * @access private
+ */
+ function _combine($input)
+ {
+ $inp_len = count($input);
+ foreach ($this->NP['replacemaps'] as $np_src => $np_target) {
+ if ($np_target[0] != $input[0]) continue;
+ if (count($np_target) != $inp_len) continue;
+ $hit = false;
+ foreach ($input as $k2 => $v2) {
+ if ($v2 == $np_target[$k2]) {
+ $hit = true;
+ } else {
+ $hit = false;
+ break;
+ }
+ }
+ if ($hit) return $np_src;
+ }
+ return false;
+ }
+
+ /**
+ * This converts an UTF-8 encoded string to its UCS-4 representation
+ * By talking about UCS-4 "strings" we mean arrays of 32bit integers representing
+ * each of the "chars". This is due to PHP not being able to handle strings with
+ * bit depth different from 8. This apllies to the reverse method _ucs4_to_utf8(), too.
+ * The following UTF-8 encodings are supported:
+ * bytes bits representation
+ * 1 7 0xxxxxxx
+ * 2 11 110xxxxx 10xxxxxx
+ * 3 16 1110xxxx 10xxxxxx 10xxxxxx
+ * 4 21 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ * 5 26 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ * 6 31 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ * Each x represents a bit that can be used to store character data.
+ * The five and six byte sequences are part of Annex D of ISO/IEC 10646-1:2000
+ * @access private
+ */
+ function _utf8_to_ucs4($input)
+ {
+ $output = array();
+ $out_len = 0;
+ $inp_len = strlen($input);
+ $mode = 'next';
+ $test = 'none';
+ for ($k = 0; $k < $inp_len; ++$k) {
+ $v = ord($input{$k}); // Extract byte from input string
+
+ if ($v < 128) { // We found an ASCII char - put into stirng as is
+ $output[$out_len] = $v;
+ ++$out_len;
+ if ('add' == $mode) {
+ $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
+ return false;
+ }
+ continue;
+ }
+ if ('next' == $mode) { // Try to find the next start byte; determine the width of the Unicode char
+ $start_byte = $v;
+ $mode = 'add';
+ $test = 'range';
+ if ($v >> 5 == 6) { // &110xxxxx 10xxxxx
+ $next_byte = 0; // Tells, how many times subsequent bitmasks must rotate 6bits to the left
+ $v = ($v - 192) << 6;
+ } elseif ($v >> 4 == 14) { // &1110xxxx 10xxxxxx 10xxxxxx
+ $next_byte = 1;
+ $v = ($v - 224) << 12;
+ } elseif ($v >> 3 == 30) { // &11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ $next_byte = 2;
+ $v = ($v - 240) << 18;
+ } elseif ($v >> 2 == 62) { // &111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ $next_byte = 3;
+ $v = ($v - 248) << 24;
+ } elseif ($v >> 1 == 126) { // &1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+ $next_byte = 4;
+ $v = ($v - 252) << 30;
+ } else {
+ $this->_error('This might be UTF-8, but I don\'t understand it at byte '.$k);
+ return false;
+ }
+ if ('add' == $mode) {
+ $output[$out_len] = (int) $v;
+ ++$out_len;
+ continue;
+ }
+ }
+ if ('add' == $mode) {
+ if (!$this->_allow_overlong && $test == 'range') {
+ $test = 'none';
+ if (($v < 0xA0 && $start_byte == 0xE0) || ($v < 0x90 && $start_byte == 0xF0) || ($v > 0x8F && $start_byte == 0xF4)) {
+ $this->_error('Bogus UTF-8 character detected (out of legal range) at byte '.$k);
+ return false;
+ }
+ }
+ if ($v >> 6 == 2) { // Bit mask must be 10xxxxxx
+ $v = ($v - 128) << ($next_byte * 6);
+ $output[($out_len - 1)] += $v;
+ --$next_byte;
+ } else {
+ $this->_error('Conversion from UTF-8 to UCS-4 failed: malformed input at byte '.$k);
+ return false;
+ }
+ if ($next_byte < 0) {
+ $mode = 'next';
+ }
+ }
+ } // for
+ return $output;
+ }
+
+ /**
+ * Convert UCS-4 string into UTF-8 string
+ * See _utf8_to_ucs4() for details
+ * @access private
+ */
+ function _ucs4_to_utf8($input)
+ {
+ $output = '';
+ $k = 0;
+ foreach ($input as $v) {
+ ++$k;
+ // $v = ord($v);
+ if ($v < 128) { // 7bit are transferred literally
+ $output .= chr($v);
+ } elseif ($v < (1 << 11)) { // 2 bytes
+ $output .= chr(192 + ($v >> 6)) . chr(128 + ($v & 63));
+ } elseif ($v < (1 << 16)) { // 3 bytes
+ $output .= chr(224 + ($v >> 12)) . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63));
+ } elseif ($v < (1 << 21)) { // 4 bytes
+ $output .= chr(240 + ($v >> 18)) . chr(128 + (($v >> 12) & 63))
+ . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63));
+ } elseif ($v < (1 << 26)) { // 5 bytes
+ $output .= chr(248 + ($v >> 24)) . chr(128 + (($v >> 18) & 63))
+ . chr(128 + (($v >> 12) & 63)) . chr(128 + (($v >> 6) & 63))
+ . chr(128 + ($v & 63));
+ } elseif ($v < (1 << 31)) { // 6 bytes
+ $output .= chr(252 + ($v >> 30)) . chr(128 + (($v >> 24) & 63))
+ . chr(128 + (($v >> 18) & 63)) . chr(128 + (($v >> 12) & 63))
+ . chr(128 + (($v >> 6) & 63)) . chr(128 + ($v & 63));
+ } else {
+ $this->_error('Conversion from UCS-4 to UTF-8 failed: malformed input at byte '.$k);
+ return false;
+ }
+ }
+ return $output;
+ }
+
+ /**
+ * Convert UCS-4 array into UCS-4 string
+ *
+ * @access private
+ */
+ function _ucs4_to_ucs4_string($input)
+ {
+ $output = '';
+ // Take array values and split output to 4 bytes per value
+ // The bit mask is 255, which reads &11111111
+ foreach ($input as $v) {
+ $output .= chr(($v >> 24) & 255).chr(($v >> 16) & 255).chr(($v >> 8) & 255).chr($v & 255);
+ }
+ return $output;
+ }
+
+ /**
+ * Convert UCS-4 strin into UCS-4 garray
+ *
+ * @access private
+ */
+ function _ucs4_string_to_ucs4($input)
+ {
+ $output = array();
+ $inp_len = strlen($input);
+ // Input length must be dividable by 4
+ if ($inp_len % 4) {
+ $this->_error('Input UCS4 string is broken');
+ return false;
+ }
+ // Empty input - return empty output
+ if (!$inp_len) return $output;
+ for ($i = 0, $out_len = -1; $i < $inp_len; ++$i) {
+ // Increment output position every 4 input bytes
+ if (!($i % 4)) {
+ $out_len++;
+ $output[$out_len] = 0;
+ }
+ $output[$out_len] += ord($input{$i}) << (8 * (3 - ($i % 4) ) );
+ }
+ return $output;
+ }
+}
+
+/**
+* Adapter class for aligning the API of idna_convert with that of Net_IDNA
+* @author Matthias Sommerfeld <mso@phlylabs.de>
+*/
+class Net_IDNA_php4 extends idna_convert
+{
+ /**
+ * Sets a new option value. Available options and values:
+ * [encoding - Use either UTF-8, UCS4 as array or UCS4 as string as input ('utf8' for UTF-8,
+ * 'ucs4_string' and 'ucs4_array' respectively for UCS4); The output is always UTF-8]
+ * [overlong - Unicode does not allow unnecessarily long encodings of chars,
+ * to allow this, set this parameter to true, else to false;
+ * default is false.]
+ * [strict - true: strict mode, good for registration purposes - Causes errors
+ * on failures; false: loose mode, ideal for "wildlife" applications
+ * by silently ignoring errors and returning the original input instead
+ *
+ * @param mixed Parameter to set (string: single parameter; array of Parameter => Value pairs)
+ * @param string Value to use (if parameter 1 is a string)
+ * @return boolean true on success, false otherwise
+ * @access public
+ */
+ function setParams($option, $param = false)
+ {
+ return $this->IC->set_parameters($option, $param);
+ }
+}
+
+?>
diff --git a/platform/www/vendor/simplepie/simplepie/idn/npdata.ser b/platform/www/vendor/simplepie/simplepie/idn/npdata.ser
new file mode 100644
index 0000000..d7ce6d0
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/idn/npdata.ser
@@ -0,0 +1 @@
+a:6:{s:11:"map_nothing";a:27:{i:0;i:173;i:1;i:847;i:2;i:6150;i:3;i:6155;i:4;i:6156;i:5;i:6157;i:6;i:8203;i:7;i:8204;i:8;i:8205;i:9;i:8288;i:10;i:65024;i:11;i:65025;i:12;i:65026;i:13;i:65027;i:14;i:65028;i:15;i:65029;i:16;i:65030;i:17;i:65031;i:18;i:65032;i:19;i:65033;i:20;i:65034;i:21;i:65035;i:22;i:65036;i:23;i:65037;i:24;i:65038;i:25;i:65039;i:26;i:65279;}s:18:"general_prohibited";a:64:{i:0;i:0;i:1;i:1;i:2;i:2;i:3;i:3;i:4;i:4;i:5;i:5;i:6;i:6;i:7;i:7;i:8;i:8;i:9;i:9;i:10;i:10;i:11;i:11;i:12;i:12;i:13;i:13;i:14;i:14;i:15;i:15;i:16;i:16;i:17;i:17;i:18;i:18;i:19;i:19;i:20;i:20;i:21;i:21;i:22;i:22;i:23;i:23;i:24;i:24;i:25;i:25;i:26;i:26;i:27;i:27;i:28;i:28;i:29;i:29;i:30;i:30;i:31;i:31;i:32;i:32;i:33;i:33;i:34;i:34;i:35;i:35;i:36;i:36;i:37;i:37;i:38;i:38;i:39;i:39;i:40;i:40;i:41;i:41;i:42;i:42;i:43;i:43;i:44;i:44;i:45;i:47;i:46;i:59;i:47;i:60;i:48;i:61;i:49;i:62;i:50;i:63;i:51;i:64;i:52;i:91;i:53;i:92;i:54;i:93;i:55;i:94;i:56;i:95;i:57;i:96;i:58;i:123;i:59;i:124;i:60;i:125;i:61;i:126;i:62;i:127;i:63;i:12290;}s:8:"prohibit";a:84:{i:0;i:160;i:1;i:5760;i:2;i:8192;i:3;i:8193;i:4;i:8194;i:5;i:8195;i:6;i:8196;i:7;i:8197;i:8;i:8198;i:9;i:8199;i:10;i:8200;i:11;i:8201;i:12;i:8202;i:13;i:8203;i:14;i:8239;i:15;i:8287;i:16;i:12288;i:17;i:1757;i:18;i:1807;i:19;i:6158;i:20;i:8204;i:21;i:8205;i:22;i:8232;i:23;i:8233;i:24;i:65279;i:25;i:65529;i:26;i:65530;i:27;i:65531;i:28;i:65532;i:29;i:65534;i:30;i:65535;i:31;i:131070;i:32;i:131071;i:33;i:196606;i:34;i:196607;i:35;i:262142;i:36;i:262143;i:37;i:327678;i:38;i:327679;i:39;i:393214;i:40;i:393215;i:41;i:458750;i:42;i:458751;i:43;i:524286;i:44;i:524287;i:45;i:589822;i:46;i:589823;i:47;i:655358;i:48;i:655359;i:49;i:720894;i:50;i:720895;i:51;i:786430;i:52;i:786431;i:53;i:851966;i:54;i:851967;i:55;i:917502;i:56;i:917503;i:57;i:983038;i:58;i:983039;i:59;i:1048574;i:60;i:1048575;i:61;i:1114110;i:62;i:1114111;i:63;i:65529;i:64;i:65530;i:65;i:65531;i:66;i:65532;i:67;i:65533;i:68;i:832;i:69;i:833;i:70;i:8206;i:71;i:8207;i:72;i:8234;i:73;i:8235;i:74;i:8236;i:75;i:8237;i:76;i:8238;i:77;i:8298;i:78;i:8299;i:79;i:8300;i:80;i:8301;i:81;i:8302;i:82;i:8303;i:83;i:917505;}s:15:"prohibit_ranges";a:10:{i:0;a:2:{i:0;i:128;i:1;i:159;}i:1;a:2:{i:0;i:8288;i:1;i:8303;}i:2;a:2:{i:0;i:119155;i:1;i:119162;}i:3;a:2:{i:0;i:57344;i:1;i:63743;}i:4;a:2:{i:0;i:983040;i:1;i:1048573;}i:5;a:2:{i:0;i:1048576;i:1;i:1114109;}i:6;a:2:{i:0;i:64976;i:1;i:65007;}i:7;a:2:{i:0;i:55296;i:1;i:57343;}i:8;a:2:{i:0;i:12272;i:1;i:12283;}i:9;a:2:{i:0;i:917536;i:1;i:917631;}}s:11:"replacemaps";a:1401:{i:65;a:1:{i:0;i:97;}i:66;a:1:{i:0;i:98;}i:67;a:1:{i:0;i:99;}i:68;a:1:{i:0;i:100;}i:69;a:1:{i:0;i:101;}i:70;a:1:{i:0;i:102;}i:71;a:1:{i:0;i:103;}i:72;a:1:{i:0;i:104;}i:73;a:1:{i:0;i:105;}i:74;a:1:{i:0;i:106;}i:75;a:1:{i:0;i:107;}i:76;a:1:{i:0;i:108;}i:77;a:1:{i:0;i:109;}i:78;a:1:{i:0;i:110;}i:79;a:1:{i:0;i:111;}i:80;a:1:{i:0;i:112;}i:81;a:1:{i:0;i:113;}i:82;a:1:{i:0;i:114;}i:83;a:1:{i:0;i:115;}i:84;a:1:{i:0;i:116;}i:85;a:1:{i:0;i:117;}i:86;a:1:{i:0;i:118;}i:87;a:1:{i:0;i:119;}i:88;a:1:{i:0;i:120;}i:89;a:1:{i:0;i:121;}i:90;a:1:{i:0;i:122;}i:181;a:1:{i:0;i:956;}i:192;a:1:{i:0;i:224;}i:193;a:1:{i:0;i:225;}i:194;a:1:{i:0;i:226;}i:195;a:1:{i:0;i:227;}i:196;a:1:{i:0;i:228;}i:197;a:1:{i:0;i:229;}i:198;a:1:{i:0;i:230;}i:199;a:1:{i:0;i:231;}i:200;a:1:{i:0;i:232;}i:201;a:1:{i:0;i:233;}i:202;a:1:{i:0;i:234;}i:203;a:1:{i:0;i:235;}i:204;a:1:{i:0;i:236;}i:205;a:1:{i:0;i:237;}i:206;a:1:{i:0;i:238;}i:207;a:1:{i:0;i:239;}i:208;a:1:{i:0;i:240;}i:209;a:1:{i:0;i:241;}i:210;a:1:{i:0;i:242;}i:211;a:1:{i:0;i:243;}i:212;a:1:{i:0;i:244;}i:213;a:1:{i:0;i:245;}i:214;a:1:{i:0;i:246;}i:216;a:1:{i:0;i:248;}i:217;a:1:{i:0;i:249;}i:218;a:1:{i:0;i:250;}i:219;a:1:{i:0;i:251;}i:220;a:1:{i:0;i:252;}i:221;a:1:{i:0;i:253;}i:222;a:1:{i:0;i:254;}i:223;a:2:{i:0;i:115;i:1;i:115;}i:256;a:1:{i:0;i:257;}i:258;a:1:{i:0;i:259;}i:260;a:1:{i:0;i:261;}i:262;a:1:{i:0;i:263;}i:264;a:1:{i:0;i:265;}i:266;a:1:{i:0;i:267;}i:268;a:1:{i:0;i:269;}i:270;a:1:{i:0;i:271;}i:272;a:1:{i:0;i:273;}i:274;a:1:{i:0;i:275;}i:276;a:1:{i:0;i:277;}i:278;a:1:{i:0;i:279;}i:280;a:1:{i:0;i:281;}i:282;a:1:{i:0;i:283;}i:284;a:1:{i:0;i:285;}i:286;a:1:{i:0;i:287;}i:288;a:1:{i:0;i:289;}i:290;a:1:{i:0;i:291;}i:292;a:1:{i:0;i:293;}i:294;a:1:{i:0;i:295;}i:296;a:1:{i:0;i:297;}i:298;a:1:{i:0;i:299;}i:300;a:1:{i:0;i:301;}i:302;a:1:{i:0;i:303;}i:304;a:2:{i:0;i:105;i:1;i:775;}i:306;a:1:{i:0;i:307;}i:308;a:1:{i:0;i:309;}i:310;a:1:{i:0;i:311;}i:313;a:1:{i:0;i:314;}i:315;a:1:{i:0;i:316;}i:317;a:1:{i:0;i:318;}i:319;a:1:{i:0;i:320;}i:321;a:1:{i:0;i:322;}i:323;a:1:{i:0;i:324;}i:325;a:1:{i:0;i:326;}i:327;a:1:{i:0;i:328;}i:329;a:2:{i:0;i:700;i:1;i:110;}i:330;a:1:{i:0;i:331;}i:332;a:1:{i:0;i:333;}i:334;a:1:{i:0;i:335;}i:336;a:1:{i:0;i:337;}i:338;a:1:{i:0;i:339;}i:340;a:1:{i:0;i:341;}i:342;a:1:{i:0;i:343;}i:344;a:1:{i:0;i:345;}i:346;a:1:{i:0;i:347;}i:348;a:1:{i:0;i:349;}i:350;a:1:{i:0;i:351;}i:352;a:1:{i:0;i:353;}i:354;a:1:{i:0;i:355;}i:356;a:1:{i:0;i:357;}i:358;a:1:{i:0;i:359;}i:360;a:1:{i:0;i:361;}i:362;a:1:{i:0;i:363;}i:364;a:1:{i:0;i:365;}i:366;a:1:{i:0;i:367;}i:368;a:1:{i:0;i:369;}i:370;a:1:{i:0;i:371;}i:372;a:1:{i:0;i:373;}i:374;a:1:{i:0;i:375;}i:376;a:1:{i:0;i:255;}i:377;a:1:{i:0;i:378;}i:379;a:1:{i:0;i:380;}i:381;a:1:{i:0;i:382;}i:383;a:1:{i:0;i:115;}i:385;a:1:{i:0;i:595;}i:386;a:1:{i:0;i:387;}i:388;a:1:{i:0;i:389;}i:390;a:1:{i:0;i:596;}i:391;a:1:{i:0;i:392;}i:393;a:1:{i:0;i:598;}i:394;a:1:{i:0;i:599;}i:395;a:1:{i:0;i:396;}i:398;a:1:{i:0;i:477;}i:399;a:1:{i:0;i:601;}i:400;a:1:{i:0;i:603;}i:401;a:1:{i:0;i:402;}i:403;a:1:{i:0;i:608;}i:404;a:1:{i:0;i:611;}i:406;a:1:{i:0;i:617;}i:407;a:1:{i:0;i:616;}i:408;a:1:{i:0;i:409;}i:412;a:1:{i:0;i:623;}i:413;a:1:{i:0;i:626;}i:415;a:1:{i:0;i:629;}i:416;a:1:{i:0;i:417;}i:418;a:1:{i:0;i:419;}i:420;a:1:{i:0;i:421;}i:422;a:1:{i:0;i:640;}i:423;a:1:{i:0;i:424;}i:425;a:1:{i:0;i:643;}i:428;a:1:{i:0;i:429;}i:430;a:1:{i:0;i:648;}i:431;a:1:{i:0;i:432;}i:433;a:1:{i:0;i:650;}i:434;a:1:{i:0;i:651;}i:435;a:1:{i:0;i:436;}i:437;a:1:{i:0;i:438;}i:439;a:1:{i:0;i:658;}i:440;a:1:{i:0;i:441;}i:444;a:1:{i:0;i:445;}i:452;a:1:{i:0;i:454;}i:453;a:1:{i:0;i:454;}i:455;a:1:{i:0;i:457;}i:456;a:1:{i:0;i:457;}i:458;a:1:{i:0;i:460;}i:459;a:1:{i:0;i:460;}i:461;a:1:{i:0;i:462;}i:463;a:1:{i:0;i:464;}i:465;a:1:{i:0;i:466;}i:467;a:1:{i:0;i:468;}i:469;a:1:{i:0;i:470;}i:471;a:1:{i:0;i:472;}i:473;a:1:{i:0;i:474;}i:475;a:1:{i:0;i:476;}i:478;a:1:{i:0;i:479;}i:480;a:1:{i:0;i:481;}i:482;a:1:{i:0;i:483;}i:484;a:1:{i:0;i:485;}i:486;a:1:{i:0;i:487;}i:488;a:1:{i:0;i:489;}i:490;a:1:{i:0;i:491;}i:492;a:1:{i:0;i:493;}i:494;a:1:{i:0;i:495;}i:496;a:2:{i:0;i:106;i:1;i:780;}i:497;a:1:{i:0;i:499;}i:498;a:1:{i:0;i:499;}i:500;a:1:{i:0;i:501;}i:502;a:1:{i:0;i:405;}i:503;a:1:{i:0;i:447;}i:504;a:1:{i:0;i:505;}i:506;a:1:{i:0;i:507;}i:508;a:1:{i:0;i:509;}i:510;a:1:{i:0;i:511;}i:512;a:1:{i:0;i:513;}i:514;a:1:{i:0;i:515;}i:516;a:1:{i:0;i:517;}i:518;a:1:{i:0;i:519;}i:520;a:1:{i:0;i:521;}i:522;a:1:{i:0;i:523;}i:524;a:1:{i:0;i:525;}i:526;a:1:{i:0;i:527;}i:528;a:1:{i:0;i:529;}i:530;a:1:{i:0;i:531;}i:532;a:1:{i:0;i:533;}i:534;a:1:{i:0;i:535;}i:536;a:1:{i:0;i:537;}i:538;a:1:{i:0;i:539;}i:540;a:1:{i:0;i:541;}i:542;a:1:{i:0;i:543;}i:544;a:1:{i:0;i:414;}i:546;a:1:{i:0;i:547;}i:548;a:1:{i:0;i:549;}i:550;a:1:{i:0;i:551;}i:552;a:1:{i:0;i:553;}i:554;a:1:{i:0;i:555;}i:556;a:1:{i:0;i:557;}i:558;a:1:{i:0;i:559;}i:560;a:1:{i:0;i:561;}i:562;a:1:{i:0;i:563;}i:837;a:1:{i:0;i:953;}i:890;a:2:{i:0;i:32;i:1;i:953;}i:902;a:1:{i:0;i:940;}i:904;a:1:{i:0;i:941;}i:905;a:1:{i:0;i:942;}i:906;a:1:{i:0;i:943;}i:908;a:1:{i:0;i:972;}i:910;a:1:{i:0;i:973;}i:911;a:1:{i:0;i:974;}i:912;a:3:{i:0;i:953;i:1;i:776;i:2;i:769;}i:913;a:1:{i:0;i:945;}i:914;a:1:{i:0;i:946;}i:915;a:1:{i:0;i:947;}i:916;a:1:{i:0;i:948;}i:917;a:1:{i:0;i:949;}i:918;a:1:{i:0;i:950;}i:919;a:1:{i:0;i:951;}i:920;a:1:{i:0;i:952;}i:921;a:1:{i:0;i:953;}i:922;a:1:{i:0;i:954;}i:923;a:1:{i:0;i:955;}i:924;a:1:{i:0;i:956;}i:925;a:1:{i:0;i:957;}i:926;a:1:{i:0;i:958;}i:927;a:1:{i:0;i:959;}i:928;a:1:{i:0;i:960;}i:929;a:1:{i:0;i:961;}i:931;a:1:{i:0;i:963;}i:932;a:1:{i:0;i:964;}i:933;a:1:{i:0;i:965;}i:934;a:1:{i:0;i:966;}i:935;a:1:{i:0;i:967;}i:936;a:1:{i:0;i:968;}i:937;a:1:{i:0;i:969;}i:938;a:1:{i:0;i:970;}i:939;a:1:{i:0;i:971;}i:944;a:3:{i:0;i:965;i:1;i:776;i:2;i:769;}i:962;a:1:{i:0;i:963;}i:976;a:1:{i:0;i:946;}i:977;a:1:{i:0;i:952;}i:978;a:1:{i:0;i:965;}i:979;a:1:{i:0;i:973;}i:980;a:1:{i:0;i:971;}i:981;a:1:{i:0;i:966;}i:982;a:1:{i:0;i:960;}i:984;a:1:{i:0;i:985;}i:986;a:1:{i:0;i:987;}i:988;a:1:{i:0;i:989;}i:990;a:1:{i:0;i:991;}i:992;a:1:{i:0;i:993;}i:994;a:1:{i:0;i:995;}i:996;a:1:{i:0;i:997;}i:998;a:1:{i:0;i:999;}i:1000;a:1:{i:0;i:1001;}i:1002;a:1:{i:0;i:1003;}i:1004;a:1:{i:0;i:1005;}i:1006;a:1:{i:0;i:1007;}i:1008;a:1:{i:0;i:954;}i:1009;a:1:{i:0;i:961;}i:1010;a:1:{i:0;i:963;}i:1012;a:1:{i:0;i:952;}i:1013;a:1:{i:0;i:949;}i:1024;a:1:{i:0;i:1104;}i:1025;a:1:{i:0;i:1105;}i:1026;a:1:{i:0;i:1106;}i:1027;a:1:{i:0;i:1107;}i:1028;a:1:{i:0;i:1108;}i:1029;a:1:{i:0;i:1109;}i:1030;a:1:{i:0;i:1110;}i:1031;a:1:{i:0;i:1111;}i:1032;a:1:{i:0;i:1112;}i:1033;a:1:{i:0;i:1113;}i:1034;a:1:{i:0;i:1114;}i:1035;a:1:{i:0;i:1115;}i:1036;a:1:{i:0;i:1116;}i:1037;a:1:{i:0;i:1117;}i:1038;a:1:{i:0;i:1118;}i:1039;a:1:{i:0;i:1119;}i:1040;a:1:{i:0;i:1072;}i:1041;a:1:{i:0;i:1073;}i:1042;a:1:{i:0;i:1074;}i:1043;a:1:{i:0;i:1075;}i:1044;a:1:{i:0;i:1076;}i:1045;a:1:{i:0;i:1077;}i:1046;a:1:{i:0;i:1078;}i:1047;a:1:{i:0;i:1079;}i:1048;a:1:{i:0;i:1080;}i:1049;a:1:{i:0;i:1081;}i:1050;a:1:{i:0;i:1082;}i:1051;a:1:{i:0;i:1083;}i:1052;a:1:{i:0;i:1084;}i:1053;a:1:{i:0;i:1085;}i:1054;a:1:{i:0;i:1086;}i:1055;a:1:{i:0;i:1087;}i:1056;a:1:{i:0;i:1088;}i:1057;a:1:{i:0;i:1089;}i:1058;a:1:{i:0;i:1090;}i:1059;a:1:{i:0;i:1091;}i:1060;a:1:{i:0;i:1092;}i:1061;a:1:{i:0;i:1093;}i:1062;a:1:{i:0;i:1094;}i:1063;a:1:{i:0;i:1095;}i:1064;a:1:{i:0;i:1096;}i:1065;a:1:{i:0;i:1097;}i:1066;a:1:{i:0;i:1098;}i:1067;a:1:{i:0;i:1099;}i:1068;a:1:{i:0;i:1100;}i:1069;a:1:{i:0;i:1101;}i:1070;a:1:{i:0;i:1102;}i:1071;a:1:{i:0;i:1103;}i:1120;a:1:{i:0;i:1121;}i:1122;a:1:{i:0;i:1123;}i:1124;a:1:{i:0;i:1125;}i:1126;a:1:{i:0;i:1127;}i:1128;a:1:{i:0;i:1129;}i:1130;a:1:{i:0;i:1131;}i:1132;a:1:{i:0;i:1133;}i:1134;a:1:{i:0;i:1135;}i:1136;a:1:{i:0;i:1137;}i:1138;a:1:{i:0;i:1139;}i:1140;a:1:{i:0;i:1141;}i:1142;a:1:{i:0;i:1143;}i:1144;a:1:{i:0;i:1145;}i:1146;a:1:{i:0;i:1147;}i:1148;a:1:{i:0;i:1149;}i:1150;a:1:{i:0;i:1151;}i:1152;a:1:{i:0;i:1153;}i:1162;a:1:{i:0;i:1163;}i:1164;a:1:{i:0;i:1165;}i:1166;a:1:{i:0;i:1167;}i:1168;a:1:{i:0;i:1169;}i:1170;a:1:{i:0;i:1171;}i:1172;a:1:{i:0;i:1173;}i:1174;a:1:{i:0;i:1175;}i:1176;a:1:{i:0;i:1177;}i:1178;a:1:{i:0;i:1179;}i:1180;a:1:{i:0;i:1181;}i:1182;a:1:{i:0;i:1183;}i:1184;a:1:{i:0;i:1185;}i:1186;a:1:{i:0;i:1187;}i:1188;a:1:{i:0;i:1189;}i:1190;a:1:{i:0;i:1191;}i:1192;a:1:{i:0;i:1193;}i:1194;a:1:{i:0;i:1195;}i:1196;a:1:{i:0;i:1197;}i:1198;a:1:{i:0;i:1199;}i:1200;a:1:{i:0;i:1201;}i:1202;a:1:{i:0;i:1203;}i:1204;a:1:{i:0;i:1205;}i:1206;a:1:{i:0;i:1207;}i:1208;a:1:{i:0;i:1209;}i:1210;a:1:{i:0;i:1211;}i:1212;a:1:{i:0;i:1213;}i:1214;a:1:{i:0;i:1215;}i:1217;a:1:{i:0;i:1218;}i:1219;a:1:{i:0;i:1220;}i:1221;a:1:{i:0;i:1222;}i:1223;a:1:{i:0;i:1224;}i:1225;a:1:{i:0;i:1226;}i:1227;a:1:{i:0;i:1228;}i:1229;a:1:{i:0;i:1230;}i:1232;a:1:{i:0;i:1233;}i:1234;a:1:{i:0;i:1235;}i:1236;a:1:{i:0;i:1237;}i:1238;a:1:{i:0;i:1239;}i:1240;a:1:{i:0;i:1241;}i:1242;a:1:{i:0;i:1243;}i:1244;a:1:{i:0;i:1245;}i:1246;a:1:{i:0;i:1247;}i:1248;a:1:{i:0;i:1249;}i:1250;a:1:{i:0;i:1251;}i:1252;a:1:{i:0;i:1253;}i:1254;a:1:{i:0;i:1255;}i:1256;a:1:{i:0;i:1257;}i:1258;a:1:{i:0;i:1259;}i:1260;a:1:{i:0;i:1261;}i:1262;a:1:{i:0;i:1263;}i:1264;a:1:{i:0;i:1265;}i:1266;a:1:{i:0;i:1267;}i:1268;a:1:{i:0;i:1269;}i:1272;a:1:{i:0;i:1273;}i:1280;a:1:{i:0;i:1281;}i:1282;a:1:{i:0;i:1283;}i:1284;a:1:{i:0;i:1285;}i:1286;a:1:{i:0;i:1287;}i:1288;a:1:{i:0;i:1289;}i:1290;a:1:{i:0;i:1291;}i:1292;a:1:{i:0;i:1293;}i:1294;a:1:{i:0;i:1295;}i:1329;a:1:{i:0;i:1377;}i:1330;a:1:{i:0;i:1378;}i:1331;a:1:{i:0;i:1379;}i:1332;a:1:{i:0;i:1380;}i:1333;a:1:{i:0;i:1381;}i:1334;a:1:{i:0;i:1382;}i:1335;a:1:{i:0;i:1383;}i:1336;a:1:{i:0;i:1384;}i:1337;a:1:{i:0;i:1385;}i:1338;a:1:{i:0;i:1386;}i:1339;a:1:{i:0;i:1387;}i:1340;a:1:{i:0;i:1388;}i:1341;a:1:{i:0;i:1389;}i:1342;a:1:{i:0;i:1390;}i:1343;a:1:{i:0;i:1391;}i:1344;a:1:{i:0;i:1392;}i:1345;a:1:{i:0;i:1393;}i:1346;a:1:{i:0;i:1394;}i:1347;a:1:{i:0;i:1395;}i:1348;a:1:{i:0;i:1396;}i:1349;a:1:{i:0;i:1397;}i:1350;a:1:{i:0;i:1398;}i:1351;a:1:{i:0;i:1399;}i:1352;a:1:{i:0;i:1400;}i:1353;a:1:{i:0;i:1401;}i:1354;a:1:{i:0;i:1402;}i:1355;a:1:{i:0;i:1403;}i:1356;a:1:{i:0;i:1404;}i:1357;a:1:{i:0;i:1405;}i:1358;a:1:{i:0;i:1406;}i:1359;a:1:{i:0;i:1407;}i:1360;a:1:{i:0;i:1408;}i:1361;a:1:{i:0;i:1409;}i:1362;a:1:{i:0;i:1410;}i:1363;a:1:{i:0;i:1411;}i:1364;a:1:{i:0;i:1412;}i:1365;a:1:{i:0;i:1413;}i:1366;a:1:{i:0;i:1414;}i:1415;a:2:{i:0;i:1381;i:1;i:1410;}i:7680;a:1:{i:0;i:7681;}i:7682;a:1:{i:0;i:7683;}i:7684;a:1:{i:0;i:7685;}i:7686;a:1:{i:0;i:7687;}i:7688;a:1:{i:0;i:7689;}i:7690;a:1:{i:0;i:7691;}i:7692;a:1:{i:0;i:7693;}i:7694;a:1:{i:0;i:7695;}i:7696;a:1:{i:0;i:7697;}i:7698;a:1:{i:0;i:7699;}i:7700;a:1:{i:0;i:7701;}i:7702;a:1:{i:0;i:7703;}i:7704;a:1:{i:0;i:7705;}i:7706;a:1:{i:0;i:7707;}i:7708;a:1:{i:0;i:7709;}i:7710;a:1:{i:0;i:7711;}i:7712;a:1:{i:0;i:7713;}i:7714;a:1:{i:0;i:7715;}i:7716;a:1:{i:0;i:7717;}i:7718;a:1:{i:0;i:7719;}i:7720;a:1:{i:0;i:7721;}i:7722;a:1:{i:0;i:7723;}i:7724;a:1:{i:0;i:7725;}i:7726;a:1:{i:0;i:7727;}i:7728;a:1:{i:0;i:7729;}i:7730;a:1:{i:0;i:7731;}i:7732;a:1:{i:0;i:7733;}i:7734;a:1:{i:0;i:7735;}i:7736;a:1:{i:0;i:7737;}i:7738;a:1:{i:0;i:7739;}i:7740;a:1:{i:0;i:7741;}i:7742;a:1:{i:0;i:7743;}i:7744;a:1:{i:0;i:7745;}i:7746;a:1:{i:0;i:7747;}i:7748;a:1:{i:0;i:7749;}i:7750;a:1:{i:0;i:7751;}i:7752;a:1:{i:0;i:7753;}i:7754;a:1:{i:0;i:7755;}i:7756;a:1:{i:0;i:7757;}i:7758;a:1:{i:0;i:7759;}i:7760;a:1:{i:0;i:7761;}i:7762;a:1:{i:0;i:7763;}i:7764;a:1:{i:0;i:7765;}i:7766;a:1:{i:0;i:7767;}i:7768;a:1:{i:0;i:7769;}i:7770;a:1:{i:0;i:7771;}i:7772;a:1:{i:0;i:7773;}i:7774;a:1:{i:0;i:7775;}i:7776;a:1:{i:0;i:7777;}i:7778;a:1:{i:0;i:7779;}i:7780;a:1:{i:0;i:7781;}i:7782;a:1:{i:0;i:7783;}i:7784;a:1:{i:0;i:7785;}i:7786;a:1:{i:0;i:7787;}i:7788;a:1:{i:0;i:7789;}i:7790;a:1:{i:0;i:7791;}i:7792;a:1:{i:0;i:7793;}i:7794;a:1:{i:0;i:7795;}i:7796;a:1:{i:0;i:7797;}i:7798;a:1:{i:0;i:7799;}i:7800;a:1:{i:0;i:7801;}i:7802;a:1:{i:0;i:7803;}i:7804;a:1:{i:0;i:7805;}i:7806;a:1:{i:0;i:7807;}i:7808;a:1:{i:0;i:7809;}i:7810;a:1:{i:0;i:7811;}i:7812;a:1:{i:0;i:7813;}i:7814;a:1:{i:0;i:7815;}i:7816;a:1:{i:0;i:7817;}i:7818;a:1:{i:0;i:7819;}i:7820;a:1:{i:0;i:7821;}i:7822;a:1:{i:0;i:7823;}i:7824;a:1:{i:0;i:7825;}i:7826;a:1:{i:0;i:7827;}i:7828;a:1:{i:0;i:7829;}i:7830;a:2:{i:0;i:104;i:1;i:817;}i:7831;a:2:{i:0;i:116;i:1;i:776;}i:7832;a:2:{i:0;i:119;i:1;i:778;}i:7833;a:2:{i:0;i:121;i:1;i:778;}i:7834;a:2:{i:0;i:97;i:1;i:702;}i:7835;a:1:{i:0;i:7777;}i:7840;a:1:{i:0;i:7841;}i:7842;a:1:{i:0;i:7843;}i:7844;a:1:{i:0;i:7845;}i:7846;a:1:{i:0;i:7847;}i:7848;a:1:{i:0;i:7849;}i:7850;a:1:{i:0;i:7851;}i:7852;a:1:{i:0;i:7853;}i:7854;a:1:{i:0;i:7855;}i:7856;a:1:{i:0;i:7857;}i:7858;a:1:{i:0;i:7859;}i:7860;a:1:{i:0;i:7861;}i:7862;a:1:{i:0;i:7863;}i:7864;a:1:{i:0;i:7865;}i:7866;a:1:{i:0;i:7867;}i:7868;a:1:{i:0;i:7869;}i:7870;a:1:{i:0;i:7871;}i:7872;a:1:{i:0;i:7873;}i:7874;a:1:{i:0;i:7875;}i:7876;a:1:{i:0;i:7877;}i:7878;a:1:{i:0;i:7879;}i:7880;a:1:{i:0;i:7881;}i:7882;a:1:{i:0;i:7883;}i:7884;a:1:{i:0;i:7885;}i:7886;a:1:{i:0;i:7887;}i:7888;a:1:{i:0;i:7889;}i:7890;a:1:{i:0;i:7891;}i:7892;a:1:{i:0;i:7893;}i:7894;a:1:{i:0;i:7895;}i:7896;a:1:{i:0;i:7897;}i:7898;a:1:{i:0;i:7899;}i:7900;a:1:{i:0;i:7901;}i:7902;a:1:{i:0;i:7903;}i:7904;a:1:{i:0;i:7905;}i:7906;a:1:{i:0;i:7907;}i:7908;a:1:{i:0;i:7909;}i:7910;a:1:{i:0;i:7911;}i:7912;a:1:{i:0;i:7913;}i:7914;a:1:{i:0;i:7915;}i:7916;a:1:{i:0;i:7917;}i:7918;a:1:{i:0;i:7919;}i:7920;a:1:{i:0;i:7921;}i:7922;a:1:{i:0;i:7923;}i:7924;a:1:{i:0;i:7925;}i:7926;a:1:{i:0;i:7927;}i:7928;a:1:{i:0;i:7929;}i:7944;a:1:{i:0;i:7936;}i:7945;a:1:{i:0;i:7937;}i:7946;a:1:{i:0;i:7938;}i:7947;a:1:{i:0;i:7939;}i:7948;a:1:{i:0;i:7940;}i:7949;a:1:{i:0;i:7941;}i:7950;a:1:{i:0;i:7942;}i:7951;a:1:{i:0;i:7943;}i:7960;a:1:{i:0;i:7952;}i:7961;a:1:{i:0;i:7953;}i:7962;a:1:{i:0;i:7954;}i:7963;a:1:{i:0;i:7955;}i:7964;a:1:{i:0;i:7956;}i:7965;a:1:{i:0;i:7957;}i:7976;a:1:{i:0;i:7968;}i:7977;a:1:{i:0;i:7969;}i:7978;a:1:{i:0;i:7970;}i:7979;a:1:{i:0;i:7971;}i:7980;a:1:{i:0;i:7972;}i:7981;a:1:{i:0;i:7973;}i:7982;a:1:{i:0;i:7974;}i:7983;a:1:{i:0;i:7975;}i:7992;a:1:{i:0;i:7984;}i:7993;a:1:{i:0;i:7985;}i:7994;a:1:{i:0;i:7986;}i:7995;a:1:{i:0;i:7987;}i:7996;a:1:{i:0;i:7988;}i:7997;a:1:{i:0;i:7989;}i:7998;a:1:{i:0;i:7990;}i:7999;a:1:{i:0;i:7991;}i:8008;a:1:{i:0;i:8000;}i:8009;a:1:{i:0;i:8001;}i:8010;a:1:{i:0;i:8002;}i:8011;a:1:{i:0;i:8003;}i:8012;a:1:{i:0;i:8004;}i:8013;a:1:{i:0;i:8005;}i:8016;a:2:{i:0;i:965;i:1;i:787;}i:8018;a:3:{i:0;i:965;i:1;i:787;i:2;i:768;}i:8020;a:3:{i:0;i:965;i:1;i:787;i:2;i:769;}i:8022;a:3:{i:0;i:965;i:1;i:787;i:2;i:834;}i:8025;a:1:{i:0;i:8017;}i:8027;a:1:{i:0;i:8019;}i:8029;a:1:{i:0;i:8021;}i:8031;a:1:{i:0;i:8023;}i:8040;a:1:{i:0;i:8032;}i:8041;a:1:{i:0;i:8033;}i:8042;a:1:{i:0;i:8034;}i:8043;a:1:{i:0;i:8035;}i:8044;a:1:{i:0;i:8036;}i:8045;a:1:{i:0;i:8037;}i:8046;a:1:{i:0;i:8038;}i:8047;a:1:{i:0;i:8039;}i:8064;a:2:{i:0;i:7936;i:1;i:953;}i:8065;a:2:{i:0;i:7937;i:1;i:953;}i:8066;a:2:{i:0;i:7938;i:1;i:953;}i:8067;a:2:{i:0;i:7939;i:1;i:953;}i:8068;a:2:{i:0;i:7940;i:1;i:953;}i:8069;a:2:{i:0;i:7941;i:1;i:953;}i:8070;a:2:{i:0;i:7942;i:1;i:953;}i:8071;a:2:{i:0;i:7943;i:1;i:953;}i:8072;a:2:{i:0;i:7936;i:1;i:953;}i:8073;a:2:{i:0;i:7937;i:1;i:953;}i:8074;a:2:{i:0;i:7938;i:1;i:953;}i:8075;a:2:{i:0;i:7939;i:1;i:953;}i:8076;a:2:{i:0;i:7940;i:1;i:953;}i:8077;a:2:{i:0;i:7941;i:1;i:953;}i:8078;a:2:{i:0;i:7942;i:1;i:953;}i:8079;a:2:{i:0;i:7943;i:1;i:953;}i:8080;a:2:{i:0;i:7968;i:1;i:953;}i:8081;a:2:{i:0;i:7969;i:1;i:953;}i:8082;a:2:{i:0;i:7970;i:1;i:953;}i:8083;a:2:{i:0;i:7971;i:1;i:953;}i:8084;a:2:{i:0;i:7972;i:1;i:953;}i:8085;a:2:{i:0;i:7973;i:1;i:953;}i:8086;a:2:{i:0;i:7974;i:1;i:953;}i:8087;a:2:{i:0;i:7975;i:1;i:953;}i:8088;a:2:{i:0;i:7968;i:1;i:953;}i:8089;a:2:{i:0;i:7969;i:1;i:953;}i:8090;a:2:{i:0;i:7970;i:1;i:953;}i:8091;a:2:{i:0;i:7971;i:1;i:953;}i:8092;a:2:{i:0;i:7972;i:1;i:953;}i:8093;a:2:{i:0;i:7973;i:1;i:953;}i:8094;a:2:{i:0;i:7974;i:1;i:953;}i:8095;a:2:{i:0;i:7975;i:1;i:953;}i:8096;a:2:{i:0;i:8032;i:1;i:953;}i:8097;a:2:{i:0;i:8033;i:1;i:953;}i:8098;a:2:{i:0;i:8034;i:1;i:953;}i:8099;a:2:{i:0;i:8035;i:1;i:953;}i:8100;a:2:{i:0;i:8036;i:1;i:953;}i:8101;a:2:{i:0;i:8037;i:1;i:953;}i:8102;a:2:{i:0;i:8038;i:1;i:953;}i:8103;a:2:{i:0;i:8039;i:1;i:953;}i:8104;a:2:{i:0;i:8032;i:1;i:953;}i:8105;a:2:{i:0;i:8033;i:1;i:953;}i:8106;a:2:{i:0;i:8034;i:1;i:953;}i:8107;a:2:{i:0;i:8035;i:1;i:953;}i:8108;a:2:{i:0;i:8036;i:1;i:953;}i:8109;a:2:{i:0;i:8037;i:1;i:953;}i:8110;a:2:{i:0;i:8038;i:1;i:953;}i:8111;a:2:{i:0;i:8039;i:1;i:953;}i:8114;a:2:{i:0;i:8048;i:1;i:953;}i:8115;a:2:{i:0;i:945;i:1;i:953;}i:8116;a:2:{i:0;i:940;i:1;i:953;}i:8118;a:2:{i:0;i:945;i:1;i:834;}i:8119;a:3:{i:0;i:945;i:1;i:834;i:2;i:953;}i:8120;a:1:{i:0;i:8112;}i:8121;a:1:{i:0;i:8113;}i:8122;a:1:{i:0;i:8048;}i:8123;a:1:{i:0;i:8049;}i:8124;a:2:{i:0;i:945;i:1;i:953;}i:8126;a:1:{i:0;i:953;}i:8130;a:2:{i:0;i:8052;i:1;i:953;}i:8131;a:2:{i:0;i:951;i:1;i:953;}i:8132;a:2:{i:0;i:942;i:1;i:953;}i:8134;a:2:{i:0;i:951;i:1;i:834;}i:8135;a:3:{i:0;i:951;i:1;i:834;i:2;i:953;}i:8136;a:1:{i:0;i:8050;}i:8137;a:1:{i:0;i:8051;}i:8138;a:1:{i:0;i:8052;}i:8139;a:1:{i:0;i:8053;}i:8140;a:2:{i:0;i:951;i:1;i:953;}i:8146;a:3:{i:0;i:953;i:1;i:776;i:2;i:768;}i:8147;a:3:{i:0;i:953;i:1;i:776;i:2;i:769;}i:8150;a:2:{i:0;i:953;i:1;i:834;}i:8151;a:3:{i:0;i:953;i:1;i:776;i:2;i:834;}i:8152;a:1:{i:0;i:8144;}i:8153;a:1:{i:0;i:8145;}i:8154;a:1:{i:0;i:8054;}i:8155;a:1:{i:0;i:8055;}i:8162;a:3:{i:0;i:965;i:1;i:776;i:2;i:768;}i:8163;a:3:{i:0;i:965;i:1;i:776;i:2;i:769;}i:8164;a:2:{i:0;i:961;i:1;i:787;}i:8166;a:2:{i:0;i:965;i:1;i:834;}i:8167;a:3:{i:0;i:965;i:1;i:776;i:2;i:834;}i:8168;a:1:{i:0;i:8160;}i:8169;a:1:{i:0;i:8161;}i:8170;a:1:{i:0;i:8058;}i:8171;a:1:{i:0;i:8059;}i:8172;a:1:{i:0;i:8165;}i:8178;a:2:{i:0;i:8060;i:1;i:953;}i:8179;a:2:{i:0;i:969;i:1;i:953;}i:8180;a:2:{i:0;i:974;i:1;i:953;}i:8182;a:2:{i:0;i:969;i:1;i:834;}i:8183;a:3:{i:0;i:969;i:1;i:834;i:2;i:953;}i:8184;a:1:{i:0;i:8056;}i:8185;a:1:{i:0;i:8057;}i:8186;a:1:{i:0;i:8060;}i:8187;a:1:{i:0;i:8061;}i:8188;a:2:{i:0;i:969;i:1;i:953;}i:8360;a:2:{i:0;i:114;i:1;i:115;}i:8450;a:1:{i:0;i:99;}i:8451;a:2:{i:0;i:176;i:1;i:99;}i:8455;a:1:{i:0;i:603;}i:8457;a:2:{i:0;i:176;i:1;i:102;}i:8459;a:1:{i:0;i:104;}i:8460;a:1:{i:0;i:104;}i:8461;a:1:{i:0;i:104;}i:8464;a:1:{i:0;i:105;}i:8465;a:1:{i:0;i:105;}i:8466;a:1:{i:0;i:108;}i:8469;a:1:{i:0;i:110;}i:8470;a:2:{i:0;i:110;i:1;i:111;}i:8473;a:1:{i:0;i:112;}i:8474;a:1:{i:0;i:113;}i:8475;a:1:{i:0;i:114;}i:8476;a:1:{i:0;i:114;}i:8477;a:1:{i:0;i:114;}i:8480;a:2:{i:0;i:115;i:1;i:109;}i:8481;a:3:{i:0;i:116;i:1;i:101;i:2;i:108;}i:8482;a:2:{i:0;i:116;i:1;i:109;}i:8484;a:1:{i:0;i:122;}i:8486;a:1:{i:0;i:969;}i:8488;a:1:{i:0;i:122;}i:8490;a:1:{i:0;i:107;}i:8491;a:1:{i:0;i:229;}i:8492;a:1:{i:0;i:98;}i:8493;a:1:{i:0;i:99;}i:8496;a:1:{i:0;i:101;}i:8497;a:1:{i:0;i:102;}i:8499;a:1:{i:0;i:109;}i:8510;a:1:{i:0;i:947;}i:8511;a:1:{i:0;i:960;}i:8517;a:1:{i:0;i:100;}i:8544;a:1:{i:0;i:8560;}i:8545;a:1:{i:0;i:8561;}i:8546;a:1:{i:0;i:8562;}i:8547;a:1:{i:0;i:8563;}i:8548;a:1:{i:0;i:8564;}i:8549;a:1:{i:0;i:8565;}i:8550;a:1:{i:0;i:8566;}i:8551;a:1:{i:0;i:8567;}i:8552;a:1:{i:0;i:8568;}i:8553;a:1:{i:0;i:8569;}i:8554;a:1:{i:0;i:8570;}i:8555;a:1:{i:0;i:8571;}i:8556;a:1:{i:0;i:8572;}i:8557;a:1:{i:0;i:8573;}i:8558;a:1:{i:0;i:8574;}i:8559;a:1:{i:0;i:8575;}i:9398;a:1:{i:0;i:9424;}i:9399;a:1:{i:0;i:9425;}i:9400;a:1:{i:0;i:9426;}i:9401;a:1:{i:0;i:9427;}i:9402;a:1:{i:0;i:9428;}i:9403;a:1:{i:0;i:9429;}i:9404;a:1:{i:0;i:9430;}i:9405;a:1:{i:0;i:9431;}i:9406;a:1:{i:0;i:9432;}i:9407;a:1:{i:0;i:9433;}i:9408;a:1:{i:0;i:9434;}i:9409;a:1:{i:0;i:9435;}i:9410;a:1:{i:0;i:9436;}i:9411;a:1:{i:0;i:9437;}i:9412;a:1:{i:0;i:9438;}i:9413;a:1:{i:0;i:9439;}i:9414;a:1:{i:0;i:9440;}i:9415;a:1:{i:0;i:9441;}i:9416;a:1:{i:0;i:9442;}i:9417;a:1:{i:0;i:9443;}i:9418;a:1:{i:0;i:9444;}i:9419;a:1:{i:0;i:9445;}i:9420;a:1:{i:0;i:9446;}i:9421;a:1:{i:0;i:9447;}i:9422;a:1:{i:0;i:9448;}i:9423;a:1:{i:0;i:9449;}i:13169;a:3:{i:0;i:104;i:1;i:112;i:2;i:97;}i:13171;a:2:{i:0;i:97;i:1;i:117;}i:13173;a:2:{i:0;i:111;i:1;i:118;}i:13184;a:2:{i:0;i:112;i:1;i:97;}i:13185;a:2:{i:0;i:110;i:1;i:97;}i:13186;a:2:{i:0;i:956;i:1;i:97;}i:13187;a:2:{i:0;i:109;i:1;i:97;}i:13188;a:2:{i:0;i:107;i:1;i:97;}i:13189;a:2:{i:0;i:107;i:1;i:98;}i:13190;a:2:{i:0;i:109;i:1;i:98;}i:13191;a:2:{i:0;i:103;i:1;i:98;}i:13194;a:2:{i:0;i:112;i:1;i:102;}i:13195;a:2:{i:0;i:110;i:1;i:102;}i:13196;a:2:{i:0;i:956;i:1;i:102;}i:13200;a:2:{i:0;i:104;i:1;i:122;}i:13201;a:3:{i:0;i:107;i:1;i:104;i:2;i:122;}i:13202;a:3:{i:0;i:109;i:1;i:104;i:2;i:122;}i:13203;a:3:{i:0;i:103;i:1;i:104;i:2;i:122;}i:13204;a:3:{i:0;i:116;i:1;i:104;i:2;i:122;}i:13225;a:2:{i:0;i:112;i:1;i:97;}i:13226;a:3:{i:0;i:107;i:1;i:112;i:2;i:97;}i:13227;a:3:{i:0;i:109;i:1;i:112;i:2;i:97;}i:13228;a:3:{i:0;i:103;i:1;i:112;i:2;i:97;}i:13236;a:2:{i:0;i:112;i:1;i:118;}i:13237;a:2:{i:0;i:110;i:1;i:118;}i:13238;a:2:{i:0;i:956;i:1;i:118;}i:13239;a:2:{i:0;i:109;i:1;i:118;}i:13240;a:2:{i:0;i:107;i:1;i:118;}i:13241;a:2:{i:0;i:109;i:1;i:118;}i:13242;a:2:{i:0;i:112;i:1;i:119;}i:13243;a:2:{i:0;i:110;i:1;i:119;}i:13244;a:2:{i:0;i:956;i:1;i:119;}i:13245;a:2:{i:0;i:109;i:1;i:119;}i:13246;a:2:{i:0;i:107;i:1;i:119;}i:13247;a:2:{i:0;i:109;i:1;i:119;}i:13248;a:2:{i:0;i:107;i:1;i:969;}i:13249;a:2:{i:0;i:109;i:1;i:969;}i:13251;a:2:{i:0;i:98;i:1;i:113;}i:13254;a:4:{i:0;i:99;i:1;i:8725;i:2;i:107;i:3;i:103;}i:13255;a:3:{i:0;i:99;i:1;i:111;i:2;i:46;}i:13256;a:2:{i:0;i:100;i:1;i:98;}i:13257;a:2:{i:0;i:103;i:1;i:121;}i:13259;a:2:{i:0;i:104;i:1;i:112;}i:13261;a:2:{i:0;i:107;i:1;i:107;}i:13262;a:2:{i:0;i:107;i:1;i:109;}i:13271;a:2:{i:0;i:112;i:1;i:104;}i:13273;a:3:{i:0;i:112;i:1;i:112;i:2;i:109;}i:13274;a:2:{i:0;i:112;i:1;i:114;}i:13276;a:2:{i:0;i:115;i:1;i:118;}i:13277;a:2:{i:0;i:119;i:1;i:98;}i:64256;a:2:{i:0;i:102;i:1;i:102;}i:64257;a:2:{i:0;i:102;i:1;i:105;}i:64258;a:2:{i:0;i:102;i:1;i:108;}i:64259;a:3:{i:0;i:102;i:1;i:102;i:2;i:105;}i:64260;a:3:{i:0;i:102;i:1;i:102;i:2;i:108;}i:64261;a:2:{i:0;i:115;i:1;i:116;}i:64262;a:2:{i:0;i:115;i:1;i:116;}i:64275;a:2:{i:0;i:1396;i:1;i:1398;}i:64276;a:2:{i:0;i:1396;i:1;i:1381;}i:64277;a:2:{i:0;i:1396;i:1;i:1387;}i:64278;a:2:{i:0;i:1406;i:1;i:1398;}i:64279;a:2:{i:0;i:1396;i:1;i:1389;}i:65313;a:1:{i:0;i:65345;}i:65314;a:1:{i:0;i:65346;}i:65315;a:1:{i:0;i:65347;}i:65316;a:1:{i:0;i:65348;}i:65317;a:1:{i:0;i:65349;}i:65318;a:1:{i:0;i:65350;}i:65319;a:1:{i:0;i:65351;}i:65320;a:1:{i:0;i:65352;}i:65321;a:1:{i:0;i:65353;}i:65322;a:1:{i:0;i:65354;}i:65323;a:1:{i:0;i:65355;}i:65324;a:1:{i:0;i:65356;}i:65325;a:1:{i:0;i:65357;}i:65326;a:1:{i:0;i:65358;}i:65327;a:1:{i:0;i:65359;}i:65328;a:1:{i:0;i:65360;}i:65329;a:1:{i:0;i:65361;}i:65330;a:1:{i:0;i:65362;}i:65331;a:1:{i:0;i:65363;}i:65332;a:1:{i:0;i:65364;}i:65333;a:1:{i:0;i:65365;}i:65334;a:1:{i:0;i:65366;}i:65335;a:1:{i:0;i:65367;}i:65336;a:1:{i:0;i:65368;}i:65337;a:1:{i:0;i:65369;}i:65338;a:1:{i:0;i:65370;}i:66560;a:1:{i:0;i:66600;}i:66561;a:1:{i:0;i:66601;}i:66562;a:1:{i:0;i:66602;}i:66563;a:1:{i:0;i:66603;}i:66564;a:1:{i:0;i:66604;}i:66565;a:1:{i:0;i:66605;}i:66566;a:1:{i:0;i:66606;}i:66567;a:1:{i:0;i:66607;}i:66568;a:1:{i:0;i:66608;}i:66569;a:1:{i:0;i:66609;}i:66570;a:1:{i:0;i:66610;}i:66571;a:1:{i:0;i:66611;}i:66572;a:1:{i:0;i:66612;}i:66573;a:1:{i:0;i:66613;}i:66574;a:1:{i:0;i:66614;}i:66575;a:1:{i:0;i:66615;}i:66576;a:1:{i:0;i:66616;}i:66577;a:1:{i:0;i:66617;}i:66578;a:1:{i:0;i:66618;}i:66579;a:1:{i:0;i:66619;}i:66580;a:1:{i:0;i:66620;}i:66581;a:1:{i:0;i:66621;}i:66582;a:1:{i:0;i:66622;}i:66583;a:1:{i:0;i:66623;}i:66584;a:1:{i:0;i:66624;}i:66585;a:1:{i:0;i:66625;}i:66586;a:1:{i:0;i:66626;}i:66587;a:1:{i:0;i:66627;}i:66588;a:1:{i:0;i:66628;}i:66589;a:1:{i:0;i:66629;}i:66590;a:1:{i:0;i:66630;}i:66591;a:1:{i:0;i:66631;}i:66592;a:1:{i:0;i:66632;}i:66593;a:1:{i:0;i:66633;}i:66594;a:1:{i:0;i:66634;}i:66595;a:1:{i:0;i:66635;}i:66596;a:1:{i:0;i:66636;}i:66597;a:1:{i:0;i:66637;}i:119808;a:1:{i:0;i:97;}i:119809;a:1:{i:0;i:98;}i:119810;a:1:{i:0;i:99;}i:119811;a:1:{i:0;i:100;}i:119812;a:1:{i:0;i:101;}i:119813;a:1:{i:0;i:102;}i:119814;a:1:{i:0;i:103;}i:119815;a:1:{i:0;i:104;}i:119816;a:1:{i:0;i:105;}i:119817;a:1:{i:0;i:106;}i:119818;a:1:{i:0;i:107;}i:119819;a:1:{i:0;i:108;}i:119820;a:1:{i:0;i:109;}i:119821;a:1:{i:0;i:110;}i:119822;a:1:{i:0;i:111;}i:119823;a:1:{i:0;i:112;}i:119824;a:1:{i:0;i:113;}i:119825;a:1:{i:0;i:114;}i:119826;a:1:{i:0;i:115;}i:119827;a:1:{i:0;i:116;}i:119828;a:1:{i:0;i:117;}i:119829;a:1:{i:0;i:118;}i:119830;a:1:{i:0;i:119;}i:119831;a:1:{i:0;i:120;}i:119832;a:1:{i:0;i:121;}i:119833;a:1:{i:0;i:122;}i:119860;a:1:{i:0;i:97;}i:119861;a:1:{i:0;i:98;}i:119862;a:1:{i:0;i:99;}i:119863;a:1:{i:0;i:100;}i:119864;a:1:{i:0;i:101;}i:119865;a:1:{i:0;i:102;}i:119866;a:1:{i:0;i:103;}i:119867;a:1:{i:0;i:104;}i:119868;a:1:{i:0;i:105;}i:119869;a:1:{i:0;i:106;}i:119870;a:1:{i:0;i:107;}i:119871;a:1:{i:0;i:108;}i:119872;a:1:{i:0;i:109;}i:119873;a:1:{i:0;i:110;}i:119874;a:1:{i:0;i:111;}i:119875;a:1:{i:0;i:112;}i:119876;a:1:{i:0;i:113;}i:119877;a:1:{i:0;i:114;}i:119878;a:1:{i:0;i:115;}i:119879;a:1:{i:0;i:116;}i:119880;a:1:{i:0;i:117;}i:119881;a:1:{i:0;i:118;}i:119882;a:1:{i:0;i:119;}i:119883;a:1:{i:0;i:120;}i:119884;a:1:{i:0;i:121;}i:119885;a:1:{i:0;i:122;}i:119912;a:1:{i:0;i:97;}i:119913;a:1:{i:0;i:98;}i:119914;a:1:{i:0;i:99;}i:119915;a:1:{i:0;i:100;}i:119916;a:1:{i:0;i:101;}i:119917;a:1:{i:0;i:102;}i:119918;a:1:{i:0;i:103;}i:119919;a:1:{i:0;i:104;}i:119920;a:1:{i:0;i:105;}i:119921;a:1:{i:0;i:106;}i:119922;a:1:{i:0;i:107;}i:119923;a:1:{i:0;i:108;}i:119924;a:1:{i:0;i:109;}i:119925;a:1:{i:0;i:110;}i:119926;a:1:{i:0;i:111;}i:119927;a:1:{i:0;i:112;}i:119928;a:1:{i:0;i:113;}i:119929;a:1:{i:0;i:114;}i:119930;a:1:{i:0;i:115;}i:119931;a:1:{i:0;i:116;}i:119932;a:1:{i:0;i:117;}i:119933;a:1:{i:0;i:118;}i:119934;a:1:{i:0;i:119;}i:119935;a:1:{i:0;i:120;}i:119936;a:1:{i:0;i:121;}i:119937;a:1:{i:0;i:122;}i:119964;a:1:{i:0;i:97;}i:119966;a:1:{i:0;i:99;}i:119967;a:1:{i:0;i:100;}i:119970;a:1:{i:0;i:103;}i:119973;a:1:{i:0;i:106;}i:119974;a:1:{i:0;i:107;}i:119977;a:1:{i:0;i:110;}i:119978;a:1:{i:0;i:111;}i:119979;a:1:{i:0;i:112;}i:119980;a:1:{i:0;i:113;}i:119982;a:1:{i:0;i:115;}i:119983;a:1:{i:0;i:116;}i:119984;a:1:{i:0;i:117;}i:119985;a:1:{i:0;i:118;}i:119986;a:1:{i:0;i:119;}i:119987;a:1:{i:0;i:120;}i:119988;a:1:{i:0;i:121;}i:119989;a:1:{i:0;i:122;}i:120016;a:1:{i:0;i:97;}i:120017;a:1:{i:0;i:98;}i:120018;a:1:{i:0;i:99;}i:120019;a:1:{i:0;i:100;}i:120020;a:1:{i:0;i:101;}i:120021;a:1:{i:0;i:102;}i:120022;a:1:{i:0;i:103;}i:120023;a:1:{i:0;i:104;}i:120024;a:1:{i:0;i:105;}i:120025;a:1:{i:0;i:106;}i:120026;a:1:{i:0;i:107;}i:120027;a:1:{i:0;i:108;}i:120028;a:1:{i:0;i:109;}i:120029;a:1:{i:0;i:110;}i:120030;a:1:{i:0;i:111;}i:120031;a:1:{i:0;i:112;}i:120032;a:1:{i:0;i:113;}i:120033;a:1:{i:0;i:114;}i:120034;a:1:{i:0;i:115;}i:120035;a:1:{i:0;i:116;}i:120036;a:1:{i:0;i:117;}i:120037;a:1:{i:0;i:118;}i:120038;a:1:{i:0;i:119;}i:120039;a:1:{i:0;i:120;}i:120040;a:1:{i:0;i:121;}i:120041;a:1:{i:0;i:122;}i:120068;a:1:{i:0;i:97;}i:120069;a:1:{i:0;i:98;}i:120071;a:1:{i:0;i:100;}i:120072;a:1:{i:0;i:101;}i:120073;a:1:{i:0;i:102;}i:120074;a:1:{i:0;i:103;}i:120077;a:1:{i:0;i:106;}i:120078;a:1:{i:0;i:107;}i:120079;a:1:{i:0;i:108;}i:120080;a:1:{i:0;i:109;}i:120081;a:1:{i:0;i:110;}i:120082;a:1:{i:0;i:111;}i:120083;a:1:{i:0;i:112;}i:120084;a:1:{i:0;i:113;}i:120086;a:1:{i:0;i:115;}i:120087;a:1:{i:0;i:116;}i:120088;a:1:{i:0;i:117;}i:120089;a:1:{i:0;i:118;}i:120090;a:1:{i:0;i:119;}i:120091;a:1:{i:0;i:120;}i:120092;a:1:{i:0;i:121;}i:120120;a:1:{i:0;i:97;}i:120121;a:1:{i:0;i:98;}i:120123;a:1:{i:0;i:100;}i:120124;a:1:{i:0;i:101;}i:120125;a:1:{i:0;i:102;}i:120126;a:1:{i:0;i:103;}i:120128;a:1:{i:0;i:105;}i:120129;a:1:{i:0;i:106;}i:120130;a:1:{i:0;i:107;}i:120131;a:1:{i:0;i:108;}i:120132;a:1:{i:0;i:109;}i:120134;a:1:{i:0;i:111;}i:120138;a:1:{i:0;i:115;}i:120139;a:1:{i:0;i:116;}i:120140;a:1:{i:0;i:117;}i:120141;a:1:{i:0;i:118;}i:120142;a:1:{i:0;i:119;}i:120143;a:1:{i:0;i:120;}i:120144;a:1:{i:0;i:121;}i:120172;a:1:{i:0;i:97;}i:120173;a:1:{i:0;i:98;}i:120174;a:1:{i:0;i:99;}i:120175;a:1:{i:0;i:100;}i:120176;a:1:{i:0;i:101;}i:120177;a:1:{i:0;i:102;}i:120178;a:1:{i:0;i:103;}i:120179;a:1:{i:0;i:104;}i:120180;a:1:{i:0;i:105;}i:120181;a:1:{i:0;i:106;}i:120182;a:1:{i:0;i:107;}i:120183;a:1:{i:0;i:108;}i:120184;a:1:{i:0;i:109;}i:120185;a:1:{i:0;i:110;}i:120186;a:1:{i:0;i:111;}i:120187;a:1:{i:0;i:112;}i:120188;a:1:{i:0;i:113;}i:120189;a:1:{i:0;i:114;}i:120190;a:1:{i:0;i:115;}i:120191;a:1:{i:0;i:116;}i:120192;a:1:{i:0;i:117;}i:120193;a:1:{i:0;i:118;}i:120194;a:1:{i:0;i:119;}i:120195;a:1:{i:0;i:120;}i:120196;a:1:{i:0;i:121;}i:120197;a:1:{i:0;i:122;}i:120224;a:1:{i:0;i:97;}i:120225;a:1:{i:0;i:98;}i:120226;a:1:{i:0;i:99;}i:120227;a:1:{i:0;i:100;}i:120228;a:1:{i:0;i:101;}i:120229;a:1:{i:0;i:102;}i:120230;a:1:{i:0;i:103;}i:120231;a:1:{i:0;i:104;}i:120232;a:1:{i:0;i:105;}i:120233;a:1:{i:0;i:106;}i:120234;a:1:{i:0;i:107;}i:120235;a:1:{i:0;i:108;}i:120236;a:1:{i:0;i:109;}i:120237;a:1:{i:0;i:110;}i:120238;a:1:{i:0;i:111;}i:120239;a:1:{i:0;i:112;}i:120240;a:1:{i:0;i:113;}i:120241;a:1:{i:0;i:114;}i:120242;a:1:{i:0;i:115;}i:120243;a:1:{i:0;i:116;}i:120244;a:1:{i:0;i:117;}i:120245;a:1:{i:0;i:118;}i:120246;a:1:{i:0;i:119;}i:120247;a:1:{i:0;i:120;}i:120248;a:1:{i:0;i:121;}i:120249;a:1:{i:0;i:122;}i:120276;a:1:{i:0;i:97;}i:120277;a:1:{i:0;i:98;}i:120278;a:1:{i:0;i:99;}i:120279;a:1:{i:0;i:100;}i:120280;a:1:{i:0;i:101;}i:120281;a:1:{i:0;i:102;}i:120282;a:1:{i:0;i:103;}i:120283;a:1:{i:0;i:104;}i:120284;a:1:{i:0;i:105;}i:120285;a:1:{i:0;i:106;}i:120286;a:1:{i:0;i:107;}i:120287;a:1:{i:0;i:108;}i:120288;a:1:{i:0;i:109;}i:120289;a:1:{i:0;i:110;}i:120290;a:1:{i:0;i:111;}i:120291;a:1:{i:0;i:112;}i:120292;a:1:{i:0;i:113;}i:120293;a:1:{i:0;i:114;}i:120294;a:1:{i:0;i:115;}i:120295;a:1:{i:0;i:116;}i:120296;a:1:{i:0;i:117;}i:120297;a:1:{i:0;i:118;}i:120298;a:1:{i:0;i:119;}i:120299;a:1:{i:0;i:120;}i:120300;a:1:{i:0;i:121;}i:120301;a:1:{i:0;i:122;}i:120328;a:1:{i:0;i:97;}i:120329;a:1:{i:0;i:98;}i:120330;a:1:{i:0;i:99;}i:120331;a:1:{i:0;i:100;}i:120332;a:1:{i:0;i:101;}i:120333;a:1:{i:0;i:102;}i:120334;a:1:{i:0;i:103;}i:120335;a:1:{i:0;i:104;}i:120336;a:1:{i:0;i:105;}i:120337;a:1:{i:0;i:106;}i:120338;a:1:{i:0;i:107;}i:120339;a:1:{i:0;i:108;}i:120340;a:1:{i:0;i:109;}i:120341;a:1:{i:0;i:110;}i:120342;a:1:{i:0;i:111;}i:120343;a:1:{i:0;i:112;}i:120344;a:1:{i:0;i:113;}i:120345;a:1:{i:0;i:114;}i:120346;a:1:{i:0;i:115;}i:120347;a:1:{i:0;i:116;}i:120348;a:1:{i:0;i:117;}i:120349;a:1:{i:0;i:118;}i:120350;a:1:{i:0;i:119;}i:120351;a:1:{i:0;i:120;}i:120352;a:1:{i:0;i:121;}i:120353;a:1:{i:0;i:122;}i:120380;a:1:{i:0;i:97;}i:120381;a:1:{i:0;i:98;}i:120382;a:1:{i:0;i:99;}i:120383;a:1:{i:0;i:100;}i:120384;a:1:{i:0;i:101;}i:120385;a:1:{i:0;i:102;}i:120386;a:1:{i:0;i:103;}i:120387;a:1:{i:0;i:104;}i:120388;a:1:{i:0;i:105;}i:120389;a:1:{i:0;i:106;}i:120390;a:1:{i:0;i:107;}i:120391;a:1:{i:0;i:108;}i:120392;a:1:{i:0;i:109;}i:120393;a:1:{i:0;i:110;}i:120394;a:1:{i:0;i:111;}i:120395;a:1:{i:0;i:112;}i:120396;a:1:{i:0;i:113;}i:120397;a:1:{i:0;i:114;}i:120398;a:1:{i:0;i:115;}i:120399;a:1:{i:0;i:116;}i:120400;a:1:{i:0;i:117;}i:120401;a:1:{i:0;i:118;}i:120402;a:1:{i:0;i:119;}i:120403;a:1:{i:0;i:120;}i:120404;a:1:{i:0;i:121;}i:120405;a:1:{i:0;i:122;}i:120432;a:1:{i:0;i:97;}i:120433;a:1:{i:0;i:98;}i:120434;a:1:{i:0;i:99;}i:120435;a:1:{i:0;i:100;}i:120436;a:1:{i:0;i:101;}i:120437;a:1:{i:0;i:102;}i:120438;a:1:{i:0;i:103;}i:120439;a:1:{i:0;i:104;}i:120440;a:1:{i:0;i:105;}i:120441;a:1:{i:0;i:106;}i:120442;a:1:{i:0;i:107;}i:120443;a:1:{i:0;i:108;}i:120444;a:1:{i:0;i:109;}i:120445;a:1:{i:0;i:110;}i:120446;a:1:{i:0;i:111;}i:120447;a:1:{i:0;i:112;}i:120448;a:1:{i:0;i:113;}i:120449;a:1:{i:0;i:114;}i:120450;a:1:{i:0;i:115;}i:120451;a:1:{i:0;i:116;}i:120452;a:1:{i:0;i:117;}i:120453;a:1:{i:0;i:118;}i:120454;a:1:{i:0;i:119;}i:120455;a:1:{i:0;i:120;}i:120456;a:1:{i:0;i:121;}i:120457;a:1:{i:0;i:122;}i:120488;a:1:{i:0;i:945;}i:120489;a:1:{i:0;i:946;}i:120490;a:1:{i:0;i:947;}i:120491;a:1:{i:0;i:948;}i:120492;a:1:{i:0;i:949;}i:120493;a:1:{i:0;i:950;}i:120494;a:1:{i:0;i:951;}i:120495;a:1:{i:0;i:952;}i:120496;a:1:{i:0;i:953;}i:120497;a:1:{i:0;i:954;}i:120498;a:1:{i:0;i:955;}i:120499;a:1:{i:0;i:956;}i:120500;a:1:{i:0;i:957;}i:120501;a:1:{i:0;i:958;}i:120502;a:1:{i:0;i:959;}i:120503;a:1:{i:0;i:960;}i:120504;a:1:{i:0;i:961;}i:120505;a:1:{i:0;i:952;}i:120506;a:1:{i:0;i:963;}i:120507;a:1:{i:0;i:964;}i:120508;a:1:{i:0;i:965;}i:120509;a:1:{i:0;i:966;}i:120510;a:1:{i:0;i:967;}i:120511;a:1:{i:0;i:968;}i:120512;a:1:{i:0;i:969;}i:120531;a:1:{i:0;i:963;}i:120546;a:1:{i:0;i:945;}i:120547;a:1:{i:0;i:946;}i:120548;a:1:{i:0;i:947;}i:120549;a:1:{i:0;i:948;}i:120550;a:1:{i:0;i:949;}i:120551;a:1:{i:0;i:950;}i:120552;a:1:{i:0;i:951;}i:120553;a:1:{i:0;i:952;}i:120554;a:1:{i:0;i:953;}i:120555;a:1:{i:0;i:954;}i:120556;a:1:{i:0;i:955;}i:120557;a:1:{i:0;i:956;}i:120558;a:1:{i:0;i:957;}i:120559;a:1:{i:0;i:958;}i:120560;a:1:{i:0;i:959;}i:120561;a:1:{i:0;i:960;}i:120562;a:1:{i:0;i:961;}i:120563;a:1:{i:0;i:952;}i:120564;a:1:{i:0;i:963;}i:120565;a:1:{i:0;i:964;}i:120566;a:1:{i:0;i:965;}i:120567;a:1:{i:0;i:966;}i:120568;a:1:{i:0;i:967;}i:120569;a:1:{i:0;i:968;}i:120570;a:1:{i:0;i:969;}i:120589;a:1:{i:0;i:963;}i:120604;a:1:{i:0;i:945;}i:120605;a:1:{i:0;i:946;}i:120606;a:1:{i:0;i:947;}i:120607;a:1:{i:0;i:948;}i:120608;a:1:{i:0;i:949;}i:120609;a:1:{i:0;i:950;}i:120610;a:1:{i:0;i:951;}i:120611;a:1:{i:0;i:952;}i:120612;a:1:{i:0;i:953;}i:120613;a:1:{i:0;i:954;}i:120614;a:1:{i:0;i:955;}i:120615;a:1:{i:0;i:956;}i:120616;a:1:{i:0;i:957;}i:120617;a:1:{i:0;i:958;}i:120618;a:1:{i:0;i:959;}i:120619;a:1:{i:0;i:960;}i:120620;a:1:{i:0;i:961;}i:120621;a:1:{i:0;i:952;}i:120622;a:1:{i:0;i:963;}i:120623;a:1:{i:0;i:964;}i:120624;a:1:{i:0;i:965;}i:120625;a:1:{i:0;i:966;}i:120626;a:1:{i:0;i:967;}i:120627;a:1:{i:0;i:968;}i:120628;a:1:{i:0;i:969;}i:120647;a:1:{i:0;i:963;}i:120662;a:1:{i:0;i:945;}i:120663;a:1:{i:0;i:946;}i:120664;a:1:{i:0;i:947;}i:120665;a:1:{i:0;i:948;}i:120666;a:1:{i:0;i:949;}i:120667;a:1:{i:0;i:950;}i:120668;a:1:{i:0;i:951;}i:120669;a:1:{i:0;i:952;}i:120670;a:1:{i:0;i:953;}i:120671;a:1:{i:0;i:954;}i:120672;a:1:{i:0;i:955;}i:120673;a:1:{i:0;i:956;}i:120674;a:1:{i:0;i:957;}i:120675;a:1:{i:0;i:958;}i:120676;a:1:{i:0;i:959;}i:120677;a:1:{i:0;i:960;}i:120678;a:1:{i:0;i:961;}i:120679;a:1:{i:0;i:952;}i:120680;a:1:{i:0;i:963;}i:120681;a:1:{i:0;i:964;}i:120682;a:1:{i:0;i:965;}i:120683;a:1:{i:0;i:966;}i:120684;a:1:{i:0;i:967;}i:120685;a:1:{i:0;i:968;}i:120686;a:1:{i:0;i:969;}i:120705;a:1:{i:0;i:963;}i:120720;a:1:{i:0;i:945;}i:120721;a:1:{i:0;i:946;}i:120722;a:1:{i:0;i:947;}i:120723;a:1:{i:0;i:948;}i:120724;a:1:{i:0;i:949;}i:120725;a:1:{i:0;i:950;}i:120726;a:1:{i:0;i:951;}i:120727;a:1:{i:0;i:952;}i:120728;a:1:{i:0;i:953;}i:120729;a:1:{i:0;i:954;}i:120730;a:1:{i:0;i:955;}i:120731;a:1:{i:0;i:956;}i:120732;a:1:{i:0;i:957;}i:120733;a:1:{i:0;i:958;}i:120734;a:1:{i:0;i:959;}i:120735;a:1:{i:0;i:960;}i:120736;a:1:{i:0;i:961;}i:120737;a:1:{i:0;i:952;}i:120738;a:1:{i:0;i:963;}i:120739;a:1:{i:0;i:964;}i:120740;a:1:{i:0;i:965;}i:120741;a:1:{i:0;i:966;}i:120742;a:1:{i:0;i:967;}i:120743;a:1:{i:0;i:968;}i:120744;a:1:{i:0;i:969;}i:120763;a:1:{i:0;i:963;}i:1017;a:1:{i:0;i:963;}i:7468;a:1:{i:0;i:97;}i:7469;a:1:{i:0;i:230;}i:7470;a:1:{i:0;i:98;}i:7472;a:1:{i:0;i:100;}i:7473;a:1:{i:0;i:101;}i:7474;a:1:{i:0;i:477;}i:7475;a:1:{i:0;i:103;}i:7476;a:1:{i:0;i:104;}i:7477;a:1:{i:0;i:105;}i:7478;a:1:{i:0;i:106;}i:7479;a:1:{i:0;i:107;}i:7480;a:1:{i:0;i:108;}i:7481;a:1:{i:0;i:109;}i:7482;a:1:{i:0;i:110;}i:7484;a:1:{i:0;i:111;}i:7485;a:1:{i:0;i:547;}i:7486;a:1:{i:0;i:112;}i:7487;a:1:{i:0;i:114;}i:7488;a:1:{i:0;i:116;}i:7489;a:1:{i:0;i:117;}i:7490;a:1:{i:0;i:119;}i:8507;a:3:{i:0;i:102;i:1;i:97;i:2;i:120;}i:12880;a:3:{i:0;i:112;i:1;i:116;i:2;i:101;}i:13004;a:2:{i:0;i:104;i:1;i:103;}i:13006;a:2:{i:0;i:101;i:1;i:118;}i:13007;a:3:{i:0;i:108;i:1;i:116;i:2;i:100;}i:13178;a:2:{i:0;i:105;i:1;i:117;}i:13278;a:3:{i:0;i:118;i:1;i:8725;i:2;i:109;}i:13279;a:3:{i:0;i:97;i:1;i:8725;i:2;i:109;}}s:12:"norm_combcls";a:341:{i:820;i:1;i:821;i:1;i:822;i:1;i:823;i:1;i:824;i:1;i:2364;i:7;i:2492;i:7;i:2620;i:7;i:2748;i:7;i:2876;i:7;i:3260;i:7;i:4151;i:7;i:12441;i:8;i:12442;i:8;i:2381;i:9;i:2509;i:9;i:2637;i:9;i:2765;i:9;i:2893;i:9;i:3021;i:9;i:3149;i:9;i:3277;i:9;i:3405;i:9;i:3530;i:9;i:3642;i:9;i:3972;i:9;i:4153;i:9;i:5908;i:9;i:5940;i:9;i:6098;i:9;i:1456;i:10;i:1457;i:11;i:1458;i:12;i:1459;i:13;i:1460;i:14;i:1461;i:15;i:1462;i:16;i:1463;i:17;i:1464;i:18;i:1465;i:19;i:1467;i:20;i:1468;i:21;i:1469;i:22;i:1471;i:23;i:1473;i:24;i:1474;i:25;i:64286;i:26;i:1611;i:27;i:1612;i:28;i:1613;i:29;i:1614;i:30;i:1615;i:31;i:1616;i:32;i:1617;i:33;i:1618;i:34;i:1648;i:35;i:1809;i:36;i:3157;i:84;i:3158;i:91;i:3640;i:103;i:3641;i:103;i:3656;i:107;i:3657;i:107;i:3658;i:107;i:3659;i:107;i:3768;i:118;i:3769;i:118;i:3784;i:122;i:3785;i:122;i:3786;i:122;i:3787;i:122;i:3953;i:129;i:3954;i:130;i:3962;i:130;i:3963;i:130;i:3964;i:130;i:3965;i:130;i:3968;i:130;i:3956;i:132;i:801;i:202;i:802;i:202;i:807;i:202;i:808;i:202;i:795;i:216;i:3897;i:216;i:119141;i:216;i:119142;i:216;i:119150;i:216;i:119151;i:216;i:119152;i:216;i:119153;i:216;i:119154;i:216;i:12330;i:218;i:790;i:220;i:791;i:220;i:792;i:220;i:793;i:220;i:796;i:220;i:797;i:220;i:798;i:220;i:799;i:220;i:800;i:220;i:803;i:220;i:804;i:220;i:805;i:220;i:806;i:220;i:809;i:220;i:810;i:220;i:811;i:220;i:812;i:220;i:813;i:220;i:814;i:220;i:815;i:220;i:816;i:220;i:817;i:220;i:818;i:220;i:819;i:220;i:825;i:220;i:826;i:220;i:827;i:220;i:828;i:220;i:839;i:220;i:840;i:220;i:841;i:220;i:845;i:220;i:846;i:220;i:851;i:220;i:852;i:220;i:853;i:220;i:854;i:220;i:1425;i:220;i:1430;i:220;i:1435;i:220;i:1443;i:220;i:1444;i:220;i:1445;i:220;i:1446;i:220;i:1447;i:220;i:1450;i:220;i:1621;i:220;i:1622;i:220;i:1763;i:220;i:1770;i:220;i:1773;i:220;i:1841;i:220;i:1844;i:220;i:1847;i:220;i:1848;i:220;i:1849;i:220;i:1851;i:220;i:1852;i:220;i:1854;i:220;i:1858;i:220;i:1860;i:220;i:1862;i:220;i:1864;i:220;i:2386;i:220;i:3864;i:220;i:3865;i:220;i:3893;i:220;i:3895;i:220;i:4038;i:220;i:6459;i:220;i:8424;i:220;i:119163;i:220;i:119164;i:220;i:119165;i:220;i:119166;i:220;i:119167;i:220;i:119168;i:220;i:119169;i:220;i:119170;i:220;i:119178;i:220;i:119179;i:220;i:1434;i:222;i:1453;i:222;i:6441;i:222;i:12333;i:222;i:12334;i:224;i:12335;i:224;i:119149;i:226;i:1454;i:228;i:6313;i:228;i:12331;i:228;i:768;i:230;i:769;i:230;i:770;i:230;i:771;i:230;i:772;i:230;i:773;i:230;i:774;i:230;i:775;i:230;i:776;i:230;i:777;i:230;i:778;i:230;i:779;i:230;i:780;i:230;i:781;i:230;i:782;i:230;i:783;i:230;i:784;i:230;i:785;i:230;i:786;i:230;i:787;i:230;i:788;i:230;i:829;i:230;i:830;i:230;i:831;i:230;i:832;i:230;i:833;i:230;i:834;i:230;i:835;i:230;i:836;i:230;i:838;i:230;i:842;i:230;i:843;i:230;i:844;i:230;i:848;i:230;i:849;i:230;i:850;i:230;i:855;i:230;i:867;i:230;i:868;i:230;i:869;i:230;i:870;i:230;i:871;i:230;i:872;i:230;i:873;i:230;i:874;i:230;i:875;i:230;i:876;i:230;i:877;i:230;i:878;i:230;i:879;i:230;i:1155;i:230;i:1156;i:230;i:1157;i:230;i:1158;i:230;i:1426;i:230;i:1427;i:230;i:1428;i:230;i:1429;i:230;i:1431;i:230;i:1432;i:230;i:1433;i:230;i:1436;i:230;i:1437;i:230;i:1438;i:230;i:1439;i:230;i:1440;i:230;i:1441;i:230;i:1448;i:230;i:1449;i:230;i:1451;i:230;i:1452;i:230;i:1455;i:230;i:1476;i:230;i:1552;i:230;i:1553;i:230;i:1554;i:230;i:1555;i:230;i:1556;i:230;i:1557;i:230;i:1619;i:230;i:1620;i:230;i:1623;i:230;i:1624;i:230;i:1750;i:230;i:1751;i:230;i:1752;i:230;i:1753;i:230;i:1754;i:230;i:1755;i:230;i:1756;i:230;i:1759;i:230;i:1760;i:230;i:1761;i:230;i:1762;i:230;i:1764;i:230;i:1767;i:230;i:1768;i:230;i:1771;i:230;i:1772;i:230;i:1840;i:230;i:1842;i:230;i:1843;i:230;i:1845;i:230;i:1846;i:230;i:1850;i:230;i:1853;i:230;i:1855;i:230;i:1856;i:230;i:1857;i:230;i:1859;i:230;i:1861;i:230;i:1863;i:230;i:1865;i:230;i:1866;i:230;i:2385;i:230;i:2387;i:230;i:2388;i:230;i:3970;i:230;i:3971;i:230;i:3974;i:230;i:3975;i:230;i:5901;i:230;i:6458;i:230;i:8400;i:230;i:8401;i:230;i:8404;i:230;i:8405;i:230;i:8406;i:230;i:8407;i:230;i:8411;i:230;i:8412;i:230;i:8417;i:230;i:8423;i:230;i:8425;i:230;i:65056;i:230;i:65057;i:230;i:65058;i:230;i:65059;i:230;i:119173;i:230;i:119174;i:230;i:119175;i:230;i:119177;i:230;i:119176;i:230;i:119210;i:230;i:119211;i:230;i:119212;i:230;i:119213;i:230;i:789;i:232;i:794;i:232;i:12332;i:232;i:863;i:233;i:866;i:233;i:861;i:234;i:862;i:234;i:864;i:234;i:865;i:234;i:837;i:240;}} \ No newline at end of file
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie.php
new file mode 100755
index 0000000..5ce5f82
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie.php
@@ -0,0 +1,3245 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2017, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @version 1.5.5
+ * @copyright 2004-2017 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * SimplePie Name
+ */
+define('SIMPLEPIE_NAME', 'SimplePie');
+
+/**
+ * SimplePie Version
+ */
+define('SIMPLEPIE_VERSION', '1.5.5');
+
+/**
+ * SimplePie Build
+ * @todo Hardcode for release (there's no need to have to call SimplePie_Misc::get_build() only every load of simplepie.inc)
+ */
+define('SIMPLEPIE_BUILD', gmdate('YmdHis', SimplePie_Misc::get_build()));
+
+/**
+ * SimplePie Website URL
+ */
+define('SIMPLEPIE_URL', 'http://simplepie.org');
+
+/**
+ * SimplePie Useragent
+ * @see SimplePie::set_useragent()
+ */
+define('SIMPLEPIE_USERAGENT', SIMPLEPIE_NAME . '/' . SIMPLEPIE_VERSION . ' (Feed Parser; ' . SIMPLEPIE_URL . '; Allow like Gecko) Build/' . SIMPLEPIE_BUILD);
+
+/**
+ * SimplePie Linkback
+ */
+define('SIMPLEPIE_LINKBACK', '<a href="' . SIMPLEPIE_URL . '" title="' . SIMPLEPIE_NAME . ' ' . SIMPLEPIE_VERSION . '">' . SIMPLEPIE_NAME . '</a>');
+
+/**
+ * No Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_NONE', 0);
+
+/**
+ * Feed Link Element Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_AUTODISCOVERY', 1);
+
+/**
+ * Local Feed Extension Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_LOCAL_EXTENSION', 2);
+
+/**
+ * Local Feed Body Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_LOCAL_BODY', 4);
+
+/**
+ * Remote Feed Extension Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_REMOTE_EXTENSION', 8);
+
+/**
+ * Remote Feed Body Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_REMOTE_BODY', 16);
+
+/**
+ * All Feed Autodiscovery
+ * @see SimplePie::set_autodiscovery_level()
+ */
+define('SIMPLEPIE_LOCATOR_ALL', 31);
+
+/**
+ * No known feed type
+ */
+define('SIMPLEPIE_TYPE_NONE', 0);
+
+/**
+ * RSS 0.90
+ */
+define('SIMPLEPIE_TYPE_RSS_090', 1);
+
+/**
+ * RSS 0.91 (Netscape)
+ */
+define('SIMPLEPIE_TYPE_RSS_091_NETSCAPE', 2);
+
+/**
+ * RSS 0.91 (Userland)
+ */
+define('SIMPLEPIE_TYPE_RSS_091_USERLAND', 4);
+
+/**
+ * RSS 0.91 (both Netscape and Userland)
+ */
+define('SIMPLEPIE_TYPE_RSS_091', 6);
+
+/**
+ * RSS 0.92
+ */
+define('SIMPLEPIE_TYPE_RSS_092', 8);
+
+/**
+ * RSS 0.93
+ */
+define('SIMPLEPIE_TYPE_RSS_093', 16);
+
+/**
+ * RSS 0.94
+ */
+define('SIMPLEPIE_TYPE_RSS_094', 32);
+
+/**
+ * RSS 1.0
+ */
+define('SIMPLEPIE_TYPE_RSS_10', 64);
+
+/**
+ * RSS 2.0
+ */
+define('SIMPLEPIE_TYPE_RSS_20', 128);
+
+/**
+ * RDF-based RSS
+ */
+define('SIMPLEPIE_TYPE_RSS_RDF', 65);
+
+/**
+ * Non-RDF-based RSS (truly intended as syndication format)
+ */
+define('SIMPLEPIE_TYPE_RSS_SYNDICATION', 190);
+
+/**
+ * All RSS
+ */
+define('SIMPLEPIE_TYPE_RSS_ALL', 255);
+
+/**
+ * Atom 0.3
+ */
+define('SIMPLEPIE_TYPE_ATOM_03', 256);
+
+/**
+ * Atom 1.0
+ */
+define('SIMPLEPIE_TYPE_ATOM_10', 512);
+
+/**
+ * All Atom
+ */
+define('SIMPLEPIE_TYPE_ATOM_ALL', 768);
+
+/**
+ * All feed types
+ */
+define('SIMPLEPIE_TYPE_ALL', 1023);
+
+/**
+ * No construct
+ */
+define('SIMPLEPIE_CONSTRUCT_NONE', 0);
+
+/**
+ * Text construct
+ */
+define('SIMPLEPIE_CONSTRUCT_TEXT', 1);
+
+/**
+ * HTML construct
+ */
+define('SIMPLEPIE_CONSTRUCT_HTML', 2);
+
+/**
+ * XHTML construct
+ */
+define('SIMPLEPIE_CONSTRUCT_XHTML', 4);
+
+/**
+ * base64-encoded construct
+ */
+define('SIMPLEPIE_CONSTRUCT_BASE64', 8);
+
+/**
+ * IRI construct
+ */
+define('SIMPLEPIE_CONSTRUCT_IRI', 16);
+
+/**
+ * A construct that might be HTML
+ */
+define('SIMPLEPIE_CONSTRUCT_MAYBE_HTML', 32);
+
+/**
+ * All constructs
+ */
+define('SIMPLEPIE_CONSTRUCT_ALL', 63);
+
+/**
+ * Don't change case
+ */
+define('SIMPLEPIE_SAME_CASE', 1);
+
+/**
+ * Change to lowercase
+ */
+define('SIMPLEPIE_LOWERCASE', 2);
+
+/**
+ * Change to uppercase
+ */
+define('SIMPLEPIE_UPPERCASE', 4);
+
+/**
+ * PCRE for HTML attributes
+ */
+define('SIMPLEPIE_PCRE_HTML_ATTRIBUTE', '((?:[\x09\x0A\x0B\x0C\x0D\x20]+[^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"(?:[^"]*)"|\'(?:[^\']*)\'|(?:[^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?)*)[\x09\x0A\x0B\x0C\x0D\x20]*');
+
+/**
+ * PCRE for XML attributes
+ */
+define('SIMPLEPIE_PCRE_XML_ATTRIBUTE', '((?:\s+(?:(?:[^\s:]+:)?[^\s:]+)\s*=\s*(?:"(?:[^"]*)"|\'(?:[^\']*)\'))*)\s*');
+
+/**
+ * XML Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_XML', 'http://www.w3.org/XML/1998/namespace');
+
+/**
+ * Atom 1.0 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_ATOM_10', 'http://www.w3.org/2005/Atom');
+
+/**
+ * Atom 0.3 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_ATOM_03', 'http://purl.org/atom/ns#');
+
+/**
+ * RDF Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_RDF', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#');
+
+/**
+ * RSS 0.90 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_RSS_090', 'http://my.netscape.com/rdf/simple/0.9/');
+
+/**
+ * RSS 1.0 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_RSS_10', 'http://purl.org/rss/1.0/');
+
+/**
+ * RSS 1.0 Content Module Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT', 'http://purl.org/rss/1.0/modules/content/');
+
+/**
+ * RSS 2.0 Namespace
+ * (Stupid, I know, but I'm certain it will confuse people less with support.)
+ */
+define('SIMPLEPIE_NAMESPACE_RSS_20', '');
+
+/**
+ * DC 1.0 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_DC_10', 'http://purl.org/dc/elements/1.0/');
+
+/**
+ * DC 1.1 Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_DC_11', 'http://purl.org/dc/elements/1.1/');
+
+/**
+ * W3C Basic Geo (WGS84 lat/long) Vocabulary Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO', 'http://www.w3.org/2003/01/geo/wgs84_pos#');
+
+/**
+ * GeoRSS Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_GEORSS', 'http://www.georss.org/georss');
+
+/**
+ * Media RSS Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_MEDIARSS', 'http://search.yahoo.com/mrss/');
+
+/**
+ * Wrong Media RSS Namespace. Caused by a long-standing typo in the spec.
+ */
+define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG', 'http://search.yahoo.com/mrss');
+
+/**
+ * Wrong Media RSS Namespace #2. New namespace introduced in Media RSS 1.5.
+ */
+define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2', 'http://video.search.yahoo.com/mrss');
+
+/**
+ * Wrong Media RSS Namespace #3. A possible typo of the Media RSS 1.5 namespace.
+ */
+define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3', 'http://video.search.yahoo.com/mrss/');
+
+/**
+ * Wrong Media RSS Namespace #4. New spec location after the RSS Advisory Board takes it over, but not a valid namespace.
+ */
+define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4', 'http://www.rssboard.org/media-rss');
+
+/**
+ * Wrong Media RSS Namespace #5. A possible typo of the RSS Advisory Board URL.
+ */
+define('SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5', 'http://www.rssboard.org/media-rss/');
+
+/**
+ * iTunes RSS Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_ITUNES', 'http://www.itunes.com/dtds/podcast-1.0.dtd');
+
+/**
+ * XHTML Namespace
+ */
+define('SIMPLEPIE_NAMESPACE_XHTML', 'http://www.w3.org/1999/xhtml');
+
+/**
+ * IANA Link Relations Registry
+ */
+define('SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY', 'http://www.iana.org/assignments/relation/');
+
+/**
+ * No file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_NONE', 0);
+
+/**
+ * Remote file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_REMOTE', 1);
+
+/**
+ * Local file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_LOCAL', 2);
+
+/**
+ * fsockopen() file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_FSOCKOPEN', 4);
+
+/**
+ * cURL file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_CURL', 8);
+
+/**
+ * file_get_contents() file source
+ */
+define('SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS', 16);
+
+
+
+/**
+ * SimplePie
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie
+{
+ /**
+ * @var array Raw data
+ * @access private
+ */
+ public $data = array();
+
+ /**
+ * @var mixed Error string
+ * @access private
+ */
+ public $error;
+
+ /**
+ * @var object Instance of SimplePie_Sanitize (or other class)
+ * @see SimplePie::set_sanitize_class()
+ * @access private
+ */
+ public $sanitize;
+
+ /**
+ * @var string SimplePie Useragent
+ * @see SimplePie::set_useragent()
+ * @access private
+ */
+ public $useragent = SIMPLEPIE_USERAGENT;
+
+ /**
+ * @var string Feed URL
+ * @see SimplePie::set_feed_url()
+ * @access private
+ */
+ public $feed_url;
+
+ /**
+ * @var string Original feed URL, or new feed URL iff HTTP 301 Moved Permanently
+ * @see SimplePie::subscribe_url()
+ * @access private
+ */
+ public $permanent_url = null;
+
+ /**
+ * @var object Instance of SimplePie_File to use as a feed
+ * @see SimplePie::set_file()
+ * @access private
+ */
+ public $file;
+
+ /**
+ * @var string Raw feed data
+ * @see SimplePie::set_raw_data()
+ * @access private
+ */
+ public $raw_data;
+
+ /**
+ * @var int Timeout for fetching remote files
+ * @see SimplePie::set_timeout()
+ * @access private
+ */
+ public $timeout = 10;
+
+ /**
+ * @var array Custom curl options
+ * @see SimplePie::set_curl_options()
+ * @access private
+ */
+ public $curl_options = array();
+
+ /**
+ * @var bool Forces fsockopen() to be used for remote files instead
+ * of cURL, even if a new enough version is installed
+ * @see SimplePie::force_fsockopen()
+ * @access private
+ */
+ public $force_fsockopen = false;
+
+ /**
+ * @var bool Force the given data/URL to be treated as a feed no matter what
+ * it appears like
+ * @see SimplePie::force_feed()
+ * @access private
+ */
+ public $force_feed = false;
+
+ /**
+ * @var bool Enable/Disable Caching
+ * @see SimplePie::enable_cache()
+ * @access private
+ */
+ public $cache = true;
+
+ /**
+ * @var bool Force SimplePie to fallback to expired cache, if enabled,
+ * when feed is unavailable.
+ * @see SimplePie::force_cache_fallback()
+ * @access private
+ */
+ public $force_cache_fallback = false;
+
+ /**
+ * @var int Cache duration (in seconds)
+ * @see SimplePie::set_cache_duration()
+ * @access private
+ */
+ public $cache_duration = 3600;
+
+ /**
+ * @var int Auto-discovery cache duration (in seconds)
+ * @see SimplePie::set_autodiscovery_cache_duration()
+ * @access private
+ */
+ public $autodiscovery_cache_duration = 604800; // 7 Days.
+
+ /**
+ * @var string Cache location (relative to executing script)
+ * @see SimplePie::set_cache_location()
+ * @access private
+ */
+ public $cache_location = './cache';
+
+ /**
+ * @var string Function that creates the cache filename
+ * @see SimplePie::set_cache_name_function()
+ * @access private
+ */
+ public $cache_name_function = 'md5';
+
+ /**
+ * @var bool Reorder feed by date descending
+ * @see SimplePie::enable_order_by_date()
+ * @access private
+ */
+ public $order_by_date = true;
+
+ /**
+ * @var mixed Force input encoding to be set to the follow value
+ * (false, or anything type-cast to false, disables this feature)
+ * @see SimplePie::set_input_encoding()
+ * @access private
+ */
+ public $input_encoding = false;
+
+ /**
+ * @var int Feed Autodiscovery Level
+ * @see SimplePie::set_autodiscovery_level()
+ * @access private
+ */
+ public $autodiscovery = SIMPLEPIE_LOCATOR_ALL;
+
+ /**
+ * Class registry object
+ *
+ * @var SimplePie_Registry
+ */
+ public $registry;
+
+ /**
+ * @var int Maximum number of feeds to check with autodiscovery
+ * @see SimplePie::set_max_checked_feeds()
+ * @access private
+ */
+ public $max_checked_feeds = 10;
+
+ /**
+ * @var array All the feeds found during the autodiscovery process
+ * @see SimplePie::get_all_discovered_feeds()
+ * @access private
+ */
+ public $all_discovered_feeds = array();
+
+ /**
+ * @var string Web-accessible path to the handler_image.php file.
+ * @see SimplePie::set_image_handler()
+ * @access private
+ */
+ public $image_handler = '';
+
+ /**
+ * @var array Stores the URLs when multiple feeds are being initialized.
+ * @see SimplePie::set_feed_url()
+ * @access private
+ */
+ public $multifeed_url = array();
+
+ /**
+ * @var array Stores SimplePie objects when multiple feeds initialized.
+ * @access private
+ */
+ public $multifeed_objects = array();
+
+ /**
+ * @var array Stores the get_object_vars() array for use with multifeeds.
+ * @see SimplePie::set_feed_url()
+ * @access private
+ */
+ public $config_settings = null;
+
+ /**
+ * @var integer Stores the number of items to return per-feed with multifeeds.
+ * @see SimplePie::set_item_limit()
+ * @access private
+ */
+ public $item_limit = 0;
+
+ /**
+ * @var bool Stores if last-modified and/or etag headers were sent with the
+ * request when checking a feed.
+ */
+ public $check_modified = false;
+
+ /**
+ * @var array Stores the default attributes to be stripped by strip_attributes().
+ * @see SimplePie::strip_attributes()
+ * @access private
+ */
+ public $strip_attributes = array('bgsound', 'class', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
+
+ /**
+ * @var array Stores the default attributes to add to different tags by add_attributes().
+ * @see SimplePie::add_attributes()
+ * @access private
+ */
+ public $add_attributes = array('audio' => array('preload' => 'none'), 'iframe' => array('sandbox' => 'allow-scripts allow-same-origin'), 'video' => array('preload' => 'none'));
+
+ /**
+ * @var array Stores the default tags to be stripped by strip_htmltags().
+ * @see SimplePie::strip_htmltags()
+ * @access private
+ */
+ public $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
+
+ /**
+ * @var bool Should we throw exceptions, or use the old-style error property?
+ * @access private
+ */
+ public $enable_exceptions = false;
+
+ /**
+ * The SimplePie class contains feed level data and options
+ *
+ * To use SimplePie, create the SimplePie object with no parameters. You can
+ * then set configuration options using the provided methods. After setting
+ * them, you must initialise the feed using $feed->init(). At that point the
+ * object's methods and properties will be available to you.
+ *
+ * Previously, it was possible to pass in the feed URL along with cache
+ * options directly into the constructor. This has been removed as of 1.3 as
+ * it caused a lot of confusion.
+ *
+ * @since 1.0 Preview Release
+ */
+ public function __construct()
+ {
+ if (version_compare(PHP_VERSION, '5.6', '<'))
+ {
+ trigger_error('Please upgrade to PHP 5.6 or newer.');
+ die();
+ }
+
+ // Other objects, instances created here so we can set options on them
+ $this->sanitize = new SimplePie_Sanitize();
+ $this->registry = new SimplePie_Registry();
+
+ if (func_num_args() > 0)
+ {
+ $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
+ trigger_error('Passing parameters to the constructor is no longer supported. Please use set_feed_url(), set_cache_location(), and set_cache_duration() directly.', $level);
+
+ $args = func_get_args();
+ switch (count($args)) {
+ case 3:
+ $this->set_cache_duration($args[2]);
+ case 2:
+ $this->set_cache_location($args[1]);
+ case 1:
+ $this->set_feed_url($args[0]);
+ $this->init();
+ }
+ }
+ }
+
+ /**
+ * Used for converting object to a string
+ */
+ public function __toString()
+ {
+ return md5(serialize($this->data));
+ }
+
+ /**
+ * Remove items that link back to this before destroying this object
+ */
+ public function __destruct()
+ {
+ if (!gc_enabled())
+ {
+ if (!empty($this->data['items']))
+ {
+ foreach ($this->data['items'] as $item)
+ {
+ $item->__destruct();
+ }
+ unset($item, $this->data['items']);
+ }
+ if (!empty($this->data['ordered_items']))
+ {
+ foreach ($this->data['ordered_items'] as $item)
+ {
+ $item->__destruct();
+ }
+ unset($item, $this->data['ordered_items']);
+ }
+ }
+ }
+
+ /**
+ * Force the given data/URL to be treated as a feed
+ *
+ * This tells SimplePie to ignore the content-type provided by the server.
+ * Be careful when using this option, as it will also disable autodiscovery.
+ *
+ * @since 1.1
+ * @param bool $enable Force the given data/URL to be treated as a feed
+ */
+ public function force_feed($enable = false)
+ {
+ $this->force_feed = (bool) $enable;
+ }
+
+ /**
+ * Set the URL of the feed you want to parse
+ *
+ * This allows you to enter the URL of the feed you want to parse, or the
+ * website you want to try to use auto-discovery on. This takes priority
+ * over any set raw data.
+ *
+ * You can set multiple feeds to mash together by passing an array instead
+ * of a string for the $url. Remember that with each additional feed comes
+ * additional processing and resources.
+ *
+ * @since 1.0 Preview Release
+ * @see set_raw_data()
+ * @param string|array $url This is the URL (or array of URLs) that you want to parse.
+ */
+ public function set_feed_url($url)
+ {
+ $this->multifeed_url = array();
+ if (is_array($url))
+ {
+ foreach ($url as $value)
+ {
+ $this->multifeed_url[] = $this->registry->call('Misc', 'fix_protocol', array($value, 1));
+ }
+ }
+ else
+ {
+ $this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1));
+ $this->permanent_url = $this->feed_url;
+ }
+ }
+
+ /**
+ * Set an instance of {@see SimplePie_File} to use as a feed
+ *
+ * @param SimplePie_File &$file
+ * @return bool True on success, false on failure
+ */
+ public function set_file(&$file)
+ {
+ if ($file instanceof SimplePie_File)
+ {
+ $this->feed_url = $file->url;
+ $this->permanent_url = $this->feed_url;
+ $this->file =& $file;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Set the raw XML data to parse
+ *
+ * Allows you to use a string of RSS/Atom data instead of a remote feed.
+ *
+ * If you have a feed available as a string in PHP, you can tell SimplePie
+ * to parse that data string instead of a remote feed. Any set feed URL
+ * takes precedence.
+ *
+ * @since 1.0 Beta 3
+ * @param string $data RSS or Atom data as a string.
+ * @see set_feed_url()
+ */
+ public function set_raw_data($data)
+ {
+ $this->raw_data = $data;
+ }
+
+ /**
+ * Set the default timeout for fetching remote feeds
+ *
+ * This allows you to change the maximum time the feed's server to respond
+ * and send the feed back.
+ *
+ * @since 1.0 Beta 3
+ * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed.
+ */
+ public function set_timeout($timeout = 10)
+ {
+ $this->timeout = (int) $timeout;
+ }
+
+ /**
+ * Set custom curl options
+ *
+ * This allows you to change default curl options
+ *
+ * @since 1.0 Beta 3
+ * @param array $curl_options Curl options to add to default settings
+ */
+ public function set_curl_options(array $curl_options = array())
+ {
+ $this->curl_options = $curl_options;
+ }
+
+ /**
+ * Force SimplePie to use fsockopen() instead of cURL
+ *
+ * @since 1.0 Beta 3
+ * @param bool $enable Force fsockopen() to be used
+ */
+ public function force_fsockopen($enable = false)
+ {
+ $this->force_fsockopen = (bool) $enable;
+ }
+
+ /**
+ * Enable/disable caching in SimplePie.
+ *
+ * This option allows you to disable caching all-together in SimplePie.
+ * However, disabling the cache can lead to longer load times.
+ *
+ * @since 1.0 Preview Release
+ * @param bool $enable Enable caching
+ */
+ public function enable_cache($enable = true)
+ {
+ $this->cache = (bool) $enable;
+ }
+
+ /**
+ * SimplePie to continue to fall back to expired cache, if enabled, when
+ * feed is unavailable.
+ *
+ * This tells SimplePie to ignore any file errors and fall back to cache
+ * instead. This only works if caching is enabled and cached content
+ * still exists.
+
+ * @param bool $enable Force use of cache on fail.
+ */
+ public function force_cache_fallback($enable = false)
+ {
+ $this->force_cache_fallback= (bool) $enable;
+ }
+
+ /**
+ * Set the length of time (in seconds) that the contents of a feed will be
+ * cached
+ *
+ * @param int $seconds The feed content cache duration
+ */
+ public function set_cache_duration($seconds = 3600)
+ {
+ $this->cache_duration = (int) $seconds;
+ }
+
+ /**
+ * Set the length of time (in seconds) that the autodiscovered feed URL will
+ * be cached
+ *
+ * @param int $seconds The autodiscovered feed URL cache duration.
+ */
+ public function set_autodiscovery_cache_duration($seconds = 604800)
+ {
+ $this->autodiscovery_cache_duration = (int) $seconds;
+ }
+
+ /**
+ * Set the file system location where the cached files should be stored
+ *
+ * @param string $location The file system location.
+ */
+ public function set_cache_location($location = './cache')
+ {
+ $this->cache_location = (string) $location;
+ }
+
+ /**
+ * Set whether feed items should be sorted into reverse chronological order
+ *
+ * @param bool $enable Sort as reverse chronological order.
+ */
+ public function enable_order_by_date($enable = true)
+ {
+ $this->order_by_date = (bool) $enable;
+ }
+
+ /**
+ * Set the character encoding used to parse the feed
+ *
+ * This overrides the encoding reported by the feed, however it will fall
+ * back to the normal encoding detection if the override fails
+ *
+ * @param string $encoding Character encoding
+ */
+ public function set_input_encoding($encoding = false)
+ {
+ if ($encoding)
+ {
+ $this->input_encoding = (string) $encoding;
+ }
+ else
+ {
+ $this->input_encoding = false;
+ }
+ }
+
+ /**
+ * Set how much feed autodiscovery to do
+ *
+ * @see SIMPLEPIE_LOCATOR_NONE
+ * @see SIMPLEPIE_LOCATOR_AUTODISCOVERY
+ * @see SIMPLEPIE_LOCATOR_LOCAL_EXTENSION
+ * @see SIMPLEPIE_LOCATOR_LOCAL_BODY
+ * @see SIMPLEPIE_LOCATOR_REMOTE_EXTENSION
+ * @see SIMPLEPIE_LOCATOR_REMOTE_BODY
+ * @see SIMPLEPIE_LOCATOR_ALL
+ * @param int $level Feed Autodiscovery Level (level can be a combination of the above constants, see bitwise OR operator)
+ */
+ public function set_autodiscovery_level($level = SIMPLEPIE_LOCATOR_ALL)
+ {
+ $this->autodiscovery = (int) $level;
+ }
+
+ /**
+ * Get the class registry
+ *
+ * Use this to override SimplePie's default classes
+ * @see SimplePie_Registry
+ * @return SimplePie_Registry
+ */
+ public function &get_registry()
+ {
+ return $this->registry;
+ }
+
+ /**#@+
+ * Useful when you are overloading or extending SimplePie's default classes.
+ *
+ * @deprecated Use {@see get_registry()} instead
+ * @link http://php.net/manual/en/language.oop5.basic.php#language.oop5.basic.extends PHP5 extends documentation
+ * @param string $class Name of custom class
+ * @return boolean True on success, false otherwise
+ */
+ /**
+ * Set which class SimplePie uses for caching
+ */
+ public function set_cache_class($class = 'SimplePie_Cache')
+ {
+ return $this->registry->register('Cache', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for auto-discovery
+ */
+ public function set_locator_class($class = 'SimplePie_Locator')
+ {
+ return $this->registry->register('Locator', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for XML parsing
+ */
+ public function set_parser_class($class = 'SimplePie_Parser')
+ {
+ return $this->registry->register('Parser', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for remote file fetching
+ */
+ public function set_file_class($class = 'SimplePie_File')
+ {
+ return $this->registry->register('File', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for data sanitization
+ */
+ public function set_sanitize_class($class = 'SimplePie_Sanitize')
+ {
+ return $this->registry->register('Sanitize', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for handling feed items
+ */
+ public function set_item_class($class = 'SimplePie_Item')
+ {
+ return $this->registry->register('Item', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for handling author data
+ */
+ public function set_author_class($class = 'SimplePie_Author')
+ {
+ return $this->registry->register('Author', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for handling category data
+ */
+ public function set_category_class($class = 'SimplePie_Category')
+ {
+ return $this->registry->register('Category', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for feed enclosures
+ */
+ public function set_enclosure_class($class = 'SimplePie_Enclosure')
+ {
+ return $this->registry->register('Enclosure', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for `<media:text>` captions
+ */
+ public function set_caption_class($class = 'SimplePie_Caption')
+ {
+ return $this->registry->register('Caption', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for `<media:copyright>`
+ */
+ public function set_copyright_class($class = 'SimplePie_Copyright')
+ {
+ return $this->registry->register('Copyright', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for `<media:credit>`
+ */
+ public function set_credit_class($class = 'SimplePie_Credit')
+ {
+ return $this->registry->register('Credit', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for `<media:rating>`
+ */
+ public function set_rating_class($class = 'SimplePie_Rating')
+ {
+ return $this->registry->register('Rating', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for `<media:restriction>`
+ */
+ public function set_restriction_class($class = 'SimplePie_Restriction')
+ {
+ return $this->registry->register('Restriction', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses for content-type sniffing
+ */
+ public function set_content_type_sniffer_class($class = 'SimplePie_Content_Type_Sniffer')
+ {
+ return $this->registry->register('Content_Type_Sniffer', $class, true);
+ }
+
+ /**
+ * Set which class SimplePie uses item sources
+ */
+ public function set_source_class($class = 'SimplePie_Source')
+ {
+ return $this->registry->register('Source', $class, true);
+ }
+ /**#@-*/
+
+ /**
+ * Set the user agent string
+ *
+ * @param string $ua New user agent string.
+ */
+ public function set_useragent($ua = SIMPLEPIE_USERAGENT)
+ {
+ $this->useragent = (string) $ua;
+ }
+
+ /**
+ * Set callback function to create cache filename with
+ *
+ * @param mixed $function Callback function
+ */
+ public function set_cache_name_function($function = 'md5')
+ {
+ if (is_callable($function))
+ {
+ $this->cache_name_function = $function;
+ }
+ }
+
+ /**
+ * Set options to make SP as fast as possible
+ *
+ * Forgoes a substantial amount of data sanitization in favor of speed. This
+ * turns SimplePie into a dumb parser of feeds.
+ *
+ * @param bool $set Whether to set them or not
+ */
+ public function set_stupidly_fast($set = false)
+ {
+ if ($set)
+ {
+ $this->enable_order_by_date(false);
+ $this->remove_div(false);
+ $this->strip_comments(false);
+ $this->strip_htmltags(false);
+ $this->strip_attributes(false);
+ $this->add_attributes(false);
+ $this->set_image_handler(false);
+ }
+ }
+
+ /**
+ * Set maximum number of feeds to check with autodiscovery
+ *
+ * @param int $max Maximum number of feeds to check
+ */
+ public function set_max_checked_feeds($max = 10)
+ {
+ $this->max_checked_feeds = (int) $max;
+ }
+
+ public function remove_div($enable = true)
+ {
+ $this->sanitize->remove_div($enable);
+ }
+
+ public function strip_htmltags($tags = '', $encode = null)
+ {
+ if ($tags === '')
+ {
+ $tags = $this->strip_htmltags;
+ }
+ $this->sanitize->strip_htmltags($tags);
+ if ($encode !== null)
+ {
+ $this->sanitize->encode_instead_of_strip($tags);
+ }
+ }
+
+ public function encode_instead_of_strip($enable = true)
+ {
+ $this->sanitize->encode_instead_of_strip($enable);
+ }
+
+ public function strip_attributes($attribs = '')
+ {
+ if ($attribs === '')
+ {
+ $attribs = $this->strip_attributes;
+ }
+ $this->sanitize->strip_attributes($attribs);
+ }
+
+ public function add_attributes($attribs = '')
+ {
+ if ($attribs === '')
+ {
+ $attribs = $this->add_attributes;
+ }
+ $this->sanitize->add_attributes($attribs);
+ }
+
+ /**
+ * Set the output encoding
+ *
+ * Allows you to override SimplePie's output to match that of your webpage.
+ * This is useful for times when your webpages are not being served as
+ * UTF-8. This setting will be obeyed by {@see handle_content_type()}, and
+ * is similar to {@see set_input_encoding()}.
+ *
+ * It should be noted, however, that not all character encodings can support
+ * all characters. If your page is being served as ISO-8859-1 and you try
+ * to display a Japanese feed, you'll likely see garbled characters.
+ * Because of this, it is highly recommended to ensure that your webpages
+ * are served as UTF-8.
+ *
+ * The number of supported character encodings depends on whether your web
+ * host supports {@link http://php.net/mbstring mbstring},
+ * {@link http://php.net/iconv iconv}, or both. See
+ * {@link http://simplepie.org/wiki/faq/Supported_Character_Encodings} for
+ * more information.
+ *
+ * @param string $encoding
+ */
+ public function set_output_encoding($encoding = 'UTF-8')
+ {
+ $this->sanitize->set_output_encoding($encoding);
+ }
+
+ public function strip_comments($strip = false)
+ {
+ $this->sanitize->strip_comments($strip);
+ }
+
+ /**
+ * Set element/attribute key/value pairs of HTML attributes
+ * containing URLs that need to be resolved relative to the feed
+ *
+ * Defaults to |a|@href, |area|@href, |blockquote|@cite, |del|@cite,
+ * |form|@action, |img|@longdesc, |img|@src, |input|@src, |ins|@cite,
+ * |q|@cite
+ *
+ * @since 1.0
+ * @param array|null $element_attribute Element/attribute key/value pairs, null for default
+ */
+ public function set_url_replacements($element_attribute = null)
+ {
+ $this->sanitize->set_url_replacements($element_attribute);
+ }
+
+ /**
+ * Set the handler to enable the display of cached images.
+ *
+ * @param string $page Web-accessible path to the handler_image.php file.
+ * @param string $qs The query string that the value should be passed to.
+ */
+ public function set_image_handler($page = false, $qs = 'i')
+ {
+ if ($page !== false)
+ {
+ $this->sanitize->set_image_handler($page . '?' . $qs . '=');
+ }
+ else
+ {
+ $this->image_handler = '';
+ }
+ }
+
+ /**
+ * Set the limit for items returned per-feed with multifeeds
+ *
+ * @param integer $limit The maximum number of items to return.
+ */
+ public function set_item_limit($limit = 0)
+ {
+ $this->item_limit = (int) $limit;
+ }
+
+ /**
+ * Enable throwing exceptions
+ *
+ * @param boolean $enable Should we throw exceptions, or use the old-style error property?
+ */
+ public function enable_exceptions($enable = true)
+ {
+ $this->enable_exceptions = $enable;
+ }
+
+ /**
+ * Initialize the feed object
+ *
+ * This is what makes everything happen. Period. This is where all of the
+ * configuration options get processed, feeds are fetched, cached, and
+ * parsed, and all of that other good stuff.
+ *
+ * @return boolean True if successful, false otherwise
+ */
+ public function init()
+ {
+ // Check absolute bare minimum requirements.
+ if (!extension_loaded('xml') || !extension_loaded('pcre'))
+ {
+ $this->error = 'XML or PCRE extensions not loaded!';
+ return false;
+ }
+ // Then check the xml extension is sane (i.e., libxml 2.7.x issue on PHP < 5.2.9 and libxml 2.7.0 to 2.7.2 on any version) if we don't have xmlreader.
+ elseif (!extension_loaded('xmlreader'))
+ {
+ static $xml_is_sane = null;
+ if ($xml_is_sane === null)
+ {
+ $parser_check = xml_parser_create();
+ xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
+ xml_parser_free($parser_check);
+ $xml_is_sane = isset($values[0]['value']);
+ }
+ if (!$xml_is_sane)
+ {
+ return false;
+ }
+ }
+
+ // The default sanitize class gets set in the constructor, check if it has
+ // changed.
+ if ($this->registry->get_class('Sanitize') !== 'SimplePie_Sanitize') {
+ $this->sanitize = $this->registry->create('Sanitize');
+ }
+ if (method_exists($this->sanitize, 'set_registry'))
+ {
+ $this->sanitize->set_registry($this->registry);
+ }
+
+ // Pass whatever was set with config options over to the sanitizer.
+ // Pass the classes in for legacy support; new classes should use the registry instead
+ $this->sanitize->pass_cache_data($this->cache, $this->cache_location, $this->cache_name_function, $this->registry->get_class('Cache'));
+ $this->sanitize->pass_file_data($this->registry->get_class('File'), $this->timeout, $this->useragent, $this->force_fsockopen, $this->curl_options);
+
+ if (!empty($this->multifeed_url))
+ {
+ $i = 0;
+ $success = 0;
+ $this->multifeed_objects = array();
+ $this->error = array();
+ foreach ($this->multifeed_url as $url)
+ {
+ $this->multifeed_objects[$i] = clone $this;
+ $this->multifeed_objects[$i]->set_feed_url($url);
+ $single_success = $this->multifeed_objects[$i]->init();
+ $success |= $single_success;
+ if (!$single_success)
+ {
+ $this->error[$i] = $this->multifeed_objects[$i]->error();
+ }
+ $i++;
+ }
+ return (bool) $success;
+ }
+ elseif ($this->feed_url === null && $this->raw_data === null)
+ {
+ return false;
+ }
+
+ $this->error = null;
+ $this->data = array();
+ $this->check_modified = false;
+ $this->multifeed_objects = array();
+ $cache = false;
+
+ if ($this->feed_url !== null)
+ {
+ $parsed_feed_url = $this->registry->call('Misc', 'parse_url', array($this->feed_url));
+
+ // Decide whether to enable caching
+ if ($this->cache && $parsed_feed_url['scheme'] !== '')
+ {
+ $url = $this->feed_url . ($this->force_feed ? '#force_feed' : '');
+ $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $url), 'spc'));
+ }
+
+ // Fetch the data via SimplePie_File into $this->raw_data
+ if (($fetched = $this->fetch_data($cache)) === true)
+ {
+ return true;
+ }
+ elseif ($fetched === false) {
+ return false;
+ }
+
+ list($headers, $sniffed) = $fetched;
+ }
+
+ // Empty response check
+ if(empty($this->raw_data)){
+ $this->error = "A feed could not be found at `$this->feed_url`. Empty body.";
+ $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
+ return false;
+ }
+
+ // Set up array of possible encodings
+ $encodings = array();
+
+ // First check to see if input has been overridden.
+ if ($this->input_encoding !== false)
+ {
+ $encodings[] = strtoupper($this->input_encoding);
+ }
+
+ $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity');
+ $text_types = array('text/xml', 'text/xml-external-parsed-entity');
+
+ // RFC 3023 (only applies to sniffed content)
+ if (isset($sniffed))
+ {
+ if (in_array($sniffed, $application_types) || substr($sniffed, 0, 12) === 'application/' && substr($sniffed, -4) === '+xml')
+ {
+ if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
+ {
+ $encodings[] = strtoupper($charset[1]);
+ }
+ $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
+ $encodings[] = 'UTF-8';
+ }
+ elseif (in_array($sniffed, $text_types) || substr($sniffed, 0, 5) === 'text/' && substr($sniffed, -4) === '+xml')
+ {
+ if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset))
+ {
+ $encodings[] = strtoupper($charset[1]);
+ }
+ $encodings[] = 'US-ASCII';
+ }
+ // Text MIME-type default
+ elseif (substr($sniffed, 0, 5) === 'text/')
+ {
+ $encodings[] = 'UTF-8';
+ }
+ }
+
+ // Fallback to XML 1.0 Appendix F.1/UTF-8/ISO-8859-1
+ $encodings = array_merge($encodings, $this->registry->call('Misc', 'xml_encoding', array($this->raw_data, &$this->registry)));
+ $encodings[] = 'UTF-8';
+ $encodings[] = 'ISO-8859-1';
+
+ // There's no point in trying an encoding twice
+ $encodings = array_unique($encodings);
+
+ // Loop through each possible encoding, till we return something, or run out of possibilities
+ foreach ($encodings as $encoding)
+ {
+ // Change the encoding to UTF-8 (as we always use UTF-8 internally)
+ if ($utf8_data = $this->registry->call('Misc', 'change_encoding', array($this->raw_data, $encoding, 'UTF-8')))
+ {
+ // Create new parser
+ $parser = $this->registry->create('Parser');
+
+ // If it's parsed fine
+ if ($parser->parse($utf8_data, 'UTF-8', $this->permanent_url))
+ {
+ $this->data = $parser->get_data();
+ if (!($this->get_type() & ~SIMPLEPIE_TYPE_NONE))
+ {
+ $this->error = "A feed could not be found at `$this->feed_url`. This does not appear to be a valid RSS or Atom feed.";
+ $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
+ return false;
+ }
+
+ if (isset($headers))
+ {
+ $this->data['headers'] = $headers;
+ }
+ $this->data['build'] = SIMPLEPIE_BUILD;
+
+ // Cache the file if caching is enabled
+ if ($cache && !$cache->save($this))
+ {
+ trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
+ }
+ return true;
+ }
+ }
+ }
+
+ if (isset($parser))
+ {
+ // We have an error, just set SimplePie_Misc::error to it and quit
+ $this->error = $this->feed_url;
+ $this->error .= sprintf(' is invalid XML, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column());
+ }
+ else
+ {
+ $this->error = 'The data could not be converted to UTF-8.';
+ if (!extension_loaded('mbstring') && !extension_loaded('iconv') && !class_exists('\UConverter')) {
+ $this->error .= ' You MUST have either the iconv, mbstring or intl (PHP 5.5+) extension installed and enabled.';
+ } else {
+ $missingExtensions = array();
+ if (!extension_loaded('iconv')) {
+ $missingExtensions[] = 'iconv';
+ }
+ if (!extension_loaded('mbstring')) {
+ $missingExtensions[] = 'mbstring';
+ }
+ if (!class_exists('\UConverter')) {
+ $missingExtensions[] = 'intl (PHP 5.5+)';
+ }
+ $this->error .= ' Try installing/enabling the ' . implode(' or ', $missingExtensions) . ' extension.';
+ }
+ }
+
+ $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
+
+ return false;
+ }
+
+ /**
+ * Fetch the data via SimplePie_File
+ *
+ * If the data is already cached, attempt to fetch it from there instead
+ * @param SimplePie_Cache|false $cache Cache handler, or false to not load from the cache
+ * @return array|true Returns true if the data was loaded from the cache, or an array of HTTP headers and sniffed type
+ */
+ protected function fetch_data(&$cache)
+ {
+ // If it's enabled, use the cache
+ if ($cache)
+ {
+ // Load the Cache
+ $this->data = $cache->load();
+ if (!empty($this->data))
+ {
+ // If the cache is for an outdated build of SimplePie
+ if (!isset($this->data['build']) || $this->data['build'] !== SIMPLEPIE_BUILD)
+ {
+ $cache->unlink();
+ $this->data = array();
+ }
+ // If we've hit a collision just rerun it with caching disabled
+ elseif (isset($this->data['url']) && $this->data['url'] !== $this->feed_url)
+ {
+ $cache = false;
+ $this->data = array();
+ }
+ // If we've got a non feed_url stored (if the page isn't actually a feed, or is a redirect) use that URL.
+ elseif (isset($this->data['feed_url']))
+ {
+ // If the autodiscovery cache is still valid use it.
+ if ($cache->mtime() + $this->autodiscovery_cache_duration > time())
+ {
+ // Do not need to do feed autodiscovery yet.
+ if ($this->data['feed_url'] !== $this->data['url'])
+ {
+ $this->set_feed_url($this->data['feed_url']);
+ return $this->init();
+ }
+
+ $cache->unlink();
+ $this->data = array();
+ }
+ }
+ // Check if the cache has been updated
+ elseif ($cache->mtime() + $this->cache_duration < time())
+ {
+ // Want to know if we tried to send last-modified and/or etag headers
+ // when requesting this file. (Note that it's up to the file to
+ // support this, but we don't always send the headers either.)
+ $this->check_modified = true;
+ if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag']))
+ {
+ $headers = array(
+ 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
+ );
+ if (isset($this->data['headers']['last-modified']))
+ {
+ $headers['if-modified-since'] = $this->data['headers']['last-modified'];
+ }
+ if (isset($this->data['headers']['etag']))
+ {
+ $headers['if-none-match'] = $this->data['headers']['etag'];
+ }
+
+ $file = $this->registry->create('File', array($this->feed_url, $this->timeout/10, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options));
+
+ if ($file->success)
+ {
+ if ($file->status_code === 304)
+ {
+ // Set raw_data to false here too, to signify that the cache
+ // is still valid.
+ $this->raw_data = false;
+ $cache->touch();
+ return true;
+ }
+ }
+ else
+ {
+ $this->check_modified = false;
+ if($this->force_cache_fallback)
+ {
+ $cache->touch();
+ return true;
+ }
+
+ unset($file);
+ }
+ }
+ }
+ // If the cache is still valid, just return true
+ else
+ {
+ $this->raw_data = false;
+ return true;
+ }
+ }
+ // If the cache is empty, delete it
+ else
+ {
+ $cache->unlink();
+ $this->data = array();
+ }
+ }
+ // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it.
+ if (!isset($file))
+ {
+ if ($this->file instanceof SimplePie_File && $this->file->url === $this->feed_url)
+ {
+ $file =& $this->file;
+ }
+ else
+ {
+ $headers = array(
+ 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
+ );
+ $file = $this->registry->create('File', array($this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options));
+ }
+ }
+ // If the file connection has an error, set SimplePie::error to that and quit
+ if (!$file->success && !($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
+ {
+ $this->error = $file->error;
+ return !empty($this->data);
+ }
+
+ if (!$this->force_feed)
+ {
+ // Check if the supplied URL is a feed, if it isn't, look for it.
+ $locate = $this->registry->create('Locator', array(&$file, $this->timeout, $this->useragent, $this->max_checked_feeds, $this->force_fsockopen, $this->curl_options));
+
+ if (!$locate->is_feed($file))
+ {
+ $copyStatusCode = $file->status_code;
+ $copyContentType = $file->headers['content-type'];
+ try
+ {
+ $microformats = false;
+ if (class_exists('DOMXpath') && function_exists('Mf2\parse')) {
+ $doc = new DOMDocument();
+ @$doc->loadHTML($file->body);
+ $xpath = new DOMXpath($doc);
+ // Check for both h-feed and h-entry, as both a feed with no entries
+ // and a list of entries without an h-feed wrapper are both valid.
+ $query = '//*[contains(concat(" ", @class, " "), " h-feed ") or '.
+ 'contains(concat(" ", @class, " "), " h-entry ")]';
+ $result = $xpath->query($query);
+ $microformats = $result->length !== 0;
+ }
+ // Now also do feed discovery, but if microformats were found don't
+ // overwrite the current value of file.
+ $discovered = $locate->find($this->autodiscovery,
+ $this->all_discovered_feeds);
+ if ($microformats)
+ {
+ if ($hub = $locate->get_rel_link('hub'))
+ {
+ $self = $locate->get_rel_link('self');
+ $this->store_links($file, $hub, $self);
+ }
+ // Push the current file onto all_discovered feeds so the user can
+ // be shown this as one of the options.
+ if (isset($this->all_discovered_feeds)) {
+ $this->all_discovered_feeds[] = $file;
+ }
+ }
+ else
+ {
+ if ($discovered)
+ {
+ $file = $discovered;
+ }
+ else
+ {
+ // We need to unset this so that if SimplePie::set_file() has
+ // been called that object is untouched
+ unset($file);
+ $this->error = "A feed could not be found at `$this->feed_url`; the status code is `$copyStatusCode` and content-type is `$copyContentType`";
+ $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, __FILE__, __LINE__));
+ return false;
+ }
+ }
+ }
+ catch (SimplePie_Exception $e)
+ {
+ // We need to unset this so that if SimplePie::set_file() has been called that object is untouched
+ unset($file);
+ // This is usually because DOMDocument doesn't exist
+ $this->error = $e->getMessage();
+ $this->registry->call('Misc', 'error', array($this->error, E_USER_NOTICE, $e->getFile(), $e->getLine()));
+ return false;
+ }
+ if ($cache)
+ {
+ $this->data = array('url' => $this->feed_url, 'feed_url' => $file->url, 'build' => SIMPLEPIE_BUILD);
+ if (!$cache->save($this))
+ {
+ trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
+ }
+ $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, call_user_func($this->cache_name_function, $file->url), 'spc'));
+ }
+ }
+ $this->feed_url = $file->url;
+ $locate = null;
+ }
+
+ $this->raw_data = $file->body;
+ $this->permanent_url = $file->permanent_url;
+ $headers = $file->headers;
+ $sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file));
+ $sniffed = $sniffer->get_type();
+
+ return array($headers, $sniffed);
+ }
+
+ /**
+ * Get the error message for the occured error
+ *
+ * @return string|array Error message, or array of messages for multifeeds
+ */
+ public function error()
+ {
+ return $this->error;
+ }
+
+ /**
+ * Get the raw XML
+ *
+ * This is the same as the old `$feed->enable_xml_dump(true)`, but returns
+ * the data instead of printing it.
+ *
+ * @return string|boolean Raw XML data, false if the cache is used
+ */
+ public function get_raw_data()
+ {
+ return $this->raw_data;
+ }
+
+ /**
+ * Get the character encoding used for output
+ *
+ * @since Preview Release
+ * @return string
+ */
+ public function get_encoding()
+ {
+ return $this->sanitize->output_encoding;
+ }
+
+ /**
+ * Send the content-type header with correct encoding
+ *
+ * This method ensures that the SimplePie-enabled page is being served with
+ * the correct {@link http://www.iana.org/assignments/media-types/ mime-type}
+ * and character encoding HTTP headers (character encoding determined by the
+ * {@see set_output_encoding} config option).
+ *
+ * This won't work properly if any content or whitespace has already been
+ * sent to the browser, because it relies on PHP's
+ * {@link http://php.net/header header()} function, and these are the
+ * circumstances under which the function works.
+ *
+ * Because it's setting these settings for the entire page (as is the nature
+ * of HTTP headers), this should only be used once per page (again, at the
+ * top).
+ *
+ * @param string $mime MIME type to serve the page as
+ */
+ public function handle_content_type($mime = 'text/html')
+ {
+ if (!headers_sent())
+ {
+ $header = "Content-type: $mime;";
+ if ($this->get_encoding())
+ {
+ $header .= ' charset=' . $this->get_encoding();
+ }
+ else
+ {
+ $header .= ' charset=UTF-8';
+ }
+ header($header);
+ }
+ }
+
+ /**
+ * Get the type of the feed
+ *
+ * This returns a SIMPLEPIE_TYPE_* constant, which can be tested against
+ * using {@link http://php.net/language.operators.bitwise bitwise operators}
+ *
+ * @since 0.8 (usage changed to using constants in 1.0)
+ * @see SIMPLEPIE_TYPE_NONE Unknown.
+ * @see SIMPLEPIE_TYPE_RSS_090 RSS 0.90.
+ * @see SIMPLEPIE_TYPE_RSS_091_NETSCAPE RSS 0.91 (Netscape).
+ * @see SIMPLEPIE_TYPE_RSS_091_USERLAND RSS 0.91 (Userland).
+ * @see SIMPLEPIE_TYPE_RSS_091 RSS 0.91.
+ * @see SIMPLEPIE_TYPE_RSS_092 RSS 0.92.
+ * @see SIMPLEPIE_TYPE_RSS_093 RSS 0.93.
+ * @see SIMPLEPIE_TYPE_RSS_094 RSS 0.94.
+ * @see SIMPLEPIE_TYPE_RSS_10 RSS 1.0.
+ * @see SIMPLEPIE_TYPE_RSS_20 RSS 2.0.x.
+ * @see SIMPLEPIE_TYPE_RSS_RDF RDF-based RSS.
+ * @see SIMPLEPIE_TYPE_RSS_SYNDICATION Non-RDF-based RSS (truly intended as syndication format).
+ * @see SIMPLEPIE_TYPE_RSS_ALL Any version of RSS.
+ * @see SIMPLEPIE_TYPE_ATOM_03 Atom 0.3.
+ * @see SIMPLEPIE_TYPE_ATOM_10 Atom 1.0.
+ * @see SIMPLEPIE_TYPE_ATOM_ALL Any version of Atom.
+ * @see SIMPLEPIE_TYPE_ALL Any known/supported feed type.
+ * @return int SIMPLEPIE_TYPE_* constant
+ */
+ public function get_type()
+ {
+ if (!isset($this->data['type']))
+ {
+ $this->data['type'] = SIMPLEPIE_TYPE_ALL;
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed']))
+ {
+ $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_10;
+ }
+ elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed']))
+ {
+ $this->data['type'] &= SIMPLEPIE_TYPE_ATOM_03;
+ }
+ elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF']))
+ {
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['channel'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['image'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_10]['textinput']))
+ {
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_10;
+ }
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['channel'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['image'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])
+ || isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_090]['textinput']))
+ {
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_090;
+ }
+ }
+ elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss']))
+ {
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_ALL;
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
+ {
+ switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['attribs']['']['version']))
+ {
+ case '0.91':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091;
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
+ {
+ switch (trim($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['skiphours']['hour'][0]['data']))
+ {
+ case '0':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_NETSCAPE;
+ break;
+
+ case '24':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_091_USERLAND;
+ break;
+ }
+ }
+ break;
+
+ case '0.92':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_092;
+ break;
+
+ case '0.93':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_093;
+ break;
+
+ case '0.94':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_094;
+ break;
+
+ case '2.0':
+ $this->data['type'] &= SIMPLEPIE_TYPE_RSS_20;
+ break;
+ }
+ }
+ }
+ else
+ {
+ $this->data['type'] = SIMPLEPIE_TYPE_NONE;
+ }
+ }
+ return $this->data['type'];
+ }
+
+ /**
+ * Get the URL for the feed
+ *
+ * When the 'permanent' mode is enabled, returns the original feed URL,
+ * except in the case of an `HTTP 301 Moved Permanently` status response,
+ * in which case the location of the first redirection is returned.
+ *
+ * When the 'permanent' mode is disabled (default),
+ * may or may not be different from the URL passed to {@see set_feed_url()},
+ * depending on whether auto-discovery was used, and whether there were
+ * any redirects along the way.
+ *
+ * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.)
+ * @todo Support <itunes:new-feed-url>
+ * @todo Also, |atom:link|@rel=self
+ * @param bool $permanent Permanent mode to return only the original URL or the first redirection
+ * iff it is a 301 redirection
+ * @return string|null
+ */
+ public function subscribe_url($permanent = false)
+ {
+ if ($permanent)
+ {
+ if ($this->permanent_url !== null)
+ {
+ // sanitize encodes ampersands which are required when used in a url.
+ return str_replace('&amp;', '&',
+ $this->sanitize($this->permanent_url,
+ SIMPLEPIE_CONSTRUCT_IRI));
+ }
+ }
+ else
+ {
+ if ($this->feed_url !== null)
+ {
+ return str_replace('&amp;', '&',
+ $this->sanitize($this->feed_url,
+ SIMPLEPIE_CONSTRUCT_IRI));
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get data for an feed-level element
+ *
+ * This method allows you to get access to ANY element/attribute that is a
+ * sub-element of the opening feed tag.
+ *
+ * The return value is an indexed array of elements matching the given
+ * namespace and tag name. Each element has `attribs`, `data` and `child`
+ * subkeys. For `attribs` and `child`, these contain namespace subkeys.
+ * `attribs` then has one level of associative name => value data (where
+ * `value` is a string) after the namespace. `child` has tag-indexed keys
+ * after the namespace, each member of which is an indexed array matching
+ * this same format.
+ *
+ * For example:
+ * <pre>
+ * // This is probably a bad example because we already support
+ * // <media:content> natively, but it shows you how to parse through
+ * // the nodes.
+ * $group = $item->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group');
+ * $content = $group[0]['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'];
+ * $file = $content[0]['attribs']['']['url'];
+ * echo $file;
+ * </pre>
+ *
+ * @since 1.0
+ * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
+ * @param string $namespace The URL of the XML namespace of the elements you're trying to access
+ * @param string $tag Tag name
+ * @return array
+ */
+ public function get_feed_tags($namespace, $tag)
+ {
+ $type = $this->get_type();
+ if ($type & SIMPLEPIE_TYPE_ATOM_10)
+ {
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['child'][$namespace][$tag];
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_ATOM_03)
+ {
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['child'][$namespace][$tag];
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_RDF)
+ {
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['child'][$namespace][$tag];
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
+ {
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][$namespace][$tag];
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get data for an channel-level element
+ *
+ * This method allows you to get access to ANY element/attribute in the
+ * channel/header section of the feed.
+ *
+ * See {@see SimplePie::get_feed_tags()} for a description of the return value
+ *
+ * @since 1.0
+ * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
+ * @param string $namespace The URL of the XML namespace of the elements you're trying to access
+ * @param string $tag Tag name
+ * @return array
+ */
+ public function get_channel_tags($namespace, $tag)
+ {
+ $type = $this->get_type();
+ if ($type & SIMPLEPIE_TYPE_ATOM_ALL)
+ {
+ if ($return = $this->get_feed_tags($namespace, $tag))
+ {
+ return $return;
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_10)
+ {
+ if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'channel'))
+ {
+ if (isset($channel[0]['child'][$namespace][$tag]))
+ {
+ return $channel[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_090)
+ {
+ if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'channel'))
+ {
+ if (isset($channel[0]['child'][$namespace][$tag]))
+ {
+ return $channel[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
+ {
+ if ($channel = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'channel'))
+ {
+ if (isset($channel[0]['child'][$namespace][$tag]))
+ {
+ return $channel[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get data for an channel-level element
+ *
+ * This method allows you to get access to ANY element/attribute in the
+ * image/logo section of the feed.
+ *
+ * See {@see SimplePie::get_feed_tags()} for a description of the return value
+ *
+ * @since 1.0
+ * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
+ * @param string $namespace The URL of the XML namespace of the elements you're trying to access
+ * @param string $tag Tag name
+ * @return array
+ */
+ public function get_image_tags($namespace, $tag)
+ {
+ $type = $this->get_type();
+ if ($type & SIMPLEPIE_TYPE_RSS_10)
+ {
+ if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'image'))
+ {
+ if (isset($image[0]['child'][$namespace][$tag]))
+ {
+ return $image[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_090)
+ {
+ if ($image = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'image'))
+ {
+ if (isset($image[0]['child'][$namespace][$tag]))
+ {
+ return $image[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ if ($type & SIMPLEPIE_TYPE_RSS_SYNDICATION)
+ {
+ if ($image = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'image'))
+ {
+ if (isset($image[0]['child'][$namespace][$tag]))
+ {
+ return $image[0]['child'][$namespace][$tag];
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the base URL value from the feed
+ *
+ * Uses `<xml:base>` if available, otherwise uses the first link in the
+ * feed, or failing that, the URL of the feed itself.
+ *
+ * @see get_link
+ * @see subscribe_url
+ *
+ * @param array $element
+ * @return string
+ */
+ public function get_base($element = array())
+ {
+ if (!($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION) && !empty($element['xml_base_explicit']) && isset($element['xml_base']))
+ {
+ return $element['xml_base'];
+ }
+ elseif ($this->get_link() !== null)
+ {
+ return $this->get_link();
+ }
+
+ return $this->subscribe_url();
+ }
+
+ /**
+ * Sanitize feed data
+ *
+ * @access private
+ * @see SimplePie_Sanitize::sanitize()
+ * @param string $data Data to sanitize
+ * @param int $type One of the SIMPLEPIE_CONSTRUCT_* constants
+ * @param string $base Base URL to resolve URLs against
+ * @return string Sanitized data
+ */
+ public function sanitize($data, $type, $base = '')
+ {
+ try
+ {
+ return $this->sanitize->sanitize($data, $type, $base);
+ }
+ catch (SimplePie_Exception $e)
+ {
+ if (!$this->enable_exceptions)
+ {
+ $this->error = $e->getMessage();
+ $this->registry->call('Misc', 'error', array($this->error, E_USER_WARNING, $e->getFile(), $e->getLine()));
+ return '';
+ }
+
+ throw $e;
+ }
+ }
+
+ /**
+ * Get the title of the feed
+ *
+ * Uses `<atom:title>`, `<title>` or `<dc:title>`
+ *
+ * @since 1.0 (previously called `get_feed_title` since 0.8)
+ * @return string|null
+ */
+ public function get_title()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a category for the feed
+ *
+ * @since Unknown
+ * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1
+ * @return SimplePie_Category|null
+ */
+ public function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all categories for the feed
+ *
+ * Uses `<atom:category>`, `<category>` or `<dc:subject>`
+ *
+ * @since Unknown
+ * @return array|null List of {@see SimplePie_Category} objects
+ */
+ public function get_categories()
+ {
+ $categories = array();
+
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['attribs']['']['term']))
+ {
+ $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
+ {
+ // This is really the label, but keep this as the term also for BC.
+ // Label will also work on retrieving because that falls back to term.
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ if (isset($category['attribs']['']['domain']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = null;
+ }
+ $categories[] = $this->registry->create('Category', array($term, $scheme, null));
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
+ {
+ $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
+ {
+ $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+
+ if (!empty($categories))
+ {
+ return array_unique($categories);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get an author for the feed
+ *
+ * @since 1.1
+ * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1
+ * @return SimplePie_Author|null
+ */
+ public function get_author($key = 0)
+ {
+ $authors = $this->get_authors();
+ if (isset($authors[$key]))
+ {
+ return $authors[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all authors for the feed
+ *
+ * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
+ *
+ * @since 1.1
+ * @return array|null List of {@see SimplePie_Author} objects
+ */
+ public function get_authors()
+ {
+ $authors = array();
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $authors[] = $this->registry->create('Author', array($name, $uri, $email));
+ }
+ }
+ if ($author = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $authors[] = $this->registry->create('Author', array($name, $url, $email));
+ }
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
+ {
+ $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
+ {
+ $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
+ {
+ $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+
+ if (!empty($authors))
+ {
+ return array_unique($authors);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a contributor for the feed
+ *
+ * @since 1.1
+ * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1
+ * @return SimplePie_Author|null
+ */
+ public function get_contributor($key = 0)
+ {
+ $contributors = $this->get_contributors();
+ if (isset($contributors[$key]))
+ {
+ return $contributors[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all contributors for the feed
+ *
+ * Uses `<atom:contributor>`
+ *
+ * @since 1.1
+ * @return array|null List of {@see SimplePie_Author} objects
+ */
+ public function get_contributors()
+ {
+ $contributors = array();
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
+ }
+ }
+ foreach ((array) $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $contributors[] = $this->registry->create('Author', array($name, $url, $email));
+ }
+ }
+
+ if (!empty($contributors))
+ {
+ return array_unique($contributors);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a single link for the feed
+ *
+ * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
+ * @param int $key The link that you want to return. Remember that arrays begin with 0, not 1
+ * @param string $rel The relationship of the link to return
+ * @return string|null Link URL
+ */
+ public function get_link($key = 0, $rel = 'alternate')
+ {
+ $links = $this->get_links($rel);
+ if (isset($links[$key]))
+ {
+ return $links[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the permalink for the item
+ *
+ * Returns the first link available with a relationship of "alternate".
+ * Identical to {@see get_link()} with key 0
+ *
+ * @see get_link
+ * @since 1.0 (previously called `get_feed_link` since Preview Release, `get_feed_permalink()` since 0.8)
+ * @internal Added for parity between the parent-level and the item/entry-level.
+ * @return string|null Link URL
+ */
+ public function get_permalink()
+ {
+ return $this->get_link(0);
+ }
+
+ /**
+ * Get all links for the feed
+ *
+ * Uses `<atom:link>` or `<link>`
+ *
+ * @since Beta 2
+ * @param string $rel The relationship of links to return
+ * @return array|null Links found for the feed (strings)
+ */
+ public function get_links($rel = 'alternate')
+ {
+ if (!isset($this->data['links']))
+ {
+ $this->data['links'] = array();
+ if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
+ {
+ foreach ($links as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+ }
+ }
+ }
+ if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
+ {
+ foreach ($links as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+
+ }
+ }
+ }
+ if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+
+ $keys = array_keys($this->data['links']);
+ foreach ($keys as $key)
+ {
+ if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
+ {
+ if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
+ $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
+ }
+ else
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
+ }
+ }
+ elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
+ {
+ $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
+ }
+ $this->data['links'][$key] = array_unique($this->data['links'][$key]);
+ }
+ }
+
+ if (isset($this->data['headers']['link']) &&
+ preg_match('/<([^>]+)>; rel='.preg_quote($rel).'/',
+ $this->data['headers']['link'], $match))
+ {
+ return array($match[1]);
+ }
+ else if (isset($this->data['links'][$rel]))
+ {
+ return $this->data['links'][$rel];
+ }
+
+ return null;
+ }
+
+ public function get_all_discovered_feeds()
+ {
+ return $this->all_discovered_feeds;
+ }
+
+ /**
+ * Get the content for the item
+ *
+ * Uses `<atom:subtitle>`, `<atom:tagline>`, `<description>`,
+ * `<dc:description>`, `<itunes:summary>` or `<itunes:subtitle>`
+ *
+ * @since 1.0 (previously called `get_feed_description()` since 0.8)
+ * @return string|null
+ */
+ public function get_description()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the copyright info for the feed
+ *
+ * Uses `<atom:rights>`, `<atom:copyright>` or `<dc:rights>`
+ *
+ * @since 1.0 (previously called `get_feed_copyright()` since 0.8)
+ * @return string|null
+ */
+ public function get_copyright()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the language for the feed
+ *
+ * Uses `<language>`, `<dc:language>`, or @xml_lang
+ *
+ * @since 1.0 (previously called `get_feed_language()` since 0.8)
+ * @return string|null
+ */
+ public function get_language()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang']))
+ {
+ return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang']))
+ {
+ return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang']))
+ {
+ return $this->sanitize($this->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($this->data['headers']['content-language']))
+ {
+ return $this->sanitize($this->data['headers']['content-language'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the latitude coordinates for the item
+ *
+ * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
+ *
+ * Uses `<geo:lat>` or `<georss:point>`
+ *
+ * @since 1.0
+ * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
+ * @link http://www.georss.org/ GeoRSS
+ * @return string|null
+ */
+ public function get_latitude()
+ {
+
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
+ {
+ return (float) $match[1];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the longitude coordinates for the feed
+ *
+ * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
+ *
+ * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>`
+ *
+ * @since 1.0
+ * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
+ * @link http://www.georss.org/ GeoRSS
+ * @return string|null
+ */
+ public function get_longitude()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
+ {
+ return (float) $match[2];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the feed logo's title
+ *
+ * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" title.
+ *
+ * Uses `<image><title>` or `<image><dc:title>`
+ *
+ * @return string|null
+ */
+ public function get_image_title()
+ {
+ if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the feed logo's URL
+ *
+ * RSS 0.9.0, 2.0, Atom 1.0, and feeds with iTunes RSS tags are allowed to
+ * have a "feed logo" URL. This points directly to the image itself.
+ *
+ * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
+ * `<image><title>` or `<image><dc:title>`
+ *
+ * @return string|null
+ */
+ public function get_image_url()
+ {
+ if ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
+ {
+ return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'url'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'url'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+
+ return null;
+ }
+
+
+ /**
+ * Get the feed logo's link
+ *
+ * RSS 0.9.0, 1.0 and 2.0 feeds are allowed to have a "feed logo" link. This
+ * points to a human-readable page that the image should link to.
+ *
+ * Uses `<itunes:image>`, `<atom:logo>`, `<atom:icon>`,
+ * `<image><title>` or `<image><dc:title>`
+ *
+ * @return string|null
+ */
+ public function get_image_link()
+ {
+ if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the feed logo's link
+ *
+ * RSS 2.0 feeds are allowed to have a "feed logo" width.
+ *
+ * Uses `<image><width>` or defaults to 88.0 if no width is specified and
+ * the feed is an RSS 2.0 feed.
+ *
+ * @return int|float|null
+ */
+ public function get_image_width()
+ {
+ if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'width'))
+ {
+ return round($return[0]['data']);
+ }
+ elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
+ {
+ return 88.0;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the feed logo's height
+ *
+ * RSS 2.0 feeds are allowed to have a "feed logo" height.
+ *
+ * Uses `<image><height>` or defaults to 31.0 if no height is specified and
+ * the feed is an RSS 2.0 feed.
+ *
+ * @return int|float|null
+ */
+ public function get_image_height()
+ {
+ if ($return = $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'height'))
+ {
+ return round($return[0]['data']);
+ }
+ elseif ($this->get_type() & SIMPLEPIE_TYPE_RSS_SYNDICATION && $this->get_image_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'url'))
+ {
+ return 31.0;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the number of items in the feed
+ *
+ * This is well-suited for {@link http://php.net/for for()} loops with
+ * {@see get_item()}
+ *
+ * @param int $max Maximum value to return. 0 for no limit
+ * @return int Number of items in the feed
+ */
+ public function get_item_quantity($max = 0)
+ {
+ $max = (int) $max;
+ $qty = count($this->get_items());
+ if ($max === 0)
+ {
+ return $qty;
+ }
+
+ return ($qty > $max) ? $max : $qty;
+ }
+
+ /**
+ * Get a single item from the feed
+ *
+ * This is better suited for {@link http://php.net/for for()} loops, whereas
+ * {@see get_items()} is better suited for
+ * {@link http://php.net/foreach foreach()} loops.
+ *
+ * @see get_item_quantity()
+ * @since Beta 2
+ * @param int $key The item that you want to return. Remember that arrays begin with 0, not 1
+ * @return SimplePie_Item|null
+ */
+ public function get_item($key = 0)
+ {
+ $items = $this->get_items();
+ if (isset($items[$key]))
+ {
+ return $items[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all items from the feed
+ *
+ * This is better suited for {@link http://php.net/for for()} loops, whereas
+ * {@see get_items()} is better suited for
+ * {@link http://php.net/foreach foreach()} loops.
+ *
+ * @see get_item_quantity
+ * @since Beta 2
+ * @param int $start Index to start at
+ * @param int $end Number of items to return. 0 for all items after `$start`
+ * @return SimplePie_Item[]|null List of {@see SimplePie_Item} objects
+ */
+ public function get_items($start = 0, $end = 0)
+ {
+ if (!isset($this->data['items']))
+ {
+ if (!empty($this->multifeed_objects))
+ {
+ $this->data['items'] = SimplePie::merge_items($this->multifeed_objects, $start, $end, $this->item_limit);
+ if (empty($this->data['items']))
+ {
+ return array();
+ }
+ return $this->data['items'];
+ }
+ $this->data['items'] = array();
+ if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'entry'))
+ {
+ $keys = array_keys($items);
+ foreach ($keys as $key)
+ {
+ $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
+ }
+ }
+ if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'entry'))
+ {
+ $keys = array_keys($items);
+ foreach ($keys as $key)
+ {
+ $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
+ }
+ }
+ if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'item'))
+ {
+ $keys = array_keys($items);
+ foreach ($keys as $key)
+ {
+ $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
+ }
+ }
+ if ($items = $this->get_feed_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'item'))
+ {
+ $keys = array_keys($items);
+ foreach ($keys as $key)
+ {
+ $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
+ }
+ }
+ if ($items = $this->get_channel_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'item'))
+ {
+ $keys = array_keys($items);
+ foreach ($keys as $key)
+ {
+ $this->data['items'][] = $this->registry->create('Item', array($this, $items[$key]));
+ }
+ }
+ }
+
+ if (empty($this->data['items']))
+ {
+ return array();
+ }
+
+ if ($this->order_by_date)
+ {
+ if (!isset($this->data['ordered_items']))
+ {
+ $this->data['ordered_items'] = $this->data['items'];
+ usort($this->data['ordered_items'], array(get_class($this), 'sort_items'));
+ }
+ $items = $this->data['ordered_items'];
+ }
+ else
+ {
+ $items = $this->data['items'];
+ }
+ // Slice the data as desired
+ if ($end === 0)
+ {
+ return array_slice($items, $start);
+ }
+
+ return array_slice($items, $start, $end);
+ }
+
+ /**
+ * Set the favicon handler
+ *
+ * @deprecated Use your own favicon handling instead
+ */
+ public function set_favicon_handler($page = false, $qs = 'i')
+ {
+ $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
+ trigger_error('Favicon handling has been removed, please use your own handling', $level);
+ return false;
+ }
+
+ /**
+ * Get the favicon for the current feed
+ *
+ * @deprecated Use your own favicon handling instead
+ */
+ public function get_favicon()
+ {
+ $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
+ trigger_error('Favicon handling has been removed, please use your own handling', $level);
+
+ if (($url = $this->get_link()) !== null)
+ {
+ return 'https://www.google.com/s2/favicons?domain=' . urlencode($url);
+ }
+
+ return false;
+ }
+
+ /**
+ * Magic method handler
+ *
+ * @param string $method Method name
+ * @param array $args Arguments to the method
+ * @return mixed
+ */
+ public function __call($method, $args)
+ {
+ if (strpos($method, 'subscribe_') === 0)
+ {
+ $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
+ trigger_error('subscribe_*() has been deprecated, implement the callback yourself', $level);
+ return '';
+ }
+ if ($method === 'enable_xml_dump')
+ {
+ $level = defined('E_USER_DEPRECATED') ? E_USER_DEPRECATED : E_USER_WARNING;
+ trigger_error('enable_xml_dump() has been deprecated, use get_raw_data() instead', $level);
+ return false;
+ }
+
+ $class = get_class($this);
+ $trace = debug_backtrace();
+ $file = $trace[0]['file'];
+ $line = $trace[0]['line'];
+ trigger_error("Call to undefined method $class::$method() in $file on line $line", E_USER_ERROR);
+ }
+
+ /**
+ * Sorting callback for items
+ *
+ * @access private
+ * @param SimplePie $a
+ * @param SimplePie $b
+ * @return boolean
+ */
+ public static function sort_items($a, $b)
+ {
+ $a_date = $a->get_date('U');
+ $b_date = $b->get_date('U');
+ if ($a_date && $b_date) {
+ return $a_date > $b_date ? -1 : 1;
+ }
+ // Sort items without dates to the top.
+ if ($a_date) {
+ return 1;
+ }
+ if ($b_date) {
+ return -1;
+ }
+ return 0;
+ }
+
+ /**
+ * Merge items from several feeds into one
+ *
+ * If you're merging multiple feeds together, they need to all have dates
+ * for the items or else SimplePie will refuse to sort them.
+ *
+ * @link http://simplepie.org/wiki/tutorial/sort_multiple_feeds_by_time_and_date#if_feeds_require_separate_per-feed_settings
+ * @param array $urls List of SimplePie feed objects to merge
+ * @param int $start Starting item
+ * @param int $end Number of items to return
+ * @param int $limit Maximum number of items per feed
+ * @return array
+ */
+ public static function merge_items($urls, $start = 0, $end = 0, $limit = 0)
+ {
+ if (is_array($urls) && sizeof($urls) > 0)
+ {
+ $items = array();
+ foreach ($urls as $arg)
+ {
+ if ($arg instanceof SimplePie)
+ {
+ $items = array_merge($items, $arg->get_items(0, $limit));
+ }
+ else
+ {
+ trigger_error('Arguments must be SimplePie objects', E_USER_WARNING);
+ }
+ }
+
+ usort($items, array(get_class($urls[0]), 'sort_items'));
+
+ if ($end === 0)
+ {
+ return array_slice($items, $start);
+ }
+
+ return array_slice($items, $start, $end);
+ }
+
+ trigger_error('Cannot merge zero SimplePie objects', E_USER_WARNING);
+ return array();
+ }
+
+ /**
+ * Store PubSubHubbub links as headers
+ *
+ * There is no way to find PuSH links in the body of a microformats feed,
+ * so they are added to the headers when found, to be used later by get_links.
+ * @param SimplePie_File $file
+ * @param string $hub
+ * @param string $self
+ */
+ private function store_links(&$file, $hub, $self) {
+ if (isset($file->headers['link']['hub']) ||
+ (isset($file->headers['link']) &&
+ preg_match('/rel=hub/', $file->headers['link'])))
+ {
+ return;
+ }
+
+ if ($hub)
+ {
+ if (isset($file->headers['link']))
+ {
+ if ($file->headers['link'] !== '')
+ {
+ $file->headers['link'] = ', ';
+ }
+ }
+ else
+ {
+ $file->headers['link'] = '';
+ }
+ $file->headers['link'] .= '<'.$hub.'>; rel=hub';
+ if ($self)
+ {
+ $file->headers['link'] .= ', <'.$self.'>; rel=self';
+ }
+ }
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Author.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Author.php
new file mode 100644
index 0000000..563932f
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Author.php
@@ -0,0 +1,149 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Manages all author-related data
+ *
+ * Used by {@see SimplePie_Item::get_author()} and {@see SimplePie::get_authors()}
+ *
+ * This class can be overloaded with {@see SimplePie::set_author_class()}
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Author
+{
+ /**
+ * Author's name
+ *
+ * @var string
+ * @see get_name()
+ */
+ var $name;
+
+ /**
+ * Author's link
+ *
+ * @var string
+ * @see get_link()
+ */
+ var $link;
+
+ /**
+ * Author's email address
+ *
+ * @var string
+ * @see get_email()
+ */
+ var $email;
+
+ /**
+ * Constructor, used to input the data
+ *
+ * @param string $name
+ * @param string $link
+ * @param string $email
+ */
+ public function __construct($name = null, $link = null, $email = null)
+ {
+ $this->name = $name;
+ $this->link = $link;
+ $this->email = $email;
+ }
+
+ /**
+ * String-ified version
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ /**
+ * Author's name
+ *
+ * @return string|null
+ */
+ public function get_name()
+ {
+ if ($this->name !== null)
+ {
+ return $this->name;
+ }
+
+ return null;
+ }
+
+ /**
+ * Author's link
+ *
+ * @return string|null
+ */
+ public function get_link()
+ {
+ if ($this->link !== null)
+ {
+ return $this->link;
+ }
+
+ return null;
+ }
+
+ /**
+ * Author's email address
+ *
+ * @return string|null
+ */
+ public function get_email()
+ {
+ if ($this->email !== null)
+ {
+ return $this->email;
+ }
+
+ return null;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache.php
new file mode 100644
index 0000000..9c5577d
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Used to create cache objects
+ *
+ * This class can be overloaded with {@see SimplePie::set_cache_class()},
+ * although the preferred way is to create your own handler
+ * via {@see register()}
+ *
+ * @package SimplePie
+ * @subpackage Caching
+ */
+class SimplePie_Cache
+{
+ /**
+ * Cache handler classes
+ *
+ * These receive 3 parameters to their constructor, as documented in
+ * {@see register()}
+ * @var array
+ */
+ protected static $handlers = array(
+ 'mysql' => 'SimplePie_Cache_MySQL',
+ 'memcache' => 'SimplePie_Cache_Memcache',
+ 'memcached' => 'SimplePie_Cache_Memcached',
+ 'redis' => 'SimplePie_Cache_Redis'
+ );
+
+ /**
+ * Don't call the constructor. Please.
+ */
+ private function __construct() { }
+
+ /**
+ * Create a new SimplePie_Cache object
+ *
+ * @param string $location URL location (scheme is used to determine handler)
+ * @param string $filename Unique identifier for cache object
+ * @param string $extension 'spi' or 'spc'
+ * @return SimplePie_Cache_Base Type of object depends on scheme of `$location`
+ */
+ public static function get_handler($location, $filename, $extension)
+ {
+ $type = explode(':', $location, 2);
+ $type = $type[0];
+ if (!empty(self::$handlers[$type]))
+ {
+ $class = self::$handlers[$type];
+ return new $class($location, $filename, $extension);
+ }
+
+ return new SimplePie_Cache_File($location, $filename, $extension);
+ }
+
+ /**
+ * Create a new SimplePie_Cache object
+ *
+ * @deprecated Use {@see get_handler} instead
+ */
+ public function create($location, $filename, $extension)
+ {
+ trigger_error('Cache::create() has been replaced with Cache::get_handler(). Switch to the registry system to use this.', E_USER_DEPRECATED);
+ return self::get_handler($location, $filename, $extension);
+ }
+
+ /**
+ * Register a handler
+ *
+ * @param string $type DSN type to register for
+ * @param string $class Name of handler class. Must implement SimplePie_Cache_Base
+ */
+ public static function register($type, $class)
+ {
+ self::$handlers[$type] = $class;
+ }
+
+ /**
+ * Parse a URL into an array
+ *
+ * @param string $url
+ * @return array
+ */
+ public static function parse_URL($url)
+ {
+ $params = parse_url($url);
+ $params['extras'] = array();
+ if (isset($params['query']))
+ {
+ parse_str($params['query'], $params['extras']);
+ }
+ return $params;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Base.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Base.php
new file mode 100644
index 0000000..522ff7e
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Base.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Base for cache objects
+ *
+ * Classes to be used with {@see SimplePie_Cache::register()} are expected
+ * to implement this interface.
+ *
+ * @package SimplePie
+ * @subpackage Caching
+ */
+interface SimplePie_Cache_Base
+{
+ /**
+ * Feed cache type
+ *
+ * @var string
+ */
+ const TYPE_FEED = 'spc';
+
+ /**
+ * Image cache type
+ *
+ * @var string
+ */
+ const TYPE_IMAGE = 'spi';
+
+ /**
+ * Create a new cache object
+ *
+ * @param string $location Location string (from SimplePie::$cache_location)
+ * @param string $name Unique ID for the cache
+ * @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
+ */
+ public function __construct($location, $name, $type);
+
+ /**
+ * Save data to the cache
+ *
+ * @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
+ * @return bool Successfulness
+ */
+ public function save($data);
+
+ /**
+ * Retrieve the data saved to the cache
+ *
+ * @return array Data for SimplePie::$data
+ */
+ public function load();
+
+ /**
+ * Retrieve the last modified time for the cache
+ *
+ * @return int Timestamp
+ */
+ public function mtime();
+
+ /**
+ * Set the last modified time to the current time
+ *
+ * @return bool Success status
+ */
+ public function touch();
+
+ /**
+ * Remove the cache
+ *
+ * @return bool Success status
+ */
+ public function unlink();
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/DB.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/DB.php
new file mode 100644
index 0000000..74d57b8
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/DB.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Base class for database-based caches
+ *
+ * @package SimplePie
+ * @subpackage Caching
+ */
+abstract class SimplePie_Cache_DB implements SimplePie_Cache_Base
+{
+ /**
+ * Helper for database conversion
+ *
+ * Converts a given {@see SimplePie} object into data to be stored
+ *
+ * @param SimplePie $data
+ * @return array First item is the serialized data for storage, second item is the unique ID for this item
+ */
+ protected static function prepare_simplepie_object_for_cache($data)
+ {
+ $items = $data->get_items();
+ $items_by_id = array();
+
+ if (!empty($items))
+ {
+ foreach ($items as $item)
+ {
+ $items_by_id[$item->get_id()] = $item;
+ }
+
+ if (count($items_by_id) !== count($items))
+ {
+ $items_by_id = array();
+ foreach ($items as $item)
+ {
+ $items_by_id[$item->get_id(true)] = $item;
+ }
+ }
+
+ if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
+ {
+ $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
+ }
+ elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
+ {
+ $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
+ }
+ elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
+ {
+ $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
+ }
+ elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]))
+ {
+ $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0];
+ }
+ else
+ {
+ $channel = null;
+ }
+
+ if ($channel !== null)
+ {
+ if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']))
+ {
+ unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']);
+ }
+ if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']))
+ {
+ unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']);
+ }
+ if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']))
+ {
+ unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']);
+ }
+ if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']))
+ {
+ unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']);
+ }
+ if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']))
+ {
+ unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']);
+ }
+ }
+ if (isset($data->data['items']))
+ {
+ unset($data->data['items']);
+ }
+ if (isset($data->data['ordered_items']))
+ {
+ unset($data->data['ordered_items']);
+ }
+ }
+ return array(serialize($data->data), $items_by_id);
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/File.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/File.php
new file mode 100644
index 0000000..03758e9
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/File.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Caches data to the filesystem
+ *
+ * @package SimplePie
+ * @subpackage Caching
+ */
+class SimplePie_Cache_File implements SimplePie_Cache_Base
+{
+ /**
+ * Location string
+ *
+ * @see SimplePie::$cache_location
+ * @var string
+ */
+ protected $location;
+
+ /**
+ * Filename
+ *
+ * @var string
+ */
+ protected $filename;
+
+ /**
+ * File extension
+ *
+ * @var string
+ */
+ protected $extension;
+
+ /**
+ * File path
+ *
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * Create a new cache object
+ *
+ * @param string $location Location string (from SimplePie::$cache_location)
+ * @param string $name Unique ID for the cache
+ * @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
+ */
+ public function __construct($location, $name, $type)
+ {
+ $this->location = $location;
+ $this->filename = $name;
+ $this->extension = $type;
+ $this->name = "$this->location/$this->filename.$this->extension";
+ }
+
+ /**
+ * Save data to the cache
+ *
+ * @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
+ * @return bool Successfulness
+ */
+ public function save($data)
+ {
+ if (file_exists($this->name) && is_writable($this->name) || file_exists($this->location) && is_writable($this->location))
+ {
+ if ($data instanceof SimplePie)
+ {
+ $data = $data->data;
+ }
+
+ $data = serialize($data);
+ return (bool) file_put_contents($this->name, $data);
+ }
+ return false;
+ }
+
+ /**
+ * Retrieve the data saved to the cache
+ *
+ * @return array Data for SimplePie::$data
+ */
+ public function load()
+ {
+ if (file_exists($this->name) && is_readable($this->name))
+ {
+ return unserialize(file_get_contents($this->name));
+ }
+ return false;
+ }
+
+ /**
+ * Retrieve the last modified time for the cache
+ *
+ * @return int Timestamp
+ */
+ public function mtime()
+ {
+ return @filemtime($this->name);
+ }
+
+ /**
+ * Set the last modified time to the current time
+ *
+ * @return bool Success status
+ */
+ public function touch()
+ {
+ return @touch($this->name);
+ }
+
+ /**
+ * Remove the cache
+ *
+ * @return bool Success status
+ */
+ public function unlink()
+ {
+ if (file_exists($this->name))
+ {
+ return unlink($this->name);
+ }
+ return false;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Memcache.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Memcache.php
new file mode 100644
index 0000000..caf7852
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Memcache.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Caches data to memcache
+ *
+ * Registered for URLs with the "memcache" protocol
+ *
+ * For example, `memcache://localhost:11211/?timeout=3600&prefix=sp_` will
+ * connect to memcache on `localhost` on port 11211. All tables will be
+ * prefixed with `sp_` and data will expire after 3600 seconds
+ *
+ * @package SimplePie
+ * @subpackage Caching
+ * @uses Memcache
+ */
+class SimplePie_Cache_Memcache implements SimplePie_Cache_Base
+{
+ /**
+ * Memcache instance
+ *
+ * @var Memcache
+ */
+ protected $cache;
+
+ /**
+ * Options
+ *
+ * @var array
+ */
+ protected $options;
+
+ /**
+ * Cache name
+ *
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * Create a new cache object
+ *
+ * @param string $location Location string (from SimplePie::$cache_location)
+ * @param string $name Unique ID for the cache
+ * @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
+ */
+ public function __construct($location, $name, $type)
+ {
+ $this->options = array(
+ 'host' => '127.0.0.1',
+ 'port' => 11211,
+ 'extras' => array(
+ 'timeout' => 3600, // one hour
+ 'prefix' => 'simplepie_',
+ ),
+ );
+ $this->options = SimplePie_Misc::array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location));
+
+ $this->name = $this->options['extras']['prefix'] . md5("$name:$type");
+
+ $this->cache = new Memcache();
+ $this->cache->addServer($this->options['host'], (int) $this->options['port']);
+ }
+
+ /**
+ * Save data to the cache
+ *
+ * @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
+ * @return bool Successfulness
+ */
+ public function save($data)
+ {
+ if ($data instanceof SimplePie)
+ {
+ $data = $data->data;
+ }
+ return $this->cache->set($this->name, serialize($data), MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']);
+ }
+
+ /**
+ * Retrieve the data saved to the cache
+ *
+ * @return array Data for SimplePie::$data
+ */
+ public function load()
+ {
+ $data = $this->cache->get($this->name);
+
+ if ($data !== false)
+ {
+ return unserialize($data);
+ }
+ return false;
+ }
+
+ /**
+ * Retrieve the last modified time for the cache
+ *
+ * @return int Timestamp
+ */
+ public function mtime()
+ {
+ $data = $this->cache->get($this->name);
+
+ if ($data !== false)
+ {
+ // essentially ignore the mtime because Memcache expires on its own
+ return time();
+ }
+
+ return false;
+ }
+
+ /**
+ * Set the last modified time to the current time
+ *
+ * @return bool Success status
+ */
+ public function touch()
+ {
+ $data = $this->cache->get($this->name);
+
+ if ($data !== false)
+ {
+ return $this->cache->set($this->name, $data, MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']);
+ }
+
+ return false;
+ }
+
+ /**
+ * Remove the cache
+ *
+ * @return bool Success status
+ */
+ public function unlink()
+ {
+ return $this->cache->delete($this->name, 0);
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Memcached.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Memcached.php
new file mode 100755
index 0000000..0b40d87
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Memcached.php
@@ -0,0 +1,166 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Caches data to memcached
+ *
+ * Registered for URLs with the "memcached" protocol
+ *
+ * For example, `memcached://localhost:11211/?timeout=3600&prefix=sp_` will
+ * connect to memcached on `localhost` on port 11211. All tables will be
+ * prefixed with `sp_` and data will expire after 3600 seconds
+ *
+ * @package SimplePie
+ * @subpackage Caching
+ * @author Paul L. McNeely
+ * @uses Memcached
+ */
+class SimplePie_Cache_Memcached implements SimplePie_Cache_Base
+{
+ /**
+ * Memcached instance
+ * @var Memcached
+ */
+ protected $cache;
+
+ /**
+ * Options
+ * @var array
+ */
+ protected $options;
+
+ /**
+ * Cache name
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * Create a new cache object
+ * @param string $location Location string (from SimplePie::$cache_location)
+ * @param string $name Unique ID for the cache
+ * @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
+ */
+ public function __construct($location, $name, $type) {
+ $this->options = array(
+ 'host' => '127.0.0.1',
+ 'port' => 11211,
+ 'extras' => array(
+ 'timeout' => 3600, // one hour
+ 'prefix' => 'simplepie_',
+ ),
+ );
+ $this->options = SimplePie_Misc::array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location));
+
+ $this->name = $this->options['extras']['prefix'] . md5("$name:$type");
+
+ $this->cache = new Memcached();
+ $this->cache->addServer($this->options['host'], (int)$this->options['port']);
+ }
+
+ /**
+ * Save data to the cache
+ * @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
+ * @return bool Successfulness
+ */
+ public function save($data) {
+ if ($data instanceof SimplePie) {
+ $data = $data->data;
+ }
+
+ return $this->setData(serialize($data));
+ }
+
+ /**
+ * Retrieve the data saved to the cache
+ * @return array Data for SimplePie::$data
+ */
+ public function load() {
+ $data = $this->cache->get($this->name);
+
+ if ($data !== false) {
+ return unserialize($data);
+ }
+ return false;
+ }
+
+ /**
+ * Retrieve the last modified time for the cache
+ * @return int Timestamp
+ */
+ public function mtime() {
+ $data = $this->cache->get($this->name . '_mtime');
+ return (int) $data;
+ }
+
+ /**
+ * Set the last modified time to the current time
+ * @return bool Success status
+ */
+ public function touch() {
+ $data = $this->cache->get($this->name);
+ return $this->setData($data);
+ }
+
+ /**
+ * Remove the cache
+ * @return bool Success status
+ */
+ public function unlink() {
+ return $this->cache->delete($this->name, 0);
+ }
+
+ /**
+ * Set the last modified time and data to Memcached
+ * @return bool Success status
+ */
+ private function setData($data) {
+
+ if ($data !== false) {
+ $this->cache->set($this->name . '_mtime', time(), (int)$this->options['extras']['timeout']);
+ return $this->cache->set($this->name, $data, (int)$this->options['extras']['timeout']);
+ }
+
+ return false;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/MySQL.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/MySQL.php
new file mode 100644
index 0000000..a684eb8
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/MySQL.php
@@ -0,0 +1,440 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Caches data to a MySQL database
+ *
+ * Registered for URLs with the "mysql" protocol
+ *
+ * For example, `mysql://root:password@localhost:3306/mydb?prefix=sp_` will
+ * connect to the `mydb` database on `localhost` on port 3306, with the user
+ * `root` and the password `password`. All tables will be prefixed with `sp_`
+ *
+ * @package SimplePie
+ * @subpackage Caching
+ */
+class SimplePie_Cache_MySQL extends SimplePie_Cache_DB
+{
+ /**
+ * PDO instance
+ *
+ * @var PDO
+ */
+ protected $mysql;
+
+ /**
+ * Options
+ *
+ * @var array
+ */
+ protected $options;
+
+ /**
+ * Cache ID
+ *
+ * @var string
+ */
+ protected $id;
+
+ /**
+ * Create a new cache object
+ *
+ * @param string $location Location string (from SimplePie::$cache_location)
+ * @param string $name Unique ID for the cache
+ * @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
+ */
+ public function __construct($location, $name, $type)
+ {
+ $this->options = array(
+ 'user' => null,
+ 'pass' => null,
+ 'host' => '127.0.0.1',
+ 'port' => '3306',
+ 'path' => '',
+ 'extras' => array(
+ 'prefix' => '',
+ 'cache_purge_time' => 2592000
+ ),
+ );
+
+ $this->options = SimplePie_Misc::array_merge_recursive($this->options, SimplePie_Cache::parse_URL($location));
+
+ // Path is prefixed with a "/"
+ $this->options['dbname'] = substr($this->options['path'], 1);
+
+ try
+ {
+ $this->mysql = new PDO("mysql:dbname={$this->options['dbname']};host={$this->options['host']};port={$this->options['port']}", $this->options['user'], $this->options['pass'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
+ }
+ catch (PDOException $e)
+ {
+ $this->mysql = null;
+ return;
+ }
+
+ $this->id = $name . $type;
+
+ if (!$query = $this->mysql->query('SHOW TABLES'))
+ {
+ $this->mysql = null;
+ return;
+ }
+
+ $db = array();
+ while ($row = $query->fetchColumn())
+ {
+ $db[] = $row;
+ }
+
+ if (!in_array($this->options['extras']['prefix'] . 'cache_data', $db))
+ {
+ $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'cache_data` (`id` TEXT CHARACTER SET utf8 NOT NULL, `items` SMALLINT NOT NULL DEFAULT 0, `data` BLOB NOT NULL, `mtime` INT UNSIGNED NOT NULL, UNIQUE (`id`(125)))');
+ if ($query === false)
+ {
+ trigger_error("Can't create " . $this->options['extras']['prefix'] . "cache_data table, check permissions", E_USER_WARNING);
+ $this->mysql = null;
+ return;
+ }
+ }
+
+ if (!in_array($this->options['extras']['prefix'] . 'items', $db))
+ {
+ $query = $this->mysql->exec('CREATE TABLE `' . $this->options['extras']['prefix'] . 'items` (`feed_id` TEXT CHARACTER SET utf8 NOT NULL, `id` TEXT CHARACTER SET utf8 NOT NULL, `data` MEDIUMBLOB NOT NULL, `posted` INT UNSIGNED NOT NULL, INDEX `feed_id` (`feed_id`(125)))');
+ if ($query === false)
+ {
+ trigger_error("Can't create " . $this->options['extras']['prefix'] . "items table, check permissions", E_USER_WARNING);
+ $this->mysql = null;
+ return;
+ }
+ }
+ }
+
+ /**
+ * Save data to the cache
+ *
+ * @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
+ * @return bool Successfulness
+ */
+ public function save($data)
+ {
+ if ($this->mysql === null)
+ {
+ return false;
+ }
+
+ $query = $this->mysql->prepare('DELETE i, cd FROM `' . $this->options['extras']['prefix'] . 'cache_data` cd, ' .
+ '`' . $this->options['extras']['prefix'] . 'items` i ' .
+ 'WHERE cd.id = i.feed_id ' .
+ 'AND cd.mtime < (unix_timestamp() - :purge_time)');
+ $query->bindValue(':purge_time', $this->options['extras']['cache_purge_time']);
+
+ if (!$query->execute())
+ {
+ return false;
+ }
+
+ if ($data instanceof SimplePie)
+ {
+ $data = clone $data;
+
+ $prepared = self::prepare_simplepie_object_for_cache($data);
+
+ $query = $this->mysql->prepare('SELECT COUNT(*) FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
+ $query->bindValue(':feed', $this->id);
+ if ($query->execute())
+ {
+ if ($query->fetchColumn() > 0)
+ {
+ $items = count($prepared[1]);
+ if ($items)
+ {
+ $sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = :items, `data` = :data, `mtime` = :time WHERE `id` = :feed';
+ $query = $this->mysql->prepare($sql);
+ $query->bindValue(':items', $items);
+ }
+ else
+ {
+ $sql = 'UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `data` = :data, `mtime` = :time WHERE `id` = :feed';
+ $query = $this->mysql->prepare($sql);
+ }
+
+ $query->bindValue(':data', $prepared[0]);
+ $query->bindValue(':time', time());
+ $query->bindValue(':feed', $this->id);
+ if (!$query->execute())
+ {
+ return false;
+ }
+ }
+ else
+ {
+ $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:feed, :count, :data, :time)');
+ $query->bindValue(':feed', $this->id);
+ $query->bindValue(':count', count($prepared[1]));
+ $query->bindValue(':data', $prepared[0]);
+ $query->bindValue(':time', time());
+ if (!$query->execute())
+ {
+ return false;
+ }
+ }
+
+ $ids = array_keys($prepared[1]);
+ if (!empty($ids))
+ {
+ foreach ($ids as $id)
+ {
+ $database_ids[] = $this->mysql->quote($id);
+ }
+
+ $query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `id` = ' . implode(' OR `id` = ', $database_ids) . ' AND `feed_id` = :feed');
+ $query->bindValue(':feed', $this->id);
+
+ if ($query->execute())
+ {
+ $existing_ids = array();
+ while ($row = $query->fetchColumn())
+ {
+ $existing_ids[] = $row;
+ }
+
+ $new_ids = array_diff($ids, $existing_ids);
+
+ foreach ($new_ids as $new_id)
+ {
+ if (!($date = $prepared[1][$new_id]->get_date('U')))
+ {
+ $date = time();
+ }
+
+ $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'items` (`feed_id`, `id`, `data`, `posted`) VALUES(:feed, :id, :data, :date)');
+ $query->bindValue(':feed', $this->id);
+ $query->bindValue(':id', $new_id);
+ $query->bindValue(':data', serialize($prepared[1][$new_id]->data));
+ $query->bindValue(':date', $date);
+ if (!$query->execute())
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ else
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ $query = $this->mysql->prepare('SELECT `id` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :feed');
+ $query->bindValue(':feed', $this->id);
+ if ($query->execute())
+ {
+ if ($query->rowCount() > 0)
+ {
+ $query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `items` = 0, `data` = :data, `mtime` = :time WHERE `id` = :feed');
+ $query->bindValue(':data', serialize($data));
+ $query->bindValue(':time', time());
+ $query->bindValue(':feed', $this->id);
+ if ($this->execute())
+ {
+ return true;
+ }
+ }
+ else
+ {
+ $query = $this->mysql->prepare('INSERT INTO `' . $this->options['extras']['prefix'] . 'cache_data` (`id`, `items`, `data`, `mtime`) VALUES(:id, 0, :data, :time)');
+ $query->bindValue(':id', $this->id);
+ $query->bindValue(':data', serialize($data));
+ $query->bindValue(':time', time());
+ if ($query->execute())
+ {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Retrieve the data saved to the cache
+ *
+ * @return array Data for SimplePie::$data
+ */
+ public function load()
+ {
+ if ($this->mysql === null)
+ {
+ return false;
+ }
+
+ $query = $this->mysql->prepare('SELECT `items`, `data` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
+ $query->bindValue(':id', $this->id);
+ if ($query->execute() && ($row = $query->fetch()))
+ {
+ $data = unserialize($row[1]);
+
+ if (isset($this->options['items'][0]))
+ {
+ $items = (int) $this->options['items'][0];
+ }
+ else
+ {
+ $items = (int) $row[0];
+ }
+
+ if ($items !== 0)
+ {
+ if (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]))
+ {
+ $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0];
+ }
+ elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]))
+ {
+ $feed =& $data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0];
+ }
+ elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]))
+ {
+ $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0];
+ }
+ elseif (isset($data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]))
+ {
+ $feed =& $data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0];
+ }
+ else
+ {
+ $feed = null;
+ }
+
+ if ($feed !== null)
+ {
+ $sql = 'SELECT `data` FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :feed ORDER BY `posted` DESC';
+ if ($items > 0)
+ {
+ $sql .= ' LIMIT ' . $items;
+ }
+
+ $query = $this->mysql->prepare($sql);
+ $query->bindValue(':feed', $this->id);
+ if ($query->execute())
+ {
+ while ($row = $query->fetchColumn())
+ {
+ $feed['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'][] = unserialize($row);
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+ return $data;
+ }
+ return false;
+ }
+
+ /**
+ * Retrieve the last modified time for the cache
+ *
+ * @return int Timestamp
+ */
+ public function mtime()
+ {
+ if ($this->mysql === null)
+ {
+ return false;
+ }
+
+ $query = $this->mysql->prepare('SELECT `mtime` FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
+ $query->bindValue(':id', $this->id);
+ if ($query->execute() && ($time = $query->fetchColumn()))
+ {
+ return $time;
+ }
+
+ return false;
+ }
+
+ /**
+ * Set the last modified time to the current time
+ *
+ * @return bool Success status
+ */
+ public function touch()
+ {
+ if ($this->mysql === null)
+ {
+ return false;
+ }
+
+ $query = $this->mysql->prepare('UPDATE `' . $this->options['extras']['prefix'] . 'cache_data` SET `mtime` = :time WHERE `id` = :id');
+ $query->bindValue(':time', time());
+ $query->bindValue(':id', $this->id);
+
+ return $query->execute() && $query->rowCount() > 0;
+ }
+
+ /**
+ * Remove the cache
+ *
+ * @return bool Success status
+ */
+ public function unlink()
+ {
+ if ($this->mysql === null)
+ {
+ return false;
+ }
+
+ $query = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'cache_data` WHERE `id` = :id');
+ $query->bindValue(':id', $this->id);
+ $query2 = $this->mysql->prepare('DELETE FROM `' . $this->options['extras']['prefix'] . 'items` WHERE `feed_id` = :id');
+ $query2->bindValue(':id', $this->id);
+
+ return $query->execute() && $query2->execute();
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Redis.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Redis.php
new file mode 100644
index 0000000..dbc88e8
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Cache/Redis.php
@@ -0,0 +1,172 @@
+<?php
+
+/**
+ * SimplePie Redis Cache Extension
+ *
+ * @package SimplePie
+ * @author Jan Kozak <galvani78@gmail.com>
+ * @link http://galvani.cz/
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ * @version 0.2.9
+ */
+
+
+/**
+ * Caches data to redis
+ *
+ * Registered for URLs with the "redis" protocol
+ *
+ * For example, `redis://localhost:6379/?timeout=3600&prefix=sp_&dbIndex=0` will
+ * connect to redis on `localhost` on port 6379. All tables will be
+ * prefixed with `simple_primary-` and data will expire after 3600 seconds
+ *
+ * @package SimplePie
+ * @subpackage Caching
+ * @uses Redis
+ */
+class SimplePie_Cache_Redis implements SimplePie_Cache_Base {
+ /**
+ * Redis instance
+ *
+ * @var \Redis
+ */
+ protected $cache;
+
+ /**
+ * Options
+ *
+ * @var array
+ */
+ protected $options;
+
+ /**
+ * Cache name
+ *
+ * @var string
+ */
+ protected $name;
+
+ /**
+ * Cache Data
+ *
+ * @var type
+ */
+ protected $data;
+
+ /**
+ * Create a new cache object
+ *
+ * @param string $location Location string (from SimplePie::$cache_location)
+ * @param string $name Unique ID for the cache
+ * @param string $type Either TYPE_FEED for SimplePie data, or TYPE_IMAGE for image data
+ */
+ public function __construct($location, $name, $options = null) {
+ //$this->cache = \flow\simple\cache\Redis::getRedisClientInstance();
+ $parsed = SimplePie_Cache::parse_URL($location);
+ $redis = new Redis();
+ $redis->connect($parsed['host'], $parsed['port']);
+ if (isset($parsed['pass'])) {
+ $redis->auth($parsed['pass']);
+ }
+ if (isset($parsed['path'])) {
+ $redis->select((int)substr($parsed['path'], 1));
+ }
+ $this->cache = $redis;
+
+ if (!is_null($options) && is_array($options)) {
+ $this->options = $options;
+ } else {
+ $this->options = array (
+ 'prefix' => 'rss:simple_primary:',
+ 'expire' => 0,
+ );
+ }
+
+ $this->name = $this->options['prefix'] . $name;
+ }
+
+ /**
+ * @param \Redis $cache
+ */
+ public function setRedisClient(\Redis $cache) {
+ $this->cache = $cache;
+ }
+
+ /**
+ * Save data to the cache
+ *
+ * @param array|SimplePie $data Data to store in the cache. If passed a SimplePie object, only cache the $data property
+ * @return bool Successfulness
+ */
+ public function save($data) {
+ if ($data instanceof SimplePie) {
+ $data = $data->data;
+ }
+ $response = $this->cache->set($this->name, serialize($data));
+ if ($this->options['expire']) {
+ $this->cache->expire($this->name, $this->options['expire']);
+ }
+
+ return $response;
+ }
+
+ /**
+ * Retrieve the data saved to the cache
+ *
+ * @return array Data for SimplePie::$data
+ */
+ public function load() {
+ $data = $this->cache->get($this->name);
+
+ if ($data !== false) {
+ return unserialize($data);
+ }
+ return false;
+ }
+
+ /**
+ * Retrieve the last modified time for the cache
+ *
+ * @return int Timestamp
+ */
+ public function mtime() {
+
+ $data = $this->cache->get($this->name);
+
+ if ($data !== false) {
+ return time();
+ }
+
+ return false;
+ }
+
+ /**
+ * Set the last modified time to the current time
+ *
+ * @return bool Success status
+ */
+ public function touch() {
+
+ $data = $this->cache->get($this->name);
+
+ if ($data !== false) {
+ $return = $this->cache->set($this->name, $data);
+ if ($this->options['expire']) {
+ return $this->cache->expire($this->name, $this->ttl);
+ }
+ return $return;
+ }
+
+ return false;
+ }
+
+ /**
+ * Remove the cache
+ *
+ * @return bool Success status
+ */
+ public function unlink() {
+ return $this->cache->set($this->name, null);
+ }
+
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Caption.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Caption.php
new file mode 100644
index 0000000..3d7bfdd
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Caption.php
@@ -0,0 +1,198 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+
+/**
+ * Handles `<media:text>` captions as defined in Media RSS.
+ *
+ * Used by {@see SimplePie_Enclosure::get_caption()} and {@see SimplePie_Enclosure::get_captions()}
+ *
+ * This class can be overloaded with {@see SimplePie::set_caption_class()}
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Caption
+{
+ /**
+ * Content type
+ *
+ * @var string
+ * @see get_type()
+ */
+ var $type;
+
+ /**
+ * Language
+ *
+ * @var string
+ * @see get_language()
+ */
+ var $lang;
+
+ /**
+ * Start time
+ *
+ * @var string
+ * @see get_starttime()
+ */
+ var $startTime;
+
+ /**
+ * End time
+ *
+ * @var string
+ * @see get_endtime()
+ */
+ var $endTime;
+
+ /**
+ * Caption text
+ *
+ * @var string
+ * @see get_text()
+ */
+ var $text;
+
+ /**
+ * Constructor, used to input the data
+ *
+ * For documentation on all the parameters, see the corresponding
+ * properties and their accessors
+ */
+ public function __construct($type = null, $lang = null, $startTime = null, $endTime = null, $text = null)
+ {
+ $this->type = $type;
+ $this->lang = $lang;
+ $this->startTime = $startTime;
+ $this->endTime = $endTime;
+ $this->text = $text;
+ }
+
+ /**
+ * String-ified version
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ /**
+ * Get the end time
+ *
+ * @return string|null Time in the format 'hh:mm:ss.SSS'
+ */
+ public function get_endtime()
+ {
+ if ($this->endTime !== null)
+ {
+ return $this->endTime;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the language
+ *
+ * @link http://tools.ietf.org/html/rfc3066
+ * @return string|null Language code as per RFC 3066
+ */
+ public function get_language()
+ {
+ if ($this->lang !== null)
+ {
+ return $this->lang;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the start time
+ *
+ * @return string|null Time in the format 'hh:mm:ss.SSS'
+ */
+ public function get_starttime()
+ {
+ if ($this->startTime !== null)
+ {
+ return $this->startTime;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the text of the caption
+ *
+ * @return string|null
+ */
+ public function get_text()
+ {
+ if ($this->text !== null)
+ {
+ return $this->text;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the content type (not MIME type)
+ *
+ * @return string|null Either 'text' or 'html'
+ */
+ public function get_type()
+ {
+ if ($this->type !== null)
+ {
+ return $this->type;
+ }
+
+ return null;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Category.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Category.php
new file mode 100644
index 0000000..e4dabed
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Category.php
@@ -0,0 +1,163 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Manages all category-related data
+ *
+ * Used by {@see SimplePie_Item::get_category()} and {@see SimplePie_Item::get_categories()}
+ *
+ * This class can be overloaded with {@see SimplePie::set_category_class()}
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Category
+{
+ /**
+ * Category identifier
+ *
+ * @var string|null
+ * @see get_term
+ */
+ var $term;
+
+ /**
+ * Categorization scheme identifier
+ *
+ * @var string|null
+ * @see get_scheme()
+ */
+ var $scheme;
+
+ /**
+ * Human readable label
+ *
+ * @var string|null
+ * @see get_label()
+ */
+ var $label;
+
+ /**
+ * Category type
+ *
+ * category for <category>
+ * subject for <dc:subject>
+ *
+ * @var string|null
+ * @see get_type()
+ */
+ var $type;
+
+ /**
+ * Constructor, used to input the data
+ *
+ * @param string|null $term
+ * @param string|null $scheme
+ * @param string|null $label
+ * @param string|null $type
+ */
+ public function __construct($term = null, $scheme = null, $label = null, $type = null)
+ {
+ $this->term = $term;
+ $this->scheme = $scheme;
+ $this->label = $label;
+ $this->type = $type;
+ }
+
+ /**
+ * String-ified version
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ /**
+ * Get the category identifier
+ *
+ * @return string|null
+ */
+ public function get_term()
+ {
+ return $this->term;
+ }
+
+ /**
+ * Get the categorization scheme identifier
+ *
+ * @return string|null
+ */
+ public function get_scheme()
+ {
+ return $this->scheme;
+ }
+
+ /**
+ * Get the human readable label
+ *
+ * @param bool $strict
+ * @return string|null
+ */
+ public function get_label($strict = false)
+ {
+ if ($this->label === null && $strict !== true)
+ {
+ return $this->get_term();
+ }
+ return $this->label;
+ }
+
+ /**
+ * Get the category type
+ *
+ * @return string|null
+ */
+ public function get_type()
+ {
+ return $this->type;
+ }
+}
+
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Content/Type/Sniffer.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Content/Type/Sniffer.php
new file mode 100644
index 0000000..39972b5
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Content/Type/Sniffer.php
@@ -0,0 +1,318 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+
+/**
+ * Content-type sniffing
+ *
+ * Based on the rules in http://tools.ietf.org/html/draft-abarth-mime-sniff-06
+ *
+ * This is used since we can't always trust Content-Type headers, and is based
+ * upon the HTML5 parsing rules.
+ *
+ *
+ * This class can be overloaded with {@see SimplePie::set_content_type_sniffer_class()}
+ *
+ * @package SimplePie
+ * @subpackage HTTP
+ */
+class SimplePie_Content_Type_Sniffer
+{
+ /**
+ * File object
+ *
+ * @var SimplePie_File
+ */
+ var $file;
+
+ /**
+ * Create an instance of the class with the input file
+ *
+ * @param SimplePie_Content_Type_Sniffer $file Input file
+ */
+ public function __construct($file)
+ {
+ $this->file = $file;
+ }
+
+ /**
+ * Get the Content-Type of the specified file
+ *
+ * @return string Actual Content-Type
+ */
+ public function get_type()
+ {
+ if (isset($this->file->headers['content-type']))
+ {
+ if (!isset($this->file->headers['content-encoding'])
+ && ($this->file->headers['content-type'] === 'text/plain'
+ || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
+ || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'
+ || $this->file->headers['content-type'] === 'text/plain; charset=UTF-8'))
+ {
+ return $this->text_or_binary();
+ }
+
+ if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
+ {
+ $official = substr($this->file->headers['content-type'], 0, $pos);
+ }
+ else
+ {
+ $official = $this->file->headers['content-type'];
+ }
+ $official = trim(strtolower($official));
+
+ if ($official === 'unknown/unknown'
+ || $official === 'application/unknown')
+ {
+ return $this->unknown();
+ }
+ elseif (substr($official, -4) === '+xml'
+ || $official === 'text/xml'
+ || $official === 'application/xml')
+ {
+ return $official;
+ }
+ elseif (substr($official, 0, 6) === 'image/')
+ {
+ if ($return = $this->image())
+ {
+ return $return;
+ }
+
+ return $official;
+ }
+ elseif ($official === 'text/html')
+ {
+ return $this->feed_or_html();
+ }
+
+ return $official;
+ }
+
+ return $this->unknown();
+ }
+
+ /**
+ * Sniff text or binary
+ *
+ * @return string Actual Content-Type
+ */
+ public function text_or_binary()
+ {
+ if (substr($this->file->body, 0, 2) === "\xFE\xFF"
+ || substr($this->file->body, 0, 2) === "\xFF\xFE"
+ || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
+ || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
+ {
+ return 'text/plain';
+ }
+ elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
+ {
+ return 'application/octect-stream';
+ }
+
+ return 'text/plain';
+ }
+
+ /**
+ * Sniff unknown
+ *
+ * @return string Actual Content-Type
+ */
+ public function unknown()
+ {
+ $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
+ if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
+ || strtolower(substr($this->file->body, $ws, 5)) === '<html'
+ || strtolower(substr($this->file->body, $ws, 7)) === '<script')
+ {
+ return 'text/html';
+ }
+ elseif (substr($this->file->body, 0, 5) === '%PDF-')
+ {
+ return 'application/pdf';
+ }
+ elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
+ {
+ return 'application/postscript';
+ }
+ elseif (substr($this->file->body, 0, 6) === 'GIF87a'
+ || substr($this->file->body, 0, 6) === 'GIF89a')
+ {
+ return 'image/gif';
+ }
+ elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
+ {
+ return 'image/png';
+ }
+ elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
+ {
+ return 'image/jpeg';
+ }
+ elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
+ {
+ return 'image/bmp';
+ }
+ elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
+ {
+ return 'image/vnd.microsoft.icon';
+ }
+
+ return $this->text_or_binary();
+ }
+
+ /**
+ * Sniff images
+ *
+ * @return string Actual Content-Type
+ */
+ public function image()
+ {
+ if (substr($this->file->body, 0, 6) === 'GIF87a'
+ || substr($this->file->body, 0, 6) === 'GIF89a')
+ {
+ return 'image/gif';
+ }
+ elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
+ {
+ return 'image/png';
+ }
+ elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
+ {
+ return 'image/jpeg';
+ }
+ elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
+ {
+ return 'image/bmp';
+ }
+ elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
+ {
+ return 'image/vnd.microsoft.icon';
+ }
+
+ return false;
+ }
+
+ /**
+ * Sniff HTML
+ *
+ * @return string Actual Content-Type
+ */
+ public function feed_or_html()
+ {
+ $len = strlen($this->file->body);
+ $pos = strspn($this->file->body, "\x09\x0A\x0D\x20\xEF\xBB\xBF");
+
+ while ($pos < $len)
+ {
+ switch ($this->file->body[$pos])
+ {
+ case "\x09":
+ case "\x0A":
+ case "\x0D":
+ case "\x20":
+ $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
+ continue 2;
+
+ case '<':
+ $pos++;
+ break;
+
+ default:
+ return 'text/html';
+ }
+
+ if (substr($this->file->body, $pos, 3) === '!--')
+ {
+ $pos += 3;
+ if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
+ {
+ $pos += 3;
+ }
+ else
+ {
+ return 'text/html';
+ }
+ }
+ elseif (substr($this->file->body, $pos, 1) === '!')
+ {
+ if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
+ {
+ $pos++;
+ }
+ else
+ {
+ return 'text/html';
+ }
+ }
+ elseif (substr($this->file->body, $pos, 1) === '?')
+ {
+ if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
+ {
+ $pos += 2;
+ }
+ else
+ {
+ return 'text/html';
+ }
+ }
+ elseif (substr($this->file->body, $pos, 3) === 'rss'
+ || substr($this->file->body, $pos, 7) === 'rdf:RDF')
+ {
+ return 'application/rss+xml';
+ }
+ elseif (substr($this->file->body, $pos, 4) === 'feed')
+ {
+ return 'application/atom+xml';
+ }
+ else
+ {
+ return 'text/html';
+ }
+ }
+
+ return 'text/html';
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Copyright.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Copyright.php
new file mode 100644
index 0000000..92f9b09
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Copyright.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Manages `<media:copyright>` copyright tags as defined in Media RSS
+ *
+ * Used by {@see SimplePie_Enclosure::get_copyright()}
+ *
+ * This class can be overloaded with {@see SimplePie::set_copyright_class()}
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Copyright
+{
+ /**
+ * Copyright URL
+ *
+ * @var string
+ * @see get_url()
+ */
+ var $url;
+
+ /**
+ * Attribution
+ *
+ * @var string
+ * @see get_attribution()
+ */
+ var $label;
+
+ /**
+ * Constructor, used to input the data
+ *
+ * For documentation on all the parameters, see the corresponding
+ * properties and their accessors
+ */
+ public function __construct($url = null, $label = null)
+ {
+ $this->url = $url;
+ $this->label = $label;
+ }
+
+ /**
+ * String-ified version
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ /**
+ * Get the copyright URL
+ *
+ * @return string|null URL to copyright information
+ */
+ public function get_url()
+ {
+ if ($this->url !== null)
+ {
+ return $this->url;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the attribution text
+ *
+ * @return string|null
+ */
+ public function get_attribution()
+ {
+ if ($this->label !== null)
+ {
+ return $this->label;
+ }
+
+ return null;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Core.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Core.php
new file mode 100644
index 0000000..ffcca46
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Core.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * SimplePie class.
+ *
+ * Class for backward compatibility.
+ *
+ * @deprecated Use {@see SimplePie} directly
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Core extends SimplePie
+{
+
+} \ No newline at end of file
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Credit.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Credit.php
new file mode 100644
index 0000000..d6ff07e
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Credit.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Handles `<media:credit>` as defined in Media RSS
+ *
+ * Used by {@see SimplePie_Enclosure::get_credit()} and {@see SimplePie_Enclosure::get_credits()}
+ *
+ * This class can be overloaded with {@see SimplePie::set_credit_class()}
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Credit
+{
+ /**
+ * Credited role
+ *
+ * @var string
+ * @see get_role()
+ */
+ var $role;
+
+ /**
+ * Organizational scheme
+ *
+ * @var string
+ * @see get_scheme()
+ */
+ var $scheme;
+
+ /**
+ * Credited name
+ *
+ * @var string
+ * @see get_name()
+ */
+ var $name;
+
+ /**
+ * Constructor, used to input the data
+ *
+ * For documentation on all the parameters, see the corresponding
+ * properties and their accessors
+ */
+ public function __construct($role = null, $scheme = null, $name = null)
+ {
+ $this->role = $role;
+ $this->scheme = $scheme;
+ $this->name = $name;
+ }
+
+ /**
+ * String-ified version
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ /**
+ * Get the role of the person receiving credit
+ *
+ * @return string|null
+ */
+ public function get_role()
+ {
+ if ($this->role !== null)
+ {
+ return $this->role;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the organizational scheme
+ *
+ * @return string|null
+ */
+ public function get_scheme()
+ {
+ if ($this->scheme !== null)
+ {
+ return $this->scheme;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the credited person/entity's name
+ *
+ * @return string|null
+ */
+ public function get_name()
+ {
+ if ($this->name !== null)
+ {
+ return $this->name;
+ }
+
+ return null;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Decode/HTML/Entities.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Decode/HTML/Entities.php
new file mode 100644
index 0000000..a43c374
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Decode/HTML/Entities.php
@@ -0,0 +1,610 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+
+/**
+ * Decode HTML Entities
+ *
+ * This implements HTML5 as of revision 967 (2007-06-28)
+ *
+ * @deprecated Use DOMDocument instead!
+ * @package SimplePie
+ */
+class SimplePie_Decode_HTML_Entities
+{
+ /**
+ * Data to be parsed
+ *
+ * @access private
+ * @var string
+ */
+ var $data = '';
+
+ /**
+ * Currently consumed bytes
+ *
+ * @access private
+ * @var string
+ */
+ var $consumed = '';
+
+ /**
+ * Position of the current byte being parsed
+ *
+ * @access private
+ * @var int
+ */
+ var $position = 0;
+
+ /**
+ * Create an instance of the class with the input data
+ *
+ * @access public
+ * @param string $data Input data
+ */
+ public function __construct($data)
+ {
+ $this->data = $data;
+ }
+
+ /**
+ * Parse the input data
+ *
+ * @access public
+ * @return string Output data
+ */
+ public function parse()
+ {
+ while (($this->position = strpos($this->data, '&', $this->position)) !== false)
+ {
+ $this->consume();
+ $this->entity();
+ $this->consumed = '';
+ }
+ return $this->data;
+ }
+
+ /**
+ * Consume the next byte
+ *
+ * @access private
+ * @return mixed The next byte, or false, if there is no more data
+ */
+ public function consume()
+ {
+ if (isset($this->data[$this->position]))
+ {
+ $this->consumed .= $this->data[$this->position];
+ return $this->data[$this->position++];
+ }
+
+ return false;
+ }
+
+ /**
+ * Consume a range of characters
+ *
+ * @access private
+ * @param string $chars Characters to consume
+ * @return mixed A series of characters that match the range, or false
+ */
+ public function consume_range($chars)
+ {
+ if ($len = strspn($this->data, $chars, $this->position))
+ {
+ $data = substr($this->data, $this->position, $len);
+ $this->consumed .= $data;
+ $this->position += $len;
+ return $data;
+ }
+
+ return false;
+ }
+
+ /**
+ * Unconsume one byte
+ *
+ * @access private
+ */
+ public function unconsume()
+ {
+ $this->consumed = substr($this->consumed, 0, -1);
+ $this->position--;
+ }
+
+ /**
+ * Decode an entity
+ *
+ * @access private
+ */
+ public function entity()
+ {
+ switch ($this->consume())
+ {
+ case "\x09":
+ case "\x0A":
+ case "\x0B":
+ case "\x0C":
+ case "\x20":
+ case "\x3C":
+ case "\x26":
+ case false:
+ break;
+
+ case "\x23":
+ switch ($this->consume())
+ {
+ case "\x78":
+ case "\x58":
+ $range = '0123456789ABCDEFabcdef';
+ $hex = true;
+ break;
+
+ default:
+ $range = '0123456789';
+ $hex = false;
+ $this->unconsume();
+ break;
+ }
+
+ if ($codepoint = $this->consume_range($range))
+ {
+ static $windows_1252_specials = array(0x0D => "\x0A", 0x80 => "\xE2\x82\xAC", 0x81 => "\xEF\xBF\xBD", 0x82 => "\xE2\x80\x9A", 0x83 => "\xC6\x92", 0x84 => "\xE2\x80\x9E", 0x85 => "\xE2\x80\xA6", 0x86 => "\xE2\x80\xA0", 0x87 => "\xE2\x80\xA1", 0x88 => "\xCB\x86", 0x89 => "\xE2\x80\xB0", 0x8A => "\xC5\xA0", 0x8B => "\xE2\x80\xB9", 0x8C => "\xC5\x92", 0x8D => "\xEF\xBF\xBD", 0x8E => "\xC5\xBD", 0x8F => "\xEF\xBF\xBD", 0x90 => "\xEF\xBF\xBD", 0x91 => "\xE2\x80\x98", 0x92 => "\xE2\x80\x99", 0x93 => "\xE2\x80\x9C", 0x94 => "\xE2\x80\x9D", 0x95 => "\xE2\x80\xA2", 0x96 => "\xE2\x80\x93", 0x97 => "\xE2\x80\x94", 0x98 => "\xCB\x9C", 0x99 => "\xE2\x84\xA2", 0x9A => "\xC5\xA1", 0x9B => "\xE2\x80\xBA", 0x9C => "\xC5\x93", 0x9D => "\xEF\xBF\xBD", 0x9E => "\xC5\xBE", 0x9F => "\xC5\xB8");
+
+ if ($hex)
+ {
+ $codepoint = hexdec($codepoint);
+ }
+ else
+ {
+ $codepoint = intval($codepoint);
+ }
+
+ if (isset($windows_1252_specials[$codepoint]))
+ {
+ $replacement = $windows_1252_specials[$codepoint];
+ }
+ else
+ {
+ $replacement = SimplePie_Misc::codepoint_to_utf8($codepoint);
+ }
+
+ if (!in_array($this->consume(), array(';', false), true))
+ {
+ $this->unconsume();
+ }
+
+ $consumed_length = strlen($this->consumed);
+ $this->data = substr_replace($this->data, $replacement, $this->position - $consumed_length, $consumed_length);
+ $this->position += strlen($replacement) - $consumed_length;
+ }
+ break;
+
+ default:
+ static $entities = array(
+ 'Aacute' => "\xC3\x81",
+ 'aacute' => "\xC3\xA1",
+ 'Aacute;' => "\xC3\x81",
+ 'aacute;' => "\xC3\xA1",
+ 'Acirc' => "\xC3\x82",
+ 'acirc' => "\xC3\xA2",
+ 'Acirc;' => "\xC3\x82",
+ 'acirc;' => "\xC3\xA2",
+ 'acute' => "\xC2\xB4",
+ 'acute;' => "\xC2\xB4",
+ 'AElig' => "\xC3\x86",
+ 'aelig' => "\xC3\xA6",
+ 'AElig;' => "\xC3\x86",
+ 'aelig;' => "\xC3\xA6",
+ 'Agrave' => "\xC3\x80",
+ 'agrave' => "\xC3\xA0",
+ 'Agrave;' => "\xC3\x80",
+ 'agrave;' => "\xC3\xA0",
+ 'alefsym;' => "\xE2\x84\xB5",
+ 'Alpha;' => "\xCE\x91",
+ 'alpha;' => "\xCE\xB1",
+ 'AMP' => "\x26",
+ 'amp' => "\x26",
+ 'AMP;' => "\x26",
+ 'amp;' => "\x26",
+ 'and;' => "\xE2\x88\xA7",
+ 'ang;' => "\xE2\x88\xA0",
+ 'apos;' => "\x27",
+ 'Aring' => "\xC3\x85",
+ 'aring' => "\xC3\xA5",
+ 'Aring;' => "\xC3\x85",
+ 'aring;' => "\xC3\xA5",
+ 'asymp;' => "\xE2\x89\x88",
+ 'Atilde' => "\xC3\x83",
+ 'atilde' => "\xC3\xA3",
+ 'Atilde;' => "\xC3\x83",
+ 'atilde;' => "\xC3\xA3",
+ 'Auml' => "\xC3\x84",
+ 'auml' => "\xC3\xA4",
+ 'Auml;' => "\xC3\x84",
+ 'auml;' => "\xC3\xA4",
+ 'bdquo;' => "\xE2\x80\x9E",
+ 'Beta;' => "\xCE\x92",
+ 'beta;' => "\xCE\xB2",
+ 'brvbar' => "\xC2\xA6",
+ 'brvbar;' => "\xC2\xA6",
+ 'bull;' => "\xE2\x80\xA2",
+ 'cap;' => "\xE2\x88\xA9",
+ 'Ccedil' => "\xC3\x87",
+ 'ccedil' => "\xC3\xA7",
+ 'Ccedil;' => "\xC3\x87",
+ 'ccedil;' => "\xC3\xA7",
+ 'cedil' => "\xC2\xB8",
+ 'cedil;' => "\xC2\xB8",
+ 'cent' => "\xC2\xA2",
+ 'cent;' => "\xC2\xA2",
+ 'Chi;' => "\xCE\xA7",
+ 'chi;' => "\xCF\x87",
+ 'circ;' => "\xCB\x86",
+ 'clubs;' => "\xE2\x99\xA3",
+ 'cong;' => "\xE2\x89\x85",
+ 'COPY' => "\xC2\xA9",
+ 'copy' => "\xC2\xA9",
+ 'COPY;' => "\xC2\xA9",
+ 'copy;' => "\xC2\xA9",
+ 'crarr;' => "\xE2\x86\xB5",
+ 'cup;' => "\xE2\x88\xAA",
+ 'curren' => "\xC2\xA4",
+ 'curren;' => "\xC2\xA4",
+ 'Dagger;' => "\xE2\x80\xA1",
+ 'dagger;' => "\xE2\x80\xA0",
+ 'dArr;' => "\xE2\x87\x93",
+ 'darr;' => "\xE2\x86\x93",
+ 'deg' => "\xC2\xB0",
+ 'deg;' => "\xC2\xB0",
+ 'Delta;' => "\xCE\x94",
+ 'delta;' => "\xCE\xB4",
+ 'diams;' => "\xE2\x99\xA6",
+ 'divide' => "\xC3\xB7",
+ 'divide;' => "\xC3\xB7",
+ 'Eacute' => "\xC3\x89",
+ 'eacute' => "\xC3\xA9",
+ 'Eacute;' => "\xC3\x89",
+ 'eacute;' => "\xC3\xA9",
+ 'Ecirc' => "\xC3\x8A",
+ 'ecirc' => "\xC3\xAA",
+ 'Ecirc;' => "\xC3\x8A",
+ 'ecirc;' => "\xC3\xAA",
+ 'Egrave' => "\xC3\x88",
+ 'egrave' => "\xC3\xA8",
+ 'Egrave;' => "\xC3\x88",
+ 'egrave;' => "\xC3\xA8",
+ 'empty;' => "\xE2\x88\x85",
+ 'emsp;' => "\xE2\x80\x83",
+ 'ensp;' => "\xE2\x80\x82",
+ 'Epsilon;' => "\xCE\x95",
+ 'epsilon;' => "\xCE\xB5",
+ 'equiv;' => "\xE2\x89\xA1",
+ 'Eta;' => "\xCE\x97",
+ 'eta;' => "\xCE\xB7",
+ 'ETH' => "\xC3\x90",
+ 'eth' => "\xC3\xB0",
+ 'ETH;' => "\xC3\x90",
+ 'eth;' => "\xC3\xB0",
+ 'Euml' => "\xC3\x8B",
+ 'euml' => "\xC3\xAB",
+ 'Euml;' => "\xC3\x8B",
+ 'euml;' => "\xC3\xAB",
+ 'euro;' => "\xE2\x82\xAC",
+ 'exist;' => "\xE2\x88\x83",
+ 'fnof;' => "\xC6\x92",
+ 'forall;' => "\xE2\x88\x80",
+ 'frac12' => "\xC2\xBD",
+ 'frac12;' => "\xC2\xBD",
+ 'frac14' => "\xC2\xBC",
+ 'frac14;' => "\xC2\xBC",
+ 'frac34' => "\xC2\xBE",
+ 'frac34;' => "\xC2\xBE",
+ 'frasl;' => "\xE2\x81\x84",
+ 'Gamma;' => "\xCE\x93",
+ 'gamma;' => "\xCE\xB3",
+ 'ge;' => "\xE2\x89\xA5",
+ 'GT' => "\x3E",
+ 'gt' => "\x3E",
+ 'GT;' => "\x3E",
+ 'gt;' => "\x3E",
+ 'hArr;' => "\xE2\x87\x94",
+ 'harr;' => "\xE2\x86\x94",
+ 'hearts;' => "\xE2\x99\xA5",
+ 'hellip;' => "\xE2\x80\xA6",
+ 'Iacute' => "\xC3\x8D",
+ 'iacute' => "\xC3\xAD",
+ 'Iacute;' => "\xC3\x8D",
+ 'iacute;' => "\xC3\xAD",
+ 'Icirc' => "\xC3\x8E",
+ 'icirc' => "\xC3\xAE",
+ 'Icirc;' => "\xC3\x8E",
+ 'icirc;' => "\xC3\xAE",
+ 'iexcl' => "\xC2\xA1",
+ 'iexcl;' => "\xC2\xA1",
+ 'Igrave' => "\xC3\x8C",
+ 'igrave' => "\xC3\xAC",
+ 'Igrave;' => "\xC3\x8C",
+ 'igrave;' => "\xC3\xAC",
+ 'image;' => "\xE2\x84\x91",
+ 'infin;' => "\xE2\x88\x9E",
+ 'int;' => "\xE2\x88\xAB",
+ 'Iota;' => "\xCE\x99",
+ 'iota;' => "\xCE\xB9",
+ 'iquest' => "\xC2\xBF",
+ 'iquest;' => "\xC2\xBF",
+ 'isin;' => "\xE2\x88\x88",
+ 'Iuml' => "\xC3\x8F",
+ 'iuml' => "\xC3\xAF",
+ 'Iuml;' => "\xC3\x8F",
+ 'iuml;' => "\xC3\xAF",
+ 'Kappa;' => "\xCE\x9A",
+ 'kappa;' => "\xCE\xBA",
+ 'Lambda;' => "\xCE\x9B",
+ 'lambda;' => "\xCE\xBB",
+ 'lang;' => "\xE3\x80\x88",
+ 'laquo' => "\xC2\xAB",
+ 'laquo;' => "\xC2\xAB",
+ 'lArr;' => "\xE2\x87\x90",
+ 'larr;' => "\xE2\x86\x90",
+ 'lceil;' => "\xE2\x8C\x88",
+ 'ldquo;' => "\xE2\x80\x9C",
+ 'le;' => "\xE2\x89\xA4",
+ 'lfloor;' => "\xE2\x8C\x8A",
+ 'lowast;' => "\xE2\x88\x97",
+ 'loz;' => "\xE2\x97\x8A",
+ 'lrm;' => "\xE2\x80\x8E",
+ 'lsaquo;' => "\xE2\x80\xB9",
+ 'lsquo;' => "\xE2\x80\x98",
+ 'LT' => "\x3C",
+ 'lt' => "\x3C",
+ 'LT;' => "\x3C",
+ 'lt;' => "\x3C",
+ 'macr' => "\xC2\xAF",
+ 'macr;' => "\xC2\xAF",
+ 'mdash;' => "\xE2\x80\x94",
+ 'micro' => "\xC2\xB5",
+ 'micro;' => "\xC2\xB5",
+ 'middot' => "\xC2\xB7",
+ 'middot;' => "\xC2\xB7",
+ 'minus;' => "\xE2\x88\x92",
+ 'Mu;' => "\xCE\x9C",
+ 'mu;' => "\xCE\xBC",
+ 'nabla;' => "\xE2\x88\x87",
+ 'nbsp' => "\xC2\xA0",
+ 'nbsp;' => "\xC2\xA0",
+ 'ndash;' => "\xE2\x80\x93",
+ 'ne;' => "\xE2\x89\xA0",
+ 'ni;' => "\xE2\x88\x8B",
+ 'not' => "\xC2\xAC",
+ 'not;' => "\xC2\xAC",
+ 'notin;' => "\xE2\x88\x89",
+ 'nsub;' => "\xE2\x8A\x84",
+ 'Ntilde' => "\xC3\x91",
+ 'ntilde' => "\xC3\xB1",
+ 'Ntilde;' => "\xC3\x91",
+ 'ntilde;' => "\xC3\xB1",
+ 'Nu;' => "\xCE\x9D",
+ 'nu;' => "\xCE\xBD",
+ 'Oacute' => "\xC3\x93",
+ 'oacute' => "\xC3\xB3",
+ 'Oacute;' => "\xC3\x93",
+ 'oacute;' => "\xC3\xB3",
+ 'Ocirc' => "\xC3\x94",
+ 'ocirc' => "\xC3\xB4",
+ 'Ocirc;' => "\xC3\x94",
+ 'ocirc;' => "\xC3\xB4",
+ 'OElig;' => "\xC5\x92",
+ 'oelig;' => "\xC5\x93",
+ 'Ograve' => "\xC3\x92",
+ 'ograve' => "\xC3\xB2",
+ 'Ograve;' => "\xC3\x92",
+ 'ograve;' => "\xC3\xB2",
+ 'oline;' => "\xE2\x80\xBE",
+ 'Omega;' => "\xCE\xA9",
+ 'omega;' => "\xCF\x89",
+ 'Omicron;' => "\xCE\x9F",
+ 'omicron;' => "\xCE\xBF",
+ 'oplus;' => "\xE2\x8A\x95",
+ 'or;' => "\xE2\x88\xA8",
+ 'ordf' => "\xC2\xAA",
+ 'ordf;' => "\xC2\xAA",
+ 'ordm' => "\xC2\xBA",
+ 'ordm;' => "\xC2\xBA",
+ 'Oslash' => "\xC3\x98",
+ 'oslash' => "\xC3\xB8",
+ 'Oslash;' => "\xC3\x98",
+ 'oslash;' => "\xC3\xB8",
+ 'Otilde' => "\xC3\x95",
+ 'otilde' => "\xC3\xB5",
+ 'Otilde;' => "\xC3\x95",
+ 'otilde;' => "\xC3\xB5",
+ 'otimes;' => "\xE2\x8A\x97",
+ 'Ouml' => "\xC3\x96",
+ 'ouml' => "\xC3\xB6",
+ 'Ouml;' => "\xC3\x96",
+ 'ouml;' => "\xC3\xB6",
+ 'para' => "\xC2\xB6",
+ 'para;' => "\xC2\xB6",
+ 'part;' => "\xE2\x88\x82",
+ 'permil;' => "\xE2\x80\xB0",
+ 'perp;' => "\xE2\x8A\xA5",
+ 'Phi;' => "\xCE\xA6",
+ 'phi;' => "\xCF\x86",
+ 'Pi;' => "\xCE\xA0",
+ 'pi;' => "\xCF\x80",
+ 'piv;' => "\xCF\x96",
+ 'plusmn' => "\xC2\xB1",
+ 'plusmn;' => "\xC2\xB1",
+ 'pound' => "\xC2\xA3",
+ 'pound;' => "\xC2\xA3",
+ 'Prime;' => "\xE2\x80\xB3",
+ 'prime;' => "\xE2\x80\xB2",
+ 'prod;' => "\xE2\x88\x8F",
+ 'prop;' => "\xE2\x88\x9D",
+ 'Psi;' => "\xCE\xA8",
+ 'psi;' => "\xCF\x88",
+ 'QUOT' => "\x22",
+ 'quot' => "\x22",
+ 'QUOT;' => "\x22",
+ 'quot;' => "\x22",
+ 'radic;' => "\xE2\x88\x9A",
+ 'rang;' => "\xE3\x80\x89",
+ 'raquo' => "\xC2\xBB",
+ 'raquo;' => "\xC2\xBB",
+ 'rArr;' => "\xE2\x87\x92",
+ 'rarr;' => "\xE2\x86\x92",
+ 'rceil;' => "\xE2\x8C\x89",
+ 'rdquo;' => "\xE2\x80\x9D",
+ 'real;' => "\xE2\x84\x9C",
+ 'REG' => "\xC2\xAE",
+ 'reg' => "\xC2\xAE",
+ 'REG;' => "\xC2\xAE",
+ 'reg;' => "\xC2\xAE",
+ 'rfloor;' => "\xE2\x8C\x8B",
+ 'Rho;' => "\xCE\xA1",
+ 'rho;' => "\xCF\x81",
+ 'rlm;' => "\xE2\x80\x8F",
+ 'rsaquo;' => "\xE2\x80\xBA",
+ 'rsquo;' => "\xE2\x80\x99",
+ 'sbquo;' => "\xE2\x80\x9A",
+ 'Scaron;' => "\xC5\xA0",
+ 'scaron;' => "\xC5\xA1",
+ 'sdot;' => "\xE2\x8B\x85",
+ 'sect' => "\xC2\xA7",
+ 'sect;' => "\xC2\xA7",
+ 'shy' => "\xC2\xAD",
+ 'shy;' => "\xC2\xAD",
+ 'Sigma;' => "\xCE\xA3",
+ 'sigma;' => "\xCF\x83",
+ 'sigmaf;' => "\xCF\x82",
+ 'sim;' => "\xE2\x88\xBC",
+ 'spades;' => "\xE2\x99\xA0",
+ 'sub;' => "\xE2\x8A\x82",
+ 'sube;' => "\xE2\x8A\x86",
+ 'sum;' => "\xE2\x88\x91",
+ 'sup;' => "\xE2\x8A\x83",
+ 'sup1' => "\xC2\xB9",
+ 'sup1;' => "\xC2\xB9",
+ 'sup2' => "\xC2\xB2",
+ 'sup2;' => "\xC2\xB2",
+ 'sup3' => "\xC2\xB3",
+ 'sup3;' => "\xC2\xB3",
+ 'supe;' => "\xE2\x8A\x87",
+ 'szlig' => "\xC3\x9F",
+ 'szlig;' => "\xC3\x9F",
+ 'Tau;' => "\xCE\xA4",
+ 'tau;' => "\xCF\x84",
+ 'there4;' => "\xE2\x88\xB4",
+ 'Theta;' => "\xCE\x98",
+ 'theta;' => "\xCE\xB8",
+ 'thetasym;' => "\xCF\x91",
+ 'thinsp;' => "\xE2\x80\x89",
+ 'THORN' => "\xC3\x9E",
+ 'thorn' => "\xC3\xBE",
+ 'THORN;' => "\xC3\x9E",
+ 'thorn;' => "\xC3\xBE",
+ 'tilde;' => "\xCB\x9C",
+ 'times' => "\xC3\x97",
+ 'times;' => "\xC3\x97",
+ 'TRADE;' => "\xE2\x84\xA2",
+ 'trade;' => "\xE2\x84\xA2",
+ 'Uacute' => "\xC3\x9A",
+ 'uacute' => "\xC3\xBA",
+ 'Uacute;' => "\xC3\x9A",
+ 'uacute;' => "\xC3\xBA",
+ 'uArr;' => "\xE2\x87\x91",
+ 'uarr;' => "\xE2\x86\x91",
+ 'Ucirc' => "\xC3\x9B",
+ 'ucirc' => "\xC3\xBB",
+ 'Ucirc;' => "\xC3\x9B",
+ 'ucirc;' => "\xC3\xBB",
+ 'Ugrave' => "\xC3\x99",
+ 'ugrave' => "\xC3\xB9",
+ 'Ugrave;' => "\xC3\x99",
+ 'ugrave;' => "\xC3\xB9",
+ 'uml' => "\xC2\xA8",
+ 'uml;' => "\xC2\xA8",
+ 'upsih;' => "\xCF\x92",
+ 'Upsilon;' => "\xCE\xA5",
+ 'upsilon;' => "\xCF\x85",
+ 'Uuml' => "\xC3\x9C",
+ 'uuml' => "\xC3\xBC",
+ 'Uuml;' => "\xC3\x9C",
+ 'uuml;' => "\xC3\xBC",
+ 'weierp;' => "\xE2\x84\x98",
+ 'Xi;' => "\xCE\x9E",
+ 'xi;' => "\xCE\xBE",
+ 'Yacute' => "\xC3\x9D",
+ 'yacute' => "\xC3\xBD",
+ 'Yacute;' => "\xC3\x9D",
+ 'yacute;' => "\xC3\xBD",
+ 'yen' => "\xC2\xA5",
+ 'yen;' => "\xC2\xA5",
+ 'yuml' => "\xC3\xBF",
+ 'Yuml;' => "\xC5\xB8",
+ 'yuml;' => "\xC3\xBF",
+ 'Zeta;' => "\xCE\x96",
+ 'zeta;' => "\xCE\xB6",
+ 'zwj;' => "\xE2\x80\x8D",
+ 'zwnj;' => "\xE2\x80\x8C"
+ );
+
+ for ($i = 0, $match = null; $i < 9 && $this->consume() !== false; $i++)
+ {
+ $consumed = substr($this->consumed, 1);
+ if (isset($entities[$consumed]))
+ {
+ $match = $consumed;
+ }
+ }
+
+ if ($match !== null)
+ {
+ $this->data = substr_replace($this->data, $entities[$match], $this->position - strlen($consumed) - 1, strlen($match) + 1);
+ $this->position += strlen($entities[$match]) - strlen($consumed) - 1;
+ }
+ break;
+ }
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Enclosure.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Enclosure.php
new file mode 100644
index 0000000..32216d8
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Enclosure.php
@@ -0,0 +1,1304 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Handles everything related to enclosures (including Media RSS and iTunes RSS)
+ *
+ * Used by {@see SimplePie_Item::get_enclosure()} and {@see SimplePie_Item::get_enclosures()}
+ *
+ * This class can be overloaded with {@see SimplePie::set_enclosure_class()}
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Enclosure
+{
+ /**
+ * @var string
+ * @see get_bitrate()
+ */
+ var $bitrate;
+
+ /**
+ * @var array
+ * @see get_captions()
+ */
+ var $captions;
+
+ /**
+ * @var array
+ * @see get_categories()
+ */
+ var $categories;
+
+ /**
+ * @var int
+ * @see get_channels()
+ */
+ var $channels;
+
+ /**
+ * @var SimplePie_Copyright
+ * @see get_copyright()
+ */
+ var $copyright;
+
+ /**
+ * @var array
+ * @see get_credits()
+ */
+ var $credits;
+
+ /**
+ * @var string
+ * @see get_description()
+ */
+ var $description;
+
+ /**
+ * @var int
+ * @see get_duration()
+ */
+ var $duration;
+
+ /**
+ * @var string
+ * @see get_expression()
+ */
+ var $expression;
+
+ /**
+ * @var string
+ * @see get_framerate()
+ */
+ var $framerate;
+
+ /**
+ * @var string
+ * @see get_handler()
+ */
+ var $handler;
+
+ /**
+ * @var array
+ * @see get_hashes()
+ */
+ var $hashes;
+
+ /**
+ * @var string
+ * @see get_height()
+ */
+ var $height;
+
+ /**
+ * @deprecated
+ * @var null
+ */
+ var $javascript;
+
+ /**
+ * @var array
+ * @see get_keywords()
+ */
+ var $keywords;
+
+ /**
+ * @var string
+ * @see get_language()
+ */
+ var $lang;
+
+ /**
+ * @var string
+ * @see get_length()
+ */
+ var $length;
+
+ /**
+ * @var string
+ * @see get_link()
+ */
+ var $link;
+
+ /**
+ * @var string
+ * @see get_medium()
+ */
+ var $medium;
+
+ /**
+ * @var string
+ * @see get_player()
+ */
+ var $player;
+
+ /**
+ * @var array
+ * @see get_ratings()
+ */
+ var $ratings;
+
+ /**
+ * @var array
+ * @see get_restrictions()
+ */
+ var $restrictions;
+
+ /**
+ * @var string
+ * @see get_sampling_rate()
+ */
+ var $samplingrate;
+
+ /**
+ * @var array
+ * @see get_thumbnails()
+ */
+ var $thumbnails;
+
+ /**
+ * @var string
+ * @see get_title()
+ */
+ var $title;
+
+ /**
+ * @var string
+ * @see get_type()
+ */
+ var $type;
+
+ /**
+ * @var string
+ * @see get_width()
+ */
+ var $width;
+
+ /**
+ * Constructor, used to input the data
+ *
+ * For documentation on all the parameters, see the corresponding
+ * properties and their accessors
+ *
+ * @uses idna_convert If available, this will convert an IDN
+ */
+ public function __construct($link = null, $type = null, $length = null, $javascript = null, $bitrate = null, $captions = null, $categories = null, $channels = null, $copyright = null, $credits = null, $description = null, $duration = null, $expression = null, $framerate = null, $hashes = null, $height = null, $keywords = null, $lang = null, $medium = null, $player = null, $ratings = null, $restrictions = null, $samplingrate = null, $thumbnails = null, $title = null, $width = null)
+ {
+ $this->bitrate = $bitrate;
+ $this->captions = $captions;
+ $this->categories = $categories;
+ $this->channels = $channels;
+ $this->copyright = $copyright;
+ $this->credits = $credits;
+ $this->description = $description;
+ $this->duration = $duration;
+ $this->expression = $expression;
+ $this->framerate = $framerate;
+ $this->hashes = $hashes;
+ $this->height = $height;
+ $this->keywords = $keywords;
+ $this->lang = $lang;
+ $this->length = $length;
+ $this->link = $link;
+ $this->medium = $medium;
+ $this->player = $player;
+ $this->ratings = $ratings;
+ $this->restrictions = $restrictions;
+ $this->samplingrate = $samplingrate;
+ $this->thumbnails = $thumbnails;
+ $this->title = $title;
+ $this->type = $type;
+ $this->width = $width;
+
+ if (class_exists('idna_convert'))
+ {
+ $idn = new idna_convert();
+ $parsed = SimplePie_Misc::parse_url($link);
+ $this->link = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']);
+ }
+ $this->handler = $this->get_handler(); // Needs to load last
+ }
+
+ /**
+ * String-ified version
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ /**
+ * Get the bitrate
+ *
+ * @return string|null
+ */
+ public function get_bitrate()
+ {
+ if ($this->bitrate !== null)
+ {
+ return $this->bitrate;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a single caption
+ *
+ * @param int $key
+ * @return SimplePie_Caption|null
+ */
+ public function get_caption($key = 0)
+ {
+ $captions = $this->get_captions();
+ if (isset($captions[$key]))
+ {
+ return $captions[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all captions
+ *
+ * @return array|null Array of {@see SimplePie_Caption} objects
+ */
+ public function get_captions()
+ {
+ if ($this->captions !== null)
+ {
+ return $this->captions;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a single category
+ *
+ * @param int $key
+ * @return SimplePie_Category|null
+ */
+ public function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all categories
+ *
+ * @return array|null Array of {@see SimplePie_Category} objects
+ */
+ public function get_categories()
+ {
+ if ($this->categories !== null)
+ {
+ return $this->categories;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the number of audio channels
+ *
+ * @return int|null
+ */
+ public function get_channels()
+ {
+ if ($this->channels !== null)
+ {
+ return $this->channels;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the copyright information
+ *
+ * @return SimplePie_Copyright|null
+ */
+ public function get_copyright()
+ {
+ if ($this->copyright !== null)
+ {
+ return $this->copyright;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a single credit
+ *
+ * @param int $key
+ * @return SimplePie_Credit|null
+ */
+ public function get_credit($key = 0)
+ {
+ $credits = $this->get_credits();
+ if (isset($credits[$key]))
+ {
+ return $credits[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all credits
+ *
+ * @return array|null Array of {@see SimplePie_Credit} objects
+ */
+ public function get_credits()
+ {
+ if ($this->credits !== null)
+ {
+ return $this->credits;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the description of the enclosure
+ *
+ * @return string|null
+ */
+ public function get_description()
+ {
+ if ($this->description !== null)
+ {
+ return $this->description;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the duration of the enclosure
+ *
+ * @param bool $convert Convert seconds into hh:mm:ss
+ * @return string|int|null 'hh:mm:ss' string if `$convert` was specified, otherwise integer (or null if none found)
+ */
+ public function get_duration($convert = false)
+ {
+ if ($this->duration !== null)
+ {
+ if ($convert)
+ {
+ $time = SimplePie_Misc::time_hms($this->duration);
+ return $time;
+ }
+
+ return $this->duration;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the expression
+ *
+ * @return string Probably one of 'sample', 'full', 'nonstop', 'clip'. Defaults to 'full'
+ */
+ public function get_expression()
+ {
+ if ($this->expression !== null)
+ {
+ return $this->expression;
+ }
+
+ return 'full';
+ }
+
+ /**
+ * Get the file extension
+ *
+ * @return string|null
+ */
+ public function get_extension()
+ {
+ if ($this->link !== null)
+ {
+ $url = SimplePie_Misc::parse_url($this->link);
+ if ($url['path'] !== '')
+ {
+ return pathinfo($url['path'], PATHINFO_EXTENSION);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the framerate (in frames-per-second)
+ *
+ * @return string|null
+ */
+ public function get_framerate()
+ {
+ if ($this->framerate !== null)
+ {
+ return $this->framerate;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the preferred handler
+ *
+ * @return string|null One of 'flash', 'fmedia', 'quicktime', 'wmedia', 'mp3'
+ */
+ public function get_handler()
+ {
+ return $this->get_real_type(true);
+ }
+
+ /**
+ * Get a single hash
+ *
+ * @link http://www.rssboard.org/media-rss#media-hash
+ * @param int $key
+ * @return string|null Hash as per `media:hash`, prefixed with "$algo:"
+ */
+ public function get_hash($key = 0)
+ {
+ $hashes = $this->get_hashes();
+ if (isset($hashes[$key]))
+ {
+ return $hashes[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all credits
+ *
+ * @return array|null Array of strings, see {@see get_hash()}
+ */
+ public function get_hashes()
+ {
+ if ($this->hashes !== null)
+ {
+ return $this->hashes;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the height
+ *
+ * @return string|null
+ */
+ public function get_height()
+ {
+ if ($this->height !== null)
+ {
+ return $this->height;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the language
+ *
+ * @link http://tools.ietf.org/html/rfc3066
+ * @return string|null Language code as per RFC 3066
+ */
+ public function get_language()
+ {
+ if ($this->lang !== null)
+ {
+ return $this->lang;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a single keyword
+ *
+ * @param int $key
+ * @return string|null
+ */
+ public function get_keyword($key = 0)
+ {
+ $keywords = $this->get_keywords();
+ if (isset($keywords[$key]))
+ {
+ return $keywords[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all keywords
+ *
+ * @return array|null Array of strings
+ */
+ public function get_keywords()
+ {
+ if ($this->keywords !== null)
+ {
+ return $this->keywords;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get length
+ *
+ * @return float Length in bytes
+ */
+ public function get_length()
+ {
+ if ($this->length !== null)
+ {
+ return $this->length;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the URL
+ *
+ * @return string|null
+ */
+ public function get_link()
+ {
+ if ($this->link !== null)
+ {
+ return urldecode($this->link);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the medium
+ *
+ * @link http://www.rssboard.org/media-rss#media-content
+ * @return string|null Should be one of 'image', 'audio', 'video', 'document', 'executable'
+ */
+ public function get_medium()
+ {
+ if ($this->medium !== null)
+ {
+ return $this->medium;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the player URL
+ *
+ * Typically the same as {@see get_permalink()}
+ * @return string|null Player URL
+ */
+ public function get_player()
+ {
+ if ($this->player !== null)
+ {
+ return $this->player;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a single rating
+ *
+ * @param int $key
+ * @return SimplePie_Rating|null
+ */
+ public function get_rating($key = 0)
+ {
+ $ratings = $this->get_ratings();
+ if (isset($ratings[$key]))
+ {
+ return $ratings[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all ratings
+ *
+ * @return array|null Array of {@see SimplePie_Rating} objects
+ */
+ public function get_ratings()
+ {
+ if ($this->ratings !== null)
+ {
+ return $this->ratings;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a single restriction
+ *
+ * @param int $key
+ * @return SimplePie_Restriction|null
+ */
+ public function get_restriction($key = 0)
+ {
+ $restrictions = $this->get_restrictions();
+ if (isset($restrictions[$key]))
+ {
+ return $restrictions[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all restrictions
+ *
+ * @return array|null Array of {@see SimplePie_Restriction} objects
+ */
+ public function get_restrictions()
+ {
+ if ($this->restrictions !== null)
+ {
+ return $this->restrictions;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the sampling rate (in kHz)
+ *
+ * @return string|null
+ */
+ public function get_sampling_rate()
+ {
+ if ($this->samplingrate !== null)
+ {
+ return $this->samplingrate;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the file size (in MiB)
+ *
+ * @return float|null File size in mebibytes (1048 bytes)
+ */
+ public function get_size()
+ {
+ $length = $this->get_length();
+ if ($length !== null)
+ {
+ return round($length/1048576, 2);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a single thumbnail
+ *
+ * @param int $key
+ * @return string|null Thumbnail URL
+ */
+ public function get_thumbnail($key = 0)
+ {
+ $thumbnails = $this->get_thumbnails();
+ if (isset($thumbnails[$key]))
+ {
+ return $thumbnails[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all thumbnails
+ *
+ * @return array|null Array of thumbnail URLs
+ */
+ public function get_thumbnails()
+ {
+ if ($this->thumbnails !== null)
+ {
+ return $this->thumbnails;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the title
+ *
+ * @return string|null
+ */
+ public function get_title()
+ {
+ if ($this->title !== null)
+ {
+ return $this->title;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get mimetype of the enclosure
+ *
+ * @see get_real_type()
+ * @return string|null MIME type
+ */
+ public function get_type()
+ {
+ if ($this->type !== null)
+ {
+ return $this->type;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the width
+ *
+ * @return string|null
+ */
+ public function get_width()
+ {
+ if ($this->width !== null)
+ {
+ return $this->width;
+ }
+
+ return null;
+ }
+
+ /**
+ * Embed the enclosure using `<embed>`
+ *
+ * @deprecated Use the second parameter to {@see embed} instead
+ *
+ * @param array|string $options See first paramter to {@see embed}
+ * @return string HTML string to output
+ */
+ public function native_embed($options='')
+ {
+ return $this->embed($options, true);
+ }
+
+ /**
+ * Embed the enclosure using Javascript
+ *
+ * `$options` is an array or comma-separated key:value string, with the
+ * following properties:
+ *
+ * - `alt` (string): Alternate content for when an end-user does not have
+ * the appropriate handler installed or when a file type is
+ * unsupported. Can be any text or HTML. Defaults to blank.
+ * - `altclass` (string): If a file type is unsupported, the end-user will
+ * see the alt text (above) linked directly to the content. That link
+ * will have this value as its class name. Defaults to blank.
+ * - `audio` (string): This is an image that should be used as a
+ * placeholder for audio files before they're loaded (QuickTime-only).
+ * Can be any relative or absolute URL. Defaults to blank.
+ * - `bgcolor` (string): The background color for the media, if not
+ * already transparent. Defaults to `#ffffff`.
+ * - `height` (integer): The height of the embedded media. Accepts any
+ * numeric pixel value (such as `360`) or `auto`. Defaults to `auto`,
+ * and it is recommended that you use this default.
+ * - `loop` (boolean): Do you want the media to loop when it's done?
+ * Defaults to `false`.
+ * - `mediaplayer` (string): The location of the included
+ * `mediaplayer.swf` file. This allows for the playback of Flash Video
+ * (`.flv`) files, and is the default handler for non-Odeo MP3's.
+ * Defaults to blank.
+ * - `video` (string): This is an image that should be used as a
+ * placeholder for video files before they're loaded (QuickTime-only).
+ * Can be any relative or absolute URL. Defaults to blank.
+ * - `width` (integer): The width of the embedded media. Accepts any
+ * numeric pixel value (such as `480`) or `auto`. Defaults to `auto`,
+ * and it is recommended that you use this default.
+ * - `widescreen` (boolean): Is the enclosure widescreen or standard?
+ * This applies only to video enclosures, and will automatically resize
+ * the content appropriately. Defaults to `false`, implying 4:3 mode.
+ *
+ * Note: Non-widescreen (4:3) mode with `width` and `height` set to `auto`
+ * will default to 480x360 video resolution. Widescreen (16:9) mode with
+ * `width` and `height` set to `auto` will default to 480x270 video resolution.
+ *
+ * @todo If the dimensions for media:content are defined, use them when width/height are set to 'auto'.
+ * @param array|string $options Comma-separated key:value list, or array
+ * @param bool $native Use `<embed>`
+ * @return string HTML string to output
+ */
+ public function embed($options = '', $native = false)
+ {
+ // Set up defaults
+ $audio = '';
+ $video = '';
+ $alt = '';
+ $altclass = '';
+ $loop = 'false';
+ $width = 'auto';
+ $height = 'auto';
+ $bgcolor = '#ffffff';
+ $mediaplayer = '';
+ $widescreen = false;
+ $handler = $this->get_handler();
+ $type = $this->get_real_type();
+
+ // Process options and reassign values as necessary
+ if (is_array($options))
+ {
+ extract($options);
+ }
+ else
+ {
+ $options = explode(',', $options);
+ foreach($options as $option)
+ {
+ $opt = explode(':', $option, 2);
+ if (isset($opt[0], $opt[1]))
+ {
+ $opt[0] = trim($opt[0]);
+ $opt[1] = trim($opt[1]);
+ switch ($opt[0])
+ {
+ case 'audio':
+ $audio = $opt[1];
+ break;
+
+ case 'video':
+ $video = $opt[1];
+ break;
+
+ case 'alt':
+ $alt = $opt[1];
+ break;
+
+ case 'altclass':
+ $altclass = $opt[1];
+ break;
+
+ case 'loop':
+ $loop = $opt[1];
+ break;
+
+ case 'width':
+ $width = $opt[1];
+ break;
+
+ case 'height':
+ $height = $opt[1];
+ break;
+
+ case 'bgcolor':
+ $bgcolor = $opt[1];
+ break;
+
+ case 'mediaplayer':
+ $mediaplayer = $opt[1];
+ break;
+
+ case 'widescreen':
+ $widescreen = $opt[1];
+ break;
+ }
+ }
+ }
+ }
+
+ $mime = explode('/', $type, 2);
+ $mime = $mime[0];
+
+ // Process values for 'auto'
+ if ($width === 'auto')
+ {
+ if ($mime === 'video')
+ {
+ if ($height === 'auto')
+ {
+ $width = 480;
+ }
+ elseif ($widescreen)
+ {
+ $width = round((intval($height)/9)*16);
+ }
+ else
+ {
+ $width = round((intval($height)/3)*4);
+ }
+ }
+ else
+ {
+ $width = '100%';
+ }
+ }
+
+ if ($height === 'auto')
+ {
+ if ($mime === 'audio')
+ {
+ $height = 0;
+ }
+ elseif ($mime === 'video')
+ {
+ if ($width === 'auto')
+ {
+ if ($widescreen)
+ {
+ $height = 270;
+ }
+ else
+ {
+ $height = 360;
+ }
+ }
+ elseif ($widescreen)
+ {
+ $height = round((intval($width)/16)*9);
+ }
+ else
+ {
+ $height = round((intval($width)/4)*3);
+ }
+ }
+ else
+ {
+ $height = 376;
+ }
+ }
+ elseif ($mime === 'audio')
+ {
+ $height = 0;
+ }
+
+ // Set proper placeholder value
+ if ($mime === 'audio')
+ {
+ $placeholder = $audio;
+ }
+ elseif ($mime === 'video')
+ {
+ $placeholder = $video;
+ }
+
+ $embed = '';
+
+ // Flash
+ if ($handler === 'flash')
+ {
+ if ($native)
+ {
+ $embed .= "<embed src=\"" . $this->get_link() . "\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"$type\" quality=\"high\" width=\"$width\" height=\"$height\" bgcolor=\"$bgcolor\" loop=\"$loop\"></embed>";
+ }
+ else
+ {
+ $embed .= "<script type='text/javascript'>embed_flash('$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$loop', '$type');</script>";
+ }
+ }
+
+ // Flash Media Player file types.
+ // Preferred handler for MP3 file types.
+ elseif ($handler === 'fmedia' || ($handler === 'mp3' && $mediaplayer !== ''))
+ {
+ $height += 20;
+ if ($native)
+ {
+ $embed .= "<embed src=\"$mediaplayer\" pluginspage=\"http://adobe.com/go/getflashplayer\" type=\"application/x-shockwave-flash\" quality=\"high\" width=\"$width\" height=\"$height\" wmode=\"transparent\" flashvars=\"file=" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "&autostart=false&repeat=$loop&showdigits=true&showfsbutton=false\"></embed>";
+ }
+ else
+ {
+ $embed .= "<script type='text/javascript'>embed_flv('$width', '$height', '" . rawurlencode($this->get_link().'?file_extension=.'.$this->get_extension()) . "', '$placeholder', '$loop', '$mediaplayer');</script>";
+ }
+ }
+
+ // QuickTime 7 file types. Need to test with QuickTime 6.
+ // Only handle MP3's if the Flash Media Player is not present.
+ elseif ($handler === 'quicktime' || ($handler === 'mp3' && $mediaplayer === ''))
+ {
+ $height += 16;
+ if ($native)
+ {
+ if ($placeholder !== '')
+ {
+ $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" href=\"" . $this->get_link() . "\" src=\"$placeholder\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"false\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
+ }
+ else
+ {
+ $embed .= "<embed type=\"$type\" style=\"cursor:hand; cursor:pointer;\" src=\"" . $this->get_link() . "\" width=\"$width\" height=\"$height\" autoplay=\"false\" target=\"myself\" controller=\"true\" loop=\"$loop\" scale=\"aspect\" bgcolor=\"$bgcolor\" pluginspage=\"http://apple.com/quicktime/download/\"></embed>";
+ }
+ }
+ else
+ {
+ $embed .= "<script type='text/javascript'>embed_quicktime('$type', '$bgcolor', '$width', '$height', '" . $this->get_link() . "', '$placeholder', '$loop');</script>";
+ }
+ }
+
+ // Windows Media
+ elseif ($handler === 'wmedia')
+ {
+ $height += 45;
+ if ($native)
+ {
+ $embed .= "<embed type=\"application/x-mplayer2\" src=\"" . $this->get_link() . "\" autosize=\"1\" width=\"$width\" height=\"$height\" showcontrols=\"1\" showstatusbar=\"0\" showdisplay=\"0\" autostart=\"0\"></embed>";
+ }
+ else
+ {
+ $embed .= "<script type='text/javascript'>embed_wmedia('$width', '$height', '" . $this->get_link() . "');</script>";
+ }
+ }
+
+ // Everything else
+ else $embed .= '<a href="' . $this->get_link() . '" class="' . $altclass . '">' . $alt . '</a>';
+
+ return $embed;
+ }
+
+ /**
+ * Get the real media type
+ *
+ * Often, feeds lie to us, necessitating a bit of deeper inspection. This
+ * converts types to their canonical representations based on the file
+ * extension
+ *
+ * @see get_type()
+ * @param bool $find_handler Internal use only, use {@see get_handler()} instead
+ * @return string MIME type
+ */
+ public function get_real_type($find_handler = false)
+ {
+ // Mime-types by handler.
+ $types_flash = array('application/x-shockwave-flash', 'application/futuresplash'); // Flash
+ $types_fmedia = array('video/flv', 'video/x-flv','flv-application/octet-stream'); // Flash Media Player
+ $types_quicktime = array('audio/3gpp', 'audio/3gpp2', 'audio/aac', 'audio/x-aac', 'audio/aiff', 'audio/x-aiff', 'audio/mid', 'audio/midi', 'audio/x-midi', 'audio/mp4', 'audio/m4a', 'audio/x-m4a', 'audio/wav', 'audio/x-wav', 'video/3gpp', 'video/3gpp2', 'video/m4v', 'video/x-m4v', 'video/mp4', 'video/mpeg', 'video/x-mpeg', 'video/quicktime', 'video/sd-video'); // QuickTime
+ $types_wmedia = array('application/asx', 'application/x-mplayer2', 'audio/x-ms-wma', 'audio/x-ms-wax', 'video/x-ms-asf-plugin', 'video/x-ms-asf', 'video/x-ms-wm', 'video/x-ms-wmv', 'video/x-ms-wvx'); // Windows Media
+ $types_mp3 = array('audio/mp3', 'audio/x-mp3', 'audio/mpeg', 'audio/x-mpeg'); // MP3
+
+ if ($this->get_type() !== null)
+ {
+ $type = strtolower($this->type);
+ }
+ else
+ {
+ $type = null;
+ }
+
+ // If we encounter an unsupported mime-type, check the file extension and guess intelligently.
+ if (!in_array($type, array_merge($types_flash, $types_fmedia, $types_quicktime, $types_wmedia, $types_mp3)))
+ {
+ switch (strtolower($this->get_extension()))
+ {
+ // Audio mime-types
+ case 'aac':
+ case 'adts':
+ $type = 'audio/acc';
+ break;
+
+ case 'aif':
+ case 'aifc':
+ case 'aiff':
+ case 'cdda':
+ $type = 'audio/aiff';
+ break;
+
+ case 'bwf':
+ $type = 'audio/wav';
+ break;
+
+ case 'kar':
+ case 'mid':
+ case 'midi':
+ case 'smf':
+ $type = 'audio/midi';
+ break;
+
+ case 'm4a':
+ $type = 'audio/x-m4a';
+ break;
+
+ case 'mp3':
+ case 'swa':
+ $type = 'audio/mp3';
+ break;
+
+ case 'wav':
+ $type = 'audio/wav';
+ break;
+
+ case 'wax':
+ $type = 'audio/x-ms-wax';
+ break;
+
+ case 'wma':
+ $type = 'audio/x-ms-wma';
+ break;
+
+ // Video mime-types
+ case '3gp':
+ case '3gpp':
+ $type = 'video/3gpp';
+ break;
+
+ case '3g2':
+ case '3gp2':
+ $type = 'video/3gpp2';
+ break;
+
+ case 'asf':
+ $type = 'video/x-ms-asf';
+ break;
+
+ case 'flv':
+ $type = 'video/x-flv';
+ break;
+
+ case 'm1a':
+ case 'm1s':
+ case 'm1v':
+ case 'm15':
+ case 'm75':
+ case 'mp2':
+ case 'mpa':
+ case 'mpeg':
+ case 'mpg':
+ case 'mpm':
+ case 'mpv':
+ $type = 'video/mpeg';
+ break;
+
+ case 'm4v':
+ $type = 'video/x-m4v';
+ break;
+
+ case 'mov':
+ case 'qt':
+ $type = 'video/quicktime';
+ break;
+
+ case 'mp4':
+ case 'mpg4':
+ $type = 'video/mp4';
+ break;
+
+ case 'sdv':
+ $type = 'video/sd-video';
+ break;
+
+ case 'wm':
+ $type = 'video/x-ms-wm';
+ break;
+
+ case 'wmv':
+ $type = 'video/x-ms-wmv';
+ break;
+
+ case 'wvx':
+ $type = 'video/x-ms-wvx';
+ break;
+
+ // Flash mime-types
+ case 'spl':
+ $type = 'application/futuresplash';
+ break;
+
+ case 'swf':
+ $type = 'application/x-shockwave-flash';
+ break;
+ }
+ }
+
+ if ($find_handler)
+ {
+ if (in_array($type, $types_flash))
+ {
+ return 'flash';
+ }
+ elseif (in_array($type, $types_fmedia))
+ {
+ return 'fmedia';
+ }
+ elseif (in_array($type, $types_quicktime))
+ {
+ return 'quicktime';
+ }
+ elseif (in_array($type, $types_wmedia))
+ {
+ return 'wmedia';
+ }
+ elseif (in_array($type, $types_mp3))
+ {
+ return 'mp3';
+ }
+
+ return null;
+ }
+
+ return $type;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Exception.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Exception.php
new file mode 100644
index 0000000..7a04c56
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Exception.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * General SimplePie exception class
+ *
+ * @package SimplePie
+ */
+class SimplePie_Exception extends Exception
+{
+} \ No newline at end of file
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/File.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/File.php
new file mode 100644
index 0000000..82db47e
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/File.php
@@ -0,0 +1,305 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Used for fetching remote files and reading local files
+ *
+ * Supports HTTP 1.0 via cURL or fsockopen, with spotty HTTP 1.1 support
+ *
+ * This class can be overloaded with {@see SimplePie::set_file_class()}
+ *
+ * @package SimplePie
+ * @subpackage HTTP
+ * @todo Move to properly supporting RFC2616 (HTTP/1.1)
+ */
+class SimplePie_File
+{
+ var $url;
+ var $useragent;
+ var $success = true;
+ var $headers = array();
+ var $body;
+ var $status_code;
+ var $redirects = 0;
+ var $error;
+ var $method = SIMPLEPIE_FILE_SOURCE_NONE;
+ var $permanent_url;
+
+ public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false, $curl_options = array())
+ {
+ if (class_exists('idna_convert'))
+ {
+ $idn = new idna_convert();
+ $parsed = SimplePie_Misc::parse_url($url);
+ $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], NULL);
+ }
+ $this->url = $url;
+ $this->permanent_url = $url;
+ $this->useragent = $useragent;
+ if (preg_match('/^http(s)?:\/\//i', $url))
+ {
+ if ($useragent === null)
+ {
+ $useragent = ini_get('user_agent');
+ $this->useragent = $useragent;
+ }
+ if (!is_array($headers))
+ {
+ $headers = array();
+ }
+ if (!$force_fsockopen && function_exists('curl_exec'))
+ {
+ $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL;
+ $fp = curl_init();
+ $headers2 = array();
+ foreach ($headers as $key => $value)
+ {
+ $headers2[] = "$key: $value";
+ }
+ if (version_compare(SimplePie_Misc::get_curl_version(), '7.10.5', '>='))
+ {
+ curl_setopt($fp, CURLOPT_ENCODING, '');
+ }
+ curl_setopt($fp, CURLOPT_URL, $url);
+ curl_setopt($fp, CURLOPT_HEADER, 1);
+ curl_setopt($fp, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($fp, CURLOPT_FAILONERROR, 1);
+ curl_setopt($fp, CURLOPT_TIMEOUT, $timeout);
+ curl_setopt($fp, CURLOPT_CONNECTTIMEOUT, $timeout);
+ curl_setopt($fp, CURLOPT_REFERER, $url);
+ curl_setopt($fp, CURLOPT_USERAGENT, $useragent);
+ curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2);
+ if (!ini_get('open_basedir') && version_compare(SimplePie_Misc::get_curl_version(), '7.15.2', '>='))
+ {
+ curl_setopt($fp, CURLOPT_FOLLOWLOCATION, 1);
+ curl_setopt($fp, CURLOPT_MAXREDIRS, $redirects);
+ }
+ foreach ($curl_options as $curl_param => $curl_value) {
+ curl_setopt($fp, $curl_param, $curl_value);
+ }
+
+ $this->headers = curl_exec($fp);
+ if (curl_errno($fp) === 23 || curl_errno($fp) === 61)
+ {
+ curl_setopt($fp, CURLOPT_ENCODING, 'none');
+ $this->headers = curl_exec($fp);
+ }
+ if (curl_errno($fp))
+ {
+ $this->error = 'cURL error ' . curl_errno($fp) . ': ' . curl_error($fp);
+ $this->success = false;
+ }
+ else
+ {
+ // Use the updated url provided by curl_getinfo after any redirects.
+ if ($info = curl_getinfo($fp)) {
+ $this->url = $info['url'];
+ }
+ curl_close($fp);
+ $this->headers = SimplePie_HTTP_Parser::prepareHeaders($this->headers, $info['redirect_count'] + 1);
+ $parser = new SimplePie_HTTP_Parser($this->headers);
+ if ($parser->parse())
+ {
+ $this->headers = $parser->headers;
+ $this->body = trim($parser->body);
+ $this->status_code = $parser->status_code;
+ if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
+ {
+ $this->redirects++;
+ $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
+ $previousStatusCode = $this->status_code;
+ $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
+ $this->permanent_url = ($previousStatusCode == 301) ? $location : $url;
+ return;
+ }
+ }
+ }
+ }
+ else
+ {
+ $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_FSOCKOPEN;
+ $url_parts = parse_url($url);
+ $socket_host = $url_parts['host'];
+ if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https')
+ {
+ $socket_host = "ssl://$url_parts[host]";
+ $url_parts['port'] = 443;
+ }
+ if (!isset($url_parts['port']))
+ {
+ $url_parts['port'] = 80;
+ }
+ $fp = @fsockopen($socket_host, $url_parts['port'], $errno, $errstr, $timeout);
+ if (!$fp)
+ {
+ $this->error = 'fsockopen error: ' . $errstr;
+ $this->success = false;
+ }
+ else
+ {
+ stream_set_timeout($fp, $timeout);
+ if (isset($url_parts['path']))
+ {
+ if (isset($url_parts['query']))
+ {
+ $get = "$url_parts[path]?$url_parts[query]";
+ }
+ else
+ {
+ $get = $url_parts['path'];
+ }
+ }
+ else
+ {
+ $get = '/';
+ }
+ $out = "GET $get HTTP/1.1\r\n";
+ $out .= "Host: $url_parts[host]\r\n";
+ $out .= "User-Agent: $useragent\r\n";
+ if (extension_loaded('zlib'))
+ {
+ $out .= "Accept-Encoding: x-gzip,gzip,deflate\r\n";
+ }
+
+ if (isset($url_parts['user']) && isset($url_parts['pass']))
+ {
+ $out .= "Authorization: Basic " . base64_encode("$url_parts[user]:$url_parts[pass]") . "\r\n";
+ }
+ foreach ($headers as $key => $value)
+ {
+ $out .= "$key: $value\r\n";
+ }
+ $out .= "Connection: Close\r\n\r\n";
+ fwrite($fp, $out);
+
+ $info = stream_get_meta_data($fp);
+
+ $this->headers = '';
+ while (!$info['eof'] && !$info['timed_out'])
+ {
+ $this->headers .= fread($fp, 1160);
+ $info = stream_get_meta_data($fp);
+ }
+ if (!$info['timed_out'])
+ {
+ $parser = new SimplePie_HTTP_Parser($this->headers);
+ if ($parser->parse())
+ {
+ $this->headers = $parser->headers;
+ $this->body = $parser->body;
+ $this->status_code = $parser->status_code;
+ if ((in_array($this->status_code, array(300, 301, 302, 303, 307)) || $this->status_code > 307 && $this->status_code < 400) && isset($this->headers['location']) && $this->redirects < $redirects)
+ {
+ $this->redirects++;
+ $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url);
+ $previousStatusCode = $this->status_code;
+ $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
+ $this->permanent_url = ($previousStatusCode == 301) ? $location : $url;
+ return;
+ }
+ if (isset($this->headers['content-encoding']))
+ {
+ // Hey, we act dumb elsewhere, so let's do that here too
+ switch (strtolower(trim($this->headers['content-encoding'], "\x09\x0A\x0D\x20")))
+ {
+ case 'gzip':
+ case 'x-gzip':
+ $decoder = new SimplePie_gzdecode($this->body);
+ if (!$decoder->parse())
+ {
+ $this->error = 'Unable to decode HTTP "gzip" stream';
+ $this->success = false;
+ }
+ else
+ {
+ $this->body = trim($decoder->data);
+ }
+ break;
+
+ case 'deflate':
+ if (($decompressed = gzinflate($this->body)) !== false)
+ {
+ $this->body = $decompressed;
+ }
+ else if (($decompressed = gzuncompress($this->body)) !== false)
+ {
+ $this->body = $decompressed;
+ }
+ else if (function_exists('gzdecode') && ($decompressed = gzdecode($this->body)) !== false)
+ {
+ $this->body = $decompressed;
+ }
+ else
+ {
+ $this->error = 'Unable to decode HTTP "deflate" stream';
+ $this->success = false;
+ }
+ break;
+
+ default:
+ $this->error = 'Unknown content coding';
+ $this->success = false;
+ }
+ }
+ }
+ }
+ else
+ {
+ $this->error = 'fsocket timed out';
+ $this->success = false;
+ }
+ fclose($fp);
+ }
+ }
+ }
+ else
+ {
+ $this->method = SIMPLEPIE_FILE_SOURCE_LOCAL | SIMPLEPIE_FILE_SOURCE_FILE_GET_CONTENTS;
+ if (empty($url) || !($this->body = trim(file_get_contents($url))))
+ {
+ $this->error = 'file_get_contents could not read the file';
+ $this->success = false;
+ }
+ }
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/HTTP/Parser.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/HTTP/Parser.php
new file mode 100644
index 0000000..1dbe06c
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/HTTP/Parser.php
@@ -0,0 +1,518 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+
+/**
+ * HTTP Response Parser
+ *
+ * @package SimplePie
+ * @subpackage HTTP
+ */
+class SimplePie_HTTP_Parser
+{
+ /**
+ * HTTP Version
+ *
+ * @var float
+ */
+ public $http_version = 0.0;
+
+ /**
+ * Status code
+ *
+ * @var int
+ */
+ public $status_code = 0;
+
+ /**
+ * Reason phrase
+ *
+ * @var string
+ */
+ public $reason = '';
+
+ /**
+ * Key/value pairs of the headers
+ *
+ * @var array
+ */
+ public $headers = array();
+
+ /**
+ * Body of the response
+ *
+ * @var string
+ */
+ public $body = '';
+
+ /**
+ * Current state of the state machine
+ *
+ * @var string
+ */
+ protected $state = 'http_version';
+
+ /**
+ * Input data
+ *
+ * @var string
+ */
+ protected $data = '';
+
+ /**
+ * Input data length (to avoid calling strlen() everytime this is needed)
+ *
+ * @var int
+ */
+ protected $data_length = 0;
+
+ /**
+ * Current position of the pointer
+ *
+ * @var int
+ */
+ protected $position = 0;
+
+ /**
+ * Name of the hedaer currently being parsed
+ *
+ * @var string
+ */
+ protected $name = '';
+
+ /**
+ * Value of the hedaer currently being parsed
+ *
+ * @var string
+ */
+ protected $value = '';
+
+ /**
+ * Create an instance of the class with the input data
+ *
+ * @param string $data Input data
+ */
+ public function __construct($data)
+ {
+ $this->data = $data;
+ $this->data_length = strlen($this->data);
+ }
+
+ /**
+ * Parse the input data
+ *
+ * @return bool true on success, false on failure
+ */
+ public function parse()
+ {
+ while ($this->state && $this->state !== 'emit' && $this->has_data())
+ {
+ $state = $this->state;
+ $this->$state();
+ }
+ $this->data = '';
+ if ($this->state === 'emit' || $this->state === 'body')
+ {
+ return true;
+ }
+
+ $this->http_version = '';
+ $this->status_code = '';
+ $this->reason = '';
+ $this->headers = array();
+ $this->body = '';
+ return false;
+ }
+
+ /**
+ * Check whether there is data beyond the pointer
+ *
+ * @return bool true if there is further data, false if not
+ */
+ protected function has_data()
+ {
+ return (bool) ($this->position < $this->data_length);
+ }
+
+ /**
+ * See if the next character is LWS
+ *
+ * @return bool true if the next character is LWS, false if not
+ */
+ protected function is_linear_whitespace()
+ {
+ return (bool) ($this->data[$this->position] === "\x09"
+ || $this->data[$this->position] === "\x20"
+ || ($this->data[$this->position] === "\x0A"
+ && isset($this->data[$this->position + 1])
+ && ($this->data[$this->position + 1] === "\x09" || $this->data[$this->position + 1] === "\x20")));
+ }
+
+ /**
+ * Parse the HTTP version
+ */
+ protected function http_version()
+ {
+ if (strpos($this->data, "\x0A") !== false && strtoupper(substr($this->data, 0, 5)) === 'HTTP/')
+ {
+ $len = strspn($this->data, '0123456789.', 5);
+ $this->http_version = substr($this->data, 5, $len);
+ $this->position += 5 + $len;
+ if (substr_count($this->http_version, '.') <= 1)
+ {
+ $this->http_version = (float) $this->http_version;
+ $this->position += strspn($this->data, "\x09\x20", $this->position);
+ $this->state = 'status';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ /**
+ * Parse the status code
+ */
+ protected function status()
+ {
+ if ($len = strspn($this->data, '0123456789', $this->position))
+ {
+ $this->status_code = (int) substr($this->data, $this->position, $len);
+ $this->position += $len;
+ $this->state = 'reason';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ /**
+ * Parse the reason phrase
+ */
+ protected function reason()
+ {
+ $len = strcspn($this->data, "\x0A", $this->position);
+ $this->reason = trim(substr($this->data, $this->position, $len), "\x09\x0D\x20");
+ $this->position += $len + 1;
+ $this->state = 'new_line';
+ }
+
+ /**
+ * Deal with a new line, shifting data around as needed
+ */
+ protected function new_line()
+ {
+ $this->value = trim($this->value, "\x0D\x20");
+ if ($this->name !== '' && $this->value !== '')
+ {
+ $this->name = strtolower($this->name);
+ // We should only use the last Content-Type header. c.f. issue #1
+ if (isset($this->headers[$this->name]) && $this->name !== 'content-type')
+ {
+ $this->headers[$this->name] .= ', ' . $this->value;
+ }
+ else
+ {
+ $this->headers[$this->name] = $this->value;
+ }
+ }
+ $this->name = '';
+ $this->value = '';
+ if (substr($this->data[$this->position], 0, 2) === "\x0D\x0A")
+ {
+ $this->position += 2;
+ $this->state = 'body';
+ }
+ elseif ($this->data[$this->position] === "\x0A")
+ {
+ $this->position++;
+ $this->state = 'body';
+ }
+ else
+ {
+ $this->state = 'name';
+ }
+ }
+
+ /**
+ * Parse a header name
+ */
+ protected function name()
+ {
+ $len = strcspn($this->data, "\x0A:", $this->position);
+ if (isset($this->data[$this->position + $len]))
+ {
+ if ($this->data[$this->position + $len] === "\x0A")
+ {
+ $this->position += $len;
+ $this->state = 'new_line';
+ }
+ else
+ {
+ $this->name = substr($this->data, $this->position, $len);
+ $this->position += $len + 1;
+ $this->state = 'value';
+ }
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ /**
+ * Parse LWS, replacing consecutive LWS characters with a single space
+ */
+ protected function linear_whitespace()
+ {
+ do
+ {
+ if (substr($this->data, $this->position, 2) === "\x0D\x0A")
+ {
+ $this->position += 2;
+ }
+ elseif ($this->data[$this->position] === "\x0A")
+ {
+ $this->position++;
+ }
+ $this->position += strspn($this->data, "\x09\x20", $this->position);
+ } while ($this->has_data() && $this->is_linear_whitespace());
+ $this->value .= "\x20";
+ }
+
+ /**
+ * See what state to move to while within non-quoted header values
+ */
+ protected function value()
+ {
+ if ($this->is_linear_whitespace())
+ {
+ $this->linear_whitespace();
+ }
+ else
+ {
+ switch ($this->data[$this->position])
+ {
+ case '"':
+ // Workaround for ETags: we have to include the quotes as
+ // part of the tag.
+ if (strtolower($this->name) === 'etag')
+ {
+ $this->value .= '"';
+ $this->position++;
+ $this->state = 'value_char';
+ break;
+ }
+ $this->position++;
+ $this->state = 'quote';
+ break;
+
+ case "\x0A":
+ $this->position++;
+ $this->state = 'new_line';
+ break;
+
+ default:
+ $this->state = 'value_char';
+ break;
+ }
+ }
+ }
+
+ /**
+ * Parse a header value while outside quotes
+ */
+ protected function value_char()
+ {
+ $len = strcspn($this->data, "\x09\x20\x0A\"", $this->position);
+ $this->value .= substr($this->data, $this->position, $len);
+ $this->position += $len;
+ $this->state = 'value';
+ }
+
+ /**
+ * See what state to move to while within quoted header values
+ */
+ protected function quote()
+ {
+ if ($this->is_linear_whitespace())
+ {
+ $this->linear_whitespace();
+ }
+ else
+ {
+ switch ($this->data[$this->position])
+ {
+ case '"':
+ $this->position++;
+ $this->state = 'value';
+ break;
+
+ case "\x0A":
+ $this->position++;
+ $this->state = 'new_line';
+ break;
+
+ case '\\':
+ $this->position++;
+ $this->state = 'quote_escaped';
+ break;
+
+ default:
+ $this->state = 'quote_char';
+ break;
+ }
+ }
+ }
+
+ /**
+ * Parse a header value while within quotes
+ */
+ protected function quote_char()
+ {
+ $len = strcspn($this->data, "\x09\x20\x0A\"\\", $this->position);
+ $this->value .= substr($this->data, $this->position, $len);
+ $this->position += $len;
+ $this->state = 'value';
+ }
+
+ /**
+ * Parse an escaped character within quotes
+ */
+ protected function quote_escaped()
+ {
+ $this->value .= $this->data[$this->position];
+ $this->position++;
+ $this->state = 'quote';
+ }
+
+ /**
+ * Parse the body
+ */
+ protected function body()
+ {
+ $this->body = substr($this->data, $this->position);
+ if (!empty($this->headers['transfer-encoding']))
+ {
+ unset($this->headers['transfer-encoding']);
+ $this->state = 'chunked';
+ }
+ else
+ {
+ $this->state = 'emit';
+ }
+ }
+
+ /**
+ * Parsed a "Transfer-Encoding: chunked" body
+ */
+ protected function chunked()
+ {
+ if (!preg_match('/^([0-9a-f]+)[^\r\n]*\r\n/i', trim($this->body)))
+ {
+ $this->state = 'emit';
+ return;
+ }
+
+ $decoded = '';
+ $encoded = $this->body;
+
+ while (true)
+ {
+ $is_chunked = (bool) preg_match( '/^([0-9a-f]+)[^\r\n]*\r\n/i', $encoded, $matches );
+ if (!$is_chunked)
+ {
+ // Looks like it's not chunked after all
+ $this->state = 'emit';
+ return;
+ }
+
+ $length = hexdec(trim($matches[1]));
+ if ($length === 0)
+ {
+ // Ignore trailer headers
+ $this->state = 'emit';
+ $this->body = $decoded;
+ return;
+ }
+
+ $chunk_length = strlen($matches[0]);
+ $decoded .= $part = substr($encoded, $chunk_length, $length);
+ $encoded = substr($encoded, $chunk_length + $length + 2);
+
+ if (trim($encoded) === '0' || empty($encoded))
+ {
+ $this->state = 'emit';
+ $this->body = $decoded;
+ return;
+ }
+ }
+ }
+
+ /**
+ * Prepare headers (take care of proxies headers)
+ *
+ * @param string $headers Raw headers
+ * @param integer $count Redirection count. Default to 1.
+ *
+ * @return string
+ */
+ static public function prepareHeaders($headers, $count = 1)
+ {
+ $data = explode("\r\n\r\n", $headers, $count);
+ $data = array_pop($data);
+ if (false !== stripos($data, "HTTP/1.0 200 Connection established\r\n\r\n")) {
+ $data = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $data);
+ }
+ if (false !== stripos($data, "HTTP/1.1 200 Connection established\r\n\r\n")) {
+ $data = str_ireplace("HTTP/1.1 200 Connection established\r\n\r\n", '', $data);
+ }
+ return $data;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/IRI.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/IRI.php
new file mode 100644
index 0000000..a02de68
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/IRI.php
@@ -0,0 +1,1236 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * IRI parser/serialiser/normaliser
+ *
+ * @package SimplePie
+ * @subpackage HTTP
+ * @author Sam Sneddon
+ * @author Steve Minutillo
+ * @author Ryan McCue
+ * @copyright 2007-2012 Sam Sneddon, Steve Minutillo, Ryan McCue
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ */
+class SimplePie_IRI
+{
+ /**
+ * Scheme
+ *
+ * @var string
+ */
+ protected $scheme = null;
+
+ /**
+ * User Information
+ *
+ * @var string
+ */
+ protected $iuserinfo = null;
+
+ /**
+ * ihost
+ *
+ * @var string
+ */
+ protected $ihost = null;
+
+ /**
+ * Port
+ *
+ * @var string
+ */
+ protected $port = null;
+
+ /**
+ * ipath
+ *
+ * @var string
+ */
+ protected $ipath = '';
+
+ /**
+ * iquery
+ *
+ * @var string
+ */
+ protected $iquery = null;
+
+ /**
+ * ifragment
+ *
+ * @var string
+ */
+ protected $ifragment = null;
+
+ /**
+ * Normalization database
+ *
+ * Each key is the scheme, each value is an array with each key as the IRI
+ * part and value as the default value for that part.
+ */
+ protected $normalization = array(
+ 'acap' => array(
+ 'port' => 674
+ ),
+ 'dict' => array(
+ 'port' => 2628
+ ),
+ 'file' => array(
+ 'ihost' => 'localhost'
+ ),
+ 'http' => array(
+ 'port' => 80,
+ 'ipath' => '/'
+ ),
+ 'https' => array(
+ 'port' => 443,
+ 'ipath' => '/'
+ ),
+ );
+
+ /**
+ * Return the entire IRI when you try and read the object as a string
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return $this->get_iri();
+ }
+
+ /**
+ * Overload __set() to provide access via properties
+ *
+ * @param string $name Property name
+ * @param mixed $value Property value
+ */
+ public function __set($name, $value)
+ {
+ if (method_exists($this, 'set_' . $name))
+ {
+ call_user_func(array($this, 'set_' . $name), $value);
+ }
+ elseif (
+ $name === 'iauthority'
+ || $name === 'iuserinfo'
+ || $name === 'ihost'
+ || $name === 'ipath'
+ || $name === 'iquery'
+ || $name === 'ifragment'
+ )
+ {
+ call_user_func(array($this, 'set_' . substr($name, 1)), $value);
+ }
+ }
+
+ /**
+ * Overload __get() to provide access via properties
+ *
+ * @param string $name Property name
+ * @return mixed
+ */
+ public function __get($name)
+ {
+ // isset() returns false for null, we don't want to do that
+ // Also why we use array_key_exists below instead of isset()
+ $props = get_object_vars($this);
+
+ if (
+ $name === 'iri' ||
+ $name === 'uri' ||
+ $name === 'iauthority' ||
+ $name === 'authority'
+ )
+ {
+ $return = $this->{"get_$name"}();
+ }
+ elseif (array_key_exists($name, $props))
+ {
+ $return = $this->$name;
+ }
+ // host -> ihost
+ elseif (($prop = 'i' . $name) && array_key_exists($prop, $props))
+ {
+ $name = $prop;
+ $return = $this->$prop;
+ }
+ // ischeme -> scheme
+ elseif (($prop = substr($name, 1)) && array_key_exists($prop, $props))
+ {
+ $name = $prop;
+ $return = $this->$prop;
+ }
+ else
+ {
+ trigger_error('Undefined property: ' . get_class($this) . '::' . $name, E_USER_NOTICE);
+ $return = null;
+ }
+
+ if ($return === null && isset($this->normalization[$this->scheme][$name]))
+ {
+ return $this->normalization[$this->scheme][$name];
+ }
+
+ return $return;
+ }
+
+ /**
+ * Overload __isset() to provide access via properties
+ *
+ * @param string $name Property name
+ * @return bool
+ */
+ public function __isset($name)
+ {
+ return method_exists($this, 'get_' . $name) || isset($this->$name);
+ }
+
+ /**
+ * Overload __unset() to provide access via properties
+ *
+ * @param string $name Property name
+ */
+ public function __unset($name)
+ {
+ if (method_exists($this, 'set_' . $name))
+ {
+ call_user_func(array($this, 'set_' . $name), '');
+ }
+ }
+
+ /**
+ * Create a new IRI object, from a specified string
+ *
+ * @param string $iri
+ */
+ public function __construct($iri = null)
+ {
+ $this->set_iri($iri);
+ }
+
+ /**
+ * Clean up
+ */
+ public function __destruct() {
+ $this->set_iri(null, true);
+ $this->set_path(null, true);
+ $this->set_authority(null, true);
+ }
+
+ /**
+ * Create a new IRI object by resolving a relative IRI
+ *
+ * Returns false if $base is not absolute, otherwise an IRI.
+ *
+ * @param IRI|string $base (Absolute) Base IRI
+ * @param IRI|string $relative Relative IRI
+ * @return IRI|false
+ */
+ public static function absolutize($base, $relative)
+ {
+ if (!($relative instanceof SimplePie_IRI))
+ {
+ $relative = new SimplePie_IRI($relative);
+ }
+ if (!$relative->is_valid())
+ {
+ return false;
+ }
+ elseif ($relative->scheme !== null)
+ {
+ return clone $relative;
+ }
+ else
+ {
+ if (!($base instanceof SimplePie_IRI))
+ {
+ $base = new SimplePie_IRI($base);
+ }
+ if ($base->scheme !== null && $base->is_valid())
+ {
+ if ($relative->get_iri() !== '')
+ {
+ if ($relative->iuserinfo !== null || $relative->ihost !== null || $relative->port !== null)
+ {
+ $target = clone $relative;
+ $target->scheme = $base->scheme;
+ }
+ else
+ {
+ $target = new SimplePie_IRI;
+ $target->scheme = $base->scheme;
+ $target->iuserinfo = $base->iuserinfo;
+ $target->ihost = $base->ihost;
+ $target->port = $base->port;
+ if ($relative->ipath !== '')
+ {
+ if ($relative->ipath[0] === '/')
+ {
+ $target->ipath = $relative->ipath;
+ }
+ elseif (($base->iuserinfo !== null || $base->ihost !== null || $base->port !== null) && $base->ipath === '')
+ {
+ $target->ipath = '/' . $relative->ipath;
+ }
+ elseif (($last_segment = strrpos($base->ipath, '/')) !== false)
+ {
+ $target->ipath = substr($base->ipath, 0, $last_segment + 1) . $relative->ipath;
+ }
+ else
+ {
+ $target->ipath = $relative->ipath;
+ }
+ $target->ipath = $target->remove_dot_segments($target->ipath);
+ $target->iquery = $relative->iquery;
+ }
+ else
+ {
+ $target->ipath = $base->ipath;
+ if ($relative->iquery !== null)
+ {
+ $target->iquery = $relative->iquery;
+ }
+ elseif ($base->iquery !== null)
+ {
+ $target->iquery = $base->iquery;
+ }
+ }
+ $target->ifragment = $relative->ifragment;
+ }
+ }
+ else
+ {
+ $target = clone $base;
+ $target->ifragment = null;
+ }
+ $target->scheme_normalization();
+ return $target;
+ }
+
+ return false;
+ }
+ }
+
+ /**
+ * Parse an IRI into scheme/authority/path/query/fragment segments
+ *
+ * @param string $iri
+ * @return array
+ */
+ protected function parse_iri($iri)
+ {
+ $iri = trim($iri, "\x20\x09\x0A\x0C\x0D");
+ if (preg_match('/^((?P<scheme>[^:\/?#]+):)?(\/\/(?P<authority>[^\/?#]*))?(?P<path>[^?#]*)(\?(?P<query>[^#]*))?(#(?P<fragment>.*))?$/', $iri, $match))
+ {
+ if ($match[1] === '')
+ {
+ $match['scheme'] = null;
+ }
+ if (!isset($match[3]) || $match[3] === '')
+ {
+ $match['authority'] = null;
+ }
+ if (!isset($match[5]))
+ {
+ $match['path'] = '';
+ }
+ if (!isset($match[6]) || $match[6] === '')
+ {
+ $match['query'] = null;
+ }
+ if (!isset($match[8]) || $match[8] === '')
+ {
+ $match['fragment'] = null;
+ }
+ return $match;
+ }
+
+ // This can occur when a paragraph is accidentally parsed as a URI
+ return false;
+ }
+
+ /**
+ * Remove dot segments from a path
+ *
+ * @param string $input
+ * @return string
+ */
+ protected function remove_dot_segments($input)
+ {
+ $output = '';
+ while (strpos($input, './') !== false || strpos($input, '/.') !== false || $input === '.' || $input === '..')
+ {
+ // A: If the input buffer begins with a prefix of "../" or "./", then remove that prefix from the input buffer; otherwise,
+ if (strpos($input, '../') === 0)
+ {
+ $input = substr($input, 3);
+ }
+ elseif (strpos($input, './') === 0)
+ {
+ $input = substr($input, 2);
+ }
+ // B: if the input buffer begins with a prefix of "/./" or "/.", where "." is a complete path segment, then replace that prefix with "/" in the input buffer; otherwise,
+ elseif (strpos($input, '/./') === 0)
+ {
+ $input = substr($input, 2);
+ }
+ elseif ($input === '/.')
+ {
+ $input = '/';
+ }
+ // C: if the input buffer begins with a prefix of "/../" or "/..", where ".." is a complete path segment, then replace that prefix with "/" in the input buffer and remove the last segment and its preceding "/" (if any) from the output buffer; otherwise,
+ elseif (strpos($input, '/../') === 0)
+ {
+ $input = substr($input, 3);
+ $output = substr_replace($output, '', strrpos($output, '/'));
+ }
+ elseif ($input === '/..')
+ {
+ $input = '/';
+ $output = substr_replace($output, '', strrpos($output, '/'));
+ }
+ // D: if the input buffer consists only of "." or "..", then remove that from the input buffer; otherwise,
+ elseif ($input === '.' || $input === '..')
+ {
+ $input = '';
+ }
+ // E: move the first path segment in the input buffer to the end of the output buffer, including the initial "/" character (if any) and any subsequent characters up to, but not including, the next "/" character or the end of the input buffer
+ elseif (($pos = strpos($input, '/', 1)) !== false)
+ {
+ $output .= substr($input, 0, $pos);
+ $input = substr_replace($input, '', 0, $pos);
+ }
+ else
+ {
+ $output .= $input;
+ $input = '';
+ }
+ }
+ return $output . $input;
+ }
+
+ /**
+ * Replace invalid character with percent encoding
+ *
+ * @param string $string Input string
+ * @param string $extra_chars Valid characters not in iunreserved or
+ * iprivate (this is ASCII-only)
+ * @param bool $iprivate Allow iprivate
+ * @return string
+ */
+ protected function replace_invalid_with_pct_encoding($string, $extra_chars, $iprivate = false)
+ {
+ // Normalize as many pct-encoded sections as possible
+ $string = preg_replace_callback('/(?:%[A-Fa-f0-9]{2})+/', array($this, 'remove_iunreserved_percent_encoded'), $string);
+
+ // Replace invalid percent characters
+ $string = preg_replace('/%(?![A-Fa-f0-9]{2})/', '%25', $string);
+
+ // Add unreserved and % to $extra_chars (the latter is safe because all
+ // pct-encoded sections are now valid).
+ $extra_chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~%';
+
+ // Now replace any bytes that aren't allowed with their pct-encoded versions
+ $position = 0;
+ $strlen = strlen($string);
+ while (($position += strspn($string, $extra_chars, $position)) < $strlen)
+ {
+ $value = ord($string[$position]);
+
+ // Start position
+ $start = $position;
+
+ // By default we are valid
+ $valid = true;
+
+ // No one byte sequences are valid due to the while.
+ // Two byte sequence:
+ if (($value & 0xE0) === 0xC0)
+ {
+ $character = ($value & 0x1F) << 6;
+ $length = 2;
+ $remaining = 1;
+ }
+ // Three byte sequence:
+ elseif (($value & 0xF0) === 0xE0)
+ {
+ $character = ($value & 0x0F) << 12;
+ $length = 3;
+ $remaining = 2;
+ }
+ // Four byte sequence:
+ elseif (($value & 0xF8) === 0xF0)
+ {
+ $character = ($value & 0x07) << 18;
+ $length = 4;
+ $remaining = 3;
+ }
+ // Invalid byte:
+ else
+ {
+ $valid = false;
+ $length = 1;
+ $remaining = 0;
+ }
+
+ if ($remaining)
+ {
+ if ($position + $length <= $strlen)
+ {
+ for ($position++; $remaining; $position++)
+ {
+ $value = ord($string[$position]);
+
+ // Check that the byte is valid, then add it to the character:
+ if (($value & 0xC0) === 0x80)
+ {
+ $character |= ($value & 0x3F) << (--$remaining * 6);
+ }
+ // If it is invalid, count the sequence as invalid and reprocess the current byte:
+ else
+ {
+ $valid = false;
+ $position--;
+ break;
+ }
+ }
+ }
+ else
+ {
+ $position = $strlen - 1;
+ $valid = false;
+ }
+ }
+
+ // Percent encode anything invalid or not in ucschar
+ if (
+ // Invalid sequences
+ !$valid
+ // Non-shortest form sequences are invalid
+ || $length > 1 && $character <= 0x7F
+ || $length > 2 && $character <= 0x7FF
+ || $length > 3 && $character <= 0xFFFF
+ // Outside of range of ucschar codepoints
+ // Noncharacters
+ || ($character & 0xFFFE) === 0xFFFE
+ || $character >= 0xFDD0 && $character <= 0xFDEF
+ || (
+ // Everything else not in ucschar
+ $character > 0xD7FF && $character < 0xF900
+ || $character < 0xA0
+ || $character > 0xEFFFD
+ )
+ && (
+ // Everything not in iprivate, if it applies
+ !$iprivate
+ || $character < 0xE000
+ || $character > 0x10FFFD
+ )
+ )
+ {
+ // If we were a character, pretend we weren't, but rather an error.
+ if ($valid)
+ $position--;
+
+ for ($j = $start; $j <= $position; $j++)
+ {
+ $string = substr_replace($string, sprintf('%%%02X', ord($string[$j])), $j, 1);
+ $j += 2;
+ $position += 2;
+ $strlen += 2;
+ }
+ }
+ }
+
+ return $string;
+ }
+
+ /**
+ * Callback function for preg_replace_callback.
+ *
+ * Removes sequences of percent encoded bytes that represent UTF-8
+ * encoded characters in iunreserved
+ *
+ * @param array $match PCRE match
+ * @return string Replacement
+ */
+ protected function remove_iunreserved_percent_encoded($match)
+ {
+ // As we just have valid percent encoded sequences we can just explode
+ // and ignore the first member of the returned array (an empty string).
+ $bytes = explode('%', $match[0]);
+
+ // Initialize the new string (this is what will be returned) and that
+ // there are no bytes remaining in the current sequence (unsurprising
+ // at the first byte!).
+ $string = '';
+ $remaining = 0;
+
+ // Loop over each and every byte, and set $value to its value
+ for ($i = 1, $len = count($bytes); $i < $len; $i++)
+ {
+ $value = hexdec($bytes[$i]);
+
+ // If we're the first byte of sequence:
+ if (!$remaining)
+ {
+ // Start position
+ $start = $i;
+
+ // By default we are valid
+ $valid = true;
+
+ // One byte sequence:
+ if ($value <= 0x7F)
+ {
+ $character = $value;
+ $length = 1;
+ }
+ // Two byte sequence:
+ elseif (($value & 0xE0) === 0xC0)
+ {
+ $character = ($value & 0x1F) << 6;
+ $length = 2;
+ $remaining = 1;
+ }
+ // Three byte sequence:
+ elseif (($value & 0xF0) === 0xE0)
+ {
+ $character = ($value & 0x0F) << 12;
+ $length = 3;
+ $remaining = 2;
+ }
+ // Four byte sequence:
+ elseif (($value & 0xF8) === 0xF0)
+ {
+ $character = ($value & 0x07) << 18;
+ $length = 4;
+ $remaining = 3;
+ }
+ // Invalid byte:
+ else
+ {
+ $valid = false;
+ $remaining = 0;
+ }
+ }
+ // Continuation byte:
+ else
+ {
+ // Check that the byte is valid, then add it to the character:
+ if (($value & 0xC0) === 0x80)
+ {
+ $remaining--;
+ $character |= ($value & 0x3F) << ($remaining * 6);
+ }
+ // If it is invalid, count the sequence as invalid and reprocess the current byte as the start of a sequence:
+ else
+ {
+ $valid = false;
+ $remaining = 0;
+ $i--;
+ }
+ }
+
+ // If we've reached the end of the current byte sequence, append it to Unicode::$data
+ if (!$remaining)
+ {
+ // Percent encode anything invalid or not in iunreserved
+ if (
+ // Invalid sequences
+ !$valid
+ // Non-shortest form sequences are invalid
+ || $length > 1 && $character <= 0x7F
+ || $length > 2 && $character <= 0x7FF
+ || $length > 3 && $character <= 0xFFFF
+ // Outside of range of iunreserved codepoints
+ || $character < 0x2D
+ || $character > 0xEFFFD
+ // Noncharacters
+ || ($character & 0xFFFE) === 0xFFFE
+ || $character >= 0xFDD0 && $character <= 0xFDEF
+ // Everything else not in iunreserved (this is all BMP)
+ || $character === 0x2F
+ || $character > 0x39 && $character < 0x41
+ || $character > 0x5A && $character < 0x61
+ || $character > 0x7A && $character < 0x7E
+ || $character > 0x7E && $character < 0xA0
+ || $character > 0xD7FF && $character < 0xF900
+ )
+ {
+ for ($j = $start; $j <= $i; $j++)
+ {
+ $string .= '%' . strtoupper($bytes[$j]);
+ }
+ }
+ else
+ {
+ for ($j = $start; $j <= $i; $j++)
+ {
+ $string .= chr(hexdec($bytes[$j]));
+ }
+ }
+ }
+ }
+
+ // If we have any bytes left over they are invalid (i.e., we are
+ // mid-way through a multi-byte sequence)
+ if ($remaining)
+ {
+ for ($j = $start; $j < $len; $j++)
+ {
+ $string .= '%' . strtoupper($bytes[$j]);
+ }
+ }
+
+ return $string;
+ }
+
+ protected function scheme_normalization()
+ {
+ if (isset($this->normalization[$this->scheme]['iuserinfo']) && $this->iuserinfo === $this->normalization[$this->scheme]['iuserinfo'])
+ {
+ $this->iuserinfo = null;
+ }
+ if (isset($this->normalization[$this->scheme]['ihost']) && $this->ihost === $this->normalization[$this->scheme]['ihost'])
+ {
+ $this->ihost = null;
+ }
+ if (isset($this->normalization[$this->scheme]['port']) && $this->port === $this->normalization[$this->scheme]['port'])
+ {
+ $this->port = null;
+ }
+ if (isset($this->normalization[$this->scheme]['ipath']) && $this->ipath === $this->normalization[$this->scheme]['ipath'])
+ {
+ $this->ipath = '';
+ }
+ if (isset($this->normalization[$this->scheme]['iquery']) && $this->iquery === $this->normalization[$this->scheme]['iquery'])
+ {
+ $this->iquery = null;
+ }
+ if (isset($this->normalization[$this->scheme]['ifragment']) && $this->ifragment === $this->normalization[$this->scheme]['ifragment'])
+ {
+ $this->ifragment = null;
+ }
+ }
+
+ /**
+ * Check if the object represents a valid IRI. This needs to be done on each
+ * call as some things change depending on another part of the IRI.
+ *
+ * @return bool
+ */
+ public function is_valid()
+ {
+ if ($this->ipath === '') return true;
+
+ $isauthority = $this->iuserinfo !== null || $this->ihost !== null ||
+ $this->port !== null;
+ if ($isauthority && $this->ipath[0] === '/') return true;
+
+ if (!$isauthority && (substr($this->ipath, 0, 2) === '//')) return false;
+
+ // Relative urls cannot have a colon in the first path segment (and the
+ // slashes themselves are not included so skip the first character).
+ if (!$this->scheme && !$isauthority &&
+ strpos($this->ipath, ':') !== false &&
+ strpos($this->ipath, '/', 1) !== false &&
+ strpos($this->ipath, ':') < strpos($this->ipath, '/', 1)) return false;
+
+ return true;
+ }
+
+ /**
+ * Set the entire IRI. Returns true on success, false on failure (if there
+ * are any invalid characters).
+ *
+ * @param string $iri
+ * @return bool
+ */
+ public function set_iri($iri, $clear_cache = false)
+ {
+ static $cache;
+ if ($clear_cache)
+ {
+ $cache = null;
+ return;
+ }
+ if (!$cache)
+ {
+ $cache = array();
+ }
+
+ if ($iri === null)
+ {
+ return true;
+ }
+ elseif (isset($cache[$iri]))
+ {
+ list($this->scheme,
+ $this->iuserinfo,
+ $this->ihost,
+ $this->port,
+ $this->ipath,
+ $this->iquery,
+ $this->ifragment,
+ $return) = $cache[$iri];
+ return $return;
+ }
+
+ $parsed = $this->parse_iri((string) $iri);
+ if (!$parsed)
+ {
+ return false;
+ }
+
+ $return = $this->set_scheme($parsed['scheme'])
+ && $this->set_authority($parsed['authority'])
+ && $this->set_path($parsed['path'])
+ && $this->set_query($parsed['query'])
+ && $this->set_fragment($parsed['fragment']);
+
+ $cache[$iri] = array($this->scheme,
+ $this->iuserinfo,
+ $this->ihost,
+ $this->port,
+ $this->ipath,
+ $this->iquery,
+ $this->ifragment,
+ $return);
+ return $return;
+ }
+
+ /**
+ * Set the scheme. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @param string $scheme
+ * @return bool
+ */
+ public function set_scheme($scheme)
+ {
+ if ($scheme === null)
+ {
+ $this->scheme = null;
+ }
+ elseif (!preg_match('/^[A-Za-z][0-9A-Za-z+\-.]*$/', $scheme))
+ {
+ $this->scheme = null;
+ return false;
+ }
+ else
+ {
+ $this->scheme = strtolower($scheme);
+ }
+ return true;
+ }
+
+ /**
+ * Set the authority. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @param string $authority
+ * @return bool
+ */
+ public function set_authority($authority, $clear_cache = false)
+ {
+ static $cache;
+ if ($clear_cache)
+ {
+ $cache = null;
+ return;
+ }
+ if (!$cache)
+ $cache = array();
+
+ if ($authority === null)
+ {
+ $this->iuserinfo = null;
+ $this->ihost = null;
+ $this->port = null;
+ return true;
+ }
+ elseif (isset($cache[$authority]))
+ {
+ list($this->iuserinfo,
+ $this->ihost,
+ $this->port,
+ $return) = $cache[$authority];
+
+ return $return;
+ }
+
+ $remaining = $authority;
+ if (($iuserinfo_end = strrpos($remaining, '@')) !== false)
+ {
+ $iuserinfo = substr($remaining, 0, $iuserinfo_end);
+ $remaining = substr($remaining, $iuserinfo_end + 1);
+ }
+ else
+ {
+ $iuserinfo = null;
+ }
+ if (($port_start = strpos($remaining, ':', strpos($remaining, ']'))) !== false)
+ {
+ if (($port = substr($remaining, $port_start + 1)) === false)
+ {
+ $port = null;
+ }
+ $remaining = substr($remaining, 0, $port_start);
+ }
+ else
+ {
+ $port = null;
+ }
+
+ $return = $this->set_userinfo($iuserinfo) &&
+ $this->set_host($remaining) &&
+ $this->set_port($port);
+
+ $cache[$authority] = array($this->iuserinfo,
+ $this->ihost,
+ $this->port,
+ $return);
+
+ return $return;
+ }
+
+ /**
+ * Set the iuserinfo.
+ *
+ * @param string $iuserinfo
+ * @return bool
+ */
+ public function set_userinfo($iuserinfo)
+ {
+ if ($iuserinfo === null)
+ {
+ $this->iuserinfo = null;
+ }
+ else
+ {
+ $this->iuserinfo = $this->replace_invalid_with_pct_encoding($iuserinfo, '!$&\'()*+,;=:');
+ $this->scheme_normalization();
+ }
+
+ return true;
+ }
+
+ /**
+ * Set the ihost. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @param string $ihost
+ * @return bool
+ */
+ public function set_host($ihost)
+ {
+ if ($ihost === null)
+ {
+ $this->ihost = null;
+ return true;
+ }
+ elseif (substr($ihost, 0, 1) === '[' && substr($ihost, -1) === ']')
+ {
+ if (SimplePie_Net_IPv6::check_ipv6(substr($ihost, 1, -1)))
+ {
+ $this->ihost = '[' . SimplePie_Net_IPv6::compress(substr($ihost, 1, -1)) . ']';
+ }
+ else
+ {
+ $this->ihost = null;
+ return false;
+ }
+ }
+ else
+ {
+ $ihost = $this->replace_invalid_with_pct_encoding($ihost, '!$&\'()*+,;=');
+
+ // Lowercase, but ignore pct-encoded sections (as they should
+ // remain uppercase). This must be done after the previous step
+ // as that can add unescaped characters.
+ $position = 0;
+ $strlen = strlen($ihost);
+ while (($position += strcspn($ihost, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ%', $position)) < $strlen)
+ {
+ if ($ihost[$position] === '%')
+ {
+ $position += 3;
+ }
+ else
+ {
+ $ihost[$position] = strtolower($ihost[$position]);
+ $position++;
+ }
+ }
+
+ $this->ihost = $ihost;
+ }
+
+ $this->scheme_normalization();
+
+ return true;
+ }
+
+ /**
+ * Set the port. Returns true on success, false on failure (if there are
+ * any invalid characters).
+ *
+ * @param string $port
+ * @return bool
+ */
+ public function set_port($port)
+ {
+ if ($port === null)
+ {
+ $this->port = null;
+ return true;
+ }
+ elseif (strspn($port, '0123456789') === strlen($port))
+ {
+ $this->port = (int) $port;
+ $this->scheme_normalization();
+ return true;
+ }
+
+ $this->port = null;
+ return false;
+ }
+
+ /**
+ * Set the ipath.
+ *
+ * @param string $ipath
+ * @return bool
+ */
+ public function set_path($ipath, $clear_cache = false)
+ {
+ static $cache;
+ if ($clear_cache)
+ {
+ $cache = null;
+ return;
+ }
+ if (!$cache)
+ {
+ $cache = array();
+ }
+
+ $ipath = (string) $ipath;
+
+ if (isset($cache[$ipath]))
+ {
+ $this->ipath = $cache[$ipath][(int) ($this->scheme !== null)];
+ }
+ else
+ {
+ $valid = $this->replace_invalid_with_pct_encoding($ipath, '!$&\'()*+,;=@:/');
+ $removed = $this->remove_dot_segments($valid);
+
+ $cache[$ipath] = array($valid, $removed);
+ $this->ipath = ($this->scheme !== null) ? $removed : $valid;
+ }
+
+ $this->scheme_normalization();
+ return true;
+ }
+
+ /**
+ * Set the iquery.
+ *
+ * @param string $iquery
+ * @return bool
+ */
+ public function set_query($iquery)
+ {
+ if ($iquery === null)
+ {
+ $this->iquery = null;
+ }
+ else
+ {
+ $this->iquery = $this->replace_invalid_with_pct_encoding($iquery, '!$&\'()*+,;=:@/?', true);
+ $this->scheme_normalization();
+ }
+ return true;
+ }
+
+ /**
+ * Set the ifragment.
+ *
+ * @param string $ifragment
+ * @return bool
+ */
+ public function set_fragment($ifragment)
+ {
+ if ($ifragment === null)
+ {
+ $this->ifragment = null;
+ }
+ else
+ {
+ $this->ifragment = $this->replace_invalid_with_pct_encoding($ifragment, '!$&\'()*+,;=:@/?');
+ $this->scheme_normalization();
+ }
+ return true;
+ }
+
+ /**
+ * Convert an IRI to a URI (or parts thereof)
+ *
+ * @return string
+ */
+ public function to_uri($string)
+ {
+ static $non_ascii;
+ if (!$non_ascii)
+ {
+ $non_ascii = implode('', range("\x80", "\xFF"));
+ }
+
+ $position = 0;
+ $strlen = strlen($string);
+ while (($position += strcspn($string, $non_ascii, $position)) < $strlen)
+ {
+ $string = substr_replace($string, sprintf('%%%02X', ord($string[$position])), $position, 1);
+ $position += 3;
+ $strlen += 2;
+ }
+
+ return $string;
+ }
+
+ /**
+ * Get the complete IRI
+ *
+ * @return string
+ */
+ public function get_iri()
+ {
+ if (!$this->is_valid())
+ {
+ return false;
+ }
+
+ $iri = '';
+ if ($this->scheme !== null)
+ {
+ $iri .= $this->scheme . ':';
+ }
+ if (($iauthority = $this->get_iauthority()) !== null)
+ {
+ $iri .= '//' . $iauthority;
+ }
+ if ($this->ipath !== '')
+ {
+ $iri .= $this->ipath;
+ }
+ elseif (!empty($this->normalization[$this->scheme]['ipath']) && $iauthority !== null && $iauthority !== '')
+ {
+ $iri .= $this->normalization[$this->scheme]['ipath'];
+ }
+ if ($this->iquery !== null)
+ {
+ $iri .= '?' . $this->iquery;
+ }
+ if ($this->ifragment !== null)
+ {
+ $iri .= '#' . $this->ifragment;
+ }
+
+ return $iri;
+ }
+
+ /**
+ * Get the complete URI
+ *
+ * @return string
+ */
+ public function get_uri()
+ {
+ return $this->to_uri($this->get_iri());
+ }
+
+ /**
+ * Get the complete iauthority
+ *
+ * @return string
+ */
+ protected function get_iauthority()
+ {
+ if ($this->iuserinfo !== null || $this->ihost !== null || $this->port !== null)
+ {
+ $iauthority = '';
+ if ($this->iuserinfo !== null)
+ {
+ $iauthority .= $this->iuserinfo . '@';
+ }
+ if ($this->ihost !== null)
+ {
+ $iauthority .= $this->ihost;
+ }
+ if ($this->port !== null && $this->port !== 0)
+ {
+ $iauthority .= ':' . $this->port;
+ }
+ return $iauthority;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the complete authority
+ *
+ * @return string
+ */
+ protected function get_authority()
+ {
+ $iauthority = $this->get_iauthority();
+ if (is_string($iauthority))
+ return $this->to_uri($iauthority);
+
+ return $iauthority;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Item.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Item.php
new file mode 100644
index 0000000..5be6b19
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Item.php
@@ -0,0 +1,2966 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+
+/**
+ * Manages all item-related data
+ *
+ * Used by {@see SimplePie::get_item()} and {@see SimplePie::get_items()}
+ *
+ * This class can be overloaded with {@see SimplePie::set_item_class()}
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Item
+{
+ /**
+ * Parent feed
+ *
+ * @access private
+ * @var SimplePie
+ */
+ var $feed;
+
+ /**
+ * Raw data
+ *
+ * @access private
+ * @var array
+ */
+ var $data = array();
+
+ /**
+ * Registry object
+ *
+ * @see set_registry
+ * @var SimplePie_Registry
+ */
+ protected $registry;
+
+ /**
+ * Create a new item object
+ *
+ * This is usually used by {@see SimplePie::get_items} and
+ * {@see SimplePie::get_item}. Avoid creating this manually.
+ *
+ * @param SimplePie $feed Parent feed
+ * @param array $data Raw data
+ */
+ public function __construct($feed, $data)
+ {
+ $this->feed = $feed;
+ $this->data = $data;
+ }
+
+ /**
+ * Set the registry handler
+ *
+ * This is usually used by {@see SimplePie_Registry::create}
+ *
+ * @since 1.3
+ * @param SimplePie_Registry $registry
+ */
+ public function set_registry(SimplePie_Registry $registry)
+ {
+ $this->registry = $registry;
+ }
+
+ /**
+ * Get a string representation of the item
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ return md5(serialize($this->data));
+ }
+
+ /**
+ * Remove items that link back to this before destroying this object
+ */
+ public function __destruct()
+ {
+ if (!gc_enabled())
+ {
+ unset($this->feed);
+ }
+ }
+
+ /**
+ * Get data for an item-level element
+ *
+ * This method allows you to get access to ANY element/attribute that is a
+ * sub-element of the item/entry tag.
+ *
+ * See {@see SimplePie::get_feed_tags()} for a description of the return value
+ *
+ * @since 1.0
+ * @see http://simplepie.org/wiki/faq/supported_xml_namespaces
+ * @param string $namespace The URL of the XML namespace of the elements you're trying to access
+ * @param string $tag Tag name
+ * @return array
+ */
+ public function get_item_tags($namespace, $tag)
+ {
+ if (isset($this->data['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][$namespace][$tag];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the base URL value from the parent feed
+ *
+ * Uses `<xml:base>`
+ *
+ * @param array $element
+ * @return string
+ */
+ public function get_base($element = array())
+ {
+ return $this->feed->get_base($element);
+ }
+
+ /**
+ * Sanitize feed data
+ *
+ * @access private
+ * @see SimplePie::sanitize()
+ * @param string $data Data to sanitize
+ * @param int $type One of the SIMPLEPIE_CONSTRUCT_* constants
+ * @param string $base Base URL to resolve URLs against
+ * @return string Sanitized data
+ */
+ public function sanitize($data, $type, $base = '')
+ {
+ return $this->feed->sanitize($data, $type, $base);
+ }
+
+ /**
+ * Get the parent feed
+ *
+ * Note: this may not work as you think for multifeeds!
+ *
+ * @link http://simplepie.org/faq/typical_multifeed_gotchas#missing_data_from_feed
+ * @since 1.0
+ * @return SimplePie
+ */
+ public function get_feed()
+ {
+ return $this->feed;
+ }
+
+ /**
+ * Get the unique identifier for the item
+ *
+ * This is usually used when writing code to check for new items in a feed.
+ *
+ * Uses `<atom:id>`, `<guid>`, `<dc:identifier>` or the `about` attribute
+ * for RDF. If none of these are supplied (or `$hash` is true), creates an
+ * MD5 hash based on the permalink, title and content.
+ *
+ * @since Beta 2
+ * @param boolean $hash Should we force using a hash instead of the supplied ID?
+ * @param string|false $fn User-supplied function to generate an hash
+ * @return string|null
+ */
+ public function get_id($hash = false, $fn = 'md5')
+ {
+ if (!$hash)
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'id'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'id'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'identifier'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'identifier'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about']))
+ {
+ return $this->sanitize($this->data['attribs'][SIMPLEPIE_NAMESPACE_RDF]['about'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ }
+ if ($fn === false)
+ {
+ return null;
+ }
+ elseif (!is_callable($fn))
+ {
+ trigger_error('User-supplied function $fn must be callable', E_USER_WARNING);
+ $fn = 'md5';
+ }
+ return call_user_func($fn,
+ $this->get_permalink().$this->get_title().$this->get_content());
+ }
+
+ /**
+ * Get the title of the item
+ *
+ * Uses `<atom:title>`, `<title>` or `<dc:title>`
+ *
+ * @since Beta 2 (previously called `get_item_title` since 0.8)
+ * @return string|null
+ */
+ public function get_title()
+ {
+ if (!isset($this->data['title']))
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
+ {
+ $this->data['title'] = $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $this->data['title'] = null;
+ }
+ }
+ return $this->data['title'];
+ }
+
+ /**
+ * Get the content for the item
+ *
+ * Prefers summaries over full content , but will return full content if a
+ * summary does not exist.
+ *
+ * To prefer full content instead, use {@see get_content}
+ *
+ * Uses `<atom:summary>`, `<description>`, `<dc:description>` or
+ * `<itunes:subtitle>`
+ *
+ * @since 0.8
+ * @param boolean $description_only Should we avoid falling back to the content?
+ * @return string|null
+ */
+ public function get_description($description_only = false)
+ {
+ if (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'summary')) &&
+ ($return = $this->sanitize($tags[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($tags[0]['attribs'])), $this->get_base($tags[0]))))
+ {
+ return $return;
+ }
+ elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'summary')) &&
+ ($return = $this->sanitize($tags[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($tags[0]['attribs'])), $this->get_base($tags[0]))))
+ {
+ return $return;
+ }
+ elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description')) &&
+ ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($tags[0]))))
+ {
+ return $return;
+ }
+ elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description')) &&
+ ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($tags[0]))))
+ {
+ return $return;
+ }
+ elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description')) &&
+ ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)))
+ {
+ return $return;
+ }
+ elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description')) &&
+ ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)))
+ {
+ return $return;
+ }
+ elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary')) &&
+ ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($tags[0]))))
+ {
+ return $return;
+ }
+ elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle')) &&
+ ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)))
+ {
+ return $return;
+ }
+ elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description')) &&
+ ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_HTML)))
+ {
+ return $return;
+ }
+
+ elseif (!$description_only)
+ {
+ return $this->get_content(true);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the content for the item
+ *
+ * Prefers full content over summaries, but will return a summary if full
+ * content does not exist.
+ *
+ * To prefer summaries instead, use {@see get_description}
+ *
+ * Uses `<atom:content>` or `<content:encoded>` (RSS 1.0 Content Module)
+ *
+ * @since 1.0
+ * @param boolean $content_only Should we avoid falling back to the description?
+ * @return string|null
+ */
+ public function get_content($content_only = false)
+ {
+ if (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'content')) &&
+ ($return = $this->sanitize($tags[0]['data'], $this->registry->call('Misc', 'atom_10_content_construct_type', array($tags[0]['attribs'])), $this->get_base($tags[0]))))
+ {
+ return $return;
+ }
+ elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'content')) &&
+ ($return = $this->sanitize($tags[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($tags[0]['attribs'])), $this->get_base($tags[0]))))
+ {
+ return $return;
+ }
+ elseif (($tags = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10_MODULES_CONTENT, 'encoded')) &&
+ ($return = $this->sanitize($tags[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($tags[0]))))
+ {
+ return $return;
+ }
+ elseif (!$content_only)
+ {
+ return $this->get_description(true);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the media:thumbnail of the item
+ *
+ * Uses `<media:thumbnail>`
+ *
+ *
+ * @return array|null
+ */
+ public function get_thumbnail()
+ {
+ if (!isset($this->data['thumbnail']))
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
+ {
+ $this->data['thumbnail'] = $return[0]['attribs'][''];
+ }
+ else
+ {
+ $this->data['thumbnail'] = null;
+ }
+ }
+ return $this->data['thumbnail'];
+ }
+
+ /**
+ * Get a category for the item
+ *
+ * @since Beta 3 (previously called `get_categories()` since Beta 2)
+ * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1
+ * @return SimplePie_Category|null
+ */
+ public function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all categories for the item
+ *
+ * Uses `<atom:category>`, `<category>` or `<dc:subject>`
+ *
+ * @since Beta 3
+ * @return SimplePie_Category[]|null List of {@see SimplePie_Category} objects
+ */
+ public function get_categories()
+ {
+ $categories = array();
+
+ $type = 'category';
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, $type) as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['attribs']['']['term']))
+ {
+ $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] = $this->registry->create('Category', array($term, $scheme, $label, $type));
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, $type) as $category)
+ {
+ // This is really the label, but keep this as the term also for BC.
+ // Label will also work on retrieving because that falls back to term.
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ if (isset($category['attribs']['']['domain']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = null;
+ }
+ $categories[] = $this->registry->create('Category', array($term, $scheme, null, $type));
+ }
+
+ $type = 'subject';
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, $type) as $category)
+ {
+ $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null, $type));
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, $type) as $category)
+ {
+ $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null, $type));
+ }
+
+ if (!empty($categories))
+ {
+ return array_unique($categories);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get an author for the item
+ *
+ * @since Beta 2
+ * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1
+ * @return SimplePie_Author|null
+ */
+ public function get_author($key = 0)
+ {
+ $authors = $this->get_authors();
+ if (isset($authors[$key]))
+ {
+ return $authors[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a contributor for the item
+ *
+ * @since 1.1
+ * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1
+ * @return SimplePie_Author|null
+ */
+ public function get_contributor($key = 0)
+ {
+ $contributors = $this->get_contributors();
+ if (isset($contributors[$key]))
+ {
+ return $contributors[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all contributors for the item
+ *
+ * Uses `<atom:contributor>`
+ *
+ * @since 1.1
+ * @return SimplePie_Author[]|null List of {@see SimplePie_Author} objects
+ */
+ public function get_contributors()
+ {
+ $contributors = array();
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
+ }
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $contributors[] = $this->registry->create('Author', array($name, $url, $email));
+ }
+ }
+
+ if (!empty($contributors))
+ {
+ return array_unique($contributors);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all authors for the item
+ *
+ * Uses `<atom:author>`, `<author>`, `<dc:creator>` or `<itunes:author>`
+ *
+ * @since Beta 2
+ * @return SimplePie_Author[]|null List of {@see SimplePie_Author} objects
+ */
+ public function get_authors()
+ {
+ $authors = array();
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $authors[] = $this->registry->create('Author', array($name, $uri, $email));
+ }
+ }
+ if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $authors[] = $this->registry->create('Author', array($name, $url, $email));
+ }
+ }
+ if ($author = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'author'))
+ {
+ $authors[] = $this->registry->create('Author', array(null, null, $this->sanitize($author[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT)));
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
+ {
+ $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
+ {
+ $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
+ {
+ $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+
+ if (!empty($authors))
+ {
+ return array_unique($authors);
+ }
+ elseif (($source = $this->get_source()) && ($authors = $source->get_authors()))
+ {
+ return $authors;
+ }
+ elseif ($authors = $this->feed->get_authors())
+ {
+ return $authors;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the copyright info for the item
+ *
+ * Uses `<atom:rights>` or `<dc:rights>`
+ *
+ * @since 1.1
+ * @return string
+ */
+ public function get_copyright()
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the posting date/time for the item
+ *
+ * Uses `<atom:published>`, `<atom:updated>`, `<atom:issued>`,
+ * `<atom:modified>`, `<pubDate>` or `<dc:date>`
+ *
+ * Note: obeys PHP's timezone setting. To get a UTC date/time, use
+ * {@see get_gmdate}
+ *
+ * @since Beta 2 (previously called `get_item_date` since 0.8)
+ *
+ * @param string $date_format Supports any PHP date format from {@see http://php.net/date} (empty for the raw data)
+ * @return int|string|null
+ */
+ public function get_date($date_format = 'j F Y, g:i a')
+ {
+ if (!isset($this->data['date']))
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'pubDate'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_11, 'date'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_DC_10, 'date'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'issued'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'created'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'modified'))
+ {
+ $this->data['date']['raw'] = $return[0]['data'];
+ }
+
+ if (!empty($this->data['date']['raw']))
+ {
+ $parser = $this->registry->call('Parse_Date', 'get');
+ $this->data['date']['parsed'] = $parser->parse($this->data['date']['raw']);
+ }
+ else
+ {
+ $this->data['date'] = null;
+ }
+ }
+ if ($this->data['date'])
+ {
+ $date_format = (string) $date_format;
+ switch ($date_format)
+ {
+ case '':
+ return $this->sanitize($this->data['date']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
+
+ case 'U':
+ return $this->data['date']['parsed'];
+
+ default:
+ return date($date_format, $this->data['date']['parsed']);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the update date/time for the item
+ *
+ * Uses `<atom:updated>`
+ *
+ * Note: obeys PHP's timezone setting. To get a UTC date/time, use
+ * {@see get_gmdate}
+ *
+ * @param string $date_format Supports any PHP date format from {@see http://php.net/date} (empty for the raw data)
+ * @return int|string|null
+ */
+ public function get_updated_date($date_format = 'j F Y, g:i a')
+ {
+ if (!isset($this->data['updated']))
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'))
+ {
+ $this->data['updated']['raw'] = $return[0]['data'];
+ }
+
+ if (!empty($this->data['updated']['raw']))
+ {
+ $parser = $this->registry->call('Parse_Date', 'get');
+ $this->data['updated']['parsed'] = $parser->parse($this->data['updated']['raw']);
+ }
+ else
+ {
+ $this->data['updated'] = null;
+ }
+ }
+ if ($this->data['updated'])
+ {
+ $date_format = (string) $date_format;
+ switch ($date_format)
+ {
+ case '':
+ return $this->sanitize($this->data['updated']['raw'], SIMPLEPIE_CONSTRUCT_TEXT);
+
+ case 'U':
+ return $this->data['updated']['parsed'];
+
+ default:
+ return date($date_format, $this->data['updated']['parsed']);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the localized posting date/time for the item
+ *
+ * Returns the date formatted in the localized language. To display in
+ * languages other than the server's default, you need to change the locale
+ * with {@link http://php.net/setlocale setlocale()}. The available
+ * localizations depend on which ones are installed on your web server.
+ *
+ * @since 1.0
+ *
+ * @param string $date_format Supports any PHP date format from {@see http://php.net/strftime} (empty for the raw data)
+ * @return int|string|null
+ */
+ public function get_local_date($date_format = '%c')
+ {
+ if (!$date_format)
+ {
+ return $this->sanitize($this->get_date(''), SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (($date = $this->get_date('U')) !== null && $date !== false)
+ {
+ return strftime($date_format, $date);
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the posting date/time for the item (UTC time)
+ *
+ * @see get_date
+ * @param string $date_format Supports any PHP date format from {@see http://php.net/date}
+ * @return int|string|null
+ */
+ public function get_gmdate($date_format = 'j F Y, g:i a')
+ {
+ $date = $this->get_date('U');
+ if ($date === null)
+ {
+ return null;
+ }
+
+ return gmdate($date_format, $date);
+ }
+
+ /**
+ * Get the update date/time for the item (UTC time)
+ *
+ * @see get_updated_date
+ * @param string $date_format Supports any PHP date format from {@see http://php.net/date}
+ * @return int|string|null
+ */
+ public function get_updated_gmdate($date_format = 'j F Y, g:i a')
+ {
+ $date = $this->get_updated_date('U');
+ if ($date === null)
+ {
+ return null;
+ }
+
+ return gmdate($date_format, $date);
+ }
+
+ /**
+ * Get the permalink for the item
+ *
+ * Returns the first link available with a relationship of "alternate".
+ * Identical to {@see get_link()} with key 0
+ *
+ * @see get_link
+ * @since 0.8
+ * @return string|null Permalink URL
+ */
+ public function get_permalink()
+ {
+ $link = $this->get_link();
+ $enclosure = $this->get_enclosure(0);
+ if ($link !== null)
+ {
+ return $link;
+ }
+ elseif ($enclosure !== null)
+ {
+ return $enclosure->get_link();
+ }
+
+ return null;
+ }
+
+ /**
+ * Get a single link for the item
+ *
+ * @since Beta 3
+ * @param int $key The link that you want to return. Remember that arrays begin with 0, not 1
+ * @param string $rel The relationship of the link to return
+ * @return string|null Link URL
+ */
+ public function get_link($key = 0, $rel = 'alternate')
+ {
+ $links = $this->get_links($rel);
+ if ($links && $links[$key] !== null)
+ {
+ return $links[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all links for the item
+ *
+ * Uses `<atom:link>`, `<link>` or `<guid>`
+ *
+ * @since Beta 2
+ * @param string $rel The relationship of links to return
+ * @return array|null Links found for the item (strings)
+ */
+ public function get_links($rel = 'alternate')
+ {
+ if (!isset($this->data['links']))
+ {
+ $this->data['links'] = array();
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+
+ }
+ }
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+ }
+ }
+ if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'guid'))
+ {
+ if (!isset($links[0]['attribs']['']['isPermaLink']) || strtolower(trim($links[0]['attribs']['']['isPermaLink'])) === 'true')
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ }
+
+ $keys = array_keys($this->data['links']);
+ foreach ($keys as $key)
+ {
+ if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
+ {
+ if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
+ $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
+ }
+ else
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
+ }
+ }
+ elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
+ {
+ $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
+ }
+ $this->data['links'][$key] = array_unique($this->data['links'][$key]);
+ }
+ }
+ if (isset($this->data['links'][$rel]))
+ {
+ return $this->data['links'][$rel];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get an enclosure from the item
+ *
+ * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
+ *
+ * @since Beta 2
+ * @todo Add ability to prefer one type of content over another (in a media group).
+ * @param int $key The enclosure that you want to return. Remember that arrays begin with 0, not 1
+ * @return SimplePie_Enclosure|null
+ */
+ public function get_enclosure($key = 0, $prefer = null)
+ {
+ $enclosures = $this->get_enclosures();
+ if (isset($enclosures[$key]))
+ {
+ return $enclosures[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all available enclosures (podcasts, etc.)
+ *
+ * Supports the <enclosure> RSS tag, as well as Media RSS and iTunes RSS.
+ *
+ * At this point, we're pretty much assuming that all enclosures for an item
+ * are the same content. Anything else is too complicated to
+ * properly support.
+ *
+ * @since Beta 2
+ * @todo Add support for end-user defined sorting of enclosures by type/handler (so we can prefer the faster-loading FLV over MP4).
+ * @todo If an element exists at a level, but its value is empty, we should fall back to the value from the parent (if it exists).
+ * @return SimplePie_Enclosure[]|null List of SimplePie_Enclosure items
+ */
+ public function get_enclosures()
+ {
+ if (!isset($this->data['enclosures']))
+ {
+ $this->data['enclosures'] = array();
+
+ // Elements
+ $captions_parent = null;
+ $categories_parent = null;
+ $copyrights_parent = null;
+ $credits_parent = null;
+ $description_parent = null;
+ $duration_parent = null;
+ $hashes_parent = null;
+ $keywords_parent = null;
+ $player_parent = null;
+ $ratings_parent = null;
+ $restrictions_parent = null;
+ $thumbnails_parent = null;
+ $title_parent = null;
+
+ // Let's do the channel and item-level ones first, and just re-use them if we need to.
+ $parent = $this->get_feed();
+
+ // CAPTIONS
+ if ($captions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
+ {
+ foreach ($captions as $caption)
+ {
+ $caption_type = null;
+ $caption_lang = null;
+ $caption_startTime = null;
+ $caption_endTime = null;
+ $caption_text = null;
+ if (isset($caption['attribs']['']['type']))
+ {
+ $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['lang']))
+ {
+ $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['start']))
+ {
+ $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['end']))
+ {
+ $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['data']))
+ {
+ $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $captions_parent[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
+ }
+ }
+ elseif ($captions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'text'))
+ {
+ foreach ($captions as $caption)
+ {
+ $caption_type = null;
+ $caption_lang = null;
+ $caption_startTime = null;
+ $caption_endTime = null;
+ $caption_text = null;
+ if (isset($caption['attribs']['']['type']))
+ {
+ $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['lang']))
+ {
+ $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['start']))
+ {
+ $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['end']))
+ {
+ $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['data']))
+ {
+ $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $captions_parent[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
+ }
+ }
+ if (is_array($captions_parent))
+ {
+ $captions_parent = array_values(array_unique($captions_parent));
+ }
+
+ // CATEGORIES
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['data']))
+ {
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = 'http://search.yahoo.com/mrss/category_schema';
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
+ }
+ foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'category') as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['data']))
+ {
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = 'http://search.yahoo.com/mrss/category_schema';
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
+ }
+ foreach ((array) $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'category') as $category)
+ {
+ $term = null;
+ $scheme = 'http://www.itunes.com/dtds/podcast-1.0.dtd';
+ $label = null;
+ if (isset($category['attribs']['']['text']))
+ {
+ $label = $this->sanitize($category['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
+
+ if (isset($category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category']))
+ {
+ foreach ((array) $category['child'][SIMPLEPIE_NAMESPACE_ITUNES]['category'] as $subcategory)
+ {
+ if (isset($subcategory['attribs']['']['text']))
+ {
+ $label = $this->sanitize($subcategory['attribs']['']['text'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories_parent[] = $this->registry->create('Category', array($term, $scheme, $label));
+ }
+ }
+ }
+ if (is_array($categories_parent))
+ {
+ $categories_parent = array_values(array_unique($categories_parent));
+ }
+
+ // COPYRIGHT
+ if ($copyright = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
+ {
+ $copyright_url = null;
+ $copyright_label = null;
+ if (isset($copyright[0]['attribs']['']['url']))
+ {
+ $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($copyright[0]['data']))
+ {
+ $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $copyrights_parent = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
+ }
+ elseif ($copyright = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'copyright'))
+ {
+ $copyright_url = null;
+ $copyright_label = null;
+ if (isset($copyright[0]['attribs']['']['url']))
+ {
+ $copyright_url = $this->sanitize($copyright[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($copyright[0]['data']))
+ {
+ $copyright_label = $this->sanitize($copyright[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $copyrights_parent = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
+ }
+
+ // CREDITS
+ if ($credits = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
+ {
+ foreach ($credits as $credit)
+ {
+ $credit_role = null;
+ $credit_scheme = null;
+ $credit_name = null;
+ if (isset($credit['attribs']['']['role']))
+ {
+ $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($credit['attribs']['']['scheme']))
+ {
+ $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $credit_scheme = 'urn:ebu';
+ }
+ if (isset($credit['data']))
+ {
+ $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $credits_parent[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
+ }
+ }
+ elseif ($credits = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'credit'))
+ {
+ foreach ($credits as $credit)
+ {
+ $credit_role = null;
+ $credit_scheme = null;
+ $credit_name = null;
+ if (isset($credit['attribs']['']['role']))
+ {
+ $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($credit['attribs']['']['scheme']))
+ {
+ $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $credit_scheme = 'urn:ebu';
+ }
+ if (isset($credit['data']))
+ {
+ $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $credits_parent[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
+ }
+ }
+ if (is_array($credits_parent))
+ {
+ $credits_parent = array_values(array_unique($credits_parent));
+ }
+
+ // DESCRIPTION
+ if ($description_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
+ {
+ if (isset($description_parent[0]['data']))
+ {
+ $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ }
+ elseif ($description_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'description'))
+ {
+ if (isset($description_parent[0]['data']))
+ {
+ $description_parent = $this->sanitize($description_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ }
+
+ // DURATION
+ if ($duration_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'duration'))
+ {
+ $seconds = null;
+ $minutes = null;
+ $hours = null;
+ if (isset($duration_parent[0]['data']))
+ {
+ $temp = explode(':', $this->sanitize($duration_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ if (sizeof($temp) > 0)
+ {
+ $seconds = (int) array_pop($temp);
+ }
+ if (sizeof($temp) > 0)
+ {
+ $minutes = (int) array_pop($temp);
+ $seconds += $minutes * 60;
+ }
+ if (sizeof($temp) > 0)
+ {
+ $hours = (int) array_pop($temp);
+ $seconds += $hours * 3600;
+ }
+ unset($temp);
+ $duration_parent = $seconds;
+ }
+ }
+
+ // HASHES
+ if ($hashes_iterator = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
+ {
+ foreach ($hashes_iterator as $hash)
+ {
+ $value = null;
+ $algo = null;
+ if (isset($hash['data']))
+ {
+ $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($hash['attribs']['']['algo']))
+ {
+ $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $algo = 'md5';
+ }
+ $hashes_parent[] = $algo.':'.$value;
+ }
+ }
+ elseif ($hashes_iterator = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'hash'))
+ {
+ foreach ($hashes_iterator as $hash)
+ {
+ $value = null;
+ $algo = null;
+ if (isset($hash['data']))
+ {
+ $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($hash['attribs']['']['algo']))
+ {
+ $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $algo = 'md5';
+ }
+ $hashes_parent[] = $algo.':'.$value;
+ }
+ }
+ if (is_array($hashes_parent))
+ {
+ $hashes_parent = array_values(array_unique($hashes_parent));
+ }
+
+ // KEYWORDS
+ if ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
+ {
+ if (isset($keywords[0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords_parent[] = trim($word);
+ }
+ }
+ unset($temp);
+ }
+ elseif ($keywords = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
+ {
+ if (isset($keywords[0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords_parent[] = trim($word);
+ }
+ }
+ unset($temp);
+ }
+ elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'keywords'))
+ {
+ if (isset($keywords[0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords_parent[] = trim($word);
+ }
+ }
+ unset($temp);
+ }
+ elseif ($keywords = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'keywords'))
+ {
+ if (isset($keywords[0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($keywords[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords_parent[] = trim($word);
+ }
+ }
+ unset($temp);
+ }
+ if (is_array($keywords_parent))
+ {
+ $keywords_parent = array_values(array_unique($keywords_parent));
+ }
+
+ // PLAYER
+ if ($player_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
+ {
+ if (isset($player_parent[0]['attribs']['']['url']))
+ {
+ $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ elseif ($player_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'player'))
+ {
+ if (isset($player_parent[0]['attribs']['']['url']))
+ {
+ $player_parent = $this->sanitize($player_parent[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+
+ // RATINGS
+ if ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
+ {
+ foreach ($ratings as $rating)
+ {
+ $rating_scheme = null;
+ $rating_value = null;
+ if (isset($rating['attribs']['']['scheme']))
+ {
+ $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $rating_scheme = 'urn:simple';
+ }
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
+ }
+ }
+ elseif ($ratings = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
+ {
+ foreach ($ratings as $rating)
+ {
+ $rating_scheme = 'urn:itunes';
+ $rating_value = null;
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
+ }
+ }
+ elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'rating'))
+ {
+ foreach ($ratings as $rating)
+ {
+ $rating_scheme = null;
+ $rating_value = null;
+ if (isset($rating['attribs']['']['scheme']))
+ {
+ $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $rating_scheme = 'urn:simple';
+ }
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
+ }
+ }
+ elseif ($ratings = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'explicit'))
+ {
+ foreach ($ratings as $rating)
+ {
+ $rating_scheme = 'urn:itunes';
+ $rating_value = null;
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings_parent[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
+ }
+ }
+ if (is_array($ratings_parent))
+ {
+ $ratings_parent = array_values(array_unique($ratings_parent));
+ }
+
+ // RESTRICTIONS
+ if ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
+ {
+ foreach ($restrictions as $restriction)
+ {
+ $restriction_relationship = null;
+ $restriction_type = null;
+ $restriction_value = null;
+ if (isset($restriction['attribs']['']['relationship']))
+ {
+ $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['attribs']['']['type']))
+ {
+ $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['data']))
+ {
+ $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
+ }
+ }
+ elseif ($restrictions = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
+ {
+ foreach ($restrictions as $restriction)
+ {
+ $restriction_relationship = 'allow';
+ $restriction_type = null;
+ $restriction_value = 'itunes';
+ if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
+ {
+ $restriction_relationship = 'deny';
+ }
+ $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
+ }
+ }
+ elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'restriction'))
+ {
+ foreach ($restrictions as $restriction)
+ {
+ $restriction_relationship = null;
+ $restriction_type = null;
+ $restriction_value = null;
+ if (isset($restriction['attribs']['']['relationship']))
+ {
+ $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['attribs']['']['type']))
+ {
+ $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['data']))
+ {
+ $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
+ }
+ }
+ elseif ($restrictions = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'block'))
+ {
+ foreach ($restrictions as $restriction)
+ {
+ $restriction_relationship = 'allow';
+ $restriction_type = null;
+ $restriction_value = 'itunes';
+ if (isset($restriction['data']) && strtolower($restriction['data']) === 'yes')
+ {
+ $restriction_relationship = 'deny';
+ }
+ $restrictions_parent[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
+ }
+ }
+ if (is_array($restrictions_parent))
+ {
+ $restrictions_parent = array_values(array_unique($restrictions_parent));
+ }
+ else
+ {
+ $restrictions_parent = array(new SimplePie_Restriction('allow', null, 'default'));
+ }
+
+ // THUMBNAILS
+ if ($thumbnails = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
+ {
+ foreach ($thumbnails as $thumbnail)
+ {
+ if (isset($thumbnail['attribs']['']['url']))
+ {
+ $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ }
+ elseif ($thumbnails = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'thumbnail'))
+ {
+ foreach ($thumbnails as $thumbnail)
+ {
+ if (isset($thumbnail['attribs']['']['url']))
+ {
+ $thumbnails_parent[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ }
+
+ // TITLES
+ if ($title_parent = $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
+ {
+ if (isset($title_parent[0]['data']))
+ {
+ $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ }
+ elseif ($title_parent = $parent->get_channel_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'title'))
+ {
+ if (isset($title_parent[0]['data']))
+ {
+ $title_parent = $this->sanitize($title_parent[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ }
+
+ // Clear the memory
+ unset($parent);
+
+ // Attributes
+ $bitrate = null;
+ $channels = null;
+ $duration = null;
+ $expression = null;
+ $framerate = null;
+ $height = null;
+ $javascript = null;
+ $lang = null;
+ $length = null;
+ $medium = null;
+ $samplingrate = null;
+ $type = null;
+ $url = null;
+ $width = null;
+
+ // Elements
+ $captions = null;
+ $categories = null;
+ $copyrights = null;
+ $credits = null;
+ $description = null;
+ $hashes = null;
+ $keywords = null;
+ $player = null;
+ $ratings = null;
+ $restrictions = null;
+ $thumbnails = null;
+ $title = null;
+
+ // If we have media:group tags, loop through them.
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_MEDIARSS, 'group') as $group)
+ {
+ if(isset($group['child']) && isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
+ {
+ // If we have media:content tags, loop through them.
+ foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
+ {
+ if (isset($content['attribs']['']['url']))
+ {
+ // Attributes
+ $bitrate = null;
+ $channels = null;
+ $duration = null;
+ $expression = null;
+ $framerate = null;
+ $height = null;
+ $javascript = null;
+ $lang = null;
+ $length = null;
+ $medium = null;
+ $samplingrate = null;
+ $type = null;
+ $url = null;
+ $width = null;
+
+ // Elements
+ $captions = null;
+ $categories = null;
+ $copyrights = null;
+ $credits = null;
+ $description = null;
+ $hashes = null;
+ $keywords = null;
+ $player = null;
+ $ratings = null;
+ $restrictions = null;
+ $thumbnails = null;
+ $title = null;
+
+ // Start checking the attributes of media:content
+ if (isset($content['attribs']['']['bitrate']))
+ {
+ $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['channels']))
+ {
+ $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['duration']))
+ {
+ $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $duration = $duration_parent;
+ }
+ if (isset($content['attribs']['']['expression']))
+ {
+ $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['framerate']))
+ {
+ $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['height']))
+ {
+ $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['lang']))
+ {
+ $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['fileSize']))
+ {
+ $length = ceil($content['attribs']['']['fileSize']);
+ }
+ if (isset($content['attribs']['']['medium']))
+ {
+ $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['samplingrate']))
+ {
+ $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['type']))
+ {
+ $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['width']))
+ {
+ $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+
+ // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
+
+ // CAPTIONS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
+ {
+ $caption_type = null;
+ $caption_lang = null;
+ $caption_startTime = null;
+ $caption_endTime = null;
+ $caption_text = null;
+ if (isset($caption['attribs']['']['type']))
+ {
+ $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['lang']))
+ {
+ $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['start']))
+ {
+ $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['end']))
+ {
+ $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['data']))
+ {
+ $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $captions[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
+ }
+ if (is_array($captions))
+ {
+ $captions = array_values(array_unique($captions));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
+ {
+ $caption_type = null;
+ $caption_lang = null;
+ $caption_startTime = null;
+ $caption_endTime = null;
+ $caption_text = null;
+ if (isset($caption['attribs']['']['type']))
+ {
+ $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['lang']))
+ {
+ $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['start']))
+ {
+ $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['end']))
+ {
+ $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['data']))
+ {
+ $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $captions[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
+ }
+ if (is_array($captions))
+ {
+ $captions = array_values(array_unique($captions));
+ }
+ }
+ else
+ {
+ $captions = $captions_parent;
+ }
+
+ // CATEGORIES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
+ {
+ foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['data']))
+ {
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = 'http://search.yahoo.com/mrss/category_schema';
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
+ }
+ }
+ if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
+ {
+ foreach ((array) $group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['data']))
+ {
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = 'http://search.yahoo.com/mrss/category_schema';
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
+ }
+ }
+ if (is_array($categories) && is_array($categories_parent))
+ {
+ $categories = array_values(array_unique(array_merge($categories, $categories_parent)));
+ }
+ elseif (is_array($categories))
+ {
+ $categories = array_values(array_unique($categories));
+ }
+ elseif (is_array($categories_parent))
+ {
+ $categories = array_values(array_unique($categories_parent));
+ }
+
+ // COPYRIGHTS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
+ {
+ $copyright_url = null;
+ $copyright_label = null;
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
+ {
+ $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
+ {
+ $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $copyrights = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
+ {
+ $copyright_url = null;
+ $copyright_label = null;
+ if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
+ {
+ $copyright_url = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
+ {
+ $copyright_label = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $copyrights = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
+ }
+ else
+ {
+ $copyrights = $copyrights_parent;
+ }
+
+ // CREDITS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
+ {
+ $credit_role = null;
+ $credit_scheme = null;
+ $credit_name = null;
+ if (isset($credit['attribs']['']['role']))
+ {
+ $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($credit['attribs']['']['scheme']))
+ {
+ $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $credit_scheme = 'urn:ebu';
+ }
+ if (isset($credit['data']))
+ {
+ $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $credits[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
+ }
+ if (is_array($credits))
+ {
+ $credits = array_values(array_unique($credits));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
+ {
+ $credit_role = null;
+ $credit_scheme = null;
+ $credit_name = null;
+ if (isset($credit['attribs']['']['role']))
+ {
+ $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($credit['attribs']['']['scheme']))
+ {
+ $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $credit_scheme = 'urn:ebu';
+ }
+ if (isset($credit['data']))
+ {
+ $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $credits[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
+ }
+ if (is_array($credits))
+ {
+ $credits = array_values(array_unique($credits));
+ }
+ }
+ else
+ {
+ $credits = $credits_parent;
+ }
+
+ // DESCRIPTION
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
+ {
+ $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
+ {
+ $description = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $description = $description_parent;
+ }
+
+ // HASHES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
+ {
+ $value = null;
+ $algo = null;
+ if (isset($hash['data']))
+ {
+ $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($hash['attribs']['']['algo']))
+ {
+ $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $algo = 'md5';
+ }
+ $hashes[] = $algo.':'.$value;
+ }
+ if (is_array($hashes))
+ {
+ $hashes = array_values(array_unique($hashes));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
+ {
+ $value = null;
+ $algo = null;
+ if (isset($hash['data']))
+ {
+ $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($hash['attribs']['']['algo']))
+ {
+ $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $algo = 'md5';
+ }
+ $hashes[] = $algo.':'.$value;
+ }
+ if (is_array($hashes))
+ {
+ $hashes = array_values(array_unique($hashes));
+ }
+ }
+ else
+ {
+ $hashes = $hashes_parent;
+ }
+
+ // KEYWORDS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
+ {
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords[] = trim($word);
+ }
+ unset($temp);
+ }
+ if (is_array($keywords))
+ {
+ $keywords = array_values(array_unique($keywords));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
+ {
+ if (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords[] = trim($word);
+ }
+ unset($temp);
+ }
+ if (is_array($keywords))
+ {
+ $keywords = array_values(array_unique($keywords));
+ }
+ }
+ else
+ {
+ $keywords = $keywords_parent;
+ }
+
+ // PLAYER
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
+ {
+ $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
+ {
+ $player = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ else
+ {
+ $player = $player_parent;
+ }
+
+ // RATINGS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
+ {
+ $rating_scheme = null;
+ $rating_value = null;
+ if (isset($rating['attribs']['']['scheme']))
+ {
+ $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $rating_scheme = 'urn:simple';
+ }
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
+ }
+ if (is_array($ratings))
+ {
+ $ratings = array_values(array_unique($ratings));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
+ {
+ $rating_scheme = null;
+ $rating_value = null;
+ if (isset($rating['attribs']['']['scheme']))
+ {
+ $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $rating_scheme = 'urn:simple';
+ }
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
+ }
+ if (is_array($ratings))
+ {
+ $ratings = array_values(array_unique($ratings));
+ }
+ }
+ else
+ {
+ $ratings = $ratings_parent;
+ }
+
+ // RESTRICTIONS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
+ {
+ $restriction_relationship = null;
+ $restriction_type = null;
+ $restriction_value = null;
+ if (isset($restriction['attribs']['']['relationship']))
+ {
+ $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['attribs']['']['type']))
+ {
+ $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['data']))
+ {
+ $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $restrictions[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
+ }
+ if (is_array($restrictions))
+ {
+ $restrictions = array_values(array_unique($restrictions));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
+ {
+ $restriction_relationship = null;
+ $restriction_type = null;
+ $restriction_value = null;
+ if (isset($restriction['attribs']['']['relationship']))
+ {
+ $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['attribs']['']['type']))
+ {
+ $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['data']))
+ {
+ $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $restrictions[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
+ }
+ if (is_array($restrictions))
+ {
+ $restrictions = array_values(array_unique($restrictions));
+ }
+ }
+ else
+ {
+ $restrictions = $restrictions_parent;
+ }
+
+ // THUMBNAILS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
+ {
+ $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ if (is_array($thumbnails))
+ {
+ $thumbnails = array_values(array_unique($thumbnails));
+ }
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
+ {
+ foreach ($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
+ {
+ $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ if (is_array($thumbnails))
+ {
+ $thumbnails = array_values(array_unique($thumbnails));
+ }
+ }
+ else
+ {
+ $thumbnails = $thumbnails_parent;
+ }
+
+ // TITLES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
+ {
+ $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
+ {
+ $title = $this->sanitize($group['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $title = $title_parent;
+ }
+
+ $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width));
+ }
+ }
+ }
+ }
+
+ // If we have standalone media:content tags, loop through them.
+ if (isset($this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content']))
+ {
+ foreach ((array) $this->data['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['content'] as $content)
+ {
+ if (isset($content['attribs']['']['url']) || isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
+ {
+ // Attributes
+ $bitrate = null;
+ $channels = null;
+ $duration = null;
+ $expression = null;
+ $framerate = null;
+ $height = null;
+ $javascript = null;
+ $lang = null;
+ $length = null;
+ $medium = null;
+ $samplingrate = null;
+ $type = null;
+ $url = null;
+ $width = null;
+
+ // Elements
+ $captions = null;
+ $categories = null;
+ $copyrights = null;
+ $credits = null;
+ $description = null;
+ $hashes = null;
+ $keywords = null;
+ $player = null;
+ $ratings = null;
+ $restrictions = null;
+ $thumbnails = null;
+ $title = null;
+
+ // Start checking the attributes of media:content
+ if (isset($content['attribs']['']['bitrate']))
+ {
+ $bitrate = $this->sanitize($content['attribs']['']['bitrate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['channels']))
+ {
+ $channels = $this->sanitize($content['attribs']['']['channels'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['duration']))
+ {
+ $duration = $this->sanitize($content['attribs']['']['duration'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $duration = $duration_parent;
+ }
+ if (isset($content['attribs']['']['expression']))
+ {
+ $expression = $this->sanitize($content['attribs']['']['expression'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['framerate']))
+ {
+ $framerate = $this->sanitize($content['attribs']['']['framerate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['height']))
+ {
+ $height = $this->sanitize($content['attribs']['']['height'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['lang']))
+ {
+ $lang = $this->sanitize($content['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['fileSize']))
+ {
+ $length = ceil($content['attribs']['']['fileSize']);
+ }
+ if (isset($content['attribs']['']['medium']))
+ {
+ $medium = $this->sanitize($content['attribs']['']['medium'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['samplingrate']))
+ {
+ $samplingrate = $this->sanitize($content['attribs']['']['samplingrate'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['type']))
+ {
+ $type = $this->sanitize($content['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['width']))
+ {
+ $width = $this->sanitize($content['attribs']['']['width'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['attribs']['']['url']))
+ {
+ $url = $this->sanitize($content['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ // Checking the other optional media: elements. Priority: media:content, media:group, item, channel
+
+ // CAPTIONS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['text'] as $caption)
+ {
+ $caption_type = null;
+ $caption_lang = null;
+ $caption_startTime = null;
+ $caption_endTime = null;
+ $caption_text = null;
+ if (isset($caption['attribs']['']['type']))
+ {
+ $caption_type = $this->sanitize($caption['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['lang']))
+ {
+ $caption_lang = $this->sanitize($caption['attribs']['']['lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['start']))
+ {
+ $caption_startTime = $this->sanitize($caption['attribs']['']['start'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['attribs']['']['end']))
+ {
+ $caption_endTime = $this->sanitize($caption['attribs']['']['end'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($caption['data']))
+ {
+ $caption_text = $this->sanitize($caption['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $captions[] = $this->registry->create('Caption', array($caption_type, $caption_lang, $caption_startTime, $caption_endTime, $caption_text));
+ }
+ if (is_array($captions))
+ {
+ $captions = array_values(array_unique($captions));
+ }
+ }
+ else
+ {
+ $captions = $captions_parent;
+ }
+
+ // CATEGORIES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category']))
+ {
+ foreach ((array) $content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['category'] as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['data']))
+ {
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = 'http://search.yahoo.com/mrss/category_schema';
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
+ }
+ }
+ if (is_array($categories) && is_array($categories_parent))
+ {
+ $categories = array_values(array_unique(array_merge($categories, $categories_parent)));
+ }
+ elseif (is_array($categories))
+ {
+ $categories = array_values(array_unique($categories));
+ }
+ elseif (is_array($categories_parent))
+ {
+ $categories = array_values(array_unique($categories_parent));
+ }
+ else
+ {
+ $categories = null;
+ }
+
+ // COPYRIGHTS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright']))
+ {
+ $copyright_url = null;
+ $copyright_label = null;
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url']))
+ {
+ $copyright_url = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data']))
+ {
+ $copyright_label = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['copyright'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $copyrights = $this->registry->create('Copyright', array($copyright_url, $copyright_label));
+ }
+ else
+ {
+ $copyrights = $copyrights_parent;
+ }
+
+ // CREDITS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['credit'] as $credit)
+ {
+ $credit_role = null;
+ $credit_scheme = null;
+ $credit_name = null;
+ if (isset($credit['attribs']['']['role']))
+ {
+ $credit_role = $this->sanitize($credit['attribs']['']['role'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($credit['attribs']['']['scheme']))
+ {
+ $credit_scheme = $this->sanitize($credit['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $credit_scheme = 'urn:ebu';
+ }
+ if (isset($credit['data']))
+ {
+ $credit_name = $this->sanitize($credit['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $credits[] = $this->registry->create('Credit', array($credit_role, $credit_scheme, $credit_name));
+ }
+ if (is_array($credits))
+ {
+ $credits = array_values(array_unique($credits));
+ }
+ }
+ else
+ {
+ $credits = $credits_parent;
+ }
+
+ // DESCRIPTION
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description']))
+ {
+ $description = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['description'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $description = $description_parent;
+ }
+
+ // HASHES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['hash'] as $hash)
+ {
+ $value = null;
+ $algo = null;
+ if (isset($hash['data']))
+ {
+ $value = $this->sanitize($hash['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($hash['attribs']['']['algo']))
+ {
+ $algo = $this->sanitize($hash['attribs']['']['algo'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $algo = 'md5';
+ }
+ $hashes[] = $algo.':'.$value;
+ }
+ if (is_array($hashes))
+ {
+ $hashes = array_values(array_unique($hashes));
+ }
+ }
+ else
+ {
+ $hashes = $hashes_parent;
+ }
+
+ // KEYWORDS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords']))
+ {
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data']))
+ {
+ $temp = explode(',', $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['keywords'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT));
+ foreach ($temp as $word)
+ {
+ $keywords[] = trim($word);
+ }
+ unset($temp);
+ }
+ if (is_array($keywords))
+ {
+ $keywords = array_values(array_unique($keywords));
+ }
+ }
+ else
+ {
+ $keywords = $keywords_parent;
+ }
+
+ // PLAYER
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player']))
+ {
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'])) {
+ $player = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['player'][0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ else
+ {
+ $player = $player_parent;
+ }
+
+ // RATINGS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['rating'] as $rating)
+ {
+ $rating_scheme = null;
+ $rating_value = null;
+ if (isset($rating['attribs']['']['scheme']))
+ {
+ $rating_scheme = $this->sanitize($rating['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $rating_scheme = 'urn:simple';
+ }
+ if (isset($rating['data']))
+ {
+ $rating_value = $this->sanitize($rating['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $ratings[] = $this->registry->create('Rating', array($rating_scheme, $rating_value));
+ }
+ if (is_array($ratings))
+ {
+ $ratings = array_values(array_unique($ratings));
+ }
+ }
+ else
+ {
+ $ratings = $ratings_parent;
+ }
+
+ // RESTRICTIONS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['restriction'] as $restriction)
+ {
+ $restriction_relationship = null;
+ $restriction_type = null;
+ $restriction_value = null;
+ if (isset($restriction['attribs']['']['relationship']))
+ {
+ $restriction_relationship = $this->sanitize($restriction['attribs']['']['relationship'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['attribs']['']['type']))
+ {
+ $restriction_type = $this->sanitize($restriction['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($restriction['data']))
+ {
+ $restriction_value = $this->sanitize($restriction['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $restrictions[] = $this->registry->create('Restriction', array($restriction_relationship, $restriction_type, $restriction_value));
+ }
+ if (is_array($restrictions))
+ {
+ $restrictions = array_values(array_unique($restrictions));
+ }
+ }
+ else
+ {
+ $restrictions = $restrictions_parent;
+ }
+
+ // THUMBNAILS
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail']))
+ {
+ foreach ($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['thumbnail'] as $thumbnail)
+ {
+ if (isset($thumbnail['attribs']['']['url'])) {
+ $thumbnails[] = $this->sanitize($thumbnail['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ }
+ if (is_array($thumbnails))
+ {
+ $thumbnails = array_values(array_unique($thumbnails));
+ }
+ }
+ else
+ {
+ $thumbnails = $thumbnails_parent;
+ }
+
+ // TITLES
+ if (isset($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title']))
+ {
+ $title = $this->sanitize($content['child'][SIMPLEPIE_NAMESPACE_MEDIARSS]['title'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $title = $title_parent;
+ }
+
+ $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions, $categories, $channels, $copyrights, $credits, $description, $duration, $expression, $framerate, $hashes, $height, $keywords, $lang, $medium, $player, $ratings, $restrictions, $samplingrate, $thumbnails, $title, $width));
+ }
+ }
+ }
+
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link') as $link)
+ {
+ if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
+ {
+ // Attributes
+ $bitrate = null;
+ $channels = null;
+ $duration = null;
+ $expression = null;
+ $framerate = null;
+ $height = null;
+ $javascript = null;
+ $lang = null;
+ $length = null;
+ $medium = null;
+ $samplingrate = null;
+ $type = null;
+ $url = null;
+ $width = null;
+
+ $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+ if (isset($link['attribs']['']['type']))
+ {
+ $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($link['attribs']['']['length']))
+ {
+ $length = ceil($link['attribs']['']['length']);
+ }
+ if (isset($link['attribs']['']['title']))
+ {
+ $title = $this->sanitize($link['attribs']['']['title'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $title = $title_parent;
+ }
+
+ // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
+ $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title, $width));
+ }
+ }
+
+ foreach ((array) $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link') as $link)
+ {
+ if (isset($link['attribs']['']['href']) && !empty($link['attribs']['']['rel']) && $link['attribs']['']['rel'] === 'enclosure')
+ {
+ // Attributes
+ $bitrate = null;
+ $channels = null;
+ $duration = null;
+ $expression = null;
+ $framerate = null;
+ $height = null;
+ $javascript = null;
+ $lang = null;
+ $length = null;
+ $medium = null;
+ $samplingrate = null;
+ $type = null;
+ $url = null;
+ $width = null;
+
+ $url = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+ if (isset($link['attribs']['']['type']))
+ {
+ $type = $this->sanitize($link['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($link['attribs']['']['length']))
+ {
+ $length = ceil($link['attribs']['']['length']);
+ }
+
+ // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
+ $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width));
+ }
+ }
+
+ if ($enclosure = $this->get_item_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'enclosure'))
+ {
+ if (isset($enclosure[0]['attribs']['']['url']))
+ {
+ // Attributes
+ $bitrate = null;
+ $channels = null;
+ $duration = null;
+ $expression = null;
+ $framerate = null;
+ $height = null;
+ $javascript = null;
+ $lang = null;
+ $length = null;
+ $medium = null;
+ $samplingrate = null;
+ $type = null;
+ $url = null;
+ $width = null;
+
+ $url = $this->sanitize($enclosure[0]['attribs']['']['url'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($enclosure[0]));
+ if (isset($enclosure[0]['attribs']['']['type']))
+ {
+ $type = $this->sanitize($enclosure[0]['attribs']['']['type'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($enclosure[0]['attribs']['']['length']))
+ {
+ $length = ceil($enclosure[0]['attribs']['']['length']);
+ }
+
+ // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
+ $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width));
+ }
+ }
+
+ if (sizeof($this->data['enclosures']) === 0 && ($url || $type || $length || $bitrate || $captions_parent || $categories_parent || $channels || $copyrights_parent || $credits_parent || $description_parent || $duration_parent || $expression || $framerate || $hashes_parent || $height || $keywords_parent || $lang || $medium || $player_parent || $ratings_parent || $restrictions_parent || $samplingrate || $thumbnails_parent || $title_parent || $width))
+ {
+ // Since we don't have group or content for these, we'll just pass the '*_parent' variables directly to the constructor
+ $this->data['enclosures'][] = $this->registry->create('Enclosure', array($url, $type, $length, null, $bitrate, $captions_parent, $categories_parent, $channels, $copyrights_parent, $credits_parent, $description_parent, $duration_parent, $expression, $framerate, $hashes_parent, $height, $keywords_parent, $lang, $medium, $player_parent, $ratings_parent, $restrictions_parent, $samplingrate, $thumbnails_parent, $title_parent, $width));
+ }
+
+ $this->data['enclosures'] = array_values(array_unique($this->data['enclosures']));
+ }
+ if (!empty($this->data['enclosures']))
+ {
+ return $this->data['enclosures'];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the latitude coordinates for the item
+ *
+ * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
+ *
+ * Uses `<geo:lat>` or `<georss:point>`
+ *
+ * @since 1.0
+ * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
+ * @link http://www.georss.org/ GeoRSS
+ * @return string|null
+ */
+ public function get_latitude()
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
+ {
+ return (float) $match[1];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the longitude coordinates for the item
+ *
+ * Compatible with the W3C WGS84 Basic Geo and GeoRSS specifications
+ *
+ * Uses `<geo:long>`, `<geo:lon>` or `<georss:point>`
+ *
+ * @since 1.0
+ * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo
+ * @link http://www.georss.org/ GeoRSS
+ * @return string|null
+ */
+ public function get_longitude()
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
+ {
+ return (float) $match[2];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the `<atom:source>` for the item
+ *
+ * @since 1.1
+ * @return SimplePie_Source|null
+ */
+ public function get_source()
+ {
+ if ($return = $this->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'source'))
+ {
+ return $this->registry->create('Source', array($this, $return[0]));
+ }
+
+ return null;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Locator.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Locator.php
new file mode 100644
index 0000000..bf7c21a
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Locator.php
@@ -0,0 +1,424 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Used for feed auto-discovery
+ *
+ *
+ * This class can be overloaded with {@see SimplePie::set_locator_class()}
+ *
+ * @package SimplePie
+ */
+class SimplePie_Locator
+{
+ var $useragent;
+ var $timeout;
+ var $file;
+ var $local = array();
+ var $elsewhere = array();
+ var $cached_entities = array();
+ var $http_base;
+ var $base;
+ var $base_location = 0;
+ var $checked_feeds = 0;
+ var $max_checked_feeds = 10;
+ var $force_fsockopen = false;
+ var $curl_options = array();
+ protected $registry;
+
+ public function __construct(SimplePie_File $file, $timeout = 10, $useragent = null, $max_checked_feeds = 10, $force_fsockopen = false, $curl_options = array())
+ {
+ $this->file = $file;
+ $this->useragent = $useragent;
+ $this->timeout = $timeout;
+ $this->max_checked_feeds = $max_checked_feeds;
+ $this->force_fsockopen = $force_fsockopen;
+ $this->curl_options = $curl_options;
+
+ if (class_exists('DOMDocument'))
+ {
+ $this->dom = new DOMDocument();
+
+ set_error_handler(array('SimplePie_Misc', 'silence_errors'));
+ $this->dom->loadHTML($this->file->body);
+ restore_error_handler();
+ }
+ else
+ {
+ $this->dom = null;
+ }
+ }
+
+ public function set_registry(SimplePie_Registry $registry)
+ {
+ $this->registry = $registry;
+ }
+
+ public function find($type = SIMPLEPIE_LOCATOR_ALL, &$working)
+ {
+ if ($this->is_feed($this->file))
+ {
+ return $this->file;
+ }
+
+ if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
+ {
+ $sniffer = $this->registry->create('Content_Type_Sniffer', array($this->file));
+ if ($sniffer->get_type() !== 'text/html')
+ {
+ return null;
+ }
+ }
+
+ if ($type & ~SIMPLEPIE_LOCATOR_NONE)
+ {
+ $this->get_base();
+ }
+
+ if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
+ {
+ return $working[0];
+ }
+
+ if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
+ {
+ if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
+ {
+ return $working[0];
+ }
+
+ if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
+ {
+ return $working[0];
+ }
+
+ if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
+ {
+ return $working[0];
+ }
+
+ if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
+ {
+ return $working[0];
+ }
+ }
+ return null;
+ }
+
+ public function is_feed($file, $check_html = false)
+ {
+ if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
+ {
+ $sniffer = $this->registry->create('Content_Type_Sniffer', array($file));
+ $sniffed = $sniffer->get_type();
+ $mime_types = array('application/rss+xml', 'application/rdf+xml',
+ 'text/rdf', 'application/atom+xml', 'text/xml',
+ 'application/xml', 'application/x-rss+xml');
+ if ($check_html)
+ {
+ $mime_types[] = 'text/html';
+ }
+
+ return in_array($sniffed, $mime_types);
+ }
+ elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public function get_base()
+ {
+ if ($this->dom === null)
+ {
+ throw new SimplePie_Exception('DOMDocument not found, unable to use locator');
+ }
+ $this->http_base = $this->file->url;
+ $this->base = $this->http_base;
+ $elements = $this->dom->getElementsByTagName('base');
+ foreach ($elements as $element)
+ {
+ if ($element->hasAttribute('href'))
+ {
+ $base = $this->registry->call('Misc', 'absolutize_url', array(trim($element->getAttribute('href')), $this->http_base));
+ if ($base === false)
+ {
+ continue;
+ }
+ $this->base = $base;
+ $this->base_location = method_exists($element, 'getLineNo') ? $element->getLineNo() : 0;
+ break;
+ }
+ }
+ }
+
+ public function autodiscovery()
+ {
+ $done = array();
+ $feeds = array();
+ $feeds = array_merge($feeds, $this->search_elements_by_tag('link', $done, $feeds));
+ $feeds = array_merge($feeds, $this->search_elements_by_tag('a', $done, $feeds));
+ $feeds = array_merge($feeds, $this->search_elements_by_tag('area', $done, $feeds));
+
+ if (!empty($feeds))
+ {
+ return array_values($feeds);
+ }
+
+ return null;
+ }
+
+ protected function search_elements_by_tag($name, &$done, $feeds)
+ {
+ if ($this->dom === null)
+ {
+ throw new SimplePie_Exception('DOMDocument not found, unable to use locator');
+ }
+
+ $links = $this->dom->getElementsByTagName($name);
+ foreach ($links as $link)
+ {
+ if ($this->checked_feeds === $this->max_checked_feeds)
+ {
+ break;
+ }
+ if ($link->hasAttribute('href') && $link->hasAttribute('rel'))
+ {
+ $rel = array_unique($this->registry->call('Misc', 'space_separated_tokens', array(strtolower($link->getAttribute('rel')))));
+ $line = method_exists($link, 'getLineNo') ? $link->getLineNo() : 1;
+
+ if ($this->base_location < $line)
+ {
+ $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base));
+ }
+ else
+ {
+ $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base));
+ }
+ if ($href === false)
+ {
+ continue;
+ }
+
+ if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !in_array('stylesheet', $rel) && $link->hasAttribute('type') && in_array(strtolower($this->registry->call('Misc', 'parse_mime', array($link->getAttribute('type')))), array('text/html', 'application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href]))
+ {
+ $this->checked_feeds++;
+ $headers = array(
+ 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
+ );
+ $feed = $this->registry->create('File', array($href, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options));
+ if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed, true))
+ {
+ $feeds[$href] = $feed;
+ }
+ }
+ $done[] = $href;
+ }
+ }
+
+ return $feeds;
+ }
+
+ public function get_links()
+ {
+ if ($this->dom === null)
+ {
+ throw new SimplePie_Exception('DOMDocument not found, unable to use locator');
+ }
+
+ $links = $this->dom->getElementsByTagName('a');
+ foreach ($links as $link)
+ {
+ if ($link->hasAttribute('href'))
+ {
+ $href = trim($link->getAttribute('href'));
+ $parsed = $this->registry->call('Misc', 'parse_url', array($href));
+ if ($parsed['scheme'] === '' || preg_match('/^(https?|feed)?$/i', $parsed['scheme']))
+ {
+ if (method_exists($link, 'getLineNo') && $this->base_location < $link->getLineNo())
+ {
+ $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base));
+ }
+ else
+ {
+ $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base));
+ }
+ if ($href === false)
+ {
+ continue;
+ }
+
+ $current = $this->registry->call('Misc', 'parse_url', array($this->file->url));
+
+ if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
+ {
+ $this->local[] = $href;
+ }
+ else
+ {
+ $this->elsewhere[] = $href;
+ }
+ }
+ }
+ }
+ $this->local = array_unique($this->local);
+ $this->elsewhere = array_unique($this->elsewhere);
+ if (!empty($this->local) || !empty($this->elsewhere))
+ {
+ return true;
+ }
+ return null;
+ }
+
+ public function get_rel_link($rel)
+ {
+ if ($this->dom === null)
+ {
+ throw new SimplePie_Exception('DOMDocument not found, unable to use '.
+ 'locator');
+ }
+ if (!class_exists('DOMXpath'))
+ {
+ throw new SimplePie_Exception('DOMXpath not found, unable to use '.
+ 'get_rel_link');
+ }
+
+ $xpath = new DOMXpath($this->dom);
+ $query = '//a[@rel and @href] | //link[@rel and @href]';
+ foreach ($xpath->query($query) as $link)
+ {
+ $href = trim($link->getAttribute('href'));
+ $parsed = $this->registry->call('Misc', 'parse_url', array($href));
+ if ($parsed['scheme'] === '' ||
+ preg_match('/^https?$/i', $parsed['scheme']))
+ {
+ if (method_exists($link, 'getLineNo') &&
+ $this->base_location < $link->getLineNo())
+ {
+ $href =
+ $this->registry->call('Misc', 'absolutize_url',
+ array(trim($link->getAttribute('href')),
+ $this->base));
+ }
+ else
+ {
+ $href =
+ $this->registry->call('Misc', 'absolutize_url',
+ array(trim($link->getAttribute('href')),
+ $this->http_base));
+ }
+ if ($href === false)
+ {
+ return null;
+ }
+ $rel_values = explode(' ', strtolower($link->getAttribute('rel')));
+ if (in_array($rel, $rel_values))
+ {
+ return $href;
+ }
+ }
+ }
+ return null;
+ }
+
+ public function extension(&$array)
+ {
+ foreach ($array as $key => $value)
+ {
+ if ($this->checked_feeds === $this->max_checked_feeds)
+ {
+ break;
+ }
+ if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
+ {
+ $this->checked_feeds++;
+
+ $headers = array(
+ 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
+ );
+ $feed = $this->registry->create('File', array($value, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options));
+ if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
+ {
+ return array($feed);
+ }
+ else
+ {
+ unset($array[$key]);
+ }
+ }
+ }
+ return null;
+ }
+
+ public function body(&$array)
+ {
+ foreach ($array as $key => $value)
+ {
+ if ($this->checked_feeds === $this->max_checked_feeds)
+ {
+ break;
+ }
+ if (preg_match('/(feed|rss|rdf|atom|xml)/i', $value))
+ {
+ $this->checked_feeds++;
+ $headers = array(
+ 'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
+ );
+ $feed = $this->registry->create('File', array($value, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen, $this->curl_options));
+ if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
+ {
+ return array($feed);
+ }
+ else
+ {
+ unset($array[$key]);
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Misc.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Misc.php
new file mode 100644
index 0000000..48d7c86
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Misc.php
@@ -0,0 +1,2262 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Miscellanous utilities
+ *
+ * @package SimplePie
+ */
+class SimplePie_Misc
+{
+ public static function time_hms($seconds)
+ {
+ $time = '';
+
+ $hours = floor($seconds / 3600);
+ $remainder = $seconds % 3600;
+ if ($hours > 0)
+ {
+ $time .= $hours.':';
+ }
+
+ $minutes = floor($remainder / 60);
+ $seconds = $remainder % 60;
+ if ($minutes < 10 && $hours > 0)
+ {
+ $minutes = '0' . $minutes;
+ }
+ if ($seconds < 10)
+ {
+ $seconds = '0' . $seconds;
+ }
+
+ $time .= $minutes.':';
+ $time .= $seconds;
+
+ return $time;
+ }
+
+ public static function absolutize_url($relative, $base)
+ {
+ $iri = SimplePie_IRI::absolutize(new SimplePie_IRI($base), $relative);
+ if ($iri === false)
+ {
+ return false;
+ }
+ return $iri->get_uri();
+ }
+
+ /**
+ * Get a HTML/XML element from a HTML string
+ *
+ * @deprecated Use DOMDocument instead (parsing HTML with regex is bad!)
+ * @param string $realname Element name (including namespace prefix if applicable)
+ * @param string $string HTML document
+ * @return array
+ */
+ public static function get_element($realname, $string)
+ {
+ $return = array();
+ $name = preg_quote($realname, '/');
+ if (preg_match_all("/<($name)" . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . "(>(.*)<\/$name>|(\/)?>)/siU", $string, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
+ {
+ for ($i = 0, $total_matches = count($matches); $i < $total_matches; $i++)
+ {
+ $return[$i]['tag'] = $realname;
+ $return[$i]['full'] = $matches[$i][0][0];
+ $return[$i]['offset'] = $matches[$i][0][1];
+ if (strlen($matches[$i][3][0]) <= 2)
+ {
+ $return[$i]['self_closing'] = true;
+ }
+ else
+ {
+ $return[$i]['self_closing'] = false;
+ $return[$i]['content'] = $matches[$i][4][0];
+ }
+ $return[$i]['attribs'] = array();
+ if (isset($matches[$i][2][0]) && preg_match_all('/[\x09\x0A\x0B\x0C\x0D\x20]+([^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3D\x3E]*)(?:[\x09\x0A\x0B\x0C\x0D\x20]*=[\x09\x0A\x0B\x0C\x0D\x20]*(?:"([^"]*)"|\'([^\']*)\'|([^\x09\x0A\x0B\x0C\x0D\x20\x22\x27\x3E][^\x09\x0A\x0B\x0C\x0D\x20\x3E]*)?))?/', ' ' . $matches[$i][2][0] . ' ', $attribs, PREG_SET_ORDER))
+ {
+ for ($j = 0, $total_attribs = count($attribs); $j < $total_attribs; $j++)
+ {
+ if (count($attribs[$j]) === 2)
+ {
+ $attribs[$j][2] = $attribs[$j][1];
+ }
+ $return[$i]['attribs'][strtolower($attribs[$j][1])]['data'] = SimplePie_Misc::entities_decode(end($attribs[$j]));
+ }
+ }
+ }
+ }
+ return $return;
+ }
+
+ public static function element_implode($element)
+ {
+ $full = "<$element[tag]";
+ foreach ($element['attribs'] as $key => $value)
+ {
+ $key = strtolower($key);
+ $full .= " $key=\"" . htmlspecialchars($value['data'], ENT_COMPAT, 'UTF-8') . '"';
+ }
+ if ($element['self_closing'])
+ {
+ $full .= ' />';
+ }
+ else
+ {
+ $full .= ">$element[content]</$element[tag]>";
+ }
+ return $full;
+ }
+
+ public static function error($message, $level, $file, $line)
+ {
+ if ((ini_get('error_reporting') & $level) > 0)
+ {
+ switch ($level)
+ {
+ case E_USER_ERROR:
+ $note = 'PHP Error';
+ break;
+ case E_USER_WARNING:
+ $note = 'PHP Warning';
+ break;
+ case E_USER_NOTICE:
+ $note = 'PHP Notice';
+ break;
+ default:
+ $note = 'Unknown Error';
+ break;
+ }
+
+ $log_error = true;
+ if (!function_exists('error_log'))
+ {
+ $log_error = false;
+ }
+
+ $log_file = @ini_get('error_log');
+ if (!empty($log_file) && ('syslog' !== $log_file) && !@is_writable($log_file))
+ {
+ $log_error = false;
+ }
+
+ if ($log_error)
+ {
+ @error_log("$note: $message in $file on line $line", 0);
+ }
+ }
+
+ return $message;
+ }
+
+ public static function fix_protocol($url, $http = 1)
+ {
+ $url = SimplePie_Misc::normalize_url($url);
+ $parsed = SimplePie_Misc::parse_url($url);
+ if ($parsed['scheme'] !== '' && $parsed['scheme'] !== 'http' && $parsed['scheme'] !== 'https')
+ {
+ return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['authority'], $parsed['path'], $parsed['query'], $parsed['fragment']), $http);
+ }
+
+ if ($parsed['scheme'] === '' && $parsed['authority'] === '' && !file_exists($url))
+ {
+ return SimplePie_Misc::fix_protocol(SimplePie_Misc::compress_parse_url('http', $parsed['path'], '', $parsed['query'], $parsed['fragment']), $http);
+ }
+
+ if ($http === 2 && $parsed['scheme'] !== '')
+ {
+ return "feed:$url";
+ }
+ elseif ($http === 3 && strtolower($parsed['scheme']) === 'http')
+ {
+ return substr_replace($url, 'podcast', 0, 4);
+ }
+ elseif ($http === 4 && strtolower($parsed['scheme']) === 'http')
+ {
+ return substr_replace($url, 'itpc', 0, 4);
+ }
+
+ return $url;
+ }
+
+ public static function array_merge_recursive($array1, $array2)
+ {
+ foreach ($array2 as $key => $value)
+ {
+ if (is_array($value))
+ {
+ $array1[$key] = SimplePie_Misc::array_merge_recursive($array1[$key], $value);
+ }
+ else
+ {
+ $array1[$key] = $value;
+ }
+ }
+
+ return $array1;
+ }
+
+ public static function parse_url($url)
+ {
+ $iri = new SimplePie_IRI($url);
+ return array(
+ 'scheme' => (string) $iri->scheme,
+ 'authority' => (string) $iri->authority,
+ 'path' => (string) $iri->path,
+ 'query' => (string) $iri->query,
+ 'fragment' => (string) $iri->fragment
+ );
+ }
+
+ public static function compress_parse_url($scheme = '', $authority = '', $path = '', $query = '', $fragment = '')
+ {
+ $iri = new SimplePie_IRI('');
+ $iri->scheme = $scheme;
+ $iri->authority = $authority;
+ $iri->path = $path;
+ $iri->query = $query;
+ $iri->fragment = $fragment;
+ return $iri->get_uri();
+ }
+
+ public static function normalize_url($url)
+ {
+ $iri = new SimplePie_IRI($url);
+ return $iri->get_uri();
+ }
+
+ public static function percent_encoding_normalization($match)
+ {
+ $integer = hexdec($match[1]);
+ if ($integer >= 0x41 && $integer <= 0x5A || $integer >= 0x61 && $integer <= 0x7A || $integer >= 0x30 && $integer <= 0x39 || $integer === 0x2D || $integer === 0x2E || $integer === 0x5F || $integer === 0x7E)
+ {
+ return chr($integer);
+ }
+
+ return strtoupper($match[0]);
+ }
+
+ /**
+ * Converts a Windows-1252 encoded string to a UTF-8 encoded string
+ *
+ * @static
+ * @param string $string Windows-1252 encoded string
+ * @return string UTF-8 encoded string
+ */
+ public static function windows_1252_to_utf8($string)
+ {
+ static $convert_table = array("\x80" => "\xE2\x82\xAC", "\x81" => "\xEF\xBF\xBD", "\x82" => "\xE2\x80\x9A", "\x83" => "\xC6\x92", "\x84" => "\xE2\x80\x9E", "\x85" => "\xE2\x80\xA6", "\x86" => "\xE2\x80\xA0", "\x87" => "\xE2\x80\xA1", "\x88" => "\xCB\x86", "\x89" => "\xE2\x80\xB0", "\x8A" => "\xC5\xA0", "\x8B" => "\xE2\x80\xB9", "\x8C" => "\xC5\x92", "\x8D" => "\xEF\xBF\xBD", "\x8E" => "\xC5\xBD", "\x8F" => "\xEF\xBF\xBD", "\x90" => "\xEF\xBF\xBD", "\x91" => "\xE2\x80\x98", "\x92" => "\xE2\x80\x99", "\x93" => "\xE2\x80\x9C", "\x94" => "\xE2\x80\x9D", "\x95" => "\xE2\x80\xA2", "\x96" => "\xE2\x80\x93", "\x97" => "\xE2\x80\x94", "\x98" => "\xCB\x9C", "\x99" => "\xE2\x84\xA2", "\x9A" => "\xC5\xA1", "\x9B" => "\xE2\x80\xBA", "\x9C" => "\xC5\x93", "\x9D" => "\xEF\xBF\xBD", "\x9E" => "\xC5\xBE", "\x9F" => "\xC5\xB8", "\xA0" => "\xC2\xA0", "\xA1" => "\xC2\xA1", "\xA2" => "\xC2\xA2", "\xA3" => "\xC2\xA3", "\xA4" => "\xC2\xA4", "\xA5" => "\xC2\xA5", "\xA6" => "\xC2\xA6", "\xA7" => "\xC2\xA7", "\xA8" => "\xC2\xA8", "\xA9" => "\xC2\xA9", "\xAA" => "\xC2\xAA", "\xAB" => "\xC2\xAB", "\xAC" => "\xC2\xAC", "\xAD" => "\xC2\xAD", "\xAE" => "\xC2\xAE", "\xAF" => "\xC2\xAF", "\xB0" => "\xC2\xB0", "\xB1" => "\xC2\xB1", "\xB2" => "\xC2\xB2", "\xB3" => "\xC2\xB3", "\xB4" => "\xC2\xB4", "\xB5" => "\xC2\xB5", "\xB6" => "\xC2\xB6", "\xB7" => "\xC2\xB7", "\xB8" => "\xC2\xB8", "\xB9" => "\xC2\xB9", "\xBA" => "\xC2\xBA", "\xBB" => "\xC2\xBB", "\xBC" => "\xC2\xBC", "\xBD" => "\xC2\xBD", "\xBE" => "\xC2\xBE", "\xBF" => "\xC2\xBF", "\xC0" => "\xC3\x80", "\xC1" => "\xC3\x81", "\xC2" => "\xC3\x82", "\xC3" => "\xC3\x83", "\xC4" => "\xC3\x84", "\xC5" => "\xC3\x85", "\xC6" => "\xC3\x86", "\xC7" => "\xC3\x87", "\xC8" => "\xC3\x88", "\xC9" => "\xC3\x89", "\xCA" => "\xC3\x8A", "\xCB" => "\xC3\x8B", "\xCC" => "\xC3\x8C", "\xCD" => "\xC3\x8D", "\xCE" => "\xC3\x8E", "\xCF" => "\xC3\x8F", "\xD0" => "\xC3\x90", "\xD1" => "\xC3\x91", "\xD2" => "\xC3\x92", "\xD3" => "\xC3\x93", "\xD4" => "\xC3\x94", "\xD5" => "\xC3\x95", "\xD6" => "\xC3\x96", "\xD7" => "\xC3\x97", "\xD8" => "\xC3\x98", "\xD9" => "\xC3\x99", "\xDA" => "\xC3\x9A", "\xDB" => "\xC3\x9B", "\xDC" => "\xC3\x9C", "\xDD" => "\xC3\x9D", "\xDE" => "\xC3\x9E", "\xDF" => "\xC3\x9F", "\xE0" => "\xC3\xA0", "\xE1" => "\xC3\xA1", "\xE2" => "\xC3\xA2", "\xE3" => "\xC3\xA3", "\xE4" => "\xC3\xA4", "\xE5" => "\xC3\xA5", "\xE6" => "\xC3\xA6", "\xE7" => "\xC3\xA7", "\xE8" => "\xC3\xA8", "\xE9" => "\xC3\xA9", "\xEA" => "\xC3\xAA", "\xEB" => "\xC3\xAB", "\xEC" => "\xC3\xAC", "\xED" => "\xC3\xAD", "\xEE" => "\xC3\xAE", "\xEF" => "\xC3\xAF", "\xF0" => "\xC3\xB0", "\xF1" => "\xC3\xB1", "\xF2" => "\xC3\xB2", "\xF3" => "\xC3\xB3", "\xF4" => "\xC3\xB4", "\xF5" => "\xC3\xB5", "\xF6" => "\xC3\xB6", "\xF7" => "\xC3\xB7", "\xF8" => "\xC3\xB8", "\xF9" => "\xC3\xB9", "\xFA" => "\xC3\xBA", "\xFB" => "\xC3\xBB", "\xFC" => "\xC3\xBC", "\xFD" => "\xC3\xBD", "\xFE" => "\xC3\xBE", "\xFF" => "\xC3\xBF");
+
+ return strtr($string, $convert_table);
+ }
+
+ /**
+ * Change a string from one encoding to another
+ *
+ * @param string $data Raw data in $input encoding
+ * @param string $input Encoding of $data
+ * @param string $output Encoding you want
+ * @return string|boolean False if we can't convert it
+ */
+ public static function change_encoding($data, $input, $output)
+ {
+ $input = SimplePie_Misc::encoding($input);
+ $output = SimplePie_Misc::encoding($output);
+
+ // We fail to fail on non US-ASCII bytes
+ if ($input === 'US-ASCII')
+ {
+ static $non_ascii_octects = '';
+ if (!$non_ascii_octects)
+ {
+ for ($i = 0x80; $i <= 0xFF; $i++)
+ {
+ $non_ascii_octects .= chr($i);
+ }
+ }
+ $data = substr($data, 0, strcspn($data, $non_ascii_octects));
+ }
+
+ // This is first, as behaviour of this is completely predictable
+ if ($input === 'windows-1252' && $output === 'UTF-8')
+ {
+ return SimplePie_Misc::windows_1252_to_utf8($data);
+ }
+ // This is second, as behaviour of this varies only with PHP version (the middle part of this expression checks the encoding is supported).
+ elseif (function_exists('mb_convert_encoding') && ($return = SimplePie_Misc::change_encoding_mbstring($data, $input, $output)))
+ {
+ return $return;
+ }
+ // This is third, as behaviour of this varies with OS userland and PHP version
+ elseif (function_exists('iconv') && ($return = SimplePie_Misc::change_encoding_iconv($data, $input, $output)))
+ {
+ return $return;
+ }
+ // This is last, as behaviour of this varies with OS userland and PHP version
+ elseif (class_exists('\UConverter') && ($return = SimplePie_Misc::change_encoding_uconverter($data, $input, $output)))
+ {
+ return $return;
+ }
+
+ // If we can't do anything, just fail
+ return false;
+ }
+
+ protected static function change_encoding_mbstring($data, $input, $output)
+ {
+ if ($input === 'windows-949')
+ {
+ $input = 'EUC-KR';
+ }
+ if ($output === 'windows-949')
+ {
+ $output = 'EUC-KR';
+ }
+ if ($input === 'Windows-31J')
+ {
+ $input = 'SJIS';
+ }
+ if ($output === 'Windows-31J')
+ {
+ $output = 'SJIS';
+ }
+
+ // Check that the encoding is supported
+ if (@mb_convert_encoding("\x80", 'UTF-16BE', $input) === "\x00\x80")
+ {
+ return false;
+ }
+ if (!in_array($input, mb_list_encodings()))
+ {
+ return false;
+ }
+
+ // Let's do some conversion
+ if ($return = @mb_convert_encoding($data, $output, $input))
+ {
+ return $return;
+ }
+
+ return false;
+ }
+
+ protected static function change_encoding_iconv($data, $input, $output)
+ {
+ return @iconv($input, $output, $data);
+ }
+
+ /**
+ * @param string $data
+ * @param string $input
+ * @param string $output
+ * @return string|false
+ */
+ protected static function change_encoding_uconverter($data, $input, $output)
+ {
+ return @\UConverter::transcode($data, $output, $input);
+ }
+
+ /**
+ * Normalize an encoding name
+ *
+ * This is automatically generated by create.php
+ *
+ * To generate it, run `php create.php` on the command line, and copy the
+ * output to replace this function.
+ *
+ * @param string $charset Character set to standardise
+ * @return string Standardised name
+ */
+ public static function encoding($charset)
+ {
+ // Normalization from UTS #22
+ switch (strtolower(preg_replace('/(?:[^a-zA-Z0-9]+|([^0-9])0+)/', '\1', $charset)))
+ {
+ case 'adobestandardencoding':
+ case 'csadobestandardencoding':
+ return 'Adobe-Standard-Encoding';
+
+ case 'adobesymbolencoding':
+ case 'cshppsmath':
+ return 'Adobe-Symbol-Encoding';
+
+ case 'ami1251':
+ case 'amiga1251':
+ return 'Amiga-1251';
+
+ case 'ansix31101983':
+ case 'csat5001983':
+ case 'csiso99naplps':
+ case 'isoir99':
+ case 'naplps':
+ return 'ANSI_X3.110-1983';
+
+ case 'arabic7':
+ case 'asmo449':
+ case 'csiso89asmo449':
+ case 'iso9036':
+ case 'isoir89':
+ return 'ASMO_449';
+
+ case 'big5':
+ case 'csbig5':
+ return 'Big5';
+
+ case 'big5hkscs':
+ return 'Big5-HKSCS';
+
+ case 'bocu1':
+ case 'csbocu1':
+ return 'BOCU-1';
+
+ case 'brf':
+ case 'csbrf':
+ return 'BRF';
+
+ case 'bs4730':
+ case 'csiso4unitedkingdom':
+ case 'gb':
+ case 'iso646gb':
+ case 'isoir4':
+ case 'uk':
+ return 'BS_4730';
+
+ case 'bsviewdata':
+ case 'csiso47bsviewdata':
+ case 'isoir47':
+ return 'BS_viewdata';
+
+ case 'cesu8':
+ case 'cscesu8':
+ return 'CESU-8';
+
+ case 'ca':
+ case 'csa71':
+ case 'csaz243419851':
+ case 'csiso121canadian1':
+ case 'iso646ca':
+ case 'isoir121':
+ return 'CSA_Z243.4-1985-1';
+
+ case 'csa72':
+ case 'csaz243419852':
+ case 'csiso122canadian2':
+ case 'iso646ca2':
+ case 'isoir122':
+ return 'CSA_Z243.4-1985-2';
+
+ case 'csaz24341985gr':
+ case 'csiso123csaz24341985gr':
+ case 'isoir123':
+ return 'CSA_Z243.4-1985-gr';
+
+ case 'csiso139csn369103':
+ case 'csn369103':
+ case 'isoir139':
+ return 'CSN_369103';
+
+ case 'csdecmcs':
+ case 'dec':
+ case 'decmcs':
+ return 'DEC-MCS';
+
+ case 'csiso21german':
+ case 'de':
+ case 'din66003':
+ case 'iso646de':
+ case 'isoir21':
+ return 'DIN_66003';
+
+ case 'csdkus':
+ case 'dkus':
+ return 'dk-us';
+
+ case 'csiso646danish':
+ case 'dk':
+ case 'ds2089':
+ case 'iso646dk':
+ return 'DS_2089';
+
+ case 'csibmebcdicatde':
+ case 'ebcdicatde':
+ return 'EBCDIC-AT-DE';
+
+ case 'csebcdicatdea':
+ case 'ebcdicatdea':
+ return 'EBCDIC-AT-DE-A';
+
+ case 'csebcdiccafr':
+ case 'ebcdiccafr':
+ return 'EBCDIC-CA-FR';
+
+ case 'csebcdicdkno':
+ case 'ebcdicdkno':
+ return 'EBCDIC-DK-NO';
+
+ case 'csebcdicdknoa':
+ case 'ebcdicdknoa':
+ return 'EBCDIC-DK-NO-A';
+
+ case 'csebcdices':
+ case 'ebcdices':
+ return 'EBCDIC-ES';
+
+ case 'csebcdicesa':
+ case 'ebcdicesa':
+ return 'EBCDIC-ES-A';
+
+ case 'csebcdicess':
+ case 'ebcdicess':
+ return 'EBCDIC-ES-S';
+
+ case 'csebcdicfise':
+ case 'ebcdicfise':
+ return 'EBCDIC-FI-SE';
+
+ case 'csebcdicfisea':
+ case 'ebcdicfisea':
+ return 'EBCDIC-FI-SE-A';
+
+ case 'csebcdicfr':
+ case 'ebcdicfr':
+ return 'EBCDIC-FR';
+
+ case 'csebcdicit':
+ case 'ebcdicit':
+ return 'EBCDIC-IT';
+
+ case 'csebcdicpt':
+ case 'ebcdicpt':
+ return 'EBCDIC-PT';
+
+ case 'csebcdicuk':
+ case 'ebcdicuk':
+ return 'EBCDIC-UK';
+
+ case 'csebcdicus':
+ case 'ebcdicus':
+ return 'EBCDIC-US';
+
+ case 'csiso111ecmacyrillic':
+ case 'ecmacyrillic':
+ case 'isoir111':
+ case 'koi8e':
+ return 'ECMA-cyrillic';
+
+ case 'csiso17spanish':
+ case 'es':
+ case 'iso646es':
+ case 'isoir17':
+ return 'ES';
+
+ case 'csiso85spanish2':
+ case 'es2':
+ case 'iso646es2':
+ case 'isoir85':
+ return 'ES2';
+
+ case 'cseucpkdfmtjapanese':
+ case 'eucjp':
+ case 'extendedunixcodepackedformatforjapanese':
+ return 'EUC-JP';
+
+ case 'cseucfixwidjapanese':
+ case 'extendedunixcodefixedwidthforjapanese':
+ return 'Extended_UNIX_Code_Fixed_Width_for_Japanese';
+
+ case 'gb18030':
+ return 'GB18030';
+
+ case 'chinese':
+ case 'cp936':
+ case 'csgb2312':
+ case 'csiso58gb231280':
+ case 'gb2312':
+ case 'gb231280':
+ case 'gbk':
+ case 'isoir58':
+ case 'ms936':
+ case 'windows936':
+ return 'GBK';
+
+ case 'cn':
+ case 'csiso57gb1988':
+ case 'gb198880':
+ case 'iso646cn':
+ case 'isoir57':
+ return 'GB_1988-80';
+
+ case 'csiso153gost1976874':
+ case 'gost1976874':
+ case 'isoir153':
+ case 'stsev35888':
+ return 'GOST_19768-74';
+
+ case 'csiso150':
+ case 'csiso150greekccitt':
+ case 'greekccitt':
+ case 'isoir150':
+ return 'greek-ccitt';
+
+ case 'csiso88greek7':
+ case 'greek7':
+ case 'isoir88':
+ return 'greek7';
+
+ case 'csiso18greek7old':
+ case 'greek7old':
+ case 'isoir18':
+ return 'greek7-old';
+
+ case 'cshpdesktop':
+ case 'hpdesktop':
+ return 'HP-DeskTop';
+
+ case 'cshplegal':
+ case 'hplegal':
+ return 'HP-Legal';
+
+ case 'cshpmath8':
+ case 'hpmath8':
+ return 'HP-Math8';
+
+ case 'cshppifont':
+ case 'hppifont':
+ return 'HP-Pi-font';
+
+ case 'cshproman8':
+ case 'hproman8':
+ case 'r8':
+ case 'roman8':
+ return 'hp-roman8';
+
+ case 'hzgb2312':
+ return 'HZ-GB-2312';
+
+ case 'csibmsymbols':
+ case 'ibmsymbols':
+ return 'IBM-Symbols';
+
+ case 'csibmthai':
+ case 'ibmthai':
+ return 'IBM-Thai';
+
+ case 'cp37':
+ case 'csibm37':
+ case 'ebcdiccpca':
+ case 'ebcdiccpnl':
+ case 'ebcdiccpus':
+ case 'ebcdiccpwt':
+ case 'ibm37':
+ return 'IBM037';
+
+ case 'cp38':
+ case 'csibm38':
+ case 'ebcdicint':
+ case 'ibm38':
+ return 'IBM038';
+
+ case 'cp273':
+ case 'csibm273':
+ case 'ibm273':
+ return 'IBM273';
+
+ case 'cp274':
+ case 'csibm274':
+ case 'ebcdicbe':
+ case 'ibm274':
+ return 'IBM274';
+
+ case 'cp275':
+ case 'csibm275':
+ case 'ebcdicbr':
+ case 'ibm275':
+ return 'IBM275';
+
+ case 'csibm277':
+ case 'ebcdiccpdk':
+ case 'ebcdiccpno':
+ case 'ibm277':
+ return 'IBM277';
+
+ case 'cp278':
+ case 'csibm278':
+ case 'ebcdiccpfi':
+ case 'ebcdiccpse':
+ case 'ibm278':
+ return 'IBM278';
+
+ case 'cp280':
+ case 'csibm280':
+ case 'ebcdiccpit':
+ case 'ibm280':
+ return 'IBM280';
+
+ case 'cp281':
+ case 'csibm281':
+ case 'ebcdicjpe':
+ case 'ibm281':
+ return 'IBM281';
+
+ case 'cp284':
+ case 'csibm284':
+ case 'ebcdiccpes':
+ case 'ibm284':
+ return 'IBM284';
+
+ case 'cp285':
+ case 'csibm285':
+ case 'ebcdiccpgb':
+ case 'ibm285':
+ return 'IBM285';
+
+ case 'cp290':
+ case 'csibm290':
+ case 'ebcdicjpkana':
+ case 'ibm290':
+ return 'IBM290';
+
+ case 'cp297':
+ case 'csibm297':
+ case 'ebcdiccpfr':
+ case 'ibm297':
+ return 'IBM297';
+
+ case 'cp420':
+ case 'csibm420':
+ case 'ebcdiccpar1':
+ case 'ibm420':
+ return 'IBM420';
+
+ case 'cp423':
+ case 'csibm423':
+ case 'ebcdiccpgr':
+ case 'ibm423':
+ return 'IBM423';
+
+ case 'cp424':
+ case 'csibm424':
+ case 'ebcdiccphe':
+ case 'ibm424':
+ return 'IBM424';
+
+ case '437':
+ case 'cp437':
+ case 'cspc8codepage437':
+ case 'ibm437':
+ return 'IBM437';
+
+ case 'cp500':
+ case 'csibm500':
+ case 'ebcdiccpbe':
+ case 'ebcdiccpch':
+ case 'ibm500':
+ return 'IBM500';
+
+ case 'cp775':
+ case 'cspc775baltic':
+ case 'ibm775':
+ return 'IBM775';
+
+ case '850':
+ case 'cp850':
+ case 'cspc850multilingual':
+ case 'ibm850':
+ return 'IBM850';
+
+ case '851':
+ case 'cp851':
+ case 'csibm851':
+ case 'ibm851':
+ return 'IBM851';
+
+ case '852':
+ case 'cp852':
+ case 'cspcp852':
+ case 'ibm852':
+ return 'IBM852';
+
+ case '855':
+ case 'cp855':
+ case 'csibm855':
+ case 'ibm855':
+ return 'IBM855';
+
+ case '857':
+ case 'cp857':
+ case 'csibm857':
+ case 'ibm857':
+ return 'IBM857';
+
+ case 'ccsid858':
+ case 'cp858':
+ case 'ibm858':
+ case 'pcmultilingual850euro':
+ return 'IBM00858';
+
+ case '860':
+ case 'cp860':
+ case 'csibm860':
+ case 'ibm860':
+ return 'IBM860';
+
+ case '861':
+ case 'cp861':
+ case 'cpis':
+ case 'csibm861':
+ case 'ibm861':
+ return 'IBM861';
+
+ case '862':
+ case 'cp862':
+ case 'cspc862latinhebrew':
+ case 'ibm862':
+ return 'IBM862';
+
+ case '863':
+ case 'cp863':
+ case 'csibm863':
+ case 'ibm863':
+ return 'IBM863';
+
+ case 'cp864':
+ case 'csibm864':
+ case 'ibm864':
+ return 'IBM864';
+
+ case '865':
+ case 'cp865':
+ case 'csibm865':
+ case 'ibm865':
+ return 'IBM865';
+
+ case '866':
+ case 'cp866':
+ case 'csibm866':
+ case 'ibm866':
+ return 'IBM866';
+
+ case 'cp868':
+ case 'cpar':
+ case 'csibm868':
+ case 'ibm868':
+ return 'IBM868';
+
+ case '869':
+ case 'cp869':
+ case 'cpgr':
+ case 'csibm869':
+ case 'ibm869':
+ return 'IBM869';
+
+ case 'cp870':
+ case 'csibm870':
+ case 'ebcdiccproece':
+ case 'ebcdiccpyu':
+ case 'ibm870':
+ return 'IBM870';
+
+ case 'cp871':
+ case 'csibm871':
+ case 'ebcdiccpis':
+ case 'ibm871':
+ return 'IBM871';
+
+ case 'cp880':
+ case 'csibm880':
+ case 'ebcdiccyrillic':
+ case 'ibm880':
+ return 'IBM880';
+
+ case 'cp891':
+ case 'csibm891':
+ case 'ibm891':
+ return 'IBM891';
+
+ case 'cp903':
+ case 'csibm903':
+ case 'ibm903':
+ return 'IBM903';
+
+ case '904':
+ case 'cp904':
+ case 'csibbm904':
+ case 'ibm904':
+ return 'IBM904';
+
+ case 'cp905':
+ case 'csibm905':
+ case 'ebcdiccptr':
+ case 'ibm905':
+ return 'IBM905';
+
+ case 'cp918':
+ case 'csibm918':
+ case 'ebcdiccpar2':
+ case 'ibm918':
+ return 'IBM918';
+
+ case 'ccsid924':
+ case 'cp924':
+ case 'ebcdiclatin9euro':
+ case 'ibm924':
+ return 'IBM00924';
+
+ case 'cp1026':
+ case 'csibm1026':
+ case 'ibm1026':
+ return 'IBM1026';
+
+ case 'ibm1047':
+ return 'IBM1047';
+
+ case 'ccsid1140':
+ case 'cp1140':
+ case 'ebcdicus37euro':
+ case 'ibm1140':
+ return 'IBM01140';
+
+ case 'ccsid1141':
+ case 'cp1141':
+ case 'ebcdicde273euro':
+ case 'ibm1141':
+ return 'IBM01141';
+
+ case 'ccsid1142':
+ case 'cp1142':
+ case 'ebcdicdk277euro':
+ case 'ebcdicno277euro':
+ case 'ibm1142':
+ return 'IBM01142';
+
+ case 'ccsid1143':
+ case 'cp1143':
+ case 'ebcdicfi278euro':
+ case 'ebcdicse278euro':
+ case 'ibm1143':
+ return 'IBM01143';
+
+ case 'ccsid1144':
+ case 'cp1144':
+ case 'ebcdicit280euro':
+ case 'ibm1144':
+ return 'IBM01144';
+
+ case 'ccsid1145':
+ case 'cp1145':
+ case 'ebcdices284euro':
+ case 'ibm1145':
+ return 'IBM01145';
+
+ case 'ccsid1146':
+ case 'cp1146':
+ case 'ebcdicgb285euro':
+ case 'ibm1146':
+ return 'IBM01146';
+
+ case 'ccsid1147':
+ case 'cp1147':
+ case 'ebcdicfr297euro':
+ case 'ibm1147':
+ return 'IBM01147';
+
+ case 'ccsid1148':
+ case 'cp1148':
+ case 'ebcdicinternational500euro':
+ case 'ibm1148':
+ return 'IBM01148';
+
+ case 'ccsid1149':
+ case 'cp1149':
+ case 'ebcdicis871euro':
+ case 'ibm1149':
+ return 'IBM01149';
+
+ case 'csiso143iecp271':
+ case 'iecp271':
+ case 'isoir143':
+ return 'IEC_P27-1';
+
+ case 'csiso49inis':
+ case 'inis':
+ case 'isoir49':
+ return 'INIS';
+
+ case 'csiso50inis8':
+ case 'inis8':
+ case 'isoir50':
+ return 'INIS-8';
+
+ case 'csiso51iniscyrillic':
+ case 'iniscyrillic':
+ case 'isoir51':
+ return 'INIS-cyrillic';
+
+ case 'csinvariant':
+ case 'invariant':
+ return 'INVARIANT';
+
+ case 'iso2022cn':
+ return 'ISO-2022-CN';
+
+ case 'iso2022cnext':
+ return 'ISO-2022-CN-EXT';
+
+ case 'csiso2022jp':
+ case 'iso2022jp':
+ return 'ISO-2022-JP';
+
+ case 'csiso2022jp2':
+ case 'iso2022jp2':
+ return 'ISO-2022-JP-2';
+
+ case 'csiso2022kr':
+ case 'iso2022kr':
+ return 'ISO-2022-KR';
+
+ case 'cswindows30latin1':
+ case 'iso88591windows30latin1':
+ return 'ISO-8859-1-Windows-3.0-Latin-1';
+
+ case 'cswindows31latin1':
+ case 'iso88591windows31latin1':
+ return 'ISO-8859-1-Windows-3.1-Latin-1';
+
+ case 'csisolatin2':
+ case 'iso88592':
+ case 'iso885921987':
+ case 'isoir101':
+ case 'l2':
+ case 'latin2':
+ return 'ISO-8859-2';
+
+ case 'cswindows31latin2':
+ case 'iso88592windowslatin2':
+ return 'ISO-8859-2-Windows-Latin-2';
+
+ case 'csisolatin3':
+ case 'iso88593':
+ case 'iso885931988':
+ case 'isoir109':
+ case 'l3':
+ case 'latin3':
+ return 'ISO-8859-3';
+
+ case 'csisolatin4':
+ case 'iso88594':
+ case 'iso885941988':
+ case 'isoir110':
+ case 'l4':
+ case 'latin4':
+ return 'ISO-8859-4';
+
+ case 'csisolatincyrillic':
+ case 'cyrillic':
+ case 'iso88595':
+ case 'iso885951988':
+ case 'isoir144':
+ return 'ISO-8859-5';
+
+ case 'arabic':
+ case 'asmo708':
+ case 'csisolatinarabic':
+ case 'ecma114':
+ case 'iso88596':
+ case 'iso885961987':
+ case 'isoir127':
+ return 'ISO-8859-6';
+
+ case 'csiso88596e':
+ case 'iso88596e':
+ return 'ISO-8859-6-E';
+
+ case 'csiso88596i':
+ case 'iso88596i':
+ return 'ISO-8859-6-I';
+
+ case 'csisolatingreek':
+ case 'ecma118':
+ case 'elot928':
+ case 'greek':
+ case 'greek8':
+ case 'iso88597':
+ case 'iso885971987':
+ case 'isoir126':
+ return 'ISO-8859-7';
+
+ case 'csisolatinhebrew':
+ case 'hebrew':
+ case 'iso88598':
+ case 'iso885981988':
+ case 'isoir138':
+ return 'ISO-8859-8';
+
+ case 'csiso88598e':
+ case 'iso88598e':
+ return 'ISO-8859-8-E';
+
+ case 'csiso88598i':
+ case 'iso88598i':
+ return 'ISO-8859-8-I';
+
+ case 'cswindows31latin5':
+ case 'iso88599windowslatin5':
+ return 'ISO-8859-9-Windows-Latin-5';
+
+ case 'csisolatin6':
+ case 'iso885910':
+ case 'iso8859101992':
+ case 'isoir157':
+ case 'l6':
+ case 'latin6':
+ return 'ISO-8859-10';
+
+ case 'iso885913':
+ return 'ISO-8859-13';
+
+ case 'iso885914':
+ case 'iso8859141998':
+ case 'isoceltic':
+ case 'isoir199':
+ case 'l8':
+ case 'latin8':
+ return 'ISO-8859-14';
+
+ case 'iso885915':
+ case 'latin9':
+ return 'ISO-8859-15';
+
+ case 'iso885916':
+ case 'iso8859162001':
+ case 'isoir226':
+ case 'l10':
+ case 'latin10':
+ return 'ISO-8859-16';
+
+ case 'iso10646j1':
+ return 'ISO-10646-J-1';
+
+ case 'csunicode':
+ case 'iso10646ucs2':
+ return 'ISO-10646-UCS-2';
+
+ case 'csucs4':
+ case 'iso10646ucs4':
+ return 'ISO-10646-UCS-4';
+
+ case 'csunicodeascii':
+ case 'iso10646ucsbasic':
+ return 'ISO-10646-UCS-Basic';
+
+ case 'csunicodelatin1':
+ case 'iso10646':
+ case 'iso10646unicodelatin1':
+ return 'ISO-10646-Unicode-Latin1';
+
+ case 'csiso10646utf1':
+ case 'iso10646utf1':
+ return 'ISO-10646-UTF-1';
+
+ case 'csiso115481':
+ case 'iso115481':
+ case 'isotr115481':
+ return 'ISO-11548-1';
+
+ case 'csiso90':
+ case 'isoir90':
+ return 'iso-ir-90';
+
+ case 'csunicodeibm1261':
+ case 'isounicodeibm1261':
+ return 'ISO-Unicode-IBM-1261';
+
+ case 'csunicodeibm1264':
+ case 'isounicodeibm1264':
+ return 'ISO-Unicode-IBM-1264';
+
+ case 'csunicodeibm1265':
+ case 'isounicodeibm1265':
+ return 'ISO-Unicode-IBM-1265';
+
+ case 'csunicodeibm1268':
+ case 'isounicodeibm1268':
+ return 'ISO-Unicode-IBM-1268';
+
+ case 'csunicodeibm1276':
+ case 'isounicodeibm1276':
+ return 'ISO-Unicode-IBM-1276';
+
+ case 'csiso646basic1983':
+ case 'iso646basic1983':
+ case 'ref':
+ return 'ISO_646.basic:1983';
+
+ case 'csiso2intlrefversion':
+ case 'irv':
+ case 'iso646irv1983':
+ case 'isoir2':
+ return 'ISO_646.irv:1983';
+
+ case 'csiso2033':
+ case 'e13b':
+ case 'iso20331983':
+ case 'isoir98':
+ return 'ISO_2033-1983';
+
+ case 'csiso5427cyrillic':
+ case 'iso5427':
+ case 'isoir37':
+ return 'ISO_5427';
+
+ case 'iso5427cyrillic1981':
+ case 'iso54271981':
+ case 'isoir54':
+ return 'ISO_5427:1981';
+
+ case 'csiso5428greek':
+ case 'iso54281980':
+ case 'isoir55':
+ return 'ISO_5428:1980';
+
+ case 'csiso6937add':
+ case 'iso6937225':
+ case 'isoir152':
+ return 'ISO_6937-2-25';
+
+ case 'csisotextcomm':
+ case 'iso69372add':
+ case 'isoir142':
+ return 'ISO_6937-2-add';
+
+ case 'csiso8859supp':
+ case 'iso8859supp':
+ case 'isoir154':
+ case 'latin125':
+ return 'ISO_8859-supp';
+
+ case 'csiso10367box':
+ case 'iso10367box':
+ case 'isoir155':
+ return 'ISO_10367-box';
+
+ case 'csiso15italian':
+ case 'iso646it':
+ case 'isoir15':
+ case 'it':
+ return 'IT';
+
+ case 'csiso13jisc6220jp':
+ case 'isoir13':
+ case 'jisc62201969':
+ case 'jisc62201969jp':
+ case 'katakana':
+ case 'x2017':
+ return 'JIS_C6220-1969-jp';
+
+ case 'csiso14jisc6220ro':
+ case 'iso646jp':
+ case 'isoir14':
+ case 'jisc62201969ro':
+ case 'jp':
+ return 'JIS_C6220-1969-ro';
+
+ case 'csiso42jisc62261978':
+ case 'isoir42':
+ case 'jisc62261978':
+ return 'JIS_C6226-1978';
+
+ case 'csiso87jisx208':
+ case 'isoir87':
+ case 'jisc62261983':
+ case 'jisx2081983':
+ case 'x208':
+ return 'JIS_C6226-1983';
+
+ case 'csiso91jisc62291984a':
+ case 'isoir91':
+ case 'jisc62291984a':
+ case 'jpocra':
+ return 'JIS_C6229-1984-a';
+
+ case 'csiso92jisc62991984b':
+ case 'iso646jpocrb':
+ case 'isoir92':
+ case 'jisc62291984b':
+ case 'jpocrb':
+ return 'JIS_C6229-1984-b';
+
+ case 'csiso93jis62291984badd':
+ case 'isoir93':
+ case 'jisc62291984badd':
+ case 'jpocrbadd':
+ return 'JIS_C6229-1984-b-add';
+
+ case 'csiso94jis62291984hand':
+ case 'isoir94':
+ case 'jisc62291984hand':
+ case 'jpocrhand':
+ return 'JIS_C6229-1984-hand';
+
+ case 'csiso95jis62291984handadd':
+ case 'isoir95':
+ case 'jisc62291984handadd':
+ case 'jpocrhandadd':
+ return 'JIS_C6229-1984-hand-add';
+
+ case 'csiso96jisc62291984kana':
+ case 'isoir96':
+ case 'jisc62291984kana':
+ return 'JIS_C6229-1984-kana';
+
+ case 'csjisencoding':
+ case 'jisencoding':
+ return 'JIS_Encoding';
+
+ case 'cshalfwidthkatakana':
+ case 'jisx201':
+ case 'x201':
+ return 'JIS_X0201';
+
+ case 'csiso159jisx2121990':
+ case 'isoir159':
+ case 'jisx2121990':
+ case 'x212':
+ return 'JIS_X0212-1990';
+
+ case 'csiso141jusib1002':
+ case 'iso646yu':
+ case 'isoir141':
+ case 'js':
+ case 'jusib1002':
+ case 'yu':
+ return 'JUS_I.B1.002';
+
+ case 'csiso147macedonian':
+ case 'isoir147':
+ case 'jusib1003mac':
+ case 'macedonian':
+ return 'JUS_I.B1.003-mac';
+
+ case 'csiso146serbian':
+ case 'isoir146':
+ case 'jusib1003serb':
+ case 'serbian':
+ return 'JUS_I.B1.003-serb';
+
+ case 'koi7switched':
+ return 'KOI7-switched';
+
+ case 'cskoi8r':
+ case 'koi8r':
+ return 'KOI8-R';
+
+ case 'koi8u':
+ return 'KOI8-U';
+
+ case 'csksc5636':
+ case 'iso646kr':
+ case 'ksc5636':
+ return 'KSC5636';
+
+ case 'cskz1048':
+ case 'kz1048':
+ case 'rk1048':
+ case 'strk10482002':
+ return 'KZ-1048';
+
+ case 'csiso19latingreek':
+ case 'isoir19':
+ case 'latingreek':
+ return 'latin-greek';
+
+ case 'csiso27latingreek1':
+ case 'isoir27':
+ case 'latingreek1':
+ return 'Latin-greek-1';
+
+ case 'csiso158lap':
+ case 'isoir158':
+ case 'lap':
+ case 'latinlap':
+ return 'latin-lap';
+
+ case 'csmacintosh':
+ case 'mac':
+ case 'macintosh':
+ return 'macintosh';
+
+ case 'csmicrosoftpublishing':
+ case 'microsoftpublishing':
+ return 'Microsoft-Publishing';
+
+ case 'csmnem':
+ case 'mnem':
+ return 'MNEM';
+
+ case 'csmnemonic':
+ case 'mnemonic':
+ return 'MNEMONIC';
+
+ case 'csiso86hungarian':
+ case 'hu':
+ case 'iso646hu':
+ case 'isoir86':
+ case 'msz77953':
+ return 'MSZ_7795.3';
+
+ case 'csnatsdano':
+ case 'isoir91':
+ case 'natsdano':
+ return 'NATS-DANO';
+
+ case 'csnatsdanoadd':
+ case 'isoir92':
+ case 'natsdanoadd':
+ return 'NATS-DANO-ADD';
+
+ case 'csnatssefi':
+ case 'isoir81':
+ case 'natssefi':
+ return 'NATS-SEFI';
+
+ case 'csnatssefiadd':
+ case 'isoir82':
+ case 'natssefiadd':
+ return 'NATS-SEFI-ADD';
+
+ case 'csiso151cuba':
+ case 'cuba':
+ case 'iso646cu':
+ case 'isoir151':
+ case 'ncnc1081':
+ return 'NC_NC00-10:81';
+
+ case 'csiso69french':
+ case 'fr':
+ case 'iso646fr':
+ case 'isoir69':
+ case 'nfz62010':
+ return 'NF_Z_62-010';
+
+ case 'csiso25french':
+ case 'iso646fr1':
+ case 'isoir25':
+ case 'nfz620101973':
+ return 'NF_Z_62-010_(1973)';
+
+ case 'csiso60danishnorwegian':
+ case 'csiso60norwegian1':
+ case 'iso646no':
+ case 'isoir60':
+ case 'no':
+ case 'ns45511':
+ return 'NS_4551-1';
+
+ case 'csiso61norwegian2':
+ case 'iso646no2':
+ case 'isoir61':
+ case 'no2':
+ case 'ns45512':
+ return 'NS_4551-2';
+
+ case 'osdebcdicdf3irv':
+ return 'OSD_EBCDIC_DF03_IRV';
+
+ case 'osdebcdicdf41':
+ return 'OSD_EBCDIC_DF04_1';
+
+ case 'osdebcdicdf415':
+ return 'OSD_EBCDIC_DF04_15';
+
+ case 'cspc8danishnorwegian':
+ case 'pc8danishnorwegian':
+ return 'PC8-Danish-Norwegian';
+
+ case 'cspc8turkish':
+ case 'pc8turkish':
+ return 'PC8-Turkish';
+
+ case 'csiso16portuguese':
+ case 'iso646pt':
+ case 'isoir16':
+ case 'pt':
+ return 'PT';
+
+ case 'csiso84portuguese2':
+ case 'iso646pt2':
+ case 'isoir84':
+ case 'pt2':
+ return 'PT2';
+
+ case 'cp154':
+ case 'csptcp154':
+ case 'cyrillicasian':
+ case 'pt154':
+ case 'ptcp154':
+ return 'PTCP154';
+
+ case 'scsu':
+ return 'SCSU';
+
+ case 'csiso10swedish':
+ case 'fi':
+ case 'iso646fi':
+ case 'iso646se':
+ case 'isoir10':
+ case 'se':
+ case 'sen850200b':
+ return 'SEN_850200_B';
+
+ case 'csiso11swedishfornames':
+ case 'iso646se2':
+ case 'isoir11':
+ case 'se2':
+ case 'sen850200c':
+ return 'SEN_850200_C';
+
+ case 'csiso102t617bit':
+ case 'isoir102':
+ case 't617bit':
+ return 'T.61-7bit';
+
+ case 'csiso103t618bit':
+ case 'isoir103':
+ case 't61':
+ case 't618bit':
+ return 'T.61-8bit';
+
+ case 'csiso128t101g2':
+ case 'isoir128':
+ case 't101g2':
+ return 'T.101-G2';
+
+ case 'cstscii':
+ case 'tscii':
+ return 'TSCII';
+
+ case 'csunicode11':
+ case 'unicode11':
+ return 'UNICODE-1-1';
+
+ case 'csunicode11utf7':
+ case 'unicode11utf7':
+ return 'UNICODE-1-1-UTF-7';
+
+ case 'csunknown8bit':
+ case 'unknown8bit':
+ return 'UNKNOWN-8BIT';
+
+ case 'ansix341968':
+ case 'ansix341986':
+ case 'ascii':
+ case 'cp367':
+ case 'csascii':
+ case 'ibm367':
+ case 'iso646irv1991':
+ case 'iso646us':
+ case 'isoir6':
+ case 'us':
+ case 'usascii':
+ return 'US-ASCII';
+
+ case 'csusdk':
+ case 'usdk':
+ return 'us-dk';
+
+ case 'utf7':
+ return 'UTF-7';
+
+ case 'utf8':
+ return 'UTF-8';
+
+ case 'utf16':
+ return 'UTF-16';
+
+ case 'utf16be':
+ return 'UTF-16BE';
+
+ case 'utf16le':
+ return 'UTF-16LE';
+
+ case 'utf32':
+ return 'UTF-32';
+
+ case 'utf32be':
+ return 'UTF-32BE';
+
+ case 'utf32le':
+ return 'UTF-32LE';
+
+ case 'csventurainternational':
+ case 'venturainternational':
+ return 'Ventura-International';
+
+ case 'csventuramath':
+ case 'venturamath':
+ return 'Ventura-Math';
+
+ case 'csventuraus':
+ case 'venturaus':
+ return 'Ventura-US';
+
+ case 'csiso70videotexsupp1':
+ case 'isoir70':
+ case 'videotexsuppl':
+ return 'videotex-suppl';
+
+ case 'csviqr':
+ case 'viqr':
+ return 'VIQR';
+
+ case 'csviscii':
+ case 'viscii':
+ return 'VISCII';
+
+ case 'csshiftjis':
+ case 'cswindows31j':
+ case 'mskanji':
+ case 'shiftjis':
+ case 'windows31j':
+ return 'Windows-31J';
+
+ case 'iso885911':
+ case 'tis620':
+ return 'windows-874';
+
+ case 'cseuckr':
+ case 'csksc56011987':
+ case 'euckr':
+ case 'isoir149':
+ case 'korean':
+ case 'ksc5601':
+ case 'ksc56011987':
+ case 'ksc56011989':
+ case 'windows949':
+ return 'windows-949';
+
+ case 'windows1250':
+ return 'windows-1250';
+
+ case 'windows1251':
+ return 'windows-1251';
+
+ case 'cp819':
+ case 'csisolatin1':
+ case 'ibm819':
+ case 'iso88591':
+ case 'iso885911987':
+ case 'isoir100':
+ case 'l1':
+ case 'latin1':
+ case 'windows1252':
+ return 'windows-1252';
+
+ case 'windows1253':
+ return 'windows-1253';
+
+ case 'csisolatin5':
+ case 'iso88599':
+ case 'iso885991989':
+ case 'isoir148':
+ case 'l5':
+ case 'latin5':
+ case 'windows1254':
+ return 'windows-1254';
+
+ case 'windows1255':
+ return 'windows-1255';
+
+ case 'windows1256':
+ return 'windows-1256';
+
+ case 'windows1257':
+ return 'windows-1257';
+
+ case 'windows1258':
+ return 'windows-1258';
+
+ default:
+ return $charset;
+ }
+ }
+
+ public static function get_curl_version()
+ {
+ if (is_array($curl = curl_version()))
+ {
+ $curl = $curl['version'];
+ }
+ elseif (substr($curl, 0, 5) === 'curl/')
+ {
+ $curl = substr($curl, 5, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 5));
+ }
+ elseif (substr($curl, 0, 8) === 'libcurl/')
+ {
+ $curl = substr($curl, 8, strcspn($curl, "\x09\x0A\x0B\x0C\x0D", 8));
+ }
+ else
+ {
+ $curl = 0;
+ }
+ return $curl;
+ }
+
+ /**
+ * Strip HTML comments
+ *
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ public static function strip_comments($data)
+ {
+ $output = '';
+ while (($start = strpos($data, '<!--')) !== false)
+ {
+ $output .= substr($data, 0, $start);
+ if (($end = strpos($data, '-->', $start)) !== false)
+ {
+ $data = substr_replace($data, '', 0, $end + 3);
+ }
+ else
+ {
+ $data = '';
+ }
+ }
+ return $output . $data;
+ }
+
+ public static function parse_date($dt)
+ {
+ $parser = SimplePie_Parse_Date::get();
+ return $parser->parse($dt);
+ }
+
+ /**
+ * Decode HTML entities
+ *
+ * @deprecated Use DOMDocument instead
+ * @param string $data Input data
+ * @return string Output data
+ */
+ public static function entities_decode($data)
+ {
+ $decoder = new SimplePie_Decode_HTML_Entities($data);
+ return $decoder->parse();
+ }
+
+ /**
+ * Remove RFC822 comments
+ *
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ public static function uncomment_rfc822($string)
+ {
+ $string = (string) $string;
+ $position = 0;
+ $length = strlen($string);
+ $depth = 0;
+
+ $output = '';
+
+ while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
+ {
+ $output .= substr($string, $position, $pos - $position);
+ $position = $pos + 1;
+ if ($string[$pos - 1] !== '\\')
+ {
+ $depth++;
+ while ($depth && $position < $length)
+ {
+ $position += strcspn($string, '()', $position);
+ if ($string[$position - 1] === '\\')
+ {
+ $position++;
+ continue;
+ }
+ elseif (isset($string[$position]))
+ {
+ switch ($string[$position])
+ {
+ case '(':
+ $depth++;
+ break;
+
+ case ')':
+ $depth--;
+ break;
+ }
+ $position++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ $output .= '(';
+ }
+ }
+ $output .= substr($string, $position);
+
+ return $output;
+ }
+
+ public static function parse_mime($mime)
+ {
+ if (($pos = strpos($mime, ';')) === false)
+ {
+ return trim($mime);
+ }
+
+ return trim(substr($mime, 0, $pos));
+ }
+
+ public static function atom_03_construct_type($attribs)
+ {
+ if (isset($attribs['']['mode']) && strtolower(trim($attribs['']['mode']) === 'base64'))
+ {
+ $mode = SIMPLEPIE_CONSTRUCT_BASE64;
+ }
+ else
+ {
+ $mode = SIMPLEPIE_CONSTRUCT_NONE;
+ }
+ if (isset($attribs['']['type']))
+ {
+ switch (strtolower(trim($attribs['']['type'])))
+ {
+ case 'text':
+ case 'text/plain':
+ return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
+
+ case 'html':
+ case 'text/html':
+ return SIMPLEPIE_CONSTRUCT_HTML | $mode;
+
+ case 'xhtml':
+ case 'application/xhtml+xml':
+ return SIMPLEPIE_CONSTRUCT_XHTML | $mode;
+
+ default:
+ return SIMPLEPIE_CONSTRUCT_NONE | $mode;
+ }
+ }
+
+ return SIMPLEPIE_CONSTRUCT_TEXT | $mode;
+ }
+
+ public static function atom_10_construct_type($attribs)
+ {
+ if (isset($attribs['']['type']))
+ {
+ switch (strtolower(trim($attribs['']['type'])))
+ {
+ case 'text':
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+
+ case 'html':
+ return SIMPLEPIE_CONSTRUCT_HTML;
+
+ case 'xhtml':
+ return SIMPLEPIE_CONSTRUCT_XHTML;
+
+ default:
+ return SIMPLEPIE_CONSTRUCT_NONE;
+ }
+ }
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+ }
+
+ public static function atom_10_content_construct_type($attribs)
+ {
+ if (isset($attribs['']['type']))
+ {
+ $type = strtolower(trim($attribs['']['type']));
+ switch ($type)
+ {
+ case 'text':
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+
+ case 'html':
+ return SIMPLEPIE_CONSTRUCT_HTML;
+
+ case 'xhtml':
+ return SIMPLEPIE_CONSTRUCT_XHTML;
+ }
+ if (in_array(substr($type, -4), array('+xml', '/xml')) || substr($type, 0, 5) === 'text/')
+ {
+ return SIMPLEPIE_CONSTRUCT_NONE;
+ }
+ else
+ {
+ return SIMPLEPIE_CONSTRUCT_BASE64;
+ }
+ }
+
+ return SIMPLEPIE_CONSTRUCT_TEXT;
+ }
+
+ public static function is_isegment_nz_nc($string)
+ {
+ return (bool) preg_match('/^([A-Za-z0-9\-._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!$&\'()*+,;=@]|(%[0-9ABCDEF]{2}))+$/u', $string);
+ }
+
+ public static function space_separated_tokens($string)
+ {
+ $space_characters = "\x20\x09\x0A\x0B\x0C\x0D";
+ $string_length = strlen($string);
+
+ $position = strspn($string, $space_characters);
+ $tokens = array();
+
+ while ($position < $string_length)
+ {
+ $len = strcspn($string, $space_characters, $position);
+ $tokens[] = substr($string, $position, $len);
+ $position += $len;
+ $position += strspn($string, $space_characters, $position);
+ }
+
+ return $tokens;
+ }
+
+ /**
+ * Converts a unicode codepoint to a UTF-8 character
+ *
+ * @static
+ * @param int $codepoint Unicode codepoint
+ * @return string UTF-8 character
+ */
+ public static function codepoint_to_utf8($codepoint)
+ {
+ $codepoint = (int) $codepoint;
+ if ($codepoint < 0)
+ {
+ return false;
+ }
+ else if ($codepoint <= 0x7f)
+ {
+ return chr($codepoint);
+ }
+ else if ($codepoint <= 0x7ff)
+ {
+ return chr(0xc0 | ($codepoint >> 6)) . chr(0x80 | ($codepoint & 0x3f));
+ }
+ else if ($codepoint <= 0xffff)
+ {
+ return chr(0xe0 | ($codepoint >> 12)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
+ }
+ else if ($codepoint <= 0x10ffff)
+ {
+ return chr(0xf0 | ($codepoint >> 18)) . chr(0x80 | (($codepoint >> 12) & 0x3f)) . chr(0x80 | (($codepoint >> 6) & 0x3f)) . chr(0x80 | ($codepoint & 0x3f));
+ }
+
+ // U+FFFD REPLACEMENT CHARACTER
+ return "\xEF\xBF\xBD";
+ }
+
+ /**
+ * Similar to parse_str()
+ *
+ * Returns an associative array of name/value pairs, where the value is an
+ * array of values that have used the same name
+ *
+ * @static
+ * @param string $str The input string.
+ * @return array
+ */
+ public static function parse_str($str)
+ {
+ $return = array();
+ $str = explode('&', $str);
+
+ foreach ($str as $section)
+ {
+ if (strpos($section, '=') !== false)
+ {
+ list($name, $value) = explode('=', $section, 2);
+ $return[urldecode($name)][] = urldecode($value);
+ }
+ else
+ {
+ $return[urldecode($section)][] = null;
+ }
+ }
+
+ return $return;
+ }
+
+ /**
+ * Detect XML encoding, as per XML 1.0 Appendix F.1
+ *
+ * @todo Add support for EBCDIC
+ * @param string $data XML data
+ * @param SimplePie_Registry $registry Class registry
+ * @return array Possible encodings
+ */
+ public static function xml_encoding($data, $registry)
+ {
+ // UTF-32 Big Endian BOM
+ if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
+ {
+ $encoding[] = 'UTF-32BE';
+ }
+ // UTF-32 Little Endian BOM
+ elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
+ {
+ $encoding[] = 'UTF-32LE';
+ }
+ // UTF-16 Big Endian BOM
+ elseif (substr($data, 0, 2) === "\xFE\xFF")
+ {
+ $encoding[] = 'UTF-16BE';
+ }
+ // UTF-16 Little Endian BOM
+ elseif (substr($data, 0, 2) === "\xFF\xFE")
+ {
+ $encoding[] = 'UTF-16LE';
+ }
+ // UTF-8 BOM
+ elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
+ {
+ $encoding[] = 'UTF-8';
+ }
+ // UTF-32 Big Endian Without BOM
+ elseif (substr($data, 0, 20) === "\x00\x00\x00\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C")
+ {
+ if ($pos = strpos($data, "\x00\x00\x00\x3F\x00\x00\x00\x3E"))
+ {
+ $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32BE', 'UTF-8')));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-32BE';
+ }
+ // UTF-32 Little Endian Without BOM
+ elseif (substr($data, 0, 20) === "\x3C\x00\x00\x00\x3F\x00\x00\x00\x78\x00\x00\x00\x6D\x00\x00\x00\x6C\x00\x00\x00")
+ {
+ if ($pos = strpos($data, "\x3F\x00\x00\x00\x3E\x00\x00\x00"))
+ {
+ $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 20), 'UTF-32LE', 'UTF-8')));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-32LE';
+ }
+ // UTF-16 Big Endian Without BOM
+ elseif (substr($data, 0, 10) === "\x00\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C")
+ {
+ if ($pos = strpos($data, "\x00\x3F\x00\x3E"))
+ {
+ $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16BE', 'UTF-8')));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-16BE';
+ }
+ // UTF-16 Little Endian Without BOM
+ elseif (substr($data, 0, 10) === "\x3C\x00\x3F\x00\x78\x00\x6D\x00\x6C\x00")
+ {
+ if ($pos = strpos($data, "\x3F\x00\x3E\x00"))
+ {
+ $parser = $registry->create('XML_Declaration_Parser', array(SimplePie_Misc::change_encoding(substr($data, 20, $pos - 10), 'UTF-16LE', 'UTF-8')));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-16LE';
+ }
+ // US-ASCII (or superset)
+ elseif (substr($data, 0, 5) === "\x3C\x3F\x78\x6D\x6C")
+ {
+ if ($pos = strpos($data, "\x3F\x3E"))
+ {
+ $parser = $registry->create('XML_Declaration_Parser', array(substr($data, 5, $pos - 5)));
+ if ($parser->parse())
+ {
+ $encoding[] = $parser->encoding;
+ }
+ }
+ $encoding[] = 'UTF-8';
+ }
+ // Fallback to UTF-8
+ else
+ {
+ $encoding[] = 'UTF-8';
+ }
+ return $encoding;
+ }
+
+ public static function output_javascript()
+ {
+ if (function_exists('ob_gzhandler'))
+ {
+ ob_start('ob_gzhandler');
+ }
+ header('Content-type: text/javascript; charset: UTF-8');
+ header('Cache-Control: must-revalidate');
+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 604800) . ' GMT'); // 7 days
+ ?>
+function embed_quicktime(type, bgcolor, width, height, link, placeholder, loop) {
+ if (placeholder != '') {
+ document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" href="'+link+'" src="'+placeholder+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="false" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
+ }
+ else {
+ document.writeln('<embed type="'+type+'" style="cursor:hand; cursor:pointer;" src="'+link+'" width="'+width+'" height="'+height+'" autoplay="false" target="myself" controller="true" loop="'+loop+'" scale="aspect" bgcolor="'+bgcolor+'" pluginspage="http://www.apple.com/quicktime/download/"></embed>');
+ }
+}
+
+function embed_flash(bgcolor, width, height, link, loop, type) {
+ document.writeln('<embed src="'+link+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="'+type+'" quality="high" width="'+width+'" height="'+height+'" bgcolor="'+bgcolor+'" loop="'+loop+'"></embed>');
+}
+
+function embed_flv(width, height, link, placeholder, loop, player) {
+ document.writeln('<embed src="'+player+'" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" quality="high" width="'+width+'" height="'+height+'" wmode="transparent" flashvars="file='+link+'&autostart=false&repeat='+loop+'&showdigits=true&showfsbutton=false"></embed>');
+}
+
+function embed_wmedia(width, height, link) {
+ document.writeln('<embed type="application/x-mplayer2" src="'+link+'" autosize="1" width="'+width+'" height="'+height+'" showcontrols="1" showstatusbar="0" showdisplay="0" autostart="0"></embed>');
+}
+ <?php
+ }
+
+ /**
+ * Get the SimplePie build timestamp
+ *
+ * Uses the git index if it exists, otherwise uses the modification time
+ * of the newest file.
+ */
+ public static function get_build()
+ {
+ $root = dirname(dirname(__FILE__));
+ if (file_exists($root . '/.git/index'))
+ {
+ return filemtime($root . '/.git/index');
+ }
+ elseif (file_exists($root . '/SimplePie'))
+ {
+ $time = 0;
+ foreach (glob($root . '/SimplePie/*.php') as $file)
+ {
+ if (($mtime = filemtime($file)) > $time)
+ {
+ $time = $mtime;
+ }
+ }
+ return $time;
+ }
+ elseif (file_exists(dirname(__FILE__) . '/Core.php'))
+ {
+ return filemtime(dirname(__FILE__) . '/Core.php');
+ }
+
+ return filemtime(__FILE__);
+ }
+
+ /**
+ * Format debugging information
+ */
+ public static function debug(&$sp)
+ {
+ $info = 'SimplePie ' . SIMPLEPIE_VERSION . ' Build ' . SIMPLEPIE_BUILD . "\n";
+ $info .= 'PHP ' . PHP_VERSION . "\n";
+ if ($sp->error() !== null)
+ {
+ $info .= 'Error occurred: ' . $sp->error() . "\n";
+ }
+ else
+ {
+ $info .= "No error found.\n";
+ }
+ $info .= "Extensions:\n";
+ $extensions = array('pcre', 'curl', 'zlib', 'mbstring', 'iconv', 'xmlreader', 'xml');
+ foreach ($extensions as $ext)
+ {
+ if (extension_loaded($ext))
+ {
+ $info .= " $ext loaded\n";
+ switch ($ext)
+ {
+ case 'pcre':
+ $info .= ' Version ' . PCRE_VERSION . "\n";
+ break;
+ case 'curl':
+ $version = curl_version();
+ $info .= ' Version ' . $version['version'] . "\n";
+ break;
+ case 'mbstring':
+ $info .= ' Overloading: ' . mb_get_info('func_overload') . "\n";
+ break;
+ case 'iconv':
+ $info .= ' Version ' . ICONV_VERSION . "\n";
+ break;
+ case 'xml':
+ $info .= ' Version ' . LIBXML_DOTTED_VERSION . "\n";
+ break;
+ }
+ }
+ else
+ {
+ $info .= " $ext not loaded\n";
+ }
+ }
+ return $info;
+ }
+
+ public static function silence_errors($num, $str)
+ {
+ // No-op
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Net/IPv6.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Net/IPv6.php
new file mode 100644
index 0000000..25c992b
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Net/IPv6.php
@@ -0,0 +1,269 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+
+/**
+ * Class to validate and to work with IPv6 addresses.
+ *
+ * @package SimplePie
+ * @subpackage HTTP
+ * @copyright 2003-2005 The PHP Group
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ * @link http://pear.php.net/package/Net_IPv6
+ * @author Alexander Merz <alexander.merz@web.de>
+ * @author elfrink at introweb dot nl
+ * @author Josh Peck <jmp at joshpeck dot org>
+ * @author Sam Sneddon <geoffers@gmail.com>
+ */
+class SimplePie_Net_IPv6
+{
+ /**
+ * Uncompresses an IPv6 address
+ *
+ * RFC 4291 allows you to compress concecutive zero pieces in an address to
+ * '::'. This method expects a valid IPv6 address and expands the '::' to
+ * the required number of zero pieces.
+ *
+ * Example: FF01::101 -> FF01:0:0:0:0:0:0:101
+ * ::1 -> 0:0:0:0:0:0:0:1
+ *
+ * @author Alexander Merz <alexander.merz@web.de>
+ * @author elfrink at introweb dot nl
+ * @author Josh Peck <jmp at joshpeck dot org>
+ * @copyright 2003-2005 The PHP Group
+ * @license http://www.opensource.org/licenses/bsd-license.php
+ * @param string $ip An IPv6 address
+ * @return string The uncompressed IPv6 address
+ */
+ public static function uncompress($ip)
+ {
+ $c1 = -1;
+ $c2 = -1;
+ if (substr_count($ip, '::') === 1)
+ {
+ list($ip1, $ip2) = explode('::', $ip);
+ if ($ip1 === '')
+ {
+ $c1 = -1;
+ }
+ else
+ {
+ $c1 = substr_count($ip1, ':');
+ }
+ if ($ip2 === '')
+ {
+ $c2 = -1;
+ }
+ else
+ {
+ $c2 = substr_count($ip2, ':');
+ }
+ if (strpos($ip2, '.') !== false)
+ {
+ $c2++;
+ }
+ // ::
+ if ($c1 === -1 && $c2 === -1)
+ {
+ $ip = '0:0:0:0:0:0:0:0';
+ }
+ // ::xxx
+ else if ($c1 === -1)
+ {
+ $fill = str_repeat('0:', 7 - $c2);
+ $ip = str_replace('::', $fill, $ip);
+ }
+ // xxx::
+ else if ($c2 === -1)
+ {
+ $fill = str_repeat(':0', 7 - $c1);
+ $ip = str_replace('::', $fill, $ip);
+ }
+ // xxx::xxx
+ else
+ {
+ $fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
+ $ip = str_replace('::', $fill, $ip);
+ }
+ }
+ return $ip;
+ }
+
+ /**
+ * Compresses an IPv6 address
+ *
+ * RFC 4291 allows you to compress concecutive zero pieces in an address to
+ * '::'. This method expects a valid IPv6 address and compresses consecutive
+ * zero pieces to '::'.
+ *
+ * Example: FF01:0:0:0:0:0:0:101 -> FF01::101
+ * 0:0:0:0:0:0:0:1 -> ::1
+ *
+ * @see uncompress()
+ * @param string $ip An IPv6 address
+ * @return string The compressed IPv6 address
+ */
+ public static function compress($ip)
+ {
+ // Prepare the IP to be compressed
+ $ip = self::uncompress($ip);
+ $ip_parts = self::split_v6_v4($ip);
+
+ // Replace all leading zeros
+ $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
+
+ // Find bunches of zeros
+ if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE))
+ {
+ $max = 0;
+ $pos = null;
+ foreach ($matches[0] as $match)
+ {
+ if (strlen($match[0]) > $max)
+ {
+ $max = strlen($match[0]);
+ $pos = $match[1];
+ }
+ }
+
+ $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
+ }
+
+ if ($ip_parts[1] !== '')
+ {
+ return implode(':', $ip_parts);
+ }
+
+ return $ip_parts[0];
+ }
+
+ /**
+ * Splits an IPv6 address into the IPv6 and IPv4 representation parts
+ *
+ * RFC 4291 allows you to represent the last two parts of an IPv6 address
+ * using the standard IPv4 representation
+ *
+ * Example: 0:0:0:0:0:0:13.1.68.3
+ * 0:0:0:0:0:FFFF:129.144.52.38
+ *
+ * @param string $ip An IPv6 address
+ * @return array [0] contains the IPv6 represented part, and [1] the IPv4 represented part
+ */
+ private static function split_v6_v4($ip)
+ {
+ if (strpos($ip, '.') !== false)
+ {
+ $pos = strrpos($ip, ':');
+ $ipv6_part = substr($ip, 0, $pos);
+ $ipv4_part = substr($ip, $pos + 1);
+ return array($ipv6_part, $ipv4_part);
+ }
+
+ return array($ip, '');
+ }
+
+ /**
+ * Checks an IPv6 address
+ *
+ * Checks if the given IP is a valid IPv6 address
+ *
+ * @param string $ip An IPv6 address
+ * @return bool true if $ip is a valid IPv6 address
+ */
+ public static function check_ipv6($ip)
+ {
+ $ip = self::uncompress($ip);
+ list($ipv6, $ipv4) = self::split_v6_v4($ip);
+ $ipv6 = explode(':', $ipv6);
+ $ipv4 = explode('.', $ipv4);
+ if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4)
+ {
+ foreach ($ipv6 as $ipv6_part)
+ {
+ // The section can't be empty
+ if ($ipv6_part === '')
+ return false;
+
+ // Nor can it be over four characters
+ if (strlen($ipv6_part) > 4)
+ return false;
+
+ // Remove leading zeros (this is safe because of the above)
+ $ipv6_part = ltrim($ipv6_part, '0');
+ if ($ipv6_part === '')
+ $ipv6_part = '0';
+
+ // Check the value is valid
+ $value = hexdec($ipv6_part);
+ if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF)
+ return false;
+ }
+ if (count($ipv4) === 4)
+ {
+ foreach ($ipv4 as $ipv4_part)
+ {
+ $value = (int) $ipv4_part;
+ if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF)
+ return false;
+ }
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Checks if the given IP is a valid IPv6 address
+ *
+ * @codeCoverageIgnore
+ * @deprecated Use {@see SimplePie_Net_IPv6::check_ipv6()} instead
+ * @see check_ipv6
+ * @param string $ip An IPv6 address
+ * @return bool true if $ip is a valid IPv6 address
+ */
+ public static function checkIPv6($ip)
+ {
+ return self::check_ipv6($ip);
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Parse/Date.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Parse/Date.php
new file mode 100644
index 0000000..cf57437
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Parse/Date.php
@@ -0,0 +1,1025 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+
+/**
+ * Date Parser
+ *
+ * @package SimplePie
+ * @subpackage Parsing
+ */
+class SimplePie_Parse_Date
+{
+ /**
+ * Input data
+ *
+ * @access protected
+ * @var string
+ */
+ var $date;
+
+ /**
+ * List of days, calendar day name => ordinal day number in the week
+ *
+ * @access protected
+ * @var array
+ */
+ var $day = array(
+ // English
+ 'mon' => 1,
+ 'monday' => 1,
+ 'tue' => 2,
+ 'tuesday' => 2,
+ 'wed' => 3,
+ 'wednesday' => 3,
+ 'thu' => 4,
+ 'thursday' => 4,
+ 'fri' => 5,
+ 'friday' => 5,
+ 'sat' => 6,
+ 'saturday' => 6,
+ 'sun' => 7,
+ 'sunday' => 7,
+ // Dutch
+ 'maandag' => 1,
+ 'dinsdag' => 2,
+ 'woensdag' => 3,
+ 'donderdag' => 4,
+ 'vrijdag' => 5,
+ 'zaterdag' => 6,
+ 'zondag' => 7,
+ // French
+ 'lundi' => 1,
+ 'mardi' => 2,
+ 'mercredi' => 3,
+ 'jeudi' => 4,
+ 'vendredi' => 5,
+ 'samedi' => 6,
+ 'dimanche' => 7,
+ // German
+ 'montag' => 1,
+ 'mo' => 1,
+ 'dienstag' => 2,
+ 'di' => 2,
+ 'mittwoch' => 3,
+ 'mi' => 3,
+ 'donnerstag' => 4,
+ 'do' => 4,
+ 'freitag' => 5,
+ 'fr' => 5,
+ 'samstag' => 6,
+ 'sa' => 6,
+ 'sonnabend' => 6,
+ // AFAIK no short form for sonnabend
+ 'so' => 7,
+ 'sonntag' => 7,
+ // Italian
+ 'lunedì' => 1,
+ 'martedì' => 2,
+ 'mercoledì' => 3,
+ 'giovedì' => 4,
+ 'venerdì' => 5,
+ 'sabato' => 6,
+ 'domenica' => 7,
+ // Spanish
+ 'lunes' => 1,
+ 'martes' => 2,
+ 'miércoles' => 3,
+ 'jueves' => 4,
+ 'viernes' => 5,
+ 'sábado' => 6,
+ 'domingo' => 7,
+ // Finnish
+ 'maanantai' => 1,
+ 'tiistai' => 2,
+ 'keskiviikko' => 3,
+ 'torstai' => 4,
+ 'perjantai' => 5,
+ 'lauantai' => 6,
+ 'sunnuntai' => 7,
+ // Hungarian
+ 'hétfő' => 1,
+ 'kedd' => 2,
+ 'szerda' => 3,
+ 'csütörtok' => 4,
+ 'péntek' => 5,
+ 'szombat' => 6,
+ 'vasárnap' => 7,
+ // Greek
+ 'Δευ' => 1,
+ 'ΤÏι' => 2,
+ 'Τετ' => 3,
+ 'Πεμ' => 4,
+ 'ΠαÏ' => 5,
+ 'Σαβ' => 6,
+ 'ΚυÏ' => 7,
+ // Russian
+ 'Пн.' => 1,
+ 'Ð’Ñ‚.' => 2,
+ 'Ср.' => 3,
+ 'Чт.' => 4,
+ 'Пт.' => 5,
+ 'Сб.' => 6,
+ 'Ð’Ñ.' => 7,
+ );
+
+ /**
+ * List of months, calendar month name => calendar month number
+ *
+ * @access protected
+ * @var array
+ */
+ var $month = array(
+ // English
+ 'jan' => 1,
+ 'january' => 1,
+ 'feb' => 2,
+ 'february' => 2,
+ 'mar' => 3,
+ 'march' => 3,
+ 'apr' => 4,
+ 'april' => 4,
+ 'may' => 5,
+ // No long form of May
+ 'jun' => 6,
+ 'june' => 6,
+ 'jul' => 7,
+ 'july' => 7,
+ 'aug' => 8,
+ 'august' => 8,
+ 'sep' => 9,
+ 'september' => 9,
+ 'oct' => 10,
+ 'october' => 10,
+ 'nov' => 11,
+ 'november' => 11,
+ 'dec' => 12,
+ 'december' => 12,
+ // Dutch
+ 'januari' => 1,
+ 'februari' => 2,
+ 'maart' => 3,
+ 'april' => 4,
+ 'mei' => 5,
+ 'juni' => 6,
+ 'juli' => 7,
+ 'augustus' => 8,
+ 'september' => 9,
+ 'oktober' => 10,
+ 'november' => 11,
+ 'december' => 12,
+ // French
+ 'janvier' => 1,
+ 'février' => 2,
+ 'mars' => 3,
+ 'avril' => 4,
+ 'mai' => 5,
+ 'juin' => 6,
+ 'juillet' => 7,
+ 'août' => 8,
+ 'septembre' => 9,
+ 'octobre' => 10,
+ 'novembre' => 11,
+ 'décembre' => 12,
+ // German
+ 'januar' => 1,
+ 'jan' => 1,
+ 'februar' => 2,
+ 'feb' => 2,
+ 'märz' => 3,
+ 'mär' => 3,
+ 'april' => 4,
+ 'apr' => 4,
+ 'mai' => 5, // no short form for may
+ 'juni' => 6,
+ 'jun' => 6,
+ 'juli' => 7,
+ 'jul' => 7,
+ 'august' => 8,
+ 'aug' => 8,
+ 'september' => 9,
+ 'sep' => 9,
+ 'oktober' => 10,
+ 'okt' => 10,
+ 'november' => 11,
+ 'nov' => 11,
+ 'dezember' => 12,
+ 'dez' => 12,
+ // Italian
+ 'gennaio' => 1,
+ 'febbraio' => 2,
+ 'marzo' => 3,
+ 'aprile' => 4,
+ 'maggio' => 5,
+ 'giugno' => 6,
+ 'luglio' => 7,
+ 'agosto' => 8,
+ 'settembre' => 9,
+ 'ottobre' => 10,
+ 'novembre' => 11,
+ 'dicembre' => 12,
+ // Spanish
+ 'enero' => 1,
+ 'febrero' => 2,
+ 'marzo' => 3,
+ 'abril' => 4,
+ 'mayo' => 5,
+ 'junio' => 6,
+ 'julio' => 7,
+ 'agosto' => 8,
+ 'septiembre' => 9,
+ 'setiembre' => 9,
+ 'octubre' => 10,
+ 'noviembre' => 11,
+ 'diciembre' => 12,
+ // Finnish
+ 'tammikuu' => 1,
+ 'helmikuu' => 2,
+ 'maaliskuu' => 3,
+ 'huhtikuu' => 4,
+ 'toukokuu' => 5,
+ 'kesäkuu' => 6,
+ 'heinäkuu' => 7,
+ 'elokuu' => 8,
+ 'suuskuu' => 9,
+ 'lokakuu' => 10,
+ 'marras' => 11,
+ 'joulukuu' => 12,
+ // Hungarian
+ 'január' => 1,
+ 'február' => 2,
+ 'március' => 3,
+ 'április' => 4,
+ 'május' => 5,
+ 'június' => 6,
+ 'július' => 7,
+ 'augusztus' => 8,
+ 'szeptember' => 9,
+ 'október' => 10,
+ 'november' => 11,
+ 'december' => 12,
+ // Greek
+ 'Ιαν' => 1,
+ 'Φεβ' => 2,
+ 'Μάώ' => 3,
+ 'Μαώ' => 3,
+ 'ΑπÏ' => 4,
+ 'Μάι' => 5,
+ 'Μαϊ' => 5,
+ 'Μαι' => 5,
+ 'ΙοÏν' => 6,
+ 'Ιον' => 6,
+ 'ΙοÏλ' => 7,
+ 'Ιολ' => 7,
+ 'ΑÏγ' => 8,
+ 'Αυγ' => 8,
+ 'Σεπ' => 9,
+ 'Οκτ' => 10,
+ 'Îοέ' => 11,
+ 'Δεκ' => 12,
+ // Russian
+ 'Янв' => 1,
+ 'ÑнварÑ' => 1,
+ 'Фев' => 2,
+ 'февралÑ' => 2,
+ 'Мар' => 3,
+ 'марта' => 3,
+ 'Ðпр' => 4,
+ 'апрелÑ' => 4,
+ 'Май' => 5,
+ 'маÑ' => 5,
+ 'Июн' => 6,
+ 'июнÑ' => 6,
+ 'Июл' => 7,
+ 'июлÑ' => 7,
+ 'Ðвг' => 8,
+ 'авгуÑта' => 8,
+ 'Сен' => 9,
+ 'ÑентÑбрÑ' => 9,
+ 'Окт' => 10,
+ 'октÑбрÑ' => 10,
+ 'ÐоÑ' => 11,
+ 'ноÑбрÑ' => 11,
+ 'Дек' => 12,
+ 'декабрÑ' => 12,
+
+ );
+
+ /**
+ * List of timezones, abbreviation => offset from UTC
+ *
+ * @access protected
+ * @var array
+ */
+ var $timezone = array(
+ 'ACDT' => 37800,
+ 'ACIT' => 28800,
+ 'ACST' => 34200,
+ 'ACT' => -18000,
+ 'ACWDT' => 35100,
+ 'ACWST' => 31500,
+ 'AEDT' => 39600,
+ 'AEST' => 36000,
+ 'AFT' => 16200,
+ 'AKDT' => -28800,
+ 'AKST' => -32400,
+ 'AMDT' => 18000,
+ 'AMT' => -14400,
+ 'ANAST' => 46800,
+ 'ANAT' => 43200,
+ 'ART' => -10800,
+ 'AZOST' => -3600,
+ 'AZST' => 18000,
+ 'AZT' => 14400,
+ 'BIOT' => 21600,
+ 'BIT' => -43200,
+ 'BOT' => -14400,
+ 'BRST' => -7200,
+ 'BRT' => -10800,
+ 'BST' => 3600,
+ 'BTT' => 21600,
+ 'CAST' => 18000,
+ 'CAT' => 7200,
+ 'CCT' => 23400,
+ 'CDT' => -18000,
+ 'CEDT' => 7200,
+ 'CEST' => 7200,
+ 'CET' => 3600,
+ 'CGST' => -7200,
+ 'CGT' => -10800,
+ 'CHADT' => 49500,
+ 'CHAST' => 45900,
+ 'CIST' => -28800,
+ 'CKT' => -36000,
+ 'CLDT' => -10800,
+ 'CLST' => -14400,
+ 'COT' => -18000,
+ 'CST' => -21600,
+ 'CVT' => -3600,
+ 'CXT' => 25200,
+ 'DAVT' => 25200,
+ 'DTAT' => 36000,
+ 'EADT' => -18000,
+ 'EAST' => -21600,
+ 'EAT' => 10800,
+ 'ECT' => -18000,
+ 'EDT' => -14400,
+ 'EEST' => 10800,
+ 'EET' => 7200,
+ 'EGT' => -3600,
+ 'EKST' => 21600,
+ 'EST' => -18000,
+ 'FJT' => 43200,
+ 'FKDT' => -10800,
+ 'FKST' => -14400,
+ 'FNT' => -7200,
+ 'GALT' => -21600,
+ 'GEDT' => 14400,
+ 'GEST' => 10800,
+ 'GFT' => -10800,
+ 'GILT' => 43200,
+ 'GIT' => -32400,
+ 'GST' => 14400,
+ 'GST' => -7200,
+ 'GYT' => -14400,
+ 'HAA' => -10800,
+ 'HAC' => -18000,
+ 'HADT' => -32400,
+ 'HAE' => -14400,
+ 'HAP' => -25200,
+ 'HAR' => -21600,
+ 'HAST' => -36000,
+ 'HAT' => -9000,
+ 'HAY' => -28800,
+ 'HKST' => 28800,
+ 'HMT' => 18000,
+ 'HNA' => -14400,
+ 'HNC' => -21600,
+ 'HNE' => -18000,
+ 'HNP' => -28800,
+ 'HNR' => -25200,
+ 'HNT' => -12600,
+ 'HNY' => -32400,
+ 'IRDT' => 16200,
+ 'IRKST' => 32400,
+ 'IRKT' => 28800,
+ 'IRST' => 12600,
+ 'JFDT' => -10800,
+ 'JFST' => -14400,
+ 'JST' => 32400,
+ 'KGST' => 21600,
+ 'KGT' => 18000,
+ 'KOST' => 39600,
+ 'KOVST' => 28800,
+ 'KOVT' => 25200,
+ 'KRAST' => 28800,
+ 'KRAT' => 25200,
+ 'KST' => 32400,
+ 'LHDT' => 39600,
+ 'LHST' => 37800,
+ 'LINT' => 50400,
+ 'LKT' => 21600,
+ 'MAGST' => 43200,
+ 'MAGT' => 39600,
+ 'MAWT' => 21600,
+ 'MDT' => -21600,
+ 'MESZ' => 7200,
+ 'MEZ' => 3600,
+ 'MHT' => 43200,
+ 'MIT' => -34200,
+ 'MNST' => 32400,
+ 'MSDT' => 14400,
+ 'MSST' => 10800,
+ 'MST' => -25200,
+ 'MUT' => 14400,
+ 'MVT' => 18000,
+ 'MYT' => 28800,
+ 'NCT' => 39600,
+ 'NDT' => -9000,
+ 'NFT' => 41400,
+ 'NMIT' => 36000,
+ 'NOVST' => 25200,
+ 'NOVT' => 21600,
+ 'NPT' => 20700,
+ 'NRT' => 43200,
+ 'NST' => -12600,
+ 'NUT' => -39600,
+ 'NZDT' => 46800,
+ 'NZST' => 43200,
+ 'OMSST' => 25200,
+ 'OMST' => 21600,
+ 'PDT' => -25200,
+ 'PET' => -18000,
+ 'PETST' => 46800,
+ 'PETT' => 43200,
+ 'PGT' => 36000,
+ 'PHOT' => 46800,
+ 'PHT' => 28800,
+ 'PKT' => 18000,
+ 'PMDT' => -7200,
+ 'PMST' => -10800,
+ 'PONT' => 39600,
+ 'PST' => -28800,
+ 'PWT' => 32400,
+ 'PYST' => -10800,
+ 'PYT' => -14400,
+ 'RET' => 14400,
+ 'ROTT' => -10800,
+ 'SAMST' => 18000,
+ 'SAMT' => 14400,
+ 'SAST' => 7200,
+ 'SBT' => 39600,
+ 'SCDT' => 46800,
+ 'SCST' => 43200,
+ 'SCT' => 14400,
+ 'SEST' => 3600,
+ 'SGT' => 28800,
+ 'SIT' => 28800,
+ 'SRT' => -10800,
+ 'SST' => -39600,
+ 'SYST' => 10800,
+ 'SYT' => 7200,
+ 'TFT' => 18000,
+ 'THAT' => -36000,
+ 'TJT' => 18000,
+ 'TKT' => -36000,
+ 'TMT' => 18000,
+ 'TOT' => 46800,
+ 'TPT' => 32400,
+ 'TRUT' => 36000,
+ 'TVT' => 43200,
+ 'TWT' => 28800,
+ 'UYST' => -7200,
+ 'UYT' => -10800,
+ 'UZT' => 18000,
+ 'VET' => -14400,
+ 'VLAST' => 39600,
+ 'VLAT' => 36000,
+ 'VOST' => 21600,
+ 'VUT' => 39600,
+ 'WAST' => 7200,
+ 'WAT' => 3600,
+ 'WDT' => 32400,
+ 'WEST' => 3600,
+ 'WFT' => 43200,
+ 'WIB' => 25200,
+ 'WIT' => 32400,
+ 'WITA' => 28800,
+ 'WKST' => 18000,
+ 'WST' => 28800,
+ 'YAKST' => 36000,
+ 'YAKT' => 32400,
+ 'YAPT' => 36000,
+ 'YEKST' => 21600,
+ 'YEKT' => 18000,
+ );
+
+ /**
+ * Cached PCRE for SimplePie_Parse_Date::$day
+ *
+ * @access protected
+ * @var string
+ */
+ var $day_pcre;
+
+ /**
+ * Cached PCRE for SimplePie_Parse_Date::$month
+ *
+ * @access protected
+ * @var string
+ */
+ var $month_pcre;
+
+ /**
+ * Array of user-added callback methods
+ *
+ * @access private
+ * @var array
+ */
+ var $built_in = array();
+
+ /**
+ * Array of user-added callback methods
+ *
+ * @access private
+ * @var array
+ */
+ var $user = array();
+
+ /**
+ * Create new SimplePie_Parse_Date object, and set self::day_pcre,
+ * self::month_pcre, and self::built_in
+ *
+ * @access private
+ */
+ public function __construct()
+ {
+ $this->day_pcre = '(' . implode('|', array_keys($this->day)) . ')';
+ $this->month_pcre = '(' . implode('|', array_keys($this->month)) . ')';
+
+ static $cache;
+ if (!isset($cache[get_class($this)]))
+ {
+ $all_methods = get_class_methods($this);
+
+ foreach ($all_methods as $method)
+ {
+ if (strtolower(substr($method, 0, 5)) === 'date_')
+ {
+ $cache[get_class($this)][] = $method;
+ }
+ }
+ }
+
+ foreach ($cache[get_class($this)] as $method)
+ {
+ $this->built_in[] = $method;
+ }
+ }
+
+ /**
+ * Get the object
+ *
+ * @access public
+ */
+ public static function get()
+ {
+ static $object;
+ if (!$object)
+ {
+ $object = new SimplePie_Parse_Date;
+ }
+ return $object;
+ }
+
+ /**
+ * Parse a date
+ *
+ * @final
+ * @access public
+ * @param string $date Date to parse
+ * @return int Timestamp corresponding to date string, or false on failure
+ */
+ public function parse($date)
+ {
+ foreach ($this->user as $method)
+ {
+ if (($returned = call_user_func($method, $date)) !== false)
+ {
+ return $returned;
+ }
+ }
+
+ foreach ($this->built_in as $method)
+ {
+ if (($returned = call_user_func(array($this, $method), $date)) !== false)
+ {
+ return $returned;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Add a callback method to parse a date
+ *
+ * @final
+ * @access public
+ * @param callback $callback
+ */
+ public function add_callback($callback)
+ {
+ if (is_callable($callback))
+ {
+ $this->user[] = $callback;
+ }
+ else
+ {
+ trigger_error('User-supplied function must be a valid callback', E_USER_WARNING);
+ }
+ }
+
+ /**
+ * Parse a superset of W3C-DTF (allows hyphens and colons to be omitted, as
+ * well as allowing any of upper or lower case "T", horizontal tabs, or
+ * spaces to be used as the time separator (including more than one))
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ public function date_w3cdtf($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $year = '([0-9]{4})';
+ $month = $day = $hour = $minute = $second = '([0-9]{2})';
+ $decimal = '([0-9]*)';
+ $zone = '(?:(Z)|([+\-])([0-9]{1,2}):?([0-9]{1,2}))';
+ $pcre = '/^' . $year . '(?:-?' . $month . '(?:-?' . $day . '(?:[Tt\x09\x20]+' . $hour . '(?::?' . $minute . '(?::?' . $second . '(?:.' . $decimal . ')?)?)?' . $zone . ')?)?)?$/';
+ }
+ if (preg_match($pcre, $date, $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Year
+ 2: Month
+ 3: Day
+ 4: Hour
+ 5: Minute
+ 6: Second
+ 7: Decimal fraction of a second
+ 8: Zulu
+ 9: Timezone ±
+ 10: Timezone hours
+ 11: Timezone minutes
+ */
+
+ // Fill in empty matches
+ for ($i = count($match); $i <= 3; $i++)
+ {
+ $match[$i] = '1';
+ }
+
+ for ($i = count($match); $i <= 7; $i++)
+ {
+ $match[$i] = '0';
+ }
+
+ // Numeric timezone
+ if (isset($match[9]) && $match[9] !== '')
+ {
+ $timezone = $match[10] * 3600;
+ $timezone += $match[11] * 60;
+ if ($match[9] === '-')
+ {
+ $timezone = 0 - $timezone;
+ }
+ }
+ else
+ {
+ $timezone = 0;
+ }
+
+ // Convert the number of seconds to an integer, taking decimals into account
+ $second = round((int)$match[6] + (int)$match[7] / (10 ** strlen($match[7])));
+
+ return gmmktime($match[4], $match[5], $second, $match[2], $match[3], $match[1]) - $timezone;
+ }
+
+ return false;
+ }
+
+ /**
+ * Remove RFC822 comments
+ *
+ * @access protected
+ * @param string $data Data to strip comments from
+ * @return string Comment stripped string
+ */
+ public function remove_rfc2822_comments($string)
+ {
+ $string = (string) $string;
+ $position = 0;
+ $length = strlen($string);
+ $depth = 0;
+
+ $output = '';
+
+ while ($position < $length && ($pos = strpos($string, '(', $position)) !== false)
+ {
+ $output .= substr($string, $position, $pos - $position);
+ $position = $pos + 1;
+ if ($pos === 0 || $string[$pos - 1] !== '\\')
+ {
+ $depth++;
+ while ($depth && $position < $length)
+ {
+ $position += strcspn($string, '()', $position);
+ if ($string[$position - 1] === '\\')
+ {
+ $position++;
+ continue;
+ }
+ elseif (isset($string[$position]))
+ {
+ switch ($string[$position])
+ {
+ case '(':
+ $depth++;
+ break;
+
+ case ')':
+ $depth--;
+ break;
+ }
+ $position++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ $output .= '(';
+ }
+ }
+ $output .= substr($string, $position);
+
+ return $output;
+ }
+
+ /**
+ * Parse RFC2822's date format
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ public function date_rfc2822($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $wsp = '[\x09\x20]';
+ $fws = '(?:' . $wsp . '+|' . $wsp . '*(?:\x0D\x0A' . $wsp . '+)+)';
+ $optional_fws = $fws . '?';
+ $day_name = $this->day_pcre;
+ $month = $this->month_pcre;
+ $day = '([0-9]{1,2})';
+ $hour = $minute = $second = '([0-9]{2})';
+ $year = '([0-9]{2,4})';
+ $num_zone = '([+\-])([0-9]{2})([0-9]{2})';
+ $character_zone = '([A-Z]{1,5})';
+ $zone = '(?:' . $num_zone . '|' . $character_zone . ')';
+ $pcre = '/(?:' . $optional_fws . $day_name . $optional_fws . ',)?' . $optional_fws . $day . $fws . $month . $fws . $year . $fws . $hour . $optional_fws . ':' . $optional_fws . $minute . '(?:' . $optional_fws . ':' . $optional_fws . $second . ')?' . $fws . $zone . '/i';
+ }
+ if (preg_match($pcre, $this->remove_rfc2822_comments($date), $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Day name
+ 2: Day
+ 3: Month
+ 4: Year
+ 5: Hour
+ 6: Minute
+ 7: Second
+ 8: Timezone ±
+ 9: Timezone hours
+ 10: Timezone minutes
+ 11: Alphabetic timezone
+ */
+
+ // Find the month number
+ $month = $this->month[strtolower($match[3])];
+
+ // Numeric timezone
+ if ($match[8] !== '')
+ {
+ $timezone = $match[9] * 3600;
+ $timezone += $match[10] * 60;
+ if ($match[8] === '-')
+ {
+ $timezone = 0 - $timezone;
+ }
+ }
+ // Character timezone
+ elseif (isset($this->timezone[strtoupper($match[11])]))
+ {
+ $timezone = $this->timezone[strtoupper($match[11])];
+ }
+ // Assume everything else to be -0000
+ else
+ {
+ $timezone = 0;
+ }
+
+ // Deal with 2/3 digit years
+ if ($match[4] < 50)
+ {
+ $match[4] += 2000;
+ }
+ elseif ($match[4] < 1000)
+ {
+ $match[4] += 1900;
+ }
+
+ // Second is optional, if it is empty set it to zero
+ if ($match[7] !== '')
+ {
+ $second = $match[7];
+ }
+ else
+ {
+ $second = 0;
+ }
+
+ return gmmktime($match[5], $match[6], $second, $month, $match[2], $match[4]) - $timezone;
+ }
+
+ return false;
+ }
+
+ /**
+ * Parse RFC850's date format
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ public function date_rfc850($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $space = '[\x09\x20]+';
+ $day_name = $this->day_pcre;
+ $month = $this->month_pcre;
+ $day = '([0-9]{1,2})';
+ $year = $hour = $minute = $second = '([0-9]{2})';
+ $zone = '([A-Z]{1,5})';
+ $pcre = '/^' . $day_name . ',' . $space . $day . '-' . $month . '-' . $year . $space . $hour . ':' . $minute . ':' . $second . $space . $zone . '$/i';
+ }
+ if (preg_match($pcre, $date, $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Day name
+ 2: Day
+ 3: Month
+ 4: Year
+ 5: Hour
+ 6: Minute
+ 7: Second
+ 8: Timezone
+ */
+
+ // Month
+ $month = $this->month[strtolower($match[3])];
+
+ // Character timezone
+ if (isset($this->timezone[strtoupper($match[8])]))
+ {
+ $timezone = $this->timezone[strtoupper($match[8])];
+ }
+ // Assume everything else to be -0000
+ else
+ {
+ $timezone = 0;
+ }
+
+ // Deal with 2 digit year
+ if ($match[4] < 50)
+ {
+ $match[4] += 2000;
+ }
+ else
+ {
+ $match[4] += 1900;
+ }
+
+ return gmmktime($match[5], $match[6], $match[7], $month, $match[2], $match[4]) - $timezone;
+ }
+
+ return false;
+ }
+
+ /**
+ * Parse C99's asctime()'s date format
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ public function date_asctime($date)
+ {
+ static $pcre;
+ if (!$pcre)
+ {
+ $space = '[\x09\x20]+';
+ $wday_name = $this->day_pcre;
+ $mon_name = $this->month_pcre;
+ $day = '([0-9]{1,2})';
+ $hour = $sec = $min = '([0-9]{2})';
+ $year = '([0-9]{4})';
+ $terminator = '\x0A?\x00?';
+ $pcre = '/^' . $wday_name . $space . $mon_name . $space . $day . $space . $hour . ':' . $min . ':' . $sec . $space . $year . $terminator . '$/i';
+ }
+ if (preg_match($pcre, $date, $match))
+ {
+ /*
+ Capturing subpatterns:
+ 1: Day name
+ 2: Month
+ 3: Day
+ 4: Hour
+ 5: Minute
+ 6: Second
+ 7: Year
+ */
+
+ $month = $this->month[strtolower($match[2])];
+ return gmmktime($match[4], $match[5], $match[6], $month, $match[3], $match[7]);
+ }
+
+ return false;
+ }
+
+ /**
+ * Parse dates using strtotime()
+ *
+ * @access protected
+ * @return int Timestamp
+ */
+ public function date_strtotime($date)
+ {
+ $strtotime = strtotime($date);
+ if ($strtotime === -1 || $strtotime === false)
+ {
+ return false;
+ }
+
+ return $strtotime;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Parser.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Parser.php
new file mode 100644
index 0000000..4efdf41
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Parser.php
@@ -0,0 +1,661 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Parses XML into something sane
+ *
+ *
+ * This class can be overloaded with {@see SimplePie::set_parser_class()}
+ *
+ * @package SimplePie
+ * @subpackage Parsing
+ */
+class SimplePie_Parser
+{
+ var $error_code;
+ var $error_string;
+ var $current_line;
+ var $current_column;
+ var $current_byte;
+ var $separator = ' ';
+ var $namespace = array('');
+ var $element = array('');
+ var $xml_base = array('');
+ var $xml_base_explicit = array(false);
+ var $xml_lang = array('');
+ var $data = array();
+ var $datas = array(array());
+ var $current_xhtml_construct = -1;
+ var $encoding;
+ protected $registry;
+
+ public function set_registry(SimplePie_Registry $registry)
+ {
+ $this->registry = $registry;
+ }
+
+ public function parse(&$data, $encoding, $url = '')
+ {
+ if (class_exists('DOMXpath') && function_exists('Mf2\parse')) {
+ $doc = new DOMDocument();
+ @$doc->loadHTML($data);
+ $xpath = new DOMXpath($doc);
+ // Check for both h-feed and h-entry, as both a feed with no entries
+ // and a list of entries without an h-feed wrapper are both valid.
+ $query = '//*[contains(concat(" ", @class, " "), " h-feed ") or '.
+ 'contains(concat(" ", @class, " "), " h-entry ")]';
+ $result = $xpath->query($query);
+ if ($result->length !== 0) {
+ return $this->parse_microformats($data, $url);
+ }
+ }
+
+ // Use UTF-8 if we get passed US-ASCII, as every US-ASCII character is a UTF-8 character
+ if (strtoupper($encoding) === 'US-ASCII')
+ {
+ $this->encoding = 'UTF-8';
+ }
+ else
+ {
+ $this->encoding = $encoding;
+ }
+
+ // Strip BOM:
+ // UTF-32 Big Endian BOM
+ if (substr($data, 0, 4) === "\x00\x00\xFE\xFF")
+ {
+ $data = substr($data, 4);
+ }
+ // UTF-32 Little Endian BOM
+ elseif (substr($data, 0, 4) === "\xFF\xFE\x00\x00")
+ {
+ $data = substr($data, 4);
+ }
+ // UTF-16 Big Endian BOM
+ elseif (substr($data, 0, 2) === "\xFE\xFF")
+ {
+ $data = substr($data, 2);
+ }
+ // UTF-16 Little Endian BOM
+ elseif (substr($data, 0, 2) === "\xFF\xFE")
+ {
+ $data = substr($data, 2);
+ }
+ // UTF-8 BOM
+ elseif (substr($data, 0, 3) === "\xEF\xBB\xBF")
+ {
+ $data = substr($data, 3);
+ }
+
+ if (substr($data, 0, 5) === '<?xml' && strspn(substr($data, 5, 1), "\x09\x0A\x0D\x20") && ($pos = strpos($data, '?>')) !== false)
+ {
+ $declaration = $this->registry->create('XML_Declaration_Parser', array(substr($data, 5, $pos - 5)));
+ if ($declaration->parse())
+ {
+ $data = substr($data, $pos + 2);
+ $data = '<?xml version="' . $declaration->version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' ."\n". $this->declare_html_entities() . $data;
+ }
+ else
+ {
+ $this->error_string = 'SimplePie bug! Please report this!';
+ return false;
+ }
+ }
+
+ $return = true;
+
+ static $xml_is_sane = null;
+ if ($xml_is_sane === null)
+ {
+ $parser_check = xml_parser_create();
+ xml_parse_into_struct($parser_check, '<foo>&amp;</foo>', $values);
+ xml_parser_free($parser_check);
+ $xml_is_sane = isset($values[0]['value']);
+ }
+
+ // Create the parser
+ if ($xml_is_sane)
+ {
+ $xml = xml_parser_create_ns($this->encoding, $this->separator);
+ xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1);
+ xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0);
+ xml_set_object($xml, $this);
+ xml_set_character_data_handler($xml, 'cdata');
+ xml_set_element_handler($xml, 'tag_open', 'tag_close');
+
+ // Parse!
+ if (!xml_parse($xml, $data, true))
+ {
+ $this->error_code = xml_get_error_code($xml);
+ $this->error_string = xml_error_string($this->error_code);
+ $return = false;
+ }
+ $this->current_line = xml_get_current_line_number($xml);
+ $this->current_column = xml_get_current_column_number($xml);
+ $this->current_byte = xml_get_current_byte_index($xml);
+ xml_parser_free($xml);
+ return $return;
+ }
+
+ libxml_clear_errors();
+ $xml = new XMLReader();
+ $xml->xml($data);
+ while (@$xml->read())
+ {
+ switch ($xml->nodeType)
+ {
+
+ case constant('XMLReader::END_ELEMENT'):
+ if ($xml->namespaceURI !== '')
+ {
+ $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
+ }
+ else
+ {
+ $tagName = $xml->localName;
+ }
+ $this->tag_close(null, $tagName);
+ break;
+ case constant('XMLReader::ELEMENT'):
+ $empty = $xml->isEmptyElement;
+ if ($xml->namespaceURI !== '')
+ {
+ $tagName = $xml->namespaceURI . $this->separator . $xml->localName;
+ }
+ else
+ {
+ $tagName = $xml->localName;
+ }
+ $attributes = array();
+ while ($xml->moveToNextAttribute())
+ {
+ if ($xml->namespaceURI !== '')
+ {
+ $attrName = $xml->namespaceURI . $this->separator . $xml->localName;
+ }
+ else
+ {
+ $attrName = $xml->localName;
+ }
+ $attributes[$attrName] = $xml->value;
+ }
+ $this->tag_open(null, $tagName, $attributes);
+ if ($empty)
+ {
+ $this->tag_close(null, $tagName);
+ }
+ break;
+ case constant('XMLReader::TEXT'):
+
+ case constant('XMLReader::CDATA'):
+ $this->cdata(null, $xml->value);
+ break;
+ }
+ }
+ if ($error = libxml_get_last_error())
+ {
+ $this->error_code = $error->code;
+ $this->error_string = $error->message;
+ $this->current_line = $error->line;
+ $this->current_column = $error->column;
+ return false;
+ }
+
+ return true;
+ }
+
+ public function get_error_code()
+ {
+ return $this->error_code;
+ }
+
+ public function get_error_string()
+ {
+ return $this->error_string;
+ }
+
+ public function get_current_line()
+ {
+ return $this->current_line;
+ }
+
+ public function get_current_column()
+ {
+ return $this->current_column;
+ }
+
+ public function get_current_byte()
+ {
+ return $this->current_byte;
+ }
+
+ public function get_data()
+ {
+ return $this->data;
+ }
+
+ public function tag_open($parser, $tag, $attributes)
+ {
+ list($this->namespace[], $this->element[]) = $this->split_ns($tag);
+
+ $attribs = array();
+ foreach ($attributes as $name => $value)
+ {
+ list($attrib_namespace, $attribute) = $this->split_ns($name);
+ $attribs[$attrib_namespace][$attribute] = $value;
+ }
+
+ if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['base']))
+ {
+ $base = $this->registry->call('Misc', 'absolutize_url', array($attribs[SIMPLEPIE_NAMESPACE_XML]['base'], end($this->xml_base)));
+ if ($base !== false)
+ {
+ $this->xml_base[] = $base;
+ $this->xml_base_explicit[] = true;
+ }
+ }
+ else
+ {
+ $this->xml_base[] = end($this->xml_base);
+ $this->xml_base_explicit[] = end($this->xml_base_explicit);
+ }
+
+ if (isset($attribs[SIMPLEPIE_NAMESPACE_XML]['lang']))
+ {
+ $this->xml_lang[] = $attribs[SIMPLEPIE_NAMESPACE_XML]['lang'];
+ }
+ else
+ {
+ $this->xml_lang[] = end($this->xml_lang);
+ }
+
+ if ($this->current_xhtml_construct >= 0)
+ {
+ $this->current_xhtml_construct++;
+ if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML)
+ {
+ $this->data['data'] .= '<' . end($this->element);
+ if (isset($attribs['']))
+ {
+ foreach ($attribs[''] as $name => $value)
+ {
+ $this->data['data'] .= ' ' . $name . '="' . htmlspecialchars($value, ENT_COMPAT, $this->encoding) . '"';
+ }
+ }
+ $this->data['data'] .= '>';
+ }
+ }
+ else
+ {
+ $this->datas[] =& $this->data;
+ $this->data =& $this->data['child'][end($this->namespace)][end($this->element)][];
+ $this->data = array('data' => '', 'attribs' => $attribs, 'xml_base' => end($this->xml_base), 'xml_base_explicit' => end($this->xml_base_explicit), 'xml_lang' => end($this->xml_lang));
+ if ((end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_03 && in_array(end($this->element), array('title', 'tagline', 'copyright', 'info', 'summary', 'content')) && isset($attribs['']['mode']) && $attribs['']['mode'] === 'xml')
+ || (end($this->namespace) === SIMPLEPIE_NAMESPACE_ATOM_10 && in_array(end($this->element), array('rights', 'subtitle', 'summary', 'info', 'title', 'content')) && isset($attribs['']['type']) && $attribs['']['type'] === 'xhtml')
+ || (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_20 && in_array(end($this->element), array('title')))
+ || (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_090 && in_array(end($this->element), array('title')))
+ || (end($this->namespace) === SIMPLEPIE_NAMESPACE_RSS_10 && in_array(end($this->element), array('title'))))
+ {
+ $this->current_xhtml_construct = 0;
+ }
+ }
+ }
+
+ public function cdata($parser, $cdata)
+ {
+ if ($this->current_xhtml_construct >= 0)
+ {
+ $this->data['data'] .= htmlspecialchars($cdata, ENT_QUOTES, $this->encoding);
+ }
+ else
+ {
+ $this->data['data'] .= $cdata;
+ }
+ }
+
+ public function tag_close($parser, $tag)
+ {
+ if ($this->current_xhtml_construct >= 0)
+ {
+ $this->current_xhtml_construct--;
+ if (end($this->namespace) === SIMPLEPIE_NAMESPACE_XHTML && !in_array(end($this->element), array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'img', 'input', 'isindex', 'link', 'meta', 'param')))
+ {
+ $this->data['data'] .= '</' . end($this->element) . '>';
+ }
+ }
+ if ($this->current_xhtml_construct === -1)
+ {
+ $this->data =& $this->datas[count($this->datas) - 1];
+ array_pop($this->datas);
+ }
+
+ array_pop($this->element);
+ array_pop($this->namespace);
+ array_pop($this->xml_base);
+ array_pop($this->xml_base_explicit);
+ array_pop($this->xml_lang);
+ }
+
+ public function split_ns($string)
+ {
+ static $cache = array();
+ if (!isset($cache[$string]))
+ {
+ if ($pos = strpos($string, $this->separator))
+ {
+ static $separator_length;
+ if (!$separator_length)
+ {
+ $separator_length = strlen($this->separator);
+ }
+ $namespace = substr($string, 0, $pos);
+ $local_name = substr($string, $pos + $separator_length);
+ if (strtolower($namespace) === SIMPLEPIE_NAMESPACE_ITUNES)
+ {
+ $namespace = SIMPLEPIE_NAMESPACE_ITUNES;
+ }
+
+ // Normalize the Media RSS namespaces
+ if ($namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG ||
+ $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG2 ||
+ $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG3 ||
+ $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG4 ||
+ $namespace === SIMPLEPIE_NAMESPACE_MEDIARSS_WRONG5 )
+ {
+ $namespace = SIMPLEPIE_NAMESPACE_MEDIARSS;
+ }
+ $cache[$string] = array($namespace, $local_name);
+ }
+ else
+ {
+ $cache[$string] = array('', $string);
+ }
+ }
+ return $cache[$string];
+ }
+
+ private function parse_hcard($data, $category = false) {
+ $name = '';
+ $link = '';
+ // Check if h-card is set and pass that information on in the link.
+ if (isset($data['type']) && in_array('h-card', $data['type'])) {
+ if (isset($data['properties']['name'][0])) {
+ $name = $data['properties']['name'][0];
+ }
+ if (isset($data['properties']['url'][0])) {
+ $link = $data['properties']['url'][0];
+ if ($name === '') {
+ $name = $link;
+ }
+ else {
+ // can't have commas in categories.
+ $name = str_replace(',', '', $name);
+ }
+ $person_tag = $category ? '<span class="person-tag"></span>' : '';
+ return '<a class="h-card" href="'.$link.'">'.$person_tag.$name.'</a>';
+ }
+ }
+ return isset($data['value']) ? $data['value'] : '';
+ }
+
+ private function parse_microformats(&$data, $url) {
+ $feed_title = '';
+ $feed_author = NULL;
+ $author_cache = array();
+ $items = array();
+ $entries = array();
+ $mf = Mf2\parse($data, $url);
+ // First look for an h-feed.
+ $h_feed = array();
+ foreach ($mf['items'] as $mf_item) {
+ if (in_array('h-feed', $mf_item['type'])) {
+ $h_feed = $mf_item;
+ break;
+ }
+ // Also look for h-feed or h-entry in the children of each top level item.
+ if (!isset($mf_item['children'][0]['type'])) continue;
+ if (in_array('h-feed', $mf_item['children'][0]['type'])) {
+ $h_feed = $mf_item['children'][0];
+ // In this case the parent of the h-feed may be an h-card, so use it as
+ // the feed_author.
+ if (in_array('h-card', $mf_item['type'])) $feed_author = $mf_item;
+ break;
+ }
+ else if (in_array('h-entry', $mf_item['children'][0]['type'])) {
+ $entries = $mf_item['children'];
+ // In this case the parent of the h-entry list may be an h-card, so use
+ // it as the feed_author.
+ if (in_array('h-card', $mf_item['type'])) $feed_author = $mf_item;
+ break;
+ }
+ }
+ if (isset($h_feed['children'])) {
+ $entries = $h_feed['children'];
+ // Also set the feed title and store author from the h-feed if available.
+ if (isset($mf['items'][0]['properties']['name'][0])) {
+ $feed_title = $mf['items'][0]['properties']['name'][0];
+ }
+ if (isset($mf['items'][0]['properties']['author'][0])) {
+ $feed_author = $mf['items'][0]['properties']['author'][0];
+ }
+ }
+ else if (count($entries) === 0) {
+ $entries = $mf['items'];
+ }
+ for ($i = 0; $i < count($entries); $i++) {
+ $entry = $entries[$i];
+ if (in_array('h-entry', $entry['type'])) {
+ $item = array();
+ $title = '';
+ $description = '';
+ if (isset($entry['properties']['url'][0])) {
+ $link = $entry['properties']['url'][0];
+ if (isset($link['value'])) $link = $link['value'];
+ $item['link'] = array(array('data' => $link));
+ }
+ if (isset($entry['properties']['uid'][0])) {
+ $guid = $entry['properties']['uid'][0];
+ if (isset($guid['value'])) $guid = $guid['value'];
+ $item['guid'] = array(array('data' => $guid));
+ }
+ if (isset($entry['properties']['name'][0])) {
+ $title = $entry['properties']['name'][0];
+ if (isset($title['value'])) $title = $title['value'];
+ $item['title'] = array(array('data' => $title));
+ }
+ if (isset($entry['properties']['author'][0]) || isset($feed_author)) {
+ // author is a special case, it can be plain text or an h-card array.
+ // If it's plain text it can also be a url that should be followed to
+ // get the actual h-card.
+ $author = isset($entry['properties']['author'][0]) ?
+ $entry['properties']['author'][0] : $feed_author;
+ if (!is_string($author)) {
+ $author = $this->parse_hcard($author);
+ }
+ else if (strpos($author, 'http') === 0) {
+ if (isset($author_cache[$author])) {
+ $author = $author_cache[$author];
+ }
+ else {
+ $mf = Mf2\fetch($author);
+ foreach ($mf['items'] as $hcard) {
+ // Only interested in an h-card by itself in this case.
+ if (!in_array('h-card', $hcard['type'])) {
+ continue;
+ }
+ // It must have a url property matching what we fetched.
+ if (!isset($hcard['properties']['url']) ||
+ !(in_array($author, $hcard['properties']['url']))) {
+ continue;
+ }
+ // Save parse_hcard the trouble of finding the correct url.
+ $hcard['properties']['url'][0] = $author;
+ // Cache this h-card for the next h-entry to check.
+ $author_cache[$author] = $this->parse_hcard($hcard);
+ $author = $author_cache[$author];
+ break;
+ }
+ }
+ }
+ $item['author'] = array(array('data' => $author));
+ }
+ if (isset($entry['properties']['photo'][0])) {
+ // If a photo is also in content, don't need to add it again here.
+ $content = '';
+ if (isset($entry['properties']['content'][0]['html'])) {
+ $content = $entry['properties']['content'][0]['html'];
+ }
+ $photo_list = array();
+ for ($j = 0; $j < count($entry['properties']['photo']); $j++) {
+ $photo = $entry['properties']['photo'][$j];
+ if (!empty($photo) && strpos($content, $photo) === false) {
+ $photo_list[] = $photo;
+ }
+ }
+ // When there's more than one photo show the first and use a lightbox.
+ // Need a permanent, unique name for the image set, but don't have
+ // anything unique except for the content itself, so use that.
+ $count = count($photo_list);
+ if ($count > 1) {
+ $image_set_id = preg_replace('/[[:^alnum:]]/', '', $photo_list[0]);
+ $description = '<p>';
+ for ($j = 0; $j < $count; $j++) {
+ $hidden = $j === 0 ? '' : 'class="hidden" ';
+ $description .= '<a href="'.$photo_list[$j].'" '.$hidden.
+ 'data-lightbox="image-set-'.$image_set_id.'">'.
+ '<img src="'.$photo_list[$j].'"></a>';
+ }
+ $description .= '<br><b>'.$count.' photos</b></p>';
+ }
+ else if ($count == 1) {
+ $description = '<p><img src="'.$photo_list[0].'"></p>';
+ }
+ }
+ if (isset($entry['properties']['content'][0]['html'])) {
+ // e-content['value'] is the same as p-name when they are on the same
+ // element. Use this to replace title with a strip_tags version so
+ // that alt text from images is not included in the title.
+ if ($entry['properties']['content'][0]['value'] === $title) {
+ $title = strip_tags($entry['properties']['content'][0]['html']);
+ $item['title'] = array(array('data' => $title));
+ }
+ $description .= $entry['properties']['content'][0]['html'];
+ if (isset($entry['properties']['in-reply-to'][0])) {
+ $in_reply_to = '';
+ if (is_string($entry['properties']['in-reply-to'][0])) {
+ $in_reply_to = $entry['properties']['in-reply-to'][0];
+ }
+ else if (isset($entry['properties']['in-reply-to'][0]['value'])) {
+ $in_reply_to = $entry['properties']['in-reply-to'][0]['value'];
+ }
+ if ($in_reply_to !== '') {
+ $description .= '<p><span class="in-reply-to"></span> '.
+ '<a href="'.$in_reply_to.'">'.$in_reply_to.'</a><p>';
+ }
+ }
+ $item['description'] = array(array('data' => $description));
+ }
+ if (isset($entry['properties']['category'])) {
+ $category_csv = '';
+ // Categories can also contain h-cards.
+ foreach ($entry['properties']['category'] as $category) {
+ if ($category_csv !== '') $category_csv .= ', ';
+ if (is_string($category)) {
+ // Can't have commas in categories.
+ $category_csv .= str_replace(',', '', $category);
+ }
+ else {
+ $category_csv .= $this->parse_hcard($category, true);
+ }
+ }
+ $item['category'] = array(array('data' => $category_csv));
+ }
+ if (isset($entry['properties']['published'][0])) {
+ $timestamp = strtotime($entry['properties']['published'][0]);
+ $pub_date = date('F j Y g:ia', $timestamp).' GMT';
+ $item['pubDate'] = array(array('data' => $pub_date));
+ }
+ // The title and description are set to the empty string to represent
+ // a deleted item (which also makes it an invalid rss item).
+ if (isset($entry['properties']['deleted'][0])) {
+ $item['title'] = array(array('data' => ''));
+ $item['description'] = array(array('data' => ''));
+ }
+ $items[] = array('child' => array('' => $item));
+ }
+ }
+ // Mimic RSS data format when storing microformats.
+ $link = array(array('data' => $url));
+ $image = '';
+ if (!is_string($feed_author) &&
+ isset($feed_author['properties']['photo'][0])) {
+ $image = array(array('child' => array('' => array('url' =>
+ array(array('data' => $feed_author['properties']['photo'][0]))))));
+ }
+ // Use the name given for the h-feed, or get the title from the html.
+ if ($feed_title !== '') {
+ $feed_title = array(array('data' => htmlspecialchars($feed_title)));
+ }
+ else if ($position = strpos($data, '<title>')) {
+ $start = $position < 200 ? 0 : $position - 200;
+ $check = substr($data, $start, 400);
+ $matches = array();
+ if (preg_match('/<title>(.+)<\/title>/', $check, $matches)) {
+ $feed_title = array(array('data' => htmlspecialchars($matches[1])));
+ }
+ }
+ $channel = array('channel' => array(array('child' => array('' =>
+ array('link' => $link, 'image' => $image, 'title' => $feed_title,
+ 'item' => $items)))));
+ $rss = array(array('attribs' => array('' => array('version' => '2.0')),
+ 'child' => array('' => $channel)));
+ $this->data = array('child' => array('' => array('rss' => $rss)));
+ return true;
+ }
+
+ private function declare_html_entities() {
+ // This is required because the RSS specification says that entity-encoded
+ // html is allowed, but the xml specification says they must be declared.
+ return '<!DOCTYPE html [ <!ENTITY nbsp "&#x00A0;"> <!ENTITY iexcl "&#x00A1;"> <!ENTITY cent "&#x00A2;"> <!ENTITY pound "&#x00A3;"> <!ENTITY curren "&#x00A4;"> <!ENTITY yen "&#x00A5;"> <!ENTITY brvbar "&#x00A6;"> <!ENTITY sect "&#x00A7;"> <!ENTITY uml "&#x00A8;"> <!ENTITY copy "&#x00A9;"> <!ENTITY ordf "&#x00AA;"> <!ENTITY laquo "&#x00AB;"> <!ENTITY not "&#x00AC;"> <!ENTITY shy "&#x00AD;"> <!ENTITY reg "&#x00AE;"> <!ENTITY macr "&#x00AF;"> <!ENTITY deg "&#x00B0;"> <!ENTITY plusmn "&#x00B1;"> <!ENTITY sup2 "&#x00B2;"> <!ENTITY sup3 "&#x00B3;"> <!ENTITY acute "&#x00B4;"> <!ENTITY micro "&#x00B5;"> <!ENTITY para "&#x00B6;"> <!ENTITY middot "&#x00B7;"> <!ENTITY cedil "&#x00B8;"> <!ENTITY sup1 "&#x00B9;"> <!ENTITY ordm "&#x00BA;"> <!ENTITY raquo "&#x00BB;"> <!ENTITY frac14 "&#x00BC;"> <!ENTITY frac12 "&#x00BD;"> <!ENTITY frac34 "&#x00BE;"> <!ENTITY iquest "&#x00BF;"> <!ENTITY Agrave "&#x00C0;"> <!ENTITY Aacute "&#x00C1;"> <!ENTITY Acirc "&#x00C2;"> <!ENTITY Atilde "&#x00C3;"> <!ENTITY Auml "&#x00C4;"> <!ENTITY Aring "&#x00C5;"> <!ENTITY AElig "&#x00C6;"> <!ENTITY Ccedil "&#x00C7;"> <!ENTITY Egrave "&#x00C8;"> <!ENTITY Eacute "&#x00C9;"> <!ENTITY Ecirc "&#x00CA;"> <!ENTITY Euml "&#x00CB;"> <!ENTITY Igrave "&#x00CC;"> <!ENTITY Iacute "&#x00CD;"> <!ENTITY Icirc "&#x00CE;"> <!ENTITY Iuml "&#x00CF;"> <!ENTITY ETH "&#x00D0;"> <!ENTITY Ntilde "&#x00D1;"> <!ENTITY Ograve "&#x00D2;"> <!ENTITY Oacute "&#x00D3;"> <!ENTITY Ocirc "&#x00D4;"> <!ENTITY Otilde "&#x00D5;"> <!ENTITY Ouml "&#x00D6;"> <!ENTITY times "&#x00D7;"> <!ENTITY Oslash "&#x00D8;"> <!ENTITY Ugrave "&#x00D9;"> <!ENTITY Uacute "&#x00DA;"> <!ENTITY Ucirc "&#x00DB;"> <!ENTITY Uuml "&#x00DC;"> <!ENTITY Yacute "&#x00DD;"> <!ENTITY THORN "&#x00DE;"> <!ENTITY szlig "&#x00DF;"> <!ENTITY agrave "&#x00E0;"> <!ENTITY aacute "&#x00E1;"> <!ENTITY acirc "&#x00E2;"> <!ENTITY atilde "&#x00E3;"> <!ENTITY auml "&#x00E4;"> <!ENTITY aring "&#x00E5;"> <!ENTITY aelig "&#x00E6;"> <!ENTITY ccedil "&#x00E7;"> <!ENTITY egrave "&#x00E8;"> <!ENTITY eacute "&#x00E9;"> <!ENTITY ecirc "&#x00EA;"> <!ENTITY euml "&#x00EB;"> <!ENTITY igrave "&#x00EC;"> <!ENTITY iacute "&#x00ED;"> <!ENTITY icirc "&#x00EE;"> <!ENTITY iuml "&#x00EF;"> <!ENTITY eth "&#x00F0;"> <!ENTITY ntilde "&#x00F1;"> <!ENTITY ograve "&#x00F2;"> <!ENTITY oacute "&#x00F3;"> <!ENTITY ocirc "&#x00F4;"> <!ENTITY otilde "&#x00F5;"> <!ENTITY ouml "&#x00F6;"> <!ENTITY divide "&#x00F7;"> <!ENTITY oslash "&#x00F8;"> <!ENTITY ugrave "&#x00F9;"> <!ENTITY uacute "&#x00FA;"> <!ENTITY ucirc "&#x00FB;"> <!ENTITY uuml "&#x00FC;"> <!ENTITY yacute "&#x00FD;"> <!ENTITY thorn "&#x00FE;"> <!ENTITY yuml "&#x00FF;"> <!ENTITY OElig "&#x0152;"> <!ENTITY oelig "&#x0153;"> <!ENTITY Scaron "&#x0160;"> <!ENTITY scaron "&#x0161;"> <!ENTITY Yuml "&#x0178;"> <!ENTITY fnof "&#x0192;"> <!ENTITY circ "&#x02C6;"> <!ENTITY tilde "&#x02DC;"> <!ENTITY Alpha "&#x0391;"> <!ENTITY Beta "&#x0392;"> <!ENTITY Gamma "&#x0393;"> <!ENTITY Epsilon "&#x0395;"> <!ENTITY Zeta "&#x0396;"> <!ENTITY Eta "&#x0397;"> <!ENTITY Theta "&#x0398;"> <!ENTITY Iota "&#x0399;"> <!ENTITY Kappa "&#x039A;"> <!ENTITY Lambda "&#x039B;"> <!ENTITY Mu "&#x039C;"> <!ENTITY Nu "&#x039D;"> <!ENTITY Xi "&#x039E;"> <!ENTITY Omicron "&#x039F;"> <!ENTITY Pi "&#x03A0;"> <!ENTITY Rho "&#x03A1;"> <!ENTITY Sigma "&#x03A3;"> <!ENTITY Tau "&#x03A4;"> <!ENTITY Upsilon "&#x03A5;"> <!ENTITY Phi "&#x03A6;"> <!ENTITY Chi "&#x03A7;"> <!ENTITY Psi "&#x03A8;"> <!ENTITY Omega "&#x03A9;"> <!ENTITY alpha "&#x03B1;"> <!ENTITY beta "&#x03B2;"> <!ENTITY gamma "&#x03B3;"> <!ENTITY delta "&#x03B4;"> <!ENTITY epsilon "&#x03B5;"> <!ENTITY zeta "&#x03B6;"> <!ENTITY eta "&#x03B7;"> <!ENTITY theta "&#x03B8;"> <!ENTITY iota "&#x03B9;"> <!ENTITY kappa "&#x03BA;"> <!ENTITY lambda "&#x03BB;"> <!ENTITY mu "&#x03BC;"> <!ENTITY nu "&#x03BD;"> <!ENTITY xi "&#x03BE;"> <!ENTITY omicron "&#x03BF;"> <!ENTITY pi "&#x03C0;"> <!ENTITY rho "&#x03C1;"> <!ENTITY sigmaf "&#x03C2;"> <!ENTITY sigma "&#x03C3;"> <!ENTITY tau "&#x03C4;"> <!ENTITY upsilon "&#x03C5;"> <!ENTITY phi "&#x03C6;"> <!ENTITY chi "&#x03C7;"> <!ENTITY psi "&#x03C8;"> <!ENTITY omega "&#x03C9;"> <!ENTITY thetasym "&#x03D1;"> <!ENTITY upsih "&#x03D2;"> <!ENTITY piv "&#x03D6;"> <!ENTITY ensp "&#x2002;"> <!ENTITY emsp "&#x2003;"> <!ENTITY thinsp "&#x2009;"> <!ENTITY zwnj "&#x200C;"> <!ENTITY zwj "&#x200D;"> <!ENTITY lrm "&#x200E;"> <!ENTITY rlm "&#x200F;"> <!ENTITY ndash "&#x2013;"> <!ENTITY mdash "&#x2014;"> <!ENTITY lsquo "&#x2018;"> <!ENTITY rsquo "&#x2019;"> <!ENTITY sbquo "&#x201A;"> <!ENTITY ldquo "&#x201C;"> <!ENTITY rdquo "&#x201D;"> <!ENTITY bdquo "&#x201E;"> <!ENTITY dagger "&#x2020;"> <!ENTITY Dagger "&#x2021;"> <!ENTITY bull "&#x2022;"> <!ENTITY hellip "&#x2026;"> <!ENTITY permil "&#x2030;"> <!ENTITY prime "&#x2032;"> <!ENTITY Prime "&#x2033;"> <!ENTITY lsaquo "&#x2039;"> <!ENTITY rsaquo "&#x203A;"> <!ENTITY oline "&#x203E;"> <!ENTITY frasl "&#x2044;"> <!ENTITY euro "&#x20AC;"> <!ENTITY image "&#x2111;"> <!ENTITY weierp "&#x2118;"> <!ENTITY real "&#x211C;"> <!ENTITY trade "&#x2122;"> <!ENTITY alefsym "&#x2135;"> <!ENTITY larr "&#x2190;"> <!ENTITY uarr "&#x2191;"> <!ENTITY rarr "&#x2192;"> <!ENTITY darr "&#x2193;"> <!ENTITY harr "&#x2194;"> <!ENTITY crarr "&#x21B5;"> <!ENTITY lArr "&#x21D0;"> <!ENTITY uArr "&#x21D1;"> <!ENTITY rArr "&#x21D2;"> <!ENTITY dArr "&#x21D3;"> <!ENTITY hArr "&#x21D4;"> <!ENTITY forall "&#x2200;"> <!ENTITY part "&#x2202;"> <!ENTITY exist "&#x2203;"> <!ENTITY empty "&#x2205;"> <!ENTITY nabla "&#x2207;"> <!ENTITY isin "&#x2208;"> <!ENTITY notin "&#x2209;"> <!ENTITY ni "&#x220B;"> <!ENTITY prod "&#x220F;"> <!ENTITY sum "&#x2211;"> <!ENTITY minus "&#x2212;"> <!ENTITY lowast "&#x2217;"> <!ENTITY radic "&#x221A;"> <!ENTITY prop "&#x221D;"> <!ENTITY infin "&#x221E;"> <!ENTITY ang "&#x2220;"> <!ENTITY and "&#x2227;"> <!ENTITY or "&#x2228;"> <!ENTITY cap "&#x2229;"> <!ENTITY cup "&#x222A;"> <!ENTITY int "&#x222B;"> <!ENTITY there4 "&#x2234;"> <!ENTITY sim "&#x223C;"> <!ENTITY cong "&#x2245;"> <!ENTITY asymp "&#x2248;"> <!ENTITY ne "&#x2260;"> <!ENTITY equiv "&#x2261;"> <!ENTITY le "&#x2264;"> <!ENTITY ge "&#x2265;"> <!ENTITY sub "&#x2282;"> <!ENTITY sup "&#x2283;"> <!ENTITY nsub "&#x2284;"> <!ENTITY sube "&#x2286;"> <!ENTITY supe "&#x2287;"> <!ENTITY oplus "&#x2295;"> <!ENTITY otimes "&#x2297;"> <!ENTITY perp "&#x22A5;"> <!ENTITY sdot "&#x22C5;"> <!ENTITY lceil "&#x2308;"> <!ENTITY rceil "&#x2309;"> <!ENTITY lfloor "&#x230A;"> <!ENTITY rfloor "&#x230B;"> <!ENTITY lang "&#x2329;"> <!ENTITY rang "&#x232A;"> <!ENTITY loz "&#x25CA;"> <!ENTITY spades "&#x2660;"> <!ENTITY clubs "&#x2663;"> <!ENTITY hearts "&#x2665;"> <!ENTITY diams "&#x2666;"> ]>';
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Rating.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Rating.php
new file mode 100644
index 0000000..599f75a
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Rating.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Handles `<media:rating>` or `<itunes:explicit>` tags as defined in Media RSS and iTunes RSS respectively
+ *
+ * Used by {@see SimplePie_Enclosure::get_rating()} and {@see SimplePie_Enclosure::get_ratings()}
+ *
+ * This class can be overloaded with {@see SimplePie::set_rating_class()}
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Rating
+{
+ /**
+ * Rating scheme
+ *
+ * @var string
+ * @see get_scheme()
+ */
+ var $scheme;
+
+ /**
+ * Rating value
+ *
+ * @var string
+ * @see get_value()
+ */
+ var $value;
+
+ /**
+ * Constructor, used to input the data
+ *
+ * For documentation on all the parameters, see the corresponding
+ * properties and their accessors
+ */
+ public function __construct($scheme = null, $value = null)
+ {
+ $this->scheme = $scheme;
+ $this->value = $value;
+ }
+
+ /**
+ * String-ified version
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ /**
+ * Get the organizational scheme for the rating
+ *
+ * @return string|null
+ */
+ public function get_scheme()
+ {
+ if ($this->scheme !== null)
+ {
+ return $this->scheme;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the value of the rating
+ *
+ * @return string|null
+ */
+ public function get_value()
+ {
+ if ($this->value !== null)
+ {
+ return $this->value;
+ }
+
+ return null;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Registry.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Registry.php
new file mode 100755
index 0000000..bf3baf1
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Registry.php
@@ -0,0 +1,224 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Handles creating objects and calling methods
+ *
+ * Access this via {@see SimplePie::get_registry()}
+ *
+ * @package SimplePie
+ */
+class SimplePie_Registry
+{
+ /**
+ * Default class mapping
+ *
+ * Overriding classes *must* subclass these.
+ *
+ * @var array
+ */
+ protected $default = array(
+ 'Cache' => 'SimplePie_Cache',
+ 'Locator' => 'SimplePie_Locator',
+ 'Parser' => 'SimplePie_Parser',
+ 'File' => 'SimplePie_File',
+ 'Sanitize' => 'SimplePie_Sanitize',
+ 'Item' => 'SimplePie_Item',
+ 'Author' => 'SimplePie_Author',
+ 'Category' => 'SimplePie_Category',
+ 'Enclosure' => 'SimplePie_Enclosure',
+ 'Caption' => 'SimplePie_Caption',
+ 'Copyright' => 'SimplePie_Copyright',
+ 'Credit' => 'SimplePie_Credit',
+ 'Rating' => 'SimplePie_Rating',
+ 'Restriction' => 'SimplePie_Restriction',
+ 'Content_Type_Sniffer' => 'SimplePie_Content_Type_Sniffer',
+ 'Source' => 'SimplePie_Source',
+ 'Misc' => 'SimplePie_Misc',
+ 'XML_Declaration_Parser' => 'SimplePie_XML_Declaration_Parser',
+ 'Parse_Date' => 'SimplePie_Parse_Date',
+ );
+
+ /**
+ * Class mapping
+ *
+ * @see register()
+ * @var array
+ */
+ protected $classes = array();
+
+ /**
+ * Legacy classes
+ *
+ * @see register()
+ * @var array
+ */
+ protected $legacy = array();
+
+ /**
+ * Constructor
+ *
+ * No-op
+ */
+ public function __construct() { }
+
+ /**
+ * Register a class
+ *
+ * @param string $type See {@see $default} for names
+ * @param string $class Class name, must subclass the corresponding default
+ * @param bool $legacy Whether to enable legacy support for this class
+ * @return bool Successfulness
+ */
+ public function register($type, $class, $legacy = false)
+ {
+ if (!@is_subclass_of($class, $this->default[$type]))
+ {
+ return false;
+ }
+
+ $this->classes[$type] = $class;
+
+ if ($legacy)
+ {
+ $this->legacy[] = $class;
+ }
+
+ return true;
+ }
+
+ /**
+ * Get the class registered for a type
+ *
+ * Where possible, use {@see create()} or {@see call()} instead
+ *
+ * @param string $type
+ * @return string|null
+ */
+ public function get_class($type)
+ {
+ if (!empty($this->classes[$type]))
+ {
+ return $this->classes[$type];
+ }
+ if (!empty($this->default[$type]))
+ {
+ return $this->default[$type];
+ }
+
+ return null;
+ }
+
+ /**
+ * Create a new instance of a given type
+ *
+ * @param string $type
+ * @param array $parameters Parameters to pass to the constructor
+ * @return object Instance of class
+ */
+ public function &create($type, $parameters = array())
+ {
+ $class = $this->get_class($type);
+
+ if (in_array($class, $this->legacy))
+ {
+ switch ($type)
+ {
+ case 'locator':
+ // Legacy: file, timeout, useragent, file_class, max_checked_feeds, content_type_sniffer_class
+ // Specified: file, timeout, useragent, max_checked_feeds
+ $replacement = array($this->get_class('file'), $parameters[3], $this->get_class('content_type_sniffer'));
+ array_splice($parameters, 3, 1, $replacement);
+ break;
+ }
+ }
+
+ if (!method_exists($class, '__construct'))
+ {
+ $instance = new $class;
+ }
+ else
+ {
+ $reflector = new ReflectionClass($class);
+ $instance = $reflector->newInstanceArgs($parameters);
+ }
+
+ if (method_exists($instance, 'set_registry'))
+ {
+ $instance->set_registry($this);
+ }
+ return $instance;
+ }
+
+ /**
+ * Call a static method for a type
+ *
+ * @param string $type
+ * @param string $method
+ * @param array $parameters
+ * @return mixed
+ */
+ public function &call($type, $method, $parameters = array())
+ {
+ $class = $this->get_class($type);
+
+ if (in_array($class, $this->legacy))
+ {
+ switch ($type)
+ {
+ case 'Cache':
+ // For backwards compatibility with old non-static
+ // Cache::create() methods
+ if ($method === 'get_handler')
+ {
+ $result = @call_user_func_array(array($class, 'create'), $parameters);
+ return $result;
+ }
+ break;
+ }
+ }
+
+ $result = call_user_func_array(array($class, $method), $parameters);
+ return $result;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Restriction.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Restriction.php
new file mode 100644
index 0000000..950017f
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Restriction.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Handles `<media:restriction>` as defined in Media RSS
+ *
+ * Used by {@see SimplePie_Enclosure::get_restriction()} and {@see SimplePie_Enclosure::get_restrictions()}
+ *
+ * This class can be overloaded with {@see SimplePie::set_restriction_class()}
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Restriction
+{
+ /**
+ * Relationship ('allow'/'deny')
+ *
+ * @var string
+ * @see get_relationship()
+ */
+ var $relationship;
+
+ /**
+ * Type of restriction
+ *
+ * @var string
+ * @see get_type()
+ */
+ var $type;
+
+ /**
+ * Restricted values
+ *
+ * @var string
+ * @see get_value()
+ */
+ var $value;
+
+ /**
+ * Constructor, used to input the data
+ *
+ * For documentation on all the parameters, see the corresponding
+ * properties and their accessors
+ */
+ public function __construct($relationship = null, $type = null, $value = null)
+ {
+ $this->relationship = $relationship;
+ $this->type = $type;
+ $this->value = $value;
+ }
+
+ /**
+ * String-ified version
+ *
+ * @return string
+ */
+ public function __toString()
+ {
+ // There is no $this->data here
+ return md5(serialize($this));
+ }
+
+ /**
+ * Get the relationship
+ *
+ * @return string|null Either 'allow' or 'deny'
+ */
+ public function get_relationship()
+ {
+ if ($this->relationship !== null)
+ {
+ return $this->relationship;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the type
+ *
+ * @return string|null
+ */
+ public function get_type()
+ {
+ if ($this->type !== null)
+ {
+ return $this->type;
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the list of restricted things
+ *
+ * @return string|null
+ */
+ public function get_value()
+ {
+ if ($this->value !== null)
+ {
+ return $this->value;
+ }
+
+ return null;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Sanitize.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Sanitize.php
new file mode 100644
index 0000000..3583803
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Sanitize.php
@@ -0,0 +1,584 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Used for data cleanup and post-processing
+ *
+ *
+ * This class can be overloaded with {@see SimplePie::set_sanitize_class()}
+ *
+ * @package SimplePie
+ * @todo Move to using an actual HTML parser (this will allow tags to be properly stripped, and to switch between HTML and XHTML), this will also make it easier to shorten a string while preserving HTML tags
+ */
+class SimplePie_Sanitize
+{
+ // Private vars
+ var $base;
+
+ // Options
+ var $remove_div = true;
+ var $image_handler = '';
+ var $strip_htmltags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style');
+ var $encode_instead_of_strip = false;
+ var $strip_attributes = array('bgsound', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc');
+ var $add_attributes = array('audio' => array('preload' => 'none'), 'iframe' => array('sandbox' => 'allow-scripts allow-same-origin'), 'video' => array('preload' => 'none'));
+ var $strip_comments = false;
+ var $output_encoding = 'UTF-8';
+ var $enable_cache = true;
+ var $cache_location = './cache';
+ var $cache_name_function = 'md5';
+ var $timeout = 10;
+ var $useragent = '';
+ var $force_fsockopen = false;
+ var $replace_url_attributes = null;
+
+ public function __construct()
+ {
+ // Set defaults
+ $this->set_url_replacements(null);
+ }
+
+ public function remove_div($enable = true)
+ {
+ $this->remove_div = (bool) $enable;
+ }
+
+ public function set_image_handler($page = false)
+ {
+ if ($page)
+ {
+ $this->image_handler = (string) $page;
+ }
+ else
+ {
+ $this->image_handler = false;
+ }
+ }
+
+ public function set_registry(SimplePie_Registry $registry)
+ {
+ $this->registry = $registry;
+ }
+
+ public function pass_cache_data($enable_cache = true, $cache_location = './cache', $cache_name_function = 'md5', $cache_class = 'SimplePie_Cache')
+ {
+ if (isset($enable_cache))
+ {
+ $this->enable_cache = (bool) $enable_cache;
+ }
+
+ if ($cache_location)
+ {
+ $this->cache_location = (string) $cache_location;
+ }
+
+ if ($cache_name_function)
+ {
+ $this->cache_name_function = (string) $cache_name_function;
+ }
+ }
+
+ public function pass_file_data($file_class = 'SimplePie_File', $timeout = 10, $useragent = '', $force_fsockopen = false)
+ {
+ if ($timeout)
+ {
+ $this->timeout = (string) $timeout;
+ }
+
+ if ($useragent)
+ {
+ $this->useragent = (string) $useragent;
+ }
+
+ if ($force_fsockopen)
+ {
+ $this->force_fsockopen = (string) $force_fsockopen;
+ }
+ }
+
+ public function strip_htmltags($tags = array('base', 'blink', 'body', 'doctype', 'embed', 'font', 'form', 'frame', 'frameset', 'html', 'iframe', 'input', 'marquee', 'meta', 'noscript', 'object', 'param', 'script', 'style'))
+ {
+ if ($tags)
+ {
+ if (is_array($tags))
+ {
+ $this->strip_htmltags = $tags;
+ }
+ else
+ {
+ $this->strip_htmltags = explode(',', $tags);
+ }
+ }
+ else
+ {
+ $this->strip_htmltags = false;
+ }
+ }
+
+ public function encode_instead_of_strip($encode = false)
+ {
+ $this->encode_instead_of_strip = (bool) $encode;
+ }
+
+ public function strip_attributes($attribs = array('bgsound', 'expr', 'id', 'style', 'onclick', 'onerror', 'onfinish', 'onmouseover', 'onmouseout', 'onfocus', 'onblur', 'lowsrc', 'dynsrc'))
+ {
+ if ($attribs)
+ {
+ if (is_array($attribs))
+ {
+ $this->strip_attributes = $attribs;
+ }
+ else
+ {
+ $this->strip_attributes = explode(',', $attribs);
+ }
+ }
+ else
+ {
+ $this->strip_attributes = false;
+ }
+ }
+
+ public function add_attributes($attribs = array('audio' => array('preload' => 'none'), 'iframe' => array('sandbox' => 'allow-scripts allow-same-origin'), 'video' => array('preload' => 'none')))
+ {
+ if ($attribs)
+ {
+ if (is_array($attribs))
+ {
+ $this->add_attributes = $attribs;
+ }
+ else
+ {
+ $this->add_attributes = explode(',', $attribs);
+ }
+ }
+ else
+ {
+ $this->add_attributes = false;
+ }
+ }
+
+ public function strip_comments($strip = false)
+ {
+ $this->strip_comments = (bool) $strip;
+ }
+
+ public function set_output_encoding($encoding = 'UTF-8')
+ {
+ $this->output_encoding = (string) $encoding;
+ }
+
+ /**
+ * Set element/attribute key/value pairs of HTML attributes
+ * containing URLs that need to be resolved relative to the feed
+ *
+ * Defaults to |a|@href, |area|@href, |blockquote|@cite, |del|@cite,
+ * |form|@action, |img|@longdesc, |img|@src, |input|@src, |ins|@cite,
+ * |q|@cite
+ *
+ * @since 1.0
+ * @param array|null $element_attribute Element/attribute key/value pairs, null for default
+ */
+ public function set_url_replacements($element_attribute = null)
+ {
+ if ($element_attribute === null)
+ {
+ $element_attribute = array(
+ 'a' => 'href',
+ 'area' => 'href',
+ 'blockquote' => 'cite',
+ 'del' => 'cite',
+ 'form' => 'action',
+ 'img' => array(
+ 'longdesc',
+ 'src'
+ ),
+ 'input' => 'src',
+ 'ins' => 'cite',
+ 'q' => 'cite'
+ );
+ }
+ $this->replace_url_attributes = (array) $element_attribute;
+ }
+
+ public function sanitize($data, $type, $base = '')
+ {
+ $data = trim($data);
+ if ($data !== '' || $type & SIMPLEPIE_CONSTRUCT_IRI)
+ {
+ if ($type & SIMPLEPIE_CONSTRUCT_MAYBE_HTML)
+ {
+ if (preg_match('/(&(#(x[0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+)|<\/[A-Za-z][^\x09\x0A\x0B\x0C\x0D\x20\x2F\x3E]*' . SIMPLEPIE_PCRE_HTML_ATTRIBUTE . '>)/', $data))
+ {
+ $type |= SIMPLEPIE_CONSTRUCT_HTML;
+ }
+ else
+ {
+ $type |= SIMPLEPIE_CONSTRUCT_TEXT;
+ }
+ }
+
+ if ($type & SIMPLEPIE_CONSTRUCT_BASE64)
+ {
+ $data = base64_decode($data);
+ }
+
+ if ($type & (SIMPLEPIE_CONSTRUCT_HTML | SIMPLEPIE_CONSTRUCT_XHTML))
+ {
+
+ if (!class_exists('DOMDocument'))
+ {
+ throw new SimplePie_Exception('DOMDocument not found, unable to use sanitizer');
+ }
+ $document = new DOMDocument();
+ $document->encoding = 'UTF-8';
+
+ $data = $this->preprocess($data, $type);
+
+ set_error_handler(array('SimplePie_Misc', 'silence_errors'));
+ $document->loadHTML($data);
+ restore_error_handler();
+
+ $xpath = new DOMXPath($document);
+
+ // Strip comments
+ if ($this->strip_comments)
+ {
+ $comments = $xpath->query('//comment()');
+
+ foreach ($comments as $comment)
+ {
+ $comment->parentNode->removeChild($comment);
+ }
+ }
+
+ // Strip out HTML tags and attributes that might cause various security problems.
+ // Based on recommendations by Mark Pilgrim at:
+ // http://diveintomark.org/archives/2003/06/12/how_to_consume_rss_safely
+ if ($this->strip_htmltags)
+ {
+ foreach ($this->strip_htmltags as $tag)
+ {
+ $this->strip_tag($tag, $document, $xpath, $type);
+ }
+ }
+
+ if ($this->strip_attributes)
+ {
+ foreach ($this->strip_attributes as $attrib)
+ {
+ $this->strip_attr($attrib, $xpath);
+ }
+ }
+
+ if ($this->add_attributes)
+ {
+ foreach ($this->add_attributes as $tag => $valuePairs)
+ {
+ $this->add_attr($tag, $valuePairs, $document);
+ }
+ }
+
+ // Replace relative URLs
+ $this->base = $base;
+ foreach ($this->replace_url_attributes as $element => $attributes)
+ {
+ $this->replace_urls($document, $element, $attributes);
+ }
+
+ // If image handling (caching, etc.) is enabled, cache and rewrite all the image tags.
+ if (isset($this->image_handler) && ((string) $this->image_handler) !== '' && $this->enable_cache)
+ {
+ $images = $document->getElementsByTagName('img');
+ foreach ($images as $img)
+ {
+ if ($img->hasAttribute('src'))
+ {
+ $image_url = call_user_func($this->cache_name_function, $img->getAttribute('src'));
+ $cache = $this->registry->call('Cache', 'get_handler', array($this->cache_location, $image_url, 'spi'));
+
+ if ($cache->load())
+ {
+ $img->setAttribute('src', $this->image_handler . $image_url);
+ }
+ else
+ {
+ $file = $this->registry->create('File', array($img->getAttribute('src'), $this->timeout, 5, array('X-FORWARDED-FOR' => $_SERVER['REMOTE_ADDR']), $this->useragent, $this->force_fsockopen));
+ $headers = $file->headers;
+
+ if ($file->success && ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code < 300)))
+ {
+ if ($cache->save(array('headers' => $file->headers, 'body' => $file->body)))
+ {
+ $img->setAttribute('src', $this->image_handler . $image_url);
+ }
+ else
+ {
+ trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Get content node
+ $div = $document->getElementsByTagName('body')->item(0)->firstChild;
+ // Finally, convert to a HTML string
+ $data = trim($document->saveHTML($div));
+
+ if ($this->remove_div)
+ {
+ $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '', $data);
+ $data = preg_replace('/<\/div>$/', '', $data);
+ }
+ else
+ {
+ $data = preg_replace('/^<div' . SIMPLEPIE_PCRE_XML_ATTRIBUTE . '>/', '<div>', $data);
+ }
+ }
+
+ if ($type & SIMPLEPIE_CONSTRUCT_IRI)
+ {
+ $absolute = $this->registry->call('Misc', 'absolutize_url', array($data, $base));
+ if ($absolute !== false)
+ {
+ $data = $absolute;
+ }
+ }
+
+ if ($type & (SIMPLEPIE_CONSTRUCT_TEXT | SIMPLEPIE_CONSTRUCT_IRI))
+ {
+ $data = htmlspecialchars($data, ENT_COMPAT, 'UTF-8');
+ }
+
+ if ($this->output_encoding !== 'UTF-8')
+ {
+ $data = $this->registry->call('Misc', 'change_encoding', array($data, 'UTF-8', $this->output_encoding));
+ }
+ }
+ return $data;
+ }
+
+ protected function preprocess($html, $type)
+ {
+ $ret = '';
+ $html = preg_replace('%</?(?:html|body)[^>]*?'.'>%is', '', $html);
+ if ($type & ~SIMPLEPIE_CONSTRUCT_XHTML)
+ {
+ // Atom XHTML constructs are wrapped with a div by default
+ // Note: No protection if $html contains a stray </div>!
+ $html = '<div>' . $html . '</div>';
+ $ret .= '<!DOCTYPE html>';
+ $content_type = 'text/html';
+ }
+ else
+ {
+ $ret .= '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
+ $content_type = 'application/xhtml+xml';
+ }
+
+ $ret .= '<html><head>';
+ $ret .= '<meta http-equiv="Content-Type" content="' . $content_type . '; charset=utf-8" />';
+ $ret .= '</head><body>' . $html . '</body></html>';
+ return $ret;
+ }
+
+ public function replace_urls($document, $tag, $attributes)
+ {
+ if (!is_array($attributes))
+ {
+ $attributes = array($attributes);
+ }
+
+ if (!is_array($this->strip_htmltags) || !in_array($tag, $this->strip_htmltags))
+ {
+ $elements = $document->getElementsByTagName($tag);
+ foreach ($elements as $element)
+ {
+ foreach ($attributes as $attribute)
+ {
+ if ($element->hasAttribute($attribute))
+ {
+ $value = $this->registry->call('Misc', 'absolutize_url', array($element->getAttribute($attribute), $this->base));
+ if ($value !== false)
+ {
+ $element->setAttribute($attribute, $value);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public function do_strip_htmltags($match)
+ {
+ if ($this->encode_instead_of_strip)
+ {
+ if (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
+ {
+ $match[1] = htmlspecialchars($match[1], ENT_COMPAT, 'UTF-8');
+ $match[2] = htmlspecialchars($match[2], ENT_COMPAT, 'UTF-8');
+ return "&lt;$match[1]$match[2]&gt;$match[3]&lt;/$match[1]&gt;";
+ }
+ else
+ {
+ return htmlspecialchars($match[0], ENT_COMPAT, 'UTF-8');
+ }
+ }
+ elseif (isset($match[4]) && !in_array(strtolower($match[1]), array('script', 'style')))
+ {
+ return $match[4];
+ }
+ else
+ {
+ return '';
+ }
+ }
+
+ protected function strip_tag($tag, $document, $xpath, $type)
+ {
+ $elements = $xpath->query('body//' . $tag);
+ if ($this->encode_instead_of_strip)
+ {
+ foreach ($elements as $element)
+ {
+ $fragment = $document->createDocumentFragment();
+
+ // For elements which aren't script or style, include the tag itself
+ if (!in_array($tag, array('script', 'style')))
+ {
+ $text = '<' . $tag;
+ if ($element->hasAttributes())
+ {
+ $attrs = array();
+ foreach ($element->attributes as $name => $attr)
+ {
+ $value = $attr->value;
+
+ // In XHTML, empty values should never exist, so we repeat the value
+ if (empty($value) && ($type & SIMPLEPIE_CONSTRUCT_XHTML))
+ {
+ $value = $name;
+ }
+ // For HTML, empty is fine
+ elseif (empty($value) && ($type & SIMPLEPIE_CONSTRUCT_HTML))
+ {
+ $attrs[] = $name;
+ continue;
+ }
+
+ // Standard attribute text
+ $attrs[] = $name . '="' . $attr->value . '"';
+ }
+ $text .= ' ' . implode(' ', $attrs);
+ }
+ $text .= '>';
+ $fragment->appendChild(new DOMText($text));
+ }
+
+ $number = $element->childNodes->length;
+ for ($i = $number; $i > 0; $i--)
+ {
+ $child = $element->childNodes->item(0);
+ $fragment->appendChild($child);
+ }
+
+ if (!in_array($tag, array('script', 'style')))
+ {
+ $fragment->appendChild(new DOMText('</' . $tag . '>'));
+ }
+
+ $element->parentNode->replaceChild($fragment, $element);
+ }
+
+ return;
+ }
+ elseif (in_array($tag, array('script', 'style')))
+ {
+ foreach ($elements as $element)
+ {
+ $element->parentNode->removeChild($element);
+ }
+
+ return;
+ }
+ else
+ {
+ foreach ($elements as $element)
+ {
+ $fragment = $document->createDocumentFragment();
+ $number = $element->childNodes->length;
+ for ($i = $number; $i > 0; $i--)
+ {
+ $child = $element->childNodes->item(0);
+ $fragment->appendChild($child);
+ }
+
+ $element->parentNode->replaceChild($fragment, $element);
+ }
+ }
+ }
+
+ protected function strip_attr($attrib, $xpath)
+ {
+ $elements = $xpath->query('//*[@' . $attrib . ']');
+
+ foreach ($elements as $element)
+ {
+ $element->removeAttribute($attrib);
+ }
+ }
+
+ protected function add_attr($tag, $valuePairs, $document)
+ {
+ $elements = $document->getElementsByTagName($tag);
+ foreach ($elements as $element)
+ {
+ foreach ($valuePairs as $attrib => $value)
+ {
+ $element->setAttribute($attrib, $value);
+ }
+ }
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/Source.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Source.php
new file mode 100644
index 0000000..f14e5b2
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/Source.php
@@ -0,0 +1,577 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+/**
+ * Handles `<atom:source>`
+ *
+ * Used by {@see SimplePie_Item::get_source()}
+ *
+ * This class can be overloaded with {@see SimplePie::set_source_class()}
+ *
+ * @package SimplePie
+ * @subpackage API
+ */
+class SimplePie_Source
+{
+ var $item;
+ var $data = array();
+ protected $registry;
+
+ public function __construct($item, $data)
+ {
+ $this->item = $item;
+ $this->data = $data;
+ }
+
+ public function set_registry(SimplePie_Registry $registry)
+ {
+ $this->registry = $registry;
+ }
+
+ public function __toString()
+ {
+ return md5(serialize($this->data));
+ }
+
+ public function get_source_tags($namespace, $tag)
+ {
+ if (isset($this->data['child'][$namespace][$tag]))
+ {
+ return $this->data['child'][$namespace][$tag];
+ }
+
+ return null;
+ }
+
+ public function get_base($element = array())
+ {
+ return $this->item->get_base($element);
+ }
+
+ public function sanitize($data, $type, $base = '')
+ {
+ return $this->item->sanitize($data, $type, $base);
+ }
+
+ public function get_item()
+ {
+ return $this->item;
+ }
+
+ public function get_title()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'title'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+
+ return null;
+ }
+
+ public function get_category($key = 0)
+ {
+ $categories = $this->get_categories();
+ if (isset($categories[$key]))
+ {
+ return $categories[$key];
+ }
+
+ return null;
+ }
+
+ public function get_categories()
+ {
+ $categories = array();
+
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'category') as $category)
+ {
+ $term = null;
+ $scheme = null;
+ $label = null;
+ if (isset($category['attribs']['']['term']))
+ {
+ $term = $this->sanitize($category['attribs']['']['term'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['scheme']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['scheme'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($category['attribs']['']['label']))
+ {
+ $label = $this->sanitize($category['attribs']['']['label'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ $categories[] = $this->registry->create('Category', array($term, $scheme, $label));
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'category') as $category)
+ {
+ // This is really the label, but keep this as the term also for BC.
+ // Label will also work on retrieving because that falls back to term.
+ $term = $this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ if (isset($category['attribs']['']['domain']))
+ {
+ $scheme = $this->sanitize($category['attribs']['']['domain'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ else
+ {
+ $scheme = null;
+ }
+ $categories[] = $this->registry->create('Category', array($term, $scheme, null));
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'subject') as $category)
+ {
+ $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'subject') as $category)
+ {
+ $categories[] = $this->registry->create('Category', array($this->sanitize($category['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+
+ if (!empty($categories))
+ {
+ return array_unique($categories);
+ }
+
+ return null;
+ }
+
+ public function get_author($key = 0)
+ {
+ $authors = $this->get_authors();
+ if (isset($authors[$key]))
+ {
+ return $authors[$key];
+ }
+
+ return null;
+ }
+
+ public function get_authors()
+ {
+ $authors = array();
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author') as $author)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $authors[] = $this->registry->create('Author', array($name, $uri, $email));
+ }
+ }
+ if ($author = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'author'))
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($author[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $authors[] = $this->registry->create('Author', array($name, $url, $email));
+ }
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'creator') as $author)
+ {
+ $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'creator') as $author)
+ {
+ $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'author') as $author)
+ {
+ $authors[] = $this->registry->create('Author', array($this->sanitize($author['data'], SIMPLEPIE_CONSTRUCT_TEXT), null, null));
+ }
+
+ if (!empty($authors))
+ {
+ return array_unique($authors);
+ }
+
+ return null;
+ }
+
+ public function get_contributor($key = 0)
+ {
+ $contributors = $this->get_contributors();
+ if (isset($contributors[$key]))
+ {
+ return $contributors[$key];
+ }
+
+ return null;
+ }
+
+ public function get_contributors()
+ {
+ $contributors = array();
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'contributor') as $contributor)
+ {
+ $name = null;
+ $uri = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']))
+ {
+ $uri = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $uri !== null)
+ {
+ $contributors[] = $this->registry->create('Author', array($name, $uri, $email));
+ }
+ }
+ foreach ((array) $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'contributor') as $contributor)
+ {
+ $name = null;
+ $url = null;
+ $email = null;
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data']))
+ {
+ $name = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['name'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data']))
+ {
+ $url = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['url'][0]));
+ }
+ if (isset($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data']))
+ {
+ $email = $this->sanitize($contributor['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['email'][0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ if ($name !== null || $email !== null || $url !== null)
+ {
+ $contributors[] = $this->registry->create('Author', array($name, $url, $email));
+ }
+ }
+
+ if (!empty($contributors))
+ {
+ return array_unique($contributors);
+ }
+
+ return null;
+ }
+
+ public function get_link($key = 0, $rel = 'alternate')
+ {
+ $links = $this->get_links($rel);
+ if (isset($links[$key]))
+ {
+ return $links[$key];
+ }
+
+ return null;
+ }
+
+ /**
+ * Added for parity between the parent-level and the item/entry-level.
+ */
+ public function get_permalink()
+ {
+ return $this->get_link(0);
+ }
+
+ public function get_links($rel = 'alternate')
+ {
+ if (!isset($this->data['links']))
+ {
+ $this->data['links'] = array();
+ if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'link'))
+ {
+ foreach ($links as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+ }
+ }
+ }
+ if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'link'))
+ {
+ foreach ($links as $link)
+ {
+ if (isset($link['attribs']['']['href']))
+ {
+ $link_rel = (isset($link['attribs']['']['rel'])) ? $link['attribs']['']['rel'] : 'alternate';
+ $this->data['links'][$link_rel][] = $this->sanitize($link['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($link));
+
+ }
+ }
+ }
+ if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+ if ($links = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'link'))
+ {
+ $this->data['links']['alternate'][] = $this->sanitize($links[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($links[0]));
+ }
+
+ $keys = array_keys($this->data['links']);
+ foreach ($keys as $key)
+ {
+ if ($this->registry->call('Misc', 'is_isegment_nz_nc', array($key)))
+ {
+ if (isset($this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]))
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] = array_merge($this->data['links'][$key], $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key]);
+ $this->data['links'][$key] =& $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key];
+ }
+ else
+ {
+ $this->data['links'][SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY . $key] =& $this->data['links'][$key];
+ }
+ }
+ elseif (substr($key, 0, 41) === SIMPLEPIE_IANA_LINK_RELATIONS_REGISTRY)
+ {
+ $this->data['links'][substr($key, 41)] =& $this->data['links'][$key];
+ }
+ $this->data['links'][$key] = array_unique($this->data['links'][$key]);
+ }
+ }
+
+ if (isset($this->data['links'][$rel]))
+ {
+ return $this->data['links'][$rel];
+ }
+
+ return null;
+ }
+
+ public function get_description()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'tagline'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_10, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_090, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_MAYBE_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'description'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'summary'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'subtitle'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_HTML, $this->get_base($return[0]));
+ }
+
+ return null;
+ }
+
+ public function get_copyright()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_10_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_03, 'copyright'))
+ {
+ return $this->sanitize($return[0]['data'], $this->registry->call('Misc', 'atom_03_construct_type', array($return[0]['attribs'])), $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'copyright'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'rights'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+
+ return null;
+ }
+
+ public function get_language()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_RSS_20, 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_11, 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_DC_10, 'language'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+ elseif (isset($this->data['xml_lang']))
+ {
+ return $this->sanitize($this->data['xml_lang'], SIMPLEPIE_CONSTRUCT_TEXT);
+ }
+
+ return null;
+ }
+
+ public function get_latitude()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lat'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
+ {
+ return (float) $match[1];
+ }
+
+ return null;
+ }
+
+ public function get_longitude()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'long'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_W3C_BASIC_GEO, 'lon'))
+ {
+ return (float) $return[0]['data'];
+ }
+ elseif (($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_GEORSS, 'point')) && preg_match('/^((?:-)?[0-9]+(?:\.[0-9]+)) ((?:-)?[0-9]+(?:\.[0-9]+))$/', trim($return[0]['data']), $match))
+ {
+ return (float) $match[2];
+ }
+
+ return null;
+ }
+
+ public function get_image_url()
+ {
+ if ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ITUNES, 'image'))
+ {
+ return $this->sanitize($return[0]['attribs']['']['href'], SIMPLEPIE_CONSTRUCT_IRI);
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'logo'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+ elseif ($return = $this->get_source_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'icon'))
+ {
+ return $this->sanitize($return[0]['data'], SIMPLEPIE_CONSTRUCT_IRI, $this->get_base($return[0]));
+ }
+
+ return null;
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/XML/Declaration/Parser.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/XML/Declaration/Parser.php
new file mode 100644
index 0000000..0c857a5
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/XML/Declaration/Parser.php
@@ -0,0 +1,359 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+
+/**
+ * Parses the XML Declaration
+ *
+ * @package SimplePie
+ * @subpackage Parsing
+ */
+class SimplePie_XML_Declaration_Parser
+{
+ /**
+ * XML Version
+ *
+ * @access public
+ * @var string
+ */
+ var $version = '1.0';
+
+ /**
+ * Encoding
+ *
+ * @access public
+ * @var string
+ */
+ var $encoding = 'UTF-8';
+
+ /**
+ * Standalone
+ *
+ * @access public
+ * @var bool
+ */
+ var $standalone = false;
+
+ /**
+ * Current state of the state machine
+ *
+ * @access private
+ * @var string
+ */
+ var $state = 'before_version_name';
+
+ /**
+ * Input data
+ *
+ * @access private
+ * @var string
+ */
+ var $data = '';
+
+ /**
+ * Input data length (to avoid calling strlen() everytime this is needed)
+ *
+ * @access private
+ * @var int
+ */
+ var $data_length = 0;
+
+ /**
+ * Current position of the pointer
+ *
+ * @var int
+ * @access private
+ */
+ var $position = 0;
+
+ /**
+ * Create an instance of the class with the input data
+ *
+ * @access public
+ * @param string $data Input data
+ */
+ public function __construct($data)
+ {
+ $this->data = $data;
+ $this->data_length = strlen($this->data);
+ }
+
+ /**
+ * Parse the input data
+ *
+ * @access public
+ * @return bool true on success, false on failure
+ */
+ public function parse()
+ {
+ while ($this->state && $this->state !== 'emit' && $this->has_data())
+ {
+ $state = $this->state;
+ $this->$state();
+ }
+ $this->data = '';
+ if ($this->state === 'emit')
+ {
+ return true;
+ }
+
+ $this->version = '';
+ $this->encoding = '';
+ $this->standalone = '';
+ return false;
+ }
+
+ /**
+ * Check whether there is data beyond the pointer
+ *
+ * @access private
+ * @return bool true if there is further data, false if not
+ */
+ public function has_data()
+ {
+ return (bool) ($this->position < $this->data_length);
+ }
+
+ /**
+ * Advance past any whitespace
+ *
+ * @return int Number of whitespace characters passed
+ */
+ public function skip_whitespace()
+ {
+ $whitespace = strspn($this->data, "\x09\x0A\x0D\x20", $this->position);
+ $this->position += $whitespace;
+ return $whitespace;
+ }
+
+ /**
+ * Read value
+ */
+ public function get_value()
+ {
+ $quote = substr($this->data, $this->position, 1);
+ if ($quote === '"' || $quote === "'")
+ {
+ $this->position++;
+ $len = strcspn($this->data, $quote, $this->position);
+ if ($this->has_data())
+ {
+ $value = substr($this->data, $this->position, $len);
+ $this->position += $len + 1;
+ return $value;
+ }
+ }
+ return false;
+ }
+
+ public function before_version_name()
+ {
+ if ($this->skip_whitespace())
+ {
+ $this->state = 'version_name';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ public function version_name()
+ {
+ if (substr($this->data, $this->position, 7) === 'version')
+ {
+ $this->position += 7;
+ $this->skip_whitespace();
+ $this->state = 'version_equals';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ public function version_equals()
+ {
+ if (substr($this->data, $this->position, 1) === '=')
+ {
+ $this->position++;
+ $this->skip_whitespace();
+ $this->state = 'version_value';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ public function version_value()
+ {
+ if ($this->version = $this->get_value())
+ {
+ $this->skip_whitespace();
+ if ($this->has_data())
+ {
+ $this->state = 'encoding_name';
+ }
+ else
+ {
+ $this->state = 'emit';
+ }
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ public function encoding_name()
+ {
+ if (substr($this->data, $this->position, 8) === 'encoding')
+ {
+ $this->position += 8;
+ $this->skip_whitespace();
+ $this->state = 'encoding_equals';
+ }
+ else
+ {
+ $this->state = 'standalone_name';
+ }
+ }
+
+ public function encoding_equals()
+ {
+ if (substr($this->data, $this->position, 1) === '=')
+ {
+ $this->position++;
+ $this->skip_whitespace();
+ $this->state = 'encoding_value';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ public function encoding_value()
+ {
+ if ($this->encoding = $this->get_value())
+ {
+ $this->skip_whitespace();
+ if ($this->has_data())
+ {
+ $this->state = 'standalone_name';
+ }
+ else
+ {
+ $this->state = 'emit';
+ }
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ public function standalone_name()
+ {
+ if (substr($this->data, $this->position, 10) === 'standalone')
+ {
+ $this->position += 10;
+ $this->skip_whitespace();
+ $this->state = 'standalone_equals';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ public function standalone_equals()
+ {
+ if (substr($this->data, $this->position, 1) === '=')
+ {
+ $this->position++;
+ $this->skip_whitespace();
+ $this->state = 'standalone_value';
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+
+ public function standalone_value()
+ {
+ if ($standalone = $this->get_value())
+ {
+ switch ($standalone)
+ {
+ case 'yes':
+ $this->standalone = true;
+ break;
+
+ case 'no':
+ $this->standalone = false;
+ break;
+
+ default:
+ $this->state = false;
+ return;
+ }
+
+ $this->skip_whitespace();
+ if ($this->has_data())
+ {
+ $this->state = false;
+ }
+ else
+ {
+ $this->state = 'emit';
+ }
+ }
+ else
+ {
+ $this->state = false;
+ }
+ }
+}
diff --git a/platform/www/vendor/simplepie/simplepie/library/SimplePie/gzdecode.php b/platform/www/vendor/simplepie/simplepie/library/SimplePie/gzdecode.php
new file mode 100644
index 0000000..9c54f88
--- /dev/null
+++ b/platform/www/vendor/simplepie/simplepie/library/SimplePie/gzdecode.php
@@ -0,0 +1,366 @@
+<?php
+/**
+ * SimplePie
+ *
+ * A PHP-Based RSS and Atom Feed Framework.
+ * Takes the hard work out of managing a complete RSS/Atom solution.
+ *
+ * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * * Neither the name of the SimplePie Team nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
+ * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @package SimplePie
+ * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue
+ * @author Ryan Parman
+ * @author Sam Sneddon
+ * @author Ryan McCue
+ * @link http://simplepie.org/ SimplePie
+ * @license http://www.opensource.org/licenses/bsd-license.php BSD License
+ */
+
+
+/**
+ * Decode 'gzip' encoded HTTP data
+ *
+ * @package SimplePie
+ * @subpackage HTTP
+ * @link http://www.gzip.org/format.txt
+ */
+class SimplePie_gzdecode
+{
+ /**
+ * Compressed data
+ *
+ * @access private
+ * @var string
+ * @see gzdecode::$data
+ */
+ var $compressed_data;
+
+ /**
+ * Size of compressed data
+ *
+ * @access private
+ * @var int
+ */
+ var $compressed_size;
+
+ /**
+ * Minimum size of a valid gzip string
+ *
+ * @access private
+ * @var int
+ */
+ var $min_compressed_size = 18;
+
+ /**
+ * Current position of pointer
+ *
+ * @access private
+ * @var int
+ */
+ var $position = 0;
+
+ /**
+ * Flags (FLG)
+ *
+ * @access private
+ * @var int
+ */
+ var $flags;
+
+ /**
+ * Uncompressed data
+ *
+ * @access public
+ * @see gzdecode::$compressed_data
+ * @var string
+ */
+ var $data;
+
+ /**
+ * Modified time
+ *
+ * @access public
+ * @var int
+ */
+ var $MTIME;
+
+ /**
+ * Extra Flags
+ *
+ * @access public
+ * @var int
+ */
+ var $XFL;
+
+ /**
+ * Operating System
+ *
+ * @access public
+ * @var int
+ */
+ var $OS;
+
+ /**
+ * Subfield ID 1
+ *
+ * @access public
+ * @see gzdecode::$extra_field
+ * @see gzdecode::$SI2
+ * @var string
+ */
+ var $SI1;
+
+ /**
+ * Subfield ID 2
+ *
+ * @access public
+ * @see gzdecode::$extra_field
+ * @see gzdecode::$SI1
+ * @var string
+ */
+ var $SI2;
+
+ /**
+ * Extra field content
+ *
+ * @access public
+ * @see gzdecode::$SI1
+ * @see gzdecode::$SI2
+ * @var string
+ */
+ var $extra_field;
+
+ /**
+ * Original filename
+ *
+ * @access public
+ * @var string
+ */
+ var $filename;
+
+ /**
+ * Human readable comment
+ *
+ * @access public
+ * @var string
+ */
+ var $comment;
+
+ /**
+ * Don't allow anything to be set
+ *
+ * @param string $name
+ * @param mixed $value
+ */
+ public function __set($name, $value)
+ {
+ trigger_error("Cannot write property $name", E_USER_ERROR);
+ }
+
+ /**
+ * Set the compressed string and related properties
+ *
+ * @param string $data
+ */
+ public function __construct($data)
+ {
+ $this->compressed_data = $data;
+ $this->compressed_size = strlen($data);
+ }
+
+ /**
+ * Decode the GZIP stream
+ *
+ * @return bool Successfulness
+ */
+ public function parse()
+ {
+ if ($this->compressed_size >= $this->min_compressed_size)
+ {
+ // Check ID1, ID2, and CM
+ if (substr($this->compressed_data, 0, 3) !== "\x1F\x8B\x08")
+ {
+ return false;
+ }
+
+ // Get the FLG (FLaGs)
+ $this->flags = ord($this->compressed_data[3]);
+
+ // FLG bits above (1 << 4) are reserved
+ if ($this->flags > 0x1F)
+ {
+ return false;
+ }
+
+ // Advance the pointer after the above
+ $this->position += 4;
+
+ // MTIME
+ $mtime = substr($this->compressed_data, $this->position, 4);
+ // Reverse the string if we're on a big-endian arch because l is the only signed long and is machine endianness
+ if (current(unpack('S', "\x00\x01")) === 1)
+ {
+ $mtime = strrev($mtime);
+ }
+ $this->MTIME = current(unpack('l', $mtime));
+ $this->position += 4;
+
+ // Get the XFL (eXtra FLags)
+ $this->XFL = ord($this->compressed_data[$this->position++]);
+
+ // Get the OS (Operating System)
+ $this->OS = ord($this->compressed_data[$this->position++]);
+
+ // Parse the FEXTRA
+ if ($this->flags & 4)
+ {
+ // Read subfield IDs
+ $this->SI1 = $this->compressed_data[$this->position++];
+ $this->SI2 = $this->compressed_data[$this->position++];
+
+ // SI2 set to zero is reserved for future use
+ if ($this->SI2 === "\x00")
+ {
+ return false;
+ }
+
+ // Get the length of the extra field
+ $len = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
+ $this->position += 2;
+
+ // Check the length of the string is still valid
+ $this->min_compressed_size += $len + 4;
+ if ($this->compressed_size >= $this->min_compressed_size)
+ {
+ // Set the extra field to the given data
+ $this->extra_field = substr($this->compressed_data, $this->position, $len);
+ $this->position += $len;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // Parse the FNAME
+ if ($this->flags & 8)
+ {
+ // Get the length of the filename
+ $len = strcspn($this->compressed_data, "\x00", $this->position);
+
+ // Check the length of the string is still valid
+ $this->min_compressed_size += $len + 1;
+ if ($this->compressed_size >= $this->min_compressed_size)
+ {
+ // Set the original filename to the given string
+ $this->filename = substr($this->compressed_data, $this->position, $len);
+ $this->position += $len + 1;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // Parse the FCOMMENT
+ if ($this->flags & 16)
+ {
+ // Get the length of the comment
+ $len = strcspn($this->compressed_data, "\x00", $this->position);
+
+ // Check the length of the string is still valid
+ $this->min_compressed_size += $len + 1;
+ if ($this->compressed_size >= $this->min_compressed_size)
+ {
+ // Set the original comment to the given string
+ $this->comment = substr($this->compressed_data, $this->position, $len);
+ $this->position += $len + 1;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // Parse the FHCRC
+ if ($this->flags & 2)
+ {
+ // Check the length of the string is still valid
+ $this->min_compressed_size += $len + 2;
+ if ($this->compressed_size >= $this->min_compressed_size)
+ {
+ // Read the CRC
+ $crc = current(unpack('v', substr($this->compressed_data, $this->position, 2)));
+
+ // Check the CRC matches
+ if ((crc32(substr($this->compressed_data, 0, $this->position)) & 0xFFFF) === $crc)
+ {
+ $this->position += 2;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ // Decompress the actual data
+ if (($this->data = gzinflate(substr($this->compressed_data, $this->position, -8))) === false)
+ {
+ return false;
+ }
+
+ $this->position = $this->compressed_size - 8;
+
+ // Check CRC of data
+ $crc = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
+ $this->position += 4;
+ /*if (extension_loaded('hash') && sprintf('%u', current(unpack('V', hash('crc32b', $this->data)))) !== sprintf('%u', $crc))
+ {
+ return false;
+ }*/
+
+ // Check ISIZE of data
+ $isize = current(unpack('V', substr($this->compressed_data, $this->position, 4)));
+ $this->position += 4;
+ if (sprintf('%u', strlen($this->data) & 0xFFFFFFFF) !== sprintf('%u', $isize))
+ {
+ return false;
+ }
+
+ // Wow, against all odds, we've actually got a valid gzip string
+ return true;
+ }
+
+ return false;
+ }
+}
diff --git a/platform/www/vendor/splitbrain/php-archive/LICENSE b/platform/www/vendor/splitbrain/php-archive/LICENSE
new file mode 100644
index 0000000..66d08e4
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-archive/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2015 Andreas Gohr <gohr@cosmocode.de>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE. \ No newline at end of file
diff --git a/platform/www/vendor/splitbrain/php-archive/README.md b/platform/www/vendor/splitbrain/php-archive/README.md
new file mode 100644
index 0000000..f18764b
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-archive/README.md
@@ -0,0 +1,70 @@
+PHPArchive - Pure PHP ZIP and TAR handling
+==========================================
+
+This library allows to handle new ZIP and TAR archives without the need for any special PHP extensions (gz and bzip are
+needed for compression). It can create new files or extract existing ones.
+
+To keep things simple, the modification (adding or removing files) of existing archives is not supported.
+
+[![Build Status](https://travis-ci.org/splitbrain/php-archive.svg)](https://travis-ci.org/splitbrain/php-archive)
+
+Install
+-------
+
+Use composer:
+
+```php composer.phar require splitbrain/php-archive```
+
+Usage
+-----
+
+The usage for the Zip and Tar classes are basically the same. Here are some
+examples for working with TARs to get you started.
+
+Check the [API docs](https://splitbrain.github.io/php-archive/) for more
+info.
+
+
+```php
+require_once 'vendor/autoload.php';
+use splitbrain\PHPArchive\Tar;
+
+// To list the contents of an existing TAR archive, open() it and use
+// contents() on it:
+$tar = new Tar();
+$tar->open('myfile.tgz');
+$toc = $tar->contents();
+print_r($toc); // array of FileInfo objects
+
+// To extract the contents of an existing TAR archive, open() it and use
+// extract() on it:
+$tar = new Tar();
+$tar->open('myfile.tgz');
+$tar->extract('/tmp');
+
+// To create a new TAR archive directly on the filesystem (low memory
+// requirements), create() it:
+$tar = new Tar();
+$tar->create('myfile.tgz');
+$tar->addFile(...);
+$tar->addData(...);
+...
+$tar->close();
+
+// To create a TAR archive directly in memory, create() it, add*()
+// files and then either save() or getArchive() it:
+$tar = new Tar();
+$tar->setCompression(9, Archive::COMPRESS_BZIP);
+$tar->create();
+$tar->addFile(...);
+$tar->addData(...);
+...
+$tar->save('myfile.tbz'); // compresses and saves it
+echo $tar->getArchive(); // compresses and returns it
+```
+
+Differences between Tar and Zip: Tars are compressed as a whole, while Zips compress each file individually. Therefore
+you can call ```setCompression``` before each ```addFile()``` and ```addData()``` function call.
+
+The FileInfo class can be used to specify additional info like ownership or permissions when adding a file to
+an archive.
diff --git a/platform/www/vendor/splitbrain/php-archive/phpunit.xml b/platform/www/vendor/splitbrain/php-archive/phpunit.xml
new file mode 100644
index 0000000..c5e1ad3
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-archive/phpunit.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit backupGlobals="false"
+ backupStaticAttributes="false"
+ bootstrap="vendor/autoload.php"
+ colors="true"
+ convertErrorsToExceptions="true"
+ convertNoticesToExceptions="true"
+ convertWarningsToExceptions="true"
+ processIsolation="false"
+ stopOnFailure="false"
+ syntaxCheck="false">
+ <testsuites>
+ <testsuite name="Test Suite">
+ <directory suffix=".php">./tests/</directory>
+ </testsuite>
+ </testsuites>
+ <filter>
+ <whitelist processUncoveredFilesFromWhitelist="false">
+ <directory suffix=".php">src</directory>
+ </whitelist>
+ </filter>
+</phpunit>
diff --git a/platform/www/vendor/splitbrain/php-archive/src/Archive.php b/platform/www/vendor/splitbrain/php-archive/src/Archive.php
new file mode 100644
index 0000000..45c87fd
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-archive/src/Archive.php
@@ -0,0 +1,135 @@
+<?php
+
+namespace splitbrain\PHPArchive;
+
+abstract class Archive
+{
+
+ const COMPRESS_AUTO = -1;
+ const COMPRESS_NONE = 0;
+ const COMPRESS_GZIP = 1;
+ const COMPRESS_BZIP = 2;
+
+ /** @var callable */
+ protected $callback;
+
+ /**
+ * Set the compression level and type
+ *
+ * @param int $level Compression level (0 to 9)
+ * @param int $type Type of compression to use (use COMPRESS_* constants)
+ * @throws ArchiveIllegalCompressionException
+ */
+ abstract public function setCompression($level = 9, $type = Archive::COMPRESS_AUTO);
+
+ /**
+ * Open an existing archive file for reading
+ *
+ * @param string $file
+ * @throws ArchiveIOException
+ */
+ abstract public function open($file);
+
+ /**
+ * Read the contents of an archive
+ *
+ * This function lists the files stored in the archive, and returns an indexed array of FileInfo objects
+ *
+ * The archive is closed afer reading the contents, because rewinding is not possible in bzip2 streams.
+ * Reopen the file with open() again if you want to do additional operations
+ *
+ * @return FileInfo[]
+ */
+ abstract public function contents();
+
+ /**
+ * Extract an existing archive
+ *
+ * The $strip parameter allows you to strip a certain number of path components from the filenames
+ * found in the archive file, similar to the --strip-components feature of GNU tar. This is triggered when
+ * an integer is passed as $strip.
+ * Alternatively a fixed string prefix may be passed in $strip. If the filename matches this prefix,
+ * the prefix will be stripped. It is recommended to give prefixes with a trailing slash.
+ *
+ * By default this will extract all files found in the archive. You can restrict the output using the $include
+ * and $exclude parameter. Both expect a full regular expression (including delimiters and modifiers). If
+ * $include is set, only files that match this expression will be extracted. Files that match the $exclude
+ * expression will never be extracted. Both parameters can be used in combination. Expressions are matched against
+ * stripped filenames as described above.
+ *
+ * The archive is closed afterwards. Reopen the file with open() again if you want to do additional operations
+ *
+ * @param string $outdir the target directory for extracting
+ * @param int|string $strip either the number of path components or a fixed prefix to strip
+ * @param string $exclude a regular expression of files to exclude
+ * @param string $include a regular expression of files to include
+ * @throws ArchiveIOException
+ * @return array
+ */
+ abstract public function extract($outdir, $strip = '', $exclude = '', $include = '');
+
+ /**
+ * Create a new archive file
+ *
+ * If $file is empty, the archive file will be created in memory
+ *
+ * @param string $file
+ */
+ abstract public function create($file = '');
+
+ /**
+ * Add a file to the current archive using an existing file in the filesystem
+ *
+ * @param string $file path to the original file
+ * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data, empty to take from original
+ * @throws ArchiveIOException
+ */
+ abstract public function addFile($file, $fileinfo = '');
+
+ /**
+ * Add a file to the current archive using the given $data as content
+ *
+ * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data
+ * @param string $data binary content of the file to add
+ * @throws ArchiveIOException
+ */
+ abstract public function addData($fileinfo, $data);
+
+ /**
+ * Close the archive, close all file handles
+ *
+ * After a call to this function no more data can be added to the archive, for
+ * read access no reading is allowed anymore
+ */
+ abstract public function close();
+
+ /**
+ * Returns the created in-memory archive data
+ *
+ * This implicitly calls close() on the Archive
+ */
+ abstract public function getArchive();
+
+ /**
+ * Save the created in-memory archive data
+ *
+ * Note: It is more memory effective to specify the filename in the create() function and
+ * let the library work on the new file directly.
+ *
+ * @param string $file
+ */
+ abstract public function save($file);
+
+ /**
+ * Set a callback function to be called whenever a file is added or extracted.
+ *
+ * The callback is called with a FileInfo object as parameter. You can use this to show progress
+ * info during an operation.
+ *
+ * @param callable $callback
+ */
+ public function setCallback($callback)
+ {
+ $this->callback = $callback;
+ }
+}
diff --git a/platform/www/vendor/splitbrain/php-archive/src/ArchiveCorruptedException.php b/platform/www/vendor/splitbrain/php-archive/src/ArchiveCorruptedException.php
new file mode 100644
index 0000000..a87cff4
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-archive/src/ArchiveCorruptedException.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace splitbrain\PHPArchive;
+
+/**
+ * The archive is unreadable
+ */
+class ArchiveCorruptedException extends \Exception
+{
+} \ No newline at end of file
diff --git a/platform/www/vendor/splitbrain/php-archive/src/ArchiveIOException.php b/platform/www/vendor/splitbrain/php-archive/src/ArchiveIOException.php
new file mode 100644
index 0000000..6128caf
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-archive/src/ArchiveIOException.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace splitbrain\PHPArchive;
+
+/**
+ * Read/Write Errors
+ */
+class ArchiveIOException extends \Exception
+{
+} \ No newline at end of file
diff --git a/platform/www/vendor/splitbrain/php-archive/src/ArchiveIllegalCompressionException.php b/platform/www/vendor/splitbrain/php-archive/src/ArchiveIllegalCompressionException.php
new file mode 100644
index 0000000..40a680f
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-archive/src/ArchiveIllegalCompressionException.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace splitbrain\PHPArchive;
+
+/**
+ * Bad or unsupported compression settings requested
+ */
+class ArchiveIllegalCompressionException extends \Exception
+{
+} \ No newline at end of file
diff --git a/platform/www/vendor/splitbrain/php-archive/src/FileInfo.php b/platform/www/vendor/splitbrain/php-archive/src/FileInfo.php
new file mode 100644
index 0000000..11fca7e
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-archive/src/FileInfo.php
@@ -0,0 +1,340 @@
+<?php
+
+namespace splitbrain\PHPArchive;
+
+/**
+ * Class FileInfo
+ *
+ * stores meta data about a file in an Archive
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @package splitbrain\PHPArchive
+ * @license MIT
+ */
+class FileInfo
+{
+
+ protected $isdir = false;
+ protected $path = '';
+ protected $size = 0;
+ protected $csize = 0;
+ protected $mtime = 0;
+ protected $mode = 0664;
+ protected $owner = '';
+ protected $group = '';
+ protected $uid = 0;
+ protected $gid = 0;
+ protected $comment = '';
+
+ /**
+ * initialize dynamic defaults
+ *
+ * @param string $path The path of the file, can also be set later through setPath()
+ */
+ public function __construct($path = '')
+ {
+ $this->mtime = time();
+ $this->setPath($path);
+ }
+
+ /**
+ * Factory to build FileInfo from existing file or directory
+ *
+ * @param string $path path to a file on the local file system
+ * @param string $as optional path to use inside the archive
+ * @throws FileInfoException
+ * @return FileInfo
+ */
+ public static function fromPath($path, $as = '')
+ {
+ clearstatcache(false, $path);
+
+ if (!file_exists($path)) {
+ throw new FileInfoException("$path does not exist");
+ }
+
+ $stat = stat($path);
+ $file = new FileInfo();
+
+ $file->setPath($path);
+ $file->setIsdir(is_dir($path));
+ $file->setMode(fileperms($path));
+ $file->setOwner(fileowner($path));
+ $file->setGroup(filegroup($path));
+ $file->setSize(filesize($path));
+ $file->setUid($stat['uid']);
+ $file->setGid($stat['gid']);
+ $file->setMtime($stat['mtime']);
+
+ if ($as) {
+ $file->setPath($as);
+ }
+
+ return $file;
+ }
+
+ /**
+ * @return int the filesize. always 0 for directories
+ */
+ public function getSize()
+ {
+ if($this->isdir) return 0;
+ return $this->size;
+ }
+
+ /**
+ * @param int $size
+ */
+ public function setSize($size)
+ {
+ $this->size = $size;
+ }
+
+ /**
+ * @return int
+ */
+ public function getCompressedSize()
+ {
+ return $this->csize;
+ }
+
+ /**
+ * @param int $csize
+ */
+ public function setCompressedSize($csize)
+ {
+ $this->csize = $csize;
+ }
+
+ /**
+ * @return int
+ */
+ public function getMtime()
+ {
+ return $this->mtime;
+ }
+
+ /**
+ * @param int $mtime
+ */
+ public function setMtime($mtime)
+ {
+ $this->mtime = $mtime;
+ }
+
+ /**
+ * @return int
+ */
+ public function getGid()
+ {
+ return $this->gid;
+ }
+
+ /**
+ * @param int $gid
+ */
+ public function setGid($gid)
+ {
+ $this->gid = $gid;
+ }
+
+ /**
+ * @return int
+ */
+ public function getUid()
+ {
+ return $this->uid;
+ }
+
+ /**
+ * @param int $uid
+ */
+ public function setUid($uid)
+ {
+ $this->uid = $uid;
+ }
+
+ /**
+ * @return string
+ */
+ public function getComment()
+ {
+ return $this->comment;
+ }
+
+ /**
+ * @param string $comment
+ */
+ public function setComment($comment)
+ {
+ $this->comment = $comment;
+ }
+
+ /**
+ * @return string
+ */
+ public function getGroup()
+ {
+ return $this->group;
+ }
+
+ /**
+ * @param string $group
+ */
+ public function setGroup($group)
+ {
+ $this->group = $group;
+ }
+
+ /**
+ * @return boolean
+ */
+ public function getIsdir()
+ {
+ return $this->isdir;
+ }
+
+ /**
+ * @param boolean $isdir
+ */
+ public function setIsdir($isdir)
+ {
+ // default mode for directories
+ if ($isdir && $this->mode === 0664) {
+ $this->mode = 0775;
+ }
+ $this->isdir = $isdir;
+ }
+
+ /**
+ * @return int
+ */
+ public function getMode()
+ {
+ return $this->mode;
+ }
+
+ /**
+ * @param int $mode
+ */
+ public function setMode($mode)
+ {
+ $this->mode = $mode;
+ }
+
+ /**
+ * @return string
+ */
+ public function getOwner()
+ {
+ return $this->owner;
+ }
+
+ /**
+ * @param string $owner
+ */
+ public function setOwner($owner)
+ {
+ $this->owner = $owner;
+ }
+
+ /**
+ * @return string
+ */
+ public function getPath()
+ {
+ return $this->path;
+ }
+
+ /**
+ * @param string $path
+ */
+ public function setPath($path)
+ {
+ $this->path = $this->cleanPath($path);
+ }
+
+ /**
+ * Cleans up a path and removes relative parts, also strips leading slashes
+ *
+ * @param string $path
+ * @return string
+ */
+ protected function cleanPath($path)
+ {
+ $path = str_replace('\\', '/', $path);
+ $path = explode('/', $path);
+ $newpath = array();
+ foreach ($path as $p) {
+ if ($p === '' || $p === '.') {
+ continue;
+ }
+ if ($p === '..') {
+ array_pop($newpath);
+ continue;
+ }
+ array_push($newpath, $p);
+ }
+ return trim(implode('/', $newpath), '/');
+ }
+
+ /**
+ * Strip given prefix or number of path segments from the filename
+ *
+ * The $strip parameter allows you to strip a certain number of path components from the filenames
+ * found in the tar file, similar to the --strip-components feature of GNU tar. This is triggered when
+ * an integer is passed as $strip.
+ * Alternatively a fixed string prefix may be passed in $strip. If the filename matches this prefix,
+ * the prefix will be stripped. It is recommended to give prefixes with a trailing slash.
+ *
+ * @param int|string $strip
+ */
+ public function strip($strip)
+ {
+ $filename = $this->getPath();
+ $striplen = strlen($strip);
+ if (is_int($strip)) {
+ // if $strip is an integer we strip this many path components
+ $parts = explode('/', $filename);
+ if (!$this->getIsdir()) {
+ $base = array_pop($parts); // keep filename itself
+ } else {
+ $base = '';
+ }
+ $filename = join('/', array_slice($parts, $strip));
+ if ($base) {
+ $filename .= "/$base";
+ }
+ } else {
+ // if strip is a string, we strip a prefix here
+ if (substr($filename, 0, $striplen) == $strip) {
+ $filename = substr($filename, $striplen);
+ }
+ }
+
+ $this->setPath($filename);
+ }
+
+ /**
+ * Does the file match the given include and exclude expressions?
+ *
+ * Exclude rules take precedence over include rules
+ *
+ * @param string $include Regular expression of files to include
+ * @param string $exclude Regular expression of files to exclude
+ * @return bool
+ */
+ public function match($include = '', $exclude = '')
+ {
+ $extract = true;
+ if ($include && !preg_match($include, $this->getPath())) {
+ $extract = false;
+ }
+ if ($exclude && preg_match($exclude, $this->getPath())) {
+ $extract = false;
+ }
+
+ return $extract;
+ }
+}
+
diff --git a/platform/www/vendor/splitbrain/php-archive/src/FileInfoException.php b/platform/www/vendor/splitbrain/php-archive/src/FileInfoException.php
new file mode 100644
index 0000000..9c6acaa
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-archive/src/FileInfoException.php
@@ -0,0 +1,10 @@
+<?php
+
+namespace splitbrain\PHPArchive;
+
+/**
+ * File meta data problems
+ */
+class FileInfoException extends \Exception
+{
+} \ No newline at end of file
diff --git a/platform/www/vendor/splitbrain/php-archive/src/Tar.php b/platform/www/vendor/splitbrain/php-archive/src/Tar.php
new file mode 100644
index 0000000..9550b6c
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-archive/src/Tar.php
@@ -0,0 +1,692 @@
+<?php
+
+namespace splitbrain\PHPArchive;
+
+/**
+ * Class Tar
+ *
+ * Creates or extracts Tar archives. Supports gz and bzip compression
+ *
+ * Long pathnames (>100 chars) are supported in POSIX ustar and GNU longlink formats.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @package splitbrain\PHPArchive
+ * @license MIT
+ */
+class Tar extends Archive
+{
+
+ protected $file = '';
+ protected $comptype = Archive::COMPRESS_AUTO;
+ protected $complevel = 9;
+ protected $fh;
+ protected $memory = '';
+ protected $closed = true;
+ protected $writeaccess = false;
+
+ /**
+ * Sets the compression to use
+ *
+ * @param int $level Compression level (0 to 9)
+ * @param int $type Type of compression to use (use COMPRESS_* constants)
+ * @throws ArchiveIllegalCompressionException
+ */
+ public function setCompression($level = 9, $type = Archive::COMPRESS_AUTO)
+ {
+ $this->compressioncheck($type);
+ if ($level < -1 || $level > 9) {
+ throw new ArchiveIllegalCompressionException('Compression level should be between -1 and 9');
+ }
+ $this->comptype = $type;
+ $this->complevel = $level;
+ if($level == 0) $this->comptype = Archive::COMPRESS_NONE;
+ if($type == Archive::COMPRESS_NONE) $this->complevel = 0;
+ }
+
+ /**
+ * Open an existing TAR file for reading
+ *
+ * @param string $file
+ * @throws ArchiveIOException
+ * @throws ArchiveIllegalCompressionException
+ */
+ public function open($file)
+ {
+ $this->file = $file;
+
+ // update compression to mach file
+ if ($this->comptype == Tar::COMPRESS_AUTO) {
+ $this->setCompression($this->complevel, $this->filetype($file));
+ }
+
+ // open file handles
+ if ($this->comptype === Archive::COMPRESS_GZIP) {
+ $this->fh = @gzopen($this->file, 'rb');
+ } elseif ($this->comptype === Archive::COMPRESS_BZIP) {
+ $this->fh = @bzopen($this->file, 'r');
+ } else {
+ $this->fh = @fopen($this->file, 'rb');
+ }
+
+ if (!$this->fh) {
+ throw new ArchiveIOException('Could not open file for reading: '.$this->file);
+ }
+ $this->closed = false;
+ }
+
+ /**
+ * Read the contents of a TAR archive
+ *
+ * This function lists the files stored in the archive
+ *
+ * The archive is closed afer reading the contents, because rewinding is not possible in bzip2 streams.
+ * Reopen the file with open() again if you want to do additional operations
+ *
+ * @throws ArchiveIOException
+ * @throws ArchiveCorruptedException
+ * @returns FileInfo[]
+ */
+ public function contents()
+ {
+ if ($this->closed || !$this->file) {
+ throw new ArchiveIOException('Can not read from a closed archive');
+ }
+
+ $result = array();
+ while ($read = $this->readbytes(512)) {
+ $header = $this->parseHeader($read);
+ if (!is_array($header)) {
+ continue;
+ }
+
+ $this->skipbytes(ceil($header['size'] / 512) * 512);
+ $result[] = $this->header2fileinfo($header);
+ }
+
+ $this->close();
+ return $result;
+ }
+
+ /**
+ * Extract an existing TAR archive
+ *
+ * The $strip parameter allows you to strip a certain number of path components from the filenames
+ * found in the tar file, similar to the --strip-components feature of GNU tar. This is triggered when
+ * an integer is passed as $strip.
+ * Alternatively a fixed string prefix may be passed in $strip. If the filename matches this prefix,
+ * the prefix will be stripped. It is recommended to give prefixes with a trailing slash.
+ *
+ * By default this will extract all files found in the archive. You can restrict the output using the $include
+ * and $exclude parameter. Both expect a full regular expression (including delimiters and modifiers). If
+ * $include is set only files that match this expression will be extracted. Files that match the $exclude
+ * expression will never be extracted. Both parameters can be used in combination. Expressions are matched against
+ * stripped filenames as described above.
+ *
+ * The archive is closed afer reading the contents, because rewinding is not possible in bzip2 streams.
+ * Reopen the file with open() again if you want to do additional operations
+ *
+ * @param string $outdir the target directory for extracting
+ * @param int|string $strip either the number of path components or a fixed prefix to strip
+ * @param string $exclude a regular expression of files to exclude
+ * @param string $include a regular expression of files to include
+ * @throws ArchiveIOException
+ * @throws ArchiveCorruptedException
+ * @return FileInfo[]
+ */
+ public function extract($outdir, $strip = '', $exclude = '', $include = '')
+ {
+ if ($this->closed || !$this->file) {
+ throw new ArchiveIOException('Can not read from a closed archive');
+ }
+
+ $outdir = rtrim($outdir, '/');
+ @mkdir($outdir, 0777, true);
+ if (!is_dir($outdir)) {
+ throw new ArchiveIOException("Could not create directory '$outdir'");
+ }
+
+ $extracted = array();
+ while ($dat = $this->readbytes(512)) {
+ // read the file header
+ $header = $this->parseHeader($dat);
+ if (!is_array($header)) {
+ continue;
+ }
+ $fileinfo = $this->header2fileinfo($header);
+
+ // apply strip rules
+ $fileinfo->strip($strip);
+
+ // skip unwanted files
+ if (!strlen($fileinfo->getPath()) || !$fileinfo->match($include, $exclude)) {
+ $this->skipbytes(ceil($header['size'] / 512) * 512);
+ continue;
+ }
+
+ // create output directory
+ $output = $outdir.'/'.$fileinfo->getPath();
+ $directory = ($fileinfo->getIsdir()) ? $output : dirname($output);
+ @mkdir($directory, 0777, true);
+
+ // extract data
+ if (!$fileinfo->getIsdir()) {
+ $fp = @fopen($output, "wb");
+ if (!$fp) {
+ throw new ArchiveIOException('Could not open file for writing: '.$output);
+ }
+
+ $size = floor($header['size'] / 512);
+ for ($i = 0; $i < $size; $i++) {
+ fwrite($fp, $this->readbytes(512), 512);
+ }
+ if (($header['size'] % 512) != 0) {
+ fwrite($fp, $this->readbytes(512), $header['size'] % 512);
+ }
+
+ fclose($fp);
+ @touch($output, $fileinfo->getMtime());
+ @chmod($output, $fileinfo->getMode());
+ } else {
+ $this->skipbytes(ceil($header['size'] / 512) * 512); // the size is usually 0 for directories
+ }
+
+ if(is_callable($this->callback)) {
+ call_user_func($this->callback, $fileinfo);
+ }
+ $extracted[] = $fileinfo;
+ }
+
+ $this->close();
+ return $extracted;
+ }
+
+ /**
+ * Create a new TAR file
+ *
+ * If $file is empty, the tar file will be created in memory
+ *
+ * @param string $file
+ * @throws ArchiveIOException
+ * @throws ArchiveIllegalCompressionException
+ */
+ public function create($file = '')
+ {
+ $this->file = $file;
+ $this->memory = '';
+ $this->fh = 0;
+
+ if ($this->file) {
+ // determine compression
+ if ($this->comptype == Archive::COMPRESS_AUTO) {
+ $this->setCompression($this->complevel, $this->filetype($file));
+ }
+
+ if ($this->comptype === Archive::COMPRESS_GZIP) {
+ $this->fh = @gzopen($this->file, 'wb'.$this->complevel);
+ } elseif ($this->comptype === Archive::COMPRESS_BZIP) {
+ $this->fh = @bzopen($this->file, 'w');
+ } else {
+ $this->fh = @fopen($this->file, 'wb');
+ }
+
+ if (!$this->fh) {
+ throw new ArchiveIOException('Could not open file for writing: '.$this->file);
+ }
+ }
+ $this->writeaccess = true;
+ $this->closed = false;
+ }
+
+ /**
+ * Add a file to the current TAR archive using an existing file in the filesystem
+ *
+ * @param string $file path to the original file
+ * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data, empty to take from original
+ * @throws ArchiveCorruptedException when the file changes while reading it, the archive will be corrupt and should be deleted
+ * @throws ArchiveIOException there was trouble reading the given file, it was not added
+ * @throws FileInfoException trouble reading file info, it was not added
+ */
+ public function addFile($file, $fileinfo = '')
+ {
+ if (is_string($fileinfo)) {
+ $fileinfo = FileInfo::fromPath($file, $fileinfo);
+ }
+
+ if ($this->closed) {
+ throw new ArchiveIOException('Archive has been closed, files can no longer be added');
+ }
+
+ $fp = @fopen($file, 'rb');
+ if (!$fp) {
+ throw new ArchiveIOException('Could not open file for reading: '.$file);
+ }
+
+ // create file header
+ $this->writeFileHeader($fileinfo);
+
+ // write data
+ $read = 0;
+ while (!feof($fp)) {
+ $data = fread($fp, 512);
+ $read += strlen($data);
+ if ($data === false) {
+ break;
+ }
+ if ($data === '') {
+ break;
+ }
+ $packed = pack("a512", $data);
+ $this->writebytes($packed);
+ }
+ fclose($fp);
+
+ if($read != $fileinfo->getSize()) {
+ $this->close();
+ throw new ArchiveCorruptedException("The size of $file changed while reading, archive corrupted. read $read expected ".$fileinfo->getSize());
+ }
+
+ if(is_callable($this->callback)) {
+ call_user_func($this->callback, $fileinfo);
+ }
+ }
+
+ /**
+ * Add a file to the current TAR archive using the given $data as content
+ *
+ * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data
+ * @param string $data binary content of the file to add
+ * @throws ArchiveIOException
+ */
+ public function addData($fileinfo, $data)
+ {
+ if (is_string($fileinfo)) {
+ $fileinfo = new FileInfo($fileinfo);
+ }
+
+ if ($this->closed) {
+ throw new ArchiveIOException('Archive has been closed, files can no longer be added');
+ }
+
+ $len = strlen($data);
+ $fileinfo->setSize($len);
+ $this->writeFileHeader($fileinfo);
+
+ for ($s = 0; $s < $len; $s += 512) {
+ $this->writebytes(pack("a512", substr($data, $s, 512)));
+ }
+
+ if (is_callable($this->callback)) {
+ call_user_func($this->callback, $fileinfo);
+ }
+ }
+
+ /**
+ * Add the closing footer to the archive if in write mode, close all file handles
+ *
+ * After a call to this function no more data can be added to the archive, for
+ * read access no reading is allowed anymore
+ *
+ * "Physically, an archive consists of a series of file entries terminated by an end-of-archive entry, which
+ * consists of two 512 blocks of zero bytes"
+ *
+ * @link http://www.gnu.org/software/tar/manual/html_chapter/tar_8.html#SEC134
+ * @throws ArchiveIOException
+ */
+ public function close()
+ {
+ if ($this->closed) {
+ return;
+ } // we did this already
+
+ // write footer
+ if ($this->writeaccess) {
+ $this->writebytes(pack("a512", ""));
+ $this->writebytes(pack("a512", ""));
+ }
+
+ // close file handles
+ if ($this->file) {
+ if ($this->comptype === Archive::COMPRESS_GZIP) {
+ gzclose($this->fh);
+ } elseif ($this->comptype === Archive::COMPRESS_BZIP) {
+ bzclose($this->fh);
+ } else {
+ fclose($this->fh);
+ }
+
+ $this->file = '';
+ $this->fh = 0;
+ }
+
+ $this->writeaccess = false;
+ $this->closed = true;
+ }
+
+ /**
+ * Returns the created in-memory archive data
+ *
+ * This implicitly calls close() on the Archive
+ * @throws ArchiveIOException
+ */
+ public function getArchive()
+ {
+ $this->close();
+
+ if ($this->comptype === Archive::COMPRESS_AUTO) {
+ $this->comptype = Archive::COMPRESS_NONE;
+ }
+
+ if ($this->comptype === Archive::COMPRESS_GZIP) {
+ return gzencode($this->memory, $this->complevel);
+ }
+ if ($this->comptype === Archive::COMPRESS_BZIP) {
+ return bzcompress($this->memory);
+ }
+ return $this->memory;
+ }
+
+ /**
+ * Save the created in-memory archive data
+ *
+ * Note: It more memory effective to specify the filename in the create() function and
+ * let the library work on the new file directly.
+ *
+ * @param string $file
+ * @throws ArchiveIOException
+ * @throws ArchiveIllegalCompressionException
+ */
+ public function save($file)
+ {
+ if ($this->comptype === Archive::COMPRESS_AUTO) {
+ $this->setCompression($this->complevel, $this->filetype($file));
+ }
+
+ if (!@file_put_contents($file, $this->getArchive())) {
+ throw new ArchiveIOException('Could not write to file: '.$file);
+ }
+ }
+
+ /**
+ * Read from the open file pointer
+ *
+ * @param int $length bytes to read
+ * @return string
+ */
+ protected function readbytes($length)
+ {
+ if ($this->comptype === Archive::COMPRESS_GZIP) {
+ return @gzread($this->fh, $length);
+ } elseif ($this->comptype === Archive::COMPRESS_BZIP) {
+ return @bzread($this->fh, $length);
+ } else {
+ return @fread($this->fh, $length);
+ }
+ }
+
+ /**
+ * Write to the open filepointer or memory
+ *
+ * @param string $data
+ * @throws ArchiveIOException
+ * @return int number of bytes written
+ */
+ protected function writebytes($data)
+ {
+ if (!$this->file) {
+ $this->memory .= $data;
+ $written = strlen($data);
+ } elseif ($this->comptype === Archive::COMPRESS_GZIP) {
+ $written = @gzwrite($this->fh, $data);
+ } elseif ($this->comptype === Archive::COMPRESS_BZIP) {
+ $written = @bzwrite($this->fh, $data);
+ } else {
+ $written = @fwrite($this->fh, $data);
+ }
+ if ($written === false) {
+ throw new ArchiveIOException('Failed to write to archive stream');
+ }
+ return $written;
+ }
+
+ /**
+ * Skip forward in the open file pointer
+ *
+ * This is basically a wrapper around seek() (and a workaround for bzip2)
+ *
+ * @param int $bytes seek to this position
+ */
+ protected function skipbytes($bytes)
+ {
+ if ($this->comptype === Archive::COMPRESS_GZIP) {
+ @gzseek($this->fh, $bytes, SEEK_CUR);
+ } elseif ($this->comptype === Archive::COMPRESS_BZIP) {
+ // there is no seek in bzip2, we simply read on
+ // bzread allows to read a max of 8kb at once
+ while($bytes) {
+ $toread = min(8192, $bytes);
+ @bzread($this->fh, $toread);
+ $bytes -= $toread;
+ }
+ } else {
+ @fseek($this->fh, $bytes, SEEK_CUR);
+ }
+ }
+
+ /**
+ * Write the given file meta data as header
+ *
+ * @param FileInfo $fileinfo
+ * @throws ArchiveIOException
+ */
+ protected function writeFileHeader(FileInfo $fileinfo)
+ {
+ $this->writeRawFileHeader(
+ $fileinfo->getPath(),
+ $fileinfo->getUid(),
+ $fileinfo->getGid(),
+ $fileinfo->getMode(),
+ $fileinfo->getSize(),
+ $fileinfo->getMtime(),
+ $fileinfo->getIsdir() ? '5' : '0'
+ );
+ }
+
+ /**
+ * Write a file header to the stream
+ *
+ * @param string $name
+ * @param int $uid
+ * @param int $gid
+ * @param int $perm
+ * @param int $size
+ * @param int $mtime
+ * @param string $typeflag Set to '5' for directories
+ * @throws ArchiveIOException
+ */
+ protected function writeRawFileHeader($name, $uid, $gid, $perm, $size, $mtime, $typeflag = '')
+ {
+ // handle filename length restrictions
+ $prefix = '';
+ $namelen = strlen($name);
+ if ($namelen > 100) {
+ $file = basename($name);
+ $dir = dirname($name);
+ if (strlen($file) > 100 || strlen($dir) > 155) {
+ // we're still too large, let's use GNU longlink
+ $this->writeRawFileHeader('././@LongLink', 0, 0, 0, $namelen, 0, 'L');
+ for ($s = 0; $s < $namelen; $s += 512) {
+ $this->writebytes(pack("a512", substr($name, $s, 512)));
+ }
+ $name = substr($name, 0, 100); // cut off name
+ } else {
+ // we're fine when splitting, use POSIX ustar
+ $prefix = $dir;
+ $name = $file;
+ }
+ }
+
+ // values are needed in octal
+ $uid = sprintf("%6s ", decoct($uid));
+ $gid = sprintf("%6s ", decoct($gid));
+ $perm = sprintf("%6s ", decoct($perm));
+ $size = sprintf("%11s ", decoct($size));
+ $mtime = sprintf("%11s", decoct($mtime));
+
+ $data_first = pack("a100a8a8a8a12A12", $name, $perm, $uid, $gid, $size, $mtime);
+ $data_last = pack("a1a100a6a2a32a32a8a8a155a12", $typeflag, '', 'ustar', '', '', '', '', '', $prefix, "");
+
+ for ($i = 0, $chks = 0; $i < 148; $i++) {
+ $chks += ord($data_first[$i]);
+ }
+
+ for ($i = 156, $chks += 256, $j = 0; $i < 512; $i++, $j++) {
+ $chks += ord($data_last[$j]);
+ }
+
+ $this->writebytes($data_first);
+
+ $chks = pack("a8", sprintf("%6s ", decoct($chks)));
+ $this->writebytes($chks.$data_last);
+ }
+
+ /**
+ * Decode the given tar file header
+ *
+ * @param string $block a 512 byte block containing the header data
+ * @return array|false returns false when this was a null block
+ * @throws ArchiveCorruptedException
+ */
+ protected function parseHeader($block)
+ {
+ if (!$block || strlen($block) != 512) {
+ throw new ArchiveCorruptedException('Unexpected length of header');
+ }
+
+ // null byte blocks are ignored
+ if(trim($block) === '') return false;
+
+ for ($i = 0, $chks = 0; $i < 148; $i++) {
+ $chks += ord($block[$i]);
+ }
+
+ for ($i = 156, $chks += 256; $i < 512; $i++) {
+ $chks += ord($block[$i]);
+ }
+
+ $header = @unpack(
+ "a100filename/a8perm/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor/a155prefix",
+ $block
+ );
+ if (!$header) {
+ throw new ArchiveCorruptedException('Failed to parse header');
+ }
+
+ $return['checksum'] = OctDec(trim($header['checksum']));
+ if ($return['checksum'] != $chks) {
+ throw new ArchiveCorruptedException('Header does not match it\'s checksum');
+ }
+
+ $return['filename'] = trim($header['filename']);
+ $return['perm'] = OctDec(trim($header['perm']));
+ $return['uid'] = OctDec(trim($header['uid']));
+ $return['gid'] = OctDec(trim($header['gid']));
+ $return['size'] = OctDec(trim($header['size']));
+ $return['mtime'] = OctDec(trim($header['mtime']));
+ $return['typeflag'] = $header['typeflag'];
+ $return['link'] = trim($header['link']);
+ $return['uname'] = trim($header['uname']);
+ $return['gname'] = trim($header['gname']);
+
+ // Handle ustar Posix compliant path prefixes
+ if (trim($header['prefix'])) {
+ $return['filename'] = trim($header['prefix']).'/'.$return['filename'];
+ }
+
+ // Handle Long-Link entries from GNU Tar
+ if ($return['typeflag'] == 'L') {
+ // following data block(s) is the filename
+ $filename = trim($this->readbytes(ceil($return['size'] / 512) * 512));
+ // next block is the real header
+ $block = $this->readbytes(512);
+ $return = $this->parseHeader($block);
+ // overwrite the filename
+ $return['filename'] = $filename;
+ }
+
+ return $return;
+ }
+
+ /**
+ * Creates a FileInfo object from the given parsed header
+ *
+ * @param $header
+ * @return FileInfo
+ */
+ protected function header2fileinfo($header)
+ {
+ $fileinfo = new FileInfo();
+ $fileinfo->setPath($header['filename']);
+ $fileinfo->setMode($header['perm']);
+ $fileinfo->setUid($header['uid']);
+ $fileinfo->setGid($header['gid']);
+ $fileinfo->setSize($header['size']);
+ $fileinfo->setMtime($header['mtime']);
+ $fileinfo->setOwner($header['uname']);
+ $fileinfo->setGroup($header['gname']);
+ $fileinfo->setIsdir((bool) $header['typeflag']);
+
+ return $fileinfo;
+ }
+
+ /**
+ * Checks if the given compression type is available and throws an exception if not
+ *
+ * @param $comptype
+ * @throws ArchiveIllegalCompressionException
+ */
+ protected function compressioncheck($comptype)
+ {
+ if ($comptype === Archive::COMPRESS_GZIP && !function_exists('gzopen')) {
+ throw new ArchiveIllegalCompressionException('No gzip support available');
+ }
+
+ if ($comptype === Archive::COMPRESS_BZIP && !function_exists('bzopen')) {
+ throw new ArchiveIllegalCompressionException('No bzip2 support available');
+ }
+ }
+
+ /**
+ * Guesses the wanted compression from the given file
+ *
+ * Uses magic bytes for existing files, the file extension otherwise
+ *
+ * You don't need to call this yourself. It's used when you pass Archive::COMPRESS_AUTO somewhere
+ *
+ * @param string $file
+ * @return int
+ */
+ public function filetype($file)
+ {
+ // for existing files, try to read the magic bytes
+ if(file_exists($file) && is_readable($file) && filesize($file) > 5) {
+ $fh = @fopen($file, 'rb');
+ if(!$fh) return false;
+ $magic = fread($fh, 5);
+ fclose($fh);
+
+ if(strpos($magic, "\x42\x5a") === 0) return Archive::COMPRESS_BZIP;
+ if(strpos($magic, "\x1f\x8b") === 0) return Archive::COMPRESS_GZIP;
+ }
+
+ // otherwise rely on file name
+ $file = strtolower($file);
+ if (substr($file, -3) == '.gz' || substr($file, -4) == '.tgz') {
+ return Archive::COMPRESS_GZIP;
+ } elseif (substr($file, -4) == '.bz2' || substr($file, -4) == '.tbz') {
+ return Archive::COMPRESS_BZIP;
+ }
+
+ return Archive::COMPRESS_NONE;
+ }
+
+}
diff --git a/platform/www/vendor/splitbrain/php-archive/src/Zip.php b/platform/www/vendor/splitbrain/php-archive/src/Zip.php
new file mode 100644
index 0000000..3dade80
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-archive/src/Zip.php
@@ -0,0 +1,895 @@
+<?php
+
+namespace splitbrain\PHPArchive;
+
+/**
+ * Class Zip
+ *
+ * Creates or extracts Zip archives
+ *
+ * for specs see http://www.pkware.com/appnote
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @package splitbrain\PHPArchive
+ * @license MIT
+ */
+class Zip extends Archive
+{
+
+ protected $file = '';
+ protected $fh;
+ protected $memory = '';
+ protected $closed = true;
+ protected $writeaccess = false;
+ protected $ctrl_dir;
+ protected $complevel = 9;
+
+ /**
+ * Set the compression level.
+ *
+ * Compression Type is ignored for ZIP
+ *
+ * You can call this function before adding each file to set differen compression levels
+ * for each file.
+ *
+ * @param int $level Compression level (0 to 9)
+ * @param int $type Type of compression to use ignored for ZIP
+ * @throws ArchiveIllegalCompressionException
+ */
+ public function setCompression($level = 9, $type = Archive::COMPRESS_AUTO)
+ {
+ if ($level < -1 || $level > 9) {
+ throw new ArchiveIllegalCompressionException('Compression level should be between -1 and 9');
+ }
+ $this->complevel = $level;
+ }
+
+ /**
+ * Open an existing ZIP file for reading
+ *
+ * @param string $file
+ * @throws ArchiveIOException
+ */
+ public function open($file)
+ {
+ $this->file = $file;
+ $this->fh = @fopen($this->file, 'rb');
+ if (!$this->fh) {
+ throw new ArchiveIOException('Could not open file for reading: '.$this->file);
+ }
+ $this->closed = false;
+ }
+
+ /**
+ * Read the contents of a ZIP archive
+ *
+ * This function lists the files stored in the archive, and returns an indexed array of FileInfo objects
+ *
+ * The archive is closed afer reading the contents, for API compatibility with TAR files
+ * Reopen the file with open() again if you want to do additional operations
+ *
+ * @throws ArchiveIOException
+ * @return FileInfo[]
+ */
+ public function contents()
+ {
+ if ($this->closed || !$this->file) {
+ throw new ArchiveIOException('Can not read from a closed archive');
+ }
+
+ $result = array();
+
+ $centd = $this->readCentralDir();
+
+ @rewind($this->fh);
+ @fseek($this->fh, $centd['offset']);
+
+ for ($i = 0; $i < $centd['entries']; $i++) {
+ $result[] = $this->header2fileinfo($this->readCentralFileHeader());
+ }
+
+ $this->close();
+ return $result;
+ }
+
+ /**
+ * Extract an existing ZIP archive
+ *
+ * The $strip parameter allows you to strip a certain number of path components from the filenames
+ * found in the tar file, similar to the --strip-components feature of GNU tar. This is triggered when
+ * an integer is passed as $strip.
+ * Alternatively a fixed string prefix may be passed in $strip. If the filename matches this prefix,
+ * the prefix will be stripped. It is recommended to give prefixes with a trailing slash.
+ *
+ * By default this will extract all files found in the archive. You can restrict the output using the $include
+ * and $exclude parameter. Both expect a full regular expression (including delimiters and modifiers). If
+ * $include is set only files that match this expression will be extracted. Files that match the $exclude
+ * expression will never be extracted. Both parameters can be used in combination. Expressions are matched against
+ * stripped filenames as described above.
+ *
+ * @param string $outdir the target directory for extracting
+ * @param int|string $strip either the number of path components or a fixed prefix to strip
+ * @param string $exclude a regular expression of files to exclude
+ * @param string $include a regular expression of files to include
+ * @throws ArchiveIOException
+ * @return FileInfo[]
+ */
+ public function extract($outdir, $strip = '', $exclude = '', $include = '')
+ {
+ if ($this->closed || !$this->file) {
+ throw new ArchiveIOException('Can not read from a closed archive');
+ }
+
+ $outdir = rtrim($outdir, '/');
+ @mkdir($outdir, 0777, true);
+
+ $extracted = array();
+
+ $cdir = $this->readCentralDir();
+ $pos_entry = $cdir['offset']; // begin of the central file directory
+
+ for ($i = 0; $i < $cdir['entries']; $i++) {
+ // read file header
+ @fseek($this->fh, $pos_entry);
+ $header = $this->readCentralFileHeader();
+ $header['index'] = $i;
+ $pos_entry = ftell($this->fh); // position of the next file in central file directory
+ fseek($this->fh, $header['offset']); // seek to beginning of file header
+ $header = $this->readFileHeader($header);
+ $fileinfo = $this->header2fileinfo($header);
+
+ // apply strip rules
+ $fileinfo->strip($strip);
+
+ // skip unwanted files
+ if (!strlen($fileinfo->getPath()) || !$fileinfo->match($include, $exclude)) {
+ continue;
+ }
+
+ $extracted[] = $fileinfo;
+
+ // create output directory
+ $output = $outdir.'/'.$fileinfo->getPath();
+ $directory = ($header['folder']) ? $output : dirname($output);
+ @mkdir($directory, 0777, true);
+
+ // nothing more to do for directories
+ if ($fileinfo->getIsdir()) {
+ if(is_callable($this->callback)) {
+ call_user_func($this->callback, $fileinfo);
+ }
+ continue;
+ }
+
+ // compressed files are written to temporary .gz file first
+ if ($header['compression'] == 0) {
+ $extractto = $output;
+ } else {
+ $extractto = $output.'.gz';
+ }
+
+ // open file for writing
+ $fp = @fopen($extractto, "wb");
+ if (!$fp) {
+ throw new ArchiveIOException('Could not open file for writing: '.$extractto);
+ }
+
+ // prepend compression header
+ if ($header['compression'] != 0) {
+ $binary_data = pack(
+ 'va1a1Va1a1',
+ 0x8b1f,
+ chr($header['compression']),
+ chr(0x00),
+ time(),
+ chr(0x00),
+ chr(3)
+ );
+ fwrite($fp, $binary_data, 10);
+ }
+
+ // read the file and store it on disk
+ $size = $header['compressed_size'];
+ while ($size != 0) {
+ $read_size = ($size < 2048 ? $size : 2048);
+ $buffer = fread($this->fh, $read_size);
+ $binary_data = pack('a'.$read_size, $buffer);
+ fwrite($fp, $binary_data, $read_size);
+ $size -= $read_size;
+ }
+
+ // finalize compressed file
+ if ($header['compression'] != 0) {
+ $binary_data = pack('VV', $header['crc'], $header['size']);
+ fwrite($fp, $binary_data, 8);
+ }
+
+ // close file
+ fclose($fp);
+
+ // unpack compressed file
+ if ($header['compression'] != 0) {
+ $gzp = @gzopen($extractto, 'rb');
+ if (!$gzp) {
+ @unlink($extractto);
+ throw new ArchiveIOException('Failed file extracting. gzip support missing?');
+ }
+ $fp = @fopen($output, 'wb');
+ if (!$fp) {
+ throw new ArchiveIOException('Could not open file for writing: '.$extractto);
+ }
+
+ $size = $header['size'];
+ while ($size != 0) {
+ $read_size = ($size < 2048 ? $size : 2048);
+ $buffer = gzread($gzp, $read_size);
+ $binary_data = pack('a'.$read_size, $buffer);
+ @fwrite($fp, $binary_data, $read_size);
+ $size -= $read_size;
+ }
+ fclose($fp);
+ gzclose($gzp);
+ unlink($extractto); // remove temporary gz file
+ }
+
+ @touch($output, $fileinfo->getMtime());
+ //FIXME what about permissions?
+ if(is_callable($this->callback)) {
+ call_user_func($this->callback, $fileinfo);
+ }
+ }
+
+ $this->close();
+ return $extracted;
+ }
+
+ /**
+ * Create a new ZIP file
+ *
+ * If $file is empty, the zip file will be created in memory
+ *
+ * @param string $file
+ * @throws ArchiveIOException
+ */
+ public function create($file = '')
+ {
+ $this->file = $file;
+ $this->memory = '';
+ $this->fh = 0;
+
+ if ($this->file) {
+ $this->fh = @fopen($this->file, 'wb');
+
+ if (!$this->fh) {
+ throw new ArchiveIOException('Could not open file for writing: '.$this->file);
+ }
+ }
+ $this->writeaccess = true;
+ $this->closed = false;
+ $this->ctrl_dir = array();
+ }
+
+ /**
+ * Add a file to the current ZIP archive using an existing file in the filesystem
+ *
+ * @param string $file path to the original file
+ * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data, empty to take from original
+ * @throws ArchiveIOException
+ */
+
+ /**
+ * Add a file to the current archive using an existing file in the filesystem
+ *
+ * @param string $file path to the original file
+ * @param string|FileInfo $fileinfo either the name to use in archive (string) or a FileInfo oject with all meta data, empty to take from original
+ * @throws ArchiveIOException
+ * @throws FileInfoException
+ */
+ public function addFile($file, $fileinfo = '')
+ {
+ if (is_string($fileinfo)) {
+ $fileinfo = FileInfo::fromPath($file, $fileinfo);
+ }
+
+ if ($this->closed) {
+ throw new ArchiveIOException('Archive has been closed, files can no longer be added');
+ }
+
+ $data = @file_get_contents($file);
+ if ($data === false) {
+ throw new ArchiveIOException('Could not open file for reading: '.$file);
+ }
+
+ // FIXME could we stream writing compressed data? gzwrite on a fopen handle?
+ $this->addData($fileinfo, $data);
+ }
+
+ /**
+ * Add a file to the current Zip archive using the given $data as content
+ *
+ * @param string|FileInfo $fileinfo either the name to us in archive (string) or a FileInfo oject with all meta data
+ * @param string $data binary content of the file to add
+ * @throws ArchiveIOException
+ */
+ public function addData($fileinfo, $data)
+ {
+ if (is_string($fileinfo)) {
+ $fileinfo = new FileInfo($fileinfo);
+ }
+
+ if ($this->closed) {
+ throw new ArchiveIOException('Archive has been closed, files can no longer be added');
+ }
+
+ // prepare info and compress data
+ $size = strlen($data);
+ $crc = crc32($data);
+ if ($this->complevel) {
+ $data = gzcompress($data, $this->complevel);
+ $data = substr($data, 2, -4); // strip compression headers
+ }
+ $csize = strlen($data);
+ $offset = $this->dataOffset();
+ $name = $fileinfo->getPath();
+ $time = $fileinfo->getMtime();
+
+ // write local file header
+ $this->writebytes($this->makeLocalFileHeader(
+ $time,
+ $crc,
+ $size,
+ $csize,
+ $name,
+ (bool) $this->complevel
+ ));
+
+ // we store no encryption header
+
+ // write data
+ $this->writebytes($data);
+
+ // we store no data descriptor
+
+ // add info to central file directory
+ $this->ctrl_dir[] = $this->makeCentralFileRecord(
+ $offset,
+ $time,
+ $crc,
+ $size,
+ $csize,
+ $name,
+ (bool) $this->complevel
+ );
+
+ if(is_callable($this->callback)) {
+ call_user_func($this->callback, $fileinfo);
+ }
+ }
+
+ /**
+ * Add the closing footer to the archive if in write mode, close all file handles
+ *
+ * After a call to this function no more data can be added to the archive, for
+ * read access no reading is allowed anymore
+ * @throws ArchiveIOException
+ */
+ public function close()
+ {
+ if ($this->closed) {
+ return;
+ } // we did this already
+
+ if ($this->writeaccess) {
+ // write central directory
+ $offset = $this->dataOffset();
+ $ctrldir = join('', $this->ctrl_dir);
+ $this->writebytes($ctrldir);
+
+ // write end of central directory record
+ $this->writebytes("\x50\x4b\x05\x06"); // end of central dir signature
+ $this->writebytes(pack('v', 0)); // number of this disk
+ $this->writebytes(pack('v', 0)); // number of the disk with the start of the central directory
+ $this->writebytes(pack('v',
+ count($this->ctrl_dir))); // total number of entries in the central directory on this disk
+ $this->writebytes(pack('v', count($this->ctrl_dir))); // total number of entries in the central directory
+ $this->writebytes(pack('V', strlen($ctrldir))); // size of the central directory
+ $this->writebytes(pack('V',
+ $offset)); // offset of start of central directory with respect to the starting disk number
+ $this->writebytes(pack('v', 0)); // .ZIP file comment length
+
+ $this->ctrl_dir = array();
+ }
+
+ // close file handles
+ if ($this->file) {
+ fclose($this->fh);
+ $this->file = '';
+ $this->fh = 0;
+ }
+
+ $this->writeaccess = false;
+ $this->closed = true;
+ }
+
+ /**
+ * Returns the created in-memory archive data
+ *
+ * This implicitly calls close() on the Archive
+ * @throws ArchiveIOException
+ */
+ public function getArchive()
+ {
+ $this->close();
+
+ return $this->memory;
+ }
+
+ /**
+ * Save the created in-memory archive data
+ *
+ * Note: It's more memory effective to specify the filename in the create() function and
+ * let the library work on the new file directly.
+ *
+ * @param $file
+ * @throws ArchiveIOException
+ */
+ public function save($file)
+ {
+ if (!@file_put_contents($file, $this->getArchive())) {
+ throw new ArchiveIOException('Could not write to file: '.$file);
+ }
+ }
+
+ /**
+ * Read the central directory
+ *
+ * This key-value list contains general information about the ZIP file
+ *
+ * @return array
+ */
+ protected function readCentralDir()
+ {
+ $size = filesize($this->file);
+ if ($size < 277) {
+ $maximum_size = $size;
+ } else {
+ $maximum_size = 277;
+ }
+
+ @fseek($this->fh, $size - $maximum_size);
+ $pos = ftell($this->fh);
+ $bytes = 0x00000000;
+
+ while ($pos < $size) {
+ $byte = @fread($this->fh, 1);
+ $bytes = (($bytes << 8) & 0xFFFFFFFF) | ord($byte);
+ if ($bytes == 0x504b0506) {
+ break;
+ }
+ $pos++;
+ }
+
+ $data = unpack(
+ 'vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size',
+ fread($this->fh, 18)
+ );
+
+ if ($data['comment_size'] != 0) {
+ $centd['comment'] = fread($this->fh, $data['comment_size']);
+ } else {
+ $centd['comment'] = '';
+ }
+ $centd['entries'] = $data['entries'];
+ $centd['disk_entries'] = $data['disk_entries'];
+ $centd['offset'] = $data['offset'];
+ $centd['disk_start'] = $data['disk_start'];
+ $centd['size'] = $data['size'];
+ $centd['disk'] = $data['disk'];
+ return $centd;
+ }
+
+ /**
+ * Read the next central file header
+ *
+ * Assumes the current file pointer is pointing at the right position
+ *
+ * @return array
+ */
+ protected function readCentralFileHeader()
+ {
+ $binary_data = fread($this->fh, 46);
+ $header = unpack(
+ 'vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset',
+ $binary_data
+ );
+
+ if ($header['filename_len'] != 0) {
+ $header['filename'] = fread($this->fh, $header['filename_len']);
+ } else {
+ $header['filename'] = '';
+ }
+
+ if ($header['extra_len'] != 0) {
+ $header['extra'] = fread($this->fh, $header['extra_len']);
+ $header['extradata'] = $this->parseExtra($header['extra']);
+ } else {
+ $header['extra'] = '';
+ $header['extradata'] = array();
+ }
+
+ if ($header['comment_len'] != 0) {
+ $header['comment'] = fread($this->fh, $header['comment_len']);
+ } else {
+ $header['comment'] = '';
+ }
+
+ $header['mtime'] = $this->makeUnixTime($header['mdate'], $header['mtime']);
+ $header['stored_filename'] = $header['filename'];
+ $header['status'] = 'ok';
+ if (substr($header['filename'], -1) == '/') {
+ $header['external'] = 0x41FF0010;
+ }
+ $header['folder'] = ($header['external'] == 0x41FF0010 || $header['external'] == 16) ? 1 : 0;
+
+ return $header;
+ }
+
+ /**
+ * Reads the local file header
+ *
+ * This header precedes each individual file inside the zip file. Assumes the current file pointer is pointing at
+ * the right position already. Enhances the given central header with the data found at the local header.
+ *
+ * @param array $header the central file header read previously (see above)
+ * @return array
+ */
+ protected function readFileHeader($header)
+ {
+ $binary_data = fread($this->fh, 30);
+ $data = unpack(
+ 'vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len',
+ $binary_data
+ );
+
+ $header['filename'] = fread($this->fh, $data['filename_len']);
+ if ($data['extra_len'] != 0) {
+ $header['extra'] = fread($this->fh, $data['extra_len']);
+ $header['extradata'] = array_merge($header['extradata'], $this->parseExtra($header['extra']));
+ } else {
+ $header['extra'] = '';
+ $header['extradata'] = array();
+ }
+
+ $header['compression'] = $data['compression'];
+ foreach (array(
+ 'size',
+ 'compressed_size',
+ 'crc'
+ ) as $hd) { // On ODT files, these headers are 0. Keep the previous value.
+ if ($data[$hd] != 0) {
+ $header[$hd] = $data[$hd];
+ }
+ }
+ $header['flag'] = $data['flag'];
+ $header['mtime'] = $this->makeUnixTime($data['mdate'], $data['mtime']);
+
+ $header['stored_filename'] = $header['filename'];
+ $header['status'] = "ok";
+ $header['folder'] = ($header['external'] == 0x41FF0010 || $header['external'] == 16) ? 1 : 0;
+ return $header;
+ }
+
+ /**
+ * Parse the extra headers into fields
+ *
+ * @param string $header
+ * @return array
+ */
+ protected function parseExtra($header)
+ {
+ $extra = array();
+ // parse all extra fields as raw values
+ while (strlen($header) !== 0) {
+ $set = unpack('vid/vlen', $header);
+ $header = substr($header, 4);
+ $value = substr($header, 0, $set['len']);
+ $header = substr($header, $set['len']);
+ $extra[$set['id']] = $value;
+ }
+
+ // handle known ones
+ if(isset($extra[0x6375])) {
+ $extra['utf8comment'] = substr($extra[0x7075], 5); // strip version and crc
+ }
+ if(isset($extra[0x7075])) {
+ $extra['utf8path'] = substr($extra[0x7075], 5); // strip version and crc
+ }
+
+ return $extra;
+ }
+
+ /**
+ * Create fileinfo object from header data
+ *
+ * @param $header
+ * @return FileInfo
+ */
+ protected function header2fileinfo($header)
+ {
+ $fileinfo = new FileInfo();
+ $fileinfo->setSize($header['size']);
+ $fileinfo->setCompressedSize($header['compressed_size']);
+ $fileinfo->setMtime($header['mtime']);
+ $fileinfo->setComment($header['comment']);
+ $fileinfo->setIsdir($header['external'] == 0x41FF0010 || $header['external'] == 16);
+
+ if(isset($header['extradata']['utf8path'])) {
+ $fileinfo->setPath($header['extradata']['utf8path']);
+ } else {
+ $fileinfo->setPath($this->cpToUtf8($header['filename']));
+ }
+
+ if(isset($header['extradata']['utf8comment'])) {
+ $fileinfo->setComment($header['extradata']['utf8comment']);
+ } else {
+ $fileinfo->setComment($this->cpToUtf8($header['comment']));
+ }
+
+ return $fileinfo;
+ }
+
+ /**
+ * Convert the given CP437 encoded string to UTF-8
+ *
+ * Tries iconv with the correct encoding first, falls back to mbstring with CP850 which is
+ * similar enough. CP437 seems not to be available in mbstring. Lastly falls back to keeping the
+ * string as is, which is still better than nothing.
+ *
+ * On some systems iconv is available, but the codepage is not. We also check for that.
+ *
+ * @param $string
+ * @return string
+ */
+ protected function cpToUtf8($string)
+ {
+ if (function_exists('iconv') && @iconv_strlen('', 'CP437') !== false) {
+ return iconv('CP437', 'UTF-8', $string);
+ } elseif (function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($string, 'UTF-8', 'CP850');
+ } else {
+ return $string;
+ }
+ }
+
+ /**
+ * Convert the given UTF-8 encoded string to CP437
+ *
+ * Same caveats as for cpToUtf8() apply
+ *
+ * @param $string
+ * @return string
+ */
+ protected function utf8ToCp($string)
+ {
+ // try iconv first
+ if (function_exists('iconv')) {
+ $conv = @iconv('UTF-8', 'CP437//IGNORE', $string);
+ if($conv) return $conv; // it worked
+ }
+
+ // still here? iconv failed to convert the string. Try another method
+ // see http://php.net/manual/en/function.iconv.php#108643
+
+ if (function_exists('mb_convert_encoding')) {
+ return mb_convert_encoding($string, 'CP850', 'UTF-8');
+ } else {
+ return $string;
+ }
+ }
+
+
+ /**
+ * Write to the open filepointer or memory
+ *
+ * @param string $data
+ * @throws ArchiveIOException
+ * @return int number of bytes written
+ */
+ protected function writebytes($data)
+ {
+ if (!$this->file) {
+ $this->memory .= $data;
+ $written = strlen($data);
+ } else {
+ $written = @fwrite($this->fh, $data);
+ }
+ if ($written === false) {
+ throw new ArchiveIOException('Failed to write to archive stream');
+ }
+ return $written;
+ }
+
+ /**
+ * Current data pointer position
+ *
+ * @fixme might need a -1
+ * @return int
+ */
+ protected function dataOffset()
+ {
+ if ($this->file) {
+ return ftell($this->fh);
+ } else {
+ return strlen($this->memory);
+ }
+ }
+
+ /**
+ * Create a DOS timestamp from a UNIX timestamp
+ *
+ * DOS timestamps start at 1980-01-01, earlier UNIX stamps will be set to this date
+ *
+ * @param $time
+ * @return int
+ */
+ protected function makeDosTime($time)
+ {
+ $timearray = getdate($time);
+ if ($timearray['year'] < 1980) {
+ $timearray['year'] = 1980;
+ $timearray['mon'] = 1;
+ $timearray['mday'] = 1;
+ $timearray['hours'] = 0;
+ $timearray['minutes'] = 0;
+ $timearray['seconds'] = 0;
+ }
+ return (($timearray['year'] - 1980) << 25) |
+ ($timearray['mon'] << 21) |
+ ($timearray['mday'] << 16) |
+ ($timearray['hours'] << 11) |
+ ($timearray['minutes'] << 5) |
+ ($timearray['seconds'] >> 1);
+ }
+
+ /**
+ * Create a UNIX timestamp from a DOS timestamp
+ *
+ * @param $mdate
+ * @param $mtime
+ * @return int
+ */
+ protected function makeUnixTime($mdate = null, $mtime = null)
+ {
+ if ($mdate && $mtime) {
+ $year = (($mdate & 0xFE00) >> 9) + 1980;
+ $month = ($mdate & 0x01E0) >> 5;
+ $day = $mdate & 0x001F;
+
+ $hour = ($mtime & 0xF800) >> 11;
+ $minute = ($mtime & 0x07E0) >> 5;
+ $seconde = ($mtime & 0x001F) << 1;
+
+ $mtime = mktime($hour, $minute, $seconde, $month, $day, $year);
+ } else {
+ $mtime = time();
+ }
+
+ return $mtime;
+ }
+
+ /**
+ * Returns a local file header for the given data
+ *
+ * @param int $offset location of the local header
+ * @param int $ts unix timestamp
+ * @param int $crc CRC32 checksum of the uncompressed data
+ * @param int $len length of the uncompressed data
+ * @param int $clen length of the compressed data
+ * @param string $name file name
+ * @param boolean|null $comp if compression is used, if null it's determined from $len != $clen
+ * @return string
+ */
+ protected function makeCentralFileRecord($offset, $ts, $crc, $len, $clen, $name, $comp = null)
+ {
+ if(is_null($comp)) $comp = $len != $clen;
+ $comp = $comp ? 8 : 0;
+ $dtime = dechex($this->makeDosTime($ts));
+
+ list($name, $extra) = $this->encodeFilename($name);
+
+ $header = "\x50\x4b\x01\x02"; // central file header signature
+ $header .= pack('v', 14); // version made by - VFAT
+ $header .= pack('v', 20); // version needed to extract - 2.0
+ $header .= pack('v', 0); // general purpose flag - no flags set
+ $header .= pack('v', $comp); // compression method - deflate|none
+ $header .= pack(
+ 'H*',
+ $dtime[6] . $dtime[7] .
+ $dtime[4] . $dtime[5] .
+ $dtime[2] . $dtime[3] .
+ $dtime[0] . $dtime[1]
+ ); // last mod file time and date
+ $header .= pack('V', $crc); // crc-32
+ $header .= pack('V', $clen); // compressed size
+ $header .= pack('V', $len); // uncompressed size
+ $header .= pack('v', strlen($name)); // file name length
+ $header .= pack('v', strlen($extra)); // extra field length
+ $header .= pack('v', 0); // file comment length
+ $header .= pack('v', 0); // disk number start
+ $header .= pack('v', 0); // internal file attributes
+ $header .= pack('V', 0); // external file attributes @todo was 0x32!?
+ $header .= pack('V', $offset); // relative offset of local header
+ $header .= $name; // file name
+ $header .= $extra; // extra (utf-8 filename)
+
+ return $header;
+ }
+
+ /**
+ * Returns a local file header for the given data
+ *
+ * @param int $ts unix timestamp
+ * @param int $crc CRC32 checksum of the uncompressed data
+ * @param int $len length of the uncompressed data
+ * @param int $clen length of the compressed data
+ * @param string $name file name
+ * @param boolean|null $comp if compression is used, if null it's determined from $len != $clen
+ * @return string
+ */
+ protected function makeLocalFileHeader($ts, $crc, $len, $clen, $name, $comp = null)
+ {
+ if(is_null($comp)) $comp = $len != $clen;
+ $comp = $comp ? 8 : 0;
+ $dtime = dechex($this->makeDosTime($ts));
+
+ list($name, $extra) = $this->encodeFilename($name);
+
+ $header = "\x50\x4b\x03\x04"; // local file header signature
+ $header .= pack('v', 20); // version needed to extract - 2.0
+ $header .= pack('v', 0); // general purpose flag - no flags set
+ $header .= pack('v', $comp); // compression method - deflate|none
+ $header .= pack(
+ 'H*',
+ $dtime[6] . $dtime[7] .
+ $dtime[4] . $dtime[5] .
+ $dtime[2] . $dtime[3] .
+ $dtime[0] . $dtime[1]
+ ); // last mod file time and date
+ $header .= pack('V', $crc); // crc-32
+ $header .= pack('V', $clen); // compressed size
+ $header .= pack('V', $len); // uncompressed size
+ $header .= pack('v', strlen($name)); // file name length
+ $header .= pack('v', strlen($extra)); // extra field length
+ $header .= $name; // file name
+ $header .= $extra; // extra (utf-8 filename)
+ return $header;
+ }
+
+ /**
+ * Returns an allowed filename and an extra field header
+ *
+ * When encoding stuff outside the 7bit ASCII range it needs to be placed in a separate
+ * extra field
+ *
+ * @param $original
+ * @return array($filename, $extra)
+ */
+ protected function encodeFilename($original)
+ {
+ $cp437 = $this->utf8ToCp($original);
+ if ($cp437 === $original) {
+ return array($original, '');
+ }
+
+ $extra = pack(
+ 'vvCV',
+ 0x7075, // tag
+ strlen($original) + 5, // length of file + version + crc
+ 1, // version
+ crc32($original) // crc
+ );
+ $extra .= $original;
+
+ return array($cp437, $extra);
+ }
+}
diff --git a/platform/www/vendor/splitbrain/php-cli/LICENSE b/platform/www/vendor/splitbrain/php-cli/LICENSE
new file mode 100644
index 0000000..4a8abc3
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-cli/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016 Andreas Gohr
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/platform/www/vendor/splitbrain/php-cli/README.md b/platform/www/vendor/splitbrain/php-cli/README.md
new file mode 100644
index 0000000..5e42a55
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-cli/README.md
@@ -0,0 +1,158 @@
+# PHP-CLI
+
+PHP-CLI is a simple library that helps with creating nice looking command line scripts.
+
+It takes care of
+
+- **option parsing**
+- **help page generation**
+- **automatic width adjustment**
+- **colored output**
+- **optional PSR3 compatibility**
+
+It is lightweight and has **no 3rd party dependencies**. Note: this is for non-interactive scripts only. It has no readline or similar support.
+
+[![Build Status](https://travis-ci.org/splitbrain/php-cli.svg)](https://travis-ci.org/splitbrain/php-cli)
+
+## Installation
+
+Use composer:
+
+```php composer.phar require splitbrain/php-cli```
+
+## Usage and Examples
+
+Minimal example:
+
+```php
+#!/usr/bin/php
+<?php
+require __DIR__ . '/../vendor/autoload.php';
+use splitbrain\phpcli\CLI;
+use splitbrain\phpcli\Options;
+
+class Minimal extends CLI
+{
+ // register options and arguments
+ protected function setup(Options $options)
+ {
+ $options->setHelp('A very minimal example that does nothing but print a version');
+ $options->registerOption('version', 'print version', 'v');
+ }
+
+ // implement your code
+ protected function main(Options $options)
+ {
+ if ($options->getOpt('version')) {
+ $this->info('1.0.0');
+ } else {
+ echo $options->help();
+ }
+ }
+}
+// execute it
+$cli = new Minimal();
+$cli->run();
+```
+
+![Screenshot](screenshot.png)
+
+
+The basic usage is simple:
+
+- create a class and ``extend splitbrain\phpcli\CLI``
+- implement the ```setup($options)``` method and register options, arguments, commands and set help texts
+ - ``$options->setHelp()`` adds a general description
+ - ``$options->registerOption()`` adds an option
+ - ``$options->registerArgument()`` adds an argument
+ - ``$options->registerCommand()`` adds a sub command
+- implement the ```main($options)``` method and do your business logic there
+ - ``$options->getOpts`` lets you access set options
+ - ``$options->getArgs()`` returns the remaining arguments after removing the options
+ - ``$options->getCmd()`` returns the sub command the user used
+- instantiate your class and call ```run()``` on it
+
+More examples can be found in the examples directory. Please refer to the [API docs](https://splitbrain.github.io/php-cli/)
+for further info.
+
+## Exceptions
+
+By default the CLI class registers an exception handler and will print the exception's message to the end user and
+exit the programm with a non-zero exit code. You can disable this behaviour and catch all exceptions yourself by
+passing false to the constructor.
+
+You can use the provided ``splitbrain\phpcli\Exception`` to signal any problems within your main code yourself. The
+exceptions's code will be used as the exit code then.
+
+Stacktraces will be printed on log level `debug`.
+
+## Colored output
+
+Colored output is handled through the ``Colors`` class. It tries to detect if a color terminal is available and only
+then uses terminal colors. You can always suppress colored output by passing ``--no-colors`` to your scripts.
+Disabling colors will also disable the emoticon prefixes.
+
+Simple colored log messages can be printed by you using the convinence methods ``success()`` (green), ``info()`` (cyan),
+``error()`` (red) or ``fatal()`` (red). The latter will also exit the programm with a non-zero exit code.
+
+For more complex coloring you can access the color class through ``$this->colors`` in your script. The ``wrap()`` method
+is probably what you want to use.
+
+The table formatter allows coloring full columns. To use that mechanism pass an array of colors as third parameter to
+its ``format()`` method. Please note that you can not pass colored texts in the second parameters (text length calculation
+and wrapping will fail, breaking your texts).
+
+## Table Formatter
+
+The ``TableFormatter`` class allows you to align texts in multiple columns. It tries to figure out the available
+terminal width on its own. It can be overwritten by setting a ``COLUMNS`` environment variable.
+
+The formatter is used through the ``format()`` method which expects at least two arrays: The first defines the column
+widths, the second contains the texts to fill into the columns. Between each column a border is printed (a single space
+by default).
+
+See the ``example/table.php`` for sample usage.
+
+Columns width can be given in three forms:
+
+- fixed width in characters by providing an integer (eg. ``15``)
+- precentages by provifing an integer and a percent sign (eg. ``25%``)
+- a single fluid "rest" column marked with an asterisk (eg. ``*``)
+
+When mixing fixed and percentage widths, percentages refer to the remaining space after all fixed columns have been
+assigned.
+
+Space for borders is automatically calculated. It is recommended to always have some relative (percentage) or a fluid
+column to adjust for different terminal widths.
+
+The table formatter is used for the automatic help screen accessible when calling your script with ``-h`` or ``--help``.
+
+## PSR-3 Logging
+
+The CLI class is a fully PSR-3 compatible logger (printing colored log data to STDOUT and STDERR). This is useful when
+you call backend code from your CLI that expects a Logger instance to produce any sensible status output while running.
+
+To use this ability simply inherit from `splitbrain\phpcli\PSR3CLI` instead of `splitbrain\phpcli\CLI`, then pass `$this`
+as the logger instance. Be sure you have the suggested `psr/log` composer package installed.
+
+![Screenshot](screenshot2.png)
+
+You can adjust the verbosity of your CLI tool using the `--loglevel` parameter. Supported loglevels are the PSR-3
+loglevels and our own `success` level:
+
+* debug
+* info
+* notice
+* success
+* warning
+* error
+* critical
+* alert
+* emergency
+
+Convenience methods for all log levels are available. Placeholder interpolation as described in PSR-3 is available, too.
+Messages from `warning` level onwards are printed to `STDERR` all below are printed to `STDOUT`.
+
+The default log level of your script can be set by overwriting the `$logdefault` member.
+
+See `example/logging.php` for an example.
diff --git a/platform/www/vendor/splitbrain/php-cli/src/CLI.php b/platform/www/vendor/splitbrain/php-cli/src/CLI.php
new file mode 100644
index 0000000..2ee7990
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-cli/src/CLI.php
@@ -0,0 +1,362 @@
+<?php
+
+namespace splitbrain\phpcli;
+
+/**
+ * Class CLI
+ *
+ * Your commandline script should inherit from this class and implement the abstract methods.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @license MIT
+ */
+abstract class CLI
+{
+ /** @var string the executed script itself */
+ protected $bin;
+ /** @var Options the option parser */
+ protected $options;
+ /** @var Colors */
+ public $colors;
+
+ /** @var array PSR-3 compatible loglevels and their prefix, color, output channel */
+ protected $loglevel = array(
+ 'debug' => array('', Colors::C_RESET, STDOUT),
+ 'info' => array('ℹ ', Colors::C_CYAN, STDOUT),
+ 'notice' => array('☛ ', Colors::C_CYAN, STDOUT),
+ 'success' => array('✓ ', Colors::C_GREEN, STDOUT),
+ 'warning' => array('âš  ', Colors::C_BROWN, STDERR),
+ 'error' => array('✗ ', Colors::C_RED, STDERR),
+ 'critical' => array('☠ ', Colors::C_LIGHTRED, STDERR),
+ 'alert' => array('✖ ', Colors::C_LIGHTRED, STDERR),
+ 'emergency' => array('✘ ', Colors::C_LIGHTRED, STDERR),
+ );
+
+ protected $logdefault = 'info';
+
+ /**
+ * constructor
+ *
+ * Initialize the arguments, set up helper classes and set up the CLI environment
+ *
+ * @param bool $autocatch should exceptions be catched and handled automatically?
+ */
+ public function __construct($autocatch = true)
+ {
+ if ($autocatch) {
+ set_exception_handler(array($this, 'fatal'));
+ }
+
+ $this->colors = new Colors();
+ $this->options = new Options($this->colors);
+ }
+
+ /**
+ * Register options and arguments on the given $options object
+ *
+ * @param Options $options
+ * @return void
+ *
+ * @throws Exception
+ */
+ abstract protected function setup(Options $options);
+
+ /**
+ * Your main program
+ *
+ * Arguments and options have been parsed when this is run
+ *
+ * @param Options $options
+ * @return void
+ *
+ * @throws Exception
+ */
+ abstract protected function main(Options $options);
+
+ /**
+ * Execute the CLI program
+ *
+ * Executes the setup() routine, adds default options, initiate the options parsing and argument checking
+ * and finally executes main() - Each part is split into their own protected function below, so behaviour
+ * can easily be overwritten
+ *
+ * @throws Exception
+ */
+ public function run()
+ {
+ if ('cli' != php_sapi_name()) {
+ throw new Exception('This has to be run from the command line');
+ }
+
+ $this->setup($this->options);
+ $this->registerDefaultOptions();
+ $this->parseOptions();
+ $this->handleDefaultOptions();
+ $this->setupLogging();
+ $this->checkArgments();
+ $this->execute();
+
+ exit(0);
+ }
+
+ // region run handlers - for easier overriding
+
+ /**
+ * Add the default help, color and log options
+ */
+ protected function registerDefaultOptions()
+ {
+ $this->options->registerOption(
+ 'help',
+ 'Display this help screen and exit immediately.',
+ 'h'
+ );
+ $this->options->registerOption(
+ 'no-colors',
+ 'Do not use any colors in output. Useful when piping output to other tools or files.'
+ );
+ $this->options->registerOption(
+ 'loglevel',
+ 'Minimum level of messages to display. Default is ' . $this->colors->wrap($this->logdefault, Colors::C_CYAN) . '. ' .
+ 'Valid levels are: debug, info, notice, success, warning, error, critical, alert, emergency.',
+ null,
+ 'level'
+ );
+ }
+
+ /**
+ * Handle the default options
+ */
+ protected function handleDefaultOptions()
+ {
+ if ($this->options->getOpt('no-colors')) {
+ $this->colors->disable();
+ }
+ if ($this->options->getOpt('help')) {
+ echo $this->options->help();
+ exit(0);
+ }
+ }
+
+ /**
+ * Handle the logging options
+ */
+ protected function setupLogging()
+ {
+ $level = $this->options->getOpt('loglevel', $this->logdefault);
+ if (!isset($this->loglevel[$level])) $this->fatal('Unknown log level');
+ foreach (array_keys($this->loglevel) as $l) {
+ if ($l == $level) break;
+ unset($this->loglevel[$l]);
+ }
+ }
+
+ /**
+ * Wrapper around the option parsing
+ */
+ protected function parseOptions()
+ {
+ $this->options->parseOptions();
+ }
+
+ /**
+ * Wrapper around the argument checking
+ */
+ protected function checkArgments()
+ {
+ $this->options->checkArguments();
+ }
+
+ /**
+ * Wrapper around main
+ */
+ protected function execute()
+ {
+ $this->main($this->options);
+ }
+
+ // endregion
+
+ // region logging
+
+ /**
+ * Exits the program on a fatal error
+ *
+ * @param \Exception|string $error either an exception or an error message
+ * @param array $context
+ */
+ public function fatal($error, array $context = array())
+ {
+ $code = 0;
+ if (is_object($error) && is_a($error, 'Exception')) {
+ /** @var Exception $error */
+ $this->debug(get_class($error) . ' caught in ' . $error->getFile() . ':' . $error->getLine());
+ $this->debug($error->getTraceAsString());
+ $code = $error->getCode();
+ $error = $error->getMessage();
+
+ }
+ if (!$code) {
+ $code = Exception::E_ANY;
+ }
+
+ $this->critical($error, $context);
+ exit($code);
+ }
+
+ /**
+ * System is unusable.
+ *
+ * @param string $message
+ * @param array $context
+ *
+ * @return void
+ */
+ public function emergency($message, array $context = array())
+ {
+ $this->log('emergency', $message, $context);
+ }
+
+ /**
+ * Action must be taken immediately.
+ *
+ * Example: Entire website down, database unavailable, etc. This should
+ * trigger the SMS alerts and wake you up.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function alert($message, array $context = array())
+ {
+ $this->log('alert', $message, $context);
+ }
+
+ /**
+ * Critical conditions.
+ *
+ * Example: Application component unavailable, unexpected exception.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function critical($message, array $context = array())
+ {
+ $this->log('critical', $message, $context);
+ }
+
+ /**
+ * Runtime errors that do not require immediate action but should typically
+ * be logged and monitored.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function error($message, array $context = array())
+ {
+ $this->log('error', $message, $context);
+ }
+
+ /**
+ * Exceptional occurrences that are not errors.
+ *
+ * Example: Use of deprecated APIs, poor use of an API, undesirable things
+ * that are not necessarily wrong.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function warning($message, array $context = array())
+ {
+ $this->log('warning', $message, $context);
+ }
+
+ /**
+ * Normal, positive outcome
+ *
+ * @param string $string
+ * @param array $context
+ */
+ public function success($string, array $context = array())
+ {
+ $this->log('success', $string, $context);
+ }
+
+ /**
+ * Normal but significant events.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function notice($message, array $context = array())
+ {
+ $this->log('notice', $message, $context);
+ }
+
+ /**
+ * Interesting events.
+ *
+ * Example: User logs in, SQL logs.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function info($message, array $context = array())
+ {
+ $this->log('info', $message, $context);
+ }
+
+ /**
+ * Detailed debug information.
+ *
+ * @param string $message
+ * @param array $context
+ */
+ public function debug($message, array $context = array())
+ {
+ $this->log('debug', $message, $context);
+ }
+
+ /**
+ * @param string $level
+ * @param string $message
+ * @param array $context
+ */
+ public function log($level, $message, array $context = array())
+ {
+ // is this log level wanted?
+ if (!isset($this->loglevel[$level])) return;
+
+ /** @var string $prefix */
+ /** @var string $color */
+ /** @var resource $channel */
+ list($prefix, $color, $channel) = $this->loglevel[$level];
+ if (!$this->colors->isEnabled()) $prefix = '';
+
+ $message = $this->interpolate($message, $context);
+ $this->colors->ptln($prefix . $message, $color, $channel);
+ }
+
+ /**
+ * Interpolates context values into the message placeholders.
+ *
+ * @param $message
+ * @param array $context
+ * @return string
+ */
+ function interpolate($message, array $context = array())
+ {
+ // build a replacement array with braces around the context keys
+ $replace = array();
+ foreach ($context as $key => $val) {
+ // check that the value can be casted to string
+ if (!is_array($val) && (!is_object($val) || method_exists($val, '__toString'))) {
+ $replace['{' . $key . '}'] = $val;
+ }
+ }
+
+ // interpolate replacement values into the message and return
+ return strtr($message, $replace);
+ }
+
+ // endregion
+}
diff --git a/platform/www/vendor/splitbrain/php-cli/src/Colors.php b/platform/www/vendor/splitbrain/php-cli/src/Colors.php
new file mode 100644
index 0000000..ae25256
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-cli/src/Colors.php
@@ -0,0 +1,170 @@
+<?php
+
+namespace splitbrain\phpcli;
+
+/**
+ * Class Colors
+ *
+ * Handles color output on (Linux) terminals
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @license MIT
+ */
+class Colors
+{
+ // these constants make IDE autocompletion easier, but color names can also be passed as strings
+ const C_RESET = 'reset';
+ const C_BLACK = 'black';
+ const C_DARKGRAY = 'darkgray';
+ const C_BLUE = 'blue';
+ const C_LIGHTBLUE = 'lightblue';
+ const C_GREEN = 'green';
+ const C_LIGHTGREEN = 'lightgreen';
+ const C_CYAN = 'cyan';
+ const C_LIGHTCYAN = 'lightcyan';
+ const C_RED = 'red';
+ const C_LIGHTRED = 'lightred';
+ const C_PURPLE = 'purple';
+ const C_LIGHTPURPLE = 'lightpurple';
+ const C_BROWN = 'brown';
+ const C_YELLOW = 'yellow';
+ const C_LIGHTGRAY = 'lightgray';
+ const C_WHITE = 'white';
+
+ /** @var array known color names */
+ protected $colors = array(
+ self::C_RESET => "\33[0m",
+ self::C_BLACK => "\33[0;30m",
+ self::C_DARKGRAY => "\33[1;30m",
+ self::C_BLUE => "\33[0;34m",
+ self::C_LIGHTBLUE => "\33[1;34m",
+ self::C_GREEN => "\33[0;32m",
+ self::C_LIGHTGREEN => "\33[1;32m",
+ self::C_CYAN => "\33[0;36m",
+ self::C_LIGHTCYAN => "\33[1;36m",
+ self::C_RED => "\33[0;31m",
+ self::C_LIGHTRED => "\33[1;31m",
+ self::C_PURPLE => "\33[0;35m",
+ self::C_LIGHTPURPLE => "\33[1;35m",
+ self::C_BROWN => "\33[0;33m",
+ self::C_YELLOW => "\33[1;33m",
+ self::C_LIGHTGRAY => "\33[0;37m",
+ self::C_WHITE => "\33[1;37m",
+ );
+
+ /** @var bool should colors be used? */
+ protected $enabled = true;
+
+ /**
+ * Constructor
+ *
+ * Tries to disable colors for non-terminals
+ */
+ public function __construct()
+ {
+ if (function_exists('posix_isatty') && !posix_isatty(STDOUT)) {
+ $this->enabled = false;
+ return;
+ }
+ if (!getenv('TERM')) {
+ $this->enabled = false;
+ return;
+ }
+ }
+
+ /**
+ * enable color output
+ */
+ public function enable()
+ {
+ $this->enabled = true;
+ }
+
+ /**
+ * disable color output
+ */
+ public function disable()
+ {
+ $this->enabled = false;
+ }
+
+ /**
+ * @return bool is color support enabled?
+ */
+ public function isEnabled()
+ {
+ return $this->enabled;
+ }
+
+ /**
+ * Convenience function to print a line in a given color
+ *
+ * @param string $line the line to print, a new line is added automatically
+ * @param string $color one of the available color names
+ * @param resource $channel file descriptor to write to
+ *
+ * @throws Exception
+ */
+ public function ptln($line, $color, $channel = STDOUT)
+ {
+ $this->set($color);
+ fwrite($channel, rtrim($line) . "\n");
+ $this->reset();
+ }
+
+ /**
+ * Returns the given text wrapped in the appropriate color and reset code
+ *
+ * @param string $text string to wrap
+ * @param string $color one of the available color names
+ * @return string the wrapped string
+ * @throws Exception
+ */
+ public function wrap($text, $color)
+ {
+ return $this->getColorCode($color) . $text . $this->getColorCode('reset');
+ }
+
+ /**
+ * Gets the appropriate terminal code for the given color
+ *
+ * @param string $color one of the available color names
+ * @return string color code
+ * @throws Exception
+ */
+ public function getColorCode($color)
+ {
+ if (!$this->enabled) {
+ return '';
+ }
+ if (!isset($this->colors[$color])) {
+ throw new Exception("No such color $color");
+ }
+
+ return $this->colors[$color];
+ }
+
+ /**
+ * Set the given color for consecutive output
+ *
+ * @param string $color one of the supported color names
+ * @param resource $channel file descriptor to write to
+ * @throws Exception
+ */
+ public function set($color, $channel = STDOUT)
+ {
+ fwrite($channel, $this->getColorCode($color));
+ }
+
+ /**
+ * reset the terminal color
+ *
+ * @param resource $channel file descriptor to write to
+ *
+ * @throws Exception
+ */
+ public function reset($channel = STDOUT)
+ {
+ $this->set('reset', $channel);
+ }
+}
diff --git a/platform/www/vendor/splitbrain/php-cli/src/Exception.php b/platform/www/vendor/splitbrain/php-cli/src/Exception.php
new file mode 100644
index 0000000..4d24d58
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-cli/src/Exception.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace splitbrain\phpcli;
+
+/**
+ * Class Exception
+ *
+ * The code is used as exit code for the CLI tool. This should probably be extended. Many cases just fall back to the
+ * E_ANY code.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @license MIT
+ */
+class Exception extends \RuntimeException
+{
+ const E_ANY = -1; // no error code specified
+ const E_UNKNOWN_OPT = 1; //Unrecognized option
+ const E_OPT_ARG_REQUIRED = 2; //Option requires argument
+ const E_OPT_ARG_DENIED = 3; //Option not allowed argument
+ const E_OPT_ABIGUOUS = 4; //Option abiguous
+ const E_ARG_READ = 5; //Could not read argv
+
+ /**
+ * @param string $message The Exception message to throw.
+ * @param int $code The Exception code
+ * @param \Exception $previous The previous exception used for the exception chaining.
+ */
+ public function __construct($message = "", $code = 0, \Exception $previous = null)
+ {
+ if (!$code) {
+ $code = self::E_ANY;
+ }
+ parent::__construct($message, $code, $previous);
+ }
+}
diff --git a/platform/www/vendor/splitbrain/php-cli/src/Options.php b/platform/www/vendor/splitbrain/php-cli/src/Options.php
new file mode 100644
index 0000000..74dae2b
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-cli/src/Options.php
@@ -0,0 +1,478 @@
+<?php
+
+namespace splitbrain\phpcli;
+
+/**
+ * Class Options
+ *
+ * Parses command line options passed to the CLI script. Allows CLI scripts to easily register all accepted options and
+ * commands and even generates a help text from this setup.
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @license MIT
+ */
+class Options
+{
+ /** @var array keeps the list of options to parse */
+ protected $setup;
+
+ /** @var array store parsed options */
+ protected $options = array();
+
+ /** @var string current parsed command if any */
+ protected $command = '';
+
+ /** @var array passed non-option arguments */
+ protected $args = array();
+
+ /** @var string the executed script */
+ protected $bin;
+
+ /** @var Colors for colored help output */
+ protected $colors;
+
+ /**
+ * Constructor
+ *
+ * @param Colors $colors optional configured color object
+ * @throws Exception when arguments can't be read
+ */
+ public function __construct(Colors $colors = null)
+ {
+ if (!is_null($colors)) {
+ $this->colors = $colors;
+ } else {
+ $this->colors = new Colors();
+ }
+
+ $this->setup = array(
+ '' => array(
+ 'opts' => array(),
+ 'args' => array(),
+ 'help' => ''
+ )
+ ); // default command
+
+ $this->args = $this->readPHPArgv();
+ $this->bin = basename(array_shift($this->args));
+
+ $this->options = array();
+ }
+
+ /**
+ * Gets the bin value
+ */
+ public function getBin()
+ {
+ return $this->bin;
+ }
+
+ /**
+ * Sets the help text for the tool itself
+ *
+ * @param string $help
+ */
+ public function setHelp($help)
+ {
+ $this->setup['']['help'] = $help;
+ }
+
+ /**
+ * Register the names of arguments for help generation and number checking
+ *
+ * This has to be called in the order arguments are expected
+ *
+ * @param string $arg argument name (just for help)
+ * @param string $help help text
+ * @param bool $required is this a required argument
+ * @param string $command if theses apply to a sub command only
+ * @throws Exception
+ */
+ public function registerArgument($arg, $help, $required = true, $command = '')
+ {
+ if (!isset($this->setup[$command])) {
+ throw new Exception("Command $command not registered");
+ }
+
+ $this->setup[$command]['args'][] = array(
+ 'name' => $arg,
+ 'help' => $help,
+ 'required' => $required
+ );
+ }
+
+ /**
+ * This registers a sub command
+ *
+ * Sub commands have their own options and use their own function (not main()).
+ *
+ * @param string $command
+ * @param string $help
+ * @throws Exception
+ */
+ public function registerCommand($command, $help)
+ {
+ if (isset($this->setup[$command])) {
+ throw new Exception("Command $command already registered");
+ }
+
+ $this->setup[$command] = array(
+ 'opts' => array(),
+ 'args' => array(),
+ 'help' => $help
+ );
+
+ }
+
+ /**
+ * Register an option for option parsing and help generation
+ *
+ * @param string $long multi character option (specified with --)
+ * @param string $help help text for this option
+ * @param string|null $short one character option (specified with -)
+ * @param bool|string $needsarg does this option require an argument? give it a name here
+ * @param string $command what command does this option apply to
+ * @throws Exception
+ */
+ public function registerOption($long, $help, $short = null, $needsarg = false, $command = '')
+ {
+ if (!isset($this->setup[$command])) {
+ throw new Exception("Command $command not registered");
+ }
+
+ $this->setup[$command]['opts'][$long] = array(
+ 'needsarg' => $needsarg,
+ 'help' => $help,
+ 'short' => $short
+ );
+
+ if ($short) {
+ if (strlen($short) > 1) {
+ throw new Exception("Short options should be exactly one ASCII character");
+ }
+
+ $this->setup[$command]['short'][$short] = $long;
+ }
+ }
+
+ /**
+ * Checks the actual number of arguments against the required number
+ *
+ * Throws an exception if arguments are missing.
+ *
+ * This is run from CLI automatically and usually does not need to be called directly
+ *
+ * @throws Exception
+ */
+ public function checkArguments()
+ {
+ $argc = count($this->args);
+
+ $req = 0;
+ foreach ($this->setup[$this->command]['args'] as $arg) {
+ if (!$arg['required']) {
+ break;
+ } // last required arguments seen
+ $req++;
+ }
+
+ if ($req > $argc) {
+ throw new Exception("Not enough arguments", Exception::E_OPT_ARG_REQUIRED);
+ }
+ }
+
+ /**
+ * Parses the given arguments for known options and command
+ *
+ * The given $args array should NOT contain the executed file as first item anymore! The $args
+ * array is stripped from any options and possible command. All found otions can be accessed via the
+ * getOpt() function
+ *
+ * Note that command options will overwrite any global options with the same name
+ *
+ * This is run from CLI automatically and usually does not need to be called directly
+ *
+ * @throws Exception
+ */
+ public function parseOptions()
+ {
+ $non_opts = array();
+
+ $argc = count($this->args);
+ for ($i = 0; $i < $argc; $i++) {
+ $arg = $this->args[$i];
+
+ // The special element '--' means explicit end of options. Treat the rest of the arguments as non-options
+ // and end the loop.
+ if ($arg == '--') {
+ $non_opts = array_merge($non_opts, array_slice($this->args, $i + 1));
+ break;
+ }
+
+ // '-' is stdin - a normal argument
+ if ($arg == '-') {
+ $non_opts = array_merge($non_opts, array_slice($this->args, $i));
+ break;
+ }
+
+ // first non-option
+ if ($arg[0] != '-') {
+ $non_opts = array_merge($non_opts, array_slice($this->args, $i));
+ break;
+ }
+
+ // long option
+ if (strlen($arg) > 1 && $arg[1] === '-') {
+ $arg = explode('=', substr($arg, 2), 2);
+ $opt = array_shift($arg);
+ $val = array_shift($arg);
+
+ if (!isset($this->setup[$this->command]['opts'][$opt])) {
+ throw new Exception("No such option '$opt'", Exception::E_UNKNOWN_OPT);
+ }
+
+ // argument required?
+ if ($this->setup[$this->command]['opts'][$opt]['needsarg']) {
+ if (is_null($val) && $i + 1 < $argc && !preg_match('/^--?[\w]/', $this->args[$i + 1])) {
+ $val = $this->args[++$i];
+ }
+ if (is_null($val)) {
+ throw new Exception("Option $opt requires an argument",
+ Exception::E_OPT_ARG_REQUIRED);
+ }
+ $this->options[$opt] = $val;
+ } else {
+ $this->options[$opt] = true;
+ }
+
+ continue;
+ }
+
+ // short option
+ $opt = substr($arg, 1);
+ if (!isset($this->setup[$this->command]['short'][$opt])) {
+ throw new Exception("No such option $arg", Exception::E_UNKNOWN_OPT);
+ } else {
+ $opt = $this->setup[$this->command]['short'][$opt]; // store it under long name
+ }
+
+ // argument required?
+ if ($this->setup[$this->command]['opts'][$opt]['needsarg']) {
+ $val = null;
+ if ($i + 1 < $argc && !preg_match('/^--?[\w]/', $this->args[$i + 1])) {
+ $val = $this->args[++$i];
+ }
+ if (is_null($val)) {
+ throw new Exception("Option $arg requires an argument",
+ Exception::E_OPT_ARG_REQUIRED);
+ }
+ $this->options[$opt] = $val;
+ } else {
+ $this->options[$opt] = true;
+ }
+ }
+
+ // parsing is now done, update args array
+ $this->args = $non_opts;
+
+ // if not done yet, check if first argument is a command and reexecute argument parsing if it is
+ if (!$this->command && $this->args && isset($this->setup[$this->args[0]])) {
+ // it is a command!
+ $this->command = array_shift($this->args);
+ $this->parseOptions(); // second pass
+ }
+ }
+
+ /**
+ * Get the value of the given option
+ *
+ * Please note that all options are accessed by their long option names regardless of how they were
+ * specified on commandline.
+ *
+ * Can only be used after parseOptions() has been run
+ *
+ * @param mixed $option
+ * @param bool|string $default what to return if the option was not set
+ * @return bool|string|string[]
+ */
+ public function getOpt($option = null, $default = false)
+ {
+ if ($option === null) {
+ return $this->options;
+ }
+
+ if (isset($this->options[$option])) {
+ return $this->options[$option];
+ }
+ return $default;
+ }
+
+ /**
+ * Return the found command if any
+ *
+ * @return string
+ */
+ public function getCmd()
+ {
+ return $this->command;
+ }
+
+ /**
+ * Get all the arguments passed to the script
+ *
+ * This will not contain any recognized options or the script name itself
+ *
+ * @return array
+ */
+ public function getArgs()
+ {
+ return $this->args;
+ }
+
+ /**
+ * Builds a help screen from the available options. You may want to call it from -h or on error
+ *
+ * @return string
+ *
+ * @throws Exception
+ */
+ public function help()
+ {
+ $tf = new TableFormatter($this->colors);
+ $text = '';
+
+ $hascommands = (count($this->setup) > 1);
+ foreach ($this->setup as $command => $config) {
+ $hasopts = (bool)$this->setup[$command]['opts'];
+ $hasargs = (bool)$this->setup[$command]['args'];
+
+ // usage or command syntax line
+ if (!$command) {
+ $text .= $this->colors->wrap('USAGE:', Colors::C_BROWN);
+ $text .= "\n";
+ $text .= ' ' . $this->bin;
+ $mv = 2;
+ } else {
+ $text .= "\n";
+ $text .= $this->colors->wrap(' ' . $command, Colors::C_PURPLE);
+ $mv = 4;
+ }
+
+ if ($hasopts) {
+ $text .= ' ' . $this->colors->wrap('<OPTIONS>', Colors::C_GREEN);
+ }
+
+ if (!$command && $hascommands) {
+ $text .= ' ' . $this->colors->wrap('<COMMAND> ...', Colors::C_PURPLE);
+ }
+
+ foreach ($this->setup[$command]['args'] as $arg) {
+ $out = $this->colors->wrap('<' . $arg['name'] . '>', Colors::C_CYAN);
+
+ if (!$arg['required']) {
+ $out = '[' . $out . ']';
+ }
+ $text .= ' ' . $out;
+ }
+ $text .= "\n";
+
+ // usage or command intro
+ if ($this->setup[$command]['help']) {
+ $text .= "\n";
+ $text .= $tf->format(
+ array($mv, '*'),
+ array('', $this->setup[$command]['help'] . "\n")
+ );
+ }
+
+ // option description
+ if ($hasopts) {
+ if (!$command) {
+ $text .= "\n";
+ $text .= $this->colors->wrap('OPTIONS:', Colors::C_BROWN);
+ }
+ $text .= "\n";
+ foreach ($this->setup[$command]['opts'] as $long => $opt) {
+
+ $name = '';
+ if ($opt['short']) {
+ $name .= '-' . $opt['short'];
+ if ($opt['needsarg']) {
+ $name .= ' <' . $opt['needsarg'] . '>';
+ }
+ $name .= ', ';
+ }
+ $name .= "--$long";
+ if ($opt['needsarg']) {
+ $name .= ' <' . $opt['needsarg'] . '>';
+ }
+
+ $text .= $tf->format(
+ array($mv, '30%', '*'),
+ array('', $name, $opt['help']),
+ array('', 'green', '')
+ );
+ $text .= "\n";
+ }
+ }
+
+ // argument description
+ if ($hasargs) {
+ if (!$command) {
+ $text .= "\n";
+ $text .= $this->colors->wrap('ARGUMENTS:', Colors::C_BROWN);
+ }
+ $text .= "\n";
+ foreach ($this->setup[$command]['args'] as $arg) {
+ $name = '<' . $arg['name'] . '>';
+
+ $text .= $tf->format(
+ array($mv, '30%', '*'),
+ array('', $name, $arg['help']),
+ array('', 'cyan', '')
+ );
+ }
+ }
+
+ // head line and intro for following command documentation
+ if (!$command && $hascommands) {
+ $text .= "\n";
+ $text .= $this->colors->wrap('COMMANDS:', Colors::C_BROWN);
+ $text .= "\n";
+ $text .= $tf->format(
+ array($mv, '*'),
+ array('', 'This tool accepts a command as first parameter as outlined below:')
+ );
+ $text .= "\n";
+ }
+ }
+
+ return $text;
+ }
+
+ /**
+ * Safely read the $argv PHP array across different PHP configurations.
+ * Will take care on register_globals and register_argc_argv ini directives
+ *
+ * @throws Exception
+ * @return array the $argv PHP array or PEAR error if not registered
+ */
+ private function readPHPArgv()
+ {
+ global $argv;
+ if (!is_array($argv)) {
+ if (!@is_array($_SERVER['argv'])) {
+ if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) {
+ throw new Exception(
+ "Could not read cmd args (register_argc_argv=Off?)",
+ Exception::E_ARG_READ
+ );
+ }
+ return $GLOBALS['HTTP_SERVER_VARS']['argv'];
+ }
+ return $_SERVER['argv'];
+ }
+ return $argv;
+ }
+}
+
diff --git a/platform/www/vendor/splitbrain/php-cli/src/PSR3CLI.php b/platform/www/vendor/splitbrain/php-cli/src/PSR3CLI.php
new file mode 100644
index 0000000..ef744f3
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-cli/src/PSR3CLI.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace splitbrain\phpcli;
+
+use Psr\Log\LoggerInterface;
+
+/**
+ * Class PSR3CLI
+ *
+ * The same as CLI, but implements the PSR-3 logger interface
+ */
+abstract class PSR3CLI extends CLI implements LoggerInterface {
+} \ No newline at end of file
diff --git a/platform/www/vendor/splitbrain/php-cli/src/TableFormatter.php b/platform/www/vendor/splitbrain/php-cli/src/TableFormatter.php
new file mode 100644
index 0000000..23bb894
--- /dev/null
+++ b/platform/www/vendor/splitbrain/php-cli/src/TableFormatter.php
@@ -0,0 +1,325 @@
+<?php
+
+namespace splitbrain\phpcli;
+
+/**
+ * Class TableFormatter
+ *
+ * Output text in multiple columns
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @license MIT
+ */
+class TableFormatter
+{
+ /** @var string border between columns */
+ protected $border = ' ';
+
+ /** @var int the terminal width */
+ protected $max = 74;
+
+ /** @var Colors for coloring output */
+ protected $colors;
+
+ /**
+ * TableFormatter constructor.
+ *
+ * @param Colors|null $colors
+ */
+ public function __construct(Colors $colors = null)
+ {
+ // try to get terminal width
+ $width = $this->getTerminalWidth();
+ if ($width) {
+ $this->max = $width - 1;
+ }
+
+ if ($colors) {
+ $this->colors = $colors;
+ } else {
+ $this->colors = new Colors();
+ }
+ }
+
+ /**
+ * The currently set border (defaults to ' ')
+ *
+ * @return string
+ */
+ public function getBorder()
+ {
+ return $this->border;
+ }
+
+ /**
+ * Set the border. The border is set between each column. Its width is
+ * added to the column widths.
+ *
+ * @param string $border
+ */
+ public function setBorder($border)
+ {
+ $this->border = $border;
+ }
+
+ /**
+ * Width of the terminal in characters
+ *
+ * initially autodetected
+ *
+ * @return int
+ */
+ public function getMaxWidth()
+ {
+ return $this->max;
+ }
+
+ /**
+ * Set the width of the terminal to assume (in characters)
+ *
+ * @param int $max
+ */
+ public function setMaxWidth($max)
+ {
+ $this->max = $max;
+ }
+
+ /**
+ * Tries to figure out the width of the terminal
+ *
+ * @return int terminal width, 0 if unknown
+ */
+ protected function getTerminalWidth()
+ {
+ // from environment
+ if (isset($_SERVER['COLUMNS'])) return (int)$_SERVER['COLUMNS'];
+
+ // via tput
+ $process = proc_open('tput cols', array(
+ 1 => array('pipe', 'w'),
+ 2 => array('pipe', 'w'),
+ ), $pipes);
+ $width = (int)stream_get_contents($pipes[1]);
+ proc_close($process);
+
+ return $width;
+ }
+
+ /**
+ * Takes an array with dynamic column width and calculates the correct width
+ *
+ * Column width can be given as fixed char widths, percentages and a single * width can be given
+ * for taking the remaining available space. When mixing percentages and fixed widths, percentages
+ * refer to the remaining space after allocating the fixed width
+ *
+ * @param array $columns
+ * @return int[]
+ * @throws Exception
+ */
+ protected function calculateColLengths($columns)
+ {
+ $idx = 0;
+ $border = $this->strlen($this->border);
+ $fixed = (count($columns) - 1) * $border; // borders are used already
+ $fluid = -1;
+
+ // first pass for format check and fixed columns
+ foreach ($columns as $idx => $col) {
+ // handle fixed columns
+ if ((string)intval($col) === (string)$col) {
+ $fixed += $col;
+ continue;
+ }
+ // check if other colums are using proper units
+ if (substr($col, -1) == '%') {
+ continue;
+ }
+ if ($col == '*') {
+ // only one fluid
+ if ($fluid < 0) {
+ $fluid = $idx;
+ continue;
+ } else {
+ throw new Exception('Only one fluid column allowed!');
+ }
+ }
+ throw new Exception("unknown column format $col");
+ }
+
+ $alloc = $fixed;
+ $remain = $this->max - $alloc;
+
+ // second pass to handle percentages
+ foreach ($columns as $idx => $col) {
+ if (substr($col, -1) != '%') {
+ continue;
+ }
+ $perc = floatval($col);
+
+ $real = (int)floor(($perc * $remain) / 100);
+
+ $columns[$idx] = $real;
+ $alloc += $real;
+ }
+
+ $remain = $this->max - $alloc;
+ if ($remain < 0) {
+ throw new Exception("Wanted column widths exceed available space");
+ }
+
+ // assign remaining space
+ if ($fluid < 0) {
+ $columns[$idx] += ($remain); // add to last column
+ } else {
+ $columns[$fluid] = $remain;
+ }
+
+ return $columns;
+ }
+
+ /**
+ * Displays text in multiple word wrapped columns
+ *
+ * @param int[] $columns list of column widths (in characters, percent or '*')
+ * @param string[] $texts list of texts for each column
+ * @param array $colors A list of color names to use for each column. use empty string for default
+ * @return string
+ * @throws Exception
+ */
+ public function format($columns, $texts, $colors = array())
+ {
+ $columns = $this->calculateColLengths($columns);
+
+ $wrapped = array();
+ $maxlen = 0;
+
+ foreach ($columns as $col => $width) {
+ $wrapped[$col] = explode("\n", $this->wordwrap($texts[$col], $width, "\n", true));
+ $len = count($wrapped[$col]);
+ if ($len > $maxlen) {
+ $maxlen = $len;
+ }
+
+ }
+
+ $last = count($columns) - 1;
+ $out = '';
+ for ($i = 0; $i < $maxlen; $i++) {
+ foreach ($columns as $col => $width) {
+ if (isset($wrapped[$col][$i])) {
+ $val = $wrapped[$col][$i];
+ } else {
+ $val = '';
+ }
+ $chunk = $this->pad($val, $width);
+ if (isset($colors[$col]) && $colors[$col]) {
+ $chunk = $this->colors->wrap($chunk, $colors[$col]);
+ }
+ $out .= $chunk;
+
+ // border
+ if ($col != $last) {
+ $out .= $this->border;
+ }
+ }
+ $out .= "\n";
+ }
+ return $out;
+
+ }
+
+ /**
+ * Pad the given string to the correct length
+ *
+ * @param string $string
+ * @param int $len
+ * @return string
+ */
+ protected function pad($string, $len)
+ {
+ $strlen = $this->strlen($string);
+ if ($strlen > $len) return $string;
+
+ $pad = $len - $strlen;
+ return $string . str_pad('', $pad, ' ');
+ }
+
+ /**
+ * Measures char length in UTF-8 when possible
+ *
+ * @param $string
+ * @return int
+ */
+ protected function strlen($string)
+ {
+ // don't count color codes
+ $string = preg_replace("/\33\\[\\d+(;\\d+)?m/", '', $string);
+
+ if (function_exists('mb_strlen')) {
+ return mb_strlen($string, 'utf-8');
+ }
+
+ return strlen($string);
+ }
+
+ /**
+ * @param string $string
+ * @param int $start
+ * @param int|null $length
+ * @return string
+ */
+ protected function substr($string, $start = 0, $length = null)
+ {
+ if (function_exists('mb_substr')) {
+ return mb_substr($string, $start, $length);
+ } else {
+ // mb_substr() treats $length differently than substr()
+ if ($length) {
+ return substr($string, $start, $length);
+ } else {
+ return substr($string, $start);
+ }
+ }
+ }
+
+ /**
+ * @param string $str
+ * @param int $width
+ * @param string $break
+ * @param bool $cut
+ * @return string
+ * @link http://stackoverflow.com/a/4988494
+ */
+ protected function wordwrap($str, $width = 75, $break = "\n", $cut = false)
+ {
+ $lines = explode($break, $str);
+ foreach ($lines as &$line) {
+ $line = rtrim($line);
+ if ($this->strlen($line) <= $width) {
+ continue;
+ }
+ $words = explode(' ', $line);
+ $line = '';
+ $actual = '';
+ foreach ($words as $word) {
+ if ($this->strlen($actual . $word) <= $width) {
+ $actual .= $word . ' ';
+ } else {
+ if ($actual != '') {
+ $line .= rtrim($actual) . $break;
+ }
+ $actual = $word;
+ if ($cut) {
+ while ($this->strlen($actual) > $width) {
+ $line .= $this->substr($actual, 0, $width) . $break;
+ $actual = $this->substr($actual, $width);
+ }
+ }
+ $actual .= ' ';
+ }
+ }
+ $line .= trim($actual);
+ }
+ return implode($break, $lines);
+ }
+} \ No newline at end of file